HoldSendWrite offline. Publish exactly once.GitHub

Notes: the HoldSend example

A small notes app that keeps working without a connection and publishes every note exactly once. It is a demo, not a template for production, but every part of it is wired the way a real app would wire HoldSend.

Run it

From the repository root:

npm install
npm run build
npm start --workspace holdsend-example-notes

Open http://localhost:3000. It uses PGlite (Postgres in WebAssembly, in memory) unless DATABASE_URL points at a real Postgres.

Try to break it

What is where

File What it shows
src/app.mjs The server. handleIdempotent around the insert, requireKey: true, the written time in its own column, the feed ordered by arrival, a tombstone on delete.
src/client.mjs The page. An Outbox over IndexedDB, auto-flush, one sender across tabs, and the outbox shown to the person with Cancel, Send, Try again and Discard, each telling the truth about what happened.
src/send.mjs How one note is sent. The outbox adds Idempotency-Key and Written-At.
src/sw.mjs The service worker. Keeps the page available offline and sends in the background where the browser supports Background Sync.
src/session.mjs Tells the service worker who is signed in, so it only ever sends that person's notes.
src/emergency-client.mjs and public/emergency.html The emergency page at /emergency: its own queue, sender lock and background sync tag. The first message goes by itself, later ones wait for Send or Send all, repeated taps are one message, and there's an SMS hand-off that takes the message out of the queue (and can put it back). A demo, not an emergency service.
src/drafts-client.mjs and public/drafts.html The drafts page at /drafts: one draft on two devices. Each edit is queued and sent once. When two devices edited the same version, the page shows every open version and a person keeps one or writes a version using both. The server routes are in src/app.mjs (/api/drafts/:id). To try it, open the page in two browsers with the same demo user id, go offline in both, edit, and go back online.
test/drafts.mjs The drafts page's browser checks: two devices in two browser contexts, read back from the server's own log.
test/emergency.mjs The emergency page's browser checks, against the server's own list of messages.
test/scenarios.mjs The checks above, run in Chromium on every pull request against this page and the React version. They count the server's notes, not what the page shows.

Demo shortcuts

Licence

Apache-2.0

Edit this page on GitHub