sibujs 4.5.0 → 4.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser.cjs +309 -129
- package/dist/browser.d.cts +46 -14
- package/dist/browser.d.ts +46 -14
- package/dist/browser.js +8 -6
- package/dist/build.cjs +184 -72
- package/dist/build.js +15 -16
- package/dist/cdn.dev.global.js +12 -12
- package/dist/cdn.full.dev.global.js +11 -11
- package/dist/cdn.full.global.js +10 -10
- package/dist/cdn.global.js +12 -12
- package/dist/{chunk-IXKSNWV5.js → chunk-2INLLLMZ.js} +1 -1
- package/dist/chunk-3ISI6ACU.js +44 -0
- package/dist/{chunk-ONOHFDLG.js → chunk-47M47FOM.js} +3 -3
- package/dist/chunk-5HZXGZ6T.js +24 -0
- package/dist/{chunk-KKLW7YWL.js → chunk-5MT6SJ3P.js} +275 -144
- package/dist/{chunk-UGRX3S57.js → chunk-5Q4R7HCL.js} +12 -3
- package/dist/{chunk-S373NSMK.js → chunk-7GQCWFOE.js} +150 -59
- package/dist/{chunk-FTIR4QW2.js → chunk-7NCARGJW.js} +6 -8
- package/dist/{chunk-5DXA2J44.js → chunk-7XHATCIH.js} +5 -2
- package/dist/{chunk-VZKNK2V7.js → chunk-AIF3Z2T7.js} +296 -38
- package/dist/{chunk-4PMLNECI.js → chunk-BAAG6ZTI.js} +98 -29
- package/dist/{chunk-XZZOBQAY.js → chunk-D33YTSX5.js} +2 -2
- package/dist/{chunk-TBYTO6BS.js → chunk-DKGBBKOF.js} +136 -80
- package/dist/{chunk-NIOYEGBQ.js → chunk-HURREPU2.js} +27 -13
- package/dist/{chunk-GW3SCCZG.js → chunk-HYXDKS4N.js} +153 -110
- package/dist/chunk-J6FW5TV6.js +233 -0
- package/dist/{chunk-PCT43HW3.js → chunk-JSXPZCET.js} +1 -1
- package/dist/chunk-NYNYSPK7.js +318 -0
- package/dist/{chunk-RJE2BNI4.js → chunk-ORMZXBKQ.js} +108 -45
- package/dist/{chunk-OMJJM3KM.js → chunk-OXUY2A6L.js} +287 -130
- package/dist/{chunk-3JZ4L5TJ.js → chunk-PK6FK2G2.js} +181 -66
- package/dist/{chunk-RBTPLM32.js → chunk-QE4TTDU3.js} +2 -2
- package/dist/{chunk-2DCGACUU.js → chunk-SXXVZMKZ.js} +251 -66
- package/dist/{chunk-R25EFXXC.js → chunk-TUCPL2HB.js} +3 -3
- package/dist/{chunk-7LN645I6.js → chunk-UZQ6ALFS.js} +3 -3
- package/dist/{chunk-KEISJXBU.js → chunk-VVWPJ543.js} +6 -8
- package/dist/{chunk-RIXRAYIU.js → chunk-XC4MEKGA.js} +3 -3
- package/dist/{chunk-B3WHI2QA.js → chunk-XRRZKZYX.js} +55 -31
- package/dist/{contracts-DBdg9J_a.d.cts → contracts-DRIuclVT.d.cts} +10 -2
- package/dist/{contracts-DBdg9J_a.d.ts → contracts-DRIuclVT.d.ts} +10 -2
- package/dist/{customElement-OB9CIsc5.d.cts → customElement-MmInOW1U.d.cts} +21 -0
- package/dist/{customElement-OB9CIsc5.d.ts → customElement-MmInOW1U.d.ts} +21 -0
- package/dist/data.cjs +213 -117
- package/dist/data.d.cts +47 -9
- package/dist/data.d.ts +47 -9
- package/dist/data.js +12 -9
- package/dist/devtools.cjs +81 -57
- package/dist/devtools.js +7 -8
- package/dist/dispose-GEIG2KOF.js +28 -0
- package/dist/ecosystem.cjs +309 -104
- package/dist/ecosystem.d.cts +19 -3
- package/dist/ecosystem.d.ts +19 -3
- package/dist/ecosystem.js +12 -12
- package/dist/extras.cjs +2133 -863
- package/dist/extras.d.cts +10 -9
- package/dist/extras.d.ts +10 -9
- package/dist/extras.js +39 -28
- package/dist/index.cjs +184 -72
- package/dist/index.d.cts +22 -5
- package/dist/index.d.ts +22 -5
- package/dist/index.js +24 -27
- package/dist/motion.cjs +107 -41
- package/dist/motion.js +5 -5
- package/dist/patterns.cjs +317 -39
- package/dist/patterns.d.cts +27 -9
- package/dist/patterns.d.ts +27 -9
- package/dist/patterns.js +8 -8
- package/dist/performance.cjs +308 -216
- package/dist/performance.d.cts +2 -2
- package/dist/performance.d.ts +2 -2
- package/dist/performance.js +8 -9
- package/dist/plugin-DVgSnTfK.d.cts +112 -0
- package/dist/plugin-DVgSnTfK.d.ts +112 -0
- package/dist/plugins.cjs +549 -202
- package/dist/plugins.d.cts +3 -3
- package/dist/plugins.d.ts +3 -3
- package/dist/plugins.js +35 -23
- package/dist/signal-EotCj4hS.d.cts +110 -0
- package/dist/signal-EotCj4hS.d.ts +110 -0
- package/dist/{ssr-BiPRdZ6n.d.cts → ssr-Bli9XRW5.d.cts} +5 -0
- package/dist/{ssr-BiPRdZ6n.d.ts → ssr-Bli9XRW5.d.ts} +5 -0
- package/dist/{ssr-Y7XOEPEN.js → ssr-XOTUASDO.js} +4 -5
- package/dist/ssr.cjs +176 -72
- package/dist/ssr.d.cts +9 -3
- package/dist/ssr.d.ts +9 -3
- package/dist/ssr.js +11 -12
- package/dist/{startup-BMpaiMhP.d.ts → startup-BLfSeL15.d.cts} +73 -22
- package/dist/{startup-BMpaiMhP.d.cts → startup-BLfSeL15.d.ts} +73 -22
- package/dist/{tagFactory-DVoDpHye.d.ts → tagFactory-DFstCLQV.d.cts} +2 -100
- package/dist/{tagFactory-DVoDpHye.d.cts → tagFactory-DkaNVUNV.d.ts} +2 -100
- package/dist/testing.cjs +2484 -2185
- package/dist/testing.d.cts +56 -5
- package/dist/testing.d.ts +56 -5
- package/dist/testing.js +580 -307
- package/dist/ui.cjs +707 -317
- package/dist/ui.d.cts +40 -7
- package/dist/ui.d.ts +40 -7
- package/dist/ui.js +151 -56
- package/dist/widgets.cjs +246 -278
- package/dist/widgets.js +9 -10
- package/package.json +1 -1
- package/dist/chunk-2WLZ6757.js +0 -149
- package/dist/chunk-CCSJMTRN.js +0 -15
- package/dist/chunk-QKRPLZ2V.js +0 -108
- package/dist/chunk-VUF4ALSW.js +0 -60
- package/dist/chunk-WWV3SJ3L.js +0 -131
- package/dist/dispose-46BOMMQJ.js +0 -19
- package/dist/plugin-D30wlGW5.d.cts +0 -71
- package/dist/plugin-D30wlGW5.d.ts +0 -71
package/dist/extras.cjs
CHANGED
|
@@ -24,6 +24,8 @@ __export(extras_exports, {
|
|
|
24
24
|
Features: () => Features,
|
|
25
25
|
FocusTrap: () => FocusTrap,
|
|
26
26
|
Head: () => Head,
|
|
27
|
+
MigrationStorageError: () => MigrationStorageError,
|
|
28
|
+
PluginInstallCancelledError: () => PluginInstallCancelledError,
|
|
27
29
|
Priority: () => Priority,
|
|
28
30
|
RenderProp: () => RenderProp,
|
|
29
31
|
SibuError: () => SibuError,
|
|
@@ -32,6 +34,7 @@ __export(extras_exports, {
|
|
|
32
34
|
VirtualList: () => VirtualList,
|
|
33
35
|
__resetDialogStack: () => __resetDialogStack,
|
|
34
36
|
__resetQueryCache: () => __resetQueryCache,
|
|
37
|
+
__resetSpeechCoordinator: () => __resetSpeechCoordinator,
|
|
35
38
|
accordion: () => accordion,
|
|
36
39
|
animate: () => animate,
|
|
37
40
|
animationFrame: () => animationFrame,
|
|
@@ -167,6 +170,7 @@ __export(extras_exports, {
|
|
|
167
170
|
isDangerousMetaRefresh: () => isDangerousMetaRefresh,
|
|
168
171
|
isDebugEnabled: () => isDebugEnabled,
|
|
169
172
|
isHMRAvailable: () => isHMRAvailable,
|
|
173
|
+
isPluginInstallCancelledError: () => isPluginInstallCancelledError,
|
|
170
174
|
isWasmCached: () => isWasmCached,
|
|
171
175
|
island: () => island,
|
|
172
176
|
keyboard: () => keyboard,
|
|
@@ -234,6 +238,7 @@ __export(extras_exports, {
|
|
|
234
238
|
renderToStream: () => renderToStream,
|
|
235
239
|
renderToString: () => renderToString,
|
|
236
240
|
renderToSuspenseStream: () => renderToSuspenseStream,
|
|
241
|
+
renderWithLoader: () => renderWithLoader,
|
|
237
242
|
required: () => required,
|
|
238
243
|
resetIdCounter: () => resetIdCounter,
|
|
239
244
|
resetPlugins: () => resetPlugins,
|
|
@@ -305,6 +310,7 @@ __export(extras_exports, {
|
|
|
305
310
|
withBoundary: () => withBoundary,
|
|
306
311
|
withDefaults: () => withDefaults,
|
|
307
312
|
withErrorTracking: () => withErrorTracking,
|
|
313
|
+
withLoader: () => withLoader,
|
|
308
314
|
withProps: () => withProps,
|
|
309
315
|
withRetry: () => withRetry,
|
|
310
316
|
withScopedStyle: () => withScopedStyle,
|
|
@@ -367,8 +373,8 @@ function safeStringify(value) {
|
|
|
367
373
|
return Object.prototype.toString.call(value);
|
|
368
374
|
}
|
|
369
375
|
}
|
|
370
|
-
function describe(
|
|
371
|
-
return
|
|
376
|
+
function describe(context) {
|
|
377
|
+
return context.name ? `${context.phase} "${context.name}"` : context.phase;
|
|
372
378
|
}
|
|
373
379
|
var REACTIVE_REGISTRY_KEY = /* @__PURE__ */ Symbol.for("sibujs.reactive.v1");
|
|
374
380
|
function untrackedRun(fn) {
|
|
@@ -376,8 +382,8 @@ function untrackedRun(fn) {
|
|
|
376
382
|
return api?.untracked ? api.untracked(fn) : fn();
|
|
377
383
|
}
|
|
378
384
|
var PROPAGATE_EVENT = "sibu:error-propagate";
|
|
379
|
-
function claimedByBoundary(error,
|
|
380
|
-
const raw =
|
|
385
|
+
function claimedByBoundary(error, context) {
|
|
386
|
+
const raw = context.node;
|
|
381
387
|
if (!raw || typeof CustomEvent === "undefined") return false;
|
|
382
388
|
const target = resolveEventTarget(raw);
|
|
383
389
|
if (!target) return false;
|
|
@@ -385,7 +391,7 @@ function claimedByBoundary(error, context2) {
|
|
|
385
391
|
const event = new CustomEvent(PROPAGATE_EVENT, {
|
|
386
392
|
bubbles: true,
|
|
387
393
|
cancelable: true,
|
|
388
|
-
detail: { error, context
|
|
394
|
+
detail: { error, context }
|
|
389
395
|
});
|
|
390
396
|
return target.dispatchEvent(event) === false;
|
|
391
397
|
} catch {
|
|
@@ -404,20 +410,20 @@ function resolveEventTarget(node) {
|
|
|
404
410
|
const self2 = node;
|
|
405
411
|
return typeof self2.dispatchEvent === "function" ? self2 : null;
|
|
406
412
|
}
|
|
407
|
-
function defaultReport(error,
|
|
413
|
+
function defaultReport(error, context) {
|
|
408
414
|
if (typeof console === "undefined") return;
|
|
409
|
-
console.error(`[SibuJS] Uncaught error during ${describe(
|
|
415
|
+
console.error(`[SibuJS] Uncaught error during ${describe(context)}: ${error.message}`, error);
|
|
410
416
|
}
|
|
411
|
-
function reportError(error,
|
|
417
|
+
function reportError(error, context) {
|
|
412
418
|
const err = normalizeError(error);
|
|
413
419
|
untrackedRun(() => {
|
|
414
|
-
if (claimedByBoundary(err,
|
|
420
|
+
if (claimedByBoundary(err, context)) return;
|
|
415
421
|
const s2 = state();
|
|
416
422
|
const handler = s2.handler;
|
|
417
423
|
if (handler && s2.handlerDepth === 0) {
|
|
418
424
|
s2.handlerDepth++;
|
|
419
425
|
try {
|
|
420
|
-
handler(error instanceof Error ? error : err,
|
|
426
|
+
handler(error instanceof Error ? error : err, context);
|
|
421
427
|
return;
|
|
422
428
|
} catch (handlerError) {
|
|
423
429
|
if (typeof console !== "undefined") {
|
|
@@ -428,10 +434,158 @@ function reportError(error, context2) {
|
|
|
428
434
|
s2.handlerDepth--;
|
|
429
435
|
}
|
|
430
436
|
}
|
|
431
|
-
defaultReport(err,
|
|
437
|
+
defaultReport(err, context);
|
|
432
438
|
});
|
|
433
439
|
}
|
|
434
440
|
|
|
441
|
+
// src/core/rendering/dispose.ts
|
|
442
|
+
var elementDisposers = /* @__PURE__ */ new WeakMap();
|
|
443
|
+
var MAX_DRAIN_TEARDOWNS = 1e4;
|
|
444
|
+
function reportDrainRunaway(label2, executed, remaining) {
|
|
445
|
+
if (typeof console === "undefined") return;
|
|
446
|
+
console.error(
|
|
447
|
+
`[SibuJS ${label2}] runaway cleanup: stopped after running ${executed} teardowns with ${remaining} still queued. Cleanup production did not stabilize before the teardown safety ceiling was reached \u2014 the remaining work was NOT run.`,
|
|
448
|
+
{ executed, remaining }
|
|
449
|
+
);
|
|
450
|
+
}
|
|
451
|
+
var activeBindingCount = 0;
|
|
452
|
+
function resolveCapture(capture) {
|
|
453
|
+
let frame = capture;
|
|
454
|
+
while (frame?.closed) frame = frame.forwardTo;
|
|
455
|
+
return frame ?? null;
|
|
456
|
+
}
|
|
457
|
+
var registrationCaptures = [];
|
|
458
|
+
function currentDisposerCapture() {
|
|
459
|
+
return resolveCapture(registrationCaptures[registrationCaptures.length - 1]);
|
|
460
|
+
}
|
|
461
|
+
function beginDisposerCapture(capture) {
|
|
462
|
+
if (capture === null && registrationCaptures.length === 0) return false;
|
|
463
|
+
registrationCaptures.push(resolveCapture(capture));
|
|
464
|
+
return true;
|
|
465
|
+
}
|
|
466
|
+
function endDisposerCapture() {
|
|
467
|
+
registrationCaptures.pop();
|
|
468
|
+
}
|
|
469
|
+
function registerDisposer(node, teardown) {
|
|
470
|
+
let disposers = elementDisposers.get(node);
|
|
471
|
+
if (!disposers) {
|
|
472
|
+
disposers = [];
|
|
473
|
+
elementDisposers.set(node, disposers);
|
|
474
|
+
}
|
|
475
|
+
disposers.push(teardown);
|
|
476
|
+
if (DEV) activeBindingCount++;
|
|
477
|
+
const capture = resolveCapture(registrationCaptures[registrationCaptures.length - 1]);
|
|
478
|
+
if (capture) capture.entries.push([node, teardown]);
|
|
479
|
+
}
|
|
480
|
+
function withDisposerRollback(build) {
|
|
481
|
+
const frame = { entries: [], closed: false };
|
|
482
|
+
const captured = frame.entries;
|
|
483
|
+
registrationCaptures.push(frame);
|
|
484
|
+
let result;
|
|
485
|
+
try {
|
|
486
|
+
result = build();
|
|
487
|
+
} catch (err) {
|
|
488
|
+
let executed = 0;
|
|
489
|
+
try {
|
|
490
|
+
while (captured.length > 0) {
|
|
491
|
+
if (executed >= MAX_DRAIN_TEARDOWNS) {
|
|
492
|
+
reportDrainRunaway("rollback", executed, captured.length);
|
|
493
|
+
break;
|
|
494
|
+
}
|
|
495
|
+
const [node, teardown] = captured.pop();
|
|
496
|
+
if (!unregisterDisposer(node, teardown)) continue;
|
|
497
|
+
executed++;
|
|
498
|
+
try {
|
|
499
|
+
teardown();
|
|
500
|
+
} catch (cleanupErr) {
|
|
501
|
+
reportError(cleanupErr, { phase: "cleanup", name: "disposer" });
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
} finally {
|
|
505
|
+
frame.closed = true;
|
|
506
|
+
captured.length = 0;
|
|
507
|
+
registrationCaptures.pop();
|
|
508
|
+
}
|
|
509
|
+
throw err;
|
|
510
|
+
}
|
|
511
|
+
frame.closed = true;
|
|
512
|
+
registrationCaptures.pop();
|
|
513
|
+
const parent = resolveCapture(registrationCaptures[registrationCaptures.length - 1]);
|
|
514
|
+
if (parent) {
|
|
515
|
+
for (const entry of captured) {
|
|
516
|
+
if (elementDisposers.get(entry[0])?.includes(entry[1])) parent.entries.push(entry);
|
|
517
|
+
}
|
|
518
|
+
frame.forwardTo = parent;
|
|
519
|
+
}
|
|
520
|
+
captured.length = 0;
|
|
521
|
+
return result;
|
|
522
|
+
}
|
|
523
|
+
function unregisterDisposer(node, teardown) {
|
|
524
|
+
const disposers = elementDisposers.get(node);
|
|
525
|
+
if (!disposers) return false;
|
|
526
|
+
const index = disposers.indexOf(teardown);
|
|
527
|
+
if (index === -1) return false;
|
|
528
|
+
disposers.splice(index, 1);
|
|
529
|
+
if (DEV) activeBindingCount--;
|
|
530
|
+
if (disposers.length === 0) elementDisposers.delete(node);
|
|
531
|
+
return true;
|
|
532
|
+
}
|
|
533
|
+
function dispose(node) {
|
|
534
|
+
const stack = [node];
|
|
535
|
+
const order = [];
|
|
536
|
+
while (stack.length > 0) {
|
|
537
|
+
const current = stack.pop();
|
|
538
|
+
order.push(current);
|
|
539
|
+
const children = Array.from(current.childNodes);
|
|
540
|
+
for (let i2 = 0; i2 < children.length; i2++) {
|
|
541
|
+
stack.push(children[i2]);
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
for (let i2 = order.length - 1; i2 >= 0; i2--) {
|
|
545
|
+
disposeNodeOwn(order[i2]);
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
function disposeNodeOwn(node) {
|
|
549
|
+
if (!elementDisposers.has(node)) return;
|
|
550
|
+
let executed = 0;
|
|
551
|
+
let runaway = false;
|
|
552
|
+
while (!runaway) {
|
|
553
|
+
const pending = elementDisposers.get(node);
|
|
554
|
+
if (!pending || pending.length === 0) break;
|
|
555
|
+
const snapshot = pending.slice();
|
|
556
|
+
elementDisposers.delete(node);
|
|
557
|
+
if (DEV) activeBindingCount -= snapshot.length;
|
|
558
|
+
for (let i2 = 0; i2 < snapshot.length; i2++) {
|
|
559
|
+
if (executed >= MAX_DRAIN_TEARDOWNS) {
|
|
560
|
+
const rest = snapshot.slice(i2);
|
|
561
|
+
const added = elementDisposers.get(node);
|
|
562
|
+
elementDisposers.set(node, added ? rest.concat(added) : rest);
|
|
563
|
+
if (DEV) activeBindingCount += rest.length;
|
|
564
|
+
reportDrainRunaway("dispose", executed, rest.length + (added?.length ?? 0));
|
|
565
|
+
runaway = true;
|
|
566
|
+
break;
|
|
567
|
+
}
|
|
568
|
+
executed++;
|
|
569
|
+
try {
|
|
570
|
+
snapshot[i2]();
|
|
571
|
+
} catch (err) {
|
|
572
|
+
reportError(err, { phase: "cleanup", name: "disposer" });
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
function replaceChildrenSafely(parent, ...next) {
|
|
578
|
+
for (let i2 = 0; i2 < next.length; i2++) {
|
|
579
|
+
const node = next[i2];
|
|
580
|
+
node.parentNode?.removeChild(node);
|
|
581
|
+
}
|
|
582
|
+
const current = Array.from(parent.childNodes);
|
|
583
|
+
for (let i2 = 0; i2 < current.length; i2++) {
|
|
584
|
+
dispose(current[i2]);
|
|
585
|
+
}
|
|
586
|
+
parent.replaceChildren(...next);
|
|
587
|
+
}
|
|
588
|
+
|
|
435
589
|
// src/reactivity/track-core.ts
|
|
436
590
|
var POOL_MAX = 4096;
|
|
437
591
|
var nodePool = [];
|
|
@@ -590,6 +744,7 @@ function retrack(effectFn, subscriber) {
|
|
|
590
744
|
}
|
|
591
745
|
currentSubscriber = subscriber;
|
|
592
746
|
const sub2 = subscriber;
|
|
747
|
+
if (sub2._cap === void 0) sub2._cap = currentDisposerCapture();
|
|
593
748
|
const epoch = ++subscriberEpochCounter;
|
|
594
749
|
sub2._epoch = epoch;
|
|
595
750
|
sub2._structDirty = false;
|
|
@@ -781,7 +936,12 @@ function drainQueue() {
|
|
|
781
936
|
quarantined.add(sub2);
|
|
782
937
|
continue;
|
|
783
938
|
}
|
|
784
|
-
|
|
939
|
+
const pushed = beginDisposerCapture(sub2._cap ?? null);
|
|
940
|
+
try {
|
|
941
|
+
safeInvoke(sub2);
|
|
942
|
+
} finally {
|
|
943
|
+
if (pushed) endDisposerCapture();
|
|
944
|
+
}
|
|
785
945
|
}
|
|
786
946
|
}
|
|
787
947
|
function drainNotificationQueue() {
|
|
@@ -917,7 +1077,7 @@ function forEachSubscriber(signal2, visit) {
|
|
|
917
1077
|
}
|
|
918
1078
|
|
|
919
1079
|
// src/reactivity/track.ts
|
|
920
|
-
var _runtimeVersion = true ? "4.
|
|
1080
|
+
var _runtimeVersion = true ? "4.6.0" : "dev";
|
|
921
1081
|
var REGISTRY_KEY = /* @__PURE__ */ Symbol.for("sibujs.reactive.v1");
|
|
922
1082
|
function resolveReactiveApi() {
|
|
923
1083
|
const g2 = globalThis;
|
|
@@ -1118,6 +1278,10 @@ function getSSRStore() {
|
|
|
1118
1278
|
}
|
|
1119
1279
|
return fallbackStore;
|
|
1120
1280
|
}
|
|
1281
|
+
function getRequestStore() {
|
|
1282
|
+
if (als) return als.getStore() ?? null;
|
|
1283
|
+
return _shared.fallbackDepth > 0 ? fallbackStore : null;
|
|
1284
|
+
}
|
|
1121
1285
|
function isSSR() {
|
|
1122
1286
|
return getSSRStore().ssr;
|
|
1123
1287
|
}
|
|
@@ -1839,7 +2003,7 @@ function mutation(mutationFn, options = {}) {
|
|
|
1839
2003
|
abortController = new AbortController();
|
|
1840
2004
|
const signal2 = abortController.signal;
|
|
1841
2005
|
const myRun = ++runId;
|
|
1842
|
-
let
|
|
2006
|
+
let context;
|
|
1843
2007
|
batch(() => {
|
|
1844
2008
|
setLoading(true);
|
|
1845
2009
|
setError(void 0);
|
|
@@ -1847,7 +2011,7 @@ function mutation(mutationFn, options = {}) {
|
|
|
1847
2011
|
});
|
|
1848
2012
|
try {
|
|
1849
2013
|
if (options.onMutate) {
|
|
1850
|
-
|
|
2014
|
+
context = await options.onMutate(variables);
|
|
1851
2015
|
}
|
|
1852
2016
|
const result = await withRetry(() => mutationFn(variables, signal2), options.retry, void 0, signal2);
|
|
1853
2017
|
if (myRun !== runId) return result;
|
|
@@ -1858,8 +2022,8 @@ function mutation(mutationFn, options = {}) {
|
|
|
1858
2022
|
setLoading(false);
|
|
1859
2023
|
setStatus("success");
|
|
1860
2024
|
});
|
|
1861
|
-
runCallback("mutation onSuccess", () => options.onSuccess?.(result, variables,
|
|
1862
|
-
runCallback("mutation onSettled", () => options.onSettled?.(result, void 0, variables,
|
|
2025
|
+
runCallback("mutation onSuccess", () => options.onSuccess?.(result, variables, context));
|
|
2026
|
+
runCallback("mutation onSettled", () => options.onSettled?.(result, void 0, variables, context));
|
|
1863
2027
|
return result;
|
|
1864
2028
|
} catch (err) {
|
|
1865
2029
|
if (isAbortError(err)) {
|
|
@@ -1881,8 +2045,8 @@ function mutation(mutationFn, options = {}) {
|
|
|
1881
2045
|
setLoading(false);
|
|
1882
2046
|
setStatus("error");
|
|
1883
2047
|
});
|
|
1884
|
-
runCallback("mutation onError", () => options.onError?.(errorObj, variables,
|
|
1885
|
-
runCallback("mutation onSettled", () => options.onSettled?.(void 0, errorObj, variables,
|
|
2048
|
+
runCallback("mutation onError", () => options.onError?.(errorObj, variables, context));
|
|
2049
|
+
runCallback("mutation onSettled", () => options.onSettled?.(void 0, errorObj, variables, context));
|
|
1886
2050
|
throw errorObj;
|
|
1887
2051
|
}
|
|
1888
2052
|
}
|
|
@@ -2020,18 +2184,21 @@ function infiniteQuery(key, fetcher, options) {
|
|
|
2020
2184
|
}
|
|
2021
2185
|
});
|
|
2022
2186
|
function fetchNextPage() {
|
|
2187
|
+
if (disposed) return Promise.resolve();
|
|
2023
2188
|
if (inFlight) return inFlight;
|
|
2024
2189
|
const param2 = nextPageParam();
|
|
2025
2190
|
if (param2 === void 0) return Promise.resolve();
|
|
2026
2191
|
return fetchPage(param2, "next");
|
|
2027
2192
|
}
|
|
2028
2193
|
function fetchPreviousPage() {
|
|
2194
|
+
if (disposed) return Promise.resolve();
|
|
2029
2195
|
if (inFlight) return inFlight;
|
|
2030
2196
|
const param2 = prevPageParam();
|
|
2031
2197
|
if (param2 === void 0) return Promise.resolve();
|
|
2032
2198
|
return fetchPage(param2, "prev");
|
|
2033
2199
|
}
|
|
2034
2200
|
async function refetch() {
|
|
2201
|
+
if (disposed) return;
|
|
2035
2202
|
batch(() => {
|
|
2036
2203
|
setPages([]);
|
|
2037
2204
|
setNextPageParam(initialPageParam);
|
|
@@ -2115,25 +2282,26 @@ function throttle(getter, interval) {
|
|
|
2115
2282
|
let pending = null;
|
|
2116
2283
|
let lastEmitted = getter();
|
|
2117
2284
|
let timer = null;
|
|
2285
|
+
function emit(value) {
|
|
2286
|
+
setThrottled(value);
|
|
2287
|
+
lastEmitted = value;
|
|
2288
|
+
cooldown = true;
|
|
2289
|
+
pending = null;
|
|
2290
|
+
timer = setTimeout(endWindow, interval);
|
|
2291
|
+
}
|
|
2292
|
+
function endWindow() {
|
|
2293
|
+
timer = null;
|
|
2294
|
+
if (pending !== null && !Object.is(pending.value, lastEmitted)) {
|
|
2295
|
+
emit(pending.value);
|
|
2296
|
+
return;
|
|
2297
|
+
}
|
|
2298
|
+
pending = null;
|
|
2299
|
+
cooldown = false;
|
|
2300
|
+
}
|
|
2118
2301
|
const stop2 = effect(() => {
|
|
2119
2302
|
const value = getter();
|
|
2120
2303
|
if (!cooldown) {
|
|
2121
|
-
if (!Object.is(value, lastEmitted))
|
|
2122
|
-
setThrottled(value);
|
|
2123
|
-
lastEmitted = value;
|
|
2124
|
-
cooldown = true;
|
|
2125
|
-
pending = null;
|
|
2126
|
-
timer = setTimeout(() => {
|
|
2127
|
-
timer = null;
|
|
2128
|
-
cooldown = false;
|
|
2129
|
-
if (pending !== null) {
|
|
2130
|
-
const trailingValue = pending.value;
|
|
2131
|
-
pending = null;
|
|
2132
|
-
setThrottled(trailingValue);
|
|
2133
|
-
lastEmitted = trailingValue;
|
|
2134
|
-
}
|
|
2135
|
-
}, interval);
|
|
2136
|
-
}
|
|
2304
|
+
if (!Object.is(value, lastEmitted)) emit(value);
|
|
2137
2305
|
} else {
|
|
2138
2306
|
pending = { value };
|
|
2139
2307
|
}
|
|
@@ -2207,7 +2375,7 @@ function resource(sourceOrFetcher, fetcherOrOptions, maybeOptions) {
|
|
|
2207
2375
|
});
|
|
2208
2376
|
runCallback("resource onError", () => options.onError?.(errorObj));
|
|
2209
2377
|
} finally {
|
|
2210
|
-
if (version === fetchVersion) {
|
|
2378
|
+
if (!disposed && version === fetchVersion) {
|
|
2211
2379
|
runCallback("resource onSettled", () => options.onSettled?.());
|
|
2212
2380
|
}
|
|
2213
2381
|
}
|
|
@@ -2513,62 +2681,55 @@ function syncAdapter(config) {
|
|
|
2513
2681
|
return config;
|
|
2514
2682
|
}
|
|
2515
2683
|
|
|
2516
|
-
// src/core/rendering/context.ts
|
|
2517
|
-
function context(defaultValue) {
|
|
2518
|
-
const [getValue, setValue] = signal(defaultValue);
|
|
2519
|
-
const warnIfSSR = (method) => {
|
|
2520
|
-
if (!DEV || !isSSR()) return;
|
|
2521
|
-
devWarn(
|
|
2522
|
-
`context.${method}() called during SSR. SibuJS context() is application-global \u2014 it is NOT isolated per request, so a concurrent request can observe this value. Do not use context() for request-specific SSR data; pass it explicitly or use request-scoped storage instead.`
|
|
2523
|
-
);
|
|
2524
|
-
};
|
|
2525
|
-
const ctx = {
|
|
2526
|
-
provide(value) {
|
|
2527
|
-
warnIfSSR("provide");
|
|
2528
|
-
const previous2 = getValue();
|
|
2529
|
-
setValue(value);
|
|
2530
|
-
return () => setValue(previous2);
|
|
2531
|
-
},
|
|
2532
|
-
use() {
|
|
2533
|
-
return getValue;
|
|
2534
|
-
},
|
|
2535
|
-
get() {
|
|
2536
|
-
return getValue();
|
|
2537
|
-
},
|
|
2538
|
-
set(value) {
|
|
2539
|
-
warnIfSSR("set");
|
|
2540
|
-
setValue(value);
|
|
2541
|
-
},
|
|
2542
|
-
withContext(value, fn) {
|
|
2543
|
-
warnIfSSR("withContext");
|
|
2544
|
-
const previous2 = getValue();
|
|
2545
|
-
setValue(value);
|
|
2546
|
-
try {
|
|
2547
|
-
const result = fn();
|
|
2548
|
-
if (DEV && result !== null && typeof result?.then === "function") {
|
|
2549
|
-
devWarn(
|
|
2550
|
-
"context.withContext() received an async callback. Scoping is synchronous only \u2014 the previous value is restored as soon as the callback returns its promise, so anything after an `await` runs outside the scope."
|
|
2551
|
-
);
|
|
2552
|
-
}
|
|
2553
|
-
return result;
|
|
2554
|
-
} finally {
|
|
2555
|
-
setValue(previous2);
|
|
2556
|
-
}
|
|
2557
|
-
}
|
|
2558
|
-
};
|
|
2559
|
-
return ctx;
|
|
2560
|
-
}
|
|
2561
|
-
|
|
2562
2684
|
// src/data/routeLoader.ts
|
|
2563
|
-
var
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2685
|
+
var _clientScope = globalSingleton(/* @__PURE__ */ Symbol.for("sibujs.routeLoader.v2"), () => ({ stack: [] }));
|
|
2686
|
+
var _disposed = globalSingleton(/* @__PURE__ */ Symbol.for("sibujs.routeLoader.disposed.v1"), () => /* @__PURE__ */ new WeakSet());
|
|
2687
|
+
function currentScope() {
|
|
2688
|
+
const cache = getRequestScopedCache("routeLoader");
|
|
2689
|
+
if (!cache) return _clientScope;
|
|
2690
|
+
let scope = cache.get("scope");
|
|
2691
|
+
if (!scope) {
|
|
2692
|
+
scope = { stack: [] };
|
|
2693
|
+
cache.set("scope", scope);
|
|
2694
|
+
}
|
|
2695
|
+
return scope;
|
|
2696
|
+
}
|
|
2697
|
+
function executeLoader(loader, context, options) {
|
|
2698
|
+
const res = resource(({ signal: signal2 }) => loader(context, { signal: signal2 }), options);
|
|
2699
|
+
const disposeResource = res.dispose;
|
|
2700
|
+
res.dispose = () => {
|
|
2701
|
+
_disposed.add(res);
|
|
2702
|
+
disposeResource();
|
|
2703
|
+
};
|
|
2567
2704
|
return res;
|
|
2568
2705
|
}
|
|
2706
|
+
function renderWithLoader(loader, render) {
|
|
2707
|
+
if (_disposed.has(loader)) {
|
|
2708
|
+
throw new Error("renderWithLoader: the loader resource has been disposed");
|
|
2709
|
+
}
|
|
2710
|
+
const scope = currentScope();
|
|
2711
|
+
const entry = loader;
|
|
2712
|
+
scope.stack.push(entry);
|
|
2713
|
+
try {
|
|
2714
|
+
return render();
|
|
2715
|
+
} finally {
|
|
2716
|
+
const index = scope.stack.lastIndexOf(entry);
|
|
2717
|
+
if (index !== -1) scope.stack.splice(index, 1);
|
|
2718
|
+
}
|
|
2719
|
+
}
|
|
2720
|
+
function withLoader(loader, context, render, options) {
|
|
2721
|
+
const res = executeLoader(loader, context, options);
|
|
2722
|
+
try {
|
|
2723
|
+
return { view: renderWithLoader(res, render), resource: res };
|
|
2724
|
+
} catch (err) {
|
|
2725
|
+
res.dispose();
|
|
2726
|
+
throw err;
|
|
2727
|
+
}
|
|
2728
|
+
}
|
|
2569
2729
|
function loaderData() {
|
|
2570
|
-
const
|
|
2571
|
-
|
|
2730
|
+
const scope = currentScope();
|
|
2731
|
+
const resource2 = scope.stack[scope.stack.length - 1];
|
|
2732
|
+
if (!resource2 || _disposed.has(resource2)) {
|
|
2572
2733
|
throw new Error("loaderData must be used inside a route with a loader");
|
|
2573
2734
|
}
|
|
2574
2735
|
return {
|
|
@@ -2577,7 +2738,7 @@ function loaderData() {
|
|
|
2577
2738
|
error: resource2.error
|
|
2578
2739
|
};
|
|
2579
2740
|
}
|
|
2580
|
-
async function preloadRoute(route,
|
|
2741
|
+
async function preloadRoute(route, context, callerSignal) {
|
|
2581
2742
|
if (!route.loader) return void 0;
|
|
2582
2743
|
const controller = new AbortController();
|
|
2583
2744
|
let onAbort = null;
|
|
@@ -2590,7 +2751,7 @@ async function preloadRoute(route, context2, callerSignal) {
|
|
|
2590
2751
|
}
|
|
2591
2752
|
}
|
|
2592
2753
|
try {
|
|
2593
|
-
return await route.loader(
|
|
2754
|
+
return await route.loader(context, { signal: controller.signal });
|
|
2594
2755
|
} finally {
|
|
2595
2756
|
if (onAbort) callerSignal?.removeEventListener("abort", onAbort);
|
|
2596
2757
|
}
|
|
@@ -2618,34 +2779,73 @@ function socket(url, options) {
|
|
|
2618
2779
|
let heartbeatTimer = null;
|
|
2619
2780
|
let disposed = false;
|
|
2620
2781
|
let manuallyClosed = false;
|
|
2782
|
+
let lifecycle = 0;
|
|
2621
2783
|
function getUrl() {
|
|
2622
2784
|
return typeof url === "function" ? url() : url;
|
|
2623
2785
|
}
|
|
2624
2786
|
function connect() {
|
|
2625
2787
|
if (disposed) return;
|
|
2788
|
+
const generation = lifecycle;
|
|
2789
|
+
const invalidated = () => disposed || generation !== lifecycle;
|
|
2626
2790
|
if (typeof WebSocket === "undefined") {
|
|
2627
2791
|
setStatus("closed");
|
|
2628
2792
|
return;
|
|
2629
2793
|
}
|
|
2630
|
-
|
|
2794
|
+
let rawUrl;
|
|
2795
|
+
try {
|
|
2796
|
+
rawUrl = getUrl();
|
|
2797
|
+
} catch (error) {
|
|
2798
|
+
setStatus("closed");
|
|
2799
|
+
reportError(error, { phase: "async", name: "socket" });
|
|
2800
|
+
return;
|
|
2801
|
+
}
|
|
2802
|
+
if (invalidated()) {
|
|
2803
|
+
setStatus("closed");
|
|
2804
|
+
return;
|
|
2805
|
+
}
|
|
2806
|
+
const safeUrl = validateWsUrl(rawUrl);
|
|
2631
2807
|
if (safeUrl === null) {
|
|
2632
2808
|
setStatus("closed");
|
|
2633
2809
|
return;
|
|
2634
2810
|
}
|
|
2635
2811
|
setStatus("connecting");
|
|
2636
|
-
|
|
2637
|
-
|
|
2812
|
+
if (invalidated()) {
|
|
2813
|
+
setStatus("closed");
|
|
2814
|
+
return;
|
|
2815
|
+
}
|
|
2816
|
+
let instance;
|
|
2817
|
+
try {
|
|
2818
|
+
instance = new WebSocket(safeUrl, protocols);
|
|
2819
|
+
} catch (error) {
|
|
2820
|
+
setStatus("closed");
|
|
2821
|
+
reportError(error, { phase: "async", name: "socket" });
|
|
2822
|
+
return;
|
|
2823
|
+
}
|
|
2824
|
+
if (invalidated()) {
|
|
2825
|
+
instance.close();
|
|
2826
|
+
setStatus("closed");
|
|
2827
|
+
return;
|
|
2828
|
+
}
|
|
2829
|
+
ws = instance;
|
|
2830
|
+
instance.onopen = () => {
|
|
2831
|
+
if (ws !== instance) return;
|
|
2832
|
+
const openGeneration = lifecycle;
|
|
2638
2833
|
setStatus("open");
|
|
2834
|
+
if (disposed || openGeneration !== lifecycle || ws !== instance) return;
|
|
2639
2835
|
reconnectCount = 0;
|
|
2640
2836
|
startHeartbeat();
|
|
2641
2837
|
};
|
|
2642
|
-
|
|
2838
|
+
instance.onmessage = (event) => {
|
|
2839
|
+
if (ws !== instance) return;
|
|
2643
2840
|
setData(event.data);
|
|
2644
2841
|
};
|
|
2645
|
-
|
|
2842
|
+
instance.onclose = () => {
|
|
2843
|
+
if (ws !== instance) return;
|
|
2844
|
+
ws = null;
|
|
2845
|
+
const closeGeneration = lifecycle;
|
|
2646
2846
|
setStatus("closed");
|
|
2647
2847
|
stopHeartbeat();
|
|
2648
|
-
const wasManual = manuallyClosed;
|
|
2848
|
+
const wasManual = manuallyClosed || closeGeneration !== lifecycle;
|
|
2649
2849
|
manuallyClosed = false;
|
|
2650
2850
|
if (autoReconnect && !disposed && !wasManual && reconnectCount < maxReconnects) {
|
|
2651
2851
|
const cap = 3e4;
|
|
@@ -2659,7 +2859,7 @@ function socket(url, options) {
|
|
|
2659
2859
|
}, jittered);
|
|
2660
2860
|
}
|
|
2661
2861
|
};
|
|
2662
|
-
|
|
2862
|
+
instance.onerror = () => {
|
|
2663
2863
|
};
|
|
2664
2864
|
}
|
|
2665
2865
|
function startHeartbeat() {
|
|
@@ -2683,13 +2883,23 @@ function socket(url, options) {
|
|
|
2683
2883
|
}
|
|
2684
2884
|
}
|
|
2685
2885
|
function close() {
|
|
2886
|
+
lifecycle++;
|
|
2686
2887
|
manuallyClosed = true;
|
|
2687
2888
|
if (reconnectTimer !== null) {
|
|
2688
2889
|
clearTimeout(reconnectTimer);
|
|
2689
2890
|
reconnectTimer = null;
|
|
2690
2891
|
}
|
|
2691
2892
|
stopHeartbeat();
|
|
2692
|
-
if (ws) {
|
|
2893
|
+
if (!ws) {
|
|
2894
|
+
setStatus("closed");
|
|
2895
|
+
return;
|
|
2896
|
+
}
|
|
2897
|
+
if (ws.readyState === WebSocket.CLOSED) {
|
|
2898
|
+
ws = null;
|
|
2899
|
+
setStatus("closed");
|
|
2900
|
+
return;
|
|
2901
|
+
}
|
|
2902
|
+
if (ws.readyState !== WebSocket.CLOSING) {
|
|
2693
2903
|
setStatus("closing");
|
|
2694
2904
|
ws.close();
|
|
2695
2905
|
}
|
|
@@ -2856,17 +3066,17 @@ function blockedCssReason(value) {
|
|
|
2856
3066
|
}
|
|
2857
3067
|
return -1;
|
|
2858
3068
|
}
|
|
2859
|
-
function sanitizeCSSValue(value,
|
|
3069
|
+
function sanitizeCSSValue(value, context) {
|
|
2860
3070
|
const reason = blockedCssReason(value);
|
|
2861
3071
|
if (reason === -1) return value;
|
|
2862
|
-
warnDroppedDeclaration(value, reason,
|
|
3072
|
+
warnDroppedDeclaration(value, reason, context);
|
|
2863
3073
|
return "";
|
|
2864
3074
|
}
|
|
2865
|
-
function sanitizeStyleAttribute(cssText,
|
|
3075
|
+
function sanitizeStyleAttribute(cssText, context) {
|
|
2866
3076
|
const input2 = String(cssText);
|
|
2867
3077
|
if (input2.trim() === "") return "";
|
|
2868
3078
|
if (typeof document === "undefined") {
|
|
2869
|
-
return sanitizeCSSValue(input2,
|
|
3079
|
+
return sanitizeCSSValue(input2, context) === "" ? "" : input2;
|
|
2870
3080
|
}
|
|
2871
3081
|
const probe = document.createElement("div");
|
|
2872
3082
|
try {
|
|
@@ -2881,7 +3091,7 @@ function sanitizeStyleAttribute(cssText, context2) {
|
|
|
2881
3091
|
let reason = blockedCssReason(value);
|
|
2882
3092
|
if (reason === -1) reason = blockedCssReason(`${property}:${value}`);
|
|
2883
3093
|
if (reason !== -1) {
|
|
2884
|
-
warnDroppedDeclaration(value, reason, { property, element:
|
|
3094
|
+
warnDroppedDeclaration(value, reason, { property, element: context?.element });
|
|
2885
3095
|
continue;
|
|
2886
3096
|
}
|
|
2887
3097
|
const priority = probe.style.getPropertyPriority(property);
|
|
@@ -2931,11 +3141,11 @@ function isPolicyAttribute(name) {
|
|
|
2931
3141
|
const lower = name.toLowerCase();
|
|
2932
3142
|
return lower === "style" || URL_ATTRIBUTES.has(lower);
|
|
2933
3143
|
}
|
|
2934
|
-
function sanitizeAttributeString(attr, value,
|
|
3144
|
+
function sanitizeAttributeString(attr, value, context) {
|
|
2935
3145
|
const lower = attr.toLowerCase();
|
|
2936
3146
|
if (lower === "srcset") return sanitizeSrcset(value);
|
|
2937
3147
|
if (URL_ATTRIBUTES.has(lower)) return sanitizeUrl(value);
|
|
2938
|
-
if (lower === "style") return sanitizeStyleAttribute(value,
|
|
3148
|
+
if (lower === "style") return sanitizeStyleAttribute(value, context);
|
|
2939
3149
|
return value;
|
|
2940
3150
|
}
|
|
2941
3151
|
|
|
@@ -2957,6 +3167,7 @@ function stream(url, options) {
|
|
|
2957
3167
|
let disposed = false;
|
|
2958
3168
|
let reconnectTimer = null;
|
|
2959
3169
|
let attempts = 0;
|
|
3170
|
+
let closeGeneration = 0;
|
|
2960
3171
|
function connect() {
|
|
2961
3172
|
if (disposed) return;
|
|
2962
3173
|
if (typeof EventSource === "undefined") {
|
|
@@ -2968,44 +3179,64 @@ function stream(url, options) {
|
|
|
2968
3179
|
setStatus("closed");
|
|
2969
3180
|
return;
|
|
2970
3181
|
}
|
|
3182
|
+
const generation = closeGeneration;
|
|
2971
3183
|
setStatus("connecting");
|
|
2972
|
-
|
|
3184
|
+
if (disposed || generation !== closeGeneration) return;
|
|
3185
|
+
const instance = new EventSource(safeUrl, {
|
|
2973
3186
|
withCredentials: options?.withCredentials ?? false
|
|
2974
3187
|
});
|
|
2975
|
-
|
|
3188
|
+
if (disposed || generation !== closeGeneration) {
|
|
3189
|
+
instance.close();
|
|
3190
|
+
return;
|
|
3191
|
+
}
|
|
3192
|
+
source2 = instance;
|
|
3193
|
+
const live = () => !disposed && source2 === instance;
|
|
3194
|
+
instance.onopen = () => {
|
|
3195
|
+
if (!live()) return;
|
|
2976
3196
|
setStatus("open");
|
|
2977
3197
|
attempts = 0;
|
|
2978
3198
|
};
|
|
2979
|
-
|
|
3199
|
+
instance.onmessage = (evt) => {
|
|
3200
|
+
if (!live()) return;
|
|
2980
3201
|
setData(evt.data);
|
|
2981
3202
|
setEvent(evt.type);
|
|
2982
3203
|
};
|
|
2983
|
-
|
|
2984
|
-
if (
|
|
2985
|
-
|
|
2986
|
-
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
3204
|
+
instance.onerror = () => {
|
|
3205
|
+
if (!live() || instance.readyState !== EventSource.CLOSED) return;
|
|
3206
|
+
detach(instance);
|
|
3207
|
+
source2 = null;
|
|
3208
|
+
const generation2 = closeGeneration;
|
|
3209
|
+
setStatus("closed");
|
|
3210
|
+
if (disposed || generation2 !== closeGeneration) return;
|
|
3211
|
+
if (autoReconnect && attempts < maxReconnects) {
|
|
3212
|
+
const delay = Math.min(maxMs, baseMs * 2 ** attempts);
|
|
3213
|
+
const jittered = delay * (0.5 + Math.random() * 0.5);
|
|
3214
|
+
attempts++;
|
|
3215
|
+
reconnectTimer = setTimeout(() => {
|
|
3216
|
+
reconnectTimer = null;
|
|
3217
|
+
connect();
|
|
3218
|
+
}, jittered);
|
|
2996
3219
|
}
|
|
2997
3220
|
};
|
|
2998
3221
|
}
|
|
3222
|
+
function detach(instance) {
|
|
3223
|
+
instance.onopen = null;
|
|
3224
|
+
instance.onmessage = null;
|
|
3225
|
+
instance.onerror = null;
|
|
3226
|
+
}
|
|
2999
3227
|
function close() {
|
|
3228
|
+
closeGeneration++;
|
|
3000
3229
|
if (reconnectTimer !== null) {
|
|
3001
3230
|
clearTimeout(reconnectTimer);
|
|
3002
3231
|
reconnectTimer = null;
|
|
3003
3232
|
}
|
|
3004
|
-
|
|
3005
|
-
|
|
3006
|
-
setStatus("closed");
|
|
3233
|
+
const instance = source2;
|
|
3234
|
+
if (instance) {
|
|
3007
3235
|
source2 = null;
|
|
3236
|
+
detach(instance);
|
|
3237
|
+
instance.close();
|
|
3008
3238
|
}
|
|
3239
|
+
setStatus("closed");
|
|
3009
3240
|
}
|
|
3010
3241
|
function dispose2() {
|
|
3011
3242
|
disposed = true;
|
|
@@ -3306,13 +3537,15 @@ function clipboard() {
|
|
|
3306
3537
|
const [copied, setCopied] = signal(false);
|
|
3307
3538
|
let copiedTimer = null;
|
|
3308
3539
|
let disposed = false;
|
|
3540
|
+
let generation = 0;
|
|
3309
3541
|
async function copy(value) {
|
|
3310
3542
|
if (disposed) return;
|
|
3311
3543
|
if (typeof navigator === "undefined" || !navigator.clipboard) {
|
|
3312
3544
|
return;
|
|
3313
3545
|
}
|
|
3546
|
+
const mine = ++generation;
|
|
3314
3547
|
await navigator.clipboard.writeText(value);
|
|
3315
|
-
if (disposed) return;
|
|
3548
|
+
if (disposed || mine !== generation) return;
|
|
3316
3549
|
setText(value);
|
|
3317
3550
|
setCopied(true);
|
|
3318
3551
|
if (copiedTimer !== null) clearTimeout(copiedTimer);
|
|
@@ -3324,6 +3557,7 @@ function clipboard() {
|
|
|
3324
3557
|
}
|
|
3325
3558
|
function dispose2() {
|
|
3326
3559
|
disposed = true;
|
|
3560
|
+
generation++;
|
|
3327
3561
|
if (copiedTimer !== null) {
|
|
3328
3562
|
clearTimeout(copiedTimer);
|
|
3329
3563
|
copiedTimer = null;
|
|
@@ -3358,15 +3592,26 @@ function draggable(element, data2) {
|
|
|
3358
3592
|
let currentEl = null;
|
|
3359
3593
|
let onDragStart = null;
|
|
3360
3594
|
let onDragEnd = null;
|
|
3595
|
+
let prevDraggableAttr = null;
|
|
3596
|
+
function detach() {
|
|
3597
|
+
if (!currentEl) return;
|
|
3598
|
+
if (onDragStart) currentEl.removeEventListener("dragstart", onDragStart);
|
|
3599
|
+
if (onDragEnd) currentEl.removeEventListener("dragend", onDragEnd);
|
|
3600
|
+
if (prevDraggableAttr === null) currentEl.removeAttribute("draggable");
|
|
3601
|
+
else currentEl.setAttribute("draggable", prevDraggableAttr);
|
|
3602
|
+
currentEl = null;
|
|
3603
|
+
onDragStart = null;
|
|
3604
|
+
onDragEnd = null;
|
|
3605
|
+
setIsDragging(false);
|
|
3606
|
+
}
|
|
3361
3607
|
const getter = resolveTarget2(element);
|
|
3362
3608
|
const cleanup3 = effect(() => {
|
|
3363
|
-
if (currentEl && onDragStart && onDragEnd) {
|
|
3364
|
-
currentEl.removeEventListener("dragstart", onDragStart);
|
|
3365
|
-
currentEl.removeEventListener("dragend", onDragEnd);
|
|
3366
|
-
}
|
|
3367
3609
|
const el = getter();
|
|
3368
|
-
currentEl
|
|
3610
|
+
if (el === currentEl) return;
|
|
3611
|
+
detach();
|
|
3369
3612
|
if (!el) return;
|
|
3613
|
+
currentEl = el;
|
|
3614
|
+
prevDraggableAttr = el.getAttribute("draggable");
|
|
3370
3615
|
el.draggable = true;
|
|
3371
3616
|
onDragStart = (e) => {
|
|
3372
3617
|
setIsDragging(true);
|
|
@@ -3380,16 +3625,16 @@ function draggable(element, data2) {
|
|
|
3380
3625
|
el.addEventListener("dragstart", onDragStart);
|
|
3381
3626
|
el.addEventListener("dragend", onDragEnd);
|
|
3382
3627
|
});
|
|
3628
|
+
let disposed = false;
|
|
3383
3629
|
function dispose2() {
|
|
3630
|
+
if (disposed) return;
|
|
3631
|
+
disposed = true;
|
|
3384
3632
|
cleanup3();
|
|
3385
|
-
|
|
3386
|
-
currentEl.removeEventListener("dragstart", onDragStart);
|
|
3387
|
-
currentEl.removeEventListener("dragend", onDragEnd);
|
|
3388
|
-
currentEl = null;
|
|
3389
|
-
}
|
|
3633
|
+
detach();
|
|
3390
3634
|
}
|
|
3391
3635
|
return { isDragging, dispose: dispose2 };
|
|
3392
3636
|
}
|
|
3637
|
+
var DROP_ZONE_EXIT_GRACE_MS = 600;
|
|
3393
3638
|
function dropZone(element, options) {
|
|
3394
3639
|
const [isOver, setIsOver] = signal(false);
|
|
3395
3640
|
if (typeof window === "undefined") {
|
|
@@ -3401,30 +3646,66 @@ function dropZone(element, options) {
|
|
|
3401
3646
|
let onDragEnter = null;
|
|
3402
3647
|
let onDragLeave = null;
|
|
3403
3648
|
let onDrop = null;
|
|
3404
|
-
|
|
3405
|
-
|
|
3649
|
+
let depth = 0;
|
|
3650
|
+
let exitTimer = null;
|
|
3651
|
+
function cancelPendingExit() {
|
|
3652
|
+
if (exitTimer !== null) {
|
|
3653
|
+
clearTimeout(exitTimer);
|
|
3654
|
+
exitTimer = null;
|
|
3655
|
+
}
|
|
3656
|
+
}
|
|
3657
|
+
function resetOver() {
|
|
3658
|
+
cancelPendingExit();
|
|
3659
|
+
depth = 0;
|
|
3660
|
+
setIsOver(false);
|
|
3661
|
+
}
|
|
3662
|
+
function detach() {
|
|
3406
3663
|
if (currentEl && onDragOver && onDragEnter && onDragLeave && onDrop) {
|
|
3407
3664
|
currentEl.removeEventListener("dragover", onDragOver);
|
|
3408
3665
|
currentEl.removeEventListener("dragenter", onDragEnter);
|
|
3409
3666
|
currentEl.removeEventListener("dragleave", onDragLeave);
|
|
3410
3667
|
currentEl.removeEventListener("drop", onDrop);
|
|
3411
3668
|
}
|
|
3669
|
+
currentEl = null;
|
|
3670
|
+
resetOver();
|
|
3671
|
+
}
|
|
3672
|
+
const getter = resolveTarget2(element);
|
|
3673
|
+
const cleanup3 = effect(() => {
|
|
3412
3674
|
const el = getter();
|
|
3413
|
-
currentEl
|
|
3675
|
+
if (el === currentEl) return;
|
|
3676
|
+
detach();
|
|
3414
3677
|
if (!el) return;
|
|
3678
|
+
currentEl = el;
|
|
3415
3679
|
onDragOver = (e) => {
|
|
3416
3680
|
e.preventDefault();
|
|
3681
|
+
cancelPendingExit();
|
|
3417
3682
|
};
|
|
3418
3683
|
onDragEnter = (e) => {
|
|
3419
3684
|
e.preventDefault();
|
|
3685
|
+
cancelPendingExit();
|
|
3686
|
+
depth++;
|
|
3420
3687
|
setIsOver(true);
|
|
3421
3688
|
};
|
|
3422
|
-
onDragLeave = () => {
|
|
3423
|
-
|
|
3689
|
+
onDragLeave = (e) => {
|
|
3690
|
+
depth = Math.max(0, depth - 1);
|
|
3691
|
+
if (depth === 0) {
|
|
3692
|
+
resetOver();
|
|
3693
|
+
return;
|
|
3694
|
+
}
|
|
3695
|
+
const to = e.relatedTarget;
|
|
3696
|
+
if (to != null && typeof to.nodeType === "number") {
|
|
3697
|
+
if (!el.contains(to)) resetOver();
|
|
3698
|
+
return;
|
|
3699
|
+
}
|
|
3700
|
+
cancelPendingExit();
|
|
3701
|
+
exitTimer = setTimeout(() => {
|
|
3702
|
+
exitTimer = null;
|
|
3703
|
+
resetOver();
|
|
3704
|
+
}, DROP_ZONE_EXIT_GRACE_MS);
|
|
3424
3705
|
};
|
|
3425
3706
|
onDrop = (e) => {
|
|
3426
3707
|
e.preventDefault();
|
|
3427
|
-
|
|
3708
|
+
resetOver();
|
|
3428
3709
|
let transferData = null;
|
|
3429
3710
|
if (e.dataTransfer) {
|
|
3430
3711
|
const raw = e.dataTransfer.getData("application/json");
|
|
@@ -3445,13 +3726,7 @@ function dropZone(element, options) {
|
|
|
3445
3726
|
});
|
|
3446
3727
|
function dispose2() {
|
|
3447
3728
|
cleanup3();
|
|
3448
|
-
|
|
3449
|
-
currentEl.removeEventListener("dragover", onDragOver);
|
|
3450
|
-
currentEl.removeEventListener("dragenter", onDragEnter);
|
|
3451
|
-
currentEl.removeEventListener("dragleave", onDragLeave);
|
|
3452
|
-
currentEl.removeEventListener("drop", onDrop);
|
|
3453
|
-
currentEl = null;
|
|
3454
|
-
}
|
|
3729
|
+
detach();
|
|
3455
3730
|
}
|
|
3456
3731
|
return { isOver, dispose: dispose2 };
|
|
3457
3732
|
}
|
|
@@ -3620,9 +3895,9 @@ function formatNumber(value, options) {
|
|
|
3620
3895
|
function formatCurrency(value, currency, options) {
|
|
3621
3896
|
const { locale, ...formatOptions } = options ?? {};
|
|
3622
3897
|
return new Intl.NumberFormat(locale, {
|
|
3898
|
+
...formatOptions,
|
|
3623
3899
|
style: "currency",
|
|
3624
|
-
currency
|
|
3625
|
-
...formatOptions
|
|
3900
|
+
currency
|
|
3626
3901
|
}).format(value);
|
|
3627
3902
|
}
|
|
3628
3903
|
|
|
@@ -3708,18 +3983,36 @@ function swipe(target, options = {}) {
|
|
|
3708
3983
|
}
|
|
3709
3984
|
let startX = 0;
|
|
3710
3985
|
let startY = 0;
|
|
3711
|
-
let
|
|
3986
|
+
let trackedId = null;
|
|
3987
|
+
const idOf = (t) => t.identifier ?? 0;
|
|
3988
|
+
const findTracked = (list) => {
|
|
3989
|
+
if (!list) return null;
|
|
3990
|
+
for (let i2 = 0; i2 < list.length; i2++) {
|
|
3991
|
+
const t = list[i2];
|
|
3992
|
+
if (idOf(t) === trackedId) return t;
|
|
3993
|
+
}
|
|
3994
|
+
return null;
|
|
3995
|
+
};
|
|
3712
3996
|
const onStart = (e) => {
|
|
3713
|
-
|
|
3714
|
-
|
|
3715
|
-
|
|
3716
|
-
|
|
3997
|
+
const onTarget = e.targetTouches ?? e.touches;
|
|
3998
|
+
if (onTarget.length > 1) {
|
|
3999
|
+
trackedId = null;
|
|
4000
|
+
return;
|
|
4001
|
+
}
|
|
4002
|
+
const touch = e.changedTouches?.[0] ?? e.touches[0];
|
|
4003
|
+
if (!touch) return;
|
|
4004
|
+
trackedId = idOf(touch);
|
|
4005
|
+
startX = touch.clientX;
|
|
4006
|
+
startY = touch.clientY;
|
|
4007
|
+
};
|
|
4008
|
+
const onCancel = (e) => {
|
|
4009
|
+
if (trackedId !== null && findTracked(e.changedTouches)) trackedId = null;
|
|
3717
4010
|
};
|
|
3718
4011
|
const onEnd = (e) => {
|
|
3719
|
-
if (
|
|
3720
|
-
|
|
3721
|
-
const touch = e.changedTouches[0];
|
|
4012
|
+
if (trackedId === null) return;
|
|
4013
|
+
const touch = findTracked(e.changedTouches);
|
|
3722
4014
|
if (!touch) return;
|
|
4015
|
+
trackedId = null;
|
|
3723
4016
|
const dx = touch.clientX - startX;
|
|
3724
4017
|
const dy = touch.clientY - startY;
|
|
3725
4018
|
const absX = Math.abs(dx);
|
|
@@ -3736,9 +4029,12 @@ function swipe(target, options = {}) {
|
|
|
3736
4029
|
};
|
|
3737
4030
|
target.addEventListener("touchstart", onStart, { passive: true });
|
|
3738
4031
|
target.addEventListener("touchend", onEnd, { passive: true });
|
|
4032
|
+
target.addEventListener("touchcancel", onCancel, { passive: true });
|
|
3739
4033
|
function dispose2() {
|
|
3740
4034
|
target.removeEventListener("touchstart", onStart);
|
|
3741
4035
|
target.removeEventListener("touchend", onEnd);
|
|
4036
|
+
target.removeEventListener("touchcancel", onCancel);
|
|
4037
|
+
trackedId = null;
|
|
3742
4038
|
}
|
|
3743
4039
|
return { direction, dispose: dispose2 };
|
|
3744
4040
|
}
|
|
@@ -3765,6 +4061,18 @@ function windowSize() {
|
|
|
3765
4061
|
}
|
|
3766
4062
|
|
|
3767
4063
|
// src/browser/urlState.ts
|
|
4064
|
+
var _url = globalSingleton(/* @__PURE__ */ Symbol.for("sibujs.urlState.v1"), () => ({
|
|
4065
|
+
instances: /* @__PURE__ */ new Set()
|
|
4066
|
+
}));
|
|
4067
|
+
function notifyUrlWrite() {
|
|
4068
|
+
for (const sync of Array.from(_url.instances)) sync();
|
|
4069
|
+
}
|
|
4070
|
+
var SCROLL_ENTRY_KEY = "__sibuScrollKey";
|
|
4071
|
+
function withoutEntryIdentity(state2) {
|
|
4072
|
+
if (state2 === null || typeof state2 !== "object" || !Object.hasOwn(state2, SCROLL_ENTRY_KEY)) return state2;
|
|
4073
|
+
const { [SCROLL_ENTRY_KEY]: _identity, ...rest } = state2;
|
|
4074
|
+
return rest;
|
|
4075
|
+
}
|
|
3768
4076
|
function urlState() {
|
|
3769
4077
|
if (typeof window === "undefined") {
|
|
3770
4078
|
const [params2] = signal(new URLSearchParams());
|
|
@@ -3798,26 +4106,36 @@ function urlState() {
|
|
|
3798
4106
|
}
|
|
3799
4107
|
window.addEventListener("popstate", syncFromLocation);
|
|
3800
4108
|
window.addEventListener("hashchange", syncFromLocation);
|
|
4109
|
+
_url.instances.add(syncFromLocation);
|
|
4110
|
+
function writeHistory(newUrl, opts) {
|
|
4111
|
+
const state2 = "state" in opts ? opts.state : window.history.state;
|
|
4112
|
+
if (opts.replace) window.history.replaceState(state2, "", newUrl);
|
|
4113
|
+
else window.history.pushState("state" in opts ? state2 : withoutEntryIdentity(state2), "", newUrl);
|
|
4114
|
+
}
|
|
3801
4115
|
function setParams(next, opts = {}) {
|
|
3802
4116
|
const p2 = next instanceof URLSearchParams ? next : new URLSearchParams(next);
|
|
3803
4117
|
const query2 = p2.toString();
|
|
3804
4118
|
const newUrl = `${window.location.pathname}${query2 ? `?${query2}` : ""}${window.location.hash}`;
|
|
3805
|
-
|
|
3806
|
-
else window.history.pushState(null, "", newUrl);
|
|
4119
|
+
writeHistory(newUrl, opts);
|
|
3807
4120
|
lastSearch = window.location.search;
|
|
3808
4121
|
setParamsSignal(new URLSearchParams(p2));
|
|
4122
|
+
notifyUrlWrite();
|
|
3809
4123
|
}
|
|
3810
4124
|
function setHash(next, opts = {}) {
|
|
3811
4125
|
const normalized = next && next !== "#" ? next.startsWith("#") ? next : `#${next}` : "";
|
|
3812
4126
|
const newUrl = `${window.location.pathname}${window.location.search}${normalized}`;
|
|
3813
|
-
|
|
3814
|
-
else window.history.pushState(null, "", newUrl);
|
|
4127
|
+
writeHistory(newUrl, opts);
|
|
3815
4128
|
lastHash = normalized;
|
|
3816
4129
|
setHashSignal(normalized);
|
|
4130
|
+
notifyUrlWrite();
|
|
3817
4131
|
}
|
|
4132
|
+
let disposed = false;
|
|
3818
4133
|
function dispose2() {
|
|
4134
|
+
if (disposed) return;
|
|
4135
|
+
disposed = true;
|
|
3819
4136
|
window.removeEventListener("popstate", syncFromLocation);
|
|
3820
4137
|
window.removeEventListener("hashchange", syncFromLocation);
|
|
4138
|
+
_url.instances.delete(syncFromLocation);
|
|
3821
4139
|
}
|
|
3822
4140
|
return { params, hash, setParams, setHash, dispose: dispose2 };
|
|
3823
4141
|
}
|
|
@@ -3834,10 +4152,14 @@ function broadcast(channelName) {
|
|
|
3834
4152
|
const channel = new BroadcastChannel(channelName);
|
|
3835
4153
|
const handler = (ev) => setLast(ev.data);
|
|
3836
4154
|
channel.addEventListener("message", handler);
|
|
4155
|
+
let disposed = false;
|
|
3837
4156
|
function post(message) {
|
|
4157
|
+
if (disposed) return;
|
|
3838
4158
|
channel.postMessage(message);
|
|
3839
4159
|
}
|
|
3840
4160
|
function dispose2() {
|
|
4161
|
+
if (disposed) return;
|
|
4162
|
+
disposed = true;
|
|
3841
4163
|
channel.removeEventListener("message", handler);
|
|
3842
4164
|
channel.close();
|
|
3843
4165
|
}
|
|
@@ -4036,31 +4358,42 @@ function animationFrame(options = {}) {
|
|
|
4036
4358
|
let prev = -1;
|
|
4037
4359
|
let start = -1;
|
|
4038
4360
|
let disposed = false;
|
|
4361
|
+
let active = false;
|
|
4362
|
+
let generation = 0;
|
|
4039
4363
|
const minFrameMs = options.fpsLimit ? 1e3 / options.fpsLimit : 0;
|
|
4040
4364
|
const step = (now) => {
|
|
4365
|
+
id = null;
|
|
4366
|
+
if (!active) return;
|
|
4367
|
+
const frameGeneration = generation;
|
|
4041
4368
|
if (start < 0) start = now;
|
|
4042
4369
|
const firstTick = prev < 0;
|
|
4043
4370
|
const dt2 = firstTick ? 0 : now - prev;
|
|
4044
4371
|
if (firstTick || dt2 >= minFrameMs) {
|
|
4045
|
-
setDelta(dt2);
|
|
4046
|
-
setElapsed(now - start);
|
|
4047
4372
|
prev = now;
|
|
4373
|
+
const elapsedValue = now - start;
|
|
4374
|
+
setDelta(dt2);
|
|
4375
|
+
if (!active || generation !== frameGeneration) return;
|
|
4376
|
+
setElapsed(elapsedValue);
|
|
4377
|
+
if (!active || generation !== frameGeneration) return;
|
|
4048
4378
|
}
|
|
4049
|
-
id = requestAnimationFrame(step);
|
|
4379
|
+
if (id === null) id = requestAnimationFrame(step);
|
|
4050
4380
|
};
|
|
4051
4381
|
function resume() {
|
|
4052
|
-
if (disposed ||
|
|
4053
|
-
|
|
4382
|
+
if (disposed || active) return;
|
|
4383
|
+
active = true;
|
|
4054
4384
|
id = requestAnimationFrame(step);
|
|
4385
|
+
setRunning(true);
|
|
4055
4386
|
}
|
|
4056
4387
|
function pause() {
|
|
4388
|
+
generation++;
|
|
4389
|
+
active = false;
|
|
4057
4390
|
if (id !== null) {
|
|
4058
4391
|
cancelAnimationFrame(id);
|
|
4059
4392
|
id = null;
|
|
4060
4393
|
}
|
|
4061
|
-
setRunning(false);
|
|
4062
4394
|
prev = -1;
|
|
4063
4395
|
start = -1;
|
|
4396
|
+
setRunning(false);
|
|
4064
4397
|
}
|
|
4065
4398
|
function dispose2() {
|
|
4066
4399
|
disposed = true;
|
|
@@ -4190,6 +4523,35 @@ function keyboard(options = {}) {
|
|
|
4190
4523
|
}
|
|
4191
4524
|
|
|
4192
4525
|
// src/browser/speech.ts
|
|
4526
|
+
var _speech = globalSingleton(/* @__PURE__ */ Symbol.for("sibujs.speech.v1"), () => ({
|
|
4527
|
+
queue: [],
|
|
4528
|
+
active: null,
|
|
4529
|
+
owners: /* @__PURE__ */ new Set()
|
|
4530
|
+
}));
|
|
4531
|
+
function syncOwners() {
|
|
4532
|
+
for (const owner of Array.from(_speech.owners)) owner.sync();
|
|
4533
|
+
}
|
|
4534
|
+
function pump(synth) {
|
|
4535
|
+
if (_speech.active) return;
|
|
4536
|
+
const index = _speech.queue.findIndex((entry2) => !entry2.owner.paused);
|
|
4537
|
+
if (index === -1) return;
|
|
4538
|
+
const [entry] = _speech.queue.splice(index, 1);
|
|
4539
|
+
_speech.active = entry;
|
|
4540
|
+
const finish = () => {
|
|
4541
|
+
if (_speech.active !== entry) return;
|
|
4542
|
+
_speech.active = null;
|
|
4543
|
+
pump(synth);
|
|
4544
|
+
syncOwners();
|
|
4545
|
+
};
|
|
4546
|
+
entry.utterance.addEventListener("end", finish, { once: true });
|
|
4547
|
+
entry.utterance.addEventListener("error", finish, { once: true });
|
|
4548
|
+
synth.speak(entry.utterance);
|
|
4549
|
+
}
|
|
4550
|
+
function __resetSpeechCoordinator() {
|
|
4551
|
+
_speech.queue.length = 0;
|
|
4552
|
+
_speech.active = null;
|
|
4553
|
+
_speech.owners.clear();
|
|
4554
|
+
}
|
|
4193
4555
|
function speech() {
|
|
4194
4556
|
const [speaking, setSpeaking] = signal(false);
|
|
4195
4557
|
const [paused, setPaused] = signal(false);
|
|
@@ -4210,19 +4572,16 @@ function speech() {
|
|
|
4210
4572
|
};
|
|
4211
4573
|
}
|
|
4212
4574
|
const synth = window.speechSynthesis;
|
|
4213
|
-
let interval = null;
|
|
4214
|
-
function startPolling() {
|
|
4215
|
-
if (interval !== null) return;
|
|
4216
|
-
interval = setInterval(() => {
|
|
4217
|
-
setSpeaking(synth.speaking);
|
|
4218
|
-
setPaused(synth.paused);
|
|
4219
|
-
if (!synth.speaking && !synth.paused) {
|
|
4220
|
-
clearInterval(interval);
|
|
4221
|
-
interval = null;
|
|
4222
|
-
}
|
|
4223
|
-
}, 200);
|
|
4224
|
-
}
|
|
4225
4575
|
let disposed = false;
|
|
4576
|
+
const owner = {
|
|
4577
|
+
paused: false,
|
|
4578
|
+
sync: () => {
|
|
4579
|
+
const mine = _speech.active?.owner === owner || _speech.queue.some((entry) => entry.owner === owner);
|
|
4580
|
+
setSpeaking(mine);
|
|
4581
|
+
setPaused(owner.paused);
|
|
4582
|
+
}
|
|
4583
|
+
};
|
|
4584
|
+
_speech.owners.add(owner);
|
|
4226
4585
|
function speak(text2, options = {}) {
|
|
4227
4586
|
if (disposed) return;
|
|
4228
4587
|
const u2 = new SpeechSynthesisUtterance(text2);
|
|
@@ -4235,52 +4594,48 @@ function speech() {
|
|
|
4235
4594
|
const match = voices.find((v) => v.name === options.voice);
|
|
4236
4595
|
if (match) u2.voice = match;
|
|
4237
4596
|
}
|
|
4238
|
-
|
|
4239
|
-
|
|
4240
|
-
|
|
4241
|
-
|
|
4242
|
-
|
|
4243
|
-
|
|
4244
|
-
|
|
4245
|
-
|
|
4246
|
-
|
|
4247
|
-
|
|
4248
|
-
|
|
4249
|
-
|
|
4250
|
-
|
|
4251
|
-
|
|
4252
|
-
|
|
4253
|
-
);
|
|
4254
|
-
|
|
4255
|
-
|
|
4256
|
-
|
|
4257
|
-
|
|
4258
|
-
|
|
4259
|
-
|
|
4260
|
-
|
|
4261
|
-
|
|
4262
|
-
|
|
4263
|
-
|
|
4264
|
-
|
|
4265
|
-
|
|
4597
|
+
_speech.queue.push({ owner, utterance: u2 });
|
|
4598
|
+
pump(synth);
|
|
4599
|
+
syncOwners();
|
|
4600
|
+
}
|
|
4601
|
+
function pause() {
|
|
4602
|
+
if (disposed || owner.paused) return;
|
|
4603
|
+
owner.paused = true;
|
|
4604
|
+
if (_speech.active?.owner === owner) synth.pause();
|
|
4605
|
+
syncOwners();
|
|
4606
|
+
}
|
|
4607
|
+
function resume() {
|
|
4608
|
+
if (disposed || !owner.paused) return;
|
|
4609
|
+
owner.paused = false;
|
|
4610
|
+
if (_speech.active?.owner === owner) synth.resume();
|
|
4611
|
+
else pump(synth);
|
|
4612
|
+
syncOwners();
|
|
4613
|
+
}
|
|
4614
|
+
function cancel() {
|
|
4615
|
+
if (disposed) return;
|
|
4616
|
+
cancelOwned();
|
|
4617
|
+
syncOwners();
|
|
4618
|
+
}
|
|
4619
|
+
function cancelOwned() {
|
|
4620
|
+
for (let i2 = _speech.queue.length - 1; i2 >= 0; i2--) {
|
|
4621
|
+
if (_speech.queue[i2].owner === owner) _speech.queue.splice(i2, 1);
|
|
4622
|
+
}
|
|
4623
|
+
owner.paused = false;
|
|
4624
|
+
if (_speech.active?.owner === owner) {
|
|
4625
|
+
_speech.active = null;
|
|
4626
|
+
if (synth.paused) synth.resume();
|
|
4627
|
+
synth.cancel();
|
|
4628
|
+
pump(synth);
|
|
4629
|
+
}
|
|
4266
4630
|
}
|
|
4267
4631
|
function dispose2() {
|
|
4632
|
+
if (disposed) return;
|
|
4633
|
+
cancelOwned();
|
|
4268
4634
|
disposed = true;
|
|
4269
|
-
|
|
4270
|
-
|
|
4271
|
-
interval = null;
|
|
4272
|
-
}
|
|
4273
|
-
synth.cancel();
|
|
4635
|
+
syncOwners();
|
|
4636
|
+
_speech.owners.delete(owner);
|
|
4274
4637
|
}
|
|
4275
|
-
return {
|
|
4276
|
-
speaking,
|
|
4277
|
-
paused,
|
|
4278
|
-
speak,
|
|
4279
|
-
pause: () => synth.pause(),
|
|
4280
|
-
resume: () => synth.resume(),
|
|
4281
|
-
cancel: () => synth.cancel(),
|
|
4282
|
-
dispose: dispose2
|
|
4283
|
-
};
|
|
4638
|
+
return { speaking, paused, speak, pause, resume, cancel, dispose: dispose2 };
|
|
4284
4639
|
}
|
|
4285
4640
|
|
|
4286
4641
|
// src/browser/gamepad.ts
|
|
@@ -4291,6 +4646,7 @@ function gamepad() {
|
|
|
4291
4646
|
} };
|
|
4292
4647
|
}
|
|
4293
4648
|
let rafId = null;
|
|
4649
|
+
let disposed = false;
|
|
4294
4650
|
function snapshot(pad) {
|
|
4295
4651
|
return {
|
|
4296
4652
|
index: pad.index,
|
|
@@ -4305,7 +4661,7 @@ function gamepad() {
|
|
|
4305
4661
|
for (let i2 = 0; i2 < a2.length; i2++) {
|
|
4306
4662
|
const pa = a2[i2];
|
|
4307
4663
|
const pb = b2[i2];
|
|
4308
|
-
if (pa.index !== pb.index || pa.connected !== pb.connected) return false;
|
|
4664
|
+
if (pa.index !== pb.index || pa.id !== pb.id || pa.connected !== pb.connected) return false;
|
|
4309
4665
|
if (pa.buttons.length !== pb.buttons.length) return false;
|
|
4310
4666
|
for (let j = 0; j < pa.buttons.length; j++) {
|
|
4311
4667
|
if (pa.buttons[j].pressed !== pb.buttons[j].pressed) return false;
|
|
@@ -4318,15 +4674,19 @@ function gamepad() {
|
|
|
4318
4674
|
}
|
|
4319
4675
|
return true;
|
|
4320
4676
|
}
|
|
4677
|
+
function publish() {
|
|
4678
|
+
const snap = Array.from(navigator.getGamepads()).filter((g2) => g2 !== null).map(snapshot);
|
|
4679
|
+
if (!equal(pads(), snap)) setPads(snap);
|
|
4680
|
+
return snap;
|
|
4681
|
+
}
|
|
4321
4682
|
function poll() {
|
|
4322
|
-
|
|
4323
|
-
|
|
4324
|
-
|
|
4325
|
-
if (!
|
|
4326
|
-
rafId = requestAnimationFrame(poll);
|
|
4683
|
+
rafId = null;
|
|
4684
|
+
if (disposed) return;
|
|
4685
|
+
publish();
|
|
4686
|
+
if (!disposed && rafId === null) rafId = requestAnimationFrame(poll);
|
|
4327
4687
|
}
|
|
4328
4688
|
function startPolling() {
|
|
4329
|
-
if (rafId === null) poll();
|
|
4689
|
+
if (!disposed && rafId === null) poll();
|
|
4330
4690
|
}
|
|
4331
4691
|
function stopPolling() {
|
|
4332
4692
|
if (rafId !== null) {
|
|
@@ -4336,15 +4696,14 @@ function gamepad() {
|
|
|
4336
4696
|
}
|
|
4337
4697
|
const onConnect = () => startPolling();
|
|
4338
4698
|
const onDisconnect = () => {
|
|
4339
|
-
|
|
4340
|
-
const hasAny = Array.from(raw).some((g2) => g2 !== null);
|
|
4341
|
-
if (!hasAny) stopPolling();
|
|
4699
|
+
if (publish().length === 0) stopPolling();
|
|
4342
4700
|
};
|
|
4343
4701
|
window.addEventListener("gamepadconnected", onConnect);
|
|
4344
4702
|
window.addEventListener("gamepaddisconnected", onDisconnect);
|
|
4345
4703
|
const initial = Array.from(navigator.getGamepads()).some((g2) => g2 !== null);
|
|
4346
4704
|
if (initial) startPolling();
|
|
4347
4705
|
function dispose2() {
|
|
4706
|
+
disposed = true;
|
|
4348
4707
|
stopPolling();
|
|
4349
4708
|
window.removeEventListener("gamepadconnected", onConnect);
|
|
4350
4709
|
window.removeEventListener("gamepaddisconnected", onDisconnect);
|
|
@@ -4358,8 +4717,7 @@ function pointerLock() {
|
|
|
4358
4717
|
if (typeof document === "undefined") {
|
|
4359
4718
|
return {
|
|
4360
4719
|
locked,
|
|
4361
|
-
request: () =>
|
|
4362
|
-
},
|
|
4720
|
+
request: () => Promise.resolve(),
|
|
4363
4721
|
exit: () => {
|
|
4364
4722
|
},
|
|
4365
4723
|
dispose: () => {
|
|
@@ -4371,8 +4729,14 @@ function pointerLock() {
|
|
|
4371
4729
|
};
|
|
4372
4730
|
document.addEventListener("pointerlockchange", handler);
|
|
4373
4731
|
function request(element) {
|
|
4374
|
-
if (typeof element.requestPointerLock
|
|
4375
|
-
|
|
4732
|
+
if (typeof element.requestPointerLock !== "function") {
|
|
4733
|
+
return Promise.resolve();
|
|
4734
|
+
}
|
|
4735
|
+
try {
|
|
4736
|
+
const result = element.requestPointerLock();
|
|
4737
|
+
return Promise.resolve(result).then(() => void 0);
|
|
4738
|
+
} catch (err) {
|
|
4739
|
+
return Promise.reject(err);
|
|
4376
4740
|
}
|
|
4377
4741
|
}
|
|
4378
4742
|
function exit() {
|
|
@@ -4475,25 +4839,46 @@ function imageLoader(src) {
|
|
|
4475
4839
|
};
|
|
4476
4840
|
}
|
|
4477
4841
|
let current = null;
|
|
4842
|
+
let currentSettled = false;
|
|
4478
4843
|
let disposed = false;
|
|
4844
|
+
let startToken = 0;
|
|
4845
|
+
function resetState() {
|
|
4846
|
+
batch(() => {
|
|
4847
|
+
setStatus("pending");
|
|
4848
|
+
setImage(null);
|
|
4849
|
+
setWidth(0);
|
|
4850
|
+
setHeight(0);
|
|
4851
|
+
});
|
|
4852
|
+
}
|
|
4853
|
+
function abandonCurrent() {
|
|
4854
|
+
if (!current) return;
|
|
4855
|
+
const prev = current;
|
|
4856
|
+
current = null;
|
|
4857
|
+
prev.onload = null;
|
|
4858
|
+
prev.onerror = null;
|
|
4859
|
+
if (!currentSettled) prev.src = "";
|
|
4860
|
+
}
|
|
4479
4861
|
function start(url) {
|
|
4480
|
-
|
|
4481
|
-
|
|
4482
|
-
|
|
4483
|
-
|
|
4484
|
-
setStatus("pending");
|
|
4485
|
-
setImage(null);
|
|
4862
|
+
const token = ++startToken;
|
|
4863
|
+
abandonCurrent();
|
|
4864
|
+
resetState();
|
|
4865
|
+
if (disposed || token !== startToken) return;
|
|
4486
4866
|
const img2 = new Image();
|
|
4487
4867
|
current = img2;
|
|
4868
|
+
currentSettled = false;
|
|
4488
4869
|
img2.onload = () => {
|
|
4489
4870
|
if (disposed || current !== img2) return;
|
|
4490
|
-
|
|
4491
|
-
|
|
4492
|
-
|
|
4493
|
-
|
|
4494
|
-
|
|
4871
|
+
currentSettled = true;
|
|
4872
|
+
batch(() => {
|
|
4873
|
+
setImage(img2);
|
|
4874
|
+
setWidth(img2.naturalWidth);
|
|
4875
|
+
setHeight(img2.naturalHeight);
|
|
4876
|
+
setStatus("loaded");
|
|
4877
|
+
});
|
|
4878
|
+
};
|
|
4495
4879
|
img2.onerror = () => {
|
|
4496
4880
|
if (disposed || current !== img2) return;
|
|
4881
|
+
currentSettled = true;
|
|
4497
4882
|
setStatus("error");
|
|
4498
4883
|
};
|
|
4499
4884
|
img2.src = url;
|
|
@@ -4508,16 +4893,15 @@ function imageLoader(src) {
|
|
|
4508
4893
|
start(src);
|
|
4509
4894
|
}
|
|
4510
4895
|
function dispose2() {
|
|
4896
|
+
if (disposed) return;
|
|
4511
4897
|
disposed = true;
|
|
4898
|
+
startToken++;
|
|
4512
4899
|
if (srcEffectTeardown) {
|
|
4513
4900
|
srcEffectTeardown();
|
|
4514
4901
|
srcEffectTeardown = null;
|
|
4515
4902
|
}
|
|
4516
|
-
|
|
4517
|
-
|
|
4518
|
-
current.onerror = null;
|
|
4519
|
-
current = null;
|
|
4520
|
-
}
|
|
4903
|
+
abandonCurrent();
|
|
4904
|
+
resetState();
|
|
4521
4905
|
}
|
|
4522
4906
|
return { status, image, width, height, dispose: dispose2 };
|
|
4523
4907
|
}
|
|
@@ -4525,13 +4909,25 @@ function imageLoader(src) {
|
|
|
4525
4909
|
// src/patterns/machine.ts
|
|
4526
4910
|
function machine(config) {
|
|
4527
4911
|
const [state2, setState] = signal(config.initial);
|
|
4528
|
-
const [
|
|
4529
|
-
|
|
4530
|
-
|
|
4531
|
-
|
|
4912
|
+
const [context, setContext] = signal(config.context || {});
|
|
4913
|
+
let currentState = config.initial;
|
|
4914
|
+
let currentContext = context();
|
|
4915
|
+
const queue = [];
|
|
4916
|
+
let processing = false;
|
|
4917
|
+
function drain() {
|
|
4918
|
+
processing = true;
|
|
4919
|
+
try {
|
|
4920
|
+
while (queue.length > 0) {
|
|
4921
|
+
step(queue.shift());
|
|
4922
|
+
}
|
|
4923
|
+
} catch (err) {
|
|
4924
|
+
queue.length = 0;
|
|
4925
|
+
throw err;
|
|
4926
|
+
} finally {
|
|
4927
|
+
processing = false;
|
|
4928
|
+
}
|
|
4532
4929
|
}
|
|
4533
|
-
function
|
|
4534
|
-
const currentState = state2();
|
|
4930
|
+
function step(event) {
|
|
4535
4931
|
const stateDef = config.states[currentState];
|
|
4536
4932
|
if (!stateDef?.on) return;
|
|
4537
4933
|
const transition2 = stateDef.on[event];
|
|
@@ -4546,38 +4942,61 @@ function machine(config) {
|
|
|
4546
4942
|
guard = transition2.guard;
|
|
4547
4943
|
action = transition2.action;
|
|
4548
4944
|
}
|
|
4549
|
-
const ctx =
|
|
4945
|
+
const ctx = currentContext;
|
|
4550
4946
|
if (guard && !guard(ctx)) return;
|
|
4551
4947
|
if (stateDef.exit) {
|
|
4552
4948
|
stateDef.exit(ctx);
|
|
4553
4949
|
}
|
|
4950
|
+
let nextContext = ctx;
|
|
4554
4951
|
if (action) {
|
|
4555
4952
|
const rawPatch = action(ctx);
|
|
4556
|
-
|
|
4557
|
-
setContext(next);
|
|
4953
|
+
nextContext = { ...ctx, ...stripUnsafeKeys(rawPatch) };
|
|
4558
4954
|
}
|
|
4559
|
-
|
|
4955
|
+
currentState = target;
|
|
4956
|
+
currentContext = nextContext;
|
|
4957
|
+
batch(() => {
|
|
4958
|
+
if (action) setContext(nextContext);
|
|
4959
|
+
setState(target);
|
|
4960
|
+
});
|
|
4560
4961
|
const targetDef = config.states[target];
|
|
4561
4962
|
if (targetDef?.entry) {
|
|
4562
|
-
targetDef.entry(
|
|
4963
|
+
targetDef.entry(currentContext);
|
|
4563
4964
|
}
|
|
4564
4965
|
}
|
|
4966
|
+
function send(event) {
|
|
4967
|
+
queue.push(event);
|
|
4968
|
+
if (processing) return;
|
|
4969
|
+
drain();
|
|
4970
|
+
}
|
|
4971
|
+
const initialDef = config.states[config.initial];
|
|
4972
|
+
if (initialDef?.entry) {
|
|
4973
|
+
processing = true;
|
|
4974
|
+
try {
|
|
4975
|
+
initialDef.entry(currentContext);
|
|
4976
|
+
} catch (err) {
|
|
4977
|
+
queue.length = 0;
|
|
4978
|
+
throw err;
|
|
4979
|
+
} finally {
|
|
4980
|
+
processing = false;
|
|
4981
|
+
}
|
|
4982
|
+
if (queue.length > 0) drain();
|
|
4983
|
+
}
|
|
4565
4984
|
function matches(s2) {
|
|
4566
4985
|
return state2() === s2;
|
|
4567
4986
|
}
|
|
4568
4987
|
function can(event) {
|
|
4569
|
-
const
|
|
4570
|
-
const stateDef = config.states[
|
|
4988
|
+
const currentState2 = state2();
|
|
4989
|
+
const stateDef = config.states[currentState2];
|
|
4571
4990
|
if (!stateDef?.on) return false;
|
|
4572
4991
|
const transition2 = stateDef.on[event];
|
|
4573
4992
|
if (!transition2) return false;
|
|
4574
4993
|
if (typeof transition2 === "string") return true;
|
|
4575
4994
|
if (transition2.guard) {
|
|
4576
|
-
return transition2.guard(
|
|
4995
|
+
return transition2.guard(context());
|
|
4577
4996
|
}
|
|
4578
4997
|
return true;
|
|
4579
4998
|
}
|
|
4580
|
-
return { state: state2, context
|
|
4999
|
+
return { state: state2, context, send, matches, can };
|
|
4581
5000
|
}
|
|
4582
5001
|
|
|
4583
5002
|
// src/patterns/persist.ts
|
|
@@ -4950,6 +5369,9 @@ function optimisticList(initialValue) {
|
|
|
4950
5369
|
|
|
4951
5370
|
// src/patterns/timeTravel.ts
|
|
4952
5371
|
function timeline(initial, maxHistory = 100) {
|
|
5372
|
+
if (!Number.isSafeInteger(maxHistory) || maxHistory < 1) {
|
|
5373
|
+
throw new RangeError(`[timeline] maxHistory must be a positive safe integer, got ${maxHistory}`);
|
|
5374
|
+
}
|
|
4953
5375
|
const [history2, setHistory] = signal([initial]);
|
|
4954
5376
|
const [index, setIndex] = signal(0);
|
|
4955
5377
|
const value = derived(() => history2()[index()]);
|
|
@@ -5004,6 +5426,120 @@ function timeline(initial, maxHistory = 100) {
|
|
|
5004
5426
|
return { value, set, undo, redo, canUndo, canRedo, history: history2, index, reset, jumpTo, dispose: dispose2 };
|
|
5005
5427
|
}
|
|
5006
5428
|
|
|
5429
|
+
// src/utils/adoption.ts
|
|
5430
|
+
var nativeThen = Promise.prototype.then;
|
|
5431
|
+
function probeNative(target, onRejected, onOpen) {
|
|
5432
|
+
let decided = false;
|
|
5433
|
+
const decide = (rejected) => {
|
|
5434
|
+
if (decided) return;
|
|
5435
|
+
decided = true;
|
|
5436
|
+
(rejected ? onRejected : onOpen)();
|
|
5437
|
+
};
|
|
5438
|
+
try {
|
|
5439
|
+
Reflect.apply(nativeThen, target, [void 0, () => decide(true)]);
|
|
5440
|
+
} catch {
|
|
5441
|
+
queueMicrotask(() => decide(true));
|
|
5442
|
+
return;
|
|
5443
|
+
}
|
|
5444
|
+
queueMicrotask(() => decide(false));
|
|
5445
|
+
}
|
|
5446
|
+
function adopt(value) {
|
|
5447
|
+
if (value === null || typeof value !== "object" && typeof value !== "function") return null;
|
|
5448
|
+
let then;
|
|
5449
|
+
try {
|
|
5450
|
+
then = value.then;
|
|
5451
|
+
} catch (error) {
|
|
5452
|
+
return {
|
|
5453
|
+
promise: Promise.reject(error),
|
|
5454
|
+
failedEarly: true,
|
|
5455
|
+
probe: (onRejected) => queueMicrotask(onRejected)
|
|
5456
|
+
};
|
|
5457
|
+
}
|
|
5458
|
+
if (typeof then !== "function") return null;
|
|
5459
|
+
let resolvePromise;
|
|
5460
|
+
let rejectPromise;
|
|
5461
|
+
const promise = new Promise((resolve, reject) => {
|
|
5462
|
+
resolvePromise = resolve;
|
|
5463
|
+
rejectPromise = reject;
|
|
5464
|
+
});
|
|
5465
|
+
let state2 = "invoking";
|
|
5466
|
+
let nativeTarget;
|
|
5467
|
+
const waiters = [];
|
|
5468
|
+
const transition2 = (next) => {
|
|
5469
|
+
state2 = next;
|
|
5470
|
+
if (next === "invoking") return;
|
|
5471
|
+
for (const waiter of waiters.splice(0)) waiter();
|
|
5472
|
+
};
|
|
5473
|
+
const fulfil = (result) => {
|
|
5474
|
+
resolvePromise(result);
|
|
5475
|
+
transition2("fulfilled");
|
|
5476
|
+
};
|
|
5477
|
+
const fail = (error) => {
|
|
5478
|
+
rejectPromise(error);
|
|
5479
|
+
transition2("rejected");
|
|
5480
|
+
};
|
|
5481
|
+
const follow = (result) => {
|
|
5482
|
+
if (result === promise) {
|
|
5483
|
+
fail(new TypeError("adopt: a thenable resolved to its own adoption"));
|
|
5484
|
+
return;
|
|
5485
|
+
}
|
|
5486
|
+
if (result === null || typeof result !== "object" && typeof result !== "function") {
|
|
5487
|
+
fulfil(result);
|
|
5488
|
+
return;
|
|
5489
|
+
}
|
|
5490
|
+
let nextThen;
|
|
5491
|
+
try {
|
|
5492
|
+
nextThen = result.then;
|
|
5493
|
+
} catch (error) {
|
|
5494
|
+
fail(error);
|
|
5495
|
+
return;
|
|
5496
|
+
}
|
|
5497
|
+
if (typeof nextThen !== "function") {
|
|
5498
|
+
fulfil(result);
|
|
5499
|
+
return;
|
|
5500
|
+
}
|
|
5501
|
+
invokeLater(result, nextThen);
|
|
5502
|
+
};
|
|
5503
|
+
const invokeLater = (target, targetThen) => {
|
|
5504
|
+
if (targetThen === nativeThen) {
|
|
5505
|
+
nativeTarget = target;
|
|
5506
|
+
transition2("native");
|
|
5507
|
+
} else {
|
|
5508
|
+
transition2("invoking");
|
|
5509
|
+
}
|
|
5510
|
+
queueMicrotask(() => {
|
|
5511
|
+
let done = false;
|
|
5512
|
+
const onResolve = (result) => {
|
|
5513
|
+
if (done) return;
|
|
5514
|
+
done = true;
|
|
5515
|
+
follow(result);
|
|
5516
|
+
};
|
|
5517
|
+
const onReject = (error) => {
|
|
5518
|
+
if (done) return;
|
|
5519
|
+
done = true;
|
|
5520
|
+
fail(error);
|
|
5521
|
+
};
|
|
5522
|
+
try {
|
|
5523
|
+
Reflect.apply(targetThen, target, [onResolve, onReject]);
|
|
5524
|
+
} catch (error) {
|
|
5525
|
+
onReject(error);
|
|
5526
|
+
}
|
|
5527
|
+
if (!done && state2 === "invoking") transition2("pending");
|
|
5528
|
+
});
|
|
5529
|
+
};
|
|
5530
|
+
invokeLater(value, then);
|
|
5531
|
+
const probe = (onRejected, onOpen) => {
|
|
5532
|
+
const decide = () => {
|
|
5533
|
+
if (state2 === "native") probeNative(nativeTarget, onRejected, onOpen);
|
|
5534
|
+
else (state2 === "rejected" ? onRejected : onOpen)();
|
|
5535
|
+
};
|
|
5536
|
+
if (state2 === "native") probeNative(nativeTarget, onRejected, onOpen);
|
|
5537
|
+
else if (state2 === "invoking") waiters.push(decide);
|
|
5538
|
+
else queueMicrotask(state2 === "rejected" ? onRejected : onOpen);
|
|
5539
|
+
};
|
|
5540
|
+
return { promise, failedEarly: false, probe };
|
|
5541
|
+
}
|
|
5542
|
+
|
|
5007
5543
|
// src/patterns/globalStore.ts
|
|
5008
5544
|
function deepClone(value) {
|
|
5009
5545
|
if (typeof structuredClone === "function") {
|
|
@@ -5038,8 +5574,51 @@ function deepClone(value) {
|
|
|
5038
5574
|
function globalStore(config) {
|
|
5039
5575
|
const initialState = deepClone(config.state);
|
|
5040
5576
|
const [getState, setState] = signal({ ...initialState });
|
|
5041
|
-
const
|
|
5577
|
+
const subscriptions = /* @__PURE__ */ new Map();
|
|
5042
5578
|
const middlewares = config.middleware || [];
|
|
5579
|
+
function notifyListeners2(state2) {
|
|
5580
|
+
if (subscriptions.size === 0) return;
|
|
5581
|
+
for (const subscription of Array.from(subscriptions.values())) {
|
|
5582
|
+
if (!subscription.active) continue;
|
|
5583
|
+
try {
|
|
5584
|
+
subscription.callback(state2);
|
|
5585
|
+
} catch (err) {
|
|
5586
|
+
reportError(err, { phase: "event", name: "globalStore(subscribe)" });
|
|
5587
|
+
}
|
|
5588
|
+
}
|
|
5589
|
+
}
|
|
5590
|
+
const operations = [];
|
|
5591
|
+
let running = false;
|
|
5592
|
+
function perform(operation, rethrowOwn = true) {
|
|
5593
|
+
operations.push(operation);
|
|
5594
|
+
if (running) return;
|
|
5595
|
+
running = true;
|
|
5596
|
+
let callerError;
|
|
5597
|
+
let callerFailed = false;
|
|
5598
|
+
try {
|
|
5599
|
+
let first = true;
|
|
5600
|
+
let cursor = 0;
|
|
5601
|
+
while (cursor < operations.length) {
|
|
5602
|
+
const next = operations[cursor];
|
|
5603
|
+
operations[cursor++] = void 0;
|
|
5604
|
+
try {
|
|
5605
|
+
next();
|
|
5606
|
+
} catch (err) {
|
|
5607
|
+
if (first && rethrowOwn) {
|
|
5608
|
+
callerFailed = true;
|
|
5609
|
+
callerError = err;
|
|
5610
|
+
} else {
|
|
5611
|
+
reportError(err, { phase: "event", name: "globalStore(dispatch)" });
|
|
5612
|
+
}
|
|
5613
|
+
}
|
|
5614
|
+
first = false;
|
|
5615
|
+
}
|
|
5616
|
+
} finally {
|
|
5617
|
+
operations.length = 0;
|
|
5618
|
+
running = false;
|
|
5619
|
+
}
|
|
5620
|
+
if (callerFailed) throw callerError;
|
|
5621
|
+
}
|
|
5043
5622
|
function dispatch(action, payload) {
|
|
5044
5623
|
const actionFn = config.actions[action];
|
|
5045
5624
|
if (!actionFn) throw new Error(`Unknown action: ${String(action)}`);
|
|
@@ -5048,38 +5627,96 @@ function globalStore(config) {
|
|
|
5048
5627
|
const rawPatch = actionFn(current, payload);
|
|
5049
5628
|
const patch = stripUnsafeKeys(rawPatch);
|
|
5050
5629
|
setState({ ...current, ...patch });
|
|
5051
|
-
|
|
5052
|
-
for (const listener of listeners) {
|
|
5053
|
-
listener(newState);
|
|
5054
|
-
}
|
|
5630
|
+
notifyListeners2(getState());
|
|
5055
5631
|
};
|
|
5056
|
-
|
|
5057
|
-
|
|
5058
|
-
return;
|
|
5059
|
-
}
|
|
5060
|
-
let index = 0;
|
|
5061
|
-
const next = () => {
|
|
5062
|
-
if (index < middlewares.length) {
|
|
5063
|
-
const mw = middlewares[index++];
|
|
5064
|
-
mw(getState(), String(action), payload, next);
|
|
5065
|
-
} else {
|
|
5632
|
+
perform(() => {
|
|
5633
|
+
if (middlewares.length === 0) {
|
|
5066
5634
|
execute();
|
|
5635
|
+
return;
|
|
5067
5636
|
}
|
|
5068
|
-
|
|
5069
|
-
|
|
5637
|
+
const runFrom = (index) => {
|
|
5638
|
+
if (index >= middlewares.length) {
|
|
5639
|
+
execute();
|
|
5640
|
+
return;
|
|
5641
|
+
}
|
|
5642
|
+
let called = false;
|
|
5643
|
+
let failed = false;
|
|
5644
|
+
let synchronous = true;
|
|
5645
|
+
const next = () => {
|
|
5646
|
+
if (failed && !called) {
|
|
5647
|
+
if (DEV)
|
|
5648
|
+
devWarn(
|
|
5649
|
+
`globalStore: middleware ${index} next() called after it failed for "${String(action)}"; ignored.`
|
|
5650
|
+
);
|
|
5651
|
+
called = true;
|
|
5652
|
+
return;
|
|
5653
|
+
}
|
|
5654
|
+
if (called) {
|
|
5655
|
+
if (DEV)
|
|
5656
|
+
devWarn(
|
|
5657
|
+
`globalStore: middleware ${index} next() called more than once for "${String(action)}"; ignored.`
|
|
5658
|
+
);
|
|
5659
|
+
return;
|
|
5660
|
+
}
|
|
5661
|
+
called = true;
|
|
5662
|
+
if (synchronous) {
|
|
5663
|
+
runFrom(index + 1);
|
|
5664
|
+
return;
|
|
5665
|
+
}
|
|
5666
|
+
const proceed = () => perform(() => runFrom(index + 1), false);
|
|
5667
|
+
if (!adoption) {
|
|
5668
|
+
proceed();
|
|
5669
|
+
return;
|
|
5670
|
+
}
|
|
5671
|
+
adoption.probe(() => {
|
|
5672
|
+
failed = true;
|
|
5673
|
+
if (DEV)
|
|
5674
|
+
devWarn(
|
|
5675
|
+
`globalStore: middleware ${index} next() called after it failed for "${String(action)}"; ignored.`
|
|
5676
|
+
);
|
|
5677
|
+
}, proceed);
|
|
5678
|
+
};
|
|
5679
|
+
let adoption = null;
|
|
5680
|
+
try {
|
|
5681
|
+
adoption = adopt(middlewares[index](getState(), String(action), payload, next));
|
|
5682
|
+
} catch (err) {
|
|
5683
|
+
failed = true;
|
|
5684
|
+
throw err;
|
|
5685
|
+
} finally {
|
|
5686
|
+
synchronous = false;
|
|
5687
|
+
}
|
|
5688
|
+
if (adoption) {
|
|
5689
|
+
if (adoption.failedEarly) failed = true;
|
|
5690
|
+
adoption.promise.then(void 0, (err) => {
|
|
5691
|
+
failed = true;
|
|
5692
|
+
reportError(err, { phase: "async", name: "globalStore(middleware)" });
|
|
5693
|
+
});
|
|
5694
|
+
}
|
|
5695
|
+
};
|
|
5696
|
+
runFrom(0);
|
|
5697
|
+
});
|
|
5070
5698
|
}
|
|
5071
5699
|
function select3(selector) {
|
|
5072
5700
|
return () => selector(getState());
|
|
5073
5701
|
}
|
|
5074
5702
|
function subscribe(callback) {
|
|
5075
|
-
|
|
5076
|
-
|
|
5703
|
+
let subscription = subscriptions.get(callback);
|
|
5704
|
+
if (!subscription) {
|
|
5705
|
+
subscription = { callback, active: true };
|
|
5706
|
+
subscriptions.set(callback, subscription);
|
|
5707
|
+
}
|
|
5708
|
+
const own = subscription;
|
|
5709
|
+
return () => {
|
|
5710
|
+
if (subscriptions.get(callback) !== own) return;
|
|
5711
|
+
own.active = false;
|
|
5712
|
+
subscriptions.delete(callback);
|
|
5713
|
+
};
|
|
5077
5714
|
}
|
|
5078
5715
|
function reset() {
|
|
5079
|
-
|
|
5080
|
-
|
|
5081
|
-
|
|
5082
|
-
}
|
|
5716
|
+
perform(() => {
|
|
5717
|
+
setState({ ...initialState });
|
|
5718
|
+
notifyListeners2(getState());
|
|
5719
|
+
});
|
|
5083
5720
|
}
|
|
5084
5721
|
return { getState, select: select3, dispatch, subscribe, reset };
|
|
5085
5722
|
}
|
|
@@ -5203,7 +5840,7 @@ function validateProps(props, schema) {
|
|
|
5203
5840
|
const errors = [];
|
|
5204
5841
|
for (const [key, def] of Object.entries(schema)) {
|
|
5205
5842
|
const propDef = typeof def === "function" ? { type: def } : def;
|
|
5206
|
-
if (result[key]
|
|
5843
|
+
if (result[key] === void 0 && propDef.default !== void 0) {
|
|
5207
5844
|
result[key] = typeof propDef.default === "function" ? propDef.default() : propDef.default;
|
|
5208
5845
|
}
|
|
5209
5846
|
if (propDef.required && result[key] == null) {
|
|
@@ -5229,7 +5866,7 @@ ${errors.map((e) => ` - ${e}`).join("\n")}`);
|
|
|
5229
5866
|
for (const [key, def] of Object.entries(schema)) {
|
|
5230
5867
|
if (typeof def === "function") continue;
|
|
5231
5868
|
const fallback = def.default;
|
|
5232
|
-
if (result[key]
|
|
5869
|
+
if (result[key] === void 0 && fallback !== void 0) {
|
|
5233
5870
|
result[key] = typeof fallback === "function" ? fallback() : fallback;
|
|
5234
5871
|
}
|
|
5235
5872
|
}
|
|
@@ -5255,81 +5892,6 @@ function createGuard(validator) {
|
|
|
5255
5892
|
};
|
|
5256
5893
|
}
|
|
5257
5894
|
|
|
5258
|
-
// src/core/rendering/dispose.ts
|
|
5259
|
-
var elementDisposers = /* @__PURE__ */ new WeakMap();
|
|
5260
|
-
var MAX_DRAIN_TEARDOWNS = 1e4;
|
|
5261
|
-
function reportDrainRunaway(label2, executed, remaining) {
|
|
5262
|
-
if (typeof console === "undefined") return;
|
|
5263
|
-
console.error(
|
|
5264
|
-
`[SibuJS ${label2}] runaway cleanup: stopped after running ${executed} teardowns with ${remaining} still queued. Cleanup production did not stabilize before the teardown safety ceiling was reached \u2014 the remaining work was NOT run.`,
|
|
5265
|
-
{ executed, remaining }
|
|
5266
|
-
);
|
|
5267
|
-
}
|
|
5268
|
-
var activeBindingCount = 0;
|
|
5269
|
-
function registerDisposer(node, teardown) {
|
|
5270
|
-
let disposers = elementDisposers.get(node);
|
|
5271
|
-
if (!disposers) {
|
|
5272
|
-
disposers = [];
|
|
5273
|
-
elementDisposers.set(node, disposers);
|
|
5274
|
-
}
|
|
5275
|
-
disposers.push(teardown);
|
|
5276
|
-
if (DEV) activeBindingCount++;
|
|
5277
|
-
}
|
|
5278
|
-
function dispose(node) {
|
|
5279
|
-
const stack = [node];
|
|
5280
|
-
const order = [];
|
|
5281
|
-
while (stack.length > 0) {
|
|
5282
|
-
const current = stack.pop();
|
|
5283
|
-
order.push(current);
|
|
5284
|
-
const children = Array.from(current.childNodes);
|
|
5285
|
-
for (let i2 = 0; i2 < children.length; i2++) {
|
|
5286
|
-
stack.push(children[i2]);
|
|
5287
|
-
}
|
|
5288
|
-
}
|
|
5289
|
-
for (let i2 = order.length - 1; i2 >= 0; i2--) {
|
|
5290
|
-
const current = order[i2];
|
|
5291
|
-
if (elementDisposers.has(current)) {
|
|
5292
|
-
let executed = 0;
|
|
5293
|
-
let runaway = false;
|
|
5294
|
-
while (!runaway) {
|
|
5295
|
-
const pending = elementDisposers.get(current);
|
|
5296
|
-
if (!pending || pending.length === 0) break;
|
|
5297
|
-
const snapshot = pending.slice();
|
|
5298
|
-
elementDisposers.delete(current);
|
|
5299
|
-
if (DEV) activeBindingCount -= snapshot.length;
|
|
5300
|
-
for (let i3 = 0; i3 < snapshot.length; i3++) {
|
|
5301
|
-
if (executed >= MAX_DRAIN_TEARDOWNS) {
|
|
5302
|
-
const rest = snapshot.slice(i3);
|
|
5303
|
-
const added = elementDisposers.get(current);
|
|
5304
|
-
elementDisposers.set(current, added ? rest.concat(added) : rest);
|
|
5305
|
-
if (DEV) activeBindingCount += rest.length;
|
|
5306
|
-
reportDrainRunaway("dispose", executed, rest.length + (added?.length ?? 0));
|
|
5307
|
-
runaway = true;
|
|
5308
|
-
break;
|
|
5309
|
-
}
|
|
5310
|
-
executed++;
|
|
5311
|
-
try {
|
|
5312
|
-
snapshot[i3]();
|
|
5313
|
-
} catch (err) {
|
|
5314
|
-
reportError(err, { phase: "cleanup", name: "disposer" });
|
|
5315
|
-
}
|
|
5316
|
-
}
|
|
5317
|
-
}
|
|
5318
|
-
}
|
|
5319
|
-
}
|
|
5320
|
-
}
|
|
5321
|
-
function replaceChildrenSafely(parent, ...next) {
|
|
5322
|
-
for (let i2 = 0; i2 < next.length; i2++) {
|
|
5323
|
-
const node = next[i2];
|
|
5324
|
-
node.parentNode?.removeChild(node);
|
|
5325
|
-
}
|
|
5326
|
-
const current = Array.from(parent.childNodes);
|
|
5327
|
-
for (let i2 = 0; i2 < current.length; i2++) {
|
|
5328
|
-
dispose(current[i2]);
|
|
5329
|
-
}
|
|
5330
|
-
parent.replaceChildren(...next);
|
|
5331
|
-
}
|
|
5332
|
-
|
|
5333
5895
|
// src/ui/transition.ts
|
|
5334
5896
|
function transition(element, options = {}) {
|
|
5335
5897
|
const {
|
|
@@ -5357,6 +5919,15 @@ function transition(element, options = {}) {
|
|
|
5357
5919
|
resolvePrev();
|
|
5358
5920
|
}
|
|
5359
5921
|
}
|
|
5922
|
+
function complete(callback, name, resolve) {
|
|
5923
|
+
try {
|
|
5924
|
+
callback?.();
|
|
5925
|
+
} catch (error) {
|
|
5926
|
+
reportError(error, { phase: "async", name, node: element });
|
|
5927
|
+
} finally {
|
|
5928
|
+
resolve();
|
|
5929
|
+
}
|
|
5930
|
+
}
|
|
5360
5931
|
function enter() {
|
|
5361
5932
|
return new Promise((resolve) => {
|
|
5362
5933
|
cancelPending();
|
|
@@ -5369,8 +5940,7 @@ function transition(element, options = {}) {
|
|
|
5369
5940
|
activeTimer = null;
|
|
5370
5941
|
pendingResolve = null;
|
|
5371
5942
|
if (enterClass) element.classList.remove(enterClass);
|
|
5372
|
-
onEnterDone
|
|
5373
|
-
resolve();
|
|
5943
|
+
complete(onEnterDone, "transition(onEnterDone)", resolve);
|
|
5374
5944
|
};
|
|
5375
5945
|
if (duration > 0) {
|
|
5376
5946
|
pendingResolve = resolve;
|
|
@@ -5391,8 +5961,7 @@ function transition(element, options = {}) {
|
|
|
5391
5961
|
activeTimer = null;
|
|
5392
5962
|
pendingResolve = null;
|
|
5393
5963
|
if (leaveClass) element.classList.remove(leaveClass);
|
|
5394
|
-
onLeaveDone
|
|
5395
|
-
resolve();
|
|
5964
|
+
complete(onLeaveDone, "transition(onLeaveDone)", resolve);
|
|
5396
5965
|
};
|
|
5397
5966
|
if (duration > 0) {
|
|
5398
5967
|
pendingResolve = resolve;
|
|
@@ -5595,22 +6164,54 @@ async function sequence(steps) {
|
|
|
5595
6164
|
}
|
|
5596
6165
|
}
|
|
5597
6166
|
|
|
6167
|
+
// src/utils/adoptThenable.ts
|
|
6168
|
+
function adoptThenable(value) {
|
|
6169
|
+
if (value === null || typeof value !== "object" && typeof value !== "function") return null;
|
|
6170
|
+
let then;
|
|
6171
|
+
try {
|
|
6172
|
+
then = value.then;
|
|
6173
|
+
} catch (error) {
|
|
6174
|
+
return Promise.reject(error);
|
|
6175
|
+
}
|
|
6176
|
+
if (typeof then !== "function") return null;
|
|
6177
|
+
return new Promise((resolve, reject) => {
|
|
6178
|
+
queueMicrotask(() => {
|
|
6179
|
+
try {
|
|
6180
|
+
Reflect.apply(then, value, [resolve, reject]);
|
|
6181
|
+
} catch (error) {
|
|
6182
|
+
reject(error);
|
|
6183
|
+
}
|
|
6184
|
+
});
|
|
6185
|
+
});
|
|
6186
|
+
}
|
|
6187
|
+
|
|
5598
6188
|
// src/ui/TransitionGroup.ts
|
|
5599
6189
|
function TransitionGroup(options) {
|
|
5600
6190
|
const [elements, setElements] = signal([]);
|
|
5601
6191
|
const positions = /* @__PURE__ */ new Map();
|
|
6192
|
+
function runCallback2(name, callback, el) {
|
|
6193
|
+
const report = (error) => reportError(error, { phase: "async", name: `TransitionGroup.${name}`, node: el });
|
|
6194
|
+
try {
|
|
6195
|
+
adoptThenable(callback(el))?.then(void 0, report);
|
|
6196
|
+
} catch (error) {
|
|
6197
|
+
report(error);
|
|
6198
|
+
}
|
|
6199
|
+
}
|
|
5602
6200
|
function add(el) {
|
|
5603
6201
|
setElements((prev) => [...prev, el]);
|
|
5604
|
-
if (options.enter)
|
|
5605
|
-
options.enter(el);
|
|
5606
|
-
}
|
|
6202
|
+
if (options.enter) runCallback2("enter", options.enter, el);
|
|
5607
6203
|
}
|
|
5608
6204
|
async function remove(el) {
|
|
5609
|
-
|
|
5610
|
-
|
|
6205
|
+
try {
|
|
6206
|
+
if (options.leave) {
|
|
6207
|
+
await adoptThenable(options.leave(el));
|
|
6208
|
+
}
|
|
6209
|
+
} catch (error) {
|
|
6210
|
+
reportError(error, { phase: "async", name: "TransitionGroup.leave", node: el });
|
|
6211
|
+
} finally {
|
|
6212
|
+
positions.delete(el);
|
|
6213
|
+
setElements((prev) => prev.filter((e) => e !== el));
|
|
5611
6214
|
}
|
|
5612
|
-
positions.delete(el);
|
|
5613
|
-
setElements((prev) => prev.filter((e) => e !== el));
|
|
5614
6215
|
}
|
|
5615
6216
|
function track4(newElements) {
|
|
5616
6217
|
const oldPositions = /* @__PURE__ */ new Map();
|
|
@@ -5622,17 +6223,13 @@ function TransitionGroup(options) {
|
|
|
5622
6223
|
const currentSet = new Set(elements());
|
|
5623
6224
|
for (const el of newElements) {
|
|
5624
6225
|
if (!currentSet.has(el)) {
|
|
5625
|
-
if (options.enter)
|
|
5626
|
-
options.enter(el);
|
|
5627
|
-
}
|
|
6226
|
+
if (options.enter) runCallback2("enter", options.enter, el);
|
|
5628
6227
|
}
|
|
5629
6228
|
}
|
|
5630
6229
|
const newSet = new Set(newElements);
|
|
5631
6230
|
for (const el of elements()) {
|
|
5632
6231
|
if (!newSet.has(el)) {
|
|
5633
|
-
if (options.leave)
|
|
5634
|
-
options.leave(el);
|
|
5635
|
-
}
|
|
6232
|
+
if (options.leave) runCallback2("leave", options.leave, el);
|
|
5636
6233
|
}
|
|
5637
6234
|
}
|
|
5638
6235
|
setElements(newElements);
|
|
@@ -5642,7 +6239,7 @@ function TransitionGroup(options) {
|
|
|
5642
6239
|
if (oldRect && typeof el.getBoundingClientRect === "function") {
|
|
5643
6240
|
const newRect = el.getBoundingClientRect();
|
|
5644
6241
|
if (oldRect.left !== newRect.left || oldRect.top !== newRect.top) {
|
|
5645
|
-
options.move
|
|
6242
|
+
runCallback2("move", options.move, el);
|
|
5646
6243
|
}
|
|
5647
6244
|
}
|
|
5648
6245
|
}
|
|
@@ -5693,9 +6290,13 @@ function springSignal(initial, options) {
|
|
|
5693
6290
|
let target = initial;
|
|
5694
6291
|
let rafId = null;
|
|
5695
6292
|
let lastTime = 0;
|
|
6293
|
+
let disposed = false;
|
|
6294
|
+
const canAnimate = () => typeof requestAnimationFrame === "function";
|
|
5696
6295
|
const REF_DT_MS = 1e3 / 60;
|
|
5697
6296
|
const MAX_STEP_RATIO = 4;
|
|
5698
6297
|
function tick(now) {
|
|
6298
|
+
rafId = null;
|
|
6299
|
+
if (disposed) return;
|
|
5699
6300
|
if (lastTime === 0) lastTime = now;
|
|
5700
6301
|
const rawDt = now - lastTime;
|
|
5701
6302
|
lastTime = now;
|
|
@@ -5708,23 +6309,27 @@ function springSignal(initial, options) {
|
|
|
5708
6309
|
if (Math.abs(current - target) < precision && Math.abs(velocity) < precision) {
|
|
5709
6310
|
current = target;
|
|
5710
6311
|
velocity = 0;
|
|
5711
|
-
rafId = null;
|
|
5712
6312
|
lastTime = 0;
|
|
5713
6313
|
setValue(current);
|
|
5714
6314
|
return;
|
|
5715
6315
|
}
|
|
5716
6316
|
setValue(current);
|
|
6317
|
+
if (disposed || rafId !== null) return;
|
|
5717
6318
|
rafId = requestAnimationFrame(tick);
|
|
5718
6319
|
}
|
|
6320
|
+
function cancelFrame() {
|
|
6321
|
+
if (rafId !== null) {
|
|
6322
|
+
if (typeof cancelAnimationFrame === "function") cancelAnimationFrame(rafId);
|
|
6323
|
+
rafId = null;
|
|
6324
|
+
}
|
|
6325
|
+
}
|
|
5719
6326
|
function set(newTarget) {
|
|
6327
|
+
if (disposed) return;
|
|
5720
6328
|
target = newTarget;
|
|
5721
|
-
if (prefersReducedMotion()) {
|
|
6329
|
+
if (!canAnimate() || prefersReducedMotion()) {
|
|
5722
6330
|
current = newTarget;
|
|
5723
6331
|
velocity = 0;
|
|
5724
|
-
|
|
5725
|
-
cancelAnimationFrame(rafId);
|
|
5726
|
-
rafId = null;
|
|
5727
|
-
}
|
|
6332
|
+
cancelFrame();
|
|
5728
6333
|
lastTime = 0;
|
|
5729
6334
|
setValue(current);
|
|
5730
6335
|
return;
|
|
@@ -5735,15 +6340,20 @@ function springSignal(initial, options) {
|
|
|
5735
6340
|
}
|
|
5736
6341
|
}
|
|
5737
6342
|
function dispose2() {
|
|
5738
|
-
|
|
5739
|
-
|
|
5740
|
-
rafId = null;
|
|
5741
|
-
}
|
|
6343
|
+
disposed = true;
|
|
6344
|
+
cancelFrame();
|
|
5742
6345
|
lastTime = 0;
|
|
5743
6346
|
}
|
|
5744
6347
|
return [value, set, dispose2];
|
|
5745
6348
|
}
|
|
5746
6349
|
|
|
6350
|
+
// src/reactivity/domBinding.ts
|
|
6351
|
+
function domBinding(commit, ownerNode) {
|
|
6352
|
+
if (isSSR()) return () => {
|
|
6353
|
+
};
|
|
6354
|
+
return reactiveBinding2(commit, ownerNode);
|
|
6355
|
+
}
|
|
6356
|
+
|
|
5747
6357
|
// src/ui/form.ts
|
|
5748
6358
|
function required(message = "This field is required") {
|
|
5749
6359
|
return (value) => {
|
|
@@ -5771,10 +6381,14 @@ function maxLength(max2, message) {
|
|
|
5771
6381
|
}
|
|
5772
6382
|
function matchesPattern(regex, message = "Invalid format") {
|
|
5773
6383
|
return (value) => {
|
|
5774
|
-
if (
|
|
5775
|
-
|
|
6384
|
+
if (!value) return null;
|
|
6385
|
+
const savedLastIndex = regex.lastIndex;
|
|
6386
|
+
regex.lastIndex = 0;
|
|
6387
|
+
try {
|
|
6388
|
+
return regex.test(value) ? null : message;
|
|
6389
|
+
} finally {
|
|
6390
|
+
regex.lastIndex = savedLastIndex;
|
|
5776
6391
|
}
|
|
5777
|
-
return null;
|
|
5778
6392
|
};
|
|
5779
6393
|
}
|
|
5780
6394
|
function email(message = "Invalid email address") {
|
|
@@ -5823,13 +6437,13 @@ function bindField(field, extras) {
|
|
|
5823
6437
|
const mergedOn = extraOn && typeof extraOn === "object" ? { ...extraOn, ...fieldOn } : fieldOn;
|
|
5824
6438
|
const onElement = (el) => {
|
|
5825
6439
|
if (el instanceof HTMLSelectElement && el.multiple) {
|
|
5826
|
-
const stop2 =
|
|
6440
|
+
const stop2 = domBinding(() => {
|
|
5827
6441
|
const v = field.value();
|
|
5828
6442
|
const selected = Array.isArray(v) ? v.map(String) : [];
|
|
5829
6443
|
for (const opt of Array.from(el.options)) {
|
|
5830
6444
|
opt.selected = selected.includes(opt.value);
|
|
5831
6445
|
}
|
|
5832
|
-
});
|
|
6446
|
+
}, el);
|
|
5833
6447
|
registerDisposer(el, stop2);
|
|
5834
6448
|
}
|
|
5835
6449
|
if (typeof extraOnElement === "function") {
|
|
@@ -5849,6 +6463,7 @@ function form(config) {
|
|
|
5849
6463
|
const fieldEntries = Object.entries(config);
|
|
5850
6464
|
const fieldMap = {};
|
|
5851
6465
|
const [manualErrors, setManualErrors] = signal({});
|
|
6466
|
+
const fieldErrors = [];
|
|
5852
6467
|
for (const [name, cfg] of fieldEntries) {
|
|
5853
6468
|
const [value, setValue] = signal(cfg.initial);
|
|
5854
6469
|
const [isTouched, setTouched] = signal(false);
|
|
@@ -5863,6 +6478,7 @@ function form(config) {
|
|
|
5863
6478
|
}
|
|
5864
6479
|
return null;
|
|
5865
6480
|
});
|
|
6481
|
+
fieldErrors.push(error);
|
|
5866
6482
|
const wrappedSet = (next) => {
|
|
5867
6483
|
setValue(next);
|
|
5868
6484
|
setManualErrors((prev) => {
|
|
@@ -5939,12 +6555,22 @@ function form(config) {
|
|
|
5939
6555
|
field.touch();
|
|
5940
6556
|
}
|
|
5941
6557
|
if (isValid()) {
|
|
5942
|
-
const
|
|
5943
|
-
|
|
6558
|
+
const report = (error) => reportError(error, { phase: "async", name: "form.handleSubmit" });
|
|
6559
|
+
let pending;
|
|
6560
|
+
try {
|
|
6561
|
+
pending = adoptThenable(onSubmit(values()));
|
|
6562
|
+
} catch (error) {
|
|
6563
|
+
report(error);
|
|
6564
|
+
return;
|
|
6565
|
+
}
|
|
6566
|
+
if (pending) {
|
|
5944
6567
|
setSubmitting(true);
|
|
5945
|
-
|
|
6568
|
+
pending.then(
|
|
5946
6569
|
() => setSubmitting(false),
|
|
5947
|
-
() =>
|
|
6570
|
+
(error) => {
|
|
6571
|
+
setSubmitting(false);
|
|
6572
|
+
report(error);
|
|
6573
|
+
}
|
|
5948
6574
|
);
|
|
5949
6575
|
}
|
|
5950
6576
|
}
|
|
@@ -5958,6 +6584,17 @@ function form(config) {
|
|
|
5958
6584
|
function setError(field, message) {
|
|
5959
6585
|
setManualErrors((prev) => ({ ...prev, [field]: message }));
|
|
5960
6586
|
}
|
|
6587
|
+
let disposed = false;
|
|
6588
|
+
function dispose2() {
|
|
6589
|
+
if (disposed) return;
|
|
6590
|
+
disposed = true;
|
|
6591
|
+
errors.dispose();
|
|
6592
|
+
isValid.dispose();
|
|
6593
|
+
isDirty.dispose();
|
|
6594
|
+
touchedState.dispose();
|
|
6595
|
+
values.dispose();
|
|
6596
|
+
for (const error of fieldErrors) error.dispose();
|
|
6597
|
+
}
|
|
5961
6598
|
return {
|
|
5962
6599
|
fields: fieldMap,
|
|
5963
6600
|
errors,
|
|
@@ -5968,7 +6605,8 @@ function form(config) {
|
|
|
5968
6605
|
values,
|
|
5969
6606
|
handleSubmit,
|
|
5970
6607
|
reset,
|
|
5971
|
-
setError
|
|
6608
|
+
setError,
|
|
6609
|
+
dispose: dispose2
|
|
5972
6610
|
};
|
|
5973
6611
|
}
|
|
5974
6612
|
|
|
@@ -6012,7 +6650,7 @@ function VirtualList(props) {
|
|
|
6012
6650
|
content.appendChild(itemEl);
|
|
6013
6651
|
}
|
|
6014
6652
|
};
|
|
6015
|
-
registerDisposer(container,
|
|
6653
|
+
registerDisposer(container, domBinding(update, container));
|
|
6016
6654
|
return container;
|
|
6017
6655
|
}
|
|
6018
6656
|
|
|
@@ -6022,11 +6660,14 @@ function intersection(options) {
|
|
|
6022
6660
|
const [ratio, setRatio] = signal(0);
|
|
6023
6661
|
let observer = null;
|
|
6024
6662
|
let currentElement = null;
|
|
6663
|
+
let generation = 0;
|
|
6025
6664
|
function observe(element) {
|
|
6026
6665
|
if (typeof IntersectionObserver === "undefined") return;
|
|
6027
6666
|
unobserve();
|
|
6028
6667
|
currentElement = element;
|
|
6668
|
+
const observation = ++generation;
|
|
6029
6669
|
observer = new IntersectionObserver((entries) => {
|
|
6670
|
+
if (observation !== generation) return;
|
|
6030
6671
|
const entry = entries[0];
|
|
6031
6672
|
if (entry) {
|
|
6032
6673
|
setIsIntersecting(entry.isIntersecting);
|
|
@@ -6036,8 +6677,10 @@ function intersection(options) {
|
|
|
6036
6677
|
observer.observe(element);
|
|
6037
6678
|
}
|
|
6038
6679
|
function unobserve() {
|
|
6680
|
+
generation++;
|
|
6039
6681
|
if (observer) {
|
|
6040
6682
|
if (currentElement) observer.unobserve(currentElement);
|
|
6683
|
+
observer.takeRecords();
|
|
6041
6684
|
observer.disconnect();
|
|
6042
6685
|
observer = null;
|
|
6043
6686
|
currentElement = null;
|
|
@@ -6056,17 +6699,26 @@ function lazyLoad(element, loader, options) {
|
|
|
6056
6699
|
return () => {
|
|
6057
6700
|
};
|
|
6058
6701
|
}
|
|
6702
|
+
let done = false;
|
|
6703
|
+
const stop2 = () => {
|
|
6704
|
+
done = true;
|
|
6705
|
+
observer.takeRecords();
|
|
6706
|
+
observer.disconnect();
|
|
6707
|
+
};
|
|
6059
6708
|
const observer = new IntersectionObserver((entries) => {
|
|
6709
|
+
if (done) return;
|
|
6060
6710
|
for (const entry of entries) {
|
|
6061
6711
|
if (entry.isIntersecting) {
|
|
6712
|
+
stop2();
|
|
6062
6713
|
loader();
|
|
6063
|
-
observer.disconnect();
|
|
6064
6714
|
break;
|
|
6065
6715
|
}
|
|
6066
6716
|
}
|
|
6067
6717
|
}, options);
|
|
6068
6718
|
observer.observe(element);
|
|
6069
|
-
return () =>
|
|
6719
|
+
return () => {
|
|
6720
|
+
if (!done) stop2();
|
|
6721
|
+
};
|
|
6070
6722
|
}
|
|
6071
6723
|
|
|
6072
6724
|
// src/ui/inputMask.ts
|
|
@@ -6215,6 +6867,7 @@ function focus() {
|
|
|
6215
6867
|
const dispose2 = () => {
|
|
6216
6868
|
if (disposed) return;
|
|
6217
6869
|
disposed = true;
|
|
6870
|
+
unregisterDisposer(element, dispose2);
|
|
6218
6871
|
element.removeEventListener("focus", onFocus);
|
|
6219
6872
|
element.removeEventListener("blur", onBlur);
|
|
6220
6873
|
if (currentElement === element) currentElement = null;
|
|
@@ -6283,14 +6936,19 @@ function FocusTrap(nodes, options = {}) {
|
|
|
6283
6936
|
}
|
|
6284
6937
|
};
|
|
6285
6938
|
container.addEventListener("keydown", onTrapKeydown);
|
|
6939
|
+
let disposed = false;
|
|
6286
6940
|
if (options.autoFocus !== false) {
|
|
6287
6941
|
queueMicrotask(() => {
|
|
6942
|
+
if (disposed || !container.isConnected) return;
|
|
6288
6943
|
const first = getFocusable()[0];
|
|
6289
6944
|
first?.focus();
|
|
6290
6945
|
});
|
|
6291
6946
|
}
|
|
6292
6947
|
let trapObserver = null;
|
|
6293
6948
|
function restoreFocusAndCleanup() {
|
|
6949
|
+
if (disposed) return;
|
|
6950
|
+
disposed = true;
|
|
6951
|
+
unregisterDisposer(container, restoreFocusAndCleanup);
|
|
6294
6952
|
if (options.restoreFocus !== false) previouslyFocused?.focus();
|
|
6295
6953
|
container.removeEventListener("keydown", onTrapKeydown);
|
|
6296
6954
|
if (trapObserver) {
|
|
@@ -6305,29 +6963,45 @@ function FocusTrap(nodes, options = {}) {
|
|
|
6305
6963
|
}
|
|
6306
6964
|
});
|
|
6307
6965
|
queueMicrotask(() => {
|
|
6308
|
-
|
|
6309
|
-
|
|
6310
|
-
}
|
|
6966
|
+
const observer = trapObserver;
|
|
6967
|
+
if (disposed || !container.isConnected || !observer) return;
|
|
6968
|
+
observer.observe(container, { childList: true, subtree: true });
|
|
6311
6969
|
});
|
|
6312
6970
|
}
|
|
6313
6971
|
registerDisposer(container, restoreFocusAndCleanup);
|
|
6314
6972
|
return container;
|
|
6315
6973
|
}
|
|
6974
|
+
function isApplePlatform() {
|
|
6975
|
+
if (typeof navigator === "undefined") return false;
|
|
6976
|
+
const nav2 = navigator;
|
|
6977
|
+
return /mac|iphone|ipad|ipod/i.test(nav2.userAgentData?.platform || nav2.platform || "");
|
|
6978
|
+
}
|
|
6316
6979
|
function hotkey(combo, handler, options = {}) {
|
|
6317
6980
|
let key = combo;
|
|
6318
6981
|
let needCtrl = options.ctrl ?? false;
|
|
6319
6982
|
let needShift = options.shift ?? false;
|
|
6320
6983
|
let needAlt = options.alt ?? false;
|
|
6321
6984
|
let needMeta = options.meta ?? false;
|
|
6322
|
-
if (combo
|
|
6323
|
-
|
|
6985
|
+
if (combo === "+") {
|
|
6986
|
+
key = "+";
|
|
6987
|
+
} else if (combo.includes("+")) {
|
|
6988
|
+
const literalPlus = combo.endsWith("++");
|
|
6989
|
+
const parts = (literalPlus ? combo.slice(0, -2) : combo).toLowerCase().split("+");
|
|
6990
|
+
if (literalPlus) parts.push("+");
|
|
6324
6991
|
key = parts[parts.length - 1];
|
|
6992
|
+
if (key === "") throw new Error(`hotkey("${combo}"): missing key`);
|
|
6325
6993
|
for (let i2 = 0; i2 < parts.length - 1; i2++) {
|
|
6326
6994
|
const mod = parts[i2];
|
|
6327
6995
|
if (mod === "ctrl" || mod === "control") needCtrl = true;
|
|
6328
6996
|
else if (mod === "shift") needShift = true;
|
|
6329
|
-
else if (mod === "alt") needAlt = true;
|
|
6997
|
+
else if (mod === "alt" || mod === "option") needAlt = true;
|
|
6330
6998
|
else if (mod === "meta" || mod === "cmd" || mod === "command") needMeta = true;
|
|
6999
|
+
else if (mod === "mod") {
|
|
7000
|
+
if (isApplePlatform()) needMeta = true;
|
|
7001
|
+
else needCtrl = true;
|
|
7002
|
+
} else {
|
|
7003
|
+
throw new Error(`hotkey("${combo}"): unknown modifier "${mod}"`);
|
|
7004
|
+
}
|
|
6331
7005
|
}
|
|
6332
7006
|
}
|
|
6333
7007
|
const listener = (e) => {
|
|
@@ -6785,6 +7459,8 @@ function removeGlobalListenerIfIdle() {
|
|
|
6785
7459
|
function dialog() {
|
|
6786
7460
|
const [isOpen, setIsOpen] = signal(false);
|
|
6787
7461
|
const entry = { close: () => close() };
|
|
7462
|
+
let opened = false;
|
|
7463
|
+
let disposed = false;
|
|
6788
7464
|
function pushOnStack() {
|
|
6789
7465
|
if (dialogStack.indexOf(entry) !== -1) return;
|
|
6790
7466
|
dialogStack.push(entry);
|
|
@@ -6796,23 +7472,27 @@ function dialog() {
|
|
|
6796
7472
|
removeGlobalListenerIfIdle();
|
|
6797
7473
|
}
|
|
6798
7474
|
function open() {
|
|
6799
|
-
if (
|
|
6800
|
-
|
|
7475
|
+
if (disposed || opened) return;
|
|
7476
|
+
opened = true;
|
|
6801
7477
|
pushOnStack();
|
|
7478
|
+
setIsOpen(true);
|
|
6802
7479
|
}
|
|
6803
7480
|
function close() {
|
|
6804
|
-
if (!
|
|
7481
|
+
if (!opened) {
|
|
6805
7482
|
removeFromStack();
|
|
6806
7483
|
return;
|
|
6807
7484
|
}
|
|
6808
|
-
|
|
7485
|
+
opened = false;
|
|
6809
7486
|
removeFromStack();
|
|
7487
|
+
setIsOpen(false);
|
|
6810
7488
|
}
|
|
6811
7489
|
function toggle() {
|
|
6812
|
-
if (
|
|
7490
|
+
if (opened) close();
|
|
6813
7491
|
else open();
|
|
6814
7492
|
}
|
|
6815
7493
|
function dispose2() {
|
|
7494
|
+
disposed = true;
|
|
7495
|
+
opened = false;
|
|
6816
7496
|
removeFromStack();
|
|
6817
7497
|
setIsOpen(false);
|
|
6818
7498
|
}
|
|
@@ -7017,32 +7697,49 @@ function pagination(options) {
|
|
|
7017
7697
|
function eventBus() {
|
|
7018
7698
|
const listeners = /* @__PURE__ */ new Map();
|
|
7019
7699
|
function on(event, handler) {
|
|
7020
|
-
let
|
|
7021
|
-
if (!
|
|
7022
|
-
|
|
7023
|
-
listeners.set(event,
|
|
7700
|
+
let subs = listeners.get(event);
|
|
7701
|
+
if (!subs) {
|
|
7702
|
+
subs = /* @__PURE__ */ new Map();
|
|
7703
|
+
listeners.set(event, subs);
|
|
7704
|
+
}
|
|
7705
|
+
let subscription = subs.get(handler);
|
|
7706
|
+
if (!subscription) {
|
|
7707
|
+
subscription = { handler, active: true };
|
|
7708
|
+
subs.set(handler, subscription);
|
|
7024
7709
|
}
|
|
7025
|
-
|
|
7026
|
-
return () =>
|
|
7710
|
+
const own = subscription;
|
|
7711
|
+
return () => {
|
|
7712
|
+
if (listeners.get(event)?.get(handler) !== own) return;
|
|
7713
|
+
off(event, handler);
|
|
7714
|
+
};
|
|
7027
7715
|
}
|
|
7028
7716
|
function emit(event, data2) {
|
|
7029
|
-
const
|
|
7030
|
-
if (
|
|
7031
|
-
|
|
7032
|
-
|
|
7717
|
+
const subs = listeners.get(event);
|
|
7718
|
+
if (!subs || subs.size === 0) return;
|
|
7719
|
+
for (const subscription of Array.from(subs.values())) {
|
|
7720
|
+
if (!subscription.active) continue;
|
|
7721
|
+
try {
|
|
7722
|
+
subscription.handler(data2);
|
|
7723
|
+
} catch (err) {
|
|
7724
|
+
reportError(err, { phase: "event", name: `eventBus(${String(event)})` });
|
|
7033
7725
|
}
|
|
7034
7726
|
}
|
|
7035
7727
|
}
|
|
7036
7728
|
function off(event, handler) {
|
|
7037
|
-
const
|
|
7038
|
-
if (
|
|
7039
|
-
|
|
7040
|
-
|
|
7041
|
-
|
|
7042
|
-
|
|
7729
|
+
const subs = listeners.get(event);
|
|
7730
|
+
if (!subs) return;
|
|
7731
|
+
const subscription = subs.get(handler);
|
|
7732
|
+
if (!subscription) return;
|
|
7733
|
+
subscription.active = false;
|
|
7734
|
+
subs.delete(handler);
|
|
7735
|
+
if (subs.size === 0) {
|
|
7736
|
+
listeners.delete(event);
|
|
7043
7737
|
}
|
|
7044
7738
|
}
|
|
7045
7739
|
function clear() {
|
|
7740
|
+
for (const subs of listeners.values()) {
|
|
7741
|
+
for (const subscription of subs.values()) subscription.active = false;
|
|
7742
|
+
}
|
|
7046
7743
|
listeners.clear();
|
|
7047
7744
|
}
|
|
7048
7745
|
return { on, emit, off, clear };
|
|
@@ -7072,28 +7769,34 @@ function insertTask(task) {
|
|
|
7072
7769
|
}
|
|
7073
7770
|
taskQueue.splice(i2, 0, task);
|
|
7074
7771
|
}
|
|
7772
|
+
function runTask(callback) {
|
|
7773
|
+
try {
|
|
7774
|
+
callback();
|
|
7775
|
+
} catch (err) {
|
|
7776
|
+
reportError(err, { phase: "scheduler", name: "scheduleUpdate" });
|
|
7777
|
+
}
|
|
7778
|
+
}
|
|
7075
7779
|
function processQueue() {
|
|
7076
7780
|
if (_sched.isProcessing || taskQueue.length === 0) return;
|
|
7077
7781
|
_sched.isProcessing = true;
|
|
7078
7782
|
const startTime = performance.now();
|
|
7079
7783
|
const timeSlice = 5;
|
|
7080
|
-
|
|
7081
|
-
|
|
7082
|
-
|
|
7784
|
+
try {
|
|
7785
|
+
while (taskQueue.length > 0) {
|
|
7786
|
+
const task = taskQueue[0];
|
|
7787
|
+
if (task.cancelled) {
|
|
7788
|
+
taskQueue.shift();
|
|
7789
|
+
continue;
|
|
7790
|
+
}
|
|
7791
|
+
if (task.priority > Priority.IMMEDIATE && performance.now() - startTime > timeSlice) {
|
|
7792
|
+
break;
|
|
7793
|
+
}
|
|
7083
7794
|
taskQueue.shift();
|
|
7084
|
-
|
|
7085
|
-
}
|
|
7086
|
-
if (task.priority > Priority.IMMEDIATE && performance.now() - startTime > timeSlice) {
|
|
7087
|
-
break;
|
|
7088
|
-
}
|
|
7089
|
-
taskQueue.shift();
|
|
7090
|
-
try {
|
|
7091
|
-
task.callback();
|
|
7092
|
-
} catch (e) {
|
|
7093
|
-
console.error("[Scheduler] Task error:", e);
|
|
7795
|
+
runTask(task.callback);
|
|
7094
7796
|
}
|
|
7797
|
+
} finally {
|
|
7798
|
+
_sched.isProcessing = false;
|
|
7095
7799
|
}
|
|
7096
|
-
_sched.isProcessing = false;
|
|
7097
7800
|
if (taskQueue.length > 0) {
|
|
7098
7801
|
scheduleFrame();
|
|
7099
7802
|
}
|
|
@@ -7161,11 +7864,7 @@ function scheduleUpdate(priority, callback) {
|
|
|
7161
7864
|
cancelled: false
|
|
7162
7865
|
};
|
|
7163
7866
|
if (priority === Priority.IMMEDIATE) {
|
|
7164
|
-
|
|
7165
|
-
callback();
|
|
7166
|
-
} catch (e) {
|
|
7167
|
-
console.error("[Scheduler] Immediate task error:", e);
|
|
7168
|
-
}
|
|
7867
|
+
runTask(callback);
|
|
7169
7868
|
return () => {
|
|
7170
7869
|
};
|
|
7171
7870
|
}
|
|
@@ -7185,14 +7884,15 @@ function flushScheduler() {
|
|
|
7185
7884
|
_sched.scheduledHandle = null;
|
|
7186
7885
|
_sched.scheduledKind = null;
|
|
7187
7886
|
_sched.microtaskScheduled = false;
|
|
7188
|
-
|
|
7189
|
-
|
|
7190
|
-
|
|
7191
|
-
|
|
7192
|
-
task.callback
|
|
7887
|
+
try {
|
|
7888
|
+
while (taskQueue.length > 0) {
|
|
7889
|
+
const task = taskQueue.shift();
|
|
7890
|
+
if (!task) break;
|
|
7891
|
+
if (!task.cancelled) runTask(task.callback);
|
|
7193
7892
|
}
|
|
7893
|
+
} finally {
|
|
7894
|
+
_sched.isProcessing = false;
|
|
7194
7895
|
}
|
|
7195
|
-
_sched.isProcessing = false;
|
|
7196
7896
|
}
|
|
7197
7897
|
function pendingTasks() {
|
|
7198
7898
|
return taskQueue.filter((t) => !t.cancelled).length;
|
|
@@ -7328,11 +8028,16 @@ function getDOMPool() {
|
|
|
7328
8028
|
return _defaultPool;
|
|
7329
8029
|
}
|
|
7330
8030
|
var preloadedResources = /* @__PURE__ */ new Set();
|
|
8031
|
+
function hintKey(rel, as, crossorigin, href) {
|
|
8032
|
+
return `${rel}\0${as}\0${crossorigin}\0${href}`;
|
|
8033
|
+
}
|
|
7331
8034
|
function preloadResource(url, type = "fetch") {
|
|
7332
8035
|
const safe = sanitizeUrl(url);
|
|
7333
8036
|
if (!safe) return;
|
|
7334
|
-
|
|
7335
|
-
|
|
8037
|
+
const as = type === "script" || type === "style" || type === "image" ? type : "fetch";
|
|
8038
|
+
const key = hintKey("preload", as, as === "fetch" ? "anonymous" : "", safe);
|
|
8039
|
+
if (preloadedResources.has(key)) return;
|
|
8040
|
+
preloadedResources.add(key);
|
|
7336
8041
|
const link2 = document.createElement("link");
|
|
7337
8042
|
link2.rel = "preload";
|
|
7338
8043
|
link2.href = safe;
|
|
@@ -7355,8 +8060,9 @@ function preloadResource(url, type = "fetch") {
|
|
|
7355
8060
|
function prefetch(url) {
|
|
7356
8061
|
const safe = sanitizeUrl(url);
|
|
7357
8062
|
if (!safe) return;
|
|
7358
|
-
|
|
7359
|
-
preloadedResources.
|
|
8063
|
+
const key = hintKey("prefetch", "", "", safe);
|
|
8064
|
+
if (preloadedResources.has(key)) return;
|
|
8065
|
+
preloadedResources.add(key);
|
|
7360
8066
|
const link2 = document.createElement("link");
|
|
7361
8067
|
link2.rel = "prefetch";
|
|
7362
8068
|
link2.href = safe;
|
|
@@ -7821,7 +8527,7 @@ function renderToDocument(component, options = {}) {
|
|
|
7821
8527
|
<head>
|
|
7822
8528
|
<meta charset="UTF-8" />
|
|
7823
8529
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7824
|
-
${options.title ? `<title>${escapeHtml(options.title)}</title>` : ""}
|
|
8530
|
+
${options.title != null ? `<title>${escapeHtml(options.title)}</title>` : ""}
|
|
7825
8531
|
${metaTags}
|
|
7826
8532
|
${linkTags}
|
|
7827
8533
|
${options.headExtra || ""}
|
|
@@ -7996,16 +8702,32 @@ function ssrSuspense(props) {
|
|
|
7996
8702
|
const timeoutPromise = new Promise((_, reject) => {
|
|
7997
8703
|
timer = setTimeout(() => reject(new Error(`[SibuJS SSR] ssrSuspense timed out after ${timeoutMs}ms`)), timeoutMs);
|
|
7998
8704
|
});
|
|
7999
|
-
|
|
8705
|
+
let contentPromise;
|
|
8706
|
+
try {
|
|
8707
|
+
contentPromise = Promise.resolve(props.content());
|
|
8708
|
+
} catch (err) {
|
|
8709
|
+
contentPromise = Promise.reject(err);
|
|
8710
|
+
}
|
|
8711
|
+
const toFallback = (err) => {
|
|
8712
|
+
if (DEV) console.warn("[SibuJS SSR] ssrSuspense rejected:", err);
|
|
8713
|
+
return { id, html: fallbackHtml };
|
|
8714
|
+
};
|
|
8715
|
+
const clearTimer = () => {
|
|
8716
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
8717
|
+
};
|
|
8718
|
+
const raced = Promise.race([contentPromise, timeoutPromise]);
|
|
8000
8719
|
const promise = raced.then(
|
|
8001
8720
|
(resolvedEl) => {
|
|
8002
|
-
|
|
8003
|
-
|
|
8721
|
+
clearTimer();
|
|
8722
|
+
try {
|
|
8723
|
+
return { id, html: renderToString(resolvedEl) };
|
|
8724
|
+
} catch (err) {
|
|
8725
|
+
return toFallback(err);
|
|
8726
|
+
}
|
|
8004
8727
|
},
|
|
8005
8728
|
(err) => {
|
|
8006
|
-
|
|
8007
|
-
|
|
8008
|
-
return { id, html: fallbackHtml };
|
|
8729
|
+
clearTimer();
|
|
8730
|
+
return toFallback(err);
|
|
8009
8731
|
}
|
|
8010
8732
|
);
|
|
8011
8733
|
promise.catch(noop);
|
|
@@ -8094,65 +8816,92 @@ function block(factory) {
|
|
|
8094
8816
|
}
|
|
8095
8817
|
|
|
8096
8818
|
// src/performance/normalize.ts
|
|
8819
|
+
function dict(source2) {
|
|
8820
|
+
const out = /* @__PURE__ */ Object.create(null);
|
|
8821
|
+
if (source2) {
|
|
8822
|
+
for (const key of Object.keys(source2)) defineOwn(out, key, source2[key]);
|
|
8823
|
+
}
|
|
8824
|
+
return out;
|
|
8825
|
+
}
|
|
8826
|
+
function ownGet(obj, key) {
|
|
8827
|
+
return obj !== void 0 && Object.hasOwn(obj, key) ? obj[key] : void 0;
|
|
8828
|
+
}
|
|
8829
|
+
function defineOwn(obj, key, value) {
|
|
8830
|
+
Object.defineProperty(obj, key, { value, writable: true, enumerable: true, configurable: true });
|
|
8831
|
+
}
|
|
8832
|
+
function readEntityId(entity, idKey, typeName) {
|
|
8833
|
+
const raw = entity !== null && typeof entity === "object" && Object.hasOwn(entity, idKey) ? entity[idKey] : void 0;
|
|
8834
|
+
if (typeof raw === "string") return raw;
|
|
8835
|
+
if (typeof raw === "number" && Number.isFinite(raw)) return String(raw);
|
|
8836
|
+
throw new TypeError(
|
|
8837
|
+
`[normalize] "${typeName}" entity has no valid "${idKey}" (expected a string or finite number, got ${raw === null ? "null" : typeof raw})`
|
|
8838
|
+
);
|
|
8839
|
+
}
|
|
8097
8840
|
function normalizedStore(schema) {
|
|
8098
8841
|
const idKey = schema.idKey || "id";
|
|
8099
8842
|
const [getState, setState] = signal({
|
|
8100
8843
|
ids: [],
|
|
8101
|
-
entities:
|
|
8844
|
+
entities: dict()
|
|
8102
8845
|
});
|
|
8103
|
-
const idOf = (entity) =>
|
|
8846
|
+
const idOf = (entity) => readEntityId(entity, idKey, schema.name);
|
|
8104
8847
|
function add(entity) {
|
|
8105
8848
|
const id = idOf(entity);
|
|
8106
8849
|
setState((prev) => {
|
|
8107
|
-
const ids = prev.
|
|
8108
|
-
|
|
8109
|
-
|
|
8110
|
-
|
|
8111
|
-
};
|
|
8850
|
+
const ids = Object.hasOwn(prev.entities, id) ? prev.ids : [...prev.ids, id];
|
|
8851
|
+
const entities = dict(prev.entities);
|
|
8852
|
+
defineOwn(entities, id, entity);
|
|
8853
|
+
return { ids, entities };
|
|
8112
8854
|
});
|
|
8113
8855
|
}
|
|
8114
8856
|
function addMany(entities) {
|
|
8857
|
+
const ids = entities.map(idOf);
|
|
8115
8858
|
setState((prev) => {
|
|
8116
8859
|
const nextIds = [...prev.ids];
|
|
8117
|
-
const nextEntities =
|
|
8118
|
-
|
|
8119
|
-
const id =
|
|
8120
|
-
if (!
|
|
8860
|
+
const nextEntities = dict(prev.entities);
|
|
8861
|
+
entities.forEach((entity, i2) => {
|
|
8862
|
+
const id = ids[i2];
|
|
8863
|
+
if (!Object.hasOwn(nextEntities, id)) {
|
|
8121
8864
|
nextIds.push(id);
|
|
8122
8865
|
}
|
|
8123
|
-
nextEntities
|
|
8124
|
-
}
|
|
8866
|
+
defineOwn(nextEntities, id, entity);
|
|
8867
|
+
});
|
|
8125
8868
|
return { ids: nextIds, entities: nextEntities };
|
|
8126
8869
|
});
|
|
8127
8870
|
}
|
|
8128
8871
|
function get(id) {
|
|
8129
|
-
|
|
8130
|
-
return state2.entities[id];
|
|
8872
|
+
return ownGet(getState().entities, id);
|
|
8131
8873
|
}
|
|
8132
8874
|
function getAll() {
|
|
8133
8875
|
const state2 = getState();
|
|
8134
8876
|
return state2.ids.map((id) => state2.entities[id]);
|
|
8135
8877
|
}
|
|
8136
8878
|
function update(id, partial) {
|
|
8137
|
-
|
|
8138
|
-
|
|
8139
|
-
|
|
8140
|
-
|
|
8141
|
-
|
|
8142
|
-
|
|
8143
|
-
|
|
8144
|
-
|
|
8145
|
-
|
|
8146
|
-
|
|
8879
|
+
const prev = getState();
|
|
8880
|
+
if (!Object.hasOwn(prev.entities, id)) return;
|
|
8881
|
+
if (partial !== null && typeof partial === "object" && Object.hasOwn(partial, idKey)) {
|
|
8882
|
+
const nextId = readEntityId(partial, idKey, schema.name);
|
|
8883
|
+
if (nextId !== id) {
|
|
8884
|
+
throw new Error(
|
|
8885
|
+
`[normalizedStore] update("${id}") cannot change "${idKey}" to "${nextId}"; remove and re-add the entity instead.`
|
|
8886
|
+
);
|
|
8887
|
+
}
|
|
8888
|
+
}
|
|
8889
|
+
setState((current) => {
|
|
8890
|
+
const existing = ownGet(current.entities, id);
|
|
8891
|
+
if (!existing) return current;
|
|
8892
|
+
const entities = dict(current.entities);
|
|
8893
|
+
defineOwn(entities, id, { ...existing, ...partial });
|
|
8894
|
+
return { ids: current.ids, entities };
|
|
8147
8895
|
});
|
|
8148
8896
|
}
|
|
8149
8897
|
function remove(id) {
|
|
8150
8898
|
setState((prev) => {
|
|
8151
|
-
if (!prev.entities
|
|
8152
|
-
const
|
|
8899
|
+
if (!Object.hasOwn(prev.entities, id)) return prev;
|
|
8900
|
+
const entities = dict(prev.entities);
|
|
8901
|
+
delete entities[id];
|
|
8153
8902
|
return {
|
|
8154
8903
|
ids: prev.ids.filter((existingId) => existingId !== id),
|
|
8155
|
-
entities
|
|
8904
|
+
entities
|
|
8156
8905
|
};
|
|
8157
8906
|
});
|
|
8158
8907
|
}
|
|
@@ -8163,31 +8912,37 @@ function normalizedStore(schema) {
|
|
|
8163
8912
|
return { add, addMany, get, getAll, update, remove, select: select3, getState };
|
|
8164
8913
|
}
|
|
8165
8914
|
function normalize(data2, schema) {
|
|
8166
|
-
const entities =
|
|
8915
|
+
const entities = dict();
|
|
8167
8916
|
function ensureTable(name) {
|
|
8168
|
-
|
|
8169
|
-
|
|
8917
|
+
let table2 = ownGet(entities, name);
|
|
8918
|
+
if (!table2) {
|
|
8919
|
+
table2 = dict();
|
|
8920
|
+
defineOwn(entities, name, table2);
|
|
8170
8921
|
}
|
|
8171
|
-
return
|
|
8922
|
+
return table2;
|
|
8172
8923
|
}
|
|
8173
8924
|
function normalizeEntity(entity, entitySchema) {
|
|
8174
8925
|
const entityIdKey = entitySchema.idKey || "id";
|
|
8175
|
-
const id =
|
|
8926
|
+
const id = readEntityId(entity, entityIdKey, entitySchema.name);
|
|
8176
8927
|
const table2 = ensureTable(entitySchema.name);
|
|
8177
8928
|
const flat = { ...entity };
|
|
8178
8929
|
if (entitySchema.relations) {
|
|
8179
8930
|
for (const [field, relationType] of Object.entries(entitySchema.relations)) {
|
|
8180
|
-
const value = entity[field];
|
|
8931
|
+
const value = Object.hasOwn(entity, field) ? entity[field] : void 0;
|
|
8181
8932
|
if (value == null) continue;
|
|
8182
8933
|
const relSchema = { name: relationType };
|
|
8183
8934
|
if (Array.isArray(value)) {
|
|
8184
|
-
|
|
8935
|
+
defineOwn(
|
|
8936
|
+
flat,
|
|
8937
|
+
field,
|
|
8938
|
+
value.map((item) => normalizeEntity(item, relSchema))
|
|
8939
|
+
);
|
|
8185
8940
|
} else if (typeof value === "object") {
|
|
8186
|
-
flat
|
|
8941
|
+
defineOwn(flat, field, normalizeEntity(value, relSchema));
|
|
8187
8942
|
}
|
|
8188
8943
|
}
|
|
8189
8944
|
}
|
|
8190
|
-
table2
|
|
8945
|
+
defineOwn(table2, id, flat);
|
|
8191
8946
|
return id;
|
|
8192
8947
|
}
|
|
8193
8948
|
if (Array.isArray(data2)) {
|
|
@@ -8198,20 +8953,24 @@ function normalize(data2, schema) {
|
|
|
8198
8953
|
return { result, entities };
|
|
8199
8954
|
}
|
|
8200
8955
|
function denormalize(id, entities, schema) {
|
|
8201
|
-
const table2 = entities
|
|
8956
|
+
const table2 = ownGet(entities, schema.name);
|
|
8202
8957
|
if (!table2) return void 0;
|
|
8203
|
-
const entity = table2
|
|
8958
|
+
const entity = ownGet(table2, id);
|
|
8204
8959
|
if (!entity) return void 0;
|
|
8205
8960
|
const result = { ...entity };
|
|
8206
8961
|
if (schema.relations) {
|
|
8207
8962
|
for (const [field, relationType] of Object.entries(schema.relations)) {
|
|
8208
|
-
const value = entity
|
|
8963
|
+
const value = ownGet(entity, field);
|
|
8209
8964
|
if (value == null) continue;
|
|
8210
8965
|
const relSchema = { name: relationType };
|
|
8211
8966
|
if (Array.isArray(value)) {
|
|
8212
|
-
|
|
8967
|
+
defineOwn(
|
|
8968
|
+
result,
|
|
8969
|
+
field,
|
|
8970
|
+
value.map((relId) => denormalize(relId, entities, relSchema))
|
|
8971
|
+
);
|
|
8213
8972
|
} else if (typeof value === "string") {
|
|
8214
|
-
result
|
|
8973
|
+
defineOwn(result, field, denormalize(value, entities, relSchema));
|
|
8215
8974
|
}
|
|
8216
8975
|
}
|
|
8217
8976
|
}
|
|
@@ -8421,13 +9180,24 @@ function lazyChunk(id, loader, registry, fallback) {
|
|
|
8421
9180
|
if (fallback) {
|
|
8422
9181
|
container.appendChild(fallback());
|
|
8423
9182
|
}
|
|
9183
|
+
let disposed = false;
|
|
9184
|
+
registerDisposer(container, () => {
|
|
9185
|
+
disposed = true;
|
|
9186
|
+
});
|
|
8424
9187
|
registry.load(id, async () => {
|
|
8425
9188
|
const mod = await loader();
|
|
8426
9189
|
return typeof mod === "function" ? mod : mod.default;
|
|
8427
9190
|
}).then((component) => {
|
|
9191
|
+
if (disposed) return;
|
|
9192
|
+
const node = component();
|
|
9193
|
+
if (disposed) {
|
|
9194
|
+
dispose(node);
|
|
9195
|
+
return;
|
|
9196
|
+
}
|
|
8428
9197
|
clearChildren(container);
|
|
8429
|
-
container.appendChild(
|
|
9198
|
+
container.appendChild(node);
|
|
8430
9199
|
}).catch((err) => {
|
|
9200
|
+
if (disposed) return;
|
|
8431
9201
|
clearChildren(container);
|
|
8432
9202
|
const errorEl = document.createElement("div");
|
|
8433
9203
|
errorEl.textContent = `Failed to load chunk '${id}': ${err.message}`;
|
|
@@ -8518,7 +9288,7 @@ function Head(props) {
|
|
|
8518
9288
|
};
|
|
8519
9289
|
const apply = () => {
|
|
8520
9290
|
cleanup3();
|
|
8521
|
-
if (props.title) {
|
|
9291
|
+
if (props.title != null) {
|
|
8522
9292
|
if (typeof props.title === "function") {
|
|
8523
9293
|
const getter = props.title;
|
|
8524
9294
|
let lease = null;
|
|
@@ -8573,13 +9343,14 @@ function Head(props) {
|
|
|
8573
9343
|
return anchor;
|
|
8574
9344
|
}
|
|
8575
9345
|
function setStructuredData(data2) {
|
|
8576
|
-
const
|
|
8577
|
-
if (existing) existing.remove();
|
|
9346
|
+
const json = escapeScriptJsonLocal(JSON.stringify(data2));
|
|
8578
9347
|
const script2 = document.createElement("script");
|
|
8579
9348
|
script2.type = "application/ld+json";
|
|
8580
9349
|
script2.setAttribute("data-sibu", "true");
|
|
8581
|
-
script2.textContent =
|
|
8582
|
-
document.head.
|
|
9350
|
+
script2.textContent = json;
|
|
9351
|
+
const existing = document.head.querySelector('script[type="application/ld+json"][data-sibu]');
|
|
9352
|
+
if (existing) existing.replaceWith(script2);
|
|
9353
|
+
else document.head.appendChild(script2);
|
|
8583
9354
|
}
|
|
8584
9355
|
function setCanonical(url) {
|
|
8585
9356
|
let link2 = document.head.querySelector('link[rel="canonical"]');
|
|
@@ -8595,13 +9366,33 @@ function setCanonical(url) {
|
|
|
8595
9366
|
|
|
8596
9367
|
// src/platform/customElement.ts
|
|
8597
9368
|
var SVG_NS2 = "http://www.w3.org/2000/svg";
|
|
9369
|
+
var MAX_RENDER_PASSES = 10;
|
|
9370
|
+
var ABANDONED_RENDER = /* @__PURE__ */ Symbol("sibujs.defineElement.abandonedRender");
|
|
8598
9371
|
function defineElement(name, component, options = {}) {
|
|
8599
9372
|
if (customElements.get(name)) return;
|
|
8600
9373
|
const observed = options.observedAttributes || [];
|
|
8601
9374
|
class SibuElement extends HTMLElement {
|
|
8602
9375
|
constructor() {
|
|
8603
9376
|
super();
|
|
8604
|
-
|
|
9377
|
+
// Re-rendering is keyed on connection, not on a previous render: a first render
|
|
9378
|
+
// that throws leaves nothing rendered, and the element must still re-render
|
|
9379
|
+
// when a later attribute change fixes the input.
|
|
9380
|
+
this._connected = false;
|
|
9381
|
+
// A render in progress, and whether an attribute changed during it. The
|
|
9382
|
+
// component may write its host's observed attributes while rendering; with
|
|
9383
|
+
// the old subtree kept during the build, rendering again from inside the
|
|
9384
|
+
// callback recursed until the stack overflowed.
|
|
9385
|
+
this._rendering = false;
|
|
9386
|
+
this._dirty = false;
|
|
9387
|
+
// How many teardowns are draining. A host teardown may reconnect the element
|
|
9388
|
+
// (and a nested disconnect may run inside it), and rendering the next
|
|
9389
|
+
// generation from inside that drain would let the drain tear down what the
|
|
9390
|
+
// new render registers. A counter, not a flag: a nested teardown returning
|
|
9391
|
+
// must not declare the outer one finished.
|
|
9392
|
+
this._teardownDepth = 0;
|
|
9393
|
+
// Disconnects so far. A render compares it across its old-subtree teardown
|
|
9394
|
+
// to detect a disconnect that happened inside it.
|
|
9395
|
+
this._disconnects = 0;
|
|
8605
9396
|
if (options.shadow !== false) {
|
|
8606
9397
|
this._root = this.attachShadow({ mode: options.mode || "open" });
|
|
8607
9398
|
} else {
|
|
@@ -8611,32 +9402,106 @@ function defineElement(name, component, options = {}) {
|
|
|
8611
9402
|
static get observedAttributes() {
|
|
8612
9403
|
return observed;
|
|
8613
9404
|
}
|
|
9405
|
+
/** Whether rendering must wait for work already in progress. */
|
|
9406
|
+
get _busy() {
|
|
9407
|
+
return this._rendering || this._teardownDepth > 0;
|
|
9408
|
+
}
|
|
8614
9409
|
connectedCallback() {
|
|
9410
|
+
this._connected = true;
|
|
9411
|
+
if (this._busy) {
|
|
9412
|
+
this._dirty = true;
|
|
9413
|
+
return;
|
|
9414
|
+
}
|
|
8615
9415
|
this._render();
|
|
8616
9416
|
}
|
|
8617
9417
|
disconnectedCallback() {
|
|
8618
|
-
this.
|
|
9418
|
+
this._connected = false;
|
|
9419
|
+
this._disconnects++;
|
|
9420
|
+
this._teardownDepth++;
|
|
9421
|
+
try {
|
|
9422
|
+
this._teardown();
|
|
9423
|
+
} finally {
|
|
9424
|
+
this._teardownDepth--;
|
|
9425
|
+
if (this._teardownDepth === 0 && this._connected && this._dirty) {
|
|
9426
|
+
this._dirty = false;
|
|
9427
|
+
if (!this._rendering) this._render();
|
|
9428
|
+
}
|
|
9429
|
+
}
|
|
8619
9430
|
}
|
|
8620
|
-
attributeChangedCallback() {
|
|
8621
|
-
if (this.
|
|
8622
|
-
|
|
9431
|
+
attributeChangedCallback(_name, oldValue, newValue) {
|
|
9432
|
+
if (oldValue === newValue || !this._connected) return;
|
|
9433
|
+
if (this._busy) {
|
|
9434
|
+
this._dirty = true;
|
|
9435
|
+
return;
|
|
8623
9436
|
}
|
|
9437
|
+
this._render();
|
|
8624
9438
|
}
|
|
8625
9439
|
_teardown() {
|
|
8626
|
-
this._rendered = null;
|
|
8627
9440
|
replaceChildrenSafely(this._root);
|
|
9441
|
+
disposeNodeOwn(this);
|
|
8628
9442
|
}
|
|
9443
|
+
/**
|
|
9444
|
+
* Render as a transaction: build the replacement first, commit only if that
|
|
9445
|
+
* succeeds. Tearing the current subtree down before calling the factory
|
|
9446
|
+
* meant a throwing rerender (an invalid attribute, say) left the element
|
|
9447
|
+
* blank with its live state already disposed. Now a failure keeps the
|
|
9448
|
+
* working subtree, releases whatever the failed attempt registered, and is
|
|
9449
|
+
* reported with this element as its node so an enclosing ErrorBoundary can
|
|
9450
|
+
* claim it.
|
|
9451
|
+
*/
|
|
8629
9452
|
_render() {
|
|
8630
|
-
this.
|
|
9453
|
+
this._rendering = true;
|
|
9454
|
+
try {
|
|
9455
|
+
let passes = 0;
|
|
9456
|
+
do {
|
|
9457
|
+
this._dirty = false;
|
|
9458
|
+
if (++passes > MAX_RENDER_PASSES) {
|
|
9459
|
+
reportError(
|
|
9460
|
+
new Error(
|
|
9461
|
+
`[SibuJS] defineElement(${name}): the component changed its own observed attributes on ${MAX_RENDER_PASSES} consecutive renders; stopped re-rendering.`
|
|
9462
|
+
),
|
|
9463
|
+
{ phase: "render", name: `defineElement(${name})`, node: this }
|
|
9464
|
+
);
|
|
9465
|
+
break;
|
|
9466
|
+
}
|
|
9467
|
+
this._renderOnce();
|
|
9468
|
+
} while (this._dirty && this._connected);
|
|
9469
|
+
} finally {
|
|
9470
|
+
this._rendering = false;
|
|
9471
|
+
this._dirty = false;
|
|
9472
|
+
}
|
|
9473
|
+
}
|
|
9474
|
+
_renderOnce() {
|
|
8631
9475
|
const props = this._getProps();
|
|
9476
|
+
let el;
|
|
9477
|
+
try {
|
|
9478
|
+
el = withDisposerRollback(() => {
|
|
9479
|
+
const built = component(props, this);
|
|
9480
|
+
if (!this._connected) throw ABANDONED_RENDER;
|
|
9481
|
+
return built;
|
|
9482
|
+
});
|
|
9483
|
+
} catch (err) {
|
|
9484
|
+
if (err !== ABANDONED_RENDER) {
|
|
9485
|
+
reportError(err, { phase: "render", name: `defineElement(${name})`, node: this });
|
|
9486
|
+
}
|
|
9487
|
+
return;
|
|
9488
|
+
}
|
|
9489
|
+
const next = [];
|
|
8632
9490
|
if (options.styles && this._root instanceof ShadowRoot) {
|
|
8633
9491
|
const styleEl = document.createElement("style");
|
|
8634
9492
|
styleEl.textContent = options.styles;
|
|
8635
|
-
|
|
9493
|
+
next.push(styleEl);
|
|
9494
|
+
}
|
|
9495
|
+
next.push(el);
|
|
9496
|
+
const disconnects = this._disconnects;
|
|
9497
|
+
for (const node of next) node.parentNode?.removeChild(node);
|
|
9498
|
+
replaceChildrenSafely(this._root);
|
|
9499
|
+
if (this._disconnects !== disconnects) {
|
|
9500
|
+
for (const node of next) dispose(node);
|
|
9501
|
+
if (this._connected) this._dirty = true;
|
|
9502
|
+
return;
|
|
8636
9503
|
}
|
|
8637
|
-
|
|
8638
|
-
this._root.appendChild(el);
|
|
8639
|
-
this._rendered = el;
|
|
9504
|
+
this._root.replaceChildren(...next);
|
|
8640
9505
|
}
|
|
8641
9506
|
_getProps() {
|
|
8642
9507
|
const props = {};
|
|
@@ -8669,6 +9534,11 @@ function svgElement(tag, props = {}, ...nodes) {
|
|
|
8669
9534
|
}
|
|
8670
9535
|
|
|
8671
9536
|
// src/platform/worker.ts
|
|
9537
|
+
function toError(err) {
|
|
9538
|
+
if (err instanceof Error) return err;
|
|
9539
|
+
if (err !== null && typeof err === "object" && "name" in err && "message" in err) return err;
|
|
9540
|
+
return new Error(String(err));
|
|
9541
|
+
}
|
|
8672
9542
|
function worker(workerFn2) {
|
|
8673
9543
|
const [result, setResult] = signal(null);
|
|
8674
9544
|
const [error, setError] = signal(null);
|
|
@@ -8691,8 +9561,11 @@ function worker(workerFn2) {
|
|
|
8691
9561
|
worker2 = new Worker(blobUrl);
|
|
8692
9562
|
worker2.addEventListener("message", (e) => {
|
|
8693
9563
|
revokeBlobUrl();
|
|
8694
|
-
|
|
8695
|
-
|
|
9564
|
+
batch(() => {
|
|
9565
|
+
setResult(e.data);
|
|
9566
|
+
setError(null);
|
|
9567
|
+
setLoading(false);
|
|
9568
|
+
});
|
|
8696
9569
|
});
|
|
8697
9570
|
worker2.addEventListener("error", (e) => {
|
|
8698
9571
|
revokeBlobUrl();
|
|
@@ -8709,10 +9582,17 @@ function worker(workerFn2) {
|
|
|
8709
9582
|
}
|
|
8710
9583
|
function post(data2) {
|
|
8711
9584
|
if (!worker2) return;
|
|
8712
|
-
|
|
8713
|
-
|
|
8714
|
-
|
|
8715
|
-
|
|
9585
|
+
try {
|
|
9586
|
+
worker2.postMessage(data2);
|
|
9587
|
+
} catch (err) {
|
|
9588
|
+
setError(toError(err));
|
|
9589
|
+
return;
|
|
9590
|
+
}
|
|
9591
|
+
batch(() => {
|
|
9592
|
+
setLoading(true);
|
|
9593
|
+
setError(null);
|
|
9594
|
+
setResult(null);
|
|
9595
|
+
});
|
|
8716
9596
|
}
|
|
8717
9597
|
function terminate() {
|
|
8718
9598
|
if (!worker2) return;
|
|
@@ -8776,9 +9656,14 @@ function workerFn(fn) {
|
|
|
8776
9656
|
reject(new Error("Worker is not available"));
|
|
8777
9657
|
return;
|
|
8778
9658
|
}
|
|
8779
|
-
|
|
9659
|
+
try {
|
|
9660
|
+
worker2.postMessage(args);
|
|
9661
|
+
} catch (err) {
|
|
9662
|
+
reject(toError(err));
|
|
9663
|
+
return;
|
|
9664
|
+
}
|
|
8780
9665
|
queue.push({ resolve, reject });
|
|
8781
|
-
|
|
9666
|
+
setLoading(true);
|
|
8782
9667
|
});
|
|
8783
9668
|
}
|
|
8784
9669
|
function terminate() {
|
|
@@ -8808,7 +9693,11 @@ function createWorkerPool(workerFn2, poolSize) {
|
|
|
8808
9693
|
}
|
|
8809
9694
|
};
|
|
8810
9695
|
function dispatchNext(idx) {
|
|
8811
|
-
|
|
9696
|
+
while (alive && !inflight[idx] && queues[idx].length > 0) {
|
|
9697
|
+
dispatchOne(idx);
|
|
9698
|
+
}
|
|
9699
|
+
}
|
|
9700
|
+
function dispatchOne(idx) {
|
|
8812
9701
|
const w = workers[idx];
|
|
8813
9702
|
const slot2 = queues[idx].shift();
|
|
8814
9703
|
const onMsg = (e) => {
|
|
@@ -8833,10 +9722,15 @@ function createWorkerPool(workerFn2, poolSize) {
|
|
|
8833
9722
|
slot2.reject(new Error(e.message || "Worker error"));
|
|
8834
9723
|
dispatchNext(idx);
|
|
8835
9724
|
};
|
|
9725
|
+
try {
|
|
9726
|
+
w.postMessage(slot2.data);
|
|
9727
|
+
} catch (err) {
|
|
9728
|
+
slot2.reject(toError(err));
|
|
9729
|
+
return;
|
|
9730
|
+
}
|
|
8836
9731
|
inflight[idx] = { ...slot2, onMsg, onErr };
|
|
8837
9732
|
w.addEventListener("message", onMsg);
|
|
8838
9733
|
w.addEventListener("error", onErr);
|
|
8839
|
-
w.postMessage(slot2.data);
|
|
8840
9734
|
}
|
|
8841
9735
|
try {
|
|
8842
9736
|
if (typeof Worker === "undefined") {
|
|
@@ -9723,13 +10617,13 @@ function createSharedScope(initialState) {
|
|
|
9723
10617
|
for (const key of Object.keys(initialState)) {
|
|
9724
10618
|
const [get2, set2] = signal(initialState[key]);
|
|
9725
10619
|
signals.set(key, { get: get2, set: set2 });
|
|
9726
|
-
subscribers.set(key, /* @__PURE__ */ new
|
|
10620
|
+
subscribers.set(key, /* @__PURE__ */ new Map());
|
|
9727
10621
|
}
|
|
9728
10622
|
function ensureSignal(key) {
|
|
9729
10623
|
if (!signals.has(key)) {
|
|
9730
10624
|
const [get2, set2] = signal(void 0);
|
|
9731
10625
|
signals.set(key, { get: get2, set: set2 });
|
|
9732
|
-
subscribers.set(key, /* @__PURE__ */ new
|
|
10626
|
+
subscribers.set(key, /* @__PURE__ */ new Map());
|
|
9733
10627
|
}
|
|
9734
10628
|
}
|
|
9735
10629
|
function get(key) {
|
|
@@ -9740,9 +10634,14 @@ function createSharedScope(initialState) {
|
|
|
9740
10634
|
ensureSignal(key);
|
|
9741
10635
|
signals.get(key)?.set(value);
|
|
9742
10636
|
const subs = subscribers.get(key);
|
|
9743
|
-
if (subs) {
|
|
9744
|
-
for (const
|
|
9745
|
-
|
|
10637
|
+
if (subs && subs.size > 0) {
|
|
10638
|
+
for (const subscription of Array.from(subs.values())) {
|
|
10639
|
+
if (!subscription.active) continue;
|
|
10640
|
+
try {
|
|
10641
|
+
subscription.callback(value);
|
|
10642
|
+
} catch (err) {
|
|
10643
|
+
reportError(err, { phase: "event", name: `sharedScope(${String(key)})` });
|
|
10644
|
+
}
|
|
9746
10645
|
}
|
|
9747
10646
|
}
|
|
9748
10647
|
}
|
|
@@ -9753,9 +10652,17 @@ function createSharedScope(initialState) {
|
|
|
9753
10652
|
return () => {
|
|
9754
10653
|
};
|
|
9755
10654
|
}
|
|
9756
|
-
|
|
10655
|
+
const cb = callback;
|
|
10656
|
+
let subscription = subs.get(cb);
|
|
10657
|
+
if (!subscription) {
|
|
10658
|
+
subscription = { callback: cb, active: true };
|
|
10659
|
+
subs.set(cb, subscription);
|
|
10660
|
+
}
|
|
10661
|
+
const own = subscription;
|
|
9757
10662
|
return () => {
|
|
9758
|
-
subs.
|
|
10663
|
+
if (subs.get(cb) !== own) return;
|
|
10664
|
+
own.active = false;
|
|
10665
|
+
subs.delete(cb);
|
|
9759
10666
|
};
|
|
9760
10667
|
}
|
|
9761
10668
|
return { get, set, subscribe };
|
|
@@ -9822,7 +10729,7 @@ function serviceWorker(scriptUrl, options) {
|
|
|
9822
10729
|
arrivedRegistration = null;
|
|
9823
10730
|
}
|
|
9824
10731
|
}
|
|
9825
|
-
function
|
|
10732
|
+
function adopt2(reg) {
|
|
9826
10733
|
if (unregisterRequested) {
|
|
9827
10734
|
arrivedRegistration = reg;
|
|
9828
10735
|
return null;
|
|
@@ -9831,7 +10738,7 @@ function serviceWorker(scriptUrl, options) {
|
|
|
9831
10738
|
return reg;
|
|
9832
10739
|
}
|
|
9833
10740
|
if (supported) {
|
|
9834
|
-
registrationPromise = navigator.serviceWorker.register(scriptUrl, options).then(
|
|
10741
|
+
registrationPromise = navigator.serviceWorker.register(scriptUrl, options).then(adopt2).catch((err) => {
|
|
9835
10742
|
if (!unregistered) {
|
|
9836
10743
|
setError(err instanceof Error ? err : new Error(String(err)));
|
|
9837
10744
|
}
|
|
@@ -9907,15 +10814,31 @@ async function generateStaticSite(options) {
|
|
|
9907
10814
|
// src/platform/incrementalRegeneration.ts
|
|
9908
10815
|
function createISR(options) {
|
|
9909
10816
|
const { revalidateAfter, fetcher, initialData } = options;
|
|
10817
|
+
if (!Number.isFinite(revalidateAfter) || revalidateAfter <= 0) {
|
|
10818
|
+
throw new RangeError(`[SibuJS ISR] revalidateAfter must be a positive finite number, got ${revalidateAfter}`);
|
|
10819
|
+
}
|
|
9910
10820
|
const [data2, setData] = signal(initialData);
|
|
9911
|
-
const [
|
|
10821
|
+
const [stale, setStale] = signal(initialData === void 0);
|
|
9912
10822
|
const controller = new AbortController();
|
|
9913
10823
|
let inFlight = false;
|
|
9914
10824
|
let disposed = false;
|
|
9915
|
-
|
|
9916
|
-
|
|
9917
|
-
if (
|
|
9918
|
-
|
|
10825
|
+
let deadline;
|
|
10826
|
+
const clearDeadline = () => {
|
|
10827
|
+
if (deadline !== void 0) {
|
|
10828
|
+
clearTimeout(deadline);
|
|
10829
|
+
deadline = void 0;
|
|
10830
|
+
}
|
|
10831
|
+
};
|
|
10832
|
+
const armDeadline = () => {
|
|
10833
|
+
clearDeadline();
|
|
10834
|
+
deadline = setTimeout(() => {
|
|
10835
|
+
deadline = void 0;
|
|
10836
|
+
if (disposed) return;
|
|
10837
|
+
setStale(true);
|
|
10838
|
+
revalidate().catch((err) => {
|
|
10839
|
+
if (typeof console !== "undefined") console.warn("[SibuJS ISR] revalidate failed", err);
|
|
10840
|
+
});
|
|
10841
|
+
}, revalidateAfter);
|
|
9919
10842
|
};
|
|
9920
10843
|
const revalidate = async () => {
|
|
9921
10844
|
if (disposed || inFlight) return;
|
|
@@ -9924,8 +10847,14 @@ function createISR(options) {
|
|
|
9924
10847
|
try {
|
|
9925
10848
|
const result = await fetcher({ signal: controller.signal });
|
|
9926
10849
|
if (disposed || controller.signal.aborted) return;
|
|
9927
|
-
|
|
9928
|
-
|
|
10850
|
+
batch(() => {
|
|
10851
|
+
setData(result);
|
|
10852
|
+
setStale(false);
|
|
10853
|
+
});
|
|
10854
|
+
armDeadline();
|
|
10855
|
+
} catch (err) {
|
|
10856
|
+
if (!disposed && !controller.signal.aborted) armDeadline();
|
|
10857
|
+
throw err;
|
|
9929
10858
|
} finally {
|
|
9930
10859
|
inFlight = false;
|
|
9931
10860
|
}
|
|
@@ -9934,19 +10863,16 @@ function createISR(options) {
|
|
|
9934
10863
|
revalidate().catch((err) => {
|
|
9935
10864
|
if (typeof console !== "undefined") console.warn("[SibuJS ISR] initial fetch failed", err);
|
|
9936
10865
|
});
|
|
10866
|
+
} else {
|
|
10867
|
+
armDeadline();
|
|
9937
10868
|
}
|
|
9938
|
-
const intervalId = setInterval(() => {
|
|
9939
|
-
revalidate().catch((err) => {
|
|
9940
|
-
if (typeof console !== "undefined") console.warn("[SibuJS ISR] revalidate failed", err);
|
|
9941
|
-
});
|
|
9942
|
-
}, revalidateAfter);
|
|
9943
10869
|
const dispose2 = () => {
|
|
9944
10870
|
if (disposed) return;
|
|
9945
10871
|
disposed = true;
|
|
9946
|
-
|
|
10872
|
+
clearDeadline();
|
|
9947
10873
|
controller.abort();
|
|
9948
10874
|
};
|
|
9949
|
-
return { data: data2, isStale, revalidate, dispose: dispose2 };
|
|
10875
|
+
return { data: data2, isStale: stale, revalidate, dispose: dispose2 };
|
|
9950
10876
|
}
|
|
9951
10877
|
|
|
9952
10878
|
// src/platform/routeActions.ts
|
|
@@ -10071,7 +10997,7 @@ function scrollRestoration(options) {
|
|
|
10071
10997
|
|
|
10072
10998
|
// src/platform/routeMiddleware.ts
|
|
10073
10999
|
function composeMiddleware(...fns) {
|
|
10074
|
-
return async (
|
|
11000
|
+
return async (context, next) => {
|
|
10075
11001
|
let index = -1;
|
|
10076
11002
|
const dispatch = async (i2) => {
|
|
10077
11003
|
if (i2 <= index) {
|
|
@@ -10079,7 +11005,7 @@ function composeMiddleware(...fns) {
|
|
|
10079
11005
|
}
|
|
10080
11006
|
index = i2;
|
|
10081
11007
|
if (i2 < fns.length) {
|
|
10082
|
-
await fns[i2](
|
|
11008
|
+
await fns[i2](context, () => dispatch(i2 + 1));
|
|
10083
11009
|
} else {
|
|
10084
11010
|
await next();
|
|
10085
11011
|
}
|
|
@@ -10092,46 +11018,136 @@ function createMiddlewareChain() {
|
|
|
10092
11018
|
const use2 = (fn) => {
|
|
10093
11019
|
middlewares.push(fn);
|
|
10094
11020
|
};
|
|
10095
|
-
const run = async (
|
|
11021
|
+
const run = async (context) => {
|
|
10096
11022
|
const composed = composeMiddleware(...middlewares);
|
|
10097
|
-
await composed(
|
|
11023
|
+
await composed(context, () => {
|
|
10098
11024
|
});
|
|
10099
11025
|
};
|
|
10100
11026
|
return { use: use2, run };
|
|
10101
11027
|
}
|
|
10102
11028
|
|
|
10103
11029
|
// src/plugins/plugin.ts
|
|
11030
|
+
var CANCELLED_BRAND = /* @__PURE__ */ Symbol.for("sibujs.plugins.installCancelled.v1");
|
|
11031
|
+
var _a;
|
|
11032
|
+
var PluginInstallCancelledError = class extends Error {
|
|
11033
|
+
constructor(pluginName) {
|
|
11034
|
+
super(`[Plugin] Installation of "${pluginName}" was cancelled before it was committed (registry reset).`);
|
|
11035
|
+
/**
|
|
11036
|
+
* Brand, not identity: the default registry is shared across duplicate copies
|
|
11037
|
+
* of this module, so the error a caller receives may come from another copy's
|
|
11038
|
+
* constructor. `instanceof` is taught to recognise the brand instead.
|
|
11039
|
+
*/
|
|
11040
|
+
this[_a] = true;
|
|
11041
|
+
this.name = "PluginInstallCancelledError";
|
|
11042
|
+
this.pluginName = pluginName;
|
|
11043
|
+
}
|
|
11044
|
+
static [(_a = CANCELLED_BRAND, Symbol.hasInstance)](value) {
|
|
11045
|
+
return isPluginInstallCancelledError(value);
|
|
11046
|
+
}
|
|
11047
|
+
};
|
|
11048
|
+
function isPluginInstallCancelledError(value) {
|
|
11049
|
+
return typeof value === "object" && value !== null && value[CANCELLED_BRAND] === true;
|
|
11050
|
+
}
|
|
10104
11051
|
function createPluginRegistry() {
|
|
10105
11052
|
const installedPlugins = /* @__PURE__ */ new Set();
|
|
10106
11053
|
const hooks = { init: [], mount: [], unmount: [], error: [] };
|
|
10107
11054
|
const provided = /* @__PURE__ */ new Map();
|
|
11055
|
+
const installStack = /* @__PURE__ */ new Set();
|
|
11056
|
+
const pendingInstalls = /* @__PURE__ */ new Map();
|
|
11057
|
+
let generation = 0;
|
|
10108
11058
|
const registry = {
|
|
10109
11059
|
installedPlugins,
|
|
10110
11060
|
hooks,
|
|
10111
11061
|
provided,
|
|
11062
|
+
/**
|
|
11063
|
+
* Install a plugin as a transaction.
|
|
11064
|
+
*
|
|
11065
|
+
* Hooks and providers registered through `ctx` are staged and committed
|
|
11066
|
+
* only if `install()` returns; a throwing install leaves the registry
|
|
11067
|
+
* exactly as it found it (and can simply be retried). The plugin is marked
|
|
11068
|
+
* installed at commit, before its init hooks run.
|
|
11069
|
+
*
|
|
11070
|
+
* Each `plugin()` call is its own transaction: a dependency installed by a
|
|
11071
|
+
* nested `plugin()` call commits on its own and stays installed even if the
|
|
11072
|
+
* outer installation later fails.
|
|
11073
|
+
*/
|
|
10112
11074
|
plugin(p2, options) {
|
|
10113
11075
|
if (installedPlugins.has(p2.name)) {
|
|
10114
11076
|
console.warn(`[Plugin] "${p2.name}" is already installed.`);
|
|
10115
11077
|
return;
|
|
10116
11078
|
}
|
|
11079
|
+
if (installStack.has(p2.name)) {
|
|
11080
|
+
throw new Error(`[Plugin] "${p2.name}" is already being installed (recursive installation).`);
|
|
11081
|
+
}
|
|
11082
|
+
if (pendingInstalls.has(p2.name)) {
|
|
11083
|
+
throw new Error(`[Plugin] "${p2.name}" is already being installed (asynchronous installation in flight).`);
|
|
11084
|
+
}
|
|
11085
|
+
const staged = { init: [], mount: [], unmount: [], error: [] };
|
|
11086
|
+
const stagedProvided = /* @__PURE__ */ new Map();
|
|
11087
|
+
let committed = false;
|
|
11088
|
+
const myGeneration = generation;
|
|
11089
|
+
const stale = () => {
|
|
11090
|
+
if (myGeneration === generation) return false;
|
|
11091
|
+
if (DEV) devWarn(`plugin: "${p2.name}" registered after the registry was reset; the registration was ignored.`);
|
|
11092
|
+
return true;
|
|
11093
|
+
};
|
|
11094
|
+
const target = () => stale() ? null : committed ? hooks : staged;
|
|
10117
11095
|
const ctx = {
|
|
10118
|
-
onInit: (cb) =>
|
|
10119
|
-
onMount: (cb) =>
|
|
10120
|
-
onUnmount: (cb) =>
|
|
10121
|
-
onError: (cb) =>
|
|
10122
|
-
provide: (key, value) =>
|
|
11096
|
+
onInit: (cb) => void target()?.init.push(cb),
|
|
11097
|
+
onMount: (cb) => void target()?.mount.push(cb),
|
|
11098
|
+
onUnmount: (cb) => void target()?.unmount.push(cb),
|
|
11099
|
+
onError: (cb) => void target()?.error.push(cb),
|
|
11100
|
+
provide: (key, value) => {
|
|
11101
|
+
if (stale()) return;
|
|
11102
|
+
(committed ? provided : stagedProvided).set(key, value);
|
|
11103
|
+
}
|
|
10123
11104
|
};
|
|
10124
|
-
const
|
|
10125
|
-
|
|
10126
|
-
|
|
10127
|
-
|
|
10128
|
-
|
|
10129
|
-
|
|
10130
|
-
|
|
10131
|
-
|
|
10132
|
-
|
|
11105
|
+
const commit = () => {
|
|
11106
|
+
if (myGeneration !== generation) return false;
|
|
11107
|
+
hooks.init.push(...staged.init);
|
|
11108
|
+
hooks.mount.push(...staged.mount);
|
|
11109
|
+
hooks.unmount.push(...staged.unmount);
|
|
11110
|
+
hooks.error.push(...staged.error);
|
|
11111
|
+
for (const [key, value] of stagedProvided) provided.set(key, value);
|
|
11112
|
+
installedPlugins.add(p2.name);
|
|
11113
|
+
committed = true;
|
|
11114
|
+
if (pendingInstalls.get(p2.name) === myGeneration) pendingInstalls.delete(p2.name);
|
|
11115
|
+
for (const cb of staged.init.slice()) {
|
|
11116
|
+
try {
|
|
11117
|
+
cb();
|
|
11118
|
+
} catch (e) {
|
|
11119
|
+
console.error(`[Plugin] "${p2.name}" init error:`, e);
|
|
11120
|
+
}
|
|
10133
11121
|
}
|
|
11122
|
+
return true;
|
|
11123
|
+
};
|
|
11124
|
+
installStack.add(p2.name);
|
|
11125
|
+
let pending;
|
|
11126
|
+
try {
|
|
11127
|
+
pending = adoptThenable(p2.install(ctx, options));
|
|
11128
|
+
} finally {
|
|
11129
|
+
installStack.delete(p2.name);
|
|
11130
|
+
}
|
|
11131
|
+
if (!pending) {
|
|
11132
|
+
if (!commit()) throw new PluginInstallCancelledError(p2.name);
|
|
11133
|
+
return;
|
|
10134
11134
|
}
|
|
11135
|
+
if (myGeneration === generation) pendingInstalls.set(p2.name, myGeneration);
|
|
11136
|
+
const settled = pending.then(
|
|
11137
|
+
() => {
|
|
11138
|
+
if (commit()) return;
|
|
11139
|
+
if (pendingInstalls.get(p2.name) === myGeneration) pendingInstalls.delete(p2.name);
|
|
11140
|
+
throw new PluginInstallCancelledError(p2.name);
|
|
11141
|
+
},
|
|
11142
|
+
(err) => {
|
|
11143
|
+
if (pendingInstalls.get(p2.name) === myGeneration) pendingInstalls.delete(p2.name);
|
|
11144
|
+
reportError(err, { phase: "async", name: `plugin(${p2.name})` });
|
|
11145
|
+
throw err;
|
|
11146
|
+
}
|
|
11147
|
+
);
|
|
11148
|
+
settled.catch(() => {
|
|
11149
|
+
});
|
|
11150
|
+
return settled;
|
|
10135
11151
|
},
|
|
10136
11152
|
inject(key, defaultValue) {
|
|
10137
11153
|
if (provided.has(key)) return provided.get(key);
|
|
@@ -10169,6 +11185,8 @@ function createPluginRegistry() {
|
|
|
10169
11185
|
}
|
|
10170
11186
|
},
|
|
10171
11187
|
reset() {
|
|
11188
|
+
generation++;
|
|
11189
|
+
pendingInstalls.clear();
|
|
10172
11190
|
installedPlugins.clear();
|
|
10173
11191
|
hooks.init.length = 0;
|
|
10174
11192
|
hooks.mount.length = 0;
|
|
@@ -10188,7 +11206,7 @@ function createPlugin(name, install) {
|
|
|
10188
11206
|
}
|
|
10189
11207
|
function plugin(plugin2, options) {
|
|
10190
11208
|
_defaults.touched = true;
|
|
10191
|
-
_defaults.registry.plugin(plugin2, options);
|
|
11209
|
+
return _defaults.registry.plugin(plugin2, options);
|
|
10192
11210
|
}
|
|
10193
11211
|
function inject(key, defaultValue) {
|
|
10194
11212
|
return _defaults.registry.inject(key, defaultValue);
|
|
@@ -10219,35 +11237,44 @@ function setDefaultPluginRegistry(registry) {
|
|
|
10219
11237
|
// src/plugins/modular.ts
|
|
10220
11238
|
function createModuleRegistry() {
|
|
10221
11239
|
const modules = /* @__PURE__ */ new Map();
|
|
10222
|
-
|
|
11240
|
+
const resolving = [];
|
|
11241
|
+
function resolveInternal(name) {
|
|
10223
11242
|
const entry = modules.get(name);
|
|
10224
11243
|
if (!entry) {
|
|
10225
11244
|
throw new Error(`[ModuleRegistry] Module "${name}" is not registered.`);
|
|
10226
11245
|
}
|
|
10227
|
-
if (entry.loaded) {
|
|
11246
|
+
if (entry.state === "loaded") {
|
|
10228
11247
|
return entry.value;
|
|
10229
11248
|
}
|
|
10230
|
-
if (
|
|
10231
|
-
const cycle = [...
|
|
11249
|
+
if (entry.state === "resolving") {
|
|
11250
|
+
const cycle = [...resolving.slice(resolving.indexOf(name)), name].join(" -> ");
|
|
10232
11251
|
throw new Error(`[ModuleRegistry] Circular dependency detected: ${cycle}`);
|
|
10233
11252
|
}
|
|
10234
|
-
|
|
10235
|
-
|
|
10236
|
-
|
|
11253
|
+
entry.state = "resolving";
|
|
11254
|
+
resolving.push(name);
|
|
11255
|
+
try {
|
|
11256
|
+
for (const dep of entry.deps) {
|
|
11257
|
+
resolveInternal(dep);
|
|
11258
|
+
}
|
|
11259
|
+
entry.value = entry.factory();
|
|
11260
|
+
entry.state = "loaded";
|
|
11261
|
+
return entry.value;
|
|
11262
|
+
} catch (err) {
|
|
11263
|
+
entry.state = "unloaded";
|
|
11264
|
+
entry.value = void 0;
|
|
11265
|
+
throw err;
|
|
11266
|
+
} finally {
|
|
11267
|
+
resolving.pop();
|
|
10237
11268
|
}
|
|
10238
|
-
stack.delete(name);
|
|
10239
|
-
entry.value = entry.factory();
|
|
10240
|
-
entry.loaded = true;
|
|
10241
|
-
return entry.value;
|
|
10242
11269
|
}
|
|
10243
11270
|
return {
|
|
10244
11271
|
/** Register a module with its factory function and optional dependencies */
|
|
10245
11272
|
register(name, factory, deps = []) {
|
|
10246
|
-
modules.set(name, { factory, deps,
|
|
11273
|
+
modules.set(name, { factory, deps, state: "unloaded" });
|
|
10247
11274
|
},
|
|
10248
11275
|
/** Resolve a module, loading its dependencies first */
|
|
10249
11276
|
resolve(name) {
|
|
10250
|
-
return resolveInternal(name
|
|
11277
|
+
return resolveInternal(name);
|
|
10251
11278
|
},
|
|
10252
11279
|
/** Check if a module is registered */
|
|
10253
11280
|
has(name) {
|
|
@@ -10282,7 +11309,7 @@ function createModuleRegistry() {
|
|
|
10282
11309
|
/** Reset all loaded modules back to unloaded state (useful for testing) */
|
|
10283
11310
|
reset() {
|
|
10284
11311
|
for (const entry of modules.values()) {
|
|
10285
|
-
entry.
|
|
11312
|
+
entry.state = "unloaded";
|
|
10286
11313
|
entry.value = void 0;
|
|
10287
11314
|
}
|
|
10288
11315
|
}
|
|
@@ -10310,46 +11337,83 @@ function createBundle(modules) {
|
|
|
10310
11337
|
function lazyModule(loader) {
|
|
10311
11338
|
let cached;
|
|
10312
11339
|
let loadedFlag = false;
|
|
10313
|
-
|
|
11340
|
+
let inFlight = null;
|
|
11341
|
+
return {
|
|
10314
11342
|
get loaded() {
|
|
10315
11343
|
return loadedFlag;
|
|
10316
11344
|
},
|
|
10317
|
-
|
|
10318
|
-
if (loadedFlag) return cached;
|
|
10319
|
-
|
|
10320
|
-
|
|
10321
|
-
|
|
10322
|
-
|
|
10323
|
-
|
|
10324
|
-
|
|
10325
|
-
}
|
|
11345
|
+
get() {
|
|
11346
|
+
if (loadedFlag) return Promise.resolve(cached);
|
|
11347
|
+
if (inFlight) return inFlight;
|
|
11348
|
+
let started;
|
|
11349
|
+
try {
|
|
11350
|
+
started = Promise.resolve(loader());
|
|
11351
|
+
} catch (err) {
|
|
11352
|
+
started = Promise.reject(err);
|
|
11353
|
+
}
|
|
11354
|
+
const attempt = started.then(
|
|
11355
|
+
(value) => {
|
|
11356
|
+
cached = value;
|
|
11357
|
+
loadedFlag = true;
|
|
11358
|
+
if (inFlight === attempt) inFlight = null;
|
|
11359
|
+
return value;
|
|
11360
|
+
},
|
|
11361
|
+
(err) => {
|
|
11362
|
+
if (inFlight === attempt) inFlight = null;
|
|
11363
|
+
throw err;
|
|
11364
|
+
}
|
|
11365
|
+
);
|
|
11366
|
+
inFlight = attempt;
|
|
11367
|
+
return attempt;
|
|
11368
|
+
}
|
|
11369
|
+
};
|
|
11370
|
+
}
|
|
11371
|
+
var MODULE_ENTRY_POINTS = {
|
|
11372
|
+
main: "./index.ts",
|
|
11373
|
+
data: "./data.ts",
|
|
11374
|
+
browser: "./browser.ts",
|
|
11375
|
+
patterns: "./patterns.ts",
|
|
11376
|
+
motion: "./motion.ts",
|
|
11377
|
+
ui: "./ui.ts",
|
|
11378
|
+
widgets: "./widgets.ts",
|
|
11379
|
+
ssr: "./ssr.ts",
|
|
11380
|
+
devtools: "./devtools.ts",
|
|
11381
|
+
performance: "./performance.ts",
|
|
11382
|
+
ecosystem: "./ecosystem.ts",
|
|
11383
|
+
plugins: "./plugins.ts",
|
|
11384
|
+
build: "./build.ts",
|
|
11385
|
+
testing: "./testing.ts",
|
|
11386
|
+
extras: "./extras.ts"
|
|
11387
|
+
};
|
|
11388
|
+
var CDN_ENTRY_POINTS = {
|
|
11389
|
+
cdn: "./dist/cdn.global.js",
|
|
11390
|
+
"cdn-dev": "./dist/cdn.dev.global.js",
|
|
11391
|
+
"cdn-full": "./dist/cdn.full.global.js",
|
|
11392
|
+
"cdn-full-dev": "./dist/cdn.full.dev.global.js"
|
|
11393
|
+
};
|
|
10326
11394
|
var packageInfo = {
|
|
10327
|
-
name: "
|
|
10328
|
-
version: "
|
|
10329
|
-
entryPoints:
|
|
10330
|
-
main: "./index.ts",
|
|
10331
|
-
core: "./src/core/html.ts",
|
|
10332
|
-
hooks: "./src/core/signals/signal.ts",
|
|
10333
|
-
router: "./src/plugins/router.ts",
|
|
10334
|
-
i18n: "./src/plugins/i18n.ts",
|
|
10335
|
-
testing: "./src/testing/index.ts",
|
|
10336
|
-
ssr: "./src/core/ssr.ts"
|
|
10337
|
-
},
|
|
11395
|
+
name: "sibujs",
|
|
11396
|
+
version: true ? "4.6.0" : "dev",
|
|
11397
|
+
entryPoints: MODULE_ENTRY_POINTS,
|
|
10338
11398
|
/**
|
|
10339
|
-
* Generate
|
|
10340
|
-
*
|
|
11399
|
+
* Generate the package.json `exports` map. Module entries resolve to the
|
|
11400
|
+
* `.js` (ESM), `.cjs` and `.d.ts` files tsup emits into `dist/`; CDN entries
|
|
11401
|
+
* resolve to their prebuilt global script.
|
|
10341
11402
|
*/
|
|
10342
11403
|
generateExportsMap() {
|
|
10343
11404
|
const exportsMap = {};
|
|
10344
|
-
for (const [name, sourcePath] of Object.entries(
|
|
11405
|
+
for (const [name, sourcePath] of Object.entries(MODULE_ENTRY_POINTS)) {
|
|
10345
11406
|
const distPath = sourcePath.replace(/^\.\//, "./dist/").replace(/\.ts$/, "");
|
|
10346
11407
|
const subpath = name === "main" ? "." : `./${name}`;
|
|
10347
11408
|
exportsMap[subpath] = {
|
|
10348
|
-
|
|
10349
|
-
|
|
10350
|
-
|
|
11409
|
+
types: `${distPath}.d.ts`,
|
|
11410
|
+
import: `${distPath}.js`,
|
|
11411
|
+
require: `${distPath}.cjs`
|
|
10351
11412
|
};
|
|
10352
11413
|
}
|
|
11414
|
+
for (const [name, file] of Object.entries(CDN_ENTRY_POINTS)) {
|
|
11415
|
+
exportsMap[`./${name}`] = { default: file };
|
|
11416
|
+
}
|
|
10353
11417
|
return exportsMap;
|
|
10354
11418
|
}
|
|
10355
11419
|
};
|
|
@@ -10474,29 +11538,26 @@ var env = {
|
|
|
10474
11538
|
};
|
|
10475
11539
|
|
|
10476
11540
|
// src/plugins/versioning.ts
|
|
10477
|
-
var VERSION = "
|
|
11541
|
+
var VERSION = true ? "4.6.0" : "dev";
|
|
11542
|
+
var NUM = "(?:0|[1-9]\\d*)";
|
|
11543
|
+
var PRE_ID = `(?:${NUM}|\\d*[a-zA-Z-][0-9a-zA-Z-]*)`;
|
|
11544
|
+
var BUILD_ID = "[0-9a-zA-Z-]+";
|
|
11545
|
+
var SEMVER_PATTERN = new RegExp(
|
|
11546
|
+
`^(${NUM})(?:\\.(${NUM})(?:\\.(${NUM})(?:-(${PRE_ID}(?:\\.${PRE_ID})*))?(?:\\+(${BUILD_ID}(?:\\.${BUILD_ID})*))?)?)?$`
|
|
11547
|
+
);
|
|
10478
11548
|
function parseSemVer(version) {
|
|
10479
|
-
const trimmed = version.trim().replace(/^v/i, "");
|
|
10480
|
-
const
|
|
10481
|
-
|
|
10482
|
-
let prerelease;
|
|
10483
|
-
if (prereleaseIndex !== -1) {
|
|
10484
|
-
main2 = trimmed.slice(0, prereleaseIndex);
|
|
10485
|
-
prerelease = trimmed.slice(prereleaseIndex + 1);
|
|
10486
|
-
} else {
|
|
10487
|
-
main2 = trimmed;
|
|
10488
|
-
}
|
|
10489
|
-
const parts = main2.split(".");
|
|
10490
|
-
const major = parseInt(parts[0], 10);
|
|
10491
|
-
const minor = parseInt(parts[1] || "0", 10);
|
|
10492
|
-
const patch = parseInt(parts[2] || "0", 10);
|
|
10493
|
-
if (Number.isNaN(major) || Number.isNaN(minor) || Number.isNaN(patch)) {
|
|
11549
|
+
const trimmed = String(version).trim().replace(/^v/i, "");
|
|
11550
|
+
const match = SEMVER_PATTERN.exec(trimmed);
|
|
11551
|
+
if (!match) {
|
|
10494
11552
|
throw new Error(`[Versioning] Invalid semver string: "${version}"`);
|
|
10495
11553
|
}
|
|
10496
|
-
const result = {
|
|
10497
|
-
|
|
10498
|
-
|
|
10499
|
-
|
|
11554
|
+
const result = {
|
|
11555
|
+
major: Number(match[1]),
|
|
11556
|
+
minor: match[2] === void 0 ? 0 : Number(match[2]),
|
|
11557
|
+
patch: match[3] === void 0 ? 0 : Number(match[3])
|
|
11558
|
+
};
|
|
11559
|
+
if (match[4] !== void 0) result.prerelease = match[4];
|
|
11560
|
+
if (match[5] !== void 0) result.build = match[5];
|
|
10500
11561
|
return result;
|
|
10501
11562
|
}
|
|
10502
11563
|
function compareSemVer(a2, b2) {
|
|
@@ -10579,82 +11640,154 @@ function satisfies(version, range) {
|
|
|
10579
11640
|
const target = parseSemVer(exactStr);
|
|
10580
11641
|
return compareSemVer(v, target) === 0;
|
|
10581
11642
|
}
|
|
11643
|
+
var MigrationStorageError = class extends Error {
|
|
11644
|
+
constructor(version, cause) {
|
|
11645
|
+
const reason = cause instanceof Error ? cause.message : String(cause);
|
|
11646
|
+
super(`[Versioning] Migration ${version} completed, but recording it in storage failed: ${reason}`);
|
|
11647
|
+
this.name = "MigrationStorageError";
|
|
11648
|
+
this.version = version;
|
|
11649
|
+
this.cause = cause;
|
|
11650
|
+
}
|
|
11651
|
+
};
|
|
11652
|
+
var _migrationQueues = globalSingleton(
|
|
11653
|
+
/* @__PURE__ */ Symbol.for("sibujs.migrationQueues.v1"),
|
|
11654
|
+
() => /* @__PURE__ */ new WeakMap()
|
|
11655
|
+
);
|
|
11656
|
+
var NO_STORAGE = {};
|
|
10582
11657
|
function createMigrationRunner(config) {
|
|
10583
11658
|
const storageKey = config.storageKey || "__sibu_migration_version__";
|
|
10584
11659
|
const sortedMigrations = [...config.migrations].sort((a2, b2) => compareSemVer(a2.version, b2.version));
|
|
10585
11660
|
function getStorage() {
|
|
11661
|
+
if (config.storage) return config.storage;
|
|
10586
11662
|
try {
|
|
10587
11663
|
return typeof localStorage !== "undefined" ? localStorage : null;
|
|
10588
11664
|
} catch {
|
|
10589
11665
|
return null;
|
|
10590
11666
|
}
|
|
10591
11667
|
}
|
|
11668
|
+
function getAppliedVersion() {
|
|
11669
|
+
const storage = getStorage();
|
|
11670
|
+
if (!storage) return null;
|
|
11671
|
+
return storage.getItem(storageKey);
|
|
11672
|
+
}
|
|
11673
|
+
function getPending() {
|
|
11674
|
+
const appliedVersion = getAppliedVersion();
|
|
11675
|
+
if (!appliedVersion) {
|
|
11676
|
+
return sortedMigrations.filter((m) => compareSemVer(m.version, config.currentVersion) <= 0);
|
|
11677
|
+
}
|
|
11678
|
+
return sortedMigrations.filter(
|
|
11679
|
+
(m) => compareSemVer(m.version, appliedVersion) > 0 && compareSemVer(m.version, config.currentVersion) <= 0
|
|
11680
|
+
);
|
|
11681
|
+
}
|
|
11682
|
+
function writeApplied(version, migrationVersion) {
|
|
11683
|
+
const storage = getStorage();
|
|
11684
|
+
if (!storage) return;
|
|
11685
|
+
try {
|
|
11686
|
+
if (version === null) storage.removeItem(storageKey);
|
|
11687
|
+
else storage.setItem(storageKey, version);
|
|
11688
|
+
} catch (e) {
|
|
11689
|
+
throw new MigrationStorageError(migrationVersion, e);
|
|
11690
|
+
}
|
|
11691
|
+
}
|
|
11692
|
+
function serialize(operation) {
|
|
11693
|
+
const identity = getStorage() ?? NO_STORAGE;
|
|
11694
|
+
let queues = _migrationQueues.get(identity);
|
|
11695
|
+
if (!queues) {
|
|
11696
|
+
queues = /* @__PURE__ */ new Map();
|
|
11697
|
+
_migrationQueues.set(identity, queues);
|
|
11698
|
+
}
|
|
11699
|
+
const run = (queues.get(storageKey) ?? Promise.resolve()).then(operation, operation);
|
|
11700
|
+
const tail = run.then(
|
|
11701
|
+
() => void 0,
|
|
11702
|
+
() => void 0
|
|
11703
|
+
);
|
|
11704
|
+
queues.set(storageKey, tail);
|
|
11705
|
+
const settled = queues;
|
|
11706
|
+
tail.then(() => {
|
|
11707
|
+
if (settled.get(storageKey) === tail) settled.delete(storageKey);
|
|
11708
|
+
});
|
|
11709
|
+
return run;
|
|
11710
|
+
}
|
|
10592
11711
|
return {
|
|
10593
11712
|
/** Get the last applied migration version from storage */
|
|
10594
|
-
getAppliedVersion
|
|
10595
|
-
const storage = getStorage();
|
|
10596
|
-
if (!storage) return null;
|
|
10597
|
-
return storage.getItem(storageKey);
|
|
10598
|
-
},
|
|
11713
|
+
getAppliedVersion,
|
|
10599
11714
|
/** Get pending migrations that haven't been applied */
|
|
10600
|
-
getPending
|
|
10601
|
-
|
|
10602
|
-
|
|
10603
|
-
|
|
10604
|
-
|
|
10605
|
-
|
|
10606
|
-
|
|
10607
|
-
|
|
10608
|
-
|
|
10609
|
-
|
|
10610
|
-
|
|
10611
|
-
|
|
10612
|
-
const applied = [];
|
|
10613
|
-
const errors = [];
|
|
10614
|
-
for (const migration of pending) {
|
|
11715
|
+
getPending,
|
|
11716
|
+
/**
|
|
11717
|
+
* Run all pending migrations in order. Concurrent calls (and calls racing
|
|
11718
|
+
* `rollback()`) run one after another, each recomputing what is pending —
|
|
11719
|
+
* on this runner and on every other runner in this realm sharing its
|
|
11720
|
+
* storage and storage key.
|
|
11721
|
+
*/
|
|
11722
|
+
migrate() {
|
|
11723
|
+
return serialize(async () => {
|
|
11724
|
+
const applied = [];
|
|
11725
|
+
const errors = [];
|
|
11726
|
+
let pending;
|
|
10615
11727
|
try {
|
|
10616
|
-
|
|
10617
|
-
applied.push(migration.version);
|
|
10618
|
-
const storage = getStorage();
|
|
10619
|
-
if (storage) {
|
|
10620
|
-
storage.setItem(storageKey, migration.version);
|
|
10621
|
-
}
|
|
11728
|
+
pending = getPending();
|
|
10622
11729
|
} catch (e) {
|
|
10623
11730
|
errors.push({
|
|
10624
|
-
version:
|
|
11731
|
+
version: getAppliedVersion() ?? "",
|
|
10625
11732
|
error: e instanceof Error ? e : new Error(String(e))
|
|
10626
11733
|
});
|
|
10627
|
-
|
|
11734
|
+
return { applied, errors };
|
|
10628
11735
|
}
|
|
10629
|
-
|
|
10630
|
-
|
|
11736
|
+
for (const migration of pending) {
|
|
11737
|
+
try {
|
|
11738
|
+
await migration.up();
|
|
11739
|
+
} catch (e) {
|
|
11740
|
+
errors.push({
|
|
11741
|
+
version: migration.version,
|
|
11742
|
+
error: e instanceof Error ? e : new Error(String(e))
|
|
11743
|
+
});
|
|
11744
|
+
break;
|
|
11745
|
+
}
|
|
11746
|
+
applied.push(migration.version);
|
|
11747
|
+
try {
|
|
11748
|
+
writeApplied(migration.version, migration.version);
|
|
11749
|
+
} catch (e) {
|
|
11750
|
+
errors.push({ version: migration.version, error: e });
|
|
11751
|
+
break;
|
|
11752
|
+
}
|
|
11753
|
+
}
|
|
11754
|
+
return { applied, errors };
|
|
11755
|
+
});
|
|
10631
11756
|
},
|
|
10632
|
-
/**
|
|
10633
|
-
|
|
10634
|
-
|
|
10635
|
-
|
|
10636
|
-
|
|
10637
|
-
|
|
10638
|
-
|
|
10639
|
-
|
|
10640
|
-
|
|
10641
|
-
|
|
10642
|
-
|
|
10643
|
-
|
|
10644
|
-
|
|
11757
|
+
/**
|
|
11758
|
+
* Rollback to a specific version.
|
|
11759
|
+
*
|
|
11760
|
+
* The applied version is checkpointed after EVERY successful `down()`, so a
|
|
11761
|
+
* rollback that fails part-way leaves storage describing what is actually
|
|
11762
|
+
* still applied, and a retry does not repeat completed `down()` steps.
|
|
11763
|
+
* Throws the failing `down()`'s error, a missing-`down()` error, or a
|
|
11764
|
+
* {@link MigrationStorageError} if a checkpoint cannot be written.
|
|
11765
|
+
*/
|
|
11766
|
+
rollback(targetVersion) {
|
|
11767
|
+
return serialize(async () => {
|
|
11768
|
+
const appliedVersion = getAppliedVersion();
|
|
11769
|
+
const rolledBack = [];
|
|
11770
|
+
if (!appliedVersion) {
|
|
11771
|
+
return { rolledBack };
|
|
10645
11772
|
}
|
|
10646
|
-
|
|
10647
|
-
|
|
10648
|
-
|
|
10649
|
-
|
|
10650
|
-
|
|
10651
|
-
|
|
10652
|
-
|
|
10653
|
-
} else {
|
|
10654
|
-
storage.setItem(storageKey, targetVersion);
|
|
11773
|
+
const toRollback = sortedMigrations.filter((m) => compareSemVer(m.version, targetVersion) > 0 && compareSemVer(m.version, appliedVersion) <= 0).reverse();
|
|
11774
|
+
for (const migration of toRollback) {
|
|
11775
|
+
if (!migration.down) {
|
|
11776
|
+
throw new Error(
|
|
11777
|
+
`[Versioning] Migration ${migration.version} ("${migration.description}") does not have a down() function and cannot be rolled back.`
|
|
11778
|
+
);
|
|
11779
|
+
}
|
|
10655
11780
|
}
|
|
10656
|
-
|
|
10657
|
-
|
|
11781
|
+
for (const migration of toRollback) {
|
|
11782
|
+
await migration.down();
|
|
11783
|
+
rolledBack.push(migration.version);
|
|
11784
|
+
const index = sortedMigrations.indexOf(migration);
|
|
11785
|
+
const previous2 = index > 0 ? sortedMigrations[index - 1].version : null;
|
|
11786
|
+
writeApplied(previous2, migration.version);
|
|
11787
|
+
}
|
|
11788
|
+
writeApplied(targetVersion === "0.0.0" ? null : targetVersion, targetVersion);
|
|
11789
|
+
return { rolledBack };
|
|
11790
|
+
});
|
|
10658
11791
|
}
|
|
10659
11792
|
};
|
|
10660
11793
|
}
|
|
@@ -10704,28 +11837,43 @@ function preloadCritical(resources) {
|
|
|
10704
11837
|
document.head.appendChild(link2);
|
|
10705
11838
|
}
|
|
10706
11839
|
}
|
|
10707
|
-
function
|
|
10708
|
-
|
|
10709
|
-
|
|
10710
|
-
|
|
10711
|
-
|
|
10712
|
-
|
|
10713
|
-
|
|
11840
|
+
function assertCacheSize(name, value) {
|
|
11841
|
+
if (!Number.isInteger(value) || value < 0) {
|
|
11842
|
+
throw new RangeError(`[Startup] ${name} must be a non-negative integer, got ${value}`);
|
|
11843
|
+
}
|
|
11844
|
+
}
|
|
11845
|
+
function makeRoomFor(cache, key, maxSize, isValid) {
|
|
11846
|
+
if (maxSize === 0) return false;
|
|
11847
|
+
if (cache.has(key)) return true;
|
|
11848
|
+
if (cache.size < maxSize) return true;
|
|
11849
|
+
for (const [k, entry] of cache) {
|
|
11850
|
+
if (!isValid(entry)) cache.delete(k);
|
|
10714
11851
|
}
|
|
10715
|
-
|
|
10716
|
-
if (cache.size < maxCacheSize) return;
|
|
11852
|
+
while (cache.size >= maxSize) {
|
|
10717
11853
|
let oldestKey = null;
|
|
10718
11854
|
let oldestTime = Infinity;
|
|
10719
|
-
for (const [
|
|
11855
|
+
for (const [k, entry] of cache) {
|
|
10720
11856
|
if (entry.timestamp < oldestTime) {
|
|
10721
11857
|
oldestTime = entry.timestamp;
|
|
10722
|
-
oldestKey =
|
|
11858
|
+
oldestKey = k;
|
|
10723
11859
|
}
|
|
10724
11860
|
}
|
|
10725
|
-
if (oldestKey)
|
|
11861
|
+
if (oldestKey === null) break;
|
|
11862
|
+
cache.delete(oldestKey);
|
|
11863
|
+
}
|
|
11864
|
+
return true;
|
|
11865
|
+
}
|
|
11866
|
+
function prerenderRoutes(routes, options) {
|
|
11867
|
+
const maxCacheSize = options?.maxCacheSize ?? 50;
|
|
11868
|
+
const cacheTTL = options?.cacheTTL ?? 0;
|
|
11869
|
+
assertCacheSize("maxCacheSize", maxCacheSize);
|
|
11870
|
+
const cache = /* @__PURE__ */ new Map();
|
|
11871
|
+
function isValid(entry) {
|
|
11872
|
+
if (cacheTTL === 0) return true;
|
|
11873
|
+
return Date.now() - entry.timestamp < cacheTTL;
|
|
10726
11874
|
}
|
|
10727
11875
|
for (const route of routes) {
|
|
10728
|
-
|
|
11876
|
+
if (!makeRoomFor(cache, route.path, maxCacheSize, isValid)) break;
|
|
10729
11877
|
const html2 = renderToString(route.component());
|
|
10730
11878
|
cache.set(route.path, { html: html2, timestamp: Date.now() });
|
|
10731
11879
|
}
|
|
@@ -10777,6 +11925,7 @@ function prerenderRoutes(routes, options) {
|
|
|
10777
11925
|
function createSSRCache(config) {
|
|
10778
11926
|
const maxSize = config?.maxSize ?? 100;
|
|
10779
11927
|
const defaultTTL = config?.defaultTTL ?? 6e4;
|
|
11928
|
+
assertCacheSize("maxSize", maxSize);
|
|
10780
11929
|
const cache = /* @__PURE__ */ new Map();
|
|
10781
11930
|
let hits = 0;
|
|
10782
11931
|
let misses = 0;
|
|
@@ -10784,18 +11933,6 @@ function createSSRCache(config) {
|
|
|
10784
11933
|
if (entry.ttl === 0) return true;
|
|
10785
11934
|
return Date.now() - entry.timestamp < entry.ttl;
|
|
10786
11935
|
}
|
|
10787
|
-
function evictOldest() {
|
|
10788
|
-
if (cache.size < maxSize) return;
|
|
10789
|
-
let oldestKey = null;
|
|
10790
|
-
let oldestTime = Infinity;
|
|
10791
|
-
for (const [key, entry] of cache) {
|
|
10792
|
-
if (entry.timestamp < oldestTime) {
|
|
10793
|
-
oldestTime = entry.timestamp;
|
|
10794
|
-
oldestKey = key;
|
|
10795
|
-
}
|
|
10796
|
-
}
|
|
10797
|
-
if (oldestKey) cache.delete(oldestKey);
|
|
10798
|
-
}
|
|
10799
11936
|
return {
|
|
10800
11937
|
/** Get cached HTML for a key, or undefined if not cached or expired */
|
|
10801
11938
|
get(key) {
|
|
@@ -10814,7 +11951,7 @@ function createSSRCache(config) {
|
|
|
10814
11951
|
},
|
|
10815
11952
|
/** Cache an HTML string with an optional TTL override */
|
|
10816
11953
|
set(key, html2, ttl) {
|
|
10817
|
-
|
|
11954
|
+
if (!makeRoomFor(cache, key, maxSize, isValid)) return;
|
|
10818
11955
|
cache.set(key, {
|
|
10819
11956
|
html: html2,
|
|
10820
11957
|
timestamp: Date.now(),
|
|
@@ -10847,25 +11984,30 @@ function createSSRCache(config) {
|
|
|
10847
11984
|
}
|
|
10848
11985
|
};
|
|
10849
11986
|
}
|
|
11987
|
+
var DEFER_IDLE_TIMEOUT_MS = 2e3;
|
|
10850
11988
|
function deferNonCritical(tasks) {
|
|
10851
11989
|
if (tasks.length === 0) return;
|
|
10852
|
-
const schedule = typeof requestIdleCallback !== "undefined" ?
|
|
11990
|
+
const schedule = typeof requestIdleCallback !== "undefined" ? (cb) => {
|
|
11991
|
+
requestIdleCallback(cb, { timeout: DEFER_IDLE_TIMEOUT_MS });
|
|
11992
|
+
} : (cb) => {
|
|
11993
|
+
setTimeout(cb, 1);
|
|
11994
|
+
};
|
|
10853
11995
|
const queue = [...tasks];
|
|
10854
11996
|
let index = 0;
|
|
10855
11997
|
function processNext(deadline) {
|
|
11998
|
+
let ranOne = false;
|
|
10856
11999
|
while (index < queue.length) {
|
|
10857
|
-
if (deadline && deadline.timeRemaining() < 1) {
|
|
12000
|
+
if (ranOne && deadline && deadline.timeRemaining() < 1) {
|
|
10858
12001
|
schedule(processNext);
|
|
10859
12002
|
return;
|
|
10860
12003
|
}
|
|
10861
12004
|
try {
|
|
10862
12005
|
queue[index]();
|
|
10863
12006
|
} catch (e) {
|
|
10864
|
-
|
|
10865
|
-
console.error("[Startup] Deferred task failed:", e);
|
|
10866
|
-
}
|
|
12007
|
+
reportError(e, { phase: "scheduler", name: "deferNonCritical" });
|
|
10867
12008
|
}
|
|
10868
12009
|
index++;
|
|
12010
|
+
ranOne = true;
|
|
10869
12011
|
}
|
|
10870
12012
|
}
|
|
10871
12013
|
schedule(processNext);
|
|
@@ -11886,20 +13028,20 @@ function createErrorReporter(options) {
|
|
|
11886
13028
|
const logToConsole = options?.logToConsole ?? true;
|
|
11887
13029
|
const maxErrors = options?.maxErrors ?? 500;
|
|
11888
13030
|
const errors = [];
|
|
11889
|
-
function report(error,
|
|
13031
|
+
function report(error, context) {
|
|
11890
13032
|
let sibuError;
|
|
11891
13033
|
if (error instanceof SibuError) {
|
|
11892
13034
|
sibuError = error;
|
|
11893
|
-
if (
|
|
11894
|
-
sibuError.component =
|
|
13035
|
+
if (context?.component && !sibuError.component) {
|
|
13036
|
+
sibuError.component = context.component;
|
|
11895
13037
|
}
|
|
11896
|
-
if (
|
|
11897
|
-
sibuError.props =
|
|
13038
|
+
if (context?.props && !sibuError.props) {
|
|
13039
|
+
sibuError.props = context.props;
|
|
11898
13040
|
}
|
|
11899
13041
|
} else {
|
|
11900
13042
|
sibuError = new SibuError(error.message, {
|
|
11901
|
-
component:
|
|
11902
|
-
props:
|
|
13043
|
+
component: context?.component,
|
|
13044
|
+
props: context?.props,
|
|
11903
13045
|
cause: error
|
|
11904
13046
|
});
|
|
11905
13047
|
sibuError.stack = error.stack;
|
|
@@ -11955,9 +13097,9 @@ function withErrorTracking(name, component, reporter) {
|
|
|
11955
13097
|
}
|
|
11956
13098
|
};
|
|
11957
13099
|
}
|
|
11958
|
-
function formatError(error,
|
|
13100
|
+
function formatError(error, context, seen = /* @__PURE__ */ new Set([error])) {
|
|
11959
13101
|
const lines = [];
|
|
11960
|
-
const componentLabel =
|
|
13102
|
+
const componentLabel = context?.component ?? (error instanceof SibuError ? error.component : void 0);
|
|
11961
13103
|
if (componentLabel) {
|
|
11962
13104
|
lines.push(`[SibuJS:${componentLabel}] ${error.name}: ${error.message}`);
|
|
11963
13105
|
} else {
|
|
@@ -11984,7 +13126,7 @@ function formatError(error, context2, seen = /* @__PURE__ */ new Set([error])) {
|
|
|
11984
13126
|
seen.add(cause);
|
|
11985
13127
|
lines.push("");
|
|
11986
13128
|
lines.push("Caused by:");
|
|
11987
|
-
lines.push(formatError(cause,
|
|
13129
|
+
lines.push(formatError(cause, context, seen));
|
|
11988
13130
|
}
|
|
11989
13131
|
return lines.join("\n");
|
|
11990
13132
|
}
|
|
@@ -12142,9 +13284,21 @@ function createDevtoolsOverlay(options) {
|
|
|
12142
13284
|
var COUNTER_KEY = /* @__PURE__ */ Symbol.for("sibujs.createId.v1");
|
|
12143
13285
|
var _counter = globalThis[COUNTER_KEY] ?? (globalThis[COUNTER_KEY] = { n: 0 });
|
|
12144
13286
|
function createId(prefix = "sibu") {
|
|
13287
|
+
const request = getRequestStore();
|
|
13288
|
+
if (request) {
|
|
13289
|
+
request.idCounter = (request.idCounter ?? 0) + 1;
|
|
13290
|
+
return `${prefix}-${request.idCounter}`;
|
|
13291
|
+
}
|
|
12145
13292
|
_counter.n++;
|
|
12146
13293
|
return `${prefix}-${_counter.n}`;
|
|
12147
13294
|
}
|
|
13295
|
+
function idSegment(key) {
|
|
13296
|
+
let out = "";
|
|
13297
|
+
for (const ch of String(key)) {
|
|
13298
|
+
out += /[A-Za-z0-9-]/.test(ch) ? ch : `_${(ch.codePointAt(0) ?? 0).toString(16)}_`;
|
|
13299
|
+
}
|
|
13300
|
+
return out;
|
|
13301
|
+
}
|
|
12148
13302
|
|
|
12149
13303
|
// src/core/signals/watch.ts
|
|
12150
13304
|
function watch(getter, callback) {
|
|
@@ -12249,7 +13403,7 @@ function combobox(options) {
|
|
|
12249
13403
|
els.input.setAttribute("role", "combobox");
|
|
12250
13404
|
els.input.setAttribute("aria-autocomplete", "list");
|
|
12251
13405
|
els.input.setAttribute("aria-controls", listboxId);
|
|
12252
|
-
const fxTeardown =
|
|
13406
|
+
const fxTeardown = domBinding(() => {
|
|
12253
13407
|
const open2 = isOpen();
|
|
12254
13408
|
els.input.setAttribute("aria-expanded", open2 ? "true" : "false");
|
|
12255
13409
|
els.listbox.hidden = !open2;
|
|
@@ -12267,7 +13421,7 @@ function combobox(options) {
|
|
|
12267
13421
|
}
|
|
12268
13422
|
if (activeId) els.input.setAttribute("aria-activedescendant", activeId);
|
|
12269
13423
|
else els.input.removeAttribute("aria-activedescendant");
|
|
12270
|
-
});
|
|
13424
|
+
}, els.input);
|
|
12271
13425
|
const onInput = () => {
|
|
12272
13426
|
setQuery(els.input.value);
|
|
12273
13427
|
open();
|
|
@@ -12315,8 +13469,11 @@ function combobox(options) {
|
|
|
12315
13469
|
els.input.addEventListener("focus", onFocus);
|
|
12316
13470
|
els.input.addEventListener("blur", onBlur);
|
|
12317
13471
|
els.listbox.addEventListener("mousedown", onListboxPointerDown);
|
|
13472
|
+
let tornDown = false;
|
|
12318
13473
|
const teardown = () => {
|
|
12319
|
-
|
|
13474
|
+
if (tornDown) return;
|
|
13475
|
+
tornDown = true;
|
|
13476
|
+
if (boundComboboxes.get(els.input) === teardown) boundComboboxes.delete(els.input);
|
|
12320
13477
|
fxTeardown();
|
|
12321
13478
|
els.input.removeEventListener("input", onInput);
|
|
12322
13479
|
els.input.removeEventListener("keydown", onKey);
|
|
@@ -12361,11 +13518,23 @@ function combobox(options) {
|
|
|
12361
13518
|
};
|
|
12362
13519
|
}
|
|
12363
13520
|
|
|
13521
|
+
// src/widgets/attributeSnapshot.ts
|
|
13522
|
+
function snapshotAttributes(el, names) {
|
|
13523
|
+
const previous2 = names.map((name) => [name, el.getAttribute(name)]);
|
|
13524
|
+
return () => {
|
|
13525
|
+
for (const [name, value] of previous2) {
|
|
13526
|
+
if (value === null) el.removeAttribute(name);
|
|
13527
|
+
else el.setAttribute(name, value);
|
|
13528
|
+
}
|
|
13529
|
+
};
|
|
13530
|
+
}
|
|
13531
|
+
|
|
12364
13532
|
// src/widgets/Tabs.ts
|
|
12365
13533
|
var boundTablists = /* @__PURE__ */ new WeakMap();
|
|
12366
13534
|
function tabs(options) {
|
|
12367
13535
|
const { tabs: tabDefs, defaultTab } = options;
|
|
12368
|
-
const
|
|
13536
|
+
const firstEnabled = tabDefs.find((t) => !t.disabled)?.id ?? "";
|
|
13537
|
+
const initialTab = defaultTab !== void 0 && tabDefs.some((t) => t.id === defaultTab && !t.disabled) ? defaultTab : firstEnabled;
|
|
12369
13538
|
const [activeTab, setActiveTabState] = signal(initialTab);
|
|
12370
13539
|
function setActiveTab(id) {
|
|
12371
13540
|
const tab = tabDefs.find((t) => t.id === id);
|
|
@@ -12412,58 +13581,29 @@ function tabs(options) {
|
|
|
12412
13581
|
function bind(els) {
|
|
12413
13582
|
const existing = boundTablists.get(els.tablist);
|
|
12414
13583
|
if (existing) return existing;
|
|
12415
|
-
const restore = [];
|
|
12416
|
-
const prevTablistRole = els.tablist.getAttribute("role");
|
|
13584
|
+
const restore = [snapshotAttributes(els.tablist, ["role"])];
|
|
12417
13585
|
els.tablist.setAttribute("role", "tablist");
|
|
12418
|
-
|
|
12419
|
-
if (prevTablistRole === null) els.tablist.removeAttribute("role");
|
|
12420
|
-
else els.tablist.setAttribute("role", prevTablistRole);
|
|
12421
|
-
});
|
|
13586
|
+
const idPrefix = createId("sibu-tabs");
|
|
12422
13587
|
for (const def of tabDefs) {
|
|
12423
13588
|
const tabEl = els.tabs[def.id];
|
|
12424
13589
|
if (!tabEl) continue;
|
|
12425
|
-
|
|
12426
|
-
|
|
12427
|
-
|
|
12428
|
-
const prevControls = tabEl.getAttribute("aria-controls");
|
|
13590
|
+
restore.push(
|
|
13591
|
+
snapshotAttributes(tabEl, ["role", "id", "aria-disabled", "aria-controls", "aria-selected", "tabindex"])
|
|
13592
|
+
);
|
|
12429
13593
|
tabEl.setAttribute("role", "tab");
|
|
12430
|
-
tabEl.
|
|
13594
|
+
if (!tabEl.id) tabEl.id = `${idPrefix}-tab-${idSegment(def.id)}`;
|
|
12431
13595
|
if (def.disabled) tabEl.setAttribute("aria-disabled", "true");
|
|
13596
|
+
else tabEl.removeAttribute("aria-disabled");
|
|
12432
13597
|
const panelEl = els.panels?.[def.id];
|
|
12433
|
-
let prevPanelRole = null;
|
|
12434
|
-
let prevPanelId = "";
|
|
12435
|
-
let prevPanelLabelledBy = null;
|
|
12436
13598
|
if (panelEl) {
|
|
12437
|
-
|
|
12438
|
-
prevPanelId = panelEl.id;
|
|
12439
|
-
prevPanelLabelledBy = panelEl.getAttribute("aria-labelledby");
|
|
13599
|
+
restore.push(snapshotAttributes(panelEl, ["role", "id", "aria-labelledby", "hidden"]));
|
|
12440
13600
|
panelEl.setAttribute("role", "tabpanel");
|
|
12441
|
-
panelEl.
|
|
12442
|
-
panelEl.setAttribute("aria-labelledby",
|
|
12443
|
-
tabEl.setAttribute("aria-controls",
|
|
13601
|
+
if (!panelEl.id) panelEl.id = `${idPrefix}-panel-${idSegment(def.id)}`;
|
|
13602
|
+
panelEl.setAttribute("aria-labelledby", tabEl.id);
|
|
13603
|
+
tabEl.setAttribute("aria-controls", panelEl.id);
|
|
12444
13604
|
}
|
|
12445
|
-
restore.push(() => {
|
|
12446
|
-
if (prevRole === null) tabEl.removeAttribute("role");
|
|
12447
|
-
else tabEl.setAttribute("role", prevRole);
|
|
12448
|
-
if (prevId === "") tabEl.removeAttribute("id");
|
|
12449
|
-
else tabEl.id = prevId;
|
|
12450
|
-
if (prevDisabled === null) tabEl.removeAttribute("aria-disabled");
|
|
12451
|
-
else tabEl.setAttribute("aria-disabled", prevDisabled);
|
|
12452
|
-
if (prevControls === null) tabEl.removeAttribute("aria-controls");
|
|
12453
|
-
else tabEl.setAttribute("aria-controls", prevControls);
|
|
12454
|
-
tabEl.removeAttribute("aria-selected");
|
|
12455
|
-
tabEl.removeAttribute("tabindex");
|
|
12456
|
-
if (panelEl) {
|
|
12457
|
-
if (prevPanelRole === null) panelEl.removeAttribute("role");
|
|
12458
|
-
else panelEl.setAttribute("role", prevPanelRole);
|
|
12459
|
-
if (prevPanelId === "") panelEl.removeAttribute("id");
|
|
12460
|
-
else panelEl.id = prevPanelId;
|
|
12461
|
-
if (prevPanelLabelledBy === null) panelEl.removeAttribute("aria-labelledby");
|
|
12462
|
-
else panelEl.setAttribute("aria-labelledby", prevPanelLabelledBy);
|
|
12463
|
-
}
|
|
12464
|
-
});
|
|
12465
13605
|
}
|
|
12466
|
-
const fxTeardown =
|
|
13606
|
+
const fxTeardown = domBinding(() => {
|
|
12467
13607
|
const active = activeTab();
|
|
12468
13608
|
for (const def of tabDefs) {
|
|
12469
13609
|
const tabEl = els.tabs[def.id];
|
|
@@ -12474,7 +13614,7 @@ function tabs(options) {
|
|
|
12474
13614
|
const panelEl = els.panels?.[def.id];
|
|
12475
13615
|
if (panelEl) panelEl.hidden = !isAct;
|
|
12476
13616
|
}
|
|
12477
|
-
});
|
|
13617
|
+
}, els.tablist);
|
|
12478
13618
|
const onKey = (e) => {
|
|
12479
13619
|
if (e.key === "ArrowRight" || e.key === "ArrowDown") {
|
|
12480
13620
|
e.preventDefault();
|
|
@@ -12511,7 +13651,10 @@ function tabs(options) {
|
|
|
12511
13651
|
tabEl.addEventListener("click", fn);
|
|
12512
13652
|
clickHandlers.push({ el: tabEl, fn });
|
|
12513
13653
|
}
|
|
13654
|
+
let tornDown = false;
|
|
12514
13655
|
const teardown = () => {
|
|
13656
|
+
if (tornDown) return;
|
|
13657
|
+
tornDown = true;
|
|
12515
13658
|
boundTablists.delete(els.tablist);
|
|
12516
13659
|
fxTeardown();
|
|
12517
13660
|
els.tablist.removeEventListener("keydown", onKey);
|
|
@@ -12537,7 +13680,10 @@ function tabs(options) {
|
|
|
12537
13680
|
var boundAccordions = /* @__PURE__ */ new WeakMap();
|
|
12538
13681
|
function accordion(options) {
|
|
12539
13682
|
const { items: itemDefs, multiple = false, defaultExpanded = [] } = options;
|
|
12540
|
-
const
|
|
13683
|
+
const knownIds = new Set(itemDefs.map((item) => item.id));
|
|
13684
|
+
const validDefaults = defaultExpanded.filter((id) => knownIds.has(id));
|
|
13685
|
+
const initialExpanded = multiple ? validDefaults : validDefaults.slice(0, 1);
|
|
13686
|
+
const [expandedIds, setExpandedIds] = signal(new Set(initialExpanded));
|
|
12541
13687
|
const items = derived(
|
|
12542
13688
|
() => itemDefs.map((item) => ({
|
|
12543
13689
|
...item,
|
|
@@ -12588,42 +13734,22 @@ function accordion(options) {
|
|
|
12588
13734
|
if (existing) return existing;
|
|
12589
13735
|
}
|
|
12590
13736
|
const restore = [];
|
|
13737
|
+
const idPrefix = createId("sibu-accordion");
|
|
12591
13738
|
for (const item of itemDefs) {
|
|
12592
13739
|
const trig = els.triggers[item.id];
|
|
12593
13740
|
const panel = els.panels[item.id];
|
|
12594
13741
|
if (!trig) continue;
|
|
12595
|
-
|
|
12596
|
-
|
|
12597
|
-
trig.id = `sibu-accordion-trigger-${item.id}`;
|
|
12598
|
-
let prevPanelRole = null;
|
|
12599
|
-
let prevPanelId = "";
|
|
12600
|
-
let prevPanelLabelledBy = null;
|
|
13742
|
+
restore.push(snapshotAttributes(trig, ["id", "aria-controls", "aria-expanded"]));
|
|
13743
|
+
if (!trig.id) trig.id = `${idPrefix}-trigger-${idSegment(item.id)}`;
|
|
12601
13744
|
if (panel) {
|
|
12602
|
-
|
|
12603
|
-
prevPanelId = panel.id;
|
|
12604
|
-
prevPanelLabelledBy = panel.getAttribute("aria-labelledby");
|
|
13745
|
+
restore.push(snapshotAttributes(panel, ["role", "id", "aria-labelledby", "hidden"]));
|
|
12605
13746
|
panel.setAttribute("role", "region");
|
|
12606
|
-
panel.id =
|
|
13747
|
+
if (!panel.id) panel.id = `${idPrefix}-panel-${idSegment(item.id)}`;
|
|
12607
13748
|
panel.setAttribute("aria-labelledby", trig.id);
|
|
12608
13749
|
trig.setAttribute("aria-controls", panel.id);
|
|
12609
13750
|
}
|
|
12610
|
-
restore.push(() => {
|
|
12611
|
-
if (prevTrigId === "") trig.removeAttribute("id");
|
|
12612
|
-
else trig.id = prevTrigId;
|
|
12613
|
-
if (prevTrigControls === null) trig.removeAttribute("aria-controls");
|
|
12614
|
-
else trig.setAttribute("aria-controls", prevTrigControls);
|
|
12615
|
-
trig.removeAttribute("aria-expanded");
|
|
12616
|
-
if (panel) {
|
|
12617
|
-
if (prevPanelRole === null) panel.removeAttribute("role");
|
|
12618
|
-
else panel.setAttribute("role", prevPanelRole);
|
|
12619
|
-
if (prevPanelId === "") panel.removeAttribute("id");
|
|
12620
|
-
else panel.id = prevPanelId;
|
|
12621
|
-
if (prevPanelLabelledBy === null) panel.removeAttribute("aria-labelledby");
|
|
12622
|
-
else panel.setAttribute("aria-labelledby", prevPanelLabelledBy);
|
|
12623
|
-
}
|
|
12624
|
-
});
|
|
12625
13751
|
}
|
|
12626
|
-
const fxTeardown =
|
|
13752
|
+
const fxTeardown = domBinding(() => {
|
|
12627
13753
|
const ids = expandedIds();
|
|
12628
13754
|
for (const item of itemDefs) {
|
|
12629
13755
|
const trig = els.triggers[item.id];
|
|
@@ -12633,7 +13759,7 @@ function accordion(options) {
|
|
|
12633
13759
|
trig.setAttribute("aria-expanded", expanded ? "true" : "false");
|
|
12634
13760
|
if (panel) panel.hidden = !expanded;
|
|
12635
13761
|
}
|
|
12636
|
-
});
|
|
13762
|
+
}, idempotencyKey);
|
|
12637
13763
|
const handlers = [];
|
|
12638
13764
|
for (const item of itemDefs) {
|
|
12639
13765
|
const trig = els.triggers[item.id];
|
|
@@ -12649,7 +13775,10 @@ function accordion(options) {
|
|
|
12649
13775
|
trig.addEventListener("keydown", key);
|
|
12650
13776
|
handlers.push({ el: trig, click, key });
|
|
12651
13777
|
}
|
|
13778
|
+
let tornDown = false;
|
|
12652
13779
|
const teardown = () => {
|
|
13780
|
+
if (tornDown) return;
|
|
13781
|
+
tornDown = true;
|
|
12653
13782
|
if (idempotencyKey) boundAccordions.delete(idempotencyKey);
|
|
12654
13783
|
fxTeardown();
|
|
12655
13784
|
for (const { el, click, key } of handlers) {
|
|
@@ -12708,11 +13837,11 @@ function popover() {
|
|
|
12708
13837
|
}
|
|
12709
13838
|
els.popover.setAttribute("aria-labelledby", els.labelledBy.id);
|
|
12710
13839
|
}
|
|
12711
|
-
const fxTeardown =
|
|
13840
|
+
const fxTeardown = domBinding(() => {
|
|
12712
13841
|
const open2 = isOpen();
|
|
12713
13842
|
els.trigger.setAttribute("aria-expanded", open2 ? "true" : "false");
|
|
12714
13843
|
els.popover.hidden = !open2;
|
|
12715
|
-
});
|
|
13844
|
+
}, els.trigger);
|
|
12716
13845
|
const onTriggerClick = (e) => {
|
|
12717
13846
|
e.preventDefault();
|
|
12718
13847
|
toggle();
|
|
@@ -12735,8 +13864,11 @@ function popover() {
|
|
|
12735
13864
|
els.popover.addEventListener("keydown", onKey);
|
|
12736
13865
|
els.trigger.addEventListener("keydown", onKey);
|
|
12737
13866
|
document.addEventListener("pointerdown", onDocPointer);
|
|
13867
|
+
let tornDown = false;
|
|
12738
13868
|
const teardown = () => {
|
|
12739
|
-
|
|
13869
|
+
if (tornDown) return;
|
|
13870
|
+
tornDown = true;
|
|
13871
|
+
if (boundPopovers.get(els.trigger) === teardown) boundPopovers.delete(els.trigger);
|
|
12740
13872
|
fxTeardown();
|
|
12741
13873
|
els.trigger.removeEventListener("click", onTriggerClick);
|
|
12742
13874
|
els.popover.removeEventListener("keydown", onKey);
|
|
@@ -12854,7 +13986,7 @@ function select2(options) {
|
|
|
12854
13986
|
els.listbox.setAttribute("aria-multiselectable", multiple ? "true" : "false");
|
|
12855
13987
|
if (els.listbox.tabIndex < 0) els.listbox.tabIndex = 0;
|
|
12856
13988
|
const toStr = els.itemToString ?? itemToString ?? ((it) => String(it));
|
|
12857
|
-
const fxTeardown =
|
|
13989
|
+
const fxTeardown = domBinding(() => {
|
|
12858
13990
|
const idx = highlightedIndex();
|
|
12859
13991
|
const sel = selectedItems();
|
|
12860
13992
|
let activeId = "";
|
|
@@ -12864,13 +13996,14 @@ function select2(options) {
|
|
|
12864
13996
|
if (!optEl.id) optEl.id = `${listboxId}-opt-${i2}`;
|
|
12865
13997
|
optEl.setAttribute("role", "option");
|
|
12866
13998
|
optEl.setAttribute("aria-selected", sel.includes(items[i2]) ? "true" : "false");
|
|
12867
|
-
|
|
13999
|
+
const disabled = isItemDisabled(items[i2]);
|
|
14000
|
+
if (disabled) optEl.setAttribute("aria-disabled", "true");
|
|
12868
14001
|
else optEl.removeAttribute("aria-disabled");
|
|
12869
|
-
if (i2 === idx) activeId = optEl.id;
|
|
14002
|
+
if (i2 === idx && !disabled) activeId = optEl.id;
|
|
12870
14003
|
}
|
|
12871
14004
|
if (activeId) els.listbox.setAttribute("aria-activedescendant", activeId);
|
|
12872
14005
|
else els.listbox.removeAttribute("aria-activedescendant");
|
|
12873
|
-
});
|
|
14006
|
+
}, els.listbox);
|
|
12874
14007
|
let typeBuffer = "";
|
|
12875
14008
|
let typeTimer = null;
|
|
12876
14009
|
const onKey = (e) => {
|
|
@@ -12882,10 +14015,12 @@ function select2(options) {
|
|
|
12882
14015
|
highlightPrev();
|
|
12883
14016
|
} else if (e.key === "Home") {
|
|
12884
14017
|
e.preventDefault();
|
|
12885
|
-
|
|
14018
|
+
const first = nextEnabled(-1, 1);
|
|
14019
|
+
if (first !== -1) setHighlightedIndex(first);
|
|
12886
14020
|
} else if (e.key === "End") {
|
|
12887
14021
|
e.preventDefault();
|
|
12888
|
-
|
|
14022
|
+
const last = nextEnabled(items.length, -1);
|
|
14023
|
+
if (last !== -1) setHighlightedIndex(last);
|
|
12889
14024
|
} else if (e.key === "Enter" || e.key === " ") {
|
|
12890
14025
|
if (highlightedIndex() >= 0) {
|
|
12891
14026
|
e.preventDefault();
|
|
@@ -12903,8 +14038,11 @@ function select2(options) {
|
|
|
12903
14038
|
}
|
|
12904
14039
|
};
|
|
12905
14040
|
els.listbox.addEventListener("keydown", onKey);
|
|
14041
|
+
let tornDown = false;
|
|
12906
14042
|
const teardown = () => {
|
|
12907
|
-
|
|
14043
|
+
if (tornDown) return;
|
|
14044
|
+
tornDown = true;
|
|
14045
|
+
if (boundSelects.get(els.listbox) === teardown) boundSelects.delete(els.listbox);
|
|
12908
14046
|
fxTeardown();
|
|
12909
14047
|
els.listbox.removeEventListener("keydown", onKey);
|
|
12910
14048
|
if (typeTimer !== null) clearTimeout(typeTimer);
|
|
@@ -12990,9 +14128,9 @@ function tooltip(options) {
|
|
|
12990
14128
|
els.tooltip.id = id;
|
|
12991
14129
|
const prevDescribedBy = els.trigger.getAttribute("aria-describedby");
|
|
12992
14130
|
els.trigger.setAttribute("aria-describedby", prevDescribedBy ? `${prevDescribedBy} ${id}` : id);
|
|
12993
|
-
const fxTeardown =
|
|
14131
|
+
const fxTeardown = domBinding(() => {
|
|
12994
14132
|
els.tooltip.hidden = !isVisible();
|
|
12995
|
-
});
|
|
14133
|
+
}, els.trigger);
|
|
12996
14134
|
const onTriggerEnter = () => show();
|
|
12997
14135
|
const onTriggerLeave = () => scheduleHide();
|
|
12998
14136
|
const onTooltipEnter = () => {
|
|
@@ -13017,8 +14155,11 @@ function tooltip(options) {
|
|
|
13017
14155
|
els.trigger.addEventListener("keydown", onKey);
|
|
13018
14156
|
els.tooltip.addEventListener("pointerenter", onTooltipEnter);
|
|
13019
14157
|
els.tooltip.addEventListener("pointerleave", onTooltipLeave);
|
|
14158
|
+
let tornDown = false;
|
|
13020
14159
|
const teardown = () => {
|
|
13021
|
-
|
|
14160
|
+
if (tornDown) return;
|
|
14161
|
+
tornDown = true;
|
|
14162
|
+
if (boundTriggers.get(els.trigger) === teardown) boundTriggers.delete(els.trigger);
|
|
13022
14163
|
fxTeardown();
|
|
13023
14164
|
els.trigger.removeEventListener("pointerenter", onTriggerEnter);
|
|
13024
14165
|
els.trigger.removeEventListener("pointerleave", onTriggerLeave);
|
|
@@ -13056,7 +14197,8 @@ function fileUpload(options) {
|
|
|
13056
14197
|
const [isDragOver, setDragOver] = signal(false);
|
|
13057
14198
|
function isAccepted(file) {
|
|
13058
14199
|
if (!accept) return true;
|
|
13059
|
-
const acceptedTypes = accept.split(",").map((t) => t.trim().toLowerCase());
|
|
14200
|
+
const acceptedTypes = accept.split(",").map((t) => t.trim().toLowerCase()).filter((t) => t.length > 0);
|
|
14201
|
+
if (acceptedTypes.length === 0) return true;
|
|
13060
14202
|
const fileName = file.name.toLowerCase();
|
|
13061
14203
|
const fileType = file.type.toLowerCase();
|
|
13062
14204
|
return acceptedTypes.some((pattern2) => {
|
|
@@ -13085,16 +14227,17 @@ function fileUpload(options) {
|
|
|
13085
14227
|
}
|
|
13086
14228
|
validFiles.push(file);
|
|
13087
14229
|
}
|
|
14230
|
+
const committed = multiple ? validFiles : validFiles.slice(-1);
|
|
13088
14231
|
batch(() => {
|
|
13089
14232
|
setErrors(newErrors);
|
|
13090
|
-
if (
|
|
14233
|
+
if (committed.length > 0) {
|
|
13091
14234
|
if (multiple) {
|
|
13092
|
-
setFiles((prev) => [...prev, ...
|
|
14235
|
+
setFiles((prev) => [...prev, ...committed]);
|
|
13093
14236
|
} else {
|
|
13094
|
-
setFiles(
|
|
14237
|
+
setFiles(committed);
|
|
13095
14238
|
}
|
|
13096
14239
|
if (onFiles) {
|
|
13097
|
-
onFiles(
|
|
14240
|
+
onFiles(committed);
|
|
13098
14241
|
}
|
|
13099
14242
|
}
|
|
13100
14243
|
});
|
|
@@ -13118,8 +14261,15 @@ function fileUpload(options) {
|
|
|
13118
14261
|
if (existing) return existing;
|
|
13119
14262
|
const id = createId("sibu-fileupload");
|
|
13120
14263
|
const restore = [];
|
|
14264
|
+
const prevAccept = els.input.getAttribute("accept");
|
|
14265
|
+
const prevMultiple = els.input.hasAttribute("multiple");
|
|
13121
14266
|
if (accept) els.input.accept = accept;
|
|
13122
14267
|
els.input.multiple = multiple;
|
|
14268
|
+
restore.push(() => {
|
|
14269
|
+
if (prevAccept === null) els.input.removeAttribute("accept");
|
|
14270
|
+
else els.input.setAttribute("accept", prevAccept);
|
|
14271
|
+
els.input.multiple = prevMultiple;
|
|
14272
|
+
});
|
|
13123
14273
|
let hintId = null;
|
|
13124
14274
|
if (els.hint) {
|
|
13125
14275
|
const assignedHintId = !els.hint.id;
|
|
@@ -13140,6 +14290,7 @@ function fileUpload(options) {
|
|
|
13140
14290
|
if (els.errorRegion) {
|
|
13141
14291
|
const prevRole = els.errorRegion.getAttribute("role");
|
|
13142
14292
|
const prevLive = els.errorRegion.getAttribute("aria-live");
|
|
14293
|
+
const prevText = els.errorRegion.textContent;
|
|
13143
14294
|
els.errorRegion.setAttribute("role", "status");
|
|
13144
14295
|
els.errorRegion.setAttribute("aria-live", "polite");
|
|
13145
14296
|
restore.push(() => {
|
|
@@ -13147,12 +14298,14 @@ function fileUpload(options) {
|
|
|
13147
14298
|
else els.errorRegion.setAttribute("role", prevRole);
|
|
13148
14299
|
if (prevLive === null) els.errorRegion.removeAttribute("aria-live");
|
|
13149
14300
|
else els.errorRegion.setAttribute("aria-live", prevLive);
|
|
14301
|
+
els.errorRegion.textContent = prevText;
|
|
13150
14302
|
});
|
|
13151
14303
|
}
|
|
13152
14304
|
if (els.dropZone) {
|
|
13153
14305
|
const prevDzRole = els.dropZone.getAttribute("role");
|
|
13154
14306
|
const prevDzLabel = els.dropZone.getAttribute("aria-label");
|
|
13155
14307
|
const prevDzTabindex = els.dropZone.hasAttribute("tabindex") ? els.dropZone.getAttribute("tabindex") : null;
|
|
14308
|
+
const prevDzDragOver = els.dropZone.getAttribute("data-drag-over");
|
|
13156
14309
|
els.dropZone.setAttribute("role", "button");
|
|
13157
14310
|
els.dropZone.setAttribute("aria-label", "File drop zone \u2014 click or press Enter to browse");
|
|
13158
14311
|
if (els.dropZone.tabIndex < 0) els.dropZone.tabIndex = 0;
|
|
@@ -13163,13 +14316,15 @@ function fileUpload(options) {
|
|
|
13163
14316
|
else els.dropZone.setAttribute("aria-label", prevDzLabel);
|
|
13164
14317
|
if (prevDzTabindex === null) els.dropZone.removeAttribute("tabindex");
|
|
13165
14318
|
else els.dropZone.setAttribute("tabindex", prevDzTabindex);
|
|
14319
|
+
if (prevDzDragOver === null) els.dropZone.removeAttribute("data-drag-over");
|
|
14320
|
+
else els.dropZone.setAttribute("data-drag-over", prevDzDragOver);
|
|
13166
14321
|
});
|
|
13167
14322
|
}
|
|
13168
|
-
const fxTeardown =
|
|
14323
|
+
const fxTeardown = domBinding(() => {
|
|
13169
14324
|
const errs = errors();
|
|
13170
14325
|
if (els.errorRegion) els.errorRegion.textContent = errs.join(". ");
|
|
13171
14326
|
if (els.dropZone) els.dropZone.setAttribute("data-drag-over", isDragOver() ? "true" : "false");
|
|
13172
|
-
});
|
|
14327
|
+
}, els.input);
|
|
13173
14328
|
const onChange = () => {
|
|
13174
14329
|
if (els.input.files) addFiles(els.input.files);
|
|
13175
14330
|
};
|
|
@@ -13198,7 +14353,10 @@ function fileUpload(options) {
|
|
|
13198
14353
|
els.dropZone.addEventListener("dragleave", onDragLeave);
|
|
13199
14354
|
els.dropZone.addEventListener("drop", onDrop);
|
|
13200
14355
|
}
|
|
14356
|
+
let tornDown = false;
|
|
13201
14357
|
const teardown = () => {
|
|
14358
|
+
if (tornDown) return;
|
|
14359
|
+
tornDown = true;
|
|
13202
14360
|
boundFileUploads.delete(els.input);
|
|
13203
14361
|
fxTeardown();
|
|
13204
14362
|
els.input.removeEventListener("change", onChange);
|
|
@@ -13227,12 +14385,15 @@ function fileUpload(options) {
|
|
|
13227
14385
|
}
|
|
13228
14386
|
|
|
13229
14387
|
// src/widgets/contentEditable.ts
|
|
14388
|
+
function toInertText(html2) {
|
|
14389
|
+
return stripHtml(String(html2)).replace(/<(?=[a-z!/?])/gi, "<");
|
|
14390
|
+
}
|
|
13230
14391
|
function contentEditable(element) {
|
|
13231
14392
|
const [content, setContentInternal] = signal("");
|
|
13232
14393
|
const [isFocused, setFocused] = signal(false);
|
|
13233
14394
|
function setContent(input2) {
|
|
13234
14395
|
if (typeof input2 === "string") {
|
|
13235
|
-
setContentInternal(input2);
|
|
14396
|
+
setContentInternal(toInertText(input2));
|
|
13236
14397
|
return;
|
|
13237
14398
|
}
|
|
13238
14399
|
if (typeof input2.text === "string") {
|
|
@@ -13241,7 +14402,7 @@ function contentEditable(element) {
|
|
|
13241
14402
|
}
|
|
13242
14403
|
if (typeof input2.html === "string") {
|
|
13243
14404
|
const shouldSanitize = input2.sanitize !== false;
|
|
13244
|
-
setContentInternal(shouldSanitize ?
|
|
14405
|
+
setContentInternal(shouldSanitize ? toInertText(input2.html) : input2.html);
|
|
13245
14406
|
return;
|
|
13246
14407
|
}
|
|
13247
14408
|
setContentInternal("");
|
|
@@ -13253,7 +14414,7 @@ function contentEditable(element) {
|
|
|
13253
14414
|
const range = selection.getRangeAt(0);
|
|
13254
14415
|
if (element && !element.contains(range.commonAncestorContainer)) return;
|
|
13255
14416
|
const ancestor = range.commonAncestorContainer;
|
|
13256
|
-
const existingWrap =
|
|
14417
|
+
const existingWrap = findWrapperWithinEditor(
|
|
13257
14418
|
ancestor instanceof HTMLElement ? ancestor : ancestor.parentElement,
|
|
13258
14419
|
tagName
|
|
13259
14420
|
);
|
|
@@ -13294,14 +14455,19 @@ function contentEditable(element) {
|
|
|
13294
14455
|
selection.addRange(newRange);
|
|
13295
14456
|
}
|
|
13296
14457
|
}
|
|
13297
|
-
function
|
|
14458
|
+
function findWrapperWithinEditor(el, tagName) {
|
|
13298
14459
|
const upper = tagName.toUpperCase();
|
|
13299
14460
|
while (el) {
|
|
14461
|
+
if (el === element || isEditingHost(el)) return null;
|
|
13300
14462
|
if (el.tagName === upper) return el;
|
|
13301
14463
|
el = el.parentElement;
|
|
13302
14464
|
}
|
|
13303
14465
|
return null;
|
|
13304
14466
|
}
|
|
14467
|
+
function isEditingHost(el) {
|
|
14468
|
+
const attr = el.getAttribute("contenteditable");
|
|
14469
|
+
return attr !== null && attr.toLowerCase() !== "false";
|
|
14470
|
+
}
|
|
13305
14471
|
function bold() {
|
|
13306
14472
|
wrapSelection("strong");
|
|
13307
14473
|
}
|
|
@@ -13437,15 +14603,36 @@ function datePicker(options) {
|
|
|
13437
14603
|
els.grid.setAttribute("role", "grid");
|
|
13438
14604
|
if (els.grid.tabIndex < 0) els.grid.tabIndex = 0;
|
|
13439
14605
|
let pendingFocus = false;
|
|
13440
|
-
const
|
|
14606
|
+
const touchedCells = /* @__PURE__ */ new Map();
|
|
14607
|
+
const restoreAttr = (el, name, value) => {
|
|
14608
|
+
if (value === null) el.removeAttribute(name);
|
|
14609
|
+
else el.setAttribute(name, value);
|
|
14610
|
+
};
|
|
14611
|
+
const restoreCell = (cell, snap) => {
|
|
14612
|
+
restoreAttr(cell, "role", snap.role);
|
|
14613
|
+
restoreAttr(cell, "aria-selected", snap.selected);
|
|
14614
|
+
restoreAttr(cell, "aria-disabled", snap.disabled);
|
|
14615
|
+
restoreAttr(cell, "tabindex", snap.tabindex);
|
|
14616
|
+
};
|
|
14617
|
+
const fxTeardown = domBinding(() => {
|
|
13441
14618
|
const sel = selectedDate();
|
|
13442
14619
|
const view = viewDate();
|
|
13443
14620
|
const days = daysInMonth();
|
|
13444
14621
|
els.grid.setAttribute("aria-label", view.toLocaleDateString(void 0, { month: "long", year: "numeric" }));
|
|
13445
14622
|
let viewCell = null;
|
|
14623
|
+
const displayed = /* @__PURE__ */ new Set();
|
|
13446
14624
|
for (const d of days) {
|
|
13447
14625
|
const cell = els.cell(d.date);
|
|
13448
14626
|
if (!cell) continue;
|
|
14627
|
+
displayed.add(cell);
|
|
14628
|
+
if (!touchedCells.has(cell)) {
|
|
14629
|
+
touchedCells.set(cell, {
|
|
14630
|
+
role: cell.getAttribute("role"),
|
|
14631
|
+
selected: cell.getAttribute("aria-selected"),
|
|
14632
|
+
disabled: cell.getAttribute("aria-disabled"),
|
|
14633
|
+
tabindex: cell.getAttribute("tabindex")
|
|
14634
|
+
});
|
|
14635
|
+
}
|
|
13449
14636
|
cell.setAttribute("role", "gridcell");
|
|
13450
14637
|
cell.setAttribute("aria-selected", sel && isSameCalendarDay(sel, d.date) ? "true" : "false");
|
|
13451
14638
|
if (d.isDisabled) cell.setAttribute("aria-disabled", "true");
|
|
@@ -13454,11 +14641,17 @@ function datePicker(options) {
|
|
|
13454
14641
|
cell.tabIndex = isView ? 0 : -1;
|
|
13455
14642
|
if (isView) viewCell = cell;
|
|
13456
14643
|
}
|
|
14644
|
+
for (const [cell, snap] of touchedCells) {
|
|
14645
|
+
if (!displayed.has(cell)) {
|
|
14646
|
+
restoreCell(cell, snap);
|
|
14647
|
+
touchedCells.delete(cell);
|
|
14648
|
+
}
|
|
14649
|
+
}
|
|
13457
14650
|
if (pendingFocus && viewCell && typeof viewCell.focus === "function") {
|
|
13458
14651
|
pendingFocus = false;
|
|
13459
14652
|
viewCell.focus();
|
|
13460
14653
|
}
|
|
13461
|
-
});
|
|
14654
|
+
}, els.grid);
|
|
13462
14655
|
function isSameCalendarDay(a2, b2) {
|
|
13463
14656
|
return a2.getFullYear() === b2.getFullYear() && a2.getMonth() === b2.getMonth() && a2.getDate() === b2.getDate();
|
|
13464
14657
|
}
|
|
@@ -13513,8 +14706,11 @@ function datePicker(options) {
|
|
|
13513
14706
|
}
|
|
13514
14707
|
};
|
|
13515
14708
|
els.grid.addEventListener("keydown", onKey);
|
|
14709
|
+
let tornDown = false;
|
|
13516
14710
|
const teardown = () => {
|
|
13517
|
-
|
|
14711
|
+
if (tornDown) return;
|
|
14712
|
+
tornDown = true;
|
|
14713
|
+
if (boundDatePickers.get(els.grid) === teardown) boundDatePickers.delete(els.grid);
|
|
13518
14714
|
fxTeardown();
|
|
13519
14715
|
els.grid.removeEventListener("keydown", onKey);
|
|
13520
14716
|
if (prevGridRole === null) els.grid.removeAttribute("role");
|
|
@@ -13523,6 +14719,8 @@ function datePicker(options) {
|
|
|
13523
14719
|
else els.grid.setAttribute("tabindex", prevGridTabIndex);
|
|
13524
14720
|
if (prevGridLabel === null) els.grid.removeAttribute("aria-label");
|
|
13525
14721
|
else els.grid.setAttribute("aria-label", prevGridLabel);
|
|
14722
|
+
for (const [cell, snap] of touchedCells) restoreCell(cell, snap);
|
|
14723
|
+
touchedCells.clear();
|
|
13526
14724
|
};
|
|
13527
14725
|
boundDatePickers.set(els.grid, teardown);
|
|
13528
14726
|
return teardown;
|
|
@@ -13625,53 +14823,119 @@ function zustandAdapter(options) {
|
|
|
13625
14823
|
}
|
|
13626
14824
|
|
|
13627
14825
|
// src/ecosystem/ui/componentAdapter.ts
|
|
14826
|
+
var _themeLayers = globalSingleton(
|
|
14827
|
+
/* @__PURE__ */ Symbol.for("sibujs.themeLayers.v1"),
|
|
14828
|
+
() => /* @__PURE__ */ new WeakMap()
|
|
14829
|
+
);
|
|
14830
|
+
function commitThemeProperty(root, name, record) {
|
|
14831
|
+
const top = record.layers[record.layers.length - 1];
|
|
14832
|
+
if (top) {
|
|
14833
|
+
root.style.setProperty(name, top.value);
|
|
14834
|
+
return;
|
|
14835
|
+
}
|
|
14836
|
+
_themeLayers.get(root)?.delete(name);
|
|
14837
|
+
if (record.original.value === "") root.style.removeProperty(name);
|
|
14838
|
+
else root.style.setProperty(name, record.original.value, record.original.priority);
|
|
14839
|
+
}
|
|
14840
|
+
function setThemeLayer(root, name, handle, value) {
|
|
14841
|
+
let properties = _themeLayers.get(root);
|
|
14842
|
+
if (!properties) _themeLayers.set(root, properties = /* @__PURE__ */ new Map());
|
|
14843
|
+
let record = properties.get(name);
|
|
14844
|
+
if (!record) {
|
|
14845
|
+
record = {
|
|
14846
|
+
original: { value: root.style.getPropertyValue(name), priority: root.style.getPropertyPriority(name) },
|
|
14847
|
+
layers: []
|
|
14848
|
+
};
|
|
14849
|
+
properties.set(name, record);
|
|
14850
|
+
}
|
|
14851
|
+
const layer = record.layers.find((l) => l.handle === handle);
|
|
14852
|
+
if (layer) layer.value = value;
|
|
14853
|
+
else record.layers.push({ handle, value });
|
|
14854
|
+
commitThemeProperty(root, name, record);
|
|
14855
|
+
}
|
|
14856
|
+
function removeThemeLayer(root, name, handle) {
|
|
14857
|
+
const record = _themeLayers.get(root)?.get(name);
|
|
14858
|
+
if (!record) return;
|
|
14859
|
+
const index = record.layers.findIndex((l) => l.handle === handle);
|
|
14860
|
+
if (index === -1) return;
|
|
14861
|
+
record.layers.splice(index, 1);
|
|
14862
|
+
commitThemeProperty(root, name, record);
|
|
14863
|
+
}
|
|
14864
|
+
function ownString(map2, key) {
|
|
14865
|
+
if (!map2 || key === void 0 || !Object.hasOwn(map2, key)) return void 0;
|
|
14866
|
+
const value = map2[key];
|
|
14867
|
+
return typeof value === "string" ? value : void 0;
|
|
14868
|
+
}
|
|
13628
14869
|
function createTheme(initial) {
|
|
13629
14870
|
const [getConfig, setConfig] = signal(initial);
|
|
13630
14871
|
function resolveClass(component, variant) {
|
|
13631
14872
|
const config = getConfig();
|
|
13632
14873
|
const overrideKey = variant ? `${component}-${variant}` : component;
|
|
13633
|
-
|
|
13634
|
-
|
|
13635
|
-
}
|
|
14874
|
+
const override = ownString(config.classOverrides, overrideKey);
|
|
14875
|
+
if (override) return override;
|
|
13636
14876
|
const base2 = `${config.prefix}-${component}`;
|
|
13637
14877
|
return variant ? `${base2} ${config.prefix}-${component}--${variant}` : base2;
|
|
13638
14878
|
}
|
|
13639
14879
|
function setTheme(partial) {
|
|
13640
14880
|
setConfig((prev) => ({ ...prev, ...partial }));
|
|
13641
14881
|
}
|
|
13642
|
-
|
|
14882
|
+
function applyTo(root) {
|
|
14883
|
+
const handle = {};
|
|
14884
|
+
let applied = /* @__PURE__ */ new Set();
|
|
14885
|
+
const stop2 = effect(() => {
|
|
14886
|
+
const variables = getConfig().variables ?? {};
|
|
14887
|
+
const next = new Set(Object.keys(variables));
|
|
14888
|
+
for (const name of applied) {
|
|
14889
|
+
if (!next.has(name)) removeThemeLayer(root, name, handle);
|
|
14890
|
+
}
|
|
14891
|
+
for (const [name, value] of Object.entries(variables)) setThemeLayer(root, name, handle, value);
|
|
14892
|
+
applied = next;
|
|
14893
|
+
});
|
|
14894
|
+
let released = false;
|
|
14895
|
+
return () => {
|
|
14896
|
+
if (released) return;
|
|
14897
|
+
released = true;
|
|
14898
|
+
stop2();
|
|
14899
|
+
for (const name of applied) removeThemeLayer(root, name, handle);
|
|
14900
|
+
applied.clear();
|
|
14901
|
+
};
|
|
14902
|
+
}
|
|
14903
|
+
return { config: getConfig, setTheme, resolveClass, applyTo };
|
|
13643
14904
|
}
|
|
13644
14905
|
function componentAdapter(config) {
|
|
13645
14906
|
const theme = createTheme({ prefix: config.prefix });
|
|
14907
|
+
const reprefix = (cls, prefix) => prefix !== config.prefix && cls.startsWith(`${config.prefix}-`) ? `${prefix}-${cls.slice(config.prefix.length + 1)}` : cls;
|
|
13646
14908
|
const components = {};
|
|
13647
14909
|
for (const [name, mapping] of Object.entries(config.components)) {
|
|
13648
14910
|
const factory = tagFactory(mapping.tag || "div");
|
|
13649
|
-
components[name] = (props = {}) => {
|
|
14911
|
+
components[name] = (props = {}, children) => {
|
|
13650
14912
|
const { variant, size, class: userClass, ...rest } = props;
|
|
13651
|
-
const
|
|
13652
|
-
|
|
13653
|
-
|
|
13654
|
-
|
|
13655
|
-
|
|
13656
|
-
|
|
13657
|
-
|
|
13658
|
-
|
|
13659
|
-
|
|
13660
|
-
|
|
13661
|
-
|
|
13662
|
-
|
|
13663
|
-
}
|
|
13664
|
-
|
|
13665
|
-
|
|
13666
|
-
|
|
13667
|
-
|
|
13668
|
-
|
|
14913
|
+
const themeClasses = () => {
|
|
14914
|
+
const current = theme.config();
|
|
14915
|
+
const overrides = current.classOverrides ?? {};
|
|
14916
|
+
const pick = (key, fallback) => Object.hasOwn(overrides, key) ? overrides[key] : reprefix(fallback, current.prefix);
|
|
14917
|
+
const classes = [pick(name, mapping.baseClass)];
|
|
14918
|
+
const variantClass = ownString(mapping.variants, variant);
|
|
14919
|
+
if (variant && variantClass) {
|
|
14920
|
+
classes.push(pick(`${name}-${variant}`, variantClass));
|
|
14921
|
+
}
|
|
14922
|
+
const sizeClass = ownString(mapping.sizes, size);
|
|
14923
|
+
if (size && sizeClass) {
|
|
14924
|
+
classes.push(pick(`${name}-${size}`, sizeClass));
|
|
14925
|
+
}
|
|
14926
|
+
return classes.filter(Boolean).join(" ");
|
|
14927
|
+
};
|
|
14928
|
+
const finalClass = () => {
|
|
14929
|
+
const base2 = themeClasses();
|
|
14930
|
+
const extra = typeof userClass === "function" ? userClass() : userClass;
|
|
14931
|
+
return typeof extra === "string" && extra ? `${base2} ${extra}` : base2;
|
|
14932
|
+
};
|
|
13669
14933
|
const mergedProps = {
|
|
13670
14934
|
...mapping.defaultProps,
|
|
13671
14935
|
...rest,
|
|
13672
14936
|
class: finalClass
|
|
13673
14937
|
};
|
|
13674
|
-
return factory(mergedProps);
|
|
14938
|
+
return children === void 0 ? factory(mergedProps) : factory(mergedProps, children);
|
|
13675
14939
|
};
|
|
13676
14940
|
}
|
|
13677
14941
|
return { name: config.name, components, theme };
|
|
@@ -13886,6 +15150,8 @@ var materialAdapter = componentAdapter(materialConfig);
|
|
|
13886
15150
|
Features,
|
|
13887
15151
|
FocusTrap,
|
|
13888
15152
|
Head,
|
|
15153
|
+
MigrationStorageError,
|
|
15154
|
+
PluginInstallCancelledError,
|
|
13889
15155
|
Priority,
|
|
13890
15156
|
RenderProp,
|
|
13891
15157
|
SibuError,
|
|
@@ -13894,6 +15160,7 @@ var materialAdapter = componentAdapter(materialConfig);
|
|
|
13894
15160
|
VirtualList,
|
|
13895
15161
|
__resetDialogStack,
|
|
13896
15162
|
__resetQueryCache,
|
|
15163
|
+
__resetSpeechCoordinator,
|
|
13897
15164
|
accordion,
|
|
13898
15165
|
animate,
|
|
13899
15166
|
animationFrame,
|
|
@@ -14029,6 +15296,7 @@ var materialAdapter = componentAdapter(materialConfig);
|
|
|
14029
15296
|
isDangerousMetaRefresh,
|
|
14030
15297
|
isDebugEnabled,
|
|
14031
15298
|
isHMRAvailable,
|
|
15299
|
+
isPluginInstallCancelledError,
|
|
14032
15300
|
isWasmCached,
|
|
14033
15301
|
island,
|
|
14034
15302
|
keyboard,
|
|
@@ -14096,6 +15364,7 @@ var materialAdapter = componentAdapter(materialConfig);
|
|
|
14096
15364
|
renderToStream,
|
|
14097
15365
|
renderToString,
|
|
14098
15366
|
renderToSuspenseStream,
|
|
15367
|
+
renderWithLoader,
|
|
14099
15368
|
required,
|
|
14100
15369
|
resetIdCounter,
|
|
14101
15370
|
resetPlugins,
|
|
@@ -14167,6 +15436,7 @@ var materialAdapter = componentAdapter(materialConfig);
|
|
|
14167
15436
|
withBoundary,
|
|
14168
15437
|
withDefaults,
|
|
14169
15438
|
withErrorTracking,
|
|
15439
|
+
withLoader,
|
|
14170
15440
|
withProps,
|
|
14171
15441
|
withRetry,
|
|
14172
15442
|
withScopedStyle,
|