From 8d2862b41448c3170c6fdea28cb5659af9ce0fc7 Mon Sep 17 00:00:00 2001 From: dajiaohuang Date: Sun, 6 Sep 2026 05:34:39 +0800 Subject: [PATCH] Fix checkpoints when mixed data changes cancel --- src/checkpoints/index.ts | 6 +++-- test/unit/core/other/checkpoints.test.ts | 31 ++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/checkpoints/index.ts b/src/checkpoints/index.ts index 5e4469269ec..4b288ae8c2f 100644 --- a/src/checkpoints/index.ts +++ b/src/checkpoints/index.ts @@ -320,7 +320,8 @@ export const createCheckpoints = getCreateFunction( cellOrValueIsEqual(oldNew[0], newCell) && collIsEmpty(mapSet(row, cellId)) && collIsEmpty(mapSet(table, rowId)) && - collIsEmpty(mapSet(cellsDelta, tableId)) + collIsEmpty(mapSet(cellsDelta, tableId)) && + collIsEmpty(valuesDelta) ) { storeUnchanged(); } @@ -342,7 +343,8 @@ export const createCheckpoints = getCreateFunction( oldNew[1] = newValue; if ( cellOrValueIsEqual(oldNew[0], newValue) && - collIsEmpty(mapSet(valuesDelta, valueId)) + collIsEmpty(mapSet(valuesDelta, valueId)) && + collIsEmpty(cellsDelta) ) { storeUnchanged(); } diff --git a/test/unit/core/other/checkpoints.test.ts b/test/unit/core/other/checkpoints.test.ts index f71141fb97e..e6794b08dc1 100644 --- a/test/unit/core/other/checkpoints.test.ts +++ b/test/unit/core/other/checkpoints.test.ts @@ -259,6 +259,37 @@ describe('Basics', () => { expect(checkpoints.getCheckpointIds()).toEqual([['0'], checkpointId, []]); }); + test.each([true, false])( + 'retain mixed changes when cancelling tabular changes: %s', + (cancelTabular) => { + const id0 = checkpoints.getCheckpointIds()[1]; + store.setCell('t1', 'r1', 'c1', 1).setValue('v1', 1); + expectChanges(listener, '/', [[id0], undefined, []]); + if (cancelTabular) { + store.delCell('t1', 'r1', 'c1'); + } else { + store.delValue('v1'); + } + expect(checkpoints.getCheckpointIds()).toEqual([[id0], undefined, []]); + expectNoChanges(listener); + + const id1 = checkpoints.addCheckpoint(); + expect(id1).not.toEqual(id0); + expectChanges(listener, '/', [[id0], id1, []]); + checkpoints.goBackward(); + expect(store.getTables()).toEqual({}); + expect(store.getValues()).toEqual({}); + expectChanges(listener, '/', [[], id0, [id1]]); + checkpoints.goForward(); + expect(store.getTables()).toEqual( + cancelTabular ? {} : {t1: {r1: {c1: 1}}}, + ); + expect(store.getValues()).toEqual(cancelTabular ? {v1: 1} : {}); + expectChanges(listener, '/', [[id0], id1, []]); + expectNoChanges(listener); + }, + ); + test('listener stats', () => { listener.listenToCheckpoint('/c0', '0'); expect(checkpoints.getListenerStats()).toEqual({