@barefootjs/cli 0.31.2 → 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.
- package/dist/index.js +409 -123
- 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(
|
|
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) =>
|
|
3042
|
-
const re = new RegExp(
|
|
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
|
|
4842
|
-
|
|
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
|
-
|
|
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",
|
|
@@ -6164,7 +6352,8 @@ function visit(node, ctx2, targetComponentName, namedExports) {
|
|
|
6164
6352
|
if (!ctx2.componentNode) {
|
|
6165
6353
|
collectAmbientGlobals(node, ctx2);
|
|
6166
6354
|
}
|
|
6167
|
-
|
|
6355
|
+
const isDeclareStatement = ts9.isVariableStatement(node) && (node.modifiers?.some((m) => m.kind === ts9.SyntaxKind.DeclareKeyword) ?? false);
|
|
6356
|
+
if (ts9.isVariableStatement(node) && !ctx2.componentNode && !isDeclareStatement) {
|
|
6168
6357
|
const isExported = node.modifiers?.some((m) => m.kind === ts9.SyntaxKind.ExportKeyword) ?? false;
|
|
6169
6358
|
const isLet = (node.declarationList.flags & ts9.NodeFlags.Let) !== 0;
|
|
6170
6359
|
const isModuleClientDirective = hasLeadingClientDirectiveOnStatement(node, ctx2.sourceFile);
|
|
@@ -6180,7 +6369,7 @@ function visit(node, ctx2, targetComponentName, namedExports) {
|
|
|
6180
6369
|
}
|
|
6181
6370
|
continue;
|
|
6182
6371
|
}
|
|
6183
|
-
if (ts9.isIdentifier(decl.name) && decl.initializer && !isArrowComponentFunction(decl)) {
|
|
6372
|
+
if (ts9.isIdentifier(decl.name) && (decl.initializer || isLet) && !isArrowComponentFunction(decl)) {
|
|
6184
6373
|
collectConstant(decl, ctx2, true, isLet ? "let" : "const", isExported);
|
|
6185
6374
|
}
|
|
6186
6375
|
}
|
|
@@ -7590,6 +7779,7 @@ function collectConstant(node, ctx2, _isModule, declarationKind = "const", isExp
|
|
|
7590
7779
|
value: value2,
|
|
7591
7780
|
parsed,
|
|
7592
7781
|
typedValue: typedValue !== value2 ? typedValue : void 0,
|
|
7782
|
+
typeAnnotation: node.type ? node.type.getText(ctx2.sourceFile) : void 0,
|
|
7593
7783
|
valueBranches,
|
|
7594
7784
|
declarationKind,
|
|
7595
7785
|
isExported,
|
|
@@ -9284,7 +9474,7 @@ function findReachableNames(primaryRefs, declarations) {
|
|
|
9284
9474
|
const reachable = /* @__PURE__ */ new Set();
|
|
9285
9475
|
const queue = [];
|
|
9286
9476
|
for (const name2 of allNames) {
|
|
9287
|
-
if (
|
|
9477
|
+
if (identifierPattern(name2).test(primaryRefs)) {
|
|
9288
9478
|
reachable.add(name2);
|
|
9289
9479
|
queue.push(name2);
|
|
9290
9480
|
}
|
|
@@ -9293,7 +9483,7 @@ function findReachableNames(primaryRefs, declarations) {
|
|
|
9293
9483
|
const current = queue.shift();
|
|
9294
9484
|
const body2 = bodyMap.get(current) || "";
|
|
9295
9485
|
for (const name2 of allNames) {
|
|
9296
|
-
if (!reachable.has(name2) &&
|
|
9486
|
+
if (!reachable.has(name2) && identifierPattern(name2).test(body2)) {
|
|
9297
9487
|
reachable.add(name2);
|
|
9298
9488
|
queue.push(name2);
|
|
9299
9489
|
}
|
|
@@ -9319,6 +9509,7 @@ function extractFunctionParams(value2) {
|
|
|
9319
9509
|
var init_module_exports = __esm({
|
|
9320
9510
|
"../jsx/src/module-exports.ts"() {
|
|
9321
9511
|
"use strict";
|
|
9512
|
+
init_identifier_pattern();
|
|
9322
9513
|
}
|
|
9323
9514
|
});
|
|
9324
9515
|
|
|
@@ -10151,8 +10342,9 @@ function rewriteBarePropRefs2(text, expr, ctx2) {
|
|
|
10151
10342
|
const dateLowered = lowerToLocaleDateCalls(lowerDateCalls(text, expr, ctx2), expr, ctx2);
|
|
10152
10343
|
let propNames = getDestructuredPropNames(ctx2);
|
|
10153
10344
|
if (!propNames) return dateLowered === text ? void 0 : dateLowered;
|
|
10154
|
-
|
|
10155
|
-
|
|
10345
|
+
const shadowingNames = ctx2.scope.boundNames();
|
|
10346
|
+
if (shadowingNames.size > 0) {
|
|
10347
|
+
const filtered = new Set([...propNames].filter((n) => !shadowingNames.has(n)));
|
|
10156
10348
|
if (filtered.size === 0) return dateLowered === text ? void 0 : dateLowered;
|
|
10157
10349
|
propNames = filtered;
|
|
10158
10350
|
}
|
|
@@ -10220,22 +10412,22 @@ function createTransformContext(analyzer) {
|
|
|
10220
10412
|
spreadIdCounter: 0,
|
|
10221
10413
|
isRoot: true,
|
|
10222
10414
|
insideComponentChildren: false,
|
|
10223
|
-
|
|
10415
|
+
scope: BindingScope.EMPTY,
|
|
10224
10416
|
loopDepth: 0,
|
|
10225
10417
|
patterns: {
|
|
10226
10418
|
signals: analyzer.signals.map((s) => ({
|
|
10227
10419
|
getter: s.getter,
|
|
10228
|
-
pattern:
|
|
10420
|
+
pattern: identifierCallPattern(s.getter)
|
|
10229
10421
|
})),
|
|
10230
10422
|
memos: analyzer.memos.map((m) => ({
|
|
10231
10423
|
name: m.name,
|
|
10232
|
-
pattern:
|
|
10424
|
+
pattern: identifierCallPattern(m.name)
|
|
10233
10425
|
})),
|
|
10234
|
-
props: analyzer.propsParams.filter((p) => p.name !== "children").map((p) => ({ name: p.name, pattern:
|
|
10426
|
+
props: analyzer.propsParams.filter((p) => p.name !== "children").map((p) => ({ name: p.name, pattern: identifierPattern(p.name) })),
|
|
10235
10427
|
constants: analyzer.localConstants.map((c) => ({
|
|
10236
10428
|
name: c.name,
|
|
10237
10429
|
value: c.value,
|
|
10238
|
-
pattern:
|
|
10430
|
+
pattern: identifierPattern(c.name)
|
|
10239
10431
|
}))
|
|
10240
10432
|
},
|
|
10241
10433
|
getJS(node) {
|
|
@@ -10289,7 +10481,8 @@ function generateSpreadSlotId(ctx2) {
|
|
|
10289
10481
|
return `Spread_${ctx2.spreadIdCounter++}`;
|
|
10290
10482
|
}
|
|
10291
10483
|
function makeBindingEnv(ctx2) {
|
|
10292
|
-
const
|
|
10484
|
+
const boundNames = ctx2.scope.valueBoundNames();
|
|
10485
|
+
const loopKey = boundNames.size === 0 ? "" : Array.from(boundNames).sort().join("\0");
|
|
10293
10486
|
if (ctx2._bindingEnv && ctx2._bindingEnvLoopKey === loopKey) {
|
|
10294
10487
|
return ctx2._bindingEnv;
|
|
10295
10488
|
}
|
|
@@ -10304,9 +10497,11 @@ function makeBindingEnv(ctx2) {
|
|
|
10304
10497
|
localFunctions: a.localFunctions,
|
|
10305
10498
|
imports: a.imports,
|
|
10306
10499
|
ambientGlobals: a.ambientGlobals,
|
|
10307
|
-
//
|
|
10308
|
-
//
|
|
10309
|
-
|
|
10500
|
+
// `valueBoundNames()` returns a per-instance set that is never
|
|
10501
|
+
// mutated (cached on the immutable `BindingScope`) — a stable
|
|
10502
|
+
// snapshot even if `ctx.scope` is later reassigned by an enclosing
|
|
10503
|
+
// visitor frame, which swaps the instance rather than mutating it.
|
|
10504
|
+
loopParams: boundNames,
|
|
10310
10505
|
checker: a.checker
|
|
10311
10506
|
};
|
|
10312
10507
|
ctx2._bindingEnv = env;
|
|
@@ -11003,7 +11198,8 @@ function transformExpressionInner(expr, ctx2, node, isClientOnly) {
|
|
|
11003
11198
|
freeRefs
|
|
11004
11199
|
};
|
|
11005
11200
|
const reactive = isReactiveExpression(exprText, ctx2, expr) || isReactiveOrigin(origin);
|
|
11006
|
-
const
|
|
11201
|
+
const scopeValueNames = ctx2.scope.valueBoundNames();
|
|
11202
|
+
const refsLoopParam = scopeValueNames.size > 0 && Array.from(scopeValueNames).some((p) => identifierPattern(p).test(exprText));
|
|
11007
11203
|
const callsReactive = exprCallsReactiveGetters(expr, ctx2);
|
|
11008
11204
|
const hasCalls = exprHasFunctionCalls(expr);
|
|
11009
11205
|
const needsSlot = reactive || isClientOnly || refsLoopParam || callsReactive || hasCalls;
|
|
@@ -11038,7 +11234,7 @@ function transformJsxFunctionCall(callExpr, jsxFunc, ctx2, _isClientOnly) {
|
|
|
11038
11234
|
const substitutedGetJS = (node) => {
|
|
11039
11235
|
let text = baseGetJS(node);
|
|
11040
11236
|
for (const [paramName, argExpr] of substitutions) {
|
|
11041
|
-
text = text.replace(
|
|
11237
|
+
text = text.replace(identifierPattern(paramName, "g"), () => argExpr);
|
|
11042
11238
|
}
|
|
11043
11239
|
return text;
|
|
11044
11240
|
};
|
|
@@ -11080,7 +11276,7 @@ function transformMultiReturnJsxFunctionCall(callExpr, info, ctx2) {
|
|
|
11080
11276
|
const substitutedGetJS = (node) => {
|
|
11081
11277
|
let text = baseGetJS(node);
|
|
11082
11278
|
for (const [paramName, argExpr] of substitutions) {
|
|
11083
|
-
text = text.replace(
|
|
11279
|
+
text = text.replace(identifierPattern(paramName, "g"), () => argExpr);
|
|
11084
11280
|
}
|
|
11085
11281
|
return text;
|
|
11086
11282
|
};
|
|
@@ -12055,7 +12251,7 @@ function extractItemConditionalKey(cond) {
|
|
|
12055
12251
|
return a ?? b;
|
|
12056
12252
|
}
|
|
12057
12253
|
function transformMapCall(node, ctx2, isClientOnly = false, method2 = "map") {
|
|
12058
|
-
const isNested = ctx2.
|
|
12254
|
+
const isNested = ctx2.scope.valueBoundNames().size > 0;
|
|
12059
12255
|
const diagCountAtEntry = ctx2.analyzer.errors.length;
|
|
12060
12256
|
const depth = ctx2.loopDepth;
|
|
12061
12257
|
const propAccess = node.expression;
|
|
@@ -12250,12 +12446,8 @@ function transformMapCall(node, ctx2, isClientOnly = false, method2 = "map") {
|
|
|
12250
12446
|
indexType = secondParam.type.getText(ctx2.sourceFile);
|
|
12251
12447
|
}
|
|
12252
12448
|
}
|
|
12253
|
-
|
|
12254
|
-
|
|
12255
|
-
} else {
|
|
12256
|
-
ctx2.loopParams.add(param);
|
|
12257
|
-
}
|
|
12258
|
-
if (index) ctx2.loopParams.add(index);
|
|
12449
|
+
const savedScope = ctx2.scope;
|
|
12450
|
+
ctx2.scope = ctx2.scope.enterLoopRow({ param, index, paramBindings });
|
|
12259
12451
|
ctx2.loopDepth++;
|
|
12260
12452
|
const tryTransformRenderableBody = (expr) => {
|
|
12261
12453
|
if (!ts12.isBinaryExpression(expr)) return;
|
|
@@ -12317,6 +12509,23 @@ function transformMapCall(node, ctx2, isClientOnly = false, method2 = "map") {
|
|
|
12317
12509
|
const returnStmt = children2.length === 0 ? body2.statements.find(
|
|
12318
12510
|
(s) => ts12.isReturnStatement(s) && s.expression != null
|
|
12319
12511
|
) : void 0;
|
|
12512
|
+
let rowScopeBeforePreamble = null;
|
|
12513
|
+
if (returnStmt) {
|
|
12514
|
+
const preambleNames = /* @__PURE__ */ new Set();
|
|
12515
|
+
for (const stmt of body2.statements) {
|
|
12516
|
+
if (stmt === returnStmt) break;
|
|
12517
|
+
collectPreambleDeclaredNames(stmt, preambleNames);
|
|
12518
|
+
}
|
|
12519
|
+
if (preambleNames.size > 0) {
|
|
12520
|
+
rowScopeBeforePreamble = ctx2.scope;
|
|
12521
|
+
ctx2.scope = savedScope.enterLoopRow({
|
|
12522
|
+
param,
|
|
12523
|
+
index,
|
|
12524
|
+
paramBindings,
|
|
12525
|
+
preamble: { declaredNames: [...preambleNames] }
|
|
12526
|
+
});
|
|
12527
|
+
}
|
|
12528
|
+
}
|
|
12320
12529
|
if (returnStmt && returnStmt.expression) {
|
|
12321
12530
|
let returnExpr = returnStmt.expression;
|
|
12322
12531
|
while (ts12.isParenthesizedExpression(returnExpr)) {
|
|
@@ -12408,6 +12617,9 @@ function transformMapCall(node, ctx2, isClientOnly = false, method2 = "map") {
|
|
|
12408
12617
|
}
|
|
12409
12618
|
}
|
|
12410
12619
|
}
|
|
12620
|
+
if (rowScopeBeforePreamble) {
|
|
12621
|
+
ctx2.scope = rowScopeBeforePreamble;
|
|
12622
|
+
}
|
|
12411
12623
|
if (method2 === "flatMap" && children2.length === 0 && !flatMapProjectionCall(body2)) {
|
|
12412
12624
|
flatMapCallback = buildFlatMapCallback(callback, body2, ctx2);
|
|
12413
12625
|
}
|
|
@@ -12441,12 +12653,7 @@ function transformMapCall(node, ctx2, isClientOnly = false, method2 = "map") {
|
|
|
12441
12653
|
)
|
|
12442
12654
|
);
|
|
12443
12655
|
}
|
|
12444
|
-
|
|
12445
|
-
for (const b of paramBindings) ctx2.loopParams.delete(b.name);
|
|
12446
|
-
} else {
|
|
12447
|
-
ctx2.loopParams.delete(param);
|
|
12448
|
-
}
|
|
12449
|
-
if (index) ctx2.loopParams.delete(index);
|
|
12656
|
+
ctx2.scope = savedScope;
|
|
12450
12657
|
ctx2.loopDepth--;
|
|
12451
12658
|
}
|
|
12452
12659
|
if (children2.length === 0 && !flatMapCallback) {
|
|
@@ -13207,7 +13414,7 @@ function parseTemplateLiteral(expr, ctx2) {
|
|
|
13207
13414
|
}
|
|
13208
13415
|
function tryResolveTemplateSpanFromConst(expr, ctx2) {
|
|
13209
13416
|
if (ts12.isIdentifier(expr)) {
|
|
13210
|
-
if (ctx2.
|
|
13417
|
+
if (ctx2.scope.isBound(expr.text)) return null;
|
|
13211
13418
|
const constInfo = findLocalConst(expr.text, ctx2.analyzer);
|
|
13212
13419
|
if (!constInfo) return null;
|
|
13213
13420
|
const ast = parseConstInitializer(constInfo);
|
|
@@ -13219,7 +13426,7 @@ function tryResolveTemplateSpanFromConst(expr, ctx2) {
|
|
|
13219
13426
|
}
|
|
13220
13427
|
if (ts12.isElementAccessExpression(expr)) {
|
|
13221
13428
|
if (!ts12.isIdentifier(expr.expression)) return null;
|
|
13222
|
-
if (ctx2.
|
|
13429
|
+
if (ctx2.scope.isBound(expr.expression.text)) return null;
|
|
13223
13430
|
const constInfo = findLocalConst(expr.expression.text, ctx2.analyzer);
|
|
13224
13431
|
if (!constInfo) return null;
|
|
13225
13432
|
const ast = parseConstInitializer(constInfo);
|
|
@@ -13285,7 +13492,7 @@ function hasDynamicTagBinding(name2, sourceFile) {
|
|
|
13285
13492
|
return found;
|
|
13286
13493
|
}
|
|
13287
13494
|
function tryResolveIdentifierAsTemplateLiteral(ident, ctx2) {
|
|
13288
|
-
if (ctx2.
|
|
13495
|
+
if (ctx2.scope.isBound(ident.text)) return null;
|
|
13289
13496
|
const constInfo = findLocalConst(ident.text, ctx2.analyzer);
|
|
13290
13497
|
if (!constInfo) return null;
|
|
13291
13498
|
const ast = parseConstInitializer(constInfo);
|
|
@@ -13621,9 +13828,10 @@ function isSignalOrMemoArray(array, ctx2) {
|
|
|
13621
13828
|
return false;
|
|
13622
13829
|
}
|
|
13623
13830
|
function referencesLoopParam(expr, ctx2) {
|
|
13624
|
-
|
|
13625
|
-
|
|
13626
|
-
|
|
13831
|
+
const boundNames = ctx2.scope.valueBoundNames();
|
|
13832
|
+
if (boundNames.size === 0) return false;
|
|
13833
|
+
for (const p of boundNames) {
|
|
13834
|
+
if (identifierPattern(p).test(expr)) return true;
|
|
13627
13835
|
}
|
|
13628
13836
|
return false;
|
|
13629
13837
|
}
|
|
@@ -13688,9 +13896,10 @@ function hasReactiveAttributes(attrs, ctx2) {
|
|
|
13688
13896
|
if (isSignalOrMemoReference(valueToCheck, ctx2) || isPropsReference(valueToCheck, ctx2)) {
|
|
13689
13897
|
return true;
|
|
13690
13898
|
}
|
|
13691
|
-
|
|
13692
|
-
|
|
13693
|
-
|
|
13899
|
+
const scopeValueNames = ctx2.scope.valueBoundNames();
|
|
13900
|
+
if (scopeValueNames.size > 0) {
|
|
13901
|
+
for (const p of scopeValueNames) {
|
|
13902
|
+
if (identifierPattern(p).test(valueToCheck)) return true;
|
|
13694
13903
|
}
|
|
13695
13904
|
}
|
|
13696
13905
|
}
|
|
@@ -13913,6 +14122,8 @@ var init_jsx_to_ir = __esm({
|
|
|
13913
14122
|
init_strip_types();
|
|
13914
14123
|
init_template_parts();
|
|
13915
14124
|
init_src();
|
|
14125
|
+
init_binding_scope();
|
|
14126
|
+
init_identifier_pattern();
|
|
13916
14127
|
CLIENT_DIRECTIVE_INTERIOR_RE2 = /^\s*@client\s*$/;
|
|
13917
14128
|
BLOCK_COMMENT_RE2 = /\/\*([\s\S]*?)\*\//g;
|
|
13918
14129
|
EMPTY_BOUND = /* @__PURE__ */ new Set();
|
|
@@ -13922,17 +14133,19 @@ var init_jsx_to_ir = __esm({
|
|
|
13922
14133
|
});
|
|
13923
14134
|
|
|
13924
14135
|
// ../jsx/src/ir-to-client-js/prop-handling.ts
|
|
13925
|
-
function expandDynamicPropValue(value2, ctx2) {
|
|
14136
|
+
function expandDynamicPropValue(value2, ctx2, scope) {
|
|
13926
14137
|
const trimmedValue = value2.trim();
|
|
14138
|
+
if (scope?.isBound(trimmedValue)) return value2;
|
|
13927
14139
|
const constant = ctx2.localConstants.find((c) => c.name === trimmedValue);
|
|
13928
14140
|
if (constant && constant.value) {
|
|
13929
14141
|
return constant.value;
|
|
13930
14142
|
}
|
|
13931
14143
|
return value2;
|
|
13932
14144
|
}
|
|
13933
|
-
function expandConstantForReactivity(expr, ctx2, originalFreeIds) {
|
|
14145
|
+
function expandConstantForReactivity(expr, ctx2, originalFreeIds, scope) {
|
|
13934
14146
|
if (ctx2.propsObjectName) return { expr, freeIds: originalFreeIds };
|
|
13935
14147
|
const trimmedValue = expr.trim();
|
|
14148
|
+
if (scope?.isBound(trimmedValue)) return { expr, freeIds: originalFreeIds };
|
|
13936
14149
|
const constant = ctx2.localConstants.find((c) => c.name === trimmedValue);
|
|
13937
14150
|
if (constant && constant.value) {
|
|
13938
14151
|
return { expr: constant.value, freeIds: constant.freeIdentifiers };
|
|
@@ -13973,6 +14186,15 @@ var init_prop_handling = __esm({
|
|
|
13973
14186
|
});
|
|
13974
14187
|
|
|
13975
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
|
+
}
|
|
13976
14198
|
function decideWrapFromAstFlags(node) {
|
|
13977
14199
|
if (node.origin && isReactiveOrigin(node.origin)) {
|
|
13978
14200
|
return { wrap: true, reason: "proven-reactive" };
|
|
@@ -13994,12 +14216,12 @@ function decideWrapForChildProp(expandedValue, ctx2, prop) {
|
|
|
13994
14216
|
}
|
|
13995
14217
|
function needsEffectWrapper(expr, ctx2, freeIdentifiers2) {
|
|
13996
14218
|
for (const signal2 of ctx2.signals) {
|
|
13997
|
-
if (
|
|
14219
|
+
if (identifierCallPattern(signal2.getter).test(expr)) {
|
|
13998
14220
|
return true;
|
|
13999
14221
|
}
|
|
14000
14222
|
}
|
|
14001
14223
|
for (const memo of ctx2.memos) {
|
|
14002
|
-
if (
|
|
14224
|
+
if (identifierCallPattern(memo.name).test(expr)) {
|
|
14003
14225
|
return true;
|
|
14004
14226
|
}
|
|
14005
14227
|
}
|
|
@@ -14195,8 +14417,9 @@ function traverseForComponents(node, components, skipConditionals = false) {
|
|
|
14195
14417
|
}
|
|
14196
14418
|
});
|
|
14197
14419
|
}
|
|
14198
|
-
function collectLoopChildReactiveTexts(node, ctx2, loopParam, loopParamBindings, stopAtReactiveConditionals = false) {
|
|
14420
|
+
function collectLoopChildReactiveTexts(node, ctx2, loopParam, loopParamBindings, stopAtReactiveConditionals = false, preambleNames, loopIndex) {
|
|
14199
14421
|
const texts = [];
|
|
14422
|
+
const scope = buildLoopRowScope(loopParam, loopParamBindings, preambleNames, loopIndex);
|
|
14200
14423
|
walkIR(node, false, {
|
|
14201
14424
|
// Skip loop/async/if-statement subtrees — the original walker omitted
|
|
14202
14425
|
// them; they have their own scopes (inner-loop reconciliation, async
|
|
@@ -14206,7 +14429,7 @@ function collectLoopChildReactiveTexts(node, ctx2, loopParam, loopParamBindings,
|
|
|
14206
14429
|
if (!n.slotId) return;
|
|
14207
14430
|
if (n.preambleRegion) return;
|
|
14208
14431
|
const originFreeIds = freeIdsFromRefs(n.origin?.freeRefs);
|
|
14209
|
-
const expanded = expandConstantForReactivity(n.expr, ctx2, originFreeIds);
|
|
14432
|
+
const expanded = expandConstantForReactivity(n.expr, ctx2, originFreeIds, scope);
|
|
14210
14433
|
const reactive = classifyReactivity(expanded.expr, ctx2, loopParam, loopParamBindings, expanded.freeIds).kind !== "none" || decideWrapFromAstFlags(n).wrap;
|
|
14211
14434
|
if (!reactive) return;
|
|
14212
14435
|
texts.push({
|
|
@@ -14226,8 +14449,9 @@ function anyNameIn(names, set) {
|
|
|
14226
14449
|
for (const n of names) if (set.has(n)) return true;
|
|
14227
14450
|
return false;
|
|
14228
14451
|
}
|
|
14229
|
-
function collectLoopChildReactiveAttrs(node, ctx2, loopParam, loopParamBindings, stopAtReactiveConditionals = false, preambleNames) {
|
|
14452
|
+
function collectLoopChildReactiveAttrs(node, ctx2, loopParam, loopParamBindings, stopAtReactiveConditionals = false, preambleNames, loopIndex) {
|
|
14230
14453
|
const attrs = [];
|
|
14454
|
+
const scope = buildLoopRowScope(loopParam, loopParamBindings, preambleNames, loopIndex);
|
|
14231
14455
|
traverseElements(node, (el) => {
|
|
14232
14456
|
if (el.slotId) {
|
|
14233
14457
|
for (const attr of el.attrs) {
|
|
@@ -14236,7 +14460,7 @@ function collectLoopChildReactiveAttrs(node, ctx2, loopParam, loopParamBindings,
|
|
|
14236
14460
|
if (attr.name === "key") continue;
|
|
14237
14461
|
const valueStr = attrValueToString(attr.value);
|
|
14238
14462
|
if (!valueStr) continue;
|
|
14239
|
-
const expanded = expandConstantForReactivity(valueStr, ctx2, attr.freeIdentifiers);
|
|
14463
|
+
const expanded = expandConstantForReactivity(valueStr, ctx2, attr.freeIdentifiers, scope);
|
|
14240
14464
|
const readsPreamble = preambleNames !== void 0 && preambleNames.size > 0 && anyNameIn(expanded.freeIds ?? extractFreeIdentifiersFromText(expanded.expr), preambleNames);
|
|
14241
14465
|
const reactive = classifyReactivity(expanded.expr, ctx2, loopParam, loopParamBindings, expanded.freeIds).kind !== "none" || readsPreamble || attr.callsReactiveGetters || attr.hasFunctionCalls;
|
|
14242
14466
|
if (!attr.clientOnly && !reactive) continue;
|
|
@@ -14261,6 +14485,8 @@ var init_reactivity = __esm({
|
|
|
14261
14485
|
init_prop_handling();
|
|
14262
14486
|
init_csr_substitute();
|
|
14263
14487
|
init_walker();
|
|
14488
|
+
init_binding_scope();
|
|
14489
|
+
init_identifier_pattern();
|
|
14264
14490
|
}
|
|
14265
14491
|
});
|
|
14266
14492
|
|
|
@@ -14533,13 +14759,13 @@ function collectInnerLoops(nodes, siblingOffsets, outerLoopParam, ctx2, options2
|
|
|
14533
14759
|
const emitDepth = fixedDepth ?? scope.depth + 1;
|
|
14534
14760
|
const loopParamsForTemplate = outerLoopParam ? [outerLoopParam, { param: n.param, bindings: n.paramBindings }] : void 0;
|
|
14535
14761
|
const template = n.children.map((c) => irToPlaceholderTemplate(c, void 0, emitDepth, loopParamsForTemplate)).join("");
|
|
14536
|
-
const refsOuter = outerLoopParam ?
|
|
14762
|
+
const refsOuter = outerLoopParam ? identifierPattern(outerLoopParam).test(n.array) : false;
|
|
14537
14763
|
const bindings = emptyLoopChildBindings();
|
|
14538
14764
|
const innerPreambleNames = preambleNamesOf(n);
|
|
14539
14765
|
if (ctx2) {
|
|
14540
14766
|
for (const child of n.children) {
|
|
14541
|
-
bindings.reactiveTexts.push(...collectLoopChildReactiveTexts(child, ctx2, n.param, n.paramBindings));
|
|
14542
|
-
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));
|
|
14543
14769
|
bindings.refs.push(...collectLoopChildRefs(child));
|
|
14544
14770
|
}
|
|
14545
14771
|
}
|
|
@@ -14571,7 +14797,9 @@ function collectInnerLoops(nodes, siblingOffsets, outerLoopParam, ctx2, options2
|
|
|
14571
14797
|
ctx2,
|
|
14572
14798
|
siblingOffsets,
|
|
14573
14799
|
n.param,
|
|
14574
|
-
n.paramBindings
|
|
14800
|
+
n.paramBindings,
|
|
14801
|
+
innerPreambleNames,
|
|
14802
|
+
n.index
|
|
14575
14803
|
));
|
|
14576
14804
|
}
|
|
14577
14805
|
}
|
|
@@ -14753,7 +14981,7 @@ function collectElements(node, ctx2, siblingOffsets, insideConditional = false)
|
|
|
14753
14981
|
if (!l.slotId || inCond) return;
|
|
14754
14982
|
const projectionInner = l.method === "flatMap" && l.children.length === 1 && l.children[0].type === "loop" ? l.children[0] : void 0;
|
|
14755
14983
|
const childHandlers = [];
|
|
14756
|
-
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);
|
|
14757
14985
|
if (!projectionInner) {
|
|
14758
14986
|
for (const child of l.children) {
|
|
14759
14987
|
childHandlers.push(...collectEventHandlersFromIR(child));
|
|
@@ -15005,7 +15233,7 @@ function collectBranchLoops(node, ctx2, siblingOffsets) {
|
|
|
15005
15233
|
} else {
|
|
15006
15234
|
childTemplate = n.children.map((c) => irToHtmlTemplate(c, void 0, 0, branchLoopParamSpec)).join("");
|
|
15007
15235
|
}
|
|
15008
|
-
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();
|
|
15009
15237
|
loops.push({
|
|
15010
15238
|
kind: "branch",
|
|
15011
15239
|
array: n.array,
|
|
@@ -15091,19 +15319,20 @@ function preambleNamesOf(loop) {
|
|
|
15091
15319
|
const declared = loop.preamble?.declaredNames;
|
|
15092
15320
|
return declared && declared.length > 0 ? new Set(declared) : void 0;
|
|
15093
15321
|
}
|
|
15094
|
-
function collectLoopChildBindings(children2, ctx2, siblingOffsets, loopParam, loopParamBindings, preambleNames) {
|
|
15322
|
+
function collectLoopChildBindings(children2, ctx2, siblingOffsets, loopParam, loopParamBindings, preambleNames, loopIndex) {
|
|
15095
15323
|
const bindings = emptyLoopChildBindings();
|
|
15096
15324
|
for (const child of children2) {
|
|
15097
15325
|
bindings.events.push(...collectLoopChildEventsWithNesting(child));
|
|
15098
|
-
bindings.reactiveAttrs.push(...collectLoopChildReactiveAttrs(child, ctx2, loopParam, loopParamBindings, true, preambleNames));
|
|
15099
|
-
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));
|
|
15100
15328
|
bindings.refs.push(...collectLoopChildRefs(child));
|
|
15101
|
-
bindings.conditionals.push(...collectLoopChildConditionals(child, ctx2, siblingOffsets, loopParam, loopParamBindings));
|
|
15329
|
+
bindings.conditionals.push(...collectLoopChildConditionals(child, ctx2, siblingOffsets, loopParam, loopParamBindings, preambleNames, loopIndex));
|
|
15102
15330
|
}
|
|
15103
15331
|
return bindings;
|
|
15104
15332
|
}
|
|
15105
|
-
function collectLoopChildConditionals(node, ctx2, siblingOffsets, loopParam, loopParamBindings) {
|
|
15333
|
+
function collectLoopChildConditionals(node, ctx2, siblingOffsets, loopParam, loopParamBindings, preambleNames, loopIndex) {
|
|
15106
15334
|
const conditionals = [];
|
|
15335
|
+
const scope = buildLoopRowScope(loopParam, loopParamBindings, preambleNames, loopIndex);
|
|
15107
15336
|
const refsAnyBindingViaFreeIds = (freeIds) => {
|
|
15108
15337
|
if (loopParamBindings && loopParamBindings.length > 0) {
|
|
15109
15338
|
for (const b of loopParamBindings) {
|
|
@@ -15123,7 +15352,7 @@ function collectLoopChildConditionals(node, ctx2, siblingOffsets, loopParam, loo
|
|
|
15123
15352
|
const sourceFreeIds = freeIdsFromRefs(n.origin?.freeRefs);
|
|
15124
15353
|
const refsLoopParamInSource = refsAnyBindingViaFreeIds(sourceFreeIds);
|
|
15125
15354
|
if (!n.reactive && !refsLoopParamInSource) return;
|
|
15126
|
-
const expanded = expandConstantForReactivity(n.condition, ctx2, sourceFreeIds);
|
|
15355
|
+
const expanded = expandConstantForReactivity(n.condition, ctx2, sourceFreeIds, scope);
|
|
15127
15356
|
if (classifyReactivity(expanded.expr, ctx2, loopParam, loopParamBindings, expanded.freeIds).kind === "none") return;
|
|
15128
15357
|
const loopParamsForCond = loopParam ? [{ param: loopParam, bindings: loopParamBindings }] : void 0;
|
|
15129
15358
|
const whenTrueHtml = irToHtmlTemplate(n.whenTrue, void 0, 0, loopParamsForCond, "__slots");
|
|
@@ -15133,27 +15362,27 @@ function collectLoopChildConditionals(node, ctx2, siblingOffsets, loopParam, loo
|
|
|
15133
15362
|
condition: expanded.expr,
|
|
15134
15363
|
whenTrueHtml,
|
|
15135
15364
|
whenFalseHtml,
|
|
15136
|
-
whenTrue: summarizeLoopChildBranch(n.whenTrue, ctx2, siblingOffsets, loopParam, loopParamBindings),
|
|
15137
|
-
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),
|
|
15138
15367
|
...expanded.freeIds !== void 0 && { conditionFreeIdentifiers: expanded.freeIds }
|
|
15139
15368
|
});
|
|
15140
15369
|
}
|
|
15141
15370
|
});
|
|
15142
15371
|
return conditionals;
|
|
15143
15372
|
}
|
|
15144
|
-
function summarizeLoopChildBranch(node, ctx2, siblingOffsets, loopParam, loopParamBindings) {
|
|
15373
|
+
function summarizeLoopChildBranch(node, ctx2, siblingOffsets, loopParam, loopParamBindings, preambleNames, loopIndex) {
|
|
15145
15374
|
const inner = collectInnerLoops([node], siblingOffsets, loopParam, ctx2, branchInnerLoopOptions);
|
|
15146
15375
|
return {
|
|
15147
15376
|
childComponents: collectConditionalBranchChildComponents(node),
|
|
15148
15377
|
innerLoops: inner.length > 0 ? inner : void 0,
|
|
15149
|
-
conditionals: collectLoopChildConditionals(node, ctx2, siblingOffsets, loopParam, loopParamBindings),
|
|
15378
|
+
conditionals: collectLoopChildConditionals(node, ctx2, siblingOffsets, loopParam, loopParamBindings, preambleNames, loopIndex),
|
|
15150
15379
|
events: collectConditionalBranchEvents(node),
|
|
15151
15380
|
// Loop-param-aware — reuses the flat loop-item collectors scoped to just
|
|
15152
15381
|
// this branch's subtree. Both already stop descending into any further
|
|
15153
15382
|
// nested reactive conditional (own insert()/arm), so calling them here
|
|
15154
15383
|
// on the branch root yields exactly this branch's direct bindings
|
|
15155
15384
|
// without re-collecting what a nested arm already owns (#2347).
|
|
15156
|
-
reactiveAttrs: collectLoopChildReactiveAttrs(node, ctx2, loopParam, loopParamBindings, true),
|
|
15385
|
+
reactiveAttrs: collectLoopChildReactiveAttrs(node, ctx2, loopParam, loopParamBindings, true, preambleNames, loopIndex),
|
|
15157
15386
|
// Skip ONLY when the branch's entire content is a single bare
|
|
15158
15387
|
// `expression` (no wrapping element) that MAY yield a live DOM node —
|
|
15159
15388
|
// i.e. it contains a call anywhere (`node.hasFunctionCalls`, computed
|
|
@@ -15201,7 +15430,7 @@ function summarizeLoopChildBranch(node, ctx2, siblingOffsets, loopParam, loopPar
|
|
|
15201
15430
|
// makes `irToHtmlTemplate` emit its `<!--bf:sN-->…<!--/-->` marker (the
|
|
15202
15431
|
// same call builds both the SSR and the CSR/hydration template, so the
|
|
15203
15432
|
// two can't disagree on shape).
|
|
15204
|
-
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)
|
|
15205
15434
|
};
|
|
15206
15435
|
}
|
|
15207
15436
|
var EMPTY_RENDER_EXPRS, branchInnerLoopOptions;
|
|
@@ -15216,6 +15445,7 @@ var init_collect_elements = __esm({
|
|
|
15216
15445
|
init_prop_handling();
|
|
15217
15446
|
init_walker();
|
|
15218
15447
|
init_loop_chain();
|
|
15448
|
+
init_identifier_pattern();
|
|
15219
15449
|
EMPTY_RENDER_EXPRS = /* @__PURE__ */ new Set(["null", "undefined", "false", "''", '""', "``"]);
|
|
15220
15450
|
branchInnerLoopOptions = {
|
|
15221
15451
|
collectItemBindings: true,
|
|
@@ -15730,7 +15960,7 @@ var init_value_references = __esm({
|
|
|
15730
15960
|
function detectUsedImports(code) {
|
|
15731
15961
|
const used = /* @__PURE__ */ new Set();
|
|
15732
15962
|
for (const name2 of RUNTIME_IMPORT_CANDIDATES) {
|
|
15733
|
-
if (
|
|
15963
|
+
if (identifierCallPattern(name2).test(code)) {
|
|
15734
15964
|
used.add(name2);
|
|
15735
15965
|
}
|
|
15736
15966
|
}
|
|
@@ -15830,6 +16060,7 @@ var init_imports = __esm({
|
|
|
15830
16060
|
"use strict";
|
|
15831
16061
|
init_builtins();
|
|
15832
16062
|
init_value_references();
|
|
16063
|
+
init_identifier_pattern();
|
|
15833
16064
|
RUNTIME_IMPORT_CANDIDATES = [
|
|
15834
16065
|
"createSignal",
|
|
15835
16066
|
"createMemo",
|
|
@@ -16204,7 +16435,7 @@ function containsAnyIdentifier(node, names) {
|
|
|
16204
16435
|
function scanRefsByName(text, bindings) {
|
|
16205
16436
|
const result2 = /* @__PURE__ */ new Map();
|
|
16206
16437
|
for (const name2 of bindings.keys()) {
|
|
16207
|
-
const re =
|
|
16438
|
+
const re = identifierPattern(name2);
|
|
16208
16439
|
if (re.test(text)) result2.set(name2, []);
|
|
16209
16440
|
}
|
|
16210
16441
|
return result2;
|
|
@@ -16297,6 +16528,7 @@ var init_relocate = __esm({
|
|
|
16297
16528
|
init_props_binding();
|
|
16298
16529
|
init_expression_parser();
|
|
16299
16530
|
init_lowering_registry();
|
|
16531
|
+
init_identifier_pattern();
|
|
16300
16532
|
REGISTRY_SAFE_BINDING_KINDS = /* @__PURE__ */ new Set([
|
|
16301
16533
|
"global",
|
|
16302
16534
|
"module-import",
|
|
@@ -19051,7 +19283,7 @@ function buildStaticArrayDelegationPlan(elem, profileComponentName) {
|
|
|
19051
19283
|
function buildKeyedOrIndexLookup(args2) {
|
|
19052
19284
|
const hasBindings = (args2.paramBindings?.length ?? 0) > 0;
|
|
19053
19285
|
if (args2.key !== null) {
|
|
19054
|
-
const keyWithItem = hasBindings ? substituteLoopBindings(args2.key, args2.paramBindings, "item") : args2.key.replace(
|
|
19286
|
+
const keyWithItem = hasBindings ? substituteLoopBindings(args2.key, args2.paramBindings, "item") : args2.key.replace(identifierPattern(args2.param, "g"), "item");
|
|
19055
19287
|
return {
|
|
19056
19288
|
kind: "keyed",
|
|
19057
19289
|
arrayExpr: args2.array,
|
|
@@ -19078,6 +19310,7 @@ var init_build_event_delegation = __esm({
|
|
|
19078
19310
|
"../jsx/src/ir-to-client-js/control-flow/plan/build-event-delegation.ts"() {
|
|
19079
19311
|
"use strict";
|
|
19080
19312
|
init_utils();
|
|
19313
|
+
init_identifier_pattern();
|
|
19081
19314
|
init_html_template();
|
|
19082
19315
|
}
|
|
19083
19316
|
});
|
|
@@ -21367,7 +21600,7 @@ function emitKeyedLookup(ls, ev, handlerCall, lookup) {
|
|
|
21367
21600
|
}
|
|
21368
21601
|
for (const nested of ev.nestedLoops) {
|
|
21369
21602
|
const rawKey = nested.key ?? "";
|
|
21370
|
-
const innerKeyExpr = nested.paramBindings && nested.paramBindings.length > 0 ? substituteLoopBindings(rawKey, nested.paramBindings, "item") : rawKey.replace(
|
|
21603
|
+
const innerKeyExpr = nested.paramBindings && nested.paramBindings.length > 0 ? substituteLoopBindings(rawKey, nested.paramBindings, "item") : rawKey.replace(identifierPattern(nested.param, "g"), "item");
|
|
21371
21604
|
const outerRef = hasBindings ? "__bfLoopItem" : param;
|
|
21372
21605
|
ls.push(` const ${nested.param} = ${outerRef} && ${nested.array}.find(item => String(${innerKeyExpr}) === innerKey${nested.depth})`);
|
|
21373
21606
|
}
|
|
@@ -21428,6 +21661,7 @@ var init_event_delegation = __esm({
|
|
|
21428
21661
|
"use strict";
|
|
21429
21662
|
init_utils();
|
|
21430
21663
|
init_csr_substitute();
|
|
21664
|
+
init_identifier_pattern();
|
|
21431
21665
|
NON_BUBBLING_EVENTS = /* @__PURE__ */ new Set([
|
|
21432
21666
|
"blur",
|
|
21433
21667
|
"focus",
|
|
@@ -22176,7 +22410,7 @@ import ts19 from "typescript";
|
|
|
22176
22410
|
function rewritePropsObjectRef(code, propsObjectName) {
|
|
22177
22411
|
const srcPropsName = propsObjectName ?? "props";
|
|
22178
22412
|
if (srcPropsName === PROPS_PARAM) return code;
|
|
22179
|
-
if (!
|
|
22413
|
+
if (!identifierPattern(srcPropsName).test(code)) return code;
|
|
22180
22414
|
const sourceFile = ts19.createSourceFile(
|
|
22181
22415
|
"init-body.ts",
|
|
22182
22416
|
code,
|
|
@@ -22216,6 +22450,7 @@ var init_rewrite_props_object = __esm({
|
|
|
22216
22450
|
"../jsx/src/ir-to-client-js/rewrite-props-object.ts"() {
|
|
22217
22451
|
"use strict";
|
|
22218
22452
|
init_utils();
|
|
22453
|
+
init_identifier_pattern();
|
|
22219
22454
|
}
|
|
22220
22455
|
});
|
|
22221
22456
|
|
|
@@ -24829,6 +25064,7 @@ var init_jsx_adapter = __esm({
|
|
|
24829
25064
|
init_env_signal();
|
|
24830
25065
|
init_module_exports();
|
|
24831
25066
|
init_csr_substitute();
|
|
25067
|
+
init_identifier_pattern();
|
|
24832
25068
|
JsxAdapter = class extends BaseAdapter {
|
|
24833
25069
|
componentName = "";
|
|
24834
25070
|
/**
|
|
@@ -24920,7 +25156,7 @@ var init_jsx_adapter = __esm({
|
|
|
24920
25156
|
lines.push(` const ${signal2.getter} = () => ${initialValue}`);
|
|
24921
25157
|
}
|
|
24922
25158
|
if (signal2.setter) {
|
|
24923
|
-
const setterUsed =
|
|
25159
|
+
const setterUsed = identifierPattern(signal2.setter).test(setterRefText);
|
|
24924
25160
|
if (setterUsed) {
|
|
24925
25161
|
lines.push(` const ${signal2.setter} = (..._args: any[]) => {}`);
|
|
24926
25162
|
}
|
|
@@ -24937,7 +25173,7 @@ var init_jsx_adapter = __esm({
|
|
|
24937
25173
|
if (moduleScopeNames.has(constant.name)) continue;
|
|
24938
25174
|
const keyword = constant.declarationKind ?? "const";
|
|
24939
25175
|
if (!constant.value) {
|
|
24940
|
-
const typeAnnotation = preserveTypes && constant.type ? `: ${constant.type
|
|
25176
|
+
const typeAnnotation = preserveTypes && (constant.typeAnnotation ?? constant.type) ? `: ${constant.typeAnnotation ?? constant.type?.raw}` : "";
|
|
24941
25177
|
lines.push(` ${keyword} ${constant.name}${typeAnnotation}`);
|
|
24942
25178
|
continue;
|
|
24943
25179
|
}
|
|
@@ -24945,7 +25181,8 @@ var init_jsx_adapter = __esm({
|
|
|
24945
25181
|
if (/^createContext\b/.test(value2) || /^new WeakMap\b/.test(value2)) continue;
|
|
24946
25182
|
if (!reachable.has(constant.name)) continue;
|
|
24947
25183
|
const constValue = preserveTypes ? constant.typedValue ?? constant.value : constant.value;
|
|
24948
|
-
|
|
25184
|
+
const letTypeAnnotation = preserveTypes && keyword === "let" && constant.typeAnnotation ? `: ${constant.typeAnnotation}` : "";
|
|
25185
|
+
lines.push(` ${keyword} ${constant.name}${letTypeAnnotation} = ${constValue}`);
|
|
24949
25186
|
}
|
|
24950
25187
|
for (const func of localFunctions) {
|
|
24951
25188
|
if (moduleScopeNames.has(func.name)) continue;
|
|
@@ -25102,14 +25339,16 @@ var init_jsx_adapter = __esm({
|
|
|
25102
25339
|
const keyword = c.declarationKind ?? "const";
|
|
25103
25340
|
const exportKw = c.isExported ? "export " : "";
|
|
25104
25341
|
if (!c.value) {
|
|
25105
|
-
|
|
25342
|
+
const typeAnnotation = preserveTypes && (c.typeAnnotation ?? c.type) ? `: ${c.typeAnnotation ?? c.type?.raw}` : "";
|
|
25343
|
+
entries2.push({ line: c.loc.start.line, text: `${exportKw}${keyword} ${c.name}${typeAnnotation}` });
|
|
25106
25344
|
continue;
|
|
25107
25345
|
}
|
|
25108
25346
|
const trimmed = c.value.trim();
|
|
25109
25347
|
if (/^new WeakMap\b/.test(trimmed)) continue;
|
|
25110
25348
|
if (c.isExported && /^createContext\b/.test(trimmed)) continue;
|
|
25111
25349
|
const value2 = preserveTypes ? c.typedValue ?? c.value : c.value;
|
|
25112
|
-
|
|
25350
|
+
const letTypeAnnotation = preserveTypes && keyword === "let" && c.typeAnnotation ? `: ${c.typeAnnotation}` : "";
|
|
25351
|
+
entries2.push({ line: c.loc.start.line, text: `${exportKw}${keyword} ${c.name}${letTypeAnnotation} = ${value2}` });
|
|
25113
25352
|
}
|
|
25114
25353
|
for (const f of ir.metadata.localFunctions) {
|
|
25115
25354
|
if (!f.isModule || !moduleNames.has(f.name)) continue;
|
|
@@ -25186,6 +25425,7 @@ var init_jsx_adapter = __esm({
|
|
|
25186
25425
|
});
|
|
25187
25426
|
|
|
25188
25427
|
// ../jsx/src/adapters/template-imports.ts
|
|
25428
|
+
import ts25 from "typescript";
|
|
25189
25429
|
function rewriteImportsForTemplate(imports, shimSource, rewriteRelative) {
|
|
25190
25430
|
const remap = (imp) => {
|
|
25191
25431
|
if (!rewriteRelative || !imp.source.startsWith(".")) return imp;
|
|
@@ -25227,6 +25467,48 @@ function rewriteImportsForTemplate(imports, shimSource, rewriteRelative) {
|
|
|
25227
25467
|
function specKey(s) {
|
|
25228
25468
|
return `${s.isDefault ? "d" : ""}${s.isNamespace ? "n" : ""}:${s.name}:${s.alias ?? ""}`;
|
|
25229
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
|
+
}
|
|
25230
25512
|
var CLIENT_PACKAGE_SOURCES;
|
|
25231
25513
|
var init_template_imports = __esm({
|
|
25232
25514
|
"../jsx/src/adapters/template-imports.ts"() {
|
|
@@ -26065,7 +26347,7 @@ var init_dangerous_inner_html = __esm({
|
|
|
26065
26347
|
});
|
|
26066
26348
|
|
|
26067
26349
|
// ../jsx/src/combine-client-js.ts
|
|
26068
|
-
import
|
|
26350
|
+
import ts26 from "typescript";
|
|
26069
26351
|
function combineParentChildClientJs(files2) {
|
|
26070
26352
|
const result2 = /* @__PURE__ */ new Map();
|
|
26071
26353
|
const lookup = /* @__PURE__ */ new Map();
|
|
@@ -26122,17 +26404,17 @@ function combineParentChildClientJs(files2) {
|
|
|
26122
26404
|
return result2;
|
|
26123
26405
|
}
|
|
26124
26406
|
function parseAndMerge(content2, importsBySource, otherImports, codeSections) {
|
|
26125
|
-
const sourceFile =
|
|
26407
|
+
const sourceFile = ts26.createSourceFile(
|
|
26126
26408
|
"combine.js",
|
|
26127
26409
|
content2,
|
|
26128
|
-
|
|
26410
|
+
ts26.ScriptTarget.Latest,
|
|
26129
26411
|
/*setParentNodes*/
|
|
26130
26412
|
false,
|
|
26131
|
-
|
|
26413
|
+
ts26.ScriptKind.JS
|
|
26132
26414
|
);
|
|
26133
26415
|
const importSpans = [];
|
|
26134
26416
|
for (const stmt of sourceFile.statements) {
|
|
26135
|
-
if (!
|
|
26417
|
+
if (!ts26.isImportDeclaration(stmt)) continue;
|
|
26136
26418
|
const start2 = stmt.getStart(sourceFile);
|
|
26137
26419
|
const end2 = stmt.getEnd();
|
|
26138
26420
|
importSpans.push([start2, end2]);
|
|
@@ -26140,8 +26422,8 @@ function parseAndMerge(content2, importsBySource, otherImports, codeSections) {
|
|
|
26140
26422
|
if (stmtText.includes("@bf-child:")) continue;
|
|
26141
26423
|
const clause = stmt.importClause;
|
|
26142
26424
|
const bindings = clause?.namedBindings;
|
|
26143
|
-
const specifier =
|
|
26144
|
-
if (clause && !clause.name && bindings &&
|
|
26425
|
+
const specifier = ts26.isStringLiteral(stmt.moduleSpecifier) ? stmt.moduleSpecifier.text : "";
|
|
26426
|
+
if (clause && !clause.name && bindings && ts26.isNamedImports(bindings)) {
|
|
26145
26427
|
if (!importsBySource.has(specifier)) {
|
|
26146
26428
|
importsBySource.set(specifier, /* @__PURE__ */ new Set());
|
|
26147
26429
|
}
|
|
@@ -26316,7 +26598,7 @@ var init_loop_destructure = __esm({
|
|
|
26316
26598
|
});
|
|
26317
26599
|
|
|
26318
26600
|
// ../jsx/src/debug.ts
|
|
26319
|
-
import
|
|
26601
|
+
import ts27 from "typescript";
|
|
26320
26602
|
function buildComponentGraph(source, filePath, componentName) {
|
|
26321
26603
|
const ctx2 = analyzeComponent(source, filePath, componentName);
|
|
26322
26604
|
if (!ctx2.jsxReturn) {
|
|
@@ -27528,18 +27810,18 @@ function truncateExpr(expr, max = 40) {
|
|
|
27528
27810
|
function exprReadsPropMember(expr, propsObjectName) {
|
|
27529
27811
|
let sf;
|
|
27530
27812
|
try {
|
|
27531
|
-
sf =
|
|
27813
|
+
sf = ts27.createSourceFile("__attr.tsx", `(${expr})`, ts27.ScriptTarget.Latest, true, ts27.ScriptKind.TSX);
|
|
27532
27814
|
} catch {
|
|
27533
27815
|
return false;
|
|
27534
27816
|
}
|
|
27535
27817
|
let found = false;
|
|
27536
27818
|
const visit3 = (n) => {
|
|
27537
27819
|
if (found) return;
|
|
27538
|
-
if (
|
|
27820
|
+
if (ts27.isPropertyAccessExpression(n) && ts27.isIdentifier(n.expression) && n.expression.text === propsObjectName && n.name.text !== "children") {
|
|
27539
27821
|
found = true;
|
|
27540
27822
|
return;
|
|
27541
27823
|
}
|
|
27542
|
-
|
|
27824
|
+
ts27.forEachChild(n, visit3);
|
|
27543
27825
|
};
|
|
27544
27826
|
visit3(sf);
|
|
27545
27827
|
return found;
|
|
@@ -27567,12 +27849,12 @@ function attrValueToString2(value2) {
|
|
|
27567
27849
|
function extractReactiveDeps(expr, signalGetters, memoNames) {
|
|
27568
27850
|
const deps = [];
|
|
27569
27851
|
for (const getter of signalGetters) {
|
|
27570
|
-
if (
|
|
27852
|
+
if (identifierCallPattern(getter).test(expr)) {
|
|
27571
27853
|
deps.push(getter);
|
|
27572
27854
|
}
|
|
27573
27855
|
}
|
|
27574
27856
|
for (const memo of memoNames) {
|
|
27575
|
-
if (
|
|
27857
|
+
if (identifierCallPattern(memo).test(expr)) {
|
|
27576
27858
|
deps.push(memo);
|
|
27577
27859
|
}
|
|
27578
27860
|
}
|
|
@@ -27585,7 +27867,7 @@ function extractSetterRefs(expr, signalGetters) {
|
|
|
27585
27867
|
refs.push(match[1]);
|
|
27586
27868
|
}
|
|
27587
27869
|
for (const getter of signalGetters) {
|
|
27588
|
-
if (
|
|
27870
|
+
if (identifierCallPattern(getter).test(expr)) {
|
|
27589
27871
|
refs.push(getter);
|
|
27590
27872
|
}
|
|
27591
27873
|
}
|
|
@@ -27612,11 +27894,12 @@ var init_debug = __esm({
|
|
|
27612
27894
|
init_ir_to_client_js();
|
|
27613
27895
|
init_reactivity();
|
|
27614
27896
|
init_utils();
|
|
27897
|
+
init_identifier_pattern();
|
|
27615
27898
|
}
|
|
27616
27899
|
});
|
|
27617
27900
|
|
|
27618
27901
|
// ../jsx/src/profiler.ts
|
|
27619
|
-
import
|
|
27902
|
+
import ts28 from "typescript";
|
|
27620
27903
|
function buildStaticBudget(source, filePath, componentName, options2 = {}) {
|
|
27621
27904
|
const threshold = options2.fanOutThreshold ?? DEFAULT_FANOUT_THRESHOLD;
|
|
27622
27905
|
const program = createProgramForFile(source, filePath)?.program;
|
|
@@ -27871,14 +28154,14 @@ function joinProfilerEvents(events, index) {
|
|
|
27871
28154
|
return { joined, unattributed, diagnostics };
|
|
27872
28155
|
}
|
|
27873
28156
|
function findUninstrumentedEffects(source, filePath, instrumentedLines) {
|
|
27874
|
-
const sf =
|
|
28157
|
+
const sf = ts28.createSourceFile(filePath, source, ts28.ScriptTarget.Latest, true, ts28.ScriptKind.TSX);
|
|
27875
28158
|
const out = [];
|
|
27876
28159
|
const visit3 = (node) => {
|
|
27877
|
-
if (
|
|
28160
|
+
if (ts28.isCallExpression(node) && ts28.isIdentifier(node.expression) && node.expression.text === "createEffect") {
|
|
27878
28161
|
const line = sf.getLineAndCharacterOfPosition(node.getStart(sf)).line + 1;
|
|
27879
28162
|
if (!instrumentedLines.has(line)) out.push({ file: filePath, line });
|
|
27880
28163
|
}
|
|
27881
|
-
|
|
28164
|
+
ts28.forEachChild(node, visit3);
|
|
27882
28165
|
};
|
|
27883
28166
|
visit3(sf);
|
|
27884
28167
|
out.sort((a, b) => a.line - b.line);
|
|
@@ -28164,19 +28447,19 @@ function assessBatchSafety(args2) {
|
|
|
28164
28447
|
const signalGetters = new Set(args2.graph.signals.map((s) => s.name));
|
|
28165
28448
|
let sf;
|
|
28166
28449
|
try {
|
|
28167
|
-
sf =
|
|
28450
|
+
sf = ts28.createSourceFile("__h.ts", `const __h = ${args2.handler}`, ts28.ScriptTarget.Latest, true);
|
|
28168
28451
|
} catch {
|
|
28169
28452
|
return "unverified";
|
|
28170
28453
|
}
|
|
28171
28454
|
const calls = [];
|
|
28172
28455
|
const visit3 = (node) => {
|
|
28173
|
-
if (
|
|
28456
|
+
if (ts28.isCallExpression(node) && ts28.isIdentifier(node.expression)) {
|
|
28174
28457
|
const name2 = node.expression.text;
|
|
28175
28458
|
if (setters.has(name2)) calls.push({ pos: node.getStart(sf), kind: "write" });
|
|
28176
28459
|
else if (D.has(name2) && node.arguments.length === 0) calls.push({ pos: node.getStart(sf), kind: "memoRead" });
|
|
28177
28460
|
else if (!signalGetters.has(name2) && !memoNames.has(name2)) calls.push({ pos: node.getStart(sf), kind: "risky" });
|
|
28178
28461
|
}
|
|
28179
|
-
|
|
28462
|
+
ts28.forEachChild(node, visit3);
|
|
28180
28463
|
};
|
|
28181
28464
|
visit3(sf);
|
|
28182
28465
|
calls.sort((a, b) => a.pos - b.pos);
|
|
@@ -28832,6 +29115,7 @@ __export(src_exports, {
|
|
|
28832
29115
|
BROWSER_ONLY_CLIENT_APIS: () => BROWSER_ONLY_CLIENT_APIS,
|
|
28833
29116
|
BUILTIN_LOWERING_PLUGINS: () => BUILTIN_LOWERING_PLUGINS,
|
|
28834
29117
|
BaseAdapter: () => BaseAdapter,
|
|
29118
|
+
BindingScope: () => BindingScope,
|
|
28835
29119
|
CALLBACK_METHODS: () => CALLBACK_METHODS,
|
|
28836
29120
|
ENV_SIGNAL_READERS: () => ENV_SIGNAL_READERS,
|
|
28837
29121
|
ErrorCodes: () => ErrorCodes,
|
|
@@ -28980,6 +29264,7 @@ __export(src_exports, {
|
|
|
28980
29264
|
resolveDangerousInnerHtml: () => resolveDangerousInnerHtml,
|
|
28981
29265
|
resolveSetters: () => resolveSetters,
|
|
28982
29266
|
resolveStaticLoopSource: () => resolveStaticLoopSource,
|
|
29267
|
+
rewriteDynamicImportsInSource: () => rewriteDynamicImportsInSource,
|
|
28983
29268
|
rewriteImportsForTemplate: () => rewriteImportsForTemplate,
|
|
28984
29269
|
searchParamsLocalNames: () => searchParamsLocalNames,
|
|
28985
29270
|
serializeParsedExpr: () => serializeParsedExpr,
|
|
@@ -29031,6 +29316,7 @@ var init_src2 = __esm({
|
|
|
29031
29316
|
init_expression_parser();
|
|
29032
29317
|
init_loop_chain();
|
|
29033
29318
|
init_loop_destructure();
|
|
29319
|
+
init_binding_scope();
|
|
29034
29320
|
init_debug();
|
|
29035
29321
|
init_profiler();
|
|
29036
29322
|
init_debug_profile();
|
|
@@ -109837,7 +110123,7 @@ __export(scenario_driver_exports, {
|
|
|
109837
110123
|
import { writeFileSync as writeFileSync9, mkdtempSync, rmSync, readFileSync as readFileSync19, existsSync as existsSync23, statSync as statSync3 } from "node:fs";
|
|
109838
110124
|
import { join as join2, dirname as dirname4, resolve as resolve6 } from "node:path";
|
|
109839
110125
|
import { tmpdir } from "node:os";
|
|
109840
|
-
import
|
|
110126
|
+
import ts29 from "typescript";
|
|
109841
110127
|
function externalRuntimeImport(clientJs) {
|
|
109842
110128
|
const chunks = Array.isArray(clientJs) ? clientJs : [clientJs];
|
|
109843
110129
|
for (const chunk of chunks) {
|
|
@@ -109907,11 +110193,11 @@ function resolveLocalFile(spec) {
|
|
|
109907
110193
|
}
|
|
109908
110194
|
function rewriteLocalImports(js, chunkPath, inlined) {
|
|
109909
110195
|
const chunkDir = dirname4(chunkPath);
|
|
109910
|
-
const sf =
|
|
110196
|
+
const sf = ts29.createSourceFile("chunk.mjs", js, ts29.ScriptTarget.Latest, false, ts29.ScriptKind.JS);
|
|
109911
110197
|
const edits = [];
|
|
109912
110198
|
for (const stmt of sf.statements) {
|
|
109913
|
-
if (!
|
|
109914
|
-
if (!
|
|
110199
|
+
if (!ts29.isImportDeclaration(stmt)) continue;
|
|
110200
|
+
if (!ts29.isStringLiteral(stmt.moduleSpecifier)) continue;
|
|
109915
110201
|
const spec = stmt.moduleSpecifier.text;
|
|
109916
110202
|
if (!spec.startsWith(".")) continue;
|
|
109917
110203
|
const resolved = resolveLocalFile(join2(chunkDir, spec.replace(/\.client\.js$/, "")));
|
|
@@ -109923,13 +110209,13 @@ function rewriteLocalImports(js, chunkPath, inlined) {
|
|
|
109923
110209
|
const abs = resolve6(resolved);
|
|
109924
110210
|
if (inlined.has(abs)) {
|
|
109925
110211
|
const clause = stmt.importClause;
|
|
109926
|
-
if (clause && (clause.name || clause.namedBindings &&
|
|
110212
|
+
if (clause && (clause.name || clause.namedBindings && ts29.isNamespaceImport(clause.namedBindings))) {
|
|
109927
110213
|
throw new Error(
|
|
109928
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.`
|
|
109929
110215
|
);
|
|
109930
110216
|
}
|
|
109931
110217
|
const shims = [];
|
|
109932
|
-
if (clause?.namedBindings &&
|
|
110218
|
+
if (clause?.namedBindings && ts29.isNamedImports(clause.namedBindings)) {
|
|
109933
110219
|
for (const el of clause.namedBindings.elements) {
|
|
109934
110220
|
if (el.propertyName) shims.push(`var ${el.name.text} = ${el.propertyName.text}`);
|
|
109935
110221
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@barefootjs/cli",
|
|
3
|
-
"version": "0.31.
|
|
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.
|
|
34
|
-
"@barefootjs/shared": "0.31.
|
|
33
|
+
"@barefootjs/client": "0.31.4",
|
|
34
|
+
"@barefootjs/shared": "0.31.4"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
|
-
"@barefootjs/jsx": "0.31.
|
|
38
|
-
"@barefootjs/vite": "0.31.
|
|
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"
|