Skip to main content
An outbox for edits, the way a mail app holds messages until it can send them. Your screen changes at once; the queue makes the change stick, now or later. It survives a reload, so an edit made offline isn’t lost if the user closes the app.
outbox.ts

createOfflineQueue

string
required
The queue’s name. Ops are stored in localStorage under cskn.outbox.<name>, so keep it stable and unique within your app.
(op: Op) => Promise<unknown>
required
Sends one op. Ops are plain data, not functions, so they can be stored and sent after a reload.
(op: Op, error: unknown) => void
Called when the server refuses an op. Use it to put the screen back the way the server has it.
(error: unknown) => boolean
Decides whether a failure means “no connection”. By default, a request that got no response at all, or navigator.onLine === false.

How ops are sent

  • In order, one at a time.
  • A failure with no response keeps the op and retries: when the device comes back online, when the page returns to the foreground, and on a backoff timer up to one minute.
  • A response with any HTTP error status is final. The op is dropped and onDrop is called.
  • Ops left over from a previous visit are sent when the page loads.
If localStorage is full or blocked, the queue still works for the current page; it just doesn’t survive a reload.

The queue object

Showing what’s waiting

useOfflineQueue(queue) returns the unsent ops and re-renders as they change:
Combined with an undo toast, the queue becomes the commit step: show the change, offer undo, and call outbox.add(op) only when the toast closes without an undo. See toast.undoable.