fix: container-aware outgoing patches, uniform child field rule, and recursive normalization#2415
Closed
christianhg wants to merge 4 commits intomainfrom
Closed
fix: container-aware outgoing patches, uniform child field rule, and recursive normalization#2415christianhg wants to merge 4 commits intomainfrom
christianhg wants to merge 4 commits intomainfrom
Conversation
🦋 Changeset detectedLatest commit: 85210d4 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 (93a4f12) |
|---|---|---|
| Internal (raw) | 766.4 KB | +6.2 KB, +0.8% |
| Internal (gzip) | 144.2 KB | +1.2 KB, +0.9% |
| Bundled (raw) | 1.37 MB | +6.2 KB, +0.4% |
| Bundled (gzip) | 307.1 KB | +1.3 KB, +0.4% |
| Import time | 97ms | +2ms, +1.8% |
@portabletext/editor/behaviors
| Metric | Value | vs main (93a4f12) |
|---|---|---|
| Internal (raw) | 467 B | - |
| Internal (gzip) | 207 B | - |
| Bundled (raw) | 424 B | - |
| Bundled (gzip) | 171 B | - |
| Import time | 6ms | -0ms, -0.4% |
@portabletext/editor/plugins
| Metric | Value | vs main (93a4f12) |
|---|---|---|
| Internal (raw) | 2.5 KB | - |
| Internal (gzip) | 910 B | - |
| Bundled (raw) | 2.3 KB | - |
| Bundled (gzip) | 839 B | - |
| Import time | 12ms | +0ms, +1.9% |
@portabletext/editor/selectors
| Metric | Value | vs main (93a4f12) |
|---|---|---|
| Internal (raw) | 60.5 KB | - |
| Internal (gzip) | 9.5 KB | - |
| Bundled (raw) | 56.9 KB | - |
| Bundled (gzip) | 8.7 KB | - |
| Import time | 10ms | -0ms, -0.7% |
@portabletext/editor/utils
| Metric | Value | vs main (93a4f12) |
|---|---|---|
| Internal (raw) | 24.2 KB | - |
| Internal (gzip) | 4.7 KB | - |
| Bundled (raw) | 22.2 KB | - |
| Bundled (gzip) | 4.4 KB | - |
| Import time | 9ms | -0ms, -1.1% |
🗺️ . · ./behaviors · ./plugins · ./selectors · ./utils · Artifacts
Details
- Import time regressions over 10% are flagged with
⚠️ - Sizes shown as raw / gzip 🗜️. Internal bytes = own code only. Total bytes = with all dependencies. Import time = Node.js cold-start median.
d812174 to
5e23333
Compare
operation-to-patches with indexedPathToKeyedPathoperation-to-patches container-aware with indexedPathToKeyedPath
d676742 to
1a54577
Compare
operation-to-patches container-aware with indexedPathToKeyedPath1a54577 to
27328e6
Compare
2336bff to
a1cd7ba
Compare
a1cd7ba to
76e88fe
Compare
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.
Rewrites the outgoing patch pipeline (
operation-to-patches.ts) to handle containers at any nesting depth. The old code hardcoded two levels (block at depth 0, child at depth 1) and threw on anything deeper. The new code usesindexedPathToKeyedPathfor path conversion, walking the tree via the schema at each level. Each function takes aPatchContext(same shape as the traversal context:schema,editableTypes,value) and usesgetNodeandgetChildrenfrom the traversal layer for tree lookups.resolveParentFieldPathbuilds the keyed path to a node's parent including the schema-defined child field name, needed by insert patches to construct positional references.The one special case is
_keychanges insetNodePatch, which must use positional paths since you can't reference a node by a key that's about to change. This derives the positional prefix by slicing the full keyed path rather than walking the tree a second time.A second commit simplifies the
applySetNodechild field check: thetextskip now usesisSpandirectly instead of a roundaboutisTextBlockparent check, and thechildrenskip remains text-block-specific since container child fields must pass through to support incoming patches that setrows,cells, etc.The third commit enforces a uniform child field rule in
set_node: you cannot set any field that holds children, whether that'schildrenon a text block orrowson a table. Bothapply-operation.tsandapplySetNodenow resolve the child field name from the schema viaresolveChildFieldNameinstead of hardcodingchildren. This makes the rule consistent across text blocks and containers.The fourth commit adds recursive container normalization. When a container node has an empty or missing child array field, normalization builds the minimum valid structure from the schema in one pass. A table with no
rowsgets a row, which gets a cell, which gets a content block with a span. This works by recursively resolving child field definitions viaresolveChildArrayFieldByTypeand building the full tree before inserting. Themodify.tsutilities (modifyDescendant,modifyChildren) are also made container-aware so thatinsert_nodeandremove_nodeoperations can target paths inside containers.modifyDescendantno longer depends oneditableTypesfor traversal, using schema-resolved child fields directly instead.Container tests cover all five patch functions with a code block schema, the uniform child field rule with table set/unset operations, and normalization at every container depth (table, row, cell).
Note
All five outgoing patch functions now return empty arrays on failure instead of throwing. The editor runs in a racy DOM environment where transient path mismatches during React re-renders are normal, not bugs that should crash the component tree.