@barefootjs/cli 0.31.3 → 0.31.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.
Files changed (2) hide show
  1. package/dist/index.js +350 -260
  2. package/package.json +5 -5
package/dist/index.js CHANGED
@@ -2384,6 +2384,30 @@ var init_template_parts = __esm({
2384
2384
  }
2385
2385
  });
2386
2386
 
2387
+ // ../jsx/src/identifier-pattern.ts
2388
+ function withUnicodeFlag(flags) {
2389
+ return flags.includes("u") ? flags : `${flags}u`;
2390
+ }
2391
+ function escapeIdentifierForRegex(name2) {
2392
+ return name2.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
2393
+ }
2394
+ function identifierPattern(name2, flags = "") {
2395
+ const esc = escapeIdentifierForRegex(name2);
2396
+ return new RegExp(`${ID_BOUNDARY_BEFORE}${esc}${ID_BOUNDARY_AFTER}`, withUnicodeFlag(flags));
2397
+ }
2398
+ function identifierCallPattern(name2, flags = "") {
2399
+ const esc = escapeIdentifierForRegex(name2);
2400
+ return new RegExp(`${ID_BOUNDARY_BEFORE}${esc}\\s*\\(`, withUnicodeFlag(flags));
2401
+ }
2402
+ var ID_BOUNDARY_BEFORE, ID_BOUNDARY_AFTER;
2403
+ var init_identifier_pattern = __esm({
2404
+ "../jsx/src/identifier-pattern.ts"() {
2405
+ "use strict";
2406
+ ID_BOUNDARY_BEFORE = "(?<![\\p{ID_Continue}$])";
2407
+ ID_BOUNDARY_AFTER = "(?![\\p{ID_Continue}$])";
2408
+ }
2409
+ });
2410
+
2387
2411
  // ../jsx/src/scanner/js-scanner.ts
2388
2412
  import ts2 from "typescript";
2389
2413
  function* iterateJsTokens(text, start2 = 0, end2 = text.length) {
@@ -2914,9 +2938,6 @@ function inferDefaultValue(type2) {
2914
2938
  if (type2.kind === "object") return "{}";
2915
2939
  return "undefined";
2916
2940
  }
2917
- function escapeRegExp(s) {
2918
- return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
2919
- }
2920
2941
  function freeIdsFromRefs(refs) {
2921
2942
  const out = /* @__PURE__ */ new Set();
2922
2943
  if (!refs) return out;
@@ -3031,15 +3052,15 @@ function wrapLoopParamAsAccessor(expr, paramName, bindings) {
3031
3052
  if (bindings && bindings.length > 0) {
3032
3053
  return rewriteLoopBindingRefs(expr, bindings, "__bfItem()");
3033
3054
  }
3034
- const re = new RegExp(`\\b${escapeRegExp(paramName)}\\b(?!\\s*\\()(?!-)`, "g");
3035
- return replaceInExprContexts(expr, re, `${paramName}()`);
3055
+ const re = new RegExp(`${ID_BOUNDARY_BEFORE}${escapeIdentifierForRegex(paramName)}(?!\\s*\\()(?!-)${ID_BOUNDARY_AFTER}`, "gu");
3056
+ return replaceInExprContexts(expr, re, () => `${paramName}()`);
3036
3057
  }
3037
3058
  function rewriteLoopBindingRefs(expr, bindings, accessor) {
3038
3059
  const byName = /* @__PURE__ */ new Map();
3039
3060
  for (const b of bindings) byName.set(b.name, b);
3040
3061
  const preprocessed = expandShorthandBindings(expr, new Set(byName.keys()));
3041
- const alt = bindings.map((b) => escapeRegExp(b.name)).join("|");
3042
- const re = new RegExp(`\\b(${alt})\\b`, "g");
3062
+ const alt = bindings.map((b) => escapeIdentifierForRegex(b.name)).join("|");
3063
+ const re = new RegExp(`${ID_BOUNDARY_BEFORE}(${alt})${ID_BOUNDARY_AFTER}`, "gu");
3043
3064
  return replaceInExprContexts(
3044
3065
  preprocessed,
3045
3066
  re,
@@ -3094,6 +3115,7 @@ var init_utils = __esm({
3094
3115
  "use strict";
3095
3116
  init_loop_chain();
3096
3117
  init_template_parts();
3118
+ init_identifier_pattern();
3097
3119
  init_js_scanner();
3098
3120
  init_src();
3099
3121
  PROPS_PARAM = "_p";
@@ -3341,7 +3363,7 @@ var init_walker = __esm({
3341
3363
 
3342
3364
  // ../jsx/src/ir-to-client-js/csr-substitute.ts
3343
3365
  import ts4 from "typescript";
3344
- function csrSubstitute(value2, env) {
3366
+ function csrSubstitute(value2, env, enclosingScope) {
3345
3367
  if (!value2 || value2.trim().length === 0) {
3346
3368
  return { rewritten: value2, freeIdentifiers: /* @__PURE__ */ new Set() };
3347
3369
  }
@@ -3349,14 +3371,14 @@ function csrSubstitute(value2, env) {
3349
3371
  let current = value2;
3350
3372
  let lastFreeIdentifiers = /* @__PURE__ */ new Set();
3351
3373
  for (let i = 0; i < maxIter; i++) {
3352
- const step = csrSubstituteOnce(current, env);
3374
+ const step = csrSubstituteOnce(current, env, enclosingScope);
3353
3375
  lastFreeIdentifiers = step.freeIdentifiers;
3354
3376
  if (step.rewritten === current) break;
3355
3377
  current = step.rewritten;
3356
3378
  }
3357
3379
  return { rewritten: current, freeIdentifiers: lastFreeIdentifiers };
3358
3380
  }
3359
- function csrSubstituteOnce(value2, env) {
3381
+ function csrSubstituteOnce(value2, env, enclosingScope) {
3360
3382
  if (!value2 || value2.trim().length === 0) {
3361
3383
  return { rewritten: value2, freeIdentifiers: /* @__PURE__ */ new Set() };
3362
3384
  }
@@ -3380,7 +3402,7 @@ function csrSubstituteOnce(value2, env) {
3380
3402
  for (let i = boundStack.length - 1; i >= 0; i--) {
3381
3403
  if (boundStack[i].has(name2)) return true;
3382
3404
  }
3383
- return false;
3405
+ return enclosingScope?.isBound(name2) ?? false;
3384
3406
  };
3385
3407
  const recordSubstitution = (start2, end2, sub2) => {
3386
3408
  splices.push({ start: start2 - OFFSET, end: end2 - OFFSET, text: `(${sub2.replacement})` });
@@ -3584,6 +3606,176 @@ var init_child_scope = __esm({
3584
3606
  }
3585
3607
  });
3586
3608
 
3609
+ // ../jsx/src/scope/binding-scope.ts
3610
+ var BindingScope;
3611
+ var init_binding_scope = __esm({
3612
+ "../jsx/src/scope/binding-scope.ts"() {
3613
+ "use strict";
3614
+ BindingScope = class _BindingScope {
3615
+ constructor(frames2) {
3616
+ this.frames = frames2;
3617
+ }
3618
+ static EMPTY = new _BindingScope([]);
3619
+ /**
3620
+ * Child scope with a new `'loop-row'` frame for one loop's per-item
3621
+ * bindings. Parent (`this`) is not mutated; the returned scope is a
3622
+ * NEW object with `frames = [newFrame, ...this.frames]`.
3623
+ *
3624
+ * Binding semantics mirror `jsx-to-ir.ts`'s `ctx.loopParams` add site
3625
+ * EXACTLY (verified against lines ~4320-4345 and the matching delete
3626
+ * site ~4695-4710 of `packages/jsx/src/jsx-to-ir.ts`):
3627
+ *
3628
+ * - When `loop.paramBindings` is non-empty (a destructured callback
3629
+ * param, e.g. `.map(({ id, name }) => ...)`), each `paramBindings[i].name`
3630
+ * is bound with source `'destructure'` and the raw `param` text
3631
+ * (which for a destructured callback holds the ORIGINAL pattern
3632
+ * source, e.g. `"{ id, name }"`, not a usable identifier) is NOT
3633
+ * bound. This matches `jsx-to-ir.ts`:
3634
+ * `if (paramBindings) { for (const b of paramBindings) ctx.loopParams.add(b.name) }`
3635
+ * — the `else` branch (`ctx.loopParams.add(param)`) is skipped
3636
+ * entirely when `paramBindings` is present.
3637
+ * - Otherwise (a plain identifier param, e.g. `.map(item => ...)`),
3638
+ * `param` itself is bound with source `'item'`.
3639
+ * - `index` (the second callback param, e.g. `.map((item, i) => ...)`)
3640
+ * is bound with source `'index'` when non-null/non-undefined.
3641
+ * - Every name in `preamble.declaredNames` (a `.map()` callback's
3642
+ * pre-return `const`/`let`/`function` locals, #2447) is bound with
3643
+ * source `'preamble'`.
3644
+ *
3645
+ * NOTE on a sibling mechanism this method does NOT mirror:
3646
+ * `adapters/loop-bound-names.ts`'s `collectLoopBoundNames` adds BOTH
3647
+ * `node.param` AND every `paramBindings[i].name` unconditionally
3648
+ * (never skipping `param` in the destructured case) — a deliberately
3649
+ * coarser, over-inclusive collection used only to subtract names from
3650
+ * a flat string-typing Set (safe to over-exclude there). This method
3651
+ * follows the precise `jsx-to-ir.ts` `ctx.loopParams` semantics, since
3652
+ * that is the mechanism actually doing scope-shadowed name RESOLUTION
3653
+ * (the behavior `BindingScope` replaces), not coarse exclusion.
3654
+ */
3655
+ enterLoopRow(loop) {
3656
+ const bindings = /* @__PURE__ */ new Map();
3657
+ if (loop.paramBindings && loop.paramBindings.length > 0) {
3658
+ for (const b of loop.paramBindings) bindings.set(b.name, { source: "destructure" });
3659
+ } else {
3660
+ bindings.set(loop.param, { source: "item" });
3661
+ }
3662
+ if (loop.index != null) bindings.set(loop.index, { source: "index" });
3663
+ for (const name2 of loop.preamble?.declaredNames ?? []) bindings.set(name2, { source: "preamble" });
3664
+ const frame = { kind: "loop-row", bindings };
3665
+ return new _BindingScope([frame, ...this.frames]);
3666
+ }
3667
+ /**
3668
+ * Child scope with a new `'callback'` frame binding `params` (a filter
3669
+ * predicate's `x`, a sort comparator's `(a, b)`, or a nested arrow's
3670
+ * parameter list) with source `'param'`. Parent is not mutated.
3671
+ */
3672
+ enterCallback(params) {
3673
+ const bindings = /* @__PURE__ */ new Map();
3674
+ for (const name2 of params) bindings.set(name2, { source: "param" });
3675
+ const frame = { kind: "callback", bindings };
3676
+ return new _BindingScope([frame, ...this.frames]);
3677
+ }
3678
+ /** Innermost-first membership check across every frame in the stack. */
3679
+ isBound(name2) {
3680
+ for (const frame of this.frames) {
3681
+ if (frame.bindings.has(name2)) return true;
3682
+ }
3683
+ return false;
3684
+ }
3685
+ /**
3686
+ * Resolves `name` against the frame stack innermost-first. `depth 0`
3687
+ * means the innermost (most recently entered) frame; `null` when `name`
3688
+ * is not bound in any frame.
3689
+ */
3690
+ lookup(name2) {
3691
+ for (let depth = 0; depth < this.frames.length; depth++) {
3692
+ const frame = this.frames[depth];
3693
+ const binding = frame.bindings.get(name2);
3694
+ if (binding) return { depth, frame, binding };
3695
+ }
3696
+ return null;
3697
+ }
3698
+ /**
3699
+ * Union of every frame's bound names (every `ScopeBindingSource`), for
3700
+ * migration interop with legacy `Set<string>`-shaped consumers (e.g.
3701
+ * `collectLoopBoundNames`'s return type) as later stages migrate them
3702
+ * onto `BindingScope`.
3703
+ *
3704
+ * This is the SHADOW-GUARD query — see {@link valueBoundNames} for the
3705
+ * other consumer class and why the two must not be conflated.
3706
+ */
3707
+ boundNames() {
3708
+ if (this.boundNamesCache) return this.boundNamesCache;
3709
+ const names = /* @__PURE__ */ new Set();
3710
+ for (const frame of this.frames) {
3711
+ for (const name2 of frame.bindings.keys()) names.add(name2);
3712
+ }
3713
+ this.boundNamesCache = names;
3714
+ return names;
3715
+ }
3716
+ // Both name queries are hot (shadow guards, slot/reactivity classifiers,
3717
+ // binding-env memo keying) and the scope is immutable, so each computes
3718
+ // once per instance. Callers receive the cached set as ReadonlySet —
3719
+ // never mutate it.
3720
+ boundNamesCache;
3721
+ valueBoundNamesCache;
3722
+ /**
3723
+ * Union of names bound via `'item'`/`'index'`/`'destructure'` sources
3724
+ * only — the loop row's own per-item identity — excluding `'preamble'`
3725
+ * (a `.map()` callback's pre-return `const`/`let`/`function` locals,
3726
+ * #2447) and `'param'` (an `enterCallback` frame's filter/sort/nested-
3727
+ * arrow parameters).
3728
+ *
3729
+ * `BindingScope` has exactly two consumer classes, and conflating them
3730
+ * is the #2482 Stage 1a Commit 2 regression this split exists to
3731
+ * prevent (a `ctx.scope`-wide preamble merge flipped `tag-cloud` and
3732
+ * `preamble-cells` conformance fixtures before this method existed):
3733
+ *
3734
+ * - SHADOW GUARDS (`tryResolveTemplateSpanFromConst`,
3735
+ * `tryResolveIdentifierAsTemplateLiteral`, `rewriteBarePropRefs`
3736
+ * in `jsx-to-ir.ts`) ask "is this name resolved to SOMETHING in
3737
+ * this scope, so an outer const/prop of the same name must not be
3738
+ * substituted here at this transform position" — every source
3739
+ * qualifies, including a preamble local shadowing a module const.
3740
+ * These call `isBound` / `boundNames()`.
3741
+ * - REACTIVITY / SLOT-ID CLASSIFIERS (`referencesLoopParam`,
3742
+ * `hasReactiveAttributes`, and the `BindingEnvironment.loopParams`
3743
+ * feed built from `makeBindingEnv`, all in `jsx-to-ir.ts`) ask
3744
+ * "does this expression read a value that changes per row and so
3745
+ * needs its own patchable slot" — a preamble local already gets
3746
+ * ITS OWN dedicated slot/region-patch machinery
3747
+ * (`preambleRegions` / `markPreambleAttrSlots`, #2447), so folding
3748
+ * it into this classification double-counts it. Worse: widening a
3749
+ * text child's `reactive` flag this way is read by
3750
+ * `hasDynamicContent` to decide whether the loop ROW's own root
3751
+ * element needs a slot — an unrelated, narrower decision that must
3752
+ * not move just because a preamble local is now scope-visible.
3753
+ * These call `valueBoundNames()`.
3754
+ */
3755
+ valueBoundNames() {
3756
+ if (this.valueBoundNamesCache) return this.valueBoundNamesCache;
3757
+ const names = /* @__PURE__ */ new Set();
3758
+ for (const frame of this.frames) {
3759
+ for (const [name2, binding] of frame.bindings) {
3760
+ if (binding.source === "item" || binding.source === "index" || binding.source === "destructure") {
3761
+ names.add(name2);
3762
+ }
3763
+ }
3764
+ }
3765
+ this.valueBoundNamesCache = names;
3766
+ return names;
3767
+ }
3768
+ /**
3769
+ * Drop-in for `resolveStaticLoopSource`'s `opts.isNameShadowed`
3770
+ * (`packages/jsx/src/static-literal.ts:112-128`).
3771
+ */
3772
+ asShadowPredicate() {
3773
+ return (name2) => this.isBound(name2);
3774
+ }
3775
+ };
3776
+ }
3777
+ });
3778
+
3587
3779
  // ../jsx/src/ir-to-client-js/html-template.ts
3588
3780
  function createStringProtector() {
3589
3781
  const strings = [];
@@ -4705,7 +4897,7 @@ function generateCsrTemplateWithOpts(node, opts) {
4705
4897
  const transformExpr = (expr, templateExpr) => {
4706
4898
  const source = templateExpr ?? expr;
4707
4899
  if (!source) return source;
4708
- const { rewritten, freeIdentifiers: freeIdentifiers2 } = csrSubstitute(source, env);
4900
+ const { rewritten, freeIdentifiers: freeIdentifiers2 } = csrSubstitute(source, env, opts.scope);
4709
4901
  if (unsafeLocalNames && unsafeLocalNames.size > 0 && setIntersects(freeIdentifiers2, unsafeLocalNames)) {
4710
4902
  return UNSAFE_TEMPLATE_EXPR;
4711
4903
  }
@@ -4838,13 +5030,8 @@ function generateCsrTemplateWithOpts(node, opts) {
4838
5030
  return `\${renderChild('${nameForRegistryRef(node.name)}', ${propsExpr}${keyArg || (slotArg ? ", undefined" : "")}${slotArg})}`;
4839
5031
  }
4840
5032
  case "loop": {
4841
- const boundHere = new Set(opts.loopBoundNames ?? []);
4842
- if (node.paramBindings && node.paramBindings.length > 0) {
4843
- for (const b of node.paramBindings) boundHere.add(b.name);
4844
- } else if (!node.param.startsWith("[") && !node.param.startsWith("{")) {
4845
- boundHere.add(node.param);
4846
- }
4847
- if (node.index) boundHere.add(node.index);
5033
+ const childScope = (opts.scope ?? BindingScope.EMPTY).enterLoopRow(node);
5034
+ const boundHere = childScope.boundNames();
4848
5035
  const childEnv = {
4849
5036
  ...env,
4850
5037
  substitutions: new Map([...env.substitutions].filter(([name2]) => !boundHere.has(name2)))
@@ -4853,7 +5040,7 @@ function generateCsrTemplateWithOpts(node, opts) {
4853
5040
  ...opts,
4854
5041
  loopDepth: loopDepth + 1,
4855
5042
  inHoistedChildren: false,
4856
- loopBoundNames: boundHere,
5043
+ scope: childScope,
4857
5044
  csrEnv: childEnv
4858
5045
  });
4859
5046
  let childTemplate = node.children.map(recurseInLoopBody).join("");
@@ -4923,6 +5110,7 @@ var init_html_template = __esm({
4923
5110
  init_src();
4924
5111
  init_loop_chain();
4925
5112
  init_child_scope();
5113
+ init_binding_scope();
4926
5114
  VOID_ELEMENTS = /* @__PURE__ */ new Set([
4927
5115
  "area",
4928
5116
  "base",
@@ -9286,7 +9474,7 @@ function findReachableNames(primaryRefs, declarations) {
9286
9474
  const reachable = /* @__PURE__ */ new Set();
9287
9475
  const queue = [];
9288
9476
  for (const name2 of allNames) {
9289
- if (new RegExp(`\\b${name2}\\b`).test(primaryRefs)) {
9477
+ if (identifierPattern(name2).test(primaryRefs)) {
9290
9478
  reachable.add(name2);
9291
9479
  queue.push(name2);
9292
9480
  }
@@ -9295,7 +9483,7 @@ function findReachableNames(primaryRefs, declarations) {
9295
9483
  const current = queue.shift();
9296
9484
  const body2 = bodyMap.get(current) || "";
9297
9485
  for (const name2 of allNames) {
9298
- if (!reachable.has(name2) && new RegExp(`\\b${name2}\\b`).test(body2)) {
9486
+ if (!reachable.has(name2) && identifierPattern(name2).test(body2)) {
9299
9487
  reachable.add(name2);
9300
9488
  queue.push(name2);
9301
9489
  }
@@ -9321,6 +9509,7 @@ function extractFunctionParams(value2) {
9321
9509
  var init_module_exports = __esm({
9322
9510
  "../jsx/src/module-exports.ts"() {
9323
9511
  "use strict";
9512
+ init_identifier_pattern();
9324
9513
  }
9325
9514
  });
9326
9515
 
@@ -9984,176 +10173,6 @@ var init_to_locale_date_lowering = __esm({
9984
10173
  }
9985
10174
  });
9986
10175
 
9987
- // ../jsx/src/scope/binding-scope.ts
9988
- var BindingScope;
9989
- var init_binding_scope = __esm({
9990
- "../jsx/src/scope/binding-scope.ts"() {
9991
- "use strict";
9992
- BindingScope = class _BindingScope {
9993
- constructor(frames2) {
9994
- this.frames = frames2;
9995
- }
9996
- static EMPTY = new _BindingScope([]);
9997
- /**
9998
- * Child scope with a new `'loop-row'` frame for one loop's per-item
9999
- * bindings. Parent (`this`) is not mutated; the returned scope is a
10000
- * NEW object with `frames = [newFrame, ...this.frames]`.
10001
- *
10002
- * Binding semantics mirror `jsx-to-ir.ts`'s `ctx.loopParams` add site
10003
- * EXACTLY (verified against lines ~4320-4345 and the matching delete
10004
- * site ~4695-4710 of `packages/jsx/src/jsx-to-ir.ts`):
10005
- *
10006
- * - When `loop.paramBindings` is non-empty (a destructured callback
10007
- * param, e.g. `.map(({ id, name }) => ...)`), each `paramBindings[i].name`
10008
- * is bound with source `'destructure'` and the raw `param` text
10009
- * (which for a destructured callback holds the ORIGINAL pattern
10010
- * source, e.g. `"{ id, name }"`, not a usable identifier) is NOT
10011
- * bound. This matches `jsx-to-ir.ts`:
10012
- * `if (paramBindings) { for (const b of paramBindings) ctx.loopParams.add(b.name) }`
10013
- * — the `else` branch (`ctx.loopParams.add(param)`) is skipped
10014
- * entirely when `paramBindings` is present.
10015
- * - Otherwise (a plain identifier param, e.g. `.map(item => ...)`),
10016
- * `param` itself is bound with source `'item'`.
10017
- * - `index` (the second callback param, e.g. `.map((item, i) => ...)`)
10018
- * is bound with source `'index'` when non-null/non-undefined.
10019
- * - Every name in `preamble.declaredNames` (a `.map()` callback's
10020
- * pre-return `const`/`let`/`function` locals, #2447) is bound with
10021
- * source `'preamble'`.
10022
- *
10023
- * NOTE on a sibling mechanism this method does NOT mirror:
10024
- * `adapters/loop-bound-names.ts`'s `collectLoopBoundNames` adds BOTH
10025
- * `node.param` AND every `paramBindings[i].name` unconditionally
10026
- * (never skipping `param` in the destructured case) — a deliberately
10027
- * coarser, over-inclusive collection used only to subtract names from
10028
- * a flat string-typing Set (safe to over-exclude there). This method
10029
- * follows the precise `jsx-to-ir.ts` `ctx.loopParams` semantics, since
10030
- * that is the mechanism actually doing scope-shadowed name RESOLUTION
10031
- * (the behavior `BindingScope` replaces), not coarse exclusion.
10032
- */
10033
- enterLoopRow(loop) {
10034
- const bindings = /* @__PURE__ */ new Map();
10035
- if (loop.paramBindings && loop.paramBindings.length > 0) {
10036
- for (const b of loop.paramBindings) bindings.set(b.name, { source: "destructure" });
10037
- } else {
10038
- bindings.set(loop.param, { source: "item" });
10039
- }
10040
- if (loop.index != null) bindings.set(loop.index, { source: "index" });
10041
- for (const name2 of loop.preamble?.declaredNames ?? []) bindings.set(name2, { source: "preamble" });
10042
- const frame = { kind: "loop-row", bindings };
10043
- return new _BindingScope([frame, ...this.frames]);
10044
- }
10045
- /**
10046
- * Child scope with a new `'callback'` frame binding `params` (a filter
10047
- * predicate's `x`, a sort comparator's `(a, b)`, or a nested arrow's
10048
- * parameter list) with source `'param'`. Parent is not mutated.
10049
- */
10050
- enterCallback(params) {
10051
- const bindings = /* @__PURE__ */ new Map();
10052
- for (const name2 of params) bindings.set(name2, { source: "param" });
10053
- const frame = { kind: "callback", bindings };
10054
- return new _BindingScope([frame, ...this.frames]);
10055
- }
10056
- /** Innermost-first membership check across every frame in the stack. */
10057
- isBound(name2) {
10058
- for (const frame of this.frames) {
10059
- if (frame.bindings.has(name2)) return true;
10060
- }
10061
- return false;
10062
- }
10063
- /**
10064
- * Resolves `name` against the frame stack innermost-first. `depth 0`
10065
- * means the innermost (most recently entered) frame; `null` when `name`
10066
- * is not bound in any frame.
10067
- */
10068
- lookup(name2) {
10069
- for (let depth = 0; depth < this.frames.length; depth++) {
10070
- const frame = this.frames[depth];
10071
- const binding = frame.bindings.get(name2);
10072
- if (binding) return { depth, frame, binding };
10073
- }
10074
- return null;
10075
- }
10076
- /**
10077
- * Union of every frame's bound names (every `ScopeBindingSource`), for
10078
- * migration interop with legacy `Set<string>`-shaped consumers (e.g.
10079
- * `collectLoopBoundNames`'s return type) as later stages migrate them
10080
- * onto `BindingScope`.
10081
- *
10082
- * This is the SHADOW-GUARD query — see {@link valueBoundNames} for the
10083
- * other consumer class and why the two must not be conflated.
10084
- */
10085
- boundNames() {
10086
- if (this.boundNamesCache) return this.boundNamesCache;
10087
- const names = /* @__PURE__ */ new Set();
10088
- for (const frame of this.frames) {
10089
- for (const name2 of frame.bindings.keys()) names.add(name2);
10090
- }
10091
- this.boundNamesCache = names;
10092
- return names;
10093
- }
10094
- // Both name queries are hot (shadow guards, slot/reactivity classifiers,
10095
- // binding-env memo keying) and the scope is immutable, so each computes
10096
- // once per instance. Callers receive the cached set as ReadonlySet —
10097
- // never mutate it.
10098
- boundNamesCache;
10099
- valueBoundNamesCache;
10100
- /**
10101
- * Union of names bound via `'item'`/`'index'`/`'destructure'` sources
10102
- * only — the loop row's own per-item identity — excluding `'preamble'`
10103
- * (a `.map()` callback's pre-return `const`/`let`/`function` locals,
10104
- * #2447) and `'param'` (an `enterCallback` frame's filter/sort/nested-
10105
- * arrow parameters).
10106
- *
10107
- * `BindingScope` has exactly two consumer classes, and conflating them
10108
- * is the #2482 Stage 1a Commit 2 regression this split exists to
10109
- * prevent (a `ctx.scope`-wide preamble merge flipped `tag-cloud` and
10110
- * `preamble-cells` conformance fixtures before this method existed):
10111
- *
10112
- * - SHADOW GUARDS (`tryResolveTemplateSpanFromConst`,
10113
- * `tryResolveIdentifierAsTemplateLiteral`, `rewriteBarePropRefs`
10114
- * in `jsx-to-ir.ts`) ask "is this name resolved to SOMETHING in
10115
- * this scope, so an outer const/prop of the same name must not be
10116
- * substituted here at this transform position" — every source
10117
- * qualifies, including a preamble local shadowing a module const.
10118
- * These call `isBound` / `boundNames()`.
10119
- * - REACTIVITY / SLOT-ID CLASSIFIERS (`referencesLoopParam`,
10120
- * `hasReactiveAttributes`, and the `BindingEnvironment.loopParams`
10121
- * feed built from `makeBindingEnv`, all in `jsx-to-ir.ts`) ask
10122
- * "does this expression read a value that changes per row and so
10123
- * needs its own patchable slot" — a preamble local already gets
10124
- * ITS OWN dedicated slot/region-patch machinery
10125
- * (`preambleRegions` / `markPreambleAttrSlots`, #2447), so folding
10126
- * it into this classification double-counts it. Worse: widening a
10127
- * text child's `reactive` flag this way is read by
10128
- * `hasDynamicContent` to decide whether the loop ROW's own root
10129
- * element needs a slot — an unrelated, narrower decision that must
10130
- * not move just because a preamble local is now scope-visible.
10131
- * These call `valueBoundNames()`.
10132
- */
10133
- valueBoundNames() {
10134
- if (this.valueBoundNamesCache) return this.valueBoundNamesCache;
10135
- const names = /* @__PURE__ */ new Set();
10136
- for (const frame of this.frames) {
10137
- for (const [name2, binding] of frame.bindings) {
10138
- if (binding.source === "item" || binding.source === "index" || binding.source === "destructure") {
10139
- names.add(name2);
10140
- }
10141
- }
10142
- }
10143
- this.valueBoundNamesCache = names;
10144
- return names;
10145
- }
10146
- /**
10147
- * Drop-in for `resolveStaticLoopSource`'s `opts.isNameShadowed`
10148
- * (`packages/jsx/src/static-literal.ts:112-128`).
10149
- */
10150
- asShadowPredicate() {
10151
- return (name2) => this.isBound(name2);
10152
- }
10153
- };
10154
- }
10155
- });
10156
-
10157
10176
  // ../jsx/src/jsx-to-ir.ts
10158
10177
  import ts12 from "typescript";
10159
10178
  function hasLeadingClientDirective(expr, sourceFile) {
@@ -10398,17 +10417,17 @@ function createTransformContext(analyzer) {
10398
10417
  patterns: {
10399
10418
  signals: analyzer.signals.map((s) => ({
10400
10419
  getter: s.getter,
10401
- pattern: new RegExp(`\\b${s.getter}\\s*\\(`)
10420
+ pattern: identifierCallPattern(s.getter)
10402
10421
  })),
10403
10422
  memos: analyzer.memos.map((m) => ({
10404
10423
  name: m.name,
10405
- pattern: new RegExp(`\\b${m.name}\\s*\\(`)
10424
+ pattern: identifierCallPattern(m.name)
10406
10425
  })),
10407
- props: analyzer.propsParams.filter((p) => p.name !== "children").map((p) => ({ name: p.name, pattern: new RegExp(`\\b${p.name}\\b`) })),
10426
+ props: analyzer.propsParams.filter((p) => p.name !== "children").map((p) => ({ name: p.name, pattern: identifierPattern(p.name) })),
10408
10427
  constants: analyzer.localConstants.map((c) => ({
10409
10428
  name: c.name,
10410
10429
  value: c.value,
10411
- pattern: new RegExp(`\\b${c.name}\\b`)
10430
+ pattern: identifierPattern(c.name)
10412
10431
  }))
10413
10432
  },
10414
10433
  getJS(node) {
@@ -11180,7 +11199,7 @@ function transformExpressionInner(expr, ctx2, node, isClientOnly) {
11180
11199
  };
11181
11200
  const reactive = isReactiveExpression(exprText, ctx2, expr) || isReactiveOrigin(origin);
11182
11201
  const scopeValueNames = ctx2.scope.valueBoundNames();
11183
- const refsLoopParam = scopeValueNames.size > 0 && Array.from(scopeValueNames).some((p) => new RegExp(`\\b${p}\\b`).test(exprText));
11202
+ const refsLoopParam = scopeValueNames.size > 0 && Array.from(scopeValueNames).some((p) => identifierPattern(p).test(exprText));
11184
11203
  const callsReactive = exprCallsReactiveGetters(expr, ctx2);
11185
11204
  const hasCalls = exprHasFunctionCalls(expr);
11186
11205
  const needsSlot = reactive || isClientOnly || refsLoopParam || callsReactive || hasCalls;
@@ -11215,7 +11234,7 @@ function transformJsxFunctionCall(callExpr, jsxFunc, ctx2, _isClientOnly) {
11215
11234
  const substitutedGetJS = (node) => {
11216
11235
  let text = baseGetJS(node);
11217
11236
  for (const [paramName, argExpr] of substitutions) {
11218
- text = text.replace(new RegExp(`\\b${paramName}\\b`, "g"), argExpr);
11237
+ text = text.replace(identifierPattern(paramName, "g"), () => argExpr);
11219
11238
  }
11220
11239
  return text;
11221
11240
  };
@@ -11257,7 +11276,7 @@ function transformMultiReturnJsxFunctionCall(callExpr, info, ctx2) {
11257
11276
  const substitutedGetJS = (node) => {
11258
11277
  let text = baseGetJS(node);
11259
11278
  for (const [paramName, argExpr] of substitutions) {
11260
- text = text.replace(new RegExp(`\\b${paramName}\\b`, "g"), argExpr);
11279
+ text = text.replace(identifierPattern(paramName, "g"), () => argExpr);
11261
11280
  }
11262
11281
  return text;
11263
11282
  };
@@ -13812,7 +13831,7 @@ function referencesLoopParam(expr, ctx2) {
13812
13831
  const boundNames = ctx2.scope.valueBoundNames();
13813
13832
  if (boundNames.size === 0) return false;
13814
13833
  for (const p of boundNames) {
13815
- if (new RegExp(`\\b${p}\\b`).test(expr)) return true;
13834
+ if (identifierPattern(p).test(expr)) return true;
13816
13835
  }
13817
13836
  return false;
13818
13837
  }
@@ -13880,7 +13899,7 @@ function hasReactiveAttributes(attrs, ctx2) {
13880
13899
  const scopeValueNames = ctx2.scope.valueBoundNames();
13881
13900
  if (scopeValueNames.size > 0) {
13882
13901
  for (const p of scopeValueNames) {
13883
- if (new RegExp(`\\b${p}\\b`).test(valueToCheck)) return true;
13902
+ if (identifierPattern(p).test(valueToCheck)) return true;
13884
13903
  }
13885
13904
  }
13886
13905
  }
@@ -14104,6 +14123,7 @@ var init_jsx_to_ir = __esm({
14104
14123
  init_template_parts();
14105
14124
  init_src();
14106
14125
  init_binding_scope();
14126
+ init_identifier_pattern();
14107
14127
  CLIENT_DIRECTIVE_INTERIOR_RE2 = /^\s*@client\s*$/;
14108
14128
  BLOCK_COMMENT_RE2 = /\/\*([\s\S]*?)\*\//g;
14109
14129
  EMPTY_BOUND = /* @__PURE__ */ new Set();
@@ -14113,17 +14133,19 @@ var init_jsx_to_ir = __esm({
14113
14133
  });
14114
14134
 
14115
14135
  // ../jsx/src/ir-to-client-js/prop-handling.ts
14116
- function expandDynamicPropValue(value2, ctx2) {
14136
+ function expandDynamicPropValue(value2, ctx2, scope) {
14117
14137
  const trimmedValue = value2.trim();
14138
+ if (scope?.isBound(trimmedValue)) return value2;
14118
14139
  const constant = ctx2.localConstants.find((c) => c.name === trimmedValue);
14119
14140
  if (constant && constant.value) {
14120
14141
  return constant.value;
14121
14142
  }
14122
14143
  return value2;
14123
14144
  }
14124
- function expandConstantForReactivity(expr, ctx2, originalFreeIds) {
14145
+ function expandConstantForReactivity(expr, ctx2, originalFreeIds, scope) {
14125
14146
  if (ctx2.propsObjectName) return { expr, freeIds: originalFreeIds };
14126
14147
  const trimmedValue = expr.trim();
14148
+ if (scope?.isBound(trimmedValue)) return { expr, freeIds: originalFreeIds };
14127
14149
  const constant = ctx2.localConstants.find((c) => c.name === trimmedValue);
14128
14150
  if (constant && constant.value) {
14129
14151
  return { expr: constant.value, freeIds: constant.freeIdentifiers };
@@ -14164,6 +14186,15 @@ var init_prop_handling = __esm({
14164
14186
  });
14165
14187
 
14166
14188
  // ../jsx/src/ir-to-client-js/reactivity.ts
14189
+ function buildLoopRowScope(loopParam, loopParamBindings, preambleNames, loopIndex) {
14190
+ if (!loopParam) return void 0;
14191
+ return BindingScope.EMPTY.enterLoopRow({
14192
+ param: loopParam,
14193
+ paramBindings: loopParamBindings,
14194
+ index: loopIndex,
14195
+ preamble: preambleNames && preambleNames.size > 0 ? { declaredNames: [...preambleNames] } : void 0
14196
+ });
14197
+ }
14167
14198
  function decideWrapFromAstFlags(node) {
14168
14199
  if (node.origin && isReactiveOrigin(node.origin)) {
14169
14200
  return { wrap: true, reason: "proven-reactive" };
@@ -14185,12 +14216,12 @@ function decideWrapForChildProp(expandedValue, ctx2, prop) {
14185
14216
  }
14186
14217
  function needsEffectWrapper(expr, ctx2, freeIdentifiers2) {
14187
14218
  for (const signal2 of ctx2.signals) {
14188
- if (new RegExp(`\\b${signal2.getter}\\s*\\(`).test(expr)) {
14219
+ if (identifierCallPattern(signal2.getter).test(expr)) {
14189
14220
  return true;
14190
14221
  }
14191
14222
  }
14192
14223
  for (const memo of ctx2.memos) {
14193
- if (new RegExp(`\\b${memo.name}\\s*\\(`).test(expr)) {
14224
+ if (identifierCallPattern(memo.name).test(expr)) {
14194
14225
  return true;
14195
14226
  }
14196
14227
  }
@@ -14386,8 +14417,9 @@ function traverseForComponents(node, components, skipConditionals = false) {
14386
14417
  }
14387
14418
  });
14388
14419
  }
14389
- function collectLoopChildReactiveTexts(node, ctx2, loopParam, loopParamBindings, stopAtReactiveConditionals = false) {
14420
+ function collectLoopChildReactiveTexts(node, ctx2, loopParam, loopParamBindings, stopAtReactiveConditionals = false, preambleNames, loopIndex) {
14390
14421
  const texts = [];
14422
+ const scope = buildLoopRowScope(loopParam, loopParamBindings, preambleNames, loopIndex);
14391
14423
  walkIR(node, false, {
14392
14424
  // Skip loop/async/if-statement subtrees — the original walker omitted
14393
14425
  // them; they have their own scopes (inner-loop reconciliation, async
@@ -14397,7 +14429,7 @@ function collectLoopChildReactiveTexts(node, ctx2, loopParam, loopParamBindings,
14397
14429
  if (!n.slotId) return;
14398
14430
  if (n.preambleRegion) return;
14399
14431
  const originFreeIds = freeIdsFromRefs(n.origin?.freeRefs);
14400
- const expanded = expandConstantForReactivity(n.expr, ctx2, originFreeIds);
14432
+ const expanded = expandConstantForReactivity(n.expr, ctx2, originFreeIds, scope);
14401
14433
  const reactive = classifyReactivity(expanded.expr, ctx2, loopParam, loopParamBindings, expanded.freeIds).kind !== "none" || decideWrapFromAstFlags(n).wrap;
14402
14434
  if (!reactive) return;
14403
14435
  texts.push({
@@ -14417,8 +14449,9 @@ function anyNameIn(names, set) {
14417
14449
  for (const n of names) if (set.has(n)) return true;
14418
14450
  return false;
14419
14451
  }
14420
- function collectLoopChildReactiveAttrs(node, ctx2, loopParam, loopParamBindings, stopAtReactiveConditionals = false, preambleNames) {
14452
+ function collectLoopChildReactiveAttrs(node, ctx2, loopParam, loopParamBindings, stopAtReactiveConditionals = false, preambleNames, loopIndex) {
14421
14453
  const attrs = [];
14454
+ const scope = buildLoopRowScope(loopParam, loopParamBindings, preambleNames, loopIndex);
14422
14455
  traverseElements(node, (el) => {
14423
14456
  if (el.slotId) {
14424
14457
  for (const attr of el.attrs) {
@@ -14427,7 +14460,7 @@ function collectLoopChildReactiveAttrs(node, ctx2, loopParam, loopParamBindings,
14427
14460
  if (attr.name === "key") continue;
14428
14461
  const valueStr = attrValueToString(attr.value);
14429
14462
  if (!valueStr) continue;
14430
- const expanded = expandConstantForReactivity(valueStr, ctx2, attr.freeIdentifiers);
14463
+ const expanded = expandConstantForReactivity(valueStr, ctx2, attr.freeIdentifiers, scope);
14431
14464
  const readsPreamble = preambleNames !== void 0 && preambleNames.size > 0 && anyNameIn(expanded.freeIds ?? extractFreeIdentifiersFromText(expanded.expr), preambleNames);
14432
14465
  const reactive = classifyReactivity(expanded.expr, ctx2, loopParam, loopParamBindings, expanded.freeIds).kind !== "none" || readsPreamble || attr.callsReactiveGetters || attr.hasFunctionCalls;
14433
14466
  if (!attr.clientOnly && !reactive) continue;
@@ -14452,6 +14485,8 @@ var init_reactivity = __esm({
14452
14485
  init_prop_handling();
14453
14486
  init_csr_substitute();
14454
14487
  init_walker();
14488
+ init_binding_scope();
14489
+ init_identifier_pattern();
14455
14490
  }
14456
14491
  });
14457
14492
 
@@ -14724,13 +14759,13 @@ function collectInnerLoops(nodes, siblingOffsets, outerLoopParam, ctx2, options2
14724
14759
  const emitDepth = fixedDepth ?? scope.depth + 1;
14725
14760
  const loopParamsForTemplate = outerLoopParam ? [outerLoopParam, { param: n.param, bindings: n.paramBindings }] : void 0;
14726
14761
  const template = n.children.map((c) => irToPlaceholderTemplate(c, void 0, emitDepth, loopParamsForTemplate)).join("");
14727
- const refsOuter = outerLoopParam ? new RegExp(`\\b${outerLoopParam}\\b`).test(n.array) : false;
14762
+ const refsOuter = outerLoopParam ? identifierPattern(outerLoopParam).test(n.array) : false;
14728
14763
  const bindings = emptyLoopChildBindings();
14729
14764
  const innerPreambleNames = preambleNamesOf(n);
14730
14765
  if (ctx2) {
14731
14766
  for (const child of n.children) {
14732
- bindings.reactiveTexts.push(...collectLoopChildReactiveTexts(child, ctx2, n.param, n.paramBindings));
14733
- bindings.reactiveAttrs.push(...collectLoopChildReactiveAttrs(child, ctx2, n.param, n.paramBindings, false, innerPreambleNames));
14767
+ bindings.reactiveTexts.push(...collectLoopChildReactiveTexts(child, ctx2, n.param, n.paramBindings, false, innerPreambleNames, n.index));
14768
+ bindings.reactiveAttrs.push(...collectLoopChildReactiveAttrs(child, ctx2, n.param, n.paramBindings, false, innerPreambleNames, n.index));
14734
14769
  bindings.refs.push(...collectLoopChildRefs(child));
14735
14770
  }
14736
14771
  }
@@ -14762,7 +14797,9 @@ function collectInnerLoops(nodes, siblingOffsets, outerLoopParam, ctx2, options2
14762
14797
  ctx2,
14763
14798
  siblingOffsets,
14764
14799
  n.param,
14765
- n.paramBindings
14800
+ n.paramBindings,
14801
+ innerPreambleNames,
14802
+ n.index
14766
14803
  ));
14767
14804
  }
14768
14805
  }
@@ -14944,7 +14981,7 @@ function collectElements(node, ctx2, siblingOffsets, insideConditional = false)
14944
14981
  if (!l.slotId || inCond) return;
14945
14982
  const projectionInner = l.method === "flatMap" && l.children.length === 1 && l.children[0].type === "loop" ? l.children[0] : void 0;
14946
14983
  const childHandlers = [];
14947
- const bindings = projectionInner ? emptyLoopChildBindings() : collectLoopChildBindings(l.children, ctx2, siblingOffsets, l.param, l.paramBindings, preambleNamesOf(l));
14984
+ const bindings = projectionInner ? emptyLoopChildBindings() : collectLoopChildBindings(l.children, ctx2, siblingOffsets, l.param, l.paramBindings, preambleNamesOf(l), l.index);
14948
14985
  if (!projectionInner) {
14949
14986
  for (const child of l.children) {
14950
14987
  childHandlers.push(...collectEventHandlersFromIR(child));
@@ -15196,7 +15233,7 @@ function collectBranchLoops(node, ctx2, siblingOffsets) {
15196
15233
  } else {
15197
15234
  childTemplate = n.children.map((c) => irToHtmlTemplate(c, void 0, 0, branchLoopParamSpec)).join("");
15198
15235
  }
15199
- const branchBindings = ctx2 && !projectionInner ? collectLoopChildBindings(n.children, ctx2, siblingOffsets, n.param, n.paramBindings, preambleNamesOf(n)) : emptyLoopChildBindings();
15236
+ const branchBindings = ctx2 && !projectionInner ? collectLoopChildBindings(n.children, ctx2, siblingOffsets, n.param, n.paramBindings, preambleNamesOf(n), n.index) : emptyLoopChildBindings();
15200
15237
  loops.push({
15201
15238
  kind: "branch",
15202
15239
  array: n.array,
@@ -15282,19 +15319,20 @@ function preambleNamesOf(loop) {
15282
15319
  const declared = loop.preamble?.declaredNames;
15283
15320
  return declared && declared.length > 0 ? new Set(declared) : void 0;
15284
15321
  }
15285
- function collectLoopChildBindings(children2, ctx2, siblingOffsets, loopParam, loopParamBindings, preambleNames) {
15322
+ function collectLoopChildBindings(children2, ctx2, siblingOffsets, loopParam, loopParamBindings, preambleNames, loopIndex) {
15286
15323
  const bindings = emptyLoopChildBindings();
15287
15324
  for (const child of children2) {
15288
15325
  bindings.events.push(...collectLoopChildEventsWithNesting(child));
15289
- bindings.reactiveAttrs.push(...collectLoopChildReactiveAttrs(child, ctx2, loopParam, loopParamBindings, true, preambleNames));
15290
- bindings.reactiveTexts.push(...collectLoopChildReactiveTexts(child, ctx2, loopParam, loopParamBindings, true));
15326
+ bindings.reactiveAttrs.push(...collectLoopChildReactiveAttrs(child, ctx2, loopParam, loopParamBindings, true, preambleNames, loopIndex));
15327
+ bindings.reactiveTexts.push(...collectLoopChildReactiveTexts(child, ctx2, loopParam, loopParamBindings, true, preambleNames, loopIndex));
15291
15328
  bindings.refs.push(...collectLoopChildRefs(child));
15292
- bindings.conditionals.push(...collectLoopChildConditionals(child, ctx2, siblingOffsets, loopParam, loopParamBindings));
15329
+ bindings.conditionals.push(...collectLoopChildConditionals(child, ctx2, siblingOffsets, loopParam, loopParamBindings, preambleNames, loopIndex));
15293
15330
  }
15294
15331
  return bindings;
15295
15332
  }
15296
- function collectLoopChildConditionals(node, ctx2, siblingOffsets, loopParam, loopParamBindings) {
15333
+ function collectLoopChildConditionals(node, ctx2, siblingOffsets, loopParam, loopParamBindings, preambleNames, loopIndex) {
15297
15334
  const conditionals = [];
15335
+ const scope = buildLoopRowScope(loopParam, loopParamBindings, preambleNames, loopIndex);
15298
15336
  const refsAnyBindingViaFreeIds = (freeIds) => {
15299
15337
  if (loopParamBindings && loopParamBindings.length > 0) {
15300
15338
  for (const b of loopParamBindings) {
@@ -15314,7 +15352,7 @@ function collectLoopChildConditionals(node, ctx2, siblingOffsets, loopParam, loo
15314
15352
  const sourceFreeIds = freeIdsFromRefs(n.origin?.freeRefs);
15315
15353
  const refsLoopParamInSource = refsAnyBindingViaFreeIds(sourceFreeIds);
15316
15354
  if (!n.reactive && !refsLoopParamInSource) return;
15317
- const expanded = expandConstantForReactivity(n.condition, ctx2, sourceFreeIds);
15355
+ const expanded = expandConstantForReactivity(n.condition, ctx2, sourceFreeIds, scope);
15318
15356
  if (classifyReactivity(expanded.expr, ctx2, loopParam, loopParamBindings, expanded.freeIds).kind === "none") return;
15319
15357
  const loopParamsForCond = loopParam ? [{ param: loopParam, bindings: loopParamBindings }] : void 0;
15320
15358
  const whenTrueHtml = irToHtmlTemplate(n.whenTrue, void 0, 0, loopParamsForCond, "__slots");
@@ -15324,27 +15362,27 @@ function collectLoopChildConditionals(node, ctx2, siblingOffsets, loopParam, loo
15324
15362
  condition: expanded.expr,
15325
15363
  whenTrueHtml,
15326
15364
  whenFalseHtml,
15327
- whenTrue: summarizeLoopChildBranch(n.whenTrue, ctx2, siblingOffsets, loopParam, loopParamBindings),
15328
- whenFalse: summarizeLoopChildBranch(n.whenFalse, ctx2, siblingOffsets, loopParam, loopParamBindings),
15365
+ whenTrue: summarizeLoopChildBranch(n.whenTrue, ctx2, siblingOffsets, loopParam, loopParamBindings, preambleNames, loopIndex),
15366
+ whenFalse: summarizeLoopChildBranch(n.whenFalse, ctx2, siblingOffsets, loopParam, loopParamBindings, preambleNames, loopIndex),
15329
15367
  ...expanded.freeIds !== void 0 && { conditionFreeIdentifiers: expanded.freeIds }
15330
15368
  });
15331
15369
  }
15332
15370
  });
15333
15371
  return conditionals;
15334
15372
  }
15335
- function summarizeLoopChildBranch(node, ctx2, siblingOffsets, loopParam, loopParamBindings) {
15373
+ function summarizeLoopChildBranch(node, ctx2, siblingOffsets, loopParam, loopParamBindings, preambleNames, loopIndex) {
15336
15374
  const inner = collectInnerLoops([node], siblingOffsets, loopParam, ctx2, branchInnerLoopOptions);
15337
15375
  return {
15338
15376
  childComponents: collectConditionalBranchChildComponents(node),
15339
15377
  innerLoops: inner.length > 0 ? inner : void 0,
15340
- conditionals: collectLoopChildConditionals(node, ctx2, siblingOffsets, loopParam, loopParamBindings),
15378
+ conditionals: collectLoopChildConditionals(node, ctx2, siblingOffsets, loopParam, loopParamBindings, preambleNames, loopIndex),
15341
15379
  events: collectConditionalBranchEvents(node),
15342
15380
  // Loop-param-aware — reuses the flat loop-item collectors scoped to just
15343
15381
  // this branch's subtree. Both already stop descending into any further
15344
15382
  // nested reactive conditional (own insert()/arm), so calling them here
15345
15383
  // on the branch root yields exactly this branch's direct bindings
15346
15384
  // without re-collecting what a nested arm already owns (#2347).
15347
- reactiveAttrs: collectLoopChildReactiveAttrs(node, ctx2, loopParam, loopParamBindings, true),
15385
+ reactiveAttrs: collectLoopChildReactiveAttrs(node, ctx2, loopParam, loopParamBindings, true, preambleNames, loopIndex),
15348
15386
  // Skip ONLY when the branch's entire content is a single bare
15349
15387
  // `expression` (no wrapping element) that MAY yield a live DOM node —
15350
15388
  // i.e. it contains a call anywhere (`node.hasFunctionCalls`, computed
@@ -15392,7 +15430,7 @@ function summarizeLoopChildBranch(node, ctx2, siblingOffsets, loopParam, loopPar
15392
15430
  // makes `irToHtmlTemplate` emit its `<!--bf:sN-->…<!--/-->` marker (the
15393
15431
  // same call builds both the SSR and the CSR/hydration template, so the
15394
15432
  // two can't disagree on shape).
15395
- reactiveTexts: node.type === "expression" && node.hasFunctionCalls ? [] : collectLoopChildReactiveTexts(node, ctx2, loopParam, loopParamBindings, true)
15433
+ reactiveTexts: node.type === "expression" && node.hasFunctionCalls ? [] : collectLoopChildReactiveTexts(node, ctx2, loopParam, loopParamBindings, true, preambleNames, loopIndex)
15396
15434
  };
15397
15435
  }
15398
15436
  var EMPTY_RENDER_EXPRS, branchInnerLoopOptions;
@@ -15407,6 +15445,7 @@ var init_collect_elements = __esm({
15407
15445
  init_prop_handling();
15408
15446
  init_walker();
15409
15447
  init_loop_chain();
15448
+ init_identifier_pattern();
15410
15449
  EMPTY_RENDER_EXPRS = /* @__PURE__ */ new Set(["null", "undefined", "false", "''", '""', "``"]);
15411
15450
  branchInnerLoopOptions = {
15412
15451
  collectItemBindings: true,
@@ -15921,7 +15960,7 @@ var init_value_references = __esm({
15921
15960
  function detectUsedImports(code) {
15922
15961
  const used = /* @__PURE__ */ new Set();
15923
15962
  for (const name2 of RUNTIME_IMPORT_CANDIDATES) {
15924
- if (new RegExp(`\\b${name2}\\s*\\(`).test(code)) {
15963
+ if (identifierCallPattern(name2).test(code)) {
15925
15964
  used.add(name2);
15926
15965
  }
15927
15966
  }
@@ -16021,6 +16060,7 @@ var init_imports = __esm({
16021
16060
  "use strict";
16022
16061
  init_builtins();
16023
16062
  init_value_references();
16063
+ init_identifier_pattern();
16024
16064
  RUNTIME_IMPORT_CANDIDATES = [
16025
16065
  "createSignal",
16026
16066
  "createMemo",
@@ -16395,7 +16435,7 @@ function containsAnyIdentifier(node, names) {
16395
16435
  function scanRefsByName(text, bindings) {
16396
16436
  const result2 = /* @__PURE__ */ new Map();
16397
16437
  for (const name2 of bindings.keys()) {
16398
- const re = new RegExp(`\\b${name2}\\b`);
16438
+ const re = identifierPattern(name2);
16399
16439
  if (re.test(text)) result2.set(name2, []);
16400
16440
  }
16401
16441
  return result2;
@@ -16488,6 +16528,7 @@ var init_relocate = __esm({
16488
16528
  init_props_binding();
16489
16529
  init_expression_parser();
16490
16530
  init_lowering_registry();
16531
+ init_identifier_pattern();
16491
16532
  REGISTRY_SAFE_BINDING_KINDS = /* @__PURE__ */ new Set([
16492
16533
  "global",
16493
16534
  "module-import",
@@ -19242,7 +19283,7 @@ function buildStaticArrayDelegationPlan(elem, profileComponentName) {
19242
19283
  function buildKeyedOrIndexLookup(args2) {
19243
19284
  const hasBindings = (args2.paramBindings?.length ?? 0) > 0;
19244
19285
  if (args2.key !== null) {
19245
- const keyWithItem = hasBindings ? substituteLoopBindings(args2.key, args2.paramBindings, "item") : args2.key.replace(new RegExp(`\\b${args2.param}\\b`, "g"), "item");
19286
+ const keyWithItem = hasBindings ? substituteLoopBindings(args2.key, args2.paramBindings, "item") : args2.key.replace(identifierPattern(args2.param, "g"), "item");
19246
19287
  return {
19247
19288
  kind: "keyed",
19248
19289
  arrayExpr: args2.array,
@@ -19269,6 +19310,7 @@ var init_build_event_delegation = __esm({
19269
19310
  "../jsx/src/ir-to-client-js/control-flow/plan/build-event-delegation.ts"() {
19270
19311
  "use strict";
19271
19312
  init_utils();
19313
+ init_identifier_pattern();
19272
19314
  init_html_template();
19273
19315
  }
19274
19316
  });
@@ -21558,7 +21600,7 @@ function emitKeyedLookup(ls, ev, handlerCall, lookup) {
21558
21600
  }
21559
21601
  for (const nested of ev.nestedLoops) {
21560
21602
  const rawKey = nested.key ?? "";
21561
- const innerKeyExpr = nested.paramBindings && nested.paramBindings.length > 0 ? substituteLoopBindings(rawKey, nested.paramBindings, "item") : rawKey.replace(new RegExp(`\\b${nested.param}\\b`, "g"), "item");
21603
+ const innerKeyExpr = nested.paramBindings && nested.paramBindings.length > 0 ? substituteLoopBindings(rawKey, nested.paramBindings, "item") : rawKey.replace(identifierPattern(nested.param, "g"), "item");
21562
21604
  const outerRef = hasBindings ? "__bfLoopItem" : param;
21563
21605
  ls.push(` const ${nested.param} = ${outerRef} && ${nested.array}.find(item => String(${innerKeyExpr}) === innerKey${nested.depth})`);
21564
21606
  }
@@ -21619,6 +21661,7 @@ var init_event_delegation = __esm({
21619
21661
  "use strict";
21620
21662
  init_utils();
21621
21663
  init_csr_substitute();
21664
+ init_identifier_pattern();
21622
21665
  NON_BUBBLING_EVENTS = /* @__PURE__ */ new Set([
21623
21666
  "blur",
21624
21667
  "focus",
@@ -22367,7 +22410,7 @@ import ts19 from "typescript";
22367
22410
  function rewritePropsObjectRef(code, propsObjectName) {
22368
22411
  const srcPropsName = propsObjectName ?? "props";
22369
22412
  if (srcPropsName === PROPS_PARAM) return code;
22370
- if (!new RegExp(`\\b${srcPropsName}\\b`).test(code)) return code;
22413
+ if (!identifierPattern(srcPropsName).test(code)) return code;
22371
22414
  const sourceFile = ts19.createSourceFile(
22372
22415
  "init-body.ts",
22373
22416
  code,
@@ -22407,6 +22450,7 @@ var init_rewrite_props_object = __esm({
22407
22450
  "../jsx/src/ir-to-client-js/rewrite-props-object.ts"() {
22408
22451
  "use strict";
22409
22452
  init_utils();
22453
+ init_identifier_pattern();
22410
22454
  }
22411
22455
  });
22412
22456
 
@@ -25020,6 +25064,7 @@ var init_jsx_adapter = __esm({
25020
25064
  init_env_signal();
25021
25065
  init_module_exports();
25022
25066
  init_csr_substitute();
25067
+ init_identifier_pattern();
25023
25068
  JsxAdapter = class extends BaseAdapter {
25024
25069
  componentName = "";
25025
25070
  /**
@@ -25111,7 +25156,7 @@ var init_jsx_adapter = __esm({
25111
25156
  lines.push(` const ${signal2.getter} = () => ${initialValue}`);
25112
25157
  }
25113
25158
  if (signal2.setter) {
25114
- const setterUsed = new RegExp(`\\b${signal2.setter}\\b`).test(setterRefText);
25159
+ const setterUsed = identifierPattern(signal2.setter).test(setterRefText);
25115
25160
  if (setterUsed) {
25116
25161
  lines.push(` const ${signal2.setter} = (..._args: any[]) => {}`);
25117
25162
  }
@@ -25380,6 +25425,7 @@ var init_jsx_adapter = __esm({
25380
25425
  });
25381
25426
 
25382
25427
  // ../jsx/src/adapters/template-imports.ts
25428
+ import ts25 from "typescript";
25383
25429
  function rewriteImportsForTemplate(imports, shimSource, rewriteRelative) {
25384
25430
  const remap = (imp) => {
25385
25431
  if (!rewriteRelative || !imp.source.startsWith(".")) return imp;
@@ -25421,6 +25467,48 @@ function rewriteImportsForTemplate(imports, shimSource, rewriteRelative) {
25421
25467
  function specKey(s) {
25422
25468
  return `${s.isDefault ? "d" : ""}${s.isNamespace ? "n" : ""}:${s.name}:${s.alias ?? ""}`;
25423
25469
  }
25470
+ function rewriteDynamicImportsInSource(sourceText, rewriteRelative) {
25471
+ if (!sourceText.includes("import")) return sourceText;
25472
+ const sf = ts25.createSourceFile(
25473
+ "bf-template-fragment.tsx",
25474
+ sourceText,
25475
+ ts25.ScriptTarget.Latest,
25476
+ /* setParentNodes */
25477
+ false,
25478
+ ts25.ScriptKind.TSX
25479
+ );
25480
+ const edits = [];
25481
+ const visit3 = (node) => {
25482
+ if (ts25.isCallExpression(node) && node.expression.kind === ts25.SyntaxKind.ImportKeyword && node.arguments.length > 0 && ts25.isStringLiteralLike(node.arguments[0])) {
25483
+ collect(node.arguments[0]);
25484
+ }
25485
+ if (ts25.isImportTypeNode(node) && ts25.isLiteralTypeNode(node.argument)) {
25486
+ const literal = node.argument.literal;
25487
+ if (ts25.isStringLiteralLike(literal)) collect(literal);
25488
+ }
25489
+ ts25.forEachChild(node, visit3);
25490
+ };
25491
+ const collect = (literal) => {
25492
+ const specifier = literal.text;
25493
+ if (!specifier.startsWith(".")) return;
25494
+ const next = rewriteRelative(specifier);
25495
+ if (next === specifier) return;
25496
+ edits.push({
25497
+ start: literal.getStart(sf),
25498
+ end: literal.getEnd(),
25499
+ // Re-quote rather than reusing the original delimiters: a rewritten
25500
+ // POSIX-relative path never contains a quote to escape.
25501
+ text: `'${next}'`
25502
+ });
25503
+ };
25504
+ ts25.forEachChild(sf, visit3);
25505
+ if (edits.length === 0) return sourceText;
25506
+ let out = sourceText;
25507
+ for (const edit of edits.sort((a, b) => b.start - a.start)) {
25508
+ out = out.slice(0, edit.start) + edit.text + out.slice(edit.end);
25509
+ }
25510
+ return out;
25511
+ }
25424
25512
  var CLIENT_PACKAGE_SOURCES;
25425
25513
  var init_template_imports = __esm({
25426
25514
  "../jsx/src/adapters/template-imports.ts"() {
@@ -26259,7 +26347,7 @@ var init_dangerous_inner_html = __esm({
26259
26347
  });
26260
26348
 
26261
26349
  // ../jsx/src/combine-client-js.ts
26262
- import ts25 from "typescript";
26350
+ import ts26 from "typescript";
26263
26351
  function combineParentChildClientJs(files2) {
26264
26352
  const result2 = /* @__PURE__ */ new Map();
26265
26353
  const lookup = /* @__PURE__ */ new Map();
@@ -26316,17 +26404,17 @@ function combineParentChildClientJs(files2) {
26316
26404
  return result2;
26317
26405
  }
26318
26406
  function parseAndMerge(content2, importsBySource, otherImports, codeSections) {
26319
- const sourceFile = ts25.createSourceFile(
26407
+ const sourceFile = ts26.createSourceFile(
26320
26408
  "combine.js",
26321
26409
  content2,
26322
- ts25.ScriptTarget.Latest,
26410
+ ts26.ScriptTarget.Latest,
26323
26411
  /*setParentNodes*/
26324
26412
  false,
26325
- ts25.ScriptKind.JS
26413
+ ts26.ScriptKind.JS
26326
26414
  );
26327
26415
  const importSpans = [];
26328
26416
  for (const stmt of sourceFile.statements) {
26329
- if (!ts25.isImportDeclaration(stmt)) continue;
26417
+ if (!ts26.isImportDeclaration(stmt)) continue;
26330
26418
  const start2 = stmt.getStart(sourceFile);
26331
26419
  const end2 = stmt.getEnd();
26332
26420
  importSpans.push([start2, end2]);
@@ -26334,8 +26422,8 @@ function parseAndMerge(content2, importsBySource, otherImports, codeSections) {
26334
26422
  if (stmtText.includes("@bf-child:")) continue;
26335
26423
  const clause = stmt.importClause;
26336
26424
  const bindings = clause?.namedBindings;
26337
- const specifier = ts25.isStringLiteral(stmt.moduleSpecifier) ? stmt.moduleSpecifier.text : "";
26338
- if (clause && !clause.name && bindings && ts25.isNamedImports(bindings)) {
26425
+ const specifier = ts26.isStringLiteral(stmt.moduleSpecifier) ? stmt.moduleSpecifier.text : "";
26426
+ if (clause && !clause.name && bindings && ts26.isNamedImports(bindings)) {
26339
26427
  if (!importsBySource.has(specifier)) {
26340
26428
  importsBySource.set(specifier, /* @__PURE__ */ new Set());
26341
26429
  }
@@ -26510,7 +26598,7 @@ var init_loop_destructure = __esm({
26510
26598
  });
26511
26599
 
26512
26600
  // ../jsx/src/debug.ts
26513
- import ts26 from "typescript";
26601
+ import ts27 from "typescript";
26514
26602
  function buildComponentGraph(source, filePath, componentName) {
26515
26603
  const ctx2 = analyzeComponent(source, filePath, componentName);
26516
26604
  if (!ctx2.jsxReturn) {
@@ -27722,18 +27810,18 @@ function truncateExpr(expr, max = 40) {
27722
27810
  function exprReadsPropMember(expr, propsObjectName) {
27723
27811
  let sf;
27724
27812
  try {
27725
- sf = ts26.createSourceFile("__attr.tsx", `(${expr})`, ts26.ScriptTarget.Latest, true, ts26.ScriptKind.TSX);
27813
+ sf = ts27.createSourceFile("__attr.tsx", `(${expr})`, ts27.ScriptTarget.Latest, true, ts27.ScriptKind.TSX);
27726
27814
  } catch {
27727
27815
  return false;
27728
27816
  }
27729
27817
  let found = false;
27730
27818
  const visit3 = (n) => {
27731
27819
  if (found) return;
27732
- if (ts26.isPropertyAccessExpression(n) && ts26.isIdentifier(n.expression) && n.expression.text === propsObjectName && n.name.text !== "children") {
27820
+ if (ts27.isPropertyAccessExpression(n) && ts27.isIdentifier(n.expression) && n.expression.text === propsObjectName && n.name.text !== "children") {
27733
27821
  found = true;
27734
27822
  return;
27735
27823
  }
27736
- ts26.forEachChild(n, visit3);
27824
+ ts27.forEachChild(n, visit3);
27737
27825
  };
27738
27826
  visit3(sf);
27739
27827
  return found;
@@ -27761,12 +27849,12 @@ function attrValueToString2(value2) {
27761
27849
  function extractReactiveDeps(expr, signalGetters, memoNames) {
27762
27850
  const deps = [];
27763
27851
  for (const getter of signalGetters) {
27764
- if (new RegExp(`\\b${getter}\\s*\\(`).test(expr)) {
27852
+ if (identifierCallPattern(getter).test(expr)) {
27765
27853
  deps.push(getter);
27766
27854
  }
27767
27855
  }
27768
27856
  for (const memo of memoNames) {
27769
- if (new RegExp(`\\b${memo}\\s*\\(`).test(expr)) {
27857
+ if (identifierCallPattern(memo).test(expr)) {
27770
27858
  deps.push(memo);
27771
27859
  }
27772
27860
  }
@@ -27779,7 +27867,7 @@ function extractSetterRefs(expr, signalGetters) {
27779
27867
  refs.push(match[1]);
27780
27868
  }
27781
27869
  for (const getter of signalGetters) {
27782
- if (new RegExp(`\\b${getter}\\s*\\(`).test(expr)) {
27870
+ if (identifierCallPattern(getter).test(expr)) {
27783
27871
  refs.push(getter);
27784
27872
  }
27785
27873
  }
@@ -27806,11 +27894,12 @@ var init_debug = __esm({
27806
27894
  init_ir_to_client_js();
27807
27895
  init_reactivity();
27808
27896
  init_utils();
27897
+ init_identifier_pattern();
27809
27898
  }
27810
27899
  });
27811
27900
 
27812
27901
  // ../jsx/src/profiler.ts
27813
- import ts27 from "typescript";
27902
+ import ts28 from "typescript";
27814
27903
  function buildStaticBudget(source, filePath, componentName, options2 = {}) {
27815
27904
  const threshold = options2.fanOutThreshold ?? DEFAULT_FANOUT_THRESHOLD;
27816
27905
  const program = createProgramForFile(source, filePath)?.program;
@@ -28065,14 +28154,14 @@ function joinProfilerEvents(events, index) {
28065
28154
  return { joined, unattributed, diagnostics };
28066
28155
  }
28067
28156
  function findUninstrumentedEffects(source, filePath, instrumentedLines) {
28068
- const sf = ts27.createSourceFile(filePath, source, ts27.ScriptTarget.Latest, true, ts27.ScriptKind.TSX);
28157
+ const sf = ts28.createSourceFile(filePath, source, ts28.ScriptTarget.Latest, true, ts28.ScriptKind.TSX);
28069
28158
  const out = [];
28070
28159
  const visit3 = (node) => {
28071
- if (ts27.isCallExpression(node) && ts27.isIdentifier(node.expression) && node.expression.text === "createEffect") {
28160
+ if (ts28.isCallExpression(node) && ts28.isIdentifier(node.expression) && node.expression.text === "createEffect") {
28072
28161
  const line = sf.getLineAndCharacterOfPosition(node.getStart(sf)).line + 1;
28073
28162
  if (!instrumentedLines.has(line)) out.push({ file: filePath, line });
28074
28163
  }
28075
- ts27.forEachChild(node, visit3);
28164
+ ts28.forEachChild(node, visit3);
28076
28165
  };
28077
28166
  visit3(sf);
28078
28167
  out.sort((a, b) => a.line - b.line);
@@ -28358,19 +28447,19 @@ function assessBatchSafety(args2) {
28358
28447
  const signalGetters = new Set(args2.graph.signals.map((s) => s.name));
28359
28448
  let sf;
28360
28449
  try {
28361
- sf = ts27.createSourceFile("__h.ts", `const __h = ${args2.handler}`, ts27.ScriptTarget.Latest, true);
28450
+ sf = ts28.createSourceFile("__h.ts", `const __h = ${args2.handler}`, ts28.ScriptTarget.Latest, true);
28362
28451
  } catch {
28363
28452
  return "unverified";
28364
28453
  }
28365
28454
  const calls = [];
28366
28455
  const visit3 = (node) => {
28367
- if (ts27.isCallExpression(node) && ts27.isIdentifier(node.expression)) {
28456
+ if (ts28.isCallExpression(node) && ts28.isIdentifier(node.expression)) {
28368
28457
  const name2 = node.expression.text;
28369
28458
  if (setters.has(name2)) calls.push({ pos: node.getStart(sf), kind: "write" });
28370
28459
  else if (D.has(name2) && node.arguments.length === 0) calls.push({ pos: node.getStart(sf), kind: "memoRead" });
28371
28460
  else if (!signalGetters.has(name2) && !memoNames.has(name2)) calls.push({ pos: node.getStart(sf), kind: "risky" });
28372
28461
  }
28373
- ts27.forEachChild(node, visit3);
28462
+ ts28.forEachChild(node, visit3);
28374
28463
  };
28375
28464
  visit3(sf);
28376
28465
  calls.sort((a, b) => a.pos - b.pos);
@@ -29175,6 +29264,7 @@ __export(src_exports, {
29175
29264
  resolveDangerousInnerHtml: () => resolveDangerousInnerHtml,
29176
29265
  resolveSetters: () => resolveSetters,
29177
29266
  resolveStaticLoopSource: () => resolveStaticLoopSource,
29267
+ rewriteDynamicImportsInSource: () => rewriteDynamicImportsInSource,
29178
29268
  rewriteImportsForTemplate: () => rewriteImportsForTemplate,
29179
29269
  searchParamsLocalNames: () => searchParamsLocalNames,
29180
29270
  serializeParsedExpr: () => serializeParsedExpr,
@@ -110033,7 +110123,7 @@ __export(scenario_driver_exports, {
110033
110123
  import { writeFileSync as writeFileSync9, mkdtempSync, rmSync, readFileSync as readFileSync19, existsSync as existsSync23, statSync as statSync3 } from "node:fs";
110034
110124
  import { join as join2, dirname as dirname4, resolve as resolve6 } from "node:path";
110035
110125
  import { tmpdir } from "node:os";
110036
- import ts28 from "typescript";
110126
+ import ts29 from "typescript";
110037
110127
  function externalRuntimeImport(clientJs) {
110038
110128
  const chunks = Array.isArray(clientJs) ? clientJs : [clientJs];
110039
110129
  for (const chunk of chunks) {
@@ -110103,11 +110193,11 @@ function resolveLocalFile(spec) {
110103
110193
  }
110104
110194
  function rewriteLocalImports(js, chunkPath, inlined) {
110105
110195
  const chunkDir = dirname4(chunkPath);
110106
- const sf = ts28.createSourceFile("chunk.mjs", js, ts28.ScriptTarget.Latest, false, ts28.ScriptKind.JS);
110196
+ const sf = ts29.createSourceFile("chunk.mjs", js, ts29.ScriptTarget.Latest, false, ts29.ScriptKind.JS);
110107
110197
  const edits = [];
110108
110198
  for (const stmt of sf.statements) {
110109
- if (!ts28.isImportDeclaration(stmt)) continue;
110110
- if (!ts28.isStringLiteral(stmt.moduleSpecifier)) continue;
110199
+ if (!ts29.isImportDeclaration(stmt)) continue;
110200
+ if (!ts29.isStringLiteral(stmt.moduleSpecifier)) continue;
110111
110201
  const spec = stmt.moduleSpecifier.text;
110112
110202
  if (!spec.startsWith(".")) continue;
110113
110203
  const resolved = resolveLocalFile(join2(chunkDir, spec.replace(/\.client\.js$/, "")));
@@ -110119,13 +110209,13 @@ function rewriteLocalImports(js, chunkPath, inlined) {
110119
110209
  const abs = resolve6(resolved);
110120
110210
  if (inlined.has(abs)) {
110121
110211
  const clause = stmt.importClause;
110122
- if (clause && (clause.name || clause.namedBindings && ts28.isNamespaceImport(clause.namedBindings))) {
110212
+ if (clause && (clause.name || clause.namedBindings && ts29.isNamespaceImport(clause.namedBindings))) {
110123
110213
  throw new Error(
110124
110214
  `"${spec}" (imported by ${chunkPath}) uses a default or namespace import of a sibling client file, which the dynamic scenario runner cannot bind after inlining that file into the run. Import its exports by name, or use the static budget (\`bf debug profile <component>\`), which needs no run.`
110125
110215
  );
110126
110216
  }
110127
110217
  const shims = [];
110128
- if (clause?.namedBindings && ts28.isNamedImports(clause.namedBindings)) {
110218
+ if (clause?.namedBindings && ts29.isNamedImports(clause.namedBindings)) {
110129
110219
  for (const el of clause.namedBindings.elements) {
110130
110220
  if (el.propertyName) shims.push(`var ${el.name.text} = ${el.propertyName.text}`);
110131
110221
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@barefootjs/cli",
3
- "version": "0.31.3",
3
+ "version": "0.31.4",
4
4
  "description": "CLI for agent-driven UI component discovery and scaffolding",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -30,12 +30,12 @@
30
30
  "esbuild": "^0.25.0",
31
31
  "typescript": "^5.0.0",
32
32
  "vite": "^6.0.0",
33
- "@barefootjs/client": "0.31.3",
34
- "@barefootjs/shared": "0.31.3"
33
+ "@barefootjs/client": "0.31.4",
34
+ "@barefootjs/shared": "0.31.4"
35
35
  },
36
36
  "devDependencies": {
37
- "@barefootjs/jsx": "0.31.3",
38
- "@barefootjs/vite": "0.31.3",
37
+ "@barefootjs/jsx": "0.31.4",
38
+ "@barefootjs/vite": "0.31.4",
39
39
  "@happy-dom/global-registrator": "^20.0.11",
40
40
  "@types/node": "^22.0.0",
41
41
  "happy-dom": "^20.0.11"