feat: add BlockPathMap with incremental updates#2336
Draft
christianhg wants to merge 3 commits intomainfrom
Draft
feat: add BlockPathMap with incremental updates#2336christianhg wants to merge 3 commits intomainfrom
christianhg wants to merge 3 commits intomainfrom
Conversation
🦋 Changeset detectedLatest commit: 2ea7685 The changes in this PR will be included in the next version bump. This PR includes changesets to release 11 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
📦 Bundle Stats —
|
| Metric | Value | vs main (d312abd) |
|---|---|---|
| Internal (raw) | 812.2 KB | +11.1 KB, +1.4% |
| Internal (gzip) | 153.2 KB | +2.9 KB, +1.9% |
| Bundled (raw) | 1.42 MB | +11.2 KB, +0.8% |
| Bundled (gzip) | 316.2 KB | +2.9 KB, +0.9% |
| Import time | 103ms | -0ms, -0.2% |
@portabletext/editor/behaviors
| Metric | Value | vs main (d312abd) |
|---|---|---|
| Internal (raw) | 467 B | - |
| Internal (gzip) | 207 B | - |
| Bundled (raw) | 424 B | - |
| Bundled (gzip) | 171 B | - |
| Import time | 6ms | +0ms, +0.0% |
@portabletext/editor/plugins
| Metric | Value | vs main (d312abd) |
|---|---|---|
| Internal (raw) | 2.5 KB | - |
| Internal (gzip) | 910 B | - |
| Bundled (raw) | 2.3 KB | - |
| Bundled (gzip) | 839 B | - |
| Import time | 13ms | +0ms, +2.8% |
@portabletext/editor/selectors
| Metric | Value | vs main (d312abd) |
|---|---|---|
| Internal (raw) | 60.2 KB | - |
| Internal (gzip) | 9.4 KB | - |
| Bundled (raw) | 56.7 KB | - |
| Bundled (gzip) | 8.6 KB | - |
| Import time | 11ms | +0ms, +0.6% |
@portabletext/editor/utils
| Metric | Value | vs main (d312abd) |
|---|---|---|
| Internal (raw) | 24.2 KB | - |
| Internal (gzip) | 4.7 KB | - |
| Bundled (raw) | 22.2 KB | - |
| Bundled (gzip) | 4.4 KB | - |
| Import time | 10ms | +0ms, +0.4% |
Details
- Import time regressions over 10% are flagged with
⚠️ - Treemap artifacts are attached to the CI run for detailed size analysis
- Sizes shown as raw / gzip 🗜️. Internal bytes = own code only. Total bytes = with all dependencies. Import time = Node.js cold-start median.
96b4f53 to
e7fd100
Compare
e7fd100 to
a2509cb
Compare
Containers are identified by a Set<string> on EditorContext, not the schema package. Field discovery uses schema.blockObjects with recursive of-definition resolution. getNextBlock/getPrevBlock treat containers as opaque cursor stops. getFirstLeaf/getLastLeaf provide explicit container entry. BlockPathMap.rebuild() recurses into container fields when provided.
b83aa6f to
2456f86
Compare
…th arrays Add 11 tests for getFirstLeaf and getLastLeaf covering leaf blocks, deep container traversal, intermediate containers, and mixed content. Return a copy from blockPathMap.get() to prevent callers from seeing stale data after in-place mutations from incremental updates.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR adds two foundational pieces for container support: a
BlockPathMapfor O(1) block lookup by key-path, and traversal utilities for navigating nested document structures.BlockPathMap
A flat
Map<string, number[]>that maps serialized key-paths to positional paths. For a block atvalue[1].rows[0].cells[2], the key-path is"table-key.row-key.cell-key"and the positional path is[1, 0, 2].The map is built once on init and updated incrementally as Slate operations come in. Text and selection operations are zero-cost (no map update needed). Structural operations (insert, remove, split, merge, move) update only the affected entries and shift siblings.
Performance on a 5,100-entry document (100 containers x 50 children): build 42ms, lookup 0.003ms, insert 0.008ms, remove 0.006ms.
Traversal utilities
Twelve functions for navigating the document tree, exposed on
EditorSnapshot:Structural:
getNode,getParent,getChildren,getNextSibling,getPrevSibling,getAncestorsCursor-order:
getNextBlock,getPrevBlock,getFirstLeaf,getLastLeafConvenience:
isNested,getDepth,isDescendantOf,getContainingContainerContainers are identified by a
Set<string>onEditorContext- an editor concern, not a schema concern.getNextBlock/getPrevBlocktreat containers as opaque cursor stops, returning the container itself rather than descending into it. Behavior authors usegetFirstLeaf/getLastLeafto explicitly enter a container.Field discovery uses the existing
schema.blockObjectsfield definitions with recursiveof-definition resolution - a table's row type is found inside the table's field definitions, a cell inside the row's. No changes to@portabletext/schema.What this enables
These are the building blocks for container navigation behaviors. A backspace behavior at the start of a text block can call
getPrevBlockto find the preceding container, then decide whether to delete it or navigate into it. Arrow key behaviors can usegetNextBlock/getPrevBlockfor document-order movement andgetFirstLeaf/getLastLeaffor container entry.No public API impact beyond the additive
containers: Set<string>onEditorContext. No changes to patches emitted. The test suite (129 new tests) validates both the map operations and all traversal patterns on deeply nested documents.