@barefootjs/jsx 0.33.6 → 0.35.0
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/adapters/parsed-expr-emitter.d.ts +17 -0
- package/dist/adapters/parsed-expr-emitter.d.ts.map +1 -1
- package/dist/analyzer.d.ts.map +1 -1
- package/dist/expression-parser.d.ts +17 -4
- package/dist/expression-parser.d.ts.map +1 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +445 -282
- package/dist/ir-to-client-js/collect-elements.d.ts.map +1 -1
- package/dist/ir-to-client-js/control-flow/plan/build-branch-loop.d.ts.map +1 -1
- package/dist/ir-to-client-js/control-flow/plan/build-component-loop.d.ts.map +1 -1
- package/dist/ir-to-client-js/control-flow/plan/build-composite-loop.d.ts.map +1 -1
- package/dist/ir-to-client-js/control-flow/plan/build-lazy-row.d.ts +11 -0
- package/dist/ir-to-client-js/control-flow/plan/build-lazy-row.d.ts.map +1 -1
- package/dist/ir-to-client-js/control-flow/plan/build-loop.d.ts.map +1 -1
- package/dist/ir-to-client-js/control-flow/plan/build-plain-row.d.ts +52 -0
- package/dist/ir-to-client-js/control-flow/plan/build-plain-row.d.ts.map +1 -0
- package/dist/ir-to-client-js/control-flow/plan/build-reactive-effects.d.ts +2 -0
- package/dist/ir-to-client-js/control-flow/plan/build-reactive-effects.d.ts.map +1 -1
- package/dist/ir-to-client-js/control-flow/plan/lazy-conditional.d.ts +6 -7
- package/dist/ir-to-client-js/control-flow/plan/lazy-conditional.d.ts.map +1 -1
- package/dist/ir-to-client-js/control-flow/plan/lazy-preamble.d.ts +5 -7
- package/dist/ir-to-client-js/control-flow/plan/lazy-preamble.d.ts.map +1 -1
- package/dist/ir-to-client-js/control-flow/plan/lazy-row-eligibility.d.ts.map +1 -1
- package/dist/ir-to-client-js/control-flow/plan/loop.d.ts +10 -6
- package/dist/ir-to-client-js/control-flow/plan/loop.d.ts.map +1 -1
- package/dist/ir-to-client-js/control-flow/shared.d.ts +11 -9
- package/dist/ir-to-client-js/control-flow/shared.d.ts.map +1 -1
- package/dist/ir-to-client-js/control-flow/stringify/composite-loop.d.ts.map +1 -1
- package/dist/ir-to-client-js/control-flow/stringify/lazy-row.d.ts.map +1 -1
- package/dist/ir-to-client-js/csr-substitute.d.ts +16 -0
- package/dist/ir-to-client-js/csr-substitute.d.ts.map +1 -1
- package/dist/ir-to-client-js/emit-reactive.d.ts.map +1 -1
- package/dist/ir-to-client-js/emit-registration.d.ts.map +1 -1
- package/dist/ir-to-client-js/html-template.d.ts +2 -2
- package/dist/ir-to-client-js/html-template.d.ts.map +1 -1
- package/dist/ir-to-client-js/imports.d.ts +2 -2
- package/dist/ir-to-client-js/imports.d.ts.map +1 -1
- package/dist/ir-to-client-js/index.d.ts.map +1 -1
- package/dist/ir-to-client-js/markup-slots.d.ts +21 -0
- package/dist/ir-to-client-js/markup-slots.d.ts.map +1 -0
- package/dist/ir-to-client-js/safe-html.d.ts +158 -0
- package/dist/ir-to-client-js/safe-html.d.ts.map +1 -0
- package/dist/ir-to-client-js/utils.d.ts +34 -1
- package/dist/ir-to-client-js/utils.d.ts.map +1 -1
- package/dist/jsx-to-ir.d.ts.map +1 -1
- package/dist/lowering-registry.d.ts +12 -0
- package/dist/lowering-registry.d.ts.map +1 -1
- package/dist/prop-rewrite.d.ts +8 -3
- package/dist/prop-rewrite.d.ts.map +1 -1
- package/dist/props-binding.d.ts +22 -1
- package/dist/props-binding.d.ts.map +1 -1
- package/dist/ssr-defaults.d.ts.map +1 -1
- package/dist/types.d.ts +5 -10
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/__tests__/__snapshots__/doc-examples.test.ts.snap +10 -12
- package/src/__tests__/build-plain-row-consolidation.test.ts +120 -0
- package/src/__tests__/client-template-escape-soundness.test.ts +538 -0
- package/src/__tests__/csr-template-loop-shadowing.test.ts +4 -2
- package/src/__tests__/flatmap-segments.test.ts +1 -1
- package/src/__tests__/lazy-conditional.test.ts +52 -12
- package/src/__tests__/lazy-preamble.test.ts +11 -11
- package/src/__tests__/lazy-row-eligibility.test.ts +8 -3
- package/src/__tests__/loop-child-reactive-attr-const-shadow.test.ts +25 -3
- package/src/__tests__/loop-item-conditional-codegen.test.ts +4 -2
- package/src/__tests__/lowering-value-position.test.ts +232 -0
- package/src/__tests__/map-arbitrary-body.test.ts +1 -1
- package/src/__tests__/nested-loop-index-param.test.ts +14 -3
- package/src/__tests__/nested-loop-reactive-attrs.test.ts +4 -2
- package/src/__tests__/reactive-attrs-in-map.test.ts +13 -10
- package/src/__tests__/rewrite-destructured-props.test.ts +37 -0
- package/src/__tests__/safe-html-splice-door.test.ts +61 -0
- package/src/__tests__/ssr-defaults.test.ts +59 -0
- package/src/adapters/parsed-expr-emitter.ts +43 -0
- package/src/analyzer.ts +4 -0
- package/src/expression-parser.ts +63 -29
- package/src/index.ts +10 -3
- package/src/ir-to-client-js/collect-elements.ts +18 -2
- package/src/ir-to-client-js/control-flow/plan/build-branch-loop.ts +20 -28
- package/src/ir-to-client-js/control-flow/plan/build-component-loop.ts +9 -7
- package/src/ir-to-client-js/control-flow/plan/build-composite-loop.ts +10 -6
- package/src/ir-to-client-js/control-flow/plan/build-inner-loop.ts +8 -8
- package/src/ir-to-client-js/control-flow/plan/build-lazy-row.ts +18 -2
- package/src/ir-to-client-js/control-flow/plan/build-loop-child-arm.ts +3 -3
- package/src/ir-to-client-js/control-flow/plan/build-loop.ts +35 -35
- package/src/ir-to-client-js/control-flow/plan/build-plain-row.ts +110 -0
- package/src/ir-to-client-js/control-flow/plan/build-reactive-effects.ts +5 -2
- package/src/ir-to-client-js/control-flow/plan/lazy-conditional.ts +11 -10
- package/src/ir-to-client-js/control-flow/plan/lazy-preamble.ts +11 -13
- package/src/ir-to-client-js/control-flow/plan/lazy-row-eligibility.ts +13 -3
- package/src/ir-to-client-js/control-flow/plan/loop.ts +10 -6
- package/src/ir-to-client-js/control-flow/shared.ts +40 -17
- package/src/ir-to-client-js/control-flow/stringify/composite-loop.ts +2 -1
- package/src/ir-to-client-js/control-flow/stringify/lazy-row.ts +10 -0
- package/src/ir-to-client-js/csr-substitute.ts +29 -0
- package/src/ir-to-client-js/emit-reactive.ts +4 -1
- package/src/ir-to-client-js/emit-registration.ts +2 -4
- package/src/ir-to-client-js/html-template.ts +58 -244
- package/src/ir-to-client-js/imports.ts +3 -0
- package/src/ir-to-client-js/index.ts +4 -4
- package/src/ir-to-client-js/markup-slots.ts +25 -0
- package/src/ir-to-client-js/safe-html.ts +243 -0
- package/src/ir-to-client-js/utils.ts +58 -10
- package/src/jsx-to-ir.ts +115 -20
- package/src/lowering-registry.ts +21 -0
- package/src/prop-rewrite.ts +8 -4
- package/src/props-binding.ts +37 -1
- package/src/ssr-defaults.ts +45 -0
- package/src/types.ts +5 -10
- package/src/__tests__/text-slot-escaping.test.ts +0 -65
package/dist/index.js
CHANGED
|
@@ -184,6 +184,56 @@ import ts10 from "typescript";
|
|
|
184
184
|
|
|
185
185
|
// src/expression-parser.ts
|
|
186
186
|
import ts2 from "typescript";
|
|
187
|
+
|
|
188
|
+
// src/lowering-registry.ts
|
|
189
|
+
var plugins = [];
|
|
190
|
+
function registerLoweringPlugin(plugin) {
|
|
191
|
+
const existing = plugins.findIndex((p) => p.name === plugin.name);
|
|
192
|
+
if (existing >= 0)
|
|
193
|
+
plugins[existing] = plugin;
|
|
194
|
+
else
|
|
195
|
+
plugins.push(plugin);
|
|
196
|
+
}
|
|
197
|
+
function getLoweringPlugins() {
|
|
198
|
+
return [...plugins];
|
|
199
|
+
}
|
|
200
|
+
function prepareLoweringMatchers(metadata) {
|
|
201
|
+
const matchers = [];
|
|
202
|
+
for (const plugin of plugins) {
|
|
203
|
+
const matcher = plugin.prepare(metadata);
|
|
204
|
+
if (matcher)
|
|
205
|
+
matchers.push(matcher);
|
|
206
|
+
}
|
|
207
|
+
return matchers;
|
|
208
|
+
}
|
|
209
|
+
function matchLoweringCall(callee, args, metadata) {
|
|
210
|
+
for (const matcher of prepareLoweringMatchers(metadata)) {
|
|
211
|
+
const node = matcher(callee, args);
|
|
212
|
+
if (node)
|
|
213
|
+
return node;
|
|
214
|
+
}
|
|
215
|
+
return null;
|
|
216
|
+
}
|
|
217
|
+
function loweringNodeChildren(node) {
|
|
218
|
+
if (node.kind === "helper-call")
|
|
219
|
+
return [...node.args];
|
|
220
|
+
const children = [node.base];
|
|
221
|
+
for (const t of node.triples) {
|
|
222
|
+
if (t.guard)
|
|
223
|
+
children.push(t.guard);
|
|
224
|
+
children.push(t.value);
|
|
225
|
+
}
|
|
226
|
+
return children;
|
|
227
|
+
}
|
|
228
|
+
function isValidHelperId(helper) {
|
|
229
|
+
return /^[A-Za-z_][A-Za-z0-9_]*$/.test(helper);
|
|
230
|
+
}
|
|
231
|
+
function __resetLoweringPluginsForTest(next = []) {
|
|
232
|
+
plugins.length = 0;
|
|
233
|
+
plugins.push(...next);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// src/expression-parser.ts
|
|
187
237
|
var PARSED_EXPR_KINDS = [
|
|
188
238
|
"identifier",
|
|
189
239
|
"literal",
|
|
@@ -526,7 +576,7 @@ function convertNode(node, raw) {
|
|
|
526
576
|
}
|
|
527
577
|
if (n === undefined || Number.isNaN(n)) {
|
|
528
578
|
const parsedDepth = convertNode(depthNode, raw);
|
|
529
|
-
if (checkSupport(parsedDepth, "rendered").supported) {
|
|
579
|
+
if (checkSupport(parsedDepth, "rendered", []).supported) {
|
|
530
580
|
depthExpr = parsedDepth;
|
|
531
581
|
flatDepth = 1;
|
|
532
582
|
} else {
|
|
@@ -1304,13 +1354,13 @@ function getUnaryOperatorString(op) {
|
|
|
1304
1354
|
return "unknown";
|
|
1305
1355
|
}
|
|
1306
1356
|
}
|
|
1307
|
-
function isSupported(expr) {
|
|
1308
|
-
return checkSupport(expr, "rendered");
|
|
1357
|
+
function isSupported(expr, opts) {
|
|
1358
|
+
return checkSupport(expr, "rendered", opts?.loweringMatchers ?? []);
|
|
1309
1359
|
}
|
|
1310
|
-
function isSupportedValue(expr) {
|
|
1311
|
-
return checkSupport(expr, "value");
|
|
1360
|
+
function isSupportedValue(expr, opts) {
|
|
1361
|
+
return checkSupport(expr, "value", opts?.loweringMatchers ?? []);
|
|
1312
1362
|
}
|
|
1313
|
-
function checkSupport(expr, pos) {
|
|
1363
|
+
function checkSupport(expr, pos, matchers) {
|
|
1314
1364
|
switch (expr.kind) {
|
|
1315
1365
|
case "unsupported":
|
|
1316
1366
|
return { supported: false, reason: expr.reason };
|
|
@@ -1319,7 +1369,7 @@ function checkSupport(expr, pos) {
|
|
|
1319
1369
|
return { supported: false, reason: "Unsupported syntax: ObjectLiteralExpression" };
|
|
1320
1370
|
}
|
|
1321
1371
|
for (const prop of expr.properties) {
|
|
1322
|
-
const propSupport = checkSupport(prop.kind === "spread" ? prop.expr : prop.value, pos);
|
|
1372
|
+
const propSupport = checkSupport(prop.kind === "spread" ? prop.expr : prop.value, pos, matchers);
|
|
1323
1373
|
if (!propSupport.supported)
|
|
1324
1374
|
return propSupport;
|
|
1325
1375
|
}
|
|
@@ -1334,7 +1384,7 @@ function checkSupport(expr, pos) {
|
|
|
1334
1384
|
return { supported: false, reason: "Standalone arrow functions / regex literals are not supported" };
|
|
1335
1385
|
case "array-literal": {
|
|
1336
1386
|
for (const el of expr.elements) {
|
|
1337
|
-
const elSupport = checkSupport(el, pos);
|
|
1387
|
+
const elSupport = checkSupport(el, pos, matchers);
|
|
1338
1388
|
if (!elSupport.supported)
|
|
1339
1389
|
return elSupport;
|
|
1340
1390
|
}
|
|
@@ -1347,28 +1397,39 @@ function checkSupport(expr, pos) {
|
|
|
1347
1397
|
reason: `String.prototype.${expr.method} supports only a string pattern + string replacement (the regex form is deferred); use a string pattern or wrap the expression in /* @client */`
|
|
1348
1398
|
};
|
|
1349
1399
|
}
|
|
1350
|
-
const objSupport = checkSupport(expr.object, pos);
|
|
1400
|
+
const objSupport = checkSupport(expr.object, pos, matchers);
|
|
1351
1401
|
if (!objSupport.supported)
|
|
1352
1402
|
return objSupport;
|
|
1353
1403
|
for (const arg of expr.args) {
|
|
1354
|
-
const argSupport = checkSupport(arg, pos);
|
|
1404
|
+
const argSupport = checkSupport(arg, pos, matchers);
|
|
1355
1405
|
if (!argSupport.supported)
|
|
1356
1406
|
return argSupport;
|
|
1357
1407
|
}
|
|
1358
1408
|
if (expr.method === "flat" && expr.depthExpr) {
|
|
1359
|
-
const depthSupport = checkSupport(expr.depthExpr, pos);
|
|
1409
|
+
const depthSupport = checkSupport(expr.depthExpr, pos, matchers);
|
|
1360
1410
|
if (!depthSupport.supported)
|
|
1361
1411
|
return depthSupport;
|
|
1362
1412
|
}
|
|
1363
1413
|
return { supported: true, level: "L2" };
|
|
1364
1414
|
}
|
|
1365
1415
|
case "call": {
|
|
1416
|
+
for (const matcher of matchers) {
|
|
1417
|
+
const node = matcher(expr.callee, expr.args);
|
|
1418
|
+
if (!node)
|
|
1419
|
+
continue;
|
|
1420
|
+
for (const child of loweringNodeChildren(node)) {
|
|
1421
|
+
const childSupport = checkSupport(child, pos, matchers);
|
|
1422
|
+
if (!childSupport.supported)
|
|
1423
|
+
return childSupport;
|
|
1424
|
+
}
|
|
1425
|
+
return { supported: true, level: "L2" };
|
|
1426
|
+
}
|
|
1366
1427
|
const cb = asCallbackMethodCall(expr);
|
|
1367
1428
|
if (cb) {
|
|
1368
|
-
const objSupport = checkSupport(cb.object, pos);
|
|
1429
|
+
const objSupport = checkSupport(cb.object, pos, matchers);
|
|
1369
1430
|
if (!objSupport.supported)
|
|
1370
1431
|
return objSupport;
|
|
1371
|
-
const bodySupport = checkSupport(cb.arrow.body, pos);
|
|
1432
|
+
const bodySupport = checkSupport(cb.arrow.body, pos, matchers);
|
|
1372
1433
|
if (!bodySupport.supported) {
|
|
1373
1434
|
return {
|
|
1374
1435
|
supported: false,
|
|
@@ -1377,13 +1438,13 @@ function checkSupport(expr, pos) {
|
|
|
1377
1438
|
};
|
|
1378
1439
|
}
|
|
1379
1440
|
for (const rest of cb.args) {
|
|
1380
|
-
const restSupport = checkSupport(rest, pos);
|
|
1441
|
+
const restSupport = checkSupport(rest, pos, matchers);
|
|
1381
1442
|
if (!restSupport.supported)
|
|
1382
1443
|
return restSupport;
|
|
1383
1444
|
}
|
|
1384
1445
|
return { supported: true, level: "L5" };
|
|
1385
1446
|
}
|
|
1386
|
-
const calleeSupport = checkSupport(expr.callee, pos);
|
|
1447
|
+
const calleeSupport = checkSupport(expr.callee, pos, matchers);
|
|
1387
1448
|
if (!calleeSupport.supported) {
|
|
1388
1449
|
return calleeSupport;
|
|
1389
1450
|
}
|
|
@@ -1402,7 +1463,7 @@ function checkSupport(expr, pos) {
|
|
|
1402
1463
|
return { supported: true, level: "L1" };
|
|
1403
1464
|
}
|
|
1404
1465
|
for (const arg of expr.args) {
|
|
1405
|
-
const argSupport = checkSupport(arg, pos);
|
|
1466
|
+
const argSupport = checkSupport(arg, pos, matchers);
|
|
1406
1467
|
if (!argSupport.supported) {
|
|
1407
1468
|
return argSupport;
|
|
1408
1469
|
}
|
|
@@ -1410,7 +1471,7 @@ function checkSupport(expr, pos) {
|
|
|
1410
1471
|
return { supported: true, level: "L2" };
|
|
1411
1472
|
}
|
|
1412
1473
|
case "member": {
|
|
1413
|
-
const objSupport = checkSupport(expr.object, pos);
|
|
1474
|
+
const objSupport = checkSupport(expr.object, pos, matchers);
|
|
1414
1475
|
if (!objSupport.supported) {
|
|
1415
1476
|
return objSupport;
|
|
1416
1477
|
}
|
|
@@ -1420,19 +1481,19 @@ function checkSupport(expr, pos) {
|
|
|
1420
1481
|
return { supported: true, level: "L2" };
|
|
1421
1482
|
}
|
|
1422
1483
|
case "index-access": {
|
|
1423
|
-
const objSupport = checkSupport(expr.object, pos);
|
|
1484
|
+
const objSupport = checkSupport(expr.object, pos, matchers);
|
|
1424
1485
|
if (!objSupport.supported)
|
|
1425
1486
|
return objSupport;
|
|
1426
|
-
const indexSupport = checkSupport(expr.index, pos);
|
|
1487
|
+
const indexSupport = checkSupport(expr.index, pos, matchers);
|
|
1427
1488
|
if (!indexSupport.supported)
|
|
1428
1489
|
return indexSupport;
|
|
1429
1490
|
return { supported: true, level: "L2" };
|
|
1430
1491
|
}
|
|
1431
1492
|
case "binary": {
|
|
1432
|
-
const leftSupport = checkSupport(expr.left, pos);
|
|
1493
|
+
const leftSupport = checkSupport(expr.left, pos, matchers);
|
|
1433
1494
|
if (!leftSupport.supported)
|
|
1434
1495
|
return leftSupport;
|
|
1435
|
-
const rightSupport = checkSupport(expr.right, pos);
|
|
1496
|
+
const rightSupport = checkSupport(expr.right, pos, matchers);
|
|
1436
1497
|
if (!rightSupport.supported)
|
|
1437
1498
|
return rightSupport;
|
|
1438
1499
|
if (["===", "==", "!==", "!=", ">", "<", ">=", "<="].includes(expr.op)) {
|
|
@@ -1444,7 +1505,7 @@ function checkSupport(expr, pos) {
|
|
|
1444
1505
|
return { supported: false, reason: `Unknown operator: ${expr.op}` };
|
|
1445
1506
|
}
|
|
1446
1507
|
case "unary": {
|
|
1447
|
-
const argSupport = checkSupport(expr.argument, pos);
|
|
1508
|
+
const argSupport = checkSupport(expr.argument, pos, matchers);
|
|
1448
1509
|
if (!argSupport.supported)
|
|
1449
1510
|
return argSupport;
|
|
1450
1511
|
if (expr.op === "!") {
|
|
@@ -1456,25 +1517,25 @@ function checkSupport(expr, pos) {
|
|
|
1456
1517
|
return { supported: false, reason: `Unsupported unary operator: ${expr.op}` };
|
|
1457
1518
|
}
|
|
1458
1519
|
case "logical": {
|
|
1459
|
-
const leftSupport = checkSupport(expr.left, pos);
|
|
1520
|
+
const leftSupport = checkSupport(expr.left, pos, matchers);
|
|
1460
1521
|
if (!leftSupport.supported)
|
|
1461
1522
|
return leftSupport;
|
|
1462
1523
|
if (expr.op === "??" && expr.right.kind === "object-literal" && expr.right.properties.length === 0) {
|
|
1463
1524
|
return { supported: true, level: "L4" };
|
|
1464
1525
|
}
|
|
1465
|
-
const rightSupport = checkSupport(expr.right, pos);
|
|
1526
|
+
const rightSupport = checkSupport(expr.right, pos, matchers);
|
|
1466
1527
|
if (!rightSupport.supported)
|
|
1467
1528
|
return rightSupport;
|
|
1468
1529
|
return { supported: true, level: "L4" };
|
|
1469
1530
|
}
|
|
1470
1531
|
case "conditional": {
|
|
1471
|
-
const testSupport = checkSupport(expr.test, pos);
|
|
1532
|
+
const testSupport = checkSupport(expr.test, pos, matchers);
|
|
1472
1533
|
if (!testSupport.supported)
|
|
1473
1534
|
return testSupport;
|
|
1474
|
-
const consSupport = checkSupport(expr.consequent, pos);
|
|
1535
|
+
const consSupport = checkSupport(expr.consequent, pos, matchers);
|
|
1475
1536
|
if (!consSupport.supported)
|
|
1476
1537
|
return consSupport;
|
|
1477
|
-
const altSupport = checkSupport(expr.alternate, pos);
|
|
1538
|
+
const altSupport = checkSupport(expr.alternate, pos, matchers);
|
|
1478
1539
|
if (!altSupport.supported)
|
|
1479
1540
|
return altSupport;
|
|
1480
1541
|
return { supported: true, level: "L4" };
|
|
@@ -1482,7 +1543,7 @@ function checkSupport(expr, pos) {
|
|
|
1482
1543
|
case "template-literal": {
|
|
1483
1544
|
for (const part of expr.parts) {
|
|
1484
1545
|
if (part.type === "expression") {
|
|
1485
|
-
const partSupport = checkSupport(part.expr, pos);
|
|
1546
|
+
const partSupport = checkSupport(part.expr, pos, matchers);
|
|
1486
1547
|
if (!partSupport.supported)
|
|
1487
1548
|
return partSupport;
|
|
1488
1549
|
}
|
|
@@ -2628,12 +2689,22 @@ function renderLoopBindingAccess(b, base) {
|
|
|
2628
2689
|
}
|
|
2629
2690
|
return parent;
|
|
2630
2691
|
}
|
|
2631
|
-
function wrapLoopParamAsAccessor(expr, paramName, bindings) {
|
|
2692
|
+
function wrapLoopParamAsAccessor(expr, paramName, bindings, indexParam) {
|
|
2693
|
+
let result;
|
|
2632
2694
|
if (bindings && bindings.length > 0) {
|
|
2633
|
-
|
|
2695
|
+
result = rewriteLoopBindingRefs(expr, bindings, "__bfItem()");
|
|
2696
|
+
} else {
|
|
2697
|
+
const re = new RegExp(`${ID_BOUNDARY_BEFORE}${escapeIdentifierForRegex(paramName)}(?!\\s*\\()(?!-)${ID_BOUNDARY_AFTER}`, "gu");
|
|
2698
|
+
result = replaceInExprContexts(expr, re, () => `${paramName}()`);
|
|
2634
2699
|
}
|
|
2635
|
-
|
|
2636
|
-
|
|
2700
|
+
if (indexParam && indexParam !== paramName) {
|
|
2701
|
+
result = wrapIndexParamAsAccessor(result, indexParam);
|
|
2702
|
+
}
|
|
2703
|
+
return result;
|
|
2704
|
+
}
|
|
2705
|
+
function wrapIndexParamAsAccessor(expr, indexParam) {
|
|
2706
|
+
const re = new RegExp(`${ID_BOUNDARY_BEFORE}${escapeIdentifierForRegex(indexParam)}(?!\\s*\\()(?!-)${ID_BOUNDARY_AFTER}`, "gu");
|
|
2707
|
+
return replaceInExprContexts(expr, re, () => `${indexParam}()`);
|
|
2637
2708
|
}
|
|
2638
2709
|
function rewriteLoopBindingRefs(expr, bindings, accessor) {
|
|
2639
2710
|
const byName = new Map;
|
|
@@ -2680,7 +2751,7 @@ function wrapExprWithLoopParams(expr, loopParams) {
|
|
|
2680
2751
|
let result = expr;
|
|
2681
2752
|
for (const p of loopParams) {
|
|
2682
2753
|
const spec = typeof p === "string" ? { param: p } : p;
|
|
2683
|
-
result = wrapLoopParamAsAccessor(result, spec.param, spec.bindings);
|
|
2754
|
+
result = wrapLoopParamAsAccessor(result, spec.param, spec.bindings, spec.index);
|
|
2684
2755
|
}
|
|
2685
2756
|
return result;
|
|
2686
2757
|
}
|
|
@@ -2967,6 +3038,20 @@ function buildPropAliasMap(params) {
|
|
|
2967
3038
|
}
|
|
2968
3039
|
return map;
|
|
2969
3040
|
}
|
|
3041
|
+
function resolveBodyDestructuredPropAliases(localConstants, propsObjectName) {
|
|
3042
|
+
const aliases = new Map;
|
|
3043
|
+
if (propsObjectName === null)
|
|
3044
|
+
return aliases;
|
|
3045
|
+
for (const c of localConstants) {
|
|
3046
|
+
if (c.isModule)
|
|
3047
|
+
continue;
|
|
3048
|
+
const m = c.parsed;
|
|
3049
|
+
if (m?.kind === "member" && !m.computed && m.object.kind === "identifier" && m.object.name === propsObjectName) {
|
|
3050
|
+
aliases.set(c.name, m.property);
|
|
3051
|
+
}
|
|
3052
|
+
}
|
|
3053
|
+
return aliases;
|
|
3054
|
+
}
|
|
2970
3055
|
function boundPropLocalNames(b) {
|
|
2971
3056
|
if (b.propsObjectName !== null)
|
|
2972
3057
|
return EMPTY_SET;
|
|
@@ -3199,6 +3284,18 @@ function resolveGetterAliases(localConstants, isGetter) {
|
|
|
3199
3284
|
}
|
|
3200
3285
|
return aliases;
|
|
3201
3286
|
}
|
|
3287
|
+
function collectAliasableGetterNames(signals, memos) {
|
|
3288
|
+
const getterNames = new Set;
|
|
3289
|
+
for (const sig of signals) {
|
|
3290
|
+
if (sig.getter && !sig.isModule && !sig.envReader)
|
|
3291
|
+
getterNames.add(sig.getter);
|
|
3292
|
+
}
|
|
3293
|
+
for (const memo of memos) {
|
|
3294
|
+
if (!memo.isModule)
|
|
3295
|
+
getterNames.add(memo.name);
|
|
3296
|
+
}
|
|
3297
|
+
return getterNames;
|
|
3298
|
+
}
|
|
3202
3299
|
function buildSignalMemoEnv(signals, memos, propsObjectName, localConstants = []) {
|
|
3203
3300
|
const substitutions = new Map;
|
|
3204
3301
|
for (const s of signals) {
|
|
@@ -3378,6 +3475,65 @@ class BindingScope {
|
|
|
3378
3475
|
}
|
|
3379
3476
|
}
|
|
3380
3477
|
|
|
3478
|
+
// src/ir-to-client-js/safe-html.ts
|
|
3479
|
+
function safeHtml(expr) {
|
|
3480
|
+
return expr;
|
|
3481
|
+
}
|
|
3482
|
+
function interp(span) {
|
|
3483
|
+
return `\${${span}}`;
|
|
3484
|
+
}
|
|
3485
|
+
function escapedText(expr) {
|
|
3486
|
+
return safeHtml(`escapeText(${expr})`);
|
|
3487
|
+
}
|
|
3488
|
+
function escapedTextOrMarkup(expr) {
|
|
3489
|
+
return safeHtml(`escapeTextOrMarkup(${expr})`);
|
|
3490
|
+
}
|
|
3491
|
+
function branchSlotValue(expr, slotsVar) {
|
|
3492
|
+
return safeHtml(`__bfSlot(${expr}, ${slotsVar})`);
|
|
3493
|
+
}
|
|
3494
|
+
function childrenMarkup(expr) {
|
|
3495
|
+
return safeHtml(`markupOrEmpty(${expr})`);
|
|
3496
|
+
}
|
|
3497
|
+
function joinedMarkup(expr) {
|
|
3498
|
+
return safeHtml(`Array.isArray(${expr}) ? ${expr}.join('') : (${expr} ?? '')`);
|
|
3499
|
+
}
|
|
3500
|
+
function renderChildCall(registryName, propsExpr, tailArgs) {
|
|
3501
|
+
return safeHtml(`renderChild('${registryName}', ${propsExpr}${tailArgs})`);
|
|
3502
|
+
}
|
|
3503
|
+
function dangerousInnerHtml(expr) {
|
|
3504
|
+
return safeHtml(`((${expr}) ?? {}).__html ?? ''`);
|
|
3505
|
+
}
|
|
3506
|
+
function conditionalMarkup(condition, whenTrue, whenFalse) {
|
|
3507
|
+
return safeHtml(`${condition} ? \`${whenTrue}\` : \`${whenFalse}\``);
|
|
3508
|
+
}
|
|
3509
|
+
function mappedRowsMarkup(arrayExpr, method, params, body) {
|
|
3510
|
+
return safeHtml(`${arrayExpr}.${method}(${params} => ${body}).join('')`);
|
|
3511
|
+
}
|
|
3512
|
+
var EMPTY_MARKUP = safeHtml("''");
|
|
3513
|
+
function isChildrenPassthroughExpr(expr) {
|
|
3514
|
+
return /^([A-Za-z_$][\w$]*\.)?children$/.test(expr.trim());
|
|
3515
|
+
}
|
|
3516
|
+
function spliceChildValue(node, valueExpr, cx) {
|
|
3517
|
+
if (node.joinArrayChild)
|
|
3518
|
+
return joinedMarkup(valueExpr);
|
|
3519
|
+
if (cx.branchSlotsVar)
|
|
3520
|
+
return branchSlotValue(valueExpr, cx.branchSlotsVar);
|
|
3521
|
+
if (node.slotId) {
|
|
3522
|
+
return cx.markupSlotIds?.has(node.slotId) ? escapedTextOrMarkup(valueExpr) : escapedText(valueExpr);
|
|
3523
|
+
}
|
|
3524
|
+
const resolved = valueExpr.trim().replace(/^\(+|\)+$/g, "");
|
|
3525
|
+
if (isChildrenPassthroughExpr(node.expr) || isChildrenPassthroughExpr(resolved)) {
|
|
3526
|
+
return childrenMarkup(valueExpr);
|
|
3527
|
+
}
|
|
3528
|
+
return escapedText(valueExpr);
|
|
3529
|
+
}
|
|
3530
|
+
|
|
3531
|
+
// src/ir-to-client-js/markup-slots.ts
|
|
3532
|
+
var DYNAMIC_ELEMENT_WRITER_KIND = "markup";
|
|
3533
|
+
function markupSlotIdsOf(ctx) {
|
|
3534
|
+
return new Set(ctx.dynamicElements.map((e) => e.slotId));
|
|
3535
|
+
}
|
|
3536
|
+
|
|
3381
3537
|
// src/ir-to-client-js/html-template.ts
|
|
3382
3538
|
function createStringProtector() {
|
|
3383
3539
|
const strings = [];
|
|
@@ -3547,22 +3703,11 @@ function templateAttrExpr(attrName, valExpr, presenceOrUndefined) {
|
|
|
3547
3703
|
function escapeAttrValueExpr(valExpr) {
|
|
3548
3704
|
return `escapeAttr(${valExpr})`;
|
|
3549
3705
|
}
|
|
3550
|
-
function escapeTextSlotExpr(innerExpr, isMarkup = false) {
|
|
3551
|
-
return `${isMarkup ? "escapeTextOrMarkup" : "escapeText"}(${innerExpr})`;
|
|
3552
|
-
}
|
|
3553
|
-
function isChildrenPassthroughExpr(expr) {
|
|
3554
|
-
return /^([A-Za-z_$][\w$]*\.)?children$/.test(expr.trim());
|
|
3555
|
-
}
|
|
3556
|
-
function bareSpliceExpr(node, valueExpr) {
|
|
3557
|
-
const resolved = valueExpr.trim().replace(/^\(+|\)+$/g, "");
|
|
3558
|
-
const isChildren = isChildrenPassthroughExpr(node.expr) || isChildrenPassthroughExpr(resolved);
|
|
3559
|
-
return !node.joinArrayChild && isChildren ? `markupOrEmpty(${valueExpr})` : valueExpr;
|
|
3560
|
-
}
|
|
3561
3706
|
function dangerouslyHtmlChildren(attrs, toExpr) {
|
|
3562
3707
|
const attr = attrs.find((a) => a.name === "dangerouslySetInnerHTML");
|
|
3563
3708
|
if (!attr || attr.value.kind !== "expression")
|
|
3564
3709
|
return null;
|
|
3565
|
-
return
|
|
3710
|
+
return interp(dangerousInnerHtml(toExpr(attr.value)));
|
|
3566
3711
|
}
|
|
3567
3712
|
function transformKeyValue(value, transformExpr) {
|
|
3568
3713
|
switch (value.kind) {
|
|
@@ -3678,7 +3823,7 @@ function buildSpreadAttrsMergeCall(args) {
|
|
|
3678
3823
|
return `\${spreadAttrs({${objMembers.join(", ")}})}`;
|
|
3679
3824
|
}
|
|
3680
3825
|
function itemAnchorTemplate(keyExpr) {
|
|
3681
|
-
return `<!--${loopItemMarker("${" + keyExpr + "}")}-->`;
|
|
3826
|
+
return `<!--${loopItemMarker("${escapeCommentText(" + keyExpr + ")}")}-->`;
|
|
3682
3827
|
}
|
|
3683
3828
|
function renderPreamble(preamble, opts) {
|
|
3684
3829
|
let out = "";
|
|
@@ -3687,9 +3832,9 @@ function renderPreamble(preamble, opts) {
|
|
|
3687
3832
|
const text = opts.textVariant === "template" ? seg.templateText ?? seg.text : seg.text;
|
|
3688
3833
|
out += opts.transformJs ? opts.transformJs(text) : text;
|
|
3689
3834
|
} else if (opts.rawLeaf) {
|
|
3690
|
-
out += opts.renderLeaf(
|
|
3835
|
+
out += opts.renderLeaf(seg.ir);
|
|
3691
3836
|
} else {
|
|
3692
|
-
out += "`" + opts.renderLeaf(
|
|
3837
|
+
out += "`" + opts.renderLeaf(seg.ir) + "`";
|
|
3693
3838
|
}
|
|
3694
3839
|
}
|
|
3695
3840
|
return out;
|
|
@@ -3734,36 +3879,12 @@ function renderFlatMapProjectionClientBody(inner, restSpreadNames) {
|
|
|
3734
3879
|
const chained = applyLoopChain(inner);
|
|
3735
3880
|
const params = inner.index ? `(${inner.param}, ${inner.index})` : `(${inner.param})`;
|
|
3736
3881
|
const key = inner.key ? `(${inner.key})` : "undefined";
|
|
3737
|
-
const html = inner.children.map((c) => irToHtmlTemplate(
|
|
3882
|
+
const html = inner.children.map((c) => irToHtmlTemplate(c, restSpreadNames, 1, undefined, undefined)).join("");
|
|
3738
3883
|
return `${chained}.map(${params} => ({ k: ${key}, h: \`${html}\` }))`;
|
|
3739
3884
|
}
|
|
3740
|
-
function escapeLeafTextExpressions(ir) {
|
|
3741
|
-
switch (ir.type) {
|
|
3742
|
-
case "element":
|
|
3743
|
-
return { ...ir, children: ir.children.map(escapeLeafTextExpressions) };
|
|
3744
|
-
case "fragment":
|
|
3745
|
-
return { ...ir, children: ir.children.map(escapeLeafTextExpressions) };
|
|
3746
|
-
case "expression": {
|
|
3747
|
-
if (ir.expr === "null" || ir.expr === "undefined")
|
|
3748
|
-
return ir;
|
|
3749
|
-
if (ir.slotId || ir.expr.trimStart().startsWith("escapeText("))
|
|
3750
|
-
return ir;
|
|
3751
|
-
return { ...ir, expr: `escapeText((${ir.expr}))`, templateExpr: ir.templateExpr ? `escapeText((${ir.templateExpr}))` : ir.templateExpr };
|
|
3752
|
-
}
|
|
3753
|
-
case "conditional":
|
|
3754
|
-
return {
|
|
3755
|
-
...ir,
|
|
3756
|
-
whenTrue: escapeLeafTextExpressions(ir.whenTrue),
|
|
3757
|
-
whenFalse: ir.whenFalse ? escapeLeafTextExpressions(ir.whenFalse) : ir.whenFalse
|
|
3758
|
-
};
|
|
3759
|
-
default:
|
|
3760
|
-
return ir;
|
|
3761
|
-
}
|
|
3762
|
-
}
|
|
3763
3885
|
function irToHtmlTemplate(node, restSpreadNames, loopDepth = 0, loopParams, branchSlotsVar, inHoistedChildren = false) {
|
|
3764
3886
|
const recurse = (n) => irToHtmlTemplate(n, restSpreadNames, loopDepth, loopParams, branchSlotsVar, inHoistedChildren);
|
|
3765
3887
|
const wrapExpr = (expr) => wrapExprWithLoopParams(expr, loopParams);
|
|
3766
|
-
const wrapInterpolation = (expr) => branchSlotsVar ? `__bfSlot(${expr}, ${branchSlotsVar})` : expr;
|
|
3767
3888
|
switch (node.type) {
|
|
3768
3889
|
case "element": {
|
|
3769
3890
|
const mergeCtx = {
|
|
@@ -3809,25 +3930,17 @@ function irToHtmlTemplate(node, restSpreadNames, loopDepth = 0, loopParams, bran
|
|
|
3809
3930
|
case "expression": {
|
|
3810
3931
|
if (node.expr === "null" || node.expr === "undefined")
|
|
3811
3932
|
return "";
|
|
3812
|
-
const
|
|
3813
|
-
if (node.markerless)
|
|
3814
|
-
|
|
3815
|
-
|
|
3816
|
-
}
|
|
3817
|
-
const inner = escapeForClient(wrapInterpolation(wrapExpr(node.expr)));
|
|
3818
|
-
const valueExpr = node.joinArrayChild ? `Array.isArray(${inner}) ? ${inner}.join('') : (${inner} ?? '')` : inner;
|
|
3819
|
-
if (node.slotId) {
|
|
3820
|
-
const slotted = branchSlotsVar || node.joinArrayChild ? valueExpr : escapeTextSlotExpr(valueExpr);
|
|
3821
|
-
return `<!--bf:${node.slotId}-->\${${slotted}}<!--/-->`;
|
|
3822
|
-
}
|
|
3823
|
-
return `\${${bareSpliceExpr(node, valueExpr)}}`;
|
|
3933
|
+
const hole = interp(spliceChildValue(node, wrapExpr(node.expr), { branchSlotsVar }));
|
|
3934
|
+
if (node.markerless)
|
|
3935
|
+
return hole;
|
|
3936
|
+
return node.slotId ? `<!--bf:${node.slotId}-->${hole}<!--/-->` : hole;
|
|
3824
3937
|
}
|
|
3825
3938
|
case "conditional": {
|
|
3826
3939
|
const trueBranch = recurse(node.whenTrue);
|
|
3827
3940
|
const falseBranch = recurse(node.whenFalse);
|
|
3828
3941
|
const trueHtml = node.slotId ? addCondAttrToTemplate(trueBranch, node.slotId) : trueBranch;
|
|
3829
3942
|
const falseHtml = node.slotId ? addCondAttrToTemplate(falseBranch, node.slotId) : falseBranch;
|
|
3830
|
-
return
|
|
3943
|
+
return interp(conditionalMarkup(wrapExpr(node.condition), trueHtml, falseHtml));
|
|
3831
3944
|
}
|
|
3832
3945
|
case "fragment":
|
|
3833
3946
|
return node.children.map(recurse).join("");
|
|
@@ -3864,7 +3977,7 @@ function irToHtmlTemplate(node, restSpreadNames, loopDepth = 0, loopParams, bran
|
|
|
3864
3977
|
const propsExpr = propsEntries.length > 0 ? `{${propsEntries.join(", ")}}` : "{}";
|
|
3865
3978
|
const keyProp = node.props.find((p) => p.name === "key");
|
|
3866
3979
|
const keyArg = keyProp ? `, ${attrValueToString(keyProp.value) ?? "undefined"}` : "";
|
|
3867
|
-
return
|
|
3980
|
+
return interp(renderChildCall(nameForRegistryRef(node.name), propsExpr, renderChildScopeArgs(node, keyArg)));
|
|
3868
3981
|
}
|
|
3869
3982
|
case "loop": {
|
|
3870
3983
|
const innerRecurse = (n) => irToHtmlTemplate(n, restSpreadNames, loopDepth + 1, loopParams, branchSlotsVar);
|
|
@@ -3882,12 +3995,12 @@ function irToHtmlTemplate(node, restSpreadNames, loopDepth = 0, loopParams, bran
|
|
|
3882
3995
|
const body = renderPreamble(node.flatMapCallback, {
|
|
3883
3996
|
renderLeaf: (ir) => irToHtmlTemplate(stripLeafKeyAttr(ir), restSpreadNames, loopDepth + 1, loopParams, branchSlotsVar)
|
|
3884
3997
|
});
|
|
3885
|
-
mapExpr =
|
|
3998
|
+
mapExpr = interp(mappedRowsMarkup(wrappedArray, "flatMap", node.flatMapCallback.params, body));
|
|
3886
3999
|
} else if (node.preamble) {
|
|
3887
4000
|
const preamble = renderPreamble(node.preamble, { textVariant: "client", renderLeaf: (ir) => irToHtmlTemplate(ir, restSpreadNames, loopDepth + 1, loopParams, branchSlotsVar) });
|
|
3888
|
-
mapExpr =
|
|
4001
|
+
mapExpr = interp(mappedRowsMarkup(wrappedArray, iterMethod, callbackParam, `{ ${preamble} return \`${childTemplate}\` }`));
|
|
3889
4002
|
} else {
|
|
3890
|
-
mapExpr =
|
|
4003
|
+
mapExpr = interp(mappedRowsMarkup(wrappedArray, iterMethod, callbackParam, `\`${childTemplate}\``));
|
|
3891
4004
|
}
|
|
3892
4005
|
return `<!--${loopStartMarker(node.markerId)}-->${mapExpr}<!--${loopEndMarker(node.markerId)}-->`;
|
|
3893
4006
|
}
|
|
@@ -4146,20 +4259,15 @@ function irToPlaceholderTemplate(node, restSpreadNames, loopDepth = 0, loopParam
|
|
|
4146
4259
|
case "expression": {
|
|
4147
4260
|
if (node.expr === "null" || node.expr === "undefined")
|
|
4148
4261
|
return "";
|
|
4149
|
-
const
|
|
4150
|
-
|
|
4151
|
-
if (node.slotId) {
|
|
4152
|
-
return `<!--bf:${node.slotId}-->\${${node.joinArrayChild ? value : escapeTextSlotExpr(wrapped)}}<!--/-->`;
|
|
4153
|
-
}
|
|
4154
|
-
const spliced = bareSpliceExpr(node, value);
|
|
4155
|
-
return `\${${node.escapeInClientTemplate ? `escapeText(${spliced})` : spliced}}`;
|
|
4262
|
+
const hole = interp(spliceChildValue(node, wrapExpr(node.expr), {}));
|
|
4263
|
+
return node.slotId ? `<!--bf:${node.slotId}-->${hole}<!--/-->` : hole;
|
|
4156
4264
|
}
|
|
4157
4265
|
case "conditional": {
|
|
4158
4266
|
const trueBranch = recurse(node.whenTrue);
|
|
4159
4267
|
const falseBranch = recurse(node.whenFalse);
|
|
4160
4268
|
const trueHtml = node.slotId ? addCondAttrToTemplate(trueBranch, node.slotId) : trueBranch;
|
|
4161
4269
|
const falseHtml = node.slotId ? addCondAttrToTemplate(falseBranch, node.slotId) : falseBranch;
|
|
4162
|
-
return
|
|
4270
|
+
return interp(conditionalMarkup(wrapExpr(node.condition), trueHtml, falseHtml));
|
|
4163
4271
|
}
|
|
4164
4272
|
case "fragment":
|
|
4165
4273
|
return node.children.map(recurse).join("");
|
|
@@ -4183,12 +4291,12 @@ function irToPlaceholderTemplate(node, restSpreadNames, loopDepth = 0, loopParam
|
|
|
4183
4291
|
const body = renderPreamble(node.flatMapCallback, {
|
|
4184
4292
|
renderLeaf: (ir) => irToPlaceholderTemplate(stripLeafKeyAttr(ir), restSpreadNames, loopDepth + 1, loopParams)
|
|
4185
4293
|
});
|
|
4186
|
-
mapExpr =
|
|
4294
|
+
mapExpr = interp(mappedRowsMarkup(wrappedArray, "flatMap", node.flatMapCallback.params, body));
|
|
4187
4295
|
} else if (node.preamble) {
|
|
4188
4296
|
const preamble = renderPreamble(node.preamble, { textVariant: "client", renderLeaf: (ir) => irToPlaceholderTemplate(ir, restSpreadNames, loopDepth + 1, loopParams) });
|
|
4189
|
-
mapExpr =
|
|
4297
|
+
mapExpr = interp(mappedRowsMarkup(wrappedArray, iterMethod, callbackParam, `{ ${preamble} return \`${childTemplate}\` }`));
|
|
4190
4298
|
} else {
|
|
4191
|
-
mapExpr =
|
|
4299
|
+
mapExpr = interp(mappedRowsMarkup(wrappedArray, iterMethod, callbackParam, `\`${childTemplate}\``));
|
|
4192
4300
|
}
|
|
4193
4301
|
return `<!--${loopStartMarker(node.markerId)}-->${mapExpr}<!--${loopEndMarker(node.markerId)}-->`;
|
|
4194
4302
|
}
|
|
@@ -4390,13 +4498,8 @@ function irToComponentTemplateWithOpts(node, opts) {
|
|
|
4390
4498
|
return "";
|
|
4391
4499
|
return `<!--bf:${node.slotId}--><!--/-->`;
|
|
4392
4500
|
}
|
|
4393
|
-
const
|
|
4394
|
-
|
|
4395
|
-
if (node.slotId) {
|
|
4396
|
-
const isMarkup = opts.markupSlotIds?.has(node.slotId) ?? false;
|
|
4397
|
-
return `<!--bf:${node.slotId}-->\${${node.joinArrayChild ? value : escapeTextSlotExpr(wrapped, isMarkup)}}<!--/-->`;
|
|
4398
|
-
}
|
|
4399
|
-
return `\${${bareSpliceExpr(node, value)}}`;
|
|
4501
|
+
const hole = interp(spliceChildValue(node, transformExpr(node.expr, node.templateExpr), { markupSlotIds: opts.markupSlotIds }));
|
|
4502
|
+
return node.slotId ? `<!--bf:${node.slotId}-->${hole}<!--/-->` : hole;
|
|
4400
4503
|
}
|
|
4401
4504
|
case "conditional": {
|
|
4402
4505
|
if (node.clientOnly && node.slotId) {
|
|
@@ -4406,7 +4509,7 @@ function irToComponentTemplateWithOpts(node, opts) {
|
|
|
4406
4509
|
const falseBranch = recurse(node.whenFalse);
|
|
4407
4510
|
const trueHtml = node.slotId ? addCondAttrToTemplate(trueBranch, node.slotId) : trueBranch;
|
|
4408
4511
|
const falseHtml = node.slotId ? addCondAttrToTemplate(falseBranch, node.slotId) : falseBranch;
|
|
4409
|
-
return
|
|
4512
|
+
return interp(conditionalMarkup(transformExpr(node.condition, node.templateCondition), trueHtml, falseHtml));
|
|
4410
4513
|
}
|
|
4411
4514
|
case "fragment":
|
|
4412
4515
|
return node.children.map(recurse).join("");
|
|
@@ -4444,7 +4547,7 @@ function irToComponentTemplateWithOpts(node, opts) {
|
|
|
4444
4547
|
const propsExpr = propsEntries.length > 0 ? `{${propsEntries.join(", ")}}` : "{}";
|
|
4445
4548
|
const keyProp = node.props.find((p) => p.name === "key");
|
|
4446
4549
|
const keyArg = keyProp ? `, ${transformKeyValue(keyProp.value, transformExpr)}` : "";
|
|
4447
|
-
return
|
|
4550
|
+
return interp(renderChildCall(nameForRegistryRef(node.name), propsExpr, keyArg));
|
|
4448
4551
|
}
|
|
4449
4552
|
case "loop": {
|
|
4450
4553
|
const innerOpts = { ...opts, loopDepth: loopDepth + 1 };
|
|
@@ -4454,7 +4557,7 @@ function irToComponentTemplateWithOpts(node, opts) {
|
|
|
4454
4557
|
case "if-statement": {
|
|
4455
4558
|
const consequent = recurse(node.consequent);
|
|
4456
4559
|
const alternate = node.alternate ? recurse(node.alternate) : "";
|
|
4457
|
-
return
|
|
4560
|
+
return interp(conditionalMarkup(transformExpr(node.condition, node.templateCondition), consequent, alternate));
|
|
4458
4561
|
}
|
|
4459
4562
|
case "provider":
|
|
4460
4563
|
case "async":
|
|
@@ -4542,7 +4645,7 @@ function generateCsrTemplate(node, inlinableConstants, ctx, restSpreadNames, pro
|
|
|
4542
4645
|
}
|
|
4543
4646
|
}
|
|
4544
4647
|
const effectiveUnsafeLocalNames = mergeCsrNullUnsafe(ctx, unsafeLocalNames);
|
|
4545
|
-
const markupSlotIds =
|
|
4648
|
+
const markupSlotIds = markupSlotIdsOf(ctx);
|
|
4546
4649
|
return generateCsrTemplateWithOpts(node, { inlinableConstants, restSpreadNames, propsObjectName, csrEnv, unsafeLocalNames: effectiveUnsafeLocalNames, deferredChildSlots, loopDepth: -1, markupSlotIds, restPropsName: ctx.restPropsName });
|
|
4547
4650
|
}
|
|
4548
4651
|
function mergeCsrNullUnsafe(ctx, unsafeLocalNames) {
|
|
@@ -4741,13 +4844,8 @@ function generateCsrTemplateWithOpts(node, opts) {
|
|
|
4741
4844
|
}
|
|
4742
4845
|
{
|
|
4743
4846
|
const transformed = transformExpr(node.expr, node.templateExpr);
|
|
4744
|
-
const
|
|
4745
|
-
|
|
4746
|
-
if (node.slotId) {
|
|
4747
|
-
const isMarkup = opts.markupSlotIds?.has(node.slotId) ?? false;
|
|
4748
|
-
return `<!--bf:${node.slotId}-->\${${node.joinArrayChild ? value : escapeTextSlotExpr(expr, isMarkup)}}<!--/-->`;
|
|
4749
|
-
}
|
|
4750
|
-
return `\${${bareSpliceExpr(node, value)}}`;
|
|
4847
|
+
const hole = interp(transformed === UNSAFE_TEMPLATE_EXPR ? EMPTY_MARKUP : spliceChildValue(node, transformed, { markupSlotIds: opts.markupSlotIds }));
|
|
4848
|
+
return node.slotId ? `<!--bf:${node.slotId}-->${hole}<!--/-->` : hole;
|
|
4751
4849
|
}
|
|
4752
4850
|
case "conditional": {
|
|
4753
4851
|
if (node.clientOnly && node.slotId) {
|
|
@@ -4757,7 +4855,7 @@ function generateCsrTemplateWithOpts(node, opts) {
|
|
|
4757
4855
|
const falseBranch = recurse(node.whenFalse);
|
|
4758
4856
|
const trueHtml = node.slotId ? addCondAttrToTemplate(trueBranch, node.slotId) : trueBranch;
|
|
4759
4857
|
const falseHtml = node.slotId ? addCondAttrToTemplate(falseBranch, node.slotId) : falseBranch;
|
|
4760
|
-
return
|
|
4858
|
+
return interp(conditionalMarkup(transformExpr(node.condition, node.templateCondition), trueHtml, falseHtml));
|
|
4761
4859
|
}
|
|
4762
4860
|
case "fragment":
|
|
4763
4861
|
return node.children.map(recurse).join("");
|
|
@@ -4806,7 +4904,7 @@ function generateCsrTemplateWithOpts(node, opts) {
|
|
|
4806
4904
|
const propsExpr = propsEntries.length > 0 ? `{${propsEntries.join(", ")}}` : "{}";
|
|
4807
4905
|
const keyProp = node.props.find((p) => p.name === "key");
|
|
4808
4906
|
const keyArg = keyProp ? `, ${transformKeyValue(keyProp.value, transformExpr)}` : "";
|
|
4809
|
-
return
|
|
4907
|
+
return interp(renderChildCall(nameForRegistryRef(node.name), propsExpr, renderChildScopeArgs(node, keyArg)));
|
|
4810
4908
|
}
|
|
4811
4909
|
case "loop": {
|
|
4812
4910
|
const childScope = (opts.scope ?? BindingScope.EMPTY).enterLoopRow(node);
|
|
@@ -4839,19 +4937,19 @@ function generateCsrTemplateWithOpts(node, opts) {
|
|
|
4839
4937
|
transformJs: (t) => rewritePropsObjectRef(t, propsObjectName ?? null, restPropsName ?? null, { enclosingScope: childScope }),
|
|
4840
4938
|
renderLeaf: (ir) => recurseInLoopBody(stripLeafKeyAttr(ir))
|
|
4841
4939
|
});
|
|
4842
|
-
mapExpr =
|
|
4940
|
+
mapExpr = interp(mappedRowsMarkup(iterArrayExpr, "flatMap", node.flatMapCallback.params, body));
|
|
4843
4941
|
} else if (node.preamble) {
|
|
4844
4942
|
const preamble = renderPreamble(node.preamble, { textVariant: "template", transformJs: (t) => rewritePropsObjectRef(t, propsObjectName ?? null, restPropsName ?? null, { enclosingScope: childScope }), renderLeaf: (ir) => recurseInLoopBody(ir) });
|
|
4845
|
-
mapExpr =
|
|
4943
|
+
mapExpr = interp(mappedRowsMarkup(iterArrayExpr, iterMethod, callbackParam, `{ ${preamble} return \`${childTemplate}\` }`));
|
|
4846
4944
|
} else {
|
|
4847
|
-
mapExpr =
|
|
4945
|
+
mapExpr = interp(mappedRowsMarkup(iterArrayExpr, iterMethod, callbackParam, `\`${childTemplate}\``));
|
|
4848
4946
|
}
|
|
4849
4947
|
return `<!--${loopStartMarker(node.markerId)}-->${mapExpr}<!--${loopEndMarker(node.markerId)}-->`;
|
|
4850
4948
|
}
|
|
4851
4949
|
case "if-statement": {
|
|
4852
4950
|
const consequent = recurse(node.consequent);
|
|
4853
4951
|
const alternate = node.alternate ? recurse(node.alternate) : "";
|
|
4854
|
-
return
|
|
4952
|
+
return interp(conditionalMarkup(transformExpr(node.condition, node.templateCondition), consequent, alternate));
|
|
4855
4953
|
}
|
|
4856
4954
|
case "provider":
|
|
4857
4955
|
case "async":
|
|
@@ -4952,8 +5050,6 @@ function collectAstPropRefs(node, propNames, out) {
|
|
|
4952
5050
|
walkWithScope(node, (n, parent, shadowed) => {
|
|
4953
5051
|
if (shadowed || !propNames.has(n.text))
|
|
4954
5052
|
return;
|
|
4955
|
-
if (parent && ts7.isShorthandPropertyAssignment(parent) && parent.name === n)
|
|
4956
|
-
return;
|
|
4957
5053
|
if (isNonValuePosition(n, parent))
|
|
4958
5054
|
return;
|
|
4959
5055
|
out.add(n.text);
|
|
@@ -7179,6 +7275,7 @@ var CLIENT_EXPORTS = new Set([
|
|
|
7179
7275
|
"isSSRPortal",
|
|
7180
7276
|
"findSiblingSlot",
|
|
7181
7277
|
"cleanupPortalPlaceholder",
|
|
7278
|
+
"trackPosition",
|
|
7182
7279
|
"createSearchParams",
|
|
7183
7280
|
"queryHref",
|
|
7184
7281
|
"formatDate",
|
|
@@ -8498,7 +8595,8 @@ var BROWSER_ONLY_CLIENT_APIS = new Set([
|
|
|
8498
8595
|
"createPortal",
|
|
8499
8596
|
"isSSRPortal",
|
|
8500
8597
|
"findSiblingSlot",
|
|
8501
|
-
"cleanupPortalPlaceholder"
|
|
8598
|
+
"cleanupPortalPlaceholder",
|
|
8599
|
+
"trackPosition"
|
|
8502
8600
|
]);
|
|
8503
8601
|
function importsBrowserOnlyClientApi(ctx) {
|
|
8504
8602
|
for (const imp of ctx.imports) {
|
|
@@ -10734,9 +10832,8 @@ function collectBranchLocalPropRefsViaSubstitution(node, ctx) {
|
|
|
10734
10832
|
function visit2(n, parent) {
|
|
10735
10833
|
if (ts14.isIdentifier(n) && propDepsMap.has(n.text)) {
|
|
10736
10834
|
const isObjectKey = parent && ts14.isPropertyAssignment(parent) && parent.name === n;
|
|
10737
|
-
const isShorthand = parent && ts14.isShorthandPropertyAssignment(parent) && parent.name === n;
|
|
10738
10835
|
const isAccessName = parent && ts14.isPropertyAccessExpression(parent) && parent.name === n;
|
|
10739
|
-
if (!isObjectKey && !
|
|
10836
|
+
if (!isObjectKey && !isAccessName) {
|
|
10740
10837
|
const deps = propDepsMap.get(n.text);
|
|
10741
10838
|
if (deps && deps.size > 0) {
|
|
10742
10839
|
if (!acc)
|
|
@@ -11214,8 +11311,7 @@ function lowerFormControlValueSsr(tagName, attrs, children) {
|
|
|
11214
11311
|
children.push({
|
|
11215
11312
|
type: "expression",
|
|
11216
11313
|
expr,
|
|
11217
|
-
templateExpr
|
|
11218
|
-
escapeInClientTemplate: true,
|
|
11314
|
+
templateExpr,
|
|
11219
11315
|
typeInfo: null,
|
|
11220
11316
|
reactive: false,
|
|
11221
11317
|
slotId: null,
|
|
@@ -11226,26 +11322,76 @@ function lowerFormControlValueSsr(tagName, attrs, children) {
|
|
|
11226
11322
|
}
|
|
11227
11323
|
const selectedForLiteral = (optValue) => AttrValueOf.expression(`(${expr}) === ${JSON.stringify(optValue)}`, templateExpr !== undefined ? { templateExpr: `(${templateExpr}) === ${JSON.stringify(optValue)}` } : undefined);
|
|
11228
11324
|
const selectedForExpr = (optExpr, optTemplateExpr) => AttrValueOf.expression(`(${expr}) === (${optExpr})`, templateExpr !== undefined || optTemplateExpr !== undefined ? { templateExpr: `(${templateExpr ?? expr}) === (${optTemplateExpr ?? optExpr})` } : undefined);
|
|
11325
|
+
const matchConditions = [];
|
|
11326
|
+
let optionSetIsDynamic = false;
|
|
11229
11327
|
const distribute = (nodes) => {
|
|
11230
11328
|
for (const n of nodes) {
|
|
11329
|
+
if (n.type === "text")
|
|
11330
|
+
continue;
|
|
11231
11331
|
if (n.type === "element" && n.tag === "option") {
|
|
11232
|
-
if (n.attrs.some((a) => a.name === "selected"))
|
|
11332
|
+
if (n.attrs.some((a) => a.name === "selected")) {
|
|
11333
|
+
optionSetIsDynamic = true;
|
|
11233
11334
|
continue;
|
|
11335
|
+
}
|
|
11234
11336
|
const optValue = n.attrs.find((a) => a.name === "value");
|
|
11235
|
-
if (!optValue)
|
|
11337
|
+
if (!optValue) {
|
|
11338
|
+
optionSetIsDynamic = true;
|
|
11236
11339
|
continue;
|
|
11340
|
+
}
|
|
11237
11341
|
if (optValue.value.kind === "literal") {
|
|
11238
|
-
|
|
11342
|
+
const selected = selectedForLiteral(optValue.value.value);
|
|
11343
|
+
n.attrs.push({ name: "selected", value: selected, loc: n.loc });
|
|
11344
|
+
matchConditions.push(selected);
|
|
11239
11345
|
} else if (optValue.value.kind === "expression") {
|
|
11240
11346
|
const selected = selectedForExpr(optValue.value.expr, optValue.value.templateExpr);
|
|
11241
11347
|
n.attrs.push({ name: "selected", value: selected, loc: n.loc });
|
|
11348
|
+
matchConditions.push(selected);
|
|
11349
|
+
} else {
|
|
11350
|
+
optionSetIsDynamic = true;
|
|
11242
11351
|
}
|
|
11243
|
-
} else if (n.type === "fragment" || n.type === "
|
|
11352
|
+
} else if (n.type === "fragment" || n.type === "element" && n.tag === "optgroup") {
|
|
11244
11353
|
distribute(n.children);
|
|
11354
|
+
} else if (n.type === "loop") {
|
|
11355
|
+
optionSetIsDynamic = true;
|
|
11356
|
+
distribute(n.children);
|
|
11357
|
+
} else {
|
|
11358
|
+
optionSetIsDynamic = true;
|
|
11245
11359
|
}
|
|
11246
11360
|
}
|
|
11247
11361
|
};
|
|
11248
11362
|
distribute(children);
|
|
11363
|
+
if (optionSetIsDynamic || matchConditions.length === 0)
|
|
11364
|
+
return;
|
|
11365
|
+
if (isMultiSelection(attrs))
|
|
11366
|
+
return;
|
|
11367
|
+
const orExpr = matchConditions.map((c) => `(${c.expr})`).join(" || ");
|
|
11368
|
+
const orTemplateExpr = matchConditions.some((c) => c.templateExpr !== undefined) ? matchConditions.map((c) => `(${c.templateExpr ?? c.expr})`).join(" || ") : undefined;
|
|
11369
|
+
children.unshift({
|
|
11370
|
+
type: "element",
|
|
11371
|
+
tag: "option",
|
|
11372
|
+
attrs: [
|
|
11373
|
+
{ name: "value", value: AttrValueOf.literal(""), loc: valueAttr.loc },
|
|
11374
|
+
{ name: "disabled", value: AttrValueOf.booleanAttr(), loc: valueAttr.loc },
|
|
11375
|
+
{ name: "hidden", value: AttrValueOf.booleanAttr(), loc: valueAttr.loc },
|
|
11376
|
+
{
|
|
11377
|
+
name: "selected",
|
|
11378
|
+
value: AttrValueOf.expression(`!(${orExpr})`, orTemplateExpr !== undefined ? { templateExpr: `!(${orTemplateExpr})` } : undefined),
|
|
11379
|
+
loc: valueAttr.loc
|
|
11380
|
+
}
|
|
11381
|
+
],
|
|
11382
|
+
events: [],
|
|
11383
|
+
ref: null,
|
|
11384
|
+
children: [],
|
|
11385
|
+
slotId: null,
|
|
11386
|
+
needsScope: false,
|
|
11387
|
+
loc: valueAttr.loc
|
|
11388
|
+
});
|
|
11389
|
+
}
|
|
11390
|
+
function isMultiSelection(attrs) {
|
|
11391
|
+
if (attrs.some((a) => a.name === "multiple"))
|
|
11392
|
+
return true;
|
|
11393
|
+
const sizeAttr = attrs.find((a) => a.name === "size");
|
|
11394
|
+
return sizeAttr?.value.kind === "literal" && Number(sizeAttr.value.value) > 1;
|
|
11249
11395
|
}
|
|
11250
11396
|
function transformHtmlElement(node, ctx, tagName) {
|
|
11251
11397
|
const { attrs, events, ref } = processAttributes(node.openingElement.attributes, ctx);
|
|
@@ -15608,7 +15754,7 @@ function collectInnerLoops(nodes, siblingOffsets, outerLoopParam, ctx, options)
|
|
|
15608
15754
|
},
|
|
15609
15755
|
loop: ({ node: n, scope, descend }) => {
|
|
15610
15756
|
const emitDepth = fixedDepth ?? scope.depth + 1;
|
|
15611
|
-
const loopParamsForTemplate = outerLoopParam ? [outerLoopParam, { param: n.param, bindings: n.paramBindings }] : undefined;
|
|
15757
|
+
const loopParamsForTemplate = outerLoopParam ? [outerLoopParam, { param: n.param, bindings: n.paramBindings, index: n.index }] : undefined;
|
|
15612
15758
|
const template = n.children.map((c) => irToPlaceholderTemplate(c, undefined, emitDepth, loopParamsForTemplate)).join("");
|
|
15613
15759
|
const refsOuter = outerLoopParam ? identifierPattern(outerLoopParam).test(n.array) : false;
|
|
15614
15760
|
const bindings = emptyLoopChildBindings();
|
|
@@ -16205,7 +16351,7 @@ function collectLoopChildConditionals(node, ctx, siblingOffsets, loopParam, loop
|
|
|
16205
16351
|
const readsPreamble = preambleNames !== undefined && preambleNames.size > 0 && anyNameIn(expanded.freeIds ?? extractFreeIdentifiersFromText(expanded.expr), preambleNames);
|
|
16206
16352
|
if (!readsPreamble && classifyReactivity(expanded.expr, ctx, loopParam, loopParamBindings, expanded.freeIds).kind === "none")
|
|
16207
16353
|
return;
|
|
16208
|
-
const loopParamsForCond = loopParam ? [{ param: loopParam, bindings: loopParamBindings }] : undefined;
|
|
16354
|
+
const loopParamsForCond = loopParam ? [{ param: loopParam, bindings: loopParamBindings, index: loopIndex }] : undefined;
|
|
16209
16355
|
const whenTrueHtml = irToHtmlTemplate(n.whenTrue, undefined, 0, loopParamsForCond, "__slots");
|
|
16210
16356
|
const whenFalseHtml = irToHtmlTemplate(n.whenFalse, undefined, 0, loopParamsForCond, "__slots");
|
|
16211
16357
|
conditionals.push({
|
|
@@ -16789,6 +16935,7 @@ var RUNTIME_IMPORT_CANDIDATES = [
|
|
|
16789
16935
|
"escapeAttr",
|
|
16790
16936
|
"escapeText",
|
|
16791
16937
|
"escapeTextOrNode",
|
|
16938
|
+
"escapeCommentText",
|
|
16792
16939
|
"bfMarkup",
|
|
16793
16940
|
"escapeTextOrMarkup",
|
|
16794
16941
|
"markupOrEmpty",
|
|
@@ -17001,45 +17148,6 @@ function collectComponentNames(node) {
|
|
|
17001
17148
|
|
|
17002
17149
|
// src/relocate.ts
|
|
17003
17150
|
import ts18 from "typescript";
|
|
17004
|
-
|
|
17005
|
-
// src/lowering-registry.ts
|
|
17006
|
-
var plugins = [];
|
|
17007
|
-
function registerLoweringPlugin(plugin) {
|
|
17008
|
-
const existing = plugins.findIndex((p) => p.name === plugin.name);
|
|
17009
|
-
if (existing >= 0)
|
|
17010
|
-
plugins[existing] = plugin;
|
|
17011
|
-
else
|
|
17012
|
-
plugins.push(plugin);
|
|
17013
|
-
}
|
|
17014
|
-
function getLoweringPlugins() {
|
|
17015
|
-
return [...plugins];
|
|
17016
|
-
}
|
|
17017
|
-
function prepareLoweringMatchers(metadata) {
|
|
17018
|
-
const matchers = [];
|
|
17019
|
-
for (const plugin of plugins) {
|
|
17020
|
-
const matcher = plugin.prepare(metadata);
|
|
17021
|
-
if (matcher)
|
|
17022
|
-
matchers.push(matcher);
|
|
17023
|
-
}
|
|
17024
|
-
return matchers;
|
|
17025
|
-
}
|
|
17026
|
-
function matchLoweringCall(callee, args, metadata) {
|
|
17027
|
-
for (const matcher of prepareLoweringMatchers(metadata)) {
|
|
17028
|
-
const node = matcher(callee, args);
|
|
17029
|
-
if (node)
|
|
17030
|
-
return node;
|
|
17031
|
-
}
|
|
17032
|
-
return null;
|
|
17033
|
-
}
|
|
17034
|
-
function isValidHelperId(helper) {
|
|
17035
|
-
return /^[A-Za-z_][A-Za-z0-9_]*$/.test(helper);
|
|
17036
|
-
}
|
|
17037
|
-
function __resetLoweringPluginsForTest(next = []) {
|
|
17038
|
-
plugins.length = 0;
|
|
17039
|
-
plugins.push(...next);
|
|
17040
|
-
}
|
|
17041
|
-
|
|
17042
|
-
// src/relocate.ts
|
|
17043
17151
|
function classify(name, env) {
|
|
17044
17152
|
return env.bindings.get(name) ?? "global";
|
|
17045
17153
|
}
|
|
@@ -17887,7 +17995,7 @@ function emitRegistrationAndHydration(lines, ctx, _ir, graph, inlinability) {
|
|
|
17887
17995
|
const isCommentScope = isFragmentRoot || _ir.root.type === "component";
|
|
17888
17996
|
const defParts = [`init: init${name}`];
|
|
17889
17997
|
if (canGenerateStaticTemplate(_ir.root, propNamesForStaticCheck, inlinableConstants, unsafeLocalNames)) {
|
|
17890
|
-
const markupSlotIds =
|
|
17998
|
+
const markupSlotIds = markupSlotIdsOf(ctx);
|
|
17891
17999
|
const templateHtml = irToComponentTemplate(_ir.root, inlinableConstants, restSpreadNames, ctx.propsObjectName, markupSlotIds, ctx.restPropsName);
|
|
17892
18000
|
if (templateHtml) {
|
|
17893
18001
|
defParts.push(buildTemplateDefPart(ctx, templateHtml));
|
|
@@ -18912,12 +19020,12 @@ function nestedLoopIndexAlias(inner, syntheticIndexVar, paramHead, comps, events
|
|
|
18912
19020
|
return null;
|
|
18913
19021
|
return `const ${index} = ${syntheticIndexVar}`;
|
|
18914
19022
|
}
|
|
18915
|
-
function buildChildRefBindings(refs, loopParam, loopParamBindings) {
|
|
19023
|
+
function buildChildRefBindings(refs, loopParam, loopParamBindings, loopIndex) {
|
|
18916
19024
|
if (refs.length === 0)
|
|
18917
19025
|
return [];
|
|
18918
19026
|
return refs.map((r) => ({
|
|
18919
19027
|
childSlotId: r.childSlotId,
|
|
18920
|
-
callback: wrapLoopParamAsAccessor(r.callback, loopParam, loopParamBindings)
|
|
19028
|
+
callback: wrapLoopParamAsAccessor(r.callback, loopParam, loopParamBindings, loopIndex)
|
|
18921
19029
|
}));
|
|
18922
19030
|
}
|
|
18923
19031
|
function buildStaticChildRefBindings(refs) {
|
|
@@ -18950,17 +19058,17 @@ function destructureLoopParam(param, paramBindings) {
|
|
|
18950
19058
|
}
|
|
18951
19059
|
return { head: param, unwrap: "" };
|
|
18952
19060
|
}
|
|
18953
|
-
function buildPreambleRegionPlans(regions, loopParam, loopParamBindings) {
|
|
19061
|
+
function buildPreambleRegionPlans(regions, loopParam, loopParamBindings, loopIndex) {
|
|
18954
19062
|
if (!regions || regions.length === 0)
|
|
18955
19063
|
return [];
|
|
18956
19064
|
return regions.map((r) => {
|
|
18957
|
-
const wrapped = wrapLoopParamAsAccessor(r.expr, loopParam, loopParamBindings);
|
|
18958
|
-
const valueExpr = r.
|
|
19065
|
+
const wrapped = wrapLoopParamAsAccessor(r.expr, loopParam, loopParamBindings, loopIndex);
|
|
19066
|
+
const valueExpr = spliceChildValue({ expr: r.expr, slotId: r.slotId, joinArrayChild: r.joinArrayChild }, wrapped, {});
|
|
18959
19067
|
return { slotId: r.slotId, valueExpr };
|
|
18960
19068
|
});
|
|
18961
19069
|
}
|
|
18962
|
-
function buildComponentPropsExpr2(comp, loopParam, loopParamBindings) {
|
|
18963
|
-
const wrap = loopParam ? (expr) => wrapLoopParamAsAccessor(expr, loopParam, loopParamBindings) : (expr) => expr;
|
|
19070
|
+
function buildComponentPropsExpr2(comp, loopParam, loopParamBindings, loopIndex) {
|
|
19071
|
+
const wrap = loopParam ? (expr) => wrapLoopParamAsAccessor(expr, loopParam, loopParamBindings, loopIndex) : (expr) => expr;
|
|
18964
19072
|
const entries = comp.props.map((p) => {
|
|
18965
19073
|
if (p.isEventHandler) {
|
|
18966
19074
|
const handlerExpr = attrValueToString(p.value) ?? "undefined";
|
|
@@ -19004,8 +19112,8 @@ function buildDepthLevels(innerLoops, nestedComps, childEvents) {
|
|
|
19004
19112
|
loopInfo: loop
|
|
19005
19113
|
}));
|
|
19006
19114
|
}
|
|
19007
|
-
function emitEventSetup(ls, indent, elVar, ev, loopParam, loopParamBindings, bodyIsMultiRoot = false) {
|
|
19008
|
-
const handler = loopParam ? wrapLoopParamAsAccessor(ev.handler, loopParam, loopParamBindings) : ev.handler;
|
|
19115
|
+
function emitEventSetup(ls, indent, elVar, ev, loopParam, loopParamBindings, bodyIsMultiRoot = false, loopIndex) {
|
|
19116
|
+
const handler = loopParam ? wrapLoopParamAsAccessor(ev.handler, loopParam, loopParamBindings, loopIndex) : ev.handler;
|
|
19009
19117
|
emitListenerBlock(ls, indent, elVar, ev.childSlotId, "__e", ev.eventName, handler, "dom", bodyIsMultiRoot);
|
|
19010
19118
|
}
|
|
19011
19119
|
function buildCompSelector(comp) {
|
|
@@ -19017,15 +19125,15 @@ function isTextOnlyConditional(node) {
|
|
|
19017
19125
|
const checkNode = (n) => n.type === "text" || n.type === "expression" || n.type === "conditional" && isTextOnlyConditional(n);
|
|
19018
19126
|
return checkNode(node.whenTrue) && checkNode(node.whenFalse);
|
|
19019
19127
|
}
|
|
19020
|
-
function emitComponentAndEventSetup(ls, indent, elVar, comps, events, loopParam, loopParamBindings, bodyIsMultiRoot = false) {
|
|
19021
|
-
const wrap = loopParam ? (expr) => wrapLoopParamAsAccessor(expr, loopParam, loopParamBindings) : (expr) => expr;
|
|
19128
|
+
function emitComponentAndEventSetup(ls, indent, elVar, comps, events, loopParam, loopParamBindings, bodyIsMultiRoot = false, loopIndex) {
|
|
19129
|
+
const wrap = loopParam ? (expr) => wrapLoopParamAsAccessor(expr, loopParam, loopParamBindings, loopIndex) : (expr) => expr;
|
|
19022
19130
|
const upsertFn = bodyIsMultiRoot ? "upsertChildItem" : "upsertChild";
|
|
19023
19131
|
for (const comp of comps) {
|
|
19024
|
-
const propsExpr = buildComponentPropsExpr2(comp, loopParam, loopParamBindings);
|
|
19132
|
+
const propsExpr = buildComponentPropsExpr2(comp, loopParam, loopParamBindings, loopIndex);
|
|
19025
19133
|
const isTextOnly = comp.children?.length ? comp.children.every((c) => c.type === "expression" || c.type === "text" || isTextOnlyConditional(c)) : false;
|
|
19026
19134
|
const rawChildrenExpr = isTextOnly ? irChildrenToJsExpr(comp.children) : null;
|
|
19027
19135
|
const childrenFreeIds = isTextOnly && comp.children ? irChildrenFreeIds(comp.children) : undefined;
|
|
19028
|
-
const childrenRefsLoop = loopParam != null && rawChildrenExpr != null && childrenFreeIds != null && exprRefsLoopBinding(childrenFreeIds, { param: loopParam, paramBindings: loopParamBindings });
|
|
19136
|
+
const childrenRefsLoop = loopParam != null && rawChildrenExpr != null && childrenFreeIds != null && (exprRefsLoopBinding(childrenFreeIds, { param: loopParam, paramBindings: loopParamBindings }) || !!loopIndex && childrenFreeIds.has(loopIndex));
|
|
19029
19137
|
const slotIdLit = comp.slotId ? `'${comp.slotId}'` : "null";
|
|
19030
19138
|
const keyProp = comp.props.find((p) => p.name === "key");
|
|
19031
19139
|
const keyArg = keyProp ? `, ${wrap(attrValueToString(keyProp.value) ?? "undefined")}` : ", undefined";
|
|
@@ -19038,7 +19146,7 @@ function emitComponentAndEventSetup(ls, indent, elVar, comps, events, loopParam,
|
|
|
19038
19146
|
}
|
|
19039
19147
|
}
|
|
19040
19148
|
for (const ev of events) {
|
|
19041
|
-
emitEventSetup(ls, indent, elVar, ev, loopParam, loopParamBindings, bodyIsMultiRoot);
|
|
19149
|
+
emitEventSetup(ls, indent, elVar, ev, loopParam, loopParamBindings, bodyIsMultiRoot, loopIndex);
|
|
19042
19150
|
}
|
|
19043
19151
|
}
|
|
19044
19152
|
|
|
@@ -19419,12 +19527,12 @@ function buildBranchInnerLoopsPlan(args) {
|
|
|
19419
19527
|
const inner = innerLoops[i];
|
|
19420
19528
|
if (!inner.refsOuterParam || !inner.template)
|
|
19421
19529
|
continue;
|
|
19422
|
-
const wrapInner = (expr) => wrapLoopParamAsAccessor(expr, inner.param, inner.paramBindings);
|
|
19423
|
-
const wrapBoth = (expr) => wrapLoopParamAsAccessor(wrapOuter(expr), inner.param, inner.paramBindings);
|
|
19530
|
+
const wrapInner = (expr) => wrapLoopParamAsAccessor(expr, inner.param, inner.paramBindings, inner.index);
|
|
19531
|
+
const wrapBoth = (expr) => wrapLoopParamAsAccessor(wrapOuter(expr), inner.param, inner.paramBindings, inner.index);
|
|
19424
19532
|
const csl = inner.containerSlotId;
|
|
19425
19533
|
const containerExpr = csl ? `(${scopeVar}.querySelector('[bf="${csl}"]') ?? ${scopeVar}.querySelector(\`[${BF_HOST2}="\${__scopeId}"][${BF_AT2}="${csl}"]\`) ?? ${scopeVar})` : `findCondContainer(${scopeVar}, '${condSlotId}')`;
|
|
19426
19534
|
const { head: paramHead, unwrap: paramUnwrap } = destructureLoopParam(inner.param, inner.paramBindings);
|
|
19427
|
-
const wrappedKey = inner.key ? wrapLoopParamAsAccessor(inner.key, inner.param, inner.paramBindings) : null;
|
|
19535
|
+
const wrappedKey = inner.key ? wrapLoopParamAsAccessor(inner.key, inner.param, inner.paramBindings, inner.index) : null;
|
|
19428
19536
|
const wrapIRNode = (node) => {
|
|
19429
19537
|
if (node.type === "component") {
|
|
19430
19538
|
return {
|
|
@@ -19586,8 +19694,8 @@ function buildLoopChildArmPlan(args) {
|
|
|
19586
19694
|
|
|
19587
19695
|
// src/ir-to-client-js/control-flow/plan/build-reactive-effects.ts
|
|
19588
19696
|
function buildReactiveEffectsPlan(args) {
|
|
19589
|
-
const { attrs, texts, conditionals, loopParam, loopParamBindings, profileComponentName } = args;
|
|
19590
|
-
const wrap = (expr) => wrapLoopParamAsAccessor(expr, loopParam, loopParamBindings);
|
|
19697
|
+
const { attrs, texts, conditionals, loopParam, loopParamBindings, loopIndex, profileComponentName } = args;
|
|
19698
|
+
const wrap = (expr) => wrapLoopParamAsAccessor(expr, loopParam, loopParamBindings, loopIndex);
|
|
19591
19699
|
const attrsBySlot = new Map;
|
|
19592
19700
|
for (const attr of attrs) {
|
|
19593
19701
|
let bucket = attrsBySlot.get(attr.childSlotId);
|
|
@@ -19671,6 +19779,7 @@ function buildLoopReactiveEffectsPlan(elem, profileComponentName) {
|
|
|
19671
19779
|
conditionals: elem.bindings.conditionals,
|
|
19672
19780
|
loopParam: elem.param,
|
|
19673
19781
|
loopParamBindings: elem.paramBindings,
|
|
19782
|
+
loopIndex: elem.index,
|
|
19674
19783
|
profileComponentName
|
|
19675
19784
|
});
|
|
19676
19785
|
}
|
|
@@ -19749,10 +19858,10 @@ function buildInnerLoopsPlan(args) {
|
|
|
19749
19858
|
return plan;
|
|
19750
19859
|
}
|
|
19751
19860
|
function buildReactiveEmit(inner, level, wrapOuter, uidSuffix, outerLoopParam, outerLoopParamBindings) {
|
|
19752
|
-
const wrapInner = (expr) => wrapLoopParamAsAccessor(expr, inner.param, inner.paramBindings);
|
|
19753
|
-
const wrapBoth = (expr) => wrapLoopParamAsAccessor(wrapOuter(expr), inner.param, inner.paramBindings);
|
|
19861
|
+
const wrapInner = (expr) => wrapLoopParamAsAccessor(expr, inner.param, inner.paramBindings, inner.index);
|
|
19862
|
+
const wrapBoth = (expr) => wrapLoopParamAsAccessor(wrapOuter(expr), inner.param, inner.paramBindings, inner.index);
|
|
19754
19863
|
const { head: paramHead, unwrap: paramUnwrap } = destructureLoopParam(inner.param, inner.paramBindings);
|
|
19755
|
-
const wrappedKey = inner.key ? wrapLoopParamAsAccessor(inner.key, inner.param, inner.paramBindings) : null;
|
|
19864
|
+
const wrappedKey = inner.key ? wrapLoopParamAsAccessor(inner.key, inner.param, inner.paramBindings, inner.index) : null;
|
|
19756
19865
|
const wrapIRNode = (node) => {
|
|
19757
19866
|
if (node.type === "component") {
|
|
19758
19867
|
return {
|
|
@@ -19783,11 +19892,11 @@ function buildReactiveEmit(inner, level, wrapOuter, uidSuffix, outerLoopParam, o
|
|
|
19783
19892
|
}));
|
|
19784
19893
|
const reactiveTexts = inner.bindings.reactiveTexts.map((text) => ({
|
|
19785
19894
|
slotId: text.slotId,
|
|
19786
|
-
wrappedExpression: wrapLoopParamAsAccessor(wrapOuter(text.expression), inner.param, inner.paramBindings),
|
|
19895
|
+
wrappedExpression: wrapLoopParamAsAccessor(wrapOuter(text.expression), inner.param, inner.paramBindings, inner.index),
|
|
19787
19896
|
insideConditional: !!text.insideConditional
|
|
19788
19897
|
}));
|
|
19789
19898
|
const reactiveAttrs = inner.bindings.reactiveAttrs.map((attr) => {
|
|
19790
|
-
const wrapped = wrapLoopParamAsAccessor(wrapOuter(attr.expression), inner.param, inner.paramBindings);
|
|
19899
|
+
const wrapped = wrapLoopParamAsAccessor(wrapOuter(attr.expression), inner.param, inner.paramBindings, inner.index);
|
|
19791
19900
|
return {
|
|
19792
19901
|
slotId: attr.childSlotId,
|
|
19793
19902
|
attrName: attr.attrName,
|
|
@@ -19804,14 +19913,14 @@ function buildReactiveEmit(inner, level, wrapOuter, uidSuffix, outerLoopParam, o
|
|
|
19804
19913
|
if (inner.preamble) {
|
|
19805
19914
|
const leafLoopParams = outerLoopParam ? [
|
|
19806
19915
|
{ param: outerLoopParam, bindings: outerLoopParamBindings },
|
|
19807
|
-
{ param: inner.param, bindings: inner.paramBindings }
|
|
19808
|
-
] : [{ param: inner.param, bindings: inner.paramBindings }];
|
|
19916
|
+
{ param: inner.param, bindings: inner.paramBindings, index: inner.index }
|
|
19917
|
+
] : [{ param: inner.param, bindings: inner.paramBindings, index: inner.index }];
|
|
19809
19918
|
preludeStatements.push(renderPreamble(inner.preamble, {
|
|
19810
19919
|
transformJs: (t) => wrapInner(wrapOuter(t)),
|
|
19811
19920
|
renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, leafLoopParams, undefined)
|
|
19812
19921
|
}));
|
|
19813
19922
|
}
|
|
19814
|
-
const childRefs = buildChildRefBindings(inner.bindings.refs, inner.param, inner.paramBindings);
|
|
19923
|
+
const childRefs = buildChildRefBindings(inner.bindings.refs, inner.param, inner.paramBindings, inner.index);
|
|
19815
19924
|
const conditionals = buildLoopChildConditionalsPlan({
|
|
19816
19925
|
conditionals: inner.bindings.conditionals,
|
|
19817
19926
|
scopeVar: `__innerEl${uidSuffix}`,
|
|
@@ -19860,7 +19969,7 @@ function buildTopLevelCompositePlan(elem, profileComponentName) {
|
|
|
19860
19969
|
const nestedComps = elem.nestedComponents;
|
|
19861
19970
|
const depthLevels = buildDepthLevels(elem.innerLoops ?? [], nestedComps, elem.bindings.events);
|
|
19862
19971
|
const { head: paramHead, unwrap: paramUnwrap } = destructureLoopParam(elem.param, elem.paramBindings);
|
|
19863
|
-
const wrap = (expr) => wrapLoopParamAsAccessor(expr, elem.param, elem.paramBindings);
|
|
19972
|
+
const wrap = (expr) => wrapLoopParamAsAccessor(expr, elem.param, elem.paramBindings, elem.index);
|
|
19864
19973
|
const outerCompsByDepth = nestedComps.filter((c) => !c.loopDepth || c.loopDepth === 0);
|
|
19865
19974
|
return {
|
|
19866
19975
|
kind: "composite",
|
|
@@ -19874,12 +19983,12 @@ function buildTopLevelCompositePlan(elem, profileComponentName) {
|
|
|
19874
19983
|
indexParam: elem.index || "__idx",
|
|
19875
19984
|
mapPreambleWrapped: elem.preamble ? renderPreamble(elem.preamble, {
|
|
19876
19985
|
transformJs: wrap,
|
|
19877
|
-
renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, [{ param: elem.param, bindings: elem.paramBindings }], undefined)
|
|
19986
|
+
renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, [{ param: elem.param, bindings: elem.paramBindings, index: elem.index }], undefined)
|
|
19878
19987
|
}) : "",
|
|
19879
19988
|
template: elem.template,
|
|
19880
19989
|
outerComps: filterCondCompsOut(outerCompsByDepth, elem.bindings.conditionals),
|
|
19881
19990
|
outerEvents: elem.bindings.events.filter((ev) => ev.nestedLoops.length === 0),
|
|
19882
|
-
childRefs: buildChildRefBindings(elem.bindings.refs, elem.param, elem.paramBindings),
|
|
19991
|
+
childRefs: buildChildRefBindings(elem.bindings.refs, elem.param, elem.paramBindings, elem.index),
|
|
19883
19992
|
innerLoops: buildInnerLoopsPlan({
|
|
19884
19993
|
levels: depthLevels,
|
|
19885
19994
|
parentElVar: "__el",
|
|
@@ -19888,12 +19997,14 @@ function buildTopLevelCompositePlan(elem, profileComponentName) {
|
|
|
19888
19997
|
}),
|
|
19889
19998
|
loopParam: elem.param,
|
|
19890
19999
|
loopParamBindings: elem.paramBindings,
|
|
20000
|
+
loopIndex: elem.index,
|
|
19891
20001
|
reactiveEffects: hasReactive(elem) ? buildReactiveEffectsPlan({
|
|
19892
20002
|
attrs: elem.bindings.reactiveAttrs,
|
|
19893
20003
|
texts: elem.bindings.reactiveTexts,
|
|
19894
20004
|
conditionals: elem.bindings.conditionals,
|
|
19895
20005
|
loopParam: elem.param,
|
|
19896
20006
|
loopParamBindings: elem.paramBindings,
|
|
20007
|
+
loopIndex: elem.index,
|
|
19897
20008
|
profileComponentName
|
|
19898
20009
|
}) : null,
|
|
19899
20010
|
branchClearChildren: false,
|
|
@@ -19910,7 +20021,7 @@ function buildBranchCompositePlan(loop, cv, profileComponentName) {
|
|
|
19910
20021
|
const childEvents = loop.bindings.events;
|
|
19911
20022
|
const depthLevels = buildDepthLevels(innerLoops, nestedComps, childEvents);
|
|
19912
20023
|
const { head: paramHead, unwrap: paramUnwrap } = destructureLoopParam(loop.param, loop.paramBindings);
|
|
19913
|
-
const wrap = (expr) => wrapLoopParamAsAccessor(expr, loop.param, loop.paramBindings);
|
|
20024
|
+
const wrap = (expr) => wrapLoopParamAsAccessor(expr, loop.param, loop.paramBindings, loop.index);
|
|
19914
20025
|
const outerCompsByDepth = nestedComps.filter((c) => !c.loopDepth || c.loopDepth === 0);
|
|
19915
20026
|
return {
|
|
19916
20027
|
kind: "composite",
|
|
@@ -19924,12 +20035,12 @@ function buildBranchCompositePlan(loop, cv, profileComponentName) {
|
|
|
19924
20035
|
indexParam: loop.index || "__idx",
|
|
19925
20036
|
mapPreambleWrapped: loop.preamble ? renderPreamble(loop.preamble, {
|
|
19926
20037
|
transformJs: wrap,
|
|
19927
|
-
renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, [{ param: loop.param, bindings: loop.paramBindings }], undefined)
|
|
20038
|
+
renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, [{ param: loop.param, bindings: loop.paramBindings, index: loop.index }], undefined)
|
|
19928
20039
|
}) : "",
|
|
19929
20040
|
template: loop.template,
|
|
19930
20041
|
outerComps: filterCondCompsOut(outerCompsByDepth, loop.bindings.conditionals),
|
|
19931
20042
|
outerEvents: childEvents.filter((ev) => ev.nestedLoops.length === 0),
|
|
19932
|
-
childRefs: buildChildRefBindings(loop.bindings.refs, loop.param, loop.paramBindings),
|
|
20043
|
+
childRefs: buildChildRefBindings(loop.bindings.refs, loop.param, loop.paramBindings, loop.index),
|
|
19933
20044
|
innerLoops: buildInnerLoopsPlan({
|
|
19934
20045
|
levels: depthLevels,
|
|
19935
20046
|
parentElVar: "__el",
|
|
@@ -19938,12 +20049,14 @@ function buildBranchCompositePlan(loop, cv, profileComponentName) {
|
|
|
19938
20049
|
}),
|
|
19939
20050
|
loopParam: loop.param,
|
|
19940
20051
|
loopParamBindings: loop.paramBindings,
|
|
20052
|
+
loopIndex: loop.index,
|
|
19941
20053
|
reactiveEffects: hasReactiveBranch(loop) ? buildReactiveEffectsPlan({
|
|
19942
20054
|
attrs: loop.bindings.reactiveAttrs,
|
|
19943
20055
|
texts: loop.bindings.reactiveTexts,
|
|
19944
20056
|
conditionals: loop.bindings.conditionals,
|
|
19945
20057
|
loopParam: loop.param,
|
|
19946
20058
|
loopParamBindings: loop.paramBindings,
|
|
20059
|
+
loopIndex: loop.index,
|
|
19947
20060
|
profileComponentName
|
|
19948
20061
|
}) : null,
|
|
19949
20062
|
branchClearChildren: true,
|
|
@@ -20078,7 +20191,7 @@ function wiringOn(branch) {
|
|
|
20078
20191
|
found.push("reactive text");
|
|
20079
20192
|
return found;
|
|
20080
20193
|
}
|
|
20081
|
-
function analyzeLazyConditional(cond,
|
|
20194
|
+
function analyzeLazyConditional(cond, arms) {
|
|
20082
20195
|
for (const [label, branch] of [["true", cond.whenTrue], ["false", cond.whenFalse]]) {
|
|
20083
20196
|
const wiring = wiringOn(branch);
|
|
20084
20197
|
if (wiring.length > 0) {
|
|
@@ -20099,9 +20212,6 @@ function analyzeLazyConditional(cond, indexParam, arms) {
|
|
|
20099
20212
|
if (!cond.conditionFreeIdentifiers) {
|
|
20100
20213
|
return NO(`conditional on slot ${cond.slotId}: condition has no analyzable identifier set`);
|
|
20101
20214
|
}
|
|
20102
|
-
if (cond.conditionFreeIdentifiers.has(indexParam)) {
|
|
20103
|
-
return NO(`conditional on slot ${cond.slotId}: condition reads the loop index parameter '${indexParam}'`);
|
|
20104
|
-
}
|
|
20105
20215
|
return {
|
|
20106
20216
|
lazySafe: true,
|
|
20107
20217
|
facts: {
|
|
@@ -20120,7 +20230,7 @@ var NO_PREAMBLE = {
|
|
|
20120
20230
|
facts: { declaredNames: new Set, freeNames: new Set }
|
|
20121
20231
|
};
|
|
20122
20232
|
var NO2 = (reason) => ({ lazySafe: false, reason });
|
|
20123
|
-
function analyzeLazyPreamble(preamble,
|
|
20233
|
+
function analyzeLazyPreamble(preamble, primableNames) {
|
|
20124
20234
|
if (!preamble)
|
|
20125
20235
|
return NO_PREAMBLE;
|
|
20126
20236
|
if (preamble.builderNames.length > 0) {
|
|
@@ -20159,9 +20269,6 @@ function analyzeLazyPreamble(preamble, indexParam, primableNames) {
|
|
|
20159
20269
|
}
|
|
20160
20270
|
}
|
|
20161
20271
|
const readNames = extractFreeIdentifiersFromStatementText(text);
|
|
20162
|
-
if (readNames.has(indexParam) && !declaredNames.has(indexParam)) {
|
|
20163
|
-
return NO2(`map-callback preamble reads the loop index parameter '${indexParam}'`);
|
|
20164
|
-
}
|
|
20165
20272
|
const freeNames = new Set(readNames);
|
|
20166
20273
|
for (const declared of declaredNames)
|
|
20167
20274
|
freeNames.delete(declared);
|
|
@@ -20311,9 +20418,6 @@ function lazyRowEligibility(args) {
|
|
|
20311
20418
|
if (shape.hasParamUnwrap)
|
|
20312
20419
|
return NO3("destructured loop param without param bindings");
|
|
20313
20420
|
for (const b of bindings) {
|
|
20314
|
-
if (b.referencesIndex) {
|
|
20315
|
-
return NO3(`binding on slot ${b.slotId} references the loop index parameter`);
|
|
20316
|
-
}
|
|
20317
20421
|
if (b.opaqueOuterNames.includes(UNKNOWN_IDENTIFIERS)) {
|
|
20318
20422
|
return NO3(`binding on slot ${b.slotId} has no analyzable identifier set`);
|
|
20319
20423
|
}
|
|
@@ -20398,6 +20502,7 @@ function classifyLazyBinding(args) {
|
|
|
20398
20502
|
}
|
|
20399
20503
|
if (name === indexParam) {
|
|
20400
20504
|
referencesIndex = true;
|
|
20505
|
+
readsItem = true;
|
|
20401
20506
|
return;
|
|
20402
20507
|
}
|
|
20403
20508
|
if (INERT_BINDING_GLOBALS.has(name))
|
|
@@ -20447,12 +20552,12 @@ function decideLazyRow(args) {
|
|
|
20447
20552
|
for (const b of loop.paramBindings ?? [])
|
|
20448
20553
|
rowLocalNames.add(b.name);
|
|
20449
20554
|
const primableNames = new Set([...scope.signals.keys(), ...scope.memos]);
|
|
20450
|
-
const preambleAnalysis = analyzeLazyPreamble(loop.preamble,
|
|
20555
|
+
const preambleAnalysis = analyzeLazyPreamble(loop.preamble, primableNames);
|
|
20451
20556
|
const rawConditionals = loop.bindings.conditionals ?? [];
|
|
20452
20557
|
const condFacts = [];
|
|
20453
20558
|
let conditionalRefusal = null;
|
|
20454
20559
|
for (const cond of rawConditionals) {
|
|
20455
|
-
const verdict = analyzeLazyConditional(cond,
|
|
20560
|
+
const verdict = analyzeLazyConditional(cond, {
|
|
20456
20561
|
whenTrueHtml: addCondAttrToTemplate(wrap(cond.whenTrueHtml), cond.slotId),
|
|
20457
20562
|
whenFalseHtml: addCondAttrToTemplate(wrap(cond.whenFalseHtml), cond.slotId)
|
|
20458
20563
|
});
|
|
@@ -20594,7 +20699,8 @@ function decideLazyRow(args) {
|
|
|
20594
20699
|
preambleStatements: args.mapPreambleWrapped,
|
|
20595
20700
|
itemNeedsPreamble: [...attrs, ...texts, ...conditionals].some((b) => b.readsItem && b.readsPreamble),
|
|
20596
20701
|
outerNeedsPreamble: [...attrs, ...texts, ...conditionals].some((b) => b.readsOuter && b.readsPreamble),
|
|
20597
|
-
conditionals
|
|
20702
|
+
conditionals,
|
|
20703
|
+
readsIndex: classified.some((c) => c.referencesIndex)
|
|
20598
20704
|
},
|
|
20599
20705
|
decision
|
|
20600
20706
|
};
|
|
@@ -20645,6 +20751,43 @@ function loopSourceIdentifiers(loop, arrayExpr) {
|
|
|
20645
20751
|
return names;
|
|
20646
20752
|
}
|
|
20647
20753
|
|
|
20754
|
+
// src/ir-to-client-js/control-flow/plan/build-plain-row.ts
|
|
20755
|
+
function buildPlainRowCore(inputs) {
|
|
20756
|
+
const { loop, arrayExpr, callSite, flatMapLeafItem, anchored, scope } = inputs;
|
|
20757
|
+
const wrapItem = (expr) => wrapLoopParamAsAccessor(expr, loop.param, loop.paramBindings);
|
|
20758
|
+
const { head: paramHead, unwrap: paramUnwrap } = destructureLoopParam(loop.param, loop.paramBindings);
|
|
20759
|
+
const indexParam = loop.index || "__idx";
|
|
20760
|
+
const mapPreambleWrapped = loop.preamble ? renderPreamble(loop.preamble, {
|
|
20761
|
+
transformJs: wrapItem,
|
|
20762
|
+
renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, [{ param: loop.param, bindings: loop.paramBindings }], undefined)
|
|
20763
|
+
}) : "";
|
|
20764
|
+
const preambleRegions = buildPreambleRegionPlans(loop.preambleRegions, loop.param, loop.paramBindings, loop.index);
|
|
20765
|
+
const lazyRow = buildLazyRowPlan({
|
|
20766
|
+
loop,
|
|
20767
|
+
arrayExpr,
|
|
20768
|
+
indexParam,
|
|
20769
|
+
paramUnwrap,
|
|
20770
|
+
mapPreambleWrapped,
|
|
20771
|
+
preambleRegionCount: preambleRegions.length,
|
|
20772
|
+
callSite,
|
|
20773
|
+
flatMapLeafItem,
|
|
20774
|
+
anchored,
|
|
20775
|
+
scope
|
|
20776
|
+
}) ?? undefined;
|
|
20777
|
+
const mapPreambleWrappedFinal = !lazyRow && loop.index ? wrapIndexParamAsAccessor(mapPreambleWrapped, loop.index) : mapPreambleWrapped;
|
|
20778
|
+
const templateFinal = !lazyRow && loop.index ? wrapIndexParamAsAccessor(loop.template, loop.index) : loop.template;
|
|
20779
|
+
return {
|
|
20780
|
+
indexParam,
|
|
20781
|
+
paramHead,
|
|
20782
|
+
paramUnwrap,
|
|
20783
|
+
preambleRegions,
|
|
20784
|
+
lazyRow,
|
|
20785
|
+
mapPreambleWrapped: mapPreambleWrappedFinal,
|
|
20786
|
+
template: templateFinal,
|
|
20787
|
+
wrapItem
|
|
20788
|
+
};
|
|
20789
|
+
}
|
|
20790
|
+
|
|
20648
20791
|
// src/ir-to-client-js/control-flow/plan/build-branch-loop.ts
|
|
20649
20792
|
function buildBranchLoopPlan(loop, profileComponentName, lazyScope) {
|
|
20650
20793
|
const containerSlotId = loop.containerSlotId;
|
|
@@ -20659,16 +20802,18 @@ function buildBranchLoopPlan(loop, profileComponentName, lazyScope) {
|
|
|
20659
20802
|
};
|
|
20660
20803
|
return composite;
|
|
20661
20804
|
}
|
|
20662
|
-
const { head: paramHead, unwrap: paramUnwrap } = destructureLoopParam(loop.param, loop.paramBindings);
|
|
20663
20805
|
const hasReactiveEffects = loop.bindings.reactiveAttrs.length > 0 || loop.bindings.reactiveTexts.length > 0 || loop.bindings.conditionals.length > 0;
|
|
20664
20806
|
const fm = loop.flatMapClient;
|
|
20665
20807
|
const arrayExpr = fm ? `(${buildChainedArrayExpr(loop)}).flatMap(${fm.params} => ${fm.body})` : buildChainedArrayExpr(loop);
|
|
20666
|
-
const
|
|
20667
|
-
|
|
20668
|
-
|
|
20669
|
-
|
|
20670
|
-
|
|
20671
|
-
|
|
20808
|
+
const core = buildPlainRowCore({
|
|
20809
|
+
loop,
|
|
20810
|
+
arrayExpr,
|
|
20811
|
+
callSite: "branch-plain",
|
|
20812
|
+
flatMapLeafItem: Boolean(fm),
|
|
20813
|
+
anchored: false,
|
|
20814
|
+
scope: lazyScope
|
|
20815
|
+
});
|
|
20816
|
+
const { paramHead, paramUnwrap, indexParam, preambleRegions, lazyRow } = core;
|
|
20672
20817
|
const plan = {
|
|
20673
20818
|
kind: "plain",
|
|
20674
20819
|
rowConstruction: "string-template",
|
|
@@ -20681,30 +20826,20 @@ function buildBranchLoopPlan(loop, profileComponentName, lazyScope) {
|
|
|
20681
20826
|
paramHead,
|
|
20682
20827
|
paramUnwrap,
|
|
20683
20828
|
indexParam,
|
|
20684
|
-
mapPreambleWrapped,
|
|
20685
|
-
lazyRow
|
|
20686
|
-
|
|
20687
|
-
arrayExpr,
|
|
20688
|
-
indexParam,
|
|
20689
|
-
paramUnwrap,
|
|
20690
|
-
mapPreambleWrapped,
|
|
20691
|
-
preambleRegionCount: preambleRegions.length,
|
|
20692
|
-
callSite: "branch-plain",
|
|
20693
|
-
flatMapLeafItem: Boolean(fm),
|
|
20694
|
-
anchored: false,
|
|
20695
|
-
scope: lazyScope
|
|
20696
|
-
}) ?? undefined,
|
|
20697
|
-
template: loop.template,
|
|
20829
|
+
mapPreambleWrapped: core.mapPreambleWrapped,
|
|
20830
|
+
lazyRow,
|
|
20831
|
+
template: core.template,
|
|
20698
20832
|
reactiveEffects: hasReactiveEffects ? buildReactiveEffectsPlan({
|
|
20699
20833
|
attrs: loop.bindings.reactiveAttrs,
|
|
20700
20834
|
texts: loop.bindings.reactiveTexts,
|
|
20701
20835
|
conditionals: loop.bindings.conditionals,
|
|
20702
20836
|
loopParam: loop.param,
|
|
20703
20837
|
loopParamBindings: loop.paramBindings,
|
|
20838
|
+
loopIndex: loop.index,
|
|
20704
20839
|
profileComponentName
|
|
20705
20840
|
}) : null,
|
|
20706
20841
|
eventDelegation: buildBranchLoopDelegationPlan(loop, cv, profileComponentName),
|
|
20707
|
-
childRefs: buildChildRefBindings(loop.bindings.refs, loop.param, loop.paramBindings),
|
|
20842
|
+
childRefs: buildChildRefBindings(loop.bindings.refs, loop.param, loop.paramBindings, loop.index),
|
|
20708
20843
|
preambleRegions,
|
|
20709
20844
|
bodyIsMultiRoot: loop.bodyIsMultiRoot ?? false,
|
|
20710
20845
|
profileLoopId: profileComponentName ? `${profileComponentName}#binding:${containerSlotId}` : undefined
|
|
@@ -20989,7 +21124,7 @@ function emitDynamicTextUpdates(lines, ctx) {
|
|
|
20989
21124
|
const __textSlot = (normalElems[0] ?? conditionalElems[0])?.slotId;
|
|
20990
21125
|
let writer = "";
|
|
20991
21126
|
if (normalElems.length > 0) {
|
|
20992
|
-
const slots = normalElems.map((elem) => ({ id: elem.slotId, kind:
|
|
21127
|
+
const slots = normalElems.map((elem) => ({ id: elem.slotId, kind: DYNAMIC_ELEMENT_WRITER_KIND, path: [] }));
|
|
20993
21128
|
writer = claimWriterVarName(slots, varSlotId);
|
|
20994
21129
|
lines.push(` const ${writer} = lazySlots(__scope, ${claimPlanLiteral(slots)})`);
|
|
20995
21130
|
}
|
|
@@ -21527,6 +21662,8 @@ function stringifyLazyRowLoop(lines, o) {
|
|
|
21527
21662
|
lines.push(`${indent}${o.guardContainer ? `if (${o.containerVar}) ` : ""}${call}`);
|
|
21528
21663
|
const b1 = `${indent} `;
|
|
21529
21664
|
const b2 = `${indent} `;
|
|
21665
|
+
if (lazyRow.readsIndex)
|
|
21666
|
+
lines.push(`${b1}indexDriven: true,`);
|
|
21530
21667
|
lines.push(`${b1}createRow: (__e, ${o.indexParam}) => {`);
|
|
21531
21668
|
lines.push(`${b2}const ${paramHead} = () => __e.item`);
|
|
21532
21669
|
if (lazyRow.preambleStatements)
|
|
@@ -21556,6 +21693,8 @@ function stringifyLazyRowLoop(lines, o) {
|
|
|
21556
21693
|
} else {
|
|
21557
21694
|
lines.push(`${b1}applyItem: (__e) => {`);
|
|
21558
21695
|
lines.push(`${b2}const ${paramHead} = () => __e.item`);
|
|
21696
|
+
if (lazyRow.readsIndex)
|
|
21697
|
+
lines.push(`${b2}const ${o.indexParam} = __e.index`);
|
|
21559
21698
|
lines.push(`${b2}const __r = __e.refs ?? (__e.refs = [])`);
|
|
21560
21699
|
lines.push(`${b2}const __l = __e.last ?? (__e.last = [])`);
|
|
21561
21700
|
if (lazyRow.itemNeedsPreamble && lazyRow.preambleStatements) {
|
|
@@ -21582,6 +21721,8 @@ function stringifyLazyRowLoop(lines, o) {
|
|
|
21582
21721
|
lines.push(`${b2}${g}()`);
|
|
21583
21722
|
lines.push(`${b2}for (const __e of __es) {`);
|
|
21584
21723
|
lines.push(`${b3}const ${paramHead} = () => __e.item`);
|
|
21724
|
+
if (lazyRow.readsIndex)
|
|
21725
|
+
lines.push(`${b3}const ${o.indexParam} = __e.index`);
|
|
21585
21726
|
lines.push(`${b3}const __r = __e.refs ?? (__e.refs = [])`);
|
|
21586
21727
|
lines.push(`${b3}const __l = __e.last ?? (__e.last = [])`);
|
|
21587
21728
|
if (lazyRow.outerNeedsPreamble && lazyRow.preambleStatements) {
|
|
@@ -22106,6 +22247,7 @@ function stringifyCompositeLoop(lines, plan) {
|
|
|
22106
22247
|
innerLoops,
|
|
22107
22248
|
loopParam,
|
|
22108
22249
|
loopParamBindings,
|
|
22250
|
+
loopIndex,
|
|
22109
22251
|
reactiveEffects,
|
|
22110
22252
|
childRefs,
|
|
22111
22253
|
branchClearChildren,
|
|
@@ -22138,7 +22280,7 @@ function stringifyCompositeLoop(lines, plan) {
|
|
|
22138
22280
|
singleRootLayout: "multiline",
|
|
22139
22281
|
mountRow: true
|
|
22140
22282
|
});
|
|
22141
|
-
emitComponentAndEventSetup(lines, bodyIndent, "__el", compsArr, eventsArr, loopParam, loopParamBindings, bodyIsMultiRoot);
|
|
22283
|
+
emitComponentAndEventSetup(lines, bodyIndent, "__el", compsArr, eventsArr, loopParam, loopParamBindings, bodyIsMultiRoot, loopIndex);
|
|
22142
22284
|
if (innerLoops.length > 0) {
|
|
22143
22285
|
stringifyInnerLoops(lines, innerLoops, bodyIndent, pc);
|
|
22144
22286
|
}
|
|
@@ -22560,11 +22702,11 @@ function scopeRefToVar(ref) {
|
|
|
22560
22702
|
// src/ir-to-client-js/control-flow/plan/build-component-loop.ts
|
|
22561
22703
|
function buildComponentLoopPlan(elem, profileComponentName) {
|
|
22562
22704
|
const { name } = elem.childComponent;
|
|
22563
|
-
const propsExpr = buildComponentPropsExpr2(elem.childComponent, elem.param);
|
|
22564
|
-
const keyExpr = wrapLoopParamAsAccessor(elem.key || "__idx", elem.param, elem.paramBindings);
|
|
22705
|
+
const propsExpr = buildComponentPropsExpr2(elem.childComponent, elem.param, undefined, elem.index);
|
|
22706
|
+
const keyExpr = wrapLoopParamAsAccessor(elem.key || "__idx", elem.param, elem.paramBindings, elem.index);
|
|
22565
22707
|
const { head: paramHead, unwrap: paramUnwrap } = destructureLoopParam(elem.param, elem.paramBindings);
|
|
22566
22708
|
const mapPreambleWrapped = elem.preamble ? renderPreamble(elem.preamble, {
|
|
22567
|
-
transformJs: (text) => wrapLoopParamAsAccessor(text, elem.param, elem.paramBindings),
|
|
22709
|
+
transformJs: (text) => wrapLoopParamAsAccessor(text, elem.param, elem.paramBindings, elem.index),
|
|
22568
22710
|
renderLeaf: () => {
|
|
22569
22711
|
internalInvariant(false, "component-root loop received a JSX-bearing preamble — Phase 1 should have refused it");
|
|
22570
22712
|
}
|
|
@@ -22574,12 +22716,12 @@ function buildComponentLoopPlan(elem, profileComponentName) {
|
|
|
22574
22716
|
const isTextOnly = comp.children?.length ? comp.children.every((c) => c.type === "expression" || c.type === "text" || isTextOnlyConditional(c)) : false;
|
|
22575
22717
|
const rawChildrenExpr = isTextOnly ? irChildrenToJsExpr(comp.children) : null;
|
|
22576
22718
|
const childrenFreeIds = isTextOnly && comp.children ? irChildrenFreeIds(comp.children) : undefined;
|
|
22577
|
-
const childrenRefsLoop = rawChildrenExpr != null && childrenFreeIds != null && childrenFreeIds.has(elem.param);
|
|
22719
|
+
const childrenRefsLoop = rawChildrenExpr != null && childrenFreeIds != null && (childrenFreeIds.has(elem.param) || !!elem.index && childrenFreeIds.has(elem.index));
|
|
22578
22720
|
return {
|
|
22579
22721
|
componentName: comp.name,
|
|
22580
22722
|
selector: buildCompSelector(comp),
|
|
22581
|
-
propsExpr: buildComponentPropsExpr2(comp, elem.param),
|
|
22582
|
-
childrenTextEffect: childrenRefsLoop ? { wrappedChildren: wrapLoopParamAsAccessor(rawChildrenExpr, elem.param, elem.paramBindings) } : null
|
|
22723
|
+
propsExpr: buildComponentPropsExpr2(comp, elem.param, undefined, elem.index),
|
|
22724
|
+
childrenTextEffect: childrenRefsLoop ? { wrappedChildren: wrapLoopParamAsAccessor(rawChildrenExpr, elem.param, elem.paramBindings, elem.index) } : null
|
|
22583
22725
|
};
|
|
22584
22726
|
});
|
|
22585
22727
|
const hasChildConds = elem.bindings.conditionals.length > 0;
|
|
@@ -22598,7 +22740,7 @@ function buildComponentLoopPlan(elem, profileComponentName) {
|
|
|
22598
22740
|
componentPropsExpr: propsExpr,
|
|
22599
22741
|
keyExpr,
|
|
22600
22742
|
nestedComps,
|
|
22601
|
-
childRefs: buildChildRefBindings(elem.bindings.refs, elem.param, elem.paramBindings),
|
|
22743
|
+
childRefs: buildChildRefBindings(elem.bindings.refs, elem.param, elem.paramBindings, elem.index),
|
|
22602
22744
|
profileLoopId: profileComponentName ? `${profileComponentName}#binding:${elem.slotId}` : undefined,
|
|
22603
22745
|
childConditionalEffects: hasChildConds ? buildReactiveEffectsPlan({
|
|
22604
22746
|
attrs: [],
|
|
@@ -22606,6 +22748,7 @@ function buildComponentLoopPlan(elem, profileComponentName) {
|
|
|
22606
22748
|
conditionals: elem.bindings.conditionals,
|
|
22607
22749
|
loopParam: elem.param,
|
|
22608
22750
|
loopParamBindings: elem.paramBindings,
|
|
22751
|
+
loopIndex: elem.index,
|
|
22609
22752
|
profileComponentName
|
|
22610
22753
|
}) : null
|
|
22611
22754
|
};
|
|
@@ -22629,8 +22772,6 @@ function buildLoopPlan(elem, opts) {
|
|
|
22629
22772
|
return buildPlainLoopPlan(elem, opts.profileComponentName, opts.lazyScope);
|
|
22630
22773
|
}
|
|
22631
22774
|
function buildPlainLoopPlan(elem, profileComponentName, lazyScope) {
|
|
22632
|
-
const wrap = (expr) => wrapLoopParamAsAccessor(expr, elem.param, elem.paramBindings);
|
|
22633
|
-
const { head: paramHead, unwrap: paramUnwrap } = destructureLoopParam(elem.param, elem.paramBindings);
|
|
22634
22775
|
const hasReactive2 = elem.bindings.reactiveAttrs.length > 0 || elem.bindings.reactiveTexts.length > 0 || elem.bindings.conditionals.length > 0;
|
|
22635
22776
|
if (elem.flatMapClient) {
|
|
22636
22777
|
return {
|
|
@@ -22656,12 +22797,15 @@ function buildPlainLoopPlan(elem, profileComponentName, lazyScope) {
|
|
|
22656
22797
|
};
|
|
22657
22798
|
}
|
|
22658
22799
|
const arrayExpr = buildChainedArrayExpr(elem);
|
|
22659
|
-
const
|
|
22660
|
-
|
|
22661
|
-
|
|
22662
|
-
|
|
22663
|
-
|
|
22664
|
-
|
|
22800
|
+
const core = buildPlainRowCore({
|
|
22801
|
+
loop: elem,
|
|
22802
|
+
arrayExpr,
|
|
22803
|
+
callSite: "plain",
|
|
22804
|
+
flatMapLeafItem: false,
|
|
22805
|
+
anchored: elem.bodyIsItemConditional ?? false,
|
|
22806
|
+
scope: lazyScope
|
|
22807
|
+
});
|
|
22808
|
+
const { paramHead, paramUnwrap, indexParam, preambleRegions, lazyRow, wrapItem: wrap } = core;
|
|
22665
22809
|
return {
|
|
22666
22810
|
kind: "plain",
|
|
22667
22811
|
rowConstruction: "string-template",
|
|
@@ -22673,28 +22817,17 @@ function buildPlainLoopPlan(elem, profileComponentName, lazyScope) {
|
|
|
22673
22817
|
paramHead,
|
|
22674
22818
|
paramUnwrap,
|
|
22675
22819
|
indexParam,
|
|
22676
|
-
lazyRow
|
|
22677
|
-
|
|
22678
|
-
|
|
22679
|
-
indexParam,
|
|
22680
|
-
paramUnwrap,
|
|
22681
|
-
mapPreambleWrapped,
|
|
22682
|
-
preambleRegionCount: preambleRegions.length,
|
|
22683
|
-
callSite: "plain",
|
|
22684
|
-
flatMapLeafItem: false,
|
|
22685
|
-
anchored: elem.bodyIsItemConditional ?? false,
|
|
22686
|
-
scope: lazyScope
|
|
22687
|
-
}) ?? undefined,
|
|
22688
|
-
mapPreambleWrapped,
|
|
22689
|
-
template: elem.template,
|
|
22820
|
+
lazyRow,
|
|
22821
|
+
mapPreambleWrapped: core.mapPreambleWrapped,
|
|
22822
|
+
template: core.template,
|
|
22690
22823
|
skeletonTemplate: elem.skeletonTemplate,
|
|
22691
22824
|
skeletonPaths: elem.skeletonPaths,
|
|
22692
22825
|
reactiveEffects: hasReactive2 ? buildLoopReactiveEffectsPlan(elem, profileComponentName) : null,
|
|
22693
|
-
childRefs: buildChildRefBindings(elem.bindings.refs, elem.param, elem.paramBindings),
|
|
22826
|
+
childRefs: buildChildRefBindings(elem.bindings.refs, elem.param, elem.paramBindings, elem.index),
|
|
22694
22827
|
preambleRegions,
|
|
22695
22828
|
bodyIsMultiRoot: elem.bodyIsMultiRoot ?? false,
|
|
22696
22829
|
anchored: elem.bodyIsItemConditional ?? false,
|
|
22697
|
-
anchorKeyExpr: elem.key ? wrap(elem.key) :
|
|
22830
|
+
anchorKeyExpr: elem.key ? wrap(elem.key) : `${indexParam}()`
|
|
22698
22831
|
};
|
|
22699
22832
|
}
|
|
22700
22833
|
function buildStaticLoopPlan(elem, unsafeLocalNames, profileComponentName) {
|
|
@@ -22736,7 +22869,7 @@ function buildStaticLoopMaterialize(elem, unsafeLocalNames) {
|
|
|
22736
22869
|
return {
|
|
22737
22870
|
itemTemplate: elem.staticItemTemplate,
|
|
22738
22871
|
mapPreamble: elem.preamble ? renderPreamble(elem.preamble, {
|
|
22739
|
-
renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, [{ param: elem.param, bindings: elem.paramBindings }], undefined)
|
|
22872
|
+
renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, [{ param: elem.param, bindings: elem.paramBindings, index: elem.index }], undefined)
|
|
22740
22873
|
}) : "",
|
|
22741
22874
|
bodyIsMultiRoot: elem.bodyIsMultiRoot ?? false
|
|
22742
22875
|
};
|
|
@@ -23313,7 +23446,7 @@ function generateTemplateOnlyMount(ir, ctx) {
|
|
|
23313
23446
|
const restSpreadNames = resolveRestSpreadNames(ctx);
|
|
23314
23447
|
let templateHtml;
|
|
23315
23448
|
if (canGenerateStaticTemplate(ir.root, propNamesForStaticCheck, inlinableConstants, unsafeLocalNames)) {
|
|
23316
|
-
const markupSlotIds =
|
|
23449
|
+
const markupSlotIds = markupSlotIdsOf(ctx);
|
|
23317
23450
|
templateHtml = irToComponentTemplate(ir.root, inlinableConstants, restSpreadNames, ctx.propsObjectName, markupSlotIds, ctx.restPropsName);
|
|
23318
23451
|
}
|
|
23319
23452
|
if (!templateHtml) {
|
|
@@ -24050,6 +24183,21 @@ function extractSsrDefaults(metadata) {
|
|
|
24050
24183
|
}
|
|
24051
24184
|
bindings[memo.name] = value;
|
|
24052
24185
|
}
|
|
24186
|
+
{
|
|
24187
|
+
const getterNames = collectAliasableGetterNames(metadata.signals, metadata.memos);
|
|
24188
|
+
for (const [alias, origin] of resolveGetterAliases(metadata.localConstants ?? [], (n) => getterNames.has(n))) {
|
|
24189
|
+
if (alias in out)
|
|
24190
|
+
continue;
|
|
24191
|
+
out[alias] = out[origin];
|
|
24192
|
+
}
|
|
24193
|
+
}
|
|
24194
|
+
for (const [local, callerKey] of resolveBodyDestructuredPropAliases(metadata.localConstants ?? [], metadata.propsObjectName)) {
|
|
24195
|
+
if (local in out)
|
|
24196
|
+
continue;
|
|
24197
|
+
const origin = out[callerKey];
|
|
24198
|
+
if (origin)
|
|
24199
|
+
out[local] = origin;
|
|
24200
|
+
}
|
|
24053
24201
|
if (metadata.propsObjectName !== null) {
|
|
24054
24202
|
const referenced = new Set;
|
|
24055
24203
|
for (const sig of metadata.signals) {
|
|
@@ -26414,6 +26562,17 @@ function emitParsedExpr(expr, emitter) {
|
|
|
26414
26562
|
case "literal":
|
|
26415
26563
|
return emitter.literal(expr.value, expr.literalType);
|
|
26416
26564
|
case "call": {
|
|
26565
|
+
if (emitter.lowering) {
|
|
26566
|
+
for (const matcher of emitter.lowering.matchers) {
|
|
26567
|
+
const node = matcher(expr.callee, expr.args);
|
|
26568
|
+
if (!node)
|
|
26569
|
+
continue;
|
|
26570
|
+
const rendered = emitter.lowering.render(node, emit);
|
|
26571
|
+
if (rendered !== null)
|
|
26572
|
+
return rendered;
|
|
26573
|
+
break;
|
|
26574
|
+
}
|
|
26575
|
+
}
|
|
26417
26576
|
const cb = asCallbackMethodCall(expr);
|
|
26418
26577
|
if (cb)
|
|
26419
26578
|
return emitter.callbackMethod(cb.method, cb.object, cb.arrow, cb.args, emit);
|
|
@@ -29717,7 +29876,9 @@ export {
|
|
|
29717
29876
|
rewriteDynamicImportsInSource,
|
|
29718
29877
|
resolveStaticLoopSource,
|
|
29719
29878
|
resolveSetters,
|
|
29879
|
+
resolveGetterAliases,
|
|
29720
29880
|
resolveDangerousInnerHtml,
|
|
29881
|
+
resolveBodyDestructuredPropAliases,
|
|
29721
29882
|
resetCompilerCounters,
|
|
29722
29883
|
registerLoweringPlugin,
|
|
29723
29884
|
registerBuiltinLoweringPlugins,
|
|
@@ -29741,6 +29902,7 @@ export {
|
|
|
29741
29902
|
matchQueryHrefCall,
|
|
29742
29903
|
matchLoweringCall,
|
|
29743
29904
|
makeIdCallRegex,
|
|
29905
|
+
loweringNodeChildren,
|
|
29744
29906
|
lookupStaticRecordLiteral,
|
|
29745
29907
|
listComponentFunctions as listExportedComponents,
|
|
29746
29908
|
listComponentFunctions,
|
|
@@ -29829,6 +29991,7 @@ export {
|
|
|
29829
29991
|
collectModuleStringConsts,
|
|
29830
29992
|
collectLoopBoundNames,
|
|
29831
29993
|
collectContextConsumers,
|
|
29994
|
+
collectAliasableGetterNames,
|
|
29832
29995
|
buildWhyUpdate,
|
|
29833
29996
|
buildStaticBudget,
|
|
29834
29997
|
buildSourceMapFromIR,
|