sibujs 3.3.0 → 3.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/dist/browser.cjs +210 -26
  2. package/dist/browser.js +4 -4
  3. package/dist/build.cjs +193 -89
  4. package/dist/build.js +10 -10
  5. package/dist/cdn.global.js +7 -7
  6. package/dist/{chunk-24DBWDTK.js → chunk-37BUKSLH.js} +1 -1
  7. package/dist/{chunk-IHBVTURX.js → chunk-4UUMSLSL.js} +4 -4
  8. package/dist/{chunk-USDR2GFV.js → chunk-6LTFHJQG.js} +3 -3
  9. package/dist/{chunk-MWZFOIBG.js → chunk-AMIKDMLP.js} +4 -4
  10. package/dist/{chunk-JBXNCZSC.js → chunk-F7FXQ3QS.js} +1 -1
  11. package/dist/{chunk-BEIKESVL.js → chunk-IKLYI3RF.js} +9 -9
  12. package/dist/{chunk-NUWKIEHE.js → chunk-LU2MQXQQ.js} +2 -2
  13. package/dist/{chunk-WVJJUFPC.js → chunk-M5KBNOSJ.js} +2 -2
  14. package/dist/{chunk-7JHWAGRQ.js → chunk-MHBCEJQO.js} +1 -1
  15. package/dist/{chunk-Q2ERM6NT.js → chunk-NHKQKKZU.js} +1 -1
  16. package/dist/{chunk-6G6UNHZI.js → chunk-RYMOSG5B.js} +5 -5
  17. package/dist/{chunk-F4UM7QBJ.js → chunk-SLMFA3ZZ.js} +1 -1
  18. package/dist/{chunk-X3NHE2DK.js → chunk-TEFZT5PJ.js} +83 -17
  19. package/dist/{chunk-SLCUP2EK.js → chunk-ULLTNDRA.js} +3 -3
  20. package/dist/{chunk-M6WSIGYW.js → chunk-VOVVTOEA.js} +2 -2
  21. package/dist/{chunk-XQ7XSGYP.js → chunk-WL7BIR6O.js} +1 -1
  22. package/dist/{chunk-CVMMULHO.js → chunk-WW6DAGGR.js} +4 -4
  23. package/dist/{chunk-5K72I3UQ.js → chunk-WZG2SZOT.js} +21 -4
  24. package/dist/{chunk-S4FHR5ZZ.js → chunk-XH2RTYEQ.js} +3 -3
  25. package/dist/{chunk-4WXWJ4SW.js → chunk-Z37APKBV.js} +4 -4
  26. package/dist/data.cjs +161 -23
  27. package/dist/data.js +6 -6
  28. package/dist/devtools.cjs +245 -31
  29. package/dist/devtools.js +4 -4
  30. package/dist/ecosystem.cjs +183 -45
  31. package/dist/ecosystem.js +7 -7
  32. package/dist/extras.cjs +185 -86
  33. package/dist/extras.js +19 -19
  34. package/dist/index.cjs +193 -89
  35. package/dist/index.d.cts +59 -8
  36. package/dist/index.d.ts +59 -8
  37. package/dist/index.js +10 -10
  38. package/dist/motion.cjs +329 -13
  39. package/dist/motion.js +3 -3
  40. package/dist/patterns.cjs +161 -23
  41. package/dist/patterns.js +5 -5
  42. package/dist/performance.cjs +258 -23
  43. package/dist/performance.js +4 -4
  44. package/dist/plugins.cjs +244 -51
  45. package/dist/plugins.js +6 -6
  46. package/dist/ssr.cjs +183 -44
  47. package/dist/ssr.js +7 -7
  48. package/dist/testing.cjs +396 -5
  49. package/dist/testing.js +2 -2
  50. package/dist/ui.cjs +221 -32
  51. package/dist/ui.js +6 -6
  52. package/dist/widgets.cjs +146 -26
  53. package/dist/widgets.js +6 -6
  54. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -170,7 +170,7 @@ __export(index_exports, {
170
170
  registerComponent: () => registerComponent,
171
171
  registerDisposer: () => registerDisposer,
172
172
  resolveComponent: () => resolveComponent,
173
- retrack: () => retrack,
173
+ retrack: () => retrack2,
174
174
  rp: () => rp,
175
175
  rt: () => rt,
176
176
  ruby: () => ruby,
@@ -181,7 +181,7 @@ __export(index_exports, {
181
181
  section: () => section,
182
182
  select: () => select,
183
183
  setGlobalErrorHandler: () => setGlobalErrorHandler,
184
- setMaxDrainIterations: () => setMaxDrainIterations,
184
+ setMaxDrainIterations: () => setMaxDrainIterations2,
185
185
  show: () => show,
186
186
  signal: () => signal,
187
187
  slot: () => slot,
@@ -213,7 +213,7 @@ __export(index_exports, {
213
213
  time: () => time,
214
214
  title: () => title,
215
215
  tr: () => tr,
216
- track: () => track2,
216
+ track: () => track3,
217
217
  transition: () => transition,
218
218
  trapFocus: () => trapFocus,
219
219
  trustHTML: () => trustHTML,
@@ -221,7 +221,7 @@ __export(index_exports, {
221
221
  u: () => u,
222
222
  ul: () => ul,
223
223
  unregisterComponent: () => unregisterComponent,
224
- untracked: () => untracked,
224
+ untracked: () => untracked2,
225
225
  use: () => use,
226
226
  var_: () => var_,
227
227
  video: () => video,
@@ -339,7 +339,7 @@ function sanitizeAttributeString(attr, value) {
339
339
  return value;
340
340
  }
341
341
 
342
- // src/reactivity/track.ts
342
+ // src/reactivity/track-core.ts
343
343
  var _isDev2 = isDev();
344
344
  var POOL_MAX = 4096;
345
345
  var nodePool = [];
@@ -453,6 +453,9 @@ function resumeTracking() {
453
453
  trackingSuspended = false;
454
454
  }
455
455
  }
456
+ function isTrackingSuspended() {
457
+ return trackingSuspended;
458
+ }
456
459
  function untracked(fn) {
457
460
  suspendTracking();
458
461
  try {
@@ -570,6 +573,11 @@ function cleanup(subscriber) {
570
573
  var maxSubscriberRepeats = 50;
571
574
  var maxDrainIterations = 1e6;
572
575
  var drainEpoch = 0;
576
+ function setMaxSubscriberRepeats(n) {
577
+ const prev = maxSubscriberRepeats;
578
+ if (Number.isFinite(n) && n > 0) maxSubscriberRepeats = Math.floor(n);
579
+ return prev;
580
+ }
573
581
  function setMaxDrainIterations(n) {
574
582
  const prev = maxDrainIterations;
575
583
  if (Number.isFinite(n) && n > 0) maxDrainIterations = Math.floor(n);
@@ -723,15 +731,94 @@ function notifySubscribers(signal2) {
723
731
  }
724
732
  }
725
733
  }
734
+ function getSubscriberCount(signal2) {
735
+ return signal2.__sc ?? 0;
736
+ }
737
+ function getSubscriberDeps(subscriber) {
738
+ const sub2 = subscriber;
739
+ const out = [];
740
+ let node = sub2.depsHead ?? null;
741
+ while (node) {
742
+ if (node.sig) out.push(node.sig);
743
+ node = node.subNext;
744
+ }
745
+ return out;
746
+ }
747
+ function forEachSubscriber(signal2, visit) {
748
+ let node = signal2.subsHead ?? null;
749
+ while (node) {
750
+ const s2 = node.sub;
751
+ if (s2) visit(s2);
752
+ node = node.sigNext;
753
+ }
754
+ }
726
755
 
727
- // src/reactivity/bindAttribute.ts
756
+ // src/reactivity/track.ts
728
757
  var _isDev3 = isDev();
758
+ var _runtimeVersion = typeof __SIBU_VERSION__ !== "undefined" ? __SIBU_VERSION__ : "dev";
759
+ var REGISTRY_KEY = /* @__PURE__ */ Symbol.for("sibujs.reactive.v1");
760
+ function resolveReactiveApi() {
761
+ const g2 = globalThis;
762
+ const existing = g2[REGISTRY_KEY];
763
+ if (existing) {
764
+ if (_isDev3 && !existing.__dupWarned) {
765
+ existing.__dupWarned = true;
766
+ devWarn(
767
+ `Multiple instances of the reactive runtime detected on this page (active: ${existing.version}, duplicate: ${_runtimeVersion}). Reactivity still works \u2014 all copies share the first one \u2014 but de-duplicate sibujs in your bundler (e.g. Vite optimizeDeps.exclude: ['sibujs'] or resolve.dedupe: ['sibujs']).`
768
+ );
769
+ }
770
+ return existing;
771
+ }
772
+ const local = {
773
+ suspendTracking,
774
+ resumeTracking,
775
+ isTrackingSuspended,
776
+ untracked,
777
+ retrack,
778
+ track,
779
+ reactiveBinding,
780
+ recordDependency,
781
+ cleanup,
782
+ setMaxSubscriberRepeats,
783
+ setMaxDrainIterations,
784
+ drainNotificationQueue,
785
+ queueSignalNotification,
786
+ notifySubscribers,
787
+ getSubscriberCount,
788
+ getSubscriberDeps,
789
+ forEachSubscriber,
790
+ version: _runtimeVersion
791
+ };
792
+ g2[REGISTRY_KEY] = local;
793
+ return local;
794
+ }
795
+ var API = resolveReactiveApi();
796
+ var suspendTracking2 = API.suspendTracking;
797
+ var resumeTracking2 = API.resumeTracking;
798
+ var isTrackingSuspended2 = API.isTrackingSuspended;
799
+ var untracked2 = API.untracked;
800
+ var retrack2 = API.retrack;
801
+ var track2 = API.track;
802
+ var reactiveBinding2 = API.reactiveBinding;
803
+ var recordDependency2 = API.recordDependency;
804
+ var cleanup2 = API.cleanup;
805
+ var setMaxSubscriberRepeats2 = API.setMaxSubscriberRepeats;
806
+ var setMaxDrainIterations2 = API.setMaxDrainIterations;
807
+ var drainNotificationQueue2 = API.drainNotificationQueue;
808
+ var queueSignalNotification2 = API.queueSignalNotification;
809
+ var notifySubscribers2 = API.notifySubscribers;
810
+ var getSubscriberCount2 = API.getSubscriberCount;
811
+ var getSubscriberDeps2 = API.getSubscriberDeps;
812
+ var forEachSubscriber2 = API.forEachSubscriber;
813
+
814
+ // src/reactivity/bindAttribute.ts
815
+ var _isDev4 = isDev();
729
816
  function setProp(el, key, val) {
730
817
  el[key] = val;
731
818
  }
732
819
  function bindAttribute(el, attr, getter) {
733
820
  if (isEventHandlerAttr(attr)) {
734
- if (_isDev3)
821
+ if (_isDev4)
735
822
  devWarn(
736
823
  `bindAttribute: refusing to bind event-handler attribute "${attr}". Use on:{ ${attr.slice(2)}: fn } instead.`
737
824
  );
@@ -743,7 +830,7 @@ function bindAttribute(el, attr, getter) {
743
830
  try {
744
831
  value = getter();
745
832
  } catch (err) {
746
- if (_isDev3)
833
+ if (_isDev4)
747
834
  devWarn(`bindAttribute: getter for "${attr}" threw: ${err instanceof Error ? err.message : String(err)}`);
748
835
  return;
749
836
  }
@@ -764,7 +851,7 @@ function bindAttribute(el, attr, getter) {
764
851
  el.setAttribute(attr, sanitizeAttributeString(attr, str));
765
852
  }
766
853
  }
767
- return reactiveBinding(commit);
854
+ return reactiveBinding2(commit);
768
855
  }
769
856
  function bindDynamic(el, nameGetter, valueGetter) {
770
857
  let prevName = null;
@@ -773,14 +860,14 @@ function bindDynamic(el, nameGetter, valueGetter) {
773
860
  try {
774
861
  name = typeof nameGetter === "function" ? nameGetter() : nameGetter;
775
862
  } catch (err) {
776
- if (_isDev3) devWarn(`bindDynamic: name getter threw: ${err instanceof Error ? err.message : String(err)}`);
863
+ if (_isDev4) devWarn(`bindDynamic: name getter threw: ${err instanceof Error ? err.message : String(err)}`);
777
864
  return;
778
865
  }
779
866
  let value;
780
867
  try {
781
868
  value = typeof valueGetter === "function" ? valueGetter() : valueGetter;
782
869
  } catch (err) {
783
- if (_isDev3) devWarn(`bindDynamic: value getter threw: ${err instanceof Error ? err.message : String(err)}`);
870
+ if (_isDev4) devWarn(`bindDynamic: value getter threw: ${err instanceof Error ? err.message : String(err)}`);
784
871
  return;
785
872
  }
786
873
  if (isEventHandlerAttr(name)) return;
@@ -795,7 +882,7 @@ function bindDynamic(el, nameGetter, valueGetter) {
795
882
  }
796
883
  prevName = name;
797
884
  }
798
- const teardown = reactiveBinding(commit);
885
+ const teardown = reactiveBinding2(commit);
799
886
  return () => {
800
887
  teardown();
801
888
  if (prevName !== null) {
@@ -806,7 +893,7 @@ function bindDynamic(el, nameGetter, valueGetter) {
806
893
 
807
894
  // src/core/rendering/dispose.ts
808
895
  var elementDisposers = /* @__PURE__ */ new WeakMap();
809
- var _isDev4 = isDev();
896
+ var _isDev5 = isDev();
810
897
  var activeBindingCount = 0;
811
898
  function registerDisposer(node, teardown) {
812
899
  let disposers = elementDisposers.get(node);
@@ -815,7 +902,7 @@ function registerDisposer(node, teardown) {
815
902
  elementDisposers.set(node, disposers);
816
903
  }
817
904
  disposers.push(teardown);
818
- if (_isDev4) activeBindingCount++;
905
+ if (_isDev5) activeBindingCount++;
819
906
  }
820
907
  function dispose(node) {
821
908
  const stack = [node];
@@ -834,12 +921,12 @@ function dispose(node) {
834
921
  if (disposers) {
835
922
  const snapshot = disposers.slice();
836
923
  elementDisposers.delete(current);
837
- if (_isDev4) activeBindingCount -= snapshot.length;
924
+ if (_isDev5) activeBindingCount -= snapshot.length;
838
925
  for (const d of snapshot) {
839
926
  try {
840
927
  d();
841
928
  } catch (err) {
842
- if (_isDev4 && typeof console !== "undefined") {
929
+ if (_isDev5 && typeof console !== "undefined") {
843
930
  console.warn("[SibuJS] Disposer threw during cleanup:", err);
844
931
  }
845
932
  }
@@ -850,12 +937,12 @@ function dispose(node) {
850
937
  if (!added || added.length === 0) break;
851
938
  const moreSnapshot = added.slice();
852
939
  elementDisposers.delete(current);
853
- if (_isDev4) activeBindingCount -= moreSnapshot.length;
940
+ if (_isDev5) activeBindingCount -= moreSnapshot.length;
854
941
  for (const d of moreSnapshot) {
855
942
  try {
856
943
  d();
857
944
  } catch (err) {
858
- if (_isDev4 && typeof console !== "undefined") {
945
+ if (_isDev5 && typeof console !== "undefined") {
859
946
  console.warn("[SibuJS] Disposer threw during cleanup:", err);
860
947
  }
861
948
  }
@@ -865,7 +952,7 @@ function dispose(node) {
865
952
  }
866
953
  }
867
954
  function checkLeaks(warnThreshold = 0) {
868
- if (!_isDev4) return 0;
955
+ if (!_isDev5) return 0;
869
956
  if (warnThreshold > 0 && activeBindingCount > warnThreshold) {
870
957
  devWarn(
871
958
  `checkLeaks: ${activeBindingCount} active DOM bindings detected. Expected \u2264${warnThreshold}. This may indicate a component was removed from the DOM without calling dispose().`
@@ -875,7 +962,7 @@ function checkLeaks(warnThreshold = 0) {
875
962
  }
876
963
 
877
964
  // src/reactivity/bindChildNode.ts
878
- var _isDev5 = isDev();
965
+ var _isDev6 = isDev();
879
966
  function bindChildNode(placeholder, getter) {
880
967
  let lastNodes = [];
881
968
  function commit() {
@@ -883,7 +970,7 @@ function bindChildNode(placeholder, getter) {
883
970
  try {
884
971
  result = getter();
885
972
  } catch (err) {
886
- if (_isDev5) devWarn(`bindChildNode: getter threw: ${err instanceof Error ? err.message : String(err)}`);
973
+ if (_isDev6) devWarn(`bindChildNode: getter threw: ${err instanceof Error ? err.message : String(err)}`);
887
974
  return;
888
975
  }
889
976
  if (result == null || typeof result === "boolean") {
@@ -909,7 +996,7 @@ function bindChildNode(placeholder, getter) {
909
996
  if (item == null || typeof item === "boolean") continue;
910
997
  const node = item instanceof Node ? item : document.createTextNode(String(item));
911
998
  if (seen.has(node)) {
912
- if (_isDev5)
999
+ if (_isDev6)
913
1000
  devWarn("bindChildNode: duplicate node reference in array \u2014 only the first occurrence is rendered.");
914
1001
  continue;
915
1002
  }
@@ -944,12 +1031,12 @@ function bindChildNode(placeholder, getter) {
944
1031
  }
945
1032
  lastNodes = newNodes;
946
1033
  }
947
- return reactiveBinding(commit);
1034
+ return reactiveBinding2(commit);
948
1035
  }
949
1036
 
950
1037
  // src/core/rendering/tagFactory.ts
951
1038
  var SVG_NS = "http://www.w3.org/2000/svg";
952
- var _isDev6 = isDev();
1039
+ var _isDev7 = isDev();
953
1040
  var BLOCKED_TAGS = /* @__PURE__ */ new Set(["script", "iframe", "object", "embed", "frame", "frameset"]);
954
1041
  function isBlockedTag(tag) {
955
1042
  return BLOCKED_TAGS.has(tag.toLowerCase());
@@ -992,7 +1079,7 @@ function toKebab(prop) {
992
1079
  }
993
1080
  function applyStyle(el, style2) {
994
1081
  if (typeof style2 === "function") {
995
- const teardown = track(() => {
1082
+ const teardown = track2(() => {
996
1083
  el.setAttribute("style", style2());
997
1084
  });
998
1085
  registerDisposer(el, teardown);
@@ -1008,7 +1095,7 @@ function applyStyle(el, style2) {
1008
1095
  const name = toKebab(prop);
1009
1096
  if (typeof val === "function") {
1010
1097
  const getter = val;
1011
- const teardown = track(() => {
1098
+ const teardown = track2(() => {
1012
1099
  htmlEl.style.setProperty(name, sanitizeCSSValue(String(getter())));
1013
1100
  });
1014
1101
  registerDisposer(el, teardown);
@@ -1023,7 +1110,7 @@ function applyClass(el, cls) {
1023
1110
  return;
1024
1111
  }
1025
1112
  if (typeof cls === "function") {
1026
- const teardown = track(() => {
1113
+ const teardown = track2(() => {
1027
1114
  el.setAttribute("class", cls());
1028
1115
  });
1029
1116
  registerDisposer(el, teardown);
@@ -1050,7 +1137,7 @@ function applyClass(el, cls) {
1050
1137
  }
1051
1138
  el.setAttribute("class", r);
1052
1139
  };
1053
- const teardown = track(update);
1140
+ const teardown = track2(update);
1054
1141
  registerDisposer(el, teardown);
1055
1142
  } else {
1056
1143
  el.setAttribute("class", result);
@@ -1120,7 +1207,7 @@ var tagFactory = (tag, ns) => {
1120
1207
  appendChildren(el, second);
1121
1208
  return el;
1122
1209
  }
1123
- if (_isDev6 && looksLikeClassList(first)) {
1210
+ if (_isDev7 && looksLikeClassList(first)) {
1124
1211
  devWarn(
1125
1212
  `tagFactory: lone string "${first}" looks like a class list but is being rendered as TEXT. For a class, use ${tag}({ class: "${first}" }) \u2014 or ${tag}("${first}", children) to set the class AND add children.`
1126
1213
  );
@@ -1141,7 +1228,7 @@ var tagFactory = (tag, ns) => {
1141
1228
  if (pClass != null) applyClass(el, pClass);
1142
1229
  const pId = props.id;
1143
1230
  if (pId != null) {
1144
- if (_isDev6 && typeof pId === "string" && CLOBBER_RISKY_IDS.has(pId.toLowerCase())) {
1231
+ if (_isDev7 && typeof pId === "string" && CLOBBER_RISKY_IDS.has(pId.toLowerCase())) {
1145
1232
  devWarn(
1146
1233
  `tagFactory: element id="${pId}" matches a common global and may cause DOM clobbering. Avoid setting ids from untrusted input.`
1147
1234
  );
@@ -1156,7 +1243,7 @@ var tagFactory = (tag, ns) => {
1156
1243
  const handler = pOn[ev];
1157
1244
  if (typeof handler === "function") {
1158
1245
  el.addEventListener(ev, handler);
1159
- } else if (_isDev6) {
1246
+ } else if (_isDev7) {
1160
1247
  devWarn(
1161
1248
  `tagFactory: on.${ev} handler is not a function (got ${typeof handler}). Event listener was not attached.`
1162
1249
  );
@@ -1269,7 +1356,7 @@ var area = tagFactory("area");
1269
1356
  var audio = tagFactory("audio");
1270
1357
  var img = tagFactory("img");
1271
1358
  var map = tagFactory("map");
1272
- var track2 = tagFactory("track");
1359
+ var track3 = tagFactory("track");
1273
1360
  var video = tagFactory("video");
1274
1361
  var embed = tagFactory("embed");
1275
1362
  var iframe = tagFactory("iframe");
@@ -1345,7 +1432,7 @@ var marquee = tagFactory("marquee");
1345
1432
  var customElement = (tagName) => tagFactory(tagName);
1346
1433
 
1347
1434
  // src/core/rendering/htm.ts
1348
- var _isDev7 = isDev();
1435
+ var _isDev8 = isDev();
1349
1436
  var RAW_TEXT_TAGS = /* @__PURE__ */ new Set(["script", "style"]);
1350
1437
  var VOID_ELEMENTS = /* @__PURE__ */ new Set([
1351
1438
  "area",
@@ -1641,7 +1728,7 @@ function executeElement(tmpl, values) {
1641
1728
  const fn = values[attr.idx];
1642
1729
  if (typeof fn === "function") {
1643
1730
  el.addEventListener(attr.name, fn);
1644
- } else if (_isDev7) {
1731
+ } else if (_isDev8) {
1645
1732
  devWarn(
1646
1733
  `html: on:${attr.name} handler is not a function (got ${typeof fn}). Event listener was not attached.`
1647
1734
  );
@@ -1769,7 +1856,7 @@ function mount(component, container) {
1769
1856
  }
1770
1857
 
1771
1858
  // src/core/rendering/each.ts
1772
- var _isDev8 = isDev();
1859
+ var _isDev9 = isDev();
1773
1860
  function resolveNodeChild(child) {
1774
1861
  if (typeof child === "function") {
1775
1862
  return resolveNodeChild(child());
@@ -1854,7 +1941,7 @@ function each(getArray, render, options) {
1854
1941
  workMap.clear();
1855
1942
  keyIndexMap.clear();
1856
1943
  for (let i2 = 0; i2 < newLen; i2++) {
1857
- if (_isDev8 && keyIndexMap.has(newKeys[i2])) {
1944
+ if (_isDev9 && keyIndexMap.has(newKeys[i2])) {
1858
1945
  devWarn(
1859
1946
  `each: duplicate key "${String(newKeys[i2])}" at index ${i2} (first seen at ${keyIndexMap.get(newKeys[i2])}). Keys must be unique \u2014 duplicates cause rows to be dropped or mis-ordered.`
1860
1947
  );
@@ -1869,12 +1956,12 @@ function each(getArray, render, options) {
1869
1956
  node = existing;
1870
1957
  } else {
1871
1958
  const itemKey = key;
1872
- const itemGetter = () => untracked(() => getArray()[keyIndexMap.get(itemKey)]);
1959
+ const itemGetter = () => untracked2(() => getArray()[keyIndexMap.get(itemKey)]);
1873
1960
  const indexGetter = () => keyIndexMap.get(itemKey);
1874
1961
  try {
1875
1962
  node = resolveNodeChild(render(itemGetter, indexGetter));
1876
1963
  } catch (err) {
1877
- if (_isDev8) {
1964
+ if (_isDev9) {
1878
1965
  devWarn(
1879
1966
  `each: render threw for item at index ${i2} (key="${newKeys[i2]}"): ${err instanceof Error ? err.message : String(err)}`
1880
1967
  );
@@ -1888,7 +1975,7 @@ function each(getArray, render, options) {
1888
1975
  target.dispatchEvent(
1889
1976
  new CustomEvent("sibu:error-propagate", { bubbles: true, detail: { error: errorObj } })
1890
1977
  );
1891
- } else if (_isDev8) {
1978
+ } else if (_isDev9) {
1892
1979
  devWarn(`each: error not surfaced \u2014 anchor detached: ${errorObj.message}`);
1893
1980
  }
1894
1981
  } catch {
@@ -1962,7 +2049,7 @@ function each(getArray, render, options) {
1962
2049
  workMap = tmp;
1963
2050
  initialized = true;
1964
2051
  };
1965
- const untrack = track(update);
2052
+ const untrack = track2(update);
1966
2053
  registerDisposer(anchor, untrack);
1967
2054
  if (!initialized) {
1968
2055
  queueMicrotask(() => {
@@ -2075,7 +2162,7 @@ function DynamicComponent(is) {
2075
2162
  }
2076
2163
  container.replaceChildren(el);
2077
2164
  }
2078
- const untrack = track(render);
2165
+ const untrack = track2(render);
2079
2166
  registerDisposer(container, untrack);
2080
2167
  return container;
2081
2168
  }
@@ -2090,7 +2177,7 @@ function show(condition, element) {
2090
2177
  const update = () => {
2091
2178
  element.style.display = condition() ? "" : "none";
2092
2179
  };
2093
- registerDisposer(element, track(update));
2180
+ registerDisposer(element, track2(update));
2094
2181
  return element;
2095
2182
  }
2096
2183
  function when(condition, thenBranch, elseBranch) {
@@ -2117,7 +2204,7 @@ function when(condition, thenBranch, elseBranch) {
2117
2204
  }
2118
2205
  initialized = true;
2119
2206
  };
2120
- registerDisposer(anchor, track(update));
2207
+ registerDisposer(anchor, track2(update));
2121
2208
  if (!initialized) {
2122
2209
  queueMicrotask(() => {
2123
2210
  if (!initialized && anchor.parentNode) update();
@@ -2152,7 +2239,7 @@ function match(value, cases, fallback) {
2152
2239
  }
2153
2240
  initialized = true;
2154
2241
  };
2155
- registerDisposer(anchor, track(update));
2242
+ registerDisposer(anchor, track2(update));
2156
2243
  if (!initialized) {
2157
2244
  queueMicrotask(() => {
2158
2245
  if (!initialized && anchor.parentNode) update();
@@ -2221,7 +2308,7 @@ function KeepAlive(activeKey, cases, options) {
2221
2308
  currentNode = node;
2222
2309
  initialized = true;
2223
2310
  };
2224
- const untrack = track(update);
2311
+ const untrack = track2(update);
2225
2312
  if (!initialized) {
2226
2313
  queueMicrotask(() => {
2227
2314
  if (!initialized && anchor.parentNode) update();
@@ -2243,9 +2330,9 @@ function KeepAlive(activeKey, cases, options) {
2243
2330
 
2244
2331
  // src/core/rendering/action.ts
2245
2332
  function action(element, actionFn, param2) {
2246
- const cleanup2 = actionFn(element, param2);
2247
- if (typeof cleanup2 === "function") {
2248
- registerDisposer(element, cleanup2);
2333
+ const cleanup3 = actionFn(element, param2);
2334
+ if (typeof cleanup3 === "function") {
2335
+ registerDisposer(element, cleanup3);
2249
2336
  }
2250
2337
  }
2251
2338
  var clickOutside = (element, callback) => {
@@ -2379,7 +2466,7 @@ function __resetIdCounter() {
2379
2466
  // src/reactivity/batch.ts
2380
2467
  var batchDepth = 0;
2381
2468
  var pendingSignals = /* @__PURE__ */ new Set();
2382
- function batch(fn) {
2469
+ function batchImpl(fn) {
2383
2470
  batchDepth++;
2384
2471
  try {
2385
2472
  return fn();
@@ -2390,28 +2477,45 @@ function batch(fn) {
2390
2477
  }
2391
2478
  }
2392
2479
  }
2393
- function enqueueBatchedSignal(signal2) {
2480
+ function enqueueBatchedSignalImpl(signal2) {
2394
2481
  if (batchDepth === 0) return false;
2395
2482
  pendingSignals.add(signal2);
2396
2483
  return true;
2397
2484
  }
2398
- function isBatching() {
2485
+ function isBatchingImpl() {
2399
2486
  return batchDepth > 0;
2400
2487
  }
2401
2488
  function flushBatch() {
2402
2489
  try {
2403
2490
  for (const signal2 of pendingSignals) {
2404
- queueSignalNotification(signal2);
2491
+ queueSignalNotification2(signal2);
2405
2492
  }
2406
2493
  } finally {
2407
2494
  pendingSignals.clear();
2408
2495
  }
2409
- drainNotificationQueue();
2496
+ drainNotificationQueue2();
2497
+ }
2498
+ var BATCH_REGISTRY_KEY = /* @__PURE__ */ Symbol.for("sibujs.reactive.batch.v1");
2499
+ function resolveBatchApi() {
2500
+ const g2 = globalThis;
2501
+ const existing = g2[BATCH_REGISTRY_KEY];
2502
+ if (existing) return existing;
2503
+ const local = {
2504
+ batch: batchImpl,
2505
+ enqueueBatchedSignal: enqueueBatchedSignalImpl,
2506
+ isBatching: isBatchingImpl
2507
+ };
2508
+ g2[BATCH_REGISTRY_KEY] = local;
2509
+ return local;
2410
2510
  }
2511
+ var API2 = resolveBatchApi();
2512
+ var batch = API2.batch;
2513
+ var enqueueBatchedSignal = API2.enqueueBatchedSignal;
2514
+ var isBatching = API2.isBatching;
2411
2515
 
2412
2516
  // src/core/signals/signal.ts
2413
2517
  var _g = globalThis;
2414
- var _isDev9 = isDev();
2518
+ var _isDev10 = isDev();
2415
2519
  function signal(initial, options) {
2416
2520
  const state = {
2417
2521
  value: initial,
@@ -2422,11 +2526,11 @@ function signal(initial, options) {
2422
2526
  __activeNode: null,
2423
2527
  __name: void 0
2424
2528
  };
2425
- const debugName = _isDev9 ? options?.name : void 0;
2529
+ const debugName = _isDev10 ? options?.name : void 0;
2426
2530
  const equalsFn = options?.equals;
2427
2531
  if (debugName) state.__name = debugName;
2428
2532
  function get() {
2429
- recordDependency(state);
2533
+ recordDependency2(state);
2430
2534
  return state.value;
2431
2535
  }
2432
2536
  get.__signal = state;
@@ -2439,15 +2543,15 @@ function signal(initial, options) {
2439
2543
  if (equalsFn(prev, newValue)) return;
2440
2544
  state.value = newValue;
2441
2545
  state.__v++;
2442
- if (_isDev9) {
2546
+ if (_isDev10) {
2443
2547
  const hook = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
2444
2548
  if (hook) hook.emit("signal:update", { signal: state, name: debugName, oldValue: prev, newValue });
2445
2549
  }
2446
2550
  if (!enqueueBatchedSignal(state)) {
2447
- notifySubscribers(state);
2551
+ notifySubscribers2(state);
2448
2552
  }
2449
2553
  };
2450
- } else if (_isDev9) {
2554
+ } else if (_isDev10) {
2451
2555
  set = (next) => {
2452
2556
  const prev = state.value;
2453
2557
  const newValue = typeof next === "function" ? next(prev) : next;
@@ -2457,7 +2561,7 @@ function signal(initial, options) {
2457
2561
  const hook = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
2458
2562
  if (hook) hook.emit("signal:update", { signal: state, name: debugName, oldValue: prev, newValue });
2459
2563
  if (!enqueueBatchedSignal(state)) {
2460
- notifySubscribers(state);
2564
+ notifySubscribers2(state);
2461
2565
  }
2462
2566
  };
2463
2567
  } else {
@@ -2468,11 +2572,11 @@ function signal(initial, options) {
2468
2572
  state.value = newValue;
2469
2573
  state.__v++;
2470
2574
  if (!enqueueBatchedSignal(state)) {
2471
- notifySubscribers(state);
2575
+ notifySubscribers2(state);
2472
2576
  }
2473
2577
  };
2474
2578
  }
2475
- if (_isDev9) {
2579
+ if (_isDev10) {
2476
2580
  const hook = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
2477
2581
  if (hook) hook.emit("signal:create", { signal: state, name: debugName, getter: get, initial });
2478
2582
  }
@@ -2561,11 +2665,11 @@ function on(deps, handler) {
2561
2665
  if (first) {
2562
2666
  first = false;
2563
2667
  prev = value;
2564
- untracked(() => handler(value, void 0));
2668
+ untracked2(() => handler(value, void 0));
2565
2669
  } else {
2566
2670
  const p2 = prev;
2567
2671
  prev = value;
2568
- untracked(() => handler(value, p2));
2672
+ untracked2(() => handler(value, p2));
2569
2673
  }
2570
2674
  };
2571
2675
  }
@@ -2587,7 +2691,7 @@ function drainReruns(ctx) {
2587
2691
  do {
2588
2692
  ctx.rerunPending = false;
2589
2693
  if (ctx.userCleanups.length > 0) flushUserCleanups(ctx);
2590
- retrack(ctx.bodyFn, ctx.subscriber);
2694
+ retrack2(ctx.bodyFn, ctx.subscriber);
2591
2695
  } while (ctx.rerunPending && ++reruns <= MAX_RERUNS);
2592
2696
  if (ctx.rerunPending) {
2593
2697
  ctx.rerunPending = false;
@@ -2616,7 +2720,7 @@ function disposeEffect(ctx) {
2616
2720
  }
2617
2721
  }
2618
2722
  try {
2619
- cleanup(ctx.subscriber);
2723
+ cleanup2(ctx.subscriber);
2620
2724
  } catch (err) {
2621
2725
  if (typeof console !== "undefined") {
2622
2726
  console.warn("[SibuJS effect] dispose threw:", err);
@@ -2661,7 +2765,7 @@ function effect(effectFn, options) {
2661
2765
  try {
2662
2766
  ctx.rerunPending = false;
2663
2767
  if (ctx.userCleanups.length > 0) flushUserCleanups(ctx);
2664
- retrack(ctx.bodyFn, sub2);
2768
+ retrack2(ctx.bodyFn, sub2);
2665
2769
  if (ctx.rerunPending) drainReruns(ctx);
2666
2770
  } finally {
2667
2771
  ctx.running = false;
@@ -2677,7 +2781,7 @@ function effect(effectFn, options) {
2677
2781
  ctx.subscriber = sub2;
2678
2782
  ctx.running = true;
2679
2783
  try {
2680
- retrack(ctx.bodyFn, ctx.subscriber);
2784
+ retrack2(ctx.bodyFn, ctx.subscriber);
2681
2785
  if (ctx.rerunPending) drainReruns(ctx);
2682
2786
  } finally {
2683
2787
  ctx.running = false;
@@ -2710,7 +2814,7 @@ function derived(getter, options) {
2710
2814
  cs._d = false;
2711
2815
  cs._init = true;
2712
2816
  };
2713
- track(() => {
2817
+ track2(() => {
2714
2818
  let threw = true;
2715
2819
  try {
2716
2820
  cs._v = getter();
@@ -2729,12 +2833,12 @@ function derived(getter, options) {
2729
2833
  `[SibuJS] Circular dependency detected in derived${debugName ? ` "${debugName}"` : ""}. A derived signal cannot read itself (directly or through a chain).`
2730
2834
  );
2731
2835
  }
2732
- if (trackingSuspended) {
2836
+ if (isTrackingSuspended2()) {
2733
2837
  if (cs._d) {
2734
2838
  const prev = cs._v;
2735
2839
  evaluating = true;
2736
2840
  try {
2737
- retrack(recompute, markDirty);
2841
+ retrack2(recompute, markDirty);
2738
2842
  if (!Object.is(prev, cs._v)) cs.__v++;
2739
2843
  } finally {
2740
2844
  evaluating = false;
@@ -2742,12 +2846,12 @@ function derived(getter, options) {
2742
2846
  }
2743
2847
  return cs._v;
2744
2848
  }
2745
- recordDependency(cs);
2849
+ recordDependency2(cs);
2746
2850
  if (cs._d) {
2747
2851
  const oldValue = cs._v;
2748
2852
  evaluating = true;
2749
2853
  try {
2750
- retrack(recompute, markDirty);
2854
+ retrack2(recompute, markDirty);
2751
2855
  if (!Object.is(oldValue, cs._v)) cs.__v++;
2752
2856
  } finally {
2753
2857
  evaluating = false;
@@ -2785,15 +2889,15 @@ function watch(getter, callback) {
2785
2889
  if (!Object.is(newValue, oldValue)) {
2786
2890
  const prev = oldValue;
2787
2891
  oldValue = newValue;
2788
- suspendTracking();
2892
+ suspendTracking2();
2789
2893
  try {
2790
2894
  callback(newValue, prev);
2791
2895
  } finally {
2792
- resumeTracking();
2896
+ resumeTracking2();
2793
2897
  }
2794
2898
  }
2795
2899
  };
2796
- const teardown = track(subscriber);
2900
+ const teardown = track2(subscriber);
2797
2901
  return teardown;
2798
2902
  }
2799
2903
 
@@ -2856,11 +2960,11 @@ function store(initialState) {
2856
2960
  first = false;
2857
2961
  return;
2858
2962
  }
2859
- suspendTracking();
2963
+ suspendTracking2();
2860
2964
  try {
2861
2965
  callback(snapshot);
2862
2966
  } finally {
2863
- resumeTracking();
2967
+ resumeTracking2();
2864
2968
  }
2865
2969
  });
2866
2970
  };
@@ -2877,11 +2981,11 @@ function store(initialState) {
2877
2981
  if (!Object.is(current, prev)) {
2878
2982
  const oldPrev = prev;
2879
2983
  prev = current;
2880
- suspendTracking();
2984
+ suspendTracking2();
2881
2985
  try {
2882
2986
  callback(current, oldPrev);
2883
2987
  } finally {
2884
- resumeTracking();
2988
+ resumeTracking2();
2885
2989
  }
2886
2990
  }
2887
2991
  });
@@ -2983,11 +3087,11 @@ function reactiveArray(initial = []) {
2983
3087
  function notify() {
2984
3088
  snapshot = null;
2985
3089
  if (!enqueueBatchedSignal(signal2)) {
2986
- notifySubscribers(signal2);
3090
+ notifySubscribers2(signal2);
2987
3091
  }
2988
3092
  }
2989
3093
  function get() {
2990
- recordDependency(signal2);
3094
+ recordDependency2(signal2);
2991
3095
  if (snapshot === null) {
2992
3096
  const copy = data2.slice();
2993
3097
  snapshot = Object.freeze(copy);
@@ -3243,9 +3347,9 @@ function safeCall(cb, hookName) {
3243
3347
  }
3244
3348
  }
3245
3349
  function runMountCallback(callback, hookName, element) {
3246
- const cleanup2 = safeCall(callback, hookName);
3247
- if (typeof cleanup2 === "function" && element) {
3248
- registerDisposer(element, cleanup2);
3350
+ const cleanup3 = safeCall(callback, hookName);
3351
+ if (typeof cleanup3 === "function" && element) {
3352
+ registerDisposer(element, cleanup3);
3249
3353
  }
3250
3354
  }
3251
3355
  var mountWatchers = /* @__PURE__ */ new WeakMap();
@@ -3561,7 +3665,7 @@ function defer(getter) {
3561
3665
  }
3562
3666
  });
3563
3667
  };
3564
- const teardown = track(() => {
3668
+ const teardown = track2(() => {
3565
3669
  latest = getter();
3566
3670
  schedule();
3567
3671
  });
@@ -3713,14 +3817,14 @@ function Suspense({ nodes, fallback }) {
3713
3817
  }
3714
3818
 
3715
3819
  // src/platform/ssr.ts
3716
- var _isDev10 = isDev();
3820
+ var _isDev11 = isDev();
3717
3821
  function trustHTML(html3) {
3718
3822
  return html3;
3719
3823
  }
3720
3824
  var DEFAULT_MAX_SSR_BYTES = 1024 * 1024;
3721
3825
 
3722
3826
  // src/components/ErrorDisplay.ts
3723
- var _isDev11 = isDev();
3827
+ var _isDev12 = isDev();
3724
3828
  var STYLES = `
3725
3829
  .sibu-error-display {
3726
3830
  border: 1px solid var(--sibu-err-border, #e5484d);
@@ -4031,7 +4135,7 @@ function ErrorDisplay(props) {
4031
4135
  injectStyles();
4032
4136
  const severity = props.severity ?? "error";
4033
4137
  const normalized = normalizeError(props.error);
4034
- const showDetails = props.alwaysShowDetails ?? _isDev11;
4138
+ const showDetails = props.alwaysShowDetails ?? _isDev12;
4035
4139
  const headline = props.title ?? normalized.message;
4036
4140
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").slice(0, 19);
4037
4141
  const [copyLabel, setCopyLabel] = signal("Copy");