@barefootjs/cli 0.6.1 → 0.8.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.
@@ -52,6 +52,7 @@
52
52
  - [Adapter Architecture](./adapters/adapter-architecture.md) — How adapters work, the `TemplateAdapter` interface, and the IR contract
53
53
  - [Hono Adapter](./adapters/hono-adapter.md) — Configuration and output format for Hono / JSX-based servers
54
54
  - [Go Template Adapter](./adapters/go-template-adapter.md) — Configuration and output format for Go `html/template`
55
+ - [Perl Adapter](./adapters/perl-adapter.md) — Mojolicious and Text::Xslate (PSGI/Plack) backends, sharing one runtime
55
56
  - [CSR (Client-Side Rendering)](./adapters/csr.md) — Static-hosting renderer: emit client JS only, no SSR template
56
57
  - [Writing a Custom Adapter](./adapters/custom-adapter.md) — Step-by-step guide to implementing your own adapter
57
58
 
@@ -12,6 +12,27 @@ npm install @barefootjs/go-template
12
12
  ```
13
13
 
14
14
 
15
+ ## Server integration
16
+
17
+ The adapter is **web-framework-agnostic** — it emits plain Go `html/template`
18
+ files plus a small runtime (`FuncMap`, `Renderer`), so any server that can
19
+ parse and execute `html/template` can render the output. The scaffolder
20
+ (`npm create barefootjs@latest -- --adapter <name>`) ships runnable starters
21
+ for four Go servers, all built on this adapter:
22
+
23
+ | `--adapter` | Framework | Router |
24
+ |-------------|-----------|--------|
25
+ | `echo` | [Echo](https://echo.labstack.com/) | `echo.Renderer` |
26
+ | `gin` | [Gin](https://gin-gonic.com/) | `gin.Engine` |
27
+ | `chi` | [Chi](https://go-chi.io/) | `chi.Router` (net/http) |
28
+ | `nethttp` | Go standard library | `http.ServeMux` |
29
+
30
+ Each scaffold loads the generated `.tmpl` files into a `template.Template`
31
+ with `bf.FuncMap()`, then renders a component through `bf.NewRenderer(...)`.
32
+ Runnable end-to-end examples for all four live under
33
+ [`integrations/`](https://github.com/piconic-ai/barefootjs/tree/main/integrations).
34
+
35
+
15
36
  ## Basic Usage
16
37
 
17
38
  ```typescript
@@ -221,6 +242,14 @@ export function TodoList({ items }: { items: TodoItem[] }) {
221
242
  }
222
243
  ```
223
244
 
245
+ Child component props carry a `ScopeID` used for hydration. You don't have to
246
+ mint these by hand: `bf.Renderer.Render` backfills a unique
247
+ `<Component>_<random>` id for any child (in a slice or a single field) whose
248
+ `ScopeID` is empty — the same shape the generated `New{Component}Props()`
249
+ constructor uses. Build child props with just the data they need (e.g.
250
+ `TodoItemProps{Todo: t}`) and the runtime fills in the rest. Setting `ScopeID`
251
+ explicitly still works and is preserved when you need a stable id.
252
+
224
253
  ## Conditional Rendering
225
254
 
226
255
  Ternaries become `{{if}}...{{else}}...{{end}}`:
@@ -0,0 +1,171 @@
1
+ ---
2
+ title: Perl Adapter
3
+ description: Render BarefootJS components from Perl — one engine-agnostic runtime with Mojolicious and Text::Xslate (PSGI/Plack) backends.
4
+ ---
5
+
6
+ # Perl Adapter
7
+
8
+ Run the same JSX components on a Perl backend. BarefootJS compiles your JSX into
9
+ a **marked template** plus **client JS**; on the server, a small Perl runtime
10
+ renders those templates. The runtime is deliberately **template-engine- and
11
+ web-framework-agnostic**, so one implementation drives multiple stacks.
12
+
13
+ ```
14
+ JSX → IR → marked template (.ep / .tx) + Component.client.js
15
+
16
+
17
+ BarefootJS runtime ──delegates──▶ pluggable backend
18
+ (@barefootjs/perl) (Mojolicious | Text::Xslate)
19
+ ```
20
+
21
+ ## Two backends, one runtime
22
+
23
+ | Backend | Template syntax | Compile-time package | Runtime | Where it runs |
24
+ |---------|-----------------|----------------------|---------|---------------|
25
+ | Mojolicious | EP (`<%= %>`) | `@barefootjs/mojolicious` | `Mojolicious::Plugin::BarefootJS` + `BarefootJS::Backend::Mojo` | Mojolicious apps |
26
+ | Text::Xslate | Kolon (`<: :>`) | `@barefootjs/xslate` | `BarefootJS::Backend::Xslate` | **any PSGI / Plack app** (no framework) |
27
+
28
+ Both compile-time packages emit per-component template files and the shared
29
+ client JS, and both render through the same engine-agnostic Perl runtime
30
+ (`BarefootJS`, shipped by `@barefootjs/perl`). The only thing that differs is
31
+ the **backend**: a tiny object that implements the four operations the runtime
32
+ delegates to.
33
+
34
+ ### The backend contract
35
+
36
+ Everything that depends on *how* a template renders — JSON marshalling,
37
+ raw-string marking, JSX-children materialisation, and named-template
38
+ rendering — lives behind a `backend` object with four methods:
39
+
40
+ | Method | Purpose |
41
+ |--------|---------|
42
+ | `encode_json($data)` | Serialize a value for `bf-p` props / inline JSON |
43
+ | `mark_raw($str)` | Mark already-safe HTML so the engine won't re-escape it |
44
+ | `materialize($value)` | Resolve captured JSX children to a string |
45
+ | `render_named($name, $bf, \%vars)` | Render a child component's template |
46
+
47
+ Because that is the *only* engine-specific surface, the EP→Kolon mapping is
48
+ mechanical and the runtime is reused unchanged:
49
+
50
+ | Mojolicious EP | Text::Xslate Kolon |
51
+ |----------------|--------------------|
52
+ | `<%= EXPR %>` (escaped) | `<: EXPR :>` (Kolon auto-escapes) |
53
+ | `<%== EXPR %>` (raw) | `<: EXPR \| mark_raw :>` |
54
+ | `bf->method(args)` | `$bf.method(args)` |
55
+ | `% if (C) { … % }` | `: if (C) { … : }` |
56
+
57
+ ## Mojolicious
58
+
59
+ ```
60
+ npm install @barefootjs/mojolicious
61
+ ```
62
+
63
+ Scaffold a runnable starter:
64
+
65
+ ```
66
+ npm create barefootjs@latest -- --adapter mojo
67
+ ```
68
+
69
+ Configure the build (`barefoot.config.ts`):
70
+
71
+ ```typescript
72
+ import { createConfig } from '@barefootjs/mojolicious/build'
73
+
74
+ export default createConfig({
75
+ components: ['./components'],
76
+ outDir: 'dist',
77
+ })
78
+ ```
79
+
80
+ In your app, load the plugin — it registers a `bf` helper that gives each
81
+ request a `BarefootJS` runtime backed by `BarefootJS::Backend::Mojo`:
82
+
83
+ ```perl
84
+ use Mojolicious::Lite -signatures;
85
+
86
+ plugin 'BarefootJS';
87
+
88
+ get '/counter' => sub ($c) {
89
+ $c->render(template => 'Counter', layout => 'default');
90
+ };
91
+
92
+ app->start;
93
+ ```
94
+
95
+ The generated `.html.ep` templates call the runtime through the `bf` helper
96
+ (`<%== bf->scope_attr %>`, `<%= bf->json($data) %>`, …).
97
+
98
+ ## Text::Xslate (PSGI / Plack)
99
+
100
+ ```
101
+ npm install @barefootjs/xslate
102
+ ```
103
+
104
+ ```typescript
105
+ import { createConfig } from '@barefootjs/xslate/build'
106
+
107
+ export default createConfig({
108
+ components: ['./components'],
109
+ outDir: 'dist',
110
+ })
111
+ ```
112
+
113
+ The build emits Kolon `.tx` templates. The backend is just a plain
114
+ `Text::Xslate` instance, so it runs under **any PSGI/Plack app** — no
115
+ Mojolicious required:
116
+
117
+ ```perl
118
+ use BarefootJS;
119
+ use BarefootJS::Backend::Xslate;
120
+
121
+ my $backend = BarefootJS::Backend::Xslate->new(path => ['dist/templates']);
122
+
123
+ my $app = sub {
124
+ my $env = shift;
125
+ my $bf = BarefootJS->new(undef, { backend => $backend });
126
+ $bf->_scope_id('Counter_' . int(rand(1e6)));
127
+ my $body = $backend->render_named('Counter', $bf, { count => 0 });
128
+ my $html = "<!doctype html><body>$body" . $bf->scripts . '</body>';
129
+ return [200, ['Content-Type' => 'text/html; charset=utf-8'], [$html]];
130
+ };
131
+ ```
132
+
133
+ The generated Kolon templates call the runtime as a `bf` object
134
+ (`<: $bf.scope_attr() :>`, `<: $bf.json($data) :>`, …). Kolon auto-escapes
135
+ `<: … :>` interpolations; helpers that emit markup return `mark_raw` values.
136
+
137
+ ## CPAN distributions
138
+
139
+ The Perl side is packaged as standalone CPAN distributions (built with
140
+ [Minilla](https://metacpan.org/pod/Minilla)), so a Perl app can depend on them
141
+ without the JS toolchain at runtime:
142
+
143
+ | Distribution | Main module | Depends on |
144
+ |--------------|-------------|------------|
145
+ | `BarefootJS` | `BarefootJS` | core Perl only |
146
+ | `BarefootJS-Backend-Xslate` | `BarefootJS::Backend::Xslate` | `BarefootJS`, `Text::Xslate` |
147
+ | `Mojolicious-Plugin-BarefootJS` | `Mojolicious::Plugin::BarefootJS` | `BarefootJS`, `Mojolicious` |
148
+
149
+ ## Dev auto-reload
150
+
151
+ `barefoot build --watch` writes a sentinel after each rebuild; the browser can
152
+ subscribe to a small SSE endpoint and reload automatically. The logic is
153
+ framework-agnostic (`BarefootJS::DevReload`):
154
+
155
+ - **Mojolicious:** `plugin 'BarefootJS::DevReload'`, then emit `%== bf_dev_snippet` before `</body>`.
156
+ - **PSGI / Plack:** mount `BarefootJS::DevReload->to_app(dist_dir => 'dist')` at the SSE endpoint, and emit `BarefootJS::DevReload->snippet($endpoint)` in your layout. Run under a prefork server (Starman / Starlet) in dev.
157
+
158
+ Both are no-ops in production.
159
+
160
+ ## Examples
161
+
162
+ Runnable end-to-end apps that render the same shared components on a Perl
163
+ backend live under
164
+ [`integrations/`](https://github.com/piconic-ai/barefootjs/tree/main/integrations) —
165
+ including SSR, fine-grained reactivity, a REST todo API, and SSE streaming.
166
+
167
+ ## See also
168
+
169
+ - [Adapter Architecture](./adapter-architecture.md) — the `TemplateAdapter` interface and IR contract
170
+ - [Backend Freedom](../core-concepts/backend-freedom.md) — why the same JSX runs on any stack
171
+ - [Writing a Custom Adapter](./custom-adapter.md)
@@ -22,10 +22,15 @@ JSX Source
22
22
  |---------|--------|---------|---------|
23
23
  | [`HonoAdapter`](./adapters/hono-adapter.md) | `.tsx` | Hono / JSX-based servers | `@barefootjs/hono` |
24
24
  | [`GoTemplateAdapter`](./adapters/go-template-adapter.md) | `.tmpl` + `_types.go` | Go `html/template` | `@barefootjs/go-template` |
25
+ | [Perl](./adapters/perl-adapter.md) | `.ep` / `.tx` | Mojolicious, Text::Xslate (PSGI/Plack) | `@barefootjs/mojolicious`, `@barefootjs/xslate` |
25
26
  | [CSR](./adapters/csr.md) | — (client-rendered) | None (browser-only) | `@barefootjs/client` |
26
27
 
27
28
  > CSR is not an IR→template adapter. It renders components directly in the browser using client-side template functions — use it when the server can't (or shouldn't) emit the initial HTML.
28
29
 
30
+ The `GoTemplateAdapter` is web-framework-agnostic: its `html/template` output runs on any Go server. `npm create barefootjs@latest` ships scaffolds for Echo, Gin, Chi, and net/http (via `--adapter`) — see [Go Template Adapter → Server integration](./adapters/go-template-adapter.md#server-integration).
31
+
32
+ The Perl adapters share one engine-agnostic runtime (`BarefootJS`): `@barefootjs/mojolicious` targets Mojolicious EP, and `@barefootjs/xslate` targets Text::Xslate (Kolon) and runs under any PSGI/Plack app. See the [Perl Adapter](./adapters/perl-adapter.md) page.
33
+
29
34
  ## Pages
30
35
 
31
36
  | Topic | Description |
@@ -33,5 +38,6 @@ JSX Source
33
38
  | [Adapter Architecture](./adapters/adapter-architecture.md) | How adapters work, the `TemplateAdapter` interface, and the IR contract |
34
39
  | [Hono Adapter](./adapters/hono-adapter.md) | Configuration and output format for Hono / JSX-based servers |
35
40
  | [Go Template Adapter](./adapters/go-template-adapter.md) | Configuration and output format for Go `html/template` |
41
+ | [Perl Adapter](./adapters/perl-adapter.md) | Mojolicious and Text::Xslate (PSGI/Plack) backends, sharing one runtime |
36
42
  | [CSR](./adapters/csr.md) | Client-side rendering without a server-rendered template |
37
43
  | [Writing a Custom Adapter](./adapters/custom-adapter.md) | Step-by-step guide to implementing your own adapter |
@@ -44,6 +44,7 @@
44
44
  - [Writing a Custom Adapter](https://barefootjs.dev/docs/adapters/custom-adapter.md): Step-by-step guide to building a custom adapter using the TestAdapter as a reference.
45
45
  - [Go Template Adapter](https://barefootjs.dev/docs/adapters/go-template-adapter.md): Generate Go html/template files and type definitions from the compiler's IR.
46
46
  - [Hono Adapter](https://barefootjs.dev/docs/adapters/hono-adapter.md): Generate Hono JSX templates from the compiler's IR for Hono-based servers.
47
+ - [Perl Adapter](https://barefootjs.dev/docs/adapters/perl-adapter.md): Render BarefootJS components from Perl — one engine-agnostic runtime with Mojolicious and Text::Xslate (PSGI/Plack) backends.
47
48
 
48
49
  ## Advanced
49
50
 
@@ -152,10 +152,10 @@ This runs `bf build`, generates the final `uno.css`, and calls `wrangler deploy`
152
152
  - **[`createSignal`](./reactivity/create-signal.md)** and **[`createMemo`](./reactivity/create-memo.md)** — the reactivity primitives you just used.
153
153
  - **[Client Directive](./rendering/client-directive.md)** — exactly what `"use client"` does and when to reach for it.
154
154
  - **[Hono Adapter](./adapters/hono-adapter.md)** — adapter-specific configuration and output details.
155
- - Pick a different backend by passing `--adapter` to the scaffolder. Supported values today: `hono` (default — Cloudflare Workers), `hono-node`, `echo` (Go / Echo), `mojo` (Mojolicious / Perl), `csr` (no backend — pure client render). For example:
155
+ - Pick a different backend by passing `--adapter` to the scaffolder. Supported values today: `hono` (default — Cloudflare Workers), `hono-node`, `echo` (Go / Echo), `gin` (Go / Gin), `chi` (Go / Chi), `nethttp` (Go / net/http stdlib), `mojo` (Mojolicious / Perl), `csr` (no backend — pure client render). For example:
156
156
 
157
157
  ```bash
158
158
  npm create barefootjs@latest -- --adapter hono-node
159
159
  ```
160
160
 
161
- See [Adapter Architecture](./adapters/adapter-architecture.md) for the architectural overview, and the per-adapter pages under [`docs/core/adapters/`](./adapters/) for output details. The `@barefootjs/go-template` package is a compile-time adapter API for generating Go `html/template` files — it does not have a `bf init` scaffold; see [Go Template Adapter](./adapters/go-template-adapter.md) for the programmatic usage.
161
+ See [Adapter Architecture](./adapters/adapter-architecture.md) for the architectural overview, and the per-adapter pages under [`docs/core/adapters/`](./adapters/) for output details. The four Go scaffolds (`echo`, `gin`, `chi`, `nethttp`) all build on the `@barefootjs/go-template` adapter, which generates Go `html/template` files; see [Go Template Adapter](./adapters/go-template-adapter.md) for its programmatic API.