@barefootjs/go-template 0.29.0 → 0.30.2

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/index.js CHANGED
@@ -972,7 +972,26 @@ function renderLoweringNode(ctx, node) {
972
972
  }
973
973
 
974
974
  // src/adapter/type/type-codegen.ts
975
- function typeInfoToGo(ctx, typeInfo, defaultValue) {
975
+ function collapseLiteralUnion(typeInfo) {
976
+ if (typeInfo.kind !== "union" || !typeInfo.unionTypes || typeInfo.unionTypes.length === 0) {
977
+ return typeInfo;
978
+ }
979
+ const familyOf = (m) => {
980
+ if (m.kind !== "primitive")
981
+ return null;
982
+ return m.primitive === "string" || m.primitive === "number" || m.primitive === "boolean" ? m.primitive : null;
983
+ };
984
+ const first = familyOf(typeInfo.unionTypes[0]);
985
+ if (!first)
986
+ return typeInfo;
987
+ for (const m of typeInfo.unionTypes) {
988
+ if (familyOf(m) !== first)
989
+ return typeInfo;
990
+ }
991
+ return { kind: "primitive", raw: typeInfo.raw, primitive: first };
992
+ }
993
+ function typeInfoToGo(ctx, _typeInfo, defaultValue) {
994
+ const typeInfo = collapseLiteralUnion(_typeInfo);
976
995
  switch (typeInfo.kind) {
977
996
  case "primitive":
978
997
  switch (typeInfo.primitive) {
@@ -1142,7 +1161,8 @@ function nillableAwarePropRef(ctx, propName, expectedType) {
1142
1161
  }
1143
1162
  return fieldRef;
1144
1163
  }
1145
- function convertInitialValue(ctx, value, typeInfo, propsParams, preParsed) {
1164
+ function convertInitialValue(ctx, value, _typeInfo, propsParams, preParsed) {
1165
+ const typeInfo = collapseLiteralUnion(_typeInfo);
1146
1166
  const propRef = (propName2) => nillableAwarePropRef(ctx, propName2, typeInfo);
1147
1167
  if (/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(value)) {
1148
1168
  if (propsParams?.some((p) => p.name === value)) {
@@ -2090,6 +2110,78 @@ function propsAccessNameFromParsed2(ctx, node) {
2090
2110
  return null;
2091
2111
  return node.property;
2092
2112
  }
2113
+ function collectPropsReadByCtorInit(body, propsObjectName, propNames) {
2114
+ const found = new Set;
2115
+ const visit = (e, bound) => {
2116
+ switch (e.kind) {
2117
+ case "identifier":
2118
+ if (!propsObjectName && propNames.has(e.name) && !bound.has(e.name))
2119
+ found.add(e.name);
2120
+ return;
2121
+ case "member":
2122
+ if (propsObjectName && !e.computed && e.object.kind === "identifier" && e.object.name === propsObjectName) {
2123
+ found.add(e.property);
2124
+ return;
2125
+ }
2126
+ visit(e.object, bound);
2127
+ return;
2128
+ case "index-access":
2129
+ visit(e.object, bound);
2130
+ visit(e.index, bound);
2131
+ return;
2132
+ case "binary":
2133
+ case "logical":
2134
+ visit(e.left, bound);
2135
+ visit(e.right, bound);
2136
+ return;
2137
+ case "unary":
2138
+ visit(e.argument, bound);
2139
+ return;
2140
+ case "conditional":
2141
+ visit(e.test, bound);
2142
+ visit(e.consequent, bound);
2143
+ visit(e.alternate, bound);
2144
+ return;
2145
+ case "call":
2146
+ visit(e.callee, bound);
2147
+ e.args.forEach((a) => visit(a, bound));
2148
+ return;
2149
+ case "template-literal":
2150
+ for (const p of e.parts)
2151
+ if (p.type === "expression")
2152
+ visit(p.expr, bound);
2153
+ return;
2154
+ case "array-literal":
2155
+ e.elements.forEach((el) => visit(el, bound));
2156
+ return;
2157
+ case "object-literal":
2158
+ for (const p of e.properties)
2159
+ visit(p.value, bound);
2160
+ return;
2161
+ case "array-method":
2162
+ visit(e.object, bound);
2163
+ e.args.forEach((a) => visit(a, bound));
2164
+ if (e.method === "flat" && e.depthExpr)
2165
+ visit(e.depthExpr, bound);
2166
+ return;
2167
+ case "arrow": {
2168
+ const inner = e.params.length === 0 ? bound : new Set([...bound, ...e.params]);
2169
+ visit(e.body, inner);
2170
+ return;
2171
+ }
2172
+ case "literal":
2173
+ case "regex":
2174
+ case "unsupported":
2175
+ return;
2176
+ default: {
2177
+ const _exhaustive = e;
2178
+ return;
2179
+ }
2180
+ }
2181
+ };
2182
+ visit(body, new Set);
2183
+ return found;
2184
+ }
2093
2185
 
2094
2186
  // src/adapter/spread/spread-codegen.ts
2095
2187
  import ts2 from "typescript";
@@ -2691,6 +2783,7 @@ class GoTemplateAdapter extends BaseAdapter {
2691
2783
  this.state.pendingChildrenDefines = [];
2692
2784
  this.primeCompileState(ir);
2693
2785
  this.state.stringValueNames = collectStringValueNames(ir);
2786
+ this.recordDerivedFieldDeps(ir, new Set((ir.metadata.propsParams ?? []).map((p) => p.name)));
2694
2787
  if (!options?.siblingTemplatesRegistered) {
2695
2788
  this.checkImportedLoopChildComponents(ir);
2696
2789
  }
@@ -2827,15 +2920,50 @@ ${scriptRegistrations}${templateBody}
2827
2920
  return `{{if .Scripts}}${registrations.join("")}{{end}}
2828
2921
  `;
2829
2922
  }
2923
+ childDerivedFieldDeps = new Map;
2924
+ childPropFieldNames = new Map;
2925
+ childRepropsReady = new Map;
2926
+ repropsOwner = new Map;
2927
+ recordDerivedFieldDeps(ir, paramNames) {
2928
+ const name = ir.metadata.componentName;
2929
+ if (!name)
2930
+ return;
2931
+ const sourceOf = new Map((ir.metadata.propsParams ?? []).map((p) => [p.name, p.sourceName ?? p.name]));
2932
+ const canonical = (local) => capitalizeFieldName(sourceOf.get(local) ?? local);
2933
+ const propFieldNames = new Set([...paramNames].map(canonical));
2934
+ const fieldNames = new Map;
2935
+ for (const p of ir.metadata.propsParams ?? []) {
2936
+ fieldNames.set(p.sourceName ?? p.name, capitalizeFieldName(p.name));
2937
+ }
2938
+ this.childPropFieldNames.set(name, fieldNames);
2939
+ const deps = new Map;
2940
+ const ctorInits = [
2941
+ ...(ir.metadata.memos ?? []).map((m) => ({ field: m.name, init: m.parsed })),
2942
+ ...(ir.metadata.signals ?? []).map((s) => ({ field: s.getter, init: s.parsed }))
2943
+ ];
2944
+ for (const { field, init } of ctorInits) {
2945
+ if (propFieldNames.has(capitalizeFieldName(field)))
2946
+ continue;
2947
+ if (!init)
2948
+ continue;
2949
+ const read = collectPropsReadByCtorInit(init, ir.metadata.propsObjectName ?? null, paramNames);
2950
+ if (read.size === 0)
2951
+ continue;
2952
+ deps.set(field, new Set([...read].map(canonical)));
2953
+ }
2954
+ if (deps.size > 0)
2955
+ this.childDerivedFieldDeps.set(name, deps);
2956
+ }
2830
2957
  registerChildComponentShape(ir) {
2831
2958
  const name = ir.metadata.componentName;
2832
2959
  if (!name)
2833
2960
  return;
2834
- const paramNames = new Set((ir.metadata.propsParams ?? []).map((p) => p.name));
2961
+ const paramNames = new Set((ir.metadata.propsParams ?? []).map((p) => p.sourceName ?? p.name));
2835
2962
  const restPropsName = ir.metadata.restPropsName ?? null;
2836
2963
  const restBagField = restPropsName ? capitalizeFieldName(restPropsName) : null;
2837
- const mapTypedParamNames = new Set((ir.metadata.propsParams ?? []).filter((p) => p.optional && (p.type.kind === "object" || p.type.kind === "interface" && !!p.type.raw)).map((p) => p.name));
2964
+ const mapTypedParamNames = new Set((ir.metadata.propsParams ?? []).filter((p) => p.optional && (p.type.kind === "object" || p.type.kind === "interface" && !!p.type.raw)).map((p) => p.sourceName ?? p.name));
2838
2965
  this.childComponentShapes.set(name, { paramNames, restBagField, mapTypedParamNames });
2966
+ this.recordDerivedFieldDeps(ir, new Set((ir.metadata.propsParams ?? []).map((p) => p.name)));
2839
2967
  this.childContextConsumers.set(name, collectContextConsumers(ir.metadata));
2840
2968
  }
2841
2969
  contextFieldName(c) {
@@ -2904,8 +3032,86 @@ ${scriptRegistrations}${templateBody}
2904
3032
  this.state.needsStringsImport = false;
2905
3033
  this.generatePropsStruct(lines, ir, componentName, nestedComponents, propTypeOverrides, spreadSlots);
2906
3034
  this.generateNewPropsFunction(lines, ir, componentName, nestedComponents, spreadSlots, propTypeOverrides);
3035
+ this.recordRepropsSpec(ir, componentName, nestedComponents, spreadSlots);
3036
+ this.emitOwnedReprops(lines, componentName);
2907
3037
  return this.composeFileHeader(lines);
2908
3038
  }
3039
+ recordRepropsSpec(ir, componentName, nestedComponents, spreadSlots) {
3040
+ if (!this.childDerivedFieldDeps.has(componentName))
3041
+ return;
3042
+ const nestedArrayFields = new Set(nestedComponents.map((n) => `${n.name}s`));
3043
+ const params = (ir.metadata.propsParams ?? []).filter((p) => !nestedArrayFields.has(capitalizeFieldName(p.name)));
3044
+ const takenInput = new Set((ir.metadata.propsParams ?? []).map((p) => capitalizeFieldName(p.name)));
3045
+ const eligible = nestedComponents.every((n) => n.isDynamic && !n.isPropDerived) && spreadSlots.length === 0 && !ir.metadata.restPropsName && this.nonCollidingContextConsumers(takenInput).length === 0;
3046
+ if (!eligible)
3047
+ return;
3048
+ this.childRepropsReady.set(componentName, {
3049
+ params: params.map((p) => capitalizeFieldName(p.name)),
3050
+ usesSearchParams: this.usesSearchParams(ir)
3051
+ });
3052
+ }
3053
+ emitOwnedReprops(lines, owner) {
3054
+ for (const [childName, ownerName] of this.repropsOwner) {
3055
+ if (ownerName !== owner)
3056
+ continue;
3057
+ const spec = this.childRepropsReady.get(childName);
3058
+ if (!spec)
3059
+ continue;
3060
+ this.emitRepropsRegistration(lines, childName, spec);
3061
+ }
3062
+ }
3063
+ emitRepropsRegistration(lines, componentName, spec) {
3064
+ const { params, usesSearchParams } = spec;
3065
+ const inputTypeName = `${componentName}Input`;
3066
+ const q = JSON.stringify(componentName);
3067
+ lines.push(`// ${componentName} computes at least one field from an input prop when its`);
3068
+ lines.push("// props are constructed, so a per-row override inside a composite loop row");
3069
+ lines.push("// cannot be applied by patching fields — the derived field would keep the");
3070
+ lines.push("// shared instance's one-shot value on every row (#2448). This rebuilder");
3071
+ lines.push(`// re-runs New${componentName}Props with the row's overrides folded into the`);
3072
+ lines.push("// Input; the parent calls it through bf_reprops.");
3073
+ lines.push("func init() {");
3074
+ lines.push(` bf.RegisterReprops(${q}, func(base interface{}, kv ...interface{}) (interface{}, error) {`);
3075
+ lines.push(` b, ok := base.(${componentName}Props)`);
3076
+ lines.push("\t\tif !ok {");
3077
+ lines.push(` return nil, bf.RepropsTypeError(${q}, base)`);
3078
+ lines.push("\t\t}");
3079
+ lines.push(` in := ${inputTypeName}{`);
3080
+ lines.push("\t\t\tScopeID: b.ScopeID,");
3081
+ lines.push("\t\t\tBfParent: b.BfParent,");
3082
+ lines.push("\t\t\tBfMount: b.BfMount,");
3083
+ if (usesSearchParams)
3084
+ lines.push("\t\t\tSearchParams: b.SearchParams,");
3085
+ for (const field of params) {
3086
+ lines.push(` ${field}: b.${field},`);
3087
+ }
3088
+ lines.push("\t\t}");
3089
+ lines.push("\t\tfor i := 0; i < len(kv); i += 2 {");
3090
+ lines.push("\t\t\tname, _ := kv[i].(string)");
3091
+ lines.push("\t\t\tvar err error");
3092
+ lines.push("\t\t\tswitch name {");
3093
+ for (const field of params) {
3094
+ lines.push(` case ${JSON.stringify(field)}:`);
3095
+ lines.push(` err = bf.RepropsAssign(${q}, ${JSON.stringify(field)}, &in.${field}, kv[i+1])`);
3096
+ }
3097
+ lines.push("\t\t\tdefault:");
3098
+ lines.push(` err = bf.RepropsUnknownFieldError(${q}, name)`);
3099
+ lines.push("\t\t\t}");
3100
+ lines.push("\t\t\tif err != nil {");
3101
+ lines.push("\t\t\t\treturn nil, err");
3102
+ lines.push("\t\t\t}");
3103
+ lines.push("\t\t}");
3104
+ lines.push(` p := New${componentName}Props(in)`);
3105
+ lines.push("\t\t// Props-only state, absent from Input and therefore not rebuilt.");
3106
+ lines.push("\t\tp.Scripts = b.Scripts");
3107
+ lines.push("\t\tp.BfIsRoot = b.BfIsRoot");
3108
+ lines.push("\t\tp.BfIsChild = b.BfIsChild");
3109
+ lines.push("\t\tp.BfDataKey = b.BfDataKey");
3110
+ lines.push("\t\treturn p, nil");
3111
+ lines.push("\t})");
3112
+ lines.push("}");
3113
+ lines.push("");
3114
+ }
2909
3115
  typeDefinitionToGo(td) {
2910
3116
  if (td.definition.match(/^type \w+ = ('[^']*'(\s*\|\s*'[^']*')*)/)) {
2911
3117
  return `// ${td.name} is a string type.
@@ -3389,7 +3595,8 @@ ${goFields.join(`
3389
3595
  }
3390
3596
  if (jsxName.includes("-"))
3391
3597
  return;
3392
- lines.push(` ${capitalizeFieldName(jsxName)}: ${goValue},`);
3598
+ const fieldName = this.childPropFieldNames.get(child.name)?.get(jsxName) ?? capitalizeFieldName(jsxName);
3599
+ lines.push(` ${fieldName}: ${goValue},`);
3393
3600
  };
3394
3601
  for (const prop of child.props) {
3395
3602
  switch (prop.value.kind) {
@@ -5373,6 +5580,78 @@ ${goFields.join(`
5373
5580
  isLoopShadowedName(name) {
5374
5581
  return this.loopParamStack.length > 0 && this.loopParamStack[this.loopParamStack.length - 1] === name || this.loopVarRefCount.has(name) || this.isOuterLoopParam(name) || this.loopBindingStack.some((bindings) => bindings.has(name));
5375
5582
  }
5583
+ loopRowChildPropOverrides(comp) {
5584
+ const childShape = this.childComponentShapes.get(comp.name);
5585
+ const args = [];
5586
+ let needsRebuild = false;
5587
+ for (const prop of comp.props) {
5588
+ if (prop.clientOnly)
5589
+ continue;
5590
+ if (prop.name === "key" || prop.name === "children")
5591
+ continue;
5592
+ if (prop.name.startsWith("on") && prop.name.length > 2)
5593
+ continue;
5594
+ if (prop.name.includes("-"))
5595
+ continue;
5596
+ if (childShape?.restBagField && !childShape.paramNames.has(prop.name))
5597
+ continue;
5598
+ if (prop.value.kind !== "expression")
5599
+ continue;
5600
+ const free = prop.freeIdentifiers;
5601
+ if (!free || ![...free].some((name) => this.isLoopShadowedName(name)))
5602
+ continue;
5603
+ {
5604
+ const derived = this.childDerivedFieldDeps.get(comp.name);
5605
+ const overriddenField = capitalizeFieldName(prop.name);
5606
+ const staleField = derived ? [...derived].find(([, deps]) => deps.has(overriddenField))?.[0] : undefined;
5607
+ if (staleField && !this.childRepropsReady.has(comp.name)) {
5608
+ this.state.errors.push({
5609
+ code: "BF101",
5610
+ severity: "error",
5611
+ message: `Prop '${prop.name}' on <${comp.name}> nested inside a dynamic loop row is overridden per row, but <${comp.name}>'s '${staleField}' field is computed from '${prop.name}' when the shared instance is first constructed and won't recompute per row — it would keep the first row's value on every row.`,
5612
+ loc: prop.loc,
5613
+ suggestion: {
5614
+ message: `Mark this loop position '@client' to render <${comp.name}> client-side, or compute '${staleField}' in the parent and pass it to <${comp.name}> as a plain prop instead of deriving it inside <${comp.name}>.`
5615
+ }
5616
+ });
5617
+ continue;
5618
+ }
5619
+ if (staleField) {
5620
+ needsRebuild = true;
5621
+ if (!this.repropsOwner.has(comp.name)) {
5622
+ this.repropsOwner.set(comp.name, this.state.componentName);
5623
+ }
5624
+ }
5625
+ }
5626
+ const exprOut = {};
5627
+ const errorCountBefore = this.state.errors.length;
5628
+ let go = this.convertExpressionToGo(prop.value.expr, exprOut, prop.value.parsed);
5629
+ if (this.state.errors.length > errorCountBefore) {
5630
+ for (let i = errorCountBefore;i < this.state.errors.length; i++) {
5631
+ this.state.errors[i].loc = prop.loc;
5632
+ }
5633
+ continue;
5634
+ }
5635
+ const singlePartTemplateLiteral = exprOut.parsed?.kind === "template-literal" && exprOut.parsed.parts.length === 1 && exprOut.parsed.parts[0].type !== "string" && go.startsWith("{{") && go.endsWith("}}");
5636
+ if (singlePartTemplateLiteral) {
5637
+ go = go.slice(2, -2);
5638
+ }
5639
+ if (!singlePartTemplateLiteral && this.isTemplateFragment(go, exprOut.parsed?.kind)) {
5640
+ this.state.errors.push({
5641
+ code: "BF101",
5642
+ severity: "error",
5643
+ message: `Prop '${prop.name}' on <${comp.name}> nested inside a dynamic loop row reads the row but can't be lowered to a Go template pipeline argument`,
5644
+ loc: prop.loc
5645
+ });
5646
+ continue;
5647
+ }
5648
+ const fieldName = this.childPropFieldNames.get(comp.name)?.get(prop.name) ?? capitalizeFieldName(prop.name);
5649
+ args.push(`${JSON.stringify(fieldName)} ${wrapIfMultiToken(go)}`);
5650
+ }
5651
+ if (args.length === 0)
5652
+ return null;
5653
+ return { args: args.join(" "), helper: needsRebuild ? "bf_reprops" : "bf_with_props" };
5654
+ }
5376
5655
  resolveStaticRecordLiteralIndex(jsExpr) {
5377
5656
  const m = /^([A-Za-z_$][\w$]*)\[\s*(?:'([^']*)'|"([^"]*)")\s*\]$/.exec(jsExpr) ?? /^([A-Za-z_$][\w$]*)\.([A-Za-z_$][\w$]*)$/.exec(jsExpr);
5378
5657
  if (!m)
@@ -5782,6 +6061,10 @@ ${goFields.join(`
5782
6061
  }
5783
6062
  this.inLoop = true;
5784
6063
  const addedLoopVars = [];
6064
+ for (const d of loop.preamble?.declarations ?? []) {
6065
+ this.loopVarRefCount.set(d.name, (this.loopVarRefCount.get(d.name) ?? 0) + 1);
6066
+ addedLoopVars.push(d.name);
6067
+ }
5785
6068
  let pushedBindingMap = false;
5786
6069
  if (supportableDestructure) {
5787
6070
  const built = this.buildDestructureBindingMap(loop, rangeValue);
@@ -5807,6 +6090,7 @@ ${goFields.join(`
5807
6090
  this.loopScalarItemStack.push(this.scalarLiteralLoopGoType(loop.arrayParsed, loop.itemType) !== null);
5808
6091
  this.loopWrapperStack.push(!!loop.childComponent);
5809
6092
  this.loopKeyDepthStack.push(loop.depth);
6093
+ const preambleAssignments = (loop.preamble?.declarations ?? []).map((d) => `{{$${d.name} := ${this.renderParsedExpr(d.valueParsed)}}}`).join("");
5810
6094
  const children = this.renderChildren(loop.children);
5811
6095
  this.loopKeyDepthStack.pop();
5812
6096
  this.loopWrapperStack.pop();
@@ -5841,9 +6125,9 @@ ${goFields.join(`
5841
6125
  } else {
5842
6126
  filterCond = "true";
5843
6127
  }
5844
- return `{{bfComment "loop:${loop.markerId}"}}{{range $${rangeIndex}, $${rangeValue} := ${goArray}}}{{if ${filterCond}}}${itemMarker}${children}{{end}}{{end}}{{bfComment "/loop:${loop.markerId}"}}`;
6128
+ return `{{bfComment "loop:${loop.markerId}"}}{{range $${rangeIndex}, $${rangeValue} := ${goArray}}}{{if ${filterCond}}}${preambleAssignments}${itemMarker}${children}{{end}}{{end}}{{bfComment "/loop:${loop.markerId}"}}`;
5845
6129
  }
5846
- return `{{bfComment "loop:${loop.markerId}"}}{{range $${rangeIndex}, $${rangeValue} := ${goArray}}}${itemMarker}${children}{{end}}{{bfComment "/loop:${loop.markerId}"}}`;
6130
+ return `{{bfComment "loop:${loop.markerId}"}}{{range $${rangeIndex}, $${rangeValue} := ${goArray}}}${preambleAssignments}${itemMarker}${children}{{end}}{{bfComment "/loop:${loop.markerId}"}}`;
5847
6131
  }
5848
6132
  renderUnrolledStaticElementLoop(loop, items) {
5849
6133
  this.inLoop = true;
@@ -5942,8 +6226,10 @@ ${goFields.join(`
5942
6226
  }
5943
6227
  } else if (this.inLoop && comp.slotId) {
5944
6228
  const suffix = slotIdToFieldSuffix(comp.slotId);
6229
+ const overrides = this.loopRowChildPropOverrides(comp);
5945
6230
  const loopBodyDefine = this.queueLoopBodyChildrenDefine(comp);
5946
- templateCall = loopBodyDefine ? `{{template "${comp.name}" (bf_with_children $.${comp.name}${suffix} (bf_tmpl "${loopBodyDefine}" .))}}` : `{{template "${comp.name}" $.${comp.name}${suffix}}}`;
6231
+ 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}`;
6232
+ templateCall = loopBodyDefine ? `{{template "${comp.name}" (bf_with_children ${base} (bf_tmpl "${loopBodyDefine}" .))}}` : `{{template "${comp.name}" ${base}}}`;
5947
6233
  } else if (this.inLoop) {
5948
6234
  templateCall = `{{template "${comp.name}" .}}`;
5949
6235
  } else if (comp.slotId) {
@@ -6184,7 +6470,6 @@ var goTemplateAdapter = new GoTemplateAdapter;
6184
6470
  // src/conformance-pins.ts
6185
6471
  var conformancePins = {
6186
6472
  "filter-typeof-predicate": [{ code: "BF021", severity: "error" }],
6187
- "map-preamble-branch-body": [{ code: "BF021", severity: "error" }],
6188
6473
  "map-array-builder-body": [{ code: "BF021", severity: "error" }],
6189
6474
  "map-array-builder-escaping": [{ code: "BF021", severity: "error" }],
6190
6475
  "fill-unsupported": [{ code: "BF101", severity: "error" }],
@@ -6212,7 +6497,12 @@ var conformancePins = {
6212
6497
  };
6213
6498
  // src/render-divergences.ts
6214
6499
  var renderDivergences = {
6215
- "composite-row-child-component": "a child component nested inside a dynamic loop row receives one hoisted props value built outside `{{range}}`, so every row renders the child with zero-value props (https://github.com/piconic-ai/barefootjs/issues/2445)"
6500
+ "aliased-destructured-prop": 'aliased destructured prop `{ n: count }` loses its rename the Input struct field is Count `json:"count"`, so the caller-side struct literal keyed by the real prop name fails `go run` outright (unknown field N, exit 1) (https://github.com/piconic-ai/barefootjs/issues/2460)',
6501
+ "loop-destructured-param-condition": "a destructured .map() param binding used as a row ternary CONDITION emits the root-scope `{{if $.Active}}` — `renderConditionExpr` omits `loopBindingStack`, unlike `identifierToGoRef` (text positions resolve the same binding correctly) (https://github.com/piconic-ai/barefootjs/issues/2486)",
6502
+ "nested-loop-tail-content": "outer-row content AFTER a nested inner loop renders through non-loop arms (spread lowers to the component-root `.Spread_0`) — `inLoop` is cleared, not restored, by the inner loop's exit; the same content BEFORE the inner loop emits correctly (https://github.com/piconic-ai/barefootjs/issues/2487)",
6503
+ "loop-param-shadows-spread-const": "spreading a loop row object mangles attribute names (`id` → `-i-d`, `title` → `-title`); the spread VALUE is correctly row-scoped, distinguishing this from the template-adapter const-shadow hole #2489 (https://github.com/piconic-ai/barefootjs/issues/2490)",
6504
+ "loop-param-shadows-record-template-span": "a dynamic-key element access on a loop row (`tone[k]`) renders empty at execute time — the emitted template contains no baked const (correct post-fix), but the row lookup resolves to nothing (https://github.com/piconic-ai/barefootjs/issues/2491)",
6505
+ "callback-param-shadows-prop": "JS-computed signal/memo initializers (`[…].map(…).join(…)`, memo over signal + prop) don't seed Go SSR — renders `[]` / empty where every other adapter renders the computed value; hydration snaps to correct (https://github.com/piconic-ai/barefootjs/issues/2492)"
6216
6506
  };
6217
6507
  export {
6218
6508
  renderDivergences,
@@ -1 +1 @@
1
- {"version":3,"file":"render-divergences.d.ts","sourceRoot":"","sources":["../src/render-divergences.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAExD,eAAO,MAAM,iBAAiB,EAAE,iBAuB/B,CAAA"}
1
+ {"version":3,"file":"render-divergences.d.ts","sourceRoot":"","sources":["../src/render-divergences.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAExD,eAAO,MAAM,iBAAiB,EAAE,iBAsC/B,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@barefootjs/go-template",
3
- "version": "0.29.0",
3
+ "version": "0.30.2",
4
4
  "description": "Go html/template adapter for BarefootJS - generates Go template files from IR",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -49,7 +49,7 @@
49
49
  "directory": "packages/adapter-go-template"
50
50
  },
51
51
  "dependencies": {
52
- "@barefootjs/shared": "0.29.0"
52
+ "@barefootjs/shared": "0.30.2"
53
53
  },
54
54
  "peerDependencies": {
55
55
  "@barefootjs/jsx": ">=0.2.0",
@@ -57,6 +57,6 @@
57
57
  },
58
58
  "devDependencies": {
59
59
  "@barefootjs/adapter-tests": "0.1.0",
60
- "@barefootjs/jsx": "0.29.0"
60
+ "@barefootjs/jsx": "0.30.2"
61
61
  }
62
62
  }