@barefootjs/jinja 0.31.9 → 0.32.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 +5 -1
- package/dist/render-divergences.d.ts.map +1 -1
- package/dist/vite.js +35 -2
- package/package.json +5 -5
- package/src/render-divergences.ts +6 -0
- package/src/test-render.ts +9 -10
package/dist/index.js
CHANGED
|
@@ -189254,7 +189254,11 @@ var conformancePins = {
|
|
|
189254
189254
|
"rich-prop-client-read": [{ code: "BF049", severity: "error", issue: "https://github.com/piconic-ai/barefootjs/issues/2648" }]
|
|
189255
189255
|
};
|
|
189256
189256
|
// src/render-divergences.ts
|
|
189257
|
-
var renderDivergences = {
|
|
189257
|
+
var renderDivergences = {
|
|
189258
|
+
"todo-app": "the `todos` signal seeds from `(props.initialTodos ?? []).map(t => ({ ...t, editing: false }))` — a different-prop-derived `.map()` chain `extractSsrDefaults` cannot statically resolve, and `computeSsrSeedPlan` classifies it opaque (no in-template recompute), so it seeds `None`; the non-`/* @client */`-marked `{todos().length > 0 && ...}` toggle-all block SSRs as if there are zero todos regardless of `initialTodos` (https://github.com/piconic-ai/barefootjs/issues/2696)",
|
|
189259
|
+
"todo-app-ssr": "same root cause as `todo-app` (https://github.com/piconic-ai/barefootjs/issues/2696), but this fixture's todo-list loop carries no `/* @client */` marker — the compiled `{% for todo in todos %}` iterates the null-seeded `todos` directly and Jinja2 raises `TypeError: 'NoneType' object is not iterable` instead of rendering",
|
|
189260
|
+
"callback-param-shadows-prop": "the `first` signal seeds from `[{ a: 'p' }].map((title) => title.a).join(',')` — a constant expression `extractSsrDefaults` still cannot statically resolve (`.map()` is unsupported for any receiver) and, unlike the sibling `joined` memo's structurally similar chain, gets no in-template recompute (`computeSsrSeedPlan` classifies it opaque too); `<span>{first()}</span>` SSRs empty instead of `p` (https://github.com/piconic-ai/barefootjs/issues/2696)"
|
|
189261
|
+
};
|
|
189258
189262
|
export {
|
|
189259
189263
|
renderDivergences,
|
|
189260
189264
|
jinjaAdapter,
|
|
@@ -1 +1 @@
|
|
|
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,
|
|
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,iBAO/B,CAAA"}
|
package/dist/vite.js
CHANGED
|
@@ -3968,6 +3968,38 @@ function classify(name, origin, expr, parsed, available) {
|
|
|
3968
3968
|
}
|
|
3969
3969
|
return { kind: "derived", name, origin, expr, parsed, frees: [...frees] };
|
|
3970
3970
|
}
|
|
3971
|
+
function localConstExprsByName(metadata) {
|
|
3972
|
+
const out = new Map;
|
|
3973
|
+
for (const c of metadata.localConstants ?? []) {
|
|
3974
|
+
if (c.isModule || c.declarationKind !== "const" || c.value === undefined)
|
|
3975
|
+
continue;
|
|
3976
|
+
out.set(c.name, c.parsed ?? parseExpression(c.value.trim()));
|
|
3977
|
+
}
|
|
3978
|
+
return out;
|
|
3979
|
+
}
|
|
3980
|
+
function resolveThroughLocalConsts(parsed, localConsts) {
|
|
3981
|
+
let current = parsed;
|
|
3982
|
+
const maxIter = localConsts.size + 1;
|
|
3983
|
+
for (let i = 0;i < maxIter; i++) {
|
|
3984
|
+
const frees = freeIdentifiers(current);
|
|
3985
|
+
if (frees === null)
|
|
3986
|
+
break;
|
|
3987
|
+
let changed = false;
|
|
3988
|
+
for (const name of frees) {
|
|
3989
|
+
const value = localConsts.get(name);
|
|
3990
|
+
if (!value)
|
|
3991
|
+
continue;
|
|
3992
|
+
const inlined = inlineBinding(current, name, value);
|
|
3993
|
+
if (inlined === null)
|
|
3994
|
+
continue;
|
|
3995
|
+
current = inlined;
|
|
3996
|
+
changed = true;
|
|
3997
|
+
}
|
|
3998
|
+
if (!changed)
|
|
3999
|
+
break;
|
|
4000
|
+
}
|
|
4001
|
+
return current;
|
|
4002
|
+
}
|
|
3971
4003
|
function computeSsrSeedPlan(metadata) {
|
|
3972
4004
|
const baseScope = metadata.propsParams.map((p) => p.name);
|
|
3973
4005
|
if (metadata.propsObjectName)
|
|
@@ -3976,6 +4008,7 @@ function computeSsrSeedPlan(metadata) {
|
|
|
3976
4008
|
baseScope.push(name);
|
|
3977
4009
|
}
|
|
3978
4010
|
const available = new Set(baseScope);
|
|
4011
|
+
const localConsts = localConstExprsByName(metadata);
|
|
3979
4012
|
const steps = [];
|
|
3980
4013
|
for (const signal of metadata.signals) {
|
|
3981
4014
|
if (signal.envReader) {
|
|
@@ -3987,13 +4020,13 @@ function computeSsrSeedPlan(metadata) {
|
|
|
3987
4020
|
}
|
|
3988
4021
|
}
|
|
3989
4022
|
const expr = signal.initialValue.trim();
|
|
3990
|
-
steps.push(expr === "" ? { kind: "opaque", name: signal.getter, origin: "signal" } : classify(signal.getter, "signal", expr, parseExpression(expr), available));
|
|
4023
|
+
steps.push(expr === "" ? { kind: "opaque", name: signal.getter, origin: "signal" } : classify(signal.getter, "signal", expr, resolveThroughLocalConsts(parseExpression(expr), localConsts), available));
|
|
3991
4024
|
available.add(signal.getter);
|
|
3992
4025
|
}
|
|
3993
4026
|
for (const memo of metadata.memos) {
|
|
3994
4027
|
const body = extractArrowBodyExpression(memo.computation);
|
|
3995
4028
|
const expr = body?.trim() ?? "";
|
|
3996
|
-
steps.push(expr === "" ? { kind: "opaque", name: memo.name, origin: "memo" } : classify(memo.name, "memo", expr, memo.parsed ?? parseExpression(expr), available));
|
|
4029
|
+
steps.push(expr === "" ? { kind: "opaque", name: memo.name, origin: "memo" } : classify(memo.name, "memo", expr, resolveThroughLocalConsts(memo.parsed ?? parseExpression(expr), localConsts), available));
|
|
3997
4030
|
available.add(memo.name);
|
|
3998
4031
|
}
|
|
3999
4032
|
return { baseScope, steps };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@barefootjs/jinja",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.32.0",
|
|
4
4
|
"description": "Jinja2 adapter for BarefootJS — compiles IR to .jinja templates and ships the Python BarefootJS rendering runtime; runs under any Python web framework (Flask, etc.)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"directory": "packages/adapter-jinja"
|
|
54
54
|
},
|
|
55
55
|
"dependencies": {
|
|
56
|
-
"@barefootjs/shared": "0.
|
|
56
|
+
"@barefootjs/shared": "0.32.0"
|
|
57
57
|
},
|
|
58
58
|
"peerDependencies": {
|
|
59
59
|
"@barefootjs/jsx": ">=0.2.0",
|
|
@@ -70,9 +70,9 @@
|
|
|
70
70
|
},
|
|
71
71
|
"devDependencies": {
|
|
72
72
|
"@barefootjs/adapter-tests": "0.1.0",
|
|
73
|
-
"@barefootjs/jsx": "0.
|
|
74
|
-
"@barefootjs/vite": "0.
|
|
75
|
-
"@barefootjs/client": "0.
|
|
73
|
+
"@barefootjs/jsx": "0.32.0",
|
|
74
|
+
"@barefootjs/vite": "0.32.0",
|
|
75
|
+
"@barefootjs/client": "0.32.0",
|
|
76
76
|
"typescript": "^5.0.0",
|
|
77
77
|
"vite": "^6.0.0"
|
|
78
78
|
}
|
|
@@ -10,4 +10,10 @@
|
|
|
10
10
|
import type { RenderDivergences } from '@barefootjs/jsx'
|
|
11
11
|
|
|
12
12
|
export const renderDivergences: RenderDivergences = {
|
|
13
|
+
'todo-app':
|
|
14
|
+
'the `todos` signal seeds from `(props.initialTodos ?? []).map(t => ({ ...t, editing: false }))` — a different-prop-derived `.map()` chain `extractSsrDefaults` cannot statically resolve, and `computeSsrSeedPlan` classifies it opaque (no in-template recompute), so it seeds `None`; the non-`/* @client */`-marked `{todos().length > 0 && ...}` toggle-all block SSRs as if there are zero todos regardless of `initialTodos` (https://github.com/piconic-ai/barefootjs/issues/2696)',
|
|
15
|
+
'todo-app-ssr':
|
|
16
|
+
'same root cause as `todo-app` (https://github.com/piconic-ai/barefootjs/issues/2696), but this fixture\'s todo-list loop carries no `/* @client */` marker — the compiled `{% for todo in todos %}` iterates the null-seeded `todos` directly and Jinja2 raises `TypeError: \'NoneType\' object is not iterable` instead of rendering',
|
|
17
|
+
'callback-param-shadows-prop':
|
|
18
|
+
"the `first` signal seeds from `[{ a: 'p' }].map((title) => title.a).join(',')` — a constant expression `extractSsrDefaults` still cannot statically resolve (`.map()` is unsupported for any receiver) and, unlike the sibling `joined` memo's structurally similar chain, gets no in-template recompute (`computeSsrSeedPlan` classifies it opaque too); `<span>{first()}</span>` SSRs empty instead of `p` (https://github.com/piconic-ai/barefootjs/issues/2696)",
|
|
13
19
|
}
|
package/src/test-render.ts
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* generated render script (Python, not Perl) and its literal syntax differ.
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
-
import { compileJSX, extractSsrDefaults, deriveStashFromDefaults, importsSearchParams
|
|
19
|
+
import { compileJSX, extractSsrDefaults, deriveStashFromDefaults, importsSearchParams } from '@barefootjs/jsx'
|
|
20
20
|
import type { ComponentIR, SsrDefault } from '@barefootjs/jsx'
|
|
21
21
|
import { mkdir, rm } from 'node:fs/promises'
|
|
22
22
|
import { resolve } from 'node:path'
|
|
@@ -595,23 +595,22 @@ function buildPythonProps(
|
|
|
595
595
|
const explicitScope = typeof props?.__instanceId === 'string' ? props.__instanceId : 'test'
|
|
596
596
|
const fullEntries = [...entries, `${pyStr('scope_id')}: ${pyStr(explicitScope)}`]
|
|
597
597
|
|
|
598
|
-
//
|
|
598
|
+
// No initializer re-evaluation against raw props — production's
|
|
599
|
+
// before_render seeds only from `deriveStashFromDefaults` (#2696).
|
|
599
600
|
for (const signal of ir.metadata.signals) {
|
|
600
601
|
// Env signals (#2057) are bound below via `SearchParams('')`, not from a
|
|
601
602
|
// static initial value.
|
|
602
603
|
if (signal.envReader) continue
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
fullEntries.push(`${pyStr(signal.getter)}: ${toPyLiteral(value)}`)
|
|
604
|
+
if (Object.prototype.hasOwnProperty.call(derivedProps, signal.getter)) {
|
|
605
|
+
fullEntries.push(`${pyStr(signal.getter)}: ${toPyLiteral(derivedProps[signal.getter])}`)
|
|
606
606
|
}
|
|
607
607
|
}
|
|
608
608
|
|
|
609
|
-
//
|
|
610
|
-
// as the production plugin's before_render hook.
|
|
609
|
+
// No `?? 0` for entries the manifest lacks — production seeds nothing there (#2696).
|
|
611
610
|
for (const memo of ir.metadata.memos) {
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
611
|
+
if (Object.prototype.hasOwnProperty.call(derivedProps, memo.name)) {
|
|
612
|
+
fullEntries.push(`${pyStr(memo.name)}: ${toPyLiteral(derivedProps[memo.name])}`)
|
|
613
|
+
}
|
|
615
614
|
}
|
|
616
615
|
|
|
617
616
|
// (#1922) Request-scoped `searchParams()`: bind `searchParams` to an
|