@braine/quantum-query 1.2.5 → 1.2.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +58 -205
- package/dist/index.cjs +1544 -1394
- package/dist/index.d.cts +246 -179
- package/dist/index.d.ts +246 -179
- package/dist/index.js +1544 -1387
- package/package.json +6 -2
package/dist/index.js
CHANGED
|
@@ -1,293 +1,167 @@
|
|
|
1
|
-
// src/
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
// src/core/asyncUtils.ts
|
|
18
|
-
var PROMISE_CACHE = /* @__PURE__ */ new WeakMap();
|
|
19
|
-
var PROMISE_STATUS = /* @__PURE__ */ new WeakMap();
|
|
20
|
-
var PROMISE_ERROR = /* @__PURE__ */ new WeakMap();
|
|
21
|
-
function isPromise(value) {
|
|
22
|
-
return !!value && typeof value.then === "function";
|
|
23
|
-
}
|
|
24
|
-
function handlePromise(promise, triggerUpdate) {
|
|
25
|
-
if (PROMISE_STATUS.has(promise)) return;
|
|
26
|
-
PROMISE_STATUS.set(promise, "pending");
|
|
27
|
-
promise.then(
|
|
28
|
-
(value) => {
|
|
29
|
-
PROMISE_STATUS.set(promise, "fulfilled");
|
|
30
|
-
PROMISE_CACHE.set(promise, value);
|
|
31
|
-
triggerUpdate();
|
|
1
|
+
// src/signals.ts
|
|
2
|
+
import {
|
|
3
|
+
signal,
|
|
4
|
+
computed as preactComputed,
|
|
5
|
+
effect as preactEffect,
|
|
6
|
+
batch as preactBatch,
|
|
7
|
+
untracked as preactUntracked
|
|
8
|
+
} from "@preact/signals-core";
|
|
9
|
+
function createSignal(initialValue, options) {
|
|
10
|
+
const s = signal(initialValue);
|
|
11
|
+
let subscriberCount = 0;
|
|
12
|
+
return {
|
|
13
|
+
get: () => s.value,
|
|
14
|
+
set: (newValue) => {
|
|
15
|
+
s.value = newValue;
|
|
32
16
|
},
|
|
33
|
-
(
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
17
|
+
subscribe: (fn) => {
|
|
18
|
+
if (subscriberCount === 0) {
|
|
19
|
+
options?.onActive?.();
|
|
20
|
+
}
|
|
21
|
+
subscriberCount++;
|
|
22
|
+
const dispose = preactEffect(() => {
|
|
23
|
+
fn(s.value);
|
|
24
|
+
});
|
|
25
|
+
return () => {
|
|
26
|
+
dispose();
|
|
27
|
+
subscriberCount--;
|
|
28
|
+
if (subscriberCount === 0) {
|
|
29
|
+
options?.onInactive?.();
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
},
|
|
33
|
+
isWatched: () => subscriberCount > 0
|
|
34
|
+
};
|
|
49
35
|
}
|
|
50
|
-
function
|
|
36
|
+
function computed(fn) {
|
|
37
|
+
const c = preactComputed(fn);
|
|
38
|
+
let subscriberCount = 0;
|
|
51
39
|
return {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
40
|
+
get: () => c.value,
|
|
41
|
+
set: () => {
|
|
42
|
+
throw new Error("[Quantum] Cannot set a computed signal directly.");
|
|
43
|
+
},
|
|
44
|
+
subscribe: (fn2) => {
|
|
45
|
+
subscriberCount++;
|
|
46
|
+
const dispose = preactEffect(() => {
|
|
47
|
+
fn2(c.value);
|
|
48
|
+
});
|
|
49
|
+
return () => {
|
|
50
|
+
dispose();
|
|
51
|
+
subscriberCount--;
|
|
52
|
+
};
|
|
53
|
+
},
|
|
54
|
+
isWatched: () => subscriberCount > 0
|
|
55
55
|
};
|
|
56
56
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
var LISTENERS = /* @__PURE__ */ new WeakMap();
|
|
60
|
-
var PROXIES = /* @__PURE__ */ new WeakMap();
|
|
61
|
-
var PROXY_TO_TARGET = /* @__PURE__ */ new WeakMap();
|
|
62
|
-
var activeListener = null;
|
|
63
|
-
function setActiveListener(listener) {
|
|
64
|
-
activeListener = listener;
|
|
65
|
-
}
|
|
66
|
-
function getActiveListener() {
|
|
67
|
-
return activeListener;
|
|
68
|
-
}
|
|
69
|
-
var GLOBAL_LISTENERS = /* @__PURE__ */ new WeakMap();
|
|
70
|
-
function subscribe(store, callback) {
|
|
71
|
-
const target = PROXY_TO_TARGET.get(store) || store;
|
|
72
|
-
let listeners = GLOBAL_LISTENERS.get(target);
|
|
73
|
-
if (!listeners) {
|
|
74
|
-
listeners = /* @__PURE__ */ new Set();
|
|
75
|
-
GLOBAL_LISTENERS.set(target, listeners);
|
|
76
|
-
}
|
|
77
|
-
listeners.add(callback);
|
|
78
|
-
return () => listeners?.delete(callback);
|
|
57
|
+
function effect(fn) {
|
|
58
|
+
return preactEffect(fn);
|
|
79
59
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
if (activeListener) {
|
|
83
|
-
let listeners = LISTENERS.get(target);
|
|
84
|
-
if (!listeners) {
|
|
85
|
-
listeners = /* @__PURE__ */ new Set();
|
|
86
|
-
LISTENERS.set(target, listeners);
|
|
87
|
-
}
|
|
88
|
-
listeners.add(activeListener);
|
|
89
|
-
}
|
|
90
|
-
const value = Reflect.get(target, prop, receiver);
|
|
91
|
-
if (isPromise(value)) {
|
|
92
|
-
return unwrapPromise(value);
|
|
93
|
-
}
|
|
94
|
-
if (typeof value === "object" && value !== null) {
|
|
95
|
-
return createState(value);
|
|
96
|
-
}
|
|
97
|
-
return value;
|
|
98
|
-
},
|
|
99
|
-
set(target, prop, value, receiver) {
|
|
100
|
-
const oldValue = Reflect.get(target, prop, receiver);
|
|
101
|
-
if (Object.is(oldValue, value)) return true;
|
|
102
|
-
if (isPromise(value)) {
|
|
103
|
-
const trigger = () => {
|
|
104
|
-
const listeners2 = LISTENERS.get(target);
|
|
105
|
-
if (listeners2) listeners2.forEach((l) => l());
|
|
106
|
-
};
|
|
107
|
-
handlePromise(value, trigger);
|
|
108
|
-
}
|
|
109
|
-
const result = Reflect.set(target, prop, value, receiver);
|
|
110
|
-
const listeners = LISTENERS.get(target);
|
|
111
|
-
if (listeners) {
|
|
112
|
-
listeners.forEach((l) => l());
|
|
113
|
-
}
|
|
114
|
-
const globals = GLOBAL_LISTENERS.get(target);
|
|
115
|
-
if (globals) {
|
|
116
|
-
globals.forEach((cb) => cb(target, prop, value));
|
|
117
|
-
}
|
|
118
|
-
return result;
|
|
119
|
-
},
|
|
120
|
-
deleteProperty(target, prop) {
|
|
121
|
-
const result = Reflect.deleteProperty(target, prop);
|
|
122
|
-
const listeners = LISTENERS.get(target);
|
|
123
|
-
if (listeners) {
|
|
124
|
-
listeners.forEach((l) => l());
|
|
125
|
-
}
|
|
126
|
-
return result;
|
|
127
|
-
}
|
|
128
|
-
};
|
|
129
|
-
function createState(initialState) {
|
|
130
|
-
if (PROXIES.has(initialState)) {
|
|
131
|
-
return PROXIES.get(initialState);
|
|
132
|
-
}
|
|
133
|
-
const proxy = new Proxy(initialState, handler);
|
|
134
|
-
PROXIES.set(initialState, proxy);
|
|
135
|
-
PROXY_TO_TARGET.set(proxy, initialState);
|
|
136
|
-
return proxy;
|
|
60
|
+
function untracked(fn) {
|
|
61
|
+
return preactUntracked(fn);
|
|
137
62
|
}
|
|
138
63
|
|
|
139
|
-
// src/
|
|
140
|
-
function
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
64
|
+
// src/store/model.ts
|
|
65
|
+
function atom(initialValue, options) {
|
|
66
|
+
const s = createSignal(initialValue);
|
|
67
|
+
if (options?.key) {
|
|
68
|
+
setupPersistence(s, options);
|
|
69
|
+
}
|
|
70
|
+
return s;
|
|
146
71
|
}
|
|
147
|
-
function
|
|
148
|
-
const
|
|
149
|
-
if (
|
|
150
|
-
|
|
151
|
-
|
|
72
|
+
function setupPersistence(s, options) {
|
|
73
|
+
const { key, storage = "local", debug } = options;
|
|
74
|
+
if (!key) return;
|
|
75
|
+
let engine = null;
|
|
76
|
+
if (typeof storage === "string") {
|
|
77
|
+
if (typeof window !== "undefined") {
|
|
78
|
+
engine = storage === "local" ? window.localStorage : window.sessionStorage;
|
|
152
79
|
}
|
|
80
|
+
} else {
|
|
81
|
+
engine = storage;
|
|
153
82
|
}
|
|
154
|
-
if (
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
83
|
+
if (!engine) return;
|
|
84
|
+
try {
|
|
85
|
+
const stored = engine.getItem(key);
|
|
86
|
+
const applyValue = (val) => {
|
|
87
|
+
try {
|
|
88
|
+
const parsed = JSON.parse(val);
|
|
89
|
+
const validated = options.validate ? options.validate(parsed) : parsed;
|
|
90
|
+
s.set(validated);
|
|
91
|
+
if (debug) console.log(`[Quantum] Hydrated atom '${key}'`);
|
|
92
|
+
} catch (e) {
|
|
93
|
+
if (debug) console.error(`[Quantum] Hydration validation failed for '${key}'`, e);
|
|
164
94
|
}
|
|
95
|
+
};
|
|
96
|
+
if (stored instanceof Promise) {
|
|
97
|
+
stored.then((val) => {
|
|
98
|
+
if (val) applyValue(val);
|
|
99
|
+
});
|
|
100
|
+
} else if (stored) {
|
|
101
|
+
applyValue(stored);
|
|
165
102
|
}
|
|
103
|
+
} catch (err) {
|
|
104
|
+
if (debug) console.error(`[Quantum] Hydration error`, err);
|
|
166
105
|
}
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
}
|
|
175
|
-
} else {
|
|
176
|
-
engine = storage;
|
|
177
|
-
}
|
|
178
|
-
if (engine) {
|
|
179
|
-
const hydrate = () => {
|
|
180
|
-
const process = (stored) => {
|
|
181
|
-
try {
|
|
182
|
-
if (stored) {
|
|
183
|
-
const parsed = JSON.parse(stored);
|
|
184
|
-
Object.assign(proxy, parsed);
|
|
185
|
-
if (debug) console.log(`[Quantum] Hydrated '${key}'`, parsed);
|
|
186
|
-
}
|
|
187
|
-
} catch (err) {
|
|
188
|
-
if (debug) console.error(`[Quantum] Hydration Failed for '${key}'`, err);
|
|
189
|
-
}
|
|
190
|
-
};
|
|
191
|
-
try {
|
|
192
|
-
const result = engine.getItem(key);
|
|
193
|
-
if (result instanceof Promise) {
|
|
194
|
-
result.then(process);
|
|
195
|
-
} else {
|
|
196
|
-
process(result);
|
|
197
|
-
}
|
|
198
|
-
} catch (err) {
|
|
199
|
-
if (debug) console.error(`[Quantum] Storage Access Failed`, err);
|
|
200
|
-
}
|
|
201
|
-
};
|
|
202
|
-
hydrate();
|
|
203
|
-
const save = debounce(async () => {
|
|
204
|
-
try {
|
|
205
|
-
let stateToSave;
|
|
206
|
-
if (paths) {
|
|
207
|
-
stateToSave = {};
|
|
208
|
-
for (const p of paths) {
|
|
209
|
-
stateToSave[p] = proxy[p];
|
|
210
|
-
}
|
|
211
|
-
} else {
|
|
212
|
-
stateToSave = {};
|
|
213
|
-
const keys = Object.keys(def.state);
|
|
214
|
-
for (const k of keys) {
|
|
215
|
-
stateToSave[k] = proxy[k];
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
const serialized = JSON.stringify(stateToSave);
|
|
219
|
-
await engine.setItem(key, serialized);
|
|
220
|
-
if (debug) console.log(`[Quantum] Saved '${key}'`);
|
|
221
|
-
} catch (err) {
|
|
222
|
-
}
|
|
223
|
-
}, 100);
|
|
224
|
-
subscribe(proxy, () => {
|
|
225
|
-
save();
|
|
226
|
-
});
|
|
106
|
+
s.subscribe((value) => {
|
|
107
|
+
try {
|
|
108
|
+
const serialized = JSON.stringify(value);
|
|
109
|
+
engine.setItem(key, serialized);
|
|
110
|
+
if (debug) console.log(`[Quantum] Saved atom '${key}'`);
|
|
111
|
+
} catch (err) {
|
|
112
|
+
if (debug) console.error(`[Quantum] Save error`, err);
|
|
227
113
|
}
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// src/react/SignalValue.tsx
|
|
118
|
+
import { useEffect, useState } from "react";
|
|
119
|
+
import { Fragment, jsx } from "react/jsx-runtime";
|
|
120
|
+
function SignalValue({ signal: signal2, render, children }) {
|
|
121
|
+
const [value, setValue] = useState(() => signal2.get());
|
|
122
|
+
useEffect(() => {
|
|
123
|
+
const unsubscribe = signal2.subscribe((newValue) => {
|
|
124
|
+
setValue(newValue);
|
|
125
|
+
});
|
|
126
|
+
return () => unsubscribe();
|
|
127
|
+
}, [signal2]);
|
|
128
|
+
const renderer = render || children;
|
|
129
|
+
if (!renderer) return null;
|
|
130
|
+
return /* @__PURE__ */ jsx(Fragment, { children: renderer(value) });
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// src/store/scheduler.ts
|
|
134
|
+
var pending = /* @__PURE__ */ new Set();
|
|
135
|
+
var timer = null;
|
|
136
|
+
function flush() {
|
|
137
|
+
timer = null;
|
|
138
|
+
const tasks = [...pending];
|
|
139
|
+
pending.clear();
|
|
140
|
+
tasks.forEach((task) => task());
|
|
141
|
+
}
|
|
142
|
+
function scheduleUpdate(callback) {
|
|
143
|
+
pending.add(callback);
|
|
144
|
+
if (!timer) {
|
|
145
|
+
timer = Promise.resolve().then(flush);
|
|
228
146
|
}
|
|
229
|
-
return proxy;
|
|
230
147
|
}
|
|
231
148
|
|
|
232
|
-
// src/
|
|
233
|
-
|
|
234
|
-
function
|
|
235
|
-
const
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
if (notifyRef.current) {
|
|
240
|
-
notifyRef.current();
|
|
241
|
-
}
|
|
242
|
-
}, []);
|
|
243
|
-
const subscribe2 = useCallback((onStoreChange) => {
|
|
244
|
-
notifyRef.current = onStoreChange;
|
|
245
|
-
return () => {
|
|
246
|
-
notifyRef.current = void 0;
|
|
247
|
-
};
|
|
248
|
-
}, []);
|
|
249
|
-
const getSnapshot = useCallback(() => versionRef.current, []);
|
|
250
|
-
useSyncExternalStore(subscribe2, getSnapshot, getSnapshot);
|
|
251
|
-
const proxy = new Proxy(store, {
|
|
252
|
-
get(target, prop, receiver) {
|
|
253
|
-
const prev = getActiveListener();
|
|
254
|
-
setActiveListener(listener);
|
|
255
|
-
try {
|
|
256
|
-
return Reflect.get(target, prop, receiver);
|
|
257
|
-
} finally {
|
|
258
|
-
setActiveListener(prev);
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
});
|
|
262
|
-
return proxy;
|
|
149
|
+
// src/devtools/registry.ts
|
|
150
|
+
var stores = createSignal([]);
|
|
151
|
+
function registerStore(store, name = "Store") {
|
|
152
|
+
const current = stores.get();
|
|
153
|
+
if (!current.find((s) => s.store === store)) {
|
|
154
|
+
stores.set([...current, { name, store }]);
|
|
155
|
+
}
|
|
263
156
|
}
|
|
264
157
|
|
|
265
158
|
// src/middleware/devtools.ts
|
|
266
159
|
function enableDevTools(store, name = "Store") {
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
devTools.init(store);
|
|
270
|
-
subscribe(store, (target, prop, value) => {
|
|
271
|
-
devTools.send({ type: `SET_${String(prop)}`, payload: value }, store);
|
|
272
|
-
});
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
// src/core/computed.ts
|
|
276
|
-
function computed(fn) {
|
|
277
|
-
let value;
|
|
278
|
-
let dirty = true;
|
|
279
|
-
return {
|
|
280
|
-
get value() {
|
|
281
|
-
if (dirty) {
|
|
282
|
-
value = fn();
|
|
283
|
-
dirty = false;
|
|
284
|
-
}
|
|
285
|
-
return value;
|
|
286
|
-
}
|
|
287
|
-
};
|
|
160
|
+
registerStore(store, name);
|
|
161
|
+
console.warn("DevTools for Signals are WIP");
|
|
288
162
|
}
|
|
289
163
|
|
|
290
|
-
// src/
|
|
164
|
+
// src/clientTypes.ts
|
|
291
165
|
var HttpError = class extends Error {
|
|
292
166
|
constructor(status, message) {
|
|
293
167
|
super(message);
|
|
@@ -296,7 +170,7 @@ var HttpError = class extends Error {
|
|
|
296
170
|
}
|
|
297
171
|
};
|
|
298
172
|
|
|
299
|
-
// src/
|
|
173
|
+
// src/middleware/types.ts
|
|
300
174
|
function compose(middleware) {
|
|
301
175
|
return (ctx, next) => {
|
|
302
176
|
let index = -1;
|
|
@@ -315,7 +189,7 @@ function compose(middleware) {
|
|
|
315
189
|
};
|
|
316
190
|
}
|
|
317
191
|
|
|
318
|
-
// src/
|
|
192
|
+
// src/middleware/dedupe.ts
|
|
319
193
|
var DedupeMiddleware = async (ctx, next) => {
|
|
320
194
|
if (ctx.req.method !== "GET") {
|
|
321
195
|
return next(ctx);
|
|
@@ -341,10 +215,10 @@ var DedupeMiddleware = async (ctx, next) => {
|
|
|
341
215
|
}
|
|
342
216
|
};
|
|
343
217
|
|
|
344
|
-
// src/
|
|
218
|
+
// src/middleware/cache.ts
|
|
345
219
|
var CacheMiddleware = async (ctx, next) => {
|
|
346
220
|
const { method, url } = ctx.req;
|
|
347
|
-
const
|
|
221
|
+
const cacheConfig = typeof ctx.config.cache === "object" ? ctx.config.cache : void 0;
|
|
348
222
|
if (method !== "GET" || !cacheConfig?.ttl || cacheConfig.force) {
|
|
349
223
|
return next(ctx);
|
|
350
224
|
}
|
|
@@ -377,7 +251,7 @@ var CacheMiddleware = async (ctx, next) => {
|
|
|
377
251
|
return response;
|
|
378
252
|
};
|
|
379
253
|
|
|
380
|
-
// src/
|
|
254
|
+
// src/middleware/auth.ts
|
|
381
255
|
var AuthMiddleware = async (ctx, next) => {
|
|
382
256
|
const { auth } = ctx.client.config;
|
|
383
257
|
if (auth && auth.getToken && !ctx.req.headers.get("Authorization")) {
|
|
@@ -422,15 +296,21 @@ var AuthMiddleware = async (ctx, next) => {
|
|
|
422
296
|
return response;
|
|
423
297
|
};
|
|
424
298
|
|
|
425
|
-
// src/
|
|
299
|
+
// src/middleware/fetch.ts
|
|
426
300
|
var FetchMiddleware = async (ctx) => {
|
|
427
301
|
return fetch(ctx.req);
|
|
428
302
|
};
|
|
429
303
|
var delay = (ms) => new Promise((res) => setTimeout(res, ms));
|
|
430
304
|
var RetryMiddleware = async (ctx, next) => {
|
|
431
|
-
const
|
|
432
|
-
if (!
|
|
433
|
-
|
|
305
|
+
const retryConfigRaw = ctx.config.retry;
|
|
306
|
+
if (!retryConfigRaw) return next(ctx);
|
|
307
|
+
let config;
|
|
308
|
+
if (typeof retryConfigRaw === "number") {
|
|
309
|
+
config = { retries: retryConfigRaw };
|
|
310
|
+
} else {
|
|
311
|
+
config = retryConfigRaw;
|
|
312
|
+
}
|
|
313
|
+
const { retries = 0, baseDelay = 1e3, maxDelay = 3e3 } = config;
|
|
434
314
|
const attempt = async (count) => {
|
|
435
315
|
try {
|
|
436
316
|
const response = await next(ctx);
|
|
@@ -443,7 +323,7 @@ var RetryMiddleware = async (ctx, next) => {
|
|
|
443
323
|
return response;
|
|
444
324
|
} catch (err) {
|
|
445
325
|
if (count < retries) {
|
|
446
|
-
if (err.name === "AbortError") throw err;
|
|
326
|
+
if (err instanceof Error && err.name === "AbortError") throw err;
|
|
447
327
|
const d = Math.min(baseDelay * 2 ** count, maxDelay);
|
|
448
328
|
await delay(d);
|
|
449
329
|
return attempt(count + 1);
|
|
@@ -454,7 +334,7 @@ var RetryMiddleware = async (ctx, next) => {
|
|
|
454
334
|
return attempt(0);
|
|
455
335
|
};
|
|
456
336
|
|
|
457
|
-
// src/
|
|
337
|
+
// src/httpClient.ts
|
|
458
338
|
function createHttpClient(config) {
|
|
459
339
|
const cache = /* @__PURE__ */ new Map();
|
|
460
340
|
const inflight = /* @__PURE__ */ new Map();
|
|
@@ -489,15 +369,17 @@ function createHttpClient(config) {
|
|
|
489
369
|
controller.abort();
|
|
490
370
|
});
|
|
491
371
|
}
|
|
372
|
+
const { cache: _c, schema: _s, timeout: _t, retry: _r, ...fetchOptions } = options;
|
|
492
373
|
let req = new Request(url, {
|
|
493
|
-
...
|
|
374
|
+
...fetchOptions,
|
|
494
375
|
headers,
|
|
495
376
|
signal: controller.signal
|
|
496
377
|
});
|
|
497
378
|
if (config.interceptors?.request) {
|
|
498
379
|
const newConfig = await config.interceptors.request({ ...options, headers: Object.fromEntries(headers) });
|
|
380
|
+
const { cache: _nc, schema: _ns, timeout: _nt, retry: _nr, ...newFetchOptions } = newConfig;
|
|
499
381
|
req = new Request(url, {
|
|
500
|
-
...
|
|
382
|
+
...newFetchOptions,
|
|
501
383
|
signal: controller.signal
|
|
502
384
|
});
|
|
503
385
|
}
|
|
@@ -538,8 +420,9 @@ function createHttpClient(config) {
|
|
|
538
420
|
if (options.schema.parse) return options.schema.parse(data);
|
|
539
421
|
if (options.schema.validateSync) return options.schema.validateSync(data);
|
|
540
422
|
} catch (error) {
|
|
541
|
-
|
|
542
|
-
|
|
423
|
+
const err = error;
|
|
424
|
+
if (err.errors || err.name === "ZodError" || err.name === "ValidationError") {
|
|
425
|
+
throw new Error(`Validation Error: ${JSON.stringify(err.errors || err.message)}`);
|
|
543
426
|
}
|
|
544
427
|
throw error;
|
|
545
428
|
}
|
|
@@ -569,345 +452,783 @@ function createHttpClient(config) {
|
|
|
569
452
|
return client;
|
|
570
453
|
}
|
|
571
454
|
|
|
572
|
-
// src/
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
455
|
+
// src/store/asyncUtils.ts
|
|
456
|
+
var PROMISE_CACHE = /* @__PURE__ */ new WeakMap();
|
|
457
|
+
var PROMISE_STATUS = /* @__PURE__ */ new WeakMap();
|
|
458
|
+
var PROMISE_ERROR = /* @__PURE__ */ new WeakMap();
|
|
459
|
+
function isPromise(value) {
|
|
460
|
+
return !!value && typeof value.then === "function";
|
|
461
|
+
}
|
|
462
|
+
function handlePromise(promise, triggerUpdate) {
|
|
463
|
+
if (PROMISE_STATUS.has(promise)) return;
|
|
464
|
+
PROMISE_STATUS.set(promise, "pending");
|
|
465
|
+
promise.then(
|
|
466
|
+
(value) => {
|
|
467
|
+
PROMISE_STATUS.set(promise, "fulfilled");
|
|
468
|
+
PROMISE_CACHE.set(promise, value);
|
|
469
|
+
triggerUpdate();
|
|
470
|
+
},
|
|
471
|
+
(error) => {
|
|
472
|
+
PROMISE_STATUS.set(promise, "rejected");
|
|
473
|
+
PROMISE_ERROR.set(promise, error);
|
|
474
|
+
triggerUpdate();
|
|
475
|
+
}
|
|
476
|
+
);
|
|
477
|
+
}
|
|
478
|
+
function unwrapPromise(promise) {
|
|
479
|
+
const status = PROMISE_STATUS.get(promise);
|
|
480
|
+
if (status === "fulfilled") {
|
|
481
|
+
return PROMISE_CACHE.get(promise);
|
|
482
|
+
} else if (status === "rejected") {
|
|
483
|
+
throw PROMISE_ERROR.get(promise);
|
|
484
|
+
} else {
|
|
485
|
+
throw promise;
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
function getPromiseState(promise) {
|
|
489
|
+
return {
|
|
490
|
+
status: PROMISE_STATUS.get(promise) || "pending",
|
|
491
|
+
value: PROMISE_CACHE.get(promise),
|
|
492
|
+
error: PROMISE_ERROR.get(promise)
|
|
493
|
+
};
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
// src/query/utils.ts
|
|
497
|
+
function stableHash(value, depth = 0) {
|
|
498
|
+
if (depth > 15) {
|
|
499
|
+
throw new Error("[Quantum] Query key is too deeply nested. Max depth is 15.");
|
|
500
|
+
}
|
|
501
|
+
if (value === null) return "null";
|
|
502
|
+
if (value === void 0) return "undefined";
|
|
503
|
+
if (typeof value !== "object") {
|
|
504
|
+
const strValue = String(value);
|
|
505
|
+
if (strValue.length > 1e3) {
|
|
506
|
+
return `${typeof value}:[large-string:${strValue.slice(0, 10)}...]`;
|
|
507
|
+
}
|
|
508
|
+
return `${typeof value}:${strValue}`;
|
|
576
509
|
}
|
|
577
510
|
if (Array.isArray(value)) {
|
|
578
|
-
return
|
|
511
|
+
return `array:[${value.map((v) => stableHash(v, depth + 1)).join(",")}]`;
|
|
579
512
|
}
|
|
580
513
|
const keys = Object.keys(value).sort();
|
|
581
|
-
return
|
|
514
|
+
return `object:{${keys.map((key) => `${key}:${stableHash(value[key], depth + 1)}`).join(",")}}`;
|
|
582
515
|
}
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
get = () => this.value;
|
|
600
|
-
set = (newValue) => {
|
|
601
|
-
if (this.value === newValue) return;
|
|
602
|
-
this.value = newValue;
|
|
603
|
-
pendingSignals.add(this);
|
|
604
|
-
if (!isFlushScheduled) {
|
|
605
|
-
isFlushScheduled = true;
|
|
606
|
-
queueMicrotask(flushPendingSignals);
|
|
516
|
+
function isDeepEqual(a, b) {
|
|
517
|
+
if (a === b) return true;
|
|
518
|
+
if (a && b && typeof a === "object" && typeof b === "object") {
|
|
519
|
+
const objA = a;
|
|
520
|
+
const objB = b;
|
|
521
|
+
if (objA.constructor !== objB.constructor) return false;
|
|
522
|
+
let length, i, keys;
|
|
523
|
+
if (Array.isArray(a)) {
|
|
524
|
+
const arrA = a;
|
|
525
|
+
const arrB = b;
|
|
526
|
+
length = arrA.length;
|
|
527
|
+
if (length !== arrB.length) return false;
|
|
528
|
+
for (i = length; i-- !== 0; ) {
|
|
529
|
+
if (!isDeepEqual(arrA[i], arrB[i])) return false;
|
|
530
|
+
}
|
|
531
|
+
return true;
|
|
607
532
|
}
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
533
|
+
if (objA.valueOf !== Object.prototype.valueOf) return objA.valueOf() === objB.valueOf();
|
|
534
|
+
if (objA.toString !== Object.prototype.toString) return objA.toString() === objB.toString();
|
|
535
|
+
keys = Object.keys(objA);
|
|
536
|
+
length = keys.length;
|
|
537
|
+
if (length !== Object.keys(objB).length) return false;
|
|
538
|
+
for (const key of keys) {
|
|
539
|
+
if (!Object.prototype.hasOwnProperty.call(objB, key)) return false;
|
|
540
|
+
}
|
|
541
|
+
for (const key of keys) {
|
|
542
|
+
if (!isDeepEqual(objA[key], objB[key])) return false;
|
|
543
|
+
}
|
|
544
|
+
return true;
|
|
612
545
|
}
|
|
613
|
-
|
|
614
|
-
this.subscribers.add(fn);
|
|
615
|
-
return () => {
|
|
616
|
-
this.subscribers.delete(fn);
|
|
617
|
-
};
|
|
618
|
-
};
|
|
619
|
-
};
|
|
620
|
-
function createSignal(initialValue) {
|
|
621
|
-
return new SignalImpl(initialValue);
|
|
546
|
+
return a !== a && b !== b;
|
|
622
547
|
}
|
|
623
548
|
|
|
624
|
-
// src/
|
|
625
|
-
var
|
|
626
|
-
//
|
|
549
|
+
// src/query/queryStorage.ts
|
|
550
|
+
var QueryStorage = class {
|
|
551
|
+
// Tracks access order (least to most recent)
|
|
552
|
+
// Default configuration
|
|
553
|
+
constructor(defaultStaleTime = 0, defaultCacheTime = 5 * 60 * 1e3, maxSize = 100) {
|
|
554
|
+
this.defaultStaleTime = defaultStaleTime;
|
|
555
|
+
this.defaultCacheTime = defaultCacheTime;
|
|
556
|
+
this.maxSize = maxSize;
|
|
557
|
+
}
|
|
627
558
|
signals = /* @__PURE__ */ new Map();
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
constructor(config) {
|
|
634
|
-
if (config?.enableGC !== false) {
|
|
635
|
-
this.startGarbageCollection();
|
|
636
|
-
}
|
|
559
|
+
gcTimers = /* @__PURE__ */ new Map();
|
|
560
|
+
lruOrder = /* @__PURE__ */ new Set();
|
|
561
|
+
generateKey(queryKey) {
|
|
562
|
+
const key = Array.isArray(queryKey) ? stableHash(queryKey) : stableHash([queryKey.key, queryKey.params]);
|
|
563
|
+
return key;
|
|
637
564
|
}
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
if (Array.isArray(queryKey)) {
|
|
643
|
-
return stableHash(queryKey);
|
|
565
|
+
get(key, autoCreate = true) {
|
|
566
|
+
let signal2 = this.signals.get(key);
|
|
567
|
+
if (signal2) {
|
|
568
|
+
this.touch(key);
|
|
644
569
|
}
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
570
|
+
if (!signal2 && autoCreate) {
|
|
571
|
+
const newSignal = createSignal(void 0, {
|
|
572
|
+
onActive: () => {
|
|
573
|
+
this.cancelGC(key);
|
|
574
|
+
},
|
|
575
|
+
onInactive: () => {
|
|
576
|
+
const currentEntry = this.signals.get(key)?.get();
|
|
577
|
+
const cacheTime = currentEntry?.cacheTime ?? this.defaultCacheTime;
|
|
578
|
+
this.scheduleGC(key, cacheTime);
|
|
579
|
+
}
|
|
580
|
+
});
|
|
581
|
+
this.signals.set(key, newSignal);
|
|
582
|
+
this.touch(key);
|
|
583
|
+
if (!newSignal.isWatched()) {
|
|
584
|
+
this.scheduleGC(key, this.defaultCacheTime);
|
|
585
|
+
}
|
|
586
|
+
this.enforceMaxSize();
|
|
587
|
+
signal2 = newSignal;
|
|
661
588
|
}
|
|
662
|
-
return
|
|
663
|
-
}
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
589
|
+
return signal2;
|
|
590
|
+
}
|
|
591
|
+
tagIndex = /* @__PURE__ */ new Map();
|
|
592
|
+
set(key, entry) {
|
|
593
|
+
this.touch(key);
|
|
594
|
+
const oldEntry = this.signals.get(key)?.get();
|
|
595
|
+
if (oldEntry?.tags) {
|
|
596
|
+
for (const tag of oldEntry.tags) {
|
|
597
|
+
const set = this.tagIndex.get(tag);
|
|
598
|
+
if (set) {
|
|
599
|
+
set.delete(key);
|
|
600
|
+
if (set.size === 0) this.tagIndex.delete(tag);
|
|
601
|
+
}
|
|
602
|
+
}
|
|
674
603
|
}
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
const signal = this.signals.get(key);
|
|
683
|
-
if (!signal) return true;
|
|
684
|
-
const entry = signal.get();
|
|
685
|
-
if (!entry) return true;
|
|
686
|
-
const now = Date.now();
|
|
687
|
-
const age = now - entry.timestamp;
|
|
688
|
-
return age > entry.staleTime;
|
|
689
|
-
};
|
|
690
|
-
/**
|
|
691
|
-
* Set cached data (updates signal)
|
|
692
|
-
*/
|
|
693
|
-
set = (queryKey, data, options) => {
|
|
694
|
-
const key = this.generateKey(queryKey);
|
|
695
|
-
const entry = {
|
|
696
|
-
data,
|
|
697
|
-
timestamp: Date.now(),
|
|
698
|
-
staleTime: options?.staleTime !== void 0 ? options.staleTime : this.defaultStaleTime,
|
|
699
|
-
cacheTime: options?.cacheTime !== void 0 ? options.cacheTime : this.defaultCacheTime,
|
|
700
|
-
key: Array.isArray(queryKey) ? queryKey : [queryKey]
|
|
701
|
-
};
|
|
702
|
-
const existingSignal = this.signals.get(key);
|
|
703
|
-
if (existingSignal) {
|
|
704
|
-
existingSignal.set(entry);
|
|
705
|
-
} else {
|
|
706
|
-
this.signals.set(key, createSignal(entry));
|
|
604
|
+
if (entry.tags) {
|
|
605
|
+
for (const tag of entry.tags) {
|
|
606
|
+
if (!this.tagIndex.has(tag)) {
|
|
607
|
+
this.tagIndex.set(tag, /* @__PURE__ */ new Set());
|
|
608
|
+
}
|
|
609
|
+
this.tagIndex.get(tag).add(key);
|
|
610
|
+
}
|
|
707
611
|
}
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
const key = this.generateKey(queryKey);
|
|
728
|
-
const normalizedKey = Array.isArray(queryKey) ? queryKey : [queryKey.key, queryKey.params];
|
|
729
|
-
if (this.deduplicationCache.has(key)) {
|
|
730
|
-
return this.deduplicationCache.get(key);
|
|
612
|
+
let signal2 = this.signals.get(key);
|
|
613
|
+
if (signal2) {
|
|
614
|
+
signal2.set(entry);
|
|
615
|
+
} else {
|
|
616
|
+
const newSignal = createSignal(entry, {
|
|
617
|
+
onActive: () => {
|
|
618
|
+
this.cancelGC(key);
|
|
619
|
+
},
|
|
620
|
+
onInactive: () => {
|
|
621
|
+
const entry2 = this.signals.get(key)?.get();
|
|
622
|
+
const cacheTime = entry2?.cacheTime ?? this.defaultCacheTime;
|
|
623
|
+
this.scheduleGC(key, cacheTime);
|
|
624
|
+
}
|
|
625
|
+
});
|
|
626
|
+
this.signals.set(key, newSignal);
|
|
627
|
+
if (!newSignal.isWatched()) {
|
|
628
|
+
this.scheduleGC(key, entry.cacheTime ?? this.defaultCacheTime);
|
|
629
|
+
}
|
|
630
|
+
this.enforceMaxSize();
|
|
731
631
|
}
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
throw error;
|
|
632
|
+
}
|
|
633
|
+
delete(key) {
|
|
634
|
+
const entry = this.signals.get(key)?.get();
|
|
635
|
+
if (entry?.tags) {
|
|
636
|
+
for (const tag of entry.tags) {
|
|
637
|
+
const set = this.tagIndex.get(tag);
|
|
638
|
+
if (set) {
|
|
639
|
+
set.delete(key);
|
|
640
|
+
if (set.size === 0) this.tagIndex.delete(tag);
|
|
641
|
+
}
|
|
743
642
|
}
|
|
744
|
-
|
|
745
|
-
this.
|
|
746
|
-
|
|
643
|
+
}
|
|
644
|
+
this.signals.delete(key);
|
|
645
|
+
this.lruOrder.delete(key);
|
|
646
|
+
this.cancelGC(key);
|
|
647
|
+
}
|
|
648
|
+
touch(key) {
|
|
649
|
+
this.lruOrder.delete(key);
|
|
650
|
+
this.lruOrder.add(key);
|
|
651
|
+
}
|
|
652
|
+
enforceMaxSize() {
|
|
653
|
+
if (this.signals.size <= this.maxSize) return;
|
|
654
|
+
for (const key of this.lruOrder) {
|
|
655
|
+
const signal2 = this.signals.get(key);
|
|
656
|
+
if (signal2 && !signal2.isWatched()) {
|
|
657
|
+
this.delete(key);
|
|
658
|
+
if (this.signals.size <= this.maxSize) break;
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
getKeysByTag(tag) {
|
|
663
|
+
return this.tagIndex.get(tag);
|
|
664
|
+
}
|
|
665
|
+
clear() {
|
|
666
|
+
this.signals.clear();
|
|
667
|
+
this.tagIndex.clear();
|
|
668
|
+
this.lruOrder.clear();
|
|
669
|
+
this.gcTimers.forEach((timer2) => clearTimeout(timer2));
|
|
670
|
+
this.gcTimers.clear();
|
|
671
|
+
}
|
|
672
|
+
getAll() {
|
|
673
|
+
const map = /* @__PURE__ */ new Map();
|
|
674
|
+
for (const [key, signal2] of this.signals.entries()) {
|
|
675
|
+
const val = signal2.get();
|
|
676
|
+
if (val) map.set(key, val);
|
|
677
|
+
}
|
|
678
|
+
return map;
|
|
679
|
+
}
|
|
680
|
+
getStats() {
|
|
681
|
+
return {
|
|
682
|
+
size: this.signals.size,
|
|
683
|
+
keys: Array.from(this.signals.keys()),
|
|
684
|
+
tags: this.tagIndex.size
|
|
685
|
+
};
|
|
686
|
+
}
|
|
687
|
+
getSnapshot() {
|
|
688
|
+
const snapshot = /* @__PURE__ */ new Map();
|
|
689
|
+
for (const [key, signal2] of this.signals.entries()) {
|
|
690
|
+
const value = signal2.get();
|
|
691
|
+
if (value) {
|
|
692
|
+
snapshot.set(key, value);
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
return snapshot;
|
|
696
|
+
}
|
|
697
|
+
// --- GC Logic ---
|
|
698
|
+
scheduleGC(key, delay2) {
|
|
699
|
+
if (this.gcTimers.has(key)) {
|
|
700
|
+
clearTimeout(this.gcTimers.get(key));
|
|
701
|
+
}
|
|
702
|
+
const timer2 = setTimeout(() => {
|
|
703
|
+
this.delete(key);
|
|
704
|
+
}, delay2);
|
|
705
|
+
this.gcTimers.set(key, timer2);
|
|
706
|
+
}
|
|
707
|
+
cancelGC(key) {
|
|
708
|
+
if (this.gcTimers.has(key)) {
|
|
709
|
+
clearTimeout(this.gcTimers.get(key));
|
|
710
|
+
this.gcTimers.delete(key);
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
};
|
|
714
|
+
|
|
715
|
+
// src/query/remotes.ts
|
|
716
|
+
var QueryRemotes = class {
|
|
717
|
+
deduplicationCache = /* @__PURE__ */ new Map();
|
|
718
|
+
async fetch(key, fn, options) {
|
|
719
|
+
if (this.deduplicationCache.has(key)) {
|
|
720
|
+
return this.deduplicationCache.get(key);
|
|
721
|
+
}
|
|
722
|
+
const promise = this.executeWithRetry(fn, options);
|
|
723
|
+
this.deduplicationCache.set(key, promise);
|
|
724
|
+
try {
|
|
725
|
+
const result = await promise;
|
|
726
|
+
this.deduplicationCache.delete(key);
|
|
727
|
+
return result;
|
|
728
|
+
} catch (error) {
|
|
729
|
+
this.deduplicationCache.delete(key);
|
|
730
|
+
throw error;
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
async executeWithRetry(fn, options) {
|
|
734
|
+
const maxRetries = this.resolveRetry(options?.retry);
|
|
735
|
+
let attempt = 0;
|
|
736
|
+
while (true) {
|
|
737
|
+
attempt++;
|
|
738
|
+
try {
|
|
739
|
+
return await fn({ signal: options?.signal });
|
|
740
|
+
} catch (error) {
|
|
741
|
+
if (attempt > maxRetries || options?.signal && options.signal.aborted) {
|
|
742
|
+
throw error;
|
|
743
|
+
}
|
|
744
|
+
let delay2 = 1e3 * 2 ** (attempt - 1);
|
|
745
|
+
if (options?.retryDelay) {
|
|
746
|
+
delay2 = typeof options.retryDelay === "number" ? options.retryDelay : options.retryDelay(attempt - 1);
|
|
747
|
+
}
|
|
748
|
+
delay2 = Math.min(delay2, 3e4);
|
|
749
|
+
await this.wait(delay2, options?.signal);
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
resolveRetry(retry) {
|
|
754
|
+
if (typeof retry === "number") return retry;
|
|
755
|
+
if (retry === false) return 0;
|
|
756
|
+
return 3;
|
|
757
|
+
}
|
|
758
|
+
wait(ms, signal2) {
|
|
759
|
+
return new Promise((resolve, reject) => {
|
|
760
|
+
if (signal2?.aborted) return reject(new Error("Aborted"));
|
|
761
|
+
const timer2 = setTimeout(() => {
|
|
762
|
+
cleanup();
|
|
763
|
+
resolve();
|
|
764
|
+
}, ms);
|
|
765
|
+
const onAbort = () => {
|
|
766
|
+
cleanup();
|
|
767
|
+
reject(new Error("Aborted"));
|
|
768
|
+
};
|
|
769
|
+
const cleanup = () => {
|
|
770
|
+
clearTimeout(timer2);
|
|
771
|
+
signal2?.removeEventListener("abort", onAbort);
|
|
772
|
+
};
|
|
773
|
+
signal2?.addEventListener("abort", onAbort);
|
|
774
|
+
});
|
|
775
|
+
}
|
|
776
|
+
};
|
|
777
|
+
|
|
778
|
+
// src/query/mutationCache.ts
|
|
779
|
+
var MutationCache = class {
|
|
780
|
+
// Map<ID, Signal> - Stores state for every unique mutation execution
|
|
781
|
+
mutations = /* @__PURE__ */ new Map();
|
|
782
|
+
// Map<KeyHash, Set<ID>> - Index to find mutations by key
|
|
783
|
+
mutationKeys = /* @__PURE__ */ new Map();
|
|
784
|
+
/**
|
|
785
|
+
* Get or Create a Signal for a specific mutation instance (ID)
|
|
786
|
+
*/
|
|
787
|
+
getSignal = (id) => {
|
|
788
|
+
let signal2 = this.mutations.get(id);
|
|
789
|
+
if (!signal2) {
|
|
790
|
+
const initialState = {
|
|
791
|
+
data: void 0,
|
|
792
|
+
error: null,
|
|
793
|
+
variables: void 0,
|
|
794
|
+
context: void 0,
|
|
795
|
+
status: "idle",
|
|
796
|
+
submittedAt: 0
|
|
797
|
+
};
|
|
798
|
+
signal2 = createSignal(initialState);
|
|
799
|
+
this.mutations.set(id, signal2);
|
|
800
|
+
}
|
|
801
|
+
return signal2;
|
|
747
802
|
};
|
|
748
803
|
/**
|
|
749
|
-
*
|
|
804
|
+
* Register a mutation ID with a Key (for tracking shared keys)
|
|
750
805
|
*/
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
806
|
+
register = (id, key) => {
|
|
807
|
+
if (!key) return;
|
|
808
|
+
const hash = stableHash(key);
|
|
809
|
+
if (!this.mutationKeys.has(hash)) {
|
|
810
|
+
this.mutationKeys.set(hash, /* @__PURE__ */ new Set());
|
|
754
811
|
}
|
|
812
|
+
this.mutationKeys.get(hash).add(id);
|
|
755
813
|
};
|
|
756
814
|
/**
|
|
757
|
-
*
|
|
815
|
+
* Unregister cleanup
|
|
758
816
|
*/
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
817
|
+
unregister = (id, key) => {
|
|
818
|
+
if (!key) return;
|
|
819
|
+
const hash = stableHash(key);
|
|
820
|
+
const set = this.mutationKeys.get(hash);
|
|
821
|
+
if (set) {
|
|
822
|
+
set.delete(id);
|
|
823
|
+
if (set.size === 0) {
|
|
824
|
+
this.mutationKeys.delete(hash);
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
this.mutations.delete(id);
|
|
828
|
+
};
|
|
829
|
+
notify = (id, state) => {
|
|
830
|
+
const signal2 = this.getSignal(id);
|
|
831
|
+
const current = signal2.get();
|
|
832
|
+
signal2.set({ ...current, ...state });
|
|
762
833
|
};
|
|
763
834
|
/**
|
|
764
|
-
*
|
|
765
|
-
* Marks them as undefined to trigger refetches without breaking subscriptions
|
|
835
|
+
* Get number of mutations currently pending
|
|
766
836
|
*/
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
837
|
+
isMutating = (filters) => {
|
|
838
|
+
let count = 0;
|
|
839
|
+
if (filters?.mutationKey) {
|
|
840
|
+
const hash = stableHash(filters.mutationKey);
|
|
841
|
+
const ids = this.mutationKeys.get(hash);
|
|
842
|
+
if (!ids) return 0;
|
|
843
|
+
for (const id of ids) {
|
|
844
|
+
if (this.mutations.get(id)?.get().status === "pending") {
|
|
845
|
+
count++;
|
|
846
|
+
}
|
|
775
847
|
}
|
|
776
|
-
}
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
if (key.startsWith(prefix.slice(0, -1))) {
|
|
780
|
-
invalidateKey(key);
|
|
848
|
+
} else {
|
|
849
|
+
for (const signal2 of this.mutations.values()) {
|
|
850
|
+
if (signal2.get().status === "pending") count++;
|
|
781
851
|
}
|
|
782
852
|
}
|
|
853
|
+
return count;
|
|
783
854
|
};
|
|
855
|
+
};
|
|
856
|
+
|
|
857
|
+
// src/query/pluginManager.ts
|
|
858
|
+
var PluginManager = class {
|
|
859
|
+
plugins = [];
|
|
860
|
+
client;
|
|
861
|
+
setClient(client) {
|
|
862
|
+
this.client = client;
|
|
863
|
+
}
|
|
864
|
+
add(plugin) {
|
|
865
|
+
this.plugins.push(plugin);
|
|
866
|
+
}
|
|
867
|
+
onFetchStart(queryKey) {
|
|
868
|
+
this.plugins.forEach((p) => p.onFetchStart?.(queryKey));
|
|
869
|
+
}
|
|
870
|
+
onFetchSuccess(queryKey, data) {
|
|
871
|
+
this.plugins.forEach((p) => p.onFetchSuccess?.(queryKey, data));
|
|
872
|
+
}
|
|
873
|
+
onFetchError(queryKey, error) {
|
|
874
|
+
this.plugins.forEach((p) => p.onFetchError?.(queryKey, error));
|
|
875
|
+
}
|
|
876
|
+
onInvalidate(queryKey) {
|
|
877
|
+
this.plugins.forEach((p) => p.onInvalidate?.(queryKey));
|
|
878
|
+
}
|
|
879
|
+
onQueryUpdated(queryKey, data) {
|
|
880
|
+
this.plugins.forEach((p) => p.onQueryUpdated?.(queryKey, data));
|
|
881
|
+
}
|
|
882
|
+
};
|
|
883
|
+
|
|
884
|
+
// src/query/plugins/validation.ts
|
|
885
|
+
function validateWithSchema(data, schema) {
|
|
886
|
+
if (!schema) {
|
|
887
|
+
return data;
|
|
888
|
+
}
|
|
889
|
+
return schema.parse(data);
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
// src/query/queryClient.ts
|
|
893
|
+
var QueryClient = class {
|
|
894
|
+
// Components
|
|
895
|
+
storage;
|
|
896
|
+
remotes;
|
|
897
|
+
// Mutation Cache
|
|
898
|
+
mutationCache = new MutationCache();
|
|
899
|
+
// Plugins
|
|
900
|
+
pluginManager = new PluginManager();
|
|
901
|
+
// Config defaults
|
|
902
|
+
defaultStaleTime;
|
|
903
|
+
defaultCacheTime;
|
|
904
|
+
defaultSchema;
|
|
905
|
+
constructor(config) {
|
|
906
|
+
this.defaultStaleTime = config?.defaultStaleTime ?? 0;
|
|
907
|
+
this.defaultCacheTime = config?.defaultCacheTime ?? 5 * 60 * 1e3;
|
|
908
|
+
this.defaultSchema = config?.defaultSchema;
|
|
909
|
+
this.storage = new QueryStorage(
|
|
910
|
+
this.defaultStaleTime,
|
|
911
|
+
this.defaultCacheTime,
|
|
912
|
+
config?.maxCacheSize
|
|
913
|
+
);
|
|
914
|
+
this.remotes = new QueryRemotes();
|
|
915
|
+
this.pluginManager.setClient(this);
|
|
916
|
+
}
|
|
917
|
+
// --- FACADE API ---
|
|
784
918
|
/**
|
|
785
|
-
*
|
|
919
|
+
* Get data from storage
|
|
786
920
|
*/
|
|
787
|
-
|
|
788
|
-
this.
|
|
921
|
+
get = (queryKey) => {
|
|
922
|
+
const key = this.storage.generateKey(queryKey);
|
|
923
|
+
const signal2 = this.storage.get(key, false);
|
|
924
|
+
if (!signal2) return void 0;
|
|
925
|
+
const entry = signal2.get();
|
|
926
|
+
if (!this.isCacheEntry(entry)) return void 0;
|
|
927
|
+
const now = Date.now();
|
|
928
|
+
const age = now - entry.timestamp;
|
|
929
|
+
if (age > entry.cacheTime) {
|
|
930
|
+
this.storage.delete(key);
|
|
931
|
+
return void 0;
|
|
932
|
+
}
|
|
933
|
+
return entry.data;
|
|
789
934
|
};
|
|
790
935
|
/**
|
|
791
|
-
*
|
|
936
|
+
* Get Signal for reactivity (used by hooks)
|
|
792
937
|
*/
|
|
793
|
-
|
|
794
|
-
this.
|
|
938
|
+
getSignal = (queryKey) => {
|
|
939
|
+
const key = this.storage.generateKey(queryKey);
|
|
940
|
+
return this.storage.get(key, true);
|
|
795
941
|
};
|
|
796
942
|
/**
|
|
797
|
-
*
|
|
943
|
+
* Set data manually (Optimistic updates / Prefetch)
|
|
798
944
|
*/
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
945
|
+
set = (queryKey, data, options) => {
|
|
946
|
+
const key = this.storage.generateKey(queryKey);
|
|
947
|
+
const entry = {
|
|
948
|
+
data,
|
|
949
|
+
status: "success",
|
|
950
|
+
error: null,
|
|
951
|
+
isFetching: false,
|
|
952
|
+
fetchDirection: "idle",
|
|
953
|
+
timestamp: Date.now(),
|
|
954
|
+
staleTime: options?.staleTime ?? this.defaultStaleTime,
|
|
955
|
+
cacheTime: options?.cacheTime ?? this.defaultCacheTime,
|
|
956
|
+
key: queryKey,
|
|
957
|
+
tags: options?.tags
|
|
958
|
+
};
|
|
959
|
+
this.storage.set(key, entry);
|
|
960
|
+
const normalizedKey = this.normalizeKey(queryKey);
|
|
961
|
+
this.pluginManager.onQueryUpdated(normalizedKey, data);
|
|
811
962
|
};
|
|
812
963
|
/**
|
|
813
|
-
*
|
|
964
|
+
* Restore cache entry (Hydration)
|
|
814
965
|
*/
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
this.clear();
|
|
966
|
+
restore = (queryKey, entry) => {
|
|
967
|
+
const key = this.storage.generateKey(queryKey);
|
|
968
|
+
this.storage.set(key, entry);
|
|
969
|
+
const normalizedKey = this.normalizeKey(queryKey);
|
|
970
|
+
this.pluginManager.onQueryUpdated(normalizedKey, entry.data);
|
|
821
971
|
};
|
|
822
972
|
/**
|
|
823
|
-
*
|
|
973
|
+
* Fetch data (Orchestration)
|
|
824
974
|
*/
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
975
|
+
fetch = async (queryKey, fn, options) => {
|
|
976
|
+
const key = this.storage.generateKey(queryKey);
|
|
977
|
+
const normalizedKey = this.normalizeKey(queryKey);
|
|
978
|
+
const direction = options?.fetchDirection || "initial";
|
|
979
|
+
const signal2 = this.storage.get(key, true);
|
|
980
|
+
const currentEntry = signal2.get();
|
|
981
|
+
const mergedTags = options?.tags ?? currentEntry?.tags;
|
|
982
|
+
this.storage.set(key, {
|
|
983
|
+
data: currentEntry?.data,
|
|
984
|
+
status: currentEntry?.status || "pending",
|
|
985
|
+
error: null,
|
|
986
|
+
isFetching: true,
|
|
987
|
+
fetchDirection: direction,
|
|
988
|
+
timestamp: currentEntry?.timestamp || Date.now(),
|
|
989
|
+
staleTime: currentEntry?.staleTime ?? this.defaultStaleTime,
|
|
990
|
+
cacheTime: currentEntry?.cacheTime ?? this.defaultCacheTime,
|
|
991
|
+
key: queryKey,
|
|
992
|
+
tags: mergedTags
|
|
993
|
+
});
|
|
994
|
+
this.pluginManager.onFetchStart(normalizedKey);
|
|
995
|
+
try {
|
|
996
|
+
const data = await this.remotes.fetch(key, fn, {
|
|
997
|
+
signal: options?.signal,
|
|
998
|
+
retry: options?.retry,
|
|
999
|
+
retryDelay: options?.retryDelay
|
|
1000
|
+
});
|
|
1001
|
+
this.storage.set(key, {
|
|
1002
|
+
data,
|
|
1003
|
+
status: "success",
|
|
1004
|
+
error: null,
|
|
1005
|
+
isFetching: false,
|
|
1006
|
+
isInvalidated: void 0,
|
|
1007
|
+
// Clear invalidation on success
|
|
1008
|
+
fetchDirection: "idle",
|
|
1009
|
+
timestamp: Date.now(),
|
|
1010
|
+
staleTime: currentEntry?.staleTime ?? this.defaultStaleTime,
|
|
1011
|
+
cacheTime: currentEntry?.cacheTime ?? this.defaultCacheTime,
|
|
1012
|
+
key: queryKey,
|
|
1013
|
+
tags: mergedTags
|
|
1014
|
+
});
|
|
1015
|
+
const schema = options?.schema || this.defaultSchema;
|
|
1016
|
+
const validatedData = validateWithSchema(data, schema);
|
|
1017
|
+
this.pluginManager.onFetchSuccess(normalizedKey, validatedData);
|
|
1018
|
+
return validatedData;
|
|
1019
|
+
} catch (error) {
|
|
1020
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
1021
|
+
this.storage.set(key, {
|
|
1022
|
+
data: currentEntry?.data,
|
|
1023
|
+
status: "error",
|
|
1024
|
+
error: err,
|
|
1025
|
+
isFetching: false,
|
|
1026
|
+
fetchDirection: "idle",
|
|
1027
|
+
timestamp: currentEntry?.timestamp || Date.now(),
|
|
1028
|
+
staleTime: currentEntry?.staleTime ?? this.defaultStaleTime,
|
|
1029
|
+
cacheTime: currentEntry?.cacheTime ?? this.defaultCacheTime,
|
|
1030
|
+
key: queryKey,
|
|
1031
|
+
tags: mergedTags
|
|
1032
|
+
});
|
|
1033
|
+
this.pluginManager.onFetchError(normalizedKey, err);
|
|
1034
|
+
throw err;
|
|
1035
|
+
}
|
|
830
1036
|
};
|
|
831
1037
|
/**
|
|
832
|
-
*
|
|
1038
|
+
* Invalidate queries
|
|
833
1039
|
*/
|
|
834
|
-
|
|
835
|
-
const
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
1040
|
+
invalidate = (queryKey) => {
|
|
1041
|
+
const prefix = this.storage.generateKey(queryKey);
|
|
1042
|
+
const normalizedKey = this.normalizeKey(queryKey);
|
|
1043
|
+
this.pluginManager.onInvalidate(normalizedKey);
|
|
1044
|
+
const allKeys = this.storage.getSnapshot().keys();
|
|
1045
|
+
for (const key of allKeys) {
|
|
1046
|
+
if (key === prefix || key.startsWith(prefix.slice(0, -1))) {
|
|
1047
|
+
const signal2 = this.storage.get(key, false);
|
|
1048
|
+
if (signal2) {
|
|
1049
|
+
const current = signal2.get();
|
|
1050
|
+
if (current) {
|
|
1051
|
+
signal2.set({ ...current, isInvalidated: true });
|
|
1052
|
+
}
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1055
|
+
}
|
|
1056
|
+
};
|
|
1057
|
+
invalidateTags = (tags) => {
|
|
1058
|
+
const tagsToInvalidate = new Set(tags);
|
|
1059
|
+
for (const tag of tagsToInvalidate) {
|
|
1060
|
+
const keys = this.storage.getKeysByTag(tag);
|
|
1061
|
+
if (keys) {
|
|
1062
|
+
for (const key of keys) {
|
|
1063
|
+
const signal2 = this.storage.get(key, false);
|
|
1064
|
+
if (signal2) {
|
|
1065
|
+
const current = signal2.get();
|
|
1066
|
+
if (current) {
|
|
1067
|
+
signal2.set({ ...current, isInvalidated: true });
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
839
1072
|
}
|
|
840
|
-
|
|
1073
|
+
};
|
|
1074
|
+
// --- Helpers ---
|
|
1075
|
+
use = (plugin) => {
|
|
1076
|
+
this.pluginManager.add(plugin);
|
|
1077
|
+
return this;
|
|
1078
|
+
};
|
|
1079
|
+
isStale = (queryKey) => {
|
|
1080
|
+
const key = this.storage.generateKey(queryKey);
|
|
1081
|
+
const signal2 = this.storage.get(key);
|
|
1082
|
+
const entry = signal2?.get();
|
|
1083
|
+
if (!entry) return true;
|
|
1084
|
+
if (entry.isInvalidated) return true;
|
|
1085
|
+
return Date.now() - entry.timestamp > entry.staleTime;
|
|
1086
|
+
};
|
|
1087
|
+
getAll = () => this.storage.getAll();
|
|
1088
|
+
snapshot = () => this.storage.getSnapshot();
|
|
1089
|
+
clear = () => this.storage.clear();
|
|
1090
|
+
remove = (key) => this.storage.delete(this.storage.generateKey(key));
|
|
1091
|
+
// Restored Methods
|
|
1092
|
+
prefetch = (queryKey, data, options) => {
|
|
1093
|
+
this.set(queryKey, data, options);
|
|
1094
|
+
};
|
|
1095
|
+
destroy = () => {
|
|
1096
|
+
this.storage.clear();
|
|
1097
|
+
};
|
|
1098
|
+
getStats = () => this.storage.getStats();
|
|
1099
|
+
// For Hydration
|
|
1100
|
+
getSnapshot = () => this.storage.getSnapshot();
|
|
1101
|
+
invalidateAll = () => {
|
|
1102
|
+
const snapshot = this.storage.getSnapshot();
|
|
1103
|
+
for (const key of snapshot.keys()) {
|
|
1104
|
+
const signal2 = this.storage.get(key, false);
|
|
1105
|
+
const entry = signal2?.get();
|
|
1106
|
+
if (entry) {
|
|
1107
|
+
signal2?.set({ ...entry, isInvalidated: true });
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
1110
|
+
};
|
|
1111
|
+
normalizeKey(queryKey) {
|
|
1112
|
+
return Array.isArray(queryKey) ? queryKey : [queryKey.key, queryKey.params];
|
|
1113
|
+
}
|
|
1114
|
+
isCacheEntry(entry) {
|
|
1115
|
+
return entry !== null && typeof entry === "object" && "status" in entry && "timestamp" in entry;
|
|
1116
|
+
}
|
|
1117
|
+
// --- DEBUGGER API (For DevTools) ---
|
|
1118
|
+
debugSet = (key, data) => {
|
|
1119
|
+
this.set(key, data);
|
|
1120
|
+
};
|
|
1121
|
+
debugInvalidate = (key) => {
|
|
1122
|
+
this.invalidate(key);
|
|
841
1123
|
};
|
|
842
1124
|
};
|
|
843
|
-
var queryCache = new QueryCache();
|
|
844
1125
|
|
|
845
|
-
// src/
|
|
846
|
-
import { useState, useEffect as useEffect2, useCallback
|
|
1126
|
+
// src/query/pagination.ts
|
|
1127
|
+
import { useState as useState2, useEffect as useEffect2, useCallback, useRef as useRef2, useSyncExternalStore } from "react";
|
|
1128
|
+
|
|
1129
|
+
// src/query/context.tsx
|
|
1130
|
+
import { createContext, useContext } from "react";
|
|
1131
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
1132
|
+
var QueryClientContext = createContext(void 0);
|
|
1133
|
+
var QueryClientProvider = ({
|
|
1134
|
+
client,
|
|
1135
|
+
children
|
|
1136
|
+
}) => {
|
|
1137
|
+
return /* @__PURE__ */ jsx2(QueryClientContext.Provider, { value: client, children: children || null });
|
|
1138
|
+
};
|
|
1139
|
+
var useQueryClient = () => {
|
|
1140
|
+
const client = useContext(QueryClientContext);
|
|
1141
|
+
if (!client) {
|
|
1142
|
+
throw new Error("No QueryClient set, use QueryClientProvider to set one");
|
|
1143
|
+
}
|
|
1144
|
+
return client;
|
|
1145
|
+
};
|
|
1146
|
+
|
|
1147
|
+
// src/query/pagination.ts
|
|
847
1148
|
function usePaginatedQuery({
|
|
848
1149
|
queryKey,
|
|
849
1150
|
queryFn,
|
|
850
1151
|
pageSize = 20,
|
|
851
1152
|
staleTime,
|
|
852
1153
|
cacheTime,
|
|
853
|
-
enabled = true
|
|
1154
|
+
enabled = true,
|
|
1155
|
+
retry
|
|
854
1156
|
}) {
|
|
855
|
-
const
|
|
856
|
-
const [
|
|
857
|
-
const [
|
|
858
|
-
const
|
|
859
|
-
const
|
|
860
|
-
|
|
1157
|
+
const client = useQueryClient();
|
|
1158
|
+
const [page, setPage] = useState2(0);
|
|
1159
|
+
const pageQueryKey = [...queryKey, "page", page];
|
|
1160
|
+
const pageQueryKeyHash = JSON.stringify(pageQueryKey);
|
|
1161
|
+
const subscribe = useCallback((onStoreChange) => {
|
|
1162
|
+
const signal2 = client.getSignal(pageQueryKey);
|
|
1163
|
+
return signal2.subscribe(() => onStoreChange());
|
|
1164
|
+
}, [client, pageQueryKeyHash]);
|
|
1165
|
+
const getSnapshot = useCallback(() => {
|
|
1166
|
+
const signal2 = client.getSignal(pageQueryKey);
|
|
1167
|
+
return signal2.get();
|
|
1168
|
+
}, [client, pageQueryKeyHash]);
|
|
1169
|
+
const cacheEntry = useSyncExternalStore(subscribe, getSnapshot);
|
|
1170
|
+
const data = cacheEntry?.data;
|
|
1171
|
+
const status = cacheEntry?.status || "pending";
|
|
1172
|
+
const error = cacheEntry?.error || null;
|
|
1173
|
+
const isFetching = cacheEntry?.isFetching || false;
|
|
1174
|
+
const dataTimestamp = cacheEntry?.timestamp;
|
|
1175
|
+
const isError = status === "error";
|
|
1176
|
+
const isLoading = data === void 0 && (isFetching || status === "pending");
|
|
1177
|
+
let hasNext = true;
|
|
1178
|
+
if (data) {
|
|
1179
|
+
if (Array.isArray(data)) {
|
|
1180
|
+
hasNext = data.length === pageSize;
|
|
1181
|
+
} else if (typeof data === "object" && "hasMore" in data) {
|
|
1182
|
+
hasNext = !!data.hasMore;
|
|
1183
|
+
}
|
|
1184
|
+
}
|
|
1185
|
+
const hasPrevious = page > 0;
|
|
861
1186
|
const queryFnRef = useRef2(queryFn);
|
|
1187
|
+
const staleTimeRef = useRef2(staleTime);
|
|
1188
|
+
const cacheTimeRef = useRef2(cacheTime);
|
|
862
1189
|
useEffect2(() => {
|
|
863
1190
|
queryFnRef.current = queryFn;
|
|
1191
|
+
staleTimeRef.current = staleTime;
|
|
1192
|
+
cacheTimeRef.current = cacheTime;
|
|
864
1193
|
});
|
|
865
|
-
const
|
|
866
|
-
const fetchPage = useCallback2(async (pageNum) => {
|
|
1194
|
+
const fetchPage = useCallback(async (background = false) => {
|
|
867
1195
|
if (!enabled) return;
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
return;
|
|
1196
|
+
if (!background) {
|
|
1197
|
+
const currentEntry = getSnapshot();
|
|
1198
|
+
if (currentEntry && Date.now() - currentEntry.timestamp <= (staleTimeRef.current || 0)) {
|
|
1199
|
+
return;
|
|
1200
|
+
}
|
|
874
1201
|
}
|
|
875
1202
|
try {
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
setHasNext(result.length === pageSize);
|
|
884
|
-
} else if (result && typeof result === "object" && "hasMore" in result) {
|
|
885
|
-
setHasNext(result.hasMore);
|
|
886
|
-
}
|
|
887
|
-
setIsLoading(false);
|
|
1203
|
+
const result = await client.fetch(pageQueryKey, async () => {
|
|
1204
|
+
return await queryFnRef.current(page);
|
|
1205
|
+
}, { retry });
|
|
1206
|
+
client.set(pageQueryKey, result, {
|
|
1207
|
+
staleTime: staleTimeRef.current,
|
|
1208
|
+
cacheTime: cacheTimeRef.current
|
|
1209
|
+
});
|
|
888
1210
|
} catch (err) {
|
|
889
|
-
setIsError(true);
|
|
890
|
-
setError(err);
|
|
891
|
-
setIsLoading(false);
|
|
892
1211
|
}
|
|
893
|
-
}, [
|
|
1212
|
+
}, [pageQueryKeyHash, enabled, client, getSnapshot, page]);
|
|
894
1213
|
useEffect2(() => {
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
1214
|
+
if (enabled) {
|
|
1215
|
+
fetchPage();
|
|
1216
|
+
}
|
|
1217
|
+
}, [fetchPage, enabled]);
|
|
1218
|
+
const nextPage = useCallback(() => {
|
|
898
1219
|
if (hasNext) {
|
|
899
1220
|
setPage((p) => p + 1);
|
|
900
1221
|
}
|
|
901
1222
|
}, [hasNext]);
|
|
902
|
-
const previousPage =
|
|
1223
|
+
const previousPage = useCallback(() => {
|
|
903
1224
|
if (page > 0) {
|
|
904
1225
|
setPage((p) => p - 1);
|
|
905
1226
|
}
|
|
906
1227
|
}, [page]);
|
|
907
|
-
const refetch =
|
|
908
|
-
|
|
909
|
-
await fetchPage(
|
|
910
|
-
}, [
|
|
1228
|
+
const refetch = useCallback(async () => {
|
|
1229
|
+
client.invalidate(pageQueryKey);
|
|
1230
|
+
await fetchPage();
|
|
1231
|
+
}, [pageQueryKeyHash, fetchPage, client]);
|
|
911
1232
|
return {
|
|
912
1233
|
data,
|
|
913
1234
|
isLoading,
|
|
@@ -918,502 +1239,723 @@ function usePaginatedQuery({
|
|
|
918
1239
|
nextPage,
|
|
919
1240
|
previousPage,
|
|
920
1241
|
hasNext,
|
|
921
|
-
hasPrevious
|
|
1242
|
+
hasPrevious,
|
|
922
1243
|
refetch
|
|
923
1244
|
};
|
|
924
1245
|
}
|
|
925
1246
|
|
|
926
|
-
// src/
|
|
927
|
-
import {
|
|
1247
|
+
// src/query/useQuery.ts
|
|
1248
|
+
import { useState as useState3, useEffect as useEffect3, useCallback as useCallback2, useSyncExternalStore as useSyncExternalStore2 } from "react";
|
|
928
1249
|
|
|
929
|
-
// src/
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
1250
|
+
// src/query/focusManager.ts
|
|
1251
|
+
var FocusManager = class {
|
|
1252
|
+
listeners = /* @__PURE__ */ new Set();
|
|
1253
|
+
focused = true;
|
|
1254
|
+
unsubscribe = null;
|
|
1255
|
+
constructor() {
|
|
1256
|
+
if (typeof window !== "undefined" && window.addEventListener) {
|
|
1257
|
+
const handleFocus = () => {
|
|
1258
|
+
this.focused = true;
|
|
1259
|
+
this.onFocus();
|
|
1260
|
+
};
|
|
1261
|
+
const handleBlur = () => {
|
|
1262
|
+
this.focused = false;
|
|
1263
|
+
};
|
|
1264
|
+
window.addEventListener("focus", handleFocus, false);
|
|
1265
|
+
window.addEventListener("visibilitychange", handleFocus, false);
|
|
1266
|
+
window.addEventListener("blur", handleBlur, false);
|
|
1267
|
+
this.unsubscribe = () => {
|
|
1268
|
+
window.removeEventListener("focus", handleFocus);
|
|
1269
|
+
window.removeEventListener("visibilitychange", handleFocus);
|
|
1270
|
+
window.removeEventListener("blur", handleBlur);
|
|
1271
|
+
};
|
|
1272
|
+
}
|
|
1273
|
+
}
|
|
1274
|
+
onFocus() {
|
|
1275
|
+
this.listeners.forEach((listener) => listener());
|
|
1276
|
+
}
|
|
1277
|
+
subscribe(listener) {
|
|
1278
|
+
this.listeners.add(listener);
|
|
1279
|
+
return () => this.listeners.delete(listener);
|
|
1280
|
+
}
|
|
1281
|
+
isFocused() {
|
|
1282
|
+
return this.focused;
|
|
1283
|
+
}
|
|
1284
|
+
setFocused(focused) {
|
|
1285
|
+
this.focused = focused;
|
|
1286
|
+
if (focused) this.onFocus();
|
|
1287
|
+
}
|
|
938
1288
|
};
|
|
939
|
-
var
|
|
940
|
-
|
|
941
|
-
|
|
1289
|
+
var focusManager = new FocusManager();
|
|
1290
|
+
|
|
1291
|
+
// src/query/onlineManager.ts
|
|
1292
|
+
var OnlineManager = class {
|
|
1293
|
+
listeners = /* @__PURE__ */ new Set();
|
|
1294
|
+
online = true;
|
|
1295
|
+
constructor() {
|
|
1296
|
+
if (typeof window !== "undefined" && window.addEventListener) {
|
|
1297
|
+
window.addEventListener("online", () => this.setOnline(true), false);
|
|
1298
|
+
window.addEventListener("offline", () => this.setOnline(false), false);
|
|
1299
|
+
this.online = navigator.onLine;
|
|
1300
|
+
}
|
|
1301
|
+
}
|
|
1302
|
+
setOnline(online) {
|
|
1303
|
+
this.online = online;
|
|
1304
|
+
this.listeners.forEach((listener) => listener(online));
|
|
1305
|
+
}
|
|
1306
|
+
subscribe(listener) {
|
|
1307
|
+
this.listeners.add(listener);
|
|
1308
|
+
return () => this.listeners.delete(listener);
|
|
1309
|
+
}
|
|
1310
|
+
isOnline() {
|
|
1311
|
+
return this.online;
|
|
1312
|
+
}
|
|
942
1313
|
};
|
|
1314
|
+
var onlineManager = new OnlineManager();
|
|
943
1315
|
|
|
944
|
-
// src/
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
1316
|
+
// src/query/queryObserver.ts
|
|
1317
|
+
var QueryObserver = class {
|
|
1318
|
+
client;
|
|
1319
|
+
// Reactive Inputs
|
|
1320
|
+
options$;
|
|
1321
|
+
// Reactive Outputs
|
|
1322
|
+
result$;
|
|
1323
|
+
// Internal
|
|
1324
|
+
unsubscribe = null;
|
|
1325
|
+
gcUnsubscribe = null;
|
|
1326
|
+
abortController = null;
|
|
1327
|
+
intervalParams = { id: null };
|
|
1328
|
+
constructor(client, options) {
|
|
1329
|
+
this.client = client;
|
|
1330
|
+
this.options$ = createSignal(options);
|
|
1331
|
+
let lastResult = null;
|
|
1332
|
+
this.result$ = computed(() => {
|
|
1333
|
+
const opts = this.options$.get();
|
|
1334
|
+
const queryKey = opts.queryKey;
|
|
1335
|
+
const cacheSignal = this.client.getSignal(queryKey);
|
|
1336
|
+
const entry = cacheSignal.get();
|
|
1337
|
+
const data = entry?.data;
|
|
1338
|
+
const status = entry?.status || "pending";
|
|
1339
|
+
const error = entry?.error || null;
|
|
1340
|
+
const isFetching = entry?.isFetching || false;
|
|
1341
|
+
const staleTime = opts.staleTime ?? 0;
|
|
1342
|
+
const now = Date.now();
|
|
1343
|
+
const dataTimestamp = entry?.timestamp;
|
|
1344
|
+
const diff = dataTimestamp ? now - dataTimestamp : -1;
|
|
1345
|
+
const isTimeStale = dataTimestamp ? diff > staleTime : true;
|
|
1346
|
+
const isStale = entry?.isInvalidated || isTimeStale;
|
|
1347
|
+
const isError = status === "error";
|
|
1348
|
+
const isSuccess = status === "success";
|
|
1349
|
+
const isPending = status === "pending";
|
|
1350
|
+
const isLoading = data === void 0 && isFetching;
|
|
1351
|
+
let finalData;
|
|
1352
|
+
if (data !== void 0) {
|
|
1353
|
+
try {
|
|
1354
|
+
finalData = opts.select ? opts.select(data) : data;
|
|
1355
|
+
} catch (e) {
|
|
1356
|
+
return {
|
|
1357
|
+
...lastResult ?? {},
|
|
1358
|
+
status: "error",
|
|
1359
|
+
error: e,
|
|
1360
|
+
isError: true
|
|
1361
|
+
};
|
|
1362
|
+
}
|
|
1363
|
+
}
|
|
1364
|
+
const nextResult = {
|
|
1365
|
+
data: finalData,
|
|
1366
|
+
isLoading,
|
|
1367
|
+
isError,
|
|
1368
|
+
isSuccess,
|
|
1369
|
+
isPending,
|
|
1370
|
+
isFetching,
|
|
1371
|
+
isStale,
|
|
1372
|
+
error,
|
|
1373
|
+
status,
|
|
1374
|
+
refetch: this.refetch
|
|
1375
|
+
};
|
|
1376
|
+
const isDataEqual = lastResult?.data === nextResult.data || isDeepEqual(lastResult?.data, nextResult.data);
|
|
1377
|
+
if (lastResult && isDataEqual && lastResult.status === nextResult.status && lastResult.isFetching === nextResult.isFetching && lastResult.isStale === nextResult.isStale && lastResult.error === nextResult.error) {
|
|
1378
|
+
return lastResult;
|
|
996
1379
|
}
|
|
1380
|
+
lastResult = nextResult;
|
|
1381
|
+
return nextResult;
|
|
1382
|
+
});
|
|
1383
|
+
this.initSideEffects();
|
|
1384
|
+
}
|
|
1385
|
+
setOptions(options) {
|
|
1386
|
+
const current = this.options$.get();
|
|
1387
|
+
if (current === options) return;
|
|
1388
|
+
const isKeyEqual = stableHash(current.queryKey) === stableHash(options.queryKey);
|
|
1389
|
+
const isConfigEqual = current.enabled === options.enabled && current.staleTime === options.staleTime && current.cacheTime === options.cacheTime && current.refetchInterval === options.refetchInterval && current.retry === options.retry;
|
|
1390
|
+
if (!isKeyEqual || !isConfigEqual || current.select !== options.select) {
|
|
1391
|
+
this.options$.set(options);
|
|
997
1392
|
}
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1393
|
+
}
|
|
1394
|
+
subscribe(listener) {
|
|
1395
|
+
const unsub = this.result$.subscribe(() => {
|
|
1396
|
+
listener();
|
|
1397
|
+
});
|
|
1398
|
+
return unsub;
|
|
1399
|
+
}
|
|
1400
|
+
getSnapshot = () => {
|
|
1401
|
+
return this.result$.get();
|
|
1402
|
+
};
|
|
1403
|
+
initSideEffects() {
|
|
1404
|
+
const disposeEffect = effect(() => {
|
|
1405
|
+
const opts = this.options$.get();
|
|
1406
|
+
const res = this.result$.get();
|
|
1407
|
+
if (opts.enabled !== false) {
|
|
1408
|
+
if (res.isLoading && !res.isFetching && !res.isError) {
|
|
1409
|
+
untracked(() => this.fetch());
|
|
1410
|
+
} else if (res.isStale && !res.isFetching && !res.isError) {
|
|
1411
|
+
untracked(() => this.fetch());
|
|
1007
1412
|
}
|
|
1008
|
-
|
|
1413
|
+
}
|
|
1414
|
+
});
|
|
1415
|
+
const disposeGC = effect(() => {
|
|
1416
|
+
const opts = this.options$.get();
|
|
1417
|
+
const signal2 = this.client.getSignal(opts.queryKey);
|
|
1418
|
+
const unsub = signal2.subscribe(() => {
|
|
1009
1419
|
});
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1420
|
+
return () => unsub();
|
|
1421
|
+
});
|
|
1422
|
+
const disposeFocus = focusManager.subscribe(() => {
|
|
1423
|
+
const opts = this.options$.get();
|
|
1424
|
+
if (opts.enabled !== false && opts.refetchOnWindowFocus !== false) {
|
|
1425
|
+
this.fetch();
|
|
1426
|
+
}
|
|
1427
|
+
});
|
|
1428
|
+
const disposeOnline = onlineManager.subscribe((isOnline) => {
|
|
1429
|
+
const opts = this.options$.get();
|
|
1430
|
+
if (isOnline && opts.enabled !== false && opts.refetchOnReconnect !== false) {
|
|
1431
|
+
this.fetch();
|
|
1432
|
+
}
|
|
1433
|
+
});
|
|
1434
|
+
this.unsubscribe = () => {
|
|
1435
|
+
disposeEffect();
|
|
1436
|
+
disposeGC();
|
|
1437
|
+
disposeFocus();
|
|
1438
|
+
disposeOnline();
|
|
1439
|
+
};
|
|
1440
|
+
}
|
|
1441
|
+
refetch = async () => {
|
|
1442
|
+
const opts = this.options$.get();
|
|
1443
|
+
this.client.invalidate(opts.queryKey);
|
|
1444
|
+
await this.fetch();
|
|
1445
|
+
};
|
|
1446
|
+
fetch = async (background = false) => {
|
|
1447
|
+
const opts = this.options$.get();
|
|
1448
|
+
if (opts.enabled === false) return;
|
|
1449
|
+
if (this.abortController) {
|
|
1450
|
+
this.abortController.abort();
|
|
1015
1451
|
}
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1452
|
+
this.abortController = new AbortController();
|
|
1453
|
+
const signal2 = this.abortController.signal;
|
|
1454
|
+
try {
|
|
1455
|
+
await this.client.fetch(
|
|
1456
|
+
opts.queryKey,
|
|
1457
|
+
async (ctx) => {
|
|
1458
|
+
const data = await opts.queryFn(ctx);
|
|
1459
|
+
if (opts.schema) {
|
|
1460
|
+
return validateWithSchema(data, opts.schema);
|
|
1461
|
+
}
|
|
1462
|
+
return data;
|
|
1463
|
+
},
|
|
1464
|
+
{ signal: signal2, retry: opts.retry, retryDelay: opts.retryDelay, tags: opts.tags }
|
|
1465
|
+
);
|
|
1466
|
+
} catch (e) {
|
|
1020
1467
|
}
|
|
1021
|
-
}
|
|
1022
|
-
|
|
1023
|
-
if (
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1468
|
+
};
|
|
1469
|
+
destroy() {
|
|
1470
|
+
if (this.unsubscribe) this.unsubscribe();
|
|
1471
|
+
if (this.abortController) this.abortController.abort();
|
|
1472
|
+
}
|
|
1473
|
+
};
|
|
1474
|
+
|
|
1475
|
+
// src/query/useQuery.ts
|
|
1476
|
+
function useQuery(options) {
|
|
1477
|
+
const client = useQueryClient();
|
|
1478
|
+
const [observer] = useState3(() => new QueryObserver(client, options));
|
|
1029
1479
|
useEffect3(() => {
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
const entry = getSnapshot();
|
|
1033
|
-
const isStaleNow = !entry || Date.now() - entry.timestamp > staleTime;
|
|
1034
|
-
if (isStaleNow) fetchData(true);
|
|
1035
|
-
};
|
|
1036
|
-
window.addEventListener("focus", handleFocus);
|
|
1037
|
-
return () => window.removeEventListener("focus", handleFocus);
|
|
1038
|
-
}, [enabled, refetchOnWindowFocus, fetchData, getSnapshot, staleTime]);
|
|
1480
|
+
observer.setOptions(options);
|
|
1481
|
+
}, [observer, options]);
|
|
1039
1482
|
useEffect3(() => {
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
const entry = getSnapshot();
|
|
1043
|
-
const isStaleNow = !entry || Date.now() - entry.timestamp > staleTime;
|
|
1044
|
-
if (isStaleNow) fetchData(true);
|
|
1483
|
+
return () => {
|
|
1484
|
+
observer.destroy();
|
|
1045
1485
|
};
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
}, [
|
|
1486
|
+
}, [observer]);
|
|
1487
|
+
const subscribe = useCallback2((onStoreChange) => {
|
|
1488
|
+
return observer.subscribe(onStoreChange);
|
|
1489
|
+
}, [observer]);
|
|
1490
|
+
const getSnapshot = useCallback2(() => {
|
|
1491
|
+
return observer.getSnapshot();
|
|
1492
|
+
}, [observer]);
|
|
1493
|
+
const result = useSyncExternalStore2(subscribe, getSnapshot);
|
|
1053
1494
|
return {
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
isError: !!statusState.error,
|
|
1057
|
-
isFetching: statusState.isFetching,
|
|
1058
|
-
isStale,
|
|
1059
|
-
error: statusState.error,
|
|
1060
|
-
refetch
|
|
1495
|
+
...result,
|
|
1496
|
+
signal: observer.result$
|
|
1061
1497
|
};
|
|
1062
1498
|
}
|
|
1063
|
-
function statusReducer(state, action) {
|
|
1064
|
-
switch (action.type) {
|
|
1065
|
-
case "FETCH_START":
|
|
1066
|
-
return {
|
|
1067
|
-
...state,
|
|
1068
|
-
isFetching: true,
|
|
1069
|
-
error: null
|
|
1070
|
-
};
|
|
1071
|
-
case "FETCH_SUCCESS":
|
|
1072
|
-
return {
|
|
1073
|
-
...state,
|
|
1074
|
-
isFetching: false,
|
|
1075
|
-
error: null
|
|
1076
|
-
};
|
|
1077
|
-
case "FETCH_ERROR":
|
|
1078
|
-
return {
|
|
1079
|
-
...state,
|
|
1080
|
-
isFetching: false,
|
|
1081
|
-
error: action.error
|
|
1082
|
-
};
|
|
1083
|
-
default:
|
|
1084
|
-
return state;
|
|
1085
|
-
}
|
|
1086
|
-
}
|
|
1087
1499
|
|
|
1088
|
-
// src/
|
|
1089
|
-
import {
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1500
|
+
// src/query/useMutation.ts
|
|
1501
|
+
import { useCallback as useCallback3, useEffect as useEffect4, useSyncExternalStore as useSyncExternalStore3, useState as useState4 } from "react";
|
|
1502
|
+
|
|
1503
|
+
// src/query/mutationObserver.ts
|
|
1504
|
+
var generateId = () => {
|
|
1505
|
+
if (typeof crypto !== "undefined" && crypto.randomUUID) {
|
|
1506
|
+
return crypto.randomUUID();
|
|
1507
|
+
}
|
|
1508
|
+
return "mutation-" + Date.now() + "-" + Math.random().toString(36).slice(2);
|
|
1509
|
+
};
|
|
1510
|
+
var MutationObserver = class {
|
|
1511
|
+
client;
|
|
1512
|
+
options;
|
|
1513
|
+
currentMutationId = null;
|
|
1514
|
+
// We maintain our own signal for this observer's view of the mutation
|
|
1515
|
+
// This ensures we don't miss updates if we switch IDs.
|
|
1516
|
+
signal;
|
|
1517
|
+
constructor(client, options) {
|
|
1518
|
+
this.client = client;
|
|
1519
|
+
this.options = options;
|
|
1520
|
+
this.signal = createSignal({
|
|
1521
|
+
status: "idle",
|
|
1522
|
+
data: void 0,
|
|
1523
|
+
error: null,
|
|
1524
|
+
variables: void 0,
|
|
1525
|
+
context: void 0,
|
|
1526
|
+
submittedAt: 0
|
|
1527
|
+
});
|
|
1528
|
+
}
|
|
1529
|
+
setOptions(options) {
|
|
1530
|
+
this.options = options;
|
|
1531
|
+
}
|
|
1532
|
+
mutate = (variables) => {
|
|
1533
|
+
const id = generateId();
|
|
1534
|
+
this.currentMutationId = id;
|
|
1535
|
+
this.client.mutationCache.register(id, this.options.mutationKey);
|
|
1536
|
+
const pendingState = {
|
|
1537
|
+
status: "pending",
|
|
1538
|
+
variables,
|
|
1539
|
+
submittedAt: Date.now(),
|
|
1540
|
+
data: void 0,
|
|
1541
|
+
error: null,
|
|
1542
|
+
context: void 0
|
|
1543
|
+
};
|
|
1544
|
+
this.signal.set({
|
|
1545
|
+
...this.signal.get(),
|
|
1546
|
+
...pendingState
|
|
1547
|
+
});
|
|
1548
|
+
this.client.mutationCache.notify(id, pendingState);
|
|
1549
|
+
const unsubscribe = this.client.mutationCache.getSignal(id).subscribe((state) => {
|
|
1550
|
+
const current = this.signal.get();
|
|
1551
|
+
if (current.status !== state.status || current.data !== state.data || current.error !== state.error) {
|
|
1552
|
+
this.signal.set(state);
|
|
1553
|
+
}
|
|
1554
|
+
});
|
|
1555
|
+
return this.executeMutation(id, variables).finally(() => {
|
|
1556
|
+
});
|
|
1557
|
+
};
|
|
1558
|
+
executeMutation = async (id, variables) => {
|
|
1559
|
+
const { mutationFn, onMutate, onSuccess, onError, onSettled, invalidatesTags, optimistic, mutationKey } = this.options;
|
|
1103
1560
|
let context;
|
|
1561
|
+
let optimisticSnapshot;
|
|
1562
|
+
const notify = (update) => {
|
|
1563
|
+
this.client.mutationCache.notify(id, update);
|
|
1564
|
+
};
|
|
1104
1565
|
try {
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1566
|
+
if (optimistic) {
|
|
1567
|
+
const { queryKey, update } = optimistic;
|
|
1568
|
+
const signal2 = this.client.getSignal(queryKey);
|
|
1569
|
+
const currentData = signal2.get()?.data;
|
|
1570
|
+
optimisticSnapshot = currentData;
|
|
1571
|
+
const optimisticData = update(variables, currentData);
|
|
1572
|
+
this.client.set(queryKey, optimisticData);
|
|
1573
|
+
}
|
|
1109
1574
|
if (onMutate) {
|
|
1110
1575
|
context = await onMutate(variables);
|
|
1576
|
+
notify({ context });
|
|
1111
1577
|
}
|
|
1112
1578
|
const result = await mutationFn(variables);
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
onSuccess(result, variables, context);
|
|
1579
|
+
notify({ status: "success", data: result });
|
|
1580
|
+
if (onSuccess) await onSuccess(result, variables, context);
|
|
1581
|
+
if (this.client.invalidateTags && invalidatesTags) {
|
|
1582
|
+
this.client.invalidateTags(invalidatesTags);
|
|
1118
1583
|
}
|
|
1119
|
-
if (
|
|
1120
|
-
|
|
1584
|
+
if (optimistic) {
|
|
1585
|
+
this.client.invalidate(optimistic.queryKey);
|
|
1121
1586
|
}
|
|
1587
|
+
if (onSettled) onSettled(result, null, variables, context);
|
|
1122
1588
|
return result;
|
|
1123
|
-
} catch (
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
setIsLoading(false);
|
|
1127
|
-
if (onError) {
|
|
1128
|
-
onError(err, variables, context);
|
|
1129
|
-
}
|
|
1130
|
-
if (onSettled) {
|
|
1131
|
-
onSettled(void 0, err, variables, context);
|
|
1589
|
+
} catch (error) {
|
|
1590
|
+
if (optimistic && optimisticSnapshot !== void 0) {
|
|
1591
|
+
this.client.set(optimistic.queryKey, optimisticSnapshot);
|
|
1132
1592
|
}
|
|
1133
|
-
|
|
1593
|
+
notify({ status: "error", error });
|
|
1594
|
+
if (onError) onError(error, variables, context);
|
|
1595
|
+
if (onSettled) onSettled(void 0, error, variables, context);
|
|
1596
|
+
throw error;
|
|
1134
1597
|
}
|
|
1135
|
-
}
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1598
|
+
};
|
|
1599
|
+
reset = () => {
|
|
1600
|
+
this.signal.set({
|
|
1601
|
+
status: "idle",
|
|
1602
|
+
data: void 0,
|
|
1603
|
+
error: null,
|
|
1604
|
+
variables: void 0,
|
|
1605
|
+
context: void 0,
|
|
1606
|
+
submittedAt: 0
|
|
1607
|
+
});
|
|
1608
|
+
this.currentMutationId = null;
|
|
1609
|
+
};
|
|
1610
|
+
};
|
|
1611
|
+
|
|
1612
|
+
// src/query/useMutation.ts
|
|
1613
|
+
function useMutation(options) {
|
|
1614
|
+
const client = useQueryClient();
|
|
1615
|
+
const [observer] = useState4(() => new MutationObserver(client, options));
|
|
1616
|
+
useEffect4(() => {
|
|
1617
|
+
observer.setOptions(options);
|
|
1618
|
+
}, [observer, options]);
|
|
1619
|
+
const state = useSyncExternalStore3(
|
|
1620
|
+
useCallback3((cb) => observer.signal.subscribe(cb), [observer]),
|
|
1621
|
+
() => observer.signal.get()
|
|
1622
|
+
);
|
|
1623
|
+
const mutateAsync = useCallback3((variables) => {
|
|
1624
|
+
return observer.mutate(variables);
|
|
1625
|
+
}, [observer]);
|
|
1626
|
+
const mutate = useCallback3((variables) => {
|
|
1627
|
+
observer.mutate(variables).catch(() => {
|
|
1628
|
+
});
|
|
1629
|
+
}, [observer]);
|
|
1149
1630
|
return {
|
|
1150
1631
|
mutate,
|
|
1151
1632
|
mutateAsync,
|
|
1152
|
-
data,
|
|
1153
|
-
error,
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1633
|
+
data: state.data,
|
|
1634
|
+
error: state.error,
|
|
1635
|
+
status: state.status,
|
|
1636
|
+
isLoading: state.status === "pending",
|
|
1637
|
+
isError: state.status === "error",
|
|
1638
|
+
isSuccess: state.status === "success",
|
|
1639
|
+
isIdle: state.status === "idle",
|
|
1640
|
+
reset: observer.reset
|
|
1158
1641
|
};
|
|
1159
1642
|
}
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
getQueryData(queryKey) {
|
|
1170
|
-
return queryCache.get(queryKey);
|
|
1171
|
-
},
|
|
1172
|
-
/**
|
|
1173
|
-
* Set query data (for optimistic updates)
|
|
1174
|
-
*/
|
|
1175
|
-
setQueryData(queryKey, updater) {
|
|
1176
|
-
const current = queryCache.get(queryKey);
|
|
1177
|
-
const newData = typeof updater === "function" ? updater(current) : updater;
|
|
1178
|
-
queryCache.set(queryKey, newData);
|
|
1179
|
-
return current;
|
|
1180
|
-
},
|
|
1181
|
-
/**
|
|
1182
|
-
* Invalidate queries (trigger refetch)
|
|
1183
|
-
*/
|
|
1184
|
-
invalidateQueries(queryKey) {
|
|
1185
|
-
queryCache.invalidate(queryKey);
|
|
1186
|
-
}
|
|
1643
|
+
|
|
1644
|
+
// src/query/infiniteQuery.ts
|
|
1645
|
+
import { useState as useState5, useEffect as useEffect5, useCallback as useCallback4, useSyncExternalStore as useSyncExternalStore4 } from "react";
|
|
1646
|
+
|
|
1647
|
+
// src/query/plugins/logger.ts
|
|
1648
|
+
var consoleLogger = {
|
|
1649
|
+
log: console.log,
|
|
1650
|
+
warn: console.warn,
|
|
1651
|
+
error: console.error
|
|
1187
1652
|
};
|
|
1653
|
+
var currentLogger = consoleLogger;
|
|
1654
|
+
var getLogger = () => currentLogger;
|
|
1188
1655
|
|
|
1189
|
-
// src/
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1656
|
+
// src/query/infiniteQueryObserver.ts
|
|
1657
|
+
var InfiniteQueryObserver = class {
|
|
1658
|
+
client;
|
|
1659
|
+
options$;
|
|
1660
|
+
result$;
|
|
1661
|
+
unsubscribe = null;
|
|
1662
|
+
lastFetchTime = 0;
|
|
1663
|
+
constructor(client, options) {
|
|
1664
|
+
this.client = client;
|
|
1665
|
+
this.options$ = createSignal(options);
|
|
1666
|
+
const infiniteQueryKey = computed(() => {
|
|
1667
|
+
const opts = this.options$.get();
|
|
1668
|
+
return [...opts.queryKey, "__infinite__"];
|
|
1669
|
+
});
|
|
1670
|
+
let lastResult = null;
|
|
1671
|
+
this.result$ = computed(() => {
|
|
1672
|
+
const opts = this.options$.get();
|
|
1673
|
+
const key = infiniteQueryKey.get();
|
|
1674
|
+
const cacheSignal = this.client.getSignal(key);
|
|
1675
|
+
const entry = cacheSignal.get();
|
|
1676
|
+
const data = entry?.data;
|
|
1677
|
+
const isFetching = entry?.isFetching || false;
|
|
1678
|
+
const fetchDirection = entry?.fetchDirection || "idle";
|
|
1679
|
+
const status = entry?.status || "pending";
|
|
1680
|
+
const error = entry?.error || null;
|
|
1681
|
+
let hasNextPage = false;
|
|
1682
|
+
let hasPreviousPage = false;
|
|
1683
|
+
if (data && data.pages.length > 0) {
|
|
1684
|
+
if (opts.getNextPageParam) {
|
|
1685
|
+
const lastPage = data.pages[data.pages.length - 1];
|
|
1686
|
+
hasNextPage = opts.getNextPageParam(lastPage, data.pages) !== void 0;
|
|
1687
|
+
}
|
|
1688
|
+
if (opts.getPreviousPageParam) {
|
|
1689
|
+
const firstPage = data.pages[0];
|
|
1690
|
+
hasPreviousPage = opts.getPreviousPageParam(firstPage, data.pages) !== void 0;
|
|
1691
|
+
}
|
|
1692
|
+
}
|
|
1693
|
+
const isFetchingNextPage = isFetching && fetchDirection === "next";
|
|
1694
|
+
const isFetchingPreviousPage = isFetching && fetchDirection === "previous";
|
|
1695
|
+
const isLoading = data === void 0 && isFetching;
|
|
1696
|
+
const nextResult = {
|
|
1697
|
+
data,
|
|
1698
|
+
isFetching,
|
|
1699
|
+
isFetchingNextPage,
|
|
1700
|
+
isFetchingPreviousPage,
|
|
1701
|
+
isLoading,
|
|
1702
|
+
isError: status === "error",
|
|
1703
|
+
hasNextPage,
|
|
1704
|
+
hasPreviousPage,
|
|
1705
|
+
error,
|
|
1706
|
+
status,
|
|
1707
|
+
fetchNextPage: this.fetchNextPage,
|
|
1708
|
+
fetchPreviousPage: this.fetchPreviousPage,
|
|
1709
|
+
refetch: this.refetch
|
|
1223
1710
|
};
|
|
1224
|
-
|
|
1225
|
-
|
|
1711
|
+
const isDataEqual = lastResult?.data === nextResult.data || isDeepEqual(lastResult?.data, nextResult.data);
|
|
1712
|
+
if (lastResult && isDataEqual && lastResult.isFetching === nextResult.isFetching && lastResult.status === nextResult.status && lastResult.hasNextPage === nextResult.hasNextPage && lastResult.hasPreviousPage === nextResult.hasPreviousPage) {
|
|
1713
|
+
return lastResult;
|
|
1714
|
+
}
|
|
1715
|
+
lastResult = nextResult;
|
|
1716
|
+
return nextResult;
|
|
1717
|
+
});
|
|
1718
|
+
this.initSideEffects();
|
|
1226
1719
|
}
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
staleTime = 0,
|
|
1235
|
-
cacheTime = 5 * 60 * 1e3,
|
|
1236
|
-
enabled = true
|
|
1237
|
-
}) {
|
|
1238
|
-
const client = useQueryClient();
|
|
1239
|
-
const queryKeyHash = stableHash(queryKey);
|
|
1240
|
-
const infiniteQueryKey = [...queryKey, "__infinite__"];
|
|
1241
|
-
const subscribe2 = useCallback5((onStoreChange) => {
|
|
1242
|
-
const signal = client.getSignal(infiniteQueryKey);
|
|
1243
|
-
return signal.subscribe(() => onStoreChange());
|
|
1244
|
-
}, [client, queryKeyHash]);
|
|
1245
|
-
const getSnapshot = useCallback5(() => {
|
|
1246
|
-
const signal = client.getSignal(infiniteQueryKey);
|
|
1247
|
-
return signal.get();
|
|
1248
|
-
}, [client, queryKeyHash]);
|
|
1249
|
-
const cacheEntry = useSyncExternalStore3(subscribe2, getSnapshot);
|
|
1250
|
-
const data = cacheEntry?.data;
|
|
1251
|
-
const [statusState, dispatch] = useReducer2(statusReducer2, {
|
|
1252
|
-
isFetching: false,
|
|
1253
|
-
isFetchingNextPage: false,
|
|
1254
|
-
isFetchingPreviousPage: false,
|
|
1255
|
-
error: null,
|
|
1256
|
-
hasNextPage: false,
|
|
1257
|
-
// Will be set after first fetch
|
|
1258
|
-
hasPreviousPage: false
|
|
1259
|
-
});
|
|
1260
|
-
const queryFnRef = useRef4(queryFn);
|
|
1261
|
-
const getNextPageParamRef = useRef4(getNextPageParam);
|
|
1262
|
-
const getPreviousPageParamRef = useRef4(getPreviousPageParam);
|
|
1263
|
-
const initialFetchDoneRef = useRef4(false);
|
|
1264
|
-
const clientRef = useRef4(client);
|
|
1265
|
-
const infiniteQueryKeyRef = useRef4(infiniteQueryKey);
|
|
1266
|
-
const initialPageParamRef = useRef4(initialPageParam);
|
|
1267
|
-
const staleTimeRef = useRef4(staleTime);
|
|
1268
|
-
const cacheTimeRef = useRef4(cacheTime);
|
|
1269
|
-
useEffect4(() => {
|
|
1270
|
-
queryFnRef.current = queryFn;
|
|
1271
|
-
getNextPageParamRef.current = getNextPageParam;
|
|
1272
|
-
getPreviousPageParamRef.current = getPreviousPageParam;
|
|
1273
|
-
clientRef.current = client;
|
|
1274
|
-
infiniteQueryKeyRef.current = infiniteQueryKey;
|
|
1275
|
-
initialPageParamRef.current = initialPageParam;
|
|
1276
|
-
staleTimeRef.current = staleTime;
|
|
1277
|
-
cacheTimeRef.current = cacheTime;
|
|
1278
|
-
});
|
|
1279
|
-
const prevDataRef = useRef4(data);
|
|
1280
|
-
useEffect4(() => {
|
|
1281
|
-
if (prevDataRef.current && !data) {
|
|
1282
|
-
initialFetchDoneRef.current = false;
|
|
1720
|
+
setOptions(options) {
|
|
1721
|
+
const current = this.options$.get();
|
|
1722
|
+
if (current === options) return;
|
|
1723
|
+
const isKeyEqual = stableHash(current.queryKey) === stableHash(options.queryKey);
|
|
1724
|
+
const isConfigEqual = current.enabled === options.enabled && current.staleTime === options.staleTime;
|
|
1725
|
+
if (!isKeyEqual || !isConfigEqual || current.getNextPageParam !== options.getNextPageParam || current.getPreviousPageParam !== options.getPreviousPageParam) {
|
|
1726
|
+
this.options$.set(options);
|
|
1283
1727
|
}
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1728
|
+
}
|
|
1729
|
+
initSideEffects() {
|
|
1730
|
+
const dispose = effect(() => {
|
|
1731
|
+
const opts = this.options$.get();
|
|
1732
|
+
const res = this.result$.get();
|
|
1733
|
+
if (opts.enabled !== false) {
|
|
1734
|
+
const infiniteKey = [...opts.queryKey, "__infinite__"];
|
|
1735
|
+
const entry = this.client.getSignal(infiniteKey).get();
|
|
1736
|
+
const staleTime = opts.staleTime ?? 0;
|
|
1737
|
+
const now = Date.now();
|
|
1738
|
+
const timestamp = entry?.timestamp || 0;
|
|
1739
|
+
const isStale = entry?.isInvalidated || entry?.data && now - timestamp > staleTime;
|
|
1740
|
+
if ((!entry?.data || isStale) && !res.isFetching && !res.isError) {
|
|
1741
|
+
untracked(() => this.fetchInitial());
|
|
1742
|
+
}
|
|
1294
1743
|
}
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1744
|
+
});
|
|
1745
|
+
const disposeFocus = focusManager.subscribe(() => {
|
|
1746
|
+
const opts = this.options$.get();
|
|
1747
|
+
if (opts.enabled !== false && opts.refetchOnWindowFocus !== false) {
|
|
1748
|
+
this.fetchInitial();
|
|
1749
|
+
}
|
|
1750
|
+
});
|
|
1751
|
+
const disposeOnline = onlineManager.subscribe((isOnline) => {
|
|
1752
|
+
const opts = this.options$.get();
|
|
1753
|
+
if (isOnline && opts.enabled !== false && opts.refetchOnReconnect !== false) {
|
|
1754
|
+
this.fetchInitial();
|
|
1755
|
+
}
|
|
1756
|
+
});
|
|
1757
|
+
this.unsubscribe = () => {
|
|
1758
|
+
dispose();
|
|
1759
|
+
disposeFocus();
|
|
1760
|
+
disposeOnline();
|
|
1761
|
+
};
|
|
1762
|
+
}
|
|
1763
|
+
fetchInitial = async (options) => {
|
|
1764
|
+
const opts = this.options$.get();
|
|
1765
|
+
const infiniteKey = [...opts.queryKey, "__infinite__"];
|
|
1766
|
+
try {
|
|
1767
|
+
const entrySignal = this.client.getSignal(infiniteKey);
|
|
1768
|
+
const data = entrySignal.get()?.data;
|
|
1769
|
+
if (data && data.pageParams.length > 0 && !options?.force) {
|
|
1770
|
+
const firstParam2 = data.pageParams[0];
|
|
1771
|
+
const firstPage = await opts.queryFn({ pageParam: firstParam2 });
|
|
1772
|
+
const latest = entrySignal.get()?.data;
|
|
1773
|
+
if (!latest) return;
|
|
1774
|
+
const updatedData = {
|
|
1775
|
+
...latest,
|
|
1776
|
+
pages: [firstPage, ...latest.pages.slice(1)]
|
|
1777
|
+
};
|
|
1778
|
+
this.client.set(infiniteKey, updatedData, {
|
|
1779
|
+
staleTime: opts.staleTime,
|
|
1780
|
+
cacheTime: opts.cacheTime
|
|
1781
|
+
});
|
|
1305
1782
|
return;
|
|
1306
1783
|
}
|
|
1307
|
-
|
|
1308
|
-
|
|
1784
|
+
const initialParam = opts.initialPageParam;
|
|
1785
|
+
const firstParam = initialParam !== void 0 ? initialParam : 0;
|
|
1786
|
+
const initialData = await this.client.fetch(infiniteKey, async () => {
|
|
1787
|
+
const firstPage = await opts.queryFn({ pageParam: firstParam });
|
|
1788
|
+
return {
|
|
1309
1789
|
pages: [firstPage],
|
|
1310
1790
|
pageParams: [firstParam]
|
|
1311
1791
|
};
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
cacheTime: cacheTimeRef.current
|
|
1320
|
-
});
|
|
1321
|
-
dispatch({ type: "FETCH_SUCCESS", hasNextPage: hasNext });
|
|
1322
|
-
}
|
|
1323
|
-
};
|
|
1324
|
-
doFetch();
|
|
1325
|
-
}, [enabled, data]);
|
|
1326
|
-
const fetchPageHelper = useCallback5(async (pageParam) => {
|
|
1327
|
-
try {
|
|
1328
|
-
const pageKey = [...infiniteQueryKey, String(pageParam)];
|
|
1329
|
-
return await clientRef.current.fetch(
|
|
1330
|
-
pageKey,
|
|
1331
|
-
() => queryFnRef.current({ pageParam })
|
|
1332
|
-
);
|
|
1333
|
-
} catch (error) {
|
|
1334
|
-
dispatch({ type: "FETCH_ERROR", error });
|
|
1335
|
-
return void 0;
|
|
1792
|
+
}, { fetchDirection: "initial", retry: opts.retry });
|
|
1793
|
+
this.client.set(infiniteKey, initialData, {
|
|
1794
|
+
staleTime: opts.staleTime,
|
|
1795
|
+
cacheTime: opts.cacheTime
|
|
1796
|
+
});
|
|
1797
|
+
} catch (err) {
|
|
1798
|
+
getLogger().error("Initial fetch failed", err);
|
|
1336
1799
|
}
|
|
1337
|
-
}
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
const
|
|
1341
|
-
if (!
|
|
1342
|
-
const
|
|
1800
|
+
};
|
|
1801
|
+
fetchNextPage = async () => {
|
|
1802
|
+
const res = this.result$.get();
|
|
1803
|
+
const opts = this.options$.get();
|
|
1804
|
+
if (!res.hasNextPage || res.isFetching || !res.data) return;
|
|
1805
|
+
const infiniteKey = [...opts.queryKey, "__infinite__"];
|
|
1806
|
+
const lastPage = res.data.pages[res.data.pages.length - 1];
|
|
1807
|
+
const nextPageParam = opts.getNextPageParam?.(lastPage, res.data.pages);
|
|
1343
1808
|
if (nextPageParam === void 0) return;
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1809
|
+
try {
|
|
1810
|
+
const updatedData = await this.client.fetch(infiniteKey, async () => {
|
|
1811
|
+
const newPage = await opts.queryFn({ pageParam: nextPageParam });
|
|
1812
|
+
const currentData = this.client.getSignal(infiniteKey).get()?.data;
|
|
1813
|
+
if (!currentData) throw new Error("Infinite query data missing");
|
|
1814
|
+
const updatedParams = [...currentData.pageParams, nextPageParam];
|
|
1815
|
+
const nextCursor = opts.getNextPageParam?.(newPage, [...currentData.pages, newPage]);
|
|
1816
|
+
if (nextCursor !== void 0) {
|
|
1817
|
+
updatedParams.push(nextCursor);
|
|
1818
|
+
}
|
|
1819
|
+
return {
|
|
1820
|
+
pages: [...currentData.pages, newPage],
|
|
1821
|
+
pageParams: updatedParams
|
|
1822
|
+
};
|
|
1823
|
+
}, { fetchDirection: "next", retry: opts.retry });
|
|
1824
|
+
this.client.set(infiniteKey, updatedData, {
|
|
1825
|
+
staleTime: opts.staleTime,
|
|
1826
|
+
cacheTime: opts.cacheTime
|
|
1359
1827
|
});
|
|
1360
|
-
|
|
1828
|
+
} catch (err) {
|
|
1829
|
+
getLogger().error("Fetch next page failed", err);
|
|
1361
1830
|
}
|
|
1362
|
-
}
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
const
|
|
1366
|
-
if (!
|
|
1367
|
-
const
|
|
1831
|
+
};
|
|
1832
|
+
fetchPreviousPage = async () => {
|
|
1833
|
+
const res = this.result$.get();
|
|
1834
|
+
const opts = this.options$.get();
|
|
1835
|
+
if (!res.hasPreviousPage || res.isFetching || !res.data) return;
|
|
1836
|
+
const infiniteKey = [...opts.queryKey, "__infinite__"];
|
|
1837
|
+
const firstPage = res.data.pages[0];
|
|
1838
|
+
const previousPageParam = opts.getPreviousPageParam?.(firstPage, res.data.pages);
|
|
1368
1839
|
if (previousPageParam === void 0) return;
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
staleTime: staleTimeRef.current,
|
|
1383
|
-
cacheTime: cacheTimeRef.current
|
|
1840
|
+
try {
|
|
1841
|
+
const updatedData = await this.client.fetch(infiniteKey, async () => {
|
|
1842
|
+
const newPage = await opts.queryFn({ pageParam: previousPageParam });
|
|
1843
|
+
const currentData = this.client.getSignal(infiniteKey).get()?.data;
|
|
1844
|
+
if (!currentData) throw new Error("Infinite query data missing");
|
|
1845
|
+
return {
|
|
1846
|
+
pages: [newPage, ...currentData.pages],
|
|
1847
|
+
pageParams: [previousPageParam, ...currentData.pageParams]
|
|
1848
|
+
};
|
|
1849
|
+
}, { fetchDirection: "previous", retry: opts.retry });
|
|
1850
|
+
this.client.set(infiniteKey, updatedData, {
|
|
1851
|
+
staleTime: opts.staleTime,
|
|
1852
|
+
cacheTime: opts.cacheTime
|
|
1384
1853
|
});
|
|
1385
|
-
|
|
1854
|
+
} catch (err) {
|
|
1855
|
+
getLogger().error("Fetch previous page failed", err);
|
|
1386
1856
|
}
|
|
1387
|
-
}, [statusState.hasPreviousPage, statusState.isFetchingPreviousPage, data, fetchPageHelper]);
|
|
1388
|
-
const refetch = useCallback5(async () => {
|
|
1389
|
-
initialFetchDoneRef.current = false;
|
|
1390
|
-
clientRef.current.invalidate(infiniteQueryKeyRef.current);
|
|
1391
|
-
}, []);
|
|
1392
|
-
return {
|
|
1393
|
-
data,
|
|
1394
|
-
fetchNextPage,
|
|
1395
|
-
fetchPreviousPage,
|
|
1396
|
-
hasNextPage: statusState.hasNextPage,
|
|
1397
|
-
hasPreviousPage: statusState.hasPreviousPage,
|
|
1398
|
-
isFetching: statusState.isFetching,
|
|
1399
|
-
isFetchingNextPage: statusState.isFetchingNextPage,
|
|
1400
|
-
isFetchingPreviousPage: statusState.isFetchingPreviousPage,
|
|
1401
|
-
isLoading: data === void 0 && statusState.isFetching,
|
|
1402
|
-
isError: !!statusState.error,
|
|
1403
|
-
error: statusState.error,
|
|
1404
|
-
refetch
|
|
1405
1857
|
};
|
|
1858
|
+
refetch = async () => {
|
|
1859
|
+
const opts = this.options$.get();
|
|
1860
|
+
const infiniteKey = [...opts.queryKey, "__infinite__"];
|
|
1861
|
+
this.client.invalidate(infiniteKey);
|
|
1862
|
+
await this.fetchInitial({ force: true });
|
|
1863
|
+
};
|
|
1864
|
+
destroy() {
|
|
1865
|
+
if (this.unsubscribe) this.unsubscribe();
|
|
1866
|
+
}
|
|
1867
|
+
};
|
|
1868
|
+
|
|
1869
|
+
// src/query/infiniteQuery.ts
|
|
1870
|
+
function useInfiniteQuery(options) {
|
|
1871
|
+
const client = useQueryClient();
|
|
1872
|
+
const [observer] = useState5(() => new InfiniteQueryObserver(client, options));
|
|
1873
|
+
useEffect5(() => {
|
|
1874
|
+
observer.setOptions(options);
|
|
1875
|
+
}, [observer, options]);
|
|
1876
|
+
useEffect5(() => {
|
|
1877
|
+
return () => {
|
|
1878
|
+
observer.destroy();
|
|
1879
|
+
};
|
|
1880
|
+
}, [observer]);
|
|
1881
|
+
const subscribe = useCallback4((onStoreChange) => {
|
|
1882
|
+
return observer.result$.subscribe(() => onStoreChange());
|
|
1883
|
+
}, [observer]);
|
|
1884
|
+
const getSnapshot = useCallback4(() => {
|
|
1885
|
+
return observer.result$.get();
|
|
1886
|
+
}, [observer]);
|
|
1887
|
+
return useSyncExternalStore4(subscribe, getSnapshot);
|
|
1406
1888
|
}
|
|
1407
1889
|
|
|
1408
|
-
// src/
|
|
1409
|
-
import {
|
|
1890
|
+
// src/query/HydrationBoundary.tsx
|
|
1891
|
+
import { useRef as useRef3 } from "react";
|
|
1410
1892
|
|
|
1411
|
-
// src/
|
|
1412
|
-
|
|
1413
|
-
|
|
1893
|
+
// src/query/hydration.ts
|
|
1894
|
+
function dehydrate(client) {
|
|
1895
|
+
const queries = [];
|
|
1896
|
+
const snapshot = client.getSnapshot();
|
|
1897
|
+
snapshot.forEach((state, hash) => {
|
|
1898
|
+
queries.push({
|
|
1899
|
+
queryKey: state.key,
|
|
1900
|
+
queryHash: hash,
|
|
1901
|
+
state
|
|
1902
|
+
});
|
|
1903
|
+
});
|
|
1904
|
+
return { queries };
|
|
1905
|
+
}
|
|
1906
|
+
function hydrate(client, state) {
|
|
1907
|
+
if (!state || !state.queries) return;
|
|
1908
|
+
state.queries.forEach(({ queryKey, state: queryState }) => {
|
|
1909
|
+
const key = queryKey;
|
|
1910
|
+
client.restore(queryKey, queryState);
|
|
1911
|
+
});
|
|
1912
|
+
}
|
|
1913
|
+
|
|
1914
|
+
// src/query/HydrationBoundary.tsx
|
|
1915
|
+
import { Fragment as Fragment2, jsx as jsx3 } from "react/jsx-runtime";
|
|
1916
|
+
function HydrationBoundary({ state, children }) {
|
|
1414
1917
|
const client = useQueryClient();
|
|
1415
|
-
const
|
|
1416
|
-
|
|
1918
|
+
const hydratedRef = useRef3(false);
|
|
1919
|
+
if (state && !hydratedRef.current) {
|
|
1920
|
+
hydrate(client, state);
|
|
1921
|
+
hydratedRef.current = true;
|
|
1922
|
+
}
|
|
1923
|
+
return /* @__PURE__ */ jsx3(Fragment2, { children });
|
|
1924
|
+
}
|
|
1925
|
+
|
|
1926
|
+
// src/query/useSuspenseQuery.ts
|
|
1927
|
+
function useSuspenseQuery(options) {
|
|
1928
|
+
const client = useQueryClient();
|
|
1929
|
+
const signal2 = client.getSignal(options.queryKey);
|
|
1930
|
+
const entry = signal2.get();
|
|
1931
|
+
const shouldSuspend = !entry || entry.status === "pending" && entry.data === void 0;
|
|
1932
|
+
if (shouldSuspend) {
|
|
1933
|
+
const fetchPromise = client.fetch(
|
|
1934
|
+
options.queryKey,
|
|
1935
|
+
(ctx) => options.queryFn({ ...ctx, signal: void 0 }),
|
|
1936
|
+
{ signal: void 0 }
|
|
1937
|
+
).then((data) => {
|
|
1938
|
+
client.set(options.queryKey, data);
|
|
1939
|
+
return data;
|
|
1940
|
+
});
|
|
1941
|
+
throw fetchPromise;
|
|
1942
|
+
}
|
|
1943
|
+
if (entry?.status === "error") {
|
|
1944
|
+
throw entry.error;
|
|
1945
|
+
}
|
|
1946
|
+
const query = useQuery(options);
|
|
1947
|
+
return {
|
|
1948
|
+
...query,
|
|
1949
|
+
data: query.data
|
|
1950
|
+
};
|
|
1951
|
+
}
|
|
1952
|
+
|
|
1953
|
+
// src/query/useQueryStore.ts
|
|
1954
|
+
import { useState as useState6, useEffect as useEffect6 } from "react";
|
|
1955
|
+
function useQueryStore() {
|
|
1956
|
+
const client = useQueryClient();
|
|
1957
|
+
const [cache, setCache] = useState6(client.getAll());
|
|
1958
|
+
useEffect6(() => {
|
|
1417
1959
|
const interval = setInterval(() => {
|
|
1418
1960
|
setCache(new Map(client.getAll()));
|
|
1419
1961
|
}, 500);
|
|
@@ -1422,430 +1964,45 @@ function useQueryCache() {
|
|
|
1422
1964
|
return cache;
|
|
1423
1965
|
}
|
|
1424
1966
|
|
|
1425
|
-
// src/
|
|
1426
|
-
import {
|
|
1427
|
-
function
|
|
1428
|
-
const [isOpen, setIsOpen] = useState5(false);
|
|
1429
|
-
const [isMinimized, setIsMinimized] = useState5(false);
|
|
1430
|
-
const [height, setHeight] = useState5(450);
|
|
1431
|
-
const [filter, setFilter] = useState5("");
|
|
1432
|
-
const cache = useQueryCache();
|
|
1967
|
+
// src/query/useQuerySignal.ts
|
|
1968
|
+
import { useEffect as useEffect7, useState as useState7 } from "react";
|
|
1969
|
+
function useQuery$(options) {
|
|
1433
1970
|
const client = useQueryClient();
|
|
1434
|
-
const
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
setHeight(newHeight);
|
|
1442
|
-
}
|
|
1443
|
-
};
|
|
1444
|
-
const handleMouseUp = () => {
|
|
1445
|
-
isResizingRef.current = false;
|
|
1446
|
-
document.body.style.cursor = "default";
|
|
1447
|
-
};
|
|
1448
|
-
window.addEventListener("mousemove", handleMouseMove);
|
|
1449
|
-
window.addEventListener("mouseup", handleMouseUp);
|
|
1971
|
+
const [observer] = useState7(() => new QueryObserver(client, options));
|
|
1972
|
+
useEffect7(() => {
|
|
1973
|
+
observer.setOptions(options);
|
|
1974
|
+
}, [observer, options.enabled, options.staleTime, options.cacheTime, options.queryKey, options.refetchInterval]);
|
|
1975
|
+
useEffect7(() => {
|
|
1976
|
+
const unsubscribe = observer.subscribe(() => {
|
|
1977
|
+
});
|
|
1450
1978
|
return () => {
|
|
1451
|
-
|
|
1452
|
-
|
|
1979
|
+
unsubscribe();
|
|
1980
|
+
observer.destroy();
|
|
1453
1981
|
};
|
|
1454
|
-
}, []);
|
|
1455
|
-
|
|
1456
|
-
const filteredEntries = useMemo(() => {
|
|
1457
|
-
if (!filter) return entries;
|
|
1458
|
-
const search = filter.toLowerCase();
|
|
1459
|
-
return entries.filter(
|
|
1460
|
-
([_, entry]) => entry.key.some((k) => String(k).toLowerCase().includes(search))
|
|
1461
|
-
);
|
|
1462
|
-
}, [entries, filter]);
|
|
1463
|
-
if (!isOpen) {
|
|
1464
|
-
return /* @__PURE__ */ jsx2(
|
|
1465
|
-
"button",
|
|
1466
|
-
{
|
|
1467
|
-
onClick: () => setIsOpen(true),
|
|
1468
|
-
style: {
|
|
1469
|
-
position: "fixed",
|
|
1470
|
-
bottom: "20px",
|
|
1471
|
-
right: "20px",
|
|
1472
|
-
background: "#111",
|
|
1473
|
-
color: "#b0fb5d",
|
|
1474
|
-
// Quantum Green
|
|
1475
|
-
border: "1px solid #333",
|
|
1476
|
-
borderRadius: "50%",
|
|
1477
|
-
width: "48px",
|
|
1478
|
-
height: "48px",
|
|
1479
|
-
cursor: "pointer",
|
|
1480
|
-
zIndex: 9999,
|
|
1481
|
-
boxShadow: "0 8px 32px rgba(0, 0, 0, 0.4)",
|
|
1482
|
-
fontSize: "20px",
|
|
1483
|
-
display: "flex",
|
|
1484
|
-
alignItems: "center",
|
|
1485
|
-
justifyContent: "center",
|
|
1486
|
-
transition: "transform 0.2s",
|
|
1487
|
-
fontFamily: "monospace"
|
|
1488
|
-
},
|
|
1489
|
-
onMouseEnter: (e) => e.currentTarget.style.transform = "scale(1.1)",
|
|
1490
|
-
onMouseLeave: (e) => e.currentTarget.style.transform = "scale(1)",
|
|
1491
|
-
title: "Open Quantum DevTools",
|
|
1492
|
-
children: "\u26A1\uFE0F"
|
|
1493
|
-
}
|
|
1494
|
-
);
|
|
1495
|
-
}
|
|
1496
|
-
if (isMinimized) {
|
|
1497
|
-
return /* @__PURE__ */ jsxs("div", { style: {
|
|
1498
|
-
position: "fixed",
|
|
1499
|
-
bottom: "20px",
|
|
1500
|
-
right: "20px",
|
|
1501
|
-
background: "#111",
|
|
1502
|
-
border: "1px solid #333",
|
|
1503
|
-
borderRadius: "8px",
|
|
1504
|
-
padding: "8px 12px",
|
|
1505
|
-
zIndex: 9999,
|
|
1506
|
-
display: "flex",
|
|
1507
|
-
alignItems: "center",
|
|
1508
|
-
gap: "10px",
|
|
1509
|
-
boxShadow: "0 8px 32px rgba(0, 0, 0, 0.4)",
|
|
1510
|
-
fontFamily: "monospace",
|
|
1511
|
-
color: "#e0e0e0",
|
|
1512
|
-
cursor: "pointer"
|
|
1513
|
-
}, onClick: () => setIsMinimized(false), children: [
|
|
1514
|
-
/* @__PURE__ */ jsx2("span", { style: { color: "#b0fb5d" }, children: "\u26A1\uFE0F" }),
|
|
1515
|
-
/* @__PURE__ */ jsx2("span", { style: { fontSize: "12px" }, children: "DevTools" }),
|
|
1516
|
-
/* @__PURE__ */ jsxs("span", { style: {
|
|
1517
|
-
background: "#333",
|
|
1518
|
-
padding: "2px 6px",
|
|
1519
|
-
borderRadius: "4px",
|
|
1520
|
-
fontSize: "10px"
|
|
1521
|
-
}, children: [
|
|
1522
|
-
entries.length,
|
|
1523
|
-
" queries"
|
|
1524
|
-
] })
|
|
1525
|
-
] });
|
|
1526
|
-
}
|
|
1527
|
-
return /* @__PURE__ */ jsxs(
|
|
1528
|
-
"div",
|
|
1529
|
-
{
|
|
1530
|
-
ref: containerRef,
|
|
1531
|
-
style: {
|
|
1532
|
-
position: "fixed",
|
|
1533
|
-
bottom: 0,
|
|
1534
|
-
right: 0,
|
|
1535
|
-
width: "100%",
|
|
1536
|
-
height: `${height}px`,
|
|
1537
|
-
background: "#0a0a0a",
|
|
1538
|
-
color: "#e0e0e0",
|
|
1539
|
-
borderTopLeftRadius: "12px",
|
|
1540
|
-
borderTopRightRadius: "12px",
|
|
1541
|
-
boxShadow: "0 -10px 40px rgba(0,0,0,0.5)",
|
|
1542
|
-
zIndex: 9999,
|
|
1543
|
-
display: "flex",
|
|
1544
|
-
flexDirection: "column",
|
|
1545
|
-
fontFamily: "'JetBrains Mono', 'Fira Code', monospace",
|
|
1546
|
-
fontSize: "13px",
|
|
1547
|
-
borderTop: "1px solid #333"
|
|
1548
|
-
},
|
|
1549
|
-
children: [
|
|
1550
|
-
/* @__PURE__ */ jsx2(
|
|
1551
|
-
"div",
|
|
1552
|
-
{
|
|
1553
|
-
onMouseDown: () => {
|
|
1554
|
-
isResizingRef.current = true;
|
|
1555
|
-
document.body.style.cursor = "ns-resize";
|
|
1556
|
-
},
|
|
1557
|
-
style: {
|
|
1558
|
-
height: "6px",
|
|
1559
|
-
width: "100%",
|
|
1560
|
-
cursor: "ns-resize",
|
|
1561
|
-
position: "absolute",
|
|
1562
|
-
top: "-3px",
|
|
1563
|
-
left: 0,
|
|
1564
|
-
zIndex: 10
|
|
1565
|
-
// debugging color: background: 'red', opacity: 0.2
|
|
1566
|
-
}
|
|
1567
|
-
}
|
|
1568
|
-
),
|
|
1569
|
-
/* @__PURE__ */ jsxs("div", { style: {
|
|
1570
|
-
padding: "12px 16px",
|
|
1571
|
-
borderBottom: "1px solid #222",
|
|
1572
|
-
display: "flex",
|
|
1573
|
-
justifyContent: "space-between",
|
|
1574
|
-
alignItems: "center",
|
|
1575
|
-
background: "#111",
|
|
1576
|
-
borderTopLeftRadius: "12px",
|
|
1577
|
-
borderTopRightRadius: "12px",
|
|
1578
|
-
userSelect: "none"
|
|
1579
|
-
}, children: [
|
|
1580
|
-
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
|
|
1581
|
-
/* @__PURE__ */ jsx2("span", { style: { color: "#b0fb5d", fontSize: "16px" }, children: "\u26A1\uFE0F" }),
|
|
1582
|
-
/* @__PURE__ */ jsx2("span", { style: { fontWeight: 600, letterSpacing: "-0.5px" }, children: "Quantum DevTools" }),
|
|
1583
|
-
/* @__PURE__ */ jsx2("span", { style: {
|
|
1584
|
-
background: "#222",
|
|
1585
|
-
padding: "2px 6px",
|
|
1586
|
-
borderRadius: "4px",
|
|
1587
|
-
fontSize: "10px",
|
|
1588
|
-
color: "#666"
|
|
1589
|
-
}, children: "v1.2.3" })
|
|
1590
|
-
] }),
|
|
1591
|
-
/* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: "8px" }, children: [
|
|
1592
|
-
/* @__PURE__ */ jsx2(
|
|
1593
|
-
"button",
|
|
1594
|
-
{
|
|
1595
|
-
onClick: () => setIsMinimized(true),
|
|
1596
|
-
title: "Minimize",
|
|
1597
|
-
style: {
|
|
1598
|
-
background: "transparent",
|
|
1599
|
-
border: "none",
|
|
1600
|
-
color: "#666",
|
|
1601
|
-
cursor: "pointer",
|
|
1602
|
-
fontSize: "16px",
|
|
1603
|
-
padding: "4px",
|
|
1604
|
-
lineHeight: 1
|
|
1605
|
-
},
|
|
1606
|
-
children: "_"
|
|
1607
|
-
}
|
|
1608
|
-
),
|
|
1609
|
-
/* @__PURE__ */ jsx2(
|
|
1610
|
-
"button",
|
|
1611
|
-
{
|
|
1612
|
-
onClick: () => setIsOpen(false),
|
|
1613
|
-
title: "Close",
|
|
1614
|
-
style: {
|
|
1615
|
-
background: "transparent",
|
|
1616
|
-
border: "none",
|
|
1617
|
-
color: "#666",
|
|
1618
|
-
cursor: "pointer",
|
|
1619
|
-
fontSize: "18px",
|
|
1620
|
-
padding: "4px",
|
|
1621
|
-
lineHeight: 1
|
|
1622
|
-
},
|
|
1623
|
-
children: "\xD7"
|
|
1624
|
-
}
|
|
1625
|
-
)
|
|
1626
|
-
] })
|
|
1627
|
-
] }),
|
|
1628
|
-
/* @__PURE__ */ jsxs("div", { style: {
|
|
1629
|
-
padding: "8px 16px",
|
|
1630
|
-
borderBottom: "1px solid #222",
|
|
1631
|
-
background: "#0f0f0f",
|
|
1632
|
-
display: "flex",
|
|
1633
|
-
gap: "12px"
|
|
1634
|
-
}, children: [
|
|
1635
|
-
/* @__PURE__ */ jsx2(
|
|
1636
|
-
"input",
|
|
1637
|
-
{
|
|
1638
|
-
type: "text",
|
|
1639
|
-
placeholder: "Filter queries...",
|
|
1640
|
-
value: filter,
|
|
1641
|
-
onChange: (e) => setFilter(e.target.value),
|
|
1642
|
-
style: {
|
|
1643
|
-
background: "#1a1a1a",
|
|
1644
|
-
border: "1px solid #333",
|
|
1645
|
-
color: "#fff",
|
|
1646
|
-
padding: "6px 10px",
|
|
1647
|
-
borderRadius: "4px",
|
|
1648
|
-
flex: 1,
|
|
1649
|
-
fontSize: "12px",
|
|
1650
|
-
outline: "none"
|
|
1651
|
-
}
|
|
1652
|
-
}
|
|
1653
|
-
),
|
|
1654
|
-
/* @__PURE__ */ jsx2(
|
|
1655
|
-
"button",
|
|
1656
|
-
{
|
|
1657
|
-
onClick: () => client.invalidateAll(),
|
|
1658
|
-
title: "Invalidate All Queries",
|
|
1659
|
-
style: {
|
|
1660
|
-
background: "#222",
|
|
1661
|
-
border: "1px solid #333",
|
|
1662
|
-
color: "#d69e2e",
|
|
1663
|
-
borderRadius: "4px",
|
|
1664
|
-
padding: "0 12px",
|
|
1665
|
-
cursor: "pointer",
|
|
1666
|
-
fontSize: "12px",
|
|
1667
|
-
fontWeight: 500
|
|
1668
|
-
},
|
|
1669
|
-
children: "\u21BB Invalidate All"
|
|
1670
|
-
}
|
|
1671
|
-
)
|
|
1672
|
-
] }),
|
|
1673
|
-
/* @__PURE__ */ jsx2("div", { style: {
|
|
1674
|
-
flex: 1,
|
|
1675
|
-
overflowY: "auto",
|
|
1676
|
-
padding: "8px",
|
|
1677
|
-
display: "flex",
|
|
1678
|
-
flexDirection: "column",
|
|
1679
|
-
gap: "8px",
|
|
1680
|
-
background: "#050505"
|
|
1681
|
-
}, children: entries.length === 0 ? /* @__PURE__ */ jsxs("div", { style: {
|
|
1682
|
-
padding: "40px",
|
|
1683
|
-
textAlign: "center",
|
|
1684
|
-
color: "#444",
|
|
1685
|
-
fontStyle: "italic"
|
|
1686
|
-
}, children: [
|
|
1687
|
-
"No active queries in cache.",
|
|
1688
|
-
/* @__PURE__ */ jsx2("br", {}),
|
|
1689
|
-
/* @__PURE__ */ jsx2("span", { style: { fontSize: "11px", opacity: 0.7 }, children: "(Note: Only `useQuery` calls appear here. Raw `api.get` calls are not cached globally.)" })
|
|
1690
|
-
] }) : filteredEntries.map(([keyHash, entry]) => /* @__PURE__ */ jsx2(
|
|
1691
|
-
QueryItem,
|
|
1692
|
-
{
|
|
1693
|
-
entry,
|
|
1694
|
-
client,
|
|
1695
|
-
isStale: client.isStale(entry.key)
|
|
1696
|
-
},
|
|
1697
|
-
keyHash
|
|
1698
|
-
)) })
|
|
1699
|
-
]
|
|
1700
|
-
}
|
|
1701
|
-
);
|
|
1702
|
-
}
|
|
1703
|
-
function QueryItem({ entry, client, isStale }) {
|
|
1704
|
-
const [expanded, setExpanded] = useState5(false);
|
|
1705
|
-
return /* @__PURE__ */ jsxs("div", { style: {
|
|
1706
|
-
background: "#111",
|
|
1707
|
-
borderRadius: "6px",
|
|
1708
|
-
border: "1px solid #222",
|
|
1709
|
-
overflow: "hidden"
|
|
1710
|
-
}, children: [
|
|
1711
|
-
/* @__PURE__ */ jsxs(
|
|
1712
|
-
"div",
|
|
1713
|
-
{
|
|
1714
|
-
onClick: () => setExpanded(!expanded),
|
|
1715
|
-
style: {
|
|
1716
|
-
padding: "8px 12px",
|
|
1717
|
-
display: "flex",
|
|
1718
|
-
alignItems: "center",
|
|
1719
|
-
justifyContent: "space-between",
|
|
1720
|
-
cursor: "pointer",
|
|
1721
|
-
background: expanded ? "#161616" : "transparent"
|
|
1722
|
-
},
|
|
1723
|
-
children: [
|
|
1724
|
-
/* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: "10px", alignItems: "center", overflow: "hidden" }, children: [
|
|
1725
|
-
/* @__PURE__ */ jsx2("span", { style: {
|
|
1726
|
-
color: isStale ? "#d69e2e" : "#b0fb5d",
|
|
1727
|
-
fontSize: "14px",
|
|
1728
|
-
fontWeight: "bold",
|
|
1729
|
-
minWidth: "10px"
|
|
1730
|
-
}, children: isStale ? "\u2022" : "\u2022" }),
|
|
1731
|
-
/* @__PURE__ */ jsxs("span", { style: {
|
|
1732
|
-
color: "#e0e0e0",
|
|
1733
|
-
fontWeight: 500,
|
|
1734
|
-
whiteSpace: "nowrap",
|
|
1735
|
-
overflow: "hidden",
|
|
1736
|
-
textOverflow: "ellipsis"
|
|
1737
|
-
}, children: [
|
|
1738
|
-
"['",
|
|
1739
|
-
entry.key.join("', '"),
|
|
1740
|
-
"']"
|
|
1741
|
-
] })
|
|
1742
|
-
] }),
|
|
1743
|
-
/* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: "8px", alignItems: "center" }, children: [
|
|
1744
|
-
/* @__PURE__ */ jsx2("span", { style: {
|
|
1745
|
-
fontSize: "10px",
|
|
1746
|
-
padding: "2px 6px",
|
|
1747
|
-
borderRadius: "3px",
|
|
1748
|
-
background: isStale ? "rgba(214, 158, 46, 0.15)" : "rgba(176, 251, 93, 0.15)",
|
|
1749
|
-
color: isStale ? "#d69e2e" : "#b0fb5d",
|
|
1750
|
-
border: `1px solid ${isStale ? "rgba(214, 158, 46, 0.3)" : "rgba(176, 251, 93, 0.3)"}`
|
|
1751
|
-
}, children: isStale ? "STALE" : "FRESH" }),
|
|
1752
|
-
/* @__PURE__ */ jsx2("span", { style: { color: "#666", fontSize: "10px" }, children: expanded ? "\u25BC" : "\u25B6" })
|
|
1753
|
-
] })
|
|
1754
|
-
]
|
|
1755
|
-
}
|
|
1756
|
-
),
|
|
1757
|
-
expanded && /* @__PURE__ */ jsxs("div", { style: {
|
|
1758
|
-
padding: "10px",
|
|
1759
|
-
borderTop: "1px solid #222",
|
|
1760
|
-
background: "#0a0a0a"
|
|
1761
|
-
}, children: [
|
|
1762
|
-
/* @__PURE__ */ jsxs("div", { style: {
|
|
1763
|
-
display: "flex",
|
|
1764
|
-
gap: "8px",
|
|
1765
|
-
marginBottom: "10px",
|
|
1766
|
-
borderBottom: "1px solid #222",
|
|
1767
|
-
paddingBottom: "8px"
|
|
1768
|
-
}, children: [
|
|
1769
|
-
/* @__PURE__ */ jsx2(
|
|
1770
|
-
"button",
|
|
1771
|
-
{
|
|
1772
|
-
onClick: (e) => {
|
|
1773
|
-
e.stopPropagation();
|
|
1774
|
-
client.invalidate(entry.key);
|
|
1775
|
-
},
|
|
1776
|
-
style: {
|
|
1777
|
-
background: "#222",
|
|
1778
|
-
border: "1px solid #333",
|
|
1779
|
-
color: "#d69e2e",
|
|
1780
|
-
padding: "4px 10px",
|
|
1781
|
-
borderRadius: "4px",
|
|
1782
|
-
cursor: "pointer",
|
|
1783
|
-
fontSize: "11px"
|
|
1784
|
-
},
|
|
1785
|
-
children: "Invalidate"
|
|
1786
|
-
}
|
|
1787
|
-
),
|
|
1788
|
-
/* @__PURE__ */ jsx2(
|
|
1789
|
-
"button",
|
|
1790
|
-
{
|
|
1791
|
-
onClick: (e) => {
|
|
1792
|
-
e.stopPropagation();
|
|
1793
|
-
client.remove(entry.key);
|
|
1794
|
-
},
|
|
1795
|
-
style: {
|
|
1796
|
-
background: "#222",
|
|
1797
|
-
border: "1px solid #333",
|
|
1798
|
-
color: "#ff4d4f",
|
|
1799
|
-
padding: "4px 10px",
|
|
1800
|
-
borderRadius: "4px",
|
|
1801
|
-
cursor: "pointer",
|
|
1802
|
-
fontSize: "11px"
|
|
1803
|
-
},
|
|
1804
|
-
children: "Remove"
|
|
1805
|
-
}
|
|
1806
|
-
)
|
|
1807
|
-
] }),
|
|
1808
|
-
/* @__PURE__ */ jsx2("div", { style: { position: "relative" }, children: /* @__PURE__ */ jsx2("pre", { style: {
|
|
1809
|
-
margin: 0,
|
|
1810
|
-
fontSize: "11px",
|
|
1811
|
-
color: "#a0a0a0",
|
|
1812
|
-
overflowX: "auto",
|
|
1813
|
-
fontFamily: "monospace"
|
|
1814
|
-
}, children: JSON.stringify(entry.data, null, 2) }) }),
|
|
1815
|
-
/* @__PURE__ */ jsxs("div", { style: {
|
|
1816
|
-
marginTop: "8px",
|
|
1817
|
-
fontSize: "10px",
|
|
1818
|
-
color: "#444",
|
|
1819
|
-
textAlign: "right"
|
|
1820
|
-
}, children: [
|
|
1821
|
-
"Updated: ",
|
|
1822
|
-
new Date(entry.updatedAt).toLocaleTimeString()
|
|
1823
|
-
] })
|
|
1824
|
-
] })
|
|
1825
|
-
] });
|
|
1982
|
+
}, [observer]);
|
|
1983
|
+
return observer.result$;
|
|
1826
1984
|
}
|
|
1827
1985
|
export {
|
|
1828
|
-
|
|
1829
|
-
|
|
1986
|
+
HydrationBoundary,
|
|
1987
|
+
QueryClient,
|
|
1830
1988
|
QueryClientProvider,
|
|
1831
|
-
|
|
1989
|
+
SignalValue,
|
|
1990
|
+
atom,
|
|
1832
1991
|
createHttpClient,
|
|
1833
|
-
|
|
1834
|
-
defineModel,
|
|
1992
|
+
dehydrate,
|
|
1835
1993
|
enableDevTools,
|
|
1836
1994
|
getPromiseState,
|
|
1837
1995
|
handlePromise,
|
|
1996
|
+
hydrate,
|
|
1838
1997
|
isPromise,
|
|
1839
|
-
optimisticHelpers,
|
|
1840
|
-
queryCache,
|
|
1841
1998
|
scheduleUpdate,
|
|
1842
|
-
subscribe,
|
|
1843
1999
|
unwrapPromise,
|
|
1844
2000
|
useInfiniteQuery,
|
|
1845
2001
|
useMutation,
|
|
1846
2002
|
usePaginatedQuery,
|
|
1847
2003
|
useQuery,
|
|
1848
|
-
|
|
2004
|
+
useQuery$,
|
|
1849
2005
|
useQueryClient,
|
|
1850
|
-
|
|
2006
|
+
useQueryStore,
|
|
2007
|
+
useSuspenseQuery
|
|
1851
2008
|
};
|