@barefootjs/mojolicious 0.35.1 → 0.35.3
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/adapter/expr/emitters.d.ts.map +1 -1
- package/dist/adapter/index.js +16 -4
- package/dist/adapter/props/prop-classes.d.ts +16 -0
- package/dist/adapter/props/prop-classes.d.ts.map +1 -1
- package/dist/index.js +16 -4
- package/dist/vite.js +33 -7
- 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/__tests__/mojo-adapter.test.ts +34 -0
- package/src/adapter/expr/emitters.ts +20 -6
- package/src/adapter/props/prop-classes.ts +23 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"emitters.d.ts","sourceRoot":"","sources":["../../../src/adapter/expr/emitters.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAGL,KAAK,iBAAiB,EAEtB,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,qBAAqB,EAC1B,KAAK,SAAS,EACd,KAAK,YAAY,EAMjB,KAAK,eAAe,EAIrB,MAAM,iBAAiB,CAAA;AAExB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;
|
|
1
|
+
{"version":3,"file":"emitters.d.ts","sourceRoot":"","sources":["../../../src/adapter/expr/emitters.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAGL,KAAK,iBAAiB,EAEtB,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,qBAAqB,EAC1B,KAAK,SAAS,EACd,KAAK,YAAY,EAMjB,KAAK,eAAe,EAIrB,MAAM,iBAAiB,CAAA;AAExB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAgEzD,qBAAa,iBAAkB,YAAW,iBAAiB;IASzD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAQ;IAC9B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqB;IAIjD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAwB;IAKrD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAA4C;IAE3E,YACE,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAChC,YAAY,GAAE,CAAC,CAAC,EAAE,MAAM,KAAK,OAAqB,EAClD,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,EAM3D;IAED,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAK/B;IAED,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,EAAE,WAAW,EAAE,WAAW,GAAG,MAAM,CAKjF;IAED,MAAM,CAAC,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAAG,MAAM,CAc5H;IAED,WAAW,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAAG,MAAM,CAE1F;IAED,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAAG,MAAM,CAMpF;IAED,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAAG,MAAM,CAS/E;IAED,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAAG,MAAM,CA4B/F;IAED,OAAO,CAAC,EAAE,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAAG,MAAM,CAM5G;IAED,cAAc,CACZ,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,UAAU,EAClB,KAAK,EAAE,OAAO,CAAC,UAAU,EAAE;QAAE,IAAI,EAAE,OAAO,CAAA;KAAE,CAAC,EAC7C,SAAS,EAAE,UAAU,EAAE,EACvB,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,CAgCR;IAED,YAAY,CAAC,QAAQ,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAAG,MAAM,CAQ5E;IAED,WAAW,CACT,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,UAAU,EAAE,EAClB,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,CAMR;IAED,UAAU,CACR,MAAM,EAAE,UAAU,EAClB,KAAK,EAAE,SAAS,GAAG;QAAE,IAAI,EAAE,UAAU,CAAA;KAAE,EACvC,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,CAER;IAED,WAAW,CAAC,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,GAAG,MAAM,CAEtF;IAED,eAAe,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,CAE9C;IAED,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAAG,MAAM,CAKpF;IAED,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAG1B;IAED,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAEjD;IAED,aAAa,CAAC,WAAW,EAAE,qBAAqB,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAAG,MAAM,CAM1G;CACF;AAED;;;;;;;;;;GAUG;AACH,qBAAa,mBAAoB,YAAW,iBAAiB;IAG3D,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAiB;IAErC,YAAY,GAAG,EAAE,eAAe,EAE/B;IAED;;;;;;;;OAQG;IACH,IAAI,QAAQ,IAAI,eAAe,CAkB9B;IAED,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAe/B;IAED,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,EAAE,WAAW,EAAE,WAAW,GAAG,MAAM,CAKjF;IAED,MAAM,CAAC,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAAG,MAAM,CAkC5H;IAED,WAAW,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAAG,MAAM,CAE1F;IAED,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAAG,MAAM,CA4CpF;IAED,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAAG,MAAM,CAK/E;IAED,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAAG,MAAM,CA8B/F;IAED,OAAO,CAAC,EAAE,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAAG,MAAM,CAM5G;IAED,cAAc,CACZ,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,UAAU,EAClB,KAAK,EAAE,OAAO,CAAC,UAAU,EAAE;QAAE,IAAI,EAAE,OAAO,CAAA;KAAE,CAAC,EAC7C,QAAQ,EAAE,UAAU,EAAE,EACtB,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,CAqER;IAED,OAAO,CAAC,eAAe;IAiDvB,YAAY,CAAC,QAAQ,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAAG,MAAM,CAO5E;IAED,WAAW,CACT,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,UAAU,EAAE,EAClB,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,CAER;IAED,UAAU,CACR,MAAM,EAAE,UAAU,EAClB,KAAK,EAAE,SAAS,GAAG;QAAE,IAAI,EAAE,UAAU,CAAA;KAAE,EACvC,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,CAER;IAED,WAAW,CACT,IAAI,EAAE,UAAU,EAChB,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,UAAU,EACrB,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,CAER;IAED,eAAe,CAAC,KAAK,EAAE,YAAY,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAAG,MAAM,CA6B9E;IAED,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAAG,MAAM,CAOpF;IAED,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAK1B;IAED,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAOjD;IAED,aAAa,CAAC,UAAU,EAAE,qBAAqB,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAAG,MAAM,CAoBxG;CACF"}
|
package/dist/adapter/index.js
CHANGED
|
@@ -381,6 +381,11 @@ var PREDICATE_METHODS = new Set([
|
|
|
381
381
|
"every",
|
|
382
382
|
"some"
|
|
383
383
|
]);
|
|
384
|
+
function flattenPropsMember(object, property) {
|
|
385
|
+
if (object.kind === "identifier" && object.name === "props")
|
|
386
|
+
return `$${property}`;
|
|
387
|
+
return null;
|
|
388
|
+
}
|
|
384
389
|
|
|
385
390
|
class MojoFilterEmitter {
|
|
386
391
|
param;
|
|
@@ -411,6 +416,9 @@ class MojoFilterEmitter {
|
|
|
411
416
|
return String(value);
|
|
412
417
|
}
|
|
413
418
|
member(object, property, _computed, _optional, emit) {
|
|
419
|
+
const flat = flattenPropsMember(object, property);
|
|
420
|
+
if (flat !== null)
|
|
421
|
+
return flat;
|
|
414
422
|
if (property === "length" && (asCallbackMethodCall(object) !== null || object.kind === "array-literal")) {
|
|
415
423
|
return `scalar(@{${emit(object)}})`;
|
|
416
424
|
}
|
|
@@ -561,9 +569,9 @@ class MojoTopLevelEmitter {
|
|
|
561
569
|
return String(value);
|
|
562
570
|
}
|
|
563
571
|
member(object, property, _computed, _optional, emit) {
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
572
|
+
const flat = flattenPropsMember(object, property);
|
|
573
|
+
if (flat !== null)
|
|
574
|
+
return flat;
|
|
567
575
|
if (object.kind === "identifier") {
|
|
568
576
|
const staticValue = this.ctx.resolveStaticRecordLiteral(object.name, property);
|
|
569
577
|
if (staticValue !== null)
|
|
@@ -969,7 +977,7 @@ function generateDerivedMemoSeed(ctx, ir) {
|
|
|
969
977
|
}
|
|
970
978
|
|
|
971
979
|
// src/adapter/props/prop-classes.ts
|
|
972
|
-
import { collectLoopBoundNames } from "@barefootjs/jsx";
|
|
980
|
+
import { collectLoopBoundNames, resolveBodyDestructuredPropAliases } from "@barefootjs/jsx";
|
|
973
981
|
|
|
974
982
|
// src/adapter/value/parsed-literal.ts
|
|
975
983
|
function isStringTypeInfo(type) {
|
|
@@ -1007,6 +1015,10 @@ function collectStringValueNames(ir) {
|
|
|
1007
1015
|
if (isStringTypeInfo(p.type))
|
|
1008
1016
|
names.add(p.name);
|
|
1009
1017
|
}
|
|
1018
|
+
for (const [local, callerKey] of resolveBodyDestructuredPropAliases(ir.metadata.localConstants ?? [], ir.metadata.propsObjectName)) {
|
|
1019
|
+
if (names.has(callerKey))
|
|
1020
|
+
names.add(local);
|
|
1021
|
+
}
|
|
1010
1022
|
for (const c of ir.metadata.localConstants) {
|
|
1011
1023
|
if (isStringTypeInfo(c.type ?? undefined) || isBareStringLiteral(c.value))
|
|
1012
1024
|
names.add(c.name);
|
|
@@ -59,6 +59,22 @@ export declare function collectNullableOptionalProps(ir: ComponentIR): Set<strin
|
|
|
59
59
|
* elsewhere in the component) but safe: the suppressed case just falls
|
|
60
60
|
* back to today's numeric `+` — the same, already-accepted residual as an
|
|
61
61
|
* unresolvable operand — never silently-wrong output.
|
|
62
|
+
*
|
|
63
|
+
* A bare-props-form component's BODY-destructured, RENAMED prop
|
|
64
|
+
* (`const { fallbackLabel: skipLabel } = props`, the #2788 alias family)
|
|
65
|
+
* has no `propsParams` entry of its own — `propsParams` only carries the
|
|
66
|
+
* TYPE-level, caller-facing names, and the local alias never appears
|
|
67
|
+
* there. Without the alias resolved here too, a string-typed prop
|
|
68
|
+
* referenced only under its local rename inside a filter predicate
|
|
69
|
+
* (`t => t.label !== skipLabel`) is invisible to this witness, so its
|
|
70
|
+
* equality lowers to numeric `!=` instead of `ne` — every row is
|
|
71
|
+
* dropped, since `'Alpha' != 'Alpha'` and `'Beta' != 'Alpha'` both
|
|
72
|
+
* numify to `0 != 0` (#2883). `resolveBodyDestructuredPropAliases`
|
|
73
|
+
* already recognizes this exact destructuring shape (built for #2788's
|
|
74
|
+
* top-level splice path); reusing it here keeps this one witness the
|
|
75
|
+
* single source of truth `MojoFilterEmitter`/`MojoTopLevelEmitter` both
|
|
76
|
+
* read via `_isStringValueName`, rather than growing a second, adapter-
|
|
77
|
+
* emitter-local alias lookup.
|
|
62
78
|
*/
|
|
63
79
|
export declare function collectStringValueNames(ir: ComponentIR): Set<string>;
|
|
64
80
|
//# sourceMappingURL=prop-classes.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prop-classes.d.ts","sourceRoot":"","sources":["../../../src/adapter/props/prop-classes.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"prop-classes.d.ts","sourceRoot":"","sources":["../../../src/adapter/props/prop-classes.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAA6D,KAAK,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAG7G;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,EAAE,EAAE,WAAW,GAAG,GAAG,CAAC,MAAM,CAAC,CAMrE;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,EAAE,EAAE,WAAW,GAAG,GAAG,CAAC,MAAM,CAAC,CAMrE;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,4BAA4B,CAAC,EAAE,EAAE,WAAW,GAAG,GAAG,CAAC,MAAM,CAAC,CAWzE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,WAAW,GAAG,GAAG,CAAC,MAAM,CAAC,CAqBpE"}
|
package/dist/index.js
CHANGED
|
@@ -381,6 +381,11 @@ var PREDICATE_METHODS = new Set([
|
|
|
381
381
|
"every",
|
|
382
382
|
"some"
|
|
383
383
|
]);
|
|
384
|
+
function flattenPropsMember(object, property) {
|
|
385
|
+
if (object.kind === "identifier" && object.name === "props")
|
|
386
|
+
return `$${property}`;
|
|
387
|
+
return null;
|
|
388
|
+
}
|
|
384
389
|
|
|
385
390
|
class MojoFilterEmitter {
|
|
386
391
|
param;
|
|
@@ -411,6 +416,9 @@ class MojoFilterEmitter {
|
|
|
411
416
|
return String(value);
|
|
412
417
|
}
|
|
413
418
|
member(object, property, _computed, _optional, emit) {
|
|
419
|
+
const flat = flattenPropsMember(object, property);
|
|
420
|
+
if (flat !== null)
|
|
421
|
+
return flat;
|
|
414
422
|
if (property === "length" && (asCallbackMethodCall(object) !== null || object.kind === "array-literal")) {
|
|
415
423
|
return `scalar(@{${emit(object)}})`;
|
|
416
424
|
}
|
|
@@ -561,9 +569,9 @@ class MojoTopLevelEmitter {
|
|
|
561
569
|
return String(value);
|
|
562
570
|
}
|
|
563
571
|
member(object, property, _computed, _optional, emit) {
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
572
|
+
const flat = flattenPropsMember(object, property);
|
|
573
|
+
if (flat !== null)
|
|
574
|
+
return flat;
|
|
567
575
|
if (object.kind === "identifier") {
|
|
568
576
|
const staticValue = this.ctx.resolveStaticRecordLiteral(object.name, property);
|
|
569
577
|
if (staticValue !== null)
|
|
@@ -969,7 +977,7 @@ function generateDerivedMemoSeed(ctx, ir) {
|
|
|
969
977
|
}
|
|
970
978
|
|
|
971
979
|
// src/adapter/props/prop-classes.ts
|
|
972
|
-
import { collectLoopBoundNames } from "@barefootjs/jsx";
|
|
980
|
+
import { collectLoopBoundNames, resolveBodyDestructuredPropAliases } from "@barefootjs/jsx";
|
|
973
981
|
|
|
974
982
|
// src/adapter/value/parsed-literal.ts
|
|
975
983
|
function isStringTypeInfo(type) {
|
|
@@ -1007,6 +1015,10 @@ function collectStringValueNames(ir) {
|
|
|
1007
1015
|
if (isStringTypeInfo(p.type))
|
|
1008
1016
|
names.add(p.name);
|
|
1009
1017
|
}
|
|
1018
|
+
for (const [local, callerKey] of resolveBodyDestructuredPropAliases(ir.metadata.localConstants ?? [], ir.metadata.propsObjectName)) {
|
|
1019
|
+
if (names.has(callerKey))
|
|
1020
|
+
names.add(local);
|
|
1021
|
+
}
|
|
1010
1022
|
for (const c of ir.metadata.localConstants) {
|
|
1011
1023
|
if (isStringTypeInfo(c.type ?? undefined) || isBareStringLiteral(c.value))
|
|
1012
1024
|
names.add(c.name);
|
package/dist/vite.js
CHANGED
|
@@ -2175,6 +2175,20 @@ function propsDestructureBinding(p) {
|
|
|
2175
2175
|
const binding = callerKey === localName ? localName : `${isIdentifierName(callerKey) ? callerKey : JSON.stringify(callerKey)}: ${localName}`;
|
|
2176
2176
|
return p.defaultValue ? `${binding} = ${p.defaultValue}` : binding;
|
|
2177
2177
|
}
|
|
2178
|
+
function resolveBodyDestructuredPropAliases(localConstants, propsObjectName) {
|
|
2179
|
+
const aliases = new Map;
|
|
2180
|
+
if (propsObjectName === null)
|
|
2181
|
+
return aliases;
|
|
2182
|
+
for (const c of localConstants) {
|
|
2183
|
+
if (c.isModule)
|
|
2184
|
+
continue;
|
|
2185
|
+
const m = c.parsed;
|
|
2186
|
+
if (m?.kind === "member" && !m.computed && m.object.kind === "identifier" && m.object.name === propsObjectName) {
|
|
2187
|
+
aliases.set(c.name, m.property);
|
|
2188
|
+
}
|
|
2189
|
+
}
|
|
2190
|
+
return aliases;
|
|
2191
|
+
}
|
|
2178
2192
|
var EMPTY_SET = new Set;
|
|
2179
2193
|
|
|
2180
2194
|
// ../jsx/src/ir-to-client-js/csr-substitute.ts
|
|
@@ -3421,8 +3435,11 @@ function matchSearchParamsMethodCall(callee, args, localNames) {
|
|
|
3421
3435
|
// ../jsx/src/ir-to-client-js/prune-unused-prop-extractions.ts
|
|
3422
3436
|
import ts19 from "typescript";
|
|
3423
3437
|
|
|
3424
|
-
// ../jsx/src/ir-to-client-js/
|
|
3438
|
+
// ../jsx/src/ir-to-client-js/emit-reactive.ts
|
|
3425
3439
|
import ts20 from "typescript";
|
|
3440
|
+
|
|
3441
|
+
// ../jsx/src/ir-to-client-js/control-flow/plan/lazy-preamble.ts
|
|
3442
|
+
import ts21 from "typescript";
|
|
3426
3443
|
var NO_PREAMBLE = {
|
|
3427
3444
|
lazySafe: true,
|
|
3428
3445
|
facts: { declaredNames: new Set, freeNames: new Set }
|
|
@@ -3471,9 +3488,6 @@ var INERT_BINDING_GLOBALS = new Set([
|
|
|
3471
3488
|
"decodeURI"
|
|
3472
3489
|
]);
|
|
3473
3490
|
|
|
3474
|
-
// ../jsx/src/ir-to-client-js/emit-reactive.ts
|
|
3475
|
-
import ts21 from "typescript";
|
|
3476
|
-
|
|
3477
3491
|
// ../jsx/src/ir-to-client-js/control-flow/stringify/event-delegation.ts
|
|
3478
3492
|
var NON_BUBBLING_EVENTS = new Set([
|
|
3479
3493
|
"blur",
|
|
@@ -5624,6 +5638,11 @@ var PREDICATE_METHODS = new Set([
|
|
|
5624
5638
|
"every",
|
|
5625
5639
|
"some"
|
|
5626
5640
|
]);
|
|
5641
|
+
function flattenPropsMember(object, property) {
|
|
5642
|
+
if (object.kind === "identifier" && object.name === "props")
|
|
5643
|
+
return `$${property}`;
|
|
5644
|
+
return null;
|
|
5645
|
+
}
|
|
5627
5646
|
|
|
5628
5647
|
class MojoFilterEmitter {
|
|
5629
5648
|
param;
|
|
@@ -5654,6 +5673,9 @@ class MojoFilterEmitter {
|
|
|
5654
5673
|
return String(value);
|
|
5655
5674
|
}
|
|
5656
5675
|
member(object, property, _computed, _optional, emit) {
|
|
5676
|
+
const flat = flattenPropsMember(object, property);
|
|
5677
|
+
if (flat !== null)
|
|
5678
|
+
return flat;
|
|
5657
5679
|
if (property === "length" && (asCallbackMethodCall(object) !== null || object.kind === "array-literal")) {
|
|
5658
5680
|
return `scalar(@{${emit(object)}})`;
|
|
5659
5681
|
}
|
|
@@ -5804,9 +5826,9 @@ class MojoTopLevelEmitter {
|
|
|
5804
5826
|
return String(value);
|
|
5805
5827
|
}
|
|
5806
5828
|
member(object, property, _computed, _optional, emit) {
|
|
5807
|
-
|
|
5808
|
-
|
|
5809
|
-
|
|
5829
|
+
const flat = flattenPropsMember(object, property);
|
|
5830
|
+
if (flat !== null)
|
|
5831
|
+
return flat;
|
|
5810
5832
|
if (object.kind === "identifier") {
|
|
5811
5833
|
const staticValue = this.ctx.resolveStaticRecordLiteral(object.name, property);
|
|
5812
5834
|
if (staticValue !== null)
|
|
@@ -6242,6 +6264,10 @@ function collectStringValueNames(ir) {
|
|
|
6242
6264
|
if (isStringTypeInfo(p.type))
|
|
6243
6265
|
names.add(p.name);
|
|
6244
6266
|
}
|
|
6267
|
+
for (const [local, callerKey] of resolveBodyDestructuredPropAliases(ir.metadata.localConstants ?? [], ir.metadata.propsObjectName)) {
|
|
6268
|
+
if (names.has(callerKey))
|
|
6269
|
+
names.add(local);
|
|
6270
|
+
}
|
|
6245
6271
|
for (const c of ir.metadata.localConstants) {
|
|
6246
6272
|
if (isStringTypeInfo(c.type ?? undefined) || isBareStringLiteral(c.value))
|
|
6247
6273
|
names.add(c.name);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@barefootjs/mojolicious",
|
|
3
|
-
"version": "0.35.
|
|
3
|
+
"version": "0.35.3",
|
|
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.35.
|
|
55
|
+
"@barefootjs/shared": "0.35.3"
|
|
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.35.
|
|
74
|
-
"@barefootjs/vite": "0.35.
|
|
75
|
-
"@barefootjs/client": "0.35.
|
|
73
|
+
"@barefootjs/jsx": "0.35.3",
|
|
74
|
+
"@barefootjs/vite": "0.35.3",
|
|
75
|
+
"@barefootjs/client": "0.35.3",
|
|
76
76
|
"vite": "^6.0.0"
|
|
77
77
|
}
|
|
78
78
|
}
|
|
@@ -733,6 +733,40 @@ export function L() {
|
|
|
733
733
|
expect(result.template).not.toContain('$sel eq $t->{n}')
|
|
734
734
|
})
|
|
735
735
|
|
|
736
|
+
test('compares a filter predicate against a renamed body-destructured prop with Perl `ne`, not numeric `!=` (#2883)', () => {
|
|
737
|
+
// `MojoFilterEmitter.identifier()` correctly resolves `skipLabel` to
|
|
738
|
+
// `$skipLabel` (Mojo seeds/derives that stash key for the #2788 alias
|
|
739
|
+
// family, same as the top-level splice path) — the actual bug was
|
|
740
|
+
// `collectStringValueNames`'s witness for `eq`/`ne` vs `==`/`!=` not
|
|
741
|
+
// knowing about body-destructured RENAMED props, so this comparison
|
|
742
|
+
// fell through to numeric `!=`. `'Alpha' != 'Alpha'` and
|
|
743
|
+
// `'Beta' != 'Alpha'` both numify to `0 != 0` — every row was
|
|
744
|
+
// filtered out regardless of the real string value.
|
|
745
|
+
const result = compileAndGenerate(`
|
|
746
|
+
"use client"
|
|
747
|
+
import { createSignal } from "@barefootjs/client"
|
|
748
|
+
|
|
749
|
+
type Todo = { id: number; label: string }
|
|
750
|
+
|
|
751
|
+
export function FilterPredicateRenamedProp(props: { fallbackLabel: string }) {
|
|
752
|
+
const { fallbackLabel: skipLabel } = props
|
|
753
|
+
const [todos] = createSignal<Todo[]>([
|
|
754
|
+
{ id: 1, label: 'Alpha' },
|
|
755
|
+
{ id: 2, label: 'Beta' },
|
|
756
|
+
])
|
|
757
|
+
return (
|
|
758
|
+
<ul>
|
|
759
|
+
{todos().filter(t => t.label !== skipLabel).map(t => (
|
|
760
|
+
<li key={t.id}>{t.label}</li>
|
|
761
|
+
))}
|
|
762
|
+
</ul>
|
|
763
|
+
)
|
|
764
|
+
}
|
|
765
|
+
`)
|
|
766
|
+
expect(result.template).toContain('$t->{label} ne $skipLabel')
|
|
767
|
+
expect(result.template).not.toContain('$t->{label} != $skipLabel')
|
|
768
|
+
})
|
|
769
|
+
|
|
736
770
|
test('generates script registration for client components', () => {
|
|
737
771
|
const result = compileAndGenerate(`
|
|
738
772
|
"use client"
|
|
@@ -81,6 +81,22 @@ const PREDICATE_METHODS: ReadonlySet<string> = new Set([
|
|
|
81
81
|
'filter', 'find', 'findIndex', 'findLast', 'findLastIndex', 'every', 'some',
|
|
82
82
|
])
|
|
83
83
|
|
|
84
|
+
/**
|
|
85
|
+
* `props.x` on a bare-props-form component flattens to the bare `$x` the
|
|
86
|
+
* Mojo SSR caller binds each prop to (props arrive as individual `my $x`
|
|
87
|
+
* vars, not a `$props` hashref). Single door for BOTH `member()` emitters
|
|
88
|
+
* below (#2886) — `MojoFilterEmitter` lacked this decision entirely
|
|
89
|
+
* (#2879's cross-adapter follow-up), silently reaching `$props->{x}`, a
|
|
90
|
+
* Perl variable never declared under `use strict`. Returns null for any
|
|
91
|
+
* other receiver so callers fall through to their generic member
|
|
92
|
+
* lowering — `props.a.b` flattens only the inner hop, then the caller's
|
|
93
|
+
* own recursion appends `.b`.
|
|
94
|
+
*/
|
|
95
|
+
function flattenPropsMember(object: ParsedExpr, property: string): string | null {
|
|
96
|
+
if (object.kind === 'identifier' && object.name === 'props') return `$${property}`
|
|
97
|
+
return null
|
|
98
|
+
}
|
|
99
|
+
|
|
84
100
|
export class MojoFilterEmitter implements ParsedExprEmitter {
|
|
85
101
|
// Plain field declarations + assignment, NOT TS constructor-parameter-
|
|
86
102
|
// property shorthand: Vite's `bundleConfigFile` externalizes any bare
|
|
@@ -129,6 +145,8 @@ export class MojoFilterEmitter implements ParsedExprEmitter {
|
|
|
129
145
|
}
|
|
130
146
|
|
|
131
147
|
member(object: ParsedExpr, property: string, _computed: boolean, _optional: boolean, emit: (e: ParsedExpr) => string): string {
|
|
148
|
+
const flat = flattenPropsMember(object, property)
|
|
149
|
+
if (flat !== null) return flat
|
|
132
150
|
// `.length` on a higher-order result (e.g.
|
|
133
151
|
// `x.tags.filter(t => t.active).length > 0` inside the outer
|
|
134
152
|
// filter predicate, #1443). The higher-order emit produces an
|
|
@@ -381,12 +399,8 @@ export class MojoTopLevelEmitter implements ParsedExprEmitter {
|
|
|
381
399
|
}
|
|
382
400
|
|
|
383
401
|
member(object: ParsedExpr, property: string, _computed: boolean, _optional: boolean, emit: (e: ParsedExpr) => string): string {
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
// `$props` hashref).
|
|
387
|
-
if (object.kind === 'identifier' && object.name === 'props') {
|
|
388
|
-
return `$${property}`
|
|
389
|
-
}
|
|
402
|
+
const flat = flattenPropsMember(object, property)
|
|
403
|
+
if (flat !== null) return flat
|
|
390
404
|
// Static property access on a module object-literal const
|
|
391
405
|
// (`variantClasses.ghost`, #1897) resolves at compile time — the
|
|
392
406
|
// generic hash lowering below would dereference a Perl var that
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* adapter's `props/prop-types.ts`. No adapter instance state.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import { collectLoopBoundNames, type ComponentIR } from '@barefootjs/jsx'
|
|
10
|
+
import { collectLoopBoundNames, resolveBodyDestructuredPropAliases, type ComponentIR } from '@barefootjs/jsx'
|
|
11
11
|
import { isStringTypeInfo, isBareStringLiteral } from '../value/parsed-literal.ts'
|
|
12
12
|
|
|
13
13
|
/**
|
|
@@ -88,6 +88,22 @@ export function collectNullableOptionalProps(ir: ComponentIR): Set<string> {
|
|
|
88
88
|
* elsewhere in the component) but safe: the suppressed case just falls
|
|
89
89
|
* back to today's numeric `+` — the same, already-accepted residual as an
|
|
90
90
|
* unresolvable operand — never silently-wrong output.
|
|
91
|
+
*
|
|
92
|
+
* A bare-props-form component's BODY-destructured, RENAMED prop
|
|
93
|
+
* (`const { fallbackLabel: skipLabel } = props`, the #2788 alias family)
|
|
94
|
+
* has no `propsParams` entry of its own — `propsParams` only carries the
|
|
95
|
+
* TYPE-level, caller-facing names, and the local alias never appears
|
|
96
|
+
* there. Without the alias resolved here too, a string-typed prop
|
|
97
|
+
* referenced only under its local rename inside a filter predicate
|
|
98
|
+
* (`t => t.label !== skipLabel`) is invisible to this witness, so its
|
|
99
|
+
* equality lowers to numeric `!=` instead of `ne` — every row is
|
|
100
|
+
* dropped, since `'Alpha' != 'Alpha'` and `'Beta' != 'Alpha'` both
|
|
101
|
+
* numify to `0 != 0` (#2883). `resolveBodyDestructuredPropAliases`
|
|
102
|
+
* already recognizes this exact destructuring shape (built for #2788's
|
|
103
|
+
* top-level splice path); reusing it here keeps this one witness the
|
|
104
|
+
* single source of truth `MojoFilterEmitter`/`MojoTopLevelEmitter` both
|
|
105
|
+
* read via `_isStringValueName`, rather than growing a second, adapter-
|
|
106
|
+
* emitter-local alias lookup.
|
|
91
107
|
*/
|
|
92
108
|
export function collectStringValueNames(ir: ComponentIR): Set<string> {
|
|
93
109
|
const names = new Set<string>()
|
|
@@ -99,6 +115,12 @@ export function collectStringValueNames(ir: ComponentIR): Set<string> {
|
|
|
99
115
|
for (const p of ir.metadata.propsParams) {
|
|
100
116
|
if (isStringTypeInfo(p.type)) names.add(p.name)
|
|
101
117
|
}
|
|
118
|
+
for (const [local, callerKey] of resolveBodyDestructuredPropAliases(
|
|
119
|
+
ir.metadata.localConstants ?? [],
|
|
120
|
+
ir.metadata.propsObjectName,
|
|
121
|
+
)) {
|
|
122
|
+
if (names.has(callerKey)) names.add(local)
|
|
123
|
+
}
|
|
102
124
|
for (const c of ir.metadata.localConstants) {
|
|
103
125
|
if (isStringTypeInfo(c.type ?? undefined) || isBareStringLiteral(c.value)) names.add(c.name)
|
|
104
126
|
}
|