sibujs 4.6.0 → 4.8.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 (94) hide show
  1. package/README.md +1 -1
  2. package/dist/browser.cjs +62 -8
  3. package/dist/browser.d.cts +23 -0
  4. package/dist/browser.d.ts +23 -0
  5. package/dist/browser.js +6 -5
  6. package/dist/build.cjs +2388 -1004
  7. package/dist/build.d.cts +147 -44
  8. package/dist/build.d.ts +147 -44
  9. package/dist/build.js +1410 -564
  10. package/dist/cdn.dev.global.js +14 -12
  11. package/dist/cdn.full.dev.global.js +15 -13
  12. package/dist/cdn.full.global.js +14 -12
  13. package/dist/cdn.global.js +12 -10
  14. package/dist/chunk-3ACAAQIN.js +224 -0
  15. package/dist/{chunk-7NCARGJW.js → chunk-44MTL7ED.js} +6 -6
  16. package/dist/{chunk-BAAG6ZTI.js → chunk-4WMSTZ7J.js} +8 -5
  17. package/dist/{chunk-H3SRKIYX.js → chunk-62BDYGAG.js} +8 -0
  18. package/dist/{chunk-DKGBBKOF.js → chunk-C5PEWEGH.js} +20 -5
  19. package/dist/{chunk-3ISI6ACU.js → chunk-C7AA2CZX.js} +1 -1
  20. package/dist/{chunk-UZQ6ALFS.js → chunk-CZPRSWSS.js} +1 -1
  21. package/dist/{chunk-D33YTSX5.js → chunk-DSID757X.js} +5 -4
  22. package/dist/{chunk-OXUY2A6L.js → chunk-EGUQLBHE.js} +22 -8
  23. package/dist/{chunk-2INLLLMZ.js → chunk-EXXSN3BW.js} +202 -26
  24. package/dist/{chunk-HURREPU2.js → chunk-FC6KCJSA.js} +87 -150
  25. package/dist/{chunk-HYXDKS4N.js → chunk-GSGNX35Q.js} +5 -5
  26. package/dist/{chunk-7GQCWFOE.js → chunk-J3YQ457H.js} +171 -85
  27. package/dist/{chunk-ORMZXBKQ.js → chunk-JUTFX2RM.js} +18 -10
  28. package/dist/{chunk-QE4TTDU3.js → chunk-KJ3UKABJ.js} +12 -11
  29. package/dist/{chunk-XRRZKZYX.js → chunk-LI4W3U6C.js} +1 -1
  30. package/dist/{chunk-47M47FOM.js → chunk-O6TRVMJI.js} +58 -6
  31. package/dist/{chunk-JSXPZCET.js → chunk-Q5J2LVKH.js} +1 -1
  32. package/dist/{chunk-5MT6SJ3P.js → chunk-QGMSESDD.js} +10 -5
  33. package/dist/{chunk-AIF3Z2T7.js → chunk-RGLPEBDE.js} +13 -10
  34. package/dist/{chunk-5Q4R7HCL.js → chunk-TQQUN4WR.js} +11 -2
  35. package/dist/{chunk-PK6FK2G2.js → chunk-UCNP3HVM.js} +183 -30
  36. package/dist/{chunk-XC4MEKGA.js → chunk-V3LHZSU5.js} +8 -2
  37. package/dist/{chunk-VVWPJ543.js → chunk-VWT3VXPL.js} +55 -20
  38. package/dist/{chunk-SXXVZMKZ.js → chunk-ZVLHNEEL.js} +17 -35
  39. package/dist/{contracts-DRIuclVT.d.cts → contracts-CLqzJnOV.d.ts} +28 -17
  40. package/dist/{contracts-DRIuclVT.d.ts → contracts-CTOJXu-x.d.cts} +28 -17
  41. package/dist/{customElement-MmInOW1U.d.ts → customElement-pYDKUzWl.d.cts} +11 -3
  42. package/dist/{customElement-MmInOW1U.d.cts → customElement-pYDKUzWl.d.ts} +11 -3
  43. package/dist/data.cjs +205 -39
  44. package/dist/data.d.cts +119 -3
  45. package/dist/data.d.ts +119 -3
  46. package/dist/data.js +6 -6
  47. package/dist/devtools.cjs +18 -5
  48. package/dist/devtools.js +5 -5
  49. package/dist/ecosystem.cjs +462 -58
  50. package/dist/ecosystem.d.cts +2 -1
  51. package/dist/ecosystem.d.ts +2 -1
  52. package/dist/ecosystem.js +9 -8
  53. package/dist/extras.cjs +852 -296
  54. package/dist/extras.d.cts +5 -4
  55. package/dist/extras.d.ts +5 -4
  56. package/dist/extras.js +24 -23
  57. package/dist/index.cjs +721 -176
  58. package/dist/index.d.cts +220 -169
  59. package/dist/index.d.ts +220 -169
  60. package/dist/index.js +16 -12
  61. package/dist/motion.cjs +12 -4
  62. package/dist/motion.js +3 -3
  63. package/dist/patterns.cjs +37 -21
  64. package/dist/patterns.d.cts +2 -1
  65. package/dist/patterns.d.ts +2 -1
  66. package/dist/patterns.js +6 -6
  67. package/dist/performance.cjs +48 -6
  68. package/dist/performance.d.cts +12 -2
  69. package/dist/performance.d.ts +12 -2
  70. package/dist/performance.js +8 -6
  71. package/dist/plugins.cjs +672 -261
  72. package/dist/plugins.d.cts +131 -13
  73. package/dist/plugins.d.ts +131 -13
  74. package/dist/plugins.js +83 -47
  75. package/dist/{ssr-XOTUASDO.js → ssr-5OWAH3U2.js} +4 -2
  76. package/dist/{ssr-Bli9XRW5.d.cts → ssr-C8hgIAw7.d.cts} +6 -0
  77. package/dist/{ssr-Bli9XRW5.d.ts → ssr-C8hgIAw7.d.ts} +6 -0
  78. package/dist/ssr.cjs +509 -142
  79. package/dist/ssr.d.cts +55 -5
  80. package/dist/ssr.d.ts +55 -5
  81. package/dist/ssr.js +11 -9
  82. package/dist/{tagFactory-DFstCLQV.d.cts → tagFactory-8qL9LCIx.d.cts} +58 -19
  83. package/dist/{tagFactory-DkaNVUNV.d.ts → tagFactory-BL2fymez.d.ts} +58 -19
  84. package/dist/testing.cjs +17 -4
  85. package/dist/testing.js +4 -4
  86. package/dist/types-CJFViL6Q.d.cts +26 -0
  87. package/dist/types-CJFViL6Q.d.ts +26 -0
  88. package/dist/ui.cjs +635 -254
  89. package/dist/ui.d.cts +3 -2
  90. package/dist/ui.d.ts +3 -2
  91. package/dist/ui.js +9 -8
  92. package/dist/widgets.cjs +22 -14
  93. package/dist/widgets.js +7 -7
  94. package/package.json +8 -5
@@ -135,40 +135,44 @@ import {
135
135
  use,
136
136
  var_,
137
137
  video
138
- } from "./chunk-JSXPZCET.js";
138
+ } from "./chunk-Q5J2LVKH.js";
139
139
  import {
140
140
  trustHTML
141
- } from "./chunk-HURREPU2.js";
141
+ } from "./chunk-FC6KCJSA.js";
142
142
  import {
143
143
  watch
144
- } from "./chunk-UZQ6ALFS.js";
144
+ } from "./chunk-CZPRSWSS.js";
145
145
  import {
146
146
  __resetIdCounter,
147
147
  createId,
148
148
  domBinding
149
- } from "./chunk-3ISI6ACU.js";
149
+ } from "./chunk-C7AA2CZX.js";
150
150
  import {
151
151
  SVG_NS,
152
152
  bindChildNode,
153
153
  captureFocusWithin,
154
154
  restoreFocusWithin,
155
155
  tagFactory
156
- } from "./chunk-VVWPJ543.js";
156
+ } from "./chunk-VWT3VXPL.js";
157
157
  import {
158
158
  bindAttribute,
159
159
  bindDynamic,
160
- setSafeAttribute
161
- } from "./chunk-47M47FOM.js";
160
+ setSafeAttribute,
161
+ setTrustedAttribute
162
+ } from "./chunk-O6TRVMJI.js";
163
+ import {
164
+ isCodeTextElement
165
+ } from "./chunk-3ACAAQIN.js";
162
166
  import {
163
167
  derived
164
- } from "./chunk-QE4TTDU3.js";
168
+ } from "./chunk-KJ3UKABJ.js";
165
169
  import {
166
170
  globalSingleton
167
171
  } from "./chunk-7ZHH77QA.js";
168
172
  import {
169
173
  effect,
170
174
  on
171
- } from "./chunk-XC4MEKGA.js";
175
+ } from "./chunk-V3LHZSU5.js";
172
176
  import {
173
177
  disableSSR,
174
178
  enableSSR,
@@ -187,8 +191,9 @@ import {
187
191
  external,
188
192
  isBatching,
189
193
  signal
190
- } from "./chunk-D33YTSX5.js";
194
+ } from "./chunk-DSID757X.js";
191
195
  import {
196
+ emitDevtools,
192
197
  notifySubscribers,
193
198
  reactiveBinding,
194
199
  recordDependency,
@@ -198,7 +203,7 @@ import {
198
203
  suspendTracking,
199
204
  track,
200
205
  untracked
201
- } from "./chunk-5Q4R7HCL.js";
206
+ } from "./chunk-TQQUN4WR.js";
202
207
  import {
203
208
  DEV,
204
209
  MAX_DRAIN_TEARDOWNS,
@@ -216,7 +221,8 @@ import {
216
221
  reportDrainRunaway,
217
222
  reportError,
218
223
  setRuntimeErrorHandler,
219
- unregisterDisposer
224
+ unregisterDisposer,
225
+ withDisposerRollback
220
226
  } from "./chunk-NYNYSPK7.js";
221
227
 
222
228
  // index.ts
@@ -232,6 +238,7 @@ __export(index_exports, {
232
238
  Portal: () => Portal,
233
239
  SVG_NS: () => SVG_NS,
234
240
  Suspense: () => Suspense,
241
+ __renderParsedTemplate: () => __renderParsedTemplate,
235
242
  __resetIdCounter: () => __resetIdCounter,
236
243
  a: () => a,
237
244
  abbr: () => abbr,
@@ -557,10 +564,13 @@ function safeCall(cb, hookName) {
557
564
  return void 0;
558
565
  }
559
566
  }
560
- function runMountCallback(callback, hookName, element) {
567
+ function runMountCallback(callback, hookName, element, isDisposed) {
561
568
  const cleanup = safeCall(callback, hookName);
562
- if (typeof cleanup === "function" && element) {
563
- registerDisposer(element, cleanup);
569
+ if (typeof cleanup !== "function") return;
570
+ if (isDisposed() || !element.isConnected) {
571
+ safeCall(cleanup, "onUnmount");
572
+ } else {
573
+ onUnmount(cleanup, element);
564
574
  }
565
575
  }
566
576
  var mountWatchers = /* @__PURE__ */ new WeakMap();
@@ -722,25 +732,26 @@ function onMount(callback, element) {
722
732
  if (typeof document === "undefined") return;
723
733
  if (element) {
724
734
  let disposed = false;
735
+ const isDisposed = () => disposed;
725
736
  registerDisposer(element, () => {
726
737
  disposed = true;
727
738
  });
728
739
  if (element.isConnected) {
729
740
  queueMicrotask(() => {
730
741
  if (disposed) return;
731
- runMountCallback(callback, "onMount", element);
742
+ runMountCallback(callback, "onMount", element, isDisposed);
732
743
  });
733
744
  return;
734
745
  }
735
746
  queueMicrotask(() => {
736
747
  if (disposed) return;
737
748
  if (element.isConnected) {
738
- runMountCallback(callback, "onMount", element);
749
+ runMountCallback(callback, "onMount", element, isDisposed);
739
750
  return;
740
751
  }
741
752
  const unregister = registerMountWatcher(element, () => {
742
753
  if (disposed) return;
743
- runMountCallback(callback, "onMount", element);
754
+ runMountCallback(callback, "onMount", element, isDisposed);
744
755
  });
745
756
  registerDisposer(element, unregister);
746
757
  });
@@ -1574,36 +1585,34 @@ function Loading(props = {}) {
1574
1585
  const { text: text2, variant = "spinner", size = "md" } = props;
1575
1586
  const sizeClass = size !== "md" ? ` sibu-loading-${size}` : "";
1576
1587
  if (variant === "dots") {
1577
- return div({
1588
+ return div(
1589
+ {
1590
+ class: `sibu-loading${sizeClass}`,
1591
+ role: "status",
1592
+ "aria-live": "polite",
1593
+ // When there's no visible text, give the live region an accessible name
1594
+ // so it isn't announced as an empty status.
1595
+ "aria-label": text2 ? void 0 : "Loading"
1596
+ },
1597
+ [
1598
+ div({ class: "sibu-loading-dots" }, [
1599
+ span({ class: "sibu-loading-dot" }),
1600
+ span({ class: "sibu-loading-dot" }),
1601
+ span({ class: "sibu-loading-dot" })
1602
+ ]),
1603
+ text2 ? span({ class: "sibu-loading-text" }, text2) : null
1604
+ ]
1605
+ );
1606
+ }
1607
+ return div(
1608
+ {
1578
1609
  class: `sibu-loading${sizeClass}`,
1579
1610
  role: "status",
1580
1611
  "aria-live": "polite",
1581
- // When there's no visible text, give the live region an accessible name
1582
- // so it isn't announced as an empty status.
1583
- "aria-label": text2 ? void 0 : "Loading",
1584
- nodes: [
1585
- div({
1586
- class: "sibu-loading-dots",
1587
- nodes: [
1588
- span({ class: "sibu-loading-dot" }),
1589
- span({ class: "sibu-loading-dot" }),
1590
- span({ class: "sibu-loading-dot" })
1591
- ]
1592
- }),
1593
- text2 ? span({ class: "sibu-loading-text", nodes: text2 }) : null
1594
- ].filter(Boolean)
1595
- });
1596
- }
1597
- return div({
1598
- class: `sibu-loading${sizeClass}`,
1599
- role: "status",
1600
- "aria-live": "polite",
1601
- "aria-label": text2 ? void 0 : "Loading",
1602
- nodes: [
1603
- div({ class: "sibu-loading-spinner" }),
1604
- text2 ? span({ class: "sibu-loading-text", nodes: text2 }) : null
1605
- ].filter(Boolean)
1606
- });
1612
+ "aria-label": text2 ? void 0 : "Loading"
1613
+ },
1614
+ [div({ class: "sibu-loading-spinner" }), text2 ? span({ class: "sibu-loading-text" }, text2) : null]
1615
+ );
1607
1616
  }
1608
1617
 
1609
1618
  // src/core/rendering/action.ts
@@ -1714,8 +1723,9 @@ var globalErrorHandler = null;
1714
1723
  function catchError(fn, onError) {
1715
1724
  try {
1716
1725
  const result = fn();
1717
- if (result && typeof result.then === "function") {
1718
- result.catch((err) => {
1726
+ const adopted = adoptThenable(result);
1727
+ if (adopted) {
1728
+ adopted.then(void 0, (err) => {
1719
1729
  if (onError) {
1720
1730
  onError(err, "async");
1721
1731
  } else if (globalErrorHandler) {
@@ -1826,6 +1836,10 @@ function attachBranch(parent, anchor, branch, attachedOnce, where) {
1826
1836
  parent.insertBefore(node, anchor.nextSibling);
1827
1837
  return { node, owned };
1828
1838
  }
1839
+ function releaseBranchNode(node, owned) {
1840
+ if (owned) dispose(node);
1841
+ node.parentNode?.removeChild(node);
1842
+ }
1829
1843
  function when(condition, thenBranch, elseBranch) {
1830
1844
  const anchor = document.createComment("when");
1831
1845
  let currentNode = null;
@@ -1839,16 +1853,15 @@ function when(condition, thenBranch, elseBranch) {
1839
1853
  const show2 = condition();
1840
1854
  const parent = anchor.parentNode;
1841
1855
  if (!parent) return;
1842
- if (initialized && show2 === lastCondition) return;
1856
+ if (initialized && Object.is(show2, lastCondition)) return;
1843
1857
  lastCondition = show2;
1844
1858
  const focused = currentNode ? captureFocusWithin([currentNode]) : null;
1845
1859
  if (currentNode?.parentNode) {
1846
- if (currentNodeOwned) dispose(currentNode);
1847
- currentNode.parentNode.removeChild(currentNode);
1860
+ releaseBranchNode(currentNode, currentNodeOwned);
1848
1861
  currentNode = null;
1849
1862
  }
1850
1863
  const branch = show2 ? thenBranch : elseBranch !== void 0 ? elseBranch : null;
1851
- const attached = attachBranch(parent, anchor, branch, attachedOnce, "when");
1864
+ const attached = untracked(() => attachBranch(parent, anchor, branch, attachedOnce, "when"));
1852
1865
  currentNode = attached.node;
1853
1866
  currentNodeOwned = attached.owned;
1854
1867
  restoreFocusWithin(focused, currentNode ? [currentNode] : [], "when");
@@ -1858,6 +1871,8 @@ function when(condition, thenBranch, elseBranch) {
1858
1871
  registerDisposer(anchor, () => {
1859
1872
  disposed = true;
1860
1873
  stopBinding();
1874
+ if (currentNode) releaseBranchNode(currentNode, currentNodeOwned);
1875
+ currentNode = null;
1861
1876
  });
1862
1877
  if (!initialized) {
1863
1878
  queueMicrotask(() => {
@@ -1883,12 +1898,11 @@ function match(value, cases, fallback) {
1883
1898
  lastKey = key;
1884
1899
  const focused = currentNode ? captureFocusWithin([currentNode]) : null;
1885
1900
  if (currentNode?.parentNode) {
1886
- if (currentNodeOwned) dispose(currentNode);
1887
- currentNode.parentNode.removeChild(currentNode);
1901
+ releaseBranchNode(currentNode, currentNodeOwned);
1888
1902
  currentNode = null;
1889
1903
  }
1890
1904
  const branch = Object.hasOwn(cases, key) ? cases[key] : fallback;
1891
- const attached = attachBranch(parent, anchor, branch ?? null, attachedOnce, "match");
1905
+ const attached = untracked(() => attachBranch(parent, anchor, branch ?? null, attachedOnce, "match"));
1892
1906
  currentNode = attached.node;
1893
1907
  currentNodeOwned = attached.owned;
1894
1908
  restoreFocusWithin(focused, currentNode ? [currentNode] : [], "match");
@@ -1898,6 +1912,8 @@ function match(value, cases, fallback) {
1898
1912
  registerDisposer(anchor, () => {
1899
1913
  disposed = true;
1900
1914
  stopBinding();
1915
+ if (currentNode) releaseBranchNode(currentNode, currentNodeOwned);
1916
+ currentNode = null;
1901
1917
  });
1902
1918
  if (!initialized) {
1903
1919
  queueMicrotask(() => {
@@ -1912,11 +1928,17 @@ var componentRegistry = globalSingleton(
1912
1928
  /* @__PURE__ */ Symbol.for("sibujs.components.registry.v1"),
1913
1929
  () => /* @__PURE__ */ new Map()
1914
1930
  );
1931
+ var registryVersion = globalSingleton(/* @__PURE__ */ Symbol.for("sibujs.components.registryVersion.v1"), () => signal(0));
1932
+ function bumpRegistry() {
1933
+ const [read, write] = registryVersion;
1934
+ write(untracked(read) + 1);
1935
+ }
1915
1936
  function registerComponent(name, component) {
1916
1937
  componentRegistry.set(name, component);
1938
+ bumpRegistry();
1917
1939
  }
1918
1940
  function unregisterComponent(name) {
1919
- componentRegistry.delete(name);
1941
+ if (componentRegistry.delete(name)) bumpRegistry();
1920
1942
  }
1921
1943
  function resolveComponent(name) {
1922
1944
  const component = componentRegistry.get(name);
@@ -1927,14 +1949,21 @@ function resolveComponent(name) {
1927
1949
  }
1928
1950
  function DynamicComponent(is) {
1929
1951
  const container = div({ class: "sibu-dynamic" });
1952
+ const NONE = {};
1953
+ let shown = NONE;
1930
1954
  function render() {
1931
1955
  const target = is();
1932
- let el;
1956
+ let component;
1933
1957
  if (typeof target === "function") {
1934
- el = target();
1958
+ component = target;
1935
1959
  } else {
1936
- el = resolveComponent(target);
1960
+ registryVersion[0]();
1961
+ component = componentRegistry.get(target);
1937
1962
  }
1963
+ const next = component ?? `missing:${target}`;
1964
+ if (next === shown) return;
1965
+ const el = untracked(() => component ? component() : div(`[Component "${target}" not found]`));
1966
+ shown = next;
1938
1967
  replaceChildrenSafely(container, el);
1939
1968
  }
1940
1969
  const untrack = track(render);
@@ -2198,31 +2227,29 @@ function Fragment(nodes) {
2198
2227
  if (Array.isArray(child)) {
2199
2228
  for (const nested of child) {
2200
2229
  if (nested == null || typeof nested === "boolean") continue;
2201
- frag.appendChild(resolveChild(nested));
2230
+ appendChild(frag, nested);
2202
2231
  }
2203
2232
  } else {
2204
- frag.appendChild(resolveChild(child));
2233
+ appendChild(frag, child);
2205
2234
  }
2206
2235
  }
2207
2236
  return frag;
2208
2237
  }
2209
- function resolveChild(child) {
2210
- if (child == null) {
2211
- return document.createTextNode("");
2212
- }
2238
+ function appendChild(frag, child) {
2213
2239
  if (child instanceof Node) {
2214
- return child;
2240
+ frag.appendChild(child);
2241
+ return;
2215
2242
  }
2216
2243
  if (typeof child === "function") {
2217
- const result = child();
2218
- if (result instanceof Node) return result;
2219
- return document.createTextNode(String(result ?? ""));
2244
+ const placeholder = document.createComment("");
2245
+ frag.appendChild(placeholder);
2246
+ registerDisposer(placeholder, bindChildNode(placeholder, child));
2247
+ return;
2220
2248
  }
2221
- return document.createTextNode(String(child));
2249
+ frag.appendChild(document.createTextNode(String(child)));
2222
2250
  }
2223
2251
 
2224
2252
  // src/core/rendering/htm.ts
2225
- var RAW_TEXT_TAGS = /* @__PURE__ */ new Set(["script", "style"]);
2226
2253
  var VOID_ELEMENTS = /* @__PURE__ */ new Set([
2227
2254
  "area",
2228
2255
  "base",
@@ -2445,7 +2472,7 @@ function parseTemplate(strings) {
2445
2472
  children.push({ t: 0, el: { tag, svg: SVG_TAGS.has(tag), attrs, children: [] } });
2446
2473
  } else {
2447
2474
  const inner = parseChildren();
2448
- if (RAW_TEXT_TAGS.has(tag.toLowerCase())) {
2475
+ if (isCodeTextElement(tag)) {
2449
2476
  for (let i2 = 0; i2 < inner.length; i2++) {
2450
2477
  if (inner[i2].t === 2) {
2451
2478
  throw new Error(
@@ -2476,7 +2503,7 @@ function executeElement(tmpl, values) {
2476
2503
  const attr = tmpl.attrs[i2];
2477
2504
  switch (attr.t) {
2478
2505
  case 0:
2479
- el.setAttribute(attr.name, attr.value);
2506
+ setTrustedAttribute(el, attr.name, attr.value);
2480
2507
  break;
2481
2508
  case 1: {
2482
2509
  const name = attr.name;
@@ -2509,7 +2536,7 @@ function executeElement(tmpl, values) {
2509
2536
  break;
2510
2537
  }
2511
2538
  case 4:
2512
- el.setAttribute(attr.name, "");
2539
+ setTrustedAttribute(el, attr.name, "");
2513
2540
  break;
2514
2541
  }
2515
2542
  }
@@ -2554,6 +2581,12 @@ function html(strings, ...values) {
2554
2581
  tmpl = parseTemplate(strings);
2555
2582
  cache.set(strings, tmpl);
2556
2583
  }
2584
+ return renderTemplate(tmpl, values);
2585
+ }
2586
+ function __renderParsedTemplate(tree, values) {
2587
+ return renderTemplate(tree, values);
2588
+ }
2589
+ function renderTemplate(tmpl, values) {
2557
2590
  if (tmpl.length === 1 && tmpl[0].t === 0) {
2558
2591
  return executeElement(tmpl[0].el, values);
2559
2592
  }
@@ -2688,25 +2721,77 @@ function mount(component, container) {
2688
2721
  typeof component === "function" || component instanceof Node,
2689
2722
  "mount: first argument must be a component function or a DOM Node."
2690
2723
  );
2691
- const startTime = typeof performance !== "undefined" ? performance.now() : 0;
2692
- const node = typeof component === "function" ? component() : component;
2693
- const duration = typeof performance !== "undefined" ? performance.now() - startTime : 0;
2694
- container.appendChild(node);
2695
- const hook = globalThis.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
2696
- if (hook) {
2697
- hook.emit("app:init", { rootElement: node, container, duration });
2724
+ const now = () => typeof performance !== "undefined" ? performance.now() : 0;
2725
+ const startTime = now();
2726
+ let range = null;
2727
+ const attach = (built) => {
2728
+ if (built instanceof DocumentFragment) {
2729
+ const start = document.createComment("");
2730
+ const end = document.createComment("");
2731
+ built.insertBefore(start, built.firstChild);
2732
+ built.appendChild(end);
2733
+ range = { start, end };
2734
+ }
2735
+ container.appendChild(built);
2736
+ };
2737
+ let node;
2738
+ if (typeof component === "function") {
2739
+ node = withDisposerRollback(() => {
2740
+ const built = component();
2741
+ attach(built);
2742
+ return built;
2743
+ });
2744
+ } else {
2745
+ node = component;
2746
+ attach(node);
2698
2747
  }
2748
+ const duration = now() - startTime;
2749
+ const hook = globalThis.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
2750
+ if (hook) emitDevtools(hook, "app:init", { rootElement: node, container, duration });
2751
+ const mounted = range;
2699
2752
  return {
2700
2753
  node,
2701
2754
  unmount() {
2702
- if (hook) hook.emit("app:unmount", { rootElement: node });
2703
- dispose(node);
2704
- if (node.parentNode) {
2705
- node.parentNode.removeChild(node);
2755
+ if (hook) emitDevtools(hook, "app:unmount", { rootElement: node });
2756
+ if (mounted) {
2757
+ unmountRange(mounted.start, mounted.end);
2758
+ return;
2706
2759
  }
2760
+ dispose(node);
2761
+ node.parentNode?.removeChild(node);
2707
2762
  }
2708
2763
  };
2709
2764
  }
2765
+ function unmountRange(start, end) {
2766
+ const parent = start.parentNode;
2767
+ if (!parent && !end.parentNode) return;
2768
+ let budget = MAX_DRAIN_TEARDOWNS;
2769
+ for (let n = start.nextSibling; n && n !== end; n = n.nextSibling) budget++;
2770
+ let before = start;
2771
+ let after = null;
2772
+ let intact = true;
2773
+ for (; ; ) {
2774
+ if (start.parentNode !== parent || end.parentNode !== parent) intact = false;
2775
+ else if (start.previousSibling !== before || end.nextSibling !== after) {
2776
+ before = start.previousSibling;
2777
+ after = end.nextSibling;
2778
+ intact = !!(start.compareDocumentPosition(end) & 4);
2779
+ }
2780
+ const n = start.nextSibling;
2781
+ if (!intact || n === end) break;
2782
+ if (budget-- <= 0) {
2783
+ reportDrainRunaway("mount", MAX_DRAIN_TEARDOWNS, 1);
2784
+ return;
2785
+ }
2786
+ dispose(n);
2787
+ if (n.parentNode === parent) parent.removeChild(n);
2788
+ }
2789
+ if (!intact) {
2790
+ reportError(new Error("[SibuJS mount] fragment markers lost"), { phase: "cleanup", name: "mount" });
2791
+ }
2792
+ start.parentNode?.removeChild(start);
2793
+ end.parentNode?.removeChild(end);
2794
+ }
2710
2795
 
2711
2796
  // src/core/rendering/portal.ts
2712
2797
  function Portal(nodes, target) {
@@ -3443,7 +3528,7 @@ function enhance(target, setup) {
3443
3528
  bindNode(el, () => {
3444
3529
  const v = value();
3445
3530
  const next = v == null ? null : String(v);
3446
- setSafeAttribute(el, name, next, { syncValueProperty: false, label: "enhance attr()" });
3531
+ setSafeAttribute(el, name, next, { syncValueProperty: false, label: "enhance attr()", reactive: true });
3447
3532
  })
3448
3533
  );
3449
3534
  });
@@ -3830,6 +3915,7 @@ export {
3830
3915
  each,
3831
3916
  Fragment,
3832
3917
  html,
3918
+ __renderParsedTemplate,
3833
3919
  KeepAlive,
3834
3920
  mount,
3835
3921
  Portal,
@@ -6,25 +6,25 @@ import {
6
6
  import {
7
7
  div,
8
8
  span
9
- } from "./chunk-JSXPZCET.js";
9
+ } from "./chunk-Q5J2LVKH.js";
10
10
  import {
11
11
  STATIC_VALUE_RESOLVER,
12
12
  planHeadElementEntry,
13
13
  planMetaEntry
14
- } from "./chunk-HURREPU2.js";
15
- import {
16
- sanitizeUrl
17
- } from "./chunk-2INLLLMZ.js";
14
+ } from "./chunk-FC6KCJSA.js";
18
15
  import {
19
16
  globalSingleton
20
17
  } from "./chunk-7ZHH77QA.js";
21
18
  import {
22
19
  effect
23
- } from "./chunk-XC4MEKGA.js";
20
+ } from "./chunk-V3LHZSU5.js";
21
+ import {
22
+ sanitizeUrl
23
+ } from "./chunk-EXXSN3BW.js";
24
24
  import {
25
25
  batch,
26
26
  signal
27
- } from "./chunk-D33YTSX5.js";
27
+ } from "./chunk-DSID757X.js";
28
28
  import {
29
29
  registerDisposer,
30
30
  replaceChildrenSafely,
@@ -179,7 +179,16 @@ function toError(err) {
179
179
  if (err !== null && typeof err === "object" && "name" in err && "message" in err) return err;
180
180
  return new Error(String(err));
181
181
  }
182
+ function workerSource(fn, api) {
183
+ if (typeof fn !== "function") {
184
+ throw new TypeError(
185
+ `${api}: expected a function, got ${typeof fn}. Worker code must be a function defined in your source \u2014 a string would be evaluated as code.`
186
+ );
187
+ }
188
+ return Function.prototype.toString.call(fn);
189
+ }
182
190
  function worker(workerFn2) {
191
+ const fnBody = workerSource(workerFn2, "worker");
183
192
  const [result, setResult] = signal(null);
184
193
  const [error, setError] = signal(null);
185
194
  const [loading, setLoading] = signal(false);
@@ -195,7 +204,6 @@ function worker(workerFn2) {
195
204
  if (typeof Worker === "undefined") {
196
205
  throw new Error("Web Workers are not supported in this environment");
197
206
  }
198
- const fnBody = workerFn2.toString();
199
207
  const blob = new Blob([`self.onmessage = ${fnBody};`], { type: "application/javascript" });
200
208
  blobUrl = URL.createObjectURL(blob);
201
209
  worker2 = new Worker(blobUrl);
@@ -244,6 +252,7 @@ function worker(workerFn2) {
244
252
  return { post, result, error, loading, terminate };
245
253
  }
246
254
  function workerFn(fn) {
255
+ const fnStr = workerSource(fn, "workerFn");
247
256
  const [loading, setLoading] = signal(false);
248
257
  let worker2 = null;
249
258
  let blobUrl = null;
@@ -258,7 +267,6 @@ function workerFn(fn) {
258
267
  if (typeof Worker === "undefined") {
259
268
  throw new Error("Web Workers are not supported in this environment");
260
269
  }
261
- const fnStr = fn.toString();
262
270
  const blob = new Blob(
263
271
  [
264
272
  `self.onmessage = function(e) {
@@ -318,6 +326,7 @@ function workerFn(fn) {
318
326
  return { run, loading, terminate };
319
327
  }
320
328
  function createWorkerPool(workerFn2, poolSize) {
329
+ const fnBody = workerSource(workerFn2, "createWorkerPool");
321
330
  const size = poolSize || typeof navigator !== "undefined" && navigator.hardwareConcurrency || 4;
322
331
  const workers = [];
323
332
  const queues = [];
@@ -376,7 +385,6 @@ function createWorkerPool(workerFn2, poolSize) {
376
385
  if (typeof Worker === "undefined") {
377
386
  throw new Error("Web Workers are not supported in this environment");
378
387
  }
379
- const fnBody = workerFn2.toString();
380
388
  const blob = new Blob([`self.onmessage = ${fnBody};`], { type: "application/javascript" });
381
389
  blobUrl = URL.createObjectURL(blob);
382
390
  for (let i = 0; i < size; i++) {
@@ -1,10 +1,11 @@
1
1
  import {
2
2
  cleanup,
3
+ emitDevtools,
3
4
  isTrackingSuspended,
4
5
  recordDependency,
5
6
  retrack,
6
7
  track
7
- } from "./chunk-5Q4R7HCL.js";
8
+ } from "./chunk-TQQUN4WR.js";
8
9
  import {
9
10
  devAssert
10
11
  } from "./chunk-NYNYSPK7.js";
@@ -35,17 +36,17 @@ function derived(getter, options) {
35
36
  cs._d = false;
36
37
  cs._init = true;
37
38
  };
38
- track(() => {
39
- let threw = true;
40
- try {
39
+ try {
40
+ track(() => {
41
41
  cs._v = getter();
42
42
  cs._d = false;
43
43
  cs._init = true;
44
- threw = false;
45
- } finally {
46
- if (threw) cs._d = true;
47
- }
48
- }, markDirty);
44
+ }, markDirty);
45
+ } catch (err) {
46
+ disposed = true;
47
+ cleanup(markDirty);
48
+ throw err;
49
+ }
49
50
  const hook = globalThis.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
50
51
  const validate = () => {
51
52
  if (!cs._d || disposed || pendingError !== void 0) return;
@@ -64,7 +65,7 @@ function derived(getter, options) {
64
65
  if (disposed) cleanup(markDirty);
65
66
  }
66
67
  if (hook && !disposed && !Object.is(oldValue, cs._v)) {
67
- hook.emit("computed:update", { signal: cs, oldValue, newValue: cs._v });
68
+ emitDevtools(hook, "computed:update", { signal: cs, oldValue, newValue: cs._v });
68
69
  }
69
70
  };
70
71
  cs._validate = validate;
@@ -115,7 +116,7 @@ function derived(getter, options) {
115
116
  }
116
117
  }
117
118
  };
118
- if (hook) hook.emit("computed:create", { signal: cs, name: debugName, getter: computedGetter });
119
+ if (hook) emitDevtools(hook, "computed:create", { signal: cs, name: debugName, getter: computedGetter });
119
120
  return computedGetter;
120
121
  }
121
122
 
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-5HZXGZ6T.js";
4
4
  import {
5
5
  signal
6
- } from "./chunk-D33YTSX5.js";
6
+ } from "./chunk-DSID757X.js";
7
7
  import {
8
8
  registerDisposer,
9
9
  reportError