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

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 +14 -9
  2. package/dist/dev.js +14 -10
  3. package/dist/server.cjs +41 -78
  4. package/dist/server.js +42 -80
  5. package/dist/web.cjs +14 -9
  6. package/dist/web.js +14 -10
  7. package/frames/dist/client.cjs +180 -224
  8. package/frames/dist/client.dev.cjs +1456 -0
  9. package/frames/dist/client.dev.js +1444 -0
  10. package/frames/dist/client.js +181 -225
  11. package/frames/dist/server.cjs +139 -123
  12. package/frames/dist/server.js +139 -123
  13. package/package.json +24 -4
  14. package/serialization/dist/serialization.cjs +6 -3
  15. package/serialization/dist/serialization.js +6 -3
  16. package/serialization/types/index.d.ts +7 -1
  17. package/serialization/types-cjs/index.d.cts +7 -1
  18. package/server-functions/dist/client.cjs +18 -5
  19. package/server-functions/dist/client.js +16 -6
  20. package/server-functions/dist/server.cjs +164 -8
  21. package/server-functions/dist/server.js +158 -9
  22. package/types/client.d.ts +3 -3
  23. package/types/frames/client.d.ts +1 -1
  24. package/types/frames/frame-client.d.ts +34 -28
  25. package/types/frames/serializer.d.ts +7 -1
  26. package/types/jsx.d.ts +1 -1
  27. package/types/response.d.ts +10 -0
  28. package/types/serializer.d.ts +7 -1
  29. package/types/server-functions/client.d.ts +3 -0
  30. package/types/server-functions/flash.d.ts +38 -0
  31. package/types/server-functions/server.d.ts +79 -4
  32. package/types/server-functions/shared.d.ts +35 -0
  33. package/types-cjs/client.d.cts +3 -3
  34. package/types-cjs/frames/client.d.cts +1 -1
  35. package/types-cjs/frames/frame-client.d.cts +34 -28
  36. package/types-cjs/frames/serializer.d.cts +7 -1
  37. package/types-cjs/jsx.d.cts +1 -1
  38. package/types-cjs/response.d.cts +10 -0
  39. package/types-cjs/serializer.d.cts +7 -1
  40. package/types-cjs/server-functions/client.d.cts +3 -0
  41. package/types-cjs/server-functions/flash.d.cts +38 -0
  42. package/types-cjs/server-functions/server.d.cts +79 -4
  43. package/types-cjs/server-functions/shared.d.cts +35 -0
@@ -9,6 +9,7 @@ const runWithHydrationScope = (id, fn) => solidJs.runWithOwner(solidJs.createOwn
9
9
  }), fn);
10
10
 
11
11
  const DEFAULT_DISABLED_FEATURES = seroval.Feature.AggregateError | seroval.Feature.BigIntTypedArray;
12
+ const serializeOnlyDisabledFeatures = () => process.env.NODE_ENV === "development" ? 0 : seroval.Feature.ErrorPrototypeStack;
12
13
  const HYDRATION_GLOBAL = "_$HY.r";
13
14
  const DEFAULT_WEB_PLUGINS = Object.freeze([web.AbortSignalPlugin,
14
15
  web.CustomEventPlugin, web.DOMExceptionPlugin, web.EventPlugin,
@@ -20,7 +21,7 @@ function createSerializer(options) {
20
21
  return new seroval.Serializer({
21
22
  ...options,
22
23
  plugins: resolveSerializerPlugins(options.plugins),
23
- disabledFeatures: options.disabledFeatures === undefined ? DEFAULT_DISABLED_FEATURES : options.disabledFeatures
24
+ disabledFeatures: (options.disabledFeatures === undefined ? DEFAULT_DISABLED_FEATURES : options.disabledFeatures) | serializeOnlyDisabledFeatures()
24
25
  });
25
26
  }
26
27
  function createHydrationSerializer({
@@ -88,7 +89,7 @@ function createJSONSerializer({
88
89
  const stream = seroval.toCrossJSONStream(value, {
89
90
  refs,
90
91
  plugins: resolved.plugins,
91
- disabledFeatures: resolved.disabledFeatures,
92
+ disabledFeatures: resolved.disabledFeatures | serializeOnlyDisabledFeatures(),
92
93
  onParse(node, initial) {
93
94
  onData({
94
95
  key,
@@ -245,7 +246,7 @@ function applyAssetTracking(context, tracking, manifest) {
245
246
  context.resolveAssetsSync = resolve;
246
247
  }
247
248
  }
248
- const REPLACE_SCRIPT = `function $df(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;_$HY.done?o.remove():o.replaceWith(n.content),n.remove(),_$HY.fe(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])}`;
249
+ const REPLACE_SCRIPT = `function $df(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,_$HY.done?o.remove():o.replaceWith(n.content),n.remove(),_$HY.fe(e,t),$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])}`;
249
250
  function renderToStream(code, options = {}) {
250
251
  let {
251
252
  nonce,
@@ -317,11 +318,7 @@ function renderToStream(code, options = {}) {
317
318
  }
318
319
  },
319
320
  shell(shellHtml, meta) {
320
- shellHtml = injectBeforeHead(shellHtml, meta.assets);
321
- shellHtml = injectPreloadLinks(meta.preloads, shellHtml);
322
- shellHtml = injectInlineStyles(meta.inlineStyles, shellHtml, nonce);
323
- if (meta.tasks.length) shellHtml = injectScripts(shellHtml, meta.tasks, nonce);
324
- buffer.write(shellHtml);
321
+ buffer.write(assembleDocument(shellHtml, meta.assets, meta.preloads, meta.inlineStyles, meta.tasks.length ? meta.tasks : "", nonce));
325
322
  },
326
323
  ...options.sink
327
324
  };
@@ -952,25 +949,36 @@ function resolveAssetsHtml(assets) {
952
949
  for (let i = 0, len = assets.length; i < len; i++) out += assets[i]();
953
950
  return out;
954
951
  }
955
- function injectBeforeHead(html, content) {
956
- if (!content) return html;
957
- const index = html.indexOf("</head>");
958
- if (index === -1) return html;
959
- return html.slice(0, index) + content + html.slice(index);
960
- }
961
- function injectPreloadLinks(emittedAssets, html, nonce) {
962
- if (!emittedAssets.size) return html;
963
- let links = "";
964
- for (const url of emittedAssets) {
965
- if (url.endsWith(".css")) {
966
- links += `<link rel="stylesheet" href="${url}">`;
967
- } else {
968
- links += `<link rel="modulepreload" href="${url}">`;
952
+ function assembleDocument(html, assetsHtml, emittedAssets, inlineStyles, scripts, nonce) {
953
+ const scriptTag = scripts ? `<script${nonce ? ` nonce="${nonce}"` : ""}>${scripts}</script>` : "";
954
+ if (!assetsHtml && !(emittedAssets && emittedAssets.size) && !(inlineStyles && inlineStyles.size)) {
955
+ if (!scriptTag) return html;
956
+ const xs = html.indexOf("<!--xs-->");
957
+ return xs === -1 ? html + scriptTag : html.slice(0, xs) + scriptTag + html.slice(xs);
958
+ }
959
+ const headIdx = html.indexOf("</head>");
960
+ if (headIdx === -1) {
961
+ if (!scriptTag) return html;
962
+ const xs = html.indexOf("<!--xs-->");
963
+ return xs === -1 ? html + scriptTag : html.slice(0, xs) + scriptTag + html.slice(xs);
964
+ }
965
+ let head = assetsHtml || "";
966
+ if (emittedAssets && emittedAssets.size) {
967
+ for (const url of emittedAssets) {
968
+ head += url.endsWith(".css") ? `<link rel="stylesheet" href="${url}">` : `<link rel="modulepreload" href="${url}">`;
969
+ }
970
+ }
971
+ if (inlineStyles && inlineStyles.size) {
972
+ for (const entry of inlineStyles.values()) {
973
+ if (entry.emitted) continue;
974
+ entry.emitted = true;
975
+ head += renderInlineStyle(entry, nonce);
969
976
  }
970
977
  }
971
- const index = html.indexOf("</head>");
972
- if (index === -1) return html;
973
- return html.slice(0, index) + links + html.slice(index);
978
+ if (!scriptTag) return html.slice(0, headIdx) + head + html.slice(headIdx);
979
+ const xsIdx = html.indexOf("<!--xs-->");
980
+ if (xsIdx === -1) return html.slice(0, headIdx) + head + html.slice(headIdx) + scriptTag;
981
+ return xsIdx < headIdx ? html.slice(0, xsIdx) + scriptTag + html.slice(xsIdx, headIdx) + head + html.slice(headIdx) : html.slice(0, headIdx) + head + html.slice(headIdx, xsIdx) + scriptTag + html.slice(xsIdx);
974
982
  }
975
983
  function serializeFragmentAssets(key, boundaryModules, context) {
976
984
  const map = boundaryModules.get(key);
@@ -1022,26 +1030,6 @@ function renderInlineStyle(entry, nonce) {
1022
1030
  }
1023
1031
  return `<style${nonce ? ` nonce="${nonce}"` : ""} data-asset="${escape(entry.id, true)}"${attrs}>${escapeStyleContent(entry.content)}</style>`;
1024
1032
  }
1025
- function injectInlineStyles(inlineStyles, html, nonce) {
1026
- if (!inlineStyles.size) return html;
1027
- const index = html.indexOf("</head>");
1028
- if (index === -1) return html;
1029
- let out = "";
1030
- for (const entry of inlineStyles.values()) {
1031
- if (entry.emitted) continue;
1032
- entry.emitted = true;
1033
- out += renderInlineStyle(entry, nonce);
1034
- }
1035
- return out ? html.slice(0, index) + out + html.slice(index) : html;
1036
- }
1037
- function injectScripts(html, scripts, nonce) {
1038
- const tag = `<script${nonce ? ` nonce="${nonce}"` : ""}>${scripts}</script>`;
1039
- const index = html.indexOf("<!--xs-->");
1040
- if (index > -1) {
1041
- return html.slice(0, index) + tag + html.slice(index);
1042
- }
1043
- return html + tag;
1044
- }
1045
1033
  function waitForFragments(registry, key) {
1046
1034
  for (const k of [...registry.keys()].reverse()) {
1047
1035
  if (key.startsWith(k)) return k;
@@ -1183,7 +1171,12 @@ function createFrameSink(emit, frame) {
1183
1171
  version
1184
1172
  } = frame;
1185
1173
  const styledKeys = new Set();
1174
+ const regionKeys = new Map();
1175
+ const frameOf = key => regionKeys.get(key) || id;
1186
1176
  return {
1177
+ tagRegion(key, childId) {
1178
+ if (!regionKeys.has(key)) regionKeys.set(key, childId);
1179
+ },
1187
1180
  shell(html, meta = {}) {
1188
1181
  if (meta.preloads && meta.preloads.size) {
1189
1182
  const styles = [];
@@ -1231,13 +1224,14 @@ function createFrameSink(emit, frame) {
1231
1224
  }
1232
1225
  },
1233
1226
  fragment(key, value, meta = {}) {
1227
+ const fid = frameOf(key);
1234
1228
  const links = meta.styles && meta.styles.links || [];
1235
1229
  const inline = meta.styles && meta.styles.inline || [];
1236
1230
  if (links.length || inline.length) {
1237
1231
  if (links.length) styledKeys.add(key);
1238
1232
  const chunk = {
1239
1233
  type: "assets",
1240
- id,
1234
+ id: fid,
1241
1235
  version,
1242
1236
  key
1243
1237
  };
@@ -1253,7 +1247,7 @@ function createFrameSink(emit, frame) {
1253
1247
  }
1254
1248
  emit({
1255
1249
  type: "fragment",
1256
- id,
1250
+ id: fid,
1257
1251
  version,
1258
1252
  key,
1259
1253
  html: value
@@ -1261,7 +1255,7 @@ function createFrameSink(emit, frame) {
1261
1255
  if (meta.error) {
1262
1256
  emit({
1263
1257
  type: "error",
1264
- id,
1258
+ id: fid,
1265
1259
  version,
1266
1260
  key,
1267
1261
  error: {
@@ -1272,7 +1266,7 @@ function createFrameSink(emit, frame) {
1272
1266
  if (!meta.revealGroup) {
1273
1267
  emit({
1274
1268
  type: "reveal",
1275
- id,
1269
+ id: fid,
1276
1270
  version,
1277
1271
  keys: [key],
1278
1272
  waitForStyles: !!links.length
@@ -1280,17 +1274,26 @@ function createFrameSink(emit, frame) {
1280
1274
  }
1281
1275
  },
1282
1276
  reveal(keys, meta = {}) {
1283
- let waitForStyles = false;
1284
- for (const key of keys) if (styledKeys.has(key)) waitForStyles = true;
1285
- const chunk = {
1286
- type: "reveal",
1287
- id,
1288
- version,
1289
- keys,
1290
- waitForStyles
1291
- };
1292
- if (meta.fallback) chunk.fallback = true;
1293
- emit(chunk);
1277
+ const byFrame = new Map();
1278
+ for (const key of keys) {
1279
+ const fid = frameOf(key);
1280
+ let group = byFrame.get(fid);
1281
+ if (!group) byFrame.set(fid, group = []);
1282
+ group.push(key);
1283
+ }
1284
+ for (const [fid, groupKeys] of byFrame) {
1285
+ let waitForStyles = false;
1286
+ for (const key of groupKeys) if (styledKeys.has(key)) waitForStyles = true;
1287
+ const chunk = {
1288
+ type: "reveal",
1289
+ id: fid,
1290
+ version,
1291
+ keys: groupKeys,
1292
+ waitForStyles
1293
+ };
1294
+ if (meta.fallback) chunk.fallback = true;
1295
+ emit(chunk);
1296
+ }
1294
1297
  },
1295
1298
  asset(type, url) {
1296
1299
  if (type !== "module") return;
@@ -1404,6 +1407,22 @@ function slotRange(occurrence) {
1404
1407
  t: `<!--slot:${occurrence}:start--><!--slot:${occurrence}:end-->`
1405
1408
  };
1406
1409
  }
1410
+ const OCCURRENCE_UNSAFE = /[^A-Za-z0-9_.-]/g;
1411
+ function encodeOccurrenceKey(key) {
1412
+ return String(key).replace(OCCURRENCE_UNSAFE, c => {
1413
+ const code = c.codePointAt(0);
1414
+ return "%" + (code < 16 ? "0" : "") + code.toString(16);
1415
+ });
1416
+ }
1417
+ function occurrenceId(prop, raw, counts) {
1418
+ const k = raw.$key;
1419
+ if (typeof k === "string" || typeof k === "number") {
1420
+ return `${prop}#${encodeOccurrenceKey(k)}`;
1421
+ }
1422
+ const n = counts[prop] || 0;
1423
+ counts[prop] = n + 1;
1424
+ return `${prop}#${n}`;
1425
+ }
1407
1426
  function createDocumentSlotProps(clientProps, frameId) {
1408
1427
  const counts = Object.create(null);
1409
1428
  const getters = new Map();
@@ -1440,36 +1459,37 @@ function createDocumentSlotProps(clientProps, frameId) {
1440
1459
  });
1441
1460
  }
1442
1461
  const raw = callArgs[0];
1443
- let occurrence;
1444
- const k = raw.$key;
1445
- if (typeof k === "string" || typeof k === "number") {
1446
- occurrence = `${prop}#${k}`;
1447
- } else {
1448
- const n = counts[prop] || 0;
1449
- counts[prop] = n + 1;
1450
- occurrence = `${prop}#${n}`;
1451
- }
1462
+ const occurrence = occurrenceId(prop, raw, counts);
1452
1463
  const slot = clientProps[prop];
1453
1464
  if (typeof slot !== "function") return range(occurrence, undefined);
1454
1465
  const resolved = {};
1455
- const regions = [];
1466
+ const vals = {};
1456
1467
  for (const key of Object.keys(raw)) {
1457
- const value = raw[key];
1458
- if (key !== "$key" && isServerContent(value)) {
1468
+ if (key === "$key") continue;
1469
+ let value = raw[key];
1470
+ for (let d = 0; typeof value === "function" && d < 16; d++) value = value();
1471
+ vals[key] = value;
1472
+ }
1473
+ const regions = [];
1474
+ for (const key of Object.keys(vals)) {
1475
+ const value = vals[key];
1476
+ if (isServerContent(value)) {
1459
1477
  const childId = `${frameId}.${occurrence}.${key}`;
1460
1478
  const region = {
1461
1479
  key,
1462
1480
  childId,
1463
1481
  value,
1464
- used: false
1482
+ used: false,
1483
+ locked: false
1465
1484
  };
1466
1485
  regions.push(region);
1467
1486
  resolved[key] = () => {
1487
+ if (region.locked) return [];
1468
1488
  region.used = true;
1469
1489
  return [{
1470
- t: `<!--frame:${childId}:start-->`
1490
+ t: frameElementOpen(childId)
1471
1491
  }, value, {
1472
- t: `<!--frame:${childId}:end-->`
1492
+ t: FRAME_ELEMENT_CLOSE
1473
1493
  }];
1474
1494
  };
1475
1495
  } else {
@@ -1479,12 +1499,10 @@ function createDocumentSlotProps(clientProps, frameId) {
1479
1499
  const out = scoped(occurrence, () => range(occurrence, slot(resolved)));
1480
1500
  const unused = regions.filter(r => !r.used);
1481
1501
  if (solidJs.sharedConfig.context) {
1482
- const rendered = renderedHtmlOf(out);
1483
1502
  const args = {};
1484
1503
  let any = false;
1485
- for (const key of Object.keys(raw)) {
1486
- const value = raw[key];
1487
- if (key === "$key") continue;
1504
+ for (const key of Object.keys(vals)) {
1505
+ const value = vals[key];
1488
1506
  const region = regions.find(r => r.key === key);
1489
1507
  if (region) {
1490
1508
  if (!region.used) {
@@ -1496,16 +1514,12 @@ function createDocumentSlotProps(clientProps, frameId) {
1496
1514
  continue;
1497
1515
  }
1498
1516
  if (isServerContent(value)) continue;
1499
- const t = typeof value;
1500
- if ((t === "string" || t === "number") && rendered !== null) {
1501
- const needle = t === "string" ? solidJs.sharedConfig.context.escape(String(value)) : String(value);
1502
- if (needle !== "" && rendered.includes(needle)) continue;
1503
- }
1504
1517
  args[key] = value;
1505
1518
  any = true;
1506
1519
  }
1507
1520
  if (any) solidJs.sharedConfig.context.serialize(`sc:slot:${frameId}:${occurrence}`, args);
1508
1521
  for (const region of unused) {
1522
+ region.locked = true;
1509
1523
  solidJs.sharedConfig.context.serialize(`sc:region:${region.childId}`, resolveRegionHtml(solidJs.sharedConfig.context, region.value));
1510
1524
  }
1511
1525
  }
@@ -1517,28 +1531,26 @@ function createDocumentSlotProps(clientProps, frameId) {
1517
1531
  }
1518
1532
  });
1519
1533
  }
1534
+ const FRAME_TAG = "dx-frame";
1535
+ const FRAME_ID_ATTR = "data-fid";
1536
+ function frameElementOpen(id) {
1537
+ const escaped = solidJs.sharedConfig.context ? solidJs.sharedConfig.context.escape(String(id), true) : String(id);
1538
+ return `<${FRAME_TAG} ${FRAME_ID_ATTR}="${escaped}" style="display:contents">`;
1539
+ }
1540
+ const FRAME_ELEMENT_CLOSE = `</${FRAME_TAG}>`;
1520
1541
  function frameTransformDirectResult(value, {
1521
1542
  id
1522
1543
  }) {
1523
1544
  if (typeof value !== "function") return value;
1524
1545
  const component = value;
1525
1546
  const wrapped = props => [{
1526
- t: `<!--frame:${id}:start-->`
1547
+ t: frameElementOpen(id)
1527
1548
  }, serverOwned(() => component(createDocumentSlotProps(props, id))), {
1528
- t: `<!--frame:${id}:end-->`
1549
+ t: FRAME_ELEMENT_CLOSE
1529
1550
  }];
1530
1551
  wrapped[SERVER_COMPONENT] = id;
1531
1552
  return wrapped;
1532
1553
  }
1533
- function renderedHtmlOf(out) {
1534
- try {
1535
- const res = solidJs.sharedConfig.context.resolve(out);
1536
- if (res && res.t && (!res.h || !res.h.length)) {
1537
- return res.t[0].replace(/<!--[^>]*-->/g, "").replace(/ _hk=("[^"]*"|[^\s>]+)/g, "");
1538
- }
1539
- } catch (e) {}
1540
- return null;
1541
- }
1542
1554
  function resolveRegionHtml(ctx, node) {
1543
1555
  const res = ctx.resolve(node);
1544
1556
  if (!res || !res.t) return String(res ?? "");
@@ -1613,37 +1625,41 @@ function createSlotProps(sink, frame) {
1613
1625
  return slotRange(prop);
1614
1626
  }
1615
1627
  const raw = callArgs[0];
1616
- let occurrence;
1617
- const k = raw.$key;
1618
- if (typeof k === "string" || typeof k === "number") {
1619
- occurrence = `${prop}#${k}`;
1620
- } else {
1621
- const n = counts[prop] || 0;
1622
- counts[prop] = n + 1;
1623
- occurrence = `${prop}#${n}`;
1624
- }
1628
+ const occurrence = occurrenceId(prop, raw, counts);
1625
1629
  const args = {};
1626
1630
  for (const key of Object.keys(raw)) {
1627
- const value = raw[key];
1628
- const t = typeof value;
1629
- if (value == null || t === "string" || t === "number" || t === "boolean") {
1630
- args[key] = value;
1631
- } else if (isServerContent(value)) {
1632
- const resolved = solidJs.sharedConfig.context.resolve(value);
1633
- if (resolved.h.length) {
1634
- throw new Error("Async server content in slot args is not supported yet (arg '" + key + "' of " + occurrence + "). Move the async read above the slot or into a fragment.");
1631
+ if (key === "$key") continue;
1632
+ const childId = `${frame.id}.${occurrence}.${key}`;
1633
+ const ctx = solidJs.sharedConfig.context;
1634
+ const origRegister = ctx.registerFragment;
1635
+ ctx.registerFragment = (fragKey, fragOptions) => {
1636
+ sink.tagRegion(fragKey, childId);
1637
+ return origRegister.call(ctx, fragKey, fragOptions);
1638
+ };
1639
+ try {
1640
+ let value = raw[key];
1641
+ for (let d = 0; typeof value === "function" && d < 16; d++) value = value();
1642
+ const t = typeof value;
1643
+ if (value == null || t === "string" || t === "number" || t === "boolean") {
1644
+ args[key] = value;
1645
+ } else if (isServerContent(value)) {
1646
+ const resolved = ctx.resolve(value);
1647
+ if (resolved.h.length) {
1648
+ throw new Error("Async server content in a slot arg needs a boundary (arg '" + key + "' of " + occurrence + "). Wrap the async read in a <Suspense>, or move it above the slot.");
1649
+ }
1650
+ sink.region(childId, resolved.t[0]);
1651
+ args[key] = {
1652
+ $frame: childId
1653
+ };
1654
+ } else {
1655
+ const ref = `arg:${occurrence}:${key}`;
1656
+ ctx.serialize(ref, value);
1657
+ args[key] = {
1658
+ $ref: ref
1659
+ };
1635
1660
  }
1636
- const childId = `${frame.id}.${occurrence}.${key}`;
1637
- sink.region(childId, resolved.t[0]);
1638
- args[key] = {
1639
- $frame: childId
1640
- };
1641
- } else {
1642
- const ref = `arg:${occurrence}:${key}`;
1643
- solidJs.sharedConfig.context.serialize(ref, value);
1644
- args[key] = {
1645
- $ref: ref
1646
- };
1661
+ } finally {
1662
+ ctx.registerFragment = origRegister;
1647
1663
  }
1648
1664
  }
1649
1665
  sink.slot(occurrence, args);