@solidjs/web 2.0.0-rc.3 → 2.0.0-rc.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dev.cjs +398 -17
- package/dist/dev.js +396 -19
- package/dist/server.cjs +166 -38
- package/dist/server.js +165 -39
- package/dist/web.cjs +369 -17
- package/dist/web.js +367 -19
- package/frames/dist/client.cjs +41 -8
- package/frames/dist/client.dev.cjs +41 -8
- package/frames/dist/client.dev.js +41 -8
- package/frames/dist/client.js +41 -8
- package/frames/dist/server.cjs +432 -44
- package/frames/dist/server.js +432 -44
- package/package.json +2 -2
- package/serialization/dist/decode.cjs +4 -2
- package/serialization/dist/decode.js +4 -2
- package/serialization/dist/serialization.cjs +12 -8
- package/serialization/dist/serialization.js +12 -8
- package/serialization/types/index.d.ts +7 -0
- package/serialization/types/serializer-decode.d.ts +14 -1
- package/serialization/types/serializer.d.ts +7 -0
- package/serialization/types-cjs/index.d.cts +7 -0
- package/serialization/types-cjs/serializer-decode.d.cts +14 -1
- package/serialization/types-cjs/serializer.d.cts +7 -0
- package/server-functions/dist/client.cjs +271 -47
- package/server-functions/dist/client.js +264 -47
- package/server-functions/dist/server.cjs +872 -131
- package/server-functions/dist/server.dev.cjs +892 -131
- package/server-functions/dist/server.dev.js +884 -131
- package/server-functions/dist/server.js +864 -131
- package/types/client.d.ts +4 -2
- package/types/cookies.d.ts +6 -14
- package/types/frames/frame-client.d.ts +4 -0
- package/types/frames/serializer-decode.d.ts +14 -1
- package/types/frames/serializer.d.ts +7 -0
- package/types/index.d.ts +1 -0
- package/types/jsx.d.ts +11 -16
- package/types/patch-driver.d.ts +3 -0
- package/types/response.d.ts +20 -1
- package/types/serializer-decode.d.ts +14 -1
- package/types/serializer.d.ts +7 -0
- package/types/server-functions/client.d.ts +58 -7
- package/types/server-functions/flash.d.ts +9 -0
- package/types/server-functions/registry.d.ts +38 -1
- package/types/server-functions/server.d.ts +66 -14
- package/types/server-functions/shared.d.ts +122 -16
- package/types/server-mock.d.ts +17 -2
- package/types/server.d.ts +16 -2
- package/types-cjs/client.d.cts +4 -2
- package/types-cjs/cookies.d.cts +6 -14
- package/types-cjs/frames/frame-client.d.cts +4 -0
- package/types-cjs/frames/serializer-decode.d.cts +14 -1
- package/types-cjs/frames/serializer.d.cts +7 -0
- package/types-cjs/index.d.cts +1 -0
- package/types-cjs/jsx.d.cts +11 -16
- package/types-cjs/patch-driver.d.cts +3 -0
- package/types-cjs/response.d.cts +20 -1
- package/types-cjs/serializer-decode.d.cts +14 -1
- package/types-cjs/serializer.d.cts +7 -0
- package/types-cjs/server-functions/client.d.cts +58 -7
- package/types-cjs/server-functions/flash.d.cts +9 -0
- package/types-cjs/server-functions/registry.d.cts +38 -1
- package/types-cjs/server-functions/server.d.cts +66 -14
- package/types-cjs/server-functions/shared.d.cts +122 -16
- package/types-cjs/server-mock.d.cts +17 -2
- package/types-cjs/server.d.cts +16 -2
package/dist/server.cjs
CHANGED
|
@@ -151,13 +151,13 @@ function resolveSerializerPlugins(customPlugins) {
|
|
|
151
151
|
seroval.Feature.RegExp;
|
|
152
152
|
|
|
153
153
|
const DEFAULT_DISABLED_FEATURES = seroval.Feature.AggregateError | seroval.Feature.BigIntTypedArray;
|
|
154
|
-
const serializeOnlyDisabledFeatures =
|
|
154
|
+
const serializeOnlyDisabledFeatures = serializeErrorStacks => (serializeErrorStacks === undefined ? process.env.NODE_ENV === "development" : serializeErrorStacks) ? 0 : seroval.Feature.ErrorPrototypeStack;
|
|
155
155
|
const HYDRATION_GLOBAL = "_$HY.r";
|
|
156
156
|
function createSerializer(options) {
|
|
157
157
|
return new seroval.Serializer({
|
|
158
158
|
...options,
|
|
159
159
|
plugins: resolveSerializerPlugins(options.plugins),
|
|
160
|
-
disabledFeatures: (options.disabledFeatures === undefined ? DEFAULT_DISABLED_FEATURES : options.disabledFeatures) | serializeOnlyDisabledFeatures()
|
|
160
|
+
disabledFeatures: (options.disabledFeatures === undefined ? DEFAULT_DISABLED_FEATURES : options.disabledFeatures) | serializeOnlyDisabledFeatures(options.serializeErrorStacks)
|
|
161
161
|
});
|
|
162
162
|
}
|
|
163
163
|
function createHydrationSerializer({
|
|
@@ -214,6 +214,7 @@ function isSafeError(value) {
|
|
|
214
214
|
return !!(value && (typeof value === "object" || typeof value === "function") && value[SAFE_ERROR]);
|
|
215
215
|
}
|
|
216
216
|
const REVALIDATE_HEADER = "X-Revalidate";
|
|
217
|
+
const RESPONSE_HEADER_VALUE_LIMIT = 4096;
|
|
217
218
|
function initWithRevalidate(init = {}) {
|
|
218
219
|
const resolved = typeof init === "number" ? {
|
|
219
220
|
status: init
|
|
@@ -234,7 +235,13 @@ function initWithRevalidate(init = {}) {
|
|
|
234
235
|
} else {
|
|
235
236
|
headers = new Headers(responseInit.headers);
|
|
236
237
|
}
|
|
237
|
-
revalidate !== undefined
|
|
238
|
+
if (revalidate !== undefined) {
|
|
239
|
+
const keys = revalidate.toString();
|
|
240
|
+
if (keys.length > RESPONSE_HEADER_VALUE_LIMIT) {
|
|
241
|
+
throw new TypeError(`revalidate names ${keys.length} characters of cache keys; past ` + `${RESPONSE_HEADER_VALUE_LIMIT} the ${REVALIDATE_HEADER} header would overflow ` + `receivers (an 8 KiB proxy buffer holds the whole header block) and the response ` + `dies at the socket after the mutation committed. Split the invalidation across ` + `calls or use coarser keys — a dropped key would be a silently stale cache, so ` + `the runtime refuses rather than trims.`);
|
|
242
|
+
}
|
|
243
|
+
headers.set(REVALIDATE_HEADER, keys);
|
|
244
|
+
}
|
|
238
245
|
return {
|
|
239
246
|
responseInit,
|
|
240
247
|
headers
|
|
@@ -251,7 +258,13 @@ function redirect(url, init = 302) {
|
|
|
251
258
|
if (responseInit.status === undefined) {
|
|
252
259
|
responseInit.status = 302;
|
|
253
260
|
}
|
|
254
|
-
|
|
261
|
+
const target = typeof url === "string" ? url : url[HREF];
|
|
262
|
+
const location = typeof target === "string" ? target : String(url);
|
|
263
|
+
const encoded = location.replace(/[^\x00-\x7f]/gu, encodeURIComponent);
|
|
264
|
+
if (encoded.length > RESPONSE_HEADER_VALUE_LIMIT) {
|
|
265
|
+
throw new TypeError(`redirect() target is ${encoded.length} characters; past ` + `${RESPONSE_HEADER_VALUE_LIMIT} the Location header (and the scripted transport's ` + `redirect header) would overflow receivers and the response dies at the socket. ` + `A target this size is usually unbounded input echoed into the url — carry the ` + `state server-side instead. Refused rather than trimmed: a cut target is a ` + `different address.`);
|
|
266
|
+
}
|
|
267
|
+
headers.set("Location", encoded);
|
|
255
268
|
return new Response(null, {
|
|
256
269
|
...responseInit,
|
|
257
270
|
headers
|
|
@@ -267,11 +280,18 @@ function reload(init = {}) {
|
|
|
267
280
|
headers
|
|
268
281
|
});
|
|
269
282
|
}
|
|
283
|
+
const NULL_BODY_STATUSES = new Set([204, 205, 304]);
|
|
270
284
|
function respond(value, init = {}) {
|
|
271
285
|
const {
|
|
272
286
|
responseInit,
|
|
273
287
|
headers
|
|
274
288
|
} = initWithRevalidate(init);
|
|
289
|
+
if (NULL_BODY_STATUSES.has(responseInit.status)) {
|
|
290
|
+
return new ResponseEnvelope(new Response(null, {
|
|
291
|
+
...responseInit,
|
|
292
|
+
headers
|
|
293
|
+
}), value);
|
|
294
|
+
}
|
|
275
295
|
headers.set("Content-Type", "application/json");
|
|
276
296
|
return new ResponseEnvelope(new Response(JSON.stringify(value), {
|
|
277
297
|
...responseInit,
|
|
@@ -322,6 +342,7 @@ function serializeCookie(name, value, options = {}) {
|
|
|
322
342
|
if (options.expires) cookie += `; Expires=${options.expires.toUTCString()}`;
|
|
323
343
|
if (options.httpOnly) cookie += "; HttpOnly";
|
|
324
344
|
if (options.secure) cookie += "; Secure";
|
|
345
|
+
if (options.partitioned) cookie += "; Partitioned";
|
|
325
346
|
if (options.sameSite) {
|
|
326
347
|
const sameSite = options.sameSite.toLowerCase();
|
|
327
348
|
cookie += `; SameSite=${sameSite === "none" ? "None" : sameSite === "strict" ? "Strict" : "Lax"}`;
|
|
@@ -339,6 +360,7 @@ function clearFlashCookie() {
|
|
|
339
360
|
|
|
340
361
|
const ERROR_HEADER = "X-Server-Function-Error";
|
|
341
362
|
const BODY_FORMAT_HEADER = "X-Server-Function-Format";
|
|
363
|
+
const REDIRECT_HEADER = "X-Server-Function-Redirect";
|
|
342
364
|
const SINGLE_FLIGHT_HEADER = "X-Single-Flight";
|
|
343
365
|
|
|
344
366
|
const HEAD_ELIGIBLE_TAGS = new Set(["title", "meta", "link", "style", "script", "base"]);
|
|
@@ -377,7 +399,8 @@ function resourceIdentity(tag, props) {
|
|
|
377
399
|
let id = "res:" + tag + ":" + (props.rel || "") + ":" + (props.href || props.src || "");
|
|
378
400
|
for (let i = 0; i < RESOURCE_QUALIFIERS.length; i++) {
|
|
379
401
|
const q = RESOURCE_QUALIFIERS[i];
|
|
380
|
-
|
|
402
|
+
const value = props[q];
|
|
403
|
+
if (value != null) id += ":" + q + "=" + (value === true ? "" : value);
|
|
381
404
|
}
|
|
382
405
|
return id;
|
|
383
406
|
}
|
|
@@ -439,6 +462,7 @@ function resolveAssets(moduleUrl, manifest) {
|
|
|
439
462
|
if (!entry) return null;
|
|
440
463
|
const css = [];
|
|
441
464
|
const js = [];
|
|
465
|
+
let preloads;
|
|
442
466
|
const visited = new Set();
|
|
443
467
|
const walk = key => {
|
|
444
468
|
if (visited.has(key)) return;
|
|
@@ -447,13 +471,26 @@ function resolveAssets(moduleUrl, manifest) {
|
|
|
447
471
|
if (!e) return;
|
|
448
472
|
js.push(joinAssetPath(base, e.file));
|
|
449
473
|
if (e.css) for (let i = 0; i < e.css.length; i++) css.push(joinAssetPath(base, e.css[i]));
|
|
474
|
+
if (e.preloads) {
|
|
475
|
+
for (let i = 0; i < e.preloads.length; i++) {
|
|
476
|
+
const link = e.preloads[i];
|
|
477
|
+
if (!link || typeof link.href !== "string" || !link.href) continue;
|
|
478
|
+
if (!preloads) preloads = [];
|
|
479
|
+
preloads.push({
|
|
480
|
+
...link,
|
|
481
|
+
href: joinAssetPath(base, link.href)
|
|
482
|
+
});
|
|
483
|
+
}
|
|
484
|
+
}
|
|
450
485
|
if (e.imports) for (let i = 0; i < e.imports.length; i++) walk(e.imports[i]);
|
|
451
486
|
};
|
|
452
487
|
walk(moduleUrl);
|
|
453
|
-
|
|
488
|
+
const assets = {
|
|
454
489
|
js,
|
|
455
490
|
css
|
|
456
491
|
};
|
|
492
|
+
if (preloads) assets.preloads = preloads;
|
|
493
|
+
return assets;
|
|
457
494
|
}
|
|
458
495
|
function registerEntryAssets(manifest) {
|
|
459
496
|
if (!manifest || typeof manifest === "function" || typeof manifest.resolve === "function") return;
|
|
@@ -463,6 +500,7 @@ function registerEntryAssets(manifest) {
|
|
|
463
500
|
if (manifest[key].isEntry) {
|
|
464
501
|
const assets = resolveAssets(key, manifest);
|
|
465
502
|
if (assets) {
|
|
503
|
+
if (assets.preloads) for (let i = 0; i < assets.preloads.length; i++) ctx.registerAsset("preload", assets.preloads[i]);
|
|
466
504
|
for (let i = 0; i < assets.css.length; i++) ctx.registerAsset("style", assets.css[i]);
|
|
467
505
|
for (let i = 1; i < assets.js.length; i++) ctx.registerAsset("module", assets.js[i]);
|
|
468
506
|
}
|
|
@@ -481,6 +519,7 @@ function createAssetTracking() {
|
|
|
481
519
|
boundaryStyles,
|
|
482
520
|
emittedAssets,
|
|
483
521
|
inlineStyles,
|
|
522
|
+
preloadLinks: null,
|
|
484
523
|
registerInlineStyle(desc) {
|
|
485
524
|
let entry = inlineStyles.get(desc.id);
|
|
486
525
|
if (!entry) {
|
|
@@ -572,6 +611,56 @@ function isCssUrl(url) {
|
|
|
572
611
|
const q = url.search(/[?#]/);
|
|
573
612
|
return (q === -1 ? url : url.slice(0, q)).endsWith(".css");
|
|
574
613
|
}
|
|
614
|
+
const PRELOAD_LINK_ATTRIBUTES = ["type", "crossorigin", "integrity", "referrerpolicy", "fetchpriority", "media"];
|
|
615
|
+
function registerPreloadLink(tracking, headRegistry, link, nonce) {
|
|
616
|
+
if (!link || typeof link !== "object" || typeof link.href !== "string" || !link.href) {
|
|
617
|
+
return null;
|
|
618
|
+
}
|
|
619
|
+
if (typeof link.as !== "string") {
|
|
620
|
+
return null;
|
|
621
|
+
}
|
|
622
|
+
const as = asciiLowerCase(link.as);
|
|
623
|
+
let destination = null;
|
|
624
|
+
switch (as) {
|
|
625
|
+
case "script":
|
|
626
|
+
case "style":
|
|
627
|
+
destination = as;
|
|
628
|
+
break;
|
|
629
|
+
case "fetch":
|
|
630
|
+
case "font":
|
|
631
|
+
case "image":
|
|
632
|
+
case "track":
|
|
633
|
+
break;
|
|
634
|
+
default:
|
|
635
|
+
return null;
|
|
636
|
+
}
|
|
637
|
+
const props = {
|
|
638
|
+
rel: "preload",
|
|
639
|
+
href: link.href,
|
|
640
|
+
as
|
|
641
|
+
};
|
|
642
|
+
for (let i = 0; i < PRELOAD_LINK_ATTRIBUTES.length; i++) {
|
|
643
|
+
const name = PRELOAD_LINK_ATTRIBUTES[i];
|
|
644
|
+
const value = link[name];
|
|
645
|
+
if (value == null || value === false) continue;
|
|
646
|
+
props[name] = value === true ? "" : String(value);
|
|
647
|
+
}
|
|
648
|
+
const identity = resourceIdentity("link", props);
|
|
649
|
+
if (headRegistry.resources.has(identity)) return null;
|
|
650
|
+
const attrs = headAttrRecord(props);
|
|
651
|
+
const nonceValue = destination && nonce && nonce[destination];
|
|
652
|
+
if (typeof nonceValue === "string" && nonceValue) attrs.nonce = nonceValue;
|
|
653
|
+
const entry = {
|
|
654
|
+
href: props.href,
|
|
655
|
+
attrs,
|
|
656
|
+
attrHtml: renderHeadAttrHtml(props) + nonceAttr(nonce, destination)
|
|
657
|
+
};
|
|
658
|
+
headRegistry.resources.add(identity);
|
|
659
|
+
let links = tracking.preloadLinks;
|
|
660
|
+
if (!links) tracking.preloadLinks = links = [];
|
|
661
|
+
links.push(entry);
|
|
662
|
+
return entry;
|
|
663
|
+
}
|
|
575
664
|
function createHeadRegistry() {
|
|
576
665
|
return {
|
|
577
666
|
pending: [],
|
|
@@ -1048,6 +1137,10 @@ function renderToString(code, options = {}) {
|
|
|
1048
1137
|
serializer.write(id, p);
|
|
1049
1138
|
},
|
|
1050
1139
|
registerAsset(type, value) {
|
|
1140
|
+
if (type === "preload") {
|
|
1141
|
+
registerPreloadLink(tracking, headRegistry, value, nonce);
|
|
1142
|
+
return;
|
|
1143
|
+
}
|
|
1051
1144
|
if (type === "inline-style") {
|
|
1052
1145
|
tracking.registerInlineStyle(value);
|
|
1053
1146
|
return;
|
|
@@ -1075,7 +1168,7 @@ function renderToString(code, options = {}) {
|
|
|
1075
1168
|
solidJs.sharedConfig.context.noHydrate = true;
|
|
1076
1169
|
serializer.close();
|
|
1077
1170
|
const head = renderShellHead(headRegistry, nonce, null, noScripts);
|
|
1078
|
-
return assembleDocument(resolveSSRSelectValues(html), tracking.emittedAssets, tracking.inlineStyles, scripts.length ? scripts : "", nonce, head, onHead);
|
|
1171
|
+
return assembleDocument(resolveSSRSelectValues(html), tracking.emittedAssets, tracking.preloadLinks, tracking.inlineStyles, scripts.length ? scripts : "", nonce, head, onHead);
|
|
1079
1172
|
}
|
|
1080
1173
|
function renderToStream(code, options = {}) {
|
|
1081
1174
|
let {
|
|
@@ -1229,6 +1322,8 @@ function renderToStream(code, options = {}) {
|
|
|
1229
1322
|
asset(type, value) {
|
|
1230
1323
|
if (type === "module") {
|
|
1231
1324
|
buffer.write(`<link rel="modulepreload" href="${value}"${nonceAttr(nonce, "script")}>`);
|
|
1325
|
+
} else if (type === "preload") {
|
|
1326
|
+
buffer.write(`<link${value.attrHtml}>`);
|
|
1232
1327
|
} else if (type === "inline-style") {
|
|
1233
1328
|
buffer.write(renderInlineStyle(value, nonce));
|
|
1234
1329
|
} else if (type === "head-tag") {
|
|
@@ -1236,7 +1331,7 @@ function renderToStream(code, options = {}) {
|
|
|
1236
1331
|
}
|
|
1237
1332
|
},
|
|
1238
1333
|
shell(shellHtml, meta) {
|
|
1239
|
-
buffer.write(assembleDocument(shellHtml, meta.preloads, meta.inlineStyles, meta.tasks.length ? meta.tasks : "", nonce, meta.head, onHead));
|
|
1334
|
+
buffer.write(assembleDocument(shellHtml, meta.preloads, meta.preloadLinks, meta.inlineStyles, meta.tasks.length ? meta.tasks : "", nonce, meta.head, onHead));
|
|
1240
1335
|
},
|
|
1241
1336
|
...options.sink
|
|
1242
1337
|
};
|
|
@@ -1269,6 +1364,29 @@ function renderToStream(code, options = {}) {
|
|
|
1269
1364
|
}
|
|
1270
1365
|
};
|
|
1271
1366
|
const registry = new Map();
|
|
1367
|
+
const pendingSerialized = new Map();
|
|
1368
|
+
const trackSerialized = (id, p) => {
|
|
1369
|
+
let settle;
|
|
1370
|
+
const raced = Promise.race([p, new Promise(r => settle = r)]);
|
|
1371
|
+
pendingSerialized.set(id, settle);
|
|
1372
|
+
const drop = () => pendingSerialized.delete(id);
|
|
1373
|
+
p.then(drop, drop);
|
|
1374
|
+
return raced;
|
|
1375
|
+
};
|
|
1376
|
+
const abandonSubtree = key => {
|
|
1377
|
+
for (const [k, entry] of registry) {
|
|
1378
|
+
if (k.length > key.length && k.startsWith(key)) {
|
|
1379
|
+
registry.delete(k);
|
|
1380
|
+
entry.resolve();
|
|
1381
|
+
}
|
|
1382
|
+
}
|
|
1383
|
+
for (const [id, settle] of pendingSerialized) {
|
|
1384
|
+
if (id.startsWith(key)) {
|
|
1385
|
+
pendingSerialized.delete(id);
|
|
1386
|
+
settle();
|
|
1387
|
+
}
|
|
1388
|
+
}
|
|
1389
|
+
};
|
|
1272
1390
|
const writeTasks = () => {
|
|
1273
1391
|
if (tasks.length && !completed && firstFlushed) {
|
|
1274
1392
|
buffer.write(`<script${nonceAttr(nonce, "script")}>${tasks}</script>`);
|
|
@@ -1339,6 +1457,11 @@ function renderToStream(code, options = {}) {
|
|
|
1339
1457
|
}, nonce, tags);
|
|
1340
1458
|
},
|
|
1341
1459
|
registerAsset(type, value) {
|
|
1460
|
+
if (type === "preload") {
|
|
1461
|
+
const entry = registerPreloadLink(tracking, headRegistry, value, nonce);
|
|
1462
|
+
if (entry && firstFlushed) sink.asset("preload", entry);
|
|
1463
|
+
return;
|
|
1464
|
+
}
|
|
1342
1465
|
if (type === "inline-style") {
|
|
1343
1466
|
const entry = tracking.registerInlineStyle(value);
|
|
1344
1467
|
if (firstFlushed && !tracking.currentBoundaryId && !entry.emitted) {
|
|
@@ -1383,13 +1506,14 @@ function renderToStream(code, options = {}) {
|
|
|
1383
1506
|
},
|
|
1384
1507
|
serialize(id, p, deferStream) {
|
|
1385
1508
|
if (solidJs.sharedConfig.context.noHydrate) return;
|
|
1386
|
-
if (
|
|
1387
|
-
if (deferStream) {
|
|
1509
|
+
if (p && typeof p === "object" && typeof p.then === "function") {
|
|
1510
|
+
if (!firstFlushed && deferStream) {
|
|
1388
1511
|
blockingPromises.add(p);
|
|
1389
1512
|
p.then(d => serializer.write(id, d)).catch(e => serializer.write(id, e));
|
|
1390
1513
|
return;
|
|
1391
1514
|
}
|
|
1392
|
-
|
|
1515
|
+
p = trackSerialized(id, p);
|
|
1516
|
+
if (!firstFlushed && canBatchStubs && !shellCompleted) {
|
|
1393
1517
|
(stubBatch ||= new Map()).set(id, p);
|
|
1394
1518
|
return;
|
|
1395
1519
|
}
|
|
@@ -1434,6 +1558,7 @@ function renderToStream(code, options = {}) {
|
|
|
1434
1558
|
if (registry.has(key)) {
|
|
1435
1559
|
const item = registry.get(key);
|
|
1436
1560
|
registry.delete(key);
|
|
1561
|
+
if (error) abandonSubtree(key);
|
|
1437
1562
|
if (item.children) {
|
|
1438
1563
|
for (const k in item.children) {
|
|
1439
1564
|
value = replacePlaceholder(value, k, item.children[k]);
|
|
@@ -1558,6 +1683,7 @@ function renderToStream(code, options = {}) {
|
|
|
1558
1683
|
const head = renderShellHead(headRegistry, nonce, k => registry.has(k), noScripts);
|
|
1559
1684
|
sink.shell(resolveSSRSelectValues(html), {
|
|
1560
1685
|
preloads: tracking.emittedAssets,
|
|
1686
|
+
preloadLinks: tracking.preloadLinks,
|
|
1561
1687
|
inlineStyles: tracking.inlineStyles,
|
|
1562
1688
|
tasks,
|
|
1563
1689
|
head
|
|
@@ -2479,7 +2605,7 @@ function ssrClaim(map) {
|
|
|
2479
2605
|
function decodeSSREntities(s) {
|
|
2480
2606
|
return s.indexOf("&") < 0 ? s : s.replace(/"/g, '"').replace(/</g, "<").replace(/&/g, "&");
|
|
2481
2607
|
}
|
|
2482
|
-
const SELECT_VALUE_ATTR = /\svalue
|
|
2608
|
+
const SELECT_VALUE_ATTR = /\svalue(?:="([^"]*)")?(?=[\s>]|$)/;
|
|
2483
2609
|
function tagEnd(html, i) {
|
|
2484
2610
|
for (let j = i + 1; j < html.length; j++) {
|
|
2485
2611
|
const c = html.charCodeAt(j);
|
|
@@ -2531,7 +2657,7 @@ function resolveSSRSelectValues(html) {
|
|
|
2531
2657
|
cand = html.indexOf("<select", e0 + 1);
|
|
2532
2658
|
continue;
|
|
2533
2659
|
}
|
|
2534
|
-
const bound = decodeSSREntities(m[1]);
|
|
2660
|
+
const bound = decodeSSREntities(m[1] ?? "");
|
|
2535
2661
|
const sel = {
|
|
2536
2662
|
values: /\smultiple(?=[\s>=])/.test(open) ? bound.split(",") : [bound],
|
|
2537
2663
|
strip: cand + m.index,
|
|
@@ -2568,7 +2694,7 @@ function resolveSSRSelectValues(html) {
|
|
|
2568
2694
|
const attrs = html.slice(i + 7, e);
|
|
2569
2695
|
if (/\sselected(?=[\s=]|$)/.test(attrs)) sel.defaulted = true;else {
|
|
2570
2696
|
const vm = SELECT_VALUE_ATTR.exec(attrs);
|
|
2571
|
-
const value = vm ? decodeSSREntities(vm[1]) : decodeSSREntities(optionText(html, e + 1)).replace(/\s+/g, " ").trim();
|
|
2697
|
+
const value = vm ? decodeSSREntities(vm[1] ?? "") : decodeSSREntities(optionText(html, e + 1)).replace(/\s+/g, " ").trim();
|
|
2572
2698
|
if (sel.values.includes(value)) sel.marks.push(e);
|
|
2573
2699
|
}
|
|
2574
2700
|
}
|
|
@@ -2704,12 +2830,12 @@ function allSettled(promises) {
|
|
|
2704
2830
|
return;
|
|
2705
2831
|
});
|
|
2706
2832
|
}
|
|
2707
|
-
function assembleDocument(html, emittedAssets, inlineStyles, scripts, nonce, headTags, onHead) {
|
|
2833
|
+
function assembleDocument(html, emittedAssets, preloadLinks, inlineStyles, scripts, nonce, headTags, onHead) {
|
|
2708
2834
|
const scriptTag = scripts ? `<script${nonceAttr(nonce, "script")}>${scripts}</script>` : "";
|
|
2709
2835
|
const title = headTags ? headTags.title : null;
|
|
2710
2836
|
let headTagsHtml = headTags ? headTags.html : "";
|
|
2711
2837
|
const headPrelude = headTags ? headTags.prelude : "";
|
|
2712
|
-
if (!onHead && title == null && !headTagsHtml && !headPrelude && !(emittedAssets && emittedAssets.size) && !(inlineStyles && inlineStyles.size)) {
|
|
2838
|
+
if (!onHead && title == null && !headTagsHtml && !headPrelude && !(emittedAssets && emittedAssets.size) && !preloadLinks && !(inlineStyles && inlineStyles.size)) {
|
|
2713
2839
|
if (!scriptTag) return html;
|
|
2714
2840
|
const xs = html.indexOf("<!--xs-->");
|
|
2715
2841
|
return xs === -1 ? html + scriptTag : html.slice(0, xs) + scriptTag + html.slice(xs);
|
|
@@ -2728,7 +2854,7 @@ function assembleDocument(html, emittedAssets, inlineStyles, scripts, nonce, hea
|
|
|
2728
2854
|
if (title != null) {
|
|
2729
2855
|
titleHtml = headTags.noScripts ? `<title data-dh="title">${escape(title)}</title>` : `<script${nonceAttr(nonce, "script")}>(function(x,t){(t=document.querySelector("title"))?(t.hasAttribute("data-dh")||t.setAttribute("data-dhf",t.textContent),t.textContent=x):(document.title=x,t=document.querySelector("title"));t&&t.setAttribute("data-dh","title")})(${JSON.stringify(title).replace(/</g, "\\u003C")})</script>`;
|
|
2730
2856
|
}
|
|
2731
|
-
onHead(headPrelude + headTagsHtml + titleHtml + renderHeadAssets(emittedAssets, inlineStyles, nonce));
|
|
2857
|
+
onHead(headPrelude + headTagsHtml + titleHtml + renderHeadAssets(emittedAssets, preloadLinks, inlineStyles, nonce));
|
|
2732
2858
|
}
|
|
2733
2859
|
if (!scriptTag) return html;
|
|
2734
2860
|
const xs = html.indexOf("<!--xs-->");
|
|
@@ -2748,13 +2874,13 @@ function assembleDocument(html, emittedAssets, inlineStyles, scripts, nonce, hea
|
|
|
2748
2874
|
headTagsHtml = `<title data-dh="title">${winner}</title>` + headTagsHtml;
|
|
2749
2875
|
}
|
|
2750
2876
|
}
|
|
2751
|
-
const head = headTagsHtml + renderHeadAssets(emittedAssets, inlineStyles, nonce);
|
|
2877
|
+
const head = headTagsHtml + renderHeadAssets(emittedAssets, preloadLinks, inlineStyles, nonce);
|
|
2752
2878
|
if (!scriptTag) return html.slice(0, headIdx) + head + html.slice(headIdx);
|
|
2753
2879
|
const xsIdx = html.indexOf("<!--xs-->");
|
|
2754
2880
|
if (xsIdx === -1) return html.slice(0, headIdx) + head + html.slice(headIdx) + scriptTag;
|
|
2755
2881
|
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);
|
|
2756
2882
|
}
|
|
2757
|
-
function renderHeadAssets(emittedAssets, inlineStyles, nonce) {
|
|
2883
|
+
function renderHeadAssets(emittedAssets, preloadLinks, inlineStyles, nonce) {
|
|
2758
2884
|
let head = "";
|
|
2759
2885
|
const styleAttr = nonceAttr(nonce, "style");
|
|
2760
2886
|
const scriptAttr = nonceAttr(nonce, "script");
|
|
@@ -2763,6 +2889,9 @@ function renderHeadAssets(emittedAssets, inlineStyles, nonce) {
|
|
|
2763
2889
|
head += isCssUrl(url) ? `<link rel="stylesheet" href="${url}"${styleAttr}>` : `<link rel="modulepreload" href="${url}"${scriptAttr}>`;
|
|
2764
2890
|
}
|
|
2765
2891
|
}
|
|
2892
|
+
if (preloadLinks) {
|
|
2893
|
+
for (const entry of preloadLinks) head += `<link${entry.attrHtml}>`;
|
|
2894
|
+
}
|
|
2766
2895
|
if (inlineStyles && inlineStyles.size) {
|
|
2767
2896
|
for (const entry of inlineStyles.values()) {
|
|
2768
2897
|
if (entry.emitted) continue;
|
|
@@ -3027,7 +3156,7 @@ function copyInitHeaders(init) {
|
|
|
3027
3156
|
for (const cookie of init.getSetCookie()) headers.append("Set-Cookie", cookie);
|
|
3028
3157
|
return headers;
|
|
3029
3158
|
}
|
|
3030
|
-
const STUB_GAP_FILL_EXCLUDED = /*#__PURE__*/new Set([ERROR_HEADER, BODY_FORMAT_HEADER, SINGLE_FLIGHT_HEADER, REVALIDATE_HEADER, "Location"].map(header => header.toLowerCase()));
|
|
3159
|
+
const STUB_GAP_FILL_EXCLUDED = /*#__PURE__*/new Set([ERROR_HEADER, BODY_FORMAT_HEADER, SINGLE_FLIGHT_HEADER, REVALIDATE_HEADER, REDIRECT_HEADER, "Location"].map(header => header.toLowerCase()));
|
|
3031
3160
|
function fillsStubGap(key, headers, response) {
|
|
3032
3161
|
if (key === "set-cookie" || STUB_GAP_FILL_EXCLUDED.has(key)) return false;
|
|
3033
3162
|
if (response.body === null && (key === "content-type" || key === "content-length")) return false;
|
|
@@ -3043,24 +3172,16 @@ function commitEventResponse(response, event = getRequestEvent()) {
|
|
|
3043
3172
|
if (fillsStubGap(key, response.headers, response)) hasGaps = true;
|
|
3044
3173
|
});
|
|
3045
3174
|
if (!cookies.length && !hasGaps) return response;
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
|
|
3049
|
-
|
|
3050
|
-
|
|
3051
|
-
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
if (fillsStubGap(key, headers, response)) headers.set(key, value);
|
|
3057
|
-
});
|
|
3058
|
-
return new Response(response.body, {
|
|
3059
|
-
status: response.status,
|
|
3060
|
-
statusText: response.statusText,
|
|
3061
|
-
headers
|
|
3062
|
-
});
|
|
3063
|
-
}
|
|
3175
|
+
const headers = copyInitHeaders(response.headers);
|
|
3176
|
+
for (const cookie of cookies) headers.append("Set-Cookie", cookie);
|
|
3177
|
+
stub.headers.forEach((value, key) => {
|
|
3178
|
+
if (fillsStubGap(key, headers, response)) headers.set(key, value);
|
|
3179
|
+
});
|
|
3180
|
+
return new Response(response.body, {
|
|
3181
|
+
status: response.status,
|
|
3182
|
+
statusText: response.statusText,
|
|
3183
|
+
headers
|
|
3184
|
+
});
|
|
3064
3185
|
}
|
|
3065
3186
|
function deriveHead(stub, responseInit = {}) {
|
|
3066
3187
|
const headers = mergeStubHeaders(copyInitHeaders(responseInit.headers), stub);
|
|
@@ -3226,6 +3347,11 @@ function registerClientOnlyPreload(moduleUrl) {
|
|
|
3226
3347
|
const css = assets.css[i];
|
|
3227
3348
|
if (typeof css === "string") registerAsset("style", css);else registerAsset("inline-style", css);
|
|
3228
3349
|
}
|
|
3350
|
+
if (assets.preloads) {
|
|
3351
|
+
for (let i = 0; i < assets.preloads.length; i++) {
|
|
3352
|
+
registerAsset("preload", assets.preloads[i]);
|
|
3353
|
+
}
|
|
3354
|
+
}
|
|
3229
3355
|
for (let i = 0; i < assets.js.length; i++) registerAsset("module", assets.js[i]);
|
|
3230
3356
|
};
|
|
3231
3357
|
const assets = resolve(moduleUrl);
|
|
@@ -3404,8 +3530,10 @@ exports.Dynamic = Dynamic;
|
|
|
3404
3530
|
exports.HREF = HREF;
|
|
3405
3531
|
exports.HydrationScript = HydrationScript;
|
|
3406
3532
|
exports.MathMLElements = MathMLElements;
|
|
3533
|
+
exports.NULL_BODY_STATUSES = NULL_BODY_STATUSES;
|
|
3407
3534
|
exports.Namespaces = Namespaces;
|
|
3408
3535
|
exports.Portal = Portal;
|
|
3536
|
+
exports.RESPONSE_HEADER_VALUE_LIMIT = RESPONSE_HEADER_VALUE_LIMIT;
|
|
3409
3537
|
exports.REVALIDATE_HEADER = REVALIDATE_HEADER;
|
|
3410
3538
|
exports.RawTextElements = RawTextElements;
|
|
3411
3539
|
exports.RequestContext = RequestContext;
|