mirror of
https://github.com/storytold/figcraft.git
synced 2026-10-26 11:26:50 -06:00
94ff3d4df65b240dd2114598fecf14b722fa4eb4
4
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
94ff3d4df6 |
M9: collaboration: per-user undo, rejections, reconnect (#105)
* M9: collaboration: per-user undo, rejections, reconnect
Step 3 of docs/collab-protocol.md, the parts that don't need the transport:
- Per-user undo and redo (figcraft_collab::Client::{undo, redo}): each undoable batch is a step
(values before/after by target, nodes created/deleted). Others' batches ordered after the step
take its targets for good; creates invert to deletes (not when others built inside), deletes
re-create the subtree. An undo or redo waits for every earlier batch and is remade from the
confirmed state when it goes out; derived data follows as a follow-up batch.
- Rejections: refused batches leave the history (with an undo waiting on them) and queue a
Notice; the engine shows it through Session::message (the UI's toast).
- Offline queue and reconnect: Hello.resume {session, client_id, seq}; the server keeps a
bounded log and answers with the missed batches or a snapshot, plus what it did with the
client's batches (processed {last_batch, refused}); queued batches then go out.
Server::state / restore persist the session (client-id counter, log, session id).
- Presence carries editing_text {node, caret, selection}.
- Engine: documents in a live session (LiveDoc, Session::collab_*): commands, gestures and
groups sync as one step each; edit.undo / edit.redo route to the per-user history; remote
edits show under a gesture in progress. Outside a session snapshot undo is unchanged.
- Sim: dropped connections, undo/redo, and a checker that no undo reverts a change by someone
else its author had seen. New tests in undo_tests, reconnect_tests, collab_live_tests,
collab_undo_tests.
- CLAUDE.md / AGENTS.md: collab in the L2 layer list.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* M9: collaboration wording in the progress docs after per-user undo and reconnect
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* M9: protocol doc: what the engine's live-session tests cover
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
|
||
|
|
4d7a9187ff |
M9: live sessions: host from the app, invite links, live cursors and presence (#104)
* M9: real-time collaboration protocol (design) docs/collab-protocol.md: WebSocket sessions with a server-ordered, per-property last-writer-wins document sync, client-scoped ids, fractional positions for children, ephemeral presence (cursors, selections, follow), per-user undo, hosting from the app first and a self-hosted server next, and the implementation plan. ROADMAP gains M9. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * M9: collaboration core: ids, change sets, server ordering, convergence Step 1 of docs/collab-protocol.md, no networking: - Client-scoped node ids: Document::set_client_id makes alloc_id hand out client << 32 | counter; single-user files allocate as before; the id counter is no longer part of document equality. - crates/collab (layer 2): the synced object/property model (every saved Node field, plus document-level styles, comments, variables, images, dev snapshots, library data), Change batches, an O(changed) diff, strict and lenient apply, fractional sibling positions, snapshots. - Server (ordering, validation, rejects with fixes) and Client (optimistic view, replay under remote batches, author-side repair of derived data) as pure state machines; binary (version byte + postcard, JSON values) and JSON message forms, fuzzed decoders. - Engine: normalize as the recompute hook, collab.diff. - Tests: round trips over random real commands, an N-client convergence fuzz test over delayed in-order links, junk batches. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * M9: fmt after merge * M9: live sessions: host from the app, invite links, live cursors and presence Step 2 of docs/collab-protocol.md, networking and presence half: - crates/collab-net (layer 6): WebSocket transport (sync tungstenite, a reader and a writer thread per connection, no async runtime), the session host the app embeds (runs figcraft_collab::Server as the authority, carries its messages), invite links, presence throttling (~30 Hz, latest wins), limits (sockets, hello/idle timeouts, message size, rate, slow clients), keep-alive, clean close, reconnect with backoff; a browser stand-in until the web-sys client (step 4). - engine: live session state (status, peers, presence, follow) and the collab.host/stop/join/leave/peers/follow/cursor commands; the network is reached only through the LiveLink the app installs. - ui-egui: remote cursors (pointer drawn in code, name tag, gliding), selection outlines (once documents sync), avatars in the right panel with follow, the Share popover (start, invite link + URL with Copy, stop), File > Join live session. - desktop app and MCP headless session install the link; xtask layers keeps networking crates out of L0-L5. - Documents don't sync between apps yet (follow-up). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * M9: live sessions: document sync between apps - The host's session runs figcraft_collab::Server seeded with the shared document; every app (the host's too, through the hub without a socket) is a collab Client. Guests open the host's file from the welcome as a new tab; leaving keeps it as a local copy. - Engine: after each local action (a gesture once it ends; nothing during version or text previews) the session document is diffed into one Changes batch; server batches go through Client::receive with EngineRecompute and are installed with Session::apply_remote, which never touches the undo history. Batches arriving mid-gesture wait. - Transport: Changes/Reject/Welcome reach the engine as Event::Sync; LiveLink::send carries batches in order; hellos are limited to 64 KiB, joined clients to the core's message size. - Tests: engine sync against a real Server (ids in the client's space, one batch per gesture, remote edits skip undo, deferral, closing the file leaves), three apps over loopback converging (create, move, recolour, delete, rename) and a late joiner getting the server's state. - Docs: collab-protocol, mcp, README, roadmap docs; the UI's "cursors only" note is gone, replaced by the per-person undo caveat. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
4924512f4e |
M9: collaboration core: ids, change sets, server ordering, convergence (#103)
* M9: real-time collaboration protocol (design) docs/collab-protocol.md: WebSocket sessions with a server-ordered, per-property last-writer-wins document sync, client-scoped ids, fractional positions for children, ephemeral presence (cursors, selections, follow), per-user undo, hosting from the app first and a self-hosted server next, and the implementation plan. ROADMAP gains M9. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * M9: collaboration core: ids, change sets, server ordering, convergence Step 1 of docs/collab-protocol.md, no networking: - Client-scoped node ids: Document::set_client_id makes alloc_id hand out client << 32 | counter; single-user files allocate as before; the id counter is no longer part of document equality. - crates/collab (layer 2): the synced object/property model (every saved Node field, plus document-level styles, comments, variables, images, dev snapshots, library data), Change batches, an O(changed) diff, strict and lenient apply, fractional sibling positions, snapshots. - Server (ordering, validation, rejects with fixes) and Client (optimistic view, replay under remote batches, author-side repair of derived data) as pure state machines; binary (version byte + postcard, JSON values) and JSON message forms, fuzzed decoders. - Engine: normalize as the recompute hook, collab.diff. - Tests: round trips over random real commands, an N-client convergence fuzz test over delayed in-order links, junk batches. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * M9: fmt after merge --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
bc587ad28a |
M9: real-time collaboration protocol (design) (#98)
docs/collab-protocol.md: WebSocket sessions with a server-ordered, per-property last-writer-wins document sync, client-scoped ids, fractional positions for children, ephemeral presence (cursors, selections, follow), per-user undo, hosting from the app first and a self-hosted server next, and the implementation plan. ROADMAP gains M9. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |