sibujs 4.14.0 → 4.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/dist/browser.cjs +297 -45
  2. package/dist/browser.js +6 -7
  3. package/dist/build.cjs +2189 -573
  4. package/dist/build.js +16 -15
  5. package/dist/cdn.dev.global.js +13 -12
  6. package/dist/cdn.full.dev.global.js +14 -13
  7. package/dist/cdn.full.global.js +12 -12
  8. package/dist/cdn.global.js +12 -12
  9. package/dist/{chunk-RVR5NPFL.js → chunk-2VKTFA7C.js} +1 -1
  10. package/dist/{chunk-7ILEHTVX.js → chunk-4AEFGRYW.js} +1 -1
  11. package/dist/{chunk-4TQDTWWN.js → chunk-6IV5ZRG6.js} +5 -7
  12. package/dist/{chunk-GVAMIU6K.js → chunk-75EAQH3U.js} +2 -2
  13. package/dist/{chunk-TLS4NVIB.js → chunk-7JO7DPSS.js} +4 -4
  14. package/dist/{chunk-SVULV7O4.js → chunk-AQH7WDSE.js} +6 -8
  15. package/dist/{chunk-S37PZD6I.js → chunk-BF3WBJJQ.js} +60 -10
  16. package/dist/{chunk-LJMX4SQ7.js → chunk-BG4BP44S.js} +3 -3
  17. package/dist/{chunk-N7A6FKWW.js → chunk-D44TAGCT.js} +2 -2
  18. package/dist/{chunk-CCKUNHVU.js → chunk-DAEXQJQA.js} +1 -1
  19. package/dist/chunk-DNCQDFJJ.js +22 -0
  20. package/dist/{chunk-BKZ5N6NK.js → chunk-DNCT2UXB.js} +4 -4
  21. package/dist/{chunk-BOYKGGVD.js → chunk-DRWOD7RZ.js} +4 -4
  22. package/dist/chunk-DS5V2PRE.js +64 -0
  23. package/dist/{chunk-VM2U5LEL.js → chunk-EHSJESRN.js} +595 -123
  24. package/dist/{chunk-MIRKTVH4.js → chunk-GFM5WWPU.js} +252 -5
  25. package/dist/{chunk-52XFPGSN.js → chunk-HTPOIAAL.js} +1 -1
  26. package/dist/{chunk-3HEX6QJQ.js → chunk-I2R5QALY.js} +2 -4
  27. package/dist/{chunk-4FJSAUKB.js → chunk-IUBV5WO5.js} +1 -1
  28. package/dist/{chunk-A454RAEK.js → chunk-KIDETDMU.js} +5 -7
  29. package/dist/{chunk-JTFQ7IL4.js → chunk-KPAXG5IR.js} +7 -9
  30. package/dist/{chunk-AE32RGWX.js → chunk-LGUXYHTZ.js} +3 -3
  31. package/dist/{chunk-Y4LUM2XS.js → chunk-LQWLPQOK.js} +6 -8
  32. package/dist/{chunk-CNPT6NKV.js → chunk-MINLMJUY.js} +48 -9
  33. package/dist/{chunk-BNXRWZZV.js → chunk-OURTGOJT.js} +8 -10
  34. package/dist/{chunk-F67F77IA.js → chunk-TQ24Y3IV.js} +2 -2
  35. package/dist/{chunk-2TTRW2TE.js → chunk-UM3M5PXS.js} +8 -8
  36. package/dist/{chunk-CJ7KS3DF.js → chunk-VSTX3XSX.js} +205 -15
  37. package/dist/{chunk-HQIAL7F2.js → chunk-XPDZ2LDR.js} +2 -2
  38. package/dist/{chunk-UUIKJJIK.js → chunk-Y7JM7GY2.js} +5 -7
  39. package/dist/{chunk-QS6GMWDD.js → chunk-YAFITBOK.js} +1269 -162
  40. package/dist/data.cjs +285 -33
  41. package/dist/data.js +6 -7
  42. package/dist/devtools.cjs +289 -39
  43. package/dist/devtools.js +5 -6
  44. package/dist/{dispose-EIHHHDC7.js → dispose-3WDBYJMH.js} +3 -1
  45. package/dist/ecosystem.cjs +345 -61
  46. package/dist/ecosystem.d.cts +1 -1
  47. package/dist/ecosystem.d.ts +1 -1
  48. package/dist/ecosystem.js +10 -10
  49. package/dist/extras.cjs +568 -248
  50. package/dist/extras.d.cts +1 -1
  51. package/dist/extras.d.ts +1 -1
  52. package/dist/extras.js +27 -27
  53. package/dist/index.cjs +2134 -515
  54. package/dist/index.d.cts +628 -211
  55. package/dist/index.d.ts +628 -211
  56. package/dist/index.js +22 -15
  57. package/dist/motion.cjs +286 -30
  58. package/dist/motion.js +4 -4
  59. package/dist/patterns.cjs +301 -43
  60. package/dist/patterns.js +6 -6
  61. package/dist/performance.cjs +286 -36
  62. package/dist/performance.js +9 -9
  63. package/dist/plugins.cjs +1237 -291
  64. package/dist/plugins.d.cts +3 -1
  65. package/dist/plugins.d.ts +3 -1
  66. package/dist/plugins.js +20 -19
  67. package/dist/{renderRoute-fxgsm2Ir.d.ts → renderRoute-B84MONaO.d.cts} +2 -2
  68. package/dist/{renderRoute-DP20XwMS.d.cts → renderRoute-_yxPuEQY.d.ts} +2 -2
  69. package/dist/{routeHead-CE9SV-cH.d.cts → routeHead-DLxlq15W.d.cts} +94 -0
  70. package/dist/{routeHead-DzVxPviY.d.ts → routeHead-w8nANZ3M.d.ts} +94 -0
  71. package/dist/{ssr-NECEU4X4.js → ssr-EF3IUHTE.js} +6 -6
  72. package/dist/ssr-dom.cjs +64 -9
  73. package/dist/ssr-dom.d.cts +2 -0
  74. package/dist/ssr-dom.d.ts +2 -0
  75. package/dist/ssr-dom.js +2 -1
  76. package/dist/ssr.cjs +850 -170
  77. package/dist/ssr.d.cts +5 -3
  78. package/dist/ssr.d.ts +5 -3
  79. package/dist/ssr.js +16 -15
  80. package/dist/{tagFactory-DkytnJws.d.cts → tagFactory-BfEh69VF.d.cts} +7 -0
  81. package/dist/{tagFactory-Bnd_Nph9.d.ts → tagFactory-pSYiLYyh.d.ts} +7 -0
  82. package/dist/testing.cjs +817 -132
  83. package/dist/testing.d.cts +4 -2
  84. package/dist/testing.d.ts +4 -2
  85. package/dist/testing.js +18 -17
  86. package/dist/track-core-0edROAF5.d.ts +187 -0
  87. package/dist/track-core-DN5fYLWi.d.cts +187 -0
  88. package/dist/ui.cjs +293 -43
  89. package/dist/ui.js +10 -12
  90. package/dist/widgets.cjs +285 -27
  91. package/dist/widgets.js +7 -7
  92. package/package.json +1 -1
  93. package/dist/chunk-7ZHH77QA.js +0 -9
package/dist/testing.cjs CHANGED
@@ -71,6 +71,12 @@ __export(testing_exports, {
71
71
  });
72
72
  module.exports = __toCommonJS(testing_exports);
73
73
 
74
+ // src/utils/globalSingleton.ts
75
+ function globalSingleton(key, create) {
76
+ const g = globalThis;
77
+ return g[key] ?? (g[key] = create());
78
+ }
79
+
74
80
  // src/core/dev.ts
75
81
  var DEV = typeof __SIBU_DEV__ !== "undefined" ? !!__SIBU_DEV__ : typeof globalThis.__SIBU_DEV__ !== "undefined" ? !!globalThis.__SIBU_DEV__ : (
76
82
  // safe default: off in browser, on in test/dev Node
@@ -303,7 +309,12 @@ function beginHydration() {
303
309
  }
304
310
 
305
311
  // src/core/rendering/dispose.ts
306
- var elementDisposers = /* @__PURE__ */ new WeakMap();
312
+ var state2 = globalSingleton(/* @__PURE__ */ Symbol.for("sibujs.disposers.v1"), () => ({
313
+ disposers: /* @__PURE__ */ new WeakMap(),
314
+ captures: [],
315
+ bindings: { count: 0 }
316
+ }));
317
+ var elementDisposers = state2.disposers;
307
318
  var MAX_DRAIN_TEARDOWNS = 1e4;
308
319
  function reportDrainRunaway(label, executed, remaining) {
309
320
  if (typeof console === "undefined") return;
@@ -312,13 +323,13 @@ function reportDrainRunaway(label, executed, remaining) {
312
323
  { executed, remaining }
313
324
  );
314
325
  }
315
- var activeBindingCount = 0;
326
+ var bindings = state2.bindings;
316
327
  function resolveCapture(capture) {
317
328
  let frame = capture;
318
329
  while (frame?.closed) frame = frame.forwardTo;
319
330
  return frame ?? null;
320
331
  }
321
- var registrationCaptures = [];
332
+ var registrationCaptures = state2.captures;
322
333
  function currentDisposerCapture() {
323
334
  return resolveCapture(registrationCaptures[registrationCaptures.length - 1]);
324
335
  }
@@ -337,7 +348,7 @@ function registerDisposer(node, teardown) {
337
348
  elementDisposers.set(node, disposers);
338
349
  }
339
350
  disposers.push(teardown);
340
- if (DEV) activeBindingCount++;
351
+ if (DEV) bindings.count++;
341
352
  const capture = resolveCapture(registrationCaptures[registrationCaptures.length - 1]);
342
353
  if (capture) capture.entries.push([node, teardown]);
343
354
  }
@@ -361,17 +372,17 @@ function disposeNodeOwn(node) {
361
372
  let executed = 0;
362
373
  let runaway = false;
363
374
  while (!runaway) {
364
- const pending = elementDisposers.get(node);
365
- if (!pending || pending.length === 0) break;
366
- const snapshot = pending.slice();
375
+ const pending2 = elementDisposers.get(node);
376
+ if (!pending2 || pending2.length === 0) break;
377
+ const snapshot = pending2.slice();
367
378
  elementDisposers.delete(node);
368
- if (DEV) activeBindingCount -= snapshot.length;
379
+ if (DEV) bindings.count -= snapshot.length;
369
380
  for (let i = 0; i < snapshot.length; i++) {
370
381
  if (executed >= MAX_DRAIN_TEARDOWNS) {
371
382
  const rest = snapshot.slice(i);
372
383
  const added = elementDisposers.get(node);
373
384
  elementDisposers.set(node, added ? rest.concat(added) : rest);
374
- if (DEV) activeBindingCount += rest.length;
385
+ if (DEV) bindings.count += rest.length;
375
386
  reportDrainRunaway("dispose", executed, rest.length + (added?.length ?? 0));
376
387
  runaway = true;
377
388
  break;
@@ -411,12 +422,6 @@ function replaceChildrenSafely(parent, ...next) {
411
422
  parent.replaceChildren(...next);
412
423
  }
413
424
 
414
- // src/utils/globalSingleton.ts
415
- function globalSingleton(key, create) {
416
- const g = globalThis;
417
- return g[key] ?? (g[key] = create());
418
- }
419
-
420
425
  // src/reactivity/track-core.ts
421
426
  var POOL_MAX = 4096;
422
427
  var nodePool = [];
@@ -580,6 +585,201 @@ function bindOwnerScope(fn) {
580
585
  return (...args) => runWithOwnerScope(scope, () => fn(...args));
581
586
  }
582
587
  var currentStructOwner = null;
588
+ var frozenOwners = 0;
589
+ var ACTIVE = 0;
590
+ var PAUSED = 1;
591
+ var ENDED = 2;
592
+ var NOOP = () => {
593
+ };
594
+ var skippedWhileHeld = /* @__PURE__ */ new Set();
595
+ var waiters = /* @__PURE__ */ new Set();
596
+ var heldRoots = /* @__PURE__ */ new Set();
597
+ function ownerState(tok) {
598
+ let state5 = ACTIVE;
599
+ for (let t = tok; t !== null; ) {
600
+ const o = t.sub;
601
+ if (o === null) return ENDED;
602
+ if (o._frozen === true) state5 = PAUSED;
603
+ t = o._owner ?? null;
604
+ }
605
+ return state5;
606
+ }
607
+ var endWatchers = /* @__PURE__ */ new Set();
608
+ var stateWatchers = /* @__PURE__ */ new Set();
609
+ var stateCheckQueued = false;
610
+ function queueStateCheck() {
611
+ if (stateCheckQueued || stateWatchers.size === 0) return;
612
+ stateCheckQueued = true;
613
+ queueMicrotask(() => {
614
+ stateCheckQueued = false;
615
+ for (const watcher of [...stateWatchers]) {
616
+ if (!stateWatchers.has(watcher)) continue;
617
+ const state5 = watcher.check.state();
618
+ if (state5 === ENDED) stateWatchers.delete(watcher);
619
+ if (state5 === ENDED || state5 === watcher.last) continue;
620
+ watcher.last = state5;
621
+ try {
622
+ watcher.listener(state5);
623
+ } catch (err) {
624
+ reportError(err, { phase: "effect" });
625
+ }
626
+ }
627
+ });
628
+ }
629
+ var ALWAYS_ACTIVE = Object.assign(() => false, {
630
+ state: () => ACTIVE,
631
+ wait: (onActive) => {
632
+ onActive();
633
+ return NOOP;
634
+ },
635
+ onEnd: () => NOOP,
636
+ run: (fn) => fn(),
637
+ onChange: () => NOOP,
638
+ within: () => false
639
+ });
640
+ function captureFrozen() {
641
+ const tok = currentStructOwner;
642
+ if (tok === null) return ALWAYS_ACTIVE;
643
+ const state5 = () => ownerState(tok);
644
+ const check = Object.assign(() => state5() !== ACTIVE, {
645
+ state: state5,
646
+ wait: (onActive, onEnd) => {
647
+ const now = state5();
648
+ if (now !== PAUSED) {
649
+ (now === ACTIVE ? onActive : onEnd)();
650
+ return NOOP;
651
+ }
652
+ const waiter = { check, onActive, onEnd };
653
+ waiters.add(waiter);
654
+ return () => {
655
+ waiters.delete(waiter);
656
+ };
657
+ },
658
+ onEnd: (onEnd) => {
659
+ if (state5() === ENDED) {
660
+ onEnd();
661
+ return NOOP;
662
+ }
663
+ const watcher = { check, onActive: NOOP, onEnd };
664
+ endWatchers.add(watcher);
665
+ return () => {
666
+ endWatchers.delete(watcher);
667
+ };
668
+ },
669
+ run: (fn) => {
670
+ const prev = currentStructOwner;
671
+ currentStructOwner = tok.sub === null ? null : tok;
672
+ try {
673
+ return fn();
674
+ } finally {
675
+ currentStructOwner = prev;
676
+ }
677
+ },
678
+ onChange: (listener) => {
679
+ const last = state5();
680
+ if (last === ENDED) return NOOP;
681
+ const watcher = { check, last, listener };
682
+ stateWatchers.add(watcher);
683
+ return () => {
684
+ stateWatchers.delete(watcher);
685
+ };
686
+ },
687
+ within: (owner) => {
688
+ const target = owner.run(() => currentStructOwner);
689
+ if (target === null) return false;
690
+ for (let t = tok; t !== null; ) {
691
+ if (t === target) return true;
692
+ const o = t.sub;
693
+ if (o === null) return false;
694
+ t = o._owner ?? null;
695
+ }
696
+ return false;
697
+ }
698
+ });
699
+ return check;
700
+ }
701
+ function holdSubtree(root) {
702
+ heldRoots.add(root);
703
+ return () => {
704
+ if (heldRoots.delete(root)) settleHeld();
705
+ };
706
+ }
707
+ function isHeld(sub) {
708
+ if (frozenOwners !== 0 && hasFrozenOwner(sub)) return true;
709
+ if (heldRoots.size !== 0) {
710
+ const node = sub._errorNode;
711
+ if (node != null) {
712
+ for (const root of heldRoots) if (root.contains(node)) return true;
713
+ }
714
+ }
715
+ return false;
716
+ }
717
+ function notifyEnded() {
718
+ for (const watcher of stateWatchers) if (watcher.check.state() === ENDED) stateWatchers.delete(watcher);
719
+ let ended = null;
720
+ for (const watcher of endWatchers) {
721
+ if (watcher.check.state() !== ENDED) continue;
722
+ endWatchers.delete(watcher);
723
+ (ended ?? (ended = [])).push(watcher);
724
+ }
725
+ if (ended === null) return;
726
+ for (const watcher of ended) {
727
+ try {
728
+ watcher.onEnd();
729
+ } catch (err) {
730
+ reportError(err, { phase: "cleanup" });
731
+ }
732
+ }
733
+ }
734
+ function dropReleasedSkipped() {
735
+ for (const sub of skippedWhileHeld) {
736
+ if (sub._disposed === true || sub.depsHead == null) skippedWhileHeld.delete(sub);
737
+ }
738
+ }
739
+ function settleHeld() {
740
+ for (const sub of skippedWhileHeld) {
741
+ if (sub._disposed === true) skippedWhileHeld.delete(sub);
742
+ else if (!isHeld(sub)) {
743
+ skippedWhileHeld.delete(sub);
744
+ if (!pendingSet.has(sub)) {
745
+ pendingSet.add(sub);
746
+ pendingQueue.push(sub);
747
+ }
748
+ }
749
+ }
750
+ if (frozenOwners === 0 && heldRoots.size === 0) skippedWhileHeld.clear();
751
+ let ready = null;
752
+ for (const waiter of waiters) {
753
+ if (waiter.check.state() === PAUSED) continue;
754
+ waiters.delete(waiter);
755
+ (ready ?? (ready = [])).push(waiter);
756
+ }
757
+ if (ready !== null) {
758
+ const settle = ready;
759
+ queueMicrotask(() => {
760
+ for (const waiter of settle) {
761
+ const state5 = waiter.check.state();
762
+ if (state5 === PAUSED) waiters.add(waiter);
763
+ else
764
+ try {
765
+ (state5 === ACTIVE ? waiter.onActive : waiter.onEnd)();
766
+ } catch (err) {
767
+ reportError(err, { phase: "effect" });
768
+ }
769
+ }
770
+ });
771
+ }
772
+ if (pendingQueue.length > 0) drainNotificationQueue();
773
+ }
774
+ function hasFrozenOwner(sub) {
775
+ for (let t = sub._owner ?? null; t !== null; ) {
776
+ const o = t.sub;
777
+ if (o === null) return false;
778
+ if (o._frozen === true) return true;
779
+ t = o._owner ?? null;
780
+ }
781
+ return false;
782
+ }
583
783
  var subscriberEpochCounter = 0;
584
784
  function retrack(effectFn, subscriber) {
585
785
  const prev = currentSubscriber;
@@ -687,6 +887,20 @@ function structuralBinding(commit, ownerNode) {
687
887
  } finally {
688
888
  currentStructOwner = prev;
689
889
  }
890
+ },
891
+ freeze: () => {
892
+ const s = sub;
893
+ if (s._disposed || s._frozen) return;
894
+ s._frozen = true;
895
+ frozenOwners++;
896
+ queueStateCheck();
897
+ },
898
+ thaw: () => {
899
+ if (!sub._frozen) return;
900
+ sub._frozen = false;
901
+ frozenOwners--;
902
+ queueStateCheck();
903
+ settleHeld();
690
904
  }
691
905
  };
692
906
  }
@@ -715,20 +929,34 @@ function createBinding(commit, ownerNode, structural) {
715
929
  subscriber._errorNode = ownerNode;
716
930
  subscriber._tok = null;
717
931
  subscriber._owner = null;
932
+ subscriber._frozen = false;
718
933
  if (structural) subscriber._tok = { sub: subscriber };
719
934
  try {
720
935
  run();
721
936
  } catch (err) {
722
937
  subscriber._disposed = true;
723
938
  subscriber._errorNode = void 0;
724
- if (subscriber._tok != null) subscriber._tok.sub = null;
939
+ if (subscriber._tok != null) {
940
+ subscriber._tok.sub = null;
941
+ if (endWatchers.size !== 0 || stateWatchers.size !== 0) notifyEnded();
942
+ }
725
943
  cleanup(subscriber);
726
944
  throw err;
727
945
  }
728
946
  subscriber._dispose = () => {
729
947
  subscriber._disposed = true;
948
+ const wasFrozen = subscriber._frozen === true;
949
+ if (wasFrozen) {
950
+ subscriber._frozen = false;
951
+ frozenOwners--;
952
+ }
730
953
  subscriber._errorNode = void 0;
731
- if (subscriber._tok != null) subscriber._tok.sub = null;
954
+ if (subscriber._tok != null) {
955
+ subscriber._tok.sub = null;
956
+ if (endWatchers.size !== 0 || stateWatchers.size !== 0) notifyEnded();
957
+ if (skippedWhileHeld.size !== 0) dropReleasedSkipped();
958
+ if (wasFrozen || waiters.size !== 0) settleHeld();
959
+ }
732
960
  cleanup(subscriber);
733
961
  };
734
962
  return subscriber;
@@ -838,6 +1066,10 @@ function runPendingOwners(sub) {
838
1066
  }
839
1067
  }
840
1068
  function runQueued(sub) {
1069
+ if ((frozenOwners !== 0 || heldRoots.size !== 0) && isHeld(sub)) {
1070
+ skippedWhileHeld.add(sub);
1071
+ return;
1072
+ }
841
1073
  if (quarantined.size > 0 && quarantined.has(sub)) return;
842
1074
  if (sub._hasComputedDep === true && !depsChanged(sub)) return;
843
1075
  if (tickRepeat(sub)) {
@@ -985,7 +1217,7 @@ function forEachSubscriber(signal2, visit) {
985
1217
  }
986
1218
 
987
1219
  // src/reactivity/track.ts
988
- var _runtimeVersion = true ? "4.14.0" : "dev";
1220
+ var _runtimeVersion = true ? "4.15.0" : "dev";
989
1221
  var REGISTRY_KEY = /* @__PURE__ */ Symbol.for("sibujs.reactive.v1");
990
1222
  function resolveReactiveApi() {
991
1223
  const g = globalThis;
@@ -1021,6 +1253,8 @@ function resolveReactiveApi() {
1021
1253
  runWithOwnerScope,
1022
1254
  bindOwnerScope,
1023
1255
  structuralBinding,
1256
+ captureFrozen,
1257
+ holdSubtree,
1024
1258
  version: _runtimeVersion
1025
1259
  };
1026
1260
  g[REGISTRY_KEY] = local;
@@ -1048,6 +1282,22 @@ var getOwnerScope2 = API.getOwnerScope ?? getOwnerScope;
1048
1282
  var runWithOwnerScope2 = API.runWithOwnerScope ?? runWithOwnerScope;
1049
1283
  var bindOwnerScope2 = API.bindOwnerScope ?? bindOwnerScope;
1050
1284
  var structuralBinding2 = API.structuralBinding ?? ((commit, ownerNode) => ({ stop: API.reactiveBinding(commit, ownerNode), run: (fn) => fn() }));
1285
+ var captureFrozen2 = API.captureFrozen ?? (() => Object.assign(() => false, {
1286
+ state: () => 0,
1287
+ wait: (onActive) => {
1288
+ onActive();
1289
+ return () => {
1290
+ };
1291
+ },
1292
+ onEnd: () => () => {
1293
+ },
1294
+ run: (fn) => fn(),
1295
+ onChange: () => () => {
1296
+ },
1297
+ within: () => false
1298
+ }));
1299
+ var holdSubtree2 = API.holdSubtree ?? (() => () => {
1300
+ });
1051
1301
 
1052
1302
  // src/core/devtoolsHook.ts
1053
1303
  function emitDevtools(hook, event, payload) {
@@ -1132,6 +1382,10 @@ function requestSlot(name, create) {
1132
1382
  if (!slots.has(name) && create) slots.set(name, create());
1133
1383
  return slots.get(name);
1134
1384
  }
1385
+ var PRERENDER_HOST = /* @__PURE__ */ Symbol.for("sibujs.prerender.v1");
1386
+ function isServer() {
1387
+ return getSSRStore().ssr || globalThis[PRERENDER_HOST] !== void 0;
1388
+ }
1135
1389
  function runInSSRContext(fn) {
1136
1390
  const store = {
1137
1391
  ssr: true,
@@ -1160,14 +1414,14 @@ function runInSSRContext(fn) {
1160
1414
  }
1161
1415
  function trackPending(promise, label, hydration = true) {
1162
1416
  const store = getRequestStore();
1163
- const pending = store?.pending;
1164
- const sessions = pending || !hydration ? [] : hydrationOwners();
1165
- if (!pending && sessions.length === 0) return promise;
1417
+ const pending2 = store?.pending;
1418
+ const sessions = pending2 || !hydration ? [] : hydrationOwners();
1419
+ if (!pending2 && sessions.length === 0) return promise;
1166
1420
  const entry = { label, since: Date.now(), boundary: currentBoundary() ?? void 0 };
1167
- pending?.add(entry);
1421
+ pending2?.add(entry);
1168
1422
  const release = holdHydration(sessions, entry);
1169
1423
  const done = () => {
1170
- pending?.delete(entry);
1424
+ pending2?.delete(entry);
1171
1425
  store?.wake?.();
1172
1426
  release();
1173
1427
  };
@@ -2367,6 +2621,25 @@ function assertA11y(root, options) {
2367
2621
  }
2368
2622
  }
2369
2623
 
2624
+ // src/utils/styleKey.ts
2625
+ var EXCEPTIONS = { cssFloat: "float" };
2626
+ var VENDOR_PREFIX = /^(webkit|moz|ms|o)-/;
2627
+ var cache = /* @__PURE__ */ new Map();
2628
+ var CACHE_MAX = 1e3;
2629
+ function styleKeyToProperty(key) {
2630
+ let name = cache.get(key);
2631
+ if (name !== void 0) return name;
2632
+ if (key.startsWith("--")) name = key;
2633
+ else if (Object.hasOwn(EXCEPTIONS, key)) name = EXCEPTIONS[key];
2634
+ else {
2635
+ name = key.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);
2636
+ if (VENDOR_PREFIX.test(name)) name = `-${name}`;
2637
+ }
2638
+ if (cache.size >= CACHE_MAX) cache.clear();
2639
+ cache.set(key, name);
2640
+ return name;
2641
+ }
2642
+
2370
2643
  // src/testing/adapters.ts
2371
2644
  function escapeAttrValue(value) {
2372
2645
  return value.replace(/[\\"]/g, "\\$&").replace(/\n/g, "\\a ").replace(/\r/g, "\\d ").replace(/\0/g, "\\fffd ");
@@ -2483,8 +2756,7 @@ function createJestAdapter() {
2483
2756
  toHaveStyle(element, style) {
2484
2757
  const mismatches = [];
2485
2758
  for (const [prop, expected] of Object.entries(style)) {
2486
- const kebabProp = prop.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);
2487
- const actual = element.style.getPropertyValue(kebabProp);
2759
+ const actual = element.style.getPropertyValue(styleKeyToProperty(prop));
2488
2760
  if (actual !== expected) {
2489
2761
  mismatches.push(`${prop}: expected "${expected}" but got "${actual}"`);
2490
2762
  }
@@ -3226,6 +3498,133 @@ ${result.diff ?? ""}`);
3226
3498
  };
3227
3499
  }
3228
3500
 
3501
+ // src/core/rendering/heldCommit.ts
3502
+ var NOOP2 = () => {
3503
+ };
3504
+ function commitWhenActive(slot3, c) {
3505
+ let over = false;
3506
+ let unhold = null;
3507
+ let drop = NOOP2;
3508
+ const finish = () => {
3509
+ over = true;
3510
+ if (slot3.cancel === cancel) slot3.cancel = NOOP2;
3511
+ drop();
3512
+ drop = NOOP2;
3513
+ };
3514
+ const cancel = () => {
3515
+ if (over) return;
3516
+ finish();
3517
+ const release = unhold;
3518
+ unhold = null;
3519
+ try {
3520
+ c.discard();
3521
+ } finally {
3522
+ release?.();
3523
+ }
3524
+ };
3525
+ const attempt = () => {
3526
+ drop = NOOP2;
3527
+ let clean = false;
3528
+ while (!over) {
3529
+ const state5 = c.held.state();
3530
+ if (state5 === 2 || c.owned !== void 0 && !c.owned()) {
3531
+ cancel();
3532
+ return;
3533
+ }
3534
+ if (state5 === 1) {
3535
+ if (c.node !== null && unhold === null) unhold = holdSubtree2(c.node);
3536
+ drop = c.held.wait(attempt, attempt);
3537
+ return;
3538
+ }
3539
+ if (unhold !== null) {
3540
+ const release = unhold;
3541
+ unhold = null;
3542
+ release();
3543
+ continue;
3544
+ }
3545
+ if (!clean) {
3546
+ clean = c.teardown?.() !== true;
3547
+ continue;
3548
+ }
3549
+ finish();
3550
+ c.insert();
3551
+ return;
3552
+ }
3553
+ };
3554
+ slot3.cancel = cancel;
3555
+ attempt();
3556
+ }
3557
+
3558
+ // src/core/rendering/range.ts
3559
+ var state3 = globalSingleton(/* @__PURE__ */ Symbol.for("sibujs.ranges.v1"), () => ({
3560
+ ends: /* @__PURE__ */ new WeakMap(),
3561
+ pending: /* @__PURE__ */ new WeakMap(),
3562
+ registrations: /* @__PURE__ */ new Set(),
3563
+ listeners: /* @__PURE__ */ new Set(),
3564
+ notice: { queued: false, batch: [] }
3565
+ }));
3566
+ var ends = state3.ends;
3567
+ function registerRange(start, last) {
3568
+ ends.set(start, last);
3569
+ }
3570
+ var pending = state3.pending;
3571
+ var NOTHING = () => {
3572
+ };
3573
+ var registrations = state3.registrations;
3574
+ var loadListeners = state3.listeners;
3575
+ var notice = state3.notice;
3576
+ function notifyLoad(settled2) {
3577
+ if (loadListeners.size === 0) return;
3578
+ if (settled2 !== null) notice.batch.push(settled2);
3579
+ if (notice.queued) return;
3580
+ notice.queued = true;
3581
+ queueMicrotask(() => {
3582
+ notice.queued = false;
3583
+ const batch2 = notice.batch;
3584
+ notice.batch = [];
3585
+ for (const listener of [...loadListeners]) listener(batch2);
3586
+ });
3587
+ }
3588
+ function beginPending(at, held) {
3589
+ const entry = { at, held, settled: false, cancelled: false, committed: null };
3590
+ registrations.add(entry);
3591
+ notifyLoad(null);
3592
+ const settle = (cancelled, committed) => {
3593
+ if (entry.settled) return;
3594
+ entry.settled = true;
3595
+ entry.cancelled = cancelled;
3596
+ entry.committed = committed;
3597
+ registrations.delete(entry);
3598
+ notifyLoad(entry);
3599
+ };
3600
+ return {
3601
+ entry,
3602
+ done: (committed) => settle(false, committed ?? null),
3603
+ cancel: () => settle(true, null)
3604
+ };
3605
+ }
3606
+ var INERT = { done: NOTHING, cancel: NOTHING };
3607
+ function beginLoading(anchor) {
3608
+ if (isServer()) return INERT;
3609
+ const { done, cancel } = beginPending(anchor, null);
3610
+ return { done: () => done(), cancel };
3611
+ }
3612
+ function registerNodesRange(anchor, nodes) {
3613
+ registerRange(anchor, () => {
3614
+ const parent = anchor.parentNode;
3615
+ const wanted = nodes().filter((n) => n !== null && n.parentNode === parent);
3616
+ let last = null;
3617
+ let left = wanted.length;
3618
+ for (let n = anchor.nextSibling; n !== null && left > 0; n = n.nextSibling) {
3619
+ if (wanted.includes(n)) {
3620
+ last = n;
3621
+ left--;
3622
+ }
3623
+ }
3624
+ return last;
3625
+ });
3626
+ }
3627
+
3229
3628
  // src/utils/sanitize.ts
3230
3629
  function stripControlChars(value) {
3231
3630
  return value.replace(/[\x00-\x20\x7f-\x9f]+/g, "");
@@ -3746,7 +4145,7 @@ var isBatching = API2.isBatching;
3746
4145
  // src/core/signals/signal.ts
3747
4146
  var _g2 = globalThis;
3748
4147
  function signal(initial, options) {
3749
- const state3 = {
4148
+ const state5 = {
3750
4149
  value: initial,
3751
4150
  __v: 0,
3752
4151
  __sc: 0,
@@ -3759,57 +4158,57 @@ function signal(initial, options) {
3759
4158
  };
3760
4159
  const debugName = DEV ? options?.name : void 0;
3761
4160
  const equalsFn = options?.equals;
3762
- if (debugName) state3.__name = debugName;
4161
+ if (debugName) state5.__name = debugName;
3763
4162
  function get() {
3764
- recordDependency2(state3);
3765
- return state3.value;
4163
+ recordDependency2(state5);
4164
+ return state5.value;
3766
4165
  }
3767
- get.__signal = state3;
4166
+ get.__signal = state5;
3768
4167
  if (debugName) get.__name = debugName;
3769
4168
  let set;
3770
4169
  if (equalsFn) {
3771
4170
  set = (next) => {
3772
- const prev = state3.value;
4171
+ const prev = state5.value;
3773
4172
  const newValue = typeof next === "function" ? next(prev) : next;
3774
4173
  if (equalsFn(prev, newValue)) return;
3775
- state3.value = newValue;
3776
- state3.__v++;
4174
+ state5.value = newValue;
4175
+ state5.__v++;
3777
4176
  if (DEV) {
3778
4177
  const hook = _g2.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
3779
- if (hook) emitDevtools(hook, "signal:update", { signal: state3, name: debugName, oldValue: prev, newValue });
4178
+ if (hook) emitDevtools(hook, "signal:update", { signal: state5, name: debugName, oldValue: prev, newValue });
3780
4179
  }
3781
- if (!enqueueBatchedSignal(state3)) {
3782
- notifySubscribers2(state3);
4180
+ if (!enqueueBatchedSignal(state5)) {
4181
+ notifySubscribers2(state5);
3783
4182
  }
3784
4183
  };
3785
4184
  } else if (DEV) {
3786
4185
  set = (next) => {
3787
- const prev = state3.value;
4186
+ const prev = state5.value;
3788
4187
  const newValue = typeof next === "function" ? next(prev) : next;
3789
4188
  if (Object.is(newValue, prev)) return;
3790
- state3.value = newValue;
3791
- state3.__v++;
4189
+ state5.value = newValue;
4190
+ state5.__v++;
3792
4191
  const hook = _g2.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
3793
- if (hook) emitDevtools(hook, "signal:update", { signal: state3, name: debugName, oldValue: prev, newValue });
3794
- if (!enqueueBatchedSignal(state3)) {
3795
- notifySubscribers2(state3);
4192
+ if (hook) emitDevtools(hook, "signal:update", { signal: state5, name: debugName, oldValue: prev, newValue });
4193
+ if (!enqueueBatchedSignal(state5)) {
4194
+ notifySubscribers2(state5);
3796
4195
  }
3797
4196
  };
3798
4197
  } else {
3799
4198
  set = (next) => {
3800
- const prev = state3.value;
4199
+ const prev = state5.value;
3801
4200
  const newValue = typeof next === "function" ? next(prev) : next;
3802
4201
  if (Object.is(newValue, prev)) return;
3803
- state3.value = newValue;
3804
- state3.__v++;
3805
- if (!enqueueBatchedSignal(state3)) {
3806
- notifySubscribers2(state3);
4202
+ state5.value = newValue;
4203
+ state5.__v++;
4204
+ if (!enqueueBatchedSignal(state5)) {
4205
+ notifySubscribers2(state5);
3807
4206
  }
3808
4207
  };
3809
4208
  }
3810
4209
  if (DEV) {
3811
4210
  const hook = _g2.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
3812
- if (hook) emitDevtools(hook, "signal:create", { signal: state3, name: debugName, getter: get, initial });
4211
+ if (hook) emitDevtools(hook, "signal:create", { signal: state5, name: debugName, getter: get, initial });
3813
4212
  }
3814
4213
  return [get, set];
3815
4214
  }
@@ -4856,15 +5255,15 @@ var _ComponentLoader = class _ComponentLoader {
4856
5255
  const cached = this.planCache.get(cacheKey);
4857
5256
  if (cached && cached.kind === "factory") return cached.component;
4858
5257
  this.assertNotHot(cacheKey);
4859
- let pending = this.moduleLoads.get(cacheKey);
4860
- const owner = pending === void 0;
4861
- if (pending === void 0) {
4862
- pending = plan.load();
4863
- this.moduleLoads.set(cacheKey, pending);
5258
+ let pending2 = this.moduleLoads.get(cacheKey);
5259
+ const owner = pending2 === void 0;
5260
+ if (pending2 === void 0) {
5261
+ pending2 = plan.load();
5262
+ this.moduleLoads.set(cacheKey, pending2);
4864
5263
  }
4865
5264
  let resolved;
4866
5265
  try {
4867
- resolved = await pending;
5266
+ resolved = await pending2;
4868
5267
  } catch (error) {
4869
5268
  this.noteError(cacheKey);
4870
5269
  throw error;
@@ -4886,7 +5285,14 @@ var _ComponentLoader = class _ComponentLoader {
4886
5285
  * is a configuration error, not something to chase.
4887
5286
  */
4888
5287
  async instantiateFactory(component, route2, routePath, scope, depth = 0) {
4889
- const build = () => scope ? runWithOwnerScope2(scope, component) : component();
5288
+ const gate = scope?.gate;
5289
+ if (gate) {
5290
+ while (gate.held()) if (!await gate.until()) throw gate.cancellation();
5291
+ if (scope?.current?.() === false) throw gate.cancellation();
5292
+ }
5293
+ const owner = scope?.owner;
5294
+ const invoke = () => scope ? runWithOwnerScope2(scope, component) : component();
5295
+ const build = owner ? () => owner.run(invoke) : invoke;
4890
5296
  const result = scope?.adopt ? inScope(scope.adopt, build) : build();
4891
5297
  const value = this.isThenable(result) ? await result : result;
4892
5298
  if (this.isElement(value)) return value;
@@ -5095,7 +5501,7 @@ var _SibuRouter = class _SibuRouter {
5095
5501
  return this.loadedPromise;
5096
5502
  }
5097
5503
  createInitialRoute() {
5098
- return {
5504
+ const route2 = {
5099
5505
  path: "/",
5100
5506
  params: {},
5101
5507
  query: {},
@@ -5104,6 +5510,8 @@ var _SibuRouter = class _SibuRouter {
5104
5510
  meta: {},
5105
5511
  matched: []
5106
5512
  };
5513
+ bootstrapRoutes.add(route2);
5514
+ return route2;
5107
5515
  }
5108
5516
  handleLocationChange(skipHistory = true, initialResolution = false) {
5109
5517
  const path = this.getCurrentPath();
@@ -5144,8 +5552,31 @@ var _SibuRouter = class _SibuRouter {
5144
5552
  matched
5145
5553
  };
5146
5554
  }
5555
+ /**
5556
+ * Once no navigation is in flight: if the route is still the placeholder
5557
+ * the router started with — every navigation that could have replaced it
5558
+ * was cancelled by a guard, failed, or was a duplicate — that IS the
5559
+ * outcome, and the outlets that rendered nothing for it settle (see
5560
+ * `settleEmpty`). Checked when a navigation has definitively completed,
5561
+ * never from `isReady` (set before the guards run). A navigation still
5562
+ * pending — a newer one, or a guard that never resolves — keeps them
5563
+ * pending; an outlet's enter is bounded by its own deadline then.
5564
+ */
5565
+ settleBootstrap() {
5566
+ if (this.destroyed || this.navigator.isNavigating) return;
5567
+ const current2 = untracked2(() => this.currentRouteGetter());
5568
+ if (!bootstrapRoutes.delete(current2)) return;
5569
+ const waiting = bootstrapWaiters.get(current2);
5570
+ bootstrapWaiters.delete(current2);
5571
+ if (waiting) for (const settle of waiting) settle();
5572
+ }
5147
5573
  // Public API
5148
5574
  async navigate(to, options = {}) {
5575
+ const result = await this.attemptNavigation(to, options);
5576
+ this.settleBootstrap();
5577
+ return result;
5578
+ }
5579
+ async attemptNavigation(to, options) {
5149
5580
  try {
5150
5581
  await this.navigator.navigate(async (signal2) => {
5151
5582
  const targetPath = this.resolvePath(to);
@@ -5399,6 +5830,13 @@ var _SibuRouter = class _SibuRouter {
5399
5830
  /**
5400
5831
  * Create exactly one real instance from an already-resolved plan. With a
5401
5832
  * `scope`, the factory runs in it (see `RouteScope`).
5833
+ *
5834
+ * When the scope belongs to an outlet whose branch is paused (playing a
5835
+ * leave it may still be taken back from), a lazy module that resolves does
5836
+ * not run its factory yet: the promise stays pending and continues once the
5837
+ * branch resumes. If the branch ends, or the outlet's pass was superseded
5838
+ * meanwhile, it rejects with a `DOMException` named `"AbortError"`. Genuine
5839
+ * loader and component failures reject with their own error, as before.
5402
5840
  */
5403
5841
  async instantiateComponent(plan, route2, routePath, scope) {
5404
5842
  return prerenderWait(this.loader.instantiate(plan, route2, routePath, scope), `router:render ${route2.path}`);
@@ -5643,6 +6081,21 @@ var RouteScope = class {
5643
6081
  constructor(route2) {
5644
6082
  /** Creation scope the instance is built in (adopting hydration); see `adoptScope`. */
5645
6083
  this.adopt = null;
6084
+ /**
6085
+ * The outlet's pause gate: while the branch holding the outlet is paused (it
6086
+ * began a leave and may still be taken back), a lazy module that resolves
6087
+ * does not get its factory invoked yet; instantiation waits for the branch
6088
+ * to resume, and is cancelled if it ends.
6089
+ */
6090
+ this.gate = null;
6091
+ /** Whether the outlet pass this instance is for is still the current one. */
6092
+ this.current = null;
6093
+ /**
6094
+ * The instance's structural owner, nested under the outlet's: its factory
6095
+ * runs as it, so what it creates is paused with the branch holding the
6096
+ * outlet, and ends (`lifecycleScope()` work included) with the instance.
6097
+ */
6098
+ this.owner = null;
5646
6099
  this.released = false;
5647
6100
  const [get, set] = signal(route2);
5648
6101
  this.get = get;
@@ -5669,6 +6122,112 @@ var RouteScope = class {
5669
6122
  queueMicrotask(() => this.set(null));
5670
6123
  }
5671
6124
  };
6125
+ var NOOP3 = () => {
6126
+ };
6127
+ var bootstrapRoutes = /* @__PURE__ */ new WeakSet();
6128
+ var bootstrapWaiters = /* @__PURE__ */ new WeakMap();
6129
+ function settleEmpty(route2, loaded, current2) {
6130
+ if (!bootstrapRoutes.has(route2)) {
6131
+ loaded.done();
6132
+ return;
6133
+ }
6134
+ let waiting = bootstrapWaiters.get(route2);
6135
+ if (waiting === void 0) bootstrapWaiters.set(route2, waiting = /* @__PURE__ */ new Set());
6136
+ waiting.add(() => {
6137
+ if (current2()) loaded.done();
6138
+ });
6139
+ }
6140
+ var cancellations = /* @__PURE__ */ new WeakSet();
6141
+ function pauseGate(frozen) {
6142
+ let closed = false;
6143
+ const pending2 = /* @__PURE__ */ new Set();
6144
+ return {
6145
+ held: () => closed || frozen(),
6146
+ until: () => {
6147
+ if (closed) return Promise.resolve(false);
6148
+ return new Promise((resolve) => {
6149
+ const settle = (active) => {
6150
+ pending2.delete(cancel);
6151
+ resolve(active && !closed);
6152
+ };
6153
+ const drop = frozen.wait(
6154
+ () => settle(true),
6155
+ () => settle(false)
6156
+ );
6157
+ const cancel = () => {
6158
+ drop();
6159
+ settle(false);
6160
+ };
6161
+ pending2.add(cancel);
6162
+ });
6163
+ },
6164
+ cancellation: () => {
6165
+ const error = new DOMException("Route instantiation cancelled: its branch was released", "AbortError");
6166
+ cancellations.add(error);
6167
+ return error;
6168
+ },
6169
+ close: () => {
6170
+ closed = true;
6171
+ for (const cancel of [...pending2]) cancel();
6172
+ },
6173
+ run: frozen.run,
6174
+ frozen,
6175
+ closed: () => closed,
6176
+ onClose: (fn) => {
6177
+ pending2.add(fn);
6178
+ return () => {
6179
+ pending2.delete(fn);
6180
+ };
6181
+ }
6182
+ };
6183
+ }
6184
+ function whenActive(gate, fn) {
6185
+ if (!gate.held()) fn();
6186
+ else
6187
+ void gate.until().then((active) => {
6188
+ if (active) whenActive(gate, fn);
6189
+ });
6190
+ }
6191
+ function commitPass(gate, c) {
6192
+ const frozen = gate.frozen;
6193
+ const held = {
6194
+ state: frozen.state,
6195
+ wait: (onActive, onEnd) => {
6196
+ let live = true;
6197
+ const later = (fn) => () => {
6198
+ void Promise.resolve().then(() => {
6199
+ if (live) fn();
6200
+ });
6201
+ };
6202
+ const drop = frozen.wait(later(onActive), later(onEnd));
6203
+ return () => {
6204
+ live = false;
6205
+ drop();
6206
+ };
6207
+ }
6208
+ };
6209
+ return new Promise((resolve, reject) => {
6210
+ const slot3 = { cancel: NOOP3 };
6211
+ const untrack = gate.onClose(() => slot3.cancel());
6212
+ const settle = (fn) => () => {
6213
+ untrack();
6214
+ try {
6215
+ fn();
6216
+ resolve();
6217
+ } catch (error) {
6218
+ reject(error);
6219
+ }
6220
+ };
6221
+ commitWhenActive(slot3, {
6222
+ held,
6223
+ node: c.node,
6224
+ owned: () => !gate.closed() && c.owned(),
6225
+ teardown: c.teardown,
6226
+ insert: settle(c.insert),
6227
+ discard: settle(c.discard)
6228
+ });
6229
+ });
6230
+ }
5672
6231
  function activeRouteScope() {
5673
6232
  const scope = getOwnerScope2();
5674
6233
  return scope instanceof RouteScope ? scope : null;
@@ -5682,14 +6241,27 @@ function scopedRoute(router) {
5682
6241
  return router.currentRoute;
5683
6242
  }
5684
6243
  var instanceScopes = /* @__PURE__ */ new WeakMap();
5685
- async function instantiateScoped(router, plan, routeDef, routePath, route2, adopt = null) {
6244
+ async function instantiateScoped(router, plan, routeDef, routePath, route2, adopt = null, gate = null, current2 = null) {
5686
6245
  const scope = new RouteScope(route2);
5687
6246
  scope.adopt = adopt;
5688
- const node = await router.instantiateComponent(plan, routeDef, routePath, scope);
6247
+ scope.gate = gate;
6248
+ scope.current = current2;
6249
+ const owner = gate ? gate.run(() => structuralBinding2(NOOP3)) : structuralBinding2(NOOP3);
6250
+ scope.owner = owner;
6251
+ let node;
6252
+ try {
6253
+ node = await router.instantiateComponent(plan, routeDef, routePath, scope);
6254
+ } catch (error) {
6255
+ owner.stop();
6256
+ throw error;
6257
+ }
5689
6258
  if (node) {
5690
6259
  instanceScopes.set(node, scope);
5691
- registerDisposer(node, () => scope.release());
5692
- }
6260
+ registerDisposer(node, () => {
6261
+ owner.stop();
6262
+ scope.release();
6263
+ });
6264
+ } else owner.stop();
5693
6265
  return node;
5694
6266
  }
5695
6267
  function updateInstanceRoute(node, route2) {
@@ -5732,6 +6304,8 @@ function instanceKey(owner, records, route2) {
5732
6304
  function Route() {
5733
6305
  const anchor = document.createComment("route-outlet");
5734
6306
  const adoptScope = captureScope();
6307
+ const frozen = captureFrozen2();
6308
+ const gate = pauseGate(frozen);
5735
6309
  let currentNode = null;
5736
6310
  let loadingNode = null;
5737
6311
  let errorNode = null;
@@ -5739,6 +6313,7 @@ function Route() {
5739
6313
  let currentTopRoute = null;
5740
6314
  let currentKey = null;
5741
6315
  let routeTorn = false;
6316
+ const loaded = beginLoading(anchor);
5742
6317
  const commitTarget = (seq) => routeTorn || seq !== navSeq ? null : anchor.parentNode;
5743
6318
  const retryIfDetached = (seq) => {
5744
6319
  if (!routeTorn && seq === navSeq && !anchor.parentNode) attachWait.request();
@@ -5783,24 +6358,54 @@ function Route() {
5783
6358
  loadingNode = null;
5784
6359
  }
5785
6360
  };
5786
- const showError = (error, routeDef) => {
6361
+ const showError = (seq, error, routeDef) => {
5787
6362
  if (!anchor.parentNode) return;
5788
- cleanupNodes();
5789
- errorNode = document.createElement("div");
5790
- errorNode.className = "route-error";
5791
- errorNode.setAttribute("role", "alert");
5792
- errorNode.setAttribute("aria-live", "assertive");
6363
+ const view = errorView(error, routeDef);
6364
+ void commitPass(gate, {
6365
+ node: view,
6366
+ owned: () => !routeTorn && seq === navSeq,
6367
+ discard: () => dispose(view),
6368
+ teardown: () => {
6369
+ if (!anchor.parentNode || !(currentNode || loadingNode || errorNode)) return false;
6370
+ cleanupNodes();
6371
+ return true;
6372
+ },
6373
+ insert: () => {
6374
+ const parent = anchor.parentNode;
6375
+ if (!parent) {
6376
+ dispose(view);
6377
+ unshownFailure = { seq, error, routeDef };
6378
+ attachWait.request();
6379
+ return;
6380
+ }
6381
+ errorNode = view;
6382
+ try {
6383
+ parent.insertBefore(view, anchor.nextSibling);
6384
+ } catch (err) {
6385
+ if (errorNode === view) errorNode = null;
6386
+ release(view);
6387
+ throw err;
6388
+ }
6389
+ if (!routeTorn && seq === navSeq) loaded.done();
6390
+ }
6391
+ }).catch((err) => console.error("[Route] Error view failed:", err));
6392
+ };
6393
+ const errorView = (error, routeDef) => {
6394
+ const errorNode2 = document.createElement("div");
6395
+ errorNode2.className = "route-error";
6396
+ errorNode2.setAttribute("role", "alert");
6397
+ errorNode2.setAttribute("aria-live", "assertive");
5793
6398
  if (routeDef && "component" in routeDef) {
5794
6399
  const src = routeDef.component.toString();
5795
6400
  const importMatch = src.match(/import\(["']([^"']+)["']\)/);
5796
6401
  if (importMatch) {
5797
- errorNode.setAttribute("data-component-source", importMatch[1]);
6402
+ errorNode2.setAttribute("data-component-source", importMatch[1]);
5798
6403
  }
5799
6404
  if (routeDef.component.name) {
5800
- errorNode.setAttribute("data-component-name", routeDef.component.name);
6405
+ errorNode2.setAttribute("data-component-name", routeDef.component.name);
5801
6406
  }
5802
6407
  }
5803
- errorNode.__routeError = error;
6408
+ errorNode2.__routeError = error;
5804
6409
  const title = document.createElement("h3");
5805
6410
  title.textContent = "Route Error";
5806
6411
  title.className = "route-error-title";
@@ -5819,10 +6424,10 @@ function Route() {
5819
6424
  };
5820
6425
  retryButton.addEventListener("click", onRetryClick);
5821
6426
  registerDisposer(retryButton, () => retryButton.removeEventListener("click", onRetryClick));
5822
- errorNode.appendChild(title);
5823
- errorNode.appendChild(message);
5824
- errorNode.appendChild(retryButton);
5825
- anchor.parentNode.insertBefore(errorNode, anchor.nextSibling);
6427
+ errorNode2.appendChild(title);
6428
+ errorNode2.appendChild(message);
6429
+ errorNode2.appendChild(retryButton);
6430
+ return errorNode2;
5826
6431
  };
5827
6432
  const update = async () => {
5828
6433
  routerRevision();
@@ -5835,12 +6440,14 @@ function Route() {
5835
6440
  currentTopRoute = null;
5836
6441
  currentKey = null;
5837
6442
  cleanupNodes();
6443
+ settleEmpty(route2, loaded, () => !routeTorn && seq === navSeq);
5838
6444
  return;
5839
6445
  }
5840
6446
  const routeDef = match.matched[0] || match.route;
5841
6447
  const key = instanceKey(routeDef, [routeDef], route2);
5842
6448
  if (routeDef === currentTopRoute && key === currentKey && currentNode) {
5843
6449
  updateInstanceRoute(currentNode, route2);
6450
+ loaded.done();
5844
6451
  return;
5845
6452
  }
5846
6453
  if ("redirect" in routeDef) {
@@ -5859,6 +6466,7 @@ function Route() {
5859
6466
  showLoading();
5860
6467
  }
5861
6468
  const plan = await _routerRef.current.loadPlan(routeDef, route2.path);
6469
+ while (gate.held()) if (!await gate.until()) return;
5862
6470
  if (!commitTarget(seq)) {
5863
6471
  retryIfDetached(seq);
5864
6472
  return;
@@ -5869,28 +6477,57 @@ function Route() {
5869
6477
  routeDef,
5870
6478
  route2.path,
5871
6479
  route2,
5872
- keyedScope(adoptScope, routeDef.path)
6480
+ keyedScope(adoptScope, routeDef.path),
6481
+ gate,
6482
+ () => commitTarget(seq) !== null
5873
6483
  );
5874
- const parent = commitTarget(seq);
5875
- if (!parent) {
5876
- release(node);
5877
- retryIfDetached(seq);
5878
- return;
5879
- }
5880
- if (node) {
5881
- currentTopRoute = routeDef;
5882
- currentKey = key;
5883
- cleanupNodes();
5884
- parent.insertBefore(node, anchor.nextSibling);
5885
- currentNode = node;
5886
- }
6484
+ await commitPass(gate, {
6485
+ node,
6486
+ owned: () => !routeTorn && seq === navSeq,
6487
+ discard: () => release(node),
6488
+ // The outgoing views go first — only when there is a page to
6489
+ // show, and a parent to show it in.
6490
+ teardown: () => {
6491
+ if (!node || !anchor.parentNode || !(currentNode || loadingNode || errorNode)) return false;
6492
+ cleanupNodes();
6493
+ return true;
6494
+ },
6495
+ insert: () => {
6496
+ const parent = commitTarget(seq);
6497
+ if (!parent) {
6498
+ release(node);
6499
+ retryIfDetached(seq);
6500
+ return;
6501
+ }
6502
+ if (node) {
6503
+ currentTopRoute = routeDef;
6504
+ currentKey = key;
6505
+ currentNode = node;
6506
+ try {
6507
+ parent.insertBefore(node, anchor.nextSibling);
6508
+ } catch (error) {
6509
+ if (currentNode === node) {
6510
+ currentNode = null;
6511
+ currentTopRoute = null;
6512
+ currentKey = null;
6513
+ }
6514
+ release(node);
6515
+ throw error;
6516
+ }
6517
+ }
6518
+ if (!routeTorn && seq === navSeq) loaded.done();
6519
+ }
6520
+ });
5887
6521
  } catch (error) {
6522
+ if (cancellations.has(error)) return;
5888
6523
  if (routeTorn || seq !== navSeq) return;
5889
- hideLoading();
5890
6524
  console.error("[Route] Component error:", error);
6525
+ while (gate.held()) if (!await gate.until()) return;
6526
+ if (routeTorn || seq !== navSeq) return;
6527
+ hideLoading();
5891
6528
  fail(seq, error, routeDef);
5892
6529
  }
5893
- }
6530
+ } else settleEmpty(route2, loaded, () => !routeTorn && seq === navSeq);
5894
6531
  } catch (error) {
5895
6532
  if (seq !== navSeq) return;
5896
6533
  if (routeTorn) return;
@@ -5902,16 +6539,20 @@ function Route() {
5902
6539
  const fail = (seq, error, routeDef) => {
5903
6540
  const err = error instanceof Error ? error : new Error(String(error));
5904
6541
  if (anchor.parentNode) {
5905
- showError(err, routeDef);
6542
+ showError(seq, err, routeDef);
5906
6543
  return;
5907
6544
  }
5908
6545
  unshownFailure = { seq, error: err, routeDef };
5909
6546
  attachWait.request();
5910
6547
  };
5911
6548
  const onAttached = () => {
6549
+ if (gate.held()) {
6550
+ void gate.until().then((active) => active && onAttached());
6551
+ return;
6552
+ }
5912
6553
  const failure = unshownFailure;
5913
6554
  unshownFailure = null;
5914
- if (failure && failure.seq === navSeq) showError(failure.error, failure.routeDef);
6555
+ if (failure && failure.seq === navSeq) showError(failure.seq, failure.error, failure.routeDef);
5915
6556
  else update();
5916
6557
  };
5917
6558
  let routeInitialized = false;
@@ -5921,11 +6562,16 @@ function Route() {
5921
6562
  routeInitialized = true;
5922
6563
  };
5923
6564
  const attachWait = attachRetry(anchor, onAttached);
5924
- const routeTeardown = track2(wrappedUpdate);
6565
+ const routeTeardown = reactiveBinding2(wrappedUpdate, anchor);
5925
6566
  if (!routeInitialized) {
5926
6567
  queueMicrotask(
5927
6568
  bindOwnerScope2(() => {
5928
- if (!routeInitialized && anchor.parentNode) wrappedUpdate();
6569
+ whenActive(
6570
+ gate,
6571
+ bindOwnerScope2(() => {
6572
+ if (!routeInitialized && anchor.parentNode) wrappedUpdate();
6573
+ })
6574
+ );
5929
6575
  })
5930
6576
  );
5931
6577
  }
@@ -5933,6 +6579,8 @@ function Route() {
5933
6579
  if (routeTorn) return;
5934
6580
  routeTorn = true;
5935
6581
  navSeq++;
6582
+ gate.close();
6583
+ loaded.cancel();
5936
6584
  routeTeardown();
5937
6585
  attachWait.cancel();
5938
6586
  unshownFailure = null;
@@ -5940,6 +6588,7 @@ function Route() {
5940
6588
  currentTopRoute = null;
5941
6589
  currentKey = null;
5942
6590
  };
6591
+ registerNodesRange(anchor, () => [currentNode, loadingNode, errorNode]);
5943
6592
  registerDisposer(anchor, routeCleanup);
5944
6593
  routeCleanups.push(routeCleanup);
5945
6594
  return anchor;
@@ -5969,14 +6618,14 @@ function ensureRouterPagehide() {
5969
6618
  }
5970
6619
 
5971
6620
  // src/utils/embedPolicy.ts
5972
- var state2 = globalSingleton(/* @__PURE__ */ Symbol.for("sibujs.embed.v2"), () => ({
6621
+ var state4 = globalSingleton(/* @__PURE__ */ Symbol.for("sibujs.embed.v2"), () => ({
5973
6622
  allowed: [],
5974
6623
  frames: /* @__PURE__ */ new WeakMap()
5975
6624
  }));
5976
6625
  var REQUEST_CACHE = "embed";
5977
6626
  function currentEmbedAllowlist() {
5978
6627
  const scoped = getRequestStore()?.caches?.get(REQUEST_CACHE)?.get("allowed");
5979
- return scoped ?? state2.allowed;
6628
+ return scoped ?? state4.allowed;
5980
6629
  }
5981
6630
  function resolveEmbedSrc(value, allowed = currentEmbedAllowlist()) {
5982
6631
  if (typeof value !== "string" || sanitizeUrl(value) === "") return null;
@@ -6036,7 +6685,7 @@ function narrowEmbedAllow(value) {
6036
6685
  return granted.filter((feature) => !denied.includes(feature)).join("; ");
6037
6686
  }
6038
6687
  function getEmbedRecord(frame) {
6039
- return state2.frames.get(frame);
6688
+ return state4.frames.get(frame);
6040
6689
  }
6041
6690
  function intersect(current2, permitted, separator) {
6042
6691
  const allowed = permitted.split(separator);
@@ -6752,9 +7401,15 @@ var ServerAttr = class {
6752
7401
  get nodeValue() {
6753
7402
  return this._value;
6754
7403
  }
7404
+ set nodeValue(v) {
7405
+ this.value = v;
7406
+ }
6755
7407
  get textContent() {
6756
7408
  return this._value;
6757
7409
  }
7410
+ set textContent(v) {
7411
+ this.value = v;
7412
+ }
6758
7413
  };
6759
7414
  var ServerNamedNodeMap = class extends Array {
6760
7415
  static get [Symbol.species]() {
@@ -6791,12 +7446,6 @@ function splitDeclarations(text) {
6791
7446
  out.push(text.slice(start));
6792
7447
  return out;
6793
7448
  }
6794
- var CAMEL_EXCEPTIONS = { cssFloat: "float" };
6795
- function toKebab(prop) {
6796
- if (prop.startsWith("--")) return prop;
6797
- if (Object.hasOwn(CAMEL_EXCEPTIONS, prop)) return CAMEL_EXCEPTIONS[prop];
6798
- return prop.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`).replace(/^(webkit|moz|ms)-/, "-$1-");
6799
- }
6800
7449
  var ServerStyle = class {
6801
7450
  constructor(el) {
6802
7451
  this.el = el;
@@ -6891,13 +7540,13 @@ function styleProxy(style) {
6891
7540
  get(target, key, receiver) {
6892
7541
  if (typeof key === "string" && !(key in target)) {
6893
7542
  if (/^\d+$/.test(key)) return target.item(Number(key));
6894
- return target.getPropertyValue(toKebab(key));
7543
+ return target.getPropertyValue(styleKeyToProperty(key));
6895
7544
  }
6896
7545
  return Reflect.get(target, key, receiver);
6897
7546
  },
6898
7547
  set(target, key, value, receiver) {
6899
7548
  if (typeof key === "string" && !(key in target)) {
6900
- target.setProperty(toKebab(key), value == null ? "" : String(value));
7549
+ target.setProperty(styleKeyToProperty(key), value == null ? "" : String(value));
6901
7550
  return true;
6902
7551
  }
6903
7552
  return Reflect.set(target, key, value, receiver);
@@ -7302,6 +7951,10 @@ var ServerInputElement = class extends ServerHTMLElement {
7302
7951
  get defaultChecked() {
7303
7952
  return this.hasAttribute("checked");
7304
7953
  }
7954
+ /** Reflects to the `checked` attribute; `checked` follows it until written (dirty checkedness). */
7955
+ set defaultChecked(v) {
7956
+ this.toggleAttribute("checked", !!v);
7957
+ }
7305
7958
  get type() {
7306
7959
  return (this.getAttribute("type") ?? "text").toLowerCase();
7307
7960
  }
@@ -7359,8 +8012,10 @@ reflectDisabled(ServerTextAreaElement.prototype);
7359
8012
  var ServerOptionElement = class extends ServerHTMLElement {
7360
8013
  constructor() {
7361
8014
  super(...arguments);
7362
- /** @internal */
8015
+ /** Selectedness; `null` while it follows the `selected` attribute. @internal */
7363
8016
  this._selected = null;
8017
+ /** Set by a `selected` write: the attribute no longer decides selectedness. @internal */
8018
+ this._dirty = false;
7364
8019
  }
7365
8020
  get value() {
7366
8021
  return this.getAttribute("value") ?? this.text;
@@ -7377,18 +8032,48 @@ var ServerOptionElement = class extends ServerHTMLElement {
7377
8032
  get label() {
7378
8033
  return this.getAttribute("label") ?? this.text;
7379
8034
  }
8035
+ set label(v) {
8036
+ this.setAttribute("label", v);
8037
+ }
7380
8038
  get selected() {
7381
8039
  return this._selected ?? this.hasAttribute("selected");
7382
8040
  }
7383
8041
  set selected(v) {
7384
8042
  this._selected = !!v;
8043
+ this._dirty = true;
8044
+ const select = singleSelectOf(this);
8045
+ if (select && v) {
8046
+ for (const o of select.options) if (o !== this) o._selected = false;
8047
+ }
7385
8048
  }
7386
8049
  get defaultSelected() {
7387
8050
  return this.hasAttribute("selected");
7388
8051
  }
8052
+ /** Reflects to the `selected` attribute; `selected` follows it unless written. */
8053
+ set defaultSelected(v) {
8054
+ this.toggleAttribute("selected", !!v);
8055
+ if (this._dirty) return;
8056
+ this._selected = null;
8057
+ const select = singleSelectOf(this);
8058
+ if (!select) return;
8059
+ let last = null;
8060
+ for (const o of select.options) if (o.selected) last = o;
8061
+ for (const o of select.options) if (o !== last && o.selected) o._selected = false;
8062
+ }
7389
8063
  };
8064
+ function singleSelectOf(option) {
8065
+ let parent = option.parentNode;
8066
+ if (parent instanceof ServerElement && parent.localName === "optgroup") parent = parent.parentNode;
8067
+ return parent instanceof ServerSelectElement && !parent.hasAttribute("multiple") ? parent : null;
8068
+ }
7390
8069
  reflectDisabled(ServerOptionElement.prototype);
7391
8070
  var ServerSelectElement = class extends ServerHTMLElement {
8071
+ get multiple() {
8072
+ return this.hasAttribute("multiple");
8073
+ }
8074
+ set multiple(v) {
8075
+ this.toggleAttribute("multiple", !!v);
8076
+ }
7392
8077
  get options() {
7393
8078
  return this.querySelectorAll("option");
7394
8079
  }
@@ -7693,21 +8378,21 @@ function compileSelector(selector) {
7693
8378
  const tokens = text.match(/(?:\\.|\[[^\]]*\]|[^\s>])+|>/g) ?? [];
7694
8379
  const compounds = [];
7695
8380
  const combinators = [];
7696
- let pending = " ";
8381
+ let pending2 = " ";
7697
8382
  let scoped = false;
7698
8383
  for (const token of tokens) {
7699
8384
  if (token === ">") {
7700
- pending = ">";
8385
+ pending2 = ">";
7701
8386
  continue;
7702
8387
  }
7703
8388
  if (token === ":scope") {
7704
8389
  scoped = true;
7705
- pending = " ";
8390
+ pending2 = " ";
7706
8391
  continue;
7707
8392
  }
7708
- if (compounds.length > 0) combinators.unshift(pending);
8393
+ if (compounds.length > 0) combinators.unshift(pending2);
7709
8394
  compounds.unshift(parseCompound(token, selector));
7710
- pending = " ";
8395
+ pending2 = " ";
7711
8396
  }
7712
8397
  if (compounds.length === 0) throw syntaxError(selector);
7713
8398
  groups.push({ compounds, combinators, scoped });
@@ -7974,14 +8659,14 @@ async function settled(_root, options = {}) {
7974
8659
  const deadline = Date.now() + timeout;
7975
8660
  for (; ; ) {
7976
8661
  await macrotask();
7977
- const pending = store?.pending;
7978
- if (!pending || pending.size === 0) {
8662
+ const pending2 = store?.pending;
8663
+ if (!pending2 || pending2.size === 0) {
7979
8664
  await macrotask();
7980
- if (!pending || pending.size === 0) return { timedOut: false, pending: [] };
8665
+ if (!pending2 || pending2.size === 0) return { timedOut: false, pending: [] };
7981
8666
  continue;
7982
8667
  }
7983
8668
  const remaining = deadline - Date.now();
7984
- if (remaining <= 0) return { timedOut: true, pending: describePending(pending) };
8669
+ if (remaining <= 0) return { timedOut: true, pending: describePending(pending2) };
7985
8670
  await new Promise((resolve) => {
7986
8671
  const done = () => {
7987
8672
  clearTimeout(timer);
@@ -7993,9 +8678,9 @@ async function settled(_root, options = {}) {
7993
8678
  });
7994
8679
  }
7995
8680
  }
7996
- function describePending(pending) {
8681
+ function describePending(pending2) {
7997
8682
  const now = Date.now();
7998
- return Array.from(pending, (work) => `${work.label} (${now - work.since} ms)`);
8683
+ return Array.from(pending2, (work) => `${work.label} (${now - work.since} ms)`);
7999
8684
  }
8000
8685
  function formatRenderDiagnostics(d, label = "render") {
8001
8686
  const lines = [
@@ -8123,7 +8808,7 @@ async function renderCore(input, options) {
8123
8808
  releaseTree();
8124
8809
  throw err;
8125
8810
  }
8126
- let state3 = "";
8811
+ let state5 = "";
8127
8812
  let stateData = null;
8128
8813
  let stateBytes = 0;
8129
8814
  let largestState = [];
@@ -8132,7 +8817,7 @@ async function renderCore(input, options) {
8132
8817
  const collected = collectTransfer();
8133
8818
  if (collected) {
8134
8819
  const built = buildTransfer(collected, options.maxStateBytes ?? DEFAULT_TRANSFER_MAX_BYTES, options.nonce);
8135
- state3 = built.script;
8820
+ state5 = built.script;
8136
8821
  stateData = built.data;
8137
8822
  stateBytes = built.bytes;
8138
8823
  largestState = built.largest;
@@ -8153,7 +8838,7 @@ async function renderCore(input, options) {
8153
8838
  if (DEV && options.log) {
8154
8839
  console.info(formatRenderDiagnostics(diagnostics, typeof options.log === "string" ? options.log : void 0));
8155
8840
  }
8156
- return { content, result: { head, state: state3, stateData, status: 200, diagnostics } };
8841
+ return { content, result: { head, state: state5, stateData, status: 200, diagnostics } };
8157
8842
  }
8158
8843
  function inRequest(api, fn) {
8159
8844
  try {
@@ -8691,12 +9376,12 @@ async function hydrateAdopt(component, container, options = {}) {
8691
9376
  inScope(rootScope, () => session.place(container, tree));
8692
9377
  }
8693
9378
  const deadline = Date.now() + (options.timeout ?? 1e4);
8694
- const { pending, wake } = hydration;
9379
+ const { pending: pending2, wake } = hydration;
8695
9380
  for (; ; ) {
8696
9381
  await macrotask2();
8697
- if (pending.size === 0) {
9382
+ if (pending2.size === 0) {
8698
9383
  await macrotask2();
8699
- if (pending.size === 0) break;
9384
+ if (pending2.size === 0) break;
8700
9385
  continue;
8701
9386
  }
8702
9387
  const remaining = deadline - Date.now();
@@ -9159,12 +9844,12 @@ function escapeScriptJson(json) {
9159
9844
  }
9160
9845
  var DEFAULT_MAX_SSR_BYTES = 1024 * 1024;
9161
9846
  var SAFE_GLOBAL_NAME = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
9162
- function serializeState(state3, nonce, options) {
9847
+ function serializeState(state5, nonce, options) {
9163
9848
  const globalName = options?.global ?? SSR_DATA_ATTR;
9164
9849
  if (!SAFE_GLOBAL_NAME.test(globalName)) {
9165
9850
  throw new Error(`[SibuJS SSR] serializeState: global must be an identifier (got: ${JSON.stringify(globalName)})`);
9166
9851
  }
9167
- const rawJson = JSON.stringify(state3);
9852
+ const rawJson = JSON.stringify(state5);
9168
9853
  const maxBytes = options?.maxBytes ?? DEFAULT_MAX_SSR_BYTES;
9169
9854
  const byteLen = typeof TextEncoder !== "undefined" ? new TextEncoder().encode(rawJson).byteLength : Buffer.byteLength(rawJson, "utf8");
9170
9855
  if (byteLen > maxBytes) {
@@ -9230,17 +9915,17 @@ function renderRoute(routes, url, options = {}) {
9230
9915
  const started = Date.now();
9231
9916
  const deadline = started + (options.timeout ?? DEFAULT_SETTLE_TIMEOUT);
9232
9917
  const router = createRouter(routes, { ...options.router, mode: "memory", url });
9233
- const wrap = (body, headHtml, state3) => options.document ? assembleDocument(body, options.document, headHtml, state3) : body;
9918
+ const wrap = (body, headHtml, state5) => options.document ? assembleDocument(body, options.document, headHtml, state5) : body;
9234
9919
  const timedOut = (phase) => {
9235
9920
  const now = Date.now();
9236
- const pending = [
9921
+ const pending2 = [
9237
9922
  `${phase} (${now - started} ms)`,
9238
9923
  ...Array.from(getRequestStore()?.pending ?? [], (work) => `${work.label} (${now - work.since} ms)`)
9239
9924
  ];
9240
- const diagnostics = { ...emptyDiagnostics(), timedOut: true, pending, durationMs: now - started };
9925
+ const diagnostics = { ...emptyDiagnostics(), timedOut: true, pending: pending2, durationMs: now - started };
9241
9926
  if (DEV) {
9242
9927
  console.warn(
9243
- `[SibuJS SSR] ${url}: the route did not render within ${options.timeout ?? DEFAULT_SETTLE_TIMEOUT} ms; pending: ${pending.join(", ")}`
9928
+ `[SibuJS SSR] ${url}: the route did not render within ${options.timeout ?? DEFAULT_SETTLE_TIMEOUT} ms; pending: ${pending2.join(", ")}`
9244
9929
  );
9245
9930
  }
9246
9931
  return {
@@ -9790,14 +10475,14 @@ function mockRouter(initialPath = "/") {
9790
10475
  return { currentPath, navigate, history: history2 };
9791
10476
  }
9792
10477
  function mockStore(initialState) {
9793
- let state3 = { ...initialState };
10478
+ let state5 = { ...initialState };
9794
10479
  return {
9795
- getState: () => ({ ...state3 }),
10480
+ getState: () => ({ ...state5 }),
9796
10481
  setState: (patch) => {
9797
- state3 = { ...state3, ...patch };
10482
+ state5 = { ...state5, ...patch };
9798
10483
  },
9799
10484
  reset: () => {
9800
- state3 = { ...initialState };
10485
+ state5 = { ...initialState };
9801
10486
  }
9802
10487
  };
9803
10488
  }