fix(quick-edit): stop RELOAD storms from cross-block index drift - #728
Merged
Conversation
createEditor looked up its target block by an exact data-prose-index match, but that index is a global ProseMirror position that shifts whenever an earlier block changes size. handleTransaction already re-shifts every other block's index for edits inside an already-open mini-editor, but createEditor -- the path taken the first time a block is touched by a remote edit -- never did, so the first remote edit to any not-yet-opened block left every later block's cached index stale. Eventually a SET_EDITOR_STATE would arrive with a cursorOffset matching nothing, and the portal gave up and asked the host to RELOAD (full body resend) -- unbounded, so a sustained editing burst from one collaborator could retrigger this indefinitely and peg the main thread. Fall back to findTextBlock's existing nearest-indexed-block lookup instead of giving up, the same drift-tolerant match findImageAtProseIndex already relies on for images. Added an exclude param so the fallback can't resolve to (and destructively replace) a different block's already-open .prosemirror-editor, and only copy the remote-cursor badge across on an exact match. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
anfibiacreativa
previously approved these changes
Sep 8, 2026
anfibiacreativa
left a comment
Member
There was a problem hiding this comment.
Approving to unblock but please follow-up
Normalize cursorOffset to Number in createEditor so the exact-match badge gate (a strict ===) can't silently fail if it ever arrives as a string. Add unit tests for findTextBlock covering the exact match, the nearest-block fallback, and the exclude case that keeps a drifted offset from resolving to an already-open .prosemirror-editor. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
anfibiacreativa
self-requested a review
September 8, 2026 12:05
anfibiacreativa
approved these changes
Sep 8, 2026
usman-khalid
approved these changes
Sep 8, 2026
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.
Summary
In the quick-edit WYSIWYG plugin,
createEditorlooked up a block's DOM element by an exactdata-prose-indexmatch. When a concurrent remote edit to an earlier block shifted every downstreamdata-prose-index(without a fullSET_BODYre-index —createEditordoesn't runupdateInstrumentationthe wayhandleTransactiondoes), that exact lookup missed and the mini-editor fell back to postingRELOAD, i.e. an unbounded full-body resync per message. Under multi-user editing this became a storm that pegged the main thread rebuilding the instrumented HTML.Fix: on a miss, fall back to the nearest indexed block at-or-before
cursorOffset— the same drift-tolerant lookupfindImageAtProseIndexalready uses for images — instead of forcing aRELOAD.findTextBlock/findNearestIndexedgain anexcludeparam so the fallback can't steal a different block's already-open.prosemirror-editor, and the remote-cursor badge is only copied on an exact match.Pairs with da-live PR adobe/da-live#1302 (host-side fixes for the same multi-user editing investigation).
Test plan
🤖 Generated with Claude Code