@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.
- package/dist/dev.cjs +14 -9
- package/dist/dev.js +14 -10
- package/dist/server.cjs +41 -78
- package/dist/server.js +42 -80
- package/dist/web.cjs +14 -9
- package/dist/web.js +14 -10
- package/frames/dist/client.cjs +180 -224
- package/frames/dist/client.dev.cjs +1456 -0
- package/frames/dist/client.dev.js +1444 -0
- package/frames/dist/client.js +181 -225
- package/frames/dist/server.cjs +139 -123
- package/frames/dist/server.js +139 -123
- package/package.json +24 -4
- package/serialization/dist/serialization.cjs +6 -3
- package/serialization/dist/serialization.js +6 -3
- package/serialization/types/index.d.ts +7 -1
- package/serialization/types-cjs/index.d.cts +7 -1
- package/server-functions/dist/client.cjs +18 -5
- package/server-functions/dist/client.js +16 -6
- package/server-functions/dist/server.cjs +164 -8
- package/server-functions/dist/server.js +158 -9
- package/types/client.d.ts +3 -3
- package/types/frames/client.d.ts +1 -1
- package/types/frames/frame-client.d.ts +34 -28
- package/types/frames/serializer.d.ts +7 -1
- package/types/jsx.d.ts +1 -1
- package/types/response.d.ts +10 -0
- package/types/serializer.d.ts +7 -1
- package/types/server-functions/client.d.ts +3 -0
- package/types/server-functions/flash.d.ts +38 -0
- package/types/server-functions/server.d.ts +79 -4
- package/types/server-functions/shared.d.ts +35 -0
- package/types-cjs/client.d.cts +3 -3
- package/types-cjs/frames/client.d.cts +1 -1
- package/types-cjs/frames/frame-client.d.cts +34 -28
- package/types-cjs/frames/serializer.d.cts +7 -1
- package/types-cjs/jsx.d.cts +1 -1
- package/types-cjs/response.d.cts +10 -0
- package/types-cjs/serializer.d.cts +7 -1
- package/types-cjs/server-functions/client.d.cts +3 -0
- package/types-cjs/server-functions/flash.d.cts +38 -0
- package/types-cjs/server-functions/server.d.cts +79 -4
- package/types-cjs/server-functions/shared.d.cts +35 -0
package/frames/dist/server.js
CHANGED
|
@@ -7,6 +7,7 @@ const runWithHydrationScope = (id, fn) => runWithOwner(createOwner({
|
|
|
7
7
|
}), fn);
|
|
8
8
|
|
|
9
9
|
const DEFAULT_DISABLED_FEATURES = Feature.AggregateError | Feature.BigIntTypedArray;
|
|
10
|
+
const serializeOnlyDisabledFeatures = () => process.env.NODE_ENV === "development" ? 0 : Feature.ErrorPrototypeStack;
|
|
10
11
|
const HYDRATION_GLOBAL = "_$HY.r";
|
|
11
12
|
const DEFAULT_WEB_PLUGINS = Object.freeze([AbortSignalPlugin,
|
|
12
13
|
CustomEventPlugin, DOMExceptionPlugin, EventPlugin,
|
|
@@ -18,7 +19,7 @@ function createSerializer(options) {
|
|
|
18
19
|
return new Serializer({
|
|
19
20
|
...options,
|
|
20
21
|
plugins: resolveSerializerPlugins(options.plugins),
|
|
21
|
-
disabledFeatures: options.disabledFeatures === undefined ? DEFAULT_DISABLED_FEATURES : options.disabledFeatures
|
|
22
|
+
disabledFeatures: (options.disabledFeatures === undefined ? DEFAULT_DISABLED_FEATURES : options.disabledFeatures) | serializeOnlyDisabledFeatures()
|
|
22
23
|
});
|
|
23
24
|
}
|
|
24
25
|
function createHydrationSerializer({
|
|
@@ -86,7 +87,7 @@ function createJSONSerializer({
|
|
|
86
87
|
const stream = toCrossJSONStream(value, {
|
|
87
88
|
refs,
|
|
88
89
|
plugins: resolved.plugins,
|
|
89
|
-
disabledFeatures: resolved.disabledFeatures,
|
|
90
|
+
disabledFeatures: resolved.disabledFeatures | serializeOnlyDisabledFeatures(),
|
|
90
91
|
onParse(node, initial) {
|
|
91
92
|
onData({
|
|
92
93
|
key,
|
|
@@ -243,7 +244,7 @@ function applyAssetTracking(context, tracking, manifest) {
|
|
|
243
244
|
context.resolveAssetsSync = resolve;
|
|
244
245
|
}
|
|
245
246
|
}
|
|
246
|
-
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])}`;
|
|
247
|
+
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])}`;
|
|
247
248
|
function renderToStream(code, options = {}) {
|
|
248
249
|
let {
|
|
249
250
|
nonce,
|
|
@@ -315,11 +316,7 @@ function renderToStream(code, options = {}) {
|
|
|
315
316
|
}
|
|
316
317
|
},
|
|
317
318
|
shell(shellHtml, meta) {
|
|
318
|
-
shellHtml
|
|
319
|
-
shellHtml = injectPreloadLinks(meta.preloads, shellHtml);
|
|
320
|
-
shellHtml = injectInlineStyles(meta.inlineStyles, shellHtml, nonce);
|
|
321
|
-
if (meta.tasks.length) shellHtml = injectScripts(shellHtml, meta.tasks, nonce);
|
|
322
|
-
buffer.write(shellHtml);
|
|
319
|
+
buffer.write(assembleDocument(shellHtml, meta.assets, meta.preloads, meta.inlineStyles, meta.tasks.length ? meta.tasks : "", nonce));
|
|
323
320
|
},
|
|
324
321
|
...options.sink
|
|
325
322
|
};
|
|
@@ -950,25 +947,36 @@ function resolveAssetsHtml(assets) {
|
|
|
950
947
|
for (let i = 0, len = assets.length; i < len; i++) out += assets[i]();
|
|
951
948
|
return out;
|
|
952
949
|
}
|
|
953
|
-
function
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
950
|
+
function assembleDocument(html, assetsHtml, emittedAssets, inlineStyles, scripts, nonce) {
|
|
951
|
+
const scriptTag = scripts ? `<script${nonce ? ` nonce="${nonce}"` : ""}>${scripts}</script>` : "";
|
|
952
|
+
if (!assetsHtml && !(emittedAssets && emittedAssets.size) && !(inlineStyles && inlineStyles.size)) {
|
|
953
|
+
if (!scriptTag) return html;
|
|
954
|
+
const xs = html.indexOf("<!--xs-->");
|
|
955
|
+
return xs === -1 ? html + scriptTag : html.slice(0, xs) + scriptTag + html.slice(xs);
|
|
956
|
+
}
|
|
957
|
+
const headIdx = html.indexOf("</head>");
|
|
958
|
+
if (headIdx === -1) {
|
|
959
|
+
if (!scriptTag) return html;
|
|
960
|
+
const xs = html.indexOf("<!--xs-->");
|
|
961
|
+
return xs === -1 ? html + scriptTag : html.slice(0, xs) + scriptTag + html.slice(xs);
|
|
962
|
+
}
|
|
963
|
+
let head = assetsHtml || "";
|
|
964
|
+
if (emittedAssets && emittedAssets.size) {
|
|
965
|
+
for (const url of emittedAssets) {
|
|
966
|
+
head += url.endsWith(".css") ? `<link rel="stylesheet" href="${url}">` : `<link rel="modulepreload" href="${url}">`;
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
if (inlineStyles && inlineStyles.size) {
|
|
970
|
+
for (const entry of inlineStyles.values()) {
|
|
971
|
+
if (entry.emitted) continue;
|
|
972
|
+
entry.emitted = true;
|
|
973
|
+
head += renderInlineStyle(entry, nonce);
|
|
967
974
|
}
|
|
968
975
|
}
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
return html.slice(0,
|
|
976
|
+
if (!scriptTag) return html.slice(0, headIdx) + head + html.slice(headIdx);
|
|
977
|
+
const xsIdx = html.indexOf("<!--xs-->");
|
|
978
|
+
if (xsIdx === -1) return html.slice(0, headIdx) + head + html.slice(headIdx) + scriptTag;
|
|
979
|
+
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);
|
|
972
980
|
}
|
|
973
981
|
function serializeFragmentAssets(key, boundaryModules, context) {
|
|
974
982
|
const map = boundaryModules.get(key);
|
|
@@ -1020,26 +1028,6 @@ function renderInlineStyle(entry, nonce) {
|
|
|
1020
1028
|
}
|
|
1021
1029
|
return `<style${nonce ? ` nonce="${nonce}"` : ""} data-asset="${escape(entry.id, true)}"${attrs}>${escapeStyleContent(entry.content)}</style>`;
|
|
1022
1030
|
}
|
|
1023
|
-
function injectInlineStyles(inlineStyles, html, nonce) {
|
|
1024
|
-
if (!inlineStyles.size) return html;
|
|
1025
|
-
const index = html.indexOf("</head>");
|
|
1026
|
-
if (index === -1) return html;
|
|
1027
|
-
let out = "";
|
|
1028
|
-
for (const entry of inlineStyles.values()) {
|
|
1029
|
-
if (entry.emitted) continue;
|
|
1030
|
-
entry.emitted = true;
|
|
1031
|
-
out += renderInlineStyle(entry, nonce);
|
|
1032
|
-
}
|
|
1033
|
-
return out ? html.slice(0, index) + out + html.slice(index) : html;
|
|
1034
|
-
}
|
|
1035
|
-
function injectScripts(html, scripts, nonce) {
|
|
1036
|
-
const tag = `<script${nonce ? ` nonce="${nonce}"` : ""}>${scripts}</script>`;
|
|
1037
|
-
const index = html.indexOf("<!--xs-->");
|
|
1038
|
-
if (index > -1) {
|
|
1039
|
-
return html.slice(0, index) + tag + html.slice(index);
|
|
1040
|
-
}
|
|
1041
|
-
return html + tag;
|
|
1042
|
-
}
|
|
1043
1031
|
function waitForFragments(registry, key) {
|
|
1044
1032
|
for (const k of [...registry.keys()].reverse()) {
|
|
1045
1033
|
if (key.startsWith(k)) return k;
|
|
@@ -1181,7 +1169,12 @@ function createFrameSink(emit, frame) {
|
|
|
1181
1169
|
version
|
|
1182
1170
|
} = frame;
|
|
1183
1171
|
const styledKeys = new Set();
|
|
1172
|
+
const regionKeys = new Map();
|
|
1173
|
+
const frameOf = key => regionKeys.get(key) || id;
|
|
1184
1174
|
return {
|
|
1175
|
+
tagRegion(key, childId) {
|
|
1176
|
+
if (!regionKeys.has(key)) regionKeys.set(key, childId);
|
|
1177
|
+
},
|
|
1185
1178
|
shell(html, meta = {}) {
|
|
1186
1179
|
if (meta.preloads && meta.preloads.size) {
|
|
1187
1180
|
const styles = [];
|
|
@@ -1229,13 +1222,14 @@ function createFrameSink(emit, frame) {
|
|
|
1229
1222
|
}
|
|
1230
1223
|
},
|
|
1231
1224
|
fragment(key, value, meta = {}) {
|
|
1225
|
+
const fid = frameOf(key);
|
|
1232
1226
|
const links = meta.styles && meta.styles.links || [];
|
|
1233
1227
|
const inline = meta.styles && meta.styles.inline || [];
|
|
1234
1228
|
if (links.length || inline.length) {
|
|
1235
1229
|
if (links.length) styledKeys.add(key);
|
|
1236
1230
|
const chunk = {
|
|
1237
1231
|
type: "assets",
|
|
1238
|
-
id,
|
|
1232
|
+
id: fid,
|
|
1239
1233
|
version,
|
|
1240
1234
|
key
|
|
1241
1235
|
};
|
|
@@ -1251,7 +1245,7 @@ function createFrameSink(emit, frame) {
|
|
|
1251
1245
|
}
|
|
1252
1246
|
emit({
|
|
1253
1247
|
type: "fragment",
|
|
1254
|
-
id,
|
|
1248
|
+
id: fid,
|
|
1255
1249
|
version,
|
|
1256
1250
|
key,
|
|
1257
1251
|
html: value
|
|
@@ -1259,7 +1253,7 @@ function createFrameSink(emit, frame) {
|
|
|
1259
1253
|
if (meta.error) {
|
|
1260
1254
|
emit({
|
|
1261
1255
|
type: "error",
|
|
1262
|
-
id,
|
|
1256
|
+
id: fid,
|
|
1263
1257
|
version,
|
|
1264
1258
|
key,
|
|
1265
1259
|
error: {
|
|
@@ -1270,7 +1264,7 @@ function createFrameSink(emit, frame) {
|
|
|
1270
1264
|
if (!meta.revealGroup) {
|
|
1271
1265
|
emit({
|
|
1272
1266
|
type: "reveal",
|
|
1273
|
-
id,
|
|
1267
|
+
id: fid,
|
|
1274
1268
|
version,
|
|
1275
1269
|
keys: [key],
|
|
1276
1270
|
waitForStyles: !!links.length
|
|
@@ -1278,17 +1272,26 @@ function createFrameSink(emit, frame) {
|
|
|
1278
1272
|
}
|
|
1279
1273
|
},
|
|
1280
1274
|
reveal(keys, meta = {}) {
|
|
1281
|
-
|
|
1282
|
-
for (const key of keys)
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1275
|
+
const byFrame = new Map();
|
|
1276
|
+
for (const key of keys) {
|
|
1277
|
+
const fid = frameOf(key);
|
|
1278
|
+
let group = byFrame.get(fid);
|
|
1279
|
+
if (!group) byFrame.set(fid, group = []);
|
|
1280
|
+
group.push(key);
|
|
1281
|
+
}
|
|
1282
|
+
for (const [fid, groupKeys] of byFrame) {
|
|
1283
|
+
let waitForStyles = false;
|
|
1284
|
+
for (const key of groupKeys) if (styledKeys.has(key)) waitForStyles = true;
|
|
1285
|
+
const chunk = {
|
|
1286
|
+
type: "reveal",
|
|
1287
|
+
id: fid,
|
|
1288
|
+
version,
|
|
1289
|
+
keys: groupKeys,
|
|
1290
|
+
waitForStyles
|
|
1291
|
+
};
|
|
1292
|
+
if (meta.fallback) chunk.fallback = true;
|
|
1293
|
+
emit(chunk);
|
|
1294
|
+
}
|
|
1292
1295
|
},
|
|
1293
1296
|
asset(type, url) {
|
|
1294
1297
|
if (type !== "module") return;
|
|
@@ -1402,6 +1405,22 @@ function slotRange(occurrence) {
|
|
|
1402
1405
|
t: `<!--slot:${occurrence}:start--><!--slot:${occurrence}:end-->`
|
|
1403
1406
|
};
|
|
1404
1407
|
}
|
|
1408
|
+
const OCCURRENCE_UNSAFE = /[^A-Za-z0-9_.-]/g;
|
|
1409
|
+
function encodeOccurrenceKey(key) {
|
|
1410
|
+
return String(key).replace(OCCURRENCE_UNSAFE, c => {
|
|
1411
|
+
const code = c.codePointAt(0);
|
|
1412
|
+
return "%" + (code < 16 ? "0" : "") + code.toString(16);
|
|
1413
|
+
});
|
|
1414
|
+
}
|
|
1415
|
+
function occurrenceId(prop, raw, counts) {
|
|
1416
|
+
const k = raw.$key;
|
|
1417
|
+
if (typeof k === "string" || typeof k === "number") {
|
|
1418
|
+
return `${prop}#${encodeOccurrenceKey(k)}`;
|
|
1419
|
+
}
|
|
1420
|
+
const n = counts[prop] || 0;
|
|
1421
|
+
counts[prop] = n + 1;
|
|
1422
|
+
return `${prop}#${n}`;
|
|
1423
|
+
}
|
|
1405
1424
|
function createDocumentSlotProps(clientProps, frameId) {
|
|
1406
1425
|
const counts = Object.create(null);
|
|
1407
1426
|
const getters = new Map();
|
|
@@ -1438,36 +1457,37 @@ function createDocumentSlotProps(clientProps, frameId) {
|
|
|
1438
1457
|
});
|
|
1439
1458
|
}
|
|
1440
1459
|
const raw = callArgs[0];
|
|
1441
|
-
|
|
1442
|
-
const k = raw.$key;
|
|
1443
|
-
if (typeof k === "string" || typeof k === "number") {
|
|
1444
|
-
occurrence = `${prop}#${k}`;
|
|
1445
|
-
} else {
|
|
1446
|
-
const n = counts[prop] || 0;
|
|
1447
|
-
counts[prop] = n + 1;
|
|
1448
|
-
occurrence = `${prop}#${n}`;
|
|
1449
|
-
}
|
|
1460
|
+
const occurrence = occurrenceId(prop, raw, counts);
|
|
1450
1461
|
const slot = clientProps[prop];
|
|
1451
1462
|
if (typeof slot !== "function") return range(occurrence, undefined);
|
|
1452
1463
|
const resolved = {};
|
|
1453
|
-
const
|
|
1464
|
+
const vals = {};
|
|
1454
1465
|
for (const key of Object.keys(raw)) {
|
|
1455
|
-
|
|
1456
|
-
|
|
1466
|
+
if (key === "$key") continue;
|
|
1467
|
+
let value = raw[key];
|
|
1468
|
+
for (let d = 0; typeof value === "function" && d < 16; d++) value = value();
|
|
1469
|
+
vals[key] = value;
|
|
1470
|
+
}
|
|
1471
|
+
const regions = [];
|
|
1472
|
+
for (const key of Object.keys(vals)) {
|
|
1473
|
+
const value = vals[key];
|
|
1474
|
+
if (isServerContent(value)) {
|
|
1457
1475
|
const childId = `${frameId}.${occurrence}.${key}`;
|
|
1458
1476
|
const region = {
|
|
1459
1477
|
key,
|
|
1460
1478
|
childId,
|
|
1461
1479
|
value,
|
|
1462
|
-
used: false
|
|
1480
|
+
used: false,
|
|
1481
|
+
locked: false
|
|
1463
1482
|
};
|
|
1464
1483
|
regions.push(region);
|
|
1465
1484
|
resolved[key] = () => {
|
|
1485
|
+
if (region.locked) return [];
|
|
1466
1486
|
region.used = true;
|
|
1467
1487
|
return [{
|
|
1468
|
-
t:
|
|
1488
|
+
t: frameElementOpen(childId)
|
|
1469
1489
|
}, value, {
|
|
1470
|
-
t:
|
|
1490
|
+
t: FRAME_ELEMENT_CLOSE
|
|
1471
1491
|
}];
|
|
1472
1492
|
};
|
|
1473
1493
|
} else {
|
|
@@ -1477,12 +1497,10 @@ function createDocumentSlotProps(clientProps, frameId) {
|
|
|
1477
1497
|
const out = scoped(occurrence, () => range(occurrence, slot(resolved)));
|
|
1478
1498
|
const unused = regions.filter(r => !r.used);
|
|
1479
1499
|
if (sharedConfig.context) {
|
|
1480
|
-
const rendered = renderedHtmlOf(out);
|
|
1481
1500
|
const args = {};
|
|
1482
1501
|
let any = false;
|
|
1483
|
-
for (const key of Object.keys(
|
|
1484
|
-
const value =
|
|
1485
|
-
if (key === "$key") continue;
|
|
1502
|
+
for (const key of Object.keys(vals)) {
|
|
1503
|
+
const value = vals[key];
|
|
1486
1504
|
const region = regions.find(r => r.key === key);
|
|
1487
1505
|
if (region) {
|
|
1488
1506
|
if (!region.used) {
|
|
@@ -1494,16 +1512,12 @@ function createDocumentSlotProps(clientProps, frameId) {
|
|
|
1494
1512
|
continue;
|
|
1495
1513
|
}
|
|
1496
1514
|
if (isServerContent(value)) continue;
|
|
1497
|
-
const t = typeof value;
|
|
1498
|
-
if ((t === "string" || t === "number") && rendered !== null) {
|
|
1499
|
-
const needle = t === "string" ? sharedConfig.context.escape(String(value)) : String(value);
|
|
1500
|
-
if (needle !== "" && rendered.includes(needle)) continue;
|
|
1501
|
-
}
|
|
1502
1515
|
args[key] = value;
|
|
1503
1516
|
any = true;
|
|
1504
1517
|
}
|
|
1505
1518
|
if (any) sharedConfig.context.serialize(`sc:slot:${frameId}:${occurrence}`, args);
|
|
1506
1519
|
for (const region of unused) {
|
|
1520
|
+
region.locked = true;
|
|
1507
1521
|
sharedConfig.context.serialize(`sc:region:${region.childId}`, resolveRegionHtml(sharedConfig.context, region.value));
|
|
1508
1522
|
}
|
|
1509
1523
|
}
|
|
@@ -1515,28 +1529,26 @@ function createDocumentSlotProps(clientProps, frameId) {
|
|
|
1515
1529
|
}
|
|
1516
1530
|
});
|
|
1517
1531
|
}
|
|
1532
|
+
const FRAME_TAG = "dx-frame";
|
|
1533
|
+
const FRAME_ID_ATTR = "data-fid";
|
|
1534
|
+
function frameElementOpen(id) {
|
|
1535
|
+
const escaped = sharedConfig.context ? sharedConfig.context.escape(String(id), true) : String(id);
|
|
1536
|
+
return `<${FRAME_TAG} ${FRAME_ID_ATTR}="${escaped}" style="display:contents">`;
|
|
1537
|
+
}
|
|
1538
|
+
const FRAME_ELEMENT_CLOSE = `</${FRAME_TAG}>`;
|
|
1518
1539
|
function frameTransformDirectResult(value, {
|
|
1519
1540
|
id
|
|
1520
1541
|
}) {
|
|
1521
1542
|
if (typeof value !== "function") return value;
|
|
1522
1543
|
const component = value;
|
|
1523
1544
|
const wrapped = props => [{
|
|
1524
|
-
t:
|
|
1545
|
+
t: frameElementOpen(id)
|
|
1525
1546
|
}, serverOwned(() => component(createDocumentSlotProps(props, id))), {
|
|
1526
|
-
t:
|
|
1547
|
+
t: FRAME_ELEMENT_CLOSE
|
|
1527
1548
|
}];
|
|
1528
1549
|
wrapped[SERVER_COMPONENT] = id;
|
|
1529
1550
|
return wrapped;
|
|
1530
1551
|
}
|
|
1531
|
-
function renderedHtmlOf(out) {
|
|
1532
|
-
try {
|
|
1533
|
-
const res = sharedConfig.context.resolve(out);
|
|
1534
|
-
if (res && res.t && (!res.h || !res.h.length)) {
|
|
1535
|
-
return res.t[0].replace(/<!--[^>]*-->/g, "").replace(/ _hk=("[^"]*"|[^\s>]+)/g, "");
|
|
1536
|
-
}
|
|
1537
|
-
} catch (e) {}
|
|
1538
|
-
return null;
|
|
1539
|
-
}
|
|
1540
1552
|
function resolveRegionHtml(ctx, node) {
|
|
1541
1553
|
const res = ctx.resolve(node);
|
|
1542
1554
|
if (!res || !res.t) return String(res ?? "");
|
|
@@ -1611,37 +1623,41 @@ function createSlotProps(sink, frame) {
|
|
|
1611
1623
|
return slotRange(prop);
|
|
1612
1624
|
}
|
|
1613
1625
|
const raw = callArgs[0];
|
|
1614
|
-
|
|
1615
|
-
const k = raw.$key;
|
|
1616
|
-
if (typeof k === "string" || typeof k === "number") {
|
|
1617
|
-
occurrence = `${prop}#${k}`;
|
|
1618
|
-
} else {
|
|
1619
|
-
const n = counts[prop] || 0;
|
|
1620
|
-
counts[prop] = n + 1;
|
|
1621
|
-
occurrence = `${prop}#${n}`;
|
|
1622
|
-
}
|
|
1626
|
+
const occurrence = occurrenceId(prop, raw, counts);
|
|
1623
1627
|
const args = {};
|
|
1624
1628
|
for (const key of Object.keys(raw)) {
|
|
1625
|
-
|
|
1626
|
-
const
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1629
|
+
if (key === "$key") continue;
|
|
1630
|
+
const childId = `${frame.id}.${occurrence}.${key}`;
|
|
1631
|
+
const ctx = sharedConfig.context;
|
|
1632
|
+
const origRegister = ctx.registerFragment;
|
|
1633
|
+
ctx.registerFragment = (fragKey, fragOptions) => {
|
|
1634
|
+
sink.tagRegion(fragKey, childId);
|
|
1635
|
+
return origRegister.call(ctx, fragKey, fragOptions);
|
|
1636
|
+
};
|
|
1637
|
+
try {
|
|
1638
|
+
let value = raw[key];
|
|
1639
|
+
for (let d = 0; typeof value === "function" && d < 16; d++) value = value();
|
|
1640
|
+
const t = typeof value;
|
|
1641
|
+
if (value == null || t === "string" || t === "number" || t === "boolean") {
|
|
1642
|
+
args[key] = value;
|
|
1643
|
+
} else if (isServerContent(value)) {
|
|
1644
|
+
const resolved = ctx.resolve(value);
|
|
1645
|
+
if (resolved.h.length) {
|
|
1646
|
+
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.");
|
|
1647
|
+
}
|
|
1648
|
+
sink.region(childId, resolved.t[0]);
|
|
1649
|
+
args[key] = {
|
|
1650
|
+
$frame: childId
|
|
1651
|
+
};
|
|
1652
|
+
} else {
|
|
1653
|
+
const ref = `arg:${occurrence}:${key}`;
|
|
1654
|
+
ctx.serialize(ref, value);
|
|
1655
|
+
args[key] = {
|
|
1656
|
+
$ref: ref
|
|
1657
|
+
};
|
|
1633
1658
|
}
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
args[key] = {
|
|
1637
|
-
$frame: childId
|
|
1638
|
-
};
|
|
1639
|
-
} else {
|
|
1640
|
-
const ref = `arg:${occurrence}:${key}`;
|
|
1641
|
-
sharedConfig.context.serialize(ref, value);
|
|
1642
|
-
args[key] = {
|
|
1643
|
-
$ref: ref
|
|
1644
|
-
};
|
|
1659
|
+
} finally {
|
|
1660
|
+
ctx.registerFragment = origRegister;
|
|
1645
1661
|
}
|
|
1646
1662
|
}
|
|
1647
1663
|
sink.slot(occurrence, args);
|
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.
|
|
4
|
+
"version": "2.0.0-beta.27",
|
|
5
5
|
"author": "Ryan Carniato",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"homepage": "https://solidjs.com",
|
|
@@ -231,6 +231,16 @@
|
|
|
231
231
|
}
|
|
232
232
|
},
|
|
233
233
|
"browser": {
|
|
234
|
+
"development": {
|
|
235
|
+
"import": {
|
|
236
|
+
"types": "./types/frames/client.d.ts",
|
|
237
|
+
"default": "./frames/dist/client.dev.js"
|
|
238
|
+
},
|
|
239
|
+
"require": {
|
|
240
|
+
"types": "./types-cjs/frames/client.d.cts",
|
|
241
|
+
"default": "./frames/dist/client.dev.cjs"
|
|
242
|
+
}
|
|
243
|
+
},
|
|
234
244
|
"import": {
|
|
235
245
|
"types": "./types/frames/client.d.ts",
|
|
236
246
|
"default": "./frames/dist/client.js"
|
|
@@ -260,6 +270,16 @@
|
|
|
260
270
|
"default": "./frames/dist/server.cjs"
|
|
261
271
|
}
|
|
262
272
|
},
|
|
273
|
+
"development": {
|
|
274
|
+
"import": {
|
|
275
|
+
"types": "./types/frames/client.d.ts",
|
|
276
|
+
"default": "./frames/dist/client.dev.js"
|
|
277
|
+
},
|
|
278
|
+
"require": {
|
|
279
|
+
"types": "./types-cjs/frames/client.d.cts",
|
|
280
|
+
"default": "./frames/dist/client.dev.cjs"
|
|
281
|
+
}
|
|
282
|
+
},
|
|
263
283
|
"import": {
|
|
264
284
|
"types": "./types/frames/client.d.ts",
|
|
265
285
|
"default": "./frames/dist/client.js"
|
|
@@ -296,10 +316,10 @@
|
|
|
296
316
|
"seroval-plugins": "~1.5.4"
|
|
297
317
|
},
|
|
298
318
|
"peerDependencies": {
|
|
299
|
-
"solid-js": "^2.0.0-beta.
|
|
319
|
+
"solid-js": "^2.0.0-beta.27"
|
|
300
320
|
},
|
|
301
321
|
"devDependencies": {
|
|
302
|
-
"solid-js": "2.0.0-beta.
|
|
322
|
+
"solid-js": "2.0.0-beta.27"
|
|
303
323
|
},
|
|
304
324
|
"scripts": {
|
|
305
325
|
"build": "npm-run-all -nl build:clean types:copy-jsx build:js",
|
|
@@ -314,7 +334,7 @@
|
|
|
314
334
|
"types:web-storage": "tsc --project ./storage/tsconfig.build.json",
|
|
315
335
|
"types:web-frames": "tsc --project ./frames/tsconfig.build.json",
|
|
316
336
|
"types:copy-serialization": "node -e \"fs.mkdirSync('./serialization/types', { recursive: true }); fs.copyFileSync('../../node_modules/@dom-expressions/runtime/src/serializer.d.ts', './serialization/types/index.d.ts');\"",
|
|
317
|
-
"types:copy-server-functions": "node -e \"fs.mkdirSync('./types/server-functions', { recursive: true }); for (const f of ['shared', 'client', 'server']) fs.copyFileSync('../../node_modules/@dom-expressions/runtime/src/server-functions/' + f + '.d.ts', './types/server-functions/' + f + '.d.ts');\"",
|
|
337
|
+
"types:copy-server-functions": "node -e \"fs.mkdirSync('./types/server-functions', { recursive: true }); for (const f of ['shared', 'flash', 'client', 'server']) fs.copyFileSync('../../node_modules/@dom-expressions/runtime/src/server-functions/' + f + '.d.ts', './types/server-functions/' + f + '.d.ts');\"",
|
|
318
338
|
"types:copy-frames": "node -e \"fs.mkdirSync('./types/frames', { recursive: true }); for (const f of ['frame-client', 'frame-transport', 'frame-sink', 'serializer']) fs.copyFileSync('../../node_modules/@dom-expressions/runtime/src/' + f + '.d.ts', './types/frames/' + f + '.d.ts'); for (const f of ['client', 'server']) fs.writeFileSync('./types/frames/' + f + '.d.ts', fs.readFileSync('./frames/types/' + f + '.d.ts', 'utf8').replaceAll('@dom-expressions/runtime/src/', './'));\"",
|
|
319
339
|
"types:cjs": "node ../../scripts/sync-dual-types.mjs ./types ./types-cjs ./storage/types ./storage/types-cjs ./serialization/types ./serialization/types-cjs",
|
|
320
340
|
"test": "vitest run && vitest run --config vite.config.server.mjs && vitest run --config vite.config.hydrate.mjs",
|
|
@@ -4,6 +4,7 @@ var seroval = require('seroval');
|
|
|
4
4
|
var web = require('seroval-plugins/web');
|
|
5
5
|
|
|
6
6
|
const DEFAULT_DISABLED_FEATURES = seroval.Feature.AggregateError | seroval.Feature.BigIntTypedArray;
|
|
7
|
+
const serializeOnlyDisabledFeatures = () => process.env.NODE_ENV === "development" ? 0 : seroval.Feature.ErrorPrototypeStack;
|
|
7
8
|
const HYDRATION_GLOBAL = "_$HY.r";
|
|
8
9
|
const DEFAULT_WEB_PLUGINS = Object.freeze([web.AbortSignalPlugin,
|
|
9
10
|
web.CustomEventPlugin, web.DOMExceptionPlugin, web.EventPlugin,
|
|
@@ -15,7 +16,7 @@ function createSerializer(options) {
|
|
|
15
16
|
return new seroval.Serializer({
|
|
16
17
|
...options,
|
|
17
18
|
plugins: resolveSerializerPlugins(options.plugins),
|
|
18
|
-
disabledFeatures: options.disabledFeatures === undefined ? DEFAULT_DISABLED_FEATURES : options.disabledFeatures
|
|
19
|
+
disabledFeatures: (options.disabledFeatures === undefined ? DEFAULT_DISABLED_FEATURES : options.disabledFeatures) | serializeOnlyDisabledFeatures()
|
|
19
20
|
});
|
|
20
21
|
}
|
|
21
22
|
function createHydrationSerializer({
|
|
@@ -56,11 +57,13 @@ function serializeJSON(value, {
|
|
|
56
57
|
onError,
|
|
57
58
|
...codecOptions
|
|
58
59
|
}) {
|
|
60
|
+
const resolved = resolveCodecOptions(codecOptions);
|
|
59
61
|
return seroval.toCrossJSONStream(value, {
|
|
60
62
|
onParse,
|
|
61
63
|
onDone,
|
|
62
64
|
onError,
|
|
63
|
-
...
|
|
65
|
+
...resolved,
|
|
66
|
+
disabledFeatures: resolved.disabledFeatures | serializeOnlyDisabledFeatures()
|
|
64
67
|
});
|
|
65
68
|
}
|
|
66
69
|
function createJSONDeserializer(options) {
|
|
@@ -106,7 +109,7 @@ function createJSONSerializer({
|
|
|
106
109
|
const stream = seroval.toCrossJSONStream(value, {
|
|
107
110
|
refs,
|
|
108
111
|
plugins: resolved.plugins,
|
|
109
|
-
disabledFeatures: resolved.disabledFeatures,
|
|
112
|
+
disabledFeatures: resolved.disabledFeatures | serializeOnlyDisabledFeatures(),
|
|
110
113
|
onParse(node, initial) {
|
|
111
114
|
onData({
|
|
112
115
|
key,
|
|
@@ -2,6 +2,7 @@ import { Feature, Serializer, getCrossReferenceHeader, toCrossJSONStream, fromCr
|
|
|
2
2
|
import { AbortSignalPlugin, CustomEventPlugin, DOMExceptionPlugin, EventPlugin, FormDataPlugin, HeadersPlugin, ReadableStreamPlugin, RequestPlugin, ResponsePlugin, URLSearchParamsPlugin, URLPlugin } from 'seroval-plugins/web';
|
|
3
3
|
|
|
4
4
|
const DEFAULT_DISABLED_FEATURES = Feature.AggregateError | Feature.BigIntTypedArray;
|
|
5
|
+
const serializeOnlyDisabledFeatures = () => process.env.NODE_ENV === "development" ? 0 : Feature.ErrorPrototypeStack;
|
|
5
6
|
const HYDRATION_GLOBAL = "_$HY.r";
|
|
6
7
|
const DEFAULT_WEB_PLUGINS = Object.freeze([AbortSignalPlugin,
|
|
7
8
|
CustomEventPlugin, DOMExceptionPlugin, EventPlugin,
|
|
@@ -13,7 +14,7 @@ function createSerializer(options) {
|
|
|
13
14
|
return new Serializer({
|
|
14
15
|
...options,
|
|
15
16
|
plugins: resolveSerializerPlugins(options.plugins),
|
|
16
|
-
disabledFeatures: options.disabledFeatures === undefined ? DEFAULT_DISABLED_FEATURES : options.disabledFeatures
|
|
17
|
+
disabledFeatures: (options.disabledFeatures === undefined ? DEFAULT_DISABLED_FEATURES : options.disabledFeatures) | serializeOnlyDisabledFeatures()
|
|
17
18
|
});
|
|
18
19
|
}
|
|
19
20
|
function createHydrationSerializer({
|
|
@@ -54,11 +55,13 @@ function serializeJSON(value, {
|
|
|
54
55
|
onError,
|
|
55
56
|
...codecOptions
|
|
56
57
|
}) {
|
|
58
|
+
const resolved = resolveCodecOptions(codecOptions);
|
|
57
59
|
return toCrossJSONStream(value, {
|
|
58
60
|
onParse,
|
|
59
61
|
onDone,
|
|
60
62
|
onError,
|
|
61
|
-
...
|
|
63
|
+
...resolved,
|
|
64
|
+
disabledFeatures: resolved.disabledFeatures | serializeOnlyDisabledFeatures()
|
|
62
65
|
});
|
|
63
66
|
}
|
|
64
67
|
function createJSONDeserializer(options) {
|
|
@@ -104,7 +107,7 @@ function createJSONSerializer({
|
|
|
104
107
|
const stream = toCrossJSONStream(value, {
|
|
105
108
|
refs,
|
|
106
109
|
plugins: resolved.plugins,
|
|
107
|
-
disabledFeatures: resolved.disabledFeatures,
|
|
110
|
+
disabledFeatures: resolved.disabledFeatures | serializeOnlyDisabledFeatures(),
|
|
108
111
|
onParse(node, initial) {
|
|
109
112
|
onData({
|
|
110
113
|
key,
|
|
@@ -37,7 +37,9 @@ export interface WebSerializerOptions {
|
|
|
37
37
|
scopeId?: string;
|
|
38
38
|
/**
|
|
39
39
|
* Seroval feature bitflags to exclude from output. Defaults to disabling
|
|
40
|
-
* post-ES2017 features (AggregateError, BigInt typed arrays).
|
|
40
|
+
* post-ES2017 features (AggregateError, BigInt typed arrays). Outside
|
|
41
|
+
* development, `Error.prototype.stack` is additionally stripped on top of
|
|
42
|
+
* any override — serialized stacks leak server paths to the client.
|
|
41
43
|
*/
|
|
42
44
|
disabledFeatures?: number;
|
|
43
45
|
/** Extra plugins, composed ahead of `DEFAULT_WEB_PLUGINS`. */
|
|
@@ -101,6 +103,10 @@ export interface JSONCodecOptions {
|
|
|
101
103
|
/**
|
|
102
104
|
* Seroval feature bitflags to exclude. Defaults to disabling `RegExp`
|
|
103
105
|
* (payloads may come from an untrusted peer). Must match on both peers.
|
|
106
|
+
* Outside development, the encoding side additionally strips
|
|
107
|
+
* `Error.prototype.stack` on top of any override — serialized stacks leak
|
|
108
|
+
* server paths to the client. Decoding stays permissive, so payloads from
|
|
109
|
+
* a development peer still round-trip.
|
|
104
110
|
*/
|
|
105
111
|
disabledFeatures?: number;
|
|
106
112
|
/** Maximum parse/deserialize depth. Defaults to 64. Must match on both peers. */
|
|
@@ -37,7 +37,9 @@ export interface WebSerializerOptions {
|
|
|
37
37
|
scopeId?: string;
|
|
38
38
|
/**
|
|
39
39
|
* Seroval feature bitflags to exclude from output. Defaults to disabling
|
|
40
|
-
* post-ES2017 features (AggregateError, BigInt typed arrays).
|
|
40
|
+
* post-ES2017 features (AggregateError, BigInt typed arrays). Outside
|
|
41
|
+
* development, `Error.prototype.stack` is additionally stripped on top of
|
|
42
|
+
* any override — serialized stacks leak server paths to the client.
|
|
41
43
|
*/
|
|
42
44
|
disabledFeatures?: number;
|
|
43
45
|
/** Extra plugins, composed ahead of `DEFAULT_WEB_PLUGINS`. */
|
|
@@ -101,6 +103,10 @@ export interface JSONCodecOptions {
|
|
|
101
103
|
/**
|
|
102
104
|
* Seroval feature bitflags to exclude. Defaults to disabling `RegExp`
|
|
103
105
|
* (payloads may come from an untrusted peer). Must match on both peers.
|
|
106
|
+
* Outside development, the encoding side additionally strips
|
|
107
|
+
* `Error.prototype.stack` on top of any override — serialized stacks leak
|
|
108
|
+
* server paths to the client. Decoding stays permissive, so payloads from
|
|
109
|
+
* a development peer still round-trip.
|
|
104
110
|
*/
|
|
105
111
|
disabledFeatures?: number;
|
|
106
112
|
/** Maximum parse/deserialize depth. Defaults to 64. Must match on both peers. */
|