githubnext/chopinPublic

Let's compose rich plans together

Make the plan collaborative and durable

Each room now owns a Y.Doc with a headless Lexical mirror bound to it, which is
what lets the server validate an update rather than relay bytes it cannot read.
Updates are grouped for five milliseconds, applied together, acknowledged to
their sender and relayed to everyone else. The document is attached on the
first open, so a room nobody has looked at costs a map entry.

Yjs cannot undo a transaction, so a batch that leaves the document invalid
cannot be rolled back. The document is rebuilt from its last known-good state
under a fresh epoch and everyone re-opens; senders of a rejected batch are
charged a strike and disconnected on the third within ten minutes.

Persistence is canonical MDX plus a small JSON sidecar, debounced on an idle
gap with a ceiling so continuous typing cannot postpone it forever. Yjs history
is deliberately not kept: it would buy undo across a restart at the price of a
binary checkpoint that could disagree with the source. A restart therefore
resumes the content under a new epoch.

Because that file is one a person can edit between runs, it is validated on the
way back in. Lexical routes anything thrown inside an update to onError, which
logs — so seeding carries its failure out by hand, or a corrupt snapshot would
open as a silently empty plan.

Empty rooms are evicted after a grace period rather than immediately, since a
reload is a departure followed by an arrival, and nothing is written to disk
until a plan has content.
KCKrzysztof Cieslak authored
5a39508Patch
Parente628de3
13 files changed+1729-17
StackedSplit
apps/server/package.json+7 −1
apps/server/src/main.ts+81 −5
apps/server/src/plan.test.ts+352 −0
apps/server/src/plan/presence.ts+104 −0
apps/server/src/plan/room.test.ts+234 −0
apps/server/src/plan/room.ts+323 −0
apps/server/src/plan/service.ts+289 −0
apps/server/src/plan/snapshot.ts+150 −0
apps/server/src/rooms.ts+30 −8
apps/server/tsconfig.json+5 −1
bun.lock+8 −0
packages/protocol/index.d.ts+4 −2
packages/protocol/plan.d.ts+142 −0