Unified Store
UnifiedStore is the high-level state container that powers the property results experience. It merges per-property state, search filters, cached API results, and questionnaire progress into a single persisted snapshot stored under the "app" key in IndexedDB.
import { UnifiedStore, store } from "inresi-indexeddb-orm";
await store.initialize(); // ensure baseline shape
await store.initializeProperty("101", "west-loop");
Every mutating method validates the next snapshot against UnifiedStoreDataSchema, dropping invalid input and preventing schema drift over time.
Initialization & hydration
| Method | Notes |
|---|---|
initialize() | Ensures the persisted state contains the default structure. Run this once during app bootstrap. |
initializeProperty(propertyId, slug) | Seeds a per-property entry (with favorites, viewed units, etc.) and updates the active pointers. Safe to call on every property navigation. |
Property state helpers
setCurrentProperty(propertyId, slug?)andsetCurrentPropertySlug(slug)adjust the active pointers.setPropertyData(propertyId, data, schema?)validates a full property payload before storing it inproperties[id].data.mergePropertyData(propertyId, partial, schema?)validates partial updates and merges them into an existing payload.upsertPropertyFromApi(apiProperty, schema?)enforces a valid property object, extractsid/slug, and writes it to the store.toggleFavorite(unitId),markUnitAsViewed(unitId, slug),setTourContactedOn(),setQuestionnaireResults(results), andsetTourContactData(data)mirror thePropertyStorebehavior but operate inside the unified state.
Results & filters
setUnitResults(units, schema?)andclearUnitResults()manage the cached API results array. Each item is validated againstUnitSchemaor a supplied schema.setFilters,setTempFilters,setFiltersToDefault,handleTempFilterChange, andsubmitFilterUpdate()keep UI and API filters in sync, coercing mixed inputs (strings, numbers, option objects) into normalized arrays/numbers.setApiFilters(filters)lets you update pagination parameters directly.setResultsMode(mode)andsetSortBy(sortBy)store UI state.setResolvedQuestionnaireValues(name, values)persists resolved questionnaire answers for reuse.
Queries
getFullState()→ returns the validatedUnifiedStoreData.getCurrentProperty()/getPropertyData(propertyId?)behave like theirPropertyStorecounterparts.getUnitState(unitId)exposes{ isFavorite, viewedDate }for quick UI decisions.getResultsUrl()builds a canonical results path using the active property slug.getTourContactedOn()mirrors the property-level helper.
Usage example
import { store } from "inresi-indexeddb-orm";
await store.initialize();
await store.initializeProperty(101, "west-loop");
await store.setFilters({ qty_bedrooms: [2, 3] });
await store.submitFilterUpdate();
await store.setUnitResults(apiResponse.units);
const state = await store.getFullState();
const resultsUrl = await store.getResultsUrl();
All methods are asynchronous; when integrating with state managers like Zustand or React Query, wrap calls in actions and keep rendered components subscribed to the relevant slices from IndexedDB.