System overview
datadata is a library with a clean client/server split. An application talks to it through a session, and two deliberate extension points — the event bus and the storage adapter — decide where and how it runs.
┌────────────────┐│ session │ the app-facing API:│ live / staging │ reads, writes, presence└───────┬────────┘ │┌───────▼────────┐ ┌─────────────────┐│ client │◄───────►│ event bus │ WebSocket / in-process│ (optimistic │ events │ ││ overlay) │ └────────┬────────┘└───────┬────────┘ │ │ ┌────────▼────────┐ │ journal + cache │ server │ │ │ (authoritative) │┌───────▼────────┐ └────────┬────────┘│ persistence │ ││ adapter │ ┌────────▼────────┐│ (IndexedDB/mem)│ │ storage adapter ││ optional, │ │ (SQLite / mem) ││ shared by tabs │ └─────────────────┘└────────────────┘The parts
Section titled “The parts”- Session — what the application actually holds. Every read and write goes through one, in one of two kinds: a live session writes straight through, a staging session accumulates a changeset to commit. Both expose the same document API — prepare a document, read it, write it, publish presence — so an app switches lanes without rewriting its call sites. Framework bindings like the React integration hand you a session too.
- Client — one per connection, shared by the sessions layered on it. Owns subscriptions and the optimistic overlay, and speaks the protocol; a session’s writes land here before they reach the wire.
- Server — the authority for one folder: validates against schemas, assigns sequence numbers, persists, broadcasts. Enforces limits (document size, rates) and exposes a change callback for automation.
- Event bus — routes protocol events between clients and server. Implementations: WebSocket (production), in-process (server-side agents, tests, demos), and a composite that combines both on one server.
- Storage adapter — persistence behind the server: documents, the event log, and Yjs state. The production implementation is SQLite in a Durable Object; tests use memory.
- Persistence adapter — the storage adapter’s client-side counterpart, and optional: the pending-write journal and the document cache that let a reload replay its writes and render offline. IndexedDB in browsers, memory in tests. Without one the client is memory-only. See offline persistence.
Tabs on the same (folder, principal) namespace share a persistence adapter,
so two offline tabs converge with no server round-trip — the only path in this
architecture where clients exchange data without the server.
Where it runs today
Section titled “Where it runs today”The current production shape is Cloudflare Workers + Durable Objects: one Durable Object per folder, embedding the server, its storage, and its WebSocket connections. The extension points exist precisely so that this is a deployment choice, not an identity — but Cloudflare is the only backend that exists today.