sibujs 3.2.2 → 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 (60) hide show
  1. package/dist/browser.cjs +217 -27
  2. package/dist/browser.js +5 -5
  3. package/dist/build.cjs +236 -105
  4. package/dist/build.js +14 -14
  5. package/dist/cdn.global.js +7 -7
  6. package/dist/{chunk-5N74TKLD.js → chunk-37BUKSLH.js} +1 -1
  7. package/dist/{chunk-BGNLPNGV.js → chunk-4UUMSLSL.js} +4 -4
  8. package/dist/{chunk-2UPRY23K.js → chunk-5VGSK6D2.js} +1 -1
  9. package/dist/{chunk-OYLPZO4N.js → chunk-6LTFHJQG.js} +4 -4
  10. package/dist/{chunk-VOCE4NNK.js → chunk-AMIKDMLP.js} +5 -5
  11. package/dist/{chunk-LMLD24FC.js → chunk-COY6PUD2.js} +7 -1
  12. package/dist/{chunk-YFDGQWDA.js → chunk-F7FXQ3QS.js} +1 -1
  13. package/dist/{chunk-V2MTG5FT.js → chunk-IKLYI3RF.js} +33 -16
  14. package/dist/{chunk-HMJFCBRR.js → chunk-L3GAGWCC.js} +10 -1
  15. package/dist/{chunk-X67UYC74.js → chunk-LU2MQXQQ.js} +14 -24
  16. package/dist/{chunk-4JCAUOLN.js → chunk-M5KBNOSJ.js} +22 -12
  17. package/dist/{chunk-FDY42FIU.js → chunk-MHBCEJQO.js} +2 -2
  18. package/dist/{chunk-RLUJL2MV.js → chunk-NHKQKKZU.js} +6 -7
  19. package/dist/{chunk-HXMS4SNP.js → chunk-R3QEDXFS.js} +2 -2
  20. package/dist/{chunk-NPIEEKPT.js → chunk-RYMOSG5B.js} +6 -6
  21. package/dist/{chunk-H6PCHJZQ.js → chunk-SLMFA3ZZ.js} +11 -3
  22. package/dist/{chunk-Z2FWAE4B.js → chunk-TEFZT5PJ.js} +84 -16
  23. package/dist/{chunk-7XDYVJLE.js → chunk-ULLTNDRA.js} +6 -6
  24. package/dist/{chunk-GOUM4JCT.js → chunk-VOVVTOEA.js} +2 -2
  25. package/dist/{chunk-FOI23UJL.js → chunk-WL7BIR6O.js} +1 -1
  26. package/dist/{chunk-JYXOEYI4.js → chunk-WW6DAGGR.js} +5 -5
  27. package/dist/{chunk-C427DVQF.js → chunk-WZG2SZOT.js} +22 -5
  28. package/dist/{chunk-NFYWLRUO.js → chunk-XH2RTYEQ.js} +3 -3
  29. package/dist/{chunk-2C4E3HBM.js → chunk-Z37APKBV.js} +5 -5
  30. package/dist/{chunk-RDRSWYNP.js → chunk-ZUVLC7TM.js} +1 -1
  31. package/dist/data.cjs +168 -24
  32. package/dist/data.js +8 -8
  33. package/dist/devtools.cjs +252 -32
  34. package/dist/devtools.js +7 -7
  35. package/dist/ecosystem.cjs +205 -64
  36. package/dist/ecosystem.js +10 -10
  37. package/dist/extras.cjs +245 -112
  38. package/dist/extras.js +24 -24
  39. package/dist/index.cjs +236 -105
  40. package/dist/index.d.cts +72 -8
  41. package/dist/index.d.ts +72 -8
  42. package/dist/index.js +14 -14
  43. package/dist/motion.cjs +336 -14
  44. package/dist/motion.js +4 -4
  45. package/dist/patterns.cjs +168 -24
  46. package/dist/patterns.js +6 -6
  47. package/dist/performance.cjs +305 -32
  48. package/dist/performance.js +8 -8
  49. package/dist/plugins.cjs +268 -69
  50. package/dist/plugins.js +12 -12
  51. package/dist/{ssr-2QDQ27EV.js → ssr-6D67RAVB.js} +3 -3
  52. package/dist/ssr.cjs +205 -63
  53. package/dist/ssr.js +11 -11
  54. package/dist/testing.cjs +415 -12
  55. package/dist/testing.js +16 -10
  56. package/dist/ui.cjs +248 -36
  57. package/dist/ui.js +9 -9
  58. package/dist/widgets.cjs +176 -26
  59. package/dist/widgets.js +8 -8
  60. package/package.json +1 -1
package/dist/ssr.js CHANGED
@@ -22,8 +22,8 @@ import {
22
22
  wasm,
23
23
  worker,
24
24
  workerFn
25
- } from "./chunk-OYLPZO4N.js";
26
- import "./chunk-5N74TKLD.js";
25
+ } from "./chunk-6LTFHJQG.js";
26
+ import "./chunk-37BUKSLH.js";
27
27
  import {
28
28
  collectStream,
29
29
  deserializeState,
@@ -43,16 +43,16 @@ import {
43
43
  ssrSuspense,
44
44
  suspenseSwapScript,
45
45
  trustHTML
46
- } from "./chunk-HXMS4SNP.js";
47
- import "./chunk-X67UYC74.js";
48
- import "./chunk-RLUJL2MV.js";
49
- import "./chunk-2UPRY23K.js";
50
- import "./chunk-HMJFCBRR.js";
51
- import "./chunk-FDY42FIU.js";
46
+ } from "./chunk-R3QEDXFS.js";
47
+ import "./chunk-LU2MQXQQ.js";
48
+ import "./chunk-NHKQKKZU.js";
49
+ import "./chunk-5VGSK6D2.js";
50
+ import "./chunk-L3GAGWCC.js";
51
+ import "./chunk-MHBCEJQO.js";
52
52
  import "./chunk-GOJMFRBL.js";
53
- import "./chunk-C427DVQF.js";
54
- import "./chunk-Z2FWAE4B.js";
55
- import "./chunk-LMLD24FC.js";
53
+ import "./chunk-WZG2SZOT.js";
54
+ import "./chunk-TEFZT5PJ.js";
55
+ import "./chunk-COY6PUD2.js";
56
56
  export {
57
57
  Head,
58
58
  clearWasmCache,
package/dist/testing.cjs CHANGED
@@ -68,7 +68,13 @@ module.exports = __toCommonJS(testing_exports);
68
68
 
69
69
  // src/core/dev.ts
70
70
  function isDev() {
71
- return typeof globalThis.__SIBU_DEV__ !== "undefined" ? !!globalThis.__SIBU_DEV__ : typeof __SIBU_DEV__ !== "undefined" ? __SIBU_DEV__ : typeof process !== "undefined" && process.env?.NODE_ENV !== "production";
71
+ return typeof globalThis.__SIBU_DEV__ !== "undefined" ? !!globalThis.__SIBU_DEV__ : (
72
+ // The bare `__SIBU_DEV__` is a bundler define that only exists in
73
+ // production builds; under the test runner it is always undefined, so
74
+ // this branch is unreachable here.
75
+ /* v8 ignore next 2 */
76
+ typeof __SIBU_DEV__ !== "undefined" ? __SIBU_DEV__ : typeof process !== "undefined" && process.env?.NODE_ENV !== "production"
77
+ );
72
78
  }
73
79
  var _isDev = isDev();
74
80
  function devAssert(condition, message) {
@@ -76,6 +82,11 @@ function devAssert(condition, message) {
76
82
  throw new Error(`[SibuJS] ${message}`);
77
83
  }
78
84
  }
85
+ function devWarn(message) {
86
+ if (_isDev) {
87
+ console.warn(`[SibuJS] ${message}`);
88
+ }
89
+ }
79
90
 
80
91
  // src/core/rendering/dispose.ts
81
92
  var elementDisposers = /* @__PURE__ */ new WeakMap();
@@ -130,6 +141,9 @@ function dispose(node) {
130
141
  }
131
142
 
132
143
  // src/testing/a11y.ts
144
+ function escSel(value) {
145
+ return value.replace(/["\\]/g, "\\$&");
146
+ }
133
147
  var VALID_ARIA_ROLES = /* @__PURE__ */ new Set([
134
148
  "alert",
135
149
  "alertdialog",
@@ -386,7 +400,7 @@ function checkInputHasLabel(input, root) {
386
400
  if (input.getAttribute("title")?.trim()) return true;
387
401
  const id = input.getAttribute("id");
388
402
  if (id) {
389
- const label = root.querySelector(`label[for="${id}"]`);
403
+ const label = root.querySelector(`label[for="${escSel(id)}"]`);
390
404
  if (label?.textContent?.trim()) return true;
391
405
  }
392
406
  let parent = input.parentElement;
@@ -972,6 +986,9 @@ function assertA11y(root, options) {
972
986
  }
973
987
 
974
988
  // src/testing/adapters.ts
989
+ function escSel2(value) {
990
+ return value.replace(/["\\]/g, "\\$&");
991
+ }
975
992
  function createJestAdapter() {
976
993
  let container = null;
977
994
  return {
@@ -1187,10 +1204,10 @@ function createUniversalAdapter() {
1187
1204
  /** Query helpers */
1188
1205
  queries: {
1189
1206
  byTestId(container2, id) {
1190
- return container2.querySelector(`[data-testid="${id}"]`);
1207
+ return container2.querySelector(`[data-testid="${escSel2(id)}"]`);
1191
1208
  },
1192
1209
  byRole(container2, role) {
1193
- return container2.querySelector(`[role="${role}"]`);
1210
+ return container2.querySelector(`[role="${escSel2(role)}"]`);
1194
1211
  },
1195
1212
  byText(container2, text) {
1196
1213
  const walker = document.createTreeWalker(container2, NodeFilter.SHOW_TEXT);
@@ -1207,16 +1224,16 @@ function createUniversalAdapter() {
1207
1224
  if (labelEl.textContent?.includes(label)) {
1208
1225
  const forAttr = labelEl.getAttribute("for");
1209
1226
  if (forAttr) {
1210
- return container2.querySelector(`#${forAttr}`);
1227
+ return container2.querySelector(`[id="${escSel2(forAttr)}"]`);
1211
1228
  }
1212
1229
  const nested = labelEl.querySelector("input, select, textarea");
1213
1230
  if (nested) return nested;
1214
1231
  }
1215
1232
  }
1216
- return container2.querySelector(`[aria-label="${label}"]`);
1233
+ return container2.querySelector(`[aria-label="${escSel2(label)}"]`);
1217
1234
  },
1218
1235
  allByRole(container2, role) {
1219
- return Array.from(container2.querySelectorAll(`[role="${role}"]`));
1236
+ return Array.from(container2.querySelectorAll(`[role="${escSel2(role)}"]`));
1220
1237
  }
1221
1238
  },
1222
1239
  /** Assertion helpers */
@@ -1547,10 +1564,36 @@ function testComponent(component, options = {}) {
1547
1564
  };
1548
1565
  }
1549
1566
 
1550
- // src/reactivity/track.ts
1567
+ // src/reactivity/track-core.ts
1551
1568
  var _isDev3 = isDev();
1552
1569
  var POOL_MAX = 4096;
1553
1570
  var nodePool = [];
1571
+ function createNode() {
1572
+ return {
1573
+ sig: null,
1574
+ sub: null,
1575
+ epoch: 0,
1576
+ sigPrev: null,
1577
+ sigNext: null,
1578
+ subPrev: null,
1579
+ subNext: null,
1580
+ prevActive: null
1581
+ };
1582
+ }
1583
+ function allocNode(sig, sub, epoch) {
1584
+ const n = nodePool.pop();
1585
+ if (n) {
1586
+ n.sig = sig;
1587
+ n.sub = sub;
1588
+ n.epoch = epoch;
1589
+ return n;
1590
+ }
1591
+ const fresh = createNode();
1592
+ fresh.sig = sig;
1593
+ fresh.sub = sub;
1594
+ fresh.epoch = epoch;
1595
+ return fresh;
1596
+ }
1554
1597
  function freeNode(node) {
1555
1598
  node.sig = null;
1556
1599
  node.sub = null;
@@ -1561,6 +1604,15 @@ function freeNode(node) {
1561
1604
  node.prevActive = null;
1562
1605
  if (nodePool.length < POOL_MAX) nodePool.push(node);
1563
1606
  }
1607
+ function linkSignal(sig, node) {
1608
+ const oldHead = sig.subsHead ?? null;
1609
+ node.sigPrev = null;
1610
+ node.sigNext = oldHead;
1611
+ if (oldHead) oldHead.sigPrev = node;
1612
+ else sig.subsTail = node;
1613
+ sig.subsHead = node;
1614
+ sig.__sc = (sig.__sc ?? 0) + 1;
1615
+ }
1564
1616
  function unlinkSignal(node) {
1565
1617
  const sig = node.sig;
1566
1618
  if (!sig) return;
@@ -1577,6 +1629,14 @@ function unlinkSignal(node) {
1577
1629
  sig.subsTail = null;
1578
1630
  }
1579
1631
  }
1632
+ function linkSub(sub, node) {
1633
+ const oldTail = sub.depsTail ?? null;
1634
+ node.subPrev = oldTail;
1635
+ node.subNext = null;
1636
+ if (oldTail) oldTail.subNext = node;
1637
+ else sub.depsHead = node;
1638
+ sub.depsTail = node;
1639
+ }
1580
1640
  function unlinkSub(node) {
1581
1641
  const sub = node.sub;
1582
1642
  if (!sub) return;
@@ -1588,6 +1648,47 @@ function unlinkSub(node) {
1588
1648
  else sub.depsTail = prev;
1589
1649
  }
1590
1650
  var currentSubscriber = null;
1651
+ var suspendSavedSub = null;
1652
+ var notifyDepth = 0;
1653
+ var pendingQueue = [];
1654
+ var pendingSet = /* @__PURE__ */ new Set();
1655
+ var propagateStack = [];
1656
+ function safeInvoke(sub) {
1657
+ try {
1658
+ sub();
1659
+ } catch (err) {
1660
+ if (_isDev3) devWarn(`Subscriber threw during notification: ${err instanceof Error ? err.message : String(err)}`);
1661
+ }
1662
+ }
1663
+ var suspendDepth = 0;
1664
+ var trackingSuspended = false;
1665
+ function suspendTracking() {
1666
+ if (suspendDepth === 0) {
1667
+ suspendSavedSub = currentSubscriber;
1668
+ currentSubscriber = null;
1669
+ trackingSuspended = true;
1670
+ }
1671
+ suspendDepth++;
1672
+ }
1673
+ function resumeTracking() {
1674
+ suspendDepth--;
1675
+ if (suspendDepth === 0) {
1676
+ currentSubscriber = suspendSavedSub;
1677
+ suspendSavedSub = null;
1678
+ trackingSuspended = false;
1679
+ }
1680
+ }
1681
+ function isTrackingSuspended() {
1682
+ return trackingSuspended;
1683
+ }
1684
+ function untracked(fn) {
1685
+ suspendTracking();
1686
+ try {
1687
+ return fn();
1688
+ } finally {
1689
+ resumeTracking();
1690
+ }
1691
+ }
1591
1692
  var subscriberEpochCounter = 0;
1592
1693
  function retrack(effectFn, subscriber) {
1593
1694
  const prev = currentSubscriber;
@@ -1620,6 +1721,68 @@ function retrack(effectFn, subscriber) {
1620
1721
  }
1621
1722
  }
1622
1723
  }
1724
+ function track(effectFn, subscriber) {
1725
+ if (!subscriber) return reactiveBinding(effectFn);
1726
+ cleanup(subscriber);
1727
+ const prev = currentSubscriber;
1728
+ currentSubscriber = subscriber;
1729
+ try {
1730
+ effectFn();
1731
+ } finally {
1732
+ currentSubscriber = prev;
1733
+ const sub2 = subscriber;
1734
+ for (let n = sub2.depsHead ?? null; n !== null; n = n.subNext) {
1735
+ const sig = n.sig;
1736
+ sig.__activeNode = n.prevActive;
1737
+ n.prevActive = null;
1738
+ }
1739
+ }
1740
+ const sub = subscriber;
1741
+ return sub._dispose ?? (sub._dispose = () => cleanup(subscriber));
1742
+ }
1743
+ function reactiveBinding(commit) {
1744
+ const run = () => {
1745
+ const s = subscriber;
1746
+ if (s._disposed || s._reentrant) return;
1747
+ s._reentrant = true;
1748
+ try {
1749
+ retrack(commit, subscriber);
1750
+ } finally {
1751
+ s._reentrant = false;
1752
+ }
1753
+ };
1754
+ const subscriber = run;
1755
+ subscriber.depsHead = null;
1756
+ subscriber.depsTail = null;
1757
+ subscriber._epoch = 0;
1758
+ subscriber._structDirty = false;
1759
+ subscriber._runEpoch = 0;
1760
+ subscriber._runs = 0;
1761
+ subscriber._reentrant = false;
1762
+ subscriber._disposed = false;
1763
+ run();
1764
+ return subscriber._dispose ?? (subscriber._dispose = () => {
1765
+ subscriber._disposed = true;
1766
+ cleanup(subscriber);
1767
+ });
1768
+ }
1769
+ function recordDependency(signal) {
1770
+ if (!currentSubscriber) return;
1771
+ const sub = currentSubscriber;
1772
+ const sig = signal;
1773
+ const epoch = sub._epoch ?? 0;
1774
+ const active = sig.__activeNode ?? null;
1775
+ if (active !== null && active.sub === sub) {
1776
+ active.epoch = epoch;
1777
+ return;
1778
+ }
1779
+ const node = allocNode(signal, sub, epoch);
1780
+ node.prevActive = active;
1781
+ sig.__activeNode = node;
1782
+ linkSub(sub, node);
1783
+ linkSignal(sig, node);
1784
+ sub._structDirty = true;
1785
+ }
1623
1786
  function cleanup(subscriber) {
1624
1787
  const sub = subscriber;
1625
1788
  let node = sub.depsHead ?? null;
@@ -1632,6 +1795,246 @@ function cleanup(subscriber) {
1632
1795
  node = next;
1633
1796
  }
1634
1797
  }
1798
+ var maxSubscriberRepeats = 50;
1799
+ var maxDrainIterations = 1e6;
1800
+ var drainEpoch = 0;
1801
+ function setMaxSubscriberRepeats(n) {
1802
+ const prev = maxSubscriberRepeats;
1803
+ if (Number.isFinite(n) && n > 0) maxSubscriberRepeats = Math.floor(n);
1804
+ return prev;
1805
+ }
1806
+ function setMaxDrainIterations(n) {
1807
+ const prev = maxDrainIterations;
1808
+ if (Number.isFinite(n) && n > 0) maxDrainIterations = Math.floor(n);
1809
+ return prev;
1810
+ }
1811
+ function tickRepeat(sub) {
1812
+ const s = sub;
1813
+ if (s._runEpoch !== drainEpoch) {
1814
+ s._runEpoch = drainEpoch;
1815
+ s._runs = 1;
1816
+ return false;
1817
+ }
1818
+ s._runs = (s._runs ?? 0) + 1;
1819
+ return s._runs > maxSubscriberRepeats;
1820
+ }
1821
+ function cycleError(sub) {
1822
+ if (typeof console !== "undefined") {
1823
+ const name = sub.__name ?? "<unnamed>";
1824
+ console.error(
1825
+ `[SibuJS] subscriber "${name}" fired more than ${maxSubscriberRepeats} times \u2014 likely a write-reads-self cycle between effects/signals. Breaking to prevent infinite loop.`
1826
+ );
1827
+ }
1828
+ }
1829
+ function absoluteDrainError() {
1830
+ if (typeof console !== "undefined") {
1831
+ console.error(
1832
+ `[SibuJS] Notification drain exceeded ${maxDrainIterations} iterations \u2014 absolute safety net tripped. Breaking to prevent infinite loop.`
1833
+ );
1834
+ }
1835
+ }
1836
+ function drainQueue() {
1837
+ let i = 0;
1838
+ while (i < pendingQueue.length) {
1839
+ if (i >= maxDrainIterations) {
1840
+ absoluteDrainError();
1841
+ break;
1842
+ }
1843
+ const sub = pendingQueue[i++];
1844
+ if (tickRepeat(sub)) {
1845
+ cycleError(sub);
1846
+ break;
1847
+ }
1848
+ pendingSet.delete(sub);
1849
+ safeInvoke(sub);
1850
+ }
1851
+ }
1852
+ function drainNotificationQueue() {
1853
+ if (notifyDepth > 0) return;
1854
+ notifyDepth++;
1855
+ drainEpoch++;
1856
+ try {
1857
+ drainQueue();
1858
+ } finally {
1859
+ notifyDepth--;
1860
+ if (notifyDepth === 0) {
1861
+ pendingQueue.length = 0;
1862
+ pendingSet.clear();
1863
+ }
1864
+ }
1865
+ }
1866
+ function propagateDirty(sub) {
1867
+ sub();
1868
+ const rootSig = sub._sig;
1869
+ if (!rootSig) return;
1870
+ const stack = propagateStack;
1871
+ const baseLen = stack.length;
1872
+ stack.push(rootSig);
1873
+ while (stack.length > baseLen) {
1874
+ const sig = stack.pop();
1875
+ let node = sig.subsHead ?? null;
1876
+ while (node) {
1877
+ const s = node.sub;
1878
+ if (s) {
1879
+ if (s._c) {
1880
+ const nSig = s._sig;
1881
+ if (nSig) {
1882
+ if (!nSig._d) {
1883
+ nSig._d = true;
1884
+ stack.push(nSig);
1885
+ }
1886
+ } else {
1887
+ s();
1888
+ }
1889
+ } else if (!pendingSet.has(s)) {
1890
+ pendingSet.add(s);
1891
+ pendingQueue.push(s);
1892
+ }
1893
+ }
1894
+ node = node.sigNext;
1895
+ }
1896
+ }
1897
+ }
1898
+ function queueSignalNotification(signal) {
1899
+ const sig = signal;
1900
+ let node = sig.subsHead ?? null;
1901
+ while (node) {
1902
+ const s = node.sub;
1903
+ if (s) {
1904
+ if (s._c) {
1905
+ propagateDirty(s);
1906
+ } else if (!pendingSet.has(s)) {
1907
+ pendingSet.add(s);
1908
+ pendingQueue.push(s);
1909
+ }
1910
+ }
1911
+ node = node.sigNext;
1912
+ }
1913
+ }
1914
+ function notifySubscribers(signal) {
1915
+ const sig = signal;
1916
+ const head = sig.subsHead;
1917
+ if (!head) return;
1918
+ if (notifyDepth > 0) {
1919
+ let node = head;
1920
+ while (node) {
1921
+ const s = node.sub;
1922
+ if (s) {
1923
+ if (s._c) {
1924
+ propagateDirty(s);
1925
+ } else if (!pendingSet.has(s)) {
1926
+ pendingSet.add(s);
1927
+ pendingQueue.push(s);
1928
+ }
1929
+ }
1930
+ node = node.sigNext;
1931
+ }
1932
+ return;
1933
+ }
1934
+ notifyDepth++;
1935
+ drainEpoch++;
1936
+ try {
1937
+ let node = head;
1938
+ while (node) {
1939
+ const s = node.sub;
1940
+ if (s) {
1941
+ if (s._c) {
1942
+ propagateDirty(s);
1943
+ } else if (!pendingSet.has(s)) {
1944
+ pendingSet.add(s);
1945
+ pendingQueue.push(s);
1946
+ }
1947
+ }
1948
+ node = node.sigNext;
1949
+ }
1950
+ drainQueue();
1951
+ } finally {
1952
+ notifyDepth--;
1953
+ if (notifyDepth === 0) {
1954
+ pendingQueue.length = 0;
1955
+ pendingSet.clear();
1956
+ }
1957
+ }
1958
+ }
1959
+ function getSubscriberCount(signal) {
1960
+ return signal.__sc ?? 0;
1961
+ }
1962
+ function getSubscriberDeps(subscriber) {
1963
+ const sub = subscriber;
1964
+ const out = [];
1965
+ let node = sub.depsHead ?? null;
1966
+ while (node) {
1967
+ if (node.sig) out.push(node.sig);
1968
+ node = node.subNext;
1969
+ }
1970
+ return out;
1971
+ }
1972
+ function forEachSubscriber(signal, visit) {
1973
+ let node = signal.subsHead ?? null;
1974
+ while (node) {
1975
+ const s = node.sub;
1976
+ if (s) visit(s);
1977
+ node = node.sigNext;
1978
+ }
1979
+ }
1980
+
1981
+ // src/reactivity/track.ts
1982
+ var _isDev4 = isDev();
1983
+ var _runtimeVersion = typeof __SIBU_VERSION__ !== "undefined" ? __SIBU_VERSION__ : "dev";
1984
+ var REGISTRY_KEY = /* @__PURE__ */ Symbol.for("sibujs.reactive.v1");
1985
+ function resolveReactiveApi() {
1986
+ const g = globalThis;
1987
+ const existing = g[REGISTRY_KEY];
1988
+ if (existing) {
1989
+ if (_isDev4 && !existing.__dupWarned) {
1990
+ existing.__dupWarned = true;
1991
+ devWarn(
1992
+ `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']).`
1993
+ );
1994
+ }
1995
+ return existing;
1996
+ }
1997
+ const local = {
1998
+ suspendTracking,
1999
+ resumeTracking,
2000
+ isTrackingSuspended,
2001
+ untracked,
2002
+ retrack,
2003
+ track,
2004
+ reactiveBinding,
2005
+ recordDependency,
2006
+ cleanup,
2007
+ setMaxSubscriberRepeats,
2008
+ setMaxDrainIterations,
2009
+ drainNotificationQueue,
2010
+ queueSignalNotification,
2011
+ notifySubscribers,
2012
+ getSubscriberCount,
2013
+ getSubscriberDeps,
2014
+ forEachSubscriber,
2015
+ version: _runtimeVersion
2016
+ };
2017
+ g[REGISTRY_KEY] = local;
2018
+ return local;
2019
+ }
2020
+ var API = resolveReactiveApi();
2021
+ var suspendTracking2 = API.suspendTracking;
2022
+ var resumeTracking2 = API.resumeTracking;
2023
+ var isTrackingSuspended2 = API.isTrackingSuspended;
2024
+ var untracked2 = API.untracked;
2025
+ var retrack2 = API.retrack;
2026
+ var track2 = API.track;
2027
+ var reactiveBinding2 = API.reactiveBinding;
2028
+ var recordDependency2 = API.recordDependency;
2029
+ var cleanup2 = API.cleanup;
2030
+ var setMaxSubscriberRepeats2 = API.setMaxSubscriberRepeats;
2031
+ var setMaxDrainIterations2 = API.setMaxDrainIterations;
2032
+ var drainNotificationQueue2 = API.drainNotificationQueue;
2033
+ var queueSignalNotification2 = API.queueSignalNotification;
2034
+ var notifySubscribers2 = API.notifySubscribers;
2035
+ var getSubscriberCount2 = API.getSubscriberCount;
2036
+ var getSubscriberDeps2 = API.getSubscriberDeps;
2037
+ var forEachSubscriber2 = API.forEachSubscriber;
1635
2038
 
1636
2039
  // src/core/ssr-context.ts
1637
2040
  var als = null;
@@ -1682,7 +2085,7 @@ function drainReruns(ctx) {
1682
2085
  do {
1683
2086
  ctx.rerunPending = false;
1684
2087
  if (ctx.userCleanups.length > 0) flushUserCleanups(ctx);
1685
- retrack(ctx.bodyFn, ctx.subscriber);
2088
+ retrack2(ctx.bodyFn, ctx.subscriber);
1686
2089
  } while (ctx.rerunPending && ++reruns <= MAX_RERUNS);
1687
2090
  if (ctx.rerunPending) {
1688
2091
  ctx.rerunPending = false;
@@ -1711,7 +2114,7 @@ function disposeEffect(ctx) {
1711
2114
  }
1712
2115
  }
1713
2116
  try {
1714
- cleanup(ctx.subscriber);
2117
+ cleanup2(ctx.subscriber);
1715
2118
  } catch (err) {
1716
2119
  if (typeof console !== "undefined") {
1717
2120
  console.warn("[SibuJS effect] dispose threw:", err);
@@ -1756,7 +2159,7 @@ function effect(effectFn, options) {
1756
2159
  try {
1757
2160
  ctx.rerunPending = false;
1758
2161
  if (ctx.userCleanups.length > 0) flushUserCleanups(ctx);
1759
- retrack(ctx.bodyFn, sub);
2162
+ retrack2(ctx.bodyFn, sub);
1760
2163
  if (ctx.rerunPending) drainReruns(ctx);
1761
2164
  } finally {
1762
2165
  ctx.running = false;
@@ -1772,7 +2175,7 @@ function effect(effectFn, options) {
1772
2175
  ctx.subscriber = sub;
1773
2176
  ctx.running = true;
1774
2177
  try {
1775
- retrack(ctx.bodyFn, ctx.subscriber);
2178
+ retrack2(ctx.bodyFn, ctx.subscriber);
1776
2179
  if (ctx.rerunPending) drainReruns(ctx);
1777
2180
  } finally {
1778
2181
  ctx.running = false;
package/dist/testing.js CHANGED
@@ -1,14 +1,17 @@
1
1
  import {
2
2
  dispose
3
- } from "./chunk-2UPRY23K.js";
3
+ } from "./chunk-5VGSK6D2.js";
4
4
  import {
5
5
  effect
6
- } from "./chunk-FDY42FIU.js";
6
+ } from "./chunk-MHBCEJQO.js";
7
7
  import "./chunk-GOJMFRBL.js";
8
- import "./chunk-Z2FWAE4B.js";
9
- import "./chunk-LMLD24FC.js";
8
+ import "./chunk-TEFZT5PJ.js";
9
+ import "./chunk-COY6PUD2.js";
10
10
 
11
11
  // src/testing/a11y.ts
12
+ function escSel(value) {
13
+ return value.replace(/["\\]/g, "\\$&");
14
+ }
12
15
  var VALID_ARIA_ROLES = /* @__PURE__ */ new Set([
13
16
  "alert",
14
17
  "alertdialog",
@@ -265,7 +268,7 @@ function checkInputHasLabel(input, root) {
265
268
  if (input.getAttribute("title")?.trim()) return true;
266
269
  const id = input.getAttribute("id");
267
270
  if (id) {
268
- const label = root.querySelector(`label[for="${id}"]`);
271
+ const label = root.querySelector(`label[for="${escSel(id)}"]`);
269
272
  if (label?.textContent?.trim()) return true;
270
273
  }
271
274
  let parent = input.parentElement;
@@ -851,6 +854,9 @@ function assertA11y(root, options) {
851
854
  }
852
855
 
853
856
  // src/testing/adapters.ts
857
+ function escSel2(value) {
858
+ return value.replace(/["\\]/g, "\\$&");
859
+ }
854
860
  function createJestAdapter() {
855
861
  let container = null;
856
862
  return {
@@ -1066,10 +1072,10 @@ function createUniversalAdapter() {
1066
1072
  /** Query helpers */
1067
1073
  queries: {
1068
1074
  byTestId(container2, id) {
1069
- return container2.querySelector(`[data-testid="${id}"]`);
1075
+ return container2.querySelector(`[data-testid="${escSel2(id)}"]`);
1070
1076
  },
1071
1077
  byRole(container2, role) {
1072
- return container2.querySelector(`[role="${role}"]`);
1078
+ return container2.querySelector(`[role="${escSel2(role)}"]`);
1073
1079
  },
1074
1080
  byText(container2, text) {
1075
1081
  const walker = document.createTreeWalker(container2, NodeFilter.SHOW_TEXT);
@@ -1086,16 +1092,16 @@ function createUniversalAdapter() {
1086
1092
  if (labelEl.textContent?.includes(label)) {
1087
1093
  const forAttr = labelEl.getAttribute("for");
1088
1094
  if (forAttr) {
1089
- return container2.querySelector(`#${forAttr}`);
1095
+ return container2.querySelector(`[id="${escSel2(forAttr)}"]`);
1090
1096
  }
1091
1097
  const nested = labelEl.querySelector("input, select, textarea");
1092
1098
  if (nested) return nested;
1093
1099
  }
1094
1100
  }
1095
- return container2.querySelector(`[aria-label="${label}"]`);
1101
+ return container2.querySelector(`[aria-label="${escSel2(label)}"]`);
1096
1102
  },
1097
1103
  allByRole(container2, role) {
1098
- return Array.from(container2.querySelectorAll(`[role="${role}"]`));
1104
+ return Array.from(container2.querySelectorAll(`[role="${escSel2(role)}"]`));
1099
1105
  }
1100
1106
  },
1101
1107
  /** Assertion helpers */