react-browser-cache 1.0.0 → 1.0.1
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/cjs/hooks/useBrowserCache.js +22 -8
- package/dist/cjs/hooks/useBrowserCache.js.map +1 -1
- package/dist/cjs/hooks/useCacheState.js +24 -9
- package/dist/cjs/hooks/useCacheState.js.map +1 -1
- package/dist/cjs/provider/BrowserCacheProvider.js +4 -4
- package/dist/cjs/provider/BrowserCacheProvider.js.map +1 -1
- package/dist/hooks/useBrowserCache.d.ts.map +1 -1
- package/dist/hooks/useBrowserCache.js +22 -8
- package/dist/hooks/useBrowserCache.js.map +1 -1
- package/dist/hooks/useCacheState.d.ts +1 -0
- package/dist/hooks/useCacheState.d.ts.map +1 -1
- package/dist/hooks/useCacheState.js +25 -10
- package/dist/hooks/useCacheState.js.map +1 -1
- package/dist/provider/BrowserCacheProvider.js +4 -4
- package/dist/provider/BrowserCacheProvider.js.map +1 -1
- package/package.json +1 -1
|
@@ -10,6 +10,12 @@ const useBrowserCache = ({ key, fetcher, enabled = true, ...options }) => {
|
|
|
10
10
|
const [isLoading, setIsLoading] = (0, react_1.useState)(enabled);
|
|
11
11
|
const [isStale, setIsStale] = (0, react_1.useState)(false);
|
|
12
12
|
const isFetching = (0, react_1.useRef)(false);
|
|
13
|
+
const dataRef = (0, react_1.useRef)(null);
|
|
14
|
+
// Stabilize fetcher and options to avoid infinite loops
|
|
15
|
+
const fetcherRef = (0, react_1.useRef)(fetcher);
|
|
16
|
+
fetcherRef.current = fetcher;
|
|
17
|
+
const optionsRef = (0, react_1.useRef)(options);
|
|
18
|
+
optionsRef.current = options;
|
|
13
19
|
const refresh = (0, react_1.useCallback)(async (isManual = true) => {
|
|
14
20
|
if (isFetching.current)
|
|
15
21
|
return;
|
|
@@ -17,8 +23,9 @@ const useBrowserCache = ({ key, fetcher, enabled = true, ...options }) => {
|
|
|
17
23
|
if (isManual)
|
|
18
24
|
setIsLoading(true);
|
|
19
25
|
try {
|
|
20
|
-
const result = await
|
|
21
|
-
await cacheManager.set(key, result,
|
|
26
|
+
const result = await fetcherRef.current();
|
|
27
|
+
await cacheManager.set(key, result, optionsRef.current);
|
|
28
|
+
dataRef.current = result;
|
|
22
29
|
setData(result);
|
|
23
30
|
setError(null);
|
|
24
31
|
setIsStale(false);
|
|
@@ -30,21 +37,23 @@ const useBrowserCache = ({ key, fetcher, enabled = true, ...options }) => {
|
|
|
30
37
|
setIsLoading(false);
|
|
31
38
|
isFetching.current = false;
|
|
32
39
|
}
|
|
33
|
-
}, [key,
|
|
40
|
+
}, [key, cacheManager]);
|
|
34
41
|
(0, react_1.useEffect)(() => {
|
|
35
42
|
let mounted = true;
|
|
36
43
|
const load = async () => {
|
|
37
|
-
const cached = await cacheManager.get(key,
|
|
44
|
+
const cached = await cacheManager.get(key, optionsRef.current);
|
|
38
45
|
if (!mounted)
|
|
39
46
|
return;
|
|
40
47
|
if (cached !== null) {
|
|
41
48
|
if (cached.__isStale) {
|
|
49
|
+
dataRef.current = cached;
|
|
42
50
|
setData(cached);
|
|
43
51
|
setIsStale(true);
|
|
44
52
|
// Revalidate in background
|
|
45
53
|
refresh(false);
|
|
46
54
|
}
|
|
47
55
|
else {
|
|
56
|
+
dataRef.current = cached;
|
|
48
57
|
setData(cached);
|
|
49
58
|
setIsLoading(false);
|
|
50
59
|
}
|
|
@@ -59,11 +68,12 @@ const useBrowserCache = ({ key, fetcher, enabled = true, ...options }) => {
|
|
|
59
68
|
return () => {
|
|
60
69
|
mounted = false;
|
|
61
70
|
};
|
|
62
|
-
}, [key, enabled, cacheManager,
|
|
71
|
+
}, [key, enabled, cacheManager, refresh]);
|
|
63
72
|
// Subscribe to external updates (cross-tab sync)
|
|
64
73
|
(0, react_1.useEffect)(() => {
|
|
65
74
|
const unsubscribe = cacheManager.subscribe((updatedKey, newValue) => {
|
|
66
75
|
if (updatedKey === key) {
|
|
76
|
+
dataRef.current = newValue;
|
|
67
77
|
setData(newValue);
|
|
68
78
|
if (newValue === null) {
|
|
69
79
|
setIsStale(false);
|
|
@@ -73,10 +83,14 @@ const useBrowserCache = ({ key, fetcher, enabled = true, ...options }) => {
|
|
|
73
83
|
return () => unsubscribe();
|
|
74
84
|
}, [key, cacheManager]);
|
|
75
85
|
const mutate = (newValue) => {
|
|
76
|
-
const value = typeof newValue === 'function'
|
|
77
|
-
|
|
86
|
+
const value = typeof newValue === 'function'
|
|
87
|
+
? newValue(dataRef.current)
|
|
88
|
+
: newValue;
|
|
89
|
+
dataRef.current = value;
|
|
90
|
+
setData(value);
|
|
91
|
+
cacheManager.set(key, value, optionsRef.current);
|
|
78
92
|
};
|
|
79
|
-
const clear = () => cacheManager.remove(key,
|
|
93
|
+
const clear = () => cacheManager.remove(key, optionsRef.current);
|
|
80
94
|
return {
|
|
81
95
|
data,
|
|
82
96
|
error,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useBrowserCache.js","sourceRoot":"","sources":["../../../src/hooks/useBrowserCache.ts"],"names":[],"mappings":";;;AAAA,iCAAiE;AACjE,2EAAmE;AAS5D,MAAM,eAAe,GAAG,CAAI,EACjC,GAAG,EACH,OAAO,EACP,OAAO,GAAG,IAAI,EACd,GAAG,OAAO,EACgB,EAAE,EAAE;IAC9B,MAAM,EAAE,YAAY,EAAE,GAAG,IAAA,sCAAe,GAAE,CAAC;IAC3C,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,IAAA,gBAAQ,EAAW,IAAI,CAAC,CAAC;IACjD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,IAAA,gBAAQ,EAAe,IAAI,CAAC,CAAC;IACvD,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,IAAA,gBAAQ,EAAC,OAAO,CAAC,CAAC;IACpD,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,IAAA,gBAAQ,EAAC,KAAK,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"useBrowserCache.js","sourceRoot":"","sources":["../../../src/hooks/useBrowserCache.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,30 +6,40 @@ const BrowserCacheProvider_1 = require("../provider/BrowserCacheProvider");
|
|
|
6
6
|
const useCacheState = (key, initialValue, options) => {
|
|
7
7
|
const { cacheManager } = (0, BrowserCacheProvider_1.useCacheManager)();
|
|
8
8
|
const [value, setValueState] = (0, react_1.useState)(initialValue);
|
|
9
|
+
const [isReady, setIsReady] = (0, react_1.useState)(false);
|
|
9
10
|
const [isExpired, setIsExpired] = (0, react_1.useState)(false);
|
|
11
|
+
// Use a ref to always have access to the latest value for functional updates
|
|
12
|
+
const valueRef = (0, react_1.useRef)(initialValue);
|
|
13
|
+
// Stabilize options to avoid infinite loops when literals are passed
|
|
14
|
+
const optionsRef = (0, react_1.useRef)(options);
|
|
15
|
+
optionsRef.current = options;
|
|
10
16
|
(0, react_1.useEffect)(() => {
|
|
11
17
|
let mounted = true;
|
|
12
18
|
const load = async () => {
|
|
13
|
-
const cached = await cacheManager.get(key,
|
|
19
|
+
const cached = await cacheManager.get(key, optionsRef.current);
|
|
14
20
|
if (mounted) {
|
|
15
21
|
if (cached !== null) {
|
|
22
|
+
valueRef.current = cached;
|
|
16
23
|
setValueState(cached);
|
|
17
24
|
setIsExpired(false);
|
|
18
25
|
}
|
|
19
26
|
else if (initialValue !== undefined) {
|
|
20
|
-
|
|
27
|
+
// Only seed if we don't have a cached value
|
|
28
|
+
await cacheManager.set(key, initialValue, optionsRef.current);
|
|
21
29
|
}
|
|
30
|
+
setIsReady(true);
|
|
22
31
|
}
|
|
23
32
|
};
|
|
24
33
|
load();
|
|
25
34
|
return () => {
|
|
26
35
|
mounted = false;
|
|
27
36
|
};
|
|
28
|
-
}, [key, initialValue
|
|
29
|
-
// Subscribe to changes
|
|
37
|
+
}, [key, cacheManager]); // Removed initialValue and options from dependencies to stop loops
|
|
38
|
+
// Subscribe to changes from other tabs/hooks
|
|
30
39
|
(0, react_1.useEffect)(() => {
|
|
31
40
|
const unsubscribe = cacheManager.subscribe((updatedKey, newValue) => {
|
|
32
41
|
if (updatedKey === key) {
|
|
42
|
+
valueRef.current = newValue;
|
|
33
43
|
setValueState(newValue);
|
|
34
44
|
if (newValue === null)
|
|
35
45
|
setIsExpired(true);
|
|
@@ -38,16 +48,21 @@ const useCacheState = (key, initialValue, options) => {
|
|
|
38
48
|
return () => unsubscribe();
|
|
39
49
|
}, [key, cacheManager]);
|
|
40
50
|
const setValue = (0, react_1.useCallback)(async (newValue) => {
|
|
41
|
-
const val = typeof newValue === 'function'
|
|
42
|
-
|
|
51
|
+
const val = typeof newValue === 'function'
|
|
52
|
+
? newValue(valueRef.current)
|
|
53
|
+
: newValue;
|
|
54
|
+
// Update ref immediately so subsequent calls in the same tick are correct
|
|
55
|
+
valueRef.current = val;
|
|
43
56
|
setValueState(val);
|
|
44
|
-
|
|
45
|
-
|
|
57
|
+
// Persist to cache
|
|
58
|
+
await cacheManager.set(key, val, optionsRef.current);
|
|
59
|
+
}, [key, cacheManager]);
|
|
60
|
+
const clear = (0, react_1.useCallback)(() => cacheManager.remove(key, optionsRef.current), [key, cacheManager]);
|
|
46
61
|
const reset = (0, react_1.useCallback)(() => setValue(initialValue), [setValue, initialValue]);
|
|
47
62
|
return [
|
|
48
63
|
value,
|
|
49
64
|
setValue,
|
|
50
|
-
{ clear, reset, isExpired }
|
|
65
|
+
{ clear, reset, isExpired, isReady }
|
|
51
66
|
];
|
|
52
67
|
};
|
|
53
68
|
exports.useCacheState = useCacheState;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useCacheState.js","sourceRoot":"","sources":["../../../src/hooks/useCacheState.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"useCacheState.js","sourceRoot":"","sources":["../../../src/hooks/useCacheState.ts"],"names":[],"mappings":";;;AAAA,iCAAiE;AACjE,2EAAmE;AAG5D,MAAM,aAAa,GAAG,CAC3B,GAAW,EACX,YAAgB,EAChB,OAAsB,EACtB,EAAE;IACF,MAAM,EAAE,YAAY,EAAE,GAAG,IAAA,sCAAe,GAAE,CAAC;IAC3C,MAAM,CAAC,KAAK,EAAE,aAAa,CAAC,GAAG,IAAA,gBAAQ,EAAI,YAAiB,CAAC,CAAC;IAC9D,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,IAAA,gBAAQ,EAAC,KAAK,CAAC,CAAC;IAC9C,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,IAAA,gBAAQ,EAAC,KAAK,CAAC,CAAC;IAElD,6EAA6E;IAC7E,MAAM,QAAQ,GAAG,IAAA,cAAM,EAAI,YAAiB,CAAC,CAAC;IAC9C,qEAAqE;IACrE,MAAM,UAAU,GAAG,IAAA,cAAM,EAAC,OAAO,CAAC,CAAC;IACnC,UAAU,CAAC,OAAO,GAAG,OAAO,CAAC;IAE7B,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,IAAI,OAAO,GAAG,IAAI,CAAC;QAEnB,MAAM,IAAI,GAAG,KAAK,IAAI,EAAE;YACtB,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,GAAG,CAAI,GAAG,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC;YAClE,IAAI,OAAO,EAAE,CAAC;gBACZ,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;oBACpB,QAAQ,CAAC,OAAO,GAAG,MAAM,CAAC;oBAC1B,aAAa,CAAC,MAAM,CAAC,CAAC;oBACtB,YAAY,CAAC,KAAK,CAAC,CAAC;gBACtB,CAAC;qBAAM,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;oBACtC,4CAA4C;oBAC5C,MAAM,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,YAAY,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC;gBAChE,CAAC;gBACD,UAAU,CAAC,IAAI,CAAC,CAAC;YACnB,CAAC;QACH,CAAC,CAAC;QAEF,IAAI,EAAE,CAAC;QAEP,OAAO,GAAG,EAAE;YACV,OAAO,GAAG,KAAK,CAAC;QAClB,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,mEAAmE;IAE5F,6CAA6C;IAC7C,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,MAAM,WAAW,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC,UAAU,EAAE,QAAQ,EAAE,EAAE;YAClE,IAAI,UAAU,KAAK,GAAG,EAAE,CAAC;gBACvB,QAAQ,CAAC,OAAO,GAAG,QAAQ,CAAC;gBAC5B,aAAa,CAAC,QAAQ,CAAC,CAAC;gBACxB,IAAI,QAAQ,KAAK,IAAI;oBAAE,YAAY,CAAC,IAAI,CAAC,CAAC;YAC5C,CAAC;QACH,CAAC,CAAC,CAAC;QACH,OAAO,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC;IAC7B,CAAC,EAAE,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC,CAAC;IAExB,MAAM,QAAQ,GAAG,IAAA,mBAAW,EAAC,KAAK,EAAE,QAA8B,EAAE,EAAE;QACpE,MAAM,GAAG,GAAG,OAAO,QAAQ,KAAK,UAAU;YACxC,CAAC,CAAE,QAAqB,CAAC,QAAQ,CAAC,OAAO,CAAC;YAC1C,CAAC,CAAC,QAAQ,CAAC;QAEb,0EAA0E;QAC1E,QAAQ,CAAC,OAAO,GAAG,GAAG,CAAC;QACvB,aAAa,CAAC,GAAG,CAAC,CAAC;QAEnB,mBAAmB;QACnB,MAAM,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC;IACvD,CAAC,EAAE,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC,CAAC;IAExB,MAAM,KAAK,GAAG,IAAA,mBAAW,EAAC,GAAG,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,GAAG,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC,CAAC;IACnG,MAAM,KAAK,GAAG,IAAA,mBAAW,EAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,YAAiB,CAAC,EAAE,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC;IAEvF,OAAO;QACL,KAAK;QACL,QAAQ;QACR,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE;KAC5B,CAAC;AACb,CAAC,CAAC;AA1EW,QAAA,aAAa,iBA0ExB"}
|
|
@@ -6,18 +6,18 @@ const react_1 = require("react");
|
|
|
6
6
|
const cache_manager_1 = require("../core/cache-manager");
|
|
7
7
|
const BrowserCacheContext = (0, react_1.createContext)(null);
|
|
8
8
|
const BrowserCacheProvider = ({ children, config = {} }) => {
|
|
9
|
-
const mergedConfig = {
|
|
9
|
+
const mergedConfig = (0, react_1.useMemo)(() => ({
|
|
10
10
|
defaultStorage: config.defaultStorage || 'memory',
|
|
11
11
|
defaultTTL: config.defaultTTL || 1000 * 60 * 5, // 5 minutes
|
|
12
12
|
prefix: config.prefix || 'rbc_',
|
|
13
13
|
...config
|
|
14
|
-
};
|
|
14
|
+
}), [config.defaultStorage, config.defaultTTL, config.prefix, config.serialize, config.deserialize]);
|
|
15
15
|
const cacheManager = (0, react_1.useMemo)(() => new cache_manager_1.CacheManager(mergedConfig), [mergedConfig]);
|
|
16
|
-
const value = {
|
|
16
|
+
const value = (0, react_1.useMemo)(() => ({
|
|
17
17
|
cacheManager,
|
|
18
18
|
defaultTTL: mergedConfig.defaultTTL,
|
|
19
19
|
defaultStorage: mergedConfig.defaultStorage
|
|
20
|
-
};
|
|
20
|
+
}), [cacheManager, mergedConfig.defaultTTL, mergedConfig.defaultStorage]);
|
|
21
21
|
return ((0, jsx_runtime_1.jsx)(BrowserCacheContext.Provider, { value: value, children: children }));
|
|
22
22
|
};
|
|
23
23
|
exports.BrowserCacheProvider = BrowserCacheProvider;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BrowserCacheProvider.js","sourceRoot":"","sources":["../../../src/provider/BrowserCacheProvider.tsx"],"names":[],"mappings":";;;;AAAA,iCAA6E;AAC7E,yDAAqD;AASrD,MAAM,mBAAmB,GAAG,IAAA,qBAAa,EAAkC,IAAI,CAAC,CAAC;AAO1E,MAAM,oBAAoB,GAAwC,CAAC,EACxE,QAAQ,EACR,MAAM,GAAG,EAAE,EACZ,EAAE,EAAE;IACH,MAAM,YAAY,GAAsB;
|
|
1
|
+
{"version":3,"file":"BrowserCacheProvider.js","sourceRoot":"","sources":["../../../src/provider/BrowserCacheProvider.tsx"],"names":[],"mappings":";;;;AAAA,iCAA6E;AAC7E,yDAAqD;AASrD,MAAM,mBAAmB,GAAG,IAAA,qBAAa,EAAkC,IAAI,CAAC,CAAC;AAO1E,MAAM,oBAAoB,GAAwC,CAAC,EACxE,QAAQ,EACR,MAAM,GAAG,EAAE,EACZ,EAAE,EAAE;IACH,MAAM,YAAY,GAAsB,IAAA,eAAO,EAAC,GAAG,EAAE,CAAC,CAAC;QACrD,cAAc,EAAE,MAAM,CAAC,cAAc,IAAI,QAAQ;QACjD,UAAU,EAAE,MAAM,CAAC,UAAU,IAAI,IAAI,GAAG,EAAE,GAAG,CAAC,EAAE,YAAY;QAC5D,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,MAAM;QAC/B,GAAG,MAAM;KACV,CAAC,EAAE,CAAC,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC;IAErG,MAAM,YAAY,GAAG,IAAA,eAAO,EAAC,GAAG,EAAE,CAAC,IAAI,4BAAY,CAAC,YAAY,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;IAEnF,MAAM,KAAK,GAA6B,IAAA,eAAO,EAAC,GAAG,EAAE,CAAC,CAAC;QACrD,YAAY;QACZ,UAAU,EAAE,YAAY,CAAC,UAAU;QACnC,cAAc,EAAE,YAAY,CAAC,cAAc;KAC5C,CAAC,EAAE,CAAC,YAAY,EAAE,YAAY,CAAC,UAAU,EAAE,YAAY,CAAC,cAAc,CAAC,CAAC,CAAC;IAE1E,OAAO,CACL,uBAAC,mBAAmB,CAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,YACvC,QAAQ,GACoB,CAChC,CAAC;AACJ,CAAC,CAAC;AAxBW,QAAA,oBAAoB,wBAwB/B;AAEK,MAAM,eAAe,GAAG,GAAG,EAAE;IAClC,MAAM,OAAO,GAAG,IAAA,kBAAU,EAAC,mBAAmB,CAAC,CAAC;IAChD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;IAChF,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC;AANW,QAAA,eAAe,mBAM1B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useBrowserCache.d.ts","sourceRoot":"","sources":["../../src/hooks/useBrowserCache.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAExC,MAAM,WAAW,sBAAsB,CAAC,CAAC,CAAE,SAAQ,YAAY;IAC7D,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,CAAC;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,eAAO,MAAM,eAAe,GAAI,CAAC,EAAE,uCAKhC,sBAAsB,CAAC,CAAC,CAAC;;;;;;
|
|
1
|
+
{"version":3,"file":"useBrowserCache.d.ts","sourceRoot":"","sources":["../../src/hooks/useBrowserCache.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAExC,MAAM,WAAW,sBAAsB,CAAC,CAAC,CAAE,SAAQ,YAAY;IAC7D,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,CAAC;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,eAAO,MAAM,eAAe,GAAI,CAAC,EAAE,uCAKhC,sBAAsB,CAAC,CAAC,CAAC;;;;;;uBAoFA,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,KAAK,CAAC,CAAC;;CAqBtD,CAAC"}
|
|
@@ -7,6 +7,12 @@ export const useBrowserCache = ({ key, fetcher, enabled = true, ...options }) =>
|
|
|
7
7
|
const [isLoading, setIsLoading] = useState(enabled);
|
|
8
8
|
const [isStale, setIsStale] = useState(false);
|
|
9
9
|
const isFetching = useRef(false);
|
|
10
|
+
const dataRef = useRef(null);
|
|
11
|
+
// Stabilize fetcher and options to avoid infinite loops
|
|
12
|
+
const fetcherRef = useRef(fetcher);
|
|
13
|
+
fetcherRef.current = fetcher;
|
|
14
|
+
const optionsRef = useRef(options);
|
|
15
|
+
optionsRef.current = options;
|
|
10
16
|
const refresh = useCallback(async (isManual = true) => {
|
|
11
17
|
if (isFetching.current)
|
|
12
18
|
return;
|
|
@@ -14,8 +20,9 @@ export const useBrowserCache = ({ key, fetcher, enabled = true, ...options }) =>
|
|
|
14
20
|
if (isManual)
|
|
15
21
|
setIsLoading(true);
|
|
16
22
|
try {
|
|
17
|
-
const result = await
|
|
18
|
-
await cacheManager.set(key, result,
|
|
23
|
+
const result = await fetcherRef.current();
|
|
24
|
+
await cacheManager.set(key, result, optionsRef.current);
|
|
25
|
+
dataRef.current = result;
|
|
19
26
|
setData(result);
|
|
20
27
|
setError(null);
|
|
21
28
|
setIsStale(false);
|
|
@@ -27,21 +34,23 @@ export const useBrowserCache = ({ key, fetcher, enabled = true, ...options }) =>
|
|
|
27
34
|
setIsLoading(false);
|
|
28
35
|
isFetching.current = false;
|
|
29
36
|
}
|
|
30
|
-
}, [key,
|
|
37
|
+
}, [key, cacheManager]);
|
|
31
38
|
useEffect(() => {
|
|
32
39
|
let mounted = true;
|
|
33
40
|
const load = async () => {
|
|
34
|
-
const cached = await cacheManager.get(key,
|
|
41
|
+
const cached = await cacheManager.get(key, optionsRef.current);
|
|
35
42
|
if (!mounted)
|
|
36
43
|
return;
|
|
37
44
|
if (cached !== null) {
|
|
38
45
|
if (cached.__isStale) {
|
|
46
|
+
dataRef.current = cached;
|
|
39
47
|
setData(cached);
|
|
40
48
|
setIsStale(true);
|
|
41
49
|
// Revalidate in background
|
|
42
50
|
refresh(false);
|
|
43
51
|
}
|
|
44
52
|
else {
|
|
53
|
+
dataRef.current = cached;
|
|
45
54
|
setData(cached);
|
|
46
55
|
setIsLoading(false);
|
|
47
56
|
}
|
|
@@ -56,11 +65,12 @@ export const useBrowserCache = ({ key, fetcher, enabled = true, ...options }) =>
|
|
|
56
65
|
return () => {
|
|
57
66
|
mounted = false;
|
|
58
67
|
};
|
|
59
|
-
}, [key, enabled, cacheManager,
|
|
68
|
+
}, [key, enabled, cacheManager, refresh]);
|
|
60
69
|
// Subscribe to external updates (cross-tab sync)
|
|
61
70
|
useEffect(() => {
|
|
62
71
|
const unsubscribe = cacheManager.subscribe((updatedKey, newValue) => {
|
|
63
72
|
if (updatedKey === key) {
|
|
73
|
+
dataRef.current = newValue;
|
|
64
74
|
setData(newValue);
|
|
65
75
|
if (newValue === null) {
|
|
66
76
|
setIsStale(false);
|
|
@@ -70,10 +80,14 @@ export const useBrowserCache = ({ key, fetcher, enabled = true, ...options }) =>
|
|
|
70
80
|
return () => unsubscribe();
|
|
71
81
|
}, [key, cacheManager]);
|
|
72
82
|
const mutate = (newValue) => {
|
|
73
|
-
const value = typeof newValue === 'function'
|
|
74
|
-
|
|
83
|
+
const value = typeof newValue === 'function'
|
|
84
|
+
? newValue(dataRef.current)
|
|
85
|
+
: newValue;
|
|
86
|
+
dataRef.current = value;
|
|
87
|
+
setData(value);
|
|
88
|
+
cacheManager.set(key, value, optionsRef.current);
|
|
75
89
|
};
|
|
76
|
-
const clear = () => cacheManager.remove(key,
|
|
90
|
+
const clear = () => cacheManager.remove(key, optionsRef.current);
|
|
77
91
|
return {
|
|
78
92
|
data,
|
|
79
93
|
error,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useBrowserCache.js","sourceRoot":"","sources":["../../src/hooks/useBrowserCache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AASnE,MAAM,CAAC,MAAM,eAAe,GAAG,CAAI,EACjC,GAAG,EACH,OAAO,EACP,OAAO,GAAG,IAAI,EACd,GAAG,OAAO,EACgB,EAAE,EAAE;IAC9B,MAAM,EAAE,YAAY,EAAE,GAAG,eAAe,EAAE,CAAC;IAC3C,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAW,IAAI,CAAC,CAAC;IACjD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAe,IAAI,CAAC,CAAC;IACvD,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;IACpD,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"useBrowserCache.js","sourceRoot":"","sources":["../../src/hooks/useBrowserCache.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useCacheState.d.ts","sourceRoot":"","sources":["../../src/hooks/useCacheState.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAExC,eAAO,MAAM,aAAa,GAAI,CAAC,EAC7B,KAAK,MAAM,EACX,eAAe,CAAC,EAChB,UAAU,YAAY,
|
|
1
|
+
{"version":3,"file":"useCacheState.d.ts","sourceRoot":"","sources":["../../src/hooks/useCacheState.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAExC,eAAO,MAAM,aAAa,GAAI,CAAC,EAC7B,KAAK,MAAM,EACX,eAAe,CAAC,EAChB,UAAU,YAAY,6BAkDwB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC;;;;;EAqBnE,CAAC"}
|
|
@@ -1,32 +1,42 @@
|
|
|
1
|
-
import { useState, useEffect, useCallback } from 'react';
|
|
1
|
+
import { useState, useEffect, useCallback, useRef } from 'react';
|
|
2
2
|
import { useCacheManager } from '../provider/BrowserCacheProvider';
|
|
3
3
|
export const useCacheState = (key, initialValue, options) => {
|
|
4
4
|
const { cacheManager } = useCacheManager();
|
|
5
5
|
const [value, setValueState] = useState(initialValue);
|
|
6
|
+
const [isReady, setIsReady] = useState(false);
|
|
6
7
|
const [isExpired, setIsExpired] = useState(false);
|
|
8
|
+
// Use a ref to always have access to the latest value for functional updates
|
|
9
|
+
const valueRef = useRef(initialValue);
|
|
10
|
+
// Stabilize options to avoid infinite loops when literals are passed
|
|
11
|
+
const optionsRef = useRef(options);
|
|
12
|
+
optionsRef.current = options;
|
|
7
13
|
useEffect(() => {
|
|
8
14
|
let mounted = true;
|
|
9
15
|
const load = async () => {
|
|
10
|
-
const cached = await cacheManager.get(key,
|
|
16
|
+
const cached = await cacheManager.get(key, optionsRef.current);
|
|
11
17
|
if (mounted) {
|
|
12
18
|
if (cached !== null) {
|
|
19
|
+
valueRef.current = cached;
|
|
13
20
|
setValueState(cached);
|
|
14
21
|
setIsExpired(false);
|
|
15
22
|
}
|
|
16
23
|
else if (initialValue !== undefined) {
|
|
17
|
-
|
|
24
|
+
// Only seed if we don't have a cached value
|
|
25
|
+
await cacheManager.set(key, initialValue, optionsRef.current);
|
|
18
26
|
}
|
|
27
|
+
setIsReady(true);
|
|
19
28
|
}
|
|
20
29
|
};
|
|
21
30
|
load();
|
|
22
31
|
return () => {
|
|
23
32
|
mounted = false;
|
|
24
33
|
};
|
|
25
|
-
}, [key, initialValue
|
|
26
|
-
// Subscribe to changes
|
|
34
|
+
}, [key, cacheManager]); // Removed initialValue and options from dependencies to stop loops
|
|
35
|
+
// Subscribe to changes from other tabs/hooks
|
|
27
36
|
useEffect(() => {
|
|
28
37
|
const unsubscribe = cacheManager.subscribe((updatedKey, newValue) => {
|
|
29
38
|
if (updatedKey === key) {
|
|
39
|
+
valueRef.current = newValue;
|
|
30
40
|
setValueState(newValue);
|
|
31
41
|
if (newValue === null)
|
|
32
42
|
setIsExpired(true);
|
|
@@ -35,16 +45,21 @@ export const useCacheState = (key, initialValue, options) => {
|
|
|
35
45
|
return () => unsubscribe();
|
|
36
46
|
}, [key, cacheManager]);
|
|
37
47
|
const setValue = useCallback(async (newValue) => {
|
|
38
|
-
const val = typeof newValue === 'function'
|
|
39
|
-
|
|
48
|
+
const val = typeof newValue === 'function'
|
|
49
|
+
? newValue(valueRef.current)
|
|
50
|
+
: newValue;
|
|
51
|
+
// Update ref immediately so subsequent calls in the same tick are correct
|
|
52
|
+
valueRef.current = val;
|
|
40
53
|
setValueState(val);
|
|
41
|
-
|
|
42
|
-
|
|
54
|
+
// Persist to cache
|
|
55
|
+
await cacheManager.set(key, val, optionsRef.current);
|
|
56
|
+
}, [key, cacheManager]);
|
|
57
|
+
const clear = useCallback(() => cacheManager.remove(key, optionsRef.current), [key, cacheManager]);
|
|
43
58
|
const reset = useCallback(() => setValue(initialValue), [setValue, initialValue]);
|
|
44
59
|
return [
|
|
45
60
|
value,
|
|
46
61
|
setValue,
|
|
47
|
-
{ clear, reset, isExpired }
|
|
62
|
+
{ clear, reset, isExpired, isReady }
|
|
48
63
|
];
|
|
49
64
|
};
|
|
50
65
|
//# sourceMappingURL=useCacheState.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useCacheState.js","sourceRoot":"","sources":["../../src/hooks/useCacheState.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"useCacheState.js","sourceRoot":"","sources":["../../src/hooks/useCacheState.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,18 +3,18 @@ import { createContext, useContext, useMemo } from 'react';
|
|
|
3
3
|
import { CacheManager } from '../core/cache-manager';
|
|
4
4
|
const BrowserCacheContext = createContext(null);
|
|
5
5
|
export const BrowserCacheProvider = ({ children, config = {} }) => {
|
|
6
|
-
const mergedConfig = {
|
|
6
|
+
const mergedConfig = useMemo(() => ({
|
|
7
7
|
defaultStorage: config.defaultStorage || 'memory',
|
|
8
8
|
defaultTTL: config.defaultTTL || 1000 * 60 * 5, // 5 minutes
|
|
9
9
|
prefix: config.prefix || 'rbc_',
|
|
10
10
|
...config
|
|
11
|
-
};
|
|
11
|
+
}), [config.defaultStorage, config.defaultTTL, config.prefix, config.serialize, config.deserialize]);
|
|
12
12
|
const cacheManager = useMemo(() => new CacheManager(mergedConfig), [mergedConfig]);
|
|
13
|
-
const value = {
|
|
13
|
+
const value = useMemo(() => ({
|
|
14
14
|
cacheManager,
|
|
15
15
|
defaultTTL: mergedConfig.defaultTTL,
|
|
16
16
|
defaultStorage: mergedConfig.defaultStorage
|
|
17
|
-
};
|
|
17
|
+
}), [cacheManager, mergedConfig.defaultTTL, mergedConfig.defaultStorage]);
|
|
18
18
|
return (_jsx(BrowserCacheContext.Provider, { value: value, children: children }));
|
|
19
19
|
};
|
|
20
20
|
export const useCacheManager = () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BrowserCacheProvider.js","sourceRoot":"","sources":["../../src/provider/BrowserCacheProvider.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,aAAa,EAAE,UAAU,EAAE,OAAO,EAAa,MAAM,OAAO,CAAC;AAC7E,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AASrD,MAAM,mBAAmB,GAAG,aAAa,CAAkC,IAAI,CAAC,CAAC;AAOjF,MAAM,CAAC,MAAM,oBAAoB,GAAwC,CAAC,EACxE,QAAQ,EACR,MAAM,GAAG,EAAE,EACZ,EAAE,EAAE;IACH,MAAM,YAAY,GAAsB;
|
|
1
|
+
{"version":3,"file":"BrowserCacheProvider.js","sourceRoot":"","sources":["../../src/provider/BrowserCacheProvider.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,aAAa,EAAE,UAAU,EAAE,OAAO,EAAa,MAAM,OAAO,CAAC;AAC7E,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AASrD,MAAM,mBAAmB,GAAG,aAAa,CAAkC,IAAI,CAAC,CAAC;AAOjF,MAAM,CAAC,MAAM,oBAAoB,GAAwC,CAAC,EACxE,QAAQ,EACR,MAAM,GAAG,EAAE,EACZ,EAAE,EAAE;IACH,MAAM,YAAY,GAAsB,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QACrD,cAAc,EAAE,MAAM,CAAC,cAAc,IAAI,QAAQ;QACjD,UAAU,EAAE,MAAM,CAAC,UAAU,IAAI,IAAI,GAAG,EAAE,GAAG,CAAC,EAAE,YAAY;QAC5D,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,MAAM;QAC/B,GAAG,MAAM;KACV,CAAC,EAAE,CAAC,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC;IAErG,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,IAAI,YAAY,CAAC,YAAY,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;IAEnF,MAAM,KAAK,GAA6B,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QACrD,YAAY;QACZ,UAAU,EAAE,YAAY,CAAC,UAAU;QACnC,cAAc,EAAE,YAAY,CAAC,cAAc;KAC5C,CAAC,EAAE,CAAC,YAAY,EAAE,YAAY,CAAC,UAAU,EAAE,YAAY,CAAC,cAAc,CAAC,CAAC,CAAC;IAE1E,OAAO,CACL,KAAC,mBAAmB,CAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,YACvC,QAAQ,GACoB,CAChC,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,EAAE;IAClC,MAAM,OAAO,GAAG,UAAU,CAAC,mBAAmB,CAAC,CAAC;IAChD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;IAChF,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-browser-cache",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "Production-ready hook-based browser caching system for React with TTL, stale-while-revalidate, and cross-tab sync.",
|
|
5
5
|
"main": "./dist/cjs/index.js",
|
|
6
6
|
"module": "./dist/index.js",
|