@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/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 ts9 from "typescript";
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 ts5 from "typescript";
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 = ts4.createSourceFile("__free_ids__.ts", `(${text});`, ts4.ScriptTarget.Latest, true, ts4.ScriptKind.TS);
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 || !ts4.isExpressionStatement(stmt))
2215
+ if (!stmt || !ts5.isExpressionStatement(stmt))
2177
2216
  return new Set;
2178
- const expr = ts4.isParenthesizedExpression(stmt.expression) ? stmt.expression.expression : stmt.expression;
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 ts8 from "typescript";
2358
+ import ts9 from "typescript";
2338
2359
 
2339
2360
  // ../jsx/src/strip-types.ts
2340
- import ts7 from "typescript";
2361
+ import ts8 from "typescript";
2341
2362
 
2342
2363
  // ../jsx/src/analyzer-context.ts
2343
- var _typePrinter = ts8.createPrinter({ removeComments: true, omitTrailingSemicolon: true });
2344
- var _blankTypeSourceFile = ts8.createSourceFile("__bf_types__.ts", "", ts8.ScriptTarget.Latest);
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 (ts9.isIdentifier(name))
2597
+ if (ts10.isIdentifier(name))
2575
2598
  out.push(name.text);
2576
- else if (ts9.isObjectBindingPattern(name))
2599
+ else if (ts10.isObjectBindingPattern(name))
2577
2600
  name.elements.forEach((e) => addBindingNames(e.name, out));
2578
- else if (ts9.isArrayBindingPattern(name))
2601
+ else if (ts10.isArrayBindingPattern(name))
2579
2602
  name.elements.forEach((e) => {
2580
- if (!ts9.isOmittedExpression(e))
2603
+ if (!ts10.isOmittedExpression(e))
2581
2604
  addBindingNames(e.name, out);
2582
2605
  });
2583
2606
  }
2584
2607
  function visit(n) {
2585
- if (ts9.isTypeNode(n))
2608
+ if (ts10.isTypeNode(n))
2586
2609
  return;
2587
- if (ts9.isIdentifier(n)) {
2610
+ if (ts10.isIdentifier(n)) {
2588
2611
  const parent = n.parent;
2589
- if (parent && ts9.isPropertyAccessExpression(parent) && parent.name === n)
2612
+ if (parent && ts10.isPropertyAccessExpression(parent) && parent.name === n)
2590
2613
  return;
2591
- if (parent && ts9.isPropertyAssignment(parent) && parent.name === n)
2614
+ if (parent && ts10.isPropertyAssignment(parent) && parent.name === n)
2592
2615
  return;
2593
- if (parent && ts9.isParameter(parent) && parent.name === n)
2616
+ if (parent && ts10.isParameter(parent) && parent.name === n)
2594
2617
  return;
2595
- if (parent && ts9.isVariableDeclaration(parent) && parent.name === n)
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 (ts9.isArrowFunction(n)) {
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
- ts9.forEachChild(n, visit);
2631
+ ts10.forEachChild(n, visit);
2609
2632
  for (const name of params)
2610
2633
  boundNames.delete(name);
2611
2634
  return;
2612
2635
  }
2613
- ts9.forEachChild(n, visit);
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 ts13 from "typescript";
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 ts10 from "typescript";
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 = ts10.createSourceFile("bf-assignment-scan.tsx", bodyText, ts10.ScriptTarget.Latest, false, ts10.ScriptKind.TSX);
2744
+ const sf = ts11.createSourceFile("bf-assignment-scan.tsx", bodyText, ts11.ScriptTarget.Latest, false, ts11.ScriptKind.TSX);
2722
2745
  const record = (target) => {
2723
- if (ts10.isIdentifier(target) && candidates.has(target.text)) {
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 (ts10.isBinaryExpression(node) && isAssignmentOperator(node.operatorToken.kind)) {
2751
+ if (ts11.isBinaryExpression(node) && isAssignmentOperator(node.operatorToken.kind)) {
2729
2752
  record(node.left);
2730
- } else if ((ts10.isPrefixUnaryExpression(node) || ts10.isPostfixUnaryExpression(node)) && (node.operator === ts10.SyntaxKind.PlusPlusToken || node.operator === ts10.SyntaxKind.MinusMinusToken)) {
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
- ts10.forEachChild(node, visit);
2756
+ ts11.forEachChild(node, visit);
2734
2757
  };
2735
- ts10.forEachChild(sf, visit);
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 >= ts10.SyntaxKind.FirstAssignment && kind <= ts10.SyntaxKind.LastAssignment;
2781
+ return kind >= ts11.SyntaxKind.FirstAssignment && kind <= ts11.SyntaxKind.LastAssignment;
2759
2782
  }
2760
2783
 
2761
2784
  // ../jsx/src/reactivity-checker.ts
2762
- import ts11 from "typescript";
2785
+ import ts12 from "typescript";
2763
2786
 
2764
2787
  // ../jsx/src/free-refs.ts
2765
- import ts12 from "typescript";
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 ts14 from "typescript";
3236
+ import ts15 from "typescript";
3214
3237
 
3215
3238
  // ../jsx/src/ir-to-client-js/imports.ts
3216
- import ts16 from "typescript";
3239
+ import ts17 from "typescript";
3217
3240
 
3218
3241
  // ../jsx/src/value-references.ts
3219
- import ts15 from "typescript";
3242
+ import ts16 from "typescript";
3220
3243
 
3221
3244
  // ../jsx/src/relocate.ts
3222
- import ts17 from "typescript";
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 ts18 from "typescript";
3441
+ import ts19 from "typescript";
3419
3442
 
3420
3443
  // ../jsx/src/ir-to-client-js/control-flow/plan/lazy-preamble.ts
3421
- import ts19 from "typescript";
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 ts20 from "typescript";
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 goTypes = new Map;
8534
- for (let i = 0;i < node.elements.length; i++) {
8535
- const el = node.elements[i];
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
- seen.add(key);
8551
- const prev = goTypes.get(key);
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
- goTypes.set(key, goType);
8619
+ shapes.set(key, { kind: "scalar", goType });
8620
+ } else if (prevShape.kind !== "scalar") {
8621
+ return null;
8557
8622
  } else {
8558
- const merged = this.mergeScalarGoType(prev, goType);
8623
+ const merged = this.mergeScalarGoType(prevShape.goType, goType);
8559
8624
  if (!merged)
8560
8625
  return null;
8561
- goTypes.set(key, merged);
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 name = `${componentName}${capitalizeFieldName(signal.getter)}Item`;
8568
- if (this.state.localTypeNames.has(name))
8569
- return null;
8570
- return {
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
- fields: order.map((key) => ({
8573
- tsName: key,
8574
- goName: capitalizeFieldName(key),
8575
- goType: goTypes.get(key)
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
- lines.push(`// ${wrapperName} wraps ${nested.name}Props with per-row loop datum`);
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(` ${nested.name}Props`);
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([]${nested.name}Props, ${baked.items.length})`);
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${nested.name}Props(${nested.name}Input{${fields}})`);
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([]${nested.name}Props, len(in.${nested.name}s))`);
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${nested.name}Props(item)`);
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
- lines.push(` ${child.fieldName}: New${child.name}Props(${child.name}Input{`);
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(child.name) ?? []) {
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(child.name);
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([]${nested.name}Props, len(items))`);
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${nested.name}Props(${nested.name}Input{ /* fields */ })`);
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
- lines.push(` ${childVar} := New${child.name}Props(${child.name}Input{`);
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(` ${nested.name}Props: New${nested.name}Props(${nested.name}Input{`);
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
- lines.push(` ${childVar} := New${child.name}Props(${child.name}Input{`);
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(` ${nested.name}Props: New${nested.name}Props(${nested.name}Input{`);
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.state.localStructFields.set(desiredName, new Map(fields.map((f) => [f.tsName, f.goName])));
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
- this.state.localTypeNames.add(synth.name);
9386
- this.state.localStructFields.set(synth.name, new Map(synth.fields.map((f) => [f.tsName, f.goName])));
9387
- this.state.synthStructTypes.set(signal.getter, {
9388
- kind: "array",
9389
- raw: `${synth.name}[]`,
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.state.localConstants.find((k) => k.name === name && k.isModule && !k.containsArrow);
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 childShape = this.childComponentShapes.get(comp.name);
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(comp.name);
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(comp.name)) {
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(comp.name)) {
11175
- this.repropsOwner.set(comp.name, this.state.componentName);
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(comp.name)?.get(prop.name) ?? capitalizeFieldName(prop.name);
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)
@@ -11744,7 +11876,8 @@ ${goFields.join(`
11744
11876
  }
11745
11877
  queueDynamicPropDefine(comp) {
11746
11878
  const args = [];
11747
- const childShape = this.childComponentShapes.get(comp.name);
11879
+ const declaredName = this.resolveChildName(comp.name);
11880
+ const childShape = this.childComponentShapes.get(declaredName);
11748
11881
  for (const prop of comp.props) {
11749
11882
  if (prop.value.kind !== "jsx-children" || prop.name === "children")
11750
11883
  continue;
@@ -11771,7 +11904,7 @@ ${goFields.join(`
11771
11904
  content: this.renderChildren(children)
11772
11905
  });
11773
11906
  }
11774
- const fieldName = this.childPropFieldNames.get(comp.name)?.get(prop.name) ?? capitalizeFieldName(prop.name);
11907
+ const fieldName = this.childPropFieldNames.get(declaredName)?.get(prop.name) ?? capitalizeFieldName(prop.name);
11775
11908
  args.push(`${JSON.stringify(fieldName)} (bf_tmpl ${JSON.stringify(name)} .)`);
11776
11909
  }
11777
11910
  return args.length > 0 ? args.join(" ") : null;
@@ -11803,31 +11936,32 @@ ${goFields.join(`
11803
11936
  if (comp.dynamicTag) {
11804
11937
  return this.renderChildren(comp.children);
11805
11938
  }
11939
+ const declaredName = this.resolveChildName(comp.name);
11806
11940
  let templateCall;
11807
11941
  if (this.inLoop && (this.loopWrapperStack[this.loopWrapperStack.length - 1] ?? false)) {
11808
11942
  const loopBodyDefine = this.queueLoopBodyChildrenDefine(comp);
11809
11943
  if (loopBodyDefine) {
11810
11944
  const bodyData = this.loopScalarItemStack[this.loopScalarItemStack.length - 1] ? ".BfLoopItem" : ".";
11811
- templateCall = `{{template "${comp.name}" (bf_with_children . (bf_tmpl "${loopBodyDefine}" ${bodyData}))}}`;
11945
+ templateCall = `{{template "${declaredName}" (bf_with_children . (bf_tmpl "${loopBodyDefine}" ${bodyData}))}}`;
11812
11946
  } else {
11813
- templateCall = `{{template "${comp.name}" .}}`;
11947
+ templateCall = `{{template "${declaredName}" .}}`;
11814
11948
  }
11815
11949
  } else if (this.inLoop && comp.slotId) {
11816
11950
  const suffix = slotIdToFieldSuffix(comp.slotId);
11817
11951
  const overrides = this.loopRowChildPropOverrides(comp);
11818
11952
  const loopBodyDefine = this.queueLoopBodyChildrenDefine(comp);
11819
- const base = overrides ? overrides.helper === "bf_reprops" ? `(bf_reprops ${JSON.stringify(comp.name)} $.${comp.name}${suffix} ${overrides.args})` : `(bf_with_props $.${comp.name}${suffix} ${overrides.args})` : `$.${comp.name}${suffix}`;
11820
- templateCall = loopBodyDefine ? `{{template "${comp.name}" (bf_with_children ${base} (bf_tmpl "${loopBodyDefine}" .))}}` : `{{template "${comp.name}" ${base}}}`;
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}}}`;
11821
11955
  } else if (this.inLoop) {
11822
- templateCall = `{{template "${comp.name}" .}}`;
11956
+ templateCall = `{{template "${declaredName}" .}}`;
11823
11957
  } else if (comp.slotId) {
11824
11958
  const suffix = slotIdToFieldSuffix(comp.slotId);
11825
11959
  const childrenDefine = this.queueDynamicChildrenDefine(comp);
11826
11960
  const propArgs = this.queueDynamicPropDefine(comp);
11827
11961
  const base = propArgs ? `(bf_with_props .${comp.name}${suffix} ${propArgs})` : `.${comp.name}${suffix}`;
11828
- templateCall = childrenDefine ? `{{template "${comp.name}" (bf_with_children ${base} (bf_tmpl "${childrenDefine}" .))}}` : `{{template "${comp.name}" ${base}}}`;
11962
+ templateCall = childrenDefine ? `{{template "${declaredName}" (bf_with_children ${base} (bf_tmpl "${childrenDefine}" .))}}` : `{{template "${declaredName}" ${base}}}`;
11829
11963
  } else {
11830
- templateCall = `{{template "${comp.name}" .${comp.name}}}`;
11964
+ templateCall = `{{template "${declaredName}" .${comp.name}}}`;
11831
11965
  }
11832
11966
  if (ctx?.isRootOfClientComponent) {
11833
11967
  return `{{bfScopeComment .}}${templateCall}`;