-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[lexical-yjs] Bug Fix: Fix text duplication bug in collaborative editors #6374
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
size-limit report 📦
|
btw, it possible to replicate this with https://stackblitz.com/github/facebook/lexical/tree/fix/collab_example/examples/react-rich-collab?file=src%2FApp.tsx simplescreenrecorder-2024-07-05_16.50.24.mp4this makes the desync more obvious. also you'll notice at the end that the text also does get duplicated, just not as severely as in our reproduction as it seems to get cut off at 3 characters |
I've put together a very minimal repro project here using Lexical 0.16.1: https://github.com/moughxyz/lexical-yjs-bug StepsBootstrap
Bug
Please see video of the result: repro-video.mov |
@fantactuka or @StyleT could probably comment more |
With some more testing, we've managed to figure out that to fix this issue in both of these scenarios, these lines (https://github.com/facebook/lexical/pull/6374/files#diff-faeb2a44b10d1affd1808827e738984026ed388ce861f20f18d498fa64a8bfe2R129-R133) need to be removed completely, and not just moved below like we do in this PR. @etrepum Since these changes were introduced in this PR, could you add some insight as to why these changes were necessary? When we remove that code so that no new paragraph is added, everything still seems to function correctly. Having that code there seems to cause the Yjs tree to get out of sync for whatever reason. Maybe we can add a |
I've updated the fix according to my comment above, and also added a unit test in Is there a way in the e2e tests to persist data after reload? That way I can also add an e2e test that simulates both manual typing and copy-pasting scenarios. |
I couldn’t tell you why the code is there, I just moved it from somewhere else because it seemed less likely to cause test failures in that spot. You’d have to follow the git blame further back to figure out who introduced it and why. |
I've created a followup PR that should be a little simpler, and hopefully more safely mergeable as it doesn't prevent the insertion of a paragraph altogether, but moves it to the appropriate location: I hope we can move forward with this, as it is a high priority item that causes permanent data loss in a very easy to replicate manner. |
#6523 covers this PR, closing this one. |
Description
When using collaboration with
shouldBootstrap
set to false, you start with an empty root. A paragraph is added when the user actually starts typing.However, it is possible to undo the creation of this initial paragraph. A new empty paragraph is indeed created, but that is not correctly reflected in the Yjs tree. This causes a de-sync of the Lexical and Yjs trees, which then depending on what the user does can lead to either broken sync (some of the changes going missing) or text duplication (seen in the video below)
This issue has also been reported by other users in the Discord: https://discord.com/channels/953974421008293909/1240637271594762270/1240637271594762270
We noticed in our testing that even though the
syncYjsChangesToLexical
function creates a new paragraph if the root gets empty, the timing of the creation seems to be incorrect in a way where the Yjs tree won't be updated properly. Moving this logic to anothereditor.update()
call in theonUpdate
callback fixes this.Steps to replicate
shouldBootstrap
set to false, so that you start with an empty root. There needs to be persistence of the Ydoc for this to happenTest plan
Before
text-duplicaton-bug.mp4
After
text-duplication-fix.mp4