sibujs 1.5.0 → 2.1.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 (208) hide show
  1. package/dist/browser.cjs +332 -121
  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 +1049 -344
  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-BMPL52BF.js → chunk-3DZP6OIT.js} +118 -66
  11. package/dist/chunk-3JHCYHWN.js +125 -0
  12. package/dist/{chunk-CZUGLNJS.js → chunk-45YP72ZQ.js} +3 -3
  13. package/dist/{chunk-JCDUJN2F.js → chunk-AMK2TYNW.js} +490 -153
  14. package/dist/{chunk-NHUC2QWH.js → chunk-CWBVQML6.js} +1 -1
  15. package/dist/{chunk-XHK6BDAJ.js → chunk-DRUZZAK4.js} +25 -8
  16. package/dist/{chunk-RJ46C3CS.js → chunk-GWWURC5M.js} +71 -20
  17. package/dist/{chunk-3X2YG6YM.js → chunk-JYD2PWXH.js} +59 -28
  18. package/dist/{chunk-2BYQDGN3.js → chunk-KGYT6UO6.js} +234 -63
  19. package/dist/{chunk-5X6PP2UK.js → chunk-LMLD24FC.js} +2 -2
  20. package/dist/{chunk-M4NLBH4I.js → chunk-LYTCUZ7H.js} +3 -2
  21. package/dist/{chunk-XUEEGU5O.js → chunk-NASX6ST2.js} +16 -4
  22. package/dist/{chunk-VQDZK23A.js → chunk-O6EFQ3KT.js} +181 -66
  23. package/dist/{chunk-BGN5ZMP4.js → chunk-OJ3P4ECI.js} +14 -2
  24. package/dist/chunk-ON5MMR2J.js +1327 -0
  25. package/dist/{chunk-SFKNRVCU.js → chunk-P2HSJDDN.js} +135 -79
  26. package/dist/chunk-QO3WC6FS.js +384 -0
  27. package/dist/{chunk-WZSPOOER.js → chunk-RDTDJCAB.js} +8 -5
  28. package/dist/{chunk-7GRNSCFT.js → chunk-TH2ILCYW.js} +312 -185
  29. package/dist/chunk-UCS6AMJ7.js +79 -0
  30. package/dist/{chunk-VAPYJN4X.js → chunk-V6C4FADE.js} +93 -23
  31. package/dist/{chunk-OUZZEE4S.js → chunk-WANSMF2L.js} +17 -11
  32. package/dist/{chunk-23VV7YD3.js → chunk-WIPZPFBQ.js} +25 -30
  33. package/dist/chunk-WZA53FXU.js +149 -0
  34. package/dist/{chunk-BGTHZHJ5.js → chunk-ZAQSMOED.js} +188 -44
  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 +536 -151
  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 +613 -266
  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 +602 -197
  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 +3500 -1608
  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 +1055 -344
  54. package/dist/index.d.cts +85 -8
  55. package/dist/index.d.ts +85 -8
  56. package/dist/index.js +32 -16
  57. package/dist/{introspect-BumjnBKr.d.cts → introspect-2TOlQ7oa.d.cts} +25 -3
  58. package/dist/{introspect-CZrlcaYy.d.ts → introspect-DnIpHQQz.d.ts} +25 -3
  59. package/dist/motion.cjs +122 -63
  60. package/dist/motion.js +4 -4
  61. package/dist/patterns.cjs +450 -110
  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 +373 -149
  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 +729 -301
  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 +736 -274
  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 +303 -76
  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 +589 -178
  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 +1103 -146
  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-K4G4ZQNR.js +0 -286
  136. package/dist/chunk-K5ZUMYVS.js +0 -89
  137. package/dist/chunk-KQPDEVVS.js +0 -398
  138. package/dist/chunk-L6JRBDNS.js +0 -60
  139. package/dist/chunk-LA6KQEDU.js +0 -712
  140. package/dist/chunk-MB6QFH3I.js +0 -2776
  141. package/dist/chunk-MDVXJWFN.js +0 -304
  142. package/dist/chunk-MEZVEBPN.js +0 -2008
  143. package/dist/chunk-MK4ERFYL.js +0 -2249
  144. package/dist/chunk-MLKGABMK.js +0 -9
  145. package/dist/chunk-MQ5GOYPH.js +0 -2249
  146. package/dist/chunk-MYRV7VDM.js +0 -742
  147. package/dist/chunk-N6IZB6KJ.js +0 -567
  148. package/dist/chunk-NEKUBFPT.js +0 -60
  149. package/dist/chunk-NMRUZALC.js +0 -1097
  150. package/dist/chunk-NYVAC6P5.js +0 -37
  151. package/dist/chunk-NZIIMDWI.js +0 -84
  152. package/dist/chunk-OF7UZIVB.js +0 -725
  153. package/dist/chunk-P3XWXJZU.js +0 -282
  154. package/dist/chunk-P6W3STU4.js +0 -2249
  155. package/dist/chunk-PBHF5WKN.js +0 -616
  156. package/dist/chunk-PDZQY43A.js +0 -616
  157. package/dist/chunk-PTQJDMRT.js +0 -146
  158. package/dist/chunk-PZEGYCF5.js +0 -61
  159. package/dist/chunk-QBMDLBU2.js +0 -975
  160. package/dist/chunk-QWZG56ET.js +0 -2744
  161. package/dist/chunk-RQGQSLQK.js +0 -725
  162. package/dist/chunk-SDLZDHKP.js +0 -107
  163. package/dist/chunk-TDGZL5CU.js +0 -365
  164. package/dist/chunk-TNQWPPE6.js +0 -37
  165. package/dist/chunk-TSOKIX5Z.js +0 -654
  166. package/dist/chunk-UHNL42EF.js +0 -2730
  167. package/dist/chunk-UNXCEF6S.js +0 -21
  168. package/dist/chunk-V2XTI523.js +0 -347
  169. package/dist/chunk-VAU366PN.js +0 -2241
  170. package/dist/chunk-VMVDTCXB.js +0 -712
  171. package/dist/chunk-VQNQZCWJ.js +0 -61
  172. package/dist/chunk-VRW3FULF.js +0 -725
  173. package/dist/chunk-WADYRCO2.js +0 -304
  174. package/dist/chunk-WILQZRO4.js +0 -282
  175. package/dist/chunk-WR5D4EGH.js +0 -26
  176. package/dist/chunk-WUHJISPP.js +0 -298
  177. package/dist/chunk-XYU6TZOW.js +0 -182
  178. package/dist/chunk-Y6GP4QGG.js +0 -276
  179. package/dist/chunk-YECR7UIA.js +0 -347
  180. package/dist/chunk-YUTWTI4B.js +0 -654
  181. package/dist/chunk-Z65KYU7I.js +0 -26
  182. package/dist/chunk-Z6POF5YC.js +0 -975
  183. package/dist/chunk-ZBJP6WFL.js +0 -482
  184. package/dist/chunk-ZD6OAMTH.js +0 -277
  185. package/dist/chunk-ZWKZCBO6.js +0 -317
  186. package/dist/contracts-DDrwxvJ-.d.cts +0 -245
  187. package/dist/contracts-DDrwxvJ-.d.ts +0 -245
  188. package/dist/contracts-DOrhwbke.d.cts +0 -245
  189. package/dist/contracts-DOrhwbke.d.ts +0 -245
  190. package/dist/contracts-xo5ckdRP.d.cts +0 -240
  191. package/dist/contracts-xo5ckdRP.d.ts +0 -240
  192. package/dist/customElement-BKQfbSZQ.d.cts +0 -262
  193. package/dist/customElement-BKQfbSZQ.d.ts +0 -262
  194. package/dist/customElement-D2DJp_xn.d.cts +0 -313
  195. package/dist/customElement-D2DJp_xn.d.ts +0 -313
  196. package/dist/customElement-yz8uyk-0.d.cts +0 -308
  197. package/dist/customElement-yz8uyk-0.d.ts +0 -308
  198. package/dist/introspect-Cb0zgpi2.d.cts +0 -477
  199. package/dist/introspect-Y2xNXGSf.d.ts +0 -477
  200. package/dist/plugin-Bek4RhJY.d.cts +0 -43
  201. package/dist/plugin-Bek4RhJY.d.ts +0 -43
  202. package/dist/ssr-3RXHP5ES.js +0 -38
  203. package/dist/ssr-6GIMY5MX.js +0 -38
  204. package/dist/ssr-BA6sxxUd.d.cts +0 -135
  205. package/dist/ssr-BA6sxxUd.d.ts +0 -135
  206. package/dist/ssr-WKUPVSSK.js +0 -36
  207. package/dist/tagFactory-Dl8QCLga.d.cts +0 -23
  208. package/dist/tagFactory-Dl8QCLga.d.ts +0 -23
@@ -1,1000 +0,0 @@
1
- import {
2
- context
3
- } from "./chunk-BGN5ZMP4.js";
4
- import {
5
- derived
6
- } from "./chunk-NEKUBFPT.js";
7
- import {
8
- sanitizeUrl
9
- } from "./chunk-CMBFNA7L.js";
10
- import {
11
- effect
12
- } from "./chunk-CHF5OHIA.js";
13
- import {
14
- batch,
15
- signal
16
- } from "./chunk-WZSPOOER.js";
17
-
18
- // src/data/retry.ts
19
- function calculateDelay(attempt, strategy, baseDelay, maxDelay, jitter) {
20
- let delay;
21
- switch (strategy) {
22
- case "exponential":
23
- delay = baseDelay * 2 ** attempt;
24
- break;
25
- case "linear":
26
- delay = baseDelay * (attempt + 1);
27
- break;
28
- case "fixed":
29
- delay = baseDelay;
30
- break;
31
- }
32
- delay = Math.min(delay, maxDelay);
33
- if (jitter > 0) {
34
- const jitterRange = delay * jitter;
35
- delay += (Math.random() * 2 - 1) * jitterRange;
36
- }
37
- return Math.max(0, delay);
38
- }
39
- async function withRetry(fn, options, onRetry, signal2) {
40
- const maxRetries = options?.maxRetries ?? 3;
41
- const strategy = options?.strategy ?? "exponential";
42
- const baseDelay = options?.baseDelay ?? 1e3;
43
- const maxDelay = options?.maxDelay ?? 3e4;
44
- const jitter = options?.jitter ?? 0.1;
45
- const shouldRetry = options?.shouldRetry ?? (() => true);
46
- let lastError;
47
- for (let attempt = 0; attempt <= maxRetries; attempt++) {
48
- if (signal2?.aborted) throw new DOMException("Aborted", "AbortError");
49
- try {
50
- return await fn();
51
- } catch (error) {
52
- lastError = error;
53
- if (attempt >= maxRetries || !shouldRetry(error, attempt)) throw error;
54
- const delay = calculateDelay(attempt, strategy, baseDelay, maxDelay, jitter);
55
- onRetry?.(error, attempt, delay);
56
- await new Promise((resolve, reject) => {
57
- const timer = setTimeout(resolve, delay);
58
- if (signal2) {
59
- const onAbort = () => {
60
- clearTimeout(timer);
61
- reject(new DOMException("Aborted", "AbortError"));
62
- };
63
- signal2.addEventListener("abort", onAbort, { once: true });
64
- }
65
- });
66
- }
67
- }
68
- throw lastError;
69
- }
70
-
71
- // src/data/query.ts
72
- var queryCache = /* @__PURE__ */ new Map();
73
- function getOrCreateEntry(key, initialData) {
74
- let entry = queryCache.get(key);
75
- if (!entry) {
76
- entry = {
77
- data: initialData,
78
- error: void 0,
79
- dataUpdatedAt: initialData !== void 0 ? Date.now() : 0,
80
- subscribers: 0,
81
- gcTimer: null,
82
- promise: null,
83
- listeners: /* @__PURE__ */ new Set(),
84
- refetchers: /* @__PURE__ */ new Set()
85
- };
86
- queryCache.set(key, entry);
87
- }
88
- return entry;
89
- }
90
- function query(key, fetcher, options = {}) {
91
- const {
92
- staleTime = 0,
93
- cacheTime = 3e5,
94
- enabled = true,
95
- retry: retryOptions,
96
- initialData,
97
- refetchInterval,
98
- refetchOnWindowFocus = false,
99
- refetchOnReconnect = false,
100
- onSuccess,
101
- onError,
102
- onSettled,
103
- select
104
- } = options;
105
- const resolveKey = typeof key === "function" ? key : () => key;
106
- const [data, setData] = signal(initialData);
107
- const [isFetching, setIsFetching] = signal(false);
108
- const [error, setError] = signal(void 0);
109
- let abortController = null;
110
- let disposed = false;
111
- let currentKey = null;
112
- let intervalTimer = null;
113
- const loading = derived(() => isFetching() && data() === void 0);
114
- const isStale = derived(() => {
115
- data();
116
- if (!currentKey) return true;
117
- const entry = queryCache.get(currentKey);
118
- if (!entry || entry.dataUpdatedAt === 0) return true;
119
- return Date.now() - entry.dataUpdatedAt >= staleTime;
120
- });
121
- async function doFetch() {
122
- if (disposed || !currentKey || !enabled) return;
123
- const key2 = currentKey;
124
- let entry = queryCache.get(key2);
125
- if (!entry) {
126
- entry = getOrCreateEntry(key2);
127
- entry.subscribers++;
128
- entry.listeners.add(onCacheUpdate);
129
- entry.refetchers.add(doFetch);
130
- }
131
- if (entry.promise) {
132
- setIsFetching(true);
133
- try {
134
- await entry.promise;
135
- } catch {
136
- }
137
- onCacheUpdate();
138
- return;
139
- }
140
- abortController?.abort();
141
- abortController = new AbortController();
142
- const signal2 = abortController.signal;
143
- setIsFetching(true);
144
- const promise = withRetry(() => fetcher({ signal: signal2, key: key2 }), retryOptions, void 0, signal2);
145
- entry.promise = promise;
146
- try {
147
- const result = await promise;
148
- entry.promise = null;
149
- if (disposed || currentKey !== key2) return;
150
- entry.data = result;
151
- entry.dataUpdatedAt = Date.now();
152
- entry.error = void 0;
153
- const selected = select ? select(result) : result;
154
- batch(() => {
155
- setData(selected);
156
- setIsFetching(false);
157
- setError(void 0);
158
- });
159
- for (const listener of entry.listeners) listener();
160
- onSuccess?.(result);
161
- } catch (err) {
162
- entry.promise = null;
163
- if (disposed || currentKey !== key2) return;
164
- if (err instanceof DOMException && err.name === "AbortError") return;
165
- const errorObj = err instanceof Error ? err : new Error(String(err));
166
- entry.error = errorObj;
167
- batch(() => {
168
- setError(errorObj);
169
- setIsFetching(false);
170
- });
171
- for (const listener of entry.listeners) listener();
172
- onError?.(errorObj);
173
- } finally {
174
- if (!disposed && currentKey === key2) onSettled?.();
175
- }
176
- }
177
- function onCacheUpdate() {
178
- if (disposed || !currentKey) return;
179
- const entry = queryCache.get(currentKey);
180
- if (!entry) {
181
- batch(() => {
182
- setData(void 0);
183
- setError(void 0);
184
- setIsFetching(false);
185
- });
186
- return;
187
- }
188
- const raw = entry.data;
189
- const selected = raw !== void 0 && select ? select(raw) : raw;
190
- batch(() => {
191
- setData(selected);
192
- setError(entry.error);
193
- if (!entry.promise) setIsFetching(false);
194
- });
195
- }
196
- const effectCleanup = effect(() => {
197
- const key2 = resolveKey();
198
- if (currentKey !== null && currentKey !== key2) {
199
- const oldEntry = queryCache.get(currentKey);
200
- if (oldEntry) {
201
- oldEntry.listeners.delete(onCacheUpdate);
202
- oldEntry.refetchers.delete(doFetch);
203
- oldEntry.subscribers--;
204
- if (oldEntry.subscribers <= 0 && cacheTime >= 0) {
205
- const oldKey = currentKey;
206
- oldEntry.gcTimer = setTimeout(() => queryCache.delete(oldKey), cacheTime);
207
- }
208
- }
209
- }
210
- currentKey = key2;
211
- const entry = getOrCreateEntry(key2, initialData);
212
- entry.subscribers++;
213
- if (entry.gcTimer !== null) {
214
- clearTimeout(entry.gcTimer);
215
- entry.gcTimer = null;
216
- }
217
- entry.listeners.add(onCacheUpdate);
218
- entry.refetchers.add(doFetch);
219
- if (entry.data !== void 0) {
220
- const raw = entry.data;
221
- const selected = select ? select(raw) : raw;
222
- batch(() => {
223
- setData(selected);
224
- setError(entry.error);
225
- });
226
- }
227
- const isDataStale = entry.dataUpdatedAt === 0 || Date.now() - entry.dataUpdatedAt >= staleTime;
228
- if (enabled && (entry.data === void 0 || isDataStale)) {
229
- doFetch();
230
- }
231
- });
232
- if (refetchInterval && refetchInterval > 0) {
233
- intervalTimer = setInterval(() => {
234
- if (!disposed && currentKey && enabled) doFetch();
235
- }, refetchInterval);
236
- }
237
- let focusHandler = null;
238
- let onlineHandler = null;
239
- if (typeof globalThis !== "undefined" && typeof globalThis.addEventListener === "function") {
240
- if (refetchOnWindowFocus) {
241
- focusHandler = () => {
242
- if (!disposed && currentKey && enabled) doFetch();
243
- };
244
- globalThis.addEventListener("focus", focusHandler);
245
- }
246
- if (refetchOnReconnect) {
247
- onlineHandler = () => {
248
- if (!disposed && currentKey && enabled) doFetch();
249
- };
250
- globalThis.addEventListener("online", onlineHandler);
251
- }
252
- }
253
- function dispose() {
254
- disposed = true;
255
- abortController?.abort();
256
- effectCleanup();
257
- if (intervalTimer) clearInterval(intervalTimer);
258
- if (currentKey) {
259
- const entry = queryCache.get(currentKey);
260
- if (entry) {
261
- entry.listeners.delete(onCacheUpdate);
262
- entry.refetchers.delete(doFetch);
263
- entry.subscribers--;
264
- if (entry.subscribers <= 0 && cacheTime >= 0) {
265
- const key2 = currentKey;
266
- entry.gcTimer = setTimeout(() => queryCache.delete(key2), cacheTime);
267
- }
268
- }
269
- }
270
- if (focusHandler) globalThis.removeEventListener("focus", focusHandler);
271
- if (onlineHandler) globalThis.removeEventListener("online", onlineHandler);
272
- }
273
- return {
274
- data,
275
- loading,
276
- fetching: isFetching,
277
- error,
278
- isStale,
279
- refetch: doFetch,
280
- dispose
281
- };
282
- }
283
- function invalidateQueries(keyOrPredicate) {
284
- const predicate = typeof keyOrPredicate === "function" ? keyOrPredicate : (k) => k === keyOrPredicate;
285
- for (const [key, entry] of queryCache.entries()) {
286
- if (predicate(key)) {
287
- entry.dataUpdatedAt = 0;
288
- for (const refetcher of entry.refetchers) refetcher();
289
- }
290
- }
291
- }
292
- function getQueryData(key) {
293
- return queryCache.get(key)?.data;
294
- }
295
- function setQueryData(key, data) {
296
- const entry = queryCache.get(key);
297
- if (!entry) return;
298
- const newData = typeof data === "function" ? data(entry.data) : data;
299
- entry.data = newData;
300
- entry.dataUpdatedAt = Date.now();
301
- for (const listener of entry.listeners) listener();
302
- }
303
- function clearQueryCache() {
304
- const activeListeners = [];
305
- const activeRefetchers = [];
306
- for (const entry of queryCache.values()) {
307
- if (entry.gcTimer) clearTimeout(entry.gcTimer);
308
- if (entry.subscribers > 0) {
309
- for (const listener of entry.listeners) activeListeners.push(listener);
310
- for (const refetcher of entry.refetchers) activeRefetchers.push(refetcher);
311
- }
312
- }
313
- queryCache.clear();
314
- for (const listener of activeListeners) listener();
315
- for (const refetcher of activeRefetchers) refetcher();
316
- }
317
-
318
- // src/data/mutation.ts
319
- function mutation(mutationFn, options = {}) {
320
- const [data, setData] = signal(void 0);
321
- const [loading, setLoading] = signal(false);
322
- const [error, setError] = signal(void 0);
323
- const [status, setStatus] = signal("idle");
324
- const isSuccess = derived(() => status() === "success");
325
- const isIdle = derived(() => status() === "idle");
326
- async function execute(variables) {
327
- let context2;
328
- batch(() => {
329
- setLoading(true);
330
- setError(void 0);
331
- setStatus("loading");
332
- });
333
- try {
334
- if (options.onMutate) {
335
- context2 = await options.onMutate(variables);
336
- }
337
- const result = await withRetry(() => mutationFn(variables), options.retry);
338
- batch(() => {
339
- setData(result);
340
- setLoading(false);
341
- setStatus("success");
342
- });
343
- options.onSuccess?.(result, variables, context2);
344
- options.onSettled?.(result, void 0, variables, context2);
345
- return result;
346
- } catch (err) {
347
- const errorObj = err instanceof Error ? err : new Error(String(err));
348
- batch(() => {
349
- setError(errorObj);
350
- setLoading(false);
351
- setStatus("error");
352
- });
353
- options.onError?.(errorObj, variables, context2);
354
- options.onSettled?.(void 0, errorObj, variables, context2);
355
- throw errorObj;
356
- }
357
- }
358
- function reset() {
359
- batch(() => {
360
- setData(void 0);
361
- setError(void 0);
362
- setLoading(false);
363
- setStatus("idle");
364
- });
365
- }
366
- return {
367
- data,
368
- loading,
369
- error,
370
- isSuccess,
371
- isIdle,
372
- mutate: (variables) => {
373
- execute(variables).catch(() => {
374
- });
375
- },
376
- mutateAsync: execute,
377
- reset
378
- };
379
- }
380
-
381
- // src/data/infiniteQuery.ts
382
- function infiniteQuery(key, fetcher, options) {
383
- const {
384
- getNextPageParam,
385
- getPreviousPageParam,
386
- initialPageParam = 0,
387
- enabled = true,
388
- retry: retryOptions,
389
- onSuccess,
390
- onError
391
- } = options;
392
- const resolveKey = typeof key === "function" ? key : () => key;
393
- const [pages, setPages] = signal([]);
394
- const [isFetching, setIsFetching] = signal(false);
395
- const [isFetchingNext, setIsFetchingNext] = signal(false);
396
- const [isFetchingPrev, setIsFetchingPrev] = signal(false);
397
- const [error, setError] = signal(void 0);
398
- const [nextPageParam, setNextPageParam] = signal(initialPageParam);
399
- const [prevPageParam, setPrevPageParam] = signal(void 0);
400
- const data = derived(() => {
401
- const p = pages();
402
- return p.length > 0 ? p : void 0;
403
- });
404
- const loading = derived(() => isFetching() && pages().length === 0);
405
- const hasNextPage = derived(() => nextPageParam() !== void 0);
406
- const hasPreviousPage = derived(() => prevPageParam() !== void 0);
407
- let abortController = null;
408
- let disposed = false;
409
- async function fetchPage(pageParam, direction) {
410
- if (disposed) return;
411
- abortController?.abort();
412
- abortController = new AbortController();
413
- const signal2 = abortController.signal;
414
- batch(() => {
415
- setIsFetching(true);
416
- if (direction === "next") setIsFetchingNext(true);
417
- if (direction === "prev") setIsFetchingPrev(true);
418
- setError(void 0);
419
- });
420
- try {
421
- const page = await withRetry(() => fetcher({ signal: signal2, pageParam }), retryOptions, void 0, signal2);
422
- if (disposed) return;
423
- const currentPages = pages();
424
- let newPages;
425
- if (direction === "prev") {
426
- newPages = [page, ...currentPages];
427
- } else {
428
- newPages = [...currentPages, page];
429
- }
430
- const nextParam = getNextPageParam(page, newPages);
431
- const prevParam = getPreviousPageParam?.(newPages[0], newPages);
432
- batch(() => {
433
- setPages(newPages);
434
- setNextPageParam(nextParam);
435
- setPrevPageParam(prevParam);
436
- setIsFetching(false);
437
- setIsFetchingNext(false);
438
- setIsFetchingPrev(false);
439
- });
440
- onSuccess?.(newPages);
441
- } catch (err) {
442
- if (disposed) return;
443
- if (err instanceof DOMException && err.name === "AbortError") return;
444
- const errorObj = err instanceof Error ? err : new Error(String(err));
445
- batch(() => {
446
- setError(errorObj);
447
- setIsFetching(false);
448
- setIsFetchingNext(false);
449
- setIsFetchingPrev(false);
450
- });
451
- onError?.(errorObj);
452
- }
453
- }
454
- const effectCleanup = effect(() => {
455
- resolveKey();
456
- if (enabled) {
457
- setPages([]);
458
- setNextPageParam(initialPageParam);
459
- setPrevPageParam(void 0);
460
- fetchPage(initialPageParam, "initial");
461
- }
462
- });
463
- function fetchNextPage() {
464
- const param = nextPageParam();
465
- if (param === void 0) return Promise.resolve();
466
- return fetchPage(param, "next");
467
- }
468
- function fetchPreviousPage() {
469
- const param = prevPageParam();
470
- if (param === void 0) return Promise.resolve();
471
- return fetchPage(param, "prev");
472
- }
473
- async function refetch() {
474
- batch(() => {
475
- setPages([]);
476
- setNextPageParam(initialPageParam);
477
- setPrevPageParam(void 0);
478
- });
479
- await fetchPage(initialPageParam, "initial");
480
- }
481
- function dispose() {
482
- disposed = true;
483
- abortController?.abort();
484
- effectCleanup();
485
- }
486
- return {
487
- data,
488
- pages,
489
- loading,
490
- fetching: isFetching,
491
- fetchingNextPage: isFetchingNext,
492
- fetchingPreviousPage: isFetchingPrev,
493
- error,
494
- hasNextPage,
495
- hasPreviousPage,
496
- fetchNextPage,
497
- fetchPreviousPage,
498
- refetch,
499
- dispose
500
- };
501
- }
502
-
503
- // src/data/previous.ts
504
- function previous(getter) {
505
- const [previous2, setPrevious] = signal(void 0);
506
- let current = getter();
507
- effect(() => {
508
- const next = getter();
509
- if (!Object.is(next, current)) {
510
- setPrevious(current);
511
- current = next;
512
- }
513
- });
514
- return previous2;
515
- }
516
-
517
- // src/data/debounce.ts
518
- function debounce(getter, delay) {
519
- const [debounced, setDebounced] = signal(getter());
520
- let timer = null;
521
- effect(() => {
522
- const value = getter();
523
- if (timer !== null) clearTimeout(timer);
524
- timer = setTimeout(() => {
525
- setDebounced(value);
526
- timer = null;
527
- }, delay);
528
- });
529
- return debounced;
530
- }
531
-
532
- // src/data/throttle.ts
533
- function throttle(getter, interval) {
534
- const [throttled, setThrottled] = signal(getter());
535
- let cooldown = false;
536
- let pending = null;
537
- let lastEmitted = getter();
538
- effect(() => {
539
- const value = getter();
540
- if (!cooldown) {
541
- if (!Object.is(value, lastEmitted)) {
542
- setThrottled(value);
543
- lastEmitted = value;
544
- cooldown = true;
545
- pending = null;
546
- setTimeout(() => {
547
- cooldown = false;
548
- if (pending !== null) {
549
- const trailingValue = pending.value;
550
- pending = null;
551
- setThrottled(trailingValue);
552
- lastEmitted = trailingValue;
553
- }
554
- }, interval);
555
- }
556
- } else {
557
- pending = { value };
558
- }
559
- });
560
- return throttled;
561
- }
562
-
563
- // src/data/resource.ts
564
- function resource(sourceOrFetcher, fetcherOrOptions, maybeOptions) {
565
- let source = null;
566
- let fetcher;
567
- let options;
568
- if (typeof fetcherOrOptions === "function") {
569
- source = sourceOrFetcher;
570
- fetcher = fetcherOrOptions;
571
- options = maybeOptions ?? {};
572
- } else {
573
- const rawFetcher = sourceOrFetcher;
574
- fetcher = (_source, info) => rawFetcher(info);
575
- options = fetcherOrOptions ?? {};
576
- }
577
- const [data, setData] = signal(options.initialValue);
578
- const [loading, setLoading] = signal(false);
579
- const [error, setError] = signal(void 0);
580
- let currentData = options.initialValue;
581
- let abortController = null;
582
- let disposed = false;
583
- let effectCleanup = null;
584
- let fetchVersion = 0;
585
- async function doFetch(sourceValue) {
586
- if (disposed) return;
587
- abortController?.abort();
588
- abortController = new AbortController();
589
- const version = ++fetchVersion;
590
- const signal2 = abortController.signal;
591
- const prev = currentData;
592
- batch(() => {
593
- setLoading(true);
594
- setError(void 0);
595
- });
596
- options.onStart?.();
597
- try {
598
- const result = await withRetry(() => fetcher(sourceValue, { signal: signal2, prev }), options.retry, void 0, signal2);
599
- if (version !== fetchVersion || disposed) return;
600
- currentData = result;
601
- batch(() => {
602
- setData(result);
603
- setLoading(false);
604
- });
605
- options.onSuccess?.(result);
606
- } catch (err) {
607
- if (version !== fetchVersion || disposed) return;
608
- if (err instanceof DOMException && err.name === "AbortError") return;
609
- const errorObj = err instanceof Error ? err : new Error(String(err));
610
- batch(() => {
611
- setError(errorObj);
612
- setLoading(false);
613
- });
614
- options.onError?.(errorObj);
615
- } finally {
616
- if (version === fetchVersion) {
617
- options.onSettled?.();
618
- }
619
- }
620
- }
621
- if (source) {
622
- effectCleanup = effect(() => {
623
- const sourceValue = source();
624
- doFetch(sourceValue);
625
- });
626
- } else if (options.immediate !== false) {
627
- doFetch(void 0);
628
- }
629
- return {
630
- data,
631
- loading,
632
- error,
633
- refetch: () => doFetch(source ? source() : void 0),
634
- mutate: (value) => {
635
- const newValue = typeof value === "function" ? value(currentData) : value;
636
- currentData = newValue;
637
- setData(newValue);
638
- },
639
- abort: () => abortController?.abort(),
640
- dispose: () => {
641
- disposed = true;
642
- abortController?.abort();
643
- effectCleanup?.();
644
- }
645
- };
646
- }
647
-
648
- // src/data/offlineStore.ts
649
- function openDB(name, version, keyPath) {
650
- return new Promise((resolve, reject) => {
651
- const request = indexedDB.open(name, version);
652
- request.onerror = () => reject(request.error);
653
- request.onsuccess = () => resolve(request.result);
654
- request.onupgradeneeded = () => {
655
- const db = request.result;
656
- if (!db.objectStoreNames.contains("items")) {
657
- db.createObjectStore("items", { keyPath });
658
- }
659
- if (!db.objectStoreNames.contains("_changes")) {
660
- const changeStore = db.createObjectStore("_changes", { autoIncrement: true });
661
- changeStore.createIndex("timestamp", "timestamp");
662
- }
663
- if (!db.objectStoreNames.contains("_meta")) {
664
- db.createObjectStore("_meta");
665
- }
666
- };
667
- });
668
- }
669
- function idbGetAll(db, store) {
670
- return new Promise((resolve, reject) => {
671
- const tx = db.transaction(store, "readonly");
672
- const req = tx.objectStore(store).getAll();
673
- req.onsuccess = () => resolve(req.result);
674
- req.onerror = () => reject(req.error);
675
- });
676
- }
677
- function idbGet(db, store, key) {
678
- return new Promise((resolve, reject) => {
679
- const tx = db.transaction(store, "readonly");
680
- const req = tx.objectStore(store).get(key);
681
- req.onsuccess = () => resolve(req.result);
682
- req.onerror = () => reject(req.error);
683
- });
684
- }
685
- function idbPut(db, store, item) {
686
- return new Promise((resolve, reject) => {
687
- const tx = db.transaction(store, "readwrite");
688
- tx.objectStore(store).put(item);
689
- tx.oncomplete = () => resolve();
690
- tx.onerror = () => reject(tx.error);
691
- });
692
- }
693
- function idbDelete(db, store, key) {
694
- return new Promise((resolve, reject) => {
695
- const tx = db.transaction(store, "readwrite");
696
- tx.objectStore(store).delete(key);
697
- tx.oncomplete = () => resolve();
698
- tx.onerror = () => reject(tx.error);
699
- });
700
- }
701
- function idbClear(db, store) {
702
- return new Promise((resolve, reject) => {
703
- const tx = db.transaction(store, "readwrite");
704
- tx.objectStore(store).clear();
705
- tx.oncomplete = () => resolve();
706
- tx.onerror = () => reject(tx.error);
707
- });
708
- }
709
- async function offlineStore(options) {
710
- const { name, version = 1, keyPath = "id", autoSync = true } = options;
711
- const db = await openDB(name, version, keyPath);
712
- const initialData = await idbGetAll(db, "items");
713
- const initialChanges = await idbGetAll(db, "_changes");
714
- const savedLastSync = await idbGet(db, "_meta", "lastSynced");
715
- const [data, setData] = signal(initialData);
716
- const [isSyncing, setIsSyncing] = signal(false);
717
- const [lastSynced, setLastSynced] = signal(savedLastSync ?? null);
718
- const [pendingCount, setPendingCount] = signal(initialChanges.length);
719
- let adapter = options.adapter;
720
- async function refreshData() {
721
- const items = await idbGetAll(db, "items");
722
- setData(items);
723
- const changes = await idbGetAll(db, "_changes");
724
- setPendingCount(changes.length);
725
- }
726
- async function put(item) {
727
- await idbPut(db, "items", item);
728
- await idbPut(db, "_changes", { type: "put", item, timestamp: Date.now() });
729
- await refreshData();
730
- }
731
- async function remove(key) {
732
- const existing = await idbGet(db, "items", key);
733
- if (existing) {
734
- await idbDelete(db, "items", key);
735
- await idbPut(db, "_changes", { type: "delete", item: existing, timestamp: Date.now() });
736
- await refreshData();
737
- }
738
- }
739
- async function get(key) {
740
- return idbGet(db, "items", key);
741
- }
742
- function query2(filter) {
743
- return data().filter(filter);
744
- }
745
- async function sync() {
746
- if (!adapter || isSyncing()) return;
747
- setIsSyncing(true);
748
- try {
749
- const changes = await idbGetAll(db, "_changes");
750
- if (changes.length > 0) {
751
- const result = await adapter.push(changes);
752
- if (result.ok) {
753
- await idbClear(db, "_changes");
754
- }
755
- }
756
- const remoteItems = await adapter.pull(lastSynced());
757
- for (const item of remoteItems) {
758
- await idbPut(db, "items", item);
759
- }
760
- const now = Date.now();
761
- await idbPut(db, "_meta", now);
762
- setLastSynced(now);
763
- await refreshData();
764
- } catch {
765
- } finally {
766
- setIsSyncing(false);
767
- }
768
- }
769
- function attach(newAdapter) {
770
- adapter = newAdapter;
771
- }
772
- function close() {
773
- db.close();
774
- }
775
- if (autoSync && typeof window !== "undefined") {
776
- window.addEventListener("online", () => {
777
- sync();
778
- });
779
- }
780
- return {
781
- data,
782
- get,
783
- put,
784
- remove,
785
- query: query2,
786
- isSyncing,
787
- lastSynced,
788
- sync,
789
- attach,
790
- pendingCount,
791
- close
792
- };
793
- }
794
- function syncAdapter(config) {
795
- return config;
796
- }
797
-
798
- // src/data/routeLoader.ts
799
- var LoaderContext = context(null);
800
- function executeLoader(loader, context2, options) {
801
- const res = resource(({ signal: signal2 }) => loader(context2, { signal: signal2 }), options);
802
- LoaderContext.provide(res);
803
- return res;
804
- }
805
- function loaderData() {
806
- const resource2 = LoaderContext.get();
807
- if (!resource2) {
808
- throw new Error("loaderData must be used inside a route with a loader");
809
- }
810
- return {
811
- data: resource2.data,
812
- loading: resource2.loading,
813
- error: resource2.error
814
- };
815
- }
816
- async function preloadRoute(route, context2) {
817
- if (!route.loader) return void 0;
818
- const controller = new AbortController();
819
- return route.loader(context2, { signal: controller.signal });
820
- }
821
-
822
- // src/ui/socket.ts
823
- function validateWsUrl(raw) {
824
- const trimmed = raw.replace(/[\x00-\x20\x7f-\x9f]+/g, "").trim();
825
- if (!trimmed) return null;
826
- const lower = trimmed.toLowerCase();
827
- if (lower.startsWith("ws://") || lower.startsWith("wss://")) return trimmed;
828
- return null;
829
- }
830
- function socket(url, options) {
831
- const autoReconnect = options?.autoReconnect ?? false;
832
- const reconnectDelay = options?.reconnectDelay ?? 1e3;
833
- const maxReconnects = options?.maxReconnects ?? Infinity;
834
- const heartbeat = options?.heartbeat;
835
- const protocols = options?.protocols;
836
- const [data, setData] = signal(null);
837
- const [status, setStatus] = signal("closed");
838
- let ws = null;
839
- let reconnectCount = 0;
840
- let reconnectTimer = null;
841
- let heartbeatTimer = null;
842
- let disposed = false;
843
- function getUrl() {
844
- return typeof url === "function" ? url() : url;
845
- }
846
- function connect() {
847
- if (disposed) return;
848
- const safeUrl = validateWsUrl(getUrl());
849
- if (safeUrl === null) {
850
- setStatus("closed");
851
- return;
852
- }
853
- setStatus("connecting");
854
- ws = new WebSocket(safeUrl, protocols);
855
- ws.onopen = () => {
856
- setStatus("open");
857
- reconnectCount = 0;
858
- startHeartbeat();
859
- };
860
- ws.onmessage = (event) => {
861
- setData(event.data);
862
- };
863
- ws.onclose = () => {
864
- setStatus("closed");
865
- stopHeartbeat();
866
- if (autoReconnect && !disposed && reconnectCount < maxReconnects) {
867
- reconnectCount++;
868
- reconnectTimer = setTimeout(() => {
869
- connect();
870
- }, reconnectDelay);
871
- }
872
- };
873
- ws.onerror = () => {
874
- };
875
- }
876
- function startHeartbeat() {
877
- if (!heartbeat) return;
878
- stopHeartbeat();
879
- heartbeatTimer = setInterval(() => {
880
- if (ws && ws.readyState === WebSocket.OPEN) {
881
- ws.send(heartbeat.message);
882
- }
883
- }, heartbeat.interval);
884
- }
885
- function stopHeartbeat() {
886
- if (heartbeatTimer !== null) {
887
- clearInterval(heartbeatTimer);
888
- heartbeatTimer = null;
889
- }
890
- }
891
- function send(msg) {
892
- if (ws && ws.readyState === WebSocket.OPEN) {
893
- ws.send(msg);
894
- }
895
- }
896
- function close() {
897
- if (reconnectTimer !== null) {
898
- clearTimeout(reconnectTimer);
899
- reconnectTimer = null;
900
- }
901
- stopHeartbeat();
902
- if (ws) {
903
- setStatus("closing");
904
- ws.close();
905
- }
906
- }
907
- function dispose() {
908
- disposed = true;
909
- close();
910
- }
911
- connect();
912
- return { data, status, send, close, dispose };
913
- }
914
-
915
- // src/ui/stream.ts
916
- function validateSseUrl(raw) {
917
- const safe = sanitizeUrl(raw);
918
- if (!safe) return null;
919
- return safe;
920
- }
921
- function stream(url, options) {
922
- const autoReconnect = options?.autoReconnect ?? false;
923
- const [data, setData] = signal(null);
924
- const [event, setEvent] = signal(null);
925
- const [status, setStatus] = signal("connecting");
926
- let source = null;
927
- let disposed = false;
928
- let reconnectTimer = null;
929
- function connect() {
930
- if (disposed) return;
931
- const safeUrl = validateSseUrl(url);
932
- if (safeUrl === null) {
933
- setStatus("closed");
934
- return;
935
- }
936
- setStatus("connecting");
937
- source = new EventSource(safeUrl, {
938
- withCredentials: options?.withCredentials ?? false
939
- });
940
- source.onopen = () => {
941
- setStatus("open");
942
- };
943
- source.onmessage = (evt) => {
944
- setData(evt.data);
945
- setEvent(evt.type);
946
- };
947
- source.onerror = () => {
948
- if (source && source.readyState === EventSource.CLOSED) {
949
- setStatus("closed");
950
- source = null;
951
- if (autoReconnect && !disposed) {
952
- reconnectTimer = setTimeout(() => {
953
- reconnectTimer = null;
954
- connect();
955
- }, 1e3);
956
- }
957
- }
958
- };
959
- }
960
- function close() {
961
- if (reconnectTimer !== null) {
962
- clearTimeout(reconnectTimer);
963
- reconnectTimer = null;
964
- }
965
- if (source) {
966
- source.close();
967
- setStatus("closed");
968
- source = null;
969
- }
970
- }
971
- function dispose() {
972
- disposed = true;
973
- close();
974
- }
975
- connect();
976
- return { data, event, status, close, dispose };
977
- }
978
-
979
- export {
980
- calculateDelay,
981
- withRetry,
982
- query,
983
- invalidateQueries,
984
- getQueryData,
985
- setQueryData,
986
- clearQueryCache,
987
- mutation,
988
- infiniteQuery,
989
- previous,
990
- debounce,
991
- throttle,
992
- resource,
993
- offlineStore,
994
- syncAdapter,
995
- executeLoader,
996
- loaderData,
997
- preloadRoute,
998
- socket,
999
- stream
1000
- };