Skip to main content

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() or buildTrackingEvents(). 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 into AnalyticsProvider.
  • 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

PageWhat it covers
AnalyticsAnalyticsProvider, useTrackingEvents, all event schemas
User Identificationvisitor_uuid, useVisitorSession, getVisitorUUID / setVisitorUUID
Unified StoreuseInResiStore, tempFilters, filters, unit results, questionnaire
Dimension Helpersmm ↔ imperial conversions, formatDimensions
API SchemasGenerated 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 site
  • http://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:

  1. Ensure the API server is running locally on port 3000.
  2. Run:
    pnpm generate:api-schema
    This validates openapi.json, fetches the latest spec from the running server, writes src/types/api.generated.ts, then regenerates src/api/schemas.generated.ts. Do not edit either file by hand.
  3. Build and publish:
    pnpm build
    npm version patch
    npm publish

See API Schemas for usage of the generated schemas.