Skip to content

Index a subtree that joins or leaves a tree the session owns - #18

Merged
ww-mw merged 2 commits into
mainfrom
index-subtree
Sep 9, 2026
Merged

Index a subtree that joins or leaves a tree the session owns#18
ww-mw merged 2 commits into
mainfrom
index-subtree

Conversation

@ww-mw

@ww-mw ww-mw commented Sep 9, 2026

Copy link
Copy Markdown
Member

A node id is a live getter over the node's path, so a subtree that is attached or detached silently rekeys every node inside it. mutateSubtree already repaired the index for an in-place edit; these two helpers cover the other two cases.

  • indexSubtree(root) — after attaching a subtree, flatten it and register every id.
  • unindexSubtree(root, detach?) — read the ids while still attached, run the detach inside a try, then delete the ids and release their selection in finally. Reading before and deleting after is the only order that works.

Why now

A consumer repainting one entry of a dictionary rather than re-parsing the whole file has to keep the index honest itself: the wide re-parse used to repair it as a side effect. Without these, findNodeById stops resolving the very rows the repaint just painted, and the next edit on one of them fails to locate its node.

Tests

test/indexSubtree.test.ts — both directions, the read-before/delete-after ordering, a subtree with children, and the selection release. Full suite green (131 files, 4101 passed, 26 skipped); tsc --noEmit and scripts/leak-check.mjs clean.

The version bump to 1.11.0 is the second commit, as usual.

mutateSubtree covers an edit INSIDE a subtree that is attached on both sides of
the change. A host that edits nodes directly also adds and removes WHOLE entries
— a paste, a delete, and each one's undo — and that shape has no before/after
pair to diff: the nodes either did not exist yet, or are about to stop existing.

So: indexSubtree(root) after attaching, unindexSubtree(root, detach) before
removing. The second takes the detach as a callback because an id is a PATH,
which makes the ordering part of the contract instead of a comment: the ids have
to be read while the subtree is still attached, or the index goes on handing out
an entry that has left the tree and the next edit routed at that row mutates an
orphan. It releases the selection over the whole subtree for the same reason
mutateSubtree releases it over the nodes an edit dropped.

Tests cover both directions, the ordering, a subtree with children, and the
selection release.
@ww-mw
ww-mw merged commit 7043c85 into main Sep 9, 2026
1 check passed
@ww-mw
ww-mw deleted the index-subtree branch September 9, 2026 15:03
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