Skip to content

Commit 635cb96

Browse files
committed
add failing test for nested update corruption
1 parent 2f093c6 commit 635cb96

File tree

1 file changed

+71
-0
lines changed

1 file changed

+71
-0
lines changed

packages/lexical-react/src/__tests__/unit/Collaboration.test.ts

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -526,4 +526,75 @@ describe('Collaboration', () => {
526526
client1.stop();
527527
client2.stop();
528528
});
529+
530+
it('should correctly sync if an update is triggered by a mutation listener', async () => {
531+
const connector = createTestConnection();
532+
const client1 = connector.createClient('1');
533+
const client2 = connector.createClient('2');
534+
client1.start(container!);
535+
client2.start(container!);
536+
537+
await expectCorrectInitialContent(client1, client2);
538+
539+
await new Promise((resolve) => setTimeout(resolve, 1050));
540+
541+
await waitForReact(() => {
542+
client1.update(() => {
543+
$getRoot()
544+
.clear()
545+
.append(
546+
$createParagraphNode().append($createTextNode('hello')),
547+
$createParagraphNode().append($createTextNode('world')),
548+
$createParagraphNode().append($createTextNode('foo')),
549+
);
550+
});
551+
});
552+
553+
await new Promise((resolve) => setTimeout(resolve, 1050));
554+
555+
const editor = client1.getEditor();
556+
557+
editor.registerMutationListener(ParagraphNode, (mutations) => {
558+
const destroyed = [...mutations.values()].some(
559+
(mutation) => mutation === 'destroyed',
560+
);
561+
if (destroyed) {
562+
editor.update(() => {
563+
$getRoot().append(
564+
$createParagraphNode().append($createTextNode('bar')),
565+
);
566+
});
567+
}
568+
});
569+
570+
editor.registerMutationListener(ParagraphNode, () => {
571+
// Force pending updates from the nested editor.update to be committed.
572+
editor.read(() => $getRoot());
573+
});
574+
575+
await waitForReact(() => {
576+
client1.update(() => {
577+
$getRoot().splice(1, 1, []);
578+
});
579+
});
580+
581+
expect(client1.getHTML()).toEqual(
582+
'<p dir="ltr"><span data-lexical-text="true">hello</span></p>' +
583+
'<p dir="ltr"><span data-lexical-text="true">foo</span></p>' +
584+
'<p dir="ltr"><span data-lexical-text="true">bar</span></p>',
585+
);
586+
587+
await new Promise((resolve) => setTimeout(resolve, 1050));
588+
589+
await waitForReact(() => {
590+
client1.getEditor().dispatchCommand(UNDO_COMMAND, undefined);
591+
});
592+
593+
expect(client1.getHTML()).toEqual(
594+
'<p dir="ltr"><span data-lexical-text="true">hello</span></p>' +
595+
'<p dir="ltr"><span data-lexical-text="true">world</span></p>' +
596+
'<p dir="ltr"><span data-lexical-text="true">foo</span></p>' +
597+
'<p dir="ltr"><span data-lexical-text="true">bar</span></p>',
598+
);
599+
});
529600
});

0 commit comments

Comments
 (0)