Repository navigation
Conversation
A version transition collects the elements each delete op touches in a Set. Packed text spans return a new scalar view per lookup, so text that two peers deleted concurrently was collected once per delete. Restoring it emitted the text twice; removing it deleted twice from the event diff and could throw "event diff position N is out of range". Deduplicate the collected elements by ID before building the event. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Contributor
WASM Size Report
|
This was referenced Sep 27, 2026
Member
Author
|
Closing: covered by #1136 ( Checked on |
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
When several peers deleted the same text concurrently,
loro.jscheckout events were wrong. The document state was right.{ insert: "bccb" }instead of{ insert: "bc" }. With astral characters the doubled text also split surrogate pairs.event diff position 1 is out of range:This is the "
event diff position N is out of range" failure seen in random fuzzing, including on full-history documents.Rationale
#applyVersionTransitioncollects the elements touched by each delete op in aSet<SequenceElement>. Text stored in packed spans returns a new scalar view object per lookup, so an element deleted by two ops ends up in the set twice. The removal and insertion lists were computed from that set before any mutation, so both copies were emitted. Lists are unaffected because their elements are stable objects. The fix deduplicates the collected elements by ID before building the event.Validation
loro-js/tests/event-diff.test.ts: restoringbcanda😀b, and the restore+double-delete checkout. All three fail onmain. The expected events are whatloro-crdt(WASM build of thismain) emits for the same scenarios.pnpm --dir loro-js format:check,lint,typecheck,test(250 passed),build.bench:complexity(1k–8k), 5 alternating rounds vsmain, loadavg 9–10: 284 items, none both >1.5× and >0.3 ms slower. Total 1003 ms onmain, 954 ms here.🤖 Generated with Claude Code