@solidjs/web 2.0.0-rc.1 → 2.0.0-rc.2
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 +31 -6
- package/dist/dev.js +30 -7
- package/dist/server.cjs +353 -93
- package/dist/server.js +346 -97
- package/dist/web.cjs +31 -6
- package/dist/web.js +30 -7
- package/frames/dist/client.cjs +93 -7
- package/frames/dist/client.dev.cjs +96 -7
- package/frames/dist/client.dev.js +97 -8
- package/frames/dist/client.js +94 -8
- package/frames/dist/server.cjs +259 -138
- package/frames/dist/server.js +260 -139
- package/package.json +3 -3
- package/serialization/dist/decode.cjs +19 -2
- package/serialization/dist/decode.js +20 -3
- package/serialization/dist/serialization.cjs +19 -2
- package/serialization/dist/serialization.js +20 -3
- package/server-functions/dist/client.cjs +48 -7
- package/server-functions/dist/client.js +48 -8
- package/server-functions/dist/server.cjs +76 -5
- package/server-functions/dist/server.dev.cjs +76 -5
- package/server-functions/dist/server.dev.js +76 -6
- package/server-functions/dist/server.js +76 -6
- package/types/core.d.ts +3 -0
- package/types/frames/frame-client.d.ts +18 -0
- package/types/server-functions/client.d.ts +33 -2
- package/types/server-functions/server.d.ts +67 -2
- package/types/server-mock.d.ts +11 -2
- package/types/server.d.ts +23 -2
- package/types-cjs/core.d.cts +3 -0
- package/types-cjs/frames/frame-client.d.cts +18 -0
- package/types-cjs/server-functions/client.d.cts +33 -2
- package/types-cjs/server-functions/server.d.cts +67 -2
- package/types-cjs/server-mock.d.cts +11 -2
- package/types-cjs/server.d.cts +23 -2
package/dist/server.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { createRenderEffect, createMemo, sharedConfig, createRoot, getOwner, ssrHandleError, runWithOwner,
|
|
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, runWithOwner, 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, 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 = {
|
|
@@ -71,6 +71,9 @@ const state = globalThis[STATE] || (globalThis[STATE] = {
|
|
|
71
71
|
function setContainerTraceResolver(fn) {
|
|
72
72
|
state.resolveTrace = fn;
|
|
73
73
|
}
|
|
74
|
+
function setContainerTraceStreamMint(fn) {
|
|
75
|
+
state.streamOf = fn;
|
|
76
|
+
}
|
|
74
77
|
const TRACE = Symbol.for("dom-expressions.container-trace");
|
|
75
78
|
function materialize(marker) {
|
|
76
79
|
let value = state.materialized.get(marker.$tr);
|
|
@@ -83,9 +86,10 @@ function materialize(marker) {
|
|
|
83
86
|
}
|
|
84
87
|
function parseTrace(value, ctx) {
|
|
85
88
|
const trace = value[TRACE];
|
|
89
|
+
const sub = trace.subscribe();
|
|
86
90
|
return {
|
|
87
91
|
a: trace.array ? 1 : 0,
|
|
88
|
-
i: ctx.parse(
|
|
92
|
+
i: ctx.parse(state.streamOf ? state.streamOf(sub) : sub)
|
|
89
93
|
};
|
|
90
94
|
}
|
|
91
95
|
const ContainerTracePlugin = {
|
|
@@ -99,9 +103,10 @@ const ContainerTracePlugin = {
|
|
|
99
103
|
},
|
|
100
104
|
async async(value, ctx) {
|
|
101
105
|
const trace = value[TRACE];
|
|
106
|
+
const sub = trace.subscribe();
|
|
102
107
|
return {
|
|
103
108
|
a: trace.array ? 1 : 0,
|
|
104
|
-
i: await ctx.parse(
|
|
109
|
+
i: await ctx.parse(state.streamOf ? state.streamOf(sub) : sub)
|
|
105
110
|
};
|
|
106
111
|
},
|
|
107
112
|
stream: parseTrace
|
|
@@ -119,6 +124,18 @@ const ContainerTracePlugin = {
|
|
|
119
124
|
}
|
|
120
125
|
};
|
|
121
126
|
|
|
127
|
+
setContainerTraceStreamMint(iterable => {
|
|
128
|
+
const stream = createStream();
|
|
129
|
+
(async () => {
|
|
130
|
+
try {
|
|
131
|
+
for await (const value of iterable) stream.next(value);
|
|
132
|
+
stream.return(undefined);
|
|
133
|
+
} catch (error) {
|
|
134
|
+
stream.throw(error);
|
|
135
|
+
}
|
|
136
|
+
})();
|
|
137
|
+
return stream;
|
|
138
|
+
});
|
|
122
139
|
const DEFAULT_WEB_PLUGINS = Object.freeze([AbortSignalPlugin,
|
|
123
140
|
CustomEventPlugin, DOMExceptionPlugin, EventPlugin,
|
|
124
141
|
FormDataPlugin, HeadersPlugin, ReadableStreamPlugin, RequestPlugin, ResponsePlugin, URLSearchParamsPlugin, URLPlugin,
|
|
@@ -441,6 +458,7 @@ function registerEntryAssets(manifest) {
|
|
|
441
458
|
const assets = resolveAssets(key, manifest);
|
|
442
459
|
if (assets) {
|
|
443
460
|
for (let i = 0; i < assets.css.length; i++) ctx.registerAsset("style", assets.css[i]);
|
|
461
|
+
for (let i = 1; i < assets.js.length; i++) ctx.registerAsset("module", assets.js[i]);
|
|
444
462
|
}
|
|
445
463
|
return;
|
|
446
464
|
}
|
|
@@ -700,7 +718,7 @@ function emitHeadResource(registry, context, tracking, emitResource, nonce, desc
|
|
|
700
718
|
if (!styles) tracking.boundaryStyles.set(tracking.currentBoundaryId, styles = new Set());
|
|
701
719
|
styles.add(entry);
|
|
702
720
|
}
|
|
703
|
-
const markup = `<link${attrHtml}>`;
|
|
721
|
+
const markup = `<link${attrHtml}${nonceAttr(nonce, "style")}>`;
|
|
704
722
|
if (emitResource) emitResource(markup, entry);else {
|
|
705
723
|
registry.eagerHtml += markup;
|
|
706
724
|
entry.emitted = true;
|
|
@@ -798,7 +816,7 @@ function headGroupSignature(winner) {
|
|
|
798
816
|
}
|
|
799
817
|
return sig;
|
|
800
818
|
}
|
|
801
|
-
function renderShellHead(registry, nonce, isPendingFragment) {
|
|
819
|
+
function renderShellHead(registry, nonce, isPendingFragment, noScripts) {
|
|
802
820
|
commitHeadBoundary(registry, "", isPendingFragment);
|
|
803
821
|
registry.shellFlushed = true;
|
|
804
822
|
const winners = resolveHead(registry.committed);
|
|
@@ -808,8 +826,14 @@ function renderShellHead(registry, nonce, isPendingFragment) {
|
|
|
808
826
|
let metas = "";
|
|
809
827
|
let others = "";
|
|
810
828
|
let scripts = "";
|
|
829
|
+
let title = null;
|
|
811
830
|
for (const [identity, winner] of winners) {
|
|
812
831
|
registry.flushed.set(identity, headGroupSignature(winner));
|
|
832
|
+
if (identity === "title") {
|
|
833
|
+
const children = winner.tags[0].props.children;
|
|
834
|
+
title = children == null ? "" : String(children);
|
|
835
|
+
continue;
|
|
836
|
+
}
|
|
813
837
|
for (let i = 0; i < winner.tags.length; i++) {
|
|
814
838
|
const t = winner.tags[i];
|
|
815
839
|
const markup = renderHeadTagMarkup(t.tag, t.props, identity, nonce);
|
|
@@ -818,10 +842,12 @@ function renderShellHead(registry, nonce, isPendingFragment) {
|
|
|
818
842
|
}
|
|
819
843
|
return {
|
|
820
844
|
prelude,
|
|
821
|
-
html: registry.eagerHtml + links + metas + others + scripts
|
|
845
|
+
html: registry.eagerHtml + links + metas + others + scripts,
|
|
846
|
+
title,
|
|
847
|
+
noScripts
|
|
822
848
|
};
|
|
823
849
|
}
|
|
824
|
-
function flushHeadFragment(registry, boundary) {
|
|
850
|
+
function flushHeadFragment(registry, boundary, nonce) {
|
|
825
851
|
const groups = commitHeadBoundary(registry, boundary);
|
|
826
852
|
if (!groups.length) return null;
|
|
827
853
|
const winners = resolveHead(registry.committed);
|
|
@@ -852,12 +878,87 @@ function flushHeadFragment(registry, boundary) {
|
|
|
852
878
|
if (v == null || v === false) continue;
|
|
853
879
|
attrs[name] = v === true ? "" : String(v);
|
|
854
880
|
}
|
|
881
|
+
if (nonce && !hasNonceProp(t.props)) {
|
|
882
|
+
const destination = nonceDestination(t.tag, t.props);
|
|
883
|
+
const value = destination && nonce[destination];
|
|
884
|
+
if (value) attrs.nonce = String(value);
|
|
885
|
+
}
|
|
855
886
|
const children = t.props.children;
|
|
856
887
|
ops.push(["a", identity, t.tag, attrs, children == null ? null : String(children)]);
|
|
857
888
|
}
|
|
858
889
|
}
|
|
859
890
|
return ops.length ? ops : null;
|
|
860
891
|
}
|
|
892
|
+
function normalizeNonce(nonce) {
|
|
893
|
+
if (nonce == null) return undefined;
|
|
894
|
+
if (typeof nonce === "string") {
|
|
895
|
+
const attr = nonce ? ` nonce="${escape(nonce, true)}"` : "";
|
|
896
|
+
return {
|
|
897
|
+
script: nonce,
|
|
898
|
+
style: nonce,
|
|
899
|
+
scriptAttr: attr,
|
|
900
|
+
styleAttr: attr
|
|
901
|
+
};
|
|
902
|
+
}
|
|
903
|
+
const script = nonce.script;
|
|
904
|
+
const style = nonce.style;
|
|
905
|
+
if (!script && !style) return undefined;
|
|
906
|
+
return {
|
|
907
|
+
script,
|
|
908
|
+
style,
|
|
909
|
+
scriptAttr: typeof script === "string" && script ? ` nonce="${escape(script, true)}"` : "",
|
|
910
|
+
styleAttr: typeof style === "string" && style ? ` nonce="${escape(style, true)}"` : ""
|
|
911
|
+
};
|
|
912
|
+
}
|
|
913
|
+
function destinationNonce(nonce, destination) {
|
|
914
|
+
if (nonce == null) return undefined;
|
|
915
|
+
if (typeof nonce === "string") return nonce || undefined;
|
|
916
|
+
const value = nonce[destination];
|
|
917
|
+
return typeof value === "string" && value ? value : undefined;
|
|
918
|
+
}
|
|
919
|
+
function scriptNonce(nonce) {
|
|
920
|
+
return destinationNonce(nonce, "script");
|
|
921
|
+
}
|
|
922
|
+
function styleNonce(nonce) {
|
|
923
|
+
return destinationNonce(nonce, "style");
|
|
924
|
+
}
|
|
925
|
+
function asciiLowerCase(value) {
|
|
926
|
+
return value.replace(/[A-Z]/g, c => String.fromCharCode(c.charCodeAt(0) + 32));
|
|
927
|
+
}
|
|
928
|
+
function hasNonceProp(props) {
|
|
929
|
+
for (const name in props) if (name.length === 5 && asciiLowerCase(name) === "nonce" && props[name] != null) return true;
|
|
930
|
+
return false;
|
|
931
|
+
}
|
|
932
|
+
function nonceDestination(tag, props) {
|
|
933
|
+
if (tag === "script") return "script";
|
|
934
|
+
if (tag === "style") return "style";
|
|
935
|
+
if (tag !== "link") return null;
|
|
936
|
+
const rel = props.rel;
|
|
937
|
+
if (typeof rel !== "string") return null;
|
|
938
|
+
const rels = asciiLowerCase(rel).split(/[\t\n\f\r ]+/);
|
|
939
|
+
if (rels.includes("stylesheet")) return "style";
|
|
940
|
+
const isModulePreload = rels.includes("modulepreload");
|
|
941
|
+
if (!isModulePreload && !rels.includes("preload")) return null;
|
|
942
|
+
const as = typeof props.as === "string" ? asciiLowerCase(props.as) : "";
|
|
943
|
+
if (as === "style") return "style";
|
|
944
|
+
if (as === "script") return "script";
|
|
945
|
+
if (!isModulePreload) return null;
|
|
946
|
+
switch (as) {
|
|
947
|
+
case "fetch":
|
|
948
|
+
case "font":
|
|
949
|
+
case "image":
|
|
950
|
+
case "json":
|
|
951
|
+
case "text":
|
|
952
|
+
case "track":
|
|
953
|
+
return null;
|
|
954
|
+
default:
|
|
955
|
+
return "script";
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
function nonceAttr(nonce, destination) {
|
|
959
|
+
if (!nonce || !destination) return "";
|
|
960
|
+
return destination === "script" ? nonce.scriptAttr : nonce.styleAttr;
|
|
961
|
+
}
|
|
861
962
|
function renderHeadAttrHtml(props) {
|
|
862
963
|
let attrs = "";
|
|
863
964
|
for (const name in props) {
|
|
@@ -886,7 +987,7 @@ function headAttrRecord(props, skipRelHref) {
|
|
|
886
987
|
function renderHeadTagMarkup(tag, props, identity, nonce) {
|
|
887
988
|
let attrs = renderHeadAttrHtml(props);
|
|
888
989
|
if (identity != null) attrs += ` data-dh="${escape(identity, true)}"`;
|
|
889
|
-
if (nonce && (
|
|
990
|
+
if (nonce && !hasNonceProp(props)) attrs += nonceAttr(nonce, nonceDestination(tag, props));
|
|
890
991
|
if (tag === "meta" || tag === "link" || tag === "base") return `<${tag}${attrs}>`;
|
|
891
992
|
let body = props.children == null ? "" : String(props.children);
|
|
892
993
|
if (tag === "script") body = body.replace(/<\/(script)/gi, "<\\/$1");else if (tag === "style") body = escapeStyleContent(body);else body = escape(body);
|
|
@@ -901,15 +1002,15 @@ function useHead(tags) {
|
|
|
901
1002
|
}
|
|
902
1003
|
const VOID_ELEMENTS = /^(?:area|base|br|col|embed|hr|img|input|keygen|link|menuitem|meta|param|source|track|wbr)$/i;
|
|
903
1004
|
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)}`;
|
|
1005
|
+
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
1006
|
function renderToString(code, options = {}) {
|
|
906
1007
|
const {
|
|
907
1008
|
renderId = "",
|
|
908
|
-
nonce,
|
|
909
1009
|
noScripts,
|
|
910
1010
|
manifest,
|
|
911
1011
|
onHead
|
|
912
1012
|
} = options;
|
|
1013
|
+
const nonce = normalizeNonce(options.nonce);
|
|
913
1014
|
let scripts = "";
|
|
914
1015
|
const serializer = createHydrationSerializer({
|
|
915
1016
|
scopeId: renderId,
|
|
@@ -926,7 +1027,7 @@ function renderToString(code, options = {}) {
|
|
|
926
1027
|
const tracking = createAssetTracking();
|
|
927
1028
|
const headRegistry = createHeadRegistry();
|
|
928
1029
|
sharedConfig.context = {
|
|
929
|
-
nonce,
|
|
1030
|
+
nonce: options.nonce,
|
|
930
1031
|
escape: escape,
|
|
931
1032
|
resolve: resolveSSRNode,
|
|
932
1033
|
ssr: ssr,
|
|
@@ -967,12 +1068,11 @@ function renderToString(code, options = {}) {
|
|
|
967
1068
|
serializeFragmentAssets("", tracking.boundaryModules, sharedConfig.context, renderId);
|
|
968
1069
|
sharedConfig.context.noHydrate = true;
|
|
969
1070
|
serializer.close();
|
|
970
|
-
const head = renderShellHead(headRegistry, nonce, null);
|
|
1071
|
+
const head = renderShellHead(headRegistry, nonce, null, noScripts);
|
|
971
1072
|
return assembleDocument(resolveSSRSelectValues(html), tracking.emittedAssets, tracking.inlineStyles, scripts.length ? scripts : "", nonce, head, onHead);
|
|
972
1073
|
}
|
|
973
1074
|
function renderToStream(code, options = {}) {
|
|
974
1075
|
let {
|
|
975
|
-
nonce,
|
|
976
1076
|
onCompleteShell,
|
|
977
1077
|
onCompleteAll,
|
|
978
1078
|
renderId = "",
|
|
@@ -980,6 +1080,7 @@ function renderToStream(code, options = {}) {
|
|
|
980
1080
|
manifest,
|
|
981
1081
|
onHead
|
|
982
1082
|
} = options;
|
|
1083
|
+
const nonce = normalizeNonce(options.nonce);
|
|
983
1084
|
let dispose;
|
|
984
1085
|
let dead = false;
|
|
985
1086
|
const abandon = () => {
|
|
@@ -1004,6 +1105,32 @@ function renderToStream(code, options = {}) {
|
|
|
1004
1105
|
} catch (_) {}
|
|
1005
1106
|
abandon();
|
|
1006
1107
|
};
|
|
1108
|
+
const coalesceWrites = (writeRaw, endRaw) => {
|
|
1109
|
+
let buf = "";
|
|
1110
|
+
let scheduled = false;
|
|
1111
|
+
const flush = () => {
|
|
1112
|
+
scheduled = false;
|
|
1113
|
+
if (!buf) return;
|
|
1114
|
+
const out = buf;
|
|
1115
|
+
buf = "";
|
|
1116
|
+
writeRaw(out);
|
|
1117
|
+
};
|
|
1118
|
+
return {
|
|
1119
|
+
write(payload) {
|
|
1120
|
+
buf += payload;
|
|
1121
|
+
if (buf.length >= 16384) return flush();
|
|
1122
|
+
if (!scheduled) {
|
|
1123
|
+
scheduled = true;
|
|
1124
|
+
deferFlush(flush);
|
|
1125
|
+
}
|
|
1126
|
+
},
|
|
1127
|
+
flush,
|
|
1128
|
+
end() {
|
|
1129
|
+
flush();
|
|
1130
|
+
endRaw();
|
|
1131
|
+
}
|
|
1132
|
+
};
|
|
1133
|
+
};
|
|
1007
1134
|
const guardSink = w => ({
|
|
1008
1135
|
write(payload) {
|
|
1009
1136
|
if (dead) return;
|
|
@@ -1023,6 +1150,23 @@ function renderToStream(code, options = {}) {
|
|
|
1023
1150
|
}
|
|
1024
1151
|
});
|
|
1025
1152
|
const blockingPromises = new Set();
|
|
1153
|
+
const canBatchStubs = !options.serializer && !options.sink;
|
|
1154
|
+
let stubBatch = null;
|
|
1155
|
+
const STUB_BATCH_KEY = "$B";
|
|
1156
|
+
const flushStubBatch = () => {
|
|
1157
|
+
if (!stubBatch) return;
|
|
1158
|
+
const batch = stubBatch;
|
|
1159
|
+
stubBatch = null;
|
|
1160
|
+
if (batch.size === 1) {
|
|
1161
|
+
const [id, p] = batch.entries().next().value;
|
|
1162
|
+
serializer.write(id, p);
|
|
1163
|
+
return;
|
|
1164
|
+
}
|
|
1165
|
+
const obj = {};
|
|
1166
|
+
for (const [id, p] of batch) obj[id] = p;
|
|
1167
|
+
serializer.write(STUB_BATCH_KEY, obj);
|
|
1168
|
+
pushTask(`(b=>{for(var k in b)_$HY.r[k]=b[k];delete _$HY.r["${STUB_BATCH_KEY}"]})(_$HY.r["${STUB_BATCH_KEY}"])`);
|
|
1169
|
+
};
|
|
1026
1170
|
let headerEmitted = false;
|
|
1027
1171
|
const pushTask = task => {
|
|
1028
1172
|
if (noScripts) return;
|
|
@@ -1059,10 +1203,11 @@ function renderToStream(code, options = {}) {
|
|
|
1059
1203
|
buffer.write(renderInlineStyle(styles.inline[i], nonce));
|
|
1060
1204
|
}
|
|
1061
1205
|
if (styles.links.length) {
|
|
1206
|
+
const styleAttr = nonceAttr(nonce, "style");
|
|
1062
1207
|
emitTask(`$dfs("${key}",${styles.links.length},${deferActivation ? 1 : 0})`);
|
|
1063
1208
|
writeTasks();
|
|
1064
1209
|
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}')">`);
|
|
1210
|
+
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
1211
|
}
|
|
1067
1212
|
buffer.write(`<template id="${key}">${value}</template>`);
|
|
1068
1213
|
} else {
|
|
@@ -1077,7 +1222,7 @@ function renderToStream(code, options = {}) {
|
|
|
1077
1222
|
},
|
|
1078
1223
|
asset(type, value) {
|
|
1079
1224
|
if (type === "module") {
|
|
1080
|
-
buffer.write(`<link rel="modulepreload" href="${value}">`);
|
|
1225
|
+
buffer.write(`<link rel="modulepreload" href="${value}"${nonceAttr(nonce, "script")}>`);
|
|
1081
1226
|
} else if (type === "inline-style") {
|
|
1082
1227
|
buffer.write(renderInlineStyle(value, nonce));
|
|
1083
1228
|
} else if (type === "head-tag") {
|
|
@@ -1112,6 +1257,7 @@ function renderToStream(code, options = {}) {
|
|
|
1112
1257
|
context.live.end = null;
|
|
1113
1258
|
end();
|
|
1114
1259
|
}
|
|
1260
|
+
flushStubBatch();
|
|
1115
1261
|
serializer.flush();
|
|
1116
1262
|
}));
|
|
1117
1263
|
}
|
|
@@ -1119,7 +1265,7 @@ function renderToStream(code, options = {}) {
|
|
|
1119
1265
|
const registry = new Map();
|
|
1120
1266
|
const writeTasks = () => {
|
|
1121
1267
|
if (tasks.length && !completed && firstFlushed) {
|
|
1122
|
-
buffer.write(`<script${nonce
|
|
1268
|
+
buffer.write(`<script${nonceAttr(nonce, "script")}>${tasks}</script>`);
|
|
1123
1269
|
tasks = "";
|
|
1124
1270
|
}
|
|
1125
1271
|
timer = null;
|
|
@@ -1173,7 +1319,7 @@ function renderToStream(code, options = {}) {
|
|
|
1173
1319
|
};
|
|
1174
1320
|
sharedConfig.context = context = {
|
|
1175
1321
|
async: true,
|
|
1176
|
-
nonce,
|
|
1322
|
+
nonce: options.nonce,
|
|
1177
1323
|
live: {},
|
|
1178
1324
|
registerHeadTags(tags) {
|
|
1179
1325
|
registerHeadTags(headRegistry, context, tracking,
|
|
@@ -1231,10 +1377,18 @@ function renderToStream(code, options = {}) {
|
|
|
1231
1377
|
},
|
|
1232
1378
|
serialize(id, p, deferStream) {
|
|
1233
1379
|
if (sharedConfig.context.noHydrate) return;
|
|
1234
|
-
if (!firstFlushed &&
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1380
|
+
if (!firstFlushed && p && typeof p === "object" && "then" in p) {
|
|
1381
|
+
if (deferStream) {
|
|
1382
|
+
blockingPromises.add(p);
|
|
1383
|
+
p.then(d => serializer.write(id, d)).catch(e => serializer.write(id, e));
|
|
1384
|
+
return;
|
|
1385
|
+
}
|
|
1386
|
+
if (canBatchStubs && !shellCompleted) {
|
|
1387
|
+
(stubBatch ||= new Map()).set(id, p);
|
|
1388
|
+
return;
|
|
1389
|
+
}
|
|
1390
|
+
}
|
|
1391
|
+
serializer.write(id, p);
|
|
1238
1392
|
},
|
|
1239
1393
|
escape: escape,
|
|
1240
1394
|
resolve: resolveSSRNode,
|
|
@@ -1268,7 +1422,7 @@ function renderToStream(code, options = {}) {
|
|
|
1268
1422
|
queue(flushEnd);
|
|
1269
1423
|
}))
|
|
1270
1424
|
});
|
|
1271
|
-
serializer.write(key + "_fr", p);
|
|
1425
|
+
if (canBatchStubs && !shellCompleted) (stubBatch ||= new Map()).set(key + "_fr", p);else serializer.write(key + "_fr", p);
|
|
1272
1426
|
}
|
|
1273
1427
|
return (value, error) => {
|
|
1274
1428
|
if (registry.has(key)) {
|
|
@@ -1299,7 +1453,7 @@ function renderToStream(code, options = {}) {
|
|
|
1299
1453
|
} else {
|
|
1300
1454
|
serializeFragmentAssets(key, tracking.boundaryModules, context);
|
|
1301
1455
|
const styles = collectStreamStyles(key, tracking, headStyles);
|
|
1302
|
-
const headOps = error ? null : flushHeadFragment(headRegistry, key);
|
|
1456
|
+
const headOps = error ? null : flushHeadFragment(headRegistry, key, nonce);
|
|
1303
1457
|
if (headOps) emitHeadOps(key, headOps);
|
|
1304
1458
|
sink.fragment(key, resolveSSRSelectValues(value !== undefined ? value : " "), {
|
|
1305
1459
|
styles,
|
|
@@ -1385,14 +1539,17 @@ function renderToStream(code, options = {}) {
|
|
|
1385
1539
|
function doShell() {
|
|
1386
1540
|
if (shellCompleted) return;
|
|
1387
1541
|
sharedConfig.context = context;
|
|
1542
|
+
const blockersBefore = blockingPromises.size;
|
|
1388
1543
|
if (!resolveRootHoles()) return;
|
|
1544
|
+
if (blockingPromises.size !== blockersBefore) return;
|
|
1389
1545
|
if (!headShellReady(headRegistry, p => blockingPromises.add(p))) return;
|
|
1390
1546
|
headStyles = new Set();
|
|
1391
1547
|
for (const url of tracking.emittedAssets) {
|
|
1392
1548
|
if (isCssUrl(url)) headStyles.add(url);
|
|
1393
1549
|
}
|
|
1394
1550
|
serializeRootAssets();
|
|
1395
|
-
|
|
1551
|
+
flushStubBatch();
|
|
1552
|
+
const head = renderShellHead(headRegistry, nonce, k => registry.has(k), noScripts);
|
|
1396
1553
|
sink.shell(resolveSSRSelectValues(html), {
|
|
1397
1554
|
preloads: tracking.emittedAssets,
|
|
1398
1555
|
inlineStyles: tracking.inlineStyles,
|
|
@@ -1413,6 +1570,7 @@ function renderToStream(code, options = {}) {
|
|
|
1413
1570
|
let drainTurn = 0;
|
|
1414
1571
|
const scheduleFlush = fn => {
|
|
1415
1572
|
const attempt = () => {
|
|
1573
|
+
flushStubBatch();
|
|
1416
1574
|
if (registry.size !== lastRegistrySize || drainTurn++ < MIN_DRAIN_TURNS) {
|
|
1417
1575
|
if (registry.size !== lastRegistrySize) drainTurn = 0;
|
|
1418
1576
|
lastRegistrySize = registry.size;
|
|
@@ -1460,22 +1618,18 @@ function renderToStream(code, options = {}) {
|
|
|
1460
1618
|
}
|
|
1461
1619
|
};
|
|
1462
1620
|
writer.closed && writer.closed.catch(failed);
|
|
1463
|
-
writable = {
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
}
|
|
1472
|
-
};
|
|
1473
|
-
buffer = {
|
|
1474
|
-
write(payload) {
|
|
1475
|
-
pendingWrites = pendingWrites.then(() => writer.write(encoder.encode(payload))).catch(failed);
|
|
1476
|
-
}
|
|
1477
|
-
};
|
|
1621
|
+
buffer = writable = coalesceWrites(payload => {
|
|
1622
|
+
pendingWrites = pendingWrites.then(() => writer.write(encoder.encode(payload))).catch(failed);
|
|
1623
|
+
}, () => {
|
|
1624
|
+
pendingWrites.then(() => {
|
|
1625
|
+
ended = true;
|
|
1626
|
+
writer.releaseLock();
|
|
1627
|
+
w.close().catch(() => {});
|
|
1628
|
+
resolve();
|
|
1629
|
+
});
|
|
1630
|
+
});
|
|
1478
1631
|
buffer.write(tmp);
|
|
1632
|
+
buffer.flush();
|
|
1479
1633
|
firstFlushed = true;
|
|
1480
1634
|
if (completed) {
|
|
1481
1635
|
dispose();
|
|
@@ -1505,7 +1659,8 @@ function renderToStream(code, options = {}) {
|
|
|
1505
1659
|
allSettled(blockingPromises).then(() => {
|
|
1506
1660
|
scheduleFlush(() => {
|
|
1507
1661
|
try {
|
|
1508
|
-
|
|
1662
|
+
const blockersBefore = blockingPromises.size;
|
|
1663
|
+
if (!resolveRootHoles() || blockingPromises.size !== blockersBefore || !headShellReady(headRegistry, p => blockingPromises.add(p))) return flush();
|
|
1509
1664
|
} catch (err) {
|
|
1510
1665
|
failRender(err);
|
|
1511
1666
|
return resolve(tmp);
|
|
@@ -1534,8 +1689,10 @@ function renderToStream(code, options = {}) {
|
|
|
1534
1689
|
return;
|
|
1535
1690
|
}
|
|
1536
1691
|
if (!shellCompleted) return flush();
|
|
1537
|
-
|
|
1692
|
+
const sink = guardSink(w);
|
|
1693
|
+
buffer = writable = coalesceWrites(sink.write, sink.end);
|
|
1538
1694
|
buffer.write(tmp);
|
|
1695
|
+
buffer.flush();
|
|
1539
1696
|
firstFlushed = true;
|
|
1540
1697
|
if (completed) {
|
|
1541
1698
|
dispose();
|
|
@@ -1562,9 +1719,7 @@ function renderToStream(code, options = {}) {
|
|
|
1562
1719
|
};
|
|
1563
1720
|
}
|
|
1564
1721
|
function HydrationScript(props) {
|
|
1565
|
-
const
|
|
1566
|
-
nonce
|
|
1567
|
-
} = sharedConfig.context;
|
|
1722
|
+
const nonce = scriptNonce(sharedConfig.context && sharedConfig.context.nonce);
|
|
1568
1723
|
return ssr(generateHydrationScript({
|
|
1569
1724
|
nonce,
|
|
1570
1725
|
...props
|
|
@@ -2278,6 +2433,32 @@ function ssrHydrationKey() {
|
|
|
2278
2433
|
const hk = getHydrationKey();
|
|
2279
2434
|
return hk ? ` _hk=${hk}` : "";
|
|
2280
2435
|
}
|
|
2436
|
+
const CLAIM_PROP = /*#__PURE__*/Symbol.for("dom-expressions.claim-prop");
|
|
2437
|
+
const CLAIMS_STREAM = 1;
|
|
2438
|
+
const CLAIMS_DOCUMENT = 2;
|
|
2439
|
+
const CLAIM_UNSAFE = /[^A-Za-z0-9_.!~*'()-]/g;
|
|
2440
|
+
function encodeClaimKey(key) {
|
|
2441
|
+
return String(key).replace(CLAIM_UNSAFE, c => encodeURIComponent(c));
|
|
2442
|
+
}
|
|
2443
|
+
function ssrClaim(map) {
|
|
2444
|
+
const mode = sharedConfig.context && sharedConfig.context.claims;
|
|
2445
|
+
if (!mode || mode === CLAIMS_DOCUMENT && !(typeof inServerComponentScope === "function" && inServerComponentScope())) {
|
|
2446
|
+
return "";
|
|
2447
|
+
}
|
|
2448
|
+
let out = "";
|
|
2449
|
+
for (const pos in map) {
|
|
2450
|
+
const value = map[pos];
|
|
2451
|
+
const list = Array.isArray(value) ? value : [value];
|
|
2452
|
+
for (const fn of list) {
|
|
2453
|
+
const prop = typeof fn === "function" && fn[CLAIM_PROP] || undefined;
|
|
2454
|
+
if (prop === undefined) {
|
|
2455
|
+
continue;
|
|
2456
|
+
}
|
|
2457
|
+
out += `${out ? "," : ""}${pos}=${encodeClaimKey(prop)}`;
|
|
2458
|
+
}
|
|
2459
|
+
}
|
|
2460
|
+
return out ? ` _bnd="${out}"` : "";
|
|
2461
|
+
}
|
|
2281
2462
|
function decodeSSREntities(s) {
|
|
2282
2463
|
return s.indexOf("&") < 0 ? s : s.replace(/"/g, '"').replace(/</g, "<").replace(/&/g, "&");
|
|
2283
2464
|
}
|
|
@@ -2310,22 +2491,49 @@ function tagIs(html, i, name) {
|
|
|
2310
2491
|
const c = html.charCodeAt(i + 1 + name.length);
|
|
2311
2492
|
return c === 32 || c === 62 || c === 9 || c === 10 || c === 13;
|
|
2312
2493
|
}
|
|
2494
|
+
let selectValuesActive = false;
|
|
2495
|
+
function ssrSelectValues() {
|
|
2496
|
+
selectValuesActive = true;
|
|
2497
|
+
}
|
|
2313
2498
|
function resolveSSRSelectValues(html) {
|
|
2314
|
-
if (
|
|
2499
|
+
if (!selectValuesActive) return html;
|
|
2500
|
+
let cand = html.indexOf("<select");
|
|
2501
|
+
if (cand < 0) return html;
|
|
2315
2502
|
let out = "";
|
|
2316
2503
|
let idx = 0;
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2504
|
+
while (cand >= 0) {
|
|
2505
|
+
if (!tagIs(html, cand, "select")) {
|
|
2506
|
+
cand = html.indexOf("<select", cand + 7);
|
|
2507
|
+
continue;
|
|
2508
|
+
}
|
|
2509
|
+
const e0 = tagEnd(html, cand);
|
|
2510
|
+
if (e0 < 0) break;
|
|
2511
|
+
const open = html.slice(cand, e0 + 1);
|
|
2512
|
+
const m = SELECT_VALUE_ATTR.exec(open);
|
|
2513
|
+
if (!m) {
|
|
2514
|
+
cand = html.indexOf("<select", e0 + 1);
|
|
2515
|
+
continue;
|
|
2516
|
+
}
|
|
2517
|
+
const bound = decodeSSREntities(m[1]);
|
|
2518
|
+
const sel = {
|
|
2519
|
+
values: /\smultiple(?=[\s>=])/.test(open) ? bound.split(",") : [bound],
|
|
2520
|
+
strip: cand + m.index,
|
|
2521
|
+
stripEnd: cand + m.index + m[0].length,
|
|
2522
|
+
body: e0 + 1,
|
|
2523
|
+
marks: [],
|
|
2524
|
+
defaulted: false
|
|
2525
|
+
};
|
|
2526
|
+
let committed = false;
|
|
2527
|
+
let i = html.indexOf("<", e0 + 1);
|
|
2528
|
+
while (i >= 0) {
|
|
2529
|
+
let e;
|
|
2530
|
+
if (html.charCodeAt(i + 1) === 33) {
|
|
2531
|
+
e = html.charCodeAt(i + 2) === 45 ? html.indexOf("-->", i) : html.indexOf(">", i);
|
|
2532
|
+
if (e < 0) break;
|
|
2533
|
+
if (html.charCodeAt(i + 2) === 45) e += 2;
|
|
2534
|
+
} else {
|
|
2535
|
+
e = tagEnd(html, i);
|
|
2536
|
+
if (e < 0) break;
|
|
2329
2537
|
if (html.startsWith("</select>", i)) {
|
|
2330
2538
|
out += html.slice(idx, sel.strip) + html.slice(sel.stripEnd, sel.body);
|
|
2331
2539
|
let seg = sel.body;
|
|
@@ -2337,7 +2545,8 @@ function resolveSSRSelectValues(html) {
|
|
|
2337
2545
|
}
|
|
2338
2546
|
out += html.slice(seg, i);
|
|
2339
2547
|
idx = i;
|
|
2340
|
-
|
|
2548
|
+
committed = true;
|
|
2549
|
+
break;
|
|
2341
2550
|
} else if (tagIs(html, i, "option")) {
|
|
2342
2551
|
const attrs = html.slice(i + 7, e);
|
|
2343
2552
|
if (/\sselected(?=[\s=]|$)/.test(attrs)) sel.defaulted = true;else {
|
|
@@ -2346,23 +2555,13 @@ function resolveSSRSelectValues(html) {
|
|
|
2346
2555
|
if (sel.values.includes(value)) sel.marks.push(e);
|
|
2347
2556
|
}
|
|
2348
2557
|
}
|
|
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
2558
|
}
|
|
2559
|
+
i = html.indexOf("<", e + 1);
|
|
2363
2560
|
}
|
|
2364
|
-
|
|
2561
|
+
if (!committed) break;
|
|
2562
|
+
cand = html.indexOf("<select", idx);
|
|
2365
2563
|
}
|
|
2564
|
+
if (idx === 0) return html;
|
|
2366
2565
|
return out + html.slice(idx);
|
|
2367
2566
|
}
|
|
2368
2567
|
function escape(s, attr) {
|
|
@@ -2386,22 +2585,20 @@ function escape(s, attr) {
|
|
|
2386
2585
|
return escapeSlow(s, attr, i);
|
|
2387
2586
|
}
|
|
2388
2587
|
const ESCAPE_CONTENT = /[&<]/;
|
|
2389
|
-
const ESCAPE_ATTR = /[&"]/;
|
|
2588
|
+
const ESCAPE_ATTR = /[&"<]/;
|
|
2390
2589
|
function escapeSlow(s, attr, start) {
|
|
2391
|
-
|
|
2392
|
-
const delimCode = attr ? 34 : 60;
|
|
2393
|
-
const escDelim = attr ? """ : "<";
|
|
2590
|
+
if (attr) return escapeAttrSlow(s, start);
|
|
2394
2591
|
const c0 = s.charCodeAt(start);
|
|
2395
|
-
let iDelim = c0 ===
|
|
2592
|
+
let iDelim = c0 === 60 ? start : s.indexOf("<", start);
|
|
2396
2593
|
let iAmp = c0 === 38 ? start : s.indexOf("&", start);
|
|
2397
2594
|
let left = 0,
|
|
2398
2595
|
out = "";
|
|
2399
2596
|
while (iDelim >= 0 && iAmp >= 0) {
|
|
2400
2597
|
if (iDelim < iAmp) {
|
|
2401
2598
|
if (left < iDelim) out += s.substring(left, iDelim);
|
|
2402
|
-
out +=
|
|
2599
|
+
out += "<";
|
|
2403
2600
|
left = iDelim + 1;
|
|
2404
|
-
iDelim = s.indexOf(
|
|
2601
|
+
iDelim = s.indexOf("<", left);
|
|
2405
2602
|
} else {
|
|
2406
2603
|
if (left < iAmp) out += s.substring(left, iAmp);
|
|
2407
2604
|
out += "&";
|
|
@@ -2412,9 +2609,9 @@ function escapeSlow(s, attr, start) {
|
|
|
2412
2609
|
if (iDelim >= 0) {
|
|
2413
2610
|
do {
|
|
2414
2611
|
if (left < iDelim) out += s.substring(left, iDelim);
|
|
2415
|
-
out +=
|
|
2612
|
+
out += "<";
|
|
2416
2613
|
left = iDelim + 1;
|
|
2417
|
-
iDelim = s.indexOf(
|
|
2614
|
+
iDelim = s.indexOf("<", left);
|
|
2418
2615
|
} while (iDelim >= 0);
|
|
2419
2616
|
} else while (iAmp >= 0) {
|
|
2420
2617
|
if (left < iAmp) out += s.substring(left, iAmp);
|
|
@@ -2424,6 +2621,36 @@ function escapeSlow(s, attr, start) {
|
|
|
2424
2621
|
}
|
|
2425
2622
|
return left < s.length ? out + s.substring(left) : out;
|
|
2426
2623
|
}
|
|
2624
|
+
function escapeAttrSlow(s, start) {
|
|
2625
|
+
const c0 = s.charCodeAt(start);
|
|
2626
|
+
let iQuot = c0 === 34 ? start : s.indexOf('"', start);
|
|
2627
|
+
let iAmp = c0 === 38 ? start : s.indexOf("&", start);
|
|
2628
|
+
let iLt = c0 === 60 ? start : s.indexOf("<", start);
|
|
2629
|
+
let left = 0,
|
|
2630
|
+
out = "";
|
|
2631
|
+
for (;;) {
|
|
2632
|
+
let i = -1,
|
|
2633
|
+
ent;
|
|
2634
|
+
if (iQuot >= 0) {
|
|
2635
|
+
i = iQuot;
|
|
2636
|
+
ent = """;
|
|
2637
|
+
}
|
|
2638
|
+
if (iAmp >= 0 && (i < 0 || iAmp < i)) {
|
|
2639
|
+
i = iAmp;
|
|
2640
|
+
ent = "&";
|
|
2641
|
+
}
|
|
2642
|
+
if (iLt >= 0 && (i < 0 || iLt < i)) {
|
|
2643
|
+
i = iLt;
|
|
2644
|
+
ent = "<";
|
|
2645
|
+
}
|
|
2646
|
+
if (i < 0) break;
|
|
2647
|
+
if (left < i) out += s.substring(left, i);
|
|
2648
|
+
out += ent;
|
|
2649
|
+
left = i + 1;
|
|
2650
|
+
if (i === iQuot) iQuot = s.indexOf('"', left);else if (i === iAmp) iAmp = s.indexOf("&", left);else iLt = s.indexOf("<", left);
|
|
2651
|
+
}
|
|
2652
|
+
return left < s.length ? out + s.substring(left) : out;
|
|
2653
|
+
}
|
|
2427
2654
|
function tryJoinPlainSSRArray(nodes) {
|
|
2428
2655
|
if (nodes.length === 0) return undefined;
|
|
2429
2656
|
let out = "";
|
|
@@ -2447,11 +2674,12 @@ function generateHydrationScript({
|
|
|
2447
2674
|
eventNames = ["click", "input"],
|
|
2448
2675
|
nonce
|
|
2449
2676
|
} = {}) {
|
|
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-->`;
|
|
2677
|
+
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
2678
|
}
|
|
2452
2679
|
function queue(fn) {
|
|
2453
2680
|
return Promise.resolve().then(fn);
|
|
2454
2681
|
}
|
|
2682
|
+
const deferFlush = typeof setImmediate === "function" ? setImmediate : fn => setTimeout(fn, 0);
|
|
2455
2683
|
function allSettled(promises) {
|
|
2456
2684
|
let size = promises.size;
|
|
2457
2685
|
return Promise.allSettled(promises).then(() => {
|
|
@@ -2460,10 +2688,11 @@ function allSettled(promises) {
|
|
|
2460
2688
|
});
|
|
2461
2689
|
}
|
|
2462
2690
|
function assembleDocument(html, emittedAssets, inlineStyles, scripts, nonce, headTags, onHead) {
|
|
2463
|
-
const scriptTag = scripts ? `<script${nonce
|
|
2464
|
-
const
|
|
2691
|
+
const scriptTag = scripts ? `<script${nonceAttr(nonce, "script")}>${scripts}</script>` : "";
|
|
2692
|
+
const title = headTags ? headTags.title : null;
|
|
2693
|
+
let headTagsHtml = headTags ? headTags.html : "";
|
|
2465
2694
|
const headPrelude = headTags ? headTags.prelude : "";
|
|
2466
|
-
if (!onHead && !headTagsHtml && !headPrelude && !(emittedAssets && emittedAssets.size) && !(inlineStyles && inlineStyles.size)) {
|
|
2695
|
+
if (!onHead && title == null && !headTagsHtml && !headPrelude && !(emittedAssets && emittedAssets.size) && !(inlineStyles && inlineStyles.size)) {
|
|
2467
2696
|
if (!scriptTag) return html;
|
|
2468
2697
|
const xs = html.indexOf("<!--xs-->");
|
|
2469
2698
|
return xs === -1 ? html + scriptTag : html.slice(0, xs) + scriptTag + html.slice(xs);
|
|
@@ -2475,15 +2704,33 @@ function assembleDocument(html, emittedAssets, inlineStyles, scripts, nonce, hea
|
|
|
2475
2704
|
html = html.slice(0, at) + headPrelude + html.slice(at);
|
|
2476
2705
|
}
|
|
2477
2706
|
}
|
|
2478
|
-
|
|
2707
|
+
let headIdx = html.indexOf("</head>");
|
|
2479
2708
|
if (headIdx === -1) {
|
|
2480
2709
|
if (onHead) {
|
|
2481
|
-
|
|
2710
|
+
let titleHtml = "";
|
|
2711
|
+
if (title != null) {
|
|
2712
|
+
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>`;
|
|
2713
|
+
}
|
|
2714
|
+
onHead(headPrelude + headTagsHtml + titleHtml + renderHeadAssets(emittedAssets, inlineStyles, nonce));
|
|
2482
2715
|
}
|
|
2483
2716
|
if (!scriptTag) return html;
|
|
2484
2717
|
const xs = html.indexOf("<!--xs-->");
|
|
2485
2718
|
return xs === -1 ? html + scriptTag : html.slice(0, xs) + scriptTag + html.slice(xs);
|
|
2486
2719
|
}
|
|
2720
|
+
if (title != null) {
|
|
2721
|
+
const winner = escape(title);
|
|
2722
|
+
const open = html.match(/<head(?:\s[^>]*)?>/);
|
|
2723
|
+
const from = open ? open.index + open[0].length : 0;
|
|
2724
|
+
const m = /<title(\s[^>]*)?>([\s\S]*?)<\/title>/.exec(html.slice(from, headIdx));
|
|
2725
|
+
if (m) {
|
|
2726
|
+
const at = from + m.index;
|
|
2727
|
+
const stash = m[2].replace(/"/g, """);
|
|
2728
|
+
html = html.slice(0, at) + `<title${m[1] || ""} data-dh="title" data-dhf="${stash}">${winner}</title>` + html.slice(at + m[0].length);
|
|
2729
|
+
headIdx = html.indexOf("</head>");
|
|
2730
|
+
} else {
|
|
2731
|
+
headTagsHtml = `<title data-dh="title">${winner}</title>` + headTagsHtml;
|
|
2732
|
+
}
|
|
2733
|
+
}
|
|
2487
2734
|
const head = headTagsHtml + renderHeadAssets(emittedAssets, inlineStyles, nonce);
|
|
2488
2735
|
if (!scriptTag) return html.slice(0, headIdx) + head + html.slice(headIdx);
|
|
2489
2736
|
const xsIdx = html.indexOf("<!--xs-->");
|
|
@@ -2492,9 +2739,11 @@ function assembleDocument(html, emittedAssets, inlineStyles, scripts, nonce, hea
|
|
|
2492
2739
|
}
|
|
2493
2740
|
function renderHeadAssets(emittedAssets, inlineStyles, nonce) {
|
|
2494
2741
|
let head = "";
|
|
2742
|
+
const styleAttr = nonceAttr(nonce, "style");
|
|
2743
|
+
const scriptAttr = nonceAttr(nonce, "script");
|
|
2495
2744
|
if (emittedAssets && emittedAssets.size) {
|
|
2496
2745
|
for (const url of emittedAssets) {
|
|
2497
|
-
head += isCssUrl(url) ? `<link rel="stylesheet" href="${url}">` : `<link rel="modulepreload" href="${url}">`;
|
|
2746
|
+
head += isCssUrl(url) ? `<link rel="stylesheet" href="${url}"${styleAttr}>` : `<link rel="modulepreload" href="${url}"${scriptAttr}>`;
|
|
2498
2747
|
}
|
|
2499
2748
|
}
|
|
2500
2749
|
if (inlineStyles && inlineStyles.size) {
|
|
@@ -2556,12 +2805,15 @@ function escapeStyleContent(content) {
|
|
|
2556
2805
|
}
|
|
2557
2806
|
function renderInlineStyle(entry, nonce) {
|
|
2558
2807
|
let attrs = "";
|
|
2808
|
+
let hasNonce = false;
|
|
2559
2809
|
if (entry.attrs) {
|
|
2560
2810
|
for (const name in entry.attrs) {
|
|
2811
|
+
if (name.length === 5 && asciiLowerCase(name) === "nonce") hasNonce = true;
|
|
2561
2812
|
attrs += ` ${name}="${escape(String(entry.attrs[name]), true)}"`;
|
|
2562
2813
|
}
|
|
2563
2814
|
}
|
|
2564
|
-
|
|
2815
|
+
const nonceHtml = hasNonce ? "" : nonceAttr(nonce, "style");
|
|
2816
|
+
return `<style${nonceHtml} data-asset="${escape(entry.id, true)}"${attrs}>${escapeStyleContent(entry.content)}</style>`;
|
|
2565
2817
|
}
|
|
2566
2818
|
function waitForFragments(registry, key) {
|
|
2567
2819
|
for (const k of [...registry.keys()].reverse()) {
|
|
@@ -2803,16 +3055,13 @@ function deriveHead(stub, responseInit = {}) {
|
|
|
2803
3055
|
headers
|
|
2804
3056
|
};
|
|
2805
3057
|
}
|
|
2806
|
-
function escapeAttribute(value) {
|
|
2807
|
-
return value.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<");
|
|
2808
|
-
}
|
|
2809
3058
|
function createSSRResponse(result, event, options = {}) {
|
|
2810
3059
|
const stub = event && event.response;
|
|
2811
3060
|
const {
|
|
2812
3061
|
responseInit,
|
|
2813
|
-
nonce,
|
|
2814
3062
|
transformChunk
|
|
2815
3063
|
} = options;
|
|
3064
|
+
const nonce = normalizeNonce(options.nonce);
|
|
2816
3065
|
if (typeof result === "string") {
|
|
2817
3066
|
if (stub) commitResponseStub(stub);
|
|
2818
3067
|
const head = deriveHead(stub, responseInit);
|
|
@@ -2882,7 +3131,7 @@ function createSSRResponse(result, event, options = {}) {
|
|
|
2882
3131
|
if (closed || !controller) return;
|
|
2883
3132
|
const location = stub && stub.headers.get("Location");
|
|
2884
3133
|
if (location) {
|
|
2885
|
-
const attr =
|
|
3134
|
+
const attr = nonceAttr(nonce, "script");
|
|
2886
3135
|
enqueue(`<script${attr}>window.location=${JSON.stringify(location).replace(/</g, "\\u003c")}</script>`);
|
|
2887
3136
|
}
|
|
2888
3137
|
closed = true;
|
|
@@ -3063,4 +3312,4 @@ function httpHeader(name, value, options) {
|
|
|
3063
3312
|
}
|
|
3064
3313
|
}
|
|
3065
3314
|
|
|
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 };
|
|
3315
|
+
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, 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 };
|