@barefootjs/rust 0.35.5 → 0.35.6

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.
@@ -188648,11 +188648,11 @@ ${whenTrue}
188648
188648
  const arrayName = loop.array.trim();
188649
188649
  if (staticArray === null && /^[A-Za-z_$][\w$]*$/.test(arrayName)) {
188650
188650
  const arrayConst = (this.localConstants ?? []).find((c) => c.name === arrayName);
188651
- if (arrayConst && !arrayConst.isModule && this._resolveLiteralConst(arrayName) === null) {
188651
+ if (arrayConst && this._resolveLiteralConst(arrayName) === null) {
188652
188652
  this.errors.push({
188653
188653
  code: "BF101",
188654
188654
  severity: "error",
188655
- message: `Loop array \`${arrayName}\` is a local computed value (\`${arrayConst.value}\`) that the MiniJinja adapter cannot bind as a template variable — only numeric/string-literal locals inline at their use site.`,
188655
+ message: `Loop array \`${arrayName}\` is a const (module- or function-scope) computed value (\`${arrayConst.value}\`) that the MiniJinja adapter cannot bind as a template variable — only numeric/string-literal locals inline at their use site.`,
188656
188656
  loc: loop.loc ?? { file: this.componentName + ".tsx", start: { line: 1, column: 0 }, end: { line: 1, column: 0 } },
188657
188657
  suggestion: {
188658
188658
  message: "Pre-compute the array server-side and pass it as a prop, or mark the loop position as @client-only so it runs in JS on the client.",
@@ -1 +1 @@
1
- {"version":3,"file":"minijinja-adapter.d.ts","sourceRoot":"","sources":["../../src/adapter/minijinja-adapter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"minijinja-adapter.d.ts","sourceRoot":"","sources":["../../src/adapter/minijinja-adapter.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"conformance-pins.d.ts","sourceRoot":"","sources":["../src/conformance-pins.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEtD,eAAO,MAAM,eAAe,EAAE,eAwE7B,CAAA"}
1
+ {"version":3,"file":"conformance-pins.d.ts","sourceRoot":"","sources":["../src/conformance-pins.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEtD,eAAO,MAAM,eAAe,EAAE,eAmF7B,CAAA"}
package/dist/index.js CHANGED
@@ -188648,11 +188648,11 @@ ${whenTrue}
188648
188648
  const arrayName = loop.array.trim();
188649
188649
  if (staticArray === null && /^[A-Za-z_$][\w$]*$/.test(arrayName)) {
188650
188650
  const arrayConst = (this.localConstants ?? []).find((c) => c.name === arrayName);
188651
- if (arrayConst && !arrayConst.isModule && this._resolveLiteralConst(arrayName) === null) {
188651
+ if (arrayConst && this._resolveLiteralConst(arrayName) === null) {
188652
188652
  this.errors.push({
188653
188653
  code: "BF101",
188654
188654
  severity: "error",
188655
- message: `Loop array \`${arrayName}\` is a local computed value (\`${arrayConst.value}\`) that the MiniJinja adapter cannot bind as a template variable — only numeric/string-literal locals inline at their use site.`,
188655
+ message: `Loop array \`${arrayName}\` is a const (module- or function-scope) computed value (\`${arrayConst.value}\`) that the MiniJinja adapter cannot bind as a template variable — only numeric/string-literal locals inline at their use site.`,
188656
188656
  loc: loop.loc ?? { file: this.componentName + ".tsx", start: { line: 1, column: 0 }, end: { line: 1, column: 0 } },
188657
188657
  suggestion: {
188658
188658
  message: "Pre-compute the array server-side and pass it as a prop, or mark the loop position as @client-only so it runs in JS on the client.",
@@ -189241,6 +189241,13 @@ var conformancePins = {
189241
189241
  issue: "https://github.com/piconic-ai/barefootjs/issues/2321"
189242
189242
  }
189243
189243
  ],
189244
+ "module-const-loop-source-computed": [
189245
+ {
189246
+ code: "BF101",
189247
+ severity: "error",
189248
+ issue: "https://github.com/piconic-ai/barefootjs/issues/2946"
189249
+ }
189250
+ ],
189244
189251
  "filter-nested-callback-predicate": [
189245
189252
  { code: "BF101", severity: "error", issue: "https://github.com/piconic-ai/barefootjs/issues/2320" }
189246
189253
  ],
@@ -1 +1 @@
1
- {"version":3,"file":"render-divergences.d.ts","sourceRoot":"","sources":["../src/render-divergences.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAQxD,eAAO,MAAM,iBAAiB,EAAE,iBAAsB,CAAA"}
1
+ {"version":3,"file":"render-divergences.d.ts","sourceRoot":"","sources":["../src/render-divergences.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAcxD,eAAO,MAAM,iBAAiB,EAAE,iBAAsB,CAAA"}
package/dist/vite.js CHANGED
@@ -5,10 +5,10 @@ import { barefoot as coreBarefoot } from "@barefootjs/vite";
5
5
  import { devModuleUrl, loadManifest, resolveDevOrigin, resolveScriptAssets, toPosixRelative } from "@barefootjs/vite";
6
6
 
7
7
  // ../jsx/src/compiler.ts
8
- import ts25 from "typescript";
8
+ import ts26 from "typescript";
9
9
 
10
10
  // ../jsx/src/analyzer.ts
11
- import ts11 from "typescript";
11
+ import ts14 from "typescript";
12
12
 
13
13
  // ../jsx/src/expression-parser.ts
14
14
  import ts from "typescript";
@@ -2039,7 +2039,7 @@ function identifierPath(callee) {
2039
2039
  }
2040
2040
 
2041
2041
  // ../jsx/src/prop-rewrite.ts
2042
- import ts7 from "typescript";
2042
+ import ts10 from "typescript";
2043
2043
 
2044
2044
  // ../jsx/src/ir-to-client-js/utils.ts
2045
2045
  import ts3 from "typescript";
@@ -2189,6 +2189,17 @@ function resolveJsxChildrenProp(props) {
2189
2189
  return [];
2190
2190
  return prop.value.children ?? [];
2191
2191
  }
2192
+ // ../jsx/src/ir-to-client-js/utils.ts
2193
+ var NON_BUBBLING_EVENTS = new Set([
2194
+ "blur",
2195
+ "focus",
2196
+ "load",
2197
+ "unload",
2198
+ "mouseenter",
2199
+ "mouseleave",
2200
+ "pointerenter",
2201
+ "pointerleave"
2202
+ ]);
2192
2203
  // ../jsx/src/ir-to-client-js/component-scope.ts
2193
2204
  function buildImportAliasMap(imports) {
2194
2205
  const aliases = new Map;
@@ -2205,16 +2216,71 @@ function buildImportAliasMap(imports) {
2205
2216
  }
2206
2217
 
2207
2218
  // ../jsx/src/ir-to-client-js/csr-substitute.ts
2208
- import ts5 from "typescript";
2219
+ import ts8 from "typescript";
2209
2220
 
2210
2221
  // ../jsx/src/props-binding.ts
2222
+ import ts7 from "typescript";
2223
+
2224
+ // ../jsx/src/ir-to-client-js/walk-prop-accesses.ts
2211
2225
  import ts4 from "typescript";
2226
+
2227
+ // ../jsx/src/ir-to-client-js/identifiers.ts
2228
+ var KEYWORDS_AND_GLOBALS = new Set([
2229
+ "true",
2230
+ "false",
2231
+ "null",
2232
+ "undefined",
2233
+ "this",
2234
+ "const",
2235
+ "let",
2236
+ "var",
2237
+ "function",
2238
+ "return",
2239
+ "if",
2240
+ "else",
2241
+ "for",
2242
+ "while",
2243
+ "do",
2244
+ "switch",
2245
+ "case",
2246
+ "break",
2247
+ "continue",
2248
+ "new",
2249
+ "typeof",
2250
+ "instanceof",
2251
+ "void",
2252
+ "delete",
2253
+ "console",
2254
+ "window",
2255
+ "document",
2256
+ "Math",
2257
+ "String",
2258
+ "Number",
2259
+ "Array",
2260
+ "Object",
2261
+ "Boolean",
2262
+ "Date",
2263
+ "JSON",
2264
+ "Promise",
2265
+ "setTimeout",
2266
+ "setInterval",
2267
+ "clearTimeout",
2268
+ "clearInterval"
2269
+ ]);
2270
+
2271
+ // ../jsx/src/ir-to-client-js/prune-unused-prop-extractions.ts
2272
+ import ts6 from "typescript";
2273
+
2274
+ // ../jsx/src/value-references.ts
2275
+ import ts5 from "typescript";
2276
+
2277
+ // ../jsx/src/props-binding.ts
2212
2278
  function isIdentifierName(key) {
2213
2279
  if (key.length === 0)
2214
2280
  return false;
2215
2281
  for (let i = 0;i < key.length; ) {
2216
2282
  const cp = key.codePointAt(i);
2217
- const ok = i === 0 ? ts4.isIdentifierStart(cp, ts4.ScriptTarget.Latest) : ts4.isIdentifierPart(cp, ts4.ScriptTarget.Latest);
2283
+ const ok = i === 0 ? ts7.isIdentifierStart(cp, ts7.ScriptTarget.Latest) : ts7.isIdentifierPart(cp, ts7.ScriptTarget.Latest);
2218
2284
  if (!ok)
2219
2285
  return false;
2220
2286
  i += cp > 65535 ? 2 : 1;
@@ -2233,16 +2299,16 @@ var EMPTY_SET = new Set;
2233
2299
  function extractFreeIdentifiersFromText(text) {
2234
2300
  if (!text || text.trim().length === 0)
2235
2301
  return new Set;
2236
- const sf = ts5.createSourceFile("__free_ids__.ts", `(${text});`, ts5.ScriptTarget.Latest, true, ts5.ScriptKind.TS);
2302
+ const sf = ts8.createSourceFile("__free_ids__.ts", `(${text});`, ts8.ScriptTarget.Latest, true, ts8.ScriptKind.TS);
2237
2303
  const stmt = sf.statements[0];
2238
- if (!stmt || !ts5.isExpressionStatement(stmt))
2304
+ if (!stmt || !ts8.isExpressionStatement(stmt))
2239
2305
  return new Set;
2240
- const expr = ts5.isParenthesizedExpression(stmt.expression) ? stmt.expression.expression : stmt.expression;
2306
+ const expr = ts8.isParenthesizedExpression(stmt.expression) ? stmt.expression.expression : stmt.expression;
2241
2307
  return extractFreeIdentifiersFromNode(expr);
2242
2308
  }
2243
2309
 
2244
2310
  // ../jsx/src/ir-to-client-js/rewrite-props-object.ts
2245
- import ts6 from "typescript";
2311
+ import ts9 from "typescript";
2246
2312
 
2247
2313
  // ../jsx/src/adapters/child-scope.ts
2248
2314
  function derivesScopeFromSlot(comp) {
@@ -2389,17 +2455,17 @@ function freshCounters() {
2389
2455
  }
2390
2456
 
2391
2457
  // ../jsx/src/analyzer-context.ts
2392
- import ts10 from "typescript";
2458
+ import ts13 from "typescript";
2393
2459
 
2394
2460
  // ../jsx/src/strip-types.ts
2395
- import ts8 from "typescript";
2461
+ import ts11 from "typescript";
2396
2462
 
2397
2463
  // ../jsx/src/reactivity-checker.ts
2398
- import ts9 from "typescript";
2464
+ import ts12 from "typescript";
2399
2465
 
2400
2466
  // ../jsx/src/analyzer-context.ts
2401
- var _typePrinter = ts10.createPrinter({ removeComments: true, omitTrailingSemicolon: true });
2402
- var _blankTypeSourceFile = ts10.createSourceFile("__bf_types__.ts", "", ts10.ScriptTarget.Latest);
2467
+ var _typePrinter = ts13.createPrinter({ removeComments: true, omitTrailingSemicolon: true });
2468
+ var _blankTypeSourceFile = ts13.createSourceFile("__bf_types__.ts", "", ts13.ScriptTarget.Latest);
2403
2469
 
2404
2470
  // ../jsx/src/errors.ts
2405
2471
  var ErrorCodes = {
@@ -2412,7 +2478,6 @@ var ErrorCodes = {
2412
2478
  MISSING_KEY_IN_NESTED_LIST: "BF024",
2413
2479
  UNSUPPORTED_DESTRUCTURE_REST: "BF025",
2414
2480
  RETURN_VALUE_NOT_JSX: "BF027",
2415
- PROPS_DESTRUCTURING: "BF043",
2416
2481
  SIGNAL_GETTER_NOT_CALLED: "BF044",
2417
2482
  JSX_IN_LOCAL_FUNCTION: "BF045",
2418
2483
  COMPONENT_REQUIRED_PROP_MISSING: "BF046",
@@ -2445,7 +2510,6 @@ var errorMessages = {
2445
2510
  [ErrorCodes.MISSING_KEY_IN_NESTED_LIST]: "Nested .map() loop requires key attribute for event delegation. Add a key prop to elements in the inner loop",
2446
2511
  [ErrorCodes.UNSUPPORTED_DESTRUCTURE_REST]: "Computed property key in .map() callback destructure is not supported. Rewrite the callback to destructure explicit bindings (e.g., `({ a, b }) => ...`) so the compiler can rewrite references to per-item signal accessors.",
2447
2512
  [ErrorCodes.RETURN_VALUE_NOT_JSX]: "Component's return value is not recognized as JSX — return the JSX expression directly instead of binding it to a local variable first.",
2448
- [ErrorCodes.PROPS_DESTRUCTURING]: "Props destructuring in function parameters breaks reactivity. Use props object directly.",
2449
2513
  [ErrorCodes.SIGNAL_GETTER_NOT_CALLED]: "Signal/memo getter passed without calling it. Use getter() to read the value.",
2450
2514
  [ErrorCodes.JSX_IN_LOCAL_FUNCTION]: "Local function returns JSX but cannot be inlined. Extract it as a top-level PascalCase component or use a single return statement.",
2451
2515
  [ErrorCodes.COMPONENT_REQUIRED_PROP_MISSING]: "Built-in component is missing a required prop.",
@@ -2647,46 +2711,46 @@ function extractFreeIdentifiersFromNode(node) {
2647
2711
  const ids = new Set;
2648
2712
  const boundNames = new Set;
2649
2713
  function addBindingNames(name, out) {
2650
- if (ts11.isIdentifier(name))
2714
+ if (ts14.isIdentifier(name))
2651
2715
  out.push(name.text);
2652
- else if (ts11.isObjectBindingPattern(name))
2716
+ else if (ts14.isObjectBindingPattern(name))
2653
2717
  name.elements.forEach((e) => addBindingNames(e.name, out));
2654
- else if (ts11.isArrayBindingPattern(name))
2718
+ else if (ts14.isArrayBindingPattern(name))
2655
2719
  name.elements.forEach((e) => {
2656
- if (!ts11.isOmittedExpression(e))
2720
+ if (!ts14.isOmittedExpression(e))
2657
2721
  addBindingNames(e.name, out);
2658
2722
  });
2659
2723
  }
2660
2724
  function visit(n) {
2661
- if (ts11.isTypeNode(n))
2725
+ if (ts14.isTypeNode(n))
2662
2726
  return;
2663
- if (ts11.isIdentifier(n)) {
2727
+ if (ts14.isIdentifier(n)) {
2664
2728
  const parent = n.parent;
2665
- if (parent && ts11.isPropertyAccessExpression(parent) && parent.name === n)
2729
+ if (parent && ts14.isPropertyAccessExpression(parent) && parent.name === n)
2666
2730
  return;
2667
- if (parent && ts11.isPropertyAssignment(parent) && parent.name === n)
2731
+ if (parent && ts14.isPropertyAssignment(parent) && parent.name === n)
2668
2732
  return;
2669
- if (parent && ts11.isParameter(parent) && parent.name === n)
2733
+ if (parent && ts14.isParameter(parent) && parent.name === n)
2670
2734
  return;
2671
- if (parent && ts11.isVariableDeclaration(parent) && parent.name === n)
2735
+ if (parent && ts14.isVariableDeclaration(parent) && parent.name === n)
2672
2736
  return;
2673
2737
  if (boundNames.has(n.text))
2674
2738
  return;
2675
2739
  ids.add(n.text);
2676
2740
  return;
2677
2741
  }
2678
- if (ts11.isArrowFunction(n)) {
2742
+ if (ts14.isArrowFunction(n)) {
2679
2743
  const params = [];
2680
2744
  for (const p of n.parameters)
2681
2745
  addBindingNames(p.name, params);
2682
2746
  for (const name of params)
2683
2747
  boundNames.add(name);
2684
- ts11.forEachChild(n, visit);
2748
+ ts14.forEachChild(n, visit);
2685
2749
  for (const name of params)
2686
2750
  boundNames.delete(name);
2687
2751
  return;
2688
2752
  }
2689
- ts11.forEachChild(n, visit);
2753
+ ts14.forEachChild(n, visit);
2690
2754
  }
2691
2755
  visit(node);
2692
2756
  return ids;
@@ -2710,7 +2774,7 @@ var REACTIVE_PRIMITIVES = new Set([
2710
2774
  ]);
2711
2775
 
2712
2776
  // ../jsx/src/jsx-to-ir.ts
2713
- import ts14 from "typescript";
2777
+ import ts17 from "typescript";
2714
2778
 
2715
2779
  // ../jsx/src/types.ts
2716
2780
  var SCOPE_FORBIDDEN = {
@@ -2760,7 +2824,7 @@ function preambleAnalysisTemplateText(p) {
2760
2824
  }
2761
2825
 
2762
2826
  // ../jsx/src/module-exports.ts
2763
- import ts12 from "typescript";
2827
+ import ts15 from "typescript";
2764
2828
  function formatParamWithType(p) {
2765
2829
  const rest = p.isRest ? "..." : "";
2766
2830
  const optional = p.optional ? "?" : "";
@@ -2795,21 +2859,21 @@ function findAssignedNames(bodyText, candidates) {
2795
2859
  const assigned = new Set;
2796
2860
  if (candidates.size === 0)
2797
2861
  return assigned;
2798
- const sf = ts12.createSourceFile("bf-assignment-scan.tsx", bodyText, ts12.ScriptTarget.Latest, false, ts12.ScriptKind.TSX);
2862
+ const sf = ts15.createSourceFile("bf-assignment-scan.tsx", bodyText, ts15.ScriptTarget.Latest, false, ts15.ScriptKind.TSX);
2799
2863
  const record = (target) => {
2800
- if (ts12.isIdentifier(target) && candidates.has(target.text)) {
2864
+ if (ts15.isIdentifier(target) && candidates.has(target.text)) {
2801
2865
  assigned.add(target.text);
2802
2866
  }
2803
2867
  };
2804
2868
  const visit = (node) => {
2805
- if (ts12.isBinaryExpression(node) && isAssignmentOperator(node.operatorToken.kind)) {
2869
+ if (ts15.isBinaryExpression(node) && isAssignmentOperator(node.operatorToken.kind)) {
2806
2870
  record(node.left);
2807
- } else if ((ts12.isPrefixUnaryExpression(node) || ts12.isPostfixUnaryExpression(node)) && (node.operator === ts12.SyntaxKind.PlusPlusToken || node.operator === ts12.SyntaxKind.MinusMinusToken)) {
2871
+ } else if ((ts15.isPrefixUnaryExpression(node) || ts15.isPostfixUnaryExpression(node)) && (node.operator === ts15.SyntaxKind.PlusPlusToken || node.operator === ts15.SyntaxKind.MinusMinusToken)) {
2808
2872
  record(node.operand);
2809
2873
  }
2810
- ts12.forEachChild(node, visit);
2874
+ ts15.forEachChild(node, visit);
2811
2875
  };
2812
- ts12.forEachChild(sf, visit);
2876
+ ts15.forEachChild(sf, visit);
2813
2877
  return assigned;
2814
2878
  }
2815
2879
  function closeOverWritersOfMutableBindings(primaryRefs, declarations, mutableNames) {
@@ -2832,11 +2896,11 @@ function closeOverWritersOfMutableBindings(primaryRefs, declarations, mutableNam
2832
2896
  return reachable;
2833
2897
  }
2834
2898
  function isAssignmentOperator(kind) {
2835
- return kind >= ts12.SyntaxKind.FirstAssignment && kind <= ts12.SyntaxKind.LastAssignment;
2899
+ return kind >= ts15.SyntaxKind.FirstAssignment && kind <= ts15.SyntaxKind.LastAssignment;
2836
2900
  }
2837
2901
 
2838
2902
  // ../jsx/src/free-refs.ts
2839
- import ts13 from "typescript";
2903
+ import ts16 from "typescript";
2840
2904
  var _bindingMapCache = new WeakMap;
2841
2905
 
2842
2906
  // ../jsx/src/to-locale-date-lowering.ts
@@ -3239,61 +3303,11 @@ var MATHML_ROOT_TAGS = new Set([
3239
3303
  // ../jsx/src/ir-to-client-js/collect-elements.ts
3240
3304
  var EMPTY_RENDER_EXPRS = new Set(["null", "undefined", "false", "''", '""', "``"]);
3241
3305
 
3242
- // ../jsx/src/ir-to-client-js/identifiers.ts
3243
- var KEYWORDS_AND_GLOBALS = new Set([
3244
- "true",
3245
- "false",
3246
- "null",
3247
- "undefined",
3248
- "this",
3249
- "const",
3250
- "let",
3251
- "var",
3252
- "function",
3253
- "return",
3254
- "if",
3255
- "else",
3256
- "for",
3257
- "while",
3258
- "do",
3259
- "switch",
3260
- "case",
3261
- "break",
3262
- "continue",
3263
- "new",
3264
- "typeof",
3265
- "instanceof",
3266
- "void",
3267
- "delete",
3268
- "console",
3269
- "window",
3270
- "document",
3271
- "Math",
3272
- "String",
3273
- "Number",
3274
- "Array",
3275
- "Object",
3276
- "Boolean",
3277
- "Date",
3278
- "JSON",
3279
- "Promise",
3280
- "setTimeout",
3281
- "setInterval",
3282
- "clearTimeout",
3283
- "clearInterval"
3284
- ]);
3285
-
3286
- // ../jsx/src/ir-to-client-js/walk-prop-accesses.ts
3287
- import ts15 from "typescript";
3288
-
3289
3306
  // ../jsx/src/ir-to-client-js/imports.ts
3290
- import ts17 from "typescript";
3291
-
3292
- // ../jsx/src/value-references.ts
3293
- import ts16 from "typescript";
3307
+ import ts18 from "typescript";
3294
3308
 
3295
3309
  // ../jsx/src/relocate.ts
3296
- import ts18 from "typescript";
3310
+ import ts19 from "typescript";
3297
3311
  var REGISTRY_SAFE_BINDING_KINDS = new Set([
3298
3312
  "global",
3299
3313
  "module-import",
@@ -3485,14 +3499,8 @@ function matchSearchParamsMethodCall(callee, args, localNames) {
3485
3499
  return { method: callee.property, args };
3486
3500
  }
3487
3501
 
3488
- // ../jsx/src/ir-to-client-js/prune-unused-prop-extractions.ts
3489
- import ts19 from "typescript";
3490
-
3491
- // ../jsx/src/ir-to-client-js/emit-reactive.ts
3492
- import ts20 from "typescript";
3493
-
3494
3502
  // ../jsx/src/ir-to-client-js/control-flow/plan/lazy-preamble.ts
3495
- import ts21 from "typescript";
3503
+ import ts20 from "typescript";
3496
3504
  var NO_PREAMBLE = {
3497
3505
  lazySafe: true,
3498
3506
  facts: { declaredNames: new Set, freeNames: new Set }
@@ -3541,17 +3549,11 @@ var INERT_BINDING_GLOBALS = new Set([
3541
3549
  "decodeURI"
3542
3550
  ]);
3543
3551
 
3544
- // ../jsx/src/ir-to-client-js/control-flow/stringify/event-delegation.ts
3545
- var NON_BUBBLING_EVENTS = new Set([
3546
- "blur",
3547
- "focus",
3548
- "load",
3549
- "unload",
3550
- "mouseenter",
3551
- "mouseleave",
3552
- "pointerenter",
3553
- "pointerleave"
3554
- ]);
3552
+ // ../jsx/src/ir-to-client-js/emit-reactive.ts
3553
+ import ts21 from "typescript";
3554
+
3555
+ // ../jsx/src/ir-to-client-js/rewrite-destructured-props.ts
3556
+ import ts22 from "typescript";
3555
3557
 
3556
3558
  // ../jsx/src/ir-to-client-js/source-map.ts
3557
3559
  var BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
@@ -3642,15 +3644,15 @@ class SourceMapGenerator {
3642
3644
  }
3643
3645
 
3644
3646
  // ../jsx/src/preprocess-inline-jsx-callbacks.ts
3645
- import ts22 from "typescript";
3647
+ import ts23 from "typescript";
3646
3648
 
3647
3649
  // ../jsx/src/ssr-defaults.ts
3648
- import ts23 from "typescript";
3650
+ import ts24 from "typescript";
3649
3651
  var UNRESOLVED = Symbol("unresolved");
3650
3652
  var NO_RETURN = Symbol("no-return");
3651
3653
 
3652
3654
  // ../jsx/src/augment-inherited-props.ts
3653
- import ts24 from "typescript";
3655
+ import ts25 from "typescript";
3654
3656
  function collectContextConsumers(metadata) {
3655
3657
  const constants = metadata.localConstants ?? [];
3656
3658
  const contextDefaults = new Map;
@@ -3682,47 +3684,47 @@ function collectContextConsumers(metadata) {
3682
3684
  }
3683
3685
  function parseUseContextArg(source) {
3684
3686
  const expr = parseSingleExpression(source);
3685
- if (!expr || !ts24.isCallExpression(expr))
3687
+ if (!expr || !ts25.isCallExpression(expr))
3686
3688
  return null;
3687
- if (!ts24.isIdentifier(expr.expression) || expr.expression.text !== "useContext")
3689
+ if (!ts25.isIdentifier(expr.expression) || expr.expression.text !== "useContext")
3688
3690
  return null;
3689
3691
  if (expr.arguments.length !== 1)
3690
3692
  return null;
3691
3693
  const arg = expr.arguments[0];
3692
- return ts24.isIdentifier(arg) ? arg.text : null;
3694
+ return ts25.isIdentifier(arg) ? arg.text : null;
3693
3695
  }
3694
3696
  function parseCreateContextDefault(source) {
3695
3697
  const expr = parseSingleExpression(source);
3696
- if (!expr || !ts24.isCallExpression(expr))
3698
+ if (!expr || !ts25.isCallExpression(expr))
3697
3699
  return null;
3698
3700
  if (expr.arguments.length === 0)
3699
3701
  return null;
3700
3702
  const arg = expr.arguments[0];
3701
- if (ts24.isStringLiteral(arg) || ts24.isNoSubstitutionTemplateLiteral(arg))
3703
+ if (ts25.isStringLiteral(arg) || ts25.isNoSubstitutionTemplateLiteral(arg))
3702
3704
  return arg.text;
3703
- if (ts24.isNumericLiteral(arg))
3705
+ if (ts25.isNumericLiteral(arg))
3704
3706
  return Number(arg.text);
3705
- if (arg.kind === ts24.SyntaxKind.TrueKeyword)
3707
+ if (arg.kind === ts25.SyntaxKind.TrueKeyword)
3706
3708
  return true;
3707
- if (arg.kind === ts24.SyntaxKind.FalseKeyword)
3709
+ if (arg.kind === ts25.SyntaxKind.FalseKeyword)
3708
3710
  return false;
3709
3711
  return null;
3710
3712
  }
3711
3713
  function isObjectLiteralCreateContextDefault(source) {
3712
3714
  const expr = parseSingleExpression(source);
3713
- if (!expr || !ts24.isCallExpression(expr))
3715
+ if (!expr || !ts25.isCallExpression(expr))
3714
3716
  return false;
3715
3717
  if (expr.arguments.length === 0)
3716
3718
  return false;
3717
- return ts24.isObjectLiteralExpression(expr.arguments[0]);
3719
+ return ts25.isObjectLiteralExpression(expr.arguments[0]);
3718
3720
  }
3719
3721
  function parseSingleExpression(source) {
3720
- const sf = ts24.createSourceFile("__ctx.ts", `(${source})`, ts24.ScriptTarget.Latest, false);
3722
+ const sf = ts25.createSourceFile("__ctx.ts", `(${source})`, ts25.ScriptTarget.Latest, false);
3721
3723
  const stmt = sf.statements[0];
3722
- if (!stmt || !ts24.isExpressionStatement(stmt))
3724
+ if (!stmt || !ts25.isExpressionStatement(stmt))
3723
3725
  return null;
3724
3726
  let e = stmt.expression;
3725
- while (ts24.isParenthesizedExpression(e))
3727
+ while (ts25.isParenthesizedExpression(e))
3726
3728
  e = e.expression;
3727
3729
  return e;
3728
3730
  }
@@ -3747,25 +3749,25 @@ function augmentInheritedPropAccesses(ir) {
3747
3749
  const pinCoalesceLiterals = (s) => {
3748
3750
  if (!s || !s.includes(propsObj))
3749
3751
  return;
3750
- const sf = ts24.createSourceFile("__aug.ts", `(${s})`, ts24.ScriptTarget.Latest, false);
3752
+ const sf = ts25.createSourceFile("__aug.ts", `(${s})`, ts25.ScriptTarget.Latest, false);
3751
3753
  const visit = (n) => {
3752
- if (ts24.isBinaryExpression(n) && (n.operatorToken.kind === ts24.SyntaxKind.QuestionQuestionToken || n.operatorToken.kind === ts24.SyntaxKind.BarBarToken)) {
3754
+ if (ts25.isBinaryExpression(n) && (n.operatorToken.kind === ts25.SyntaxKind.QuestionQuestionToken || n.operatorToken.kind === ts25.SyntaxKind.BarBarToken)) {
3753
3755
  let left = n.left;
3754
- while (ts24.isParenthesizedExpression(left))
3756
+ while (ts25.isParenthesizedExpression(left))
3755
3757
  left = left.expression;
3756
- if (ts24.isPropertyAccessExpression(left) && ts24.isIdentifier(left.expression) && left.expression.text === propsObj) {
3758
+ if (ts25.isPropertyAccessExpression(left) && ts25.isIdentifier(left.expression) && left.expression.text === propsObj) {
3757
3759
  const name = left.name.text;
3758
3760
  let right = n.right;
3759
- while (ts24.isParenthesizedExpression(right))
3761
+ while (ts25.isParenthesizedExpression(right))
3760
3762
  right = right.expression;
3761
- if (ts24.isPrefixUnaryExpression(right))
3763
+ if (ts25.isPrefixUnaryExpression(right))
3762
3764
  right = right.operand;
3763
- const kind = ts24.isNumericLiteral(right) ? "number" : right.kind === ts24.SyntaxKind.TrueKeyword || right.kind === ts24.SyntaxKind.FalseKeyword ? "boolean" : ts24.isStringLiteralLike(right) ? "string" : null;
3765
+ const kind = ts25.isNumericLiteral(right) ? "number" : right.kind === ts25.SyntaxKind.TrueKeyword || right.kind === ts25.SyntaxKind.FalseKeyword ? "boolean" : ts25.isStringLiteralLike(right) ? "string" : null;
3764
3766
  if (kind && !coalesceLiteralTypes.has(name))
3765
3767
  coalesceLiteralTypes.set(name, kind);
3766
3768
  }
3767
3769
  }
3768
- ts24.forEachChild(n, visit);
3770
+ ts25.forEachChild(n, visit);
3769
3771
  };
3770
3772
  visit(sf);
3771
3773
  };
@@ -3876,33 +3878,33 @@ function augmentInheritedPropAccesses(ir) {
3876
3878
  }
3877
3879
  }
3878
3880
  function parseStaticStringConst(source) {
3879
- const sf = ts24.createSourceFile("__const.ts", `const __x = (${source});`, ts24.ScriptTarget.Latest, false);
3881
+ const sf = ts25.createSourceFile("__const.ts", `const __x = (${source});`, ts25.ScriptTarget.Latest, false);
3880
3882
  const stmt = sf.statements[0];
3881
- if (!stmt || !ts24.isVariableStatement(stmt))
3883
+ if (!stmt || !ts25.isVariableStatement(stmt))
3882
3884
  return null;
3883
3885
  let init = stmt.declarationList.declarations[0]?.initializer;
3884
- while (init && ts24.isParenthesizedExpression(init))
3886
+ while (init && ts25.isParenthesizedExpression(init))
3885
3887
  init = init.expression;
3886
3888
  if (!init)
3887
3889
  return null;
3888
- if (ts24.isStringLiteral(init) || ts24.isNoSubstitutionTemplateLiteral(init)) {
3890
+ if (ts25.isStringLiteral(init) || ts25.isNoSubstitutionTemplateLiteral(init)) {
3889
3891
  return init.text;
3890
3892
  }
3891
3893
  return evalStringArrayJoin(source);
3892
3894
  }
3893
3895
  function evalTemplateOfStringConsts(source, resolved) {
3894
- const sf = ts24.createSourceFile("__const.ts", `const __x = (${source});`, ts24.ScriptTarget.Latest, false);
3896
+ const sf = ts25.createSourceFile("__const.ts", `const __x = (${source});`, ts25.ScriptTarget.Latest, false);
3895
3897
  const stmt = sf.statements[0];
3896
- if (!stmt || !ts24.isVariableStatement(stmt))
3898
+ if (!stmt || !ts25.isVariableStatement(stmt))
3897
3899
  return null;
3898
3900
  let init = stmt.declarationList.declarations[0]?.initializer;
3899
- while (init && ts24.isParenthesizedExpression(init))
3901
+ while (init && ts25.isParenthesizedExpression(init))
3900
3902
  init = init.expression;
3901
- if (!init || !ts24.isTemplateExpression(init))
3903
+ if (!init || !ts25.isTemplateExpression(init))
3902
3904
  return null;
3903
3905
  let out = init.head.text;
3904
3906
  for (const span of init.templateSpans) {
3905
- if (!ts24.isIdentifier(span.expression))
3907
+ if (!ts25.isIdentifier(span.expression))
3906
3908
  return null;
3907
3909
  const value = resolved.get(span.expression.text);
3908
3910
  if (value === undefined)
@@ -3935,30 +3937,30 @@ function lookupStaticRecordLiteral(objectName, key, constants, isShadowed) {
3935
3937
  const constInfo = (constants ?? []).find((c) => c.name === objectName && c.isModule);
3936
3938
  if (constInfo?.value === undefined)
3937
3939
  return null;
3938
- const sf = ts24.createSourceFile("__rec.ts", `(${constInfo.value})`, ts24.ScriptTarget.Latest, true);
3940
+ const sf = ts25.createSourceFile("__rec.ts", `(${constInfo.value})`, ts25.ScriptTarget.Latest, true);
3939
3941
  if (sf.statements.length !== 1)
3940
3942
  return null;
3941
3943
  const stmt = sf.statements[0];
3942
- if (!ts24.isExpressionStatement(stmt))
3944
+ if (!ts25.isExpressionStatement(stmt))
3943
3945
  return null;
3944
3946
  let parsed = stmt.expression;
3945
- while (ts24.isParenthesizedExpression(parsed))
3947
+ while (ts25.isParenthesizedExpression(parsed))
3946
3948
  parsed = parsed.expression;
3947
- if (!ts24.isObjectLiteralExpression(parsed))
3949
+ if (!ts25.isObjectLiteralExpression(parsed))
3948
3950
  return null;
3949
3951
  for (const prop of parsed.properties) {
3950
- if (!ts24.isPropertyAssignment(prop))
3952
+ if (!ts25.isPropertyAssignment(prop))
3951
3953
  continue;
3952
3954
  const name = prop.name;
3953
- const propKey = ts24.isIdentifier(name) || ts24.isStringLiteral(name) || ts24.isNoSubstitutionTemplateLiteral(name) ? name.text : null;
3955
+ const propKey = ts25.isIdentifier(name) || ts25.isStringLiteral(name) || ts25.isNoSubstitutionTemplateLiteral(name) ? name.text : null;
3954
3956
  if (propKey !== key)
3955
3957
  continue;
3956
3958
  let v = prop.initializer;
3957
- while (ts24.isParenthesizedExpression(v))
3959
+ while (ts25.isParenthesizedExpression(v))
3958
3960
  v = v.expression;
3959
- if (ts24.isNumericLiteral(v))
3961
+ if (ts25.isNumericLiteral(v))
3960
3962
  return { kind: "number", text: v.text };
3961
- if (ts24.isStringLiteral(v) || ts24.isNoSubstitutionTemplateLiteral(v)) {
3963
+ if (ts25.isStringLiteral(v) || ts25.isNoSubstitutionTemplateLiteral(v)) {
3962
3964
  return { kind: "string", text: v.text };
3963
3965
  }
3964
3966
  return null;
@@ -3966,28 +3968,28 @@ function lookupStaticRecordLiteral(objectName, key, constants, isShadowed) {
3966
3968
  return null;
3967
3969
  }
3968
3970
  function evalStringArrayJoin(source) {
3969
- const sf = ts24.createSourceFile("__join.ts", `const __x = (${source});`, ts24.ScriptTarget.Latest, false);
3971
+ const sf = ts25.createSourceFile("__join.ts", `const __x = (${source});`, ts25.ScriptTarget.Latest, false);
3970
3972
  const stmt = sf.statements[0];
3971
- if (!stmt || !ts24.isVariableStatement(stmt))
3973
+ if (!stmt || !ts25.isVariableStatement(stmt))
3972
3974
  return null;
3973
3975
  let node = stmt.declarationList.declarations[0]?.initializer;
3974
- while (node && ts24.isParenthesizedExpression(node))
3976
+ while (node && ts25.isParenthesizedExpression(node))
3975
3977
  node = node.expression;
3976
- if (!node || !ts24.isCallExpression(node))
3978
+ if (!node || !ts25.isCallExpression(node))
3977
3979
  return null;
3978
3980
  const callee = node.expression;
3979
- if (!ts24.isPropertyAccessExpression(callee))
3981
+ if (!ts25.isPropertyAccessExpression(callee))
3980
3982
  return null;
3981
3983
  if (callee.name.text !== "join")
3982
3984
  return null;
3983
3985
  let recv = callee.expression;
3984
- while (ts24.isParenthesizedExpression(recv))
3986
+ while (ts25.isParenthesizedExpression(recv))
3985
3987
  recv = recv.expression;
3986
- if (!ts24.isArrayLiteralExpression(recv))
3988
+ if (!ts25.isArrayLiteralExpression(recv))
3987
3989
  return null;
3988
3990
  const parts = [];
3989
3991
  for (const el of recv.elements) {
3990
- if (ts24.isStringLiteral(el) || ts24.isNoSubstitutionTemplateLiteral(el)) {
3992
+ if (ts25.isStringLiteral(el) || ts25.isNoSubstitutionTemplateLiteral(el)) {
3991
3993
  parts.push(el.text);
3992
3994
  } else {
3993
3995
  return null;
@@ -3996,7 +3998,7 @@ function evalStringArrayJoin(source) {
3996
3998
  let sep = ",";
3997
3999
  if (node.arguments.length >= 1) {
3998
4000
  const arg = node.arguments[0];
3999
- if (ts24.isStringLiteral(arg) || ts24.isNoSubstitutionTemplateLiteral(arg))
4001
+ if (ts25.isStringLiteral(arg) || ts25.isNoSubstitutionTemplateLiteral(arg))
4000
4002
  sep = arg.text;
4001
4003
  else
4002
4004
  return null;
@@ -4004,11 +4006,11 @@ function evalStringArrayJoin(source) {
4004
4006
  return parts.join(sep);
4005
4007
  }
4006
4008
  function parseRecordIndexAccess(val, localConstants, propsParams, resolveKey) {
4007
- if (!ts24.isElementAccessExpression(val))
4009
+ if (!ts25.isElementAccessExpression(val))
4008
4010
  return null;
4009
4011
  const obj = val.expression;
4010
4012
  const arg = val.argumentExpression;
4011
- if (!ts24.isIdentifier(obj) || !ts24.isIdentifier(arg))
4013
+ if (!ts25.isIdentifier(obj) || !ts25.isIdentifier(arg))
4012
4014
  return null;
4013
4015
  let indexPropName;
4014
4016
  let defaultKey;
@@ -4024,35 +4026,35 @@ function parseRecordIndexAccess(val, localConstants, propsParams, resolveKey) {
4024
4026
  const constInfo = localConstants.find((c) => c.name === obj.text && c.isModule);
4025
4027
  if (constInfo?.value === undefined)
4026
4028
  return null;
4027
- const sf = ts24.createSourceFile("__rec.ts", `(${constInfo.value})`, ts24.ScriptTarget.Latest, true);
4029
+ const sf = ts25.createSourceFile("__rec.ts", `(${constInfo.value})`, ts25.ScriptTarget.Latest, true);
4028
4030
  if (sf.statements.length !== 1)
4029
4031
  return null;
4030
4032
  const stmt = sf.statements[0];
4031
- if (!ts24.isExpressionStatement(stmt))
4033
+ if (!ts25.isExpressionStatement(stmt))
4032
4034
  return null;
4033
4035
  let parsed = stmt.expression;
4034
- while (ts24.isParenthesizedExpression(parsed))
4036
+ while (ts25.isParenthesizedExpression(parsed))
4035
4037
  parsed = parsed.expression;
4036
- if (!ts24.isObjectLiteralExpression(parsed))
4038
+ if (!ts25.isObjectLiteralExpression(parsed))
4037
4039
  return null;
4038
4040
  const entries = [];
4039
4041
  for (const prop of parsed.properties) {
4040
- if (!ts24.isPropertyAssignment(prop))
4042
+ if (!ts25.isPropertyAssignment(prop))
4041
4043
  return null;
4042
4044
  let key;
4043
- if (ts24.isIdentifier(prop.name)) {
4045
+ if (ts25.isIdentifier(prop.name)) {
4044
4046
  key = prop.name.text;
4045
- } else if (ts24.isStringLiteral(prop.name) || ts24.isNoSubstitutionTemplateLiteral(prop.name)) {
4047
+ } else if (ts25.isStringLiteral(prop.name) || ts25.isNoSubstitutionTemplateLiteral(prop.name)) {
4046
4048
  key = prop.name.text;
4047
4049
  } else {
4048
4050
  return null;
4049
4051
  }
4050
4052
  let v = prop.initializer;
4051
- while (ts24.isParenthesizedExpression(v))
4053
+ while (ts25.isParenthesizedExpression(v))
4052
4054
  v = v.expression;
4053
- if (ts24.isNumericLiteral(v)) {
4055
+ if (ts25.isNumericLiteral(v)) {
4054
4056
  entries.push({ key, value: { kind: "number", text: v.text } });
4055
- } else if (ts24.isStringLiteral(v) || ts24.isNoSubstitutionTemplateLiteral(v)) {
4057
+ } else if (ts25.isStringLiteral(v) || ts25.isNoSubstitutionTemplateLiteral(v)) {
4056
4058
  entries.push({ key, value: { kind: "string", text: v.text } });
4057
4059
  } else {
4058
4060
  return null;
@@ -4141,7 +4143,7 @@ function computeSsrSeedPlan(metadata) {
4141
4143
  // ../jsx/src/rich-type-refusal.ts
4142
4144
  var EMPTY_BINDINGS2 = new Map;
4143
4145
  // ../jsx/src/shared-program.ts
4144
- import ts26 from "typescript";
4146
+ import ts27 from "typescript";
4145
4147
  // ../jsx/src/adapters/interface.ts
4146
4148
  class BaseAdapter {
4147
4149
  renderChildren(children) {
@@ -4423,7 +4425,7 @@ class JsxAdapter extends BaseAdapter {
4423
4425
  }
4424
4426
 
4425
4427
  // ../jsx/src/adapters/template-imports.ts
4426
- import ts27 from "typescript";
4428
+ import ts28 from "typescript";
4427
4429
  var CLIENT_PACKAGE_SOURCES = new Set([
4428
4430
  "@barefootjs/client",
4429
4431
  "@barefootjs/client/runtime"
@@ -4880,7 +4882,7 @@ function resolveStaticLoopSource(arrayParsed, localConstants, opts) {
4880
4882
  if (opts?.isNameShadowed?.(arrayParsed.name))
4881
4883
  return null;
4882
4884
  const local = localConstants?.find((c) => c.name === arrayParsed.name);
4883
- if (!local || local.isModule || !local.parsed)
4885
+ if (!local?.parsed || local.mutatedAfterDeclaration)
4884
4886
  return null;
4885
4887
  target = local.parsed;
4886
4888
  }
@@ -5127,7 +5129,7 @@ function dangerousInnerHtmlDiagnostic(expr, loc, reason) {
5127
5129
  };
5128
5130
  }
5129
5131
  // ../jsx/src/combine-client-js.ts
5130
- import ts28 from "typescript";
5132
+ import ts29 from "typescript";
5131
5133
  // ../jsx/src/loop-destructure.ts
5132
5134
  function isLowerableLoopDestructure(loop) {
5133
5135
  const bindings = loop.paramBindings;
@@ -5267,9 +5269,9 @@ function escapeRe(s) {
5267
5269
  return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
5268
5270
  }
5269
5271
  // ../jsx/src/debug.ts
5270
- import ts29 from "typescript";
5271
- // ../jsx/src/profiler.ts
5272
5272
  import ts30 from "typescript";
5273
+ // ../jsx/src/profiler.ts
5274
+ import ts31 from "typescript";
5273
5275
 
5274
5276
  // ../jsx/src/index.ts
5275
5277
  registerBuiltinLoweringPlugins();
@@ -6063,7 +6065,7 @@ function collectImportedLoopChildComponentErrors(ir, componentName) {
6063
6065
  }
6064
6066
 
6065
6067
  // src/adapter/spread/spread-codegen.ts
6066
- import ts31 from "typescript";
6068
+ import ts32 from "typescript";
6067
6069
  function conditionalSpreadToJinja(ctx, expr) {
6068
6070
  if (!expr || expr.kind !== "conditional")
6069
6071
  return null;
@@ -6120,7 +6122,7 @@ function recordIndexAccessToJinja(ctx, val) {
6120
6122
  if (val.kind !== "index-access" || val.object.kind !== "identifier" || val.index.kind !== "identifier") {
6121
6123
  return null;
6122
6124
  }
6123
- const tsVal = ts31.factory.createElementAccessExpression(ts31.factory.createIdentifier(val.object.name), ts31.factory.createIdentifier(val.index.name));
6125
+ const tsVal = ts32.factory.createElementAccessExpression(ts32.factory.createIdentifier(val.object.name), ts32.factory.createIdentifier(val.index.name));
6124
6126
  const parsed = parseRecordIndexAccess(tsVal, ctx.localConstants ?? [], ctx.propsParams);
6125
6127
  if (!parsed)
6126
6128
  return null;
@@ -6579,11 +6581,11 @@ ${whenTrue}
6579
6581
  const arrayName = loop.array.trim();
6580
6582
  if (staticArray === null && /^[A-Za-z_$][\w$]*$/.test(arrayName)) {
6581
6583
  const arrayConst = (this.localConstants ?? []).find((c) => c.name === arrayName);
6582
- if (arrayConst && !arrayConst.isModule && this._resolveLiteralConst(arrayName) === null) {
6584
+ if (arrayConst && this._resolveLiteralConst(arrayName) === null) {
6583
6585
  this.errors.push({
6584
6586
  code: "BF101",
6585
6587
  severity: "error",
6586
- message: `Loop array \`${arrayName}\` is a local computed value (\`${arrayConst.value}\`) that the MiniJinja adapter cannot bind as a template variable — only numeric/string-literal locals inline at their use site.`,
6588
+ message: `Loop array \`${arrayName}\` is a const (module- or function-scope) computed value (\`${arrayConst.value}\`) that the MiniJinja adapter cannot bind as a template variable — only numeric/string-literal locals inline at their use site.`,
6587
6589
  loc: loop.loc ?? { file: this.componentName + ".tsx", start: { line: 1, column: 0 }, end: { line: 1, column: 0 } },
6588
6590
  suggestion: {
6589
6591
  message: "Pre-compute the array server-side and pass it as a prop, or mark the loop position as @client-only so it runs in JS on the client.",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@barefootjs/rust",
3
- "version": "0.35.5",
3
+ "version": "0.35.6",
4
4
  "description": "minijinja (Rust) adapter for BarefootJS — compiles IR to .j2 templates and ships a Rust rendering runtime (packages/adapter-rust/runtime/); runs under any Rust web framework (axum, etc.)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -54,7 +54,7 @@
54
54
  "directory": "packages/adapter-rust"
55
55
  },
56
56
  "dependencies": {
57
- "@barefootjs/shared": "0.35.5"
57
+ "@barefootjs/shared": "0.35.6"
58
58
  },
59
59
  "peerDependencies": {
60
60
  "@barefootjs/jsx": ">=0.2.0",
@@ -71,9 +71,9 @@
71
71
  },
72
72
  "devDependencies": {
73
73
  "@barefootjs/adapter-tests": "0.1.0",
74
- "@barefootjs/jsx": "0.35.5",
75
- "@barefootjs/vite": "0.35.5",
76
- "@barefootjs/client": "0.35.5",
74
+ "@barefootjs/jsx": "0.35.6",
75
+ "@barefootjs/vite": "0.35.6",
76
+ "@barefootjs/client": "0.35.6",
77
77
  "typescript": "^5.0.0",
78
78
  "vite": "^6.0.0"
79
79
  }
@@ -848,17 +848,11 @@ export class MinijinjaAdapter extends BaseAdapter implements IRNodeEmitter<Jinja
848
848
  })
849
849
  }
850
850
 
851
- // A `.map()` loop whose array is a bare identifier bound to a
852
- // FUNCTION-scope local const with a non-statically-evaluable initializer
853
- // that reads props/signals (e.g. `const entries =
854
- // Object.entries(props.x ?? {}).filter(...)`) can't render correctly.
855
- // Module-scope consts (`isModule`, e.g. `const payments = [...]` at the
856
- // top of the file) are a DIFFERENT, already-working case — the shared
857
- // `ssr-defaults.ts` statically evaluates those and seeds them straight
858
- // into the render context, so a bare `payments` reference resolves for
859
- // free (data-table demo). Function-scope locals get no such seeding
860
- // (`ssr-defaults.ts`: "component-scope locals can depend on
861
- // signals/props and are evaluated lazily elsewhere") — and this
851
+ // A `.map()` loop whose array is a bare identifier bound to a local
852
+ // const (module- or function-scope, #2946) with a non-statically-
853
+ // evaluable initializer that reads props/signals/a function call (e.g.
854
+ // `const entries = Object.entries(props.x ?? {}).filter(...)`) can't
855
+ // render correctly. Locals get no per-render stash slot this
862
856
  // adapter's only "elsewhere" is inlining a const's value at its use
863
857
  // site (`_resolveLiteralConst`'s numeric/single-quoted-string fast
864
858
  // path, or a static-record-literal lookup), never binding one as a
@@ -871,22 +865,21 @@ export class MinijinjaAdapter extends BaseAdapter implements IRNodeEmitter<Jinja
871
865
  // corpus only because the widened destructure gate (#2087 Phase A/B)
872
866
  // no longer refuses this fixture's `([emoji, users]) => ...` param
873
867
  // first. Mirrors adapter-jinja's identical check.
874
- // #2208: a loop source that is a fully-static array literal — either
875
- // inline (`[{ label: 'Alpha' }, ...].map(...)`) or a bare identifier
876
- // bound to a FUNCTION-scope local const whose initializer has no
877
- // prop/signal/function-call dependency — inlines as a native MiniJinja
878
- // list/dict literal below, the same way a module-scope const's value
879
- // is already seeded. A runtime-computed local (#2069, e.g.
880
- // `Object.entries(props.tags).filter(...)`) still refuses below.
881
- // `isNameShadowed` guards a DIFFERENT, enclosing loop's own callback
882
- // param shadowing this identifier (fable review) — never resolve the
883
- // static const in that case. `rawArray` then falls through to the
884
- // bare identifier expression below, same as before #2208 — which
885
- // still trips the pre-existing BF101 gate for an unresolvable local
886
- // const reference (a loud, conservative refusal, not a silent wrong
887
- // value). Canonical, position-accurate predicate (#2482 Stage 2) — the
888
- // enclosing loop scope's own membership, not a coarse whole-component
889
- // union.
868
+ // #2208/#2946: a loop source that is a fully-static array literal —
869
+ // either inline (`[{ label: 'Alpha' }, ...].map(...)`) or a bare
870
+ // identifier bound to a local const (module- or function-scope) whose
871
+ // initializer has no prop/signal/function-call dependency — inlines as
872
+ // a native MiniJinja list/dict literal below. A runtime-computed local
873
+ // (#2069, e.g. `Object.entries(props.tags).filter(...)`) still refuses
874
+ // below, whichever scope it's declared in. `isNameShadowed` guards a
875
+ // DIFFERENT, enclosing loop's own callback param shadowing this
876
+ // identifier (fable review) — never resolve the static const in that
877
+ // case. `rawArray` then falls through to the bare identifier expression
878
+ // below, same as before #2208 — which still trips the pre-existing
879
+ // BF101 gate for an unresolvable local const reference (a loud,
880
+ // conservative refusal, not a silent wrong value). Canonical,
881
+ // position-accurate predicate (#2482 Stage 2) — the enclosing loop
882
+ // scope's own membership, not a coarse whole-component union.
890
883
  const staticItems = resolveStaticLoopSource(loop.arrayParsed, this.localConstants, {
891
884
  isNameShadowed: this.scope.asShadowPredicate(),
892
885
  })
@@ -895,11 +888,11 @@ export class MinijinjaAdapter extends BaseAdapter implements IRNodeEmitter<Jinja
895
888
  const arrayName = loop.array.trim()
896
889
  if (staticArray === null && /^[A-Za-z_$][\w$]*$/.test(arrayName)) {
897
890
  const arrayConst = (this.localConstants ?? []).find(c => c.name === arrayName)
898
- if (arrayConst && !arrayConst.isModule && this._resolveLiteralConst(arrayName) === null) {
891
+ if (arrayConst && this._resolveLiteralConst(arrayName) === null) {
899
892
  this.errors.push({
900
893
  code: 'BF101',
901
894
  severity: 'error',
902
- message: `Loop array \`${arrayName}\` is a local computed value (\`${arrayConst.value}\`) that the MiniJinja adapter cannot bind as a template variable — only numeric/string-literal locals inline at their use site.`,
895
+ message: `Loop array \`${arrayName}\` is a const (module- or function-scope) computed value (\`${arrayConst.value}\`) that the MiniJinja adapter cannot bind as a template variable — only numeric/string-literal locals inline at their use site.`,
903
896
  loc: loop.loc ?? { file: this.componentName + '.tsx', start: { line: 1, column: 0 }, end: { line: 1, column: 0 } },
904
897
  suggestion: {
905
898
  message:
@@ -48,6 +48,17 @@ export const conformancePins: ConformancePins = {
48
48
  issue: 'https://github.com/piconic-ai/barefootjs/issues/2321',
49
49
  },
50
50
  ],
51
+ // #2946: the module-scope const is computed via a function call, not a
52
+ // static literal — genuinely unresolvable at SSR render time, same
53
+ // policy as an unresolvable FUNCTION-scope const above. Escape twin:
54
+ // `module-const-loop-source-computed-client`.
55
+ 'module-const-loop-source-computed': [
56
+ {
57
+ code: 'BF101',
58
+ severity: 'error',
59
+ issue: 'https://github.com/piconic-ai/barefootjs/issues/2946',
60
+ },
61
+ ],
51
62
  // #2038: no inline comprehension-with-nested-callback form via the
52
63
  // evaluator-JSON `*_eval` mechanism (`minijinja-adapter.ts`'s header,
53
64
  // divergence 3) — loud BF101 instead of lossy.
@@ -17,4 +17,10 @@ import type { RenderDivergences } from '@barefootjs/jsx'
17
17
  // at value position and the runtime evaluator's `object-literal` case
18
18
  // now merges it, so the seed classifies `derived` and SSRs identically
19
19
  // to Hono.
20
+ // #2943 graduated: a BODY-destructured prop's default now reaches
21
+ // `ParamInfo.defaultValue` directly (the analyzer overlays it onto
22
+ // `propsParams` at the binding's own declaration), so `extractSsrDefaults`
23
+ // seeds the evaluated default and the adapter's presence guard no longer
24
+ // treats the prop as defaultless — `data-label` now renders `'none'` here
25
+ // exactly like Hono, both for a plain default and a renamed one.
20
26
  export const renderDivergences: RenderDivergences = {}