sibujs 3.0.0 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/README.md +6 -0
  2. package/dist/browser.cjs +16 -8
  3. package/dist/browser.js +6 -5
  4. package/dist/build.cjs +276 -150
  5. package/dist/build.js +35 -24
  6. package/dist/cdn.global.js +7 -7
  7. package/dist/{chunk-RJIRT46U.js → chunk-2C4E3HBM.js} +5 -5
  8. package/dist/{chunk-XDKP4T7G.js → chunk-4JCAUOLN.js} +45 -23
  9. package/dist/{chunk-VSNLICTS.js → chunk-5N74TKLD.js} +1 -1
  10. package/dist/{chunk-XVYB3J6C.js → chunk-7XDYVJLE.js} +19 -9
  11. package/dist/{chunk-L52H775O.js → chunk-BGNLPNGV.js} +20 -12
  12. package/dist/{chunk-6QZO7MMG.js → chunk-C427DVQF.js} +1 -1
  13. package/dist/{chunk-5WD7BYTZ.js → chunk-FDY42FIU.js} +3 -2
  14. package/dist/{chunk-4YTVESDX.js → chunk-FOI23UJL.js} +11 -1
  15. package/dist/{chunk-2RA7SHDA.js → chunk-GOJMFRBL.js} +20 -4
  16. package/dist/{chunk-2KM2724A.js → chunk-GOUM4JCT.js} +6 -6
  17. package/dist/chunk-H3SRKIYX.js +17 -0
  18. package/dist/{chunk-NEWH4O5U.js → chunk-H6PCHJZQ.js} +2 -2
  19. package/dist/{chunk-UCS6AMJ7.js → chunk-HMJFCBRR.js} +26 -3
  20. package/dist/{chunk-JYD2PWXH.js → chunk-HXMS4SNP.js} +22 -15
  21. package/dist/{chunk-DF3GTP4Q.js → chunk-JYXOEYI4.js} +12 -18
  22. package/dist/{chunk-KZA7ANXP.js → chunk-NFYWLRUO.js} +11 -18
  23. package/dist/{chunk-KH4OE6WY.js → chunk-NPIEEKPT.js} +20 -11
  24. package/dist/{chunk-V65KTDZW.js → chunk-OYLPZO4N.js} +33 -15
  25. package/dist/{chunk-LYTCUZ7H.js → chunk-RDRSWYNP.js} +1 -1
  26. package/dist/{chunk-UKMXT5T6.js → chunk-RLUJL2MV.js} +7 -12
  27. package/dist/{chunk-INBOWHQ3.js → chunk-V2MTG5FT.js} +99 -36
  28. package/dist/{chunk-CNZ35WI2.js → chunk-VJE6DDYM.js} +2 -2
  29. package/dist/{chunk-2JQUV4Y3.js → chunk-VOCE4NNK.js} +157 -75
  30. package/dist/{chunk-STFTTMO2.js → chunk-X67UYC74.js} +31 -12
  31. package/dist/{chunk-YMOIAHWA.js → chunk-YFDGQWDA.js} +1 -1
  32. package/dist/{chunk-L4DAT4WU.js → chunk-Z2FWAE4B.js} +28 -1
  33. package/dist/data.cjs +211 -93
  34. package/dist/data.d.cts +7 -1
  35. package/dist/data.d.ts +7 -1
  36. package/dist/data.js +8 -8
  37. package/dist/devtools.cjs +38 -10
  38. package/dist/devtools.d.cts +1 -1
  39. package/dist/devtools.d.ts +1 -1
  40. package/dist/devtools.js +6 -6
  41. package/dist/ecosystem.cjs +163 -65
  42. package/dist/ecosystem.js +9 -9
  43. package/dist/extras.cjs +420 -198
  44. package/dist/extras.d.cts +2 -2
  45. package/dist/extras.d.ts +2 -2
  46. package/dist/extras.js +27 -24
  47. package/dist/index.cjs +255 -139
  48. package/dist/index.d.cts +15 -2
  49. package/dist/index.d.ts +15 -2
  50. package/dist/index.js +15 -13
  51. package/dist/{introspect-BZWKvQUZ.d.ts → introspect-DOZfmC-4.d.ts} +1 -1
  52. package/dist/{introspect-DsJlDD2T.d.cts → introspect-RjLfIFpL.d.cts} +1 -1
  53. package/dist/motion.cjs +10 -0
  54. package/dist/motion.js +3 -3
  55. package/dist/patterns.cjs +66 -39
  56. package/dist/patterns.js +8 -7
  57. package/dist/performance.cjs +101 -25
  58. package/dist/performance.d.cts +2 -2
  59. package/dist/performance.d.ts +2 -2
  60. package/dist/performance.js +8 -7
  61. package/dist/plugins.cjs +243 -138
  62. package/dist/plugins.d.cts +1 -1
  63. package/dist/plugins.d.ts +1 -1
  64. package/dist/plugins.js +96 -45
  65. package/dist/{ssr-FXD2PPMC.js → ssr-2QDQ27EV.js} +5 -3
  66. package/dist/{ssr-CrVNy6Pa.d.cts → ssr-D62yFwuw.d.cts} +8 -1
  67. package/dist/{ssr-CrVNy6Pa.d.ts → ssr-D62yFwuw.d.ts} +8 -1
  68. package/dist/ssr.cjs +185 -68
  69. package/dist/ssr.d.cts +1 -1
  70. package/dist/ssr.d.ts +1 -1
  71. package/dist/ssr.js +12 -10
  72. package/dist/testing.cjs +9 -4
  73. package/dist/testing.js +3 -3
  74. package/dist/ui.cjs +76 -39
  75. package/dist/ui.js +10 -9
  76. package/dist/widgets.cjs +61 -23
  77. package/dist/widgets.js +8 -8
  78. package/package.json +3 -1
package/dist/build.cjs CHANGED
@@ -394,14 +394,16 @@ function compileHtmlTemplates(code2) {
394
394
  const tmpl = templates[i2];
395
395
  const ast = parseTemplateToAST(tmpl.strings);
396
396
  collectTags(ast, usedTags);
397
+ if (ast.length > 1) usedTags.add("div");
397
398
  if (Array.from(usedTags).some((t) => SVG_TAGS.has(t))) usesSvg = true;
398
399
  const valuesVar = "__v";
399
400
  const childExprs = ast.map((c) => generateChild(c, valuesVar));
401
+ const rootExpr = childExprs.length === 1 ? childExprs[0] : `div([${childExprs.join(", ")}])`;
400
402
  let compiled;
401
403
  if (tmpl.exprCount === 0) {
402
- compiled = childExprs.length === 1 ? childExprs[0] : childExprs[0];
404
+ compiled = rootExpr;
403
405
  } else {
404
- const body2 = childExprs.length === 1 ? childExprs[0] : childExprs[0];
406
+ const body2 = rootExpr;
405
407
  const exprSource = extractExpressions(code2, tmpl.start, tmpl.end, tmpl.exprCount);
406
408
  compiled = `((${valuesVar}) => ${body2})([${exprSource.join(", ")}])`;
407
409
  }
@@ -1134,6 +1136,7 @@ __export(index_exports, {
1134
1136
  footer: () => footer,
1135
1137
  form: () => form,
1136
1138
  g: () => g,
1139
+ getRequestScopedCache: () => getRequestScopedCache,
1137
1140
  getSSRStore: () => getSSRStore,
1138
1141
  getSlot: () => getSlot,
1139
1142
  h1: () => h1,
@@ -1282,9 +1285,17 @@ function devWarn(message) {
1282
1285
  }
1283
1286
 
1284
1287
  // src/utils/sanitize.ts
1288
+ function stripControlChars(value) {
1289
+ return value.replace(/[\x00-\x20\x7f-\x9f]+/g, "");
1290
+ }
1291
+ function isEventHandlerAttr(name) {
1292
+ if (name.length < 3) return false;
1293
+ const lower = name.toLowerCase();
1294
+ return lower[0] === "o" && lower[1] === "n" && lower.charCodeAt(2) >= 97 && lower.charCodeAt(2) <= 122;
1295
+ }
1285
1296
  var SAFE_URL_PROTOCOLS = ["http:", "https:", "mailto:", "tel:", "ftp:"];
1286
1297
  function sanitizeUrl(url) {
1287
- const trimmed = url.replace(/[\x00-\x20\x7f-\x9f]+/g, "").trim();
1298
+ const trimmed = stripControlChars(url).trim();
1288
1299
  if (!trimmed) return "";
1289
1300
  const lower = trimmed.toLowerCase();
1290
1301
  let schemeEnd = -1;
@@ -1347,7 +1358,7 @@ var URL_ATTRIBUTES = /* @__PURE__ */ new Set([
1347
1358
  "data"
1348
1359
  ]);
1349
1360
  function isUrlAttribute(attr) {
1350
- return URL_ATTRIBUTES.has(attr);
1361
+ return URL_ATTRIBUTES.has(attr.toLowerCase());
1351
1362
  }
1352
1363
 
1353
1364
  // src/reactivity/track.ts
@@ -1505,7 +1516,7 @@ function retrack(effectFn, subscriber) {
1505
1516
  }
1506
1517
  }
1507
1518
  function track(effectFn, subscriber) {
1508
- if (!subscriber) subscriber = effectFn;
1519
+ if (!subscriber) return reactiveBinding(effectFn);
1509
1520
  cleanup(subscriber);
1510
1521
  const prev = currentSubscriber;
1511
1522
  currentSubscriber = subscriber;
@@ -1523,6 +1534,32 @@ function track(effectFn, subscriber) {
1523
1534
  const sub2 = subscriber;
1524
1535
  return sub2._dispose ?? (sub2._dispose = () => cleanup(subscriber));
1525
1536
  }
1537
+ function reactiveBinding(commit) {
1538
+ const run = () => {
1539
+ const s2 = subscriber;
1540
+ if (s2._disposed || s2._reentrant) return;
1541
+ s2._reentrant = true;
1542
+ try {
1543
+ retrack(commit, subscriber);
1544
+ } finally {
1545
+ s2._reentrant = false;
1546
+ }
1547
+ };
1548
+ const subscriber = run;
1549
+ subscriber.depsHead = null;
1550
+ subscriber.depsTail = null;
1551
+ subscriber._epoch = 0;
1552
+ subscriber._structDirty = false;
1553
+ subscriber._runEpoch = 0;
1554
+ subscriber._runs = 0;
1555
+ subscriber._reentrant = false;
1556
+ subscriber._disposed = false;
1557
+ run();
1558
+ return subscriber._dispose ?? (subscriber._dispose = () => {
1559
+ subscriber._disposed = true;
1560
+ cleanup(subscriber);
1561
+ });
1562
+ }
1526
1563
  function recordDependency(signal2) {
1527
1564
  if (!currentSubscriber) return;
1528
1565
  const sub2 = currentSubscriber;
@@ -1714,11 +1751,6 @@ var _isDev3 = isDev();
1714
1751
  function setProp(el, key, val) {
1715
1752
  el[key] = val;
1716
1753
  }
1717
- function isEventHandlerAttr(name) {
1718
- if (name.length < 3) return false;
1719
- const lower = name.toLowerCase();
1720
- return lower[0] === "o" && lower[1] === "n" && lower.charCodeAt(2) >= 97 && lower.charCodeAt(2) <= 122;
1721
- }
1722
1754
  function bindAttribute(el, attr, getter) {
1723
1755
  if (isEventHandlerAttr(attr)) {
1724
1756
  if (_isDev3)
@@ -1754,8 +1786,7 @@ function bindAttribute(el, attr, getter) {
1754
1786
  el.setAttribute(attr, isUrlAttribute(attr) ? sanitizeUrl(str) : str);
1755
1787
  }
1756
1788
  }
1757
- const teardown = track(commit);
1758
- return teardown;
1789
+ return reactiveBinding(commit);
1759
1790
  }
1760
1791
  function bindDynamic(el, nameGetter, valueGetter) {
1761
1792
  let prevName = null;
@@ -1774,7 +1805,7 @@ function bindDynamic(el, nameGetter, valueGetter) {
1774
1805
  if (_isDev3) devWarn(`bindDynamic: value getter threw: ${err instanceof Error ? err.message : String(err)}`);
1775
1806
  return;
1776
1807
  }
1777
- if ((name[0] === "o" || name[0] === "O") && (name[1] === "n" || name[1] === "N")) return;
1808
+ if (isEventHandlerAttr(name)) return;
1778
1809
  if (prevName !== null && prevName !== name) {
1779
1810
  el.removeAttribute(prevName);
1780
1811
  }
@@ -1786,7 +1817,7 @@ function bindDynamic(el, nameGetter, valueGetter) {
1786
1817
  }
1787
1818
  prevName = name;
1788
1819
  }
1789
- const teardown = track(commit);
1820
+ const teardown = reactiveBinding(commit);
1790
1821
  return () => {
1791
1822
  teardown();
1792
1823
  if (prevName !== null) {
@@ -1795,83 +1826,9 @@ function bindDynamic(el, nameGetter, valueGetter) {
1795
1826
  };
1796
1827
  }
1797
1828
 
1798
- // src/reactivity/bindChildNode.ts
1799
- var _isDev4 = isDev();
1800
- function bindChildNode(placeholder, getter) {
1801
- let lastNodes = [];
1802
- function commit() {
1803
- let result;
1804
- try {
1805
- result = getter();
1806
- } catch (err) {
1807
- if (_isDev4) devWarn(`bindChildNode: getter threw: ${err instanceof Error ? err.message : String(err)}`);
1808
- return;
1809
- }
1810
- if (result == null || typeof result === "boolean") {
1811
- for (let i2 = 0; i2 < lastNodes.length; i2++) {
1812
- const node = lastNodes[i2];
1813
- if (node.parentNode) node.parentNode.removeChild(node);
1814
- }
1815
- lastNodes.length = 0;
1816
- return;
1817
- }
1818
- const parent = placeholder.parentNode;
1819
- if (!parent) {
1820
- lastNodes.length = 0;
1821
- return;
1822
- }
1823
- let newNodes;
1824
- if (Array.isArray(result)) {
1825
- newNodes = [];
1826
- const seen = /* @__PURE__ */ new Set();
1827
- for (let i2 = 0; i2 < result.length; i2++) {
1828
- const item = result[i2];
1829
- if (item == null || typeof item === "boolean") continue;
1830
- const node = item instanceof Node ? item : document.createTextNode(String(item));
1831
- if (seen.has(node)) {
1832
- if (_isDev4)
1833
- devWarn("bindChildNode: duplicate node reference in array \u2014 only the first occurrence is rendered.");
1834
- continue;
1835
- }
1836
- seen.add(node);
1837
- newNodes.push(node);
1838
- }
1839
- } else {
1840
- const node = result instanceof Node ? result : document.createTextNode(String(result));
1841
- newNodes = [node];
1842
- }
1843
- let reused;
1844
- if (lastNodes.length > 0 && newNodes.length > 0) {
1845
- const lastSet = new Set(lastNodes);
1846
- reused = /* @__PURE__ */ new Set();
1847
- for (let i2 = 0; i2 < newNodes.length; i2++) {
1848
- if (lastSet.has(newNodes[i2])) reused.add(newNodes[i2]);
1849
- }
1850
- }
1851
- for (let i2 = 0; i2 < lastNodes.length; i2++) {
1852
- const node = lastNodes[i2];
1853
- if (reused?.has(node)) continue;
1854
- if (node.parentNode) node.parentNode.removeChild(node);
1855
- }
1856
- const anchor = placeholder.nextSibling;
1857
- for (let i2 = 0; i2 < newNodes.length; i2++) {
1858
- const node = newNodes[i2];
1859
- if (reused?.has(node) && node.parentNode === parent) {
1860
- if (node.nextSibling !== anchor) {
1861
- parent.insertBefore(node, anchor);
1862
- }
1863
- } else {
1864
- parent.insertBefore(node, anchor);
1865
- }
1866
- }
1867
- lastNodes = newNodes;
1868
- }
1869
- return track(commit);
1870
- }
1871
-
1872
1829
  // src/core/rendering/dispose.ts
1873
1830
  var elementDisposers = /* @__PURE__ */ new WeakMap();
1874
- var _isDev5 = isDev();
1831
+ var _isDev4 = isDev();
1875
1832
  var activeBindingCount = 0;
1876
1833
  function registerDisposer(node, teardown) {
1877
1834
  let disposers = elementDisposers.get(node);
@@ -1880,7 +1837,7 @@ function registerDisposer(node, teardown) {
1880
1837
  elementDisposers.set(node, disposers);
1881
1838
  }
1882
1839
  disposers.push(teardown);
1883
- if (_isDev5) activeBindingCount++;
1840
+ if (_isDev4) activeBindingCount++;
1884
1841
  }
1885
1842
  function dispose(node) {
1886
1843
  const stack = [node];
@@ -1899,12 +1856,12 @@ function dispose(node) {
1899
1856
  if (disposers) {
1900
1857
  const snapshot = disposers.slice();
1901
1858
  elementDisposers.delete(current);
1902
- if (_isDev5) activeBindingCount -= snapshot.length;
1859
+ if (_isDev4) activeBindingCount -= snapshot.length;
1903
1860
  for (const d of snapshot) {
1904
1861
  try {
1905
1862
  d();
1906
1863
  } catch (err) {
1907
- if (_isDev5 && typeof console !== "undefined") {
1864
+ if (_isDev4 && typeof console !== "undefined") {
1908
1865
  console.warn("[SibuJS] Disposer threw during cleanup:", err);
1909
1866
  }
1910
1867
  }
@@ -1915,12 +1872,12 @@ function dispose(node) {
1915
1872
  if (!added || added.length === 0) break;
1916
1873
  const moreSnapshot = added.slice();
1917
1874
  elementDisposers.delete(current);
1918
- if (_isDev5) activeBindingCount -= moreSnapshot.length;
1875
+ if (_isDev4) activeBindingCount -= moreSnapshot.length;
1919
1876
  for (const d of moreSnapshot) {
1920
1877
  try {
1921
1878
  d();
1922
1879
  } catch (err) {
1923
- if (_isDev5 && typeof console !== "undefined") {
1880
+ if (_isDev4 && typeof console !== "undefined") {
1924
1881
  console.warn("[SibuJS] Disposer threw during cleanup:", err);
1925
1882
  }
1926
1883
  }
@@ -1930,7 +1887,7 @@ function dispose(node) {
1930
1887
  }
1931
1888
  }
1932
1889
  function checkLeaks(warnThreshold = 0) {
1933
- if (!_isDev5) return 0;
1890
+ if (!_isDev4) return 0;
1934
1891
  if (warnThreshold > 0 && activeBindingCount > warnThreshold) {
1935
1892
  devWarn(
1936
1893
  `checkLeaks: ${activeBindingCount} active DOM bindings detected. Expected \u2264${warnThreshold}. This may indicate a component was removed from the DOM without calling dispose().`
@@ -1939,6 +1896,79 @@ function checkLeaks(warnThreshold = 0) {
1939
1896
  return activeBindingCount;
1940
1897
  }
1941
1898
 
1899
+ // src/reactivity/bindChildNode.ts
1900
+ var _isDev5 = isDev();
1901
+ function bindChildNode(placeholder, getter) {
1902
+ let lastNodes = [];
1903
+ function commit() {
1904
+ let result;
1905
+ try {
1906
+ result = getter();
1907
+ } catch (err) {
1908
+ if (_isDev5) devWarn(`bindChildNode: getter threw: ${err instanceof Error ? err.message : String(err)}`);
1909
+ return;
1910
+ }
1911
+ if (result == null || typeof result === "boolean") {
1912
+ for (let i2 = 0; i2 < lastNodes.length; i2++) {
1913
+ const node = lastNodes[i2];
1914
+ dispose(node);
1915
+ if (node.parentNode) node.parentNode.removeChild(node);
1916
+ }
1917
+ lastNodes.length = 0;
1918
+ return;
1919
+ }
1920
+ const parent = placeholder.parentNode;
1921
+ if (!parent) {
1922
+ lastNodes.length = 0;
1923
+ return;
1924
+ }
1925
+ let newNodes;
1926
+ if (Array.isArray(result)) {
1927
+ newNodes = [];
1928
+ const seen = /* @__PURE__ */ new Set();
1929
+ for (let i2 = 0; i2 < result.length; i2++) {
1930
+ const item = result[i2];
1931
+ if (item == null || typeof item === "boolean") continue;
1932
+ const node = item instanceof Node ? item : document.createTextNode(String(item));
1933
+ if (seen.has(node)) {
1934
+ if (_isDev5)
1935
+ devWarn("bindChildNode: duplicate node reference in array \u2014 only the first occurrence is rendered.");
1936
+ continue;
1937
+ }
1938
+ seen.add(node);
1939
+ newNodes.push(node);
1940
+ }
1941
+ } else {
1942
+ const node = result instanceof Node ? result : document.createTextNode(String(result));
1943
+ newNodes = [node];
1944
+ }
1945
+ let reused;
1946
+ if (lastNodes.length > 0 && newNodes.length > 0) {
1947
+ const lastSet = new Set(lastNodes);
1948
+ reused = /* @__PURE__ */ new Set();
1949
+ for (let i2 = 0; i2 < newNodes.length; i2++) {
1950
+ if (lastSet.has(newNodes[i2])) reused.add(newNodes[i2]);
1951
+ }
1952
+ }
1953
+ for (let i2 = 0; i2 < lastNodes.length; i2++) {
1954
+ const node = lastNodes[i2];
1955
+ if (reused?.has(node)) continue;
1956
+ dispose(node);
1957
+ if (node.parentNode) node.parentNode.removeChild(node);
1958
+ }
1959
+ let prev = placeholder;
1960
+ for (let i2 = 0; i2 < newNodes.length; i2++) {
1961
+ const node = newNodes[i2];
1962
+ if (prev.nextSibling !== node) {
1963
+ parent.insertBefore(node, prev.nextSibling);
1964
+ }
1965
+ prev = node;
1966
+ }
1967
+ lastNodes = newNodes;
1968
+ }
1969
+ return reactiveBinding(commit);
1970
+ }
1971
+
1942
1972
  // src/core/rendering/tagFactory.ts
1943
1973
  var SVG_NS = "http://www.w3.org/2000/svg";
1944
1974
  var _isDev6 = isDev();
@@ -1965,6 +1995,18 @@ var CLOBBER_RISKY_IDS = /* @__PURE__ */ new Set([
1965
1995
  function setProp2(el, key, val) {
1966
1996
  el[key] = val;
1967
1997
  }
1998
+ function looksLikeClassList(s2) {
1999
+ const t = s2.trim();
2000
+ if (!t) return false;
2001
+ const tokens = t.split(/\s+/);
2002
+ let sawClassish = false;
2003
+ for (let i2 = 0; i2 < tokens.length; i2++) {
2004
+ const tok = tokens[i2];
2005
+ if (!/^-?[A-Za-z_][A-Za-z0-9_:/.-]*$/.test(tok)) return false;
2006
+ if (/[-:/0-9]/.test(tok)) sawClassish = true;
2007
+ }
2008
+ return sawClassish;
2009
+ }
1968
2010
  var kebabCache = /* @__PURE__ */ new Map();
1969
2011
  function toKebab(prop) {
1970
2012
  let cached = kebabCache.get(prop);
@@ -2100,6 +2142,11 @@ var tagFactory = (tag, ns) => {
2100
2142
  appendChildren(el, second);
2101
2143
  return el;
2102
2144
  }
2145
+ if (_isDev6 && looksLikeClassList(first)) {
2146
+ devWarn(
2147
+ `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.`
2148
+ );
2149
+ }
2103
2150
  el.textContent = first;
2104
2151
  return el;
2105
2152
  }
@@ -2157,7 +2204,7 @@ var tagFactory = (tag, ns) => {
2157
2204
  const value = props[key];
2158
2205
  if (value == null) continue;
2159
2206
  const lkey = key.toLowerCase();
2160
- if (lkey[0] === "o" && lkey[1] === "n") continue;
2207
+ if (isEventHandlerAttr(key)) continue;
2161
2208
  if (typeof value === "function") {
2162
2209
  registerDisposer(el, bindAttribute(el, key, value));
2163
2210
  } else if (typeof value === "boolean") {
@@ -2438,14 +2485,28 @@ function parseTemplate(strings) {
2438
2485
  }
2439
2486
  return { kind: "mixed", statics, exprs };
2440
2487
  }
2441
- const valStart = pos;
2442
- while (pos < len) {
2443
- const c = template2.charCodeAt(pos);
2444
- if (c === 32 || c === 9 || c === 10 || c === 13 || c === 62 || c === 47) break;
2445
- pos++;
2488
+ {
2489
+ const statics = [];
2490
+ const exprs = [];
2491
+ let current = "";
2492
+ while (pos < len) {
2493
+ const c = template2.charCodeAt(pos);
2494
+ if (c === 32 || c === 9 || c === 10 || c === 13 || c === 62) break;
2495
+ const innerIdx = tryExprIdx();
2496
+ if (innerIdx >= 0) {
2497
+ statics.push(current);
2498
+ current = "";
2499
+ exprs.push(innerIdx);
2500
+ } else {
2501
+ current += template2[pos++];
2502
+ }
2503
+ }
2504
+ statics.push(current);
2505
+ if (exprs.length === 0) {
2506
+ return { kind: "static", value: statics[0] };
2507
+ }
2508
+ return { kind: "mixed", statics, exprs };
2446
2509
  }
2447
- const val = template2.slice(valStart, pos);
2448
- return { kind: "static", value: val };
2449
2510
  }
2450
2511
  function parseAttrs() {
2451
2512
  const attrs = [];
@@ -2502,6 +2563,30 @@ function parseTemplate(strings) {
2502
2563
  while (pos < len) {
2503
2564
  if (template2[pos] === "<" && pos + 1 < len && template2[pos + 1] === "/") break;
2504
2565
  if (template2[pos] === "<") {
2566
+ const next = template2[pos + 1];
2567
+ if (next === "!") {
2568
+ if (template2.startsWith("<!--", pos)) {
2569
+ const end = template2.indexOf("-->", pos + 4);
2570
+ pos = end === -1 ? len : end + 3;
2571
+ } else if (template2.startsWith("<![CDATA[", pos)) {
2572
+ const end = template2.indexOf("]]>", pos + 9);
2573
+ pos = end === -1 ? len : end + 3;
2574
+ } else {
2575
+ const end = template2.indexOf(">", pos);
2576
+ pos = end === -1 ? len : end + 1;
2577
+ }
2578
+ continue;
2579
+ }
2580
+ if (next === "?") {
2581
+ const end = template2.indexOf(">", pos);
2582
+ pos = end === -1 ? len : end + 1;
2583
+ continue;
2584
+ }
2585
+ if (!(next >= "a" && next <= "z") && !(next >= "A" && next <= "Z")) {
2586
+ children.push({ t: 1, value: "<" });
2587
+ pos++;
2588
+ continue;
2589
+ }
2505
2590
  pos++;
2506
2591
  const tag = readTagName();
2507
2592
  const attrs = parseAttrs();
@@ -2550,7 +2635,7 @@ function executeElement(tmpl, values) {
2550
2635
  case 1: {
2551
2636
  const name = attr.name;
2552
2637
  const lname = name.toLowerCase();
2553
- if (lname[0] === "o" && lname[1] === "n") break;
2638
+ if (isEventHandlerAttr(name)) break;
2554
2639
  const val = values[attr.idx];
2555
2640
  if (typeof val === "function") {
2556
2641
  registerDisposer(el, bindAttribute(el, name, val));
@@ -2799,6 +2884,11 @@ function each(getArray, render, options) {
2799
2884
  workMap.clear();
2800
2885
  keyIndexMap.clear();
2801
2886
  for (let i2 = 0; i2 < newLen; i2++) {
2887
+ if (_isDev8 && keyIndexMap.has(newKeys[i2])) {
2888
+ devWarn(
2889
+ `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.`
2890
+ );
2891
+ }
2802
2892
  keyIndexMap.set(newKeys[i2], i2);
2803
2893
  }
2804
2894
  for (let i2 = 0; i2 < newLen; i2++) {
@@ -3030,7 +3120,7 @@ function show(condition, element) {
3030
3120
  const update = () => {
3031
3121
  element.style.display = condition() ? "" : "none";
3032
3122
  };
3033
- track(update);
3123
+ registerDisposer(element, track(update));
3034
3124
  return element;
3035
3125
  }
3036
3126
  function when(condition, thenBranch, elseBranch) {
@@ -3057,7 +3147,7 @@ function when(condition, thenBranch, elseBranch) {
3057
3147
  }
3058
3148
  initialized = true;
3059
3149
  };
3060
- track(update);
3150
+ registerDisposer(anchor, track(update));
3061
3151
  if (!initialized) {
3062
3152
  queueMicrotask(() => {
3063
3153
  if (!initialized && anchor.parentNode) update();
@@ -3092,7 +3182,7 @@ function match(value, cases, fallback) {
3092
3182
  }
3093
3183
  initialized = true;
3094
3184
  };
3095
- track(update);
3185
+ registerDisposer(anchor, track(update));
3096
3186
  if (!initialized) {
3097
3187
  queueMicrotask(() => {
3098
3188
  if (!initialized && anchor.parentNode) update();
@@ -3133,6 +3223,12 @@ function KeepAlive(activeKey, cases, options) {
3133
3223
  return;
3134
3224
  }
3135
3225
  node = factory();
3226
+ if (node instanceof DocumentFragment) {
3227
+ const wrapper = document.createElement("div");
3228
+ wrapper.style.display = "contents";
3229
+ wrapper.appendChild(node);
3230
+ node = wrapper;
3231
+ }
3136
3232
  cache2.set(key, node);
3137
3233
  lruOrder.push(key);
3138
3234
  if (max > 0 && lruOrder.length > max) {
@@ -3417,11 +3513,15 @@ function signal(initial, options) {
3417
3513
  var als = null;
3418
3514
  try {
3419
3515
  if (typeof process !== "undefined" && process.versions && process.versions.node) {
3420
- const req = Function("return typeof require==='function'?require:null")();
3421
- if (req) {
3422
- const mod = req("node:async_hooks");
3423
- als = new mod.AsyncLocalStorage();
3516
+ let mod = null;
3517
+ const getBuiltin = process.getBuiltinModule;
3518
+ if (typeof getBuiltin === "function") {
3519
+ mod = getBuiltin("node:async_hooks");
3520
+ } else {
3521
+ const req = Function("return typeof require==='function'?require:null")();
3522
+ if (req) mod = req("node:async_hooks");
3424
3523
  }
3524
+ if (mod) als = new mod.AsyncLocalStorage();
3425
3525
  }
3426
3526
  } catch {
3427
3527
  als = null;
@@ -3437,6 +3537,17 @@ function getSSRStore() {
3437
3537
  function isSSR() {
3438
3538
  return getSSRStore().ssr;
3439
3539
  }
3540
+ function getRequestScopedCache(name) {
3541
+ if (!isSSR()) return null;
3542
+ const store2 = getSSRStore();
3543
+ const caches = store2.caches ?? (store2.caches = /* @__PURE__ */ new Map());
3544
+ let c = caches.get(name);
3545
+ if (!c) {
3546
+ c = /* @__PURE__ */ new Map();
3547
+ caches.set(name, c);
3548
+ }
3549
+ return c;
3550
+ }
3440
3551
  function enableSSR() {
3441
3552
  getSSRStore().ssr = true;
3442
3553
  }
@@ -3571,6 +3682,7 @@ function effect(effectFn, options) {
3571
3682
  ctx.fn(ctx.onCleanup);
3572
3683
  };
3573
3684
  const sub2 = (() => {
3685
+ if (ctx.disposed) return;
3574
3686
  if (ctx.running) {
3575
3687
  ctx.rerunPending = true;
3576
3688
  return;
@@ -3613,6 +3725,7 @@ function derived(getter, options) {
3613
3725
  const equals = options?.equals;
3614
3726
  const cs = {};
3615
3727
  cs._d = false;
3728
+ cs._init = false;
3616
3729
  cs._g = getter;
3617
3730
  cs.__v = 0;
3618
3731
  const markDirty = () => {
@@ -3621,11 +3734,18 @@ function derived(getter, options) {
3621
3734
  };
3622
3735
  markDirty._c = 1;
3623
3736
  markDirty._sig = cs;
3737
+ const recompute = () => {
3738
+ const next = getter();
3739
+ cs._v = equals && cs._init ? equals(cs._v, next) ? cs._v : next : next;
3740
+ cs._d = false;
3741
+ cs._init = true;
3742
+ };
3624
3743
  track(() => {
3625
3744
  let threw = true;
3626
3745
  try {
3627
3746
  cs._v = getter();
3628
3747
  cs._d = false;
3748
+ cs._init = true;
3629
3749
  threw = false;
3630
3750
  } finally {
3631
3751
  if (threw) cs._d = true;
@@ -3641,20 +3761,13 @@ function derived(getter, options) {
3641
3761
  }
3642
3762
  if (trackingSuspended) {
3643
3763
  if (cs._d) {
3764
+ const prev = cs._v;
3644
3765
  evaluating = true;
3645
- let threw = true;
3646
3766
  try {
3647
- const prev = cs._v;
3648
- retrack(() => {
3649
- const next = getter();
3650
- cs._v = equals && cs._v !== void 0 ? equals(cs._v, next) ? cs._v : next : next;
3651
- cs._d = false;
3652
- threw = false;
3653
- }, markDirty);
3767
+ retrack(recompute, markDirty);
3654
3768
  if (!Object.is(prev, cs._v)) cs.__v++;
3655
3769
  } finally {
3656
3770
  evaluating = false;
3657
- if (threw) cs._d = true;
3658
3771
  }
3659
3772
  }
3660
3773
  return cs._v;
@@ -3663,18 +3776,11 @@ function derived(getter, options) {
3663
3776
  if (cs._d) {
3664
3777
  const oldValue = cs._v;
3665
3778
  evaluating = true;
3666
- let threw = true;
3667
3779
  try {
3668
- retrack(() => {
3669
- const next = getter();
3670
- cs._v = equals && cs._v !== void 0 ? equals(cs._v, next) ? cs._v : next : next;
3671
- cs._d = false;
3672
- threw = false;
3673
- }, markDirty);
3780
+ retrack(recompute, markDirty);
3674
3781
  if (!Object.is(oldValue, cs._v)) cs.__v++;
3675
3782
  } finally {
3676
3783
  evaluating = false;
3677
- if (threw) cs._d = true;
3678
3784
  }
3679
3785
  if (hook && oldValue !== cs._v) {
3680
3786
  hook.emit("computed:update", { signal: cs, oldValue, newValue: cs._v });
@@ -3727,12 +3833,12 @@ function store(initialState) {
3727
3833
  signals[key] = [getter, setter];
3728
3834
  });
3729
3835
  const store2 = new Proxy({}, {
3730
- get(_, prop) {
3731
- if (prop in signals) {
3836
+ get(target, prop) {
3837
+ if (typeof prop === "string" && Object.hasOwn(signals, prop)) {
3732
3838
  const getter = signals[prop][0];
3733
3839
  return getter();
3734
3840
  }
3735
- return void 0;
3841
+ return Reflect.get(target, prop);
3736
3842
  },
3737
3843
  set() {
3738
3844
  throw new Error(
@@ -3752,7 +3858,7 @@ function store(initialState) {
3752
3858
  const nextState = typeof patch === "function" ? patch(current) : patch;
3753
3859
  batch(() => {
3754
3860
  Object.entries(nextState).forEach(([key, value]) => {
3755
- if (key in signals) {
3861
+ if (Object.hasOwn(signals, key)) {
3756
3862
  signals[key][1](value);
3757
3863
  }
3758
3864
  });
@@ -4050,6 +4156,14 @@ function deepEqual(a2, b2, seen) {
4050
4156
  }
4051
4157
  return true;
4052
4158
  }
4159
+ if (a2 instanceof DataView) {
4160
+ if (!(b2 instanceof DataView)) return false;
4161
+ if (a2.byteLength !== b2.byteLength) return false;
4162
+ for (let i2 = 0; i2 < a2.byteLength; i2++) {
4163
+ if (a2.getUint8(i2) !== b2.getUint8(i2)) return false;
4164
+ }
4165
+ return true;
4166
+ }
4053
4167
  if (ArrayBuffer.isView(a2) && ArrayBuffer.isView(b2)) {
4054
4168
  const ta = a2;
4055
4169
  const tb = b2;
@@ -4068,7 +4182,7 @@ function deepEqual(a2, b2, seen) {
4068
4182
  const keysB = Object.keys(objB);
4069
4183
  if (keysA.length !== keysB.length) return false;
4070
4184
  return keysA.every(
4071
- (key) => deepEqual(objA[key], objB[key], seen)
4185
+ (key) => Object.hasOwn(objB, key) && deepEqual(objA[key], objB[key], seen)
4072
4186
  );
4073
4187
  }
4074
4188
  function deepSignal(initial) {
@@ -4571,34 +4685,37 @@ function Suspense({ nodes, fallback }) {
4571
4685
  container.appendChild(fallbackEl);
4572
4686
  let suspenseDisposed = false;
4573
4687
  let observer = null;
4688
+ let childEl = null;
4574
4689
  registerDisposer(container, () => {
4575
4690
  suspenseDisposed = true;
4576
4691
  if (observer) {
4577
4692
  observer.disconnect();
4578
4693
  observer = null;
4579
4694
  }
4695
+ if (childEl && !container.contains(childEl)) dispose(childEl);
4580
4696
  });
4581
4697
  queueMicrotask(() => {
4582
4698
  if (suspenseDisposed) return;
4583
4699
  try {
4584
- const childEl = nodes();
4585
- if (childEl.classList.contains("sibu-lazy")) {
4586
- if (!childEl.querySelector(".sibu-lazy-loading")) {
4587
- container.replaceChildren(childEl);
4700
+ const el = nodes();
4701
+ childEl = el;
4702
+ if (el.classList.contains("sibu-lazy")) {
4703
+ if (!el.querySelector(".sibu-lazy-loading")) {
4704
+ container.replaceChildren(el);
4588
4705
  return;
4589
4706
  }
4590
4707
  observer = new MutationObserver(() => {
4591
4708
  if (suspenseDisposed) return;
4592
- const loading = childEl.querySelector(".sibu-lazy-loading");
4709
+ const loading = el.querySelector(".sibu-lazy-loading");
4593
4710
  if (!loading) {
4594
4711
  observer?.disconnect();
4595
4712
  observer = null;
4596
- container.replaceChildren(childEl);
4713
+ container.replaceChildren(el);
4597
4714
  }
4598
4715
  });
4599
- observer.observe(childEl, { childList: true, subtree: true });
4716
+ observer.observe(el, { childList: true, subtree: true });
4600
4717
  } else {
4601
- container.replaceChildren(childEl);
4718
+ container.replaceChildren(el);
4602
4719
  }
4603
4720
  } catch (err) {
4604
4721
  const errorObj = err instanceof Error ? err : new Error(String(err));
@@ -5882,25 +5999,34 @@ var lintRules = {
5882
5999
  let braceDepth = 0;
5883
6000
  let insideConditionalOrLoop = false;
5884
6001
  let insideNestedFunction = false;
5885
- let functionDepth = 0;
6002
+ const fnOpenDepths = [];
5886
6003
  for (let i2 = 0; i2 <= lineIdx; i2++) {
5887
- const scanLine = lines[i2].trim();
5888
- if (/\b(function\s+\w+|function\s*\(|=>\s*\{)/.test(scanLine) && i2 < lineIdx) {
5889
- functionDepth++;
5890
- }
5891
- if (i2 < lineIdx && /^\s*(if|else\s+if|else|for|while|do|switch)\s*[({]/.test(lines[i2])) {
6004
+ const rawLine = lines[i2];
6005
+ const scanLine = rawLine.trim();
6006
+ const opensFunction = i2 < lineIdx && /\b(function\s+\w+|function\s*\(|=>\s*\{)/.test(scanLine);
6007
+ if (i2 < lineIdx && /^\s*(if|else\s+if|else|for|while|do|switch)\s*[({]/.test(rawLine)) {
5892
6008
  insideConditionalOrLoop = true;
5893
6009
  }
5894
- for (const ch of lines[i2]) {
5895
- if (ch === "{") braceDepth++;
5896
- if (ch === "}") {
6010
+ let fnBracePending = opensFunction;
6011
+ for (const ch of rawLine) {
6012
+ if (ch === "{") {
6013
+ braceDepth++;
6014
+ if (fnBracePending) {
6015
+ fnOpenDepths.push(braceDepth);
6016
+ fnBracePending = false;
6017
+ }
6018
+ } else if (ch === "}") {
5897
6019
  braceDepth--;
6020
+ while (fnOpenDepths.length > 0 && fnOpenDepths[fnOpenDepths.length - 1] > braceDepth) {
6021
+ fnOpenDepths.pop();
6022
+ }
5898
6023
  if (braceDepth <= 1) {
5899
6024
  insideConditionalOrLoop = false;
5900
6025
  }
5901
6026
  }
5902
6027
  }
5903
6028
  }
6029
+ const functionDepth = fnOpenDepths.length;
5904
6030
  const beforeHook = line2.substring(0, line2.indexOf(hookMatch[0]));
5905
6031
  const inlineConditional = /\b(if|else|for|while|switch)\s*\(/.test(beforeHook) || /\?\s*$/.test(beforeHook.trim());
5906
6032
  if (insideConditionalOrLoop || inlineConditional) {