@barefootjs/erb 0.31.6 → 0.31.7

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,12 +1,10 @@
1
1
  /**
2
- * Per-fixture build-time contracts for shapes the ERB adapter
3
- * intentionally refuses to lower. Mirrors mojo's set the lowering
4
- * gates (`isLowerableLoopDestructure`, `collectImportedLoopChild
5
- * ComponentErrors`, `refuseUnsupportedAttrExpression`, the #2038
6
- * nested-higher-order-callback gate) are shared code in `@barefootjs/jsx`
7
- * that every EP/ERB-family adapter reuses verbatim. Consumed by this
8
- * package's own conformance test (as `expectedDiagnostics`) and by
9
- * `bf compat` (issue-URL attribution).
2
+ * Per-fixture build-time contracts for shapes this adapter intentionally
3
+ * refuses to lower. Declared per adapter, not on the shared fixtures, so
4
+ * adding a new adapter never touches a cross-adapter file. Per-fixture
5
+ * rationale lives on each fixture's docstring
6
+ * (`packages/adapter-tests/fixtures/<id>.ts`) and spec/callback-fidelity.md;
7
+ * comments below only mark where this adapter's set diverges from siblings.
10
8
  */
11
9
  import type { ConformancePins } from '@barefootjs/jsx';
12
10
  export declare const conformancePins: ConformancePins;
@@ -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,eAkJ7B,CAAA"}
1
+ {"version":3,"file":"conformance-pins.d.ts","sourceRoot":"","sources":["../src/conformance-pins.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEtD,eAAO,MAAM,eAAe,EAAE,eAwC7B,CAAA"}
package/dist/index.js CHANGED
@@ -189269,7 +189269,8 @@ var conformancePins = {
189269
189269
  }
189270
189270
  ],
189271
189271
  "filter-nested-find-predicate": [{ code: "BF101", severity: "error", issue: "https://github.com/piconic-ai/barefootjs/issues/2320" }],
189272
- "date-method-uncatalogued": [{ code: "BF021", severity: "error", issue: "https://github.com/piconic-ai/barefootjs/issues/2356" }]
189272
+ "date-method-uncatalogued": [{ code: "BF021", severity: "error", issue: "https://github.com/piconic-ai/barefootjs/issues/2356" }],
189273
+ "rich-prop-client-read": [{ code: "BF049", severity: "error", issue: "https://github.com/piconic-ai/barefootjs/issues/2648" }]
189273
189274
  };
189274
189275
  // src/render-divergences.ts
189275
189276
  var renderDivergences = {};
@@ -1,15 +1,10 @@
1
1
  /**
2
- * Render-level divergences against the shared conformance corpus
3
- * (Priority-12 edge-case sweep, #2168): fixtures that COMPILE clean on
4
- * this adapter but whose rendered output diverges from the Hono
5
- * reference on real Ruby erb (or fails at render time).
6
- *
7
- * Consumed by this package's conformance test (its `skipJsx` set is
8
- * derived from these keys, so the skip list and this declaration can't
9
- * drift) and by `packages/compat`, which publishes the entries in the
10
- * fixture-divergences section of `ui/compat.lock.json` — surfaced on
11
- * the docs compatibility-matrix page. Graduating an entry means fixing
12
- * the adapter (or the shared compiler layer) and deleting the line.
2
+ * Fixtures that compile clean on this adapter but render divergent from the
3
+ * Hono reference on real Ruby erb. The conformance `skipJsx` set and
4
+ * `packages/compat`'s published fixture-divergences both derive from this
5
+ * one object, so the skip list and the declaration can't drift. Keep the
6
+ * file even when the set is empty — the next divergence lands here, not in
7
+ * a re-created file.
13
8
  */
14
9
  import type { RenderDivergences } from '@barefootjs/jsx';
15
10
  export declare const renderDivergences: RenderDivergences;
@@ -1 +1 @@
1
- {"version":3,"file":"render-divergences.d.ts","sourceRoot":"","sources":["../src/render-divergences.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAExD,eAAO,MAAM,iBAAiB,EAAE,iBAM/B,CAAA"}
1
+ {"version":3,"file":"render-divergences.d.ts","sourceRoot":"","sources":["../src/render-divergences.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAExD,eAAO,MAAM,iBAAiB,EAAE,iBAC/B,CAAA"}
package/dist/vite.js CHANGED
@@ -2258,6 +2258,7 @@ var ErrorCodes = {
2258
2258
  COMPONENT_REQUIRED_PROP_MISSING: "BF046",
2259
2259
  JSX_BRANCH_LOCAL_IN_CALLBACK: "BF047",
2260
2260
  SIBLING_COMPONENT_NOT_COMPILED: "BF048",
2261
+ RICH_TYPE_PROP_NOT_HYDRATABLE: "BF049",
2261
2262
  SHARED_PROGRAM_REQUIRED: "BF050",
2262
2263
  WRONG_PACKAGE_IMPORT: "BF051",
2263
2264
  BUILTIN_REQUIRES_IMPORT: "BF054",
@@ -2288,6 +2289,7 @@ var errorMessages = {
2288
2289
  [ErrorCodes.COMPONENT_REQUIRED_PROP_MISSING]: "Built-in component is missing a required prop.",
2289
2290
  [ErrorCodes.JSX_BRANCH_LOCAL_IN_CALLBACK]: "JSX-typed local declared inside an `if`-block cannot be referenced from a callback body (ref / event handler). " + "Render it as a child instead: `<div ref={...}>{local}</div>`.",
2290
2291
  [ErrorCodes.SIBLING_COMPONENT_NOT_COMPILED]: "Referenced component did not compile to a template, so this reference would throw " + "`ReferenceError` at render time. Multi-return JSX dispatch (a `switch` or `if`/`else` " + "chain across multiple JSX-returning branches) cannot compile as a component in a " + `'use client' file. Extract it to a separate non-"use client" file (where it is preserved ` + "verbatim, see #932), or rewrite it as a single-return ternary/conditional chain so the " + "component pipeline can compile it.",
2292
+ [ErrorCodes.RICH_TYPE_PROP_NOT_HYDRATABLE]: "Rich-typed prop cannot cross the bf-p hydration boundary as JSON.",
2291
2293
  [ErrorCodes.SHARED_PROGRAM_REQUIRED]: "Shared ts.Program required for type-based reactivity classification. This source imports a Reactive<T>-branded library (e.g. @barefootjs/form) whose getters cannot be classified by regex alone. Pass `options.program` (built via `createProgramForCorpus`) so the analyzer can resolve the brand through the TypeChecker.",
2292
2294
  [ErrorCodes.WRONG_PACKAGE_IMPORT]: "Import from wrong package.",
2293
2295
  [ErrorCodes.BUILTIN_REQUIRES_IMPORT]: "Built-in <Async> / <Region> must be imported from '@barefootjs/client'. " + "The compiler recognises these tags by their import (not by tag name), " + "so an unimported tag with this name is treated as an undeclared component.",
@@ -2321,6 +2323,8 @@ var HOST_RICH_TYPE_NAMES = new Set([
2321
2323
  "BigInt",
2322
2324
  "Function"
2323
2325
  ]);
2326
+ var JSON_REVIVABLE_RICH_TYPE_NAMES = new Set(["Date", "URL"]);
2327
+ var JSON_UNSAFE_RICH_TYPE_NAMES = new Set([...HOST_RICH_TYPE_NAMES].filter((n) => !JSON_REVIVABLE_RICH_TYPE_NAMES.has(n)));
2324
2328
  function baseTypeName(raw) {
2325
2329
  const idx = raw.indexOf("<");
2326
2330
  return (idx === -1 ? raw : raw.slice(0, idx)).trim();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@barefootjs/erb",
3
- "version": "0.31.6",
3
+ "version": "0.31.7",
4
4
  "description": "ERB (Embedded Ruby) adapter for BarefootJS — compiles IR to .erb templates and ships the Ruby rendering backend; runs under any Rack app (Sinatra, Rails)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -54,7 +54,7 @@
54
54
  "directory": "packages/adapter-erb"
55
55
  },
56
56
  "dependencies": {
57
- "@barefootjs/shared": "0.31.6"
57
+ "@barefootjs/shared": "0.31.7"
58
58
  },
59
59
  "peerDependencies": {
60
60
  "@barefootjs/jsx": ">=0.2.0",
@@ -71,9 +71,9 @@
71
71
  },
72
72
  "devDependencies": {
73
73
  "@barefootjs/adapter-tests": "0.1.0",
74
- "@barefootjs/jsx": "0.31.6",
75
- "@barefootjs/vite": "0.31.6",
76
- "@barefootjs/client": "0.31.6",
74
+ "@barefootjs/jsx": "0.31.7",
75
+ "@barefootjs/vite": "0.31.7",
76
+ "@barefootjs/client": "0.31.7",
77
77
  "typescript": "^5.0.0",
78
78
  "vite": "^6.0.0"
79
79
  }
@@ -1,89 +1,33 @@
1
1
  /**
2
- * Per-fixture build-time contracts for shapes the ERB adapter
3
- * intentionally refuses to lower. Mirrors mojo's set the lowering
4
- * gates (`isLowerableLoopDestructure`, `collectImportedLoopChild
5
- * ComponentErrors`, `refuseUnsupportedAttrExpression`, the #2038
6
- * nested-higher-order-callback gate) are shared code in `@barefootjs/jsx`
7
- * that every EP/ERB-family adapter reuses verbatim. Consumed by this
8
- * package's own conformance test (as `expectedDiagnostics`) and by
9
- * `bf compat` (issue-URL attribution).
2
+ * Per-fixture build-time contracts for shapes this adapter intentionally
3
+ * refuses to lower. Declared per adapter, not on the shared fixtures, so
4
+ * adding a new adapter never touches a cross-adapter file. Per-fixture
5
+ * rationale lives on each fixture's docstring
6
+ * (`packages/adapter-tests/fixtures/<id>.ts`) and spec/callback-fidelity.md;
7
+ * comments below only mark where this adapter's set diverges from siblings.
10
8
  */
11
9
 
12
10
  import type { ConformancePins } from '@barefootjs/jsx'
13
11
 
14
12
  export const conformancePins: ConformancePins = {
15
- // Off-subset filter predicate (`typeof`) the compiler can't lower; a
16
- // JS-runtime target runs it, a DSL adapter surfaces BF021 + `/* @client */`.
17
- // See spec/callback-fidelity.md.
18
13
  'filter-typeof-predicate': [{ code: 'BF021', severity: 'error' }],
19
- // Array-builder `.map()` body (imperative `push`-into-array preamble):
20
- // BF021, with a verified `/* @client */` escape — `map-array-builder-
21
- // body-client` (#2613). See that fixture's docstring.
22
14
  'map-array-builder-body': [{ code: 'BF021', severity: 'error' }],
23
15
  'map-array-builder-escaping': [{ code: 'BF021', severity: 'error' }],
24
- // `.fill(value)` mutates the receiver in place — no template lowering
25
- // on any DSL adapter; a JS-runtime target runs it, a DSL adapter
26
- // surfaces BF101 + `/* @client */`. See spec/callback-fidelity.md.
27
16
  'fill-unsupported': [{ code: 'BF101', severity: 'error' }],
28
- // Off-subset `.find()` / `.some()` / `.every()` predicate (`typeof`) the
29
- // compiler can't lower; a JS-runtime target runs it, a DSL adapter
30
- // surfaces BF101 + `/* @client */`. See spec/callback-fidelity.md.
31
17
  'find-typeof-predicate': [{ code: 'BF101', severity: 'error' }],
32
18
  'some-typeof-predicate': [{ code: 'BF101', severity: 'error' }],
33
19
  'every-typeof-predicate': [{ code: 'BF101', severity: 'error' }],
34
- // Off-subset `.reduce()` / `.reduceRight()` body / `.flatMap()`
35
- // projection (`typeof`) the compiler can't lower; a JS-runtime target
36
- // runs it, a DSL adapter surfaces BF101 + `/* @client */`.
37
- // See spec/callback-fidelity.md.
38
20
  'reduce-typeof-body': [{ code: 'BF101', severity: 'error' }],
39
21
  'reduce-right-typeof-body': [{ code: 'BF101', severity: 'error' }],
40
22
  'flatmap-typeof-projection': [{ code: 'BF101', severity: 'error' }],
41
- // JSX-returning `.flatMap()` body carried as structured segments i.e.
42
- // one with STATEMENTS (early returns, consts): a JS runtime executes it
43
- // verbatim; a DSL template runtime can't, so it refuses with BF021 +
44
- // `/* @client */` (pre-gate this emitted an empty loop body — silent
45
- // divergence). A pure PROJECTION body (`flatMap(it => it.tags.map(...))`,
46
- // e.g. the `flatmap-expression-body` fixture) is NOT pinned: it lowers to
47
- // neutral nested-loop IR this adapter templatizes natively.
48
- // See spec/callback-fidelity.md.
23
+ // A pure PROJECTION flatMap body (`flatmap-expression-body`) is NOT pinned
24
+ // it lowers to neutral nested-loop IR this adapter templatizes natively;
25
+ // only the statement-carrying body refuses.
49
26
  'tag-cloud': [{ code: 'BF021', severity: 'error' }],
50
- // A keyed `.map()` row body whose preamble builds a JSX leaf from item
51
- // state (`cells.push(<td>{stateLabel}</td>)`) embedded as `{cells}` — the
52
- // Stage 3 array-builder carrier, jsRuntime-only: a JS runtime runs it
53
- // verbatim (and patches the region on same-key updates, #2389), a DSL
54
- // adapter refuses with BF021 + `/* @client */`. See spec/callback-fidelity.md.
55
27
  'preamble-cells': [{ code: 'BF021', severity: 'error' }],
56
- // `todo-app` / `todo-app-ssr` no longer pinned (#2205) the conformance
57
- // harness now passes `siblingTemplatesRegistered: true` for fixtures with
58
- // sibling `components`, matching `bf build`'s real semantics, so the
59
- // BF103 loop-body cross-template check no longer fires spuriously. (Both
60
- // fixtures are still skipped on this adapter via `render-divergences.ts`
61
- // — #2209 — for an unrelated signal-seeding gap.)
62
- // `static-array-children` no longer pinned (#2208) — `items`'s
63
- // array-literal initializer is now recognized as fully-static
64
- // (`resolveStaticLoopSource`) and inlined as a native Ruby array/hash
65
- // literal in the loop-bound expression, the same way a module-scope
66
- // const's value is already seeded.
67
- // `static-array-from-props` / `static-array-from-props-with-component`:
68
- // the `.map(([emoji, users]) => …)` / `.map(([id, t]) => …)` callback is
69
- // a plain array-index destructure (the `.filter(...)` runs on a
70
- // separate `const entries = …` statement, so `loop.filterPredicate` is
71
- // unset — this is not the `.filter().map(destructure)` chain
72
- // `isLowerableLoopDestructure` still refuses), and #2087 Phase B's
73
- // segments-walking accessor DOES lower it natively. But both fixtures'
74
- // loop array is that same `entries` — a component-scope `const`
75
- // computed from `Object.entries(props.x).filter(...)`, a runtime
76
- // expression the ERB adapter has no mechanism to evaluate at SSR
77
- // render time (only a pure-literal or module-string const is ever
78
- // inlined; a computed const falls through to an unseeded `v[:entries]`
79
- // and crashes). This is a pre-existing, orthogonal gap the widened
80
- // destructure gate merely exposes — it reproduces identically with a
81
- // non-destructured param (verified) — not a destructure-lowering
82
- // limitation, so it is NOT part of #2087's scope. Tracked as its own
83
- // gap under https://github.com/piconic-ai/barefootjs/issues/2321;
84
- // pinned honestly as BF101 (the adapter's own check, see `renderLoop`'s
85
- // "Loop array is a bare identifier..." comment) rather than faked as
86
- // BF104 or silently producing broken Ruby.
28
+ // Refused for the COMPUTED loop array (`const entries = Object.entries(...)
29
+ // .filter(...)`), not the destructure param (that lowers, #2087) — loud
30
+ // BF101 instead of silently iterating an unbound name zero times.
87
31
  'static-array-from-props': [
88
32
  {
89
33
  code: 'BF101',
@@ -91,8 +35,7 @@ export const conformancePins: ConformancePins = {
91
35
  issue: 'https://github.com/piconic-ai/barefootjs/issues/2321',
92
36
  },
93
37
  ],
94
- // BF103 (imported child in the loop body) no longer fires now that the
95
- // conformance harness passes `siblingTemplatesRegistered: true` (#2205).
38
+ // No BF103 pin: the harness registers sibling templates (#2205).
96
39
  'static-array-from-props-with-component': [
97
40
  {
98
41
  code: 'BF101',
@@ -100,61 +43,10 @@ export const conformancePins: ConformancePins = {
100
43
  issue: 'https://github.com/piconic-ai/barefootjs/issues/2321',
101
44
  },
102
45
  ],
103
- // #2087 Phase B: `isLowerableLoopDestructure` now admits every fixed-
104
- // binding shape (any field/index depth `destructure-array-index-in-map`,
105
- // `destructure-nested-object-in-map`), array-rest (`rest-destructure-
106
- // array-in-map`, native `bf.slice`), and object-rest whose every use is a
107
- // member read or a `{...rest}` spread onto an intrinsic element
108
- // (`rest-destructure-object-in-map`, `rest-destructure-object-spread-in-
109
- // map`, `rest-destructure-nested-in-map` — native `Hash#except` builds a
110
- // true residual Hash). None of the six destructure-in-map fixtures are
111
- // pinned here any more; all render to Hono parity. See
112
- // `rubyAccessorFromSegments` / the object-rest-in-loop branch in
113
- // `erb-adapter.ts`'s `renderLoop`.
114
- // #2038: a filter predicate containing a nested `.find(...)` callback.
115
- // `find*` returns an element, not a boolean — there is no inline
116
- // predicate form, and the emitter used to silently degrade the call to
117
- // its receiver. The nested `.some` sibling
118
- // (`filter-nested-callback-predicate`) is NOT pinned: like mojo, ERB
119
- // lowers it to a real inline Ruby block predicate and must render to
120
- // Hono parity instead.
121
- // Faithful lowering tracked: https://github.com/piconic-ai/barefootjs/issues/2320 (successor to #2038)
46
+ // Only the `.find` variant is pinned — `find*` returns an element, not a
47
+ // boolean, so there is no inline predicate form; the nested-`.some` sibling
48
+ // lowers to a real inline Ruby block and must render to Hono parity instead.
122
49
  'filter-nested-find-predicate': [{ code: 'BF101', severity: 'error', issue: 'https://github.com/piconic-ai/barefootjs/issues/2320' }],
123
- // #1467 demo-corpus context providers (`radio-group`, `accordion`,
124
- // `dialog`, `popover`, `select`, `dropdown-menu`, `combobox`,
125
- // `command`) are NOT pinned — an object-literal provider value lowers
126
- // to a Ruby Hash via `parseProviderObjectLiteral` (#1897): getter
127
- // members snapshot their body's SSR value, handler / function-shaped
128
- // members lower to `nil`.
129
- //
130
- // `button` / `kbd` are NOT pinned (unlike xslate): the auto-inferred
131
- // `<Slot>` sibling's `{...props}` / `{...children.props}` spread onto
132
- // its root element lowers via Ruby's native `**hash` double-splat in
133
- // the component-invocation Hash literal — the same shape mojo's EP
134
- // `%{$props}` flatten already handles.
135
- //
136
- // `data-table` is NOT pinned here either — it compiles clean
137
- // (`selected()[index]` → `index-access`, `.toFixed(2)` →
138
- // `bf.to_fixed`, `/* @client */` memo SSR-folded) and renders to Hono
139
- // parity. It stays in `skipMarkerConformance` below for the shared
140
- // `/* @client */` keyed-map slot-id elision contract only (same as
141
- // `todo-app`), not a render or BF101 gap.
142
- //
143
- // `array-map-function-reference` no longer pinned — a bare-identifier
144
- // `.map(format)` callback now resolves one hop to its declaration
145
- // (`resolveCallbackMethodFunctionReferences`, #2206), the same mechanism
146
- // #2090 established for `.sort(fnref)`.
147
- // `dangerous-inner-html` no longer pinned — a compile-time string-literal
148
- // `dangerouslySetInnerHTML={{ __html: '...' }}` is spliced directly into
149
- // the template as trusted raw text (`resolveDangerousInnerHtml`, #2207).
150
- // A dynamic/signal-derived value now lowers through ERB's unescaped
151
- // `<%= %>` (dropping the `bf.h(...)` escape wrap, #2319) — `dangerous-inner-
152
- // html-dynamic` is no longer pinned and renders to Hono parity, same as the
153
- // static case.
154
- // #2273: a method call on a prop typed as a built-in host rich type
155
- // (Date, Map, …) has no catalogued lowering in any adapter — this is a
156
- // compiler-level refusal (`checkRichTypeMethodCalls`, wired ahead of
157
- // `adapter.generate()`), not an adapter-specific gap, so it is pinned
158
- // identically across every adapter package including Hono.
159
50
  'date-method-uncatalogued': [{ code: 'BF021', severity: 'error', issue: 'https://github.com/piconic-ai/barefootjs/issues/2356' }],
51
+ 'rich-prop-client-read': [{ code: 'BF049', severity: 'error', issue: 'https://github.com/piconic-ai/barefootjs/issues/2648' }],
160
52
  }
@@ -1,23 +1,13 @@
1
1
  /**
2
- * Render-level divergences against the shared conformance corpus
3
- * (Priority-12 edge-case sweep, #2168): fixtures that COMPILE clean on
4
- * this adapter but whose rendered output diverges from the Hono
5
- * reference on real Ruby erb (or fails at render time).
6
- *
7
- * Consumed by this package's conformance test (its `skipJsx` set is
8
- * derived from these keys, so the skip list and this declaration can't
9
- * drift) and by `packages/compat`, which publishes the entries in the
10
- * fixture-divergences section of `ui/compat.lock.json` — surfaced on
11
- * the docs compatibility-matrix page. Graduating an entry means fixing
12
- * the adapter (or the shared compiler layer) and deleting the line.
2
+ * Fixtures that compile clean on this adapter but render divergent from the
3
+ * Hono reference on real Ruby erb. The conformance `skipJsx` set and
4
+ * `packages/compat`'s published fixture-divergences both derive from this
5
+ * one object, so the skip list and the declaration can't drift. Keep the
6
+ * file even when the set is empty — the next divergence lands here, not in
7
+ * a re-created file.
13
8
  */
14
9
 
15
10
  import type { RenderDivergences } from '@barefootjs/jsx'
16
11
 
17
12
  export const renderDivergences: RenderDivergences = {
18
- // `todo-app` / `todo-app-ssr` no longer diverge (#2209) — the shared
19
- // `evaluateSignalInit` (`@barefootjs/jsx`, sandboxed real-JS evaluation
20
- // instead of a fixed regex-shape catalogue) now correctly seeds `todos`
21
- // from `(props.initialTodos ?? []).map(t => ({ ...t, editing: false }))`.
22
-
23
13
  }