@barefootjs/erb 0.31.3 → 0.31.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -128,17 +128,23 @@ export declare class ErbAdapter extends BaseAdapter implements IRNodeEmitter<Erb
128
128
  */
129
129
  private localConstants;
130
130
  /**
131
- * Names currently bound by an enclosing loop body — the block-param
132
- * locals `renderLoop` introduces (item, index, per-binding destructure
133
- * fields) ref-counted so nested loops compose. This is load-bearing
134
- * for TWO things in the ERB adapter (more than the Mojo original, which
135
- * only used it to guard const-inlining): it also decides the
136
- * fundamental `v[:name]` vs bare-Ruby-local rendering choice in
137
- * `ErbTopLevelEmitter.identifier` — see `emit-context.ts`'s
138
- * `isLoopBoundName` docstring for why ERB's two-locals model needs this
139
- * where Perl's uniform `$name` sigil does not.
131
+ * The one canonical, position-accurate "names bound by an enclosing loop
132
+ * callback" service (#2482 Stage 2) — replaces the ref-counted
133
+ * `Map<string, number>` this adapter used to push/pop around
134
+ * `renderLoop`'s body. Load-bearing for TWO things in the ERB adapter
135
+ * (more than the Mojo original, which only used it to guard
136
+ * const-inlining): it also decides the fundamental `v[:name]` vs
137
+ * bare-Ruby-local rendering choice in `ErbTopLevelEmitter.identifier` —
138
+ * see `emit-context.ts`'s `isLoopBoundName` docstring for why ERB's
139
+ * two-locals model needs this where Perl's uniform `$name` sigil does
140
+ * not. Threaded via save/restore-by-reference around
141
+ * `renderChildren(loop.children)` in `renderLoop` (immutable — no
142
+ * ref-count bookkeeping), mirroring the Stage 1a/1b `ctx.scope`
143
+ * precedent in `jsx-to-ir.ts`. `IRLoop` already structurally satisfies
144
+ * `LoopBindingSource` (`param`/`index`/`paramBindings`/`preamble`), so
145
+ * `renderLoop` passes the loop node straight to `enterLoopRow`.
140
146
  */
141
- private loopBoundNames;
147
+ private scope;
142
148
  /**
143
149
  * Prop names whose value is `nil` in the template body when the caller
144
150
  * omits them — so a bare-reference attribute should be dropped rather
@@ -1 +1 @@
1
- {"version":3,"file":"erb-adapter.d.ts","sourceRoot":"","sources":["../../src/adapter/erb-adapter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"erb-adapter.d.ts","sourceRoot":"","sources":["../../src/adapter/erb-adapter.ts"],"names":[],"mappings":"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"}
@@ -187314,7 +187314,8 @@ import {
187314
187314
  dangerousInnerHtmlMetacharViolation,
187315
187315
  dangerousInnerHtmlDiagnostic,
187316
187316
  resolveStaticLoopSource,
187317
- derivesScopeFromSlot
187317
+ derivesScopeFromSlot,
187318
+ BindingScope
187318
187319
  } from "@barefootjs/jsx";
187319
187320
 
187320
187321
  // src/adapter/boolean-result.ts
@@ -188372,7 +188373,7 @@ class ErbAdapter extends BaseAdapter {
188372
188373
  _loweringMatchers = [];
188373
188374
  moduleStringConsts = new Map;
188374
188375
  localConstants = [];
188375
- loopBoundNames = new Map;
188376
+ scope = BindingScope.EMPTY;
188376
188377
  nullableOptionalProps = new Set;
188377
188378
  constructor(options = {}) {
188378
188379
  super();
@@ -188394,7 +188395,7 @@ class ErbAdapter extends BaseAdapter {
188394
188395
  this._searchParamsLocals = searchParamsLocalNames(ir.metadata);
188395
188396
  this._loweringMatchers = prepareLoweringMatchers(ir.metadata);
188396
188397
  this.localConstants = ir.metadata.localConstants ?? [];
188397
- this.loopBoundNames.clear();
188398
+ this.scope = BindingScope.EMPTY;
188398
188399
  this.errors = [];
188399
188400
  this.childrenCaptureCounter = 0;
188400
188401
  if (!options?.siblingTemplatesRegistered) {
@@ -188452,7 +188453,7 @@ class ErbAdapter extends BaseAdapter {
188452
188453
  };
188453
188454
  }
188454
188455
  resolveLiteralConst(name) {
188455
- if (this.loopBoundNames?.has?.(name))
188456
+ if (this.scope.isBound(name))
188456
188457
  return null;
188457
188458
  const c = (this.localConstants ?? []).find((lc) => lc.name === name);
188458
188459
  if (c?.value === undefined)
@@ -188466,15 +188467,13 @@ class ErbAdapter extends BaseAdapter {
188466
188467
  return null;
188467
188468
  }
188468
188469
  resolveStaticRecordLiteral(objectName, key) {
188469
- if (this.loopBoundNames?.has?.(objectName))
188470
- return null;
188471
- const hit = lookupStaticRecordLiteral(objectName, key, this.localConstants);
188470
+ const hit = lookupStaticRecordLiteral(objectName, key, this.localConstants, (name) => this.scope.isBound(name));
188472
188471
  if (!hit)
188473
188472
  return null;
188474
188473
  return hit.kind === "number" ? hit.text : rubyStringLiteral(hit.text);
188475
188474
  }
188476
188475
  resolveModuleStringConst(name) {
188477
- if (this.loopBoundNames.has(name))
188476
+ if (this.scope.isBound(name))
188478
188477
  return null;
188479
188478
  const value = this.moduleStringConsts.get(name);
188480
188479
  if (value === undefined)
@@ -188482,7 +188481,7 @@ class ErbAdapter extends BaseAdapter {
188482
188481
  return rubyStringLiteral(value);
188483
188482
  }
188484
188483
  isLoopBoundName(name) {
188485
- return this.loopBoundNames.has(name);
188484
+ return this.scope.isBound(name);
188486
188485
  }
188487
188486
  generateScriptRegistrations(ir, scriptBaseName, scriptAssets, preloadAssets) {
188488
188487
  if (scriptAssets) {
@@ -188759,12 +188758,12 @@ ${whenTrue}
188759
188758
  });
188760
188759
  }
188761
188760
  const staticItems = resolveStaticLoopSource(loop.arrayParsed, this.localConstants, {
188762
- isNameShadowed: (name) => this.loopBoundNames.has(name)
188761
+ isNameShadowed: this.scope.asShadowPredicate()
188763
188762
  });
188764
188763
  const staticArray = staticItems !== null ? staticValueToRuby(staticItems) : null;
188765
188764
  if (staticArray === null && loop.arrayParsed?.kind === "identifier") {
188766
188765
  const arrayName = loop.arrayParsed.name;
188767
- const isUnresolvableLocalConst = !this.loopBoundNames.has(arrayName) && this.resolveModuleStringConst(arrayName) === null && this.resolveLiteralConst(arrayName) === null && this.localConstants.some((c) => c.name === arrayName && !c.isModule);
188766
+ const isUnresolvableLocalConst = !this.scope.isBound(arrayName) && this.resolveModuleStringConst(arrayName) === null && this.resolveLiteralConst(arrayName) === null && this.localConstants.some((c) => c.name === arrayName && !c.isModule);
188768
188767
  if (isUnresolvableLocalConst) {
188769
188768
  this._recordExprBF101(`Loop array \`${arrayName}\` is a component-scope const computed from a runtime expression the ERB adapter cannot evaluate at SSR render time.`, `Options:
188770
188769
  1. Inline the array expression directly in the .map() call instead of a preceding const.
@@ -188781,13 +188780,9 @@ ${whenTrue}
188781
188780
  }
188782
188781
  const param = loop.param;
188783
188782
  const indexVar = loop.iterationShape === "keys" ? rubyLocal(param) : rubyLocal(loop.index ?? "_i");
188784
- const loopBound = loop.objectIteration === "entries" ? [param, loop.index ?? "_k"] : loop.objectIteration === "keys" || loop.objectIteration === "values" || loop.iterationShape === "keys" ? [param] : supportableDestructure ? ["__bf_item", ...(loop.paramBindings ?? []).map((b) => b.name), loop.index ?? "_i"] : [param, loop.index ?? "_i"];
188785
188783
  const preambleDecls = loop.preamble?.declarations ?? [];
188786
- for (const d of preambleDecls)
188787
- loopBound.push(d.name);
188788
- for (const n of loopBound) {
188789
- this.loopBoundNames.set(n, (this.loopBoundNames.get(n) ?? 0) + 1);
188790
- }
188784
+ const prevScope = this.scope;
188785
+ this.scope = prevScope.enterLoopRow(loop);
188791
188786
  const prevLoopKeyDepth = this.currentLoopKeyDepth;
188792
188787
  this.currentLoopKeyDepth = loop.depth;
188793
188788
  const renderedChildren = this.renderChildren(loop.children);
@@ -188797,13 +188792,7 @@ ${renderedChildren}` : renderedChildren;
188797
188792
  const lines = [];
188798
188793
  lines.push(`<%= bf.comment("loop:${loop.markerId}") %>`);
188799
188794
  if (sortedHoist && loop.sortComparator) {
188800
- for (const n of loopBound) {
188801
- const c = (this.loopBoundNames.get(n) ?? 1) - 1;
188802
- if (c <= 0)
188803
- this.loopBoundNames.delete(n);
188804
- else
188805
- this.loopBoundNames.set(n, c);
188806
- }
188795
+ this.scope = prevScope;
188807
188796
  const sortEmit = (e) => this.convertExpressionToRuby("", e);
188808
188797
  const sortArrow = loop.sortComparator.arrow;
188809
188798
  let sorted = null;
@@ -188819,9 +188808,7 @@ ${renderedChildren}` : renderedChildren;
188819
188808
  this._recordExprBF101(`.sort(...) loop comparator is not lowerable to a template sort`, `Pre-sort the array in the route handler, or mark the loop @client-only.`);
188820
188809
  sorted = rawArray;
188821
188810
  }
188822
- for (const n of loopBound) {
188823
- this.loopBoundNames.set(n, (this.loopBoundNames.get(n) ?? 0) + 1);
188824
- }
188811
+ this.scope = prevScope.enterLoopRow(loop);
188825
188812
  lines.push(`<%- ${sortedHoist} = ${sorted} -%>`);
188826
188813
  }
188827
188814
  if (loop.objectIteration) {
@@ -188867,13 +188854,7 @@ ${renderedChildren}` : renderedChildren;
188867
188854
  lines.push(...preambleLines);
188868
188855
  lines.push(children);
188869
188856
  }
188870
- for (const n of loopBound) {
188871
- const c = (this.loopBoundNames.get(n) ?? 1) - 1;
188872
- if (c <= 0)
188873
- this.loopBoundNames.delete(n);
188874
- else
188875
- this.loopBoundNames.set(n, c);
188876
- }
188857
+ this.scope = prevScope;
188877
188858
  lines.push(`<%- end -%>`);
188878
188859
  lines.push(`<%= bf.comment("/loop:${loop.markerId}") %>`);
188879
188860
  return lines.join(`
@@ -189035,7 +189016,7 @@ ${children}`;
189035
189016
  if (ternaryHash !== null) {
189036
189017
  return `<%= bf.spread_attrs(${ternaryHash}) %>`;
189037
189018
  }
189038
- if (/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(trimmed) && !this.loopBoundNames.has(trimmed)) {
189019
+ if (/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(trimmed) && !this.scope.isBound(trimmed)) {
189039
189020
  const localConst = this.localConstants.find((c) => c.name === trimmed && !c.isModule);
189040
189021
  if (localConst?.value !== undefined) {
189041
189022
  const initTrimmed = localConst.value.trim();
package/dist/index.js CHANGED
@@ -187314,7 +187314,8 @@ import {
187314
187314
  dangerousInnerHtmlMetacharViolation,
187315
187315
  dangerousInnerHtmlDiagnostic,
187316
187316
  resolveStaticLoopSource,
187317
- derivesScopeFromSlot
187317
+ derivesScopeFromSlot,
187318
+ BindingScope
187318
187319
  } from "@barefootjs/jsx";
187319
187320
 
187320
187321
  // src/adapter/boolean-result.ts
@@ -188372,7 +188373,7 @@ class ErbAdapter extends BaseAdapter {
188372
188373
  _loweringMatchers = [];
188373
188374
  moduleStringConsts = new Map;
188374
188375
  localConstants = [];
188375
- loopBoundNames = new Map;
188376
+ scope = BindingScope.EMPTY;
188376
188377
  nullableOptionalProps = new Set;
188377
188378
  constructor(options = {}) {
188378
188379
  super();
@@ -188394,7 +188395,7 @@ class ErbAdapter extends BaseAdapter {
188394
188395
  this._searchParamsLocals = searchParamsLocalNames(ir.metadata);
188395
188396
  this._loweringMatchers = prepareLoweringMatchers(ir.metadata);
188396
188397
  this.localConstants = ir.metadata.localConstants ?? [];
188397
- this.loopBoundNames.clear();
188398
+ this.scope = BindingScope.EMPTY;
188398
188399
  this.errors = [];
188399
188400
  this.childrenCaptureCounter = 0;
188400
188401
  if (!options?.siblingTemplatesRegistered) {
@@ -188452,7 +188453,7 @@ class ErbAdapter extends BaseAdapter {
188452
188453
  };
188453
188454
  }
188454
188455
  resolveLiteralConst(name) {
188455
- if (this.loopBoundNames?.has?.(name))
188456
+ if (this.scope.isBound(name))
188456
188457
  return null;
188457
188458
  const c = (this.localConstants ?? []).find((lc) => lc.name === name);
188458
188459
  if (c?.value === undefined)
@@ -188466,15 +188467,13 @@ class ErbAdapter extends BaseAdapter {
188466
188467
  return null;
188467
188468
  }
188468
188469
  resolveStaticRecordLiteral(objectName, key) {
188469
- if (this.loopBoundNames?.has?.(objectName))
188470
- return null;
188471
- const hit = lookupStaticRecordLiteral(objectName, key, this.localConstants);
188470
+ const hit = lookupStaticRecordLiteral(objectName, key, this.localConstants, (name) => this.scope.isBound(name));
188472
188471
  if (!hit)
188473
188472
  return null;
188474
188473
  return hit.kind === "number" ? hit.text : rubyStringLiteral(hit.text);
188475
188474
  }
188476
188475
  resolveModuleStringConst(name) {
188477
- if (this.loopBoundNames.has(name))
188476
+ if (this.scope.isBound(name))
188478
188477
  return null;
188479
188478
  const value = this.moduleStringConsts.get(name);
188480
188479
  if (value === undefined)
@@ -188482,7 +188481,7 @@ class ErbAdapter extends BaseAdapter {
188482
188481
  return rubyStringLiteral(value);
188483
188482
  }
188484
188483
  isLoopBoundName(name) {
188485
- return this.loopBoundNames.has(name);
188484
+ return this.scope.isBound(name);
188486
188485
  }
188487
188486
  generateScriptRegistrations(ir, scriptBaseName, scriptAssets, preloadAssets) {
188488
188487
  if (scriptAssets) {
@@ -188759,12 +188758,12 @@ ${whenTrue}
188759
188758
  });
188760
188759
  }
188761
188760
  const staticItems = resolveStaticLoopSource(loop.arrayParsed, this.localConstants, {
188762
- isNameShadowed: (name) => this.loopBoundNames.has(name)
188761
+ isNameShadowed: this.scope.asShadowPredicate()
188763
188762
  });
188764
188763
  const staticArray = staticItems !== null ? staticValueToRuby(staticItems) : null;
188765
188764
  if (staticArray === null && loop.arrayParsed?.kind === "identifier") {
188766
188765
  const arrayName = loop.arrayParsed.name;
188767
- const isUnresolvableLocalConst = !this.loopBoundNames.has(arrayName) && this.resolveModuleStringConst(arrayName) === null && this.resolveLiteralConst(arrayName) === null && this.localConstants.some((c) => c.name === arrayName && !c.isModule);
188766
+ const isUnresolvableLocalConst = !this.scope.isBound(arrayName) && this.resolveModuleStringConst(arrayName) === null && this.resolveLiteralConst(arrayName) === null && this.localConstants.some((c) => c.name === arrayName && !c.isModule);
188768
188767
  if (isUnresolvableLocalConst) {
188769
188768
  this._recordExprBF101(`Loop array \`${arrayName}\` is a component-scope const computed from a runtime expression the ERB adapter cannot evaluate at SSR render time.`, `Options:
188770
188769
  1. Inline the array expression directly in the .map() call instead of a preceding const.
@@ -188781,13 +188780,9 @@ ${whenTrue}
188781
188780
  }
188782
188781
  const param = loop.param;
188783
188782
  const indexVar = loop.iterationShape === "keys" ? rubyLocal(param) : rubyLocal(loop.index ?? "_i");
188784
- const loopBound = loop.objectIteration === "entries" ? [param, loop.index ?? "_k"] : loop.objectIteration === "keys" || loop.objectIteration === "values" || loop.iterationShape === "keys" ? [param] : supportableDestructure ? ["__bf_item", ...(loop.paramBindings ?? []).map((b) => b.name), loop.index ?? "_i"] : [param, loop.index ?? "_i"];
188785
188783
  const preambleDecls = loop.preamble?.declarations ?? [];
188786
- for (const d of preambleDecls)
188787
- loopBound.push(d.name);
188788
- for (const n of loopBound) {
188789
- this.loopBoundNames.set(n, (this.loopBoundNames.get(n) ?? 0) + 1);
188790
- }
188784
+ const prevScope = this.scope;
188785
+ this.scope = prevScope.enterLoopRow(loop);
188791
188786
  const prevLoopKeyDepth = this.currentLoopKeyDepth;
188792
188787
  this.currentLoopKeyDepth = loop.depth;
188793
188788
  const renderedChildren = this.renderChildren(loop.children);
@@ -188797,13 +188792,7 @@ ${renderedChildren}` : renderedChildren;
188797
188792
  const lines = [];
188798
188793
  lines.push(`<%= bf.comment("loop:${loop.markerId}") %>`);
188799
188794
  if (sortedHoist && loop.sortComparator) {
188800
- for (const n of loopBound) {
188801
- const c = (this.loopBoundNames.get(n) ?? 1) - 1;
188802
- if (c <= 0)
188803
- this.loopBoundNames.delete(n);
188804
- else
188805
- this.loopBoundNames.set(n, c);
188806
- }
188795
+ this.scope = prevScope;
188807
188796
  const sortEmit = (e) => this.convertExpressionToRuby("", e);
188808
188797
  const sortArrow = loop.sortComparator.arrow;
188809
188798
  let sorted = null;
@@ -188819,9 +188808,7 @@ ${renderedChildren}` : renderedChildren;
188819
188808
  this._recordExprBF101(`.sort(...) loop comparator is not lowerable to a template sort`, `Pre-sort the array in the route handler, or mark the loop @client-only.`);
188820
188809
  sorted = rawArray;
188821
188810
  }
188822
- for (const n of loopBound) {
188823
- this.loopBoundNames.set(n, (this.loopBoundNames.get(n) ?? 0) + 1);
188824
- }
188811
+ this.scope = prevScope.enterLoopRow(loop);
188825
188812
  lines.push(`<%- ${sortedHoist} = ${sorted} -%>`);
188826
188813
  }
188827
188814
  if (loop.objectIteration) {
@@ -188867,13 +188854,7 @@ ${renderedChildren}` : renderedChildren;
188867
188854
  lines.push(...preambleLines);
188868
188855
  lines.push(children);
188869
188856
  }
188870
- for (const n of loopBound) {
188871
- const c = (this.loopBoundNames.get(n) ?? 1) - 1;
188872
- if (c <= 0)
188873
- this.loopBoundNames.delete(n);
188874
- else
188875
- this.loopBoundNames.set(n, c);
188876
- }
188857
+ this.scope = prevScope;
188877
188858
  lines.push(`<%- end -%>`);
188878
188859
  lines.push(`<%= bf.comment("/loop:${loop.markerId}") %>`);
188879
188860
  return lines.join(`
@@ -189035,7 +189016,7 @@ ${children}`;
189035
189016
  if (ternaryHash !== null) {
189036
189017
  return `<%= bf.spread_attrs(${ternaryHash}) %>`;
189037
189018
  }
189038
- if (/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(trimmed) && !this.loopBoundNames.has(trimmed)) {
189019
+ if (/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(trimmed) && !this.scope.isBound(trimmed)) {
189039
189020
  const localConst = this.localConstants.find((c) => c.name === trimmed && !c.isModule);
189040
189021
  if (localConst?.value !== undefined) {
189041
189022
  const initTrimmed = localConst.value.trim();