fix: emit post-normalize snapshot in mutation events#2533
Open
christianhg wants to merge 1 commit into
Open
Conversation
🦋 Changeset detectedLatest commit: 5832724 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 (9fd84fd) |
|---|---|---|
| Internal (raw) | 729.1 KB | +183 B, +0.0% |
| Internal (gzip) | 138.2 KB | +25 B, +0.0% |
| Bundled (raw) | 1.32 MB | +183 B, +0.0% |
| Bundled (gzip) | 299.1 KB | +25 B, +0.0% |
| Import time | 94ms | -0ms, -0.1% |
@portabletext/editor/behaviors
| Metric | Value | vs main (9fd84fd) |
|---|---|---|
| Internal (raw) | 467 B | - |
| Internal (gzip) | 207 B | - |
| Bundled (raw) | 424 B | - |
| Bundled (gzip) | 171 B | - |
| Import time | 2ms | +0ms, +0.5% |
@portabletext/editor/plugins
| Metric | Value | vs main (9fd84fd) |
|---|---|---|
| Internal (raw) | 3.1 KB | - |
| Internal (gzip) | 967 B | - |
| Bundled (raw) | 2.9 KB | - |
| Bundled (gzip) | 899 B | - |
| Import time | 8ms | -0ms, -1.0% |
@portabletext/editor/selectors
| Metric | Value | vs main (9fd84fd) |
|---|---|---|
| Internal (raw) | 60.5 KB | - |
| Internal (gzip) | 9.6 KB | - |
| Bundled (raw) | 57.0 KB | - |
| Bundled (gzip) | 8.7 KB | - |
| Import time | 6ms | -0ms, -0.0% |
@portabletext/editor/utils
| Metric | Value | vs main (9fd84fd) |
|---|---|---|
| Internal (raw) | 24.2 KB | - |
| Internal (gzip) | 4.7 KB | - |
| Bundled (raw) | 22.2 KB | - |
| Bundled (gzip) | 4.4 KB | - |
| Import time | 6ms | +0ms, +0.6% |
🗺️ . · ./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.
4259772 to
4a365a0
Compare
When the editor became empty (for example by deleting the only block), normalization synthesized a fresh placeholder block to preserve the empty-tree invariant. The synth runs under `withoutPatching`, so it does not emit a patch. Meanwhile, mutation bulks captured their `value` snapshot per-patch at emit time, meaning the final bulk recorded `editor.children` as `[]` from the last user unset and never saw the synthesized placeholder. Consumers receiving that mutation event saw `value: []`, would call `clearEditor` or broadcast the empty value back to the editor, and subsequent undo attempts failed because the history was wiped or the round-trip inserted a differently-keyed placeholder that did not match the inverse of the original delete. The fix is to capture the final bulk's snapshot from live `editor.children` at flush time rather than per-patch at emit time. By the time the mutation-machine flushes, any in-flight `withoutNormalizing` transaction has unwound and normalization has settled, so the live children accurately reflect the post-normalize state. Earlier pending bulks keep their in-sequence snapshots; only the final bulk is updated, because that is where a patch-less synth lands.
4a365a0 to
5832724
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.
When the editor became empty (for example by deleting the only block), normalization synthesized a fresh placeholder block to preserve the empty-tree invariant. The synth runs under
withoutPatching, so it does not emit a patch. Meanwhile mutation bulks captured theirvaluesnapshot per-patch at emit time, so the final bulk recordededitor.childrenas[]from the last user unset and never saw the synthesized placeholder.Consumers receiving that mutation event saw
value: [], would callclearEditoror broadcast the empty value back to the editor, and subsequent undo attempts failed because the history was wiped or the round-trip inserted a differently-keyed placeholder that did not match the inverse of the original delete.The fix is to capture the final bulk's snapshot from live
editor.childrenat flush time rather than per-patch at emit time. By the time the mutation-machine flushes, any in-flightwithoutNormalizingtransaction has unwound and normalization has settled, so the live children accurately reflect the post-normalize state. Earlier pending bulks keep their in-sequence snapshots; only the final bulk is updated, because that is where a patch-less synth lands.Regression tests exercise the scenario end-to-end: delete the only block, wait for the mutation debounce, assert the emitted mutation carries a post-normalize value, feed that value back in as an
update value, undo, and expect the original content back.