Skip to content

feat(webapp): the hub can write the document back to the file - #243

Merged
ssowonny merged 1 commit into
mainfrom
feat/hub-writes-the-file
Sep 20, 2026
Merged

ssowonny merged 1 commit into
mainfrom
feat/hub-writes-the-file

Conversation

@ssowonny

Copy link
Copy Markdown
Contributor

TL;DR

  • "Whoever stops typing last writes the file" is what a relay leaves you with — close every laptop at once and unsaved keystrokes are gone.
  • The hub holds the document now, so it can write it: on the last editor leaving, and on the room unloading.
  • A safety net, not a replacement. The browser still saves on idle, and the duplicate is free because identical content journals nothing (perf(webapp): saving the same bytes twice is not two versions #238).
  • Attributed to the human, never to the server.

What this actually adds

Not fewer versions — #238 already delivered that by making duplicate writes free. Durability. The one case no client can cover is every client going away at once, and until now that lost whatever hadn't reached the 700 ms idle save.

Two things it's careful about

Attribution. A version whose author is "the server" is a regression in History even when the server is holding the pen. The writer is recorded when their connection is authorized, and a room that nobody with write access ever joined writes nothing at all rather than guessing. Both pinned by tests.

The route in. The snapshot re-enters the API rather than calling the uploader directly, so quota, folder permissions, the no-op check, journaling and the change frame are all the same code every other write goes through. A second path into the file would be a second set of rules to keep in agreement — and they wouldn't stay agreed.

Also

Seeding moves from the persistence adapter to OnLoadDocument, which hands over the actual *crdt.Doc instead of encoded bytes — one fewer encode/decode round trip per room opened.

Tests

  • the snapshot lands, and History attributes it to the human who typed it
  • snapshotting text the file already holds adds no version
  • a room with no write-capable joiner writes nothing

Full module: 12 packages ok, zero failures.

🤖 Generated with Claude Code

"Whoever stops typing last writes the file" is what a relay leaves you with:
the document lives only between browsers, so the only machine that can save it
is one of the browsers. Close every laptop at once and whatever had not
reached the 700ms idle save is gone.

The hub holds the document now, so it can write it. On the last peer leaving
and on the room being unloaded, the text goes back to the file.

A SAFETY NET, not a replacement. The browser still saves on idle exactly as it
did, and that is not double-writing: identical content journals nothing
(#238), so whichever write lands second is free. What this adds is the case no
client can cover.

Two things it is careful about.

Attribution. A version whose author is "the server" is a regression in History
even when the server is holding the pen, so the snapshot is written AS the
human who was editing — recorded when their connection was authorized — and a
room that nobody with write access ever joined writes nothing at all rather
than guessing.

The route in. It re-enters the API instead of calling the uploader directly,
so quota, folder permissions, the no-op check, journaling and the change frame
are the same code every other write goes through. A second path into the file
would be a second set of rules to keep in agreement, and they would not stay
agreed.

Seeding moves from the persistence adapter to OnLoadDocument while here, which
hands over the actual document rather than encoded bytes — one fewer
encode/decode round trip on every room that opens.

Stage 3 of docs/collab-provider-prd.md. Full module: 12 packages ok.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@ssowonny
ssowonny merged commit adbc4e0 into main Sep 20, 2026
5 of 6 checks passed
@ssowonny
ssowonny deleted the feat/hub-writes-the-file branch September 20, 2026 08:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant