@barefootjs/jsx 0.28.1 → 0.30.0

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.
Files changed (101) hide show
  1. package/dist/adapters/child-scope.d.ts +17 -0
  2. package/dist/adapters/child-scope.d.ts.map +1 -0
  3. package/dist/adapters/loop-bound-names.d.ts.map +1 -1
  4. package/dist/analyzer-context.d.ts.map +1 -1
  5. package/dist/analyzer.d.ts.map +1 -1
  6. package/dist/index.d.ts +1 -0
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js +890 -357
  9. package/dist/ir-to-client-js/collect-elements.d.ts +5 -25
  10. package/dist/ir-to-client-js/collect-elements.d.ts.map +1 -1
  11. package/dist/ir-to-client-js/control-flow/plan/build-lazy-row.d.ts +66 -2
  12. package/dist/ir-to-client-js/control-flow/plan/build-lazy-row.d.ts.map +1 -1
  13. package/dist/ir-to-client-js/control-flow/plan/build-reactive-effects.d.ts.map +1 -1
  14. package/dist/ir-to-client-js/control-flow/plan/lazy-conditional.d.ts +92 -0
  15. package/dist/ir-to-client-js/control-flow/plan/lazy-conditional.d.ts.map +1 -0
  16. package/dist/ir-to-client-js/control-flow/plan/lazy-preamble.d.ts +134 -0
  17. package/dist/ir-to-client-js/control-flow/plan/lazy-preamble.d.ts.map +1 -0
  18. package/dist/ir-to-client-js/control-flow/plan/lazy-row-eligibility.d.ts +46 -11
  19. package/dist/ir-to-client-js/control-flow/plan/lazy-row-eligibility.d.ts.map +1 -1
  20. package/dist/ir-to-client-js/control-flow/plan/reactive-effects.d.ts +7 -0
  21. package/dist/ir-to-client-js/control-flow/plan/reactive-effects.d.ts.map +1 -1
  22. package/dist/ir-to-client-js/control-flow/stringify/composite-loop.d.ts.map +1 -1
  23. package/dist/ir-to-client-js/control-flow/stringify/lazy-row.d.ts.map +1 -1
  24. package/dist/ir-to-client-js/control-flow/stringify/template-parse.d.ts +14 -0
  25. package/dist/ir-to-client-js/control-flow/stringify/template-parse.d.ts.map +1 -1
  26. package/dist/ir-to-client-js/csr-substitute.d.ts.map +1 -1
  27. package/dist/ir-to-client-js/html-template.d.ts +2 -3
  28. package/dist/ir-to-client-js/html-template.d.ts.map +1 -1
  29. package/dist/ir-to-client-js/imports.d.ts +2 -2
  30. package/dist/ir-to-client-js/imports.d.ts.map +1 -1
  31. package/dist/ir-to-client-js/plan/declaration-emit.d.ts +6 -0
  32. package/dist/ir-to-client-js/plan/declaration-emit.d.ts.map +1 -1
  33. package/dist/ir-to-client-js/reactivity.d.ts +1 -10
  34. package/dist/ir-to-client-js/reactivity.d.ts.map +1 -1
  35. package/dist/ir-to-client-js/types.d.ts +12 -0
  36. package/dist/ir-to-client-js/types.d.ts.map +1 -1
  37. package/dist/jsx-to-ir.d.ts.map +1 -1
  38. package/dist/rich-type-evidence.d.ts.map +1 -1
  39. package/dist/ssr-defaults.d.ts.map +1 -1
  40. package/dist/to-locale-date-lowering.d.ts.map +1 -1
  41. package/dist/types.d.ts +78 -0
  42. package/dist/types.d.ts.map +1 -1
  43. package/dist/value-references.d.ts +17 -4
  44. package/dist/value-references.d.ts.map +1 -1
  45. package/package.json +2 -2
  46. package/src/__tests__/__snapshots__/doc-examples.test.ts.snap +6 -24
  47. package/src/__tests__/branch-loop-plain.test.ts +28 -45
  48. package/src/__tests__/csr-substitution-safety-divergence.test.ts +9 -3
  49. package/src/__tests__/csr-template-scope-soundness.test.ts +96 -0
  50. package/src/__tests__/early-return-branch-switch.test.ts +96 -0
  51. package/src/__tests__/form-control-value-ssr.test.ts +102 -0
  52. package/src/__tests__/ir-to-client-js/imports.test.ts +18 -0
  53. package/src/__tests__/lazy-conditional.test.ts +190 -0
  54. package/src/__tests__/lazy-preamble.test.ts +297 -0
  55. package/src/__tests__/lazy-row-eligibility.test.ts +97 -28
  56. package/src/__tests__/loop-item-root-scope.test.ts +213 -0
  57. package/src/__tests__/loop-row-creation-paths.test.ts +169 -0
  58. package/src/__tests__/map-multi-return-body.test.ts +30 -3
  59. package/src/__tests__/nested-loop-conditional.test.ts +27 -6
  60. package/src/__tests__/preamble-attr-reactivity.test.ts +217 -0
  61. package/src/__tests__/preamble-declarations.test.ts +207 -0
  62. package/src/__tests__/ssr-defaults.test.ts +44 -0
  63. package/src/__tests__/value-references.test.ts +88 -0
  64. package/src/adapters/child-scope.ts +22 -0
  65. package/src/adapters/loop-bound-names.ts +6 -0
  66. package/src/analyzer-context.ts +43 -0
  67. package/src/analyzer.ts +33 -3
  68. package/src/index.ts +1 -0
  69. package/src/ir-to-client-js/collect-elements.ts +51 -10
  70. package/src/ir-to-client-js/control-flow/plan/build-branch-loop.ts +1 -1
  71. package/src/ir-to-client-js/control-flow/plan/build-composite-loop.ts +2 -2
  72. package/src/ir-to-client-js/control-flow/plan/build-event-delegation.ts +3 -3
  73. package/src/ir-to-client-js/control-flow/plan/build-inner-loop.ts +2 -2
  74. package/src/ir-to-client-js/control-flow/plan/build-lazy-row.ts +147 -5
  75. package/src/ir-to-client-js/control-flow/plan/build-loop.ts +2 -2
  76. package/src/ir-to-client-js/control-flow/plan/build-reactive-effects.ts +1 -0
  77. package/src/ir-to-client-js/control-flow/plan/lazy-conditional.ts +151 -0
  78. package/src/ir-to-client-js/control-flow/plan/lazy-preamble.ts +287 -0
  79. package/src/ir-to-client-js/control-flow/plan/lazy-row-eligibility.ts +85 -22
  80. package/src/ir-to-client-js/control-flow/plan/reactive-effects.ts +7 -0
  81. package/src/ir-to-client-js/control-flow/stringify/composite-loop.ts +4 -0
  82. package/src/ir-to-client-js/control-flow/stringify/lazy-row.ts +133 -35
  83. package/src/ir-to-client-js/control-flow/stringify/reactive-effects.ts +24 -4
  84. package/src/ir-to-client-js/control-flow/stringify/template-parse.ts +23 -4
  85. package/src/ir-to-client-js/csr-substitute.ts +6 -1
  86. package/src/ir-to-client-js/emit-registration.ts +1 -1
  87. package/src/ir-to-client-js/html-template.ts +51 -40
  88. package/src/ir-to-client-js/imports.ts +5 -0
  89. package/src/ir-to-client-js/index.ts +1 -1
  90. package/src/ir-to-client-js/plan/build-declaration-emit.ts +2 -0
  91. package/src/ir-to-client-js/plan/build-static-array-child-init.ts +1 -1
  92. package/src/ir-to-client-js/plan/declaration-emit.ts +6 -0
  93. package/src/ir-to-client-js/reactivity.ts +25 -0
  94. package/src/ir-to-client-js/stringify/declaration-emit.ts +9 -4
  95. package/src/ir-to-client-js/types.ts +12 -0
  96. package/src/jsx-to-ir.ts +400 -24
  97. package/src/rich-type-evidence.ts +6 -7
  98. package/src/ssr-defaults.ts +7 -2
  99. package/src/to-locale-date-lowering.ts +8 -2
  100. package/src/types.ts +80 -0
  101. package/src/value-references.ts +26 -4
package/dist/index.js CHANGED
@@ -3073,7 +3073,7 @@ function buildSignalMemoEnv(signals, memos, propsObjectName) {
3073
3073
  for (const m of memos) {
3074
3074
  substitutions.set(m.name, {
3075
3075
  kind: "call",
3076
- replacement: extractMemoBodyExpr(m.computation),
3076
+ replacement: extractMemoBodyExpr(m.templateComputation ?? m.computation),
3077
3077
  freeIdentifiers: m.computationFreeIdentifiers ?? new Set
3078
3078
  });
3079
3079
  }
@@ -3091,6 +3091,13 @@ function normalizeSignalInitial(signal, propsObjectName) {
3091
3091
 
3092
3092
  // src/ir-to-client-js/html-template.ts
3093
3093
  import { BF_PARENT_SCOPE_PLACEHOLDER, BF_SCOPE, escapeHtml } from "@barefootjs/shared";
3094
+
3095
+ // src/adapters/child-scope.ts
3096
+ function derivesScopeFromSlot(comp) {
3097
+ return comp.slotId != null && comp.loopItemRoot !== true;
3098
+ }
3099
+
3100
+ // src/ir-to-client-js/html-template.ts
3094
3101
  function createStringProtector() {
3095
3102
  const strings = [];
3096
3103
  const protect = (s) => {
@@ -3423,7 +3430,7 @@ function renderFlatMapClientBody(cb, restSpreadNames) {
3423
3430
  rawLeaf: true,
3424
3431
  renderLeaf: (ir) => {
3425
3432
  const key = flatMapLeafKeyExpr(ir);
3426
- const html = irToHtmlTemplate(stripLeafKeyAttr(ir), restSpreadNames, 1, undefined, undefined, true);
3433
+ const html = irToHtmlTemplate(stripLeafKeyAttr(ir), restSpreadNames, 1, undefined, undefined);
3427
3434
  return `({ k: ${key ?? "undefined"}, h: \`${html}\` })`;
3428
3435
  }
3429
3436
  });
@@ -3435,7 +3442,7 @@ function renderFlatMapProjectionClientBody(inner, restSpreadNames) {
3435
3442
  const chained = applyLoopChain(inner);
3436
3443
  const params = inner.index ? `(${inner.param}, ${inner.index})` : `(${inner.param})`;
3437
3444
  const key = inner.key ? `(${inner.key})` : "undefined";
3438
- const html = inner.children.map((c) => irToHtmlTemplate(escapeLeafTextExpressions(c), restSpreadNames, 1, undefined, undefined, true)).join("");
3445
+ const html = inner.children.map((c) => irToHtmlTemplate(escapeLeafTextExpressions(c), restSpreadNames, 1, undefined, undefined)).join("");
3439
3446
  return `${chained}.map(${params} => ({ k: ${key}, h: \`${html}\` }))`;
3440
3447
  }
3441
3448
  function escapeLeafTextExpressions(ir) {
@@ -3461,8 +3468,8 @@ function escapeLeafTextExpressions(ir) {
3461
3468
  return ir;
3462
3469
  }
3463
3470
  }
3464
- function irToHtmlTemplate(node, restSpreadNames, loopDepth = 0, loopParams, branchSlotsVar, insideLoop = false, inHoistedChildren = false) {
3465
- const recurse = (n) => irToHtmlTemplate(n, restSpreadNames, loopDepth, loopParams, branchSlotsVar, insideLoop, inHoistedChildren);
3471
+ function irToHtmlTemplate(node, restSpreadNames, loopDepth = 0, loopParams, branchSlotsVar, inHoistedChildren = false) {
3472
+ const recurse = (n) => irToHtmlTemplate(n, restSpreadNames, loopDepth, loopParams, branchSlotsVar, inHoistedChildren);
3466
3473
  const wrapExpr = (expr) => wrapExprWithLoopParams(expr, loopParams);
3467
3474
  const wrapInterpolation = (expr) => branchSlotsVar ? `__bfSlot(${expr}, ${branchSlotsVar})` : expr;
3468
3475
  switch (node.type) {
@@ -3493,7 +3500,7 @@ function irToHtmlTemplate(node, restSpreadNames, loopDepth = 0, loopParams, bran
3493
3500
  attrParts.push(`bf="${node.slotId}"`);
3494
3501
  }
3495
3502
  const attrs = attrParts.join(" ");
3496
- const childrenRecurse = (n) => irToHtmlTemplate(n, restSpreadNames, loopDepth, loopParams, branchSlotsVar, insideLoop, false);
3503
+ const childrenRecurse = (n) => irToHtmlTemplate(n, restSpreadNames, loopDepth, loopParams, branchSlotsVar, false);
3497
3504
  const children = dangerouslyHtmlChildren(node.attrs, (v) => wrapExpr(v.expr)) ?? node.children.map(childrenRecurse).join("");
3498
3505
  if (children || !VOID_ELEMENTS.has(node.tag)) {
3499
3506
  return `<${node.tag}${attrs ? " " + attrs : ""}>${children}</${node.tag}>`;
@@ -3530,12 +3537,12 @@ function irToHtmlTemplate(node, restSpreadNames, loopDepth = 0, loopParams, bran
3530
3537
  if (node.name === "Portal") {
3531
3538
  return node.children.map(recurse).join("");
3532
3539
  }
3533
- const propsEntries = node.props.filter((p) => p.name !== "..." && !p.name.startsWith("...") && p.name !== "key").filter((p) => !(p.name.startsWith("on") && p.name.length > 2 && p.name[2] === p.name[2].toUpperCase())).map((p) => {
3540
+ const propsEntries = node.props.filter((p) => p.name !== "..." && !p.name.startsWith("...") && p.name !== "key").filter((p) => p.name !== "ref" && !(p.name.startsWith("on") && p.name.length > 2 && p.name[2] === p.name[2].toUpperCase())).map((p) => {
3534
3541
  if (p.clientOnly)
3535
3542
  return null;
3536
3543
  switch (p.value.kind) {
3537
3544
  case "jsx-children": {
3538
- const hoistedRecurse = (n) => irToHtmlTemplate(n, restSpreadNames, loopDepth, loopParams, branchSlotsVar, insideLoop, true);
3545
+ const hoistedRecurse = (n) => irToHtmlTemplate(n, restSpreadNames, loopDepth, loopParams, branchSlotsVar, true);
3539
3546
  const childHtml = p.value.children.map((c) => hoistedRecurse(c)).join("");
3540
3547
  return `${quotePropName(p.name)}: \`${childHtml}\``;
3541
3548
  }
@@ -3548,7 +3555,7 @@ function irToHtmlTemplate(node, restSpreadNames, loopDepth = 0, loopParams, bran
3548
3555
  case "expression":
3549
3556
  case "template":
3550
3557
  case "spread": {
3551
- const expr = attrValueToString(p.value) ?? "undefined";
3558
+ const expr = attrValueToString(p.value, { useTemplate: true }) ?? "undefined";
3552
3559
  return `${quotePropName(p.name)}: ${expr}`;
3553
3560
  }
3554
3561
  }
@@ -3559,11 +3566,11 @@ function irToHtmlTemplate(node, restSpreadNames, loopDepth = 0, loopParams, bran
3559
3566
  const propsExpr = propsEntries.length > 0 ? `{${propsEntries.join(", ")}}` : "{}";
3560
3567
  const keyProp = node.props.find((p) => p.name === "key");
3561
3568
  const keyArg = keyProp ? `, ${attrValueToString(keyProp.value) ?? "undefined"}` : "";
3562
- const slotArg = !insideLoop && node.slotId ? `, '${node.slotId}'` : "";
3569
+ const slotArg = derivesScopeFromSlot(node) ? `, '${node.slotId}'` : "";
3563
3570
  return `\${renderChild('${nameForRegistryRef(node.name)}', ${propsExpr}${keyArg || (slotArg ? ", undefined" : "")}${slotArg})}`;
3564
3571
  }
3565
3572
  case "loop": {
3566
- const innerRecurse = (n) => irToHtmlTemplate(n, restSpreadNames, loopDepth + 1, loopParams, branchSlotsVar, insideLoop);
3573
+ const innerRecurse = (n) => irToHtmlTemplate(n, restSpreadNames, loopDepth + 1, loopParams, branchSlotsVar);
3567
3574
  let childTemplate = node.children.map(innerRecurse).join("");
3568
3575
  if (node.bodyIsItemConditional && node.key) {
3569
3576
  childTemplate = `${itemAnchorTemplate(node.key)}${childTemplate}`;
@@ -3576,11 +3583,11 @@ function irToHtmlTemplate(node, restSpreadNames, loopDepth = 0, loopParams, bran
3576
3583
  let mapExpr;
3577
3584
  if (node.flatMapCallback) {
3578
3585
  const body = renderPreamble(node.flatMapCallback, {
3579
- renderLeaf: (ir) => irToHtmlTemplate(stripLeafKeyAttr(ir), restSpreadNames, loopDepth + 1, loopParams, branchSlotsVar, insideLoop)
3586
+ renderLeaf: (ir) => irToHtmlTemplate(stripLeafKeyAttr(ir), restSpreadNames, loopDepth + 1, loopParams, branchSlotsVar)
3580
3587
  });
3581
3588
  mapExpr = `\${${wrappedArray}.flatMap(${node.flatMapCallback.params} => ${body}).join('')}`;
3582
3589
  } else if (node.preamble) {
3583
- const preamble = renderPreamble(node.preamble, { textVariant: "client", renderLeaf: (ir) => irToHtmlTemplate(ir, restSpreadNames, loopDepth + 1, loopParams, branchSlotsVar, insideLoop) });
3590
+ const preamble = renderPreamble(node.preamble, { textVariant: "client", renderLeaf: (ir) => irToHtmlTemplate(ir, restSpreadNames, loopDepth + 1, loopParams, branchSlotsVar) });
3584
3591
  mapExpr = `\${${wrappedArray}.${iterMethod}(${callbackParam} => { ${preamble} return \`${childTemplate}\` }).join('')}`;
3585
3592
  } else {
3586
3593
  mapExpr = `\${${wrappedArray}.${iterMethod}(${callbackParam} => \`${childTemplate}\`).join('')}`;
@@ -4085,7 +4092,7 @@ function irToComponentTemplateWithOpts(node, opts) {
4085
4092
  if (node.name === "Portal") {
4086
4093
  return node.children.map(recurse).join("");
4087
4094
  }
4088
- const propsEntries = node.props.filter((p) => p.name !== "..." && !p.name.startsWith("...") && p.name !== "key").filter((p) => !(p.name.startsWith("on") && p.name.length > 2 && p.name[2] === p.name[2].toUpperCase())).map((p) => {
4095
+ const propsEntries = node.props.filter((p) => p.name !== "..." && !p.name.startsWith("...") && p.name !== "key").filter((p) => p.name !== "ref" && !(p.name.startsWith("on") && p.name.length > 2 && p.name[2] === p.name[2].toUpperCase())).map((p) => {
4089
4096
  if (p.clientOnly)
4090
4097
  return null;
4091
4098
  switch (p.value.kind) {
@@ -4202,7 +4209,7 @@ function canGenerateStaticTemplate(node, propNames, inlinableConstants, unsafeLo
4202
4209
  return assertNever(node);
4203
4210
  }
4204
4211
  }
4205
- function generateCsrTemplate(node, inlinableConstants, ctx, insideLoop, restSpreadNames, propsObjectName, unsafeLocalNames, deferredChildSlots) {
4212
+ function generateCsrTemplate(node, inlinableConstants, ctx, restSpreadNames, propsObjectName, unsafeLocalNames, deferredChildSlots) {
4206
4213
  const base = buildSignalMemoEnv(ctx.signals, ctx.memos, propsObjectName ?? null);
4207
4214
  const csrEnv = { substitutions: new Map(base.substitutions), propsObjectName: base.propsObjectName };
4208
4215
  if (inlinableConstants) {
@@ -4213,7 +4220,7 @@ function generateCsrTemplate(node, inlinableConstants, ctx, insideLoop, restSpre
4213
4220
  }
4214
4221
  }
4215
4222
  const effectiveUnsafeLocalNames = mergeCsrNullUnsafe(ctx, unsafeLocalNames);
4216
- return generateCsrTemplateWithOpts(node, { inlinableConstants, restSpreadNames, propsObjectName, csrEnv, insideLoop, unsafeLocalNames: effectiveUnsafeLocalNames, deferredChildSlots, loopDepth: -1 });
4223
+ return generateCsrTemplateWithOpts(node, { inlinableConstants, restSpreadNames, propsObjectName, csrEnv, unsafeLocalNames: effectiveUnsafeLocalNames, deferredChildSlots, loopDepth: -1 });
4217
4224
  }
4218
4225
  function mergeCsrNullUnsafe(ctx, unsafeLocalNames) {
4219
4226
  let merged = null;
@@ -4278,6 +4285,8 @@ function computeDeferredChildSlots(node, ctx, inlinableConstants, unsafeLocalNam
4278
4285
  const dropped = n.props.some((p) => {
4279
4286
  if (p.name === "..." || p.name.startsWith("...") || p.name === "key")
4280
4287
  return false;
4288
+ if (p.name === "ref")
4289
+ return false;
4281
4290
  if (p.name.startsWith("on") && p.name.length > 2 && p.name[2] === p.name[2].toUpperCase())
4282
4291
  return false;
4283
4292
  if (p.clientOnly)
@@ -4307,7 +4316,7 @@ function computeDeferredChildSlots(node, ctx, inlinableConstants, unsafeLocalNam
4307
4316
  return deferred;
4308
4317
  }
4309
4318
  function generateCsrTemplateWithOpts(node, opts) {
4310
- const { restSpreadNames, propsObjectName, csrEnv, insideLoop, unsafeLocalNames, loopDepth = 0 } = opts;
4319
+ const { restSpreadNames, propsObjectName, csrEnv, unsafeLocalNames, loopDepth = 0 } = opts;
4311
4320
  const env = csrEnv ?? { substitutions: new Map, propsObjectName: propsObjectName ?? null };
4312
4321
  const transformExpr = (expr, templateExpr) => {
4313
4322
  const source = templateExpr ?? expr;
@@ -4321,7 +4330,6 @@ function generateCsrTemplateWithOpts(node, opts) {
4321
4330
  };
4322
4331
  const recurse = (n) => generateCsrTemplateWithOpts(n, opts);
4323
4332
  const childrenRecurse = (n) => generateCsrTemplateWithOpts(n, { ...opts, inHoistedChildren: false });
4324
- const recurseInLoop = (n) => generateCsrTemplateWithOpts(n, { ...opts, insideLoop: true, loopDepth: loopDepth + 1, inHoistedChildren: false });
4325
4333
  switch (node.type) {
4326
4334
  case "element": {
4327
4335
  const mergeCtx = {
@@ -4414,7 +4422,7 @@ function generateCsrTemplateWithOpts(node, opts) {
4414
4422
  if (node.slotId && opts.deferredChildSlots?.has(node.slotId)) {
4415
4423
  return `<div ${DATA_BF_PH}="${node.slotId}"></div>`;
4416
4424
  }
4417
- const propsEntries = node.props.filter((p) => p.name !== "..." && !p.name.startsWith("...") && p.name !== "key").filter((p) => !(p.name.startsWith("on") && p.name.length > 2 && p.name[2] === p.name[2].toUpperCase())).map((p) => {
4425
+ const propsEntries = node.props.filter((p) => p.name !== "..." && !p.name.startsWith("...") && p.name !== "key").filter((p) => p.name !== "ref" && !(p.name.startsWith("on") && p.name.length > 2 && p.name[2] === p.name[2].toUpperCase())).map((p) => {
4418
4426
  if (p.clientOnly)
4419
4427
  return null;
4420
4428
  switch (p.value.kind) {
@@ -4452,7 +4460,7 @@ function generateCsrTemplateWithOpts(node, opts) {
4452
4460
  const propsExpr = propsEntries.length > 0 ? `{${propsEntries.join(", ")}}` : "{}";
4453
4461
  const keyProp = node.props.find((p) => p.name === "key");
4454
4462
  const keyArg = keyProp ? `, ${transformKeyValue(keyProp.value, transformExpr)}` : "";
4455
- const slotArg = !insideLoop && node.slotId ? `, '${node.slotId}'` : "";
4463
+ const slotArg = derivesScopeFromSlot(node) ? `, '${node.slotId}'` : "";
4456
4464
  return `\${renderChild('${nameForRegistryRef(node.name)}', ${propsExpr}${keyArg || (slotArg ? ", undefined" : "")}${slotArg})}`;
4457
4465
  }
4458
4466
  case "loop": {
@@ -4471,7 +4479,6 @@ function generateCsrTemplateWithOpts(node, opts) {
4471
4479
  };
4472
4480
  const recurseInLoopBody = (n) => generateCsrTemplateWithOpts(n, {
4473
4481
  ...opts,
4474
- insideLoop: true,
4475
4482
  loopDepth: loopDepth + 1,
4476
4483
  inHoistedChildren: false,
4477
4484
  loopBoundNames: boundHere,
@@ -4948,6 +4955,30 @@ function typeNodeToTypeInfo(typeNode, sourceFile, rawOf) {
4948
4955
  if (ts7.isArrayTypeNode(typeNode)) {
4949
4956
  return { kind: "array", raw, elementType: recurse(typeNode.elementType) };
4950
4957
  }
4958
+ if (ts7.isLiteralTypeNode(typeNode)) {
4959
+ const lit = typeNode.literal;
4960
+ if (ts7.isStringLiteral(lit) || ts7.isNoSubstitutionTemplateLiteral(lit)) {
4961
+ return { kind: "primitive", raw, primitive: "string", literalValue: lit.text };
4962
+ }
4963
+ if (ts7.isNumericLiteral(lit)) {
4964
+ return { kind: "primitive", raw, primitive: "number", literalValue: lit.text };
4965
+ }
4966
+ if (ts7.isPrefixUnaryExpression(lit) && lit.operator === ts7.SyntaxKind.MinusToken && ts7.isNumericLiteral(lit.operand)) {
4967
+ return { kind: "primitive", raw, primitive: "number", literalValue: `-${lit.operand.text}` };
4968
+ }
4969
+ if (lit.kind === ts7.SyntaxKind.TrueKeyword || lit.kind === ts7.SyntaxKind.FalseKeyword) {
4970
+ return {
4971
+ kind: "primitive",
4972
+ raw,
4973
+ primitive: "boolean",
4974
+ literalValue: lit.kind === ts7.SyntaxKind.TrueKeyword ? "true" : "false"
4975
+ };
4976
+ }
4977
+ if (lit.kind === ts7.SyntaxKind.NullKeyword) {
4978
+ return { kind: "primitive", raw, primitive: "null" };
4979
+ }
4980
+ return { kind: "unknown", raw };
4981
+ }
4951
4982
  if (ts7.isUnionTypeNode(typeNode)) {
4952
4983
  return { kind: "union", raw, unionTypes: typeNode.types.map(recurse) };
4953
4984
  }
@@ -5515,9 +5546,7 @@ function baseTypeName(raw) {
5515
5546
  return (idx === -1 ? raw : raw.slice(0, idx)).trim();
5516
5547
  }
5517
5548
  function isNullishArm(t) {
5518
- if (t.kind === "primitive" && (t.primitive === "null" || t.primitive === "undefined"))
5519
- return true;
5520
- return t.kind === "unknown" && (t.raw === "null" || t.raw === "undefined");
5549
+ return t.kind === "primitive" && (t.primitive === "null" || t.primitive === "undefined");
5521
5550
  }
5522
5551
  function stripUnion(type) {
5523
5552
  if (!type || type.kind !== "union" || !type.unionTypes)
@@ -6236,14 +6265,17 @@ function collectSignal(node, ctx) {
6236
6265
  const pattern = node.name;
6237
6266
  const callExpr = node.initializer;
6238
6267
  const elements = pattern.elements;
6239
- if (elements.length < 1 || elements.length > 2 || !ts8.isBindingElement(elements[0]) || !ts8.isIdentifier(elements[0].name)) {
6268
+ const getterElided = elements.length === 2 && ts8.isOmittedExpression(elements[0]);
6269
+ if (elements.length < 1 || elements.length > 2 || !getterElided && (!ts8.isBindingElement(elements[0]) || !ts8.isIdentifier(elements[0].name))) {
6240
6270
  return;
6241
6271
  }
6242
6272
  if (elements.length === 2 && (!ts8.isBindingElement(elements[1]) || !ts8.isIdentifier(elements[1].name))) {
6243
6273
  return;
6244
6274
  }
6245
- const getter = elements[0].name.text;
6246
6275
  const setter = elements.length === 2 && ts8.isBindingElement(elements[1]) && ts8.isIdentifier(elements[1].name) ? elements[1].name.text : null;
6276
+ if (getterElided && !setter)
6277
+ return;
6278
+ const getter = getterElided ? `__bfGet_${setter}` : elements[0].name.text;
6247
6279
  const initialValue = callExpr.arguments[0] ? ctx.getJS(callExpr.arguments[0]) : "";
6248
6280
  const typedInitialValue = callExpr.arguments[0] ? callExpr.arguments[0].getText(ctx.sourceFile) : undefined;
6249
6281
  let type = { kind: "unknown", raw: "unknown" };
@@ -6264,6 +6296,7 @@ function collectSignal(node, ctx) {
6264
6296
  ctx.signals.push({
6265
6297
  getter,
6266
6298
  setter,
6299
+ getterElided: getterElided || undefined,
6267
6300
  initialValue,
6268
6301
  typedInitialValue: typedInitialValue !== initialValue ? typedInitialValue : undefined,
6269
6302
  templateInitialValue,
@@ -6454,9 +6487,17 @@ function collectMemo(node, ctx) {
6454
6487
  const blockBody = arrowNode && ts8.isArrowFunction(arrowNode) && ts8.isBlock(arrowNode.body) ? arrowNode.body : undefined;
6455
6488
  const parsedBlock = blockBody ? parseBlockBodyTolerant(blockBody, ctx.sourceFile, (node2) => ctx.getJS(node2)) : undefined;
6456
6489
  const parsedBlockComplete = parsedBlock && blockBody ? parsedBlock.length === blockBody.statements.length : undefined;
6490
+ let templateComputation;
6491
+ if (!ctx.propsObjectName && callExpr.arguments[0]) {
6492
+ const propNames = new Set(ctx.propsParams.map((p) => p.name));
6493
+ if (propNames.size > 0) {
6494
+ templateComputation = rewriteBarePropRefs(computation, callExpr.arguments[0], propNames);
6495
+ }
6496
+ }
6457
6497
  ctx.memos.push({
6458
6498
  name,
6459
6499
  computation,
6500
+ templateComputation,
6460
6501
  parsedBlock,
6461
6502
  parsedBlockComplete,
6462
6503
  typedComputation: typedComputation !== computation ? typedComputation : undefined,
@@ -9677,8 +9718,10 @@ function deriveFormat(locale, probeOptions) {
9677
9718
  return { pattern, names };
9678
9719
  }
9679
9720
  function unionMemberLiteral(member) {
9680
- const m = /^'([^'\\]*)'$|^"([^"\\]*)"$/.exec(member.raw.trim());
9681
- return m ? m[1] ?? m[2] : null;
9721
+ if (member.kind === "primitive" && member.primitive === "string" && member.literalValue !== undefined) {
9722
+ return member.literalValue;
9723
+ }
9724
+ return null;
9682
9725
  }
9683
9726
  function resolveLocaleUnionMembers(locale, metadata) {
9684
9727
  let sourcePropName = null;
@@ -10284,6 +10327,13 @@ function jsxToIR(analyzer) {
10284
10327
  function buildIRRoot(analyzer) {
10285
10328
  if (analyzer.conditionalReturns.length > 0) {
10286
10329
  const ctx2 = createTransformContext(analyzer);
10330
+ const allReactiveNoLocals = analyzer.jsxReturn != null && analyzer.conditionalReturns.every((cr) => cr.scopeVariables.length === 0 && exprCallsReactiveGetters(cr.condition, ctx2));
10331
+ if (allReactiveNoLocals) {
10332
+ const chain = buildIfStatementChain(analyzer, ctx2, { asConditional: true });
10333
+ if (!chain)
10334
+ return null;
10335
+ return chain.type === "conditional" ? wrapInScopeElement(chain) : chain;
10336
+ }
10287
10337
  return buildIfStatementChain(analyzer, ctx2);
10288
10338
  }
10289
10339
  if (!analyzer.jsxReturn)
@@ -10439,11 +10489,52 @@ function transformJsxElement(node, ctx) {
10439
10489
  }
10440
10490
  return transformHtmlElement(node, ctx, tagName);
10441
10491
  }
10492
+ function lowerFormControlValueSsr(tagName, attrs, children) {
10493
+ if (tagName !== "textarea" && tagName !== "select")
10494
+ return;
10495
+ const valueAttr = attrs.find((a) => a.name === "value");
10496
+ if (!valueAttr || valueAttr.clientOnly || valueAttr.value.kind !== "expression")
10497
+ return;
10498
+ const { expr, templateExpr } = valueAttr.value;
10499
+ valueAttr.clientOnly = true;
10500
+ if (tagName === "textarea") {
10501
+ if (children.length > 0)
10502
+ return;
10503
+ children.push({
10504
+ type: "expression",
10505
+ expr,
10506
+ templateExpr: `escapeText(${templateExpr ?? expr})`,
10507
+ typeInfo: null,
10508
+ reactive: false,
10509
+ slotId: null,
10510
+ loc: valueAttr.loc,
10511
+ origin: { phase: "ssr", scope: "template", effect: "pure" }
10512
+ });
10513
+ return;
10514
+ }
10515
+ const selectedFor = (optValue) => AttrValueOf.expression(`(${expr}) === ${JSON.stringify(optValue)}`, templateExpr !== undefined ? { templateExpr: `(${templateExpr}) === ${JSON.stringify(optValue)}` } : undefined);
10516
+ const distribute = (nodes) => {
10517
+ for (const n of nodes) {
10518
+ if (n.type === "element" && n.tag === "option") {
10519
+ if (n.attrs.some((a) => a.name === "selected"))
10520
+ continue;
10521
+ const optValue = n.attrs.find((a) => a.name === "value");
10522
+ if (!optValue || optValue.value.kind !== "literal")
10523
+ continue;
10524
+ n.attrs.push({ name: "selected", value: selectedFor(optValue.value.value), loc: n.loc });
10525
+ } else if (n.type === "fragment" || n.type === "element" && n.tag === "optgroup") {
10526
+ distribute(n.children);
10527
+ }
10528
+ }
10529
+ };
10530
+ distribute(children);
10531
+ }
10442
10532
  function transformHtmlElement(node, ctx, tagName) {
10443
10533
  const { attrs, events, ref } = processAttributes(node.openingElement.attributes, ctx);
10444
10534
  const needsScope = ctx.isRoot;
10445
10535
  ctx.isRoot = false;
10446
10536
  const children = transformChildren(node.children, ctx);
10537
+ lowerFormControlValueSsr(tagName, attrs, children);
10447
10538
  const needsSlot = events.length > 0 || hasDynamicContent(children) || hasReactiveAttributes(attrs, ctx) || ref !== null;
10448
10539
  const slotId = needsSlot ? generateSlotId(ctx) : null;
10449
10540
  if (slotId) {
@@ -10475,6 +10566,8 @@ function transformSelfClosingElement(node, ctx) {
10475
10566
  return transformSelfClosingComponent(node, ctx, resolved ?? tagName);
10476
10567
  }
10477
10568
  const { attrs, events, ref } = processAttributes(node.attributes, ctx);
10569
+ const selfClosingChildren = [];
10570
+ lowerFormControlValueSsr(tagName, attrs, selfClosingChildren);
10478
10571
  const needsSlot = events.length > 0 || hasReactiveAttributes(attrs, ctx) || ref !== null;
10479
10572
  const slotId = needsSlot ? generateSlotId(ctx) : null;
10480
10573
  const needsScope = ctx.isRoot;
@@ -10485,7 +10578,7 @@ function transformSelfClosingElement(node, ctx) {
10485
10578
  attrs,
10486
10579
  events,
10487
10580
  ref,
10488
- children: [],
10581
+ children: selfClosingChildren,
10489
10582
  slotId,
10490
10583
  needsScope,
10491
10584
  loc: getSourceLocation(node, ctx.sourceFile, ctx.filePath)
@@ -11868,6 +11961,15 @@ function branchHasNoElement(node) {
11868
11961
  }
11869
11962
  return true;
11870
11963
  }
11964
+ function tagLoopItemRootComponents(nodes) {
11965
+ for (const node of nodes) {
11966
+ if (node.type === "component") {
11967
+ node.loopItemRoot = true;
11968
+ } else if (node.type === "conditional") {
11969
+ tagLoopItemRootComponents([node.whenTrue, node.whenFalse]);
11970
+ }
11971
+ }
11972
+ }
11871
11973
  function loopBodyItemConditional(children) {
11872
11974
  const real = children.filter((c) => !(c.type === "text" && typeof c.value === "string" && !c.value.trim()));
11873
11975
  if (real.length !== 1)
@@ -12105,9 +12207,9 @@ function transformMapCall(node, ctx, isClientOnly = false, method = "map") {
12105
12207
  const pre = multiReturn.preamble ?? [];
12106
12208
  if (pre.length > 0) {
12107
12209
  preamble = preambleFromValueStatements(pre, ctx);
12108
- if (!isClientOnly && !(ctx.analyzer.acceptsCallbackBody?.("map") ?? false)) {
12210
+ if (!preamble.declarations && !isClientOnly && !(ctx.analyzer.acceptsCallbackBody?.("map") ?? false)) {
12109
12211
  ctx.analyzer.errors.push(createError(ErrorCodes.UNSUPPORTED_JSX_PATTERN, loc, {
12110
- message: "A .map() callback body with a `const`/`let` preamble before its " + "branches cannot be lowered to a template: the loop-local binding " + "cannot be carried into a conditional branch on this backend.",
12212
+ message: "A .map() callback body with a preamble before its branches cannot be " + "lowered to a template: the preamble is not a sequence of value " + "declarations, so this backend has no per-row local to carry into the " + "branches.",
12111
12213
  suggestion: {
12112
12214
  message: "Add /* @client */ to evaluate this expression on the client only"
12113
12215
  }
@@ -12174,6 +12276,14 @@ function transformMapCall(node, ctx, isClientOnly = false, method = "map") {
12174
12276
  }
12175
12277
  if (valueStmts.length > 0) {
12176
12278
  preamble = preambleFromValueStatements(valueStmts, ctx);
12279
+ if (!preamble.declarations && !isClientOnly && !(ctx.analyzer.acceptsCallbackBody?.("map") ?? false)) {
12280
+ ctx.analyzer.errors.push(createError(ErrorCodes.UNSUPPORTED_JSX_PATTERN, getSourceLocation(body, ctx.sourceFile, ctx.filePath), {
12281
+ message: "A .map() callback preamble that is not a sequence of value " + "declarations cannot be lowered to a template: this backend can " + "declare a per-row local, but cannot run arbitrary statements per row.",
12282
+ suggestion: {
12283
+ message: "Add /* @client */ to evaluate this expression on the client only"
12284
+ }
12285
+ }));
12286
+ }
12177
12287
  }
12178
12288
  }
12179
12289
  }
@@ -12259,6 +12369,7 @@ function transformMapCall(node, ctx, isClientOnly = false, method = "map") {
12259
12369
  }));
12260
12370
  preamble = undefined;
12261
12371
  }
12372
+ tagLoopItemRootComponents(children);
12262
12373
  let childComponent;
12263
12374
  if (children.length === 1 && children[0].type === "component") {
12264
12375
  const comp = children[0];
@@ -12279,6 +12390,9 @@ function transformMapCall(node, ctx, isClientOnly = false, method = "map") {
12279
12390
  const isDirectPropArray = method !== "flatMap" && isArrayExprDirectPropRef(arrayExpr, ctx);
12280
12391
  const isStaticArray = !isSignalOrMemoArray(array, ctx) && !isDirectPropArray && !hasCalls && !objectIteration;
12281
12392
  const preambleRegions = preamble && !isStaticArray ? collectPreambleRegions(children, new Set(preamble.declaredNames), ctx) : undefined;
12393
+ if (preamble && !isStaticArray) {
12394
+ markPreambleAttrSlots(children, new Set(preamble.declaredNames), ctx);
12395
+ }
12282
12396
  const nestedComponents = collectNestedComponents(children).filter((c) => c.name !== childComponent?.name);
12283
12397
  return {
12284
12398
  type: "loop",
@@ -12503,6 +12617,52 @@ function collectPreambleRegions(nodes, declared, ctx) {
12503
12617
  visit2(nodes);
12504
12618
  return regions;
12505
12619
  }
12620
+ function markPreambleAttrSlots(nodes, declared, ctx) {
12621
+ const readsDeclared = (attr) => {
12622
+ if (attr.name === "key")
12623
+ return false;
12624
+ const value = attr.value;
12625
+ if (value.kind !== "expression" && value.kind !== "template")
12626
+ return false;
12627
+ const refs = attr.freeIdentifiers ?? extractFreeIdentifiersFromText(attrValueText(value));
12628
+ for (const r of refs)
12629
+ if (declared.has(r))
12630
+ return true;
12631
+ return false;
12632
+ };
12633
+ const visit2 = (list) => {
12634
+ for (const node of list) {
12635
+ switch (node.type) {
12636
+ case "element":
12637
+ if (!node.slotId && node.attrs.some(readsDeclared))
12638
+ node.slotId = generateSlotId(ctx);
12639
+ visit2(node.children);
12640
+ break;
12641
+ case "fragment":
12642
+ visit2(node.children);
12643
+ break;
12644
+ case "conditional":
12645
+ visit2([node.whenTrue, ...node.whenFalse ? [node.whenFalse] : []]);
12646
+ break;
12647
+ }
12648
+ }
12649
+ };
12650
+ visit2(nodes);
12651
+ }
12652
+ function attrValueText(value) {
12653
+ if (value.kind === "expression")
12654
+ return value.expr;
12655
+ if (value.kind !== "template")
12656
+ return "";
12657
+ const out = [];
12658
+ for (const p of value.parts) {
12659
+ if (p.type === "ternary")
12660
+ out.push(p.condition, p.whenTrue, p.whenFalse);
12661
+ else if (p.type === "lookup")
12662
+ out.push(p.key);
12663
+ }
12664
+ return out.join(" ");
12665
+ }
12506
12666
  function collectBindingNames(name, out) {
12507
12667
  if (ts11.isIdentifier(name)) {
12508
12668
  out.add(name.text);
@@ -12540,9 +12700,32 @@ function preambleFromValueStatements(statements, ctx) {
12540
12700
  segments: trimPreambleSegments(segments),
12541
12701
  ssrText: tsxSourceText(typedParts.join(" ")),
12542
12702
  declaredNames: [...declared],
12543
- builderNames: []
12703
+ builderNames: [],
12704
+ declarations: neutralPreambleDeclarations(statements, ctx) ?? undefined
12544
12705
  };
12545
12706
  }
12707
+ function neutralPreambleDeclarations(statements, ctx) {
12708
+ const out = [];
12709
+ for (const stmt of statements) {
12710
+ if (!ts11.isVariableStatement(stmt))
12711
+ return null;
12712
+ for (const decl of stmt.declarationList.declarations) {
12713
+ if (!ts11.isIdentifier(decl.name))
12714
+ return null;
12715
+ if (!decl.initializer)
12716
+ return null;
12717
+ const valueParsed = tsNodeToParsedExpr(decl.initializer);
12718
+ if (!isSupported(valueParsed).supported)
12719
+ return null;
12720
+ out.push({
12721
+ name: decl.name.text,
12722
+ valueParsed,
12723
+ raw: decl.initializer.getText(ctx.sourceFile)
12724
+ });
12725
+ }
12726
+ }
12727
+ return out.length > 0 ? out : null;
12728
+ }
12546
12729
  function trimPreambleSegments(segments) {
12547
12730
  const last = segments[segments.length - 1];
12548
12731
  if (last?.kind === "js") {
@@ -12988,6 +13171,9 @@ function tryResolveIdentifierAsTemplateLiteral(ident, ctx) {
12988
13171
  if (ts11.isNoSubstitutionTemplateLiteral(ast) || ts11.isStringLiteral(ast)) {
12989
13172
  return [{ type: "string", value: ast.text }];
12990
13173
  }
13174
+ if (ts11.isElementAccessExpression(ast) && !ts11.isStringLiteralLike(ast.argumentExpression) && !ts11.isNumericLiteral(ast.argumentExpression)) {
13175
+ return tryResolveTemplateSpanFromConst(ast, ctx);
13176
+ }
12991
13177
  if (!ts11.isTemplateExpression(ast))
12992
13178
  return null;
12993
13179
  let resolvedAny = false;
@@ -13235,8 +13421,11 @@ function processComponentProps(attributes, ctx) {
13235
13421
  }
13236
13422
  let value = getAttributeValue(attr, ctx);
13237
13423
  if (value.kind === "template") {
13238
- value = AttrValueOf.expression(templatePartsToJsString(value.parts), {
13239
- parts: value.parts
13424
+ const collapsed = templatePartsToJsString(value.parts);
13425
+ const collapsedTemplate = templatePartsToJsString(value.parts, { useTemplate: true });
13426
+ value = AttrValueOf.expression(collapsed, {
13427
+ parts: value.parts,
13428
+ ...collapsedTemplate !== collapsed && { templateExpr: collapsedTemplate }
13240
13429
  });
13241
13430
  } else if (value.kind === "boolean-attr") {
13242
13431
  value = AttrValueOf.booleanShorthand();
@@ -13265,16 +13454,18 @@ function processComponentProps(attributes, ctx) {
13265
13454
  }
13266
13455
  return props;
13267
13456
  }
13268
- function templatePartsToJsString(parts) {
13457
+ function templatePartsToJsString(parts, opts) {
13269
13458
  let result = "`";
13270
13459
  for (const part of parts) {
13271
13460
  if (part.type === "string") {
13272
- result += part.value;
13461
+ result += opts?.useTemplate && part.templateValue ? part.templateValue : part.value;
13273
13462
  } else if (part.type === "ternary") {
13274
- result += `\${${part.condition} ? '${part.whenTrue}' : '${part.whenFalse}'}`;
13463
+ const cond = opts?.useTemplate && part.templateCondition ? part.templateCondition : part.condition;
13464
+ result += `\${${cond} ? '${part.whenTrue}' : '${part.whenFalse}'}`;
13275
13465
  } else if (part.type === "lookup") {
13466
+ const key = opts?.useTemplate && part.templateKey ? part.templateKey : part.key;
13276
13467
  const obj = "{" + Object.entries(part.cases).map(([k, v]) => `${JSON.stringify(k)}: ${JSON.stringify(v)}`).join(", ") + "}";
13277
- result += `\${(${obj})[${part.key}]}`;
13468
+ result += `\${(${obj})[${key}]}`;
13278
13469
  }
13279
13470
  }
13280
13471
  result += "`";
@@ -13485,11 +13676,12 @@ function replaceBranchLocalRefs(text, branchNames, resolve2) {
13485
13676
  const pattern = new RegExp(`(?<![\\w$])(${branchNames.join("|")})(?![\\w$])`, "g");
13486
13677
  return replaceInExprContexts(text, pattern, (_match, name) => resolve2(name));
13487
13678
  }
13488
- function buildIfStatementChain(analyzer, ctx) {
13679
+ function buildIfStatementChain(analyzer, ctx, opts) {
13489
13680
  const conditionalReturns = analyzer.conditionalReturns;
13681
+ const asConditional = opts?.asConditional === true;
13490
13682
  let alternate = null;
13491
13683
  if (analyzer.jsxReturn) {
13492
- ctx.isRoot = true;
13684
+ ctx.isRoot = !asConditional;
13493
13685
  alternate = transformNode(analyzer.jsxReturn, ctx);
13494
13686
  }
13495
13687
  for (let i = conditionalReturns.length - 1;i >= 0; i--) {
@@ -13558,7 +13750,7 @@ function buildIfStatementChain(analyzer, ctx) {
13558
13750
  ctx.getJS = substitutedGetJS;
13559
13751
  ctx.analyzer.getJS = substitutedGetJS;
13560
13752
  }
13561
- ctx.isRoot = true;
13753
+ ctx.isRoot = !asConditional;
13562
13754
  let consequent;
13563
13755
  try {
13564
13756
  consequent = transformNode(condReturn.jsxReturn, ctx);
@@ -13588,6 +13780,27 @@ function buildIfStatementChain(analyzer, ctx) {
13588
13780
  }
13589
13781
  }
13590
13782
  const loc = getSourceLocation(condReturn.ifStatement, analyzer.sourceFile, analyzer.filePath);
13783
+ if (asConditional && alternate) {
13784
+ const conditional = {
13785
+ type: "conditional",
13786
+ condition,
13787
+ templateCondition,
13788
+ conditionType: null,
13789
+ reactive: true,
13790
+ whenTrue: consequent,
13791
+ whenFalse: alternate,
13792
+ slotId: generateSlotId(ctx),
13793
+ loc,
13794
+ origin: {
13795
+ phase: "tick",
13796
+ scope: "template",
13797
+ effect: "pure",
13798
+ freeRefs: resolveFreeRefs(condReturn.condition, makeBindingEnv(ctx))
13799
+ }
13800
+ };
13801
+ alternate = conditional;
13802
+ continue;
13803
+ }
13591
13804
  const ifStmt = {
13592
13805
  type: "if-statement",
13593
13806
  condition,
@@ -13901,7 +14114,13 @@ function collectLoopChildReactiveTexts(node, ctx, loopParam, loopParamBindings,
13901
14114
  });
13902
14115
  return texts;
13903
14116
  }
13904
- function collectLoopChildReactiveAttrs(node, ctx, loopParam, loopParamBindings, stopAtReactiveConditionals = false) {
14117
+ function anyNameIn(names, set) {
14118
+ for (const n of names)
14119
+ if (set.has(n))
14120
+ return true;
14121
+ return false;
14122
+ }
14123
+ function collectLoopChildReactiveAttrs(node, ctx, loopParam, loopParamBindings, stopAtReactiveConditionals = false, preambleNames) {
13905
14124
  const attrs = [];
13906
14125
  traverseElements(node, (el) => {
13907
14126
  if (el.slotId) {
@@ -13916,7 +14135,8 @@ function collectLoopChildReactiveAttrs(node, ctx, loopParam, loopParamBindings,
13916
14135
  if (!valueStr)
13917
14136
  continue;
13918
14137
  const expanded = expandConstantForReactivity(valueStr, ctx, attr.freeIdentifiers);
13919
- const reactive = classifyReactivity(expanded.expr, ctx, loopParam, loopParamBindings, expanded.freeIds).kind !== "none" || attr.callsReactiveGetters || attr.hasFunctionCalls;
14138
+ const readsPreamble = preambleNames !== undefined && preambleNames.size > 0 && anyNameIn(expanded.freeIds ?? extractFreeIdentifiersFromText(expanded.expr), preambleNames);
14139
+ const reactive = classifyReactivity(expanded.expr, ctx, loopParam, loopParamBindings, expanded.freeIds).kind !== "none" || readsPreamble || attr.callsReactiveGetters || attr.hasFunctionCalls;
13920
14140
  if (!attr.clientOnly && !reactive)
13921
14141
  continue;
13922
14142
  attrs.push({
@@ -13924,7 +14144,8 @@ function collectLoopChildReactiveAttrs(node, ctx, loopParam, loopParamBindings,
13924
14144
  attrName: attr.name,
13925
14145
  expression: expanded.expr,
13926
14146
  ...pickAttrMetaFromIR(attr),
13927
- ...expanded.freeIds !== undefined && { freeIdentifiers: expanded.freeIds }
14147
+ ...expanded.freeIds !== undefined && { freeIdentifiers: expanded.freeIds },
14148
+ ...readsPreamble && { readsPreamble: true }
13928
14149
  });
13929
14150
  }
13930
14151
  }
@@ -14046,7 +14267,7 @@ function emitTemplateCloneLines(template, indent) {
14046
14267
  ];
14047
14268
  }
14048
14269
  function emitLoopItemElementSetup(lines, opts) {
14049
- const { template, bodyIsMultiRoot, indent, singleRootLayout } = opts;
14270
+ const { template, bodyIsMultiRoot, indent, singleRootLayout, mountRow } = opts;
14050
14271
  const innerIndent = indent + " ";
14051
14272
  if (bodyIsMultiRoot) {
14052
14273
  lines.push(`${indent}let __el, __extras`);
@@ -14057,18 +14278,21 @@ function emitLoopItemElementSetup(lines, opts) {
14057
14278
  lines.push(ln);
14058
14279
  }
14059
14280
  lines.push(`${innerIndent}__el.__bfExtras = __extras`);
14281
+ if (mountRow)
14282
+ lines.push(`${innerIndent}mountRowRoot(__el)`);
14060
14283
  lines.push(`${indent}}`);
14061
14284
  return;
14062
14285
  }
14063
14286
  if (singleRootLayout === "inline") {
14064
14287
  const cloneExpr = emitTemplateCloneInline(template);
14065
- lines.push(`${indent}const __el = __existing ?? (() => { ${cloneExpr} })()`);
14288
+ const clone = `__existing ?? (() => { ${cloneExpr} })()`;
14289
+ lines.push(`${indent}const __el = ${mountRow ? `__existing ?? mountRowRoot((() => { ${cloneExpr} })())` : clone}`);
14066
14290
  return;
14067
14291
  }
14068
- lines.push(`${indent}const __el = __existing ?? (() => {`);
14292
+ lines.push(`${indent}const __el = __existing ?? ${mountRow ? "mountRowRoot(" : ""}(() => {`);
14069
14293
  for (const ln of emitTemplateCloneLines(template, innerIndent))
14070
14294
  lines.push(ln);
14071
- lines.push(`${indent}})()`);
14295
+ lines.push(`${indent}})()${mountRow ? ")" : ""}`);
14072
14296
  }
14073
14297
  function emitMultiRootTemplateCloneLines(template, indent, varEl, varExtras) {
14074
14298
  const isSvg = multiRootTemplateNeedsSvgWrap(template);
@@ -14217,10 +14441,11 @@ function collectInnerLoops(nodes, siblingOffsets, outerLoopParam, ctx, options)
14217
14441
  const template = n.children.map((c) => irToPlaceholderTemplate(c, undefined, emitDepth, loopParamsForTemplate)).join("");
14218
14442
  const refsOuter = outerLoopParam ? new RegExp(`\\b${outerLoopParam}\\b`).test(n.array) : false;
14219
14443
  const bindings = emptyLoopChildBindings();
14444
+ const innerPreambleNames = preambleNamesOf(n);
14220
14445
  if (ctx) {
14221
14446
  for (const child of n.children) {
14222
14447
  bindings.reactiveTexts.push(...collectLoopChildReactiveTexts(child, ctx, n.param, n.paramBindings));
14223
- bindings.reactiveAttrs.push(...collectLoopChildReactiveAttrs(child, ctx, n.param, n.paramBindings));
14448
+ bindings.reactiveAttrs.push(...collectLoopChildReactiveAttrs(child, ctx, n.param, n.paramBindings, false, innerPreambleNames));
14224
14449
  bindings.refs.push(...collectLoopChildRefs(child));
14225
14450
  }
14226
14451
  }
@@ -14443,7 +14668,7 @@ function collectElements(node, ctx, siblingOffsets, insideConditional = false) {
14443
14668
  return;
14444
14669
  const projectionInner = l.method === "flatMap" && l.children.length === 1 && l.children[0].type === "loop" ? l.children[0] : undefined;
14445
14670
  const childHandlers = [];
14446
- const bindings = projectionInner ? emptyLoopChildBindings() : collectLoopChildBindings(l.children, ctx, siblingOffsets, l.param, l.paramBindings);
14671
+ const bindings = projectionInner ? emptyLoopChildBindings() : collectLoopChildBindings(l.children, ctx, siblingOffsets, l.param, l.paramBindings, preambleNamesOf(l));
14447
14672
  if (!projectionInner) {
14448
14673
  for (const child of l.children) {
14449
14674
  childHandlers.push(...collectEventHandlersFromIR(child));
@@ -14466,7 +14691,7 @@ function collectElements(node, ctx, siblingOffsets, insideConditional = false) {
14466
14691
  if (l.childComponent) {
14467
14692
  template = "";
14468
14693
  if (l.isStaticArray && l.children[0]) {
14469
- staticItemTemplate = irToHtmlTemplate(l.children[0], buildRestSpreadNames(ctx), 0, undefined, undefined, true);
14694
+ staticItemTemplate = irToHtmlTemplate(l.children[0], buildRestSpreadNames(ctx), 0, undefined, undefined);
14470
14695
  }
14471
14696
  } else if (l.children[0] && !projectionInner) {
14472
14697
  const loopParamSpec = [{ param: l.param, bindings: l.paramBindings }];
@@ -14698,7 +14923,7 @@ function collectBranchLoops(node, ctx, siblingOffsets) {
14698
14923
  } else {
14699
14924
  childTemplate = n.children.map((c) => irToHtmlTemplate(c, undefined, 0, branchLoopParamSpec)).join("");
14700
14925
  }
14701
- const branchBindings = ctx && !projectionInner ? collectLoopChildBindings(n.children, ctx, siblingOffsets, n.param, n.paramBindings) : emptyLoopChildBindings();
14926
+ const branchBindings = ctx && !projectionInner ? collectLoopChildBindings(n.children, ctx, siblingOffsets, n.param, n.paramBindings, preambleNamesOf(n)) : emptyLoopChildBindings();
14702
14927
  loops.push({
14703
14928
  kind: "branch",
14704
14929
  array: n.array,
@@ -14778,11 +15003,17 @@ function collectBranchConditionals(node, ctx, siblingOffsets) {
14778
15003
  });
14779
15004
  return result;
14780
15005
  }
14781
- function collectLoopChildBindings(children, ctx, siblingOffsets, loopParam, loopParamBindings) {
15006
+ function preambleNamesOf(loop) {
15007
+ if (loop.isStaticArray)
15008
+ return;
15009
+ const declared = loop.preamble?.declaredNames;
15010
+ return declared && declared.length > 0 ? new Set(declared) : undefined;
15011
+ }
15012
+ function collectLoopChildBindings(children, ctx, siblingOffsets, loopParam, loopParamBindings, preambleNames) {
14782
15013
  const bindings = emptyLoopChildBindings();
14783
15014
  for (const child of children) {
14784
15015
  bindings.events.push(...collectLoopChildEventsWithNesting(child));
14785
- bindings.reactiveAttrs.push(...collectLoopChildReactiveAttrs(child, ctx, loopParam, loopParamBindings, true));
15016
+ bindings.reactiveAttrs.push(...collectLoopChildReactiveAttrs(child, ctx, loopParam, loopParamBindings, true, preambleNames));
14786
15017
  bindings.reactiveTexts.push(...collectLoopChildReactiveTexts(child, ctx, loopParam, loopParamBindings, true));
14787
15018
  bindings.refs.push(...collectLoopChildRefs(child));
14788
15019
  bindings.conditionals.push(...collectLoopChildConditionals(child, ctx, siblingOffsets, loopParam, loopParamBindings));
@@ -15296,6 +15527,10 @@ function isValueReferenceIdentifier(id) {
15296
15527
  if ((ts13.isMethodDeclaration(parent) || ts13.isGetAccessorDeclaration(parent) || ts13.isSetAccessorDeclaration(parent)) && parent.name === id) {
15297
15528
  return false;
15298
15529
  }
15530
+ if (ts13.isPropertyDeclaration(parent) && parent.name === id)
15531
+ return false;
15532
+ if (ts13.isMetaProperty(parent) && parent.name === id)
15533
+ return false;
15299
15534
  if (ts13.isVariableDeclaration(parent) && parent.name === id)
15300
15535
  return false;
15301
15536
  if (ts13.isFunctionDeclaration(parent) && parent.name === id)
@@ -15369,6 +15604,7 @@ var RUNTIME_IMPORT_CANDIDATES = [
15369
15604
  "registerTemplate",
15370
15605
  "initChild",
15371
15606
  "upsertChild",
15607
+ "mountRowRoot",
15372
15608
  "createPortal",
15373
15609
  "provideContext",
15374
15610
  "createContext",
@@ -16391,7 +16627,7 @@ function emitRegistrationAndHydration(lines, ctx, _ir, graph, inlinability) {
16391
16627
  }
16392
16628
  } else {
16393
16629
  const csrInlinableConstants = csrInlinableConstantsFromCtx(ctx);
16394
- const templateHtml = generateCsrTemplate(_ir.root, csrInlinableConstants, ctx, undefined, restSpreadNames, ctx.propsObjectName, unsafeLocalNames, ctx.deferredChildSlots);
16630
+ const templateHtml = generateCsrTemplate(_ir.root, csrInlinableConstants, ctx, restSpreadNames, ctx.propsObjectName, unsafeLocalNames, ctx.deferredChildSlots);
16395
16631
  if (templateHtml) {
16396
16632
  defParts.push(`template: (${PROPS_PARAM}) => \`${templateHtml}\``);
16397
16633
  }
@@ -16789,6 +17025,7 @@ function buildSignalPlan(signal, ctx, lookups) {
16789
17025
  kind: "signal",
16790
17026
  getter: signal.getter,
16791
17027
  setter: signal.setter,
17028
+ getterElided: signal.getterElided,
16792
17029
  initialValueExpr: "",
16793
17030
  controlledEffect: null,
16794
17031
  initializerOverride: `${factory}()`
@@ -16803,6 +17040,7 @@ function buildSignalPlan(signal, ctx, lookups) {
16803
17040
  kind: "signal",
16804
17041
  getter: signal.getter,
16805
17042
  setter: signal.setter,
17043
+ getterElided: signal.getterElided,
16806
17044
  initialValueExpr: resolveSignalInitialValue(signal, ctx, lookups),
16807
17045
  controlledEffect,
16808
17046
  branchCondition: signal.branchCondition,
@@ -16874,9 +17112,10 @@ function bfIdArg(bfId) {
16874
17112
  return bfId ? `, ${JSON.stringify(bfId)}` : "";
16875
17113
  }
16876
17114
  function emitSignal(lines, plan) {
17115
+ const getterSlot = plan.getterElided ? "" : plan.getter;
16877
17116
  if (plan.initializerOverride) {
16878
17117
  if (plan.setter) {
16879
- lines.push(` const [${plan.getter}, ${plan.setter}] = ${plan.initializerOverride}`);
17118
+ lines.push(` const [${getterSlot}, ${plan.setter}] = ${plan.initializerOverride}`);
16880
17119
  } else {
16881
17120
  lines.push(` const [${plan.getter}] = ${plan.initializerOverride}`);
16882
17121
  }
@@ -16885,9 +17124,9 @@ function emitSignal(lines, plan) {
16885
17124
  const id = bfIdArg(plan.bfId);
16886
17125
  if (plan.branchCondition) {
16887
17126
  if (plan.setter) {
16888
- lines.push(` let ${plan.getter}, ${plan.setter}`);
17127
+ lines.push(plan.getterElided ? ` let ${plan.setter}` : ` let ${plan.getter}, ${plan.setter}`);
16889
17128
  lines.push(` if (${plan.branchCondition}) {`);
16890
- lines.push(` ;[${plan.getter}, ${plan.setter}] = createSignal(${plan.initialValueExpr}${id})`);
17129
+ lines.push(` ;[${getterSlot}, ${plan.setter}] = createSignal(${plan.initialValueExpr}${id})`);
16891
17130
  lines.push(` }`);
16892
17131
  } else {
16893
17132
  lines.push(` let ${plan.getter}`);
@@ -16898,7 +17137,7 @@ function emitSignal(lines, plan) {
16898
17137
  return;
16899
17138
  }
16900
17139
  if (plan.setter) {
16901
- lines.push(` const [${plan.getter}, ${plan.setter}] = createSignal(${plan.initialValueExpr}${id})`);
17140
+ lines.push(` const [${getterSlot}, ${plan.setter}] = createSignal(${plan.initialValueExpr}${id})`);
16902
17141
  } else {
16903
17142
  lines.push(` const [${plan.getter}] = createSignal(${plan.initialValueExpr}${id})`);
16904
17143
  }
@@ -17477,7 +17716,7 @@ function emitComponentAndEventSetup(ls, indent, elVar, comps, events, loopParam,
17477
17716
  // src/ir-to-client-js/plan/build-static-array-child-init.ts
17478
17717
  function staticPreludeStatements(preamble) {
17479
17718
  return preamble ? [renderPreamble(preamble, {
17480
- renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, undefined, undefined, true)
17719
+ renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, undefined, undefined)
17481
17720
  })] : [];
17482
17721
  }
17483
17722
  function buildStaticArrayChildInitsPlan(ctx) {
@@ -18032,7 +18271,8 @@ function buildReactiveEffectsPlan(args) {
18032
18271
  attrs: slotAttrs.map((attr) => ({
18033
18272
  attrName: attr.attrName,
18034
18273
  wrappedExpression: wrap(attr.expression),
18035
- meta: pickAttrMeta(attr)
18274
+ meta: pickAttrMeta(attr),
18275
+ ...attr.readsPreamble && { readsPreamble: true }
18036
18276
  }))
18037
18277
  });
18038
18278
  }
@@ -18232,7 +18472,7 @@ function buildReactiveEmit(inner, level, wrapOuter, uidSuffix, outerLoopParam, o
18232
18472
  ] : [{ param: inner.param, bindings: inner.paramBindings }];
18233
18473
  preludeStatements.push(renderPreamble(inner.preamble, {
18234
18474
  transformJs: (t) => wrapInner(wrapOuter(t)),
18235
- renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, leafLoopParams, undefined, true)
18475
+ renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, leafLoopParams, undefined)
18236
18476
  }));
18237
18477
  }
18238
18478
  const childRefs = buildChildRefBindings(inner.bindings.refs, inner.param, inner.paramBindings);
@@ -18258,7 +18498,7 @@ function buildStaticEmit(inner, level, uidSuffix) {
18258
18498
  preludeStatements.push(indexAlias);
18259
18499
  if (inner.preamble) {
18260
18500
  preludeStatements.push(renderPreamble(inner.preamble, {
18261
- renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, undefined, undefined, true)
18501
+ renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, undefined, undefined)
18262
18502
  }));
18263
18503
  }
18264
18504
  return {
@@ -18290,7 +18530,7 @@ function buildTopLevelCompositePlan(elem, profileComponentName) {
18290
18530
  indexParam: elem.index || "__idx",
18291
18531
  mapPreambleWrapped: elem.preamble ? renderPreamble(elem.preamble, {
18292
18532
  transformJs: wrap,
18293
- renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, [{ param: elem.param, bindings: elem.paramBindings }], undefined, true)
18533
+ renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, [{ param: elem.param, bindings: elem.paramBindings }], undefined)
18294
18534
  }) : "",
18295
18535
  template: elem.template,
18296
18536
  outerComps: filterCondCompsOut(outerCompsByDepth, elem.bindings.conditionals),
@@ -18340,7 +18580,7 @@ function buildBranchCompositePlan(loop, cv, profileComponentName) {
18340
18580
  indexParam: loop.index || "__idx",
18341
18581
  mapPreambleWrapped: loop.preamble ? renderPreamble(loop.preamble, {
18342
18582
  transformJs: wrap,
18343
- renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, [{ param: loop.param, bindings: loop.paramBindings }], undefined, true)
18583
+ renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, [{ param: loop.param, bindings: loop.paramBindings }], undefined)
18344
18584
  }) : "",
18345
18585
  template: loop.template,
18346
18586
  outerComps: filterCondCompsOut(outerCompsByDepth, loop.bindings.conditionals),
@@ -18405,7 +18645,7 @@ function buildDynamicLoopDelegationPlan(elem, profileComponentName) {
18405
18645
  key: elem.key,
18406
18646
  index: elem.index,
18407
18647
  mapPreamble: elem.preamble ? renderPreamble(elem.preamble, {
18408
- renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, undefined, undefined, true)
18648
+ renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, undefined, undefined)
18409
18649
  }) : null,
18410
18650
  mapPreambleDeclaredNames: elem.preamble?.declaredNames ?? []
18411
18651
  })
@@ -18424,7 +18664,7 @@ function buildBranchLoopDelegationPlan(loop, cv, profileComponentName) {
18424
18664
  key: loop.key,
18425
18665
  index: loop.index,
18426
18666
  mapPreamble: loop.preamble ? renderPreamble(loop.preamble, {
18427
- renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, undefined, undefined, true)
18667
+ renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, undefined, undefined)
18428
18668
  }) : null,
18429
18669
  mapPreambleDeclaredNames: loop.preamble?.declaredNames ?? []
18430
18670
  })
@@ -18441,7 +18681,7 @@ function buildStaticArrayDelegationPlan(elem, profileComponentName) {
18441
18681
  arrayExpr: buildChainedArrayExpr(elem),
18442
18682
  param: elem.param,
18443
18683
  mapPreamble: elem.preamble ? renderPreamble(elem.preamble, {
18444
- renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, undefined, undefined, true)
18684
+ renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, undefined, undefined)
18445
18685
  }) : null,
18446
18686
  mapPreambleDeclaredNames: elem.preamble?.declaredNames ?? [],
18447
18687
  offset: elem.offset ?? null,
@@ -18476,6 +18716,181 @@ function buildKeyedOrIndexLookup(args) {
18476
18716
  };
18477
18717
  }
18478
18718
 
18719
+ // src/ir-to-client-js/control-flow/plan/lazy-conditional.ts
18720
+ var NO = (reason) => ({ lazySafe: false, reason });
18721
+ function wiringOn(branch) {
18722
+ const found = [];
18723
+ if (branch.childComponents.length > 0)
18724
+ found.push("child components");
18725
+ if (branch.innerLoops && branch.innerLoops.length > 0)
18726
+ found.push("an inner loop");
18727
+ if (branch.conditionals && branch.conditionals.length > 0)
18728
+ found.push("a nested conditional");
18729
+ if (branch.events && branch.events.length > 0)
18730
+ found.push("events");
18731
+ if (branch.reactiveAttrs && branch.reactiveAttrs.length > 0)
18732
+ found.push("reactive attrs");
18733
+ if (branch.reactiveTexts && branch.reactiveTexts.length > 0)
18734
+ found.push("reactive text");
18735
+ return found;
18736
+ }
18737
+ function analyzeLazyConditional(cond, indexParam, arms) {
18738
+ for (const [label, branch] of [["true", cond.whenTrue], ["false", cond.whenFalse]]) {
18739
+ const wiring = wiringOn(branch);
18740
+ if (wiring.length > 0) {
18741
+ return NO(`conditional on slot ${cond.slotId}: its ${label} arm owns ${wiring.join(" + ")}`);
18742
+ }
18743
+ }
18744
+ for (const [label, html] of [["true", arms.whenTrueHtml], ["false", arms.whenFalseHtml]]) {
18745
+ if (html.includes("bf-cond-start:")) {
18746
+ return NO(`conditional on slot ${cond.slotId}: its ${label} arm is a fragment conditional`);
18747
+ }
18748
+ if (!html.includes(`bf-c="${cond.slotId}"`)) {
18749
+ return NO(`conditional on slot ${cond.slotId}: its ${label} arm has no single bf-c root`);
18750
+ }
18751
+ if (html.includes("${")) {
18752
+ return NO(`conditional on slot ${cond.slotId}: its ${label} arm interpolates a value`);
18753
+ }
18754
+ }
18755
+ if (!cond.conditionFreeIdentifiers) {
18756
+ return NO(`conditional on slot ${cond.slotId}: condition has no analyzable identifier set`);
18757
+ }
18758
+ if (cond.conditionFreeIdentifiers.has(indexParam)) {
18759
+ return NO(`conditional on slot ${cond.slotId}: condition reads the loop index parameter '${indexParam}'`);
18760
+ }
18761
+ return {
18762
+ lazySafe: true,
18763
+ facts: {
18764
+ slotId: cond.slotId,
18765
+ condition: cond.condition,
18766
+ whenTrueHtml: arms.whenTrueHtml,
18767
+ whenFalseHtml: arms.whenFalseHtml
18768
+ }
18769
+ };
18770
+ }
18771
+
18772
+ // src/ir-to-client-js/control-flow/plan/lazy-preamble.ts
18773
+ import ts15 from "typescript";
18774
+ var NO_PREAMBLE = {
18775
+ lazySafe: true,
18776
+ facts: { declaredNames: new Set, freeNames: new Set }
18777
+ };
18778
+ var NO2 = (reason) => ({ lazySafe: false, reason });
18779
+ function analyzeLazyPreamble(preamble, indexParam, primableNames) {
18780
+ if (!preamble)
18781
+ return NO_PREAMBLE;
18782
+ if (preamble.builderNames.length > 0) {
18783
+ return NO2(`map-callback preamble accumulates JSX leaves (${preamble.builderNames.join(", ")})`);
18784
+ }
18785
+ for (const seg of preamble.segments) {
18786
+ if (seg.kind !== "js")
18787
+ return NO2("map-callback preamble contains a JSX leaf");
18788
+ }
18789
+ const text = preambleAnalysisText(preamble);
18790
+ if (text.trim().length === 0)
18791
+ return NO_PREAMBLE;
18792
+ const declaredNames = new Set;
18793
+ const sf = ts15.createSourceFile("__lazy_preamble__.ts", text, ts15.ScriptTarget.Latest, true, ts15.ScriptKind.TS);
18794
+ for (const stmt of sf.statements) {
18795
+ if (!ts15.isVariableStatement(stmt)) {
18796
+ return NO2(`map-callback preamble has a non-declaration statement (${ts15.SyntaxKind[stmt.kind]})`);
18797
+ }
18798
+ const isConst = (stmt.declarationList.flags & ts15.NodeFlags.Const) !== 0;
18799
+ if (!isConst)
18800
+ return NO2("map-callback preamble declares a mutable binding (let/var)");
18801
+ for (const decl of stmt.declarationList.declarations) {
18802
+ collectBindingNames2(decl.name, declaredNames);
18803
+ if (!decl.initializer) {
18804
+ return NO2("map-callback preamble has a declaration with no initializer");
18805
+ }
18806
+ const impure = findImpureNode(decl.initializer, primableNames);
18807
+ if (impure) {
18808
+ return NO2(`map-callback preamble initializer is not re-runnable (${impure})`);
18809
+ }
18810
+ }
18811
+ }
18812
+ for (const name of declaredNames) {
18813
+ if (primableNames.has(name)) {
18814
+ return NO2(`map-callback preamble shadows the signal/memo getter '${name}'`);
18815
+ }
18816
+ }
18817
+ const readNames = extractFreeIdentifiersFromStatementText(text);
18818
+ if (readNames.has(indexParam) && !declaredNames.has(indexParam)) {
18819
+ return NO2(`map-callback preamble reads the loop index parameter '${indexParam}'`);
18820
+ }
18821
+ const freeNames = new Set(readNames);
18822
+ for (const declared of declaredNames)
18823
+ freeNames.delete(declared);
18824
+ return { lazySafe: true, facts: { declaredNames, freeNames } };
18825
+ }
18826
+ function collectBindingNames2(name, out) {
18827
+ if (ts15.isIdentifier(name)) {
18828
+ out.add(name.text);
18829
+ return;
18830
+ }
18831
+ for (const element of name.elements) {
18832
+ if (ts15.isOmittedExpression(element))
18833
+ continue;
18834
+ collectBindingNames2(element.name, out);
18835
+ }
18836
+ }
18837
+ function findImpureNode(root, primableNames) {
18838
+ let found = null;
18839
+ const visit3 = (node) => {
18840
+ if (found)
18841
+ return;
18842
+ if (ts15.isCallExpression(node)) {
18843
+ const callee = node.expression;
18844
+ const isSignalRead = ts15.isIdentifier(callee) && primableNames.has(callee.text) && node.arguments.length === 0 && node.questionDotToken === undefined;
18845
+ if (!isSignalRead) {
18846
+ found = `call to ${callee.getText(callee.getSourceFile())}`;
18847
+ return;
18848
+ }
18849
+ }
18850
+ if (ts15.isNewExpression(node)) {
18851
+ found = "new expression";
18852
+ return;
18853
+ }
18854
+ if (ts15.isTaggedTemplateExpression(node)) {
18855
+ found = "tagged template";
18856
+ return;
18857
+ }
18858
+ if (ts15.isAwaitExpression(node)) {
18859
+ found = "await";
18860
+ return;
18861
+ }
18862
+ if (ts15.isYieldExpression(node)) {
18863
+ found = "yield";
18864
+ return;
18865
+ }
18866
+ if (ts15.isPrefixUnaryExpression(node) || ts15.isPostfixUnaryExpression(node)) {
18867
+ const op = node.operator;
18868
+ if (op === ts15.SyntaxKind.PlusPlusToken || op === ts15.SyntaxKind.MinusMinusToken) {
18869
+ found = "increment/decrement";
18870
+ return;
18871
+ }
18872
+ }
18873
+ if (ts15.isDeleteExpression(node)) {
18874
+ found = "delete";
18875
+ return;
18876
+ }
18877
+ if (ts15.isFunctionExpression(node) || ts15.isArrowFunction(node) || ts15.isClassExpression(node)) {
18878
+ found = "function or class expression";
18879
+ return;
18880
+ }
18881
+ if (ts15.isBinaryExpression(node) && isAssignmentOperator(node.operatorToken.kind)) {
18882
+ found = "assignment";
18883
+ return;
18884
+ }
18885
+ ts15.forEachChild(node, visit3);
18886
+ };
18887
+ visit3(root);
18888
+ return found;
18889
+ }
18890
+ function isAssignmentOperator(kind) {
18891
+ return kind >= ts15.SyntaxKind.FirstAssignment && kind <= ts15.SyntaxKind.LastAssignment;
18892
+ }
18893
+
18479
18894
  // src/ir-to-client-js/control-flow/plan/lazy-row-eligibility.ts
18480
18895
  var PURE_SOURCE_GLOBALS = new Set([
18481
18896
  "Object",
@@ -18519,51 +18934,51 @@ var INERT_BINDING_GLOBALS = new Set([
18519
18934
  "decodeURI"
18520
18935
  ]);
18521
18936
  var UNKNOWN_IDENTIFIERS = "<unknown>";
18522
- var NO = (reason) => ({ eligible: false, reason });
18937
+ var NO3 = (reason) => ({ eligible: false, reason });
18523
18938
  function lazyRowEligibility(args) {
18524
18939
  const { shape, bindings, arraySourceIdentifiers, scope } = args;
18525
18940
  if (scope.profile)
18526
- return NO("profile mode keeps the granular eager emission");
18941
+ return NO3("profile mode keeps the granular eager emission");
18527
18942
  if (shape.callSite !== "plain" && shape.callSite !== "branch-plain") {
18528
- return NO(`call site '${shape.callSite}' is not a plain loop row`);
18943
+ return NO3(`call site '${shape.callSite}' is not a plain loop row`);
18529
18944
  }
18530
18945
  if (shape.flatMapLeafItem)
18531
- return NO("flatMap descriptor loop (build-or-patch renderItem)");
18946
+ return NO3("flatMap descriptor loop (build-or-patch renderItem)");
18532
18947
  if (shape.anchored)
18533
- return NO("anchored whole-item-conditional loop");
18948
+ return NO3("anchored whole-item-conditional loop");
18534
18949
  if (shape.bodyIsMultiRoot)
18535
- return NO("multi-root (Fragment) row");
18950
+ return NO3("multi-root (Fragment) row");
18536
18951
  if (!shape.hasExplicitKey)
18537
- return NO("index-keyed loop (no explicit key)");
18538
- if (shape.conditionalCount > 0)
18539
- return NO("row contains a reactive conditional");
18952
+ return NO3("index-keyed loop (no explicit key)");
18953
+ if (shape.conditionalRefusal)
18954
+ return NO3(shape.conditionalRefusal);
18540
18955
  if (shape.childRefCount > 0)
18541
- return NO("row has imperative child refs");
18956
+ return NO3("row has imperative child refs");
18542
18957
  if (shape.hasChildComponent)
18543
- return NO("row body is a child component");
18958
+ return NO3("row body is a child component");
18544
18959
  if (shape.nestedComponentCount > 0)
18545
- return NO("row contains nested child components");
18960
+ return NO3("row contains nested child components");
18546
18961
  if (shape.innerLoopCount > 0)
18547
- return NO("row contains an inner loop");
18548
- if (shape.hasMapPreamble)
18549
- return NO("row has a map-callback preamble (may declare row-local reactivity)");
18962
+ return NO3("row contains an inner loop");
18963
+ if (shape.mapPreambleRefusal)
18964
+ return NO3(shape.mapPreambleRefusal);
18550
18965
  if (shape.preambleRegionCount > 0)
18551
- return NO("row has preamble-patched regions");
18966
+ return NO3("row has preamble-patched regions");
18552
18967
  if (shape.hasParamUnwrap)
18553
- return NO("destructured loop param without param bindings");
18968
+ return NO3("destructured loop param without param bindings");
18554
18969
  for (const b of bindings) {
18555
18970
  if (b.referencesIndex) {
18556
- return NO(`binding on slot ${b.slotId} references the loop index parameter`);
18971
+ return NO3(`binding on slot ${b.slotId} references the loop index parameter`);
18557
18972
  }
18558
18973
  if (b.opaqueOuterNames.includes(UNKNOWN_IDENTIFIERS)) {
18559
- return NO(`binding on slot ${b.slotId} has no analyzable identifier set`);
18974
+ return NO3(`binding on slot ${b.slotId} has no analyzable identifier set`);
18560
18975
  }
18561
18976
  }
18562
18977
  if (!arraySourceIdentifiers)
18563
- return NO("loop source free identifiers unavailable");
18978
+ return NO3("loop source free identifiers unavailable");
18564
18979
  const sourceGate = checkSourceConsistency(arraySourceIdentifiers, scope);
18565
18980
  if (sourceGate)
18566
- return NO(`loop source is not provably hydration-consistent: ${sourceGate}`);
18981
+ return NO3(`loop source is not provably hydration-consistent: ${sourceGate}`);
18567
18982
  return { eligible: true };
18568
18983
  }
18569
18984
  function checkSourceConsistency(names, scope) {
@@ -18614,6 +19029,7 @@ function checkSourceConsistency(names, scope) {
18614
19029
  }
18615
19030
  function classifyLazyBinding(args) {
18616
19031
  const { kind, slotId, free, rowLocalNames, indexParam, scope } = args;
19032
+ const preamble = args.preamble;
18617
19033
  if (free === null) {
18618
19034
  return {
18619
19035
  kind,
@@ -18622,33 +19038,44 @@ function classifyLazyBinding(args) {
18622
19038
  readsOuter: true,
18623
19039
  reactiveOuterNames: [],
18624
19040
  opaqueOuterNames: [UNKNOWN_IDENTIFIERS],
18625
- referencesIndex: false
19041
+ referencesIndex: false,
19042
+ readsPreamble: preamble != null && preamble.declaredNames.size > 0
18626
19043
  };
18627
19044
  }
18628
19045
  let readsItem = false;
18629
19046
  let referencesIndex = false;
19047
+ let readsPreamble = false;
18630
19048
  const reactiveOuterNames = [];
18631
19049
  const opaqueOuterNames = [];
18632
- for (const name of free) {
19050
+ const classifyName = (name) => {
18633
19051
  if (rowLocalNames.has(name)) {
18634
19052
  readsItem = true;
18635
- continue;
19053
+ return;
18636
19054
  }
18637
19055
  if (name === indexParam) {
18638
19056
  referencesIndex = true;
18639
- continue;
19057
+ return;
18640
19058
  }
18641
19059
  if (INERT_BINDING_GLOBALS.has(name))
18642
- continue;
19060
+ return;
18643
19061
  if (scope.signals.has(name) || scope.memos.has(name)) {
18644
19062
  if (!reactiveOuterNames.includes(name))
18645
19063
  reactiveOuterNames.push(name);
18646
- continue;
19064
+ return;
18647
19065
  }
18648
19066
  const constFree = scope.constants.get(name);
18649
19067
  if (constFree !== undefined && constFree !== null && constFree.size === 0)
18650
- continue;
19068
+ return;
18651
19069
  opaqueOuterNames.push(name);
19070
+ };
19071
+ for (const name of free) {
19072
+ if (preamble?.declaredNames.has(name)) {
19073
+ readsPreamble = true;
19074
+ for (const dep of preamble.freeNames)
19075
+ classifyName(dep);
19076
+ continue;
19077
+ }
19078
+ classifyName(name);
18652
19079
  }
18653
19080
  return {
18654
19081
  kind,
@@ -18657,7 +19084,8 @@ function classifyLazyBinding(args) {
18657
19084
  readsOuter: reactiveOuterNames.length > 0 || opaqueOuterNames.length > 0,
18658
19085
  reactiveOuterNames,
18659
19086
  opaqueOuterNames,
18660
- referencesIndex
19087
+ referencesIndex,
19088
+ readsPreamble
18661
19089
  };
18662
19090
  }
18663
19091
 
@@ -18674,6 +19102,23 @@ function decideLazyRow(args) {
18674
19102
  const rowLocalNames = new Set([loop.param]);
18675
19103
  for (const b of loop.paramBindings ?? [])
18676
19104
  rowLocalNames.add(b.name);
19105
+ const primableNames = new Set([...scope.signals.keys(), ...scope.memos]);
19106
+ const preambleAnalysis = analyzeLazyPreamble(loop.preamble, args.indexParam, primableNames);
19107
+ const rawConditionals = loop.bindings.conditionals ?? [];
19108
+ const condFacts = [];
19109
+ let conditionalRefusal = null;
19110
+ for (const cond of rawConditionals) {
19111
+ const verdict = analyzeLazyConditional(cond, args.indexParam, {
19112
+ whenTrueHtml: addCondAttrToTemplate(wrap(cond.whenTrueHtml), cond.slotId),
19113
+ whenFalseHtml: addCondAttrToTemplate(wrap(cond.whenFalseHtml), cond.slotId)
19114
+ });
19115
+ if (!verdict.lazySafe) {
19116
+ conditionalRefusal = verdict.reason;
19117
+ break;
19118
+ }
19119
+ condFacts.push(verdict.facts);
19120
+ }
19121
+ const preambleFacts = preambleAnalysis.lazySafe ? preambleAnalysis.facts : undefined;
18677
19122
  const classified = [];
18678
19123
  const attrClass = new Map;
18679
19124
  loop.bindings.reactiveAttrs.forEach((attr, i) => {
@@ -18683,7 +19128,8 @@ function decideLazyRow(args) {
18683
19128
  free: attrFreeIdentifiers2(attr.expression),
18684
19129
  rowLocalNames,
18685
19130
  indexParam: args.indexParam,
18686
- scope
19131
+ scope,
19132
+ preamble: preambleFacts
18687
19133
  });
18688
19134
  attrClass.set(i, c);
18689
19135
  classified.push(c);
@@ -18696,23 +19142,38 @@ function decideLazyRow(args) {
18696
19142
  free: text.freeIdentifiers ?? null,
18697
19143
  rowLocalNames,
18698
19144
  indexParam: args.indexParam,
18699
- scope
19145
+ scope,
19146
+ preamble: preambleFacts
18700
19147
  });
18701
19148
  textClass.set(i, c);
18702
19149
  classified.push(c);
18703
19150
  });
19151
+ const condClass = new Map;
19152
+ condFacts.forEach((c, i) => {
19153
+ const k = classifyLazyBinding({
19154
+ kind: "attr",
19155
+ slotId: c.slotId,
19156
+ free: rawConditionals[i].conditionFreeIdentifiers ?? null,
19157
+ rowLocalNames,
19158
+ indexParam: args.indexParam,
19159
+ scope,
19160
+ preamble: preambleFacts
19161
+ });
19162
+ condClass.set(i, k);
19163
+ classified.push(k);
19164
+ });
18704
19165
  const shape = {
18705
19166
  callSite: args.callSite,
18706
19167
  flatMapLeafItem: args.flatMapLeafItem,
18707
19168
  anchored: args.anchored,
18708
19169
  bodyIsMultiRoot: loop.bodyIsMultiRoot ?? false,
18709
19170
  hasExplicitKey: loop.key != null,
18710
- conditionalCount: loop.bindings.conditionals?.length ?? 0,
19171
+ conditionalRefusal,
18711
19172
  childRefCount: loop.bindings.refs?.length ?? 0,
18712
19173
  nestedComponentCount: loop.nestedComponents?.length ?? 0,
18713
19174
  innerLoopCount: loop.innerLoops?.length ?? 0,
18714
19175
  hasChildComponent: "childComponent" in loop && loop.childComponent != null,
18715
- hasMapPreamble: args.mapPreambleWrapped.length > 0,
19176
+ mapPreambleRefusal: preambleAnalysis.lazySafe ? null : preambleAnalysis.reason,
18716
19177
  preambleRegionCount: args.preambleRegionCount,
18717
19178
  hasParamUnwrap: args.paramUnwrap.length > 0
18718
19179
  };
@@ -18740,7 +19201,8 @@ function decideLazyRow(args) {
18740
19201
  refIndex: attrSlotIds.indexOf(attr.childSlotId),
18741
19202
  ordinal: ordinal++,
18742
19203
  readsItem: c.readsItem,
18743
- readsOuter: c.readsOuter
19204
+ readsOuter: c.readsOuter,
19205
+ readsPreamble: c.readsPreamble
18744
19206
  };
18745
19207
  });
18746
19208
  const texts = loop.bindings.reactiveTexts.map((text, i) => {
@@ -18750,7 +19212,8 @@ function decideLazyRow(args) {
18750
19212
  wrappedExpression: wrap(text.expression),
18751
19213
  ordinal: ordinal++,
18752
19214
  readsItem: c.readsItem || !c.readsOuter,
18753
- readsOuter: c.readsOuter
19215
+ readsOuter: c.readsOuter,
19216
+ readsPreamble: c.readsPreamble
18754
19217
  };
18755
19218
  });
18756
19219
  const outerPrimeGetters = [];
@@ -18760,6 +19223,21 @@ function decideLazyRow(args) {
18760
19223
  outerPrimeGetters.push(name);
18761
19224
  }
18762
19225
  }
19226
+ const condRefBase = attrSlotIds.length + (texts.length > 0 ? 1 : 0);
19227
+ const conditionals = condFacts.map((c, i) => {
19228
+ const klass = condClass.get(i);
19229
+ return {
19230
+ slotId: c.slotId,
19231
+ wrappedCondition: wrap(c.condition),
19232
+ whenTrueHtml: c.whenTrueHtml,
19233
+ whenFalseHtml: c.whenFalseHtml,
19234
+ refIndex: condRefBase + i,
19235
+ ordinal: ordinal++,
19236
+ readsItem: klass.readsItem || !klass.readsOuter,
19237
+ readsOuter: klass.readsOuter,
19238
+ readsPreamble: klass.readsPreamble
19239
+ };
19240
+ });
18763
19241
  return {
18764
19242
  plan: {
18765
19243
  attrSlotIds,
@@ -18769,7 +19247,10 @@ function decideLazyRow(args) {
18769
19247
  textNeedsRead: texts.some((t) => t.readsOuter),
18770
19248
  lastCount: ordinal,
18771
19249
  outerPrimeGetters,
18772
- hasOuter: attrs.some((a) => a.readsOuter) || texts.some((t) => t.readsOuter)
19250
+ preambleStatements: args.mapPreambleWrapped,
19251
+ itemNeedsPreamble: [...attrs, ...texts, ...conditionals].some((b) => b.readsItem && b.readsPreamble),
19252
+ outerNeedsPreamble: [...attrs, ...texts, ...conditionals].some((b) => b.readsOuter && b.readsPreamble),
19253
+ conditionals
18773
19254
  },
18774
19255
  decision
18775
19256
  };
@@ -18841,7 +19322,7 @@ function buildBranchLoopPlan(loop, profileComponentName, lazyScope) {
18841
19322
  const indexParam = loop.index || "__idx";
18842
19323
  const mapPreambleWrapped = loop.preamble ? renderPreamble(loop.preamble, {
18843
19324
  transformJs: (t) => wrapLoopParamAsAccessor(t, loop.param, loop.paramBindings),
18844
- renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, [{ param: loop.param, bindings: loop.paramBindings }], undefined, true)
19325
+ renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, [{ param: loop.param, bindings: loop.paramBindings }], undefined)
18845
19326
  }) : "";
18846
19327
  const preambleRegions = buildPreambleRegionPlans(loop.preambleRegions, loop.param, loop.paramBindings);
18847
19328
  const plan = {
@@ -18937,7 +19418,7 @@ function buildArmBody(branch, options) {
18937
19418
  }
18938
19419
 
18939
19420
  // src/ir-to-client-js/emit-reactive.ts
18940
- import ts15 from "typescript";
19421
+ import ts16 from "typescript";
18941
19422
 
18942
19423
  // src/ir-to-client-js/control-flow/stringify/claim-plan.ts
18943
19424
  function slotSpecLiteral(slot) {
@@ -19040,20 +19521,20 @@ function lowerToLocaleCallsInReactiveExpr(expr, matcher) {
19040
19521
  return expr;
19041
19522
  let sourceFile;
19042
19523
  try {
19043
- sourceFile = ts15.createSourceFile("__reactive_expr__.ts", `(${expr});`, ts15.ScriptTarget.Latest, true, ts15.ScriptKind.TS);
19524
+ sourceFile = ts16.createSourceFile("__reactive_expr__.ts", `(${expr});`, ts16.ScriptTarget.Latest, true, ts16.ScriptKind.TS);
19044
19525
  } catch {
19045
19526
  return expr;
19046
19527
  }
19047
19528
  const stmt = sourceFile.statements[0];
19048
- if (!stmt || !ts15.isExpressionStatement(stmt))
19529
+ if (!stmt || !ts16.isExpressionStatement(stmt))
19049
19530
  return expr;
19050
- const root = ts15.isParenthesizedExpression(stmt.expression) ? stmt.expression.expression : stmt.expression;
19531
+ const root = ts16.isParenthesizedExpression(stmt.expression) ? stmt.expression.expression : stmt.expression;
19051
19532
  const candidates = [];
19052
19533
  const visit3 = (n) => {
19053
- if (ts15.isCallExpression(n) && n.arguments.length === 2 && ts15.isPropertyAccessExpression(n.expression) && !n.expression.questionDotToken && n.expression.name.text === "toLocaleDateString") {
19534
+ if (ts16.isCallExpression(n) && n.arguments.length === 2 && ts16.isPropertyAccessExpression(n.expression) && !n.expression.questionDotToken && n.expression.name.text === "toLocaleDateString") {
19054
19535
  candidates.push(n);
19055
19536
  }
19056
- ts15.forEachChild(n, visit3);
19537
+ ts16.forEachChild(n, visit3);
19057
19538
  };
19058
19539
  visit3(root);
19059
19540
  if (candidates.length === 0)
@@ -19089,20 +19570,20 @@ function lowerDateCallsInReactiveExpr(expr, matcher) {
19089
19570
  return expr;
19090
19571
  let sourceFile;
19091
19572
  try {
19092
- sourceFile = ts15.createSourceFile("__reactive_expr__.ts", `(${expr});`, ts15.ScriptTarget.Latest, true, ts15.ScriptKind.TS);
19573
+ sourceFile = ts16.createSourceFile("__reactive_expr__.ts", `(${expr});`, ts16.ScriptTarget.Latest, true, ts16.ScriptKind.TS);
19093
19574
  } catch {
19094
19575
  return expr;
19095
19576
  }
19096
19577
  const stmt = sourceFile.statements[0];
19097
- if (!stmt || !ts15.isExpressionStatement(stmt))
19578
+ if (!stmt || !ts16.isExpressionStatement(stmt))
19098
19579
  return expr;
19099
- const root = ts15.isParenthesizedExpression(stmt.expression) ? stmt.expression.expression : stmt.expression;
19580
+ const root = ts16.isParenthesizedExpression(stmt.expression) ? stmt.expression.expression : stmt.expression;
19100
19581
  const candidates = [];
19101
19582
  const visit3 = (n) => {
19102
- if (ts15.isCallExpression(n) && n.arguments.length === 0 && ts15.isPropertyAccessExpression(n.expression) && !n.expression.questionDotToken && DATE_METHODS.has(n.expression.name.text)) {
19583
+ if (ts16.isCallExpression(n) && n.arguments.length === 0 && ts16.isPropertyAccessExpression(n.expression) && !n.expression.questionDotToken && DATE_METHODS.has(n.expression.name.text)) {
19103
19584
  candidates.push(n);
19104
19585
  }
19105
- ts15.forEachChild(n, visit3);
19586
+ ts16.forEachChild(n, visit3);
19106
19587
  };
19107
19588
  visit3(root);
19108
19589
  if (candidates.length === 0)
@@ -19410,7 +19891,7 @@ function stringifyReactiveEffects(lines, plan, opts) {
19410
19891
  const outerTexts = plan?.outerTexts ?? [];
19411
19892
  const conditionals = plan?.conditionals ?? [];
19412
19893
  if (pc) {
19413
- emitAttrSlotsGranular(lines, indent, elVar, lookup, attrSlots, elementIndexBySlot, bindingBfId);
19894
+ emitAttrSlotsGranular(lines, indent, elVar, lookup, attrSlots, elementIndexBySlot, bindingBfId, mapPreambleWrapped);
19414
19895
  emitOuterTexts(lines, indent, elVar, outerTexts, bindingBfId, textClaimPathExprs);
19415
19896
  emitPreambleRegionsEffect(lines, indent, elVar, preambleRegions, mapPreambleWrapped);
19416
19897
  } else {
@@ -19420,7 +19901,7 @@ function stringifyReactiveEffects(lines, plan, opts) {
19420
19901
  emitOuterConditional(lines, indent, elVar, cond, pc);
19421
19902
  }
19422
19903
  }
19423
- function emitAttrSlotsGranular(lines, indent, elVar, lookup, attrSlots, elementIndexBySlot, bindingBfId) {
19904
+ function emitAttrSlotsGranular(lines, indent, elVar, lookup, attrSlots, elementIndexBySlot, bindingBfId, mapPreambleWrapped) {
19424
19905
  for (const slot of attrSlots) {
19425
19906
  const varName = `__ra_${varSlotId(slot.slotId)}`;
19426
19907
  const lookupExpr = attrLookupExpr(slot.slotId, varName, elVar, lookup, elementIndexBySlot);
@@ -19428,6 +19909,9 @@ function emitAttrSlotsGranular(lines, indent, elVar, lookup, attrSlots, elementI
19428
19909
  lines.push(`${indent}if (${varName}) {`);
19429
19910
  for (const attr of slot.attrs) {
19430
19911
  lines.push(`${indent} createEffect(() => {`);
19912
+ if (attr.readsPreamble && mapPreambleWrapped) {
19913
+ lines.push(`${indent} ${mapPreambleWrapped}`);
19914
+ }
19431
19915
  for (const stmt of emitAttrUpdate(varName, attr.attrName, attr.wrappedExpression, attr.meta)) {
19432
19916
  lines.push(`${indent} ${stmt}`);
19433
19917
  }
@@ -19450,6 +19934,9 @@ function emitPreambleRegionsEffect(lines, indent, elVar, preambleRegions, mapPre
19450
19934
  }
19451
19935
  lines.push(`${indent}})`);
19452
19936
  }
19937
+ function attrsReadPreamble(attrSlots) {
19938
+ return attrSlots.some((slot) => slot.attrs.some((a) => a.readsPreamble));
19939
+ }
19453
19940
  function attrLookupExpr(slotId, varName, elVar, lookup, elementIndexBySlot) {
19454
19941
  const pIdx = elementIndexBySlot?.get(slotId);
19455
19942
  return pIdx !== undefined ? `__p ? __p[${pIdx}] : ${lookup}(${elVar}, '[bf="${slotId}"]')` : `${lookup}(${elVar}, '[bf="${slotId}"]')`;
@@ -19475,6 +19962,9 @@ function emitConsolidatedRowEffect(lines, indent, elVar, lookup, attrSlots, oute
19475
19962
  return;
19476
19963
  }
19477
19964
  lines.push(`${indent}createEffect(() => {`);
19965
+ if (mapPreambleWrapped && (preambleRegions.length > 0 || attrsReadPreamble(attrSlots))) {
19966
+ lines.push(`${indent} ${mapPreambleWrapped}`);
19967
+ }
19478
19968
  for (const slot of attrSlots) {
19479
19969
  const varName = `__ra_${varSlotId(slot.slotId)}`;
19480
19970
  lines.push(`${indent} if (${varName}) {`);
@@ -19487,9 +19977,6 @@ function emitConsolidatedRowEffect(lines, indent, elVar, lookup, attrSlots, oute
19487
19977
  }
19488
19978
  lines.push(`${indent} }`);
19489
19979
  }
19490
- if (preambleRegions.length > 0 && mapPreambleWrapped) {
19491
- lines.push(`${indent} ${mapPreambleWrapped}`);
19492
- }
19493
19980
  for (const text of outerTexts) {
19494
19981
  lines.push(`${indent} ${writer}('${text.slotId}', String(${text.wrappedExpression}))`);
19495
19982
  }
@@ -19623,9 +20110,8 @@ function stringifyLazyRowLoop(lines, o) {
19623
20110
  const { indent, lazyRow, paramHead } = o;
19624
20111
  const mid = o.markerId.replace(/[^A-Za-z0-9_$]/g, "_");
19625
20112
  const tplVar = `__tpl_${mid}`;
19626
- const claimVar = `__lzc_${mid}`;
19627
20113
  const hasRefs = lazyRow.attrSlotIds.length > 0 || lazyRow.texts.length > 0;
19628
- const hasBindings = lazyRow.attrs.length > 0 || lazyRow.texts.length > 0;
20114
+ const hasBindings = lazyRow.attrs.length > 0 || lazyRow.texts.length > 0 || lazyRow.conditionals.length > 0;
19629
20115
  const rwDoor = lazyRow.textNeedsRead;
19630
20116
  const paths = o.skeletonPaths;
19631
20117
  const useHoisted = Boolean(o.skeletonTemplate);
@@ -19655,13 +20141,10 @@ function stringifyLazyRowLoop(lines, o) {
19655
20141
  freshPlanVar = adoptedPlanVar;
19656
20142
  }
19657
20143
  }
19658
- if (hasRefs) {
19659
- const parts = refParts(lazyRow, "__el", null, adoptedPlanVar, true);
19660
- lines.push(`${indent}const ${claimVar} = (__e) => {`);
19661
- if (parts.some((p) => p.includes("__el")))
19662
- lines.push(`${indent} const __el = __e.primaryEl`);
19663
- lines.push(`${indent} return [${parts.join(", ")}]`);
19664
- lines.push(`${indent}}`);
20144
+ for (const c of lazyRow.conditionals) {
20145
+ const v = condVars(mid, c.slotId);
20146
+ emitHoistedTemplateDecl(lines, indent, v.trueTpl, c.whenTrueHtml);
20147
+ emitHoistedTemplateDecl(lines, indent, v.falseTpl, c.whenFalseHtml);
19665
20148
  }
19666
20149
  const call = `mapArrayLazy(() => ${o.arrayExpr}, ${o.containerVar}, ${o.keyFn}, {`;
19667
20150
  lines.push(`${indent}${o.guardContainer ? `if (${o.containerVar}) ` : ""}${call}`);
@@ -19669,6 +20152,8 @@ function stringifyLazyRowLoop(lines, o) {
19669
20152
  const b2 = `${indent} `;
19670
20153
  lines.push(`${b1}createRow: (__e, ${o.indexParam}) => {`);
19671
20154
  lines.push(`${b2}const ${paramHead} = () => __e.item`);
20155
+ if (lazyRow.preambleStatements)
20156
+ lines.push(`${b2}${lazyRow.preambleStatements}`);
19672
20157
  const cloneExpr = useHoisted ? hoistedCloneExpr(tplVar, o.skeletonTemplate) : `(() => { ${emitTemplateCloneInline(o.template)} })()`;
19673
20158
  lines.push(`${b2}const __el = ${cloneExpr}`);
19674
20159
  if (hasRefs) {
@@ -19682,17 +20167,23 @@ function stringifyLazyRowLoop(lines, o) {
19682
20167
  for (const t of lazyRow.texts)
19683
20168
  emitTextBinding(lines, b2, t, createDoor, "create", rwDoor);
19684
20169
  }
20170
+ for (const c of lazyRow.conditionals)
20171
+ emitConditional(lines, b2, mid, c, "create");
19685
20172
  lines.push(`${b2}return __el`);
19686
20173
  lines.push(`${b1}},`);
19687
20174
  const itemAttrs = lazyRow.attrs.filter((a) => a.readsItem);
19688
20175
  const itemTexts = lazyRow.texts.filter((t) => t.readsItem);
19689
- if (itemAttrs.length === 0 && itemTexts.length === 0) {
20176
+ const itemConds = lazyRow.conditionals.filter((c) => c.readsItem);
20177
+ if (itemAttrs.length === 0 && itemTexts.length === 0 && itemConds.length === 0) {
19690
20178
  lines.push(`${b1}applyItem: () => {},`);
19691
20179
  } else {
19692
20180
  lines.push(`${b1}applyItem: (__e) => {`);
19693
20181
  lines.push(`${b2}const ${paramHead} = () => __e.item`);
19694
- lines.push(`${b2}const __r = __e.refs ?? (__e.refs = ${claimVar}(__e))`);
20182
+ lines.push(`${b2}const __r = __e.refs ?? (__e.refs = [])`);
19695
20183
  lines.push(`${b2}const __l = __e.last ?? (__e.last = [])`);
20184
+ if (lazyRow.itemNeedsPreamble && lazyRow.preambleStatements) {
20185
+ lines.push(`${b2}${lazyRow.preambleStatements}`);
20186
+ }
19696
20187
  for (const a of itemAttrs)
19697
20188
  emitAttrBinding(lines, b2, a, "item");
19698
20189
  if (itemTexts.length > 0) {
@@ -19700,19 +20191,25 @@ function stringifyLazyRowLoop(lines, o) {
19700
20191
  for (const t of itemTexts)
19701
20192
  emitTextBinding(lines, b2, t, "__d", "item", rwDoor);
19702
20193
  }
20194
+ for (const c of itemConds)
20195
+ emitConditional(lines, b2, mid, c, "item");
19703
20196
  lines.push(`${b1}},`);
19704
20197
  }
19705
20198
  const outerAttrs = lazyRow.attrs.filter((a) => a.readsOuter);
19706
20199
  const outerTexts = lazyRow.texts.filter((t) => t.readsOuter);
19707
- if (outerAttrs.length > 0 || outerTexts.length > 0) {
20200
+ const outerConds = lazyRow.conditionals.filter((c) => c.readsOuter);
20201
+ if (outerAttrs.length > 0 || outerTexts.length > 0 || outerConds.length > 0) {
19708
20202
  const b3 = `${indent} `;
19709
20203
  lines.push(`${b1}applyOuter: (__es, __seed) => {`);
19710
20204
  for (const g of lazyRow.outerPrimeGetters)
19711
20205
  lines.push(`${b2}${g}()`);
19712
20206
  lines.push(`${b2}for (const __e of __es) {`);
19713
20207
  lines.push(`${b3}const ${paramHead} = () => __e.item`);
19714
- lines.push(`${b3}const __r = __e.refs ?? (__e.refs = ${claimVar}(__e))`);
20208
+ lines.push(`${b3}const __r = __e.refs ?? (__e.refs = [])`);
19715
20209
  lines.push(`${b3}const __l = __e.last ?? (__e.last = [])`);
20210
+ if (lazyRow.outerNeedsPreamble && lazyRow.preambleStatements) {
20211
+ lines.push(`${b3}${lazyRow.preambleStatements}`);
20212
+ }
19716
20213
  for (const a of outerAttrs)
19717
20214
  emitAttrBinding(lines, b3, a, "outer");
19718
20215
  if (outerTexts.length > 0) {
@@ -19720,22 +20217,28 @@ function stringifyLazyRowLoop(lines, o) {
19720
20217
  for (const t of outerTexts)
19721
20218
  emitTextBinding(lines, b3, t, "__d", "outer", rwDoor);
19722
20219
  }
20220
+ for (const c of outerConds)
20221
+ emitConditional(lines, b3, mid, c, "outer");
19723
20222
  lines.push(`${b2}}`);
19724
20223
  lines.push(`${b1}},`);
19725
20224
  }
19726
20225
  lines.push(`${indent}}, '${o.markerId}')`);
19727
20226
  }
19728
- function refParts(lazyRow, elVar, skeletonPaths, planVar, deferDoor = false) {
20227
+ function refParts(lazyRow, elVar, skeletonPaths, planVar) {
19729
20228
  const parts = [];
19730
20229
  for (const slotId of lazyRow.attrSlotIds) {
19731
20230
  const path = skeletonPaths?.elementPaths.get(slotId);
19732
20231
  parts.push(path ? pathExpr(elVar, path) : `qsa(${elVar}, '[bf="${slotId}"]')`);
19733
20232
  }
19734
20233
  if (lazyRow.texts.length > 0) {
19735
- parts.push(deferDoor ? "null" : `${doorCtor(lazyRow)}(${elVar}, ${planVar})`);
20234
+ parts.push(`${doorCtor(lazyRow)}(${elVar}, ${planVar})`);
19736
20235
  }
19737
20236
  return parts;
19738
20237
  }
20238
+ function elementAccess(a) {
20239
+ const slot = `__r[${a.refIndex}]`;
20240
+ return `${a.refIndex} in __r ? ${slot} : (${slot} = qsa(__e.primaryEl, '[bf="${a.slotId}"]'))`;
20241
+ }
19739
20242
  function doorCtor(lazyRow) {
19740
20243
  return lazyRow.textNeedsRead ? "lazyClaimSlots" : "lazySlots";
19741
20244
  }
@@ -19743,11 +20246,36 @@ function doorAccess(lazyRow, writerIndex, adoptedPlanVar) {
19743
20246
  const slot = `__r[${writerIndex}]`;
19744
20247
  return `${slot} ?? (${slot} = ${doorCtor(lazyRow)}(__e.primaryEl, ${adoptedPlanVar}))`;
19745
20248
  }
20249
+ function condVars(mid, slotId) {
20250
+ const key = `${mid}_${slotId.replace(/[^A-Za-z0-9_$]/g, "_")}`;
20251
+ return { trueTpl: `__cbt_${key}`, falseTpl: `__cbf_${key}` };
20252
+ }
20253
+ function emitConditional(lines, ind, mid, c, mode) {
20254
+ const v = condVars(mid, c.slotId);
20255
+ if (mode === "create") {
20256
+ lines.push(`${ind}__l[${c.ordinal}] = !!(${c.wrappedCondition})`);
20257
+ return;
20258
+ }
20259
+ const slot = `__r[${c.refIndex}]`;
20260
+ lines.push(`${ind}{ const __c = ${c.refIndex} in __r ? ${slot} : (${slot} = qsa(__e.primaryEl, '[bf-c="${c.slotId}"]'))`);
20261
+ lines.push(`${ind}if (__c) {`);
20262
+ lines.push(`${ind} const __x = !!(${c.wrappedCondition})`);
20263
+ lines.push(`${ind} const __w = (__x ? ${v.trueTpl} : ${v.falseTpl}).content.firstElementChild`);
20264
+ const guard = mode === "item" ? dedupGuard(c.ordinal) : `__seed ? (__c.outerHTML !== __w.outerHTML) : (${dedupGuard(c.ordinal)})`;
20265
+ lines.push(`${ind} if (${guard}) {`);
20266
+ lines.push(`${ind} const __n = __w.cloneNode(true)`);
20267
+ lines.push(`${ind} __c.replaceWith(__n)`);
20268
+ lines.push(`${ind} ${slot} = __n`);
20269
+ lines.push(`${ind} }`);
20270
+ lines.push(`${ind} __l[${c.ordinal}] = __x`);
20271
+ lines.push(`${ind}} }`);
20272
+ }
19746
20273
  function dedupGuard(ordinal) {
19747
20274
  return `!(${ordinal} in __l) || !Object.is(__l[${ordinal}], __x)`;
19748
20275
  }
19749
20276
  function emitAttrBinding(lines, ind, a, mode) {
19750
- lines.push(`${ind}{ const __t = __r[${a.refIndex}]`);
20277
+ const target = mode === "create" ? `__r[${a.refIndex}]` : elementAccess(a);
20278
+ lines.push(`${ind}{ const __t = ${target}`);
19751
20279
  lines.push(`${ind}if (__t) {`);
19752
20280
  lines.push(`${ind} const __x = ${a.wrappedExpression}`);
19753
20281
  const guard = mode === "create" ? null : mode === "item" ? dedupGuard(a.ordinal) : `__seed ? (${seedDiffersExpr("__t", a)}) : (${dedupGuard(a.ordinal)})`;
@@ -20227,7 +20755,8 @@ function stringifyCompositeLoop(lines, plan) {
20227
20755
  template,
20228
20756
  bodyIsMultiRoot,
20229
20757
  indent: bodyIndent,
20230
- singleRootLayout: "multiline"
20758
+ singleRootLayout: "multiline",
20759
+ mountRow: true
20231
20760
  });
20232
20761
  emitComponentAndEventSetup(lines, bodyIndent, "__el", compsArr, eventsArr, loopParam, loopParamBindings, bodyIsMultiRoot);
20233
20762
  if (innerLoops.length > 0) {
@@ -20743,7 +21272,7 @@ function buildPlainLoopPlan(elem, profileComponentName, lazyScope) {
20743
21272
  const indexParam = elem.index || "__idx";
20744
21273
  const mapPreambleWrapped = elem.preamble ? renderPreamble(elem.preamble, {
20745
21274
  transformJs: wrap,
20746
- renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, [{ param: elem.param, bindings: elem.paramBindings }], undefined, true)
21275
+ renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, [{ param: elem.param, bindings: elem.paramBindings }], undefined)
20747
21276
  }) : "";
20748
21277
  const preambleRegions = buildPreambleRegionPlans(elem.preambleRegions, elem.param, elem.paramBindings);
20749
21278
  return {
@@ -20820,7 +21349,7 @@ function buildStaticLoopMaterialize(elem, unsafeLocalNames) {
20820
21349
  return {
20821
21350
  itemTemplate: elem.staticItemTemplate,
20822
21351
  mapPreamble: elem.preamble ? renderPreamble(elem.preamble, {
20823
- renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, [{ param: elem.param, bindings: elem.paramBindings }], undefined, true)
21352
+ renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, [{ param: elem.param, bindings: elem.paramBindings }], undefined)
20824
21353
  }) : "",
20825
21354
  bodyIsMultiRoot: elem.bodyIsMultiRoot ?? false
20826
21355
  };
@@ -21057,20 +21586,20 @@ var PHASES = [
21057
21586
  ];
21058
21587
 
21059
21588
  // src/ir-to-client-js/rewrite-props-object.ts
21060
- import ts16 from "typescript";
21589
+ import ts17 from "typescript";
21061
21590
  function rewritePropsObjectRef(code, propsObjectName) {
21062
21591
  const srcPropsName = propsObjectName ?? "props";
21063
21592
  if (srcPropsName === PROPS_PARAM)
21064
21593
  return code;
21065
21594
  if (!new RegExp(`\\b${srcPropsName}\\b`).test(code))
21066
21595
  return code;
21067
- const sourceFile = ts16.createSourceFile("init-body.ts", code, ts16.ScriptTarget.Latest, true, ts16.ScriptKind.TS);
21596
+ const sourceFile = ts17.createSourceFile("init-body.ts", code, ts17.ScriptTarget.Latest, true, ts17.ScriptKind.TS);
21068
21597
  const spans = [];
21069
21598
  function visit3(node) {
21070
- if (ts16.isIdentifier(node) && node.text === srcPropsName && shouldRewrite(node)) {
21599
+ if (ts17.isIdentifier(node) && node.text === srcPropsName && shouldRewrite(node)) {
21071
21600
  spans.push([node.getStart(sourceFile), node.getEnd()]);
21072
21601
  }
21073
- ts16.forEachChild(node, visit3);
21602
+ ts17.forEachChild(node, visit3);
21074
21603
  }
21075
21604
  visit3(sourceFile);
21076
21605
  if (spans.length === 0)
@@ -21086,17 +21615,17 @@ function shouldRewrite(node) {
21086
21615
  const parent = node.parent;
21087
21616
  if (!parent)
21088
21617
  return true;
21089
- if (ts16.isPropertyAccessExpression(parent) && parent.name === node)
21618
+ if (ts17.isPropertyAccessExpression(parent) && parent.name === node)
21090
21619
  return false;
21091
- if (ts16.isPropertyAssignment(parent) && parent.name === node)
21620
+ if (ts17.isPropertyAssignment(parent) && parent.name === node)
21092
21621
  return false;
21093
- if (ts16.isShorthandPropertyAssignment(parent) && parent.name === node)
21622
+ if (ts17.isShorthandPropertyAssignment(parent) && parent.name === node)
21094
21623
  return false;
21095
- if (ts16.isPropertySignature(parent) && parent.name === node)
21624
+ if (ts17.isPropertySignature(parent) && parent.name === node)
21096
21625
  return false;
21097
- if (ts16.isPropertyDeclaration(parent) && parent.name === node)
21626
+ if (ts17.isPropertyDeclaration(parent) && parent.name === node)
21098
21627
  return false;
21099
- if (ts16.isBindingElement(parent) && parent.name === node)
21628
+ if (ts17.isBindingElement(parent) && parent.name === node)
21100
21629
  return false;
21101
21630
  return true;
21102
21631
  }
@@ -21440,7 +21969,7 @@ function generateTemplateOnlyMount(ir, ctx) {
21440
21969
  }
21441
21970
  if (!templateHtml) {
21442
21971
  const csrInlinableConstants = csrInlinableConstantsFromCtx(ctx);
21443
- templateHtml = generateCsrTemplate(ir.root, csrInlinableConstants, ctx, undefined, restSpreadNames, ctx.propsObjectName, unsafeLocalNames);
21972
+ templateHtml = generateCsrTemplate(ir.root, csrInlinableConstants, ctx, restSpreadNames, ctx.propsObjectName, unsafeLocalNames);
21444
21973
  }
21445
21974
  if (!templateHtml) {
21446
21975
  return "";
@@ -21726,7 +22255,7 @@ function walkIR2(node, visitor) {
21726
22255
  }
21727
22256
 
21728
22257
  // src/preprocess-inline-jsx-callbacks.ts
21729
- import ts17 from "typescript";
22258
+ import ts18 from "typescript";
21730
22259
  var SYNTHETIC_PREFIX = "BFInlineJsxCallback";
21731
22260
  var MAX_FIXPOINT_ITERATIONS = 16;
21732
22261
  function preprocessInlineJsxCallbacks(source, filePath) {
@@ -21748,8 +22277,8 @@ function preprocessInlineJsxCallbacks(source, filePath) {
21748
22277
  return { source: current, errors, syntheticNames };
21749
22278
  }
21750
22279
  function runSinglePass(source, filePath, startingCounter) {
21751
- const sourceFile = ts17.createSourceFile(filePath, source, ts17.ScriptTarget.Latest, true, ts17.ScriptKind.TSX);
21752
- const hasUseClient = sourceFile.statements.some((stmt) => ts17.isExpressionStatement(stmt) && ts17.isStringLiteral(stmt.expression) && (stmt.expression.text === "use client" || stmt.expression.text === "'use client'"));
22280
+ const sourceFile = ts18.createSourceFile(filePath, source, ts18.ScriptTarget.Latest, true, ts18.ScriptKind.TSX);
22281
+ const hasUseClient = sourceFile.statements.some((stmt) => ts18.isExpressionStatement(stmt) && ts18.isStringLiteral(stmt.expression) && (stmt.expression.text === "use client" || stmt.expression.text === "'use client'"));
21753
22282
  if (!hasUseClient) {
21754
22283
  return { source, errors: [], syntheticNames: [], counterAfter: startingCounter };
21755
22284
  }
@@ -21771,22 +22300,22 @@ function runSinglePass(source, filePath, startingCounter) {
21771
22300
  }
21772
22301
  }
21773
22302
  function visit3(node) {
21774
- if (ts17.isJsxAttribute(node) && node.initializer && ts17.isJsxExpression(node.initializer) && node.initializer.expression) {
22303
+ if (ts18.isJsxAttribute(node) && node.initializer && ts18.isJsxExpression(node.initializer) && node.initializer.expression) {
21775
22304
  if (tryHandleArrowValue(node.initializer.expression)) {
21776
22305
  return;
21777
22306
  }
21778
22307
  }
21779
- if (ts17.isPropertyAssignment(node) && node.initializer) {
22308
+ if (ts18.isPropertyAssignment(node) && node.initializer) {
21780
22309
  if (tryHandleArrowValue(node.initializer))
21781
22310
  return;
21782
22311
  }
21783
- ts17.forEachChild(node, visit3);
22312
+ ts18.forEachChild(node, visit3);
21784
22313
  }
21785
22314
  function tryHandleArrowValue(initializer) {
21786
22315
  let expr = initializer;
21787
- while (ts17.isParenthesizedExpression(expr))
22316
+ while (ts18.isParenthesizedExpression(expr))
21788
22317
  expr = expr.expression;
21789
- if (ts17.isArrowFunction(expr) && arrowBodyContainsJsx(expr)) {
22318
+ if (ts18.isArrowFunction(expr) && arrowBodyContainsJsx(expr)) {
21790
22319
  return handleInlineArrow(expr);
21791
22320
  }
21792
22321
  return false;
@@ -21823,7 +22352,7 @@ function runSinglePass(source, filePath, startingCounter) {
21823
22352
  replacements.push({ start: arrowStart, end: arrowEnd, text: name });
21824
22353
  return true;
21825
22354
  }
21826
- ts17.forEachChild(sourceFile, visit3);
22355
+ ts18.forEachChild(sourceFile, visit3);
21827
22356
  if (replacements.length === 0) {
21828
22357
  return { source, errors, syntheticNames, counterAfter: counter };
21829
22358
  }
@@ -21846,11 +22375,11 @@ function errorMessageForCapture(captures) {
21846
22375
  return `Inline JSX-returning arrow function captures non-module identifier(s): ` + `${captures.sort().join(", ")}. ` + `Extract the callback into a top-level '\\'use client\\'' component (e.g. ` + `\`function MyNode(n) { return <div/> }\` then \`renderNode={MyNode}\`) ` + `or pass captured values via component props.`;
21847
22376
  }
21848
22377
  function arrowBodyContainsJsx(arrow) {
21849
- if (ts17.isBlock(arrow.body)) {
22378
+ if (ts18.isBlock(arrow.body)) {
21850
22379
  return blockReturnsJsx(arrow.body);
21851
22380
  }
21852
22381
  let body = arrow.body;
21853
- while (ts17.isParenthesizedExpression(body))
22382
+ while (ts18.isParenthesizedExpression(body))
21854
22383
  body = body.expression;
21855
22384
  return isJsxLike(body);
21856
22385
  }
@@ -21859,41 +22388,41 @@ function blockReturnsJsx(block) {
21859
22388
  function visit3(n) {
21860
22389
  if (found)
21861
22390
  return;
21862
- if (ts17.isReturnStatement(n) && n.expression) {
22391
+ if (ts18.isReturnStatement(n) && n.expression) {
21863
22392
  let e = n.expression;
21864
- while (ts17.isParenthesizedExpression(e))
22393
+ while (ts18.isParenthesizedExpression(e))
21865
22394
  e = e.expression;
21866
22395
  if (isJsxLike(e)) {
21867
22396
  found = true;
21868
22397
  return;
21869
22398
  }
21870
22399
  }
21871
- if (ts17.isArrowFunction(n) || ts17.isFunctionDeclaration(n) || ts17.isFunctionExpression(n))
22400
+ if (ts18.isArrowFunction(n) || ts18.isFunctionDeclaration(n) || ts18.isFunctionExpression(n))
21872
22401
  return;
21873
- ts17.forEachChild(n, visit3);
22402
+ ts18.forEachChild(n, visit3);
21874
22403
  }
21875
- ts17.forEachChild(block, visit3);
22404
+ ts18.forEachChild(block, visit3);
21876
22405
  return found;
21877
22406
  }
21878
22407
  function isJsxLike(expr) {
21879
- return ts17.isJsxElement(expr) || ts17.isJsxSelfClosingElement(expr) || ts17.isJsxFragment(expr);
22408
+ return ts18.isJsxElement(expr) || ts18.isJsxSelfClosingElement(expr) || ts18.isJsxFragment(expr);
21880
22409
  }
21881
22410
  function collectArrowParamNames(arrow) {
21882
22411
  const names = new Set;
21883
22412
  for (const p of arrow.parameters)
21884
- collectBindingNames2(p.name, names);
22413
+ collectBindingNames3(p.name, names);
21885
22414
  return names;
21886
22415
  }
21887
- function collectBindingNames2(name, out) {
22416
+ function collectBindingNames3(name, out) {
21888
22417
  const push = Array.isArray(out) ? (n) => out.push(n) : (n) => out.add(n);
21889
- if (ts17.isIdentifier(name)) {
22418
+ if (ts18.isIdentifier(name)) {
21890
22419
  push(name.text);
21891
- } else if (ts17.isObjectBindingPattern(name)) {
21892
- name.elements.forEach((el) => collectBindingNames2(el.name, out));
21893
- } else if (ts17.isArrayBindingPattern(name)) {
22420
+ } else if (ts18.isObjectBindingPattern(name)) {
22421
+ name.elements.forEach((el) => collectBindingNames3(el.name, out));
22422
+ } else if (ts18.isArrayBindingPattern(name)) {
21894
22423
  name.elements.forEach((el) => {
21895
- if (!ts17.isOmittedExpression(el))
21896
- collectBindingNames2(el.name, out);
22424
+ if (!ts18.isOmittedExpression(el))
22425
+ collectBindingNames3(el.name, out);
21897
22426
  });
21898
22427
  }
21899
22428
  }
@@ -21902,12 +22431,12 @@ function collectFreeIdentifiers(arrow) {
21902
22431
  const bound = [];
21903
22432
  for (const p of arrow.parameters) {
21904
22433
  const names = [];
21905
- collectBindingNames2(p.name, names);
22434
+ collectBindingNames3(p.name, names);
21906
22435
  bound.push(...names);
21907
22436
  }
21908
22437
  function pushBindings(name) {
21909
22438
  const names = [];
21910
- collectBindingNames2(name, names);
22439
+ collectBindingNames3(name, names);
21911
22440
  bound.push(...names);
21912
22441
  return names;
21913
22442
  }
@@ -21919,48 +22448,48 @@ function collectFreeIdentifiers(arrow) {
21919
22448
  return bound.includes(name);
21920
22449
  }
21921
22450
  function visit3(node) {
21922
- if (ts17.isIdentifier(node)) {
22451
+ if (ts18.isIdentifier(node)) {
21923
22452
  const parent = node.parent;
21924
- if (parent && ts17.isPropertyAccessExpression(parent) && parent.name === node)
22453
+ if (parent && ts18.isPropertyAccessExpression(parent) && parent.name === node)
21925
22454
  return;
21926
- if (parent && ts17.isPropertyAssignment(parent) && parent.name === node)
22455
+ if (parent && ts18.isPropertyAssignment(parent) && parent.name === node)
21927
22456
  return;
21928
- if (parent && ts17.isPropertySignature(parent) && parent.name === node)
22457
+ if (parent && ts18.isPropertySignature(parent) && parent.name === node)
21929
22458
  return;
21930
- if (parent && ts17.isPropertyDeclaration(parent) && parent.name === node)
22459
+ if (parent && ts18.isPropertyDeclaration(parent) && parent.name === node)
21931
22460
  return;
21932
- if (parent && ts17.isMethodDeclaration(parent) && parent.name === node)
22461
+ if (parent && ts18.isMethodDeclaration(parent) && parent.name === node)
21933
22462
  return;
21934
- if (parent && ts17.isMethodSignature(parent) && parent.name === node)
22463
+ if (parent && ts18.isMethodSignature(parent) && parent.name === node)
21935
22464
  return;
21936
- if (parent && ts17.isGetAccessorDeclaration(parent) && parent.name === node)
22465
+ if (parent && ts18.isGetAccessorDeclaration(parent) && parent.name === node)
21937
22466
  return;
21938
- if (parent && ts17.isSetAccessorDeclaration(parent) && parent.name === node)
22467
+ if (parent && ts18.isSetAccessorDeclaration(parent) && parent.name === node)
21939
22468
  return;
21940
- if (parent && ts17.isEnumMember(parent) && parent.name === node)
22469
+ if (parent && ts18.isEnumMember(parent) && parent.name === node)
21941
22470
  return;
21942
- if (parent && ts17.isBindingElement(parent) && parent.propertyName === node)
22471
+ if (parent && ts18.isBindingElement(parent) && parent.propertyName === node)
21943
22472
  return;
21944
- if (parent && ts17.isShorthandPropertyAssignment(parent) && parent.name === node) {
22473
+ if (parent && ts18.isShorthandPropertyAssignment(parent) && parent.name === node) {
21945
22474
  if (!isBound(node.text))
21946
22475
  ids.add(node.text);
21947
22476
  return;
21948
22477
  }
21949
- if (parent && ts17.isParameter(parent) && parent.name === node)
22478
+ if (parent && ts18.isParameter(parent) && parent.name === node)
21950
22479
  return;
21951
- if (parent && ts17.isVariableDeclaration(parent) && parent.name === node)
22480
+ if (parent && ts18.isVariableDeclaration(parent) && parent.name === node)
21952
22481
  return;
21953
- if (parent && ts17.isFunctionDeclaration(parent) && parent.name === node)
22482
+ if (parent && ts18.isFunctionDeclaration(parent) && parent.name === node)
21954
22483
  return;
21955
- if (parent && ts17.isClassDeclaration(parent) && parent.name === node)
22484
+ if (parent && ts18.isClassDeclaration(parent) && parent.name === node)
21956
22485
  return;
21957
- if (parent && ts17.isJsxAttribute(parent) && parent.name === node)
22486
+ if (parent && ts18.isJsxAttribute(parent) && parent.name === node)
21958
22487
  return;
21959
- if (parent && ts17.isJsxOpeningElement(parent) && parent.tagName === node) {
22488
+ if (parent && ts18.isJsxOpeningElement(parent) && parent.tagName === node) {
21960
22489
  if (/^[a-z]/.test(node.text))
21961
22490
  return;
21962
22491
  }
21963
- if (parent && ts17.isJsxClosingElement(parent) && parent.tagName === node) {
22492
+ if (parent && ts18.isJsxClosingElement(parent) && parent.tagName === node) {
21964
22493
  if (/^[a-z]/.test(node.text))
21965
22494
  return;
21966
22495
  }
@@ -21969,43 +22498,43 @@ function collectFreeIdentifiers(arrow) {
21969
22498
  ids.add(node.text);
21970
22499
  return;
21971
22500
  }
21972
- if (ts17.isVariableDeclaration(node)) {
22501
+ if (ts18.isVariableDeclaration(node)) {
21973
22502
  const declared = pushBindings(node.name);
21974
22503
  if (node.initializer)
21975
22504
  visit3(node.initializer);
21976
22505
  return;
21977
22506
  }
21978
- if (ts17.isFunctionDeclaration(node)) {
22507
+ if (ts18.isFunctionDeclaration(node)) {
21979
22508
  if (node.name)
21980
22509
  bound.push(node.name.text);
21981
22510
  visitInsideNewScope(node);
21982
22511
  return;
21983
22512
  }
21984
- if (ts17.isClassDeclaration(node)) {
22513
+ if (ts18.isClassDeclaration(node)) {
21985
22514
  if (node.name)
21986
22515
  bound.push(node.name.text);
21987
- ts17.forEachChild(node, visit3);
22516
+ ts18.forEachChild(node, visit3);
21988
22517
  return;
21989
22518
  }
21990
- if (ts17.isArrowFunction(node) || ts17.isFunctionExpression(node)) {
22519
+ if (ts18.isArrowFunction(node) || ts18.isFunctionExpression(node)) {
21991
22520
  visitInsideNewScope(node);
21992
22521
  return;
21993
22522
  }
21994
- if (ts17.isCatchClause(node)) {
22523
+ if (ts18.isCatchClause(node)) {
21995
22524
  const before = bound.length;
21996
22525
  if (node.variableDeclaration)
21997
22526
  pushBindings(node.variableDeclaration.name);
21998
- ts17.forEachChild(node, visit3);
22527
+ ts18.forEachChild(node, visit3);
21999
22528
  popN(bound.length - before);
22000
22529
  return;
22001
22530
  }
22002
- if (ts17.isBlock(node)) {
22531
+ if (ts18.isBlock(node)) {
22003
22532
  const before = bound.length;
22004
- ts17.forEachChild(node, visit3);
22533
+ ts18.forEachChild(node, visit3);
22005
22534
  popN(bound.length - before);
22006
22535
  return;
22007
22536
  }
22008
- ts17.forEachChild(node, visit3);
22537
+ ts18.forEachChild(node, visit3);
22009
22538
  }
22010
22539
  function visitInsideNewScope(fn) {
22011
22540
  const before = bound.length;
@@ -22028,29 +22557,29 @@ function collectFreeIdentifiers(arrow) {
22028
22557
  function collectModuleScopeNames(sourceFile) {
22029
22558
  const names = new Set;
22030
22559
  for (const stmt of sourceFile.statements) {
22031
- if (ts17.isFunctionDeclaration(stmt) && stmt.name)
22560
+ if (ts18.isFunctionDeclaration(stmt) && stmt.name)
22032
22561
  names.add(stmt.name.text);
22033
- else if (ts17.isClassDeclaration(stmt) && stmt.name)
22562
+ else if (ts18.isClassDeclaration(stmt) && stmt.name)
22034
22563
  names.add(stmt.name.text);
22035
- else if (ts17.isVariableStatement(stmt)) {
22564
+ else if (ts18.isVariableStatement(stmt)) {
22036
22565
  for (const decl of stmt.declarationList.declarations)
22037
- collectBindingNames2(decl.name, names);
22038
- } else if (ts17.isImportDeclaration(stmt) && stmt.importClause) {
22566
+ collectBindingNames3(decl.name, names);
22567
+ } else if (ts18.isImportDeclaration(stmt) && stmt.importClause) {
22039
22568
  const ic = stmt.importClause;
22040
22569
  if (ic.name)
22041
22570
  names.add(ic.name.text);
22042
22571
  if (ic.namedBindings) {
22043
- if (ts17.isNamespaceImport(ic.namedBindings))
22572
+ if (ts18.isNamespaceImport(ic.namedBindings))
22044
22573
  names.add(ic.namedBindings.name.text);
22045
22574
  else
22046
22575
  for (const e of ic.namedBindings.elements)
22047
22576
  names.add(e.name.text);
22048
22577
  }
22049
- } else if (ts17.isTypeAliasDeclaration(stmt))
22578
+ } else if (ts18.isTypeAliasDeclaration(stmt))
22050
22579
  names.add(stmt.name.text);
22051
- else if (ts17.isInterfaceDeclaration(stmt))
22580
+ else if (ts18.isInterfaceDeclaration(stmt))
22052
22581
  names.add(stmt.name.text);
22053
- else if (ts17.isEnumDeclaration(stmt))
22582
+ else if (ts18.isEnumDeclaration(stmt))
22054
22583
  names.add(stmt.name.text);
22055
22584
  }
22056
22585
  return names;
@@ -22058,7 +22587,7 @@ function collectModuleScopeNames(sourceFile) {
22058
22587
  function buildSyntheticDeclaration(name, arrow, sourceFile) {
22059
22588
  const paramsText = arrow.parameters.length === 0 ? "" : arrow.parameters.map((p) => p.getText(sourceFile)).join(", ");
22060
22589
  let bodyText;
22061
- if (ts17.isBlock(arrow.body)) {
22590
+ if (ts18.isBlock(arrow.body)) {
22062
22591
  bodyText = arrow.body.getText(sourceFile);
22063
22592
  } else {
22064
22593
  const expr = arrow.body.getText(sourceFile);
@@ -22068,7 +22597,7 @@ function buildSyntheticDeclaration(name, arrow, sourceFile) {
22068
22597
  }
22069
22598
 
22070
22599
  // src/ssr-defaults.ts
22071
- import ts18 from "typescript";
22600
+ import ts19 from "typescript";
22072
22601
  var UNRESOLVED = Symbol("unresolved");
22073
22602
  var NO_RETURN = Symbol("no-return");
22074
22603
  function extractSsrDefaults(metadata) {
@@ -22081,11 +22610,12 @@ function extractSsrDefaults(metadata) {
22081
22610
  for (const p of metadata.propsParams) {
22082
22611
  if (p.isRest)
22083
22612
  continue;
22613
+ const callerPropName = p.sourceName ?? p.name;
22084
22614
  if (metadata.propsObjectName === null && p.defaultValue !== undefined) {
22085
22615
  const value = tryStaticEval(p.defaultValue, { bindings: {}, propsLike });
22086
- out[p.name] = { propName: p.name, value: resultToJsonable(value) };
22616
+ out[p.name] = { propName: callerPropName, value: resultToJsonable(value) };
22087
22617
  } else {
22088
- out[p.name] = { propName: p.name, value: null };
22618
+ out[p.name] = { propName: callerPropName, value: null };
22089
22619
  }
22090
22620
  }
22091
22621
  if (metadata.restPropsName) {
@@ -22144,11 +22674,11 @@ function collectPropRefs(expr, propsObjectName, out) {
22144
22674
  if (!node)
22145
22675
  return;
22146
22676
  const visit3 = (n) => {
22147
- if (ts18.isPropertyAccessExpression(n) && ts18.isIdentifier(n.expression) && n.expression.text === propsObjectName && ts18.isIdentifier(n.name)) {
22677
+ if (ts19.isPropertyAccessExpression(n) && ts19.isIdentifier(n.expression) && n.expression.text === propsObjectName && ts19.isIdentifier(n.name)) {
22148
22678
  out.add(n.name.text);
22149
22679
  return;
22150
22680
  }
22151
- ts18.forEachChild(n, visit3);
22681
+ ts19.forEachChild(n, visit3);
22152
22682
  };
22153
22683
  visit3(node);
22154
22684
  }
@@ -22169,23 +22699,23 @@ function tryStaticEval(expr, ctx) {
22169
22699
  }
22170
22700
  function evalStatementsForReturn(statements, ctx) {
22171
22701
  for (const stmt of statements) {
22172
- if (ts18.isVariableStatement(stmt)) {
22702
+ if (ts19.isVariableStatement(stmt)) {
22173
22703
  for (const d of stmt.declarationList.declarations) {
22174
- if (!ts18.isIdentifier(d.name) || !d.initializer)
22704
+ if (!ts19.isIdentifier(d.name) || !d.initializer)
22175
22705
  continue;
22176
22706
  const v = evalNode(d.initializer, ctx);
22177
22707
  if (v !== UNRESOLVED)
22178
22708
  ctx.bindings[d.name.text] = v;
22179
22709
  }
22180
- } else if (ts18.isReturnStatement(stmt)) {
22710
+ } else if (ts19.isReturnStatement(stmt)) {
22181
22711
  return stmt.expression ? evalNode(stmt.expression, ctx) : UNRESOLVED;
22182
- } else if (ts18.isIfStatement(stmt)) {
22712
+ } else if (ts19.isIfStatement(stmt)) {
22183
22713
  const cond = evalNode(stmt.expression, ctx);
22184
22714
  if (cond === UNRESOLVED)
22185
22715
  return UNRESOLVED;
22186
22716
  const branch = cond ? stmt.thenStatement : stmt.elseStatement;
22187
22717
  if (branch) {
22188
- const taken = evalStatementsForReturn(ts18.isBlock(branch) ? branch.statements : [branch], ctx);
22718
+ const taken = evalStatementsForReturn(ts19.isBlock(branch) ? branch.statements : [branch], ctx);
22189
22719
  if (taken !== NO_RETURN)
22190
22720
  return taken;
22191
22721
  }
@@ -22196,45 +22726,45 @@ function evalStatementsForReturn(statements, ctx) {
22196
22726
  return NO_RETURN;
22197
22727
  }
22198
22728
  function parseExpression2(expr) {
22199
- const sf = ts18.createSourceFile("__ssr_default__.ts", `(${expr})`, ts18.ScriptTarget.Latest, false, ts18.ScriptKind.TS);
22729
+ const sf = ts19.createSourceFile("__ssr_default__.ts", `(${expr})`, ts19.ScriptTarget.Latest, false, ts19.ScriptKind.TS);
22200
22730
  const stmt = sf.statements[0];
22201
- if (!stmt || !ts18.isExpressionStatement(stmt))
22731
+ if (!stmt || !ts19.isExpressionStatement(stmt))
22202
22732
  return null;
22203
- const inner = ts18.isParenthesizedExpression(stmt.expression) ? stmt.expression.expression : stmt.expression;
22733
+ const inner = ts19.isParenthesizedExpression(stmt.expression) ? stmt.expression.expression : stmt.expression;
22204
22734
  return inner;
22205
22735
  }
22206
22736
  function evalNode(node, ctx) {
22207
- if (ts18.isParenthesizedExpression(node))
22737
+ if (ts19.isParenthesizedExpression(node))
22208
22738
  return evalNode(node.expression, ctx);
22209
- if (ts18.isAsExpression(node))
22739
+ if (ts19.isAsExpression(node))
22210
22740
  return evalNode(node.expression, ctx);
22211
- if (ts18.isSatisfiesExpression(node))
22741
+ if (ts19.isSatisfiesExpression(node))
22212
22742
  return evalNode(node.expression, ctx);
22213
- if (ts18.isTypeAssertionExpression(node))
22743
+ if (ts19.isTypeAssertionExpression(node))
22214
22744
  return evalNode(node.expression, ctx);
22215
- if (ts18.isNonNullExpression(node))
22745
+ if (ts19.isNonNullExpression(node))
22216
22746
  return evalNode(node.expression, ctx);
22217
- if (ts18.isArrowFunction(node)) {
22747
+ if (ts19.isArrowFunction(node)) {
22218
22748
  if (node.parameters.length !== 0)
22219
22749
  return UNRESOLVED;
22220
- if (!ts18.isBlock(node.body))
22750
+ if (!ts19.isBlock(node.body))
22221
22751
  return evalNode(node.body, ctx);
22222
22752
  const localBindings = { ...ctx.bindings };
22223
22753
  const localCtx = { ...ctx, bindings: localBindings };
22224
22754
  const result = evalStatementsForReturn(node.body.statements, localCtx);
22225
22755
  return result === NO_RETURN ? UNRESOLVED : result;
22226
22756
  }
22227
- if (ts18.isNumericLiteral(node))
22757
+ if (ts19.isNumericLiteral(node))
22228
22758
  return Number(node.text);
22229
- if (ts18.isStringLiteralLike(node))
22759
+ if (ts19.isStringLiteralLike(node))
22230
22760
  return node.text;
22231
- if (node.kind === ts18.SyntaxKind.TrueKeyword)
22761
+ if (node.kind === ts19.SyntaxKind.TrueKeyword)
22232
22762
  return true;
22233
- if (node.kind === ts18.SyntaxKind.FalseKeyword)
22763
+ if (node.kind === ts19.SyntaxKind.FalseKeyword)
22234
22764
  return false;
22235
- if (node.kind === ts18.SyntaxKind.NullKeyword)
22765
+ if (node.kind === ts19.SyntaxKind.NullKeyword)
22236
22766
  return null;
22237
- if (ts18.isIdentifier(node)) {
22767
+ if (ts19.isIdentifier(node)) {
22238
22768
  if (node.text === "undefined")
22239
22769
  return;
22240
22770
  if (node.text in ctx.bindings)
@@ -22243,29 +22773,29 @@ function evalNode(node, ctx) {
22243
22773
  return;
22244
22774
  return UNRESOLVED;
22245
22775
  }
22246
- if (ts18.isPrefixUnaryExpression(node)) {
22776
+ if (ts19.isPrefixUnaryExpression(node)) {
22247
22777
  const arg = evalNode(node.operand, ctx);
22248
22778
  if (arg === UNRESOLVED)
22249
22779
  return UNRESOLVED;
22250
22780
  switch (node.operator) {
22251
- case ts18.SyntaxKind.MinusToken:
22781
+ case ts19.SyntaxKind.MinusToken:
22252
22782
  return typeof arg === "number" ? -arg : UNRESOLVED;
22253
- case ts18.SyntaxKind.PlusToken:
22783
+ case ts19.SyntaxKind.PlusToken:
22254
22784
  return typeof arg === "number" ? +arg : UNRESOLVED;
22255
- case ts18.SyntaxKind.ExclamationToken:
22785
+ case ts19.SyntaxKind.ExclamationToken:
22256
22786
  return !arg;
22257
22787
  }
22258
22788
  return UNRESOLVED;
22259
22789
  }
22260
- if (ts18.isObjectLiteralExpression(node)) {
22790
+ if (ts19.isObjectLiteralExpression(node)) {
22261
22791
  const obj = {};
22262
22792
  for (const prop of node.properties) {
22263
- if (!ts18.isPropertyAssignment(prop))
22793
+ if (!ts19.isPropertyAssignment(prop))
22264
22794
  return UNRESOLVED;
22265
22795
  let key;
22266
- if (ts18.isIdentifier(prop.name) || ts18.isStringLiteralLike(prop.name)) {
22796
+ if (ts19.isIdentifier(prop.name) || ts19.isStringLiteralLike(prop.name)) {
22267
22797
  key = prop.name.text;
22268
- } else if (ts18.isNumericLiteral(prop.name)) {
22798
+ } else if (ts19.isNumericLiteral(prop.name)) {
22269
22799
  key = prop.name.text;
22270
22800
  } else {
22271
22801
  return UNRESOLVED;
@@ -22277,10 +22807,10 @@ function evalNode(node, ctx) {
22277
22807
  }
22278
22808
  return obj;
22279
22809
  }
22280
- if (ts18.isArrayLiteralExpression(node)) {
22810
+ if (ts19.isArrayLiteralExpression(node)) {
22281
22811
  const arr = [];
22282
22812
  for (const elem of node.elements) {
22283
- if (ts18.isOmittedExpression(elem))
22813
+ if (ts19.isOmittedExpression(elem))
22284
22814
  return UNRESOLVED;
22285
22815
  const v = evalNode(elem, ctx);
22286
22816
  if (v === UNRESOLVED)
@@ -22289,7 +22819,7 @@ function evalNode(node, ctx) {
22289
22819
  }
22290
22820
  return arr;
22291
22821
  }
22292
- if (ts18.isElementAccessExpression(node)) {
22822
+ if (ts19.isElementAccessExpression(node)) {
22293
22823
  const base = evalNode(node.expression, ctx);
22294
22824
  if (base === undefined)
22295
22825
  return;
@@ -22303,17 +22833,17 @@ function evalNode(node, ctx) {
22303
22833
  const k = String(key);
22304
22834
  return Object.prototype.hasOwnProperty.call(base, k) ? base[k] : undefined;
22305
22835
  }
22306
- if (ts18.isPropertyAccessExpression(node)) {
22836
+ if (ts19.isPropertyAccessExpression(node)) {
22307
22837
  const baseResult = evalNode(node.expression, ctx);
22308
22838
  if (baseResult === undefined)
22309
22839
  return;
22310
22840
  return UNRESOLVED;
22311
22841
  }
22312
- if (ts18.isCallExpression(node)) {
22313
- if (node.arguments.length === 0 && ts18.isIdentifier(node.expression) && node.expression.text in ctx.bindings) {
22842
+ if (ts19.isCallExpression(node)) {
22843
+ if (node.arguments.length === 0 && ts19.isIdentifier(node.expression) && node.expression.text in ctx.bindings) {
22314
22844
  return ctx.bindings[node.expression.text];
22315
22845
  }
22316
- if (ts18.isPropertyAccessExpression(node.expression) && node.expression.name.text === "join") {
22846
+ if (ts19.isPropertyAccessExpression(node.expression) && node.expression.name.text === "join") {
22317
22847
  const recv = evalNode(node.expression.expression, ctx);
22318
22848
  if (Array.isArray(recv)) {
22319
22849
  let sep2 = ",";
@@ -22329,27 +22859,27 @@ function evalNode(node, ctx) {
22329
22859
  }
22330
22860
  return UNRESOLVED;
22331
22861
  }
22332
- if (ts18.isConditionalExpression(node)) {
22862
+ if (ts19.isConditionalExpression(node)) {
22333
22863
  const cond = evalNode(node.condition, ctx);
22334
22864
  if (cond === UNRESOLVED)
22335
22865
  return UNRESOLVED;
22336
22866
  return cond ? evalNode(node.whenTrue, ctx) : evalNode(node.whenFalse, ctx);
22337
22867
  }
22338
- if (ts18.isBinaryExpression(node)) {
22868
+ if (ts19.isBinaryExpression(node)) {
22339
22869
  const op = node.operatorToken.kind;
22340
- if (op === ts18.SyntaxKind.QuestionQuestionToken) {
22870
+ if (op === ts19.SyntaxKind.QuestionQuestionToken) {
22341
22871
  const l2 = evalNode(node.left, ctx);
22342
22872
  if (l2 !== UNRESOLVED && l2 !== null && l2 !== undefined)
22343
22873
  return l2;
22344
22874
  return evalNode(node.right, ctx);
22345
22875
  }
22346
- if (op === ts18.SyntaxKind.BarBarToken) {
22876
+ if (op === ts19.SyntaxKind.BarBarToken) {
22347
22877
  const l2 = evalNode(node.left, ctx);
22348
22878
  if (l2 !== UNRESOLVED && l2)
22349
22879
  return l2;
22350
22880
  return evalNode(node.right, ctx);
22351
22881
  }
22352
- if (op === ts18.SyntaxKind.AmpersandAmpersandToken) {
22882
+ if (op === ts19.SyntaxKind.AmpersandAmpersandToken) {
22353
22883
  const l2 = evalNode(node.left, ctx);
22354
22884
  if (l2 === UNRESOLVED)
22355
22885
  return UNRESOLVED;
@@ -22362,30 +22892,30 @@ function evalNode(node, ctx) {
22362
22892
  if (l === UNRESOLVED || r === UNRESOLVED)
22363
22893
  return UNRESOLVED;
22364
22894
  switch (op) {
22365
- case ts18.SyntaxKind.PlusToken:
22895
+ case ts19.SyntaxKind.PlusToken:
22366
22896
  if (typeof l === "string" || typeof r === "string")
22367
22897
  return `${l}${r}`;
22368
22898
  if (typeof l === "number" && typeof r === "number")
22369
22899
  return l + r;
22370
22900
  return UNRESOLVED;
22371
- case ts18.SyntaxKind.MinusToken:
22901
+ case ts19.SyntaxKind.MinusToken:
22372
22902
  return typeof l === "number" && typeof r === "number" ? l - r : UNRESOLVED;
22373
- case ts18.SyntaxKind.AsteriskToken:
22903
+ case ts19.SyntaxKind.AsteriskToken:
22374
22904
  return typeof l === "number" && typeof r === "number" ? l * r : UNRESOLVED;
22375
- case ts18.SyntaxKind.SlashToken:
22905
+ case ts19.SyntaxKind.SlashToken:
22376
22906
  return typeof l === "number" && typeof r === "number" && r !== 0 ? l / r : UNRESOLVED;
22377
- case ts18.SyntaxKind.PercentToken:
22907
+ case ts19.SyntaxKind.PercentToken:
22378
22908
  return typeof l === "number" && typeof r === "number" && r !== 0 ? l % r : UNRESOLVED;
22379
- case ts18.SyntaxKind.EqualsEqualsEqualsToken:
22380
- case ts18.SyntaxKind.EqualsEqualsToken:
22909
+ case ts19.SyntaxKind.EqualsEqualsEqualsToken:
22910
+ case ts19.SyntaxKind.EqualsEqualsToken:
22381
22911
  return l === r;
22382
- case ts18.SyntaxKind.ExclamationEqualsEqualsToken:
22383
- case ts18.SyntaxKind.ExclamationEqualsToken:
22912
+ case ts19.SyntaxKind.ExclamationEqualsEqualsToken:
22913
+ case ts19.SyntaxKind.ExclamationEqualsToken:
22384
22914
  return l !== r;
22385
22915
  }
22386
22916
  return UNRESOLVED;
22387
22917
  }
22388
- if (ts18.isTemplateExpression(node)) {
22918
+ if (ts19.isTemplateExpression(node)) {
22389
22919
  if (node.templateSpans.length === 0)
22390
22920
  return node.head.text;
22391
22921
  let acc = node.head.text;
@@ -22397,13 +22927,13 @@ function evalNode(node, ctx) {
22397
22927
  }
22398
22928
  return acc;
22399
22929
  }
22400
- if (ts18.isNoSubstitutionTemplateLiteral(node))
22930
+ if (ts19.isNoSubstitutionTemplateLiteral(node))
22401
22931
  return node.text;
22402
22932
  return UNRESOLVED;
22403
22933
  }
22404
22934
 
22405
22935
  // src/augment-inherited-props.ts
22406
- import ts19 from "typescript";
22936
+ import ts20 from "typescript";
22407
22937
  function collectContextConsumers(metadata) {
22408
22938
  const constants = metadata.localConstants ?? [];
22409
22939
  const contextDefaults = new Map;
@@ -22435,47 +22965,47 @@ function collectContextConsumers(metadata) {
22435
22965
  }
22436
22966
  function parseUseContextArg(source) {
22437
22967
  const expr = parseSingleExpression(source);
22438
- if (!expr || !ts19.isCallExpression(expr))
22968
+ if (!expr || !ts20.isCallExpression(expr))
22439
22969
  return null;
22440
- if (!ts19.isIdentifier(expr.expression) || expr.expression.text !== "useContext")
22970
+ if (!ts20.isIdentifier(expr.expression) || expr.expression.text !== "useContext")
22441
22971
  return null;
22442
22972
  if (expr.arguments.length !== 1)
22443
22973
  return null;
22444
22974
  const arg = expr.arguments[0];
22445
- return ts19.isIdentifier(arg) ? arg.text : null;
22975
+ return ts20.isIdentifier(arg) ? arg.text : null;
22446
22976
  }
22447
22977
  function parseCreateContextDefault(source) {
22448
22978
  const expr = parseSingleExpression(source);
22449
- if (!expr || !ts19.isCallExpression(expr))
22979
+ if (!expr || !ts20.isCallExpression(expr))
22450
22980
  return null;
22451
22981
  if (expr.arguments.length === 0)
22452
22982
  return null;
22453
22983
  const arg = expr.arguments[0];
22454
- if (ts19.isStringLiteral(arg) || ts19.isNoSubstitutionTemplateLiteral(arg))
22984
+ if (ts20.isStringLiteral(arg) || ts20.isNoSubstitutionTemplateLiteral(arg))
22455
22985
  return arg.text;
22456
- if (ts19.isNumericLiteral(arg))
22986
+ if (ts20.isNumericLiteral(arg))
22457
22987
  return Number(arg.text);
22458
- if (arg.kind === ts19.SyntaxKind.TrueKeyword)
22988
+ if (arg.kind === ts20.SyntaxKind.TrueKeyword)
22459
22989
  return true;
22460
- if (arg.kind === ts19.SyntaxKind.FalseKeyword)
22990
+ if (arg.kind === ts20.SyntaxKind.FalseKeyword)
22461
22991
  return false;
22462
22992
  return null;
22463
22993
  }
22464
22994
  function isObjectLiteralCreateContextDefault(source) {
22465
22995
  const expr = parseSingleExpression(source);
22466
- if (!expr || !ts19.isCallExpression(expr))
22996
+ if (!expr || !ts20.isCallExpression(expr))
22467
22997
  return false;
22468
22998
  if (expr.arguments.length === 0)
22469
22999
  return false;
22470
- return ts19.isObjectLiteralExpression(expr.arguments[0]);
23000
+ return ts20.isObjectLiteralExpression(expr.arguments[0]);
22471
23001
  }
22472
23002
  function parseSingleExpression(source) {
22473
- const sf = ts19.createSourceFile("__ctx.ts", `(${source})`, ts19.ScriptTarget.Latest, false);
23003
+ const sf = ts20.createSourceFile("__ctx.ts", `(${source})`, ts20.ScriptTarget.Latest, false);
22474
23004
  const stmt = sf.statements[0];
22475
- if (!stmt || !ts19.isExpressionStatement(stmt))
23005
+ if (!stmt || !ts20.isExpressionStatement(stmt))
22476
23006
  return null;
22477
23007
  let e = stmt.expression;
22478
- while (ts19.isParenthesizedExpression(e))
23008
+ while (ts20.isParenthesizedExpression(e))
22479
23009
  e = e.expression;
22480
23010
  return e;
22481
23011
  }
@@ -22500,25 +23030,25 @@ function augmentInheritedPropAccesses(ir) {
22500
23030
  const pinCoalesceLiterals = (s) => {
22501
23031
  if (!s || !s.includes(propsObj))
22502
23032
  return;
22503
- const sf = ts19.createSourceFile("__aug.ts", `(${s})`, ts19.ScriptTarget.Latest, false);
23033
+ const sf = ts20.createSourceFile("__aug.ts", `(${s})`, ts20.ScriptTarget.Latest, false);
22504
23034
  const visit3 = (n) => {
22505
- if (ts19.isBinaryExpression(n) && (n.operatorToken.kind === ts19.SyntaxKind.QuestionQuestionToken || n.operatorToken.kind === ts19.SyntaxKind.BarBarToken)) {
23035
+ if (ts20.isBinaryExpression(n) && (n.operatorToken.kind === ts20.SyntaxKind.QuestionQuestionToken || n.operatorToken.kind === ts20.SyntaxKind.BarBarToken)) {
22506
23036
  let left = n.left;
22507
- while (ts19.isParenthesizedExpression(left))
23037
+ while (ts20.isParenthesizedExpression(left))
22508
23038
  left = left.expression;
22509
- if (ts19.isPropertyAccessExpression(left) && ts19.isIdentifier(left.expression) && left.expression.text === propsObj) {
23039
+ if (ts20.isPropertyAccessExpression(left) && ts20.isIdentifier(left.expression) && left.expression.text === propsObj) {
22510
23040
  const name = left.name.text;
22511
23041
  let right = n.right;
22512
- while (ts19.isParenthesizedExpression(right))
23042
+ while (ts20.isParenthesizedExpression(right))
22513
23043
  right = right.expression;
22514
- if (ts19.isPrefixUnaryExpression(right))
23044
+ if (ts20.isPrefixUnaryExpression(right))
22515
23045
  right = right.operand;
22516
- const kind = ts19.isNumericLiteral(right) ? "number" : right.kind === ts19.SyntaxKind.TrueKeyword || right.kind === ts19.SyntaxKind.FalseKeyword ? "boolean" : ts19.isStringLiteralLike(right) ? "string" : null;
23046
+ const kind = ts20.isNumericLiteral(right) ? "number" : right.kind === ts20.SyntaxKind.TrueKeyword || right.kind === ts20.SyntaxKind.FalseKeyword ? "boolean" : ts20.isStringLiteralLike(right) ? "string" : null;
22517
23047
  if (kind && !coalesceLiteralTypes.has(name))
22518
23048
  coalesceLiteralTypes.set(name, kind);
22519
23049
  }
22520
23050
  }
22521
- ts19.forEachChild(n, visit3);
23051
+ ts20.forEachChild(n, visit3);
22522
23052
  };
22523
23053
  visit3(sf);
22524
23054
  };
@@ -22629,33 +23159,33 @@ function augmentInheritedPropAccesses(ir) {
22629
23159
  }
22630
23160
  }
22631
23161
  function parseStaticStringConst(source) {
22632
- const sf = ts19.createSourceFile("__const.ts", `const __x = (${source});`, ts19.ScriptTarget.Latest, false);
23162
+ const sf = ts20.createSourceFile("__const.ts", `const __x = (${source});`, ts20.ScriptTarget.Latest, false);
22633
23163
  const stmt = sf.statements[0];
22634
- if (!stmt || !ts19.isVariableStatement(stmt))
23164
+ if (!stmt || !ts20.isVariableStatement(stmt))
22635
23165
  return null;
22636
23166
  let init = stmt.declarationList.declarations[0]?.initializer;
22637
- while (init && ts19.isParenthesizedExpression(init))
23167
+ while (init && ts20.isParenthesizedExpression(init))
22638
23168
  init = init.expression;
22639
23169
  if (!init)
22640
23170
  return null;
22641
- if (ts19.isStringLiteral(init) || ts19.isNoSubstitutionTemplateLiteral(init)) {
23171
+ if (ts20.isStringLiteral(init) || ts20.isNoSubstitutionTemplateLiteral(init)) {
22642
23172
  return init.text;
22643
23173
  }
22644
23174
  return evalStringArrayJoin(source);
22645
23175
  }
22646
23176
  function evalTemplateOfStringConsts(source, resolved) {
22647
- const sf = ts19.createSourceFile("__const.ts", `const __x = (${source});`, ts19.ScriptTarget.Latest, false);
23177
+ const sf = ts20.createSourceFile("__const.ts", `const __x = (${source});`, ts20.ScriptTarget.Latest, false);
22648
23178
  const stmt = sf.statements[0];
22649
- if (!stmt || !ts19.isVariableStatement(stmt))
23179
+ if (!stmt || !ts20.isVariableStatement(stmt))
22650
23180
  return null;
22651
23181
  let init = stmt.declarationList.declarations[0]?.initializer;
22652
- while (init && ts19.isParenthesizedExpression(init))
23182
+ while (init && ts20.isParenthesizedExpression(init))
22653
23183
  init = init.expression;
22654
- if (!init || !ts19.isTemplateExpression(init))
23184
+ if (!init || !ts20.isTemplateExpression(init))
22655
23185
  return null;
22656
23186
  let out = init.head.text;
22657
23187
  for (const span of init.templateSpans) {
22658
- if (!ts19.isIdentifier(span.expression))
23188
+ if (!ts20.isIdentifier(span.expression))
22659
23189
  return null;
22660
23190
  const value = resolved.get(span.expression.text);
22661
23191
  if (value === undefined)
@@ -22686,30 +23216,30 @@ function lookupStaticRecordLiteral(objectName, key, constants) {
22686
23216
  const constInfo = (constants ?? []).find((c) => c.name === objectName && c.isModule);
22687
23217
  if (constInfo?.value === undefined)
22688
23218
  return null;
22689
- const sf = ts19.createSourceFile("__rec.ts", `(${constInfo.value})`, ts19.ScriptTarget.Latest, true);
23219
+ const sf = ts20.createSourceFile("__rec.ts", `(${constInfo.value})`, ts20.ScriptTarget.Latest, true);
22690
23220
  if (sf.statements.length !== 1)
22691
23221
  return null;
22692
23222
  const stmt = sf.statements[0];
22693
- if (!ts19.isExpressionStatement(stmt))
23223
+ if (!ts20.isExpressionStatement(stmt))
22694
23224
  return null;
22695
23225
  let parsed = stmt.expression;
22696
- while (ts19.isParenthesizedExpression(parsed))
23226
+ while (ts20.isParenthesizedExpression(parsed))
22697
23227
  parsed = parsed.expression;
22698
- if (!ts19.isObjectLiteralExpression(parsed))
23228
+ if (!ts20.isObjectLiteralExpression(parsed))
22699
23229
  return null;
22700
23230
  for (const prop of parsed.properties) {
22701
- if (!ts19.isPropertyAssignment(prop))
23231
+ if (!ts20.isPropertyAssignment(prop))
22702
23232
  continue;
22703
23233
  const name = prop.name;
22704
- const propKey = ts19.isIdentifier(name) || ts19.isStringLiteral(name) || ts19.isNoSubstitutionTemplateLiteral(name) ? name.text : null;
23234
+ const propKey = ts20.isIdentifier(name) || ts20.isStringLiteral(name) || ts20.isNoSubstitutionTemplateLiteral(name) ? name.text : null;
22705
23235
  if (propKey !== key)
22706
23236
  continue;
22707
23237
  let v = prop.initializer;
22708
- while (ts19.isParenthesizedExpression(v))
23238
+ while (ts20.isParenthesizedExpression(v))
22709
23239
  v = v.expression;
22710
- if (ts19.isNumericLiteral(v))
23240
+ if (ts20.isNumericLiteral(v))
22711
23241
  return { kind: "number", text: v.text };
22712
- if (ts19.isStringLiteral(v) || ts19.isNoSubstitutionTemplateLiteral(v)) {
23242
+ if (ts20.isStringLiteral(v) || ts20.isNoSubstitutionTemplateLiteral(v)) {
22713
23243
  return { kind: "string", text: v.text };
22714
23244
  }
22715
23245
  return null;
@@ -22717,28 +23247,28 @@ function lookupStaticRecordLiteral(objectName, key, constants) {
22717
23247
  return null;
22718
23248
  }
22719
23249
  function evalStringArrayJoin(source) {
22720
- const sf = ts19.createSourceFile("__join.ts", `const __x = (${source});`, ts19.ScriptTarget.Latest, false);
23250
+ const sf = ts20.createSourceFile("__join.ts", `const __x = (${source});`, ts20.ScriptTarget.Latest, false);
22721
23251
  const stmt = sf.statements[0];
22722
- if (!stmt || !ts19.isVariableStatement(stmt))
23252
+ if (!stmt || !ts20.isVariableStatement(stmt))
22723
23253
  return null;
22724
23254
  let node = stmt.declarationList.declarations[0]?.initializer;
22725
- while (node && ts19.isParenthesizedExpression(node))
23255
+ while (node && ts20.isParenthesizedExpression(node))
22726
23256
  node = node.expression;
22727
- if (!node || !ts19.isCallExpression(node))
23257
+ if (!node || !ts20.isCallExpression(node))
22728
23258
  return null;
22729
23259
  const callee = node.expression;
22730
- if (!ts19.isPropertyAccessExpression(callee))
23260
+ if (!ts20.isPropertyAccessExpression(callee))
22731
23261
  return null;
22732
23262
  if (callee.name.text !== "join")
22733
23263
  return null;
22734
23264
  let recv = callee.expression;
22735
- while (ts19.isParenthesizedExpression(recv))
23265
+ while (ts20.isParenthesizedExpression(recv))
22736
23266
  recv = recv.expression;
22737
- if (!ts19.isArrayLiteralExpression(recv))
23267
+ if (!ts20.isArrayLiteralExpression(recv))
22738
23268
  return null;
22739
23269
  const parts = [];
22740
23270
  for (const el of recv.elements) {
22741
- if (ts19.isStringLiteral(el) || ts19.isNoSubstitutionTemplateLiteral(el)) {
23271
+ if (ts20.isStringLiteral(el) || ts20.isNoSubstitutionTemplateLiteral(el)) {
22742
23272
  parts.push(el.text);
22743
23273
  } else {
22744
23274
  return null;
@@ -22747,7 +23277,7 @@ function evalStringArrayJoin(source) {
22747
23277
  let sep2 = ",";
22748
23278
  if (node.arguments.length >= 1) {
22749
23279
  const arg = node.arguments[0];
22750
- if (ts19.isStringLiteral(arg) || ts19.isNoSubstitutionTemplateLiteral(arg))
23280
+ if (ts20.isStringLiteral(arg) || ts20.isNoSubstitutionTemplateLiteral(arg))
22751
23281
  sep2 = arg.text;
22752
23282
  else
22753
23283
  return null;
@@ -22755,11 +23285,11 @@ function evalStringArrayJoin(source) {
22755
23285
  return parts.join(sep2);
22756
23286
  }
22757
23287
  function parseRecordIndexAccess(val, localConstants, propsParams, resolveKey) {
22758
- if (!ts19.isElementAccessExpression(val))
23288
+ if (!ts20.isElementAccessExpression(val))
22759
23289
  return null;
22760
23290
  const obj = val.expression;
22761
23291
  const arg = val.argumentExpression;
22762
- if (!ts19.isIdentifier(obj) || !ts19.isIdentifier(arg))
23292
+ if (!ts20.isIdentifier(obj) || !ts20.isIdentifier(arg))
22763
23293
  return null;
22764
23294
  let indexPropName;
22765
23295
  let defaultKey;
@@ -22775,35 +23305,35 @@ function parseRecordIndexAccess(val, localConstants, propsParams, resolveKey) {
22775
23305
  const constInfo = localConstants.find((c) => c.name === obj.text && c.isModule);
22776
23306
  if (constInfo?.value === undefined)
22777
23307
  return null;
22778
- const sf = ts19.createSourceFile("__rec.ts", `(${constInfo.value})`, ts19.ScriptTarget.Latest, true);
23308
+ const sf = ts20.createSourceFile("__rec.ts", `(${constInfo.value})`, ts20.ScriptTarget.Latest, true);
22779
23309
  if (sf.statements.length !== 1)
22780
23310
  return null;
22781
23311
  const stmt = sf.statements[0];
22782
- if (!ts19.isExpressionStatement(stmt))
23312
+ if (!ts20.isExpressionStatement(stmt))
22783
23313
  return null;
22784
23314
  let parsed = stmt.expression;
22785
- while (ts19.isParenthesizedExpression(parsed))
23315
+ while (ts20.isParenthesizedExpression(parsed))
22786
23316
  parsed = parsed.expression;
22787
- if (!ts19.isObjectLiteralExpression(parsed))
23317
+ if (!ts20.isObjectLiteralExpression(parsed))
22788
23318
  return null;
22789
23319
  const entries = [];
22790
23320
  for (const prop of parsed.properties) {
22791
- if (!ts19.isPropertyAssignment(prop))
23321
+ if (!ts20.isPropertyAssignment(prop))
22792
23322
  return null;
22793
23323
  let key;
22794
- if (ts19.isIdentifier(prop.name)) {
23324
+ if (ts20.isIdentifier(prop.name)) {
22795
23325
  key = prop.name.text;
22796
- } else if (ts19.isStringLiteral(prop.name) || ts19.isNoSubstitutionTemplateLiteral(prop.name)) {
23326
+ } else if (ts20.isStringLiteral(prop.name) || ts20.isNoSubstitutionTemplateLiteral(prop.name)) {
22797
23327
  key = prop.name.text;
22798
23328
  } else {
22799
23329
  return null;
22800
23330
  }
22801
23331
  let v = prop.initializer;
22802
- while (ts19.isParenthesizedExpression(v))
23332
+ while (ts20.isParenthesizedExpression(v))
22803
23333
  v = v.expression;
22804
- if (ts19.isNumericLiteral(v)) {
23334
+ if (ts20.isNumericLiteral(v)) {
22805
23335
  entries.push({ key, value: { kind: "number", text: v.text } });
22806
- } else if (ts19.isStringLiteral(v) || ts19.isNoSubstitutionTemplateLiteral(v)) {
23336
+ } else if (ts20.isStringLiteral(v) || ts20.isNoSubstitutionTemplateLiteral(v)) {
22807
23337
  entries.push({ key, value: { kind: "string", text: v.text } });
22808
23338
  } else {
22809
23339
  return null;
@@ -23586,7 +24116,7 @@ function compileJSX(source, filePath, options) {
23586
24116
  return { files, errors };
23587
24117
  }
23588
24118
  // src/shared-program.ts
23589
- import ts20 from "typescript";
24119
+ import ts21 from "typescript";
23590
24120
  function commonParent(paths) {
23591
24121
  if (paths.length === 0)
23592
24122
  return process.cwd();
@@ -23607,10 +24137,10 @@ function commonParent(paths) {
23607
24137
  function createProgramForCorpus(files, options = {}) {
23608
24138
  const baseUrl = options.baseUrl ?? commonParent(files);
23609
24139
  const compilerOptions = {
23610
- target: ts20.ScriptTarget.Latest,
23611
- module: ts20.ModuleKind.ESNext,
23612
- moduleResolution: ts20.ModuleResolutionKind.Bundler,
23613
- jsx: ts20.JsxEmit.ReactJSX,
24140
+ target: ts21.ScriptTarget.Latest,
24141
+ module: ts21.ModuleKind.ESNext,
24142
+ moduleResolution: ts21.ModuleResolutionKind.Bundler,
24143
+ jsx: ts21.JsxEmit.ReactJSX,
23614
24144
  strict: true,
23615
24145
  skipLibCheck: true,
23616
24146
  noEmit: true,
@@ -23620,7 +24150,7 @@ function createProgramForCorpus(files, options = {}) {
23620
24150
  ...options.compilerOptions
23621
24151
  };
23622
24152
  const absolute = files.map((f) => path_default.resolve(f));
23623
- return ts20.createProgram(absolute, compilerOptions, undefined, options.oldProgram);
24153
+ return ts21.createProgram(absolute, compilerOptions, undefined, options.oldProgram);
23624
24154
  }
23625
24155
  // src/adapters/interface.ts
23626
24156
  class BaseAdapter {
@@ -24175,6 +24705,8 @@ function collectLoopBoundNames(ir) {
24175
24705
  names.add(binding.name);
24176
24706
  if (node.filterPredicate)
24177
24707
  names.add(node.filterPredicate.param);
24708
+ for (const name of node.preamble?.declaredNames ?? [])
24709
+ names.add(name);
24178
24710
  for (const child of node.children)
24179
24711
  visit3(child);
24180
24712
  if (node.childComponent) {
@@ -24602,7 +25134,7 @@ function dangerousInnerHtmlDiagnostic(expr, loc, reason) {
24602
25134
  };
24603
25135
  }
24604
25136
  // src/combine-client-js.ts
24605
- import ts21 from "typescript";
25137
+ import ts22 from "typescript";
24606
25138
  var CHILD_PLACEHOLDER_RE = /import '\/\* @bf-child:(\w+) \*\/'/g;
24607
25139
  function combineParentChildClientJs(files) {
24608
25140
  const result = new Map;
@@ -24659,10 +25191,10 @@ function combineParentChildClientJs(files) {
24659
25191
  return result;
24660
25192
  }
24661
25193
  function parseAndMerge(content, importsBySource, otherImports, codeSections) {
24662
- const sourceFile = ts21.createSourceFile("combine.js", content, ts21.ScriptTarget.Latest, false, ts21.ScriptKind.JS);
25194
+ const sourceFile = ts22.createSourceFile("combine.js", content, ts22.ScriptTarget.Latest, false, ts22.ScriptKind.JS);
24663
25195
  const importSpans = [];
24664
25196
  for (const stmt of sourceFile.statements) {
24665
- if (!ts21.isImportDeclaration(stmt))
25197
+ if (!ts22.isImportDeclaration(stmt))
24666
25198
  continue;
24667
25199
  const start = stmt.getStart(sourceFile);
24668
25200
  const end = stmt.getEnd();
@@ -24672,8 +25204,8 @@ function parseAndMerge(content, importsBySource, otherImports, codeSections) {
24672
25204
  continue;
24673
25205
  const clause = stmt.importClause;
24674
25206
  const bindings = clause?.namedBindings;
24675
- const specifier = ts21.isStringLiteral(stmt.moduleSpecifier) ? stmt.moduleSpecifier.text : "";
24676
- if (clause && !clause.name && bindings && ts21.isNamedImports(bindings)) {
25207
+ const specifier = ts22.isStringLiteral(stmt.moduleSpecifier) ? stmt.moduleSpecifier.text : "";
25208
+ if (clause && !clause.name && bindings && ts22.isNamedImports(bindings)) {
24677
25209
  if (!importsBySource.has(specifier)) {
24678
25210
  importsBySource.set(specifier, new Set);
24679
25211
  }
@@ -24840,7 +25372,7 @@ function escapeRe(s) {
24840
25372
  return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
24841
25373
  }
24842
25374
  // src/debug.ts
24843
- import ts22 from "typescript";
25375
+ import ts23 from "typescript";
24844
25376
  function buildComponentGraph(source, filePath, componentName) {
24845
25377
  const ctx = analyzeComponent(source, filePath, componentName);
24846
25378
  if (!ctx.jsxReturn) {
@@ -26125,7 +26657,7 @@ function truncateExpr(expr, max = 40) {
26125
26657
  function exprReadsPropMember(expr, propsObjectName) {
26126
26658
  let sf;
26127
26659
  try {
26128
- sf = ts22.createSourceFile("__attr.tsx", `(${expr})`, ts22.ScriptTarget.Latest, true, ts22.ScriptKind.TSX);
26660
+ sf = ts23.createSourceFile("__attr.tsx", `(${expr})`, ts23.ScriptTarget.Latest, true, ts23.ScriptKind.TSX);
26129
26661
  } catch {
26130
26662
  return false;
26131
26663
  }
@@ -26133,11 +26665,11 @@ function exprReadsPropMember(expr, propsObjectName) {
26133
26665
  const visit3 = (n) => {
26134
26666
  if (found)
26135
26667
  return;
26136
- if (ts22.isPropertyAccessExpression(n) && ts22.isIdentifier(n.expression) && n.expression.text === propsObjectName && n.name.text !== "children") {
26668
+ if (ts23.isPropertyAccessExpression(n) && ts23.isIdentifier(n.expression) && n.expression.text === propsObjectName && n.name.text !== "children") {
26137
26669
  found = true;
26138
26670
  return;
26139
26671
  }
26140
- ts22.forEachChild(n, visit3);
26672
+ ts23.forEachChild(n, visit3);
26141
26673
  };
26142
26674
  visit3(sf);
26143
26675
  return found;
@@ -26207,7 +26739,7 @@ function findSourceFile2(meta) {
26207
26739
  return null;
26208
26740
  }
26209
26741
  // src/profiler.ts
26210
- import ts23 from "typescript";
26742
+ import ts24 from "typescript";
26211
26743
  var PROFILE_SCHEMA_VERSION = 1;
26212
26744
  var DEFAULT_FANOUT_THRESHOLD = 8;
26213
26745
  function buildStaticBudget(source, filePath, componentName, options = {}) {
@@ -26477,15 +27009,15 @@ function joinProfilerEvents(events, index) {
26477
27009
  return { joined, unattributed, diagnostics };
26478
27010
  }
26479
27011
  function findUninstrumentedEffects(source, filePath, instrumentedLines) {
26480
- const sf = ts23.createSourceFile(filePath, source, ts23.ScriptTarget.Latest, true, ts23.ScriptKind.TSX);
27012
+ const sf = ts24.createSourceFile(filePath, source, ts24.ScriptTarget.Latest, true, ts24.ScriptKind.TSX);
26481
27013
  const out = [];
26482
27014
  const visit3 = (node) => {
26483
- if (ts23.isCallExpression(node) && ts23.isIdentifier(node.expression) && node.expression.text === "createEffect") {
27015
+ if (ts24.isCallExpression(node) && ts24.isIdentifier(node.expression) && node.expression.text === "createEffect") {
26484
27016
  const line = sf.getLineAndCharacterOfPosition(node.getStart(sf)).line + 1;
26485
27017
  if (!instrumentedLines.has(line))
26486
27018
  out.push({ file: filePath, line });
26487
27019
  }
26488
- ts23.forEachChild(node, visit3);
27020
+ ts24.forEachChild(node, visit3);
26489
27021
  };
26490
27022
  visit3(sf);
26491
27023
  out.sort((a, b) => a.line - b.line);
@@ -26793,13 +27325,13 @@ function assessBatchSafety(args) {
26793
27325
  const signalGetters = new Set(args.graph.signals.map((s) => s.name));
26794
27326
  let sf;
26795
27327
  try {
26796
- sf = ts23.createSourceFile("__h.ts", `const __h = ${args.handler}`, ts23.ScriptTarget.Latest, true);
27328
+ sf = ts24.createSourceFile("__h.ts", `const __h = ${args.handler}`, ts24.ScriptTarget.Latest, true);
26797
27329
  } catch {
26798
27330
  return "unverified";
26799
27331
  }
26800
27332
  const calls = [];
26801
27333
  const visit3 = (node) => {
26802
- if (ts23.isCallExpression(node) && ts23.isIdentifier(node.expression)) {
27334
+ if (ts24.isCallExpression(node) && ts24.isIdentifier(node.expression)) {
26803
27335
  const name = node.expression.text;
26804
27336
  if (setters.has(name))
26805
27337
  calls.push({ pos: node.getStart(sf), kind: "write" });
@@ -26808,7 +27340,7 @@ function assessBatchSafety(args) {
26808
27340
  else if (!signalGetters.has(name) && !memoNames.has(name))
26809
27341
  calls.push({ pos: node.getStart(sf), kind: "risky" });
26810
27342
  }
26811
- ts23.forEachChild(node, visit3);
27343
+ ts24.forEachChild(node, visit3);
26812
27344
  };
26813
27345
  visit3(sf);
26814
27346
  calls.sort((a, b) => a.pos - b.pos);
@@ -27550,6 +28082,7 @@ export {
27550
28082
  diffStaticBudget,
27551
28083
  diffProfiles,
27552
28084
  describeFallback,
28085
+ derivesScopeFromSlot,
27553
28086
  decideClientOnlyElision,
27554
28087
  dangerousInnerHtmlMetacharViolation,
27555
28088
  dangerousInnerHtmlDiagnostic,