@barefootjs/rust 0.31.4 → 0.31.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -187314,8 +187314,8 @@ import {
187314
187314
  dangerousInnerHtmlMetacharViolation,
187315
187315
  dangerousInnerHtmlDiagnostic,
187316
187316
  resolveStaticLoopSource,
187317
- collectLoopBoundNames,
187318
- derivesScopeFromSlot
187317
+ derivesScopeFromSlot,
187318
+ BindingScope
187319
187319
  } from "@barefootjs/jsx";
187320
187320
 
187321
187321
  // src/adapter/boolean-result.ts
@@ -188315,8 +188315,7 @@ class MinijinjaAdapter extends BaseAdapter {
188315
188315
  _searchParamsLocals = new Set;
188316
188316
  _loweringMatchers = [];
188317
188317
  localConstants = [];
188318
- staticLoopSourceBoundNames = new Set;
188319
- loopBoundNames = new Map;
188318
+ scope = BindingScope.EMPTY;
188320
188319
  nullableOptionalProps = new Set;
188321
188320
  constructor(options = {}) {
188322
188321
  super();
@@ -188332,8 +188331,7 @@ class MinijinjaAdapter extends BaseAdapter {
188332
188331
  this.propsParams = ir.metadata.propsParams.map((p) => ({ name: p.name }));
188333
188332
  this.booleanTypedProps = collectBooleanTypedProps(ir);
188334
188333
  this.localConstants = ir.metadata.localConstants ?? [];
188335
- this.staticLoopSourceBoundNames = collectLoopBoundNames(ir);
188336
- this.loopBoundNames.clear();
188334
+ this.scope = BindingScope.EMPTY;
188337
188335
  this.nullableOptionalProps = collectNullableOptionalProps(ir);
188338
188336
  this.stringValueNames = collectStringValueNames(ir);
188339
188337
  this.moduleStringConsts = collectModuleStringConsts(ir.metadata.localConstants);
@@ -188627,7 +188625,7 @@ ${whenTrue}
188627
188625
  });
188628
188626
  }
188629
188627
  const staticItems = resolveStaticLoopSource(loop.arrayParsed, this.localConstants, {
188630
- isNameShadowed: (name) => this.staticLoopSourceBoundNames.has(name)
188628
+ isNameShadowed: this.scope.asShadowPredicate()
188631
188629
  });
188632
188630
  const staticArray = staticItems !== null ? staticValueToMinijinja(staticItems) : null;
188633
188631
  const arrayName = loop.array.trim();
@@ -188640,7 +188638,8 @@ ${whenTrue}
188640
188638
  message: `Loop array \`${arrayName}\` is a local computed value (\`${arrayConst.value}\`) that the MiniJinja adapter cannot bind as a template variable — only numeric/string-literal locals inline at their use site.`,
188641
188639
  loc: loop.loc ?? { file: this.componentName + ".tsx", start: { line: 1, column: 0 }, end: { line: 1, column: 0 } },
188642
188640
  suggestion: {
188643
- message: "Pre-compute the array server-side and pass it as a prop, or mark the loop position as @client-only so it runs in JS on the client."
188641
+ message: "Pre-compute the array server-side and pass it as a prop, or mark the loop position as @client-only so it runs in JS on the client.",
188642
+ escape: [{ kind: "prop-precompute" }, { kind: "client-directive" }]
188644
188643
  }
188645
188644
  });
188646
188645
  }
@@ -188681,42 +188680,15 @@ ${whenTrue}
188681
188680
  this.inLoop = true;
188682
188681
  const prevLoopKeyDepth = this.currentLoopKeyDepth;
188683
188682
  this.currentLoopKeyDepth = loop.depth;
188683
+ const prevScope = this.scope;
188684
+ this.scope = prevScope.enterLoopRow(loop);
188684
188685
  const preambleLines = (loop.preamble?.declarations ?? []).map((d) => `{% set ${minijinjaIdent(d.name)} = ${this.convertExpressionToJinja(d.raw, d.valueParsed)} %}`);
188685
- const loopBound = [];
188686
- if (loop.objectIteration === "entries") {
188687
- loopBound.push(loop.index ?? param, param);
188688
- } else if (loop.objectIteration === "keys") {
188689
- loopBound.push(param, "__bf_v");
188690
- } else if (loop.objectIteration === "values") {
188691
- loopBound.push("__bf_k", param);
188692
- } else if (loop.iterationShape === "keys") {
188693
- loopBound.push("__bf_item", param);
188694
- } else if (supportableDestructure) {
188695
- loopBound.push("__bf_item", ...(loop.paramBindings ?? []).map((b) => b.name));
188696
- if (loop.index)
188697
- loopBound.push(loop.index);
188698
- } else {
188699
- loopBound.push(param);
188700
- if (loop.index)
188701
- loopBound.push(loop.index);
188702
- }
188703
- for (const d of loop.preamble?.declarations ?? [])
188704
- loopBound.push(d.name);
188705
- for (const n of loopBound) {
188706
- this.loopBoundNames.set(n, (this.loopBoundNames.get(n) ?? 0) + 1);
188707
- }
188708
188686
  const childrenUnderLoop = this.renderChildren(loop.children);
188709
- for (const n of loopBound) {
188710
- const c = (this.loopBoundNames.get(n) ?? 1) - 1;
188711
- if (c <= 0)
188712
- this.loopBoundNames.delete(n);
188713
- else
188714
- this.loopBoundNames.set(n, c);
188715
- }
188716
188687
  this.currentLoopKeyDepth = prevLoopKeyDepth;
188717
188688
  this.inLoop = prevInLoop;
188718
188689
  const bodyChildren = loop.bodyIsItemConditional && loop.key ? `{{ bf.comment("loop-i:" ~ bf.string(${this.convertExpressionToJinja(loop.key)})) | safe }}
188719
188690
  ${childrenUnderLoop}` : childrenUnderLoop;
188691
+ this.scope = prevScope;
188720
188692
  const lines = [];
188721
188693
  lines.push(`{{ bf.comment("loop:${loop.markerId}") | safe }}`);
188722
188694
  const forHeader = loop.objectIteration === "entries" ? `{% for ${minijinjaIdent(loop.index ?? param)}, ${minijinjaIdent(param)} in ${array}|items %}` : loop.objectIteration === "keys" ? `{% for ${minijinjaIdent(param)}, __bf_v in ${array}|items %}` : loop.objectIteration === "values" ? `{% for __bf_k, ${minijinjaIdent(param)} in ${array}|items %}` : `{% for ${minijinjaIdent(loopVar)} in ${array} %}`;
@@ -188948,7 +188920,7 @@ ${name}="{{ bf.string(${val}) }}"
188948
188920
  if (ternaryDict !== null) {
188949
188921
  return `{{ bf.spread_attrs(${ternaryDict}) | safe }}`;
188950
188922
  }
188951
- if (/^[A-Za-z_$][\w$]*$/.test(trimmed) && !this.loopBoundNames.has(trimmed)) {
188923
+ if (/^[A-Za-z_$][\w$]*$/.test(trimmed) && !this.scope.isBound(trimmed)) {
188952
188924
  const localConst = (this.localConstants ?? []).find((c) => c.name === trimmed && !c.isModule);
188953
188925
  if (localConst?.value !== undefined) {
188954
188926
  const initTrimmed = localConst.value.trim();
@@ -189183,7 +189155,7 @@ Options:
189183
189155
  return this.booleanTypedProps.has(bare);
189184
189156
  }
189185
189157
  isLoopBoundName(name) {
189186
- return this.loopBoundNames.has(name);
189158
+ return this.scope.isBound(name);
189187
189159
  }
189188
189160
  shouldBoolStr(expr, name) {
189189
189161
  if (isExplicitStringCall(expr))
@@ -189191,7 +189163,7 @@ Options:
189191
189163
  return isBooleanResultExpr(expr) || isAriaBooleanAttr(name) || this.isBooleanTypedPropRef(expr);
189192
189164
  }
189193
189165
  _resolveLiteralConst(name) {
189194
- if (this.staticLoopSourceBoundNames.has(name))
189166
+ if (this.scope.isBound(name))
189195
189167
  return null;
189196
189168
  const c = (this.localConstants ?? []).find((lc) => lc.name === name);
189197
189169
  if (c?.value === undefined)
@@ -189205,9 +189177,7 @@ Options:
189205
189177
  return null;
189206
189178
  }
189207
189179
  _resolveStaticRecordLiteral(objectName, key) {
189208
- if (this.staticLoopSourceBoundNames.has(objectName))
189209
- return null;
189210
- const hit = lookupStaticRecordLiteral(objectName, key, this.localConstants);
189180
+ const hit = lookupStaticRecordLiteral(objectName, key, this.localConstants, (name) => this.scope.isBound(name));
189211
189181
  if (!hit)
189212
189182
  return null;
189213
189183
  return hit.kind === "number" ? hit.text : `'${escapeMinijinjaSingleQuoted(hit.text)}'`;
@@ -193,29 +193,24 @@ export declare class MinijinjaAdapter extends BaseAdapter implements IRNodeEmitt
193
193
  */
194
194
  private localConstants;
195
195
  /**
196
- * Every name a `.map()`/`.filter()` loop callback binds as its item/index
197
- * parameter anywhere in the component (#2208 fable review). A static
198
- * loop-SOURCE name (e.g. a function-scope `const items = [...]`) must
199
- * never resolve through `resolveStaticLoopSource` at a use site where a
200
- * DIFFERENT, enclosing loop's own callback param shadows it — same
201
- * shadowing hazard, and same coarse-but-safe mitigation, as #2212's
202
- * `collectLoopBoundNames` use in `collectStringValueNames`.
203
- */
204
- private staticLoopSourceBoundNames;
205
- /**
206
- * Names currently bound by an enclosing loop body — the block-param
207
- * locals `renderLoop` introduces (item, index, per-binding destructure
208
- * fields, `.map()` preamble declarations) — ref-counted so nested loops
209
- * compose. This is the POSITION-ACCURATE twin of the coarse
210
- * `staticLoopSourceBoundNames` above: that set is a whole-component
211
- * union used only to guard static-const inlining (safe to over-suppress
212
- * there — the fallback is just "don't inline"), whereas the boolean-prop
213
- * and nullable-optional classification sites (#2488) and `emitSpread`'s
214
- * local-const fallback (#2489) need to know whether a name is loop-bound
215
- * AT THIS POSITION, because for those the coarse fallback would silently
216
- * mis-render a genuine occurrence of the same name outside the loop too.
217
- */
218
- private loopBoundNames;
196
+ * The one canonical, position-accurate "names bound by an enclosing loop
197
+ * callback" service (#2482 Stage 2) replaces the two ad-hoc devices
198
+ * this adapter used to carry side by side: a coarse whole-component
199
+ * shadow-name Set (built once at `generate()` entry, used only to guard
200
+ * static-const inlining) and a ref-counted, position-accurate live map
201
+ * (pushed/popped around `renderLoop`'s body, used for the boolean-prop/
202
+ * nullable-optional classification sites (#2488) and `emitSpread`'s
203
+ * local-const fallback (#2489)). Both consulted the "is this name
204
+ * loop-bound" question with DIFFERENT meanings — the coarse/live drift
205
+ * #2482 Stage 2 ends. Every shadow-guard site now reads this ONE
206
+ * threaded, immutable scope: `enterLoopRow`/pop-by-reference around
207
+ * `renderChildren(loop.children)` in `renderLoop`, mirroring the Stage
208
+ * 1a/1b `ctx.scope` precedent in `jsx-to-ir.ts`. `IRLoop` already
209
+ * structurally satisfies `LoopBindingSource`
210
+ * (`param`/`index`/`paramBindings`/`preamble`), so `renderLoop` passes
211
+ * the loop node straight to `enterLoopRow`.
212
+ */
213
+ private scope;
219
214
  /**
220
215
  * Optional, no-default props that are `None` when the caller omits them.
221
216
  * Their bare-reference attribute emission is guarded with a Jinja
@@ -430,7 +425,7 @@ export declare class MinijinjaAdapter extends BaseAdapter implements IRNodeEmitt
430
425
  consequent: string;
431
426
  } | null;
432
427
  isBooleanTypedPropRef(expr: string): boolean;
433
- /** Position-accurate loop-bound-name check — see `loopBoundNames`'s docstring. */
428
+ /** Position-accurate loop-bound-name check — see `this.scope`'s docstring. */
434
429
  private isLoopBoundName;
435
430
  /**
436
431
  * Whether an attribute-value expression should route through
@@ -452,14 +447,13 @@ export declare class MinijinjaAdapter extends BaseAdapter implements IRNodeEmitt
452
447
  * context, so a bare reference would resolve to Undefined.
453
448
  *
454
449
  * The lookup is a flat name match with no notion of AST scope, so a
455
- * name that any loop callback binds as its item/index param never
456
- * inlines (#2221) — the occurrence may be the loop's own (shadowing)
457
- * binding, and substituting the outer const's value there renders every
458
- * iteration with the same hard-coded literal. Coarse (a genuinely
459
- * non-shadowed same-named const elsewhere in the component also stops
460
- * inlining, falling back to the bare identifier) but safe — the same
461
- * trade-off as #2212's `collectLoopBoundNames` use in
462
- * `collectStringValueNames`.
450
+ * name bound by the CURRENTLY ENCLOSING loop's item/index/destructure/
451
+ * preamble param never inlines (#2221) — the occurrence may be the
452
+ * loop's own (shadowing) binding, and substituting the outer const's
453
+ * value there renders every iteration with the same hard-coded literal.
454
+ * Position-accurate via the threaded `this.scope` (#2482 Stage 2) — a
455
+ * same-named const elsewhere in the component, outside any loop that
456
+ * shadows it, still inlines.
463
457
  */
464
458
  private _resolveLiteralConst;
465
459
  /**
@@ -470,11 +464,13 @@ export declare class MinijinjaAdapter extends BaseAdapter implements IRNodeEmitt
470
464
  * scope, so an enclosing loop callback's own param of the same name
471
465
  * (`.map((cfg) => <li>{cfg.x}</li>)` shadowing a module `const cfg = {…}`)
472
466
  * still resolved to the OUTER const's member value at every iteration
473
- * (#2237) — the sibling hazard to #2221's `_resolveLiteralConst`. Same
474
- * coarse-but-safe `staticLoopSourceBoundNames` guard: any name a loop
475
- * binds anywhere in the component never inlines, falling back to the bare
476
- * `cfg.x` member expression (which a minijinja `for` loop binds correctly
477
- * at the shadowed occurrences).
467
+ * (#2237) — the sibling hazard to #2221's `_resolveLiteralConst`.
468
+ * Position-accurate via the threaded `this.scope` (#2482 Stage 2), passed
469
+ * as `lookupStaticRecordLiteral`'s required guard: a name the CURRENTLY
470
+ * ENCLOSING loop binds never inlines, falling back to the bare `cfg.x`
471
+ * member expression (which a minijinja `for` loop binds correctly at the
472
+ * shadowed occurrence); a same-named const elsewhere, outside any loop
473
+ * that shadows it, still inlines.
478
474
  */
479
475
  private _resolveStaticRecordLiteral;
480
476
  private _resolveModuleStringConst;
@@ -1 +1 @@
1
- {"version":3,"file":"minijinja-adapter.d.ts","sourceRoot":"","sources":["../../src/adapter/minijinja-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiHG;AAEH,OAAO,KAAK,EACV,WAAW,EACX,MAAM,EACN,SAAS,EACT,MAAM,EACN,YAAY,EACZ,aAAa,EACb,MAAM,EACN,WAAW,EACX,UAAU,EACV,MAAM,EACN,aAAa,EACb,UAAU,EACV,OAAO,EAKP,yBAAyB,EAE1B,MAAM,iBAAiB,CAAA;AACxB,OAAO,EACL,WAAW,EACX,KAAK,aAAa,EAClB,KAAK,sBAAsB,EAE3B,KAAK,aAAa,EAClB,KAAK,UAAU,EAgChB,MAAM,iBAAiB,CAAA;AAKxB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AA6BpD,YAAY,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAA;AAC7D,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAA;AA8B7D,qBAAa,gBAAiB,SAAQ,WAAY,YAAW,aAAa,CAAC,cAAc,CAAC;IACxF,IAAI,SAAc;IAClB,SAAS,SAAQ;IACjB,qBAAqB,UAAO;IAE5B;;;;;OAKG;IACH,kBAAkB,EAAE,yBAAyB,CAA2B;IAExE,OAAO,CAAC,aAAa,CAAa;IAClC;;;uCAGmC;IACnC,OAAO,CAAC,cAAc,CAAyB;IAC/C,OAAO,CAAC,OAAO,CAAmC;IAClD,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,MAAM,CAAiB;IAC/B;;;;;;OAMG;IACH,OAAO,CAAC,mBAAmB,CAAI;IAC/B;;;;;OAKG;IACH,OAAO,CAAC,eAAe,CAAsB;IAC7C,OAAO,CAAC,WAAW,CAAyB;IAC5C,OAAO,CAAC,iBAAiB,CAAyB;IAClD;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB,CAAyB;IAEjD;;;;;;OAMG;IACH,OAAO,CAAC,kBAAkB,CAAiC;IAE3D;;;;;;;OAOG;IACH,OAAO,CAAC,mBAAmB,CAAyB;IAEpD;;;;;OAKG;IACH,OAAO,CAAC,iBAAiB,CAAwB;IAEjD;;;;;OAKG;IACH,OAAO,CAAC,cAAc,CAAmC;IAEzD;;;;;;;;OAQG;IACH,OAAO,CAAC,0BAA0B,CAAyB;IAE3D;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,cAAc,CAAiC;IAEvD;;;;;;;OAOG;IACH,OAAO,CAAC,qBAAqB,CAAyB;IAEtD,YAAY,OAAO,GAAE,uBAA4B,EAMhD;IAED,QAAQ,CAAC,EAAE,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,sBAAsB,GAAG,aAAa,CA8EzE;IAMD,OAAO,CAAC,2BAA2B;IAqDnC;;;;OAIG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE/B;IAMD,WAAW,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,UAAU,CAAC,cAAc,CAAC,GAAG,MAAM,CAE5F;IAED,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAI7B;IAED,cAAc,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAEzC;IAED,eAAe,CAAC,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,UAAU,CAAC,cAAc,CAAC,GAAG,MAAM,CAEpG;IAED,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,UAAU,CAAC,cAAc,CAAC,GAAG,MAAM,CAEtF;IAED,aAAa,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,UAAU,CAAC,cAAc,CAAC,GAAG,MAAM,CAEhG;IAED,YAAY,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,UAAU,CAAC,cAAc,CAAC,GAAG,MAAM,CAE9F;IAED,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE7B;IAED,eAAe,CAAC,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,UAAU,CAAC,cAAc,CAAC,GAAG,MAAM,CAEpG;IAED,YAAY,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,UAAU,CAAC,cAAc,CAAC,GAAG,MAAM,CAe9F;IAED,uEAAuE;IACvE,OAAO,CAAC,kBAAkB;IAmB1B;;;;;;;;;;;;;;;;;OAiBG;IACH,OAAO,CAAC,0BAA0B;IAYlC,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,UAAU,CAAC,cAAc,CAAC,GAAG,MAAM,CAExF;IAMD,aAAa,CAAC,OAAO,EAAE,SAAS,GAAG,MAAM,CAqCxC;IAED;;;;;OAKG;IACH,OAAO,CAAC,wBAAwB;IA2BhC,gBAAgB,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CA6B3C;IAMD,iBAAiB,CAAC,IAAI,EAAE,aAAa,GAAG,MAAM,CAuC7C;IAED,OAAO,CAAC,gBAAgB;IAOxB;;;OAGG;IACH,OAAO,CAAC,2BAA2B;IAcnC,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAmT/B;IAMD;;;;;;;;OAQG;IACH,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAoCpC;IAED;;;;;;;;;;OAUG;IACH,OAAO,CAAC,2BAA2B;IAUnC;;;;;;;;;;;;;;;;;;OAkBG;IACH,OAAO,CAAC,4BAA4B;IAiBpC,eAAe,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,CA8FzC;IAED,OAAO,CAAC,sBAAsB,CAAI;IAElC;+DAC2D;IAC3D,OAAO,CAAC,kBAAkB,CAAI;IAE9B,OAAO,CAAC,cAAc;IAYtB,OAAO,CAAC,iBAAiB;IA0BzB,OAAO,CAAC,cAAc;IAWtB,OAAO,CAAC,UAAU;IAYT,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAQ1C;IAMD;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAqKlC;IAED;;;;;;;;;OASG;IACH,OAAO,CAAC,mBAAmB;IAa3B,OAAO,CAAC,gBAAgB;IAoCxB,iBAAiB,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,CAIjD;IAED,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEvC;IAED,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEvC;IAMD;;;;;OAKG;IACH,OAAO,CAAC,qBAAqB;IAuB7B,OAAO,CAAC,kCAAkC;IAoC1C;;;;;OAKG;IACH,OAAO,CAAC,iCAAiC;IAmBzC;;;;;OAKG;IACH,OAAO,CAAC,+BAA+B;IAuBvC;;;;;;;OAOG;IACH,OAAO,KAAK,OAAO,GASlB;IAED;;;;;OAKG;IACH,OAAO,KAAK,SAAS,GASpB;IAED,sEAAsE;IACtE,OAAO,KAAK,OAAO,GAKlB;IAED,OAAO,CAAC,wBAAwB;IAyEhC;;;;;OAKG;IACH,OAAO,CAAC,uBAAuB;IAK/B;;;;;;;OAOG;IACH,OAAO,CAAC,iBAAiB;IAOzB;;;OAGG;IACH,OAAO,CAAC,uBAAuB;IAI/B;;gFAE4E;IAC5E,OAAO,CAAC,kBAAkB;IAI1B;;;;OAIG;IACH,8BAA8B,CAC5B,IAAI,EAAE,MAAM,GACX;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAgBlD;IAED,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAW3C;IAED,kFAAkF;IAClF,OAAO,CAAC,eAAe;IAIvB;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,aAAa;IAKrB;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,oBAAoB;IAW5B;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,2BAA2B;IASnC,OAAO,CAAC,yBAAyB;IAUjC,OAAO,CAAC,gBAAgB;IAcxB,iFAAiF;IACjF,OAAO,CAAC,4BAA4B;CAGrC;AAED,eAAO,MAAM,gBAAgB,kBAAyB,CAAA"}
1
+ {"version":3,"file":"minijinja-adapter.d.ts","sourceRoot":"","sources":["../../src/adapter/minijinja-adapter.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"conformance-pins.d.ts","sourceRoot":"","sources":["../src/conformance-pins.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEtD,eAAO,MAAM,eAAe,EAAE,eAwI7B,CAAA"}
1
+ {"version":3,"file":"conformance-pins.d.ts","sourceRoot":"","sources":["../src/conformance-pins.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEtD,eAAO,MAAM,eAAe,EAAE,eAiJ7B,CAAA"}
package/dist/index.js CHANGED
@@ -187314,8 +187314,8 @@ import {
187314
187314
  dangerousInnerHtmlMetacharViolation,
187315
187315
  dangerousInnerHtmlDiagnostic,
187316
187316
  resolveStaticLoopSource,
187317
- collectLoopBoundNames,
187318
- derivesScopeFromSlot
187317
+ derivesScopeFromSlot,
187318
+ BindingScope
187319
187319
  } from "@barefootjs/jsx";
187320
187320
 
187321
187321
  // src/adapter/boolean-result.ts
@@ -188315,8 +188315,7 @@ class MinijinjaAdapter extends BaseAdapter {
188315
188315
  _searchParamsLocals = new Set;
188316
188316
  _loweringMatchers = [];
188317
188317
  localConstants = [];
188318
- staticLoopSourceBoundNames = new Set;
188319
- loopBoundNames = new Map;
188318
+ scope = BindingScope.EMPTY;
188320
188319
  nullableOptionalProps = new Set;
188321
188320
  constructor(options = {}) {
188322
188321
  super();
@@ -188332,8 +188331,7 @@ class MinijinjaAdapter extends BaseAdapter {
188332
188331
  this.propsParams = ir.metadata.propsParams.map((p) => ({ name: p.name }));
188333
188332
  this.booleanTypedProps = collectBooleanTypedProps(ir);
188334
188333
  this.localConstants = ir.metadata.localConstants ?? [];
188335
- this.staticLoopSourceBoundNames = collectLoopBoundNames(ir);
188336
- this.loopBoundNames.clear();
188334
+ this.scope = BindingScope.EMPTY;
188337
188335
  this.nullableOptionalProps = collectNullableOptionalProps(ir);
188338
188336
  this.stringValueNames = collectStringValueNames(ir);
188339
188337
  this.moduleStringConsts = collectModuleStringConsts(ir.metadata.localConstants);
@@ -188627,7 +188625,7 @@ ${whenTrue}
188627
188625
  });
188628
188626
  }
188629
188627
  const staticItems = resolveStaticLoopSource(loop.arrayParsed, this.localConstants, {
188630
- isNameShadowed: (name) => this.staticLoopSourceBoundNames.has(name)
188628
+ isNameShadowed: this.scope.asShadowPredicate()
188631
188629
  });
188632
188630
  const staticArray = staticItems !== null ? staticValueToMinijinja(staticItems) : null;
188633
188631
  const arrayName = loop.array.trim();
@@ -188640,7 +188638,8 @@ ${whenTrue}
188640
188638
  message: `Loop array \`${arrayName}\` is a local computed value (\`${arrayConst.value}\`) that the MiniJinja adapter cannot bind as a template variable — only numeric/string-literal locals inline at their use site.`,
188641
188639
  loc: loop.loc ?? { file: this.componentName + ".tsx", start: { line: 1, column: 0 }, end: { line: 1, column: 0 } },
188642
188640
  suggestion: {
188643
- message: "Pre-compute the array server-side and pass it as a prop, or mark the loop position as @client-only so it runs in JS on the client."
188641
+ message: "Pre-compute the array server-side and pass it as a prop, or mark the loop position as @client-only so it runs in JS on the client.",
188642
+ escape: [{ kind: "prop-precompute" }, { kind: "client-directive" }]
188644
188643
  }
188645
188644
  });
188646
188645
  }
@@ -188681,42 +188680,15 @@ ${whenTrue}
188681
188680
  this.inLoop = true;
188682
188681
  const prevLoopKeyDepth = this.currentLoopKeyDepth;
188683
188682
  this.currentLoopKeyDepth = loop.depth;
188683
+ const prevScope = this.scope;
188684
+ this.scope = prevScope.enterLoopRow(loop);
188684
188685
  const preambleLines = (loop.preamble?.declarations ?? []).map((d) => `{% set ${minijinjaIdent(d.name)} = ${this.convertExpressionToJinja(d.raw, d.valueParsed)} %}`);
188685
- const loopBound = [];
188686
- if (loop.objectIteration === "entries") {
188687
- loopBound.push(loop.index ?? param, param);
188688
- } else if (loop.objectIteration === "keys") {
188689
- loopBound.push(param, "__bf_v");
188690
- } else if (loop.objectIteration === "values") {
188691
- loopBound.push("__bf_k", param);
188692
- } else if (loop.iterationShape === "keys") {
188693
- loopBound.push("__bf_item", param);
188694
- } else if (supportableDestructure) {
188695
- loopBound.push("__bf_item", ...(loop.paramBindings ?? []).map((b) => b.name));
188696
- if (loop.index)
188697
- loopBound.push(loop.index);
188698
- } else {
188699
- loopBound.push(param);
188700
- if (loop.index)
188701
- loopBound.push(loop.index);
188702
- }
188703
- for (const d of loop.preamble?.declarations ?? [])
188704
- loopBound.push(d.name);
188705
- for (const n of loopBound) {
188706
- this.loopBoundNames.set(n, (this.loopBoundNames.get(n) ?? 0) + 1);
188707
- }
188708
188686
  const childrenUnderLoop = this.renderChildren(loop.children);
188709
- for (const n of loopBound) {
188710
- const c = (this.loopBoundNames.get(n) ?? 1) - 1;
188711
- if (c <= 0)
188712
- this.loopBoundNames.delete(n);
188713
- else
188714
- this.loopBoundNames.set(n, c);
188715
- }
188716
188687
  this.currentLoopKeyDepth = prevLoopKeyDepth;
188717
188688
  this.inLoop = prevInLoop;
188718
188689
  const bodyChildren = loop.bodyIsItemConditional && loop.key ? `{{ bf.comment("loop-i:" ~ bf.string(${this.convertExpressionToJinja(loop.key)})) | safe }}
188719
188690
  ${childrenUnderLoop}` : childrenUnderLoop;
188691
+ this.scope = prevScope;
188720
188692
  const lines = [];
188721
188693
  lines.push(`{{ bf.comment("loop:${loop.markerId}") | safe }}`);
188722
188694
  const forHeader = loop.objectIteration === "entries" ? `{% for ${minijinjaIdent(loop.index ?? param)}, ${minijinjaIdent(param)} in ${array}|items %}` : loop.objectIteration === "keys" ? `{% for ${minijinjaIdent(param)}, __bf_v in ${array}|items %}` : loop.objectIteration === "values" ? `{% for __bf_k, ${minijinjaIdent(param)} in ${array}|items %}` : `{% for ${minijinjaIdent(loopVar)} in ${array} %}`;
@@ -188948,7 +188920,7 @@ ${name}="{{ bf.string(${val}) }}"
188948
188920
  if (ternaryDict !== null) {
188949
188921
  return `{{ bf.spread_attrs(${ternaryDict}) | safe }}`;
188950
188922
  }
188951
- if (/^[A-Za-z_$][\w$]*$/.test(trimmed) && !this.loopBoundNames.has(trimmed)) {
188923
+ if (/^[A-Za-z_$][\w$]*$/.test(trimmed) && !this.scope.isBound(trimmed)) {
188952
188924
  const localConst = (this.localConstants ?? []).find((c) => c.name === trimmed && !c.isModule);
188953
188925
  if (localConst?.value !== undefined) {
188954
188926
  const initTrimmed = localConst.value.trim();
@@ -189183,7 +189155,7 @@ Options:
189183
189155
  return this.booleanTypedProps.has(bare);
189184
189156
  }
189185
189157
  isLoopBoundName(name) {
189186
- return this.loopBoundNames.has(name);
189158
+ return this.scope.isBound(name);
189187
189159
  }
189188
189160
  shouldBoolStr(expr, name) {
189189
189161
  if (isExplicitStringCall(expr))
@@ -189191,7 +189163,7 @@ Options:
189191
189163
  return isBooleanResultExpr(expr) || isAriaBooleanAttr(name) || this.isBooleanTypedPropRef(expr);
189192
189164
  }
189193
189165
  _resolveLiteralConst(name) {
189194
- if (this.staticLoopSourceBoundNames.has(name))
189166
+ if (this.scope.isBound(name))
189195
189167
  return null;
189196
189168
  const c = (this.localConstants ?? []).find((lc) => lc.name === name);
189197
189169
  if (c?.value === undefined)
@@ -189205,9 +189177,7 @@ Options:
189205
189177
  return null;
189206
189178
  }
189207
189179
  _resolveStaticRecordLiteral(objectName, key) {
189208
- if (this.staticLoopSourceBoundNames.has(objectName))
189209
- return null;
189210
- const hit = lookupStaticRecordLiteral(objectName, key, this.localConstants);
189180
+ const hit = lookupStaticRecordLiteral(objectName, key, this.localConstants, (name) => this.scope.isBound(name));
189211
189181
  if (!hit)
189212
189182
  return null;
189213
189183
  return hit.kind === "number" ? hit.text : `'${escapeMinijinjaSingleQuoted(hit.text)}'`;
@@ -189257,17 +189227,23 @@ var conformancePins = {
189257
189227
  "tag-cloud": [{ code: "BF021", severity: "error" }],
189258
189228
  "preamble-cells": [{ code: "BF021", severity: "error" }],
189259
189229
  "static-array-from-props": [
189260
- { code: "BF101", severity: "error", issue: "https://github.com/piconic-ai/barefootjs/issues/2321" }
189230
+ {
189231
+ code: "BF101",
189232
+ severity: "error",
189233
+ issue: "https://github.com/piconic-ai/barefootjs/issues/2321"
189234
+ }
189261
189235
  ],
189262
189236
  "static-array-from-props-with-component": [
189263
- { code: "BF101", severity: "error", issue: "https://github.com/piconic-ai/barefootjs/issues/2321" }
189237
+ {
189238
+ code: "BF101",
189239
+ severity: "error",
189240
+ issue: "https://github.com/piconic-ai/barefootjs/issues/2321"
189241
+ }
189264
189242
  ],
189265
189243
  "filter-nested-callback-predicate": [
189266
189244
  { code: "BF101", severity: "error", issue: "https://github.com/piconic-ai/barefootjs/issues/2320" }
189267
189245
  ],
189268
- "filter-nested-find-predicate": [
189269
- { code: "BF101", severity: "error", issue: "https://github.com/piconic-ai/barefootjs/issues/2320" }
189270
- ],
189246
+ "filter-nested-find-predicate": [{ code: "BF101", severity: "error", issue: "https://github.com/piconic-ai/barefootjs/issues/2320" }],
189271
189247
  "date-method-uncatalogued": [{ code: "BF021", severity: "error", issue: "https://github.com/piconic-ai/barefootjs/issues/2356" }]
189272
189248
  };
189273
189249
  // src/render-divergences.ts