@barefootjs/xslate 0.13.0 → 0.15.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/boolean-result.d.ts.map +1 -1
- package/dist/adapter/index.js +150 -81
- package/dist/adapter/xslate-adapter.d.ts +62 -0
- package/dist/adapter/xslate-adapter.d.ts.map +1 -1
- package/dist/build.js +150 -81
- package/dist/index.js +150 -81
- package/lib/BarefootJS/Backend/Xslate.pm +1 -1
- package/package.json +3 -3
- package/src/__tests__/xslate-adapter.test.ts +23 -4
- package/src/adapter/boolean-result.ts +5 -0
- package/src/adapter/xslate-adapter.ts +269 -33
- package/src/test-render.ts +43 -19
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"boolean-result.d.ts","sourceRoot":"","sources":["../../src/adapter/boolean-result.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAwCH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAIzD;
|
|
1
|
+
{"version":3,"file":"boolean-result.d.ts","sourceRoot":"","sources":["../../src/adapter/boolean-result.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAwCH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAIzD;AA8CD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEvD"}
|
package/dist/adapter/index.js
CHANGED
|
@@ -187292,6 +187292,8 @@ import {
|
|
|
187292
187292
|
BaseAdapter,
|
|
187293
187293
|
isBooleanAttr,
|
|
187294
187294
|
parseExpression as parseExpression2,
|
|
187295
|
+
exprToString,
|
|
187296
|
+
parseProviderObjectLiteral,
|
|
187295
187297
|
parseStyleObjectEntries,
|
|
187296
187298
|
isSupported,
|
|
187297
187299
|
identifierPath,
|
|
@@ -187301,10 +187303,13 @@ import {
|
|
|
187301
187303
|
augmentInheritedPropAccesses,
|
|
187302
187304
|
parseRecordIndexAccess,
|
|
187303
187305
|
evalStringArrayJoin,
|
|
187306
|
+
collectModuleStringConsts,
|
|
187304
187307
|
extractArrowBodyExpression,
|
|
187305
187308
|
collectContextConsumers,
|
|
187306
187309
|
isLowerableObjectRestDestructure,
|
|
187307
|
-
|
|
187310
|
+
lookupStaticRecordLiteral,
|
|
187311
|
+
searchParamsLocalNames,
|
|
187312
|
+
matchSearchParamsMethodCall
|
|
187308
187313
|
} from "@barefootjs/jsx";
|
|
187309
187314
|
|
|
187310
187315
|
// src/adapter/boolean-result.ts
|
|
@@ -187351,6 +187356,8 @@ var ARIA_BOOLEAN_ATTRS = new Set([
|
|
|
187351
187356
|
"aria-multiselectable",
|
|
187352
187357
|
"aria-readonly",
|
|
187353
187358
|
"aria-required",
|
|
187359
|
+
"aria-selected",
|
|
187360
|
+
"aria-expanded",
|
|
187354
187361
|
"aria-checked",
|
|
187355
187362
|
"aria-pressed"
|
|
187356
187363
|
]);
|
|
@@ -187360,7 +187367,7 @@ function isAriaBooleanAttr(name) {
|
|
|
187360
187367
|
|
|
187361
187368
|
// src/adapter/xslate-adapter.ts
|
|
187362
187369
|
var import_typescript = __toESM(require_typescript(), 1);
|
|
187363
|
-
import { BF_SLOT, BF_COND } from "@barefootjs/shared";
|
|
187370
|
+
import { BF_SLOT, BF_COND, BF_REGION } from "@barefootjs/shared";
|
|
187364
187371
|
var XSLATE_TEMPLATE_PRIMITIVES = {
|
|
187365
187372
|
"JSON.stringify": { arity: 1, emit: (args) => `$bf.json(${args[0]})` },
|
|
187366
187373
|
String: { arity: 1, emit: (args) => `$bf.string(${args[0]})` },
|
|
@@ -187428,8 +187435,10 @@ class XslateAdapter extends BaseAdapter {
|
|
|
187428
187435
|
inLoop = false;
|
|
187429
187436
|
propsObjectName = null;
|
|
187430
187437
|
propsParams = [];
|
|
187438
|
+
booleanTypedProps = new Set;
|
|
187431
187439
|
stringValueNames = new Set;
|
|
187432
187440
|
moduleStringConsts = new Map;
|
|
187441
|
+
_searchParamsLocals = new Set;
|
|
187433
187442
|
localConstants = [];
|
|
187434
187443
|
nullableOptionalProps = new Set;
|
|
187435
187444
|
constructor(options = {}) {
|
|
@@ -187444,6 +187453,7 @@ class XslateAdapter extends BaseAdapter {
|
|
|
187444
187453
|
this.propsObjectName = ir.metadata.propsObjectName ?? null;
|
|
187445
187454
|
augmentInheritedPropAccesses(ir);
|
|
187446
187455
|
this.propsParams = ir.metadata.propsParams.map((p) => ({ name: p.name }));
|
|
187456
|
+
this.booleanTypedProps = new Set(ir.metadata.propsParams.filter((prop) => prop.type?.primitive === "boolean" || prop.type?.raw === "boolean").map((prop) => prop.name));
|
|
187447
187457
|
this.localConstants = ir.metadata.localConstants ?? [];
|
|
187448
187458
|
this.nullableOptionalProps = new Set(ir.metadata.propsParams.filter((p) => p.defaultValue === undefined && !p.isRest && p.type?.kind !== "primitive").map((p) => p.name));
|
|
187449
187459
|
this.stringValueNames = new Set;
|
|
@@ -187457,6 +187467,7 @@ class XslateAdapter extends BaseAdapter {
|
|
|
187457
187467
|
this.stringValueNames.add(p.name);
|
|
187458
187468
|
}
|
|
187459
187469
|
this.moduleStringConsts = collectModuleStringConsts(ir.metadata.localConstants);
|
|
187470
|
+
this._searchParamsLocals = searchParamsLocalNames(ir.metadata);
|
|
187460
187471
|
this.errors = [];
|
|
187461
187472
|
this.childrenCaptureCounter = 0;
|
|
187462
187473
|
if (!options?.siblingTemplatesRegistered) {
|
|
@@ -187542,12 +187553,29 @@ class XslateAdapter extends BaseAdapter {
|
|
|
187542
187553
|
if (v.kind === "literal") {
|
|
187543
187554
|
return typeof v.value === "string" ? `'${v.value.replace(/[\\']/g, (m) => `\\${m}`)}'` : String(v.value);
|
|
187544
187555
|
}
|
|
187545
|
-
if (v.kind === "expression")
|
|
187556
|
+
if (v.kind === "expression") {
|
|
187557
|
+
const hashref = this.providerObjectLiteralKolon(v.expr);
|
|
187558
|
+
if (hashref !== null)
|
|
187559
|
+
return hashref;
|
|
187546
187560
|
return this.convertExpressionToKolon(v.expr);
|
|
187561
|
+
}
|
|
187547
187562
|
if (v.kind === "template")
|
|
187548
187563
|
return this.convertTemplateLiteralPartsToKolon(v.parts);
|
|
187549
187564
|
return "nil";
|
|
187550
187565
|
}
|
|
187566
|
+
providerObjectLiteralKolon(expr) {
|
|
187567
|
+
const members = parseProviderObjectLiteral(expr.trim());
|
|
187568
|
+
if (members === null)
|
|
187569
|
+
return null;
|
|
187570
|
+
const entries = members.map((m) => {
|
|
187571
|
+
const key = `'${m.name.replace(/[\\']/g, (c) => `\\${c}`)}'`;
|
|
187572
|
+
if (m.kind === "function" || /^on[A-Z]/.test(m.name))
|
|
187573
|
+
return `${key} => nil`;
|
|
187574
|
+
const src = m.kind === "getter" ? m.body : m.expr;
|
|
187575
|
+
return `${key} => ${this.convertExpressionToKolon(src)}`;
|
|
187576
|
+
});
|
|
187577
|
+
return `{ ${entries.join(", ")} }`;
|
|
187578
|
+
}
|
|
187551
187579
|
contextDefaultKolon(c) {
|
|
187552
187580
|
const d = c.defaultValue;
|
|
187553
187581
|
if (d === null || d === undefined)
|
|
@@ -187571,7 +187599,6 @@ class XslateAdapter extends BaseAdapter {
|
|
|
187571
187599
|
const signals = ir.metadata.signals ?? [];
|
|
187572
187600
|
if (memos.length === 0 && signals.length === 0)
|
|
187573
187601
|
return "";
|
|
187574
|
-
const ssrDefaults = extractSsrDefaults(ir.metadata) ?? {};
|
|
187575
187602
|
const available = new Set(ir.metadata.propsParams.map((p) => p.name));
|
|
187576
187603
|
const lines = [];
|
|
187577
187604
|
for (const signal of signals) {
|
|
@@ -187582,18 +187609,13 @@ class XslateAdapter extends BaseAdapter {
|
|
|
187582
187609
|
available.add(signal.getter);
|
|
187583
187610
|
}
|
|
187584
187611
|
for (const memo of memos) {
|
|
187585
|
-
const def = ssrDefaults[memo.name];
|
|
187586
|
-
const isNull2 = !def || typeof def === "object" && "value" in def && def.value === null;
|
|
187587
|
-
if (!isNull2) {
|
|
187588
|
-
available.add(memo.name);
|
|
187589
|
-
continue;
|
|
187590
|
-
}
|
|
187591
187612
|
const body = extractArrowBodyExpression(memo.computation);
|
|
187592
|
-
if (body
|
|
187593
|
-
|
|
187594
|
-
|
|
187595
|
-
|
|
187596
|
-
|
|
187613
|
+
if (body !== null) {
|
|
187614
|
+
const kolon = this.tryLowerToKolon(body, available);
|
|
187615
|
+
const refsSelf = kolon !== null && new RegExp(`\\$${memo.name}\\b`).test(kolon);
|
|
187616
|
+
if (kolon !== null && !refsSelf)
|
|
187617
|
+
lines.push(`: my $${memo.name} = ${kolon};`);
|
|
187618
|
+
}
|
|
187597
187619
|
available.add(memo.name);
|
|
187598
187620
|
}
|
|
187599
187621
|
return lines.length > 0 ? lines.join(`
|
|
@@ -187628,6 +187650,9 @@ class XslateAdapter extends BaseAdapter {
|
|
|
187628
187650
|
if (element.slotId) {
|
|
187629
187651
|
hydrationAttrs += ` ${this.renderSlotMarker(element.slotId)}`;
|
|
187630
187652
|
}
|
|
187653
|
+
if (element.regionId) {
|
|
187654
|
+
hydrationAttrs += ` ${BF_REGION}="${element.regionId}"`;
|
|
187655
|
+
}
|
|
187631
187656
|
const voidElements = [
|
|
187632
187657
|
"area",
|
|
187633
187658
|
"base",
|
|
@@ -187895,7 +187920,7 @@ ${childrenUnderLoop}` : childrenUnderLoop;
|
|
|
187895
187920
|
renderComponent(comp) {
|
|
187896
187921
|
const propParts = [];
|
|
187897
187922
|
for (const p of comp.props) {
|
|
187898
|
-
if (p.name.match(/^on[A-Z]/) && p.value.kind === "expression")
|
|
187923
|
+
if ((p.name.match(/^on[A-Z]/) || p.name === "ref") && p.value.kind === "expression")
|
|
187899
187924
|
continue;
|
|
187900
187925
|
if (p.value.kind === "spread") {
|
|
187901
187926
|
const trimmed = p.value.expr.trim();
|
|
@@ -187926,7 +187951,10 @@ ${childrenUnderLoop}` : childrenUnderLoop;
|
|
|
187926
187951
|
const tplName = this.toTemplateName(comp.name);
|
|
187927
187952
|
const effectiveChildren = comp.children.length > 0 ? comp.children : resolveJsxChildrenProp(comp.props);
|
|
187928
187953
|
if (effectiveChildren.length > 0) {
|
|
187954
|
+
const prevInLoop = this.inLoop;
|
|
187955
|
+
this.inLoop = false;
|
|
187929
187956
|
const childrenBody = this.renderChildren(effectiveChildren);
|
|
187957
|
+
this.inLoop = prevInLoop;
|
|
187930
187958
|
const macroName = `bf_children_${comp.slotId ?? "c" + this.childrenCaptureCounter++}`;
|
|
187931
187959
|
const childrenEntry = `children => ${macroName}()`;
|
|
187932
187960
|
const allParts = [...propParts, childrenEntry];
|
|
@@ -187936,6 +187964,7 @@ ${childrenUnderLoop}` : childrenUnderLoop;
|
|
|
187936
187964
|
return `<: $bf.render_child('${tplName}'${hashEntries}) | mark_raw :>`;
|
|
187937
187965
|
}
|
|
187938
187966
|
childrenCaptureCounter = 0;
|
|
187967
|
+
presenceVarCounter = 0;
|
|
187939
187968
|
toTemplateName(componentName) {
|
|
187940
187969
|
return componentName.replace(/([A-Z])/g, "_$1").toLowerCase().replace(/^_/, "");
|
|
187941
187970
|
}
|
|
@@ -187991,18 +188020,41 @@ ${children}`;
|
|
|
187991
188020
|
const normalizedBareId = this.propsObjectName && bareId.startsWith(`${this.propsObjectName}.`) ? bareId.slice(this.propsObjectName.length + 1) : bareId;
|
|
187992
188021
|
if (!isBooleanAttr(name) && !value.presenceOrUndefined && /^[A-Za-z_$][\w$]*$/.test(normalizedBareId) && this.nullableOptionalProps.has(normalizedBareId)) {
|
|
187993
188022
|
const perl2 = this.convertExpressionToKolon(value.expr);
|
|
187994
|
-
const body = isBooleanResultExpr(value.expr) || isAriaBooleanAttr(name) ? `${name}="<: $bf.bool_str(${perl2}) :>"` : `${name}="<: ${perl2} :>"`;
|
|
188023
|
+
const body = isBooleanResultExpr(value.expr) || isAriaBooleanAttr(name) || this.isBooleanTypedPropRef(value.expr) ? `${name}="<: $bf.bool_str(${perl2}) :>"` : `${name}="<: ${perl2} :>"`;
|
|
187995
188024
|
return `
|
|
187996
188025
|
: if (defined ${perl2}) {
|
|
187997
188026
|
${body}
|
|
187998
188027
|
: }
|
|
187999
188028
|
`;
|
|
188000
188029
|
}
|
|
188001
|
-
if (isBooleanAttr(name)
|
|
188030
|
+
if (isBooleanAttr(name)) {
|
|
188002
188031
|
return `<: ${this.convertExpressionToKolon(value.expr)} ? '${name}' : '' :>`;
|
|
188003
188032
|
}
|
|
188033
|
+
if (value.presenceOrUndefined) {
|
|
188034
|
+
const perl2 = this.convertExpressionToKolon(value.expr);
|
|
188035
|
+
const tmp = `$bf_pu${this.presenceVarCounter++}`;
|
|
188036
|
+
const body = isBooleanResultExpr(value.expr) || isAriaBooleanAttr(name) || this.isBooleanTypedPropRef(value.expr) ? `${name}="<: $bf.bool_str(${tmp}) :>"` : `${name}="<: ${tmp} :>"`;
|
|
188037
|
+
return `
|
|
188038
|
+
: my ${tmp} = ${perl2};
|
|
188039
|
+
: if (${tmp}) {
|
|
188040
|
+
${body}
|
|
188041
|
+
: }
|
|
188042
|
+
`;
|
|
188043
|
+
}
|
|
188044
|
+
{
|
|
188045
|
+
const m = this.parseUndefinedAlternateTernary(value.expr);
|
|
188046
|
+
if (m) {
|
|
188047
|
+
const cond = this.convertExpressionToKolon(m.condition);
|
|
188048
|
+
const val = this.convertExpressionToKolon(m.consequent);
|
|
188049
|
+
return `
|
|
188050
|
+
: if (${cond}) {
|
|
188051
|
+
${name}="<: ${val} :>"
|
|
188052
|
+
: }
|
|
188053
|
+
`;
|
|
188054
|
+
}
|
|
188055
|
+
}
|
|
188004
188056
|
const perl = this.convertExpressionToKolon(value.expr);
|
|
188005
|
-
if (isBooleanResultExpr(value.expr) || isAriaBooleanAttr(name)) {
|
|
188057
|
+
if (isBooleanResultExpr(value.expr) || isAriaBooleanAttr(name) || this.isBooleanTypedPropRef(value.expr)) {
|
|
188006
188058
|
return `${name}="<: $bf.bool_str(${perl}) :>"`;
|
|
188007
188059
|
}
|
|
188008
188060
|
return `${name}="<: ${perl} :>"`;
|
|
@@ -188261,6 +188313,18 @@ ${reason}` : "";
|
|
|
188261
188313
|
return n;
|
|
188262
188314
|
})();
|
|
188263
188315
|
const indexed = this.recordIndexAccessToKolon(initNode);
|
|
188316
|
+
if (indexed === null && import_typescript.default.isElementAccessExpression(initNode) && initNode.argumentExpression && !import_typescript.default.isNumericLiteral(initNode.argumentExpression) && !import_typescript.default.isStringLiteral(initNode.argumentExpression)) {
|
|
188317
|
+
this.errors.push({
|
|
188318
|
+
code: "BF101",
|
|
188319
|
+
severity: "error",
|
|
188320
|
+
message: `Spread object value '${initNode.getText(sf)}' indexes a record map whose values aren't scalar literals — it can't lower to an inline Kolon hashref.`,
|
|
188321
|
+
loc: { file: this.componentName + ".tsx", start: { line: 1, column: 0 }, end: { line: 1, column: 0 } },
|
|
188322
|
+
suggestion: {
|
|
188323
|
+
message: "Index a record whose values are number/string literals, or move the spread into a `'use client'` component so hydration computes it."
|
|
188324
|
+
}
|
|
188325
|
+
});
|
|
188326
|
+
return null;
|
|
188327
|
+
}
|
|
188264
188328
|
const valPerl = indexed !== null ? indexed : this.convertExpressionToKolon(prop.initializer.getText(sf));
|
|
188265
188329
|
entries.push(`'${escapeKolonSingleQuoted(key)}' => ${valPerl}`);
|
|
188266
188330
|
}
|
|
@@ -188308,6 +188372,46 @@ Options:
|
|
|
188308
188372
|
_isStringValueName(name) {
|
|
188309
188373
|
return this.stringValueNames.has(name);
|
|
188310
188374
|
}
|
|
188375
|
+
parseUndefinedAlternateTernary(expr) {
|
|
188376
|
+
const parsed = parseExpression2(expr.trim());
|
|
188377
|
+
if (parsed?.kind !== "conditional")
|
|
188378
|
+
return null;
|
|
188379
|
+
const alt = parsed.alternate;
|
|
188380
|
+
const isUndef = alt.kind === "identifier" && (alt.name === "undefined" || alt.name === "null") || alt.kind === "literal" && (alt.value === null || alt.value === undefined);
|
|
188381
|
+
if (!isUndef)
|
|
188382
|
+
return null;
|
|
188383
|
+
return {
|
|
188384
|
+
condition: exprToString(parsed.test),
|
|
188385
|
+
consequent: exprToString(parsed.consequent)
|
|
188386
|
+
};
|
|
188387
|
+
}
|
|
188388
|
+
isBooleanTypedPropRef(expr) {
|
|
188389
|
+
let bare = expr.trim();
|
|
188390
|
+
if (this.propsObjectName && bare.startsWith(`${this.propsObjectName}.`)) {
|
|
188391
|
+
bare = bare.slice(this.propsObjectName.length + 1);
|
|
188392
|
+
}
|
|
188393
|
+
if (!/^[A-Za-z_$][\w$]*$/.test(bare))
|
|
188394
|
+
return false;
|
|
188395
|
+
return this.booleanTypedProps.has(bare);
|
|
188396
|
+
}
|
|
188397
|
+
_resolveLiteralConst(name) {
|
|
188398
|
+
const c = (this.localConstants ?? []).find((lc) => lc.name === name);
|
|
188399
|
+
if (c?.value === undefined)
|
|
188400
|
+
return null;
|
|
188401
|
+
const v = c.value.trim();
|
|
188402
|
+
if (/^-?\d+(\.\d+)?$/.test(v))
|
|
188403
|
+
return v;
|
|
188404
|
+
const strLit = /^'([^'\\]*)'$/.exec(v) ?? /^"([^"\\]*)"$/.exec(v);
|
|
188405
|
+
if (strLit)
|
|
188406
|
+
return `'${strLit[1].replace(/[\\']/g, (m) => `\\${m}`)}'`;
|
|
188407
|
+
return null;
|
|
188408
|
+
}
|
|
188409
|
+
_resolveStaticRecordLiteral(objectName, key) {
|
|
188410
|
+
const hit = lookupStaticRecordLiteral(objectName, key, this.localConstants);
|
|
188411
|
+
if (!hit)
|
|
188412
|
+
return null;
|
|
188413
|
+
return hit.kind === "number" ? hit.text : `'${hit.text.replace(/[\\']/g, (m) => `\\${m}`)}'`;
|
|
188414
|
+
}
|
|
188311
188415
|
_resolveModuleStringConst(name) {
|
|
188312
188416
|
if (this.inLoop)
|
|
188313
188417
|
return null;
|
|
@@ -188392,6 +188496,11 @@ function renderArrayMethod(method, object, args, emit) {
|
|
|
188392
188496
|
const recv = emit(object);
|
|
188393
188497
|
return `$bf.trim(${recv})`;
|
|
188394
188498
|
}
|
|
188499
|
+
case "toFixed": {
|
|
188500
|
+
const recv = emit(object);
|
|
188501
|
+
const digits = args.length >= 1 ? emit(args[0]) : "0";
|
|
188502
|
+
return `$bf.to_fixed(${recv}, ${digits})`;
|
|
188503
|
+
}
|
|
188395
188504
|
case "split": {
|
|
188396
188505
|
const recv = emit(object);
|
|
188397
188506
|
if (args.length === 0) {
|
|
@@ -188471,68 +188580,6 @@ function renderFlatMapMethod(recv, op) {
|
|
|
188471
188580
|
return `$bf.flat_map(${recv}, 'self', '')`;
|
|
188472
188581
|
return `$bf.flat_map(${recv}, 'field', '${proj.field}')`;
|
|
188473
188582
|
}
|
|
188474
|
-
function parsePureStringLiteral(source) {
|
|
188475
|
-
let s = source.trim();
|
|
188476
|
-
while (s.startsWith("(") && s.endsWith(")"))
|
|
188477
|
-
s = s.slice(1, -1).trim();
|
|
188478
|
-
const quote = s[0];
|
|
188479
|
-
if ((quote === "'" || quote === '"') && s[s.length - 1] === quote) {
|
|
188480
|
-
const body = s.slice(1, -1);
|
|
188481
|
-
if (containsUnescaped(body, quote))
|
|
188482
|
-
return null;
|
|
188483
|
-
return unescapeStringLiteralBody(body);
|
|
188484
|
-
}
|
|
188485
|
-
if (quote === "`" && s[s.length - 1] === "`") {
|
|
188486
|
-
const body = s.slice(1, -1);
|
|
188487
|
-
if (body.includes("${"))
|
|
188488
|
-
return null;
|
|
188489
|
-
if (containsUnescaped(body, "`"))
|
|
188490
|
-
return null;
|
|
188491
|
-
return unescapeStringLiteralBody(body);
|
|
188492
|
-
}
|
|
188493
|
-
return evalStringArrayJoin(source);
|
|
188494
|
-
}
|
|
188495
|
-
function containsUnescaped(s, ch) {
|
|
188496
|
-
for (let i2 = 0;i2 < s.length; i2++) {
|
|
188497
|
-
if (s[i2] === "\\") {
|
|
188498
|
-
i2++;
|
|
188499
|
-
continue;
|
|
188500
|
-
}
|
|
188501
|
-
if (s[i2] === ch)
|
|
188502
|
-
return true;
|
|
188503
|
-
}
|
|
188504
|
-
return false;
|
|
188505
|
-
}
|
|
188506
|
-
function unescapeStringLiteralBody(s) {
|
|
188507
|
-
return s.replace(/\\(.)/g, (_, c) => {
|
|
188508
|
-
switch (c) {
|
|
188509
|
-
case "n":
|
|
188510
|
-
return `
|
|
188511
|
-
`;
|
|
188512
|
-
case "r":
|
|
188513
|
-
return "\r";
|
|
188514
|
-
case "t":
|
|
188515
|
-
return "\t";
|
|
188516
|
-
case "0":
|
|
188517
|
-
return "\x00";
|
|
188518
|
-
default:
|
|
188519
|
-
return c;
|
|
188520
|
-
}
|
|
188521
|
-
});
|
|
188522
|
-
}
|
|
188523
|
-
function collectModuleStringConsts(constants3) {
|
|
188524
|
-
const map = new Map;
|
|
188525
|
-
for (const c of constants3 ?? []) {
|
|
188526
|
-
if (!c.isModule)
|
|
188527
|
-
continue;
|
|
188528
|
-
if (c.value === undefined)
|
|
188529
|
-
continue;
|
|
188530
|
-
const literal = parsePureStringLiteral(c.value);
|
|
188531
|
-
if (literal !== null)
|
|
188532
|
-
map.set(c.name, literal);
|
|
188533
|
-
}
|
|
188534
|
-
return map;
|
|
188535
|
-
}
|
|
188536
188583
|
function isStringTypeInfo(type2) {
|
|
188537
188584
|
return type2?.kind === "primitive" && type2.primitive === "string";
|
|
188538
188585
|
}
|
|
@@ -188574,6 +188621,9 @@ class XslateFilterEmitter {
|
|
|
188574
188621
|
}
|
|
188575
188622
|
return `${emit(object)}.${property}`;
|
|
188576
188623
|
}
|
|
188624
|
+
indexAccess(object, index, emit) {
|
|
188625
|
+
return `${emit(object)}[${emit(index)}]`;
|
|
188626
|
+
}
|
|
188577
188627
|
call(callee, args, emit) {
|
|
188578
188628
|
if (callee.kind === "identifier" && args.length === 0) {
|
|
188579
188629
|
return `$${callee.name}`;
|
|
@@ -188657,9 +188707,14 @@ class XslateTopLevelEmitter {
|
|
|
188657
188707
|
this.adapter = adapter;
|
|
188658
188708
|
}
|
|
188659
188709
|
identifier(name) {
|
|
188710
|
+
if (name === "undefined" || name === "null")
|
|
188711
|
+
return "nil";
|
|
188660
188712
|
const inlined = this.adapter._resolveModuleStringConst(name);
|
|
188661
188713
|
if (inlined !== null)
|
|
188662
188714
|
return inlined;
|
|
188715
|
+
const literalConst = this.adapter._resolveLiteralConst(name);
|
|
188716
|
+
if (literalConst !== null)
|
|
188717
|
+
return literalConst;
|
|
188663
188718
|
return `$${name}`;
|
|
188664
188719
|
}
|
|
188665
188720
|
literal(value, literalType) {
|
|
@@ -188675,15 +188730,29 @@ class XslateTopLevelEmitter {
|
|
|
188675
188730
|
if (object.kind === "identifier" && object.name === "props") {
|
|
188676
188731
|
return `$${property}`;
|
|
188677
188732
|
}
|
|
188733
|
+
if (object.kind === "identifier") {
|
|
188734
|
+
const staticValue = this.adapter._resolveStaticRecordLiteral(object.name, property);
|
|
188735
|
+
if (staticValue !== null)
|
|
188736
|
+
return staticValue;
|
|
188737
|
+
}
|
|
188678
188738
|
const obj = emit(object);
|
|
188679
188739
|
if (property === "length")
|
|
188680
188740
|
return `$bf.length(${obj})`;
|
|
188681
188741
|
return `${obj}.${property}`;
|
|
188682
188742
|
}
|
|
188743
|
+
indexAccess(object, index, emit) {
|
|
188744
|
+
return `${emit(object)}[${emit(index)}]`;
|
|
188745
|
+
}
|
|
188683
188746
|
call(callee, args, emit) {
|
|
188684
188747
|
if (callee.kind === "identifier" && args.length === 0) {
|
|
188685
188748
|
return `$${callee.name}`;
|
|
188686
188749
|
}
|
|
188750
|
+
if (this.adapter._searchParamsLocals.size > 0) {
|
|
188751
|
+
const sp = matchSearchParamsMethodCall(callee, args, this.adapter._searchParamsLocals);
|
|
188752
|
+
if (sp) {
|
|
188753
|
+
return `$searchParams.${sp.method}(${sp.args.map(emit).join(", ")})`;
|
|
188754
|
+
}
|
|
188755
|
+
}
|
|
188687
188756
|
const path = identifierPath(callee);
|
|
188688
188757
|
const spec = path ? XSLATE_TEMPLATE_PRIMITIVES[path] : undefined;
|
|
188689
188758
|
if (path && spec) {
|
|
@@ -64,6 +64,7 @@ export declare class XslateAdapter extends BaseAdapter implements IRNodeEmitter<
|
|
|
64
64
|
*/
|
|
65
65
|
private propsObjectName;
|
|
66
66
|
private propsParams;
|
|
67
|
+
private booleanTypedProps;
|
|
67
68
|
/**
|
|
68
69
|
* Names (signal getters + props) whose value is a string, so `===`/`!==`
|
|
69
70
|
* against them lowers to Perl `eq`/`ne` rather than numeric `==`/`!=`.
|
|
@@ -80,6 +81,15 @@ export declare class XslateAdapter extends BaseAdapter implements IRNodeEmitter<
|
|
|
80
81
|
* `moduleStringConsts` fix.
|
|
81
82
|
*/
|
|
82
83
|
private moduleStringConsts;
|
|
84
|
+
/**
|
|
85
|
+
* (#1922) Local binding names the request-scoped `searchParams()` env signal
|
|
86
|
+
* is imported under (handles `import { searchParams as sp }`). When non-empty
|
|
87
|
+
* the emitter lowers a `<binding>().get(k)` call to a real method call on the
|
|
88
|
+
* per-request `$searchParams` reader (`$searchParams.get('sort')`) instead of
|
|
89
|
+
* the generic dot deref. Set at `generate()` entry from `ir.metadata.imports`;
|
|
90
|
+
* read by the top-level ParsedExpr emitter.
|
|
91
|
+
*/
|
|
92
|
+
_searchParamsLocals: Set<string>;
|
|
83
93
|
/**
|
|
84
94
|
* Local + module constants from the IR, used by the conditional-spread and
|
|
85
95
|
* `Record<staticKeys, scalar>[propKey]` lowering paths (#textarea / #checkbox).
|
|
@@ -117,6 +127,25 @@ export declare class XslateAdapter extends BaseAdapter implements IRNodeEmitter<
|
|
|
117
127
|
emitProvider(node: IRProvider, _ctx: XslateRenderCtx, _emit: EmitIRNode<XslateRenderCtx>): string;
|
|
118
128
|
/** Lower a `<Ctx.Provider value>` value prop to a Kolon expression. */
|
|
119
129
|
private providerValueKolon;
|
|
130
|
+
/**
|
|
131
|
+
* Lower an object-literal provider value (`value={{ open: () => props.open
|
|
132
|
+
* ?? false, onOpenChange: … }}`) to a Kolon hashref literal (#1897). The
|
|
133
|
+
* SSR lowering is a per-member snapshot of what a consumer would READ
|
|
134
|
+
* during the same render:
|
|
135
|
+
*
|
|
136
|
+
* - zero-param expression-body arrows are getters — lower the body (the
|
|
137
|
+
* value is fixed for the render, so the call-time indirection drops out)
|
|
138
|
+
* - `on[A-Z]`-named members and function-shaped values are client-only
|
|
139
|
+
* behavior SSR never invokes — lower to `nil`
|
|
140
|
+
* - anything else lowers through the normal expression pipeline (so an
|
|
141
|
+
* unsupported getter body still refuses loudly with BF101)
|
|
142
|
+
*
|
|
143
|
+
* Keys keep their JS names verbatim so a consumer-side `ctx.open` access
|
|
144
|
+
* maps onto the same key. Returns `null` when the expression is not a
|
|
145
|
+
* plain object literal (spread / computed key) — the caller falls back to
|
|
146
|
+
* the whole-expression path, which refuses those shapes with BF101.
|
|
147
|
+
*/
|
|
148
|
+
private providerObjectLiteralKolon;
|
|
120
149
|
/** Kolon literal for a context-consumer's `createContext` default. */
|
|
121
150
|
private contextDefaultKolon;
|
|
122
151
|
/**
|
|
@@ -172,6 +201,9 @@ export declare class XslateAdapter extends BaseAdapter implements IRNodeEmitter<
|
|
|
172
201
|
private readonly componentPropEmitter;
|
|
173
202
|
renderComponent(comp: IRComponent): string;
|
|
174
203
|
private childrenCaptureCounter;
|
|
204
|
+
/** Uniquifies the `presenceOrUndefined` temp binding (`$bf_puN`) so two
|
|
205
|
+
* presence-folded attrs in one template don't collide. */
|
|
206
|
+
private presenceVarCounter;
|
|
175
207
|
private toTemplateName;
|
|
176
208
|
private renderIfStatement;
|
|
177
209
|
private renderFragment;
|
|
@@ -267,6 +299,36 @@ export declare class XslateAdapter extends BaseAdapter implements IRNodeEmitter<
|
|
|
267
299
|
* normal `$name` stash lowering). Loop-bound names shadow module consts, so
|
|
268
300
|
* never inline inside a loop body. Returns `'<escaped>'`.
|
|
269
301
|
*/
|
|
302
|
+
/**
|
|
303
|
+
* Resolve `IDENT.key` over a module object-literal const to its Kolon
|
|
304
|
+
* literal (`variantClasses.ghost` in a class template literal —
|
|
305
|
+
* #1897). Same compile-time inlining family as
|
|
306
|
+
* `_resolveModuleStringConst`; returns `null` for any non-static shape.
|
|
307
|
+
*/
|
|
308
|
+
/**
|
|
309
|
+
* Whether `expr` is a bare reference to a boolean-TYPED prop
|
|
310
|
+
* (`props.isActive` / destructured `isActive`) — used to route the
|
|
311
|
+
* binding through `bool_str` even though the expression itself is
|
|
312
|
+
* structurally opaque (#1897).
|
|
313
|
+
*/
|
|
314
|
+
/**
|
|
315
|
+
* Parse `cond ? value : undefined` (or `: null`), returning the
|
|
316
|
+
* condition/consequent source spans, else `null`. Used for the
|
|
317
|
+
* attribute-omission rule (#1897).
|
|
318
|
+
*/
|
|
319
|
+
parseUndefinedAlternateTernary(expr: string): {
|
|
320
|
+
condition: string;
|
|
321
|
+
consequent: string;
|
|
322
|
+
} | null;
|
|
323
|
+
isBooleanTypedPropRef(expr: string): boolean;
|
|
324
|
+
/**
|
|
325
|
+
* Inline a const (any scope) whose initializer is a pure numeric or
|
|
326
|
+
* single-quoted string literal (`const totalPages = 5`, #1897
|
|
327
|
+
* pagination) — function-scope consts never reach the per-render
|
|
328
|
+
* stash, so a bare `$totalPages` renders empty.
|
|
329
|
+
*/
|
|
330
|
+
_resolveLiteralConst(name: string): string | null;
|
|
331
|
+
_resolveStaticRecordLiteral(objectName: string, key: string): string | null;
|
|
270
332
|
_resolveModuleStringConst(name: string): string | null;
|
|
271
333
|
_recordExprBF101(message: string, reason?: string): void;
|
|
272
334
|
/** Internal hook for higher-order: predicate body re-uses the filter emitter. */
|
|
@@ -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,EAE1B,MAAM,iBAAiB,CAAA;AACxB,OAAO,EACL,WAAW,EACX,KAAK,aAAa,EAClB,KAAK,sBAAsB,EAM3B,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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"}
|