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