Sync / Replicated state
When things go wrong
Each of these is designed for. The ones that change how you build come first.
| Failure | What happens |
|---|---|
| The network is gone | edits apply and save; pending grows; the loop retries |
| The server rejects an edit | dropped from pending, the rest replayed, the Model re-installed |
| The local save fails | the edit is reverted and onPersistenceFailure says so |
| Another device commits first | the base advances; local edits replay on top |
| An operation is retried | the stable opId is answered from history, never applied twice |
| The replica is far behind | pages (more), or a checkpoint when the tail was compacted |
| The server lost its history | a new epoch: the replica rebuilds from 0 and resends its outbox; what the old server committed is gone everywhere; a replica that never heard an epoch cannot tell and fails until its storage is cleared |
| Another actor sends a replica's operations | Durable refuses them: a replica is bound to its first committing actor |
| Local storage was evicted | the replica catches up from the server, but unsent edits are lost: the outbox is user data |
| Two tabs share one storage name | compare-and-swap fails the stale writer rather than merging histories |
| Stored state is from another version | opening fails naming both versions; the bytes are kept for a deliberate migration |
| The server answers nonsense | a malformed answer, a gap in the order, an ack for an operation never sent, or a checkpoint behind the cursor fails the exchange; local work is untouched |
| An external effect succeeded before a crash recorded it | the provider call may repeat; use provider idempotency with Durable's effect ledger |
The last row is the one the libraries cannot close. A committed operation may
imply work outside SQLite (an email, a charge), and no local database can
commit atomically with a provider. Durable's runEffect and recover record
intents and reuse known outcomes; they do not make the provider transactional.
Read external effects
before wiring one.