@braine/quantum-query 1.3.2 → 1.3.4
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 +363 -243
- package/dist/index.d.cts +44 -8
- package/dist/index.d.ts +44 -8
- package/dist/index.js +286 -169
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -21,9 +21,12 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
23
|
HydrationBoundary: () => HydrationBoundary,
|
|
24
|
+
Match: () => Match,
|
|
25
|
+
MutationCache: () => MutationCache,
|
|
24
26
|
QuantumDevTools: () => QuantumDevTools,
|
|
25
27
|
QueryClient: () => QueryClient,
|
|
26
28
|
QueryClientProvider: () => QueryClientProvider,
|
|
29
|
+
QueryMatch: () => QueryMatch,
|
|
27
30
|
SignalValue: () => SignalValue,
|
|
28
31
|
atom: () => atom,
|
|
29
32
|
createHttpClient: () => createHttpClient,
|
|
@@ -120,7 +123,7 @@ function atom(initialValue, options) {
|
|
|
120
123
|
return s;
|
|
121
124
|
}
|
|
122
125
|
function setupPersistence(s, options) {
|
|
123
|
-
const { key, storage = "local", debug } = options;
|
|
126
|
+
const { key, storage = "local", debug, hydrateSync } = options;
|
|
124
127
|
if (!key) return;
|
|
125
128
|
let engine = null;
|
|
126
129
|
if (typeof storage === "string") {
|
|
@@ -131,27 +134,34 @@ function setupPersistence(s, options) {
|
|
|
131
134
|
engine = storage;
|
|
132
135
|
}
|
|
133
136
|
if (!engine) return;
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
137
|
+
const hydrate2 = () => {
|
|
138
|
+
try {
|
|
139
|
+
const stored = engine?.getItem(key);
|
|
140
|
+
const applyValue = (val) => {
|
|
141
|
+
try {
|
|
142
|
+
const parsed = JSON.parse(val);
|
|
143
|
+
const validated = options.validate ? options.validate(parsed) : parsed;
|
|
144
|
+
s.set(validated);
|
|
145
|
+
if (debug) console.log(`[Quantum] Hydrated atom '${key}'`);
|
|
146
|
+
} catch (e) {
|
|
147
|
+
if (debug) console.error(`[Quantum] Hydration validation failed for '${key}'`, e);
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
if (stored instanceof Promise) {
|
|
151
|
+
stored.then((val) => {
|
|
152
|
+
if (val) applyValue(val);
|
|
153
|
+
});
|
|
154
|
+
} else if (stored) {
|
|
155
|
+
applyValue(stored);
|
|
144
156
|
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
stored.then((val) => {
|
|
148
|
-
if (val) applyValue(val);
|
|
149
|
-
});
|
|
150
|
-
} else if (stored) {
|
|
151
|
-
applyValue(stored);
|
|
157
|
+
} catch (err) {
|
|
158
|
+
if (debug) console.error(`[Quantum] Hydration error`, err);
|
|
152
159
|
}
|
|
153
|
-
}
|
|
154
|
-
|
|
160
|
+
};
|
|
161
|
+
if (hydrateSync) {
|
|
162
|
+
hydrate2();
|
|
163
|
+
} else {
|
|
164
|
+
Promise.resolve().then(hydrate2);
|
|
155
165
|
}
|
|
156
166
|
s.subscribe((value) => {
|
|
157
167
|
try {
|
|
@@ -182,6 +192,19 @@ function SignalValue({ signal: signal2, render, children }) {
|
|
|
182
192
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: renderer(value) });
|
|
183
193
|
}
|
|
184
194
|
|
|
195
|
+
// src/react/QueryMatch.tsx
|
|
196
|
+
var import_react2 = require("react");
|
|
197
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
198
|
+
function QueryMatch({ signal: signal2, selector, children }) {
|
|
199
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SignalValue, { signal: signal2, children: (value) => {
|
|
200
|
+
const selected = selector(value);
|
|
201
|
+
return children(selected);
|
|
202
|
+
} });
|
|
203
|
+
}
|
|
204
|
+
function Match({ signal: signal2, when, children }) {
|
|
205
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SignalValue, { signal: signal2, children: (value) => when(value) ? children : null });
|
|
206
|
+
}
|
|
207
|
+
|
|
185
208
|
// src/store/scheduler.ts
|
|
186
209
|
var pending = /* @__PURE__ */ new Set();
|
|
187
210
|
var timer = null;
|
|
@@ -214,16 +237,16 @@ function enableDevTools(store, name = "Store") {
|
|
|
214
237
|
}
|
|
215
238
|
|
|
216
239
|
// src/devtools/index.tsx
|
|
217
|
-
var
|
|
240
|
+
var import_react6 = require("react");
|
|
218
241
|
|
|
219
242
|
// src/devtools/QueryPanel.tsx
|
|
220
|
-
var
|
|
243
|
+
var import_react5 = require("react");
|
|
221
244
|
|
|
222
245
|
// src/query/useQueryStore.ts
|
|
223
|
-
var
|
|
246
|
+
var import_react4 = require("react");
|
|
224
247
|
|
|
225
248
|
// src/query/context.tsx
|
|
226
|
-
var
|
|
249
|
+
var import_react3 = require("react");
|
|
227
250
|
|
|
228
251
|
// src/query/utils.ts
|
|
229
252
|
function stableHash(value, depth = 0) {
|
|
@@ -245,41 +268,90 @@ function stableHash(value, depth = 0) {
|
|
|
245
268
|
const keys = Object.keys(value).sort();
|
|
246
269
|
return `object:{${keys.map((key) => `${key}:${stableHash(value[key], depth + 1)}`).join(",")}}`;
|
|
247
270
|
}
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
271
|
+
|
|
272
|
+
// src/query/trie.ts
|
|
273
|
+
var TrieNode = class {
|
|
274
|
+
children = /* @__PURE__ */ new Map();
|
|
275
|
+
keys = /* @__PURE__ */ new Set();
|
|
276
|
+
// Stores the full hashed keys valid at this path
|
|
277
|
+
};
|
|
278
|
+
var QueryKeyTrie = class {
|
|
279
|
+
root = new TrieNode();
|
|
280
|
+
insert(queryKey, hashedKey) {
|
|
281
|
+
const parts = this.normalizeParts(queryKey);
|
|
282
|
+
let node = this.root;
|
|
283
|
+
for (const part of parts) {
|
|
284
|
+
const hash = stableHash(part);
|
|
285
|
+
let child = node.children.get(hash);
|
|
286
|
+
if (!child) {
|
|
287
|
+
child = new TrieNode();
|
|
288
|
+
node.children.set(hash, child);
|
|
289
|
+
}
|
|
290
|
+
node = child;
|
|
291
|
+
}
|
|
292
|
+
node.keys.add(hashedKey);
|
|
293
|
+
}
|
|
294
|
+
remove(queryKey, hashedKey) {
|
|
295
|
+
const parts = this.normalizeParts(queryKey);
|
|
296
|
+
this.removeRecursive(this.root, parts, 0, hashedKey);
|
|
297
|
+
}
|
|
298
|
+
removeRecursive(node, parts, index, hashedKey) {
|
|
299
|
+
if (index === parts.length) {
|
|
300
|
+
node.keys.delete(hashedKey);
|
|
301
|
+
return node.children.size === 0 && node.keys.size === 0;
|
|
302
|
+
}
|
|
303
|
+
const part = parts[index];
|
|
304
|
+
const hash = stableHash(part);
|
|
305
|
+
const child = node.children.get(hash);
|
|
306
|
+
if (child) {
|
|
307
|
+
const shouldDeleteChild = this.removeRecursive(child, parts, index + 1, hashedKey);
|
|
308
|
+
if (shouldDeleteChild) {
|
|
309
|
+
node.children.delete(hash);
|
|
261
310
|
}
|
|
262
|
-
return true;
|
|
263
311
|
}
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
312
|
+
return node.children.size === 0 && node.keys.size === 0;
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* Get all hashed keys that match the given partial query key (prefix)
|
|
316
|
+
*/
|
|
317
|
+
getMatchingKeys(partialKey) {
|
|
318
|
+
const parts = this.normalizeParts(partialKey);
|
|
319
|
+
let node = this.root;
|
|
320
|
+
for (const part of parts) {
|
|
321
|
+
const hash = stableHash(part);
|
|
322
|
+
const child = node.children.get(hash);
|
|
323
|
+
if (!child) {
|
|
324
|
+
return /* @__PURE__ */ new Set();
|
|
325
|
+
}
|
|
326
|
+
node = child;
|
|
327
|
+
}
|
|
328
|
+
const results = /* @__PURE__ */ new Set();
|
|
329
|
+
this.collectKeys(node, results);
|
|
330
|
+
return results;
|
|
331
|
+
}
|
|
332
|
+
collectKeys(node, results) {
|
|
333
|
+
for (const key of node.keys) {
|
|
334
|
+
results.add(key);
|
|
271
335
|
}
|
|
272
|
-
for (const
|
|
273
|
-
|
|
336
|
+
for (const child of node.children.values()) {
|
|
337
|
+
this.collectKeys(child, results);
|
|
274
338
|
}
|
|
275
|
-
return true;
|
|
276
339
|
}
|
|
277
|
-
|
|
278
|
-
|
|
340
|
+
normalizeParts(queryKey) {
|
|
341
|
+
if (Array.isArray(queryKey)) {
|
|
342
|
+
return queryKey;
|
|
343
|
+
}
|
|
344
|
+
if (queryKey && typeof queryKey === "object" && "key" in queryKey) {
|
|
345
|
+
const qk = queryKey;
|
|
346
|
+
return [qk.key, qk.params];
|
|
347
|
+
}
|
|
348
|
+
return [queryKey];
|
|
349
|
+
}
|
|
350
|
+
};
|
|
279
351
|
|
|
280
352
|
// src/query/queryStorage.ts
|
|
281
353
|
var QueryStorage = class {
|
|
282
|
-
//
|
|
354
|
+
// 10/10: O(K) Lookup
|
|
283
355
|
// Default configuration
|
|
284
356
|
constructor(defaultStaleTime = 5 * 60 * 1e3, defaultCacheTime = 5 * 60 * 1e3, maxSize = 100) {
|
|
285
357
|
this.defaultStaleTime = defaultStaleTime;
|
|
@@ -289,6 +361,8 @@ var QueryStorage = class {
|
|
|
289
361
|
signals = /* @__PURE__ */ new Map();
|
|
290
362
|
gcTimers = /* @__PURE__ */ new Map();
|
|
291
363
|
lruOrder = /* @__PURE__ */ new Set();
|
|
364
|
+
// Tracks access order (least to most recent)
|
|
365
|
+
trie = new QueryKeyTrie();
|
|
292
366
|
generateKey(queryKey) {
|
|
293
367
|
const key = Array.isArray(queryKey) ? stableHash(queryKey) : stableHash([queryKey.key, queryKey.params]);
|
|
294
368
|
return key;
|
|
@@ -363,6 +437,7 @@ var QueryStorage = class {
|
|
|
363
437
|
}
|
|
364
438
|
this.enforceMaxSize();
|
|
365
439
|
}
|
|
440
|
+
this.trie.insert(entry.key, key);
|
|
366
441
|
}
|
|
367
442
|
delete(key) {
|
|
368
443
|
const entry = this.signals.get(key)?.get();
|
|
@@ -375,6 +450,9 @@ var QueryStorage = class {
|
|
|
375
450
|
}
|
|
376
451
|
}
|
|
377
452
|
}
|
|
453
|
+
if (entry?.key) {
|
|
454
|
+
this.trie.remove(entry.key, key);
|
|
455
|
+
}
|
|
378
456
|
this.signals.delete(key);
|
|
379
457
|
this.lruOrder.delete(key);
|
|
380
458
|
this.cancelGC(key);
|
|
@@ -399,6 +477,7 @@ var QueryStorage = class {
|
|
|
399
477
|
clear() {
|
|
400
478
|
this.signals.clear();
|
|
401
479
|
this.tagIndex.clear();
|
|
480
|
+
this.trie = new QueryKeyTrie();
|
|
402
481
|
this.lruOrder.clear();
|
|
403
482
|
this.gcTimers.forEach((timer2) => clearTimeout(timer2));
|
|
404
483
|
this.gcTimers.clear();
|
|
@@ -951,11 +1030,26 @@ var QueryClient = class {
|
|
|
951
1030
|
});
|
|
952
1031
|
this.pluginManager.onFetchStart(normalizedKey);
|
|
953
1032
|
try {
|
|
954
|
-
const
|
|
1033
|
+
const fetchPromise = this.remotes.fetch(key, fn, {
|
|
955
1034
|
signal: options?.signal,
|
|
956
1035
|
retry: options?.retry,
|
|
957
1036
|
retryDelay: options?.retryDelay
|
|
958
1037
|
});
|
|
1038
|
+
this.storage.set(key, {
|
|
1039
|
+
data: currentEntry?.data,
|
|
1040
|
+
status: currentEntry?.status || "pending",
|
|
1041
|
+
error: null,
|
|
1042
|
+
isFetching: true,
|
|
1043
|
+
fetchDirection: direction,
|
|
1044
|
+
timestamp: currentEntry?.timestamp || Date.now(),
|
|
1045
|
+
staleTime: currentEntry?.staleTime ?? this.defaultStaleTime,
|
|
1046
|
+
cacheTime: currentEntry?.cacheTime ?? this.defaultCacheTime,
|
|
1047
|
+
key: queryKey,
|
|
1048
|
+
tags: mergedTags,
|
|
1049
|
+
promise: fetchPromise
|
|
1050
|
+
// Store for Suspense
|
|
1051
|
+
});
|
|
1052
|
+
const data = await fetchPromise;
|
|
959
1053
|
this.storage.set(key, {
|
|
960
1054
|
data,
|
|
961
1055
|
status: "success",
|
|
@@ -968,7 +1062,9 @@ var QueryClient = class {
|
|
|
968
1062
|
staleTime: currentEntry?.staleTime ?? this.defaultStaleTime,
|
|
969
1063
|
cacheTime: currentEntry?.cacheTime ?? this.defaultCacheTime,
|
|
970
1064
|
key: queryKey,
|
|
971
|
-
tags: mergedTags
|
|
1065
|
+
tags: mergedTags,
|
|
1066
|
+
promise: void 0
|
|
1067
|
+
// Clear promise
|
|
972
1068
|
});
|
|
973
1069
|
const schema = options?.schema || this.defaultSchema;
|
|
974
1070
|
const validatedData = validateWithSchema(data, schema);
|
|
@@ -986,7 +1082,9 @@ var QueryClient = class {
|
|
|
986
1082
|
staleTime: currentEntry?.staleTime ?? this.defaultStaleTime,
|
|
987
1083
|
cacheTime: currentEntry?.cacheTime ?? this.defaultCacheTime,
|
|
988
1084
|
key: queryKey,
|
|
989
|
-
tags: mergedTags
|
|
1085
|
+
tags: mergedTags,
|
|
1086
|
+
promise: void 0
|
|
1087
|
+
// Clear promise
|
|
990
1088
|
});
|
|
991
1089
|
this.pluginManager.onFetchError(normalizedKey, err);
|
|
992
1090
|
throw err;
|
|
@@ -996,18 +1094,15 @@ var QueryClient = class {
|
|
|
996
1094
|
* Invalidate queries
|
|
997
1095
|
*/
|
|
998
1096
|
invalidate = (queryKey) => {
|
|
999
|
-
const prefix = this.storage.generateKey(queryKey);
|
|
1000
1097
|
const normalizedKey = this.normalizeKey(queryKey);
|
|
1001
1098
|
this.pluginManager.onInvalidate(normalizedKey);
|
|
1002
|
-
const
|
|
1003
|
-
for (const key of
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
signal2.set({ ...current, isInvalidated: true });
|
|
1010
|
-
}
|
|
1099
|
+
const matchingKeys = this.storage.trie.getMatchingKeys(queryKey);
|
|
1100
|
+
for (const key of matchingKeys) {
|
|
1101
|
+
const signal2 = this.storage.get(key, false);
|
|
1102
|
+
if (signal2) {
|
|
1103
|
+
const current = signal2.get();
|
|
1104
|
+
if (current) {
|
|
1105
|
+
signal2.set({ ...current, isInvalidated: true });
|
|
1011
1106
|
}
|
|
1012
1107
|
}
|
|
1013
1108
|
}
|
|
@@ -1100,16 +1195,16 @@ var QueryClient = class {
|
|
|
1100
1195
|
};
|
|
1101
1196
|
|
|
1102
1197
|
// src/query/context.tsx
|
|
1103
|
-
var
|
|
1104
|
-
var QueryClientContext = (0,
|
|
1198
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
1199
|
+
var QueryClientContext = (0, import_react3.createContext)(void 0);
|
|
1105
1200
|
var QueryClientProvider = ({
|
|
1106
1201
|
client,
|
|
1107
1202
|
children
|
|
1108
1203
|
}) => {
|
|
1109
|
-
return /* @__PURE__ */ (0,
|
|
1204
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(QueryClientContext.Provider, { value: client, children: children || null });
|
|
1110
1205
|
};
|
|
1111
1206
|
var useQueryClient = () => {
|
|
1112
|
-
const client = (0,
|
|
1207
|
+
const client = (0, import_react3.useContext)(QueryClientContext);
|
|
1113
1208
|
if (!client) {
|
|
1114
1209
|
throw new Error("No QueryClient set, use QueryClientProvider to set one");
|
|
1115
1210
|
}
|
|
@@ -1119,8 +1214,8 @@ var useQueryClient = () => {
|
|
|
1119
1214
|
// src/query/useQueryStore.ts
|
|
1120
1215
|
function useQueryStore() {
|
|
1121
1216
|
const client = useQueryClient();
|
|
1122
|
-
const [cache, setCache] = (0,
|
|
1123
|
-
(0,
|
|
1217
|
+
const [cache, setCache] = (0, import_react4.useState)(client.getAll());
|
|
1218
|
+
(0, import_react4.useEffect)(() => {
|
|
1124
1219
|
const interval = setInterval(() => {
|
|
1125
1220
|
setCache(new Map(client.getAll()));
|
|
1126
1221
|
}, 500);
|
|
@@ -1130,13 +1225,13 @@ function useQueryStore() {
|
|
|
1130
1225
|
}
|
|
1131
1226
|
|
|
1132
1227
|
// src/devtools/QueryPanel.tsx
|
|
1133
|
-
var
|
|
1228
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
1134
1229
|
function QueryPanel() {
|
|
1135
1230
|
const cache = useQueryStore();
|
|
1136
1231
|
const client = useQueryClient();
|
|
1137
|
-
const [filter, setFilter] = (0,
|
|
1138
|
-
const entries = (0,
|
|
1139
|
-
const filteredEntries = (0,
|
|
1232
|
+
const [filter, setFilter] = (0, import_react5.useState)("");
|
|
1233
|
+
const entries = (0, import_react5.useMemo)(() => Array.from(cache.entries()), [cache]);
|
|
1234
|
+
const filteredEntries = (0, import_react5.useMemo)(() => {
|
|
1140
1235
|
if (!filter) return entries;
|
|
1141
1236
|
const search = filter.toLowerCase();
|
|
1142
1237
|
return entries.filter(([_, entry]) => {
|
|
@@ -1147,15 +1242,15 @@ function QueryPanel() {
|
|
|
1147
1242
|
return JSON.stringify(key).toLowerCase().includes(search);
|
|
1148
1243
|
});
|
|
1149
1244
|
}, [entries, filter]);
|
|
1150
|
-
return /* @__PURE__ */ (0,
|
|
1151
|
-
/* @__PURE__ */ (0,
|
|
1245
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { display: "flex", flexDirection: "column", height: "100%" }, children: [
|
|
1246
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: {
|
|
1152
1247
|
padding: "8px",
|
|
1153
1248
|
borderBottom: "1px solid #222",
|
|
1154
1249
|
background: "#0f0f0f",
|
|
1155
1250
|
display: "flex",
|
|
1156
1251
|
gap: "8px"
|
|
1157
1252
|
}, children: [
|
|
1158
|
-
/* @__PURE__ */ (0,
|
|
1253
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1159
1254
|
"input",
|
|
1160
1255
|
{
|
|
1161
1256
|
type: "text",
|
|
@@ -1174,7 +1269,7 @@ function QueryPanel() {
|
|
|
1174
1269
|
}
|
|
1175
1270
|
}
|
|
1176
1271
|
),
|
|
1177
|
-
/* @__PURE__ */ (0,
|
|
1272
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1178
1273
|
"button",
|
|
1179
1274
|
{
|
|
1180
1275
|
onClick: () => client.invalidateAll(),
|
|
@@ -1191,7 +1286,7 @@ function QueryPanel() {
|
|
|
1191
1286
|
}
|
|
1192
1287
|
)
|
|
1193
1288
|
] }),
|
|
1194
|
-
/* @__PURE__ */ (0,
|
|
1289
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: {
|
|
1195
1290
|
flex: 1,
|
|
1196
1291
|
overflowY: "auto",
|
|
1197
1292
|
padding: "8px",
|
|
@@ -1199,7 +1294,7 @@ function QueryPanel() {
|
|
|
1199
1294
|
flexDirection: "column",
|
|
1200
1295
|
gap: "8px",
|
|
1201
1296
|
background: "#050505"
|
|
1202
|
-
}, children: entries.length === 0 ? /* @__PURE__ */ (0,
|
|
1297
|
+
}, children: entries.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { padding: "20px", textAlign: "center", color: "#444", fontSize: "12px" }, children: "No active queries." }) : filteredEntries.map(([keyHash, entry]) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1203
1298
|
QueryItem,
|
|
1204
1299
|
{
|
|
1205
1300
|
entry,
|
|
@@ -1211,14 +1306,14 @@ function QueryPanel() {
|
|
|
1211
1306
|
] });
|
|
1212
1307
|
}
|
|
1213
1308
|
function QueryItem({ entry, client, isStale }) {
|
|
1214
|
-
const [expanded, setExpanded] = (0,
|
|
1215
|
-
return /* @__PURE__ */ (0,
|
|
1309
|
+
const [expanded, setExpanded] = (0, import_react5.useState)(false);
|
|
1310
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: {
|
|
1216
1311
|
background: "#111",
|
|
1217
1312
|
borderRadius: "4px",
|
|
1218
1313
|
border: "1px solid #222",
|
|
1219
1314
|
overflow: "hidden"
|
|
1220
1315
|
}, children: [
|
|
1221
|
-
/* @__PURE__ */ (0,
|
|
1316
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
1222
1317
|
"div",
|
|
1223
1318
|
{
|
|
1224
1319
|
onClick: () => setExpanded(!expanded),
|
|
@@ -1231,13 +1326,13 @@ function QueryItem({ entry, client, isStale }) {
|
|
|
1231
1326
|
background: expanded ? "#161616" : "transparent"
|
|
1232
1327
|
},
|
|
1233
1328
|
children: [
|
|
1234
|
-
/* @__PURE__ */ (0,
|
|
1235
|
-
/* @__PURE__ */ (0,
|
|
1329
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { display: "flex", gap: "8px", alignItems: "center", overflow: "hidden" }, children: [
|
|
1330
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { style: {
|
|
1236
1331
|
color: isStale ? "#d69e2e" : "#b0fb5d",
|
|
1237
1332
|
fontSize: "12px",
|
|
1238
1333
|
fontWeight: "bold"
|
|
1239
1334
|
}, children: "\u2022" }),
|
|
1240
|
-
/* @__PURE__ */ (0,
|
|
1335
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { style: {
|
|
1241
1336
|
color: "#e0e0e0",
|
|
1242
1337
|
fontSize: "12px",
|
|
1243
1338
|
whiteSpace: "nowrap",
|
|
@@ -1245,7 +1340,7 @@ function QueryItem({ entry, client, isStale }) {
|
|
|
1245
1340
|
textOverflow: "ellipsis"
|
|
1246
1341
|
}, children: JSON.stringify(entry.key) })
|
|
1247
1342
|
] }),
|
|
1248
|
-
/* @__PURE__ */ (0,
|
|
1343
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { style: {
|
|
1249
1344
|
fontSize: "9px",
|
|
1250
1345
|
color: isStale ? "#d69e2e" : "#b0fb5d",
|
|
1251
1346
|
padding: "1px 4px",
|
|
@@ -1256,13 +1351,13 @@ function QueryItem({ entry, client, isStale }) {
|
|
|
1256
1351
|
]
|
|
1257
1352
|
}
|
|
1258
1353
|
),
|
|
1259
|
-
expanded && /* @__PURE__ */ (0,
|
|
1354
|
+
expanded && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: {
|
|
1260
1355
|
padding: "8px",
|
|
1261
1356
|
borderTop: "1px solid #222",
|
|
1262
1357
|
background: "#0a0a0a"
|
|
1263
1358
|
}, children: [
|
|
1264
|
-
/* @__PURE__ */ (0,
|
|
1265
|
-
/* @__PURE__ */ (0,
|
|
1359
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { display: "flex", gap: "8px", marginBottom: "8px" }, children: [
|
|
1360
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1266
1361
|
"button",
|
|
1267
1362
|
{
|
|
1268
1363
|
onClick: (e) => {
|
|
@@ -1273,7 +1368,7 @@ function QueryItem({ entry, client, isStale }) {
|
|
|
1273
1368
|
children: "Invalidate"
|
|
1274
1369
|
}
|
|
1275
1370
|
),
|
|
1276
|
-
/* @__PURE__ */ (0,
|
|
1371
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1277
1372
|
"button",
|
|
1278
1373
|
{
|
|
1279
1374
|
onClick: (e) => {
|
|
@@ -1285,19 +1380,19 @@ function QueryItem({ entry, client, isStale }) {
|
|
|
1285
1380
|
}
|
|
1286
1381
|
)
|
|
1287
1382
|
] }),
|
|
1288
|
-
/* @__PURE__ */ (0,
|
|
1383
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("pre", { style: { margin: 0, fontSize: "10px", color: "#a0a0a0", overflowX: "auto", fontFamily: "monospace" }, children: JSON.stringify(entry.data, null, 2) })
|
|
1289
1384
|
] })
|
|
1290
1385
|
] });
|
|
1291
1386
|
}
|
|
1292
1387
|
|
|
1293
1388
|
// src/devtools/index.tsx
|
|
1294
|
-
var
|
|
1389
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
1295
1390
|
function QuantumDevTools() {
|
|
1296
|
-
const [isOpen, setIsOpen] = (0,
|
|
1297
|
-
const [activeTab, setActiveTab] = (0,
|
|
1298
|
-
const [height, setHeight] = (0,
|
|
1299
|
-
const isResizingRef = (0,
|
|
1300
|
-
(0,
|
|
1391
|
+
const [isOpen, setIsOpen] = (0, import_react6.useState)(false);
|
|
1392
|
+
const [activeTab, setActiveTab] = (0, import_react6.useState)("queries");
|
|
1393
|
+
const [height, setHeight] = (0, import_react6.useState)(400);
|
|
1394
|
+
const isResizingRef = (0, import_react6.useRef)(false);
|
|
1395
|
+
(0, import_react6.useEffect)(() => {
|
|
1301
1396
|
const handleMouseMove = (e) => {
|
|
1302
1397
|
if (!isResizingRef.current) return;
|
|
1303
1398
|
const newHeight = window.innerHeight - e.clientY;
|
|
@@ -1315,7 +1410,7 @@ function QuantumDevTools() {
|
|
|
1315
1410
|
};
|
|
1316
1411
|
}, []);
|
|
1317
1412
|
if (!isOpen) {
|
|
1318
|
-
return /* @__PURE__ */ (0,
|
|
1413
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1319
1414
|
"button",
|
|
1320
1415
|
{
|
|
1321
1416
|
onClick: () => setIsOpen(true),
|
|
@@ -1340,7 +1435,7 @@ function QuantumDevTools() {
|
|
|
1340
1435
|
}
|
|
1341
1436
|
);
|
|
1342
1437
|
}
|
|
1343
|
-
return /* @__PURE__ */ (0,
|
|
1438
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: {
|
|
1344
1439
|
position: "fixed",
|
|
1345
1440
|
bottom: 0,
|
|
1346
1441
|
right: 0,
|
|
@@ -1353,7 +1448,7 @@ function QuantumDevTools() {
|
|
|
1353
1448
|
flexDirection: "column",
|
|
1354
1449
|
fontFamily: "monospace"
|
|
1355
1450
|
}, children: [
|
|
1356
|
-
/* @__PURE__ */ (0,
|
|
1451
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1357
1452
|
"div",
|
|
1358
1453
|
{
|
|
1359
1454
|
onMouseDown: () => {
|
|
@@ -1363,7 +1458,7 @@ function QuantumDevTools() {
|
|
|
1363
1458
|
style: { height: "6px", top: "-3px", position: "absolute", width: "100%", cursor: "ns-resize", zIndex: 100 }
|
|
1364
1459
|
}
|
|
1365
1460
|
),
|
|
1366
|
-
/* @__PURE__ */ (0,
|
|
1461
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: {
|
|
1367
1462
|
display: "flex",
|
|
1368
1463
|
justifyContent: "space-between",
|
|
1369
1464
|
alignItems: "center",
|
|
@@ -1371,20 +1466,20 @@ function QuantumDevTools() {
|
|
|
1371
1466
|
background: "#111",
|
|
1372
1467
|
borderBottom: "1px solid #222"
|
|
1373
1468
|
}, children: [
|
|
1374
|
-
/* @__PURE__ */ (0,
|
|
1375
|
-
/* @__PURE__ */ (0,
|
|
1376
|
-
/* @__PURE__ */ (0,
|
|
1377
|
-
/* @__PURE__ */ (0,
|
|
1378
|
-
/* @__PURE__ */ (0,
|
|
1469
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: { display: "flex", gap: "16px", alignItems: "center" }, children: [
|
|
1470
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { style: { color: "#b0fb5d", fontWeight: "bold" }, children: "Quantum DevTools" }),
|
|
1471
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: { display: "flex", gap: "4px", background: "#000", padding: "2px", borderRadius: "4px" }, children: [
|
|
1472
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(TabButton, { active: activeTab === "queries", onClick: () => setActiveTab("queries"), children: "Queries" }),
|
|
1473
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(TabButton, { active: activeTab === "state", onClick: () => setActiveTab("state"), children: "State" })
|
|
1379
1474
|
] })
|
|
1380
1475
|
] }),
|
|
1381
|
-
/* @__PURE__ */ (0,
|
|
1476
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { onClick: () => setIsOpen(false), style: { background: "none", border: "none", color: "#666", cursor: "pointer" }, children: "\xD7" })
|
|
1382
1477
|
] }),
|
|
1383
|
-
/* @__PURE__ */ (0,
|
|
1478
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { flex: 1, overflow: "hidden" }, children: activeTab === "queries" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(QueryPanel, {}) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { children: "State Panel (Under Construction)" }) })
|
|
1384
1479
|
] });
|
|
1385
1480
|
}
|
|
1386
1481
|
function TabButton({ active, children, onClick }) {
|
|
1387
|
-
return /* @__PURE__ */ (0,
|
|
1482
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1388
1483
|
"button",
|
|
1389
1484
|
{
|
|
1390
1485
|
onClick,
|
|
@@ -1550,6 +1645,8 @@ var RetryMiddleware = async (ctx, next) => {
|
|
|
1550
1645
|
let config;
|
|
1551
1646
|
if (typeof retryConfigRaw === "number") {
|
|
1552
1647
|
config = { retries: retryConfigRaw };
|
|
1648
|
+
} else if (typeof retryConfigRaw === "boolean") {
|
|
1649
|
+
config = retryConfigRaw ? { retries: 3 } : { retries: 0 };
|
|
1553
1650
|
} else if (typeof retryConfigRaw === "object" && retryConfigRaw !== null) {
|
|
1554
1651
|
config = retryConfigRaw;
|
|
1555
1652
|
} else {
|
|
@@ -1739,7 +1836,7 @@ function getPromiseState(promise) {
|
|
|
1739
1836
|
}
|
|
1740
1837
|
|
|
1741
1838
|
// src/query/pagination.ts
|
|
1742
|
-
var
|
|
1839
|
+
var import_react7 = require("react");
|
|
1743
1840
|
function usePaginatedQuery({
|
|
1744
1841
|
queryKey,
|
|
1745
1842
|
queryFn,
|
|
@@ -1750,18 +1847,18 @@ function usePaginatedQuery({
|
|
|
1750
1847
|
retry
|
|
1751
1848
|
}) {
|
|
1752
1849
|
const client = useQueryClient();
|
|
1753
|
-
const [page, setPage] = (0,
|
|
1850
|
+
const [page, setPage] = (0, import_react7.useState)(0);
|
|
1754
1851
|
const pageQueryKey = [...queryKey, "page", page];
|
|
1755
1852
|
const pageQueryKeyHash = JSON.stringify(pageQueryKey);
|
|
1756
|
-
const subscribe = (0,
|
|
1853
|
+
const subscribe = (0, import_react7.useCallback)((onStoreChange) => {
|
|
1757
1854
|
const signal2 = client.getSignal(pageQueryKey);
|
|
1758
1855
|
return signal2.subscribe(() => onStoreChange());
|
|
1759
1856
|
}, [client, pageQueryKeyHash]);
|
|
1760
|
-
const getSnapshot = (0,
|
|
1857
|
+
const getSnapshot = (0, import_react7.useCallback)(() => {
|
|
1761
1858
|
const signal2 = client.getSignal(pageQueryKey);
|
|
1762
1859
|
return signal2.get();
|
|
1763
1860
|
}, [client, pageQueryKeyHash]);
|
|
1764
|
-
const cacheEntry = (0,
|
|
1861
|
+
const cacheEntry = (0, import_react7.useSyncExternalStore)(subscribe, getSnapshot);
|
|
1765
1862
|
const data = cacheEntry?.data;
|
|
1766
1863
|
const status = cacheEntry?.status || "pending";
|
|
1767
1864
|
const error = cacheEntry?.error || null;
|
|
@@ -1778,15 +1875,15 @@ function usePaginatedQuery({
|
|
|
1778
1875
|
}
|
|
1779
1876
|
}
|
|
1780
1877
|
const hasPrevious = page > 0;
|
|
1781
|
-
const queryFnRef = (0,
|
|
1782
|
-
const staleTimeRef = (0,
|
|
1783
|
-
const cacheTimeRef = (0,
|
|
1784
|
-
(0,
|
|
1878
|
+
const queryFnRef = (0, import_react7.useRef)(queryFn);
|
|
1879
|
+
const staleTimeRef = (0, import_react7.useRef)(staleTime);
|
|
1880
|
+
const cacheTimeRef = (0, import_react7.useRef)(cacheTime);
|
|
1881
|
+
(0, import_react7.useEffect)(() => {
|
|
1785
1882
|
queryFnRef.current = queryFn;
|
|
1786
1883
|
staleTimeRef.current = staleTime;
|
|
1787
1884
|
cacheTimeRef.current = cacheTime;
|
|
1788
1885
|
});
|
|
1789
|
-
const fetchPage = (0,
|
|
1886
|
+
const fetchPage = (0, import_react7.useCallback)(async (background = false) => {
|
|
1790
1887
|
if (!enabled) return;
|
|
1791
1888
|
if (!background) {
|
|
1792
1889
|
const currentEntry = getSnapshot();
|
|
@@ -1805,22 +1902,22 @@ function usePaginatedQuery({
|
|
|
1805
1902
|
} catch (err) {
|
|
1806
1903
|
}
|
|
1807
1904
|
}, [pageQueryKeyHash, enabled, client, getSnapshot, page]);
|
|
1808
|
-
(0,
|
|
1905
|
+
(0, import_react7.useEffect)(() => {
|
|
1809
1906
|
if (enabled) {
|
|
1810
1907
|
fetchPage();
|
|
1811
1908
|
}
|
|
1812
1909
|
}, [fetchPage, enabled]);
|
|
1813
|
-
const nextPage = (0,
|
|
1910
|
+
const nextPage = (0, import_react7.useCallback)(() => {
|
|
1814
1911
|
if (hasNext) {
|
|
1815
1912
|
setPage((p) => p + 1);
|
|
1816
1913
|
}
|
|
1817
1914
|
}, [hasNext]);
|
|
1818
|
-
const previousPage = (0,
|
|
1915
|
+
const previousPage = (0, import_react7.useCallback)(() => {
|
|
1819
1916
|
if (page > 0) {
|
|
1820
1917
|
setPage((p) => p - 1);
|
|
1821
1918
|
}
|
|
1822
1919
|
}, [page]);
|
|
1823
|
-
const refetch = (0,
|
|
1920
|
+
const refetch = (0, import_react7.useCallback)(async () => {
|
|
1824
1921
|
client.invalidate(pageQueryKey);
|
|
1825
1922
|
await fetchPage();
|
|
1826
1923
|
}, [pageQueryKeyHash, fetchPage, client]);
|
|
@@ -1840,7 +1937,7 @@ function usePaginatedQuery({
|
|
|
1840
1937
|
}
|
|
1841
1938
|
|
|
1842
1939
|
// src/query/useQuery.ts
|
|
1843
|
-
var
|
|
1940
|
+
var import_react8 = require("react");
|
|
1844
1941
|
|
|
1845
1942
|
// src/query/focusManager.ts
|
|
1846
1943
|
var FocusManager = class {
|
|
@@ -1976,7 +2073,7 @@ var QueryObserver = class {
|
|
|
1976
2073
|
status: selectorError ? "error" : status,
|
|
1977
2074
|
refetch: this.refetch
|
|
1978
2075
|
};
|
|
1979
|
-
const isDataEqual = lastResult?.data === nextResult.data
|
|
2076
|
+
const isDataEqual = lastResult?.data === nextResult.data;
|
|
1980
2077
|
if (lastResult && isDataEqual && lastResult.status === nextResult.status && lastResult.isFetching === nextResult.isFetching && lastResult.isStale === nextResult.isStale && lastResult.error === nextResult.error) {
|
|
1981
2078
|
return lastResult;
|
|
1982
2079
|
}
|
|
@@ -2098,30 +2195,57 @@ var QueryObserver = class {
|
|
|
2098
2195
|
// src/query/useQuery.ts
|
|
2099
2196
|
function useQuery(options) {
|
|
2100
2197
|
const client = useQueryClient();
|
|
2101
|
-
const [observer] = (0,
|
|
2102
|
-
(0,
|
|
2198
|
+
const [observer] = (0, import_react8.useState)(() => new QueryObserver(client, options));
|
|
2199
|
+
(0, import_react8.useEffect)(() => {
|
|
2103
2200
|
observer.setOptions(options);
|
|
2104
2201
|
}, [observer, options]);
|
|
2105
|
-
(0,
|
|
2202
|
+
(0, import_react8.useEffect)(() => {
|
|
2106
2203
|
return () => {
|
|
2107
2204
|
observer.destroy();
|
|
2108
2205
|
};
|
|
2109
2206
|
}, [observer]);
|
|
2110
|
-
const subscribe = (0,
|
|
2207
|
+
const subscribe = (0, import_react8.useCallback)((onStoreChange) => {
|
|
2111
2208
|
return observer.subscribe(onStoreChange);
|
|
2112
2209
|
}, [observer]);
|
|
2113
|
-
const getSnapshot = (0,
|
|
2210
|
+
const getSnapshot = (0, import_react8.useCallback)(() => {
|
|
2114
2211
|
return observer.getSnapshot();
|
|
2115
2212
|
}, [observer]);
|
|
2116
|
-
const result = (0,
|
|
2213
|
+
const result = (0, import_react8.useSyncExternalStore)(subscribe, getSnapshot);
|
|
2117
2214
|
return {
|
|
2118
2215
|
...result,
|
|
2119
2216
|
signal: observer.result$
|
|
2120
2217
|
};
|
|
2121
2218
|
}
|
|
2122
2219
|
|
|
2220
|
+
// src/query/useSuspenseQuery.ts
|
|
2221
|
+
function useSuspenseQuery(options) {
|
|
2222
|
+
const client = useQueryClient();
|
|
2223
|
+
const signal2 = client.getSignal(options.queryKey);
|
|
2224
|
+
const entry = signal2.get();
|
|
2225
|
+
if (entry?.status === "error") {
|
|
2226
|
+
throw entry.error;
|
|
2227
|
+
}
|
|
2228
|
+
if (!entry || entry.status === "pending" && entry.data === void 0) {
|
|
2229
|
+
if (entry?.promise) {
|
|
2230
|
+
throw entry.promise;
|
|
2231
|
+
}
|
|
2232
|
+
const fetchPromise = client.fetch(options.queryKey, options.queryFn, {
|
|
2233
|
+
retry: options.retry,
|
|
2234
|
+
retryDelay: options.retryDelay,
|
|
2235
|
+
tags: options.tags,
|
|
2236
|
+
schema: options.schema
|
|
2237
|
+
});
|
|
2238
|
+
throw fetchPromise;
|
|
2239
|
+
}
|
|
2240
|
+
const query = useQuery(options);
|
|
2241
|
+
return {
|
|
2242
|
+
...query,
|
|
2243
|
+
data: query.data
|
|
2244
|
+
};
|
|
2245
|
+
}
|
|
2246
|
+
|
|
2123
2247
|
// src/query/useMutation.ts
|
|
2124
|
-
var
|
|
2248
|
+
var import_react9 = require("react");
|
|
2125
2249
|
|
|
2126
2250
|
// src/query/mutationObserver.ts
|
|
2127
2251
|
var generateId = () => {
|
|
@@ -2238,18 +2362,18 @@ var MutationObserver = class {
|
|
|
2238
2362
|
// src/query/useMutation.ts
|
|
2239
2363
|
function useMutation(options) {
|
|
2240
2364
|
const client = useQueryClient();
|
|
2241
|
-
const [observer] = (0,
|
|
2242
|
-
(0,
|
|
2365
|
+
const [observer] = (0, import_react9.useState)(() => new MutationObserver(client, options));
|
|
2366
|
+
(0, import_react9.useEffect)(() => {
|
|
2243
2367
|
observer.setOptions(options);
|
|
2244
2368
|
}, [observer, options]);
|
|
2245
|
-
const state = (0,
|
|
2246
|
-
(0,
|
|
2369
|
+
const state = (0, import_react9.useSyncExternalStore)(
|
|
2370
|
+
(0, import_react9.useCallback)((cb) => observer.signal.subscribe(cb), [observer]),
|
|
2247
2371
|
() => observer.signal.get()
|
|
2248
2372
|
);
|
|
2249
|
-
const mutateAsync = (0,
|
|
2373
|
+
const mutateAsync = (0, import_react9.useCallback)((variables) => {
|
|
2250
2374
|
return observer.mutate(variables);
|
|
2251
2375
|
}, [observer]);
|
|
2252
|
-
const mutate = (0,
|
|
2376
|
+
const mutate = (0, import_react9.useCallback)((variables) => {
|
|
2253
2377
|
observer.mutate(variables).catch(() => {
|
|
2254
2378
|
});
|
|
2255
2379
|
}, [observer]);
|
|
@@ -2268,7 +2392,7 @@ function useMutation(options) {
|
|
|
2268
2392
|
}
|
|
2269
2393
|
|
|
2270
2394
|
// src/query/infiniteQuery.ts
|
|
2271
|
-
var
|
|
2395
|
+
var import_react10 = require("react");
|
|
2272
2396
|
|
|
2273
2397
|
// src/query/plugins/logger.ts
|
|
2274
2398
|
var consoleLogger = {
|
|
@@ -2285,7 +2409,7 @@ var InfiniteQueryObserver = class {
|
|
|
2285
2409
|
options$;
|
|
2286
2410
|
result$;
|
|
2287
2411
|
unsubscribe = null;
|
|
2288
|
-
|
|
2412
|
+
abortController = null;
|
|
2289
2413
|
constructor(client, options) {
|
|
2290
2414
|
this.client = client;
|
|
2291
2415
|
this.options$ = createSignal(options);
|
|
@@ -2338,8 +2462,7 @@ var InfiniteQueryObserver = class {
|
|
|
2338
2462
|
fetchPreviousPage: this.fetchPreviousPage,
|
|
2339
2463
|
refetch: this.refetch
|
|
2340
2464
|
};
|
|
2341
|
-
|
|
2342
|
-
if (lastResult && isDataEqual && lastResult.isFetching === nextResult.isFetching && lastResult.status === nextResult.status && lastResult.hasNextPage === nextResult.hasNextPage && lastResult.hasPreviousPage === nextResult.hasPreviousPage) {
|
|
2465
|
+
if (lastResult && lastResult.data === nextResult.data && lastResult.isFetching === nextResult.isFetching && lastResult.status === nextResult.status && lastResult.hasNextPage === nextResult.hasNextPage && lastResult.hasPreviousPage === nextResult.hasPreviousPage && lastResult.error === nextResult.error) {
|
|
2343
2466
|
return lastResult;
|
|
2344
2467
|
}
|
|
2345
2468
|
lastResult = nextResult;
|
|
@@ -2351,8 +2474,8 @@ var InfiniteQueryObserver = class {
|
|
|
2351
2474
|
const current = this.options$.get();
|
|
2352
2475
|
if (current === options) return;
|
|
2353
2476
|
const isKeyEqual = stableHash(current.queryKey) === stableHash(options.queryKey);
|
|
2354
|
-
const isConfigEqual = current.enabled === options.enabled && current.staleTime === options.staleTime;
|
|
2355
|
-
if (!isKeyEqual || !isConfigEqual
|
|
2477
|
+
const isConfigEqual = current.enabled === options.enabled && current.staleTime === options.staleTime && current.retry === options.retry;
|
|
2478
|
+
if (!isKeyEqual || !isConfigEqual) {
|
|
2356
2479
|
this.options$.set(options);
|
|
2357
2480
|
}
|
|
2358
2481
|
}
|
|
@@ -2385,25 +2508,37 @@ var InfiniteQueryObserver = class {
|
|
|
2385
2508
|
}
|
|
2386
2509
|
});
|
|
2387
2510
|
this.unsubscribe = () => {
|
|
2511
|
+
this.cancel();
|
|
2388
2512
|
dispose();
|
|
2389
2513
|
disposeFocus();
|
|
2390
2514
|
disposeOnline();
|
|
2391
2515
|
};
|
|
2392
2516
|
}
|
|
2517
|
+
cancel() {
|
|
2518
|
+
if (this.abortController) {
|
|
2519
|
+
this.abortController.abort();
|
|
2520
|
+
this.abortController = null;
|
|
2521
|
+
}
|
|
2522
|
+
}
|
|
2393
2523
|
fetchInitial = async (options) => {
|
|
2524
|
+
this.cancel();
|
|
2525
|
+
this.abortController = new AbortController();
|
|
2526
|
+
const signal2 = this.abortController.signal;
|
|
2394
2527
|
const opts = this.options$.get();
|
|
2395
2528
|
const infiniteKey = [...opts.queryKey, "__infinite__"];
|
|
2396
2529
|
try {
|
|
2397
2530
|
const entrySignal = this.client.getSignal(infiniteKey);
|
|
2398
|
-
const
|
|
2399
|
-
if (
|
|
2400
|
-
const firstParam2 =
|
|
2531
|
+
const currentState = entrySignal.get()?.data;
|
|
2532
|
+
if (currentState && currentState.pageParams.length > 0 && !options?.force) {
|
|
2533
|
+
const firstParam2 = currentState.pageParams[0];
|
|
2401
2534
|
const firstPage = await opts.queryFn({ pageParam: firstParam2 });
|
|
2535
|
+
if (signal2.aborted) return;
|
|
2402
2536
|
const latest = entrySignal.get()?.data;
|
|
2403
2537
|
if (!latest) return;
|
|
2404
2538
|
const updatedData = {
|
|
2405
2539
|
...latest,
|
|
2406
2540
|
pages: [firstPage, ...latest.pages.slice(1)]
|
|
2541
|
+
// pageParams remain the same
|
|
2407
2542
|
};
|
|
2408
2543
|
this.client.set(infiniteKey, updatedData, {
|
|
2409
2544
|
staleTime: opts.staleTime,
|
|
@@ -2413,107 +2548,116 @@ var InfiniteQueryObserver = class {
|
|
|
2413
2548
|
}
|
|
2414
2549
|
const initialParam = opts.initialPageParam;
|
|
2415
2550
|
const firstParam = initialParam !== void 0 ? initialParam : 0;
|
|
2416
|
-
const initialData = await this.client.fetch(infiniteKey, async () => {
|
|
2551
|
+
const initialData = await this.client.fetch(infiniteKey, async (ctx) => {
|
|
2417
2552
|
const firstPage = await opts.queryFn({ pageParam: firstParam });
|
|
2418
2553
|
return {
|
|
2419
2554
|
pages: [firstPage],
|
|
2420
2555
|
pageParams: [firstParam]
|
|
2421
2556
|
};
|
|
2422
|
-
}, {
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2557
|
+
}, {
|
|
2558
|
+
fetchDirection: "initial",
|
|
2559
|
+
retry: opts.retry,
|
|
2560
|
+
signal: signal2
|
|
2426
2561
|
});
|
|
2562
|
+
if (!signal2.aborted) {
|
|
2563
|
+
this.client.set(infiniteKey, initialData, {
|
|
2564
|
+
staleTime: opts.staleTime,
|
|
2565
|
+
cacheTime: opts.cacheTime
|
|
2566
|
+
});
|
|
2567
|
+
}
|
|
2427
2568
|
} catch (err) {
|
|
2428
|
-
|
|
2569
|
+
if (!signal2.aborted) {
|
|
2570
|
+
getLogger().error("Initial fetch failed", err);
|
|
2571
|
+
}
|
|
2429
2572
|
}
|
|
2430
2573
|
};
|
|
2431
2574
|
fetchNextPage = async () => {
|
|
2432
2575
|
const res = this.result$.get();
|
|
2433
|
-
const opts = this.options$.get();
|
|
2434
2576
|
if (!res.hasNextPage || res.isFetching || !res.data) return;
|
|
2577
|
+
this.cancel();
|
|
2578
|
+
this.abortController = new AbortController();
|
|
2579
|
+
const signal2 = this.abortController.signal;
|
|
2580
|
+
const opts = this.options$.get();
|
|
2435
2581
|
const infiniteKey = [...opts.queryKey, "__infinite__"];
|
|
2436
2582
|
const lastPage = res.data.pages[res.data.pages.length - 1];
|
|
2437
|
-
if (!lastPage)
|
|
2438
|
-
return;
|
|
2439
|
-
}
|
|
2583
|
+
if (!lastPage) return;
|
|
2440
2584
|
const nextPageParam = opts.getNextPageParam?.(lastPage, res.data.pages);
|
|
2441
2585
|
if (nextPageParam === void 0) return;
|
|
2442
2586
|
try {
|
|
2443
|
-
const updatedData = await this.client.fetch(infiniteKey, async () => {
|
|
2587
|
+
const updatedData = await this.client.fetch(infiniteKey, async (ctx) => {
|
|
2444
2588
|
const newPage = await opts.queryFn({ pageParam: nextPageParam });
|
|
2589
|
+
if (ctx.signal?.aborted) throw new Error("Aborted");
|
|
2445
2590
|
const currentData = this.client.getSignal(infiniteKey).get()?.data;
|
|
2446
2591
|
if (!currentData) throw new Error("Infinite query data missing");
|
|
2447
|
-
const updatedParams = [...currentData.pageParams, nextPageParam];
|
|
2448
|
-
const nextCursor = opts.getNextPageParam?.(newPage, [...currentData.pages, newPage]);
|
|
2449
|
-
if (nextCursor !== void 0) {
|
|
2450
|
-
updatedParams.push(nextCursor);
|
|
2451
|
-
}
|
|
2452
2592
|
return {
|
|
2453
2593
|
pages: [...currentData.pages, newPage],
|
|
2454
|
-
pageParams:
|
|
2594
|
+
pageParams: [...currentData.pageParams, nextPageParam]
|
|
2455
2595
|
};
|
|
2456
|
-
}, {
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2596
|
+
}, {
|
|
2597
|
+
fetchDirection: "next",
|
|
2598
|
+
retry: opts.retry,
|
|
2599
|
+
signal: signal2
|
|
2460
2600
|
});
|
|
2601
|
+
if (!signal2.aborted) {
|
|
2602
|
+
this.client.set(infiniteKey, updatedData, {
|
|
2603
|
+
staleTime: opts.staleTime,
|
|
2604
|
+
cacheTime: opts.cacheTime
|
|
2605
|
+
});
|
|
2606
|
+
}
|
|
2461
2607
|
} catch (err) {
|
|
2462
|
-
|
|
2608
|
+
if (!signal2.aborted) {
|
|
2609
|
+
getLogger().error("Fetch next page failed", err);
|
|
2610
|
+
}
|
|
2463
2611
|
}
|
|
2464
2612
|
};
|
|
2465
2613
|
fetchPreviousPage = async () => {
|
|
2466
2614
|
const res = this.result$.get();
|
|
2467
|
-
const opts = this.options$.get();
|
|
2468
2615
|
if (!res.hasPreviousPage || res.isFetching || !res.data) return;
|
|
2616
|
+
this.cancel();
|
|
2617
|
+
this.abortController = new AbortController();
|
|
2618
|
+
const signal2 = this.abortController.signal;
|
|
2619
|
+
const opts = this.options$.get();
|
|
2469
2620
|
const infiniteKey = [...opts.queryKey, "__infinite__"];
|
|
2470
2621
|
const firstPage = res.data.pages[0];
|
|
2471
|
-
if (!firstPage)
|
|
2472
|
-
return;
|
|
2473
|
-
}
|
|
2622
|
+
if (!firstPage) return;
|
|
2474
2623
|
const previousPageParam = opts.getPreviousPageParam?.(firstPage, res.data.pages);
|
|
2475
2624
|
if (previousPageParam === void 0) return;
|
|
2476
2625
|
try {
|
|
2477
|
-
const updatedData = await this.client.fetch(infiniteKey, async () => {
|
|
2626
|
+
const updatedData = await this.client.fetch(infiniteKey, async (ctx) => {
|
|
2478
2627
|
const newPage = await opts.queryFn({ pageParam: previousPageParam });
|
|
2628
|
+
if (ctx.signal?.aborted) throw new Error("Aborted");
|
|
2479
2629
|
const currentData = this.client.getSignal(infiniteKey).get()?.data;
|
|
2480
2630
|
if (!currentData) throw new Error("Infinite query data missing");
|
|
2481
2631
|
return {
|
|
2482
2632
|
pages: [newPage, ...currentData.pages],
|
|
2483
2633
|
pageParams: [previousPageParam, ...currentData.pageParams]
|
|
2484
2634
|
};
|
|
2485
|
-
}, {
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2635
|
+
}, {
|
|
2636
|
+
fetchDirection: "previous",
|
|
2637
|
+
retry: opts.retry,
|
|
2638
|
+
signal: signal2
|
|
2489
2639
|
});
|
|
2640
|
+
if (!signal2.aborted) {
|
|
2641
|
+
this.client.set(infiniteKey, updatedData, {
|
|
2642
|
+
staleTime: opts.staleTime,
|
|
2643
|
+
cacheTime: opts.cacheTime
|
|
2644
|
+
});
|
|
2645
|
+
}
|
|
2490
2646
|
} catch (err) {
|
|
2491
|
-
|
|
2647
|
+
if (!signal2.aborted) {
|
|
2648
|
+
getLogger().error("Fetch previous page failed", err);
|
|
2649
|
+
}
|
|
2492
2650
|
}
|
|
2493
2651
|
};
|
|
2494
2652
|
refetch = async () => {
|
|
2653
|
+
this.cancel();
|
|
2495
2654
|
const opts = this.options$.get();
|
|
2496
2655
|
const infiniteKey = [...opts.queryKey, "__infinite__"];
|
|
2497
2656
|
this.client.invalidate(infiniteKey);
|
|
2498
|
-
|
|
2499
|
-
const firstParam = initialParam !== void 0 ? initialParam : 0;
|
|
2500
|
-
try {
|
|
2501
|
-
const initialData = await this.client.fetch(infiniteKey, async () => {
|
|
2502
|
-
const firstPage = await opts.queryFn({ pageParam: firstParam });
|
|
2503
|
-
return {
|
|
2504
|
-
pages: [firstPage],
|
|
2505
|
-
pageParams: [firstParam]
|
|
2506
|
-
};
|
|
2507
|
-
}, { fetchDirection: "initial", retry: opts.retry });
|
|
2508
|
-
this.client.set(infiniteKey, initialData, {
|
|
2509
|
-
staleTime: opts.staleTime,
|
|
2510
|
-
cacheTime: opts.cacheTime
|
|
2511
|
-
});
|
|
2512
|
-
} catch (err) {
|
|
2513
|
-
getLogger().error("Refetch failed", err);
|
|
2514
|
-
}
|
|
2657
|
+
await this.fetchInitial({ force: true });
|
|
2515
2658
|
};
|
|
2516
2659
|
destroy() {
|
|
2660
|
+
this.cancel();
|
|
2517
2661
|
if (this.unsubscribe) this.unsubscribe();
|
|
2518
2662
|
}
|
|
2519
2663
|
};
|
|
@@ -2521,26 +2665,26 @@ var InfiniteQueryObserver = class {
|
|
|
2521
2665
|
// src/query/infiniteQuery.ts
|
|
2522
2666
|
function useInfiniteQuery(options) {
|
|
2523
2667
|
const client = useQueryClient();
|
|
2524
|
-
const [observer] = (0,
|
|
2525
|
-
(0,
|
|
2668
|
+
const [observer] = (0, import_react10.useState)(() => new InfiniteQueryObserver(client, options));
|
|
2669
|
+
(0, import_react10.useEffect)(() => {
|
|
2526
2670
|
observer.setOptions(options);
|
|
2527
2671
|
}, [observer, options]);
|
|
2528
|
-
(0,
|
|
2672
|
+
(0, import_react10.useEffect)(() => {
|
|
2529
2673
|
return () => {
|
|
2530
2674
|
observer.destroy();
|
|
2531
2675
|
};
|
|
2532
2676
|
}, [observer]);
|
|
2533
|
-
const subscribe = (0,
|
|
2677
|
+
const subscribe = (0, import_react10.useCallback)((onStoreChange) => {
|
|
2534
2678
|
return observer.result$.subscribe(() => onStoreChange());
|
|
2535
2679
|
}, [observer]);
|
|
2536
|
-
const getSnapshot = (0,
|
|
2680
|
+
const getSnapshot = (0, import_react10.useCallback)(() => {
|
|
2537
2681
|
return observer.result$.get();
|
|
2538
2682
|
}, [observer]);
|
|
2539
|
-
return (0,
|
|
2683
|
+
return (0, import_react10.useSyncExternalStore)(subscribe, getSnapshot);
|
|
2540
2684
|
}
|
|
2541
2685
|
|
|
2542
2686
|
// src/query/HydrationBoundary.tsx
|
|
2543
|
-
var
|
|
2687
|
+
var import_react11 = require("react");
|
|
2544
2688
|
|
|
2545
2689
|
// src/query/hydration.ts
|
|
2546
2690
|
function dehydrate(client) {
|
|
@@ -2565,53 +2709,26 @@ function hydrate(client, state) {
|
|
|
2565
2709
|
}
|
|
2566
2710
|
|
|
2567
2711
|
// src/query/HydrationBoundary.tsx
|
|
2568
|
-
var
|
|
2712
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
2569
2713
|
function HydrationBoundary({ state, children }) {
|
|
2570
2714
|
const client = useQueryClient();
|
|
2571
|
-
const hydratedRef = (0,
|
|
2715
|
+
const hydratedRef = (0, import_react11.useRef)(false);
|
|
2572
2716
|
if (state && !hydratedRef.current) {
|
|
2573
2717
|
hydrate(client, state);
|
|
2574
2718
|
hydratedRef.current = true;
|
|
2575
2719
|
}
|
|
2576
|
-
return /* @__PURE__ */ (0,
|
|
2577
|
-
}
|
|
2578
|
-
|
|
2579
|
-
// src/query/useSuspenseQuery.ts
|
|
2580
|
-
function useSuspenseQuery(options) {
|
|
2581
|
-
const client = useQueryClient();
|
|
2582
|
-
const signal2 = client.getSignal(options.queryKey);
|
|
2583
|
-
const entry = signal2.get();
|
|
2584
|
-
const shouldSuspend = !entry || entry.status === "pending" && entry.data === void 0;
|
|
2585
|
-
if (shouldSuspend) {
|
|
2586
|
-
const fetchPromise = client.fetch(
|
|
2587
|
-
options.queryKey,
|
|
2588
|
-
(ctx) => options.queryFn({ ...ctx, signal: void 0 }),
|
|
2589
|
-
{ signal: void 0 }
|
|
2590
|
-
).then((data) => {
|
|
2591
|
-
client.set(options.queryKey, data);
|
|
2592
|
-
return data;
|
|
2593
|
-
});
|
|
2594
|
-
throw fetchPromise;
|
|
2595
|
-
}
|
|
2596
|
-
if (entry?.status === "error") {
|
|
2597
|
-
throw entry.error;
|
|
2598
|
-
}
|
|
2599
|
-
const query = useQuery(options);
|
|
2600
|
-
return {
|
|
2601
|
-
...query,
|
|
2602
|
-
data: query.data
|
|
2603
|
-
};
|
|
2720
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_jsx_runtime6.Fragment, { children });
|
|
2604
2721
|
}
|
|
2605
2722
|
|
|
2606
2723
|
// src/query/useQuerySignal.ts
|
|
2607
|
-
var
|
|
2724
|
+
var import_react12 = require("react");
|
|
2608
2725
|
function useQuery$(options) {
|
|
2609
2726
|
const client = useQueryClient();
|
|
2610
|
-
const [observer] = (0,
|
|
2611
|
-
(0,
|
|
2727
|
+
const [observer] = (0, import_react12.useState)(() => new QueryObserver(client, options));
|
|
2728
|
+
(0, import_react12.useEffect)(() => {
|
|
2612
2729
|
observer.setOptions(options);
|
|
2613
2730
|
}, [observer, options.enabled, options.staleTime, options.cacheTime, options.queryKey, options.refetchInterval]);
|
|
2614
|
-
(0,
|
|
2731
|
+
(0, import_react12.useEffect)(() => {
|
|
2615
2732
|
const unsubscribe = observer.subscribe(() => {
|
|
2616
2733
|
});
|
|
2617
2734
|
return () => {
|
|
@@ -2623,18 +2740,18 @@ function useQuery$(options) {
|
|
|
2623
2740
|
}
|
|
2624
2741
|
|
|
2625
2742
|
// src/query/useQueries.ts
|
|
2626
|
-
var
|
|
2743
|
+
var import_react13 = require("react");
|
|
2627
2744
|
function useQueries(queries, client) {
|
|
2628
2745
|
const queryClient = client || globalThis.__QUANTUM_CLIENT__;
|
|
2629
2746
|
if (!queryClient) {
|
|
2630
2747
|
throw new Error("[Quantum] No QueryClient found. Wrap your app with QueryClientProvider or pass a client.");
|
|
2631
2748
|
}
|
|
2632
|
-
const [observers] = (0,
|
|
2749
|
+
const [observers] = (0, import_react13.useState)(
|
|
2633
2750
|
() => queries.map(
|
|
2634
2751
|
(options) => new QueryObserver(queryClient, options)
|
|
2635
2752
|
)
|
|
2636
2753
|
);
|
|
2637
|
-
const results = (0,
|
|
2754
|
+
const results = (0, import_react13.useSyncExternalStore)(
|
|
2638
2755
|
(callback) => {
|
|
2639
2756
|
const unsubscribes = observers.map((observer) => observer.subscribe(callback));
|
|
2640
2757
|
return () => {
|
|
@@ -2644,7 +2761,7 @@ function useQueries(queries, client) {
|
|
|
2644
2761
|
() => observers.map((observer) => observer.getSnapshot()),
|
|
2645
2762
|
() => observers.map((observer) => observer.getSnapshot())
|
|
2646
2763
|
);
|
|
2647
|
-
(0,
|
|
2764
|
+
(0, import_react13.useEffect)(() => {
|
|
2648
2765
|
queries.forEach((options, index) => {
|
|
2649
2766
|
const observer = observers[index];
|
|
2650
2767
|
if (observer) {
|
|
@@ -2652,7 +2769,7 @@ function useQueries(queries, client) {
|
|
|
2652
2769
|
}
|
|
2653
2770
|
});
|
|
2654
2771
|
}, [queries, observers]);
|
|
2655
|
-
(0,
|
|
2772
|
+
(0, import_react13.useEffect)(() => {
|
|
2656
2773
|
return () => {
|
|
2657
2774
|
observers.forEach((observer) => observer.destroy());
|
|
2658
2775
|
};
|
|
@@ -2683,9 +2800,12 @@ function useCombinedQueries(queries, client) {
|
|
|
2683
2800
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2684
2801
|
0 && (module.exports = {
|
|
2685
2802
|
HydrationBoundary,
|
|
2803
|
+
Match,
|
|
2804
|
+
MutationCache,
|
|
2686
2805
|
QuantumDevTools,
|
|
2687
2806
|
QueryClient,
|
|
2688
2807
|
QueryClientProvider,
|
|
2808
|
+
QueryMatch,
|
|
2689
2809
|
SignalValue,
|
|
2690
2810
|
atom,
|
|
2691
2811
|
createHttpClient,
|