@barefootjs/xslate 0.33.6 → 0.35.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/adapter/emit-context.d.ts +11 -1
- package/dist/adapter/emit-context.d.ts.map +1 -1
- package/dist/adapter/expr/emitters.d.ts +11 -1
- package/dist/adapter/expr/emitters.d.ts.map +1 -1
- package/dist/adapter/index.js +28 -22
- package/dist/adapter/xslate-adapter.d.ts +3 -0
- package/dist/adapter/xslate-adapter.d.ts.map +1 -1
- package/dist/conformance-pins.d.ts.map +1 -1
- package/dist/index.js +29 -25
- package/dist/render-divergences.d.ts.map +1 -1
- package/dist/vite.js +119 -72
- package/lib/BarefootJS/Backend/Xslate.pm +1 -1
- package/package.json +5 -5
- package/src/__tests__/xslate-adapter.test.ts +2 -2
- package/src/adapter/emit-context.ts +12 -1
- package/src/adapter/expr/emitters.ts +33 -0
- package/src/adapter/xslate-adapter.ts +34 -43
- package/src/conformance-pins.ts +4 -0
- package/src/render-divergences.ts +1 -4
- package/src/test-render.ts +20 -0
|
@@ -17,13 +17,23 @@
|
|
|
17
17
|
* genuinely needs it, so the seam documents the real cross-module coupling
|
|
18
18
|
* rather than re-exposing the whole adapter.
|
|
19
19
|
*/
|
|
20
|
-
import type { ParsedExpr, CompilerError, IRMetadata } from '@barefootjs/jsx';
|
|
20
|
+
import type { ParsedExpr, CompilerError, IRMetadata, LoweringMatcher } from '@barefootjs/jsx';
|
|
21
21
|
export interface XslateEmitContext {
|
|
22
22
|
/**
|
|
23
23
|
* (#1922) Local binding names the request-scoped `searchParams()` env signal
|
|
24
24
|
* is imported under. Non-empty enables the env-signal method-call lowering.
|
|
25
25
|
*/
|
|
26
26
|
readonly _searchParamsLocals: Set<string>;
|
|
27
|
+
/**
|
|
28
|
+
* Registered lowering-plugin matchers (#2057), bound to this component's
|
|
29
|
+
* metadata at init. Read by `XslateTopLevelEmitter`'s `lowering` seam
|
|
30
|
+
* (#2843) so a registered call — the built-in `queryHref`, or any
|
|
31
|
+
* userland plugin — is recognised no matter where it sits in an
|
|
32
|
+
* expression tree (a ternary branch, a template-literal interpolation, …),
|
|
33
|
+
* not only when it's the call the adapter's own top-level conversion
|
|
34
|
+
* entry point (`convertExpressionToKolon`) is asked to lower directly.
|
|
35
|
+
*/
|
|
36
|
+
readonly _loweringMatchers: readonly LoweringMatcher[];
|
|
27
37
|
/**
|
|
28
38
|
* Inline a module-scope pure string-literal const by name as the resolved
|
|
29
39
|
* literal value, or null when the name is not such a const.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"emit-context.d.ts","sourceRoot":"","sources":["../../src/adapter/emit-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;
|
|
1
|
+
{"version":3,"file":"emit-context.d.ts","sourceRoot":"","sources":["../../src/adapter/emit-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAE7F,MAAM,WAAW,iBAAiB;IAChC;;;OAGG;IACH,QAAQ,CAAC,mBAAmB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAEzC;;;;;;;;OAQG;IACH,QAAQ,CAAC,iBAAiB,EAAE,SAAS,eAAe,EAAE,CAAA;IAEtD;;;OAGG;IACH,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;IAEtD,oFAAoF;IACpF,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;IAEjD;;;OAGG;IACH,2BAA2B,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;IAE3E,uEAAuE;IACvE,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAA;IAEzC,wDAAwD;IACxD,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAExD,yEAAyE;IACzE,4BAA4B,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;CACtE;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,mBAAmB;IAClC,uDAAuD;IACvD,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAE9B,kEAAkE;IAClE,QAAQ,CAAC,MAAM,EAAE,aAAa,EAAE,CAAA;IAEhC,0EAA0E;IAC1E,QAAQ,CAAC,cAAc,EAAE,UAAU,CAAC,gBAAgB,CAAC,CAAA;IAErD,sEAAsE;IACtE,QAAQ,CAAC,WAAW,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IAExC;;;;;;;;;OASG;IACH,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,UAAU,GAAG,MAAM,CAAA;CACvE;AAED;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;;;;;;;;;;OAYG;IACH,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,UAAU,EAAE,GAAG,CAAC,EAAE,UAAU,GAAG,OAAO,GAAG,MAAM,CAAA;CACnG"}
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* - `XslateTopLevelEmitter` — top-level / per-render-var context; depends on
|
|
11
11
|
* the adapter only through the narrow `XslateEmitContext` seam.
|
|
12
12
|
*/
|
|
13
|
-
import { type ParsedExprEmitter, type ArrayMethod, type LiteralType, type ParsedExpr, type ObjectLiteralProperty, type FlatDepth, type TemplatePart } from '@barefootjs/jsx';
|
|
13
|
+
import { type ParsedExprEmitter, type LoweringEmitter, type ArrayMethod, type LiteralType, type ParsedExpr, type ObjectLiteralProperty, type FlatDepth, type TemplatePart } from '@barefootjs/jsx';
|
|
14
14
|
import type { XslateEmitContext } from '../emit-context.ts';
|
|
15
15
|
/**
|
|
16
16
|
* Lowering for the predicate body of a filter / every / some / find, plus the
|
|
@@ -63,6 +63,16 @@ export declare class XslateFilterEmitter implements ParsedExprEmitter {
|
|
|
63
63
|
export declare class XslateTopLevelEmitter implements ParsedExprEmitter {
|
|
64
64
|
private readonly ctx;
|
|
65
65
|
constructor(ctx: XslateEmitContext);
|
|
66
|
+
/**
|
|
67
|
+
* Registered-lowering seam (#2843): `emitParsedExpr`'s shared `call` case
|
|
68
|
+
* tries every matcher here BEFORE `call()` itself, so a registered call
|
|
69
|
+
* (the built-in `queryHref`, or any userland plugin) is recognised no
|
|
70
|
+
* matter where it sits in the tree. `render` is what used to live inline
|
|
71
|
+
* in `XslateAdapter.convertExpressionToKolon` before the object-literal
|
|
72
|
+
* support-gate refusal (`checkSupport`'s `call` arm, now itself
|
|
73
|
+
* registry-aware) made the pre-gate special case unnecessary.
|
|
74
|
+
*/
|
|
75
|
+
get lowering(): LoweringEmitter;
|
|
66
76
|
identifier(name: string): string;
|
|
67
77
|
literal(value: string | number | boolean | null, literalType: LiteralType): string;
|
|
68
78
|
member(object: ParsedExpr, property: string, _computed: boolean, _optional: boolean, emit: (e: ParsedExpr) => string): string;
|
|
@@ -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,
|
|
1
|
+
{"version":3,"file":"emitters.d.ts","sourceRoot":"","sources":["../../../src/adapter/expr/emitters.ts"],"names":[],"mappings":"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"}
|
package/dist/adapter/index.js
CHANGED
|
@@ -187306,8 +187306,6 @@ import {
|
|
|
187306
187306
|
lookupStaticRecordLiteral,
|
|
187307
187307
|
searchParamsLocalNames,
|
|
187308
187308
|
prepareLoweringMatchers,
|
|
187309
|
-
queryHrefArgs,
|
|
187310
|
-
isValidHelperId,
|
|
187311
187309
|
sortComparatorFromArrow as sortComparatorFromArrow2,
|
|
187312
187310
|
isLowerableLoopDestructure,
|
|
187313
187311
|
isDangerousInnerHtmlAttr,
|
|
@@ -187640,7 +187638,9 @@ import {
|
|
|
187640
187638
|
isStringConcatBinary,
|
|
187641
187639
|
identifierPath,
|
|
187642
187640
|
matchSearchParamsMethodCall,
|
|
187643
|
-
sortComparatorFromArrow
|
|
187641
|
+
sortComparatorFromArrow,
|
|
187642
|
+
queryHrefArgs,
|
|
187643
|
+
isValidHelperId
|
|
187644
187644
|
} from "@barefootjs/jsx";
|
|
187645
187645
|
var PREDICATE_METHODS = new Set([
|
|
187646
187646
|
"filter",
|
|
@@ -187772,6 +187772,21 @@ class XslateTopLevelEmitter {
|
|
|
187772
187772
|
constructor(ctx) {
|
|
187773
187773
|
this.ctx = ctx;
|
|
187774
187774
|
}
|
|
187775
|
+
get lowering() {
|
|
187776
|
+
return {
|
|
187777
|
+
matchers: this.ctx._loweringMatchers,
|
|
187778
|
+
render: (node, emit) => {
|
|
187779
|
+
if (node.kind === "guard-list" && node.helper === "query") {
|
|
187780
|
+
const qArgs = queryHrefArgs(node, emit);
|
|
187781
|
+
return `$bf.query(${qArgs.join(", ")})`;
|
|
187782
|
+
}
|
|
187783
|
+
if (node.kind === "helper-call" && isValidHelperId(node.helper)) {
|
|
187784
|
+
return `$bf.${node.helper}(${node.args.map(emit).join(", ")})`;
|
|
187785
|
+
}
|
|
187786
|
+
return null;
|
|
187787
|
+
}
|
|
187788
|
+
};
|
|
187789
|
+
}
|
|
187775
187790
|
identifier(name) {
|
|
187776
187791
|
if (name === "undefined" || name === "null")
|
|
187777
187792
|
return "nil";
|
|
@@ -188628,7 +188643,7 @@ ${whenTrue}
|
|
|
188628
188643
|
const preambleLines = (loop.preamble?.declarations ?? []).map((d) => `: my $${d.name} = ${this.convertExpressionToKolon(d.raw, d.valueParsed)};`);
|
|
188629
188644
|
const childrenUnderLoop = this.renderChildren(loop.children);
|
|
188630
188645
|
this.inLoop = prevInLoop;
|
|
188631
|
-
const bodyChildren = loop.bodyIsItemConditional && loop.key ? `<: $bf.comment("loop-i:" ~ ${this.convertExpressionToKolon(loop.key)}) | mark_raw :>
|
|
188646
|
+
const bodyChildren = loop.bodyIsItemConditional && loop.key ? `<: $bf.comment("loop-i:" ~ $bf.escape_comment_key(${this.convertExpressionToKolon(loop.key)})) | mark_raw :>
|
|
188632
188647
|
${childrenUnderLoop}` : childrenUnderLoop;
|
|
188633
188648
|
this.scope = prevScope;
|
|
188634
188649
|
const lines = [];
|
|
@@ -188831,8 +188846,8 @@ ${body}
|
|
|
188831
188846
|
{
|
|
188832
188847
|
const m = this.parseUndefinedAlternateTernary(value.expr);
|
|
188833
188848
|
if (m) {
|
|
188834
|
-
const cond = this.convertExpressionToKolon(m.
|
|
188835
|
-
const val = this.convertExpressionToKolon(m.
|
|
188849
|
+
const cond = this.convertExpressionToKolon("", m.testParsed);
|
|
188850
|
+
const val = this.convertExpressionToKolon("", m.consequentParsed);
|
|
188836
188851
|
return `
|
|
188837
188852
|
: if (${cond}) {
|
|
188838
188853
|
${name}="<: ${val} :>"
|
|
@@ -188965,7 +188980,7 @@ ${name}="<: ${val} :>"
|
|
|
188965
188980
|
if (!startsAsObjectLiteral && !hasTaggedTemplate)
|
|
188966
188981
|
return false;
|
|
188967
188982
|
const parsed = parseExpression2(expr.trim());
|
|
188968
|
-
const support = isSupported(parsed);
|
|
188983
|
+
const support = isSupported(parsed, { loweringMatchers: this._loweringMatchers });
|
|
188969
188984
|
if (parsed.kind !== "unsupported" && support.supported)
|
|
188970
188985
|
return false;
|
|
188971
188986
|
const reason = support.reason ?? (parsed.kind === "unsupported" ? parsed.reason : undefined);
|
|
@@ -188985,6 +189000,7 @@ ${reason}` : "";
|
|
|
188985
189000
|
get emitCtx() {
|
|
188986
189001
|
return {
|
|
188987
189002
|
_searchParamsLocals: this._searchParamsLocals,
|
|
189003
|
+
_loweringMatchers: this._loweringMatchers,
|
|
188988
189004
|
_resolveModuleStringConst: (name) => this._resolveModuleStringConst(name),
|
|
188989
189005
|
_resolveLiteralConst: (name) => this._resolveLiteralConst(name),
|
|
188990
189006
|
_resolveStaticRecordLiteral: (o, k) => this._resolveStaticRecordLiteral(o, k),
|
|
@@ -189015,20 +189031,8 @@ ${reason}` : "";
|
|
|
189015
189031
|
return "''";
|
|
189016
189032
|
parsed = parseExpression2(trimmed);
|
|
189017
189033
|
}
|
|
189018
|
-
|
|
189019
|
-
|
|
189020
|
-
const node = matcher(parsed.callee, parsed.args);
|
|
189021
|
-
if (node?.kind === "guard-list" && node.helper === "query") {
|
|
189022
|
-
const qArgs = queryHrefArgs(node, (n) => this.renderParsedExprToKolon(n));
|
|
189023
|
-
return `$bf.query(${qArgs.join(", ")})`;
|
|
189024
|
-
}
|
|
189025
|
-
if (node?.kind === "helper-call" && isValidHelperId(node.helper)) {
|
|
189026
|
-
const argsX = node.args.map((a) => this.renderParsedExprToKolon(a));
|
|
189027
|
-
return `$bf.${node.helper}(${argsX.join(", ")})`;
|
|
189028
|
-
}
|
|
189029
|
-
}
|
|
189030
|
-
}
|
|
189031
|
-
const support = pos === "value" ? isSupportedValue(parsed) : isSupported(parsed);
|
|
189034
|
+
const supportOpts = { loweringMatchers: this._loweringMatchers };
|
|
189035
|
+
const support = pos === "value" ? isSupportedValue(parsed, supportOpts) : isSupported(parsed, supportOpts);
|
|
189032
189036
|
if (!support.supported) {
|
|
189033
189037
|
this.errors.push({
|
|
189034
189038
|
code: "BF101",
|
|
@@ -189065,7 +189069,9 @@ Options:
|
|
|
189065
189069
|
return null;
|
|
189066
189070
|
return {
|
|
189067
189071
|
condition: exprToString(parsed.test),
|
|
189068
|
-
consequent: exprToString(parsed.consequent)
|
|
189072
|
+
consequent: exprToString(parsed.consequent),
|
|
189073
|
+
testParsed: parsed.test,
|
|
189074
|
+
consequentParsed: parsed.consequent
|
|
189069
189075
|
};
|
|
189070
189076
|
}
|
|
189071
189077
|
isBooleanTypedPropRef(expr) {
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
*/
|
|
22
22
|
import type { ComponentIR, IRNode, IRElement, IRText, IRExpression, IRConditional, IRLoop, IRComponent, IRFragment, IRSlot, IRIfStatement, IRProvider, IRAsync, TemplatePrimitiveRegistry } from '@barefootjs/jsx';
|
|
23
23
|
import { BaseAdapter, type AdapterOutput, type AdapterGenerateOptions, type IRNodeEmitter, type EmitIRNode } from '@barefootjs/jsx';
|
|
24
|
+
import type { ParsedExpr } from '@barefootjs/jsx';
|
|
24
25
|
import type { XslateRenderCtx } from './lib/types.ts';
|
|
25
26
|
export type { XslateAdapterOptions } from './lib/types.ts';
|
|
26
27
|
import type { XslateAdapterOptions } from './lib/types.ts';
|
|
@@ -332,6 +333,8 @@ export declare class XslateAdapter extends BaseAdapter implements IRNodeEmitter<
|
|
|
332
333
|
parseUndefinedAlternateTernary(expr: string): {
|
|
333
334
|
condition: string;
|
|
334
335
|
consequent: string;
|
|
336
|
+
testParsed: ParsedExpr;
|
|
337
|
+
consequentParsed: ParsedExpr;
|
|
335
338
|
} | null;
|
|
336
339
|
isBooleanTypedPropRef(expr: string): boolean;
|
|
337
340
|
/** Position-accurate loop-bound-name check — see `this.scope`'s docstring. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"xslate-adapter.d.ts","sourceRoot":"","sources":["../../src/adapter/xslate-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EACV,WAAW,EACX,MAAM,EACN,SAAS,EACT,MAAM,EACN,YAAY,EACZ,aAAa,EACb,MAAM,EACN,WAAW,EACX,UAAU,EACV,MAAM,EACN,aAAa,EACb,UAAU,EACV,OAAO,EAKP,yBAAyB,EAG1B,MAAM,iBAAiB,CAAA;AACxB,OAAO,EACL,WAAW,EACX,KAAK,aAAa,EAClB,KAAK,sBAAsB,EAE3B,KAAK,aAAa,EAClB,KAAK,UAAU,
|
|
1
|
+
{"version":3,"file":"xslate-adapter.d.ts","sourceRoot":"","sources":["../../src/adapter/xslate-adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conformance-pins.d.ts","sourceRoot":"","sources":["../src/conformance-pins.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEtD,eAAO,MAAM,eAAe,EAAE,
|
|
1
|
+
{"version":3,"file":"conformance-pins.d.ts","sourceRoot":"","sources":["../src/conformance-pins.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEtD,eAAO,MAAM,eAAe,EAAE,eAiE7B,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -187306,8 +187306,6 @@ import {
|
|
|
187306
187306
|
lookupStaticRecordLiteral,
|
|
187307
187307
|
searchParamsLocalNames,
|
|
187308
187308
|
prepareLoweringMatchers,
|
|
187309
|
-
queryHrefArgs,
|
|
187310
|
-
isValidHelperId,
|
|
187311
187309
|
sortComparatorFromArrow as sortComparatorFromArrow2,
|
|
187312
187310
|
isLowerableLoopDestructure,
|
|
187313
187311
|
isDangerousInnerHtmlAttr,
|
|
@@ -187640,7 +187638,9 @@ import {
|
|
|
187640
187638
|
isStringConcatBinary,
|
|
187641
187639
|
identifierPath,
|
|
187642
187640
|
matchSearchParamsMethodCall,
|
|
187643
|
-
sortComparatorFromArrow
|
|
187641
|
+
sortComparatorFromArrow,
|
|
187642
|
+
queryHrefArgs,
|
|
187643
|
+
isValidHelperId
|
|
187644
187644
|
} from "@barefootjs/jsx";
|
|
187645
187645
|
var PREDICATE_METHODS = new Set([
|
|
187646
187646
|
"filter",
|
|
@@ -187772,6 +187772,21 @@ class XslateTopLevelEmitter {
|
|
|
187772
187772
|
constructor(ctx) {
|
|
187773
187773
|
this.ctx = ctx;
|
|
187774
187774
|
}
|
|
187775
|
+
get lowering() {
|
|
187776
|
+
return {
|
|
187777
|
+
matchers: this.ctx._loweringMatchers,
|
|
187778
|
+
render: (node, emit) => {
|
|
187779
|
+
if (node.kind === "guard-list" && node.helper === "query") {
|
|
187780
|
+
const qArgs = queryHrefArgs(node, emit);
|
|
187781
|
+
return `$bf.query(${qArgs.join(", ")})`;
|
|
187782
|
+
}
|
|
187783
|
+
if (node.kind === "helper-call" && isValidHelperId(node.helper)) {
|
|
187784
|
+
return `$bf.${node.helper}(${node.args.map(emit).join(", ")})`;
|
|
187785
|
+
}
|
|
187786
|
+
return null;
|
|
187787
|
+
}
|
|
187788
|
+
};
|
|
187789
|
+
}
|
|
187775
187790
|
identifier(name) {
|
|
187776
187791
|
if (name === "undefined" || name === "null")
|
|
187777
187792
|
return "nil";
|
|
@@ -188628,7 +188643,7 @@ ${whenTrue}
|
|
|
188628
188643
|
const preambleLines = (loop.preamble?.declarations ?? []).map((d) => `: my $${d.name} = ${this.convertExpressionToKolon(d.raw, d.valueParsed)};`);
|
|
188629
188644
|
const childrenUnderLoop = this.renderChildren(loop.children);
|
|
188630
188645
|
this.inLoop = prevInLoop;
|
|
188631
|
-
const bodyChildren = loop.bodyIsItemConditional && loop.key ? `<: $bf.comment("loop-i:" ~ ${this.convertExpressionToKolon(loop.key)}) | mark_raw :>
|
|
188646
|
+
const bodyChildren = loop.bodyIsItemConditional && loop.key ? `<: $bf.comment("loop-i:" ~ $bf.escape_comment_key(${this.convertExpressionToKolon(loop.key)})) | mark_raw :>
|
|
188632
188647
|
${childrenUnderLoop}` : childrenUnderLoop;
|
|
188633
188648
|
this.scope = prevScope;
|
|
188634
188649
|
const lines = [];
|
|
@@ -188831,8 +188846,8 @@ ${body}
|
|
|
188831
188846
|
{
|
|
188832
188847
|
const m = this.parseUndefinedAlternateTernary(value.expr);
|
|
188833
188848
|
if (m) {
|
|
188834
|
-
const cond = this.convertExpressionToKolon(m.
|
|
188835
|
-
const val = this.convertExpressionToKolon(m.
|
|
188849
|
+
const cond = this.convertExpressionToKolon("", m.testParsed);
|
|
188850
|
+
const val = this.convertExpressionToKolon("", m.consequentParsed);
|
|
188836
188851
|
return `
|
|
188837
188852
|
: if (${cond}) {
|
|
188838
188853
|
${name}="<: ${val} :>"
|
|
@@ -188965,7 +188980,7 @@ ${name}="<: ${val} :>"
|
|
|
188965
188980
|
if (!startsAsObjectLiteral && !hasTaggedTemplate)
|
|
188966
188981
|
return false;
|
|
188967
188982
|
const parsed = parseExpression2(expr.trim());
|
|
188968
|
-
const support = isSupported(parsed);
|
|
188983
|
+
const support = isSupported(parsed, { loweringMatchers: this._loweringMatchers });
|
|
188969
188984
|
if (parsed.kind !== "unsupported" && support.supported)
|
|
188970
188985
|
return false;
|
|
188971
188986
|
const reason = support.reason ?? (parsed.kind === "unsupported" ? parsed.reason : undefined);
|
|
@@ -188985,6 +189000,7 @@ ${reason}` : "";
|
|
|
188985
189000
|
get emitCtx() {
|
|
188986
189001
|
return {
|
|
188987
189002
|
_searchParamsLocals: this._searchParamsLocals,
|
|
189003
|
+
_loweringMatchers: this._loweringMatchers,
|
|
188988
189004
|
_resolveModuleStringConst: (name) => this._resolveModuleStringConst(name),
|
|
188989
189005
|
_resolveLiteralConst: (name) => this._resolveLiteralConst(name),
|
|
188990
189006
|
_resolveStaticRecordLiteral: (o, k) => this._resolveStaticRecordLiteral(o, k),
|
|
@@ -189015,20 +189031,8 @@ ${reason}` : "";
|
|
|
189015
189031
|
return "''";
|
|
189016
189032
|
parsed = parseExpression2(trimmed);
|
|
189017
189033
|
}
|
|
189018
|
-
|
|
189019
|
-
|
|
189020
|
-
const node = matcher(parsed.callee, parsed.args);
|
|
189021
|
-
if (node?.kind === "guard-list" && node.helper === "query") {
|
|
189022
|
-
const qArgs = queryHrefArgs(node, (n) => this.renderParsedExprToKolon(n));
|
|
189023
|
-
return `$bf.query(${qArgs.join(", ")})`;
|
|
189024
|
-
}
|
|
189025
|
-
if (node?.kind === "helper-call" && isValidHelperId(node.helper)) {
|
|
189026
|
-
const argsX = node.args.map((a) => this.renderParsedExprToKolon(a));
|
|
189027
|
-
return `$bf.${node.helper}(${argsX.join(", ")})`;
|
|
189028
|
-
}
|
|
189029
|
-
}
|
|
189030
|
-
}
|
|
189031
|
-
const support = pos === "value" ? isSupportedValue(parsed) : isSupported(parsed);
|
|
189034
|
+
const supportOpts = { loweringMatchers: this._loweringMatchers };
|
|
189035
|
+
const support = pos === "value" ? isSupportedValue(parsed, supportOpts) : isSupported(parsed, supportOpts);
|
|
189032
189036
|
if (!support.supported) {
|
|
189033
189037
|
this.errors.push({
|
|
189034
189038
|
code: "BF101",
|
|
@@ -189065,7 +189069,9 @@ Options:
|
|
|
189065
189069
|
return null;
|
|
189066
189070
|
return {
|
|
189067
189071
|
condition: exprToString(parsed.test),
|
|
189068
|
-
consequent: exprToString(parsed.consequent)
|
|
189072
|
+
consequent: exprToString(parsed.consequent),
|
|
189073
|
+
testParsed: parsed.test,
|
|
189074
|
+
consequentParsed: parsed.consequent
|
|
189069
189075
|
};
|
|
189070
189076
|
}
|
|
189071
189077
|
isBooleanTypedPropRef(expr) {
|
|
@@ -189171,9 +189177,7 @@ var conformancePins = {
|
|
|
189171
189177
|
"namespace-import-primitive": [{ code: "BF013", severity: "error", issue: "https://github.com/piconic-ai/barefootjs/issues/2771" }]
|
|
189172
189178
|
};
|
|
189173
189179
|
// src/render-divergences.ts
|
|
189174
|
-
var renderDivergences = {
|
|
189175
|
-
"aliased-loop-source": "A `.map()` loop whose source is a local const alias of a signal getter (`const items__alias = items`) SSRs an empty `<ul>` on real Text::Xslate — the seeded loop data is keyed by the signal's real name (`items`), and the alias hop is never resolved when deciding what to seed under `items__alias`. This is the SSR-side twin of #2778 (fixed for the CSR client-JS template in the same PR that added this fixture) — that fix only touches client-JS emission, not SSR data-seeding. Tracked at https://github.com/piconic-ai/barefootjs/issues/2813; graduate by resolving the alias hop at SSR-seeding time using the same `resolveAliasOrigin`/`resolveGetterAliases` mechanism #2778 introduced, rather than a third alias-hop walker."
|
|
189176
|
-
};
|
|
189180
|
+
var renderDivergences = {};
|
|
189177
189181
|
export {
|
|
189178
189182
|
xslateAdapter,
|
|
189179
189183
|
renderDivergences,
|
|
@@ -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,iBAAsB,CAAA"}
|
package/dist/vite.js
CHANGED
|
@@ -12,6 +12,41 @@ import ts10 from "typescript";
|
|
|
12
12
|
|
|
13
13
|
// ../jsx/src/expression-parser.ts
|
|
14
14
|
import ts from "typescript";
|
|
15
|
+
|
|
16
|
+
// ../jsx/src/lowering-registry.ts
|
|
17
|
+
var plugins = [];
|
|
18
|
+
function registerLoweringPlugin(plugin) {
|
|
19
|
+
const existing = plugins.findIndex((p) => p.name === plugin.name);
|
|
20
|
+
if (existing >= 0)
|
|
21
|
+
plugins[existing] = plugin;
|
|
22
|
+
else
|
|
23
|
+
plugins.push(plugin);
|
|
24
|
+
}
|
|
25
|
+
function prepareLoweringMatchers(metadata) {
|
|
26
|
+
const matchers = [];
|
|
27
|
+
for (const plugin of plugins) {
|
|
28
|
+
const matcher = plugin.prepare(metadata);
|
|
29
|
+
if (matcher)
|
|
30
|
+
matchers.push(matcher);
|
|
31
|
+
}
|
|
32
|
+
return matchers;
|
|
33
|
+
}
|
|
34
|
+
function loweringNodeChildren(node) {
|
|
35
|
+
if (node.kind === "helper-call")
|
|
36
|
+
return [...node.args];
|
|
37
|
+
const children = [node.base];
|
|
38
|
+
for (const t of node.triples) {
|
|
39
|
+
if (t.guard)
|
|
40
|
+
children.push(t.guard);
|
|
41
|
+
children.push(t.value);
|
|
42
|
+
}
|
|
43
|
+
return children;
|
|
44
|
+
}
|
|
45
|
+
function isValidHelperId(helper) {
|
|
46
|
+
return /^[A-Za-z_][A-Za-z0-9_]*$/.test(helper);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// ../jsx/src/expression-parser.ts
|
|
15
50
|
var UNSUPPORTED_METHODS = new Set([
|
|
16
51
|
"filter",
|
|
17
52
|
"map",
|
|
@@ -263,7 +298,7 @@ function convertNode(node, raw) {
|
|
|
263
298
|
}
|
|
264
299
|
if (n === undefined || Number.isNaN(n)) {
|
|
265
300
|
const parsedDepth = convertNode(depthNode, raw);
|
|
266
|
-
if (checkSupport(parsedDepth, "rendered").supported) {
|
|
301
|
+
if (checkSupport(parsedDepth, "rendered", []).supported) {
|
|
267
302
|
depthExpr = parsedDepth;
|
|
268
303
|
flatDepth = 1;
|
|
269
304
|
} else {
|
|
@@ -1041,13 +1076,13 @@ function getUnaryOperatorString(op) {
|
|
|
1041
1076
|
return "unknown";
|
|
1042
1077
|
}
|
|
1043
1078
|
}
|
|
1044
|
-
function isSupported(expr) {
|
|
1045
|
-
return checkSupport(expr, "rendered");
|
|
1079
|
+
function isSupported(expr, opts) {
|
|
1080
|
+
return checkSupport(expr, "rendered", opts?.loweringMatchers ?? []);
|
|
1046
1081
|
}
|
|
1047
|
-
function isSupportedValue(expr) {
|
|
1048
|
-
return checkSupport(expr, "value");
|
|
1082
|
+
function isSupportedValue(expr, opts) {
|
|
1083
|
+
return checkSupport(expr, "value", opts?.loweringMatchers ?? []);
|
|
1049
1084
|
}
|
|
1050
|
-
function checkSupport(expr, pos) {
|
|
1085
|
+
function checkSupport(expr, pos, matchers) {
|
|
1051
1086
|
switch (expr.kind) {
|
|
1052
1087
|
case "unsupported":
|
|
1053
1088
|
return { supported: false, reason: expr.reason };
|
|
@@ -1056,7 +1091,7 @@ function checkSupport(expr, pos) {
|
|
|
1056
1091
|
return { supported: false, reason: "Unsupported syntax: ObjectLiteralExpression" };
|
|
1057
1092
|
}
|
|
1058
1093
|
for (const prop of expr.properties) {
|
|
1059
|
-
const propSupport = checkSupport(prop.kind === "spread" ? prop.expr : prop.value, pos);
|
|
1094
|
+
const propSupport = checkSupport(prop.kind === "spread" ? prop.expr : prop.value, pos, matchers);
|
|
1060
1095
|
if (!propSupport.supported)
|
|
1061
1096
|
return propSupport;
|
|
1062
1097
|
}
|
|
@@ -1071,7 +1106,7 @@ function checkSupport(expr, pos) {
|
|
|
1071
1106
|
return { supported: false, reason: "Standalone arrow functions / regex literals are not supported" };
|
|
1072
1107
|
case "array-literal": {
|
|
1073
1108
|
for (const el of expr.elements) {
|
|
1074
|
-
const elSupport = checkSupport(el, pos);
|
|
1109
|
+
const elSupport = checkSupport(el, pos, matchers);
|
|
1075
1110
|
if (!elSupport.supported)
|
|
1076
1111
|
return elSupport;
|
|
1077
1112
|
}
|
|
@@ -1084,28 +1119,39 @@ function checkSupport(expr, pos) {
|
|
|
1084
1119
|
reason: `String.prototype.${expr.method} supports only a string pattern + string replacement (the regex form is deferred); use a string pattern or wrap the expression in /* @client */`
|
|
1085
1120
|
};
|
|
1086
1121
|
}
|
|
1087
|
-
const objSupport = checkSupport(expr.object, pos);
|
|
1122
|
+
const objSupport = checkSupport(expr.object, pos, matchers);
|
|
1088
1123
|
if (!objSupport.supported)
|
|
1089
1124
|
return objSupport;
|
|
1090
1125
|
for (const arg of expr.args) {
|
|
1091
|
-
const argSupport = checkSupport(arg, pos);
|
|
1126
|
+
const argSupport = checkSupport(arg, pos, matchers);
|
|
1092
1127
|
if (!argSupport.supported)
|
|
1093
1128
|
return argSupport;
|
|
1094
1129
|
}
|
|
1095
1130
|
if (expr.method === "flat" && expr.depthExpr) {
|
|
1096
|
-
const depthSupport = checkSupport(expr.depthExpr, pos);
|
|
1131
|
+
const depthSupport = checkSupport(expr.depthExpr, pos, matchers);
|
|
1097
1132
|
if (!depthSupport.supported)
|
|
1098
1133
|
return depthSupport;
|
|
1099
1134
|
}
|
|
1100
1135
|
return { supported: true, level: "L2" };
|
|
1101
1136
|
}
|
|
1102
1137
|
case "call": {
|
|
1138
|
+
for (const matcher of matchers) {
|
|
1139
|
+
const node = matcher(expr.callee, expr.args);
|
|
1140
|
+
if (!node)
|
|
1141
|
+
continue;
|
|
1142
|
+
for (const child of loweringNodeChildren(node)) {
|
|
1143
|
+
const childSupport = checkSupport(child, pos, matchers);
|
|
1144
|
+
if (!childSupport.supported)
|
|
1145
|
+
return childSupport;
|
|
1146
|
+
}
|
|
1147
|
+
return { supported: true, level: "L2" };
|
|
1148
|
+
}
|
|
1103
1149
|
const cb = asCallbackMethodCall(expr);
|
|
1104
1150
|
if (cb) {
|
|
1105
|
-
const objSupport = checkSupport(cb.object, pos);
|
|
1151
|
+
const objSupport = checkSupport(cb.object, pos, matchers);
|
|
1106
1152
|
if (!objSupport.supported)
|
|
1107
1153
|
return objSupport;
|
|
1108
|
-
const bodySupport = checkSupport(cb.arrow.body, pos);
|
|
1154
|
+
const bodySupport = checkSupport(cb.arrow.body, pos, matchers);
|
|
1109
1155
|
if (!bodySupport.supported) {
|
|
1110
1156
|
return {
|
|
1111
1157
|
supported: false,
|
|
@@ -1114,13 +1160,13 @@ function checkSupport(expr, pos) {
|
|
|
1114
1160
|
};
|
|
1115
1161
|
}
|
|
1116
1162
|
for (const rest of cb.args) {
|
|
1117
|
-
const restSupport = checkSupport(rest, pos);
|
|
1163
|
+
const restSupport = checkSupport(rest, pos, matchers);
|
|
1118
1164
|
if (!restSupport.supported)
|
|
1119
1165
|
return restSupport;
|
|
1120
1166
|
}
|
|
1121
1167
|
return { supported: true, level: "L5" };
|
|
1122
1168
|
}
|
|
1123
|
-
const calleeSupport = checkSupport(expr.callee, pos);
|
|
1169
|
+
const calleeSupport = checkSupport(expr.callee, pos, matchers);
|
|
1124
1170
|
if (!calleeSupport.supported) {
|
|
1125
1171
|
return calleeSupport;
|
|
1126
1172
|
}
|
|
@@ -1139,7 +1185,7 @@ function checkSupport(expr, pos) {
|
|
|
1139
1185
|
return { supported: true, level: "L1" };
|
|
1140
1186
|
}
|
|
1141
1187
|
for (const arg of expr.args) {
|
|
1142
|
-
const argSupport = checkSupport(arg, pos);
|
|
1188
|
+
const argSupport = checkSupport(arg, pos, matchers);
|
|
1143
1189
|
if (!argSupport.supported) {
|
|
1144
1190
|
return argSupport;
|
|
1145
1191
|
}
|
|
@@ -1147,7 +1193,7 @@ function checkSupport(expr, pos) {
|
|
|
1147
1193
|
return { supported: true, level: "L2" };
|
|
1148
1194
|
}
|
|
1149
1195
|
case "member": {
|
|
1150
|
-
const objSupport = checkSupport(expr.object, pos);
|
|
1196
|
+
const objSupport = checkSupport(expr.object, pos, matchers);
|
|
1151
1197
|
if (!objSupport.supported) {
|
|
1152
1198
|
return objSupport;
|
|
1153
1199
|
}
|
|
@@ -1157,19 +1203,19 @@ function checkSupport(expr, pos) {
|
|
|
1157
1203
|
return { supported: true, level: "L2" };
|
|
1158
1204
|
}
|
|
1159
1205
|
case "index-access": {
|
|
1160
|
-
const objSupport = checkSupport(expr.object, pos);
|
|
1206
|
+
const objSupport = checkSupport(expr.object, pos, matchers);
|
|
1161
1207
|
if (!objSupport.supported)
|
|
1162
1208
|
return objSupport;
|
|
1163
|
-
const indexSupport = checkSupport(expr.index, pos);
|
|
1209
|
+
const indexSupport = checkSupport(expr.index, pos, matchers);
|
|
1164
1210
|
if (!indexSupport.supported)
|
|
1165
1211
|
return indexSupport;
|
|
1166
1212
|
return { supported: true, level: "L2" };
|
|
1167
1213
|
}
|
|
1168
1214
|
case "binary": {
|
|
1169
|
-
const leftSupport = checkSupport(expr.left, pos);
|
|
1215
|
+
const leftSupport = checkSupport(expr.left, pos, matchers);
|
|
1170
1216
|
if (!leftSupport.supported)
|
|
1171
1217
|
return leftSupport;
|
|
1172
|
-
const rightSupport = checkSupport(expr.right, pos);
|
|
1218
|
+
const rightSupport = checkSupport(expr.right, pos, matchers);
|
|
1173
1219
|
if (!rightSupport.supported)
|
|
1174
1220
|
return rightSupport;
|
|
1175
1221
|
if (["===", "==", "!==", "!=", ">", "<", ">=", "<="].includes(expr.op)) {
|
|
@@ -1181,7 +1227,7 @@ function checkSupport(expr, pos) {
|
|
|
1181
1227
|
return { supported: false, reason: `Unknown operator: ${expr.op}` };
|
|
1182
1228
|
}
|
|
1183
1229
|
case "unary": {
|
|
1184
|
-
const argSupport = checkSupport(expr.argument, pos);
|
|
1230
|
+
const argSupport = checkSupport(expr.argument, pos, matchers);
|
|
1185
1231
|
if (!argSupport.supported)
|
|
1186
1232
|
return argSupport;
|
|
1187
1233
|
if (expr.op === "!") {
|
|
@@ -1193,25 +1239,25 @@ function checkSupport(expr, pos) {
|
|
|
1193
1239
|
return { supported: false, reason: `Unsupported unary operator: ${expr.op}` };
|
|
1194
1240
|
}
|
|
1195
1241
|
case "logical": {
|
|
1196
|
-
const leftSupport = checkSupport(expr.left, pos);
|
|
1242
|
+
const leftSupport = checkSupport(expr.left, pos, matchers);
|
|
1197
1243
|
if (!leftSupport.supported)
|
|
1198
1244
|
return leftSupport;
|
|
1199
1245
|
if (expr.op === "??" && expr.right.kind === "object-literal" && expr.right.properties.length === 0) {
|
|
1200
1246
|
return { supported: true, level: "L4" };
|
|
1201
1247
|
}
|
|
1202
|
-
const rightSupport = checkSupport(expr.right, pos);
|
|
1248
|
+
const rightSupport = checkSupport(expr.right, pos, matchers);
|
|
1203
1249
|
if (!rightSupport.supported)
|
|
1204
1250
|
return rightSupport;
|
|
1205
1251
|
return { supported: true, level: "L4" };
|
|
1206
1252
|
}
|
|
1207
1253
|
case "conditional": {
|
|
1208
|
-
const testSupport = checkSupport(expr.test, pos);
|
|
1254
|
+
const testSupport = checkSupport(expr.test, pos, matchers);
|
|
1209
1255
|
if (!testSupport.supported)
|
|
1210
1256
|
return testSupport;
|
|
1211
|
-
const consSupport = checkSupport(expr.consequent, pos);
|
|
1257
|
+
const consSupport = checkSupport(expr.consequent, pos, matchers);
|
|
1212
1258
|
if (!consSupport.supported)
|
|
1213
1259
|
return consSupport;
|
|
1214
|
-
const altSupport = checkSupport(expr.alternate, pos);
|
|
1260
|
+
const altSupport = checkSupport(expr.alternate, pos, matchers);
|
|
1215
1261
|
if (!altSupport.supported)
|
|
1216
1262
|
return altSupport;
|
|
1217
1263
|
return { supported: true, level: "L4" };
|
|
@@ -1219,7 +1265,7 @@ function checkSupport(expr, pos) {
|
|
|
1219
1265
|
case "template-literal": {
|
|
1220
1266
|
for (const part of expr.parts) {
|
|
1221
1267
|
if (part.type === "expression") {
|
|
1222
|
-
const partSupport = checkSupport(part.expr, pos);
|
|
1268
|
+
const partSupport = checkSupport(part.expr, pos, matchers);
|
|
1223
1269
|
if (!partSupport.supported)
|
|
1224
1270
|
return partSupport;
|
|
1225
1271
|
}
|
|
@@ -2228,6 +2274,12 @@ class BindingScope {
|
|
|
2228
2274
|
}
|
|
2229
2275
|
}
|
|
2230
2276
|
|
|
2277
|
+
// ../jsx/src/ir-to-client-js/safe-html.ts
|
|
2278
|
+
function safeHtml(expr) {
|
|
2279
|
+
return expr;
|
|
2280
|
+
}
|
|
2281
|
+
var EMPTY_MARKUP = safeHtml("''");
|
|
2282
|
+
|
|
2231
2283
|
// ../jsx/src/ir-to-client-js/html-template.ts
|
|
2232
2284
|
var VOID_ELEMENTS = new Set([
|
|
2233
2285
|
"area",
|
|
@@ -2514,6 +2566,7 @@ var CLIENT_EXPORTS = new Set([
|
|
|
2514
2566
|
"isSSRPortal",
|
|
2515
2567
|
"findSiblingSlot",
|
|
2516
2568
|
"cleanupPortalPlaceholder",
|
|
2569
|
+
"trackPosition",
|
|
2517
2570
|
"createSearchParams",
|
|
2518
2571
|
"queryHref",
|
|
2519
2572
|
"formatDate",
|
|
@@ -2574,7 +2627,8 @@ var BROWSER_ONLY_CLIENT_APIS = new Set([
|
|
|
2574
2627
|
"createPortal",
|
|
2575
2628
|
"isSSRPortal",
|
|
2576
2629
|
"findSiblingSlot",
|
|
2577
|
-
"cleanupPortalPlaceholder"
|
|
2630
|
+
"cleanupPortalPlaceholder",
|
|
2631
|
+
"trackPosition"
|
|
2578
2632
|
]);
|
|
2579
2633
|
var REACTIVE_PRIMITIVES = new Set([
|
|
2580
2634
|
"createSignal",
|
|
@@ -3173,30 +3227,6 @@ import ts16 from "typescript";
|
|
|
3173
3227
|
|
|
3174
3228
|
// ../jsx/src/relocate.ts
|
|
3175
3229
|
import ts18 from "typescript";
|
|
3176
|
-
|
|
3177
|
-
// ../jsx/src/lowering-registry.ts
|
|
3178
|
-
var plugins = [];
|
|
3179
|
-
function registerLoweringPlugin(plugin) {
|
|
3180
|
-
const existing = plugins.findIndex((p) => p.name === plugin.name);
|
|
3181
|
-
if (existing >= 0)
|
|
3182
|
-
plugins[existing] = plugin;
|
|
3183
|
-
else
|
|
3184
|
-
plugins.push(plugin);
|
|
3185
|
-
}
|
|
3186
|
-
function prepareLoweringMatchers(metadata) {
|
|
3187
|
-
const matchers = [];
|
|
3188
|
-
for (const plugin of plugins) {
|
|
3189
|
-
const matcher = plugin.prepare(metadata);
|
|
3190
|
-
if (matcher)
|
|
3191
|
-
matchers.push(matcher);
|
|
3192
|
-
}
|
|
3193
|
-
return matchers;
|
|
3194
|
-
}
|
|
3195
|
-
function isValidHelperId(helper) {
|
|
3196
|
-
return /^[A-Za-z_][A-Za-z0-9_]*$/.test(helper);
|
|
3197
|
-
}
|
|
3198
|
-
|
|
3199
|
-
// ../jsx/src/relocate.ts
|
|
3200
3230
|
var REGISTRY_SAFE_BINDING_KINDS = new Set([
|
|
3201
3231
|
"global",
|
|
3202
3232
|
"module-import",
|
|
@@ -4684,6 +4714,17 @@ function emitParsedExpr(expr, emitter) {
|
|
|
4684
4714
|
case "literal":
|
|
4685
4715
|
return emitter.literal(expr.value, expr.literalType);
|
|
4686
4716
|
case "call": {
|
|
4717
|
+
if (emitter.lowering) {
|
|
4718
|
+
for (const matcher of emitter.lowering.matchers) {
|
|
4719
|
+
const node = matcher(expr.callee, expr.args);
|
|
4720
|
+
if (!node)
|
|
4721
|
+
continue;
|
|
4722
|
+
const rendered = emitter.lowering.render(node, emit);
|
|
4723
|
+
if (rendered !== null)
|
|
4724
|
+
return rendered;
|
|
4725
|
+
break;
|
|
4726
|
+
}
|
|
4727
|
+
}
|
|
4687
4728
|
const cb = asCallbackMethodCall(expr);
|
|
4688
4729
|
if (cb)
|
|
4689
4730
|
return emitter.callbackMethod(cb.method, cb.object, cb.arrow, cb.args, emit);
|
|
@@ -5709,6 +5750,21 @@ class XslateTopLevelEmitter {
|
|
|
5709
5750
|
constructor(ctx) {
|
|
5710
5751
|
this.ctx = ctx;
|
|
5711
5752
|
}
|
|
5753
|
+
get lowering() {
|
|
5754
|
+
return {
|
|
5755
|
+
matchers: this.ctx._loweringMatchers,
|
|
5756
|
+
render: (node, emit) => {
|
|
5757
|
+
if (node.kind === "guard-list" && node.helper === "query") {
|
|
5758
|
+
const qArgs = queryHrefArgs(node, emit);
|
|
5759
|
+
return `$bf.query(${qArgs.join(", ")})`;
|
|
5760
|
+
}
|
|
5761
|
+
if (node.kind === "helper-call" && isValidHelperId(node.helper)) {
|
|
5762
|
+
return `$bf.${node.helper}(${node.args.map(emit).join(", ")})`;
|
|
5763
|
+
}
|
|
5764
|
+
return null;
|
|
5765
|
+
}
|
|
5766
|
+
};
|
|
5767
|
+
}
|
|
5712
5768
|
identifier(name) {
|
|
5713
5769
|
if (name === "undefined" || name === "null")
|
|
5714
5770
|
return "nil";
|
|
@@ -6556,7 +6612,7 @@ ${whenTrue}
|
|
|
6556
6612
|
const preambleLines = (loop.preamble?.declarations ?? []).map((d) => `: my $${d.name} = ${this.convertExpressionToKolon(d.raw, d.valueParsed)};`);
|
|
6557
6613
|
const childrenUnderLoop = this.renderChildren(loop.children);
|
|
6558
6614
|
this.inLoop = prevInLoop;
|
|
6559
|
-
const bodyChildren = loop.bodyIsItemConditional && loop.key ? `<: $bf.comment("loop-i:" ~ ${this.convertExpressionToKolon(loop.key)}) | mark_raw :>
|
|
6615
|
+
const bodyChildren = loop.bodyIsItemConditional && loop.key ? `<: $bf.comment("loop-i:" ~ $bf.escape_comment_key(${this.convertExpressionToKolon(loop.key)})) | mark_raw :>
|
|
6560
6616
|
${childrenUnderLoop}` : childrenUnderLoop;
|
|
6561
6617
|
this.scope = prevScope;
|
|
6562
6618
|
const lines = [];
|
|
@@ -6759,8 +6815,8 @@ ${body}
|
|
|
6759
6815
|
{
|
|
6760
6816
|
const m = this.parseUndefinedAlternateTernary(value.expr);
|
|
6761
6817
|
if (m) {
|
|
6762
|
-
const cond = this.convertExpressionToKolon(m.
|
|
6763
|
-
const val = this.convertExpressionToKolon(m.
|
|
6818
|
+
const cond = this.convertExpressionToKolon("", m.testParsed);
|
|
6819
|
+
const val = this.convertExpressionToKolon("", m.consequentParsed);
|
|
6764
6820
|
return `
|
|
6765
6821
|
: if (${cond}) {
|
|
6766
6822
|
${name}="<: ${val} :>"
|
|
@@ -6893,7 +6949,7 @@ ${name}="<: ${val} :>"
|
|
|
6893
6949
|
if (!startsAsObjectLiteral && !hasTaggedTemplate)
|
|
6894
6950
|
return false;
|
|
6895
6951
|
const parsed = parseExpression(expr.trim());
|
|
6896
|
-
const support = isSupported(parsed);
|
|
6952
|
+
const support = isSupported(parsed, { loweringMatchers: this._loweringMatchers });
|
|
6897
6953
|
if (parsed.kind !== "unsupported" && support.supported)
|
|
6898
6954
|
return false;
|
|
6899
6955
|
const reason = support.reason ?? (parsed.kind === "unsupported" ? parsed.reason : undefined);
|
|
@@ -6913,6 +6969,7 @@ ${reason}` : "";
|
|
|
6913
6969
|
get emitCtx() {
|
|
6914
6970
|
return {
|
|
6915
6971
|
_searchParamsLocals: this._searchParamsLocals,
|
|
6972
|
+
_loweringMatchers: this._loweringMatchers,
|
|
6916
6973
|
_resolveModuleStringConst: (name) => this._resolveModuleStringConst(name),
|
|
6917
6974
|
_resolveLiteralConst: (name) => this._resolveLiteralConst(name),
|
|
6918
6975
|
_resolveStaticRecordLiteral: (o, k) => this._resolveStaticRecordLiteral(o, k),
|
|
@@ -6943,20 +7000,8 @@ ${reason}` : "";
|
|
|
6943
7000
|
return "''";
|
|
6944
7001
|
parsed = parseExpression(trimmed);
|
|
6945
7002
|
}
|
|
6946
|
-
|
|
6947
|
-
|
|
6948
|
-
const node = matcher(parsed.callee, parsed.args);
|
|
6949
|
-
if (node?.kind === "guard-list" && node.helper === "query") {
|
|
6950
|
-
const qArgs = queryHrefArgs(node, (n) => this.renderParsedExprToKolon(n));
|
|
6951
|
-
return `$bf.query(${qArgs.join(", ")})`;
|
|
6952
|
-
}
|
|
6953
|
-
if (node?.kind === "helper-call" && isValidHelperId(node.helper)) {
|
|
6954
|
-
const argsX = node.args.map((a) => this.renderParsedExprToKolon(a));
|
|
6955
|
-
return `$bf.${node.helper}(${argsX.join(", ")})`;
|
|
6956
|
-
}
|
|
6957
|
-
}
|
|
6958
|
-
}
|
|
6959
|
-
const support = pos === "value" ? isSupportedValue(parsed) : isSupported(parsed);
|
|
7003
|
+
const supportOpts = { loweringMatchers: this._loweringMatchers };
|
|
7004
|
+
const support = pos === "value" ? isSupportedValue(parsed, supportOpts) : isSupported(parsed, supportOpts);
|
|
6960
7005
|
if (!support.supported) {
|
|
6961
7006
|
this.errors.push({
|
|
6962
7007
|
code: "BF101",
|
|
@@ -6993,7 +7038,9 @@ Options:
|
|
|
6993
7038
|
return null;
|
|
6994
7039
|
return {
|
|
6995
7040
|
condition: exprToString(parsed.test),
|
|
6996
|
-
consequent: exprToString(parsed.consequent)
|
|
7041
|
+
consequent: exprToString(parsed.consequent),
|
|
7042
|
+
testParsed: parsed.test,
|
|
7043
|
+
consequentParsed: parsed.consequent
|
|
6997
7044
|
};
|
|
6998
7045
|
}
|
|
6999
7046
|
isBooleanTypedPropRef(expr) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@barefootjs/xslate",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.35.0",
|
|
4
4
|
"description": "Text::Xslate (Kolon) adapter for BarefootJS — compiles IR to .tx templates and ships the Xslate rendering backend; runs under any PSGI/Plack app",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"directory": "packages/adapter-xslate"
|
|
56
56
|
},
|
|
57
57
|
"dependencies": {
|
|
58
|
-
"@barefootjs/shared": "0.
|
|
58
|
+
"@barefootjs/shared": "0.35.0"
|
|
59
59
|
},
|
|
60
60
|
"peerDependencies": {
|
|
61
61
|
"@barefootjs/jsx": ">=0.2.0",
|
|
@@ -72,9 +72,9 @@
|
|
|
72
72
|
},
|
|
73
73
|
"devDependencies": {
|
|
74
74
|
"@barefootjs/adapter-tests": "0.1.0",
|
|
75
|
-
"@barefootjs/jsx": "0.
|
|
76
|
-
"@barefootjs/vite": "0.
|
|
77
|
-
"@barefootjs/client": "0.
|
|
75
|
+
"@barefootjs/jsx": "0.35.0",
|
|
76
|
+
"@barefootjs/vite": "0.35.0",
|
|
77
|
+
"@barefootjs/client": "0.35.0",
|
|
78
78
|
"typescript": "^5.0.0",
|
|
79
79
|
"vite": "^6.0.0"
|
|
80
80
|
}
|
|
@@ -595,8 +595,8 @@ function Widget({ values }: { values: number[] }) {
|
|
|
595
595
|
return <ul>{values.map((label) => (label > 0 ? <li key={label}>{label}</li> : null))}</ul>
|
|
596
596
|
}
|
|
597
597
|
`)
|
|
598
|
-
expect(template).toContain('$bf.comment("loop-i:" ~ $label)')
|
|
599
|
-
expect(template).not.toContain('$bf.comment("loop-i:" ~ \'x\')')
|
|
598
|
+
expect(template).toContain('$bf.comment("loop-i:" ~ $bf.escape_comment_key($label))')
|
|
599
|
+
expect(template).not.toContain('$bf.comment("loop-i:" ~ $bf.escape_comment_key(\'x\'))')
|
|
600
600
|
})
|
|
601
601
|
|
|
602
602
|
test('a loop param shadowing an outer const resolves to the row value inside a .map() preamble local initializer', () => {
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
* rather than re-exposing the whole adapter.
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
|
-
import type { ParsedExpr, CompilerError, IRMetadata } from '@barefootjs/jsx'
|
|
21
|
+
import type { ParsedExpr, CompilerError, IRMetadata, LoweringMatcher } from '@barefootjs/jsx'
|
|
22
22
|
|
|
23
23
|
export interface XslateEmitContext {
|
|
24
24
|
/**
|
|
@@ -27,6 +27,17 @@ export interface XslateEmitContext {
|
|
|
27
27
|
*/
|
|
28
28
|
readonly _searchParamsLocals: Set<string>
|
|
29
29
|
|
|
30
|
+
/**
|
|
31
|
+
* Registered lowering-plugin matchers (#2057), bound to this component's
|
|
32
|
+
* metadata at init. Read by `XslateTopLevelEmitter`'s `lowering` seam
|
|
33
|
+
* (#2843) so a registered call — the built-in `queryHref`, or any
|
|
34
|
+
* userland plugin — is recognised no matter where it sits in an
|
|
35
|
+
* expression tree (a ternary branch, a template-literal interpolation, …),
|
|
36
|
+
* not only when it's the call the adapter's own top-level conversion
|
|
37
|
+
* entry point (`convertExpressionToKolon`) is asked to lower directly.
|
|
38
|
+
*/
|
|
39
|
+
readonly _loweringMatchers: readonly LoweringMatcher[]
|
|
40
|
+
|
|
30
41
|
/**
|
|
31
42
|
* Inline a module-scope pure string-literal const by name as the resolved
|
|
32
43
|
* literal value, or null when the name is not such a const.
|
|
@@ -15,6 +15,8 @@ import { groupBinaryOperand,
|
|
|
15
15
|
groupObjectLiteralSegments,
|
|
16
16
|
isStringConcatBinary,
|
|
17
17
|
type ParsedExprEmitter,
|
|
18
|
+
type LoweringEmitter,
|
|
19
|
+
type LoweringNode,
|
|
18
20
|
type HigherOrderMethod,
|
|
19
21
|
type ArrayMethod,
|
|
20
22
|
type LiteralType,
|
|
@@ -25,6 +27,8 @@ import { groupBinaryOperand,
|
|
|
25
27
|
identifierPath,
|
|
26
28
|
matchSearchParamsMethodCall,
|
|
27
29
|
sortComparatorFromArrow,
|
|
30
|
+
queryHrefArgs,
|
|
31
|
+
isValidHelperId,
|
|
28
32
|
} from '@barefootjs/jsx'
|
|
29
33
|
|
|
30
34
|
import type { XslateEmitContext } from '../emit-context.ts'
|
|
@@ -267,6 +271,35 @@ export class XslateTopLevelEmitter implements ParsedExprEmitter {
|
|
|
267
271
|
this.ctx = ctx
|
|
268
272
|
}
|
|
269
273
|
|
|
274
|
+
/**
|
|
275
|
+
* Registered-lowering seam (#2843): `emitParsedExpr`'s shared `call` case
|
|
276
|
+
* tries every matcher here BEFORE `call()` itself, so a registered call
|
|
277
|
+
* (the built-in `queryHref`, or any userland plugin) is recognised no
|
|
278
|
+
* matter where it sits in the tree. `render` is what used to live inline
|
|
279
|
+
* in `XslateAdapter.convertExpressionToKolon` before the object-literal
|
|
280
|
+
* support-gate refusal (`checkSupport`'s `call` arm, now itself
|
|
281
|
+
* registry-aware) made the pre-gate special case unnecessary.
|
|
282
|
+
*/
|
|
283
|
+
get lowering(): LoweringEmitter {
|
|
284
|
+
return {
|
|
285
|
+
matchers: this.ctx._loweringMatchers,
|
|
286
|
+
render: (node: LoweringNode, emit: (e: ParsedExpr) => string): string | null => {
|
|
287
|
+
// `query` guard-list — `queryHref`-shaped.
|
|
288
|
+
if (node.kind === 'guard-list' && node.helper === 'query') {
|
|
289
|
+
const qArgs = queryHrefArgs(node, emit)
|
|
290
|
+
return `$bf.query(${qArgs.join(', ')})`
|
|
291
|
+
}
|
|
292
|
+
// Generic `helper-call` (#2069) — a userland `LoweringPlugin`'s
|
|
293
|
+
// single runtime-helper invocation; `$bf.<helper>(args…)` mirrors
|
|
294
|
+
// the `query` helper's own naming convention.
|
|
295
|
+
if (node.kind === 'helper-call' && isValidHelperId(node.helper)) {
|
|
296
|
+
return `$bf.${node.helper}(${node.args.map(emit).join(', ')})`
|
|
297
|
+
}
|
|
298
|
+
return null
|
|
299
|
+
},
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
270
303
|
identifier(name: string): string {
|
|
271
304
|
// `undefined` / `null` nested inside a larger expression tree —
|
|
272
305
|
// Kolon `nil` (#1897).
|
|
@@ -70,8 +70,6 @@ import {
|
|
|
70
70
|
lookupStaticRecordLiteral,
|
|
71
71
|
searchParamsLocalNames,
|
|
72
72
|
prepareLoweringMatchers,
|
|
73
|
-
queryHrefArgs,
|
|
74
|
-
isValidHelperId,
|
|
75
73
|
sortComparatorFromArrow,
|
|
76
74
|
isLowerableLoopDestructure,
|
|
77
75
|
isDangerousInnerHtmlAttr,
|
|
@@ -981,9 +979,13 @@ export class XslateAdapter extends BaseAdapter implements IRNodeEmitter<XslateRe
|
|
|
981
979
|
// client's `mapArrayAnchored` can hydrate every SSR-rendered item by its
|
|
982
980
|
// anchor. Still under the row scope (see above) — `loop.key` is a
|
|
983
981
|
// per-row expression.
|
|
982
|
+
// `$bf.escape_comment_key` (#2795 follow-up) both stringifies the key
|
|
983
|
+
// (JS `String()` semantics, matching the other adapters) and neutralizes
|
|
984
|
+
// `-` so it can't spell `-->` and close the comment early — see its doc
|
|
985
|
+
// in `BarefootJS.pm`.
|
|
984
986
|
const bodyChildren =
|
|
985
987
|
loop.bodyIsItemConditional && loop.key
|
|
986
|
-
? `<: $bf.comment("loop-i:" ~ ${this.convertExpressionToKolon(loop.key)}) | mark_raw :>\n${childrenUnderLoop}`
|
|
988
|
+
? `<: $bf.comment("loop-i:" ~ $bf.escape_comment_key(${this.convertExpressionToKolon(loop.key)})) | mark_raw :>\n${childrenUnderLoop}`
|
|
987
989
|
: childrenUnderLoop
|
|
988
990
|
this.scope = prevScope
|
|
989
991
|
|
|
@@ -1403,8 +1405,13 @@ export class XslateAdapter extends BaseAdapter implements IRNodeEmitter<XslateRe
|
|
|
1403
1405
|
{
|
|
1404
1406
|
const m = this.parseUndefinedAlternateTernary(value.expr)
|
|
1405
1407
|
if (m) {
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
+
// Pass the PARSED sub-trees through as `preParsed` (#2843 review)
|
|
1409
|
+
// rather than re-parsing `m.condition`/`m.consequent` — those are
|
|
1410
|
+
// `exprToString` debug text, which renders any nested
|
|
1411
|
+
// `object-literal` (e.g. a registered call's params, `queryHref`'s
|
|
1412
|
+
// `{ tag }`) as a non-reparseable `[UNSUPPORTED: …]` placeholder.
|
|
1413
|
+
const cond = this.convertExpressionToKolon('', m.testParsed)
|
|
1414
|
+
const val = this.convertExpressionToKolon('', m.consequentParsed)
|
|
1408
1415
|
return `\n: if (${cond}) {\n${name}="<: ${val} :>"\n: }\n`
|
|
1409
1416
|
}
|
|
1410
1417
|
}
|
|
@@ -1659,7 +1666,7 @@ export class XslateAdapter extends BaseAdapter implements IRNodeEmitter<XslateRe
|
|
|
1659
1666
|
const hasTaggedTemplate = /[A-Za-z_$][\w$]*\s*`/.test(probe)
|
|
1660
1667
|
if (!startsAsObjectLiteral && !hasTaggedTemplate) return false
|
|
1661
1668
|
const parsed = parseExpression(expr.trim())
|
|
1662
|
-
const support = isSupported(parsed)
|
|
1669
|
+
const support = isSupported(parsed, { loweringMatchers: this._loweringMatchers })
|
|
1663
1670
|
if (parsed.kind !== 'unsupported' && support.supported) return false
|
|
1664
1671
|
const reason = support.reason ?? (parsed.kind === 'unsupported' ? parsed.reason : undefined)
|
|
1665
1672
|
const reasonLine = reason ? `\n${reason}` : ''
|
|
@@ -1686,6 +1693,7 @@ export class XslateAdapter extends BaseAdapter implements IRNodeEmitter<XslateRe
|
|
|
1686
1693
|
private get emitCtx(): XslateEmitContext {
|
|
1687
1694
|
return {
|
|
1688
1695
|
_searchParamsLocals: this._searchParamsLocals,
|
|
1696
|
+
_loweringMatchers: this._loweringMatchers,
|
|
1689
1697
|
_resolveModuleStringConst: (name) => this._resolveModuleStringConst(name),
|
|
1690
1698
|
_resolveLiteralConst: (name) => this._resolveLiteralConst(name),
|
|
1691
1699
|
_resolveStaticRecordLiteral: (o, k) => this._resolveStaticRecordLiteral(o, k),
|
|
@@ -1737,42 +1745,22 @@ export class XslateAdapter extends BaseAdapter implements IRNodeEmitter<XslateRe
|
|
|
1737
1745
|
parsed = parseExpression(trimmed)
|
|
1738
1746
|
}
|
|
1739
1747
|
|
|
1740
|
-
//
|
|
1741
|
-
// plugin
|
|
1742
|
-
//
|
|
1743
|
-
//
|
|
1744
|
-
//
|
|
1745
|
-
//
|
|
1746
|
-
//
|
|
1747
|
-
// `
|
|
1748
|
-
//
|
|
1749
|
-
//
|
|
1750
|
-
if (parsed.kind === 'call') {
|
|
1751
|
-
for (const matcher of this._loweringMatchers) {
|
|
1752
|
-
const node = matcher(parsed.callee, parsed.args)
|
|
1753
|
-
if (node?.kind === 'guard-list' && node.helper === 'query') {
|
|
1754
|
-
const qArgs = queryHrefArgs(node, n => this.renderParsedExprToKolon(n))
|
|
1755
|
-
return `$bf.query(${qArgs.join(', ')})`
|
|
1756
|
-
}
|
|
1757
|
-
// Generic `helper-call` (#2069) — the neutral vocabulary's escape
|
|
1758
|
-
// hatch for a userland `LoweringPlugin` that lowers to a single
|
|
1759
|
-
// runtime-helper invocation. `$bf.<helper>(args…)` mirrors the
|
|
1760
|
-
// `query` helper's own naming convention exactly: the framework
|
|
1761
|
-
// renders the call, the plugin author registers `<helper>` as a
|
|
1762
|
-
// Kolon-callable method on the `$bf` vars entry in their own
|
|
1763
|
-
// runtime — same contract as `$bf.query` itself, just not built in.
|
|
1764
|
-
if (node?.kind === 'helper-call' && isValidHelperId(node.helper)) {
|
|
1765
|
-
const argsX = node.args.map(a => this.renderParsedExprToKolon(a))
|
|
1766
|
-
return `$bf.${node.helper}(${argsX.join(', ')})`
|
|
1767
|
-
}
|
|
1768
|
-
}
|
|
1769
|
-
}
|
|
1770
|
-
|
|
1748
|
+
// #2843: a registered lowering plugin's call (the built-in `queryHref`,
|
|
1749
|
+
// or any userland plugin) is recognised no matter where it sits in the
|
|
1750
|
+
// tree — a ternary branch, a template-literal interpolation, … — not
|
|
1751
|
+
// only when `parsed.kind === 'call'` directly. That recognition now
|
|
1752
|
+
// lives in `XslateTopLevelEmitter`'s `lowering` seam, consulted by
|
|
1753
|
+
// `emitParsedExpr`'s shared `call` dispatch; the support gate below is
|
|
1754
|
+
// passed `this._loweringMatchers` so a matched call's params (e.g.
|
|
1755
|
+
// `queryHref`'s object literal, otherwise `unsupported` at `rendered`
|
|
1756
|
+
// position) are admitted wherever the call is nested.
|
|
1757
|
+
//
|
|
1771
1758
|
// `pos` distinguishes a derived-seed RHS (an assignment, checked via
|
|
1772
1759
|
// `isSupportedValue`) from every other, genuinely rendered call site —
|
|
1773
1760
|
// the rendered gate would otherwise re-refuse a tree the seed plan
|
|
1774
1761
|
// already classified `derived` at value position (#2696 review).
|
|
1775
|
-
const
|
|
1762
|
+
const supportOpts = { loweringMatchers: this._loweringMatchers }
|
|
1763
|
+
const support = pos === 'value' ? isSupportedValue(parsed, supportOpts) : isSupported(parsed, supportOpts)
|
|
1776
1764
|
if (!support.supported) {
|
|
1777
1765
|
this.errors.push({
|
|
1778
1766
|
code: 'BF101',
|
|
@@ -1832,7 +1820,7 @@ export class XslateAdapter extends BaseAdapter implements IRNodeEmitter<XslateRe
|
|
|
1832
1820
|
*/
|
|
1833
1821
|
parseUndefinedAlternateTernary(
|
|
1834
1822
|
expr: string,
|
|
1835
|
-
): { condition: string; consequent: string } | null {
|
|
1823
|
+
): { condition: string; consequent: string; testParsed: ParsedExpr; consequentParsed: ParsedExpr } | null {
|
|
1836
1824
|
const parsed = parseExpression(expr.trim())
|
|
1837
1825
|
if (parsed?.kind !== 'conditional') return null
|
|
1838
1826
|
const alt = parsed.alternate
|
|
@@ -1840,13 +1828,16 @@ export class XslateAdapter extends BaseAdapter implements IRNodeEmitter<XslateRe
|
|
|
1840
1828
|
(alt.kind === 'identifier' && (alt.name === 'undefined' || alt.name === 'null')) ||
|
|
1841
1829
|
(alt.kind === 'literal' && (alt.value === null || alt.value === undefined))
|
|
1842
1830
|
if (!isUndef) return null
|
|
1843
|
-
//
|
|
1844
|
-
//
|
|
1845
|
-
//
|
|
1846
|
-
//
|
|
1831
|
+
// `condition`/`consequent` are DEBUG text only (`exprToString` renders an
|
|
1832
|
+
// unsupported nested shape like an object literal as non-reparseable
|
|
1833
|
+
// `[UNSUPPORTED: …]` text) — callers that need to re-lower the
|
|
1834
|
+
// sub-expression must use `testParsed`/`consequentParsed` (the actual
|
|
1835
|
+
// parsed trees) as `preParsed`, not re-parse these strings.
|
|
1847
1836
|
return {
|
|
1848
1837
|
condition: exprToString(parsed.test),
|
|
1849
1838
|
consequent: exprToString(parsed.consequent),
|
|
1839
|
+
testParsed: parsed.test,
|
|
1840
|
+
consequentParsed: parsed.consequent,
|
|
1850
1841
|
}
|
|
1851
1842
|
}
|
|
1852
1843
|
|
package/src/conformance-pins.ts
CHANGED
|
@@ -10,6 +10,10 @@
|
|
|
10
10
|
import type { ConformancePins } from '@barefootjs/jsx'
|
|
11
11
|
|
|
12
12
|
export const conformancePins: ConformancePins = {
|
|
13
|
+
// #2843: graduated — a registered lowering call inside a ternary
|
|
14
|
+
// attribute branch (or any nested value position) is now recognised via
|
|
15
|
+
// `XslateTopLevelEmitter`'s `lowering` seam + the registry-aware support
|
|
16
|
+
// gate, matching the direct-call attribute path exactly.
|
|
13
17
|
'filter-typeof-predicate': [{ code: 'BF021', severity: 'error' }],
|
|
14
18
|
'map-array-builder-body': [{ code: 'BF021', severity: 'error' }],
|
|
15
19
|
'map-array-builder-escaping': [{ code: 'BF021', severity: 'error' }],
|
|
@@ -22,7 +22,4 @@ import type { RenderDivergences } from '@barefootjs/jsx'
|
|
|
22
22
|
// the real name off that capture — the same in-template recompute the other
|
|
23
23
|
// six template-stash backends already had. Keep the file even when the set
|
|
24
24
|
// is empty — the next divergence lands here, not in a re-created file.
|
|
25
|
-
export const renderDivergences: RenderDivergences = {
|
|
26
|
-
'aliased-loop-source':
|
|
27
|
-
'A `.map()` loop whose source is a local const alias of a signal getter (`const items__alias = items`) SSRs an empty `<ul>` on real Text::Xslate — the seeded loop data is keyed by the signal\'s real name (`items`), and the alias hop is never resolved when deciding what to seed under `items__alias`. This is the SSR-side twin of #2778 (fixed for the CSR client-JS template in the same PR that added this fixture) — that fix only touches client-JS emission, not SSR data-seeding. Tracked at https://github.com/piconic-ai/barefootjs/issues/2813; graduate by resolving the alias hop at SSR-seeding time using the same `resolveAliasOrigin`/`resolveGetterAliases` mechanism #2778 introduced, rather than a third alias-hop walker.',
|
|
28
|
-
}
|
|
25
|
+
export const renderDivergences: RenderDivergences = {}
|
package/src/test-render.ts
CHANGED
|
@@ -581,6 +581,26 @@ function buildPerlProps(
|
|
|
581
581
|
}
|
|
582
582
|
}
|
|
583
583
|
|
|
584
|
+
// #2813: `extractSsrDefaults` can seed an entry under a name that is
|
|
585
|
+
// none of `propsParams` / `signals` / `memos` above — a bare local-const
|
|
586
|
+
// alias of a signal/memo getter (`const items__alias = items`,
|
|
587
|
+
// `ssr-defaults.ts`) seeds `items__alias` alongside `items`. Production
|
|
588
|
+
// hands the whole manifest-derived stash straight through
|
|
589
|
+
// (`deriveStashFromDefaults` IS the production seeding mechanism here,
|
|
590
|
+
// not a harness stand-in), so any leftover `derivedProps` key must be
|
|
591
|
+
// pushed too, or this harness would silently omit what production
|
|
592
|
+
// actually provides, mismeasuring this conformance case.
|
|
593
|
+
const seededNames = new Set<string>([
|
|
594
|
+
...ir.metadata.propsParams.filter(p => !p.isRest).map(p => p.name),
|
|
595
|
+
...(restPropsName ? [restPropsName] : []),
|
|
596
|
+
...ir.metadata.signals.filter(s => !s.envReader).map(s => s.getter),
|
|
597
|
+
...ir.metadata.memos.map(m => m.name),
|
|
598
|
+
])
|
|
599
|
+
for (const [name, value] of Object.entries(derivedProps)) {
|
|
600
|
+
if (seededNames.has(name)) continue
|
|
601
|
+
entries.push(`${name} => ${toPerlLiteral(value)}`)
|
|
602
|
+
}
|
|
603
|
+
|
|
584
604
|
// (#1922) Request-scoped `searchParams()`: bind `$searchParams` to an
|
|
585
605
|
// empty-query reader via the lazy-loading factory (so the render script
|
|
586
606
|
// needn't `use BarefootJS::SearchParams`). The conformance harness issues no
|