Sync Engine
The Sync Engine (lib/sync-engine.ts) is the bridge between the Convex cloud backend and the local SQLite cache. It receives Delta Payloads containing tasks and instances that have changed since the last sync, and atomically upserts them into the local database.
Delta Payload Structure
Every sync cycle, the Convex backend computes a differential payload based on the client’s last known sync token:expo-secure-store (encrypted, persisted across app restarts) — not in SQLite, which can be wiped during Nuke and Pave operations.
The Freshness Guard
The Freshness Guard is the critical anti-corruption mechanism that prevents background sync from overwriting the user’s fresh edits with stale cloud data. The problem it solves: A user edits a task atT=100. The background sync fires at T=101 with data from T=90 (because the Convex query was slow). Without the Freshness Guard, the sync would silently overwrite the user’s edit.
Atomic Transaction Safety
All multi-row writes are wrapped in a singlewithTransactionAsync() call. If any row fails, the entire batch rolls back atomically:
The sync token is written outside the transaction, after it succeeds. This means if the transaction fails, the token is not updated, and the next sync cycle will re-fetch the same data — guaranteeing at-least-once delivery without data loss.
Automatic Corruption Recovery
If the transaction throws amalformed or disk I/O error, the engine enters an automatic recovery protocol:
This prevents the app from entering a death loop where corrupted data causes every subsequent transaction to fail.
HydrationEngine
TheHydrationEngine is an invisible React component mounted at the root of the app tree. It runs the useHydrationSync() hook, which:
- Monitors the authenticated session state
- Reads the local sync token from SecureStore
- If the token is missing (Amnesia Mode), fetches a full payload from Convex
- If the token exists, fetches only the delta since the last sync
- Passes the payload to
ingestDeltaPayload()for atomic upsert - After successful ingestion, triggers
scheduleNextAlarm()to re-arm the hardware