@solidjs/web 2.0.0-beta.30 → 2.0.0-beta.32

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 (66) hide show
  1. package/README.md +1 -6
  2. package/dist/dev.cjs +284 -82
  3. package/dist/dev.js +271 -79
  4. package/dist/server.cjs +555 -135
  5. package/dist/server.js +544 -132
  6. package/dist/web.cjs +281 -79
  7. package/dist/web.js +268 -76
  8. package/frames/dist/client.cjs +413 -360
  9. package/frames/dist/client.dev.cjs +413 -360
  10. package/frames/dist/client.dev.js +414 -361
  11. package/frames/dist/client.js +414 -361
  12. package/frames/dist/server.cjs +604 -199
  13. package/frames/dist/server.js +605 -201
  14. package/package.json +56 -6
  15. package/serialization/dist/serialization.cjs +8 -0
  16. package/serialization/dist/serialization.js +1 -0
  17. package/serialization/types/index.d.ts +173 -6
  18. package/serialization/types-cjs/index.d.cts +173 -6
  19. package/server-functions/dist/client.cjs +46 -9
  20. package/server-functions/dist/client.js +47 -11
  21. package/server-functions/dist/rich-args.cjs +11 -0
  22. package/server-functions/dist/rich-args.js +9 -0
  23. package/server-functions/dist/server.cjs +275 -126
  24. package/server-functions/dist/server.dev.cjs +1053 -0
  25. package/server-functions/dist/server.dev.js +1021 -0
  26. package/server-functions/dist/server.js +273 -127
  27. package/server-functions/package.json +10 -0
  28. package/server-functions/rich-args/package.json +20 -0
  29. package/storage/types/index.d.ts +1 -1
  30. package/storage/types-cjs/index.d.cts +1 -1
  31. package/types/client.d.ts +134 -11
  32. package/types/core.d.ts +3 -1
  33. package/types/frames/client.d.ts +24 -8
  34. package/types/frames/frame-client.d.ts +49 -7
  35. package/types/frames/frame-sink.d.ts +32 -6
  36. package/types/frames/frame-transport.d.ts +88 -62
  37. package/types/frames/serializer.d.ts +173 -6
  38. package/types/frames/server.d.ts +22 -0
  39. package/types/index.d.ts +2 -3
  40. package/types/jsx.d.ts +3 -3
  41. package/types/response.d.ts +45 -0
  42. package/types/serializer.d.ts +173 -6
  43. package/types/server-functions/client.d.ts +1 -0
  44. package/types/server-functions/rich-args.d.ts +10 -0
  45. package/types/server-functions/server.d.ts +98 -0
  46. package/types/server-functions/shared.d.ts +22 -0
  47. package/types/server-mock.d.ts +171 -59
  48. package/types/server.d.ts +196 -42
  49. package/types-cjs/client.d.cts +134 -11
  50. package/types-cjs/core.d.cts +3 -1
  51. package/types-cjs/frames/client.d.cts +24 -8
  52. package/types-cjs/frames/frame-client.d.cts +49 -7
  53. package/types-cjs/frames/frame-sink.d.cts +32 -6
  54. package/types-cjs/frames/frame-transport.d.cts +88 -62
  55. package/types-cjs/frames/serializer.d.cts +173 -6
  56. package/types-cjs/frames/server.d.cts +22 -0
  57. package/types-cjs/index.d.cts +2 -3
  58. package/types-cjs/jsx.d.cts +3 -3
  59. package/types-cjs/response.d.cts +45 -0
  60. package/types-cjs/serializer.d.cts +173 -6
  61. package/types-cjs/server-functions/client.d.cts +1 -0
  62. package/types-cjs/server-functions/rich-args.d.cts +10 -0
  63. package/types-cjs/server-functions/server.d.cts +98 -0
  64. package/types-cjs/server-functions/shared.d.cts +22 -0
  65. package/types-cjs/server-mock.d.cts +171 -59
  66. package/types-cjs/server.d.cts +196 -42
@@ -7,6 +7,9 @@ var web = require('seroval-plugins/web');
7
7
  const runWithHydrationScope = (id, fn) => solidJs.runWithOwner(solidJs.createOwner({
8
8
  id
9
9
  }), fn);
10
+ const ssrAsyncValue = value => solidJs.createMemo(() => value, {
11
+ serialize: false
12
+ });
10
13
 
11
14
  const DEFAULT_DISABLED_FEATURES = seroval.Feature.AggregateError | seroval.Feature.BigIntTypedArray;
12
15
  const serializeOnlyDisabledFeatures = () => process.env.NODE_ENV === "development" ? 0 : seroval.Feature.ErrorPrototypeStack;
@@ -137,9 +140,146 @@ function createJSONSerializer({
137
140
  };
138
141
  }
139
142
 
143
+ const ENVELOPE = Symbol.for("solid.ResponseEnvelope");
144
+ function isResponseEnvelope(value) {
145
+ return !!(value && typeof value === "object" && value[ENVELOPE]);
146
+ }
147
+ const REVALIDATE_HEADER = "X-Revalidate";
148
+
149
+ function frameAddress(id, args) {
150
+ return args && args.length ? id + ":" + hashArguments(args) : id;
151
+ }
152
+ function hashArguments(args) {
153
+ let hash = 0;
154
+ const text = stableString(args);
155
+ for (let i = 0; i < text.length; i++) {
156
+ hash = (hash << 5) - hash + text.charCodeAt(i);
157
+ hash |= 0;
158
+ }
159
+ return (hash >>> 0).toString(36);
160
+ }
161
+ function stableString(value, seen) {
162
+ if (value === null || typeof value !== "object") {
163
+ return typeof value === "bigint" ? value + "n" : String(value);
164
+ }
165
+ if (value instanceof Date) return "Date:" + value.getTime();
166
+ seen || (seen = new Set());
167
+ if (seen.has(value)) return "~";
168
+ seen.add(value);
169
+ if (value instanceof Map) {
170
+ const entries = [];
171
+ for (const [k, v] of value) {
172
+ entries.push(stableString(k, seen) + "=>" + stableString(v, seen));
173
+ }
174
+ return "Map{" + entries.sort().join(",") + "}";
175
+ }
176
+ if (value instanceof Set) {
177
+ const members = [];
178
+ for (const v of value) members.push(stableString(v, seen));
179
+ return "Set{" + members.sort().join(",") + "}";
180
+ }
181
+ if (Array.isArray(value)) {
182
+ let out = "[";
183
+ for (let i = 0; i < value.length; i++) out += (i ? "," : "") + stableString(value[i], seen);
184
+ return out + "]";
185
+ }
186
+ const keys = Object.keys(value).sort();
187
+ let out = "{";
188
+ for (let i = 0; i < keys.length; i++) {
189
+ out += (i ? "," : "") + keys[i] + ":" + stableString(value[keys[i]], seen);
190
+ }
191
+ return out + "}";
192
+ }
193
+ const ERROR_HEADER = "X-Server-Function-Error";
194
+ const BODY_FORMAT_HEADER = "X-Server-Function-Format";
195
+ const SINGLE_FLIGHT_HEADER = "X-Single-Flight";
196
+ function createChunk(data) {
197
+ const encoder = new TextEncoder();
198
+ const encodeData = encoder.encode(data);
199
+ const bytes = encodeData.length;
200
+ const chunk = new Uint8Array(12 + bytes);
201
+ chunk.set(encoder.encode(`;0x${bytes.toString(16).padStart(8, "0")};`));
202
+ chunk.set(encodeData, 12);
203
+ return chunk;
204
+ }
205
+ class ChunkReader {
206
+ constructor(stream) {
207
+ this.reader = stream.getReader();
208
+ this.buffer = new Uint8Array(0);
209
+ this.done = false;
210
+ }
211
+ async readChunk() {
212
+ const chunk = await this.reader.read();
213
+ if (!chunk.done) {
214
+ const newBuffer = new Uint8Array(this.buffer.length + chunk.value.length);
215
+ newBuffer.set(this.buffer);
216
+ newBuffer.set(chunk.value, this.buffer.length);
217
+ this.buffer = newBuffer;
218
+ } else {
219
+ this.done = true;
220
+ }
221
+ }
222
+ async next() {
223
+ while (this.buffer.length < 12) {
224
+ if (this.done) {
225
+ if (this.buffer.length === 0) return {
226
+ done: true,
227
+ value: undefined
228
+ };
229
+ throw new Error("Malformed server function stream.");
230
+ }
231
+ await this.readChunk();
232
+ }
233
+ const decoder = new TextDecoder();
234
+ const bytes = Number.parseInt(decoder.decode(this.buffer.subarray(1, 11)), 16);
235
+ if (Number.isNaN(bytes)) {
236
+ throw new Error("Malformed server function stream.");
237
+ }
238
+ while (bytes > this.buffer.length - 12) {
239
+ if (this.done) {
240
+ throw new Error("Malformed server function stream.");
241
+ }
242
+ await this.readChunk();
243
+ }
244
+ const partial = decoder.decode(this.buffer.subarray(12, 12 + bytes));
245
+ this.buffer = this.buffer.subarray(12 + bytes);
246
+ return {
247
+ done: false,
248
+ value: partial
249
+ };
250
+ }
251
+ async drain(interpret) {
252
+ while (true) {
253
+ const result = await this.next();
254
+ if (result.done) {
255
+ break;
256
+ }
257
+ interpret(result.value);
258
+ }
259
+ }
260
+ }
261
+ function serializeStream(value, codecOptions) {
262
+ return new ReadableStream({
263
+ start(controller) {
264
+ serializeJSON(value, {
265
+ ...codecOptions,
266
+ onParse(node) {
267
+ controller.enqueue(createChunk(JSON.stringify(node)));
268
+ },
269
+ onDone() {
270
+ controller.close();
271
+ },
272
+ onError(error) {
273
+ controller.error(error);
274
+ }
275
+ });
276
+ }
277
+ });
278
+ }
279
+
140
280
  const HEAD_ELIGIBLE_TAGS = new Set(["title", "meta", "link", "style", "script", "base"]);
141
281
  const HEAD_ATTR_NAME = /^[a-zA-Z_][a-zA-Z0-9_:.-]*$/;
142
- const RESOURCE_LINK_RELS = new Set(["preload", "modulepreload", "prefetch", "preconnect", "dns-prefetch", "icon", "stylesheet"]);
282
+ const RESOURCE_LINK_RELS = new Set(["preload", "modulepreload", "prefetch", "preconnect", "dns-prefetch", "stylesheet"]);
143
283
  const RESOURCE_QUALIFIERS = ["as", "crossorigin", "type", "media", "imagesrcset", "imagesizes"];
144
284
  const STYLESHEET_FETCH_META = new Set(["crossorigin", "integrity", "referrerpolicy", "fetchpriority"]);
145
285
  function evalHeadValue(v) {
@@ -183,12 +323,14 @@ function replaceableIdentity(tag, props, key, unique) {
183
323
  if (tag === "meta" && props.charset != null) return "charset";
184
324
  if (key != null) return tag + ":key:" + key;
185
325
  if (tag === "meta") {
186
- if (props.name != null) return "meta:name:" + props.name;
187
- if (props.property != null) return "meta:property:" + props.property;
188
- if (props["http-equiv"] != null) return "meta:http-equiv:" + props["http-equiv"];
326
+ for (const ns of ["name", "property", "http-equiv"]) if (props[ns] != null) return "meta:" + ns + ":" + props[ns] + (props.media != null ? ":media=" + props.media : "");
189
327
  return unique;
190
328
  }
191
- if (tag === "link") return "link:" + (props.rel || "") + ":" + (props.href || "");
329
+ if (tag === "link") {
330
+ const rel = props.rel || "";
331
+ if (rel === "icon" || rel === "apple-touch-icon") return "link:" + rel + (props.sizes != null ? ":sizes=" + props.sizes : "") + (props.type != null ? ":type=" + props.type : "");
332
+ return "link:" + rel + ":" + (props.href || "");
333
+ }
192
334
  return unique;
193
335
  }
194
336
  function resolveHead(groups) {
@@ -375,11 +517,22 @@ function createHeadRegistry() {
375
517
  resources: new Set(),
376
518
  eagerHtml: "",
377
519
  flushed: null,
378
- shellFlushed: false
520
+ shellFlushed: false,
521
+ parkedResources: []
379
522
  };
380
523
  }
381
524
  function registerHeadTags(registry, context, tracking, emitResource, nonce, tags) {
382
525
  const boundary = context._currentBoundaryId || "";
526
+ if (typeof tags === "function") {
527
+ registry.pending.push({
528
+ boundary,
529
+ list: tags,
530
+ resource: (desc, rel) => emitHeadResource(registry, context, tracking, emitResource, nonce, desc, rel)
531
+ });
532
+ return;
533
+ }
534
+ if (!Array.isArray(tags)) tags = [tags];
535
+ const probe = solidJs.sharedConfig.context && solidJs.sharedConfig.context._loadingPhase;
383
536
  let replaceable = null;
384
537
  for (let i = 0; i < tags.length; i++) {
385
538
  const desc = tags[i];
@@ -388,6 +541,16 @@ function registerHeadTags(registry, context, tracking, emitResource, nonce, tags
388
541
  continue;
389
542
  }
390
543
  const cls = classifyHeadTag(desc);
544
+ if (probe && !cls.resource) {
545
+ try {
546
+ evalHeadProps(desc.props || {}, cls.rel !== undefined ? {
547
+ rel: cls.rel
548
+ } : undefined);
549
+ evalHeadValue(desc.key);
550
+ } catch (err) {
551
+ if (solidJs.ssrHandleError(err)) throw err;
552
+ }
553
+ }
391
554
  if (cls.resource) {
392
555
  emitHeadResource(registry, context, tracking, emitResource, nonce, desc, cls.rel);
393
556
  } else {
@@ -404,6 +567,52 @@ function registerHeadTags(registry, context, tracking, emitResource, nonce, tags
404
567
  tags: replaceable
405
568
  });
406
569
  }
570
+ function headShellReady(registry, block) {
571
+ let ready = true;
572
+ const pends = err => {
573
+ const source = solidJs.ssrHandleError(err, true);
574
+ if (!source) return false;
575
+ block(source);
576
+ ready = false;
577
+ return true;
578
+ };
579
+ const parked = registry.parkedResources;
580
+ for (let i = parked.length - 1; i >= 0; i--) {
581
+ const {
582
+ desc,
583
+ rel,
584
+ emit
585
+ } = parked[i];
586
+ try {
587
+ evalHeadProps(desc.props || {}, rel !== undefined ? {
588
+ rel
589
+ } : undefined);
590
+ } catch (err) {
591
+ if (pends(err)) continue;
592
+ console.warn(`useHead: error evaluating resource tag props`, err);
593
+ parked.splice(i, 1);
594
+ continue;
595
+ }
596
+ parked.splice(i, 1);
597
+ emit();
598
+ }
599
+ for (let i = 0; i < registry.pending.length; i++) {
600
+ const reg = registry.pending[i];
601
+ if (reg.boundary !== "" || reg.list) continue;
602
+ for (let j = 0; j < reg.tags.length; j++) {
603
+ const desc = reg.tags[j];
604
+ try {
605
+ evalHeadProps(desc.props || {}, desc.rel !== undefined ? {
606
+ rel: desc.rel
607
+ } : undefined);
608
+ evalHeadValue(desc.key);
609
+ } catch (err) {
610
+ pends(err);
611
+ }
612
+ }
613
+ }
614
+ return ready;
615
+ }
407
616
  function emitHeadResource(registry, context, tracking, emitResource, nonce, desc, rel) {
408
617
  let props;
409
618
  try {
@@ -411,6 +620,16 @@ function emitHeadResource(registry, context, tracking, emitResource, nonce, desc
411
620
  rel
412
621
  } : undefined);
413
622
  } catch (err) {
623
+ const loadingPhase = solidJs.sharedConfig.context && solidJs.sharedConfig.context._loadingPhase;
624
+ if (loadingPhase && solidJs.ssrHandleError(err)) throw err;
625
+ if (!loadingPhase && !context._currentBoundaryId && !registry.shellFlushed && typeof context.block === "function" && solidJs.ssrHandleError(err, true)) {
626
+ registry.parkedResources.push({
627
+ desc,
628
+ rel,
629
+ emit: () => emitHeadResource(registry, context, tracking, emitResource, nonce, desc, rel)
630
+ });
631
+ return;
632
+ }
414
633
  console.warn(`useHead: error evaluating resource tag props`, err);
415
634
  return;
416
635
  }
@@ -467,9 +686,39 @@ function commitHeadBoundary(registry, boundary, isPendingFragment) {
467
686
  keep.push(reg);
468
687
  continue;
469
688
  }
689
+ let descs = reg.tags;
690
+ if (reg.list) {
691
+ let resolved;
692
+ try {
693
+ resolved = reg.list();
694
+ } catch (err) {
695
+ console.warn(`useHead: error evaluating head group membership`, err);
696
+ continue;
697
+ }
698
+ if (!Array.isArray(resolved)) resolved = [resolved];
699
+ descs = [];
700
+ for (let j = 0; j < resolved.length; j++) {
701
+ const desc = resolved[j];
702
+ if (!desc || !HEAD_ELIGIBLE_TAGS.has(desc.tag)) {
703
+ console.warn(`useHead: ignoring non-head tag`, desc);
704
+ continue;
705
+ }
706
+ const cls = classifyHeadTag(desc);
707
+ if (cls.resource) {
708
+ reg.resource(desc, cls.rel);
709
+ } else {
710
+ descs.push(cls.rel !== undefined ? {
711
+ tag: desc.tag,
712
+ props: desc.props,
713
+ key: desc.key,
714
+ rel: cls.rel
715
+ } : desc);
716
+ }
717
+ }
718
+ }
470
719
  const tags = [];
471
- for (let j = 0; j < reg.tags.length; j++) {
472
- const desc = reg.tags[j];
720
+ for (let j = 0; j < descs.length; j++) {
721
+ const desc = descs[j];
473
722
  let props, key;
474
723
  try {
475
724
  props = evalHeadProps(desc.props || {}, desc.rel !== undefined ? {
@@ -612,7 +861,7 @@ function renderHeadTagMarkup(tag, props, identity, nonce) {
612
861
  if (tag === "script") body = body.replace(/<\/(script)/gi, "<\\/$1");else if (tag === "style") body = escapeStyleContent(body);else body = escape(body);
613
862
  return `<${tag}${attrs}>${body}</${tag}>`;
614
863
  }
615
- const REPLACE_SCRIPT = `function $df(e){return _$HY.f?_$HY.f(e):$dfr(e)}function $dfr(e,n,o,t){if(!(n=document.getElementById(e)))return 0;if(!(o=document.getElementById("pl-"+e)))return(_$HY.dq=_$HY.dq||{})[e]=1,0;for(;o&&(8!==o.nodeType||o.nodeValue!=="pl-"+e);)t=o.nextSibling,o.remove(),o=t;t=o.parentNode,o.replaceWith(n.content),n.remove(),_$HY.fe(e,t),_$HY.hp&&_$HY.hp[e]&&($dh(_$HY.hp[e]),delete _$HY.hp[e]),$dfd();return 1}function $dfl(e,o,n){if(!(o=document.getElementById("pl-"+e)))return(_$HY.dlq=_$HY.dlq||{})[e]=1,0;if(o._$fl)return 1;for(n=o.nextSibling;n;){if(8===n.nodeType&&n.nodeValue==="pl-"+e){o.parentNode&&o.parentNode.insertBefore(o.content.cloneNode(!0),n),o._$fl=1,$dfd();return 1}n=n.nextSibling}return 0}function $dflj(e,i){for(i=0;i<e.length;i++)$dfl(e[i])}function $dfd(e,i){if(e=_$HY.dq){_$HY.dq=0;for(i in e)$df(i)}if(e=_$HY.dlq){_$HY.dlq=0;for(i in e)$dfl(i)}}function $dfs(e,c,d){(_$HY.sc=_$HY.sc||{})[e]=c,d&&((_$HY.sd=_$HY.sd||{})[e]=1)}function $dfg(e,g,i,k){if(!(g=_$HY.sg&&_$HY.sg[e]))return;for(i=0;i<g.length;i++)if(_$HY.sc&&_$HY.sc[g[i]]>0)return;for(i=0;i<g.length;i++)k=g[i],delete _$HY.sg[k],$df(k)}function $dfc(e){if(--_$HY.sc[e]<=0){delete _$HY.sc[e],_$HY.sg&&_$HY.sg[e]?$dfg(e):!(_$HY.sd&&_$HY.sd[e])&&$df(e);_$HY.sd&&delete _$HY.sd[e]}}function $dfj(e,i,n){for(i=0;i<e.length;i++)if(_$HY.sc&&_$HY.sc[e[i]]>0){for(n=0;n<e.length;n++)(_$HY.sg=_$HY.sg||{})[e[n]]=e;return}for(i=0;i<e.length;i++)$df(e[i])}`;
864
+ const REPLACE_SCRIPT = `function $df(e){return _$HY.f?_$HY.f(e):$dfr(e)}function $dfr(e,n,o,t){if(!(n=document.getElementById(e)))return 0;if(!(o=document.getElementById("pl-"+e)))return(_$HY.dq=_$HY.dq||{})[e]=1,0;for(;o&&(8!==o.nodeType||o.nodeValue!=="pl-"+e);)t=o.nextSibling,o.remove(),o=t;t=o.parentNode,o.replaceWith(n.content),n.remove(),(_$HY.v=_$HY.v||{})[e]=1,_$HY.fe(e,t),_$HY.hp&&_$HY.hp[e]&&($dh(_$HY.hp[e]),delete _$HY.hp[e]),$dfd();return 1}function $dfl(e,o,n){if(!(o=document.getElementById("pl-"+e)))return(_$HY.dlq=_$HY.dlq||{})[e]=1,0;if(o._$fl)return 1;for(n=o.nextSibling;n;){if(8===n.nodeType&&n.nodeValue==="pl-"+e){o.parentNode&&o.parentNode.insertBefore(o.content.cloneNode(!0),n),o._$fl=1,$dfd();return 1}n=n.nextSibling}return 0}function $dflj(e,i){for(i=0;i<e.length;i++)$dfl(e[i])}function $dfd(e,i){if(e=_$HY.dq){_$HY.dq=0;for(i in e)$df(i)}if(e=_$HY.dlq){_$HY.dlq=0;for(i in e)$dfl(i)}}function $dfs(e,c,d){(_$HY.sc=_$HY.sc||{})[e]=c,d&&((_$HY.sd=_$HY.sd||{})[e]=1)}function $dfg(e,g,i,k){if(!(g=_$HY.sg&&_$HY.sg[e]))return;for(i=0;i<g.length;i++)if(_$HY.sc&&_$HY.sc[g[i]]>0)return;for(i=0;i<g.length;i++)k=g[i],delete _$HY.sg[k],$df(k)}function $dfc(e){if(--_$HY.sc[e]<=0){delete _$HY.sc[e],_$HY.sg&&_$HY.sg[e]?$dfg(e):!(_$HY.sd&&_$HY.sd[e])&&$df(e);_$HY.sd&&delete _$HY.sd[e]}}function $dfj(e,i,n){for(i=0;i<e.length;i++)if(_$HY.sc&&_$HY.sc[e[i]]>0){for(n=0;n<e.length;n++)(_$HY.sg=_$HY.sg||{})[e[n]]=e;return}for(i=0;i<e.length;i++)$df(e[i])}`;
616
865
  const HEAD_SCRIPT = `function $dha(o,i,e,n){for(i=0;i<o.length;i++)e=o[i],"t"==e[0]?((n=document.querySelector("title"))||(n=document.createElement("title"),document.head.appendChild(n)),n.textContent=e[1],n.setAttribute("data-dh","title")):"r"==e[0]?$dhr(e[1]):(n=document.createElement(e[2]),Object.keys(e[3]).forEach(function(a){n.setAttribute(a,e[3][a])}),null!=e[4]&&(n.textContent=e[4]),n.setAttribute("data-dh",e[1]),document.head.appendChild(n))}function $dhr(v,l,i){for(l=document.head.querySelectorAll("[data-dh]"),i=0;i<l.length;i++)l[i].getAttribute("data-dh")==v&&l[i].remove()}function $dh(o){_$HY.h?_$HY.h(o):$dha(o)}`;
617
866
  function renderToStream(code, options = {}) {
618
867
  let {
@@ -625,6 +874,41 @@ function renderToStream(code, options = {}) {
625
874
  onHead
626
875
  } = options;
627
876
  let dispose;
877
+ let dead = false;
878
+ const abandon = () => {
879
+ if (dead) return;
880
+ dead = true;
881
+ completed = true;
882
+ buffer = {
883
+ write() {}
884
+ };
885
+ writable = {
886
+ end() {}
887
+ };
888
+ if (dispose) {
889
+ const d = dispose;
890
+ dispose = () => {};
891
+ d();
892
+ }
893
+ };
894
+ const guardSink = w => ({
895
+ write(payload) {
896
+ if (dead) return;
897
+ try {
898
+ w.write(payload);
899
+ } catch (_) {
900
+ abandon();
901
+ }
902
+ },
903
+ end() {
904
+ if (dead) return;
905
+ try {
906
+ w.end();
907
+ } catch (_) {
908
+ abandon();
909
+ }
910
+ }
911
+ });
628
912
  const blockingPromises = new Set();
629
913
  let headerEmitted = false;
630
914
  const pushTask = task => {
@@ -688,7 +972,7 @@ function renderToStream(code, options = {}) {
688
972
  }
689
973
  },
690
974
  shell(shellHtml, meta) {
691
- buffer.write(assembleDocument(shellHtml, meta.assets, meta.preloads, meta.inlineStyles, meta.tasks.length ? meta.tasks : "", nonce, meta.head, onHead));
975
+ buffer.write(assembleDocument(shellHtml, meta.preloads, meta.inlineStyles, meta.tasks.length ? meta.tasks : "", nonce, meta.head, onHead));
692
976
  },
693
977
  ...options.sink
694
978
  };
@@ -768,7 +1052,6 @@ function renderToStream(code, options = {}) {
768
1052
  };
769
1053
  solidJs.sharedConfig.context = context = {
770
1054
  async: true,
771
- assets: [],
772
1055
  nonce,
773
1056
  registerHeadTags(tags) {
774
1057
  registerHeadTags(headRegistry, context, tracking,
@@ -968,9 +1251,9 @@ function renderToStream(code, options = {}) {
968
1251
  }
969
1252
  function doShell() {
970
1253
  if (shellCompleted) return;
971
- if (!resolveRootHoles()) return;
972
1254
  solidJs.sharedConfig.context = context;
973
- const assetsHtml = resolveAssetsHtml(context.assets);
1255
+ if (!resolveRootHoles()) return;
1256
+ if (!headShellReady(headRegistry, p => blockingPromises.add(p))) return;
974
1257
  headStyles = new Set();
975
1258
  for (const url of tracking.emittedAssets) {
976
1259
  if (isCssUrl(url)) headStyles.add(url);
@@ -978,7 +1261,6 @@ function renderToStream(code, options = {}) {
978
1261
  serializeRootAssets();
979
1262
  const head = renderShellHead(headRegistry, nonce, k => registry.has(k));
980
1263
  sink.shell(html, {
981
- assets: assetsHtml,
982
1264
  preloads: tracking.emittedAssets,
983
1265
  inlineStyles: tracking.inlineStyles,
984
1266
  tasks,
@@ -1026,14 +1308,24 @@ function renderToStream(code, options = {}) {
1026
1308
  function flush() {
1027
1309
  allSettled(blockingPromises).then(() => {
1028
1310
  scheduleFlush(() => {
1311
+ if (dead) return resolve();
1029
1312
  doShell();
1030
1313
  if (!shellCompleted) return flush();
1031
1314
  const encoder = new TextEncoder();
1032
1315
  const writer = w.getWriter();
1033
1316
  let pendingWrites = Promise.resolve();
1317
+ let ended = false;
1318
+ const failed = () => {
1319
+ if (!ended) {
1320
+ abandon();
1321
+ resolve();
1322
+ }
1323
+ };
1324
+ writer.closed && writer.closed.catch(failed);
1034
1325
  writable = {
1035
1326
  end() {
1036
1327
  pendingWrites.then(() => {
1328
+ ended = true;
1037
1329
  writer.releaseLock();
1038
1330
  w.close().catch(() => {});
1039
1331
  resolve();
@@ -1042,7 +1334,7 @@ function renderToStream(code, options = {}) {
1042
1334
  };
1043
1335
  buffer = {
1044
1336
  write(payload) {
1045
- pendingWrites = pendingWrites.then(() => writer.write(encoder.encode(payload))).catch(() => {});
1337
+ pendingWrites = pendingWrites.then(() => writer.write(encoder.encode(payload))).catch(failed);
1046
1338
  }
1047
1339
  };
1048
1340
  buffer.write(tmp);
@@ -1058,36 +1350,40 @@ function renderToStream(code, options = {}) {
1058
1350
  return p;
1059
1351
  };
1060
1352
  return {
1061
- then(fn) {
1062
- function complete() {
1063
- dispose();
1064
- fn(tmp);
1065
- }
1066
- if (onCompleteAll) {
1067
- let ogComplete = onCompleteAll;
1068
- onCompleteAll = options => {
1069
- ogComplete(options);
1070
- complete();
1071
- };
1072
- } else onCompleteAll = complete;
1073
- function flush() {
1074
- allSettled(blockingPromises).then(() => {
1075
- scheduleFlush(() => {
1076
- if (!resolveRootHoles()) return flush();
1077
- queue(flushEnd);
1353
+ then(onFulfilled, onRejected) {
1354
+ const p = new Promise(resolve => {
1355
+ function complete() {
1356
+ dispose();
1357
+ resolve(tmp);
1358
+ }
1359
+ if (onCompleteAll) {
1360
+ let ogComplete = onCompleteAll;
1361
+ onCompleteAll = options => {
1362
+ ogComplete(options);
1363
+ complete();
1364
+ };
1365
+ } else onCompleteAll = complete;
1366
+ function flush() {
1367
+ allSettled(blockingPromises).then(() => {
1368
+ scheduleFlush(() => {
1369
+ if (!resolveRootHoles() || !headShellReady(headRegistry, p => blockingPromises.add(p))) return flush();
1370
+ queue(flushEnd);
1371
+ });
1078
1372
  });
1079
- });
1080
- }
1081
- flush();
1373
+ }
1374
+ flush();
1375
+ });
1376
+ return p.then(onFulfilled, onRejected);
1082
1377
  },
1083
1378
  pipe(w) {
1084
1379
  claimConsumer("pipe");
1085
1380
  function flush() {
1086
1381
  allSettled(blockingPromises).then(() => {
1087
1382
  scheduleFlush(() => {
1383
+ if (dead) return;
1088
1384
  doShell();
1089
1385
  if (!shellCompleted) return flush();
1090
- buffer = writable = w;
1386
+ buffer = writable = guardSink(w);
1091
1387
  buffer.write(tmp);
1092
1388
  firstFlushed = true;
1093
1389
  if (completed) {
@@ -1362,17 +1658,11 @@ function allSettled(promises) {
1362
1658
  return;
1363
1659
  });
1364
1660
  }
1365
- function resolveAssetsHtml(assets) {
1366
- if (!assets || !assets.length) return "";
1367
- let out = "";
1368
- for (let i = 0, len = assets.length; i < len; i++) out += assets[i]();
1369
- return out;
1370
- }
1371
- function assembleDocument(html, assetsHtml, emittedAssets, inlineStyles, scripts, nonce, headTags, onHead) {
1661
+ function assembleDocument(html, emittedAssets, inlineStyles, scripts, nonce, headTags, onHead) {
1372
1662
  const scriptTag = scripts ? `<script${nonce ? ` nonce="${nonce}"` : ""}>${scripts}</script>` : "";
1373
1663
  const headTagsHtml = headTags ? headTags.html : "";
1374
1664
  const headPrelude = headTags ? headTags.prelude : "";
1375
- if (!onHead && !assetsHtml && !headTagsHtml && !headPrelude && !(emittedAssets && emittedAssets.size) && !(inlineStyles && inlineStyles.size)) {
1665
+ if (!onHead && !headTagsHtml && !headPrelude && !(emittedAssets && emittedAssets.size) && !(inlineStyles && inlineStyles.size)) {
1376
1666
  if (!scriptTag) return html;
1377
1667
  const xs = html.indexOf("<!--xs-->");
1378
1668
  return xs === -1 ? html + scriptTag : html.slice(0, xs) + scriptTag + html.slice(xs);
@@ -1387,13 +1677,13 @@ function assembleDocument(html, assetsHtml, emittedAssets, inlineStyles, scripts
1387
1677
  const headIdx = html.indexOf("</head>");
1388
1678
  if (headIdx === -1) {
1389
1679
  if (onHead) {
1390
- onHead(headPrelude + headTagsHtml + (assetsHtml || "") + renderHeadAssets(emittedAssets, inlineStyles, nonce));
1680
+ onHead(headPrelude + headTagsHtml + renderHeadAssets(emittedAssets, inlineStyles, nonce));
1391
1681
  }
1392
1682
  if (!scriptTag) return html;
1393
1683
  const xs = html.indexOf("<!--xs-->");
1394
1684
  return xs === -1 ? html + scriptTag : html.slice(0, xs) + scriptTag + html.slice(xs);
1395
1685
  }
1396
- const head = headTagsHtml + (assetsHtml || "") + renderHeadAssets(emittedAssets, inlineStyles, nonce);
1686
+ const head = headTagsHtml + renderHeadAssets(emittedAssets, inlineStyles, nonce);
1397
1687
  if (!scriptTag) return html.slice(0, headIdx) + head + html.slice(headIdx);
1398
1688
  const xsIdx = html.indexOf("<!--xs-->");
1399
1689
  if (xsIdx === -1) return html.slice(0, headIdx) + head + html.slice(headIdx) + scriptTag;
@@ -1575,142 +1865,7 @@ function resolveSSRSync(node) {
1575
1865
  if (!res.h.length) return res.t[0];
1576
1866
  throw new Error("This value cannot be rendered synchronously. Are you missing a boundary?");
1577
1867
  }
1578
-
1579
- function frameAddress(id, args) {
1580
- return args && args.length ? id + ":" + hashArguments(args) : id;
1581
- }
1582
- function hashArguments(args) {
1583
- let hash = 0;
1584
- const text = stableString(args);
1585
- for (let i = 0; i < text.length; i++) {
1586
- hash = (hash << 5) - hash + text.charCodeAt(i);
1587
- hash |= 0;
1588
- }
1589
- return (hash >>> 0).toString(36);
1590
- }
1591
- function stableString(value, seen) {
1592
- if (value === null || typeof value !== "object") {
1593
- return typeof value === "bigint" ? value + "n" : String(value);
1594
- }
1595
- if (value instanceof Date) return "Date:" + value.getTime();
1596
- seen || (seen = new Set());
1597
- if (seen.has(value)) return "~";
1598
- seen.add(value);
1599
- if (value instanceof Map) {
1600
- const entries = [];
1601
- for (const [k, v] of value) {
1602
- entries.push(stableString(k, seen) + "=>" + stableString(v, seen));
1603
- }
1604
- return "Map{" + entries.sort().join(",") + "}";
1605
- }
1606
- if (value instanceof Set) {
1607
- const members = [];
1608
- for (const v of value) members.push(stableString(v, seen));
1609
- return "Set{" + members.sort().join(",") + "}";
1610
- }
1611
- if (Array.isArray(value)) {
1612
- let out = "[";
1613
- for (let i = 0; i < value.length; i++) out += (i ? "," : "") + stableString(value[i], seen);
1614
- return out + "]";
1615
- }
1616
- const keys = Object.keys(value).sort();
1617
- let out = "{";
1618
- for (let i = 0; i < keys.length; i++) {
1619
- out += (i ? "," : "") + keys[i] + ":" + stableString(value[keys[i]], seen);
1620
- }
1621
- return out + "}";
1622
- }
1623
- const SINGLE_FLIGHT_HEADER = "X-Single-Flight";
1624
- function createChunk(data) {
1625
- const encodeData = new TextEncoder().encode(data);
1626
- const bytes = encodeData.length;
1627
- const baseHex = bytes.toString(16);
1628
- const totalHex = "00000000".substring(0, 8 - baseHex.length) + baseHex;
1629
- const head = new TextEncoder().encode(`;0x${totalHex};`);
1630
- const chunk = new Uint8Array(12 + bytes);
1631
- chunk.set(head);
1632
- chunk.set(encodeData, 12);
1633
- return chunk;
1634
- }
1635
- class ChunkReader {
1636
- constructor(stream) {
1637
- this.reader = stream.getReader();
1638
- this.buffer = new Uint8Array(0);
1639
- this.done = false;
1640
- }
1641
- async readChunk() {
1642
- const chunk = await this.reader.read();
1643
- if (!chunk.done) {
1644
- const newBuffer = new Uint8Array(this.buffer.length + chunk.value.length);
1645
- newBuffer.set(this.buffer);
1646
- newBuffer.set(chunk.value, this.buffer.length);
1647
- this.buffer = newBuffer;
1648
- } else {
1649
- this.done = true;
1650
- }
1651
- }
1652
- async next() {
1653
- while (this.buffer.length < 12) {
1654
- if (this.done) {
1655
- if (this.buffer.length === 0) return {
1656
- done: true,
1657
- value: undefined
1658
- };
1659
- throw new Error("Malformed server function stream.");
1660
- }
1661
- await this.readChunk();
1662
- }
1663
- const head = new TextDecoder().decode(this.buffer.subarray(1, 11));
1664
- const bytes = Number.parseInt(head, 16);
1665
- if (Number.isNaN(bytes)) {
1666
- throw new Error("Malformed server function stream.");
1667
- }
1668
- while (bytes > this.buffer.length - 12) {
1669
- if (this.done) {
1670
- throw new Error("Malformed server function stream.");
1671
- }
1672
- await this.readChunk();
1673
- }
1674
- const partial = new TextDecoder().decode(this.buffer.subarray(12, 12 + bytes));
1675
- this.buffer = this.buffer.subarray(12 + bytes);
1676
- return {
1677
- done: false,
1678
- value: partial
1679
- };
1680
- }
1681
- async drain(interpret) {
1682
- while (true) {
1683
- const result = await this.next();
1684
- if (result.done) {
1685
- break;
1686
- }
1687
- interpret(result.value);
1688
- }
1689
- }
1690
- }
1691
- function serializeStream(value, codecOptions) {
1692
- return new ReadableStream({
1693
- start(controller) {
1694
- serializeJSON(value, {
1695
- ...codecOptions,
1696
- onParse(node) {
1697
- controller.enqueue(createChunk(JSON.stringify(node)));
1698
- },
1699
- onDone() {
1700
- controller.close();
1701
- },
1702
- onError(error) {
1703
- controller.error(error);
1704
- }
1705
- });
1706
- }
1707
- });
1708
- }
1709
-
1710
- const ENVELOPE = Symbol.for("solid.ResponseEnvelope");
1711
- function isResponseEnvelope(value) {
1712
- return !!(value && typeof value === "object" && value[ENVELOPE]);
1713
- }
1868
+ /*#__PURE__*/new Set([ERROR_HEADER, BODY_FORMAT_HEADER, SINGLE_FLIGHT_HEADER, REVALIDATE_HEADER, "Location"].map(header => header.toLowerCase()));
1714
1869
 
1715
1870
  const INVOCATIONS = new WeakMap();
1716
1871
  function getEventServerFunctionInvocation(event) {
@@ -1724,6 +1879,10 @@ function isFrameStreamResponse(response) {
1724
1879
  const SERVER_COMPONENT = /*#__PURE__*/Symbol.for("dom-expressions.server-component");
1725
1880
  const SERVER_COMPONENT_SOURCE = /*#__PURE__*/Symbol.for("dom-expressions.server-component-source");
1726
1881
  const SERVER_COMPONENT_ADDRESS = /*#__PURE__*/Symbol.for("dom-expressions.server-component-address");
1882
+ let serverComponentRegistryExpr;
1883
+ function setServerComponentBootstrap(resolve) {
1884
+ serverComponentRegistryExpr = resolve;
1885
+ }
1727
1886
  function parseServerComponent(value, ctx) {
1728
1887
  return {
1729
1888
  id: ctx.parse(value[SERVER_COMPONENT]),
@@ -1746,7 +1905,8 @@ const ServerComponentPlugin = /*#__PURE__*/seroval.createPlugin({
1746
1905
  stream: parseServerComponent
1747
1906
  },
1748
1907
  serialize(node, ctx) {
1749
- return "self._$SC.r(" + ctx.serialize(node.id) + "," + ctx.serialize(node.address) + ")";
1908
+ const registry = serverComponentRegistryExpr ? serverComponentRegistryExpr(ctx) : "self._$SC";
1909
+ return registry + ".r(" + ctx.serialize(node.id) + "," + ctx.serialize(node.address) + ")";
1750
1910
  },
1751
1911
  deserialize(node, ctx) {
1752
1912
  const id = ctx.deserialize(node.id);
@@ -1775,12 +1935,43 @@ function serverOwned(render) {
1775
1935
  function serverComponentScope(render) {
1776
1936
  return solidJs.runInServerComponentScope ? solidJs.runInServerComponentScope(render) : render();
1777
1937
  }
1938
+ 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))}}))";
1939
+ const bootstrappedScripts = new WeakSet();
1940
+ setServerComponentBootstrap(ctx => {
1941
+ if (bootstrappedScripts.has(ctx)) return "self._$SC";
1942
+ bootstrappedScripts.add(ctx);
1943
+ return SERVER_COMPONENT_BOOTSTRAP_EXPR;
1944
+ });
1945
+ const SERVER_COMPONENT_BOOTSTRAP = SERVER_COMPONENT_BOOTSTRAP_EXPR + ";";
1778
1946
  function createFrameSink(emit, frame) {
1779
1947
  const {
1780
1948
  id,
1781
1949
  version
1782
1950
  } = frame;
1783
1951
  const styledKeys = new Set();
1952
+ const bindings = new Map();
1953
+ const sweepMinted = new Set();
1954
+ const argRefVersions = new Map();
1955
+ let sweepScheduled = false;
1956
+ let closed = false;
1957
+ let epoch = 0;
1958
+ const sweep = () => {
1959
+ epoch++;
1960
+ for (const b of [...bindings.values()]) {
1961
+ try {
1962
+ b.sweep();
1963
+ } catch (_) {
1964
+ }
1965
+ }
1966
+ };
1967
+ const scheduleSweep = () => {
1968
+ if (closed || sweepScheduled || !bindings.size) return;
1969
+ sweepScheduled = true;
1970
+ queueMicrotask(() => {
1971
+ sweepScheduled = false;
1972
+ if (!closed) sweep();
1973
+ });
1974
+ };
1784
1975
  const regionKeys = new Map();
1785
1976
  const frameOf = key => regionKeys.get(key) || id;
1786
1977
  return {
@@ -1822,6 +2013,7 @@ function createFrameSink(emit, frame) {
1822
2013
  version,
1823
2014
  payload: record
1824
2015
  });
2016
+ scheduleSweep();
1825
2017
  } else {
1826
2018
  emit({
1827
2019
  type: "data",
@@ -1831,6 +2023,7 @@ function createFrameSink(emit, frame) {
1831
2023
  node: record.node,
1832
2024
  initial: record.initial
1833
2025
  });
2026
+ if (!sweepMinted.has(record.key)) scheduleSweep();
1834
2027
  }
1835
2028
  },
1836
2029
  fragment(key, value, meta = {}) {
@@ -1867,6 +2060,7 @@ function createFrameSink(emit, frame) {
1867
2060
  key,
1868
2061
  html: value
1869
2062
  });
2063
+ scheduleSweep();
1870
2064
  if (meta.error) {
1871
2065
  emit({
1872
2066
  type: "error",
@@ -1921,6 +2115,8 @@ function createFrameSink(emit, frame) {
1921
2115
  });
1922
2116
  },
1923
2117
  end() {
2118
+ if (bindings.size) sweep();
2119
+ closed = true;
1924
2120
  emit({
1925
2121
  type: "complete",
1926
2122
  id,
@@ -1952,6 +2148,24 @@ function createFrameSink(emit, frame) {
1952
2148
  version,
1953
2149
  html
1954
2150
  });
2151
+ },
2152
+ openBinding(key, b) {
2153
+ bindings.set(key, b);
2154
+ },
2155
+ closeBinding(key) {
2156
+ bindings.delete(key);
2157
+ },
2158
+ mintRef(ref) {
2159
+ sweepMinted.add(ref);
2160
+ },
2161
+ nextArgRef(ledgerKey) {
2162
+ const n = (argRefVersions.get(ledgerKey) || 0) + 1;
2163
+ argRefVersions.set(ledgerKey, n);
2164
+ return n;
2165
+ },
2166
+ commit: scheduleSweep,
2167
+ get epoch() {
2168
+ return epoch;
1955
2169
  }
1956
2170
  };
1957
2171
  }
@@ -1961,7 +2175,14 @@ function renderToFrameStream(code, options = {}) {
1961
2175
  function renderServerComponent(component, options = {}) {
1962
2176
  return frameStream((sink, frame) => {
1963
2177
  const props = createSlotProps(sink, frame);
1964
- return () => serverComponentScope(() => component(props));
2178
+ return () => {
2179
+ const ctx = solidJs.sharedConfig.context;
2180
+ if (ctx) {
2181
+ ctx.commit = sink.commit;
2182
+ ctx.commitEpoch = () => sink.epoch;
2183
+ }
2184
+ return serverComponentScope(() => component(props));
2185
+ };
1965
2186
  }, options);
1966
2187
  }
1967
2188
  function frameStream(makeCode, options) {
@@ -2038,6 +2259,35 @@ function occurrenceId(prop, raw, counts) {
2038
2259
  counts[prop] = n + 1;
2039
2260
  return `${prop}#${n}`;
2040
2261
  }
2262
+ function isAsyncValue(v) {
2263
+ return !!v && typeof v === "object" && (typeof v.then === "function" || typeof v[Symbol.asyncIterator] === "function");
2264
+ }
2265
+ function tapFirstYield(iterable) {
2266
+ const iter = iterable[Symbol.asyncIterator]();
2267
+ const firstStep = Promise.resolve(iter.next());
2268
+ return {
2269
+ first: firstStep.then(r => r.done ? undefined : r.value),
2270
+ rest: {
2271
+ [Symbol.asyncIterator]() {
2272
+ let replayed = false;
2273
+ return {
2274
+ next: () => {
2275
+ if (!replayed) {
2276
+ replayed = true;
2277
+ return firstStep;
2278
+ }
2279
+ return iter.next();
2280
+ },
2281
+ return: v => iter.return ? iter.return(v) : Promise.resolve({
2282
+ done: true,
2283
+ value: v
2284
+ }),
2285
+ throw: e => iter.throw ? iter.throw(e) : Promise.reject(e)
2286
+ };
2287
+ }
2288
+ }
2289
+ };
2290
+ }
2041
2291
  function createDocumentSlotProps(clientProps, frameId) {
2042
2292
  const counts = Object.create(null);
2043
2293
  const getters = new Map();
@@ -2107,6 +2357,22 @@ function createDocumentSlotProps(clientProps, frameId) {
2107
2357
  t: FRAME_ELEMENT_CLOSE
2108
2358
  }];
2109
2359
  };
2360
+ } else if (ssrAsyncValue && isAsyncValue(value)) {
2361
+ let readable = value;
2362
+ if (typeof value.then !== "function") {
2363
+ const {
2364
+ first,
2365
+ rest
2366
+ } = tapFirstYield(value);
2367
+ readable = first;
2368
+ vals[key] = rest;
2369
+ }
2370
+ const read = ssrAsyncValue(readable);
2371
+ Object.defineProperty(resolved, key, {
2372
+ get: read,
2373
+ enumerable: true,
2374
+ configurable: true
2375
+ });
2110
2376
  } else {
2111
2377
  resolved[key] = value;
2112
2378
  }
@@ -2115,24 +2381,19 @@ function createDocumentSlotProps(clientProps, frameId) {
2115
2381
  const unused = regions.filter(r => !r.used);
2116
2382
  if (solidJs.sharedConfig.context) {
2117
2383
  const args = {};
2118
- let any = false;
2119
2384
  for (const key of Object.keys(vals)) {
2120
2385
  const value = vals[key];
2121
2386
  const region = regions.find(r => r.key === key);
2122
2387
  if (region) {
2123
- if (!region.used) {
2124
- args[key] = {
2125
- $frame: region.childId
2126
- };
2127
- any = true;
2128
- }
2388
+ args[key] = {
2389
+ $frame: region.childId
2390
+ };
2129
2391
  continue;
2130
2392
  }
2131
2393
  if (isServerContent(value)) continue;
2132
2394
  args[key] = value;
2133
- any = true;
2134
2395
  }
2135
- if (any) solidJs.sharedConfig.context.serialize(`sc:slot:${frameId}:${occurrence}`, args);
2396
+ solidJs.sharedConfig.context.serialize(`sc:slot:${frameId}:${occurrence}`, args);
2136
2397
  for (const region of unused) {
2137
2398
  region.locked = true;
2138
2399
  solidJs.sharedConfig.context.serialize(`sc:region:${region.childId}`, resolveRegionHtml(solidJs.sharedConfig.context, region.value));
@@ -2187,7 +2448,6 @@ function resolveRegionHtml(ctx, node) {
2187
2448
  return out;
2188
2449
  });
2189
2450
  }
2190
- const SERVER_COMPONENT_BOOTSTRAP = "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)=>self._$SC.impl(i,p))}};";
2191
2451
  function isServerContent(value) {
2192
2452
  if (value && typeof value === "object") {
2193
2453
  if ("t" in value) return true;
@@ -2200,6 +2460,88 @@ function isServerContent(value) {
2200
2460
  }
2201
2461
  return false;
2202
2462
  }
2463
+ function unwrapThunks(value) {
2464
+ for (let d = 0; typeof value === "function" && d < 16; d++) value = value();
2465
+ return value;
2466
+ }
2467
+ function contentArgError(key, occurrence) {
2468
+ return new Error("Async slot arg resolved to JSX (arg '" + key + "' of " + occurrence + "). Async args must resolve to serializable values; render async content through a boundary instead.");
2469
+ }
2470
+ function retryArgUntilSettled(evaluate, blocked, key, occurrence, onSettle) {
2471
+ const owner = solidJs.getOwner();
2472
+ return new Promise((resolve, reject) => {
2473
+ const retry = () => {
2474
+ try {
2475
+ const value = owner ? solidJs.runWithOwner(owner, evaluate) : evaluate();
2476
+ if (isServerContent(value)) {
2477
+ reject(contentArgError(key, occurrence));
2478
+ return;
2479
+ }
2480
+ if (onSettle) onSettle(value);
2481
+ resolve(value);
2482
+ } catch (err) {
2483
+ const next = solidJs.ssrHandleError && solidJs.ssrHandleError(err);
2484
+ if (next) next.then(retry, retry);else reject(err);
2485
+ }
2486
+ };
2487
+ blocked.then(retry, retry);
2488
+ });
2489
+ }
2490
+ function openArgBinding(sink, ctx, occurrence, key, evaluate, args, state) {
2491
+ const owner = solidJs.getOwner();
2492
+ const ledgerKey = `${occurrence}:${key}`;
2493
+ const reEmit = value => {
2494
+ const ref = `arg:${occurrence}:${key}@${sink.nextArgRef(ledgerKey)}`;
2495
+ sink.mintRef(ref);
2496
+ ctx.serialize(ref, value);
2497
+ args[key] = {
2498
+ $ref: ref
2499
+ };
2500
+ sink.slot(occurrence, {
2501
+ ...args
2502
+ });
2503
+ };
2504
+ const binding = {
2505
+ sweep() {
2506
+ if (!state.settled) return;
2507
+ let value;
2508
+ try {
2509
+ value = owner ? solidJs.runWithOwner(owner, evaluate) : evaluate();
2510
+ } catch (err) {
2511
+ const blocked = solidJs.ssrHandleError && solidJs.ssrHandleError(err);
2512
+ if (!blocked) {
2513
+ sink.closeBinding(ledgerKey);
2514
+ reEmit(Promise.reject(err instanceof Error ? err : new Error(String(err))));
2515
+ return;
2516
+ }
2517
+ state.settled = false;
2518
+ reEmit(retryArgUntilSettled(evaluate, blocked, key, occurrence, v => {
2519
+ state.settled = true;
2520
+ state.last = v;
2521
+ sink.commit();
2522
+ }));
2523
+ return;
2524
+ }
2525
+ if (value === state.last) return;
2526
+ state.last = value;
2527
+ if (isServerContent(value)) {
2528
+ sink.closeBinding(ledgerKey);
2529
+ reEmit(Promise.reject(contentArgError(key, occurrence)));
2530
+ return;
2531
+ }
2532
+ const t = typeof value;
2533
+ if (value == null || t === "string" || t === "number" || t === "boolean") {
2534
+ args[key] = value;
2535
+ sink.slot(occurrence, {
2536
+ ...args
2537
+ });
2538
+ } else {
2539
+ reEmit(value);
2540
+ }
2541
+ }
2542
+ };
2543
+ sink.openBinding(ledgerKey, binding);
2544
+ }
2203
2545
  function createSlotProps(sink, frame) {
2204
2546
  const counts = Object.create(null);
2205
2547
  const getters = new Map();
@@ -2219,6 +2561,7 @@ function createSlotProps(sink, frame) {
2219
2561
  const raw = callArgs[0];
2220
2562
  const occurrence = occurrenceId(prop, raw, counts);
2221
2563
  const args = {};
2564
+ const opened = [];
2222
2565
  for (const key of Object.keys(raw)) {
2223
2566
  if (key === "$key") continue;
2224
2567
  const childId = `${frame.id}.${occurrence}.${key}`;
@@ -2229,11 +2572,44 @@ function createSlotProps(sink, frame) {
2229
2572
  return origRegister.call(ctx, fragKey, fragOptions);
2230
2573
  };
2231
2574
  try {
2232
- let value = raw[key];
2233
- for (let d = 0; typeof value === "function" && d < 16; d++) value = value();
2575
+ const desc = Object.getOwnPropertyDescriptor(raw, key);
2576
+ let evaluate = null;
2577
+ let value;
2578
+ let state = null;
2579
+ try {
2580
+ if (desc.get) {
2581
+ const get = desc.get;
2582
+ evaluate = () => unwrapThunks(get.call(raw));
2583
+ value = evaluate();
2584
+ } else {
2585
+ value = desc.value;
2586
+ if (typeof value === "function") {
2587
+ const fn = value;
2588
+ evaluate = () => unwrapThunks(fn);
2589
+ value = evaluate();
2590
+ }
2591
+ }
2592
+ } catch (err) {
2593
+ const blocked = solidJs.ssrHandleError && solidJs.ssrHandleError(err);
2594
+ if (!blocked) throw err;
2595
+ state = {
2596
+ settled: false,
2597
+ last: undefined
2598
+ };
2599
+ const pendingState = state;
2600
+ value = retryArgUntilSettled(evaluate, blocked, key, occurrence, v => {
2601
+ pendingState.settled = true;
2602
+ pendingState.last = v;
2603
+ sink.commit();
2604
+ });
2605
+ }
2234
2606
  const t = typeof value;
2235
2607
  if (value == null || t === "string" || t === "number" || t === "boolean") {
2236
2608
  args[key] = value;
2609
+ if (evaluate) state = {
2610
+ settled: true,
2611
+ last: value
2612
+ };
2237
2613
  } else if (isServerContent(value)) {
2238
2614
  const resolved = ctx.resolve(value);
2239
2615
  if (resolved.h.length) {
@@ -2249,12 +2625,27 @@ function createSlotProps(sink, frame) {
2249
2625
  args[key] = {
2250
2626
  $ref: ref
2251
2627
  };
2628
+ if (evaluate && !state) state = {
2629
+ settled: true,
2630
+ last: value
2631
+ };
2252
2632
  }
2633
+ if (evaluate && state) opened.push({
2634
+ key,
2635
+ evaluate,
2636
+ state
2637
+ });
2253
2638
  } finally {
2254
2639
  ctx.registerFragment = origRegister;
2255
2640
  }
2256
2641
  }
2257
- sink.slot(occurrence, args);
2642
+ sink.slot(occurrence, {
2643
+ ...args
2644
+ });
2645
+ const ctx = solidJs.sharedConfig.context;
2646
+ for (const b of opened) {
2647
+ openArgBinding(sink, ctx, occurrence, b.key, b.evaluate, args, b.state);
2648
+ }
2258
2649
  return slotRange(occurrence);
2259
2650
  };
2260
2651
  getters.set(prop, fn);
@@ -2263,12 +2654,21 @@ function createSlotProps(sink, frame) {
2263
2654
  }
2264
2655
  });
2265
2656
  }
2657
+ function copyInitHeaders(init) {
2658
+ if (!init || !init.getSetCookie) return new Headers(init);
2659
+ const headers = new Headers();
2660
+ init.forEach((value, key) => {
2661
+ if (key !== "set-cookie") headers.append(key, value);
2662
+ });
2663
+ for (const cookie of init.getSetCookie()) headers.append("Set-Cookie", cookie);
2664
+ return headers;
2665
+ }
2266
2666
  function serverComponentResponse(component, options = {}, init = {}) {
2267
2667
  const {
2268
2668
  id = "",
2269
2669
  version = 1
2270
2670
  } = options.frame || {};
2271
- const headers = new Headers(init.headers);
2671
+ const headers = copyInitHeaders(init.headers);
2272
2672
  headers.set("Content-Type", "application/x-frame-stream");
2273
2673
  headers.set(FRAME_STREAM_HEADER, id);
2274
2674
  headers.set("X-Content-Raw", "1");
@@ -2367,7 +2767,7 @@ function frameFlightResponse({
2367
2767
  codec
2368
2768
  }, init = {}) {
2369
2769
  const frames = primary ? [primary, ...regions] : regions;
2370
- const headers = new Headers(init.headers);
2770
+ const headers = copyInitHeaders(init.headers);
2371
2771
  headers.set("Content-Type", "application/x-frame-stream");
2372
2772
  headers.set(FRAME_STREAM_HEADER, primary ? primary.id : "");
2373
2773
  headers.set("X-Content-Raw", "1");
@@ -2413,9 +2813,14 @@ function frameFlightResponse({
2413
2813
  });
2414
2814
  }
2415
2815
 
2816
+ function asyncArg(value) {
2817
+ return value;
2818
+ }
2819
+
2416
2820
  exports.FRAME_STREAM_HEADER = FRAME_STREAM_HEADER;
2417
2821
  exports.SERVER_COMPONENT_BOOTSTRAP = SERVER_COMPONENT_BOOTSTRAP;
2418
2822
  exports.ServerComponentPlugin = ServerComponentPlugin;
2823
+ exports.asyncArg = asyncArg;
2419
2824
  exports.createFrameSink = createFrameSink;
2420
2825
  exports.frameTransformDirectResult = frameTransformDirectResult;
2421
2826
  exports.frameTransformFlightResult = frameTransformFlightResult;