@barefootjs/go-template 0.33.3 → 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 +171 -7
- package/dist/adapter/go-template-adapter.d.ts.map +1 -1
- package/dist/adapter/index.js +237 -86
- 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 +251 -90
- package/dist/render-divergences.d.ts +20 -0
- package/dist/render-divergences.d.ts.map +1 -1
- package/dist/vite.js +319 -149
- package/package.json +5 -5
- package/src/__tests__/go-template-adapter.test.ts +342 -7
- package/src/adapter/emit-context.ts +14 -0
- package/src/adapter/go-template-adapter.ts +568 -103
- 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 +36 -0
- package/src/render-divergences.ts +22 -6
- package/src/test-render.ts +32 -15
package/dist/vite.js
CHANGED
|
@@ -8,7 +8,7 @@ import { devModuleUrl, loadManifest, resolveDevOrigin, resolveScriptAssets, toPo
|
|
|
8
8
|
import ts25 from "typescript";
|
|
9
9
|
|
|
10
10
|
// ../jsx/src/analyzer.ts
|
|
11
|
-
import
|
|
11
|
+
import ts10 from "typescript";
|
|
12
12
|
|
|
13
13
|
// ../jsx/src/expression-parser.ts
|
|
14
14
|
import ts from "typescript";
|
|
@@ -1939,7 +1939,7 @@ function identifierPath(callee) {
|
|
|
1939
1939
|
}
|
|
1940
1940
|
|
|
1941
1941
|
// ../jsx/src/prop-rewrite.ts
|
|
1942
|
-
import
|
|
1942
|
+
import ts7 from "typescript";
|
|
1943
1943
|
|
|
1944
1944
|
// ../jsx/src/ir-to-client-js/utils.ts
|
|
1945
1945
|
import ts3 from "typescript";
|
|
@@ -2166,19 +2166,61 @@ function resolveJsxChildrenProp(props) {
|
|
|
2166
2166
|
return [];
|
|
2167
2167
|
return prop.value.children ?? [];
|
|
2168
2168
|
}
|
|
2169
|
+
// ../jsx/src/ir-to-client-js/component-scope.ts
|
|
2170
|
+
function buildImportAliasMap(imports) {
|
|
2171
|
+
const aliases = new Map;
|
|
2172
|
+
for (const imp of imports) {
|
|
2173
|
+
if (imp.isTypeOnly)
|
|
2174
|
+
continue;
|
|
2175
|
+
for (const spec of imp.specifiers) {
|
|
2176
|
+
if (spec.isTypeOnly || spec.isDefault || spec.isNamespace || spec.alias === null)
|
|
2177
|
+
continue;
|
|
2178
|
+
aliases.set(spec.alias, spec.name);
|
|
2179
|
+
}
|
|
2180
|
+
}
|
|
2181
|
+
return aliases;
|
|
2182
|
+
}
|
|
2183
|
+
|
|
2169
2184
|
// ../jsx/src/ir-to-client-js/csr-substitute.ts
|
|
2185
|
+
import ts5 from "typescript";
|
|
2186
|
+
|
|
2187
|
+
// ../jsx/src/props-binding.ts
|
|
2170
2188
|
import ts4 from "typescript";
|
|
2189
|
+
function isIdentifierName(key) {
|
|
2190
|
+
if (key.length === 0)
|
|
2191
|
+
return false;
|
|
2192
|
+
for (let i = 0;i < key.length; ) {
|
|
2193
|
+
const cp = key.codePointAt(i);
|
|
2194
|
+
const ok = i === 0 ? ts4.isIdentifierStart(cp, ts4.ScriptTarget.Latest) : ts4.isIdentifierPart(cp, ts4.ScriptTarget.Latest);
|
|
2195
|
+
if (!ok)
|
|
2196
|
+
return false;
|
|
2197
|
+
i += cp > 65535 ? 2 : 1;
|
|
2198
|
+
}
|
|
2199
|
+
return true;
|
|
2200
|
+
}
|
|
2201
|
+
function propsDestructureBinding(p) {
|
|
2202
|
+
const callerKey = p.sourceName ?? p.name;
|
|
2203
|
+
const localName = p.name;
|
|
2204
|
+
const binding = callerKey === localName ? localName : `${isIdentifierName(callerKey) ? callerKey : JSON.stringify(callerKey)}: ${localName}`;
|
|
2205
|
+
return p.defaultValue ? `${binding} = ${p.defaultValue}` : binding;
|
|
2206
|
+
}
|
|
2207
|
+
var EMPTY_SET = new Set;
|
|
2208
|
+
|
|
2209
|
+
// ../jsx/src/ir-to-client-js/csr-substitute.ts
|
|
2171
2210
|
function extractFreeIdentifiersFromText(text) {
|
|
2172
2211
|
if (!text || text.trim().length === 0)
|
|
2173
2212
|
return new Set;
|
|
2174
|
-
const sf =
|
|
2213
|
+
const sf = ts5.createSourceFile("__free_ids__.ts", `(${text});`, ts5.ScriptTarget.Latest, true, ts5.ScriptKind.TS);
|
|
2175
2214
|
const stmt = sf.statements[0];
|
|
2176
|
-
if (!stmt || !
|
|
2215
|
+
if (!stmt || !ts5.isExpressionStatement(stmt))
|
|
2177
2216
|
return new Set;
|
|
2178
|
-
const expr =
|
|
2217
|
+
const expr = ts5.isParenthesizedExpression(stmt.expression) ? stmt.expression.expression : stmt.expression;
|
|
2179
2218
|
return extractFreeIdentifiersFromNode(expr);
|
|
2180
2219
|
}
|
|
2181
2220
|
|
|
2221
|
+
// ../jsx/src/ir-to-client-js/rewrite-props-object.ts
|
|
2222
|
+
import ts6 from "typescript";
|
|
2223
|
+
|
|
2182
2224
|
// ../jsx/src/scope/binding-scope.ts
|
|
2183
2225
|
class BindingScope {
|
|
2184
2226
|
frames;
|
|
@@ -2300,27 +2342,6 @@ var SKELETON_PATH_FORCE_CLOSE_GROUPS = [
|
|
|
2300
2342
|
new Set(["li"])
|
|
2301
2343
|
];
|
|
2302
2344
|
|
|
2303
|
-
// ../jsx/src/props-binding.ts
|
|
2304
|
-
import ts6 from "typescript";
|
|
2305
|
-
function isIdentifierName(key) {
|
|
2306
|
-
if (key.length === 0)
|
|
2307
|
-
return false;
|
|
2308
|
-
for (let i = 0;i < key.length; ) {
|
|
2309
|
-
const cp = key.codePointAt(i);
|
|
2310
|
-
const ok = i === 0 ? ts6.isIdentifierStart(cp, ts6.ScriptTarget.Latest) : ts6.isIdentifierPart(cp, ts6.ScriptTarget.Latest);
|
|
2311
|
-
if (!ok)
|
|
2312
|
-
return false;
|
|
2313
|
-
i += cp > 65535 ? 2 : 1;
|
|
2314
|
-
}
|
|
2315
|
-
return true;
|
|
2316
|
-
}
|
|
2317
|
-
function propsDestructureBinding(p) {
|
|
2318
|
-
const callerKey = p.sourceName ?? p.name;
|
|
2319
|
-
const localName = p.name;
|
|
2320
|
-
const binding = callerKey === localName ? localName : `${isIdentifierName(callerKey) ? callerKey : JSON.stringify(callerKey)}: ${localName}`;
|
|
2321
|
-
return p.defaultValue ? `${binding} = ${p.defaultValue}` : binding;
|
|
2322
|
-
}
|
|
2323
|
-
|
|
2324
2345
|
// ../jsx/src/instrumentation.ts
|
|
2325
2346
|
var _counters = freshCounters();
|
|
2326
2347
|
function freshCounters() {
|
|
@@ -2334,20 +2355,21 @@ function freshCounters() {
|
|
|
2334
2355
|
}
|
|
2335
2356
|
|
|
2336
2357
|
// ../jsx/src/analyzer-context.ts
|
|
2337
|
-
import
|
|
2358
|
+
import ts9 from "typescript";
|
|
2338
2359
|
|
|
2339
2360
|
// ../jsx/src/strip-types.ts
|
|
2340
|
-
import
|
|
2361
|
+
import ts8 from "typescript";
|
|
2341
2362
|
|
|
2342
2363
|
// ../jsx/src/analyzer-context.ts
|
|
2343
|
-
var _typePrinter =
|
|
2344
|
-
var _blankTypeSourceFile =
|
|
2364
|
+
var _typePrinter = ts9.createPrinter({ removeComments: true, omitTrailingSemicolon: true });
|
|
2365
|
+
var _blankTypeSourceFile = ts9.createSourceFile("__bf_types__.ts", "", ts9.ScriptTarget.Latest);
|
|
2345
2366
|
|
|
2346
2367
|
// ../jsx/src/errors.ts
|
|
2347
2368
|
var ErrorCodes = {
|
|
2348
2369
|
MISSING_USE_CLIENT: "BF001",
|
|
2349
2370
|
CLIENT_IMPORTING_SERVER: "BF003",
|
|
2350
2371
|
SIGNAL_OUTSIDE_COMPONENT: "BF011",
|
|
2372
|
+
PRIMITIVE_VIA_NAMESPACE_IMPORT: "BF013",
|
|
2351
2373
|
UNSUPPORTED_JSX_PATTERN: "BF021",
|
|
2352
2374
|
MISSING_KEY_IN_LIST: "BF023",
|
|
2353
2375
|
MISSING_KEY_IN_NESTED_LIST: "BF024",
|
|
@@ -2380,6 +2402,7 @@ var errorMessages = {
|
|
|
2380
2402
|
[ErrorCodes.MISSING_USE_CLIENT]: "'use client' directive required for components with createSignal or event handlers",
|
|
2381
2403
|
[ErrorCodes.CLIENT_IMPORTING_SERVER]: "Client component cannot import server component",
|
|
2382
2404
|
[ErrorCodes.SIGNAL_OUTSIDE_COMPONENT]: "Module-level reactive declaration (createSignal / createMemo) is not allowed. " + "The downstream codegen drops the declaration silently and every reference becomes a ReferenceError at SSR and at hydrate. " + "Move the declaration inside a component function so each mount gets its own state.",
|
|
2405
|
+
[ErrorCodes.PRIMITIVE_VIA_NAMESPACE_IMPORT]: "Reactive primitive called through a namespace import of '@barefootjs/client' (import * as ns) is not recognized; " + "the declaration is dropped and its references throw ReferenceError at hydrate. Import the primitive by name instead.",
|
|
2383
2406
|
[ErrorCodes.UNSUPPORTED_JSX_PATTERN]: "Unsupported JSX pattern",
|
|
2384
2407
|
[ErrorCodes.MISSING_KEY_IN_LIST]: "Missing key attribute in list rendering. Add a key prop for efficient updates",
|
|
2385
2408
|
[ErrorCodes.MISSING_KEY_IN_NESTED_LIST]: "Nested .map() loop requires key attribute for event delegation. Add a key prop to elements in the inner loop",
|
|
@@ -2571,46 +2594,46 @@ function extractFreeIdentifiersFromNode(node) {
|
|
|
2571
2594
|
const ids = new Set;
|
|
2572
2595
|
const boundNames = new Set;
|
|
2573
2596
|
function addBindingNames(name, out) {
|
|
2574
|
-
if (
|
|
2597
|
+
if (ts10.isIdentifier(name))
|
|
2575
2598
|
out.push(name.text);
|
|
2576
|
-
else if (
|
|
2599
|
+
else if (ts10.isObjectBindingPattern(name))
|
|
2577
2600
|
name.elements.forEach((e) => addBindingNames(e.name, out));
|
|
2578
|
-
else if (
|
|
2601
|
+
else if (ts10.isArrayBindingPattern(name))
|
|
2579
2602
|
name.elements.forEach((e) => {
|
|
2580
|
-
if (!
|
|
2603
|
+
if (!ts10.isOmittedExpression(e))
|
|
2581
2604
|
addBindingNames(e.name, out);
|
|
2582
2605
|
});
|
|
2583
2606
|
}
|
|
2584
2607
|
function visit(n) {
|
|
2585
|
-
if (
|
|
2608
|
+
if (ts10.isTypeNode(n))
|
|
2586
2609
|
return;
|
|
2587
|
-
if (
|
|
2610
|
+
if (ts10.isIdentifier(n)) {
|
|
2588
2611
|
const parent = n.parent;
|
|
2589
|
-
if (parent &&
|
|
2612
|
+
if (parent && ts10.isPropertyAccessExpression(parent) && parent.name === n)
|
|
2590
2613
|
return;
|
|
2591
|
-
if (parent &&
|
|
2614
|
+
if (parent && ts10.isPropertyAssignment(parent) && parent.name === n)
|
|
2592
2615
|
return;
|
|
2593
|
-
if (parent &&
|
|
2616
|
+
if (parent && ts10.isParameter(parent) && parent.name === n)
|
|
2594
2617
|
return;
|
|
2595
|
-
if (parent &&
|
|
2618
|
+
if (parent && ts10.isVariableDeclaration(parent) && parent.name === n)
|
|
2596
2619
|
return;
|
|
2597
2620
|
if (boundNames.has(n.text))
|
|
2598
2621
|
return;
|
|
2599
2622
|
ids.add(n.text);
|
|
2600
2623
|
return;
|
|
2601
2624
|
}
|
|
2602
|
-
if (
|
|
2625
|
+
if (ts10.isArrowFunction(n)) {
|
|
2603
2626
|
const params = [];
|
|
2604
2627
|
for (const p of n.parameters)
|
|
2605
2628
|
addBindingNames(p.name, params);
|
|
2606
2629
|
for (const name of params)
|
|
2607
2630
|
boundNames.add(name);
|
|
2608
|
-
|
|
2631
|
+
ts10.forEachChild(n, visit);
|
|
2609
2632
|
for (const name of params)
|
|
2610
2633
|
boundNames.delete(name);
|
|
2611
2634
|
return;
|
|
2612
2635
|
}
|
|
2613
|
-
|
|
2636
|
+
ts10.forEachChild(n, visit);
|
|
2614
2637
|
}
|
|
2615
2638
|
visit(node);
|
|
2616
2639
|
return ids;
|
|
@@ -2633,7 +2656,7 @@ var REACTIVE_PRIMITIVES = new Set([
|
|
|
2633
2656
|
]);
|
|
2634
2657
|
|
|
2635
2658
|
// ../jsx/src/jsx-to-ir.ts
|
|
2636
|
-
import
|
|
2659
|
+
import ts14 from "typescript";
|
|
2637
2660
|
|
|
2638
2661
|
// ../jsx/src/types.ts
|
|
2639
2662
|
var SCOPE_FORBIDDEN = {
|
|
@@ -2683,7 +2706,7 @@ function preambleAnalysisTemplateText(p) {
|
|
|
2683
2706
|
}
|
|
2684
2707
|
|
|
2685
2708
|
// ../jsx/src/module-exports.ts
|
|
2686
|
-
import
|
|
2709
|
+
import ts11 from "typescript";
|
|
2687
2710
|
function formatParamWithType(p) {
|
|
2688
2711
|
const rest = p.isRest ? "..." : "";
|
|
2689
2712
|
const optional = p.optional ? "?" : "";
|
|
@@ -2718,21 +2741,21 @@ function findAssignedNames(bodyText, candidates) {
|
|
|
2718
2741
|
const assigned = new Set;
|
|
2719
2742
|
if (candidates.size === 0)
|
|
2720
2743
|
return assigned;
|
|
2721
|
-
const sf =
|
|
2744
|
+
const sf = ts11.createSourceFile("bf-assignment-scan.tsx", bodyText, ts11.ScriptTarget.Latest, false, ts11.ScriptKind.TSX);
|
|
2722
2745
|
const record = (target) => {
|
|
2723
|
-
if (
|
|
2746
|
+
if (ts11.isIdentifier(target) && candidates.has(target.text)) {
|
|
2724
2747
|
assigned.add(target.text);
|
|
2725
2748
|
}
|
|
2726
2749
|
};
|
|
2727
2750
|
const visit = (node) => {
|
|
2728
|
-
if (
|
|
2751
|
+
if (ts11.isBinaryExpression(node) && isAssignmentOperator(node.operatorToken.kind)) {
|
|
2729
2752
|
record(node.left);
|
|
2730
|
-
} else if ((
|
|
2753
|
+
} else if ((ts11.isPrefixUnaryExpression(node) || ts11.isPostfixUnaryExpression(node)) && (node.operator === ts11.SyntaxKind.PlusPlusToken || node.operator === ts11.SyntaxKind.MinusMinusToken)) {
|
|
2731
2754
|
record(node.operand);
|
|
2732
2755
|
}
|
|
2733
|
-
|
|
2756
|
+
ts11.forEachChild(node, visit);
|
|
2734
2757
|
};
|
|
2735
|
-
|
|
2758
|
+
ts11.forEachChild(sf, visit);
|
|
2736
2759
|
return assigned;
|
|
2737
2760
|
}
|
|
2738
2761
|
function closeOverWritersOfMutableBindings(primaryRefs, declarations, mutableNames) {
|
|
@@ -2755,14 +2778,14 @@ function closeOverWritersOfMutableBindings(primaryRefs, declarations, mutableNam
|
|
|
2755
2778
|
return reachable;
|
|
2756
2779
|
}
|
|
2757
2780
|
function isAssignmentOperator(kind) {
|
|
2758
|
-
return kind >=
|
|
2781
|
+
return kind >= ts11.SyntaxKind.FirstAssignment && kind <= ts11.SyntaxKind.LastAssignment;
|
|
2759
2782
|
}
|
|
2760
2783
|
|
|
2761
2784
|
// ../jsx/src/reactivity-checker.ts
|
|
2762
|
-
import
|
|
2785
|
+
import ts12 from "typescript";
|
|
2763
2786
|
|
|
2764
2787
|
// ../jsx/src/free-refs.ts
|
|
2765
|
-
import
|
|
2788
|
+
import ts13 from "typescript";
|
|
2766
2789
|
var _bindingMapCache = new WeakMap;
|
|
2767
2790
|
|
|
2768
2791
|
// ../jsx/src/to-locale-date-lowering.ts
|
|
@@ -3210,16 +3233,16 @@ var KEYWORDS_AND_GLOBALS = new Set([
|
|
|
3210
3233
|
]);
|
|
3211
3234
|
|
|
3212
3235
|
// ../jsx/src/ir-to-client-js/walk-prop-accesses.ts
|
|
3213
|
-
import
|
|
3236
|
+
import ts15 from "typescript";
|
|
3214
3237
|
|
|
3215
3238
|
// ../jsx/src/ir-to-client-js/imports.ts
|
|
3216
|
-
import
|
|
3239
|
+
import ts17 from "typescript";
|
|
3217
3240
|
|
|
3218
3241
|
// ../jsx/src/value-references.ts
|
|
3219
|
-
import
|
|
3242
|
+
import ts16 from "typescript";
|
|
3220
3243
|
|
|
3221
3244
|
// ../jsx/src/relocate.ts
|
|
3222
|
-
import
|
|
3245
|
+
import ts18 from "typescript";
|
|
3223
3246
|
|
|
3224
3247
|
// ../jsx/src/lowering-registry.ts
|
|
3225
3248
|
var plugins = [];
|
|
@@ -3415,10 +3438,10 @@ function formatDateLocalNames(metadata) {
|
|
|
3415
3438
|
}
|
|
3416
3439
|
|
|
3417
3440
|
// ../jsx/src/ir-to-client-js/prune-unused-prop-extractions.ts
|
|
3418
|
-
import
|
|
3441
|
+
import ts19 from "typescript";
|
|
3419
3442
|
|
|
3420
3443
|
// ../jsx/src/ir-to-client-js/control-flow/plan/lazy-preamble.ts
|
|
3421
|
-
import
|
|
3444
|
+
import ts20 from "typescript";
|
|
3422
3445
|
var NO_PREAMBLE = {
|
|
3423
3446
|
lazySafe: true,
|
|
3424
3447
|
facts: { declaredNames: new Set, freeNames: new Set }
|
|
@@ -3468,7 +3491,7 @@ var INERT_BINDING_GLOBALS = new Set([
|
|
|
3468
3491
|
]);
|
|
3469
3492
|
|
|
3470
3493
|
// ../jsx/src/ir-to-client-js/emit-reactive.ts
|
|
3471
|
-
import
|
|
3494
|
+
import ts21 from "typescript";
|
|
3472
3495
|
|
|
3473
3496
|
// ../jsx/src/ir-to-client-js/control-flow/stringify/event-delegation.ts
|
|
3474
3497
|
var NON_BUBBLING_EVENTS = new Set([
|
|
@@ -3482,9 +3505,6 @@ var NON_BUBBLING_EVENTS = new Set([
|
|
|
3482
3505
|
"pointerleave"
|
|
3483
3506
|
]);
|
|
3484
3507
|
|
|
3485
|
-
// ../jsx/src/ir-to-client-js/rewrite-props-object.ts
|
|
3486
|
-
import ts21 from "typescript";
|
|
3487
|
-
|
|
3488
3508
|
// ../jsx/src/ir-to-client-js/source-map.ts
|
|
3489
3509
|
var BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
3490
3510
|
function encodeVLQ(value) {
|
|
@@ -5508,6 +5528,7 @@ class CompileState {
|
|
|
5508
5528
|
componentName = "";
|
|
5509
5529
|
errors = [];
|
|
5510
5530
|
referencedDerivedConsts = new Set;
|
|
5531
|
+
templateReadRootFields = new Set;
|
|
5511
5532
|
templateVarCounter = 0;
|
|
5512
5533
|
pendingChildrenDefines = [];
|
|
5513
5534
|
propsObjectName = null;
|
|
@@ -6357,6 +6378,15 @@ function convertInitialValue(ctx, value, _typeInfo, propsParams, preParsed) {
|
|
|
6357
6378
|
if (param2) {
|
|
6358
6379
|
return propRef(param2);
|
|
6359
6380
|
}
|
|
6381
|
+
const inlinedStr = ctx.resolveModuleStringConst(value);
|
|
6382
|
+
if (inlinedStr !== null)
|
|
6383
|
+
return inlinedStr;
|
|
6384
|
+
const inlinedNum = ctx.resolveModuleNumericConst(value);
|
|
6385
|
+
if (inlinedNum !== null)
|
|
6386
|
+
return inlinedNum;
|
|
6387
|
+
const inlinedBool = ctx.resolveModuleBooleanConst(value);
|
|
6388
|
+
if (inlinedBool !== null)
|
|
6389
|
+
return inlinedBool;
|
|
6360
6390
|
}
|
|
6361
6391
|
const propName = ctx.extractPropNameFromInitialValue(value, preParsed);
|
|
6362
6392
|
const param = propName ? propsParams?.find((p) => p.name === propName) : undefined;
|
|
@@ -8064,7 +8094,9 @@ class GoTemplateAdapter extends BaseAdapter {
|
|
|
8064
8094
|
extractPropNameFromInitialValue: (initialValue, preParsed) => this.extractPropNameFromInitialValue(initialValue, preParsed),
|
|
8065
8095
|
extractPropFallback: (initialValue, preParsed) => this.extractPropFallback(initialValue, preParsed),
|
|
8066
8096
|
extractCollisionDerivation: (parsed) => this.extractCollisionDerivation(parsed),
|
|
8067
|
-
resolveModuleStringConst: (name) => this.resolveModuleStringConst(name)
|
|
8097
|
+
resolveModuleStringConst: (name) => this.resolveModuleStringConst(name),
|
|
8098
|
+
resolveModuleNumericConst: (name) => this.resolveModuleNumericConst(name),
|
|
8099
|
+
resolveModuleBooleanConst: (name) => this.resolveModuleBooleanConst(name)
|
|
8068
8100
|
};
|
|
8069
8101
|
get errors() {
|
|
8070
8102
|
return this.state.errors;
|
|
@@ -8081,6 +8113,10 @@ class GoTemplateAdapter extends BaseAdapter {
|
|
|
8081
8113
|
staticLoopBakeFailed = false;
|
|
8082
8114
|
childComponentShapes = new Map;
|
|
8083
8115
|
childContextConsumers = new Map;
|
|
8116
|
+
importAliases = new Map;
|
|
8117
|
+
resolveChildName(name) {
|
|
8118
|
+
return this.importAliases.get(name) ?? name;
|
|
8119
|
+
}
|
|
8084
8120
|
constructor(options = {}) {
|
|
8085
8121
|
super();
|
|
8086
8122
|
this.options = {
|
|
@@ -8092,6 +8128,7 @@ class GoTemplateAdapter extends BaseAdapter {
|
|
|
8092
8128
|
primeCompileState(ir) {
|
|
8093
8129
|
this.state.propsObjectName = ir.metadata.propsObjectName;
|
|
8094
8130
|
this.state.restPropsName = ir.metadata.restPropsName ?? null;
|
|
8131
|
+
this.importAliases = buildImportAliasMap(ir.metadata.imports ?? []);
|
|
8095
8132
|
this.state.objectTypedPropNames = new Set((ir.metadata.propsParams ?? []).filter((p) => p.type.kind === "object").map((p) => p.name));
|
|
8096
8133
|
this.state.moduleStringConsts = this.collectModuleStringConsts(ir.metadata.localConstants);
|
|
8097
8134
|
this.state.localConstants = ir.metadata.localConstants ?? [];
|
|
@@ -8126,6 +8163,7 @@ class GoTemplateAdapter extends BaseAdapter {
|
|
|
8126
8163
|
this.state.componentName = ir.metadata.componentName;
|
|
8127
8164
|
this.state.errors = [];
|
|
8128
8165
|
this.state.referencedDerivedConsts = new Set;
|
|
8166
|
+
this.state.templateReadRootFields = new Set;
|
|
8129
8167
|
this.state.templateVarCounter = 0;
|
|
8130
8168
|
this.state.pendingChildrenDefines = [];
|
|
8131
8169
|
this.scope = BindingScope.EMPTY;
|
|
@@ -8154,7 +8192,7 @@ ${scriptRegistrations}${templateBody}
|
|
|
8154
8192
|
template += `{{define "${d.name}"}}${d.content}{{end}}
|
|
8155
8193
|
`;
|
|
8156
8194
|
}
|
|
8157
|
-
const types = this.generateTypes(ir);
|
|
8195
|
+
const types = this.generateTypes(ir, true);
|
|
8158
8196
|
if (this.state.errors.length > 0) {
|
|
8159
8197
|
ir.errors.push(...this.state.errors);
|
|
8160
8198
|
}
|
|
@@ -8383,9 +8421,12 @@ ${scriptRegistrations}${templateBody}
|
|
|
8383
8421
|
taken.add(desired);
|
|
8384
8422
|
return desired;
|
|
8385
8423
|
}
|
|
8386
|
-
generateTypes(ir) {
|
|
8424
|
+
generateTypes(ir, preserveTemplateReadRootFields = false) {
|
|
8387
8425
|
this.state.usesHtmlTemplate = false;
|
|
8388
8426
|
this.state.usesFmt = false;
|
|
8427
|
+
if (!preserveTemplateReadRootFields) {
|
|
8428
|
+
this.state.templateReadRootFields = new Set;
|
|
8429
|
+
}
|
|
8389
8430
|
this.primeCompileState(ir);
|
|
8390
8431
|
const lines = [];
|
|
8391
8432
|
const componentName = ir.metadata.componentName;
|
|
@@ -8529,10 +8570,17 @@ ${goFields.join(`
|
|
|
8529
8570
|
const node = signal.parsed;
|
|
8530
8571
|
if (!node || node.kind !== "array-literal" || node.elements.length === 0)
|
|
8531
8572
|
return null;
|
|
8573
|
+
const name = `${componentName}${capitalizeFieldName(signal.getter)}Item`;
|
|
8574
|
+
return this.synthesizeStructsFromElements(node.elements, name);
|
|
8575
|
+
}
|
|
8576
|
+
synthesizeStructsFromElements(elements, name) {
|
|
8577
|
+
if (this.state.localTypeNames.has(name))
|
|
8578
|
+
return null;
|
|
8532
8579
|
const order = [];
|
|
8533
|
-
const
|
|
8534
|
-
|
|
8535
|
-
|
|
8580
|
+
const shapes = new Map;
|
|
8581
|
+
const nestedElements = new Map;
|
|
8582
|
+
for (let i = 0;i < elements.length; i++) {
|
|
8583
|
+
const el = elements[i];
|
|
8536
8584
|
if (el.kind !== "object-literal")
|
|
8537
8585
|
return null;
|
|
8538
8586
|
const seen = new Set;
|
|
@@ -8544,37 +8592,93 @@ ${goFields.join(`
|
|
|
8544
8592
|
const key = prop.key;
|
|
8545
8593
|
if (!GO_IDENTIFIER.test(key))
|
|
8546
8594
|
return null;
|
|
8595
|
+
seen.add(key);
|
|
8596
|
+
const isNestedArray = prop.value.kind === "array-literal" && prop.value.elements.every((e) => e.kind === "object-literal");
|
|
8597
|
+
if (isNestedArray) {
|
|
8598
|
+
const prevShape2 = shapes.get(key);
|
|
8599
|
+
if (prevShape2 === undefined) {
|
|
8600
|
+
if (i !== 0)
|
|
8601
|
+
return null;
|
|
8602
|
+
order.push(key);
|
|
8603
|
+
shapes.set(key, { kind: "nested-array" });
|
|
8604
|
+
nestedElements.set(key, []);
|
|
8605
|
+
} else if (prevShape2.kind !== "nested-array") {
|
|
8606
|
+
return null;
|
|
8607
|
+
}
|
|
8608
|
+
nestedElements.get(key).push(...prop.value.elements);
|
|
8609
|
+
continue;
|
|
8610
|
+
}
|
|
8547
8611
|
const goType = this.scalarParsedGoType(prop.value);
|
|
8548
8612
|
if (!goType)
|
|
8549
8613
|
return null;
|
|
8550
|
-
|
|
8551
|
-
|
|
8552
|
-
if (prev === undefined) {
|
|
8614
|
+
const prevShape = shapes.get(key);
|
|
8615
|
+
if (prevShape === undefined) {
|
|
8553
8616
|
if (i !== 0)
|
|
8554
8617
|
return null;
|
|
8555
8618
|
order.push(key);
|
|
8556
|
-
|
|
8619
|
+
shapes.set(key, { kind: "scalar", goType });
|
|
8620
|
+
} else if (prevShape.kind !== "scalar") {
|
|
8621
|
+
return null;
|
|
8557
8622
|
} else {
|
|
8558
|
-
const merged = this.mergeScalarGoType(
|
|
8623
|
+
const merged = this.mergeScalarGoType(prevShape.goType, goType);
|
|
8559
8624
|
if (!merged)
|
|
8560
8625
|
return null;
|
|
8561
|
-
|
|
8626
|
+
shapes.set(key, { kind: "scalar", goType: merged });
|
|
8562
8627
|
}
|
|
8563
8628
|
}
|
|
8564
8629
|
if (seen.size !== order.length)
|
|
8565
8630
|
return null;
|
|
8566
8631
|
}
|
|
8567
|
-
const
|
|
8568
|
-
|
|
8569
|
-
|
|
8570
|
-
|
|
8632
|
+
const nestedStructs = [];
|
|
8633
|
+
const fields = [];
|
|
8634
|
+
const properties = [];
|
|
8635
|
+
for (const key of order) {
|
|
8636
|
+
const shape = shapes.get(key);
|
|
8637
|
+
if (shape.kind === "scalar") {
|
|
8638
|
+
fields.push({ tsName: key, goName: capitalizeFieldName(key), goType: shape.goType });
|
|
8639
|
+
properties.push({ name: key, type: this.scalarGoTypeToTypeInfo(shape.goType), optional: false, readonly: false });
|
|
8640
|
+
continue;
|
|
8641
|
+
}
|
|
8642
|
+
const nestedList = nestedElements.get(key);
|
|
8643
|
+
if (nestedList.length === 0)
|
|
8644
|
+
return null;
|
|
8645
|
+
const nestedName = `${name}${capitalizeFieldName(key)}Item`;
|
|
8646
|
+
const nested = this.synthesizeStructsFromElements(nestedList, nestedName);
|
|
8647
|
+
if (!nested)
|
|
8648
|
+
return null;
|
|
8649
|
+
nestedStructs.push(...nested);
|
|
8650
|
+
fields.push({ tsName: key, goName: capitalizeFieldName(key), goType: `[]${nestedName}` });
|
|
8651
|
+
properties.push({ name: key, type: this.synthSliceTypeInfo(nestedName), optional: false, readonly: false });
|
|
8652
|
+
}
|
|
8653
|
+
return [...nestedStructs, { name, fields, properties }];
|
|
8654
|
+
}
|
|
8655
|
+
scalarGoTypeToTypeInfo(goType) {
|
|
8656
|
+
if (goType === "string")
|
|
8657
|
+
return { kind: "primitive", raw: "string", primitive: "string" };
|
|
8658
|
+
if (goType === "bool")
|
|
8659
|
+
return { kind: "primitive", raw: "boolean", primitive: "boolean" };
|
|
8660
|
+
return { kind: "primitive", raw: "number", primitive: "number" };
|
|
8661
|
+
}
|
|
8662
|
+
synthSliceTypeInfo(name) {
|
|
8663
|
+
return { kind: "array", raw: `${name}[]`, elementType: { kind: "interface", raw: name } };
|
|
8664
|
+
}
|
|
8665
|
+
registerSynthStruct(lines, name, fields, properties, comment) {
|
|
8666
|
+
this.state.localTypeNames.add(name);
|
|
8667
|
+
this.state.localStructFields.set(name, new Map(fields.map((f) => [f.tsName, f.goName])));
|
|
8668
|
+
this.state.currentTypeDefinitions.push({
|
|
8669
|
+
kind: "type",
|
|
8571
8670
|
name,
|
|
8572
|
-
|
|
8573
|
-
|
|
8574
|
-
|
|
8575
|
-
|
|
8576
|
-
|
|
8577
|
-
|
|
8671
|
+
definition: "",
|
|
8672
|
+
properties,
|
|
8673
|
+
loc: SYNTH_TYPE_LOC
|
|
8674
|
+
});
|
|
8675
|
+
const goFields = fields.map((f) => ` ${f.goName} ${f.goType} \`json:"${this.toJsonTag(f.tsName)}"\``);
|
|
8676
|
+
lines.push(comment);
|
|
8677
|
+
lines.push(`type ${name} struct {
|
|
8678
|
+
${goFields.join(`
|
|
8679
|
+
`)}
|
|
8680
|
+
}`);
|
|
8681
|
+
lines.push("");
|
|
8578
8682
|
}
|
|
8579
8683
|
scalarParsedGoType(value) {
|
|
8580
8684
|
if (value.kind === "unary" && value.op === "-" && value.argument.kind === "literal") {
|
|
@@ -8641,7 +8745,7 @@ ${goFields.join(`
|
|
|
8641
8745
|
for (const nested of inputNested) {
|
|
8642
8746
|
if (nested.loopMarkerId && this.getBakedStaticChildLoop(nested.loopMarkerId, nested, nested.loopArrayParsed, nested.loopParam, nested.loopKey))
|
|
8643
8747
|
continue;
|
|
8644
|
-
lines.push(` ${nested.name}s []${nested.name}Input`);
|
|
8748
|
+
lines.push(` ${nested.name}s []${this.resolveChildName(nested.name)}Input`);
|
|
8645
8749
|
}
|
|
8646
8750
|
const takenInput = new Set(this.propParamFieldNamesUnion(ir.metadata.propsParams));
|
|
8647
8751
|
for (const c of this.nonCollidingContextConsumers(takenInput)) {
|
|
@@ -8677,10 +8781,11 @@ ${goFields.join(`
|
|
|
8677
8781
|
const wrapperName = this.loopBodyWrapperName(parentComponentName, nested);
|
|
8678
8782
|
const datumFields = this.resolveLoopDatumFields(nested.loopItemType);
|
|
8679
8783
|
const bodyChildInstances = this.collectBodyChildInstances(nested.bodyChildren);
|
|
8680
|
-
|
|
8784
|
+
const declaredName = this.resolveChildName(nested.name);
|
|
8785
|
+
lines.push(`// ${wrapperName} wraps ${declaredName}Props with per-row loop datum`);
|
|
8681
8786
|
lines.push(`// fields and child component slots for the loop body children. (#1897)`);
|
|
8682
8787
|
lines.push(`type ${wrapperName} struct {`);
|
|
8683
|
-
lines.push(` ${
|
|
8788
|
+
lines.push(` ${declaredName}Props`);
|
|
8684
8789
|
for (const f of datumFields) {
|
|
8685
8790
|
lines.push(` ${f.goName} ${f.goType} \`json:"-"\``);
|
|
8686
8791
|
}
|
|
@@ -8689,7 +8794,7 @@ ${goFields.join(`
|
|
|
8689
8794
|
lines.push(` BfLoopItem ${scalarLoopType} \`json:"-"\``);
|
|
8690
8795
|
}
|
|
8691
8796
|
for (const child of bodyChildInstances) {
|
|
8692
|
-
lines.push(` ${child.fieldName} ${child.name}Props \`json:"-"\``);
|
|
8797
|
+
lines.push(` ${child.fieldName} ${this.resolveChildName(child.name)}Props \`json:"-"\``);
|
|
8693
8798
|
}
|
|
8694
8799
|
lines.push("}");
|
|
8695
8800
|
lines.push("");
|
|
@@ -8773,12 +8878,13 @@ ${goFields.join(`
|
|
|
8773
8878
|
const staticWithoutBody = staticNested.filter((n) => !n.bodyChildren || n.bodyChildren.length === 0);
|
|
8774
8879
|
for (const nested of staticWithoutBody) {
|
|
8775
8880
|
const varName = `${nested.name.charAt(0).toLowerCase()}${nested.name.slice(1)}s`;
|
|
8881
|
+
const declaredName = this.resolveChildName(nested.name);
|
|
8776
8882
|
const baked = nested.loopMarkerId ? this.getBakedStaticChildLoop(nested.loopMarkerId, nested, nested.loopArrayParsed, nested.loopParam, nested.loopKey) : null;
|
|
8777
8883
|
if (baked) {
|
|
8778
|
-
lines.push(` ${varName} := make([]${
|
|
8884
|
+
lines.push(` ${varName} := make([]${declaredName}Props, ${baked.items.length})`);
|
|
8779
8885
|
baked.items.forEach((item, i) => {
|
|
8780
8886
|
const fields = item.inputFields.map((f) => `${f.goField}: ${f.goValue}`).join(", ");
|
|
8781
|
-
lines.push(` ${varName}[${i}] = New${
|
|
8887
|
+
lines.push(` ${varName}[${i}] = New${declaredName}Props(${declaredName}Input{${fields}})`);
|
|
8782
8888
|
lines.push(` ${varName}[${i}].BfParent = scopeID`);
|
|
8783
8889
|
lines.push(` ${varName}[${i}].BfMount = "${nested.slotId}"`);
|
|
8784
8890
|
if (item.dataKey !== null) {
|
|
@@ -8788,9 +8894,9 @@ ${goFields.join(`
|
|
|
8788
8894
|
lines.push("");
|
|
8789
8895
|
continue;
|
|
8790
8896
|
}
|
|
8791
|
-
lines.push(` ${varName} := make([]${
|
|
8897
|
+
lines.push(` ${varName} := make([]${declaredName}Props, len(in.${nested.name}s))`);
|
|
8792
8898
|
lines.push(` for i, item := range in.${nested.name}s {`);
|
|
8793
|
-
lines.push(` ${varName}[i] = New${
|
|
8899
|
+
lines.push(` ${varName}[i] = New${declaredName}Props(item)`);
|
|
8794
8900
|
lines.push(` ${varName}[i].BfParent = scopeID`);
|
|
8795
8901
|
lines.push(` ${varName}[i].BfMount = "${nested.slotId}"`);
|
|
8796
8902
|
const keyField = loopKeyToGoFieldPath(nested.loopKey, nested.loopParam);
|
|
@@ -8905,8 +9011,14 @@ ${goFields.join(`
|
|
|
8905
9011
|
lines.push(` ${fieldName}: ${hoisted.varName},`);
|
|
8906
9012
|
} else {
|
|
8907
9013
|
const bakeType = this.state.synthStructTypes.get(signal.getter) ?? signal.type;
|
|
9014
|
+
const resolvedParsed = this.resolvedSignalParsed(signal);
|
|
8908
9015
|
const initialValue = convertInitialValue(this.emitCtx, signal.initialValue, bakeType, ir.metadata.propsParams, signal.parsed);
|
|
8909
9016
|
lines.push(` ${fieldName}: ${initialValue},`);
|
|
9017
|
+
if (resolvedParsed?.kind === "object-literal" && jsLiteralToGo(this.emitCtx, bakeType, resolvedParsed) === null) {
|
|
9018
|
+
const step = this.state.ssrSeedPlan.steps.find((s) => s.kind === "derived" && s.origin === "signal" && s.name === signal.getter);
|
|
9019
|
+
if (step?.kind === "derived")
|
|
9020
|
+
this.refuseUnbakeableDerivedObjectLiteral(signal.getter, signal.loc, step.frees);
|
|
9021
|
+
}
|
|
8910
9022
|
}
|
|
8911
9023
|
}
|
|
8912
9024
|
for (const nested of staticWithoutBody) {
|
|
@@ -9006,19 +9118,20 @@ ${goFields.join(`
|
|
|
9006
9118
|
emitStaticChildInstances(lines, ir) {
|
|
9007
9119
|
const staticChildren = this.collectStaticChildInstances(ir.root, ir.metadata.propsParams);
|
|
9008
9120
|
for (const child of staticChildren) {
|
|
9009
|
-
|
|
9121
|
+
const declaredName = this.resolveChildName(child.name);
|
|
9122
|
+
lines.push(` ${child.fieldName}: New${declaredName}Props(${declaredName}Input{`);
|
|
9010
9123
|
lines.push(` ScopeID: scopeID + "_${child.slotId}",`);
|
|
9011
9124
|
lines.push(` BfParent: scopeID,`);
|
|
9012
9125
|
lines.push(` BfMount: "${child.slotId}",`);
|
|
9013
9126
|
if (child.contextBindings) {
|
|
9014
|
-
for (const consumer of this.childContextConsumers.get(
|
|
9127
|
+
for (const consumer of this.childContextConsumers.get(declaredName) ?? []) {
|
|
9015
9128
|
const goVal = child.contextBindings.get(consumer.contextName);
|
|
9016
9129
|
if (goVal !== undefined) {
|
|
9017
9130
|
lines.push(` ${this.contextFieldName(consumer)}: ${goVal},`);
|
|
9018
9131
|
}
|
|
9019
9132
|
}
|
|
9020
9133
|
}
|
|
9021
|
-
const childShape = this.childComponentShapes.get(
|
|
9134
|
+
const childShape = this.childComponentShapes.get(declaredName);
|
|
9022
9135
|
const restBagEntries = [];
|
|
9023
9136
|
const emitChildField = (jsxName, goValue) => {
|
|
9024
9137
|
if (childShape && childShape.restBagField && !childShape.paramNames.has(jsxName)) {
|
|
@@ -9115,6 +9228,7 @@ ${goFields.join(`
|
|
|
9115
9228
|
lines.push(`// New${componentName}Props creates ${propsTypeName} from ${inputTypeName}.`);
|
|
9116
9229
|
for (const nested of signalDynamicNested) {
|
|
9117
9230
|
const arrayField = `${nested.name}s`;
|
|
9231
|
+
const declaredName = this.resolveChildName(nested.name);
|
|
9118
9232
|
lines.push(`//`);
|
|
9119
9233
|
lines.push(`// NOTE: \`${arrayField}\` is populated by the route handler, not by`);
|
|
9120
9234
|
lines.push(`// New${componentName}Props — the SSR template iterates over it`);
|
|
@@ -9122,9 +9236,9 @@ ${goFields.join(`
|
|
|
9122
9236
|
lines.push(`// assign it before passing the props to your renderer. Example:`);
|
|
9123
9237
|
lines.push(`//`);
|
|
9124
9238
|
lines.push(`// props := New${componentName}Props(${inputTypeName}{ /* ... */ })`);
|
|
9125
|
-
lines.push(`// props.${arrayField} = make([]${
|
|
9239
|
+
lines.push(`// props.${arrayField} = make([]${declaredName}Props, len(items))`);
|
|
9126
9240
|
lines.push(`// for i, item := range items {`);
|
|
9127
|
-
lines.push(`// props.${arrayField}[i] = New${
|
|
9241
|
+
lines.push(`// props.${arrayField}[i] = New${declaredName}Props(${declaredName}Input{ /* fields */ })`);
|
|
9128
9242
|
lines.push(`// props.${arrayField}[i].BfParent = props.ScopeID`);
|
|
9129
9243
|
lines.push(`// props.${arrayField}[i].BfMount = "${nested.slotId}"`);
|
|
9130
9244
|
lines.push(`// }`);
|
|
@@ -9163,9 +9277,11 @@ ${goFields.join(`
|
|
|
9163
9277
|
const wrapperType = this.loopBodyWrapperName(componentName, nested);
|
|
9164
9278
|
const datumFields = this.resolveLoopDatumFields(nested.loopItemType);
|
|
9165
9279
|
const bodyChildInstances = this.collectBodyChildInstances(nested.bodyChildren, ir.metadata.propsParams);
|
|
9280
|
+
const declaredName = this.resolveChildName(nested.name);
|
|
9166
9281
|
for (const child of bodyChildInstances) {
|
|
9167
9282
|
const childVar = `child_${child.fieldName}`;
|
|
9168
|
-
|
|
9283
|
+
const childDeclaredName = this.resolveChildName(child.name);
|
|
9284
|
+
lines.push(` ${childVar} := New${childDeclaredName}Props(${childDeclaredName}Input{`);
|
|
9169
9285
|
lines.push(` ScopeID: scopeID + "_${child.slotId}",`);
|
|
9170
9286
|
lines.push(` BfParent: scopeID,`);
|
|
9171
9287
|
lines.push(` BfMount: "${child.slotId}",`);
|
|
@@ -9185,7 +9301,7 @@ ${goFields.join(`
|
|
|
9185
9301
|
lines.push(` ${varName} := make([]${wrapperType}, len(${dataVar}))`);
|
|
9186
9302
|
lines.push(` for i, item := range ${dataVar} {`);
|
|
9187
9303
|
lines.push(` ${varName}[i] = ${wrapperType}{`);
|
|
9188
|
-
lines.push(` ${
|
|
9304
|
+
lines.push(` ${declaredName}Props: New${declaredName}Props(${declaredName}Input{`);
|
|
9189
9305
|
lines.push(` BfParent: scopeID,`);
|
|
9190
9306
|
lines.push(` BfMount: "${nested.slotId}",`);
|
|
9191
9307
|
for (const prop of nested.props ?? []) {
|
|
@@ -9240,9 +9356,11 @@ ${goFields.join(`
|
|
|
9240
9356
|
const varName = `${nested.name.charAt(0).toLowerCase()}${nested.name.slice(1)}s`;
|
|
9241
9357
|
const datumFields = this.resolveLoopDatumFields(nested.loopItemType);
|
|
9242
9358
|
const bodyChildInstances = this.collectBodyChildInstances(nested.bodyChildren, ir.metadata.propsParams);
|
|
9359
|
+
const declaredName = this.resolveChildName(nested.name);
|
|
9243
9360
|
for (const child of bodyChildInstances) {
|
|
9244
9361
|
const childVar = `child_${child.fieldName}`;
|
|
9245
|
-
|
|
9362
|
+
const childDeclaredName = this.resolveChildName(child.name);
|
|
9363
|
+
lines.push(` ${childVar} := New${childDeclaredName}Props(${childDeclaredName}Input{`);
|
|
9246
9364
|
lines.push(` ScopeID: scopeID + "_${child.slotId}",`);
|
|
9247
9365
|
lines.push(` BfParent: scopeID,`);
|
|
9248
9366
|
lines.push(` BfMount: "${child.slotId}",`);
|
|
@@ -9261,7 +9379,7 @@ ${goFields.join(`
|
|
|
9261
9379
|
lines.push(` ${varName} := make([]${wrapperType}, len(bakedData))`);
|
|
9262
9380
|
lines.push(` for i, item := range bakedData {`);
|
|
9263
9381
|
lines.push(` ${varName}[i] = ${wrapperType}{`);
|
|
9264
|
-
lines.push(` ${
|
|
9382
|
+
lines.push(` ${declaredName}Props: New${declaredName}Props(${declaredName}Input{`);
|
|
9265
9383
|
lines.push(` BfParent: scopeID,`);
|
|
9266
9384
|
lines.push(` BfMount: "${nested.slotId}",`);
|
|
9267
9385
|
lines.push(` }),`);
|
|
@@ -9316,21 +9434,7 @@ ${goFields.join(`
|
|
|
9316
9434
|
visit(prop.type, desiredName, prop.name);
|
|
9317
9435
|
}
|
|
9318
9436
|
const fields = this.structFieldsFor(typeInfo);
|
|
9319
|
-
this.
|
|
9320
|
-
this.state.currentTypeDefinitions.push({
|
|
9321
|
-
kind: "type",
|
|
9322
|
-
name: desiredName,
|
|
9323
|
-
definition: "",
|
|
9324
|
-
properties: typeInfo.properties ?? [],
|
|
9325
|
-
loc: SYNTH_TYPE_LOC
|
|
9326
|
-
});
|
|
9327
|
-
const goFields = fields.map((f) => ` ${f.goName} ${f.goType} \`json:"${this.toJsonTag(f.tsName)}"\``);
|
|
9328
|
-
lines.push(`// ${desiredName} is a synthesised type for an anonymous object type (#2674).`);
|
|
9329
|
-
lines.push(`type ${desiredName} struct {
|
|
9330
|
-
${goFields.join(`
|
|
9331
|
-
`)}
|
|
9332
|
-
}`);
|
|
9333
|
-
lines.push("");
|
|
9437
|
+
this.registerSynthStruct(lines, desiredName, fields, typeInfo.properties ?? [], `// ${desiredName} is a synthesised type for an anonymous object type (#2674).`);
|
|
9334
9438
|
};
|
|
9335
9439
|
const visitArrayElem = (elemType, parentName, propName) => {
|
|
9336
9440
|
if (!elemType)
|
|
@@ -9382,20 +9486,11 @@ ${goFields.join(`
|
|
|
9382
9486
|
const synth = this.synthesizeStructFromSignal(signal, componentName);
|
|
9383
9487
|
if (!synth)
|
|
9384
9488
|
continue;
|
|
9385
|
-
|
|
9386
|
-
|
|
9387
|
-
|
|
9388
|
-
|
|
9389
|
-
|
|
9390
|
-
elementType: { kind: "interface", raw: synth.name }
|
|
9391
|
-
});
|
|
9392
|
-
const goFields = synth.fields.map((f) => ` ${f.goName} ${f.goType} \`json:"${this.toJsonTag(f.tsName)}"\``);
|
|
9393
|
-
lines.push(`// ${synth.name} is a synthesised element type for the ${signal.getter} signal.`);
|
|
9394
|
-
lines.push(`type ${synth.name} struct {
|
|
9395
|
-
${goFields.join(`
|
|
9396
|
-
`)}
|
|
9397
|
-
}`);
|
|
9398
|
-
lines.push("");
|
|
9489
|
+
for (const s of synth) {
|
|
9490
|
+
this.registerSynthStruct(lines, s.name, s.fields, s.properties, `// ${s.name} is a synthesised element type for the ${signal.getter} signal.`);
|
|
9491
|
+
}
|
|
9492
|
+
const top = synth[synth.length - 1];
|
|
9493
|
+
this.state.synthStructTypes.set(signal.getter, this.synthSliceTypeInfo(top.name));
|
|
9399
9494
|
}
|
|
9400
9495
|
}
|
|
9401
9496
|
resolveNestedLoopItemTypes(ir, nestedComponents) {
|
|
@@ -9538,7 +9633,7 @@ ${goFields.join(`
|
|
|
9538
9633
|
for (const nested of nestedComponents) {
|
|
9539
9634
|
if (this.isOrphanedClientOnlyNested(nested))
|
|
9540
9635
|
continue;
|
|
9541
|
-
const elemType = nested.bodyChildren?.length ? this.loopBodyWrapperName(componentName, nested) : `${nested.name}Props`;
|
|
9636
|
+
const elemType = nested.bodyChildren?.length ? this.loopBodyWrapperName(componentName, nested) : `${this.resolveChildName(nested.name)}Props`;
|
|
9542
9637
|
if (nested.isDynamic && !nested.isPropDerived) {
|
|
9543
9638
|
lines.push(` ${nested.name}s []${elemType} \`json:"-"\``);
|
|
9544
9639
|
} else if (nested.isDynamic && nested.isPropDerived && !propDrivingFieldNames.has(`${nested.name}s`)) {
|
|
@@ -9550,7 +9645,7 @@ ${goFields.join(`
|
|
|
9550
9645
|
}
|
|
9551
9646
|
const staticChildren = this.collectStaticChildInstances(ir.root, ir.metadata.propsParams);
|
|
9552
9647
|
for (const child of staticChildren) {
|
|
9553
|
-
lines.push(` ${child.fieldName} ${child.name}Props \`json:"-"\``);
|
|
9648
|
+
lines.push(` ${child.fieldName} ${this.resolveChildName(child.name)}Props \`json:"-"\``);
|
|
9554
9649
|
}
|
|
9555
9650
|
for (const slot of spreadSlots) {
|
|
9556
9651
|
const jsonTag = "-";
|
|
@@ -9929,6 +10024,22 @@ ${goFields.join(`
|
|
|
9929
10024
|
resolvedSignalParsed(signal) {
|
|
9930
10025
|
return resolveSignalParsedThroughSeedPlan(this.state, signal);
|
|
9931
10026
|
}
|
|
10027
|
+
refuseUnbakeableDerivedObjectLiteral(name, loc, frees) {
|
|
10028
|
+
if (frees.length === 0)
|
|
10029
|
+
return;
|
|
10030
|
+
if (!this.state.templateReadRootFields.has(name))
|
|
10031
|
+
return;
|
|
10032
|
+
this.state.errors.push({
|
|
10033
|
+
code: "BF101",
|
|
10034
|
+
severity: "error",
|
|
10035
|
+
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.`,
|
|
10036
|
+
loc,
|
|
10037
|
+
suggestion: {
|
|
10038
|
+
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.`,
|
|
10039
|
+
escape: [{ kind: "client-directive" }]
|
|
10040
|
+
}
|
|
10041
|
+
});
|
|
10042
|
+
}
|
|
9932
10043
|
extractPropFallback(initialValue, preParsed) {
|
|
9933
10044
|
const structural = preParsed ? this.extractPropFallbackFromParsed(preParsed) : null;
|
|
9934
10045
|
if (structural)
|
|
@@ -10257,6 +10368,7 @@ ${goFields.join(`
|
|
|
10257
10368
|
return hit !== null && hit.depth > 0 && hit.binding.source === "item";
|
|
10258
10369
|
}
|
|
10259
10370
|
rootFieldRef(name) {
|
|
10371
|
+
this.state.templateReadRootFields.add(name);
|
|
10260
10372
|
const prefix = this.inLoop ? "$." : ".";
|
|
10261
10373
|
return `${prefix}${capitalizeFieldName(name)}`;
|
|
10262
10374
|
}
|
|
@@ -10278,6 +10390,9 @@ ${goFields.join(`
|
|
|
10278
10390
|
return null;
|
|
10279
10391
|
return `"${escapeGoString(value)}"`;
|
|
10280
10392
|
}
|
|
10393
|
+
findModuleConst(name) {
|
|
10394
|
+
return this.state.localConstants.find((k) => k.name === name && k.isModule && !k.containsArrow);
|
|
10395
|
+
}
|
|
10281
10396
|
resolveModuleNumericConst(name) {
|
|
10282
10397
|
if (this.isCurrentLoopItem(name))
|
|
10283
10398
|
return null;
|
|
@@ -10285,12 +10400,25 @@ ${goFields.join(`
|
|
|
10285
10400
|
return null;
|
|
10286
10401
|
if (this.isOuterLoopParam(name))
|
|
10287
10402
|
return null;
|
|
10288
|
-
const c = this.
|
|
10403
|
+
const c = this.findModuleConst(name);
|
|
10289
10404
|
if (!c || c.value === undefined)
|
|
10290
10405
|
return null;
|
|
10291
10406
|
const v = c.value.trim().replace(/(?<=\d)_(?=\d)/g, "");
|
|
10292
10407
|
return /^-?\d+(\.\d+)?$/.test(v) ? v : null;
|
|
10293
10408
|
}
|
|
10409
|
+
resolveModuleBooleanConst(name) {
|
|
10410
|
+
if (this.isCurrentLoopItem(name))
|
|
10411
|
+
return null;
|
|
10412
|
+
if (this.loopVarRefCount.has(name))
|
|
10413
|
+
return null;
|
|
10414
|
+
if (this.isOuterLoopParam(name))
|
|
10415
|
+
return null;
|
|
10416
|
+
const c = this.findModuleConst(name);
|
|
10417
|
+
if (!c || c.value === undefined)
|
|
10418
|
+
return null;
|
|
10419
|
+
const v = c.value.trim();
|
|
10420
|
+
return v === "true" || v === "false" ? v : null;
|
|
10421
|
+
}
|
|
10294
10422
|
literal(value, literalType) {
|
|
10295
10423
|
if (literalType === "string")
|
|
10296
10424
|
return `"${value}"`;
|
|
@@ -10928,8 +11056,10 @@ ${goFields.join(`
|
|
|
10928
11056
|
}
|
|
10929
11057
|
const signal = localVarMap.get(expr.name);
|
|
10930
11058
|
if (signal) {
|
|
11059
|
+
this.rootFieldRef(signal);
|
|
10931
11060
|
return `$.${capitalizeFieldName(signal)}`;
|
|
10932
11061
|
}
|
|
11062
|
+
this.rootFieldRef(expr.name);
|
|
10933
11063
|
return `.${capitalizeFieldName(expr.name)}`;
|
|
10934
11064
|
}
|
|
10935
11065
|
case "literal":
|
|
@@ -10962,6 +11092,7 @@ ${goFields.join(`
|
|
|
10962
11092
|
return `${paramPrefix}.${capitalizeFieldName(expr.callee.property)}`;
|
|
10963
11093
|
}
|
|
10964
11094
|
if (expr.callee.kind === "identifier" && expr.args.length === 0) {
|
|
11095
|
+
this.rootFieldRef(expr.callee.name);
|
|
10965
11096
|
return `$.${capitalizeFieldName(expr.callee.name)}`;
|
|
10966
11097
|
}
|
|
10967
11098
|
if (asCallbackMethodCall(expr) !== null) {
|
|
@@ -11134,7 +11265,8 @@ ${goFields.join(`
|
|
|
11134
11265
|
return this.scope.isBound(name) || this.loopVarRefCount.has(name);
|
|
11135
11266
|
}
|
|
11136
11267
|
loopRowChildPropOverrides(comp) {
|
|
11137
|
-
const
|
|
11268
|
+
const declaredName = this.resolveChildName(comp.name);
|
|
11269
|
+
const childShape = this.childComponentShapes.get(declaredName);
|
|
11138
11270
|
const args = [];
|
|
11139
11271
|
let needsRebuild = false;
|
|
11140
11272
|
for (const prop of comp.props) {
|
|
@@ -11154,10 +11286,10 @@ ${goFields.join(`
|
|
|
11154
11286
|
if (!free || ![...free].some((name) => this.isLoopShadowedName(name)))
|
|
11155
11287
|
continue;
|
|
11156
11288
|
{
|
|
11157
|
-
const derived = this.childDerivedFieldDeps.get(
|
|
11289
|
+
const derived = this.childDerivedFieldDeps.get(declaredName);
|
|
11158
11290
|
const overriddenField = capitalizeFieldName(prop.name);
|
|
11159
11291
|
const staleField = derived ? [...derived].find(([, deps]) => deps.has(overriddenField))?.[0] : undefined;
|
|
11160
|
-
if (staleField && !this.childRepropsReady.has(
|
|
11292
|
+
if (staleField && !this.childRepropsReady.has(declaredName)) {
|
|
11161
11293
|
this.state.errors.push({
|
|
11162
11294
|
code: "BF101",
|
|
11163
11295
|
severity: "error",
|
|
@@ -11171,8 +11303,8 @@ ${goFields.join(`
|
|
|
11171
11303
|
}
|
|
11172
11304
|
if (staleField) {
|
|
11173
11305
|
needsRebuild = true;
|
|
11174
|
-
if (!this.repropsOwner.has(
|
|
11175
|
-
this.repropsOwner.set(
|
|
11306
|
+
if (!this.repropsOwner.has(declaredName)) {
|
|
11307
|
+
this.repropsOwner.set(declaredName, this.state.componentName);
|
|
11176
11308
|
}
|
|
11177
11309
|
}
|
|
11178
11310
|
}
|
|
@@ -11198,7 +11330,7 @@ ${goFields.join(`
|
|
|
11198
11330
|
});
|
|
11199
11331
|
continue;
|
|
11200
11332
|
}
|
|
11201
|
-
const fieldName = this.childPropFieldNames.get(
|
|
11333
|
+
const fieldName = this.childPropFieldNames.get(declaredName)?.get(prop.name) ?? capitalizeFieldName(prop.name);
|
|
11202
11334
|
args.push(`${JSON.stringify(fieldName)} ${wrapIfMultiToken(go)}`);
|
|
11203
11335
|
}
|
|
11204
11336
|
if (args.length === 0)
|
|
@@ -11717,7 +11849,7 @@ ${goFields.join(`
|
|
|
11717
11849
|
}
|
|
11718
11850
|
loopItemMarker(loop) {
|
|
11719
11851
|
if (loop.bodyIsMultiRoot)
|
|
11720
|
-
return `{{bfComment "
|
|
11852
|
+
return `{{bfComment "loop-i"}}`;
|
|
11721
11853
|
if (loop.bodyIsItemConditional && loop.key) {
|
|
11722
11854
|
return `{{bfComment (printf "loop-i:%v" ${this.convertExpressionToGo(loop.key)})}}`;
|
|
11723
11855
|
}
|
|
@@ -11742,6 +11874,41 @@ ${goFields.join(`
|
|
|
11742
11874
|
}
|
|
11743
11875
|
return name;
|
|
11744
11876
|
}
|
|
11877
|
+
queueDynamicPropDefine(comp) {
|
|
11878
|
+
const args = [];
|
|
11879
|
+
const declaredName = this.resolveChildName(comp.name);
|
|
11880
|
+
const childShape = this.childComponentShapes.get(declaredName);
|
|
11881
|
+
for (const prop of comp.props) {
|
|
11882
|
+
if (prop.value.kind !== "jsx-children" || prop.name === "children")
|
|
11883
|
+
continue;
|
|
11884
|
+
const children = prop.value.children;
|
|
11885
|
+
if (this.extractTextChildren(children) !== null)
|
|
11886
|
+
continue;
|
|
11887
|
+
if (this.extractHtmlChildren(children) !== null)
|
|
11888
|
+
continue;
|
|
11889
|
+
if (this.extractScopedHtmlChildren(children) !== null)
|
|
11890
|
+
continue;
|
|
11891
|
+
if (childShape?.restBagField && !childShape.paramNames.has(prop.name)) {
|
|
11892
|
+
this.state.errors.push({
|
|
11893
|
+
code: "BF101",
|
|
11894
|
+
severity: "error",
|
|
11895
|
+
message: `JSX-valued prop '${prop.name}' on <${comp.name}> is dynamic and routes into the child's rest-bag prop ('${childShape.restBagField}') rather than a declared field — there is no named Go struct field for 'bf_with_props' to target`,
|
|
11896
|
+
loc: prop.loc
|
|
11897
|
+
});
|
|
11898
|
+
continue;
|
|
11899
|
+
}
|
|
11900
|
+
const name = `${this.state.componentName}__prop_${prop.name}_${comp.slotId}`;
|
|
11901
|
+
if (!this.state.pendingChildrenDefines.some((d) => d.name === name)) {
|
|
11902
|
+
this.state.pendingChildrenDefines.push({
|
|
11903
|
+
name,
|
|
11904
|
+
content: this.renderChildren(children)
|
|
11905
|
+
});
|
|
11906
|
+
}
|
|
11907
|
+
const fieldName = this.childPropFieldNames.get(declaredName)?.get(prop.name) ?? capitalizeFieldName(prop.name);
|
|
11908
|
+
args.push(`${JSON.stringify(fieldName)} (bf_tmpl ${JSON.stringify(name)} .)`);
|
|
11909
|
+
}
|
|
11910
|
+
return args.length > 0 ? args.join(" ") : null;
|
|
11911
|
+
}
|
|
11745
11912
|
queueLoopBodyChildrenDefine(comp) {
|
|
11746
11913
|
const effectiveChildren = comp.children.length > 0 ? comp.children : resolveJsxChildrenProp(comp.props);
|
|
11747
11914
|
if (effectiveChildren.length === 0)
|
|
@@ -11769,29 +11936,32 @@ ${goFields.join(`
|
|
|
11769
11936
|
if (comp.dynamicTag) {
|
|
11770
11937
|
return this.renderChildren(comp.children);
|
|
11771
11938
|
}
|
|
11939
|
+
const declaredName = this.resolveChildName(comp.name);
|
|
11772
11940
|
let templateCall;
|
|
11773
11941
|
if (this.inLoop && (this.loopWrapperStack[this.loopWrapperStack.length - 1] ?? false)) {
|
|
11774
11942
|
const loopBodyDefine = this.queueLoopBodyChildrenDefine(comp);
|
|
11775
11943
|
if (loopBodyDefine) {
|
|
11776
11944
|
const bodyData = this.loopScalarItemStack[this.loopScalarItemStack.length - 1] ? ".BfLoopItem" : ".";
|
|
11777
|
-
templateCall = `{{template "${
|
|
11945
|
+
templateCall = `{{template "${declaredName}" (bf_with_children . (bf_tmpl "${loopBodyDefine}" ${bodyData}))}}`;
|
|
11778
11946
|
} else {
|
|
11779
|
-
templateCall = `{{template "${
|
|
11947
|
+
templateCall = `{{template "${declaredName}" .}}`;
|
|
11780
11948
|
}
|
|
11781
11949
|
} else if (this.inLoop && comp.slotId) {
|
|
11782
11950
|
const suffix = slotIdToFieldSuffix(comp.slotId);
|
|
11783
11951
|
const overrides = this.loopRowChildPropOverrides(comp);
|
|
11784
11952
|
const loopBodyDefine = this.queueLoopBodyChildrenDefine(comp);
|
|
11785
|
-
const base = overrides ? overrides.helper === "bf_reprops" ? `(bf_reprops ${JSON.stringify(
|
|
11786
|
-
templateCall = loopBodyDefine ? `{{template "${
|
|
11953
|
+
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}`;
|
|
11954
|
+
templateCall = loopBodyDefine ? `{{template "${declaredName}" (bf_with_children ${base} (bf_tmpl "${loopBodyDefine}" .))}}` : `{{template "${declaredName}" ${base}}}`;
|
|
11787
11955
|
} else if (this.inLoop) {
|
|
11788
|
-
templateCall = `{{template "${
|
|
11956
|
+
templateCall = `{{template "${declaredName}" .}}`;
|
|
11789
11957
|
} else if (comp.slotId) {
|
|
11790
11958
|
const suffix = slotIdToFieldSuffix(comp.slotId);
|
|
11791
11959
|
const childrenDefine = this.queueDynamicChildrenDefine(comp);
|
|
11792
|
-
|
|
11960
|
+
const propArgs = this.queueDynamicPropDefine(comp);
|
|
11961
|
+
const base = propArgs ? `(bf_with_props .${comp.name}${suffix} ${propArgs})` : `.${comp.name}${suffix}`;
|
|
11962
|
+
templateCall = childrenDefine ? `{{template "${declaredName}" (bf_with_children ${base} (bf_tmpl "${childrenDefine}" .))}}` : `{{template "${declaredName}" ${base}}}`;
|
|
11793
11963
|
} else {
|
|
11794
|
-
templateCall = `{{template "${
|
|
11964
|
+
templateCall = `{{template "${declaredName}" .${comp.name}}}`;
|
|
11795
11965
|
}
|
|
11796
11966
|
if (ctx?.isRootOfClientComponent) {
|
|
11797
11967
|
return `{{bfScopeComment .}}${templateCall}`;
|