Skip to content

Sync-Core Reconcilers

src/lib/offline/sync-core.ts holds the pure functions that reconcile server delta reads into the Dexie cache. They are side-effect-free (testable in isolation) and shared by both the polling fallback and the live transport — the data path is identical regardless of how a refresh is triggered.

The client fetches changes since a cursor (a ?since read keyed by maxUpdatedAt(...)) per surface, then reconciles:

  • reconcile(...) / reconcileGroups(...) — fold lists/groups deltas.
  • reconcileTasks(...), reconcileSteps(...), reconcileAllSteps(...) — fold task/step deltas.
  • reconcileMyDay(...) — fold “My Day” view membership.
  • reconcileMemberships(...) — fold list-sharing changes.
  • deltaDeleteIds(...) — extract tombstoned (deletedAt) ids to remove locally.
  • evictRevoked(...) — drop cached data for a List the user has lost access to (revocation boundary).
  • maxUpdatedAt(...) — compute the next cursor from a batch.

Because reconcilers are pure, the transport (polling timer vs. WebSocket signal) only decides when to call them — never what they do. This is the invariant that let the event-push upgrade (spec 021) replace the polling timer without touching read/reconcile logic. Optimistic local mutations are issued separately from src/lib/offline/sync.ts (createList, renameList, moveList, duplicateList, …).

Related: Offline Outbox & Checklists (the write side), LiveConnection WS Client and Poll Controller (the triggers).