Undo-manager over arrays sometimes generates a wrong result when undoing.
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
});
Checklist
Describe the bug
Undo-manager over arrays sometimes generates a wrong result when undoing.
To Reproduce
Run the following jest test:
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
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