@barefootjs/mojolicious 0.17.1 → 0.18.0

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.
@@ -81,5 +81,7 @@ export declare function renderMapEval(recv: string, body: ParsedExpr, param: str
81
81
  * straightforward.
82
82
  */
83
83
  export declare function renderSortMethod(recv: string, c: SortComparator): string;
84
- export declare function renderFlatMethod(recv: string, depth: FlatDepth): string;
84
+ export declare function renderFlatMethod(recv: string, depth: FlatDepth | {
85
+ expr: ParsedExpr;
86
+ }, emit: (e: ParsedExpr) => string): string;
85
87
  //# sourceMappingURL=array-method.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"array-method.d.ts","sourceRoot":"","sources":["../../../src/adapter/expr/array-method.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,OAAO,KAAK,EACV,UAAU,EACV,WAAW,EACX,cAAc,EACd,SAAS,EACV,MAAM,iBAAiB,CAAA;AAExB;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,UAAU,EAAE,EAClB,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,CA6MR;AA6BD;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,MAAM,EAAE,EAChB,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,GAAG,IAAI,CAOf;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,MAAM,EAAE,EAChB,IAAI,EAAE,UAAU,EAChB,SAAS,EAAE,MAAM,GAAG,OAAO,EAC3B,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,GAAG,IAAI,CAmBf;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,UAAU,EACrB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,EAC/B,OAAO,CAAC,EAAE,OAAO,GAChB,MAAM,GAAG,IAAI,CAMf;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,GAAG,IAAI,CAKf;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,GAAG,IAAI,CAKf;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,cAAc,GAAG,MAAM,CAaxE;AAKD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,MAAM,CAGvE"}
1
+ {"version":3,"file":"array-method.d.ts","sourceRoot":"","sources":["../../../src/adapter/expr/array-method.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,OAAO,KAAK,EACV,UAAU,EACV,WAAW,EACX,cAAc,EACd,SAAS,EACV,MAAM,iBAAiB,CAAA;AAExB;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,UAAU,EAAE,EAClB,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,CA6MR;AA6BD;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,MAAM,EAAE,EAChB,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,GAAG,IAAI,CAOf;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,MAAM,EAAE,EAChB,IAAI,EAAE,UAAU,EAChB,SAAS,EAAE,MAAM,GAAG,OAAO,EAC3B,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,GAAG,IAAI,CAmBf;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,UAAU,EACrB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,EAC/B,OAAO,CAAC,EAAE,OAAO,GAChB,MAAM,GAAG,IAAI,CAMf;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,GAAG,IAAI,CAKf;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,GAAG,IAAI,CAKf;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,cAAc,GAAG,MAAM,CAaxE;AAKD,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,SAAS,GAAG;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,EACvC,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,CAoBR"}
@@ -31,7 +31,9 @@ export declare class MojoFilterEmitter implements ParsedExprEmitter {
31
31
  }>, _restArgs: ParsedExpr[], emit: (e: ParsedExpr) => string): string;
32
32
  arrayLiteral(elements: ParsedExpr[], emit: (e: ParsedExpr) => string): string;
33
33
  arrayMethod(method: ArrayMethod, object: ParsedExpr, args: ParsedExpr[], emit: (e: ParsedExpr) => string): string;
34
- flatMethod(object: ParsedExpr, depth: FlatDepth, emit: (e: ParsedExpr) => string): string;
34
+ flatMethod(object: ParsedExpr, depth: FlatDepth | {
35
+ expr: ParsedExpr;
36
+ }, emit: (e: ParsedExpr) => string): string;
35
37
  conditional(_test: ParsedExpr, _consequent: ParsedExpr, _alternate: ParsedExpr): string;
36
38
  templateLiteral(_parts: TemplatePart[]): string;
37
39
  arrow(_params: string[], _body: ParsedExpr, _emit: (e: ParsedExpr) => string): string;
@@ -67,12 +69,14 @@ export declare class MojoTopLevelEmitter implements ParsedExprEmitter {
67
69
  private renderPredicate;
68
70
  arrayLiteral(elements: ParsedExpr[], emit: (e: ParsedExpr) => string): string;
69
71
  arrayMethod(method: ArrayMethod, object: ParsedExpr, args: ParsedExpr[], emit: (e: ParsedExpr) => string): string;
70
- flatMethod(object: ParsedExpr, depth: FlatDepth, emit: (e: ParsedExpr) => string): string;
72
+ flatMethod(object: ParsedExpr, depth: FlatDepth | {
73
+ expr: ParsedExpr;
74
+ }, emit: (e: ParsedExpr) => string): string;
71
75
  conditional(test: ParsedExpr, consequent: ParsedExpr, alternate: ParsedExpr, emit: (e: ParsedExpr) => string): string;
72
76
  templateLiteral(parts: TemplatePart[], emit: (e: ParsedExpr) => string): string;
73
77
  arrow(_params: string[], _body: ParsedExpr, _emit: (e: ParsedExpr) => string): string;
74
78
  regex(_raw: string): string;
75
79
  unsupported(_raw: string, _reason: string): string;
76
- objectLiteral(_properties: ObjectLiteralProperty[], _raw: string, _emit: (e: ParsedExpr) => string): string;
80
+ objectLiteral(properties: ObjectLiteralProperty[], _raw: string, _emit: (e: ParsedExpr) => string): string;
77
81
  }
78
82
  //# sourceMappingURL=emitters.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"emitters.d.ts","sourceRoot":"","sources":["../../../src/adapter/expr/emitters.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"emitters.d.ts","sourceRoot":"","sources":["../../../src/adapter/expr/emitters.ts"],"names":[],"mappings":"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"}
@@ -12,13 +12,14 @@ import {
12
12
  emitIRNode,
13
13
  emitAttrValue,
14
14
  augmentInheritedPropAccesses,
15
- isLowerableObjectRestDestructure,
16
15
  collectModuleStringConsts,
17
16
  lookupStaticRecordLiteral,
18
17
  searchParamsLocalNames,
19
18
  prepareLoweringMatchers,
20
19
  queryHrefArgs,
21
- sortComparatorFromArrow as sortComparatorFromArrow2
20
+ isValidHelperId,
21
+ sortComparatorFromArrow as sortComparatorFromArrow2,
22
+ isLowerableLoopDestructure
22
23
  } from "@barefootjs/jsx";
23
24
 
24
25
  // src/adapter/boolean-result.ts
@@ -314,7 +315,10 @@ function renderSortMethod(recv, c) {
314
315
  });
315
316
  return `bf->sort(${recv}, { keys => [${keyHashes.join(", ")}] })`;
316
317
  }
317
- function renderFlatMethod(recv, depth) {
318
+ function renderFlatMethod(recv, depth, emit) {
319
+ if (typeof depth === "object") {
320
+ return `bf->flat_dynamic(${recv}, ${emit(depth.expr)})`;
321
+ }
318
322
  const d = depth === "infinity" ? -1 : depth;
319
323
  return `bf->flat(${recv}, ${d})`;
320
324
  }
@@ -469,7 +473,7 @@ class MojoFilterEmitter {
469
473
  return renderArrayMethod(method, object, args, emit);
470
474
  }
471
475
  flatMethod(object, depth, emit) {
472
- return renderFlatMethod(emit(object), depth);
476
+ return renderFlatMethod(emit(object), depth, emit);
473
477
  }
474
478
  conditional(_test, _consequent, _alternate) {
475
479
  return "1";
@@ -684,7 +688,7 @@ class MojoTopLevelEmitter {
684
688
  return renderArrayMethod(method, object, args, emit);
685
689
  }
686
690
  flatMethod(object, depth, emit) {
687
- return renderFlatMethod(emit(object), depth);
691
+ return renderFlatMethod(emit(object), depth, emit);
688
692
  }
689
693
  conditional(test, consequent, alternate, emit) {
690
694
  return `(${emit(test)} ? ${emit(consequent)} : ${emit(alternate)})`;
@@ -715,8 +719,8 @@ class MojoTopLevelEmitter {
715
719
  unsupported(_raw, _reason) {
716
720
  return "''";
717
721
  }
718
- objectLiteral(_properties, _raw, _emit) {
719
- return "''";
722
+ objectLiteral(properties, _raw, _emit) {
723
+ return properties.length === 0 ? "{}" : "''";
720
724
  }
721
725
  }
722
726
 
@@ -951,6 +955,17 @@ function collectStringValueNames(ir) {
951
955
  }
952
956
 
953
957
  // src/adapter/mojo-adapter.ts
958
+ function perlSegmentAccessor(base, segments) {
959
+ let expr = base;
960
+ for (const seg of segments) {
961
+ expr += seg.kind === "field" ? `->{${seg.isIdent ? seg.key : perlHashKey(seg.key)}}` : `->[${seg.index}]`;
962
+ }
963
+ return expr;
964
+ }
965
+ function perlStringLiteral(s) {
966
+ return `'${s.replace(/\\/g, "\\\\").replace(/'/g, "\\'")}'`;
967
+ }
968
+
954
969
  class MojoAdapter extends BaseAdapter {
955
970
  name = "mojolicious";
956
971
  extension = ".html.ep";
@@ -1283,21 +1298,37 @@ ${whenTrue}
1283
1298
  return `<%== bf->comment("loop:${loop.markerId}") %><%== bf->comment("/loop:${loop.markerId}") %>`;
1284
1299
  }
1285
1300
  const destructure = !!(loop.paramBindings && loop.paramBindings.length > 0);
1286
- const supportableDestructure = destructure && isLowerableObjectRestDestructure(loop);
1301
+ const supportableDestructure = destructure && isLowerableLoopDestructure(loop);
1287
1302
  if (destructure && !supportableDestructure) {
1288
1303
  this.errors.push({
1289
1304
  code: "BF104",
1290
1305
  severity: "error",
1291
- message: `Loop callback uses an array/object destructure pattern (\`${loop.param}\`) that the Mojo adapter cannot lower — Perl scalar bindings can't unpack a tuple in a single \`my\` declaration.`,
1306
+ message: `Loop callback uses a destructure pattern (\`${loop.param}\`) that the Mojo adapter cannot lower — see the diagnostic detail for the specific shape.`,
1292
1307
  loc: loop.loc ?? { file: this.componentName + ".tsx", start: { line: 1, column: 0 }, end: { line: 1, column: 0 } },
1293
1308
  suggestion: {
1294
1309
  message: `Options:
1295
- ` + ` 1. Rename the parameter to a single name and access tuple elements with index syntax in the body (e.g. \`entry => entry->[0]\` instead of \`([k, v]) => ...\`).
1296
- ` + ` 2. Mark the loop position as @client-only so the destructure runs in JS on the client.
1297
- ` + ` 3. Move the loop into a primitive that the adapter registers explicitly.`
1310
+ ` + ` 1. If this is an object-rest binding (\`{ ...rest }\`), only reading \`rest.field\` or spreading \`{...rest}\` onto an intrinsic element lowers — other uses (passing \`rest\` to a function, rendering it as text) need the client runtime.
1311
+ ` + ` 2. If this is chained \`.filter().map(({ ... }) => ...)\`, hoist the destructure into a variable inside the callback body instead.
1312
+ ` + ` 3. Mark the loop position as @client-only so the destructure runs in JS on the client.
1313
+ ` + ` 4. Move the loop into a primitive that the adapter registers explicitly.`
1298
1314
  }
1299
1315
  });
1300
1316
  }
1317
+ const arrayName = loop.array.trim();
1318
+ if (/^[A-Za-z_$][\w$]*$/.test(arrayName)) {
1319
+ const arrayConst = (this.localConstants ?? []).find((c) => c.name === arrayName);
1320
+ if (arrayConst && !arrayConst.isModule && this.resolveLiteralConst(arrayName) === null) {
1321
+ this.errors.push({
1322
+ code: "BF101",
1323
+ severity: "error",
1324
+ message: `Loop array \`${arrayName}\` is a local computed value (\`${arrayConst.value}\`) that the Mojo adapter cannot bind as a template variable — only numeric/string-literal locals inline at their use site.`,
1325
+ loc: loop.loc ?? { file: this.componentName + ".tsx", start: { line: 1, column: 0 }, end: { line: 1, column: 0 } },
1326
+ suggestion: {
1327
+ 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."
1328
+ }
1329
+ });
1330
+ }
1331
+ }
1301
1332
  const rawArray = this.convertExpressionToPerl(loop.array);
1302
1333
  let sortedHoist = null;
1303
1334
  let array = rawArray;
@@ -1352,7 +1383,15 @@ ${renderedChildren}` : renderedChildren;
1352
1383
  if (supportableDestructure) {
1353
1384
  lines.push(`% my $__bf_item = ${array}->[${indexVar}];`);
1354
1385
  for (const b of loop.paramBindings ?? []) {
1355
- lines.push(b.rest ? `% my $${b.name} = $__bf_item;` : `% my $${b.name} = $__bf_item->{${b.path.slice(1)}};`);
1386
+ const parent = perlSegmentAccessor("$__bf_item", b.segments ?? []);
1387
+ if (b.rest?.kind === "object") {
1388
+ const exclude = b.rest.exclude.map((k) => perlStringLiteral(k.key)).join(", ");
1389
+ lines.push(`% my $${b.name} = bf->omit(${parent}, [${exclude}]);`);
1390
+ } else if (b.rest?.kind === "array") {
1391
+ lines.push(`% my $${b.name} = bf->slice(${parent}, ${b.rest.from}, undef);`);
1392
+ } else {
1393
+ lines.push(`% my $${b.name} = ${perlSegmentAccessor("$__bf_item", b.segments ?? [])};`);
1394
+ }
1356
1395
  }
1357
1396
  } else {
1358
1397
  lines.push(`% my $${param} = ${array}->[${indexVar}];`);
@@ -1693,6 +1732,10 @@ ${reason}` : "";
1693
1732
  const argsGo = queryHrefArgs(node, (n) => this.renderParsedExprToPerl(n));
1694
1733
  return `bf->query(${argsGo.join(", ")})`;
1695
1734
  }
1735
+ if (node?.kind === "helper-call" && isValidHelperId(node.helper)) {
1736
+ const argsX = node.args.map((a) => this.renderParsedExprToPerl(a));
1737
+ return `bf->${node.helper}(${argsX.join(", ")})`;
1738
+ }
1696
1739
  }
1697
1740
  }
1698
1741
  const support = isSupported(parsed);
@@ -1 +1 @@
1
- {"version":3,"file":"mojo-adapter.d.ts","sourceRoot":"","sources":["../../src/adapter/mojo-adapter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mojo-adapter.d.ts","sourceRoot":"","sources":["../../src/adapter/mojo-adapter.ts"],"names":[],"mappings":"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"}
package/dist/build.js CHANGED
@@ -12,13 +12,14 @@ import {
12
12
  emitIRNode,
13
13
  emitAttrValue,
14
14
  augmentInheritedPropAccesses,
15
- isLowerableObjectRestDestructure,
16
15
  collectModuleStringConsts,
17
16
  lookupStaticRecordLiteral,
18
17
  searchParamsLocalNames,
19
18
  prepareLoweringMatchers,
20
19
  queryHrefArgs,
21
- sortComparatorFromArrow as sortComparatorFromArrow2
20
+ isValidHelperId,
21
+ sortComparatorFromArrow as sortComparatorFromArrow2,
22
+ isLowerableLoopDestructure
22
23
  } from "@barefootjs/jsx";
23
24
 
24
25
  // src/adapter/boolean-result.ts
@@ -314,7 +315,10 @@ function renderSortMethod(recv, c) {
314
315
  });
315
316
  return `bf->sort(${recv}, { keys => [${keyHashes.join(", ")}] })`;
316
317
  }
317
- function renderFlatMethod(recv, depth) {
318
+ function renderFlatMethod(recv, depth, emit) {
319
+ if (typeof depth === "object") {
320
+ return `bf->flat_dynamic(${recv}, ${emit(depth.expr)})`;
321
+ }
318
322
  const d = depth === "infinity" ? -1 : depth;
319
323
  return `bf->flat(${recv}, ${d})`;
320
324
  }
@@ -469,7 +473,7 @@ class MojoFilterEmitter {
469
473
  return renderArrayMethod(method, object, args, emit);
470
474
  }
471
475
  flatMethod(object, depth, emit) {
472
- return renderFlatMethod(emit(object), depth);
476
+ return renderFlatMethod(emit(object), depth, emit);
473
477
  }
474
478
  conditional(_test, _consequent, _alternate) {
475
479
  return "1";
@@ -684,7 +688,7 @@ class MojoTopLevelEmitter {
684
688
  return renderArrayMethod(method, object, args, emit);
685
689
  }
686
690
  flatMethod(object, depth, emit) {
687
- return renderFlatMethod(emit(object), depth);
691
+ return renderFlatMethod(emit(object), depth, emit);
688
692
  }
689
693
  conditional(test, consequent, alternate, emit) {
690
694
  return `(${emit(test)} ? ${emit(consequent)} : ${emit(alternate)})`;
@@ -715,8 +719,8 @@ class MojoTopLevelEmitter {
715
719
  unsupported(_raw, _reason) {
716
720
  return "''";
717
721
  }
718
- objectLiteral(_properties, _raw, _emit) {
719
- return "''";
722
+ objectLiteral(properties, _raw, _emit) {
723
+ return properties.length === 0 ? "{}" : "''";
720
724
  }
721
725
  }
722
726
 
@@ -951,6 +955,17 @@ function collectStringValueNames(ir) {
951
955
  }
952
956
 
953
957
  // src/adapter/mojo-adapter.ts
958
+ function perlSegmentAccessor(base, segments) {
959
+ let expr = base;
960
+ for (const seg of segments) {
961
+ expr += seg.kind === "field" ? `->{${seg.isIdent ? seg.key : perlHashKey(seg.key)}}` : `->[${seg.index}]`;
962
+ }
963
+ return expr;
964
+ }
965
+ function perlStringLiteral(s) {
966
+ return `'${s.replace(/\\/g, "\\\\").replace(/'/g, "\\'")}'`;
967
+ }
968
+
954
969
  class MojoAdapter extends BaseAdapter {
955
970
  name = "mojolicious";
956
971
  extension = ".html.ep";
@@ -1283,21 +1298,37 @@ ${whenTrue}
1283
1298
  return `<%== bf->comment("loop:${loop.markerId}") %><%== bf->comment("/loop:${loop.markerId}") %>`;
1284
1299
  }
1285
1300
  const destructure = !!(loop.paramBindings && loop.paramBindings.length > 0);
1286
- const supportableDestructure = destructure && isLowerableObjectRestDestructure(loop);
1301
+ const supportableDestructure = destructure && isLowerableLoopDestructure(loop);
1287
1302
  if (destructure && !supportableDestructure) {
1288
1303
  this.errors.push({
1289
1304
  code: "BF104",
1290
1305
  severity: "error",
1291
- message: `Loop callback uses an array/object destructure pattern (\`${loop.param}\`) that the Mojo adapter cannot lower — Perl scalar bindings can't unpack a tuple in a single \`my\` declaration.`,
1306
+ message: `Loop callback uses a destructure pattern (\`${loop.param}\`) that the Mojo adapter cannot lower — see the diagnostic detail for the specific shape.`,
1292
1307
  loc: loop.loc ?? { file: this.componentName + ".tsx", start: { line: 1, column: 0 }, end: { line: 1, column: 0 } },
1293
1308
  suggestion: {
1294
1309
  message: `Options:
1295
- ` + ` 1. Rename the parameter to a single name and access tuple elements with index syntax in the body (e.g. \`entry => entry->[0]\` instead of \`([k, v]) => ...\`).
1296
- ` + ` 2. Mark the loop position as @client-only so the destructure runs in JS on the client.
1297
- ` + ` 3. Move the loop into a primitive that the adapter registers explicitly.`
1310
+ ` + ` 1. If this is an object-rest binding (\`{ ...rest }\`), only reading \`rest.field\` or spreading \`{...rest}\` onto an intrinsic element lowers — other uses (passing \`rest\` to a function, rendering it as text) need the client runtime.
1311
+ ` + ` 2. If this is chained \`.filter().map(({ ... }) => ...)\`, hoist the destructure into a variable inside the callback body instead.
1312
+ ` + ` 3. Mark the loop position as @client-only so the destructure runs in JS on the client.
1313
+ ` + ` 4. Move the loop into a primitive that the adapter registers explicitly.`
1298
1314
  }
1299
1315
  });
1300
1316
  }
1317
+ const arrayName = loop.array.trim();
1318
+ if (/^[A-Za-z_$][\w$]*$/.test(arrayName)) {
1319
+ const arrayConst = (this.localConstants ?? []).find((c) => c.name === arrayName);
1320
+ if (arrayConst && !arrayConst.isModule && this.resolveLiteralConst(arrayName) === null) {
1321
+ this.errors.push({
1322
+ code: "BF101",
1323
+ severity: "error",
1324
+ message: `Loop array \`${arrayName}\` is a local computed value (\`${arrayConst.value}\`) that the Mojo adapter cannot bind as a template variable — only numeric/string-literal locals inline at their use site.`,
1325
+ loc: loop.loc ?? { file: this.componentName + ".tsx", start: { line: 1, column: 0 }, end: { line: 1, column: 0 } },
1326
+ suggestion: {
1327
+ 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."
1328
+ }
1329
+ });
1330
+ }
1331
+ }
1301
1332
  const rawArray = this.convertExpressionToPerl(loop.array);
1302
1333
  let sortedHoist = null;
1303
1334
  let array = rawArray;
@@ -1352,7 +1383,15 @@ ${renderedChildren}` : renderedChildren;
1352
1383
  if (supportableDestructure) {
1353
1384
  lines.push(`% my $__bf_item = ${array}->[${indexVar}];`);
1354
1385
  for (const b of loop.paramBindings ?? []) {
1355
- lines.push(b.rest ? `% my $${b.name} = $__bf_item;` : `% my $${b.name} = $__bf_item->{${b.path.slice(1)}};`);
1386
+ const parent = perlSegmentAccessor("$__bf_item", b.segments ?? []);
1387
+ if (b.rest?.kind === "object") {
1388
+ const exclude = b.rest.exclude.map((k) => perlStringLiteral(k.key)).join(", ");
1389
+ lines.push(`% my $${b.name} = bf->omit(${parent}, [${exclude}]);`);
1390
+ } else if (b.rest?.kind === "array") {
1391
+ lines.push(`% my $${b.name} = bf->slice(${parent}, ${b.rest.from}, undef);`);
1392
+ } else {
1393
+ lines.push(`% my $${b.name} = ${perlSegmentAccessor("$__bf_item", b.segments ?? [])};`);
1394
+ }
1356
1395
  }
1357
1396
  } else {
1358
1397
  lines.push(`% my $${param} = ${array}->[${indexVar}];`);
@@ -1693,6 +1732,10 @@ ${reason}` : "";
1693
1732
  const argsGo = queryHrefArgs(node, (n) => this.renderParsedExprToPerl(n));
1694
1733
  return `bf->query(${argsGo.join(", ")})`;
1695
1734
  }
1735
+ if (node?.kind === "helper-call" && isValidHelperId(node.helper)) {
1736
+ const argsX = node.args.map((a) => this.renderParsedExprToPerl(a));
1737
+ return `bf->${node.helper}(${argsX.join(", ")})`;
1738
+ }
1696
1739
  }
1697
1740
  }
1698
1741
  const support = isSupported(parsed);
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Per-fixture build-time contracts for shapes the Mojo adapter
3
+ * intentionally refuses to lower. Owned by this module (not by the
4
+ * shared fixtures) so adding a new adapter doesn't require touching any
5
+ * cross-adapter file. Consumed by this package's own conformance test
6
+ * (as `expectedDiagnostics`) and by `bf compat` (issue-URL attribution).
7
+ */
8
+ import type { ConformancePins } from '@barefootjs/jsx';
9
+ export declare const conformancePins: ConformancePins;
10
+ //# sourceMappingURL=conformance-pins.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conformance-pins.d.ts","sourceRoot":"","sources":["../src/conformance-pins.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEtD,eAAO,MAAM,eAAe,EAAE,eA+H7B,CAAA"}
package/dist/index.d.ts CHANGED
@@ -5,4 +5,5 @@
5
5
  */
6
6
  export { MojoAdapter, mojoAdapter } from './adapter/index.ts';
7
7
  export type { MojoAdapterOptions } from './adapter/index.ts';
8
+ export { conformancePins } from './conformance-pins.ts';
8
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAC7D,YAAY,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAC7D,YAAY,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA"}
package/dist/index.js CHANGED
@@ -12,13 +12,14 @@ import {
12
12
  emitIRNode,
13
13
  emitAttrValue,
14
14
  augmentInheritedPropAccesses,
15
- isLowerableObjectRestDestructure,
16
15
  collectModuleStringConsts,
17
16
  lookupStaticRecordLiteral,
18
17
  searchParamsLocalNames,
19
18
  prepareLoweringMatchers,
20
19
  queryHrefArgs,
21
- sortComparatorFromArrow as sortComparatorFromArrow2
20
+ isValidHelperId,
21
+ sortComparatorFromArrow as sortComparatorFromArrow2,
22
+ isLowerableLoopDestructure
22
23
  } from "@barefootjs/jsx";
23
24
 
24
25
  // src/adapter/boolean-result.ts
@@ -314,7 +315,10 @@ function renderSortMethod(recv, c) {
314
315
  });
315
316
  return `bf->sort(${recv}, { keys => [${keyHashes.join(", ")}] })`;
316
317
  }
317
- function renderFlatMethod(recv, depth) {
318
+ function renderFlatMethod(recv, depth, emit) {
319
+ if (typeof depth === "object") {
320
+ return `bf->flat_dynamic(${recv}, ${emit(depth.expr)})`;
321
+ }
318
322
  const d = depth === "infinity" ? -1 : depth;
319
323
  return `bf->flat(${recv}, ${d})`;
320
324
  }
@@ -469,7 +473,7 @@ class MojoFilterEmitter {
469
473
  return renderArrayMethod(method, object, args, emit);
470
474
  }
471
475
  flatMethod(object, depth, emit) {
472
- return renderFlatMethod(emit(object), depth);
476
+ return renderFlatMethod(emit(object), depth, emit);
473
477
  }
474
478
  conditional(_test, _consequent, _alternate) {
475
479
  return "1";
@@ -684,7 +688,7 @@ class MojoTopLevelEmitter {
684
688
  return renderArrayMethod(method, object, args, emit);
685
689
  }
686
690
  flatMethod(object, depth, emit) {
687
- return renderFlatMethod(emit(object), depth);
691
+ return renderFlatMethod(emit(object), depth, emit);
688
692
  }
689
693
  conditional(test, consequent, alternate, emit) {
690
694
  return `(${emit(test)} ? ${emit(consequent)} : ${emit(alternate)})`;
@@ -715,8 +719,8 @@ class MojoTopLevelEmitter {
715
719
  unsupported(_raw, _reason) {
716
720
  return "''";
717
721
  }
718
- objectLiteral(_properties, _raw, _emit) {
719
- return "''";
722
+ objectLiteral(properties, _raw, _emit) {
723
+ return properties.length === 0 ? "{}" : "''";
720
724
  }
721
725
  }
722
726
 
@@ -951,6 +955,17 @@ function collectStringValueNames(ir) {
951
955
  }
952
956
 
953
957
  // src/adapter/mojo-adapter.ts
958
+ function perlSegmentAccessor(base, segments) {
959
+ let expr = base;
960
+ for (const seg of segments) {
961
+ expr += seg.kind === "field" ? `->{${seg.isIdent ? seg.key : perlHashKey(seg.key)}}` : `->[${seg.index}]`;
962
+ }
963
+ return expr;
964
+ }
965
+ function perlStringLiteral(s) {
966
+ return `'${s.replace(/\\/g, "\\\\").replace(/'/g, "\\'")}'`;
967
+ }
968
+
954
969
  class MojoAdapter extends BaseAdapter {
955
970
  name = "mojolicious";
956
971
  extension = ".html.ep";
@@ -1283,21 +1298,37 @@ ${whenTrue}
1283
1298
  return `<%== bf->comment("loop:${loop.markerId}") %><%== bf->comment("/loop:${loop.markerId}") %>`;
1284
1299
  }
1285
1300
  const destructure = !!(loop.paramBindings && loop.paramBindings.length > 0);
1286
- const supportableDestructure = destructure && isLowerableObjectRestDestructure(loop);
1301
+ const supportableDestructure = destructure && isLowerableLoopDestructure(loop);
1287
1302
  if (destructure && !supportableDestructure) {
1288
1303
  this.errors.push({
1289
1304
  code: "BF104",
1290
1305
  severity: "error",
1291
- message: `Loop callback uses an array/object destructure pattern (\`${loop.param}\`) that the Mojo adapter cannot lower — Perl scalar bindings can't unpack a tuple in a single \`my\` declaration.`,
1306
+ message: `Loop callback uses a destructure pattern (\`${loop.param}\`) that the Mojo adapter cannot lower — see the diagnostic detail for the specific shape.`,
1292
1307
  loc: loop.loc ?? { file: this.componentName + ".tsx", start: { line: 1, column: 0 }, end: { line: 1, column: 0 } },
1293
1308
  suggestion: {
1294
1309
  message: `Options:
1295
- ` + ` 1. Rename the parameter to a single name and access tuple elements with index syntax in the body (e.g. \`entry => entry->[0]\` instead of \`([k, v]) => ...\`).
1296
- ` + ` 2. Mark the loop position as @client-only so the destructure runs in JS on the client.
1297
- ` + ` 3. Move the loop into a primitive that the adapter registers explicitly.`
1310
+ ` + ` 1. If this is an object-rest binding (\`{ ...rest }\`), only reading \`rest.field\` or spreading \`{...rest}\` onto an intrinsic element lowers — other uses (passing \`rest\` to a function, rendering it as text) need the client runtime.
1311
+ ` + ` 2. If this is chained \`.filter().map(({ ... }) => ...)\`, hoist the destructure into a variable inside the callback body instead.
1312
+ ` + ` 3. Mark the loop position as @client-only so the destructure runs in JS on the client.
1313
+ ` + ` 4. Move the loop into a primitive that the adapter registers explicitly.`
1298
1314
  }
1299
1315
  });
1300
1316
  }
1317
+ const arrayName = loop.array.trim();
1318
+ if (/^[A-Za-z_$][\w$]*$/.test(arrayName)) {
1319
+ const arrayConst = (this.localConstants ?? []).find((c) => c.name === arrayName);
1320
+ if (arrayConst && !arrayConst.isModule && this.resolveLiteralConst(arrayName) === null) {
1321
+ this.errors.push({
1322
+ code: "BF101",
1323
+ severity: "error",
1324
+ message: `Loop array \`${arrayName}\` is a local computed value (\`${arrayConst.value}\`) that the Mojo adapter cannot bind as a template variable — only numeric/string-literal locals inline at their use site.`,
1325
+ loc: loop.loc ?? { file: this.componentName + ".tsx", start: { line: 1, column: 0 }, end: { line: 1, column: 0 } },
1326
+ suggestion: {
1327
+ 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."
1328
+ }
1329
+ });
1330
+ }
1331
+ }
1301
1332
  const rawArray = this.convertExpressionToPerl(loop.array);
1302
1333
  let sortedHoist = null;
1303
1334
  let array = rawArray;
@@ -1352,7 +1383,15 @@ ${renderedChildren}` : renderedChildren;
1352
1383
  if (supportableDestructure) {
1353
1384
  lines.push(`% my $__bf_item = ${array}->[${indexVar}];`);
1354
1385
  for (const b of loop.paramBindings ?? []) {
1355
- lines.push(b.rest ? `% my $${b.name} = $__bf_item;` : `% my $${b.name} = $__bf_item->{${b.path.slice(1)}};`);
1386
+ const parent = perlSegmentAccessor("$__bf_item", b.segments ?? []);
1387
+ if (b.rest?.kind === "object") {
1388
+ const exclude = b.rest.exclude.map((k) => perlStringLiteral(k.key)).join(", ");
1389
+ lines.push(`% my $${b.name} = bf->omit(${parent}, [${exclude}]);`);
1390
+ } else if (b.rest?.kind === "array") {
1391
+ lines.push(`% my $${b.name} = bf->slice(${parent}, ${b.rest.from}, undef);`);
1392
+ } else {
1393
+ lines.push(`% my $${b.name} = ${perlSegmentAccessor("$__bf_item", b.segments ?? [])};`);
1394
+ }
1356
1395
  }
1357
1396
  } else {
1358
1397
  lines.push(`% my $${param} = ${array}->[${indexVar}];`);
@@ -1693,6 +1732,10 @@ ${reason}` : "";
1693
1732
  const argsGo = queryHrefArgs(node, (n) => this.renderParsedExprToPerl(n));
1694
1733
  return `bf->query(${argsGo.join(", ")})`;
1695
1734
  }
1735
+ if (node?.kind === "helper-call" && isValidHelperId(node.helper)) {
1736
+ const argsX = node.args.map((a) => this.renderParsedExprToPerl(a));
1737
+ return `bf->${node.helper}(${argsX.join(", ")})`;
1738
+ }
1696
1739
  }
1697
1740
  }
1698
1741
  const support = isSupported(parsed);
@@ -1744,7 +1787,23 @@ Options:
1744
1787
  }
1745
1788
  }
1746
1789
  var mojoAdapter = new MojoAdapter;
1790
+ // src/conformance-pins.ts
1791
+ var conformancePins = {
1792
+ "static-array-children": [{ code: "BF103", severity: "error" }],
1793
+ "todo-app": [{ code: "BF103", severity: "error" }],
1794
+ "todo-app-ssr": [{ code: "BF103", severity: "error" }],
1795
+ "static-array-from-props": [{ code: "BF101", severity: "error" }],
1796
+ "static-array-from-props-with-component": [
1797
+ { code: "BF103", severity: "error" },
1798
+ { code: "BF101", severity: "error" }
1799
+ ],
1800
+ "filter-nested-find-predicate": [
1801
+ { code: "BF101", severity: "error", issue: "https://github.com/piconic-ai/barefootjs/issues/2038" }
1802
+ ],
1803
+ "array-map-function-reference": [{ code: "BF101", severity: "error" }]
1804
+ };
1747
1805
  export {
1748
1806
  mojoAdapter,
1807
+ conformancePins,
1749
1808
  MojoAdapter
1750
1809
  };
@@ -1 +1 @@
1
- {"version":3,"file":"test-render.d.ts","sourceRoot":"","sources":["../src/test-render.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAeH,qBAAa,qBAAsB,SAAQ,KAAK;IAC9C,YAAY,OAAO,EAAE,MAAM,EAG1B;CACF;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAKxE;AAkCD,MAAM,WAAW,aAAa;IAC5B,sBAAsB;IACtB,MAAM,EAAE,MAAM,CAAA;IACd,8BAA8B;IAC9B,OAAO,EAAE,OAAO,iBAAiB,EAAE,eAAe,CAAA;IAClD,iCAAiC;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC/B,qDAAqD;IACrD,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACnC;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAgNjF;AAqWD;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,OAAO,CAuBT"}
1
+ {"version":3,"file":"test-render.d.ts","sourceRoot":"","sources":["../src/test-render.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAeH,qBAAa,qBAAsB,SAAQ,KAAK;IAC9C,YAAY,OAAO,EAAE,MAAM,EAG1B;CACF;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAKxE;AAkCD,MAAM,WAAW,aAAa;IAC5B,sBAAsB;IACtB,MAAM,EAAE,MAAM,CAAA;IACd,8BAA8B;IAC9B,OAAO,EAAE,OAAO,iBAAiB,EAAE,eAAe,CAAA;IAClD,iCAAiC;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC/B,qDAAqD;IACrD,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACnC;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAwNjF;AAqWD;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,OAAO,CAuBT"}
@@ -1,5 +1,5 @@
1
1
  package BarefootJS::Backend::Mojo;
2
- our $VERSION = "0.17.0";
2
+ our $VERSION = "0.17.1";
3
3
  use Mojo::Base -base, -signatures;
4
4
 
5
5
  use Mojo::ByteStream qw(b);
@@ -78,13 +78,22 @@ sub materialize ($self, $value) {
78
78
  # instance for that render. The Mojo `bf` helper resolves the current
79
79
  # instance off `$c->stash->{'bf.instance'}`; swap it for the duration of
80
80
  # the nested render and restore it afterwards so sibling renders are
81
- # unaffected.
81
+ # unaffected. `local` (rather than a manual swap) keeps the restore
82
+ # exception-safe: a die inside the nested render — e.g. a grandchild with
83
+ # no registered renderer — propagates without leaving the child instance
84
+ # bound as the request's active one.
82
85
  sub render_named ($self, $template_name, $child_bf, $vars) {
83
86
  my $c = $self->c;
84
- my $prev = $c->stash->{'bf.instance'};
85
- $c->stash->{'bf.instance'} = $child_bf;
87
+ local $c->stash->{'bf.instance'} = $child_bf;
86
88
  my $html = $c->render_to_string(template => $template_name, %$vars);
87
- $c->stash->{'bf.instance'} = $prev;
89
+ # `render_to_string` returns undef — it does NOT die — when the named
90
+ # template can't be rendered (typically: the template file is missing
91
+ # from the renderer paths). The calling template's `<%==` would emit
92
+ # that as an empty string, silently dropping the whole child subtree
93
+ # from the page (#2132). Fail the render loudly instead.
94
+ die qq{BarefootJS: child template "$template_name" rendered no output }
95
+ . qq{(is the template missing from the renderer paths?)\n}
96
+ unless defined $html;
88
97
  return $html;
89
98
  }
90
99
 
@@ -1,5 +1,5 @@
1
1
  package Mojolicious::Plugin::BarefootJS::DevReload;
2
- our $VERSION = "0.17.0";
2
+ our $VERSION = "0.17.1";
3
3
  use Mojo::Base 'Mojolicious::Plugin', -signatures;
4
4
 
5
5
  =head1 NAME