Skip to content

v0.8.0 — Collaborative Editing (CRDT)

Choose a tag to compare

@Fiyy Fiyy released this 04 Jun 03:46
· 16 commits to main since this release

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)

  • Commutativityapply(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.py with 7 collab endpoints + --collab flag
  • 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 --collab is 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 .grid file remains the source of truth, so gridlang 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