@solidjs/web 2.0.0-rc.4 → 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 +52 -7
- package/dist/dev.js +51 -8
- package/dist/server.cjs +162 -35
- package/dist/server.js +161 -36
- package/dist/web.cjs +32 -7
- package/dist/web.js +31 -8
- 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 +150 -33
- package/server-functions/dist/client.js +147 -34
- package/server-functions/dist/server.cjs +731 -118
- package/server-functions/dist/server.dev.cjs +751 -118
- package/server-functions/dist/server.dev.js +747 -119
- package/server-functions/dist/server.js +727 -119
- 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/jsx.d.ts +11 -16
- package/types/response.d.ts +11 -0
- package/types/serializer-decode.d.ts +14 -1
- package/types/serializer.d.ts +7 -0
- package/types/server-functions/client.d.ts +22 -2
- package/types/server-functions/flash.d.ts +9 -0
- package/types/server-functions/server.d.ts +58 -9
- package/types/server-functions/shared.d.ts +77 -14
- package/types/server-mock.d.ts +17 -2
- package/types/server.d.ts +16 -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/jsx.d.cts +11 -16
- package/types-cjs/response.d.cts +11 -0
- 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 +22 -2
- package/types-cjs/server-functions/flash.d.cts +9 -0
- package/types-cjs/server-functions/server.d.cts +58 -9
- package/types-cjs/server-functions/shared.d.cts +77 -14
- package/types-cjs/server-mock.d.cts +17 -2
- package/types-cjs/server.d.cts +16 -2
package/dist/server.js
CHANGED
|
@@ -150,13 +150,13 @@ function resolveSerializerPlugins(customPlugins) {
|
|
|
150
150
|
Feature.RegExp;
|
|
151
151
|
|
|
152
152
|
const DEFAULT_DISABLED_FEATURES = Feature.AggregateError | Feature.BigIntTypedArray;
|
|
153
|
-
const serializeOnlyDisabledFeatures =
|
|
153
|
+
const serializeOnlyDisabledFeatures = serializeErrorStacks => (serializeErrorStacks === undefined ? process.env.NODE_ENV === "development" : serializeErrorStacks) ? 0 : Feature.ErrorPrototypeStack;
|
|
154
154
|
const HYDRATION_GLOBAL = "_$HY.r";
|
|
155
155
|
function createSerializer(options) {
|
|
156
156
|
return new Serializer({
|
|
157
157
|
...options,
|
|
158
158
|
plugins: resolveSerializerPlugins(options.plugins),
|
|
159
|
-
disabledFeatures: (options.disabledFeatures === undefined ? DEFAULT_DISABLED_FEATURES : options.disabledFeatures) | serializeOnlyDisabledFeatures()
|
|
159
|
+
disabledFeatures: (options.disabledFeatures === undefined ? DEFAULT_DISABLED_FEATURES : options.disabledFeatures) | serializeOnlyDisabledFeatures(options.serializeErrorStacks)
|
|
160
160
|
});
|
|
161
161
|
}
|
|
162
162
|
function createHydrationSerializer({
|
|
@@ -213,6 +213,7 @@ function isSafeError(value) {
|
|
|
213
213
|
return !!(value && (typeof value === "object" || typeof value === "function") && value[SAFE_ERROR]);
|
|
214
214
|
}
|
|
215
215
|
const REVALIDATE_HEADER = "X-Revalidate";
|
|
216
|
+
const RESPONSE_HEADER_VALUE_LIMIT = 4096;
|
|
216
217
|
function initWithRevalidate(init = {}) {
|
|
217
218
|
const resolved = typeof init === "number" ? {
|
|
218
219
|
status: init
|
|
@@ -233,7 +234,13 @@ function initWithRevalidate(init = {}) {
|
|
|
233
234
|
} else {
|
|
234
235
|
headers = new Headers(responseInit.headers);
|
|
235
236
|
}
|
|
236
|
-
revalidate !== undefined
|
|
237
|
+
if (revalidate !== undefined) {
|
|
238
|
+
const keys = revalidate.toString();
|
|
239
|
+
if (keys.length > RESPONSE_HEADER_VALUE_LIMIT) {
|
|
240
|
+
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.`);
|
|
241
|
+
}
|
|
242
|
+
headers.set(REVALIDATE_HEADER, keys);
|
|
243
|
+
}
|
|
237
244
|
return {
|
|
238
245
|
responseInit,
|
|
239
246
|
headers
|
|
@@ -251,7 +258,12 @@ function redirect(url, init = 302) {
|
|
|
251
258
|
responseInit.status = 302;
|
|
252
259
|
}
|
|
253
260
|
const target = typeof url === "string" ? url : url[HREF];
|
|
254
|
-
|
|
261
|
+
const location = typeof target === "string" ? target : String(url);
|
|
262
|
+
const encoded = location.replace(/[^\x00-\x7f]/gu, encodeURIComponent);
|
|
263
|
+
if (encoded.length > RESPONSE_HEADER_VALUE_LIMIT) {
|
|
264
|
+
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.`);
|
|
265
|
+
}
|
|
266
|
+
headers.set("Location", encoded);
|
|
255
267
|
return new Response(null, {
|
|
256
268
|
...responseInit,
|
|
257
269
|
headers
|
|
@@ -267,11 +279,18 @@ function reload(init = {}) {
|
|
|
267
279
|
headers
|
|
268
280
|
});
|
|
269
281
|
}
|
|
282
|
+
const NULL_BODY_STATUSES = new Set([204, 205, 304]);
|
|
270
283
|
function respond(value, init = {}) {
|
|
271
284
|
const {
|
|
272
285
|
responseInit,
|
|
273
286
|
headers
|
|
274
287
|
} = initWithRevalidate(init);
|
|
288
|
+
if (NULL_BODY_STATUSES.has(responseInit.status)) {
|
|
289
|
+
return new ResponseEnvelope(new Response(null, {
|
|
290
|
+
...responseInit,
|
|
291
|
+
headers
|
|
292
|
+
}), value);
|
|
293
|
+
}
|
|
275
294
|
headers.set("Content-Type", "application/json");
|
|
276
295
|
return new ResponseEnvelope(new Response(JSON.stringify(value), {
|
|
277
296
|
...responseInit,
|
|
@@ -322,6 +341,7 @@ function serializeCookie(name, value, options = {}) {
|
|
|
322
341
|
if (options.expires) cookie += `; Expires=${options.expires.toUTCString()}`;
|
|
323
342
|
if (options.httpOnly) cookie += "; HttpOnly";
|
|
324
343
|
if (options.secure) cookie += "; Secure";
|
|
344
|
+
if (options.partitioned) cookie += "; Partitioned";
|
|
325
345
|
if (options.sameSite) {
|
|
326
346
|
const sameSite = options.sameSite.toLowerCase();
|
|
327
347
|
cookie += `; SameSite=${sameSite === "none" ? "None" : sameSite === "strict" ? "Strict" : "Lax"}`;
|
|
@@ -339,6 +359,7 @@ function clearFlashCookie() {
|
|
|
339
359
|
|
|
340
360
|
const ERROR_HEADER = "X-Server-Function-Error";
|
|
341
361
|
const BODY_FORMAT_HEADER = "X-Server-Function-Format";
|
|
362
|
+
const REDIRECT_HEADER = "X-Server-Function-Redirect";
|
|
342
363
|
const SINGLE_FLIGHT_HEADER = "X-Single-Flight";
|
|
343
364
|
|
|
344
365
|
const HEAD_ELIGIBLE_TAGS = new Set(["title", "meta", "link", "style", "script", "base"]);
|
|
@@ -377,7 +398,8 @@ function resourceIdentity(tag, props) {
|
|
|
377
398
|
let id = "res:" + tag + ":" + (props.rel || "") + ":" + (props.href || props.src || "");
|
|
378
399
|
for (let i = 0; i < RESOURCE_QUALIFIERS.length; i++) {
|
|
379
400
|
const q = RESOURCE_QUALIFIERS[i];
|
|
380
|
-
|
|
401
|
+
const value = props[q];
|
|
402
|
+
if (value != null) id += ":" + q + "=" + (value === true ? "" : value);
|
|
381
403
|
}
|
|
382
404
|
return id;
|
|
383
405
|
}
|
|
@@ -439,6 +461,7 @@ function resolveAssets(moduleUrl, manifest) {
|
|
|
439
461
|
if (!entry) return null;
|
|
440
462
|
const css = [];
|
|
441
463
|
const js = [];
|
|
464
|
+
let preloads;
|
|
442
465
|
const visited = new Set();
|
|
443
466
|
const walk = key => {
|
|
444
467
|
if (visited.has(key)) return;
|
|
@@ -447,13 +470,26 @@ function resolveAssets(moduleUrl, manifest) {
|
|
|
447
470
|
if (!e) return;
|
|
448
471
|
js.push(joinAssetPath(base, e.file));
|
|
449
472
|
if (e.css) for (let i = 0; i < e.css.length; i++) css.push(joinAssetPath(base, e.css[i]));
|
|
473
|
+
if (e.preloads) {
|
|
474
|
+
for (let i = 0; i < e.preloads.length; i++) {
|
|
475
|
+
const link = e.preloads[i];
|
|
476
|
+
if (!link || typeof link.href !== "string" || !link.href) continue;
|
|
477
|
+
if (!preloads) preloads = [];
|
|
478
|
+
preloads.push({
|
|
479
|
+
...link,
|
|
480
|
+
href: joinAssetPath(base, link.href)
|
|
481
|
+
});
|
|
482
|
+
}
|
|
483
|
+
}
|
|
450
484
|
if (e.imports) for (let i = 0; i < e.imports.length; i++) walk(e.imports[i]);
|
|
451
485
|
};
|
|
452
486
|
walk(moduleUrl);
|
|
453
|
-
|
|
487
|
+
const assets = {
|
|
454
488
|
js,
|
|
455
489
|
css
|
|
456
490
|
};
|
|
491
|
+
if (preloads) assets.preloads = preloads;
|
|
492
|
+
return assets;
|
|
457
493
|
}
|
|
458
494
|
function registerEntryAssets(manifest) {
|
|
459
495
|
if (!manifest || typeof manifest === "function" || typeof manifest.resolve === "function") return;
|
|
@@ -463,6 +499,7 @@ function registerEntryAssets(manifest) {
|
|
|
463
499
|
if (manifest[key].isEntry) {
|
|
464
500
|
const assets = resolveAssets(key, manifest);
|
|
465
501
|
if (assets) {
|
|
502
|
+
if (assets.preloads) for (let i = 0; i < assets.preloads.length; i++) ctx.registerAsset("preload", assets.preloads[i]);
|
|
466
503
|
for (let i = 0; i < assets.css.length; i++) ctx.registerAsset("style", assets.css[i]);
|
|
467
504
|
for (let i = 1; i < assets.js.length; i++) ctx.registerAsset("module", assets.js[i]);
|
|
468
505
|
}
|
|
@@ -481,6 +518,7 @@ function createAssetTracking() {
|
|
|
481
518
|
boundaryStyles,
|
|
482
519
|
emittedAssets,
|
|
483
520
|
inlineStyles,
|
|
521
|
+
preloadLinks: null,
|
|
484
522
|
registerInlineStyle(desc) {
|
|
485
523
|
let entry = inlineStyles.get(desc.id);
|
|
486
524
|
if (!entry) {
|
|
@@ -572,6 +610,56 @@ function isCssUrl(url) {
|
|
|
572
610
|
const q = url.search(/[?#]/);
|
|
573
611
|
return (q === -1 ? url : url.slice(0, q)).endsWith(".css");
|
|
574
612
|
}
|
|
613
|
+
const PRELOAD_LINK_ATTRIBUTES = ["type", "crossorigin", "integrity", "referrerpolicy", "fetchpriority", "media"];
|
|
614
|
+
function registerPreloadLink(tracking, headRegistry, link, nonce) {
|
|
615
|
+
if (!link || typeof link !== "object" || typeof link.href !== "string" || !link.href) {
|
|
616
|
+
return null;
|
|
617
|
+
}
|
|
618
|
+
if (typeof link.as !== "string") {
|
|
619
|
+
return null;
|
|
620
|
+
}
|
|
621
|
+
const as = asciiLowerCase(link.as);
|
|
622
|
+
let destination = null;
|
|
623
|
+
switch (as) {
|
|
624
|
+
case "script":
|
|
625
|
+
case "style":
|
|
626
|
+
destination = as;
|
|
627
|
+
break;
|
|
628
|
+
case "fetch":
|
|
629
|
+
case "font":
|
|
630
|
+
case "image":
|
|
631
|
+
case "track":
|
|
632
|
+
break;
|
|
633
|
+
default:
|
|
634
|
+
return null;
|
|
635
|
+
}
|
|
636
|
+
const props = {
|
|
637
|
+
rel: "preload",
|
|
638
|
+
href: link.href,
|
|
639
|
+
as
|
|
640
|
+
};
|
|
641
|
+
for (let i = 0; i < PRELOAD_LINK_ATTRIBUTES.length; i++) {
|
|
642
|
+
const name = PRELOAD_LINK_ATTRIBUTES[i];
|
|
643
|
+
const value = link[name];
|
|
644
|
+
if (value == null || value === false) continue;
|
|
645
|
+
props[name] = value === true ? "" : String(value);
|
|
646
|
+
}
|
|
647
|
+
const identity = resourceIdentity("link", props);
|
|
648
|
+
if (headRegistry.resources.has(identity)) return null;
|
|
649
|
+
const attrs = headAttrRecord(props);
|
|
650
|
+
const nonceValue = destination && nonce && nonce[destination];
|
|
651
|
+
if (typeof nonceValue === "string" && nonceValue) attrs.nonce = nonceValue;
|
|
652
|
+
const entry = {
|
|
653
|
+
href: props.href,
|
|
654
|
+
attrs,
|
|
655
|
+
attrHtml: renderHeadAttrHtml(props) + nonceAttr(nonce, destination)
|
|
656
|
+
};
|
|
657
|
+
headRegistry.resources.add(identity);
|
|
658
|
+
let links = tracking.preloadLinks;
|
|
659
|
+
if (!links) tracking.preloadLinks = links = [];
|
|
660
|
+
links.push(entry);
|
|
661
|
+
return entry;
|
|
662
|
+
}
|
|
575
663
|
function createHeadRegistry() {
|
|
576
664
|
return {
|
|
577
665
|
pending: [],
|
|
@@ -1048,6 +1136,10 @@ function renderToString(code, options = {}) {
|
|
|
1048
1136
|
serializer.write(id, p);
|
|
1049
1137
|
},
|
|
1050
1138
|
registerAsset(type, value) {
|
|
1139
|
+
if (type === "preload") {
|
|
1140
|
+
registerPreloadLink(tracking, headRegistry, value, nonce);
|
|
1141
|
+
return;
|
|
1142
|
+
}
|
|
1051
1143
|
if (type === "inline-style") {
|
|
1052
1144
|
tracking.registerInlineStyle(value);
|
|
1053
1145
|
return;
|
|
@@ -1075,7 +1167,7 @@ function renderToString(code, options = {}) {
|
|
|
1075
1167
|
sharedConfig.context.noHydrate = true;
|
|
1076
1168
|
serializer.close();
|
|
1077
1169
|
const head = renderShellHead(headRegistry, nonce, null, noScripts);
|
|
1078
|
-
return assembleDocument(resolveSSRSelectValues(html), tracking.emittedAssets, tracking.inlineStyles, scripts.length ? scripts : "", nonce, head, onHead);
|
|
1170
|
+
return assembleDocument(resolveSSRSelectValues(html), tracking.emittedAssets, tracking.preloadLinks, tracking.inlineStyles, scripts.length ? scripts : "", nonce, head, onHead);
|
|
1079
1171
|
}
|
|
1080
1172
|
function renderToStream(code, options = {}) {
|
|
1081
1173
|
let {
|
|
@@ -1229,6 +1321,8 @@ function renderToStream(code, options = {}) {
|
|
|
1229
1321
|
asset(type, value) {
|
|
1230
1322
|
if (type === "module") {
|
|
1231
1323
|
buffer.write(`<link rel="modulepreload" href="${value}"${nonceAttr(nonce, "script")}>`);
|
|
1324
|
+
} else if (type === "preload") {
|
|
1325
|
+
buffer.write(`<link${value.attrHtml}>`);
|
|
1232
1326
|
} else if (type === "inline-style") {
|
|
1233
1327
|
buffer.write(renderInlineStyle(value, nonce));
|
|
1234
1328
|
} else if (type === "head-tag") {
|
|
@@ -1236,7 +1330,7 @@ function renderToStream(code, options = {}) {
|
|
|
1236
1330
|
}
|
|
1237
1331
|
},
|
|
1238
1332
|
shell(shellHtml, meta) {
|
|
1239
|
-
buffer.write(assembleDocument(shellHtml, meta.preloads, meta.inlineStyles, meta.tasks.length ? meta.tasks : "", nonce, meta.head, onHead));
|
|
1333
|
+
buffer.write(assembleDocument(shellHtml, meta.preloads, meta.preloadLinks, meta.inlineStyles, meta.tasks.length ? meta.tasks : "", nonce, meta.head, onHead));
|
|
1240
1334
|
},
|
|
1241
1335
|
...options.sink
|
|
1242
1336
|
};
|
|
@@ -1269,6 +1363,29 @@ function renderToStream(code, options = {}) {
|
|
|
1269
1363
|
}
|
|
1270
1364
|
};
|
|
1271
1365
|
const registry = new Map();
|
|
1366
|
+
const pendingSerialized = new Map();
|
|
1367
|
+
const trackSerialized = (id, p) => {
|
|
1368
|
+
let settle;
|
|
1369
|
+
const raced = Promise.race([p, new Promise(r => settle = r)]);
|
|
1370
|
+
pendingSerialized.set(id, settle);
|
|
1371
|
+
const drop = () => pendingSerialized.delete(id);
|
|
1372
|
+
p.then(drop, drop);
|
|
1373
|
+
return raced;
|
|
1374
|
+
};
|
|
1375
|
+
const abandonSubtree = key => {
|
|
1376
|
+
for (const [k, entry] of registry) {
|
|
1377
|
+
if (k.length > key.length && k.startsWith(key)) {
|
|
1378
|
+
registry.delete(k);
|
|
1379
|
+
entry.resolve();
|
|
1380
|
+
}
|
|
1381
|
+
}
|
|
1382
|
+
for (const [id, settle] of pendingSerialized) {
|
|
1383
|
+
if (id.startsWith(key)) {
|
|
1384
|
+
pendingSerialized.delete(id);
|
|
1385
|
+
settle();
|
|
1386
|
+
}
|
|
1387
|
+
}
|
|
1388
|
+
};
|
|
1272
1389
|
const writeTasks = () => {
|
|
1273
1390
|
if (tasks.length && !completed && firstFlushed) {
|
|
1274
1391
|
buffer.write(`<script${nonceAttr(nonce, "script")}>${tasks}</script>`);
|
|
@@ -1339,6 +1456,11 @@ function renderToStream(code, options = {}) {
|
|
|
1339
1456
|
}, nonce, tags);
|
|
1340
1457
|
},
|
|
1341
1458
|
registerAsset(type, value) {
|
|
1459
|
+
if (type === "preload") {
|
|
1460
|
+
const entry = registerPreloadLink(tracking, headRegistry, value, nonce);
|
|
1461
|
+
if (entry && firstFlushed) sink.asset("preload", entry);
|
|
1462
|
+
return;
|
|
1463
|
+
}
|
|
1342
1464
|
if (type === "inline-style") {
|
|
1343
1465
|
const entry = tracking.registerInlineStyle(value);
|
|
1344
1466
|
if (firstFlushed && !tracking.currentBoundaryId && !entry.emitted) {
|
|
@@ -1383,13 +1505,14 @@ function renderToStream(code, options = {}) {
|
|
|
1383
1505
|
},
|
|
1384
1506
|
serialize(id, p, deferStream) {
|
|
1385
1507
|
if (sharedConfig.context.noHydrate) return;
|
|
1386
|
-
if (
|
|
1387
|
-
if (deferStream) {
|
|
1508
|
+
if (p && typeof p === "object" && typeof p.then === "function") {
|
|
1509
|
+
if (!firstFlushed && deferStream) {
|
|
1388
1510
|
blockingPromises.add(p);
|
|
1389
1511
|
p.then(d => serializer.write(id, d)).catch(e => serializer.write(id, e));
|
|
1390
1512
|
return;
|
|
1391
1513
|
}
|
|
1392
|
-
|
|
1514
|
+
p = trackSerialized(id, p);
|
|
1515
|
+
if (!firstFlushed && canBatchStubs && !shellCompleted) {
|
|
1393
1516
|
(stubBatch ||= new Map()).set(id, p);
|
|
1394
1517
|
return;
|
|
1395
1518
|
}
|
|
@@ -1434,6 +1557,7 @@ function renderToStream(code, options = {}) {
|
|
|
1434
1557
|
if (registry.has(key)) {
|
|
1435
1558
|
const item = registry.get(key);
|
|
1436
1559
|
registry.delete(key);
|
|
1560
|
+
if (error) abandonSubtree(key);
|
|
1437
1561
|
if (item.children) {
|
|
1438
1562
|
for (const k in item.children) {
|
|
1439
1563
|
value = replacePlaceholder(value, k, item.children[k]);
|
|
@@ -1558,6 +1682,7 @@ function renderToStream(code, options = {}) {
|
|
|
1558
1682
|
const head = renderShellHead(headRegistry, nonce, k => registry.has(k), noScripts);
|
|
1559
1683
|
sink.shell(resolveSSRSelectValues(html), {
|
|
1560
1684
|
preloads: tracking.emittedAssets,
|
|
1685
|
+
preloadLinks: tracking.preloadLinks,
|
|
1561
1686
|
inlineStyles: tracking.inlineStyles,
|
|
1562
1687
|
tasks,
|
|
1563
1688
|
head
|
|
@@ -2704,12 +2829,12 @@ function allSettled(promises) {
|
|
|
2704
2829
|
return;
|
|
2705
2830
|
});
|
|
2706
2831
|
}
|
|
2707
|
-
function assembleDocument(html, emittedAssets, inlineStyles, scripts, nonce, headTags, onHead) {
|
|
2832
|
+
function assembleDocument(html, emittedAssets, preloadLinks, inlineStyles, scripts, nonce, headTags, onHead) {
|
|
2708
2833
|
const scriptTag = scripts ? `<script${nonceAttr(nonce, "script")}>${scripts}</script>` : "";
|
|
2709
2834
|
const title = headTags ? headTags.title : null;
|
|
2710
2835
|
let headTagsHtml = headTags ? headTags.html : "";
|
|
2711
2836
|
const headPrelude = headTags ? headTags.prelude : "";
|
|
2712
|
-
if (!onHead && title == null && !headTagsHtml && !headPrelude && !(emittedAssets && emittedAssets.size) && !(inlineStyles && inlineStyles.size)) {
|
|
2837
|
+
if (!onHead && title == null && !headTagsHtml && !headPrelude && !(emittedAssets && emittedAssets.size) && !preloadLinks && !(inlineStyles && inlineStyles.size)) {
|
|
2713
2838
|
if (!scriptTag) return html;
|
|
2714
2839
|
const xs = html.indexOf("<!--xs-->");
|
|
2715
2840
|
return xs === -1 ? html + scriptTag : html.slice(0, xs) + scriptTag + html.slice(xs);
|
|
@@ -2728,7 +2853,7 @@ function assembleDocument(html, emittedAssets, inlineStyles, scripts, nonce, hea
|
|
|
2728
2853
|
if (title != null) {
|
|
2729
2854
|
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
2855
|
}
|
|
2731
|
-
onHead(headPrelude + headTagsHtml + titleHtml + renderHeadAssets(emittedAssets, inlineStyles, nonce));
|
|
2856
|
+
onHead(headPrelude + headTagsHtml + titleHtml + renderHeadAssets(emittedAssets, preloadLinks, inlineStyles, nonce));
|
|
2732
2857
|
}
|
|
2733
2858
|
if (!scriptTag) return html;
|
|
2734
2859
|
const xs = html.indexOf("<!--xs-->");
|
|
@@ -2748,13 +2873,13 @@ function assembleDocument(html, emittedAssets, inlineStyles, scripts, nonce, hea
|
|
|
2748
2873
|
headTagsHtml = `<title data-dh="title">${winner}</title>` + headTagsHtml;
|
|
2749
2874
|
}
|
|
2750
2875
|
}
|
|
2751
|
-
const head = headTagsHtml + renderHeadAssets(emittedAssets, inlineStyles, nonce);
|
|
2876
|
+
const head = headTagsHtml + renderHeadAssets(emittedAssets, preloadLinks, inlineStyles, nonce);
|
|
2752
2877
|
if (!scriptTag) return html.slice(0, headIdx) + head + html.slice(headIdx);
|
|
2753
2878
|
const xsIdx = html.indexOf("<!--xs-->");
|
|
2754
2879
|
if (xsIdx === -1) return html.slice(0, headIdx) + head + html.slice(headIdx) + scriptTag;
|
|
2755
2880
|
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
2881
|
}
|
|
2757
|
-
function renderHeadAssets(emittedAssets, inlineStyles, nonce) {
|
|
2882
|
+
function renderHeadAssets(emittedAssets, preloadLinks, inlineStyles, nonce) {
|
|
2758
2883
|
let head = "";
|
|
2759
2884
|
const styleAttr = nonceAttr(nonce, "style");
|
|
2760
2885
|
const scriptAttr = nonceAttr(nonce, "script");
|
|
@@ -2763,6 +2888,9 @@ function renderHeadAssets(emittedAssets, inlineStyles, nonce) {
|
|
|
2763
2888
|
head += isCssUrl(url) ? `<link rel="stylesheet" href="${url}"${styleAttr}>` : `<link rel="modulepreload" href="${url}"${scriptAttr}>`;
|
|
2764
2889
|
}
|
|
2765
2890
|
}
|
|
2891
|
+
if (preloadLinks) {
|
|
2892
|
+
for (const entry of preloadLinks) head += `<link${entry.attrHtml}>`;
|
|
2893
|
+
}
|
|
2766
2894
|
if (inlineStyles && inlineStyles.size) {
|
|
2767
2895
|
for (const entry of inlineStyles.values()) {
|
|
2768
2896
|
if (entry.emitted) continue;
|
|
@@ -3027,7 +3155,7 @@ function copyInitHeaders(init) {
|
|
|
3027
3155
|
for (const cookie of init.getSetCookie()) headers.append("Set-Cookie", cookie);
|
|
3028
3156
|
return headers;
|
|
3029
3157
|
}
|
|
3030
|
-
const STUB_GAP_FILL_EXCLUDED = /*#__PURE__*/new Set([ERROR_HEADER, BODY_FORMAT_HEADER, SINGLE_FLIGHT_HEADER, REVALIDATE_HEADER, "Location"].map(header => header.toLowerCase()));
|
|
3158
|
+
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
3159
|
function fillsStubGap(key, headers, response) {
|
|
3032
3160
|
if (key === "set-cookie" || STUB_GAP_FILL_EXCLUDED.has(key)) return false;
|
|
3033
3161
|
if (response.body === null && (key === "content-type" || key === "content-length")) return false;
|
|
@@ -3043,24 +3171,16 @@ function commitEventResponse(response, event = getRequestEvent()) {
|
|
|
3043
3171
|
if (fillsStubGap(key, response.headers, response)) hasGaps = true;
|
|
3044
3172
|
});
|
|
3045
3173
|
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
|
-
}
|
|
3174
|
+
const headers = copyInitHeaders(response.headers);
|
|
3175
|
+
for (const cookie of cookies) headers.append("Set-Cookie", cookie);
|
|
3176
|
+
stub.headers.forEach((value, key) => {
|
|
3177
|
+
if (fillsStubGap(key, headers, response)) headers.set(key, value);
|
|
3178
|
+
});
|
|
3179
|
+
return new Response(response.body, {
|
|
3180
|
+
status: response.status,
|
|
3181
|
+
statusText: response.statusText,
|
|
3182
|
+
headers
|
|
3183
|
+
});
|
|
3064
3184
|
}
|
|
3065
3185
|
function deriveHead(stub, responseInit = {}) {
|
|
3066
3186
|
const headers = mergeStubHeaders(copyInitHeaders(responseInit.headers), stub);
|
|
@@ -3226,6 +3346,11 @@ function registerClientOnlyPreload(moduleUrl) {
|
|
|
3226
3346
|
const css = assets.css[i];
|
|
3227
3347
|
if (typeof css === "string") registerAsset("style", css);else registerAsset("inline-style", css);
|
|
3228
3348
|
}
|
|
3349
|
+
if (assets.preloads) {
|
|
3350
|
+
for (let i = 0; i < assets.preloads.length; i++) {
|
|
3351
|
+
registerAsset("preload", assets.preloads[i]);
|
|
3352
|
+
}
|
|
3353
|
+
}
|
|
3229
3354
|
for (let i = 0; i < assets.js.length; i++) registerAsset("module", assets.js[i]);
|
|
3230
3355
|
};
|
|
3231
3356
|
const assets = resolve(moduleUrl);
|
|
@@ -3329,4 +3454,4 @@ function httpHeader(name, value, options) {
|
|
|
3329
3454
|
}
|
|
3330
3455
|
}
|
|
3331
3456
|
|
|
3332
|
-
export { CLAIMS_DOCUMENT, CLAIMS_STREAM, CLAIM_PROP, ChildProperties, DOMElements, DOMWithState, DelegatedEvents, Dynamic, HREF, HydrationScript, MathMLElements, Namespaces, Portal, REVALIDATE_HEADER, RawTextElements, RequestContext, ResponseEnvelope, SAFE_ERROR, SVGElements, VoidElements, notSup as acquireAsset, notSup as addEvent, applyRef, notSup as assign, claimElement, claimElementTree, notSup as className, clearFlashCookie, clientOnly, commitEventResponse, commitResponseStub, composeMiddleware, createLiveHoles, createRequestEvent, createResponseStub, createSSRResponse, notSup as delegateEvents, dynamic, notSup as dynamicProperty, effect, escape, generateHydrationScript, notSup as getDelegatedRoot, getExpectedRedirectStatus, getHydrationKey, notSup as getNextElement, notSup as getNextMarker, notSup as getNextMatch, getRequestEvent, getServerFunctionMetadata, getServerFunctionRPC, hasFlashCookie, httpHeader, httpStatus, notSup as hydrate, notSup as insert, isDev, isHref, isResponseEnvelope, isSafeError, isServer, isServerFunction, markSafeError, memo, parseCookieHeader, redirect, notSup as ref, notSup as registerDelegatedContainer, notSup as registerDelegatedRoot, registerElementClaim, reload, notSup as render, renderToStream, renderToString, resolveSSRNode, resolveSSRSelectValues, respond, notSup as runHydrationEvents, scriptNonce, serializeCookie, notSup as setAttribute, notSup as setAttributeNS, notSup as setProperty, notSup as setStyleProperty, notSup as spread, ssr, ssrAttribute, ssrClaim, ssrClassName, ssrElement, ssrGroup, ssrHydrationKey, ssrSelectValues, ssrStyle, ssrStyleProperty, notSup as style, styleNonce, notSup as template, notSup as unregisterDelegatedContainer, notSup as unregisterDelegatedRoot, useHead };
|
|
3457
|
+
export { CLAIMS_DOCUMENT, CLAIMS_STREAM, CLAIM_PROP, ChildProperties, DOMElements, DOMWithState, DelegatedEvents, Dynamic, HREF, HydrationScript, MathMLElements, NULL_BODY_STATUSES, Namespaces, Portal, RESPONSE_HEADER_VALUE_LIMIT, REVALIDATE_HEADER, RawTextElements, RequestContext, ResponseEnvelope, SAFE_ERROR, SVGElements, VoidElements, notSup as acquireAsset, notSup as addEvent, applyRef, notSup as assign, claimElement, claimElementTree, notSup as className, clearFlashCookie, clientOnly, commitEventResponse, commitResponseStub, composeMiddleware, createLiveHoles, createRequestEvent, createResponseStub, createSSRResponse, notSup as delegateEvents, dynamic, notSup as dynamicProperty, effect, escape, generateHydrationScript, notSup as getDelegatedRoot, getExpectedRedirectStatus, getHydrationKey, notSup as getNextElement, notSup as getNextMarker, notSup as getNextMatch, getRequestEvent, getServerFunctionMetadata, getServerFunctionRPC, hasFlashCookie, httpHeader, httpStatus, notSup as hydrate, notSup as insert, isDev, isHref, isResponseEnvelope, isSafeError, isServer, isServerFunction, markSafeError, memo, parseCookieHeader, redirect, notSup as ref, notSup as registerDelegatedContainer, notSup as registerDelegatedRoot, registerElementClaim, reload, notSup as render, renderToStream, renderToString, resolveSSRNode, resolveSSRSelectValues, respond, notSup as runHydrationEvents, scriptNonce, serializeCookie, notSup as setAttribute, notSup as setAttributeNS, notSup as setProperty, notSup as setStyleProperty, notSup as spread, ssr, ssrAttribute, ssrClaim, ssrClassName, ssrElement, ssrGroup, ssrHydrationKey, ssrSelectValues, ssrStyle, ssrStyleProperty, notSup as style, styleNonce, notSup as template, notSup as unregisterDelegatedContainer, notSup as unregisterDelegatedRoot, useHead };
|
package/dist/web.cjs
CHANGED
|
@@ -215,7 +215,8 @@ function resourceIdentity(tag, props) {
|
|
|
215
215
|
let id = "res:" + tag + ":" + (props.rel || "") + ":" + (props.href || props.src || "");
|
|
216
216
|
for (let i = 0; i < RESOURCE_QUALIFIERS.length; i++) {
|
|
217
217
|
const q = RESOURCE_QUALIFIERS[i];
|
|
218
|
-
|
|
218
|
+
const value = props[q];
|
|
219
|
+
if (value != null) id += ":" + q + "=" + (value === true ? "" : value);
|
|
219
220
|
}
|
|
220
221
|
return id;
|
|
221
222
|
}
|
|
@@ -294,6 +295,7 @@ function serializeCookie(name, value, options = {}) {
|
|
|
294
295
|
if (options.expires) cookie += `; Expires=${options.expires.toUTCString()}`;
|
|
295
296
|
if (options.httpOnly) cookie += "; HttpOnly";
|
|
296
297
|
if (options.secure) cookie += "; Secure";
|
|
298
|
+
if (options.partitioned) cookie += "; Partitioned";
|
|
297
299
|
if (options.sameSite) {
|
|
298
300
|
const sameSite = options.sameSite.toLowerCase();
|
|
299
301
|
cookie += `; SameSite=${sameSite === "none" ? "None" : sameSite === "strict" ? "Strict" : "Lax"}`;
|
|
@@ -580,16 +582,18 @@ function setStyleProperty(node, name, value) {
|
|
|
580
582
|
}
|
|
581
583
|
function spread(node, props = {}, skipChildren) {
|
|
582
584
|
const prevProps = {};
|
|
583
|
-
|
|
585
|
+
const get = typeof props === "function" ? props : () => props;
|
|
586
|
+
if (!skipChildren) insert(node, () => get().children);
|
|
584
587
|
effect(() => {
|
|
585
|
-
const r =
|
|
588
|
+
const r = get().ref;
|
|
586
589
|
(typeof r === "function" || Array.isArray(r)) && ref(() => r, node);
|
|
587
590
|
}, () => {});
|
|
588
591
|
effect(() => {
|
|
592
|
+
const source = get();
|
|
589
593
|
const newProps = {};
|
|
590
|
-
for (const prop in
|
|
594
|
+
for (const prop in source) {
|
|
591
595
|
if (prop === "children" || prop === "ref") continue;
|
|
592
|
-
newProps[prop] =
|
|
596
|
+
newProps[prop] = source[prop];
|
|
593
597
|
}
|
|
594
598
|
return newProps;
|
|
595
599
|
}, props => assign(node, props, true, prevProps, true));
|
|
@@ -2016,6 +2020,7 @@ function isSafeError(value) {
|
|
|
2016
2020
|
return !!(value && (typeof value === "object" || typeof value === "function") && value[SAFE_ERROR]);
|
|
2017
2021
|
}
|
|
2018
2022
|
const REVALIDATE_HEADER = "X-Revalidate";
|
|
2023
|
+
const RESPONSE_HEADER_VALUE_LIMIT = 4096;
|
|
2019
2024
|
function initWithRevalidate(init = {}) {
|
|
2020
2025
|
const resolved = typeof init === "number" ? {
|
|
2021
2026
|
status: init
|
|
@@ -2036,7 +2041,13 @@ function initWithRevalidate(init = {}) {
|
|
|
2036
2041
|
} else {
|
|
2037
2042
|
headers = new Headers(responseInit.headers);
|
|
2038
2043
|
}
|
|
2039
|
-
revalidate !== undefined
|
|
2044
|
+
if (revalidate !== undefined) {
|
|
2045
|
+
const keys = revalidate.toString();
|
|
2046
|
+
if (keys.length > RESPONSE_HEADER_VALUE_LIMIT) {
|
|
2047
|
+
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.`);
|
|
2048
|
+
}
|
|
2049
|
+
headers.set(REVALIDATE_HEADER, keys);
|
|
2050
|
+
}
|
|
2040
2051
|
return {
|
|
2041
2052
|
responseInit,
|
|
2042
2053
|
headers
|
|
@@ -2054,7 +2065,12 @@ function redirect(url, init = 302) {
|
|
|
2054
2065
|
responseInit.status = 302;
|
|
2055
2066
|
}
|
|
2056
2067
|
const target = typeof url === "string" ? url : url[HREF];
|
|
2057
|
-
|
|
2068
|
+
const location = typeof target === "string" ? target : String(url);
|
|
2069
|
+
const encoded = location.replace(/[^\x00-\x7f]/gu, encodeURIComponent);
|
|
2070
|
+
if (encoded.length > RESPONSE_HEADER_VALUE_LIMIT) {
|
|
2071
|
+
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.`);
|
|
2072
|
+
}
|
|
2073
|
+
headers.set("Location", encoded);
|
|
2058
2074
|
return new Response(null, {
|
|
2059
2075
|
...responseInit,
|
|
2060
2076
|
headers
|
|
@@ -2070,11 +2086,18 @@ function reload(init = {}) {
|
|
|
2070
2086
|
headers
|
|
2071
2087
|
});
|
|
2072
2088
|
}
|
|
2089
|
+
const NULL_BODY_STATUSES = new Set([204, 205, 304]);
|
|
2073
2090
|
function respond(value, init = {}) {
|
|
2074
2091
|
const {
|
|
2075
2092
|
responseInit,
|
|
2076
2093
|
headers
|
|
2077
2094
|
} = initWithRevalidate(init);
|
|
2095
|
+
if (NULL_BODY_STATUSES.has(responseInit.status)) {
|
|
2096
|
+
return new ResponseEnvelope(new Response(null, {
|
|
2097
|
+
...responseInit,
|
|
2098
|
+
headers
|
|
2099
|
+
}), value);
|
|
2100
|
+
}
|
|
2078
2101
|
headers.set("Content-Type", "application/json");
|
|
2079
2102
|
return new ResponseEnvelope(new Response(JSON.stringify(value), {
|
|
2080
2103
|
...responseInit,
|
|
@@ -2289,8 +2312,10 @@ exports.Dynamic = Dynamic;
|
|
|
2289
2312
|
exports.HREF = HREF;
|
|
2290
2313
|
exports.HydrationScript = HydrationScript;
|
|
2291
2314
|
exports.MathMLElements = MathMLElements;
|
|
2315
|
+
exports.NULL_BODY_STATUSES = NULL_BODY_STATUSES;
|
|
2292
2316
|
exports.Namespaces = Namespaces;
|
|
2293
2317
|
exports.Portal = Portal;
|
|
2318
|
+
exports.RESPONSE_HEADER_VALUE_LIMIT = RESPONSE_HEADER_VALUE_LIMIT;
|
|
2294
2319
|
exports.REVALIDATE_HEADER = REVALIDATE_HEADER;
|
|
2295
2320
|
exports.RawTextElements = RawTextElements;
|
|
2296
2321
|
exports.RequestContext = RequestContext;
|
package/dist/web.js
CHANGED
|
@@ -214,7 +214,8 @@ function resourceIdentity(tag, props) {
|
|
|
214
214
|
let id = "res:" + tag + ":" + (props.rel || "") + ":" + (props.href || props.src || "");
|
|
215
215
|
for (let i = 0; i < RESOURCE_QUALIFIERS.length; i++) {
|
|
216
216
|
const q = RESOURCE_QUALIFIERS[i];
|
|
217
|
-
|
|
217
|
+
const value = props[q];
|
|
218
|
+
if (value != null) id += ":" + q + "=" + (value === true ? "" : value);
|
|
218
219
|
}
|
|
219
220
|
return id;
|
|
220
221
|
}
|
|
@@ -293,6 +294,7 @@ function serializeCookie(name, value, options = {}) {
|
|
|
293
294
|
if (options.expires) cookie += `; Expires=${options.expires.toUTCString()}`;
|
|
294
295
|
if (options.httpOnly) cookie += "; HttpOnly";
|
|
295
296
|
if (options.secure) cookie += "; Secure";
|
|
297
|
+
if (options.partitioned) cookie += "; Partitioned";
|
|
296
298
|
if (options.sameSite) {
|
|
297
299
|
const sameSite = options.sameSite.toLowerCase();
|
|
298
300
|
cookie += `; SameSite=${sameSite === "none" ? "None" : sameSite === "strict" ? "Strict" : "Lax"}`;
|
|
@@ -579,16 +581,18 @@ function setStyleProperty(node, name, value) {
|
|
|
579
581
|
}
|
|
580
582
|
function spread(node, props = {}, skipChildren) {
|
|
581
583
|
const prevProps = {};
|
|
582
|
-
|
|
584
|
+
const get = typeof props === "function" ? props : () => props;
|
|
585
|
+
if (!skipChildren) insert(node, () => get().children);
|
|
583
586
|
effect(() => {
|
|
584
|
-
const r =
|
|
587
|
+
const r = get().ref;
|
|
585
588
|
(typeof r === "function" || Array.isArray(r)) && ref(() => r, node);
|
|
586
589
|
}, () => {});
|
|
587
590
|
effect(() => {
|
|
591
|
+
const source = get();
|
|
588
592
|
const newProps = {};
|
|
589
|
-
for (const prop in
|
|
593
|
+
for (const prop in source) {
|
|
590
594
|
if (prop === "children" || prop === "ref") continue;
|
|
591
|
-
newProps[prop] =
|
|
595
|
+
newProps[prop] = source[prop];
|
|
592
596
|
}
|
|
593
597
|
return newProps;
|
|
594
598
|
}, props => assign(node, props, true, prevProps, true));
|
|
@@ -2015,6 +2019,7 @@ function isSafeError(value) {
|
|
|
2015
2019
|
return !!(value && (typeof value === "object" || typeof value === "function") && value[SAFE_ERROR]);
|
|
2016
2020
|
}
|
|
2017
2021
|
const REVALIDATE_HEADER = "X-Revalidate";
|
|
2022
|
+
const RESPONSE_HEADER_VALUE_LIMIT = 4096;
|
|
2018
2023
|
function initWithRevalidate(init = {}) {
|
|
2019
2024
|
const resolved = typeof init === "number" ? {
|
|
2020
2025
|
status: init
|
|
@@ -2035,7 +2040,13 @@ function initWithRevalidate(init = {}) {
|
|
|
2035
2040
|
} else {
|
|
2036
2041
|
headers = new Headers(responseInit.headers);
|
|
2037
2042
|
}
|
|
2038
|
-
revalidate !== undefined
|
|
2043
|
+
if (revalidate !== undefined) {
|
|
2044
|
+
const keys = revalidate.toString();
|
|
2045
|
+
if (keys.length > RESPONSE_HEADER_VALUE_LIMIT) {
|
|
2046
|
+
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.`);
|
|
2047
|
+
}
|
|
2048
|
+
headers.set(REVALIDATE_HEADER, keys);
|
|
2049
|
+
}
|
|
2039
2050
|
return {
|
|
2040
2051
|
responseInit,
|
|
2041
2052
|
headers
|
|
@@ -2053,7 +2064,12 @@ function redirect(url, init = 302) {
|
|
|
2053
2064
|
responseInit.status = 302;
|
|
2054
2065
|
}
|
|
2055
2066
|
const target = typeof url === "string" ? url : url[HREF];
|
|
2056
|
-
|
|
2067
|
+
const location = typeof target === "string" ? target : String(url);
|
|
2068
|
+
const encoded = location.replace(/[^\x00-\x7f]/gu, encodeURIComponent);
|
|
2069
|
+
if (encoded.length > RESPONSE_HEADER_VALUE_LIMIT) {
|
|
2070
|
+
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.`);
|
|
2071
|
+
}
|
|
2072
|
+
headers.set("Location", encoded);
|
|
2057
2073
|
return new Response(null, {
|
|
2058
2074
|
...responseInit,
|
|
2059
2075
|
headers
|
|
@@ -2069,11 +2085,18 @@ function reload(init = {}) {
|
|
|
2069
2085
|
headers
|
|
2070
2086
|
});
|
|
2071
2087
|
}
|
|
2088
|
+
const NULL_BODY_STATUSES = new Set([204, 205, 304]);
|
|
2072
2089
|
function respond(value, init = {}) {
|
|
2073
2090
|
const {
|
|
2074
2091
|
responseInit,
|
|
2075
2092
|
headers
|
|
2076
2093
|
} = initWithRevalidate(init);
|
|
2094
|
+
if (NULL_BODY_STATUSES.has(responseInit.status)) {
|
|
2095
|
+
return new ResponseEnvelope(new Response(null, {
|
|
2096
|
+
...responseInit,
|
|
2097
|
+
headers
|
|
2098
|
+
}), value);
|
|
2099
|
+
}
|
|
2077
2100
|
headers.set("Content-Type", "application/json");
|
|
2078
2101
|
return new ResponseEnvelope(new Response(JSON.stringify(value), {
|
|
2079
2102
|
...responseInit,
|
|
@@ -2224,4 +2247,4 @@ _moduleUrl) {
|
|
|
2224
2247
|
function httpStatus(_code, _text) {}
|
|
2225
2248
|
function httpHeader(_name, _value, _options) {}
|
|
2226
2249
|
|
|
2227
|
-
export { ChildProperties, DOMElements, DOMWithState, DelegatedEvents, Dynamic, HREF, HydrationScript, MathMLElements, Namespaces, Portal, REVALIDATE_HEADER, RawTextElements, RequestContext, ResponseEnvelope, SAFE_ERROR, SVGElements, VoidElements, acquireAsset, addEvent, applyRef, assign, claimElement, claimElementTree, className, clearFlashCookie, clientOnly, commitEventResponse, composeMiddleware, createRequestEvent, createResponseStub, createSSRResponse, delegateEvents, driveList, dynamic, dynamicProperty, effect, escape, generateHydrationScript, getDelegatedRoot, getExpectedRedirectStatus, getFirstChild, getHydrationKey, getNextElement, getNextMarker, getNextMatch, getNextSibling, getRequestEvent, getServerFunctionMetadata, getServerFunctionRPC, hasFlashCookie, httpHeader, httpStatus, hydrate, insert, installHydrationRuntime, installListDriver, isDev, isHref, isResponseEnvelope, isSafeError, isServer, isServerFunction, listDriver, markSafeError, memo, parseCookieHeader, patchDriver, redirect, ref, registerDelegatedContainer, registerDelegatedRoot, registerElementClaim, reload, render, renderToStream, renderToString, resolveSSRNode, respond, rowProof, runHydrationEvents, scope, serializeCookie, setAttribute, setAttributeNS, setProperty, setStyleProperty, spread, ssr, ssrAttribute, ssrClassName, ssrElement, ssrGroup, ssrHydrationKey, ssrStyle, ssrStyleProperty, style, template, unregisterDelegatedContainer, unregisterDelegatedRoot, useHead, waitAsset, warmAsset };
|
|
2250
|
+
export { ChildProperties, DOMElements, DOMWithState, DelegatedEvents, Dynamic, HREF, HydrationScript, MathMLElements, NULL_BODY_STATUSES, Namespaces, Portal, RESPONSE_HEADER_VALUE_LIMIT, REVALIDATE_HEADER, RawTextElements, RequestContext, ResponseEnvelope, SAFE_ERROR, SVGElements, VoidElements, acquireAsset, addEvent, applyRef, assign, claimElement, claimElementTree, className, clearFlashCookie, clientOnly, commitEventResponse, composeMiddleware, createRequestEvent, createResponseStub, createSSRResponse, delegateEvents, driveList, dynamic, dynamicProperty, effect, escape, generateHydrationScript, getDelegatedRoot, getExpectedRedirectStatus, getFirstChild, getHydrationKey, getNextElement, getNextMarker, getNextMatch, getNextSibling, getRequestEvent, getServerFunctionMetadata, getServerFunctionRPC, hasFlashCookie, httpHeader, httpStatus, hydrate, insert, installHydrationRuntime, installListDriver, isDev, isHref, isResponseEnvelope, isSafeError, isServer, isServerFunction, listDriver, markSafeError, memo, parseCookieHeader, patchDriver, redirect, ref, registerDelegatedContainer, registerDelegatedRoot, registerElementClaim, reload, render, renderToStream, renderToString, resolveSSRNode, respond, rowProof, runHydrationEvents, scope, serializeCookie, setAttribute, setAttributeNS, setProperty, setStyleProperty, spread, ssr, ssrAttribute, ssrClassName, ssrElement, ssrGroup, ssrHydrationKey, ssrStyle, ssrStyleProperty, style, template, unregisterDelegatedContainer, unregisterDelegatedRoot, useHead, waitAsset, warmAsset };
|