use-good-hooks 1.0.10 → 1.0.12
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 +88 -0
- package/dist/is-BPZNFd2v.mjs +4 -0
- package/dist/use-debounce.d.ts +4 -0
- package/dist/use-debounce.js +20 -0
- package/dist/use-distinct.d.ts +16 -0
- package/dist/use-distinct.js +43 -0
- package/dist/use-global-state.d.ts +9 -0
- package/dist/use-global-state.js +34 -0
- package/dist/use-prev.d.ts +4 -0
- package/dist/use-prev.js +10 -0
- package/dist/use-storage-state.d.ts +22 -0
- package/dist/use-storage-state.js +76 -0
- package/dist/use-throttle.d.ts +4 -0
- package/dist/use-throttle.js +20 -0
- package/dist/use-url-state.d.ts +19 -0
- package/dist/use-url-state.js +71 -0
- package/package.json +7 -3
- package/dist/index.d.ts +0 -56
- package/dist/index.js +0 -204
package/README.md
CHANGED
|
@@ -274,6 +274,94 @@ const ProductFilter = () => {
|
|
|
274
274
|
- State value
|
|
275
275
|
- State setter function
|
|
276
276
|
|
|
277
|
+
### `useGlobalState` and `createGlobalState`
|
|
278
|
+
|
|
279
|
+
Creates and manages global state that can be shared across components with automatic synchronization.
|
|
280
|
+
|
|
281
|
+
```typescript
|
|
282
|
+
import { createGlobalState, useGlobalState } from 'use-good-hooks';
|
|
283
|
+
|
|
284
|
+
// Create a global state instance (typically in a separate file)
|
|
285
|
+
const counterState = createGlobalState({ count: 0 });
|
|
286
|
+
|
|
287
|
+
// Component A
|
|
288
|
+
const CounterDisplay = () => {
|
|
289
|
+
const [counter, setCounter] = useGlobalState(counterState);
|
|
290
|
+
|
|
291
|
+
return (
|
|
292
|
+
<div>
|
|
293
|
+
<p>Count: {counter.count}</p>
|
|
294
|
+
<button onClick={() => setCounter({ count: counter.count + 1 })}>
|
|
295
|
+
Increment
|
|
296
|
+
</button>
|
|
297
|
+
</div>
|
|
298
|
+
);
|
|
299
|
+
};
|
|
300
|
+
|
|
301
|
+
// Component B (in a different part of your app)
|
|
302
|
+
const CounterActions = () => {
|
|
303
|
+
const [counter, setCounter] = useGlobalState(counterState);
|
|
304
|
+
|
|
305
|
+
return (
|
|
306
|
+
<div>
|
|
307
|
+
<button onClick={() => setCounter({ count: 0 })}>
|
|
308
|
+
Reset Count
|
|
309
|
+
</button>
|
|
310
|
+
<button onClick={() => setCounter(prev => ({ count: prev.count + 5 }))}>
|
|
311
|
+
Add 5
|
|
312
|
+
</button>
|
|
313
|
+
</div>
|
|
314
|
+
);
|
|
315
|
+
};
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
#### Usage
|
|
319
|
+
|
|
320
|
+
1. First, create a global state store:
|
|
321
|
+
|
|
322
|
+
```typescript
|
|
323
|
+
// state/counter.ts
|
|
324
|
+
import { createGlobalState } from 'use-good-hooks';
|
|
325
|
+
|
|
326
|
+
export const counterState = createGlobalState({ count: 0 });
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
2. Then use it in any component:
|
|
330
|
+
|
|
331
|
+
```typescript
|
|
332
|
+
import { useGlobalState } from 'use-good-hooks';
|
|
333
|
+
import { counterState } from './state/counter';
|
|
334
|
+
|
|
335
|
+
const MyComponent = () => {
|
|
336
|
+
const [counter, setCounter] = useGlobalState(counterState);
|
|
337
|
+
// ...
|
|
338
|
+
};
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
#### `createGlobalState` Parameters
|
|
342
|
+
|
|
343
|
+
- `initialState`: The initial state value
|
|
344
|
+
|
|
345
|
+
#### `createGlobalState` Returns
|
|
346
|
+
|
|
347
|
+
- Array with:
|
|
348
|
+
- `state`: The current state
|
|
349
|
+
- `setState`: Function to update state
|
|
350
|
+
- `store`: Object with utility methods:
|
|
351
|
+
- `getState()`: Function to get current state
|
|
352
|
+
- `subscribe(callback)`: Subscribe to state changes
|
|
353
|
+
- `resetState()`: Reset to initial state
|
|
354
|
+
|
|
355
|
+
#### `useGlobalState` Parameters
|
|
356
|
+
|
|
357
|
+
- `globalState`: The global state created with `createGlobalState`
|
|
358
|
+
|
|
359
|
+
#### `useGlobalState` Returns
|
|
360
|
+
|
|
361
|
+
- Array with:
|
|
362
|
+
- `state`: The component's local copy of the state
|
|
363
|
+
- `setState`: Function to update global state (accepts new value or update function)
|
|
364
|
+
|
|
277
365
|
## 🧪 Running Tests
|
|
278
366
|
|
|
279
367
|
This library is thoroughly tested with Vitest and React Testing Library. To run the tests:
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { useState as s, useRef as d, useEffect as n } from "react";
|
|
2
|
+
import f from "lodash/debounce";
|
|
3
|
+
const b = 300, D = (e, o = b) => {
|
|
4
|
+
const [u, r] = s(e), c = d(
|
|
5
|
+
f((t) => {
|
|
6
|
+
r(t);
|
|
7
|
+
}, o)
|
|
8
|
+
);
|
|
9
|
+
return n(() => {
|
|
10
|
+
c.current(e);
|
|
11
|
+
}, [e]), n(() => {
|
|
12
|
+
const t = c.current;
|
|
13
|
+
return () => {
|
|
14
|
+
t.cancel();
|
|
15
|
+
};
|
|
16
|
+
}, []), u;
|
|
17
|
+
};
|
|
18
|
+
export {
|
|
19
|
+
D as default
|
|
20
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
declare const useDistinct: <T>(inputValue: T, options?: UseDistinctOptions) => UseDistinctReturn<T>;
|
|
2
|
+
export default useDistinct;
|
|
3
|
+
|
|
4
|
+
declare type UseDistinctOptions = {
|
|
5
|
+
compare?: (a: any, b: any) => boolean;
|
|
6
|
+
debounce?: number;
|
|
7
|
+
deep?: boolean;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
declare type UseDistinctReturn<T> = {
|
|
11
|
+
distinct: boolean;
|
|
12
|
+
prevValue: T | undefined;
|
|
13
|
+
value: T;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export { }
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { useRef as c, useState as p, useCallback as b, useEffect as i } from "react";
|
|
2
|
+
import v from "lodash/debounce";
|
|
3
|
+
import R from "lodash/isEqual";
|
|
4
|
+
import q from "lodash/isFunction";
|
|
5
|
+
const D = (e, n) => e === n, g = (e, n = {}) => {
|
|
6
|
+
const s = c(!1), o = c(n), u = c(e), a = c(
|
|
7
|
+
v((t) => {
|
|
8
|
+
const { compare: d, deep: m } = o.current;
|
|
9
|
+
!(q(d) ? d : m ? R : D)(t, u.current) && (f({
|
|
10
|
+
distinct: !0,
|
|
11
|
+
prevValue: u.current,
|
|
12
|
+
value: t
|
|
13
|
+
}), u.current = t);
|
|
14
|
+
}, o.current.debounce ?? 0)
|
|
15
|
+
), [r, f] = p({
|
|
16
|
+
distinct: !1,
|
|
17
|
+
prevValue: void 0,
|
|
18
|
+
value: e
|
|
19
|
+
}), l = b(() => {
|
|
20
|
+
s.current = !1, f((t) => ({
|
|
21
|
+
...t,
|
|
22
|
+
distinct: !1
|
|
23
|
+
}));
|
|
24
|
+
}, []);
|
|
25
|
+
return i(() => {
|
|
26
|
+
if (r.distinct && s.current) {
|
|
27
|
+
l();
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
const t = a.current;
|
|
31
|
+
t(e);
|
|
32
|
+
}), i(() => {
|
|
33
|
+
r.distinct && (s.current = !0);
|
|
34
|
+
}, [r.distinct]), i(() => {
|
|
35
|
+
const t = a.current;
|
|
36
|
+
return () => {
|
|
37
|
+
t.cancel();
|
|
38
|
+
};
|
|
39
|
+
}, []), r;
|
|
40
|
+
};
|
|
41
|
+
export {
|
|
42
|
+
g as default
|
|
43
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare const createGlobalState: <T>(initialState: T) => readonly [T, (newState: T | ((prevState: T) => T)) => void, {
|
|
2
|
+
getState: () => T;
|
|
3
|
+
subscribe: (callback: (state: T) => void) => () => void;
|
|
4
|
+
resetState: () => void;
|
|
5
|
+
}];
|
|
6
|
+
|
|
7
|
+
export declare const useGlobalState: <T>(globalState: ReturnType<typeof createGlobalState<T>>) => [T, ReturnType<typeof createGlobalState<T>>[1]];
|
|
8
|
+
|
|
9
|
+
export { }
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { useState as i, useEffect as l } from "react";
|
|
2
|
+
const f = (o) => {
|
|
3
|
+
let t = o, s = /* @__PURE__ */ new Set();
|
|
4
|
+
const r = () => {
|
|
5
|
+
s.forEach((e) => {
|
|
6
|
+
try {
|
|
7
|
+
e(t);
|
|
8
|
+
} catch (c) {
|
|
9
|
+
console.error("Error in global state subscriber:", c);
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
};
|
|
13
|
+
return [t, (e) => {
|
|
14
|
+
const c = typeof e == "function" ? e(t) : e;
|
|
15
|
+
JSON.stringify(t) !== JSON.stringify(c) && (t = c, r());
|
|
16
|
+
}, {
|
|
17
|
+
getState: () => t,
|
|
18
|
+
subscribe: (e) => (s.add(e), () => {
|
|
19
|
+
s.delete(e);
|
|
20
|
+
}),
|
|
21
|
+
resetState: () => {
|
|
22
|
+
t = o, r();
|
|
23
|
+
}
|
|
24
|
+
}];
|
|
25
|
+
}, g = (o) => {
|
|
26
|
+
const [t, s, r] = o, [n, b] = i(t);
|
|
27
|
+
return l(() => r.subscribe((u) => {
|
|
28
|
+
b(u);
|
|
29
|
+
}), [r]), [n, s];
|
|
30
|
+
};
|
|
31
|
+
export {
|
|
32
|
+
f as createGlobalState,
|
|
33
|
+
g as useGlobalState
|
|
34
|
+
};
|
package/dist/use-prev.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { StrictObject } from './types';
|
|
2
|
+
|
|
3
|
+
export declare const jsonReplacer: (key: string, value: any) => any;
|
|
4
|
+
|
|
5
|
+
export declare const jsonReviver: (key: string, value: any) => any;
|
|
6
|
+
|
|
7
|
+
declare type StorageType = 'local' | 'session';
|
|
8
|
+
|
|
9
|
+
declare const useStorageState: <T extends StrictObject>(key: string, initialState: T, options?: UseStorageStateOptions) => [T, (value: T | ((prev: T) => T)) => void, {
|
|
10
|
+
removeKey: () => void;
|
|
11
|
+
}];
|
|
12
|
+
export default useStorageState;
|
|
13
|
+
|
|
14
|
+
declare type UseStorageStateOptions = {
|
|
15
|
+
debounce?: number;
|
|
16
|
+
onError?: (err: Error) => void;
|
|
17
|
+
omitKeys?: string[] | ((value: any, key: string) => boolean);
|
|
18
|
+
pickKeys?: string[] | ((value: any, key: string) => boolean);
|
|
19
|
+
storage?: StorageType;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export { }
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { useRef as _, useState as k, useEffect as E, useCallback as B } from "react";
|
|
2
|
+
import F from "lodash/isEmpty";
|
|
3
|
+
import i from "lodash/isFunction";
|
|
4
|
+
import I from "lodash/isMap";
|
|
5
|
+
import O from "lodash/isSet";
|
|
6
|
+
import b from "use-json";
|
|
7
|
+
import T from "lodash/merge";
|
|
8
|
+
import d from "lodash/omit";
|
|
9
|
+
import K from "lodash/omitBy";
|
|
10
|
+
import R from "lodash/pick";
|
|
11
|
+
import w from "lodash/pickBy";
|
|
12
|
+
import a from "lodash/size";
|
|
13
|
+
import { i as A } from "./is-BPZNFd2v.mjs";
|
|
14
|
+
import U from "./use-debounce.js";
|
|
15
|
+
const h = 500, y = "local", j = (m, r) => I(r) ? {
|
|
16
|
+
__type: "Map",
|
|
17
|
+
value: Array.from(r.entries())
|
|
18
|
+
} : O(r) ? {
|
|
19
|
+
__type: "Set",
|
|
20
|
+
value: Array.from(r)
|
|
21
|
+
} : r, C = (m, r) => r && r.__type === "Map" ? new Map(r.value) : r && r.__type === "Set" ? new Set(r.value) : r, Z = (m, r, D) => {
|
|
22
|
+
const p = _(D || {}), S = _(!1), [l, u] = k(r), g = U(
|
|
23
|
+
l,
|
|
24
|
+
p.current.debounce ?? h
|
|
25
|
+
);
|
|
26
|
+
E(() => {
|
|
27
|
+
if (!A.browser() || !S.current)
|
|
28
|
+
return;
|
|
29
|
+
const {
|
|
30
|
+
storage: f = y,
|
|
31
|
+
onError: t,
|
|
32
|
+
omitKeys: s,
|
|
33
|
+
pickKeys: o
|
|
34
|
+
} = p.current, n = f === "local" ? localStorage : sessionStorage;
|
|
35
|
+
if (n)
|
|
36
|
+
try {
|
|
37
|
+
let e = g;
|
|
38
|
+
s && (a(s) || i(s)) && (e = i(s) ? K(e, s) : d(e, s)), o && (a(o) || i(o)) && (e = i(o) ? w(e, o) : R(e, o)), n.setItem(m, b.stringify(e, j));
|
|
39
|
+
} catch (e) {
|
|
40
|
+
t && t(e);
|
|
41
|
+
}
|
|
42
|
+
}, [m, g]), E(() => {
|
|
43
|
+
const {
|
|
44
|
+
storage: f = y,
|
|
45
|
+
omitKeys: t,
|
|
46
|
+
onError: s,
|
|
47
|
+
pickKeys: o
|
|
48
|
+
} = p.current;
|
|
49
|
+
try {
|
|
50
|
+
const n = f === "local" ? localStorage : sessionStorage, e = n == null ? void 0 : n.getItem(m);
|
|
51
|
+
if (e) {
|
|
52
|
+
let c = b.parse(e, C);
|
|
53
|
+
t && (a(t) || i(t)) && (c = i(t) ? K(c, t) : d(c, t)), o && (a(o) || i(o)) && (c = i(o) ? w(c, o) : R(c, o)), u(
|
|
54
|
+
F(c) ? r : T({}, r, c)
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
} catch (n) {
|
|
58
|
+
s && s(n);
|
|
59
|
+
} finally {
|
|
60
|
+
S.current = !0;
|
|
61
|
+
}
|
|
62
|
+
}, []);
|
|
63
|
+
const M = B(() => {
|
|
64
|
+
if (!A.browser())
|
|
65
|
+
return;
|
|
66
|
+
u(r);
|
|
67
|
+
const { storage: f = y } = p.current, t = f === "local" ? localStorage : sessionStorage;
|
|
68
|
+
t == null || t.removeItem(m);
|
|
69
|
+
}, [m, r]);
|
|
70
|
+
return [l, u, { removeKey: M }];
|
|
71
|
+
};
|
|
72
|
+
export {
|
|
73
|
+
Z as default,
|
|
74
|
+
j as jsonReplacer,
|
|
75
|
+
C as jsonReviver
|
|
76
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { useState as u, useRef as l, useEffect as o } from "react";
|
|
2
|
+
import f from "lodash/throttle";
|
|
3
|
+
const h = 300, d = (t, s = h) => {
|
|
4
|
+
const [c, n] = u(t), r = l(
|
|
5
|
+
f((e) => {
|
|
6
|
+
n(e);
|
|
7
|
+
}, s)
|
|
8
|
+
);
|
|
9
|
+
return o(() => {
|
|
10
|
+
r.current(t);
|
|
11
|
+
}, [t]), o(() => {
|
|
12
|
+
const e = r.current;
|
|
13
|
+
return () => {
|
|
14
|
+
e.cancel();
|
|
15
|
+
};
|
|
16
|
+
}, []), c;
|
|
17
|
+
};
|
|
18
|
+
export {
|
|
19
|
+
d as default
|
|
20
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { StrictObject } from './types';
|
|
2
|
+
|
|
3
|
+
declare type SetUrlStateAction<T> = T | ((prevState: T) => T);
|
|
4
|
+
|
|
5
|
+
declare const useUrlState: <T extends StrictObject>(initialState: T, options: UseUrlStateOptions) => [T, (value: SetUrlStateAction<T>) => void];
|
|
6
|
+
export default useUrlState;
|
|
7
|
+
|
|
8
|
+
declare type UseUrlStateOptions = {
|
|
9
|
+
debounce?: number;
|
|
10
|
+
kebabCase?: boolean;
|
|
11
|
+
omitKeys?: string[] | ((value: any, key: string) => boolean);
|
|
12
|
+
omitValues?: any[] | ((value: any, key: string) => boolean);
|
|
13
|
+
onError?: (err: Error) => void;
|
|
14
|
+
pickKeys?: string[] | ((value: any, key: string) => boolean);
|
|
15
|
+
prefix?: string;
|
|
16
|
+
url: URL;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export { }
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { useRef as S, useState as K, useEffect as U } from "react";
|
|
2
|
+
import g from "lodash/isEmpty";
|
|
3
|
+
import s from "lodash/isFunction";
|
|
4
|
+
import x from "lodash/merge";
|
|
5
|
+
import b from "lodash/omit";
|
|
6
|
+
import y from "lodash/omitBy";
|
|
7
|
+
import d from "lodash/pick";
|
|
8
|
+
import h from "lodash/pickBy";
|
|
9
|
+
import w from "use-qs";
|
|
10
|
+
import c from "lodash/size";
|
|
11
|
+
import { i as B } from "./is-BPZNFd2v.mjs";
|
|
12
|
+
import D from "./use-debounce.js";
|
|
13
|
+
const R = 500, j = (a, k) => {
|
|
14
|
+
const m = S(k), E = () => {
|
|
15
|
+
const {
|
|
16
|
+
kebabCase: n = !0,
|
|
17
|
+
omitKeys: e,
|
|
18
|
+
omitValues: f,
|
|
19
|
+
onError: i,
|
|
20
|
+
pickKeys: r,
|
|
21
|
+
prefix: p = "",
|
|
22
|
+
url: o
|
|
23
|
+
} = m.current;
|
|
24
|
+
if (!o.search)
|
|
25
|
+
return a;
|
|
26
|
+
try {
|
|
27
|
+
let t = w.parse(decodeURIComponent(o.search), {
|
|
28
|
+
case: n ? "kebab-case" : "camelCase",
|
|
29
|
+
omitValues: f,
|
|
30
|
+
prefix: p
|
|
31
|
+
});
|
|
32
|
+
return e && (c(e) || s(e)) && (t = s(e) ? y(t, e) : b(t, e)), r && (c(r) || s(r)) && (t = s(r) ? h(t, r) : d(t, r)), g(t) ? a : x({}, a, t);
|
|
33
|
+
} catch (t) {
|
|
34
|
+
return i && i(t), a;
|
|
35
|
+
}
|
|
36
|
+
}, [u, C] = K(E), l = D(
|
|
37
|
+
u,
|
|
38
|
+
m.current.debounce ?? R
|
|
39
|
+
);
|
|
40
|
+
return U(() => {
|
|
41
|
+
if (!B.browser())
|
|
42
|
+
return;
|
|
43
|
+
const {
|
|
44
|
+
kebabCase: n = !0,
|
|
45
|
+
omitKeys: e,
|
|
46
|
+
omitValues: f,
|
|
47
|
+
onError: i,
|
|
48
|
+
pickKeys: r,
|
|
49
|
+
prefix: p = ""
|
|
50
|
+
} = m.current;
|
|
51
|
+
try {
|
|
52
|
+
let o = l;
|
|
53
|
+
e && (c(e) || s(e)) && (o = s(e) ? y(o, e) : b(o, e)), r && (c(r) || s(r)) && (o = s(r) ? h(o, r) : d(o, r));
|
|
54
|
+
const t = w.stringify(o, {
|
|
55
|
+
case: n ? "kebab-case" : "camelCase",
|
|
56
|
+
omitValues: f,
|
|
57
|
+
prefix: p
|
|
58
|
+
});
|
|
59
|
+
t ? window.history.replaceState(
|
|
60
|
+
{},
|
|
61
|
+
"",
|
|
62
|
+
`${window.location.pathname}${t}`
|
|
63
|
+
) : window.history.replaceState({}, "", window.location.pathname);
|
|
64
|
+
} catch (o) {
|
|
65
|
+
i && i(o);
|
|
66
|
+
}
|
|
67
|
+
}, [l]), [u, C];
|
|
68
|
+
};
|
|
69
|
+
export {
|
|
70
|
+
j as default
|
|
71
|
+
};
|
package/package.json
CHANGED
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
"@types/react": "^19.0.8",
|
|
15
15
|
"@types/react-dom": "^19.0.3",
|
|
16
16
|
"@vitejs/plugin-react": "^4.3.4",
|
|
17
|
+
"@vitest/coverage-v8": "3.0.7",
|
|
17
18
|
"clsx": "^2.1.1",
|
|
18
19
|
"eslint": "^9.19.0",
|
|
19
20
|
"eslint-plugin-react-hooks": "^5.0.0",
|
|
@@ -30,10 +31,12 @@
|
|
|
30
31
|
"vite-plugin-dts": "^4.5.3",
|
|
31
32
|
"vitest": "^3.0.7"
|
|
32
33
|
},
|
|
34
|
+
"exports": {
|
|
35
|
+
"./*": "./dist/*.js"
|
|
36
|
+
},
|
|
33
37
|
"files": [
|
|
34
38
|
"dist"
|
|
35
39
|
],
|
|
36
|
-
"main": "./dist/index.js",
|
|
37
40
|
"peerDependencies": {
|
|
38
41
|
"lodash": "^4.17.21",
|
|
39
42
|
"react": "^19.0.0",
|
|
@@ -43,7 +46,8 @@
|
|
|
43
46
|
"build": "yarn lint && vite build --mode export",
|
|
44
47
|
"lint": "prettier --write . && eslint .",
|
|
45
48
|
"npm-publish": "yarn test --run && yarn build && yarn version --patch --no-git-tag-version && yarn publish --non-interactive",
|
|
46
|
-
"test": "vitest"
|
|
49
|
+
"test": "vitest",
|
|
50
|
+
"test:coverage": "vitest --coverage"
|
|
47
51
|
},
|
|
48
|
-
"version": "1.0.
|
|
52
|
+
"version": "1.0.12"
|
|
49
53
|
}
|
package/dist/index.d.ts
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
declare type SetUrlStateAction<T> = T | ((prevState: T) => T);
|
|
2
|
-
|
|
3
|
-
declare type StorageType = 'local' | 'session';
|
|
4
|
-
|
|
5
|
-
declare type StrictObject = {
|
|
6
|
-
[key: string]: any;
|
|
7
|
-
} & {
|
|
8
|
-
length?: never;
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
export declare const useDebounce: <T>(value: T, delay?: number) => T;
|
|
12
|
-
|
|
13
|
-
export declare const useDistinct: <T>(inputValue: T, options?: UseDistinctOptions) => UseDistinctReturn<T>;
|
|
14
|
-
|
|
15
|
-
declare type UseDistinctOptions = {
|
|
16
|
-
compare?: (a: any, b: any) => boolean;
|
|
17
|
-
debounce?: number;
|
|
18
|
-
deep?: boolean;
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
declare type UseDistinctReturn<T> = {
|
|
22
|
-
distinct: boolean;
|
|
23
|
-
prevValue: T | undefined;
|
|
24
|
-
value: T;
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
export declare const usePrev: <T>(value: T) => T | undefined;
|
|
28
|
-
|
|
29
|
-
export declare const useStorageState: <T extends StrictObject>(key: string, initialState: T, options?: UseStorageStateOptions) => [T, (value: T | ((prev: T) => T)) => void, {
|
|
30
|
-
removeKey: () => void;
|
|
31
|
-
}];
|
|
32
|
-
|
|
33
|
-
declare type UseStorageStateOptions = {
|
|
34
|
-
debounce?: number;
|
|
35
|
-
onError?: (err: Error) => void;
|
|
36
|
-
omitKeys?: string[] | ((value: any, key: string) => boolean);
|
|
37
|
-
pickKeys?: string[] | ((value: any, key: string) => boolean);
|
|
38
|
-
storage?: StorageType;
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
export declare const useThrottle: <T>(value: T, delay?: number) => T;
|
|
42
|
-
|
|
43
|
-
export declare const useUrlState: <T extends StrictObject>(initialState: T, options: UseUrlStateOptions) => [T, (value: SetUrlStateAction<T>) => void];
|
|
44
|
-
|
|
45
|
-
declare type UseUrlStateOptions = {
|
|
46
|
-
debounce?: number;
|
|
47
|
-
kebabCase?: boolean;
|
|
48
|
-
omitKeys?: string[] | ((value: any, key: string) => boolean);
|
|
49
|
-
omitValues?: any[] | ((value: any, key: string) => boolean);
|
|
50
|
-
onError?: (err: Error) => void;
|
|
51
|
-
pickKeys?: string[] | ((value: any, key: string) => boolean);
|
|
52
|
-
prefix?: string;
|
|
53
|
-
url: URL;
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
export { }
|
package/dist/index.js
DELETED
|
@@ -1,204 +0,0 @@
|
|
|
1
|
-
import { useState as g, useRef as y, useEffect as b, useCallback as C } from "react";
|
|
2
|
-
import T from "lodash/debounce";
|
|
3
|
-
import q from "lodash/isEqual";
|
|
4
|
-
import a from "lodash/isFunction";
|
|
5
|
-
import L from "lodash/isEmpty";
|
|
6
|
-
import I from "lodash/isMap";
|
|
7
|
-
import B from "lodash/isSet";
|
|
8
|
-
import K from "use-json";
|
|
9
|
-
import V from "lodash/merge";
|
|
10
|
-
import w from "lodash/omit";
|
|
11
|
-
import D from "lodash/omitBy";
|
|
12
|
-
import R from "lodash/pick";
|
|
13
|
-
import _ from "lodash/pickBy";
|
|
14
|
-
import h from "lodash/size";
|
|
15
|
-
import M from "lodash/throttle";
|
|
16
|
-
import U from "use-qs";
|
|
17
|
-
const O = 300, F = (e, t = O) => {
|
|
18
|
-
const [p, l] = g(e), f = y(
|
|
19
|
-
T((m) => {
|
|
20
|
-
l(m);
|
|
21
|
-
}, t)
|
|
22
|
-
);
|
|
23
|
-
return b(() => {
|
|
24
|
-
f.current(e);
|
|
25
|
-
}, [e]), b(() => {
|
|
26
|
-
const m = f.current;
|
|
27
|
-
return () => {
|
|
28
|
-
m.cancel();
|
|
29
|
-
};
|
|
30
|
-
}, []), p;
|
|
31
|
-
}, $ = (e, t) => e === t, ut = (e, t = {}) => {
|
|
32
|
-
const p = y(!1), l = y(t), f = y(e), m = y(
|
|
33
|
-
T((c) => {
|
|
34
|
-
const { compare: n, deep: o } = l.current;
|
|
35
|
-
!(a(n) ? n : o ? q : $)(c, f.current) && (S({
|
|
36
|
-
distinct: !0,
|
|
37
|
-
prevValue: f.current,
|
|
38
|
-
value: c
|
|
39
|
-
}), f.current = c);
|
|
40
|
-
}, l.current.debounce ?? 0)
|
|
41
|
-
), [d, S] = g({
|
|
42
|
-
distinct: !1,
|
|
43
|
-
prevValue: void 0,
|
|
44
|
-
value: e
|
|
45
|
-
}), u = C(() => {
|
|
46
|
-
p.current = !1, S((c) => ({
|
|
47
|
-
...c,
|
|
48
|
-
distinct: !1
|
|
49
|
-
}));
|
|
50
|
-
}, []);
|
|
51
|
-
return b(() => {
|
|
52
|
-
if (d.distinct && p.current) {
|
|
53
|
-
u();
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
56
|
-
const c = m.current;
|
|
57
|
-
c(e);
|
|
58
|
-
}), b(() => {
|
|
59
|
-
d.distinct && (p.current = !0);
|
|
60
|
-
}, [d.distinct]), b(() => {
|
|
61
|
-
const c = m.current;
|
|
62
|
-
return () => {
|
|
63
|
-
c.cancel();
|
|
64
|
-
};
|
|
65
|
-
}, []), d;
|
|
66
|
-
}, at = (e) => {
|
|
67
|
-
const t = y(void 0);
|
|
68
|
-
return b(() => {
|
|
69
|
-
t.current = e;
|
|
70
|
-
}), t.current;
|
|
71
|
-
}, v = () => typeof window < "u", A = { browser: v }, x = 500, k = "local", N = (e, t) => I(t) ? {
|
|
72
|
-
__type: "Map",
|
|
73
|
-
value: Array.from(t.entries())
|
|
74
|
-
} : B(t) ? {
|
|
75
|
-
__type: "Set",
|
|
76
|
-
value: Array.from(t)
|
|
77
|
-
} : t, j = (e, t) => t && t.__type === "Map" ? new Map(t.value) : t && t.__type === "Set" ? new Set(t.value) : t, ft = (e, t, p) => {
|
|
78
|
-
const l = y(p || {}), f = y(!1), [m, d] = g(t), S = F(
|
|
79
|
-
m,
|
|
80
|
-
l.current.debounce ?? x
|
|
81
|
-
);
|
|
82
|
-
b(() => {
|
|
83
|
-
if (!A.browser() || !f.current)
|
|
84
|
-
return;
|
|
85
|
-
const {
|
|
86
|
-
storage: c = k,
|
|
87
|
-
onError: n,
|
|
88
|
-
omitKeys: o,
|
|
89
|
-
pickKeys: i
|
|
90
|
-
} = l.current, s = c === "local" ? localStorage : sessionStorage;
|
|
91
|
-
if (s)
|
|
92
|
-
try {
|
|
93
|
-
let r = S;
|
|
94
|
-
o && (h(o) || a(o)) && (r = a(o) ? D(r, o) : w(r, o)), i && (h(i) || a(i)) && (r = a(i) ? _(r, i) : R(r, i)), s.setItem(e, K.stringify(r, N));
|
|
95
|
-
} catch (r) {
|
|
96
|
-
n && n(r);
|
|
97
|
-
}
|
|
98
|
-
}, [e, S]), b(() => {
|
|
99
|
-
const {
|
|
100
|
-
storage: c = k,
|
|
101
|
-
omitKeys: n,
|
|
102
|
-
onError: o,
|
|
103
|
-
pickKeys: i
|
|
104
|
-
} = l.current;
|
|
105
|
-
try {
|
|
106
|
-
const s = c === "local" ? localStorage : sessionStorage, r = s == null ? void 0 : s.getItem(e);
|
|
107
|
-
if (r) {
|
|
108
|
-
let E = K.parse(r, j);
|
|
109
|
-
n && (h(n) || a(n)) && (E = a(n) ? D(E, n) : w(E, n)), i && (h(i) || a(i)) && (E = a(i) ? _(E, i) : R(E, i)), d(
|
|
110
|
-
L(E) ? t : V({}, t, E)
|
|
111
|
-
);
|
|
112
|
-
}
|
|
113
|
-
} catch (s) {
|
|
114
|
-
o && o(s);
|
|
115
|
-
} finally {
|
|
116
|
-
f.current = !0;
|
|
117
|
-
}
|
|
118
|
-
}, []);
|
|
119
|
-
const u = C(() => {
|
|
120
|
-
if (!A.browser())
|
|
121
|
-
return;
|
|
122
|
-
d(t);
|
|
123
|
-
const { storage: c = k } = l.current, n = c === "local" ? localStorage : sessionStorage;
|
|
124
|
-
n == null || n.removeItem(e);
|
|
125
|
-
}, [e, t]);
|
|
126
|
-
return [m, d, { removeKey: u }];
|
|
127
|
-
}, Y = 300, mt = (e, t = Y) => {
|
|
128
|
-
const [p, l] = g(e), f = y(
|
|
129
|
-
M((m) => {
|
|
130
|
-
l(m);
|
|
131
|
-
}, t)
|
|
132
|
-
);
|
|
133
|
-
return b(() => {
|
|
134
|
-
f.current(e);
|
|
135
|
-
}, [e]), b(() => {
|
|
136
|
-
const m = f.current;
|
|
137
|
-
return () => {
|
|
138
|
-
m.cancel();
|
|
139
|
-
};
|
|
140
|
-
}, []), p;
|
|
141
|
-
}, z = 500, pt = (e, t) => {
|
|
142
|
-
const p = y(t), l = () => {
|
|
143
|
-
const {
|
|
144
|
-
kebabCase: S = !0,
|
|
145
|
-
omitKeys: u,
|
|
146
|
-
omitValues: c,
|
|
147
|
-
onError: n,
|
|
148
|
-
pickKeys: o,
|
|
149
|
-
prefix: i = "",
|
|
150
|
-
url: s
|
|
151
|
-
} = p.current;
|
|
152
|
-
if (!s.search)
|
|
153
|
-
return e;
|
|
154
|
-
try {
|
|
155
|
-
let r = U.parse(decodeURIComponent(s.search), {
|
|
156
|
-
case: S ? "kebab-case" : "camelCase",
|
|
157
|
-
omitValues: c,
|
|
158
|
-
prefix: i
|
|
159
|
-
});
|
|
160
|
-
return u && (h(u) || a(u)) && (r = a(u) ? D(r, u) : w(r, u)), o && (h(o) || a(o)) && (r = a(o) ? _(r, o) : R(r, o)), L(r) ? e : V({}, e, r);
|
|
161
|
-
} catch (r) {
|
|
162
|
-
return n && n(r), e;
|
|
163
|
-
}
|
|
164
|
-
}, [f, m] = g(l), d = F(
|
|
165
|
-
f,
|
|
166
|
-
p.current.debounce ?? z
|
|
167
|
-
);
|
|
168
|
-
return b(() => {
|
|
169
|
-
if (!A.browser())
|
|
170
|
-
return;
|
|
171
|
-
const {
|
|
172
|
-
kebabCase: S = !0,
|
|
173
|
-
omitKeys: u,
|
|
174
|
-
omitValues: c,
|
|
175
|
-
onError: n,
|
|
176
|
-
pickKeys: o,
|
|
177
|
-
prefix: i = ""
|
|
178
|
-
} = p.current;
|
|
179
|
-
try {
|
|
180
|
-
let s = d;
|
|
181
|
-
u && (h(u) || a(u)) && (s = a(u) ? D(s, u) : w(s, u)), o && (h(o) || a(o)) && (s = a(o) ? _(s, o) : R(s, o));
|
|
182
|
-
const r = U.stringify(s, {
|
|
183
|
-
case: S ? "kebab-case" : "camelCase",
|
|
184
|
-
omitValues: c,
|
|
185
|
-
prefix: i
|
|
186
|
-
});
|
|
187
|
-
r ? window.history.replaceState(
|
|
188
|
-
{},
|
|
189
|
-
"",
|
|
190
|
-
`${window.location.pathname}${r}`
|
|
191
|
-
) : window.history.replaceState({}, "", window.location.pathname);
|
|
192
|
-
} catch (s) {
|
|
193
|
-
n && n(s);
|
|
194
|
-
}
|
|
195
|
-
}, [d]), [f, m];
|
|
196
|
-
};
|
|
197
|
-
export {
|
|
198
|
-
F as useDebounce,
|
|
199
|
-
ut as useDistinct,
|
|
200
|
-
at as usePrev,
|
|
201
|
-
ft as useStorageState,
|
|
202
|
-
mt as useThrottle,
|
|
203
|
-
pt as useUrlState
|
|
204
|
-
};
|