sibujs 4.7.0 → 4.9.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 (83) hide show
  1. package/dist/browser.cjs +48 -6
  2. package/dist/browser.d.cts +26 -2
  3. package/dist/browser.d.ts +26 -2
  4. package/dist/browser.js +6 -5
  5. package/dist/build.cjs +539 -96
  6. package/dist/build.d.cts +22 -8
  7. package/dist/build.d.ts +22 -8
  8. package/dist/build.js +68 -21
  9. package/dist/cdn.dev.global.js +15 -13
  10. package/dist/cdn.full.dev.global.js +15 -13
  11. package/dist/cdn.full.global.js +14 -12
  12. package/dist/cdn.global.js +14 -12
  13. package/dist/{chunk-Z3OHK6QT.js → chunk-2K3Z3XO4.js} +5 -5
  14. package/dist/chunk-3ACAAQIN.js +224 -0
  15. package/dist/{chunk-WOLJZUFQ.js → chunk-562UVHMM.js} +32 -15
  16. package/dist/{chunk-UOL2ECCS.js → chunk-5MLWTIQE.js} +18 -12
  17. package/dist/{chunk-H3SRKIYX.js → chunk-62BDYGAG.js} +8 -0
  18. package/dist/{chunk-3QWBSL5R.js → chunk-7OV5Q2UU.js} +8 -5
  19. package/dist/{chunk-SLM3IA34.js → chunk-CDBKFGXN.js} +1 -1
  20. package/dist/{chunk-4AWA2PVD.js → chunk-CF2KCWRE.js} +10 -5
  21. package/dist/{chunk-BSY63EM6.js → chunk-DRMLIF6M.js} +20 -5
  22. package/dist/{chunk-2INLLLMZ.js → chunk-EXXSN3BW.js} +202 -26
  23. package/dist/{chunk-HURREPU2.js → chunk-FC6KCJSA.js} +87 -150
  24. package/dist/{chunk-BC2SECJD.js → chunk-FHCZMHHE.js} +1 -1
  25. package/dist/{chunk-XYV3EDB7.js → chunk-FNOK662L.js} +63 -38
  26. package/dist/{chunk-JWKYU5GV.js → chunk-G2WHYEL7.js} +1 -1
  27. package/dist/{chunk-DKXRACVN.js → chunk-K6K5ACO6.js} +6 -6
  28. package/dist/{chunk-VZSG24LS.js → chunk-KG25XMGP.js} +45 -17
  29. package/dist/{chunk-FNJXNGYZ.js → chunk-MPWDSTYK.js} +58 -6
  30. package/dist/{chunk-UNWRJRKC.js → chunk-NQMKWBKU.js} +1 -1
  31. package/dist/{chunk-7LUJQAOJ.js → chunk-QBKCK6MJ.js} +1 -1
  32. package/dist/{chunk-WEQ3DMVL.js → chunk-SBTZEYNI.js} +1 -1
  33. package/dist/{chunk-FQRUXCEE.js → chunk-SYHGGDNW.js} +1 -1
  34. package/dist/{chunk-XZR4PXRE.js → chunk-TV464N2M.js} +13 -10
  35. package/dist/{chunk-RUSSKG6G.js → chunk-X7NRHFZR.js} +1 -1
  36. package/dist/{chunk-2BPG2XDA.js → chunk-XJVTQUIV.js} +18 -36
  37. package/dist/{chunk-ZVL7TY4K.js → chunk-YW6HQKGO.js} +25 -10
  38. package/dist/{customElement-MmInOW1U.d.ts → customElement-pYDKUzWl.d.cts} +11 -3
  39. package/dist/{customElement-MmInOW1U.d.cts → customElement-pYDKUzWl.d.ts} +11 -3
  40. package/dist/data.cjs +29 -9
  41. package/dist/data.d.cts +23 -4
  42. package/dist/data.d.ts +23 -4
  43. package/dist/data.js +6 -6
  44. package/dist/devtools.cjs +1 -1
  45. package/dist/devtools.js +5 -5
  46. package/dist/ecosystem.cjs +400 -37
  47. package/dist/ecosystem.js +9 -8
  48. package/dist/extras.cjs +672 -269
  49. package/dist/extras.d.cts +2 -2
  50. package/dist/extras.d.ts +2 -2
  51. package/dist/extras.js +24 -23
  52. package/dist/index.cjs +490 -88
  53. package/dist/index.d.cts +34 -2
  54. package/dist/index.d.ts +34 -2
  55. package/dist/index.js +16 -12
  56. package/dist/motion.cjs +1 -1
  57. package/dist/motion.js +3 -3
  58. package/dist/patterns.cjs +10 -7
  59. package/dist/patterns.js +6 -6
  60. package/dist/performance.cjs +31 -2
  61. package/dist/performance.d.cts +12 -2
  62. package/dist/performance.d.ts +12 -2
  63. package/dist/performance.js +8 -6
  64. package/dist/plugins.cjs +571 -240
  65. package/dist/plugins.d.cts +14 -3
  66. package/dist/plugins.d.ts +14 -3
  67. package/dist/plugins.js +35 -37
  68. package/dist/{ssr-XOTUASDO.js → ssr-5OWAH3U2.js} +4 -2
  69. package/dist/{ssr-Bli9XRW5.d.ts → ssr-C8hgIAw7.d.cts} +6 -0
  70. package/dist/{ssr-Bli9XRW5.d.cts → ssr-C8hgIAw7.d.ts} +6 -0
  71. package/dist/ssr.cjs +484 -138
  72. package/dist/ssr.d.cts +59 -5
  73. package/dist/ssr.d.ts +59 -5
  74. package/dist/ssr.js +11 -9
  75. package/dist/testing.cjs +3 -3
  76. package/dist/testing.js +4 -4
  77. package/dist/ui.cjs +609 -241
  78. package/dist/ui.d.cts +1 -1
  79. package/dist/ui.d.ts +1 -1
  80. package/dist/ui.js +9 -8
  81. package/dist/widgets.cjs +1 -1
  82. package/dist/widgets.js +7 -7
  83. package/package.json +5 -4
@@ -135,40 +135,44 @@ import {
135
135
  use,
136
136
  var_,
137
137
  video
138
- } from "./chunk-7LUJQAOJ.js";
138
+ } from "./chunk-QBKCK6MJ.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-SLM3IA34.js";
144
+ } from "./chunk-CDBKFGXN.js";
145
145
  import {
146
146
  __resetIdCounter,
147
147
  createId,
148
148
  domBinding
149
- } from "./chunk-BC2SECJD.js";
149
+ } from "./chunk-FHCZMHHE.js";
150
150
  import {
151
151
  SVG_NS,
152
152
  bindChildNode,
153
153
  captureFocusWithin,
154
154
  restoreFocusWithin,
155
155
  tagFactory
156
- } from "./chunk-UOL2ECCS.js";
156
+ } from "./chunk-5MLWTIQE.js";
157
157
  import {
158
158
  bindAttribute,
159
159
  bindDynamic,
160
- setSafeAttribute
161
- } from "./chunk-FNJXNGYZ.js";
160
+ setSafeAttribute,
161
+ setTrustedAttribute
162
+ } from "./chunk-MPWDSTYK.js";
163
+ import {
164
+ isCodeTextElement
165
+ } from "./chunk-3ACAAQIN.js";
162
166
  import {
163
167
  derived
164
- } from "./chunk-RUSSKG6G.js";
168
+ } from "./chunk-X7NRHFZR.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-WEQ3DMVL.js";
175
+ } from "./chunk-SBTZEYNI.js";
172
176
  import {
173
177
  disableSSR,
174
178
  enableSSR,
@@ -187,7 +191,7 @@ import {
187
191
  external,
188
192
  isBatching,
189
193
  signal
190
- } from "./chunk-FQRUXCEE.js";
194
+ } from "./chunk-SYHGGDNW.js";
191
195
  import {
192
196
  emitDevtools,
193
197
  notifySubscribers,
@@ -199,7 +203,7 @@ import {
199
203
  suspendTracking,
200
204
  track,
201
205
  untracked
202
- } from "./chunk-JWKYU5GV.js";
206
+ } from "./chunk-G2WHYEL7.js";
203
207
  import {
204
208
  DEV,
205
209
  MAX_DRAIN_TEARDOWNS,
@@ -234,6 +238,7 @@ __export(index_exports, {
234
238
  Portal: () => Portal,
235
239
  SVG_NS: () => SVG_NS,
236
240
  Suspense: () => Suspense,
241
+ __renderParsedTemplate: () => __renderParsedTemplate,
237
242
  __resetIdCounter: () => __resetIdCounter,
238
243
  a: () => a,
239
244
  abbr: () => abbr,
@@ -1632,37 +1637,44 @@ function action(element, action2, param2) {
1632
1637
  }
1633
1638
  }
1634
1639
  var clickOutside = (element, callback) => {
1640
+ const doc = element.ownerDocument;
1635
1641
  const handler = (e) => {
1636
- if (!element.contains(e.target)) {
1637
- callback();
1638
- }
1642
+ const target = e.target;
1643
+ if (!(typeof target?.nodeType === "number" && element.contains(target))) callback();
1639
1644
  };
1640
- document.addEventListener("pointerdown", handler, true);
1641
- return () => document.removeEventListener("pointerdown", handler, true);
1645
+ doc.addEventListener("pointerdown", handler, true);
1646
+ return () => doc.removeEventListener("pointerdown", handler, true);
1642
1647
  };
1648
+ var PRESS_END_EVENTS = ["pointerup", "pointerleave", "pointercancel"];
1643
1649
  var longPress = (element, options) => {
1644
1650
  const duration = options.duration ?? 500;
1645
1651
  let timer = null;
1646
- const start = () => {
1647
- timer = setTimeout(() => {
1648
- options.callback();
1649
- timer = null;
1650
- }, duration);
1651
- };
1652
+ let owner;
1652
1653
  const cancel = () => {
1653
1654
  if (timer !== null) {
1654
1655
  clearTimeout(timer);
1655
1656
  timer = null;
1656
1657
  }
1657
1658
  };
1659
+ const start = (e) => {
1660
+ const id = e.pointerId;
1661
+ if (timer !== null && id !== owner) return;
1662
+ cancel();
1663
+ owner = id;
1664
+ timer = setTimeout(() => {
1665
+ timer = null;
1666
+ options.callback();
1667
+ }, duration);
1668
+ };
1669
+ const end = (e) => {
1670
+ if (timer !== null && e.pointerId === owner) cancel();
1671
+ };
1658
1672
  element.addEventListener("pointerdown", start);
1659
- element.addEventListener("pointerup", cancel);
1660
- element.addEventListener("pointerleave", cancel);
1673
+ for (const type of PRESS_END_EVENTS) element.addEventListener(type, end);
1661
1674
  return () => {
1662
1675
  cancel();
1663
1676
  element.removeEventListener("pointerdown", start);
1664
- element.removeEventListener("pointerup", cancel);
1665
- element.removeEventListener("pointerleave", cancel);
1677
+ for (const type of PRESS_END_EVENTS) element.removeEventListener(type, end);
1666
1678
  };
1667
1679
  };
1668
1680
  var copyOnClick = (element, getText) => {
@@ -1696,10 +1708,11 @@ var trapFocus = (element) => {
1696
1708
  if (elements.length === 0) return;
1697
1709
  const first = elements[0];
1698
1710
  const last = elements[elements.length - 1];
1699
- if (e.shiftKey && document.activeElement === first) {
1711
+ const active = element.ownerDocument.activeElement;
1712
+ if (e.shiftKey && active === first) {
1700
1713
  e.preventDefault();
1701
1714
  last.focus();
1702
- } else if (!e.shiftKey && document.activeElement === last) {
1715
+ } else if (!e.shiftKey && active === last) {
1703
1716
  e.preventDefault();
1704
1717
  first.focus();
1705
1718
  }
@@ -1831,6 +1844,10 @@ function attachBranch(parent, anchor, branch, attachedOnce, where) {
1831
1844
  parent.insertBefore(node, anchor.nextSibling);
1832
1845
  return { node, owned };
1833
1846
  }
1847
+ function releaseBranchNode(node, owned) {
1848
+ if (owned) dispose(node);
1849
+ node.parentNode?.removeChild(node);
1850
+ }
1834
1851
  function when(condition, thenBranch, elseBranch) {
1835
1852
  const anchor = document.createComment("when");
1836
1853
  let currentNode = null;
@@ -1848,8 +1865,7 @@ function when(condition, thenBranch, elseBranch) {
1848
1865
  lastCondition = show2;
1849
1866
  const focused = currentNode ? captureFocusWithin([currentNode]) : null;
1850
1867
  if (currentNode?.parentNode) {
1851
- if (currentNodeOwned) dispose(currentNode);
1852
- currentNode.parentNode.removeChild(currentNode);
1868
+ releaseBranchNode(currentNode, currentNodeOwned);
1853
1869
  currentNode = null;
1854
1870
  }
1855
1871
  const branch = show2 ? thenBranch : elseBranch !== void 0 ? elseBranch : null;
@@ -1863,6 +1879,8 @@ function when(condition, thenBranch, elseBranch) {
1863
1879
  registerDisposer(anchor, () => {
1864
1880
  disposed = true;
1865
1881
  stopBinding();
1882
+ if (currentNode) releaseBranchNode(currentNode, currentNodeOwned);
1883
+ currentNode = null;
1866
1884
  });
1867
1885
  if (!initialized) {
1868
1886
  queueMicrotask(() => {
@@ -1888,8 +1906,7 @@ function match(value, cases, fallback) {
1888
1906
  lastKey = key;
1889
1907
  const focused = currentNode ? captureFocusWithin([currentNode]) : null;
1890
1908
  if (currentNode?.parentNode) {
1891
- if (currentNodeOwned) dispose(currentNode);
1892
- currentNode.parentNode.removeChild(currentNode);
1909
+ releaseBranchNode(currentNode, currentNodeOwned);
1893
1910
  currentNode = null;
1894
1911
  }
1895
1912
  const branch = Object.hasOwn(cases, key) ? cases[key] : fallback;
@@ -1903,6 +1920,8 @@ function match(value, cases, fallback) {
1903
1920
  registerDisposer(anchor, () => {
1904
1921
  disposed = true;
1905
1922
  stopBinding();
1923
+ if (currentNode) releaseBranchNode(currentNode, currentNodeOwned);
1924
+ currentNode = null;
1906
1925
  });
1907
1926
  if (!initialized) {
1908
1927
  queueMicrotask(() => {
@@ -2239,7 +2258,6 @@ function appendChild(frag, child) {
2239
2258
  }
2240
2259
 
2241
2260
  // src/core/rendering/htm.ts
2242
- var RAW_TEXT_TAGS = /* @__PURE__ */ new Set(["script", "style"]);
2243
2261
  var VOID_ELEMENTS = /* @__PURE__ */ new Set([
2244
2262
  "area",
2245
2263
  "base",
@@ -2462,7 +2480,7 @@ function parseTemplate(strings) {
2462
2480
  children.push({ t: 0, el: { tag, svg: SVG_TAGS.has(tag), attrs, children: [] } });
2463
2481
  } else {
2464
2482
  const inner = parseChildren();
2465
- if (RAW_TEXT_TAGS.has(tag.toLowerCase())) {
2483
+ if (isCodeTextElement(tag)) {
2466
2484
  for (let i2 = 0; i2 < inner.length; i2++) {
2467
2485
  if (inner[i2].t === 2) {
2468
2486
  throw new Error(
@@ -2493,7 +2511,7 @@ function executeElement(tmpl, values) {
2493
2511
  const attr = tmpl.attrs[i2];
2494
2512
  switch (attr.t) {
2495
2513
  case 0:
2496
- el.setAttribute(attr.name, attr.value);
2514
+ setTrustedAttribute(el, attr.name, attr.value);
2497
2515
  break;
2498
2516
  case 1: {
2499
2517
  const name = attr.name;
@@ -2526,7 +2544,7 @@ function executeElement(tmpl, values) {
2526
2544
  break;
2527
2545
  }
2528
2546
  case 4:
2529
- el.setAttribute(attr.name, "");
2547
+ setTrustedAttribute(el, attr.name, "");
2530
2548
  break;
2531
2549
  }
2532
2550
  }
@@ -2571,6 +2589,12 @@ function html(strings, ...values) {
2571
2589
  tmpl = parseTemplate(strings);
2572
2590
  cache.set(strings, tmpl);
2573
2591
  }
2592
+ return renderTemplate(tmpl, values);
2593
+ }
2594
+ function __renderParsedTemplate(tree, values) {
2595
+ return renderTemplate(tree, values);
2596
+ }
2597
+ function renderTemplate(tmpl, values) {
2574
2598
  if (tmpl.length === 1 && tmpl[0].t === 0) {
2575
2599
  return executeElement(tmpl[0].el, values);
2576
2600
  }
@@ -2646,7 +2670,7 @@ function KeepAlive(activeKey, cases, options) {
2646
2670
  return;
2647
2671
  }
2648
2672
  node = factory();
2649
- if (node instanceof DocumentFragment) {
2673
+ if (node.nodeType === 11) {
2650
2674
  const wrapper = document.createElement("div");
2651
2675
  wrapper.style.display = "contents";
2652
2676
  wrapper.appendChild(node);
@@ -3512,7 +3536,7 @@ function enhance(target, setup) {
3512
3536
  bindNode(el, () => {
3513
3537
  const v = value();
3514
3538
  const next = v == null ? null : String(v);
3515
- setSafeAttribute(el, name, next, { syncValueProperty: false, label: "enhance attr()" });
3539
+ setSafeAttribute(el, name, next, { syncValueProperty: false, label: "enhance attr()", reactive: true });
3516
3540
  })
3517
3541
  );
3518
3542
  });
@@ -3899,6 +3923,7 @@ export {
3899
3923
  each,
3900
3924
  Fragment,
3901
3925
  html,
3926
+ __renderParsedTemplate,
3902
3927
  KeepAlive,
3903
3928
  mount,
3904
3929
  Portal,
@@ -498,7 +498,7 @@ function forEachSubscriber(signal, visit) {
498
498
  }
499
499
 
500
500
  // src/reactivity/track.ts
501
- var _runtimeVersion = true ? "4.7.0" : "dev";
501
+ var _runtimeVersion = true ? "4.9.0" : "dev";
502
502
  var REGISTRY_KEY = /* @__PURE__ */ Symbol.for("sibujs.reactive.v1");
503
503
  function resolveReactiveApi() {
504
504
  const g = globalThis;
@@ -1,20 +1,20 @@
1
- import {
2
- stripHtml
3
- } from "./chunk-2INLLLMZ.js";
4
1
  import {
5
2
  globalSingleton
6
3
  } from "./chunk-7ZHH77QA.js";
7
4
  import {
8
5
  effect
9
- } from "./chunk-WEQ3DMVL.js";
6
+ } from "./chunk-SBTZEYNI.js";
7
+ import {
8
+ stripHtml
9
+ } from "./chunk-EXXSN3BW.js";
10
10
  import {
11
11
  signal
12
- } from "./chunk-FQRUXCEE.js";
12
+ } from "./chunk-SYHGGDNW.js";
13
13
  import {
14
14
  forEachSubscriber,
15
15
  getSubscriberCount,
16
16
  getSubscriberDeps
17
- } from "./chunk-JWKYU5GV.js";
17
+ } from "./chunk-G2WHYEL7.js";
18
18
  import {
19
19
  dispose,
20
20
  isDev
@@ -6,25 +6,25 @@ import {
6
6
  import {
7
7
  div,
8
8
  span
9
- } from "./chunk-7LUJQAOJ.js";
9
+ } from "./chunk-QBKCK6MJ.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-WEQ3DMVL.js";
20
+ } from "./chunk-SBTZEYNI.js";
21
+ import {
22
+ sanitizeUrl
23
+ } from "./chunk-EXXSN3BW.js";
24
24
  import {
25
25
  batch,
26
26
  signal
27
- } from "./chunk-FQRUXCEE.js";
27
+ } from "./chunk-SYHGGDNW.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++) {
@@ -902,7 +910,7 @@ function createISR(options) {
902
910
  const [data, setData] = signal(initialData);
903
911
  const [stale, setStale] = signal(initialData === void 0);
904
912
  const controller = new AbortController();
905
- let inFlight = false;
913
+ let inFlight = null;
906
914
  let disposed = false;
907
915
  let deadline;
908
916
  const clearDeadline = () => {
@@ -922,10 +930,7 @@ function createISR(options) {
922
930
  });
923
931
  }, revalidateAfter);
924
932
  };
925
- const revalidate = async () => {
926
- if (disposed || inFlight) return;
927
- if (controller.signal.aborted) return;
928
- inFlight = true;
933
+ const run = async () => {
929
934
  try {
930
935
  const result = await fetcher({ signal: controller.signal });
931
936
  if (disposed || controller.signal.aborted) return;
@@ -937,10 +942,33 @@ function createISR(options) {
937
942
  } catch (err) {
938
943
  if (!disposed && !controller.signal.aborted) armDeadline();
939
944
  throw err;
940
- } finally {
941
- inFlight = false;
942
945
  }
943
946
  };
947
+ const revalidate = () => {
948
+ if (disposed || controller.signal.aborted) return Promise.resolve();
949
+ if (inFlight) return inFlight;
950
+ let resolve;
951
+ let reject;
952
+ const current = new Promise((res, rej) => {
953
+ resolve = res;
954
+ reject = rej;
955
+ });
956
+ inFlight = current;
957
+ const release = () => {
958
+ if (inFlight === current) inFlight = null;
959
+ };
960
+ run().then(
961
+ () => {
962
+ release();
963
+ resolve();
964
+ },
965
+ (err) => {
966
+ release();
967
+ reject(err);
968
+ }
969
+ );
970
+ return current;
971
+ };
944
972
  if (initialData === void 0) {
945
973
  revalidate().catch((err) => {
946
974
  if (typeof console !== "undefined") console.warn("[SibuJS ISR] initial fetch failed", err);
@@ -1,14 +1,20 @@
1
+ import {
2
+ ContextualRefusal,
3
+ contextualAttributeRefusal,
4
+ settleAttributeProvenance
5
+ } from "./chunk-3ACAAQIN.js";
1
6
  import {
2
7
  isEventHandlerAttr,
3
8
  isHtmlContentAttribute,
4
- sanitizeAttributeString
5
- } from "./chunk-2INLLLMZ.js";
9
+ resolveAttributeValue
10
+ } from "./chunk-EXXSN3BW.js";
6
11
  import {
7
12
  reactiveBinding
8
- } from "./chunk-JWKYU5GV.js";
13
+ } from "./chunk-G2WHYEL7.js";
9
14
  import {
10
15
  DEV,
11
16
  devWarn,
17
+ devWarnLazy,
12
18
  reportError
13
19
  } from "./chunk-NYNYSPK7.js";
14
20
 
@@ -21,6 +27,19 @@ var BOOLEAN_IDL_ATTRS = /* @__PURE__ */ new Set(["checked", "disabled", "selecte
21
27
  function isHtmlElement(el) {
22
28
  return el.namespaceURI === null || el.namespaceURI === HTML_NS;
23
29
  }
30
+ function warnContextualRefusal(label, name, refusal) {
31
+ devWarnLazy(() => {
32
+ const reasons = [
33
+ "",
34
+ 'the element would become a <meta http-equiv="refresh"> directive the shared refresh policy forbids (a destination outside the URL allowlist, or a directive too malformed to read unambiguously)',
35
+ "a <meta> whose http-equiv or content is reactive may never carry a refresh directive: a browser schedules the navigation as soon as the directive is valid, and nothing can withdraw it when the state changes back",
36
+ "a runtime value may not choose the program a <script> runs; name the script in static template source, or load it through Head({ script }) as an explicit trust decision",
37
+ "an SVG animation may not target a URL, event-handler or nested-document attribute; its to / values would be written into that attribute without passing the URL policy",
38
+ 'a runtime-chosen href may not become an applied <link rel="stylesheet">: a well-formed URL is not a trusted stylesheet. Name the stylesheet in static template source, or load a runtime-chosen one through Head({ link }) as an explicit trust decision'
39
+ ];
40
+ return `${label}: refusing "${name}" in this element's context \u2014 ${reasons[refusal]}. The write was not performed.`;
41
+ });
42
+ }
24
43
  function setProp(el, key, val) {
25
44
  el[key] = val;
26
45
  }
@@ -32,6 +51,11 @@ function namespaceFor(el, name) {
32
51
  return null;
33
52
  }
34
53
  function setSafeAttribute(el, name, value, options = {}) {
54
+ const written = commitSafeAttribute(el, name, value, options);
55
+ if (el.localName === "link") settleAttributeProvenance(el, name, options.reactive ? "reactive" : "runtime");
56
+ return written;
57
+ }
58
+ function commitSafeAttribute(el, name, value, options) {
35
59
  const ns = namespaceFor(el, name);
36
60
  const localName = ns ? name.slice(name.indexOf(":") + 1) : name;
37
61
  if (isEventHandlerAttr(name)) {
@@ -44,6 +68,14 @@ function setSafeAttribute(el, name, value, options = {}) {
44
68
  else el.removeAttribute(name);
45
69
  return false;
46
70
  }
71
+ const pending = value == null || value === false ? null : value === true ? "" : String(value);
72
+ const refusal = contextualAttributeRefusal(el, name, pending, options.reactive ? "reactive" : "runtime");
73
+ if (refusal !== ContextualRefusal.None) {
74
+ warnContextualRefusal(options.label ?? "setSafeAttribute", name, refusal);
75
+ if (ns) el.removeAttributeNS(ns, localName);
76
+ else el.removeAttribute(name);
77
+ return false;
78
+ }
47
79
  if (value == null) {
48
80
  if (ns) el.removeAttributeNS(ns, localName);
49
81
  else el.removeAttribute(name);
@@ -87,13 +119,32 @@ function setSafeAttribute(el, name, value, options = {}) {
87
119
  setProp(el, idlName, idlName === "checked" ? Boolean(value) : str);
88
120
  return true;
89
121
  }
90
- const safe = sanitizeAttributeString(name, str, { element: el });
122
+ const safe = str === "" ? "" : resolveAttributeValue(name, str, { element: el });
123
+ if (safe === null) {
124
+ if (ns) el.removeAttributeNS(ns, localName);
125
+ else el.removeAttribute(name);
126
+ return true;
127
+ }
91
128
  const current = ns ? el.getAttributeNS(ns, localName) : el.getAttribute(name);
92
129
  if (current === safe) return true;
93
130
  if (ns) el.setAttributeNS(ns, name, safe);
94
131
  else el.setAttribute(name, safe);
95
132
  return true;
96
133
  }
134
+ function setTrustedAttribute(el, name, value) {
135
+ if (isHtmlContentAttribute(name)) {
136
+ if (DEV) devWarn(`html: refusing static attribute "${name}" \u2014 the browser parses it as a nested document.`);
137
+ return false;
138
+ }
139
+ const refusal = contextualAttributeRefusal(el, name, value, "static");
140
+ if (refusal !== ContextualRefusal.None) {
141
+ warnContextualRefusal("html (static attribute)", name, refusal);
142
+ return false;
143
+ }
144
+ el.setAttribute(name, value);
145
+ if (el.localName === "link") settleAttributeProvenance(el, name, "static");
146
+ return true;
147
+ }
97
148
 
98
149
  // src/reactivity/bindAttribute.ts
99
150
  function bindAttribute(el, attr, getter) {
@@ -110,7 +161,7 @@ function bindAttribute(el, attr, getter) {
110
161
  reportError(err, { phase: "binding", name: `bindAttribute("${attr}")`, node: el });
111
162
  return;
112
163
  }
113
- setSafeAttribute(el, attr, value, { label: `bindAttribute("${attr}")` });
164
+ setSafeAttribute(el, attr, value, { label: `bindAttribute("${attr}")`, reactive: true });
114
165
  }
115
166
  return reactiveBinding(commit, el);
116
167
  }
@@ -135,7 +186,7 @@ function bindDynamic(el, nameGetter, valueGetter) {
135
186
  el.removeAttribute(prevName);
136
187
  prevName = null;
137
188
  }
138
- if (!setSafeAttribute(el, name, value, { label: "bindDynamic" })) return;
189
+ if (!setSafeAttribute(el, name, value, { label: "bindDynamic", reactive: true })) return;
139
190
  prevName = name;
140
191
  }
141
192
  const teardown = reactiveBinding(commit, el);
@@ -149,6 +200,7 @@ function bindDynamic(el, nameGetter, valueGetter) {
149
200
 
150
201
  export {
151
202
  setSafeAttribute,
203
+ setTrustedAttribute,
152
204
  bindAttribute,
153
205
  bindDynamic
154
206
  };
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-5HZXGZ6T.js";
4
4
  import {
5
5
  signal
6
- } from "./chunk-FQRUXCEE.js";
6
+ } from "./chunk-SYHGGDNW.js";
7
7
  import {
8
8
  registerDisposer,
9
9
  reportError
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  SVG_NS,
3
3
  tagFactory
4
- } from "./chunk-UOL2ECCS.js";
4
+ } from "./chunk-5MLWTIQE.js";
5
5
 
6
6
  // src/core/rendering/html.ts
7
7
  var html = tagFactory("html");
@@ -6,7 +6,7 @@ import {
6
6
  emitDevtools,
7
7
  retrack,
8
8
  untracked
9
- } from "./chunk-JWKYU5GV.js";
9
+ } from "./chunk-G2WHYEL7.js";
10
10
  import {
11
11
  devAssert,
12
12
  reportError
@@ -4,7 +4,7 @@ import {
4
4
  notifySubscribers,
5
5
  queueSignalNotification,
6
6
  recordDependency
7
- } from "./chunk-JWKYU5GV.js";
7
+ } from "./chunk-G2WHYEL7.js";
8
8
  import {
9
9
  DEV
10
10
  } from "./chunk-NYNYSPK7.js";