sibujs 1.4.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +105 -119
- package/dist/browser.cjs +288 -80
- package/dist/browser.d.cts +19 -9
- package/dist/browser.d.ts +19 -9
- package/dist/browser.js +6 -6
- package/dist/build.cjs +1019 -313
- package/dist/build.d.cts +1 -1
- package/dist/build.d.ts +1 -1
- package/dist/build.js +15 -13
- package/dist/cdn.global.js +17 -16
- package/dist/chunk-2RA7SHDA.js +65 -0
- package/dist/chunk-2UPRY23K.js +80 -0
- package/dist/chunk-3JHCYHWN.js +125 -0
- package/dist/{chunk-ZWKZCBO6.js → chunk-3LR7GLWQ.js} +154 -33
- package/dist/{chunk-3AIRKM3B.js → chunk-3NSGB5JN.js} +115 -34
- package/dist/{chunk-3ARAQO7B.js → chunk-52YJLLRO.js} +29 -6
- package/dist/chunk-54EDRCEF.js +93 -0
- package/dist/chunk-7JDB7I65.js +1327 -0
- package/dist/{chunk-WZSPOOER.js → chunk-CC65Y57T.js} +8 -5
- package/dist/{chunk-23VV7YD3.js → chunk-DFPFITST.js} +25 -30
- package/dist/{chunk-WR5D4EGH.js → chunk-GTBNNBJ6.js} +14 -2
- package/dist/chunk-HB24TBAF.js +121 -0
- package/dist/{chunk-CZUGLNJS.js → chunk-ITX6OO3F.js} +3 -3
- package/dist/{chunk-JAKHTMQU.js → chunk-JA6667UN.js} +206 -46
- package/dist/{chunk-77L6NL3X.js → chunk-JXMMDLBY.js} +306 -183
- package/dist/{chunk-3X2YG6YM.js → chunk-JYD2PWXH.js} +59 -28
- package/dist/{chunk-F3FA4F32.js → chunk-KLRMB5ZS.js} +135 -79
- package/dist/{chunk-5X6PP2UK.js → chunk-LMLD24FC.js} +2 -2
- package/dist/{chunk-M4NLBH4I.js → chunk-LYTCUZ7H.js} +3 -2
- package/dist/{chunk-TSOKIX5Z.js → chunk-MIUAXB7K.js} +126 -74
- package/dist/{chunk-QWZG56ET.js → chunk-ND2664SF.js} +558 -190
- package/dist/{chunk-JCI5M6U6.js → chunk-O2MNQFLP.js} +261 -79
- package/dist/{chunk-EWFVA3TJ.js → chunk-R73P76YZ.js} +1 -1
- package/dist/{chunk-2BYQDGN3.js → chunk-SAHNHTFC.js} +234 -63
- package/dist/chunk-UCS6AMJ7.js +79 -0
- package/dist/{chunk-ZD6OAMTH.js → chunk-VLPPXTYG.js} +90 -35
- package/dist/{chunk-OUZZEE4S.js → chunk-WOMYAHHI.js} +17 -11
- package/dist/{contracts-xo5ckdRP.d.cts → contracts-ey_Qh8ef.d.cts} +7 -8
- package/dist/{contracts-xo5ckdRP.d.ts → contracts-ey_Qh8ef.d.ts} +7 -8
- package/dist/{customElement-D2DJp_xn.d.cts → customElement-CPfIrbvg.d.cts} +18 -9
- package/dist/{customElement-D2DJp_xn.d.ts → customElement-CPfIrbvg.d.ts} +18 -9
- package/dist/data.cjs +452 -100
- package/dist/data.d.cts +20 -2
- package/dist/data.d.ts +20 -2
- package/dist/data.js +11 -9
- package/dist/devtools.cjs +535 -247
- package/dist/devtools.d.cts +1 -1
- package/dist/devtools.d.ts +1 -1
- package/dist/devtools.js +34 -30
- package/dist/ecosystem.cjs +499 -143
- package/dist/ecosystem.d.cts +13 -11
- package/dist/ecosystem.d.ts +13 -11
- package/dist/ecosystem.js +12 -11
- package/dist/extras.cjs +3639 -1629
- package/dist/extras.d.cts +11 -11
- package/dist/extras.d.ts +11 -11
- package/dist/extras.js +58 -45
- package/dist/index.cjs +1023 -313
- package/dist/index.d.cts +128 -55
- package/dist/index.d.ts +128 -55
- package/dist/index.js +28 -16
- package/dist/{introspect-BumjnBKr.d.cts → introspect-BWNjNw64.d.cts} +22 -2
- package/dist/{introspect-CZrlcaYy.d.ts → introspect-cY2pg9pW.d.ts} +22 -2
- package/dist/motion.cjs +90 -36
- package/dist/motion.d.cts +1 -1
- package/dist/motion.d.ts +1 -1
- package/dist/motion.js +4 -4
- package/dist/patterns.cjs +414 -81
- package/dist/patterns.d.cts +53 -20
- package/dist/patterns.d.ts +53 -20
- package/dist/patterns.js +7 -7
- package/dist/performance.cjs +364 -108
- package/dist/performance.d.cts +29 -17
- package/dist/performance.d.ts +29 -17
- package/dist/performance.js +13 -6
- package/dist/plugin-D30wlGW5.d.cts +71 -0
- package/dist/plugin-D30wlGW5.d.ts +71 -0
- package/dist/plugins.cjs +652 -271
- package/dist/plugins.d.cts +13 -6
- package/dist/plugins.d.ts +13 -6
- package/dist/plugins.js +116 -50
- package/dist/{ssr-Do_SiVoL.d.cts → ssr-CrVNy6Pa.d.cts} +9 -15
- package/dist/{ssr-Do_SiVoL.d.ts → ssr-CrVNy6Pa.d.ts} +9 -15
- package/dist/{ssr-4PBXAOO3.js → ssr-FXD2PPMC.js} +4 -3
- package/dist/ssr.cjs +648 -219
- package/dist/ssr.d.cts +27 -7
- package/dist/ssr.d.ts +27 -7
- package/dist/ssr.js +12 -11
- package/dist/{tagFactory-DaJ0YWX6.d.ts → tagFactory-S17H2qxu.d.cts} +9 -1
- package/dist/{tagFactory-DaJ0YWX6.d.cts → tagFactory-S17H2qxu.d.ts} +9 -1
- package/dist/testing.cjs +252 -63
- package/dist/testing.d.cts +17 -4
- package/dist/testing.d.ts +17 -4
- package/dist/testing.js +100 -44
- package/dist/ui.cjs +576 -168
- package/dist/ui.d.cts +13 -16
- package/dist/ui.d.ts +13 -16
- package/dist/ui.js +20 -17
- package/dist/widgets.cjs +1001 -93
- package/dist/widgets.d.cts +104 -2
- package/dist/widgets.d.ts +104 -2
- package/dist/widgets.js +9 -7
- package/package.json +8 -2
- package/dist/chunk-32DY64NT.js +0 -282
- package/dist/chunk-3CRQALYP.js +0 -877
- package/dist/chunk-4EI4AG32.js +0 -482
- package/dist/chunk-4MYMUBRS.js +0 -21
- package/dist/chunk-6HLLIF3K.js +0 -398
- package/dist/chunk-6LSNVCS2.js +0 -937
- package/dist/chunk-6SA3QQES.js +0 -61
- package/dist/chunk-7BF6TK55.js +0 -1097
- package/dist/chunk-7TQKR4PP.js +0 -294
- package/dist/chunk-7V26P53V.js +0 -712
- package/dist/chunk-AZ3ISID5.js +0 -298
- package/dist/chunk-B7SWRFUT.js +0 -332
- package/dist/chunk-BGN5ZMP4.js +0 -26
- package/dist/chunk-BTU3TJDS.js +0 -365
- package/dist/chunk-BW3WT46K.js +0 -937
- package/dist/chunk-C6KFWOFV.js +0 -616
- package/dist/chunk-CHF5OHIA.js +0 -61
- package/dist/chunk-CHJ27IGK.js +0 -26
- package/dist/chunk-CMBFNA7L.js +0 -27
- package/dist/chunk-DAHRH4ON.js +0 -331
- package/dist/chunk-DKOHBI74.js +0 -924
- package/dist/chunk-DTCOOBMX.js +0 -725
- package/dist/chunk-EBGIRKQY.js +0 -616
- package/dist/chunk-EUZND3CB.js +0 -27
- package/dist/chunk-EVCZO745.js +0 -365
- package/dist/chunk-FGOEVHY3.js +0 -60
- package/dist/chunk-G3BOQPVO.js +0 -365
- package/dist/chunk-GCOK2LC3.js +0 -282
- package/dist/chunk-HGMJFBC7.js +0 -654
- package/dist/chunk-K5ZUMYVS.js +0 -89
- package/dist/chunk-KQPDEVVS.js +0 -398
- package/dist/chunk-L6JRBDNS.js +0 -60
- package/dist/chunk-LA6KQEDU.js +0 -712
- package/dist/chunk-MDVXJWFN.js +0 -304
- package/dist/chunk-MEZVEBPN.js +0 -2008
- package/dist/chunk-MK4ERFYL.js +0 -2249
- package/dist/chunk-MLKGABMK.js +0 -9
- package/dist/chunk-MQ5GOYPH.js +0 -2249
- package/dist/chunk-N6IZB6KJ.js +0 -567
- package/dist/chunk-NEKUBFPT.js +0 -60
- package/dist/chunk-NHUC2QWH.js +0 -282
- package/dist/chunk-NMRUZALC.js +0 -1097
- package/dist/chunk-NYVAC6P5.js +0 -37
- package/dist/chunk-OF7UZIVB.js +0 -725
- package/dist/chunk-P6W3STU4.js +0 -2249
- package/dist/chunk-PBHF5WKN.js +0 -616
- package/dist/chunk-PTQJDMRT.js +0 -146
- package/dist/chunk-PZEGYCF5.js +0 -61
- package/dist/chunk-QBMDLBU2.js +0 -975
- package/dist/chunk-RQGQSLQK.js +0 -725
- package/dist/chunk-SDLZDHKP.js +0 -107
- package/dist/chunk-TNQWPPE6.js +0 -37
- package/dist/chunk-UHNL42EF.js +0 -2730
- package/dist/chunk-UNXCEF6S.js +0 -21
- package/dist/chunk-V2XTI523.js +0 -347
- package/dist/chunk-VAU366PN.js +0 -2241
- package/dist/chunk-VMVDTCXB.js +0 -712
- package/dist/chunk-VRW3FULF.js +0 -725
- package/dist/chunk-WADYRCO2.js +0 -304
- package/dist/chunk-WILQZRO4.js +0 -282
- package/dist/chunk-WUHJISPP.js +0 -298
- package/dist/chunk-XYU6TZOW.js +0 -182
- package/dist/chunk-Y6GP4QGG.js +0 -276
- package/dist/chunk-YECR7UIA.js +0 -347
- package/dist/chunk-YUTWTI4B.js +0 -654
- package/dist/chunk-Z65KYU7I.js +0 -26
- package/dist/chunk-Z6POF5YC.js +0 -975
- package/dist/chunk-ZBJP6WFL.js +0 -482
- package/dist/contracts-DDrwxvJ-.d.cts +0 -245
- package/dist/contracts-DDrwxvJ-.d.ts +0 -245
- package/dist/contracts-DOrhwbke.d.cts +0 -245
- package/dist/contracts-DOrhwbke.d.ts +0 -245
- package/dist/customElement-BKQfbSZQ.d.cts +0 -262
- package/dist/customElement-BKQfbSZQ.d.ts +0 -262
- package/dist/customElement-yz8uyk-0.d.cts +0 -308
- package/dist/customElement-yz8uyk-0.d.ts +0 -308
- package/dist/introspect-Cb0zgpi2.d.cts +0 -477
- package/dist/introspect-Y2xNXGSf.d.ts +0 -477
- package/dist/plugin-Bek4RhJY.d.cts +0 -43
- package/dist/plugin-Bek4RhJY.d.ts +0 -43
- package/dist/ssr-3RXHP5ES.js +0 -38
- package/dist/ssr-6GIMY5MX.js +0 -38
- package/dist/ssr-BA6sxxUd.d.cts +0 -135
- package/dist/ssr-BA6sxxUd.d.ts +0 -135
- package/dist/ssr-WKUPVSSK.js +0 -36
- package/dist/tagFactory-Dl8QCLga.d.cts +0 -23
- package/dist/tagFactory-Dl8QCLga.d.ts +0 -23
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import {
|
|
2
2
|
context
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-GTBNNBJ6.js";
|
|
4
4
|
import {
|
|
5
5
|
derived
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-54EDRCEF.js";
|
|
7
7
|
import {
|
|
8
8
|
sanitizeUrl
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-UCS6AMJ7.js";
|
|
10
10
|
import {
|
|
11
11
|
effect
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-HB24TBAF.js";
|
|
13
13
|
import {
|
|
14
14
|
batch,
|
|
15
15
|
signal
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-CC65Y57T.js";
|
|
17
17
|
|
|
18
18
|
// src/data/retry.ts
|
|
19
19
|
function calculateDelay(attempt, strategy, baseDelay, maxDelay, jitter) {
|
|
@@ -30,10 +30,12 @@ function calculateDelay(attempt, strategy, baseDelay, maxDelay, jitter) {
|
|
|
30
30
|
break;
|
|
31
31
|
}
|
|
32
32
|
delay = Math.min(delay, maxDelay);
|
|
33
|
+
if (!Number.isFinite(delay)) delay = Number.MAX_SAFE_INTEGER;
|
|
33
34
|
if (jitter > 0) {
|
|
34
35
|
const jitterRange = delay * jitter;
|
|
35
36
|
delay += (Math.random() * 2 - 1) * jitterRange;
|
|
36
37
|
}
|
|
38
|
+
if (!Number.isFinite(delay) || Number.isNaN(delay)) delay = 0;
|
|
37
39
|
return Math.max(0, delay);
|
|
38
40
|
}
|
|
39
41
|
async function withRetry(fn, options, onRetry, signal2) {
|
|
@@ -47,6 +49,7 @@ async function withRetry(fn, options, onRetry, signal2) {
|
|
|
47
49
|
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
48
50
|
if (signal2?.aborted) throw new DOMException("Aborted", "AbortError");
|
|
49
51
|
try {
|
|
52
|
+
if (signal2?.aborted) throw new DOMException("Aborted", "AbortError");
|
|
50
53
|
return await fn();
|
|
51
54
|
} catch (error) {
|
|
52
55
|
lastError = error;
|
|
@@ -54,9 +57,13 @@ async function withRetry(fn, options, onRetry, signal2) {
|
|
|
54
57
|
const delay = calculateDelay(attempt, strategy, baseDelay, maxDelay, jitter);
|
|
55
58
|
onRetry?.(error, attempt, delay);
|
|
56
59
|
await new Promise((resolve, reject) => {
|
|
57
|
-
|
|
60
|
+
let onAbort = null;
|
|
61
|
+
const timer = setTimeout(() => {
|
|
62
|
+
if (onAbort && signal2) signal2.removeEventListener("abort", onAbort);
|
|
63
|
+
resolve();
|
|
64
|
+
}, delay);
|
|
58
65
|
if (signal2) {
|
|
59
|
-
|
|
66
|
+
onAbort = () => {
|
|
60
67
|
clearTimeout(timer);
|
|
61
68
|
reject(new DOMException("Aborted", "AbortError"));
|
|
62
69
|
};
|
|
@@ -124,24 +131,46 @@ function query(key, fetcher, options = {}) {
|
|
|
124
131
|
let entry = queryCache.get(key2);
|
|
125
132
|
if (!entry) {
|
|
126
133
|
entry = getOrCreateEntry(key2);
|
|
127
|
-
entry.subscribers++;
|
|
128
134
|
entry.listeners.add(onCacheUpdate);
|
|
129
135
|
entry.refetchers.add(doFetch);
|
|
130
136
|
}
|
|
131
137
|
if (entry.promise) {
|
|
132
138
|
setIsFetching(true);
|
|
139
|
+
const captured = entry.promise;
|
|
133
140
|
try {
|
|
134
|
-
await
|
|
141
|
+
await captured;
|
|
142
|
+
if (disposed || currentKey !== key2) return;
|
|
143
|
+
if (entry.promise === captured) {
|
|
144
|
+
onCacheUpdate();
|
|
145
|
+
if (entry.error) onError?.(entry.error);
|
|
146
|
+
else if (entry.data !== void 0) onSuccess?.(entry.data);
|
|
147
|
+
}
|
|
135
148
|
} catch {
|
|
149
|
+
if (disposed || currentKey !== key2) return;
|
|
150
|
+
if (entry.promise === captured) {
|
|
151
|
+
onCacheUpdate();
|
|
152
|
+
if (entry.error) onError?.(entry.error);
|
|
153
|
+
}
|
|
154
|
+
} finally {
|
|
155
|
+
if (!disposed && currentKey === key2) onSettled?.();
|
|
136
156
|
}
|
|
137
|
-
onCacheUpdate();
|
|
138
157
|
return;
|
|
139
158
|
}
|
|
140
159
|
abortController?.abort();
|
|
141
160
|
abortController = new AbortController();
|
|
142
161
|
const signal2 = abortController.signal;
|
|
143
162
|
setIsFetching(true);
|
|
144
|
-
|
|
163
|
+
let promise;
|
|
164
|
+
try {
|
|
165
|
+
promise = withRetry(() => fetcher({ signal: signal2, key: key2 }), retryOptions, void 0, signal2);
|
|
166
|
+
} catch (err) {
|
|
167
|
+
setIsFetching(false);
|
|
168
|
+
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
169
|
+
entry.error = errorObj;
|
|
170
|
+
onError?.(errorObj);
|
|
171
|
+
onSettled?.();
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
145
174
|
entry.promise = promise;
|
|
146
175
|
try {
|
|
147
176
|
const result = await promise;
|
|
@@ -203,13 +232,15 @@ function query(key, fetcher, options = {}) {
|
|
|
203
232
|
oldEntry.subscribers--;
|
|
204
233
|
if (oldEntry.subscribers <= 0 && cacheTime >= 0) {
|
|
205
234
|
const oldKey = currentKey;
|
|
235
|
+
if (oldEntry.gcTimer !== null) clearTimeout(oldEntry.gcTimer);
|
|
206
236
|
oldEntry.gcTimer = setTimeout(() => queryCache.delete(oldKey), cacheTime);
|
|
207
237
|
}
|
|
208
238
|
}
|
|
209
239
|
}
|
|
240
|
+
const keyChanged = currentKey !== key2;
|
|
210
241
|
currentKey = key2;
|
|
211
242
|
const entry = getOrCreateEntry(key2, initialData);
|
|
212
|
-
entry.subscribers++;
|
|
243
|
+
if (keyChanged) entry.subscribers++;
|
|
213
244
|
if (entry.gcTimer !== null) {
|
|
214
245
|
clearTimeout(entry.gcTimer);
|
|
215
246
|
entry.gcTimer = null;
|
|
@@ -224,6 +255,11 @@ function query(key, fetcher, options = {}) {
|
|
|
224
255
|
setError(entry.error);
|
|
225
256
|
});
|
|
226
257
|
}
|
|
258
|
+
if (!keyChanged && currentKey === key2 && entry.data !== void 0) {
|
|
259
|
+
const isDataStale2 = entry.dataUpdatedAt === 0 || Date.now() - entry.dataUpdatedAt >= staleTime;
|
|
260
|
+
if (enabled && isDataStale2 && !entry.promise) doFetch();
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
227
263
|
const isDataStale = entry.dataUpdatedAt === 0 || Date.now() - entry.dataUpdatedAt >= staleTime;
|
|
228
264
|
if (enabled && (entry.data === void 0 || isDataStale)) {
|
|
229
265
|
doFetch();
|
|
@@ -251,6 +287,7 @@ function query(key, fetcher, options = {}) {
|
|
|
251
287
|
}
|
|
252
288
|
}
|
|
253
289
|
function dispose() {
|
|
290
|
+
if (disposed) return;
|
|
254
291
|
disposed = true;
|
|
255
292
|
abortController?.abort();
|
|
256
293
|
effectCleanup();
|
|
@@ -263,12 +300,17 @@ function query(key, fetcher, options = {}) {
|
|
|
263
300
|
entry.subscribers--;
|
|
264
301
|
if (entry.subscribers <= 0 && cacheTime >= 0) {
|
|
265
302
|
const key2 = currentKey;
|
|
303
|
+
if (entry.gcTimer !== null) clearTimeout(entry.gcTimer);
|
|
266
304
|
entry.gcTimer = setTimeout(() => queryCache.delete(key2), cacheTime);
|
|
267
305
|
}
|
|
268
306
|
}
|
|
269
307
|
}
|
|
270
|
-
if (focusHandler
|
|
271
|
-
|
|
308
|
+
if (focusHandler && typeof globalThis.removeEventListener === "function") {
|
|
309
|
+
globalThis.removeEventListener("focus", focusHandler);
|
|
310
|
+
}
|
|
311
|
+
if (onlineHandler && typeof globalThis.removeEventListener === "function") {
|
|
312
|
+
globalThis.removeEventListener("online", onlineHandler);
|
|
313
|
+
}
|
|
272
314
|
}
|
|
273
315
|
return {
|
|
274
316
|
data,
|
|
@@ -312,7 +354,19 @@ function clearQueryCache() {
|
|
|
312
354
|
}
|
|
313
355
|
queryCache.clear();
|
|
314
356
|
for (const listener of activeListeners) listener();
|
|
315
|
-
for (const refetcher of activeRefetchers)
|
|
357
|
+
for (const refetcher of activeRefetchers) {
|
|
358
|
+
refetcher().catch((err) => {
|
|
359
|
+
if (typeof console !== "undefined") {
|
|
360
|
+
console.warn("[SibuJS query] refetch after clearQueryCache failed:", err);
|
|
361
|
+
}
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
function __resetQueryCache() {
|
|
366
|
+
for (const entry of queryCache.values()) {
|
|
367
|
+
if (entry.gcTimer) clearTimeout(entry.gcTimer);
|
|
368
|
+
}
|
|
369
|
+
queryCache.clear();
|
|
316
370
|
}
|
|
317
371
|
|
|
318
372
|
// src/data/mutation.ts
|
|
@@ -323,7 +377,9 @@ function mutation(mutationFn, options = {}) {
|
|
|
323
377
|
const [status, setStatus] = signal("idle");
|
|
324
378
|
const isSuccess = derived(() => status() === "success");
|
|
325
379
|
const isIdle = derived(() => status() === "idle");
|
|
380
|
+
let runId = 0;
|
|
326
381
|
async function execute(variables) {
|
|
382
|
+
const myRun = ++runId;
|
|
327
383
|
let context2;
|
|
328
384
|
batch(() => {
|
|
329
385
|
setLoading(true);
|
|
@@ -335,6 +391,7 @@ function mutation(mutationFn, options = {}) {
|
|
|
335
391
|
context2 = await options.onMutate(variables);
|
|
336
392
|
}
|
|
337
393
|
const result = await withRetry(() => mutationFn(variables), options.retry);
|
|
394
|
+
if (myRun !== runId) return result;
|
|
338
395
|
batch(() => {
|
|
339
396
|
setData(result);
|
|
340
397
|
setLoading(false);
|
|
@@ -345,6 +402,7 @@ function mutation(mutationFn, options = {}) {
|
|
|
345
402
|
return result;
|
|
346
403
|
} catch (err) {
|
|
347
404
|
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
405
|
+
if (myRun !== runId) throw errorObj;
|
|
348
406
|
batch(() => {
|
|
349
407
|
setError(errorObj);
|
|
350
408
|
setLoading(false);
|
|
@@ -356,6 +414,7 @@ function mutation(mutationFn, options = {}) {
|
|
|
356
414
|
}
|
|
357
415
|
}
|
|
358
416
|
function reset() {
|
|
417
|
+
runId++;
|
|
359
418
|
batch(() => {
|
|
360
419
|
setData(void 0);
|
|
361
420
|
setError(void 0);
|
|
@@ -370,7 +429,10 @@ function mutation(mutationFn, options = {}) {
|
|
|
370
429
|
isSuccess,
|
|
371
430
|
isIdle,
|
|
372
431
|
mutate: (variables) => {
|
|
373
|
-
execute(variables).catch(() => {
|
|
432
|
+
execute(variables).catch((err) => {
|
|
433
|
+
if (typeof console !== "undefined") {
|
|
434
|
+
console.warn("[SibuJS mutation] mutate() failed; check `.error()` signal or onError option.", err);
|
|
435
|
+
}
|
|
374
436
|
});
|
|
375
437
|
},
|
|
376
438
|
mutateAsync: execute,
|
|
@@ -406,11 +468,13 @@ function infiniteQuery(key, fetcher, options) {
|
|
|
406
468
|
const hasPreviousPage = derived(() => prevPageParam() !== void 0);
|
|
407
469
|
let abortController = null;
|
|
408
470
|
let disposed = false;
|
|
471
|
+
let runId = 0;
|
|
409
472
|
async function fetchPage(pageParam, direction) {
|
|
410
473
|
if (disposed) return;
|
|
411
474
|
abortController?.abort();
|
|
412
475
|
abortController = new AbortController();
|
|
413
476
|
const signal2 = abortController.signal;
|
|
477
|
+
const myRun = ++runId;
|
|
414
478
|
batch(() => {
|
|
415
479
|
setIsFetching(true);
|
|
416
480
|
if (direction === "next") setIsFetchingNext(true);
|
|
@@ -419,7 +483,7 @@ function infiniteQuery(key, fetcher, options) {
|
|
|
419
483
|
});
|
|
420
484
|
try {
|
|
421
485
|
const page = await withRetry(() => fetcher({ signal: signal2, pageParam }), retryOptions, void 0, signal2);
|
|
422
|
-
if (disposed) return;
|
|
486
|
+
if (disposed || myRun !== runId) return;
|
|
423
487
|
const currentPages = pages();
|
|
424
488
|
let newPages;
|
|
425
489
|
if (direction === "prev") {
|
|
@@ -439,7 +503,7 @@ function infiniteQuery(key, fetcher, options) {
|
|
|
439
503
|
});
|
|
440
504
|
onSuccess?.(newPages);
|
|
441
505
|
} catch (err) {
|
|
442
|
-
if (disposed) return;
|
|
506
|
+
if (disposed || myRun !== runId) return;
|
|
443
507
|
if (err instanceof DOMException && err.name === "AbortError") return;
|
|
444
508
|
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
445
509
|
batch(() => {
|
|
@@ -454,9 +518,12 @@ function infiniteQuery(key, fetcher, options) {
|
|
|
454
518
|
const effectCleanup = effect(() => {
|
|
455
519
|
resolveKey();
|
|
456
520
|
if (enabled) {
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
521
|
+
abortController?.abort();
|
|
522
|
+
batch(() => {
|
|
523
|
+
setPages([]);
|
|
524
|
+
setNextPageParam(initialPageParam);
|
|
525
|
+
setPrevPageParam(void 0);
|
|
526
|
+
});
|
|
460
527
|
fetchPage(initialPageParam, "initial");
|
|
461
528
|
}
|
|
462
529
|
});
|
|
@@ -605,7 +672,10 @@ function resource(sourceOrFetcher, fetcherOrOptions, maybeOptions) {
|
|
|
605
672
|
options.onSuccess?.(result);
|
|
606
673
|
} catch (err) {
|
|
607
674
|
if (version !== fetchVersion || disposed) return;
|
|
608
|
-
if (err instanceof DOMException && err.name === "AbortError")
|
|
675
|
+
if (err instanceof DOMException && err.name === "AbortError") {
|
|
676
|
+
if (version === fetchVersion) setLoading(false);
|
|
677
|
+
return;
|
|
678
|
+
}
|
|
609
679
|
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
610
680
|
batch(() => {
|
|
611
681
|
setError(errorObj);
|
|
@@ -690,18 +760,57 @@ function idbPut(db, store, item) {
|
|
|
690
760
|
tx.onerror = () => reject(tx.error);
|
|
691
761
|
});
|
|
692
762
|
}
|
|
693
|
-
function
|
|
763
|
+
function idbPutWithChange(db, item, change) {
|
|
764
|
+
return new Promise((resolve, reject) => {
|
|
765
|
+
const tx = db.transaction(["items", "_changes"], "readwrite");
|
|
766
|
+
tx.objectStore("items").put(item);
|
|
767
|
+
tx.objectStore("_changes").put(change);
|
|
768
|
+
tx.oncomplete = () => resolve();
|
|
769
|
+
tx.onerror = () => reject(tx.error);
|
|
770
|
+
});
|
|
771
|
+
}
|
|
772
|
+
function idbDeleteWithChange(db, key, change) {
|
|
773
|
+
return new Promise((resolve, reject) => {
|
|
774
|
+
const tx = db.transaction(["items", "_changes"], "readwrite");
|
|
775
|
+
tx.objectStore("items").delete(key);
|
|
776
|
+
tx.objectStore("_changes").put(change);
|
|
777
|
+
tx.oncomplete = () => resolve();
|
|
778
|
+
tx.onerror = () => reject(tx.error);
|
|
779
|
+
});
|
|
780
|
+
}
|
|
781
|
+
function idbGetAllWithKeys(db, store) {
|
|
782
|
+
return new Promise((resolve, reject) => {
|
|
783
|
+
const tx = db.transaction(store, "readonly");
|
|
784
|
+
const out = [];
|
|
785
|
+
const req = tx.objectStore(store).openCursor();
|
|
786
|
+
req.onsuccess = () => {
|
|
787
|
+
const cursor = req.result;
|
|
788
|
+
if (cursor) {
|
|
789
|
+
out.push({ key: cursor.primaryKey, value: cursor.value });
|
|
790
|
+
cursor.continue();
|
|
791
|
+
} else {
|
|
792
|
+
resolve(out);
|
|
793
|
+
}
|
|
794
|
+
};
|
|
795
|
+
req.onerror = () => reject(req.error);
|
|
796
|
+
});
|
|
797
|
+
}
|
|
798
|
+
function idbDeleteKeys(db, store, keys) {
|
|
799
|
+
if (keys.length === 0) return Promise.resolve();
|
|
694
800
|
return new Promise((resolve, reject) => {
|
|
695
801
|
const tx = db.transaction(store, "readwrite");
|
|
696
|
-
tx.objectStore(store)
|
|
802
|
+
const objStore = tx.objectStore(store);
|
|
803
|
+
for (const k of keys) objStore.delete(k);
|
|
697
804
|
tx.oncomplete = () => resolve();
|
|
698
805
|
tx.onerror = () => reject(tx.error);
|
|
699
806
|
});
|
|
700
807
|
}
|
|
701
|
-
function
|
|
808
|
+
function idbPutMany(db, store, items) {
|
|
809
|
+
if (items.length === 0) return Promise.resolve();
|
|
702
810
|
return new Promise((resolve, reject) => {
|
|
703
811
|
const tx = db.transaction(store, "readwrite");
|
|
704
|
-
tx.objectStore(store)
|
|
812
|
+
const objStore = tx.objectStore(store);
|
|
813
|
+
for (const item of items) objStore.put(item);
|
|
705
814
|
tx.oncomplete = () => resolve();
|
|
706
815
|
tx.onerror = () => reject(tx.error);
|
|
707
816
|
});
|
|
@@ -724,15 +833,13 @@ async function offlineStore(options) {
|
|
|
724
833
|
setPendingCount(changes.length);
|
|
725
834
|
}
|
|
726
835
|
async function put(item) {
|
|
727
|
-
await
|
|
728
|
-
await idbPut(db, "_changes", { type: "put", item, timestamp: Date.now() });
|
|
836
|
+
await idbPutWithChange(db, item, { type: "put", item, timestamp: Date.now() });
|
|
729
837
|
await refreshData();
|
|
730
838
|
}
|
|
731
839
|
async function remove(key) {
|
|
732
840
|
const existing = await idbGet(db, "items", key);
|
|
733
841
|
if (existing) {
|
|
734
|
-
await
|
|
735
|
-
await idbPut(db, "_changes", { type: "delete", item: existing, timestamp: Date.now() });
|
|
842
|
+
await idbDeleteWithChange(db, key, { type: "delete", item: existing, timestamp: Date.now() });
|
|
736
843
|
await refreshData();
|
|
737
844
|
}
|
|
738
845
|
}
|
|
@@ -743,25 +850,45 @@ async function offlineStore(options) {
|
|
|
743
850
|
return data().filter(filter);
|
|
744
851
|
}
|
|
745
852
|
async function sync() {
|
|
746
|
-
if (!adapter || isSyncing()) return;
|
|
853
|
+
if (!adapter || isSyncing() || closed) return;
|
|
747
854
|
setIsSyncing(true);
|
|
748
855
|
try {
|
|
749
|
-
const
|
|
750
|
-
if (
|
|
751
|
-
|
|
856
|
+
const snapshot = await idbGetAllWithKeys(db, "_changes");
|
|
857
|
+
if (closed) return;
|
|
858
|
+
if (snapshot.length > 0) {
|
|
859
|
+
const result = await adapter.push(snapshot.map((e) => e.value));
|
|
860
|
+
if (closed) return;
|
|
752
861
|
if (result.ok) {
|
|
753
|
-
await
|
|
862
|
+
await idbDeleteKeys(
|
|
863
|
+
db,
|
|
864
|
+
"_changes",
|
|
865
|
+
snapshot.map((e) => e.key)
|
|
866
|
+
);
|
|
867
|
+
if (closed) return;
|
|
754
868
|
}
|
|
755
869
|
}
|
|
756
870
|
const remoteItems = await adapter.pull(lastSynced());
|
|
757
|
-
|
|
758
|
-
|
|
871
|
+
if (closed) return;
|
|
872
|
+
const pendingChanges = await idbGetAll(db, "_changes");
|
|
873
|
+
if (closed) return;
|
|
874
|
+
const pendingKeys = /* @__PURE__ */ new Set();
|
|
875
|
+
for (const c of pendingChanges) {
|
|
876
|
+
const k = c.item[keyPath];
|
|
877
|
+
if (k != null) pendingKeys.add(k);
|
|
759
878
|
}
|
|
879
|
+
const safeRemote = remoteItems.filter((item) => {
|
|
880
|
+
const k = item[keyPath];
|
|
881
|
+
return k == null || !pendingKeys.has(k);
|
|
882
|
+
});
|
|
883
|
+
await idbPutMany(db, "items", safeRemote);
|
|
884
|
+
if (closed) return;
|
|
760
885
|
const now = Date.now();
|
|
761
886
|
await idbPut(db, "_meta", now);
|
|
887
|
+
if (closed) return;
|
|
762
888
|
setLastSynced(now);
|
|
763
889
|
await refreshData();
|
|
764
|
-
} catch {
|
|
890
|
+
} catch (err) {
|
|
891
|
+
if (typeof console !== "undefined") console.warn("[offlineStore] sync failed", err);
|
|
765
892
|
} finally {
|
|
766
893
|
setIsSyncing(false);
|
|
767
894
|
}
|
|
@@ -769,13 +896,21 @@ async function offlineStore(options) {
|
|
|
769
896
|
function attach(newAdapter) {
|
|
770
897
|
adapter = newAdapter;
|
|
771
898
|
}
|
|
899
|
+
let onlineHandler = null;
|
|
900
|
+
let closed = false;
|
|
772
901
|
function close() {
|
|
902
|
+
closed = true;
|
|
903
|
+
if (onlineHandler && typeof window !== "undefined") {
|
|
904
|
+
window.removeEventListener("online", onlineHandler);
|
|
905
|
+
onlineHandler = null;
|
|
906
|
+
}
|
|
773
907
|
db.close();
|
|
774
908
|
}
|
|
775
909
|
if (autoSync && typeof window !== "undefined") {
|
|
776
|
-
|
|
910
|
+
onlineHandler = () => {
|
|
777
911
|
sync();
|
|
778
|
-
}
|
|
912
|
+
};
|
|
913
|
+
window.addEventListener("online", onlineHandler);
|
|
779
914
|
}
|
|
780
915
|
return {
|
|
781
916
|
data,
|
|
@@ -813,9 +948,16 @@ function loaderData() {
|
|
|
813
948
|
error: resource2.error
|
|
814
949
|
};
|
|
815
950
|
}
|
|
816
|
-
async function preloadRoute(route, context2) {
|
|
951
|
+
async function preloadRoute(route, context2, callerSignal) {
|
|
817
952
|
if (!route.loader) return void 0;
|
|
818
953
|
const controller = new AbortController();
|
|
954
|
+
if (callerSignal) {
|
|
955
|
+
if (callerSignal.aborted) {
|
|
956
|
+
controller.abort();
|
|
957
|
+
} else {
|
|
958
|
+
callerSignal.addEventListener("abort", () => controller.abort(), { once: true });
|
|
959
|
+
}
|
|
960
|
+
}
|
|
819
961
|
return route.loader(context2, { signal: controller.signal });
|
|
820
962
|
}
|
|
821
963
|
|
|
@@ -830,7 +972,7 @@ function validateWsUrl(raw) {
|
|
|
830
972
|
function socket(url, options) {
|
|
831
973
|
const autoReconnect = options?.autoReconnect ?? false;
|
|
832
974
|
const reconnectDelay = options?.reconnectDelay ?? 1e3;
|
|
833
|
-
const maxReconnects = options?.maxReconnects ??
|
|
975
|
+
const maxReconnects = options?.maxReconnects ?? 10;
|
|
834
976
|
const heartbeat = options?.heartbeat;
|
|
835
977
|
const protocols = options?.protocols;
|
|
836
978
|
const [data, setData] = signal(null);
|
|
@@ -840,6 +982,7 @@ function socket(url, options) {
|
|
|
840
982
|
let reconnectTimer = null;
|
|
841
983
|
let heartbeatTimer = null;
|
|
842
984
|
let disposed = false;
|
|
985
|
+
let manuallyClosed = false;
|
|
843
986
|
function getUrl() {
|
|
844
987
|
return typeof url === "function" ? url() : url;
|
|
845
988
|
}
|
|
@@ -863,11 +1006,18 @@ function socket(url, options) {
|
|
|
863
1006
|
ws.onclose = () => {
|
|
864
1007
|
setStatus("closed");
|
|
865
1008
|
stopHeartbeat();
|
|
866
|
-
|
|
1009
|
+
const wasManual = manuallyClosed;
|
|
1010
|
+
manuallyClosed = false;
|
|
1011
|
+
if (autoReconnect && !disposed && !wasManual && reconnectCount < maxReconnects) {
|
|
1012
|
+
const cap = 3e4;
|
|
1013
|
+
const delay = Math.min(cap, reconnectDelay * 2 ** reconnectCount);
|
|
1014
|
+
const jittered = delay * (0.5 + Math.random() * 0.5);
|
|
867
1015
|
reconnectCount++;
|
|
868
1016
|
reconnectTimer = setTimeout(() => {
|
|
1017
|
+
reconnectTimer = null;
|
|
1018
|
+
if (disposed || manuallyClosed) return;
|
|
869
1019
|
connect();
|
|
870
|
-
},
|
|
1020
|
+
}, jittered);
|
|
871
1021
|
}
|
|
872
1022
|
};
|
|
873
1023
|
ws.onerror = () => {
|
|
@@ -894,6 +1044,7 @@ function socket(url, options) {
|
|
|
894
1044
|
}
|
|
895
1045
|
}
|
|
896
1046
|
function close() {
|
|
1047
|
+
manuallyClosed = true;
|
|
897
1048
|
if (reconnectTimer !== null) {
|
|
898
1049
|
clearTimeout(reconnectTimer);
|
|
899
1050
|
reconnectTimer = null;
|
|
@@ -920,12 +1071,16 @@ function validateSseUrl(raw) {
|
|
|
920
1071
|
}
|
|
921
1072
|
function stream(url, options) {
|
|
922
1073
|
const autoReconnect = options?.autoReconnect ?? false;
|
|
1074
|
+
const maxReconnects = options?.maxReconnects ?? 10;
|
|
1075
|
+
const baseMs = options?.reconnectBaseMs ?? 1e3;
|
|
1076
|
+
const maxMs = options?.reconnectMaxMs ?? 3e4;
|
|
923
1077
|
const [data, setData] = signal(null);
|
|
924
1078
|
const [event, setEvent] = signal(null);
|
|
925
1079
|
const [status, setStatus] = signal("connecting");
|
|
926
1080
|
let source = null;
|
|
927
1081
|
let disposed = false;
|
|
928
1082
|
let reconnectTimer = null;
|
|
1083
|
+
let attempts = 0;
|
|
929
1084
|
function connect() {
|
|
930
1085
|
if (disposed) return;
|
|
931
1086
|
const safeUrl = validateSseUrl(url);
|
|
@@ -939,6 +1094,7 @@ function stream(url, options) {
|
|
|
939
1094
|
});
|
|
940
1095
|
source.onopen = () => {
|
|
941
1096
|
setStatus("open");
|
|
1097
|
+
attempts = 0;
|
|
942
1098
|
};
|
|
943
1099
|
source.onmessage = (evt) => {
|
|
944
1100
|
setData(evt.data);
|
|
@@ -948,11 +1104,14 @@ function stream(url, options) {
|
|
|
948
1104
|
if (source && source.readyState === EventSource.CLOSED) {
|
|
949
1105
|
setStatus("closed");
|
|
950
1106
|
source = null;
|
|
951
|
-
if (autoReconnect && !disposed) {
|
|
1107
|
+
if (autoReconnect && !disposed && attempts < maxReconnects) {
|
|
1108
|
+
const delay = Math.min(maxMs, baseMs * 2 ** attempts);
|
|
1109
|
+
const jittered = delay * (0.5 + Math.random() * 0.5);
|
|
1110
|
+
attempts++;
|
|
952
1111
|
reconnectTimer = setTimeout(() => {
|
|
953
1112
|
reconnectTimer = null;
|
|
954
1113
|
connect();
|
|
955
|
-
},
|
|
1114
|
+
}, jittered);
|
|
956
1115
|
}
|
|
957
1116
|
}
|
|
958
1117
|
};
|
|
@@ -984,6 +1143,7 @@ export {
|
|
|
984
1143
|
getQueryData,
|
|
985
1144
|
setQueryData,
|
|
986
1145
|
clearQueryCache,
|
|
1146
|
+
__resetQueryCache,
|
|
987
1147
|
mutation,
|
|
988
1148
|
infiniteQuery,
|
|
989
1149
|
previous,
|