Mutation queue
The mutation queue is the reliability core of offline write behavior. When a write cannot be sent immediately, FFDB stores it and retries during sync so user actions are not lost.
Why this matters
Without queueing, offline writes fail and users have to repeat work. Queueing solves this by separating local acceptance from remote delivery.
- Name
Offline-safe writes- Description
Users can keep working while disconnected.
- Name
Deterministic retry path- Description
Queued mutations are retried during push and removed only after success.
- Name
Operational visibility- Description
pendingMutationsand push result counts make delivery state observable.
Queue-related interfaces
type SyncStatus = {
isSyncing: boolean
isOnline: boolean
lastSyncedAt: number | null
pendingMutations: number
error: Error | null
}
type MutationEntry = {
id: number
sql: string
params: string
created_at: number
}
Push and full sync return explicit queue results:
type PushResult = {
pushed: number
failed: number
}
End-to-end queue flow
import { createClient } from 'ffdb-client'
import type { Database } from './ffdb.types'
const { db, sync } = await createClient<Database>({
config: { apiUrl: import.meta.env.VITE_FFDB_API_URL },
offline: {
adapter: offlineAdapter,
syncOnReconnect: true,
},
})
// Write while offline or unstable network.
await db
.updateTable('task')
.set({ completed: 1 })
.where('id', '=', taskId)
.execute()
if (sync) {
console.log('pending before push', sync.status.pendingMutations)
const result = await sync.push()
console.log(result) // { pushed, failed }
console.log('pending after push', sync.status.pendingMutations)
}
Expected queue behavior
- Local write is accepted first.
- Mutation enters queue if remote delivery is not immediately available.
sync.push()replays queued entries in order.- Successfully delivered entries are removed from queue.
- Failed entries remain queued for future retries.
Failure handling patterns
- Name
Expose pending count in UI- Description
Show users when writes are waiting to sync.
- Name
React to failed counts- Description
If
failed > 0, notify the user and offer manual retry.
- Name
Use reconnect triggers- Description
Pair queueing with
syncOnReconnectso recovery is automatic.
- Name
Use waitForIdle for critical flows- Description
Wait for queue drain before completion screens that require remote confirmation.
Queue success is eventual, not immediate. If a workflow requires confirmed remote persistence, check push results and sync status explicitly.
Practical tradeoffs
- Queueing improves reliability but can delay remote visibility.
- Aggressive auto-sync improves freshness but increases network and battery usage.
- Manual retry controls improve transparency in high-latency environments.