@barefootjs/jsx 0.3.0 → 0.4.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.
package/dist/index.js
CHANGED
|
@@ -1652,6 +1652,9 @@ function irToComponentTemplateWithOpts(node, opts) {
|
|
|
1652
1652
|
}
|
|
1653
1653
|
return `\${${transformExpr(node.expr, node.templateExpr)}}`;
|
|
1654
1654
|
case "conditional": {
|
|
1655
|
+
if (node.clientOnly && node.slotId) {
|
|
1656
|
+
return `<!--bf-cond-start:${node.slotId}--><!--bf-cond-end:${node.slotId}-->`;
|
|
1657
|
+
}
|
|
1655
1658
|
const trueBranch = recurse(node.whenTrue);
|
|
1656
1659
|
const falseBranch = recurse(node.whenFalse);
|
|
1657
1660
|
const trueHtml = node.slotId ? addCondAttrToTemplate(trueBranch, node.slotId) : trueBranch;
|
|
@@ -1882,6 +1885,9 @@ function generateCsrTemplateWithOpts(node, opts) {
|
|
|
1882
1885
|
return `\${${expr}}`;
|
|
1883
1886
|
}
|
|
1884
1887
|
case "conditional": {
|
|
1888
|
+
if (node.clientOnly && node.slotId) {
|
|
1889
|
+
return `<!--bf-cond-start:${node.slotId}--><!--bf-cond-end:${node.slotId}-->`;
|
|
1890
|
+
}
|
|
1885
1891
|
const trueBranch = recurse(node.whenTrue);
|
|
1886
1892
|
const falseBranch = recurse(node.whenFalse);
|
|
1887
1893
|
const trueHtml = node.slotId ? addCondAttrToTemplate(trueBranch, node.slotId) : trueBranch;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"html-template.d.ts","sourceRoot":"","sources":["../../src/ir-to-client-js/html-template.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAe,MAAM,EAAE,MAAM,UAAU,CAAA;AAG9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAG5C,OAAO,EAAwD,KAAK,MAAM,EAAE,MAAM,kBAAkB,CAAA;AACpG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAI9C;;;;GAIG;AACH,wBAAgB,qBAAqB,IAAI;IACvC,OAAO,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAA;IAC9B,OAAO,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAA;CAC/B,CAaA;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAwBnE;AAED;;;;;GAKG;AACH,wBAAgB,kCAAkC,IAAI;IACpD,OAAO,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAA;IAC9B,OAAO,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAA;CAC/B,CAeA;AA+LD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,WAAW,YAAY;IAC3B,oEAAoE;IACpE,gBAAgB,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,SAAS,EAAE;QAAE,IAAI,EAAE,QAAQ,CAAA;KAAE,CAAC,KAAK,OAAO,CAAA;IACxE,+EAA+E;IAC/E,eAAe,EAAE,OAAO,CAAA;CACzB;AAiFD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,SAAS,SAAI,EAAE,UAAU,CAAC,EAAE,aAAa,CAAC,MAAM,GAAG,aAAa,CAAC,EAAE,cAAc,CAAC,EAAE,MAAM,EAAE,UAAU,UAAQ,EAAE,iBAAiB,UAAQ,GAAG,MAAM,CAqM/N;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,SAAS,SAAI,EAAE,UAAU,CAAC,EAAE,aAAa,CAAC,MAAM,GAAG,aAAa,CAAC,GAAG,MAAM,CAoG9J;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,CAM7D;AA0ED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAM1E;AAeD;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,kBAAkB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACxC,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAC7B,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B;;;;;;;;;;;;OAYG;IACH,gBAAgB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAC9B;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,qFAAqF;IACrF,iBAAiB,CAAC,EAAE,OAAO,CAAA;CAC5B;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,MAAM,EACZ,kBAAkB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EACxC,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,EAC7B,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,GAC9B,MAAM,CAER;
|
|
1
|
+
{"version":3,"file":"html-template.d.ts","sourceRoot":"","sources":["../../src/ir-to-client-js/html-template.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAe,MAAM,EAAE,MAAM,UAAU,CAAA;AAG9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAG5C,OAAO,EAAwD,KAAK,MAAM,EAAE,MAAM,kBAAkB,CAAA;AACpG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAI9C;;;;GAIG;AACH,wBAAgB,qBAAqB,IAAI;IACvC,OAAO,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAA;IAC9B,OAAO,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAA;CAC/B,CAaA;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAwBnE;AAED;;;;;GAKG;AACH,wBAAgB,kCAAkC,IAAI;IACpD,OAAO,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAA;IAC9B,OAAO,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAA;CAC/B,CAeA;AA+LD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,WAAW,YAAY;IAC3B,oEAAoE;IACpE,gBAAgB,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,SAAS,EAAE;QAAE,IAAI,EAAE,QAAQ,CAAA;KAAE,CAAC,KAAK,OAAO,CAAA;IACxE,+EAA+E;IAC/E,eAAe,EAAE,OAAO,CAAA;CACzB;AAiFD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,SAAS,SAAI,EAAE,UAAU,CAAC,EAAE,aAAa,CAAC,MAAM,GAAG,aAAa,CAAC,EAAE,cAAc,CAAC,EAAE,MAAM,EAAE,UAAU,UAAQ,EAAE,iBAAiB,UAAQ,GAAG,MAAM,CAqM/N;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,SAAS,SAAI,EAAE,UAAU,CAAC,EAAE,aAAa,CAAC,MAAM,GAAG,aAAa,CAAC,GAAG,MAAM,CAoG9J;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,CAM7D;AA0ED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAM1E;AAeD;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,kBAAkB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACxC,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAC7B,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B;;;;;;;;;;;;OAYG;IACH,gBAAgB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAC9B;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,qFAAqF;IACrF,iBAAiB,CAAC,EAAE,OAAO,CAAA;CAC5B;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,MAAM,EACZ,kBAAkB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EACxC,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,EAC7B,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,GAC9B,MAAM,CAER;AAoPD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,EACtB,kBAAkB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EACxC,gBAAgB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAC7B,OAAO,CA8ET;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,EACZ,kBAAkB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,EACnD,GAAG,EAAE,eAAe,EACpB,UAAU,CAAC,EAAE,OAAO,EACpB,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,EAC7B,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,EAC/B,gBAAgB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAC7B,MAAM,CAeR;AA4RD;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,OAAO,CAiBpF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@barefootjs/jsx",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "JSX compiler for BarefootJS - transforms JSX to server HTML + client JS",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"directory": "packages/jsx"
|
|
50
50
|
},
|
|
51
51
|
"dependencies": {
|
|
52
|
-
"@barefootjs/shared": "0.
|
|
52
|
+
"@barefootjs/shared": "0.4.0"
|
|
53
53
|
},
|
|
54
54
|
"peerDependencies": {
|
|
55
55
|
"@barefootjs/client": ">=0.2.0",
|
|
@@ -201,3 +201,84 @@ describe('auto-defer brand-package reactive bindings (#1638)', () => {
|
|
|
201
201
|
expect(templateBody).toContain('data-count=')
|
|
202
202
|
})
|
|
203
203
|
})
|
|
204
|
+
|
|
205
|
+
describe('client hydrate template defers brand conditionals (#1645)', () => {
|
|
206
|
+
// The `template: (_p) => ...` lambda runs at module scope when the
|
|
207
|
+
// component is client-rendered via `createComponent` (not when hydrating
|
|
208
|
+
// existing SSR DOM). It cannot reproduce per-instance `createForm` state,
|
|
209
|
+
// so an auto-deferred conditional must emit empty cond markers — exactly
|
|
210
|
+
// like the SSR adapter — and let `init`'s `insert()` populate the branch.
|
|
211
|
+
|
|
212
|
+
test('non-inlinable createForm (onSubmit): no undefined.field, emits cond markers', () => {
|
|
213
|
+
const { templateBody } = compileWithBrand(`
|
|
214
|
+
'use client'
|
|
215
|
+
import { createForm } from './_form-defs'
|
|
216
|
+
|
|
217
|
+
export function SignupForm() {
|
|
218
|
+
const form = createForm({
|
|
219
|
+
onSubmit: async (data) => { await fetch('/signup', { method: 'POST', body: JSON.stringify(data) }) },
|
|
220
|
+
})
|
|
221
|
+
const email = form.field('email')
|
|
222
|
+
return (
|
|
223
|
+
<form>
|
|
224
|
+
<input value={email.value()} />
|
|
225
|
+
{email.error() && <p>{email.error()}</p>}
|
|
226
|
+
</form>
|
|
227
|
+
)
|
|
228
|
+
}
|
|
229
|
+
`)
|
|
230
|
+
|
|
231
|
+
// Never re-derive the form at module scope: `undefined.field(...)` throws.
|
|
232
|
+
expect(templateBody).not.toContain('undefined.field')
|
|
233
|
+
expect(templateBody).not.toContain('.field(')
|
|
234
|
+
// The deferred conditional collapses to the same empty markers SSR emits.
|
|
235
|
+
expect(templateBody).toMatch(/<!--bf-cond-start:s\d+--><!--bf-cond-end:s\d+-->/)
|
|
236
|
+
})
|
|
237
|
+
|
|
238
|
+
test('inlinable createForm (no onSubmit): no re-inlined createForm in template', () => {
|
|
239
|
+
const { templateBody } = compileWithBrand(`
|
|
240
|
+
'use client'
|
|
241
|
+
import { createForm } from './_form-defs'
|
|
242
|
+
|
|
243
|
+
export function SignupForm() {
|
|
244
|
+
const form = createForm({ defaultValues: { email: '' } })
|
|
245
|
+
const email = form.field('email')
|
|
246
|
+
return (
|
|
247
|
+
<form>
|
|
248
|
+
<input value={email.value()} />
|
|
249
|
+
{email.error() && <p>{email.error()}</p>}
|
|
250
|
+
</form>
|
|
251
|
+
)
|
|
252
|
+
}
|
|
253
|
+
`)
|
|
254
|
+
|
|
255
|
+
// A re-inlined `createForm({...})` would build a throwaway instance on
|
|
256
|
+
// every template render (error always '', never the live instance).
|
|
257
|
+
expect(templateBody).not.toContain('createForm(')
|
|
258
|
+
expect(templateBody).not.toContain('undefined.field')
|
|
259
|
+
expect(templateBody).toMatch(/<!--bf-cond-start:s\d+--><!--bf-cond-end:s\d+-->/)
|
|
260
|
+
})
|
|
261
|
+
|
|
262
|
+
test('init still wires the deferred conditional via insert()', () => {
|
|
263
|
+
const { initBody } = compileWithBrand(`
|
|
264
|
+
'use client'
|
|
265
|
+
import { createForm } from './_form-defs'
|
|
266
|
+
|
|
267
|
+
export function SignupForm() {
|
|
268
|
+
const form = createForm()
|
|
269
|
+
const email = form.field('email')
|
|
270
|
+
return (
|
|
271
|
+
<form>
|
|
272
|
+
<input value={email.value()} />
|
|
273
|
+
{email.error() && <p>{email.error()}</p>}
|
|
274
|
+
</form>
|
|
275
|
+
)
|
|
276
|
+
}
|
|
277
|
+
`)
|
|
278
|
+
|
|
279
|
+
// The reactive binding lives in init (where `email`/`form` are in scope),
|
|
280
|
+
// not in the module-scope template lambda.
|
|
281
|
+
expect(initBody).toMatch(/insert\(/)
|
|
282
|
+
expect(initBody).toContain('email.error()')
|
|
283
|
+
})
|
|
284
|
+
})
|
|
@@ -1040,6 +1040,14 @@ function irToComponentTemplateWithOpts(node: IRNode, opts: TemplateOptions): str
|
|
|
1040
1040
|
return `\${${transformExpr(node.expr, node.templateExpr)}}`
|
|
1041
1041
|
|
|
1042
1042
|
case 'conditional': {
|
|
1043
|
+
// A client-only conditional (auto-deferred brand read or manual
|
|
1044
|
+
// `/* @client */`) is owned by init's `insert()`, not the module-scope
|
|
1045
|
+
// template lambda. Match the SSR adapter: emit empty cond markers so
|
|
1046
|
+
// the client-render path (`createComponent`) produces the same DOM SSR
|
|
1047
|
+
// does, instead of evaluating an init-scope condition here (#1645).
|
|
1048
|
+
if (node.clientOnly && node.slotId) {
|
|
1049
|
+
return `<!--bf-cond-start:${node.slotId}--><!--bf-cond-end:${node.slotId}-->`
|
|
1050
|
+
}
|
|
1043
1051
|
const trueBranch = recurse(node.whenTrue)
|
|
1044
1052
|
const falseBranch = recurse(node.whenFalse)
|
|
1045
1053
|
const trueHtml = node.slotId ? addCondAttrToTemplate(trueBranch, node.slotId) : trueBranch
|
|
@@ -1418,6 +1426,15 @@ function generateCsrTemplateWithOpts(node: IRNode, opts: TemplateOptions): strin
|
|
|
1418
1426
|
}
|
|
1419
1427
|
|
|
1420
1428
|
case 'conditional': {
|
|
1429
|
+
// An auto-deferred conditional (e.g. `{form.field('x').error() && …}`)
|
|
1430
|
+
// reads per-instance init-scope state the module-scope template lambda
|
|
1431
|
+
// can't evaluate — re-deriving it here yields `undefined.field(...)` or
|
|
1432
|
+
// a throwaway re-inlined `createForm({...})`. Match the SSR adapter:
|
|
1433
|
+
// emit empty cond markers and let init's `insert()` populate the branch
|
|
1434
|
+
// at hydrate time via the reactive binding (#1645).
|
|
1435
|
+
if (node.clientOnly && node.slotId) {
|
|
1436
|
+
return `<!--bf-cond-start:${node.slotId}--><!--bf-cond-end:${node.slotId}-->`
|
|
1437
|
+
}
|
|
1421
1438
|
const trueBranch = recurse(node.whenTrue)
|
|
1422
1439
|
const falseBranch = recurse(node.whenFalse)
|
|
1423
1440
|
const trueHtml = node.slotId ? addCondAttrToTemplate(trueBranch, node.slotId) : trueBranch
|