@barefootjs/jsx 0.29.0 → 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 (87) 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 +876 -352
  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/lazy-row.d.ts.map +1 -1
  23. package/dist/ir-to-client-js/csr-substitute.d.ts.map +1 -1
  24. package/dist/ir-to-client-js/html-template.d.ts +2 -3
  25. package/dist/ir-to-client-js/html-template.d.ts.map +1 -1
  26. package/dist/ir-to-client-js/plan/declaration-emit.d.ts +6 -0
  27. package/dist/ir-to-client-js/plan/declaration-emit.d.ts.map +1 -1
  28. package/dist/ir-to-client-js/reactivity.d.ts +1 -10
  29. package/dist/ir-to-client-js/reactivity.d.ts.map +1 -1
  30. package/dist/ir-to-client-js/types.d.ts +12 -0
  31. package/dist/ir-to-client-js/types.d.ts.map +1 -1
  32. package/dist/jsx-to-ir.d.ts.map +1 -1
  33. package/dist/rich-type-evidence.d.ts.map +1 -1
  34. package/dist/ssr-defaults.d.ts.map +1 -1
  35. package/dist/to-locale-date-lowering.d.ts.map +1 -1
  36. package/dist/types.d.ts +78 -0
  37. package/dist/types.d.ts.map +1 -1
  38. package/package.json +2 -2
  39. package/src/__tests__/__snapshots__/doc-examples.test.ts.snap +6 -24
  40. package/src/__tests__/branch-loop-plain.test.ts +28 -45
  41. package/src/__tests__/csr-substitution-safety-divergence.test.ts +9 -3
  42. package/src/__tests__/csr-template-scope-soundness.test.ts +96 -0
  43. package/src/__tests__/early-return-branch-switch.test.ts +96 -0
  44. package/src/__tests__/form-control-value-ssr.test.ts +102 -0
  45. package/src/__tests__/lazy-conditional.test.ts +190 -0
  46. package/src/__tests__/lazy-preamble.test.ts +297 -0
  47. package/src/__tests__/lazy-row-eligibility.test.ts +97 -28
  48. package/src/__tests__/loop-item-root-scope.test.ts +213 -0
  49. package/src/__tests__/map-multi-return-body.test.ts +30 -3
  50. package/src/__tests__/nested-loop-conditional.test.ts +27 -6
  51. package/src/__tests__/preamble-attr-reactivity.test.ts +217 -0
  52. package/src/__tests__/preamble-declarations.test.ts +207 -0
  53. package/src/__tests__/ssr-defaults.test.ts +44 -0
  54. package/src/adapters/child-scope.ts +22 -0
  55. package/src/adapters/loop-bound-names.ts +6 -0
  56. package/src/analyzer-context.ts +43 -0
  57. package/src/analyzer.ts +33 -3
  58. package/src/index.ts +1 -0
  59. package/src/ir-to-client-js/collect-elements.ts +51 -10
  60. package/src/ir-to-client-js/control-flow/plan/build-branch-loop.ts +1 -1
  61. package/src/ir-to-client-js/control-flow/plan/build-composite-loop.ts +2 -2
  62. package/src/ir-to-client-js/control-flow/plan/build-event-delegation.ts +3 -3
  63. package/src/ir-to-client-js/control-flow/plan/build-inner-loop.ts +2 -2
  64. package/src/ir-to-client-js/control-flow/plan/build-lazy-row.ts +147 -5
  65. package/src/ir-to-client-js/control-flow/plan/build-loop.ts +2 -2
  66. package/src/ir-to-client-js/control-flow/plan/build-reactive-effects.ts +1 -0
  67. package/src/ir-to-client-js/control-flow/plan/lazy-conditional.ts +151 -0
  68. package/src/ir-to-client-js/control-flow/plan/lazy-preamble.ts +287 -0
  69. package/src/ir-to-client-js/control-flow/plan/lazy-row-eligibility.ts +85 -22
  70. package/src/ir-to-client-js/control-flow/plan/reactive-effects.ts +7 -0
  71. package/src/ir-to-client-js/control-flow/stringify/lazy-row.ts +133 -35
  72. package/src/ir-to-client-js/control-flow/stringify/reactive-effects.ts +24 -4
  73. package/src/ir-to-client-js/csr-substitute.ts +6 -1
  74. package/src/ir-to-client-js/emit-registration.ts +1 -1
  75. package/src/ir-to-client-js/html-template.ts +51 -40
  76. package/src/ir-to-client-js/index.ts +1 -1
  77. package/src/ir-to-client-js/plan/build-declaration-emit.ts +2 -0
  78. package/src/ir-to-client-js/plan/build-static-array-child-init.ts +1 -1
  79. package/src/ir-to-client-js/plan/declaration-emit.ts +6 -0
  80. package/src/ir-to-client-js/reactivity.ts +25 -0
  81. package/src/ir-to-client-js/stringify/declaration-emit.ts +9 -4
  82. package/src/ir-to-client-js/types.ts +12 -0
  83. package/src/jsx-to-ir.ts +400 -24
  84. package/src/rich-type-evidence.ts +6 -7
  85. package/src/ssr-defaults.ts +7 -2
  86. package/src/to-locale-date-lowering.ts +8 -2
  87. package/src/types.ts +80 -0
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
  }
@@ -14220,10 +14441,11 @@ function collectInnerLoops(nodes, siblingOffsets, outerLoopParam, ctx, options)
14220
14441
  const template = n.children.map((c) => irToPlaceholderTemplate(c, undefined, emitDepth, loopParamsForTemplate)).join("");
14221
14442
  const refsOuter = outerLoopParam ? new RegExp(`\\b${outerLoopParam}\\b`).test(n.array) : false;
14222
14443
  const bindings = emptyLoopChildBindings();
14444
+ const innerPreambleNames = preambleNamesOf(n);
14223
14445
  if (ctx) {
14224
14446
  for (const child of n.children) {
14225
14447
  bindings.reactiveTexts.push(...collectLoopChildReactiveTexts(child, ctx, n.param, n.paramBindings));
14226
- bindings.reactiveAttrs.push(...collectLoopChildReactiveAttrs(child, ctx, n.param, n.paramBindings));
14448
+ bindings.reactiveAttrs.push(...collectLoopChildReactiveAttrs(child, ctx, n.param, n.paramBindings, false, innerPreambleNames));
14227
14449
  bindings.refs.push(...collectLoopChildRefs(child));
14228
14450
  }
14229
14451
  }
@@ -14446,7 +14668,7 @@ function collectElements(node, ctx, siblingOffsets, insideConditional = false) {
14446
14668
  return;
14447
14669
  const projectionInner = l.method === "flatMap" && l.children.length === 1 && l.children[0].type === "loop" ? l.children[0] : undefined;
14448
14670
  const childHandlers = [];
14449
- 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));
14450
14672
  if (!projectionInner) {
14451
14673
  for (const child of l.children) {
14452
14674
  childHandlers.push(...collectEventHandlersFromIR(child));
@@ -14469,7 +14691,7 @@ function collectElements(node, ctx, siblingOffsets, insideConditional = false) {
14469
14691
  if (l.childComponent) {
14470
14692
  template = "";
14471
14693
  if (l.isStaticArray && l.children[0]) {
14472
- staticItemTemplate = irToHtmlTemplate(l.children[0], buildRestSpreadNames(ctx), 0, undefined, undefined, true);
14694
+ staticItemTemplate = irToHtmlTemplate(l.children[0], buildRestSpreadNames(ctx), 0, undefined, undefined);
14473
14695
  }
14474
14696
  } else if (l.children[0] && !projectionInner) {
14475
14697
  const loopParamSpec = [{ param: l.param, bindings: l.paramBindings }];
@@ -14701,7 +14923,7 @@ function collectBranchLoops(node, ctx, siblingOffsets) {
14701
14923
  } else {
14702
14924
  childTemplate = n.children.map((c) => irToHtmlTemplate(c, undefined, 0, branchLoopParamSpec)).join("");
14703
14925
  }
14704
- 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();
14705
14927
  loops.push({
14706
14928
  kind: "branch",
14707
14929
  array: n.array,
@@ -14781,11 +15003,17 @@ function collectBranchConditionals(node, ctx, siblingOffsets) {
14781
15003
  });
14782
15004
  return result;
14783
15005
  }
14784
- 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) {
14785
15013
  const bindings = emptyLoopChildBindings();
14786
15014
  for (const child of children) {
14787
15015
  bindings.events.push(...collectLoopChildEventsWithNesting(child));
14788
- bindings.reactiveAttrs.push(...collectLoopChildReactiveAttrs(child, ctx, loopParam, loopParamBindings, true));
15016
+ bindings.reactiveAttrs.push(...collectLoopChildReactiveAttrs(child, ctx, loopParam, loopParamBindings, true, preambleNames));
14789
15017
  bindings.reactiveTexts.push(...collectLoopChildReactiveTexts(child, ctx, loopParam, loopParamBindings, true));
14790
15018
  bindings.refs.push(...collectLoopChildRefs(child));
14791
15019
  bindings.conditionals.push(...collectLoopChildConditionals(child, ctx, siblingOffsets, loopParam, loopParamBindings));
@@ -16399,7 +16627,7 @@ function emitRegistrationAndHydration(lines, ctx, _ir, graph, inlinability) {
16399
16627
  }
16400
16628
  } else {
16401
16629
  const csrInlinableConstants = csrInlinableConstantsFromCtx(ctx);
16402
- 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);
16403
16631
  if (templateHtml) {
16404
16632
  defParts.push(`template: (${PROPS_PARAM}) => \`${templateHtml}\``);
16405
16633
  }
@@ -16797,6 +17025,7 @@ function buildSignalPlan(signal, ctx, lookups) {
16797
17025
  kind: "signal",
16798
17026
  getter: signal.getter,
16799
17027
  setter: signal.setter,
17028
+ getterElided: signal.getterElided,
16800
17029
  initialValueExpr: "",
16801
17030
  controlledEffect: null,
16802
17031
  initializerOverride: `${factory}()`
@@ -16811,6 +17040,7 @@ function buildSignalPlan(signal, ctx, lookups) {
16811
17040
  kind: "signal",
16812
17041
  getter: signal.getter,
16813
17042
  setter: signal.setter,
17043
+ getterElided: signal.getterElided,
16814
17044
  initialValueExpr: resolveSignalInitialValue(signal, ctx, lookups),
16815
17045
  controlledEffect,
16816
17046
  branchCondition: signal.branchCondition,
@@ -16882,9 +17112,10 @@ function bfIdArg(bfId) {
16882
17112
  return bfId ? `, ${JSON.stringify(bfId)}` : "";
16883
17113
  }
16884
17114
  function emitSignal(lines, plan) {
17115
+ const getterSlot = plan.getterElided ? "" : plan.getter;
16885
17116
  if (plan.initializerOverride) {
16886
17117
  if (plan.setter) {
16887
- lines.push(` const [${plan.getter}, ${plan.setter}] = ${plan.initializerOverride}`);
17118
+ lines.push(` const [${getterSlot}, ${plan.setter}] = ${plan.initializerOverride}`);
16888
17119
  } else {
16889
17120
  lines.push(` const [${plan.getter}] = ${plan.initializerOverride}`);
16890
17121
  }
@@ -16893,9 +17124,9 @@ function emitSignal(lines, plan) {
16893
17124
  const id = bfIdArg(plan.bfId);
16894
17125
  if (plan.branchCondition) {
16895
17126
  if (plan.setter) {
16896
- lines.push(` let ${plan.getter}, ${plan.setter}`);
17127
+ lines.push(plan.getterElided ? ` let ${plan.setter}` : ` let ${plan.getter}, ${plan.setter}`);
16897
17128
  lines.push(` if (${plan.branchCondition}) {`);
16898
- lines.push(` ;[${plan.getter}, ${plan.setter}] = createSignal(${plan.initialValueExpr}${id})`);
17129
+ lines.push(` ;[${getterSlot}, ${plan.setter}] = createSignal(${plan.initialValueExpr}${id})`);
16899
17130
  lines.push(` }`);
16900
17131
  } else {
16901
17132
  lines.push(` let ${plan.getter}`);
@@ -16906,7 +17137,7 @@ function emitSignal(lines, plan) {
16906
17137
  return;
16907
17138
  }
16908
17139
  if (plan.setter) {
16909
- lines.push(` const [${plan.getter}, ${plan.setter}] = createSignal(${plan.initialValueExpr}${id})`);
17140
+ lines.push(` const [${getterSlot}, ${plan.setter}] = createSignal(${plan.initialValueExpr}${id})`);
16910
17141
  } else {
16911
17142
  lines.push(` const [${plan.getter}] = createSignal(${plan.initialValueExpr}${id})`);
16912
17143
  }
@@ -17485,7 +17716,7 @@ function emitComponentAndEventSetup(ls, indent, elVar, comps, events, loopParam,
17485
17716
  // src/ir-to-client-js/plan/build-static-array-child-init.ts
17486
17717
  function staticPreludeStatements(preamble) {
17487
17718
  return preamble ? [renderPreamble(preamble, {
17488
- renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, undefined, undefined, true)
17719
+ renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, undefined, undefined)
17489
17720
  })] : [];
17490
17721
  }
17491
17722
  function buildStaticArrayChildInitsPlan(ctx) {
@@ -18040,7 +18271,8 @@ function buildReactiveEffectsPlan(args) {
18040
18271
  attrs: slotAttrs.map((attr) => ({
18041
18272
  attrName: attr.attrName,
18042
18273
  wrappedExpression: wrap(attr.expression),
18043
- meta: pickAttrMeta(attr)
18274
+ meta: pickAttrMeta(attr),
18275
+ ...attr.readsPreamble && { readsPreamble: true }
18044
18276
  }))
18045
18277
  });
18046
18278
  }
@@ -18240,7 +18472,7 @@ function buildReactiveEmit(inner, level, wrapOuter, uidSuffix, outerLoopParam, o
18240
18472
  ] : [{ param: inner.param, bindings: inner.paramBindings }];
18241
18473
  preludeStatements.push(renderPreamble(inner.preamble, {
18242
18474
  transformJs: (t) => wrapInner(wrapOuter(t)),
18243
- renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, leafLoopParams, undefined, true)
18475
+ renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, leafLoopParams, undefined)
18244
18476
  }));
18245
18477
  }
18246
18478
  const childRefs = buildChildRefBindings(inner.bindings.refs, inner.param, inner.paramBindings);
@@ -18266,7 +18498,7 @@ function buildStaticEmit(inner, level, uidSuffix) {
18266
18498
  preludeStatements.push(indexAlias);
18267
18499
  if (inner.preamble) {
18268
18500
  preludeStatements.push(renderPreamble(inner.preamble, {
18269
- renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, undefined, undefined, true)
18501
+ renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, undefined, undefined)
18270
18502
  }));
18271
18503
  }
18272
18504
  return {
@@ -18298,7 +18530,7 @@ function buildTopLevelCompositePlan(elem, profileComponentName) {
18298
18530
  indexParam: elem.index || "__idx",
18299
18531
  mapPreambleWrapped: elem.preamble ? renderPreamble(elem.preamble, {
18300
18532
  transformJs: wrap,
18301
- 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)
18302
18534
  }) : "",
18303
18535
  template: elem.template,
18304
18536
  outerComps: filterCondCompsOut(outerCompsByDepth, elem.bindings.conditionals),
@@ -18348,7 +18580,7 @@ function buildBranchCompositePlan(loop, cv, profileComponentName) {
18348
18580
  indexParam: loop.index || "__idx",
18349
18581
  mapPreambleWrapped: loop.preamble ? renderPreamble(loop.preamble, {
18350
18582
  transformJs: wrap,
18351
- 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)
18352
18584
  }) : "",
18353
18585
  template: loop.template,
18354
18586
  outerComps: filterCondCompsOut(outerCompsByDepth, loop.bindings.conditionals),
@@ -18413,7 +18645,7 @@ function buildDynamicLoopDelegationPlan(elem, profileComponentName) {
18413
18645
  key: elem.key,
18414
18646
  index: elem.index,
18415
18647
  mapPreamble: elem.preamble ? renderPreamble(elem.preamble, {
18416
- renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, undefined, undefined, true)
18648
+ renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, undefined, undefined)
18417
18649
  }) : null,
18418
18650
  mapPreambleDeclaredNames: elem.preamble?.declaredNames ?? []
18419
18651
  })
@@ -18432,7 +18664,7 @@ function buildBranchLoopDelegationPlan(loop, cv, profileComponentName) {
18432
18664
  key: loop.key,
18433
18665
  index: loop.index,
18434
18666
  mapPreamble: loop.preamble ? renderPreamble(loop.preamble, {
18435
- renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, undefined, undefined, true)
18667
+ renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, undefined, undefined)
18436
18668
  }) : null,
18437
18669
  mapPreambleDeclaredNames: loop.preamble?.declaredNames ?? []
18438
18670
  })
@@ -18449,7 +18681,7 @@ function buildStaticArrayDelegationPlan(elem, profileComponentName) {
18449
18681
  arrayExpr: buildChainedArrayExpr(elem),
18450
18682
  param: elem.param,
18451
18683
  mapPreamble: elem.preamble ? renderPreamble(elem.preamble, {
18452
- renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, undefined, undefined, true)
18684
+ renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, undefined, undefined)
18453
18685
  }) : null,
18454
18686
  mapPreambleDeclaredNames: elem.preamble?.declaredNames ?? [],
18455
18687
  offset: elem.offset ?? null,
@@ -18484,6 +18716,181 @@ function buildKeyedOrIndexLookup(args) {
18484
18716
  };
18485
18717
  }
18486
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
+
18487
18894
  // src/ir-to-client-js/control-flow/plan/lazy-row-eligibility.ts
18488
18895
  var PURE_SOURCE_GLOBALS = new Set([
18489
18896
  "Object",
@@ -18527,51 +18934,51 @@ var INERT_BINDING_GLOBALS = new Set([
18527
18934
  "decodeURI"
18528
18935
  ]);
18529
18936
  var UNKNOWN_IDENTIFIERS = "<unknown>";
18530
- var NO = (reason) => ({ eligible: false, reason });
18937
+ var NO3 = (reason) => ({ eligible: false, reason });
18531
18938
  function lazyRowEligibility(args) {
18532
18939
  const { shape, bindings, arraySourceIdentifiers, scope } = args;
18533
18940
  if (scope.profile)
18534
- return NO("profile mode keeps the granular eager emission");
18941
+ return NO3("profile mode keeps the granular eager emission");
18535
18942
  if (shape.callSite !== "plain" && shape.callSite !== "branch-plain") {
18536
- 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`);
18537
18944
  }
18538
18945
  if (shape.flatMapLeafItem)
18539
- return NO("flatMap descriptor loop (build-or-patch renderItem)");
18946
+ return NO3("flatMap descriptor loop (build-or-patch renderItem)");
18540
18947
  if (shape.anchored)
18541
- return NO("anchored whole-item-conditional loop");
18948
+ return NO3("anchored whole-item-conditional loop");
18542
18949
  if (shape.bodyIsMultiRoot)
18543
- return NO("multi-root (Fragment) row");
18950
+ return NO3("multi-root (Fragment) row");
18544
18951
  if (!shape.hasExplicitKey)
18545
- return NO("index-keyed loop (no explicit key)");
18546
- if (shape.conditionalCount > 0)
18547
- 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);
18548
18955
  if (shape.childRefCount > 0)
18549
- return NO("row has imperative child refs");
18956
+ return NO3("row has imperative child refs");
18550
18957
  if (shape.hasChildComponent)
18551
- return NO("row body is a child component");
18958
+ return NO3("row body is a child component");
18552
18959
  if (shape.nestedComponentCount > 0)
18553
- return NO("row contains nested child components");
18960
+ return NO3("row contains nested child components");
18554
18961
  if (shape.innerLoopCount > 0)
18555
- return NO("row contains an inner loop");
18556
- if (shape.hasMapPreamble)
18557
- 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);
18558
18965
  if (shape.preambleRegionCount > 0)
18559
- return NO("row has preamble-patched regions");
18966
+ return NO3("row has preamble-patched regions");
18560
18967
  if (shape.hasParamUnwrap)
18561
- return NO("destructured loop param without param bindings");
18968
+ return NO3("destructured loop param without param bindings");
18562
18969
  for (const b of bindings) {
18563
18970
  if (b.referencesIndex) {
18564
- 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`);
18565
18972
  }
18566
18973
  if (b.opaqueOuterNames.includes(UNKNOWN_IDENTIFIERS)) {
18567
- 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`);
18568
18975
  }
18569
18976
  }
18570
18977
  if (!arraySourceIdentifiers)
18571
- return NO("loop source free identifiers unavailable");
18978
+ return NO3("loop source free identifiers unavailable");
18572
18979
  const sourceGate = checkSourceConsistency(arraySourceIdentifiers, scope);
18573
18980
  if (sourceGate)
18574
- return NO(`loop source is not provably hydration-consistent: ${sourceGate}`);
18981
+ return NO3(`loop source is not provably hydration-consistent: ${sourceGate}`);
18575
18982
  return { eligible: true };
18576
18983
  }
18577
18984
  function checkSourceConsistency(names, scope) {
@@ -18622,6 +19029,7 @@ function checkSourceConsistency(names, scope) {
18622
19029
  }
18623
19030
  function classifyLazyBinding(args) {
18624
19031
  const { kind, slotId, free, rowLocalNames, indexParam, scope } = args;
19032
+ const preamble = args.preamble;
18625
19033
  if (free === null) {
18626
19034
  return {
18627
19035
  kind,
@@ -18630,33 +19038,44 @@ function classifyLazyBinding(args) {
18630
19038
  readsOuter: true,
18631
19039
  reactiveOuterNames: [],
18632
19040
  opaqueOuterNames: [UNKNOWN_IDENTIFIERS],
18633
- referencesIndex: false
19041
+ referencesIndex: false,
19042
+ readsPreamble: preamble != null && preamble.declaredNames.size > 0
18634
19043
  };
18635
19044
  }
18636
19045
  let readsItem = false;
18637
19046
  let referencesIndex = false;
19047
+ let readsPreamble = false;
18638
19048
  const reactiveOuterNames = [];
18639
19049
  const opaqueOuterNames = [];
18640
- for (const name of free) {
19050
+ const classifyName = (name) => {
18641
19051
  if (rowLocalNames.has(name)) {
18642
19052
  readsItem = true;
18643
- continue;
19053
+ return;
18644
19054
  }
18645
19055
  if (name === indexParam) {
18646
19056
  referencesIndex = true;
18647
- continue;
19057
+ return;
18648
19058
  }
18649
19059
  if (INERT_BINDING_GLOBALS.has(name))
18650
- continue;
19060
+ return;
18651
19061
  if (scope.signals.has(name) || scope.memos.has(name)) {
18652
19062
  if (!reactiveOuterNames.includes(name))
18653
19063
  reactiveOuterNames.push(name);
18654
- continue;
19064
+ return;
18655
19065
  }
18656
19066
  const constFree = scope.constants.get(name);
18657
19067
  if (constFree !== undefined && constFree !== null && constFree.size === 0)
18658
- continue;
19068
+ return;
18659
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);
18660
19079
  }
18661
19080
  return {
18662
19081
  kind,
@@ -18665,7 +19084,8 @@ function classifyLazyBinding(args) {
18665
19084
  readsOuter: reactiveOuterNames.length > 0 || opaqueOuterNames.length > 0,
18666
19085
  reactiveOuterNames,
18667
19086
  opaqueOuterNames,
18668
- referencesIndex
19087
+ referencesIndex,
19088
+ readsPreamble
18669
19089
  };
18670
19090
  }
18671
19091
 
@@ -18682,6 +19102,23 @@ function decideLazyRow(args) {
18682
19102
  const rowLocalNames = new Set([loop.param]);
18683
19103
  for (const b of loop.paramBindings ?? [])
18684
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;
18685
19122
  const classified = [];
18686
19123
  const attrClass = new Map;
18687
19124
  loop.bindings.reactiveAttrs.forEach((attr, i) => {
@@ -18691,7 +19128,8 @@ function decideLazyRow(args) {
18691
19128
  free: attrFreeIdentifiers2(attr.expression),
18692
19129
  rowLocalNames,
18693
19130
  indexParam: args.indexParam,
18694
- scope
19131
+ scope,
19132
+ preamble: preambleFacts
18695
19133
  });
18696
19134
  attrClass.set(i, c);
18697
19135
  classified.push(c);
@@ -18704,23 +19142,38 @@ function decideLazyRow(args) {
18704
19142
  free: text.freeIdentifiers ?? null,
18705
19143
  rowLocalNames,
18706
19144
  indexParam: args.indexParam,
18707
- scope
19145
+ scope,
19146
+ preamble: preambleFacts
18708
19147
  });
18709
19148
  textClass.set(i, c);
18710
19149
  classified.push(c);
18711
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
+ });
18712
19165
  const shape = {
18713
19166
  callSite: args.callSite,
18714
19167
  flatMapLeafItem: args.flatMapLeafItem,
18715
19168
  anchored: args.anchored,
18716
19169
  bodyIsMultiRoot: loop.bodyIsMultiRoot ?? false,
18717
19170
  hasExplicitKey: loop.key != null,
18718
- conditionalCount: loop.bindings.conditionals?.length ?? 0,
19171
+ conditionalRefusal,
18719
19172
  childRefCount: loop.bindings.refs?.length ?? 0,
18720
19173
  nestedComponentCount: loop.nestedComponents?.length ?? 0,
18721
19174
  innerLoopCount: loop.innerLoops?.length ?? 0,
18722
19175
  hasChildComponent: "childComponent" in loop && loop.childComponent != null,
18723
- hasMapPreamble: args.mapPreambleWrapped.length > 0,
19176
+ mapPreambleRefusal: preambleAnalysis.lazySafe ? null : preambleAnalysis.reason,
18724
19177
  preambleRegionCount: args.preambleRegionCount,
18725
19178
  hasParamUnwrap: args.paramUnwrap.length > 0
18726
19179
  };
@@ -18748,7 +19201,8 @@ function decideLazyRow(args) {
18748
19201
  refIndex: attrSlotIds.indexOf(attr.childSlotId),
18749
19202
  ordinal: ordinal++,
18750
19203
  readsItem: c.readsItem,
18751
- readsOuter: c.readsOuter
19204
+ readsOuter: c.readsOuter,
19205
+ readsPreamble: c.readsPreamble
18752
19206
  };
18753
19207
  });
18754
19208
  const texts = loop.bindings.reactiveTexts.map((text, i) => {
@@ -18758,7 +19212,8 @@ function decideLazyRow(args) {
18758
19212
  wrappedExpression: wrap(text.expression),
18759
19213
  ordinal: ordinal++,
18760
19214
  readsItem: c.readsItem || !c.readsOuter,
18761
- readsOuter: c.readsOuter
19215
+ readsOuter: c.readsOuter,
19216
+ readsPreamble: c.readsPreamble
18762
19217
  };
18763
19218
  });
18764
19219
  const outerPrimeGetters = [];
@@ -18768,6 +19223,21 @@ function decideLazyRow(args) {
18768
19223
  outerPrimeGetters.push(name);
18769
19224
  }
18770
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
+ });
18771
19241
  return {
18772
19242
  plan: {
18773
19243
  attrSlotIds,
@@ -18777,7 +19247,10 @@ function decideLazyRow(args) {
18777
19247
  textNeedsRead: texts.some((t) => t.readsOuter),
18778
19248
  lastCount: ordinal,
18779
19249
  outerPrimeGetters,
18780
- 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
18781
19254
  },
18782
19255
  decision
18783
19256
  };
@@ -18849,7 +19322,7 @@ function buildBranchLoopPlan(loop, profileComponentName, lazyScope) {
18849
19322
  const indexParam = loop.index || "__idx";
18850
19323
  const mapPreambleWrapped = loop.preamble ? renderPreamble(loop.preamble, {
18851
19324
  transformJs: (t) => wrapLoopParamAsAccessor(t, loop.param, loop.paramBindings),
18852
- 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)
18853
19326
  }) : "";
18854
19327
  const preambleRegions = buildPreambleRegionPlans(loop.preambleRegions, loop.param, loop.paramBindings);
18855
19328
  const plan = {
@@ -18945,7 +19418,7 @@ function buildArmBody(branch, options) {
18945
19418
  }
18946
19419
 
18947
19420
  // src/ir-to-client-js/emit-reactive.ts
18948
- import ts15 from "typescript";
19421
+ import ts16 from "typescript";
18949
19422
 
18950
19423
  // src/ir-to-client-js/control-flow/stringify/claim-plan.ts
18951
19424
  function slotSpecLiteral(slot) {
@@ -19048,20 +19521,20 @@ function lowerToLocaleCallsInReactiveExpr(expr, matcher) {
19048
19521
  return expr;
19049
19522
  let sourceFile;
19050
19523
  try {
19051
- 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);
19052
19525
  } catch {
19053
19526
  return expr;
19054
19527
  }
19055
19528
  const stmt = sourceFile.statements[0];
19056
- if (!stmt || !ts15.isExpressionStatement(stmt))
19529
+ if (!stmt || !ts16.isExpressionStatement(stmt))
19057
19530
  return expr;
19058
- const root = ts15.isParenthesizedExpression(stmt.expression) ? stmt.expression.expression : stmt.expression;
19531
+ const root = ts16.isParenthesizedExpression(stmt.expression) ? stmt.expression.expression : stmt.expression;
19059
19532
  const candidates = [];
19060
19533
  const visit3 = (n) => {
19061
- 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") {
19062
19535
  candidates.push(n);
19063
19536
  }
19064
- ts15.forEachChild(n, visit3);
19537
+ ts16.forEachChild(n, visit3);
19065
19538
  };
19066
19539
  visit3(root);
19067
19540
  if (candidates.length === 0)
@@ -19097,20 +19570,20 @@ function lowerDateCallsInReactiveExpr(expr, matcher) {
19097
19570
  return expr;
19098
19571
  let sourceFile;
19099
19572
  try {
19100
- 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);
19101
19574
  } catch {
19102
19575
  return expr;
19103
19576
  }
19104
19577
  const stmt = sourceFile.statements[0];
19105
- if (!stmt || !ts15.isExpressionStatement(stmt))
19578
+ if (!stmt || !ts16.isExpressionStatement(stmt))
19106
19579
  return expr;
19107
- const root = ts15.isParenthesizedExpression(stmt.expression) ? stmt.expression.expression : stmt.expression;
19580
+ const root = ts16.isParenthesizedExpression(stmt.expression) ? stmt.expression.expression : stmt.expression;
19108
19581
  const candidates = [];
19109
19582
  const visit3 = (n) => {
19110
- 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)) {
19111
19584
  candidates.push(n);
19112
19585
  }
19113
- ts15.forEachChild(n, visit3);
19586
+ ts16.forEachChild(n, visit3);
19114
19587
  };
19115
19588
  visit3(root);
19116
19589
  if (candidates.length === 0)
@@ -19418,7 +19891,7 @@ function stringifyReactiveEffects(lines, plan, opts) {
19418
19891
  const outerTexts = plan?.outerTexts ?? [];
19419
19892
  const conditionals = plan?.conditionals ?? [];
19420
19893
  if (pc) {
19421
- emitAttrSlotsGranular(lines, indent, elVar, lookup, attrSlots, elementIndexBySlot, bindingBfId);
19894
+ emitAttrSlotsGranular(lines, indent, elVar, lookup, attrSlots, elementIndexBySlot, bindingBfId, mapPreambleWrapped);
19422
19895
  emitOuterTexts(lines, indent, elVar, outerTexts, bindingBfId, textClaimPathExprs);
19423
19896
  emitPreambleRegionsEffect(lines, indent, elVar, preambleRegions, mapPreambleWrapped);
19424
19897
  } else {
@@ -19428,7 +19901,7 @@ function stringifyReactiveEffects(lines, plan, opts) {
19428
19901
  emitOuterConditional(lines, indent, elVar, cond, pc);
19429
19902
  }
19430
19903
  }
19431
- function emitAttrSlotsGranular(lines, indent, elVar, lookup, attrSlots, elementIndexBySlot, bindingBfId) {
19904
+ function emitAttrSlotsGranular(lines, indent, elVar, lookup, attrSlots, elementIndexBySlot, bindingBfId, mapPreambleWrapped) {
19432
19905
  for (const slot of attrSlots) {
19433
19906
  const varName = `__ra_${varSlotId(slot.slotId)}`;
19434
19907
  const lookupExpr = attrLookupExpr(slot.slotId, varName, elVar, lookup, elementIndexBySlot);
@@ -19436,6 +19909,9 @@ function emitAttrSlotsGranular(lines, indent, elVar, lookup, attrSlots, elementI
19436
19909
  lines.push(`${indent}if (${varName}) {`);
19437
19910
  for (const attr of slot.attrs) {
19438
19911
  lines.push(`${indent} createEffect(() => {`);
19912
+ if (attr.readsPreamble && mapPreambleWrapped) {
19913
+ lines.push(`${indent} ${mapPreambleWrapped}`);
19914
+ }
19439
19915
  for (const stmt of emitAttrUpdate(varName, attr.attrName, attr.wrappedExpression, attr.meta)) {
19440
19916
  lines.push(`${indent} ${stmt}`);
19441
19917
  }
@@ -19458,6 +19934,9 @@ function emitPreambleRegionsEffect(lines, indent, elVar, preambleRegions, mapPre
19458
19934
  }
19459
19935
  lines.push(`${indent}})`);
19460
19936
  }
19937
+ function attrsReadPreamble(attrSlots) {
19938
+ return attrSlots.some((slot) => slot.attrs.some((a) => a.readsPreamble));
19939
+ }
19461
19940
  function attrLookupExpr(slotId, varName, elVar, lookup, elementIndexBySlot) {
19462
19941
  const pIdx = elementIndexBySlot?.get(slotId);
19463
19942
  return pIdx !== undefined ? `__p ? __p[${pIdx}] : ${lookup}(${elVar}, '[bf="${slotId}"]')` : `${lookup}(${elVar}, '[bf="${slotId}"]')`;
@@ -19483,6 +19962,9 @@ function emitConsolidatedRowEffect(lines, indent, elVar, lookup, attrSlots, oute
19483
19962
  return;
19484
19963
  }
19485
19964
  lines.push(`${indent}createEffect(() => {`);
19965
+ if (mapPreambleWrapped && (preambleRegions.length > 0 || attrsReadPreamble(attrSlots))) {
19966
+ lines.push(`${indent} ${mapPreambleWrapped}`);
19967
+ }
19486
19968
  for (const slot of attrSlots) {
19487
19969
  const varName = `__ra_${varSlotId(slot.slotId)}`;
19488
19970
  lines.push(`${indent} if (${varName}) {`);
@@ -19495,9 +19977,6 @@ function emitConsolidatedRowEffect(lines, indent, elVar, lookup, attrSlots, oute
19495
19977
  }
19496
19978
  lines.push(`${indent} }`);
19497
19979
  }
19498
- if (preambleRegions.length > 0 && mapPreambleWrapped) {
19499
- lines.push(`${indent} ${mapPreambleWrapped}`);
19500
- }
19501
19980
  for (const text of outerTexts) {
19502
19981
  lines.push(`${indent} ${writer}('${text.slotId}', String(${text.wrappedExpression}))`);
19503
19982
  }
@@ -19631,9 +20110,8 @@ function stringifyLazyRowLoop(lines, o) {
19631
20110
  const { indent, lazyRow, paramHead } = o;
19632
20111
  const mid = o.markerId.replace(/[^A-Za-z0-9_$]/g, "_");
19633
20112
  const tplVar = `__tpl_${mid}`;
19634
- const claimVar = `__lzc_${mid}`;
19635
20113
  const hasRefs = lazyRow.attrSlotIds.length > 0 || lazyRow.texts.length > 0;
19636
- 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;
19637
20115
  const rwDoor = lazyRow.textNeedsRead;
19638
20116
  const paths = o.skeletonPaths;
19639
20117
  const useHoisted = Boolean(o.skeletonTemplate);
@@ -19663,13 +20141,10 @@ function stringifyLazyRowLoop(lines, o) {
19663
20141
  freshPlanVar = adoptedPlanVar;
19664
20142
  }
19665
20143
  }
19666
- if (hasRefs) {
19667
- const parts = refParts(lazyRow, "__el", null, adoptedPlanVar, true);
19668
- lines.push(`${indent}const ${claimVar} = (__e) => {`);
19669
- if (parts.some((p) => p.includes("__el")))
19670
- lines.push(`${indent} const __el = __e.primaryEl`);
19671
- lines.push(`${indent} return [${parts.join(", ")}]`);
19672
- 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);
19673
20148
  }
19674
20149
  const call = `mapArrayLazy(() => ${o.arrayExpr}, ${o.containerVar}, ${o.keyFn}, {`;
19675
20150
  lines.push(`${indent}${o.guardContainer ? `if (${o.containerVar}) ` : ""}${call}`);
@@ -19677,6 +20152,8 @@ function stringifyLazyRowLoop(lines, o) {
19677
20152
  const b2 = `${indent} `;
19678
20153
  lines.push(`${b1}createRow: (__e, ${o.indexParam}) => {`);
19679
20154
  lines.push(`${b2}const ${paramHead} = () => __e.item`);
20155
+ if (lazyRow.preambleStatements)
20156
+ lines.push(`${b2}${lazyRow.preambleStatements}`);
19680
20157
  const cloneExpr = useHoisted ? hoistedCloneExpr(tplVar, o.skeletonTemplate) : `(() => { ${emitTemplateCloneInline(o.template)} })()`;
19681
20158
  lines.push(`${b2}const __el = ${cloneExpr}`);
19682
20159
  if (hasRefs) {
@@ -19690,17 +20167,23 @@ function stringifyLazyRowLoop(lines, o) {
19690
20167
  for (const t of lazyRow.texts)
19691
20168
  emitTextBinding(lines, b2, t, createDoor, "create", rwDoor);
19692
20169
  }
20170
+ for (const c of lazyRow.conditionals)
20171
+ emitConditional(lines, b2, mid, c, "create");
19693
20172
  lines.push(`${b2}return __el`);
19694
20173
  lines.push(`${b1}},`);
19695
20174
  const itemAttrs = lazyRow.attrs.filter((a) => a.readsItem);
19696
20175
  const itemTexts = lazyRow.texts.filter((t) => t.readsItem);
19697
- 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) {
19698
20178
  lines.push(`${b1}applyItem: () => {},`);
19699
20179
  } else {
19700
20180
  lines.push(`${b1}applyItem: (__e) => {`);
19701
20181
  lines.push(`${b2}const ${paramHead} = () => __e.item`);
19702
- lines.push(`${b2}const __r = __e.refs ?? (__e.refs = ${claimVar}(__e))`);
20182
+ lines.push(`${b2}const __r = __e.refs ?? (__e.refs = [])`);
19703
20183
  lines.push(`${b2}const __l = __e.last ?? (__e.last = [])`);
20184
+ if (lazyRow.itemNeedsPreamble && lazyRow.preambleStatements) {
20185
+ lines.push(`${b2}${lazyRow.preambleStatements}`);
20186
+ }
19704
20187
  for (const a of itemAttrs)
19705
20188
  emitAttrBinding(lines, b2, a, "item");
19706
20189
  if (itemTexts.length > 0) {
@@ -19708,19 +20191,25 @@ function stringifyLazyRowLoop(lines, o) {
19708
20191
  for (const t of itemTexts)
19709
20192
  emitTextBinding(lines, b2, t, "__d", "item", rwDoor);
19710
20193
  }
20194
+ for (const c of itemConds)
20195
+ emitConditional(lines, b2, mid, c, "item");
19711
20196
  lines.push(`${b1}},`);
19712
20197
  }
19713
20198
  const outerAttrs = lazyRow.attrs.filter((a) => a.readsOuter);
19714
20199
  const outerTexts = lazyRow.texts.filter((t) => t.readsOuter);
19715
- 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) {
19716
20202
  const b3 = `${indent} `;
19717
20203
  lines.push(`${b1}applyOuter: (__es, __seed) => {`);
19718
20204
  for (const g of lazyRow.outerPrimeGetters)
19719
20205
  lines.push(`${b2}${g}()`);
19720
20206
  lines.push(`${b2}for (const __e of __es) {`);
19721
20207
  lines.push(`${b3}const ${paramHead} = () => __e.item`);
19722
- lines.push(`${b3}const __r = __e.refs ?? (__e.refs = ${claimVar}(__e))`);
20208
+ lines.push(`${b3}const __r = __e.refs ?? (__e.refs = [])`);
19723
20209
  lines.push(`${b3}const __l = __e.last ?? (__e.last = [])`);
20210
+ if (lazyRow.outerNeedsPreamble && lazyRow.preambleStatements) {
20211
+ lines.push(`${b3}${lazyRow.preambleStatements}`);
20212
+ }
19724
20213
  for (const a of outerAttrs)
19725
20214
  emitAttrBinding(lines, b3, a, "outer");
19726
20215
  if (outerTexts.length > 0) {
@@ -19728,22 +20217,28 @@ function stringifyLazyRowLoop(lines, o) {
19728
20217
  for (const t of outerTexts)
19729
20218
  emitTextBinding(lines, b3, t, "__d", "outer", rwDoor);
19730
20219
  }
20220
+ for (const c of outerConds)
20221
+ emitConditional(lines, b3, mid, c, "outer");
19731
20222
  lines.push(`${b2}}`);
19732
20223
  lines.push(`${b1}},`);
19733
20224
  }
19734
20225
  lines.push(`${indent}}, '${o.markerId}')`);
19735
20226
  }
19736
- function refParts(lazyRow, elVar, skeletonPaths, planVar, deferDoor = false) {
20227
+ function refParts(lazyRow, elVar, skeletonPaths, planVar) {
19737
20228
  const parts = [];
19738
20229
  for (const slotId of lazyRow.attrSlotIds) {
19739
20230
  const path = skeletonPaths?.elementPaths.get(slotId);
19740
20231
  parts.push(path ? pathExpr(elVar, path) : `qsa(${elVar}, '[bf="${slotId}"]')`);
19741
20232
  }
19742
20233
  if (lazyRow.texts.length > 0) {
19743
- parts.push(deferDoor ? "null" : `${doorCtor(lazyRow)}(${elVar}, ${planVar})`);
20234
+ parts.push(`${doorCtor(lazyRow)}(${elVar}, ${planVar})`);
19744
20235
  }
19745
20236
  return parts;
19746
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
+ }
19747
20242
  function doorCtor(lazyRow) {
19748
20243
  return lazyRow.textNeedsRead ? "lazyClaimSlots" : "lazySlots";
19749
20244
  }
@@ -19751,11 +20246,36 @@ function doorAccess(lazyRow, writerIndex, adoptedPlanVar) {
19751
20246
  const slot = `__r[${writerIndex}]`;
19752
20247
  return `${slot} ?? (${slot} = ${doorCtor(lazyRow)}(__e.primaryEl, ${adoptedPlanVar}))`;
19753
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
+ }
19754
20273
  function dedupGuard(ordinal) {
19755
20274
  return `!(${ordinal} in __l) || !Object.is(__l[${ordinal}], __x)`;
19756
20275
  }
19757
20276
  function emitAttrBinding(lines, ind, a, mode) {
19758
- 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}`);
19759
20279
  lines.push(`${ind}if (__t) {`);
19760
20280
  lines.push(`${ind} const __x = ${a.wrappedExpression}`);
19761
20281
  const guard = mode === "create" ? null : mode === "item" ? dedupGuard(a.ordinal) : `__seed ? (${seedDiffersExpr("__t", a)}) : (${dedupGuard(a.ordinal)})`;
@@ -20752,7 +21272,7 @@ function buildPlainLoopPlan(elem, profileComponentName, lazyScope) {
20752
21272
  const indexParam = elem.index || "__idx";
20753
21273
  const mapPreambleWrapped = elem.preamble ? renderPreamble(elem.preamble, {
20754
21274
  transformJs: wrap,
20755
- 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)
20756
21276
  }) : "";
20757
21277
  const preambleRegions = buildPreambleRegionPlans(elem.preambleRegions, elem.param, elem.paramBindings);
20758
21278
  return {
@@ -20829,7 +21349,7 @@ function buildStaticLoopMaterialize(elem, unsafeLocalNames) {
20829
21349
  return {
20830
21350
  itemTemplate: elem.staticItemTemplate,
20831
21351
  mapPreamble: elem.preamble ? renderPreamble(elem.preamble, {
20832
- 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)
20833
21353
  }) : "",
20834
21354
  bodyIsMultiRoot: elem.bodyIsMultiRoot ?? false
20835
21355
  };
@@ -21066,20 +21586,20 @@ var PHASES = [
21066
21586
  ];
21067
21587
 
21068
21588
  // src/ir-to-client-js/rewrite-props-object.ts
21069
- import ts16 from "typescript";
21589
+ import ts17 from "typescript";
21070
21590
  function rewritePropsObjectRef(code, propsObjectName) {
21071
21591
  const srcPropsName = propsObjectName ?? "props";
21072
21592
  if (srcPropsName === PROPS_PARAM)
21073
21593
  return code;
21074
21594
  if (!new RegExp(`\\b${srcPropsName}\\b`).test(code))
21075
21595
  return code;
21076
- 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);
21077
21597
  const spans = [];
21078
21598
  function visit3(node) {
21079
- if (ts16.isIdentifier(node) && node.text === srcPropsName && shouldRewrite(node)) {
21599
+ if (ts17.isIdentifier(node) && node.text === srcPropsName && shouldRewrite(node)) {
21080
21600
  spans.push([node.getStart(sourceFile), node.getEnd()]);
21081
21601
  }
21082
- ts16.forEachChild(node, visit3);
21602
+ ts17.forEachChild(node, visit3);
21083
21603
  }
21084
21604
  visit3(sourceFile);
21085
21605
  if (spans.length === 0)
@@ -21095,17 +21615,17 @@ function shouldRewrite(node) {
21095
21615
  const parent = node.parent;
21096
21616
  if (!parent)
21097
21617
  return true;
21098
- if (ts16.isPropertyAccessExpression(parent) && parent.name === node)
21618
+ if (ts17.isPropertyAccessExpression(parent) && parent.name === node)
21099
21619
  return false;
21100
- if (ts16.isPropertyAssignment(parent) && parent.name === node)
21620
+ if (ts17.isPropertyAssignment(parent) && parent.name === node)
21101
21621
  return false;
21102
- if (ts16.isShorthandPropertyAssignment(parent) && parent.name === node)
21622
+ if (ts17.isShorthandPropertyAssignment(parent) && parent.name === node)
21103
21623
  return false;
21104
- if (ts16.isPropertySignature(parent) && parent.name === node)
21624
+ if (ts17.isPropertySignature(parent) && parent.name === node)
21105
21625
  return false;
21106
- if (ts16.isPropertyDeclaration(parent) && parent.name === node)
21626
+ if (ts17.isPropertyDeclaration(parent) && parent.name === node)
21107
21627
  return false;
21108
- if (ts16.isBindingElement(parent) && parent.name === node)
21628
+ if (ts17.isBindingElement(parent) && parent.name === node)
21109
21629
  return false;
21110
21630
  return true;
21111
21631
  }
@@ -21449,7 +21969,7 @@ function generateTemplateOnlyMount(ir, ctx) {
21449
21969
  }
21450
21970
  if (!templateHtml) {
21451
21971
  const csrInlinableConstants = csrInlinableConstantsFromCtx(ctx);
21452
- templateHtml = generateCsrTemplate(ir.root, csrInlinableConstants, ctx, undefined, restSpreadNames, ctx.propsObjectName, unsafeLocalNames);
21972
+ templateHtml = generateCsrTemplate(ir.root, csrInlinableConstants, ctx, restSpreadNames, ctx.propsObjectName, unsafeLocalNames);
21453
21973
  }
21454
21974
  if (!templateHtml) {
21455
21975
  return "";
@@ -21735,7 +22255,7 @@ function walkIR2(node, visitor) {
21735
22255
  }
21736
22256
 
21737
22257
  // src/preprocess-inline-jsx-callbacks.ts
21738
- import ts17 from "typescript";
22258
+ import ts18 from "typescript";
21739
22259
  var SYNTHETIC_PREFIX = "BFInlineJsxCallback";
21740
22260
  var MAX_FIXPOINT_ITERATIONS = 16;
21741
22261
  function preprocessInlineJsxCallbacks(source, filePath) {
@@ -21757,8 +22277,8 @@ function preprocessInlineJsxCallbacks(source, filePath) {
21757
22277
  return { source: current, errors, syntheticNames };
21758
22278
  }
21759
22279
  function runSinglePass(source, filePath, startingCounter) {
21760
- const sourceFile = ts17.createSourceFile(filePath, source, ts17.ScriptTarget.Latest, true, ts17.ScriptKind.TSX);
21761
- 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'"));
21762
22282
  if (!hasUseClient) {
21763
22283
  return { source, errors: [], syntheticNames: [], counterAfter: startingCounter };
21764
22284
  }
@@ -21780,22 +22300,22 @@ function runSinglePass(source, filePath, startingCounter) {
21780
22300
  }
21781
22301
  }
21782
22302
  function visit3(node) {
21783
- 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) {
21784
22304
  if (tryHandleArrowValue(node.initializer.expression)) {
21785
22305
  return;
21786
22306
  }
21787
22307
  }
21788
- if (ts17.isPropertyAssignment(node) && node.initializer) {
22308
+ if (ts18.isPropertyAssignment(node) && node.initializer) {
21789
22309
  if (tryHandleArrowValue(node.initializer))
21790
22310
  return;
21791
22311
  }
21792
- ts17.forEachChild(node, visit3);
22312
+ ts18.forEachChild(node, visit3);
21793
22313
  }
21794
22314
  function tryHandleArrowValue(initializer) {
21795
22315
  let expr = initializer;
21796
- while (ts17.isParenthesizedExpression(expr))
22316
+ while (ts18.isParenthesizedExpression(expr))
21797
22317
  expr = expr.expression;
21798
- if (ts17.isArrowFunction(expr) && arrowBodyContainsJsx(expr)) {
22318
+ if (ts18.isArrowFunction(expr) && arrowBodyContainsJsx(expr)) {
21799
22319
  return handleInlineArrow(expr);
21800
22320
  }
21801
22321
  return false;
@@ -21832,7 +22352,7 @@ function runSinglePass(source, filePath, startingCounter) {
21832
22352
  replacements.push({ start: arrowStart, end: arrowEnd, text: name });
21833
22353
  return true;
21834
22354
  }
21835
- ts17.forEachChild(sourceFile, visit3);
22355
+ ts18.forEachChild(sourceFile, visit3);
21836
22356
  if (replacements.length === 0) {
21837
22357
  return { source, errors, syntheticNames, counterAfter: counter };
21838
22358
  }
@@ -21855,11 +22375,11 @@ function errorMessageForCapture(captures) {
21855
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.`;
21856
22376
  }
21857
22377
  function arrowBodyContainsJsx(arrow) {
21858
- if (ts17.isBlock(arrow.body)) {
22378
+ if (ts18.isBlock(arrow.body)) {
21859
22379
  return blockReturnsJsx(arrow.body);
21860
22380
  }
21861
22381
  let body = arrow.body;
21862
- while (ts17.isParenthesizedExpression(body))
22382
+ while (ts18.isParenthesizedExpression(body))
21863
22383
  body = body.expression;
21864
22384
  return isJsxLike(body);
21865
22385
  }
@@ -21868,41 +22388,41 @@ function blockReturnsJsx(block) {
21868
22388
  function visit3(n) {
21869
22389
  if (found)
21870
22390
  return;
21871
- if (ts17.isReturnStatement(n) && n.expression) {
22391
+ if (ts18.isReturnStatement(n) && n.expression) {
21872
22392
  let e = n.expression;
21873
- while (ts17.isParenthesizedExpression(e))
22393
+ while (ts18.isParenthesizedExpression(e))
21874
22394
  e = e.expression;
21875
22395
  if (isJsxLike(e)) {
21876
22396
  found = true;
21877
22397
  return;
21878
22398
  }
21879
22399
  }
21880
- if (ts17.isArrowFunction(n) || ts17.isFunctionDeclaration(n) || ts17.isFunctionExpression(n))
22400
+ if (ts18.isArrowFunction(n) || ts18.isFunctionDeclaration(n) || ts18.isFunctionExpression(n))
21881
22401
  return;
21882
- ts17.forEachChild(n, visit3);
22402
+ ts18.forEachChild(n, visit3);
21883
22403
  }
21884
- ts17.forEachChild(block, visit3);
22404
+ ts18.forEachChild(block, visit3);
21885
22405
  return found;
21886
22406
  }
21887
22407
  function isJsxLike(expr) {
21888
- return ts17.isJsxElement(expr) || ts17.isJsxSelfClosingElement(expr) || ts17.isJsxFragment(expr);
22408
+ return ts18.isJsxElement(expr) || ts18.isJsxSelfClosingElement(expr) || ts18.isJsxFragment(expr);
21889
22409
  }
21890
22410
  function collectArrowParamNames(arrow) {
21891
22411
  const names = new Set;
21892
22412
  for (const p of arrow.parameters)
21893
- collectBindingNames2(p.name, names);
22413
+ collectBindingNames3(p.name, names);
21894
22414
  return names;
21895
22415
  }
21896
- function collectBindingNames2(name, out) {
22416
+ function collectBindingNames3(name, out) {
21897
22417
  const push = Array.isArray(out) ? (n) => out.push(n) : (n) => out.add(n);
21898
- if (ts17.isIdentifier(name)) {
22418
+ if (ts18.isIdentifier(name)) {
21899
22419
  push(name.text);
21900
- } else if (ts17.isObjectBindingPattern(name)) {
21901
- name.elements.forEach((el) => collectBindingNames2(el.name, out));
21902
- } 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)) {
21903
22423
  name.elements.forEach((el) => {
21904
- if (!ts17.isOmittedExpression(el))
21905
- collectBindingNames2(el.name, out);
22424
+ if (!ts18.isOmittedExpression(el))
22425
+ collectBindingNames3(el.name, out);
21906
22426
  });
21907
22427
  }
21908
22428
  }
@@ -21911,12 +22431,12 @@ function collectFreeIdentifiers(arrow) {
21911
22431
  const bound = [];
21912
22432
  for (const p of arrow.parameters) {
21913
22433
  const names = [];
21914
- collectBindingNames2(p.name, names);
22434
+ collectBindingNames3(p.name, names);
21915
22435
  bound.push(...names);
21916
22436
  }
21917
22437
  function pushBindings(name) {
21918
22438
  const names = [];
21919
- collectBindingNames2(name, names);
22439
+ collectBindingNames3(name, names);
21920
22440
  bound.push(...names);
21921
22441
  return names;
21922
22442
  }
@@ -21928,48 +22448,48 @@ function collectFreeIdentifiers(arrow) {
21928
22448
  return bound.includes(name);
21929
22449
  }
21930
22450
  function visit3(node) {
21931
- if (ts17.isIdentifier(node)) {
22451
+ if (ts18.isIdentifier(node)) {
21932
22452
  const parent = node.parent;
21933
- if (parent && ts17.isPropertyAccessExpression(parent) && parent.name === node)
22453
+ if (parent && ts18.isPropertyAccessExpression(parent) && parent.name === node)
21934
22454
  return;
21935
- if (parent && ts17.isPropertyAssignment(parent) && parent.name === node)
22455
+ if (parent && ts18.isPropertyAssignment(parent) && parent.name === node)
21936
22456
  return;
21937
- if (parent && ts17.isPropertySignature(parent) && parent.name === node)
22457
+ if (parent && ts18.isPropertySignature(parent) && parent.name === node)
21938
22458
  return;
21939
- if (parent && ts17.isPropertyDeclaration(parent) && parent.name === node)
22459
+ if (parent && ts18.isPropertyDeclaration(parent) && parent.name === node)
21940
22460
  return;
21941
- if (parent && ts17.isMethodDeclaration(parent) && parent.name === node)
22461
+ if (parent && ts18.isMethodDeclaration(parent) && parent.name === node)
21942
22462
  return;
21943
- if (parent && ts17.isMethodSignature(parent) && parent.name === node)
22463
+ if (parent && ts18.isMethodSignature(parent) && parent.name === node)
21944
22464
  return;
21945
- if (parent && ts17.isGetAccessorDeclaration(parent) && parent.name === node)
22465
+ if (parent && ts18.isGetAccessorDeclaration(parent) && parent.name === node)
21946
22466
  return;
21947
- if (parent && ts17.isSetAccessorDeclaration(parent) && parent.name === node)
22467
+ if (parent && ts18.isSetAccessorDeclaration(parent) && parent.name === node)
21948
22468
  return;
21949
- if (parent && ts17.isEnumMember(parent) && parent.name === node)
22469
+ if (parent && ts18.isEnumMember(parent) && parent.name === node)
21950
22470
  return;
21951
- if (parent && ts17.isBindingElement(parent) && parent.propertyName === node)
22471
+ if (parent && ts18.isBindingElement(parent) && parent.propertyName === node)
21952
22472
  return;
21953
- if (parent && ts17.isShorthandPropertyAssignment(parent) && parent.name === node) {
22473
+ if (parent && ts18.isShorthandPropertyAssignment(parent) && parent.name === node) {
21954
22474
  if (!isBound(node.text))
21955
22475
  ids.add(node.text);
21956
22476
  return;
21957
22477
  }
21958
- if (parent && ts17.isParameter(parent) && parent.name === node)
22478
+ if (parent && ts18.isParameter(parent) && parent.name === node)
21959
22479
  return;
21960
- if (parent && ts17.isVariableDeclaration(parent) && parent.name === node)
22480
+ if (parent && ts18.isVariableDeclaration(parent) && parent.name === node)
21961
22481
  return;
21962
- if (parent && ts17.isFunctionDeclaration(parent) && parent.name === node)
22482
+ if (parent && ts18.isFunctionDeclaration(parent) && parent.name === node)
21963
22483
  return;
21964
- if (parent && ts17.isClassDeclaration(parent) && parent.name === node)
22484
+ if (parent && ts18.isClassDeclaration(parent) && parent.name === node)
21965
22485
  return;
21966
- if (parent && ts17.isJsxAttribute(parent) && parent.name === node)
22486
+ if (parent && ts18.isJsxAttribute(parent) && parent.name === node)
21967
22487
  return;
21968
- if (parent && ts17.isJsxOpeningElement(parent) && parent.tagName === node) {
22488
+ if (parent && ts18.isJsxOpeningElement(parent) && parent.tagName === node) {
21969
22489
  if (/^[a-z]/.test(node.text))
21970
22490
  return;
21971
22491
  }
21972
- if (parent && ts17.isJsxClosingElement(parent) && parent.tagName === node) {
22492
+ if (parent && ts18.isJsxClosingElement(parent) && parent.tagName === node) {
21973
22493
  if (/^[a-z]/.test(node.text))
21974
22494
  return;
21975
22495
  }
@@ -21978,43 +22498,43 @@ function collectFreeIdentifiers(arrow) {
21978
22498
  ids.add(node.text);
21979
22499
  return;
21980
22500
  }
21981
- if (ts17.isVariableDeclaration(node)) {
22501
+ if (ts18.isVariableDeclaration(node)) {
21982
22502
  const declared = pushBindings(node.name);
21983
22503
  if (node.initializer)
21984
22504
  visit3(node.initializer);
21985
22505
  return;
21986
22506
  }
21987
- if (ts17.isFunctionDeclaration(node)) {
22507
+ if (ts18.isFunctionDeclaration(node)) {
21988
22508
  if (node.name)
21989
22509
  bound.push(node.name.text);
21990
22510
  visitInsideNewScope(node);
21991
22511
  return;
21992
22512
  }
21993
- if (ts17.isClassDeclaration(node)) {
22513
+ if (ts18.isClassDeclaration(node)) {
21994
22514
  if (node.name)
21995
22515
  bound.push(node.name.text);
21996
- ts17.forEachChild(node, visit3);
22516
+ ts18.forEachChild(node, visit3);
21997
22517
  return;
21998
22518
  }
21999
- if (ts17.isArrowFunction(node) || ts17.isFunctionExpression(node)) {
22519
+ if (ts18.isArrowFunction(node) || ts18.isFunctionExpression(node)) {
22000
22520
  visitInsideNewScope(node);
22001
22521
  return;
22002
22522
  }
22003
- if (ts17.isCatchClause(node)) {
22523
+ if (ts18.isCatchClause(node)) {
22004
22524
  const before = bound.length;
22005
22525
  if (node.variableDeclaration)
22006
22526
  pushBindings(node.variableDeclaration.name);
22007
- ts17.forEachChild(node, visit3);
22527
+ ts18.forEachChild(node, visit3);
22008
22528
  popN(bound.length - before);
22009
22529
  return;
22010
22530
  }
22011
- if (ts17.isBlock(node)) {
22531
+ if (ts18.isBlock(node)) {
22012
22532
  const before = bound.length;
22013
- ts17.forEachChild(node, visit3);
22533
+ ts18.forEachChild(node, visit3);
22014
22534
  popN(bound.length - before);
22015
22535
  return;
22016
22536
  }
22017
- ts17.forEachChild(node, visit3);
22537
+ ts18.forEachChild(node, visit3);
22018
22538
  }
22019
22539
  function visitInsideNewScope(fn) {
22020
22540
  const before = bound.length;
@@ -22037,29 +22557,29 @@ function collectFreeIdentifiers(arrow) {
22037
22557
  function collectModuleScopeNames(sourceFile) {
22038
22558
  const names = new Set;
22039
22559
  for (const stmt of sourceFile.statements) {
22040
- if (ts17.isFunctionDeclaration(stmt) && stmt.name)
22560
+ if (ts18.isFunctionDeclaration(stmt) && stmt.name)
22041
22561
  names.add(stmt.name.text);
22042
- else if (ts17.isClassDeclaration(stmt) && stmt.name)
22562
+ else if (ts18.isClassDeclaration(stmt) && stmt.name)
22043
22563
  names.add(stmt.name.text);
22044
- else if (ts17.isVariableStatement(stmt)) {
22564
+ else if (ts18.isVariableStatement(stmt)) {
22045
22565
  for (const decl of stmt.declarationList.declarations)
22046
- collectBindingNames2(decl.name, names);
22047
- } else if (ts17.isImportDeclaration(stmt) && stmt.importClause) {
22566
+ collectBindingNames3(decl.name, names);
22567
+ } else if (ts18.isImportDeclaration(stmt) && stmt.importClause) {
22048
22568
  const ic = stmt.importClause;
22049
22569
  if (ic.name)
22050
22570
  names.add(ic.name.text);
22051
22571
  if (ic.namedBindings) {
22052
- if (ts17.isNamespaceImport(ic.namedBindings))
22572
+ if (ts18.isNamespaceImport(ic.namedBindings))
22053
22573
  names.add(ic.namedBindings.name.text);
22054
22574
  else
22055
22575
  for (const e of ic.namedBindings.elements)
22056
22576
  names.add(e.name.text);
22057
22577
  }
22058
- } else if (ts17.isTypeAliasDeclaration(stmt))
22578
+ } else if (ts18.isTypeAliasDeclaration(stmt))
22059
22579
  names.add(stmt.name.text);
22060
- else if (ts17.isInterfaceDeclaration(stmt))
22580
+ else if (ts18.isInterfaceDeclaration(stmt))
22061
22581
  names.add(stmt.name.text);
22062
- else if (ts17.isEnumDeclaration(stmt))
22582
+ else if (ts18.isEnumDeclaration(stmt))
22063
22583
  names.add(stmt.name.text);
22064
22584
  }
22065
22585
  return names;
@@ -22067,7 +22587,7 @@ function collectModuleScopeNames(sourceFile) {
22067
22587
  function buildSyntheticDeclaration(name, arrow, sourceFile) {
22068
22588
  const paramsText = arrow.parameters.length === 0 ? "" : arrow.parameters.map((p) => p.getText(sourceFile)).join(", ");
22069
22589
  let bodyText;
22070
- if (ts17.isBlock(arrow.body)) {
22590
+ if (ts18.isBlock(arrow.body)) {
22071
22591
  bodyText = arrow.body.getText(sourceFile);
22072
22592
  } else {
22073
22593
  const expr = arrow.body.getText(sourceFile);
@@ -22077,7 +22597,7 @@ function buildSyntheticDeclaration(name, arrow, sourceFile) {
22077
22597
  }
22078
22598
 
22079
22599
  // src/ssr-defaults.ts
22080
- import ts18 from "typescript";
22600
+ import ts19 from "typescript";
22081
22601
  var UNRESOLVED = Symbol("unresolved");
22082
22602
  var NO_RETURN = Symbol("no-return");
22083
22603
  function extractSsrDefaults(metadata) {
@@ -22090,11 +22610,12 @@ function extractSsrDefaults(metadata) {
22090
22610
  for (const p of metadata.propsParams) {
22091
22611
  if (p.isRest)
22092
22612
  continue;
22613
+ const callerPropName = p.sourceName ?? p.name;
22093
22614
  if (metadata.propsObjectName === null && p.defaultValue !== undefined) {
22094
22615
  const value = tryStaticEval(p.defaultValue, { bindings: {}, propsLike });
22095
- out[p.name] = { propName: p.name, value: resultToJsonable(value) };
22616
+ out[p.name] = { propName: callerPropName, value: resultToJsonable(value) };
22096
22617
  } else {
22097
- out[p.name] = { propName: p.name, value: null };
22618
+ out[p.name] = { propName: callerPropName, value: null };
22098
22619
  }
22099
22620
  }
22100
22621
  if (metadata.restPropsName) {
@@ -22153,11 +22674,11 @@ function collectPropRefs(expr, propsObjectName, out) {
22153
22674
  if (!node)
22154
22675
  return;
22155
22676
  const visit3 = (n) => {
22156
- 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)) {
22157
22678
  out.add(n.name.text);
22158
22679
  return;
22159
22680
  }
22160
- ts18.forEachChild(n, visit3);
22681
+ ts19.forEachChild(n, visit3);
22161
22682
  };
22162
22683
  visit3(node);
22163
22684
  }
@@ -22178,23 +22699,23 @@ function tryStaticEval(expr, ctx) {
22178
22699
  }
22179
22700
  function evalStatementsForReturn(statements, ctx) {
22180
22701
  for (const stmt of statements) {
22181
- if (ts18.isVariableStatement(stmt)) {
22702
+ if (ts19.isVariableStatement(stmt)) {
22182
22703
  for (const d of stmt.declarationList.declarations) {
22183
- if (!ts18.isIdentifier(d.name) || !d.initializer)
22704
+ if (!ts19.isIdentifier(d.name) || !d.initializer)
22184
22705
  continue;
22185
22706
  const v = evalNode(d.initializer, ctx);
22186
22707
  if (v !== UNRESOLVED)
22187
22708
  ctx.bindings[d.name.text] = v;
22188
22709
  }
22189
- } else if (ts18.isReturnStatement(stmt)) {
22710
+ } else if (ts19.isReturnStatement(stmt)) {
22190
22711
  return stmt.expression ? evalNode(stmt.expression, ctx) : UNRESOLVED;
22191
- } else if (ts18.isIfStatement(stmt)) {
22712
+ } else if (ts19.isIfStatement(stmt)) {
22192
22713
  const cond = evalNode(stmt.expression, ctx);
22193
22714
  if (cond === UNRESOLVED)
22194
22715
  return UNRESOLVED;
22195
22716
  const branch = cond ? stmt.thenStatement : stmt.elseStatement;
22196
22717
  if (branch) {
22197
- const taken = evalStatementsForReturn(ts18.isBlock(branch) ? branch.statements : [branch], ctx);
22718
+ const taken = evalStatementsForReturn(ts19.isBlock(branch) ? branch.statements : [branch], ctx);
22198
22719
  if (taken !== NO_RETURN)
22199
22720
  return taken;
22200
22721
  }
@@ -22205,45 +22726,45 @@ function evalStatementsForReturn(statements, ctx) {
22205
22726
  return NO_RETURN;
22206
22727
  }
22207
22728
  function parseExpression2(expr) {
22208
- 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);
22209
22730
  const stmt = sf.statements[0];
22210
- if (!stmt || !ts18.isExpressionStatement(stmt))
22731
+ if (!stmt || !ts19.isExpressionStatement(stmt))
22211
22732
  return null;
22212
- const inner = ts18.isParenthesizedExpression(stmt.expression) ? stmt.expression.expression : stmt.expression;
22733
+ const inner = ts19.isParenthesizedExpression(stmt.expression) ? stmt.expression.expression : stmt.expression;
22213
22734
  return inner;
22214
22735
  }
22215
22736
  function evalNode(node, ctx) {
22216
- if (ts18.isParenthesizedExpression(node))
22737
+ if (ts19.isParenthesizedExpression(node))
22217
22738
  return evalNode(node.expression, ctx);
22218
- if (ts18.isAsExpression(node))
22739
+ if (ts19.isAsExpression(node))
22219
22740
  return evalNode(node.expression, ctx);
22220
- if (ts18.isSatisfiesExpression(node))
22741
+ if (ts19.isSatisfiesExpression(node))
22221
22742
  return evalNode(node.expression, ctx);
22222
- if (ts18.isTypeAssertionExpression(node))
22743
+ if (ts19.isTypeAssertionExpression(node))
22223
22744
  return evalNode(node.expression, ctx);
22224
- if (ts18.isNonNullExpression(node))
22745
+ if (ts19.isNonNullExpression(node))
22225
22746
  return evalNode(node.expression, ctx);
22226
- if (ts18.isArrowFunction(node)) {
22747
+ if (ts19.isArrowFunction(node)) {
22227
22748
  if (node.parameters.length !== 0)
22228
22749
  return UNRESOLVED;
22229
- if (!ts18.isBlock(node.body))
22750
+ if (!ts19.isBlock(node.body))
22230
22751
  return evalNode(node.body, ctx);
22231
22752
  const localBindings = { ...ctx.bindings };
22232
22753
  const localCtx = { ...ctx, bindings: localBindings };
22233
22754
  const result = evalStatementsForReturn(node.body.statements, localCtx);
22234
22755
  return result === NO_RETURN ? UNRESOLVED : result;
22235
22756
  }
22236
- if (ts18.isNumericLiteral(node))
22757
+ if (ts19.isNumericLiteral(node))
22237
22758
  return Number(node.text);
22238
- if (ts18.isStringLiteralLike(node))
22759
+ if (ts19.isStringLiteralLike(node))
22239
22760
  return node.text;
22240
- if (node.kind === ts18.SyntaxKind.TrueKeyword)
22761
+ if (node.kind === ts19.SyntaxKind.TrueKeyword)
22241
22762
  return true;
22242
- if (node.kind === ts18.SyntaxKind.FalseKeyword)
22763
+ if (node.kind === ts19.SyntaxKind.FalseKeyword)
22243
22764
  return false;
22244
- if (node.kind === ts18.SyntaxKind.NullKeyword)
22765
+ if (node.kind === ts19.SyntaxKind.NullKeyword)
22245
22766
  return null;
22246
- if (ts18.isIdentifier(node)) {
22767
+ if (ts19.isIdentifier(node)) {
22247
22768
  if (node.text === "undefined")
22248
22769
  return;
22249
22770
  if (node.text in ctx.bindings)
@@ -22252,29 +22773,29 @@ function evalNode(node, ctx) {
22252
22773
  return;
22253
22774
  return UNRESOLVED;
22254
22775
  }
22255
- if (ts18.isPrefixUnaryExpression(node)) {
22776
+ if (ts19.isPrefixUnaryExpression(node)) {
22256
22777
  const arg = evalNode(node.operand, ctx);
22257
22778
  if (arg === UNRESOLVED)
22258
22779
  return UNRESOLVED;
22259
22780
  switch (node.operator) {
22260
- case ts18.SyntaxKind.MinusToken:
22781
+ case ts19.SyntaxKind.MinusToken:
22261
22782
  return typeof arg === "number" ? -arg : UNRESOLVED;
22262
- case ts18.SyntaxKind.PlusToken:
22783
+ case ts19.SyntaxKind.PlusToken:
22263
22784
  return typeof arg === "number" ? +arg : UNRESOLVED;
22264
- case ts18.SyntaxKind.ExclamationToken:
22785
+ case ts19.SyntaxKind.ExclamationToken:
22265
22786
  return !arg;
22266
22787
  }
22267
22788
  return UNRESOLVED;
22268
22789
  }
22269
- if (ts18.isObjectLiteralExpression(node)) {
22790
+ if (ts19.isObjectLiteralExpression(node)) {
22270
22791
  const obj = {};
22271
22792
  for (const prop of node.properties) {
22272
- if (!ts18.isPropertyAssignment(prop))
22793
+ if (!ts19.isPropertyAssignment(prop))
22273
22794
  return UNRESOLVED;
22274
22795
  let key;
22275
- if (ts18.isIdentifier(prop.name) || ts18.isStringLiteralLike(prop.name)) {
22796
+ if (ts19.isIdentifier(prop.name) || ts19.isStringLiteralLike(prop.name)) {
22276
22797
  key = prop.name.text;
22277
- } else if (ts18.isNumericLiteral(prop.name)) {
22798
+ } else if (ts19.isNumericLiteral(prop.name)) {
22278
22799
  key = prop.name.text;
22279
22800
  } else {
22280
22801
  return UNRESOLVED;
@@ -22286,10 +22807,10 @@ function evalNode(node, ctx) {
22286
22807
  }
22287
22808
  return obj;
22288
22809
  }
22289
- if (ts18.isArrayLiteralExpression(node)) {
22810
+ if (ts19.isArrayLiteralExpression(node)) {
22290
22811
  const arr = [];
22291
22812
  for (const elem of node.elements) {
22292
- if (ts18.isOmittedExpression(elem))
22813
+ if (ts19.isOmittedExpression(elem))
22293
22814
  return UNRESOLVED;
22294
22815
  const v = evalNode(elem, ctx);
22295
22816
  if (v === UNRESOLVED)
@@ -22298,7 +22819,7 @@ function evalNode(node, ctx) {
22298
22819
  }
22299
22820
  return arr;
22300
22821
  }
22301
- if (ts18.isElementAccessExpression(node)) {
22822
+ if (ts19.isElementAccessExpression(node)) {
22302
22823
  const base = evalNode(node.expression, ctx);
22303
22824
  if (base === undefined)
22304
22825
  return;
@@ -22312,17 +22833,17 @@ function evalNode(node, ctx) {
22312
22833
  const k = String(key);
22313
22834
  return Object.prototype.hasOwnProperty.call(base, k) ? base[k] : undefined;
22314
22835
  }
22315
- if (ts18.isPropertyAccessExpression(node)) {
22836
+ if (ts19.isPropertyAccessExpression(node)) {
22316
22837
  const baseResult = evalNode(node.expression, ctx);
22317
22838
  if (baseResult === undefined)
22318
22839
  return;
22319
22840
  return UNRESOLVED;
22320
22841
  }
22321
- if (ts18.isCallExpression(node)) {
22322
- 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) {
22323
22844
  return ctx.bindings[node.expression.text];
22324
22845
  }
22325
- if (ts18.isPropertyAccessExpression(node.expression) && node.expression.name.text === "join") {
22846
+ if (ts19.isPropertyAccessExpression(node.expression) && node.expression.name.text === "join") {
22326
22847
  const recv = evalNode(node.expression.expression, ctx);
22327
22848
  if (Array.isArray(recv)) {
22328
22849
  let sep2 = ",";
@@ -22338,27 +22859,27 @@ function evalNode(node, ctx) {
22338
22859
  }
22339
22860
  return UNRESOLVED;
22340
22861
  }
22341
- if (ts18.isConditionalExpression(node)) {
22862
+ if (ts19.isConditionalExpression(node)) {
22342
22863
  const cond = evalNode(node.condition, ctx);
22343
22864
  if (cond === UNRESOLVED)
22344
22865
  return UNRESOLVED;
22345
22866
  return cond ? evalNode(node.whenTrue, ctx) : evalNode(node.whenFalse, ctx);
22346
22867
  }
22347
- if (ts18.isBinaryExpression(node)) {
22868
+ if (ts19.isBinaryExpression(node)) {
22348
22869
  const op = node.operatorToken.kind;
22349
- if (op === ts18.SyntaxKind.QuestionQuestionToken) {
22870
+ if (op === ts19.SyntaxKind.QuestionQuestionToken) {
22350
22871
  const l2 = evalNode(node.left, ctx);
22351
22872
  if (l2 !== UNRESOLVED && l2 !== null && l2 !== undefined)
22352
22873
  return l2;
22353
22874
  return evalNode(node.right, ctx);
22354
22875
  }
22355
- if (op === ts18.SyntaxKind.BarBarToken) {
22876
+ if (op === ts19.SyntaxKind.BarBarToken) {
22356
22877
  const l2 = evalNode(node.left, ctx);
22357
22878
  if (l2 !== UNRESOLVED && l2)
22358
22879
  return l2;
22359
22880
  return evalNode(node.right, ctx);
22360
22881
  }
22361
- if (op === ts18.SyntaxKind.AmpersandAmpersandToken) {
22882
+ if (op === ts19.SyntaxKind.AmpersandAmpersandToken) {
22362
22883
  const l2 = evalNode(node.left, ctx);
22363
22884
  if (l2 === UNRESOLVED)
22364
22885
  return UNRESOLVED;
@@ -22371,30 +22892,30 @@ function evalNode(node, ctx) {
22371
22892
  if (l === UNRESOLVED || r === UNRESOLVED)
22372
22893
  return UNRESOLVED;
22373
22894
  switch (op) {
22374
- case ts18.SyntaxKind.PlusToken:
22895
+ case ts19.SyntaxKind.PlusToken:
22375
22896
  if (typeof l === "string" || typeof r === "string")
22376
22897
  return `${l}${r}`;
22377
22898
  if (typeof l === "number" && typeof r === "number")
22378
22899
  return l + r;
22379
22900
  return UNRESOLVED;
22380
- case ts18.SyntaxKind.MinusToken:
22901
+ case ts19.SyntaxKind.MinusToken:
22381
22902
  return typeof l === "number" && typeof r === "number" ? l - r : UNRESOLVED;
22382
- case ts18.SyntaxKind.AsteriskToken:
22903
+ case ts19.SyntaxKind.AsteriskToken:
22383
22904
  return typeof l === "number" && typeof r === "number" ? l * r : UNRESOLVED;
22384
- case ts18.SyntaxKind.SlashToken:
22905
+ case ts19.SyntaxKind.SlashToken:
22385
22906
  return typeof l === "number" && typeof r === "number" && r !== 0 ? l / r : UNRESOLVED;
22386
- case ts18.SyntaxKind.PercentToken:
22907
+ case ts19.SyntaxKind.PercentToken:
22387
22908
  return typeof l === "number" && typeof r === "number" && r !== 0 ? l % r : UNRESOLVED;
22388
- case ts18.SyntaxKind.EqualsEqualsEqualsToken:
22389
- case ts18.SyntaxKind.EqualsEqualsToken:
22909
+ case ts19.SyntaxKind.EqualsEqualsEqualsToken:
22910
+ case ts19.SyntaxKind.EqualsEqualsToken:
22390
22911
  return l === r;
22391
- case ts18.SyntaxKind.ExclamationEqualsEqualsToken:
22392
- case ts18.SyntaxKind.ExclamationEqualsToken:
22912
+ case ts19.SyntaxKind.ExclamationEqualsEqualsToken:
22913
+ case ts19.SyntaxKind.ExclamationEqualsToken:
22393
22914
  return l !== r;
22394
22915
  }
22395
22916
  return UNRESOLVED;
22396
22917
  }
22397
- if (ts18.isTemplateExpression(node)) {
22918
+ if (ts19.isTemplateExpression(node)) {
22398
22919
  if (node.templateSpans.length === 0)
22399
22920
  return node.head.text;
22400
22921
  let acc = node.head.text;
@@ -22406,13 +22927,13 @@ function evalNode(node, ctx) {
22406
22927
  }
22407
22928
  return acc;
22408
22929
  }
22409
- if (ts18.isNoSubstitutionTemplateLiteral(node))
22930
+ if (ts19.isNoSubstitutionTemplateLiteral(node))
22410
22931
  return node.text;
22411
22932
  return UNRESOLVED;
22412
22933
  }
22413
22934
 
22414
22935
  // src/augment-inherited-props.ts
22415
- import ts19 from "typescript";
22936
+ import ts20 from "typescript";
22416
22937
  function collectContextConsumers(metadata) {
22417
22938
  const constants = metadata.localConstants ?? [];
22418
22939
  const contextDefaults = new Map;
@@ -22444,47 +22965,47 @@ function collectContextConsumers(metadata) {
22444
22965
  }
22445
22966
  function parseUseContextArg(source) {
22446
22967
  const expr = parseSingleExpression(source);
22447
- if (!expr || !ts19.isCallExpression(expr))
22968
+ if (!expr || !ts20.isCallExpression(expr))
22448
22969
  return null;
22449
- if (!ts19.isIdentifier(expr.expression) || expr.expression.text !== "useContext")
22970
+ if (!ts20.isIdentifier(expr.expression) || expr.expression.text !== "useContext")
22450
22971
  return null;
22451
22972
  if (expr.arguments.length !== 1)
22452
22973
  return null;
22453
22974
  const arg = expr.arguments[0];
22454
- return ts19.isIdentifier(arg) ? arg.text : null;
22975
+ return ts20.isIdentifier(arg) ? arg.text : null;
22455
22976
  }
22456
22977
  function parseCreateContextDefault(source) {
22457
22978
  const expr = parseSingleExpression(source);
22458
- if (!expr || !ts19.isCallExpression(expr))
22979
+ if (!expr || !ts20.isCallExpression(expr))
22459
22980
  return null;
22460
22981
  if (expr.arguments.length === 0)
22461
22982
  return null;
22462
22983
  const arg = expr.arguments[0];
22463
- if (ts19.isStringLiteral(arg) || ts19.isNoSubstitutionTemplateLiteral(arg))
22984
+ if (ts20.isStringLiteral(arg) || ts20.isNoSubstitutionTemplateLiteral(arg))
22464
22985
  return arg.text;
22465
- if (ts19.isNumericLiteral(arg))
22986
+ if (ts20.isNumericLiteral(arg))
22466
22987
  return Number(arg.text);
22467
- if (arg.kind === ts19.SyntaxKind.TrueKeyword)
22988
+ if (arg.kind === ts20.SyntaxKind.TrueKeyword)
22468
22989
  return true;
22469
- if (arg.kind === ts19.SyntaxKind.FalseKeyword)
22990
+ if (arg.kind === ts20.SyntaxKind.FalseKeyword)
22470
22991
  return false;
22471
22992
  return null;
22472
22993
  }
22473
22994
  function isObjectLiteralCreateContextDefault(source) {
22474
22995
  const expr = parseSingleExpression(source);
22475
- if (!expr || !ts19.isCallExpression(expr))
22996
+ if (!expr || !ts20.isCallExpression(expr))
22476
22997
  return false;
22477
22998
  if (expr.arguments.length === 0)
22478
22999
  return false;
22479
- return ts19.isObjectLiteralExpression(expr.arguments[0]);
23000
+ return ts20.isObjectLiteralExpression(expr.arguments[0]);
22480
23001
  }
22481
23002
  function parseSingleExpression(source) {
22482
- const sf = ts19.createSourceFile("__ctx.ts", `(${source})`, ts19.ScriptTarget.Latest, false);
23003
+ const sf = ts20.createSourceFile("__ctx.ts", `(${source})`, ts20.ScriptTarget.Latest, false);
22483
23004
  const stmt = sf.statements[0];
22484
- if (!stmt || !ts19.isExpressionStatement(stmt))
23005
+ if (!stmt || !ts20.isExpressionStatement(stmt))
22485
23006
  return null;
22486
23007
  let e = stmt.expression;
22487
- while (ts19.isParenthesizedExpression(e))
23008
+ while (ts20.isParenthesizedExpression(e))
22488
23009
  e = e.expression;
22489
23010
  return e;
22490
23011
  }
@@ -22509,25 +23030,25 @@ function augmentInheritedPropAccesses(ir) {
22509
23030
  const pinCoalesceLiterals = (s) => {
22510
23031
  if (!s || !s.includes(propsObj))
22511
23032
  return;
22512
- const sf = ts19.createSourceFile("__aug.ts", `(${s})`, ts19.ScriptTarget.Latest, false);
23033
+ const sf = ts20.createSourceFile("__aug.ts", `(${s})`, ts20.ScriptTarget.Latest, false);
22513
23034
  const visit3 = (n) => {
22514
- 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)) {
22515
23036
  let left = n.left;
22516
- while (ts19.isParenthesizedExpression(left))
23037
+ while (ts20.isParenthesizedExpression(left))
22517
23038
  left = left.expression;
22518
- 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) {
22519
23040
  const name = left.name.text;
22520
23041
  let right = n.right;
22521
- while (ts19.isParenthesizedExpression(right))
23042
+ while (ts20.isParenthesizedExpression(right))
22522
23043
  right = right.expression;
22523
- if (ts19.isPrefixUnaryExpression(right))
23044
+ if (ts20.isPrefixUnaryExpression(right))
22524
23045
  right = right.operand;
22525
- 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;
22526
23047
  if (kind && !coalesceLiteralTypes.has(name))
22527
23048
  coalesceLiteralTypes.set(name, kind);
22528
23049
  }
22529
23050
  }
22530
- ts19.forEachChild(n, visit3);
23051
+ ts20.forEachChild(n, visit3);
22531
23052
  };
22532
23053
  visit3(sf);
22533
23054
  };
@@ -22638,33 +23159,33 @@ function augmentInheritedPropAccesses(ir) {
22638
23159
  }
22639
23160
  }
22640
23161
  function parseStaticStringConst(source) {
22641
- 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);
22642
23163
  const stmt = sf.statements[0];
22643
- if (!stmt || !ts19.isVariableStatement(stmt))
23164
+ if (!stmt || !ts20.isVariableStatement(stmt))
22644
23165
  return null;
22645
23166
  let init = stmt.declarationList.declarations[0]?.initializer;
22646
- while (init && ts19.isParenthesizedExpression(init))
23167
+ while (init && ts20.isParenthesizedExpression(init))
22647
23168
  init = init.expression;
22648
23169
  if (!init)
22649
23170
  return null;
22650
- if (ts19.isStringLiteral(init) || ts19.isNoSubstitutionTemplateLiteral(init)) {
23171
+ if (ts20.isStringLiteral(init) || ts20.isNoSubstitutionTemplateLiteral(init)) {
22651
23172
  return init.text;
22652
23173
  }
22653
23174
  return evalStringArrayJoin(source);
22654
23175
  }
22655
23176
  function evalTemplateOfStringConsts(source, resolved) {
22656
- 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);
22657
23178
  const stmt = sf.statements[0];
22658
- if (!stmt || !ts19.isVariableStatement(stmt))
23179
+ if (!stmt || !ts20.isVariableStatement(stmt))
22659
23180
  return null;
22660
23181
  let init = stmt.declarationList.declarations[0]?.initializer;
22661
- while (init && ts19.isParenthesizedExpression(init))
23182
+ while (init && ts20.isParenthesizedExpression(init))
22662
23183
  init = init.expression;
22663
- if (!init || !ts19.isTemplateExpression(init))
23184
+ if (!init || !ts20.isTemplateExpression(init))
22664
23185
  return null;
22665
23186
  let out = init.head.text;
22666
23187
  for (const span of init.templateSpans) {
22667
- if (!ts19.isIdentifier(span.expression))
23188
+ if (!ts20.isIdentifier(span.expression))
22668
23189
  return null;
22669
23190
  const value = resolved.get(span.expression.text);
22670
23191
  if (value === undefined)
@@ -22695,30 +23216,30 @@ function lookupStaticRecordLiteral(objectName, key, constants) {
22695
23216
  const constInfo = (constants ?? []).find((c) => c.name === objectName && c.isModule);
22696
23217
  if (constInfo?.value === undefined)
22697
23218
  return null;
22698
- 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);
22699
23220
  if (sf.statements.length !== 1)
22700
23221
  return null;
22701
23222
  const stmt = sf.statements[0];
22702
- if (!ts19.isExpressionStatement(stmt))
23223
+ if (!ts20.isExpressionStatement(stmt))
22703
23224
  return null;
22704
23225
  let parsed = stmt.expression;
22705
- while (ts19.isParenthesizedExpression(parsed))
23226
+ while (ts20.isParenthesizedExpression(parsed))
22706
23227
  parsed = parsed.expression;
22707
- if (!ts19.isObjectLiteralExpression(parsed))
23228
+ if (!ts20.isObjectLiteralExpression(parsed))
22708
23229
  return null;
22709
23230
  for (const prop of parsed.properties) {
22710
- if (!ts19.isPropertyAssignment(prop))
23231
+ if (!ts20.isPropertyAssignment(prop))
22711
23232
  continue;
22712
23233
  const name = prop.name;
22713
- 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;
22714
23235
  if (propKey !== key)
22715
23236
  continue;
22716
23237
  let v = prop.initializer;
22717
- while (ts19.isParenthesizedExpression(v))
23238
+ while (ts20.isParenthesizedExpression(v))
22718
23239
  v = v.expression;
22719
- if (ts19.isNumericLiteral(v))
23240
+ if (ts20.isNumericLiteral(v))
22720
23241
  return { kind: "number", text: v.text };
22721
- if (ts19.isStringLiteral(v) || ts19.isNoSubstitutionTemplateLiteral(v)) {
23242
+ if (ts20.isStringLiteral(v) || ts20.isNoSubstitutionTemplateLiteral(v)) {
22722
23243
  return { kind: "string", text: v.text };
22723
23244
  }
22724
23245
  return null;
@@ -22726,28 +23247,28 @@ function lookupStaticRecordLiteral(objectName, key, constants) {
22726
23247
  return null;
22727
23248
  }
22728
23249
  function evalStringArrayJoin(source) {
22729
- 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);
22730
23251
  const stmt = sf.statements[0];
22731
- if (!stmt || !ts19.isVariableStatement(stmt))
23252
+ if (!stmt || !ts20.isVariableStatement(stmt))
22732
23253
  return null;
22733
23254
  let node = stmt.declarationList.declarations[0]?.initializer;
22734
- while (node && ts19.isParenthesizedExpression(node))
23255
+ while (node && ts20.isParenthesizedExpression(node))
22735
23256
  node = node.expression;
22736
- if (!node || !ts19.isCallExpression(node))
23257
+ if (!node || !ts20.isCallExpression(node))
22737
23258
  return null;
22738
23259
  const callee = node.expression;
22739
- if (!ts19.isPropertyAccessExpression(callee))
23260
+ if (!ts20.isPropertyAccessExpression(callee))
22740
23261
  return null;
22741
23262
  if (callee.name.text !== "join")
22742
23263
  return null;
22743
23264
  let recv = callee.expression;
22744
- while (ts19.isParenthesizedExpression(recv))
23265
+ while (ts20.isParenthesizedExpression(recv))
22745
23266
  recv = recv.expression;
22746
- if (!ts19.isArrayLiteralExpression(recv))
23267
+ if (!ts20.isArrayLiteralExpression(recv))
22747
23268
  return null;
22748
23269
  const parts = [];
22749
23270
  for (const el of recv.elements) {
22750
- if (ts19.isStringLiteral(el) || ts19.isNoSubstitutionTemplateLiteral(el)) {
23271
+ if (ts20.isStringLiteral(el) || ts20.isNoSubstitutionTemplateLiteral(el)) {
22751
23272
  parts.push(el.text);
22752
23273
  } else {
22753
23274
  return null;
@@ -22756,7 +23277,7 @@ function evalStringArrayJoin(source) {
22756
23277
  let sep2 = ",";
22757
23278
  if (node.arguments.length >= 1) {
22758
23279
  const arg = node.arguments[0];
22759
- if (ts19.isStringLiteral(arg) || ts19.isNoSubstitutionTemplateLiteral(arg))
23280
+ if (ts20.isStringLiteral(arg) || ts20.isNoSubstitutionTemplateLiteral(arg))
22760
23281
  sep2 = arg.text;
22761
23282
  else
22762
23283
  return null;
@@ -22764,11 +23285,11 @@ function evalStringArrayJoin(source) {
22764
23285
  return parts.join(sep2);
22765
23286
  }
22766
23287
  function parseRecordIndexAccess(val, localConstants, propsParams, resolveKey) {
22767
- if (!ts19.isElementAccessExpression(val))
23288
+ if (!ts20.isElementAccessExpression(val))
22768
23289
  return null;
22769
23290
  const obj = val.expression;
22770
23291
  const arg = val.argumentExpression;
22771
- if (!ts19.isIdentifier(obj) || !ts19.isIdentifier(arg))
23292
+ if (!ts20.isIdentifier(obj) || !ts20.isIdentifier(arg))
22772
23293
  return null;
22773
23294
  let indexPropName;
22774
23295
  let defaultKey;
@@ -22784,35 +23305,35 @@ function parseRecordIndexAccess(val, localConstants, propsParams, resolveKey) {
22784
23305
  const constInfo = localConstants.find((c) => c.name === obj.text && c.isModule);
22785
23306
  if (constInfo?.value === undefined)
22786
23307
  return null;
22787
- 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);
22788
23309
  if (sf.statements.length !== 1)
22789
23310
  return null;
22790
23311
  const stmt = sf.statements[0];
22791
- if (!ts19.isExpressionStatement(stmt))
23312
+ if (!ts20.isExpressionStatement(stmt))
22792
23313
  return null;
22793
23314
  let parsed = stmt.expression;
22794
- while (ts19.isParenthesizedExpression(parsed))
23315
+ while (ts20.isParenthesizedExpression(parsed))
22795
23316
  parsed = parsed.expression;
22796
- if (!ts19.isObjectLiteralExpression(parsed))
23317
+ if (!ts20.isObjectLiteralExpression(parsed))
22797
23318
  return null;
22798
23319
  const entries = [];
22799
23320
  for (const prop of parsed.properties) {
22800
- if (!ts19.isPropertyAssignment(prop))
23321
+ if (!ts20.isPropertyAssignment(prop))
22801
23322
  return null;
22802
23323
  let key;
22803
- if (ts19.isIdentifier(prop.name)) {
23324
+ if (ts20.isIdentifier(prop.name)) {
22804
23325
  key = prop.name.text;
22805
- } else if (ts19.isStringLiteral(prop.name) || ts19.isNoSubstitutionTemplateLiteral(prop.name)) {
23326
+ } else if (ts20.isStringLiteral(prop.name) || ts20.isNoSubstitutionTemplateLiteral(prop.name)) {
22806
23327
  key = prop.name.text;
22807
23328
  } else {
22808
23329
  return null;
22809
23330
  }
22810
23331
  let v = prop.initializer;
22811
- while (ts19.isParenthesizedExpression(v))
23332
+ while (ts20.isParenthesizedExpression(v))
22812
23333
  v = v.expression;
22813
- if (ts19.isNumericLiteral(v)) {
23334
+ if (ts20.isNumericLiteral(v)) {
22814
23335
  entries.push({ key, value: { kind: "number", text: v.text } });
22815
- } else if (ts19.isStringLiteral(v) || ts19.isNoSubstitutionTemplateLiteral(v)) {
23336
+ } else if (ts20.isStringLiteral(v) || ts20.isNoSubstitutionTemplateLiteral(v)) {
22816
23337
  entries.push({ key, value: { kind: "string", text: v.text } });
22817
23338
  } else {
22818
23339
  return null;
@@ -23595,7 +24116,7 @@ function compileJSX(source, filePath, options) {
23595
24116
  return { files, errors };
23596
24117
  }
23597
24118
  // src/shared-program.ts
23598
- import ts20 from "typescript";
24119
+ import ts21 from "typescript";
23599
24120
  function commonParent(paths) {
23600
24121
  if (paths.length === 0)
23601
24122
  return process.cwd();
@@ -23616,10 +24137,10 @@ function commonParent(paths) {
23616
24137
  function createProgramForCorpus(files, options = {}) {
23617
24138
  const baseUrl = options.baseUrl ?? commonParent(files);
23618
24139
  const compilerOptions = {
23619
- target: ts20.ScriptTarget.Latest,
23620
- module: ts20.ModuleKind.ESNext,
23621
- moduleResolution: ts20.ModuleResolutionKind.Bundler,
23622
- jsx: ts20.JsxEmit.ReactJSX,
24140
+ target: ts21.ScriptTarget.Latest,
24141
+ module: ts21.ModuleKind.ESNext,
24142
+ moduleResolution: ts21.ModuleResolutionKind.Bundler,
24143
+ jsx: ts21.JsxEmit.ReactJSX,
23623
24144
  strict: true,
23624
24145
  skipLibCheck: true,
23625
24146
  noEmit: true,
@@ -23629,7 +24150,7 @@ function createProgramForCorpus(files, options = {}) {
23629
24150
  ...options.compilerOptions
23630
24151
  };
23631
24152
  const absolute = files.map((f) => path_default.resolve(f));
23632
- return ts20.createProgram(absolute, compilerOptions, undefined, options.oldProgram);
24153
+ return ts21.createProgram(absolute, compilerOptions, undefined, options.oldProgram);
23633
24154
  }
23634
24155
  // src/adapters/interface.ts
23635
24156
  class BaseAdapter {
@@ -24184,6 +24705,8 @@ function collectLoopBoundNames(ir) {
24184
24705
  names.add(binding.name);
24185
24706
  if (node.filterPredicate)
24186
24707
  names.add(node.filterPredicate.param);
24708
+ for (const name of node.preamble?.declaredNames ?? [])
24709
+ names.add(name);
24187
24710
  for (const child of node.children)
24188
24711
  visit3(child);
24189
24712
  if (node.childComponent) {
@@ -24611,7 +25134,7 @@ function dangerousInnerHtmlDiagnostic(expr, loc, reason) {
24611
25134
  };
24612
25135
  }
24613
25136
  // src/combine-client-js.ts
24614
- import ts21 from "typescript";
25137
+ import ts22 from "typescript";
24615
25138
  var CHILD_PLACEHOLDER_RE = /import '\/\* @bf-child:(\w+) \*\/'/g;
24616
25139
  function combineParentChildClientJs(files) {
24617
25140
  const result = new Map;
@@ -24668,10 +25191,10 @@ function combineParentChildClientJs(files) {
24668
25191
  return result;
24669
25192
  }
24670
25193
  function parseAndMerge(content, importsBySource, otherImports, codeSections) {
24671
- 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);
24672
25195
  const importSpans = [];
24673
25196
  for (const stmt of sourceFile.statements) {
24674
- if (!ts21.isImportDeclaration(stmt))
25197
+ if (!ts22.isImportDeclaration(stmt))
24675
25198
  continue;
24676
25199
  const start = stmt.getStart(sourceFile);
24677
25200
  const end = stmt.getEnd();
@@ -24681,8 +25204,8 @@ function parseAndMerge(content, importsBySource, otherImports, codeSections) {
24681
25204
  continue;
24682
25205
  const clause = stmt.importClause;
24683
25206
  const bindings = clause?.namedBindings;
24684
- const specifier = ts21.isStringLiteral(stmt.moduleSpecifier) ? stmt.moduleSpecifier.text : "";
24685
- 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)) {
24686
25209
  if (!importsBySource.has(specifier)) {
24687
25210
  importsBySource.set(specifier, new Set);
24688
25211
  }
@@ -24849,7 +25372,7 @@ function escapeRe(s) {
24849
25372
  return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
24850
25373
  }
24851
25374
  // src/debug.ts
24852
- import ts22 from "typescript";
25375
+ import ts23 from "typescript";
24853
25376
  function buildComponentGraph(source, filePath, componentName) {
24854
25377
  const ctx = analyzeComponent(source, filePath, componentName);
24855
25378
  if (!ctx.jsxReturn) {
@@ -26134,7 +26657,7 @@ function truncateExpr(expr, max = 40) {
26134
26657
  function exprReadsPropMember(expr, propsObjectName) {
26135
26658
  let sf;
26136
26659
  try {
26137
- 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);
26138
26661
  } catch {
26139
26662
  return false;
26140
26663
  }
@@ -26142,11 +26665,11 @@ function exprReadsPropMember(expr, propsObjectName) {
26142
26665
  const visit3 = (n) => {
26143
26666
  if (found)
26144
26667
  return;
26145
- 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") {
26146
26669
  found = true;
26147
26670
  return;
26148
26671
  }
26149
- ts22.forEachChild(n, visit3);
26672
+ ts23.forEachChild(n, visit3);
26150
26673
  };
26151
26674
  visit3(sf);
26152
26675
  return found;
@@ -26216,7 +26739,7 @@ function findSourceFile2(meta) {
26216
26739
  return null;
26217
26740
  }
26218
26741
  // src/profiler.ts
26219
- import ts23 from "typescript";
26742
+ import ts24 from "typescript";
26220
26743
  var PROFILE_SCHEMA_VERSION = 1;
26221
26744
  var DEFAULT_FANOUT_THRESHOLD = 8;
26222
26745
  function buildStaticBudget(source, filePath, componentName, options = {}) {
@@ -26486,15 +27009,15 @@ function joinProfilerEvents(events, index) {
26486
27009
  return { joined, unattributed, diagnostics };
26487
27010
  }
26488
27011
  function findUninstrumentedEffects(source, filePath, instrumentedLines) {
26489
- 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);
26490
27013
  const out = [];
26491
27014
  const visit3 = (node) => {
26492
- 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") {
26493
27016
  const line = sf.getLineAndCharacterOfPosition(node.getStart(sf)).line + 1;
26494
27017
  if (!instrumentedLines.has(line))
26495
27018
  out.push({ file: filePath, line });
26496
27019
  }
26497
- ts23.forEachChild(node, visit3);
27020
+ ts24.forEachChild(node, visit3);
26498
27021
  };
26499
27022
  visit3(sf);
26500
27023
  out.sort((a, b) => a.line - b.line);
@@ -26802,13 +27325,13 @@ function assessBatchSafety(args) {
26802
27325
  const signalGetters = new Set(args.graph.signals.map((s) => s.name));
26803
27326
  let sf;
26804
27327
  try {
26805
- 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);
26806
27329
  } catch {
26807
27330
  return "unverified";
26808
27331
  }
26809
27332
  const calls = [];
26810
27333
  const visit3 = (node) => {
26811
- if (ts23.isCallExpression(node) && ts23.isIdentifier(node.expression)) {
27334
+ if (ts24.isCallExpression(node) && ts24.isIdentifier(node.expression)) {
26812
27335
  const name = node.expression.text;
26813
27336
  if (setters.has(name))
26814
27337
  calls.push({ pos: node.getStart(sf), kind: "write" });
@@ -26817,7 +27340,7 @@ function assessBatchSafety(args) {
26817
27340
  else if (!signalGetters.has(name) && !memoNames.has(name))
26818
27341
  calls.push({ pos: node.getStart(sf), kind: "risky" });
26819
27342
  }
26820
- ts23.forEachChild(node, visit3);
27343
+ ts24.forEachChild(node, visit3);
26821
27344
  };
26822
27345
  visit3(sf);
26823
27346
  calls.sort((a, b) => a.pos - b.pos);
@@ -27559,6 +28082,7 @@ export {
27559
28082
  diffStaticBudget,
27560
28083
  diffProfiles,
27561
28084
  describeFallback,
28085
+ derivesScopeFromSlot,
27562
28086
  decideClientOnlyElision,
27563
28087
  dangerousInnerHtmlMetacharViolation,
27564
28088
  dangerousInnerHtmlDiagnostic,