@barefootjs/rust 0.31.4 → 0.31.5

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/vite.js CHANGED
@@ -5,7 +5,7 @@ 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 ts23 from "typescript";
8
+ import ts24 from "typescript";
9
9
 
10
10
  // ../jsx/src/analyzer.ts
11
11
  import ts9 from "typescript";
@@ -2579,7 +2579,7 @@ var REACTIVE_PRIMITIVES = new Set([
2579
2579
  ]);
2580
2580
 
2581
2581
  // ../jsx/src/jsx-to-ir.ts
2582
- import ts12 from "typescript";
2582
+ import ts13 from "typescript";
2583
2583
 
2584
2584
  // ../jsx/src/types.ts
2585
2585
  var SCOPE_FORBIDDEN = {
@@ -2629,6 +2629,7 @@ function preambleAnalysisTemplateText(p) {
2629
2629
  }
2630
2630
 
2631
2631
  // ../jsx/src/module-exports.ts
2632
+ import ts10 from "typescript";
2632
2633
  function formatParamWithType(p) {
2633
2634
  const rest = p.isRest ? "..." : "";
2634
2635
  const optional = p.optional ? "?" : "";
@@ -2659,12 +2660,55 @@ function findReachableNames(primaryRefs, declarations) {
2659
2660
  }
2660
2661
  return reachable;
2661
2662
  }
2663
+ function findAssignedNames(bodyText, candidates) {
2664
+ const assigned = new Set;
2665
+ if (candidates.size === 0)
2666
+ return assigned;
2667
+ const sf = ts10.createSourceFile("bf-assignment-scan.tsx", bodyText, ts10.ScriptTarget.Latest, false, ts10.ScriptKind.TSX);
2668
+ const record = (target) => {
2669
+ if (ts10.isIdentifier(target) && candidates.has(target.text)) {
2670
+ assigned.add(target.text);
2671
+ }
2672
+ };
2673
+ const visit = (node) => {
2674
+ if (ts10.isBinaryExpression(node) && isAssignmentOperator(node.operatorToken.kind)) {
2675
+ record(node.left);
2676
+ } else if ((ts10.isPrefixUnaryExpression(node) || ts10.isPostfixUnaryExpression(node)) && (node.operator === ts10.SyntaxKind.PlusPlusToken || node.operator === ts10.SyntaxKind.MinusMinusToken)) {
2677
+ record(node.operand);
2678
+ }
2679
+ ts10.forEachChild(node, visit);
2680
+ };
2681
+ ts10.forEachChild(sf, visit);
2682
+ return assigned;
2683
+ }
2684
+ function closeOverWritersOfMutableBindings(primaryRefs, declarations, mutableNames) {
2685
+ let reachable = findReachableNames(primaryRefs, declarations);
2686
+ if (mutableNames.size === 0)
2687
+ return reachable;
2688
+ let seedText = primaryRefs;
2689
+ for (let round = 0;round <= declarations.length; round++) {
2690
+ const survivingMutables = new Set([...reachable].filter((name) => mutableNames.has(name)));
2691
+ if (survivingMutables.size === 0)
2692
+ return reachable;
2693
+ const added = declarations.filter((d) => !reachable.has(d.name)).filter((d) => findAssignedNames(d.body, survivingMutables).size > 0).map((d) => d.name);
2694
+ if (added.length === 0)
2695
+ return reachable;
2696
+ seedText += `
2697
+ ` + added.join(`
2698
+ `);
2699
+ reachable = findReachableNames(seedText, declarations);
2700
+ }
2701
+ return reachable;
2702
+ }
2703
+ function isAssignmentOperator(kind) {
2704
+ return kind >= ts10.SyntaxKind.FirstAssignment && kind <= ts10.SyntaxKind.LastAssignment;
2705
+ }
2662
2706
 
2663
2707
  // ../jsx/src/reactivity-checker.ts
2664
- import ts10 from "typescript";
2708
+ import ts11 from "typescript";
2665
2709
 
2666
2710
  // ../jsx/src/free-refs.ts
2667
- import ts11 from "typescript";
2711
+ import ts12 from "typescript";
2668
2712
  var _bindingMapCache = new WeakMap;
2669
2713
 
2670
2714
  // ../jsx/src/to-locale-date-lowering.ts
@@ -3078,13 +3122,13 @@ var KEYWORDS_AND_GLOBALS = new Set([
3078
3122
  ]);
3079
3123
 
3080
3124
  // ../jsx/src/ir-to-client-js/walk-prop-accesses.ts
3081
- import ts13 from "typescript";
3125
+ import ts14 from "typescript";
3082
3126
 
3083
3127
  // ../jsx/src/value-references.ts
3084
- import ts14 from "typescript";
3128
+ import ts15 from "typescript";
3085
3129
 
3086
3130
  // ../jsx/src/relocate.ts
3087
- import ts15 from "typescript";
3131
+ import ts16 from "typescript";
3088
3132
 
3089
3133
  // ../jsx/src/lowering-registry.ts
3090
3134
  var plugins = [];
@@ -3301,10 +3345,10 @@ function matchSearchParamsMethodCall(callee, args, localNames) {
3301
3345
  }
3302
3346
 
3303
3347
  // ../jsx/src/ir-to-client-js/prune-unused-prop-extractions.ts
3304
- import ts16 from "typescript";
3348
+ import ts17 from "typescript";
3305
3349
 
3306
3350
  // ../jsx/src/ir-to-client-js/control-flow/plan/lazy-preamble.ts
3307
- import ts17 from "typescript";
3351
+ import ts18 from "typescript";
3308
3352
  var NO_PREAMBLE = {
3309
3353
  lazySafe: true,
3310
3354
  facts: { declaredNames: new Set, freeNames: new Set }
@@ -3354,7 +3398,7 @@ var INERT_BINDING_GLOBALS = new Set([
3354
3398
  ]);
3355
3399
 
3356
3400
  // ../jsx/src/ir-to-client-js/emit-reactive.ts
3357
- import ts18 from "typescript";
3401
+ import ts19 from "typescript";
3358
3402
 
3359
3403
  // ../jsx/src/ir-to-client-js/control-flow/stringify/event-delegation.ts
3360
3404
  var NON_BUBBLING_EVENTS = new Set([
@@ -3369,7 +3413,7 @@ var NON_BUBBLING_EVENTS = new Set([
3369
3413
  ]);
3370
3414
 
3371
3415
  // ../jsx/src/ir-to-client-js/rewrite-props-object.ts
3372
- import ts19 from "typescript";
3416
+ import ts20 from "typescript";
3373
3417
 
3374
3418
  // ../jsx/src/ir-to-client-js/source-map.ts
3375
3419
  var BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
@@ -3460,15 +3504,15 @@ class SourceMapGenerator {
3460
3504
  }
3461
3505
 
3462
3506
  // ../jsx/src/preprocess-inline-jsx-callbacks.ts
3463
- import ts20 from "typescript";
3507
+ import ts21 from "typescript";
3464
3508
 
3465
3509
  // ../jsx/src/ssr-defaults.ts
3466
- import ts21 from "typescript";
3510
+ import ts22 from "typescript";
3467
3511
  var UNRESOLVED = Symbol("unresolved");
3468
3512
  var NO_RETURN = Symbol("no-return");
3469
3513
 
3470
3514
  // ../jsx/src/augment-inherited-props.ts
3471
- import ts22 from "typescript";
3515
+ import ts23 from "typescript";
3472
3516
  function collectContextConsumers(metadata) {
3473
3517
  const constants = metadata.localConstants ?? [];
3474
3518
  const contextDefaults = new Map;
@@ -3500,47 +3544,47 @@ function collectContextConsumers(metadata) {
3500
3544
  }
3501
3545
  function parseUseContextArg(source) {
3502
3546
  const expr = parseSingleExpression(source);
3503
- if (!expr || !ts22.isCallExpression(expr))
3547
+ if (!expr || !ts23.isCallExpression(expr))
3504
3548
  return null;
3505
- if (!ts22.isIdentifier(expr.expression) || expr.expression.text !== "useContext")
3549
+ if (!ts23.isIdentifier(expr.expression) || expr.expression.text !== "useContext")
3506
3550
  return null;
3507
3551
  if (expr.arguments.length !== 1)
3508
3552
  return null;
3509
3553
  const arg = expr.arguments[0];
3510
- return ts22.isIdentifier(arg) ? arg.text : null;
3554
+ return ts23.isIdentifier(arg) ? arg.text : null;
3511
3555
  }
3512
3556
  function parseCreateContextDefault(source) {
3513
3557
  const expr = parseSingleExpression(source);
3514
- if (!expr || !ts22.isCallExpression(expr))
3558
+ if (!expr || !ts23.isCallExpression(expr))
3515
3559
  return null;
3516
3560
  if (expr.arguments.length === 0)
3517
3561
  return null;
3518
3562
  const arg = expr.arguments[0];
3519
- if (ts22.isStringLiteral(arg) || ts22.isNoSubstitutionTemplateLiteral(arg))
3563
+ if (ts23.isStringLiteral(arg) || ts23.isNoSubstitutionTemplateLiteral(arg))
3520
3564
  return arg.text;
3521
- if (ts22.isNumericLiteral(arg))
3565
+ if (ts23.isNumericLiteral(arg))
3522
3566
  return Number(arg.text);
3523
- if (arg.kind === ts22.SyntaxKind.TrueKeyword)
3567
+ if (arg.kind === ts23.SyntaxKind.TrueKeyword)
3524
3568
  return true;
3525
- if (arg.kind === ts22.SyntaxKind.FalseKeyword)
3569
+ if (arg.kind === ts23.SyntaxKind.FalseKeyword)
3526
3570
  return false;
3527
3571
  return null;
3528
3572
  }
3529
3573
  function isObjectLiteralCreateContextDefault(source) {
3530
3574
  const expr = parseSingleExpression(source);
3531
- if (!expr || !ts22.isCallExpression(expr))
3575
+ if (!expr || !ts23.isCallExpression(expr))
3532
3576
  return false;
3533
3577
  if (expr.arguments.length === 0)
3534
3578
  return false;
3535
- return ts22.isObjectLiteralExpression(expr.arguments[0]);
3579
+ return ts23.isObjectLiteralExpression(expr.arguments[0]);
3536
3580
  }
3537
3581
  function parseSingleExpression(source) {
3538
- const sf = ts22.createSourceFile("__ctx.ts", `(${source})`, ts22.ScriptTarget.Latest, false);
3582
+ const sf = ts23.createSourceFile("__ctx.ts", `(${source})`, ts23.ScriptTarget.Latest, false);
3539
3583
  const stmt = sf.statements[0];
3540
- if (!stmt || !ts22.isExpressionStatement(stmt))
3584
+ if (!stmt || !ts23.isExpressionStatement(stmt))
3541
3585
  return null;
3542
3586
  let e = stmt.expression;
3543
- while (ts22.isParenthesizedExpression(e))
3587
+ while (ts23.isParenthesizedExpression(e))
3544
3588
  e = e.expression;
3545
3589
  return e;
3546
3590
  }
@@ -3565,25 +3609,25 @@ function augmentInheritedPropAccesses(ir) {
3565
3609
  const pinCoalesceLiterals = (s) => {
3566
3610
  if (!s || !s.includes(propsObj))
3567
3611
  return;
3568
- const sf = ts22.createSourceFile("__aug.ts", `(${s})`, ts22.ScriptTarget.Latest, false);
3612
+ const sf = ts23.createSourceFile("__aug.ts", `(${s})`, ts23.ScriptTarget.Latest, false);
3569
3613
  const visit = (n) => {
3570
- if (ts22.isBinaryExpression(n) && (n.operatorToken.kind === ts22.SyntaxKind.QuestionQuestionToken || n.operatorToken.kind === ts22.SyntaxKind.BarBarToken)) {
3614
+ if (ts23.isBinaryExpression(n) && (n.operatorToken.kind === ts23.SyntaxKind.QuestionQuestionToken || n.operatorToken.kind === ts23.SyntaxKind.BarBarToken)) {
3571
3615
  let left = n.left;
3572
- while (ts22.isParenthesizedExpression(left))
3616
+ while (ts23.isParenthesizedExpression(left))
3573
3617
  left = left.expression;
3574
- if (ts22.isPropertyAccessExpression(left) && ts22.isIdentifier(left.expression) && left.expression.text === propsObj) {
3618
+ if (ts23.isPropertyAccessExpression(left) && ts23.isIdentifier(left.expression) && left.expression.text === propsObj) {
3575
3619
  const name = left.name.text;
3576
3620
  let right = n.right;
3577
- while (ts22.isParenthesizedExpression(right))
3621
+ while (ts23.isParenthesizedExpression(right))
3578
3622
  right = right.expression;
3579
- if (ts22.isPrefixUnaryExpression(right))
3623
+ if (ts23.isPrefixUnaryExpression(right))
3580
3624
  right = right.operand;
3581
- const kind = ts22.isNumericLiteral(right) ? "number" : right.kind === ts22.SyntaxKind.TrueKeyword || right.kind === ts22.SyntaxKind.FalseKeyword ? "boolean" : ts22.isStringLiteralLike(right) ? "string" : null;
3625
+ const kind = ts23.isNumericLiteral(right) ? "number" : right.kind === ts23.SyntaxKind.TrueKeyword || right.kind === ts23.SyntaxKind.FalseKeyword ? "boolean" : ts23.isStringLiteralLike(right) ? "string" : null;
3582
3626
  if (kind && !coalesceLiteralTypes.has(name))
3583
3627
  coalesceLiteralTypes.set(name, kind);
3584
3628
  }
3585
3629
  }
3586
- ts22.forEachChild(n, visit);
3630
+ ts23.forEachChild(n, visit);
3587
3631
  };
3588
3632
  visit(sf);
3589
3633
  };
@@ -3694,33 +3738,33 @@ function augmentInheritedPropAccesses(ir) {
3694
3738
  }
3695
3739
  }
3696
3740
  function parseStaticStringConst(source) {
3697
- const sf = ts22.createSourceFile("__const.ts", `const __x = (${source});`, ts22.ScriptTarget.Latest, false);
3741
+ const sf = ts23.createSourceFile("__const.ts", `const __x = (${source});`, ts23.ScriptTarget.Latest, false);
3698
3742
  const stmt = sf.statements[0];
3699
- if (!stmt || !ts22.isVariableStatement(stmt))
3743
+ if (!stmt || !ts23.isVariableStatement(stmt))
3700
3744
  return null;
3701
3745
  let init = stmt.declarationList.declarations[0]?.initializer;
3702
- while (init && ts22.isParenthesizedExpression(init))
3746
+ while (init && ts23.isParenthesizedExpression(init))
3703
3747
  init = init.expression;
3704
3748
  if (!init)
3705
3749
  return null;
3706
- if (ts22.isStringLiteral(init) || ts22.isNoSubstitutionTemplateLiteral(init)) {
3750
+ if (ts23.isStringLiteral(init) || ts23.isNoSubstitutionTemplateLiteral(init)) {
3707
3751
  return init.text;
3708
3752
  }
3709
3753
  return evalStringArrayJoin(source);
3710
3754
  }
3711
3755
  function evalTemplateOfStringConsts(source, resolved) {
3712
- const sf = ts22.createSourceFile("__const.ts", `const __x = (${source});`, ts22.ScriptTarget.Latest, false);
3756
+ const sf = ts23.createSourceFile("__const.ts", `const __x = (${source});`, ts23.ScriptTarget.Latest, false);
3713
3757
  const stmt = sf.statements[0];
3714
- if (!stmt || !ts22.isVariableStatement(stmt))
3758
+ if (!stmt || !ts23.isVariableStatement(stmt))
3715
3759
  return null;
3716
3760
  let init = stmt.declarationList.declarations[0]?.initializer;
3717
- while (init && ts22.isParenthesizedExpression(init))
3761
+ while (init && ts23.isParenthesizedExpression(init))
3718
3762
  init = init.expression;
3719
- if (!init || !ts22.isTemplateExpression(init))
3763
+ if (!init || !ts23.isTemplateExpression(init))
3720
3764
  return null;
3721
3765
  let out = init.head.text;
3722
3766
  for (const span of init.templateSpans) {
3723
- if (!ts22.isIdentifier(span.expression))
3767
+ if (!ts23.isIdentifier(span.expression))
3724
3768
  return null;
3725
3769
  const value = resolved.get(span.expression.text);
3726
3770
  if (value === undefined)
@@ -3747,34 +3791,36 @@ function collectModuleStringConsts(constants) {
3747
3791
  }
3748
3792
  return map;
3749
3793
  }
3750
- function lookupStaticRecordLiteral(objectName, key, constants) {
3794
+ function lookupStaticRecordLiteral(objectName, key, constants, isShadowed) {
3795
+ if (isShadowed(objectName))
3796
+ return null;
3751
3797
  const constInfo = (constants ?? []).find((c) => c.name === objectName && c.isModule);
3752
3798
  if (constInfo?.value === undefined)
3753
3799
  return null;
3754
- const sf = ts22.createSourceFile("__rec.ts", `(${constInfo.value})`, ts22.ScriptTarget.Latest, true);
3800
+ const sf = ts23.createSourceFile("__rec.ts", `(${constInfo.value})`, ts23.ScriptTarget.Latest, true);
3755
3801
  if (sf.statements.length !== 1)
3756
3802
  return null;
3757
3803
  const stmt = sf.statements[0];
3758
- if (!ts22.isExpressionStatement(stmt))
3804
+ if (!ts23.isExpressionStatement(stmt))
3759
3805
  return null;
3760
3806
  let parsed = stmt.expression;
3761
- while (ts22.isParenthesizedExpression(parsed))
3807
+ while (ts23.isParenthesizedExpression(parsed))
3762
3808
  parsed = parsed.expression;
3763
- if (!ts22.isObjectLiteralExpression(parsed))
3809
+ if (!ts23.isObjectLiteralExpression(parsed))
3764
3810
  return null;
3765
3811
  for (const prop of parsed.properties) {
3766
- if (!ts22.isPropertyAssignment(prop))
3812
+ if (!ts23.isPropertyAssignment(prop))
3767
3813
  continue;
3768
3814
  const name = prop.name;
3769
- const propKey = ts22.isIdentifier(name) || ts22.isStringLiteral(name) || ts22.isNoSubstitutionTemplateLiteral(name) ? name.text : null;
3815
+ const propKey = ts23.isIdentifier(name) || ts23.isStringLiteral(name) || ts23.isNoSubstitutionTemplateLiteral(name) ? name.text : null;
3770
3816
  if (propKey !== key)
3771
3817
  continue;
3772
3818
  let v = prop.initializer;
3773
- while (ts22.isParenthesizedExpression(v))
3819
+ while (ts23.isParenthesizedExpression(v))
3774
3820
  v = v.expression;
3775
- if (ts22.isNumericLiteral(v))
3821
+ if (ts23.isNumericLiteral(v))
3776
3822
  return { kind: "number", text: v.text };
3777
- if (ts22.isStringLiteral(v) || ts22.isNoSubstitutionTemplateLiteral(v)) {
3823
+ if (ts23.isStringLiteral(v) || ts23.isNoSubstitutionTemplateLiteral(v)) {
3778
3824
  return { kind: "string", text: v.text };
3779
3825
  }
3780
3826
  return null;
@@ -3782,28 +3828,28 @@ function lookupStaticRecordLiteral(objectName, key, constants) {
3782
3828
  return null;
3783
3829
  }
3784
3830
  function evalStringArrayJoin(source) {
3785
- const sf = ts22.createSourceFile("__join.ts", `const __x = (${source});`, ts22.ScriptTarget.Latest, false);
3831
+ const sf = ts23.createSourceFile("__join.ts", `const __x = (${source});`, ts23.ScriptTarget.Latest, false);
3786
3832
  const stmt = sf.statements[0];
3787
- if (!stmt || !ts22.isVariableStatement(stmt))
3833
+ if (!stmt || !ts23.isVariableStatement(stmt))
3788
3834
  return null;
3789
3835
  let node = stmt.declarationList.declarations[0]?.initializer;
3790
- while (node && ts22.isParenthesizedExpression(node))
3836
+ while (node && ts23.isParenthesizedExpression(node))
3791
3837
  node = node.expression;
3792
- if (!node || !ts22.isCallExpression(node))
3838
+ if (!node || !ts23.isCallExpression(node))
3793
3839
  return null;
3794
3840
  const callee = node.expression;
3795
- if (!ts22.isPropertyAccessExpression(callee))
3841
+ if (!ts23.isPropertyAccessExpression(callee))
3796
3842
  return null;
3797
3843
  if (callee.name.text !== "join")
3798
3844
  return null;
3799
3845
  let recv = callee.expression;
3800
- while (ts22.isParenthesizedExpression(recv))
3846
+ while (ts23.isParenthesizedExpression(recv))
3801
3847
  recv = recv.expression;
3802
- if (!ts22.isArrayLiteralExpression(recv))
3848
+ if (!ts23.isArrayLiteralExpression(recv))
3803
3849
  return null;
3804
3850
  const parts = [];
3805
3851
  for (const el of recv.elements) {
3806
- if (ts22.isStringLiteral(el) || ts22.isNoSubstitutionTemplateLiteral(el)) {
3852
+ if (ts23.isStringLiteral(el) || ts23.isNoSubstitutionTemplateLiteral(el)) {
3807
3853
  parts.push(el.text);
3808
3854
  } else {
3809
3855
  return null;
@@ -3812,7 +3858,7 @@ function evalStringArrayJoin(source) {
3812
3858
  let sep = ",";
3813
3859
  if (node.arguments.length >= 1) {
3814
3860
  const arg = node.arguments[0];
3815
- if (ts22.isStringLiteral(arg) || ts22.isNoSubstitutionTemplateLiteral(arg))
3861
+ if (ts23.isStringLiteral(arg) || ts23.isNoSubstitutionTemplateLiteral(arg))
3816
3862
  sep = arg.text;
3817
3863
  else
3818
3864
  return null;
@@ -3820,11 +3866,11 @@ function evalStringArrayJoin(source) {
3820
3866
  return parts.join(sep);
3821
3867
  }
3822
3868
  function parseRecordIndexAccess(val, localConstants, propsParams, resolveKey) {
3823
- if (!ts22.isElementAccessExpression(val))
3869
+ if (!ts23.isElementAccessExpression(val))
3824
3870
  return null;
3825
3871
  const obj = val.expression;
3826
3872
  const arg = val.argumentExpression;
3827
- if (!ts22.isIdentifier(obj) || !ts22.isIdentifier(arg))
3873
+ if (!ts23.isIdentifier(obj) || !ts23.isIdentifier(arg))
3828
3874
  return null;
3829
3875
  let indexPropName;
3830
3876
  let defaultKey;
@@ -3840,35 +3886,35 @@ function parseRecordIndexAccess(val, localConstants, propsParams, resolveKey) {
3840
3886
  const constInfo = localConstants.find((c) => c.name === obj.text && c.isModule);
3841
3887
  if (constInfo?.value === undefined)
3842
3888
  return null;
3843
- const sf = ts22.createSourceFile("__rec.ts", `(${constInfo.value})`, ts22.ScriptTarget.Latest, true);
3889
+ const sf = ts23.createSourceFile("__rec.ts", `(${constInfo.value})`, ts23.ScriptTarget.Latest, true);
3844
3890
  if (sf.statements.length !== 1)
3845
3891
  return null;
3846
3892
  const stmt = sf.statements[0];
3847
- if (!ts22.isExpressionStatement(stmt))
3893
+ if (!ts23.isExpressionStatement(stmt))
3848
3894
  return null;
3849
3895
  let parsed = stmt.expression;
3850
- while (ts22.isParenthesizedExpression(parsed))
3896
+ while (ts23.isParenthesizedExpression(parsed))
3851
3897
  parsed = parsed.expression;
3852
- if (!ts22.isObjectLiteralExpression(parsed))
3898
+ if (!ts23.isObjectLiteralExpression(parsed))
3853
3899
  return null;
3854
3900
  const entries = [];
3855
3901
  for (const prop of parsed.properties) {
3856
- if (!ts22.isPropertyAssignment(prop))
3902
+ if (!ts23.isPropertyAssignment(prop))
3857
3903
  return null;
3858
3904
  let key;
3859
- if (ts22.isIdentifier(prop.name)) {
3905
+ if (ts23.isIdentifier(prop.name)) {
3860
3906
  key = prop.name.text;
3861
- } else if (ts22.isStringLiteral(prop.name) || ts22.isNoSubstitutionTemplateLiteral(prop.name)) {
3907
+ } else if (ts23.isStringLiteral(prop.name) || ts23.isNoSubstitutionTemplateLiteral(prop.name)) {
3862
3908
  key = prop.name.text;
3863
3909
  } else {
3864
3910
  return null;
3865
3911
  }
3866
3912
  let v = prop.initializer;
3867
- while (ts22.isParenthesizedExpression(v))
3913
+ while (ts23.isParenthesizedExpression(v))
3868
3914
  v = v.expression;
3869
- if (ts22.isNumericLiteral(v)) {
3915
+ if (ts23.isNumericLiteral(v)) {
3870
3916
  entries.push({ key, value: { kind: "number", text: v.text } });
3871
- } else if (ts22.isStringLiteral(v) || ts22.isNoSubstitutionTemplateLiteral(v)) {
3917
+ } else if (ts23.isStringLiteral(v) || ts23.isNoSubstitutionTemplateLiteral(v)) {
3872
3918
  entries.push({ key, value: { kind: "string", text: v.text } });
3873
3919
  } else {
3874
3920
  return null;
@@ -3924,7 +3970,7 @@ function computeSsrSeedPlan(metadata) {
3924
3970
  // ../jsx/src/rich-type-refusal.ts
3925
3971
  var EMPTY_BINDINGS2 = new Map;
3926
3972
  // ../jsx/src/shared-program.ts
3927
- import ts24 from "typescript";
3973
+ import ts25 from "typescript";
3928
3974
  // ../jsx/src/adapters/interface.ts
3929
3975
  class BaseAdapter {
3930
3976
  renderChildren(children) {
@@ -3977,7 +4023,7 @@ class JsxAdapter extends BaseAdapter {
3977
4023
  ...localFunctions.map((f) => ({ name: f.name, body: f.body })),
3978
4024
  ...localConstants.map((c) => ({ name: c.name, body: c.value }))
3979
4025
  ];
3980
- const reachable = findReachableNames(primaryRefText, declarations);
4026
+ const reachable = closeOverWritersOfMutableBindings(primaryRefText, declarations, new Set(ir.metadata.localConstants.filter((c) => (c.declarationKind ?? "const") !== "const").map((c) => c.name)));
3981
4027
  const reachableBodies = [...reachable].map((name) => {
3982
4028
  const func = localFunctions.find((f) => f.name === name);
3983
4029
  if (func)
@@ -4009,7 +4055,8 @@ class JsxAdapter extends BaseAdapter {
4009
4055
  if (signal.setter) {
4010
4056
  const setterUsed = identifierPattern(signal.setter).test(setterRefText);
4011
4057
  if (setterUsed) {
4012
- lines.push(` const ${signal.setter} = (..._args: any[]) => {}`);
4058
+ const setterType = preserveTypes && signal.type.kind !== "unknown" ? `(valueOrFn: ${signal.type.raw} | ((prev: ${signal.type.raw}) => ${signal.type.raw})) => void` : null;
4059
+ lines.push(setterType ? ` const ${signal.setter}: ${setterType} = () => {}` : ` const ${signal.setter} = (..._args: any[]) => {}`);
4013
4060
  }
4014
4061
  }
4015
4062
  }
@@ -4205,7 +4252,7 @@ class JsxAdapter extends BaseAdapter {
4205
4252
  }
4206
4253
 
4207
4254
  // ../jsx/src/adapters/template-imports.ts
4208
- import ts25 from "typescript";
4255
+ import ts26 from "typescript";
4209
4256
  var CLIENT_PACKAGE_SOURCES = new Set([
4210
4257
  "@barefootjs/client",
4211
4258
  "@barefootjs/client/runtime"
@@ -4344,7 +4391,8 @@ export default ${this.componentName}` : "";
4344
4391
  const noArgDefault = hasRequiredProps ? "" : ` = {} as ${propsTypeExpr}`;
4345
4392
  const lines = [];
4346
4393
  const exportPrefix = ir.metadata.isExported === false ? "" : "export ";
4347
- lines.push(`${exportPrefix}function ${name}(${fullPropsDestructure}${typeAnnotation}${noArgDefault}) {`);
4394
+ const typeParameters = ir.metadata.typeParameters ?? "";
4395
+ lines.push(`${exportPrefix}function ${name}${typeParameters}(${fullPropsDestructure}${typeAnnotation}${noArgDefault}) {`);
4348
4396
  if (hasClientInteractivity) {
4349
4397
  lines.push(` const __scopeId = (/_s\\d/.test(__bfScope || '') ? __bfScope : null) || __instanceId || \`${name}_\${Math.random().toString(36).slice(2, 8)}\``);
4350
4398
  } else {
@@ -4561,72 +4609,6 @@ function emitParsedExpr(expr, emitter) {
4561
4609
  }
4562
4610
  }
4563
4611
  }
4564
- // ../jsx/src/adapters/loop-bound-names.ts
4565
- function collectLoopBoundNames(ir) {
4566
- const names = new Set;
4567
- const visit = (node) => {
4568
- if (!node)
4569
- return;
4570
- switch (node.type) {
4571
- case "element":
4572
- case "component":
4573
- case "fragment":
4574
- case "provider":
4575
- for (const child of node.children)
4576
- visit(child);
4577
- break;
4578
- case "async":
4579
- visit(node.fallback);
4580
- for (const child of node.children)
4581
- visit(child);
4582
- break;
4583
- case "loop":
4584
- names.add(node.param);
4585
- if (node.index)
4586
- names.add(node.index);
4587
- for (const binding of node.paramBindings ?? [])
4588
- names.add(binding.name);
4589
- if (node.filterPredicate)
4590
- names.add(node.filterPredicate.param);
4591
- for (const name of node.preamble?.declaredNames ?? [])
4592
- names.add(name);
4593
- for (const child of node.children)
4594
- visit(child);
4595
- if (node.childComponent) {
4596
- for (const child of node.childComponent.children)
4597
- visit(child);
4598
- }
4599
- for (const nested of node.nestedComponents ?? []) {
4600
- for (const child of nested.children)
4601
- visit(child);
4602
- }
4603
- for (const seg of node.flatMapCallback?.segments ?? []) {
4604
- if (seg.kind === "jsx")
4605
- visit(seg.ir);
4606
- }
4607
- for (const seg of node.preamble?.segments ?? []) {
4608
- if (seg.kind === "jsx")
4609
- visit(seg.ir);
4610
- }
4611
- break;
4612
- case "conditional":
4613
- visit(node.whenTrue);
4614
- visit(node.whenFalse);
4615
- break;
4616
- case "if-statement":
4617
- visit(node.consequent);
4618
- if (node.alternate)
4619
- visit(node.alternate);
4620
- break;
4621
- case "text":
4622
- case "expression":
4623
- case "slot":
4624
- break;
4625
- }
4626
- };
4627
- visit(ir.root);
4628
- return names;
4629
- }
4630
4612
  // ../jsx/src/static-literal.ts
4631
4613
  function evaluateStaticLiteral(expr, bindings) {
4632
4614
  switch (expr.kind) {
@@ -4948,7 +4930,7 @@ function dangerousInnerHtmlDiagnostic(expr, loc, reason) {
4948
4930
  };
4949
4931
  }
4950
4932
  // ../jsx/src/combine-client-js.ts
4951
- import ts26 from "typescript";
4933
+ import ts27 from "typescript";
4952
4934
  // ../jsx/src/loop-destructure.ts
4953
4935
  function isLowerableLoopDestructure(loop) {
4954
4936
  const bindings = loop.paramBindings;
@@ -5088,9 +5070,9 @@ function escapeRe(s) {
5088
5070
  return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
5089
5071
  }
5090
5072
  // ../jsx/src/debug.ts
5091
- import ts27 from "typescript";
5092
- // ../jsx/src/profiler.ts
5093
5073
  import ts28 from "typescript";
5074
+ // ../jsx/src/profiler.ts
5075
+ import ts29 from "typescript";
5094
5076
 
5095
5077
  // ../jsx/src/index.ts
5096
5078
  registerBuiltinLoweringPlugins();
@@ -5903,7 +5885,7 @@ function collectImportedLoopChildComponentErrors(ir, componentName) {
5903
5885
  }
5904
5886
 
5905
5887
  // src/adapter/spread/spread-codegen.ts
5906
- import ts29 from "typescript";
5888
+ import ts30 from "typescript";
5907
5889
  function conditionalSpreadToJinja(ctx, expr) {
5908
5890
  if (!expr || expr.kind !== "conditional")
5909
5891
  return null;
@@ -5958,7 +5940,7 @@ function recordIndexAccessToJinja(ctx, val) {
5958
5940
  if (val.kind !== "index-access" || val.object.kind !== "identifier" || val.index.kind !== "identifier") {
5959
5941
  return null;
5960
5942
  }
5961
- const tsVal = ts29.factory.createElementAccessExpression(ts29.factory.createIdentifier(val.object.name), ts29.factory.createIdentifier(val.index.name));
5943
+ const tsVal = ts30.factory.createElementAccessExpression(ts30.factory.createIdentifier(val.object.name), ts30.factory.createIdentifier(val.index.name));
5962
5944
  const parsed = parseRecordIndexAccess(tsVal, ctx.localConstants ?? [], ctx.propsParams);
5963
5945
  if (!parsed)
5964
5946
  return null;
@@ -6071,8 +6053,7 @@ class MinijinjaAdapter extends BaseAdapter {
6071
6053
  _searchParamsLocals = new Set;
6072
6054
  _loweringMatchers = [];
6073
6055
  localConstants = [];
6074
- staticLoopSourceBoundNames = new Set;
6075
- loopBoundNames = new Map;
6056
+ scope = BindingScope.EMPTY;
6076
6057
  nullableOptionalProps = new Set;
6077
6058
  constructor(options = {}) {
6078
6059
  super();
@@ -6088,8 +6069,7 @@ class MinijinjaAdapter extends BaseAdapter {
6088
6069
  this.propsParams = ir.metadata.propsParams.map((p) => ({ name: p.name }));
6089
6070
  this.booleanTypedProps = collectBooleanTypedProps(ir);
6090
6071
  this.localConstants = ir.metadata.localConstants ?? [];
6091
- this.staticLoopSourceBoundNames = collectLoopBoundNames(ir);
6092
- this.loopBoundNames.clear();
6072
+ this.scope = BindingScope.EMPTY;
6093
6073
  this.nullableOptionalProps = collectNullableOptionalProps(ir);
6094
6074
  this.stringValueNames = collectStringValueNames(ir);
6095
6075
  this.moduleStringConsts = collectModuleStringConsts(ir.metadata.localConstants);
@@ -6383,7 +6363,7 @@ ${whenTrue}
6383
6363
  });
6384
6364
  }
6385
6365
  const staticItems = resolveStaticLoopSource(loop.arrayParsed, this.localConstants, {
6386
- isNameShadowed: (name) => this.staticLoopSourceBoundNames.has(name)
6366
+ isNameShadowed: this.scope.asShadowPredicate()
6387
6367
  });
6388
6368
  const staticArray = staticItems !== null ? staticValueToMinijinja(staticItems) : null;
6389
6369
  const arrayName = loop.array.trim();
@@ -6437,42 +6417,15 @@ ${whenTrue}
6437
6417
  this.inLoop = true;
6438
6418
  const prevLoopKeyDepth = this.currentLoopKeyDepth;
6439
6419
  this.currentLoopKeyDepth = loop.depth;
6420
+ const prevScope = this.scope;
6421
+ this.scope = prevScope.enterLoopRow(loop);
6440
6422
  const preambleLines = (loop.preamble?.declarations ?? []).map((d) => `{% set ${minijinjaIdent(d.name)} = ${this.convertExpressionToJinja(d.raw, d.valueParsed)} %}`);
6441
- const loopBound = [];
6442
- if (loop.objectIteration === "entries") {
6443
- loopBound.push(loop.index ?? param, param);
6444
- } else if (loop.objectIteration === "keys") {
6445
- loopBound.push(param, "__bf_v");
6446
- } else if (loop.objectIteration === "values") {
6447
- loopBound.push("__bf_k", param);
6448
- } else if (loop.iterationShape === "keys") {
6449
- loopBound.push("__bf_item", param);
6450
- } else if (supportableDestructure) {
6451
- loopBound.push("__bf_item", ...(loop.paramBindings ?? []).map((b) => b.name));
6452
- if (loop.index)
6453
- loopBound.push(loop.index);
6454
- } else {
6455
- loopBound.push(param);
6456
- if (loop.index)
6457
- loopBound.push(loop.index);
6458
- }
6459
- for (const d of loop.preamble?.declarations ?? [])
6460
- loopBound.push(d.name);
6461
- for (const n of loopBound) {
6462
- this.loopBoundNames.set(n, (this.loopBoundNames.get(n) ?? 0) + 1);
6463
- }
6464
6423
  const childrenUnderLoop = this.renderChildren(loop.children);
6465
- for (const n of loopBound) {
6466
- const c = (this.loopBoundNames.get(n) ?? 1) - 1;
6467
- if (c <= 0)
6468
- this.loopBoundNames.delete(n);
6469
- else
6470
- this.loopBoundNames.set(n, c);
6471
- }
6472
6424
  this.currentLoopKeyDepth = prevLoopKeyDepth;
6473
6425
  this.inLoop = prevInLoop;
6474
6426
  const bodyChildren = loop.bodyIsItemConditional && loop.key ? `{{ bf.comment("loop-i:" ~ bf.string(${this.convertExpressionToJinja(loop.key)})) | safe }}
6475
6427
  ${childrenUnderLoop}` : childrenUnderLoop;
6428
+ this.scope = prevScope;
6476
6429
  const lines = [];
6477
6430
  lines.push(`{{ bf.comment("loop:${loop.markerId}") | safe }}`);
6478
6431
  const forHeader = loop.objectIteration === "entries" ? `{% for ${minijinjaIdent(loop.index ?? param)}, ${minijinjaIdent(param)} in ${array}|items %}` : loop.objectIteration === "keys" ? `{% for ${minijinjaIdent(param)}, __bf_v in ${array}|items %}` : loop.objectIteration === "values" ? `{% for __bf_k, ${minijinjaIdent(param)} in ${array}|items %}` : `{% for ${minijinjaIdent(loopVar)} in ${array} %}`;
@@ -6704,7 +6657,7 @@ ${name}="{{ bf.string(${val}) }}"
6704
6657
  if (ternaryDict !== null) {
6705
6658
  return `{{ bf.spread_attrs(${ternaryDict}) | safe }}`;
6706
6659
  }
6707
- if (/^[A-Za-z_$][\w$]*$/.test(trimmed) && !this.loopBoundNames.has(trimmed)) {
6660
+ if (/^[A-Za-z_$][\w$]*$/.test(trimmed) && !this.scope.isBound(trimmed)) {
6708
6661
  const localConst = (this.localConstants ?? []).find((c) => c.name === trimmed && !c.isModule);
6709
6662
  if (localConst?.value !== undefined) {
6710
6663
  const initTrimmed = localConst.value.trim();
@@ -6939,7 +6892,7 @@ Options:
6939
6892
  return this.booleanTypedProps.has(bare);
6940
6893
  }
6941
6894
  isLoopBoundName(name) {
6942
- return this.loopBoundNames.has(name);
6895
+ return this.scope.isBound(name);
6943
6896
  }
6944
6897
  shouldBoolStr(expr, name) {
6945
6898
  if (isExplicitStringCall(expr))
@@ -6947,7 +6900,7 @@ Options:
6947
6900
  return isBooleanResultExpr(expr) || isAriaBooleanAttr(name) || this.isBooleanTypedPropRef(expr);
6948
6901
  }
6949
6902
  _resolveLiteralConst(name) {
6950
- if (this.staticLoopSourceBoundNames.has(name))
6903
+ if (this.scope.isBound(name))
6951
6904
  return null;
6952
6905
  const c = (this.localConstants ?? []).find((lc) => lc.name === name);
6953
6906
  if (c?.value === undefined)
@@ -6961,9 +6914,7 @@ Options:
6961
6914
  return null;
6962
6915
  }
6963
6916
  _resolveStaticRecordLiteral(objectName, key) {
6964
- if (this.staticLoopSourceBoundNames.has(objectName))
6965
- return null;
6966
- const hit = lookupStaticRecordLiteral(objectName, key, this.localConstants);
6917
+ const hit = lookupStaticRecordLiteral(objectName, key, this.localConstants, (name) => this.scope.isBound(name));
6967
6918
  if (!hit)
6968
6919
  return null;
6969
6920
  return hit.kind === "number" ? hit.text : `'${escapeMinijinjaSingleQuoted(hit.text)}'`;