@barefootjs/cli 0.5.0 → 0.5.1
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/index.js +179 -31
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -359,13 +359,16 @@ var init_js_scanner = __esm({
|
|
|
359
359
|
});
|
|
360
360
|
|
|
361
361
|
// ../shared/src/markers.ts
|
|
362
|
+
function loopItemMarker(key) {
|
|
363
|
+
return `${BF_LOOP_ITEM}:${key}`;
|
|
364
|
+
}
|
|
362
365
|
function loopStartMarker(markerId) {
|
|
363
366
|
return `${BF_LOOP_START}:${markerId}`;
|
|
364
367
|
}
|
|
365
368
|
function loopEndMarker(markerId) {
|
|
366
369
|
return `${BF_LOOP_END}:${markerId}`;
|
|
367
370
|
}
|
|
368
|
-
var BF_SCOPE, BF_SLOT, BF_HOST, BF_AT, BF_COND, BF_LOOP_START, BF_LOOP_END, BF_KEY, BF_KEY_PREFIX, BF_PLACEHOLDER, BF_PARENT_SCOPE_PLACEHOLDER;
|
|
371
|
+
var BF_SCOPE, BF_SLOT, BF_HOST, BF_AT, BF_COND, BF_LOOP_START, BF_LOOP_END, BF_LOOP_ITEM, BF_KEY, BF_KEY_PREFIX, BF_PLACEHOLDER, BF_PARENT_SCOPE_PLACEHOLDER;
|
|
369
372
|
var init_markers = __esm({
|
|
370
373
|
"../shared/src/markers.ts"() {
|
|
371
374
|
"use strict";
|
|
@@ -376,6 +379,7 @@ var init_markers = __esm({
|
|
|
376
379
|
BF_COND = "bf-c";
|
|
377
380
|
BF_LOOP_START = "bf-loop";
|
|
378
381
|
BF_LOOP_END = "bf-/loop";
|
|
382
|
+
BF_LOOP_ITEM = "bf-loop-i";
|
|
379
383
|
BF_KEY = "data-key";
|
|
380
384
|
BF_KEY_PREFIX = "data-key-";
|
|
381
385
|
BF_PLACEHOLDER = "data-bf-ph";
|
|
@@ -1376,6 +1380,9 @@ function buildSpreadAttrsMergeCall(args2) {
|
|
|
1376
1380
|
}
|
|
1377
1381
|
return `\${spreadAttrs({${objMembers.join(", ")}})}`;
|
|
1378
1382
|
}
|
|
1383
|
+
function itemAnchorTemplate(keyExpr) {
|
|
1384
|
+
return `<!--${loopItemMarker("${" + keyExpr + "}")}-->`;
|
|
1385
|
+
}
|
|
1379
1386
|
function irToHtmlTemplate(node, restSpreadNames, loopDepth = 0, loopParams, branchSlotsVar, insideLoop = false, inHoistedChildren = false) {
|
|
1380
1387
|
const recurse = (n) => irToHtmlTemplate(n, restSpreadNames, loopDepth, loopParams, branchSlotsVar, insideLoop, inHoistedChildren);
|
|
1381
1388
|
const wrapExpr = (expr) => wrapExprWithLoopParams(expr, loopParams);
|
|
@@ -1467,7 +1474,10 @@ function irToHtmlTemplate(node, restSpreadNames, loopDepth = 0, loopParams, bran
|
|
|
1467
1474
|
}
|
|
1468
1475
|
case "loop": {
|
|
1469
1476
|
const innerRecurse = (n) => irToHtmlTemplate(n, restSpreadNames, loopDepth + 1, loopParams, branchSlotsVar, insideLoop);
|
|
1470
|
-
|
|
1477
|
+
let childTemplate = node.children.map(innerRecurse).join("");
|
|
1478
|
+
if (node.bodyIsItemConditional && node.key) {
|
|
1479
|
+
childTemplate = `${itemAnchorTemplate(node.key)}${childTemplate}`;
|
|
1480
|
+
}
|
|
1471
1481
|
const indexParam = node.index ? `, ${node.index}` : "";
|
|
1472
1482
|
const rawChainedArray = applyLoopChain(node);
|
|
1473
1483
|
const { array: iterArray, callbackParam } = applyIterationShape(node, rawChainedArray, indexParam);
|
|
@@ -2030,7 +2040,10 @@ function generateCsrTemplateWithOpts(node, opts) {
|
|
|
2030
2040
|
return `\${renderChild('${nameForRegistryRef(node.name)}', ${propsExpr}${keyArg || (slotArg ? ", undefined" : "")}${slotArg})}`;
|
|
2031
2041
|
}
|
|
2032
2042
|
case "loop": {
|
|
2033
|
-
|
|
2043
|
+
let childTemplate = node.children.map(recurseInLoop).join("");
|
|
2044
|
+
if (node.bodyIsItemConditional && node.key) {
|
|
2045
|
+
childTemplate = `${itemAnchorTemplate(node.key)}${childTemplate}`;
|
|
2046
|
+
}
|
|
2034
2047
|
const indexParam = node.index ? `, ${node.index}` : "";
|
|
2035
2048
|
const chainedTemplateArray = node.sortComparator || node.filterPredicate ? applyLoopChain(node, node.templateArray) : node.templateArray;
|
|
2036
2049
|
const rawArrayExpr = transformExpr(node.array, chainedTemplateArray);
|
|
@@ -7385,6 +7398,22 @@ function containsJsxInExpression(node) {
|
|
|
7385
7398
|
}
|
|
7386
7399
|
return ts11.forEachChild(node, containsJsxInExpression) ?? false;
|
|
7387
7400
|
}
|
|
7401
|
+
function callsJsxHelper(node, ctx2) {
|
|
7402
|
+
let found = false;
|
|
7403
|
+
const visit3 = (n) => {
|
|
7404
|
+
if (found) return;
|
|
7405
|
+
if (ts11.isCallExpression(n) && ts11.isIdentifier(n.expression)) {
|
|
7406
|
+
const name = n.expression.text;
|
|
7407
|
+
if (ctx2.analyzer.jsxFunctions.has(name) || ctx2.analyzer.jsxMultiReturnFunctions.has(name)) {
|
|
7408
|
+
found = true;
|
|
7409
|
+
return;
|
|
7410
|
+
}
|
|
7411
|
+
}
|
|
7412
|
+
ts11.forEachChild(n, visit3);
|
|
7413
|
+
};
|
|
7414
|
+
visit3(node);
|
|
7415
|
+
return found;
|
|
7416
|
+
}
|
|
7388
7417
|
function containsAwaitExpression(node) {
|
|
7389
7418
|
if (ts11.isAwaitExpression(node)) return true;
|
|
7390
7419
|
if (ts11.isFunctionDeclaration(node) || ts11.isFunctionExpression(node) || ts11.isArrowFunction(node)) return false;
|
|
@@ -7466,7 +7495,7 @@ function transformJsxExpression(expr, ctx2, isClientOnly = false) {
|
|
|
7466
7495
|
if (node.operatorToken.kind === ts11.SyntaxKind.AmpersandAmpersandToken) {
|
|
7467
7496
|
return transformLogicalAnd(node, ctx2);
|
|
7468
7497
|
}
|
|
7469
|
-
if ((node.operatorToken.kind === ts11.SyntaxKind.QuestionQuestionToken || node.operatorToken.kind === ts11.SyntaxKind.BarBarToken) && containsJsxInExpression(node.right)) {
|
|
7498
|
+
if ((node.operatorToken.kind === ts11.SyntaxKind.QuestionQuestionToken || node.operatorToken.kind === ts11.SyntaxKind.BarBarToken) && (containsJsxInExpression(node.right) || callsJsxHelper(node.right, ctx2))) {
|
|
7470
7499
|
return transformNullishCoalescing(node, ctx2);
|
|
7471
7500
|
}
|
|
7472
7501
|
return null;
|
|
@@ -7906,17 +7935,20 @@ function checkLoopKey(callback, ctx2, isNested) {
|
|
|
7906
7935
|
body = ret.expression;
|
|
7907
7936
|
}
|
|
7908
7937
|
while (ts11.isParenthesizedExpression(body)) body = body.expression;
|
|
7938
|
+
function checkJsxOperand(node) {
|
|
7939
|
+
let n = node;
|
|
7940
|
+
while (ts11.isParenthesizedExpression(n)) n = n.expression;
|
|
7941
|
+
if (ts11.isJsxElement(n)) checkOpening(n.openingElement);
|
|
7942
|
+
else if (ts11.isJsxSelfClosingElement(n)) checkOpening(n);
|
|
7943
|
+
}
|
|
7909
7944
|
if (ts11.isConditionalExpression(body)) {
|
|
7910
|
-
|
|
7911
|
-
|
|
7912
|
-
|
|
7913
|
-
|
|
7914
|
-
|
|
7915
|
-
|
|
7916
|
-
|
|
7917
|
-
else if (ts11.isJsxSelfClosingElement(wt)) checkOpening(wt);
|
|
7918
|
-
if (ts11.isJsxElement(wf)) checkOpening(wf.openingElement);
|
|
7919
|
-
else if (ts11.isJsxSelfClosingElement(wf)) checkOpening(wf);
|
|
7945
|
+
checkJsxOperand(body.whenTrue);
|
|
7946
|
+
checkJsxOperand(body.whenFalse);
|
|
7947
|
+
return;
|
|
7948
|
+
}
|
|
7949
|
+
if (ts11.isBinaryExpression(body) && (body.operatorToken.kind === ts11.SyntaxKind.AmpersandAmpersandToken || body.operatorToken.kind === ts11.SyntaxKind.BarBarToken || body.operatorToken.kind === ts11.SyntaxKind.QuestionQuestionToken)) {
|
|
7950
|
+
checkJsxOperand(body.left);
|
|
7951
|
+
checkJsxOperand(body.right);
|
|
7920
7952
|
return;
|
|
7921
7953
|
}
|
|
7922
7954
|
if (ts11.isJsxElement(body)) {
|
|
@@ -7938,6 +7970,39 @@ function loopBodyIsMultiRoot(children) {
|
|
|
7938
7970
|
if (only.type !== "fragment") return false;
|
|
7939
7971
|
return loopBodyIsMultiRoot(only.children);
|
|
7940
7972
|
}
|
|
7973
|
+
function branchHasNoElement(node) {
|
|
7974
|
+
if (node.type === "element" || node.type === "component") return false;
|
|
7975
|
+
if (node.type === "conditional") {
|
|
7976
|
+
return branchHasNoElement(node.whenTrue) || branchHasNoElement(node.whenFalse);
|
|
7977
|
+
}
|
|
7978
|
+
if (node.type === "fragment") {
|
|
7979
|
+
const real = node.children.filter(
|
|
7980
|
+
(c) => !(c.type === "text" && typeof c.value === "string" && !c.value.trim())
|
|
7981
|
+
);
|
|
7982
|
+
return real.length !== 1 || branchHasNoElement(real[0]);
|
|
7983
|
+
}
|
|
7984
|
+
return true;
|
|
7985
|
+
}
|
|
7986
|
+
function loopBodyItemConditional(children) {
|
|
7987
|
+
const real = children.filter(
|
|
7988
|
+
(c) => !(c.type === "text" && typeof c.value === "string" && !c.value.trim())
|
|
7989
|
+
);
|
|
7990
|
+
if (real.length !== 1) return null;
|
|
7991
|
+
const only = real[0];
|
|
7992
|
+
if (only.type !== "conditional") return null;
|
|
7993
|
+
if (branchHasNoElement(only.whenTrue) || branchHasNoElement(only.whenFalse)) {
|
|
7994
|
+
return only;
|
|
7995
|
+
}
|
|
7996
|
+
return null;
|
|
7997
|
+
}
|
|
7998
|
+
function extractItemConditionalKey(cond) {
|
|
7999
|
+
const a = branchHasNoElement(cond.whenTrue) ? null : extractLoopKey(cond.whenTrue);
|
|
8000
|
+
const b = branchHasNoElement(cond.whenFalse) ? null : extractLoopKey(cond.whenFalse);
|
|
8001
|
+
if (a !== null && b !== null) {
|
|
8002
|
+
return normalizeKeyExpr(a) === normalizeKeyExpr(b) ? a : null;
|
|
8003
|
+
}
|
|
8004
|
+
return a ?? b;
|
|
8005
|
+
}
|
|
7941
8006
|
function transformMapCall(node, ctx2, isClientOnly = false, method = "map") {
|
|
7942
8007
|
const isNested = ctx2.loopParams.size > 0;
|
|
7943
8008
|
const propAccess = node.expression;
|
|
@@ -8134,6 +8199,16 @@ function transformMapCall(node, ctx2, isClientOnly = false, method = "map") {
|
|
|
8134
8199
|
ctx2.loopParams.add(param);
|
|
8135
8200
|
}
|
|
8136
8201
|
if (index) ctx2.loopParams.add(index);
|
|
8202
|
+
const tryTransformRenderableBody = (expr) => {
|
|
8203
|
+
if (!ts11.isBinaryExpression(expr)) return;
|
|
8204
|
+
const op = expr.operatorToken.kind;
|
|
8205
|
+
if (op !== ts11.SyntaxKind.AmpersandAmpersandToken && op !== ts11.SyntaxKind.BarBarToken && op !== ts11.SyntaxKind.QuestionQuestionToken) {
|
|
8206
|
+
return;
|
|
8207
|
+
}
|
|
8208
|
+
if (!containsJsxInExpression(expr) && !callsJsxHelper(expr, ctx2)) return;
|
|
8209
|
+
const transformed = transformJsxExpression(expr, ctx2, isClientOnly);
|
|
8210
|
+
if (transformed) children = [transformed];
|
|
8211
|
+
};
|
|
8137
8212
|
const body = callback.body;
|
|
8138
8213
|
if (ts11.isJsxElement(body) || ts11.isJsxSelfClosingElement(body) || ts11.isJsxFragment(body)) {
|
|
8139
8214
|
const transformed = transformNode(body, ctx2);
|
|
@@ -8156,6 +8231,8 @@ function transformMapCall(node, ctx2, isClientOnly = false, method = "map") {
|
|
|
8156
8231
|
children = [transformConditional(inner, ctx2)];
|
|
8157
8232
|
} else if (method === "flatMap" && ts11.isArrayLiteralExpression(inner)) {
|
|
8158
8233
|
children = transformArrayLiteralChildren(inner, ctx2);
|
|
8234
|
+
} else {
|
|
8235
|
+
tryTransformRenderableBody(inner);
|
|
8159
8236
|
}
|
|
8160
8237
|
} else if (method === "flatMap" && ts11.isArrayLiteralExpression(body)) {
|
|
8161
8238
|
children = transformArrayLiteralChildren(body, ctx2);
|
|
@@ -8203,6 +8280,8 @@ function transformMapCall(node, ctx2, isClientOnly = false, method = "map") {
|
|
|
8203
8280
|
if (method === "flatMap" && children.length === 0) {
|
|
8204
8281
|
flatMapCallback = buildFlatMapCallback(callback, body, ctx2);
|
|
8205
8282
|
}
|
|
8283
|
+
} else {
|
|
8284
|
+
tryTransformRenderableBody(body);
|
|
8206
8285
|
}
|
|
8207
8286
|
if (paramBindings) {
|
|
8208
8287
|
for (const b of paramBindings) ctx2.loopParams.delete(b.name);
|
|
@@ -8217,7 +8296,9 @@ function transformMapCall(node, ctx2, isClientOnly = false, method = "map") {
|
|
|
8217
8296
|
if (ts11.isArrowFunction(node.arguments[0]) && children.length > 0) {
|
|
8218
8297
|
checkLoopKey(node.arguments[0], ctx2, isNested);
|
|
8219
8298
|
}
|
|
8220
|
-
const
|
|
8299
|
+
const itemConditional = children.length > 0 ? loopBodyItemConditional(children) : null;
|
|
8300
|
+
const bodyIsItemConditional = itemConditional !== null;
|
|
8301
|
+
const key = bodyIsItemConditional ? extractItemConditionalKey(itemConditional) : children.length > 0 ? extractLoopKey(children[0]) : null;
|
|
8221
8302
|
let childComponent;
|
|
8222
8303
|
if (children.length === 1 && children[0].type === "component") {
|
|
8223
8304
|
const comp = children[0];
|
|
@@ -8263,6 +8344,7 @@ function transformMapCall(node, ctx2, isClientOnly = false, method = "map") {
|
|
|
8263
8344
|
callsReactiveGetters: callsReactive || void 0,
|
|
8264
8345
|
hasFunctionCalls: hasCalls || void 0,
|
|
8265
8346
|
bodyIsMultiRoot: bodyIsMultiRoot || void 0,
|
|
8347
|
+
bodyIsItemConditional: bodyIsItemConditional || void 0,
|
|
8266
8348
|
childComponent,
|
|
8267
8349
|
nestedComponents,
|
|
8268
8350
|
filterPredicate,
|
|
@@ -9433,7 +9515,8 @@ function collectLoopChildReactiveAttrs(node, ctx2, loopParam, loopParamBindings)
|
|
|
9433
9515
|
const valueStr = attrValueToString(attr.value);
|
|
9434
9516
|
if (!valueStr) continue;
|
|
9435
9517
|
const expanded = expandConstantForReactivity(valueStr, ctx2, attr.freeIdentifiers);
|
|
9436
|
-
|
|
9518
|
+
const reactive = classifyReactivity(expanded.expr, ctx2, loopParam, loopParamBindings, expanded.freeIds).kind !== "none" || attr.callsReactiveGetters || attr.hasFunctionCalls;
|
|
9519
|
+
if (!attr.clientOnly && !reactive) continue;
|
|
9437
9520
|
attrs.push({
|
|
9438
9521
|
childSlotId: el.slotId,
|
|
9439
9522
|
attrName: attr.name,
|
|
@@ -9557,6 +9640,7 @@ function collectInnerLoops(nodes, siblingOffsets, outerLoopParam, ctx2, options)
|
|
|
9557
9640
|
key: n.key,
|
|
9558
9641
|
markerId: n.markerId,
|
|
9559
9642
|
bodyIsMultiRoot: n.bodyIsMultiRoot,
|
|
9643
|
+
bodyIsItemConditional: n.bodyIsItemConditional,
|
|
9560
9644
|
iterationShape: n.iterationShape,
|
|
9561
9645
|
containerSlotId: scope.parentSlotId,
|
|
9562
9646
|
template,
|
|
@@ -9763,6 +9847,7 @@ function collectElements(node, ctx2, siblingOffsets, insideConditional = false)
|
|
|
9763
9847
|
key: l.key,
|
|
9764
9848
|
markerId: l.markerId,
|
|
9765
9849
|
bodyIsMultiRoot: l.bodyIsMultiRoot,
|
|
9850
|
+
bodyIsItemConditional: l.bodyIsItemConditional,
|
|
9766
9851
|
iterationShape: l.iterationShape,
|
|
9767
9852
|
template,
|
|
9768
9853
|
staticItemTemplate,
|
|
@@ -9956,6 +10041,7 @@ function collectBranchLoops(node, ctx2, siblingOffsets) {
|
|
|
9956
10041
|
key: n.key,
|
|
9957
10042
|
markerId: n.markerId,
|
|
9958
10043
|
bodyIsMultiRoot: n.bodyIsMultiRoot,
|
|
10044
|
+
bodyIsItemConditional: n.bodyIsItemConditional,
|
|
9959
10045
|
iterationShape: n.iterationShape,
|
|
9960
10046
|
template: childTemplate,
|
|
9961
10047
|
containerSlotId: containerSlot,
|
|
@@ -10624,6 +10710,7 @@ var init_imports = __esm({
|
|
|
10624
10710
|
"getLoopChildren",
|
|
10625
10711
|
"getLoopNodes",
|
|
10626
10712
|
"mapArray",
|
|
10713
|
+
"mapArrayAnchored",
|
|
10627
10714
|
"createDisposableEffect",
|
|
10628
10715
|
"createComponent",
|
|
10629
10716
|
"renderChild",
|
|
@@ -10647,7 +10734,8 @@ var init_imports = __esm({
|
|
|
10647
10734
|
"qsaChildScopes",
|
|
10648
10735
|
"upsertChildItem",
|
|
10649
10736
|
"__slot",
|
|
10650
|
-
"__bfSlot"
|
|
10737
|
+
"__bfSlot",
|
|
10738
|
+
"__bfText"
|
|
10651
10739
|
];
|
|
10652
10740
|
RUNTIME_MODULE = "@barefootjs/client/runtime";
|
|
10653
10741
|
IMPORT_PLACEHOLDER = "/* __BAREFOOTJS_DOM_IMPORTS__ */";
|
|
@@ -13528,17 +13616,21 @@ function emitDynamicTextUpdates(lines, ctx2) {
|
|
|
13528
13616
|
const conditionalElems = elems.filter((e) => e.insideConditional);
|
|
13529
13617
|
const normalElems = elems.filter((e) => !e.insideConditional);
|
|
13530
13618
|
if (normalElems.length > 0 || conditionalElems.length > 0) {
|
|
13619
|
+
for (const elem of normalElems) {
|
|
13620
|
+
const v = varSlotId(elem.slotId);
|
|
13621
|
+
lines.push(` let __anchor_${v} = _${v}`);
|
|
13622
|
+
}
|
|
13531
13623
|
lines.push(` createEffect(() => {`);
|
|
13532
13624
|
if (normalElems.length > 0) {
|
|
13533
13625
|
lines.push(` const __val = ${expr}`);
|
|
13534
13626
|
for (const elem of normalElems) {
|
|
13535
13627
|
const v = varSlotId(elem.slotId);
|
|
13536
|
-
lines.push(`
|
|
13628
|
+
lines.push(` __anchor_${v} = __bfText(__anchor_${v}, __val)`);
|
|
13537
13629
|
}
|
|
13538
13630
|
for (const elem of conditionalElems) {
|
|
13539
13631
|
const v = varSlotId(elem.slotId);
|
|
13540
13632
|
lines.push(` const [__el_${v}] = $t(__scope, '${elem.slotId}')`);
|
|
13541
|
-
lines.push(`
|
|
13633
|
+
lines.push(` __bfText(__el_${v}, __val)`);
|
|
13542
13634
|
}
|
|
13543
13635
|
} else {
|
|
13544
13636
|
lines.push(` let __val`);
|
|
@@ -13546,7 +13638,7 @@ function emitDynamicTextUpdates(lines, ctx2) {
|
|
|
13546
13638
|
for (const elem of conditionalElems) {
|
|
13547
13639
|
const v = varSlotId(elem.slotId);
|
|
13548
13640
|
lines.push(` const [__el_${v}] = $t(__scope, '${elem.slotId}')`);
|
|
13549
|
-
lines.push(`
|
|
13641
|
+
lines.push(` __bfText(__el_${v}, __val)`);
|
|
13550
13642
|
}
|
|
13551
13643
|
}
|
|
13552
13644
|
lines.push(` })`);
|
|
@@ -14079,8 +14171,14 @@ function stringifyPlainLoop(lines, plan, topIndent = " ") {
|
|
|
14079
14171
|
template,
|
|
14080
14172
|
reactiveEffects,
|
|
14081
14173
|
childRefs,
|
|
14082
|
-
bodyIsMultiRoot
|
|
14174
|
+
bodyIsMultiRoot,
|
|
14175
|
+
anchored,
|
|
14176
|
+
anchorKeyExpr
|
|
14083
14177
|
} = plan;
|
|
14178
|
+
if (anchored) {
|
|
14179
|
+
stringifyAnchoredLoop(lines, plan, topIndent, anchorKeyExpr);
|
|
14180
|
+
return;
|
|
14181
|
+
}
|
|
14084
14182
|
if (reactiveEffects === null && !bodyIsMultiRoot && childRefs.length === 0) {
|
|
14085
14183
|
const unwrapInline = paramUnwrap ? `${paramUnwrap} ` : "";
|
|
14086
14184
|
const preamble = mapPreambleWrapped ? `${mapPreambleWrapped}; ` : "";
|
|
@@ -14107,6 +14205,39 @@ function stringifyPlainLoop(lines, plan, topIndent = " ") {
|
|
|
14107
14205
|
lines.push(`${bodyIndent}return __el`);
|
|
14108
14206
|
lines.push(`${topIndent}}, '${markerId}')`);
|
|
14109
14207
|
}
|
|
14208
|
+
function stringifyAnchoredLoop(lines, plan, topIndent, anchorKeyExpr) {
|
|
14209
|
+
const {
|
|
14210
|
+
containerVar,
|
|
14211
|
+
markerId,
|
|
14212
|
+
arrayExpr,
|
|
14213
|
+
keyFn,
|
|
14214
|
+
paramHead,
|
|
14215
|
+
paramUnwrap,
|
|
14216
|
+
indexParam,
|
|
14217
|
+
mapPreambleWrapped,
|
|
14218
|
+
reactiveEffects
|
|
14219
|
+
} = plan;
|
|
14220
|
+
const condSlot = reactiveEffects?.conditionals[0]?.slotId ?? null;
|
|
14221
|
+
lines.push(`${topIndent}mapArrayAnchored(() => ${arrayExpr}, ${containerVar}, ${keyFn}, (${paramHead}, ${indexParam}, __existing) => {`);
|
|
14222
|
+
const bodyIndent = topIndent + " ";
|
|
14223
|
+
if (paramUnwrap) lines.push(`${bodyIndent}${paramUnwrap}`);
|
|
14224
|
+
if (mapPreambleWrapped) lines.push(`${bodyIndent}${mapPreambleWrapped}`);
|
|
14225
|
+
lines.push(`${bodyIndent}const __anchor = __existing ?? document.createComment(\`bf-loop-i:\${${anchorKeyExpr}}\`)`);
|
|
14226
|
+
lines.push(`${bodyIndent}let __frag = null`);
|
|
14227
|
+
lines.push(`${bodyIndent}if (!__existing) {`);
|
|
14228
|
+
lines.push(`${bodyIndent} __frag = document.createDocumentFragment()`);
|
|
14229
|
+
lines.push(`${bodyIndent} __frag.appendChild(__anchor)`);
|
|
14230
|
+
if (condSlot) {
|
|
14231
|
+
lines.push(`${bodyIndent} __frag.appendChild(document.createComment('bf-cond-start:${condSlot}'))`);
|
|
14232
|
+
lines.push(`${bodyIndent} __frag.appendChild(document.createComment('bf-cond-end:${condSlot}'))`);
|
|
14233
|
+
}
|
|
14234
|
+
lines.push(`${bodyIndent}}`);
|
|
14235
|
+
if (reactiveEffects !== null) {
|
|
14236
|
+
stringifyReactiveEffects(lines, reactiveEffects, { indent: bodyIndent, elVar: "__anchor", bodyIsMultiRoot: false });
|
|
14237
|
+
}
|
|
14238
|
+
lines.push(`${bodyIndent}return __frag ?? __anchor`);
|
|
14239
|
+
lines.push(`${topIndent}}, '${markerId}')`);
|
|
14240
|
+
}
|
|
14110
14241
|
function stringifyStaticLoop(lines, plan) {
|
|
14111
14242
|
const { containerVar, arrayExpr, param, indexParam, childIndexExpr, attrsBySlot, texts, childRefs, csrMaterialize } = plan;
|
|
14112
14243
|
const hasAttrs = attrsBySlot.length > 0;
|
|
@@ -14667,10 +14798,10 @@ function emitArmBody2(lines, body, mode, indent) {
|
|
|
14667
14798
|
}
|
|
14668
14799
|
for (const te of body.textEffects) {
|
|
14669
14800
|
const v = varSlotId(te.slotId);
|
|
14670
|
-
lines.push(`${indent}
|
|
14801
|
+
lines.push(`${indent}let __anchor_${v} = $t(__branchScope, '${te.slotId}')[0]`);
|
|
14671
14802
|
lines.push(`${indent}__disposers.push(createDisposableEffect(() => {`);
|
|
14672
14803
|
lines.push(`${indent} const __val = ${te.expression}`);
|
|
14673
|
-
lines.push(`${indent}
|
|
14804
|
+
lines.push(`${indent} __anchor_${v} = __bfText(__anchor_${v}, __val)`);
|
|
14674
14805
|
lines.push(`${indent}}))`);
|
|
14675
14806
|
}
|
|
14676
14807
|
if (body.loops.length > 0) {
|
|
@@ -14767,6 +14898,9 @@ var init_build_component_loop = __esm({
|
|
|
14767
14898
|
|
|
14768
14899
|
// ../jsx/src/ir-to-client-js/control-flow/plan/build-loop.ts
|
|
14769
14900
|
function buildLoopPlan(elem, opts) {
|
|
14901
|
+
if (elem.bodyIsItemConditional) {
|
|
14902
|
+
return buildPlainLoopPlan(elem);
|
|
14903
|
+
}
|
|
14770
14904
|
if (elem.isStaticArray) {
|
|
14771
14905
|
return buildStaticLoopPlan(elem, opts.unsafeLocalNames);
|
|
14772
14906
|
}
|
|
@@ -14796,7 +14930,15 @@ function buildPlainLoopPlan(elem) {
|
|
|
14796
14930
|
template: elem.template,
|
|
14797
14931
|
reactiveEffects: hasReactive2 ? buildLoopReactiveEffectsPlan(elem) : null,
|
|
14798
14932
|
childRefs: buildChildRefBindings(elem.bindings.refs, elem.param, elem.paramBindings),
|
|
14799
|
-
bodyIsMultiRoot: elem.bodyIsMultiRoot ?? false
|
|
14933
|
+
bodyIsMultiRoot: elem.bodyIsMultiRoot ?? false,
|
|
14934
|
+
anchored: elem.bodyIsItemConditional ?? false,
|
|
14935
|
+
// Fall back to the iteration index when the loop has no key. A whole-item
|
|
14936
|
+
// conditional without a key is a BF023 error, but the emitted client JS
|
|
14937
|
+
// must still parse — an empty `anchorKeyExpr` would produce
|
|
14938
|
+
// `createComment(`bf-loop-i:${}`)` (a SyntaxError that breaks the whole
|
|
14939
|
+
// bundle). `elem.index || '__idx'` matches `indexParam` above, so the
|
|
14940
|
+
// anchor value stays consistent with the renderItem's own index param.
|
|
14941
|
+
anchorKeyExpr: elem.key ? wrap(elem.key) : elem.index || "__idx"
|
|
14800
14942
|
};
|
|
14801
14943
|
}
|
|
14802
14944
|
function buildStaticLoopPlan(elem, unsafeLocalNames) {
|
|
@@ -15888,17 +16030,23 @@ function runSinglePass(source, filePath, startingCounter) {
|
|
|
15888
16030
|
}
|
|
15889
16031
|
function visit3(node) {
|
|
15890
16032
|
if (ts15.isJsxAttribute(node) && node.initializer && ts15.isJsxExpression(node.initializer) && node.initializer.expression) {
|
|
15891
|
-
|
|
15892
|
-
|
|
15893
|
-
if (ts15.isArrowFunction(expr) && arrowBodyContainsJsx(expr)) {
|
|
15894
|
-
const handled = handleInlineArrow(expr);
|
|
15895
|
-
if (handled) {
|
|
15896
|
-
return;
|
|
15897
|
-
}
|
|
16033
|
+
if (tryHandleArrowValue(node.initializer.expression)) {
|
|
16034
|
+
return;
|
|
15898
16035
|
}
|
|
15899
16036
|
}
|
|
16037
|
+
if (ts15.isPropertyAssignment(node) && node.initializer) {
|
|
16038
|
+
if (tryHandleArrowValue(node.initializer)) return;
|
|
16039
|
+
}
|
|
15900
16040
|
ts15.forEachChild(node, visit3);
|
|
15901
16041
|
}
|
|
16042
|
+
function tryHandleArrowValue(initializer) {
|
|
16043
|
+
let expr = initializer;
|
|
16044
|
+
while (ts15.isParenthesizedExpression(expr)) expr = expr.expression;
|
|
16045
|
+
if (ts15.isArrowFunction(expr) && arrowBodyContainsJsx(expr)) {
|
|
16046
|
+
return handleInlineArrow(expr);
|
|
16047
|
+
}
|
|
16048
|
+
return false;
|
|
16049
|
+
}
|
|
15902
16050
|
function handleInlineArrow(arrow) {
|
|
15903
16051
|
const paramNames = collectArrowParamNames(arrow);
|
|
15904
16052
|
const free = collectFreeIdentifiers(arrow);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@barefootjs/cli",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "CLI for agent-driven UI component discovery and scaffolding",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"typescript": "^5.0.0"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
|
-
"@barefootjs/jsx": "0.5.
|
|
34
|
+
"@barefootjs/jsx": "0.5.1",
|
|
35
35
|
"@types/node": "^22.0.0"
|
|
36
36
|
}
|
|
37
37
|
}
|