@bgub/fig-server 0.1.0-alpha.0 → 0.1.0-alpha.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/README.md +99 -72
- package/dist/escaping-DAot8sFu.js +26 -0
- package/dist/escaping-DAot8sFu.js.map +1 -0
- package/dist/html-entry.d.ts +7 -0
- package/dist/html-entry.js +2 -0
- package/dist/image-preloads-BIFcrqm9.js +161 -0
- package/dist/image-preloads-BIFcrqm9.js.map +1 -0
- package/dist/index.d.ts +3 -7
- package/dist/index.js +723 -391
- package/dist/index.js.map +1 -1
- package/dist/payload.d.ts +13 -236
- package/dist/payload.js +252 -1364
- package/dist/payload.js.map +1 -1
- package/dist/{types-4X0JT0wt.d.ts → types-mrjoQDOc.d.ts} +35 -10
- package/package.json +8 -3
- package/dist/shared-CQn6Dje6.js +0 -105
- package/dist/shared-CQn6Dje6.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { i as
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { i as escapeText, n as escapeScriptJson, t as escapeAttribute } from "./escaping-DAot8sFu.js";
|
|
2
|
+
import { a as componentStack, c as nonceAttribute, d as withContextValue, i as cloneContextValues, l as streamFlowBlocked, n as suppressesImagePreloads, o as createStaticDispatcher, r as STREAMED_METADATA_ATTRIBUTE, s as deferred, t as imagePreloadFromHostProps, u as streamHighWaterMark } from "./image-preloads-BIFcrqm9.js";
|
|
3
|
+
import { Fragment, createElement, isValidElement } from "@bgub/fig";
|
|
4
|
+
import { ACTIVITY_TEMPLATE_ATTRIBUTE, EARLY_EVENT_HANDLER_PROPERTY, EARLY_EVENT_QUEUE_PROPERTY, HYDRATION_SKIP_ATTRIBUTE, REPLAYABLE_EVENT_TYPES, SUSPENSE_CLIENT_MARKER, SUSPENSE_COMPLETED_MARKER, SUSPENSE_END_MARKER, SUSPENSE_MARKER_PREFIX, SUSPENSE_PENDING_PREFIX, TEXT_SEPARATOR_DATA, VIEW_TRANSITION_CLASS_ATTRIBUTE, VIEW_TRANSITION_NAME_ATTRIBUTE, VIEW_TRANSITION_PENDING_PROPERTY, VIEW_TRANSITION_TIMEOUT_MS, assetResourceFromHostProps, assetResourceHostAttributes, assetResourceKey, attachDataStore, collectChildren, createRendererDataStore, invalidChildError, isActivity, isAssets, isClientReference, isContext, isErrorBoundary, isFigAssetResource, isPortal, isSuspense, isThenable, isViewTransition, readThenable, setCurrentDataStore, setCurrentDispatcher } from "@bgub/fig/internal";
|
|
4
5
|
//#region src/html.ts
|
|
5
6
|
const voidElements = /* @__PURE__ */ new Set([
|
|
6
7
|
"area",
|
|
@@ -23,9 +24,7 @@ function writeText(value, sink) {
|
|
|
23
24
|
}
|
|
24
25
|
function writeElementStart(type, props, sink, inheritedProps = {}) {
|
|
25
26
|
validateTagName(type);
|
|
26
|
-
sink.write(`<${type}
|
|
27
|
-
writeAttributes(type, props, inheritedProps, sink);
|
|
28
|
-
sink.write(">");
|
|
27
|
+
sink.write(`<${type}${serializeAttributes(type, props, inheritedProps)}>`);
|
|
29
28
|
}
|
|
30
29
|
function writeElementEnd(type, sink) {
|
|
31
30
|
sink.write(`</${type}>`);
|
|
@@ -48,46 +47,39 @@ function unsafeHTMLContent(props) {
|
|
|
48
47
|
if (typeof value === "string") return value;
|
|
49
48
|
throw new Error("The unsafeHTML prop must be a string during server render.");
|
|
50
49
|
}
|
|
51
|
-
function
|
|
52
|
-
|
|
50
|
+
function serializeAttributes(type, props, inheritedProps) {
|
|
51
|
+
let attributes = "";
|
|
52
|
+
for (const name of Object.keys(props)) {
|
|
53
|
+
const value = props[name];
|
|
53
54
|
if (reservedProp(name)) continue;
|
|
54
55
|
if (name === "value" && props.defaultValue !== void 0) continue;
|
|
55
56
|
if (name === "checked" && props.defaultChecked !== void 0) continue;
|
|
56
57
|
if (name === "style") {
|
|
57
58
|
const style = serializeStyle(value);
|
|
58
|
-
if (style !== "")
|
|
59
|
+
if (style !== "") attributes += serializeAttribute("style", style);
|
|
59
60
|
continue;
|
|
60
61
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
if (
|
|
80
|
-
if (
|
|
81
|
-
|
|
82
|
-
return attributeValue(name, value);
|
|
83
|
-
}
|
|
84
|
-
function attributeValue(name, value) {
|
|
85
|
-
return emptyValue(value) ? null : [name, value];
|
|
86
|
-
}
|
|
87
|
-
function valueAttribute(value) {
|
|
88
|
-
if (emptyValue(value)) return null;
|
|
89
|
-
if (serializableAttributeValue(value)) return ["value", String(value)];
|
|
90
|
-
return ["value", value];
|
|
62
|
+
attributes += serializeProp(type, name, value);
|
|
63
|
+
}
|
|
64
|
+
if (type === "option" && props.selected === void 0 && optionSelected(optionValue(props), inheritedProps)) attributes += " selected";
|
|
65
|
+
return attributes;
|
|
66
|
+
}
|
|
67
|
+
function serializeProp(type, name, value) {
|
|
68
|
+
if ((type === "textarea" || type === "select") && valueProp(name)) return "";
|
|
69
|
+
let attributeName = name;
|
|
70
|
+
let attributeValue = value;
|
|
71
|
+
if (valueProp(name)) {
|
|
72
|
+
attributeName = "value";
|
|
73
|
+
if (serializableAttributeValue(value)) attributeValue = String(value);
|
|
74
|
+
} else if (name === "defaultChecked") {
|
|
75
|
+
attributeName = "checked";
|
|
76
|
+
attributeValue = value === true ? true : null;
|
|
77
|
+
} else if (type === "option" && name === "selected") attributeValue = value === true ? true : null;
|
|
78
|
+
if (emptyValue(attributeValue)) return "";
|
|
79
|
+
validateAttributeName(attributeName);
|
|
80
|
+
if (attributeValue === true) return ` ${attributeName}`;
|
|
81
|
+
if (serializableAttributeValue(attributeValue)) return serializeAttribute(attributeName, String(attributeValue));
|
|
82
|
+
throw new Error(`Cannot serialize prop "${name}" to HTML.`);
|
|
91
83
|
}
|
|
92
84
|
function optionSelected(value, selectProps) {
|
|
93
85
|
const selectValue = selectProps.value !== void 0 ? selectProps.value : selectProps.defaultValue;
|
|
@@ -129,22 +121,23 @@ function emptyValue(value) {
|
|
|
129
121
|
function emptyChild(value) {
|
|
130
122
|
return value === null || value === void 0 || typeof value === "boolean";
|
|
131
123
|
}
|
|
132
|
-
function
|
|
133
|
-
|
|
124
|
+
function serializeAttribute(name, value) {
|
|
125
|
+
return ` ${name}="${escapeAttribute(value)}"`;
|
|
134
126
|
}
|
|
135
127
|
function serializeStyle(value) {
|
|
136
128
|
if (emptyValue(value)) return "";
|
|
137
129
|
if (typeof value !== "object" || value === null) throw new Error("The style prop must be an object during server render.");
|
|
138
|
-
|
|
130
|
+
let serialized = "";
|
|
139
131
|
for (const [name, item] of Object.entries(value)) {
|
|
140
132
|
if (emptyValue(item)) continue;
|
|
141
133
|
if (typeof item !== "string" && typeof item !== "number" && typeof item !== "bigint") throw new Error(`Cannot serialize style property "${name}" to HTML.`);
|
|
142
|
-
|
|
134
|
+
if (serialized !== "") serialized += ";";
|
|
135
|
+
serialized += `${styleName(name)}:${String(item)}`;
|
|
143
136
|
}
|
|
144
|
-
return
|
|
137
|
+
return serialized;
|
|
145
138
|
}
|
|
146
139
|
function reservedProp(name) {
|
|
147
|
-
return name === "children" || name === "key" || name === "
|
|
140
|
+
return name === "children" || name === "key" || name === "mix" || name === "bind" || name === "suppressHydrationWarning" || name === "unsafeHTML" || /^on[A-Z]/.test(name);
|
|
148
141
|
}
|
|
149
142
|
function valueProp(name) {
|
|
150
143
|
return name === "value" || name === "defaultValue";
|
|
@@ -159,79 +152,261 @@ function validateTagName(name) {
|
|
|
159
152
|
function validateAttributeName(name) {
|
|
160
153
|
if (/[\s"'<>/=]/.test(name)) throw new Error(`Invalid HTML attribute name "${name}".`);
|
|
161
154
|
}
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
155
|
+
//#endregion
|
|
156
|
+
//#region src/preload-header.ts
|
|
157
|
+
const DEFAULT_LENGTH = 2e3;
|
|
158
|
+
const HEX_ESCAPE = /^[0-9A-Fa-f]{2}$/;
|
|
159
|
+
const PARAMETER_TOKEN = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;
|
|
160
|
+
const URI_REFERENCE_PUNCTUATION = "-._~:/?#[]@!$&'()*+,;=";
|
|
161
|
+
function createPreloadHeaderEntries(resources, isEarlyImage) {
|
|
162
|
+
const preconnects = [];
|
|
163
|
+
const criticalPreloads = [];
|
|
164
|
+
const stylesheets = [];
|
|
165
|
+
const remaining = [];
|
|
166
|
+
for (const resource of resources) {
|
|
167
|
+
if (!isServerPreloadHeaderResource(resource)) continue;
|
|
168
|
+
const value = preloadHeaderValue(resource);
|
|
169
|
+
if (value === null) continue;
|
|
170
|
+
const entry = {
|
|
171
|
+
resource,
|
|
172
|
+
value
|
|
173
|
+
};
|
|
174
|
+
if (resource.kind === "preconnect") preconnects.push(entry);
|
|
175
|
+
else if (resource.kind === "font" || resource.kind === "preload" && (resource.as === "font" || resource.as === "image" && (resource.fetchpriority === "high" || isEarlyImage?.(resource) === true))) criticalPreloads.push(entry);
|
|
176
|
+
else if (resource.kind === "stylesheet") stylesheets.push(entry);
|
|
177
|
+
else remaining.push(entry);
|
|
178
|
+
}
|
|
179
|
+
return [
|
|
180
|
+
...preconnects,
|
|
181
|
+
...criticalPreloads,
|
|
182
|
+
...stylesheets,
|
|
183
|
+
...remaining
|
|
184
|
+
];
|
|
185
|
+
}
|
|
186
|
+
function formatPreloadHeader(entries, options = {}) {
|
|
187
|
+
const maxLength = normalizedLength(options.maxLength);
|
|
188
|
+
if (maxLength === 0) return void 0;
|
|
189
|
+
const seen = /* @__PURE__ */ new Set();
|
|
190
|
+
const values = [];
|
|
191
|
+
let length = 0;
|
|
192
|
+
for (const entry of entries) {
|
|
193
|
+
if (options.filter !== void 0 && !options.filter(entry.resource)) continue;
|
|
194
|
+
if (seen.has(entry.value)) continue;
|
|
195
|
+
const addedLength = entry.value.length + (values.length === 0 ? 0 : 2);
|
|
196
|
+
if (length + addedLength > maxLength) continue;
|
|
197
|
+
seen.add(entry.value);
|
|
198
|
+
values.push(entry.value);
|
|
199
|
+
length += addedLength;
|
|
200
|
+
}
|
|
201
|
+
return values.length === 0 ? void 0 : values.join(", ");
|
|
202
|
+
}
|
|
203
|
+
function preloadHeaderValue(resource) {
|
|
204
|
+
switch (resource.kind) {
|
|
205
|
+
case "stylesheet": return serializeLink(resource.href, [
|
|
206
|
+
["rel", "preload"],
|
|
207
|
+
["as", "style"],
|
|
208
|
+
["crossorigin", resource.crossorigin],
|
|
209
|
+
["media", resource.media]
|
|
210
|
+
]);
|
|
211
|
+
case "preload": return serializeLink(resource.href, [
|
|
212
|
+
["rel", "preload"],
|
|
213
|
+
["as", resource.as],
|
|
214
|
+
["crossorigin", resource.crossorigin],
|
|
215
|
+
["type", resource.type],
|
|
216
|
+
["fetchpriority", resource.fetchpriority],
|
|
217
|
+
["referrerpolicy", resource.referrerpolicy]
|
|
218
|
+
]);
|
|
219
|
+
case "modulepreload": return serializeLink(resource.href, [
|
|
220
|
+
["rel", "modulepreload"],
|
|
221
|
+
["as", "script"],
|
|
222
|
+
["crossorigin", resource.crossorigin],
|
|
223
|
+
["fetchpriority", resource.fetchpriority]
|
|
224
|
+
]);
|
|
225
|
+
case "font": return serializeLink(resource.href, [
|
|
226
|
+
["rel", "preload"],
|
|
227
|
+
["as", "font"],
|
|
228
|
+
["crossorigin", resource.crossorigin ?? "anonymous"],
|
|
229
|
+
["type", resource.type],
|
|
230
|
+
["fetchpriority", resource.fetchpriority]
|
|
231
|
+
]);
|
|
232
|
+
case "preconnect": return serializeLink(resource.href, [["rel", "preconnect"], ["crossorigin", resource.crossorigin]]);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
function isServerPreloadHeaderResource(resource) {
|
|
236
|
+
if (resource.kind === "script") return false;
|
|
237
|
+
return resource.kind !== "preload" || resource.href !== void 0 && (resource.as !== "image" || !resource.imagesrcset);
|
|
238
|
+
}
|
|
239
|
+
function serializeLink(target, parameters) {
|
|
240
|
+
const encodedTarget = encodeLinkTarget(target);
|
|
241
|
+
if (encodedTarget === null) return null;
|
|
242
|
+
const parts = [`<${encodedTarget}>`];
|
|
243
|
+
for (const [name, value] of parameters) {
|
|
244
|
+
if (value === void 0) continue;
|
|
245
|
+
const parameter = serializeParameter(name, value);
|
|
246
|
+
if (parameter === null) return null;
|
|
247
|
+
parts.push(parameter);
|
|
248
|
+
}
|
|
249
|
+
return parts.join("; ");
|
|
250
|
+
}
|
|
251
|
+
function serializeParameter(name, value) {
|
|
252
|
+
if (value === "") return name;
|
|
253
|
+
if (hasInvalidParameterCharacter(value)) return null;
|
|
254
|
+
if (PARAMETER_TOKEN.test(value)) return `${name}=${value}`;
|
|
255
|
+
return `${name}="${value.replaceAll("\\", "\\\\").replaceAll("\"", "\\\"")}"`;
|
|
256
|
+
}
|
|
257
|
+
function encodeLinkTarget(value) {
|
|
258
|
+
if (value === "") return null;
|
|
259
|
+
let encoded = "";
|
|
260
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
261
|
+
const code = value.charCodeAt(index);
|
|
262
|
+
if (code <= 32 || code === 127) return null;
|
|
263
|
+
const character = value[index];
|
|
264
|
+
if (character === "%" && HEX_ESCAPE.test(value.slice(index + 1, index + 3))) {
|
|
265
|
+
encoded += value.slice(index, index + 3);
|
|
266
|
+
index += 2;
|
|
267
|
+
continue;
|
|
268
|
+
}
|
|
269
|
+
if (code >= 48 && code <= 57 || code >= 65 && code <= 90 || code >= 97 && code <= 122 || URI_REFERENCE_PUNCTUATION.includes(character)) {
|
|
270
|
+
encoded += character;
|
|
271
|
+
continue;
|
|
272
|
+
}
|
|
273
|
+
const codePoint = value.codePointAt(index);
|
|
274
|
+
if (codePoint === void 0) return null;
|
|
275
|
+
const symbol = String.fromCodePoint(codePoint);
|
|
276
|
+
if (symbol.length === 2) index += 1;
|
|
277
|
+
try {
|
|
278
|
+
encoded += encodeURIComponent(symbol);
|
|
279
|
+
} catch {
|
|
280
|
+
return null;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
return encoded;
|
|
168
284
|
}
|
|
169
|
-
function
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
if (
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
285
|
+
function hasInvalidParameterCharacter(value) {
|
|
286
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
287
|
+
const code = value.charCodeAt(index);
|
|
288
|
+
if (code < 32 || code === 127 || code > 255) return true;
|
|
289
|
+
}
|
|
290
|
+
return false;
|
|
291
|
+
}
|
|
292
|
+
function normalizedLength(value) {
|
|
293
|
+
if (value === void 0 || Number.isNaN(value)) return DEFAULT_LENGTH;
|
|
294
|
+
return Math.max(0, Math.floor(value));
|
|
176
295
|
}
|
|
177
296
|
//#endregion
|
|
178
297
|
//#region src/asset-registry.ts
|
|
179
298
|
var AssetResourceRegistry = class {
|
|
180
299
|
identifierPrefix;
|
|
300
|
+
earlyImageKeys = /* @__PURE__ */ new Set();
|
|
181
301
|
emittedResources = /* @__PURE__ */ new Set();
|
|
182
|
-
|
|
302
|
+
deliveryResources = /* @__PURE__ */ new Map();
|
|
303
|
+
metadataByOwner = /* @__PURE__ */ new Map();
|
|
183
304
|
stylesheetIds = /* @__PURE__ */ new Map();
|
|
184
305
|
nextStylesheetId = 0;
|
|
185
306
|
constructor(identifierPrefix) {
|
|
186
307
|
this.identifierPrefix = identifierPrefix;
|
|
187
308
|
}
|
|
188
309
|
register(resource) {
|
|
189
|
-
|
|
310
|
+
if (isMetadataResource(resource)) return;
|
|
311
|
+
this.canonical(resource);
|
|
312
|
+
}
|
|
313
|
+
registerAutomaticImage(resource) {
|
|
314
|
+
const { key, resource: current } = this.canonical(resource);
|
|
315
|
+
if (this.earlyImageKeys.size < 10 || current.kind === "preload" && current.as === "image" && current.fetchpriority === "high") this.earlyImageKeys.add(key);
|
|
316
|
+
}
|
|
317
|
+
isEarlyImage(resource) {
|
|
318
|
+
return this.earlyImageKeys.has(assetResourceKey(resource));
|
|
319
|
+
}
|
|
320
|
+
activateMetadata(owner, resources) {
|
|
321
|
+
const metadata = resources.filter(isMetadataResource);
|
|
322
|
+
if (metadata.length === 0) {
|
|
323
|
+
this.metadataByOwner.delete(owner);
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
this.metadataByOwner.set(owner, metadata);
|
|
327
|
+
}
|
|
328
|
+
releaseMetadata(owner) {
|
|
329
|
+
this.metadataByOwner.delete(owner);
|
|
190
330
|
}
|
|
191
331
|
write(resource, sink) {
|
|
332
|
+
if (isMetadataResource(resource)) return null;
|
|
192
333
|
const { key, resource: current } = this.canonical(resource);
|
|
193
334
|
const id = this.revealBlockerId(key, current);
|
|
194
|
-
if (assetResourceDestination(current) === "head") return id;
|
|
195
335
|
if (this.emittedResources.has(key)) return id;
|
|
196
336
|
this.emittedResources.add(key);
|
|
197
337
|
writeAssetTag(sink, current, id);
|
|
198
338
|
return id;
|
|
199
339
|
}
|
|
200
|
-
headHtml(nonce) {
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
340
|
+
headHtml(nonce, streamMetadata = false) {
|
|
341
|
+
const { preamble, metadata } = this.headMetadataHtml(nonce, streamMetadata);
|
|
342
|
+
return preamble + metadata;
|
|
343
|
+
}
|
|
344
|
+
headMetadataHtml(nonce, streamMetadata = false) {
|
|
345
|
+
const buckets = {
|
|
346
|
+
charset: [],
|
|
347
|
+
parser: [],
|
|
348
|
+
viewport: [],
|
|
349
|
+
metadata: []
|
|
207
350
|
};
|
|
208
|
-
for (const resource of this.
|
|
209
|
-
|
|
351
|
+
for (const resource of this.visibleMetadata().values()) {
|
|
352
|
+
const bucket = buckets[metadataPhase(resource)];
|
|
353
|
+
writeAssetTag({
|
|
354
|
+
nonce,
|
|
355
|
+
streamMetadata,
|
|
356
|
+
write: (chunk) => bucket.push(chunk)
|
|
357
|
+
}, resource, null);
|
|
358
|
+
}
|
|
359
|
+
return {
|
|
360
|
+
preamble: [
|
|
361
|
+
...buckets.charset,
|
|
362
|
+
...buckets.parser,
|
|
363
|
+
...buckets.viewport
|
|
364
|
+
].join(""),
|
|
365
|
+
metadata: buckets.metadata.join("")
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
metadataSnapshot() {
|
|
369
|
+
const snapshot = [];
|
|
370
|
+
for (const [key, resource] of this.visibleMetadata()) if (resource.kind === "title") snapshot.push([
|
|
371
|
+
key,
|
|
372
|
+
resource.kind,
|
|
373
|
+
resource.value
|
|
374
|
+
]);
|
|
375
|
+
else snapshot.push([
|
|
376
|
+
key,
|
|
377
|
+
resource.kind,
|
|
378
|
+
metadataAttributes(resource)
|
|
379
|
+
]);
|
|
380
|
+
return snapshot;
|
|
381
|
+
}
|
|
382
|
+
preloadHeaderEntries() {
|
|
383
|
+
return createPreloadHeaderEntries(this.deliveryResources.values(), (resource) => this.isEarlyImage(resource));
|
|
384
|
+
}
|
|
385
|
+
visibleMetadata() {
|
|
386
|
+
const visible = /* @__PURE__ */ new Map();
|
|
387
|
+
for (const metadata of this.metadataByOwner.values()) for (const resource of metadata) visible.set(assetResourceKey(resource), resource);
|
|
388
|
+
return visible;
|
|
210
389
|
}
|
|
211
390
|
canonical(resource) {
|
|
212
391
|
const key = assetResourceKey(resource);
|
|
213
|
-
const current = this.
|
|
392
|
+
const current = this.deliveryResources.get(key);
|
|
214
393
|
if (current !== void 0) {
|
|
215
394
|
if (assetSignature(current) !== assetSignature(resource)) {
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
}
|
|
224
|
-
throw new AssetResourceConflictError(key, current, resource);
|
|
395
|
+
const promoted = promoteCompatibleImagePreload(current, resource);
|
|
396
|
+
if (promoted === null) throw new AssetResourceConflictError(key, current, resource);
|
|
397
|
+
this.deliveryResources.set(key, promoted);
|
|
398
|
+
return {
|
|
399
|
+
key,
|
|
400
|
+
resource: promoted
|
|
401
|
+
};
|
|
225
402
|
}
|
|
226
403
|
return {
|
|
227
|
-
added: false,
|
|
228
404
|
key,
|
|
229
405
|
resource: current
|
|
230
406
|
};
|
|
231
407
|
}
|
|
232
|
-
this.
|
|
408
|
+
this.deliveryResources.set(key, resource);
|
|
233
409
|
return {
|
|
234
|
-
added: true,
|
|
235
410
|
key,
|
|
236
411
|
resource
|
|
237
412
|
};
|
|
@@ -258,7 +433,10 @@ var AssetResourceConflictError = class extends Error {
|
|
|
258
433
|
function writeAssetTag(sink, resource, id) {
|
|
259
434
|
switch (resource.kind) {
|
|
260
435
|
case "title":
|
|
261
|
-
writeElementStart("title", {
|
|
436
|
+
writeElementStart("title", {
|
|
437
|
+
[HYDRATION_SKIP_ATTRIBUTE]: true,
|
|
438
|
+
[STREAMED_METADATA_ATTRIBUTE]: sink.streamMetadata ? assetResourceKey(resource) : void 0
|
|
439
|
+
}, sink);
|
|
262
440
|
writeText(resource.value, sink);
|
|
263
441
|
writeElementEnd("title", sink);
|
|
264
442
|
return;
|
|
@@ -267,13 +445,18 @@ function writeAssetTag(sink, resource, id) {
|
|
|
267
445
|
charset: resource.charset,
|
|
268
446
|
name: resource.name,
|
|
269
447
|
property: resource.property,
|
|
270
|
-
"http-equiv": resource
|
|
448
|
+
"http-equiv": resource["http-equiv"],
|
|
271
449
|
content: resource.content,
|
|
450
|
+
[HYDRATION_SKIP_ATTRIBUTE]: true,
|
|
451
|
+
[STREAMED_METADATA_ATTRIBUTE]: sink.streamMetadata ? assetResourceKey(resource) : void 0,
|
|
272
452
|
"data-fig-resource-key": resource.key
|
|
273
453
|
}, sink);
|
|
274
454
|
return;
|
|
275
455
|
default: {
|
|
276
|
-
const props =
|
|
456
|
+
const props = {
|
|
457
|
+
[HYDRATION_SKIP_ATTRIBUTE]: true,
|
|
458
|
+
...Object.fromEntries(assetResourceHostAttributes(resource))
|
|
459
|
+
};
|
|
277
460
|
if (resource.kind === "stylesheet" && id !== null) props.id = id;
|
|
278
461
|
const tag = resource.kind === "script" ? "script" : "link";
|
|
279
462
|
writeElementStart(tag, withNonce(sink, props), sink);
|
|
@@ -281,6 +464,29 @@ function writeAssetTag(sink, resource, id) {
|
|
|
281
464
|
}
|
|
282
465
|
}
|
|
283
466
|
}
|
|
467
|
+
function isMetadataResource(resource) {
|
|
468
|
+
return resource.kind === "title" || resource.kind === "meta";
|
|
469
|
+
}
|
|
470
|
+
function metadataPhase(resource) {
|
|
471
|
+
if (resource.kind === "title") return "metadata";
|
|
472
|
+
if (resource.charset !== void 0) return "charset";
|
|
473
|
+
if (normalizedMetadataName(resource["http-equiv"]) === "content-security-policy") return "parser";
|
|
474
|
+
if (normalizedMetadataName(resource.name) === "viewport") return "viewport";
|
|
475
|
+
return "metadata";
|
|
476
|
+
}
|
|
477
|
+
function normalizedMetadataName(value) {
|
|
478
|
+
return value?.trim().toLowerCase();
|
|
479
|
+
}
|
|
480
|
+
function metadataAttributes(resource) {
|
|
481
|
+
return [
|
|
482
|
+
["charset", resource.charset],
|
|
483
|
+
["name", resource.name],
|
|
484
|
+
["property", resource.property],
|
|
485
|
+
["http-equiv", resource["http-equiv"]],
|
|
486
|
+
["content", resource.content],
|
|
487
|
+
["data-fig-resource-key", resource.key]
|
|
488
|
+
].filter((entry) => entry[1] !== void 0);
|
|
489
|
+
}
|
|
284
490
|
function withNonce(sink, props) {
|
|
285
491
|
return sink.nonce === void 0 ? props : {
|
|
286
492
|
...props,
|
|
@@ -289,17 +495,34 @@ function withNonce(sink, props) {
|
|
|
289
495
|
}
|
|
290
496
|
function assetSignature(resource) {
|
|
291
497
|
switch (resource.kind) {
|
|
292
|
-
case "stylesheet": return signature(resource.kind, resource.href, resource.media ?? "", resource.precedence ?? "", resource.
|
|
293
|
-
case "preload":
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
case "
|
|
498
|
+
case "stylesheet": return signature(resource.kind, resource.href, resource.media ?? "", resource.precedence ?? "", resource.crossorigin ?? "", resource.blocking ?? "reveal");
|
|
499
|
+
case "preload": {
|
|
500
|
+
const imagesrcset = resource.as === "image" ? resource.imagesrcset || void 0 : void 0;
|
|
501
|
+
return signature(resource.kind, imagesrcset === void 0 ? resource.href ?? "" : "", resource.as, resource.type ?? "", resource.crossorigin ?? "", resource.fetchpriority ?? "", imagesrcset ?? "", imagesrcset === void 0 ? "" : resource.imagesizes ?? "", resource.referrerpolicy ?? "");
|
|
502
|
+
}
|
|
503
|
+
case "modulepreload": return signature(resource.kind, resource.href, resource.crossorigin ?? "", resource.fetchpriority ?? "");
|
|
504
|
+
case "font": return signature("preload", resource.href, "font", resource.type, resource.crossorigin ?? "anonymous", resource.fetchpriority ?? "", "", "", "");
|
|
505
|
+
case "preconnect": return signature(resource.kind, resource.href, resource.crossorigin ?? "");
|
|
506
|
+
case "script": return signature(resource.kind, resource.src, resource.module === true, resource.async !== false, resource.defer === true, resource.crossorigin ?? "");
|
|
298
507
|
case "title": return signature(resource.kind, resource.value);
|
|
299
|
-
case "meta": return signature(resource.kind, resource.charset ?? "", resource.name ?? "", resource.property ?? "", resource
|
|
508
|
+
case "meta": return signature(resource.kind, resource.charset ?? "", resource.name ?? "", resource.property ?? "", resource["http-equiv"] ?? "", resource.content ?? "");
|
|
300
509
|
}
|
|
301
510
|
return unsupportedAssetResource(resource);
|
|
302
511
|
}
|
|
512
|
+
function promoteCompatibleImagePreload(current, incoming) {
|
|
513
|
+
if (current.kind !== "preload" || incoming.kind !== "preload" || current.as !== "image" || incoming.as !== "image" || assetSignature({
|
|
514
|
+
...current,
|
|
515
|
+
fetchpriority: incoming.fetchpriority
|
|
516
|
+
}) !== assetSignature(incoming)) return null;
|
|
517
|
+
const currentPriority = current.fetchpriority === "auto" ? void 0 : current.fetchpriority;
|
|
518
|
+
const incomingPriority = incoming.fetchpriority === "auto" ? void 0 : incoming.fetchpriority;
|
|
519
|
+
if (currentPriority === incomingPriority) return current;
|
|
520
|
+
if (currentPriority === "low" || incomingPriority === "low") return null;
|
|
521
|
+
return currentPriority === "high" ? current : {
|
|
522
|
+
...current,
|
|
523
|
+
fetchpriority: "high"
|
|
524
|
+
};
|
|
525
|
+
}
|
|
303
526
|
function unsupportedAssetResource(resource) {
|
|
304
527
|
throw new Error(`Unsupported asset resource kind: ${resource.kind}`);
|
|
305
528
|
}
|
|
@@ -309,7 +532,7 @@ function signature(...values) {
|
|
|
309
532
|
//#endregion
|
|
310
533
|
//#region src/protocol.ts
|
|
311
534
|
function serverRuntimeCodeFor(runtimeName) {
|
|
312
|
-
return `globalThis[${jsString(runtimeName)}]??={r(a,f){let n=0,d=()=>{--n||f()};for(let i of a){let e=document.getElementById(i);if(e&&e.tagName==='LINK'&&e.rel==='stylesheet'&&!e.sheet){n++;e.addEventListener('load',d,{once:true});e.addEventListener('error',d,{once:true})}}n||f()},q(e,a){if(e&&e.nodeType===1){if(e.hasAttribute&&e.hasAttribute('${VIEW_TRANSITION_NAME_ATTRIBUTE}'))a.push([e,e.getAttribute('${VIEW_TRANSITION_NAME_ATTRIBUTE}'),e.getAttribute('${VIEW_TRANSITION_CLASS_ATTRIBUTE}')]);if(e.querySelectorAll)for(let x of e.querySelectorAll('[${VIEW_TRANSITION_NAME_ATTRIBUTE}]'))a.push([x,x.getAttribute('${VIEW_TRANSITION_NAME_ATTRIBUTE}'),x.getAttribute('${VIEW_TRANSITION_CLASS_ATTRIBUTE}')])}},g(r){let a=[];this.q(r,a);return a},h(b){let a=[],d=0;for(let e=b;e;){if(e.nodeType===8){if(e.data.indexOf('${SUSPENSE_MARKER_PREFIX}')===0)d++;else if(e.data==='${SUSPENSE_END_MARKER}'){if(d===0)break;d--}}else this.q(e,a);e=e.nextSibling}return a},a(l){for(let x of l){let e=x[0],s=e.style;x[3]=s.viewTransitionName;x[4]=s.viewTransitionClass;s.viewTransitionName=x[1];if(x[2])s.viewTransitionClass=x[2]}},u(l){for(let x of l){let e=x[0],s=e.style;s.viewTransitionName=x[3]||'';s.viewTransitionClass=x[4]||'';!(e.getAttribute&&e.getAttribute('style'))&&e.removeAttribute&&e.removeAttribute('style')}},z(l){for(let f of l)f()},j(t,r){let p=t&&(t.ready||t.finished);p&&p.then?p.then(r,()=>{let f=t&&t.finished;f&&f.then?f.then(r,r):r()}):r()},v(b,s,f){let o=this.h(b),n=this.g(s);if(!o.length&&!n.length){f();return}let d=document,w=d.startViewTransition;if(typeof w!='function'){f();return}let p=d.${VIEW_TRANSITION_PENDING_PROPERTY},pw=p&&(p.finished||p.ready);if(pw&&pw.then){let g=()=>this.v(b,s,f);pw.then(g,g);return}this.a(o);let m=0,l=[],r=()=>{this.u(o);this.u(n);this.z(l)};try{let t=w.call(d,()=>{m=1;f(l);this.a(n)});if(t){d.${VIEW_TRANSITION_PENDING_PROPERTY}=t;let c=()=>{d.${VIEW_TRANSITION_PENDING_PROPERTY}===t&&(d.${VIEW_TRANSITION_PENDING_PROPERTY}=null)},cw=t.finished||t.ready;cw&&cw.then?cw.then(c,c):c()}this.j(t,r)}catch(e){r();if(m)throw e;f()}},s(p,s){p=document.getElementById(p);s=document.getElementById(s);if(!p||!s)return;this.v(p,s,()=>{while(s.firstChild)p.parentNode.insertBefore(s.firstChild,p);p.remove();s.remove()})},f(r,i){if(!r)return null;if(r.id===i)return r;for(let e of r.querySelectorAll?r.querySelectorAll('[id]'):[])if(e.id===i)return e;return null},b(t,b){let e=document.getElementById(t),r=e&&(e.content||e);return this.f(r,b)||document.getElementById(b)},c(b,s){let x=document.getElementById(b),y=document.getElementById(s);this.v(x,y,r=>this.o(x,y,r))},o(b,s,l){if(!b||!s)return;let a=b.previousSibling||b,p=a.parentNode,c=s.content||s;if(!p)return;while(c.firstChild)p.insertBefore(c.firstChild,b);for(let e=b,d=0;e;){if(e.nodeType===8){if(e.data.indexOf('${SUSPENSE_MARKER_PREFIX}')===0)d++;else if(e.data==='${SUSPENSE_END_MARKER}'){if(d===0)break;d--}}let x=e.nextSibling;e.remove();e=x}s.remove();if(a.nodeType===8){a.data='${SUSPENSE_COMPLETED_MARKER}';
|
|
535
|
+
return `globalThis[${jsString(runtimeName)}]??={r(a,f){let n=0,d=()=>{--n||f()};for(let i of a){let e=document.getElementById(i);if(e&&e.tagName==='LINK'&&e.rel==='stylesheet'&&!e.sheet){n++;e.addEventListener('load',d,{once:true});e.addEventListener('error',d,{once:true})}}n||f()},q(e,a){if(e&&e.nodeType===1){if(e.hasAttribute&&e.hasAttribute('${VIEW_TRANSITION_NAME_ATTRIBUTE}'))a.push([e,e.getAttribute('${VIEW_TRANSITION_NAME_ATTRIBUTE}'),e.getAttribute('${VIEW_TRANSITION_CLASS_ATTRIBUTE}')]);if(e.querySelectorAll)for(let x of e.querySelectorAll('[${VIEW_TRANSITION_NAME_ATTRIBUTE}]'))a.push([x,x.getAttribute('${VIEW_TRANSITION_NAME_ATTRIBUTE}'),x.getAttribute('${VIEW_TRANSITION_CLASS_ATTRIBUTE}')])}},g(r){let a=[];this.q(r,a);return a},h(b){let a=[],d=0;for(let e=b;e;){if(e.nodeType===8){if(e.data.indexOf('${SUSPENSE_MARKER_PREFIX}')===0)d++;else if(e.data==='${SUSPENSE_END_MARKER}'){if(d===0)break;d--}}else this.q(e,a);e=e.nextSibling}return a},a(l){for(let x of l){let e=x[0],s=e.style;x[3]=s.viewTransitionName;x[4]=s.viewTransitionClass;s.viewTransitionName=x[1];if(x[2])s.viewTransitionClass=x[2]}},u(l){for(let x of l){let e=x[0],s=e.style;s.viewTransitionName=x[3]||'';s.viewTransitionClass=x[4]||'';!(e.getAttribute&&e.getAttribute('style'))&&e.removeAttribute&&e.removeAttribute('style')}},z(l){for(let f of l)f()},j(t,r){let p=t&&(t.ready||t.finished);p&&p.then?p.then(r,()=>{let f=t&&t.finished;f&&f.then?f.then(r,r):r()}):r()},v(b,s,f){let o=this.h(b),n=this.g(s);if(!o.length&&!n.length){f();return}let d=document,w=d.startViewTransition;if(typeof w!='function'){f();return}let p=d.${VIEW_TRANSITION_PENDING_PROPERTY},pw=p&&(p.finished||p.ready);if(pw&&pw.then){let q=0,i,g=()=>{if(q)return;q=1;clearTimeout(i);d.${VIEW_TRANSITION_PENDING_PROPERTY}===p&&(d.${VIEW_TRANSITION_PENDING_PROPERTY}=null);this.v(b,s,f)};i=setTimeout(g,${VIEW_TRANSITION_TIMEOUT_MS});pw.then(g,g);return}this.a(o);let m=0,l=[],r=()=>{this.u(o);this.u(n);this.z(l)};try{let t=w.call(d,()=>{m=1;f(l);this.a(n)});if(t){d.${VIEW_TRANSITION_PENDING_PROPERTY}=t;let c=()=>{d.${VIEW_TRANSITION_PENDING_PROPERTY}===t&&(d.${VIEW_TRANSITION_PENDING_PROPERTY}=null)},cw=t.finished||t.ready;cw&&cw.then?cw.then(c,c):c()}this.j(t,r)}catch(e){r();if(m)throw e;f()}},m(a){let h=document.head,e=new Map;for(let n of h.querySelectorAll('[${STREAMED_METADATA_ATTRIBUTE}]'))e.set(n.getAttribute('${STREAMED_METADATA_ATTRIBUTE}'),n);for(let d of a){let k=d[0],t=d[1],v=d[2],n=e.get(k);if(!n||n.tagName.toLowerCase()!==t){n&&n.remove();n=document.createElement(t);n.setAttribute('${STREAMED_METADATA_ATTRIBUTE}',k);n.setAttribute('${HYDRATION_SKIP_ATTRIBUTE}','');h.appendChild(n)}e.delete(k);if(t==='title')n.textContent=v;else{for(let x of Array.from(n.attributes))if(x.name!=='${STREAMED_METADATA_ATTRIBUTE}'&&x.name!=='${HYDRATION_SKIP_ATTRIBUTE}')n.removeAttribute(x.name);for(let x of v)n.setAttribute(x[0],x[1])}}for(let n of e.values())n.remove()},s(p,s){p=document.getElementById(p);s=document.getElementById(s);if(!p||!s)return;this.v(p,s,()=>{while(s.firstChild)p.parentNode.insertBefore(s.firstChild,p);p.remove();s.remove()})},f(r,i){if(!r)return null;if(r.id===i)return r;for(let e of r.querySelectorAll?r.querySelectorAll('[id]'):[])if(e.id===i)return e;return null},b(t,b){let e=document.getElementById(t),r=e&&(e.content||e);return this.f(r,b)||document.getElementById(b)},c(b,s,m){let x=document.getElementById(b),y=document.getElementById(s);this.v(x,y,r=>this.o(x,y,r,m))},o(b,s,l,m){if(!b||!s)return;let a=b.previousSibling||b,p=a.parentNode,c=s.content||s;if(!p)return;let r=a.nodeType===8&&a.__figRetry;if(!r&&m)this.m(m);while(c.firstChild)p.insertBefore(c.firstChild,b);for(let e=b,d=0;e;){if(e.nodeType===8){if(e.data.indexOf('${SUSPENSE_MARKER_PREFIX}')===0)d++;else if(e.data==='${SUSPENSE_END_MARKER}'){if(d===0)break;d--}}let x=e.nextSibling;e.remove();e=x}s.remove();if(a.nodeType===8){a.data='${SUSPENSE_COMPLETED_MARKER}';if(r){if(l)l.push(r);else r()}}},x(b,d,m){this.y(document.getElementById(b),d,m)},y(b,d,m){if(!b)return;let s=b.previousSibling;if(s&&s.nodeType===8){s.data='${SUSPENSE_CLIENT_MARKER}';if(d)b.dataset.dgst=d;if(m)b.dataset.msg=m;s.__figRetry&&s.__figRetry()}},ac(t,b,s,m){let x=this.b(t,b),y=document.getElementById(s);this.v(x,y,r=>this.o(x,y,r,m))},ax(t,b,d,m){this.y(this.b(t,b),d,m)}}`;
|
|
313
536
|
}
|
|
314
537
|
function writeRuntime$1(request, write) {
|
|
315
538
|
if (request.runtimeWritten) return;
|
|
@@ -317,17 +540,13 @@ function writeRuntime$1(request, write) {
|
|
|
317
540
|
writeScript$1(request, serverRuntimeCodeFor(request.runtimeName), write);
|
|
318
541
|
}
|
|
319
542
|
function writeScript$1(request, code, write) {
|
|
320
|
-
write(`<script${
|
|
543
|
+
write(`<script ${HYDRATION_SKIP_ATTRIBUTE}=""${nonceAttribute(request.nonce)}>${code}<\/script>`);
|
|
321
544
|
}
|
|
322
545
|
function earlyEventCaptureCode() {
|
|
323
546
|
return `(d=>{if(d.${EARLY_EVENT_QUEUE_PROPERTY})return;let q=d.${EARLY_EVENT_QUEUE_PROPERTY}=[],h=d.${EARLY_EVENT_HANDLER_PROPERTY}=e=>{q.push(e)};for(let t of [${REPLAYABLE_EVENT_TYPES.map((type) => `'${type}'`).join(",")}])d.addEventListener(t,h,!0)})(document)`;
|
|
324
547
|
}
|
|
325
548
|
function earlyEventCaptureMarkup(request) {
|
|
326
|
-
|
|
327
|
-
writeScript$1(request, earlyEventCaptureCode(), (chunk) => {
|
|
328
|
-
markup += chunk;
|
|
329
|
-
});
|
|
330
|
-
return markup;
|
|
549
|
+
return `<script ${HYDRATION_SKIP_ATTRIBUTE}=""${nonceAttribute(request.nonce)}>${earlyEventCaptureCode()}<\/script>`;
|
|
331
550
|
}
|
|
332
551
|
function placeholderMarkup(request, id) {
|
|
333
552
|
return templateMarkup(placeholderId(request, id));
|
|
@@ -354,18 +573,281 @@ function boundaryId(request, id) {
|
|
|
354
573
|
return prefixedId(request, "b", id);
|
|
355
574
|
}
|
|
356
575
|
function jsString(value) {
|
|
357
|
-
return
|
|
576
|
+
return escapeScriptJson(value);
|
|
358
577
|
}
|
|
359
578
|
function prefixedId(request, kind, id) {
|
|
360
579
|
return request.identifierPrefix === "" ? `${kind}-${id}` : `${request.identifierPrefix}-${kind}-${id}`;
|
|
361
580
|
}
|
|
362
581
|
//#endregion
|
|
363
|
-
//#region src/renderer.ts
|
|
364
|
-
const errorStacks = /* @__PURE__ */ new WeakMap();
|
|
365
|
-
const textEncoder = new TextEncoder();
|
|
582
|
+
//#region src/renderer-flush.ts
|
|
366
583
|
const documentHeadMarker = Symbol("fig.document-head");
|
|
584
|
+
const leadingNewlineStartMarker = Symbol("fig.leading-newline-start");
|
|
585
|
+
const leadingNewlineEndMarker = Symbol("fig.leading-newline-end");
|
|
367
586
|
const RUNTIME_REF = "__figSSR";
|
|
368
|
-
const
|
|
587
|
+
const textEncoder = new TextEncoder();
|
|
588
|
+
function flushCompletedQueues(request) {
|
|
589
|
+
if (request.controller === null || request.status === "closed") return;
|
|
590
|
+
if (request.pendingRootTasks > 0) return;
|
|
591
|
+
if (request.prerender && request.pendingTasks > 0) return;
|
|
592
|
+
if (request.flushing) return;
|
|
593
|
+
request.flushing = true;
|
|
594
|
+
try {
|
|
595
|
+
sealHead(request);
|
|
596
|
+
if (request.completedRootSegment !== null) {
|
|
597
|
+
flushSegment(request, request.completedRootSegment);
|
|
598
|
+
request.completedRootSegment = null;
|
|
599
|
+
flushWriteBuffer(request);
|
|
600
|
+
}
|
|
601
|
+
if (!drainBoundaryQueue(request, request.clientRenderedBoundaries, flushClientRenderedBoundary) && !drainBoundaryQueue(request, request.completedBoundaries, flushCompletedBoundary)) drainBoundaryQueue(request, request.partialBoundaries, flushPartialBoundary);
|
|
602
|
+
flushWriteBuffer(request);
|
|
603
|
+
} finally {
|
|
604
|
+
request.flushing = false;
|
|
605
|
+
}
|
|
606
|
+
if (request.pendingTasks === 0 && request.completedBoundaries.size === 0 && request.clientRenderedBoundaries.size === 0 && request.partialBoundaries.size === 0) {
|
|
607
|
+
request.cleanupAbortListener();
|
|
608
|
+
request.status = "closed";
|
|
609
|
+
request.dataStore.dispose();
|
|
610
|
+
request.controller.close();
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
function sealHead(request) {
|
|
614
|
+
if (request.headSnapshot !== null) return;
|
|
615
|
+
activateVisibleMetadata(request, request.rootSegment);
|
|
616
|
+
const metadata = request.assetRegistry.headMetadataHtml(request.nonce, !request.prerender && request.pendingTasks > 0);
|
|
617
|
+
request.headSnapshot = {
|
|
618
|
+
...metadata,
|
|
619
|
+
preloadHeaderEntries: request.assetRegistry.preloadHeaderEntries()
|
|
620
|
+
};
|
|
621
|
+
request.headReady.resolve(metadata.preamble + metadata.metadata);
|
|
622
|
+
}
|
|
623
|
+
function flushSegment(request, segment) {
|
|
624
|
+
if (segment.status === "flushed") return;
|
|
625
|
+
if (segment.boundary !== null) {
|
|
626
|
+
flushSuspenseBoundary(request, segment, segment.boundary);
|
|
627
|
+
return;
|
|
628
|
+
}
|
|
629
|
+
flushSubtree(request, segment);
|
|
630
|
+
}
|
|
631
|
+
function flushSubtree(request, segment) {
|
|
632
|
+
segment.parentFlushed = true;
|
|
633
|
+
if (segment.status === "pending" || segment.status === "rendering") {
|
|
634
|
+
request.write(placeholderMarkup(request, ensureSegmentId(request, segment)));
|
|
635
|
+
return;
|
|
636
|
+
}
|
|
637
|
+
if (segment.status === "flushed") return;
|
|
638
|
+
segment.status = "flushed";
|
|
639
|
+
if (request.document === null || segment !== request.rootSegment) flushSegmentAssets(request, segment);
|
|
640
|
+
let chunkIndex = 0;
|
|
641
|
+
for (const child of segment.children) {
|
|
642
|
+
for (; chunkIndex < child.index; chunkIndex += 1) writeChunk(request, segment.chunks[chunkIndex], segment);
|
|
643
|
+
flushSegment(request, child);
|
|
644
|
+
}
|
|
645
|
+
for (; chunkIndex < segment.chunks.length; chunkIndex += 1) writeChunk(request, segment.chunks[chunkIndex], segment);
|
|
646
|
+
}
|
|
647
|
+
function flushSuspenseBoundary(request, segment, boundary) {
|
|
648
|
+
boundary.parentFlushed = true;
|
|
649
|
+
if (boundary.status === "completed") {
|
|
650
|
+
request.write(`<!--${SUSPENSE_COMPLETED_MARKER}-->`);
|
|
651
|
+
flushBoundaryContent(request, boundary);
|
|
652
|
+
request.write(`<!--${SUSPENSE_END_MARKER}-->`);
|
|
653
|
+
segment.status = "flushed";
|
|
654
|
+
return;
|
|
655
|
+
}
|
|
656
|
+
if (request.prerender && boundary.status === "client-rendered") {
|
|
657
|
+
request.write(`<!--${SUSPENSE_CLIENT_MARKER}-->`);
|
|
658
|
+
request.write(clientRenderedBoundaryPlaceholderMarkup(request, boundary));
|
|
659
|
+
flushSubtree(request, segment);
|
|
660
|
+
request.write(`<!--${SUSPENSE_END_MARKER}-->`);
|
|
661
|
+
return;
|
|
662
|
+
}
|
|
663
|
+
const boundaryIdValue = ensureBoundaryId(request, boundary);
|
|
664
|
+
flushSegmentAssets(request, boundary.contentSegment);
|
|
665
|
+
request.write(`<!--${SUSPENSE_PENDING_PREFIX}${boundaryIdValue}-->`);
|
|
666
|
+
request.write(boundaryPlaceholderMarkup(request, boundaryIdValue));
|
|
667
|
+
flushSubtree(request, segment);
|
|
668
|
+
request.write(`<!--${SUSPENSE_END_MARKER}-->`);
|
|
669
|
+
if (boundary.status === "client-rendered") request.clientRenderedBoundaries.add(boundary);
|
|
670
|
+
else if (boundary.completedSegments.length > 0) request.partialBoundaries.add(boundary);
|
|
671
|
+
}
|
|
672
|
+
function flushBoundaryContent(request, boundary) {
|
|
673
|
+
for (const segment of boundary.completedSegments) flushSegment(request, segment);
|
|
674
|
+
boundary.completedSegments = [];
|
|
675
|
+
}
|
|
676
|
+
function clientRenderedBoundaryPlaceholderMarkup(request, boundary) {
|
|
677
|
+
const id = escapeAttribute(boundaryId(request, ensureBoundaryId(request, boundary)));
|
|
678
|
+
const digest = boundary.error?.digest;
|
|
679
|
+
const message = boundary.error?.message;
|
|
680
|
+
return `<template id="${id}"${digest === void 0 || digest === "" ? "" : ` data-dgst="${escapeAttribute(digest)}"`}${message === void 0 || message === "" ? "" : ` data-msg="${escapeAttribute(message)}"`}></template>`;
|
|
681
|
+
}
|
|
682
|
+
function flushCompletedBoundary(request, boundary) {
|
|
683
|
+
flushPartialBoundary(request, boundary);
|
|
684
|
+
writeBoundaryRevealScript(request, boundary);
|
|
685
|
+
}
|
|
686
|
+
function flushPartialBoundary(request, boundary) {
|
|
687
|
+
for (const segment of boundary.completedSegments) flushBoundarySegment(request, boundary, segment);
|
|
688
|
+
boundary.completedSegments = [];
|
|
689
|
+
}
|
|
690
|
+
function flushBoundarySegment(request, boundary, segment) {
|
|
691
|
+
ensureBoundaryId(request, boundary);
|
|
692
|
+
const blockingIds = flushSegmentContainer(request, segment);
|
|
693
|
+
if (segment !== boundary.contentSegment) writeSegmentRevealScript(request, segment, blockingIds);
|
|
694
|
+
}
|
|
695
|
+
function writeSegmentRevealScript(request, segment, blockingIds) {
|
|
696
|
+
const id = ensureSegmentId(request, segment);
|
|
697
|
+
writeRuntime(request);
|
|
698
|
+
writeScript(request, withAssetGate(blockingIds, `${RUNTIME_REF}.s(${jsString(placeholderId(request, id))},${jsString(segmentId(request, id))})`));
|
|
699
|
+
}
|
|
700
|
+
function writeBoundaryRevealScript(request, boundary) {
|
|
701
|
+
const blockingIds = flushSegmentAssets(request, boundary.contentSegment);
|
|
702
|
+
const metadata = switchBoundaryMetadata(request, boundary);
|
|
703
|
+
const metadataArgument = metadata === null ? "" : `,${metadata}`;
|
|
704
|
+
writeRuntime(request);
|
|
705
|
+
const boundaryRef = jsString(boundaryId(request, ensureBoundaryId(request, boundary)));
|
|
706
|
+
const contentRef = jsString(segmentId(request, ensureSegmentId(request, boundary.contentSegment)));
|
|
707
|
+
writeScript(request, withAssetGate(blockingIds, boundary.activityId === null ? `${RUNTIME_REF}.c(${boundaryRef},${contentRef}${metadataArgument})` : `${RUNTIME_REF}.ac(${jsString(boundary.activityId)},${boundaryRef},${contentRef}${metadataArgument})`));
|
|
708
|
+
}
|
|
709
|
+
function switchBoundaryMetadata(request, boundary) {
|
|
710
|
+
if (!boundary.metadataVisible) return null;
|
|
711
|
+
const before = escapeScriptJson(request.assetRegistry.metadataSnapshot());
|
|
712
|
+
const fallback = boundary.fallbackSegment;
|
|
713
|
+
if (fallback !== null) {
|
|
714
|
+
request.assetRegistry.releaseMetadata(fallback);
|
|
715
|
+
for (const child of fallback.children) deactivateMetadataTree(request, child);
|
|
716
|
+
}
|
|
717
|
+
activateVisibleMetadata(request, boundary.contentSegment);
|
|
718
|
+
const after = escapeScriptJson(request.assetRegistry.metadataSnapshot());
|
|
719
|
+
return before === after ? null : after;
|
|
720
|
+
}
|
|
721
|
+
function activateVisibleMetadata(request, segment) {
|
|
722
|
+
if (segment.status === "pending" || segment.status === "rendering") return;
|
|
723
|
+
const boundary = segment.boundary;
|
|
724
|
+
if (boundary !== null) {
|
|
725
|
+
boundary.metadataVisible = true;
|
|
726
|
+
if (boundary.status === "completed") {
|
|
727
|
+
activateVisibleMetadata(request, boundary.contentSegment);
|
|
728
|
+
return;
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
request.assetRegistry.activateMetadata(segment, segment.assetResources);
|
|
732
|
+
for (const child of segment.children) activateVisibleMetadata(request, child);
|
|
733
|
+
}
|
|
734
|
+
function deactivateMetadataTree(request, segment) {
|
|
735
|
+
request.assetRegistry.releaseMetadata(segment);
|
|
736
|
+
for (const child of segment.children) deactivateMetadataTree(request, child);
|
|
737
|
+
const boundary = segment.boundary;
|
|
738
|
+
if (boundary === null) return;
|
|
739
|
+
boundary.metadataVisible = false;
|
|
740
|
+
deactivateMetadataTree(request, boundary.contentSegment);
|
|
741
|
+
}
|
|
742
|
+
function flushSegmentContainer(request, segment) {
|
|
743
|
+
if (segment.status === "flushed") return [];
|
|
744
|
+
const blockingIds = flushSegmentAssets(request, segment);
|
|
745
|
+
request.write(segmentContainerStartMarkup(request, ensureSegmentId(request, segment)));
|
|
746
|
+
flushSegment(request, segment);
|
|
747
|
+
request.write("</div>");
|
|
748
|
+
return blockingIds;
|
|
749
|
+
}
|
|
750
|
+
function flushSegmentAssets(request, segment) {
|
|
751
|
+
const blockingIds = /* @__PURE__ */ new Set();
|
|
752
|
+
collectSegmentAssets(request, segment, blockingIds);
|
|
753
|
+
return [...blockingIds];
|
|
754
|
+
}
|
|
755
|
+
function collectSegmentAssets(request, segment, blockingIds) {
|
|
756
|
+
if (segment.status !== "pending" && segment.status !== "rendering") flushAssetList(request, segment.assetResources, blockingIds);
|
|
757
|
+
for (const child of segment.children) collectSegmentAssets(request, child, blockingIds);
|
|
758
|
+
}
|
|
759
|
+
function flushAssetList(request, resources, blockingIds) {
|
|
760
|
+
for (const resource of resources) {
|
|
761
|
+
const id = request.assetRegistry.write(resource, request);
|
|
762
|
+
if (id !== null) blockingIds.add(id);
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
function withAssetGate(blockingIds, call) {
|
|
766
|
+
if (blockingIds.length === 0) return call;
|
|
767
|
+
return `${RUNTIME_REF}.r([${blockingIds.map(jsString).join(",")}],()=>{${call}})`;
|
|
768
|
+
}
|
|
769
|
+
function flushClientRenderedBoundary(request, boundary) {
|
|
770
|
+
if (boundary.id === null) return;
|
|
771
|
+
writeRuntime(request);
|
|
772
|
+
const boundaryRef = jsString(boundaryId(request, boundary.id));
|
|
773
|
+
const digest = jsString(boundary.error?.digest ?? "");
|
|
774
|
+
const message = jsString(boundary.error?.message ?? "");
|
|
775
|
+
writeScript(request, boundary.activityId === null ? `${RUNTIME_REF}.x(${boundaryRef},${digest},${message})` : `${RUNTIME_REF}.ax(${jsString(boundary.activityId)},${boundaryRef},${digest},${message})`);
|
|
776
|
+
}
|
|
777
|
+
function drainBoundaryQueue(request, queue, flush) {
|
|
778
|
+
for (;;) {
|
|
779
|
+
if (streamFlowBlocked(request.controller)) return true;
|
|
780
|
+
const first = queue.values().next();
|
|
781
|
+
if (first.done === true) return false;
|
|
782
|
+
flush(request, first.value);
|
|
783
|
+
queue.delete(first.value);
|
|
784
|
+
flushWriteBuffer(request);
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
function writeRuntime(request) {
|
|
788
|
+
writeRuntime$1(request, (chunk) => request.write(chunk));
|
|
789
|
+
}
|
|
790
|
+
function writeScript(request, code) {
|
|
791
|
+
writeScript$1(request, `(__figSSR=>{${code}})(globalThis[${jsString(request.runtimeName)}])`, (chunk) => request.write(chunk));
|
|
792
|
+
}
|
|
793
|
+
function writeChunk(request, chunk, segment) {
|
|
794
|
+
if (chunk === leadingNewlineStartMarker) {
|
|
795
|
+
request.leadingNewlineStack.push(false);
|
|
796
|
+
return;
|
|
797
|
+
}
|
|
798
|
+
if (chunk === leadingNewlineEndMarker) {
|
|
799
|
+
request.leadingNewlineStack.pop();
|
|
800
|
+
return;
|
|
801
|
+
}
|
|
802
|
+
if (typeof chunk === "object") {
|
|
803
|
+
request.write(request.leadingNewlineStack.at(-1) === false && chunk.value.startsWith("\n") ? `\n${chunk.value}` : chunk.value);
|
|
804
|
+
return;
|
|
805
|
+
}
|
|
806
|
+
if (chunk !== documentHeadMarker) {
|
|
807
|
+
request.write(chunk);
|
|
808
|
+
return;
|
|
809
|
+
}
|
|
810
|
+
if (request.document === null) return;
|
|
811
|
+
const metadata = request.headSnapshot ?? request.assetRegistry.headMetadataHtml(request.nonce);
|
|
812
|
+
const [beforeMetadata, afterMetadata] = partitionHeadAssets(request, segment.assetResources);
|
|
813
|
+
const blockingIds = /* @__PURE__ */ new Set();
|
|
814
|
+
request.write(metadata.preamble);
|
|
815
|
+
flushAssetList(request, beforeMetadata, blockingIds);
|
|
816
|
+
request.write(metadata.metadata);
|
|
817
|
+
flushAssetList(request, afterMetadata, blockingIds);
|
|
818
|
+
}
|
|
819
|
+
function partitionHeadAssets(request, resources) {
|
|
820
|
+
const preconnects = [];
|
|
821
|
+
const criticalPreloads = [];
|
|
822
|
+
const stylesheets = [];
|
|
823
|
+
const afterMetadata = [];
|
|
824
|
+
for (const resource of resources) if (resource.kind === "preconnect") preconnects.push(resource);
|
|
825
|
+
else if (resource.kind === "font" || resource.kind === "preload" && (resource.as === "font" || resource.as === "image" && (resource.fetchpriority === "high" || request.assetRegistry.isEarlyImage(resource)))) criticalPreloads.push(resource);
|
|
826
|
+
else if (resource.kind === "stylesheet") stylesheets.push(resource);
|
|
827
|
+
else afterMetadata.push(resource);
|
|
828
|
+
return [[
|
|
829
|
+
...preconnects,
|
|
830
|
+
...criticalPreloads,
|
|
831
|
+
...stylesheets
|
|
832
|
+
], afterMetadata];
|
|
833
|
+
}
|
|
834
|
+
function flushWriteBuffer(request) {
|
|
835
|
+
if (request.writeBuffer.length === 0 || request.controller === null) return;
|
|
836
|
+
request.controller.enqueue(textEncoder.encode(request.writeBuffer.join("")));
|
|
837
|
+
request.writeBuffer = [];
|
|
838
|
+
}
|
|
839
|
+
function ensureSegmentId(request, segment) {
|
|
840
|
+
segment.id ??= request.nextSegmentId++;
|
|
841
|
+
return segment.id;
|
|
842
|
+
}
|
|
843
|
+
function ensureBoundaryId(request, boundary) {
|
|
844
|
+
boundary.id ??= request.nextBoundaryId++;
|
|
845
|
+
return boundary.id;
|
|
846
|
+
}
|
|
847
|
+
//#endregion
|
|
848
|
+
//#region src/renderer.ts
|
|
849
|
+
const errorStacks = /* @__PURE__ */ new WeakMap();
|
|
850
|
+
const TEXT_SEPARATOR = `<!--${TEXT_SEPARATOR_DATA}-->`;
|
|
369
851
|
let nextRuntimeId = 0;
|
|
370
852
|
function createServerRenderRequest(node, options = {}, mode = {}) {
|
|
371
853
|
throwIfAborted(options.signal);
|
|
@@ -376,40 +858,39 @@ function createServerRenderRequest(node, options = {}, mode = {}) {
|
|
|
376
858
|
headReady.promise.catch(() => void 0);
|
|
377
859
|
allReady.promise.catch(() => void 0);
|
|
378
860
|
const rootSegment = createSegment(0, null);
|
|
861
|
+
const dataStoreHost = {
|
|
862
|
+
getLane: () => null,
|
|
863
|
+
partition: options.dataPartition,
|
|
864
|
+
schedule: () => void 0
|
|
865
|
+
};
|
|
866
|
+
const dataStore = options.dataStore === void 0 ? createRendererDataStore(dataStoreHost) : attachDataStore(options.dataStore, dataStoreHost, options.initialData);
|
|
379
867
|
const request = {
|
|
380
868
|
abortableTasks: /* @__PURE__ */ new Set(),
|
|
381
|
-
abortListener: null,
|
|
382
|
-
abortSignal: options.signal ?? null,
|
|
383
869
|
allReady,
|
|
870
|
+
cleanupAbortListener: () => void 0,
|
|
384
871
|
completedBoundaries: /* @__PURE__ */ new Set(),
|
|
385
872
|
completedRootSegment: null,
|
|
386
873
|
controller: null,
|
|
387
|
-
dataStore
|
|
388
|
-
getLane: () => null,
|
|
389
|
-
partition: options.dataPartition,
|
|
390
|
-
schedule: () => void 0
|
|
391
|
-
}),
|
|
874
|
+
dataStore,
|
|
392
875
|
fatalError: null,
|
|
393
876
|
identifierPrefix: options.identifierPrefix ?? "",
|
|
877
|
+
leadingNewlineStack: [],
|
|
394
878
|
nextBoundaryId: 0,
|
|
395
879
|
nextSegmentId: 0,
|
|
396
880
|
nextActivityId: 0,
|
|
397
881
|
nextViewTransitionId: 0,
|
|
398
882
|
nonce: options.nonce,
|
|
399
883
|
onError: options.onError,
|
|
400
|
-
onAssetError: options.onAssetError,
|
|
401
884
|
pendingRootTasks: 0,
|
|
402
885
|
pendingTasks: 0,
|
|
403
886
|
pingedTasks: [],
|
|
404
|
-
assetSink: null,
|
|
405
887
|
rootSegment,
|
|
406
888
|
runtimeName: createRuntimeName(options.identifierPrefix),
|
|
407
889
|
runtimeWritten: false,
|
|
408
890
|
headReady,
|
|
409
891
|
headSnapshot: null,
|
|
410
892
|
shellReady,
|
|
411
|
-
status: "
|
|
412
|
-
stream: null,
|
|
893
|
+
status: "open",
|
|
413
894
|
clientRenderedBoundaries: /* @__PURE__ */ new Set(),
|
|
414
895
|
clientReferenceFallback: options.clientReferenceFallback,
|
|
415
896
|
partialBoundaries: /* @__PURE__ */ new Set(),
|
|
@@ -419,22 +900,14 @@ function createServerRenderRequest(node, options = {}, mode = {}) {
|
|
|
419
900
|
assetRegistry: new AssetResourceRegistry(options.identifierPrefix ?? ""),
|
|
420
901
|
resolveAssetKey: options.resolveAssetKey,
|
|
421
902
|
workScheduled: false,
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
};
|
|
428
|
-
const stream = new ReadableStream({
|
|
429
|
-
start(streamController) {
|
|
430
|
-
request.controller = streamController;
|
|
431
|
-
flushCompletedQueues(request);
|
|
432
|
-
},
|
|
433
|
-
cancel(reason) {
|
|
434
|
-
abort(request, reason);
|
|
903
|
+
flushing: false,
|
|
904
|
+
writeBuffer: [],
|
|
905
|
+
write(chunk) {
|
|
906
|
+
if (chunk !== "" && this.leadingNewlineStack.length > 0) this.leadingNewlineStack[this.leadingNewlineStack.length - 1] = true;
|
|
907
|
+
this.writeBuffer.push(chunk);
|
|
435
908
|
}
|
|
436
|
-
}
|
|
437
|
-
|
|
909
|
+
};
|
|
910
|
+
if (options.dataStore === void 0 && options.initialData !== void 0) request.dataStore.hydrate(options.initialData);
|
|
438
911
|
rootSegment.parentFlushed = true;
|
|
439
912
|
const rootTask = createTask(request, node, rootSegment, {
|
|
440
913
|
abortSet: request.abortableTasks,
|
|
@@ -442,17 +915,39 @@ function createServerRenderRequest(node, options = {}, mode = {}) {
|
|
|
442
915
|
contextValues: /* @__PURE__ */ new Map(),
|
|
443
916
|
hiddenActivityId: null,
|
|
444
917
|
hostAncestors: [],
|
|
918
|
+
hostNamespace: "html",
|
|
919
|
+
imagePreloadsSuppressed: false,
|
|
445
920
|
idPath: "",
|
|
921
|
+
pendingLeadingNewline: false,
|
|
446
922
|
selectProps: null,
|
|
447
923
|
stack: null,
|
|
448
924
|
treeParent: options.renderTree?.tree ?? null,
|
|
449
925
|
viewTransition: null
|
|
450
926
|
});
|
|
451
927
|
request.pingedTasks.push(rootTask);
|
|
928
|
+
const stream = new ReadableStream({
|
|
929
|
+
start(streamController) {
|
|
930
|
+
request.controller = streamController;
|
|
931
|
+
flushCompletedQueues(request);
|
|
932
|
+
},
|
|
933
|
+
pull() {
|
|
934
|
+
flushCompletedQueues(request);
|
|
935
|
+
},
|
|
936
|
+
cancel(reason) {
|
|
937
|
+
request.controller = null;
|
|
938
|
+
request.writeBuffer = [];
|
|
939
|
+
abort(request, reason);
|
|
940
|
+
request.status = "closed";
|
|
941
|
+
}
|
|
942
|
+
}, new ByteLengthQueuingStrategy({ highWaterMark: streamHighWaterMark(options.highWaterMark) }));
|
|
452
943
|
if (options.signal !== void 0) {
|
|
453
|
-
const
|
|
454
|
-
|
|
455
|
-
|
|
944
|
+
const signal = options.signal;
|
|
945
|
+
const abortListener = () => abort(request, signal.reason);
|
|
946
|
+
signal.addEventListener("abort", abortListener, { once: true });
|
|
947
|
+
request.cleanupAbortListener = () => {
|
|
948
|
+
signal.removeEventListener("abort", abortListener);
|
|
949
|
+
request.cleanupAbortListener = () => void 0;
|
|
950
|
+
};
|
|
456
951
|
}
|
|
457
952
|
request.workScheduled = true;
|
|
458
953
|
queueMicrotask(() => {
|
|
@@ -463,8 +958,13 @@ function createServerRenderRequest(node, options = {}, mode = {}) {
|
|
|
463
958
|
abort: (reason) => abort(request, reason),
|
|
464
959
|
allReady: allReady.promise,
|
|
465
960
|
contentType: "text/html; charset=utf-8",
|
|
961
|
+
data: request.dataStore,
|
|
466
962
|
getData: () => request.dataStore.snapshot(),
|
|
467
|
-
|
|
963
|
+
getPreloadHeader: (headerOptions) => request.headSnapshot === null ? void 0 : formatPreloadHeader(request.headSnapshot.preloadHeaderEntries, headerOptions),
|
|
964
|
+
getHead: () => {
|
|
965
|
+
const snapshot = request.headSnapshot;
|
|
966
|
+
return snapshot === null ? request.assetRegistry.headHtml(request.nonce) : snapshot.preamble + snapshot.metadata;
|
|
967
|
+
},
|
|
468
968
|
headReady: headReady.promise,
|
|
469
969
|
shellReady: shellReady.promise,
|
|
470
970
|
stream
|
|
@@ -491,7 +991,10 @@ function forkScope(scope) {
|
|
|
491
991
|
contextValues: cloneContextValues(scope.contextValues),
|
|
492
992
|
hiddenActivityId: scope.hiddenActivityId,
|
|
493
993
|
hostAncestors: scope.hostAncestors,
|
|
994
|
+
hostNamespace: scope.hostNamespace,
|
|
995
|
+
imagePreloadsSuppressed: scope.imagePreloadsSuppressed,
|
|
494
996
|
idPath: scope.idPath,
|
|
997
|
+
pendingLeadingNewline: scope.pendingLeadingNewline,
|
|
495
998
|
selectProps: scope.selectProps,
|
|
496
999
|
stack: scope.stack,
|
|
497
1000
|
treeParent: scope.treeParent,
|
|
@@ -525,16 +1028,17 @@ function createBoundary(fallbackAbortableTasks, contentSegment) {
|
|
|
525
1028
|
completedSegments: [],
|
|
526
1029
|
contentSegment,
|
|
527
1030
|
error: null,
|
|
1031
|
+
fallbackSegment: null,
|
|
528
1032
|
fallbackAbortableTasks,
|
|
529
1033
|
id: null,
|
|
530
1034
|
parentFlushed: false,
|
|
531
1035
|
pendingTasks: 0,
|
|
532
|
-
status: "pending"
|
|
1036
|
+
status: "pending",
|
|
1037
|
+
metadataVisible: false
|
|
533
1038
|
};
|
|
534
1039
|
}
|
|
535
1040
|
function performWork(request) {
|
|
536
1041
|
if (request.status === "closed") return;
|
|
537
|
-
if (request.status === "opening") request.status = "open";
|
|
538
1042
|
const tasks = request.pingedTasks;
|
|
539
1043
|
request.pingedTasks = [];
|
|
540
1044
|
for (const task of tasks) retryTask(request, task);
|
|
@@ -549,7 +1053,7 @@ function retryTask(request, task) {
|
|
|
549
1053
|
completeSegmentText(task.segment);
|
|
550
1054
|
task.segment.status = "completed";
|
|
551
1055
|
detachTask(request, task);
|
|
552
|
-
finishedTask(request, task
|
|
1056
|
+
finishedTask(request, task);
|
|
553
1057
|
} catch (error) {
|
|
554
1058
|
detachTask(request, task);
|
|
555
1059
|
task.segment.status = "completed";
|
|
@@ -557,16 +1061,13 @@ function retryTask(request, task) {
|
|
|
557
1061
|
}
|
|
558
1062
|
}
|
|
559
1063
|
function createRenderFrame(request, segment, scope) {
|
|
560
|
-
|
|
1064
|
+
return {
|
|
561
1065
|
...scope,
|
|
562
1066
|
dispatcher: null,
|
|
563
1067
|
localIdCounter: 0,
|
|
564
|
-
pendingLeadingNewlineHost: null,
|
|
565
1068
|
request,
|
|
566
1069
|
segment
|
|
567
1070
|
};
|
|
568
|
-
frame.dispatcher = createServerDispatcher(frame);
|
|
569
|
-
return frame;
|
|
570
1071
|
}
|
|
571
1072
|
function createServerDispatcher(frame) {
|
|
572
1073
|
return createStaticDispatcher({
|
|
@@ -611,29 +1112,39 @@ function renderNode(node, frame) {
|
|
|
611
1112
|
name: "#text",
|
|
612
1113
|
props: { nodeValue: text }
|
|
613
1114
|
});
|
|
614
|
-
const output = consumePendingLeadingNewline(frame) ? preserveParserStrippedLeadingNewline(text) : text;
|
|
615
1115
|
if (frame.segment.lastPushedText) frame.segment.write(TEXT_SEPARATOR);
|
|
616
|
-
|
|
1116
|
+
if (consumePendingLeadingNewline(frame)) writeLeadingNewlineText(text, frame.segment);
|
|
1117
|
+
else writeText(text, frame.segment);
|
|
617
1118
|
frame.segment.lastPushedText = true;
|
|
618
1119
|
}
|
|
619
1120
|
return;
|
|
620
1121
|
}
|
|
621
1122
|
if (isPortal(node)) return;
|
|
622
|
-
if (
|
|
623
|
-
|
|
1123
|
+
if (isValidElement(node)) {
|
|
1124
|
+
renderElement(node, frame);
|
|
1125
|
+
return;
|
|
1126
|
+
}
|
|
1127
|
+
if (isThenable(node)) {
|
|
1128
|
+
renderChildren(readThenable(node), frame);
|
|
1129
|
+
return;
|
|
1130
|
+
}
|
|
1131
|
+
throw invalidChildError(node);
|
|
624
1132
|
}
|
|
625
1133
|
function renderChildren(node, frame) {
|
|
626
1134
|
renderChildSequence(collectChildren(node), frame);
|
|
627
1135
|
}
|
|
628
1136
|
function renderChildSequence(children, frame, indexBase = 0) {
|
|
629
|
-
for (let index = 0; index < children.length; index += 1)
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
1137
|
+
for (let index = 0; index < children.length; index += 1) {
|
|
1138
|
+
const child = children[index];
|
|
1139
|
+
try {
|
|
1140
|
+
withIdSegment(frame, indexBase + index, () => renderNode(child, frame));
|
|
1141
|
+
} catch (error) {
|
|
1142
|
+
if (isThenable(error)) {
|
|
1143
|
+
spawnSuspendedTask(frame, child, error, indexBase + index);
|
|
1144
|
+
continue;
|
|
1145
|
+
}
|
|
1146
|
+
throw error;
|
|
635
1147
|
}
|
|
636
|
-
throw error;
|
|
637
1148
|
}
|
|
638
1149
|
}
|
|
639
1150
|
function completeSegmentText(segment) {
|
|
@@ -678,20 +1189,13 @@ function collectedTreeNode(element) {
|
|
|
678
1189
|
function collectedNameAndKind(type) {
|
|
679
1190
|
if (typeof type === "string") return [type, "host"];
|
|
680
1191
|
if (type === Fragment) return ["Fragment", "fragment"];
|
|
681
|
-
if (isContext(type))
|
|
682
|
-
const named = type;
|
|
683
|
-
return [`${typeof named.displayName === "string" && named.displayName !== "" ? named.displayName : "Context"}.Provider`, "context-provider"];
|
|
684
|
-
}
|
|
1192
|
+
if (isContext(type)) return ["Context.Provider", "context-provider"];
|
|
685
1193
|
if (isAssets(type)) return ["Assets", "assets"];
|
|
686
1194
|
if (isSuspense(type)) return ["Suspense", "suspense"];
|
|
687
1195
|
if (isErrorBoundary(type)) return ["ErrorBoundary", "error-boundary"];
|
|
688
1196
|
if (isActivity(type)) return ["Activity", "activity"];
|
|
689
1197
|
if (isViewTransition(type)) return ["ViewTransition", "view-transition"];
|
|
690
|
-
if (isClientReference(type))
|
|
691
|
-
const id = type.id;
|
|
692
|
-
const exportName = id.slice(id.lastIndexOf("#") + 1);
|
|
693
|
-
return [exportName === "" ? "ClientReference" : exportName, "client-reference"];
|
|
694
|
-
}
|
|
1198
|
+
if (isClientReference(type)) return [type.id.slice(type.id.lastIndexOf("#") + 1) || "ClientReference", "client-reference"];
|
|
695
1199
|
if (typeof type === "function") return [type.name === "" ? "Anonymous" : type.name, "function"];
|
|
696
1200
|
return ["Anonymous", "function"];
|
|
697
1201
|
}
|
|
@@ -740,6 +1244,7 @@ function renderElementKind(element, frame) {
|
|
|
740
1244
|
throw new Error(`Unsupported Fig element type: ${describeElementType(type)}.`);
|
|
741
1245
|
}
|
|
742
1246
|
function renderFunctionComponent(type, props, frame) {
|
|
1247
|
+
frame.dispatcher ??= createServerDispatcher(frame);
|
|
743
1248
|
const previousDispatcher = setCurrentDispatcher(frame.dispatcher);
|
|
744
1249
|
const previousDataStore = setCurrentDataStore(frame.request.dataStore);
|
|
745
1250
|
const previousStack = frame.stack;
|
|
@@ -792,7 +1297,7 @@ function renderAssetValue(value, frame) {
|
|
|
792
1297
|
for (const resource of Array.isArray(value) ? value : [value]) {
|
|
793
1298
|
if (!isFigAssetResource(resource)) throw new Error("The assets prop must contain Fig asset resources.");
|
|
794
1299
|
try {
|
|
795
|
-
|
|
1300
|
+
frame.request.assetRegistry.register(resource);
|
|
796
1301
|
} catch (error) {
|
|
797
1302
|
recordErrorStack(error, frame.stack);
|
|
798
1303
|
throw error;
|
|
@@ -800,18 +1305,14 @@ function renderAssetValue(value, frame) {
|
|
|
800
1305
|
frame.segment.assetResources.push(resource);
|
|
801
1306
|
}
|
|
802
1307
|
}
|
|
803
|
-
function
|
|
804
|
-
if (request.headSnapshot === null || assetResourceDestination(resource) !== "head") return;
|
|
805
|
-
const key = assetResourceKey(resource);
|
|
806
|
-
const error = /* @__PURE__ */ new Error(`Fig head resource "${key}" was discovered after headReady. Move required metadata outside pending Suspense boundaries, or wait for allReady before reading getHead().`);
|
|
1308
|
+
function renderAutomaticImagePreload(resource, frame) {
|
|
807
1309
|
try {
|
|
808
|
-
request.
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
} catch {}
|
|
1310
|
+
frame.request.assetRegistry.registerAutomaticImage(resource);
|
|
1311
|
+
} catch (error) {
|
|
1312
|
+
recordErrorStack(error, frame.stack);
|
|
1313
|
+
throw error;
|
|
1314
|
+
}
|
|
1315
|
+
frame.segment.assetResources.push(resource);
|
|
815
1316
|
}
|
|
816
1317
|
function renderSuspense(props, frame) {
|
|
817
1318
|
consumePendingLeadingNewline(frame);
|
|
@@ -821,6 +1322,7 @@ function renderSuspense(props, frame) {
|
|
|
821
1322
|
boundary.activityId = frame.hiddenActivityId;
|
|
822
1323
|
const parentSegment = frame.segment;
|
|
823
1324
|
const boundarySegment = createSegment(parentSegment.chunks.length, boundary);
|
|
1325
|
+
boundary.fallbackSegment = boundarySegment;
|
|
824
1326
|
parentSegment.children.push(boundarySegment);
|
|
825
1327
|
parentSegment.lastPushedText = false;
|
|
826
1328
|
contentSegment.parentFlushed = true;
|
|
@@ -894,54 +1396,77 @@ function renderActivity(props, frame) {
|
|
|
894
1396
|
frame.segment.write("</template>");
|
|
895
1397
|
}
|
|
896
1398
|
function renderHostElement(type, props, frame) {
|
|
897
|
-
|
|
1399
|
+
const namespace = hostElementNamespace(type, frame.hostNamespace);
|
|
1400
|
+
if (namespace === "html" && renderHostAsset(type, props, frame)) return;
|
|
898
1401
|
const document = frame.request.document;
|
|
899
1402
|
if (document !== null && !document.hasHead) {
|
|
900
1403
|
if (type !== "html" && type !== "head") throw invalidDocumentShellError();
|
|
901
1404
|
}
|
|
902
1405
|
if (document !== null && type === "html") frame.segment.write("<!doctype html>");
|
|
903
1406
|
if (document !== null && type === "head") document.hasHead = true;
|
|
904
|
-
const isVoid = isVoidElement(type);
|
|
1407
|
+
const isVoid = namespace === "html" && isVoidElement(type);
|
|
905
1408
|
const unsafeHTML = unsafeHTMLContent(props);
|
|
906
1409
|
if (isVoid && hasRenderableChild(props.children)) throw new Error(`Void element <${type}> cannot have children.`);
|
|
907
1410
|
if (isVoid && unsafeHTML !== null) throw new Error(`Void element <${type}> cannot have unsafeHTML.`);
|
|
908
1411
|
if (unsafeHTML !== null && hasRenderableChild(props.children)) throw new Error("Host elements cannot have both unsafeHTML and children.");
|
|
1412
|
+
if (namespace === "html") {
|
|
1413
|
+
const imagePreload = imagePreloadFromHostProps(type, props, frame.imagePreloadsSuppressed);
|
|
1414
|
+
if (imagePreload !== null) renderAutomaticImagePreload(imagePreload, frame);
|
|
1415
|
+
}
|
|
909
1416
|
consumePendingLeadingNewline(frame);
|
|
910
1417
|
const viewTransition = frame.viewTransition;
|
|
911
1418
|
writeElementStart(type, viewTransition === null ? props : viewTransitionHostProps(props, viewTransition), frame.segment, frame.selectProps ?? {});
|
|
912
1419
|
if (document !== null && type === "head") frame.segment.write(earlyEventCaptureMarkup(frame.request));
|
|
913
1420
|
if (isVoid) return;
|
|
914
|
-
const
|
|
915
|
-
|
|
1421
|
+
const previousPendingLeadingNewline = frame.pendingLeadingNewline;
|
|
1422
|
+
const tracksLeadingNewline = leadingNewlineStrippedHost(type);
|
|
1423
|
+
frame.pendingLeadingNewline = tracksLeadingNewline;
|
|
916
1424
|
if (unsafeHTML !== null) {
|
|
917
1425
|
frame.segment.write(consumePendingLeadingNewline(frame) ? preserveParserStrippedLeadingNewline(unsafeHTML) : unsafeHTML);
|
|
918
|
-
frame.
|
|
1426
|
+
frame.pendingLeadingNewline = previousPendingLeadingNewline;
|
|
919
1427
|
writeElementEnd(type, frame.segment);
|
|
920
1428
|
return;
|
|
921
1429
|
}
|
|
922
|
-
const formText = formTextContent(type, props);
|
|
1430
|
+
const formText = namespace === "html" ? formTextContent(type, props) : null;
|
|
923
1431
|
if (formText !== null) {
|
|
924
1432
|
writeText(consumePendingLeadingNewline(frame) ? preserveParserStrippedLeadingNewline(formText) : formText, frame.segment);
|
|
925
|
-
frame.
|
|
1433
|
+
frame.pendingLeadingNewline = previousPendingLeadingNewline;
|
|
926
1434
|
writeElementEnd(type, frame.segment);
|
|
927
1435
|
return;
|
|
928
1436
|
}
|
|
929
1437
|
const previousSelectProps = frame.selectProps;
|
|
930
|
-
if (type === "select") frame.selectProps = props;
|
|
1438
|
+
if (namespace === "html" && type === "select") frame.selectProps = props;
|
|
931
1439
|
const previousHostAncestors = frame.hostAncestors;
|
|
1440
|
+
const previousHostNamespace = frame.hostNamespace;
|
|
1441
|
+
const previousImagePreloadsSuppressed = frame.imagePreloadsSuppressed;
|
|
932
1442
|
const previousViewTransition = frame.viewTransition;
|
|
933
1443
|
if (viewTransition !== null) frame.viewTransition = null;
|
|
1444
|
+
frame.hostNamespace = childHostNamespace(type, namespace);
|
|
1445
|
+
frame.imagePreloadsSuppressed = previousImagePreloadsSuppressed || namespace === "html" && suppressesImagePreloads(type);
|
|
1446
|
+
if (tracksLeadingNewline) frame.segment.chunks.push(leadingNewlineStartMarker);
|
|
934
1447
|
try {
|
|
935
1448
|
renderChildren(props.children, frame);
|
|
936
1449
|
} finally {
|
|
937
1450
|
frame.selectProps = previousSelectProps;
|
|
938
1451
|
frame.hostAncestors = previousHostAncestors;
|
|
1452
|
+
frame.hostNamespace = previousHostNamespace;
|
|
1453
|
+
frame.imagePreloadsSuppressed = previousImagePreloadsSuppressed;
|
|
939
1454
|
frame.viewTransition = previousViewTransition;
|
|
940
|
-
frame.
|
|
1455
|
+
frame.pendingLeadingNewline = previousPendingLeadingNewline;
|
|
941
1456
|
}
|
|
1457
|
+
if (tracksLeadingNewline) frame.segment.chunks.push(leadingNewlineEndMarker);
|
|
942
1458
|
if (document !== null && type === "head") writeDocumentHeadMarker(frame.segment);
|
|
943
1459
|
writeElementEnd(type, frame.segment);
|
|
944
1460
|
}
|
|
1461
|
+
function hostElementNamespace(type, parent) {
|
|
1462
|
+
const normalizedType = type.toLowerCase();
|
|
1463
|
+
if (normalizedType === "svg") return "svg";
|
|
1464
|
+
if (normalizedType === "math") return "mathml";
|
|
1465
|
+
return parent;
|
|
1466
|
+
}
|
|
1467
|
+
function childHostNamespace(type, namespace) {
|
|
1468
|
+
return namespace === "svg" && type.toLowerCase() === "foreignobject" ? "html" : namespace;
|
|
1469
|
+
}
|
|
945
1470
|
function renderHostAsset(type, props, frame) {
|
|
946
1471
|
const resource = assetResourceFromHostProps(type, props);
|
|
947
1472
|
if (resource === null) return false;
|
|
@@ -979,16 +1504,16 @@ function pingTask(request, task) {
|
|
|
979
1504
|
performWork(request);
|
|
980
1505
|
});
|
|
981
1506
|
}
|
|
982
|
-
function finishedTask(request, task
|
|
1507
|
+
function finishedTask(request, task) {
|
|
983
1508
|
request.pendingTasks -= 1;
|
|
984
1509
|
const boundary = task.boundary;
|
|
985
1510
|
if (boundary === null) {
|
|
986
1511
|
request.pendingRootTasks -= 1;
|
|
987
|
-
if (segment === request.rootSegment || request.completedRootSegment === null) request.completedRootSegment = request.rootSegment;
|
|
1512
|
+
if (task.segment === request.rootSegment || request.completedRootSegment === null) request.completedRootSegment = request.rootSegment;
|
|
988
1513
|
if (request.pendingRootTasks === 0) finishRootShell(request);
|
|
989
1514
|
} else {
|
|
990
1515
|
boundary.pendingTasks -= 1;
|
|
991
|
-
if (segment.parentFlushed) enqueueUnique(boundary.completedSegments, segment);
|
|
1516
|
+
if (task.segment.parentFlushed) enqueueUnique(boundary.completedSegments, task.segment);
|
|
992
1517
|
if (!completeBoundaryIfReady(request, boundary) && boundary.parentFlushed) request.partialBoundaries.add(boundary);
|
|
993
1518
|
}
|
|
994
1519
|
if (request.pendingTasks === 0) request.allReady.resolve(void 0);
|
|
@@ -1048,7 +1573,7 @@ function markBoundaryClientRendered(request, boundary, error, stack, payload) {
|
|
|
1048
1573
|
}
|
|
1049
1574
|
function abort(request, reason) {
|
|
1050
1575
|
if (request.status === "closed") return;
|
|
1051
|
-
cleanupAbortListener(
|
|
1576
|
+
request.cleanupAbortListener();
|
|
1052
1577
|
request.status = "aborting";
|
|
1053
1578
|
request.dataStore.dispose();
|
|
1054
1579
|
const error = abortError(reason);
|
|
@@ -1068,7 +1593,7 @@ function abort(request, reason) {
|
|
|
1068
1593
|
}
|
|
1069
1594
|
function fatalError(request, error) {
|
|
1070
1595
|
if (request.status === "closed") return;
|
|
1071
|
-
cleanupAbortListener(
|
|
1596
|
+
request.cleanupAbortListener();
|
|
1072
1597
|
request.status = "closed";
|
|
1073
1598
|
request.dataStore.dispose();
|
|
1074
1599
|
request.fatalError = error;
|
|
@@ -1085,164 +1610,6 @@ function finishRootShell(request) {
|
|
|
1085
1610
|
if (!request.prerender) sealHead(request);
|
|
1086
1611
|
request.shellReady.resolve(void 0);
|
|
1087
1612
|
}
|
|
1088
|
-
function flushCompletedQueues(request) {
|
|
1089
|
-
if (request.controller === null || request.status === "closed") return;
|
|
1090
|
-
if (request.status === "opening") return;
|
|
1091
|
-
if (request.pendingRootTasks > 0) return;
|
|
1092
|
-
if (request.prerender && request.pendingTasks > 0) return;
|
|
1093
|
-
sealHead(request);
|
|
1094
|
-
if (request.completedRootSegment !== null) {
|
|
1095
|
-
flushSegment(request, request.completedRootSegment);
|
|
1096
|
-
request.completedRootSegment = null;
|
|
1097
|
-
flushWriteBuffer(request);
|
|
1098
|
-
}
|
|
1099
|
-
drainBoundaryQueue(request, request.clientRenderedBoundaries, flushClientRenderedBoundary);
|
|
1100
|
-
drainBoundaryQueue(request, request.completedBoundaries, flushCompletedBoundary);
|
|
1101
|
-
drainBoundaryQueue(request, request.partialBoundaries, flushPartialBoundary);
|
|
1102
|
-
flushWriteBuffer(request);
|
|
1103
|
-
if (request.pendingTasks === 0 && request.completedBoundaries.size === 0 && request.clientRenderedBoundaries.size === 0 && request.partialBoundaries.size === 0) {
|
|
1104
|
-
cleanupAbortListener(request);
|
|
1105
|
-
request.status = "closed";
|
|
1106
|
-
request.dataStore.dispose();
|
|
1107
|
-
request.controller.close();
|
|
1108
|
-
}
|
|
1109
|
-
}
|
|
1110
|
-
function flushSegment(request, segment) {
|
|
1111
|
-
if (segment.boundary !== null) {
|
|
1112
|
-
flushSuspenseBoundary(request, segment, segment.boundary);
|
|
1113
|
-
return;
|
|
1114
|
-
}
|
|
1115
|
-
flushSubtree(request, segment);
|
|
1116
|
-
}
|
|
1117
|
-
function flushSubtree(request, segment) {
|
|
1118
|
-
segment.parentFlushed = true;
|
|
1119
|
-
if (segment.status === "pending" || segment.status === "rendering") {
|
|
1120
|
-
write(request, placeholderMarkup(request, ensureSegmentId(request, segment)));
|
|
1121
|
-
return;
|
|
1122
|
-
}
|
|
1123
|
-
if (segment.status === "flushed") return;
|
|
1124
|
-
segment.status = "flushed";
|
|
1125
|
-
if (request.document === null || segment !== request.rootSegment) flushSegmentAssets(request, segment);
|
|
1126
|
-
let chunkIndex = 0;
|
|
1127
|
-
for (const child of segment.children) {
|
|
1128
|
-
for (; chunkIndex < child.index; chunkIndex += 1) writeChunk(request, segment.chunks[chunkIndex], segment);
|
|
1129
|
-
flushSegment(request, child);
|
|
1130
|
-
}
|
|
1131
|
-
for (; chunkIndex < segment.chunks.length; chunkIndex += 1) writeChunk(request, segment.chunks[chunkIndex], segment);
|
|
1132
|
-
}
|
|
1133
|
-
function flushSuspenseBoundary(request, segment, boundary) {
|
|
1134
|
-
segment.boundary = null;
|
|
1135
|
-
boundary.parentFlushed = true;
|
|
1136
|
-
if (boundary.status === "completed") {
|
|
1137
|
-
write(request, `<!--${SUSPENSE_COMPLETED_MARKER}-->`);
|
|
1138
|
-
flushBoundaryContent(request, boundary);
|
|
1139
|
-
write(request, `<!--${SUSPENSE_END_MARKER}-->`);
|
|
1140
|
-
return;
|
|
1141
|
-
}
|
|
1142
|
-
if (request.prerender && boundary.status === "client-rendered") {
|
|
1143
|
-
write(request, `<!--${SUSPENSE_CLIENT_MARKER}-->`);
|
|
1144
|
-
write(request, clientRenderedBoundaryPlaceholderMarkup(request, boundary));
|
|
1145
|
-
flushSubtree(request, segment);
|
|
1146
|
-
write(request, `<!--${SUSPENSE_END_MARKER}-->`);
|
|
1147
|
-
return;
|
|
1148
|
-
}
|
|
1149
|
-
const boundaryIdValue = ensureBoundaryId(request, boundary);
|
|
1150
|
-
flushSegmentAssets(request, boundary.contentSegment);
|
|
1151
|
-
write(request, `<!--${SUSPENSE_PENDING_PREFIX}${boundaryIdValue}-->`);
|
|
1152
|
-
write(request, boundaryPlaceholderMarkup(request, boundaryIdValue));
|
|
1153
|
-
flushSubtree(request, segment);
|
|
1154
|
-
write(request, `<!--${SUSPENSE_END_MARKER}-->`);
|
|
1155
|
-
if (boundary.status === "client-rendered") request.clientRenderedBoundaries.add(boundary);
|
|
1156
|
-
else if (boundary.completedSegments.length > 0) request.partialBoundaries.add(boundary);
|
|
1157
|
-
}
|
|
1158
|
-
function flushBoundaryContent(request, boundary) {
|
|
1159
|
-
for (const segment of boundary.completedSegments) flushSegment(request, segment);
|
|
1160
|
-
boundary.completedSegments = [];
|
|
1161
|
-
}
|
|
1162
|
-
function clientRenderedBoundaryPlaceholderMarkup(request, boundary) {
|
|
1163
|
-
const id = escapeAttribute(boundaryId(request, ensureBoundaryId(request, boundary)));
|
|
1164
|
-
const digest = boundary.error?.digest;
|
|
1165
|
-
const message = boundary.error?.message;
|
|
1166
|
-
return `<template id="${id}"${digest === void 0 || digest === "" ? "" : ` data-dgst="${escapeAttribute(digest)}"`}${message === void 0 || message === "" ? "" : ` data-msg="${escapeAttribute(message)}"`}></template>`;
|
|
1167
|
-
}
|
|
1168
|
-
function sealHead(request) {
|
|
1169
|
-
if (request.headSnapshot !== null) return;
|
|
1170
|
-
const head = request.assetRegistry.headHtml(request.nonce);
|
|
1171
|
-
request.headSnapshot = head;
|
|
1172
|
-
request.headReady.resolve(head);
|
|
1173
|
-
}
|
|
1174
|
-
function flushCompletedBoundary(request, boundary) {
|
|
1175
|
-
flushPartialBoundary(request, boundary);
|
|
1176
|
-
writeBoundaryRevealScript(request, boundary);
|
|
1177
|
-
}
|
|
1178
|
-
function flushPartialBoundary(request, boundary) {
|
|
1179
|
-
for (const segment of boundary.completedSegments) flushBoundarySegment(request, boundary, segment);
|
|
1180
|
-
boundary.completedSegments = [];
|
|
1181
|
-
}
|
|
1182
|
-
function flushBoundarySegment(request, boundary, segment) {
|
|
1183
|
-
ensureBoundaryId(request, boundary);
|
|
1184
|
-
ensureSegmentId(request, segment);
|
|
1185
|
-
const blockingIds = flushSegmentContainer(request, segment);
|
|
1186
|
-
if (segment !== boundary.contentSegment) writeSegmentRevealScript(request, segment, blockingIds);
|
|
1187
|
-
}
|
|
1188
|
-
function writeSegmentRevealScript(request, segment, blockingIds) {
|
|
1189
|
-
const id = ensureSegmentId(request, segment);
|
|
1190
|
-
writeRuntime(request);
|
|
1191
|
-
writeScript(request, withAssetGate(request, blockingIds, `${RUNTIME_REF}.s(${jsString(placeholderId(request, id))},${jsString(segmentId(request, id))})`));
|
|
1192
|
-
}
|
|
1193
|
-
function writeBoundaryRevealScript(request, boundary) {
|
|
1194
|
-
const blockingIds = flushSegmentAssets(request, boundary.contentSegment);
|
|
1195
|
-
writeRuntime(request);
|
|
1196
|
-
const boundaryRef = jsString(boundaryId(request, ensureBoundaryId(request, boundary)));
|
|
1197
|
-
const contentRef = jsString(segmentId(request, ensureSegmentId(request, boundary.contentSegment)));
|
|
1198
|
-
const runtime = RUNTIME_REF;
|
|
1199
|
-
writeScript(request, withAssetGate(request, blockingIds, boundary.activityId === null ? `${runtime}.c(${boundaryRef},${contentRef})` : `${runtime}.ac(${jsString(boundary.activityId)},${boundaryRef},${contentRef})`));
|
|
1200
|
-
}
|
|
1201
|
-
function flushSegmentContainer(request, segment) {
|
|
1202
|
-
if (segment.status === "flushed") return [];
|
|
1203
|
-
const blockingIds = flushSegmentAssets(request, segment);
|
|
1204
|
-
write(request, segmentContainerStartMarkup(request, ensureSegmentId(request, segment)));
|
|
1205
|
-
flushSegment(request, segment);
|
|
1206
|
-
write(request, "</div>");
|
|
1207
|
-
return blockingIds;
|
|
1208
|
-
}
|
|
1209
|
-
function flushSegmentAssets(request, segment) {
|
|
1210
|
-
const blockingIds = /* @__PURE__ */ new Set();
|
|
1211
|
-
collectSegmentAssets(request, segment, request.assetSink, blockingIds);
|
|
1212
|
-
return [...blockingIds];
|
|
1213
|
-
}
|
|
1214
|
-
function collectSegmentAssets(request, segment, sink, blockingIds) {
|
|
1215
|
-
if (segment.status !== "pending" && segment.status !== "rendering") flushAssetList(request, segment.assetResources, sink, blockingIds);
|
|
1216
|
-
for (const child of segment.children) collectSegmentAssets(request, child, sink, blockingIds);
|
|
1217
|
-
}
|
|
1218
|
-
function flushAssetList(request, resources, sink, blockingIds) {
|
|
1219
|
-
for (const resource of resources) {
|
|
1220
|
-
const id = request.assetRegistry.write(resource, sink);
|
|
1221
|
-
if (id !== null) blockingIds.add(id);
|
|
1222
|
-
}
|
|
1223
|
-
}
|
|
1224
|
-
function withAssetGate(request, blockingIds, call) {
|
|
1225
|
-
if (blockingIds.length === 0) return call;
|
|
1226
|
-
return `${RUNTIME_REF}.r([${blockingIds.map(jsString).join(",")}],()=>{${call}})`;
|
|
1227
|
-
}
|
|
1228
|
-
function flushClientRenderedBoundary(request, boundary) {
|
|
1229
|
-
if (boundary.id === null) return;
|
|
1230
|
-
writeRuntime(request);
|
|
1231
|
-
const boundaryRef = jsString(boundaryId(request, boundary.id));
|
|
1232
|
-
const digest = jsString(boundary.error?.digest ?? "");
|
|
1233
|
-
const message = jsString(boundary.error?.message ?? "");
|
|
1234
|
-
const runtime = RUNTIME_REF;
|
|
1235
|
-
writeScript(request, boundary.activityId === null ? `${runtime}.x(${boundaryRef},${digest},${message})` : `${runtime}.ax(${jsString(boundary.activityId)},${boundaryRef},${digest},${message})`);
|
|
1236
|
-
}
|
|
1237
|
-
function drainBoundaryQueue(request, queue, flush) {
|
|
1238
|
-
for (;;) {
|
|
1239
|
-
const first = queue.values().next();
|
|
1240
|
-
if (first.done === true) return;
|
|
1241
|
-
flush(request, first.value);
|
|
1242
|
-
queue.delete(first.value);
|
|
1243
|
-
flushWriteBuffer(request);
|
|
1244
|
-
}
|
|
1245
|
-
}
|
|
1246
1613
|
function enqueueUnique(queue, item) {
|
|
1247
1614
|
if (!queue.includes(item)) queue.push(item);
|
|
1248
1615
|
}
|
|
@@ -1265,72 +1632,35 @@ function stackForError(error, fallback) {
|
|
|
1265
1632
|
if (typeof error !== "object" && typeof error !== "function" || error === null) return fallback;
|
|
1266
1633
|
return errorStacks.get(error) ?? fallback;
|
|
1267
1634
|
}
|
|
1268
|
-
function writeRuntime(request) {
|
|
1269
|
-
writeRuntime$1(request, (chunk) => write(request, chunk));
|
|
1270
|
-
}
|
|
1271
|
-
function writeScript(request, code) {
|
|
1272
|
-
writeScript$1(request, `(__figSSR=>{${code}})(globalThis[${jsString(request.runtimeName)}])`, (chunk) => write(request, chunk));
|
|
1273
|
-
}
|
|
1274
1635
|
function createRuntimeName(identifierPrefix) {
|
|
1275
1636
|
const id = nextRuntimeId.toString(36);
|
|
1276
1637
|
nextRuntimeId += 1;
|
|
1277
1638
|
const prefix = identifierPrefix?.replace(/[^A-Za-z0-9_$]/g, "_") ?? "";
|
|
1278
1639
|
return prefix === "" ? `__figSSR_${id}` : `__figSSR_${prefix}_${id}`;
|
|
1279
1640
|
}
|
|
1280
|
-
function writeChunk(request, chunk, segment) {
|
|
1281
|
-
if (chunk !== documentHeadMarker) {
|
|
1282
|
-
write(request, chunk);
|
|
1283
|
-
return;
|
|
1284
|
-
}
|
|
1285
|
-
if (request.document === null) return;
|
|
1286
|
-
write(request, request.assetRegistry.headHtml(request.nonce));
|
|
1287
|
-
flushAssetList(request, segment.assetResources, request.assetSink, /* @__PURE__ */ new Set());
|
|
1288
|
-
}
|
|
1289
|
-
function write(request, chunk) {
|
|
1290
|
-
request.writeBuffer.push(chunk);
|
|
1291
|
-
}
|
|
1292
1641
|
function writeDocumentHeadMarker(segment) {
|
|
1293
1642
|
segment.lastPushedText = false;
|
|
1294
1643
|
segment.chunks.push(documentHeadMarker);
|
|
1295
1644
|
}
|
|
1296
1645
|
function consumePendingLeadingNewline(frame) {
|
|
1297
|
-
const pending = frame.
|
|
1298
|
-
frame.
|
|
1646
|
+
const pending = frame.pendingLeadingNewline;
|
|
1647
|
+
frame.pendingLeadingNewline = false;
|
|
1299
1648
|
return pending;
|
|
1300
1649
|
}
|
|
1301
1650
|
function leadingNewlineStrippedHost(type) {
|
|
1302
1651
|
return type === "pre" || type === "textarea";
|
|
1303
1652
|
}
|
|
1653
|
+
function writeLeadingNewlineText(text, segment) {
|
|
1654
|
+
writeText(text, { write(value) {
|
|
1655
|
+
segment.write({ value });
|
|
1656
|
+
} });
|
|
1657
|
+
}
|
|
1304
1658
|
function preserveParserStrippedLeadingNewline(text) {
|
|
1305
1659
|
return text.startsWith("\n") ? `\n${text}` : text;
|
|
1306
1660
|
}
|
|
1307
|
-
function cleanupAbortListener(request) {
|
|
1308
|
-
if (request.abortListener === null || request.abortSignal === null) return;
|
|
1309
|
-
request.abortSignal.removeEventListener("abort", request.abortListener);
|
|
1310
|
-
request.abortListener = null;
|
|
1311
|
-
request.abortSignal = null;
|
|
1312
|
-
}
|
|
1313
|
-
function flushWriteBuffer(request) {
|
|
1314
|
-
if (request.writeBuffer.length === 0 || request.controller === null) return;
|
|
1315
|
-
request.controller.enqueue(textEncoder.encode(request.writeBuffer.join("")));
|
|
1316
|
-
request.writeBuffer = [];
|
|
1317
|
-
}
|
|
1318
1661
|
function invalidDocumentShellError() {
|
|
1319
1662
|
return /* @__PURE__ */ new Error("renderToDocumentStream requires the root to render an <html> document with a <head>.");
|
|
1320
1663
|
}
|
|
1321
|
-
function ensureSegmentId(request, segment) {
|
|
1322
|
-
segment.id ??= request.nextSegmentId++;
|
|
1323
|
-
return segment.id;
|
|
1324
|
-
}
|
|
1325
|
-
function ensureBoundaryId(request, boundary) {
|
|
1326
|
-
boundary.id ??= request.nextBoundaryId++;
|
|
1327
|
-
return boundary.id;
|
|
1328
|
-
}
|
|
1329
|
-
function componentStack(stack) {
|
|
1330
|
-
const frames = [];
|
|
1331
|
-
for (let frame = stack; frame !== null; frame = frame.parent) frames.push(` at ${frame.name}`);
|
|
1332
|
-
return frames.length === 0 ? "" : `\n${frames.join("\n")}`;
|
|
1333
|
-
}
|
|
1334
1664
|
function throwIfAborted(signal) {
|
|
1335
1665
|
if (signal?.aborted === true) throw abortReason(signal.reason);
|
|
1336
1666
|
}
|
|
@@ -1371,7 +1701,9 @@ function renderToDocumentStream(node, options = {}) {
|
|
|
1371
1701
|
abort: (reason) => request.abort(reason),
|
|
1372
1702
|
allReady: request.allReady,
|
|
1373
1703
|
contentType: request.contentType,
|
|
1704
|
+
data: request.data,
|
|
1374
1705
|
getData: () => request.getData(),
|
|
1706
|
+
getPreloadHeader: (headerOptions) => request.getPreloadHeader(headerOptions),
|
|
1375
1707
|
shellReady: request.shellReady,
|
|
1376
1708
|
stream: request.stream
|
|
1377
1709
|
};
|
|
@@ -1424,6 +1756,6 @@ async function readStreamToString(stream) {
|
|
|
1424
1756
|
}
|
|
1425
1757
|
}
|
|
1426
1758
|
//#endregion
|
|
1427
|
-
export { createRenderTreeCollector,
|
|
1759
|
+
export { createRenderTreeCollector, prerender, renderToDocumentHtml, renderToDocumentStream, renderToHtml, renderToStream };
|
|
1428
1760
|
|
|
1429
1761
|
//# sourceMappingURL=index.js.map
|