Skip to content

fix(plugin-sdk-value): guard keyed markDefs unsets against store-referenced definitions - #2984

Draft
christianhg wants to merge 1 commit into
mainfrom
fix-guard-keyed-markdefs-unsets
Draft

fix(plugin-sdk-value): guard keyed markDefs unsets against store-referenced definitions#2984
christianhg wants to merge 1 commit into
mainfrom
fix-guard-keyed-markdefs-unsets

Conversation

@christianhg

Copy link
Copy Markdown
Member

Preparatory extraction from #2982, which changes the editor to emit normalization's unused-annotation-definition prunes as item-keyed unset patches instead of whole-array markDefs sets. Under that emission, a client that has diverged from the store (its span marks overwritten by another client's flush, its own definition now locally unused) prunes a definition the store's spans still reference. toMergeableMarkDefsPatches only decomposes whole-array sets, so the keyed unset passed through without the referenced-keys guard and orphaned the other client's annotation at the server; the collision-matrix link scenarios in this package caught exactly that (orphan mark (no markDef)) when run against #2982's emission.

Keyed markDefs unsets now route through the same store-side referenced-keys check as decomposed whole-array sets, and are dropped while the store's spans reference the definition. A dropped prune leaves an unused definition behind at worst, which normalization in a later converged session removes for real, strictly better than a dangling mark.

This lands and releases ahead of #2982 because of the published peer range: the plugin's ^7.x peer accepts an editor with the new emission, so a consumer upgrading @portabletext/editor without upgrading this plugin would run the orphan race with no guard. Shipping the guard first closes that window. Against current editor releases the new branch is inert (keyed markDefs unsets don't occur), which is also why all suites here pass unchanged on main's emission; the collision-matrix runs that exercise the guard live in #2982, which stacks on this.

@vercel

vercel Bot commented Jul 20, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
portable-text-editor-documentation Ready Ready Preview, Comment Jul 21, 2026 8:32am
portable-text-example-basic Ready Ready Preview, Comment Jul 21, 2026 8:32am
portable-text-playground Ready Ready Preview, Comment Jul 21, 2026 8:32am

Request Review

@changeset-bot

changeset-bot Bot commented Jul 20, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 867129c

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@portabletext/plugin-sdk-value Patch

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

@github-actions

github-actions Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

📦 Bundle Stats — @portabletext/editor

Compared against main (04b79737)

@portabletext/editor

Metric Value vs main (04b7973)
Internal (raw) 804.0 KB -
Internal (gzip) 154.3 KB -
Bundled (raw) 1.41 MB -
Bundled (gzip) 318.6 KB -
Import time 107ms +5ms, +5.3%

@portabletext/editor/behaviors

Metric Value vs main (04b7973)
Internal (raw) 467 B -
Internal (gzip) 207 B -
Bundled (raw) 424 B -
Bundled (gzip) 171 B -
Import time 2ms +0ms, +2.9%

@portabletext/editor/plugins

Metric Value vs main (04b7973)
Internal (raw) 2.7 KB -
Internal (gzip) 894 B -
Bundled (raw) 2.5 KB -
Bundled (gzip) 827 B -
Import time 7ms +0ms, +2.3%

@portabletext/editor/selectors

Metric Value vs main (04b7973)
Internal (raw) 81.8 KB -
Internal (gzip) 15.2 KB -
Bundled (raw) 77.6 KB -
Bundled (gzip) 14.1 KB -
Import time 8ms -0ms, -0.1%

@portabletext/editor/traversal

Metric Value vs main (04b7973)
Internal (raw) 28.1 KB -
Internal (gzip) 5.6 KB -
Bundled (raw) 28.1 KB -
Bundled (gzip) 5.5 KB -
Import time 6ms -0ms, -1.4%

@portabletext/editor/utils

Metric Value vs main (04b7973)
Internal (raw) 29.7 KB -
Internal (gzip) 6.2 KB -
Bundled (raw) 27.4 KB -
Bundled (gzip) 5.9 KB -
Import time 6ms -0ms, -1.2%

🗺️ . · ./behaviors · ./plugins · ./selectors · ./traversal · ./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.

📦 Bundle Stats — @portabletext/markdown

Compared against main (04b79737)

Metric Value vs main (04b7973)
Internal (raw) 53.8 KB -
Internal (gzip) 9.8 KB -
Bundled (raw) 348.9 KB -
Bundled (gzip) 96.3 KB -
Import time 42ms +1ms, +3.4%

🗺️ View treemap · 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.

…ferenced definitions

An upcoming editor change emits normalization's unused-definition
prunes as item-keyed `unset` patches instead of whole-array sets.
`toMergeableMarkDefsPatches` only decomposes whole-array sets, so
those unsets would pass through without the referenced-keys guard: a
diverged client (its span `marks` overwritten by the other client's
flush, its own definition now locally unused) would prune a definition
the store's spans still reference, orphaning the other client's
annotation at the server.

Keyed `markDefs` unsets now go through the same store-side
referenced-keys check as decomposed sets and are dropped while the
store's spans reference the definition. A dropped prune leaves an
unused definition behind at worst; normalization in a later converged
session removes it for real. Against the current editor's emission
(whole-array sets only) the guard is inert; it ships ahead so a
consumer upgrading the editor without upgrading this plugin is never
exposed.
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