OpOutbox
The SECOND outbox shape: a durable, FIFO, append-only operation log — distinct from SubmitOutbox, which is a keyed latest-write-wins draft store. Reach for this one when order matters and every mutation must reach the server exactly once, surviving process death:
append-only — enqueue logs an opaque
(type, payload)op and returns its stable id, which doubles as an idempotency key the caller sends to the server so a re-delivered op is collapsed.FIFO replay — replay drains oldest-first through a caller-supplied
send. It stops at the first transient failure (offline / 5xx / timeout) to preserve order and let the next trigger resume, rather than reordering the queue or hammering a down server.dead-lettering — an op the server rejects (classified permanent by
isPermanent, e.g. a 4xx) or one that exhaustsmaxAttemptstransient retries is marked dead (kept, not deleted) so replay moves past it instead of getting stuck behind a poison row. Dead ops are inspectable via deadLetters and re-runnable via requeue.
Payload-agnostic by design: it stores opaque type + serialized-payload strings, and the caller owns both serialization and the send transport — so this stays decoupled from any HTTP client or DTO.
Inheritors
Functions
Dead-lettered ops, for inspection or a manual-retry UI.
Drain PENDING ops oldest-first. For each, calls send; on success the op is deleted. On failure: if isPermanent returns true for the error, or the op has now failed maxAttempts times, it is dead-lettered and replay continues; otherwise the failure is recorded and replay STOPS (preserving order) — the next trigger resumes from the same op.