@solidjs/web 2.0.0-beta.27 → 2.0.0-beta.29

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 (43) hide show
  1. package/dist/dev.cjs +40 -2
  2. package/dist/dev.js +39 -4
  3. package/dist/server.cjs +113 -37
  4. package/dist/server.js +112 -39
  5. package/dist/web.cjs +40 -2
  6. package/dist/web.js +39 -4
  7. package/frames/dist/client.cjs +370 -209
  8. package/frames/dist/client.dev.cjs +370 -210
  9. package/frames/dist/client.dev.js +371 -211
  10. package/frames/dist/client.js +371 -210
  11. package/frames/dist/server.cjs +373 -74
  12. package/frames/dist/server.js +373 -75
  13. package/package.json +3 -3
  14. package/server-functions/dist/client.cjs +100 -3
  15. package/server-functions/dist/client.js +92 -4
  16. package/server-functions/dist/server.cjs +85 -17
  17. package/server-functions/dist/server.js +83 -17
  18. package/types/client.d.ts +15 -0
  19. package/types/core.d.ts +1 -1
  20. package/types/frames/client.d.ts +8 -5
  21. package/types/frames/frame-client.d.ts +17 -0
  22. package/types/frames/frame-sink.d.ts +29 -6
  23. package/types/frames/frame-transport.d.ts +76 -12
  24. package/types/frames/server.d.ts +29 -1
  25. package/types/index.d.ts +74 -0
  26. package/types/server-functions/client.d.ts +25 -0
  27. package/types/server-functions/server.d.ts +105 -18
  28. package/types/server-functions/shared.d.ts +22 -0
  29. package/types/server-mock.d.ts +6 -2
  30. package/types/server.d.ts +39 -1
  31. package/types-cjs/client.d.cts +15 -0
  32. package/types-cjs/core.d.cts +1 -1
  33. package/types-cjs/frames/client.d.cts +8 -5
  34. package/types-cjs/frames/frame-client.d.cts +17 -0
  35. package/types-cjs/frames/frame-sink.d.cts +29 -6
  36. package/types-cjs/frames/frame-transport.d.cts +76 -12
  37. package/types-cjs/frames/server.d.cts +29 -1
  38. package/types-cjs/index.d.cts +74 -0
  39. package/types-cjs/server-functions/client.d.cts +25 -0
  40. package/types-cjs/server-functions/server.d.cts +105 -18
  41. package/types-cjs/server-functions/shared.d.cts +22 -0
  42. package/types-cjs/server-mock.d.cts +6 -2
  43. package/types-cjs/server.d.cts +39 -1
@@ -1,5 +1,5 @@
1
+ import { runWithOwner, createOwner, sharedConfig, createRoot, ssrHandleError, getOwner, NoHydration, runInServerComponentScope, Hydration } from 'solid-js';
1
2
  import { toCrossJSONStream, Feature, Serializer, getCrossReferenceHeader, createPlugin } from 'seroval';
2
- import { runWithOwner, createOwner, sharedConfig, createRoot, ssrHandleError, getOwner, NoHydration, Hydration } from 'solid-js';
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({
@@ -54,6 +54,21 @@ function resolveCodecOptions({
54
54
  depthLimit: depthLimit === undefined ? JSON_CODEC_DEPTH_LIMIT : depthLimit
55
55
  };
56
56
  }
57
+ function serializeJSON(value, {
58
+ onParse,
59
+ onDone,
60
+ onError,
61
+ ...codecOptions
62
+ }) {
63
+ const resolved = resolveCodecOptions(codecOptions);
64
+ return toCrossJSONStream(value, {
65
+ onParse,
66
+ onDone,
67
+ onError,
68
+ ...resolved,
69
+ disabledFeatures: resolved.disabledFeatures | serializeOnlyDisabledFeatures()
70
+ });
71
+ }
57
72
  function createJSONSerializer({
58
73
  onData,
59
74
  onDone,
@@ -218,7 +233,24 @@ function createAssetTracking() {
218
233
  }
219
234
  };
220
235
  }
221
- function applyAssetTracking(context, tracking, manifest) {
236
+ function warnUnresolvedModuleAssets(moduleUrl, warned) {
237
+ if (warned.has(moduleUrl)) return;
238
+ warned.add(moduleUrl);
239
+ console.error(`Asset manifest returned no client assets for module "${moduleUrl}". ` + "If this module is a server-rendered lazy() component, its entry will be missing from " + "the serialized hydration asset map, the client will be unable to preload it, and " + "hydration will fail with 'lazy() module \"…\" was not preloaded before hydration'. " + "This means the integration's asset resolver (dev manifest bridge or build client " + "manifest) failed to answer for this module — check the integration's server logs, " + "restart the dev server, or verify the module is included in the client build.");
240
+ }
241
+ function guardResolvedAssets(moduleUrl, result, warned) {
242
+ if (result && typeof result.then === "function") {
243
+ return result.then(assets => {
244
+ if (!assets || !assets.js || !assets.js.length) warnUnresolvedModuleAssets(moduleUrl, warned);
245
+ return assets;
246
+ });
247
+ }
248
+ if (!result || !result.js || !result.js.length) warnUnresolvedModuleAssets(moduleUrl, warned);
249
+ return result;
250
+ }
251
+ function applyAssetTracking(context, tracking, manifest, noScripts) {
252
+ const warned = new Set();
253
+ const guard = noScripts ? resolve => resolve : resolve => moduleUrl => guardResolvedAssets(moduleUrl, resolve(moduleUrl), warned);
222
254
  Object.defineProperty(context, "_currentBoundaryId", {
223
255
  get() {
224
256
  return tracking.currentBoundaryId;
@@ -232,15 +264,15 @@ function applyAssetTracking(context, tracking, manifest) {
232
264
  context.registerModule = tracking.registerModule;
233
265
  context.getBoundaryModules = tracking.getBoundaryModules;
234
266
  if (typeof manifest === "function") {
235
- context.resolveAssets = manifest;
267
+ context.resolveAssets = guard(manifest);
236
268
  } else if (manifest && typeof manifest.resolve === "function") {
237
- context.resolveAssets = key => manifest.resolve(key);
269
+ context.resolveAssets = guard(key => manifest.resolve(key));
238
270
  if (typeof manifest.resolveSync === "function") {
239
271
  context.resolveAssetsSync = key => manifest.resolveSync(key);
240
272
  }
241
273
  } else if (manifest) {
242
274
  const resolve = moduleUrl => resolveAssets(moduleUrl, manifest);
243
- context.resolveAssets = resolve;
275
+ context.resolveAssets = guard(resolve);
244
276
  context.resolveAssetsSync = resolve;
245
277
  }
246
278
  }
@@ -519,7 +551,7 @@ function renderToStream(code, options = {}) {
519
551
  });
520
552
  }
521
553
  };
522
- applyAssetTracking(context, tracking, manifest);
554
+ applyAssetTracking(context, tracking, manifest, noScripts);
523
555
  registerEntryAssets(manifest);
524
556
  let html = createRoot(d => {
525
557
  dispose = d;
@@ -616,6 +648,51 @@ function renderToStream(code, options = {}) {
616
648
  drainTurn = 0;
617
649
  progressed ? queue(attempt) : setTimeout(attempt);
618
650
  };
651
+ let cachedReadable;
652
+ let consumer;
653
+ const claimConsumer = name => {
654
+ if (consumer && consumer !== name) {
655
+ throw new Error(`renderToStream result was already consumed via \`${consumer}\`; cannot also consume it via \`${name}\`. Use exactly one of \`pipe\`, \`pipeTo\`, or \`readable\`.`);
656
+ }
657
+ consumer = name;
658
+ };
659
+ const pipeToImpl = w => {
660
+ let resolve;
661
+ const p = new Promise(r => resolve = r);
662
+ function flush() {
663
+ allSettled(blockingPromises).then(() => {
664
+ scheduleFlush(() => {
665
+ doShell();
666
+ if (!shellCompleted) return flush();
667
+ const encoder = new TextEncoder();
668
+ const writer = w.getWriter();
669
+ let pendingWrites = Promise.resolve();
670
+ writable = {
671
+ end() {
672
+ pendingWrites.then(() => {
673
+ writer.releaseLock();
674
+ w.close().catch(() => {});
675
+ resolve();
676
+ });
677
+ }
678
+ };
679
+ buffer = {
680
+ write(payload) {
681
+ pendingWrites = pendingWrites.then(() => writer.write(encoder.encode(payload))).catch(() => {});
682
+ }
683
+ };
684
+ buffer.write(tmp);
685
+ firstFlushed = true;
686
+ if (completed) {
687
+ dispose();
688
+ writable.end();
689
+ } else flushEnd();
690
+ });
691
+ });
692
+ }
693
+ flush();
694
+ return p;
695
+ };
619
696
  return {
620
697
  then(fn) {
621
698
  function complete() {
@@ -640,6 +717,7 @@ function renderToStream(code, options = {}) {
640
717
  flush();
641
718
  },
642
719
  pipe(w) {
720
+ claimConsumer("pipe");
643
721
  function flush() {
644
722
  allSettled(blockingPromises).then(() => {
645
723
  scheduleFlush(() => {
@@ -658,38 +736,17 @@ function renderToStream(code, options = {}) {
658
736
  flush();
659
737
  },
660
738
  pipeTo(w) {
661
- let resolve;
662
- const p = new Promise(r => resolve = r);
663
- function flush() {
664
- allSettled(blockingPromises).then(() => {
665
- scheduleFlush(() => {
666
- doShell();
667
- if (!shellCompleted) return flush();
668
- const encoder = new TextEncoder();
669
- const writer = w.getWriter();
670
- writable = {
671
- end() {
672
- writer.releaseLock();
673
- w.close().catch(() => {});
674
- resolve();
675
- }
676
- };
677
- buffer = {
678
- write(payload) {
679
- writer.write(encoder.encode(payload)).catch(() => {});
680
- }
681
- };
682
- buffer.write(tmp);
683
- firstFlushed = true;
684
- if (completed) {
685
- dispose();
686
- writable.end();
687
- } else flushEnd();
688
- });
689
- });
739
+ claimConsumer("pipeTo");
740
+ return pipeToImpl(w);
741
+ },
742
+ get readable() {
743
+ claimConsumer("readable");
744
+ if (!cachedReadable) {
745
+ const t = new TransformStream();
746
+ pipeToImpl(t.writable);
747
+ cachedReadable = t.readable;
690
748
  }
691
- flush();
692
- return p;
749
+ return cachedReadable;
693
750
  }
694
751
  };
695
752
  }
@@ -1134,6 +1191,51 @@ function resolveSSRSync(node) {
1134
1191
  throw new Error("This value cannot be rendered synchronously. Are you missing a boundary?");
1135
1192
  }
1136
1193
 
1194
+ function frameAddress(id, args) {
1195
+ return args && args.length ? id + ":" + hashArguments(args) : id;
1196
+ }
1197
+ function hashArguments(args) {
1198
+ let hash = 0;
1199
+ const text = stableString(args);
1200
+ for (let i = 0; i < text.length; i++) {
1201
+ hash = (hash << 5) - hash + text.charCodeAt(i);
1202
+ hash |= 0;
1203
+ }
1204
+ return (hash >>> 0).toString(36);
1205
+ }
1206
+ function stableString(value, seen) {
1207
+ if (value === null || typeof value !== "object") {
1208
+ return typeof value === "bigint" ? value + "n" : String(value);
1209
+ }
1210
+ if (value instanceof Date) return "Date:" + value.getTime();
1211
+ seen || (seen = new Set());
1212
+ if (seen.has(value)) return "~";
1213
+ seen.add(value);
1214
+ if (value instanceof Map) {
1215
+ const entries = [];
1216
+ for (const [k, v] of value) {
1217
+ entries.push(stableString(k, seen) + "=>" + stableString(v, seen));
1218
+ }
1219
+ return "Map{" + entries.sort().join(",") + "}";
1220
+ }
1221
+ if (value instanceof Set) {
1222
+ const members = [];
1223
+ for (const v of value) members.push(stableString(v, seen));
1224
+ return "Set{" + members.sort().join(",") + "}";
1225
+ }
1226
+ if (Array.isArray(value)) {
1227
+ let out = "[";
1228
+ for (let i = 0; i < value.length; i++) out += (i ? "," : "") + stableString(value[i], seen);
1229
+ return out + "]";
1230
+ }
1231
+ const keys = Object.keys(value).sort();
1232
+ let out = "{";
1233
+ for (let i = 0; i < keys.length; i++) {
1234
+ out += (i ? "," : "") + keys[i] + ":" + stableString(value[keys[i]], seen);
1235
+ }
1236
+ return out + "}";
1237
+ }
1238
+ const SINGLE_FLIGHT_HEADER = "X-Single-Flight";
1137
1239
  function createChunk(data) {
1138
1240
  const encodeData = new TextEncoder().encode(data);
1139
1241
  const bytes = encodeData.length;
@@ -1145,16 +1247,138 @@ function createChunk(data) {
1145
1247
  chunk.set(encodeData, 12);
1146
1248
  return chunk;
1147
1249
  }
1250
+ class ChunkReader {
1251
+ constructor(stream) {
1252
+ this.reader = stream.getReader();
1253
+ this.buffer = new Uint8Array(0);
1254
+ this.done = false;
1255
+ }
1256
+ async readChunk() {
1257
+ const chunk = await this.reader.read();
1258
+ if (!chunk.done) {
1259
+ const newBuffer = new Uint8Array(this.buffer.length + chunk.value.length);
1260
+ newBuffer.set(this.buffer);
1261
+ newBuffer.set(chunk.value, this.buffer.length);
1262
+ this.buffer = newBuffer;
1263
+ } else {
1264
+ this.done = true;
1265
+ }
1266
+ }
1267
+ async next() {
1268
+ while (this.buffer.length < 12) {
1269
+ if (this.done) {
1270
+ if (this.buffer.length === 0) return {
1271
+ done: true,
1272
+ value: undefined
1273
+ };
1274
+ throw new Error("Malformed server function stream.");
1275
+ }
1276
+ await this.readChunk();
1277
+ }
1278
+ const head = new TextDecoder().decode(this.buffer.subarray(1, 11));
1279
+ const bytes = Number.parseInt(head, 16);
1280
+ if (Number.isNaN(bytes)) {
1281
+ throw new Error("Malformed server function stream.");
1282
+ }
1283
+ while (bytes > this.buffer.length - 12) {
1284
+ if (this.done) {
1285
+ throw new Error("Malformed server function stream.");
1286
+ }
1287
+ await this.readChunk();
1288
+ }
1289
+ const partial = new TextDecoder().decode(this.buffer.subarray(12, 12 + bytes));
1290
+ this.buffer = this.buffer.subarray(12 + bytes);
1291
+ return {
1292
+ done: false,
1293
+ value: partial
1294
+ };
1295
+ }
1296
+ async drain(interpret) {
1297
+ while (true) {
1298
+ const result = await this.next();
1299
+ if (result.done) {
1300
+ break;
1301
+ }
1302
+ interpret(result.value);
1303
+ }
1304
+ }
1305
+ }
1306
+ function serializeStream(value, codecOptions) {
1307
+ return new ReadableStream({
1308
+ start(controller) {
1309
+ serializeJSON(value, {
1310
+ ...codecOptions,
1311
+ onParse(node) {
1312
+ controller.enqueue(createChunk(JSON.stringify(node)));
1313
+ },
1314
+ onDone() {
1315
+ controller.close();
1316
+ },
1317
+ onError(error) {
1318
+ controller.error(error);
1319
+ }
1320
+ });
1321
+ }
1322
+ });
1323
+ }
1148
1324
 
1149
1325
  const ENVELOPE = Symbol.for("solid.ResponseEnvelope");
1150
1326
  function isResponseEnvelope(value) {
1151
1327
  return !!(value && typeof value === "object" && value[ENVELOPE]);
1152
1328
  }
1153
1329
 
1330
+ const INVOCATIONS = new WeakMap();
1331
+ function getEventServerFunctionInvocation(event) {
1332
+ return event && INVOCATIONS.get(event);
1333
+ }
1334
+
1154
1335
  const FRAME_STREAM_HEADER = "X-Frame-Stream";
1155
1336
  function isFrameStreamResponse(response) {
1156
1337
  return response.headers.has(FRAME_STREAM_HEADER);
1157
1338
  }
1339
+ const SERVER_COMPONENT = /*#__PURE__*/Symbol.for("dom-expressions.server-component");
1340
+ const SERVER_COMPONENT_SOURCE = /*#__PURE__*/Symbol.for("dom-expressions.server-component-source");
1341
+ const SERVER_COMPONENT_ADDRESS = /*#__PURE__*/Symbol.for("dom-expressions.server-component-address");
1342
+ function parseServerComponent(value, ctx) {
1343
+ return {
1344
+ id: ctx.parse(value[SERVER_COMPONENT]),
1345
+ address: ctx.parse(value[SERVER_COMPONENT_ADDRESS])
1346
+ };
1347
+ }
1348
+ const ServerComponentPlugin = /*#__PURE__*/createPlugin({
1349
+ tag: "dom-expressions/server-component",
1350
+ test(value) {
1351
+ return typeof value === "function" && SERVER_COMPONENT in value;
1352
+ },
1353
+ parse: {
1354
+ sync: parseServerComponent,
1355
+ async async(value, ctx) {
1356
+ return {
1357
+ id: await ctx.parse(value[SERVER_COMPONENT]),
1358
+ address: await ctx.parse(value[SERVER_COMPONENT_ADDRESS])
1359
+ };
1360
+ },
1361
+ stream: parseServerComponent
1362
+ },
1363
+ serialize(node, ctx) {
1364
+ return "self._$SC.r(" + ctx.serialize(node.id) + "," + ctx.serialize(node.address) + ")";
1365
+ },
1366
+ deserialize(node, ctx) {
1367
+ const id = ctx.deserialize(node.id);
1368
+ ctx.deserialize(node.address);
1369
+ return globalThis._$SC.r(id);
1370
+ }
1371
+ });
1372
+ function flightCodec(codec) {
1373
+ const plugins = codec && codec.plugins || [];
1374
+ for (const plugin of plugins) {
1375
+ if (plugin && plugin.tag === "dom-expressions/server-component") return codec;
1376
+ }
1377
+ return {
1378
+ ...codec,
1379
+ plugins: [...plugins, ServerComponentPlugin]
1380
+ };
1381
+ }
1158
1382
 
1159
1383
  function serverOwned(render) {
1160
1384
  return NoHydration ? NoHydration({
@@ -1163,6 +1387,9 @@ function serverOwned(render) {
1163
1387
  }
1164
1388
  }) : render();
1165
1389
  }
1390
+ function serverComponentScope(render) {
1391
+ return runInServerComponentScope ? runInServerComponentScope(render) : render();
1392
+ }
1166
1393
  function createFrameSink(emit, frame) {
1167
1394
  const {
1168
1395
  id,
@@ -1344,7 +1571,7 @@ function renderToFrameStream(code, options = {}) {
1344
1571
  function renderServerComponent(component, options = {}) {
1345
1572
  return frameStream((sink, frame) => {
1346
1573
  const props = createSlotProps(sink, frame);
1347
- return () => component(props);
1574
+ return () => serverComponentScope(() => component(props));
1348
1575
  }, options);
1349
1576
  }
1350
1577
  function frameStream(makeCode, options) {
@@ -1537,16 +1764,23 @@ function frameElementOpen(id) {
1537
1764
  }
1538
1765
  const FRAME_ELEMENT_CLOSE = `</${FRAME_TAG}>`;
1539
1766
  function frameTransformDirectResult(value, {
1540
- id
1767
+ id,
1768
+ args
1541
1769
  }) {
1542
1770
  if (typeof value !== "function") return value;
1543
1771
  const component = value;
1544
1772
  const wrapped = props => [{
1545
1773
  t: frameElementOpen(id)
1546
- }, serverOwned(() => component(createDocumentSlotProps(props, id))), {
1774
+ },
1775
+ serverOwned(() => {
1776
+ const slotProps = createDocumentSlotProps(props, id);
1777
+ return serverComponentScope(() => component(slotProps));
1778
+ }), {
1547
1779
  t: FRAME_ELEMENT_CLOSE
1548
1780
  }];
1549
1781
  wrapped[SERVER_COMPONENT] = id;
1782
+ wrapped[SERVER_COMPONENT_SOURCE] = component;
1783
+ wrapped[SERVER_COMPONENT_ADDRESS] = frameAddress(id, args);
1550
1784
  return wrapped;
1551
1785
  }
1552
1786
  function resolveRegionHtml(ctx, node) {
@@ -1563,37 +1797,7 @@ function resolveRegionHtml(ctx, node) {
1563
1797
  return out;
1564
1798
  });
1565
1799
  }
1566
- const SERVER_COMPONENT = /*#__PURE__*/Symbol.for("dom-expressions.server-component");
1567
- const ServerComponentPlugin = /*#__PURE__*/createPlugin({
1568
- tag: "dom-expressions/server-component",
1569
- test(value) {
1570
- return typeof value === "function" && SERVER_COMPONENT in value;
1571
- },
1572
- parse: {
1573
- sync(value, ctx) {
1574
- return {
1575
- id: ctx.parse(value[SERVER_COMPONENT])
1576
- };
1577
- },
1578
- async async(value, ctx) {
1579
- return {
1580
- id: await ctx.parse(value[SERVER_COMPONENT])
1581
- };
1582
- },
1583
- stream(value, ctx) {
1584
- return {
1585
- id: ctx.parse(value[SERVER_COMPONENT])
1586
- };
1587
- }
1588
- },
1589
- serialize(node, ctx) {
1590
- return "self._$SC.r(" + ctx.serialize(node.id) + ")";
1591
- },
1592
- deserialize(node, ctx) {
1593
- return globalThis._$SC.r(ctx.deserialize(node.id));
1594
- }
1595
- });
1596
- const SERVER_COMPONENT_BOOTSTRAP = "self._$SC={c:{},r(i){return this.c[i]||(this.c[i]=(p)=>self._$SC.impl(i,p))}};";
1800
+ 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))}};";
1597
1801
  function isServerContent(value) {
1598
1802
  if (value && typeof value === "object") {
1599
1803
  if ("t" in value) return true;
@@ -1702,7 +1906,7 @@ function serverComponentResponse(component, options = {}, init = {}) {
1702
1906
  headers
1703
1907
  });
1704
1908
  }
1705
- function frameTransformResult(event, result) {
1909
+ function frameTransformResult(event, result, context) {
1706
1910
  let init;
1707
1911
  if (isResponseEnvelope(result)) {
1708
1912
  const {
@@ -1717,12 +1921,106 @@ function frameTransformResult(event, result) {
1717
1921
  result = value;
1718
1922
  }
1719
1923
  if (typeof result !== "function") return result;
1720
- const meta = event && event.locals && event.locals.serverFunctionMeta;
1924
+ if (context && context.collectsFlight) return init ? {
1925
+ response: init,
1926
+ value: result
1927
+ } : result;
1928
+ const invocation = getEventServerFunctionInvocation(event);
1721
1929
  return serverComponentResponse(result, {
1722
1930
  frame: {
1723
- id: meta && meta.id || ""
1931
+ id: invocation && invocation.id || ""
1724
1932
  }
1725
1933
  }, init);
1726
1934
  }
1935
+ async function frameTransformFlightResult(event, outcome, context) {
1936
+ const {
1937
+ value,
1938
+ data
1939
+ } = outcome;
1940
+ const regions = [];
1941
+ let serialized = data;
1942
+ if (data && typeof data === "object") {
1943
+ serialized = {};
1944
+ const keys = Object.keys(data);
1945
+ const values = await Promise.all(keys.map(key => data[key]));
1946
+ for (let i = 0; i < keys.length; i++) {
1947
+ const entry = values[i];
1948
+ serialized[keys[i]] = entry;
1949
+ if (typeof entry === "function") {
1950
+ regions.push({
1951
+ id: entry[SERVER_COMPONENT_ADDRESS] || keys[i],
1952
+ component: entry[SERVER_COMPONENT_SOURCE] || entry
1953
+ });
1954
+ }
1955
+ }
1956
+ }
1957
+ const invocation = getEventServerFunctionInvocation(event);
1958
+ const primary = typeof value === "function" ? {
1959
+ id: invocation && invocation.id || "",
1960
+ component: value
1961
+ } : undefined;
1962
+ if (!primary && !regions.length) return undefined;
1963
+ return frameFlightResponse({
1964
+ primary,
1965
+ regions,
1966
+ outcome: {
1967
+ value: primary ? undefined : value,
1968
+ data: serialized
1969
+ },
1970
+ codec: context && context.codec
1971
+ });
1972
+ }
1973
+ function frameFlightResponse({
1974
+ primary,
1975
+ regions = [],
1976
+ outcome,
1977
+ codec
1978
+ }, init = {}) {
1979
+ const frames = primary ? [primary, ...regions] : regions;
1980
+ const headers = new Headers(init.headers);
1981
+ headers.set("Content-Type", "application/x-frame-stream");
1982
+ headers.set(FRAME_STREAM_HEADER, primary ? primary.id : "");
1983
+ headers.set("X-Content-Raw", "1");
1984
+ headers.set(SINGLE_FLIGHT_HEADER, "true");
1985
+ const body = new ReadableStream({
1986
+ async start(controller) {
1987
+ const write = chunk => controller.enqueue(createChunk(JSON.stringify(chunk)));
1988
+ try {
1989
+ for (const {
1990
+ id,
1991
+ component
1992
+ } of frames) {
1993
+ await new Promise(resolve => {
1994
+ renderServerComponent(component, {
1995
+ frame: {
1996
+ id,
1997
+ version: 1
1998
+ }
1999
+ }).pipe({
2000
+ write,
2001
+ end: resolve
2002
+ });
2003
+ });
2004
+ }
2005
+ if (outcome) {
2006
+ const reader = new ChunkReader(serializeStream(outcome, flightCodec(codec)));
2007
+ for (let node = await reader.next(); !node.done; node = await reader.next()) {
2008
+ write({
2009
+ type: "outcome",
2010
+ payload: node.value
2011
+ });
2012
+ }
2013
+ }
2014
+ controller.close();
2015
+ } catch (err) {
2016
+ controller.error(err);
2017
+ }
2018
+ }
2019
+ });
2020
+ return new Response(body, {
2021
+ status: init.status || 200,
2022
+ headers
2023
+ });
2024
+ }
1727
2025
 
1728
- export { FRAME_STREAM_HEADER, SERVER_COMPONENT_BOOTSTRAP, ServerComponentPlugin, createFrameSink, frameTransformDirectResult, frameTransformResult, isFrameStreamResponse, renderServerComponent, renderToFrameStream, serverComponentResponse };
2026
+ export { FRAME_STREAM_HEADER, SERVER_COMPONENT_BOOTSTRAP, ServerComponentPlugin, createFrameSink, frameTransformDirectResult, frameTransformFlightResult, frameTransformResult, isFrameStreamResponse, renderServerComponent, renderToFrameStream, serverComponentResponse };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@solidjs/web",
3
3
  "description": "Solid's web runtime: client rendering, hydration, SSR, and DOM-specific control flow (Portal, Dynamic).",
4
- "version": "2.0.0-beta.27",
4
+ "version": "2.0.0-beta.29",
5
5
  "author": "Ryan Carniato",
6
6
  "license": "MIT",
7
7
  "homepage": "https://solidjs.com",
@@ -316,10 +316,10 @@
316
316
  "seroval-plugins": "~1.5.4"
317
317
  },
318
318
  "peerDependencies": {
319
- "solid-js": "^2.0.0-beta.27"
319
+ "solid-js": "^2.0.0-beta.29"
320
320
  },
321
321
  "devDependencies": {
322
- "solid-js": "2.0.0-beta.27"
322
+ "solid-js": "2.0.0-beta.29"
323
323
  },
324
324
  "scripts": {
325
325
  "build": "npm-run-all -nl build:clean types:copy-jsx build:js",