@solidjs/web 2.0.0-beta.3 → 2.0.0-beta.31
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/README.md +27 -4
- package/dist/dev.cjs +1224 -205
- package/dist/dev.js +1188 -199
- package/dist/server.cjs +1429 -234
- package/dist/server.js +1391 -231
- package/dist/web.cjs +1207 -195
- package/dist/web.js +1171 -189
- package/frames/dist/client.cjs +1694 -0
- package/frames/dist/client.dev.cjs +1707 -0
- package/frames/dist/client.dev.js +1695 -0
- package/frames/dist/client.js +1682 -0
- package/frames/dist/server.cjs +2520 -0
- package/frames/dist/server.js +2508 -0
- package/frames/package.json +30 -0
- package/package.json +285 -37
- package/serialization/dist/serialization.cjs +169 -0
- package/serialization/dist/serialization.js +159 -0
- package/serialization/package.json +20 -0
- package/serialization/types/index.d.ts +157 -0
- package/serialization/types-cjs/index.d.cts +157 -0
- package/serialization/types-cjs/package.json +3 -0
- package/server-functions/dist/client.cjs +613 -0
- package/server-functions/dist/client.js +585 -0
- package/server-functions/dist/server.cjs +904 -0
- package/server-functions/dist/server.js +875 -0
- package/server-functions/package.json +30 -0
- package/storage/package.json +8 -3
- package/storage/types/index.d.ts +26 -0
- package/storage/types-cjs/index.d.cts +28 -0
- package/storage/types-cjs/package.json +3 -0
- package/types/client.d.ts +127 -21
- package/types/core.d.ts +4 -3
- package/types/frames/client.d.ts +22 -0
- package/types/frames/frame-client.d.ts +282 -0
- package/types/frames/frame-sink.d.ts +171 -0
- package/types/frames/frame-transport.d.ts +190 -0
- package/types/frames/serializer.d.ts +157 -0
- package/types/frames/server.d.ts +30 -0
- package/types/index.d.ts +211 -26
- package/types/jsx-properties.d.ts +93 -0
- package/types/jsx.d.ts +4150 -1
- package/types/response.d.ts +129 -0
- package/types/serializer.d.ts +157 -0
- package/types/server-functions/client.d.ts +200 -0
- package/types/server-functions/flash.d.ts +38 -0
- package/types/server-functions/server.d.ts +490 -0
- package/types/server-functions/shared.d.ts +445 -0
- package/types/server-mock.d.ts +93 -0
- package/types/server.d.ts +223 -28
- package/types-cjs/client.d.cts +194 -0
- package/types-cjs/core.d.cts +4 -0
- package/types-cjs/frames/client.d.cts +22 -0
- package/types-cjs/frames/frame-client.d.cts +282 -0
- package/types-cjs/frames/frame-sink.d.cts +171 -0
- package/types-cjs/frames/frame-transport.d.cts +190 -0
- package/types-cjs/frames/serializer.d.cts +157 -0
- package/types-cjs/frames/server.d.cts +30 -0
- package/types-cjs/index.d.cts +231 -0
- package/types-cjs/jsx-properties.d.cts +93 -0
- package/types-cjs/jsx.d.cts +4150 -0
- package/types-cjs/package.json +3 -0
- package/types-cjs/response.d.cts +129 -0
- package/types-cjs/serializer.d.cts +157 -0
- package/types-cjs/server-functions/client.d.cts +200 -0
- package/types-cjs/server-functions/flash.d.cts +38 -0
- package/types-cjs/server-functions/server.d.cts +490 -0
- package/types-cjs/server-functions/shared.d.cts +445 -0
- package/types-cjs/server-mock.d.cts +165 -0
- package/types-cjs/server.d.cts +351 -0
- package/storage/types/src/client.d.ts +0 -1
- package/storage/types/src/index.d.ts +0 -46
- package/storage/types/src/server-mock.d.ts +0 -72
- package/storage/types/storage/src/index.d.ts +0 -2
package/dist/server.js
CHANGED
|
@@ -1,11 +1,36 @@
|
|
|
1
|
-
import { createRenderEffect, createMemo
|
|
2
|
-
export { Errored, For, Hydration, Loading, Match, NoHydration, Repeat, Show, Switch, createComponent, getOwner,
|
|
3
|
-
import { Serializer,
|
|
1
|
+
import { createRenderEffect, createMemo, sharedConfig, createRoot, ssrHandleError, getOwner, runWithOwner, createComponent, omit, getNextChildId, onCleanup } 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 { Serializer, getCrossReferenceHeader, Feature } from 'seroval';
|
|
4
4
|
import { AbortSignalPlugin, CustomEventPlugin, DOMExceptionPlugin, EventPlugin, FormDataPlugin, HeadersPlugin, ReadableStreamPlugin, RequestPlugin, ResponsePlugin, URLSearchParamsPlugin, URLPlugin } from 'seroval-plugins/web';
|
|
5
|
-
import { createMemo } from '@solidjs/signals';
|
|
6
5
|
|
|
7
|
-
const
|
|
8
|
-
|
|
6
|
+
const DOMWithState = {
|
|
7
|
+
INPUT: {
|
|
8
|
+
value: 1,
|
|
9
|
+
defaultValue: 2,
|
|
10
|
+
checked: 1,
|
|
11
|
+
defaultChecked: 2
|
|
12
|
+
},
|
|
13
|
+
SELECT: {
|
|
14
|
+
value: 1
|
|
15
|
+
},
|
|
16
|
+
OPTION: {
|
|
17
|
+
value: 1,
|
|
18
|
+
selected: 1,
|
|
19
|
+
defaultSelected: 2
|
|
20
|
+
},
|
|
21
|
+
TEXTAREA: {
|
|
22
|
+
value: 1,
|
|
23
|
+
defaultValue: 2
|
|
24
|
+
},
|
|
25
|
+
VIDEO: {
|
|
26
|
+
muted: 1,
|
|
27
|
+
defaultMuted: 2
|
|
28
|
+
},
|
|
29
|
+
AUDIO: {
|
|
30
|
+
muted: 1,
|
|
31
|
+
defaultMuted: 2
|
|
32
|
+
}
|
|
33
|
+
};
|
|
9
34
|
const ChildProperties = /*#__PURE__*/new Set(["innerHTML", "textContent", "innerText", "children"]);
|
|
10
35
|
const DelegatedEvents = /*#__PURE__*/new Set(["beforeinput", "click", "dblclick", "contextmenu", "focusin", "focusout", "input", "keydown", "keyup", "mousedown", "mousemove", "mouseout", "mouseover", "mouseup", "pointerdown", "pointermove", "pointerout", "pointerover", "pointerup", "touchend", "touchmove", "touchstart"]);
|
|
11
36
|
const SVGElements = /*#__PURE__*/new Set([
|
|
@@ -13,52 +38,163 @@ const SVGElements = /*#__PURE__*/new Set([
|
|
|
13
38
|
"set", "stop",
|
|
14
39
|
"svg", "switch", "symbol", "text", "textPath",
|
|
15
40
|
"tref", "tspan", "use", "view", "vkern"]);
|
|
16
|
-
const
|
|
41
|
+
const MathMLElements = /*#__PURE__*/new Set(["annotation", "annotation-xml", "maction", "math", "menclose", "merror", "mfenced", "mfrac", "mi", "mmultiscripts", "mn", "mo", "mover", "mpadded", "mphantom", "mprescripts", "mroot", "mrow", "ms", "mspace", "msqrt", "mstyle", "msub", "msubsup", "msup", "mtable", "mtd", "mtext", "mtr", "munder", "munderover", "semantics"]);
|
|
42
|
+
const Namespaces = {
|
|
43
|
+
svg: "http://www.w3.org/2000/svg",
|
|
44
|
+
mathml: "http://www.w3.org/1998/Math/MathML",
|
|
17
45
|
xlink: "http://www.w3.org/1999/xlink",
|
|
18
46
|
xml: "http://www.w3.org/XML/1998/namespace"
|
|
19
47
|
};
|
|
20
|
-
const
|
|
21
|
-
"
|
|
22
|
-
"isindex
|
|
48
|
+
const VoidElements = /*#__PURE__*/new Set(["area", "base", "br", "col", "embed", "hr", "img", "input", "link", "meta", "param", "source", "track", "wbr"]);
|
|
49
|
+
const RawTextElements = /*#__PURE__*/new Set(["style", "script", "noscript", "template", "textarea", "title"]);
|
|
50
|
+
const DOMElements = /*#__PURE__*/new Set(/*#__PURE__*/"a,abbr,acronym,address,applet,area,article,aside,audio,b,base,basefont,bdi,bdo,bgsound,big,blink,blockquote,body,br,button,canvas,caption,center,cite,code,col,colgroup,content,data,datalist,dd,del,details,dfn,dialog,dir,div,dl,dt,em,embed,fieldset,figcaption,figure,font,footer,form,frame,frameset,h1,h2,h3,h4,h5,h6,head,header,hgroup,hr,html,i,iframe,image,img,input,ins,isindex,kbd,keygen,label,legend,li,link,listing,main,map,mark,marquee,math,menu,menuitem,meta,meter,multicol,nav,nextid,nobr,noembed,noframes,noindex,noscript,object,ol,optgroup,option,output,p,param,picture,plaintext,portal,pre,progress,q,rb,rp,rt,rtc,ruby,s,samp,script,search,section,select,shadow,slot,small,source,spacer,span,strike,strong,style,sub,summary,sup,svg,table,tbody,td,template,textarea,tfoot,th,thead,time,title,tr,track,tt,u,ul,var,video,wbr,webview,xmp".split(","));
|
|
23
51
|
|
|
24
|
-
const
|
|
25
|
-
transparent: true
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
52
|
+
const transparentOptions = {
|
|
53
|
+
transparent: true,
|
|
54
|
+
sync: true
|
|
55
|
+
};
|
|
56
|
+
const syncOptions = {
|
|
57
|
+
sync: true
|
|
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);
|
|
30
65
|
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
const
|
|
34
|
-
|
|
66
|
+
const DEFAULT_DISABLED_FEATURES = Feature.AggregateError | Feature.BigIntTypedArray;
|
|
67
|
+
const serializeOnlyDisabledFeatures = () => process.env.NODE_ENV === "development" ? 0 : Feature.ErrorPrototypeStack;
|
|
68
|
+
const HYDRATION_GLOBAL = "_$HY.r";
|
|
69
|
+
const DEFAULT_WEB_PLUGINS = Object.freeze([AbortSignalPlugin,
|
|
70
|
+
CustomEventPlugin, DOMExceptionPlugin, EventPlugin,
|
|
71
|
+
FormDataPlugin, HeadersPlugin, ReadableStreamPlugin, RequestPlugin, ResponsePlugin, URLSearchParamsPlugin, URLPlugin]);
|
|
72
|
+
function resolveSerializerPlugins(customPlugins) {
|
|
73
|
+
return customPlugins ? [...customPlugins, ...DEFAULT_WEB_PLUGINS] : [...DEFAULT_WEB_PLUGINS];
|
|
74
|
+
}
|
|
75
|
+
function createSerializer(options) {
|
|
76
|
+
return new Serializer({
|
|
77
|
+
...options,
|
|
78
|
+
plugins: resolveSerializerPlugins(options.plugins),
|
|
79
|
+
disabledFeatures: (options.disabledFeatures === undefined ? DEFAULT_DISABLED_FEATURES : options.disabledFeatures) | serializeOnlyDisabledFeatures()
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
function createHydrationSerializer({
|
|
35
83
|
onData,
|
|
36
84
|
onDone,
|
|
37
85
|
scopeId,
|
|
38
86
|
onError,
|
|
39
|
-
plugins
|
|
87
|
+
plugins
|
|
40
88
|
}) {
|
|
41
|
-
|
|
42
|
-
CustomEventPlugin, DOMExceptionPlugin, EventPlugin,
|
|
43
|
-
FormDataPlugin, HeadersPlugin, ReadableStreamPlugin, RequestPlugin, ResponsePlugin, URLSearchParamsPlugin, URLPlugin];
|
|
44
|
-
const allPlugins = customPlugins ? [...customPlugins, ...defaultPlugins] : defaultPlugins;
|
|
45
|
-
return new Serializer({
|
|
89
|
+
return createSerializer({
|
|
46
90
|
scopeId,
|
|
47
|
-
plugins
|
|
48
|
-
globalIdentifier:
|
|
49
|
-
disabledFeatures: ES2017FLAG,
|
|
91
|
+
plugins,
|
|
92
|
+
globalIdentifier: HYDRATION_GLOBAL,
|
|
50
93
|
onData,
|
|
51
94
|
onDone,
|
|
52
95
|
onError
|
|
53
96
|
});
|
|
54
97
|
}
|
|
55
98
|
function getLocalHeaderScript(id) {
|
|
56
|
-
return getCrossReferenceHeader(id) +
|
|
99
|
+
return getCrossReferenceHeader(id) + ";";
|
|
100
|
+
}
|
|
101
|
+
Feature.RegExp;
|
|
102
|
+
|
|
103
|
+
const HEAD_ELIGIBLE_TAGS = new Set(["title", "meta", "link", "style", "script", "base"]);
|
|
104
|
+
const HEAD_ATTR_NAME = /^[a-zA-Z_][a-zA-Z0-9_:.-]*$/;
|
|
105
|
+
const RESOURCE_LINK_RELS = new Set(["preload", "modulepreload", "prefetch", "preconnect", "dns-prefetch", "stylesheet"]);
|
|
106
|
+
const RESOURCE_QUALIFIERS = ["as", "crossorigin", "type", "media", "imagesrcset", "imagesizes"];
|
|
107
|
+
const STYLESHEET_FETCH_META = new Set(["crossorigin", "integrity", "referrerpolicy", "fetchpriority"]);
|
|
108
|
+
function evalHeadValue(v) {
|
|
109
|
+
return typeof v === "function" ? v() : v;
|
|
110
|
+
}
|
|
111
|
+
function evalHeadProps(props, presets) {
|
|
112
|
+
const out = {};
|
|
113
|
+
for (const name in props) out[name] = presets && name in presets ? presets[name] : evalHeadValue(props[name]);
|
|
114
|
+
return out;
|
|
115
|
+
}
|
|
116
|
+
function classifyHeadTag(desc) {
|
|
117
|
+
const tag = desc.tag;
|
|
118
|
+
if (tag === "link") {
|
|
119
|
+
const rel = evalHeadValue(desc.props && desc.props.rel);
|
|
120
|
+
return {
|
|
121
|
+
resource: RESOURCE_LINK_RELS.has(rel),
|
|
122
|
+
rel
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
if (tag === "style") return {
|
|
126
|
+
resource: !!(desc.props && "href" in desc.props)
|
|
127
|
+
};
|
|
128
|
+
if (tag === "script") return {
|
|
129
|
+
resource: !!(desc.props && "src" in desc.props)
|
|
130
|
+
};
|
|
131
|
+
return {
|
|
132
|
+
resource: false
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
function resourceIdentity(tag, props) {
|
|
136
|
+
let id = "res:" + tag + ":" + (props.rel || "") + ":" + (props.href || props.src || "");
|
|
137
|
+
for (let i = 0; i < RESOURCE_QUALIFIERS.length; i++) {
|
|
138
|
+
const q = RESOURCE_QUALIFIERS[i];
|
|
139
|
+
if (props[q] != null) id += ":" + q + "=" + props[q];
|
|
140
|
+
}
|
|
141
|
+
return id;
|
|
142
|
+
}
|
|
143
|
+
function replaceableIdentity(tag, props, key, unique) {
|
|
144
|
+
if (tag === "title") return "title";
|
|
145
|
+
if (tag === "base") return "base";
|
|
146
|
+
if (tag === "meta" && props.charset != null) return "charset";
|
|
147
|
+
if (key != null) return tag + ":key:" + key;
|
|
148
|
+
if (tag === "meta") {
|
|
149
|
+
for (const ns of ["name", "property", "http-equiv"]) if (props[ns] != null) return "meta:" + ns + ":" + props[ns] + (props.media != null ? ":media=" + props.media : "");
|
|
150
|
+
return unique;
|
|
151
|
+
}
|
|
152
|
+
if (tag === "link") {
|
|
153
|
+
const rel = props.rel || "";
|
|
154
|
+
if (rel === "icon" || rel === "apple-touch-icon") return "link:" + rel + (props.sizes != null ? ":sizes=" + props.sizes : "") + (props.type != null ? ":type=" + props.type : "");
|
|
155
|
+
return "link:" + rel + ":" + (props.href || "");
|
|
156
|
+
}
|
|
157
|
+
return unique;
|
|
158
|
+
}
|
|
159
|
+
function resolveHead(groups) {
|
|
160
|
+
const winners = new Map();
|
|
161
|
+
const sorted = groups.slice().sort((a, b) => a.seq - b.seq);
|
|
162
|
+
for (let i = 0; i < sorted.length; i++) {
|
|
163
|
+
const group = sorted[i];
|
|
164
|
+
const byIdentity = new Map();
|
|
165
|
+
for (let j = 0; j < group.tags.length; j++) {
|
|
166
|
+
const t = group.tags[j];
|
|
167
|
+
let list = byIdentity.get(t.identity);
|
|
168
|
+
if (!list) byIdentity.set(t.identity, list = []);
|
|
169
|
+
list.push(t);
|
|
170
|
+
}
|
|
171
|
+
for (const [identity, tags] of byIdentity) {
|
|
172
|
+
if (identity === "title") {
|
|
173
|
+
if (tags.length > 1) console.warn("Multiple <title> tags in one head group; the last one wins.");
|
|
174
|
+
winners.set(identity, {
|
|
175
|
+
seq: group.seq,
|
|
176
|
+
tags: [tags[tags.length - 1]]
|
|
177
|
+
});
|
|
178
|
+
} else {
|
|
179
|
+
winners.set(identity, {
|
|
180
|
+
seq: group.seq,
|
|
181
|
+
tags
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return winners;
|
|
57
187
|
}
|
|
58
188
|
|
|
189
|
+
function joinAssetPath(base, file) {
|
|
190
|
+
if (/^(?:[a-z][a-z0-9+.-]*:)?\/\//i.test(file)) return file;
|
|
191
|
+
if (typeof base !== "string" || !base) base = "/";
|
|
192
|
+
if (base[base.length - 1] !== "/") base += "/";
|
|
193
|
+
return base + (file[0] === "/" ? file.slice(1) : file);
|
|
194
|
+
}
|
|
59
195
|
function resolveAssets(moduleUrl, manifest) {
|
|
60
196
|
if (!manifest) return null;
|
|
61
|
-
const base = manifest._base
|
|
197
|
+
const base = manifest._base;
|
|
62
198
|
const entry = manifest[moduleUrl];
|
|
63
199
|
if (!entry) return null;
|
|
64
200
|
const css = [];
|
|
@@ -69,8 +205,8 @@ function resolveAssets(moduleUrl, manifest) {
|
|
|
69
205
|
visited.add(key);
|
|
70
206
|
const e = manifest[key];
|
|
71
207
|
if (!e) return;
|
|
72
|
-
js.push(base
|
|
73
|
-
if (e.css) for (let i = 0; i < e.css.length; i++) css.push(base
|
|
208
|
+
js.push(joinAssetPath(base, e.file));
|
|
209
|
+
if (e.css) for (let i = 0; i < e.css.length; i++) css.push(joinAssetPath(base, e.css[i]));
|
|
74
210
|
if (e.imports) for (let i = 0; i < e.imports.length; i++) walk(e.imports[i]);
|
|
75
211
|
};
|
|
76
212
|
walk(moduleUrl);
|
|
@@ -80,7 +216,7 @@ function resolveAssets(moduleUrl, manifest) {
|
|
|
80
216
|
};
|
|
81
217
|
}
|
|
82
218
|
function registerEntryAssets(manifest) {
|
|
83
|
-
if (!manifest) return;
|
|
219
|
+
if (!manifest || typeof manifest === "function" || typeof manifest.resolve === "function") return;
|
|
84
220
|
const ctx = sharedConfig.context;
|
|
85
221
|
if (!ctx?.registerAsset) return;
|
|
86
222
|
for (const key in manifest) {
|
|
@@ -97,25 +233,48 @@ function createAssetTracking() {
|
|
|
97
233
|
const boundaryModules = new Map();
|
|
98
234
|
const boundaryStyles = new Map();
|
|
99
235
|
const emittedAssets = new Set();
|
|
236
|
+
const inlineStyles = new Map();
|
|
100
237
|
let currentBoundaryId = null;
|
|
101
238
|
return {
|
|
102
239
|
boundaryModules,
|
|
103
240
|
boundaryStyles,
|
|
104
241
|
emittedAssets,
|
|
242
|
+
inlineStyles,
|
|
243
|
+
registerInlineStyle(desc) {
|
|
244
|
+
let entry = inlineStyles.get(desc.id);
|
|
245
|
+
if (!entry) {
|
|
246
|
+
entry = {
|
|
247
|
+
id: desc.id,
|
|
248
|
+
content: desc.content || "",
|
|
249
|
+
attrs: desc.attrs,
|
|
250
|
+
emitted: false
|
|
251
|
+
};
|
|
252
|
+
inlineStyles.set(desc.id, entry);
|
|
253
|
+
}
|
|
254
|
+
if (currentBoundaryId) {
|
|
255
|
+
let styles = boundaryStyles.get(currentBoundaryId);
|
|
256
|
+
if (!styles) {
|
|
257
|
+
styles = new Set();
|
|
258
|
+
boundaryStyles.set(currentBoundaryId, styles);
|
|
259
|
+
}
|
|
260
|
+
styles.add(entry);
|
|
261
|
+
}
|
|
262
|
+
return entry;
|
|
263
|
+
},
|
|
105
264
|
get currentBoundaryId() {
|
|
106
265
|
return currentBoundaryId;
|
|
107
266
|
},
|
|
108
267
|
set currentBoundaryId(v) {
|
|
109
268
|
currentBoundaryId = v;
|
|
110
269
|
},
|
|
111
|
-
registerModule(
|
|
112
|
-
|
|
113
|
-
let map = boundaryModules.get(
|
|
270
|
+
registerModule(key, entryUrl) {
|
|
271
|
+
const id = currentBoundaryId || "";
|
|
272
|
+
let map = boundaryModules.get(id);
|
|
114
273
|
if (!map) {
|
|
115
274
|
map = {};
|
|
116
|
-
boundaryModules.set(
|
|
275
|
+
boundaryModules.set(id, map);
|
|
117
276
|
}
|
|
118
|
-
map[
|
|
277
|
+
map[key] = entryUrl;
|
|
119
278
|
},
|
|
120
279
|
getBoundaryModules(id) {
|
|
121
280
|
return boundaryModules.get(id) || null;
|
|
@@ -125,7 +284,24 @@ function createAssetTracking() {
|
|
|
125
284
|
}
|
|
126
285
|
};
|
|
127
286
|
}
|
|
128
|
-
function
|
|
287
|
+
function warnUnresolvedModuleAssets(moduleUrl, warned) {
|
|
288
|
+
if (warned.has(moduleUrl)) return;
|
|
289
|
+
warned.add(moduleUrl);
|
|
290
|
+
console.error(`Asset manifest returned no client assets for module "${moduleUrl}". ` + "If this module is a server-rendered lazy() component, its entry will be missing from " + "the serialized hydration asset map, the client will be unable to preload it, and " + "hydration will fail with 'lazy() module \"…\" was not preloaded before hydration'. " + "This means the integration's asset resolver (dev manifest bridge or build client " + "manifest) failed to answer for this module — check the integration's server logs, " + "restart the dev server, or verify the module is included in the client build.");
|
|
291
|
+
}
|
|
292
|
+
function guardResolvedAssets(moduleUrl, result, warned) {
|
|
293
|
+
if (result && typeof result.then === "function") {
|
|
294
|
+
return result.then(assets => {
|
|
295
|
+
if (!assets || !assets.js || !assets.js.length) warnUnresolvedModuleAssets(moduleUrl, warned);
|
|
296
|
+
return assets;
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
if (!result || !result.js || !result.js.length) warnUnresolvedModuleAssets(moduleUrl, warned);
|
|
300
|
+
return result;
|
|
301
|
+
}
|
|
302
|
+
function applyAssetTracking(context, tracking, manifest, noScripts) {
|
|
303
|
+
const warned = new Set();
|
|
304
|
+
const guard = noScripts ? resolve => resolve : resolve => moduleUrl => guardResolvedAssets(moduleUrl, resolve(moduleUrl), warned);
|
|
129
305
|
Object.defineProperty(context, "_currentBoundaryId", {
|
|
130
306
|
get() {
|
|
131
307
|
return tracking.currentBoundaryId;
|
|
@@ -138,19 +314,329 @@ function applyAssetTracking(context, tracking, manifest) {
|
|
|
138
314
|
});
|
|
139
315
|
context.registerModule = tracking.registerModule;
|
|
140
316
|
context.getBoundaryModules = tracking.getBoundaryModules;
|
|
141
|
-
if (manifest
|
|
317
|
+
if (typeof manifest === "function") {
|
|
318
|
+
context.resolveAssets = guard(manifest);
|
|
319
|
+
} else if (manifest && typeof manifest.resolve === "function") {
|
|
320
|
+
context.resolveAssets = guard(key => manifest.resolve(key));
|
|
321
|
+
if (typeof manifest.resolveSync === "function") {
|
|
322
|
+
context.resolveAssetsSync = key => manifest.resolveSync(key);
|
|
323
|
+
}
|
|
324
|
+
} else if (manifest) {
|
|
325
|
+
const resolve = moduleUrl => resolveAssets(moduleUrl, manifest);
|
|
326
|
+
context.resolveAssets = guard(resolve);
|
|
327
|
+
context.resolveAssetsSync = resolve;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
function isCssUrl(url) {
|
|
331
|
+
const q = url.search(/[?#]/);
|
|
332
|
+
return (q === -1 ? url : url.slice(0, q)).endsWith(".css");
|
|
333
|
+
}
|
|
334
|
+
function createHeadRegistry() {
|
|
335
|
+
return {
|
|
336
|
+
pending: [],
|
|
337
|
+
committed: [],
|
|
338
|
+
seq: 0,
|
|
339
|
+
uniq: 0,
|
|
340
|
+
resources: new Set(),
|
|
341
|
+
eagerHtml: "",
|
|
342
|
+
flushed: null,
|
|
343
|
+
shellFlushed: false
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
function registerHeadTags(registry, context, tracking, emitResource, nonce, tags) {
|
|
347
|
+
const boundary = context._currentBoundaryId || "";
|
|
348
|
+
if (typeof tags === "function") {
|
|
349
|
+
registry.pending.push({
|
|
350
|
+
boundary,
|
|
351
|
+
list: tags,
|
|
352
|
+
resource: (desc, rel) => emitHeadResource(registry, context, tracking, emitResource, nonce, desc, rel)
|
|
353
|
+
});
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
if (!Array.isArray(tags)) tags = [tags];
|
|
357
|
+
let replaceable = null;
|
|
358
|
+
for (let i = 0; i < tags.length; i++) {
|
|
359
|
+
const desc = tags[i];
|
|
360
|
+
if (!desc || !HEAD_ELIGIBLE_TAGS.has(desc.tag)) {
|
|
361
|
+
console.warn(`useHead: ignoring non-head tag`, desc);
|
|
362
|
+
continue;
|
|
363
|
+
}
|
|
364
|
+
const cls = classifyHeadTag(desc);
|
|
365
|
+
if (cls.resource) {
|
|
366
|
+
emitHeadResource(registry, context, tracking, emitResource, nonce, desc, cls.rel);
|
|
367
|
+
} else {
|
|
368
|
+
(replaceable || (replaceable = [])).push(cls.rel !== undefined ? {
|
|
369
|
+
tag: desc.tag,
|
|
370
|
+
props: desc.props,
|
|
371
|
+
key: desc.key,
|
|
372
|
+
rel: cls.rel
|
|
373
|
+
} : desc);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
if (replaceable) registry.pending.push({
|
|
377
|
+
boundary,
|
|
378
|
+
tags: replaceable
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
function emitHeadResource(registry, context, tracking, emitResource, nonce, desc, rel) {
|
|
382
|
+
let props;
|
|
383
|
+
try {
|
|
384
|
+
props = evalHeadProps(desc.props || {}, rel !== undefined ? {
|
|
385
|
+
rel
|
|
386
|
+
} : undefined);
|
|
387
|
+
} catch (err) {
|
|
388
|
+
console.warn(`useHead: error evaluating resource tag props`, err);
|
|
389
|
+
return;
|
|
390
|
+
}
|
|
391
|
+
const identity = resourceIdentity(desc.tag, props);
|
|
392
|
+
if (registry.resources.has(identity)) return;
|
|
393
|
+
registry.resources.add(identity);
|
|
394
|
+
if (desc.tag === "link" && (rel === "stylesheet" || rel === "modulepreload")) {
|
|
395
|
+
let plain = true;
|
|
396
|
+
let gateable = rel === "stylesheet";
|
|
397
|
+
for (const name in props) {
|
|
398
|
+
if (name === "rel" || name === "href") continue;
|
|
399
|
+
plain = false;
|
|
400
|
+
if (!STYLESHEET_FETCH_META.has(name)) gateable = false;
|
|
401
|
+
}
|
|
402
|
+
if (plain && props.href != null) {
|
|
403
|
+
const isCss = isCssUrl(props.href);
|
|
404
|
+
if (rel === "stylesheet" ? isCss : !isCss) {
|
|
405
|
+
context.registerAsset(rel === "stylesheet" ? "style" : "module", props.href);
|
|
406
|
+
return;
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
if (gateable && props.href != null) {
|
|
410
|
+
const attrHtml = renderHeadAttrHtml(props);
|
|
411
|
+
const entry = {
|
|
412
|
+
href: props.href,
|
|
413
|
+
attrHtml,
|
|
414
|
+
attrs: headAttrRecord(props)
|
|
415
|
+
};
|
|
416
|
+
if (tracking.currentBoundaryId) {
|
|
417
|
+
let styles = tracking.boundaryStyles.get(tracking.currentBoundaryId);
|
|
418
|
+
if (!styles) tracking.boundaryStyles.set(tracking.currentBoundaryId, styles = new Set());
|
|
419
|
+
styles.add(entry);
|
|
420
|
+
}
|
|
421
|
+
const markup = `<link${attrHtml}>`;
|
|
422
|
+
if (emitResource) emitResource(markup, entry);else {
|
|
423
|
+
registry.eagerHtml += markup;
|
|
424
|
+
entry.emitted = true;
|
|
425
|
+
}
|
|
426
|
+
return;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
const url = props.href || props.src;
|
|
430
|
+
if (url != null && tracking.emittedAssets.has(url)) return;
|
|
431
|
+
const markup = renderHeadTagMarkup(desc.tag, props, null, nonce);
|
|
432
|
+
if (emitResource) emitResource(markup);else registry.eagerHtml += markup;
|
|
433
|
+
}
|
|
434
|
+
function commitHeadBoundary(registry, boundary, isPendingFragment) {
|
|
435
|
+
const keep = [];
|
|
436
|
+
const groups = [];
|
|
437
|
+
for (let i = 0; i < registry.pending.length; i++) {
|
|
438
|
+
const reg = registry.pending[i];
|
|
439
|
+
const mine = boundary === "" ? !(isPendingFragment && reg.boundary !== "" && isPendingFragment(reg.boundary)) : reg.boundary === boundary;
|
|
440
|
+
if (!mine) {
|
|
441
|
+
keep.push(reg);
|
|
442
|
+
continue;
|
|
443
|
+
}
|
|
444
|
+
let descs = reg.tags;
|
|
445
|
+
if (reg.list) {
|
|
446
|
+
let resolved;
|
|
447
|
+
try {
|
|
448
|
+
resolved = reg.list();
|
|
449
|
+
} catch (err) {
|
|
450
|
+
console.warn(`useHead: error evaluating head group membership`, err);
|
|
451
|
+
continue;
|
|
452
|
+
}
|
|
453
|
+
if (!Array.isArray(resolved)) resolved = [resolved];
|
|
454
|
+
descs = [];
|
|
455
|
+
for (let j = 0; j < resolved.length; j++) {
|
|
456
|
+
const desc = resolved[j];
|
|
457
|
+
if (!desc || !HEAD_ELIGIBLE_TAGS.has(desc.tag)) {
|
|
458
|
+
console.warn(`useHead: ignoring non-head tag`, desc);
|
|
459
|
+
continue;
|
|
460
|
+
}
|
|
461
|
+
const cls = classifyHeadTag(desc);
|
|
462
|
+
if (cls.resource) {
|
|
463
|
+
reg.resource(desc, cls.rel);
|
|
464
|
+
} else {
|
|
465
|
+
descs.push(cls.rel !== undefined ? {
|
|
466
|
+
tag: desc.tag,
|
|
467
|
+
props: desc.props,
|
|
468
|
+
key: desc.key,
|
|
469
|
+
rel: cls.rel
|
|
470
|
+
} : desc);
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
const tags = [];
|
|
475
|
+
for (let j = 0; j < descs.length; j++) {
|
|
476
|
+
const desc = descs[j];
|
|
477
|
+
let props, key;
|
|
478
|
+
try {
|
|
479
|
+
props = evalHeadProps(desc.props || {}, desc.rel !== undefined ? {
|
|
480
|
+
rel: desc.rel
|
|
481
|
+
} : undefined);
|
|
482
|
+
key = evalHeadValue(desc.key);
|
|
483
|
+
} catch (err) {
|
|
484
|
+
console.warn(`useHead: error evaluating tag props`, err);
|
|
485
|
+
continue;
|
|
486
|
+
}
|
|
487
|
+
const identity = replaceableIdentity(desc.tag, props, key, "u:" + registry.uniq++);
|
|
488
|
+
if ((identity === "base" || identity === "charset") && registry.shellFlushed) {
|
|
489
|
+
console.warn(`useHead: <${desc.tag}> (${identity}) registered after shell flush is ignored`);
|
|
490
|
+
continue;
|
|
491
|
+
}
|
|
492
|
+
tags.push({
|
|
493
|
+
tag: desc.tag,
|
|
494
|
+
props,
|
|
495
|
+
identity
|
|
496
|
+
});
|
|
497
|
+
}
|
|
498
|
+
if (tags.length) groups.push({
|
|
499
|
+
seq: registry.seq++,
|
|
500
|
+
tags
|
|
501
|
+
});
|
|
502
|
+
}
|
|
503
|
+
registry.pending = keep;
|
|
504
|
+
for (let i = 0; i < groups.length; i++) registry.committed.push(groups[i]);
|
|
505
|
+
return groups;
|
|
506
|
+
}
|
|
507
|
+
function adoptHeadBoundary(registry, childKey, parentKey) {
|
|
508
|
+
for (let i = 0; i < registry.pending.length; i++) {
|
|
509
|
+
if (registry.pending[i].boundary === childKey) registry.pending[i].boundary = parentKey;
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
function dropHeadBoundary(registry, boundary) {
|
|
513
|
+
registry.pending = registry.pending.filter(reg => reg.boundary !== boundary);
|
|
514
|
+
}
|
|
515
|
+
function headGroupSignature(winner) {
|
|
516
|
+
let sig = "" + winner.seq;
|
|
517
|
+
for (let i = 0; i < winner.tags.length; i++) {
|
|
518
|
+
const t = winner.tags[i];
|
|
519
|
+
sig += "|" + t.tag + JSON.stringify(t.props);
|
|
520
|
+
}
|
|
521
|
+
return sig;
|
|
522
|
+
}
|
|
523
|
+
function renderShellHead(registry, nonce, isPendingFragment) {
|
|
524
|
+
commitHeadBoundary(registry, "", isPendingFragment);
|
|
525
|
+
registry.shellFlushed = true;
|
|
526
|
+
const winners = resolveHead(registry.committed);
|
|
527
|
+
registry.flushed = new Map();
|
|
528
|
+
let prelude = "";
|
|
529
|
+
let links = "";
|
|
530
|
+
let metas = "";
|
|
531
|
+
let others = "";
|
|
532
|
+
let scripts = "";
|
|
533
|
+
for (const [identity, winner] of winners) {
|
|
534
|
+
registry.flushed.set(identity, headGroupSignature(winner));
|
|
535
|
+
for (let i = 0; i < winner.tags.length; i++) {
|
|
536
|
+
const t = winner.tags[i];
|
|
537
|
+
const markup = renderHeadTagMarkup(t.tag, t.props, identity, nonce);
|
|
538
|
+
if (identity === "charset" || identity === "base") prelude += markup;else if (t.tag === "link" || t.tag === "style") links += markup;else if (t.tag === "meta") metas += markup;else if (t.tag === "script") scripts += markup;else others += markup;
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
return {
|
|
542
|
+
prelude,
|
|
543
|
+
html: registry.eagerHtml + links + metas + others + scripts
|
|
544
|
+
};
|
|
545
|
+
}
|
|
546
|
+
function flushHeadFragment(registry, boundary) {
|
|
547
|
+
const groups = commitHeadBoundary(registry, boundary);
|
|
548
|
+
if (!groups.length) return null;
|
|
549
|
+
const winners = resolveHead(registry.committed);
|
|
550
|
+
const affected = new Set();
|
|
551
|
+
for (let i = 0; i < groups.length; i++) for (let j = 0; j < groups[i].tags.length; j++) affected.add(groups[i].tags[j].identity);
|
|
552
|
+
const ops = [];
|
|
553
|
+
for (const identity of affected) {
|
|
554
|
+
const winner = winners.get(identity);
|
|
555
|
+
const sig = headGroupSignature(winner);
|
|
556
|
+
if (registry.flushed.get(identity) === sig) continue;
|
|
557
|
+
const existed = registry.flushed.has(identity);
|
|
558
|
+
registry.flushed.set(identity, sig);
|
|
559
|
+
if (identity === "title") {
|
|
560
|
+
const children = winner.tags[0].props.children;
|
|
561
|
+
ops.push(["t", children == null ? "" : String(children)]);
|
|
562
|
+
continue;
|
|
563
|
+
}
|
|
564
|
+
if (existed) ops.push(["r", identity]);
|
|
565
|
+
for (let i = 0; i < winner.tags.length; i++) {
|
|
566
|
+
const t = winner.tags[i];
|
|
567
|
+
const attrs = {};
|
|
568
|
+
for (const name in t.props) {
|
|
569
|
+
if (name === "children" || name === "ref" || name.slice(0, 2) === "on") continue;
|
|
570
|
+
if (!HEAD_ATTR_NAME.test(name)) {
|
|
571
|
+
console.warn(`useHead: ignoring invalid attribute name "${name}"`);
|
|
572
|
+
continue;
|
|
573
|
+
}
|
|
574
|
+
const v = t.props[name];
|
|
575
|
+
if (v == null || v === false) continue;
|
|
576
|
+
attrs[name] = v === true ? "" : String(v);
|
|
577
|
+
}
|
|
578
|
+
const children = t.props.children;
|
|
579
|
+
ops.push(["a", identity, t.tag, attrs, children == null ? null : String(children)]);
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
return ops.length ? ops : null;
|
|
583
|
+
}
|
|
584
|
+
function renderHeadAttrHtml(props) {
|
|
585
|
+
let attrs = "";
|
|
586
|
+
for (const name in props) {
|
|
587
|
+
if (name === "children" || name === "ref" || name.slice(0, 2) === "on") continue;
|
|
588
|
+
if (!HEAD_ATTR_NAME.test(name)) {
|
|
589
|
+
console.warn(`useHead: ignoring invalid attribute name "${name}"`);
|
|
590
|
+
continue;
|
|
591
|
+
}
|
|
592
|
+
const v = props[name];
|
|
593
|
+
if (v == null || v === false) continue;
|
|
594
|
+
attrs += v === true ? ` ${name}` : ` ${name}="${escape(String(v), true)}"`;
|
|
595
|
+
}
|
|
596
|
+
return attrs;
|
|
597
|
+
}
|
|
598
|
+
function headAttrRecord(props, skipRelHref) {
|
|
599
|
+
let attrs = null;
|
|
600
|
+
for (const name in props) {
|
|
601
|
+
if (name === "children" || name === "ref" || name.slice(0, 2) === "on") continue;
|
|
602
|
+
if ((name === "rel" || name === "href")) continue;
|
|
603
|
+
if (!HEAD_ATTR_NAME.test(name)) continue;
|
|
604
|
+
const v = props[name];
|
|
605
|
+
if (v == null || v === false) continue;
|
|
606
|
+
(attrs || (attrs = {}))[name] = v === true ? "" : String(v);
|
|
607
|
+
}
|
|
608
|
+
return attrs;
|
|
609
|
+
}
|
|
610
|
+
function renderHeadTagMarkup(tag, props, identity, nonce) {
|
|
611
|
+
let attrs = renderHeadAttrHtml(props);
|
|
612
|
+
if (identity != null) attrs += ` data-dh="${escape(identity, true)}"`;
|
|
613
|
+
if (nonce && (tag === "script" || tag === "style")) attrs += ` nonce="${nonce}"`;
|
|
614
|
+
if (tag === "meta" || tag === "link" || tag === "base") return `<${tag}${attrs}>`;
|
|
615
|
+
let body = props.children == null ? "" : String(props.children);
|
|
616
|
+
if (tag === "script") body = body.replace(/<\/(script)/gi, "<\\/$1");else if (tag === "style") body = escapeStyleContent(body);else body = escape(body);
|
|
617
|
+
return `<${tag}${attrs}>${body}</${tag}>`;
|
|
618
|
+
}
|
|
619
|
+
function useHead(tags) {
|
|
620
|
+
const ctx = sharedConfig.context;
|
|
621
|
+
if (!ctx || !ctx.registerHeadTags) {
|
|
622
|
+
console.warn("useHead() called outside of a server render; registration ignored.");
|
|
623
|
+
return;
|
|
624
|
+
}
|
|
625
|
+
ctx.registerHeadTags(tags);
|
|
142
626
|
}
|
|
143
627
|
const VOID_ELEMENTS = /^(?:area|base|br|col|embed|hr|img|input|keygen|link|menuitem|meta|param|source|track|wbr)$/i;
|
|
144
|
-
const REPLACE_SCRIPT = `function $df(e,n,o,t){if(n=document.getElementById(e)
|
|
628
|
+
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])}`;
|
|
629
|
+
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)}`;
|
|
145
630
|
function renderToString(code, options = {}) {
|
|
146
631
|
const {
|
|
147
632
|
renderId = "",
|
|
148
633
|
nonce,
|
|
149
634
|
noScripts,
|
|
150
|
-
manifest
|
|
635
|
+
manifest,
|
|
636
|
+
onHead
|
|
151
637
|
} = options;
|
|
152
638
|
let scripts = "";
|
|
153
|
-
const serializer =
|
|
639
|
+
const serializer = createHydrationSerializer({
|
|
154
640
|
scopeId: renderId,
|
|
155
641
|
plugins: options.plugins,
|
|
156
642
|
onData(script) {
|
|
@@ -163,12 +649,16 @@ function renderToString(code, options = {}) {
|
|
|
163
649
|
onError: options.onError
|
|
164
650
|
});
|
|
165
651
|
const tracking = createAssetTracking();
|
|
652
|
+
const headRegistry = createHeadRegistry();
|
|
166
653
|
sharedConfig.context = {
|
|
167
654
|
assets: [],
|
|
168
655
|
nonce,
|
|
169
656
|
escape: escape,
|
|
170
657
|
resolve: resolveSSRNode,
|
|
171
658
|
ssr: ssr,
|
|
659
|
+
registerHeadTags(tags) {
|
|
660
|
+
registerHeadTags(headRegistry, sharedConfig.context, tracking, null, nonce, tags);
|
|
661
|
+
},
|
|
172
662
|
serialize(id, p) {
|
|
173
663
|
if (sharedConfig.context.noHydrate) return;
|
|
174
664
|
if (p != null && typeof p === "object" && (typeof p.then === "function" || typeof p[Symbol.asyncIterator] === "function")) {
|
|
@@ -176,19 +666,23 @@ function renderToString(code, options = {}) {
|
|
|
176
666
|
}
|
|
177
667
|
serializer.write(id, p);
|
|
178
668
|
},
|
|
179
|
-
registerAsset(type,
|
|
669
|
+
registerAsset(type, value) {
|
|
670
|
+
if (type === "inline-style") {
|
|
671
|
+
tracking.registerInlineStyle(value);
|
|
672
|
+
return;
|
|
673
|
+
}
|
|
180
674
|
if (tracking.currentBoundaryId && type === "style") {
|
|
181
675
|
let styles = tracking.boundaryStyles.get(tracking.currentBoundaryId);
|
|
182
676
|
if (!styles) {
|
|
183
677
|
styles = new Set();
|
|
184
678
|
tracking.boundaryStyles.set(tracking.currentBoundaryId, styles);
|
|
185
679
|
}
|
|
186
|
-
styles.add(
|
|
680
|
+
styles.add(value);
|
|
187
681
|
}
|
|
188
|
-
tracking.emittedAssets.add(
|
|
682
|
+
tracking.emittedAssets.add(value);
|
|
189
683
|
}
|
|
190
684
|
};
|
|
191
|
-
applyAssetTracking(sharedConfig.context, tracking, manifest);
|
|
685
|
+
applyAssetTracking(sharedConfig.context, tracking, manifest, noScripts);
|
|
192
686
|
registerEntryAssets(manifest);
|
|
193
687
|
let html = createRoot(d => {
|
|
194
688
|
setTimeout(d);
|
|
@@ -196,12 +690,12 @@ function renderToString(code, options = {}) {
|
|
|
196
690
|
}, {
|
|
197
691
|
id: renderId
|
|
198
692
|
});
|
|
693
|
+
serializeFragmentAssets("", tracking.boundaryModules, sharedConfig.context);
|
|
199
694
|
sharedConfig.context.noHydrate = true;
|
|
200
695
|
serializer.close();
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
return html;
|
|
696
|
+
const assetsHtml = resolveAssetsHtml(sharedConfig.context.assets);
|
|
697
|
+
const head = renderShellHead(headRegistry, nonce, null);
|
|
698
|
+
return assembleDocument(html, assetsHtml, tracking.emittedAssets, tracking.inlineStyles, scripts.length ? scripts : "", nonce, head, onHead);
|
|
205
699
|
}
|
|
206
700
|
function renderToStream(code, options = {}) {
|
|
207
701
|
let {
|
|
@@ -210,18 +704,57 @@ function renderToStream(code, options = {}) {
|
|
|
210
704
|
onCompleteAll,
|
|
211
705
|
renderId = "",
|
|
212
706
|
noScripts,
|
|
213
|
-
manifest
|
|
707
|
+
manifest,
|
|
708
|
+
onHead
|
|
214
709
|
} = options;
|
|
215
710
|
let dispose;
|
|
711
|
+
let dead = false;
|
|
712
|
+
const abandon = () => {
|
|
713
|
+
if (dead) return;
|
|
714
|
+
dead = true;
|
|
715
|
+
completed = true;
|
|
716
|
+
buffer = {
|
|
717
|
+
write() {}
|
|
718
|
+
};
|
|
719
|
+
writable = {
|
|
720
|
+
end() {}
|
|
721
|
+
};
|
|
722
|
+
if (dispose) {
|
|
723
|
+
const d = dispose;
|
|
724
|
+
dispose = () => {};
|
|
725
|
+
d();
|
|
726
|
+
}
|
|
727
|
+
};
|
|
728
|
+
const guardSink = w => ({
|
|
729
|
+
write(payload) {
|
|
730
|
+
if (dead) return;
|
|
731
|
+
try {
|
|
732
|
+
w.write(payload);
|
|
733
|
+
} catch (_) {
|
|
734
|
+
abandon();
|
|
735
|
+
}
|
|
736
|
+
},
|
|
737
|
+
end() {
|
|
738
|
+
if (dead) return;
|
|
739
|
+
try {
|
|
740
|
+
w.end();
|
|
741
|
+
} catch (_) {
|
|
742
|
+
abandon();
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
});
|
|
216
746
|
const blockingPromises = new Set();
|
|
747
|
+
let headerEmitted = false;
|
|
217
748
|
const pushTask = task => {
|
|
218
749
|
if (noScripts) return;
|
|
219
|
-
if (!
|
|
220
|
-
|
|
750
|
+
if (!headerEmitted) {
|
|
751
|
+
headerEmitted = true;
|
|
752
|
+
tasks += getLocalHeaderScript(renderId);
|
|
221
753
|
}
|
|
222
754
|
tasks += task + ";";
|
|
223
755
|
if (!timer && firstFlushed) {
|
|
224
|
-
timer =
|
|
756
|
+
timer = true;
|
|
757
|
+
queue(() => queue(writeTasks));
|
|
225
758
|
}
|
|
226
759
|
};
|
|
227
760
|
const onDone = () => {
|
|
@@ -236,15 +769,63 @@ function renderToStream(code, options = {}) {
|
|
|
236
769
|
completed = true;
|
|
237
770
|
if (firstFlushed) dispose();
|
|
238
771
|
};
|
|
239
|
-
const
|
|
772
|
+
const sink = {
|
|
773
|
+
data(payload) {
|
|
774
|
+
pushTask(payload);
|
|
775
|
+
},
|
|
776
|
+
fragment(key, value, meta) {
|
|
777
|
+
const deferActivation = !!meta.revealGroup;
|
|
778
|
+
const styles = meta.styles;
|
|
779
|
+
for (let i = 0; i < styles.inline.length; i++) {
|
|
780
|
+
buffer.write(renderInlineStyle(styles.inline[i], nonce));
|
|
781
|
+
}
|
|
782
|
+
if (styles.links.length) {
|
|
783
|
+
emitTask(`$dfs("${key}",${styles.links.length},${deferActivation ? 1 : 0})`);
|
|
784
|
+
writeTasks();
|
|
785
|
+
for (const entry of styles.links) {
|
|
786
|
+
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}')">`);
|
|
787
|
+
}
|
|
788
|
+
buffer.write(`<template id="${key}">${value}</template>`);
|
|
789
|
+
} else {
|
|
790
|
+
buffer.write(`<template id="${key}">${value}</template>`);
|
|
791
|
+
if (!deferActivation) {
|
|
792
|
+
emitTask(`$df("${key}")`);
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
},
|
|
796
|
+
reveal(keys, meta) {
|
|
797
|
+
emitTask(`${meta.fallback ? "$dflj" : "$dfj"}(${JSON.stringify(keys)})`);
|
|
798
|
+
},
|
|
799
|
+
asset(type, value) {
|
|
800
|
+
if (type === "module") {
|
|
801
|
+
buffer.write(`<link rel="modulepreload" href="${value}">`);
|
|
802
|
+
} else if (type === "inline-style") {
|
|
803
|
+
buffer.write(renderInlineStyle(value, nonce));
|
|
804
|
+
} else if (type === "head-tag") {
|
|
805
|
+
buffer.write(value);
|
|
806
|
+
}
|
|
807
|
+
},
|
|
808
|
+
shell(shellHtml, meta) {
|
|
809
|
+
buffer.write(assembleDocument(shellHtml, meta.assets, meta.preloads, meta.inlineStyles, meta.tasks.length ? meta.tasks : "", nonce, meta.head, onHead));
|
|
810
|
+
},
|
|
811
|
+
...options.sink
|
|
812
|
+
};
|
|
813
|
+
const serializer = (options.serializer || createHydrationSerializer)({
|
|
240
814
|
scopeId: options.renderId,
|
|
241
815
|
plugins: options.plugins,
|
|
242
|
-
onData:
|
|
816
|
+
onData: payload => sink.data(payload),
|
|
243
817
|
onDone,
|
|
244
818
|
onError: options.onError
|
|
245
819
|
});
|
|
820
|
+
let rootAssetsSerialized = false;
|
|
821
|
+
const serializeRootAssets = () => {
|
|
822
|
+
if (rootAssetsSerialized) return;
|
|
823
|
+
rootAssetsSerialized = true;
|
|
824
|
+
serializeFragmentAssets("", tracking.boundaryModules, context);
|
|
825
|
+
};
|
|
246
826
|
const flushEnd = () => {
|
|
247
827
|
if (!registry.size) {
|
|
828
|
+
serializeRootAssets();
|
|
248
829
|
queue(() => queue(() => serializer.flush()));
|
|
249
830
|
}
|
|
250
831
|
};
|
|
@@ -254,7 +835,6 @@ function renderToStream(code, options = {}) {
|
|
|
254
835
|
buffer.write(`<script${nonce ? ` nonce="${nonce}"` : ""}>${tasks}</script>`);
|
|
255
836
|
tasks = "";
|
|
256
837
|
}
|
|
257
|
-
timer && clearTimeout(timer);
|
|
258
838
|
timer = null;
|
|
259
839
|
};
|
|
260
840
|
let context;
|
|
@@ -266,7 +846,29 @@ function renderToStream(code, options = {}) {
|
|
|
266
846
|
let shellCompleted = false;
|
|
267
847
|
let scriptFlushed = false;
|
|
268
848
|
let headStyles;
|
|
849
|
+
const revealGroups = new Map();
|
|
269
850
|
let timer = null;
|
|
851
|
+
const emitTask = task => {
|
|
852
|
+
pushTask(`${task}${!scriptFlushed ? ";" + REPLACE_SCRIPT : ""}`);
|
|
853
|
+
scriptFlushed = true;
|
|
854
|
+
};
|
|
855
|
+
function resolveRevealKeys(groupOrKeys, release, consume) {
|
|
856
|
+
if (Array.isArray(groupOrKeys)) return groupOrKeys.slice();
|
|
857
|
+
let group = revealGroups.get(groupOrKeys);
|
|
858
|
+
if (!group) {
|
|
859
|
+
if (!release) return;
|
|
860
|
+
group = {
|
|
861
|
+
order: [],
|
|
862
|
+
keys: new Set(),
|
|
863
|
+
released: true
|
|
864
|
+
};
|
|
865
|
+
revealGroups.set(groupOrKeys, group);
|
|
866
|
+
} else if (release) group.released = true;
|
|
867
|
+
if (!group.order.length) return;
|
|
868
|
+
const keys = group.order.slice();
|
|
869
|
+
if (consume) revealGroups.delete(groupOrKeys);
|
|
870
|
+
return keys;
|
|
871
|
+
}
|
|
270
872
|
let rootHoles = null;
|
|
271
873
|
let nextHoleId = 0;
|
|
272
874
|
let buffer = {
|
|
@@ -275,24 +877,48 @@ function renderToStream(code, options = {}) {
|
|
|
275
877
|
}
|
|
276
878
|
};
|
|
277
879
|
const tracking = createAssetTracking();
|
|
880
|
+
const headRegistry = createHeadRegistry();
|
|
881
|
+
let headScriptFlushed = false;
|
|
882
|
+
const emitHeadOps = (key, ops) => {
|
|
883
|
+
const payload = JSON.stringify(ops).replace(/</g, "\\u003C");
|
|
884
|
+
emitTask(`${!headScriptFlushed ? HEAD_SCRIPT : ""}(_$HY.hp=_$HY.hp||{})[${JSON.stringify(key)}]=${payload}`);
|
|
885
|
+
headScriptFlushed = true;
|
|
886
|
+
};
|
|
278
887
|
sharedConfig.context = context = {
|
|
279
888
|
async: true,
|
|
280
889
|
assets: [],
|
|
281
890
|
nonce,
|
|
282
|
-
|
|
891
|
+
registerHeadTags(tags) {
|
|
892
|
+
registerHeadTags(headRegistry, context, tracking,
|
|
893
|
+
(markup, gateEntry) => {
|
|
894
|
+
if (!firstFlushed) {
|
|
895
|
+
headRegistry.eagerHtml += markup;
|
|
896
|
+
if (gateEntry) gateEntry.emitted = true;
|
|
897
|
+
} else if (!gateEntry || !tracking.currentBoundaryId) {
|
|
898
|
+
sink.asset("head-tag", markup);
|
|
899
|
+
}
|
|
900
|
+
}, nonce, tags);
|
|
901
|
+
},
|
|
902
|
+
registerAsset(type, value) {
|
|
903
|
+
if (type === "inline-style") {
|
|
904
|
+
const entry = tracking.registerInlineStyle(value);
|
|
905
|
+
if (firstFlushed && !tracking.currentBoundaryId && !entry.emitted) {
|
|
906
|
+
entry.emitted = true;
|
|
907
|
+
sink.asset("inline-style", entry);
|
|
908
|
+
}
|
|
909
|
+
return;
|
|
910
|
+
}
|
|
283
911
|
if (tracking.currentBoundaryId && type === "style") {
|
|
284
912
|
let styles = tracking.boundaryStyles.get(tracking.currentBoundaryId);
|
|
285
913
|
if (!styles) {
|
|
286
914
|
styles = new Set();
|
|
287
915
|
tracking.boundaryStyles.set(tracking.currentBoundaryId, styles);
|
|
288
916
|
}
|
|
289
|
-
styles.add(
|
|
917
|
+
styles.add(value);
|
|
290
918
|
}
|
|
291
|
-
if (!tracking.emittedAssets.has(
|
|
292
|
-
tracking.emittedAssets.add(
|
|
293
|
-
if (firstFlushed
|
|
294
|
-
buffer.write(`<link rel="modulepreload" href="${url}">`);
|
|
295
|
-
}
|
|
919
|
+
if (!tracking.emittedAssets.has(value)) {
|
|
920
|
+
tracking.emittedAssets.add(value);
|
|
921
|
+
if (firstFlushed) sink.asset(type, value);
|
|
296
922
|
}
|
|
297
923
|
},
|
|
298
924
|
block(p) {
|
|
@@ -316,7 +942,26 @@ function renderToStream(code, options = {}) {
|
|
|
316
942
|
escape: escape,
|
|
317
943
|
resolve: resolveSSRNode,
|
|
318
944
|
ssr: ssr,
|
|
319
|
-
registerFragment(key) {
|
|
945
|
+
registerFragment(key, options) {
|
|
946
|
+
const revealGroup = options && options.revealGroup;
|
|
947
|
+
if (revealGroup) {
|
|
948
|
+
let group = revealGroups.get(revealGroup);
|
|
949
|
+
if (!group) {
|
|
950
|
+
group = {
|
|
951
|
+
order: [],
|
|
952
|
+
keys: new Set(),
|
|
953
|
+
released: false
|
|
954
|
+
};
|
|
955
|
+
revealGroups.set(revealGroup, group);
|
|
956
|
+
}
|
|
957
|
+
if (!group.keys.has(key)) {
|
|
958
|
+
group.keys.add(key);
|
|
959
|
+
group.order.push(key);
|
|
960
|
+
}
|
|
961
|
+
if (group.released) {
|
|
962
|
+
throw new Error("registerFragment() for reveal group '" + revealGroup + "' was called after revealFragments(). Ensure template payload is emitted before grouped reveal.");
|
|
963
|
+
}
|
|
964
|
+
}
|
|
320
965
|
if (!registry.has(key)) {
|
|
321
966
|
let resolve, reject;
|
|
322
967
|
const p = new Promise((r, rej) => (resolve = r, reject = rej));
|
|
@@ -326,7 +971,7 @@ function renderToStream(code, options = {}) {
|
|
|
326
971
|
queue(flushEnd);
|
|
327
972
|
}))
|
|
328
973
|
});
|
|
329
|
-
serializer.write(key, p);
|
|
974
|
+
serializer.write(key + "_fr", p);
|
|
330
975
|
}
|
|
331
976
|
return (value, error) => {
|
|
332
977
|
if (registry.has(key)) {
|
|
@@ -344,10 +989,12 @@ function renderToStream(code, options = {}) {
|
|
|
344
989
|
parent.children[key] = value !== undefined ? value : "";
|
|
345
990
|
serializeFragmentAssets(key, tracking.boundaryModules, context);
|
|
346
991
|
propagateBoundaryStyles(key, parentKey, tracking);
|
|
992
|
+
adoptHeadBoundary(headRegistry, key, parentKey);
|
|
347
993
|
item.resolve();
|
|
348
994
|
return;
|
|
349
995
|
}
|
|
350
996
|
if (!completed) {
|
|
997
|
+
if (error) dropHeadBoundary(headRegistry, key);
|
|
351
998
|
if (!firstFlushed) {
|
|
352
999
|
queue(() => html = replacePlaceholder(html, key, value !== undefined ? value : ""));
|
|
353
1000
|
serializeFragmentAssets(key, tracking.boundaryModules, context);
|
|
@@ -355,28 +1002,36 @@ function renderToStream(code, options = {}) {
|
|
|
355
1002
|
} else {
|
|
356
1003
|
serializeFragmentAssets(key, tracking.boundaryModules, context);
|
|
357
1004
|
const styles = collectStreamStyles(key, tracking, headStyles);
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
buffer.write(`<template id="${key}">${value !== undefined ? value : " "}</template>`);
|
|
366
|
-
} else {
|
|
367
|
-
buffer.write(`<template id="${key}">${value !== undefined ? value : " "}</template>`);
|
|
368
|
-
pushTask(`$df("${key}")${!scriptFlushed ? ";" + REPLACE_SCRIPT : ""}`);
|
|
369
|
-
scriptFlushed = true;
|
|
370
|
-
}
|
|
1005
|
+
const headOps = error ? null : flushHeadFragment(headRegistry, key);
|
|
1006
|
+
if (headOps) emitHeadOps(key, headOps);
|
|
1007
|
+
sink.fragment(key, value !== undefined ? value : " ", {
|
|
1008
|
+
styles,
|
|
1009
|
+
revealGroup,
|
|
1010
|
+
error
|
|
1011
|
+
});
|
|
371
1012
|
item.resolve(error);
|
|
372
1013
|
}
|
|
373
1014
|
}
|
|
374
1015
|
}
|
|
375
1016
|
return firstFlushed;
|
|
376
1017
|
};
|
|
1018
|
+
},
|
|
1019
|
+
revealFragments(groupOrKeys) {
|
|
1020
|
+
const keys = resolveRevealKeys(groupOrKeys, true, true);
|
|
1021
|
+
if (!keys) return;
|
|
1022
|
+
sink.reveal(keys, {
|
|
1023
|
+
fallback: false
|
|
1024
|
+
});
|
|
1025
|
+
},
|
|
1026
|
+
revealFallbacks(groupOrKeys) {
|
|
1027
|
+
const keys = resolveRevealKeys(groupOrKeys, false, false);
|
|
1028
|
+
if (!keys) return;
|
|
1029
|
+
sink.reveal(keys, {
|
|
1030
|
+
fallback: true
|
|
1031
|
+
});
|
|
377
1032
|
}
|
|
378
1033
|
};
|
|
379
|
-
applyAssetTracking(context, tracking, manifest);
|
|
1034
|
+
applyAssetTracking(context, tracking, manifest, noScripts);
|
|
380
1035
|
registerEntryAssets(manifest);
|
|
381
1036
|
let html = createRoot(d => {
|
|
382
1037
|
dispose = d;
|
|
@@ -397,28 +1052,56 @@ function renderToStream(code, options = {}) {
|
|
|
397
1052
|
}, {
|
|
398
1053
|
id: renderId
|
|
399
1054
|
});
|
|
400
|
-
function
|
|
401
|
-
if (
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
1055
|
+
function resolveRootHoles() {
|
|
1056
|
+
if (!rootHoles) return true;
|
|
1057
|
+
const pending = [];
|
|
1058
|
+
for (const {
|
|
1059
|
+
id,
|
|
1060
|
+
fn
|
|
1061
|
+
} of rootHoles) {
|
|
1062
|
+
const marker = `<!--rh${id}-->`;
|
|
1063
|
+
const res = resolveSSRNode(fn);
|
|
1064
|
+
if (!res.h.length) {
|
|
1065
|
+
html = html.replace(marker, res.t[0]);
|
|
1066
|
+
} else {
|
|
1067
|
+
let out = res.t[0];
|
|
1068
|
+
for (let j = 0; j < res.h.length; j++) {
|
|
1069
|
+
const newId = nextHoleId++;
|
|
1070
|
+
pending.push({
|
|
1071
|
+
id: newId,
|
|
1072
|
+
fn: res.h[j]
|
|
1073
|
+
});
|
|
1074
|
+
out += `<!--rh${newId}-->` + res.t[j + 1];
|
|
1075
|
+
}
|
|
1076
|
+
html = html.replace(marker, out);
|
|
1077
|
+
for (const p of res.p) blockingPromises.add(p);
|
|
410
1078
|
}
|
|
411
|
-
rootHoles = null;
|
|
412
1079
|
}
|
|
1080
|
+
if (pending.length) {
|
|
1081
|
+
rootHoles = pending;
|
|
1082
|
+
return false;
|
|
1083
|
+
}
|
|
1084
|
+
rootHoles = null;
|
|
1085
|
+
return true;
|
|
1086
|
+
}
|
|
1087
|
+
function doShell() {
|
|
1088
|
+
if (shellCompleted) return;
|
|
413
1089
|
sharedConfig.context = context;
|
|
414
|
-
|
|
1090
|
+
if (!resolveRootHoles()) return;
|
|
1091
|
+
const assetsHtml = resolveAssetsHtml(context.assets);
|
|
415
1092
|
headStyles = new Set();
|
|
416
1093
|
for (const url of tracking.emittedAssets) {
|
|
417
|
-
if (url
|
|
1094
|
+
if (isCssUrl(url)) headStyles.add(url);
|
|
418
1095
|
}
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
1096
|
+
serializeRootAssets();
|
|
1097
|
+
const head = renderShellHead(headRegistry, nonce, k => registry.has(k));
|
|
1098
|
+
sink.shell(html, {
|
|
1099
|
+
assets: assetsHtml,
|
|
1100
|
+
preloads: tracking.emittedAssets,
|
|
1101
|
+
inlineStyles: tracking.inlineStyles,
|
|
1102
|
+
tasks,
|
|
1103
|
+
head
|
|
1104
|
+
});
|
|
422
1105
|
tasks = "";
|
|
423
1106
|
onCompleteShell && onCompleteShell({
|
|
424
1107
|
write(v) {
|
|
@@ -427,53 +1110,67 @@ function renderToStream(code, options = {}) {
|
|
|
427
1110
|
});
|
|
428
1111
|
shellCompleted = true;
|
|
429
1112
|
}
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
1113
|
+
const MIN_DRAIN_TURNS = 8;
|
|
1114
|
+
let lastBlockingSize = -1;
|
|
1115
|
+
let lastRegistrySize = -1;
|
|
1116
|
+
let drainTurn = 0;
|
|
1117
|
+
const scheduleFlush = fn => {
|
|
1118
|
+
const attempt = () => {
|
|
1119
|
+
if (registry.size !== lastRegistrySize || drainTurn++ < MIN_DRAIN_TURNS) {
|
|
1120
|
+
if (registry.size !== lastRegistrySize) drainTurn = 0;
|
|
1121
|
+
lastRegistrySize = registry.size;
|
|
1122
|
+
queue(attempt);
|
|
1123
|
+
return;
|
|
435
1124
|
}
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
1125
|
+
fn();
|
|
1126
|
+
};
|
|
1127
|
+
const progressed = blockingPromises.size !== lastBlockingSize;
|
|
1128
|
+
lastBlockingSize = blockingPromises.size;
|
|
1129
|
+
lastRegistrySize = -1;
|
|
1130
|
+
drainTurn = 0;
|
|
1131
|
+
progressed ? queue(attempt) : setTimeout(attempt);
|
|
1132
|
+
};
|
|
1133
|
+
let cachedReadable;
|
|
1134
|
+
let consumer;
|
|
1135
|
+
const claimConsumer = name => {
|
|
1136
|
+
if (consumer && consumer !== name) {
|
|
1137
|
+
throw new Error(`renderToStream result was already consumed via \`${consumer}\`; cannot also consume it via \`${name}\`. Use exactly one of \`pipe\`, \`pipeTo\`, or \`readable\`.`);
|
|
1138
|
+
}
|
|
1139
|
+
consumer = name;
|
|
1140
|
+
};
|
|
1141
|
+
const pipeToImpl = w => {
|
|
1142
|
+
let resolve;
|
|
1143
|
+
const p = new Promise(r => resolve = r);
|
|
1144
|
+
function flush() {
|
|
446
1145
|
allSettled(blockingPromises).then(() => {
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
buffer = writable = w;
|
|
450
|
-
buffer.write(tmp);
|
|
451
|
-
firstFlushed = true;
|
|
452
|
-
if (completed) {
|
|
453
|
-
dispose();
|
|
454
|
-
writable.end();
|
|
455
|
-
} else flushEnd();
|
|
456
|
-
});
|
|
457
|
-
});
|
|
458
|
-
},
|
|
459
|
-
pipeTo(w) {
|
|
460
|
-
return allSettled(blockingPromises).then(() => {
|
|
461
|
-
let resolve;
|
|
462
|
-
const p = new Promise(r => resolve = r);
|
|
463
|
-
setTimeout(() => {
|
|
1146
|
+
scheduleFlush(() => {
|
|
1147
|
+
if (dead) return resolve();
|
|
464
1148
|
doShell();
|
|
1149
|
+
if (!shellCompleted) return flush();
|
|
465
1150
|
const encoder = new TextEncoder();
|
|
466
1151
|
const writer = w.getWriter();
|
|
1152
|
+
let pendingWrites = Promise.resolve();
|
|
1153
|
+
let ended = false;
|
|
1154
|
+
const failed = () => {
|
|
1155
|
+
if (!ended) {
|
|
1156
|
+
abandon();
|
|
1157
|
+
resolve();
|
|
1158
|
+
}
|
|
1159
|
+
};
|
|
1160
|
+
writer.closed && writer.closed.catch(failed);
|
|
467
1161
|
writable = {
|
|
468
1162
|
end() {
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
1163
|
+
pendingWrites.then(() => {
|
|
1164
|
+
ended = true;
|
|
1165
|
+
writer.releaseLock();
|
|
1166
|
+
w.close().catch(() => {});
|
|
1167
|
+
resolve();
|
|
1168
|
+
});
|
|
472
1169
|
}
|
|
473
1170
|
};
|
|
474
1171
|
buffer = {
|
|
475
1172
|
write(payload) {
|
|
476
|
-
writer.write(encoder.encode(payload)).catch(
|
|
1173
|
+
pendingWrites = pendingWrites.then(() => writer.write(encoder.encode(payload))).catch(failed);
|
|
477
1174
|
}
|
|
478
1175
|
};
|
|
479
1176
|
buffer.write(tmp);
|
|
@@ -483,9 +1180,67 @@ function renderToStream(code, options = {}) {
|
|
|
483
1180
|
writable.end();
|
|
484
1181
|
} else flushEnd();
|
|
485
1182
|
});
|
|
486
|
-
return p;
|
|
487
1183
|
});
|
|
488
1184
|
}
|
|
1185
|
+
flush();
|
|
1186
|
+
return p;
|
|
1187
|
+
};
|
|
1188
|
+
return {
|
|
1189
|
+
then(fn) {
|
|
1190
|
+
function complete() {
|
|
1191
|
+
dispose();
|
|
1192
|
+
fn(tmp);
|
|
1193
|
+
}
|
|
1194
|
+
if (onCompleteAll) {
|
|
1195
|
+
let ogComplete = onCompleteAll;
|
|
1196
|
+
onCompleteAll = options => {
|
|
1197
|
+
ogComplete(options);
|
|
1198
|
+
complete();
|
|
1199
|
+
};
|
|
1200
|
+
} else onCompleteAll = complete;
|
|
1201
|
+
function flush() {
|
|
1202
|
+
allSettled(blockingPromises).then(() => {
|
|
1203
|
+
scheduleFlush(() => {
|
|
1204
|
+
if (!resolveRootHoles()) return flush();
|
|
1205
|
+
queue(flushEnd);
|
|
1206
|
+
});
|
|
1207
|
+
});
|
|
1208
|
+
}
|
|
1209
|
+
flush();
|
|
1210
|
+
},
|
|
1211
|
+
pipe(w) {
|
|
1212
|
+
claimConsumer("pipe");
|
|
1213
|
+
function flush() {
|
|
1214
|
+
allSettled(blockingPromises).then(() => {
|
|
1215
|
+
scheduleFlush(() => {
|
|
1216
|
+
if (dead) return;
|
|
1217
|
+
doShell();
|
|
1218
|
+
if (!shellCompleted) return flush();
|
|
1219
|
+
buffer = writable = guardSink(w);
|
|
1220
|
+
buffer.write(tmp);
|
|
1221
|
+
firstFlushed = true;
|
|
1222
|
+
if (completed) {
|
|
1223
|
+
dispose();
|
|
1224
|
+
writable.end();
|
|
1225
|
+
} else flushEnd();
|
|
1226
|
+
});
|
|
1227
|
+
});
|
|
1228
|
+
}
|
|
1229
|
+
flush();
|
|
1230
|
+
},
|
|
1231
|
+
pipeTo(w) {
|
|
1232
|
+
claimConsumer("pipeTo");
|
|
1233
|
+
return pipeToImpl(w);
|
|
1234
|
+
},
|
|
1235
|
+
get readable() {
|
|
1236
|
+
claimConsumer("readable");
|
|
1237
|
+
if (!cachedReadable) {
|
|
1238
|
+
const t = new TransformStream();
|
|
1239
|
+
pipeToImpl(t.writable);
|
|
1240
|
+
cachedReadable = t.readable;
|
|
1241
|
+
}
|
|
1242
|
+
return cachedReadable;
|
|
1243
|
+
}
|
|
489
1244
|
};
|
|
490
1245
|
}
|
|
491
1246
|
function HydrationScript(props) {
|
|
@@ -497,11 +1252,176 @@ function HydrationScript(props) {
|
|
|
497
1252
|
...props
|
|
498
1253
|
}));
|
|
499
1254
|
}
|
|
500
|
-
function
|
|
501
|
-
|
|
1255
|
+
function ssrGroup(fn, n) {
|
|
1256
|
+
fn.$g = n;
|
|
1257
|
+
return fn;
|
|
1258
|
+
}
|
|
1259
|
+
function buildAsyncWrap(err, node) {
|
|
1260
|
+
const p = ssrHandleError(err);
|
|
1261
|
+
if (!p) return null;
|
|
1262
|
+
const owner = getOwner();
|
|
502
1263
|
return {
|
|
1264
|
+
fn: owner ? () => runWithOwner(owner, node) : node,
|
|
1265
|
+
p
|
|
1266
|
+
};
|
|
1267
|
+
}
|
|
1268
|
+
function ssrFirstGroupHit(hole) {
|
|
1269
|
+
try {
|
|
1270
|
+
return hole();
|
|
1271
|
+
} catch (err) {
|
|
1272
|
+
return buildAsyncWrap(err, hole);
|
|
1273
|
+
}
|
|
1274
|
+
}
|
|
1275
|
+
function tryResolveFunctionHole(hole) {
|
|
1276
|
+
let value;
|
|
1277
|
+
try {
|
|
1278
|
+
value = hole();
|
|
1279
|
+
} catch (err) {
|
|
1280
|
+
return buildAsyncWrap(err, hole) || "";
|
|
1281
|
+
}
|
|
1282
|
+
const t = typeof value;
|
|
1283
|
+
if (t === "string") return value;
|
|
1284
|
+
if (t === "number") return "" + value;
|
|
1285
|
+
if (value == null || t === "boolean") return "";
|
|
1286
|
+
return tryResolveString(value);
|
|
1287
|
+
}
|
|
1288
|
+
function mergeTemplateInto(result, node) {
|
|
1289
|
+
result.t[result.t.length - 1] += node.t[0];
|
|
1290
|
+
if (node.t.length > 1) {
|
|
1291
|
+
result.t.push(...node.t.slice(1));
|
|
1292
|
+
result.h.push(...node.h);
|
|
1293
|
+
result.p.push(...node.p);
|
|
1294
|
+
}
|
|
1295
|
+
}
|
|
1296
|
+
function appendResolvedNode(result, node) {
|
|
1297
|
+
if (node.fn !== undefined) {
|
|
1298
|
+
result.h.push(node.fn);
|
|
1299
|
+
result.p.push(node.p);
|
|
1300
|
+
result.t.push("");
|
|
1301
|
+
} else if (node.merge !== undefined) mergeTemplateInto(result, node.merge);else resolveSSRNode(node.bail, result);
|
|
1302
|
+
}
|
|
1303
|
+
let _lastGroupFn = null;
|
|
1304
|
+
let _lastGroupArr = null;
|
|
1305
|
+
let _lastGroupErr = null;
|
|
1306
|
+
function ssrGroupSlot(fn, idx) {
|
|
1307
|
+
return () => {
|
|
1308
|
+
if (idx > 0 && _lastGroupFn === fn) {
|
|
1309
|
+
if (_lastGroupArr !== null) return _lastGroupArr[idx];
|
|
1310
|
+
throw _lastGroupErr;
|
|
1311
|
+
}
|
|
1312
|
+
_lastGroupFn = fn;
|
|
1313
|
+
_lastGroupArr = null;
|
|
1314
|
+
_lastGroupErr = null;
|
|
1315
|
+
try {
|
|
1316
|
+
_lastGroupArr = fn();
|
|
1317
|
+
return _lastGroupArr[idx];
|
|
1318
|
+
} catch (err) {
|
|
1319
|
+
_lastGroupErr = err;
|
|
1320
|
+
throw err;
|
|
1321
|
+
}
|
|
1322
|
+
};
|
|
1323
|
+
}
|
|
1324
|
+
function ssr(t) {
|
|
1325
|
+
const len = arguments.length;
|
|
1326
|
+
if (len === 1) return {
|
|
503
1327
|
t
|
|
504
1328
|
};
|
|
1329
|
+
let s = t[0];
|
|
1330
|
+
let result = null;
|
|
1331
|
+
let lastGroup = null;
|
|
1332
|
+
let lastGroupVal = null;
|
|
1333
|
+
let lastGroupIdx = 0;
|
|
1334
|
+
for (let i = 1; i < len; i++) {
|
|
1335
|
+
const hole = arguments[i];
|
|
1336
|
+
const ht = typeof hole;
|
|
1337
|
+
if (ht === "string") {
|
|
1338
|
+
if (result === null) s += hole;else result.t[result.t.length - 1] += hole;
|
|
1339
|
+
} else if (ht === "number") {
|
|
1340
|
+
if (result === null) s += hole;else result.t[result.t.length - 1] += hole;
|
|
1341
|
+
} else if (hole == null || ht === "boolean") ; else if (ht === "function" && hole.$g) {
|
|
1342
|
+
let value;
|
|
1343
|
+
let hasValue = false;
|
|
1344
|
+
if (lastGroup !== hole) {
|
|
1345
|
+
const r = ssrFirstGroupHit(hole);
|
|
1346
|
+
if (r !== null) {
|
|
1347
|
+
lastGroup = hole;
|
|
1348
|
+
lastGroupVal = r;
|
|
1349
|
+
lastGroupIdx = 0;
|
|
1350
|
+
if (!Array.isArray(r) && result === null) {
|
|
1351
|
+
result = {
|
|
1352
|
+
t: [s],
|
|
1353
|
+
h: [],
|
|
1354
|
+
p: []
|
|
1355
|
+
};
|
|
1356
|
+
s = "";
|
|
1357
|
+
}
|
|
1358
|
+
}
|
|
1359
|
+
}
|
|
1360
|
+
if (lastGroup === hole) {
|
|
1361
|
+
if (Array.isArray(lastGroupVal)) {
|
|
1362
|
+
value = lastGroupVal[lastGroupIdx++];
|
|
1363
|
+
hasValue = true;
|
|
1364
|
+
} else {
|
|
1365
|
+
result.h.push(ssrGroupSlot(lastGroupVal.fn, lastGroupIdx++));
|
|
1366
|
+
result.p.push(lastGroupVal.p);
|
|
1367
|
+
result.t.push("");
|
|
1368
|
+
}
|
|
1369
|
+
}
|
|
1370
|
+
if (hasValue) {
|
|
1371
|
+
const vt = typeof value;
|
|
1372
|
+
if (vt === "string" || vt === "number") {
|
|
1373
|
+
if (result === null) s += value;else result.t[result.t.length - 1] += value;
|
|
1374
|
+
} else if (value == null || vt === "boolean") ; else if (result !== null) {
|
|
1375
|
+
resolveSSRNode(value, result);
|
|
1376
|
+
} else {
|
|
1377
|
+
const rs = tryResolveString(value);
|
|
1378
|
+
if (typeof rs === "string") {
|
|
1379
|
+
s += rs;
|
|
1380
|
+
} else {
|
|
1381
|
+
result = {
|
|
1382
|
+
t: [s],
|
|
1383
|
+
h: [],
|
|
1384
|
+
p: []
|
|
1385
|
+
};
|
|
1386
|
+
s = "";
|
|
1387
|
+
if (rs.merge !== undefined) mergeTemplateInto(result, rs.merge);else resolveSSRNode(rs.bail, result);
|
|
1388
|
+
}
|
|
1389
|
+
}
|
|
1390
|
+
}
|
|
1391
|
+
} else if (result !== null) {
|
|
1392
|
+
resolveSSRNode(hole, result);
|
|
1393
|
+
} else if (ht === "function") {
|
|
1394
|
+
const r = tryResolveFunctionHole(hole);
|
|
1395
|
+
if (typeof r === "string") s += r;else {
|
|
1396
|
+
result = {
|
|
1397
|
+
t: [s],
|
|
1398
|
+
h: [],
|
|
1399
|
+
p: []
|
|
1400
|
+
};
|
|
1401
|
+
s = "";
|
|
1402
|
+
appendResolvedNode(result, r);
|
|
1403
|
+
}
|
|
1404
|
+
} else {
|
|
1405
|
+
const r = tryResolveString(hole);
|
|
1406
|
+
if (typeof r === "string") {
|
|
1407
|
+
s += r;
|
|
1408
|
+
} else {
|
|
1409
|
+
result = {
|
|
1410
|
+
t: [s],
|
|
1411
|
+
h: [],
|
|
1412
|
+
p: []
|
|
1413
|
+
};
|
|
1414
|
+
s = "";
|
|
1415
|
+
appendResolvedNode(result, r);
|
|
1416
|
+
}
|
|
1417
|
+
}
|
|
1418
|
+
const next = t[i];
|
|
1419
|
+
if (result === null) s += next;else result.t[result.t.length - 1] += next;
|
|
1420
|
+
}
|
|
1421
|
+
if (result === null) return {
|
|
1422
|
+
t: s
|
|
1423
|
+
};
|
|
1424
|
+
return result;
|
|
505
1425
|
}
|
|
506
1426
|
function ssrClassName(value) {
|
|
507
1427
|
if (!value) return "";
|
|
@@ -514,7 +1434,7 @@ function ssrClassName(value) {
|
|
|
514
1434
|
classValue = !!value[key];
|
|
515
1435
|
if (!key || key === "undefined" || !classValue) continue;
|
|
516
1436
|
i && (result += " ");
|
|
517
|
-
result += escape(key);
|
|
1437
|
+
result += escape(key, true);
|
|
518
1438
|
}
|
|
519
1439
|
return result;
|
|
520
1440
|
}
|
|
@@ -524,8 +1444,8 @@ function ssrStyle(value) {
|
|
|
524
1444
|
let result = "";
|
|
525
1445
|
const k = Object.keys(value);
|
|
526
1446
|
for (let i = 0; i < k.length; i++) {
|
|
527
|
-
const s = k[i];
|
|
528
|
-
const v = value[
|
|
1447
|
+
const s = escape(k[i], true);
|
|
1448
|
+
const v = value[k[i]];
|
|
529
1449
|
if (v != undefined) {
|
|
530
1450
|
if (i) result += ";";
|
|
531
1451
|
const r = escape(v, true);
|
|
@@ -540,10 +1460,11 @@ function ssrStyleProperty(name, value) {
|
|
|
540
1460
|
return value != null ? name + value : "";
|
|
541
1461
|
}
|
|
542
1462
|
function ssrElement(tag, props, children, needsId) {
|
|
1463
|
+
const hk = needsId ? ssrHydrationKey() : "";
|
|
543
1464
|
if (props == null) props = {};else if (typeof props === "function") props = props();
|
|
544
1465
|
const skipChildren = VOID_ELEMENTS.test(tag);
|
|
545
1466
|
const keys = Object.keys(props);
|
|
546
|
-
let result = `<${tag}${
|
|
1467
|
+
let result = `<${tag}${hk} `;
|
|
547
1468
|
for (let i = 0; i < keys.length; i++) {
|
|
548
1469
|
const prop = keys[i];
|
|
549
1470
|
if (ChildProperties.has(prop)) {
|
|
@@ -582,18 +1503,31 @@ function escape(s, attr) {
|
|
|
582
1503
|
const t = typeof s;
|
|
583
1504
|
if (t !== "string") {
|
|
584
1505
|
if (!attr && Array.isArray(s)) {
|
|
1506
|
+
const joined = tryJoinPlainSSRArray(s);
|
|
1507
|
+
if (joined !== undefined) return joined;
|
|
585
1508
|
s = s.slice();
|
|
586
1509
|
for (let i = 0; i < s.length; i++) s[i] = escape(s[i]);
|
|
587
1510
|
return s;
|
|
588
1511
|
}
|
|
589
|
-
if (attr
|
|
1512
|
+
if (attr) {
|
|
1513
|
+
if (s == null || t === "boolean" || t === "number") return s;
|
|
1514
|
+
return escape(String(s), attr);
|
|
1515
|
+
}
|
|
590
1516
|
return s;
|
|
591
1517
|
}
|
|
1518
|
+
const i = s.search(attr ? ESCAPE_ATTR : ESCAPE_CONTENT);
|
|
1519
|
+
if (i < 0) return s;
|
|
1520
|
+
return escapeSlow(s, attr, i);
|
|
1521
|
+
}
|
|
1522
|
+
const ESCAPE_CONTENT = /[&<]/;
|
|
1523
|
+
const ESCAPE_ATTR = /[&"]/;
|
|
1524
|
+
function escapeSlow(s, attr, start) {
|
|
592
1525
|
const delim = attr ? '"' : "<";
|
|
1526
|
+
const delimCode = attr ? 34 : 60;
|
|
593
1527
|
const escDelim = attr ? """ : "<";
|
|
594
|
-
|
|
595
|
-
let
|
|
596
|
-
|
|
1528
|
+
const c0 = s.charCodeAt(start);
|
|
1529
|
+
let iDelim = c0 === delimCode ? start : s.indexOf(delim, start);
|
|
1530
|
+
let iAmp = c0 === 38 ? start : s.indexOf("&", start);
|
|
597
1531
|
let left = 0,
|
|
598
1532
|
out = "";
|
|
599
1533
|
while (iDelim >= 0 && iAmp >= 0) {
|
|
@@ -624,28 +1558,17 @@ function escape(s, attr) {
|
|
|
624
1558
|
}
|
|
625
1559
|
return left < s.length ? out + s.substring(left) : out;
|
|
626
1560
|
}
|
|
627
|
-
function
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
if (
|
|
633
|
-
|
|
634
|
-
for (const key in descriptors) {
|
|
635
|
-
if (key in target) continue;
|
|
636
|
-
Object.defineProperty(target, key, {
|
|
637
|
-
enumerable: true,
|
|
638
|
-
get() {
|
|
639
|
-
for (let i = sources.length - 1; i >= 0; i--) {
|
|
640
|
-
const v = (sources[i] || {})[key];
|
|
641
|
-
if (v !== undefined) return v;
|
|
642
|
-
}
|
|
643
|
-
}
|
|
644
|
-
});
|
|
645
|
-
}
|
|
1561
|
+
function tryJoinPlainSSRArray(nodes) {
|
|
1562
|
+
if (nodes.length === 0) return undefined;
|
|
1563
|
+
let out = "";
|
|
1564
|
+
for (let i = 0, len = nodes.length; i < len; i++) {
|
|
1565
|
+
const node = nodes[i];
|
|
1566
|
+
if (node == null || typeof node !== "object" || node.h || typeof node.t !== "string") {
|
|
1567
|
+
return undefined;
|
|
646
1568
|
}
|
|
1569
|
+
out += node.t;
|
|
647
1570
|
}
|
|
648
|
-
return
|
|
1571
|
+
return out;
|
|
649
1572
|
}
|
|
650
1573
|
function getHydrationKey() {
|
|
651
1574
|
const hydrate = sharedConfig.context;
|
|
@@ -663,11 +1586,14 @@ function getAssets() {
|
|
|
663
1586
|
for (let i = 0, len = assets.length; i < len; i++) out += assets[i]();
|
|
664
1587
|
return out;
|
|
665
1588
|
}
|
|
1589
|
+
function Assets(props) {
|
|
1590
|
+
useAssets(() => props.children);
|
|
1591
|
+
}
|
|
666
1592
|
function generateHydrationScript({
|
|
667
1593
|
eventNames = ["click", "input"],
|
|
668
1594
|
nonce
|
|
669
1595
|
} = {}) {
|
|
670
|
-
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('",
|
|
1596
|
+
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-->`;
|
|
671
1597
|
}
|
|
672
1598
|
function queue(fn) {
|
|
673
1599
|
return Promise.resolve().then(fn);
|
|
@@ -679,27 +1605,58 @@ function allSettled(promises) {
|
|
|
679
1605
|
return;
|
|
680
1606
|
});
|
|
681
1607
|
}
|
|
682
|
-
function
|
|
683
|
-
if (!assets || !assets.length) return
|
|
1608
|
+
function resolveAssetsHtml(assets) {
|
|
1609
|
+
if (!assets || !assets.length) return "";
|
|
684
1610
|
let out = "";
|
|
685
1611
|
for (let i = 0, len = assets.length; i < len; i++) out += assets[i]();
|
|
686
|
-
|
|
687
|
-
if (index === -1) return html;
|
|
688
|
-
return html.slice(0, index) + out + html.slice(index);
|
|
1612
|
+
return out;
|
|
689
1613
|
}
|
|
690
|
-
function
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
1614
|
+
function assembleDocument(html, assetsHtml, emittedAssets, inlineStyles, scripts, nonce, headTags, onHead) {
|
|
1615
|
+
const scriptTag = scripts ? `<script${nonce ? ` nonce="${nonce}"` : ""}>${scripts}</script>` : "";
|
|
1616
|
+
const headTagsHtml = headTags ? headTags.html : "";
|
|
1617
|
+
const headPrelude = headTags ? headTags.prelude : "";
|
|
1618
|
+
if (!onHead && !assetsHtml && !headTagsHtml && !headPrelude && !(emittedAssets && emittedAssets.size) && !(inlineStyles && inlineStyles.size)) {
|
|
1619
|
+
if (!scriptTag) return html;
|
|
1620
|
+
const xs = html.indexOf("<!--xs-->");
|
|
1621
|
+
return xs === -1 ? html + scriptTag : html.slice(0, xs) + scriptTag + html.slice(xs);
|
|
1622
|
+
}
|
|
1623
|
+
if (headPrelude) {
|
|
1624
|
+
const open = html.match(/<head(?:\s[^>]*)?>/);
|
|
1625
|
+
if (open) {
|
|
1626
|
+
const at = open.index + open[0].length;
|
|
1627
|
+
html = html.slice(0, at) + headPrelude + html.slice(at);
|
|
1628
|
+
}
|
|
1629
|
+
}
|
|
1630
|
+
const headIdx = html.indexOf("</head>");
|
|
1631
|
+
if (headIdx === -1) {
|
|
1632
|
+
if (onHead) {
|
|
1633
|
+
onHead(headPrelude + headTagsHtml + (assetsHtml || "") + renderHeadAssets(emittedAssets, inlineStyles, nonce));
|
|
1634
|
+
}
|
|
1635
|
+
if (!scriptTag) return html;
|
|
1636
|
+
const xs = html.indexOf("<!--xs-->");
|
|
1637
|
+
return xs === -1 ? html + scriptTag : html.slice(0, xs) + scriptTag + html.slice(xs);
|
|
1638
|
+
}
|
|
1639
|
+
const head = headTagsHtml + (assetsHtml || "") + renderHeadAssets(emittedAssets, inlineStyles, nonce);
|
|
1640
|
+
if (!scriptTag) return html.slice(0, headIdx) + head + html.slice(headIdx);
|
|
1641
|
+
const xsIdx = html.indexOf("<!--xs-->");
|
|
1642
|
+
if (xsIdx === -1) return html.slice(0, headIdx) + head + html.slice(headIdx) + scriptTag;
|
|
1643
|
+
return xsIdx < headIdx ? html.slice(0, xsIdx) + scriptTag + html.slice(xsIdx, headIdx) + head + html.slice(headIdx) : html.slice(0, headIdx) + head + html.slice(headIdx, xsIdx) + scriptTag + html.slice(xsIdx);
|
|
1644
|
+
}
|
|
1645
|
+
function renderHeadAssets(emittedAssets, inlineStyles, nonce) {
|
|
1646
|
+
let head = "";
|
|
1647
|
+
if (emittedAssets && emittedAssets.size) {
|
|
1648
|
+
for (const url of emittedAssets) {
|
|
1649
|
+
head += isCssUrl(url) ? `<link rel="stylesheet" href="${url}">` : `<link rel="modulepreload" href="${url}">`;
|
|
1650
|
+
}
|
|
1651
|
+
}
|
|
1652
|
+
if (inlineStyles && inlineStyles.size) {
|
|
1653
|
+
for (const entry of inlineStyles.values()) {
|
|
1654
|
+
if (entry.emitted) continue;
|
|
1655
|
+
entry.emitted = true;
|
|
1656
|
+
head += renderInlineStyle(entry, nonce);
|
|
698
1657
|
}
|
|
699
1658
|
}
|
|
700
|
-
|
|
701
|
-
if (index === -1) return html;
|
|
702
|
-
return html.slice(0, index) + links + html.slice(index);
|
|
1659
|
+
return head;
|
|
703
1660
|
}
|
|
704
1661
|
function serializeFragmentAssets(key, boundaryModules, context) {
|
|
705
1662
|
const map = boundaryModules.get(key);
|
|
@@ -720,22 +1677,41 @@ function propagateBoundaryStyles(childKey, parentKey, tracking) {
|
|
|
720
1677
|
}
|
|
721
1678
|
function collectStreamStyles(key, tracking, headStyles) {
|
|
722
1679
|
const styles = tracking.getBoundaryStyles(key);
|
|
723
|
-
|
|
724
|
-
const
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
1680
|
+
const links = [];
|
|
1681
|
+
const inline = [];
|
|
1682
|
+
if (!styles) return {
|
|
1683
|
+
links,
|
|
1684
|
+
inline
|
|
1685
|
+
};
|
|
1686
|
+
for (const entry of styles) {
|
|
1687
|
+
if (typeof entry === "string") {
|
|
1688
|
+
if (!headStyles || !headStyles.has(entry)) links.push(entry);
|
|
1689
|
+
} else if (entry.emitted) {
|
|
1690
|
+
continue;
|
|
1691
|
+
} else if (entry.attrHtml !== undefined) {
|
|
1692
|
+
entry.emitted = true;
|
|
1693
|
+
links.push(entry);
|
|
1694
|
+
} else {
|
|
1695
|
+
entry.emitted = true;
|
|
1696
|
+
inline.push(entry);
|
|
728
1697
|
}
|
|
729
1698
|
}
|
|
730
|
-
return
|
|
1699
|
+
return {
|
|
1700
|
+
links,
|
|
1701
|
+
inline
|
|
1702
|
+
};
|
|
1703
|
+
}
|
|
1704
|
+
function escapeStyleContent(content) {
|
|
1705
|
+
return content.replace(/<\/(style)/gi, "<\\/$1");
|
|
731
1706
|
}
|
|
732
|
-
function
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
1707
|
+
function renderInlineStyle(entry, nonce) {
|
|
1708
|
+
let attrs = "";
|
|
1709
|
+
if (entry.attrs) {
|
|
1710
|
+
for (const name in entry.attrs) {
|
|
1711
|
+
attrs += ` ${name}="${escape(String(entry.attrs[name]), true)}"`;
|
|
1712
|
+
}
|
|
737
1713
|
}
|
|
738
|
-
return
|
|
1714
|
+
return `<style${nonce ? ` nonce="${nonce}"` : ""} data-asset="${escape(entry.id, true)}"${attrs}>${escapeStyleContent(entry.content)}</style>`;
|
|
739
1715
|
}
|
|
740
1716
|
function waitForFragments(registry, key) {
|
|
741
1717
|
for (const k of [...registry.keys()].reverse()) {
|
|
@@ -765,19 +1741,49 @@ function flattenClassList(list, result) {
|
|
|
765
1741
|
if (Array.isArray(item)) flattenClassList(item, result);else if (typeof item === "object" && item != null) Object.assign(result, item);else if (item || item === 0) result[item] = true;
|
|
766
1742
|
}
|
|
767
1743
|
}
|
|
768
|
-
function
|
|
769
|
-
t
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
1744
|
+
function tryResolveString(node) {
|
|
1745
|
+
const t = typeof node;
|
|
1746
|
+
if (t === "string") return node;
|
|
1747
|
+
if (t === "number") return "" + node;
|
|
1748
|
+
if (node == null || t === "boolean") return "";
|
|
1749
|
+
if (t === "object") {
|
|
1750
|
+
if (Array.isArray(node)) {
|
|
1751
|
+
const joined = tryJoinPlainSSRArray(node);
|
|
1752
|
+
if (joined !== undefined) return joined;
|
|
1753
|
+
let s = "";
|
|
1754
|
+
let prevNonObj = false;
|
|
1755
|
+
for (let i = 0, len = node.length; i < len; i++) {
|
|
1756
|
+
const item = node[i];
|
|
1757
|
+
const itemNonObj = item !== null && typeof item !== "object";
|
|
1758
|
+
if (prevNonObj && itemNonObj) s += "<!--!$-->";
|
|
1759
|
+
prevNonObj = itemNonObj;
|
|
1760
|
+
const r = tryResolveString(item);
|
|
1761
|
+
if (typeof r !== "string") return {
|
|
1762
|
+
bail: node
|
|
1763
|
+
};
|
|
1764
|
+
s += r;
|
|
1765
|
+
}
|
|
1766
|
+
return s;
|
|
1767
|
+
}
|
|
1768
|
+
if (node.h && node.h.length > 0) return {
|
|
1769
|
+
merge: node
|
|
1770
|
+
};
|
|
1771
|
+
if (node.t === undefined) {
|
|
1772
|
+
console.warn(`Unrecognized value. Skipped inserting`, node);
|
|
1773
|
+
return "";
|
|
1774
|
+
}
|
|
1775
|
+
return Array.isArray(node.t) ? node.t[0] : node.t;
|
|
778
1776
|
}
|
|
779
|
-
|
|
780
|
-
|
|
1777
|
+
if (t === "function") {
|
|
1778
|
+
let v;
|
|
1779
|
+
try {
|
|
1780
|
+
v = node();
|
|
1781
|
+
} catch (err) {
|
|
1782
|
+
return buildAsyncWrap(err, node) || "";
|
|
1783
|
+
}
|
|
1784
|
+
return tryResolveString(v);
|
|
1785
|
+
}
|
|
1786
|
+
return "";
|
|
781
1787
|
}
|
|
782
1788
|
function resolveSSRNode(node, result = {
|
|
783
1789
|
t: [""],
|
|
@@ -788,10 +1794,13 @@ function resolveSSRNode(node, result = {
|
|
|
788
1794
|
if (t === "string" || t === "number") {
|
|
789
1795
|
result.t[result.t.length - 1] += node;
|
|
790
1796
|
} else if (node == null || t === "boolean") ; else if (Array.isArray(node)) {
|
|
791
|
-
let
|
|
1797
|
+
let prevNonObj = false;
|
|
792
1798
|
for (let i = 0, len = node.length; i < len; i++) {
|
|
793
|
-
|
|
794
|
-
|
|
1799
|
+
const item = node[i];
|
|
1800
|
+
const itemNonObj = item !== null && typeof item !== "object";
|
|
1801
|
+
if (!top && prevNonObj && itemNonObj) result.t[result.t.length - 1] += `<!--!$-->`;
|
|
1802
|
+
prevNonObj = itemNonObj;
|
|
1803
|
+
resolveSSRNode(item, result);
|
|
795
1804
|
}
|
|
796
1805
|
} else if (t === "object") {
|
|
797
1806
|
if (node.h) {
|
|
@@ -801,15 +1810,17 @@ function resolveSSRNode(node, result = {
|
|
|
801
1810
|
result.h.push(...node.h);
|
|
802
1811
|
result.p.push(...node.p);
|
|
803
1812
|
}
|
|
804
|
-
} else
|
|
1813
|
+
} else if (node.t !== undefined) {
|
|
1814
|
+
result.t[result.t.length - 1] += node.t;
|
|
1815
|
+
} else console.warn(`Unrecognized value. Skipped inserting`, node);
|
|
805
1816
|
} else if (t === "function") {
|
|
806
1817
|
try {
|
|
807
1818
|
resolveSSRNode(node(), result);
|
|
808
1819
|
} catch (err) {
|
|
809
|
-
const
|
|
810
|
-
if (
|
|
811
|
-
result.h.push(
|
|
812
|
-
result.p.push(p);
|
|
1820
|
+
const wrap = buildAsyncWrap(err, node);
|
|
1821
|
+
if (wrap) {
|
|
1822
|
+
result.h.push(wrap.fn);
|
|
1823
|
+
result.p.push(wrap.p);
|
|
813
1824
|
result.t.push("");
|
|
814
1825
|
}
|
|
815
1826
|
}
|
|
@@ -821,39 +1832,188 @@ function resolveSSRSync(node) {
|
|
|
821
1832
|
if (!res.h.length) return res.t[0];
|
|
822
1833
|
throw new Error("This value cannot be rendered synchronously. Are you missing a boundary?");
|
|
823
1834
|
}
|
|
824
|
-
const RequestContext = Symbol();
|
|
1835
|
+
const RequestContext = Symbol.for("solid.RequestContext");
|
|
825
1836
|
function getRequestEvent() {
|
|
826
1837
|
return globalThis[RequestContext] ? globalThis[RequestContext].getStore() || sharedConfig.context && sharedConfig.context.event || console.warn("RequestEvent is missing. This is most likely due to accessing `getRequestEvent` non-managed async scope in a partially polyfilled environment. Try moving it above all `await` calls.") : undefined;
|
|
827
1838
|
}
|
|
828
1839
|
function renderToStringAsync(code, options = {}) {
|
|
829
1840
|
return new Promise(resolve => renderToStream(code, options).then(resolve));
|
|
830
1841
|
}
|
|
1842
|
+
function registerElementClaim() {
|
|
1843
|
+
return noopCleanup;
|
|
1844
|
+
}
|
|
1845
|
+
function noopCleanup() {}
|
|
1846
|
+
function claimElement(node) {
|
|
1847
|
+
return node;
|
|
1848
|
+
}
|
|
1849
|
+
function claimElementTree(root) {
|
|
1850
|
+
return root;
|
|
1851
|
+
}
|
|
831
1852
|
function notSup() {
|
|
832
1853
|
throw new Error("Client-only API called on the server side. Run client-only code in onMount, or conditionally run client-only component with <Show>.");
|
|
833
1854
|
}
|
|
834
1855
|
|
|
1856
|
+
const ENVELOPE = Symbol.for("solid.ResponseEnvelope");
|
|
1857
|
+
class ResponseEnvelope {
|
|
1858
|
+
constructor(response, value) {
|
|
1859
|
+
this.response = response;
|
|
1860
|
+
this.value = value;
|
|
1861
|
+
}
|
|
1862
|
+
}
|
|
1863
|
+
ResponseEnvelope.prototype[ENVELOPE] = true;
|
|
1864
|
+
function isResponseEnvelope(value) {
|
|
1865
|
+
return !!(value && typeof value === "object" && value[ENVELOPE]);
|
|
1866
|
+
}
|
|
1867
|
+
const HREF = Symbol.for("solid.Href");
|
|
1868
|
+
function isHref(value) {
|
|
1869
|
+
return !!(value && (typeof value === "object" || typeof value === "function") && value[HREF]);
|
|
1870
|
+
}
|
|
1871
|
+
const REVALIDATE_HEADER = "X-Revalidate";
|
|
1872
|
+
function initWithRevalidate(init) {
|
|
1873
|
+
const {
|
|
1874
|
+
revalidate,
|
|
1875
|
+
...responseInit
|
|
1876
|
+
} = init;
|
|
1877
|
+
const headers = new Headers(responseInit.headers);
|
|
1878
|
+
revalidate !== undefined && headers.set(REVALIDATE_HEADER, revalidate.toString());
|
|
1879
|
+
return {
|
|
1880
|
+
responseInit,
|
|
1881
|
+
headers
|
|
1882
|
+
};
|
|
1883
|
+
}
|
|
1884
|
+
function redirect(url, init = 302) {
|
|
1885
|
+
if (typeof url !== "string" && !isHref(url)) {
|
|
1886
|
+
throw new TypeError("redirect() expects a string URL or an Href-branded value (Symbol.for('solid.Href')).");
|
|
1887
|
+
}
|
|
1888
|
+
const {
|
|
1889
|
+
responseInit,
|
|
1890
|
+
headers
|
|
1891
|
+
} = initWithRevalidate(typeof init === "number" ? {
|
|
1892
|
+
status: init
|
|
1893
|
+
} : init);
|
|
1894
|
+
if (responseInit.status === undefined) {
|
|
1895
|
+
responseInit.status = 302;
|
|
1896
|
+
}
|
|
1897
|
+
headers.set("Location", String(url));
|
|
1898
|
+
return new Response(null, {
|
|
1899
|
+
...responseInit,
|
|
1900
|
+
headers
|
|
1901
|
+
});
|
|
1902
|
+
}
|
|
1903
|
+
function reload(init = {}) {
|
|
1904
|
+
const {
|
|
1905
|
+
responseInit,
|
|
1906
|
+
headers
|
|
1907
|
+
} = initWithRevalidate(init);
|
|
1908
|
+
return new Response(null, {
|
|
1909
|
+
...responseInit,
|
|
1910
|
+
headers
|
|
1911
|
+
});
|
|
1912
|
+
}
|
|
1913
|
+
function respond(value, init = {}) {
|
|
1914
|
+
const {
|
|
1915
|
+
responseInit,
|
|
1916
|
+
headers
|
|
1917
|
+
} = initWithRevalidate(init);
|
|
1918
|
+
headers.set("Content-Type", "application/json");
|
|
1919
|
+
return new ResponseEnvelope(new Response(JSON.stringify(value), {
|
|
1920
|
+
...responseInit,
|
|
1921
|
+
headers
|
|
1922
|
+
}), value);
|
|
1923
|
+
}
|
|
1924
|
+
|
|
835
1925
|
const isServer = true;
|
|
836
1926
|
const isDev = false;
|
|
837
|
-
function
|
|
838
|
-
const
|
|
839
|
-
|
|
840
|
-
const memoOwner = createOwner();
|
|
841
|
-
return runWithOwner(memoOwner, () => {
|
|
842
|
-
const comp = component(),
|
|
843
|
-
t = typeof comp;
|
|
844
|
-
if (comp) {
|
|
845
|
-
if (t === "function") return comp(props);else if (t === "string") {
|
|
846
|
-
return ssrElement(comp, props, undefined, true);
|
|
847
|
-
}
|
|
848
|
-
}
|
|
1927
|
+
function dynamic(source) {
|
|
1928
|
+
const cached = createMemo(source, {
|
|
1929
|
+
serialize: false
|
|
849
1930
|
});
|
|
1931
|
+
return props => {
|
|
1932
|
+
return createMemo(() => {
|
|
1933
|
+
const c = cached();
|
|
1934
|
+
if (c) {
|
|
1935
|
+
if (typeof c === "function") return c(props);
|
|
1936
|
+
if (typeof c === "string") {
|
|
1937
|
+
return ssrElement(c, props, undefined, true);
|
|
1938
|
+
}
|
|
1939
|
+
}
|
|
1940
|
+
}, {
|
|
1941
|
+
sync: true
|
|
1942
|
+
});
|
|
1943
|
+
};
|
|
850
1944
|
}
|
|
851
1945
|
function Dynamic(props) {
|
|
852
|
-
const
|
|
853
|
-
return
|
|
1946
|
+
const Comp = dynamic(() => props.component);
|
|
1947
|
+
return createComponent(Comp, omit(props, "component"));
|
|
854
1948
|
}
|
|
855
1949
|
function Portal(props) {
|
|
856
|
-
|
|
1950
|
+
const o = getOwner();
|
|
1951
|
+
if (o?.id != null) getNextChildId(o);
|
|
1952
|
+
return undefined;
|
|
1953
|
+
}
|
|
1954
|
+
function registerClientOnlyPreload(moduleUrl) {
|
|
1955
|
+
const ctx = sharedConfig.context;
|
|
1956
|
+
if (!ctx?.registerAsset || !ctx.resolveAssets) return;
|
|
1957
|
+
const registerAsset = ctx.registerAsset;
|
|
1958
|
+
const resolve = ctx.resolveAssets;
|
|
1959
|
+
const apply = assets => {
|
|
1960
|
+
if (!assets) return;
|
|
1961
|
+
for (let i = 0; i < assets.css.length; i++) {
|
|
1962
|
+
const css = assets.css[i];
|
|
1963
|
+
if (typeof css === "string") registerAsset("style", css);else registerAsset("inline-style", css);
|
|
1964
|
+
}
|
|
1965
|
+
for (let i = 0; i < assets.js.length; i++) registerAsset("module", assets.js[i]);
|
|
1966
|
+
};
|
|
1967
|
+
const assets = resolve(moduleUrl);
|
|
1968
|
+
if (assets && typeof assets.then === "function") {
|
|
1969
|
+
const boundary = ctx._currentBoundaryId;
|
|
1970
|
+
assets.then(resolved => {
|
|
1971
|
+
const current = ctx._currentBoundaryId;
|
|
1972
|
+
ctx._currentBoundaryId = boundary;
|
|
1973
|
+
try {
|
|
1974
|
+
apply(resolved);
|
|
1975
|
+
} finally {
|
|
1976
|
+
ctx._currentBoundaryId = current;
|
|
1977
|
+
}
|
|
1978
|
+
},
|
|
1979
|
+
() => {});
|
|
1980
|
+
} else {
|
|
1981
|
+
apply(assets);
|
|
1982
|
+
}
|
|
1983
|
+
}
|
|
1984
|
+
function clientOnly(_fn, _options = {}, moduleUrl) {
|
|
1985
|
+
return props => {
|
|
1986
|
+
if (moduleUrl) registerClientOnlyPreload(moduleUrl);
|
|
1987
|
+
return createMemo(() => props.fallback);
|
|
1988
|
+
};
|
|
1989
|
+
}
|
|
1990
|
+
function httpStatus(code, text) {
|
|
1991
|
+
const event = getRequestEvent();
|
|
1992
|
+
const response = event && event.response;
|
|
1993
|
+
if (response && !response.committed) {
|
|
1994
|
+
const prevStatus = response.status;
|
|
1995
|
+
const prevStatusText = response.statusText;
|
|
1996
|
+
response.status = code;
|
|
1997
|
+
response.statusText = text;
|
|
1998
|
+
onCleanup(() => {
|
|
1999
|
+
if (response.committed) return;
|
|
2000
|
+
response.status = prevStatus;
|
|
2001
|
+
response.statusText = prevStatusText;
|
|
2002
|
+
});
|
|
2003
|
+
}
|
|
2004
|
+
}
|
|
2005
|
+
function httpHeader(name, value, options) {
|
|
2006
|
+
const event = getRequestEvent();
|
|
2007
|
+
const response = event && event.response;
|
|
2008
|
+
if (response && !response.committed) {
|
|
2009
|
+
const headers = response.headers;
|
|
2010
|
+
const prev = headers.get(name);
|
|
2011
|
+
if (options && options.append) headers.append(name, value);else headers.set(name, value);
|
|
2012
|
+
onCleanup(() => {
|
|
2013
|
+
if (response.committed) return;
|
|
2014
|
+
if (prev === null) headers.delete(name);else headers.set(name, prev);
|
|
2015
|
+
});
|
|
2016
|
+
}
|
|
857
2017
|
}
|
|
858
2018
|
|
|
859
|
-
export { ChildProperties, DOMElements, DelegatedEvents, Dynamic, HydrationScript, Portal,
|
|
2019
|
+
export { Assets, ChildProperties, DOMElements, DOMWithState, DelegatedEvents, Dynamic, HREF, HydrationScript, MathMLElements, Namespaces, Portal, REVALIDATE_HEADER, RawTextElements, RequestContext, ResponseEnvelope, SVGElements, VoidElements, notSup as acquireAsset, notSup as addEvent, applyRef, notSup as assign, claimElement, claimElementTree, notSup as className, clientOnly, notSup as delegateEvents, dynamic, notSup as dynamicProperty, effect, escape, generateHydrationScript, getAssets, notSup as getDelegatedRoot, getHydrationKey, notSup as getNextElement, notSup as getNextMarker, notSup as getNextMatch, getRequestEvent, httpHeader, httpStatus, notSup as hydrate, notSup as insert, isDev, isHref, isResponseEnvelope, isServer, memo, redirect, notSup as ref, notSup as registerDelegatedContainer, notSup as registerDelegatedRoot, registerElementClaim, reload, notSup as render, renderToStream, renderToString, renderToStringAsync, respond, notSup as runHydrationEvents, 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, useAssets, useHead };
|