offline-sync
Installation
SKILL.md
Offline Sync
Conflict Resolution — Choose One Per Data Type
| Strategy | Use when |
|---|---|
| Last-Write-Wins (LWW) | Settings, profile fields — losing concurrent edits is acceptable |
| Server-wins | Inventory, balances — server is authoritative |
| Client-wins | Purely local data (drafts, preferences) never shared |
| Field-level merge | Documents — non-overlapping fields merge; conflicts flagged |
| CRDT (Yjs, Automerge) | Collaborative text, sets, counters — guaranteed merge; high complexity |
Define the policy per collection in writing before implementation — changing it later requires a data migration.
Sync Protocol Design
- Every write gets a logical clock (Lamport or hybrid logical clock). Wall-clock alone is insufficient — clocks drift and go backward.
- Delta sync: client sends
{since: lastSyncedCursor}; server returns only changes since that cursor. Never full-table sync after initial load. - Tombstones: soft-delete with
deletedAt; never hard-delete until all clients have synced past that version. - Sync cursor: opaque, server-generated; stored per collection on the client; resumed on next sync.