-
-
Notifications
You must be signed in to change notification settings - Fork 738
Description
Please save me some time and use the following template. In 90% of all issues I can't reproduce the problem because I don't know what exactly you are doing, in which environment, or which y-* version is responsible. Just use the following template even if you think the problem is obvious.
Checklist
- Are you reporting a bug? Use github issues for bug reports and feature requests. For general questions, please use https://discuss.yjs.dev/
- Try to report your issue in the correct repository. Yjs consists of many modules. When in doubt, report it to https://github.com/yjs/yjs/issues/
Describe the bug
Undo-manager over arrays sometimes generates a wrong result when undoing.
To Reproduce
Run the following jest test:
import * as Y from "yjs";
it("undo should be ok", () => {
const doc = new Y.Doc();
const array = doc.getArray("array");
const undoManager = new Y.UndoManager(array, { captureTimeout: 0 });
doc.transact(() => {
array.insert(0, [1, 2, 3]);
});
// 1,2,3
expect(array.toJSON()).toEqual([1, 2, 3]);
doc.transact(() => {
array.insert(2, [6, 7]);
});
// 1,2,3
// 1,2,6,7,3
expect(array.toJSON()).toEqual([1, 2, 6, 7, 3]);
doc.transact(() => {
array.delete(1, 1);
array.insert(1, [8]);
});
// 1,2,3
// 1,2,6,7,3
// 1,8,6,7,3
expect(array.toJSON()).toEqual([1, 8, 6, 7, 3]);
doc.transact(() => {
array.delete(0, 1);
});
// 1,2,3
// 1,2,6,7,3
// 1,8,6,7,3
// 8,6,7,3
expect(array.toJSON()).toEqual([8, 6, 7, 3]);
doc.transact(() => {
array.delete(1, 2);
});
// 1,2,3
// 1,2,6,7,3
// 1,8,6,7,3
// 8,6,7,3
// 8,3
expect(array.toJSON()).toEqual([8, 3]);
undoManager.undo();
// 1,2,3
// 1,2,6,7,3
// 1,8,6,7,3
// 8,6,7,3
expect(array.toJSON()).toEqual([8, 6, 7, 3]);
doc.transact(() => {
array.insert(2, [9]);
});
// 1,2,3
// 1,2,6,7,3
// 1,8,6,7,3
// 8,6,7,3
// 8,6,9,7,3
expect(array.toJSON()).toEqual([8, 6, 9, 7, 3]);
undoManager.undo();
// 1,2,3
// 1,2,6,7,3
// 1,8,6,7,3
// 8,6,7,3
expect(array.toJSON()).toEqual([8, 6, 7, 3]);
undoManager.undo();
// 1,2,3
// 1,2,6,7,3
// 1,8,6,7,3
expect(array.toJSON()).toEqual([1, 8, 6, 7, 3]);
undoManager.undo();
// 1,2,3
// 1,2,6,7,3
expect(array.toJSON()).toEqual([1, 2, 6, 7, 3]);
undoManager.undo();
// 1,2,3
expect(array.toJSON()).toEqual([1, 2, 3]); // !! actually has 1,2,7,3
});Expected behavior
Undo manager should be able to go back to the first initial state, 1,2,3, but it goest to a weird 1,2,7,3 state instead. This is the minimal amount of operations I could find that trigger this error.
Environment Information
- Node 20.6.0
- Yjs version 13.6.27 and 14.0.0-8
Additional context
The problem with this kind of broken undo steps is that you never know exactly when they are going to trigger and it leaves you in a potentially corrupted state
- I'm a sponsor 💖
- This issue is a blocker for my project.