@barefootjs/mojolicious 0.19.1 → 0.20.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.
@@ -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,CAgOR;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"}
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,CAsOR;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"}
@@ -149,7 +149,7 @@ function renderArrayMethod(method, object, args, emit) {
149
149
  case "join": {
150
150
  const obj = emit(object);
151
151
  const sep = args.length >= 1 ? emit(args[0]) : `','`;
152
- return `join(${sep}, @{${obj}})`;
152
+ return `bf->join(${obj}, ${sep})`;
153
153
  }
154
154
  case "includes": {
155
155
  const obj = emit(object);
package/dist/build.js CHANGED
@@ -149,7 +149,7 @@ function renderArrayMethod(method, object, args, emit) {
149
149
  case "join": {
150
150
  const obj = emit(object);
151
151
  const sep = args.length >= 1 ? emit(args[0]) : `','`;
152
- return `join(${sep}, @{${obj}})`;
152
+ return `bf->join(${obj}, ${sep})`;
153
153
  }
154
154
  case "includes": {
155
155
  const obj = emit(object);
@@ -1 +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,eAmI7B,CAAA"}
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,eAyI7B,CAAA"}
package/dist/index.js CHANGED
@@ -149,7 +149,7 @@ function renderArrayMethod(method, object, args, emit) {
149
149
  case "join": {
150
150
  const obj = emit(object);
151
151
  const sep = args.length >= 1 ? emit(args[0]) : `','`;
152
- return `join(${sep}, @{${obj}})`;
152
+ return `bf->join(${obj}, ${sep})`;
153
153
  }
154
154
  case "includes": {
155
155
  const obj = emit(object);
@@ -1912,7 +1912,8 @@ var conformancePins = {
1912
1912
  "filter-nested-find-predicate": [
1913
1913
  { code: "BF101", severity: "error", issue: "https://github.com/piconic-ai/barefootjs/issues/2038" }
1914
1914
  ],
1915
- "dangerous-inner-html-dynamic": [{ code: "BF101", severity: "error", issue: "https://github.com/piconic-ai/barefootjs/issues/2215" }]
1915
+ "dangerous-inner-html-dynamic": [{ code: "BF101", severity: "error", issue: "https://github.com/piconic-ai/barefootjs/issues/2215" }],
1916
+ "date-method-uncatalogued": [{ code: "BF021", severity: "error", issue: "https://github.com/piconic-ai/barefootjs/issues/2274" }]
1916
1917
  };
1917
1918
  // src/render-divergences.ts
1918
1919
  var renderDivergences = {};
@@ -1,5 +1,5 @@
1
1
  package BarefootJS::Backend::Mojo;
2
- our $VERSION = "0.19.0";
2
+ our $VERSION = "0.19.1";
3
3
  use Mojo::Base -base, -signatures;
4
4
 
5
5
  use Mojo::ByteStream qw(b);
@@ -1,5 +1,5 @@
1
1
  package Mojolicious::Plugin::BarefootJS::DevReload;
2
- our $VERSION = "0.19.0";
2
+ our $VERSION = "0.19.1";
3
3
  use Mojo::Base 'Mojolicious::Plugin', -signatures;
4
4
 
5
5
  =head1 NAME
@@ -1,5 +1,5 @@
1
1
  package Mojolicious::Plugin::BarefootJS;
2
- our $VERSION = "0.19.0";
2
+ our $VERSION = "0.19.1";
3
3
  use Mojo::Base 'Mojolicious::Plugin', -signatures;
4
4
 
5
5
  use Mojo::File qw(path);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@barefootjs/mojolicious",
3
- "version": "0.19.1",
3
+ "version": "0.20.0",
4
4
  "description": "Mojolicious EP template adapter for BarefootJS - generates .html.ep files from IR",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -52,7 +52,7 @@
52
52
  "directory": "packages/adapter-mojolicious"
53
53
  },
54
54
  "dependencies": {
55
- "@barefootjs/shared": "0.19.1"
55
+ "@barefootjs/shared": "0.20.0"
56
56
  },
57
57
  "peerDependencies": {
58
58
  "@barefootjs/jsx": ">=0.2.0",
@@ -60,6 +60,6 @@
60
60
  },
61
61
  "devDependencies": {
62
62
  "@barefootjs/adapter-tests": "0.1.0",
63
- "@barefootjs/jsx": "0.19.1"
63
+ "@barefootjs/jsx": "0.20.0"
64
64
  }
65
65
  }
@@ -59,17 +59,7 @@ runAdapterConformanceTests({
59
59
  // #1467 Phase 2e: same `/* @client */` keyed-map elision (data-table).
60
60
  'data-table',
61
61
  ]),
62
- skipDataPoints: new Set<string>([
63
- // #2260 — controlled boolean props: the SSR seed evaluates only the
64
- // static fallback of `props.X ?? internal()` chains.
65
- 'toggle:gen:pressed:true',
66
- 'switch:gen:checked:true',
67
- 'checkbox:gen:checked:true',
68
- // #2262 — dynamic `.flat` depth 0/negative violates the documented
69
- // shallow-copy contract.
70
- 'array-flat-dynamic-depth:gen:depth:zero',
71
- 'array-flat-dynamic-depth:gen:depth:negative',
72
- ]),
62
+ skipDataPoints: new Set<string>(),
73
63
  onRenderError: (err, id) => {
74
64
  if (err instanceof PerlNotAvailableError) {
75
65
  console.log(`Skipping [${id}]: ${err.message}`)
@@ -915,7 +905,7 @@ export function C() {
915
905
  // filter, `.join`) hit a separate refusal gate and the chain
916
906
  // emitted BF101 — making the scaffold `<Button>` / `<Card>`
917
907
  // unusable on Mojo. The fix lowers all three to Embedded Perl
918
- // (`join(' ', @{[grep { $_ } @{[...]}]})`), unblocking the
908
+ // (`bf->join([grep { $_ } @{[...]}], ' ')`), unblocking the
919
909
  // registry surface. The #1421 recursion guard stays in place
920
910
  // as defence in depth for other unsupported shapes, but this
921
911
  // specific chain no longer reaches the loop because the parser
@@ -938,7 +928,7 @@ export { Slot }
938
928
  )
939
929
  expect(result.errors?.filter(e => e.code === 'BF101') ?? []).toEqual([])
940
930
  const template = result.files.find(f => f.path.endsWith('.html.ep'))?.content ?? ''
941
- expect(template).toContain(`join(' ', @{[grep { $_ } @{[$className]}]})`)
931
+ expect(template).toContain(`bf->join([grep { $_ } @{[$className]}], ' ')`)
942
932
  })
943
933
 
944
934
  test('lowers .includes(x) on an array prop via bf->includes(...) (#1448 Tier A)', () => {
@@ -1168,7 +1158,7 @@ export { A }`, 'A.tsx', { adapter })
1168
1158
  export { A }`, 'A.tsx', { adapter })
1169
1159
  expect(result.errors?.filter(e => e.code === 'BF101') ?? []).toEqual([])
1170
1160
  const template = result.files.find(f => f.path.endsWith('.html.ep'))?.content ?? ''
1171
- expect(template).toContain("join(' ', @{bf->reverse($items)})")
1161
+ expect(template).toContain("bf->join(bf->reverse($items), ' ')")
1172
1162
  expect(template).not.toContain('$bf->reverse')
1173
1163
  })
1174
1164
 
@@ -1180,7 +1170,7 @@ export { A }`, 'A.tsx', { adapter })
1180
1170
  export { A }`, 'A.tsx', { adapter })
1181
1171
  expect(result.errors?.filter(e => e.code === 'BF101') ?? []).toEqual([])
1182
1172
  const template = result.files.find(f => f.path.endsWith('.html.ep'))?.content ?? ''
1183
- expect(template).toContain("join(' ', @{bf->reverse($items)})")
1173
+ expect(template).toContain("bf->join(bf->reverse($items), ' ')")
1184
1174
  })
1185
1175
 
1186
1176
  test('lowers .slice(start, end).join(\' \') via bf->slice + join (#1448 Tier A)', () => {
@@ -1192,7 +1182,7 @@ export { A }`, 'A.tsx', { adapter })
1192
1182
  export { A }`, 'A.tsx', { adapter })
1193
1183
  expect(result.errors?.filter(e => e.code === 'BF101') ?? []).toEqual([])
1194
1184
  const template = result.files.find(f => f.path.endsWith('.html.ep'))?.content ?? ''
1195
- expect(template).toContain("join(' ', @{bf->slice($items, 1, 3)})")
1185
+ expect(template).toContain("bf->join(bf->slice($items, 1, 3), ' ')")
1196
1186
  expect(template).not.toContain('$bf->slice')
1197
1187
  })
1198
1188
 
@@ -1206,7 +1196,7 @@ export { A }`, 'A.tsx', { adapter })
1206
1196
  export { A }`, 'A.tsx', { adapter })
1207
1197
  expect(result.errors?.filter(e => e.code === 'BF101') ?? []).toEqual([])
1208
1198
  const template = result.files.find(f => f.path.endsWith('.html.ep'))?.content ?? ''
1209
- expect(template).toContain("join(' ', @{bf->slice($items, 2, undef)})")
1199
+ expect(template).toContain("bf->join(bf->slice($items, 2, undef), ' ')")
1210
1200
  })
1211
1201
 
1212
1202
  test('lowers .concat(other).join(\' \') via bf->concat + join (#1448 Tier A)', () => {
@@ -1222,7 +1212,7 @@ export { A }`, 'A.tsx', { adapter })
1222
1212
  export { A }`, 'A.tsx', { adapter })
1223
1213
  expect(result.errors?.filter(e => e.code === 'BF101') ?? []).toEqual([])
1224
1214
  const template = result.files.find(f => f.path.endsWith('.html.ep'))?.content ?? ''
1225
- expect(template).toContain("join(' ', @{bf->concat($left, $right)})")
1215
+ expect(template).toContain("bf->join(bf->concat($left, $right), ' ')")
1226
1216
  expect(template).not.toContain('$bf->concat')
1227
1217
  })
1228
1218
 
@@ -1484,10 +1474,10 @@ describe('MojoAdapter - #1448 Tier A/B fixture-driven lowering pins', () => {
1484
1474
  { fixture: arraySliceFixture, expect: 'bf->slice($items, 1, 3)' },
1485
1475
  // #1448 full-arity — zero-arg defaults.
1486
1476
  { fixture: arraySliceCopyFixture, expect: 'bf->slice($items, 0, undef)' },
1487
- { fixture: arrayJoinDefaultFixture, expect: `join(',', @{$items})` },
1477
+ { fixture: arrayJoinDefaultFixture, expect: `bf->join($items, ',')` },
1488
1478
  // `.at()` → index 0; `.concat()` → the receiver (shallow copy).
1489
1479
  { fixture: arrayAtDefaultFixture, expect: 'bf->at($items, 0)' },
1490
- { fixture: arrayConcatCopyFixture, expect: `join('|', @{$items})` },
1480
+ { fixture: arrayConcatCopyFixture, expect: `bf->join($items, '|')` },
1491
1481
  { fixture: arrayReverseFixture, expect: 'bf->reverse($items)' },
1492
1482
  // .toReversed shares the helper with .reverse — pinning both
1493
1483
  // routings catches a future divergence between them.
@@ -1497,7 +1487,7 @@ describe('MojoAdapter - #1448 Tier A/B fixture-driven lowering pins', () => {
1497
1487
  { fixture: stringTrimFixture, expect: 'bf->trim($value)' },
1498
1488
  // #1448 Tier B — string → array. `.split(',')` lowers to
1499
1489
  // `bf->split`, here chained into `.join('|')` so the array ref is
1500
- // observable (`join('|', @{bf->split($value, ',')})`).
1490
+ // observable (`bf->join(bf->split($value, ','), '|')`).
1501
1491
  { fixture: stringSplitFixture, expect: `bf->split($value, ',')` },
1502
1492
  { fixture: stringSplitLimitFixture, expect: `bf->split($value, ',', 2)` },
1503
1493
  // #1448 Tier B — string → boolean at condition position (`% if`).
@@ -1687,7 +1677,7 @@ export { C }
1687
1677
  // projects each element (no flatten) and composes through `.join`.
1688
1678
  test('.map(t => `#${t}`).join(" ") emits bf->map_eval composed into join', () => {
1689
1679
  const t = emitMap("tags.map(t => `#${t}`).join(' ')")
1690
- expect(t).toContain(`join(' ', @{bf->map_eval($tags,`)
1680
+ expect(t).toContain(`bf->join(bf->map_eval($tags,`)
1691
1681
  expect(t).toContain(`"kind":"template-literal"`)
1692
1682
  })
1693
1683
 
@@ -35,14 +35,20 @@ export function renderArrayMethod(
35
35
  ): string {
36
36
  switch (method) {
37
37
  case 'join': {
38
- // arr.join(sep) → join(sep, @{arr}). The default `${obj}->{join}`
39
- // hash-lookup fallback would emit invalid Perl, which is why the
40
- // IR carves out a dedicated method node instead of routing
41
- // through the generic call dispatcher. `.join()` defaults the
42
- // separator to `,` (JS) and ignores any extra argument.
38
+ // arr.join(sep) → bf->join(arr, sep), NOT Perl's native `join`
39
+ // builtin directly on `@{arr}` a nested-array element (e.g.
40
+ // `.flat(0)`'s shallow copy) would stringify to its Perl memory
41
+ // address ("ARRAY(0x...)") under native `join`'s scalar coercion
42
+ // instead of JS's recursive comma-join (#2262/#2272). `bf->join`
43
+ // (BarefootJS.pm) routes each element through `string()` first.
44
+ // The default `${obj}->{join}` hash-lookup fallback would emit
45
+ // invalid Perl, which is why the IR carves out a dedicated method
46
+ // node instead of routing through the generic call dispatcher.
47
+ // `.join()` defaults the separator to `,` (JS) and ignores any
48
+ // extra argument.
43
49
  const obj = emit(object)
44
50
  const sep = args.length >= 1 ? emit(args[0]) : `','`
45
- return `join(${sep}, @{${obj}})`
51
+ return `bf->join(${obj}, ${sep})`
46
52
  }
47
53
  case 'includes': {
48
54
  // Both `arr.includes(x)` and `str.includes(sub)` route here —
@@ -88,7 +88,7 @@ export const conformancePins: ConformancePins = {
88
88
  // below for the shared `/* @client */` keyed-map slot-id elision
89
89
  // contract (same as `todo-app`), not a render or BF101 gap.
90
90
  // #1443: `[a, b].filter(Boolean).join(' ')` (the registry Slot's
91
- // shape) now lowers to `join(' ', @{[grep { $_ } @{[$a, $b]}]})`.
91
+ // shape) now lowers to `bf->join([grep { $_ } @{[$a, $b]}], ' ')`.
92
92
  // No BF101 expected — pinned positively via the
93
93
  // `branch-local-filter-join` template-output test below.
94
94
  //
@@ -139,4 +139,10 @@ export const conformancePins: ConformancePins = {
139
139
  // A dynamic/signal-derived value still refuses with BF101 — see the
140
140
  // `dangerous-inner-html-dynamic` fixture/pin below (tracked: #2215).
141
141
  'dangerous-inner-html-dynamic': [{ code: 'BF101', severity: 'error', issue: 'https://github.com/piconic-ai/barefootjs/issues/2215' }],
142
+ // #2273: a method call on a prop typed as a built-in host rich type
143
+ // (Date, Map, …) has no catalogued lowering in any adapter — this is a
144
+ // compiler-level refusal (`checkRichTypeMethodCalls`, wired ahead of
145
+ // `adapter.generate()`), not an adapter-specific gap, so it is pinned
146
+ // identically across every adapter package including Hono.
147
+ 'date-method-uncatalogued': [{ code: 'BF021', severity: 'error', issue: 'https://github.com/piconic-ai/barefootjs/issues/2274' }],
142
148
  }