@solidjs/web 2.0.0-beta.24 → 2.0.0-beta.26
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 +11 -8
- package/dist/dev.js +11 -8
- package/dist/web.cjs +11 -8
- package/dist/web.js +11 -8
- package/frames/dist/client.cjs +135 -208
- package/frames/dist/client.dev.cjs +1408 -0
- package/frames/dist/client.dev.js +1396 -0
- package/frames/dist/client.js +136 -209
- package/frames/dist/server.cjs +106 -78
- package/frames/dist/server.js +106 -78
- package/package.json +27 -6
- package/server-functions/dist/client.cjs +3 -3
- package/server-functions/dist/client.js +3 -3
- package/server-functions/dist/server.cjs +3 -3
- package/server-functions/dist/server.js +3 -3
- package/types/frames/client.d.ts +13 -49
- package/types/frames/frame-client.d.ts +34 -28
- package/types/frames/server.d.ts +1 -20
- package/types-cjs/frames/client.d.cts +13 -49
- package/types-cjs/frames/frame-client.d.cts +34 -28
- package/types-cjs/frames/server.d.cts +1 -20
package/frames/dist/server.cjs
CHANGED
|
@@ -1183,7 +1183,12 @@ function createFrameSink(emit, frame) {
|
|
|
1183
1183
|
version
|
|
1184
1184
|
} = frame;
|
|
1185
1185
|
const styledKeys = new Set();
|
|
1186
|
+
const regionKeys = new Map();
|
|
1187
|
+
const frameOf = key => regionKeys.get(key) || id;
|
|
1186
1188
|
return {
|
|
1189
|
+
tagRegion(key, childId) {
|
|
1190
|
+
if (!regionKeys.has(key)) regionKeys.set(key, childId);
|
|
1191
|
+
},
|
|
1187
1192
|
shell(html, meta = {}) {
|
|
1188
1193
|
if (meta.preloads && meta.preloads.size) {
|
|
1189
1194
|
const styles = [];
|
|
@@ -1231,13 +1236,14 @@ function createFrameSink(emit, frame) {
|
|
|
1231
1236
|
}
|
|
1232
1237
|
},
|
|
1233
1238
|
fragment(key, value, meta = {}) {
|
|
1239
|
+
const fid = frameOf(key);
|
|
1234
1240
|
const links = meta.styles && meta.styles.links || [];
|
|
1235
1241
|
const inline = meta.styles && meta.styles.inline || [];
|
|
1236
1242
|
if (links.length || inline.length) {
|
|
1237
1243
|
if (links.length) styledKeys.add(key);
|
|
1238
1244
|
const chunk = {
|
|
1239
1245
|
type: "assets",
|
|
1240
|
-
id,
|
|
1246
|
+
id: fid,
|
|
1241
1247
|
version,
|
|
1242
1248
|
key
|
|
1243
1249
|
};
|
|
@@ -1253,7 +1259,7 @@ function createFrameSink(emit, frame) {
|
|
|
1253
1259
|
}
|
|
1254
1260
|
emit({
|
|
1255
1261
|
type: "fragment",
|
|
1256
|
-
id,
|
|
1262
|
+
id: fid,
|
|
1257
1263
|
version,
|
|
1258
1264
|
key,
|
|
1259
1265
|
html: value
|
|
@@ -1261,7 +1267,7 @@ function createFrameSink(emit, frame) {
|
|
|
1261
1267
|
if (meta.error) {
|
|
1262
1268
|
emit({
|
|
1263
1269
|
type: "error",
|
|
1264
|
-
id,
|
|
1270
|
+
id: fid,
|
|
1265
1271
|
version,
|
|
1266
1272
|
key,
|
|
1267
1273
|
error: {
|
|
@@ -1272,7 +1278,7 @@ function createFrameSink(emit, frame) {
|
|
|
1272
1278
|
if (!meta.revealGroup) {
|
|
1273
1279
|
emit({
|
|
1274
1280
|
type: "reveal",
|
|
1275
|
-
id,
|
|
1281
|
+
id: fid,
|
|
1276
1282
|
version,
|
|
1277
1283
|
keys: [key],
|
|
1278
1284
|
waitForStyles: !!links.length
|
|
@@ -1280,17 +1286,26 @@ function createFrameSink(emit, frame) {
|
|
|
1280
1286
|
}
|
|
1281
1287
|
},
|
|
1282
1288
|
reveal(keys, meta = {}) {
|
|
1283
|
-
|
|
1284
|
-
for (const key of keys)
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1289
|
+
const byFrame = new Map();
|
|
1290
|
+
for (const key of keys) {
|
|
1291
|
+
const fid = frameOf(key);
|
|
1292
|
+
let group = byFrame.get(fid);
|
|
1293
|
+
if (!group) byFrame.set(fid, group = []);
|
|
1294
|
+
group.push(key);
|
|
1295
|
+
}
|
|
1296
|
+
for (const [fid, groupKeys] of byFrame) {
|
|
1297
|
+
let waitForStyles = false;
|
|
1298
|
+
for (const key of groupKeys) if (styledKeys.has(key)) waitForStyles = true;
|
|
1299
|
+
const chunk = {
|
|
1300
|
+
type: "reveal",
|
|
1301
|
+
id: fid,
|
|
1302
|
+
version,
|
|
1303
|
+
keys: groupKeys,
|
|
1304
|
+
waitForStyles
|
|
1305
|
+
};
|
|
1306
|
+
if (meta.fallback) chunk.fallback = true;
|
|
1307
|
+
emit(chunk);
|
|
1308
|
+
}
|
|
1294
1309
|
},
|
|
1295
1310
|
asset(type, url) {
|
|
1296
1311
|
if (type !== "module") return;
|
|
@@ -1404,6 +1419,22 @@ function slotRange(occurrence) {
|
|
|
1404
1419
|
t: `<!--slot:${occurrence}:start--><!--slot:${occurrence}:end-->`
|
|
1405
1420
|
};
|
|
1406
1421
|
}
|
|
1422
|
+
const OCCURRENCE_UNSAFE = /[^A-Za-z0-9_.-]/g;
|
|
1423
|
+
function encodeOccurrenceKey(key) {
|
|
1424
|
+
return String(key).replace(OCCURRENCE_UNSAFE, c => {
|
|
1425
|
+
const code = c.codePointAt(0);
|
|
1426
|
+
return "%" + (code < 16 ? "0" : "") + code.toString(16);
|
|
1427
|
+
});
|
|
1428
|
+
}
|
|
1429
|
+
function occurrenceId(prop, raw, counts) {
|
|
1430
|
+
const k = raw.$key;
|
|
1431
|
+
if (typeof k === "string" || typeof k === "number") {
|
|
1432
|
+
return `${prop}#${encodeOccurrenceKey(k)}`;
|
|
1433
|
+
}
|
|
1434
|
+
const n = counts[prop] || 0;
|
|
1435
|
+
counts[prop] = n + 1;
|
|
1436
|
+
return `${prop}#${n}`;
|
|
1437
|
+
}
|
|
1407
1438
|
function createDocumentSlotProps(clientProps, frameId) {
|
|
1408
1439
|
const counts = Object.create(null);
|
|
1409
1440
|
const getters = new Map();
|
|
@@ -1440,36 +1471,37 @@ function createDocumentSlotProps(clientProps, frameId) {
|
|
|
1440
1471
|
});
|
|
1441
1472
|
}
|
|
1442
1473
|
const raw = callArgs[0];
|
|
1443
|
-
|
|
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
|
-
}
|
|
1474
|
+
const occurrence = occurrenceId(prop, raw, counts);
|
|
1452
1475
|
const slot = clientProps[prop];
|
|
1453
1476
|
if (typeof slot !== "function") return range(occurrence, undefined);
|
|
1454
1477
|
const resolved = {};
|
|
1455
|
-
const
|
|
1478
|
+
const vals = {};
|
|
1456
1479
|
for (const key of Object.keys(raw)) {
|
|
1457
|
-
|
|
1458
|
-
|
|
1480
|
+
if (key === "$key") continue;
|
|
1481
|
+
let value = raw[key];
|
|
1482
|
+
for (let d = 0; typeof value === "function" && d < 16; d++) value = value();
|
|
1483
|
+
vals[key] = value;
|
|
1484
|
+
}
|
|
1485
|
+
const regions = [];
|
|
1486
|
+
for (const key of Object.keys(vals)) {
|
|
1487
|
+
const value = vals[key];
|
|
1488
|
+
if (isServerContent(value)) {
|
|
1459
1489
|
const childId = `${frameId}.${occurrence}.${key}`;
|
|
1460
1490
|
const region = {
|
|
1461
1491
|
key,
|
|
1462
1492
|
childId,
|
|
1463
1493
|
value,
|
|
1464
|
-
used: false
|
|
1494
|
+
used: false,
|
|
1495
|
+
locked: false
|
|
1465
1496
|
};
|
|
1466
1497
|
regions.push(region);
|
|
1467
1498
|
resolved[key] = () => {
|
|
1499
|
+
if (region.locked) return [];
|
|
1468
1500
|
region.used = true;
|
|
1469
1501
|
return [{
|
|
1470
|
-
t:
|
|
1502
|
+
t: frameElementOpen(childId)
|
|
1471
1503
|
}, value, {
|
|
1472
|
-
t:
|
|
1504
|
+
t: FRAME_ELEMENT_CLOSE
|
|
1473
1505
|
}];
|
|
1474
1506
|
};
|
|
1475
1507
|
} else {
|
|
@@ -1479,12 +1511,10 @@ function createDocumentSlotProps(clientProps, frameId) {
|
|
|
1479
1511
|
const out = scoped(occurrence, () => range(occurrence, slot(resolved)));
|
|
1480
1512
|
const unused = regions.filter(r => !r.used);
|
|
1481
1513
|
if (solidJs.sharedConfig.context) {
|
|
1482
|
-
const rendered = renderedHtmlOf(out);
|
|
1483
1514
|
const args = {};
|
|
1484
1515
|
let any = false;
|
|
1485
|
-
for (const key of Object.keys(
|
|
1486
|
-
const value =
|
|
1487
|
-
if (key === "$key") continue;
|
|
1516
|
+
for (const key of Object.keys(vals)) {
|
|
1517
|
+
const value = vals[key];
|
|
1488
1518
|
const region = regions.find(r => r.key === key);
|
|
1489
1519
|
if (region) {
|
|
1490
1520
|
if (!region.used) {
|
|
@@ -1496,16 +1526,12 @@ function createDocumentSlotProps(clientProps, frameId) {
|
|
|
1496
1526
|
continue;
|
|
1497
1527
|
}
|
|
1498
1528
|
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
1529
|
args[key] = value;
|
|
1505
1530
|
any = true;
|
|
1506
1531
|
}
|
|
1507
1532
|
if (any) solidJs.sharedConfig.context.serialize(`sc:slot:${frameId}:${occurrence}`, args);
|
|
1508
1533
|
for (const region of unused) {
|
|
1534
|
+
region.locked = true;
|
|
1509
1535
|
solidJs.sharedConfig.context.serialize(`sc:region:${region.childId}`, resolveRegionHtml(solidJs.sharedConfig.context, region.value));
|
|
1510
1536
|
}
|
|
1511
1537
|
}
|
|
@@ -1517,28 +1543,26 @@ function createDocumentSlotProps(clientProps, frameId) {
|
|
|
1517
1543
|
}
|
|
1518
1544
|
});
|
|
1519
1545
|
}
|
|
1546
|
+
const FRAME_TAG = "dx-frame";
|
|
1547
|
+
const FRAME_ID_ATTR = "data-fid";
|
|
1548
|
+
function frameElementOpen(id) {
|
|
1549
|
+
const escaped = solidJs.sharedConfig.context ? solidJs.sharedConfig.context.escape(String(id), true) : String(id);
|
|
1550
|
+
return `<${FRAME_TAG} ${FRAME_ID_ATTR}="${escaped}" style="display:contents">`;
|
|
1551
|
+
}
|
|
1552
|
+
const FRAME_ELEMENT_CLOSE = `</${FRAME_TAG}>`;
|
|
1520
1553
|
function frameTransformDirectResult(value, {
|
|
1521
1554
|
id
|
|
1522
1555
|
}) {
|
|
1523
1556
|
if (typeof value !== "function") return value;
|
|
1524
1557
|
const component = value;
|
|
1525
1558
|
const wrapped = props => [{
|
|
1526
|
-
t:
|
|
1559
|
+
t: frameElementOpen(id)
|
|
1527
1560
|
}, serverOwned(() => component(createDocumentSlotProps(props, id))), {
|
|
1528
|
-
t:
|
|
1561
|
+
t: FRAME_ELEMENT_CLOSE
|
|
1529
1562
|
}];
|
|
1530
1563
|
wrapped[SERVER_COMPONENT] = id;
|
|
1531
1564
|
return wrapped;
|
|
1532
1565
|
}
|
|
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
1566
|
function resolveRegionHtml(ctx, node) {
|
|
1543
1567
|
const res = ctx.resolve(node);
|
|
1544
1568
|
if (!res || !res.t) return String(res ?? "");
|
|
@@ -1613,37 +1637,41 @@ function createSlotProps(sink, frame) {
|
|
|
1613
1637
|
return slotRange(prop);
|
|
1614
1638
|
}
|
|
1615
1639
|
const raw = callArgs[0];
|
|
1616
|
-
|
|
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
|
-
}
|
|
1640
|
+
const occurrence = occurrenceId(prop, raw, counts);
|
|
1625
1641
|
const args = {};
|
|
1626
1642
|
for (const key of Object.keys(raw)) {
|
|
1627
|
-
|
|
1628
|
-
const
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1643
|
+
if (key === "$key") continue;
|
|
1644
|
+
const childId = `${frame.id}.${occurrence}.${key}`;
|
|
1645
|
+
const ctx = solidJs.sharedConfig.context;
|
|
1646
|
+
const origRegister = ctx.registerFragment;
|
|
1647
|
+
ctx.registerFragment = (fragKey, fragOptions) => {
|
|
1648
|
+
sink.tagRegion(fragKey, childId);
|
|
1649
|
+
return origRegister.call(ctx, fragKey, fragOptions);
|
|
1650
|
+
};
|
|
1651
|
+
try {
|
|
1652
|
+
let value = raw[key];
|
|
1653
|
+
for (let d = 0; typeof value === "function" && d < 16; d++) value = value();
|
|
1654
|
+
const t = typeof value;
|
|
1655
|
+
if (value == null || t === "string" || t === "number" || t === "boolean") {
|
|
1656
|
+
args[key] = value;
|
|
1657
|
+
} else if (isServerContent(value)) {
|
|
1658
|
+
const resolved = ctx.resolve(value);
|
|
1659
|
+
if (resolved.h.length) {
|
|
1660
|
+
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.");
|
|
1661
|
+
}
|
|
1662
|
+
sink.region(childId, resolved.t[0]);
|
|
1663
|
+
args[key] = {
|
|
1664
|
+
$frame: childId
|
|
1665
|
+
};
|
|
1666
|
+
} else {
|
|
1667
|
+
const ref = `arg:${occurrence}:${key}`;
|
|
1668
|
+
ctx.serialize(ref, value);
|
|
1669
|
+
args[key] = {
|
|
1670
|
+
$ref: ref
|
|
1671
|
+
};
|
|
1635
1672
|
}
|
|
1636
|
-
|
|
1637
|
-
|
|
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
|
-
};
|
|
1673
|
+
} finally {
|
|
1674
|
+
ctx.registerFragment = origRegister;
|
|
1647
1675
|
}
|
|
1648
1676
|
}
|
|
1649
1677
|
sink.slot(occurrence, args);
|
package/frames/dist/server.js
CHANGED
|
@@ -1181,7 +1181,12 @@ function createFrameSink(emit, frame) {
|
|
|
1181
1181
|
version
|
|
1182
1182
|
} = frame;
|
|
1183
1183
|
const styledKeys = new Set();
|
|
1184
|
+
const regionKeys = new Map();
|
|
1185
|
+
const frameOf = key => regionKeys.get(key) || id;
|
|
1184
1186
|
return {
|
|
1187
|
+
tagRegion(key, childId) {
|
|
1188
|
+
if (!regionKeys.has(key)) regionKeys.set(key, childId);
|
|
1189
|
+
},
|
|
1185
1190
|
shell(html, meta = {}) {
|
|
1186
1191
|
if (meta.preloads && meta.preloads.size) {
|
|
1187
1192
|
const styles = [];
|
|
@@ -1229,13 +1234,14 @@ function createFrameSink(emit, frame) {
|
|
|
1229
1234
|
}
|
|
1230
1235
|
},
|
|
1231
1236
|
fragment(key, value, meta = {}) {
|
|
1237
|
+
const fid = frameOf(key);
|
|
1232
1238
|
const links = meta.styles && meta.styles.links || [];
|
|
1233
1239
|
const inline = meta.styles && meta.styles.inline || [];
|
|
1234
1240
|
if (links.length || inline.length) {
|
|
1235
1241
|
if (links.length) styledKeys.add(key);
|
|
1236
1242
|
const chunk = {
|
|
1237
1243
|
type: "assets",
|
|
1238
|
-
id,
|
|
1244
|
+
id: fid,
|
|
1239
1245
|
version,
|
|
1240
1246
|
key
|
|
1241
1247
|
};
|
|
@@ -1251,7 +1257,7 @@ function createFrameSink(emit, frame) {
|
|
|
1251
1257
|
}
|
|
1252
1258
|
emit({
|
|
1253
1259
|
type: "fragment",
|
|
1254
|
-
id,
|
|
1260
|
+
id: fid,
|
|
1255
1261
|
version,
|
|
1256
1262
|
key,
|
|
1257
1263
|
html: value
|
|
@@ -1259,7 +1265,7 @@ function createFrameSink(emit, frame) {
|
|
|
1259
1265
|
if (meta.error) {
|
|
1260
1266
|
emit({
|
|
1261
1267
|
type: "error",
|
|
1262
|
-
id,
|
|
1268
|
+
id: fid,
|
|
1263
1269
|
version,
|
|
1264
1270
|
key,
|
|
1265
1271
|
error: {
|
|
@@ -1270,7 +1276,7 @@ function createFrameSink(emit, frame) {
|
|
|
1270
1276
|
if (!meta.revealGroup) {
|
|
1271
1277
|
emit({
|
|
1272
1278
|
type: "reveal",
|
|
1273
|
-
id,
|
|
1279
|
+
id: fid,
|
|
1274
1280
|
version,
|
|
1275
1281
|
keys: [key],
|
|
1276
1282
|
waitForStyles: !!links.length
|
|
@@ -1278,17 +1284,26 @@ function createFrameSink(emit, frame) {
|
|
|
1278
1284
|
}
|
|
1279
1285
|
},
|
|
1280
1286
|
reveal(keys, meta = {}) {
|
|
1281
|
-
|
|
1282
|
-
for (const key of keys)
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1287
|
+
const byFrame = new Map();
|
|
1288
|
+
for (const key of keys) {
|
|
1289
|
+
const fid = frameOf(key);
|
|
1290
|
+
let group = byFrame.get(fid);
|
|
1291
|
+
if (!group) byFrame.set(fid, group = []);
|
|
1292
|
+
group.push(key);
|
|
1293
|
+
}
|
|
1294
|
+
for (const [fid, groupKeys] of byFrame) {
|
|
1295
|
+
let waitForStyles = false;
|
|
1296
|
+
for (const key of groupKeys) if (styledKeys.has(key)) waitForStyles = true;
|
|
1297
|
+
const chunk = {
|
|
1298
|
+
type: "reveal",
|
|
1299
|
+
id: fid,
|
|
1300
|
+
version,
|
|
1301
|
+
keys: groupKeys,
|
|
1302
|
+
waitForStyles
|
|
1303
|
+
};
|
|
1304
|
+
if (meta.fallback) chunk.fallback = true;
|
|
1305
|
+
emit(chunk);
|
|
1306
|
+
}
|
|
1292
1307
|
},
|
|
1293
1308
|
asset(type, url) {
|
|
1294
1309
|
if (type !== "module") return;
|
|
@@ -1402,6 +1417,22 @@ function slotRange(occurrence) {
|
|
|
1402
1417
|
t: `<!--slot:${occurrence}:start--><!--slot:${occurrence}:end-->`
|
|
1403
1418
|
};
|
|
1404
1419
|
}
|
|
1420
|
+
const OCCURRENCE_UNSAFE = /[^A-Za-z0-9_.-]/g;
|
|
1421
|
+
function encodeOccurrenceKey(key) {
|
|
1422
|
+
return String(key).replace(OCCURRENCE_UNSAFE, c => {
|
|
1423
|
+
const code = c.codePointAt(0);
|
|
1424
|
+
return "%" + (code < 16 ? "0" : "") + code.toString(16);
|
|
1425
|
+
});
|
|
1426
|
+
}
|
|
1427
|
+
function occurrenceId(prop, raw, counts) {
|
|
1428
|
+
const k = raw.$key;
|
|
1429
|
+
if (typeof k === "string" || typeof k === "number") {
|
|
1430
|
+
return `${prop}#${encodeOccurrenceKey(k)}`;
|
|
1431
|
+
}
|
|
1432
|
+
const n = counts[prop] || 0;
|
|
1433
|
+
counts[prop] = n + 1;
|
|
1434
|
+
return `${prop}#${n}`;
|
|
1435
|
+
}
|
|
1405
1436
|
function createDocumentSlotProps(clientProps, frameId) {
|
|
1406
1437
|
const counts = Object.create(null);
|
|
1407
1438
|
const getters = new Map();
|
|
@@ -1438,36 +1469,37 @@ function createDocumentSlotProps(clientProps, frameId) {
|
|
|
1438
1469
|
});
|
|
1439
1470
|
}
|
|
1440
1471
|
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
|
-
}
|
|
1472
|
+
const occurrence = occurrenceId(prop, raw, counts);
|
|
1450
1473
|
const slot = clientProps[prop];
|
|
1451
1474
|
if (typeof slot !== "function") return range(occurrence, undefined);
|
|
1452
1475
|
const resolved = {};
|
|
1453
|
-
const
|
|
1476
|
+
const vals = {};
|
|
1454
1477
|
for (const key of Object.keys(raw)) {
|
|
1455
|
-
|
|
1456
|
-
|
|
1478
|
+
if (key === "$key") continue;
|
|
1479
|
+
let value = raw[key];
|
|
1480
|
+
for (let d = 0; typeof value === "function" && d < 16; d++) value = value();
|
|
1481
|
+
vals[key] = value;
|
|
1482
|
+
}
|
|
1483
|
+
const regions = [];
|
|
1484
|
+
for (const key of Object.keys(vals)) {
|
|
1485
|
+
const value = vals[key];
|
|
1486
|
+
if (isServerContent(value)) {
|
|
1457
1487
|
const childId = `${frameId}.${occurrence}.${key}`;
|
|
1458
1488
|
const region = {
|
|
1459
1489
|
key,
|
|
1460
1490
|
childId,
|
|
1461
1491
|
value,
|
|
1462
|
-
used: false
|
|
1492
|
+
used: false,
|
|
1493
|
+
locked: false
|
|
1463
1494
|
};
|
|
1464
1495
|
regions.push(region);
|
|
1465
1496
|
resolved[key] = () => {
|
|
1497
|
+
if (region.locked) return [];
|
|
1466
1498
|
region.used = true;
|
|
1467
1499
|
return [{
|
|
1468
|
-
t:
|
|
1500
|
+
t: frameElementOpen(childId)
|
|
1469
1501
|
}, value, {
|
|
1470
|
-
t:
|
|
1502
|
+
t: FRAME_ELEMENT_CLOSE
|
|
1471
1503
|
}];
|
|
1472
1504
|
};
|
|
1473
1505
|
} else {
|
|
@@ -1477,12 +1509,10 @@ function createDocumentSlotProps(clientProps, frameId) {
|
|
|
1477
1509
|
const out = scoped(occurrence, () => range(occurrence, slot(resolved)));
|
|
1478
1510
|
const unused = regions.filter(r => !r.used);
|
|
1479
1511
|
if (sharedConfig.context) {
|
|
1480
|
-
const rendered = renderedHtmlOf(out);
|
|
1481
1512
|
const args = {};
|
|
1482
1513
|
let any = false;
|
|
1483
|
-
for (const key of Object.keys(
|
|
1484
|
-
const value =
|
|
1485
|
-
if (key === "$key") continue;
|
|
1514
|
+
for (const key of Object.keys(vals)) {
|
|
1515
|
+
const value = vals[key];
|
|
1486
1516
|
const region = regions.find(r => r.key === key);
|
|
1487
1517
|
if (region) {
|
|
1488
1518
|
if (!region.used) {
|
|
@@ -1494,16 +1524,12 @@ function createDocumentSlotProps(clientProps, frameId) {
|
|
|
1494
1524
|
continue;
|
|
1495
1525
|
}
|
|
1496
1526
|
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
1527
|
args[key] = value;
|
|
1503
1528
|
any = true;
|
|
1504
1529
|
}
|
|
1505
1530
|
if (any) sharedConfig.context.serialize(`sc:slot:${frameId}:${occurrence}`, args);
|
|
1506
1531
|
for (const region of unused) {
|
|
1532
|
+
region.locked = true;
|
|
1507
1533
|
sharedConfig.context.serialize(`sc:region:${region.childId}`, resolveRegionHtml(sharedConfig.context, region.value));
|
|
1508
1534
|
}
|
|
1509
1535
|
}
|
|
@@ -1515,28 +1541,26 @@ function createDocumentSlotProps(clientProps, frameId) {
|
|
|
1515
1541
|
}
|
|
1516
1542
|
});
|
|
1517
1543
|
}
|
|
1544
|
+
const FRAME_TAG = "dx-frame";
|
|
1545
|
+
const FRAME_ID_ATTR = "data-fid";
|
|
1546
|
+
function frameElementOpen(id) {
|
|
1547
|
+
const escaped = sharedConfig.context ? sharedConfig.context.escape(String(id), true) : String(id);
|
|
1548
|
+
return `<${FRAME_TAG} ${FRAME_ID_ATTR}="${escaped}" style="display:contents">`;
|
|
1549
|
+
}
|
|
1550
|
+
const FRAME_ELEMENT_CLOSE = `</${FRAME_TAG}>`;
|
|
1518
1551
|
function frameTransformDirectResult(value, {
|
|
1519
1552
|
id
|
|
1520
1553
|
}) {
|
|
1521
1554
|
if (typeof value !== "function") return value;
|
|
1522
1555
|
const component = value;
|
|
1523
1556
|
const wrapped = props => [{
|
|
1524
|
-
t:
|
|
1557
|
+
t: frameElementOpen(id)
|
|
1525
1558
|
}, serverOwned(() => component(createDocumentSlotProps(props, id))), {
|
|
1526
|
-
t:
|
|
1559
|
+
t: FRAME_ELEMENT_CLOSE
|
|
1527
1560
|
}];
|
|
1528
1561
|
wrapped[SERVER_COMPONENT] = id;
|
|
1529
1562
|
return wrapped;
|
|
1530
1563
|
}
|
|
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
1564
|
function resolveRegionHtml(ctx, node) {
|
|
1541
1565
|
const res = ctx.resolve(node);
|
|
1542
1566
|
if (!res || !res.t) return String(res ?? "");
|
|
@@ -1611,37 +1635,41 @@ function createSlotProps(sink, frame) {
|
|
|
1611
1635
|
return slotRange(prop);
|
|
1612
1636
|
}
|
|
1613
1637
|
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
|
-
}
|
|
1638
|
+
const occurrence = occurrenceId(prop, raw, counts);
|
|
1623
1639
|
const args = {};
|
|
1624
1640
|
for (const key of Object.keys(raw)) {
|
|
1625
|
-
|
|
1626
|
-
const
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1641
|
+
if (key === "$key") continue;
|
|
1642
|
+
const childId = `${frame.id}.${occurrence}.${key}`;
|
|
1643
|
+
const ctx = sharedConfig.context;
|
|
1644
|
+
const origRegister = ctx.registerFragment;
|
|
1645
|
+
ctx.registerFragment = (fragKey, fragOptions) => {
|
|
1646
|
+
sink.tagRegion(fragKey, childId);
|
|
1647
|
+
return origRegister.call(ctx, fragKey, fragOptions);
|
|
1648
|
+
};
|
|
1649
|
+
try {
|
|
1650
|
+
let value = raw[key];
|
|
1651
|
+
for (let d = 0; typeof value === "function" && d < 16; d++) value = value();
|
|
1652
|
+
const t = typeof value;
|
|
1653
|
+
if (value == null || t === "string" || t === "number" || t === "boolean") {
|
|
1654
|
+
args[key] = value;
|
|
1655
|
+
} else if (isServerContent(value)) {
|
|
1656
|
+
const resolved = ctx.resolve(value);
|
|
1657
|
+
if (resolved.h.length) {
|
|
1658
|
+
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.");
|
|
1659
|
+
}
|
|
1660
|
+
sink.region(childId, resolved.t[0]);
|
|
1661
|
+
args[key] = {
|
|
1662
|
+
$frame: childId
|
|
1663
|
+
};
|
|
1664
|
+
} else {
|
|
1665
|
+
const ref = `arg:${occurrence}:${key}`;
|
|
1666
|
+
ctx.serialize(ref, value);
|
|
1667
|
+
args[key] = {
|
|
1668
|
+
$ref: ref
|
|
1669
|
+
};
|
|
1633
1670
|
}
|
|
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
|
-
};
|
|
1671
|
+
} finally {
|
|
1672
|
+
ctx.registerFragment = origRegister;
|
|
1645
1673
|
}
|
|
1646
1674
|
}
|
|
1647
1675
|
sink.slot(occurrence, args);
|