sibujs 4.10.1 → 4.12.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 (79) hide show
  1. package/README.md +2 -2
  2. package/dist/browser.cjs +1 -1
  3. package/dist/browser.js +4 -4
  4. package/dist/build.cjs +19 -1
  5. package/dist/build.js +13 -12
  6. package/dist/cdn.dev.global.js +12 -12
  7. package/dist/cdn.full.dev.global.js +13 -13
  8. package/dist/cdn.full.global.js +12 -12
  9. package/dist/cdn.global.js +12 -12
  10. package/dist/{chunk-FC6KCJSA.js → chunk-2F4PSJ5Z.js} +162 -67
  11. package/dist/{chunk-JZMLRF2G.js → chunk-653KGQS2.js} +3 -3
  12. package/dist/chunk-AM6DZLBM.js +181 -0
  13. package/dist/{chunk-NROLUUCO.js → chunk-B2Y5BJSP.js} +1 -1
  14. package/dist/{chunk-WHZKRSHQ.js → chunk-CI4W6XAU.js} +4 -4
  15. package/dist/{chunk-GEQNWNYS.js → chunk-DFZL3AX7.js} +6 -6
  16. package/dist/{chunk-6DYRY2NF.js → chunk-EMB5PG7V.js} +1 -1
  17. package/dist/{chunk-3ACAAQIN.js → chunk-F2UWOZ6J.js} +4 -0
  18. package/dist/{chunk-DA2LJXK3.js → chunk-HXT2RNH5.js} +1 -1
  19. package/dist/{chunk-BNZDDNBR.js → chunk-IHA62NGJ.js} +1 -1
  20. package/dist/{chunk-42REZXE4.js → chunk-LEUEKK4G.js} +2 -2
  21. package/dist/{chunk-CYUU3XXG.js → chunk-LXBMVGVB.js} +3 -3
  22. package/dist/{chunk-LYM6TT2R.js → chunk-LYTUTXQP.js} +4 -4
  23. package/dist/{chunk-2D47RVVK.js → chunk-NAVLCP4S.js} +4 -4
  24. package/dist/{chunk-MJZUXQHR.js → chunk-NB7TFSJE.js} +5 -5
  25. package/dist/{chunk-ADJEMTRC.js → chunk-QLG5IK7F.js} +4 -4
  26. package/dist/{chunk-LK3VK47W.js → chunk-RK7EPQPG.js} +1 -1
  27. package/dist/{chunk-YNE4FSVX.js → chunk-T5O2CUHV.js} +1 -1
  28. package/dist/{chunk-GVVZPMA5.js → chunk-WFRQ6D7H.js} +1 -1
  29. package/dist/{chunk-2T73SWKF.js → chunk-WH4U2VUE.js} +5 -3
  30. package/dist/{chunk-DS6PFIZK.js → chunk-XX4BRMWF.js} +15 -3
  31. package/dist/{chunk-HZQEL575.js → chunk-ZJCHY2IB.js} +1 -1
  32. package/dist/{chunk-CID4BYBF.js → chunk-ZPY2UAKM.js} +3 -3
  33. package/dist/{chunk-CZINTERN.js → chunk-ZTYCCBU3.js} +19 -11
  34. package/dist/data.cjs +1 -1
  35. package/dist/data.js +5 -5
  36. package/dist/devtools.cjs +1 -1
  37. package/dist/devtools.js +4 -4
  38. package/dist/ecosystem.cjs +9 -1
  39. package/dist/ecosystem.d.cts +1 -1
  40. package/dist/ecosystem.d.ts +1 -1
  41. package/dist/ecosystem.js +8 -8
  42. package/dist/extras.cjs +368 -154
  43. package/dist/extras.d.cts +2 -2
  44. package/dist/extras.d.ts +2 -2
  45. package/dist/extras.js +23 -22
  46. package/dist/index.cjs +19 -1
  47. package/dist/index.d.cts +91 -90
  48. package/dist/index.d.ts +91 -90
  49. package/dist/index.js +13 -12
  50. package/dist/motion.cjs +1 -1
  51. package/dist/motion.js +3 -3
  52. package/dist/patterns.cjs +1 -1
  53. package/dist/patterns.js +5 -5
  54. package/dist/performance.cjs +1 -1
  55. package/dist/performance.d.cts +2 -2
  56. package/dist/performance.d.ts +2 -2
  57. package/dist/performance.js +7 -6
  58. package/dist/plugins.cjs +482 -120
  59. package/dist/plugins.d.cts +20 -6
  60. package/dist/plugins.d.ts +20 -6
  61. package/dist/plugins.js +153 -23
  62. package/dist/{ssr-C8hgIAw7.d.cts → ssr-Db0Sgdu3.d.cts} +7 -4
  63. package/dist/{ssr-C8hgIAw7.d.ts → ssr-Db0Sgdu3.d.ts} +7 -4
  64. package/dist/{ssr-5OWAH3U2.js → ssr-VBM6J5SJ.js} +4 -2
  65. package/dist/ssr.cjs +346 -128
  66. package/dist/ssr.d.cts +1 -1
  67. package/dist/ssr.d.ts +1 -1
  68. package/dist/ssr.js +10 -9
  69. package/dist/{tagFactory-BL2fymez.d.ts → tagFactory-Bnd_Nph9.d.ts} +1 -1
  70. package/dist/{tagFactory-8qL9LCIx.d.cts → tagFactory-DkytnJws.d.cts} +1 -1
  71. package/dist/testing.cjs +1 -1
  72. package/dist/testing.js +2 -2
  73. package/dist/ui.cjs +251 -24
  74. package/dist/ui.d.cts +111 -1
  75. package/dist/ui.d.ts +111 -1
  76. package/dist/ui.js +130 -8
  77. package/dist/widgets.cjs +1 -1
  78. package/dist/widgets.js +6 -6
  79. package/package.json +1 -1
package/dist/extras.cjs CHANGED
@@ -1103,7 +1103,7 @@ function forEachSubscriber(signal2, visit) {
1103
1103
  }
1104
1104
 
1105
1105
  // src/reactivity/track.ts
1106
- var _runtimeVersion = true ? "4.10.1" : "dev";
1106
+ var _runtimeVersion = true ? "4.12.0" : "dev";
1107
1107
  var REGISTRY_KEY = /* @__PURE__ */ Symbol.for("sibujs.reactive.v1");
1108
1108
  function resolveReactiveApi() {
1109
1109
  const g2 = globalThis;
@@ -1524,7 +1524,7 @@ var isBatching = API2.isBatching;
1524
1524
  // src/core/signals/signal.ts
1525
1525
  var _g2 = globalThis;
1526
1526
  function signal(initial, options) {
1527
- const state2 = {
1527
+ const state3 = {
1528
1528
  value: initial,
1529
1529
  __v: 0,
1530
1530
  __sc: 0,
@@ -1537,57 +1537,57 @@ function signal(initial, options) {
1537
1537
  };
1538
1538
  const debugName = DEV ? options?.name : void 0;
1539
1539
  const equalsFn = options?.equals;
1540
- if (debugName) state2.__name = debugName;
1540
+ if (debugName) state3.__name = debugName;
1541
1541
  function get() {
1542
- recordDependency2(state2);
1543
- return state2.value;
1542
+ recordDependency2(state3);
1543
+ return state3.value;
1544
1544
  }
1545
- get.__signal = state2;
1545
+ get.__signal = state3;
1546
1546
  if (debugName) get.__name = debugName;
1547
1547
  let set;
1548
1548
  if (equalsFn) {
1549
1549
  set = (next) => {
1550
- const prev = state2.value;
1550
+ const prev = state3.value;
1551
1551
  const newValue = typeof next === "function" ? next(prev) : next;
1552
1552
  if (equalsFn(prev, newValue)) return;
1553
- state2.value = newValue;
1554
- state2.__v++;
1553
+ state3.value = newValue;
1554
+ state3.__v++;
1555
1555
  if (DEV) {
1556
1556
  const hook = _g2.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
1557
- if (hook) emitDevtools(hook, "signal:update", { signal: state2, name: debugName, oldValue: prev, newValue });
1557
+ if (hook) emitDevtools(hook, "signal:update", { signal: state3, name: debugName, oldValue: prev, newValue });
1558
1558
  }
1559
- if (!enqueueBatchedSignal(state2)) {
1560
- notifySubscribers2(state2);
1559
+ if (!enqueueBatchedSignal(state3)) {
1560
+ notifySubscribers2(state3);
1561
1561
  }
1562
1562
  };
1563
1563
  } else if (DEV) {
1564
1564
  set = (next) => {
1565
- const prev = state2.value;
1565
+ const prev = state3.value;
1566
1566
  const newValue = typeof next === "function" ? next(prev) : next;
1567
1567
  if (Object.is(newValue, prev)) return;
1568
- state2.value = newValue;
1569
- state2.__v++;
1568
+ state3.value = newValue;
1569
+ state3.__v++;
1570
1570
  const hook = _g2.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
1571
- if (hook) emitDevtools(hook, "signal:update", { signal: state2, name: debugName, oldValue: prev, newValue });
1572
- if (!enqueueBatchedSignal(state2)) {
1573
- notifySubscribers2(state2);
1571
+ if (hook) emitDevtools(hook, "signal:update", { signal: state3, name: debugName, oldValue: prev, newValue });
1572
+ if (!enqueueBatchedSignal(state3)) {
1573
+ notifySubscribers2(state3);
1574
1574
  }
1575
1575
  };
1576
1576
  } else {
1577
1577
  set = (next) => {
1578
- const prev = state2.value;
1578
+ const prev = state3.value;
1579
1579
  const newValue = typeof next === "function" ? next(prev) : next;
1580
1580
  if (Object.is(newValue, prev)) return;
1581
- state2.value = newValue;
1582
- state2.__v++;
1583
- if (!enqueueBatchedSignal(state2)) {
1584
- notifySubscribers2(state2);
1581
+ state3.value = newValue;
1582
+ state3.__v++;
1583
+ if (!enqueueBatchedSignal(state3)) {
1584
+ notifySubscribers2(state3);
1585
1585
  }
1586
1586
  };
1587
1587
  }
1588
1588
  if (DEV) {
1589
1589
  const hook = _g2.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
1590
- if (hook) emitDevtools(hook, "signal:create", { signal: state2, name: debugName, getter: get, initial });
1590
+ if (hook) emitDevtools(hook, "signal:create", { signal: state3, name: debugName, getter: get, initial });
1591
1591
  }
1592
1592
  return [get, set];
1593
1593
  }
@@ -3896,13 +3896,13 @@ function idle(timeout = 6e4) {
3896
3896
 
3897
3897
  // src/browser/permissions.ts
3898
3898
  function permissions(name) {
3899
- const [state2, setState] = signal("prompt");
3899
+ const [state3, setState] = signal("prompt");
3900
3900
  let permissionStatus = null;
3901
3901
  let onChange = null;
3902
3902
  let disposed = false;
3903
3903
  if (typeof navigator === "undefined" || !navigator.permissions) {
3904
3904
  setState("unsupported");
3905
- return { state: state2, dispose: () => {
3905
+ return { state: state3, dispose: () => {
3906
3906
  } };
3907
3907
  }
3908
3908
  navigator.permissions.query({ name }).then((status) => {
@@ -3925,7 +3925,7 @@ function permissions(name) {
3925
3925
  onChange = null;
3926
3926
  }
3927
3927
  }
3928
- return { state: state2, dispose: dispose2 };
3928
+ return { state: state3, dispose: dispose2 };
3929
3929
  }
3930
3930
 
3931
3931
  // src/browser/clipboard.ts
@@ -4294,9 +4294,9 @@ function colorScheme() {
4294
4294
  // src/browser/format.ts
4295
4295
  var I18N_STATE = /* @__PURE__ */ Symbol.for("sibujs.i18n.v1");
4296
4296
  function activeI18nLocale() {
4297
- const state2 = globalThis[I18N_STATE];
4298
- if (!state2) return void 0;
4299
- return state2.getLocale ? state2.getLocale() : state2.locale?.[0]();
4297
+ const state3 = globalThis[I18N_STATE];
4298
+ if (!state3) return void 0;
4299
+ return state3.getLocale ? state3.getLocale() : state3.locale?.[0]();
4300
4300
  }
4301
4301
  function formatNumber(value, options) {
4302
4302
  const { locale, ...formatOptions } = options ?? {};
@@ -4478,9 +4478,9 @@ function notifyUrlWrite() {
4478
4478
  for (const sync of Array.from(_url.instances)) sync();
4479
4479
  }
4480
4480
  var SCROLL_ENTRY_KEY = "__sibuScrollKey";
4481
- function withoutEntryIdentity(state2) {
4482
- if (state2 === null || typeof state2 !== "object" || !Object.hasOwn(state2, SCROLL_ENTRY_KEY)) return state2;
4483
- const { [SCROLL_ENTRY_KEY]: _identity, ...rest } = state2;
4481
+ function withoutEntryIdentity(state3) {
4482
+ if (state3 === null || typeof state3 !== "object" || !Object.hasOwn(state3, SCROLL_ENTRY_KEY)) return state3;
4483
+ const { [SCROLL_ENTRY_KEY]: _identity, ...rest } = state3;
4484
4484
  return rest;
4485
4485
  }
4486
4486
  function urlState() {
@@ -4518,9 +4518,9 @@ function urlState() {
4518
4518
  window.addEventListener("hashchange", syncFromLocation);
4519
4519
  _url.instances.add(syncFromLocation);
4520
4520
  function writeHistory(newUrl, opts) {
4521
- const state2 = "state" in opts ? opts.state : window.history.state;
4522
- if (opts.replace) window.history.replaceState(state2, "", newUrl);
4523
- else window.history.pushState("state" in opts ? state2 : withoutEntryIdentity(state2), "", newUrl);
4521
+ const state3 = "state" in opts ? opts.state : window.history.state;
4522
+ if (opts.replace) window.history.replaceState(state3, "", newUrl);
4523
+ else window.history.pushState("state" in opts ? state3 : withoutEntryIdentity(state3), "", newUrl);
4524
4524
  }
4525
4525
  function setParams(next, opts = {}) {
4526
4526
  const p2 = next instanceof URLSearchParams ? next : new URLSearchParams(next);
@@ -5327,7 +5327,7 @@ function ownEntry(table2, key) {
5327
5327
  return Object.hasOwn(table2, key) ? table2[key] : void 0;
5328
5328
  }
5329
5329
  function machine(config) {
5330
- const [state2, setState] = signal(config.initial);
5330
+ const [state3, setState] = signal(config.initial);
5331
5331
  const [context, setContext] = signal(config.context || {});
5332
5332
  let currentState = config.initial;
5333
5333
  let currentContext = context();
@@ -5401,10 +5401,10 @@ function machine(config) {
5401
5401
  if (queue.length > 0) drain();
5402
5402
  }
5403
5403
  function matches(s2) {
5404
- return state2() === s2;
5404
+ return state3() === s2;
5405
5405
  }
5406
5406
  function can(event) {
5407
- const currentState2 = state2();
5407
+ const currentState2 = state3();
5408
5408
  const stateDef = ownEntry(config.states, currentState2);
5409
5409
  if (!stateDef?.on) return false;
5410
5410
  const transition2 = ownEntry(stateDef.on, event);
@@ -5415,7 +5415,7 @@ function machine(config) {
5415
5415
  }
5416
5416
  return true;
5417
5417
  }
5418
- return { state: state2, context, send, matches, can };
5418
+ return { state: state3, context, send, matches, can };
5419
5419
  }
5420
5420
 
5421
5421
  // src/patterns/persist.ts
@@ -5881,11 +5881,11 @@ function adopt(value) {
5881
5881
  resolvePromise = resolve;
5882
5882
  rejectPromise = reject;
5883
5883
  });
5884
- let state2 = "invoking";
5884
+ let state3 = "invoking";
5885
5885
  let nativeTarget;
5886
5886
  const waiters = [];
5887
5887
  const transition2 = (next) => {
5888
- state2 = next;
5888
+ state3 = next;
5889
5889
  if (next === "invoking") return;
5890
5890
  for (const waiter of waiters.splice(0)) waiter();
5891
5891
  };
@@ -5943,18 +5943,18 @@ function adopt(value) {
5943
5943
  } catch (error) {
5944
5944
  onReject(error);
5945
5945
  }
5946
- if (!done && state2 === "invoking") transition2("pending");
5946
+ if (!done && state3 === "invoking") transition2("pending");
5947
5947
  });
5948
5948
  };
5949
5949
  invokeLater(value, then);
5950
5950
  const probe = (onRejected, onOpen) => {
5951
5951
  const decide = () => {
5952
- if (state2 === "native") probeNative(nativeTarget, onRejected, onOpen);
5953
- else (state2 === "rejected" ? onRejected : onOpen)();
5952
+ if (state3 === "native") probeNative(nativeTarget, onRejected, onOpen);
5953
+ else (state3 === "rejected" ? onRejected : onOpen)();
5954
5954
  };
5955
- if (state2 === "native") probeNative(nativeTarget, onRejected, onOpen);
5956
- else if (state2 === "invoking") waiters.push(decide);
5957
- else queueMicrotask(state2 === "rejected" ? onRejected : onOpen);
5955
+ if (state3 === "native") probeNative(nativeTarget, onRejected, onOpen);
5956
+ else if (state3 === "invoking") waiters.push(decide);
5957
+ else queueMicrotask(state3 === "rejected" ? onRejected : onOpen);
5958
5958
  };
5959
5959
  return { promise, failedEarly: false, probe };
5960
5960
  }
@@ -5995,12 +5995,12 @@ function globalStore(config) {
5995
5995
  const [getState, setState] = signal({ ...initialState });
5996
5996
  const subscriptions = /* @__PURE__ */ new Map();
5997
5997
  const middlewares = config.middleware || [];
5998
- function notifyListeners2(state2) {
5998
+ function notifyListeners2(state3) {
5999
5999
  if (subscriptions.size === 0) return;
6000
6000
  for (const subscription of Array.from(subscriptions.values())) {
6001
6001
  if (!subscription.active) continue;
6002
6002
  try {
6003
- subscription.callback(state2);
6003
+ subscription.callback(state3);
6004
6004
  } catch (err) {
6005
6005
  reportError(err, { phase: "event", name: "globalStore(subscribe)" });
6006
6006
  }
@@ -7864,6 +7864,9 @@ function contextualAttributeRefusal(el, name, value, origin) {
7864
7864
  if (SVG_ANIMATION_ELEMENTS.has(local) && el.namespaceURI === SVG_NS) return animationRefusal(name, value);
7865
7865
  return ContextualRefusal.None;
7866
7866
  }
7867
+ function isRefusedAnimationAttribute(el, name, value) {
7868
+ return SVG_ANIMATION_ELEMENTS.has(el.localName) && el.namespaceURI === SVG_NS && animationRefusal(name, value) !== ContextualRefusal.None;
7869
+ }
7867
7870
  function settleAttributeProvenance(el, name, origin) {
7868
7871
  if (el.localName !== "link" || canonicalAttrName(name) !== "href") return;
7869
7872
  if (origin !== "static" && el.hasAttribute("href")) runtimeHrefLinks.add(el);
@@ -8738,6 +8741,120 @@ function noSideEffect(fn) {
8738
8741
  return fn;
8739
8742
  }
8740
8743
 
8744
+ // src/utils/embedPolicy.ts
8745
+ var state2 = globalSingleton(/* @__PURE__ */ Symbol.for("sibujs.embed.v2"), () => ({
8746
+ allowed: [],
8747
+ frames: /* @__PURE__ */ new WeakMap()
8748
+ }));
8749
+ var REQUEST_CACHE = "embed";
8750
+ function currentEmbedAllowlist() {
8751
+ const scoped = getRequestStore()?.caches?.get(REQUEST_CACHE)?.get("allowed");
8752
+ return scoped ?? state2.allowed;
8753
+ }
8754
+ function resolveEmbedSrc(value, allowed = currentEmbedAllowlist()) {
8755
+ if (typeof value !== "string" || sanitizeUrl(value) === "") return null;
8756
+ let url;
8757
+ try {
8758
+ url = new URL(value);
8759
+ } catch {
8760
+ return null;
8761
+ }
8762
+ if (url.protocol !== "https:" || url.username || url.password) return null;
8763
+ if (typeof location !== "undefined" && url.origin === location.origin) return null;
8764
+ for (const entry of allowed) {
8765
+ if (url.origin !== entry.origin) continue;
8766
+ const path2 = entry.path;
8767
+ if (path2 === "" || url.pathname === path2 || url.pathname.startsWith(path2.endsWith("/") ? path2 : `${path2}/`)) {
8768
+ return url.href;
8769
+ }
8770
+ }
8771
+ return null;
8772
+ }
8773
+ var DEFAULT_EMBED_SANDBOX = [
8774
+ "allow-scripts",
8775
+ "allow-same-origin",
8776
+ "allow-presentation",
8777
+ "allow-popups",
8778
+ "allow-popups-to-escape-sandbox"
8779
+ ];
8780
+ var EMBED_FEATURES = /* @__PURE__ */ new Set([
8781
+ "accelerometer",
8782
+ "autoplay",
8783
+ "clipboard-write",
8784
+ "encrypted-media",
8785
+ "fullscreen",
8786
+ "gyroscope",
8787
+ "picture-in-picture",
8788
+ "web-share"
8789
+ ]);
8790
+ function narrowEmbedSandbox(value) {
8791
+ const out = [];
8792
+ for (const token of value.toLowerCase().split(/[\t\n\f\r ]+/)) {
8793
+ if (token && DEFAULT_EMBED_SANDBOX.includes(token) && !out.includes(token)) out.push(token);
8794
+ }
8795
+ return out.join(" ");
8796
+ }
8797
+ function narrowEmbedAllow(value) {
8798
+ const granted = [];
8799
+ const denied = [];
8800
+ for (const directive of value.split(";")) {
8801
+ const tokens = directive.trim().split(/[\t\n\f\r ]+/);
8802
+ const feature = tokens[0];
8803
+ if (!feature) continue;
8804
+ const list = tokens.slice(1).map((token) => token.toLowerCase());
8805
+ const grantsSrc = (list.length === 0 || list.includes("'src'") || list.includes("*")) && !list.includes("'none'");
8806
+ if (!grantsSrc) denied.push(feature);
8807
+ else if (EMBED_FEATURES.has(feature) && !granted.includes(feature)) granted.push(feature);
8808
+ }
8809
+ return granted.filter((feature) => !denied.includes(feature)).join("; ");
8810
+ }
8811
+ function getEmbedRecord(frame) {
8812
+ return state2.frames.get(frame);
8813
+ }
8814
+ function intersect(current, permitted, separator) {
8815
+ const allowed = permitted.split(separator);
8816
+ return current.split(separator).filter((token) => token && allowed.includes(token)).join(separator);
8817
+ }
8818
+ function embedSerializedAttribute(record, seen, name, value) {
8819
+ switch (name) {
8820
+ case "src":
8821
+ return resolveEmbedSrc(value, record.allowed);
8822
+ case "title":
8823
+ if (!value.trim()) return null;
8824
+ seen.title = true;
8825
+ return value;
8826
+ case "sandbox":
8827
+ seen.sandbox = true;
8828
+ return intersect(narrowEmbedSandbox(value), record.sandbox, " ");
8829
+ case "allow": {
8830
+ const allow = intersect(narrowEmbedAllow(value), record.allow, "; ");
8831
+ if (allow.split("; ").includes("fullscreen")) seen.fullscreen = true;
8832
+ return allow || null;
8833
+ }
8834
+ case "referrerpolicy":
8835
+ seen.referrer = true;
8836
+ return value.trim().toLowerCase() === "no-referrer" ? "no-referrer" : record.referrer;
8837
+ case "loading":
8838
+ return value === "eager" ? "eager" : "lazy";
8839
+ case "id":
8840
+ case "class":
8841
+ case "style":
8842
+ case "width":
8843
+ case "height":
8844
+ return value;
8845
+ default:
8846
+ return name.startsWith("data-") || name.startsWith("aria-") ? value : null;
8847
+ }
8848
+ }
8849
+ function embedSerializationTail(record, seen) {
8850
+ if (!seen.title) return null;
8851
+ let tail = "";
8852
+ if (!seen.sandbox) tail += ` sandbox="${record.sandbox}"`;
8853
+ if (!seen.referrer) tail += ` referrerpolicy="${record.referrer}"`;
8854
+ if (seen.fullscreen) tail += ' allowfullscreen=""';
8855
+ return tail;
8856
+ }
8857
+
8741
8858
  // src/utils/headEntry.ts
8742
8859
  var SAFE_HEAD_ATTR_NAME = /^[A-Za-z_:][-A-Za-z0-9_.:]*$/;
8743
8860
  function isEmittableHeadAttrName(name) {
@@ -8875,69 +8992,180 @@ function childNodesOf(node) {
8875
8992
  function getAttributeOf(el, name) {
8876
8993
  return nativeAccessors().getAttribute.call(el, name);
8877
8994
  }
8878
- function serializeOpenTag(element, tag) {
8995
+ var SVG_NS3 = "http://www.w3.org/2000/svg";
8996
+ var MATHML_NS = "http://www.w3.org/1998/Math/MathML";
8997
+ var XLINK_NS2 = "http://www.w3.org/1999/xlink";
8998
+ var XML_NS2 = "http://www.w3.org/XML/1998/namespace";
8999
+ var XMLNS_NS = "http://www.w3.org/2000/xmlns/";
9000
+ var BREAKOUT_TAGS = /* @__PURE__ */ new Set([
9001
+ "b",
9002
+ "big",
9003
+ "blockquote",
9004
+ "body",
9005
+ "br",
9006
+ "center",
9007
+ "code",
9008
+ "dd",
9009
+ "div",
9010
+ "dl",
9011
+ "dt",
9012
+ "em",
9013
+ "embed",
9014
+ "h1",
9015
+ "h2",
9016
+ "h3",
9017
+ "h4",
9018
+ "h5",
9019
+ "h6",
9020
+ "head",
9021
+ "hr",
9022
+ "i",
9023
+ "img",
9024
+ "li",
9025
+ "listing",
9026
+ "menu",
9027
+ "meta",
9028
+ "nobr",
9029
+ "ol",
9030
+ "p",
9031
+ "pre",
9032
+ "ruby",
9033
+ "s",
9034
+ "small",
9035
+ "span",
9036
+ "strong",
9037
+ "strike",
9038
+ "sub",
9039
+ "sup",
9040
+ "table",
9041
+ "tt",
9042
+ "u",
9043
+ "ul",
9044
+ "var"
9045
+ ]);
9046
+ function isBreakout(lowerName, element) {
9047
+ if (BREAKOUT_TAGS.has(lowerName)) return true;
9048
+ return lowerName === "font" && (element.hasAttribute("color") || element.hasAttribute("face") || element.hasAttribute("size"));
9049
+ }
9050
+ function fitsParseContext(ns, lowerName, element, context) {
9051
+ if (ns === SVG_NS3) {
9052
+ if (context === 1 /* Svg */) return !isBreakout(lowerName, element);
9053
+ return lowerName === "svg" && (context === 0 /* Html */ || context === 3 /* Annotation */);
9054
+ }
9055
+ if (ns === MATHML_NS) {
9056
+ if (context === 2 /* Math */ || context === 3 /* Annotation */) return !isBreakout(lowerName, element);
9057
+ return lowerName === "math" && context === 0 /* Html */;
9058
+ }
9059
+ return context === 0 /* Html */;
9060
+ }
9061
+ function childParseContext(ns, lowerName, element) {
9062
+ if (ns === SVG_NS3) {
9063
+ return lowerName === "foreignobject" || lowerName === "desc" || lowerName === "title" ? 0 /* Html */ : 1 /* Svg */;
9064
+ }
9065
+ if (ns === MATHML_NS) {
9066
+ if (lowerName === "mi" || lowerName === "mo" || lowerName === "mn" || lowerName === "ms" || lowerName === "mtext") {
9067
+ return 0 /* Html */;
9068
+ }
9069
+ if (lowerName === "annotation-xml") {
9070
+ const encoding = (element.getAttribute("encoding") ?? "").toLowerCase();
9071
+ return encoding === "text/html" || encoding === "application/xhtml+xml" ? 0 /* Html */ : 3 /* Annotation */;
9072
+ }
9073
+ return 2 /* Math */;
9074
+ }
9075
+ return 0 /* Html */;
9076
+ }
9077
+ function foreignAttrName(attr) {
9078
+ const ns = attr.namespaceURI;
9079
+ if (ns === XLINK_NS2) return `xlink:${attr.localName}`;
9080
+ if (ns === XML_NS2) return `xml:${attr.localName}`;
9081
+ if (ns === XMLNS_NS) return attr.localName === "xmlns" ? "xmlns" : `xmlns:${attr.localName}`;
9082
+ return attr.name;
9083
+ }
9084
+ function serializeOpenTag(element, tag, foreign) {
8879
9085
  let html2 = `<${tag}`;
8880
- const meta2 = tag === "meta" ? /* @__PURE__ */ new Map() : null;
9086
+ const meta2 = tag === "meta" && !foreign ? /* @__PURE__ */ new Map() : null;
9087
+ const embed2 = tag === "iframe" && !foreign ? getEmbedRecord(element) : void 0;
9088
+ const embedSeen = embed2 ? { sandbox: false, referrer: false, title: false, fullscreen: false } : null;
8881
9089
  const attrs = attributesOf(element);
8882
9090
  for (let i2 = 0; i2 < attrs.length; i2++) {
8883
9091
  const attr = attrs[i2];
8884
- const rawName = attr.name;
9092
+ const rawName = foreign ? foreignAttrName(attr) : attr.name;
8885
9093
  if (!isSafeAttrName(rawName)) continue;
8886
9094
  if (isEventHandlerAttr(rawName)) continue;
8887
9095
  if (isForbiddenSsrAttr(rawName)) continue;
8888
- const value = resolveAttributeValue(rawName.toLowerCase(), attr.value);
9096
+ const lowerName = rawName.toLowerCase();
9097
+ let value = resolveAttributeValue(lowerName, attr.value);
8889
9098
  if (value === null) continue;
9099
+ if (foreign && isRefusedAnimationAttribute(element, rawName, value)) continue;
9100
+ if (embed2 && embedSeen) {
9101
+ value = embedSerializedAttribute(embed2, embedSeen, lowerName, value);
9102
+ if (value === null) continue;
9103
+ }
8890
9104
  meta2?.set(rawName, value);
8891
9105
  html2 += ` ${rawName}="${escapeAttr(value)}"`;
8892
9106
  }
8893
9107
  if (meta2 && isForbiddenMetaSnapshot(meta2)) return null;
9108
+ if (embed2 && embedSeen) {
9109
+ const tail = embedSerializationTail(embed2, embedSeen);
9110
+ if (tail === null) return null;
9111
+ html2 += tail;
9112
+ }
8894
9113
  if (!getAttributeOf(element, "data-sibu-hydrate")) {
8895
9114
  html2 += ` data-sibu-ssr="true"`;
8896
9115
  }
8897
9116
  return html2;
8898
9117
  }
9118
+ function serializeNode(node, context) {
9119
+ if (node.nodeType === 3) return escapeHtml(node.textContent || "");
9120
+ if (node.nodeType === 8) return `<!--${safeCommentText(node.textContent || "")}-->`;
9121
+ let foreign = false;
9122
+ if (!(node instanceof HTMLElement)) {
9123
+ const ns2 = node.nodeType === 1 ? node.namespaceURI : null;
9124
+ if (ns2 !== SVG_NS3 && ns2 !== MATHML_NS) return escapeHtml(node.textContent || "");
9125
+ foreign = true;
9126
+ }
9127
+ const element = node;
9128
+ const tag = foreign ? element.localName : tagNameOf(element).toLowerCase();
9129
+ if (isCodeTextElement(tag)) return DEV ? `<!--ssr:${tag}-stripped-->` : "";
9130
+ if (!/^[a-z][a-z0-9-]*$/i.test(tag)) return DEV ? "<!--ssr:invalid-tag-->" : "";
9131
+ const ns = foreign ? element.namespaceURI : null;
9132
+ const lowerName = tag.toLowerCase();
9133
+ if (!fitsParseContext(ns, lowerName, element, context)) return DEV ? `<!--ssr:${tag}-misplaced-->` : "";
9134
+ const openTag = serializeOpenTag(element, tag, foreign);
9135
+ if (openTag === null) return DEV ? `<!--ssr:${tag}-stripped-->` : "";
9136
+ const children = childNodesOf(element);
9137
+ if (foreign ? children.length === 0 : VOID_ELEMENTS.has(tag)) return `${openTag} />`;
9138
+ return {
9139
+ open: `${openTag}>`,
9140
+ close: `</${tag}>`,
9141
+ children: Array.from(children),
9142
+ context: childParseContext(ns, lowerName, element)
9143
+ };
9144
+ }
8899
9145
  function renderToString(element) {
9146
+ return renderNodeToString(element, 0 /* Html */);
9147
+ }
9148
+ function renderNodeToString(element, context) {
8900
9149
  if (element instanceof DocumentFragment) {
8901
9150
  return Array.from(element.childNodes).map((child) => {
8902
9151
  try {
8903
- return renderToString(child);
9152
+ return renderNodeToString(child, context);
8904
9153
  } catch (err) {
8905
9154
  return ssrErrorComment(err);
8906
9155
  }
8907
9156
  }).join("");
8908
9157
  }
8909
- if (element.nodeType === 3) {
8910
- return escapeHtml(element.textContent || "");
8911
- }
8912
- if (element.nodeType === 8) {
8913
- return `<!--${safeCommentText(element.textContent || "")}-->`;
8914
- }
8915
- if (!(element instanceof HTMLElement)) {
8916
- return escapeHtml(element.textContent || "");
8917
- }
8918
- const tag = tagNameOf(element).toLowerCase();
8919
- if (isCodeTextElement(tag)) {
8920
- return DEV ? `<!--ssr:${tag}-stripped-->` : "";
8921
- }
8922
- if (!/^[a-z][a-z0-9-]*$/i.test(tag)) {
8923
- return DEV ? "<!--ssr:invalid-tag-->" : "";
8924
- }
8925
- const openTag = serializeOpenTag(element, tag);
8926
- if (openTag === null) return DEV ? `<!--ssr:${tag}-stripped-->` : "";
8927
- let html2 = openTag;
8928
- if (VOID_ELEMENTS.has(tag)) {
8929
- return `${html2} />`;
8930
- }
8931
- html2 += ">";
8932
- for (const child of Array.from(childNodesOf(element))) {
9158
+ const frame = serializeNode(element, context);
9159
+ if (typeof frame === "string") return frame;
9160
+ let html2 = frame.open;
9161
+ for (const child of frame.children) {
8933
9162
  try {
8934
- html2 += renderToString(child);
9163
+ html2 += renderNodeToString(child, frame.context);
8935
9164
  } catch (err) {
8936
9165
  html2 += ssrErrorComment(err);
8937
9166
  }
8938
9167
  }
8939
- html2 += `</${tag}>`;
8940
- return html2;
9168
+ return html2 + frame.close;
8941
9169
  }
8942
9170
  function hydrate(component, container, options = {}) {
8943
9171
  const clientTree = component();
@@ -9120,56 +9348,34 @@ function renderToDocument(component, options = {}) {
9120
9348
  </body>
9121
9349
  </html>`;
9122
9350
  }
9123
- async function* renderToStream(element) {
9351
+ function renderToStream(element) {
9352
+ return streamNode(element, 0 /* Html */);
9353
+ }
9354
+ async function* streamNode(element, context) {
9124
9355
  if (element instanceof DocumentFragment) {
9125
9356
  for (const child of Array.from(element.childNodes)) {
9126
9357
  try {
9127
- yield* renderToStream(child);
9358
+ yield* streamNode(child, context);
9128
9359
  } catch (err) {
9129
9360
  yield ssrErrorComment(err);
9130
9361
  }
9131
9362
  }
9132
9363
  return;
9133
9364
  }
9134
- if (element.nodeType === 3) {
9135
- yield escapeHtml(element.textContent || "");
9365
+ const frame = serializeNode(element, context);
9366
+ if (typeof frame === "string") {
9367
+ if (frame) yield frame;
9136
9368
  return;
9137
9369
  }
9138
- if (element.nodeType === 8) {
9139
- yield `<!--${safeCommentText(element.textContent || "")}-->`;
9140
- return;
9141
- }
9142
- if (!(element instanceof HTMLElement)) {
9143
- yield escapeHtml(element.textContent || "");
9144
- return;
9145
- }
9146
- const tag = tagNameOf(element).toLowerCase();
9147
- if (isCodeTextElement(tag)) {
9148
- if (DEV) yield `<!--ssr:${tag}-stripped-->`;
9149
- return;
9150
- }
9151
- if (!/^[a-z][a-z0-9-]*$/i.test(tag)) {
9152
- if (DEV) yield "<!--ssr:invalid-tag-->";
9153
- return;
9154
- }
9155
- const openTag = serializeOpenTag(element, tag);
9156
- if (openTag === null) {
9157
- if (DEV) yield `<!--ssr:${tag}-stripped-->`;
9158
- return;
9159
- }
9160
- if (VOID_ELEMENTS.has(tag)) {
9161
- yield `${openTag} />`;
9162
- return;
9163
- }
9164
- yield `${openTag}>`;
9165
- for (const child of Array.from(childNodesOf(element))) {
9370
+ yield frame.open;
9371
+ for (const child of frame.children) {
9166
9372
  try {
9167
- yield* renderToStream(child);
9373
+ yield* streamNode(child, frame.context);
9168
9374
  } catch (err) {
9169
9375
  yield ssrErrorComment(err);
9170
9376
  }
9171
9377
  }
9172
- yield `</${tag}>`;
9378
+ yield frame.close;
9173
9379
  }
9174
9380
  async function collectStream(stream2) {
9175
9381
  let result = "";
@@ -9329,8 +9535,8 @@ function escapeScriptJson(json) {
9329
9535
  return json.replace(/</g, "\\u003c").replace(/>/g, "\\u003e").replace(/&/g, "\\u0026").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
9330
9536
  }
9331
9537
  var DEFAULT_MAX_SSR_BYTES = 1024 * 1024;
9332
- function serializeState(state2, nonce, options) {
9333
- const rawJson = JSON.stringify(state2);
9538
+ function serializeState(state3, nonce, options) {
9539
+ const rawJson = JSON.stringify(state3);
9334
9540
  const maxBytes = options?.maxBytes ?? DEFAULT_MAX_SSR_BYTES;
9335
9541
  const byteLen = typeof TextEncoder !== "undefined" ? new TextEncoder().encode(rawJson).byteLength : Buffer.byteLength(rawJson, "utf8");
9336
9542
  if (byteLen > maxBytes) {
@@ -9441,8 +9647,8 @@ function normalizedStore(schema) {
9441
9647
  return ownGet(getState().entities, id);
9442
9648
  }
9443
9649
  function getAll() {
9444
- const state2 = getState();
9445
- return state2.ids.map((id) => state2.entities[id]);
9650
+ const state3 = getState();
9651
+ return state3.ids.map((id) => state3.entities[id]);
9446
9652
  }
9447
9653
  function update(id, partial) {
9448
9654
  const prev = getState();
@@ -9475,8 +9681,8 @@ function normalizedStore(schema) {
9475
9681
  });
9476
9682
  }
9477
9683
  function select3(predicate) {
9478
- const state2 = getState();
9479
- return state2.ids.map((id) => state2.entities[id]).filter(predicate);
9684
+ const state3 = getState();
9685
+ return state3.ids.map((id) => state3.entities[id]).filter(predicate);
9480
9686
  }
9481
9687
  return { add, addMany, get, getAll, update, remove, select: select3, getState };
9482
9688
  }
@@ -9938,7 +10144,7 @@ function setCanonical(url) {
9938
10144
  }
9939
10145
 
9940
10146
  // src/platform/customElement.ts
9941
- var SVG_NS3 = "http://www.w3.org/2000/svg";
10147
+ var SVG_NS4 = "http://www.w3.org/2000/svg";
9942
10148
  var MAX_RENDER_PASSES = 10;
9943
10149
  var ABANDONED_RENDER = /* @__PURE__ */ Symbol("sibujs.defineElement.abandonedRender");
9944
10150
  function defineElement(name, component, options = {}) {
@@ -10090,7 +10296,7 @@ function svgElement(tag, props = {}, ...nodes) {
10090
10296
  if (isBlockedElement(tag)) {
10091
10297
  throw new Error(`svgElement: refusing to create <${tag}> \u2014 tag is blocked for security reasons.`);
10092
10298
  }
10093
- const el = document.createElementNS(SVG_NS3, tag);
10299
+ const el = document.createElementNS(SVG_NS4, tag);
10094
10300
  for (const [key, value] of Object.entries(props)) {
10095
10301
  if (key === "nodes") continue;
10096
10302
  if (typeof value === "function" && isEventHandlerAttr(key)) {
@@ -10716,8 +10922,15 @@ function bindChildNode(placeholder, getter) {
10716
10922
  return reactiveBinding2(commit, placeholder);
10717
10923
  }
10718
10924
 
10925
+ // src/core/rendering/requireDocument.ts
10926
+ function noDocument() {
10927
+ throw new Error(
10928
+ "[SibuJS] renderToString needs a DOM: register happy-dom or jsdom globals first." + (DEV ? ' There is no global `document`, and SibuJS builds live DOM nodes, on the server too. For example: import { GlobalRegistrator } from "@happy-dom/global-registrator"; GlobalRegistrator.register(); See SSR in AGENTS.md \xA710.' : "")
10929
+ );
10930
+ }
10931
+
10719
10932
  // src/core/rendering/tagFactory.ts
10720
- var SVG_NS4 = "http://www.w3.org/2000/svg";
10933
+ var SVG_NS5 = "http://www.w3.org/2000/svg";
10721
10934
  var CLOBBER_RISKY_IDS = /* @__PURE__ */ new Set([
10722
10935
  "config",
10723
10936
  "location",
@@ -10896,6 +11109,7 @@ function tagFactory(tag, ns) {
10896
11109
  if (blocked) {
10897
11110
  throw new Error(`tagFactory: refusing to create <${tag}> \u2014 tag is blocked for security reasons.`);
10898
11111
  }
11112
+ if (typeof document === "undefined") noDocument();
10899
11113
  const el = ns ? document.createElementNS(ns, tag) : document.createElement(tag);
10900
11114
  if (first === void 0) return el;
10901
11115
  if (typeof first === "string") {
@@ -11071,7 +11285,7 @@ var param = tagFactory("param");
11071
11285
  var picture = tagFactory("picture");
11072
11286
  var portal = tagFactory("portal");
11073
11287
  var source = tagFactory("source");
11074
- var svg = tagFactory("svg", SVG_NS4);
11288
+ var svg = tagFactory("svg", SVG_NS5);
11075
11289
  var math = tagFactory("math");
11076
11290
  var canvas = tagFactory("canvas");
11077
11291
  var noscript = tagFactory("noscript");
@@ -11112,26 +11326,26 @@ var base = tagFactory("base");
11112
11326
  var link = tagFactory("link");
11113
11327
  var meta = tagFactory("meta");
11114
11328
  var style = tagFactory("style");
11115
- var circle = tagFactory("circle", SVG_NS4);
11116
- var ellipse = tagFactory("ellipse", SVG_NS4);
11117
- var g = tagFactory("g", SVG_NS4);
11118
- var line = tagFactory("line", SVG_NS4);
11119
- var path = tagFactory("path", SVG_NS4);
11120
- var polygon = tagFactory("polygon", SVG_NS4);
11121
- var polyline = tagFactory("polyline", SVG_NS4);
11122
- var rect = tagFactory("rect", SVG_NS4);
11123
- var text = tagFactory("text", SVG_NS4);
11124
- var tspan = tagFactory("tspan", SVG_NS4);
11125
- var defs = tagFactory("defs", SVG_NS4);
11126
- var clipPath = tagFactory("clipPath", SVG_NS4);
11127
- var mask = tagFactory("mask", SVG_NS4);
11128
- var pattern = tagFactory("pattern", SVG_NS4);
11129
- var linearGradient = tagFactory("linearGradient", SVG_NS4);
11130
- var radialGradient = tagFactory("radialGradient", SVG_NS4);
11131
- var stop = tagFactory("stop", SVG_NS4);
11132
- var use = tagFactory("use", SVG_NS4);
11133
- var symbol = tagFactory("symbol", SVG_NS4);
11134
- var marker = tagFactory("marker", SVG_NS4);
11329
+ var circle = tagFactory("circle", SVG_NS5);
11330
+ var ellipse = tagFactory("ellipse", SVG_NS5);
11331
+ var g = tagFactory("g", SVG_NS5);
11332
+ var line = tagFactory("line", SVG_NS5);
11333
+ var path = tagFactory("path", SVG_NS5);
11334
+ var polygon = tagFactory("polygon", SVG_NS5);
11335
+ var polyline = tagFactory("polyline", SVG_NS5);
11336
+ var rect = tagFactory("rect", SVG_NS5);
11337
+ var text = tagFactory("text", SVG_NS5);
11338
+ var tspan = tagFactory("tspan", SVG_NS5);
11339
+ var defs = tagFactory("defs", SVG_NS5);
11340
+ var clipPath = tagFactory("clipPath", SVG_NS5);
11341
+ var mask = tagFactory("mask", SVG_NS5);
11342
+ var pattern = tagFactory("pattern", SVG_NS5);
11343
+ var linearGradient = tagFactory("linearGradient", SVG_NS5);
11344
+ var radialGradient = tagFactory("radialGradient", SVG_NS5);
11345
+ var stop = tagFactory("stop", SVG_NS5);
11346
+ var use = tagFactory("use", SVG_NS5);
11347
+ var symbol = tagFactory("symbol", SVG_NS5);
11348
+ var marker = tagFactory("marker", SVG_NS5);
11135
11349
  var center = tagFactory("center");
11136
11350
  var font = tagFactory("font");
11137
11351
  var marquee = tagFactory("marquee");
@@ -11603,8 +11817,8 @@ function scrollRestoration(options) {
11603
11817
  nativeModeLease = acquireScrollRestorationMode("manual");
11604
11818
  if (currentKey !== null) tagCurrentEntry(currentKey);
11605
11819
  popstateHandler = (event) => {
11606
- const state2 = event.state ?? null;
11607
- const rawDestination = state2 ? state2[stateKey] : void 0;
11820
+ const state3 = event.state ?? null;
11821
+ const rawDestination = state3 ? state3[stateKey] : void 0;
11608
11822
  const destination = typeof rawDestination === "string" ? rawDestination : null;
11609
11823
  let outgoing = currentKey;
11610
11824
  if (outgoing === null && options?.getKey) {
@@ -12031,7 +12245,7 @@ var CDN_ENTRY_POINTS = {
12031
12245
  };
12032
12246
  var packageInfo = {
12033
12247
  name: "sibujs",
12034
- version: true ? "4.10.1" : "dev",
12248
+ version: true ? "4.12.0" : "dev",
12035
12249
  entryPoints: MODULE_ENTRY_POINTS,
12036
12250
  /**
12037
12251
  * Generate the package.json `exports` map. Module entries resolve to the
@@ -12176,7 +12390,7 @@ var env = {
12176
12390
  };
12177
12391
 
12178
12392
  // src/plugins/versioning.ts
12179
- var VERSION = true ? "4.10.1" : "dev";
12393
+ var VERSION = true ? "4.12.0" : "dev";
12180
12394
  var NUM = "(?:0|[1-9]\\d*)";
12181
12395
  var PRE_ID = `(?:${NUM}|\\d*[a-zA-Z-][0-9a-zA-Z-]*)`;
12182
12396
  var BUILD_ID = "[0-9a-zA-Z-]+";
@@ -13033,8 +13247,8 @@ function initDevTools(config) {
13033
13247
  function clearEvents() {
13034
13248
  eventLog.length = 0;
13035
13249
  }
13036
- function registerComponent(name, element, state2) {
13037
- hook.components.set(name, { element, state: state2 });
13250
+ function registerComponent(name, element, state3) {
13251
+ hook.components.set(name, { element, state: state3 });
13038
13252
  emit();
13039
13253
  }
13040
13254
  function unregisterComponent(name) {
@@ -15441,9 +15655,9 @@ function zustandAdapter(options) {
15441
15655
  return createPlugin("sibu-zustand", (ctx) => {
15442
15656
  const { store } = options;
15443
15657
  const [getState, setSibuState] = signal(store.getState());
15444
- const unsubscribe = store.subscribe((state2) => {
15658
+ const unsubscribe = store.subscribe((state3) => {
15445
15659
  batch(() => {
15446
- setSibuState(state2);
15660
+ setSibuState(state3);
15447
15661
  });
15448
15662
  });
15449
15663
  function select3(selector) {