sibujs 1.5.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.
Files changed (207) hide show
  1. package/dist/browser.cjs +238 -69
  2. package/dist/browser.d.cts +5 -0
  3. package/dist/browser.d.ts +5 -0
  4. package/dist/browser.js +6 -6
  5. package/dist/build.cjs +916 -292
  6. package/dist/build.js +15 -13
  7. package/dist/cdn.global.js +17 -16
  8. package/dist/chunk-2RA7SHDA.js +65 -0
  9. package/dist/chunk-2UPRY23K.js +80 -0
  10. package/dist/chunk-3JHCYHWN.js +125 -0
  11. package/dist/{chunk-VAPYJN4X.js → chunk-3LR7GLWQ.js} +93 -23
  12. package/dist/{chunk-RJ46C3CS.js → chunk-3NSGB5JN.js} +71 -20
  13. package/dist/{chunk-XUEEGU5O.js → chunk-52YJLLRO.js} +16 -4
  14. package/dist/{chunk-XHK6BDAJ.js → chunk-54EDRCEF.js} +25 -8
  15. package/dist/chunk-7JDB7I65.js +1327 -0
  16. package/dist/{chunk-WZSPOOER.js → chunk-CC65Y57T.js} +8 -5
  17. package/dist/{chunk-23VV7YD3.js → chunk-DFPFITST.js} +25 -30
  18. package/dist/{chunk-BGN5ZMP4.js → chunk-GTBNNBJ6.js} +14 -2
  19. package/dist/chunk-HB24TBAF.js +121 -0
  20. package/dist/{chunk-CZUGLNJS.js → chunk-ITX6OO3F.js} +3 -3
  21. package/dist/{chunk-BGTHZHJ5.js → chunk-JA6667UN.js} +188 -44
  22. package/dist/{chunk-7GRNSCFT.js → chunk-JXMMDLBY.js} +306 -183
  23. package/dist/{chunk-3X2YG6YM.js → chunk-JYD2PWXH.js} +59 -28
  24. package/dist/{chunk-SFKNRVCU.js → chunk-KLRMB5ZS.js} +135 -79
  25. package/dist/{chunk-5X6PP2UK.js → chunk-LMLD24FC.js} +2 -2
  26. package/dist/{chunk-M4NLBH4I.js → chunk-LYTCUZ7H.js} +3 -2
  27. package/dist/{chunk-BMPL52BF.js → chunk-MIUAXB7K.js} +118 -66
  28. package/dist/{chunk-JCDUJN2F.js → chunk-ND2664SF.js} +486 -153
  29. package/dist/{chunk-VQDZK23A.js → chunk-O2MNQFLP.js} +181 -66
  30. package/dist/{chunk-NHUC2QWH.js → chunk-R73P76YZ.js} +1 -1
  31. package/dist/{chunk-2BYQDGN3.js → chunk-SAHNHTFC.js} +234 -63
  32. package/dist/chunk-UCS6AMJ7.js +79 -0
  33. package/dist/{chunk-K4G4ZQNR.js → chunk-VLPPXTYG.js} +84 -38
  34. package/dist/{chunk-OUZZEE4S.js → chunk-WOMYAHHI.js} +17 -11
  35. package/dist/{customElement-BL3Uo8dL.d.cts → customElement-CPfIrbvg.d.cts} +14 -10
  36. package/dist/{customElement-BL3Uo8dL.d.ts → customElement-CPfIrbvg.d.ts} +14 -10
  37. package/dist/data.cjs +410 -99
  38. package/dist/data.d.cts +20 -2
  39. package/dist/data.d.ts +20 -2
  40. package/dist/data.js +11 -9
  41. package/dist/devtools.cjs +513 -223
  42. package/dist/devtools.d.cts +1 -1
  43. package/dist/devtools.d.ts +1 -1
  44. package/dist/devtools.js +12 -6
  45. package/dist/ecosystem.cjs +475 -144
  46. package/dist/ecosystem.d.cts +9 -7
  47. package/dist/ecosystem.d.ts +9 -7
  48. package/dist/ecosystem.js +12 -11
  49. package/dist/extras.cjs +3355 -1541
  50. package/dist/extras.d.cts +9 -9
  51. package/dist/extras.d.ts +9 -9
  52. package/dist/extras.js +58 -45
  53. package/dist/index.cjs +920 -292
  54. package/dist/index.d.cts +71 -8
  55. package/dist/index.d.ts +71 -8
  56. package/dist/index.js +28 -16
  57. package/dist/{introspect-BumjnBKr.d.cts → introspect-BWNjNw64.d.cts} +22 -2
  58. package/dist/{introspect-CZrlcaYy.d.ts → introspect-cY2pg9pW.d.ts} +22 -2
  59. package/dist/motion.cjs +77 -34
  60. package/dist/motion.js +4 -4
  61. package/dist/patterns.cjs +335 -69
  62. package/dist/patterns.d.cts +11 -12
  63. package/dist/patterns.d.ts +11 -12
  64. package/dist/patterns.js +7 -7
  65. package/dist/performance.cjs +279 -108
  66. package/dist/performance.d.cts +23 -16
  67. package/dist/performance.d.ts +23 -16
  68. package/dist/performance.js +13 -8
  69. package/dist/plugin-D30wlGW5.d.cts +71 -0
  70. package/dist/plugin-D30wlGW5.d.ts +71 -0
  71. package/dist/plugins.cjs +635 -260
  72. package/dist/plugins.d.cts +10 -3
  73. package/dist/plugins.d.ts +10 -3
  74. package/dist/plugins.js +106 -38
  75. package/dist/{ssr-Do_SiVoL.d.cts → ssr-CrVNy6Pa.d.cts} +9 -15
  76. package/dist/{ssr-Do_SiVoL.d.ts → ssr-CrVNy6Pa.d.ts} +9 -15
  77. package/dist/{ssr-4PBXAOO3.js → ssr-FXD2PPMC.js} +4 -3
  78. package/dist/ssr.cjs +642 -222
  79. package/dist/ssr.d.cts +26 -6
  80. package/dist/ssr.d.ts +26 -6
  81. package/dist/ssr.js +12 -11
  82. package/dist/{tagFactory-DaJ0YWX6.d.cts → tagFactory-S17H2qxu.d.cts} +9 -1
  83. package/dist/{tagFactory-DaJ0YWX6.d.ts → tagFactory-S17H2qxu.d.ts} +9 -1
  84. package/dist/testing.cjs +252 -63
  85. package/dist/testing.d.cts +17 -4
  86. package/dist/testing.d.ts +17 -4
  87. package/dist/testing.js +100 -44
  88. package/dist/ui.cjs +463 -137
  89. package/dist/ui.d.cts +1 -1
  90. package/dist/ui.d.ts +1 -1
  91. package/dist/ui.js +20 -17
  92. package/dist/widgets.cjs +977 -94
  93. package/dist/widgets.d.cts +104 -2
  94. package/dist/widgets.d.ts +104 -2
  95. package/dist/widgets.js +9 -7
  96. package/package.json +8 -2
  97. package/dist/chunk-32DY64NT.js +0 -282
  98. package/dist/chunk-3AIRKM3B.js +0 -1263
  99. package/dist/chunk-3ARAQO7B.js +0 -398
  100. package/dist/chunk-3CRQALYP.js +0 -877
  101. package/dist/chunk-4EI4AG32.js +0 -482
  102. package/dist/chunk-4MYMUBRS.js +0 -21
  103. package/dist/chunk-5ZYQ6KDD.js +0 -154
  104. package/dist/chunk-6BMPXPUW.js +0 -26
  105. package/dist/chunk-6HLLIF3K.js +0 -398
  106. package/dist/chunk-6LSNVCS2.js +0 -937
  107. package/dist/chunk-6SA3QQES.js +0 -61
  108. package/dist/chunk-77L6NL3X.js +0 -1097
  109. package/dist/chunk-7BF6TK55.js +0 -1097
  110. package/dist/chunk-7TQKR4PP.js +0 -294
  111. package/dist/chunk-7V26P53V.js +0 -712
  112. package/dist/chunk-AZ3ISID5.js +0 -298
  113. package/dist/chunk-B7SWRFUT.js +0 -332
  114. package/dist/chunk-BTU3TJDS.js +0 -365
  115. package/dist/chunk-BW3WT46K.js +0 -937
  116. package/dist/chunk-C6KFWOFV.js +0 -616
  117. package/dist/chunk-CHF5OHIA.js +0 -61
  118. package/dist/chunk-CHJ27IGK.js +0 -26
  119. package/dist/chunk-CMBFNA7L.js +0 -27
  120. package/dist/chunk-DAHRH4ON.js +0 -331
  121. package/dist/chunk-DKOHBI74.js +0 -924
  122. package/dist/chunk-DTCOOBMX.js +0 -725
  123. package/dist/chunk-EBGIRKQY.js +0 -616
  124. package/dist/chunk-EUZND3CB.js +0 -27
  125. package/dist/chunk-EVCZO745.js +0 -365
  126. package/dist/chunk-EWFVA3TJ.js +0 -282
  127. package/dist/chunk-F3FA4F32.js +0 -292
  128. package/dist/chunk-FGOEVHY3.js +0 -60
  129. package/dist/chunk-G3BOQPVO.js +0 -365
  130. package/dist/chunk-GCOK2LC3.js +0 -282
  131. package/dist/chunk-GJPXRJ45.js +0 -37
  132. package/dist/chunk-HGMJFBC7.js +0 -654
  133. package/dist/chunk-JAKHTMQU.js +0 -1000
  134. package/dist/chunk-JCI5M6U6.js +0 -956
  135. package/dist/chunk-K5ZUMYVS.js +0 -89
  136. package/dist/chunk-KQPDEVVS.js +0 -398
  137. package/dist/chunk-L6JRBDNS.js +0 -60
  138. package/dist/chunk-LA6KQEDU.js +0 -712
  139. package/dist/chunk-MB6QFH3I.js +0 -2776
  140. package/dist/chunk-MDVXJWFN.js +0 -304
  141. package/dist/chunk-MEZVEBPN.js +0 -2008
  142. package/dist/chunk-MK4ERFYL.js +0 -2249
  143. package/dist/chunk-MLKGABMK.js +0 -9
  144. package/dist/chunk-MQ5GOYPH.js +0 -2249
  145. package/dist/chunk-MYRV7VDM.js +0 -742
  146. package/dist/chunk-N6IZB6KJ.js +0 -567
  147. package/dist/chunk-NEKUBFPT.js +0 -60
  148. package/dist/chunk-NMRUZALC.js +0 -1097
  149. package/dist/chunk-NYVAC6P5.js +0 -37
  150. package/dist/chunk-NZIIMDWI.js +0 -84
  151. package/dist/chunk-OF7UZIVB.js +0 -725
  152. package/dist/chunk-P3XWXJZU.js +0 -282
  153. package/dist/chunk-P6W3STU4.js +0 -2249
  154. package/dist/chunk-PBHF5WKN.js +0 -616
  155. package/dist/chunk-PDZQY43A.js +0 -616
  156. package/dist/chunk-PTQJDMRT.js +0 -146
  157. package/dist/chunk-PZEGYCF5.js +0 -61
  158. package/dist/chunk-QBMDLBU2.js +0 -975
  159. package/dist/chunk-QWZG56ET.js +0 -2744
  160. package/dist/chunk-RQGQSLQK.js +0 -725
  161. package/dist/chunk-SDLZDHKP.js +0 -107
  162. package/dist/chunk-TDGZL5CU.js +0 -365
  163. package/dist/chunk-TNQWPPE6.js +0 -37
  164. package/dist/chunk-TSOKIX5Z.js +0 -654
  165. package/dist/chunk-UHNL42EF.js +0 -2730
  166. package/dist/chunk-UNXCEF6S.js +0 -21
  167. package/dist/chunk-V2XTI523.js +0 -347
  168. package/dist/chunk-VAU366PN.js +0 -2241
  169. package/dist/chunk-VMVDTCXB.js +0 -712
  170. package/dist/chunk-VQNQZCWJ.js +0 -61
  171. package/dist/chunk-VRW3FULF.js +0 -725
  172. package/dist/chunk-WADYRCO2.js +0 -304
  173. package/dist/chunk-WILQZRO4.js +0 -282
  174. package/dist/chunk-WR5D4EGH.js +0 -26
  175. package/dist/chunk-WUHJISPP.js +0 -298
  176. package/dist/chunk-XYU6TZOW.js +0 -182
  177. package/dist/chunk-Y6GP4QGG.js +0 -276
  178. package/dist/chunk-YECR7UIA.js +0 -347
  179. package/dist/chunk-YUTWTI4B.js +0 -654
  180. package/dist/chunk-Z65KYU7I.js +0 -26
  181. package/dist/chunk-Z6POF5YC.js +0 -975
  182. package/dist/chunk-ZBJP6WFL.js +0 -482
  183. package/dist/chunk-ZD6OAMTH.js +0 -277
  184. package/dist/chunk-ZWKZCBO6.js +0 -317
  185. package/dist/contracts-DDrwxvJ-.d.cts +0 -245
  186. package/dist/contracts-DDrwxvJ-.d.ts +0 -245
  187. package/dist/contracts-DOrhwbke.d.cts +0 -245
  188. package/dist/contracts-DOrhwbke.d.ts +0 -245
  189. package/dist/contracts-xo5ckdRP.d.cts +0 -240
  190. package/dist/contracts-xo5ckdRP.d.ts +0 -240
  191. package/dist/customElement-BKQfbSZQ.d.cts +0 -262
  192. package/dist/customElement-BKQfbSZQ.d.ts +0 -262
  193. package/dist/customElement-D2DJp_xn.d.cts +0 -313
  194. package/dist/customElement-D2DJp_xn.d.ts +0 -313
  195. package/dist/customElement-yz8uyk-0.d.cts +0 -308
  196. package/dist/customElement-yz8uyk-0.d.ts +0 -308
  197. package/dist/introspect-Cb0zgpi2.d.cts +0 -477
  198. package/dist/introspect-Y2xNXGSf.d.ts +0 -477
  199. package/dist/plugin-Bek4RhJY.d.cts +0 -43
  200. package/dist/plugin-Bek4RhJY.d.ts +0 -43
  201. package/dist/ssr-3RXHP5ES.js +0 -38
  202. package/dist/ssr-6GIMY5MX.js +0 -38
  203. package/dist/ssr-BA6sxxUd.d.cts +0 -135
  204. package/dist/ssr-BA6sxxUd.d.ts +0 -135
  205. package/dist/ssr-WKUPVSSK.js +0 -36
  206. package/dist/tagFactory-Dl8QCLga.d.cts +0 -23
  207. package/dist/tagFactory-Dl8QCLga.d.ts +0 -23
@@ -1,19 +1,19 @@
1
1
  import {
2
2
  context
3
- } from "./chunk-6BMPXPUW.js";
3
+ } from "./chunk-GTBNNBJ6.js";
4
4
  import {
5
5
  derived
6
- } from "./chunk-XHK6BDAJ.js";
6
+ } from "./chunk-54EDRCEF.js";
7
7
  import {
8
8
  sanitizeUrl
9
- } from "./chunk-CMBFNA7L.js";
9
+ } from "./chunk-UCS6AMJ7.js";
10
10
  import {
11
11
  effect
12
- } from "./chunk-VQNQZCWJ.js";
12
+ } from "./chunk-HB24TBAF.js";
13
13
  import {
14
14
  batch,
15
15
  signal
16
- } from "./chunk-NZIIMDWI.js";
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;
@@ -128,24 +131,46 @@ function query(key, fetcher, options = {}) {
128
131
  let entry = queryCache.get(key2);
129
132
  if (!entry) {
130
133
  entry = getOrCreateEntry(key2);
131
- entry.subscribers++;
132
134
  entry.listeners.add(onCacheUpdate);
133
135
  entry.refetchers.add(doFetch);
134
136
  }
135
137
  if (entry.promise) {
136
138
  setIsFetching(true);
139
+ const captured = entry.promise;
137
140
  try {
138
- await entry.promise;
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
+ }
139
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?.();
140
156
  }
141
- onCacheUpdate();
142
157
  return;
143
158
  }
144
159
  abortController?.abort();
145
160
  abortController = new AbortController();
146
161
  const signal2 = abortController.signal;
147
162
  setIsFetching(true);
148
- const promise = withRetry(() => fetcher({ signal: signal2, key: key2 }), retryOptions, void 0, signal2);
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
+ }
149
174
  entry.promise = promise;
150
175
  try {
151
176
  const result = await promise;
@@ -207,6 +232,7 @@ function query(key, fetcher, options = {}) {
207
232
  oldEntry.subscribers--;
208
233
  if (oldEntry.subscribers <= 0 && cacheTime >= 0) {
209
234
  const oldKey = currentKey;
235
+ if (oldEntry.gcTimer !== null) clearTimeout(oldEntry.gcTimer);
210
236
  oldEntry.gcTimer = setTimeout(() => queryCache.delete(oldKey), cacheTime);
211
237
  }
212
238
  }
@@ -214,7 +240,7 @@ function query(key, fetcher, options = {}) {
214
240
  const keyChanged = currentKey !== key2;
215
241
  currentKey = key2;
216
242
  const entry = getOrCreateEntry(key2, initialData);
217
- if (keyChanged || entry.subscribers === 0) entry.subscribers++;
243
+ if (keyChanged) entry.subscribers++;
218
244
  if (entry.gcTimer !== null) {
219
245
  clearTimeout(entry.gcTimer);
220
246
  entry.gcTimer = null;
@@ -229,6 +255,11 @@ function query(key, fetcher, options = {}) {
229
255
  setError(entry.error);
230
256
  });
231
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
+ }
232
263
  const isDataStale = entry.dataUpdatedAt === 0 || Date.now() - entry.dataUpdatedAt >= staleTime;
233
264
  if (enabled && (entry.data === void 0 || isDataStale)) {
234
265
  doFetch();
@@ -256,6 +287,7 @@ function query(key, fetcher, options = {}) {
256
287
  }
257
288
  }
258
289
  function dispose() {
290
+ if (disposed) return;
259
291
  disposed = true;
260
292
  abortController?.abort();
261
293
  effectCleanup();
@@ -268,12 +300,17 @@ function query(key, fetcher, options = {}) {
268
300
  entry.subscribers--;
269
301
  if (entry.subscribers <= 0 && cacheTime >= 0) {
270
302
  const key2 = currentKey;
303
+ if (entry.gcTimer !== null) clearTimeout(entry.gcTimer);
271
304
  entry.gcTimer = setTimeout(() => queryCache.delete(key2), cacheTime);
272
305
  }
273
306
  }
274
307
  }
275
- if (focusHandler) globalThis.removeEventListener("focus", focusHandler);
276
- if (onlineHandler) globalThis.removeEventListener("online", onlineHandler);
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
+ }
277
314
  }
278
315
  return {
279
316
  data,
@@ -317,7 +354,19 @@ function clearQueryCache() {
317
354
  }
318
355
  queryCache.clear();
319
356
  for (const listener of activeListeners) listener();
320
- for (const refetcher of activeRefetchers) refetcher();
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();
321
370
  }
322
371
 
323
372
  // src/data/mutation.ts
@@ -380,7 +429,10 @@ function mutation(mutationFn, options = {}) {
380
429
  isSuccess,
381
430
  isIdle,
382
431
  mutate: (variables) => {
383
- 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
+ }
384
436
  });
385
437
  },
386
438
  mutateAsync: execute,
@@ -416,11 +468,13 @@ function infiniteQuery(key, fetcher, options) {
416
468
  const hasPreviousPage = derived(() => prevPageParam() !== void 0);
417
469
  let abortController = null;
418
470
  let disposed = false;
471
+ let runId = 0;
419
472
  async function fetchPage(pageParam, direction) {
420
473
  if (disposed) return;
421
474
  abortController?.abort();
422
475
  abortController = new AbortController();
423
476
  const signal2 = abortController.signal;
477
+ const myRun = ++runId;
424
478
  batch(() => {
425
479
  setIsFetching(true);
426
480
  if (direction === "next") setIsFetchingNext(true);
@@ -429,7 +483,7 @@ function infiniteQuery(key, fetcher, options) {
429
483
  });
430
484
  try {
431
485
  const page = await withRetry(() => fetcher({ signal: signal2, pageParam }), retryOptions, void 0, signal2);
432
- if (disposed) return;
486
+ if (disposed || myRun !== runId) return;
433
487
  const currentPages = pages();
434
488
  let newPages;
435
489
  if (direction === "prev") {
@@ -449,7 +503,7 @@ function infiniteQuery(key, fetcher, options) {
449
503
  });
450
504
  onSuccess?.(newPages);
451
505
  } catch (err) {
452
- if (disposed) return;
506
+ if (disposed || myRun !== runId) return;
453
507
  if (err instanceof DOMException && err.name === "AbortError") return;
454
508
  const errorObj = err instanceof Error ? err : new Error(String(err));
455
509
  batch(() => {
@@ -464,9 +518,12 @@ function infiniteQuery(key, fetcher, options) {
464
518
  const effectCleanup = effect(() => {
465
519
  resolveKey();
466
520
  if (enabled) {
467
- setPages([]);
468
- setNextPageParam(initialPageParam);
469
- setPrevPageParam(void 0);
521
+ abortController?.abort();
522
+ batch(() => {
523
+ setPages([]);
524
+ setNextPageParam(initialPageParam);
525
+ setPrevPageParam(void 0);
526
+ });
470
527
  fetchPage(initialPageParam, "initial");
471
528
  }
472
529
  });
@@ -703,18 +760,57 @@ function idbPut(db, store, item) {
703
760
  tx.onerror = () => reject(tx.error);
704
761
  });
705
762
  }
706
- function idbDelete(db, store, key) {
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();
707
800
  return new Promise((resolve, reject) => {
708
801
  const tx = db.transaction(store, "readwrite");
709
- tx.objectStore(store).delete(key);
802
+ const objStore = tx.objectStore(store);
803
+ for (const k of keys) objStore.delete(k);
710
804
  tx.oncomplete = () => resolve();
711
805
  tx.onerror = () => reject(tx.error);
712
806
  });
713
807
  }
714
- function idbClear(db, store) {
808
+ function idbPutMany(db, store, items) {
809
+ if (items.length === 0) return Promise.resolve();
715
810
  return new Promise((resolve, reject) => {
716
811
  const tx = db.transaction(store, "readwrite");
717
- tx.objectStore(store).clear();
812
+ const objStore = tx.objectStore(store);
813
+ for (const item of items) objStore.put(item);
718
814
  tx.oncomplete = () => resolve();
719
815
  tx.onerror = () => reject(tx.error);
720
816
  });
@@ -737,15 +833,13 @@ async function offlineStore(options) {
737
833
  setPendingCount(changes.length);
738
834
  }
739
835
  async function put(item) {
740
- await idbPut(db, "items", item);
741
- await idbPut(db, "_changes", { type: "put", item, timestamp: Date.now() });
836
+ await idbPutWithChange(db, item, { type: "put", item, timestamp: Date.now() });
742
837
  await refreshData();
743
838
  }
744
839
  async function remove(key) {
745
840
  const existing = await idbGet(db, "items", key);
746
841
  if (existing) {
747
- await idbDelete(db, "items", key);
748
- await idbPut(db, "_changes", { type: "delete", item: existing, timestamp: Date.now() });
842
+ await idbDeleteWithChange(db, key, { type: "delete", item: existing, timestamp: Date.now() });
749
843
  await refreshData();
750
844
  }
751
845
  }
@@ -756,25 +850,45 @@ async function offlineStore(options) {
756
850
  return data().filter(filter);
757
851
  }
758
852
  async function sync() {
759
- if (!adapter || isSyncing()) return;
853
+ if (!adapter || isSyncing() || closed) return;
760
854
  setIsSyncing(true);
761
855
  try {
762
- const changes = await idbGetAll(db, "_changes");
763
- if (changes.length > 0) {
764
- const result = await adapter.push(changes);
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;
765
861
  if (result.ok) {
766
- await idbClear(db, "_changes");
862
+ await idbDeleteKeys(
863
+ db,
864
+ "_changes",
865
+ snapshot.map((e) => e.key)
866
+ );
867
+ if (closed) return;
767
868
  }
768
869
  }
769
870
  const remoteItems = await adapter.pull(lastSynced());
770
- for (const item of remoteItems) {
771
- await idbPut(db, "items", item);
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);
772
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;
773
885
  const now = Date.now();
774
886
  await idbPut(db, "_meta", now);
887
+ if (closed) return;
775
888
  setLastSynced(now);
776
889
  await refreshData();
777
- } catch {
890
+ } catch (err) {
891
+ if (typeof console !== "undefined") console.warn("[offlineStore] sync failed", err);
778
892
  } finally {
779
893
  setIsSyncing(false);
780
894
  }
@@ -782,13 +896,21 @@ async function offlineStore(options) {
782
896
  function attach(newAdapter) {
783
897
  adapter = newAdapter;
784
898
  }
899
+ let onlineHandler = null;
900
+ let closed = false;
785
901
  function close() {
902
+ closed = true;
903
+ if (onlineHandler && typeof window !== "undefined") {
904
+ window.removeEventListener("online", onlineHandler);
905
+ onlineHandler = null;
906
+ }
786
907
  db.close();
787
908
  }
788
909
  if (autoSync && typeof window !== "undefined") {
789
- window.addEventListener("online", () => {
910
+ onlineHandler = () => {
790
911
  sync();
791
- });
912
+ };
913
+ window.addEventListener("online", onlineHandler);
792
914
  }
793
915
  return {
794
916
  data,
@@ -826,9 +948,16 @@ function loaderData() {
826
948
  error: resource2.error
827
949
  };
828
950
  }
829
- async function preloadRoute(route, context2) {
951
+ async function preloadRoute(route, context2, callerSignal) {
830
952
  if (!route.loader) return void 0;
831
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
+ }
832
961
  return route.loader(context2, { signal: controller.signal });
833
962
  }
834
963
 
@@ -843,7 +972,7 @@ function validateWsUrl(raw) {
843
972
  function socket(url, options) {
844
973
  const autoReconnect = options?.autoReconnect ?? false;
845
974
  const reconnectDelay = options?.reconnectDelay ?? 1e3;
846
- const maxReconnects = options?.maxReconnects ?? Infinity;
975
+ const maxReconnects = options?.maxReconnects ?? 10;
847
976
  const heartbeat = options?.heartbeat;
848
977
  const protocols = options?.protocols;
849
978
  const [data, setData] = signal(null);
@@ -877,13 +1006,19 @@ function socket(url, options) {
877
1006
  ws.onclose = () => {
878
1007
  setStatus("closed");
879
1008
  stopHeartbeat();
880
- if (autoReconnect && !disposed && !manuallyClosed && reconnectCount < maxReconnects) {
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);
881
1015
  reconnectCount++;
882
1016
  reconnectTimer = setTimeout(() => {
1017
+ reconnectTimer = null;
1018
+ if (disposed || manuallyClosed) return;
883
1019
  connect();
884
- }, reconnectDelay);
1020
+ }, jittered);
885
1021
  }
886
- manuallyClosed = false;
887
1022
  };
888
1023
  ws.onerror = () => {
889
1024
  };
@@ -936,12 +1071,16 @@ function validateSseUrl(raw) {
936
1071
  }
937
1072
  function stream(url, options) {
938
1073
  const autoReconnect = options?.autoReconnect ?? false;
1074
+ const maxReconnects = options?.maxReconnects ?? 10;
1075
+ const baseMs = options?.reconnectBaseMs ?? 1e3;
1076
+ const maxMs = options?.reconnectMaxMs ?? 3e4;
939
1077
  const [data, setData] = signal(null);
940
1078
  const [event, setEvent] = signal(null);
941
1079
  const [status, setStatus] = signal("connecting");
942
1080
  let source = null;
943
1081
  let disposed = false;
944
1082
  let reconnectTimer = null;
1083
+ let attempts = 0;
945
1084
  function connect() {
946
1085
  if (disposed) return;
947
1086
  const safeUrl = validateSseUrl(url);
@@ -955,6 +1094,7 @@ function stream(url, options) {
955
1094
  });
956
1095
  source.onopen = () => {
957
1096
  setStatus("open");
1097
+ attempts = 0;
958
1098
  };
959
1099
  source.onmessage = (evt) => {
960
1100
  setData(evt.data);
@@ -964,11 +1104,14 @@ function stream(url, options) {
964
1104
  if (source && source.readyState === EventSource.CLOSED) {
965
1105
  setStatus("closed");
966
1106
  source = null;
967
- 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++;
968
1111
  reconnectTimer = setTimeout(() => {
969
1112
  reconnectTimer = null;
970
1113
  connect();
971
- }, 1e3);
1114
+ }, jittered);
972
1115
  }
973
1116
  }
974
1117
  };
@@ -1000,6 +1143,7 @@ export {
1000
1143
  getQueryData,
1001
1144
  setQueryData,
1002
1145
  clearQueryCache,
1146
+ __resetQueryCache,
1003
1147
  mutation,
1004
1148
  infiniteQuery,
1005
1149
  previous,