Rebasely Beta: data may be purged

examples/live-notes Public

Markdown · 35 lines · 1.4 KiB · at 27f140d

---id: wire-protocoltype: conceptowner: justinreviewed: 2026-10-13component: opsdescribes:  - src/protocol.ts---# Wire protocolEditors and a room exchange JSON text frames over the WebSocket at `/notes/:id/ws`. Versionsare the room's: the number of ops it has applied to the note.From an editor:```json{ "type": "op", "base": 41, "op": { "type": "insert", "pos": 4, "text": "oat " } }{ "type": "op", "base": 41, "op": { "type": "delete", "pos": 0, "count": 3 } }```From the room:| type       | fields            | when                                                      || ---------- | ----------------- | --------------------------------------------------------- || `snapshot` | `text`, `version` | on connect, and when an editor's op can't be used         || `ack`      | `version`         | your op was applied, or turned out to change nothing      || `op`       | `version`, `op`   | someone else's op, already transformed, at that version   || `error`    | `message`         | the frame was not an op message                           |`parseClientMessage()` checks every field and copies only the ones it knows, so a frame withextra fields still works and a malformed one is answered with `error` and changes nothing.An editor sends its next op only after the ack for the previous one; see [[conflict-strategy]]for why that keeps the room's job simple.