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