Overview
@superbright/indexeddb-orm is the shared state and analytics layer for InResi apps. It combines an IndexedDB-backed store (Dexie + Zustand) with a validated analytics event system (Zod + Mixpanel/PostHog).
Core concepts
useInResiStore— the primary React hook for reading and mutating store state (filters, tempFilters, unit results, favorites, questionnaire, etc.)- Analytics — validated event tracking via
useTrackingEvents()orbuildTrackingEvents(). Events that fail Zod schema validation are silently dropped in production and warned in dev. - Visitor UUID — a stable per-browser identity stored in IndexedDB, surfaced via
useVisitorSession()and wired intoAnalyticsProvider. - Dimension helpers — mm ↔ imperial conversion utilities for furniture display.
Typical setup
// main.tsx / App.tsx
import { AnalyticsProvider } from "@superbright/indexeddb-orm";
import { useVisitorSession } from "./hooks/useVisitorSession";
function Providers({ children }: { children: React.ReactNode }) {
const visitor_uuid = useVisitorSession(slug);
return (
<AnalyticsProvider
visitor_uuid={visitor_uuid}
mixpanelToken={import.meta.env.VITE_MIXPANEL_TOKEN}
posthogKey={import.meta.env.VITE_POSTHOG_KEY}
posthogHost={import.meta.env.VITE_POSTHOG_HOST}
envMode={import.meta.env.MODE ?? "production"}
>
{children}
</AnalyticsProvider>
);
}
// Component usage
import { useInResiStore, useTrackingEvents } from "@superbright/indexeddb-orm";
function MyComponent() {
const store = useInResiStore();
const { trackClickUnit, trackFilterApplied } = useTrackingEvents();
// Read temp filters
const tempFilters = store.tempFilters;
// Mutate
store.handleTempFilterChange("qty_bedrooms", [1, 2]);
store.submitFilterUpdate();
}
What's documented here
| Page | What it covers |
|---|---|
| Analytics | AnalyticsProvider, useTrackingEvents, all event schemas |
| User Identification | visitor_uuid, useVisitorSession, getVisitorUUID / setVisitorUUID |
| Unified Store | useInResiStore, tempFilters, filters, unit results, questionnaire |
| Dimension Helpers | mm ↔ imperial conversions, formatDimensions |
| API Schemas | Generated Zod schemas for all REST API objects |
API Tooling
All API tooling reads from openapi.json at the repo root.
Docs
pnpm docs:serve
Copies openapi.json into the static assets and starts the documentation site on port 3001:
http://localhost:3001/inResi-indexedDB-ORM— full docs sitehttp://localhost:3001/inResi-indexedDB-ORM/scalar.html— interactive Scalar API reference
Mock server
pnpm mock:api
Starts a Scalar mock server on port 4010. Every endpoint in the spec returns realistic example responses without needing the real API running. Useful for frontend development and integration tests.
# Example: hit a mocked endpoint
curl http://localhost:4010/app/{slug}/units
Validation
pnpm validate:api
Validates openapi.json against the OpenAPI 3.0 spec. Run this after editing the spec manually or after pulling a new version from the backend.
Validation also runs automatically as a pre-step inside generate:api-schema, so a broken spec will never silently produce bad generated types.
Updating API Schemas
When the inResi REST API changes, regenerate the TypeScript types and bundled Zod schemas in one step:
- Ensure the API server is running locally on port 3000.
- Run:
This validates
pnpm generate:api-schemaopenapi.json, fetches the latest spec from the running server, writessrc/types/api.generated.ts, then regeneratessrc/api/schemas.generated.ts. Do not edit either file by hand. - Build and publish:
pnpm build
npm version patch
npm publish
See API Schemas for usage of the generated schemas.