v0.8.0 — Collaborative Editing (CRDT)
v0.8.0 — Collaborative editing (CRDT)
The final item in the v2.0 roadmap (§15). Multiple browser tabs (or peers on the same network) can now edit the same .grid file at the same time; operations converge via a per-cell LWW CRDT keyed by Hybrid Logical Clock timestamps.
Try it
gridlang serve dashboard.grid --collab --edit
# Open http://localhost:8080 in two browser tabs.
# Edit a cell in tab A → within ~700ms the value appears (and flashes blue) in tab B.
# Edit the same cell in both tabs at once → the higher-HLC write wins on every replica.Architecture (3 small modules, ~700 lines)
| Module | Role |
|---|---|
gridlang.crdt |
HLC clocks + LWW per-cell Document + version vectors |
gridlang.collab |
CollabSession — peers, persistence, sync |
gridlang.collab_client |
Self-contained ~250-line browser JS |
Wire protocol — JSON over HTTP
POST /api/collab/join { peer_id? } → { peer_id, site_id, ops, version }
POST /api/collab/leave { peer_id }
POST /api/collab/op { peer_id, cell, value, sheet? } → { op, version }
POST /api/collab/poll { peer_id, since: vv } → { ops, version, peer_count }
GET /api/collab/snapshot → { site_id, ops, version }
GET /api/collab/stats → { cells, journal, peers, version }
GET /api/collab/client.js → IIFE that joins + polls + applies
Version vector vv is {site_id: [wall_ms, logical]} — each peer summarizes "what I've seen from each replica" in O(sites) space.
Convergence guarantees (proven by tests/test_crdt.py)
- Commutativity —
apply(a) ∘ apply(b) ≡ apply(b) ∘ apply(a) - Idempotence — applying the same op twice is a no-op
- Random-permutation property — 10 random permutations of an op set yield byte-identical state on all replicas
What changed
- Added
gridlang/crdt.py,gridlang/collab.py,gridlang/collab_client.py - Extended
gridlang/server.pywith 7 collab endpoints +--collabflag - Added
examples/12_collab.grid(multi-peer demo) spec/SPEC.md§21 — full protocol, data model, convergence proof sketch, programmatic API- §15 marks the roadmap item DONE
README.md— collab section, updated CLI docs- 64 new tests; 442 total (was 378)
Backward compatibility
- When
--collabis off (the default), all/api/collab/*endpoints return 404. The single-user editor (gridlang serve --edit) is unchanged. - When on, the v0.5 contenteditable cells and
bind:widgets keep working — they just commit through the CRDT layer instead of/api/cell-edit. The on-disk.gridfile remains the source of truth, sogridlang run/render/ exports always see the merged values.
Out of scope for v0.8 (planned for v0.9+)
- Inserting / deleting rows or columns concurrently — would need an RGA layer beneath cell ops
- Federation between independent servers — current implementation is single-server
- Auth — protocol assumes peers on a trusted network
🎉 The v2.0 roadmap is now complete — multi-sheet (v0.2), Chart DSL (v0.3), Remote Data (v0.4), Reactive Bindings (v0.5), JavaScript Engine (v0.6), JS Bundles & Extended API (v0.7), and now Collaborative Editing (v0.8).
🤖 Generated with Claude Code