Skip to content

client.offline

See the Offline guide for concepts and patterns. Offline support is on by default in browsers and a no-op in Node, serverless runtimes and SSR.

client.offline.status: "online" | "offline" | "syncing"

Current connectivity, fused from navigator.onLine, real request outcomes, and the websocket lifecycle. "syncing" means the durable write queue is draining after a reconnect.

client.offline.enabled: boolean

true in a browser with IndexedDB + the Cache API; false otherwise (all methods become no-ops / return empty).

onStatusChange(cb: (status: "online" | "offline" | "syncing") => void): () => void

Subscribe to connectivity changes. Returns an unsubscribe function. Status changes are also emitted on EventCore (ONLINE, OFFLINE, SYNCING, SYNC_PROGRESS, SYNC_COMPLETE, SYNC_ERROR).

resume(): Promise<void>

Replay the durable write queue now, as a reconnect does, if the queue holds anything. Writes kept after a payment refusal (see below) go out this way. It does nothing when offline support is off or the queue is empty. The SDK calls it for you each time client.app.access() reports the app allowed; call it yourself only if you have another reason to think a refusal has cleared.

The durable queue replays writes in clock order when the connection returns. Progress is reported on EventCore, with these payloads:

EventPayload
SYNC_PROGRESS{ domain, method } — one queued write was accepted.
SYNC_COMPLETE{} — the drain finished.
SYNC_ERROR{ domain, method, error, dropped } — dropped: true means the server permanently refused the write (a 4xx) and it was discarded; a transient failure stops the drain and keeps the rest for the next reconnect.

A write refused for payment (PaymentRequiredError: the app takes paid plans only, or someone’s payment is past due) is kept, not dropped. SYNC_ERROR carries dropped: false and the refusal’s code, and the drain stops there, keeping order. It resumes on the next reconnect or when client.offline.resume() runs.

App-state snapshots — client.offline.snapshot

Section titled “App-state snapshots — client.offline.snapshot”

An encrypted cache for UI/view state that never leaves the device. Encrypted at rest with the identity-derived key; reads return null while the client is locked.

save<T>(name: string, state: T): Promise<void>

Persist state under name (encrypted). Throws OfflineLockedError if the identity isn’t unlocked. The latest save wins. No-op when offline support is off.

load<T>(name: string): Promise<T | null>

Decrypt and return the snapshot, or null if absent or the client is locked.

delete(name: string): Promise<void>
list(): Promise<string[]>

Remove a snapshot; list all snapshot names for the current user.

new Client({ offline }) accepts enabled and store. It also declares cacheShards and maxQueueBytes, but the SDK does not currently read either: file-shard caching is on whenever offline support is on and the Cache API exists, and the queue has no size cap.

Thrown when an encrypted offline read/write needs the user’s identity but the client is locked (typically right after a reload, before unlock()). Distinct from the generic “not signed in” error so apps can prompt to unlock specifically.