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.
Delta-read model
Section titled “Delta-read model”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.
Why pure
Section titled “Why pure”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).