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.
Files changed (109) hide show
  1. package/dist/browser.cjs +309 -129
  2. package/dist/browser.d.cts +46 -14
  3. package/dist/browser.d.ts +46 -14
  4. package/dist/browser.js +8 -6
  5. package/dist/build.cjs +184 -72
  6. package/dist/build.js +15 -16
  7. package/dist/cdn.dev.global.js +12 -12
  8. package/dist/cdn.full.dev.global.js +11 -11
  9. package/dist/cdn.full.global.js +10 -10
  10. package/dist/cdn.global.js +12 -12
  11. package/dist/{chunk-IXKSNWV5.js → chunk-2INLLLMZ.js} +1 -1
  12. package/dist/chunk-3ISI6ACU.js +44 -0
  13. package/dist/{chunk-ONOHFDLG.js → chunk-47M47FOM.js} +3 -3
  14. package/dist/chunk-5HZXGZ6T.js +24 -0
  15. package/dist/{chunk-KKLW7YWL.js → chunk-5MT6SJ3P.js} +275 -144
  16. package/dist/{chunk-UGRX3S57.js → chunk-5Q4R7HCL.js} +12 -3
  17. package/dist/{chunk-S373NSMK.js → chunk-7GQCWFOE.js} +150 -59
  18. package/dist/{chunk-FTIR4QW2.js → chunk-7NCARGJW.js} +6 -8
  19. package/dist/{chunk-5DXA2J44.js → chunk-7XHATCIH.js} +5 -2
  20. package/dist/{chunk-VZKNK2V7.js → chunk-AIF3Z2T7.js} +296 -38
  21. package/dist/{chunk-4PMLNECI.js → chunk-BAAG6ZTI.js} +98 -29
  22. package/dist/{chunk-XZZOBQAY.js → chunk-D33YTSX5.js} +2 -2
  23. package/dist/{chunk-TBYTO6BS.js → chunk-DKGBBKOF.js} +136 -80
  24. package/dist/{chunk-NIOYEGBQ.js → chunk-HURREPU2.js} +27 -13
  25. package/dist/{chunk-GW3SCCZG.js → chunk-HYXDKS4N.js} +153 -110
  26. package/dist/chunk-J6FW5TV6.js +233 -0
  27. package/dist/{chunk-PCT43HW3.js → chunk-JSXPZCET.js} +1 -1
  28. package/dist/chunk-NYNYSPK7.js +318 -0
  29. package/dist/{chunk-RJE2BNI4.js → chunk-ORMZXBKQ.js} +108 -45
  30. package/dist/{chunk-OMJJM3KM.js → chunk-OXUY2A6L.js} +287 -130
  31. package/dist/{chunk-3JZ4L5TJ.js → chunk-PK6FK2G2.js} +181 -66
  32. package/dist/{chunk-RBTPLM32.js → chunk-QE4TTDU3.js} +2 -2
  33. package/dist/{chunk-2DCGACUU.js → chunk-SXXVZMKZ.js} +251 -66
  34. package/dist/{chunk-R25EFXXC.js → chunk-TUCPL2HB.js} +3 -3
  35. package/dist/{chunk-7LN645I6.js → chunk-UZQ6ALFS.js} +3 -3
  36. package/dist/{chunk-KEISJXBU.js → chunk-VVWPJ543.js} +6 -8
  37. package/dist/{chunk-RIXRAYIU.js → chunk-XC4MEKGA.js} +3 -3
  38. package/dist/{chunk-B3WHI2QA.js → chunk-XRRZKZYX.js} +55 -31
  39. package/dist/{contracts-DBdg9J_a.d.cts → contracts-DRIuclVT.d.cts} +10 -2
  40. package/dist/{contracts-DBdg9J_a.d.ts → contracts-DRIuclVT.d.ts} +10 -2
  41. package/dist/{customElement-OB9CIsc5.d.cts → customElement-MmInOW1U.d.cts} +21 -0
  42. package/dist/{customElement-OB9CIsc5.d.ts → customElement-MmInOW1U.d.ts} +21 -0
  43. package/dist/data.cjs +213 -117
  44. package/dist/data.d.cts +47 -9
  45. package/dist/data.d.ts +47 -9
  46. package/dist/data.js +12 -9
  47. package/dist/devtools.cjs +81 -57
  48. package/dist/devtools.js +7 -8
  49. package/dist/dispose-GEIG2KOF.js +28 -0
  50. package/dist/ecosystem.cjs +309 -104
  51. package/dist/ecosystem.d.cts +19 -3
  52. package/dist/ecosystem.d.ts +19 -3
  53. package/dist/ecosystem.js +12 -12
  54. package/dist/extras.cjs +2133 -863
  55. package/dist/extras.d.cts +10 -9
  56. package/dist/extras.d.ts +10 -9
  57. package/dist/extras.js +39 -28
  58. package/dist/index.cjs +184 -72
  59. package/dist/index.d.cts +22 -5
  60. package/dist/index.d.ts +22 -5
  61. package/dist/index.js +24 -27
  62. package/dist/motion.cjs +107 -41
  63. package/dist/motion.js +5 -5
  64. package/dist/patterns.cjs +317 -39
  65. package/dist/patterns.d.cts +27 -9
  66. package/dist/patterns.d.ts +27 -9
  67. package/dist/patterns.js +8 -8
  68. package/dist/performance.cjs +308 -216
  69. package/dist/performance.d.cts +2 -2
  70. package/dist/performance.d.ts +2 -2
  71. package/dist/performance.js +8 -9
  72. package/dist/plugin-DVgSnTfK.d.cts +112 -0
  73. package/dist/plugin-DVgSnTfK.d.ts +112 -0
  74. package/dist/plugins.cjs +549 -202
  75. package/dist/plugins.d.cts +3 -3
  76. package/dist/plugins.d.ts +3 -3
  77. package/dist/plugins.js +35 -23
  78. package/dist/signal-EotCj4hS.d.cts +110 -0
  79. package/dist/signal-EotCj4hS.d.ts +110 -0
  80. package/dist/{ssr-BiPRdZ6n.d.cts → ssr-Bli9XRW5.d.cts} +5 -0
  81. package/dist/{ssr-BiPRdZ6n.d.ts → ssr-Bli9XRW5.d.ts} +5 -0
  82. package/dist/{ssr-Y7XOEPEN.js → ssr-XOTUASDO.js} +4 -5
  83. package/dist/ssr.cjs +176 -72
  84. package/dist/ssr.d.cts +9 -3
  85. package/dist/ssr.d.ts +9 -3
  86. package/dist/ssr.js +11 -12
  87. package/dist/{startup-BMpaiMhP.d.ts → startup-BLfSeL15.d.cts} +73 -22
  88. package/dist/{startup-BMpaiMhP.d.cts → startup-BLfSeL15.d.ts} +73 -22
  89. package/dist/{tagFactory-DVoDpHye.d.ts → tagFactory-DFstCLQV.d.cts} +2 -100
  90. package/dist/{tagFactory-DVoDpHye.d.cts → tagFactory-DkaNVUNV.d.ts} +2 -100
  91. package/dist/testing.cjs +2484 -2185
  92. package/dist/testing.d.cts +56 -5
  93. package/dist/testing.d.ts +56 -5
  94. package/dist/testing.js +580 -307
  95. package/dist/ui.cjs +707 -317
  96. package/dist/ui.d.cts +40 -7
  97. package/dist/ui.d.ts +40 -7
  98. package/dist/ui.js +151 -56
  99. package/dist/widgets.cjs +246 -278
  100. package/dist/widgets.js +9 -10
  101. package/package.json +1 -1
  102. package/dist/chunk-2WLZ6757.js +0 -149
  103. package/dist/chunk-CCSJMTRN.js +0 -15
  104. package/dist/chunk-QKRPLZ2V.js +0 -108
  105. package/dist/chunk-VUF4ALSW.js +0 -60
  106. package/dist/chunk-WWV3SJ3L.js +0 -131
  107. package/dist/dispose-46BOMMQJ.js +0 -19
  108. package/dist/plugin-D30wlGW5.d.cts +0 -71
  109. package/dist/plugin-D30wlGW5.d.ts +0 -71
package/dist/index.cjs CHANGED
@@ -383,6 +383,23 @@ function reportDrainRunaway(label2, executed, remaining) {
383
383
  );
384
384
  }
385
385
  var activeBindingCount = 0;
386
+ function resolveCapture(capture) {
387
+ let frame = capture;
388
+ while (frame?.closed) frame = frame.forwardTo;
389
+ return frame ?? null;
390
+ }
391
+ var registrationCaptures = [];
392
+ function currentDisposerCapture() {
393
+ return resolveCapture(registrationCaptures[registrationCaptures.length - 1]);
394
+ }
395
+ function beginDisposerCapture(capture) {
396
+ if (capture === null && registrationCaptures.length === 0) return false;
397
+ registrationCaptures.push(resolveCapture(capture));
398
+ return true;
399
+ }
400
+ function endDisposerCapture() {
401
+ registrationCaptures.pop();
402
+ }
386
403
  function registerDisposer(node, teardown) {
387
404
  let disposers = elementDisposers.get(node);
388
405
  if (!disposers) {
@@ -391,15 +408,18 @@ function registerDisposer(node, teardown) {
391
408
  }
392
409
  disposers.push(teardown);
393
410
  if (DEV) activeBindingCount++;
411
+ const capture = resolveCapture(registrationCaptures[registrationCaptures.length - 1]);
412
+ if (capture) capture.entries.push([node, teardown]);
394
413
  }
395
414
  function unregisterDisposer(node, teardown) {
396
415
  const disposers = elementDisposers.get(node);
397
- if (!disposers) return;
416
+ if (!disposers) return false;
398
417
  const index = disposers.indexOf(teardown);
399
- if (index === -1) return;
418
+ if (index === -1) return false;
400
419
  disposers.splice(index, 1);
401
420
  if (DEV) activeBindingCount--;
402
421
  if (disposers.length === 0) elementDisposers.delete(node);
422
+ return true;
403
423
  }
404
424
  function dispose(node) {
405
425
  const stack = [node];
@@ -413,33 +433,34 @@ function dispose(node) {
413
433
  }
414
434
  }
415
435
  for (let i2 = order.length - 1; i2 >= 0; i2--) {
416
- const current = order[i2];
417
- if (elementDisposers.has(current)) {
418
- let executed = 0;
419
- let runaway = false;
420
- while (!runaway) {
421
- const pending = elementDisposers.get(current);
422
- if (!pending || pending.length === 0) break;
423
- const snapshot = pending.slice();
424
- elementDisposers.delete(current);
425
- if (DEV) activeBindingCount -= snapshot.length;
426
- for (let i3 = 0; i3 < snapshot.length; i3++) {
427
- if (executed >= MAX_DRAIN_TEARDOWNS) {
428
- const rest = snapshot.slice(i3);
429
- const added = elementDisposers.get(current);
430
- elementDisposers.set(current, added ? rest.concat(added) : rest);
431
- if (DEV) activeBindingCount += rest.length;
432
- reportDrainRunaway("dispose", executed, rest.length + (added?.length ?? 0));
433
- runaway = true;
434
- break;
435
- }
436
- executed++;
437
- try {
438
- snapshot[i3]();
439
- } catch (err) {
440
- reportError(err, { phase: "cleanup", name: "disposer" });
441
- }
442
- }
436
+ disposeNodeOwn(order[i2]);
437
+ }
438
+ }
439
+ function disposeNodeOwn(node) {
440
+ if (!elementDisposers.has(node)) return;
441
+ let executed = 0;
442
+ let runaway = false;
443
+ while (!runaway) {
444
+ const pending = elementDisposers.get(node);
445
+ if (!pending || pending.length === 0) break;
446
+ const snapshot = pending.slice();
447
+ elementDisposers.delete(node);
448
+ if (DEV) activeBindingCount -= snapshot.length;
449
+ for (let i2 = 0; i2 < snapshot.length; i2++) {
450
+ if (executed >= MAX_DRAIN_TEARDOWNS) {
451
+ const rest = snapshot.slice(i2);
452
+ const added = elementDisposers.get(node);
453
+ elementDisposers.set(node, added ? rest.concat(added) : rest);
454
+ if (DEV) activeBindingCount += rest.length;
455
+ reportDrainRunaway("dispose", executed, rest.length + (added?.length ?? 0));
456
+ runaway = true;
457
+ break;
458
+ }
459
+ executed++;
460
+ try {
461
+ snapshot[i2]();
462
+ } catch (err) {
463
+ reportError(err, { phase: "cleanup", name: "disposer" });
443
464
  }
444
465
  }
445
466
  }
@@ -920,6 +941,7 @@ function retrack(effectFn, subscriber) {
920
941
  }
921
942
  currentSubscriber = subscriber;
922
943
  const sub2 = subscriber;
944
+ if (sub2._cap === void 0) sub2._cap = currentDisposerCapture();
923
945
  const epoch = ++subscriberEpochCounter;
924
946
  sub2._epoch = epoch;
925
947
  sub2._structDirty = false;
@@ -1111,7 +1133,12 @@ function drainQueue() {
1111
1133
  quarantined.add(sub2);
1112
1134
  continue;
1113
1135
  }
1114
- safeInvoke(sub2);
1136
+ const pushed = beginDisposerCapture(sub2._cap ?? null);
1137
+ try {
1138
+ safeInvoke(sub2);
1139
+ } finally {
1140
+ if (pushed) endDisposerCapture();
1141
+ }
1115
1142
  }
1116
1143
  }
1117
1144
  function drainNotificationQueue() {
@@ -1247,7 +1274,7 @@ function forEachSubscriber(signal2, visit) {
1247
1274
  }
1248
1275
 
1249
1276
  // src/reactivity/track.ts
1250
- var _runtimeVersion = true ? "4.5.0" : "dev";
1277
+ var _runtimeVersion = true ? "4.6.0" : "dev";
1251
1278
  var REGISTRY_KEY = /* @__PURE__ */ Symbol.for("sibujs.reactive.v1");
1252
1279
  function resolveReactiveApi() {
1253
1280
  const g2 = globalThis;
@@ -2288,6 +2315,10 @@ function getSSRStore() {
2288
2315
  }
2289
2316
  return fallbackStore;
2290
2317
  }
2318
+ function getRequestStore() {
2319
+ if (als) return als.getStore() ?? null;
2320
+ return _shared.fallbackDepth > 0 ? fallbackStore : null;
2321
+ }
2291
2322
  function isSSR() {
2292
2323
  return getSSRStore().ssr;
2293
2324
  }
@@ -2309,16 +2340,18 @@ function disableSSR() {
2309
2340
  getSSRStore().ssr = false;
2310
2341
  }
2311
2342
  function runInSSRContext(fn) {
2312
- const store2 = { ssr: true, suspenseIdCounter: 0, locale: void 0 };
2343
+ const store2 = { ssr: true, suspenseIdCounter: 0, idCounter: 0, locale: void 0 };
2313
2344
  if (als) {
2314
2345
  return als.run(store2, fn);
2315
2346
  }
2316
2347
  warnMissingAsyncLocalStorage();
2317
2348
  const prevSSR = fallbackStore.ssr;
2318
2349
  const prevCounter = fallbackStore.suspenseIdCounter;
2350
+ const prevIdCounter = fallbackStore.idCounter;
2319
2351
  const prevLocale = fallbackStore.locale;
2320
2352
  fallbackStore.ssr = true;
2321
2353
  fallbackStore.suspenseIdCounter = 0;
2354
+ fallbackStore.idCounter = 0;
2322
2355
  fallbackStore.locale = void 0;
2323
2356
  _shared.fallbackDepth++;
2324
2357
  try {
@@ -2327,6 +2360,7 @@ function runInSSRContext(fn) {
2327
2360
  _shared.fallbackDepth--;
2328
2361
  fallbackStore.ssr = prevSSR;
2329
2362
  fallbackStore.suspenseIdCounter = prevCounter;
2363
+ fallbackStore.idCounter = prevIdCounter;
2330
2364
  fallbackStore.locale = prevLocale;
2331
2365
  }
2332
2366
  }
@@ -3498,9 +3532,14 @@ var longPress = (element, options) => {
3498
3532
  };
3499
3533
  };
3500
3534
  var copyOnClick = (element, getText) => {
3535
+ const report = (error) => reportError(error, { phase: "async", name: "copyOnClick", node: element });
3501
3536
  const handler = () => {
3502
- const text2 = typeof getText === "function" ? getText() : element.textContent ?? "";
3503
- navigator.clipboard.writeText(text2);
3537
+ try {
3538
+ const text2 = typeof getText === "function" ? getText() : element.textContent ?? "";
3539
+ Promise.resolve(navigator.clipboard.writeText(text2)).catch(report);
3540
+ } catch (error) {
3541
+ report(error);
3542
+ }
3504
3543
  };
3505
3544
  element.addEventListener("click", handler);
3506
3545
  return () => element.removeEventListener("click", handler);
@@ -3636,6 +3675,11 @@ function context(defaultValue) {
3636
3675
  var COUNTER_KEY = /* @__PURE__ */ Symbol.for("sibujs.createId.v1");
3637
3676
  var _counter = globalThis[COUNTER_KEY] ?? (globalThis[COUNTER_KEY] = { n: 0 });
3638
3677
  function createId(prefix = "sibu") {
3678
+ const request = getRequestStore();
3679
+ if (request) {
3680
+ request.idCounter = (request.idCounter ?? 0) + 1;
3681
+ return `${prefix}-${request.idCounter}`;
3682
+ }
3639
3683
  _counter.n++;
3640
3684
  return `${prefix}-${_counter.n}`;
3641
3685
  }
@@ -3673,9 +3717,11 @@ function when(condition, thenBranch, elseBranch) {
3673
3717
  let currentNode = null;
3674
3718
  let lastCondition;
3675
3719
  let initialized = false;
3720
+ let disposed = false;
3676
3721
  const attachedOnce = /* @__PURE__ */ new WeakSet();
3677
3722
  let currentNodeOwned = false;
3678
3723
  const update = () => {
3724
+ if (disposed) return;
3679
3725
  const show2 = condition();
3680
3726
  const parent = anchor.parentNode;
3681
3727
  if (!parent) return;
@@ -3694,10 +3740,14 @@ function when(condition, thenBranch, elseBranch) {
3694
3740
  restoreFocusWithin(focused, currentNode ? [currentNode] : [], "when");
3695
3741
  initialized = true;
3696
3742
  };
3697
- registerDisposer(anchor, reactiveBinding2(update, anchor));
3743
+ const stopBinding = reactiveBinding2(update, anchor);
3744
+ registerDisposer(anchor, () => {
3745
+ disposed = true;
3746
+ stopBinding();
3747
+ });
3698
3748
  if (!initialized) {
3699
3749
  queueMicrotask(() => {
3700
- if (!initialized && anchor.parentNode) update();
3750
+ if (!disposed && !initialized && anchor.parentNode) update();
3701
3751
  });
3702
3752
  }
3703
3753
  return anchor;
@@ -3707,9 +3757,11 @@ function match(value, cases, fallback) {
3707
3757
  let currentNode = null;
3708
3758
  let lastKey;
3709
3759
  let initialized = false;
3760
+ let disposed = false;
3710
3761
  const attachedOnce = /* @__PURE__ */ new WeakSet();
3711
3762
  let currentNodeOwned = false;
3712
3763
  const update = () => {
3764
+ if (disposed) return;
3713
3765
  const key = String(value());
3714
3766
  const parent = anchor.parentNode;
3715
3767
  if (!parent) return;
@@ -3728,17 +3780,30 @@ function match(value, cases, fallback) {
3728
3780
  restoreFocusWithin(focused, currentNode ? [currentNode] : [], "match");
3729
3781
  initialized = true;
3730
3782
  };
3731
- registerDisposer(anchor, reactiveBinding2(update, anchor));
3783
+ const stopBinding = reactiveBinding2(update, anchor);
3784
+ registerDisposer(anchor, () => {
3785
+ disposed = true;
3786
+ stopBinding();
3787
+ });
3732
3788
  if (!initialized) {
3733
3789
  queueMicrotask(() => {
3734
- if (!initialized && anchor.parentNode) update();
3790
+ if (!disposed && !initialized && anchor.parentNode) update();
3735
3791
  });
3736
3792
  }
3737
3793
  return anchor;
3738
3794
  }
3739
3795
 
3796
+ // src/utils/globalSingleton.ts
3797
+ function globalSingleton(key, create) {
3798
+ const g2 = globalThis;
3799
+ return g2[key] ?? (g2[key] = create());
3800
+ }
3801
+
3740
3802
  // src/core/rendering/dynamic.ts
3741
- var componentRegistry = /* @__PURE__ */ new Map();
3803
+ var componentRegistry = globalSingleton(
3804
+ /* @__PURE__ */ Symbol.for("sibujs.components.registry.v1"),
3805
+ () => /* @__PURE__ */ new Map()
3806
+ );
3742
3807
  function registerComponent(name, component) {
3743
3808
  componentRegistry.set(name, component);
3744
3809
  }
@@ -3750,7 +3815,7 @@ function resolveComponent(name) {
3750
3815
  if (component) {
3751
3816
  return component();
3752
3817
  }
3753
- return div({ nodes: `[Component "${name}" not found]` });
3818
+ return div(`[Component "${name}" not found]`);
3754
3819
  }
3755
3820
  function DynamicComponent(is) {
3756
3821
  const container = div({ class: "sibu-dynamic" });
@@ -4569,10 +4634,15 @@ function Portal(nodes, target) {
4569
4634
 
4570
4635
  // src/core/rendering/slots.ts
4571
4636
  function getSlot(slots, name = "default") {
4572
- return slots?.[name];
4637
+ if (slots == null || !Object.hasOwn(slots, name)) return void 0;
4638
+ const slot2 = slots[name];
4639
+ return typeof slot2 === "function" ? slot2 : void 0;
4573
4640
  }
4574
4641
 
4575
4642
  // src/core/signals/array.ts
4643
+ function nativeSplice(target, start, rest) {
4644
+ return rest.length === 0 ? target.splice(start) : target.splice(start, ...rest);
4645
+ }
4576
4646
  function array(initial = []) {
4577
4647
  const [arr, setArr] = signal([...initial]);
4578
4648
  const actions = {
@@ -4600,12 +4670,12 @@ function array(initial = []) {
4600
4670
  unshift(...items) {
4601
4671
  setArr((prev) => [...items, ...prev]);
4602
4672
  },
4603
- splice(start, deleteCount = 0, ...items) {
4673
+ splice(start, ...rest) {
4604
4674
  let removed = [];
4605
4675
  setArr((prev) => {
4606
4676
  const copy = [...prev];
4607
- removed = copy.splice(start, deleteCount, ...items);
4608
- return copy;
4677
+ removed = nativeSplice(copy, start, rest);
4678
+ return removed.length === 0 && rest.length <= 1 ? prev : copy;
4609
4679
  });
4610
4680
  return removed;
4611
4681
  },
@@ -4688,9 +4758,9 @@ function reactiveArray(initial = []) {
4688
4758
  data2.unshift(...items);
4689
4759
  notify();
4690
4760
  },
4691
- splice(start, deleteCount = 0, ...items) {
4692
- const removed = data2.splice(start, deleteCount, ...items);
4693
- if (removed.length > 0 || items.length > 0) {
4761
+ splice(start, ...rest) {
4762
+ const removed = nativeSplice(data2, start, rest);
4763
+ if (removed.length > 0 || rest.length > 1) {
4694
4764
  notify();
4695
4765
  }
4696
4766
  return removed;
@@ -4912,6 +4982,21 @@ function deepEqual(a2, b2, seen) {
4912
4982
  if (a2.length !== b2.length) return false;
4913
4983
  return a2.every((val, i2) => deepEqual(val, b2[i2], seen));
4914
4984
  }
4985
+ if (a2 instanceof Number || a2 instanceof String || a2 instanceof Boolean) {
4986
+ return Object.is(a2.valueOf(), b2.valueOf());
4987
+ }
4988
+ if (typeof URL !== "undefined" && a2 instanceof URL) {
4989
+ return a2.href === b2.href;
4990
+ }
4991
+ if (a2 instanceof Error) {
4992
+ const eb = b2;
4993
+ return a2.name === eb.name && a2.message === eb.message && deepEqual(a2.cause, eb.cause, seen) && plainKeysEqual(objA, objB, seen);
4994
+ }
4995
+ const proto = Object.getPrototypeOf(objA);
4996
+ if (proto !== Object.prototype && proto !== null) return false;
4997
+ return plainKeysEqual(objA, objB, seen);
4998
+ }
4999
+ function plainKeysEqual(objA, objB, seen) {
4915
5000
  const keysA = Object.keys(objA);
4916
5001
  const keysB = Object.keys(objB);
4917
5002
  if (keysA.length !== keysB.length) return false;
@@ -5047,15 +5132,18 @@ function ref(initial) {
5047
5132
  }
5048
5133
 
5049
5134
  // src/core/signals/store.ts
5135
+ function defineOwn(obj, key, value) {
5136
+ Object.defineProperty(obj, key, { value, writable: true, enumerable: true, configurable: true });
5137
+ }
5050
5138
  function store(initialState) {
5051
5139
  devAssert(
5052
5140
  initialState !== null && typeof initialState === "object" && !Array.isArray(initialState),
5053
5141
  "store: argument must be a plain object. For arrays, use array() instead."
5054
5142
  );
5055
- const signals = {};
5143
+ const signals = /* @__PURE__ */ Object.create(null);
5056
5144
  Object.keys(initialState).forEach((key) => {
5057
5145
  const [getter, setter] = signal(initialState[key]);
5058
- signals[key] = [getter, setter];
5146
+ defineOwn(signals, key, [getter, setter]);
5059
5147
  });
5060
5148
  const store2 = new Proxy({}, {
5061
5149
  get(target, prop) {
@@ -5074,7 +5162,7 @@ function store(initialState) {
5074
5162
  const getSnapshot = () => {
5075
5163
  const snapshot = {};
5076
5164
  Object.keys(signals).forEach((key) => {
5077
- snapshot[key] = signals[key][0]();
5165
+ defineOwn(snapshot, key, signals[key][0]());
5078
5166
  });
5079
5167
  return snapshot;
5080
5168
  };
@@ -5210,6 +5298,13 @@ function strictEffect(fn) {
5210
5298
  };
5211
5299
  }
5212
5300
 
5301
+ // src/reactivity/domBinding.ts
5302
+ function domBinding(commit, ownerNode) {
5303
+ if (isSSR()) return () => {
5304
+ };
5305
+ return reactiveBinding2(commit, ownerNode);
5306
+ }
5307
+
5213
5308
  // src/platform/enhance.ts
5214
5309
  var ENHANCED_ATTR = "data-sibu-enhanced";
5215
5310
  var enhancementOwner = /* @__PURE__ */ new WeakMap();
@@ -5245,9 +5340,7 @@ function resolveTarget(root, target) {
5245
5340
  }
5246
5341
  }
5247
5342
  function bindNode(el, commit) {
5248
- if (isSSR()) return () => {
5249
- };
5250
- return reactiveBinding2(commit, el);
5343
+ return domBinding(commit, el);
5251
5344
  }
5252
5345
  function readControlValue(el) {
5253
5346
  if (el instanceof HTMLInputElement) {
@@ -5505,12 +5598,6 @@ function enhanceAll(selector, setup) {
5505
5598
  };
5506
5599
  }
5507
5600
 
5508
- // src/utils/globalSingleton.ts
5509
- function globalSingleton(key, create) {
5510
- const g2 = globalThis;
5511
- return g2[key] ?? (g2[key] = create());
5512
- }
5513
-
5514
5601
  // src/platform/islands.ts
5515
5602
  var SAFE_NAME = /^[A-Za-z0-9_-]+$/;
5516
5603
  var LAZY = /* @__PURE__ */ Symbol.for("sibujs.islands.lazy");
@@ -5667,6 +5754,27 @@ function trustHTML(html3) {
5667
5754
  }
5668
5755
  var DEFAULT_MAX_SSR_BYTES = 1024 * 1024;
5669
5756
 
5757
+ // src/utils/adoptThenable.ts
5758
+ function adoptThenable(value) {
5759
+ if (value === null || typeof value !== "object" && typeof value !== "function") return null;
5760
+ let then;
5761
+ try {
5762
+ then = value.then;
5763
+ } catch (error) {
5764
+ return Promise.reject(error);
5765
+ }
5766
+ if (typeof then !== "function") return null;
5767
+ return new Promise((resolve, reject) => {
5768
+ queueMicrotask(() => {
5769
+ try {
5770
+ Reflect.apply(then, value, [resolve, reject]);
5771
+ } catch (error) {
5772
+ reject(error);
5773
+ }
5774
+ });
5775
+ });
5776
+ }
5777
+
5670
5778
  // src/reactivity/concurrent.ts
5671
5779
  function defer(getter) {
5672
5780
  const [value, setValue] = signal(getter());
@@ -5716,23 +5824,27 @@ function scheduleIdle(fn) {
5716
5824
  }
5717
5825
  function transition() {
5718
5826
  const [pending, setPending] = signal(false);
5827
+ let outstanding = 0;
5719
5828
  function start(fn) {
5829
+ outstanding++;
5720
5830
  setPending(true);
5831
+ let settled = false;
5832
+ const finish = () => {
5833
+ if (settled) return;
5834
+ settled = true;
5835
+ outstanding--;
5836
+ if (outstanding === 0) setPending(false);
5837
+ };
5838
+ const fail = (error) => {
5839
+ finish();
5840
+ reportError(error, { phase: "async", name: "transition" });
5841
+ };
5721
5842
  scheduleIdle(() => {
5722
- let result;
5723
5843
  try {
5724
- result = fn();
5725
- } catch {
5726
- setPending(false);
5727
- return;
5728
- }
5729
- if (result && typeof result.then === "function") {
5730
- result.then(
5731
- () => setPending(false),
5732
- () => setPending(false)
5733
- );
5734
- } else {
5735
- setPending(false);
5844
+ const adopted = adoptThenable(fn());
5845
+ adopted ? adopted.then(finish, fail) : finish();
5846
+ } catch (error) {
5847
+ fail(error);
5736
5848
  }
5737
5849
  });
5738
5850
  }
package/dist/index.d.cts CHANGED
@@ -1,6 +1,8 @@
1
- import { N as NodeChild, a as NodeChildren, T as TagProps, A as Accessor, D as DerivedAccessor } from './tagFactory-DVoDpHye.cjs';
2
- export { b as Dispose, E as ExternalSource, S as SVG_NS, c as SignalOptions, d as derived, e as external, s as signal, t as tagFactory } from './tagFactory-DVoDpHye.cjs';
3
- export { T as TrustedHTML, t as trustHTML } from './ssr-BiPRdZ6n.cjs';
1
+ import { N as NodeChild, a as NodeChildren, T as TagProps, D as DerivedAccessor } from './tagFactory-DFstCLQV.cjs';
2
+ export { b as Dispose, S as SVG_NS, d as derived, t as tagFactory } from './tagFactory-DFstCLQV.cjs';
3
+ import { A as Accessor } from './signal-EotCj4hS.cjs';
4
+ export { D as DisposableAccessor, E as ExternalSource, S as SignalOptions, e as external, s as signal } from './signal-EotCj4hS.cjs';
5
+ export { T as TrustedHTML, t as trustHTML } from './ssr-Bli9XRW5.cjs';
4
6
  import { R as ReactiveSignal } from './signal-BnWpq6WB.cjs';
5
7
 
6
8
  interface ErrorBoundaryOptions {
@@ -416,6 +418,11 @@ declare function context<T>(defaultValue: T): Context<T>;
416
418
  *
417
419
  * Each call returns a fresh incrementing id. Optionally accepts a prefix.
418
420
  *
421
+ * Inside an SSR request (`runInSSRContext`) the counter belongs to that request,
422
+ * so every request's ids start from 1 — independent of earlier or concurrent
423
+ * requests, and identical to a fresh client's sequence for hydration. Outside a
424
+ * request the shared client counter is used.
425
+ *
419
426
  * IDs are plain strings (not reactive) — call once per component instance
420
427
  * and reuse the returned value for both sides of the association.
421
428
  *
@@ -558,7 +565,7 @@ declare function registerDisposer(node: Node, teardown: () => void): void;
558
565
  * The teardown is assumed to have already run (or to be deliberately abandoned);
559
566
  * this only releases the reference.
560
567
  */
561
- declare function unregisterDisposer(node: Node, teardown: () => void): void;
568
+ declare function unregisterDisposer(node: Node, teardown: () => void): boolean;
562
569
  /**
563
570
  * Run all registered teardowns for a node and its descendants,
564
571
  * cleaning up reactive subscriptions to prevent memory leaks.
@@ -1206,6 +1213,8 @@ type Slots = Record<string, SlotFn>;
1206
1213
  * @param slots The slot map, which may be undefined.
1207
1214
  * @param name Slot name; defaults to `"default"`.
1208
1215
  * @returns The slot factory, or `undefined` when the slot was not provided.
1216
+ * Only an OWN function-valued entry counts: an inherited member such as
1217
+ * `toString` or `constructor` is not a slot, so fallback content renders.
1209
1218
  */
1210
1219
  declare function getSlot(slots: Slots | undefined, name?: string): SlotFn | undefined;
1211
1220
 
@@ -1597,6 +1606,13 @@ declare function writable<T>(get: () => T, set: (value: T) => void, options?: {
1597
1606
  interface SSRStore {
1598
1607
  ssr: boolean;
1599
1608
  suspenseIdCounter: number;
1609
+ /**
1610
+ * `createId()` counter for this request. Request-scoped for the same reason
1611
+ * as `suspenseIdCounter`: a server render's ids must not depend on earlier or
1612
+ * concurrent requests, and must match a fresh client's sequence. Optional so
1613
+ * stores created elsewhere start it lazily at 0.
1614
+ */
1615
+ idCounter?: number;
1600
1616
  /**
1601
1617
  * Per-request data caches (e.g. the query cache). Lazily created and keyed
1602
1618
  * by subsystem so request-scoped data never bleeds between concurrent
@@ -2045,7 +2061,8 @@ interface TransitionState {
2045
2061
  * and avoids the complexity of an interruptible reconciler.
2046
2062
  *
2047
2063
  * Async callbacks are supported: `pending()` stays `true` until the
2048
- * returned promise resolves OR rejects.
2064
+ * returned promise resolves OR rejects. With overlapping `start()` calls it
2065
+ * stays `true` until every one of them has settled.
2049
2066
  *
2050
2067
  * @example
2051
2068
  * ```ts
package/dist/index.d.ts CHANGED
@@ -1,6 +1,8 @@
1
- import { N as NodeChild, a as NodeChildren, T as TagProps, A as Accessor, D as DerivedAccessor } from './tagFactory-DVoDpHye.js';
2
- export { b as Dispose, E as ExternalSource, S as SVG_NS, c as SignalOptions, d as derived, e as external, s as signal, t as tagFactory } from './tagFactory-DVoDpHye.js';
3
- export { T as TrustedHTML, t as trustHTML } from './ssr-BiPRdZ6n.js';
1
+ import { N as NodeChild, a as NodeChildren, T as TagProps, D as DerivedAccessor } from './tagFactory-DkaNVUNV.js';
2
+ export { b as Dispose, S as SVG_NS, d as derived, t as tagFactory } from './tagFactory-DkaNVUNV.js';
3
+ import { A as Accessor } from './signal-EotCj4hS.js';
4
+ export { D as DisposableAccessor, E as ExternalSource, S as SignalOptions, e as external, s as signal } from './signal-EotCj4hS.js';
5
+ export { T as TrustedHTML, t as trustHTML } from './ssr-Bli9XRW5.js';
4
6
  import { R as ReactiveSignal } from './signal-BnWpq6WB.js';
5
7
 
6
8
  interface ErrorBoundaryOptions {
@@ -416,6 +418,11 @@ declare function context<T>(defaultValue: T): Context<T>;
416
418
  *
417
419
  * Each call returns a fresh incrementing id. Optionally accepts a prefix.
418
420
  *
421
+ * Inside an SSR request (`runInSSRContext`) the counter belongs to that request,
422
+ * so every request's ids start from 1 — independent of earlier or concurrent
423
+ * requests, and identical to a fresh client's sequence for hydration. Outside a
424
+ * request the shared client counter is used.
425
+ *
419
426
  * IDs are plain strings (not reactive) — call once per component instance
420
427
  * and reuse the returned value for both sides of the association.
421
428
  *
@@ -558,7 +565,7 @@ declare function registerDisposer(node: Node, teardown: () => void): void;
558
565
  * The teardown is assumed to have already run (or to be deliberately abandoned);
559
566
  * this only releases the reference.
560
567
  */
561
- declare function unregisterDisposer(node: Node, teardown: () => void): void;
568
+ declare function unregisterDisposer(node: Node, teardown: () => void): boolean;
562
569
  /**
563
570
  * Run all registered teardowns for a node and its descendants,
564
571
  * cleaning up reactive subscriptions to prevent memory leaks.
@@ -1206,6 +1213,8 @@ type Slots = Record<string, SlotFn>;
1206
1213
  * @param slots The slot map, which may be undefined.
1207
1214
  * @param name Slot name; defaults to `"default"`.
1208
1215
  * @returns The slot factory, or `undefined` when the slot was not provided.
1216
+ * Only an OWN function-valued entry counts: an inherited member such as
1217
+ * `toString` or `constructor` is not a slot, so fallback content renders.
1209
1218
  */
1210
1219
  declare function getSlot(slots: Slots | undefined, name?: string): SlotFn | undefined;
1211
1220
 
@@ -1597,6 +1606,13 @@ declare function writable<T>(get: () => T, set: (value: T) => void, options?: {
1597
1606
  interface SSRStore {
1598
1607
  ssr: boolean;
1599
1608
  suspenseIdCounter: number;
1609
+ /**
1610
+ * `createId()` counter for this request. Request-scoped for the same reason
1611
+ * as `suspenseIdCounter`: a server render's ids must not depend on earlier or
1612
+ * concurrent requests, and must match a fresh client's sequence. Optional so
1613
+ * stores created elsewhere start it lazily at 0.
1614
+ */
1615
+ idCounter?: number;
1600
1616
  /**
1601
1617
  * Per-request data caches (e.g. the query cache). Lazily created and keyed
1602
1618
  * by subsystem so request-scoped data never bleeds between concurrent
@@ -2045,7 +2061,8 @@ interface TransitionState {
2045
2061
  * and avoids the complexity of an interruptible reconciler.
2046
2062
  *
2047
2063
  * Async callbacks are supported: `pending()` stays `true` until the
2048
- * returned promise resolves OR rejects.
2064
+ * returned promise resolves OR rejects. With overlapping `start()` calls it
2065
+ * stays `true` until every one of them has settled.
2049
2066
  *
2050
2067
  * @example
2051
2068
  * ```ts