@barefootjs/vite 0.33.3 → 0.33.4
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 +100 -17
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -3233,6 +3233,9 @@ function renderTemplateAttrPart(attr, attrName, wrap, restSpreadNames) {
|
|
|
3233
3233
|
return "";
|
|
3234
3234
|
}
|
|
3235
3235
|
}
|
|
3236
|
+
function resolvedKeyAttrName(node, loopDepth) {
|
|
3237
|
+
return node.keyAttr ? keyAttrName2(loopDepth) : null;
|
|
3238
|
+
}
|
|
3236
3239
|
function isMergeableAttr(a, ctx) {
|
|
3237
3240
|
if (ctx.honorClientOnly && a.clientOnly)
|
|
3238
3241
|
return false;
|
|
@@ -3409,8 +3412,11 @@ function irToHtmlTemplate(node, restSpreadNames, loopDepth = 0, loopParams, bran
|
|
|
3409
3412
|
if (useMerge && isMergeableAttr(a, mergeCtx)) {
|
|
3410
3413
|
return idx === firstMergeableIdx ? mergeCall : "";
|
|
3411
3414
|
}
|
|
3412
|
-
|
|
3413
|
-
|
|
3415
|
+
if (a.name === "key") {
|
|
3416
|
+
const attrName = resolvedKeyAttrName(node, loopDepth);
|
|
3417
|
+
return attrName ? renderTemplateAttrPart(a, attrName, wrapExpr, restSpreadNames) : "";
|
|
3418
|
+
}
|
|
3419
|
+
return renderTemplateAttrPart(a, toHTMLAttrName(a.name), wrapExpr, restSpreadNames);
|
|
3414
3420
|
}).filter(Boolean);
|
|
3415
3421
|
const hoistedScopeAttr = maybeHoistedScopeAttr(inHoistedChildren, node);
|
|
3416
3422
|
if (hoistedScopeAttr)
|
|
@@ -3535,7 +3541,9 @@ function buildLoopSkeletonTemplate(node, safe) {
|
|
|
3535
3541
|
if (a.name === "dangerouslySetInnerHTML")
|
|
3536
3542
|
return null;
|
|
3537
3543
|
if (a.name === "key") {
|
|
3538
|
-
|
|
3544
|
+
if (resolvedKeyAttrName(node, 0)) {
|
|
3545
|
+
attrParts.push(`${keyAttrName2(0)}=""`);
|
|
3546
|
+
}
|
|
3539
3547
|
continue;
|
|
3540
3548
|
}
|
|
3541
3549
|
const v = a.value;
|
|
@@ -3743,7 +3751,11 @@ function irToPlaceholderTemplate(node, restSpreadNames, loopDepth = 0, loopParam
|
|
|
3743
3751
|
const attrParts = node.attrs.map((a) => {
|
|
3744
3752
|
if (a.clientOnly)
|
|
3745
3753
|
return "";
|
|
3746
|
-
|
|
3754
|
+
if (a.name === "key") {
|
|
3755
|
+
const attrName2 = resolvedKeyAttrName(node, loopDepth);
|
|
3756
|
+
return attrName2 ? renderTemplateAttrPart(a, attrName2, wrapExpr, restSpreadNames) : "";
|
|
3757
|
+
}
|
|
3758
|
+
const attrName = a.name === "..." ? "..." : toHTMLAttrName(a.name);
|
|
3747
3759
|
return renderTemplateAttrPart(a, attrName, wrapExpr, restSpreadNames);
|
|
3748
3760
|
}).filter(Boolean);
|
|
3749
3761
|
if (node.slotId) {
|
|
@@ -4292,7 +4304,27 @@ function generateCsrTemplateWithOpts(node, opts) {
|
|
|
4292
4304
|
return "";
|
|
4293
4305
|
return `\${spreadAttrs(${transformExpr(v.expr, v.templateExpr)})}`;
|
|
4294
4306
|
}
|
|
4295
|
-
|
|
4307
|
+
if (a.name === "key") {
|
|
4308
|
+
const keyName = resolvedKeyAttrName(node, loopDepth);
|
|
4309
|
+
if (!keyName)
|
|
4310
|
+
return "";
|
|
4311
|
+
switch (v.kind) {
|
|
4312
|
+
case "boolean-attr":
|
|
4313
|
+
return keyName;
|
|
4314
|
+
case "literal":
|
|
4315
|
+
return `${keyName}="${escapeHtml(v.value)}"`;
|
|
4316
|
+
case "expression":
|
|
4317
|
+
return templateAttrExpr(keyName, transformExpr(v.expr, v.templateExpr), v.presenceOrUndefined);
|
|
4318
|
+
case "template": {
|
|
4319
|
+
const valueStr = attrValueToString(v, { useTemplate: true });
|
|
4320
|
+
return valueStr ? templateAttrExpr(keyName, transformExpr(valueStr)) : "";
|
|
4321
|
+
}
|
|
4322
|
+
case "boolean-shorthand":
|
|
4323
|
+
case "jsx-children":
|
|
4324
|
+
return "";
|
|
4325
|
+
}
|
|
4326
|
+
}
|
|
4327
|
+
const attrName = toHTMLAttrName(a.name);
|
|
4296
4328
|
switch (v.kind) {
|
|
4297
4329
|
case "boolean-attr":
|
|
4298
4330
|
return attrName;
|
|
@@ -11687,6 +11719,10 @@ function extractLoopKey(node) {
|
|
|
11687
11719
|
return null;
|
|
11688
11720
|
return normalizeKeyExpr(a) === normalizeKeyExpr(b) ? a : null;
|
|
11689
11721
|
}
|
|
11722
|
+
if (node.type === "fragment") {
|
|
11723
|
+
const first = node.children.find((c) => !(c.type === "text" && typeof c.value === "string" && !c.value.trim()));
|
|
11724
|
+
return first ? extractLoopKey(first) : null;
|
|
11725
|
+
}
|
|
11690
11726
|
return null;
|
|
11691
11727
|
}
|
|
11692
11728
|
function keyAttrValueToExpr(v) {
|
|
@@ -11877,7 +11913,7 @@ function leafIsWirelessElement(el) {
|
|
|
11877
11913
|
}
|
|
11878
11914
|
if (ts13.isJsxAttribute(attr)) {
|
|
11879
11915
|
const name = attr.name.getText();
|
|
11880
|
-
if (
|
|
11916
|
+
if (isEventHandlerAttrName(name)) {
|
|
11881
11917
|
ok = false;
|
|
11882
11918
|
return;
|
|
11883
11919
|
}
|
|
@@ -11933,6 +11969,12 @@ function applyLoopKeyAttr(node, name, value) {
|
|
|
11933
11969
|
if (node.type === "conditional") {
|
|
11934
11970
|
applyLoopKeyAttr(node.whenTrue, name, value);
|
|
11935
11971
|
applyLoopKeyAttr(node.whenFalse, name, value);
|
|
11972
|
+
return;
|
|
11973
|
+
}
|
|
11974
|
+
if (node.type === "fragment") {
|
|
11975
|
+
const first = node.children.find((c) => !(c.type === "text" && typeof c.value === "string" && !c.value.trim()));
|
|
11976
|
+
if (first)
|
|
11977
|
+
applyLoopKeyAttr(first, name, value);
|
|
11936
11978
|
}
|
|
11937
11979
|
}
|
|
11938
11980
|
function loopBodyItemConditional(children) {
|
|
@@ -12165,7 +12207,7 @@ function transformMapCall(node, ctx, isClientOnly = false, method = "map") {
|
|
|
12165
12207
|
children = [foldMultiReturnBranches(multiReturn, ctx, loc, ctx.getJS)];
|
|
12166
12208
|
const pre = multiReturn.preamble ?? [];
|
|
12167
12209
|
if (pre.length > 0) {
|
|
12168
|
-
preamble = preambleFromValueStatements(pre, ctx);
|
|
12210
|
+
preamble = preambleFromValueStatements(pre, ctx, body.statements);
|
|
12169
12211
|
if (!preamble.declarations && !isClientOnly && !(ctx.analyzer.acceptsCallbackBody?.("map") ?? false)) {
|
|
12170
12212
|
ctx.analyzer.errors.push(createError(ErrorCodes.UNSUPPORTED_JSX_PATTERN, loc, {
|
|
12171
12213
|
message: "A .map() callback body with a preamble before its branches cannot be " + "lowered to a template: the preamble is not a sequence of value " + "declarations, so this backend has no per-row local to carry into the " + "branches.",
|
|
@@ -12252,7 +12294,7 @@ function transformMapCall(node, ctx, isClientOnly = false, method = "map") {
|
|
|
12252
12294
|
valueStmts.push(stmt);
|
|
12253
12295
|
}
|
|
12254
12296
|
if (valueStmts.length > 0) {
|
|
12255
|
-
preamble = preambleFromValueStatements(valueStmts, ctx);
|
|
12297
|
+
preamble = preambleFromValueStatements(valueStmts, ctx, body.statements);
|
|
12256
12298
|
if (!preamble.declarations && !isClientOnly && !(ctx.analyzer.acceptsCallbackBody?.("map") ?? false)) {
|
|
12257
12299
|
ctx.analyzer.errors.push(createError(ErrorCodes.UNSUPPORTED_JSX_PATTERN, getSourceLocation(body, ctx.sourceFile, ctx.filePath), {
|
|
12258
12300
|
message: "A .map() callback preamble that is not a sequence of value " + "declarations cannot be lowered to a template: this backend can " + "declare a per-row local, but cannot run arbitrary statements per row.",
|
|
@@ -12318,11 +12360,11 @@ function transformMapCall(node, ctx, isClientOnly = false, method = "map") {
|
|
|
12318
12360
|
const bodyIsItemConditional = itemConditional !== null;
|
|
12319
12361
|
const key = bodyIsItemConditional ? extractItemConditionalKey(itemConditional) : children.length > 0 ? extractLoopKey(children[0]) : null;
|
|
12320
12362
|
if (key !== null) {
|
|
12321
|
-
const
|
|
12363
|
+
const resolvedKeyAttrName2 = keyAttrName(depth);
|
|
12322
12364
|
if (bodyIsItemConditional) {
|
|
12323
|
-
applyLoopKeyAttr(itemConditional,
|
|
12365
|
+
applyLoopKeyAttr(itemConditional, resolvedKeyAttrName2, key);
|
|
12324
12366
|
} else if (children.length > 0) {
|
|
12325
|
-
applyLoopKeyAttr(children[0],
|
|
12367
|
+
applyLoopKeyAttr(children[0], resolvedKeyAttrName2, key);
|
|
12326
12368
|
}
|
|
12327
12369
|
}
|
|
12328
12370
|
const declaredNameSet = preamble && preamble.declaredNames.length > 0 ? new Set(preamble.declaredNames) : undefined;
|
|
@@ -12715,7 +12757,7 @@ function computePreambleReactiveNames(statements, ctx) {
|
|
|
12715
12757
|
}
|
|
12716
12758
|
return reactiveNames;
|
|
12717
12759
|
}
|
|
12718
|
-
function preambleFromValueStatements(statements, ctx) {
|
|
12760
|
+
function preambleFromValueStatements(statements, ctx, bodyStatements) {
|
|
12719
12761
|
const segments = [];
|
|
12720
12762
|
const typedParts = [];
|
|
12721
12763
|
const declared = new Set;
|
|
@@ -12735,11 +12777,11 @@ function preambleFromValueStatements(statements, ctx) {
|
|
|
12735
12777
|
ssrText: tsxSourceText(typedParts.join(" ")),
|
|
12736
12778
|
declaredNames: [...declared],
|
|
12737
12779
|
builderNames: [],
|
|
12738
|
-
declarations: neutralPreambleDeclarations(statements, ctx) ?? undefined,
|
|
12780
|
+
declarations: neutralPreambleDeclarations(statements, ctx, bodyStatements) ?? undefined,
|
|
12739
12781
|
reactiveNames: reactiveNames.size > 0 ? [...reactiveNames] : undefined
|
|
12740
12782
|
};
|
|
12741
12783
|
}
|
|
12742
|
-
function neutralPreambleDeclarations(statements, ctx) {
|
|
12784
|
+
function neutralPreambleDeclarations(statements, ctx, bodyStatements) {
|
|
12743
12785
|
const out = [];
|
|
12744
12786
|
for (const stmt of statements) {
|
|
12745
12787
|
if (!ts13.isVariableStatement(stmt))
|
|
@@ -12749,6 +12791,11 @@ function neutralPreambleDeclarations(statements, ctx) {
|
|
|
12749
12791
|
return null;
|
|
12750
12792
|
if (!decl.initializer)
|
|
12751
12793
|
return null;
|
|
12794
|
+
if (isFunctionLiteral(decl.initializer)) {
|
|
12795
|
+
if (everyReadIsEventHandlerPropValue(decl.name.text, bodyStatements))
|
|
12796
|
+
continue;
|
|
12797
|
+
return null;
|
|
12798
|
+
}
|
|
12752
12799
|
const valueParsed = tsNodeToParsedExpr(decl.initializer);
|
|
12753
12800
|
if (!isSupported(valueParsed).supported)
|
|
12754
12801
|
return null;
|
|
@@ -12759,7 +12806,30 @@ function neutralPreambleDeclarations(statements, ctx) {
|
|
|
12759
12806
|
});
|
|
12760
12807
|
}
|
|
12761
12808
|
}
|
|
12762
|
-
return out
|
|
12809
|
+
return out;
|
|
12810
|
+
}
|
|
12811
|
+
function isFunctionLiteral(node) {
|
|
12812
|
+
return ts13.isArrowFunction(node) || ts13.isFunctionExpression(node);
|
|
12813
|
+
}
|
|
12814
|
+
function everyReadIsEventHandlerPropValue(name, bodyStatements) {
|
|
12815
|
+
const findDisallowedRead = (node) => {
|
|
12816
|
+
if (ts13.isIdentifier(node) && node.text === name) {
|
|
12817
|
+
const isBindingName = ts13.isVariableDeclaration(node.parent) && node.parent.name === node;
|
|
12818
|
+
const isPropertyName = ts13.isPropertyAccessExpression(node.parent) && node.parent.name === node;
|
|
12819
|
+
if (!isBindingName && !isPropertyName) {
|
|
12820
|
+
const jsxExpr = node.parent;
|
|
12821
|
+
const attr = jsxExpr.parent;
|
|
12822
|
+
const isEventHandlerAttrValue = ts13.isJsxExpression(jsxExpr) && ts13.isJsxAttribute(attr) && attr.initializer === jsxExpr && ts13.isIdentifier(attr.name) && isEventHandlerAttrName(attr.name.text);
|
|
12823
|
+
if (!isEventHandlerAttrValue)
|
|
12824
|
+
return true;
|
|
12825
|
+
}
|
|
12826
|
+
}
|
|
12827
|
+
return ts13.forEachChild(node, findDisallowedRead);
|
|
12828
|
+
};
|
|
12829
|
+
return !bodyStatements.some(findDisallowedRead);
|
|
12830
|
+
}
|
|
12831
|
+
function isEventHandlerAttrName(name) {
|
|
12832
|
+
return /^on[A-Z]/.test(name);
|
|
12763
12833
|
}
|
|
12764
12834
|
function trimPreambleSegments(segments) {
|
|
12765
12835
|
const last = segments[segments.length - 1];
|
|
@@ -12956,7 +13026,7 @@ function processAttributes(attributes, ctx) {
|
|
|
12956
13026
|
}
|
|
12957
13027
|
continue;
|
|
12958
13028
|
}
|
|
12959
|
-
if (
|
|
13029
|
+
if (isEventHandlerAttrName(rawName)) {
|
|
12960
13030
|
if (attr.initializer && ts13.isJsxExpression(attr.initializer) && attr.initializer.expression) {
|
|
12961
13031
|
const eventName = rawName.slice(2).toLowerCase();
|
|
12962
13032
|
reportJsxBranchLocalInCallback(attr.initializer.expression, ctx);
|
|
@@ -15611,6 +15681,8 @@ function buildReferencesGraph(ctx, irRoot) {
|
|
|
15611
15681
|
}
|
|
15612
15682
|
for (const ev of el.events)
|
|
15613
15683
|
addExprEdges(ROOT_SOURCE, ev.handler, "init-body");
|
|
15684
|
+
if (el.ref)
|
|
15685
|
+
addExprEdges(ROOT_SOURCE, el.ref, "init-body");
|
|
15614
15686
|
descend();
|
|
15615
15687
|
},
|
|
15616
15688
|
component: ({ node: c, descend, descendJsxChildren }) => {
|
|
@@ -20519,12 +20591,15 @@ function stringifyComponentLoop(lines, plan) {
|
|
|
20519
20591
|
keyExpr,
|
|
20520
20592
|
nestedComps,
|
|
20521
20593
|
childConditionalEffects,
|
|
20522
|
-
profileLoopId
|
|
20594
|
+
profileLoopId,
|
|
20595
|
+
mapPreambleWrapped
|
|
20523
20596
|
} = plan;
|
|
20524
20597
|
const loopBfId = profileLoopId ? `, ${JSON.stringify(profileLoopId)}` : "";
|
|
20525
20598
|
lines.push(` mapArray(() => ${arrayExpr}, ${containerVar}, ${keyFn}, (${paramHead}, ${indexParam}, __existing) => {`);
|
|
20526
20599
|
if (paramUnwrap)
|
|
20527
20600
|
lines.push(` ${paramUnwrap}`);
|
|
20601
|
+
if (mapPreambleWrapped)
|
|
20602
|
+
lines.push(` ${mapPreambleWrapped}`);
|
|
20528
20603
|
const scopedComp = nameForRegistryRef(componentName);
|
|
20529
20604
|
if (nestedComps.length === 0) {
|
|
20530
20605
|
lines.push(` if (__existing) { initChild('${scopedComp}', __existing, ${componentPropsExpr}); return __existing }`);
|
|
@@ -21640,6 +21715,12 @@ function buildComponentLoopPlan(elem, profileComponentName) {
|
|
|
21640
21715
|
const propsExpr = buildComponentPropsExpr2(elem.childComponent, elem.param);
|
|
21641
21716
|
const keyExpr = wrapLoopParamAsAccessor(elem.key || "__idx", elem.param, elem.paramBindings);
|
|
21642
21717
|
const { head: paramHead, unwrap: paramUnwrap } = destructureLoopParam(elem.param, elem.paramBindings);
|
|
21718
|
+
const mapPreambleWrapped = elem.preamble ? renderPreamble(elem.preamble, {
|
|
21719
|
+
transformJs: (text) => wrapLoopParamAsAccessor(text, elem.param, elem.paramBindings),
|
|
21720
|
+
renderLeaf: () => {
|
|
21721
|
+
internalInvariant(false, "component-root loop received a JSX-bearing preamble — Phase 1 should have refused it");
|
|
21722
|
+
}
|
|
21723
|
+
}) : "";
|
|
21643
21724
|
const outerNestedComps = (elem.nestedComponents ?? []).filter((c) => !c.loopDepth);
|
|
21644
21725
|
const nestedComps = outerNestedComps.map((comp) => {
|
|
21645
21726
|
const isTextOnly = comp.children?.length ? comp.children.every((c) => c.type === "expression" || c.type === "text" || isTextOnlyConditional(c)) : false;
|
|
@@ -21657,6 +21738,7 @@ function buildComponentLoopPlan(elem, profileComponentName) {
|
|
|
21657
21738
|
return {
|
|
21658
21739
|
kind: "component",
|
|
21659
21740
|
rowConstruction: "dom-ops",
|
|
21741
|
+
mapPreambleWrapped,
|
|
21660
21742
|
containerVar: `_${varSlotId(elem.slotId)}`,
|
|
21661
21743
|
markerId: elem.markerId,
|
|
21662
21744
|
arrayExpr: buildChainedArrayExpr(elem),
|
|
@@ -21839,6 +21921,7 @@ function emitLoopUpdates(lines, ctx, unsafeLocalNames) {
|
|
|
21839
21921
|
lazyScope
|
|
21840
21922
|
});
|
|
21841
21923
|
internalInvariant(!(elem.preamble && elem.preamble.builderNames.length > 0 && plan.rowConstruction === "dom-ops"), `loop variant '${plan.kind}' declares dom-ops row construction but received a JSX-bearing preamble — add a Phase-1 refusal (or wire renderPreamble support) for this shape`);
|
|
21924
|
+
internalInvariant(!(elem.preamble && elem.preamble.declaredNames.length > 0 && ("mapPreambleWrapped" in plan) && plan.mapPreambleWrapped === ""), `loop variant '${plan.kind}' has a preamble with declared names (${elem.preamble?.declaredNames.join(", ")}) but its plan's mapPreambleWrapped is empty — wire it up or the emitted call site references a name nothing declares`);
|
|
21842
21925
|
stringifyLoop(lines, plan);
|
|
21843
21926
|
emitLoopEventDelegation(lines, elem, plan.kind, ctx.profile ? ctx.componentName : undefined);
|
|
21844
21927
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@barefootjs/vite",
|
|
3
|
-
"version": "0.33.
|
|
3
|
+
"version": "0.33.4",
|
|
4
4
|
"description": "Vite plugin for BarefootJS: Vite/Rollup owns bundling, hashing, chunking, tree-shaking and minification of client assets, BarefootJS keeps only the JSX to (template, client JS) compile",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -38,17 +38,17 @@
|
|
|
38
38
|
"directory": "packages/vite"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@barefootjs/shared": "0.33.
|
|
41
|
+
"@barefootjs/shared": "0.33.4"
|
|
42
42
|
},
|
|
43
43
|
"peerDependencies": {
|
|
44
44
|
"@barefootjs/jsx": ">=0.2.0",
|
|
45
45
|
"vite": "^6.0.0"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
|
-
"@barefootjs/client": "0.33.
|
|
49
|
-
"@barefootjs/go-template": "0.33.
|
|
50
|
-
"@barefootjs/hono": "0.33.
|
|
51
|
-
"@barefootjs/jsx": "0.33.
|
|
48
|
+
"@barefootjs/client": "0.33.4",
|
|
49
|
+
"@barefootjs/go-template": "0.33.4",
|
|
50
|
+
"@barefootjs/hono": "0.33.4",
|
|
51
|
+
"@barefootjs/jsx": "0.33.4",
|
|
52
52
|
"typescript": "^5.0.0",
|
|
53
53
|
"vite": "^6.0.0"
|
|
54
54
|
}
|