Each host owns one id: one room, one thread, one session. Clients attach to it by URL, like /rooms/ab12. Whatever runs your hosts makes sure every client of an id reaches the same instance, and starts one when the first client arrives.
Pick a runtime
| Runtime | Package | What you get |
|---|---|---|
| Cloudflare Durable Objects | @statewire/cloudflare | One object per id, worldwide. Hibernating WebSockets, state saved to object storage. |
| Pinboard, in Python | statewire, pinned | One object per id across your own workers. Restarts and deploys move objects without losing commands. |
| Your Node server | statewire/host-internal | A socket host you wire to any WebSocket or HTTP server, in a few lines. |
| The page itself | statewire | The host runs next to the client. Good for tests, demos and offline-first apps. |
The client doesn't change between them. Attach over WebSocket or over HTTP with server-sent events.
Cloudflare
A Durable Object is a natural Statewire host: one per id, single-threaded, with storage attached. statewireHandlers serves the WebSocket and HTTP routes and restores the state after the object wakes up. Riff runs every session this way.
Pinboard
In Python, a Statewire class is a Pinboard object. Pinboard places each id on one of your workers and moves it when a worker drains or dies. With a state store, admitted commands survive the move. Pinboard docs.
Your own server
StatewireSocketHost takes your host and speaks the protocol over any socket with send and close. Wire it to the WebSocket server you already run.