@ttoss/react-hooks 2.3.12 → 2.3.13
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/dist/index.cjs +219 -0
- package/dist/{index.d.ts → index.d.cts} +15 -11
- package/dist/index.d.mts +33 -0
- package/dist/{esm/index.js → index.mjs} +82 -61
- package/package.json +6 -6
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
/** Powered by @ttoss/config. https://ttoss.dev/docs/modules/packages/config/ */
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, {
|
|
3
|
+
value: 'Module'
|
|
4
|
+
});
|
|
5
|
+
//#region \0rolldown/runtime.js
|
|
6
|
+
var __create = Object.create;
|
|
7
|
+
var __defProp = Object.defineProperty;
|
|
8
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
9
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
10
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
11
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
15
|
+
key = keys[i];
|
|
16
|
+
if (!__hasOwnProp.call(to, key) && key !== except) {
|
|
17
|
+
__defProp(to, key, {
|
|
18
|
+
get: (k => from[k]).bind(null, key),
|
|
19
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return to;
|
|
25
|
+
};
|
|
26
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
27
|
+
value: mod,
|
|
28
|
+
enumerable: true
|
|
29
|
+
}) : target, mod));
|
|
30
|
+
|
|
31
|
+
//#endregion
|
|
32
|
+
let react = require("react");
|
|
33
|
+
react = __toESM(react, 1);
|
|
34
|
+
|
|
35
|
+
//#region src/useDebounce.ts
|
|
36
|
+
const useDebounce = (value, delay) => {
|
|
37
|
+
const [debouncedValue, setDebouncedValue] = react.useState(value);
|
|
38
|
+
react.useEffect(() => {
|
|
39
|
+
const timer = setTimeout(() => {
|
|
40
|
+
return setDebouncedValue(value);
|
|
41
|
+
}, delay || 500);
|
|
42
|
+
return () => {
|
|
43
|
+
clearTimeout(timer);
|
|
44
|
+
};
|
|
45
|
+
}, [value, delay]);
|
|
46
|
+
return debouncedValue;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
//#endregion
|
|
50
|
+
//#region src/useScript.ts
|
|
51
|
+
/**
|
|
52
|
+
* https://usehooks.com/useScript/
|
|
53
|
+
*
|
|
54
|
+
* @param src: string - the url of the script to load.
|
|
55
|
+
* @returns status: Status
|
|
56
|
+
*/
|
|
57
|
+
const useScript = src => {
|
|
58
|
+
/**
|
|
59
|
+
* Keep track of script status ("idle", "loading", "ready", "error")
|
|
60
|
+
*/
|
|
61
|
+
const [status, setStatus] = react.useState(src ? "loading" : "idle");
|
|
62
|
+
react.useEffect(() => {
|
|
63
|
+
/**
|
|
64
|
+
* Allow falsy src value if waiting on other data needed for
|
|
65
|
+
* constructing the script URL passed to this hook.
|
|
66
|
+
*/
|
|
67
|
+
if (!src) {
|
|
68
|
+
setStatus("idle");
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Fetch existing script element by src.
|
|
73
|
+
* It may have been added by another instance of this hook.
|
|
74
|
+
*/
|
|
75
|
+
let script = document.querySelector(`script[src="${src}"]`);
|
|
76
|
+
if (!script) {
|
|
77
|
+
/**
|
|
78
|
+
* Create script element and set its src.
|
|
79
|
+
*/
|
|
80
|
+
script = document.createElement("script");
|
|
81
|
+
script.src = src;
|
|
82
|
+
script.async = true;
|
|
83
|
+
script.setAttribute("data-status", "loading");
|
|
84
|
+
/**
|
|
85
|
+
* Add script to document body
|
|
86
|
+
*/
|
|
87
|
+
document.body.appendChild(script);
|
|
88
|
+
/**
|
|
89
|
+
* Store status in attribute on script.
|
|
90
|
+
* This can be read by other instances of this hook.
|
|
91
|
+
*/
|
|
92
|
+
const setAttributeFromEvent = event => {
|
|
93
|
+
if (script) script.setAttribute("data-status", event.type === "load" ? "ready" : "error");
|
|
94
|
+
};
|
|
95
|
+
script.addEventListener("load", setAttributeFromEvent);
|
|
96
|
+
script.addEventListener("error", setAttributeFromEvent);
|
|
97
|
+
} else
|
|
98
|
+
/**
|
|
99
|
+
* Grab existing script status from attribute and set to state.
|
|
100
|
+
*/
|
|
101
|
+
setStatus(script.getAttribute("data-status") || "error");
|
|
102
|
+
/**
|
|
103
|
+
* Script event handler to update status in state
|
|
104
|
+
* Note: Even if the script already exists we still need to add
|
|
105
|
+
* event handlers to update the state for *this* hook instance.
|
|
106
|
+
*/
|
|
107
|
+
const setStateFromEvent = event => {
|
|
108
|
+
setStatus(event.type === "load" ? "ready" : "error");
|
|
109
|
+
};
|
|
110
|
+
/**
|
|
111
|
+
* Add event listeners.
|
|
112
|
+
*/
|
|
113
|
+
script.addEventListener("load", setStateFromEvent);
|
|
114
|
+
script.addEventListener("error", setStateFromEvent);
|
|
115
|
+
/**
|
|
116
|
+
* Remove event listeners on cleanup.
|
|
117
|
+
*/
|
|
118
|
+
return () => {
|
|
119
|
+
if (script) {
|
|
120
|
+
script.removeEventListener("load", setStateFromEvent);
|
|
121
|
+
script.removeEventListener("error", setStateFromEvent);
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
},
|
|
125
|
+
/**
|
|
126
|
+
* Only re-run effect if script src changes.
|
|
127
|
+
*/
|
|
128
|
+
[src]);
|
|
129
|
+
return {
|
|
130
|
+
status
|
|
131
|
+
};
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
//#endregion
|
|
135
|
+
//#region src/useStorage.ts
|
|
136
|
+
function useStorage(key, defaultValue, options) {
|
|
137
|
+
const {
|
|
138
|
+
serializer,
|
|
139
|
+
parser,
|
|
140
|
+
logger,
|
|
141
|
+
syncData,
|
|
142
|
+
storage
|
|
143
|
+
} = react.useMemo(() => {
|
|
144
|
+
return {
|
|
145
|
+
serializer: JSON.stringify,
|
|
146
|
+
parser: JSON.parse,
|
|
147
|
+
logger: console.log,
|
|
148
|
+
syncData: true,
|
|
149
|
+
...options
|
|
150
|
+
};
|
|
151
|
+
}, [options]);
|
|
152
|
+
const effectiveStorage = storage ?? (typeof window !== "undefined" ? window.localStorage : void 0);
|
|
153
|
+
const rawValueRef = react.useRef(null);
|
|
154
|
+
const [value, setValue] = react.useState(() => {
|
|
155
|
+
if (typeof window === "undefined" || !effectiveStorage) return defaultValue;
|
|
156
|
+
try {
|
|
157
|
+
rawValueRef.current = effectiveStorage.getItem(key);
|
|
158
|
+
return rawValueRef.current ? parser(rawValueRef.current) : defaultValue;
|
|
159
|
+
} catch (error) {
|
|
160
|
+
logger(error);
|
|
161
|
+
return defaultValue;
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
react.useEffect(() => {
|
|
165
|
+
if (typeof window === "undefined" || !effectiveStorage) return;
|
|
166
|
+
const updateLocalStorage = () => {
|
|
167
|
+
if (value !== void 0) {
|
|
168
|
+
const newValue = serializer(value);
|
|
169
|
+
const oldValue = rawValueRef.current;
|
|
170
|
+
rawValueRef.current = newValue;
|
|
171
|
+
effectiveStorage.setItem(key, newValue);
|
|
172
|
+
window.dispatchEvent(new StorageEvent("storage", {
|
|
173
|
+
storageArea: effectiveStorage,
|
|
174
|
+
url: window.location.href,
|
|
175
|
+
key,
|
|
176
|
+
newValue,
|
|
177
|
+
oldValue
|
|
178
|
+
}));
|
|
179
|
+
} else {
|
|
180
|
+
effectiveStorage.removeItem(key);
|
|
181
|
+
window.dispatchEvent(new StorageEvent("storage", {
|
|
182
|
+
storageArea: effectiveStorage,
|
|
183
|
+
url: window.location.href,
|
|
184
|
+
key
|
|
185
|
+
}));
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
try {
|
|
189
|
+
updateLocalStorage();
|
|
190
|
+
} catch (error) {
|
|
191
|
+
logger(error);
|
|
192
|
+
}
|
|
193
|
+
}, [key, logger, serializer, effectiveStorage, value]);
|
|
194
|
+
react.useEffect(() => {
|
|
195
|
+
if (!syncData) return;
|
|
196
|
+
const handleStorageChange = e => {
|
|
197
|
+
if (e.key !== key || e.storageArea !== effectiveStorage) return;
|
|
198
|
+
try {
|
|
199
|
+
if (e.newValue !== rawValueRef.current) {
|
|
200
|
+
rawValueRef.current = e.newValue;
|
|
201
|
+
setValue(e.newValue ? parser(e.newValue) : void 0);
|
|
202
|
+
}
|
|
203
|
+
} catch (error) {
|
|
204
|
+
logger(error);
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
if (typeof window === "undefined") return;
|
|
208
|
+
window.addEventListener("storage", handleStorageChange);
|
|
209
|
+
return () => {
|
|
210
|
+
return window.removeEventListener("storage", handleStorageChange);
|
|
211
|
+
};
|
|
212
|
+
}, [key, logger, parser, effectiveStorage, syncData]);
|
|
213
|
+
return [value, setValue];
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
//#endregion
|
|
217
|
+
exports.useDebounce = useDebounce;
|
|
218
|
+
exports.useScript = useScript;
|
|
219
|
+
exports.useStorage = useStorage;
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
1
|
|
|
3
|
-
|
|
2
|
+
import * as React from "react";
|
|
4
3
|
|
|
4
|
+
//#region src/useDebounce.d.ts
|
|
5
|
+
declare const useDebounce: <T>(value: T, delay?: number) => T;
|
|
6
|
+
//#endregion
|
|
7
|
+
//#region src/useScript.d.ts
|
|
5
8
|
type ScriptStatus = 'idle' | 'loading' | 'ready' | 'error';
|
|
6
9
|
/**
|
|
7
10
|
* https://usehooks.com/useScript/
|
|
@@ -10,20 +13,21 @@ type ScriptStatus = 'idle' | 'loading' | 'ready' | 'error';
|
|
|
10
13
|
* @returns status: Status
|
|
11
14
|
*/
|
|
12
15
|
declare const useScript: (src: string) => {
|
|
13
|
-
|
|
16
|
+
status: ScriptStatus;
|
|
14
17
|
};
|
|
15
|
-
|
|
18
|
+
//#endregion
|
|
19
|
+
//#region src/useStorage.d.ts
|
|
16
20
|
type Serializer<T> = (object: T | undefined) => string;
|
|
17
21
|
type Parser<T> = (val: string) => T | undefined;
|
|
18
22
|
type Setter<T> = React.Dispatch<React.SetStateAction<T | undefined>>;
|
|
19
23
|
type Options<T> = Partial<{
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
24
|
+
serializer: Serializer<T>;
|
|
25
|
+
parser: Parser<T>;
|
|
26
|
+
logger: (error: any) => void;
|
|
27
|
+
syncData: boolean;
|
|
28
|
+
storage?: Storage;
|
|
25
29
|
}>;
|
|
26
30
|
declare function useStorage<T>(key: string, defaultValue: T, options?: Options<T>): [T, Setter<T>];
|
|
27
31
|
declare function useStorage<T>(key: string, defaultValue?: undefined, options?: Options<T>): [T | undefined, Setter<T>];
|
|
28
|
-
|
|
29
|
-
export { type ScriptStatus, useDebounce, useScript, useStorage };
|
|
32
|
+
//#endregion
|
|
33
|
+
export { type ScriptStatus, useDebounce, useScript, useStorage };
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
|
|
4
|
+
//#region src/useDebounce.d.ts
|
|
5
|
+
declare const useDebounce: <T>(value: T, delay?: number) => T;
|
|
6
|
+
//#endregion
|
|
7
|
+
//#region src/useScript.d.ts
|
|
8
|
+
type ScriptStatus = 'idle' | 'loading' | 'ready' | 'error';
|
|
9
|
+
/**
|
|
10
|
+
* https://usehooks.com/useScript/
|
|
11
|
+
*
|
|
12
|
+
* @param src: string - the url of the script to load.
|
|
13
|
+
* @returns status: Status
|
|
14
|
+
*/
|
|
15
|
+
declare const useScript: (src: string) => {
|
|
16
|
+
status: ScriptStatus;
|
|
17
|
+
};
|
|
18
|
+
//#endregion
|
|
19
|
+
//#region src/useStorage.d.ts
|
|
20
|
+
type Serializer<T> = (object: T | undefined) => string;
|
|
21
|
+
type Parser<T> = (val: string) => T | undefined;
|
|
22
|
+
type Setter<T> = React.Dispatch<React.SetStateAction<T | undefined>>;
|
|
23
|
+
type Options<T> = Partial<{
|
|
24
|
+
serializer: Serializer<T>;
|
|
25
|
+
parser: Parser<T>;
|
|
26
|
+
logger: (error: any) => void;
|
|
27
|
+
syncData: boolean;
|
|
28
|
+
storage?: Storage;
|
|
29
|
+
}>;
|
|
30
|
+
declare function useStorage<T>(key: string, defaultValue: T, options?: Options<T>): [T, Setter<T>];
|
|
31
|
+
declare function useStorage<T>(key: string, defaultValue?: undefined, options?: Options<T>): [T | undefined, Setter<T>];
|
|
32
|
+
//#endregion
|
|
33
|
+
export { type ScriptStatus, useDebounce, useScript, useStorage };
|
|
@@ -1,13 +1,8 @@
|
|
|
1
1
|
/** Powered by @ttoss/config. https://ttoss.dev/docs/modules/packages/config/ */
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __name = (target, value) => __defProp(target, "name", {
|
|
4
|
-
value,
|
|
5
|
-
configurable: true
|
|
6
|
-
});
|
|
7
|
-
|
|
8
|
-
// src/useDebounce.ts
|
|
9
2
|
import * as React from "react";
|
|
10
|
-
|
|
3
|
+
|
|
4
|
+
//#region src/useDebounce.ts
|
|
5
|
+
const useDebounce = (value, delay) => {
|
|
11
6
|
const [debouncedValue, setDebouncedValue] = React.useState(value);
|
|
12
7
|
React.useEffect(() => {
|
|
13
8
|
const timer = setTimeout(() => {
|
|
@@ -18,39 +13,77 @@ var useDebounce = /* @__PURE__ */__name((value, delay) => {
|
|
|
18
13
|
};
|
|
19
14
|
}, [value, delay]);
|
|
20
15
|
return debouncedValue;
|
|
21
|
-
}
|
|
16
|
+
};
|
|
22
17
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
18
|
+
//#endregion
|
|
19
|
+
//#region src/useScript.ts
|
|
20
|
+
/**
|
|
21
|
+
* https://usehooks.com/useScript/
|
|
22
|
+
*
|
|
23
|
+
* @param src: string - the url of the script to load.
|
|
24
|
+
* @returns status: Status
|
|
25
|
+
*/
|
|
26
|
+
const useScript = src => {
|
|
27
|
+
/**
|
|
28
|
+
* Keep track of script status ("idle", "loading", "ready", "error")
|
|
29
|
+
*/
|
|
30
|
+
const [status, setStatus] = React.useState(src ? "loading" : "idle");
|
|
31
|
+
React.useEffect(() => {
|
|
32
|
+
/**
|
|
33
|
+
* Allow falsy src value if waiting on other data needed for
|
|
34
|
+
* constructing the script URL passed to this hook.
|
|
35
|
+
*/
|
|
28
36
|
if (!src) {
|
|
29
37
|
setStatus("idle");
|
|
30
38
|
return;
|
|
31
39
|
}
|
|
40
|
+
/**
|
|
41
|
+
* Fetch existing script element by src.
|
|
42
|
+
* It may have been added by another instance of this hook.
|
|
43
|
+
*/
|
|
32
44
|
let script = document.querySelector(`script[src="${src}"]`);
|
|
33
45
|
if (!script) {
|
|
46
|
+
/**
|
|
47
|
+
* Create script element and set its src.
|
|
48
|
+
*/
|
|
34
49
|
script = document.createElement("script");
|
|
35
50
|
script.src = src;
|
|
36
51
|
script.async = true;
|
|
37
52
|
script.setAttribute("data-status", "loading");
|
|
53
|
+
/**
|
|
54
|
+
* Add script to document body
|
|
55
|
+
*/
|
|
38
56
|
document.body.appendChild(script);
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
57
|
+
/**
|
|
58
|
+
* Store status in attribute on script.
|
|
59
|
+
* This can be read by other instances of this hook.
|
|
60
|
+
*/
|
|
61
|
+
const setAttributeFromEvent = event => {
|
|
62
|
+
if (script) script.setAttribute("data-status", event.type === "load" ? "ready" : "error");
|
|
63
|
+
};
|
|
44
64
|
script.addEventListener("load", setAttributeFromEvent);
|
|
45
65
|
script.addEventListener("error", setAttributeFromEvent);
|
|
46
|
-
} else
|
|
66
|
+
} else
|
|
67
|
+
/**
|
|
68
|
+
* Grab existing script status from attribute and set to state.
|
|
69
|
+
*/
|
|
47
70
|
setStatus(script.getAttribute("data-status") || "error");
|
|
48
|
-
|
|
49
|
-
|
|
71
|
+
/**
|
|
72
|
+
* Script event handler to update status in state
|
|
73
|
+
* Note: Even if the script already exists we still need to add
|
|
74
|
+
* event handlers to update the state for *this* hook instance.
|
|
75
|
+
*/
|
|
76
|
+
const setStateFromEvent = event => {
|
|
50
77
|
setStatus(event.type === "load" ? "ready" : "error");
|
|
51
|
-
}
|
|
78
|
+
};
|
|
79
|
+
/**
|
|
80
|
+
* Add event listeners.
|
|
81
|
+
*/
|
|
52
82
|
script.addEventListener("load", setStateFromEvent);
|
|
53
83
|
script.addEventListener("error", setStateFromEvent);
|
|
84
|
+
/**
|
|
85
|
+
* Remove event listeners on cleanup.
|
|
86
|
+
*/
|
|
54
87
|
return () => {
|
|
55
88
|
if (script) {
|
|
56
89
|
script.removeEventListener("load", setStateFromEvent);
|
|
@@ -65,48 +98,41 @@ var useScript = /* @__PURE__ */__name(src => {
|
|
|
65
98
|
return {
|
|
66
99
|
status
|
|
67
100
|
};
|
|
68
|
-
}
|
|
101
|
+
};
|
|
69
102
|
|
|
70
|
-
|
|
71
|
-
|
|
103
|
+
//#endregion
|
|
104
|
+
//#region src/useStorage.ts
|
|
72
105
|
function useStorage(key, defaultValue, options) {
|
|
73
|
-
const
|
|
106
|
+
const {
|
|
107
|
+
serializer,
|
|
108
|
+
parser,
|
|
109
|
+
logger,
|
|
110
|
+
syncData,
|
|
111
|
+
storage
|
|
112
|
+
} = React.useMemo(() => {
|
|
74
113
|
return {
|
|
75
114
|
serializer: JSON.stringify,
|
|
76
115
|
parser: JSON.parse,
|
|
77
|
-
// eslint-disable-next-line no-console
|
|
78
116
|
logger: console.log,
|
|
79
117
|
syncData: true,
|
|
80
118
|
...options
|
|
81
119
|
};
|
|
82
120
|
}, [options]);
|
|
83
|
-
const {
|
|
84
|
-
serializer,
|
|
85
|
-
parser,
|
|
86
|
-
logger,
|
|
87
|
-
syncData,
|
|
88
|
-
storage
|
|
89
|
-
} = opts;
|
|
90
121
|
const effectiveStorage = storage ?? (typeof window !== "undefined" ? window.localStorage : void 0);
|
|
91
|
-
const rawValueRef =
|
|
92
|
-
const [value, setValue] =
|
|
93
|
-
if (typeof window === "undefined" || !effectiveStorage)
|
|
94
|
-
return defaultValue;
|
|
95
|
-
}
|
|
122
|
+
const rawValueRef = React.useRef(null);
|
|
123
|
+
const [value, setValue] = React.useState(() => {
|
|
124
|
+
if (typeof window === "undefined" || !effectiveStorage) return defaultValue;
|
|
96
125
|
try {
|
|
97
126
|
rawValueRef.current = effectiveStorage.getItem(key);
|
|
98
|
-
|
|
99
|
-
return res;
|
|
127
|
+
return rawValueRef.current ? parser(rawValueRef.current) : defaultValue;
|
|
100
128
|
} catch (error) {
|
|
101
129
|
logger(error);
|
|
102
130
|
return defaultValue;
|
|
103
131
|
}
|
|
104
132
|
});
|
|
105
|
-
|
|
106
|
-
if (typeof window === "undefined" || !effectiveStorage)
|
|
107
|
-
|
|
108
|
-
}
|
|
109
|
-
const updateLocalStorage = /* @__PURE__ */__name(() => {
|
|
133
|
+
React.useEffect(() => {
|
|
134
|
+
if (typeof window === "undefined" || !effectiveStorage) return;
|
|
135
|
+
const updateLocalStorage = () => {
|
|
110
136
|
if (value !== void 0) {
|
|
111
137
|
const newValue = serializer(value);
|
|
112
138
|
const oldValue = rawValueRef.current;
|
|
@@ -127,21 +153,17 @@ function useStorage(key, defaultValue, options) {
|
|
|
127
153
|
key
|
|
128
154
|
}));
|
|
129
155
|
}
|
|
130
|
-
}
|
|
156
|
+
};
|
|
131
157
|
try {
|
|
132
158
|
updateLocalStorage();
|
|
133
159
|
} catch (error) {
|
|
134
160
|
logger(error);
|
|
135
161
|
}
|
|
136
162
|
}, [key, logger, serializer, effectiveStorage, value]);
|
|
137
|
-
|
|
138
|
-
if (!syncData)
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
const handleStorageChange = /* @__PURE__ */__name(e => {
|
|
142
|
-
if (e.key !== key || e.storageArea !== effectiveStorage) {
|
|
143
|
-
return;
|
|
144
|
-
}
|
|
163
|
+
React.useEffect(() => {
|
|
164
|
+
if (!syncData) return;
|
|
165
|
+
const handleStorageChange = e => {
|
|
166
|
+
if (e.key !== key || e.storageArea !== effectiveStorage) return;
|
|
145
167
|
try {
|
|
146
168
|
if (e.newValue !== rawValueRef.current) {
|
|
147
169
|
rawValueRef.current = e.newValue;
|
|
@@ -150,10 +172,8 @@ function useStorage(key, defaultValue, options) {
|
|
|
150
172
|
} catch (error) {
|
|
151
173
|
logger(error);
|
|
152
174
|
}
|
|
153
|
-
}
|
|
154
|
-
if (typeof window === "undefined")
|
|
155
|
-
return;
|
|
156
|
-
}
|
|
175
|
+
};
|
|
176
|
+
if (typeof window === "undefined") return;
|
|
157
177
|
window.addEventListener("storage", handleStorageChange);
|
|
158
178
|
return () => {
|
|
159
179
|
return window.removeEventListener("storage", handleStorageChange);
|
|
@@ -161,5 +181,6 @@ function useStorage(key, defaultValue, options) {
|
|
|
161
181
|
}, [key, logger, parser, effectiveStorage, syncData]);
|
|
162
182
|
return [value, setValue];
|
|
163
183
|
}
|
|
164
|
-
|
|
184
|
+
|
|
185
|
+
//#endregion
|
|
165
186
|
export { useDebounce, useScript, useStorage };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ttoss/react-hooks",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.13",
|
|
4
4
|
"description": "React hooks.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"React",
|
|
@@ -29,10 +29,10 @@
|
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"@types/react": "^19.2.14",
|
|
31
31
|
"jest": "^30.3.0",
|
|
32
|
-
"react": "^19.2.
|
|
33
|
-
"
|
|
34
|
-
"@ttoss/config": "^1.37.
|
|
35
|
-
"@ttoss/test-utils": "^4.2.
|
|
32
|
+
"react": "^19.2.6",
|
|
33
|
+
"tsdown": "^0.22.0",
|
|
34
|
+
"@ttoss/config": "^1.37.13",
|
|
35
|
+
"@ttoss/test-utils": "^4.2.13"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
38
|
"react": ">=16.8.0"
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"provenance": true
|
|
43
43
|
},
|
|
44
44
|
"scripts": {
|
|
45
|
-
"build": "
|
|
45
|
+
"build": "tsdown",
|
|
46
46
|
"test": "jest --projects tests/unit"
|
|
47
47
|
}
|
|
48
48
|
}
|