sibujs 3.3.0 → 3.3.2

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 (60) hide show
  1. package/dist/browser.cjs +230 -40
  2. package/dist/browser.js +5 -5
  3. package/dist/build.cjs +240 -108
  4. package/dist/build.js +13 -13
  5. package/dist/cdn.global.js +7 -7
  6. package/dist/{chunk-BEIKESVL.js → chunk-2ARSB7NG.js} +36 -13
  7. package/dist/{chunk-X3NHE2DK.js → chunk-4NJEAPLI.js} +83 -17
  8. package/dist/{chunk-JBXNCZSC.js → chunk-5VH3GIDX.js} +1 -1
  9. package/dist/{chunk-6G6UNHZI.js → chunk-62V653X2.js} +16 -21
  10. package/dist/{chunk-S4FHR5ZZ.js → chunk-655B7MMR.js} +3 -3
  11. package/dist/{chunk-24DBWDTK.js → chunk-6TCOWMGY.js} +1 -1
  12. package/dist/{chunk-USDR2GFV.js → chunk-A7CZH3GN.js} +3 -3
  13. package/dist/{chunk-SLCUP2EK.js → chunk-AEOLHSSQ.js} +3 -3
  14. package/dist/chunk-CCSJMTRN.js +15 -0
  15. package/dist/{chunk-R3QEDXFS.js → chunk-EX77FXTT.js} +1 -1
  16. package/dist/{chunk-ZUVLC7TM.js → chunk-FJIRS3FM.js} +1 -1
  17. package/dist/{chunk-4WXWJ4SW.js → chunk-FJO2ZL4Q.js} +4 -4
  18. package/dist/{chunk-CVMMULHO.js → chunk-G6N3LMO2.js} +4 -4
  19. package/dist/{chunk-XQ7XSGYP.js → chunk-IQJ36UTJ.js} +1 -1
  20. package/dist/{chunk-5K72I3UQ.js → chunk-JCQG2I2G.js} +21 -4
  21. package/dist/{chunk-7JHWAGRQ.js → chunk-N5TQVEKE.js} +2 -2
  22. package/dist/{chunk-IHBVTURX.js → chunk-P7C7SEJV.js} +4 -4
  23. package/dist/{chunk-M6WSIGYW.js → chunk-Q46YIQYW.js} +2 -2
  24. package/dist/{chunk-Q2ERM6NT.js → chunk-QCFBIVIQ.js} +1 -1
  25. package/dist/{chunk-F4UM7QBJ.js → chunk-RLTFJYDN.js} +2 -2
  26. package/dist/{chunk-GOJMFRBL.js → chunk-S3NFJO6L.js} +20 -14
  27. package/dist/{chunk-MWZFOIBG.js → chunk-YUBEOWII.js} +5 -5
  28. package/dist/{chunk-WVJJUFPC.js → chunk-YUR5SX7F.js} +2 -2
  29. package/dist/{chunk-NUWKIEHE.js → chunk-ZEUP4TUD.js} +2 -2
  30. package/dist/data.cjs +181 -37
  31. package/dist/data.js +7 -7
  32. package/dist/devtools.cjs +265 -45
  33. package/dist/devtools.js +5 -5
  34. package/dist/ecosystem.cjs +203 -59
  35. package/dist/ecosystem.js +8 -8
  36. package/dist/extras.cjs +216 -116
  37. package/dist/extras.js +22 -22
  38. package/dist/index.cjs +242 -108
  39. package/dist/index.d.cts +78 -14
  40. package/dist/index.d.ts +78 -14
  41. package/dist/index.js +17 -13
  42. package/dist/motion.cjs +329 -13
  43. package/dist/motion.js +3 -3
  44. package/dist/patterns.cjs +181 -37
  45. package/dist/patterns.js +6 -6
  46. package/dist/performance.cjs +278 -37
  47. package/dist/performance.js +6 -6
  48. package/dist/plugins.cjs +353 -153
  49. package/dist/plugins.js +95 -94
  50. package/dist/{ssr-6D67RAVB.js → ssr-2PPULEK2.js} +2 -2
  51. package/dist/ssr.cjs +203 -58
  52. package/dist/ssr.js +9 -9
  53. package/dist/testing.cjs +416 -19
  54. package/dist/testing.js +3 -3
  55. package/dist/ui.cjs +256 -65
  56. package/dist/ui.js +8 -8
  57. package/dist/widgets.cjs +166 -40
  58. package/dist/widgets.js +7 -7
  59. package/package.json +1 -1
  60. package/dist/chunk-YT6HQ6AM.js +0 -14
package/dist/index.cjs CHANGED
@@ -99,6 +99,7 @@ __export(index_exports, {
99
99
  footer: () => footer,
100
100
  form: () => form,
101
101
  g: () => g,
102
+ getAction: () => getAction,
102
103
  getRequestScopedCache: () => getRequestScopedCache,
103
104
  getSSRStore: () => getSSRStore,
104
105
  getSlot: () => getSlot,
@@ -167,10 +168,11 @@ __export(index_exports, {
167
168
  reactiveArray: () => reactiveArray,
168
169
  rect: () => rect,
169
170
  ref: () => ref,
171
+ registerAction: () => registerAction,
170
172
  registerComponent: () => registerComponent,
171
173
  registerDisposer: () => registerDisposer,
172
174
  resolveComponent: () => resolveComponent,
173
- retrack: () => retrack,
175
+ retrack: () => retrack2,
174
176
  rp: () => rp,
175
177
  rt: () => rt,
176
178
  ruby: () => ruby,
@@ -181,7 +183,7 @@ __export(index_exports, {
181
183
  section: () => section,
182
184
  select: () => select,
183
185
  setGlobalErrorHandler: () => setGlobalErrorHandler,
184
- setMaxDrainIterations: () => setMaxDrainIterations,
186
+ setMaxDrainIterations: () => setMaxDrainIterations2,
185
187
  show: () => show,
186
188
  signal: () => signal,
187
189
  slot: () => slot,
@@ -213,7 +215,7 @@ __export(index_exports, {
213
215
  time: () => time,
214
216
  title: () => title,
215
217
  tr: () => tr,
216
- track: () => track2,
218
+ track: () => track3,
217
219
  transition: () => transition,
218
220
  trapFocus: () => trapFocus,
219
221
  trustHTML: () => trustHTML,
@@ -221,7 +223,7 @@ __export(index_exports, {
221
223
  u: () => u,
222
224
  ul: () => ul,
223
225
  unregisterComponent: () => unregisterComponent,
224
- untracked: () => untracked,
226
+ untracked: () => untracked2,
225
227
  use: () => use,
226
228
  var_: () => var_,
227
229
  video: () => video,
@@ -339,7 +341,7 @@ function sanitizeAttributeString(attr, value) {
339
341
  return value;
340
342
  }
341
343
 
342
- // src/reactivity/track.ts
344
+ // src/reactivity/track-core.ts
343
345
  var _isDev2 = isDev();
344
346
  var POOL_MAX = 4096;
345
347
  var nodePool = [];
@@ -453,6 +455,9 @@ function resumeTracking() {
453
455
  trackingSuspended = false;
454
456
  }
455
457
  }
458
+ function isTrackingSuspended() {
459
+ return trackingSuspended;
460
+ }
456
461
  function untracked(fn) {
457
462
  suspendTracking();
458
463
  try {
@@ -570,6 +575,11 @@ function cleanup(subscriber) {
570
575
  var maxSubscriberRepeats = 50;
571
576
  var maxDrainIterations = 1e6;
572
577
  var drainEpoch = 0;
578
+ function setMaxSubscriberRepeats(n) {
579
+ const prev = maxSubscriberRepeats;
580
+ if (Number.isFinite(n) && n > 0) maxSubscriberRepeats = Math.floor(n);
581
+ return prev;
582
+ }
573
583
  function setMaxDrainIterations(n) {
574
584
  const prev = maxDrainIterations;
575
585
  if (Number.isFinite(n) && n > 0) maxDrainIterations = Math.floor(n);
@@ -723,15 +733,94 @@ function notifySubscribers(signal2) {
723
733
  }
724
734
  }
725
735
  }
736
+ function getSubscriberCount(signal2) {
737
+ return signal2.__sc ?? 0;
738
+ }
739
+ function getSubscriberDeps(subscriber) {
740
+ const sub2 = subscriber;
741
+ const out = [];
742
+ let node = sub2.depsHead ?? null;
743
+ while (node) {
744
+ if (node.sig) out.push(node.sig);
745
+ node = node.subNext;
746
+ }
747
+ return out;
748
+ }
749
+ function forEachSubscriber(signal2, visit) {
750
+ let node = signal2.subsHead ?? null;
751
+ while (node) {
752
+ const s2 = node.sub;
753
+ if (s2) visit(s2);
754
+ node = node.sigNext;
755
+ }
756
+ }
726
757
 
727
- // src/reactivity/bindAttribute.ts
758
+ // src/reactivity/track.ts
728
759
  var _isDev3 = isDev();
760
+ var _runtimeVersion = true ? "3.3.2" : "dev";
761
+ var REGISTRY_KEY = /* @__PURE__ */ Symbol.for("sibujs.reactive.v1");
762
+ function resolveReactiveApi() {
763
+ const g2 = globalThis;
764
+ const existing = g2[REGISTRY_KEY];
765
+ if (existing) {
766
+ if (_isDev3 && !existing.__dupWarned) {
767
+ existing.__dupWarned = true;
768
+ devWarn(
769
+ `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']).`
770
+ );
771
+ }
772
+ return existing;
773
+ }
774
+ const local = {
775
+ suspendTracking,
776
+ resumeTracking,
777
+ isTrackingSuspended,
778
+ untracked,
779
+ retrack,
780
+ track,
781
+ reactiveBinding,
782
+ recordDependency,
783
+ cleanup,
784
+ setMaxSubscriberRepeats,
785
+ setMaxDrainIterations,
786
+ drainNotificationQueue,
787
+ queueSignalNotification,
788
+ notifySubscribers,
789
+ getSubscriberCount,
790
+ getSubscriberDeps,
791
+ forEachSubscriber,
792
+ version: _runtimeVersion
793
+ };
794
+ g2[REGISTRY_KEY] = local;
795
+ return local;
796
+ }
797
+ var API = resolveReactiveApi();
798
+ var suspendTracking2 = API.suspendTracking;
799
+ var resumeTracking2 = API.resumeTracking;
800
+ var isTrackingSuspended2 = API.isTrackingSuspended;
801
+ var untracked2 = API.untracked;
802
+ var retrack2 = API.retrack;
803
+ var track2 = API.track;
804
+ var reactiveBinding2 = API.reactiveBinding;
805
+ var recordDependency2 = API.recordDependency;
806
+ var cleanup2 = API.cleanup;
807
+ var setMaxSubscriberRepeats2 = API.setMaxSubscriberRepeats;
808
+ var setMaxDrainIterations2 = API.setMaxDrainIterations;
809
+ var drainNotificationQueue2 = API.drainNotificationQueue;
810
+ var queueSignalNotification2 = API.queueSignalNotification;
811
+ var notifySubscribers2 = API.notifySubscribers;
812
+ var getSubscriberCount2 = API.getSubscriberCount;
813
+ var getSubscriberDeps2 = API.getSubscriberDeps;
814
+ var forEachSubscriber2 = API.forEachSubscriber;
815
+
816
+ // src/reactivity/bindAttribute.ts
817
+ var _isDev4 = isDev();
729
818
  function setProp(el, key, val) {
730
819
  el[key] = val;
731
820
  }
732
821
  function bindAttribute(el, attr, getter) {
733
822
  if (isEventHandlerAttr(attr)) {
734
- if (_isDev3)
823
+ if (_isDev4)
735
824
  devWarn(
736
825
  `bindAttribute: refusing to bind event-handler attribute "${attr}". Use on:{ ${attr.slice(2)}: fn } instead.`
737
826
  );
@@ -743,7 +832,7 @@ function bindAttribute(el, attr, getter) {
743
832
  try {
744
833
  value = getter();
745
834
  } catch (err) {
746
- if (_isDev3)
835
+ if (_isDev4)
747
836
  devWarn(`bindAttribute: getter for "${attr}" threw: ${err instanceof Error ? err.message : String(err)}`);
748
837
  return;
749
838
  }
@@ -764,7 +853,7 @@ function bindAttribute(el, attr, getter) {
764
853
  el.setAttribute(attr, sanitizeAttributeString(attr, str));
765
854
  }
766
855
  }
767
- return reactiveBinding(commit);
856
+ return reactiveBinding2(commit);
768
857
  }
769
858
  function bindDynamic(el, nameGetter, valueGetter) {
770
859
  let prevName = null;
@@ -773,14 +862,14 @@ function bindDynamic(el, nameGetter, valueGetter) {
773
862
  try {
774
863
  name = typeof nameGetter === "function" ? nameGetter() : nameGetter;
775
864
  } catch (err) {
776
- if (_isDev3) devWarn(`bindDynamic: name getter threw: ${err instanceof Error ? err.message : String(err)}`);
865
+ if (_isDev4) devWarn(`bindDynamic: name getter threw: ${err instanceof Error ? err.message : String(err)}`);
777
866
  return;
778
867
  }
779
868
  let value;
780
869
  try {
781
870
  value = typeof valueGetter === "function" ? valueGetter() : valueGetter;
782
871
  } catch (err) {
783
- if (_isDev3) devWarn(`bindDynamic: value getter threw: ${err instanceof Error ? err.message : String(err)}`);
872
+ if (_isDev4) devWarn(`bindDynamic: value getter threw: ${err instanceof Error ? err.message : String(err)}`);
784
873
  return;
785
874
  }
786
875
  if (isEventHandlerAttr(name)) return;
@@ -795,7 +884,7 @@ function bindDynamic(el, nameGetter, valueGetter) {
795
884
  }
796
885
  prevName = name;
797
886
  }
798
- const teardown = reactiveBinding(commit);
887
+ const teardown = reactiveBinding2(commit);
799
888
  return () => {
800
889
  teardown();
801
890
  if (prevName !== null) {
@@ -806,7 +895,7 @@ function bindDynamic(el, nameGetter, valueGetter) {
806
895
 
807
896
  // src/core/rendering/dispose.ts
808
897
  var elementDisposers = /* @__PURE__ */ new WeakMap();
809
- var _isDev4 = isDev();
898
+ var _isDev5 = isDev();
810
899
  var activeBindingCount = 0;
811
900
  function registerDisposer(node, teardown) {
812
901
  let disposers = elementDisposers.get(node);
@@ -815,7 +904,7 @@ function registerDisposer(node, teardown) {
815
904
  elementDisposers.set(node, disposers);
816
905
  }
817
906
  disposers.push(teardown);
818
- if (_isDev4) activeBindingCount++;
907
+ if (_isDev5) activeBindingCount++;
819
908
  }
820
909
  function dispose(node) {
821
910
  const stack = [node];
@@ -834,12 +923,12 @@ function dispose(node) {
834
923
  if (disposers) {
835
924
  const snapshot = disposers.slice();
836
925
  elementDisposers.delete(current);
837
- if (_isDev4) activeBindingCount -= snapshot.length;
926
+ if (_isDev5) activeBindingCount -= snapshot.length;
838
927
  for (const d of snapshot) {
839
928
  try {
840
929
  d();
841
930
  } catch (err) {
842
- if (_isDev4 && typeof console !== "undefined") {
931
+ if (_isDev5 && typeof console !== "undefined") {
843
932
  console.warn("[SibuJS] Disposer threw during cleanup:", err);
844
933
  }
845
934
  }
@@ -850,12 +939,12 @@ function dispose(node) {
850
939
  if (!added || added.length === 0) break;
851
940
  const moreSnapshot = added.slice();
852
941
  elementDisposers.delete(current);
853
- if (_isDev4) activeBindingCount -= moreSnapshot.length;
942
+ if (_isDev5) activeBindingCount -= moreSnapshot.length;
854
943
  for (const d of moreSnapshot) {
855
944
  try {
856
945
  d();
857
946
  } catch (err) {
858
- if (_isDev4 && typeof console !== "undefined") {
947
+ if (_isDev5 && typeof console !== "undefined") {
859
948
  console.warn("[SibuJS] Disposer threw during cleanup:", err);
860
949
  }
861
950
  }
@@ -865,7 +954,7 @@ function dispose(node) {
865
954
  }
866
955
  }
867
956
  function checkLeaks(warnThreshold = 0) {
868
- if (!_isDev4) return 0;
957
+ if (!_isDev5) return 0;
869
958
  if (warnThreshold > 0 && activeBindingCount > warnThreshold) {
870
959
  devWarn(
871
960
  `checkLeaks: ${activeBindingCount} active DOM bindings detected. Expected \u2264${warnThreshold}. This may indicate a component was removed from the DOM without calling dispose().`
@@ -875,7 +964,7 @@ function checkLeaks(warnThreshold = 0) {
875
964
  }
876
965
 
877
966
  // src/reactivity/bindChildNode.ts
878
- var _isDev5 = isDev();
967
+ var _isDev6 = isDev();
879
968
  function bindChildNode(placeholder, getter) {
880
969
  let lastNodes = [];
881
970
  function commit() {
@@ -883,7 +972,7 @@ function bindChildNode(placeholder, getter) {
883
972
  try {
884
973
  result = getter();
885
974
  } catch (err) {
886
- if (_isDev5) devWarn(`bindChildNode: getter threw: ${err instanceof Error ? err.message : String(err)}`);
975
+ if (_isDev6) devWarn(`bindChildNode: getter threw: ${err instanceof Error ? err.message : String(err)}`);
887
976
  return;
888
977
  }
889
978
  if (result == null || typeof result === "boolean") {
@@ -909,7 +998,7 @@ function bindChildNode(placeholder, getter) {
909
998
  if (item == null || typeof item === "boolean") continue;
910
999
  const node = item instanceof Node ? item : document.createTextNode(String(item));
911
1000
  if (seen.has(node)) {
912
- if (_isDev5)
1001
+ if (_isDev6)
913
1002
  devWarn("bindChildNode: duplicate node reference in array \u2014 only the first occurrence is rendered.");
914
1003
  continue;
915
1004
  }
@@ -944,12 +1033,12 @@ function bindChildNode(placeholder, getter) {
944
1033
  }
945
1034
  lastNodes = newNodes;
946
1035
  }
947
- return reactiveBinding(commit);
1036
+ return reactiveBinding2(commit);
948
1037
  }
949
1038
 
950
1039
  // src/core/rendering/tagFactory.ts
951
1040
  var SVG_NS = "http://www.w3.org/2000/svg";
952
- var _isDev6 = isDev();
1041
+ var _isDev7 = isDev();
953
1042
  var BLOCKED_TAGS = /* @__PURE__ */ new Set(["script", "iframe", "object", "embed", "frame", "frameset"]);
954
1043
  function isBlockedTag(tag) {
955
1044
  return BLOCKED_TAGS.has(tag.toLowerCase());
@@ -992,7 +1081,7 @@ function toKebab(prop) {
992
1081
  }
993
1082
  function applyStyle(el, style2) {
994
1083
  if (typeof style2 === "function") {
995
- const teardown = track(() => {
1084
+ const teardown = track2(() => {
996
1085
  el.setAttribute("style", style2());
997
1086
  });
998
1087
  registerDisposer(el, teardown);
@@ -1008,7 +1097,7 @@ function applyStyle(el, style2) {
1008
1097
  const name = toKebab(prop);
1009
1098
  if (typeof val === "function") {
1010
1099
  const getter = val;
1011
- const teardown = track(() => {
1100
+ const teardown = track2(() => {
1012
1101
  htmlEl.style.setProperty(name, sanitizeCSSValue(String(getter())));
1013
1102
  });
1014
1103
  registerDisposer(el, teardown);
@@ -1023,7 +1112,7 @@ function applyClass(el, cls) {
1023
1112
  return;
1024
1113
  }
1025
1114
  if (typeof cls === "function") {
1026
- const teardown = track(() => {
1115
+ const teardown = track2(() => {
1027
1116
  el.setAttribute("class", cls());
1028
1117
  });
1029
1118
  registerDisposer(el, teardown);
@@ -1050,7 +1139,7 @@ function applyClass(el, cls) {
1050
1139
  }
1051
1140
  el.setAttribute("class", r);
1052
1141
  };
1053
- const teardown = track(update);
1142
+ const teardown = track2(update);
1054
1143
  registerDisposer(el, teardown);
1055
1144
  } else {
1056
1145
  el.setAttribute("class", result);
@@ -1120,7 +1209,7 @@ var tagFactory = (tag, ns) => {
1120
1209
  appendChildren(el, second);
1121
1210
  return el;
1122
1211
  }
1123
- if (_isDev6 && looksLikeClassList(first)) {
1212
+ if (_isDev7 && looksLikeClassList(first)) {
1124
1213
  devWarn(
1125
1214
  `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
1215
  );
@@ -1141,7 +1230,7 @@ var tagFactory = (tag, ns) => {
1141
1230
  if (pClass != null) applyClass(el, pClass);
1142
1231
  const pId = props.id;
1143
1232
  if (pId != null) {
1144
- if (_isDev6 && typeof pId === "string" && CLOBBER_RISKY_IDS.has(pId.toLowerCase())) {
1233
+ if (_isDev7 && typeof pId === "string" && CLOBBER_RISKY_IDS.has(pId.toLowerCase())) {
1145
1234
  devWarn(
1146
1235
  `tagFactory: element id="${pId}" matches a common global and may cause DOM clobbering. Avoid setting ids from untrusted input.`
1147
1236
  );
@@ -1156,7 +1245,7 @@ var tagFactory = (tag, ns) => {
1156
1245
  const handler = pOn[ev];
1157
1246
  if (typeof handler === "function") {
1158
1247
  el.addEventListener(ev, handler);
1159
- } else if (_isDev6) {
1248
+ } else if (_isDev7) {
1160
1249
  devWarn(
1161
1250
  `tagFactory: on.${ev} handler is not a function (got ${typeof handler}). Event listener was not attached.`
1162
1251
  );
@@ -1269,7 +1358,7 @@ var area = tagFactory("area");
1269
1358
  var audio = tagFactory("audio");
1270
1359
  var img = tagFactory("img");
1271
1360
  var map = tagFactory("map");
1272
- var track2 = tagFactory("track");
1361
+ var track3 = tagFactory("track");
1273
1362
  var video = tagFactory("video");
1274
1363
  var embed = tagFactory("embed");
1275
1364
  var iframe = tagFactory("iframe");
@@ -1345,7 +1434,7 @@ var marquee = tagFactory("marquee");
1345
1434
  var customElement = (tagName) => tagFactory(tagName);
1346
1435
 
1347
1436
  // src/core/rendering/htm.ts
1348
- var _isDev7 = isDev();
1437
+ var _isDev8 = isDev();
1349
1438
  var RAW_TEXT_TAGS = /* @__PURE__ */ new Set(["script", "style"]);
1350
1439
  var VOID_ELEMENTS = /* @__PURE__ */ new Set([
1351
1440
  "area",
@@ -1641,7 +1730,7 @@ function executeElement(tmpl, values) {
1641
1730
  const fn = values[attr.idx];
1642
1731
  if (typeof fn === "function") {
1643
1732
  el.addEventListener(attr.name, fn);
1644
- } else if (_isDev7) {
1733
+ } else if (_isDev8) {
1645
1734
  devWarn(
1646
1735
  `html: on:${attr.name} handler is not a function (got ${typeof fn}). Event listener was not attached.`
1647
1736
  );
@@ -1769,7 +1858,7 @@ function mount(component, container) {
1769
1858
  }
1770
1859
 
1771
1860
  // src/core/rendering/each.ts
1772
- var _isDev8 = isDev();
1861
+ var _isDev9 = isDev();
1773
1862
  function resolveNodeChild(child) {
1774
1863
  if (typeof child === "function") {
1775
1864
  return resolveNodeChild(child());
@@ -1854,7 +1943,7 @@ function each(getArray, render, options) {
1854
1943
  workMap.clear();
1855
1944
  keyIndexMap.clear();
1856
1945
  for (let i2 = 0; i2 < newLen; i2++) {
1857
- if (_isDev8 && keyIndexMap.has(newKeys[i2])) {
1946
+ if (_isDev9 && keyIndexMap.has(newKeys[i2])) {
1858
1947
  devWarn(
1859
1948
  `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
1949
  );
@@ -1869,12 +1958,12 @@ function each(getArray, render, options) {
1869
1958
  node = existing;
1870
1959
  } else {
1871
1960
  const itemKey = key;
1872
- const itemGetter = () => untracked(() => getArray()[keyIndexMap.get(itemKey)]);
1961
+ const itemGetter = () => untracked2(() => getArray()[keyIndexMap.get(itemKey)]);
1873
1962
  const indexGetter = () => keyIndexMap.get(itemKey);
1874
1963
  try {
1875
1964
  node = resolveNodeChild(render(itemGetter, indexGetter));
1876
1965
  } catch (err) {
1877
- if (_isDev8) {
1966
+ if (_isDev9) {
1878
1967
  devWarn(
1879
1968
  `each: render threw for item at index ${i2} (key="${newKeys[i2]}"): ${err instanceof Error ? err.message : String(err)}`
1880
1969
  );
@@ -1888,7 +1977,7 @@ function each(getArray, render, options) {
1888
1977
  target.dispatchEvent(
1889
1978
  new CustomEvent("sibu:error-propagate", { bubbles: true, detail: { error: errorObj } })
1890
1979
  );
1891
- } else if (_isDev8) {
1980
+ } else if (_isDev9) {
1892
1981
  devWarn(`each: error not surfaced \u2014 anchor detached: ${errorObj.message}`);
1893
1982
  }
1894
1983
  } catch {
@@ -1962,7 +2051,7 @@ function each(getArray, render, options) {
1962
2051
  workMap = tmp;
1963
2052
  initialized = true;
1964
2053
  };
1965
- const untrack = track(update);
2054
+ const untrack = track2(update);
1966
2055
  registerDisposer(anchor, untrack);
1967
2056
  if (!initialized) {
1968
2057
  queueMicrotask(() => {
@@ -2075,7 +2164,7 @@ function DynamicComponent(is) {
2075
2164
  }
2076
2165
  container.replaceChildren(el);
2077
2166
  }
2078
- const untrack = track(render);
2167
+ const untrack = track2(render);
2079
2168
  registerDisposer(container, untrack);
2080
2169
  return container;
2081
2170
  }
@@ -2090,7 +2179,7 @@ function show(condition, element) {
2090
2179
  const update = () => {
2091
2180
  element.style.display = condition() ? "" : "none";
2092
2181
  };
2093
- registerDisposer(element, track(update));
2182
+ registerDisposer(element, track2(update));
2094
2183
  return element;
2095
2184
  }
2096
2185
  function when(condition, thenBranch, elseBranch) {
@@ -2117,7 +2206,7 @@ function when(condition, thenBranch, elseBranch) {
2117
2206
  }
2118
2207
  initialized = true;
2119
2208
  };
2120
- registerDisposer(anchor, track(update));
2209
+ registerDisposer(anchor, track2(update));
2121
2210
  if (!initialized) {
2122
2211
  queueMicrotask(() => {
2123
2212
  if (!initialized && anchor.parentNode) update();
@@ -2152,7 +2241,7 @@ function match(value, cases, fallback) {
2152
2241
  }
2153
2242
  initialized = true;
2154
2243
  };
2155
- registerDisposer(anchor, track(update));
2244
+ registerDisposer(anchor, track2(update));
2156
2245
  if (!initialized) {
2157
2246
  queueMicrotask(() => {
2158
2247
  if (!initialized && anchor.parentNode) update();
@@ -2221,7 +2310,7 @@ function KeepAlive(activeKey, cases, options) {
2221
2310
  currentNode = node;
2222
2311
  initialized = true;
2223
2312
  };
2224
- const untrack = track(update);
2313
+ const untrack = track2(update);
2225
2314
  if (!initialized) {
2226
2315
  queueMicrotask(() => {
2227
2316
  if (!initialized && anchor.parentNode) update();
@@ -2242,10 +2331,24 @@ function KeepAlive(activeKey, cases, options) {
2242
2331
  }
2243
2332
 
2244
2333
  // src/core/rendering/action.ts
2245
- function action(element, actionFn, param2) {
2246
- const cleanup2 = actionFn(element, param2);
2247
- if (typeof cleanup2 === "function") {
2248
- registerDisposer(element, cleanup2);
2334
+ var ACTIONS_KEY = /* @__PURE__ */ Symbol.for("sibujs.actions.v1");
2335
+ var _actions = globalThis[ACTIONS_KEY] ?? (globalThis[ACTIONS_KEY] = /* @__PURE__ */ new Map());
2336
+ function registerAction(name, fn) {
2337
+ _actions.set(name, fn);
2338
+ }
2339
+ function getAction(name) {
2340
+ return _actions.get(name);
2341
+ }
2342
+ function action(element, action2, param2) {
2343
+ const actionFn = typeof action2 === "string" ? getAction(action2) : action2;
2344
+ if (!actionFn) {
2345
+ throw new Error(
2346
+ `[SibuJS] No action registered under the name "${action2}". Register it with registerAction() before applying it by name.`
2347
+ );
2348
+ }
2349
+ const cleanup3 = actionFn(element, param2);
2350
+ if (typeof cleanup3 === "function") {
2351
+ registerDisposer(element, cleanup3);
2249
2352
  }
2250
2353
  }
2251
2354
  var clickOutside = (element, callback) => {
@@ -2319,6 +2422,11 @@ var trapFocus = (element) => {
2319
2422
  element.addEventListener("keydown", handler);
2320
2423
  return () => element.removeEventListener("keydown", handler);
2321
2424
  };
2425
+ registerAction("clickOutside", clickOutside);
2426
+ registerAction("longPress", longPress);
2427
+ registerAction("copyOnClick", copyOnClick);
2428
+ registerAction("autoResize", autoResize);
2429
+ registerAction("trapFocus", trapFocus);
2322
2430
 
2323
2431
  // src/core/rendering/catch.ts
2324
2432
  var globalErrorHandler = null;
@@ -2367,19 +2475,20 @@ function setGlobalErrorHandler(handler) {
2367
2475
  }
2368
2476
 
2369
2477
  // src/core/rendering/createId.ts
2370
- var idCounter = 0;
2478
+ var COUNTER_KEY = /* @__PURE__ */ Symbol.for("sibujs.createId.v1");
2479
+ var _counter = globalThis[COUNTER_KEY] ?? (globalThis[COUNTER_KEY] = { n: 0 });
2371
2480
  function createId(prefix = "sibu") {
2372
- idCounter++;
2373
- return `${prefix}-${idCounter}`;
2481
+ _counter.n++;
2482
+ return `${prefix}-${_counter.n}`;
2374
2483
  }
2375
2484
  function __resetIdCounter() {
2376
- idCounter = 0;
2485
+ _counter.n = 0;
2377
2486
  }
2378
2487
 
2379
2488
  // src/reactivity/batch.ts
2380
2489
  var batchDepth = 0;
2381
2490
  var pendingSignals = /* @__PURE__ */ new Set();
2382
- function batch(fn) {
2491
+ function batchImpl(fn) {
2383
2492
  batchDepth++;
2384
2493
  try {
2385
2494
  return fn();
@@ -2390,28 +2499,45 @@ function batch(fn) {
2390
2499
  }
2391
2500
  }
2392
2501
  }
2393
- function enqueueBatchedSignal(signal2) {
2502
+ function enqueueBatchedSignalImpl(signal2) {
2394
2503
  if (batchDepth === 0) return false;
2395
2504
  pendingSignals.add(signal2);
2396
2505
  return true;
2397
2506
  }
2398
- function isBatching() {
2507
+ function isBatchingImpl() {
2399
2508
  return batchDepth > 0;
2400
2509
  }
2401
2510
  function flushBatch() {
2402
2511
  try {
2403
2512
  for (const signal2 of pendingSignals) {
2404
- queueSignalNotification(signal2);
2513
+ queueSignalNotification2(signal2);
2405
2514
  }
2406
2515
  } finally {
2407
2516
  pendingSignals.clear();
2408
2517
  }
2409
- drainNotificationQueue();
2518
+ drainNotificationQueue2();
2519
+ }
2520
+ var BATCH_REGISTRY_KEY = /* @__PURE__ */ Symbol.for("sibujs.reactive.batch.v1");
2521
+ function resolveBatchApi() {
2522
+ const g2 = globalThis;
2523
+ const existing = g2[BATCH_REGISTRY_KEY];
2524
+ if (existing) return existing;
2525
+ const local = {
2526
+ batch: batchImpl,
2527
+ enqueueBatchedSignal: enqueueBatchedSignalImpl,
2528
+ isBatching: isBatchingImpl
2529
+ };
2530
+ g2[BATCH_REGISTRY_KEY] = local;
2531
+ return local;
2410
2532
  }
2533
+ var API2 = resolveBatchApi();
2534
+ var batch = API2.batch;
2535
+ var enqueueBatchedSignal = API2.enqueueBatchedSignal;
2536
+ var isBatching = API2.isBatching;
2411
2537
 
2412
2538
  // src/core/signals/signal.ts
2413
2539
  var _g = globalThis;
2414
- var _isDev9 = isDev();
2540
+ var _isDev10 = isDev();
2415
2541
  function signal(initial, options) {
2416
2542
  const state = {
2417
2543
  value: initial,
@@ -2422,11 +2548,11 @@ function signal(initial, options) {
2422
2548
  __activeNode: null,
2423
2549
  __name: void 0
2424
2550
  };
2425
- const debugName = _isDev9 ? options?.name : void 0;
2551
+ const debugName = _isDev10 ? options?.name : void 0;
2426
2552
  const equalsFn = options?.equals;
2427
2553
  if (debugName) state.__name = debugName;
2428
2554
  function get() {
2429
- recordDependency(state);
2555
+ recordDependency2(state);
2430
2556
  return state.value;
2431
2557
  }
2432
2558
  get.__signal = state;
@@ -2439,15 +2565,15 @@ function signal(initial, options) {
2439
2565
  if (equalsFn(prev, newValue)) return;
2440
2566
  state.value = newValue;
2441
2567
  state.__v++;
2442
- if (_isDev9) {
2568
+ if (_isDev10) {
2443
2569
  const hook = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
2444
2570
  if (hook) hook.emit("signal:update", { signal: state, name: debugName, oldValue: prev, newValue });
2445
2571
  }
2446
2572
  if (!enqueueBatchedSignal(state)) {
2447
- notifySubscribers(state);
2573
+ notifySubscribers2(state);
2448
2574
  }
2449
2575
  };
2450
- } else if (_isDev9) {
2576
+ } else if (_isDev10) {
2451
2577
  set = (next) => {
2452
2578
  const prev = state.value;
2453
2579
  const newValue = typeof next === "function" ? next(prev) : next;
@@ -2457,7 +2583,7 @@ function signal(initial, options) {
2457
2583
  const hook = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
2458
2584
  if (hook) hook.emit("signal:update", { signal: state, name: debugName, oldValue: prev, newValue });
2459
2585
  if (!enqueueBatchedSignal(state)) {
2460
- notifySubscribers(state);
2586
+ notifySubscribers2(state);
2461
2587
  }
2462
2588
  };
2463
2589
  } else {
@@ -2468,11 +2594,11 @@ function signal(initial, options) {
2468
2594
  state.value = newValue;
2469
2595
  state.__v++;
2470
2596
  if (!enqueueBatchedSignal(state)) {
2471
- notifySubscribers(state);
2597
+ notifySubscribers2(state);
2472
2598
  }
2473
2599
  };
2474
2600
  }
2475
- if (_isDev9) {
2601
+ if (_isDev10) {
2476
2602
  const hook = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
2477
2603
  if (hook) hook.emit("signal:create", { signal: state, name: debugName, getter: get, initial });
2478
2604
  }
@@ -2480,23 +2606,29 @@ function signal(initial, options) {
2480
2606
  }
2481
2607
 
2482
2608
  // src/core/ssr-context.ts
2483
- var als = null;
2484
- try {
2485
- if (typeof process !== "undefined" && process.versions && process.versions.node) {
2486
- let mod = null;
2487
- const getBuiltin = process.getBuiltinModule;
2488
- if (typeof getBuiltin === "function") {
2489
- mod = getBuiltin("node:async_hooks");
2490
- } else {
2491
- const req = Function("return typeof require==='function'?require:null")();
2492
- if (req) mod = req("node:async_hooks");
2609
+ var SSR_KEY = /* @__PURE__ */ Symbol.for("sibujs.ssr.v1");
2610
+ function detectSSRShared() {
2611
+ let detected = null;
2612
+ try {
2613
+ if (typeof process !== "undefined" && process.versions && process.versions.node) {
2614
+ let mod = null;
2615
+ const getBuiltin = process.getBuiltinModule;
2616
+ if (typeof getBuiltin === "function") {
2617
+ mod = getBuiltin("node:async_hooks");
2618
+ } else {
2619
+ const req = Function("return typeof require==='function'?require:null")();
2620
+ if (req) mod = req("node:async_hooks");
2621
+ }
2622
+ if (mod) detected = new mod.AsyncLocalStorage();
2493
2623
  }
2494
- if (mod) als = new mod.AsyncLocalStorage();
2624
+ } catch {
2625
+ detected = null;
2495
2626
  }
2496
- } catch {
2497
- als = null;
2627
+ return { als: detected, fallbackStore: { ssr: false, suspenseIdCounter: 0 } };
2498
2628
  }
2499
- var fallbackStore = { ssr: false, suspenseIdCounter: 0 };
2629
+ var _shared = globalThis[SSR_KEY] ?? (globalThis[SSR_KEY] = detectSSRShared());
2630
+ var als = _shared.als;
2631
+ var fallbackStore = _shared.fallbackStore;
2500
2632
  function getSSRStore() {
2501
2633
  if (als) {
2502
2634
  const s2 = als.getStore();
@@ -2561,11 +2693,11 @@ function on(deps, handler) {
2561
2693
  if (first) {
2562
2694
  first = false;
2563
2695
  prev = value;
2564
- untracked(() => handler(value, void 0));
2696
+ untracked2(() => handler(value, void 0));
2565
2697
  } else {
2566
2698
  const p2 = prev;
2567
2699
  prev = value;
2568
- untracked(() => handler(value, p2));
2700
+ untracked2(() => handler(value, p2));
2569
2701
  }
2570
2702
  };
2571
2703
  }
@@ -2587,7 +2719,7 @@ function drainReruns(ctx) {
2587
2719
  do {
2588
2720
  ctx.rerunPending = false;
2589
2721
  if (ctx.userCleanups.length > 0) flushUserCleanups(ctx);
2590
- retrack(ctx.bodyFn, ctx.subscriber);
2722
+ retrack2(ctx.bodyFn, ctx.subscriber);
2591
2723
  } while (ctx.rerunPending && ++reruns <= MAX_RERUNS);
2592
2724
  if (ctx.rerunPending) {
2593
2725
  ctx.rerunPending = false;
@@ -2616,7 +2748,7 @@ function disposeEffect(ctx) {
2616
2748
  }
2617
2749
  }
2618
2750
  try {
2619
- cleanup(ctx.subscriber);
2751
+ cleanup2(ctx.subscriber);
2620
2752
  } catch (err) {
2621
2753
  if (typeof console !== "undefined") {
2622
2754
  console.warn("[SibuJS effect] dispose threw:", err);
@@ -2661,7 +2793,7 @@ function effect(effectFn, options) {
2661
2793
  try {
2662
2794
  ctx.rerunPending = false;
2663
2795
  if (ctx.userCleanups.length > 0) flushUserCleanups(ctx);
2664
- retrack(ctx.bodyFn, sub2);
2796
+ retrack2(ctx.bodyFn, sub2);
2665
2797
  if (ctx.rerunPending) drainReruns(ctx);
2666
2798
  } finally {
2667
2799
  ctx.running = false;
@@ -2677,7 +2809,7 @@ function effect(effectFn, options) {
2677
2809
  ctx.subscriber = sub2;
2678
2810
  ctx.running = true;
2679
2811
  try {
2680
- retrack(ctx.bodyFn, ctx.subscriber);
2812
+ retrack2(ctx.bodyFn, ctx.subscriber);
2681
2813
  if (ctx.rerunPending) drainReruns(ctx);
2682
2814
  } finally {
2683
2815
  ctx.running = false;
@@ -2710,7 +2842,7 @@ function derived(getter, options) {
2710
2842
  cs._d = false;
2711
2843
  cs._init = true;
2712
2844
  };
2713
- track(() => {
2845
+ track2(() => {
2714
2846
  let threw = true;
2715
2847
  try {
2716
2848
  cs._v = getter();
@@ -2729,12 +2861,12 @@ function derived(getter, options) {
2729
2861
  `[SibuJS] Circular dependency detected in derived${debugName ? ` "${debugName}"` : ""}. A derived signal cannot read itself (directly or through a chain).`
2730
2862
  );
2731
2863
  }
2732
- if (trackingSuspended) {
2864
+ if (isTrackingSuspended2()) {
2733
2865
  if (cs._d) {
2734
2866
  const prev = cs._v;
2735
2867
  evaluating = true;
2736
2868
  try {
2737
- retrack(recompute, markDirty);
2869
+ retrack2(recompute, markDirty);
2738
2870
  if (!Object.is(prev, cs._v)) cs.__v++;
2739
2871
  } finally {
2740
2872
  evaluating = false;
@@ -2742,12 +2874,12 @@ function derived(getter, options) {
2742
2874
  }
2743
2875
  return cs._v;
2744
2876
  }
2745
- recordDependency(cs);
2877
+ recordDependency2(cs);
2746
2878
  if (cs._d) {
2747
2879
  const oldValue = cs._v;
2748
2880
  evaluating = true;
2749
2881
  try {
2750
- retrack(recompute, markDirty);
2882
+ retrack2(recompute, markDirty);
2751
2883
  if (!Object.is(oldValue, cs._v)) cs.__v++;
2752
2884
  } finally {
2753
2885
  evaluating = false;
@@ -2785,15 +2917,15 @@ function watch(getter, callback) {
2785
2917
  if (!Object.is(newValue, oldValue)) {
2786
2918
  const prev = oldValue;
2787
2919
  oldValue = newValue;
2788
- suspendTracking();
2920
+ suspendTracking2();
2789
2921
  try {
2790
2922
  callback(newValue, prev);
2791
2923
  } finally {
2792
- resumeTracking();
2924
+ resumeTracking2();
2793
2925
  }
2794
2926
  }
2795
2927
  };
2796
- const teardown = track(subscriber);
2928
+ const teardown = track2(subscriber);
2797
2929
  return teardown;
2798
2930
  }
2799
2931
 
@@ -2856,11 +2988,11 @@ function store(initialState) {
2856
2988
  first = false;
2857
2989
  return;
2858
2990
  }
2859
- suspendTracking();
2991
+ suspendTracking2();
2860
2992
  try {
2861
2993
  callback(snapshot);
2862
2994
  } finally {
2863
- resumeTracking();
2995
+ resumeTracking2();
2864
2996
  }
2865
2997
  });
2866
2998
  };
@@ -2877,11 +3009,11 @@ function store(initialState) {
2877
3009
  if (!Object.is(current, prev)) {
2878
3010
  const oldPrev = prev;
2879
3011
  prev = current;
2880
- suspendTracking();
3012
+ suspendTracking2();
2881
3013
  try {
2882
3014
  callback(current, oldPrev);
2883
3015
  } finally {
2884
- resumeTracking();
3016
+ resumeTracking2();
2885
3017
  }
2886
3018
  }
2887
3019
  });
@@ -2983,11 +3115,11 @@ function reactiveArray(initial = []) {
2983
3115
  function notify() {
2984
3116
  snapshot = null;
2985
3117
  if (!enqueueBatchedSignal(signal2)) {
2986
- notifySubscribers(signal2);
3118
+ notifySubscribers2(signal2);
2987
3119
  }
2988
3120
  }
2989
3121
  function get() {
2990
- recordDependency(signal2);
3122
+ recordDependency2(signal2);
2991
3123
  if (snapshot === null) {
2992
3124
  const copy = data2.slice();
2993
3125
  snapshot = Object.freeze(copy);
@@ -3243,9 +3375,9 @@ function safeCall(cb, hookName) {
3243
3375
  }
3244
3376
  }
3245
3377
  function runMountCallback(callback, hookName, element) {
3246
- const cleanup2 = safeCall(callback, hookName);
3247
- if (typeof cleanup2 === "function" && element) {
3248
- registerDisposer(element, cleanup2);
3378
+ const cleanup3 = safeCall(callback, hookName);
3379
+ if (typeof cleanup3 === "function" && element) {
3380
+ registerDisposer(element, cleanup3);
3249
3381
  }
3250
3382
  }
3251
3383
  var mountWatchers = /* @__PURE__ */ new WeakMap();
@@ -3561,7 +3693,7 @@ function defer(getter) {
3561
3693
  }
3562
3694
  });
3563
3695
  };
3564
- const teardown = track(() => {
3696
+ const teardown = track2(() => {
3565
3697
  latest = getter();
3566
3698
  schedule();
3567
3699
  });
@@ -3713,14 +3845,14 @@ function Suspense({ nodes, fallback }) {
3713
3845
  }
3714
3846
 
3715
3847
  // src/platform/ssr.ts
3716
- var _isDev10 = isDev();
3848
+ var _isDev11 = isDev();
3717
3849
  function trustHTML(html3) {
3718
3850
  return html3;
3719
3851
  }
3720
3852
  var DEFAULT_MAX_SSR_BYTES = 1024 * 1024;
3721
3853
 
3722
3854
  // src/components/ErrorDisplay.ts
3723
- var _isDev11 = isDev();
3855
+ var _isDev12 = isDev();
3724
3856
  var STYLES = `
3725
3857
  .sibu-error-display {
3726
3858
  border: 1px solid var(--sibu-err-border, #e5484d);
@@ -4031,7 +4163,7 @@ function ErrorDisplay(props) {
4031
4163
  injectStyles();
4032
4164
  const severity = props.severity ?? "error";
4033
4165
  const normalized = normalizeError(props.error);
4034
- const showDetails = props.alwaysShowDetails ?? _isDev11;
4166
+ const showDetails = props.alwaysShowDetails ?? _isDev12;
4035
4167
  const headline = props.title ?? normalized.message;
4036
4168
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").slice(0, 19);
4037
4169
  const [copyLabel, setCopyLabel] = signal("Copy");
@@ -4620,6 +4752,7 @@ function Loading(props = {}) {
4620
4752
  footer,
4621
4753
  form,
4622
4754
  g,
4755
+ getAction,
4623
4756
  getRequestScopedCache,
4624
4757
  getSSRStore,
4625
4758
  getSlot,
@@ -4688,6 +4821,7 @@ function Loading(props = {}) {
4688
4821
  reactiveArray,
4689
4822
  rect,
4690
4823
  ref,
4824
+ registerAction,
4691
4825
  registerComponent,
4692
4826
  registerDisposer,
4693
4827
  resolveComponent,