@choksheak/react-utils 0.3.9 → 0.4.0
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/NoSSR.cjs +7 -30
- package/NoSSR.min.cjs +1 -1
- package/NoSSR.min.cjs.map +1 -1
- package/NoSSR.min.mjs +1 -1
- package/NoSSR.min.mjs.map +1 -1
- package/NoSSR.mjs +2 -0
- package/chunk-33UMQLKY.mjs +43 -0
- package/chunk-3V7WBGWQ.mjs +16 -0
- package/chunk-3X25NN6X.cjs +195 -0
- package/chunk-5DO7KC3L.cjs +43 -0
- package/chunk-5PDGU37E.cjs +104 -0
- package/chunk-6ZZ54XM5.min.mjs +2 -0
- package/chunk-6ZZ54XM5.min.mjs.map +1 -0
- package/chunk-74BS2FAO.cjs +12 -0
- package/chunk-F5L32IUC.min.cjs +2 -0
- package/chunk-F5L32IUC.min.cjs.map +1 -0
- package/chunk-GPV6JIQK.mjs +17 -0
- package/chunk-KE3RXVMS.min.cjs +2 -0
- package/chunk-KE3RXVMS.min.cjs.map +1 -0
- package/chunk-KILGR7YA.min.mjs +2 -0
- package/chunk-KILGR7YA.min.mjs.map +1 -0
- package/chunk-KRXENFK3.mjs +195 -0
- package/chunk-MWDH7YON.min.mjs +2 -0
- package/chunk-MWDH7YON.min.mjs.map +1 -0
- package/chunk-NTFFK7ZH.min.cjs +2 -0
- package/chunk-NTFFK7ZH.min.cjs.map +1 -0
- package/chunk-O3RBYG3W.min.cjs +2 -0
- package/chunk-O3RBYG3W.min.cjs.map +1 -0
- package/chunk-PHLY3LR4.mjs +104 -0
- package/chunk-RM4ZGGZ2.min.mjs +2 -0
- package/chunk-RM4ZGGZ2.min.mjs.map +1 -0
- package/chunk-TEZPF6BG.min.cjs +2 -0
- package/chunk-TEZPF6BG.min.cjs.map +1 -0
- package/chunk-UFJNJ3WV.cjs +16 -0
- package/chunk-UFJQLQFI.min.cjs +2 -0
- package/chunk-UFJQLQFI.min.cjs.map +1 -0
- package/chunk-V7L3UICC.min.mjs +2 -0
- package/chunk-V7L3UICC.min.mjs.map +1 -0
- package/chunk-VHMO75EY.min.mjs +2 -0
- package/chunk-VHMO75EY.min.mjs.map +1 -0
- package/chunk-WVLPJPWG.cjs +17 -0
- package/chunk-X6BYQHVC.mjs +12 -0
- package/fetcher.cjs +8 -50
- package/fetcher.d.mts +3 -3
- package/fetcher.d.ts +2 -2
- package/fetcher.min.cjs +1 -1
- package/fetcher.min.cjs.map +1 -1
- package/fetcher.min.mjs +1 -1
- package/fetcher.min.mjs.map +1 -1
- package/fetcher.mjs +5 -11
- package/package.json +124 -29
- package/sharedQuery.cjs +129 -391
- package/sharedQuery.d.mts +54 -10
- package/sharedQuery.d.ts +53 -9
- package/sharedQuery.min.cjs +1 -1
- package/sharedQuery.min.cjs.map +1 -1
- package/sharedQuery.min.mjs +1 -1
- package/sharedQuery.min.mjs.map +1 -1
- package/sharedQuery.mjs +91 -321
- package/sharedState.cjs +15 -304
- package/sharedState.d.mts +4 -4
- package/sharedState.d.ts +4 -4
- package/sharedState.min.cjs +1 -1
- package/sharedState.min.cjs.map +1 -1
- package/sharedState.min.mjs +1 -1
- package/sharedState.min.mjs.map +1 -1
- package/sharedState.mjs +10 -269
- package/storage.cjs +10 -123
- package/storage.d.mts +1 -0
- package/storage.d.ts +1 -0
- package/storage.min.cjs +1 -1
- package/storage.min.cjs.map +1 -1
- package/storage.min.mjs +1 -1
- package/storage.min.mjs.map +1 -1
- package/storage.mjs +6 -92
- package/stringify.cjs +8 -57
- package/stringify.min.cjs +1 -1
- package/stringify.min.cjs.map +1 -1
- package/stringify.min.mjs +1 -1
- package/stringify.min.mjs.map +1 -1
- package/stringify.mjs +6 -30
- package/useDeepMemo.cjs +6 -50
- package/useDeepMemo.min.cjs +1 -1
- package/useDeepMemo.min.cjs.map +1 -1
- package/useDeepMemo.min.mjs +1 -1
- package/useDeepMemo.min.mjs.map +1 -1
- package/useDeepMemo.mjs +4 -13
package/sharedQuery.cjs
CHANGED
|
@@ -1,356 +1,36 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __create = Object.create;
|
|
3
|
-
var __defProp = Object.defineProperty;
|
|
4
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
-
var __export = (target, all) => {
|
|
9
|
-
for (var name in all)
|
|
10
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
-
};
|
|
12
|
-
var __copyProps = (to, from, except, desc) => {
|
|
13
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
-
for (let key of __getOwnPropNames(from))
|
|
15
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
-
}
|
|
18
|
-
return to;
|
|
19
|
-
};
|
|
20
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
-
mod
|
|
27
|
-
));
|
|
28
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
29
2
|
|
|
30
|
-
|
|
31
|
-
var sharedQuery_exports = {};
|
|
32
|
-
__export(sharedQuery_exports, {
|
|
33
|
-
SharedQueryConfig: () => SharedQueryConfig,
|
|
34
|
-
configureSharedQuery: () => configureSharedQuery,
|
|
35
|
-
sharedQuery: () => sharedQuery,
|
|
36
|
-
useSharedQuery: () => useSharedQuery
|
|
37
|
-
});
|
|
38
|
-
module.exports = __toCommonJS(sharedQuery_exports);
|
|
39
|
-
var import_timeConstants2 = require("@choksheak/ts-utils/timeConstants");
|
|
40
|
-
var import_object_sizeof = __toESM(require("object-sizeof"));
|
|
41
|
-
var import_react3 = require("react");
|
|
3
|
+
var _chunkUFJNJ3WVcjs = require('./chunk-UFJNJ3WV.cjs');
|
|
42
4
|
|
|
43
|
-
// src/sharedState.ts
|
|
44
|
-
var import_timeConstants = require("@choksheak/ts-utils/timeConstants");
|
|
45
|
-
var import_react = require("react");
|
|
46
5
|
|
|
47
|
-
// src/storage.ts
|
|
48
|
-
var import_kvStore = require("@choksheak/ts-utils/kvStore");
|
|
49
|
-
var import_localStore = require("@choksheak/ts-utils/localStore");
|
|
50
|
-
var IS_NOT_BROWSER = typeof window === "undefined";
|
|
51
|
-
function getStorageAdapter(options, defaultStoreExpiryMs) {
|
|
52
|
-
const { store } = options ?? {};
|
|
53
|
-
if (!store) {
|
|
54
|
-
return null;
|
|
55
|
-
}
|
|
56
|
-
if ("persistTo" in store && typeof store.persistTo === "string" && "key" in store && typeof store.key === "string") {
|
|
57
|
-
const expiryMs = store.expiryMs || defaultStoreExpiryMs;
|
|
58
|
-
const config = { ...store, expiryMs };
|
|
59
|
-
switch (store.persistTo) {
|
|
60
|
-
case "localStorage":
|
|
61
|
-
return localStoreAdapter(config);
|
|
62
|
-
case "indexedDb":
|
|
63
|
-
return kvStoreAdapter(config);
|
|
64
|
-
default:
|
|
65
|
-
store.persistTo;
|
|
66
|
-
throw new Error(`Unknown store.adapter ${store.persistTo}`);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
return store;
|
|
70
|
-
}
|
|
71
|
-
function localStoreAdapter({
|
|
72
|
-
key,
|
|
73
|
-
expiryMs,
|
|
74
|
-
isValid
|
|
75
|
-
}) {
|
|
76
|
-
const adapter = (0, import_localStore.createLocalStore)(key, { defaultExpiryMs: expiryMs });
|
|
77
|
-
return {
|
|
78
|
-
set: (key2, value) => {
|
|
79
|
-
if (IS_NOT_BROWSER) return;
|
|
80
|
-
adapter.set(key2, value);
|
|
81
|
-
},
|
|
82
|
-
get: (key2) => {
|
|
83
|
-
if (IS_NOT_BROWSER) return void 0;
|
|
84
|
-
const value = adapter.get(key2);
|
|
85
|
-
if (isValid && !isValid(value)) {
|
|
86
|
-
console.warn(
|
|
87
|
-
`localStorage adapter: Auto-discard invalid value for ${key2}: ${JSON.stringify(value)}`
|
|
88
|
-
);
|
|
89
|
-
adapter.delete(key2);
|
|
90
|
-
return void 0;
|
|
91
|
-
}
|
|
92
|
-
return value;
|
|
93
|
-
},
|
|
94
|
-
delete: (key2) => {
|
|
95
|
-
if (IS_NOT_BROWSER) return;
|
|
96
|
-
adapter.delete(key2);
|
|
97
|
-
},
|
|
98
|
-
clear: () => {
|
|
99
|
-
if (IS_NOT_BROWSER) return;
|
|
100
|
-
adapter.clear();
|
|
101
|
-
}
|
|
102
|
-
};
|
|
103
|
-
}
|
|
104
|
-
function kvStoreAdapter({
|
|
105
|
-
key,
|
|
106
|
-
expiryMs,
|
|
107
|
-
isValid
|
|
108
|
-
}) {
|
|
109
|
-
const keyPrefix = key + ":";
|
|
110
|
-
return {
|
|
111
|
-
set: async (key2, value) => {
|
|
112
|
-
if (IS_NOT_BROWSER) return;
|
|
113
|
-
await import_kvStore.kvStore.set(keyPrefix + key2, value, expiryMs);
|
|
114
|
-
},
|
|
115
|
-
get: async (key2) => {
|
|
116
|
-
if (IS_NOT_BROWSER) return void 0;
|
|
117
|
-
const fullKey = keyPrefix + key2;
|
|
118
|
-
const value = await import_kvStore.kvStore.get(fullKey);
|
|
119
|
-
if (value !== void 0 && isValid && !isValid(value)) {
|
|
120
|
-
console.warn(
|
|
121
|
-
`indexedDb adapter: Auto-discard invalid value for ${key2}:`,
|
|
122
|
-
value
|
|
123
|
-
);
|
|
124
|
-
await import_kvStore.kvStore.delete(fullKey);
|
|
125
|
-
return void 0;
|
|
126
|
-
}
|
|
127
|
-
return value;
|
|
128
|
-
},
|
|
129
|
-
delete: async (key2) => {
|
|
130
|
-
if (IS_NOT_BROWSER) return;
|
|
131
|
-
await import_kvStore.kvStore.delete(keyPrefix + key2);
|
|
132
|
-
},
|
|
133
|
-
clear: async () => {
|
|
134
|
-
if (IS_NOT_BROWSER) return;
|
|
135
|
-
await import_kvStore.kvStore.clear();
|
|
136
|
-
}
|
|
137
|
-
};
|
|
138
|
-
}
|
|
139
6
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
/**
|
|
143
|
-
* Default duration for storage expiration in milliseconds. Initial value
|
|
144
|
-
* is 30 days, but can be changed to anything.
|
|
145
|
-
*/
|
|
146
|
-
storeExpiryMs: 30 * import_timeConstants.MS_PER_DAY,
|
|
147
|
-
/**
|
|
148
|
-
* True to load from storage only on mount, false (default) to load in
|
|
149
|
-
* the top level scope when the shared state is defined.
|
|
150
|
-
*/
|
|
151
|
-
lazyLoad: false
|
|
152
|
-
};
|
|
153
|
-
function createPubSubStore() {
|
|
154
|
-
const dataByKey = /* @__PURE__ */ new Map();
|
|
155
|
-
const subscribersByKey = /* @__PURE__ */ new Map();
|
|
156
|
-
function notify(key, next, prev) {
|
|
157
|
-
const subscribers = subscribersByKey.get(key);
|
|
158
|
-
if (!subscribers) return;
|
|
159
|
-
const copy = Array.from(subscribers.values());
|
|
160
|
-
for (const subscriber of copy) {
|
|
161
|
-
try {
|
|
162
|
-
subscriber(next, prev);
|
|
163
|
-
} catch (e) {
|
|
164
|
-
console.error(`Error invoking subscriber:`, e);
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
return {
|
|
169
|
-
// This could be undefined if T includes undefined, else it should never
|
|
170
|
-
// return undefined because the user has to always specify the default value.
|
|
171
|
-
get(key) {
|
|
172
|
-
return dataByKey.get(key);
|
|
173
|
-
},
|
|
174
|
-
set(key, value) {
|
|
175
|
-
const prev = dataByKey.get(key);
|
|
176
|
-
if (prev === value) return;
|
|
177
|
-
dataByKey.set(key, value);
|
|
178
|
-
notify(key, value, prev);
|
|
179
|
-
},
|
|
180
|
-
delete(key) {
|
|
181
|
-
dataByKey.delete(key);
|
|
182
|
-
},
|
|
183
|
-
setNoNotify(key, value) {
|
|
184
|
-
dataByKey.set(key, value);
|
|
185
|
-
},
|
|
186
|
-
// Subscribe to changes of a specific key
|
|
187
|
-
subscribe(key, subscriber) {
|
|
188
|
-
let subscribers = subscribersByKey.get(key);
|
|
189
|
-
if (!subscribers) {
|
|
190
|
-
subscribers = /* @__PURE__ */ new Set();
|
|
191
|
-
subscribersByKey.set(key, subscribers);
|
|
192
|
-
}
|
|
193
|
-
subscribers.add(subscriber);
|
|
194
|
-
return () => {
|
|
195
|
-
subscribers.delete(subscriber);
|
|
196
|
-
if (subscribers.size === 0) subscribersByKey.delete(key);
|
|
197
|
-
};
|
|
198
|
-
}
|
|
199
|
-
};
|
|
200
|
-
}
|
|
201
|
-
var pubSubStore = createPubSubStore();
|
|
202
|
-
var STORAGE_KEY = "state";
|
|
203
|
-
var stateKey = 0;
|
|
204
|
-
function sharedState(defaultValue, options) {
|
|
205
|
-
let readyResolve = () => {
|
|
206
|
-
};
|
|
207
|
-
const readyPromise = new Promise((resolve) => {
|
|
208
|
-
readyResolve = resolve;
|
|
209
|
-
});
|
|
210
|
-
const resolveReadyPromise = readyResolve;
|
|
211
|
-
const pubSubKey = String(stateKey++);
|
|
212
|
-
const storageAdapter = getStorageAdapter(
|
|
213
|
-
options,
|
|
214
|
-
SharedStateConfig.storeExpiryMs
|
|
215
|
-
);
|
|
216
|
-
pubSubStore.setNoNotify(pubSubKey, defaultValue);
|
|
217
|
-
const lazyLoad = options?.lazyLoad;
|
|
218
|
-
const lazy = lazyLoad !== void 0 ? lazyLoad : SharedStateConfig.lazyLoad;
|
|
219
|
-
const obj = {
|
|
220
|
-
/** Allow users to await for the completion of data init. */
|
|
221
|
-
readyPromise,
|
|
222
|
-
lazy,
|
|
223
|
-
initStarted: false,
|
|
224
|
-
initDone: false,
|
|
225
|
-
/** `subscribe` function required by useSyncExternalStore. */
|
|
226
|
-
subscribe(subscriber) {
|
|
227
|
-
return pubSubStore.subscribe(pubSubKey, () => subscriber());
|
|
228
|
-
},
|
|
229
|
-
/** Returns true if there is a backing store. */
|
|
230
|
-
hasStore() {
|
|
231
|
-
return Boolean(storageAdapter);
|
|
232
|
-
},
|
|
233
|
-
/**
|
|
234
|
-
* Set a value directly into the store. Does nothing if there is no
|
|
235
|
-
* backing store.
|
|
236
|
-
*
|
|
237
|
-
* Warning: If you want to set the value properly, you should use
|
|
238
|
-
* `setValue()` instead which also updates the in-memory copy.
|
|
239
|
-
*/
|
|
240
|
-
async setInStore(value) {
|
|
241
|
-
return await storageAdapter?.set(STORAGE_KEY, value);
|
|
242
|
-
},
|
|
243
|
-
/**
|
|
244
|
-
* Get a value directly from the store. Returns undefined if there is no
|
|
245
|
-
* backing store.
|
|
246
|
-
*/
|
|
247
|
-
async getFromStore() {
|
|
248
|
-
return await storageAdapter?.get(STORAGE_KEY);
|
|
249
|
-
},
|
|
250
|
-
/**
|
|
251
|
-
* Get the value of the shared state.
|
|
252
|
-
* `getSnapshot` function — must return same ref if value unchanged.
|
|
253
|
-
* Note that this would return the default value if data init from store is
|
|
254
|
-
* not completed yet.
|
|
255
|
-
*/
|
|
256
|
-
getSnapshot() {
|
|
257
|
-
return pubSubStore.get(pubSubKey);
|
|
258
|
-
},
|
|
259
|
-
/** Set the value of the shared state. */
|
|
260
|
-
setValue(next) {
|
|
261
|
-
if (typeof next === "function") {
|
|
262
|
-
const prev = pubSubStore.get(pubSubKey);
|
|
263
|
-
next = next(prev);
|
|
264
|
-
}
|
|
265
|
-
pubSubStore.set(pubSubKey, next);
|
|
266
|
-
void obj.setInStore(next);
|
|
267
|
-
},
|
|
268
|
-
/**
|
|
269
|
-
* Remove the value of the shared state. Actually this just sets the value
|
|
270
|
-
* back to the given default value.
|
|
271
|
-
*/
|
|
272
|
-
delete() {
|
|
273
|
-
pubSubStore.set(pubSubKey, defaultValue);
|
|
274
|
-
void storageAdapter?.set(STORAGE_KEY, defaultValue);
|
|
275
|
-
},
|
|
276
|
-
/** Initial default handling. */
|
|
277
|
-
async initDefaultValueOnce() {
|
|
278
|
-
if (obj.initDone || obj.initStarted) return;
|
|
279
|
-
obj.initStarted = true;
|
|
280
|
-
const stored = await obj.getFromStore();
|
|
281
|
-
const value = stored !== void 0 ? stored : defaultValue;
|
|
282
|
-
pubSubStore.set(pubSubKey, value);
|
|
283
|
-
obj.initDone = true;
|
|
284
|
-
resolveReadyPromise();
|
|
285
|
-
}
|
|
286
|
-
};
|
|
287
|
-
if (!lazy) {
|
|
288
|
-
void obj.initDefaultValueOnce();
|
|
289
|
-
}
|
|
290
|
-
return obj;
|
|
291
|
-
}
|
|
292
|
-
function useSharedState(state) {
|
|
293
|
-
void state.initDefaultValueOnce();
|
|
294
|
-
const value = (0, import_react.useSyncExternalStore)(
|
|
295
|
-
(onStoreChange) => state.subscribe(onStoreChange),
|
|
296
|
-
() => state.getSnapshot(),
|
|
297
|
-
// getServerSnapshot is needed to prevent SSR dev errors in nextjs.
|
|
298
|
-
() => state.getSnapshot()
|
|
299
|
-
);
|
|
300
|
-
return [value, state.setValue];
|
|
301
|
-
}
|
|
7
|
+
var _chunk3X25NN6Xcjs = require('./chunk-3X25NN6X.cjs');
|
|
8
|
+
require('./chunk-5PDGU37E.cjs');
|
|
302
9
|
|
|
303
|
-
// src/stringify.ts
|
|
304
|
-
function stringifyDeterministicForKeys(params) {
|
|
305
|
-
const cache = /* @__PURE__ */ new Set();
|
|
306
|
-
return JSON.stringify(params, (_, value) => {
|
|
307
|
-
if (typeof value === "function") {
|
|
308
|
-
throw new Error(`Functions should not be passed into query parameters`);
|
|
309
|
-
}
|
|
310
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
311
|
-
return value;
|
|
312
|
-
}
|
|
313
|
-
if (cache.has(value)) {
|
|
314
|
-
return "[Circular]";
|
|
315
|
-
}
|
|
316
|
-
cache.add(value);
|
|
317
|
-
if (value !== params) {
|
|
318
|
-
try {
|
|
319
|
-
JSON.stringify(value);
|
|
320
|
-
} catch {
|
|
321
|
-
return "[Unserializable]";
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
return Object.keys(value).sort().reduce(
|
|
325
|
-
(result, key) => {
|
|
326
|
-
result[key] = value[key];
|
|
327
|
-
return result;
|
|
328
|
-
},
|
|
329
|
-
{}
|
|
330
|
-
);
|
|
331
|
-
});
|
|
332
|
-
}
|
|
333
10
|
|
|
334
|
-
|
|
335
|
-
var
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
if ((0, import_isEqual.default)(state, value)) {
|
|
341
|
-
return state;
|
|
342
|
-
}
|
|
343
|
-
setState(value);
|
|
344
|
-
return value;
|
|
345
|
-
}, [state, value]);
|
|
346
|
-
}
|
|
11
|
+
|
|
12
|
+
var _chunk5DO7KC3Lcjs = require('./chunk-5DO7KC3L.cjs');
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
var _chunkWVLPJPWGcjs = require('./chunk-WVLPJPWG.cjs');
|
|
16
|
+
require('./chunk-74BS2FAO.cjs');
|
|
347
17
|
|
|
348
18
|
// src/sharedQuery.ts
|
|
19
|
+
var _objectsizeof = require('object-sizeof'); var _objectsizeof2 = _interopRequireDefault(_objectsizeof);
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
var _react = require('react');
|
|
27
|
+
var _xxhashjs = require('xxhashjs'); var _xxhashjs2 = _interopRequireDefault(_xxhashjs);
|
|
28
|
+
_chunk5DO7KC3Lcjs.init_stringify.call(void 0, );
|
|
349
29
|
var SharedQueryConfig = {
|
|
350
30
|
/** Refetch on every page load. */
|
|
351
31
|
staleMs: 0,
|
|
352
32
|
/** Keep in cache for a long time. */
|
|
353
|
-
expiryMs: 30 *
|
|
33
|
+
expiryMs: 30 * 864e5,
|
|
354
34
|
/** Always refetch automatically if the data is stale. */
|
|
355
35
|
refetchOnStale: true,
|
|
356
36
|
/** No default persistence configured. */
|
|
@@ -367,18 +47,59 @@ function configureSharedQuery(config) {
|
|
|
367
47
|
}
|
|
368
48
|
var seenQueryNames = /* @__PURE__ */ new Set();
|
|
369
49
|
function sharedQuery(options) {
|
|
370
|
-
|
|
371
|
-
|
|
50
|
+
const url = options.url || "";
|
|
51
|
+
const queryName = options.queryName || url;
|
|
52
|
+
if (!queryName) {
|
|
53
|
+
throw new Error(`Either queryName or url must be specified.`);
|
|
54
|
+
}
|
|
55
|
+
if (seenQueryNames.has(queryName)) {
|
|
56
|
+
throw new Error(`Duplicate shared query name "${queryName}"`);
|
|
372
57
|
}
|
|
373
|
-
seenQueryNames.add(
|
|
58
|
+
seenQueryNames.add(queryName);
|
|
374
59
|
const inflightQueries = /* @__PURE__ */ new Map();
|
|
375
60
|
const mountedKeys = /* @__PURE__ */ new Map();
|
|
376
|
-
|
|
377
|
-
|
|
61
|
+
let queryFn;
|
|
62
|
+
if (options.queryFn) {
|
|
63
|
+
queryFn = options.queryFn;
|
|
64
|
+
} else if (url) {
|
|
65
|
+
queryFn = (...args) => {
|
|
66
|
+
let params = "";
|
|
67
|
+
const firstArg = _optionalChain([args, 'optionalAccess', _ => _[0]]);
|
|
68
|
+
if (firstArg) {
|
|
69
|
+
if (typeof firstArg === "string") {
|
|
70
|
+
params = firstArg;
|
|
71
|
+
} else if (typeof firstArg === "object") {
|
|
72
|
+
const entries = [];
|
|
73
|
+
for (const [k, v] of Object.entries(firstArg)) {
|
|
74
|
+
if (v === void 0) continue;
|
|
75
|
+
if (Array.isArray(v)) {
|
|
76
|
+
for (const item of v) {
|
|
77
|
+
if (item === void 0) continue;
|
|
78
|
+
entries.push([k, String(item)]);
|
|
79
|
+
}
|
|
80
|
+
} else {
|
|
81
|
+
entries.push([k, String(v)]);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
params = new URLSearchParams(entries).toString();
|
|
85
|
+
}
|
|
86
|
+
if (params) {
|
|
87
|
+
if (url.includes("?")) {
|
|
88
|
+
params = "&" + params;
|
|
89
|
+
} else {
|
|
90
|
+
params = "?" + params;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return _chunkUFJNJ3WVcjs.fetcher.url(url + params).get().json();
|
|
95
|
+
};
|
|
96
|
+
} else {
|
|
97
|
+
throw new Error(`Either queryFn or url must be specified`);
|
|
98
|
+
}
|
|
378
99
|
const refetchFn = options.refetchFn;
|
|
379
|
-
const staleMs = options
|
|
380
|
-
const expiryMs = options
|
|
381
|
-
const refetchOnStale = options
|
|
100
|
+
const staleMs = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _2 => _2.staleMs]), () => ( SharedQueryConfig.staleMs));
|
|
101
|
+
const expiryMs = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _3 => _3.expiryMs]), () => ( SharedQueryConfig.expiryMs));
|
|
102
|
+
const refetchOnStale = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _4 => _4.refetchOnStale]), () => ( SharedQueryConfig.refetchOnStale));
|
|
382
103
|
const store = options.store;
|
|
383
104
|
if (store) {
|
|
384
105
|
if ("persistTo" in store && store.isValid) {
|
|
@@ -402,7 +123,7 @@ function sharedQuery(options) {
|
|
|
402
123
|
};
|
|
403
124
|
}
|
|
404
125
|
} else {
|
|
405
|
-
const persistTo = options.persistTo
|
|
126
|
+
const persistTo = _nullishCoalesce(options.persistTo, () => ( SharedQueryConfig.persistTo));
|
|
406
127
|
if (persistTo) {
|
|
407
128
|
options = {
|
|
408
129
|
...options,
|
|
@@ -414,11 +135,11 @@ function sharedQuery(options) {
|
|
|
414
135
|
};
|
|
415
136
|
}
|
|
416
137
|
}
|
|
417
|
-
const maxSize = options
|
|
418
|
-
const maxBytes = options
|
|
419
|
-
const keepLastNonEmptyData = Boolean(options
|
|
420
|
-
const log = options
|
|
421
|
-
const queryState = sharedState(
|
|
138
|
+
const maxSize = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _5 => _5.maxSize]), () => ( SharedQueryConfig.maxSize));
|
|
139
|
+
const maxBytes = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _6 => _6.maxBytes]), () => ( SharedQueryConfig.maxBytes));
|
|
140
|
+
const keepLastNonEmptyData = Boolean(_optionalChain([options, 'optionalAccess', _7 => _7.keepLastNonEmptyData]));
|
|
141
|
+
const log = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _8 => _8.log]), () => ( SharedQueryConfig.log));
|
|
142
|
+
const queryState = _chunk3X25NN6Xcjs.sharedState.call(void 0,
|
|
422
143
|
{},
|
|
423
144
|
// defaultValue
|
|
424
145
|
options
|
|
@@ -442,7 +163,7 @@ function sharedQuery(options) {
|
|
|
442
163
|
if (oldSize <= 1) {
|
|
443
164
|
return;
|
|
444
165
|
}
|
|
445
|
-
const oldByteSize = (0,
|
|
166
|
+
const oldByteSize = _objectsizeof2.default.call(void 0, oldState);
|
|
446
167
|
let numToCut = maxSize ? oldSize - maxSize : 0;
|
|
447
168
|
let bytesToCut = maxBytes ? oldByteSize - maxBytes : 0;
|
|
448
169
|
if (numToCut <= 0 && bytesToCut <= 0) {
|
|
@@ -461,7 +182,7 @@ function sharedQuery(options) {
|
|
|
461
182
|
log(`Cannot clean up ${key} as it is mounted`);
|
|
462
183
|
return;
|
|
463
184
|
}
|
|
464
|
-
const byteSize = (0,
|
|
185
|
+
const byteSize = _objectsizeof2.default.call(void 0, key) + _objectsizeof2.default.call(void 0, newState[key]);
|
|
465
186
|
log(
|
|
466
187
|
`Cleaning up unmounted${expired ? ", expired" : ""} ${key} (byteSize=${byteSize.toLocaleString()})`
|
|
467
188
|
);
|
|
@@ -500,7 +221,7 @@ function sharedQuery(options) {
|
|
|
500
221
|
}
|
|
501
222
|
queryState.setValue(newState);
|
|
502
223
|
log(
|
|
503
|
-
`Trimmed data for ${queryName}: size=[${oldSize} -> ${Object.keys(newState).length}] (limit=${maxSize}), byteSize=[${oldByteSize.toLocaleString()} -> ${(0,
|
|
224
|
+
`Trimmed data for ${queryName}: size=[${oldSize} -> ${Object.keys(newState).length}] (limit=${maxSize}), byteSize=[${oldByteSize.toLocaleString()} -> ${_objectsizeof2.default.call(void 0, newState).toLocaleString()}] (limit=${maxBytes.toLocaleString()})`
|
|
504
225
|
);
|
|
505
226
|
}
|
|
506
227
|
function setData(queryKey, data, dataUpdatedMs = Date.now()) {
|
|
@@ -554,7 +275,11 @@ function sharedQuery(options) {
|
|
|
554
275
|
queryState,
|
|
555
276
|
/** Returns a key to identify requests based on the given args. */
|
|
556
277
|
getQueryKey(args) {
|
|
557
|
-
|
|
278
|
+
let s = _chunk5DO7KC3Lcjs.stringifyDeterministicForKeys.call(void 0, args);
|
|
279
|
+
if (s.length > 30) {
|
|
280
|
+
s = _xxhashjs2.default.h32(s, 39406).toString(16).slice(2);
|
|
281
|
+
}
|
|
282
|
+
return queryName + ":" + s;
|
|
558
283
|
},
|
|
559
284
|
/**
|
|
560
285
|
* Get the AbortController to abort the inflight query (if any).
|
|
@@ -568,12 +293,12 @@ function sharedQuery(options) {
|
|
|
568
293
|
return obj.getAbortControllerByKey(queryKey);
|
|
569
294
|
},
|
|
570
295
|
getAbortControllerByKey(queryKey) {
|
|
571
|
-
return inflightQueries.get(queryKey)
|
|
296
|
+
return _nullishCoalesce(_optionalChain([inflightQueries, 'access', _9 => _9.get, 'call', _10 => _10(queryKey), 'optionalAccess', _11 => _11.abortController]), () => ( null));
|
|
572
297
|
},
|
|
573
298
|
/**
|
|
574
299
|
* Get the AbortSignal to check for query abortions.
|
|
575
300
|
*
|
|
576
|
-
* Example:
|
|
301
|
+
* Example using fetch:
|
|
577
302
|
* ```
|
|
578
303
|
* const getUserQuery = sharedQuery({
|
|
579
304
|
* queryName: "getUser",
|
|
@@ -594,13 +319,27 @@ function sharedQuery(options) {
|
|
|
594
319
|
* },
|
|
595
320
|
* });
|
|
596
321
|
* ```
|
|
322
|
+
*
|
|
323
|
+
* Example using `fetcher.ts`:
|
|
324
|
+
* ```
|
|
325
|
+
* const getUserQuery = sharedQuery({
|
|
326
|
+
* queryName: "getUser",
|
|
327
|
+
* queryFn: (userId: string) => {
|
|
328
|
+
* // Get the signal for this current execution.
|
|
329
|
+
* const signal = getUserQuery.getAbortSignal([userId]);
|
|
330
|
+
*
|
|
331
|
+
* // Pass the signal to fetch so that it can be aborted.
|
|
332
|
+
* return fetcher.url(`/users/${userId}`).options({ signal }).get().json();
|
|
333
|
+
* },
|
|
334
|
+
* });
|
|
335
|
+
* ```
|
|
597
336
|
*/
|
|
598
337
|
getAbortSignal(args) {
|
|
599
338
|
const queryKey = obj.getQueryKey(args);
|
|
600
339
|
return obj.getAbortSignalByKey(queryKey);
|
|
601
340
|
},
|
|
602
341
|
getAbortSignalByKey(queryKey) {
|
|
603
|
-
return obj.getAbortControllerByKey(queryKey)
|
|
342
|
+
return _nullishCoalesce(_optionalChain([obj, 'access', _12 => _12.getAbortControllerByKey, 'call', _13 => _13(queryKey), 'optionalAccess', _14 => _14.signal]), () => ( null));
|
|
604
343
|
},
|
|
605
344
|
/** For cached data, we need to return the correct timestamps as well. */
|
|
606
345
|
async getCachedOrFetch(...args) {
|
|
@@ -608,12 +347,12 @@ function sharedQuery(options) {
|
|
|
608
347
|
await queryState.readyPromise;
|
|
609
348
|
const waitedMs = Date.now() - startMs;
|
|
610
349
|
const queryKey = obj.getQueryKey(args);
|
|
611
|
-
const cached = queryState.getSnapshot()
|
|
350
|
+
const cached = _optionalChain([queryState, 'access', _15 => _15.getSnapshot, 'call', _16 => _16(), 'optionalAccess', _17 => _17[queryKey]]);
|
|
612
351
|
if (waitedMs) {
|
|
613
352
|
log(`${queryKey}: Waited for ${waitedMs}ms before data is ready`);
|
|
614
353
|
}
|
|
615
|
-
if (cached
|
|
616
|
-
if (!isStale(cached.dataUpdatedMs
|
|
354
|
+
if (_optionalChain([cached, 'optionalAccess', _18 => _18.data]) && !isExpired(_nullishCoalesce(cached.dataUpdatedMs, () => ( 0)))) {
|
|
355
|
+
if (!isStale(_nullishCoalesce(cached.dataUpdatedMs, () => ( 0)))) {
|
|
617
356
|
log(`Return fresh data ${queryKey} from cache without fetching`);
|
|
618
357
|
return cached;
|
|
619
358
|
}
|
|
@@ -636,18 +375,18 @@ function sharedQuery(options) {
|
|
|
636
375
|
},
|
|
637
376
|
/** Get the entire stored entry for a query key. */
|
|
638
377
|
getQueryValue(queryKey) {
|
|
639
|
-
return queryState.getSnapshot()
|
|
378
|
+
return _optionalChain([queryState, 'access', _19 => _19.getSnapshot, 'call', _20 => _20(), 'optionalAccess', _21 => _21[queryKey]]);
|
|
640
379
|
},
|
|
641
380
|
/** Get the current stored data for a query key. */
|
|
642
381
|
getData(queryKey) {
|
|
643
|
-
const stateValue = queryState.getSnapshot()
|
|
644
|
-
if (stateValue
|
|
382
|
+
const stateValue = _optionalChain([queryState, 'access', _22 => _22.getSnapshot, 'call', _23 => _23(), 'optionalAccess', _24 => _24[queryKey]]);
|
|
383
|
+
if (_optionalChain([stateValue, 'optionalAccess', _25 => _25.lastUpdatedMs])) {
|
|
645
384
|
if (isExpired(stateValue.lastUpdatedMs)) {
|
|
646
385
|
obj.deleteData(queryKey);
|
|
647
386
|
return void 0;
|
|
648
387
|
}
|
|
649
388
|
}
|
|
650
|
-
return stateValue
|
|
389
|
+
return _optionalChain([stateValue, 'optionalAccess', _26 => _26.data]);
|
|
651
390
|
},
|
|
652
391
|
/** Set the data directly if the user obtained it from somewhere else. */
|
|
653
392
|
setData,
|
|
@@ -689,7 +428,7 @@ function sharedQuery(options) {
|
|
|
689
428
|
},
|
|
690
429
|
/** Keep track of mounted keys. */
|
|
691
430
|
mount(queryKey) {
|
|
692
|
-
mountedKeys.set(queryKey, (mountedKeys.get(queryKey)
|
|
431
|
+
mountedKeys.set(queryKey, (_nullishCoalesce(mountedKeys.get(queryKey), () => ( 0))) + 1);
|
|
693
432
|
},
|
|
694
433
|
/** Clean up mounted keys. */
|
|
695
434
|
unmount(queryKey) {
|
|
@@ -697,7 +436,7 @@ function sharedQuery(options) {
|
|
|
697
436
|
if (count === 1) {
|
|
698
437
|
mountedKeys.delete(queryKey);
|
|
699
438
|
} else {
|
|
700
|
-
mountedKeys.set(queryKey, (count
|
|
439
|
+
mountedKeys.set(queryKey, (_nullishCoalesce(count, () => ( 0))) - 1);
|
|
701
440
|
}
|
|
702
441
|
},
|
|
703
442
|
/**
|
|
@@ -713,31 +452,31 @@ var DEFAULT_QUERY_STATE_ENTRY = {
|
|
|
713
452
|
loading: true
|
|
714
453
|
};
|
|
715
454
|
function useSharedQuery(query, ...args) {
|
|
716
|
-
const stableArgs = useDeepMemo(args);
|
|
717
|
-
const [queryState, setQueryState] = useSharedState(query.queryState);
|
|
718
|
-
const isMounted = (0,
|
|
719
|
-
const queryKey = (0,
|
|
455
|
+
const stableArgs = _chunkWVLPJPWGcjs.useDeepMemo.call(void 0, args);
|
|
456
|
+
const [queryState, setQueryState] = _chunk3X25NN6Xcjs.useSharedState.call(void 0, query.queryState);
|
|
457
|
+
const isMounted = _react.useRef.call(void 0, true);
|
|
458
|
+
const queryKey = _react.useMemo.call(void 0,
|
|
720
459
|
() => query.getQueryKey(stableArgs),
|
|
721
460
|
[query, stableArgs]
|
|
722
461
|
);
|
|
723
|
-
const queryStateValue = queryState[queryKey]
|
|
724
|
-
const setQueryStateValue = (0,
|
|
462
|
+
const queryStateValue = _nullishCoalesce(queryState[queryKey], () => ( DEFAULT_QUERY_STATE_ENTRY));
|
|
463
|
+
const setQueryStateValue = _react.useCallback.call(void 0,
|
|
725
464
|
(next) => {
|
|
726
465
|
setQueryState((prev) => {
|
|
727
466
|
const clone = { ...prev };
|
|
728
|
-
clone[queryKey] = typeof next === "function" ? next(clone[queryKey]
|
|
467
|
+
clone[queryKey] = typeof next === "function" ? next(_nullishCoalesce(clone[queryKey], () => ( DEFAULT_QUERY_STATE_ENTRY))) : next;
|
|
729
468
|
return clone;
|
|
730
469
|
});
|
|
731
470
|
},
|
|
732
471
|
[queryKey, setQueryState]
|
|
733
472
|
);
|
|
734
|
-
const [lastNonEmptyData, setLastNonEmptyData] = (0,
|
|
735
|
-
(0,
|
|
473
|
+
const [lastNonEmptyData, setLastNonEmptyData] = _react.useState.call(void 0, );
|
|
474
|
+
_react.useEffect.call(void 0, () => {
|
|
736
475
|
if (query.keepLastNonEmptyData && queryStateValue.data !== void 0) {
|
|
737
476
|
setLastNonEmptyData(queryStateValue.data);
|
|
738
477
|
}
|
|
739
478
|
}, [query.keepLastNonEmptyData, queryStateValue.data]);
|
|
740
|
-
const execute = (0,
|
|
479
|
+
const execute = _react.useCallback.call(void 0,
|
|
741
480
|
async (isRefetch) => {
|
|
742
481
|
query.log(
|
|
743
482
|
`Begin executing shared query ${queryKey}, isRefetch=${isRefetch}`
|
|
@@ -781,7 +520,7 @@ function useSharedQuery(query, ...args) {
|
|
|
781
520
|
},
|
|
782
521
|
[query, queryKey, setQueryStateValue, stableArgs]
|
|
783
522
|
);
|
|
784
|
-
(0,
|
|
523
|
+
_react.useEffect.call(void 0, () => {
|
|
785
524
|
isMounted.current = true;
|
|
786
525
|
query.mount(queryKey);
|
|
787
526
|
void execute(false);
|
|
@@ -790,7 +529,7 @@ function useSharedQuery(query, ...args) {
|
|
|
790
529
|
query.unmount(queryKey);
|
|
791
530
|
};
|
|
792
531
|
}, [execute, query, queryKey]);
|
|
793
|
-
return (0,
|
|
532
|
+
return _react.useMemo.call(void 0, () => {
|
|
794
533
|
return {
|
|
795
534
|
...queryStateValue,
|
|
796
535
|
// Fill with lastNonEmptyData when data is undefined.
|
|
@@ -801,7 +540,7 @@ function useSharedQuery(query, ...args) {
|
|
|
801
540
|
// abort the running queryFn.
|
|
802
541
|
abortCurrentQuery: (reason) => {
|
|
803
542
|
const controller = query.getAbortControllerByKey(queryKey);
|
|
804
|
-
controller
|
|
543
|
+
_optionalChain([controller, 'optionalAccess', _27 => _27.abort, 'call', _28 => _28(reason)]);
|
|
805
544
|
return Boolean(controller);
|
|
806
545
|
},
|
|
807
546
|
refetch: () => {
|
|
@@ -816,10 +555,9 @@ function useSharedQuery(query, ...args) {
|
|
|
816
555
|
};
|
|
817
556
|
}, [execute, lastNonEmptyData, query, queryKey, queryStateValue]);
|
|
818
557
|
}
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
});
|
|
558
|
+
|
|
559
|
+
|
|
560
|
+
|
|
561
|
+
|
|
562
|
+
|
|
563
|
+
exports.SharedQueryConfig = SharedQueryConfig; exports.configureSharedQuery = configureSharedQuery; exports.sharedQuery = sharedQuery; exports.useSharedQuery = useSharedQuery;
|