Skip to content

Commit

Permalink
feat(archive): imlement canArchive() API
Browse files Browse the repository at this point in the history
  • Loading branch information
unadlib committed Mar 24, 2024
1 parent 5974588 commit 773f295
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 8 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ yarn add use-travel mutative

### API

You can use `useTravel` to create a time travel state. And it returns a tuple with the current state, the state setter, and the controls. The controls include `back()`, `forward()`, `reset()`, `canBack()`, `canForward()`, `getHistory()`, `patches`, `position`, `archive()`, and `go()`.
You can use `useTravel` to create a time travel state. And it returns a tuple with the current state, the state setter, and the controls. The controls include `back()`, `forward()`, `reset()`, `canBack()`, `canForward()`, `canArchive()`, `getHistory()`, `patches`, `position`, `archive()`, and `go()`.

```jsx
import { useTravel } from 'use-travel';
Expand Down Expand Up @@ -105,6 +105,7 @@ const App = () => {
| `controls.reset` | () => void | Reset the state to the initial state |
| `controls.canBack` | () => boolean | Check if can go back to the previous state |
| `controls.canForward` | () => boolean | Check if can go forward to the next state |
| `controls.canArchive` | () => boolean | Check if can archive the current state |
| `controls.getHistory` | () => T[] | Get the history of the state |
| `controls.patches` | TravelPatches[] | Get the patches history of the state |
| `controls.position` | number | Get the current position of the state |
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "use-travel",
"version": "1.0.2",
"version": "1.0.3",
"description": "A React hook for state time travel with undo, redo, reset and archive functionalities.",
"main": "dist/index.cjs.js",
"unpkg": "dist/index.umd.js",
Expand Down
11 changes: 9 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ type Result<S, F extends boolean, A extends boolean> = [
* Archive the current state
*/
archive: () => void;
/**
* Check if it's possible to archive the current state
*/
canArchive: () => boolean;
}
: Controls<S, F>
];
Expand Down Expand Up @@ -221,7 +225,7 @@ export const useTravel = <S, F extends boolean, A extends boolean>(
});
};
const shouldArchive = useMemo(
() => !autoArchive && tempPatches.patches.length,
() => !autoArchive && !!tempPatches.patches.length,
[tempPatches]
);
const _allPatches = useMemo(() => {
Expand All @@ -232,7 +236,9 @@ export const useTravel = <S, F extends boolean, A extends boolean>(
inversePatches: allPatches.inversePatches.concat(),
};
mergedPatches.patches.push(tempPatches.patches.flat());
mergedPatches.inversePatches.push(tempPatches.inversePatches.flat().reverse());
mergedPatches.inversePatches.push(
tempPatches.inversePatches.flat().reverse()
);
}
return mergedPatches;
}, [allPatches, tempPatches, shouldArchive]);
Expand Down Expand Up @@ -322,6 +328,7 @@ export const useTravel = <S, F extends boolean, A extends boolean>(
shouldArchive
? position < _allPatches.patches.length - 1
: position < allPatches.patches.length,
canArchive: () => shouldArchive,
archive,
};
}, [
Expand Down
47 changes: 43 additions & 4 deletions test/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1509,15 +1509,54 @@ describe('useTravel', () => {
expect(nextState).toEqual(2);
expect(controls.position).toEqual(1);
expect(controls.getHistory()).toEqual([0, 2]);


// act(() => controls.archive());
// [nextState, setState, controls] = result.current;
expect(controls.canBack()).toBe(true);
expect(controls.canForward()).toBe(false);
expect(controls.canArchive()).toBe(true);

act(() => controls.back());
[nextState, setState, controls] = result.current;
expect(nextState).toEqual(0);
expect(controls.position).toEqual(0);
expect(controls.getHistory()).toEqual([0, 2]);
expect(controls.canBack()).toBe(false);
expect(controls.canForward()).toBe(true);
expect(controls.canArchive()).toBe(false);
});

it('[useTravel] - back() with autoArchive: false', () => {
let { result } = renderHook(() =>
useTravel(0, {
maxHistory: 3,
autoArchive: false,
})
);
let [nextState, setState, controls] = result.current;
expect(nextState).toEqual(0);
expect(controls.position).toEqual(0);
expect(controls.getHistory()).toEqual([0]);

act(() => setState(() => 1));
[nextState, setState, controls] = result.current;
expect(nextState).toEqual(1);
expect(controls.position).toEqual(1);
expect(controls.getHistory()).toEqual([0, 1]);

act(() => setState(() => 2));
[nextState, setState, controls] = result.current;
expect(nextState).toEqual(2);
expect(controls.position).toEqual(1);
expect(controls.getHistory()).toEqual([0, 2]);
expect(controls.canBack()).toBe(true);
expect(controls.canForward()).toBe(false);
expect(controls.canArchive()).toBe(true);

act(() => controls.archive());
[nextState, setState, controls] = result.current;
expect(nextState).toEqual(2);
expect(controls.position).toEqual(1);
expect(controls.getHistory()).toEqual([0, 2]);
expect(controls.canBack()).toBe(true);
expect(controls.canForward()).toBe(false);
expect(controls.canArchive()).toBe(false);
});
});

0 comments on commit 773f295

Please sign in to comment.