@solidjs/web 2.0.0-rc.1 → 2.0.0-rc.3

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 (84) hide show
  1. package/dist/dev.cjs +116 -66
  2. package/dist/dev.js +109 -65
  3. package/dist/server.cjs +386 -109
  4. package/dist/server.js +378 -113
  5. package/dist/web.cjs +113 -64
  6. package/dist/web.js +106 -63
  7. package/frames/dist/client.cjs +100 -14
  8. package/frames/dist/client.dev.cjs +103 -14
  9. package/frames/dist/client.dev.js +104 -15
  10. package/frames/dist/client.js +101 -15
  11. package/frames/dist/server.cjs +285 -154
  12. package/frames/dist/server.js +287 -156
  13. package/package.json +20 -22
  14. package/serialization/dist/decode.cjs +22 -5
  15. package/serialization/dist/decode.js +23 -6
  16. package/serialization/dist/serialization.cjs +26 -13
  17. package/serialization/dist/serialization.js +26 -8
  18. package/serialization/types/index.d.ts +69 -157
  19. package/serialization/types/serializer-decode.d.ts +89 -112
  20. package/serialization/types/serializer.d.ts +94 -0
  21. package/serialization/types-cjs/index.d.cts +69 -157
  22. package/serialization/types-cjs/serializer-decode.d.cts +89 -112
  23. package/serialization/types-cjs/serializer.d.cts +94 -0
  24. package/server-functions/dist/client.cjs +48 -7
  25. package/server-functions/dist/client.js +48 -8
  26. package/server-functions/dist/server.cjs +76 -5
  27. package/server-functions/dist/server.dev.cjs +76 -5
  28. package/server-functions/dist/server.dev.js +76 -6
  29. package/server-functions/dist/server.js +76 -6
  30. package/types/client.d.ts +150 -290
  31. package/types/constants.d.ts +18 -0
  32. package/types/cookies.d.ts +31 -75
  33. package/types/frames/frame-client.d.ts +287 -259
  34. package/types/frames/frame-container-plugin.d.ts +71 -0
  35. package/types/frames/frame-sink.d.ts +58 -160
  36. package/types/frames/frame-transport.d.ts +161 -194
  37. package/types/frames/serializer-decode.d.ts +159 -0
  38. package/types/frames/serializer.d.ts +69 -157
  39. package/types/head.d.ts +16 -0
  40. package/types/index.d.ts +0 -65
  41. package/types/index.server.d.ts +125 -0
  42. package/types/jsx.d.ts +5 -13
  43. package/types/reconcile.d.ts +1 -0
  44. package/types/render.d.ts +4 -0
  45. package/types/response.d.ts +41 -153
  46. package/types/serializer-decode.d.ts +89 -112
  47. package/types/serializer.d.ts +69 -157
  48. package/types/server-functions/client.d.ts +101 -199
  49. package/types/server-functions/flash.d.ts +10 -30
  50. package/types/server-functions/registry.d.ts +63 -0
  51. package/types/server-functions/rich-args.d.ts +1 -10
  52. package/types/server-functions/server.d.ts +301 -518
  53. package/types/server-functions/shared.d.ts +112 -458
  54. package/types/server-mock.d.ts +13 -4
  55. package/types/server.d.ts +256 -427
  56. package/types-cjs/client.d.cts +150 -290
  57. package/types-cjs/constants.d.cts +18 -0
  58. package/types-cjs/cookies.d.cts +31 -75
  59. package/types-cjs/frames/frame-client.d.cts +287 -259
  60. package/types-cjs/frames/frame-container-plugin.d.cts +71 -0
  61. package/types-cjs/frames/frame-sink.d.cts +58 -160
  62. package/types-cjs/frames/frame-transport.d.cts +161 -194
  63. package/types-cjs/frames/serializer-decode.d.cts +159 -0
  64. package/types-cjs/frames/serializer.d.cts +69 -157
  65. package/types-cjs/head.d.cts +16 -0
  66. package/types-cjs/index.d.cts +0 -65
  67. package/types-cjs/index.server.d.cts +125 -0
  68. package/types-cjs/jsx.d.cts +5 -13
  69. package/types-cjs/reconcile.d.cts +1 -0
  70. package/types-cjs/render.d.cts +4 -0
  71. package/types-cjs/response.d.cts +41 -153
  72. package/types-cjs/serializer-decode.d.cts +89 -112
  73. package/types-cjs/serializer.d.cts +69 -157
  74. package/types-cjs/server-functions/client.d.cts +101 -199
  75. package/types-cjs/server-functions/flash.d.cts +10 -30
  76. package/types-cjs/server-functions/registry.d.cts +63 -0
  77. package/types-cjs/server-functions/rich-args.d.cts +1 -10
  78. package/types-cjs/server-functions/server.d.cts +301 -518
  79. package/types-cjs/server-functions/shared.d.cts +112 -458
  80. package/types-cjs/server-mock.d.cts +13 -4
  81. package/types-cjs/server.d.cts +256 -427
  82. package/LICENSE +0 -21
  83. package/types/core.d.ts +0 -6
  84. package/types-cjs/core.d.cts +0 -6
package/dist/server.js CHANGED
@@ -1,6 +1,6 @@
1
- import { createRenderEffect, createMemo, sharedConfig, createRoot, getOwner, ssrHandleError, runWithOwner, inServerComponentScope, creationStamp, createComponent, omit, getNextChildId, onCleanup, getProjectionTrace } from 'solid-js';
2
- export { Errored, For, Hydration, Loading, Match, NoHydration, Repeat, Reveal, Show, Switch, createComponent, getOwner, merge as mergeProps, ssrScope as scope, untrack } from 'solid-js';
3
- import { Feature, Serializer, getCrossReferenceHeader } from 'seroval';
1
+ import { createRenderEffect, createMemo, sharedConfig, createRoot, inServerComponentScope, getOwner, ssrHandleError, creationStamp, runWithOwner, createComponent, omit, getNextChildId, onCleanup, getProjectionTrace } from 'solid-js';
2
+ export { Errored, For, Hydration, Loading, Match, NoHydration, Repeat, Reveal, Show, Switch, createComponent, getOwner, merge as mergeProps, ssrScope as scope, sharedConfig, untrack } from 'solid-js';
3
+ import { Feature, createStream, Serializer, getCrossReferenceHeader } from 'seroval';
4
4
  import { AbortSignalPlugin, CustomEventPlugin, DOMExceptionPlugin, EventPlugin, FormDataPlugin, HeadersPlugin, ReadableStreamPlugin, RequestPlugin, ResponsePlugin, URLSearchParamsPlugin, URLPlugin } from 'seroval-plugins/web';
5
5
 
6
6
  const DOMWithState = {
@@ -56,14 +56,18 @@ const transparentOptions = {
56
56
  const syncOptions = {
57
57
  sync: true
58
58
  };
59
- const effect = (fn, effectFn, options) => createRenderEffect(fn, effectFn, options ? {
60
- sync: true,
61
- ...options,
62
- transparent: !options.scope
63
- } : transparentOptions);
64
- const memo = fn => createMemo(() => fn(), syncOptions);
59
+ function effect(fn, effectFn, options) {
60
+ createRenderEffect(fn, effectFn, options ? {
61
+ sync: true,
62
+ ...options,
63
+ transparent: !options.scope
64
+ } : transparentOptions);
65
+ }
66
+ function memo(fn) {
67
+ return createMemo(() => fn(), syncOptions);
68
+ }
65
69
 
66
- const STATE = Symbol.for("dom-expressions.container-trace-state");
70
+ const STATE = Symbol.for("solid.container-trace-state");
67
71
  const state = globalThis[STATE] || (globalThis[STATE] = {
68
72
  materialized: new WeakMap(),
69
73
  materializedValues: new WeakSet()
@@ -71,7 +75,10 @@ const state = globalThis[STATE] || (globalThis[STATE] = {
71
75
  function setContainerTraceResolver(fn) {
72
76
  state.resolveTrace = fn;
73
77
  }
74
- const TRACE = Symbol.for("dom-expressions.container-trace");
78
+ function setContainerTraceStreamMint(fn) {
79
+ state.streamOf = fn;
80
+ }
81
+ const TRACE = Symbol.for("solid.container-trace");
75
82
  function materialize(marker) {
76
83
  let value = state.materialized.get(marker.$tr);
77
84
  if (value === undefined) {
@@ -83,13 +90,14 @@ function materialize(marker) {
83
90
  }
84
91
  function parseTrace(value, ctx) {
85
92
  const trace = value[TRACE];
93
+ const sub = trace.subscribe();
86
94
  return {
87
95
  a: trace.array ? 1 : 0,
88
- i: ctx.parse(trace.subscribe())
96
+ i: ctx.parse(state.streamOf ? state.streamOf(sub) : sub)
89
97
  };
90
98
  }
91
99
  const ContainerTracePlugin = {
92
- tag: "dom-expressions/container-trace",
100
+ tag: "solid/container-trace",
93
101
  test(value) {
94
102
  return value != null && typeof value === "object" && TRACE in value;
95
103
  },
@@ -99,9 +107,10 @@ const ContainerTracePlugin = {
99
107
  },
100
108
  async async(value, ctx) {
101
109
  const trace = value[TRACE];
110
+ const sub = trace.subscribe();
102
111
  return {
103
112
  a: trace.array ? 1 : 0,
104
- i: await ctx.parse(trace.subscribe())
113
+ i: await ctx.parse(state.streamOf ? state.streamOf(sub) : sub)
105
114
  };
106
115
  },
107
116
  stream: parseTrace
@@ -119,6 +128,18 @@ const ContainerTracePlugin = {
119
128
  }
120
129
  };
121
130
 
131
+ setContainerTraceStreamMint(iterable => {
132
+ const stream = createStream();
133
+ (async () => {
134
+ try {
135
+ for await (const value of iterable) stream.next(value);
136
+ stream.return(undefined);
137
+ } catch (error) {
138
+ stream.throw(error);
139
+ }
140
+ })();
141
+ return stream;
142
+ });
122
143
  const DEFAULT_WEB_PLUGINS = Object.freeze([AbortSignalPlugin,
123
144
  CustomEventPlugin, DOMExceptionPlugin, EventPlugin,
124
145
  FormDataPlugin, HeadersPlugin, ReadableStreamPlugin, RequestPlugin, ResponsePlugin, URLSearchParamsPlugin, URLPlugin,
@@ -192,11 +213,14 @@ function isSafeError(value) {
192
213
  return !!(value && (typeof value === "object" || typeof value === "function") && value[SAFE_ERROR]);
193
214
  }
194
215
  const REVALIDATE_HEADER = "X-Revalidate";
195
- function initWithRevalidate(init) {
216
+ function initWithRevalidate(init = {}) {
217
+ const resolved = typeof init === "number" ? {
218
+ status: init
219
+ } : init;
196
220
  const {
197
221
  revalidate,
198
222
  ...responseInit
199
- } = init;
223
+ } = resolved;
200
224
  let headers;
201
225
  if (responseInit.headers && responseInit.headers.getSetCookie) {
202
226
  headers = new Headers();
@@ -222,9 +246,7 @@ function redirect(url, init = 302) {
222
246
  const {
223
247
  responseInit,
224
248
  headers
225
- } = initWithRevalidate(typeof init === "number" ? {
226
- status: init
227
- } : init);
249
+ } = initWithRevalidate(init);
228
250
  if (responseInit.status === undefined) {
229
251
  responseInit.status = 302;
230
252
  }
@@ -441,6 +463,7 @@ function registerEntryAssets(manifest) {
441
463
  const assets = resolveAssets(key, manifest);
442
464
  if (assets) {
443
465
  for (let i = 0; i < assets.css.length; i++) ctx.registerAsset("style", assets.css[i]);
466
+ for (let i = 1; i < assets.js.length; i++) ctx.registerAsset("module", assets.js[i]);
444
467
  }
445
468
  return;
446
469
  }
@@ -700,7 +723,7 @@ function emitHeadResource(registry, context, tracking, emitResource, nonce, desc
700
723
  if (!styles) tracking.boundaryStyles.set(tracking.currentBoundaryId, styles = new Set());
701
724
  styles.add(entry);
702
725
  }
703
- const markup = `<link${attrHtml}>`;
726
+ const markup = `<link${attrHtml}${nonceAttr(nonce, "style")}>`;
704
727
  if (emitResource) emitResource(markup, entry);else {
705
728
  registry.eagerHtml += markup;
706
729
  entry.emitted = true;
@@ -798,7 +821,7 @@ function headGroupSignature(winner) {
798
821
  }
799
822
  return sig;
800
823
  }
801
- function renderShellHead(registry, nonce, isPendingFragment) {
824
+ function renderShellHead(registry, nonce, isPendingFragment, noScripts) {
802
825
  commitHeadBoundary(registry, "", isPendingFragment);
803
826
  registry.shellFlushed = true;
804
827
  const winners = resolveHead(registry.committed);
@@ -808,8 +831,14 @@ function renderShellHead(registry, nonce, isPendingFragment) {
808
831
  let metas = "";
809
832
  let others = "";
810
833
  let scripts = "";
834
+ let title = null;
811
835
  for (const [identity, winner] of winners) {
812
836
  registry.flushed.set(identity, headGroupSignature(winner));
837
+ if (identity === "title") {
838
+ const children = winner.tags[0].props.children;
839
+ title = children == null ? "" : String(children);
840
+ continue;
841
+ }
813
842
  for (let i = 0; i < winner.tags.length; i++) {
814
843
  const t = winner.tags[i];
815
844
  const markup = renderHeadTagMarkup(t.tag, t.props, identity, nonce);
@@ -818,10 +847,12 @@ function renderShellHead(registry, nonce, isPendingFragment) {
818
847
  }
819
848
  return {
820
849
  prelude,
821
- html: registry.eagerHtml + links + metas + others + scripts
850
+ html: registry.eagerHtml + links + metas + others + scripts,
851
+ title,
852
+ noScripts
822
853
  };
823
854
  }
824
- function flushHeadFragment(registry, boundary) {
855
+ function flushHeadFragment(registry, boundary, nonce) {
825
856
  const groups = commitHeadBoundary(registry, boundary);
826
857
  if (!groups.length) return null;
827
858
  const winners = resolveHead(registry.committed);
@@ -852,12 +883,87 @@ function flushHeadFragment(registry, boundary) {
852
883
  if (v == null || v === false) continue;
853
884
  attrs[name] = v === true ? "" : String(v);
854
885
  }
886
+ if (nonce && !hasNonceProp(t.props)) {
887
+ const destination = nonceDestination(t.tag, t.props);
888
+ const value = destination && nonce[destination];
889
+ if (value) attrs.nonce = String(value);
890
+ }
855
891
  const children = t.props.children;
856
892
  ops.push(["a", identity, t.tag, attrs, children == null ? null : String(children)]);
857
893
  }
858
894
  }
859
895
  return ops.length ? ops : null;
860
896
  }
897
+ function normalizeNonce(nonce) {
898
+ if (nonce == null) return undefined;
899
+ if (typeof nonce === "string") {
900
+ const attr = nonce ? ` nonce="${escape(nonce, true)}"` : "";
901
+ return {
902
+ script: nonce,
903
+ style: nonce,
904
+ scriptAttr: attr,
905
+ styleAttr: attr
906
+ };
907
+ }
908
+ const script = nonce.script;
909
+ const style = nonce.style;
910
+ if (!script && !style) return undefined;
911
+ return {
912
+ script,
913
+ style,
914
+ scriptAttr: typeof script === "string" && script ? ` nonce="${escape(script, true)}"` : "",
915
+ styleAttr: typeof style === "string" && style ? ` nonce="${escape(style, true)}"` : ""
916
+ };
917
+ }
918
+ function destinationNonce(nonce, destination) {
919
+ if (nonce == null) return undefined;
920
+ if (typeof nonce === "string") return nonce || undefined;
921
+ const value = nonce[destination];
922
+ return typeof value === "string" && value ? value : undefined;
923
+ }
924
+ function scriptNonce(nonce) {
925
+ return destinationNonce(nonce, "script");
926
+ }
927
+ function styleNonce(nonce) {
928
+ return destinationNonce(nonce, "style");
929
+ }
930
+ function asciiLowerCase(value) {
931
+ return value.replace(/[A-Z]/g, c => String.fromCharCode(c.charCodeAt(0) + 32));
932
+ }
933
+ function hasNonceProp(props) {
934
+ for (const name in props) if (name.length === 5 && asciiLowerCase(name) === "nonce" && props[name] != null) return true;
935
+ return false;
936
+ }
937
+ function nonceDestination(tag, props) {
938
+ if (tag === "script") return "script";
939
+ if (tag === "style") return "style";
940
+ if (tag !== "link") return null;
941
+ const rel = props.rel;
942
+ if (typeof rel !== "string") return null;
943
+ const rels = asciiLowerCase(rel).split(/[\t\n\f\r ]+/);
944
+ if (rels.includes("stylesheet")) return "style";
945
+ const isModulePreload = rels.includes("modulepreload");
946
+ if (!isModulePreload && !rels.includes("preload")) return null;
947
+ const as = typeof props.as === "string" ? asciiLowerCase(props.as) : "";
948
+ if (as === "style") return "style";
949
+ if (as === "script") return "script";
950
+ if (!isModulePreload) return null;
951
+ switch (as) {
952
+ case "fetch":
953
+ case "font":
954
+ case "image":
955
+ case "json":
956
+ case "text":
957
+ case "track":
958
+ return null;
959
+ default:
960
+ return "script";
961
+ }
962
+ }
963
+ function nonceAttr(nonce, destination) {
964
+ if (!nonce || !destination) return "";
965
+ return destination === "script" ? nonce.scriptAttr : nonce.styleAttr;
966
+ }
861
967
  function renderHeadAttrHtml(props) {
862
968
  let attrs = "";
863
969
  for (const name in props) {
@@ -886,7 +992,7 @@ function headAttrRecord(props, skipRelHref) {
886
992
  function renderHeadTagMarkup(tag, props, identity, nonce) {
887
993
  let attrs = renderHeadAttrHtml(props);
888
994
  if (identity != null) attrs += ` data-dh="${escape(identity, true)}"`;
889
- if (nonce && (tag === "script" || tag === "style")) attrs += ` nonce="${nonce}"`;
995
+ if (nonce && !hasNonceProp(props)) attrs += nonceAttr(nonce, nonceDestination(tag, props));
890
996
  if (tag === "meta" || tag === "link" || tag === "base") return `<${tag}${attrs}>`;
891
997
  let body = props.children == null ? "" : String(props.children);
892
998
  if (tag === "script") body = body.replace(/<\/(script)/gi, "<\\/$1");else if (tag === "style") body = escapeStyleContent(body);else body = escape(body);
@@ -901,15 +1007,15 @@ function useHead(tags) {
901
1007
  }
902
1008
  const VOID_ELEMENTS = /^(?:area|base|br|col|embed|hr|img|input|keygen|link|menuitem|meta|param|source|track|wbr)$/i;
903
1009
  const REPLACE_SCRIPT = `function $df(e){return _$HY.f?_$HY.f(e):$dfr(e)}function $dfr(e,n,o,t){if(!(n=document.getElementById(e)))return 0;if(!(o=document.getElementById("pl-"+e)))return(_$HY.dq=_$HY.dq||{})[e]=1,0;for(;o&&(8!==o.nodeType||o.nodeValue!=="pl-"+e);)t=o.nextSibling,o.remove(),o=t;t=o.parentNode,o.replaceWith(n.content),n.remove(),(_$HY.v=_$HY.v||{})[e]=1,_$HY.fe(e,t),_$HY.hp&&_$HY.hp[e]&&($dh(_$HY.hp[e]),delete _$HY.hp[e]),$dfd();return 1}function $dfl(e,o,n){if(!(o=document.getElementById("pl-"+e)))return(_$HY.dlq=_$HY.dlq||{})[e]=1,0;if(o._$fl)return 1;for(n=o.nextSibling;n;){if(8===n.nodeType&&n.nodeValue==="pl-"+e){o.parentNode&&o.parentNode.insertBefore(o.content.cloneNode(!0),n),o._$fl=1,$dfd();return 1}n=n.nextSibling}return 0}function $dflj(e,i){for(i=0;i<e.length;i++)$dfl(e[i])}function $dfd(e,i){if(e=_$HY.dq){_$HY.dq=0;for(i in e)$df(i)}if(e=_$HY.dlq){_$HY.dlq=0;for(i in e)$dfl(i)}}function $dfs(e,c,d){(_$HY.sc=_$HY.sc||{})[e]=c,d&&((_$HY.sd=_$HY.sd||{})[e]=1)}function $dfg(e,g,i,k){if(!(g=_$HY.sg&&_$HY.sg[e]))return;for(i=0;i<g.length;i++)if(_$HY.sc&&_$HY.sc[g[i]]>0)return;for(i=0;i<g.length;i++)k=g[i],delete _$HY.sg[k],$df(k)}function $dfc(e){if(--_$HY.sc[e]<=0){delete _$HY.sc[e],_$HY.sg&&_$HY.sg[e]?$dfg(e):!(_$HY.sd&&_$HY.sd[e])&&$df(e);_$HY.sd&&delete _$HY.sd[e]}}function $dfj(e,i,n){for(i=0;i<e.length;i++)if(_$HY.sc&&_$HY.sc[e[i]]>0){for(n=0;n<e.length;n++)(_$HY.sg=_$HY.sg||{})[e[n]]=e;return}for(i=0;i<e.length;i++)$df(e[i])}`;
904
- const HEAD_SCRIPT = `function $dha(o,i,e,n){for(i=0;i<o.length;i++)e=o[i],"t"==e[0]?((n=document.querySelector("title"))||(n=document.createElement("title"),document.head.appendChild(n)),n.textContent=e[1],n.setAttribute("data-dh","title")):"r"==e[0]?$dhr(e[1]):(n=document.createElement(e[2]),Object.keys(e[3]).forEach(function(a){n.setAttribute(a,e[3][a])}),null!=e[4]&&(n.textContent=e[4]),n.setAttribute("data-dh",e[1]),document.head.appendChild(n))}function $dhr(v,l,i){for(l=document.head.querySelectorAll("[data-dh]"),i=0;i<l.length;i++)l[i].getAttribute("data-dh")==v&&l[i].remove()}function $dh(o){_$HY.h?_$HY.h(o):$dha(o)}`;
1010
+ const HEAD_SCRIPT = `function $dha(o,i,e,n){for(i=0;i<o.length;i++)e=o[i],"t"==e[0]?((n=document.querySelector("title"))?n.hasAttribute("data-dh")||n.setAttribute("data-dhf",n.textContent):(n=document.createElement("title"),document.head.appendChild(n)),n.textContent=e[1],n.setAttribute("data-dh","title")):"r"==e[0]?$dhr(e[1]):(n=document.createElement(e[2]),Object.keys(e[3]).forEach(function(a){n.setAttribute(a,e[3][a])}),null!=e[4]&&(n.textContent=e[4]),n.setAttribute("data-dh",e[1]),document.head.appendChild(n))}function $dhr(v,l,i){for(l=document.head.querySelectorAll("[data-dh]"),i=0;i<l.length;i++)l[i].getAttribute("data-dh")==v&&l[i].remove()}function $dh(o){_$HY.h?_$HY.h(o):$dha(o)}`;
905
1011
  function renderToString(code, options = {}) {
906
1012
  const {
907
1013
  renderId = "",
908
- nonce,
909
1014
  noScripts,
910
1015
  manifest,
911
1016
  onHead
912
1017
  } = options;
1018
+ const nonce = normalizeNonce(options.nonce);
913
1019
  let scripts = "";
914
1020
  const serializer = createHydrationSerializer({
915
1021
  scopeId: renderId,
@@ -926,7 +1032,7 @@ function renderToString(code, options = {}) {
926
1032
  const tracking = createAssetTracking();
927
1033
  const headRegistry = createHeadRegistry();
928
1034
  sharedConfig.context = {
929
- nonce,
1035
+ nonce: options.nonce,
930
1036
  escape: escape,
931
1037
  resolve: resolveSSRNode,
932
1038
  ssr: ssr,
@@ -967,12 +1073,11 @@ function renderToString(code, options = {}) {
967
1073
  serializeFragmentAssets("", tracking.boundaryModules, sharedConfig.context, renderId);
968
1074
  sharedConfig.context.noHydrate = true;
969
1075
  serializer.close();
970
- const head = renderShellHead(headRegistry, nonce, null);
1076
+ const head = renderShellHead(headRegistry, nonce, null, noScripts);
971
1077
  return assembleDocument(resolveSSRSelectValues(html), tracking.emittedAssets, tracking.inlineStyles, scripts.length ? scripts : "", nonce, head, onHead);
972
1078
  }
973
1079
  function renderToStream(code, options = {}) {
974
1080
  let {
975
- nonce,
976
1081
  onCompleteShell,
977
1082
  onCompleteAll,
978
1083
  renderId = "",
@@ -980,6 +1085,7 @@ function renderToStream(code, options = {}) {
980
1085
  manifest,
981
1086
  onHead
982
1087
  } = options;
1088
+ const nonce = normalizeNonce(options.nonce);
983
1089
  let dispose;
984
1090
  let dead = false;
985
1091
  const abandon = () => {
@@ -1004,6 +1110,32 @@ function renderToStream(code, options = {}) {
1004
1110
  } catch (_) {}
1005
1111
  abandon();
1006
1112
  };
1113
+ const coalesceWrites = (writeRaw, endRaw) => {
1114
+ let buf = "";
1115
+ let scheduled = false;
1116
+ const flush = () => {
1117
+ scheduled = false;
1118
+ if (!buf) return;
1119
+ const out = buf;
1120
+ buf = "";
1121
+ writeRaw(out);
1122
+ };
1123
+ return {
1124
+ write(payload) {
1125
+ buf += payload;
1126
+ if (buf.length >= 16384) return flush();
1127
+ if (!scheduled) {
1128
+ scheduled = true;
1129
+ deferFlush(flush);
1130
+ }
1131
+ },
1132
+ flush,
1133
+ end() {
1134
+ flush();
1135
+ endRaw();
1136
+ }
1137
+ };
1138
+ };
1007
1139
  const guardSink = w => ({
1008
1140
  write(payload) {
1009
1141
  if (dead) return;
@@ -1023,6 +1155,23 @@ function renderToStream(code, options = {}) {
1023
1155
  }
1024
1156
  });
1025
1157
  const blockingPromises = new Set();
1158
+ const canBatchStubs = !options.serializer && !options.sink;
1159
+ let stubBatch = null;
1160
+ const STUB_BATCH_KEY = "$B";
1161
+ const flushStubBatch = () => {
1162
+ if (!stubBatch) return;
1163
+ const batch = stubBatch;
1164
+ stubBatch = null;
1165
+ if (batch.size === 1) {
1166
+ const [id, p] = batch.entries().next().value;
1167
+ serializer.write(id, p);
1168
+ return;
1169
+ }
1170
+ const obj = {};
1171
+ for (const [id, p] of batch) obj[id] = p;
1172
+ serializer.write(STUB_BATCH_KEY, obj);
1173
+ pushTask(`(b=>{for(var k in b)_$HY.r[k]=b[k];delete _$HY.r["${STUB_BATCH_KEY}"]})(_$HY.r["${STUB_BATCH_KEY}"])`);
1174
+ };
1026
1175
  let headerEmitted = false;
1027
1176
  const pushTask = task => {
1028
1177
  if (noScripts) return;
@@ -1059,10 +1208,11 @@ function renderToStream(code, options = {}) {
1059
1208
  buffer.write(renderInlineStyle(styles.inline[i], nonce));
1060
1209
  }
1061
1210
  if (styles.links.length) {
1211
+ const styleAttr = nonceAttr(nonce, "style");
1062
1212
  emitTask(`$dfs("${key}",${styles.links.length},${deferActivation ? 1 : 0})`);
1063
1213
  writeTasks();
1064
1214
  for (const entry of styles.links) {
1065
- buffer.write(typeof entry === "string" ? `<link rel="stylesheet" href="${entry}" onload="$dfc('${key}')" onerror="$dfc('${key}')">` : `<link${entry.attrHtml} onload="$dfc('${key}')" onerror="$dfc('${key}')">`);
1215
+ buffer.write(typeof entry === "string" ? `<link rel="stylesheet" href="${entry}"${styleAttr} onload="$dfc('${key}')" onerror="$dfc('${key}')">` : `<link${entry.attrHtml}${styleAttr} onload="$dfc('${key}')" onerror="$dfc('${key}')">`);
1066
1216
  }
1067
1217
  buffer.write(`<template id="${key}">${value}</template>`);
1068
1218
  } else {
@@ -1077,7 +1227,7 @@ function renderToStream(code, options = {}) {
1077
1227
  },
1078
1228
  asset(type, value) {
1079
1229
  if (type === "module") {
1080
- buffer.write(`<link rel="modulepreload" href="${value}">`);
1230
+ buffer.write(`<link rel="modulepreload" href="${value}"${nonceAttr(nonce, "script")}>`);
1081
1231
  } else if (type === "inline-style") {
1082
1232
  buffer.write(renderInlineStyle(value, nonce));
1083
1233
  } else if (type === "head-tag") {
@@ -1112,6 +1262,7 @@ function renderToStream(code, options = {}) {
1112
1262
  context.live.end = null;
1113
1263
  end();
1114
1264
  }
1265
+ flushStubBatch();
1115
1266
  serializer.flush();
1116
1267
  }));
1117
1268
  }
@@ -1119,7 +1270,7 @@ function renderToStream(code, options = {}) {
1119
1270
  const registry = new Map();
1120
1271
  const writeTasks = () => {
1121
1272
  if (tasks.length && !completed && firstFlushed) {
1122
- buffer.write(`<script${nonce ? ` nonce="${nonce}"` : ""}>${tasks}</script>`);
1273
+ buffer.write(`<script${nonceAttr(nonce, "script")}>${tasks}</script>`);
1123
1274
  tasks = "";
1124
1275
  }
1125
1276
  timer = null;
@@ -1173,7 +1324,7 @@ function renderToStream(code, options = {}) {
1173
1324
  };
1174
1325
  sharedConfig.context = context = {
1175
1326
  async: true,
1176
- nonce,
1327
+ nonce: options.nonce,
1177
1328
  live: {},
1178
1329
  registerHeadTags(tags) {
1179
1330
  registerHeadTags(headRegistry, context, tracking,
@@ -1231,10 +1382,18 @@ function renderToStream(code, options = {}) {
1231
1382
  },
1232
1383
  serialize(id, p, deferStream) {
1233
1384
  if (sharedConfig.context.noHydrate) return;
1234
- if (!firstFlushed && deferStream && typeof p === "object" && "then" in p) {
1235
- blockingPromises.add(p);
1236
- p.then(d => serializer.write(id, d)).catch(e => serializer.write(id, e));
1237
- } else serializer.write(id, p);
1385
+ if (!firstFlushed && p && typeof p === "object" && "then" in p) {
1386
+ if (deferStream) {
1387
+ blockingPromises.add(p);
1388
+ p.then(d => serializer.write(id, d)).catch(e => serializer.write(id, e));
1389
+ return;
1390
+ }
1391
+ if (canBatchStubs && !shellCompleted) {
1392
+ (stubBatch ||= new Map()).set(id, p);
1393
+ return;
1394
+ }
1395
+ }
1396
+ serializer.write(id, p);
1238
1397
  },
1239
1398
  escape: escape,
1240
1399
  resolve: resolveSSRNode,
@@ -1268,7 +1427,7 @@ function renderToStream(code, options = {}) {
1268
1427
  queue(flushEnd);
1269
1428
  }))
1270
1429
  });
1271
- serializer.write(key + "_fr", p);
1430
+ if (canBatchStubs && !shellCompleted) (stubBatch ||= new Map()).set(key + "_fr", p);else serializer.write(key + "_fr", p);
1272
1431
  }
1273
1432
  return (value, error) => {
1274
1433
  if (registry.has(key)) {
@@ -1299,7 +1458,7 @@ function renderToStream(code, options = {}) {
1299
1458
  } else {
1300
1459
  serializeFragmentAssets(key, tracking.boundaryModules, context);
1301
1460
  const styles = collectStreamStyles(key, tracking, headStyles);
1302
- const headOps = error ? null : flushHeadFragment(headRegistry, key);
1461
+ const headOps = error ? null : flushHeadFragment(headRegistry, key, nonce);
1303
1462
  if (headOps) emitHeadOps(key, headOps);
1304
1463
  sink.fragment(key, resolveSSRSelectValues(value !== undefined ? value : " "), {
1305
1464
  styles,
@@ -1385,14 +1544,17 @@ function renderToStream(code, options = {}) {
1385
1544
  function doShell() {
1386
1545
  if (shellCompleted) return;
1387
1546
  sharedConfig.context = context;
1547
+ const blockersBefore = blockingPromises.size;
1388
1548
  if (!resolveRootHoles()) return;
1549
+ if (blockingPromises.size !== blockersBefore) return;
1389
1550
  if (!headShellReady(headRegistry, p => blockingPromises.add(p))) return;
1390
1551
  headStyles = new Set();
1391
1552
  for (const url of tracking.emittedAssets) {
1392
1553
  if (isCssUrl(url)) headStyles.add(url);
1393
1554
  }
1394
1555
  serializeRootAssets();
1395
- const head = renderShellHead(headRegistry, nonce, k => registry.has(k));
1556
+ flushStubBatch();
1557
+ const head = renderShellHead(headRegistry, nonce, k => registry.has(k), noScripts);
1396
1558
  sink.shell(resolveSSRSelectValues(html), {
1397
1559
  preloads: tracking.emittedAssets,
1398
1560
  inlineStyles: tracking.inlineStyles,
@@ -1413,6 +1575,7 @@ function renderToStream(code, options = {}) {
1413
1575
  let drainTurn = 0;
1414
1576
  const scheduleFlush = fn => {
1415
1577
  const attempt = () => {
1578
+ flushStubBatch();
1416
1579
  if (registry.size !== lastRegistrySize || drainTurn++ < MIN_DRAIN_TURNS) {
1417
1580
  if (registry.size !== lastRegistrySize) drainTurn = 0;
1418
1581
  lastRegistrySize = registry.size;
@@ -1460,22 +1623,18 @@ function renderToStream(code, options = {}) {
1460
1623
  }
1461
1624
  };
1462
1625
  writer.closed && writer.closed.catch(failed);
1463
- writable = {
1464
- end() {
1465
- pendingWrites.then(() => {
1466
- ended = true;
1467
- writer.releaseLock();
1468
- w.close().catch(() => {});
1469
- resolve();
1470
- });
1471
- }
1472
- };
1473
- buffer = {
1474
- write(payload) {
1475
- pendingWrites = pendingWrites.then(() => writer.write(encoder.encode(payload))).catch(failed);
1476
- }
1477
- };
1626
+ buffer = writable = coalesceWrites(payload => {
1627
+ pendingWrites = pendingWrites.then(() => writer.write(encoder.encode(payload))).catch(failed);
1628
+ }, () => {
1629
+ pendingWrites.then(() => {
1630
+ ended = true;
1631
+ writer.releaseLock();
1632
+ w.close().catch(() => {});
1633
+ resolve();
1634
+ });
1635
+ });
1478
1636
  buffer.write(tmp);
1637
+ buffer.flush();
1479
1638
  firstFlushed = true;
1480
1639
  if (completed) {
1481
1640
  dispose();
@@ -1505,7 +1664,8 @@ function renderToStream(code, options = {}) {
1505
1664
  allSettled(blockingPromises).then(() => {
1506
1665
  scheduleFlush(() => {
1507
1666
  try {
1508
- if (!resolveRootHoles() || !headShellReady(headRegistry, p => blockingPromises.add(p))) return flush();
1667
+ const blockersBefore = blockingPromises.size;
1668
+ if (!resolveRootHoles() || blockingPromises.size !== blockersBefore || !headShellReady(headRegistry, p => blockingPromises.add(p))) return flush();
1509
1669
  } catch (err) {
1510
1670
  failRender(err);
1511
1671
  return resolve(tmp);
@@ -1534,8 +1694,10 @@ function renderToStream(code, options = {}) {
1534
1694
  return;
1535
1695
  }
1536
1696
  if (!shellCompleted) return flush();
1537
- buffer = writable = guardSink(w);
1697
+ const sink = guardSink(w);
1698
+ buffer = writable = coalesceWrites(sink.write, sink.end);
1538
1699
  buffer.write(tmp);
1700
+ buffer.flush();
1539
1701
  firstFlushed = true;
1540
1702
  if (completed) {
1541
1703
  dispose();
@@ -1562,9 +1724,7 @@ function renderToStream(code, options = {}) {
1562
1724
  };
1563
1725
  }
1564
1726
  function HydrationScript(props) {
1565
- const {
1566
- nonce
1567
- } = sharedConfig.context;
1727
+ const nonce = scriptNonce(sharedConfig.context && sharedConfig.context.nonce);
1568
1728
  return ssr(generateHydrationScript({
1569
1729
  nonce,
1570
1730
  ...props
@@ -1721,6 +1881,15 @@ function createLiveHoles(sink, scoped) {
1721
1881
  const stamp = typeof creationStamp === "function" ? creationStamp : () => 0;
1722
1882
  const inScope = scoped && typeof inServerComponentScope === "function" ? inServerComponentScope : null;
1723
1883
  const stripMarkers = html => html.replace(/<!--lh:\/?\d+-->/g, "");
1884
+ const swept = (owner, ctx, fn) => {
1885
+ const prev = sharedConfig.context;
1886
+ sharedConfig.context = ctx;
1887
+ try {
1888
+ return owner ? runWithOwner(owner, fn) : fn();
1889
+ } finally {
1890
+ sharedConfig.context = prev;
1891
+ }
1892
+ };
1724
1893
  function resolveHoleValue(hole) {
1725
1894
  const result = {
1726
1895
  t: [""],
@@ -1786,6 +1955,7 @@ function createLiveHoles(sink, scoped) {
1786
1955
  const recordsBefore = engine.recordStamp;
1787
1956
  const ownersBefore = stamp();
1788
1957
  const owner = getOwner();
1958
+ const holeCtx = sharedConfig.context;
1789
1959
  const b = {
1790
1960
  key: null,
1791
1961
  children: [],
@@ -1799,7 +1969,7 @@ function createLiveHoles(sink, scoped) {
1799
1969
  const sweepOwnersBefore = stamp();
1800
1970
  let res;
1801
1971
  try {
1802
- res = owner ? runWithOwner(owner, () => resolveHoleValue(hole)) : resolveHoleValue(hole);
1972
+ res = swept(owner, holeCtx, () => resolveHoleValue(hole));
1803
1973
  } catch (err) {
1804
1974
  b.closed = true;
1805
1975
  sink.closeBinding(b.key);
@@ -1907,6 +2077,7 @@ function createLiveHoles(sink, scoped) {
1907
2077
  },
1908
2078
  attr(cap) {
1909
2079
  const owner = getOwner();
2080
+ const holeCtx = sharedConfig.context;
1910
2081
  const b = {
1911
2082
  key: "lha:" + cap.id,
1912
2083
  children: [],
@@ -1942,7 +2113,7 @@ function createLiveHoles(sink, scoped) {
1942
2113
  if (vt === "string" || vt === "number") html += v;
1943
2114
  }
1944
2115
  };
1945
- owner ? runWithOwner(owner, run) : run();
2116
+ swept(owner, holeCtx, run);
1946
2117
  } catch (err) {
1947
2118
  if (ssrHandleError(err, true)) return;
1948
2119
  b.closed = true;
@@ -2278,6 +2449,32 @@ function ssrHydrationKey() {
2278
2449
  const hk = getHydrationKey();
2279
2450
  return hk ? ` _hk=${hk}` : "";
2280
2451
  }
2452
+ const CLAIM_PROP = /*#__PURE__*/Symbol.for("solid.claim-prop");
2453
+ const CLAIMS_STREAM = 1;
2454
+ const CLAIMS_DOCUMENT = 2;
2455
+ const CLAIM_UNSAFE = /[^A-Za-z0-9_.!~*'()-]/g;
2456
+ function encodeClaimKey(key) {
2457
+ return String(key).replace(CLAIM_UNSAFE, c => encodeURIComponent(c));
2458
+ }
2459
+ function ssrClaim(map) {
2460
+ const mode = sharedConfig.context && sharedConfig.context.claims;
2461
+ if (!mode || mode === CLAIMS_DOCUMENT && !(typeof inServerComponentScope === "function" && inServerComponentScope())) {
2462
+ return "";
2463
+ }
2464
+ let out = "";
2465
+ for (const pos in map) {
2466
+ const value = map[pos];
2467
+ const list = Array.isArray(value) ? value : [value];
2468
+ for (const fn of list) {
2469
+ const prop = typeof fn === "function" && fn[CLAIM_PROP] || undefined;
2470
+ if (prop === undefined) {
2471
+ continue;
2472
+ }
2473
+ out += `${out ? "," : ""}${pos}=${encodeClaimKey(prop)}`;
2474
+ }
2475
+ }
2476
+ return out ? ` _bnd="${out}"` : "";
2477
+ }
2281
2478
  function decodeSSREntities(s) {
2282
2479
  return s.indexOf("&") < 0 ? s : s.replace(/&quot;/g, '"').replace(/&lt;/g, "<").replace(/&amp;/g, "&");
2283
2480
  }
@@ -2310,22 +2507,49 @@ function tagIs(html, i, name) {
2310
2507
  const c = html.charCodeAt(i + 1 + name.length);
2311
2508
  return c === 32 || c === 62 || c === 9 || c === 10 || c === 13;
2312
2509
  }
2510
+ let selectValuesActive = false;
2511
+ function ssrSelectValues() {
2512
+ selectValuesActive = true;
2513
+ }
2313
2514
  function resolveSSRSelectValues(html) {
2314
- if (html.indexOf("<select") < 0) return html;
2515
+ if (!selectValuesActive) return html;
2516
+ let cand = html.indexOf("<select");
2517
+ if (cand < 0) return html;
2315
2518
  let out = "";
2316
2519
  let idx = 0;
2317
- let sel = null;
2318
- let i = html.indexOf("<");
2319
- while (i >= 0) {
2320
- let e;
2321
- if (html.charCodeAt(i + 1) === 33) {
2322
- e = html.charCodeAt(i + 2) === 45 ? html.indexOf("-->", i) : html.indexOf(">", i);
2323
- if (e < 0) break;
2324
- if (html.charCodeAt(i + 2) === 45) e += 2;
2325
- } else {
2326
- e = tagEnd(html, i);
2327
- if (e < 0) break;
2328
- if (sel) {
2520
+ while (cand >= 0) {
2521
+ if (!tagIs(html, cand, "select")) {
2522
+ cand = html.indexOf("<select", cand + 7);
2523
+ continue;
2524
+ }
2525
+ const e0 = tagEnd(html, cand);
2526
+ if (e0 < 0) break;
2527
+ const open = html.slice(cand, e0 + 1);
2528
+ const m = SELECT_VALUE_ATTR.exec(open);
2529
+ if (!m) {
2530
+ cand = html.indexOf("<select", e0 + 1);
2531
+ continue;
2532
+ }
2533
+ const bound = decodeSSREntities(m[1]);
2534
+ const sel = {
2535
+ values: /\smultiple(?=[\s>=])/.test(open) ? bound.split(",") : [bound],
2536
+ strip: cand + m.index,
2537
+ stripEnd: cand + m.index + m[0].length,
2538
+ body: e0 + 1,
2539
+ marks: [],
2540
+ defaulted: false
2541
+ };
2542
+ let committed = false;
2543
+ let i = html.indexOf("<", e0 + 1);
2544
+ while (i >= 0) {
2545
+ let e;
2546
+ if (html.charCodeAt(i + 1) === 33) {
2547
+ e = html.charCodeAt(i + 2) === 45 ? html.indexOf("-->", i) : html.indexOf(">", i);
2548
+ if (e < 0) break;
2549
+ if (html.charCodeAt(i + 2) === 45) e += 2;
2550
+ } else {
2551
+ e = tagEnd(html, i);
2552
+ if (e < 0) break;
2329
2553
  if (html.startsWith("</select>", i)) {
2330
2554
  out += html.slice(idx, sel.strip) + html.slice(sel.stripEnd, sel.body);
2331
2555
  let seg = sel.body;
@@ -2337,7 +2561,8 @@ function resolveSSRSelectValues(html) {
2337
2561
  }
2338
2562
  out += html.slice(seg, i);
2339
2563
  idx = i;
2340
- sel = null;
2564
+ committed = true;
2565
+ break;
2341
2566
  } else if (tagIs(html, i, "option")) {
2342
2567
  const attrs = html.slice(i + 7, e);
2343
2568
  if (/\sselected(?=[\s=]|$)/.test(attrs)) sel.defaulted = true;else {
@@ -2346,23 +2571,13 @@ function resolveSSRSelectValues(html) {
2346
2571
  if (sel.values.includes(value)) sel.marks.push(e);
2347
2572
  }
2348
2573
  }
2349
- } else if (tagIs(html, i, "select")) {
2350
- const m = SELECT_VALUE_ATTR.exec(html.slice(i, e + 1));
2351
- if (m) {
2352
- const bound = decodeSSREntities(m[1]);
2353
- sel = {
2354
- values: /\smultiple(?=[\s>=])/.test(html.slice(i, e + 1)) ? bound.split(",") : [bound],
2355
- strip: i + m.index,
2356
- stripEnd: i + m.index + m[0].length,
2357
- body: e + 1,
2358
- marks: [],
2359
- defaulted: false
2360
- };
2361
- }
2362
2574
  }
2575
+ i = html.indexOf("<", e + 1);
2363
2576
  }
2364
- i = html.indexOf("<", e + 1);
2577
+ if (!committed) break;
2578
+ cand = html.indexOf("<select", idx);
2365
2579
  }
2580
+ if (idx === 0) return html;
2366
2581
  return out + html.slice(idx);
2367
2582
  }
2368
2583
  function escape(s, attr) {
@@ -2386,22 +2601,20 @@ function escape(s, attr) {
2386
2601
  return escapeSlow(s, attr, i);
2387
2602
  }
2388
2603
  const ESCAPE_CONTENT = /[&<]/;
2389
- const ESCAPE_ATTR = /[&"]/;
2604
+ const ESCAPE_ATTR = /[&"<]/;
2390
2605
  function escapeSlow(s, attr, start) {
2391
- const delim = attr ? '"' : "<";
2392
- const delimCode = attr ? 34 : 60;
2393
- const escDelim = attr ? "&quot;" : "&lt;";
2606
+ if (attr) return escapeAttrSlow(s, start);
2394
2607
  const c0 = s.charCodeAt(start);
2395
- let iDelim = c0 === delimCode ? start : s.indexOf(delim, start);
2608
+ let iDelim = c0 === 60 ? start : s.indexOf("<", start);
2396
2609
  let iAmp = c0 === 38 ? start : s.indexOf("&", start);
2397
2610
  let left = 0,
2398
2611
  out = "";
2399
2612
  while (iDelim >= 0 && iAmp >= 0) {
2400
2613
  if (iDelim < iAmp) {
2401
2614
  if (left < iDelim) out += s.substring(left, iDelim);
2402
- out += escDelim;
2615
+ out += "&lt;";
2403
2616
  left = iDelim + 1;
2404
- iDelim = s.indexOf(delim, left);
2617
+ iDelim = s.indexOf("<", left);
2405
2618
  } else {
2406
2619
  if (left < iAmp) out += s.substring(left, iAmp);
2407
2620
  out += "&amp;";
@@ -2412,9 +2625,9 @@ function escapeSlow(s, attr, start) {
2412
2625
  if (iDelim >= 0) {
2413
2626
  do {
2414
2627
  if (left < iDelim) out += s.substring(left, iDelim);
2415
- out += escDelim;
2628
+ out += "&lt;";
2416
2629
  left = iDelim + 1;
2417
- iDelim = s.indexOf(delim, left);
2630
+ iDelim = s.indexOf("<", left);
2418
2631
  } while (iDelim >= 0);
2419
2632
  } else while (iAmp >= 0) {
2420
2633
  if (left < iAmp) out += s.substring(left, iAmp);
@@ -2424,6 +2637,36 @@ function escapeSlow(s, attr, start) {
2424
2637
  }
2425
2638
  return left < s.length ? out + s.substring(left) : out;
2426
2639
  }
2640
+ function escapeAttrSlow(s, start) {
2641
+ const c0 = s.charCodeAt(start);
2642
+ let iQuot = c0 === 34 ? start : s.indexOf('"', start);
2643
+ let iAmp = c0 === 38 ? start : s.indexOf("&", start);
2644
+ let iLt = c0 === 60 ? start : s.indexOf("<", start);
2645
+ let left = 0,
2646
+ out = "";
2647
+ for (;;) {
2648
+ let i = -1,
2649
+ ent;
2650
+ if (iQuot >= 0) {
2651
+ i = iQuot;
2652
+ ent = "&quot;";
2653
+ }
2654
+ if (iAmp >= 0 && (i < 0 || iAmp < i)) {
2655
+ i = iAmp;
2656
+ ent = "&amp;";
2657
+ }
2658
+ if (iLt >= 0 && (i < 0 || iLt < i)) {
2659
+ i = iLt;
2660
+ ent = "&lt;";
2661
+ }
2662
+ if (i < 0) break;
2663
+ if (left < i) out += s.substring(left, i);
2664
+ out += ent;
2665
+ left = i + 1;
2666
+ if (i === iQuot) iQuot = s.indexOf('"', left);else if (i === iAmp) iAmp = s.indexOf("&", left);else iLt = s.indexOf("<", left);
2667
+ }
2668
+ return left < s.length ? out + s.substring(left) : out;
2669
+ }
2427
2670
  function tryJoinPlainSSRArray(nodes) {
2428
2671
  if (nodes.length === 0) return undefined;
2429
2672
  let out = "";
@@ -2447,11 +2690,12 @@ function generateHydrationScript({
2447
2690
  eventNames = ["click", "input"],
2448
2691
  nonce
2449
2692
  } = {}) {
2450
- return `<script${nonce ? ` nonce="${nonce}"` : ""}>window._$HY||(e=>{let t=e=>e&&e.hasAttribute&&(e.hasAttribute("_hk")?e:t(e.host&&e.host.nodeType?e.host:e.parentNode));["${eventNames.join('","')}"].forEach((o=>document.addEventListener(o,(o=>{if(!e.events)return;let s=t(o.composedPath&&o.composedPath()[0]||o.target);s&&!e.completed.has(s)&&e.events.push([s,o])}))))})(_$HY={events:[],completed:new WeakSet,r:{},fe(){}});</script><!--xs-->`;
2693
+ return `<script${nonce ? ` nonce="${escape(String(nonce), true)}"` : ""}>window._$HY||(e=>{let t=e=>e&&e.hasAttribute&&(e.hasAttribute("_hk")?e:t(e.host&&e.host.nodeType?e.host:e.parentNode));["${eventNames.join('","')}"].forEach((o=>document.addEventListener(o,(o=>{if(!e.events)return;let s=t(o.composedPath&&o.composedPath()[0]||o.target);s&&!e.completed.has(s)&&e.events.push([s,o])}))))})(_$HY={events:[],completed:new WeakSet,r:{},fe(){}});</script><!--xs-->`;
2451
2694
  }
2452
2695
  function queue(fn) {
2453
2696
  return Promise.resolve().then(fn);
2454
2697
  }
2698
+ const deferFlush = typeof setImmediate === "function" ? setImmediate : fn => setTimeout(fn, 0);
2455
2699
  function allSettled(promises) {
2456
2700
  let size = promises.size;
2457
2701
  return Promise.allSettled(promises).then(() => {
@@ -2460,10 +2704,11 @@ function allSettled(promises) {
2460
2704
  });
2461
2705
  }
2462
2706
  function assembleDocument(html, emittedAssets, inlineStyles, scripts, nonce, headTags, onHead) {
2463
- const scriptTag = scripts ? `<script${nonce ? ` nonce="${nonce}"` : ""}>${scripts}</script>` : "";
2464
- const headTagsHtml = headTags ? headTags.html : "";
2707
+ const scriptTag = scripts ? `<script${nonceAttr(nonce, "script")}>${scripts}</script>` : "";
2708
+ const title = headTags ? headTags.title : null;
2709
+ let headTagsHtml = headTags ? headTags.html : "";
2465
2710
  const headPrelude = headTags ? headTags.prelude : "";
2466
- if (!onHead && !headTagsHtml && !headPrelude && !(emittedAssets && emittedAssets.size) && !(inlineStyles && inlineStyles.size)) {
2711
+ if (!onHead && title == null && !headTagsHtml && !headPrelude && !(emittedAssets && emittedAssets.size) && !(inlineStyles && inlineStyles.size)) {
2467
2712
  if (!scriptTag) return html;
2468
2713
  const xs = html.indexOf("<!--xs-->");
2469
2714
  return xs === -1 ? html + scriptTag : html.slice(0, xs) + scriptTag + html.slice(xs);
@@ -2475,15 +2720,33 @@ function assembleDocument(html, emittedAssets, inlineStyles, scripts, nonce, hea
2475
2720
  html = html.slice(0, at) + headPrelude + html.slice(at);
2476
2721
  }
2477
2722
  }
2478
- const headIdx = html.indexOf("</head>");
2723
+ let headIdx = html.indexOf("</head>");
2479
2724
  if (headIdx === -1) {
2480
2725
  if (onHead) {
2481
- onHead(headPrelude + headTagsHtml + renderHeadAssets(emittedAssets, inlineStyles, nonce));
2726
+ let titleHtml = "";
2727
+ if (title != null) {
2728
+ titleHtml = headTags.noScripts ? `<title data-dh="title">${escape(title)}</title>` : `<script${nonceAttr(nonce, "script")}>(function(x,t){(t=document.querySelector("title"))?(t.hasAttribute("data-dh")||t.setAttribute("data-dhf",t.textContent),t.textContent=x):(document.title=x,t=document.querySelector("title"));t&&t.setAttribute("data-dh","title")})(${JSON.stringify(title).replace(/</g, "\\u003C")})</script>`;
2729
+ }
2730
+ onHead(headPrelude + headTagsHtml + titleHtml + renderHeadAssets(emittedAssets, inlineStyles, nonce));
2482
2731
  }
2483
2732
  if (!scriptTag) return html;
2484
2733
  const xs = html.indexOf("<!--xs-->");
2485
2734
  return xs === -1 ? html + scriptTag : html.slice(0, xs) + scriptTag + html.slice(xs);
2486
2735
  }
2736
+ if (title != null) {
2737
+ const winner = escape(title);
2738
+ const open = html.match(/<head(?:\s[^>]*)?>/);
2739
+ const from = open ? open.index + open[0].length : 0;
2740
+ const m = /<title(\s[^>]*)?>([\s\S]*?)<\/title>/.exec(html.slice(from, headIdx));
2741
+ if (m) {
2742
+ const at = from + m.index;
2743
+ const stash = m[2].replace(/"/g, "&quot;");
2744
+ html = html.slice(0, at) + `<title${m[1] || ""} data-dh="title" data-dhf="${stash}">${winner}</title>` + html.slice(at + m[0].length);
2745
+ headIdx = html.indexOf("</head>");
2746
+ } else {
2747
+ headTagsHtml = `<title data-dh="title">${winner}</title>` + headTagsHtml;
2748
+ }
2749
+ }
2487
2750
  const head = headTagsHtml + renderHeadAssets(emittedAssets, inlineStyles, nonce);
2488
2751
  if (!scriptTag) return html.slice(0, headIdx) + head + html.slice(headIdx);
2489
2752
  const xsIdx = html.indexOf("<!--xs-->");
@@ -2492,9 +2755,11 @@ function assembleDocument(html, emittedAssets, inlineStyles, scripts, nonce, hea
2492
2755
  }
2493
2756
  function renderHeadAssets(emittedAssets, inlineStyles, nonce) {
2494
2757
  let head = "";
2758
+ const styleAttr = nonceAttr(nonce, "style");
2759
+ const scriptAttr = nonceAttr(nonce, "script");
2495
2760
  if (emittedAssets && emittedAssets.size) {
2496
2761
  for (const url of emittedAssets) {
2497
- head += isCssUrl(url) ? `<link rel="stylesheet" href="${url}">` : `<link rel="modulepreload" href="${url}">`;
2762
+ head += isCssUrl(url) ? `<link rel="stylesheet" href="${url}"${styleAttr}>` : `<link rel="modulepreload" href="${url}"${scriptAttr}>`;
2498
2763
  }
2499
2764
  }
2500
2765
  if (inlineStyles && inlineStyles.size) {
@@ -2556,12 +2821,15 @@ function escapeStyleContent(content) {
2556
2821
  }
2557
2822
  function renderInlineStyle(entry, nonce) {
2558
2823
  let attrs = "";
2824
+ let hasNonce = false;
2559
2825
  if (entry.attrs) {
2560
2826
  for (const name in entry.attrs) {
2827
+ if (name.length === 5 && asciiLowerCase(name) === "nonce") hasNonce = true;
2561
2828
  attrs += ` ${name}="${escape(String(entry.attrs[name]), true)}"`;
2562
2829
  }
2563
2830
  }
2564
- return `<style${nonce ? ` nonce="${nonce}"` : ""} data-asset="${escape(entry.id, true)}"${attrs}>${escapeStyleContent(entry.content)}</style>`;
2831
+ const nonceHtml = hasNonce ? "" : nonceAttr(nonce, "style");
2832
+ return `<style${nonceHtml} data-asset="${escape(entry.id, true)}"${attrs}>${escapeStyleContent(entry.content)}</style>`;
2565
2833
  }
2566
2834
  function waitForFragments(registry, key) {
2567
2835
  for (const k of [...registry.keys()].reverse()) {
@@ -2803,16 +3071,13 @@ function deriveHead(stub, responseInit = {}) {
2803
3071
  headers
2804
3072
  };
2805
3073
  }
2806
- function escapeAttribute(value) {
2807
- return value.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;");
2808
- }
2809
3074
  function createSSRResponse(result, event, options = {}) {
2810
3075
  const stub = event && event.response;
2811
3076
  const {
2812
3077
  responseInit,
2813
- nonce,
2814
3078
  transformChunk
2815
3079
  } = options;
3080
+ const nonce = normalizeNonce(options.nonce);
2816
3081
  if (typeof result === "string") {
2817
3082
  if (stub) commitResponseStub(stub);
2818
3083
  const head = deriveHead(stub, responseInit);
@@ -2882,7 +3147,7 @@ function createSSRResponse(result, event, options = {}) {
2882
3147
  if (closed || !controller) return;
2883
3148
  const location = stub && stub.headers.get("Location");
2884
3149
  if (location) {
2885
- const attr = nonce ? ` nonce="${escapeAttribute(nonce)}"` : "";
3150
+ const attr = nonceAttr(nonce, "script");
2886
3151
  enqueue(`<script${attr}>window.location=${JSON.stringify(location).replace(/</g, "\\u003c")}</script>`);
2887
3152
  }
2888
3153
  closed = true;
@@ -3063,4 +3328,4 @@ function httpHeader(name, value, options) {
3063
3328
  }
3064
3329
  }
3065
3330
 
3066
- export { ChildProperties, DOMElements, DOMWithState, DelegatedEvents, Dynamic, HREF, HydrationScript, MathMLElements, Namespaces, Portal, REVALIDATE_HEADER, RawTextElements, RequestContext, ResponseEnvelope, SAFE_ERROR, SVGElements, VoidElements, notSup as acquireAsset, notSup as addEvent, applyRef, notSup as assign, claimElement, claimElementTree, notSup as className, clearFlashCookie, clientOnly, commitEventResponse, commitResponseStub, composeMiddleware, createLiveHoles, createRequestEvent, createResponseStub, createSSRResponse, notSup as delegateEvents, dynamic, notSup as dynamicProperty, effect, escape, generateHydrationScript, notSup as getDelegatedRoot, getExpectedRedirectStatus, getHydrationKey, notSup as getNextElement, notSup as getNextMarker, notSup as getNextMatch, getRequestEvent, getServerFunctionMetadata, getServerFunctionRPC, hasFlashCookie, httpHeader, httpStatus, notSup as hydrate, notSup as insert, isDev, isHref, isResponseEnvelope, isSafeError, isServer, isServerFunction, markSafeError, memo, parseCookieHeader, redirect, notSup as ref, notSup as registerDelegatedContainer, notSup as registerDelegatedRoot, registerElementClaim, reload, notSup as render, renderToStream, renderToString, resolveSSRSelectValues, respond, notSup as runHydrationEvents, serializeCookie, notSup as setAttribute, notSup as setAttributeNS, notSup as setProperty, notSup as setStyleProperty, notSup as spread, ssr, ssrAttribute, ssrClassName, ssrElement, ssrGroup, ssrHydrationKey, ssrStyle, ssrStyleProperty, notSup as style, notSup as template, notSup as unregisterDelegatedContainer, notSup as unregisterDelegatedRoot, useHead };
3331
+ export { CLAIMS_DOCUMENT, CLAIMS_STREAM, CLAIM_PROP, ChildProperties, DOMElements, DOMWithState, DelegatedEvents, Dynamic, HREF, HydrationScript, MathMLElements, Namespaces, Portal, REVALIDATE_HEADER, RawTextElements, RequestContext, ResponseEnvelope, SAFE_ERROR, SVGElements, VoidElements, notSup as acquireAsset, notSup as addEvent, applyRef, notSup as assign, claimElement, claimElementTree, notSup as className, clearFlashCookie, clientOnly, commitEventResponse, commitResponseStub, composeMiddleware, createLiveHoles, createRequestEvent, createResponseStub, createSSRResponse, notSup as delegateEvents, dynamic, notSup as dynamicProperty, effect, escape, generateHydrationScript, notSup as getDelegatedRoot, getExpectedRedirectStatus, getHydrationKey, notSup as getNextElement, notSup as getNextMarker, notSup as getNextMatch, getRequestEvent, getServerFunctionMetadata, getServerFunctionRPC, hasFlashCookie, httpHeader, httpStatus, notSup as hydrate, notSup as insert, isDev, isHref, isResponseEnvelope, isSafeError, isServer, isServerFunction, markSafeError, memo, parseCookieHeader, redirect, notSup as ref, notSup as registerDelegatedContainer, notSup as registerDelegatedRoot, registerElementClaim, reload, notSup as render, renderToStream, renderToString, resolveSSRNode, resolveSSRSelectValues, respond, notSup as runHydrationEvents, scriptNonce, serializeCookie, notSup as setAttribute, notSup as setAttributeNS, notSup as setProperty, notSup as setStyleProperty, notSup as spread, ssr, ssrAttribute, ssrClaim, ssrClassName, ssrElement, ssrGroup, ssrHydrationKey, ssrSelectValues, ssrStyle, ssrStyleProperty, notSup as style, styleNonce, notSup as template, notSup as unregisterDelegatedContainer, notSup as unregisterDelegatedRoot, useHead };