Canvas structural merge over disk #45

Closed
opened 2026-09-21 18:03:44 +01:00 by cruelacid · 1 comment
Owner

Part of #37. Depends on the structured file kind.

What Relay does

Real-time CRDT merge within the board — nodes and edges merged individually
rather than whole-file last-writer-wins. Graduated from beta and enabled by
default in 0.8.12
(9 Sep 2026), free on every tier including Free.
(docs.relay.md/how-relay-works/canvas-collaboration/, read 21 Sep 2026.)

What we do today

.canvas is a blob: last-writer-wins with a visible conflict copy. Two people
moving different nodes produces a conflict, not a merge.

What changes

A canvas is JSON with nodes and edges. Model them as Y.Map/Y.Array inside
the file's own Y.Doc and serialise to disk on change: two people moving different
nodes both win, and Obsidian reloads the file.

Deliberately over disk, not in the view. This closes the honest part of the
gap without touching Obsidian's undocumented leaf.view.canvas internals. Live
in-view multiplayer is tracked separately and is a decision with ongoing upkeep,
not something this issue implies.

Risk

risk:none. No server change.

Verification

Two vaults move different nodes concurrently; both survive. Then the case that
matters more: two vaults edit the same node, and the result is either a clean
merge or a visible conflict copy — never a canvas that opens wrong. Per
CLAUDE.md, data safety beats convergence.

Part of #37. Depends on the `structured` file kind. ## What Relay does Real-time CRDT merge *within* the board — nodes and edges merged individually rather than whole-file last-writer-wins. **Graduated from beta and enabled by default in 0.8.12** (9 Sep 2026), free on every tier including Free. (`docs.relay.md/how-relay-works/canvas-collaboration/`, read 21 Sep 2026.) ## What we do today `.canvas` is a blob: last-writer-wins with a visible conflict copy. Two people moving different nodes produces a conflict, not a merge. ## What changes A canvas is JSON with `nodes` and `edges`. Model them as `Y.Map`/`Y.Array` inside the file's own Y.Doc and serialise to disk on change: two people moving different nodes both win, and Obsidian reloads the file. **Deliberately over disk, not in the view.** This closes the honest part of the gap without touching Obsidian's undocumented `leaf.view.canvas` internals. Live in-view multiplayer is tracked separately and is a decision with ongoing upkeep, not something this issue implies. ## Risk `risk:none`. No server change. ## Verification Two vaults move different nodes concurrently; both survive. Then the case that matters more: two vaults edit the *same* node, and the result is either a clean merge or a visible conflict copy — never a canvas that opens wrong. Per `CLAUDE.md`, data safety beats convergence.
Author
Owner

Moved to the Vikunja board as NEC-22: https://projectron.nerchure.com/tasks/22

Moved to the Vikunja board as **NEC-22**: https://projectron.nerchure.com/tasks/22
Sign in to join this conversation.
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Nectenda/nectenda#45
No description provided.