@solidjs/web 2.0.0-beta.16 → 2.0.0-beta.17

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.
package/dist/dev.cjs CHANGED
@@ -509,22 +509,117 @@ function assign(node, props, skipChildren, prevProps = {}, skipRef = false) {
509
509
  prevProps[prop] = assignProp(node, prop, props[prop], prevProps[prop], skipRef, nodeName);
510
510
  }
511
511
  }
512
+ const ASSET_REMOVAL_GRACE = 100;
513
+ const assetRegistry = new Map();
514
+ function assetEntryKey(descriptor) {
515
+ if (descriptor.policy === "exclusive") return "x|" + descriptor.key;
516
+ return descriptor.type === "inline-style" ? "i|" + descriptor.id : descriptor.type + "|" + descriptor.href;
517
+ }
518
+ function findAssetElement(selector, attr, value) {
519
+ const nodes = document.querySelectorAll(selector);
520
+ for (let i = 0; i < nodes.length; i++) {
521
+ if (nodes[i].getAttribute(attr) === value) return nodes[i];
522
+ }
523
+ return null;
524
+ }
525
+ function mountAssetElement(descriptor) {
526
+ let el;
527
+ if (descriptor.type === "inline-style") {
528
+ el = findAssetElement("style[data-asset]", "data-asset", descriptor.id);
529
+ if (!el) {
530
+ el = document.createElement("style");
531
+ el.setAttribute("data-asset", descriptor.id);
532
+ el.textContent = descriptor.content || "";
533
+ }
534
+ } else {
535
+ const rel = descriptor.type === "module" ? "modulepreload" : "stylesheet";
536
+ el = findAssetElement(`link[rel="${rel}"]`, "href", descriptor.href);
537
+ if (!el) {
538
+ el = document.createElement("link");
539
+ el.rel = rel;
540
+ el.href = descriptor.href;
541
+ }
542
+ }
543
+ if (descriptor.attrs) {
544
+ for (const name in descriptor.attrs) el.setAttribute(name, descriptor.attrs[name]);
545
+ }
546
+ if (!el.isConnected) document.head.appendChild(el);
547
+ return el;
548
+ }
549
+ function acquireAsset(descriptor) {
550
+ const key = assetEntryKey(descriptor);
551
+ let entry = assetRegistry.get(key);
552
+ if (descriptor.policy === "exclusive") {
553
+ if (!entry) {
554
+ entry = {
555
+ original: descriptor.get(),
556
+ set: descriptor.set,
557
+ writers: []
558
+ };
559
+ assetRegistry.set(key, entry);
560
+ }
561
+ const writer = {
562
+ value: descriptor.value
563
+ };
564
+ entry.writers.push(writer);
565
+ entry.set(writer.value);
566
+ let released = false;
567
+ return () => {
568
+ if (released) return;
569
+ released = true;
570
+ const index = entry.writers.indexOf(writer);
571
+ const wasTop = index === entry.writers.length - 1;
572
+ entry.writers.splice(index, 1);
573
+ if (!wasTop) return;
574
+ if (entry.writers.length) {
575
+ entry.set(entry.writers[entry.writers.length - 1].value);
576
+ } else {
577
+ entry.set(entry.original);
578
+ assetRegistry.delete(key);
579
+ }
580
+ };
581
+ }
582
+ if (!entry) {
583
+ entry = {
584
+ count: 0,
585
+ element: null,
586
+ timer: null
587
+ };
588
+ assetRegistry.set(key, entry);
589
+ }
590
+ if (entry.timer) {
591
+ clearTimeout(entry.timer);
592
+ entry.timer = null;
593
+ }
594
+ entry.count++;
595
+ if (!entry.element || !entry.element.isConnected) entry.element = mountAssetElement(descriptor);
596
+ let released = false;
597
+ return () => {
598
+ if (released) return;
599
+ released = true;
600
+ if (--entry.count > 0) return;
601
+ entry.timer = setTimeout(() => {
602
+ assetRegistry.delete(key);
603
+ entry.element && entry.element.remove();
604
+ }, ASSET_REMOVAL_GRACE);
605
+ };
606
+ }
512
607
  function loadModuleAssets(mapping) {
513
608
  const hy = globalThis._$HY;
514
609
  if (!hy) return;
515
610
  const pending = [];
516
- for (const moduleUrl in mapping) {
517
- if (hy.modules[moduleUrl]) continue;
518
- const entryUrl = mapping[moduleUrl];
519
- if (!hy.loading[moduleUrl]) {
520
- hy.loading[moduleUrl] = import(entryUrl).then(mod => {
521
- hy.modules[moduleUrl] = mod;
611
+ for (const key in mapping) {
612
+ if (hy.modules[key]) continue;
613
+ const entryUrl = mapping[key];
614
+ if (!hy.loading[key]) {
615
+ hy.loading[key] = import(entryUrl).then(mod => {
616
+ hy.modules[key] = mod;
522
617
  }, err => {
523
- delete hy.loading[moduleUrl];
618
+ delete hy.loading[key];
524
619
  throw err;
525
620
  });
526
621
  }
527
- pending.push(hy.loading[moduleUrl]);
622
+ pending.push(hy.loading[key]);
528
623
  }
529
624
  return pending.length ? Promise.all(pending).then(() => {}) : undefined;
530
625
  }
@@ -863,7 +958,13 @@ function insertExpression(parent, value, current, marker) {
863
958
  const tc = typeof current;
864
959
  if (tc === "string" || tc === "number") {
865
960
  parent.firstChild.data = value;
866
- } else parent.textContent = value;
961
+ } else {
962
+ const owned = ownedChildCount(current);
963
+ if (owned === -1 || owned === parent.childNodes.length) parent.textContent = value;else {
964
+ removeOwnedChildren(parent, current);
965
+ parent.insertBefore(document.createTextNode(value), parent.firstChild);
966
+ }
967
+ }
867
968
  } else if (value === undefined) {
868
969
  cleanChildren(parent, current, marker);
869
970
  } else if (value.nodeType) {
@@ -886,7 +987,7 @@ function insertExpression(parent, value, current, marker) {
886
987
  appendNodes(parent, value, marker);
887
988
  } else reconcileArrays(parent, current, value, marker);
888
989
  } else {
889
- current && cleanChildren(parent);
990
+ current && cleanChildren(parent, current);
890
991
  appendNodes(parent, value);
891
992
  }
892
993
  } else console.warn(`Unrecognized value. Skipped inserting`, value);
@@ -926,8 +1027,31 @@ function appendNodes(parent, array, marker = null) {
926
1027
  if (marker) n[$$SLOT] = marker;
927
1028
  }
928
1029
  }
1030
+ function ownedChildCount(current) {
1031
+ if (Array.isArray(current)) return current.length;
1032
+ if (current == null) return -1;
1033
+ if (current === "") return 0;
1034
+ return 1;
1035
+ }
1036
+ function removeOwnedChildren(parent, current) {
1037
+ if (Array.isArray(current)) {
1038
+ for (let i = 0; i < current.length; i++) {
1039
+ const el = current[i];
1040
+ if (el.parentNode === parent) el.remove();
1041
+ }
1042
+ } else if (current.nodeType) {
1043
+ if (current.parentNode === parent) current.remove();
1044
+ } else {
1045
+ const first = parent.firstChild;
1046
+ if (first && first.nodeType === 3) first.remove();
1047
+ }
1048
+ }
929
1049
  function cleanChildren(parent, current, marker, replacement) {
930
- if (marker === undefined) return parent.textContent = "";
1050
+ if (marker === undefined) {
1051
+ const owned = ownedChildCount(current);
1052
+ if (owned === -1 || owned === parent.childNodes.length) return parent.textContent = "";
1053
+ return removeOwnedChildren(parent, current);
1054
+ }
931
1055
  if (current.length) {
932
1056
  let inserted = false;
933
1057
  for (let i = current.length - 1; i >= 0; i--) {
@@ -1134,6 +1258,7 @@ exports.RawTextElements = RawTextElements;
1134
1258
  exports.RequestContext = RequestContext;
1135
1259
  exports.SVGElements = SVGElements;
1136
1260
  exports.VoidElements = VoidElements;
1261
+ exports.acquireAsset = acquireAsset;
1137
1262
  exports.addEvent = addEvent;
1138
1263
  exports.applyRef = applyRef;
1139
1264
  exports.assign = assign;
package/dist/dev.js CHANGED
@@ -508,22 +508,117 @@ function assign(node, props, skipChildren, prevProps = {}, skipRef = false) {
508
508
  prevProps[prop] = assignProp(node, prop, props[prop], prevProps[prop], skipRef, nodeName);
509
509
  }
510
510
  }
511
+ const ASSET_REMOVAL_GRACE = 100;
512
+ const assetRegistry = new Map();
513
+ function assetEntryKey(descriptor) {
514
+ if (descriptor.policy === "exclusive") return "x|" + descriptor.key;
515
+ return descriptor.type === "inline-style" ? "i|" + descriptor.id : descriptor.type + "|" + descriptor.href;
516
+ }
517
+ function findAssetElement(selector, attr, value) {
518
+ const nodes = document.querySelectorAll(selector);
519
+ for (let i = 0; i < nodes.length; i++) {
520
+ if (nodes[i].getAttribute(attr) === value) return nodes[i];
521
+ }
522
+ return null;
523
+ }
524
+ function mountAssetElement(descriptor) {
525
+ let el;
526
+ if (descriptor.type === "inline-style") {
527
+ el = findAssetElement("style[data-asset]", "data-asset", descriptor.id);
528
+ if (!el) {
529
+ el = document.createElement("style");
530
+ el.setAttribute("data-asset", descriptor.id);
531
+ el.textContent = descriptor.content || "";
532
+ }
533
+ } else {
534
+ const rel = descriptor.type === "module" ? "modulepreload" : "stylesheet";
535
+ el = findAssetElement(`link[rel="${rel}"]`, "href", descriptor.href);
536
+ if (!el) {
537
+ el = document.createElement("link");
538
+ el.rel = rel;
539
+ el.href = descriptor.href;
540
+ }
541
+ }
542
+ if (descriptor.attrs) {
543
+ for (const name in descriptor.attrs) el.setAttribute(name, descriptor.attrs[name]);
544
+ }
545
+ if (!el.isConnected) document.head.appendChild(el);
546
+ return el;
547
+ }
548
+ function acquireAsset(descriptor) {
549
+ const key = assetEntryKey(descriptor);
550
+ let entry = assetRegistry.get(key);
551
+ if (descriptor.policy === "exclusive") {
552
+ if (!entry) {
553
+ entry = {
554
+ original: descriptor.get(),
555
+ set: descriptor.set,
556
+ writers: []
557
+ };
558
+ assetRegistry.set(key, entry);
559
+ }
560
+ const writer = {
561
+ value: descriptor.value
562
+ };
563
+ entry.writers.push(writer);
564
+ entry.set(writer.value);
565
+ let released = false;
566
+ return () => {
567
+ if (released) return;
568
+ released = true;
569
+ const index = entry.writers.indexOf(writer);
570
+ const wasTop = index === entry.writers.length - 1;
571
+ entry.writers.splice(index, 1);
572
+ if (!wasTop) return;
573
+ if (entry.writers.length) {
574
+ entry.set(entry.writers[entry.writers.length - 1].value);
575
+ } else {
576
+ entry.set(entry.original);
577
+ assetRegistry.delete(key);
578
+ }
579
+ };
580
+ }
581
+ if (!entry) {
582
+ entry = {
583
+ count: 0,
584
+ element: null,
585
+ timer: null
586
+ };
587
+ assetRegistry.set(key, entry);
588
+ }
589
+ if (entry.timer) {
590
+ clearTimeout(entry.timer);
591
+ entry.timer = null;
592
+ }
593
+ entry.count++;
594
+ if (!entry.element || !entry.element.isConnected) entry.element = mountAssetElement(descriptor);
595
+ let released = false;
596
+ return () => {
597
+ if (released) return;
598
+ released = true;
599
+ if (--entry.count > 0) return;
600
+ entry.timer = setTimeout(() => {
601
+ assetRegistry.delete(key);
602
+ entry.element && entry.element.remove();
603
+ }, ASSET_REMOVAL_GRACE);
604
+ };
605
+ }
511
606
  function loadModuleAssets(mapping) {
512
607
  const hy = globalThis._$HY;
513
608
  if (!hy) return;
514
609
  const pending = [];
515
- for (const moduleUrl in mapping) {
516
- if (hy.modules[moduleUrl]) continue;
517
- const entryUrl = mapping[moduleUrl];
518
- if (!hy.loading[moduleUrl]) {
519
- hy.loading[moduleUrl] = import(entryUrl).then(mod => {
520
- hy.modules[moduleUrl] = mod;
610
+ for (const key in mapping) {
611
+ if (hy.modules[key]) continue;
612
+ const entryUrl = mapping[key];
613
+ if (!hy.loading[key]) {
614
+ hy.loading[key] = import(entryUrl).then(mod => {
615
+ hy.modules[key] = mod;
521
616
  }, err => {
522
- delete hy.loading[moduleUrl];
617
+ delete hy.loading[key];
523
618
  throw err;
524
619
  });
525
620
  }
526
- pending.push(hy.loading[moduleUrl]);
621
+ pending.push(hy.loading[key]);
527
622
  }
528
623
  return pending.length ? Promise.all(pending).then(() => {}) : undefined;
529
624
  }
@@ -862,7 +957,13 @@ function insertExpression(parent, value, current, marker) {
862
957
  const tc = typeof current;
863
958
  if (tc === "string" || tc === "number") {
864
959
  parent.firstChild.data = value;
865
- } else parent.textContent = value;
960
+ } else {
961
+ const owned = ownedChildCount(current);
962
+ if (owned === -1 || owned === parent.childNodes.length) parent.textContent = value;else {
963
+ removeOwnedChildren(parent, current);
964
+ parent.insertBefore(document.createTextNode(value), parent.firstChild);
965
+ }
966
+ }
866
967
  } else if (value === undefined) {
867
968
  cleanChildren(parent, current, marker);
868
969
  } else if (value.nodeType) {
@@ -885,7 +986,7 @@ function insertExpression(parent, value, current, marker) {
885
986
  appendNodes(parent, value, marker);
886
987
  } else reconcileArrays(parent, current, value, marker);
887
988
  } else {
888
- current && cleanChildren(parent);
989
+ current && cleanChildren(parent, current);
889
990
  appendNodes(parent, value);
890
991
  }
891
992
  } else console.warn(`Unrecognized value. Skipped inserting`, value);
@@ -925,8 +1026,31 @@ function appendNodes(parent, array, marker = null) {
925
1026
  if (marker) n[$$SLOT] = marker;
926
1027
  }
927
1028
  }
1029
+ function ownedChildCount(current) {
1030
+ if (Array.isArray(current)) return current.length;
1031
+ if (current == null) return -1;
1032
+ if (current === "") return 0;
1033
+ return 1;
1034
+ }
1035
+ function removeOwnedChildren(parent, current) {
1036
+ if (Array.isArray(current)) {
1037
+ for (let i = 0; i < current.length; i++) {
1038
+ const el = current[i];
1039
+ if (el.parentNode === parent) el.remove();
1040
+ }
1041
+ } else if (current.nodeType) {
1042
+ if (current.parentNode === parent) current.remove();
1043
+ } else {
1044
+ const first = parent.firstChild;
1045
+ if (first && first.nodeType === 3) first.remove();
1046
+ }
1047
+ }
928
1048
  function cleanChildren(parent, current, marker, replacement) {
929
- if (marker === undefined) return parent.textContent = "";
1049
+ if (marker === undefined) {
1050
+ const owned = ownedChildCount(current);
1051
+ if (owned === -1 || owned === parent.childNodes.length) return parent.textContent = "";
1052
+ return removeOwnedChildren(parent, current);
1053
+ }
930
1054
  if (current.length) {
931
1055
  let inserted = false;
932
1056
  for (let i = current.length - 1; i >= 0; i--) {
@@ -1067,4 +1191,4 @@ function createElement(tagName, is = undefined) {
1067
1191
  });
1068
1192
  }
1069
1193
 
1070
- export { voidFn as Assets, ChildProperties, DOMElements, DOMWithState, DelegatedEvents, Dynamic, voidFn as HydrationScript, MathMLElements, Namespaces, Portal, RawTextElements, RequestContext, SVGElements, VoidElements, addEvent, applyRef, assign, className, delegateEvents, dynamic, dynamicProperty, effect, escape, voidFn as generateHydrationScript, voidFn as getAssets, getDelegatedRoot, getFirstChild, getHydrationKey, getNextElement, getNextMarker, getNextMatch, getNextSibling, voidFn as getRequestEvent, hydrate, insert, isDev, isServer, memo, mergeProps, ref, registerDelegatedContainer, registerDelegatedRoot, render, renderToStream, renderToString, renderToStringAsync, resolveSSRNode, runHydrationEvents, scope, setAttribute, setAttributeNS, setProperty, setStyleProperty, spread, ssr, ssrAttribute, ssrClassList, ssrElement, ssrHydrationKey, ssrStyle, style, template, unregisterDelegatedContainer, unregisterDelegatedRoot, voidFn as useAssets };
1194
+ export { voidFn as Assets, ChildProperties, DOMElements, DOMWithState, DelegatedEvents, Dynamic, voidFn as HydrationScript, MathMLElements, Namespaces, Portal, RawTextElements, RequestContext, SVGElements, VoidElements, acquireAsset, addEvent, applyRef, assign, className, delegateEvents, dynamic, dynamicProperty, effect, escape, voidFn as generateHydrationScript, voidFn as getAssets, getDelegatedRoot, getFirstChild, getHydrationKey, getNextElement, getNextMarker, getNextMatch, getNextSibling, voidFn as getRequestEvent, hydrate, insert, isDev, isServer, memo, mergeProps, ref, registerDelegatedContainer, registerDelegatedRoot, render, renderToStream, renderToString, renderToStringAsync, resolveSSRNode, runHydrationEvents, scope, setAttribute, setAttributeNS, setProperty, setStyleProperty, spread, ssr, ssrAttribute, ssrClassList, ssrElement, ssrHydrationKey, ssrStyle, style, template, unregisterDelegatedContainer, unregisterDelegatedRoot, voidFn as useAssets };
package/dist/server.cjs CHANGED
@@ -141,25 +141,48 @@ function createAssetTracking() {
141
141
  const boundaryModules = new Map();
142
142
  const boundaryStyles = new Map();
143
143
  const emittedAssets = new Set();
144
+ const inlineStyles = new Map();
144
145
  let currentBoundaryId = null;
145
146
  return {
146
147
  boundaryModules,
147
148
  boundaryStyles,
148
149
  emittedAssets,
150
+ inlineStyles,
151
+ registerInlineStyle(desc) {
152
+ let entry = inlineStyles.get(desc.id);
153
+ if (!entry) {
154
+ entry = {
155
+ id: desc.id,
156
+ content: desc.content || "",
157
+ attrs: desc.attrs,
158
+ emitted: false
159
+ };
160
+ inlineStyles.set(desc.id, entry);
161
+ }
162
+ if (currentBoundaryId) {
163
+ let styles = boundaryStyles.get(currentBoundaryId);
164
+ if (!styles) {
165
+ styles = new Set();
166
+ boundaryStyles.set(currentBoundaryId, styles);
167
+ }
168
+ styles.add(entry);
169
+ }
170
+ return entry;
171
+ },
149
172
  get currentBoundaryId() {
150
173
  return currentBoundaryId;
151
174
  },
152
175
  set currentBoundaryId(v) {
153
176
  currentBoundaryId = v;
154
177
  },
155
- registerModule(moduleUrl, entryUrl) {
178
+ registerModule(key, entryUrl) {
156
179
  const id = currentBoundaryId || "";
157
180
  let map = boundaryModules.get(id);
158
181
  if (!map) {
159
182
  map = {};
160
183
  boundaryModules.set(id, map);
161
184
  }
162
- map[moduleUrl] = entryUrl;
185
+ map[key] = entryUrl;
163
186
  },
164
187
  getBoundaryModules(id) {
165
188
  return boundaryModules.get(id) || null;
@@ -220,16 +243,20 @@ function renderToString(code, options = {}) {
220
243
  }
221
244
  serializer.write(id, p);
222
245
  },
223
- registerAsset(type, url) {
246
+ registerAsset(type, value) {
247
+ if (type === "inline-style") {
248
+ tracking.registerInlineStyle(value);
249
+ return;
250
+ }
224
251
  if (tracking.currentBoundaryId && type === "style") {
225
252
  let styles = tracking.boundaryStyles.get(tracking.currentBoundaryId);
226
253
  if (!styles) {
227
254
  styles = new Set();
228
255
  tracking.boundaryStyles.set(tracking.currentBoundaryId, styles);
229
256
  }
230
- styles.add(url);
257
+ styles.add(value);
231
258
  }
232
- tracking.emittedAssets.add(url);
259
+ tracking.emittedAssets.add(value);
233
260
  }
234
261
  };
235
262
  applyAssetTracking(solidJs.sharedConfig.context, tracking, manifest);
@@ -245,6 +272,7 @@ function renderToString(code, options = {}) {
245
272
  serializer.close();
246
273
  html = injectAssets(solidJs.sharedConfig.context.assets, html);
247
274
  html = injectPreloadLinks(tracking.emittedAssets, html);
275
+ html = injectInlineStyles(tracking.inlineStyles, html, nonce);
248
276
  if (scripts.length) html = injectScripts(html, scripts, options.nonce);
249
277
  return html;
250
278
  }
@@ -355,19 +383,27 @@ function renderToStream(code, options = {}) {
355
383
  async: true,
356
384
  assets: [],
357
385
  nonce,
358
- registerAsset(type, url) {
386
+ registerAsset(type, value) {
387
+ if (type === "inline-style") {
388
+ const entry = tracking.registerInlineStyle(value);
389
+ if (firstFlushed && !tracking.currentBoundaryId && !entry.emitted) {
390
+ entry.emitted = true;
391
+ buffer.write(renderInlineStyle(entry, nonce));
392
+ }
393
+ return;
394
+ }
359
395
  if (tracking.currentBoundaryId && type === "style") {
360
396
  let styles = tracking.boundaryStyles.get(tracking.currentBoundaryId);
361
397
  if (!styles) {
362
398
  styles = new Set();
363
399
  tracking.boundaryStyles.set(tracking.currentBoundaryId, styles);
364
400
  }
365
- styles.add(url);
401
+ styles.add(value);
366
402
  }
367
- if (!tracking.emittedAssets.has(url)) {
368
- tracking.emittedAssets.add(url);
403
+ if (!tracking.emittedAssets.has(value)) {
404
+ tracking.emittedAssets.add(value);
369
405
  if (firstFlushed && type === "module") {
370
- buffer.write(`<link rel="modulepreload" href="${url}">`);
406
+ buffer.write(`<link rel="modulepreload" href="${value}">`);
371
407
  }
372
408
  }
373
409
  },
@@ -451,10 +487,13 @@ function renderToStream(code, options = {}) {
451
487
  serializeFragmentAssets(key, tracking.boundaryModules, context);
452
488
  const styles = collectStreamStyles(key, tracking, headStyles);
453
489
  const deferActivation = !!revealGroup;
454
- if (styles.length) {
455
- emitTask(`$dfs("${key}",${styles.length},${deferActivation ? 1 : 0})`);
490
+ for (let i = 0; i < styles.inline.length; i++) {
491
+ buffer.write(renderInlineStyle(styles.inline[i], nonce));
492
+ }
493
+ if (styles.links.length) {
494
+ emitTask(`$dfs("${key}",${styles.links.length},${deferActivation ? 1 : 0})`);
456
495
  writeTasks();
457
- for (const url of styles) {
496
+ for (const url of styles.links) {
458
497
  buffer.write(`<link rel="stylesheet" href="${url}" onload="$dfc('${key}')" onerror="$dfc('${key}')">`);
459
498
  }
460
499
  buffer.write(`<template id="${key}">${value !== undefined ? value : " "}</template>`);
@@ -545,6 +584,7 @@ function renderToStream(code, options = {}) {
545
584
  if (url.endsWith(".css")) headStyles.add(url);
546
585
  }
547
586
  html = injectPreloadLinks(tracking.emittedAssets, html);
587
+ html = injectInlineStyles(tracking.inlineStyles, html, nonce);
548
588
  serializeRootAssets();
549
589
  if (tasks.length) html = injectScripts(html, tasks, nonce);
550
590
  buffer.write(html);
@@ -850,10 +890,11 @@ function ssrStyleProperty(name, value) {
850
890
  return value != null ? name + value : "";
851
891
  }
852
892
  function ssrElement(tag, props, children, needsId) {
893
+ const hk = needsId ? ssrHydrationKey() : "";
853
894
  if (props == null) props = {};else if (typeof props === "function") props = props();
854
895
  const skipChildren = VOID_ELEMENTS.test(tag);
855
896
  const keys = Object.keys(props);
856
- let result = `<${tag}${needsId ? ssrHydrationKey() : ""} `;
897
+ let result = `<${tag}${hk} `;
857
898
  for (let i = 0; i < keys.length; i++) {
858
899
  const prop = keys[i];
859
900
  if (ChildProperties.has(prop)) {
@@ -898,7 +939,10 @@ function escape(s, attr) {
898
939
  for (let i = 0; i < s.length; i++) s[i] = escape(s[i]);
899
940
  return s;
900
941
  }
901
- if (attr && t === "boolean") return s;
942
+ if (attr) {
943
+ if (s == null || t === "boolean" || t === "number") return s;
944
+ return escape(String(s), attr);
945
+ }
902
946
  return s;
903
947
  }
904
948
  const delimCode = attr ? 34 : 60;
@@ -1034,14 +1078,48 @@ function propagateBoundaryStyles(childKey, parentKey, tracking) {
1034
1078
  }
1035
1079
  function collectStreamStyles(key, tracking, headStyles) {
1036
1080
  const styles = tracking.getBoundaryStyles(key);
1037
- if (!styles) return [];
1038
- const result = [];
1039
- for (const url of styles) {
1040
- if (!headStyles || !headStyles.has(url)) {
1041
- result.push(url);
1081
+ const links = [];
1082
+ const inline = [];
1083
+ if (!styles) return {
1084
+ links,
1085
+ inline
1086
+ };
1087
+ for (const entry of styles) {
1088
+ if (typeof entry === "string") {
1089
+ if (!headStyles || !headStyles.has(entry)) links.push(entry);
1090
+ } else if (!entry.emitted) {
1091
+ entry.emitted = true;
1092
+ inline.push(entry);
1042
1093
  }
1043
1094
  }
1044
- return result;
1095
+ return {
1096
+ links,
1097
+ inline
1098
+ };
1099
+ }
1100
+ function escapeStyleContent(content) {
1101
+ return content.replace(/<\/(style)/gi, "<\\/$1");
1102
+ }
1103
+ function renderInlineStyle(entry, nonce) {
1104
+ let attrs = "";
1105
+ if (entry.attrs) {
1106
+ for (const name in entry.attrs) {
1107
+ attrs += ` ${name}="${escape(String(entry.attrs[name]), true)}"`;
1108
+ }
1109
+ }
1110
+ return `<style${nonce ? ` nonce="${nonce}"` : ""} data-asset="${escape(entry.id, true)}"${attrs}>${escapeStyleContent(entry.content)}</style>`;
1111
+ }
1112
+ function injectInlineStyles(inlineStyles, html, nonce) {
1113
+ if (!inlineStyles.size) return html;
1114
+ const index = html.indexOf("</head>");
1115
+ if (index === -1) return html;
1116
+ let out = "";
1117
+ for (const entry of inlineStyles.values()) {
1118
+ if (entry.emitted) continue;
1119
+ entry.emitted = true;
1120
+ out += renderInlineStyle(entry, nonce);
1121
+ }
1122
+ return out ? html.slice(0, index) + out + html.slice(index) : html;
1045
1123
  }
1046
1124
  function injectScripts(html, scripts, nonce) {
1047
1125
  const tag = `<script${nonce ? ` nonce="${nonce}"` : ""}>${scripts}</script>`;
@@ -1304,6 +1382,7 @@ exports.RawTextElements = RawTextElements;
1304
1382
  exports.RequestContext = RequestContext;
1305
1383
  exports.SVGElements = SVGElements;
1306
1384
  exports.VoidElements = VoidElements;
1385
+ exports.acquireAsset = notSup;
1307
1386
  exports.addEvent = notSup;
1308
1387
  exports.applyRef = applyRef;
1309
1388
  exports.assign = notSup;