@solidjs/web 2.0.0-rc.4 → 2.0.0-rc.6

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.
Files changed (61) hide show
  1. package/dist/dev.cjs +163 -36
  2. package/dist/dev.js +161 -37
  3. package/dist/server.cjs +178 -37
  4. package/dist/server.js +177 -38
  5. package/dist/web.cjs +143 -36
  6. package/dist/web.js +141 -37
  7. package/frames/dist/client.cjs +41 -8
  8. package/frames/dist/client.dev.cjs +41 -8
  9. package/frames/dist/client.dev.js +41 -8
  10. package/frames/dist/client.js +41 -8
  11. package/frames/dist/server.cjs +497 -44
  12. package/frames/dist/server.js +497 -44
  13. package/package.json +2 -2
  14. package/serialization/dist/decode.cjs +4 -2
  15. package/serialization/dist/decode.js +4 -2
  16. package/serialization/dist/serialization.cjs +12 -8
  17. package/serialization/dist/serialization.js +12 -8
  18. package/serialization/types/index.d.ts +7 -0
  19. package/serialization/types/serializer-decode.d.ts +14 -1
  20. package/serialization/types/serializer.d.ts +7 -0
  21. package/serialization/types-cjs/index.d.cts +7 -0
  22. package/serialization/types-cjs/serializer-decode.d.cts +14 -1
  23. package/serialization/types-cjs/serializer.d.cts +7 -0
  24. package/server-functions/dist/client.cjs +164 -35
  25. package/server-functions/dist/client.js +161 -36
  26. package/server-functions/dist/server.cjs +899 -136
  27. package/server-functions/dist/server.dev.cjs +919 -136
  28. package/server-functions/dist/server.dev.js +915 -137
  29. package/server-functions/dist/server.js +895 -137
  30. package/types/client.d.ts +2 -1
  31. package/types/constants.d.ts +3 -1
  32. package/types/cookies.d.ts +6 -14
  33. package/types/frames/frame-client.d.ts +4 -0
  34. package/types/frames/serializer-decode.d.ts +14 -1
  35. package/types/frames/serializer.d.ts +7 -0
  36. package/types/jsx.d.ts +11 -16
  37. package/types/response.d.ts +11 -0
  38. package/types/serializer-decode.d.ts +14 -1
  39. package/types/serializer.d.ts +7 -0
  40. package/types/server-functions/client.d.ts +22 -2
  41. package/types/server-functions/flash.d.ts +9 -0
  42. package/types/server-functions/server.d.ts +131 -11
  43. package/types/server-functions/shared.d.ts +77 -14
  44. package/types/server-mock.d.ts +17 -2
  45. package/types/server.d.ts +16 -2
  46. package/types-cjs/client.d.cts +2 -1
  47. package/types-cjs/constants.d.cts +3 -1
  48. package/types-cjs/cookies.d.cts +6 -14
  49. package/types-cjs/frames/frame-client.d.cts +4 -0
  50. package/types-cjs/frames/serializer-decode.d.cts +14 -1
  51. package/types-cjs/frames/serializer.d.cts +7 -0
  52. package/types-cjs/jsx.d.cts +11 -16
  53. package/types-cjs/response.d.cts +11 -0
  54. package/types-cjs/serializer-decode.d.cts +14 -1
  55. package/types-cjs/serializer.d.cts +7 -0
  56. package/types-cjs/server-functions/client.d.cts +22 -2
  57. package/types-cjs/server-functions/flash.d.cts +9 -0
  58. package/types-cjs/server-functions/server.d.cts +131 -11
  59. package/types-cjs/server-functions/shared.d.cts +77 -14
  60. package/types-cjs/server-mock.d.cts +17 -2
  61. package/types-cjs/server.d.cts +16 -2
@@ -99,6 +99,8 @@ const ContainerTracePlugin = {
99
99
  }
100
100
  };
101
101
 
102
+ const COMPOSED_BODY_FRAMING = /*#__PURE__*/new Set(["content-length", "content-encoding", "transfer-encoding"]);
103
+
102
104
  setContainerTraceStreamMint(iterable => {
103
105
  const stream = createStream();
104
106
  (async () => {
@@ -123,23 +125,25 @@ const JSON_CODEC_DEPTH_LIMIT = 64;
123
125
  function resolveCodecOptions({
124
126
  plugins,
125
127
  disabledFeatures,
126
- depthLimit
128
+ depthLimit,
129
+ serializeErrorStacks
127
130
  } = {}) {
128
131
  return {
129
132
  plugins: resolveSerializerPlugins(plugins),
130
133
  disabledFeatures: disabledFeatures === undefined ? JSON_CODEC_DISABLED_FEATURES : disabledFeatures,
131
- depthLimit: depthLimit === undefined ? JSON_CODEC_DEPTH_LIMIT : depthLimit
134
+ depthLimit: depthLimit === undefined ? JSON_CODEC_DEPTH_LIMIT : depthLimit,
135
+ serializeErrorStacks
132
136
  };
133
137
  }
134
138
 
135
139
  const DEFAULT_DISABLED_FEATURES = Feature.AggregateError | Feature.BigIntTypedArray;
136
- const serializeOnlyDisabledFeatures = () => process.env.NODE_ENV === "development" ? 0 : Feature.ErrorPrototypeStack;
140
+ const serializeOnlyDisabledFeatures = serializeErrorStacks => (serializeErrorStacks === undefined ? process.env.NODE_ENV === "development" : serializeErrorStacks) ? 0 : Feature.ErrorPrototypeStack;
137
141
  const HYDRATION_GLOBAL = "_$HY.r";
138
142
  function createSerializer(options) {
139
143
  return new Serializer({
140
144
  ...options,
141
145
  plugins: resolveSerializerPlugins(options.plugins),
142
- disabledFeatures: (options.disabledFeatures === undefined ? DEFAULT_DISABLED_FEATURES : options.disabledFeatures) | serializeOnlyDisabledFeatures()
146
+ disabledFeatures: (options.disabledFeatures === undefined ? DEFAULT_DISABLED_FEATURES : options.disabledFeatures) | serializeOnlyDisabledFeatures(options.serializeErrorStacks)
143
147
  });
144
148
  }
145
149
  function createHydrationSerializer({
@@ -167,12 +171,14 @@ function createJSONSerializer({
167
171
  onError,
168
172
  plugins,
169
173
  disabledFeatures,
170
- depthLimit
174
+ depthLimit,
175
+ serializeErrorStacks
171
176
  }) {
172
177
  const resolved = resolveCodecOptions({
173
178
  plugins,
174
179
  disabledFeatures,
175
- depthLimit
180
+ depthLimit,
181
+ serializeErrorStacks
176
182
  });
177
183
  const refs = new Map();
178
184
  const cancels = new Set();
@@ -194,7 +200,7 @@ function createJSONSerializer({
194
200
  const stream = toCrossJSONStream(value, {
195
201
  refs,
196
202
  plugins: resolved.plugins,
197
- disabledFeatures: resolved.disabledFeatures | serializeOnlyDisabledFeatures(),
203
+ disabledFeatures: resolved.disabledFeatures | serializeOnlyDisabledFeatures(resolved.serializeErrorStacks),
198
204
  onParse(node, initial) {
199
205
  onData({
200
206
  key,
@@ -231,6 +237,10 @@ const ENVELOPE = Symbol.for("solid.ResponseEnvelope");
231
237
  function isResponseEnvelope(value) {
232
238
  return !!(value && typeof value === "object" && value[ENVELOPE]);
233
239
  }
240
+ const SAFE_ERROR = Symbol.for("solid.SafeError");
241
+ function isSafeError(value) {
242
+ return !!(value && (typeof value === "object" || typeof value === "function") && value[SAFE_ERROR]);
243
+ }
234
244
  const REVALIDATE_HEADER = "X-Revalidate";
235
245
 
236
246
  function frameAddress(id, args) {
@@ -279,6 +289,7 @@ function stableString(value, seen) {
279
289
  }
280
290
  const ERROR_HEADER = "X-Server-Function-Error";
281
291
  const BODY_FORMAT_HEADER = "X-Server-Function-Format";
292
+ const REDIRECT_HEADER = "X-Server-Function-Redirect";
282
293
  const SINGLE_FLIGHT_HEADER = "X-Single-Flight";
283
294
  function createChunk(data) {
284
295
  const encoder = new TextEncoder();
@@ -292,18 +303,34 @@ function createChunk(data) {
292
303
  class ChunkReader {
293
304
  constructor(stream) {
294
305
  this.reader = stream.getReader();
295
- this.buffer = new Uint8Array(0);
306
+ this.store = new Uint8Array(0);
307
+ this.buffer = this.store;
296
308
  this.done = false;
297
309
  }
298
310
  async readChunk() {
299
311
  const chunk = await this.reader.read();
300
- if (!chunk.done) {
301
- const newBuffer = new Uint8Array(this.buffer.length + chunk.value.length);
302
- newBuffer.set(this.buffer);
303
- newBuffer.set(chunk.value, this.buffer.length);
304
- this.buffer = newBuffer;
305
- } else {
312
+ if (chunk.done) {
306
313
  this.done = true;
314
+ return;
315
+ }
316
+ const incoming = chunk.value;
317
+ const store = this.store;
318
+ const start = this.buffer.byteOffset;
319
+ const end = start + this.buffer.length;
320
+ const needed = this.buffer.length + incoming.length;
321
+ if (end + incoming.length <= store.length) {
322
+ store.set(incoming, end);
323
+ this.buffer = store.subarray(start, end + incoming.length);
324
+ } else if (needed <= store.length) {
325
+ store.copyWithin(0, start, end);
326
+ store.set(incoming, this.buffer.length);
327
+ this.buffer = store.subarray(0, needed);
328
+ } else {
329
+ const grown = new Uint8Array(Math.max(needed, store.length * 2));
330
+ grown.set(this.buffer);
331
+ grown.set(incoming, this.buffer.length);
332
+ this.store = grown;
333
+ this.buffer = grown.subarray(0, needed);
307
334
  }
308
335
  }
309
336
  async next() {
@@ -403,7 +430,8 @@ function resourceIdentity(tag, props) {
403
430
  let id = "res:" + tag + ":" + (props.rel || "") + ":" + (props.href || props.src || "");
404
431
  for (let i = 0; i < RESOURCE_QUALIFIERS.length; i++) {
405
432
  const q = RESOURCE_QUALIFIERS[i];
406
- if (props[q] != null) id += ":" + q + "=" + props[q];
433
+ const value = props[q];
434
+ if (value != null) id += ":" + q + "=" + (value === true ? "" : value);
407
435
  }
408
436
  return id;
409
437
  }
@@ -465,6 +493,7 @@ function resolveAssets(moduleUrl, manifest) {
465
493
  if (!entry) return null;
466
494
  const css = [];
467
495
  const js = [];
496
+ let preloads;
468
497
  const visited = new Set();
469
498
  const walk = key => {
470
499
  if (visited.has(key)) return;
@@ -473,13 +502,26 @@ function resolveAssets(moduleUrl, manifest) {
473
502
  if (!e) return;
474
503
  js.push(joinAssetPath(base, e.file));
475
504
  if (e.css) for (let i = 0; i < e.css.length; i++) css.push(joinAssetPath(base, e.css[i]));
505
+ if (e.preloads) {
506
+ for (let i = 0; i < e.preloads.length; i++) {
507
+ const link = e.preloads[i];
508
+ if (!link || typeof link.href !== "string" || !link.href) continue;
509
+ if (!preloads) preloads = [];
510
+ preloads.push({
511
+ ...link,
512
+ href: joinAssetPath(base, link.href)
513
+ });
514
+ }
515
+ }
476
516
  if (e.imports) for (let i = 0; i < e.imports.length; i++) walk(e.imports[i]);
477
517
  };
478
518
  walk(moduleUrl);
479
- return {
519
+ const assets = {
480
520
  js,
481
521
  css
482
522
  };
523
+ if (preloads) assets.preloads = preloads;
524
+ return assets;
483
525
  }
484
526
  function registerEntryAssets(manifest) {
485
527
  if (!manifest || typeof manifest === "function" || typeof manifest.resolve === "function") return;
@@ -489,6 +531,7 @@ function registerEntryAssets(manifest) {
489
531
  if (manifest[key].isEntry) {
490
532
  const assets = resolveAssets(key, manifest);
491
533
  if (assets) {
534
+ if (assets.preloads) for (let i = 0; i < assets.preloads.length; i++) ctx.registerAsset("preload", assets.preloads[i]);
492
535
  for (let i = 0; i < assets.css.length; i++) ctx.registerAsset("style", assets.css[i]);
493
536
  for (let i = 1; i < assets.js.length; i++) ctx.registerAsset("module", assets.js[i]);
494
537
  }
@@ -507,6 +550,7 @@ function createAssetTracking() {
507
550
  boundaryStyles,
508
551
  emittedAssets,
509
552
  inlineStyles,
553
+ preloadLinks: null,
510
554
  registerInlineStyle(desc) {
511
555
  let entry = inlineStyles.get(desc.id);
512
556
  if (!entry) {
@@ -598,6 +642,56 @@ function isCssUrl(url) {
598
642
  const q = url.search(/[?#]/);
599
643
  return (q === -1 ? url : url.slice(0, q)).endsWith(".css");
600
644
  }
645
+ const PRELOAD_LINK_ATTRIBUTES = ["type", "crossorigin", "integrity", "referrerpolicy", "fetchpriority", "media"];
646
+ function registerPreloadLink(tracking, headRegistry, link, nonce) {
647
+ if (!link || typeof link !== "object" || typeof link.href !== "string" || !link.href) {
648
+ return null;
649
+ }
650
+ if (typeof link.as !== "string") {
651
+ return null;
652
+ }
653
+ const as = asciiLowerCase(link.as);
654
+ let destination = null;
655
+ switch (as) {
656
+ case "script":
657
+ case "style":
658
+ destination = as;
659
+ break;
660
+ case "fetch":
661
+ case "font":
662
+ case "image":
663
+ case "track":
664
+ break;
665
+ default:
666
+ return null;
667
+ }
668
+ const props = {
669
+ rel: "preload",
670
+ href: link.href,
671
+ as
672
+ };
673
+ for (let i = 0; i < PRELOAD_LINK_ATTRIBUTES.length; i++) {
674
+ const name = PRELOAD_LINK_ATTRIBUTES[i];
675
+ const value = link[name];
676
+ if (value == null || value === false) continue;
677
+ props[name] = value === true ? "" : String(value);
678
+ }
679
+ const identity = resourceIdentity("link", props);
680
+ if (headRegistry.resources.has(identity)) return null;
681
+ const attrs = headAttrRecord(props);
682
+ const nonceValue = destination && nonce && nonce[destination];
683
+ if (typeof nonceValue === "string" && nonceValue) attrs.nonce = nonceValue;
684
+ const entry = {
685
+ href: props.href,
686
+ attrs,
687
+ attrHtml: renderHeadAttrHtml(props) + nonceAttr(nonce, destination)
688
+ };
689
+ headRegistry.resources.add(identity);
690
+ let links = tracking.preloadLinks;
691
+ if (!links) tracking.preloadLinks = links = [];
692
+ links.push(entry);
693
+ return entry;
694
+ }
601
695
  function createHeadRegistry() {
602
696
  return {
603
697
  pending: [],
@@ -1167,6 +1261,8 @@ function renderToStream(code, options = {}) {
1167
1261
  asset(type, value) {
1168
1262
  if (type === "module") {
1169
1263
  buffer.write(`<link rel="modulepreload" href="${value}"${nonceAttr(nonce, "script")}>`);
1264
+ } else if (type === "preload") {
1265
+ buffer.write(`<link${value.attrHtml}>`);
1170
1266
  } else if (type === "inline-style") {
1171
1267
  buffer.write(renderInlineStyle(value, nonce));
1172
1268
  } else if (type === "head-tag") {
@@ -1174,7 +1270,7 @@ function renderToStream(code, options = {}) {
1174
1270
  }
1175
1271
  },
1176
1272
  shell(shellHtml, meta) {
1177
- buffer.write(assembleDocument(shellHtml, meta.preloads, meta.inlineStyles, meta.tasks.length ? meta.tasks : "", nonce, meta.head, onHead));
1273
+ buffer.write(assembleDocument(shellHtml, meta.preloads, meta.preloadLinks, meta.inlineStyles, meta.tasks.length ? meta.tasks : "", nonce, meta.head, onHead));
1178
1274
  },
1179
1275
  ...options.sink
1180
1276
  };
@@ -1207,6 +1303,29 @@ function renderToStream(code, options = {}) {
1207
1303
  }
1208
1304
  };
1209
1305
  const registry = new Map();
1306
+ const pendingSerialized = new Map();
1307
+ const trackSerialized = (id, p) => {
1308
+ let settle;
1309
+ const raced = Promise.race([p, new Promise(r => settle = r)]);
1310
+ pendingSerialized.set(id, settle);
1311
+ const drop = () => pendingSerialized.delete(id);
1312
+ p.then(drop, drop);
1313
+ return raced;
1314
+ };
1315
+ const abandonSubtree = key => {
1316
+ for (const [k, entry] of registry) {
1317
+ if (k.length > key.length && k.startsWith(key)) {
1318
+ registry.delete(k);
1319
+ entry.resolve();
1320
+ }
1321
+ }
1322
+ for (const [id, settle] of pendingSerialized) {
1323
+ if (id.startsWith(key)) {
1324
+ pendingSerialized.delete(id);
1325
+ settle();
1326
+ }
1327
+ }
1328
+ };
1210
1329
  const writeTasks = () => {
1211
1330
  if (tasks.length && !completed && firstFlushed) {
1212
1331
  buffer.write(`<script${nonceAttr(nonce, "script")}>${tasks}</script>`);
@@ -1277,6 +1396,11 @@ function renderToStream(code, options = {}) {
1277
1396
  }, nonce, tags);
1278
1397
  },
1279
1398
  registerAsset(type, value) {
1399
+ if (type === "preload") {
1400
+ const entry = registerPreloadLink(tracking, headRegistry, value, nonce);
1401
+ if (entry && firstFlushed) sink.asset("preload", entry);
1402
+ return;
1403
+ }
1280
1404
  if (type === "inline-style") {
1281
1405
  const entry = tracking.registerInlineStyle(value);
1282
1406
  if (firstFlushed && !tracking.currentBoundaryId && !entry.emitted) {
@@ -1321,13 +1445,14 @@ function renderToStream(code, options = {}) {
1321
1445
  },
1322
1446
  serialize(id, p, deferStream) {
1323
1447
  if (sharedConfig.context.noHydrate) return;
1324
- if (!firstFlushed && p && typeof p === "object" && "then" in p) {
1325
- if (deferStream) {
1448
+ if (p && typeof p === "object" && typeof p.then === "function") {
1449
+ if (!firstFlushed && deferStream) {
1326
1450
  blockingPromises.add(p);
1327
1451
  p.then(d => serializer.write(id, d)).catch(e => serializer.write(id, e));
1328
1452
  return;
1329
1453
  }
1330
- if (canBatchStubs && !shellCompleted) {
1454
+ p = trackSerialized(id, p);
1455
+ if (!firstFlushed && canBatchStubs && !shellCompleted) {
1331
1456
  (stubBatch ||= new Map()).set(id, p);
1332
1457
  return;
1333
1458
  }
@@ -1372,6 +1497,7 @@ function renderToStream(code, options = {}) {
1372
1497
  if (registry.has(key)) {
1373
1498
  const item = registry.get(key);
1374
1499
  registry.delete(key);
1500
+ if (error) abandonSubtree(key);
1375
1501
  if (item.children) {
1376
1502
  for (const k in item.children) {
1377
1503
  value = replacePlaceholder(value, k, item.children[k]);
@@ -1496,6 +1622,7 @@ function renderToStream(code, options = {}) {
1496
1622
  const head = renderShellHead(headRegistry, nonce, k => registry.has(k), noScripts);
1497
1623
  sink.shell(resolveSSRSelectValues(html), {
1498
1624
  preloads: tracking.emittedAssets,
1625
+ preloadLinks: tracking.preloadLinks,
1499
1626
  inlineStyles: tracking.inlineStyles,
1500
1627
  tasks,
1501
1628
  head
@@ -2417,12 +2544,12 @@ function allSettled(promises) {
2417
2544
  return;
2418
2545
  });
2419
2546
  }
2420
- function assembleDocument(html, emittedAssets, inlineStyles, scripts, nonce, headTags, onHead) {
2547
+ function assembleDocument(html, emittedAssets, preloadLinks, inlineStyles, scripts, nonce, headTags, onHead) {
2421
2548
  const scriptTag = scripts ? `<script${nonceAttr(nonce, "script")}>${scripts}</script>` : "";
2422
2549
  const title = headTags ? headTags.title : null;
2423
2550
  let headTagsHtml = headTags ? headTags.html : "";
2424
2551
  const headPrelude = headTags ? headTags.prelude : "";
2425
- if (!onHead && title == null && !headTagsHtml && !headPrelude && !(emittedAssets && emittedAssets.size) && !(inlineStyles && inlineStyles.size)) {
2552
+ if (!onHead && title == null && !headTagsHtml && !headPrelude && !(emittedAssets && emittedAssets.size) && !preloadLinks && !(inlineStyles && inlineStyles.size)) {
2426
2553
  if (!scriptTag) return html;
2427
2554
  const xs = html.indexOf("<!--xs-->");
2428
2555
  return xs === -1 ? html + scriptTag : html.slice(0, xs) + scriptTag + html.slice(xs);
@@ -2441,7 +2568,7 @@ function assembleDocument(html, emittedAssets, inlineStyles, scripts, nonce, hea
2441
2568
  if (title != null) {
2442
2569
  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>`;
2443
2570
  }
2444
- onHead(headPrelude + headTagsHtml + titleHtml + renderHeadAssets(emittedAssets, inlineStyles, nonce));
2571
+ onHead(headPrelude + headTagsHtml + titleHtml + renderHeadAssets(emittedAssets, preloadLinks, inlineStyles, nonce));
2445
2572
  }
2446
2573
  if (!scriptTag) return html;
2447
2574
  const xs = html.indexOf("<!--xs-->");
@@ -2461,13 +2588,13 @@ function assembleDocument(html, emittedAssets, inlineStyles, scripts, nonce, hea
2461
2588
  headTagsHtml = `<title data-dh="title">${winner}</title>` + headTagsHtml;
2462
2589
  }
2463
2590
  }
2464
- const head = headTagsHtml + renderHeadAssets(emittedAssets, inlineStyles, nonce);
2591
+ const head = headTagsHtml + renderHeadAssets(emittedAssets, preloadLinks, inlineStyles, nonce);
2465
2592
  if (!scriptTag) return html.slice(0, headIdx) + head + html.slice(headIdx);
2466
2593
  const xsIdx = html.indexOf("<!--xs-->");
2467
2594
  if (xsIdx === -1) return html.slice(0, headIdx) + head + html.slice(headIdx) + scriptTag;
2468
2595
  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);
2469
2596
  }
2470
- function renderHeadAssets(emittedAssets, inlineStyles, nonce) {
2597
+ function renderHeadAssets(emittedAssets, preloadLinks, inlineStyles, nonce) {
2471
2598
  let head = "";
2472
2599
  const styleAttr = nonceAttr(nonce, "style");
2473
2600
  const scriptAttr = nonceAttr(nonce, "script");
@@ -2476,6 +2603,9 @@ function renderHeadAssets(emittedAssets, inlineStyles, nonce) {
2476
2603
  head += isCssUrl(url) ? `<link rel="stylesheet" href="${url}"${styleAttr}>` : `<link rel="modulepreload" href="${url}"${scriptAttr}>`;
2477
2604
  }
2478
2605
  }
2606
+ if (preloadLinks) {
2607
+ for (const entry of preloadLinks) head += `<link${entry.attrHtml}>`;
2608
+ }
2479
2609
  if (inlineStyles && inlineStyles.size) {
2480
2610
  for (const entry of inlineStyles.values()) {
2481
2611
  if (entry.emitted) continue;
@@ -2661,12 +2791,312 @@ function resolveSSRSync(node) {
2661
2791
  if (!res.h.length) return res.t[0];
2662
2792
  throw new Error("This value cannot be rendered synchronously. Are you missing a boundary?");
2663
2793
  }
2664
- /*#__PURE__*/new Set([ERROR_HEADER, BODY_FORMAT_HEADER, SINGLE_FLIGHT_HEADER, REVALIDATE_HEADER, "Location"].map(header => header.toLowerCase()));
2794
+ /*#__PURE__*/new Set([ERROR_HEADER, BODY_FORMAT_HEADER, SINGLE_FLIGHT_HEADER, REVALIDATE_HEADER, REDIRECT_HEADER, "Location",
2795
+ ...COMPOSED_BODY_FRAMING].map(header => header.toLowerCase()));
2665
2796
 
2797
+ function scopeDeferredResult(value, scope) {
2798
+ if (value === null || typeof value !== "object" && typeof value !== "function") return value;
2799
+ const promised = scope(() => nativePromise(value));
2800
+ if (promised) {
2801
+ return promised.then(result => scope(() => scopeDeferredResult(result, scope)));
2802
+ }
2803
+ if (typeof ReadableStream !== "undefined" && value instanceof ReadableStream) {
2804
+ let reader;
2805
+ return new ReadableStream({
2806
+ async pull(controller) {
2807
+ try {
2808
+ const step = await scope(() => {
2809
+ if (!reader) reader = value.getReader();
2810
+ return reader.read();
2811
+ });
2812
+ if (step.done) controller.close();else controller.enqueue(step.value);
2813
+ } catch (error) {
2814
+ controller.error(error);
2815
+ }
2816
+ },
2817
+ cancel(reason) {
2818
+ return scope(() => reader ? reader.cancel(reason) : value.cancel(reason));
2819
+ }
2820
+ }, {
2821
+ highWaterMark: 0
2822
+ });
2823
+ }
2824
+ const scopedIterator = symbol => ({
2825
+ [symbol]() {
2826
+ const iterator = scope(() => value[symbol]());
2827
+ return new Proxy(iterator, {
2828
+ get(target, property) {
2829
+ const member = Reflect.get(target, property, target);
2830
+ return typeof member === "function" && (property === "next" || property === "return" || property === "throw") ? (...args) => scope(() => member.apply(target, args)) : member;
2831
+ }
2832
+ });
2833
+ }
2834
+ });
2835
+ if (typeof value[Symbol.asyncIterator] === "function") {
2836
+ return scopedIterator(Symbol.asyncIterator);
2837
+ }
2838
+ if (typeof value[Symbol.iterator] === "function" && !Array.isArray(value) && !(value instanceof Map) && !(value instanceof Set) && !ArrayBuffer.isView(value)) {
2839
+ return scopedIterator(Symbol.iterator);
2840
+ }
2841
+ return value;
2842
+ }
2666
2843
  const INVOCATIONS = new WeakMap();
2667
2844
  function getEventServerFunctionInvocation(event) {
2668
2845
  return event && INVOCATIONS.get(event);
2669
2846
  }
2847
+ function guardFailures(value, state) {
2848
+ if (!state) state = {
2849
+ seen: new WeakMap(),
2850
+ cyclic: new WeakSet()
2851
+ };
2852
+ const entered = enterGuard(value, state);
2853
+ if (!(entered instanceof Frame)) return entered;
2854
+ const stack = [entered];
2855
+ let delivered = NOTHING;
2856
+ for (;;) {
2857
+ const top = stack[stack.length - 1];
2858
+ const items = top.items;
2859
+ let pushed = null;
2860
+ while (top.i < items.length) {
2861
+ const i = top.i;
2862
+ let original;
2863
+ if (top.kind === OBJECT) {
2864
+ const descriptor = top.descriptors[items[i]];
2865
+ if ("value" in descriptor) {
2866
+ original = descriptor.value;
2867
+ } else if (typeof descriptor.get === "function") {
2868
+ if (top.accessorRead !== i) {
2869
+ try {
2870
+ top.accessorValue = descriptor.get.call(top.value);
2871
+ } catch (error) {
2872
+ throw sanitizeServerError(error);
2873
+ }
2874
+ top.accessorRead = i;
2875
+ }
2876
+ original = top.accessorValue;
2877
+ } else {
2878
+ top.i++;
2879
+ continue;
2880
+ }
2881
+ } else {
2882
+ original = items[i];
2883
+ }
2884
+ let guarded;
2885
+ if (delivered !== NOTHING) {
2886
+ guarded = delivered;
2887
+ delivered = NOTHING;
2888
+ } else {
2889
+ guarded = enterGuard(original, state);
2890
+ if (guarded instanceof Frame) {
2891
+ pushed = guarded;
2892
+ break;
2893
+ }
2894
+ }
2895
+ if (top.kind === ARRAY) {
2896
+ if (guarded !== original) {
2897
+ top.next[i] = guarded;
2898
+ top.changed = true;
2899
+ }
2900
+ } else if (top.kind === MAP) {
2901
+ if ((i & 1) === 0) top.pendingKey = guarded;else top.next.set(top.pendingKey, guarded);
2902
+ if (guarded !== original) top.changed = true;
2903
+ } else if (top.kind === SET) {
2904
+ top.next.add(guarded);
2905
+ if (guarded !== original) top.changed = true;
2906
+ } else if (guarded !== original || top.accessorRead === i) {
2907
+ Object.defineProperty(top.next, items[i], {
2908
+ value: guarded,
2909
+ writable: true,
2910
+ configurable: true,
2911
+ enumerable: top.descriptors[items[i]].enumerable
2912
+ });
2913
+ top.changed = true;
2914
+ }
2915
+ top.i++;
2916
+ }
2917
+ if (pushed !== null) {
2918
+ stack.push(pushed);
2919
+ continue;
2920
+ }
2921
+ stack.pop();
2922
+ const out = keepGuarded(top.value, top.next, top.changed, state);
2923
+ if (stack.length === 0) return out;
2924
+ delivered = out;
2925
+ }
2926
+ }
2927
+ const NOTHING = Symbol();
2928
+ const ARRAY = 0;
2929
+ const MAP = 1;
2930
+ const SET = 2;
2931
+ const OBJECT = 3;
2932
+ class Frame {
2933
+ constructor(kind, value, next, items, descriptors) {
2934
+ this.kind = kind;
2935
+ this.value = value;
2936
+ this.next = next;
2937
+ this.items = items;
2938
+ this.descriptors = descriptors;
2939
+ this.i = 0;
2940
+ this.changed = false;
2941
+ this.accessorRead = -1;
2942
+ this.accessorValue = undefined;
2943
+ this.pendingKey = undefined;
2944
+ }
2945
+ }
2946
+ function guardOperation(state, run) {
2947
+ return state.scope ? state.scope(run) : run();
2948
+ }
2949
+ function enterGuard(value, state) {
2950
+ if (value === null || typeof value !== "object") return value;
2951
+ if (state.seen.has(value)) {
2952
+ state.cyclic.add(value);
2953
+ return state.seen.get(value);
2954
+ }
2955
+ if (typeof ReadableStream !== "undefined" && value instanceof ReadableStream) {
2956
+ let reader;
2957
+ const gate = state.gate;
2958
+ let finished = false;
2959
+ const close = () => {
2960
+ if (finished) return;
2961
+ finished = true;
2962
+ try {
2963
+ const cancelled = guardOperation(state, () => reader ? reader.cancel() : value.cancel());
2964
+ if (cancelled && typeof cancelled.then === "function") cancelled.then(undefined, () => {});
2965
+ } catch {}
2966
+ };
2967
+ const guardedStream = new ReadableStream({
2968
+ async pull(controller) {
2969
+ try {
2970
+ if (gate && !finished && !gate.wantsMore()) await gate.awaitDemand();
2971
+ if (finished) {
2972
+ controller.close();
2973
+ return;
2974
+ }
2975
+ if (!reader) reader = guardOperation(state, () => value.getReader());
2976
+ const {
2977
+ done,
2978
+ value: chunk
2979
+ } = await guardOperation(state, () => reader.read());
2980
+ done ? controller.close() : controller.enqueue(guardOperation(state, () => guardFailures(chunk, state)));
2981
+ } catch (error) {
2982
+ controller.error(guardOperation(state, () => sanitizeServerError(error)));
2983
+ }
2984
+ },
2985
+ cancel(reason) {
2986
+ finished = true;
2987
+ return guardOperation(state, () => reader ? reader.cancel(reason) : value.cancel(reason));
2988
+ }
2989
+ });
2990
+ if (gate) gate.onOpen(close);
2991
+ state.seen.set(value, guardedStream);
2992
+ return guardedStream;
2993
+ }
2994
+ if (typeof value.then === "function") {
2995
+ const guardedPromise = Promise.resolve(value).then(resolved => guardOperation(state, () => guardFailures(resolved, state)), error => {
2996
+ throw guardOperation(state, () => sanitizeServerError(error));
2997
+ });
2998
+ guardedPromise.catch(() => {});
2999
+ state.seen.set(value, guardedPromise);
3000
+ return guardedPromise;
3001
+ }
3002
+ if (typeof value[Symbol.asyncIterator] === "function") {
3003
+ const source = value;
3004
+ const gate = state.gate;
3005
+ const guardedIterable = {
3006
+ [Symbol.asyncIterator]() {
3007
+ const iterator = guardOperation(state, () => source[Symbol.asyncIterator]());
3008
+ let finished = false;
3009
+ const close = () => {
3010
+ if (finished) return;
3011
+ finished = true;
3012
+ try {
3013
+ const returned = iterator.return && guardOperation(state, () => iterator.return());
3014
+ if (returned && typeof returned.then === "function") returned.then(undefined, () => {});
3015
+ } catch {}
3016
+ };
3017
+ if (gate) gate.onOpen(close);
3018
+ const step = () => finished ? Promise.resolve({
3019
+ done: true,
3020
+ value: undefined
3021
+ }) : guardOperation(state, () => iterator.next()).then(step => {
3022
+ if (step.done) {
3023
+ finished = true;
3024
+ return step;
3025
+ }
3026
+ return {
3027
+ done: false,
3028
+ value: guardOperation(state, () => guardFailures(step.value, state))
3029
+ };
3030
+ }, error => {
3031
+ throw guardOperation(state, () => sanitizeServerError(error));
3032
+ });
3033
+ return {
3034
+ next: () => finished || !gate || gate.wantsMore() ? step() : gate.awaitDemand().then(step),
3035
+ return: () => {
3036
+ close();
3037
+ return Promise.resolve({
3038
+ done: true,
3039
+ value: undefined
3040
+ });
3041
+ }
3042
+ };
3043
+ }
3044
+ };
3045
+ state.seen.set(value, guardedIterable);
3046
+ return guardedIterable;
3047
+ }
3048
+ if (state.scope && typeof value[Symbol.iterator] === "function" && !Array.isArray(value) && !(value instanceof Map) && !(value instanceof Set) && !ArrayBuffer.isView(value)) {
3049
+ const scopedIterable = scopeDeferredResult(value, state.scope);
3050
+ state.seen.set(value, scopedIterable);
3051
+ return scopedIterable;
3052
+ }
3053
+ if (Array.isArray(value)) {
3054
+ const next = value.slice();
3055
+ state.seen.set(value, next);
3056
+ return new Frame(ARRAY, value, next, value, null);
3057
+ }
3058
+ if (value instanceof Map) {
3059
+ const next = new Map();
3060
+ state.seen.set(value, next);
3061
+ const items = [];
3062
+ for (const entry of value) items.push(entry[0], entry[1]);
3063
+ return new Frame(MAP, value, next, items, null);
3064
+ }
3065
+ if (value instanceof Set) {
3066
+ const next = new Set();
3067
+ state.seen.set(value, next);
3068
+ return new Frame(SET, value, next, [...value], null);
3069
+ }
3070
+ const prototype = Object.getPrototypeOf(value);
3071
+ if (prototype !== Object.prototype && prototype !== null) {
3072
+ state.seen.set(value, value);
3073
+ return value;
3074
+ }
3075
+ const descriptors = Object.getOwnPropertyDescriptors(value);
3076
+ for (const key of Object.keys(descriptors)) {
3077
+ descriptors[key].configurable = true;
3078
+ if ("value" in descriptors[key]) descriptors[key].writable = true;
3079
+ }
3080
+ const next = Object.create(prototype, descriptors);
3081
+ state.seen.set(value, next);
3082
+ return new Frame(OBJECT, value, next, Object.keys(value), descriptors);
3083
+ }
3084
+ function keepGuarded(value, next, changed, state) {
3085
+ if (changed || state.cyclic.has(value)) return next;
3086
+ state.seen.set(value, value);
3087
+ return value;
3088
+ }
3089
+ const GENERIC_SERVER_ERROR_MESSAGE = "Internal Server Error";
3090
+ function sanitizeServerError(value) {
3091
+ if (isSafeError(value)) return value;
3092
+ return new Error(GENERIC_SERVER_ERROR_MESSAGE);
3093
+ }
3094
+ function nativePromise(value) {
3095
+ if (value instanceof Promise) return value;
3096
+ try {
3097
+ if (Object.prototype.toString.call(value) === "[object Promise]") return Promise.prototype.then.call(value, value => value);
3098
+ } catch {}
3099
+ }
2670
3100
 
2671
3101
  const FRAME_STREAM_HEADER = "X-Frame-Stream";
2672
3102
  function isFrameStreamResponse(response) {
@@ -2736,6 +3166,12 @@ function serverOwned(render) {
2736
3166
  function serverComponentScope(render) {
2737
3167
  return runInServerComponentScope ? runInServerComponentScope(render) : render();
2738
3168
  }
3169
+ function wirePreload(entry) {
3170
+ return {
3171
+ href: entry.href,
3172
+ attrs: entry.attrs
3173
+ };
3174
+ }
2739
3175
  const SERVER_COMPONENT_BOOTSTRAP_EXPR = "(self._$SC||(self._$SC={c:{},a:{},r(i,a){a&&(this.a[a]=i,this.reg&&this.reg(a,i));return this.c[i]||(this.c[i]=(p,b)=>self._$SC.impl(i,p,b))}}))";
2740
3176
  const bootstrappedScripts = new WeakSet();
2741
3177
  setServerComponentBootstrap(ctx => {
@@ -2780,20 +3216,28 @@ function createFrameSink(emit, frame) {
2780
3216
  if (!regionKeys.has(key)) regionKeys.set(key, childId);
2781
3217
  },
2782
3218
  shell(html, meta = {}) {
2783
- if (meta.preloads && meta.preloads.size) {
2784
- const styles = [];
2785
- const modules = [];
2786
- for (const url of meta.preloads) {
2787
- (url.endsWith(".css") ? styles : modules).push(url);
2788
- }
3219
+ if (meta.preloads && meta.preloads.size || meta.preloadLinks) {
2789
3220
  const chunk = {
2790
3221
  type: "assets",
2791
3222
  id,
2792
3223
  version,
2793
3224
  key: ""
2794
3225
  };
2795
- if (styles.length) chunk.styles = styles;
2796
- if (modules.length) chunk.modules = modules;
3226
+ if (meta.preloads && meta.preloads.size) {
3227
+ const styles = [];
3228
+ const modules = [];
3229
+ for (const url of meta.preloads) {
3230
+ (url.endsWith(".css") ? styles : modules).push(url);
3231
+ }
3232
+ if (styles.length) chunk.styles = styles;
3233
+ if (modules.length) chunk.modules = modules;
3234
+ }
3235
+ if (meta.preloadLinks) {
3236
+ chunk.preloads = [];
3237
+ for (const entry of meta.preloadLinks) {
3238
+ chunk.preloads.push(wirePreload(entry));
3239
+ }
3240
+ }
2797
3241
  emit(chunk);
2798
3242
  }
2799
3243
  emit({
@@ -2905,15 +3349,24 @@ function createFrameSink(emit, frame) {
2905
3349
  emit(chunk);
2906
3350
  }
2907
3351
  },
2908
- asset(type, url) {
2909
- if (type !== "module") return;
2910
- emit({
2911
- type: "assets",
2912
- id,
2913
- version,
2914
- key: "",
2915
- modules: [url]
2916
- });
3352
+ asset(type, value) {
3353
+ if (type === "module") {
3354
+ emit({
3355
+ type: "assets",
3356
+ id,
3357
+ version,
3358
+ key: "",
3359
+ modules: [value]
3360
+ });
3361
+ } else if (type === "preload") {
3362
+ emit({
3363
+ type: "assets",
3364
+ id,
3365
+ version,
3366
+ key: "",
3367
+ preloads: [wirePreload(value)]
3368
+ });
3369
+ }
2917
3370
  },
2918
3371
  end() {
2919
3372
  if (bindings.size) sweep();
@@ -3837,7 +4290,7 @@ function frameFlightResponse({
3837
4290
  });
3838
4291
  }
3839
4292
  if (outcome) {
3840
- const reader = new ChunkReader(serializeStream(outcome, flightCodec(codec)));
4293
+ const reader = new ChunkReader(serializeStream(guardFailures(outcome), flightCodec(codec)));
3841
4294
  for (let node = await reader.next(); !node.done; node = await reader.next()) {
3842
4295
  write({
3843
4296
  type: "outcome",