diff --git a/src/index.ts b/src/index.ts index 6f1f15b..96d57af 100644 --- a/src/index.ts +++ b/src/index.ts @@ -198,8 +198,16 @@ export const useTravel = ( } if (!tempPatches.patches.length) return; setAllPatches((allPatchesDraft) => { - allPatchesDraft.patches.push(tempPatches.patches.flat()); - allPatchesDraft.inversePatches.push(tempPatches.inversePatches.flat()); + // All patches will be merged, it helps to minimize the patch structure + const [, patches, inversePatches] = create( + state as object, + (draft) => apply(draft, tempPatches.inversePatches.flat().reverse()), + { + enablePatches: true, + } + ); + allPatchesDraft.patches.push(inversePatches); + allPatchesDraft.inversePatches.push(patches); if (maxHistory < allPatchesDraft.patches.length) { allPatchesDraft.patches = allPatchesDraft.patches.slice(-maxHistory); allPatchesDraft.inversePatches = allPatchesDraft.inversePatches.slice( diff --git a/test/index.test.ts b/test/index.test.ts index f2ddc31..21eed9c 100644 --- a/test/index.test.ts +++ b/test/index.test.ts @@ -1169,6 +1169,57 @@ describe('useTravel', () => { expect(controls.canBack()).toBe(true); expect(controls.canForward()).toBe(true); + expect(controls.patches).toMatchInlineSnapshot(` + { + "inversePatches": [ + [ + { + "op": "replace", + "path": [], + "value": 3, + }, + ], + [ + { + "op": "replace", + "path": [], + "value": 4, + }, + ], + [ + { + "op": "replace", + "path": [], + "value": 5, + }, + ], + ], + "patches": [ + [ + { + "op": "replace", + "path": [], + "value": 4, + }, + ], + [ + { + "op": "replace", + "path": [], + "value": 5, + }, + ], + [ + { + "op": "replace", + "path": [], + "value": 6, + }, + ], + ], + } + `); + result = renderHook(() => useTravel(nextState, { maxHistory: 3, @@ -1374,5 +1425,64 @@ describe('useTravel', () => { ], } `); + + act(() => controls.archive()); + [nextState, setState, controls] = result.current; + + expect(nextState).toEqual(8); + expect(controls.position).toEqual(3); + expect(controls.getHistory()).toEqual([3, 4, 5, 8]); + expect(controls.canBack()).toBe(true); + expect(controls.canForward()).toBe(false); + expect(controls.patches).toMatchInlineSnapshot(` + { + "inversePatches": [ + [ + { + "op": "replace", + "path": [], + "value": 3, + }, + ], + [ + { + "op": "replace", + "path": [], + "value": 4, + }, + ], + [ + { + "op": "replace", + "path": [], + "value": 5, + }, + ], + ], + "patches": [ + [ + { + "op": "replace", + "path": [], + "value": 4, + }, + ], + [ + { + "op": "replace", + "path": [], + "value": 5, + }, + ], + [ + { + "op": "replace", + "path": [], + "value": 8, + }, + ], + ], + } + `); }); });