@barefootjs/jsx 0.5.0 → 0.5.2
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/test-adapter.d.ts.map +1 -1
- package/dist/analyzer-context.d.ts +8 -1
- package/dist/analyzer-context.d.ts.map +1 -1
- package/dist/analyzer.d.ts.map +1 -1
- package/dist/expression-parser.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +250 -59
- package/dist/ir-to-client-js/collect-elements.d.ts +11 -1
- package/dist/ir-to-client-js/collect-elements.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/loop.d.ts +14 -0
- package/dist/ir-to-client-js/control-flow/plan/loop.d.ts.map +1 -1
- package/dist/ir-to-client-js/control-flow/stringify/loop.d.ts.map +1 -1
- package/dist/ir-to-client-js/emit-reactive.d.ts.map +1 -1
- package/dist/ir-to-client-js/html-template.d.ts +0 -14
- 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/reactivity.d.ts.map +1 -1
- package/dist/ir-to-client-js/types.d.ts +7 -0
- package/dist/ir-to-client-js/types.d.ts.map +1 -1
- package/dist/ir-to-client-js/utils.d.ts +2 -2
- package/dist/ir-to-client-js/utils.d.ts.map +1 -1
- package/dist/types.d.ts +17 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/__tests__/__snapshots__/doc-examples.test.ts.snap +310 -188
- package/src/__tests__/adapter-output.test.ts +49 -0
- package/src/__tests__/child-components-in-map.test.ts +43 -0
- package/src/__tests__/client-js-generation.test.ts +5 -2
- package/src/__tests__/inline-jsx-callback.test.ts +95 -0
- package/src/__tests__/ir-jsx-props.test.ts +5 -2
- package/src/__tests__/loop-item-conditional-codegen.test.ts +81 -0
- package/src/__tests__/map-logical-jsx-helper.test.ts +159 -0
- package/src/__tests__/missing-key-in-list.test.ts +49 -0
- package/src/__tests__/reactive-attrs-in-map.test.ts +41 -0
- package/src/adapters/test-adapter.ts +16 -1
- package/src/analyzer-context.ts +59 -13
- package/src/analyzer.ts +8 -0
- package/src/expression-parser.ts +16 -1
- package/src/index.ts +2 -0
- package/src/ir-to-client-js/collect-elements.ts +37 -15
- package/src/ir-to-client-js/control-flow/plan/build-loop.ts +17 -0
- package/src/ir-to-client-js/control-flow/plan/loop.ts +14 -0
- package/src/ir-to-client-js/control-flow/stringify/insert.ts +7 -2
- package/src/ir-to-client-js/control-flow/stringify/loop.ts +60 -0
- package/src/ir-to-client-js/emit-reactive.ts +12 -3
- package/src/ir-to-client-js/html-template.ts +29 -3
- package/src/ir-to-client-js/imports.ts +2 -2
- package/src/ir-to-client-js/reactivity.ts +17 -1
- package/src/ir-to-client-js/types.ts +7 -0
- package/src/ir-to-client-js/utils.ts +2 -1
- package/src/jsx-to-ir.ts +161 -12
- package/src/preprocess-inline-jsx-callbacks.ts +28 -10
- package/src/scanner/__tests__/js-scanner.fuzz.test.ts +202 -0
- package/src/types.ts +18 -0
package/dist/index.js
CHANGED
|
@@ -222,6 +222,7 @@ import {
|
|
|
222
222
|
BF_LOOP_END,
|
|
223
223
|
loopStartMarker,
|
|
224
224
|
loopEndMarker,
|
|
225
|
+
loopItemMarker,
|
|
225
226
|
toHTMLAttrName as toHtmlAttrName
|
|
226
227
|
} from "@barefootjs/shared";
|
|
227
228
|
var PROPS_PARAM = "_p";
|
|
@@ -1154,6 +1155,9 @@ function buildSpreadAttrsMergeCall(args) {
|
|
|
1154
1155
|
}
|
|
1155
1156
|
return `\${spreadAttrs({${objMembers.join(", ")}})}`;
|
|
1156
1157
|
}
|
|
1158
|
+
function itemAnchorTemplate(keyExpr) {
|
|
1159
|
+
return `<!--${loopItemMarker("${" + keyExpr + "}")}-->`;
|
|
1160
|
+
}
|
|
1157
1161
|
function irToHtmlTemplate(node, restSpreadNames, loopDepth = 0, loopParams, branchSlotsVar, insideLoop = false, inHoistedChildren = false) {
|
|
1158
1162
|
const recurse = (n) => irToHtmlTemplate(n, restSpreadNames, loopDepth, loopParams, branchSlotsVar, insideLoop, inHoistedChildren);
|
|
1159
1163
|
const wrapExpr = (expr) => wrapExprWithLoopParams(expr, loopParams);
|
|
@@ -1249,7 +1253,10 @@ function irToHtmlTemplate(node, restSpreadNames, loopDepth = 0, loopParams, bran
|
|
|
1249
1253
|
}
|
|
1250
1254
|
case "loop": {
|
|
1251
1255
|
const innerRecurse = (n) => irToHtmlTemplate(n, restSpreadNames, loopDepth + 1, loopParams, branchSlotsVar, insideLoop);
|
|
1252
|
-
|
|
1256
|
+
let childTemplate = node.children.map(innerRecurse).join("");
|
|
1257
|
+
if (node.bodyIsItemConditional && node.key) {
|
|
1258
|
+
childTemplate = `${itemAnchorTemplate(node.key)}${childTemplate}`;
|
|
1259
|
+
}
|
|
1253
1260
|
const indexParam = node.index ? `, ${node.index}` : "";
|
|
1254
1261
|
const rawChainedArray = applyLoopChain(node);
|
|
1255
1262
|
const { array: iterArray, callbackParam } = applyIterationShape(node, rawChainedArray, indexParam);
|
|
@@ -1828,7 +1835,10 @@ function generateCsrTemplateWithOpts(node, opts) {
|
|
|
1828
1835
|
return `\${renderChild('${nameForRegistryRef(node.name)}', ${propsExpr}${keyArg || (slotArg ? ", undefined" : "")}${slotArg})}`;
|
|
1829
1836
|
}
|
|
1830
1837
|
case "loop": {
|
|
1831
|
-
|
|
1838
|
+
let childTemplate = node.children.map(recurseInLoop).join("");
|
|
1839
|
+
if (node.bodyIsItemConditional && node.key) {
|
|
1840
|
+
childTemplate = `${itemAnchorTemplate(node.key)}${childTemplate}`;
|
|
1841
|
+
}
|
|
1832
1842
|
const indexParam = node.index ? `, ${node.index}` : "";
|
|
1833
1843
|
const chainedTemplateArray = node.sortComparator || node.filterPredicate ? applyLoopChain(node, node.templateArray) : node.templateArray;
|
|
1834
1844
|
const rawArrayExpr = transformExpr(node.array, chainedTemplateArray);
|
|
@@ -2205,6 +2215,24 @@ function getSourceLocation(node, sourceFile, filePath) {
|
|
|
2205
2215
|
}
|
|
2206
2216
|
};
|
|
2207
2217
|
}
|
|
2218
|
+
function membersToProperties(members, sourceFile) {
|
|
2219
|
+
return members.filter(ts6.isPropertySignature).map((member) => ({
|
|
2220
|
+
name: propertyNameText(member.name, sourceFile),
|
|
2221
|
+
type: typeNodeToTypeInfo(member.type, sourceFile) ?? {
|
|
2222
|
+
kind: "unknown",
|
|
2223
|
+
raw: "unknown"
|
|
2224
|
+
},
|
|
2225
|
+
optional: !!member.questionToken,
|
|
2226
|
+
readonly: !!member.modifiers?.some((m) => m.kind === ts6.SyntaxKind.ReadonlyKeyword)
|
|
2227
|
+
}));
|
|
2228
|
+
}
|
|
2229
|
+
function propertyNameText(name, sourceFile) {
|
|
2230
|
+
if (!name)
|
|
2231
|
+
return "";
|
|
2232
|
+
if (ts6.isStringLiteral(name) || ts6.isNumericLiteral(name))
|
|
2233
|
+
return name.text;
|
|
2234
|
+
return name.getText(sourceFile);
|
|
2235
|
+
}
|
|
2208
2236
|
function typeNodeToTypeInfo(typeNode, sourceFile) {
|
|
2209
2237
|
if (!typeNode)
|
|
2210
2238
|
return null;
|
|
@@ -2242,18 +2270,21 @@ function typeNodeToTypeInfo(typeNode, sourceFile) {
|
|
|
2242
2270
|
return {
|
|
2243
2271
|
kind: "object",
|
|
2244
2272
|
raw,
|
|
2245
|
-
properties: typeNode.members
|
|
2246
|
-
name: member.name?.getText(sourceFile) ?? "",
|
|
2247
|
-
type: typeNodeToTypeInfo(member.type, sourceFile) ?? {
|
|
2248
|
-
kind: "unknown",
|
|
2249
|
-
raw: "unknown"
|
|
2250
|
-
},
|
|
2251
|
-
optional: !!member.questionToken,
|
|
2252
|
-
readonly: !!member.modifiers?.some((m) => m.kind === ts6.SyntaxKind.ReadonlyKeyword)
|
|
2253
|
-
}))
|
|
2273
|
+
properties: membersToProperties(typeNode.members, sourceFile)
|
|
2254
2274
|
};
|
|
2255
2275
|
}
|
|
2256
2276
|
if (ts6.isTypeReferenceNode(typeNode)) {
|
|
2277
|
+
const refName = ts6.isIdentifier(typeNode.typeName) ? typeNode.typeName.text : "";
|
|
2278
|
+
if ((refName === "Array" || refName === "ReadonlyArray") && typeNode.typeArguments?.length === 1) {
|
|
2279
|
+
return {
|
|
2280
|
+
kind: "array",
|
|
2281
|
+
raw,
|
|
2282
|
+
elementType: typeNodeToTypeInfo(typeNode.typeArguments[0], sourceFile) ?? {
|
|
2283
|
+
kind: "unknown",
|
|
2284
|
+
raw: "unknown"
|
|
2285
|
+
}
|
|
2286
|
+
};
|
|
2287
|
+
}
|
|
2257
2288
|
return {
|
|
2258
2289
|
kind: "interface",
|
|
2259
2290
|
raw
|
|
@@ -3772,14 +3803,17 @@ function collectInterfaceDefinition(node, ctx) {
|
|
|
3772
3803
|
kind: "interface",
|
|
3773
3804
|
name: node.name.text,
|
|
3774
3805
|
definition: node.getText(ctx.sourceFile),
|
|
3806
|
+
properties: membersToProperties(node.members, ctx.sourceFile),
|
|
3775
3807
|
loc: getSourceLocation(node, ctx.sourceFile, ctx.filePath)
|
|
3776
3808
|
});
|
|
3777
3809
|
}
|
|
3778
3810
|
function collectTypeAliasDefinition(node, ctx) {
|
|
3811
|
+
const properties = ts7.isTypeLiteralNode(node.type) ? membersToProperties(node.type.members, ctx.sourceFile) : undefined;
|
|
3779
3812
|
ctx.typeDefinitions.push({
|
|
3780
3813
|
kind: "type",
|
|
3781
3814
|
name: node.name.text,
|
|
3782
3815
|
definition: node.getText(ctx.sourceFile),
|
|
3816
|
+
properties,
|
|
3783
3817
|
loc: getSourceLocation(node, ctx.sourceFile, ctx.filePath)
|
|
3784
3818
|
});
|
|
3785
3819
|
}
|
|
@@ -5193,7 +5227,24 @@ var UNSUPPORTED_METHODS = new Set([
|
|
|
5193
5227
|
"some",
|
|
5194
5228
|
"forEach",
|
|
5195
5229
|
"flatMap",
|
|
5196
|
-
"flat"
|
|
5230
|
+
"flat",
|
|
5231
|
+
"split",
|
|
5232
|
+
"startsWith",
|
|
5233
|
+
"endsWith",
|
|
5234
|
+
"replace",
|
|
5235
|
+
"replaceAll",
|
|
5236
|
+
"repeat",
|
|
5237
|
+
"padStart",
|
|
5238
|
+
"padEnd",
|
|
5239
|
+
"charAt",
|
|
5240
|
+
"charCodeAt",
|
|
5241
|
+
"codePointAt",
|
|
5242
|
+
"normalize",
|
|
5243
|
+
"substring",
|
|
5244
|
+
"substr",
|
|
5245
|
+
"match",
|
|
5246
|
+
"matchAll",
|
|
5247
|
+
"search"
|
|
5197
5248
|
]);
|
|
5198
5249
|
function parseExpression(expr) {
|
|
5199
5250
|
const trimmed = expr.trim();
|
|
@@ -6055,7 +6106,7 @@ function checkSupport(expr) {
|
|
|
6055
6106
|
return {
|
|
6056
6107
|
supported: false,
|
|
6057
6108
|
level: "L5_UNSUPPORTED",
|
|
6058
|
-
reason: `
|
|
6109
|
+
reason: `Method '${methodName}()' has no template lowering and requires client-side evaluation. Wrap the expression in /* @client */ to defer it to hydration, or pre-compute the value before rendering.`
|
|
6059
6110
|
};
|
|
6060
6111
|
}
|
|
6061
6112
|
}
|
|
@@ -7533,6 +7584,23 @@ function containsJsxInExpression(node) {
|
|
|
7533
7584
|
}
|
|
7534
7585
|
return ts11.forEachChild(node, containsJsxInExpression) ?? false;
|
|
7535
7586
|
}
|
|
7587
|
+
function callsJsxHelper(node, ctx) {
|
|
7588
|
+
let found = false;
|
|
7589
|
+
const visit2 = (n) => {
|
|
7590
|
+
if (found)
|
|
7591
|
+
return;
|
|
7592
|
+
if (ts11.isCallExpression(n) && ts11.isIdentifier(n.expression)) {
|
|
7593
|
+
const name = n.expression.text;
|
|
7594
|
+
if (ctx.analyzer.jsxFunctions.has(name) || ctx.analyzer.jsxMultiReturnFunctions.has(name)) {
|
|
7595
|
+
found = true;
|
|
7596
|
+
return;
|
|
7597
|
+
}
|
|
7598
|
+
}
|
|
7599
|
+
ts11.forEachChild(n, visit2);
|
|
7600
|
+
};
|
|
7601
|
+
visit2(node);
|
|
7602
|
+
return found;
|
|
7603
|
+
}
|
|
7536
7604
|
function containsAwaitExpression(node) {
|
|
7537
7605
|
if (ts11.isAwaitExpression(node))
|
|
7538
7606
|
return true;
|
|
@@ -7612,7 +7680,7 @@ function transformJsxExpression(expr, ctx, isClientOnly = false) {
|
|
|
7612
7680
|
if (node.operatorToken.kind === ts11.SyntaxKind.AmpersandAmpersandToken) {
|
|
7613
7681
|
return transformLogicalAnd(node, ctx);
|
|
7614
7682
|
}
|
|
7615
|
-
if ((node.operatorToken.kind === ts11.SyntaxKind.QuestionQuestionToken || node.operatorToken.kind === ts11.SyntaxKind.BarBarToken) && containsJsxInExpression(node.right)) {
|
|
7683
|
+
if ((node.operatorToken.kind === ts11.SyntaxKind.QuestionQuestionToken || node.operatorToken.kind === ts11.SyntaxKind.BarBarToken) && (containsJsxInExpression(node.right) || callsJsxHelper(node.right, ctx))) {
|
|
7616
7684
|
return transformNullishCoalescing(node, ctx);
|
|
7617
7685
|
}
|
|
7618
7686
|
return null;
|
|
@@ -8069,23 +8137,23 @@ function checkLoopKey(callback, ctx, isNested) {
|
|
|
8069
8137
|
}
|
|
8070
8138
|
while (ts11.isParenthesizedExpression(body))
|
|
8071
8139
|
body = body.expression;
|
|
8140
|
+
function checkJsxOperand(node) {
|
|
8141
|
+
let n = node;
|
|
8142
|
+
while (ts11.isParenthesizedExpression(n))
|
|
8143
|
+
n = n.expression;
|
|
8144
|
+
if (ts11.isJsxElement(n))
|
|
8145
|
+
checkOpening(n.openingElement);
|
|
8146
|
+
else if (ts11.isJsxSelfClosingElement(n))
|
|
8147
|
+
checkOpening(n);
|
|
8148
|
+
}
|
|
8072
8149
|
if (ts11.isConditionalExpression(body)) {
|
|
8073
|
-
|
|
8074
|
-
|
|
8075
|
-
|
|
8076
|
-
|
|
8077
|
-
|
|
8078
|
-
|
|
8079
|
-
|
|
8080
|
-
wf = wf.expression;
|
|
8081
|
-
if (ts11.isJsxElement(wt))
|
|
8082
|
-
checkOpening(wt.openingElement);
|
|
8083
|
-
else if (ts11.isJsxSelfClosingElement(wt))
|
|
8084
|
-
checkOpening(wt);
|
|
8085
|
-
if (ts11.isJsxElement(wf))
|
|
8086
|
-
checkOpening(wf.openingElement);
|
|
8087
|
-
else if (ts11.isJsxSelfClosingElement(wf))
|
|
8088
|
-
checkOpening(wf);
|
|
8150
|
+
checkJsxOperand(body.whenTrue);
|
|
8151
|
+
checkJsxOperand(body.whenFalse);
|
|
8152
|
+
return;
|
|
8153
|
+
}
|
|
8154
|
+
if (ts11.isBinaryExpression(body) && (body.operatorToken.kind === ts11.SyntaxKind.AmpersandAmpersandToken || body.operatorToken.kind === ts11.SyntaxKind.BarBarToken || body.operatorToken.kind === ts11.SyntaxKind.QuestionQuestionToken)) {
|
|
8155
|
+
checkJsxOperand(body.left);
|
|
8156
|
+
checkJsxOperand(body.right);
|
|
8089
8157
|
return;
|
|
8090
8158
|
}
|
|
8091
8159
|
if (ts11.isJsxElement(body)) {
|
|
@@ -8108,6 +8176,38 @@ function loopBodyIsMultiRoot(children) {
|
|
|
8108
8176
|
return false;
|
|
8109
8177
|
return loopBodyIsMultiRoot(only.children);
|
|
8110
8178
|
}
|
|
8179
|
+
function branchHasNoElement(node) {
|
|
8180
|
+
if (node.type === "element" || node.type === "component")
|
|
8181
|
+
return false;
|
|
8182
|
+
if (node.type === "conditional") {
|
|
8183
|
+
return branchHasNoElement(node.whenTrue) || branchHasNoElement(node.whenFalse);
|
|
8184
|
+
}
|
|
8185
|
+
if (node.type === "fragment") {
|
|
8186
|
+
const real = node.children.filter((c) => !(c.type === "text" && typeof c.value === "string" && !c.value.trim()));
|
|
8187
|
+
return real.length !== 1 || branchHasNoElement(real[0]);
|
|
8188
|
+
}
|
|
8189
|
+
return true;
|
|
8190
|
+
}
|
|
8191
|
+
function loopBodyItemConditional(children) {
|
|
8192
|
+
const real = children.filter((c) => !(c.type === "text" && typeof c.value === "string" && !c.value.trim()));
|
|
8193
|
+
if (real.length !== 1)
|
|
8194
|
+
return null;
|
|
8195
|
+
const only = real[0];
|
|
8196
|
+
if (only.type !== "conditional")
|
|
8197
|
+
return null;
|
|
8198
|
+
if (branchHasNoElement(only.whenTrue) || branchHasNoElement(only.whenFalse)) {
|
|
8199
|
+
return only;
|
|
8200
|
+
}
|
|
8201
|
+
return null;
|
|
8202
|
+
}
|
|
8203
|
+
function extractItemConditionalKey(cond) {
|
|
8204
|
+
const a = branchHasNoElement(cond.whenTrue) ? null : extractLoopKey(cond.whenTrue);
|
|
8205
|
+
const b = branchHasNoElement(cond.whenFalse) ? null : extractLoopKey(cond.whenFalse);
|
|
8206
|
+
if (a !== null && b !== null) {
|
|
8207
|
+
return normalizeKeyExpr(a) === normalizeKeyExpr(b) ? a : null;
|
|
8208
|
+
}
|
|
8209
|
+
return a ?? b;
|
|
8210
|
+
}
|
|
8111
8211
|
function transformMapCall(node, ctx, isClientOnly = false, method = "map") {
|
|
8112
8212
|
const isNested = ctx.loopParams.size > 0;
|
|
8113
8213
|
const propAccess = node.expression;
|
|
@@ -8270,6 +8370,19 @@ function transformMapCall(node, ctx, isClientOnly = false, method = "map") {
|
|
|
8270
8370
|
}
|
|
8271
8371
|
if (index)
|
|
8272
8372
|
ctx.loopParams.add(index);
|
|
8373
|
+
const tryTransformRenderableBody = (expr) => {
|
|
8374
|
+
if (!ts11.isBinaryExpression(expr))
|
|
8375
|
+
return;
|
|
8376
|
+
const op = expr.operatorToken.kind;
|
|
8377
|
+
if (op !== ts11.SyntaxKind.AmpersandAmpersandToken && op !== ts11.SyntaxKind.BarBarToken && op !== ts11.SyntaxKind.QuestionQuestionToken) {
|
|
8378
|
+
return;
|
|
8379
|
+
}
|
|
8380
|
+
if (!containsJsxInExpression(expr) && !callsJsxHelper(expr, ctx))
|
|
8381
|
+
return;
|
|
8382
|
+
const transformed = transformJsxExpression(expr, ctx, isClientOnly);
|
|
8383
|
+
if (transformed)
|
|
8384
|
+
children = [transformed];
|
|
8385
|
+
};
|
|
8273
8386
|
const body = callback.body;
|
|
8274
8387
|
if (ts11.isJsxElement(body) || ts11.isJsxSelfClosingElement(body) || ts11.isJsxFragment(body)) {
|
|
8275
8388
|
const transformed = transformNode(body, ctx);
|
|
@@ -8292,6 +8405,8 @@ function transformMapCall(node, ctx, isClientOnly = false, method = "map") {
|
|
|
8292
8405
|
children = [transformConditional(inner, ctx)];
|
|
8293
8406
|
} else if (method === "flatMap" && ts11.isArrayLiteralExpression(inner)) {
|
|
8294
8407
|
children = transformArrayLiteralChildren(inner, ctx);
|
|
8408
|
+
} else {
|
|
8409
|
+
tryTransformRenderableBody(inner);
|
|
8295
8410
|
}
|
|
8296
8411
|
} else if (method === "flatMap" && ts11.isArrayLiteralExpression(body)) {
|
|
8297
8412
|
children = transformArrayLiteralChildren(body, ctx);
|
|
@@ -8340,6 +8455,8 @@ function transformMapCall(node, ctx, isClientOnly = false, method = "map") {
|
|
|
8340
8455
|
if (method === "flatMap" && children.length === 0) {
|
|
8341
8456
|
flatMapCallback = buildFlatMapCallback(callback, body, ctx);
|
|
8342
8457
|
}
|
|
8458
|
+
} else {
|
|
8459
|
+
tryTransformRenderableBody(body);
|
|
8343
8460
|
}
|
|
8344
8461
|
if (paramBindings) {
|
|
8345
8462
|
for (const b of paramBindings)
|
|
@@ -8356,7 +8473,9 @@ function transformMapCall(node, ctx, isClientOnly = false, method = "map") {
|
|
|
8356
8473
|
if (ts11.isArrowFunction(node.arguments[0]) && children.length > 0) {
|
|
8357
8474
|
checkLoopKey(node.arguments[0], ctx, isNested);
|
|
8358
8475
|
}
|
|
8359
|
-
const
|
|
8476
|
+
const itemConditional = children.length > 0 ? loopBodyItemConditional(children) : null;
|
|
8477
|
+
const bodyIsItemConditional = itemConditional !== null;
|
|
8478
|
+
const key = bodyIsItemConditional ? extractItemConditionalKey(itemConditional) : children.length > 0 ? extractLoopKey(children[0]) : null;
|
|
8360
8479
|
let childComponent;
|
|
8361
8480
|
if (children.length === 1 && children[0].type === "component") {
|
|
8362
8481
|
const comp = children[0];
|
|
@@ -8395,6 +8514,7 @@ function transformMapCall(node, ctx, isClientOnly = false, method = "map") {
|
|
|
8395
8514
|
callsReactiveGetters: callsReactive || undefined,
|
|
8396
8515
|
hasFunctionCalls: hasCalls || undefined,
|
|
8397
8516
|
bodyIsMultiRoot: bodyIsMultiRoot || undefined,
|
|
8517
|
+
bodyIsItemConditional: bodyIsItemConditional || undefined,
|
|
8398
8518
|
childComponent,
|
|
8399
8519
|
nestedComponents,
|
|
8400
8520
|
filterPredicate,
|
|
@@ -9573,7 +9693,8 @@ function collectLoopChildReactiveAttrs(node, ctx, loopParam, loopParamBindings)
|
|
|
9573
9693
|
if (!valueStr)
|
|
9574
9694
|
continue;
|
|
9575
9695
|
const expanded = expandConstantForReactivity(valueStr, ctx, attr.freeIdentifiers);
|
|
9576
|
-
|
|
9696
|
+
const reactive = classifyReactivity(expanded.expr, ctx, loopParam, loopParamBindings, expanded.freeIds).kind !== "none" || attr.callsReactiveGetters || attr.hasFunctionCalls;
|
|
9697
|
+
if (!attr.clientOnly && !reactive)
|
|
9577
9698
|
continue;
|
|
9578
9699
|
attrs.push({
|
|
9579
9700
|
childSlotId: el.slotId,
|
|
@@ -9594,19 +9715,27 @@ function producesDomChild(node) {
|
|
|
9594
9715
|
}
|
|
9595
9716
|
function computeLoopSiblingOffsets(root) {
|
|
9596
9717
|
const offsets = new Map;
|
|
9597
|
-
|
|
9598
|
-
|
|
9599
|
-
|
|
9600
|
-
|
|
9601
|
-
if (
|
|
9602
|
-
|
|
9603
|
-
|
|
9604
|
-
|
|
9605
|
-
nonLoopCount++;
|
|
9606
|
-
}
|
|
9718
|
+
const recordChildren = (children) => {
|
|
9719
|
+
let nonLoopCount = 0;
|
|
9720
|
+
for (const child of children) {
|
|
9721
|
+
if (child.type === "loop") {
|
|
9722
|
+
if (nonLoopCount > 0)
|
|
9723
|
+
offsets.set(child, nonLoopCount);
|
|
9724
|
+
} else if (producesDomChild(child)) {
|
|
9725
|
+
nonLoopCount++;
|
|
9607
9726
|
}
|
|
9608
|
-
descend();
|
|
9609
9727
|
}
|
|
9728
|
+
};
|
|
9729
|
+
const containerVisit = ({ node, descend }) => {
|
|
9730
|
+
recordChildren(node.children);
|
|
9731
|
+
descend();
|
|
9732
|
+
};
|
|
9733
|
+
walkIR(root, null, {
|
|
9734
|
+
element: containerVisit,
|
|
9735
|
+
component: containerVisit,
|
|
9736
|
+
fragment: containerVisit,
|
|
9737
|
+
provider: containerVisit,
|
|
9738
|
+
async: containerVisit
|
|
9610
9739
|
});
|
|
9611
9740
|
return offsets;
|
|
9612
9741
|
}
|
|
@@ -9687,6 +9816,7 @@ function collectInnerLoops(nodes, siblingOffsets, outerLoopParam, ctx, options)
|
|
|
9687
9816
|
key: n.key,
|
|
9688
9817
|
markerId: n.markerId,
|
|
9689
9818
|
bodyIsMultiRoot: n.bodyIsMultiRoot,
|
|
9819
|
+
bodyIsItemConditional: n.bodyIsItemConditional,
|
|
9690
9820
|
iterationShape: n.iterationShape,
|
|
9691
9821
|
containerSlotId: scope.parentSlotId,
|
|
9692
9822
|
template,
|
|
@@ -9901,6 +10031,7 @@ function collectElements(node, ctx, siblingOffsets, insideConditional = false) {
|
|
|
9901
10031
|
key: l.key,
|
|
9902
10032
|
markerId: l.markerId,
|
|
9903
10033
|
bodyIsMultiRoot: l.bodyIsMultiRoot,
|
|
10034
|
+
bodyIsItemConditional: l.bodyIsItemConditional,
|
|
9904
10035
|
iterationShape: l.iterationShape,
|
|
9905
10036
|
template,
|
|
9906
10037
|
staticItemTemplate,
|
|
@@ -10096,6 +10227,7 @@ function collectBranchLoops(node, ctx, siblingOffsets) {
|
|
|
10096
10227
|
key: n.key,
|
|
10097
10228
|
markerId: n.markerId,
|
|
10098
10229
|
bodyIsMultiRoot: n.bodyIsMultiRoot,
|
|
10230
|
+
bodyIsItemConditional: n.bodyIsItemConditional,
|
|
10099
10231
|
iterationShape: n.iterationShape,
|
|
10100
10232
|
template: childTemplate,
|
|
10101
10233
|
containerSlotId: containerSlot,
|
|
@@ -10662,6 +10794,7 @@ var RUNTIME_IMPORT_CANDIDATES = [
|
|
|
10662
10794
|
"getLoopChildren",
|
|
10663
10795
|
"getLoopNodes",
|
|
10664
10796
|
"mapArray",
|
|
10797
|
+
"mapArrayAnchored",
|
|
10665
10798
|
"createDisposableEffect",
|
|
10666
10799
|
"createComponent",
|
|
10667
10800
|
"renderChild",
|
|
@@ -10685,7 +10818,8 @@ var RUNTIME_IMPORT_CANDIDATES = [
|
|
|
10685
10818
|
"qsaChildScopes",
|
|
10686
10819
|
"upsertChildItem",
|
|
10687
10820
|
"__slot",
|
|
10688
|
-
"__bfSlot"
|
|
10821
|
+
"__bfSlot",
|
|
10822
|
+
"__bfText"
|
|
10689
10823
|
];
|
|
10690
10824
|
var RUNTIME_MODULE = "@barefootjs/client/runtime";
|
|
10691
10825
|
var IMPORT_PLACEHOLDER = "/* __BAREFOOTJS_DOM_IMPORTS__ */";
|
|
@@ -13507,17 +13641,21 @@ function emitDynamicTextUpdates(lines, ctx) {
|
|
|
13507
13641
|
const conditionalElems = elems.filter((e) => e.insideConditional);
|
|
13508
13642
|
const normalElems = elems.filter((e) => !e.insideConditional);
|
|
13509
13643
|
if (normalElems.length > 0 || conditionalElems.length > 0) {
|
|
13644
|
+
for (const elem of normalElems) {
|
|
13645
|
+
const v = varSlotId(elem.slotId);
|
|
13646
|
+
lines.push(` let __anchor_${v} = _${v}`);
|
|
13647
|
+
}
|
|
13510
13648
|
lines.push(` createEffect(() => {`);
|
|
13511
13649
|
if (normalElems.length > 0) {
|
|
13512
13650
|
lines.push(` const __val = ${expr}`);
|
|
13513
13651
|
for (const elem of normalElems) {
|
|
13514
13652
|
const v = varSlotId(elem.slotId);
|
|
13515
|
-
lines.push(`
|
|
13653
|
+
lines.push(` __anchor_${v} = __bfText(__anchor_${v}, __val)`);
|
|
13516
13654
|
}
|
|
13517
13655
|
for (const elem of conditionalElems) {
|
|
13518
13656
|
const v = varSlotId(elem.slotId);
|
|
13519
13657
|
lines.push(` const [__el_${v}] = $t(__scope, '${elem.slotId}')`);
|
|
13520
|
-
lines.push(`
|
|
13658
|
+
lines.push(` __bfText(__el_${v}, __val)`);
|
|
13521
13659
|
}
|
|
13522
13660
|
} else {
|
|
13523
13661
|
lines.push(` let __val`);
|
|
@@ -13525,7 +13663,7 @@ function emitDynamicTextUpdates(lines, ctx) {
|
|
|
13525
13663
|
for (const elem of conditionalElems) {
|
|
13526
13664
|
const v = varSlotId(elem.slotId);
|
|
13527
13665
|
lines.push(` const [__el_${v}] = $t(__scope, '${elem.slotId}')`);
|
|
13528
|
-
lines.push(`
|
|
13666
|
+
lines.push(` __bfText(__el_${v}, __val)`);
|
|
13529
13667
|
}
|
|
13530
13668
|
}
|
|
13531
13669
|
lines.push(` })`);
|
|
@@ -14021,8 +14159,14 @@ function stringifyPlainLoop(lines, plan, topIndent = " ") {
|
|
|
14021
14159
|
template,
|
|
14022
14160
|
reactiveEffects,
|
|
14023
14161
|
childRefs,
|
|
14024
|
-
bodyIsMultiRoot
|
|
14162
|
+
bodyIsMultiRoot,
|
|
14163
|
+
anchored,
|
|
14164
|
+
anchorKeyExpr
|
|
14025
14165
|
} = plan;
|
|
14166
|
+
if (anchored) {
|
|
14167
|
+
stringifyAnchoredLoop(lines, plan, topIndent, anchorKeyExpr);
|
|
14168
|
+
return;
|
|
14169
|
+
}
|
|
14026
14170
|
if (reactiveEffects === null && !bodyIsMultiRoot && childRefs.length === 0) {
|
|
14027
14171
|
const unwrapInline = paramUnwrap ? `${paramUnwrap} ` : "";
|
|
14028
14172
|
const preamble = mapPreambleWrapped ? `${mapPreambleWrapped}; ` : "";
|
|
@@ -14049,6 +14193,41 @@ function stringifyPlainLoop(lines, plan, topIndent = " ") {
|
|
|
14049
14193
|
lines.push(`${bodyIndent}return __el`);
|
|
14050
14194
|
lines.push(`${topIndent}}, '${markerId}')`);
|
|
14051
14195
|
}
|
|
14196
|
+
function stringifyAnchoredLoop(lines, plan, topIndent, anchorKeyExpr) {
|
|
14197
|
+
const {
|
|
14198
|
+
containerVar,
|
|
14199
|
+
markerId,
|
|
14200
|
+
arrayExpr,
|
|
14201
|
+
keyFn,
|
|
14202
|
+
paramHead,
|
|
14203
|
+
paramUnwrap,
|
|
14204
|
+
indexParam,
|
|
14205
|
+
mapPreambleWrapped,
|
|
14206
|
+
reactiveEffects
|
|
14207
|
+
} = plan;
|
|
14208
|
+
const condSlot = reactiveEffects?.conditionals[0]?.slotId ?? null;
|
|
14209
|
+
lines.push(`${topIndent}mapArrayAnchored(() => ${arrayExpr}, ${containerVar}, ${keyFn}, (${paramHead}, ${indexParam}, __existing) => {`);
|
|
14210
|
+
const bodyIndent = topIndent + " ";
|
|
14211
|
+
if (paramUnwrap)
|
|
14212
|
+
lines.push(`${bodyIndent}${paramUnwrap}`);
|
|
14213
|
+
if (mapPreambleWrapped)
|
|
14214
|
+
lines.push(`${bodyIndent}${mapPreambleWrapped}`);
|
|
14215
|
+
lines.push(`${bodyIndent}const __anchor = __existing ?? document.createComment(\`bf-loop-i:\${${anchorKeyExpr}}\`)`);
|
|
14216
|
+
lines.push(`${bodyIndent}let __frag = null`);
|
|
14217
|
+
lines.push(`${bodyIndent}if (!__existing) {`);
|
|
14218
|
+
lines.push(`${bodyIndent} __frag = document.createDocumentFragment()`);
|
|
14219
|
+
lines.push(`${bodyIndent} __frag.appendChild(__anchor)`);
|
|
14220
|
+
if (condSlot) {
|
|
14221
|
+
lines.push(`${bodyIndent} __frag.appendChild(document.createComment('bf-cond-start:${condSlot}'))`);
|
|
14222
|
+
lines.push(`${bodyIndent} __frag.appendChild(document.createComment('bf-cond-end:${condSlot}'))`);
|
|
14223
|
+
}
|
|
14224
|
+
lines.push(`${bodyIndent}}`);
|
|
14225
|
+
if (reactiveEffects !== null) {
|
|
14226
|
+
stringifyReactiveEffects(lines, reactiveEffects, { indent: bodyIndent, elVar: "__anchor", bodyIsMultiRoot: false });
|
|
14227
|
+
}
|
|
14228
|
+
lines.push(`${bodyIndent}return __frag ?? __anchor`);
|
|
14229
|
+
lines.push(`${topIndent}}, '${markerId}')`);
|
|
14230
|
+
}
|
|
14052
14231
|
function stringifyStaticLoop(lines, plan) {
|
|
14053
14232
|
const { containerVar, arrayExpr, param, indexParam, childIndexExpr, attrsBySlot, texts, childRefs, csrMaterialize } = plan;
|
|
14054
14233
|
const hasAttrs = attrsBySlot.length > 0;
|
|
@@ -14568,10 +14747,10 @@ function emitArmBody2(lines, body, mode, indent) {
|
|
|
14568
14747
|
}
|
|
14569
14748
|
for (const te of body.textEffects) {
|
|
14570
14749
|
const v = varSlotId(te.slotId);
|
|
14571
|
-
lines.push(`${indent}
|
|
14750
|
+
lines.push(`${indent}let __anchor_${v} = $t(__branchScope, '${te.slotId}')[0]`);
|
|
14572
14751
|
lines.push(`${indent}__disposers.push(createDisposableEffect(() => {`);
|
|
14573
14752
|
lines.push(`${indent} const __val = ${te.expression}`);
|
|
14574
|
-
lines.push(`${indent}
|
|
14753
|
+
lines.push(`${indent} __anchor_${v} = __bfText(__anchor_${v}, __val)`);
|
|
14575
14754
|
lines.push(`${indent}}))`);
|
|
14576
14755
|
}
|
|
14577
14756
|
if (body.loops.length > 0) {
|
|
@@ -14644,6 +14823,9 @@ function buildComponentLoopPlan(elem) {
|
|
|
14644
14823
|
|
|
14645
14824
|
// src/ir-to-client-js/control-flow/plan/build-loop.ts
|
|
14646
14825
|
function buildLoopPlan(elem, opts) {
|
|
14826
|
+
if (elem.bodyIsItemConditional) {
|
|
14827
|
+
return buildPlainLoopPlan(elem);
|
|
14828
|
+
}
|
|
14647
14829
|
if (elem.isStaticArray) {
|
|
14648
14830
|
return buildStaticLoopPlan(elem, opts.unsafeLocalNames);
|
|
14649
14831
|
}
|
|
@@ -14673,7 +14855,9 @@ function buildPlainLoopPlan(elem) {
|
|
|
14673
14855
|
template: elem.template,
|
|
14674
14856
|
reactiveEffects: hasReactive2 ? buildLoopReactiveEffectsPlan(elem) : null,
|
|
14675
14857
|
childRefs: buildChildRefBindings(elem.bindings.refs, elem.param, elem.paramBindings),
|
|
14676
|
-
bodyIsMultiRoot: elem.bodyIsMultiRoot ?? false
|
|
14858
|
+
bodyIsMultiRoot: elem.bodyIsMultiRoot ?? false,
|
|
14859
|
+
anchored: elem.bodyIsItemConditional ?? false,
|
|
14860
|
+
anchorKeyExpr: elem.key ? wrap(elem.key) : elem.index || "__idx"
|
|
14677
14861
|
};
|
|
14678
14862
|
}
|
|
14679
14863
|
function buildStaticLoopPlan(elem, unsafeLocalNames) {
|
|
@@ -15663,18 +15847,25 @@ function runSinglePass(source, filePath, startingCounter) {
|
|
|
15663
15847
|
}
|
|
15664
15848
|
function visit3(node) {
|
|
15665
15849
|
if (ts15.isJsxAttribute(node) && node.initializer && ts15.isJsxExpression(node.initializer) && node.initializer.expression) {
|
|
15666
|
-
|
|
15667
|
-
|
|
15668
|
-
expr = expr.expression;
|
|
15669
|
-
if (ts15.isArrowFunction(expr) && arrowBodyContainsJsx(expr)) {
|
|
15670
|
-
const handled = handleInlineArrow(expr);
|
|
15671
|
-
if (handled) {
|
|
15672
|
-
return;
|
|
15673
|
-
}
|
|
15850
|
+
if (tryHandleArrowValue(node.initializer.expression)) {
|
|
15851
|
+
return;
|
|
15674
15852
|
}
|
|
15675
15853
|
}
|
|
15854
|
+
if (ts15.isPropertyAssignment(node) && node.initializer) {
|
|
15855
|
+
if (tryHandleArrowValue(node.initializer))
|
|
15856
|
+
return;
|
|
15857
|
+
}
|
|
15676
15858
|
ts15.forEachChild(node, visit3);
|
|
15677
15859
|
}
|
|
15860
|
+
function tryHandleArrowValue(initializer) {
|
|
15861
|
+
let expr = initializer;
|
|
15862
|
+
while (ts15.isParenthesizedExpression(expr))
|
|
15863
|
+
expr = expr.expression;
|
|
15864
|
+
if (ts15.isArrowFunction(expr) && arrowBodyContainsJsx(expr)) {
|
|
15865
|
+
return handleInlineArrow(expr);
|
|
15866
|
+
}
|
|
15867
|
+
return false;
|
|
15868
|
+
}
|
|
15678
15869
|
function handleInlineArrow(arrow) {
|
|
15679
15870
|
const paramNames = collectArrowParamNames(arrow);
|
|
15680
15871
|
const free = collectFreeIdentifiers(arrow);
|
|
@@ -5,10 +5,20 @@ import { type IRNode, type IRLoop } from '../types';
|
|
|
5
5
|
import type { ClientJsContext, LoopChildBindings, LoopChildConditional, NestedLoop } from './types';
|
|
6
6
|
/**
|
|
7
7
|
* Pre-pass: for every loop node in the IR tree, record the number of non-loop
|
|
8
|
-
* DOM siblings that appear before it in its parent
|
|
8
|
+
* DOM siblings that appear before it in its parent container. Read when
|
|
9
9
|
* constructing TopLevelLoop and NestedLoop so the client JS can offset
|
|
10
10
|
* children[idx] access past statically-rendered siblings.
|
|
11
11
|
*
|
|
12
|
+
* Counting must happen for every container whose children render as a
|
|
13
|
+
* contiguous run of DOM siblings into the same parent — not just `element`.
|
|
14
|
+
* A loop nested directly inside a component (`<Wrapper><span/>{xs.map(...)}`
|
|
15
|
+
* </Wrapper>`), fragment, provider, or async boundary has its preceding
|
|
16
|
+
* static sibling rendered as a sibling of the loop's items too, so
|
|
17
|
+
* `children[idx]` access is shifted exactly as it is under an element parent
|
|
18
|
+
* (#1688). Before this, a static sibling before a `.map()` inside a
|
|
19
|
+
* (self-portaling) component dropped the first item's nested child component
|
|
20
|
+
* during hydration because the offset was silently zero.
|
|
21
|
+
*
|
|
12
22
|
* Computed once up front (instead of during collection) so the offset data
|
|
13
23
|
* lives in an explicit value rather than a module-level WeakMap mutated by
|
|
14
24
|
* two separate traversals.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collect-elements.d.ts","sourceRoot":"","sources":["../../src/ir-to-client-js/collect-elements.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,KAAK,MAAM,EAAoC,KAAK,MAAM,EAAmC,MAAM,UAAU,CAAA;AACtH,OAAO,KAAK,EAAE,eAAe,EAA+H,iBAAiB,EAA0B,oBAAoB,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAexP
|
|
1
|
+
{"version":3,"file":"collect-elements.d.ts","sourceRoot":"","sources":["../../src/ir-to-client-js/collect-elements.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,KAAK,MAAM,EAAoC,KAAK,MAAM,EAAmC,MAAM,UAAU,CAAA;AACtH,OAAO,KAAK,EAAE,eAAe,EAA+H,iBAAiB,EAA0B,oBAAoB,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAexP;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CA4B3E;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,wBAAwB;IACvC;;;;;OAKG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAA;IAC7B;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB;;;;;;;OAOG;IACH,cAAc,CAAC,EAAE,OAAO,CAAA;CACzB;AAED,4DAA4D;AAC5D,eAAO,MAAM,sBAAsB,EAAE,wBAIpC,CAAA;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,MAAM,EAAE,EACf,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EACnC,cAAc,CAAC,EAAE,MAAM,EACvB,GAAG,CAAC,EAAE,eAAe,EACrB,OAAO,CAAC,EAAE,wBAAwB,GACjC,UAAU,EAAE,CAyId;AA+JD;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,eAAe,EACpB,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EACnC,iBAAiB,UAAQ,GACxB,IAAI,CAsON;AA6VD;;;;;;;;;;GAUG;AAEH;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,SAAS,MAAM,EAAE,EAC3B,GAAG,EAAE,eAAe,EACpB,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EACnC,SAAS,EAAE,MAAM,EACjB,iBAAiB,EAAE,SAAS,OAAO,UAAU,EAAE,gBAAgB,EAAE,GAAG,SAAS,GAC5E,iBAAiB,CAUnB;AAED,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,eAAe,EACpB,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EACnC,SAAS,CAAC,EAAE,MAAM,EAClB,iBAAiB,CAAC,EAAE,SAAS,OAAO,UAAU,EAAE,gBAAgB,EAAE,GACjE,oBAAoB,EAAE,CA4DxB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-loop.d.ts","sourceRoot":"","sources":["../../../../src/ir-to-client-js/control-flow/plan/build-loop.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EACV,YAAY,EAEb,MAAM,aAAa,CAAA;AAgBpB,OAAO,KAAK,EACV,QAAQ,EACR,aAAa,EAEb,cAAc,EACf,MAAM,SAAS,CAAA;AAEhB,qDAAqD;AACrD,MAAM,WAAW,oBAAoB;IACnC,8FAA8F;IAC9F,gBAAgB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;CAC9B;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,oBAAoB,GAAG,QAAQ,
|
|
1
|
+
{"version":3,"file":"build-loop.d.ts","sourceRoot":"","sources":["../../../../src/ir-to-client-js/control-flow/plan/build-loop.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EACV,YAAY,EAEb,MAAM,aAAa,CAAA;AAgBpB,OAAO,KAAK,EACV,QAAQ,EACR,aAAa,EAEb,cAAc,EACf,MAAM,SAAS,CAAA;AAEhB,qDAAqD;AACrD,MAAM,WAAW,oBAAoB;IACnC,8FAA8F;IAC9F,gBAAgB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;CAC9B;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,oBAAoB,GAAG,QAAQ,CAsBtF;AAED,qFAAqF;AACrF,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,YAAY,GAAG,aAAa,CA8BpE;AAED,0CAA0C;AAC1C,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,YAAY,EAAE,gBAAgB,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,cAAc,CAiCrG"}
|
|
@@ -85,6 +85,20 @@ interface PlainLoopVariant extends DynamicLoopCommon {
|
|
|
85
85
|
* `<!--bf-loop-i-->` marker emission, and `qsaItem` slot lookups (#1212).
|
|
86
86
|
*/
|
|
87
87
|
bodyIsMultiRoot: boolean;
|
|
88
|
+
/**
|
|
89
|
+
* True when the loop body is a whole-item conditional (#1665). Switches
|
|
90
|
+
* emission to `mapArrayAnchored`: the renderItem returns a fragment headed
|
|
91
|
+
* by a `<!--bf-loop-i:KEY-->` anchor and seeded with the conditional's
|
|
92
|
+
* markers, and `insert(anchor, …)` (not `insert(__el, …)`) owns the
|
|
93
|
+
* possibly-empty content.
|
|
94
|
+
*/
|
|
95
|
+
anchored: boolean;
|
|
96
|
+
/**
|
|
97
|
+
* Key expression wrapped as a loop-param accessor (`t().id`), used to bake
|
|
98
|
+
* the per-item `bf-loop-i:KEY` anchor value inside the anchored renderItem.
|
|
99
|
+
* Empty when the loop has no key (only meaningful when `anchored`).
|
|
100
|
+
*/
|
|
101
|
+
anchorKeyExpr: string;
|
|
88
102
|
}
|
|
89
103
|
/**
|
|
90
104
|
* Loop body is a single child component (with or without nested child
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loop.d.ts","sourceRoot":"","sources":["../../../../src/ir-to-client-js/control-flow/plan/loop.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EACV,cAAc,EACd,qBAAqB,EACrB,qBAAqB,EACrB,YAAY,EACb,MAAM,aAAa,CAAA;AACpB,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAA;AAC1D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAElD,iDAAiD;AACjD,UAAU,cAAc;IACtB,uFAAuF;IACvF,YAAY,EAAE,MAAM,CAAA;IACpB,kGAAkG;IAClG,SAAS,EAAE,MAAM,CAAA;IACjB,iEAAiE;IACjE,UAAU,EAAE,MAAM,CAAA;IAClB;;;;;;;;OAQG;IACH,SAAS,EAAE,SAAS,mBAAmB,EAAE,CAAA;CAC1C;AAED,uEAAuE;AACvE,UAAU,iBAAkB,SAAQ,cAAc;IAChD,iFAAiF;IACjF,QAAQ,EAAE,MAAM,CAAA;IAChB,sEAAsE;IACtE,KAAK,EAAE,MAAM,CAAA;IACb,qEAAqE;IACrE,SAAS,EAAE,MAAM,CAAA;IACjB,qFAAqF;IACrF,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,gFAAgF;AAChF,MAAM,WAAW,mBAAmB;IAClC,yEAAyE;IACzE,WAAW,EAAE,MAAM,CAAA;IACnB;;;;;;;;;;OAUG;IACH,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED;;;;GAIG;AACH,UAAU,gBAAiB,SAAQ,iBAAiB;IAClD,IAAI,EAAE,OAAO,CAAA;IACb,4FAA4F;IAC5F,kBAAkB,EAAE,MAAM,CAAA;IAC1B,yCAAyC;IACzC,QAAQ,EAAE,MAAM,CAAA;IAChB,qFAAqF;IACrF,eAAe,EAAE,mBAAmB,GAAG,IAAI,CAAA;IAC3C;;;;OAIG;IACH,eAAe,EAAE,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"loop.d.ts","sourceRoot":"","sources":["../../../../src/ir-to-client-js/control-flow/plan/loop.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loop.d.ts","sourceRoot":"","sources":["../../../../src/ir-to-client-js/control-flow/stringify/loop.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAQH,OAAO,KAAK,EAAE,mBAAmB,EAAE,QAAQ,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAEjG;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,MAAM,EAAE,EACf,IAAI,EAAE,SAAS,mBAAmB,EAAE,EACpC,IAAI,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,OAAO,CAAA;CAAE,GAChE,IAAI,CASN;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,GAAG,IAAI,CAoBnE;AAYD,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,MAAM,EAAE,EACf,IAAI,EAAE,aAAa,EACnB,SAAS,GAAE,MAAa,GACvB,IAAI,
|
|
1
|
+
{"version":3,"file":"loop.d.ts","sourceRoot":"","sources":["../../../../src/ir-to-client-js/control-flow/stringify/loop.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAQH,OAAO,KAAK,EAAE,mBAAmB,EAAE,QAAQ,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAEjG;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,MAAM,EAAE,EACf,IAAI,EAAE,SAAS,mBAAmB,EAAE,EACpC,IAAI,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,OAAO,CAAA;CAAE,GAChE,IAAI,CASN;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,GAAG,IAAI,CAoBnE;AAYD,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,MAAM,EAAE,EACf,IAAI,EAAE,aAAa,EACnB,SAAS,GAAE,MAAa,GACvB,IAAI,CA0DN;AAmDD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,cAAc,GAAG,IAAI,CAoG/E"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"emit-reactive.d.ts","sourceRoot":"","sources":["../../src/ir-to-client-js/emit-reactive.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAExC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAI9C;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,MAAM,EAAE,CAgC7G;AAED;;;GAGG;AACH,wBAAgB,8BAA8B,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,eAAe,GAAG,MAAM,CAmBzF;AAED,gFAAgF;AAChF,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,eAAe,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"emit-reactive.d.ts","sourceRoot":"","sources":["../../src/ir-to-client-js/emit-reactive.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAExC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAI9C;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,MAAM,EAAE,CAgC7G;AAED;;;GAGG;AACH,wBAAgB,8BAA8B,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,eAAe,GAAG,MAAM,CAmBzF;AAED,gFAAgF;AAChF,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,eAAe,GAAG,IAAI,CA2DlF;AAED,kFAAkF;AAClF,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,eAAe,GAAG,IAAI,CAQrF;AAED,kGAAkG;AAClG,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,eAAe,GAAG,IAAI,CAyBxF;AAED,+FAA+F;AAC/F,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,eAAe,GAAG,IAAI,CAqDpF;AAED,2FAA2F;AAC3F,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,eAAe,GAAG,IAAI,CAgClF"}
|