@barefootjs/go-template 0.33.2 → 0.33.4

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
@@ -5,7 +5,7 @@ import { barefoot as coreBarefoot } from "@barefootjs/vite";
5
5
  import { devModuleUrl, loadManifest, resolveDevOrigin, resolveScriptAssets, toPosixRelative } from "@barefootjs/vite";
6
6
 
7
7
  // ../jsx/src/compiler.ts
8
- import ts24 from "typescript";
8
+ import ts25 from "typescript";
9
9
 
10
10
  // ../jsx/src/analyzer.ts
11
11
  import ts9 from "typescript";
@@ -2157,6 +2157,15 @@ function isBooleanAttr(name) {
2157
2157
  function escapeHtml(text) {
2158
2158
  return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
2159
2159
  }
2160
+ // ../shared/src/jsx-children-prop.ts
2161
+ function resolveJsxChildrenProp(props) {
2162
+ const prop = props.find((p) => p.name === "children");
2163
+ if (!prop)
2164
+ return [];
2165
+ if (prop.value.kind !== "jsx-children")
2166
+ return [];
2167
+ return prop.value.children ?? [];
2168
+ }
2160
2169
  // ../jsx/src/ir-to-client-js/csr-substitute.ts
2161
2170
  import ts4 from "typescript";
2162
2171
  function extractFreeIdentifiersFromText(text) {
@@ -3203,11 +3212,14 @@ var KEYWORDS_AND_GLOBALS = new Set([
3203
3212
  // ../jsx/src/ir-to-client-js/walk-prop-accesses.ts
3204
3213
  import ts14 from "typescript";
3205
3214
 
3215
+ // ../jsx/src/ir-to-client-js/imports.ts
3216
+ import ts16 from "typescript";
3217
+
3206
3218
  // ../jsx/src/value-references.ts
3207
3219
  import ts15 from "typescript";
3208
3220
 
3209
3221
  // ../jsx/src/relocate.ts
3210
- import ts16 from "typescript";
3222
+ import ts17 from "typescript";
3211
3223
 
3212
3224
  // ../jsx/src/lowering-registry.ts
3213
3225
  var plugins = [];
@@ -3403,10 +3415,10 @@ function formatDateLocalNames(metadata) {
3403
3415
  }
3404
3416
 
3405
3417
  // ../jsx/src/ir-to-client-js/prune-unused-prop-extractions.ts
3406
- import ts17 from "typescript";
3418
+ import ts18 from "typescript";
3407
3419
 
3408
3420
  // ../jsx/src/ir-to-client-js/control-flow/plan/lazy-preamble.ts
3409
- import ts18 from "typescript";
3421
+ import ts19 from "typescript";
3410
3422
  var NO_PREAMBLE = {
3411
3423
  lazySafe: true,
3412
3424
  facts: { declaredNames: new Set, freeNames: new Set }
@@ -3456,7 +3468,7 @@ var INERT_BINDING_GLOBALS = new Set([
3456
3468
  ]);
3457
3469
 
3458
3470
  // ../jsx/src/ir-to-client-js/emit-reactive.ts
3459
- import ts19 from "typescript";
3471
+ import ts20 from "typescript";
3460
3472
 
3461
3473
  // ../jsx/src/ir-to-client-js/control-flow/stringify/event-delegation.ts
3462
3474
  var NON_BUBBLING_EVENTS = new Set([
@@ -3471,7 +3483,7 @@ var NON_BUBBLING_EVENTS = new Set([
3471
3483
  ]);
3472
3484
 
3473
3485
  // ../jsx/src/ir-to-client-js/rewrite-props-object.ts
3474
- import ts20 from "typescript";
3486
+ import ts21 from "typescript";
3475
3487
 
3476
3488
  // ../jsx/src/ir-to-client-js/source-map.ts
3477
3489
  var BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
@@ -3562,15 +3574,15 @@ class SourceMapGenerator {
3562
3574
  }
3563
3575
 
3564
3576
  // ../jsx/src/preprocess-inline-jsx-callbacks.ts
3565
- import ts21 from "typescript";
3577
+ import ts22 from "typescript";
3566
3578
 
3567
3579
  // ../jsx/src/ssr-defaults.ts
3568
- import ts22 from "typescript";
3580
+ import ts23 from "typescript";
3569
3581
  var UNRESOLVED = Symbol("unresolved");
3570
3582
  var NO_RETURN = Symbol("no-return");
3571
3583
 
3572
3584
  // ../jsx/src/augment-inherited-props.ts
3573
- import ts23 from "typescript";
3585
+ import ts24 from "typescript";
3574
3586
  function collectContextConsumers(metadata) {
3575
3587
  const constants = metadata.localConstants ?? [];
3576
3588
  const contextDefaults = new Map;
@@ -3602,47 +3614,47 @@ function collectContextConsumers(metadata) {
3602
3614
  }
3603
3615
  function parseUseContextArg(source) {
3604
3616
  const expr = parseSingleExpression(source);
3605
- if (!expr || !ts23.isCallExpression(expr))
3617
+ if (!expr || !ts24.isCallExpression(expr))
3606
3618
  return null;
3607
- if (!ts23.isIdentifier(expr.expression) || expr.expression.text !== "useContext")
3619
+ if (!ts24.isIdentifier(expr.expression) || expr.expression.text !== "useContext")
3608
3620
  return null;
3609
3621
  if (expr.arguments.length !== 1)
3610
3622
  return null;
3611
3623
  const arg = expr.arguments[0];
3612
- return ts23.isIdentifier(arg) ? arg.text : null;
3624
+ return ts24.isIdentifier(arg) ? arg.text : null;
3613
3625
  }
3614
3626
  function parseCreateContextDefault(source) {
3615
3627
  const expr = parseSingleExpression(source);
3616
- if (!expr || !ts23.isCallExpression(expr))
3628
+ if (!expr || !ts24.isCallExpression(expr))
3617
3629
  return null;
3618
3630
  if (expr.arguments.length === 0)
3619
3631
  return null;
3620
3632
  const arg = expr.arguments[0];
3621
- if (ts23.isStringLiteral(arg) || ts23.isNoSubstitutionTemplateLiteral(arg))
3633
+ if (ts24.isStringLiteral(arg) || ts24.isNoSubstitutionTemplateLiteral(arg))
3622
3634
  return arg.text;
3623
- if (ts23.isNumericLiteral(arg))
3635
+ if (ts24.isNumericLiteral(arg))
3624
3636
  return Number(arg.text);
3625
- if (arg.kind === ts23.SyntaxKind.TrueKeyword)
3637
+ if (arg.kind === ts24.SyntaxKind.TrueKeyword)
3626
3638
  return true;
3627
- if (arg.kind === ts23.SyntaxKind.FalseKeyword)
3639
+ if (arg.kind === ts24.SyntaxKind.FalseKeyword)
3628
3640
  return false;
3629
3641
  return null;
3630
3642
  }
3631
3643
  function isObjectLiteralCreateContextDefault(source) {
3632
3644
  const expr = parseSingleExpression(source);
3633
- if (!expr || !ts23.isCallExpression(expr))
3645
+ if (!expr || !ts24.isCallExpression(expr))
3634
3646
  return false;
3635
3647
  if (expr.arguments.length === 0)
3636
3648
  return false;
3637
- return ts23.isObjectLiteralExpression(expr.arguments[0]);
3649
+ return ts24.isObjectLiteralExpression(expr.arguments[0]);
3638
3650
  }
3639
3651
  function parseSingleExpression(source) {
3640
- const sf = ts23.createSourceFile("__ctx.ts", `(${source})`, ts23.ScriptTarget.Latest, false);
3652
+ const sf = ts24.createSourceFile("__ctx.ts", `(${source})`, ts24.ScriptTarget.Latest, false);
3641
3653
  const stmt = sf.statements[0];
3642
- if (!stmt || !ts23.isExpressionStatement(stmt))
3654
+ if (!stmt || !ts24.isExpressionStatement(stmt))
3643
3655
  return null;
3644
3656
  let e = stmt.expression;
3645
- while (ts23.isParenthesizedExpression(e))
3657
+ while (ts24.isParenthesizedExpression(e))
3646
3658
  e = e.expression;
3647
3659
  return e;
3648
3660
  }
@@ -3667,25 +3679,25 @@ function augmentInheritedPropAccesses(ir) {
3667
3679
  const pinCoalesceLiterals = (s) => {
3668
3680
  if (!s || !s.includes(propsObj))
3669
3681
  return;
3670
- const sf = ts23.createSourceFile("__aug.ts", `(${s})`, ts23.ScriptTarget.Latest, false);
3682
+ const sf = ts24.createSourceFile("__aug.ts", `(${s})`, ts24.ScriptTarget.Latest, false);
3671
3683
  const visit = (n) => {
3672
- if (ts23.isBinaryExpression(n) && (n.operatorToken.kind === ts23.SyntaxKind.QuestionQuestionToken || n.operatorToken.kind === ts23.SyntaxKind.BarBarToken)) {
3684
+ if (ts24.isBinaryExpression(n) && (n.operatorToken.kind === ts24.SyntaxKind.QuestionQuestionToken || n.operatorToken.kind === ts24.SyntaxKind.BarBarToken)) {
3673
3685
  let left = n.left;
3674
- while (ts23.isParenthesizedExpression(left))
3686
+ while (ts24.isParenthesizedExpression(left))
3675
3687
  left = left.expression;
3676
- if (ts23.isPropertyAccessExpression(left) && ts23.isIdentifier(left.expression) && left.expression.text === propsObj) {
3688
+ if (ts24.isPropertyAccessExpression(left) && ts24.isIdentifier(left.expression) && left.expression.text === propsObj) {
3677
3689
  const name = left.name.text;
3678
3690
  let right = n.right;
3679
- while (ts23.isParenthesizedExpression(right))
3691
+ while (ts24.isParenthesizedExpression(right))
3680
3692
  right = right.expression;
3681
- if (ts23.isPrefixUnaryExpression(right))
3693
+ if (ts24.isPrefixUnaryExpression(right))
3682
3694
  right = right.operand;
3683
- const kind = ts23.isNumericLiteral(right) ? "number" : right.kind === ts23.SyntaxKind.TrueKeyword || right.kind === ts23.SyntaxKind.FalseKeyword ? "boolean" : ts23.isStringLiteralLike(right) ? "string" : null;
3695
+ const kind = ts24.isNumericLiteral(right) ? "number" : right.kind === ts24.SyntaxKind.TrueKeyword || right.kind === ts24.SyntaxKind.FalseKeyword ? "boolean" : ts24.isStringLiteralLike(right) ? "string" : null;
3684
3696
  if (kind && !coalesceLiteralTypes.has(name))
3685
3697
  coalesceLiteralTypes.set(name, kind);
3686
3698
  }
3687
3699
  }
3688
- ts23.forEachChild(n, visit);
3700
+ ts24.forEachChild(n, visit);
3689
3701
  };
3690
3702
  visit(sf);
3691
3703
  };
@@ -3796,33 +3808,33 @@ function augmentInheritedPropAccesses(ir) {
3796
3808
  }
3797
3809
  }
3798
3810
  function parseStaticStringConst(source) {
3799
- const sf = ts23.createSourceFile("__const.ts", `const __x = (${source});`, ts23.ScriptTarget.Latest, false);
3811
+ const sf = ts24.createSourceFile("__const.ts", `const __x = (${source});`, ts24.ScriptTarget.Latest, false);
3800
3812
  const stmt = sf.statements[0];
3801
- if (!stmt || !ts23.isVariableStatement(stmt))
3813
+ if (!stmt || !ts24.isVariableStatement(stmt))
3802
3814
  return null;
3803
3815
  let init = stmt.declarationList.declarations[0]?.initializer;
3804
- while (init && ts23.isParenthesizedExpression(init))
3816
+ while (init && ts24.isParenthesizedExpression(init))
3805
3817
  init = init.expression;
3806
3818
  if (!init)
3807
3819
  return null;
3808
- if (ts23.isStringLiteral(init) || ts23.isNoSubstitutionTemplateLiteral(init)) {
3820
+ if (ts24.isStringLiteral(init) || ts24.isNoSubstitutionTemplateLiteral(init)) {
3809
3821
  return init.text;
3810
3822
  }
3811
3823
  return evalStringArrayJoin(source);
3812
3824
  }
3813
3825
  function evalTemplateOfStringConsts(source, resolved) {
3814
- const sf = ts23.createSourceFile("__const.ts", `const __x = (${source});`, ts23.ScriptTarget.Latest, false);
3826
+ const sf = ts24.createSourceFile("__const.ts", `const __x = (${source});`, ts24.ScriptTarget.Latest, false);
3815
3827
  const stmt = sf.statements[0];
3816
- if (!stmt || !ts23.isVariableStatement(stmt))
3828
+ if (!stmt || !ts24.isVariableStatement(stmt))
3817
3829
  return null;
3818
3830
  let init = stmt.declarationList.declarations[0]?.initializer;
3819
- while (init && ts23.isParenthesizedExpression(init))
3831
+ while (init && ts24.isParenthesizedExpression(init))
3820
3832
  init = init.expression;
3821
- if (!init || !ts23.isTemplateExpression(init))
3833
+ if (!init || !ts24.isTemplateExpression(init))
3822
3834
  return null;
3823
3835
  let out = init.head.text;
3824
3836
  for (const span of init.templateSpans) {
3825
- if (!ts23.isIdentifier(span.expression))
3837
+ if (!ts24.isIdentifier(span.expression))
3826
3838
  return null;
3827
3839
  const value = resolved.get(span.expression.text);
3828
3840
  if (value === undefined)
@@ -3850,28 +3862,28 @@ function collectModuleStringConsts(constants) {
3850
3862
  return map;
3851
3863
  }
3852
3864
  function evalStringArrayJoin(source) {
3853
- const sf = ts23.createSourceFile("__join.ts", `const __x = (${source});`, ts23.ScriptTarget.Latest, false);
3865
+ const sf = ts24.createSourceFile("__join.ts", `const __x = (${source});`, ts24.ScriptTarget.Latest, false);
3854
3866
  const stmt = sf.statements[0];
3855
- if (!stmt || !ts23.isVariableStatement(stmt))
3867
+ if (!stmt || !ts24.isVariableStatement(stmt))
3856
3868
  return null;
3857
3869
  let node = stmt.declarationList.declarations[0]?.initializer;
3858
- while (node && ts23.isParenthesizedExpression(node))
3870
+ while (node && ts24.isParenthesizedExpression(node))
3859
3871
  node = node.expression;
3860
- if (!node || !ts23.isCallExpression(node))
3872
+ if (!node || !ts24.isCallExpression(node))
3861
3873
  return null;
3862
3874
  const callee = node.expression;
3863
- if (!ts23.isPropertyAccessExpression(callee))
3875
+ if (!ts24.isPropertyAccessExpression(callee))
3864
3876
  return null;
3865
3877
  if (callee.name.text !== "join")
3866
3878
  return null;
3867
3879
  let recv = callee.expression;
3868
- while (ts23.isParenthesizedExpression(recv))
3880
+ while (ts24.isParenthesizedExpression(recv))
3869
3881
  recv = recv.expression;
3870
- if (!ts23.isArrayLiteralExpression(recv))
3882
+ if (!ts24.isArrayLiteralExpression(recv))
3871
3883
  return null;
3872
3884
  const parts = [];
3873
3885
  for (const el of recv.elements) {
3874
- if (ts23.isStringLiteral(el) || ts23.isNoSubstitutionTemplateLiteral(el)) {
3886
+ if (ts24.isStringLiteral(el) || ts24.isNoSubstitutionTemplateLiteral(el)) {
3875
3887
  parts.push(el.text);
3876
3888
  } else {
3877
3889
  return null;
@@ -3880,7 +3892,7 @@ function evalStringArrayJoin(source) {
3880
3892
  let sep = ",";
3881
3893
  if (node.arguments.length >= 1) {
3882
3894
  const arg = node.arguments[0];
3883
- if (ts23.isStringLiteral(arg) || ts23.isNoSubstitutionTemplateLiteral(arg))
3895
+ if (ts24.isStringLiteral(arg) || ts24.isNoSubstitutionTemplateLiteral(arg))
3884
3896
  sep = arg.text;
3885
3897
  else
3886
3898
  return null;
@@ -3888,11 +3900,11 @@ function evalStringArrayJoin(source) {
3888
3900
  return parts.join(sep);
3889
3901
  }
3890
3902
  function parseRecordIndexAccess(val, localConstants, propsParams, resolveKey) {
3891
- if (!ts23.isElementAccessExpression(val))
3903
+ if (!ts24.isElementAccessExpression(val))
3892
3904
  return null;
3893
3905
  const obj = val.expression;
3894
3906
  const arg = val.argumentExpression;
3895
- if (!ts23.isIdentifier(obj) || !ts23.isIdentifier(arg))
3907
+ if (!ts24.isIdentifier(obj) || !ts24.isIdentifier(arg))
3896
3908
  return null;
3897
3909
  let indexPropName;
3898
3910
  let defaultKey;
@@ -3908,35 +3920,35 @@ function parseRecordIndexAccess(val, localConstants, propsParams, resolveKey) {
3908
3920
  const constInfo = localConstants.find((c) => c.name === obj.text && c.isModule);
3909
3921
  if (constInfo?.value === undefined)
3910
3922
  return null;
3911
- const sf = ts23.createSourceFile("__rec.ts", `(${constInfo.value})`, ts23.ScriptTarget.Latest, true);
3923
+ const sf = ts24.createSourceFile("__rec.ts", `(${constInfo.value})`, ts24.ScriptTarget.Latest, true);
3912
3924
  if (sf.statements.length !== 1)
3913
3925
  return null;
3914
3926
  const stmt = sf.statements[0];
3915
- if (!ts23.isExpressionStatement(stmt))
3927
+ if (!ts24.isExpressionStatement(stmt))
3916
3928
  return null;
3917
3929
  let parsed = stmt.expression;
3918
- while (ts23.isParenthesizedExpression(parsed))
3930
+ while (ts24.isParenthesizedExpression(parsed))
3919
3931
  parsed = parsed.expression;
3920
- if (!ts23.isObjectLiteralExpression(parsed))
3932
+ if (!ts24.isObjectLiteralExpression(parsed))
3921
3933
  return null;
3922
3934
  const entries = [];
3923
3935
  for (const prop of parsed.properties) {
3924
- if (!ts23.isPropertyAssignment(prop))
3936
+ if (!ts24.isPropertyAssignment(prop))
3925
3937
  return null;
3926
3938
  let key;
3927
- if (ts23.isIdentifier(prop.name)) {
3939
+ if (ts24.isIdentifier(prop.name)) {
3928
3940
  key = prop.name.text;
3929
- } else if (ts23.isStringLiteral(prop.name) || ts23.isNoSubstitutionTemplateLiteral(prop.name)) {
3941
+ } else if (ts24.isStringLiteral(prop.name) || ts24.isNoSubstitutionTemplateLiteral(prop.name)) {
3930
3942
  key = prop.name.text;
3931
3943
  } else {
3932
3944
  return null;
3933
3945
  }
3934
3946
  let v = prop.initializer;
3935
- while (ts23.isParenthesizedExpression(v))
3947
+ while (ts24.isParenthesizedExpression(v))
3936
3948
  v = v.expression;
3937
- if (ts23.isNumericLiteral(v)) {
3949
+ if (ts24.isNumericLiteral(v)) {
3938
3950
  entries.push({ key, value: { kind: "number", text: v.text } });
3939
- } else if (ts23.isStringLiteral(v) || ts23.isNoSubstitutionTemplateLiteral(v)) {
3951
+ } else if (ts24.isStringLiteral(v) || ts24.isNoSubstitutionTemplateLiteral(v)) {
3940
3952
  entries.push({ key, value: { kind: "string", text: v.text } });
3941
3953
  } else {
3942
3954
  return null;
@@ -4025,7 +4037,7 @@ function computeSsrSeedPlan(metadata) {
4025
4037
  // ../jsx/src/rich-type-refusal.ts
4026
4038
  var EMPTY_BINDINGS2 = new Map;
4027
4039
  // ../jsx/src/shared-program.ts
4028
- import ts25 from "typescript";
4040
+ import ts26 from "typescript";
4029
4041
  // ../jsx/src/adapters/interface.ts
4030
4042
  class BaseAdapter {
4031
4043
  renderChildren(children) {
@@ -4307,7 +4319,7 @@ class JsxAdapter extends BaseAdapter {
4307
4319
  }
4308
4320
 
4309
4321
  // ../jsx/src/adapters/template-imports.ts
4310
- import ts26 from "typescript";
4322
+ import ts27 from "typescript";
4311
4323
  var CLIENT_PACKAGE_SOURCES = new Set([
4312
4324
  "@barefootjs/client",
4313
4325
  "@barefootjs/client/runtime"
@@ -5080,7 +5092,7 @@ function dangerousInnerHtmlDiagnostic(expr, loc, reason) {
5080
5092
  };
5081
5093
  }
5082
5094
  // ../jsx/src/combine-client-js.ts
5083
- import ts27 from "typescript";
5095
+ import ts28 from "typescript";
5084
5096
  // ../jsx/src/loop-destructure.ts
5085
5097
  function isLowerableLoopDestructure(loop) {
5086
5098
  const bindings = loop.paramBindings;
@@ -5220,9 +5232,9 @@ function escapeRe(s) {
5220
5232
  return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
5221
5233
  }
5222
5234
  // ../jsx/src/debug.ts
5223
- import ts28 from "typescript";
5224
- // ../jsx/src/profiler.ts
5225
5235
  import ts29 from "typescript";
5236
+ // ../jsx/src/profiler.ts
5237
+ import ts30 from "typescript";
5226
5238
 
5227
5239
  // ../jsx/src/index.ts
5228
5240
  registerBuiltinLoweringPlugins();
@@ -5478,31 +5490,6 @@ function goLiteral(value) {
5478
5490
  return `"${value}"`;
5479
5491
  }
5480
5492
 
5481
- // src/adapter/lib/ir-scope.ts
5482
- function collectRootScopeNodes(node) {
5483
- const out = new Set;
5484
- const visit = (n) => {
5485
- if (!n)
5486
- return;
5487
- if (n.type === "element") {
5488
- out.add(n);
5489
- return;
5490
- }
5491
- if (n.type === "if-statement") {
5492
- const s = n;
5493
- visit(s.consequent);
5494
- visit(s.alternate);
5495
- return;
5496
- }
5497
- if (n.type === "fragment") {
5498
- for (const c of n.children)
5499
- visit(c);
5500
- }
5501
- };
5502
- visit(node);
5503
- return out;
5504
- }
5505
-
5506
5493
  // src/adapter/lib/constants.ts
5507
5494
  var GO_TEMPLATE_PRIMITIVES = {
5508
5495
  "JSON.stringify": { arity: 1, emit: (args) => `bf_json ${wrapGoArg(args[0])}` },
@@ -5544,7 +5531,6 @@ class CompileState {
5544
5531
  textConsumedPropNames = new Set;
5545
5532
  presenceCheckedPropNames = new Set;
5546
5533
  stringValueNames = new Set;
5547
- rootScopeNodes = new Set;
5548
5534
  memoBackedLoopSlice = new Map;
5549
5535
  usesHtmlTemplate = false;
5550
5536
  usesFmt = false;
@@ -6889,7 +6875,7 @@ function computeObjectMemoInitialValue(ctx, memo) {
6889
6875
  }
6890
6876
 
6891
6877
  // src/adapter/memo/template-interp.ts
6892
- import ts30 from "typescript";
6878
+ import ts31 from "typescript";
6893
6879
  function computeTemplateLiteralMemoInitialValue(ctx, memo, propsParams) {
6894
6880
  const localKeyBindings = new Map;
6895
6881
  let templateValue;
@@ -7528,7 +7514,7 @@ function collectPropsReadByCtorInit(body, propsObjectName, propNames) {
7528
7514
  }
7529
7515
 
7530
7516
  // src/adapter/spread/spread-codegen.ts
7531
- import ts31 from "typescript";
7517
+ import ts32 from "typescript";
7532
7518
  function collectSpreadSlots(ctx, node) {
7533
7519
  const result = [];
7534
7520
  collectSpreadSlotsRecursive(ctx, node, result);
@@ -7767,7 +7753,7 @@ function recordIndexAccessToGoMap(ctx, val, ir) {
7767
7753
  if (val.kind !== "index-access" || val.object.kind !== "identifier" || val.index.kind !== "identifier") {
7768
7754
  return null;
7769
7755
  }
7770
- const tsVal = ts31.factory.createElementAccessExpression(ts31.factory.createIdentifier(val.object.name), ts31.factory.createIdentifier(val.index.name));
7756
+ const tsVal = ts32.factory.createElementAccessExpression(ts32.factory.createIdentifier(val.object.name), ts32.factory.createIdentifier(val.index.name));
7771
7757
  const parsed = parseRecordIndexAccess(tsVal, ir.metadata.localConstants ?? [], ir.metadata.propsParams);
7772
7758
  if (!parsed)
7773
7759
  return null;
@@ -8086,7 +8072,6 @@ class GoTemplateAdapter extends BaseAdapter {
8086
8072
  inLoop = false;
8087
8073
  bakedStaticChildLoopCache = new Map;
8088
8074
  scope = BindingScope.EMPTY;
8089
- loopKeyDepthStack = [];
8090
8075
  loopScalarItemStack = [];
8091
8076
  loopWrapperStack = [];
8092
8077
  loopVarRefCount = new Map;
@@ -8153,7 +8138,6 @@ class GoTemplateAdapter extends BaseAdapter {
8153
8138
  const hasInteractivity = hasClientInteractivity(ir);
8154
8139
  const isRootComponent = ir.root.type === "component";
8155
8140
  const isIfStatement = ir.root.type === "if-statement";
8156
- this.state.rootScopeNodes = collectRootScopeNodes(ir.root);
8157
8141
  this.state.memoBackedLoopSlice = new Map;
8158
8142
  for (const nested of findNestedComponents(ir.root)) {
8159
8143
  const memoName = this.extractMemoNameFromLoopArray(nested.loopArray);
@@ -9592,13 +9576,6 @@ ${goFields.join(`
9592
9576
  }
9593
9577
  return out;
9594
9578
  }
9595
- jsxChildrenPropNodes(props) {
9596
- for (const p of props) {
9597
- if (p.value.kind === "jsx-children")
9598
- return p.value.children;
9599
- }
9600
- return [];
9601
- }
9602
9579
  extractHtmlChildren(children) {
9603
9580
  if (children.length === 0)
9604
9581
  return null;
@@ -9642,7 +9619,7 @@ ${goFields.join(`
9642
9619
  }
9643
9620
  if (comp.name !== "Portal" && !inLoop && comp.slotId) {
9644
9621
  const suffix = slotIdToFieldSuffix(comp.slotId);
9645
- const effectiveChildren = comp.children.length > 0 ? comp.children : this.jsxChildrenPropNodes(comp.props);
9622
+ const effectiveChildren = comp.children.length > 0 ? comp.children : resolveJsxChildrenProp(comp.props);
9646
9623
  result.push({
9647
9624
  name: comp.name,
9648
9625
  slotId: comp.slotId,
@@ -10083,8 +10060,14 @@ ${goFields.join(`
10083
10060
  if (element.needsScope) {
10084
10061
  hydrationAttrs += ` ${this.renderScopeMarker(".ScopeID")}`;
10085
10062
  }
10086
- if (this.state.rootScopeNodes.has(element) && element.needsScope || element.carriesDataKey && !this.bakingStaticChildren) {
10087
- hydrationAttrs += `{{if .BfDataKey}} data-key="{{.BfDataKey}}"{{end}}`;
10063
+ if (element.keyAttr) {
10064
+ if (element.keyAttr.value !== undefined) {
10065
+ const lowered = emitAttrValue({ kind: "expression", expr: element.keyAttr.value }, this.elementAttrEmitter, element.keyAttr.name);
10066
+ if (lowered)
10067
+ hydrationAttrs += ` ${lowered}`;
10068
+ } else if (!this.bakingStaticChildren) {
10069
+ hydrationAttrs += `{{if .BfDataKey}} data-key="{{.BfDataKey}}"{{end}}`;
10070
+ }
10088
10071
  }
10089
10072
  if (element.slotId) {
10090
10073
  hydrationAttrs += ` ${this.renderSlotMarker(element.slotId)}`;
@@ -11662,10 +11645,8 @@ ${goFields.join(`
11662
11645
  }
11663
11646
  this.loopScalarItemStack.push(this.scalarLiteralLoopGoType(loop.arrayParsed, loop.itemType) !== null);
11664
11647
  this.loopWrapperStack.push(!!loop.childComponent);
11665
- this.loopKeyDepthStack.push(loop.depth);
11666
11648
  const preambleAssignments = (loop.preamble?.declarations ?? []).map((d) => `{{$${d.name} := ${this.renderParsedExpr(d.valueParsed)}}}`).join("");
11667
11649
  const children = this.renderChildren(loop.children);
11668
- this.loopKeyDepthStack.pop();
11669
11650
  this.loopWrapperStack.pop();
11670
11651
  this.loopScalarItemStack.pop();
11671
11652
  const itemMarker = this.loopItemMarker(loop);
@@ -11706,7 +11687,6 @@ ${goFields.join(`
11706
11687
  const wasInLoopOuter = this.inLoop;
11707
11688
  this.inLoop = true;
11708
11689
  this.loopWrapperStack.push(false);
11709
- this.loopKeyDepthStack.push(loop.depth);
11710
11690
  this.loopScalarItemStack.push(this.scalarLiteralLoopGoType(loop.arrayParsed, loop.itemType) !== null);
11711
11691
  const prevScope = this.scope;
11712
11692
  this.scope = prevScope.enterLoopRow(loop);
@@ -11731,21 +11711,20 @@ ${goFields.join(`
11731
11711
  }
11732
11712
  this.scope = prevScope;
11733
11713
  this.loopScalarItemStack.pop();
11734
- this.loopKeyDepthStack.pop();
11735
11714
  this.loopWrapperStack.pop();
11736
11715
  this.inLoop = wasInLoopOuter;
11737
11716
  return `{{bfComment "loop:${loop.markerId}"}}${body}{{bfComment "/loop:${loop.markerId}"}}`;
11738
11717
  }
11739
11718
  loopItemMarker(loop) {
11740
11719
  if (loop.bodyIsMultiRoot)
11741
- return `{{bfComment "bf-loop-i"}}`;
11720
+ return `{{bfComment "loop-i"}}`;
11742
11721
  if (loop.bodyIsItemConditional && loop.key) {
11743
11722
  return `{{bfComment (printf "loop-i:%v" ${this.convertExpressionToGo(loop.key)})}}`;
11744
11723
  }
11745
11724
  return "";
11746
11725
  }
11747
11726
  queueDynamicChildrenDefine(comp) {
11748
- const effectiveChildren = comp.children.length > 0 ? comp.children : this.jsxChildrenPropNodes(comp.props);
11727
+ const effectiveChildren = comp.children.length > 0 ? comp.children : resolveJsxChildrenProp(comp.props);
11749
11728
  if (effectiveChildren.length === 0)
11750
11729
  return null;
11751
11730
  if (this.extractTextChildren(effectiveChildren) !== null)
@@ -11763,8 +11742,42 @@ ${goFields.join(`
11763
11742
  }
11764
11743
  return name;
11765
11744
  }
11745
+ queueDynamicPropDefine(comp) {
11746
+ const args = [];
11747
+ const childShape = this.childComponentShapes.get(comp.name);
11748
+ for (const prop of comp.props) {
11749
+ if (prop.value.kind !== "jsx-children" || prop.name === "children")
11750
+ continue;
11751
+ const children = prop.value.children;
11752
+ if (this.extractTextChildren(children) !== null)
11753
+ continue;
11754
+ if (this.extractHtmlChildren(children) !== null)
11755
+ continue;
11756
+ if (this.extractScopedHtmlChildren(children) !== null)
11757
+ continue;
11758
+ if (childShape?.restBagField && !childShape.paramNames.has(prop.name)) {
11759
+ this.state.errors.push({
11760
+ code: "BF101",
11761
+ severity: "error",
11762
+ 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`,
11763
+ loc: prop.loc
11764
+ });
11765
+ continue;
11766
+ }
11767
+ const name = `${this.state.componentName}__prop_${prop.name}_${comp.slotId}`;
11768
+ if (!this.state.pendingChildrenDefines.some((d) => d.name === name)) {
11769
+ this.state.pendingChildrenDefines.push({
11770
+ name,
11771
+ content: this.renderChildren(children)
11772
+ });
11773
+ }
11774
+ const fieldName = this.childPropFieldNames.get(comp.name)?.get(prop.name) ?? capitalizeFieldName(prop.name);
11775
+ args.push(`${JSON.stringify(fieldName)} (bf_tmpl ${JSON.stringify(name)} .)`);
11776
+ }
11777
+ return args.length > 0 ? args.join(" ") : null;
11778
+ }
11766
11779
  queueLoopBodyChildrenDefine(comp) {
11767
- const effectiveChildren = comp.children.length > 0 ? comp.children : this.jsxChildrenPropNodes(comp.props);
11780
+ const effectiveChildren = comp.children.length > 0 ? comp.children : resolveJsxChildrenProp(comp.props);
11768
11781
  if (effectiveChildren.length === 0)
11769
11782
  return null;
11770
11783
  if (this.extractTextChildren(effectiveChildren) !== null)
@@ -11810,7 +11823,9 @@ ${goFields.join(`
11810
11823
  } else if (comp.slotId) {
11811
11824
  const suffix = slotIdToFieldSuffix(comp.slotId);
11812
11825
  const childrenDefine = this.queueDynamicChildrenDefine(comp);
11813
- templateCall = childrenDefine ? `{{template "${comp.name}" (bf_with_children .${comp.name}${suffix} (bf_tmpl "${childrenDefine}" .))}}` : `{{template "${comp.name}" .${comp.name}${suffix}}}`;
11826
+ const propArgs = this.queueDynamicPropDefine(comp);
11827
+ 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}}}`;
11814
11829
  } else {
11815
11830
  templateCall = `{{template "${comp.name}" .${comp.name}}}`;
11816
11831
  }
@@ -11937,14 +11952,9 @@ ${children}`;
11937
11952
  continue;
11938
11953
  if (isDangerousInnerHtmlAttr(attr))
11939
11954
  continue;
11940
- let attrName;
11941
- if (attr.name === "className")
11942
- attrName = "class";
11943
- else if (attr.name === "key") {
11944
- const depth = this.loopKeyDepthStack.at(-1) ?? 0;
11945
- attrName = depth > 0 ? `data-key-${depth}` : "data-key";
11946
- } else
11947
- attrName = attr.name;
11955
+ if (attr.name === "key")
11956
+ continue;
11957
+ const attrName = attr.name === "className" ? "class" : attr.name;
11948
11958
  const lowered = emitAttrValue(attr.value, this.elementAttrEmitter, attrName);
11949
11959
  if (lowered)
11950
11960
  parts.push(lowered);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@barefootjs/go-template",
3
- "version": "0.33.2",
3
+ "version": "0.33.4",
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.33.2"
52
+ "@barefootjs/shared": "0.33.4"
53
53
  },
54
54
  "peerDependencies": {
55
55
  "@barefootjs/jsx": ">=0.2.0",
@@ -67,9 +67,9 @@
67
67
  },
68
68
  "devDependencies": {
69
69
  "@barefootjs/adapter-tests": "0.1.0",
70
- "@barefootjs/client": "0.33.2",
71
- "@barefootjs/jsx": "0.33.2",
72
- "@barefootjs/vite": "0.33.2",
70
+ "@barefootjs/client": "0.33.4",
71
+ "@barefootjs/jsx": "0.33.4",
72
+ "@barefootjs/vite": "0.33.4",
73
73
  "vite": "^6.0.0"
74
74
  }
75
75
  }
@@ -118,12 +118,15 @@ runAdapterConformanceTests({
118
118
  'todo-app',
119
119
  // (#1897) data-table no longer skipped — loop body children + wrapper
120
120
  // struct + block-body memo baking render correctly on Go.
121
- // Real-render divergence (see `render-divergences.ts` for the full
122
- // description): Go's real SSR output drops the `header` prop's
123
- // content entirely for this shape, so its rendered template has no
124
- // `^s0` marker for the IR's conditional to match against. Paired
125
- // with the `renderDivergences` entry, not an independent gap.
126
- 'jsx-element-prop-fragment-conditional',
121
+ // `jsx-element-prop-fragment-conditional` (#2703) no longer skipped
122
+ // renders correctly since named jsx-children props got the same
123
+ // `bf_with_props`/`bf_tmpl` dynamic-delivery route reserved `children`
124
+ // already had.
125
+ // #2805: this shape refuses with BF101 at compile time (see
126
+ // `conformance-pins.ts`) — `expectedDiagnostics` covers the diagnostic
127
+ // contract, and marker comparison can't apply to a fixture that
128
+ // produces no complete template.
129
+ 'jsx-element-prop-rest-bag-dynamic',
127
130
  ]),
128
131
  skipDataPoints: new Set<string>([
129
132
  // #2743: html/template's URL-context autoescape percent-encodes the