@barefootjs/jsx 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 (52) hide show
  1. package/dist/adapters/jsx-adapter.d.ts.map +1 -1
  2. package/dist/adapters/template-imports.d.ts +27 -15
  3. package/dist/adapters/template-imports.d.ts.map +1 -1
  4. package/dist/debug.d.ts.map +1 -1
  5. package/dist/identifier-pattern.d.ts +62 -0
  6. package/dist/identifier-pattern.d.ts.map +1 -0
  7. package/dist/index.d.ts +1 -1
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js +226 -163
  10. package/dist/ir-to-client-js/collect-elements.d.ts +23 -2
  11. package/dist/ir-to-client-js/collect-elements.d.ts.map +1 -1
  12. package/dist/ir-to-client-js/control-flow/plan/build-event-delegation.d.ts.map +1 -1
  13. package/dist/ir-to-client-js/control-flow/stringify/event-delegation.d.ts.map +1 -1
  14. package/dist/ir-to-client-js/csr-substitute.d.ts +12 -1
  15. package/dist/ir-to-client-js/csr-substitute.d.ts.map +1 -1
  16. package/dist/ir-to-client-js/html-template.d.ts +20 -12
  17. package/dist/ir-to-client-js/html-template.d.ts.map +1 -1
  18. package/dist/ir-to-client-js/imports.d.ts.map +1 -1
  19. package/dist/ir-to-client-js/prop-handling.d.ts +25 -2
  20. package/dist/ir-to-client-js/prop-handling.d.ts.map +1 -1
  21. package/dist/ir-to-client-js/reactivity.d.ts +30 -2
  22. package/dist/ir-to-client-js/reactivity.d.ts.map +1 -1
  23. package/dist/ir-to-client-js/rewrite-props-object.d.ts.map +1 -1
  24. package/dist/ir-to-client-js/utils.d.ts.map +1 -1
  25. package/dist/jsx-to-ir.d.ts.map +1 -1
  26. package/dist/module-exports.d.ts.map +1 -1
  27. package/dist/relocate.d.ts.map +1 -1
  28. package/package.json +2 -2
  29. package/src/__tests__/binding-scope-ratchet.test.ts +1 -1
  30. package/src/__tests__/csr-materialize-loop-preamble-shadow.test.ts +76 -0
  31. package/src/__tests__/csr-substitute-enclosing-scope.test.ts +77 -0
  32. package/src/__tests__/identifier-pattern.test.ts +170 -0
  33. package/src/__tests__/loop-child-reactive-attr-const-shadow.test.ts +107 -0
  34. package/src/__tests__/rewrite-dynamic-imports.test.ts +98 -0
  35. package/src/adapters/jsx-adapter.ts +2 -1
  36. package/src/adapters/template-imports.ts +93 -0
  37. package/src/debug.ts +4 -3
  38. package/src/identifier-pattern.ts +79 -0
  39. package/src/index.ts +1 -1
  40. package/src/ir-to-client-js/collect-elements.ts +44 -15
  41. package/src/ir-to-client-js/control-flow/plan/build-event-delegation.ts +2 -1
  42. package/src/ir-to-client-js/control-flow/stringify/event-delegation.ts +2 -1
  43. package/src/ir-to-client-js/csr-substitute.ts +19 -2
  44. package/src/ir-to-client-js/html-template.ts +37 -31
  45. package/src/ir-to-client-js/imports.ts +2 -1
  46. package/src/ir-to-client-js/prop-handling.ts +28 -1
  47. package/src/ir-to-client-js/reactivity.ts +54 -4
  48. package/src/ir-to-client-js/rewrite-props-object.ts +2 -1
  49. package/src/ir-to-client-js/utils.ts +9 -8
  50. package/src/jsx-to-ir.ts +18 -9
  51. package/src/module-exports.ts +3 -2
  52. package/src/relocate.ts +2 -1
package/dist/index.js CHANGED
@@ -2332,6 +2332,24 @@ function templatePartsToJsExpr(parts, opts) {
2332
2332
  return result;
2333
2333
  }
2334
2334
 
2335
+ // src/identifier-pattern.ts
2336
+ function withUnicodeFlag(flags) {
2337
+ return flags.includes("u") ? flags : `${flags}u`;
2338
+ }
2339
+ function escapeIdentifierForRegex(name) {
2340
+ return name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
2341
+ }
2342
+ var ID_BOUNDARY_BEFORE = "(?<![\\p{ID_Continue}$])";
2343
+ var ID_BOUNDARY_AFTER = "(?![\\p{ID_Continue}$])";
2344
+ function identifierPattern(name, flags = "") {
2345
+ const esc = escapeIdentifierForRegex(name);
2346
+ return new RegExp(`${ID_BOUNDARY_BEFORE}${esc}${ID_BOUNDARY_AFTER}`, withUnicodeFlag(flags));
2347
+ }
2348
+ function identifierCallPattern(name, flags = "") {
2349
+ const esc = escapeIdentifierForRegex(name);
2350
+ return new RegExp(`${ID_BOUNDARY_BEFORE}${esc}\\s*\\(`, withUnicodeFlag(flags));
2351
+ }
2352
+
2335
2353
  // src/ir-to-client-js/utils.ts
2336
2354
  import {
2337
2355
  BF_KEY as DATA_KEY,
@@ -2458,9 +2476,6 @@ function inferDefaultValue(type) {
2458
2476
  return "{}";
2459
2477
  return "undefined";
2460
2478
  }
2461
- function escapeRegExp(s) {
2462
- return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
2463
- }
2464
2479
  function freeIdsFromRefs(refs) {
2465
2480
  const out = new Set;
2466
2481
  if (!refs)
@@ -2588,16 +2603,16 @@ function wrapLoopParamAsAccessor(expr, paramName, bindings) {
2588
2603
  if (bindings && bindings.length > 0) {
2589
2604
  return rewriteLoopBindingRefs(expr, bindings, "__bfItem()");
2590
2605
  }
2591
- const re = new RegExp(`\\b${escapeRegExp(paramName)}\\b(?!\\s*\\()(?!-)`, "g");
2592
- return replaceInExprContexts(expr, re, `${paramName}()`);
2606
+ const re = new RegExp(`${ID_BOUNDARY_BEFORE}${escapeIdentifierForRegex(paramName)}(?!\\s*\\()(?!-)${ID_BOUNDARY_AFTER}`, "gu");
2607
+ return replaceInExprContexts(expr, re, () => `${paramName}()`);
2593
2608
  }
2594
2609
  function rewriteLoopBindingRefs(expr, bindings, accessor) {
2595
2610
  const byName = new Map;
2596
2611
  for (const b of bindings)
2597
2612
  byName.set(b.name, b);
2598
2613
  const preprocessed = expandShorthandBindings(expr, new Set(byName.keys()));
2599
- const alt = bindings.map((b) => escapeRegExp(b.name)).join("|");
2600
- const re = new RegExp(`\\b(${alt})\\b`, "g");
2614
+ const alt = bindings.map((b) => escapeIdentifierForRegex(b.name)).join("|");
2615
+ const re = new RegExp(`${ID_BOUNDARY_BEFORE}(${alt})${ID_BOUNDARY_AFTER}`, "gu");
2601
2616
  return replaceInExprContexts(preprocessed, re, (_m, name) => renderLoopBindingAccess(byName.get(name), accessor));
2602
2617
  }
2603
2618
  function expandShorthandBindings(expr, bindingNames) {
@@ -2868,7 +2883,7 @@ function stopAt(...kinds) {
2868
2883
 
2869
2884
  // src/ir-to-client-js/csr-substitute.ts
2870
2885
  import ts4 from "typescript";
2871
- function csrSubstitute(value, env) {
2886
+ function csrSubstitute(value, env, enclosingScope) {
2872
2887
  if (!value || value.trim().length === 0) {
2873
2888
  return { rewritten: value, freeIdentifiers: new Set };
2874
2889
  }
@@ -2876,7 +2891,7 @@ function csrSubstitute(value, env) {
2876
2891
  let current = value;
2877
2892
  let lastFreeIdentifiers = new Set;
2878
2893
  for (let i = 0;i < maxIter; i++) {
2879
- const step = csrSubstituteOnce(current, env);
2894
+ const step = csrSubstituteOnce(current, env, enclosingScope);
2880
2895
  lastFreeIdentifiers = step.freeIdentifiers;
2881
2896
  if (step.rewritten === current)
2882
2897
  break;
@@ -2884,7 +2899,7 @@ function csrSubstitute(value, env) {
2884
2899
  }
2885
2900
  return { rewritten: current, freeIdentifiers: lastFreeIdentifiers };
2886
2901
  }
2887
- function csrSubstituteOnce(value, env) {
2902
+ function csrSubstituteOnce(value, env, enclosingScope) {
2888
2903
  if (!value || value.trim().length === 0) {
2889
2904
  return { rewritten: value, freeIdentifiers: new Set };
2890
2905
  }
@@ -2902,7 +2917,7 @@ function csrSubstituteOnce(value, env) {
2902
2917
  if (boundStack[i].has(name))
2903
2918
  return true;
2904
2919
  }
2905
- return false;
2920
+ return enclosingScope?.isBound(name) ?? false;
2906
2921
  };
2907
2922
  const recordSubstitution = (start, end, sub) => {
2908
2923
  splices.push({ start: start - OFFSET, end: end - OFFSET, text: `(${sub.replacement})` });
@@ -3090,6 +3105,83 @@ function derivesScopeFromSlot(comp) {
3090
3105
  return comp.slotId != null && comp.loopItemRoot !== true;
3091
3106
  }
3092
3107
 
3108
+ // src/scope/binding-scope.ts
3109
+ class BindingScope {
3110
+ frames;
3111
+ static EMPTY = new BindingScope([]);
3112
+ constructor(frames) {
3113
+ this.frames = frames;
3114
+ }
3115
+ enterLoopRow(loop) {
3116
+ const bindings = new Map;
3117
+ if (loop.paramBindings && loop.paramBindings.length > 0) {
3118
+ for (const b of loop.paramBindings)
3119
+ bindings.set(b.name, { source: "destructure" });
3120
+ } else {
3121
+ bindings.set(loop.param, { source: "item" });
3122
+ }
3123
+ if (loop.index != null)
3124
+ bindings.set(loop.index, { source: "index" });
3125
+ for (const name of loop.preamble?.declaredNames ?? [])
3126
+ bindings.set(name, { source: "preamble" });
3127
+ const frame = { kind: "loop-row", bindings };
3128
+ return new BindingScope([frame, ...this.frames]);
3129
+ }
3130
+ enterCallback(params) {
3131
+ const bindings = new Map;
3132
+ for (const name of params)
3133
+ bindings.set(name, { source: "param" });
3134
+ const frame = { kind: "callback", bindings };
3135
+ return new BindingScope([frame, ...this.frames]);
3136
+ }
3137
+ isBound(name) {
3138
+ for (const frame of this.frames) {
3139
+ if (frame.bindings.has(name))
3140
+ return true;
3141
+ }
3142
+ return false;
3143
+ }
3144
+ lookup(name) {
3145
+ for (let depth = 0;depth < this.frames.length; depth++) {
3146
+ const frame = this.frames[depth];
3147
+ const binding = frame.bindings.get(name);
3148
+ if (binding)
3149
+ return { depth, frame, binding };
3150
+ }
3151
+ return null;
3152
+ }
3153
+ boundNames() {
3154
+ if (this.boundNamesCache)
3155
+ return this.boundNamesCache;
3156
+ const names = new Set;
3157
+ for (const frame of this.frames) {
3158
+ for (const name of frame.bindings.keys())
3159
+ names.add(name);
3160
+ }
3161
+ this.boundNamesCache = names;
3162
+ return names;
3163
+ }
3164
+ boundNamesCache;
3165
+ valueBoundNamesCache;
3166
+ valueBoundNames() {
3167
+ if (this.valueBoundNamesCache)
3168
+ return this.valueBoundNamesCache;
3169
+ const names = new Set;
3170
+ for (const frame of this.frames) {
3171
+ for (const [name, binding] of frame.bindings) {
3172
+ if (binding.source === "item" || binding.source === "index" || binding.source === "destructure") {
3173
+ names.add(name);
3174
+ }
3175
+ }
3176
+ }
3177
+ this.valueBoundNamesCache = names;
3178
+ return names;
3179
+ }
3180
+ asShadowPredicate() {
3181
+ return (name) => this.isBound(name);
3182
+ }
3183
+ }
3184
+
3093
3185
  // src/ir-to-client-js/html-template.ts
3094
3186
  function createStringProtector() {
3095
3187
  const strings = [];
@@ -4315,7 +4407,7 @@ function generateCsrTemplateWithOpts(node, opts) {
4315
4407
  const source = templateExpr ?? expr;
4316
4408
  if (!source)
4317
4409
  return source;
4318
- const { rewritten, freeIdentifiers: freeIdentifiers2 } = csrSubstitute(source, env);
4410
+ const { rewritten, freeIdentifiers: freeIdentifiers2 } = csrSubstitute(source, env, opts.scope);
4319
4411
  if (unsafeLocalNames && unsafeLocalNames.size > 0 && setIntersects(freeIdentifiers2, unsafeLocalNames)) {
4320
4412
  return UNSAFE_TEMPLATE_EXPR;
4321
4413
  }
@@ -4457,15 +4549,8 @@ function generateCsrTemplateWithOpts(node, opts) {
4457
4549
  return `\${renderChild('${nameForRegistryRef(node.name)}', ${propsExpr}${keyArg || (slotArg ? ", undefined" : "")}${slotArg})}`;
4458
4550
  }
4459
4551
  case "loop": {
4460
- const boundHere = new Set(opts.loopBoundNames ?? []);
4461
- if (node.paramBindings && node.paramBindings.length > 0) {
4462
- for (const b of node.paramBindings)
4463
- boundHere.add(b.name);
4464
- } else if (!node.param.startsWith("[") && !node.param.startsWith("{")) {
4465
- boundHere.add(node.param);
4466
- }
4467
- if (node.index)
4468
- boundHere.add(node.index);
4552
+ const childScope = (opts.scope ?? BindingScope.EMPTY).enterLoopRow(node);
4553
+ const boundHere = childScope.boundNames();
4469
4554
  const childEnv = {
4470
4555
  ...env,
4471
4556
  substitutions: new Map([...env.substitutions].filter(([name]) => !boundHere.has(name)))
@@ -4474,7 +4559,7 @@ function generateCsrTemplateWithOpts(node, opts) {
4474
4559
  ...opts,
4475
4560
  loopDepth: loopDepth + 1,
4476
4561
  inHoistedChildren: false,
4477
- loopBoundNames: boundHere,
4562
+ scope: childScope,
4478
4563
  csrEnv: childEnv
4479
4564
  });
4480
4565
  let childTemplate = node.children.map(recurseInLoopBody).join("");
@@ -9330,7 +9415,7 @@ function findReachableNames(primaryRefs, declarations) {
9330
9415
  const reachable = new Set;
9331
9416
  const queue = [];
9332
9417
  for (const name of allNames) {
9333
- if (new RegExp(`\\b${name}\\b`).test(primaryRefs)) {
9418
+ if (identifierPattern(name).test(primaryRefs)) {
9334
9419
  reachable.add(name);
9335
9420
  queue.push(name);
9336
9421
  }
@@ -9339,7 +9424,7 @@ function findReachableNames(primaryRefs, declarations) {
9339
9424
  const current = queue.shift();
9340
9425
  const body = bodyMap.get(current) || "";
9341
9426
  for (const name of allNames) {
9342
- if (!reachable.has(name) && new RegExp(`\\b${name}\\b`).test(body)) {
9427
+ if (!reachable.has(name) && identifierPattern(name).test(body)) {
9343
9428
  reachable.add(name);
9344
9429
  queue.push(name);
9345
9430
  }
@@ -10022,85 +10107,6 @@ var toLocaleDatePlugin = {
10022
10107
 
10023
10108
  // src/jsx-to-ir.ts
10024
10109
  import { toHTMLAttrName, decodeEntities } from "@barefootjs/shared";
10025
-
10026
- // src/scope/binding-scope.ts
10027
- class BindingScope {
10028
- frames;
10029
- static EMPTY = new BindingScope([]);
10030
- constructor(frames) {
10031
- this.frames = frames;
10032
- }
10033
- enterLoopRow(loop) {
10034
- const bindings = new Map;
10035
- if (loop.paramBindings && loop.paramBindings.length > 0) {
10036
- for (const b of loop.paramBindings)
10037
- bindings.set(b.name, { source: "destructure" });
10038
- } else {
10039
- bindings.set(loop.param, { source: "item" });
10040
- }
10041
- if (loop.index != null)
10042
- bindings.set(loop.index, { source: "index" });
10043
- for (const name of loop.preamble?.declaredNames ?? [])
10044
- bindings.set(name, { source: "preamble" });
10045
- const frame = { kind: "loop-row", bindings };
10046
- return new BindingScope([frame, ...this.frames]);
10047
- }
10048
- enterCallback(params) {
10049
- const bindings = new Map;
10050
- for (const name of params)
10051
- bindings.set(name, { source: "param" });
10052
- const frame = { kind: "callback", bindings };
10053
- return new BindingScope([frame, ...this.frames]);
10054
- }
10055
- isBound(name) {
10056
- for (const frame of this.frames) {
10057
- if (frame.bindings.has(name))
10058
- return true;
10059
- }
10060
- return false;
10061
- }
10062
- lookup(name) {
10063
- for (let depth = 0;depth < this.frames.length; depth++) {
10064
- const frame = this.frames[depth];
10065
- const binding = frame.bindings.get(name);
10066
- if (binding)
10067
- return { depth, frame, binding };
10068
- }
10069
- return null;
10070
- }
10071
- boundNames() {
10072
- if (this.boundNamesCache)
10073
- return this.boundNamesCache;
10074
- const names = new Set;
10075
- for (const frame of this.frames) {
10076
- for (const name of frame.bindings.keys())
10077
- names.add(name);
10078
- }
10079
- this.boundNamesCache = names;
10080
- return names;
10081
- }
10082
- boundNamesCache;
10083
- valueBoundNamesCache;
10084
- valueBoundNames() {
10085
- if (this.valueBoundNamesCache)
10086
- return this.valueBoundNamesCache;
10087
- const names = new Set;
10088
- for (const frame of this.frames) {
10089
- for (const [name, binding] of frame.bindings) {
10090
- if (binding.source === "item" || binding.source === "index" || binding.source === "destructure") {
10091
- names.add(name);
10092
- }
10093
- }
10094
- }
10095
- this.valueBoundNamesCache = names;
10096
- return names;
10097
- }
10098
- asShadowPredicate() {
10099
- return (name) => this.isBound(name);
10100
- }
10101
- }
10102
-
10103
- // src/jsx-to-ir.ts
10104
10110
  var CLIENT_DIRECTIVE_INTERIOR_RE2 = /^\s*@client\s*$/;
10105
10111
  var BLOCK_COMMENT_RE2 = /\/\*([\s\S]*?)\*\//g;
10106
10112
  function hasLeadingClientDirective(expr, sourceFile) {
@@ -10363,17 +10369,17 @@ function createTransformContext(analyzer) {
10363
10369
  patterns: {
10364
10370
  signals: analyzer.signals.map((s) => ({
10365
10371
  getter: s.getter,
10366
- pattern: new RegExp(`\\b${s.getter}\\s*\\(`)
10372
+ pattern: identifierCallPattern(s.getter)
10367
10373
  })),
10368
10374
  memos: analyzer.memos.map((m) => ({
10369
10375
  name: m.name,
10370
- pattern: new RegExp(`\\b${m.name}\\s*\\(`)
10376
+ pattern: identifierCallPattern(m.name)
10371
10377
  })),
10372
- props: analyzer.propsParams.filter((p) => p.name !== "children").map((p) => ({ name: p.name, pattern: new RegExp(`\\b${p.name}\\b`) })),
10378
+ props: analyzer.propsParams.filter((p) => p.name !== "children").map((p) => ({ name: p.name, pattern: identifierPattern(p.name) })),
10373
10379
  constants: analyzer.localConstants.map((c) => ({
10374
10380
  name: c.name,
10375
10381
  value: c.value,
10376
- pattern: new RegExp(`\\b${c.name}\\b`)
10382
+ pattern: identifierPattern(c.name)
10377
10383
  }))
10378
10384
  },
10379
10385
  getJS(node) {
@@ -11145,7 +11151,7 @@ function transformExpressionInner(expr, ctx, node, isClientOnly) {
11145
11151
  };
11146
11152
  const reactive = isReactiveExpression(exprText, ctx, expr) || isReactiveOrigin(origin);
11147
11153
  const scopeValueNames = ctx.scope.valueBoundNames();
11148
- const refsLoopParam = scopeValueNames.size > 0 && Array.from(scopeValueNames).some((p) => new RegExp(`\\b${p}\\b`).test(exprText));
11154
+ const refsLoopParam = scopeValueNames.size > 0 && Array.from(scopeValueNames).some((p) => identifierPattern(p).test(exprText));
11149
11155
  const callsReactive = exprCallsReactiveGetters(expr, ctx);
11150
11156
  const hasCalls = exprHasFunctionCalls(expr);
11151
11157
  const needsSlot = reactive || isClientOnly || refsLoopParam || callsReactive || hasCalls;
@@ -11180,7 +11186,7 @@ function transformJsxFunctionCall(callExpr, jsxFunc, ctx, _isClientOnly) {
11180
11186
  const substitutedGetJS = (node) => {
11181
11187
  let text = baseGetJS(node);
11182
11188
  for (const [paramName, argExpr] of substitutions) {
11183
- text = text.replace(new RegExp(`\\b${paramName}\\b`, "g"), argExpr);
11189
+ text = text.replace(identifierPattern(paramName, "g"), () => argExpr);
11184
11190
  }
11185
11191
  return text;
11186
11192
  };
@@ -11222,7 +11228,7 @@ function transformMultiReturnJsxFunctionCall(callExpr, info, ctx) {
11222
11228
  const substitutedGetJS = (node) => {
11223
11229
  let text = baseGetJS(node);
11224
11230
  for (const [paramName, argExpr] of substitutions) {
11225
- text = text.replace(new RegExp(`\\b${paramName}\\b`, "g"), argExpr);
11231
+ text = text.replace(identifierPattern(paramName, "g"), () => argExpr);
11226
11232
  }
11227
11233
  return text;
11228
11234
  };
@@ -13767,7 +13773,7 @@ function referencesLoopParam(expr, ctx) {
13767
13773
  if (boundNames.size === 0)
13768
13774
  return false;
13769
13775
  for (const p of boundNames) {
13770
- if (new RegExp(`\\b${p}\\b`).test(expr))
13776
+ if (identifierPattern(p).test(expr))
13771
13777
  return true;
13772
13778
  }
13773
13779
  return false;
@@ -13849,7 +13855,7 @@ function hasReactiveAttributes(attrs, ctx) {
13849
13855
  const scopeValueNames = ctx.scope.valueBoundNames();
13850
13856
  if (scopeValueNames.size > 0) {
13851
13857
  for (const p of scopeValueNames) {
13852
- if (new RegExp(`\\b${p}\\b`).test(valueToCheck))
13858
+ if (identifierPattern(p).test(valueToCheck))
13853
13859
  return true;
13854
13860
  }
13855
13861
  }
@@ -14055,18 +14061,22 @@ function buildIfStatementChain(analyzer, ctx, opts) {
14055
14061
  }
14056
14062
 
14057
14063
  // src/ir-to-client-js/prop-handling.ts
14058
- function expandDynamicPropValue(value, ctx) {
14064
+ function expandDynamicPropValue(value, ctx, scope) {
14059
14065
  const trimmedValue = value.trim();
14066
+ if (scope?.isBound(trimmedValue))
14067
+ return value;
14060
14068
  const constant = ctx.localConstants.find((c) => c.name === trimmedValue);
14061
14069
  if (constant && constant.value) {
14062
14070
  return constant.value;
14063
14071
  }
14064
14072
  return value;
14065
14073
  }
14066
- function expandConstantForReactivity(expr, ctx, originalFreeIds) {
14074
+ function expandConstantForReactivity(expr, ctx, originalFreeIds, scope) {
14067
14075
  if (ctx.propsObjectName)
14068
14076
  return { expr, freeIds: originalFreeIds };
14069
14077
  const trimmedValue = expr.trim();
14078
+ if (scope?.isBound(trimmedValue))
14079
+ return { expr, freeIds: originalFreeIds };
14070
14080
  const constant = ctx.localConstants.find((c) => c.name === trimmedValue);
14071
14081
  if (constant && constant.value) {
14072
14082
  return { expr: constant.value, freeIds: constant.freeIdentifiers };
@@ -14102,6 +14112,16 @@ function getControlledPropName(signal, propsParams, propsObjectName = null) {
14102
14112
  }
14103
14113
 
14104
14114
  // src/ir-to-client-js/reactivity.ts
14115
+ function buildLoopRowScope(loopParam, loopParamBindings, preambleNames, loopIndex) {
14116
+ if (!loopParam)
14117
+ return;
14118
+ return BindingScope.EMPTY.enterLoopRow({
14119
+ param: loopParam,
14120
+ paramBindings: loopParamBindings,
14121
+ index: loopIndex,
14122
+ preamble: preambleNames && preambleNames.size > 0 ? { declaredNames: [...preambleNames] } : undefined
14123
+ });
14124
+ }
14105
14125
  function decideWrapFromAstFlags(node) {
14106
14126
  if (node.origin && isReactiveOrigin(node.origin)) {
14107
14127
  return { wrap: true, reason: "proven-reactive" };
@@ -14130,12 +14150,12 @@ function decideWrapForChildProp(expandedValue, ctx, prop) {
14130
14150
  }
14131
14151
  function needsEffectWrapper(expr, ctx, freeIdentifiers2) {
14132
14152
  for (const signal of ctx.signals) {
14133
- if (new RegExp(`\\b${signal.getter}\\s*\\(`).test(expr)) {
14153
+ if (identifierCallPattern(signal.getter).test(expr)) {
14134
14154
  return true;
14135
14155
  }
14136
14156
  }
14137
14157
  for (const memo of ctx.memos) {
14138
- if (new RegExp(`\\b${memo.name}\\s*\\(`).test(expr)) {
14158
+ if (identifierCallPattern(memo.name).test(expr)) {
14139
14159
  return true;
14140
14160
  }
14141
14161
  }
@@ -14325,8 +14345,9 @@ function traverseForComponents(node, components, skipConditionals = false) {
14325
14345
  }
14326
14346
  });
14327
14347
  }
14328
- function collectLoopChildReactiveTexts(node, ctx, loopParam, loopParamBindings, stopAtReactiveConditionals = false) {
14348
+ function collectLoopChildReactiveTexts(node, ctx, loopParam, loopParamBindings, stopAtReactiveConditionals = false, preambleNames, loopIndex) {
14329
14349
  const texts = [];
14350
+ const scope = buildLoopRowScope(loopParam, loopParamBindings, preambleNames, loopIndex);
14330
14351
  walkIR(node, false, {
14331
14352
  ...stopAt("loop", "async", "ifStatement"),
14332
14353
  expression: ({ node: n, scope: insideConditional }) => {
@@ -14335,7 +14356,7 @@ function collectLoopChildReactiveTexts(node, ctx, loopParam, loopParamBindings,
14335
14356
  if (n.preambleRegion)
14336
14357
  return;
14337
14358
  const originFreeIds = freeIdsFromRefs(n.origin?.freeRefs);
14338
- const expanded = expandConstantForReactivity(n.expr, ctx, originFreeIds);
14359
+ const expanded = expandConstantForReactivity(n.expr, ctx, originFreeIds, scope);
14339
14360
  const reactive = classifyReactivity(expanded.expr, ctx, loopParam, loopParamBindings, expanded.freeIds).kind !== "none" || decideWrapFromAstFlags(n).wrap;
14340
14361
  if (!reactive)
14341
14362
  return;
@@ -14359,8 +14380,9 @@ function anyNameIn(names, set) {
14359
14380
  return true;
14360
14381
  return false;
14361
14382
  }
14362
- function collectLoopChildReactiveAttrs(node, ctx, loopParam, loopParamBindings, stopAtReactiveConditionals = false, preambleNames) {
14383
+ function collectLoopChildReactiveAttrs(node, ctx, loopParam, loopParamBindings, stopAtReactiveConditionals = false, preambleNames, loopIndex) {
14363
14384
  const attrs = [];
14385
+ const scope = buildLoopRowScope(loopParam, loopParamBindings, preambleNames, loopIndex);
14364
14386
  traverseElements(node, (el) => {
14365
14387
  if (el.slotId) {
14366
14388
  for (const attr of el.attrs) {
@@ -14373,7 +14395,7 @@ function collectLoopChildReactiveAttrs(node, ctx, loopParam, loopParamBindings,
14373
14395
  const valueStr = attrValueToString(attr.value);
14374
14396
  if (!valueStr)
14375
14397
  continue;
14376
- const expanded = expandConstantForReactivity(valueStr, ctx, attr.freeIdentifiers);
14398
+ const expanded = expandConstantForReactivity(valueStr, ctx, attr.freeIdentifiers, scope);
14377
14399
  const readsPreamble = preambleNames !== undefined && preambleNames.size > 0 && anyNameIn(expanded.freeIds ?? extractFreeIdentifiersFromText(expanded.expr), preambleNames);
14378
14400
  const reactive = classifyReactivity(expanded.expr, ctx, loopParam, loopParamBindings, expanded.freeIds).kind !== "none" || readsPreamble || attr.callsReactiveGetters || attr.hasFunctionCalls;
14379
14401
  if (!attr.clientOnly && !reactive)
@@ -14678,13 +14700,13 @@ function collectInnerLoops(nodes, siblingOffsets, outerLoopParam, ctx, options)
14678
14700
  const emitDepth = fixedDepth ?? scope.depth + 1;
14679
14701
  const loopParamsForTemplate = outerLoopParam ? [outerLoopParam, { param: n.param, bindings: n.paramBindings }] : undefined;
14680
14702
  const template = n.children.map((c) => irToPlaceholderTemplate(c, undefined, emitDepth, loopParamsForTemplate)).join("");
14681
- const refsOuter = outerLoopParam ? new RegExp(`\\b${outerLoopParam}\\b`).test(n.array) : false;
14703
+ const refsOuter = outerLoopParam ? identifierPattern(outerLoopParam).test(n.array) : false;
14682
14704
  const bindings = emptyLoopChildBindings();
14683
14705
  const innerPreambleNames = preambleNamesOf(n);
14684
14706
  if (ctx) {
14685
14707
  for (const child of n.children) {
14686
- bindings.reactiveTexts.push(...collectLoopChildReactiveTexts(child, ctx, n.param, n.paramBindings));
14687
- bindings.reactiveAttrs.push(...collectLoopChildReactiveAttrs(child, ctx, n.param, n.paramBindings, false, innerPreambleNames));
14708
+ bindings.reactiveTexts.push(...collectLoopChildReactiveTexts(child, ctx, n.param, n.paramBindings, false, innerPreambleNames, n.index));
14709
+ bindings.reactiveAttrs.push(...collectLoopChildReactiveAttrs(child, ctx, n.param, n.paramBindings, false, innerPreambleNames, n.index));
14688
14710
  bindings.refs.push(...collectLoopChildRefs(child));
14689
14711
  }
14690
14712
  }
@@ -14711,7 +14733,7 @@ function collectInnerLoops(nodes, siblingOffsets, outerLoopParam, ctx, options)
14711
14733
  bindings.events.push(...collectLoopChildEventsWithNesting(child));
14712
14734
  }
14713
14735
  if (ctx) {
14714
- bindings.conditionals.push(...collectLoopChildConditionals({ type: "fragment", children: n.children, loc: n.loc }, ctx, siblingOffsets, n.param, n.paramBindings));
14736
+ bindings.conditionals.push(...collectLoopChildConditionals({ type: "fragment", children: n.children, loc: n.loc }, ctx, siblingOffsets, n.param, n.paramBindings, innerPreambleNames, n.index));
14715
14737
  }
14716
14738
  }
14717
14739
  result.push({
@@ -14907,7 +14929,7 @@ function collectElements(node, ctx, siblingOffsets, insideConditional = false) {
14907
14929
  return;
14908
14930
  const projectionInner = l.method === "flatMap" && l.children.length === 1 && l.children[0].type === "loop" ? l.children[0] : undefined;
14909
14931
  const childHandlers = [];
14910
- const bindings = projectionInner ? emptyLoopChildBindings() : collectLoopChildBindings(l.children, ctx, siblingOffsets, l.param, l.paramBindings, preambleNamesOf(l));
14932
+ const bindings = projectionInner ? emptyLoopChildBindings() : collectLoopChildBindings(l.children, ctx, siblingOffsets, l.param, l.paramBindings, preambleNamesOf(l), l.index);
14911
14933
  if (!projectionInner) {
14912
14934
  for (const child of l.children) {
14913
14935
  childHandlers.push(...collectEventHandlersFromIR(child));
@@ -15162,7 +15184,7 @@ function collectBranchLoops(node, ctx, siblingOffsets) {
15162
15184
  } else {
15163
15185
  childTemplate = n.children.map((c) => irToHtmlTemplate(c, undefined, 0, branchLoopParamSpec)).join("");
15164
15186
  }
15165
- const branchBindings = ctx && !projectionInner ? collectLoopChildBindings(n.children, ctx, siblingOffsets, n.param, n.paramBindings, preambleNamesOf(n)) : emptyLoopChildBindings();
15187
+ const branchBindings = ctx && !projectionInner ? collectLoopChildBindings(n.children, ctx, siblingOffsets, n.param, n.paramBindings, preambleNamesOf(n), n.index) : emptyLoopChildBindings();
15166
15188
  loops.push({
15167
15189
  kind: "branch",
15168
15190
  array: n.array,
@@ -15248,19 +15270,20 @@ function preambleNamesOf(loop) {
15248
15270
  const declared = loop.preamble?.declaredNames;
15249
15271
  return declared && declared.length > 0 ? new Set(declared) : undefined;
15250
15272
  }
15251
- function collectLoopChildBindings(children, ctx, siblingOffsets, loopParam, loopParamBindings, preambleNames) {
15273
+ function collectLoopChildBindings(children, ctx, siblingOffsets, loopParam, loopParamBindings, preambleNames, loopIndex) {
15252
15274
  const bindings = emptyLoopChildBindings();
15253
15275
  for (const child of children) {
15254
15276
  bindings.events.push(...collectLoopChildEventsWithNesting(child));
15255
- bindings.reactiveAttrs.push(...collectLoopChildReactiveAttrs(child, ctx, loopParam, loopParamBindings, true, preambleNames));
15256
- bindings.reactiveTexts.push(...collectLoopChildReactiveTexts(child, ctx, loopParam, loopParamBindings, true));
15277
+ bindings.reactiveAttrs.push(...collectLoopChildReactiveAttrs(child, ctx, loopParam, loopParamBindings, true, preambleNames, loopIndex));
15278
+ bindings.reactiveTexts.push(...collectLoopChildReactiveTexts(child, ctx, loopParam, loopParamBindings, true, preambleNames, loopIndex));
15257
15279
  bindings.refs.push(...collectLoopChildRefs(child));
15258
- bindings.conditionals.push(...collectLoopChildConditionals(child, ctx, siblingOffsets, loopParam, loopParamBindings));
15280
+ bindings.conditionals.push(...collectLoopChildConditionals(child, ctx, siblingOffsets, loopParam, loopParamBindings, preambleNames, loopIndex));
15259
15281
  }
15260
15282
  return bindings;
15261
15283
  }
15262
- function collectLoopChildConditionals(node, ctx, siblingOffsets, loopParam, loopParamBindings) {
15284
+ function collectLoopChildConditionals(node, ctx, siblingOffsets, loopParam, loopParamBindings, preambleNames, loopIndex) {
15263
15285
  const conditionals = [];
15286
+ const scope = buildLoopRowScope(loopParam, loopParamBindings, preambleNames, loopIndex);
15264
15287
  const refsAnyBindingViaFreeIds = (freeIds) => {
15265
15288
  if (loopParamBindings && loopParamBindings.length > 0) {
15266
15289
  for (const b of loopParamBindings) {
@@ -15280,7 +15303,7 @@ function collectLoopChildConditionals(node, ctx, siblingOffsets, loopParam, loop
15280
15303
  const refsLoopParamInSource = refsAnyBindingViaFreeIds(sourceFreeIds);
15281
15304
  if (!n.reactive && !refsLoopParamInSource)
15282
15305
  return;
15283
- const expanded = expandConstantForReactivity(n.condition, ctx, sourceFreeIds);
15306
+ const expanded = expandConstantForReactivity(n.condition, ctx, sourceFreeIds, scope);
15284
15307
  if (classifyReactivity(expanded.expr, ctx, loopParam, loopParamBindings, expanded.freeIds).kind === "none")
15285
15308
  return;
15286
15309
  const loopParamsForCond = loopParam ? [{ param: loopParam, bindings: loopParamBindings }] : undefined;
@@ -15291,23 +15314,23 @@ function collectLoopChildConditionals(node, ctx, siblingOffsets, loopParam, loop
15291
15314
  condition: expanded.expr,
15292
15315
  whenTrueHtml,
15293
15316
  whenFalseHtml,
15294
- whenTrue: summarizeLoopChildBranch(n.whenTrue, ctx, siblingOffsets, loopParam, loopParamBindings),
15295
- whenFalse: summarizeLoopChildBranch(n.whenFalse, ctx, siblingOffsets, loopParam, loopParamBindings),
15317
+ whenTrue: summarizeLoopChildBranch(n.whenTrue, ctx, siblingOffsets, loopParam, loopParamBindings, preambleNames, loopIndex),
15318
+ whenFalse: summarizeLoopChildBranch(n.whenFalse, ctx, siblingOffsets, loopParam, loopParamBindings, preambleNames, loopIndex),
15296
15319
  ...expanded.freeIds !== undefined && { conditionFreeIdentifiers: expanded.freeIds }
15297
15320
  });
15298
15321
  }
15299
15322
  });
15300
15323
  return conditionals;
15301
15324
  }
15302
- function summarizeLoopChildBranch(node, ctx, siblingOffsets, loopParam, loopParamBindings) {
15325
+ function summarizeLoopChildBranch(node, ctx, siblingOffsets, loopParam, loopParamBindings, preambleNames, loopIndex) {
15303
15326
  const inner = collectInnerLoops([node], siblingOffsets, loopParam, ctx, branchInnerLoopOptions);
15304
15327
  return {
15305
15328
  childComponents: collectConditionalBranchChildComponents(node),
15306
15329
  innerLoops: inner.length > 0 ? inner : undefined,
15307
- conditionals: collectLoopChildConditionals(node, ctx, siblingOffsets, loopParam, loopParamBindings),
15330
+ conditionals: collectLoopChildConditionals(node, ctx, siblingOffsets, loopParam, loopParamBindings, preambleNames, loopIndex),
15308
15331
  events: collectConditionalBranchEvents(node),
15309
- reactiveAttrs: collectLoopChildReactiveAttrs(node, ctx, loopParam, loopParamBindings, true),
15310
- reactiveTexts: node.type === "expression" && node.hasFunctionCalls ? [] : collectLoopChildReactiveTexts(node, ctx, loopParam, loopParamBindings, true)
15332
+ reactiveAttrs: collectLoopChildReactiveAttrs(node, ctx, loopParam, loopParamBindings, true, preambleNames, loopIndex),
15333
+ reactiveTexts: node.type === "expression" && node.hasFunctionCalls ? [] : collectLoopChildReactiveTexts(node, ctx, loopParam, loopParamBindings, true, preambleNames, loopIndex)
15311
15334
  };
15312
15335
  }
15313
15336
 
@@ -15879,7 +15902,7 @@ var MODULE_CONSTANTS_PLACEHOLDER = "/* __MODULE_LEVEL_CONSTANTS__ */";
15879
15902
  function detectUsedImports(code) {
15880
15903
  const used = new Set;
15881
15904
  for (const name of RUNTIME_IMPORT_CANDIDATES) {
15882
- if (new RegExp(`\\b${name}\\s*\\(`).test(code)) {
15905
+ if (identifierCallPattern(name).test(code)) {
15883
15906
  used.add(name);
15884
15907
  }
15885
15908
  }
@@ -16298,7 +16321,7 @@ function containsAnyIdentifier(node, names) {
16298
16321
  function scanRefsByName(text, bindings) {
16299
16322
  const result = new Map;
16300
16323
  for (const name of bindings.keys()) {
16301
- const re = new RegExp(`\\b${name}\\b`);
16324
+ const re = identifierPattern(name);
16302
16325
  if (re.test(text))
16303
16326
  result.set(name, []);
16304
16327
  }
@@ -18992,7 +19015,7 @@ function buildStaticArrayDelegationPlan(elem, profileComponentName) {
18992
19015
  function buildKeyedOrIndexLookup(args) {
18993
19016
  const hasBindings = (args.paramBindings?.length ?? 0) > 0;
18994
19017
  if (args.key !== null) {
18995
- const keyWithItem = hasBindings ? substituteLoopBindings(args.key, args.paramBindings, "item") : args.key.replace(new RegExp(`\\b${args.param}\\b`, "g"), "item");
19018
+ const keyWithItem = hasBindings ? substituteLoopBindings(args.key, args.paramBindings, "item") : args.key.replace(identifierPattern(args.param, "g"), "item");
18996
19019
  return {
18997
19020
  kind: "keyed",
18998
19021
  arrayExpr: args.array,
@@ -21198,7 +21221,7 @@ function emitKeyedLookup(ls, ev, handlerCall, lookup) {
21198
21221
  }
21199
21222
  for (const nested of ev.nestedLoops) {
21200
21223
  const rawKey = nested.key ?? "";
21201
- const innerKeyExpr = nested.paramBindings && nested.paramBindings.length > 0 ? substituteLoopBindings(rawKey, nested.paramBindings, "item") : rawKey.replace(new RegExp(`\\b${nested.param}\\b`, "g"), "item");
21224
+ const innerKeyExpr = nested.paramBindings && nested.paramBindings.length > 0 ? substituteLoopBindings(rawKey, nested.paramBindings, "item") : rawKey.replace(identifierPattern(nested.param, "g"), "item");
21202
21225
  const outerRef = hasBindings ? "__bfLoopItem" : param;
21203
21226
  ls.push(` const ${nested.param} = ${outerRef} && ${nested.array}.find(item => String(${innerKeyExpr}) === innerKey${nested.depth})`);
21204
21227
  }
@@ -21892,7 +21915,7 @@ function rewritePropsObjectRef(code, propsObjectName) {
21892
21915
  const srcPropsName = propsObjectName ?? "props";
21893
21916
  if (srcPropsName === PROPS_PARAM)
21894
21917
  return code;
21895
- if (!new RegExp(`\\b${srcPropsName}\\b`).test(code))
21918
+ if (!identifierPattern(srcPropsName).test(code))
21896
21919
  return code;
21897
21920
  const sourceFile = ts19.createSourceFile("init-body.ts", code, ts19.ScriptTarget.Latest, true, ts19.ScriptKind.TS);
21898
21921
  const spans = [];
@@ -24637,7 +24660,7 @@ class JsxAdapter extends BaseAdapter {
24637
24660
  lines.push(` const ${signal.getter} = () => ${initialValue}`);
24638
24661
  }
24639
24662
  if (signal.setter) {
24640
- const setterUsed = new RegExp(`\\b${signal.setter}\\b`).test(setterRefText);
24663
+ const setterUsed = identifierPattern(signal.setter).test(setterRefText);
24641
24664
  if (setterUsed) {
24642
24665
  lines.push(` const ${signal.setter} = (..._args: any[]) => {}`);
24643
24666
  }
@@ -24835,6 +24858,7 @@ class JsxAdapter extends BaseAdapter {
24835
24858
  }
24836
24859
 
24837
24860
  // src/adapters/template-imports.ts
24861
+ import ts25 from "typescript";
24838
24862
  var CLIENT_PACKAGE_SOURCES = new Set([
24839
24863
  "@barefootjs/client",
24840
24864
  "@barefootjs/client/runtime"
@@ -24881,6 +24905,44 @@ function rewriteImportsForTemplate(imports, shimSource, rewriteRelative) {
24881
24905
  function specKey(s) {
24882
24906
  return `${s.isDefault ? "d" : ""}${s.isNamespace ? "n" : ""}:${s.name}:${s.alias ?? ""}`;
24883
24907
  }
24908
+ function rewriteDynamicImportsInSource(sourceText, rewriteRelative) {
24909
+ if (!sourceText.includes("import"))
24910
+ return sourceText;
24911
+ const sf = ts25.createSourceFile("bf-template-fragment.tsx", sourceText, ts25.ScriptTarget.Latest, false, ts25.ScriptKind.TSX);
24912
+ const edits = [];
24913
+ const visit3 = (node) => {
24914
+ if (ts25.isCallExpression(node) && node.expression.kind === ts25.SyntaxKind.ImportKeyword && node.arguments.length > 0 && ts25.isStringLiteralLike(node.arguments[0])) {
24915
+ collect(node.arguments[0]);
24916
+ }
24917
+ if (ts25.isImportTypeNode(node) && ts25.isLiteralTypeNode(node.argument)) {
24918
+ const literal = node.argument.literal;
24919
+ if (ts25.isStringLiteralLike(literal))
24920
+ collect(literal);
24921
+ }
24922
+ ts25.forEachChild(node, visit3);
24923
+ };
24924
+ const collect = (literal) => {
24925
+ const specifier = literal.text;
24926
+ if (!specifier.startsWith("."))
24927
+ return;
24928
+ const next = rewriteRelative(specifier);
24929
+ if (next === specifier)
24930
+ return;
24931
+ edits.push({
24932
+ start: literal.getStart(sf),
24933
+ end: literal.getEnd(),
24934
+ text: `'${next}'`
24935
+ });
24936
+ };
24937
+ ts25.forEachChild(sf, visit3);
24938
+ if (edits.length === 0)
24939
+ return sourceText;
24940
+ let out = sourceText;
24941
+ for (const edit of edits.sort((a, b) => b.start - a.start)) {
24942
+ out = out.slice(0, edit.start) + edit.text + out.slice(edit.end);
24943
+ }
24944
+ return out;
24945
+ }
24884
24946
 
24885
24947
  // src/adapters/test-adapter.ts
24886
24948
  class TestAdapter extends JsxAdapter {
@@ -25667,7 +25729,7 @@ function dangerousInnerHtmlDiagnostic(expr, loc, reason) {
25667
25729
  };
25668
25730
  }
25669
25731
  // src/combine-client-js.ts
25670
- import ts25 from "typescript";
25732
+ import ts26 from "typescript";
25671
25733
  var CHILD_PLACEHOLDER_RE = /import '\/\* @bf-child:(\w+) \*\/'/g;
25672
25734
  function combineParentChildClientJs(files) {
25673
25735
  const result = new Map;
@@ -25724,10 +25786,10 @@ function combineParentChildClientJs(files) {
25724
25786
  return result;
25725
25787
  }
25726
25788
  function parseAndMerge(content, importsBySource, otherImports, codeSections) {
25727
- const sourceFile = ts25.createSourceFile("combine.js", content, ts25.ScriptTarget.Latest, false, ts25.ScriptKind.JS);
25789
+ const sourceFile = ts26.createSourceFile("combine.js", content, ts26.ScriptTarget.Latest, false, ts26.ScriptKind.JS);
25728
25790
  const importSpans = [];
25729
25791
  for (const stmt of sourceFile.statements) {
25730
- if (!ts25.isImportDeclaration(stmt))
25792
+ if (!ts26.isImportDeclaration(stmt))
25731
25793
  continue;
25732
25794
  const start = stmt.getStart(sourceFile);
25733
25795
  const end = stmt.getEnd();
@@ -25737,8 +25799,8 @@ function parseAndMerge(content, importsBySource, otherImports, codeSections) {
25737
25799
  continue;
25738
25800
  const clause = stmt.importClause;
25739
25801
  const bindings = clause?.namedBindings;
25740
- const specifier = ts25.isStringLiteral(stmt.moduleSpecifier) ? stmt.moduleSpecifier.text : "";
25741
- if (clause && !clause.name && bindings && ts25.isNamedImports(bindings)) {
25802
+ const specifier = ts26.isStringLiteral(stmt.moduleSpecifier) ? stmt.moduleSpecifier.text : "";
25803
+ if (clause && !clause.name && bindings && ts26.isNamedImports(bindings)) {
25742
25804
  if (!importsBySource.has(specifier)) {
25743
25805
  importsBySource.set(specifier, new Set);
25744
25806
  }
@@ -25905,7 +25967,7 @@ function escapeRe(s) {
25905
25967
  return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
25906
25968
  }
25907
25969
  // src/debug.ts
25908
- import ts26 from "typescript";
25970
+ import ts27 from "typescript";
25909
25971
  function buildComponentGraph(source, filePath, componentName) {
25910
25972
  const ctx = analyzeComponent(source, filePath, componentName);
25911
25973
  if (!ctx.jsxReturn) {
@@ -27190,7 +27252,7 @@ function truncateExpr(expr, max = 40) {
27190
27252
  function exprReadsPropMember(expr, propsObjectName) {
27191
27253
  let sf;
27192
27254
  try {
27193
- sf = ts26.createSourceFile("__attr.tsx", `(${expr})`, ts26.ScriptTarget.Latest, true, ts26.ScriptKind.TSX);
27255
+ sf = ts27.createSourceFile("__attr.tsx", `(${expr})`, ts27.ScriptTarget.Latest, true, ts27.ScriptKind.TSX);
27194
27256
  } catch {
27195
27257
  return false;
27196
27258
  }
@@ -27198,11 +27260,11 @@ function exprReadsPropMember(expr, propsObjectName) {
27198
27260
  const visit3 = (n) => {
27199
27261
  if (found)
27200
27262
  return;
27201
- if (ts26.isPropertyAccessExpression(n) && ts26.isIdentifier(n.expression) && n.expression.text === propsObjectName && n.name.text !== "children") {
27263
+ if (ts27.isPropertyAccessExpression(n) && ts27.isIdentifier(n.expression) && n.expression.text === propsObjectName && n.name.text !== "children") {
27202
27264
  found = true;
27203
27265
  return;
27204
27266
  }
27205
- ts26.forEachChild(n, visit3);
27267
+ ts27.forEachChild(n, visit3);
27206
27268
  };
27207
27269
  visit3(sf);
27208
27270
  return found;
@@ -27232,12 +27294,12 @@ function attrValueToString2(value) {
27232
27294
  function extractReactiveDeps(expr, signalGetters, memoNames) {
27233
27295
  const deps = [];
27234
27296
  for (const getter of signalGetters) {
27235
- if (new RegExp(`\\b${getter}\\s*\\(`).test(expr)) {
27297
+ if (identifierCallPattern(getter).test(expr)) {
27236
27298
  deps.push(getter);
27237
27299
  }
27238
27300
  }
27239
27301
  for (const memo of memoNames) {
27240
- if (new RegExp(`\\b${memo}\\s*\\(`).test(expr)) {
27302
+ if (identifierCallPattern(memo).test(expr)) {
27241
27303
  deps.push(memo);
27242
27304
  }
27243
27305
  }
@@ -27250,7 +27312,7 @@ function extractSetterRefs(expr, signalGetters) {
27250
27312
  refs.push(match[1]);
27251
27313
  }
27252
27314
  for (const getter of signalGetters) {
27253
- if (new RegExp(`\\b${getter}\\s*\\(`).test(expr)) {
27315
+ if (identifierCallPattern(getter).test(expr)) {
27254
27316
  refs.push(getter);
27255
27317
  }
27256
27318
  }
@@ -27272,7 +27334,7 @@ function findSourceFile2(meta) {
27272
27334
  return null;
27273
27335
  }
27274
27336
  // src/profiler.ts
27275
- import ts27 from "typescript";
27337
+ import ts28 from "typescript";
27276
27338
  var PROFILE_SCHEMA_VERSION = 1;
27277
27339
  var DEFAULT_FANOUT_THRESHOLD = 8;
27278
27340
  function buildStaticBudget(source, filePath, componentName, options = {}) {
@@ -27542,15 +27604,15 @@ function joinProfilerEvents(events, index) {
27542
27604
  return { joined, unattributed, diagnostics };
27543
27605
  }
27544
27606
  function findUninstrumentedEffects(source, filePath, instrumentedLines) {
27545
- const sf = ts27.createSourceFile(filePath, source, ts27.ScriptTarget.Latest, true, ts27.ScriptKind.TSX);
27607
+ const sf = ts28.createSourceFile(filePath, source, ts28.ScriptTarget.Latest, true, ts28.ScriptKind.TSX);
27546
27608
  const out = [];
27547
27609
  const visit3 = (node) => {
27548
- if (ts27.isCallExpression(node) && ts27.isIdentifier(node.expression) && node.expression.text === "createEffect") {
27610
+ if (ts28.isCallExpression(node) && ts28.isIdentifier(node.expression) && node.expression.text === "createEffect") {
27549
27611
  const line = sf.getLineAndCharacterOfPosition(node.getStart(sf)).line + 1;
27550
27612
  if (!instrumentedLines.has(line))
27551
27613
  out.push({ file: filePath, line });
27552
27614
  }
27553
- ts27.forEachChild(node, visit3);
27615
+ ts28.forEachChild(node, visit3);
27554
27616
  };
27555
27617
  visit3(sf);
27556
27618
  out.sort((a, b) => a.line - b.line);
@@ -27858,13 +27920,13 @@ function assessBatchSafety(args) {
27858
27920
  const signalGetters = new Set(args.graph.signals.map((s) => s.name));
27859
27921
  let sf;
27860
27922
  try {
27861
- sf = ts27.createSourceFile("__h.ts", `const __h = ${args.handler}`, ts27.ScriptTarget.Latest, true);
27923
+ sf = ts28.createSourceFile("__h.ts", `const __h = ${args.handler}`, ts28.ScriptTarget.Latest, true);
27862
27924
  } catch {
27863
27925
  return "unverified";
27864
27926
  }
27865
27927
  const calls = [];
27866
27928
  const visit3 = (node) => {
27867
- if (ts27.isCallExpression(node) && ts27.isIdentifier(node.expression)) {
27929
+ if (ts28.isCallExpression(node) && ts28.isIdentifier(node.expression)) {
27868
27930
  const name = node.expression.text;
27869
27931
  if (setters.has(name))
27870
27932
  calls.push({ pos: node.getStart(sf), kind: "write" });
@@ -27873,7 +27935,7 @@ function assessBatchSafety(args) {
27873
27935
  else if (!signalGetters.has(name) && !memoNames.has(name))
27874
27936
  calls.push({ pos: node.getStart(sf), kind: "risky" });
27875
27937
  }
27876
- ts27.forEachChild(node, visit3);
27938
+ ts28.forEachChild(node, visit3);
27877
27939
  };
27878
27940
  visit3(sf);
27879
27941
  calls.sort((a, b) => a.pos - b.pos);
@@ -28519,6 +28581,7 @@ export {
28519
28581
  serializeParsedExpr,
28520
28582
  searchParamsLocalNames,
28521
28583
  rewriteImportsForTemplate,
28584
+ rewriteDynamicImportsInSource,
28522
28585
  resolveStaticLoopSource,
28523
28586
  resolveSetters,
28524
28587
  resolveDangerousInnerHtml,