@barefootjs/mojolicious 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/lib/BarefootJS/Backend/Mojo.pm +1 -1
- package/lib/Mojolicious/Plugin/BarefootJS/DevReload.pm +1 -1
- package/lib/Mojolicious/Plugin/BarefootJS.pm +1 -1
- package/package.json +5 -5
- package/src/render-divergences.ts +6 -0
- package/src/test-render.ts +36 -14
package/dist/index.js
CHANGED
|
@@ -1930,7 +1930,11 @@ var conformancePins = {
|
|
|
1930
1930
|
"rich-prop-client-read": [{ code: "BF049", severity: "error", issue: "https://github.com/piconic-ai/barefootjs/issues/2648" }]
|
|
1931
1931
|
};
|
|
1932
1932
|
// src/render-divergences.ts
|
|
1933
|
-
var renderDivergences = {
|
|
1933
|
+
var renderDivergences = {
|
|
1934
|
+
"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 `undef`; 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)",
|
|
1935
|
+
"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 Mojo::Template loop iterates the undef-seeded `todos` directly and Perl's strict vars abort the render instead of producing HTML",
|
|
1936
|
+
"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)"
|
|
1937
|
+
};
|
|
1934
1938
|
export {
|
|
1935
1939
|
renderDivergences,
|
|
1936
1940
|
mojoAdapter,
|
|
@@ -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
|
@@ -3916,6 +3916,38 @@ function classify(name, origin, expr, parsed, available) {
|
|
|
3916
3916
|
}
|
|
3917
3917
|
return { kind: "derived", name, origin, expr, parsed, frees: [...frees] };
|
|
3918
3918
|
}
|
|
3919
|
+
function localConstExprsByName(metadata) {
|
|
3920
|
+
const out = new Map;
|
|
3921
|
+
for (const c of metadata.localConstants ?? []) {
|
|
3922
|
+
if (c.isModule || c.declarationKind !== "const" || c.value === undefined)
|
|
3923
|
+
continue;
|
|
3924
|
+
out.set(c.name, c.parsed ?? parseExpression(c.value.trim()));
|
|
3925
|
+
}
|
|
3926
|
+
return out;
|
|
3927
|
+
}
|
|
3928
|
+
function resolveThroughLocalConsts(parsed, localConsts) {
|
|
3929
|
+
let current = parsed;
|
|
3930
|
+
const maxIter = localConsts.size + 1;
|
|
3931
|
+
for (let i = 0;i < maxIter; i++) {
|
|
3932
|
+
const frees = freeIdentifiers(current);
|
|
3933
|
+
if (frees === null)
|
|
3934
|
+
break;
|
|
3935
|
+
let changed = false;
|
|
3936
|
+
for (const name of frees) {
|
|
3937
|
+
const value = localConsts.get(name);
|
|
3938
|
+
if (!value)
|
|
3939
|
+
continue;
|
|
3940
|
+
const inlined = inlineBinding(current, name, value);
|
|
3941
|
+
if (inlined === null)
|
|
3942
|
+
continue;
|
|
3943
|
+
current = inlined;
|
|
3944
|
+
changed = true;
|
|
3945
|
+
}
|
|
3946
|
+
if (!changed)
|
|
3947
|
+
break;
|
|
3948
|
+
}
|
|
3949
|
+
return current;
|
|
3950
|
+
}
|
|
3919
3951
|
function computeSsrSeedPlan(metadata) {
|
|
3920
3952
|
const baseScope = metadata.propsParams.map((p) => p.name);
|
|
3921
3953
|
if (metadata.propsObjectName)
|
|
@@ -3924,6 +3956,7 @@ function computeSsrSeedPlan(metadata) {
|
|
|
3924
3956
|
baseScope.push(name);
|
|
3925
3957
|
}
|
|
3926
3958
|
const available = new Set(baseScope);
|
|
3959
|
+
const localConsts = localConstExprsByName(metadata);
|
|
3927
3960
|
const steps = [];
|
|
3928
3961
|
for (const signal of metadata.signals) {
|
|
3929
3962
|
if (signal.envReader) {
|
|
@@ -3935,13 +3968,13 @@ function computeSsrSeedPlan(metadata) {
|
|
|
3935
3968
|
}
|
|
3936
3969
|
}
|
|
3937
3970
|
const expr = signal.initialValue.trim();
|
|
3938
|
-
steps.push(expr === "" ? { kind: "opaque", name: signal.getter, origin: "signal" } : classify(signal.getter, "signal", expr, parseExpression(expr), available));
|
|
3971
|
+
steps.push(expr === "" ? { kind: "opaque", name: signal.getter, origin: "signal" } : classify(signal.getter, "signal", expr, resolveThroughLocalConsts(parseExpression(expr), localConsts), available));
|
|
3939
3972
|
available.add(signal.getter);
|
|
3940
3973
|
}
|
|
3941
3974
|
for (const memo of metadata.memos) {
|
|
3942
3975
|
const body = extractArrowBodyExpression(memo.computation);
|
|
3943
3976
|
const expr = body?.trim() ?? "";
|
|
3944
|
-
steps.push(expr === "" ? { kind: "opaque", name: memo.name, origin: "memo" } : classify(memo.name, "memo", expr, memo.parsed ?? parseExpression(expr), available));
|
|
3977
|
+
steps.push(expr === "" ? { kind: "opaque", name: memo.name, origin: "memo" } : classify(memo.name, "memo", expr, resolveThroughLocalConsts(memo.parsed ?? parseExpression(expr), localConsts), available));
|
|
3945
3978
|
available.add(memo.name);
|
|
3946
3979
|
}
|
|
3947
3980
|
return { baseScope, steps };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@barefootjs/mojolicious",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.32.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.
|
|
55
|
+
"@barefootjs/shared": "0.32.0"
|
|
56
56
|
},
|
|
57
57
|
"peerDependencies": {
|
|
58
58
|
"@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
|
"vite": "^6.0.0"
|
|
77
77
|
}
|
|
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 `undef`; 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 Mojo::Template loop iterates the undef-seeded `todos` directly and Perl's strict vars abort the render instead of producing HTML",
|
|
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
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Used by adapter-tests conformance runner.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import { compileJSX, extractSsrDefaults, deriveStashFromDefaults, augmentInheritedPropAccesses, importsSearchParams
|
|
8
|
+
import { compileJSX, extractSsrDefaults, deriveStashFromDefaults, augmentInheritedPropAccesses, importsSearchParams } from '@barefootjs/jsx'
|
|
9
9
|
import type { ComponentIR, SsrDefault } from '@barefootjs/jsx'
|
|
10
10
|
import { mkdir, rm } from 'node:fs/promises'
|
|
11
11
|
import { resolve } from 'node:path'
|
|
@@ -514,11 +514,35 @@ function buildChildDefaultsPerl(ir: ComponentIR): string {
|
|
|
514
514
|
// semantic divergence from those adapters.
|
|
515
515
|
for (const signal of ir.metadata.signals) {
|
|
516
516
|
if (signal.envReader) continue // env signal is the request reader, not a stashed value (#2057)
|
|
517
|
-
|
|
518
|
-
|
|
517
|
+
// #2669: a self-derivation collision (the signal's initializer derives
|
|
518
|
+
// from a same-named prop) gets a `propName`-carrying entry from
|
|
519
|
+
// `extractSsrDefaults` (see its docstring's invariant) — that entry
|
|
520
|
+
// MUST stay a hashref so `_derive_stash_from_defaults` resolves it
|
|
521
|
+
// against the REAL child props at runtime; the declared-prop loop above
|
|
522
|
+
// already emitted it for a DECLARED prop, so only an undeclared one
|
|
523
|
+
// needs adding here.
|
|
524
|
+
const d = ssrDefaults[signal.getter]
|
|
525
|
+
if (d?.propName !== undefined) {
|
|
526
|
+
if (!declared.has(signal.getter)) {
|
|
527
|
+
entries.push(`${signal.getter} => ${ssrDefaultEntryToPerl(d)}`)
|
|
528
|
+
declared.add(signal.getter)
|
|
529
|
+
}
|
|
530
|
+
continue
|
|
531
|
+
}
|
|
532
|
+
// Static manifest value only — no harness-side evaluation (#2696).
|
|
533
|
+
const value = d ? d.value : undefined
|
|
534
|
+
entries.push(`${signal.getter} => ${value !== undefined && value !== null ? toPerlLiteral(value) : 'undef'}`)
|
|
519
535
|
}
|
|
520
536
|
for (const memo of ir.metadata.memos) {
|
|
521
537
|
const entry = ssrDefaults[memo.name]
|
|
538
|
+
// #2669: same self-derivation handling as the signal loop above.
|
|
539
|
+
if (entry?.propName !== undefined) {
|
|
540
|
+
if (!declared.has(memo.name)) {
|
|
541
|
+
entries.push(`${memo.name} => ${ssrDefaultEntryToPerl(entry)}`)
|
|
542
|
+
declared.add(memo.name)
|
|
543
|
+
}
|
|
544
|
+
continue
|
|
545
|
+
}
|
|
522
546
|
const value = entry ? entry.value : undefined
|
|
523
547
|
entries.push(
|
|
524
548
|
`${memo.name} => ${value !== undefined && value !== null ? toPerlLiteral(value) : 'undef'}`,
|
|
@@ -718,22 +742,20 @@ function buildPerlProps(
|
|
|
718
742
|
// ternary) rather than skipping it — an unseeded getter faults strict
|
|
719
743
|
// vars with `Global symbol "$x" requires explicit package name`. Same
|
|
720
744
|
// rule `buildChildDefaultsPerl` applies to child signals (#1897).
|
|
745
|
+
// No initializer re-evaluation against raw props — production's
|
|
746
|
+
// before_render seeds only from `deriveStashFromDefaults` (#2696).
|
|
721
747
|
for (const signal of ir.metadata.signals) {
|
|
722
748
|
if (signal.envReader) continue // env signal bound below via search_params('') (#2057)
|
|
723
|
-
|
|
724
|
-
|
|
749
|
+
if (Object.prototype.hasOwnProperty.call(derivedProps, signal.getter)) {
|
|
750
|
+
entries.push(`${signal.getter} => ${toPerlLiteral(derivedProps[signal.getter])}`)
|
|
751
|
+
}
|
|
725
752
|
}
|
|
726
753
|
|
|
727
|
-
//
|
|
728
|
-
// manifest's `ssrDefaults` (see Plugin/BarefootJS.pm `before_render`
|
|
729
|
-
// hook), which carries the statically-evaluated result of each memo
|
|
730
|
-
// computation. Mirror that here so the test harness doesn't diverge
|
|
731
|
-
// from the plugin: hard-coding `0` masked memos with non-zero
|
|
732
|
-
// initial values until #1423 added a fixture that exposed the gap.
|
|
754
|
+
// No `?? 0` for entries the manifest lacks — production seeds nothing there (#2696).
|
|
733
755
|
for (const memo of ir.metadata.memos) {
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
756
|
+
if (Object.prototype.hasOwnProperty.call(derivedProps, memo.name)) {
|
|
757
|
+
entries.push(`${memo.name} => ${toPerlLiteral(derivedProps[memo.name])}`)
|
|
758
|
+
}
|
|
737
759
|
}
|
|
738
760
|
|
|
739
761
|
// (#1922) Request-scoped `searchParams()`: bind `$searchParams` to an
|