use-good-hooks 1.0.40 → 1.0.42
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -4
- package/dist/use-history-state.d.ts +2 -3
- package/dist/use-history-state.js +78 -84
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -230,7 +230,7 @@ const TextEditor = () => {
|
|
|
230
230
|
<button onClick={actions.redo} disabled={!state.canRedo}>
|
|
231
231
|
Redo
|
|
232
232
|
</button>
|
|
233
|
-
<button onClick={actions.
|
|
233
|
+
<button onClick={actions.initial}>Initial State</button>
|
|
234
234
|
</div>
|
|
235
235
|
<p>Past states: {state.past.length}</p>
|
|
236
236
|
<p>Future states: {state.future.length}</p>
|
|
@@ -245,7 +245,6 @@ const TextEditor = () => {
|
|
|
245
245
|
- `options`: (Optional) Configuration options:
|
|
246
246
|
- `debounceMs`: Time in milliseconds to debounce the state changes (default: 250)
|
|
247
247
|
- `debounceSettings`: Debounce settings object from Lodash
|
|
248
|
-
- `immutable`: Boolean indicating if the state should be treated as immutable (default: true)
|
|
249
248
|
- `maxCapacity`: Maximum number of history entries to keep (default: 10)
|
|
250
249
|
- `onChange`: Function to call when the state changes, receives `{ action, state }`
|
|
251
250
|
- `paused`: Boolean indicating if the history is paused (default: false)
|
|
@@ -256,7 +255,7 @@ Returns a tuple `[historyState, historyActions]`:
|
|
|
256
255
|
|
|
257
256
|
**historyState** (Object): - `canRedo`: Boolean indicating if redo is possible - `canUndo`: Boolean indicating if undo is possible - `future`: Array of future states (for redo) - `past`: Array of past states (for undo) - `paused`: Boolean indicating if the history is paused - `present`: The current state value
|
|
258
257
|
|
|
259
|
-
**historyActions** (Object): - `
|
|
258
|
+
**historyActions** (Object): - `initial`: Function to reset to initial state - `pause`: Function to pause history tracking (updates won't be recorded) - `redo`: Function to move to the next state (redo) - `replace`: Function to replace the state without adding to history - `resume`: Function to resume history tracking - `set`: Function to update the state and record history (debounced by default) - `setDirect`: Function to update the state immediately, bypassing debounce - `undo`: Function to move to the previous state (undo)
|
|
260
259
|
|
|
261
260
|
#### Example with onChange callback
|
|
262
261
|
|
|
@@ -265,7 +264,7 @@ const Editor = () => {
|
|
|
265
264
|
const [state, actions] = useHistoryState('', {
|
|
266
265
|
onChange: ({ action, state }) => {
|
|
267
266
|
console.log(`Action: ${action}, State: ${state}`);
|
|
268
|
-
// Action can be: 'SET', 'UNDO', 'REDO', '
|
|
267
|
+
// Action can be: 'SET', 'UNDO', 'REDO', 'INITIAL', 'REPLACE'
|
|
269
268
|
}
|
|
270
269
|
});
|
|
271
270
|
|
|
@@ -3,7 +3,7 @@ import { DebounceSettings } from 'lodash';
|
|
|
3
3
|
export { DebounceSettings }
|
|
4
4
|
|
|
5
5
|
export declare type HistoryAction<T> = {
|
|
6
|
-
type: '
|
|
6
|
+
type: 'INITIAL';
|
|
7
7
|
initialState: T;
|
|
8
8
|
} | {
|
|
9
9
|
type: 'PAUSE';
|
|
@@ -29,7 +29,6 @@ declare type HistoryOnChange<T> = ({ action, state }: {
|
|
|
29
29
|
export declare type HistoryOptions<T> = {
|
|
30
30
|
debounceMs?: number;
|
|
31
31
|
debounceSettings?: DebounceSettings;
|
|
32
|
-
immutable?: boolean;
|
|
33
32
|
maxCapacity?: number;
|
|
34
33
|
onChange?: HistoryOnChange<T>;
|
|
35
34
|
paused?: boolean;
|
|
@@ -50,7 +49,7 @@ declare const useHistoryState: <T>(initialState: T, options?: HistoryOptions<T>)
|
|
|
50
49
|
paused: boolean;
|
|
51
50
|
present: T;
|
|
52
51
|
}, {
|
|
53
|
-
|
|
52
|
+
initial: () => void;
|
|
54
53
|
pause: () => void;
|
|
55
54
|
redo: () => void;
|
|
56
55
|
replace: (newPresent: T) => void;
|
|
@@ -1,27 +1,24 @@
|
|
|
1
|
-
import { useRef as
|
|
1
|
+
import { useRef as U, useReducer as I, useMemo as A, useEffect as T } from "react";
|
|
2
2
|
import h from "lodash/cloneDeep";
|
|
3
|
-
import
|
|
4
|
-
import
|
|
3
|
+
import b from "lodash/isEqual";
|
|
4
|
+
import C from "lodash/debounce";
|
|
5
|
+
import o from "lodash/size";
|
|
5
6
|
const L = {
|
|
6
7
|
future: [],
|
|
7
8
|
past: [],
|
|
8
9
|
present: null
|
|
9
|
-
},
|
|
10
|
-
const w =
|
|
10
|
+
}, p = (l) => h(l), M = (l, f) => b(l, f), v = (l, f) => {
|
|
11
|
+
const w = U(l), d = U(f ?? {}), [c, u] = I(
|
|
11
12
|
(n, e) => {
|
|
12
|
-
const {
|
|
13
|
-
|
|
14
|
-
maxCapacity: r = 10,
|
|
15
|
-
onChange: S = () => null
|
|
16
|
-
} = E.current, { future: R, past: y, paused: d, present: m } = n;
|
|
17
|
-
if (e.type === "CLEAR") {
|
|
13
|
+
const { maxCapacity: y = 10, onChange: t = () => null } = d.current, { future: m, past: i, paused: S, present: E } = n;
|
|
14
|
+
if (e.type === "INITIAL") {
|
|
18
15
|
const s = {
|
|
19
16
|
future: [],
|
|
20
17
|
past: [],
|
|
21
|
-
paused:
|
|
22
|
-
present:
|
|
18
|
+
paused: S,
|
|
19
|
+
present: p(e.initialState)
|
|
23
20
|
};
|
|
24
|
-
return
|
|
21
|
+
return t({
|
|
25
22
|
action: e.type,
|
|
26
23
|
state: s.present
|
|
27
24
|
}), s;
|
|
@@ -32,18 +29,18 @@ const L = {
|
|
|
32
29
|
paused: !0
|
|
33
30
|
};
|
|
34
31
|
if (e.type === "REDO") {
|
|
35
|
-
if (
|
|
32
|
+
if (o(m) === 0)
|
|
36
33
|
return n;
|
|
37
|
-
const s =
|
|
38
|
-
future:
|
|
39
|
-
past: [...
|
|
40
|
-
paused:
|
|
41
|
-
present:
|
|
34
|
+
const s = m[0], a = {
|
|
35
|
+
future: m.slice(1),
|
|
36
|
+
past: [...i, p(E)],
|
|
37
|
+
paused: S,
|
|
38
|
+
present: p(s)
|
|
42
39
|
};
|
|
43
|
-
return
|
|
40
|
+
return t({
|
|
44
41
|
action: e.type,
|
|
45
|
-
state:
|
|
46
|
-
}),
|
|
42
|
+
state: a.present
|
|
43
|
+
}), a;
|
|
47
44
|
} else {
|
|
48
45
|
if (e.type === "RESUME")
|
|
49
46
|
return {
|
|
@@ -51,55 +48,55 @@ const L = {
|
|
|
51
48
|
paused: !1
|
|
52
49
|
};
|
|
53
50
|
if (e.type === "REPLACE") {
|
|
54
|
-
const { newPresent: s } = e,
|
|
51
|
+
const { newPresent: s } = e, r = {
|
|
55
52
|
...n,
|
|
56
53
|
future: [],
|
|
57
54
|
past: [],
|
|
58
55
|
present: s
|
|
59
56
|
};
|
|
60
|
-
return
|
|
57
|
+
return t({
|
|
61
58
|
action: e.type,
|
|
62
|
-
state:
|
|
63
|
-
}),
|
|
59
|
+
state: r.present
|
|
60
|
+
}), r;
|
|
64
61
|
} else if (e.type === "SET") {
|
|
65
62
|
const { newPresent: s } = e;
|
|
66
|
-
if (M(s,
|
|
63
|
+
if (M(s, E))
|
|
67
64
|
return n;
|
|
68
|
-
if (
|
|
69
|
-
const
|
|
65
|
+
if (S) {
|
|
66
|
+
const R = {
|
|
70
67
|
...n,
|
|
71
|
-
present:
|
|
68
|
+
present: p(s)
|
|
72
69
|
};
|
|
73
|
-
return
|
|
70
|
+
return t({
|
|
74
71
|
action: e.type,
|
|
75
|
-
state:
|
|
76
|
-
}),
|
|
72
|
+
state: R.present
|
|
73
|
+
}), R;
|
|
77
74
|
}
|
|
78
|
-
let
|
|
79
|
-
|
|
80
|
-
const
|
|
75
|
+
let r = [...i];
|
|
76
|
+
E !== null && (r = [...r, p(E)]), y > 0 && o(r) > y && (r = r.slice(o(r) - y));
|
|
77
|
+
const a = {
|
|
81
78
|
future: [],
|
|
82
|
-
past:
|
|
83
|
-
paused:
|
|
84
|
-
present:
|
|
79
|
+
past: r,
|
|
80
|
+
paused: S,
|
|
81
|
+
present: p(s)
|
|
85
82
|
};
|
|
86
|
-
return
|
|
83
|
+
return t({
|
|
87
84
|
action: e.type,
|
|
88
|
-
state:
|
|
89
|
-
}),
|
|
85
|
+
state: a.present
|
|
86
|
+
}), a;
|
|
90
87
|
} else if (e.type === "UNDO") {
|
|
91
|
-
if (i
|
|
88
|
+
if (o(i) === 0)
|
|
92
89
|
return n;
|
|
93
|
-
const s =
|
|
94
|
-
future: [
|
|
95
|
-
past:
|
|
96
|
-
paused:
|
|
97
|
-
present:
|
|
90
|
+
const s = i[o(i) - 1], r = i.slice(0, o(i) - 1), a = {
|
|
91
|
+
future: [p(E), ...m],
|
|
92
|
+
past: r,
|
|
93
|
+
paused: S,
|
|
94
|
+
present: p(s)
|
|
98
95
|
};
|
|
99
|
-
return
|
|
96
|
+
return t({
|
|
100
97
|
action: e.type,
|
|
101
|
-
state:
|
|
102
|
-
}),
|
|
98
|
+
state: a.present
|
|
99
|
+
}), a;
|
|
103
100
|
} else
|
|
104
101
|
throw new Error("Unsupported action type");
|
|
105
102
|
}
|
|
@@ -107,59 +104,56 @@ const L = {
|
|
|
107
104
|
},
|
|
108
105
|
{
|
|
109
106
|
...L,
|
|
110
|
-
paused:
|
|
111
|
-
present:
|
|
112
|
-
w.current,
|
|
113
|
-
E.current.immutable
|
|
114
|
-
)
|
|
107
|
+
paused: d.current.paused ?? !1,
|
|
108
|
+
present: p(w.current)
|
|
115
109
|
}
|
|
116
|
-
),
|
|
117
|
-
canRedo:
|
|
118
|
-
canUndo:
|
|
119
|
-
future:
|
|
120
|
-
past:
|
|
121
|
-
paused:
|
|
122
|
-
present:
|
|
123
|
-
}), [
|
|
124
|
-
const { debounceMs: n = 250, debounceSettings: e } =
|
|
125
|
-
(
|
|
110
|
+
), D = A(() => ({
|
|
111
|
+
canRedo: o(c.future) !== 0,
|
|
112
|
+
canUndo: o(c.past) !== 0,
|
|
113
|
+
future: c.future,
|
|
114
|
+
past: c.past,
|
|
115
|
+
paused: c.paused,
|
|
116
|
+
present: c.present
|
|
117
|
+
}), [c]), P = A(() => {
|
|
118
|
+
const { debounceMs: n = 250, debounceSettings: e } = d.current, y = C(
|
|
119
|
+
(t) => u({ type: "SET", newPresent: t }),
|
|
126
120
|
n,
|
|
127
121
|
e
|
|
128
122
|
);
|
|
129
123
|
return {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
type: "
|
|
124
|
+
initial: () => {
|
|
125
|
+
u({
|
|
126
|
+
type: "INITIAL",
|
|
133
127
|
initialState: w.current
|
|
134
128
|
});
|
|
135
129
|
},
|
|
136
130
|
pause: () => {
|
|
137
|
-
|
|
131
|
+
u({ type: "PAUSE" });
|
|
138
132
|
},
|
|
139
133
|
redo: () => {
|
|
140
|
-
|
|
134
|
+
u({ type: "REDO" });
|
|
141
135
|
},
|
|
142
|
-
replace: (
|
|
143
|
-
|
|
136
|
+
replace: (t) => {
|
|
137
|
+
u({ type: "REPLACE", newPresent: t });
|
|
144
138
|
},
|
|
145
139
|
resume: () => {
|
|
146
|
-
|
|
140
|
+
u({ type: "RESUME" });
|
|
147
141
|
},
|
|
148
|
-
set: (
|
|
149
|
-
n ?
|
|
142
|
+
set: (t) => {
|
|
143
|
+
n ? y(t) : u({ type: "SET", newPresent: t });
|
|
150
144
|
},
|
|
151
|
-
setDirect: (
|
|
152
|
-
|
|
145
|
+
setDirect: (t) => {
|
|
146
|
+
u({ type: "SET", newPresent: t });
|
|
153
147
|
},
|
|
154
148
|
undo: () => {
|
|
155
|
-
|
|
149
|
+
u({ type: "UNDO" });
|
|
156
150
|
}
|
|
157
151
|
};
|
|
158
152
|
}, []);
|
|
159
|
-
return
|
|
160
|
-
|
|
161
|
-
}, [
|
|
153
|
+
return T(() => {
|
|
154
|
+
f && (d.current = f);
|
|
155
|
+
}, [f]), [D, P];
|
|
162
156
|
};
|
|
163
157
|
export {
|
|
164
|
-
|
|
158
|
+
v as default
|
|
165
159
|
};
|
package/package.json
CHANGED