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 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,4 @@
1
+ const e = () => typeof window < "u", n = { browser: e };
2
+ export {
3
+ n as i
4
+ };
@@ -0,0 +1,4 @@
1
+ declare const useDebounce: <T>(value: T, delay?: number) => T;
2
+ export default useDebounce;
3
+
4
+ export { }
@@ -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
+ };
@@ -0,0 +1,4 @@
1
+ declare const usePrev: <T>(value: T) => T | undefined;
2
+ export default usePrev;
3
+
4
+ export { }
@@ -0,0 +1,10 @@
1
+ import { useRef as t, useEffect as u } from "react";
2
+ const o = (r) => {
3
+ const e = t(void 0);
4
+ return u(() => {
5
+ e.current = r;
6
+ }), e.current;
7
+ };
8
+ export {
9
+ o as default
10
+ };
@@ -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,4 @@
1
+ declare const useThrottle: <T>(value: T, delay?: number) => T;
2
+ export default useThrottle;
3
+
4
+ export { }
@@ -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.10"
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
- };