sibujs 3.1.0 → 3.2.1
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 +6 -0
- package/dist/browser.cjs +16 -8
- package/dist/browser.js +6 -5
- package/dist/build.cjs +235 -147
- package/dist/build.js +35 -24
- package/dist/cdn.global.js +7 -7
- package/dist/{chunk-WYU7CYJ3.js → chunk-2C4E3HBM.js} +5 -5
- package/dist/{chunk-3DYB5B3S.js → chunk-4JCAUOLN.js} +45 -23
- package/dist/{chunk-2HAGQWDV.js → chunk-5N74TKLD.js} +1 -1
- package/dist/{chunk-SVVAUX7J.js → chunk-7XDYVJLE.js} +19 -9
- package/dist/{chunk-2N2UL7O4.js → chunk-BGNLPNGV.js} +20 -12
- package/dist/{chunk-RK4BQG25.js → chunk-C427DVQF.js} +1 -1
- package/dist/{chunk-ZIBE2SAT.js → chunk-FDY42FIU.js} +3 -2
- package/dist/{chunk-GQ7RRFPU.js → chunk-FOI23UJL.js} +11 -1
- package/dist/{chunk-2RA7SHDA.js → chunk-GOJMFRBL.js} +20 -4
- package/dist/{chunk-IVOUCSZL.js → chunk-GOUM4JCT.js} +6 -6
- package/dist/chunk-H3SRKIYX.js +17 -0
- package/dist/{chunk-3DJH25UO.js → chunk-H6PCHJZQ.js} +2 -2
- package/dist/{chunk-UCS6AMJ7.js → chunk-HMJFCBRR.js} +26 -3
- package/dist/{chunk-JYD2PWXH.js → chunk-HXMS4SNP.js} +22 -15
- package/dist/{chunk-SC437AMI.js → chunk-JYXOEYI4.js} +12 -18
- package/dist/{chunk-KB3BA2XK.js → chunk-NFYWLRUO.js} +11 -18
- package/dist/{chunk-QNQY5DUS.js → chunk-NPIEEKPT.js} +20 -11
- package/dist/{chunk-UYX2NDOH.js → chunk-OYLPZO4N.js} +33 -15
- package/dist/{chunk-LYTCUZ7H.js → chunk-RDRSWYNP.js} +1 -1
- package/dist/{chunk-2ZJ7TSW4.js → chunk-RLUJL2MV.js} +4 -8
- package/dist/{chunk-CR4MXPHB.js → chunk-V2MTG5FT.js} +99 -36
- package/dist/{chunk-CNZ35WI2.js → chunk-VJE6DDYM.js} +2 -2
- package/dist/{chunk-PMSDFTK3.js → chunk-VOCE4NNK.js} +157 -75
- package/dist/{chunk-WKUXSE7V.js → chunk-X67UYC74.js} +12 -11
- package/dist/{chunk-EFOAE5NC.js → chunk-YFDGQWDA.js} +1 -1
- package/dist/{chunk-3U4ZVXVD.js → chunk-Z2FWAE4B.js} +6 -2
- package/dist/data.cjs +190 -94
- package/dist/data.d.cts +7 -1
- package/dist/data.d.ts +7 -1
- package/dist/data.js +8 -8
- package/dist/devtools.cjs +38 -10
- package/dist/devtools.d.cts +1 -1
- package/dist/devtools.d.ts +1 -1
- package/dist/devtools.js +6 -6
- package/dist/ecosystem.cjs +123 -63
- package/dist/ecosystem.js +9 -9
- package/dist/extras.cjs +380 -196
- package/dist/extras.d.cts +2 -2
- package/dist/extras.d.ts +2 -2
- package/dist/extras.js +27 -24
- package/dist/index.cjs +214 -136
- package/dist/index.d.cts +15 -2
- package/dist/index.d.ts +15 -2
- package/dist/index.js +15 -13
- package/dist/{introspect-BZWKvQUZ.d.ts → introspect-DOZfmC-4.d.ts} +1 -1
- package/dist/{introspect-DsJlDD2T.d.cts → introspect-RjLfIFpL.d.cts} +1 -1
- package/dist/motion.cjs +10 -0
- package/dist/motion.js +3 -3
- package/dist/patterns.cjs +45 -40
- package/dist/patterns.js +8 -7
- package/dist/performance.cjs +101 -25
- package/dist/performance.d.cts +2 -2
- package/dist/performance.d.ts +2 -2
- package/dist/performance.js +8 -7
- package/dist/plugins.cjs +234 -160
- package/dist/plugins.d.cts +1 -1
- package/dist/plugins.d.ts +1 -1
- package/dist/plugins.js +127 -69
- package/dist/{ssr-FXD2PPMC.js → ssr-2QDQ27EV.js} +5 -3
- package/dist/{ssr-CrVNy6Pa.d.cts → ssr-D62yFwuw.d.cts} +8 -1
- package/dist/{ssr-CrVNy6Pa.d.ts → ssr-D62yFwuw.d.ts} +8 -1
- package/dist/ssr.cjs +145 -66
- package/dist/ssr.d.cts +1 -1
- package/dist/ssr.d.ts +1 -1
- package/dist/ssr.js +12 -10
- package/dist/testing.cjs +9 -4
- package/dist/testing.js +3 -3
- package/dist/ui.cjs +54 -38
- package/dist/ui.js +10 -9
- package/dist/widgets.cjs +40 -24
- package/dist/widgets.js +8 -8
- package/package.json +3 -1
|
@@ -1,19 +1,22 @@
|
|
|
1
1
|
import {
|
|
2
2
|
context
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-YFDGQWDA.js";
|
|
4
4
|
import {
|
|
5
5
|
derived
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-JYXOEYI4.js";
|
|
7
7
|
import {
|
|
8
8
|
sanitizeUrl
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-HMJFCBRR.js";
|
|
10
10
|
import {
|
|
11
11
|
effect
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-FDY42FIU.js";
|
|
13
|
+
import {
|
|
14
|
+
getRequestScopedCache
|
|
15
|
+
} from "./chunk-GOJMFRBL.js";
|
|
13
16
|
import {
|
|
14
17
|
batch,
|
|
15
18
|
signal
|
|
16
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-C427DVQF.js";
|
|
17
20
|
|
|
18
21
|
// src/data/retry.ts
|
|
19
22
|
function calculateDelay(attempt, strategy, baseDelay, maxDelay, jitter) {
|
|
@@ -76,9 +79,12 @@ async function withRetry(fn, options, onRetry, signal2) {
|
|
|
76
79
|
}
|
|
77
80
|
|
|
78
81
|
// src/data/query.ts
|
|
79
|
-
var
|
|
80
|
-
function
|
|
81
|
-
|
|
82
|
+
var globalQueryCache = /* @__PURE__ */ new Map();
|
|
83
|
+
function getActiveQueryCache() {
|
|
84
|
+
return getRequestScopedCache("query") ?? globalQueryCache;
|
|
85
|
+
}
|
|
86
|
+
function getOrCreateEntry(cache, key, initialData) {
|
|
87
|
+
let entry = cache.get(key);
|
|
82
88
|
if (!entry) {
|
|
83
89
|
entry = {
|
|
84
90
|
data: initialData,
|
|
@@ -90,7 +96,7 @@ function getOrCreateEntry(key, initialData) {
|
|
|
90
96
|
listeners: /* @__PURE__ */ new Set(),
|
|
91
97
|
refetchers: /* @__PURE__ */ new Set()
|
|
92
98
|
};
|
|
93
|
-
|
|
99
|
+
cache.set(key, entry);
|
|
94
100
|
}
|
|
95
101
|
return entry;
|
|
96
102
|
}
|
|
@@ -110,6 +116,7 @@ function query(key, fetcher, options = {}) {
|
|
|
110
116
|
select
|
|
111
117
|
} = options;
|
|
112
118
|
const resolveKey = typeof key === "function" ? key : () => key;
|
|
119
|
+
const cache = getActiveQueryCache();
|
|
113
120
|
const [data, setData] = signal(initialData);
|
|
114
121
|
const [isFetching, setIsFetching] = signal(false);
|
|
115
122
|
const [error, setError] = signal(void 0);
|
|
@@ -121,16 +128,16 @@ function query(key, fetcher, options = {}) {
|
|
|
121
128
|
const isStale = derived(() => {
|
|
122
129
|
data();
|
|
123
130
|
if (!currentKey) return true;
|
|
124
|
-
const entry =
|
|
131
|
+
const entry = cache.get(currentKey);
|
|
125
132
|
if (!entry || entry.dataUpdatedAt === 0) return true;
|
|
126
133
|
return Date.now() - entry.dataUpdatedAt >= staleTime;
|
|
127
134
|
});
|
|
128
135
|
async function doFetch() {
|
|
129
136
|
if (disposed || !currentKey || !enabled) return;
|
|
130
137
|
const key2 = currentKey;
|
|
131
|
-
let entry =
|
|
138
|
+
let entry = cache.get(key2);
|
|
132
139
|
if (!entry) {
|
|
133
|
-
entry = getOrCreateEntry(key2);
|
|
140
|
+
entry = getOrCreateEntry(cache, key2);
|
|
134
141
|
entry.listeners.add(onCacheUpdate);
|
|
135
142
|
entry.refetchers.add(doFetch);
|
|
136
143
|
}
|
|
@@ -205,7 +212,7 @@ function query(key, fetcher, options = {}) {
|
|
|
205
212
|
}
|
|
206
213
|
function onCacheUpdate() {
|
|
207
214
|
if (disposed || !currentKey) return;
|
|
208
|
-
const entry =
|
|
215
|
+
const entry = cache.get(currentKey);
|
|
209
216
|
if (!entry) {
|
|
210
217
|
batch(() => {
|
|
211
218
|
setData(void 0);
|
|
@@ -225,7 +232,7 @@ function query(key, fetcher, options = {}) {
|
|
|
225
232
|
const effectCleanup = effect(() => {
|
|
226
233
|
const key2 = resolveKey();
|
|
227
234
|
if (currentKey !== null && currentKey !== key2) {
|
|
228
|
-
const oldEntry =
|
|
235
|
+
const oldEntry = cache.get(currentKey);
|
|
229
236
|
if (oldEntry) {
|
|
230
237
|
oldEntry.listeners.delete(onCacheUpdate);
|
|
231
238
|
oldEntry.refetchers.delete(doFetch);
|
|
@@ -233,13 +240,13 @@ function query(key, fetcher, options = {}) {
|
|
|
233
240
|
if (oldEntry.subscribers <= 0 && cacheTime >= 0) {
|
|
234
241
|
const oldKey = currentKey;
|
|
235
242
|
if (oldEntry.gcTimer !== null) clearTimeout(oldEntry.gcTimer);
|
|
236
|
-
oldEntry.gcTimer = setTimeout(() =>
|
|
243
|
+
oldEntry.gcTimer = setTimeout(() => cache.delete(oldKey), cacheTime);
|
|
237
244
|
}
|
|
238
245
|
}
|
|
239
246
|
}
|
|
240
247
|
const keyChanged = currentKey !== key2;
|
|
241
248
|
currentKey = key2;
|
|
242
|
-
const entry = getOrCreateEntry(key2, initialData);
|
|
249
|
+
const entry = getOrCreateEntry(cache, key2, initialData);
|
|
243
250
|
if (keyChanged) entry.subscribers++;
|
|
244
251
|
if (entry.gcTimer !== null) {
|
|
245
252
|
clearTimeout(entry.gcTimer);
|
|
@@ -293,7 +300,7 @@ function query(key, fetcher, options = {}) {
|
|
|
293
300
|
effectCleanup();
|
|
294
301
|
if (intervalTimer) clearInterval(intervalTimer);
|
|
295
302
|
if (currentKey) {
|
|
296
|
-
const entry =
|
|
303
|
+
const entry = cache.get(currentKey);
|
|
297
304
|
if (entry) {
|
|
298
305
|
entry.listeners.delete(onCacheUpdate);
|
|
299
306
|
entry.refetchers.delete(doFetch);
|
|
@@ -301,7 +308,7 @@ function query(key, fetcher, options = {}) {
|
|
|
301
308
|
if (entry.subscribers <= 0 && cacheTime >= 0) {
|
|
302
309
|
const key2 = currentKey;
|
|
303
310
|
if (entry.gcTimer !== null) clearTimeout(entry.gcTimer);
|
|
304
|
-
entry.gcTimer = setTimeout(() =>
|
|
311
|
+
entry.gcTimer = setTimeout(() => cache.delete(key2), cacheTime);
|
|
305
312
|
}
|
|
306
313
|
}
|
|
307
314
|
}
|
|
@@ -324,7 +331,7 @@ function query(key, fetcher, options = {}) {
|
|
|
324
331
|
}
|
|
325
332
|
function invalidateQueries(keyOrPredicate) {
|
|
326
333
|
const predicate = typeof keyOrPredicate === "function" ? keyOrPredicate : (k) => k === keyOrPredicate;
|
|
327
|
-
for (const [key, entry] of
|
|
334
|
+
for (const [key, entry] of getActiveQueryCache().entries()) {
|
|
328
335
|
if (predicate(key)) {
|
|
329
336
|
entry.dataUpdatedAt = 0;
|
|
330
337
|
for (const refetcher of entry.refetchers) refetcher();
|
|
@@ -332,10 +339,10 @@ function invalidateQueries(keyOrPredicate) {
|
|
|
332
339
|
}
|
|
333
340
|
}
|
|
334
341
|
function getQueryData(key) {
|
|
335
|
-
return
|
|
342
|
+
return getActiveQueryCache().get(key)?.data;
|
|
336
343
|
}
|
|
337
344
|
function setQueryData(key, data) {
|
|
338
|
-
const entry =
|
|
345
|
+
const entry = getActiveQueryCache().get(key);
|
|
339
346
|
if (!entry) return;
|
|
340
347
|
const newData = typeof data === "function" ? data(entry.data) : data;
|
|
341
348
|
entry.data = newData;
|
|
@@ -345,14 +352,15 @@ function setQueryData(key, data) {
|
|
|
345
352
|
function clearQueryCache() {
|
|
346
353
|
const activeListeners = [];
|
|
347
354
|
const activeRefetchers = [];
|
|
348
|
-
|
|
355
|
+
const activeCache = getActiveQueryCache();
|
|
356
|
+
for (const entry of activeCache.values()) {
|
|
349
357
|
if (entry.gcTimer) clearTimeout(entry.gcTimer);
|
|
350
358
|
if (entry.subscribers > 0) {
|
|
351
359
|
for (const listener of entry.listeners) activeListeners.push(listener);
|
|
352
360
|
for (const refetcher of entry.refetchers) activeRefetchers.push(refetcher);
|
|
353
361
|
}
|
|
354
362
|
}
|
|
355
|
-
|
|
363
|
+
activeCache.clear();
|
|
356
364
|
for (const listener of activeListeners) listener();
|
|
357
365
|
for (const refetcher of activeRefetchers) {
|
|
358
366
|
refetcher().catch((err) => {
|
|
@@ -363,10 +371,11 @@ function clearQueryCache() {
|
|
|
363
371
|
}
|
|
364
372
|
}
|
|
365
373
|
function __resetQueryCache() {
|
|
366
|
-
|
|
374
|
+
const activeCache = getActiveQueryCache();
|
|
375
|
+
for (const entry of activeCache.values()) {
|
|
367
376
|
if (entry.gcTimer) clearTimeout(entry.gcTimer);
|
|
368
377
|
}
|
|
369
|
-
|
|
378
|
+
activeCache.clear();
|
|
370
379
|
}
|
|
371
380
|
|
|
372
381
|
// src/data/mutation.ts
|
|
@@ -378,7 +387,11 @@ function mutation(mutationFn, options = {}) {
|
|
|
378
387
|
const isSuccess = derived(() => status() === "success");
|
|
379
388
|
const isIdle = derived(() => status() === "idle");
|
|
380
389
|
let runId = 0;
|
|
390
|
+
let abortController = null;
|
|
381
391
|
async function execute(variables) {
|
|
392
|
+
abortController?.abort();
|
|
393
|
+
abortController = new AbortController();
|
|
394
|
+
const signal2 = abortController.signal;
|
|
382
395
|
const myRun = ++runId;
|
|
383
396
|
let context2;
|
|
384
397
|
batch(() => {
|
|
@@ -390,7 +403,7 @@ function mutation(mutationFn, options = {}) {
|
|
|
390
403
|
if (options.onMutate) {
|
|
391
404
|
context2 = await options.onMutate(variables);
|
|
392
405
|
}
|
|
393
|
-
const result = await withRetry(() => mutationFn(variables), options.retry);
|
|
406
|
+
const result = await withRetry(() => mutationFn(variables, signal2), options.retry, void 0, signal2);
|
|
394
407
|
if (myRun !== runId) return result;
|
|
395
408
|
batch(() => {
|
|
396
409
|
setData(result);
|
|
@@ -402,6 +415,7 @@ function mutation(mutationFn, options = {}) {
|
|
|
402
415
|
return result;
|
|
403
416
|
} catch (err) {
|
|
404
417
|
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
418
|
+
if (errorObj instanceof DOMException && errorObj.name === "AbortError") throw errorObj;
|
|
405
419
|
if (myRun !== runId) throw errorObj;
|
|
406
420
|
batch(() => {
|
|
407
421
|
setError(errorObj);
|
|
@@ -415,6 +429,8 @@ function mutation(mutationFn, options = {}) {
|
|
|
415
429
|
}
|
|
416
430
|
function reset() {
|
|
417
431
|
runId++;
|
|
432
|
+
abortController?.abort();
|
|
433
|
+
abortController = null;
|
|
418
434
|
batch(() => {
|
|
419
435
|
setData(void 0);
|
|
420
436
|
setError(void 0);
|
|
@@ -430,6 +446,7 @@ function mutation(mutationFn, options = {}) {
|
|
|
430
446
|
isIdle,
|
|
431
447
|
mutate: (variables) => {
|
|
432
448
|
execute(variables).catch((err) => {
|
|
449
|
+
if (err instanceof DOMException && err.name === "AbortError") return;
|
|
433
450
|
if (typeof console !== "undefined") {
|
|
434
451
|
console.warn("[SibuJS mutation] mutate() failed; check `.error()` signal or onError option.", err);
|
|
435
452
|
}
|
|
@@ -446,6 +463,7 @@ function infiniteQuery(key, fetcher, options) {
|
|
|
446
463
|
getNextPageParam,
|
|
447
464
|
getPreviousPageParam,
|
|
448
465
|
initialPageParam = 0,
|
|
466
|
+
maxPages,
|
|
449
467
|
enabled = true,
|
|
450
468
|
retry: retryOptions,
|
|
451
469
|
onSuccess,
|
|
@@ -469,8 +487,9 @@ function infiniteQuery(key, fetcher, options) {
|
|
|
469
487
|
let abortController = null;
|
|
470
488
|
let disposed = false;
|
|
471
489
|
let runId = 0;
|
|
472
|
-
|
|
473
|
-
|
|
490
|
+
let inFlight = null;
|
|
491
|
+
function fetchPage(pageParam, direction) {
|
|
492
|
+
if (disposed) return Promise.resolve();
|
|
474
493
|
abortController?.abort();
|
|
475
494
|
abortController = new AbortController();
|
|
476
495
|
const signal2 = abortController.signal;
|
|
@@ -481,39 +500,44 @@ function infiniteQuery(key, fetcher, options) {
|
|
|
481
500
|
if (direction === "prev") setIsFetchingPrev(true);
|
|
482
501
|
setError(void 0);
|
|
483
502
|
});
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
newPages
|
|
491
|
-
|
|
492
|
-
|
|
503
|
+
const promise = (async () => {
|
|
504
|
+
try {
|
|
505
|
+
const page = await withRetry(() => fetcher({ signal: signal2, pageParam }), retryOptions, void 0, signal2);
|
|
506
|
+
if (disposed || myRun !== runId) return;
|
|
507
|
+
const currentPages = pages();
|
|
508
|
+
let newPages = direction === "prev" ? [page, ...currentPages] : [...currentPages, page];
|
|
509
|
+
if (maxPages != null && maxPages > 0 && newPages.length > maxPages) {
|
|
510
|
+
newPages = direction === "prev" ? newPages.slice(0, maxPages) : newPages.slice(newPages.length - maxPages);
|
|
511
|
+
}
|
|
512
|
+
const nextParam = getNextPageParam(newPages[newPages.length - 1], newPages);
|
|
513
|
+
const prevParam = getPreviousPageParam?.(newPages[0], newPages);
|
|
514
|
+
batch(() => {
|
|
515
|
+
setPages(newPages);
|
|
516
|
+
setNextPageParam(nextParam);
|
|
517
|
+
setPrevPageParam(prevParam);
|
|
518
|
+
setIsFetching(false);
|
|
519
|
+
setIsFetchingNext(false);
|
|
520
|
+
setIsFetchingPrev(false);
|
|
521
|
+
});
|
|
522
|
+
onSuccess?.(newPages);
|
|
523
|
+
} catch (err) {
|
|
524
|
+
if (disposed || myRun !== runId) return;
|
|
525
|
+
if (err instanceof DOMException && err.name === "AbortError") return;
|
|
526
|
+
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
527
|
+
batch(() => {
|
|
528
|
+
setError(errorObj);
|
|
529
|
+
setIsFetching(false);
|
|
530
|
+
setIsFetchingNext(false);
|
|
531
|
+
setIsFetchingPrev(false);
|
|
532
|
+
});
|
|
533
|
+
onError?.(errorObj);
|
|
493
534
|
}
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
setIsFetching(false);
|
|
501
|
-
setIsFetchingNext(false);
|
|
502
|
-
setIsFetchingPrev(false);
|
|
503
|
-
});
|
|
504
|
-
onSuccess?.(newPages);
|
|
505
|
-
} catch (err) {
|
|
506
|
-
if (disposed || myRun !== runId) return;
|
|
507
|
-
if (err instanceof DOMException && err.name === "AbortError") return;
|
|
508
|
-
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
509
|
-
batch(() => {
|
|
510
|
-
setError(errorObj);
|
|
511
|
-
setIsFetching(false);
|
|
512
|
-
setIsFetchingNext(false);
|
|
513
|
-
setIsFetchingPrev(false);
|
|
514
|
-
});
|
|
515
|
-
onError?.(errorObj);
|
|
516
|
-
}
|
|
535
|
+
})();
|
|
536
|
+
inFlight = promise;
|
|
537
|
+
void promise.finally(() => {
|
|
538
|
+
if (inFlight === promise) inFlight = null;
|
|
539
|
+
});
|
|
540
|
+
return promise;
|
|
517
541
|
}
|
|
518
542
|
const effectCleanup = effect(() => {
|
|
519
543
|
resolveKey();
|
|
@@ -528,11 +552,13 @@ function infiniteQuery(key, fetcher, options) {
|
|
|
528
552
|
}
|
|
529
553
|
});
|
|
530
554
|
function fetchNextPage() {
|
|
555
|
+
if (inFlight) return inFlight;
|
|
531
556
|
const param = nextPageParam();
|
|
532
557
|
if (param === void 0) return Promise.resolve();
|
|
533
558
|
return fetchPage(param, "next");
|
|
534
559
|
}
|
|
535
560
|
function fetchPreviousPage() {
|
|
561
|
+
if (inFlight) return inFlight;
|
|
536
562
|
const param = prevPageParam();
|
|
537
563
|
if (param === void 0) return Promise.resolve();
|
|
538
564
|
return fetchPage(param, "prev");
|
|
@@ -571,13 +597,17 @@ function infiniteQuery(key, fetcher, options) {
|
|
|
571
597
|
function previous(getter) {
|
|
572
598
|
const [previous2, setPrevious] = signal(void 0);
|
|
573
599
|
let current = getter();
|
|
574
|
-
effect(() => {
|
|
600
|
+
const stop = effect(() => {
|
|
575
601
|
const next = getter();
|
|
576
602
|
if (!Object.is(next, current)) {
|
|
577
603
|
setPrevious(current);
|
|
578
604
|
current = next;
|
|
579
605
|
}
|
|
580
606
|
});
|
|
607
|
+
Object.defineProperty(previous2, "dispose", {
|
|
608
|
+
value: stop,
|
|
609
|
+
enumerable: false
|
|
610
|
+
});
|
|
581
611
|
return previous2;
|
|
582
612
|
}
|
|
583
613
|
|
|
@@ -585,7 +615,7 @@ function previous(getter) {
|
|
|
585
615
|
function debounce(getter, delay) {
|
|
586
616
|
const [debounced, setDebounced] = signal(getter());
|
|
587
617
|
let timer = null;
|
|
588
|
-
effect(() => {
|
|
618
|
+
const stop = effect(() => {
|
|
589
619
|
const value = getter();
|
|
590
620
|
if (timer !== null) clearTimeout(timer);
|
|
591
621
|
timer = setTimeout(() => {
|
|
@@ -593,6 +623,16 @@ function debounce(getter, delay) {
|
|
|
593
623
|
timer = null;
|
|
594
624
|
}, delay);
|
|
595
625
|
});
|
|
626
|
+
Object.defineProperty(debounced, "dispose", {
|
|
627
|
+
value: () => {
|
|
628
|
+
stop();
|
|
629
|
+
if (timer !== null) {
|
|
630
|
+
clearTimeout(timer);
|
|
631
|
+
timer = null;
|
|
632
|
+
}
|
|
633
|
+
},
|
|
634
|
+
enumerable: false
|
|
635
|
+
});
|
|
596
636
|
return debounced;
|
|
597
637
|
}
|
|
598
638
|
|
|
@@ -602,7 +642,8 @@ function throttle(getter, interval) {
|
|
|
602
642
|
let cooldown = false;
|
|
603
643
|
let pending = null;
|
|
604
644
|
let lastEmitted = getter();
|
|
605
|
-
|
|
645
|
+
let timer = null;
|
|
646
|
+
const stop = effect(() => {
|
|
606
647
|
const value = getter();
|
|
607
648
|
if (!cooldown) {
|
|
608
649
|
if (!Object.is(value, lastEmitted)) {
|
|
@@ -610,7 +651,8 @@ function throttle(getter, interval) {
|
|
|
610
651
|
lastEmitted = value;
|
|
611
652
|
cooldown = true;
|
|
612
653
|
pending = null;
|
|
613
|
-
setTimeout(() => {
|
|
654
|
+
timer = setTimeout(() => {
|
|
655
|
+
timer = null;
|
|
614
656
|
cooldown = false;
|
|
615
657
|
if (pending !== null) {
|
|
616
658
|
const trailingValue = pending.value;
|
|
@@ -624,6 +666,16 @@ function throttle(getter, interval) {
|
|
|
624
666
|
pending = { value };
|
|
625
667
|
}
|
|
626
668
|
});
|
|
669
|
+
Object.defineProperty(throttled, "dispose", {
|
|
670
|
+
value: () => {
|
|
671
|
+
stop();
|
|
672
|
+
if (timer !== null) {
|
|
673
|
+
clearTimeout(timer);
|
|
674
|
+
timer = null;
|
|
675
|
+
}
|
|
676
|
+
},
|
|
677
|
+
enumerable: false
|
|
678
|
+
});
|
|
627
679
|
return throttled;
|
|
628
680
|
}
|
|
629
681
|
|
|
@@ -752,28 +804,45 @@ function idbGet(db, store, key) {
|
|
|
752
804
|
req.onerror = () => reject(req.error);
|
|
753
805
|
});
|
|
754
806
|
}
|
|
755
|
-
function idbPut(db, store, item) {
|
|
807
|
+
function idbPut(db, store, item, key) {
|
|
756
808
|
return new Promise((resolve, reject) => {
|
|
757
809
|
const tx = db.transaction(store, "readwrite");
|
|
758
|
-
tx.objectStore(store).put(item);
|
|
810
|
+
if (key !== void 0) tx.objectStore(store).put(item, key);
|
|
811
|
+
else tx.objectStore(store).put(item);
|
|
759
812
|
tx.oncomplete = () => resolve();
|
|
760
813
|
tx.onerror = () => reject(tx.error);
|
|
761
814
|
});
|
|
762
815
|
}
|
|
763
|
-
function
|
|
816
|
+
function coalesceAndAddChange(tx, change, keyPath) {
|
|
817
|
+
const store = tx.objectStore("_changes");
|
|
818
|
+
const targetKey = change.item[keyPath];
|
|
819
|
+
const cursorReq = store.openCursor();
|
|
820
|
+
cursorReq.onsuccess = () => {
|
|
821
|
+
const cursor = cursorReq.result;
|
|
822
|
+
if (cursor) {
|
|
823
|
+
const existing = cursor.value;
|
|
824
|
+
const k = existing.item[keyPath];
|
|
825
|
+
if (targetKey != null && k === targetKey) cursor.delete();
|
|
826
|
+
cursor.continue();
|
|
827
|
+
} else {
|
|
828
|
+
store.put(change);
|
|
829
|
+
}
|
|
830
|
+
};
|
|
831
|
+
}
|
|
832
|
+
function idbPutWithChange(db, item, change, keyPath) {
|
|
764
833
|
return new Promise((resolve, reject) => {
|
|
765
834
|
const tx = db.transaction(["items", "_changes"], "readwrite");
|
|
766
835
|
tx.objectStore("items").put(item);
|
|
767
|
-
tx
|
|
836
|
+
coalesceAndAddChange(tx, change, keyPath);
|
|
768
837
|
tx.oncomplete = () => resolve();
|
|
769
838
|
tx.onerror = () => reject(tx.error);
|
|
770
839
|
});
|
|
771
840
|
}
|
|
772
|
-
function idbDeleteWithChange(db, key, change) {
|
|
841
|
+
function idbDeleteWithChange(db, key, change, keyPath) {
|
|
773
842
|
return new Promise((resolve, reject) => {
|
|
774
843
|
const tx = db.transaction(["items", "_changes"], "readwrite");
|
|
775
844
|
tx.objectStore("items").delete(key);
|
|
776
|
-
tx
|
|
845
|
+
coalesceAndAddChange(tx, change, keyPath);
|
|
777
846
|
tx.oncomplete = () => resolve();
|
|
778
847
|
tx.onerror = () => reject(tx.error);
|
|
779
848
|
});
|
|
@@ -833,13 +902,18 @@ async function offlineStore(options) {
|
|
|
833
902
|
setPendingCount(changes.length);
|
|
834
903
|
}
|
|
835
904
|
async function put(item) {
|
|
836
|
-
await idbPutWithChange(db, item, { type: "put", item, timestamp: Date.now() });
|
|
905
|
+
await idbPutWithChange(db, item, { type: "put", item, timestamp: Date.now() }, keyPath);
|
|
837
906
|
await refreshData();
|
|
838
907
|
}
|
|
839
908
|
async function remove(key) {
|
|
840
909
|
const existing = await idbGet(db, "items", key);
|
|
841
910
|
if (existing) {
|
|
842
|
-
await idbDeleteWithChange(
|
|
911
|
+
await idbDeleteWithChange(
|
|
912
|
+
db,
|
|
913
|
+
key,
|
|
914
|
+
{ type: "delete", item: existing, timestamp: Date.now() },
|
|
915
|
+
keyPath
|
|
916
|
+
);
|
|
843
917
|
await refreshData();
|
|
844
918
|
}
|
|
845
919
|
}
|
|
@@ -865,6 +939,8 @@ async function offlineStore(options) {
|
|
|
865
939
|
snapshot.map((e) => e.key)
|
|
866
940
|
);
|
|
867
941
|
if (closed) return;
|
|
942
|
+
} else if (typeof console !== "undefined") {
|
|
943
|
+
console.warn(`[offlineStore] push rejected by adapter${result.error ? `: ${result.error}` : ""}`);
|
|
868
944
|
}
|
|
869
945
|
}
|
|
870
946
|
const remoteItems = await adapter.pull(lastSynced());
|
|
@@ -883,7 +959,7 @@ async function offlineStore(options) {
|
|
|
883
959
|
await idbPutMany(db, "items", safeRemote);
|
|
884
960
|
if (closed) return;
|
|
885
961
|
const now = Date.now();
|
|
886
|
-
await idbPut(db, "_meta", now);
|
|
962
|
+
await idbPut(db, "_meta", now, "lastSynced");
|
|
887
963
|
if (closed) return;
|
|
888
964
|
setLastSynced(now);
|
|
889
965
|
await refreshData();
|
|
@@ -951,14 +1027,20 @@ function loaderData() {
|
|
|
951
1027
|
async function preloadRoute(route, context2, callerSignal) {
|
|
952
1028
|
if (!route.loader) return void 0;
|
|
953
1029
|
const controller = new AbortController();
|
|
1030
|
+
let onAbort = null;
|
|
954
1031
|
if (callerSignal) {
|
|
955
1032
|
if (callerSignal.aborted) {
|
|
956
1033
|
controller.abort();
|
|
957
1034
|
} else {
|
|
958
|
-
|
|
1035
|
+
onAbort = () => controller.abort();
|
|
1036
|
+
callerSignal.addEventListener("abort", onAbort, { once: true });
|
|
959
1037
|
}
|
|
960
1038
|
}
|
|
961
|
-
|
|
1039
|
+
try {
|
|
1040
|
+
return await route.loader(context2, { signal: controller.signal });
|
|
1041
|
+
} finally {
|
|
1042
|
+
if (onAbort) callerSignal?.removeEventListener("abort", onAbort);
|
|
1043
|
+
}
|
|
962
1044
|
}
|
|
963
1045
|
|
|
964
1046
|
// src/ui/socket.ts
|
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
import {
|
|
2
2
|
bindAttribute
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-RLUJL2MV.js";
|
|
4
4
|
import {
|
|
5
|
+
dispose,
|
|
5
6
|
registerDisposer
|
|
6
7
|
} from "./chunk-2UPRY23K.js";
|
|
7
8
|
import {
|
|
9
|
+
isEventHandlerAttr,
|
|
8
10
|
isUrlAttribute,
|
|
9
11
|
sanitizeCSSValue,
|
|
10
12
|
sanitizeSrcset,
|
|
11
13
|
sanitizeUrl
|
|
12
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-HMJFCBRR.js";
|
|
13
15
|
import {
|
|
14
16
|
reactiveBinding,
|
|
15
17
|
track
|
|
16
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-Z2FWAE4B.js";
|
|
17
19
|
import {
|
|
18
20
|
devWarn,
|
|
19
21
|
isDev
|
|
@@ -34,6 +36,7 @@ function bindChildNode(placeholder, getter) {
|
|
|
34
36
|
if (result == null || typeof result === "boolean") {
|
|
35
37
|
for (let i = 0; i < lastNodes.length; i++) {
|
|
36
38
|
const node = lastNodes[i];
|
|
39
|
+
dispose(node);
|
|
37
40
|
if (node.parentNode) node.parentNode.removeChild(node);
|
|
38
41
|
}
|
|
39
42
|
lastNodes.length = 0;
|
|
@@ -75,18 +78,16 @@ function bindChildNode(placeholder, getter) {
|
|
|
75
78
|
for (let i = 0; i < lastNodes.length; i++) {
|
|
76
79
|
const node = lastNodes[i];
|
|
77
80
|
if (reused?.has(node)) continue;
|
|
81
|
+
dispose(node);
|
|
78
82
|
if (node.parentNode) node.parentNode.removeChild(node);
|
|
79
83
|
}
|
|
80
|
-
|
|
84
|
+
let prev = placeholder;
|
|
81
85
|
for (let i = 0; i < newNodes.length; i++) {
|
|
82
86
|
const node = newNodes[i];
|
|
83
|
-
if (
|
|
84
|
-
|
|
85
|
-
parent.insertBefore(node, anchor);
|
|
86
|
-
}
|
|
87
|
-
} else {
|
|
88
|
-
parent.insertBefore(node, anchor);
|
|
87
|
+
if (prev.nextSibling !== node) {
|
|
88
|
+
parent.insertBefore(node, prev.nextSibling);
|
|
89
89
|
}
|
|
90
|
+
prev = node;
|
|
90
91
|
}
|
|
91
92
|
lastNodes = newNodes;
|
|
92
93
|
}
|
|
@@ -328,7 +329,7 @@ var tagFactory = (tag, ns) => {
|
|
|
328
329
|
const value = props[key];
|
|
329
330
|
if (value == null) continue;
|
|
330
331
|
const lkey = key.toLowerCase();
|
|
331
|
-
if (
|
|
332
|
+
if (isEventHandlerAttr(key)) continue;
|
|
332
333
|
if (typeof value === "function") {
|
|
333
334
|
registerDisposer(el, bindAttribute(el, key, value));
|
|
334
335
|
} else if (typeof value === "boolean") {
|
|
@@ -179,7 +179,7 @@ function track(effectFn, subscriber) {
|
|
|
179
179
|
function reactiveBinding(commit) {
|
|
180
180
|
const run = () => {
|
|
181
181
|
const s = subscriber;
|
|
182
|
-
if (s._reentrant) return;
|
|
182
|
+
if (s._disposed || s._reentrant) return;
|
|
183
183
|
s._reentrant = true;
|
|
184
184
|
try {
|
|
185
185
|
retrack(commit, subscriber);
|
|
@@ -195,8 +195,12 @@ function reactiveBinding(commit) {
|
|
|
195
195
|
subscriber._runEpoch = 0;
|
|
196
196
|
subscriber._runs = 0;
|
|
197
197
|
subscriber._reentrant = false;
|
|
198
|
+
subscriber._disposed = false;
|
|
198
199
|
run();
|
|
199
|
-
return subscriber._dispose ?? (subscriber._dispose = () =>
|
|
200
|
+
return subscriber._dispose ?? (subscriber._dispose = () => {
|
|
201
|
+
subscriber._disposed = true;
|
|
202
|
+
cleanup(subscriber);
|
|
203
|
+
});
|
|
200
204
|
}
|
|
201
205
|
function recordDependency(signal) {
|
|
202
206
|
if (!currentSubscriber) return;
|