Local Store Adapter Visual Overview
Technical notes from the Jett team.
Status: Working visual companion for V4 local-first storage Canonical sources: Roadmap V4, ADR-001 Goal: Show how Dexie, native SQLite, SQLite WASM/OPFS, the shared adapter contract, sync, and UI fit together.
1. Mental Model
Jett should not let React components care whether data comes from Dexie, native SQLite, or browser SQLite. The app talks to a shared domain boundary. Runtime-specific adapters hide the database details.
The rule is simple: UI and agent code depend on the contract, not on a database driver. Dexie stays alive while we migrate, but it stops being the architecture.
2. Current State vs Target State
What already exists
LocalMailStoretype boundary.DexieMailStoreadapter.- Runtime feature flags for adapter selection.
- Contract checks for the Dexie adapter.
- Basic local thread list projection.
What still needs to be built
- Native SQLite Rust module and Tauri IPC commands.
- Native adapter parity with Dexie.
- Hot cache as the primary render source.
- Durable cursor change feed.
- Modifier/outbox queue.
- FTS5 local search.
- Removal of direct Dexie imports from UI paths.
3. Runtime Adapter Selection
The app chooses one store implementation based on runtime capability and feature flags.
Dexie is the safety net. Native SQLite is the desktop target. SQLite WASM/OPFS is the browser target.
4. Data Ownership
Data rules:
- Provider owns raw bodies and attachments.
- Local store caches bodies and derived indexes.
- Supabase should be metadata and coordination, not a mailbox clone.
- Zustand is fast UI memory, not durable storage.
- Pending local modifiers are important because they may not exist remotely yet.
5. Local Database Shape
Target local schema, shared logically across desktop and browser:
The physical implementation can differ by runtime, but the behavior must pass the same contract tests.
6. Read Path: Open Mailbox
The target render path is memory first. Database work happens off the render path.
7. Read Path: Open Thread Body
Bodies can transit the Jett API, but the V4 target says they should not become permanent Supabase mailbox storage.
8. Write Path: Mark Done / Star / Move
This is the move from “optimistic UI plus refetch” to real local-first mutation durability.
9. Realtime and Durable Sync
Realtime should wake the client up. It should not be the correctness mechanism.
If Realtime is missed, duplicated, delayed, or reordered, the next catch-up still converges because the cursor feed is durable.
10. Migration Phases
The practical sequence for today starts at step 1/2: make native SQLite real, prove it against the same contract, then move reads behind a flag.
11. File Map
Current important files:
src/lib/local-store/types.ts- shared local-store contract.src/lib/local-store/current.ts- active adapter wiring.src/lib/local-store/adapters/dexie-mail-store.ts- current fallback adapter.src/lib/local-store/runtime.ts- feature flag and runtime selection helpers.scripts/test-local-store.ts- current adapter contract checks.scripts/benchmark-local-store.ts- current synthetic baseline.src-tauri/src/lib.rs- Tauri shell and security/navigation boundary.src-tauri/Cargo.toml- whererusqliteand native dependencies will be added.
Target files to add:
src-tauri/src/local_store/mod.rssrc-tauri/src/local_store/schema.rssrc-tauri/src/local_store/commands.rssrc-tauri/src/local_store/models.rssrc/lib/local-store/adapters/native-sqlite-mail-store.tssrc/lib/local-store/thread-hot-cache.tssrc/lib/local-store/body-cache-service.tssrc/lib/local-store/modifier-queue.tssrc/lib/local-store/realtime-buffer.ts
12. Implementation Checklist
- [x] Expand
LocalMailStoreto include body cache, search, modifiers, cursors, and snapshot operations. - [x] Add Rust SQLite module with WAL,
synchronous=NORMAL, foreign keys, busy timeout, and FTS5-backed search. - [x] Create versioned local migrations.
- [x] Expose narrow typed Tauri commands only.
- [x] Implement TS native adapter bridge.
- [x] Run Dexie and native through focused local-store contract checks.
- [x] Remove direct Dexie imports from active mail UI surfaces.
- [x] Add
ThreadHotCachefoundation and cached store wrapper. - [ ] Add modifier queue for done/starred/inbox actions.
- [x] Add local sync cursor storage and Realtime wake-up buffer foundation.
- [x] Add atomic local change-batch/cursor apply across Dexie, native SQLite, and hot cache.
- [x] Wire Realtime wake-ups to paged cursor catch-up instead of full thread-view refresh.
- [x] Add append-only durable server change log, tombstones, and missed-event convergence tests.
- [ ] Add FTS5 local search.
- [ ] Keep Dexie as rollback until parity and telemetry prove native/web SQLite are safe.