@barefootjs/go-template 0.33.4 → 0.33.6
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 +12 -0
- package/dist/adapter/emit-context.d.ts.map +1 -1
- package/dist/adapter/go-template-adapter.d.ts +153 -7
- package/dist/adapter/go-template-adapter.d.ts.map +1 -1
- package/dist/adapter/index.js +202 -87
- package/dist/adapter/lib/compile-state.d.ts +17 -0
- package/dist/adapter/lib/compile-state.d.ts.map +1 -1
- package/dist/adapter/value/parsed-literal-to-go.d.ts.map +1 -1
- package/dist/adapter/value/value-lowering.d.ts.map +1 -1
- package/dist/conformance-pins.d.ts.map +1 -1
- package/dist/index.js +210 -91
- package/dist/render-divergences.d.ts +10 -0
- package/dist/render-divergences.d.ts.map +1 -1
- package/dist/vite.js +284 -150
- package/package.json +5 -5
- package/src/__tests__/go-template-adapter.test.ts +333 -1
- package/src/adapter/emit-context.ts +14 -0
- package/src/adapter/go-template-adapter.ts +476 -104
- package/src/adapter/lib/compile-state.ts +18 -0
- package/src/adapter/value/parsed-literal-to-go.ts +11 -7
- package/src/adapter/value/value-lowering.ts +17 -0
- package/src/conformance-pins.ts +19 -0
- package/src/render-divergences.ts +12 -6
- package/src/test-render.ts +32 -15
package/dist/adapter/index.js
CHANGED
|
@@ -28,7 +28,8 @@ import {
|
|
|
28
28
|
dangerousInnerHtmlDiagnostic,
|
|
29
29
|
collectLoopBoundNames as collectLoopBoundNames2,
|
|
30
30
|
evaluateStaticLiteral as evaluateStaticLiteral3,
|
|
31
|
-
BindingScope
|
|
31
|
+
BindingScope,
|
|
32
|
+
buildImportAliasMap
|
|
32
33
|
} from "@barefootjs/jsx";
|
|
33
34
|
import { findInterpolationEnd } from "@barefootjs/jsx/scanner";
|
|
34
35
|
import { BF_REGION, escapeHtml, resolveJsxChildrenProp } from "@barefootjs/shared";
|
|
@@ -303,6 +304,7 @@ class CompileState {
|
|
|
303
304
|
componentName = "";
|
|
304
305
|
errors = [];
|
|
305
306
|
referencedDerivedConsts = new Set;
|
|
307
|
+
templateReadRootFields = new Set;
|
|
306
308
|
templateVarCounter = 0;
|
|
307
309
|
pendingChildrenDefines = [];
|
|
308
310
|
propsObjectName = null;
|
|
@@ -1170,6 +1172,15 @@ function convertInitialValue(ctx, value, _typeInfo, propsParams, preParsed) {
|
|
|
1170
1172
|
if (param2) {
|
|
1171
1173
|
return propRef(param2);
|
|
1172
1174
|
}
|
|
1175
|
+
const inlinedStr = ctx.resolveModuleStringConst(value);
|
|
1176
|
+
if (inlinedStr !== null)
|
|
1177
|
+
return inlinedStr;
|
|
1178
|
+
const inlinedNum = ctx.resolveModuleNumericConst(value);
|
|
1179
|
+
if (inlinedNum !== null)
|
|
1180
|
+
return inlinedNum;
|
|
1181
|
+
const inlinedBool = ctx.resolveModuleBooleanConst(value);
|
|
1182
|
+
if (inlinedBool !== null)
|
|
1183
|
+
return inlinedBool;
|
|
1173
1184
|
}
|
|
1174
1185
|
const propName = ctx.extractPropNameFromInitialValue(value, preParsed);
|
|
1175
1186
|
const param = propName ? propsParams?.find((p) => p.name === propName) : undefined;
|
|
@@ -2890,7 +2901,9 @@ class GoTemplateAdapter extends BaseAdapter {
|
|
|
2890
2901
|
extractPropNameFromInitialValue: (initialValue, preParsed) => this.extractPropNameFromInitialValue(initialValue, preParsed),
|
|
2891
2902
|
extractPropFallback: (initialValue, preParsed) => this.extractPropFallback(initialValue, preParsed),
|
|
2892
2903
|
extractCollisionDerivation: (parsed) => this.extractCollisionDerivation(parsed),
|
|
2893
|
-
resolveModuleStringConst: (name) => this.resolveModuleStringConst(name)
|
|
2904
|
+
resolveModuleStringConst: (name) => this.resolveModuleStringConst(name),
|
|
2905
|
+
resolveModuleNumericConst: (name) => this.resolveModuleNumericConst(name),
|
|
2906
|
+
resolveModuleBooleanConst: (name) => this.resolveModuleBooleanConst(name)
|
|
2894
2907
|
};
|
|
2895
2908
|
get errors() {
|
|
2896
2909
|
return this.state.errors;
|
|
@@ -2907,6 +2920,10 @@ class GoTemplateAdapter extends BaseAdapter {
|
|
|
2907
2920
|
staticLoopBakeFailed = false;
|
|
2908
2921
|
childComponentShapes = new Map;
|
|
2909
2922
|
childContextConsumers = new Map;
|
|
2923
|
+
importAliases = new Map;
|
|
2924
|
+
resolveChildName(name) {
|
|
2925
|
+
return this.importAliases.get(name) ?? name;
|
|
2926
|
+
}
|
|
2910
2927
|
constructor(options = {}) {
|
|
2911
2928
|
super();
|
|
2912
2929
|
this.options = {
|
|
@@ -2918,6 +2935,7 @@ class GoTemplateAdapter extends BaseAdapter {
|
|
|
2918
2935
|
primeCompileState(ir) {
|
|
2919
2936
|
this.state.propsObjectName = ir.metadata.propsObjectName;
|
|
2920
2937
|
this.state.restPropsName = ir.metadata.restPropsName ?? null;
|
|
2938
|
+
this.importAliases = buildImportAliasMap(ir.metadata.imports ?? []);
|
|
2921
2939
|
this.state.objectTypedPropNames = new Set((ir.metadata.propsParams ?? []).filter((p) => p.type.kind === "object").map((p) => p.name));
|
|
2922
2940
|
this.state.moduleStringConsts = this.collectModuleStringConsts(ir.metadata.localConstants);
|
|
2923
2941
|
this.state.localConstants = ir.metadata.localConstants ?? [];
|
|
@@ -2952,6 +2970,7 @@ class GoTemplateAdapter extends BaseAdapter {
|
|
|
2952
2970
|
this.state.componentName = ir.metadata.componentName;
|
|
2953
2971
|
this.state.errors = [];
|
|
2954
2972
|
this.state.referencedDerivedConsts = new Set;
|
|
2973
|
+
this.state.templateReadRootFields = new Set;
|
|
2955
2974
|
this.state.templateVarCounter = 0;
|
|
2956
2975
|
this.state.pendingChildrenDefines = [];
|
|
2957
2976
|
this.scope = BindingScope.EMPTY;
|
|
@@ -2980,7 +2999,7 @@ ${scriptRegistrations}${templateBody}
|
|
|
2980
2999
|
template += `{{define "${d.name}"}}${d.content}{{end}}
|
|
2981
3000
|
`;
|
|
2982
3001
|
}
|
|
2983
|
-
const types = this.generateTypes(ir);
|
|
3002
|
+
const types = this.generateTypes(ir, true);
|
|
2984
3003
|
if (this.state.errors.length > 0) {
|
|
2985
3004
|
ir.errors.push(...this.state.errors);
|
|
2986
3005
|
}
|
|
@@ -3209,9 +3228,12 @@ ${scriptRegistrations}${templateBody}
|
|
|
3209
3228
|
taken.add(desired);
|
|
3210
3229
|
return desired;
|
|
3211
3230
|
}
|
|
3212
|
-
generateTypes(ir) {
|
|
3231
|
+
generateTypes(ir, preserveTemplateReadRootFields = false) {
|
|
3213
3232
|
this.state.usesHtmlTemplate = false;
|
|
3214
3233
|
this.state.usesFmt = false;
|
|
3234
|
+
if (!preserveTemplateReadRootFields) {
|
|
3235
|
+
this.state.templateReadRootFields = new Set;
|
|
3236
|
+
}
|
|
3215
3237
|
this.primeCompileState(ir);
|
|
3216
3238
|
const lines = [];
|
|
3217
3239
|
const componentName = ir.metadata.componentName;
|
|
@@ -3355,10 +3377,17 @@ ${goFields.join(`
|
|
|
3355
3377
|
const node = signal.parsed;
|
|
3356
3378
|
if (!node || node.kind !== "array-literal" || node.elements.length === 0)
|
|
3357
3379
|
return null;
|
|
3380
|
+
const name = `${componentName}${capitalizeFieldName(signal.getter)}Item`;
|
|
3381
|
+
return this.synthesizeStructsFromElements(node.elements, name);
|
|
3382
|
+
}
|
|
3383
|
+
synthesizeStructsFromElements(elements, name) {
|
|
3384
|
+
if (this.state.localTypeNames.has(name))
|
|
3385
|
+
return null;
|
|
3358
3386
|
const order = [];
|
|
3359
|
-
const
|
|
3360
|
-
|
|
3361
|
-
|
|
3387
|
+
const shapes = new Map;
|
|
3388
|
+
const nestedElements = new Map;
|
|
3389
|
+
for (let i = 0;i < elements.length; i++) {
|
|
3390
|
+
const el = elements[i];
|
|
3362
3391
|
if (el.kind !== "object-literal")
|
|
3363
3392
|
return null;
|
|
3364
3393
|
const seen = new Set;
|
|
@@ -3370,37 +3399,93 @@ ${goFields.join(`
|
|
|
3370
3399
|
const key = prop.key;
|
|
3371
3400
|
if (!GO_IDENTIFIER.test(key))
|
|
3372
3401
|
return null;
|
|
3402
|
+
seen.add(key);
|
|
3403
|
+
const isNestedArray = prop.value.kind === "array-literal" && prop.value.elements.every((e) => e.kind === "object-literal");
|
|
3404
|
+
if (isNestedArray) {
|
|
3405
|
+
const prevShape2 = shapes.get(key);
|
|
3406
|
+
if (prevShape2 === undefined) {
|
|
3407
|
+
if (i !== 0)
|
|
3408
|
+
return null;
|
|
3409
|
+
order.push(key);
|
|
3410
|
+
shapes.set(key, { kind: "nested-array" });
|
|
3411
|
+
nestedElements.set(key, []);
|
|
3412
|
+
} else if (prevShape2.kind !== "nested-array") {
|
|
3413
|
+
return null;
|
|
3414
|
+
}
|
|
3415
|
+
nestedElements.get(key).push(...prop.value.elements);
|
|
3416
|
+
continue;
|
|
3417
|
+
}
|
|
3373
3418
|
const goType = this.scalarParsedGoType(prop.value);
|
|
3374
3419
|
if (!goType)
|
|
3375
3420
|
return null;
|
|
3376
|
-
|
|
3377
|
-
|
|
3378
|
-
if (prev === undefined) {
|
|
3421
|
+
const prevShape = shapes.get(key);
|
|
3422
|
+
if (prevShape === undefined) {
|
|
3379
3423
|
if (i !== 0)
|
|
3380
3424
|
return null;
|
|
3381
3425
|
order.push(key);
|
|
3382
|
-
|
|
3426
|
+
shapes.set(key, { kind: "scalar", goType });
|
|
3427
|
+
} else if (prevShape.kind !== "scalar") {
|
|
3428
|
+
return null;
|
|
3383
3429
|
} else {
|
|
3384
|
-
const merged = this.mergeScalarGoType(
|
|
3430
|
+
const merged = this.mergeScalarGoType(prevShape.goType, goType);
|
|
3385
3431
|
if (!merged)
|
|
3386
3432
|
return null;
|
|
3387
|
-
|
|
3433
|
+
shapes.set(key, { kind: "scalar", goType: merged });
|
|
3388
3434
|
}
|
|
3389
3435
|
}
|
|
3390
3436
|
if (seen.size !== order.length)
|
|
3391
3437
|
return null;
|
|
3392
3438
|
}
|
|
3393
|
-
const
|
|
3394
|
-
|
|
3395
|
-
|
|
3396
|
-
|
|
3439
|
+
const nestedStructs = [];
|
|
3440
|
+
const fields = [];
|
|
3441
|
+
const properties = [];
|
|
3442
|
+
for (const key of order) {
|
|
3443
|
+
const shape = shapes.get(key);
|
|
3444
|
+
if (shape.kind === "scalar") {
|
|
3445
|
+
fields.push({ tsName: key, goName: capitalizeFieldName(key), goType: shape.goType });
|
|
3446
|
+
properties.push({ name: key, type: this.scalarGoTypeToTypeInfo(shape.goType), optional: false, readonly: false });
|
|
3447
|
+
continue;
|
|
3448
|
+
}
|
|
3449
|
+
const nestedList = nestedElements.get(key);
|
|
3450
|
+
if (nestedList.length === 0)
|
|
3451
|
+
return null;
|
|
3452
|
+
const nestedName = `${name}${capitalizeFieldName(key)}Item`;
|
|
3453
|
+
const nested = this.synthesizeStructsFromElements(nestedList, nestedName);
|
|
3454
|
+
if (!nested)
|
|
3455
|
+
return null;
|
|
3456
|
+
nestedStructs.push(...nested);
|
|
3457
|
+
fields.push({ tsName: key, goName: capitalizeFieldName(key), goType: `[]${nestedName}` });
|
|
3458
|
+
properties.push({ name: key, type: this.synthSliceTypeInfo(nestedName), optional: false, readonly: false });
|
|
3459
|
+
}
|
|
3460
|
+
return [...nestedStructs, { name, fields, properties }];
|
|
3461
|
+
}
|
|
3462
|
+
scalarGoTypeToTypeInfo(goType) {
|
|
3463
|
+
if (goType === "string")
|
|
3464
|
+
return { kind: "primitive", raw: "string", primitive: "string" };
|
|
3465
|
+
if (goType === "bool")
|
|
3466
|
+
return { kind: "primitive", raw: "boolean", primitive: "boolean" };
|
|
3467
|
+
return { kind: "primitive", raw: "number", primitive: "number" };
|
|
3468
|
+
}
|
|
3469
|
+
synthSliceTypeInfo(name) {
|
|
3470
|
+
return { kind: "array", raw: `${name}[]`, elementType: { kind: "interface", raw: name } };
|
|
3471
|
+
}
|
|
3472
|
+
registerSynthStruct(lines, name, fields, properties, comment) {
|
|
3473
|
+
this.state.localTypeNames.add(name);
|
|
3474
|
+
this.state.localStructFields.set(name, new Map(fields.map((f) => [f.tsName, f.goName])));
|
|
3475
|
+
this.state.currentTypeDefinitions.push({
|
|
3476
|
+
kind: "type",
|
|
3397
3477
|
name,
|
|
3398
|
-
|
|
3399
|
-
|
|
3400
|
-
|
|
3401
|
-
|
|
3402
|
-
|
|
3403
|
-
|
|
3478
|
+
definition: "",
|
|
3479
|
+
properties,
|
|
3480
|
+
loc: SYNTH_TYPE_LOC
|
|
3481
|
+
});
|
|
3482
|
+
const goFields = fields.map((f) => ` ${f.goName} ${f.goType} \`json:"${this.toJsonTag(f.tsName)}"\``);
|
|
3483
|
+
lines.push(comment);
|
|
3484
|
+
lines.push(`type ${name} struct {
|
|
3485
|
+
${goFields.join(`
|
|
3486
|
+
`)}
|
|
3487
|
+
}`);
|
|
3488
|
+
lines.push("");
|
|
3404
3489
|
}
|
|
3405
3490
|
scalarParsedGoType(value) {
|
|
3406
3491
|
if (value.kind === "unary" && value.op === "-" && value.argument.kind === "literal") {
|
|
@@ -3467,7 +3552,7 @@ ${goFields.join(`
|
|
|
3467
3552
|
for (const nested of inputNested) {
|
|
3468
3553
|
if (nested.loopMarkerId && this.getBakedStaticChildLoop(nested.loopMarkerId, nested, nested.loopArrayParsed, nested.loopParam, nested.loopKey))
|
|
3469
3554
|
continue;
|
|
3470
|
-
lines.push(` ${nested.name}s []${nested.name}Input`);
|
|
3555
|
+
lines.push(` ${nested.name}s []${this.resolveChildName(nested.name)}Input`);
|
|
3471
3556
|
}
|
|
3472
3557
|
const takenInput = new Set(this.propParamFieldNamesUnion(ir.metadata.propsParams));
|
|
3473
3558
|
for (const c of this.nonCollidingContextConsumers(takenInput)) {
|
|
@@ -3503,10 +3588,11 @@ ${goFields.join(`
|
|
|
3503
3588
|
const wrapperName = this.loopBodyWrapperName(parentComponentName, nested);
|
|
3504
3589
|
const datumFields = this.resolveLoopDatumFields(nested.loopItemType);
|
|
3505
3590
|
const bodyChildInstances = this.collectBodyChildInstances(nested.bodyChildren);
|
|
3506
|
-
|
|
3591
|
+
const declaredName = this.resolveChildName(nested.name);
|
|
3592
|
+
lines.push(`// ${wrapperName} wraps ${declaredName}Props with per-row loop datum`);
|
|
3507
3593
|
lines.push(`// fields and child component slots for the loop body children. (#1897)`);
|
|
3508
3594
|
lines.push(`type ${wrapperName} struct {`);
|
|
3509
|
-
lines.push(` ${
|
|
3595
|
+
lines.push(` ${declaredName}Props`);
|
|
3510
3596
|
for (const f of datumFields) {
|
|
3511
3597
|
lines.push(` ${f.goName} ${f.goType} \`json:"-"\``);
|
|
3512
3598
|
}
|
|
@@ -3515,7 +3601,7 @@ ${goFields.join(`
|
|
|
3515
3601
|
lines.push(` BfLoopItem ${scalarLoopType} \`json:"-"\``);
|
|
3516
3602
|
}
|
|
3517
3603
|
for (const child of bodyChildInstances) {
|
|
3518
|
-
lines.push(` ${child.fieldName} ${child.name}Props \`json:"-"\``);
|
|
3604
|
+
lines.push(` ${child.fieldName} ${this.resolveChildName(child.name)}Props \`json:"-"\``);
|
|
3519
3605
|
}
|
|
3520
3606
|
lines.push("}");
|
|
3521
3607
|
lines.push("");
|
|
@@ -3599,12 +3685,13 @@ ${goFields.join(`
|
|
|
3599
3685
|
const staticWithoutBody = staticNested.filter((n) => !n.bodyChildren || n.bodyChildren.length === 0);
|
|
3600
3686
|
for (const nested of staticWithoutBody) {
|
|
3601
3687
|
const varName = `${nested.name.charAt(0).toLowerCase()}${nested.name.slice(1)}s`;
|
|
3688
|
+
const declaredName = this.resolveChildName(nested.name);
|
|
3602
3689
|
const baked = nested.loopMarkerId ? this.getBakedStaticChildLoop(nested.loopMarkerId, nested, nested.loopArrayParsed, nested.loopParam, nested.loopKey) : null;
|
|
3603
3690
|
if (baked) {
|
|
3604
|
-
lines.push(` ${varName} := make([]${
|
|
3691
|
+
lines.push(` ${varName} := make([]${declaredName}Props, ${baked.items.length})`);
|
|
3605
3692
|
baked.items.forEach((item, i) => {
|
|
3606
3693
|
const fields = item.inputFields.map((f) => `${f.goField}: ${f.goValue}`).join(", ");
|
|
3607
|
-
lines.push(` ${varName}[${i}] = New${
|
|
3694
|
+
lines.push(` ${varName}[${i}] = New${declaredName}Props(${declaredName}Input{${fields}})`);
|
|
3608
3695
|
lines.push(` ${varName}[${i}].BfParent = scopeID`);
|
|
3609
3696
|
lines.push(` ${varName}[${i}].BfMount = "${nested.slotId}"`);
|
|
3610
3697
|
if (item.dataKey !== null) {
|
|
@@ -3614,9 +3701,9 @@ ${goFields.join(`
|
|
|
3614
3701
|
lines.push("");
|
|
3615
3702
|
continue;
|
|
3616
3703
|
}
|
|
3617
|
-
lines.push(` ${varName} := make([]${
|
|
3704
|
+
lines.push(` ${varName} := make([]${declaredName}Props, len(in.${nested.name}s))`);
|
|
3618
3705
|
lines.push(` for i, item := range in.${nested.name}s {`);
|
|
3619
|
-
lines.push(` ${varName}[i] = New${
|
|
3706
|
+
lines.push(` ${varName}[i] = New${declaredName}Props(item)`);
|
|
3620
3707
|
lines.push(` ${varName}[i].BfParent = scopeID`);
|
|
3621
3708
|
lines.push(` ${varName}[i].BfMount = "${nested.slotId}"`);
|
|
3622
3709
|
const keyField = loopKeyToGoFieldPath(nested.loopKey, nested.loopParam);
|
|
@@ -3731,8 +3818,14 @@ ${goFields.join(`
|
|
|
3731
3818
|
lines.push(` ${fieldName}: ${hoisted.varName},`);
|
|
3732
3819
|
} else {
|
|
3733
3820
|
const bakeType = this.state.synthStructTypes.get(signal.getter) ?? signal.type;
|
|
3821
|
+
const resolvedParsed = this.resolvedSignalParsed(signal);
|
|
3734
3822
|
const initialValue = convertInitialValue(this.emitCtx, signal.initialValue, bakeType, ir.metadata.propsParams, signal.parsed);
|
|
3735
3823
|
lines.push(` ${fieldName}: ${initialValue},`);
|
|
3824
|
+
if (resolvedParsed?.kind === "object-literal" && jsLiteralToGo(this.emitCtx, bakeType, resolvedParsed) === null) {
|
|
3825
|
+
const step = this.state.ssrSeedPlan.steps.find((s) => s.kind === "derived" && s.origin === "signal" && s.name === signal.getter);
|
|
3826
|
+
if (step?.kind === "derived")
|
|
3827
|
+
this.refuseUnbakeableDerivedObjectLiteral(signal.getter, signal.loc, step.frees);
|
|
3828
|
+
}
|
|
3736
3829
|
}
|
|
3737
3830
|
}
|
|
3738
3831
|
for (const nested of staticWithoutBody) {
|
|
@@ -3832,19 +3925,20 @@ ${goFields.join(`
|
|
|
3832
3925
|
emitStaticChildInstances(lines, ir) {
|
|
3833
3926
|
const staticChildren = this.collectStaticChildInstances(ir.root, ir.metadata.propsParams);
|
|
3834
3927
|
for (const child of staticChildren) {
|
|
3835
|
-
|
|
3928
|
+
const declaredName = this.resolveChildName(child.name);
|
|
3929
|
+
lines.push(` ${child.fieldName}: New${declaredName}Props(${declaredName}Input{`);
|
|
3836
3930
|
lines.push(` ScopeID: scopeID + "_${child.slotId}",`);
|
|
3837
3931
|
lines.push(` BfParent: scopeID,`);
|
|
3838
3932
|
lines.push(` BfMount: "${child.slotId}",`);
|
|
3839
3933
|
if (child.contextBindings) {
|
|
3840
|
-
for (const consumer of this.childContextConsumers.get(
|
|
3934
|
+
for (const consumer of this.childContextConsumers.get(declaredName) ?? []) {
|
|
3841
3935
|
const goVal = child.contextBindings.get(consumer.contextName);
|
|
3842
3936
|
if (goVal !== undefined) {
|
|
3843
3937
|
lines.push(` ${this.contextFieldName(consumer)}: ${goVal},`);
|
|
3844
3938
|
}
|
|
3845
3939
|
}
|
|
3846
3940
|
}
|
|
3847
|
-
const childShape = this.childComponentShapes.get(
|
|
3941
|
+
const childShape = this.childComponentShapes.get(declaredName);
|
|
3848
3942
|
const restBagEntries = [];
|
|
3849
3943
|
const emitChildField = (jsxName, goValue) => {
|
|
3850
3944
|
if (childShape && childShape.restBagField && !childShape.paramNames.has(jsxName)) {
|
|
@@ -3941,6 +4035,7 @@ ${goFields.join(`
|
|
|
3941
4035
|
lines.push(`// New${componentName}Props creates ${propsTypeName} from ${inputTypeName}.`);
|
|
3942
4036
|
for (const nested of signalDynamicNested) {
|
|
3943
4037
|
const arrayField = `${nested.name}s`;
|
|
4038
|
+
const declaredName = this.resolveChildName(nested.name);
|
|
3944
4039
|
lines.push(`//`);
|
|
3945
4040
|
lines.push(`// NOTE: \`${arrayField}\` is populated by the route handler, not by`);
|
|
3946
4041
|
lines.push(`// New${componentName}Props — the SSR template iterates over it`);
|
|
@@ -3948,9 +4043,9 @@ ${goFields.join(`
|
|
|
3948
4043
|
lines.push(`// assign it before passing the props to your renderer. Example:`);
|
|
3949
4044
|
lines.push(`//`);
|
|
3950
4045
|
lines.push(`// props := New${componentName}Props(${inputTypeName}{ /* ... */ })`);
|
|
3951
|
-
lines.push(`// props.${arrayField} = make([]${
|
|
4046
|
+
lines.push(`// props.${arrayField} = make([]${declaredName}Props, len(items))`);
|
|
3952
4047
|
lines.push(`// for i, item := range items {`);
|
|
3953
|
-
lines.push(`// props.${arrayField}[i] = New${
|
|
4048
|
+
lines.push(`// props.${arrayField}[i] = New${declaredName}Props(${declaredName}Input{ /* fields */ })`);
|
|
3954
4049
|
lines.push(`// props.${arrayField}[i].BfParent = props.ScopeID`);
|
|
3955
4050
|
lines.push(`// props.${arrayField}[i].BfMount = "${nested.slotId}"`);
|
|
3956
4051
|
lines.push(`// }`);
|
|
@@ -3989,9 +4084,11 @@ ${goFields.join(`
|
|
|
3989
4084
|
const wrapperType = this.loopBodyWrapperName(componentName, nested);
|
|
3990
4085
|
const datumFields = this.resolveLoopDatumFields(nested.loopItemType);
|
|
3991
4086
|
const bodyChildInstances = this.collectBodyChildInstances(nested.bodyChildren, ir.metadata.propsParams);
|
|
4087
|
+
const declaredName = this.resolveChildName(nested.name);
|
|
3992
4088
|
for (const child of bodyChildInstances) {
|
|
3993
4089
|
const childVar = `child_${child.fieldName}`;
|
|
3994
|
-
|
|
4090
|
+
const childDeclaredName = this.resolveChildName(child.name);
|
|
4091
|
+
lines.push(` ${childVar} := New${childDeclaredName}Props(${childDeclaredName}Input{`);
|
|
3995
4092
|
lines.push(` ScopeID: scopeID + "_${child.slotId}",`);
|
|
3996
4093
|
lines.push(` BfParent: scopeID,`);
|
|
3997
4094
|
lines.push(` BfMount: "${child.slotId}",`);
|
|
@@ -4011,7 +4108,7 @@ ${goFields.join(`
|
|
|
4011
4108
|
lines.push(` ${varName} := make([]${wrapperType}, len(${dataVar}))`);
|
|
4012
4109
|
lines.push(` for i, item := range ${dataVar} {`);
|
|
4013
4110
|
lines.push(` ${varName}[i] = ${wrapperType}{`);
|
|
4014
|
-
lines.push(` ${
|
|
4111
|
+
lines.push(` ${declaredName}Props: New${declaredName}Props(${declaredName}Input{`);
|
|
4015
4112
|
lines.push(` BfParent: scopeID,`);
|
|
4016
4113
|
lines.push(` BfMount: "${nested.slotId}",`);
|
|
4017
4114
|
for (const prop of nested.props ?? []) {
|
|
@@ -4066,9 +4163,11 @@ ${goFields.join(`
|
|
|
4066
4163
|
const varName = `${nested.name.charAt(0).toLowerCase()}${nested.name.slice(1)}s`;
|
|
4067
4164
|
const datumFields = this.resolveLoopDatumFields(nested.loopItemType);
|
|
4068
4165
|
const bodyChildInstances = this.collectBodyChildInstances(nested.bodyChildren, ir.metadata.propsParams);
|
|
4166
|
+
const declaredName = this.resolveChildName(nested.name);
|
|
4069
4167
|
for (const child of bodyChildInstances) {
|
|
4070
4168
|
const childVar = `child_${child.fieldName}`;
|
|
4071
|
-
|
|
4169
|
+
const childDeclaredName = this.resolveChildName(child.name);
|
|
4170
|
+
lines.push(` ${childVar} := New${childDeclaredName}Props(${childDeclaredName}Input{`);
|
|
4072
4171
|
lines.push(` ScopeID: scopeID + "_${child.slotId}",`);
|
|
4073
4172
|
lines.push(` BfParent: scopeID,`);
|
|
4074
4173
|
lines.push(` BfMount: "${child.slotId}",`);
|
|
@@ -4087,7 +4186,7 @@ ${goFields.join(`
|
|
|
4087
4186
|
lines.push(` ${varName} := make([]${wrapperType}, len(bakedData))`);
|
|
4088
4187
|
lines.push(` for i, item := range bakedData {`);
|
|
4089
4188
|
lines.push(` ${varName}[i] = ${wrapperType}{`);
|
|
4090
|
-
lines.push(` ${
|
|
4189
|
+
lines.push(` ${declaredName}Props: New${declaredName}Props(${declaredName}Input{`);
|
|
4091
4190
|
lines.push(` BfParent: scopeID,`);
|
|
4092
4191
|
lines.push(` BfMount: "${nested.slotId}",`);
|
|
4093
4192
|
lines.push(` }),`);
|
|
@@ -4142,21 +4241,7 @@ ${goFields.join(`
|
|
|
4142
4241
|
visit(prop.type, desiredName, prop.name);
|
|
4143
4242
|
}
|
|
4144
4243
|
const fields = this.structFieldsFor(typeInfo);
|
|
4145
|
-
this.
|
|
4146
|
-
this.state.currentTypeDefinitions.push({
|
|
4147
|
-
kind: "type",
|
|
4148
|
-
name: desiredName,
|
|
4149
|
-
definition: "",
|
|
4150
|
-
properties: typeInfo.properties ?? [],
|
|
4151
|
-
loc: SYNTH_TYPE_LOC
|
|
4152
|
-
});
|
|
4153
|
-
const goFields = fields.map((f) => ` ${f.goName} ${f.goType} \`json:"${this.toJsonTag(f.tsName)}"\``);
|
|
4154
|
-
lines.push(`// ${desiredName} is a synthesised type for an anonymous object type (#2674).`);
|
|
4155
|
-
lines.push(`type ${desiredName} struct {
|
|
4156
|
-
${goFields.join(`
|
|
4157
|
-
`)}
|
|
4158
|
-
}`);
|
|
4159
|
-
lines.push("");
|
|
4244
|
+
this.registerSynthStruct(lines, desiredName, fields, typeInfo.properties ?? [], `// ${desiredName} is a synthesised type for an anonymous object type (#2674).`);
|
|
4160
4245
|
};
|
|
4161
4246
|
const visitArrayElem = (elemType, parentName, propName) => {
|
|
4162
4247
|
if (!elemType)
|
|
@@ -4208,20 +4293,11 @@ ${goFields.join(`
|
|
|
4208
4293
|
const synth = this.synthesizeStructFromSignal(signal, componentName);
|
|
4209
4294
|
if (!synth)
|
|
4210
4295
|
continue;
|
|
4211
|
-
|
|
4212
|
-
|
|
4213
|
-
|
|
4214
|
-
|
|
4215
|
-
|
|
4216
|
-
elementType: { kind: "interface", raw: synth.name }
|
|
4217
|
-
});
|
|
4218
|
-
const goFields = synth.fields.map((f) => ` ${f.goName} ${f.goType} \`json:"${this.toJsonTag(f.tsName)}"\``);
|
|
4219
|
-
lines.push(`// ${synth.name} is a synthesised element type for the ${signal.getter} signal.`);
|
|
4220
|
-
lines.push(`type ${synth.name} struct {
|
|
4221
|
-
${goFields.join(`
|
|
4222
|
-
`)}
|
|
4223
|
-
}`);
|
|
4224
|
-
lines.push("");
|
|
4296
|
+
for (const s of synth) {
|
|
4297
|
+
this.registerSynthStruct(lines, s.name, s.fields, s.properties, `// ${s.name} is a synthesised element type for the ${signal.getter} signal.`);
|
|
4298
|
+
}
|
|
4299
|
+
const top = synth[synth.length - 1];
|
|
4300
|
+
this.state.synthStructTypes.set(signal.getter, this.synthSliceTypeInfo(top.name));
|
|
4225
4301
|
}
|
|
4226
4302
|
}
|
|
4227
4303
|
resolveNestedLoopItemTypes(ir, nestedComponents) {
|
|
@@ -4364,7 +4440,7 @@ ${goFields.join(`
|
|
|
4364
4440
|
for (const nested of nestedComponents) {
|
|
4365
4441
|
if (this.isOrphanedClientOnlyNested(nested))
|
|
4366
4442
|
continue;
|
|
4367
|
-
const elemType = nested.bodyChildren?.length ? this.loopBodyWrapperName(componentName, nested) : `${nested.name}Props`;
|
|
4443
|
+
const elemType = nested.bodyChildren?.length ? this.loopBodyWrapperName(componentName, nested) : `${this.resolveChildName(nested.name)}Props`;
|
|
4368
4444
|
if (nested.isDynamic && !nested.isPropDerived) {
|
|
4369
4445
|
lines.push(` ${nested.name}s []${elemType} \`json:"-"\``);
|
|
4370
4446
|
} else if (nested.isDynamic && nested.isPropDerived && !propDrivingFieldNames.has(`${nested.name}s`)) {
|
|
@@ -4376,7 +4452,7 @@ ${goFields.join(`
|
|
|
4376
4452
|
}
|
|
4377
4453
|
const staticChildren = this.collectStaticChildInstances(ir.root, ir.metadata.propsParams);
|
|
4378
4454
|
for (const child of staticChildren) {
|
|
4379
|
-
lines.push(` ${child.fieldName} ${child.name}Props \`json:"-"\``);
|
|
4455
|
+
lines.push(` ${child.fieldName} ${this.resolveChildName(child.name)}Props \`json:"-"\``);
|
|
4380
4456
|
}
|
|
4381
4457
|
for (const slot of spreadSlots) {
|
|
4382
4458
|
const jsonTag = "-";
|
|
@@ -4755,6 +4831,22 @@ ${goFields.join(`
|
|
|
4755
4831
|
resolvedSignalParsed(signal) {
|
|
4756
4832
|
return resolveSignalParsedThroughSeedPlan(this.state, signal);
|
|
4757
4833
|
}
|
|
4834
|
+
refuseUnbakeableDerivedObjectLiteral(name, loc, frees) {
|
|
4835
|
+
if (frees.length === 0)
|
|
4836
|
+
return;
|
|
4837
|
+
if (!this.state.templateReadRootFields.has(name))
|
|
4838
|
+
return;
|
|
4839
|
+
this.state.errors.push({
|
|
4840
|
+
code: "BF101",
|
|
4841
|
+
severity: "error",
|
|
4842
|
+
message: `Signal '${name}' is seeded from an object literal that references live value(s) (${frees.join(", ")}) — the Go template adapter bakes object-typed signal values into Go source at New${this.state.componentName}Props time, and that baker is static-only (identifier/member/call operands defer), so the SSR template's read of it would see the Go zero value instead of the derived object.`,
|
|
4843
|
+
loc,
|
|
4844
|
+
suggestion: {
|
|
4845
|
+
message: `Wrap each SSR read of '${name}()' in /* @client */ so it renders on the client instead, or pass the already-derived object in as a prop.`,
|
|
4846
|
+
escape: [{ kind: "client-directive" }]
|
|
4847
|
+
}
|
|
4848
|
+
});
|
|
4849
|
+
}
|
|
4758
4850
|
extractPropFallback(initialValue, preParsed) {
|
|
4759
4851
|
const structural = preParsed ? this.extractPropFallbackFromParsed(preParsed) : null;
|
|
4760
4852
|
if (structural)
|
|
@@ -5083,6 +5175,7 @@ ${goFields.join(`
|
|
|
5083
5175
|
return hit !== null && hit.depth > 0 && hit.binding.source === "item";
|
|
5084
5176
|
}
|
|
5085
5177
|
rootFieldRef(name) {
|
|
5178
|
+
this.state.templateReadRootFields.add(name);
|
|
5086
5179
|
const prefix = this.inLoop ? "$." : ".";
|
|
5087
5180
|
return `${prefix}${capitalizeFieldName(name)}`;
|
|
5088
5181
|
}
|
|
@@ -5104,6 +5197,9 @@ ${goFields.join(`
|
|
|
5104
5197
|
return null;
|
|
5105
5198
|
return `"${escapeGoString(value)}"`;
|
|
5106
5199
|
}
|
|
5200
|
+
findModuleConst(name) {
|
|
5201
|
+
return this.state.localConstants.find((k) => k.name === name && k.isModule && !k.containsArrow);
|
|
5202
|
+
}
|
|
5107
5203
|
resolveModuleNumericConst(name) {
|
|
5108
5204
|
if (this.isCurrentLoopItem(name))
|
|
5109
5205
|
return null;
|
|
@@ -5111,12 +5207,25 @@ ${goFields.join(`
|
|
|
5111
5207
|
return null;
|
|
5112
5208
|
if (this.isOuterLoopParam(name))
|
|
5113
5209
|
return null;
|
|
5114
|
-
const c = this.
|
|
5210
|
+
const c = this.findModuleConst(name);
|
|
5115
5211
|
if (!c || c.value === undefined)
|
|
5116
5212
|
return null;
|
|
5117
5213
|
const v = c.value.trim().replace(/(?<=\d)_(?=\d)/g, "");
|
|
5118
5214
|
return /^-?\d+(\.\d+)?$/.test(v) ? v : null;
|
|
5119
5215
|
}
|
|
5216
|
+
resolveModuleBooleanConst(name) {
|
|
5217
|
+
if (this.isCurrentLoopItem(name))
|
|
5218
|
+
return null;
|
|
5219
|
+
if (this.loopVarRefCount.has(name))
|
|
5220
|
+
return null;
|
|
5221
|
+
if (this.isOuterLoopParam(name))
|
|
5222
|
+
return null;
|
|
5223
|
+
const c = this.findModuleConst(name);
|
|
5224
|
+
if (!c || c.value === undefined)
|
|
5225
|
+
return null;
|
|
5226
|
+
const v = c.value.trim();
|
|
5227
|
+
return v === "true" || v === "false" ? v : null;
|
|
5228
|
+
}
|
|
5120
5229
|
literal(value, literalType) {
|
|
5121
5230
|
if (literalType === "string")
|
|
5122
5231
|
return `"${value}"`;
|
|
@@ -5754,8 +5863,10 @@ ${goFields.join(`
|
|
|
5754
5863
|
}
|
|
5755
5864
|
const signal = localVarMap.get(expr.name);
|
|
5756
5865
|
if (signal) {
|
|
5866
|
+
this.rootFieldRef(signal);
|
|
5757
5867
|
return `$.${capitalizeFieldName(signal)}`;
|
|
5758
5868
|
}
|
|
5869
|
+
this.rootFieldRef(expr.name);
|
|
5759
5870
|
return `.${capitalizeFieldName(expr.name)}`;
|
|
5760
5871
|
}
|
|
5761
5872
|
case "literal":
|
|
@@ -5788,6 +5899,7 @@ ${goFields.join(`
|
|
|
5788
5899
|
return `${paramPrefix}.${capitalizeFieldName(expr.callee.property)}`;
|
|
5789
5900
|
}
|
|
5790
5901
|
if (expr.callee.kind === "identifier" && expr.args.length === 0) {
|
|
5902
|
+
this.rootFieldRef(expr.callee.name);
|
|
5791
5903
|
return `$.${capitalizeFieldName(expr.callee.name)}`;
|
|
5792
5904
|
}
|
|
5793
5905
|
if (asCallbackMethodCall4(expr) !== null) {
|
|
@@ -5960,7 +6072,8 @@ ${goFields.join(`
|
|
|
5960
6072
|
return this.scope.isBound(name) || this.loopVarRefCount.has(name);
|
|
5961
6073
|
}
|
|
5962
6074
|
loopRowChildPropOverrides(comp) {
|
|
5963
|
-
const
|
|
6075
|
+
const declaredName = this.resolveChildName(comp.name);
|
|
6076
|
+
const childShape = this.childComponentShapes.get(declaredName);
|
|
5964
6077
|
const args = [];
|
|
5965
6078
|
let needsRebuild = false;
|
|
5966
6079
|
for (const prop of comp.props) {
|
|
@@ -5980,10 +6093,10 @@ ${goFields.join(`
|
|
|
5980
6093
|
if (!free || ![...free].some((name) => this.isLoopShadowedName(name)))
|
|
5981
6094
|
continue;
|
|
5982
6095
|
{
|
|
5983
|
-
const derived = this.childDerivedFieldDeps.get(
|
|
6096
|
+
const derived = this.childDerivedFieldDeps.get(declaredName);
|
|
5984
6097
|
const overriddenField = capitalizeFieldName(prop.name);
|
|
5985
6098
|
const staleField = derived ? [...derived].find(([, deps]) => deps.has(overriddenField))?.[0] : undefined;
|
|
5986
|
-
if (staleField && !this.childRepropsReady.has(
|
|
6099
|
+
if (staleField && !this.childRepropsReady.has(declaredName)) {
|
|
5987
6100
|
this.state.errors.push({
|
|
5988
6101
|
code: "BF101",
|
|
5989
6102
|
severity: "error",
|
|
@@ -5997,8 +6110,8 @@ ${goFields.join(`
|
|
|
5997
6110
|
}
|
|
5998
6111
|
if (staleField) {
|
|
5999
6112
|
needsRebuild = true;
|
|
6000
|
-
if (!this.repropsOwner.has(
|
|
6001
|
-
this.repropsOwner.set(
|
|
6113
|
+
if (!this.repropsOwner.has(declaredName)) {
|
|
6114
|
+
this.repropsOwner.set(declaredName, this.state.componentName);
|
|
6002
6115
|
}
|
|
6003
6116
|
}
|
|
6004
6117
|
}
|
|
@@ -6024,7 +6137,7 @@ ${goFields.join(`
|
|
|
6024
6137
|
});
|
|
6025
6138
|
continue;
|
|
6026
6139
|
}
|
|
6027
|
-
const fieldName = this.childPropFieldNames.get(
|
|
6140
|
+
const fieldName = this.childPropFieldNames.get(declaredName)?.get(prop.name) ?? capitalizeFieldName(prop.name);
|
|
6028
6141
|
args.push(`${JSON.stringify(fieldName)} ${wrapIfMultiToken(go)}`);
|
|
6029
6142
|
}
|
|
6030
6143
|
if (args.length === 0)
|
|
@@ -6570,7 +6683,8 @@ ${goFields.join(`
|
|
|
6570
6683
|
}
|
|
6571
6684
|
queueDynamicPropDefine(comp) {
|
|
6572
6685
|
const args = [];
|
|
6573
|
-
const
|
|
6686
|
+
const declaredName = this.resolveChildName(comp.name);
|
|
6687
|
+
const childShape = this.childComponentShapes.get(declaredName);
|
|
6574
6688
|
for (const prop of comp.props) {
|
|
6575
6689
|
if (prop.value.kind !== "jsx-children" || prop.name === "children")
|
|
6576
6690
|
continue;
|
|
@@ -6597,7 +6711,7 @@ ${goFields.join(`
|
|
|
6597
6711
|
content: this.renderChildren(children)
|
|
6598
6712
|
});
|
|
6599
6713
|
}
|
|
6600
|
-
const fieldName = this.childPropFieldNames.get(
|
|
6714
|
+
const fieldName = this.childPropFieldNames.get(declaredName)?.get(prop.name) ?? capitalizeFieldName(prop.name);
|
|
6601
6715
|
args.push(`${JSON.stringify(fieldName)} (bf_tmpl ${JSON.stringify(name)} .)`);
|
|
6602
6716
|
}
|
|
6603
6717
|
return args.length > 0 ? args.join(" ") : null;
|
|
@@ -6629,31 +6743,32 @@ ${goFields.join(`
|
|
|
6629
6743
|
if (comp.dynamicTag) {
|
|
6630
6744
|
return this.renderChildren(comp.children);
|
|
6631
6745
|
}
|
|
6746
|
+
const declaredName = this.resolveChildName(comp.name);
|
|
6632
6747
|
let templateCall;
|
|
6633
6748
|
if (this.inLoop && (this.loopWrapperStack[this.loopWrapperStack.length - 1] ?? false)) {
|
|
6634
6749
|
const loopBodyDefine = this.queueLoopBodyChildrenDefine(comp);
|
|
6635
6750
|
if (loopBodyDefine) {
|
|
6636
6751
|
const bodyData = this.loopScalarItemStack[this.loopScalarItemStack.length - 1] ? ".BfLoopItem" : ".";
|
|
6637
|
-
templateCall = `{{template "${
|
|
6752
|
+
templateCall = `{{template "${declaredName}" (bf_with_children . (bf_tmpl "${loopBodyDefine}" ${bodyData}))}}`;
|
|
6638
6753
|
} else {
|
|
6639
|
-
templateCall = `{{template "${
|
|
6754
|
+
templateCall = `{{template "${declaredName}" .}}`;
|
|
6640
6755
|
}
|
|
6641
6756
|
} else if (this.inLoop && comp.slotId) {
|
|
6642
6757
|
const suffix = slotIdToFieldSuffix(comp.slotId);
|
|
6643
6758
|
const overrides = this.loopRowChildPropOverrides(comp);
|
|
6644
6759
|
const loopBodyDefine = this.queueLoopBodyChildrenDefine(comp);
|
|
6645
|
-
const base = overrides ? overrides.helper === "bf_reprops" ? `(bf_reprops ${JSON.stringify(
|
|
6646
|
-
templateCall = loopBodyDefine ? `{{template "${
|
|
6760
|
+
const base = overrides ? overrides.helper === "bf_reprops" ? `(bf_reprops ${JSON.stringify(declaredName)} $.${comp.name}${suffix} ${overrides.args})` : `(bf_with_props $.${comp.name}${suffix} ${overrides.args})` : `$.${comp.name}${suffix}`;
|
|
6761
|
+
templateCall = loopBodyDefine ? `{{template "${declaredName}" (bf_with_children ${base} (bf_tmpl "${loopBodyDefine}" .))}}` : `{{template "${declaredName}" ${base}}}`;
|
|
6647
6762
|
} else if (this.inLoop) {
|
|
6648
|
-
templateCall = `{{template "${
|
|
6763
|
+
templateCall = `{{template "${declaredName}" .}}`;
|
|
6649
6764
|
} else if (comp.slotId) {
|
|
6650
6765
|
const suffix = slotIdToFieldSuffix(comp.slotId);
|
|
6651
6766
|
const childrenDefine = this.queueDynamicChildrenDefine(comp);
|
|
6652
6767
|
const propArgs = this.queueDynamicPropDefine(comp);
|
|
6653
6768
|
const base = propArgs ? `(bf_with_props .${comp.name}${suffix} ${propArgs})` : `.${comp.name}${suffix}`;
|
|
6654
|
-
templateCall = childrenDefine ? `{{template "${
|
|
6769
|
+
templateCall = childrenDefine ? `{{template "${declaredName}" (bf_with_children ${base} (bf_tmpl "${childrenDefine}" .))}}` : `{{template "${declaredName}" ${base}}}`;
|
|
6655
6770
|
} else {
|
|
6656
|
-
templateCall = `{{template "${
|
|
6771
|
+
templateCall = `{{template "${declaredName}" .${comp.name}}}`;
|
|
6657
6772
|
}
|
|
6658
6773
|
if (ctx?.isRootOfClientComponent) {
|
|
6659
6774
|
return `{{bfScopeComment .}}${templateCall}`;
|
|
@@ -21,6 +21,23 @@ export declare class CompileState {
|
|
|
21
21
|
* (e.g. `root` → `.Root`). `generateTypes` emits a computed field for each
|
|
22
22
|
* that's resolvable and non-colliding. */
|
|
23
23
|
referencedDerivedConsts: Set<string>;
|
|
24
|
+
/**
|
|
25
|
+
* Root-scope field names (signal getters, memo names, props, derived
|
|
26
|
+
* consts) the SSR template actually READ while rendering — recorded by
|
|
27
|
+
* `rootFieldRef`, the single door every such read passes through
|
|
28
|
+
* (`identifier`/`call`/`member`'s zero-arg-getter and bare-name lowering,
|
|
29
|
+
* plus the typed-expression emitter). `generateTypes` (#2700) consults
|
|
30
|
+
* this AFTER `generate()` has rendered the template to decide whether a
|
|
31
|
+
* signal whose object-literal initializer the constructor-time baker
|
|
32
|
+
* can't reproduce (`convertInitialValue` returning null) needs a loud
|
|
33
|
+
* BF101 refusal: a deferred bake that is NEVER read by the template (e.g.
|
|
34
|
+
* only feeds a spread-attrs bag, which routes through its own
|
|
35
|
+
* `.Spread_<slot>` field, never this set) silently keeping its Go zero
|
|
36
|
+
* value is harmless, so refusing it would be a false positive — see
|
|
37
|
+
* `refuseUnbakeableDerivedObjectLiteral`'s docstring for why the check is
|
|
38
|
+
* call-site-aware instead of firing at the bake site itself.
|
|
39
|
+
*/
|
|
40
|
+
templateReadRootFields: Set<string>;
|
|
24
41
|
templateVarCounter: number;
|
|
25
42
|
/**
|
|
26
43
|
* Companion `{{define "<Component>__children_<slot>"}}` blocks queued while
|