sibujs 4.11.0 → 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-R244COCR.js → chunk-653KGQS2.js} +3 -3
  12. package/dist/chunk-AM6DZLBM.js +181 -0
  13. package/dist/{chunk-ADWDDJ5M.js → chunk-B2Y5BJSP.js} +1 -1
  14. package/dist/{chunk-KREPZR2U.js → chunk-CI4W6XAU.js} +4 -4
  15. package/dist/{chunk-NBBFF5VA.js → chunk-DFZL3AX7.js} +6 -6
  16. package/dist/{chunk-OJV2RW4D.js → chunk-EMB5PG7V.js} +1 -1
  17. package/dist/{chunk-3ACAAQIN.js → chunk-F2UWOZ6J.js} +4 -0
  18. package/dist/{chunk-REOAVT2M.js → chunk-HXT2RNH5.js} +1 -1
  19. package/dist/{chunk-F6B5CKF7.js → chunk-IHA62NGJ.js} +1 -1
  20. package/dist/{chunk-VZDMHDVA.js → chunk-LEUEKK4G.js} +2 -2
  21. package/dist/{chunk-WQ7M57JJ.js → chunk-LXBMVGVB.js} +3 -3
  22. package/dist/{chunk-RRKGQKPU.js → chunk-LYTUTXQP.js} +4 -4
  23. package/dist/{chunk-5IODQRR3.js → chunk-NAVLCP4S.js} +4 -4
  24. package/dist/{chunk-YXJHLMRH.js → chunk-NB7TFSJE.js} +5 -5
  25. package/dist/{chunk-5G53CC6L.js → chunk-QLG5IK7F.js} +4 -4
  26. package/dist/{chunk-KFJUMC3Q.js → chunk-RK7EPQPG.js} +1 -1
  27. package/dist/{chunk-LQ2C44YH.js → chunk-T5O2CUHV.js} +1 -1
  28. package/dist/{chunk-CHQPJY47.js → chunk-WFRQ6D7H.js} +1 -1
  29. package/dist/{chunk-3Z7AEJMQ.js → chunk-WH4U2VUE.js} +5 -3
  30. package/dist/{chunk-HMOPAC2Z.js → chunk-XX4BRMWF.js} +15 -3
  31. package/dist/{chunk-7V7VFT7E.js → chunk-ZJCHY2IB.js} +1 -1
  32. package/dist/{chunk-MCPL5WKQ.js → chunk-ZPY2UAKM.js} +3 -3
  33. package/dist/{chunk-DEUONJYR.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 +344 -109
  59. package/dist/plugins.d.cts +1 -1
  60. package/dist/plugins.d.ts +1 -1
  61. package/dist/plugins.js +15 -12
  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/ssr.cjs CHANGED
@@ -305,6 +305,10 @@ function getSSRStore() {
305
305
  }
306
306
  return fallbackStore;
307
307
  }
308
+ function getRequestStore() {
309
+ if (als) return als.getStore() ?? null;
310
+ return _shared.fallbackDepth > 0 ? fallbackStore : null;
311
+ }
308
312
  function isSSR() {
309
313
  return getSSRStore().ssr;
310
314
  }
@@ -867,6 +871,9 @@ function contextualAttributeRefusal(el, name, value, origin) {
867
871
  if (SVG_ANIMATION_ELEMENTS.has(local) && el.namespaceURI === SVG_NS) return animationRefusal(name, value);
868
872
  return ContextualRefusal.None;
869
873
  }
874
+ function isRefusedAnimationAttribute(el, name, value) {
875
+ return SVG_ANIMATION_ELEMENTS.has(el.localName) && el.namespaceURI === SVG_NS && animationRefusal(name, value) !== ContextualRefusal.None;
876
+ }
870
877
  function settleAttributeProvenance(el, name, origin) {
871
878
  if (el.localName !== "link" || canonicalAttrName(name) !== "href") return;
872
879
  if (origin !== "static" && el.hasAttribute("href")) runtimeHrefLinks.add(el);
@@ -876,6 +883,126 @@ function isForbiddenMetaSnapshot(attributes) {
876
883
  return resolveMetaRefreshPolicy(attributes).kind === "forbidden";
877
884
  }
878
885
 
886
+ // src/utils/globalSingleton.ts
887
+ function globalSingleton(key, create) {
888
+ const g2 = globalThis;
889
+ return g2[key] ?? (g2[key] = create());
890
+ }
891
+
892
+ // src/utils/embedPolicy.ts
893
+ var state2 = globalSingleton(/* @__PURE__ */ Symbol.for("sibujs.embed.v2"), () => ({
894
+ allowed: [],
895
+ frames: /* @__PURE__ */ new WeakMap()
896
+ }));
897
+ var REQUEST_CACHE = "embed";
898
+ function currentEmbedAllowlist() {
899
+ const scoped = getRequestStore()?.caches?.get(REQUEST_CACHE)?.get("allowed");
900
+ return scoped ?? state2.allowed;
901
+ }
902
+ function resolveEmbedSrc(value, allowed = currentEmbedAllowlist()) {
903
+ if (typeof value !== "string" || sanitizeUrl(value) === "") return null;
904
+ let url;
905
+ try {
906
+ url = new URL(value);
907
+ } catch {
908
+ return null;
909
+ }
910
+ if (url.protocol !== "https:" || url.username || url.password) return null;
911
+ if (typeof location !== "undefined" && url.origin === location.origin) return null;
912
+ for (const entry of allowed) {
913
+ if (url.origin !== entry.origin) continue;
914
+ const path2 = entry.path;
915
+ if (path2 === "" || url.pathname === path2 || url.pathname.startsWith(path2.endsWith("/") ? path2 : `${path2}/`)) {
916
+ return url.href;
917
+ }
918
+ }
919
+ return null;
920
+ }
921
+ var DEFAULT_EMBED_SANDBOX = [
922
+ "allow-scripts",
923
+ "allow-same-origin",
924
+ "allow-presentation",
925
+ "allow-popups",
926
+ "allow-popups-to-escape-sandbox"
927
+ ];
928
+ var EMBED_FEATURES = /* @__PURE__ */ new Set([
929
+ "accelerometer",
930
+ "autoplay",
931
+ "clipboard-write",
932
+ "encrypted-media",
933
+ "fullscreen",
934
+ "gyroscope",
935
+ "picture-in-picture",
936
+ "web-share"
937
+ ]);
938
+ function narrowEmbedSandbox(value) {
939
+ const out = [];
940
+ for (const token of value.toLowerCase().split(/[\t\n\f\r ]+/)) {
941
+ if (token && DEFAULT_EMBED_SANDBOX.includes(token) && !out.includes(token)) out.push(token);
942
+ }
943
+ return out.join(" ");
944
+ }
945
+ function narrowEmbedAllow(value) {
946
+ const granted = [];
947
+ const denied = [];
948
+ for (const directive of value.split(";")) {
949
+ const tokens = directive.trim().split(/[\t\n\f\r ]+/);
950
+ const feature = tokens[0];
951
+ if (!feature) continue;
952
+ const list = tokens.slice(1).map((token) => token.toLowerCase());
953
+ const grantsSrc = (list.length === 0 || list.includes("'src'") || list.includes("*")) && !list.includes("'none'");
954
+ if (!grantsSrc) denied.push(feature);
955
+ else if (EMBED_FEATURES.has(feature) && !granted.includes(feature)) granted.push(feature);
956
+ }
957
+ return granted.filter((feature) => !denied.includes(feature)).join("; ");
958
+ }
959
+ function getEmbedRecord(frame) {
960
+ return state2.frames.get(frame);
961
+ }
962
+ function intersect(current, permitted, separator) {
963
+ const allowed = permitted.split(separator);
964
+ return current.split(separator).filter((token) => token && allowed.includes(token)).join(separator);
965
+ }
966
+ function embedSerializedAttribute(record, seen, name, value) {
967
+ switch (name) {
968
+ case "src":
969
+ return resolveEmbedSrc(value, record.allowed);
970
+ case "title":
971
+ if (!value.trim()) return null;
972
+ seen.title = true;
973
+ return value;
974
+ case "sandbox":
975
+ seen.sandbox = true;
976
+ return intersect(narrowEmbedSandbox(value), record.sandbox, " ");
977
+ case "allow": {
978
+ const allow = intersect(narrowEmbedAllow(value), record.allow, "; ");
979
+ if (allow.split("; ").includes("fullscreen")) seen.fullscreen = true;
980
+ return allow || null;
981
+ }
982
+ case "referrerpolicy":
983
+ seen.referrer = true;
984
+ return value.trim().toLowerCase() === "no-referrer" ? "no-referrer" : record.referrer;
985
+ case "loading":
986
+ return value === "eager" ? "eager" : "lazy";
987
+ case "id":
988
+ case "class":
989
+ case "style":
990
+ case "width":
991
+ case "height":
992
+ return value;
993
+ default:
994
+ return name.startsWith("data-") || name.startsWith("aria-") ? value : null;
995
+ }
996
+ }
997
+ function embedSerializationTail(record, seen) {
998
+ if (!seen.title) return null;
999
+ let tail = "";
1000
+ if (!seen.sandbox) tail += ` sandbox="${record.sandbox}"`;
1001
+ if (!seen.referrer) tail += ` referrerpolicy="${record.referrer}"`;
1002
+ if (seen.fullscreen) tail += ' allowfullscreen=""';
1003
+ return tail;
1004
+ }
1005
+
879
1006
  // src/utils/guards.ts
880
1007
  function readOwnGlobal(key) {
881
1008
  if (typeof window === "undefined") return void 0;
@@ -1022,69 +1149,180 @@ function childNodesOf(node) {
1022
1149
  function getAttributeOf(el, name) {
1023
1150
  return nativeAccessors().getAttribute.call(el, name);
1024
1151
  }
1025
- function serializeOpenTag(element, tag) {
1152
+ var SVG_NS2 = "http://www.w3.org/2000/svg";
1153
+ var MATHML_NS = "http://www.w3.org/1998/Math/MathML";
1154
+ var XLINK_NS = "http://www.w3.org/1999/xlink";
1155
+ var XML_NS = "http://www.w3.org/XML/1998/namespace";
1156
+ var XMLNS_NS = "http://www.w3.org/2000/xmlns/";
1157
+ var BREAKOUT_TAGS = /* @__PURE__ */ new Set([
1158
+ "b",
1159
+ "big",
1160
+ "blockquote",
1161
+ "body",
1162
+ "br",
1163
+ "center",
1164
+ "code",
1165
+ "dd",
1166
+ "div",
1167
+ "dl",
1168
+ "dt",
1169
+ "em",
1170
+ "embed",
1171
+ "h1",
1172
+ "h2",
1173
+ "h3",
1174
+ "h4",
1175
+ "h5",
1176
+ "h6",
1177
+ "head",
1178
+ "hr",
1179
+ "i",
1180
+ "img",
1181
+ "li",
1182
+ "listing",
1183
+ "menu",
1184
+ "meta",
1185
+ "nobr",
1186
+ "ol",
1187
+ "p",
1188
+ "pre",
1189
+ "ruby",
1190
+ "s",
1191
+ "small",
1192
+ "span",
1193
+ "strong",
1194
+ "strike",
1195
+ "sub",
1196
+ "sup",
1197
+ "table",
1198
+ "tt",
1199
+ "u",
1200
+ "ul",
1201
+ "var"
1202
+ ]);
1203
+ function isBreakout(lowerName, element) {
1204
+ if (BREAKOUT_TAGS.has(lowerName)) return true;
1205
+ return lowerName === "font" && (element.hasAttribute("color") || element.hasAttribute("face") || element.hasAttribute("size"));
1206
+ }
1207
+ function fitsParseContext(ns, lowerName, element, context) {
1208
+ if (ns === SVG_NS2) {
1209
+ if (context === 1 /* Svg */) return !isBreakout(lowerName, element);
1210
+ return lowerName === "svg" && (context === 0 /* Html */ || context === 3 /* Annotation */);
1211
+ }
1212
+ if (ns === MATHML_NS) {
1213
+ if (context === 2 /* Math */ || context === 3 /* Annotation */) return !isBreakout(lowerName, element);
1214
+ return lowerName === "math" && context === 0 /* Html */;
1215
+ }
1216
+ return context === 0 /* Html */;
1217
+ }
1218
+ function childParseContext(ns, lowerName, element) {
1219
+ if (ns === SVG_NS2) {
1220
+ return lowerName === "foreignobject" || lowerName === "desc" || lowerName === "title" ? 0 /* Html */ : 1 /* Svg */;
1221
+ }
1222
+ if (ns === MATHML_NS) {
1223
+ if (lowerName === "mi" || lowerName === "mo" || lowerName === "mn" || lowerName === "ms" || lowerName === "mtext") {
1224
+ return 0 /* Html */;
1225
+ }
1226
+ if (lowerName === "annotation-xml") {
1227
+ const encoding = (element.getAttribute("encoding") ?? "").toLowerCase();
1228
+ return encoding === "text/html" || encoding === "application/xhtml+xml" ? 0 /* Html */ : 3 /* Annotation */;
1229
+ }
1230
+ return 2 /* Math */;
1231
+ }
1232
+ return 0 /* Html */;
1233
+ }
1234
+ function foreignAttrName(attr) {
1235
+ const ns = attr.namespaceURI;
1236
+ if (ns === XLINK_NS) return `xlink:${attr.localName}`;
1237
+ if (ns === XML_NS) return `xml:${attr.localName}`;
1238
+ if (ns === XMLNS_NS) return attr.localName === "xmlns" ? "xmlns" : `xmlns:${attr.localName}`;
1239
+ return attr.name;
1240
+ }
1241
+ function serializeOpenTag(element, tag, foreign) {
1026
1242
  let html2 = `<${tag}`;
1027
- const meta2 = tag === "meta" ? /* @__PURE__ */ new Map() : null;
1243
+ const meta2 = tag === "meta" && !foreign ? /* @__PURE__ */ new Map() : null;
1244
+ const embed2 = tag === "iframe" && !foreign ? getEmbedRecord(element) : void 0;
1245
+ const embedSeen = embed2 ? { sandbox: false, referrer: false, title: false, fullscreen: false } : null;
1028
1246
  const attrs = attributesOf(element);
1029
1247
  for (let i2 = 0; i2 < attrs.length; i2++) {
1030
1248
  const attr = attrs[i2];
1031
- const rawName = attr.name;
1249
+ const rawName = foreign ? foreignAttrName(attr) : attr.name;
1032
1250
  if (!isSafeAttrName(rawName)) continue;
1033
1251
  if (isEventHandlerAttr(rawName)) continue;
1034
1252
  if (isForbiddenSsrAttr(rawName)) continue;
1035
- const value = resolveAttributeValue(rawName.toLowerCase(), attr.value);
1253
+ const lowerName = rawName.toLowerCase();
1254
+ let value = resolveAttributeValue(lowerName, attr.value);
1036
1255
  if (value === null) continue;
1256
+ if (foreign && isRefusedAnimationAttribute(element, rawName, value)) continue;
1257
+ if (embed2 && embedSeen) {
1258
+ value = embedSerializedAttribute(embed2, embedSeen, lowerName, value);
1259
+ if (value === null) continue;
1260
+ }
1037
1261
  meta2?.set(rawName, value);
1038
1262
  html2 += ` ${rawName}="${escapeAttr(value)}"`;
1039
1263
  }
1040
1264
  if (meta2 && isForbiddenMetaSnapshot(meta2)) return null;
1265
+ if (embed2 && embedSeen) {
1266
+ const tail = embedSerializationTail(embed2, embedSeen);
1267
+ if (tail === null) return null;
1268
+ html2 += tail;
1269
+ }
1041
1270
  if (!getAttributeOf(element, "data-sibu-hydrate")) {
1042
1271
  html2 += ` data-sibu-ssr="true"`;
1043
1272
  }
1044
1273
  return html2;
1045
1274
  }
1275
+ function serializeNode(node, context) {
1276
+ if (node.nodeType === 3) return escapeHtml(node.textContent || "");
1277
+ if (node.nodeType === 8) return `<!--${safeCommentText(node.textContent || "")}-->`;
1278
+ let foreign = false;
1279
+ if (!(node instanceof HTMLElement)) {
1280
+ const ns2 = node.nodeType === 1 ? node.namespaceURI : null;
1281
+ if (ns2 !== SVG_NS2 && ns2 !== MATHML_NS) return escapeHtml(node.textContent || "");
1282
+ foreign = true;
1283
+ }
1284
+ const element = node;
1285
+ const tag = foreign ? element.localName : tagNameOf(element).toLowerCase();
1286
+ if (isCodeTextElement(tag)) return DEV ? `<!--ssr:${tag}-stripped-->` : "";
1287
+ if (!/^[a-z][a-z0-9-]*$/i.test(tag)) return DEV ? "<!--ssr:invalid-tag-->" : "";
1288
+ const ns = foreign ? element.namespaceURI : null;
1289
+ const lowerName = tag.toLowerCase();
1290
+ if (!fitsParseContext(ns, lowerName, element, context)) return DEV ? `<!--ssr:${tag}-misplaced-->` : "";
1291
+ const openTag = serializeOpenTag(element, tag, foreign);
1292
+ if (openTag === null) return DEV ? `<!--ssr:${tag}-stripped-->` : "";
1293
+ const children = childNodesOf(element);
1294
+ if (foreign ? children.length === 0 : VOID_ELEMENTS.has(tag)) return `${openTag} />`;
1295
+ return {
1296
+ open: `${openTag}>`,
1297
+ close: `</${tag}>`,
1298
+ children: Array.from(children),
1299
+ context: childParseContext(ns, lowerName, element)
1300
+ };
1301
+ }
1046
1302
  function renderToString(element) {
1303
+ return renderNodeToString(element, 0 /* Html */);
1304
+ }
1305
+ function renderNodeToString(element, context) {
1047
1306
  if (element instanceof DocumentFragment) {
1048
1307
  return Array.from(element.childNodes).map((child) => {
1049
1308
  try {
1050
- return renderToString(child);
1309
+ return renderNodeToString(child, context);
1051
1310
  } catch (err) {
1052
1311
  return ssrErrorComment(err);
1053
1312
  }
1054
1313
  }).join("");
1055
1314
  }
1056
- if (element.nodeType === 3) {
1057
- return escapeHtml(element.textContent || "");
1058
- }
1059
- if (element.nodeType === 8) {
1060
- return `<!--${safeCommentText(element.textContent || "")}-->`;
1061
- }
1062
- if (!(element instanceof HTMLElement)) {
1063
- return escapeHtml(element.textContent || "");
1064
- }
1065
- const tag = tagNameOf(element).toLowerCase();
1066
- if (isCodeTextElement(tag)) {
1067
- return DEV ? `<!--ssr:${tag}-stripped-->` : "";
1068
- }
1069
- if (!/^[a-z][a-z0-9-]*$/i.test(tag)) {
1070
- return DEV ? "<!--ssr:invalid-tag-->" : "";
1071
- }
1072
- const openTag = serializeOpenTag(element, tag);
1073
- if (openTag === null) return DEV ? `<!--ssr:${tag}-stripped-->` : "";
1074
- let html2 = openTag;
1075
- if (VOID_ELEMENTS.has(tag)) {
1076
- return `${html2} />`;
1077
- }
1078
- html2 += ">";
1079
- for (const child of Array.from(childNodesOf(element))) {
1315
+ const frame = serializeNode(element, context);
1316
+ if (typeof frame === "string") return frame;
1317
+ let html2 = frame.open;
1318
+ for (const child of frame.children) {
1080
1319
  try {
1081
- html2 += renderToString(child);
1320
+ html2 += renderNodeToString(child, frame.context);
1082
1321
  } catch (err) {
1083
1322
  html2 += ssrErrorComment(err);
1084
1323
  }
1085
1324
  }
1086
- html2 += `</${tag}>`;
1087
- return html2;
1325
+ return html2 + frame.close;
1088
1326
  }
1089
1327
  function hydrate(component, container, options = {}) {
1090
1328
  const clientTree = component();
@@ -1267,56 +1505,34 @@ function renderToDocument(component, options = {}) {
1267
1505
  </body>
1268
1506
  </html>`;
1269
1507
  }
1270
- async function* renderToStream(element) {
1508
+ function renderToStream(element) {
1509
+ return streamNode(element, 0 /* Html */);
1510
+ }
1511
+ async function* streamNode(element, context) {
1271
1512
  if (element instanceof DocumentFragment) {
1272
1513
  for (const child of Array.from(element.childNodes)) {
1273
1514
  try {
1274
- yield* renderToStream(child);
1515
+ yield* streamNode(child, context);
1275
1516
  } catch (err) {
1276
1517
  yield ssrErrorComment(err);
1277
1518
  }
1278
1519
  }
1279
1520
  return;
1280
1521
  }
1281
- if (element.nodeType === 3) {
1282
- yield escapeHtml(element.textContent || "");
1283
- return;
1284
- }
1285
- if (element.nodeType === 8) {
1286
- yield `<!--${safeCommentText(element.textContent || "")}-->`;
1287
- return;
1288
- }
1289
- if (!(element instanceof HTMLElement)) {
1290
- yield escapeHtml(element.textContent || "");
1291
- return;
1292
- }
1293
- const tag = tagNameOf(element).toLowerCase();
1294
- if (isCodeTextElement(tag)) {
1295
- if (DEV) yield `<!--ssr:${tag}-stripped-->`;
1296
- return;
1297
- }
1298
- if (!/^[a-z][a-z0-9-]*$/i.test(tag)) {
1299
- if (DEV) yield "<!--ssr:invalid-tag-->";
1522
+ const frame = serializeNode(element, context);
1523
+ if (typeof frame === "string") {
1524
+ if (frame) yield frame;
1300
1525
  return;
1301
1526
  }
1302
- const openTag = serializeOpenTag(element, tag);
1303
- if (openTag === null) {
1304
- if (DEV) yield `<!--ssr:${tag}-stripped-->`;
1305
- return;
1306
- }
1307
- if (VOID_ELEMENTS.has(tag)) {
1308
- yield `${openTag} />`;
1309
- return;
1310
- }
1311
- yield `${openTag}>`;
1312
- for (const child of Array.from(childNodesOf(element))) {
1527
+ yield frame.open;
1528
+ for (const child of frame.children) {
1313
1529
  try {
1314
- yield* renderToStream(child);
1530
+ yield* streamNode(child, frame.context);
1315
1531
  } catch (err) {
1316
1532
  yield ssrErrorComment(err);
1317
1533
  }
1318
1534
  }
1319
- yield `</${tag}>`;
1535
+ yield frame.close;
1320
1536
  }
1321
1537
  async function collectStream(stream) {
1322
1538
  let result = "";
@@ -1476,8 +1692,8 @@ function escapeScriptJson(json) {
1476
1692
  return json.replace(/</g, "\\u003c").replace(/>/g, "\\u003e").replace(/&/g, "\\u0026").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
1477
1693
  }
1478
1694
  var DEFAULT_MAX_SSR_BYTES = 1024 * 1024;
1479
- function serializeState(state2, nonce, options) {
1480
- const rawJson = JSON.stringify(state2);
1695
+ function serializeState(state3, nonce, options) {
1696
+ const rawJson = JSON.stringify(state3);
1481
1697
  const maxBytes = options?.maxBytes ?? DEFAULT_MAX_SSR_BYTES;
1482
1698
  const byteLen = typeof TextEncoder !== "undefined" ? new TextEncoder().encode(rawJson).byteLength : Buffer.byteLength(rawJson, "utf8");
1483
1699
  if (byteLen > maxBytes) {
@@ -2023,7 +2239,7 @@ function forEachSubscriber(signal2, visit) {
2023
2239
  }
2024
2240
 
2025
2241
  // src/reactivity/track.ts
2026
- var _runtimeVersion = true ? "4.11.0" : "dev";
2242
+ var _runtimeVersion = true ? "4.12.0" : "dev";
2027
2243
  var REGISTRY_KEY = /* @__PURE__ */ Symbol.for("sibujs.reactive.v1");
2028
2244
  function resolveReactiveApi() {
2029
2245
  const g2 = globalThis;
@@ -2227,12 +2443,6 @@ function effect(effectFn, options) {
2227
2443
  return () => disposeEffect(ctx);
2228
2444
  }
2229
2445
 
2230
- // src/utils/globalSingleton.ts
2231
- function globalSingleton(key, create) {
2232
- const g2 = globalThis;
2233
- return g2[key] ?? (g2[key] = create());
2234
- }
2235
-
2236
2446
  // src/utils/singletonResource.ts
2237
2447
  function singletonResource(io) {
2238
2448
  let original = null;
@@ -2561,7 +2771,7 @@ var isBatching = API2.isBatching;
2561
2771
  // src/core/signals/signal.ts
2562
2772
  var _g2 = globalThis;
2563
2773
  function signal(initial, options) {
2564
- const state2 = {
2774
+ const state3 = {
2565
2775
  value: initial,
2566
2776
  __v: 0,
2567
2777
  __sc: 0,
@@ -2574,57 +2784,57 @@ function signal(initial, options) {
2574
2784
  };
2575
2785
  const debugName = DEV ? options?.name : void 0;
2576
2786
  const equalsFn = options?.equals;
2577
- if (debugName) state2.__name = debugName;
2787
+ if (debugName) state3.__name = debugName;
2578
2788
  function get() {
2579
- recordDependency2(state2);
2580
- return state2.value;
2789
+ recordDependency2(state3);
2790
+ return state3.value;
2581
2791
  }
2582
- get.__signal = state2;
2792
+ get.__signal = state3;
2583
2793
  if (debugName) get.__name = debugName;
2584
2794
  let set;
2585
2795
  if (equalsFn) {
2586
2796
  set = (next) => {
2587
- const prev = state2.value;
2797
+ const prev = state3.value;
2588
2798
  const newValue = typeof next === "function" ? next(prev) : next;
2589
2799
  if (equalsFn(prev, newValue)) return;
2590
- state2.value = newValue;
2591
- state2.__v++;
2800
+ state3.value = newValue;
2801
+ state3.__v++;
2592
2802
  if (DEV) {
2593
2803
  const hook = _g2.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
2594
- if (hook) emitDevtools(hook, "signal:update", { signal: state2, name: debugName, oldValue: prev, newValue });
2804
+ if (hook) emitDevtools(hook, "signal:update", { signal: state3, name: debugName, oldValue: prev, newValue });
2595
2805
  }
2596
- if (!enqueueBatchedSignal(state2)) {
2597
- notifySubscribers2(state2);
2806
+ if (!enqueueBatchedSignal(state3)) {
2807
+ notifySubscribers2(state3);
2598
2808
  }
2599
2809
  };
2600
2810
  } else if (DEV) {
2601
2811
  set = (next) => {
2602
- const prev = state2.value;
2812
+ const prev = state3.value;
2603
2813
  const newValue = typeof next === "function" ? next(prev) : next;
2604
2814
  if (Object.is(newValue, prev)) return;
2605
- state2.value = newValue;
2606
- state2.__v++;
2815
+ state3.value = newValue;
2816
+ state3.__v++;
2607
2817
  const hook = _g2.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
2608
- if (hook) emitDevtools(hook, "signal:update", { signal: state2, name: debugName, oldValue: prev, newValue });
2609
- if (!enqueueBatchedSignal(state2)) {
2610
- notifySubscribers2(state2);
2818
+ if (hook) emitDevtools(hook, "signal:update", { signal: state3, name: debugName, oldValue: prev, newValue });
2819
+ if (!enqueueBatchedSignal(state3)) {
2820
+ notifySubscribers2(state3);
2611
2821
  }
2612
2822
  };
2613
2823
  } else {
2614
2824
  set = (next) => {
2615
- const prev = state2.value;
2825
+ const prev = state3.value;
2616
2826
  const newValue = typeof next === "function" ? next(prev) : next;
2617
2827
  if (Object.is(newValue, prev)) return;
2618
- state2.value = newValue;
2619
- state2.__v++;
2620
- if (!enqueueBatchedSignal(state2)) {
2621
- notifySubscribers2(state2);
2828
+ state3.value = newValue;
2829
+ state3.__v++;
2830
+ if (!enqueueBatchedSignal(state3)) {
2831
+ notifySubscribers2(state3);
2622
2832
  }
2623
2833
  };
2624
2834
  }
2625
2835
  if (DEV) {
2626
2836
  const hook = _g2.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
2627
- if (hook) emitDevtools(hook, "signal:create", { signal: state2, name: debugName, getter: get, initial });
2837
+ if (hook) emitDevtools(hook, "signal:create", { signal: state3, name: debugName, getter: get, initial });
2628
2838
  }
2629
2839
  return [get, set];
2630
2840
  }
@@ -2803,8 +3013,8 @@ function scrollRestoration(options) {
2803
3013
  nativeModeLease = acquireScrollRestorationMode("manual");
2804
3014
  if (currentKey !== null) tagCurrentEntry(currentKey);
2805
3015
  popstateHandler = (event) => {
2806
- const state2 = event.state ?? null;
2807
- const rawDestination = state2 ? state2[stateKey] : void 0;
3016
+ const state3 = event.state ?? null;
3017
+ const rawDestination = state3 ? state3[stateKey] : void 0;
2808
3018
  const destination = typeof rawDestination === "string" ? rawDestination : null;
2809
3019
  let outgoing = currentKey;
2810
3020
  if (outgoing === null && options?.getKey) {
@@ -2866,9 +3076,9 @@ function createMiddlewareChain() {
2866
3076
 
2867
3077
  // src/utils/setSafeAttribute.ts
2868
3078
  var HTML_NS2 = "http://www.w3.org/1999/xhtml";
2869
- var SVG_NS2 = "http://www.w3.org/2000/svg";
2870
- var XLINK_NS = "http://www.w3.org/1999/xlink";
2871
- var XML_NS = "http://www.w3.org/XML/1998/namespace";
3079
+ var SVG_NS3 = "http://www.w3.org/2000/svg";
3080
+ var XLINK_NS2 = "http://www.w3.org/1999/xlink";
3081
+ var XML_NS2 = "http://www.w3.org/XML/1998/namespace";
2872
3082
  var BOOLEAN_IDL_ATTRS = /* @__PURE__ */ new Set(["checked", "disabled", "selected"]);
2873
3083
  function isHtmlElement(el) {
2874
3084
  return el.namespaceURI === null || el.namespaceURI === HTML_NS2;
@@ -2890,10 +3100,10 @@ function setProp(el, key, val) {
2890
3100
  el[key] = val;
2891
3101
  }
2892
3102
  function namespaceFor(el, name) {
2893
- if (el.namespaceURI !== SVG_NS2) return null;
3103
+ if (el.namespaceURI !== SVG_NS3) return null;
2894
3104
  const lower = name.toLowerCase();
2895
- if (lower.startsWith("xlink:")) return XLINK_NS;
2896
- if (lower.startsWith("xml:")) return XML_NS;
3105
+ if (lower.startsWith("xlink:")) return XLINK_NS2;
3106
+ if (lower.startsWith("xml:")) return XML_NS2;
2897
3107
  return null;
2898
3108
  }
2899
3109
  function setSafeAttribute(el, name, value, options = {}) {
@@ -3166,8 +3376,15 @@ function bindChildNode(placeholder, getter) {
3166
3376
  return reactiveBinding2(commit, placeholder);
3167
3377
  }
3168
3378
 
3379
+ // src/core/rendering/requireDocument.ts
3380
+ function noDocument() {
3381
+ throw new Error(
3382
+ "[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.' : "")
3383
+ );
3384
+ }
3385
+
3169
3386
  // src/core/rendering/tagFactory.ts
3170
- var SVG_NS3 = "http://www.w3.org/2000/svg";
3387
+ var SVG_NS4 = "http://www.w3.org/2000/svg";
3171
3388
  var CLOBBER_RISKY_IDS = /* @__PURE__ */ new Set([
3172
3389
  "config",
3173
3390
  "location",
@@ -3346,6 +3563,7 @@ function tagFactory(tag, ns) {
3346
3563
  if (blocked) {
3347
3564
  throw new Error(`tagFactory: refusing to create <${tag}> \u2014 tag is blocked for security reasons.`);
3348
3565
  }
3566
+ if (typeof document === "undefined") noDocument();
3349
3567
  const el = ns ? document.createElementNS(ns, tag) : document.createElement(tag);
3350
3568
  if (first === void 0) return el;
3351
3569
  if (typeof first === "string") {
@@ -3521,7 +3739,7 @@ var param = tagFactory("param");
3521
3739
  var picture = tagFactory("picture");
3522
3740
  var portal = tagFactory("portal");
3523
3741
  var source = tagFactory("source");
3524
- var svg = tagFactory("svg", SVG_NS3);
3742
+ var svg = tagFactory("svg", SVG_NS4);
3525
3743
  var math = tagFactory("math");
3526
3744
  var canvas = tagFactory("canvas");
3527
3745
  var noscript = tagFactory("noscript");
@@ -3562,26 +3780,26 @@ var base = tagFactory("base");
3562
3780
  var link = tagFactory("link");
3563
3781
  var meta = tagFactory("meta");
3564
3782
  var style = tagFactory("style");
3565
- var circle = tagFactory("circle", SVG_NS3);
3566
- var ellipse = tagFactory("ellipse", SVG_NS3);
3567
- var g = tagFactory("g", SVG_NS3);
3568
- var line = tagFactory("line", SVG_NS3);
3569
- var path = tagFactory("path", SVG_NS3);
3570
- var polygon = tagFactory("polygon", SVG_NS3);
3571
- var polyline = tagFactory("polyline", SVG_NS3);
3572
- var rect = tagFactory("rect", SVG_NS3);
3573
- var text = tagFactory("text", SVG_NS3);
3574
- var tspan = tagFactory("tspan", SVG_NS3);
3575
- var defs = tagFactory("defs", SVG_NS3);
3576
- var clipPath = tagFactory("clipPath", SVG_NS3);
3577
- var mask = tagFactory("mask", SVG_NS3);
3578
- var pattern = tagFactory("pattern", SVG_NS3);
3579
- var linearGradient = tagFactory("linearGradient", SVG_NS3);
3580
- var radialGradient = tagFactory("radialGradient", SVG_NS3);
3581
- var stop = tagFactory("stop", SVG_NS3);
3582
- var use = tagFactory("use", SVG_NS3);
3583
- var symbol = tagFactory("symbol", SVG_NS3);
3584
- var marker = tagFactory("marker", SVG_NS3);
3783
+ var circle = tagFactory("circle", SVG_NS4);
3784
+ var ellipse = tagFactory("ellipse", SVG_NS4);
3785
+ var g = tagFactory("g", SVG_NS4);
3786
+ var line = tagFactory("line", SVG_NS4);
3787
+ var path = tagFactory("path", SVG_NS4);
3788
+ var polygon = tagFactory("polygon", SVG_NS4);
3789
+ var polyline = tagFactory("polyline", SVG_NS4);
3790
+ var rect = tagFactory("rect", SVG_NS4);
3791
+ var text = tagFactory("text", SVG_NS4);
3792
+ var tspan = tagFactory("tspan", SVG_NS4);
3793
+ var defs = tagFactory("defs", SVG_NS4);
3794
+ var clipPath = tagFactory("clipPath", SVG_NS4);
3795
+ var mask = tagFactory("mask", SVG_NS4);
3796
+ var pattern = tagFactory("pattern", SVG_NS4);
3797
+ var linearGradient = tagFactory("linearGradient", SVG_NS4);
3798
+ var radialGradient = tagFactory("radialGradient", SVG_NS4);
3799
+ var stop = tagFactory("stop", SVG_NS4);
3800
+ var use = tagFactory("use", SVG_NS4);
3801
+ var symbol = tagFactory("symbol", SVG_NS4);
3802
+ var marker = tagFactory("marker", SVG_NS4);
3585
3803
  var center = tagFactory("center");
3586
3804
  var font = tagFactory("font");
3587
3805
  var marquee = tagFactory("marquee");
package/dist/ssr.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- export { H as HydrateOptions, a as HydrationMismatch, T as TrustedHTML, c as collectStream, d as deserializeState, e as escapeScriptJson, h as hydrate, b as hydrateIslands, f as hydrateProgressively, i as isDangerousMetaRefresh, g as island, r as renderToDocument, j as renderToReadableStream, k as renderToStream, l as renderToString, m as renderToSuspenseStream, n as resetSSRState, s as serializeState, o as ssrSuspense, p as suspenseSwapScript, t as trustHTML } from './ssr-C8hgIAw7.cjs';
1
+ export { H as HydrateOptions, a as HydrationMismatch, T as TrustedHTML, c as collectStream, d as deserializeState, e as escapeScriptJson, h as hydrate, b as hydrateIslands, f as hydrateProgressively, i as isDangerousMetaRefresh, g as island, r as renderToDocument, j as renderToReadableStream, k as renderToStream, l as renderToString, m as renderToSuspenseStream, n as resetSSRState, s as serializeState, o as ssrSuspense, p as suspenseSwapScript, t as trustHTML } from './ssr-Db0Sgdu3.cjs';
2
2
  import { C as Component } from './types-CJFViL6Q.cjs';
3
3
 
4
4
  interface HeadProps {
package/dist/ssr.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { H as HydrateOptions, a as HydrationMismatch, T as TrustedHTML, c as collectStream, d as deserializeState, e as escapeScriptJson, h as hydrate, b as hydrateIslands, f as hydrateProgressively, i as isDangerousMetaRefresh, g as island, r as renderToDocument, j as renderToReadableStream, k as renderToStream, l as renderToString, m as renderToSuspenseStream, n as resetSSRState, s as serializeState, o as ssrSuspense, p as suspenseSwapScript, t as trustHTML } from './ssr-C8hgIAw7.js';
1
+ export { H as HydrateOptions, a as HydrationMismatch, T as TrustedHTML, c as collectStream, d as deserializeState, e as escapeScriptJson, h as hydrate, b as hydrateIslands, f as hydrateProgressively, i as isDangerousMetaRefresh, g as island, r as renderToDocument, j as renderToReadableStream, k as renderToStream, l as renderToString, m as renderToSuspenseStream, n as resetSSRState, s as serializeState, o as ssrSuspense, p as suspenseSwapScript, t as trustHTML } from './ssr-Db0Sgdu3.js';
2
2
  import { C as Component } from './types-CJFViL6Q.js';
3
3
 
4
4
  interface HeadProps {