@barefootjs/vite 0.33.2 → 0.33.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@ import { mkdir as mkdir2, readFile as readFile2, rm, writeFile as writeFile2 } f
3
3
  import { relative as relative2, resolve as resolve7, sep as sep3 } from "node:path";
4
4
 
5
5
  // ../jsx/src/compiler.ts
6
- import ts24 from "typescript";
6
+ import ts25 from "typescript";
7
7
 
8
8
  // ../jsx/src/analyzer.ts
9
9
  import ts9 from "typescript";
@@ -1885,6 +1885,9 @@ function loopEndMarker(markerId) {
1885
1885
  }
1886
1886
  var BF_KEY = "data-key";
1887
1887
  var BF_KEY_PREFIX = "data-key-";
1888
+ function keyAttrName(loopDepth) {
1889
+ return loopDepth > 0 ? `${BF_KEY_PREFIX}${loopDepth}` : BF_KEY;
1890
+ }
1888
1891
  var BF_PLACEHOLDER = "data-bf-ph";
1889
1892
  var BF_PARENT_SCOPE_PLACEHOLDER = "__BF_PARENT_SCOPE__";
1890
1893
  // ../shared/src/dom-prop.ts
@@ -2058,6 +2061,29 @@ var SVG_XML_CAMEL_ATTRS = new Set([
2058
2061
  "yChannelSelector",
2059
2062
  "zoomAndPan"
2060
2063
  ]);
2064
+ function isEventProp(key) {
2065
+ return key.length > 2 && key[0] === "o" && key[1] === "n" && key[2] >= "A" && key[2] <= "Z";
2066
+ }
2067
+ function classifyDOMProp(key) {
2068
+ if (key === "children")
2069
+ return { kind: "skip", attrName: key };
2070
+ if (key === "ref")
2071
+ return { kind: "ref", attrName: key };
2072
+ if (key === "dangerouslySetInnerHTML")
2073
+ return { kind: "innerHTML", attrName: key };
2074
+ if (isEventProp(key))
2075
+ return { kind: "event", attrName: key };
2076
+ const attrName = toHTMLAttrNameRuntime(key);
2077
+ if (attrName === "style")
2078
+ return { kind: "style", attrName };
2079
+ if (attrName === "value")
2080
+ return { kind: "property", attrName };
2081
+ if (attrName === "checked")
2082
+ return { kind: "property", attrName };
2083
+ if (BOOLEAN_ATTRS.has(attrName.toLowerCase()))
2084
+ return { kind: "boolean", attrName };
2085
+ return { kind: "attr", attrName };
2086
+ }
2061
2087
  function toHTMLAttrName(key) {
2062
2088
  if (key === "className")
2063
2089
  return "class";
@@ -2071,6 +2097,24 @@ function toHTMLAttrName(key) {
2071
2097
  return svgKebab;
2072
2098
  return key;
2073
2099
  }
2100
+ function toHTMLAttrNameRuntime(key) {
2101
+ if (key === "className")
2102
+ return "class";
2103
+ if (key === "htmlFor")
2104
+ return "for";
2105
+ const htmlAlias = HTML_CAMEL_ALIASES[key];
2106
+ if (htmlAlias !== undefined)
2107
+ return htmlAlias;
2108
+ const svgKebab = SVG_CAMEL_TO_KEBAB[key];
2109
+ if (svgKebab !== undefined)
2110
+ return svgKebab;
2111
+ if (SVG_XML_CAMEL_ATTRS.has(key))
2112
+ return key;
2113
+ if (key.startsWith("data") || key.startsWith("aria")) {
2114
+ return key.replace(/([A-Z])/g, "-$1").toLowerCase();
2115
+ }
2116
+ return key;
2117
+ }
2074
2118
  function isBooleanAttr(name) {
2075
2119
  return BOOLEAN_ATTRS.has(name.toLowerCase());
2076
2120
  }
@@ -2146,8 +2190,12 @@ function escapeHtml(text) {
2146
2190
  }
2147
2191
  // ../jsx/src/ir-to-client-js/utils.ts
2148
2192
  var PROPS_PARAM = "_p";
2149
- function keyAttrName(loopDepth) {
2150
- return loopDepth > 0 ? `${BF_KEY_PREFIX}${loopDepth}` : BF_KEY;
2193
+ var keyAttrName2 = keyAttrName;
2194
+ function mapArrayKeyArgs(bfIdArg, keyed, loopDepth) {
2195
+ if (!keyed || loopDepth <= 0)
2196
+ return bfIdArg;
2197
+ const bfIdSlot = bfIdArg || ", undefined";
2198
+ return `${bfIdSlot}, ${JSON.stringify(keyAttrName2(loopDepth))}`;
2151
2199
  }
2152
2200
  function varSlotId(slotId) {
2153
2201
  return slotId.startsWith("^") ? slotId.slice(1) : slotId;
@@ -3130,6 +3178,14 @@ function escapeAttrValueExpr(valExpr) {
3130
3178
  function escapeTextSlotExpr(innerExpr, isMarkup = false) {
3131
3179
  return `${isMarkup ? "escapeTextOrMarkup" : "escapeText"}(${innerExpr})`;
3132
3180
  }
3181
+ function isChildrenPassthroughExpr(expr) {
3182
+ return /^([A-Za-z_$][\w$]*\.)?children$/.test(expr.trim());
3183
+ }
3184
+ function bareSpliceExpr(node, valueExpr) {
3185
+ const resolved = valueExpr.trim().replace(/^\(+|\)+$/g, "");
3186
+ const isChildren = isChildrenPassthroughExpr(node.expr) || isChildrenPassthroughExpr(resolved);
3187
+ return !node.joinArrayChild && isChildren ? `markupOrEmpty(${valueExpr})` : valueExpr;
3188
+ }
3133
3189
  function dangerouslyHtmlChildren(attrs, toExpr) {
3134
3190
  const attr = attrs.find((a) => a.name === "dangerouslySetInnerHTML");
3135
3191
  if (!attr || attr.value.kind !== "expression")
@@ -3177,6 +3233,9 @@ function renderTemplateAttrPart(attr, attrName, wrap, restSpreadNames) {
3177
3233
  return "";
3178
3234
  }
3179
3235
  }
3236
+ function resolvedKeyAttrName(node, loopDepth) {
3237
+ return node.keyAttr ? keyAttrName2(loopDepth) : null;
3238
+ }
3180
3239
  function isMergeableAttr(a, ctx) {
3181
3240
  if (ctx.honorClientOnly && a.clientOnly)
3182
3241
  return false;
@@ -3337,7 +3396,7 @@ function irToHtmlTemplate(node, restSpreadNames, loopDepth = 0, loopParams, bran
3337
3396
  case "element": {
3338
3397
  const mergeCtx = {
3339
3398
  isFilteredSpread: (v) => !!restSpreadNames?.has(v.expr),
3340
- honorClientOnly: false
3399
+ honorClientOnly: true
3341
3400
  };
3342
3401
  const useMerge = shouldUseSpreadAttrsMerge(node.attrs, mergeCtx);
3343
3402
  const firstMergeableIdx = useMerge ? node.attrs.findIndex((a) => isMergeableAttr(a, mergeCtx)) : -1;
@@ -3348,11 +3407,16 @@ function irToHtmlTemplate(node, restSpreadNames, loopDepth = 0, loopParams, bran
3348
3407
  templateExprFor: (v) => wrapExpr(attrValueToString(v) ?? "")
3349
3408
  }) : null;
3350
3409
  const attrParts = node.attrs.map((a, idx) => {
3410
+ if (a.clientOnly)
3411
+ return "";
3351
3412
  if (useMerge && isMergeableAttr(a, mergeCtx)) {
3352
3413
  return idx === firstMergeableIdx ? mergeCall : "";
3353
3414
  }
3354
- const attrName = a.name === "..." ? "..." : a.name === "key" ? keyAttrName(loopDepth) : toHTMLAttrName(a.name);
3355
- return renderTemplateAttrPart(a, attrName, wrapExpr, restSpreadNames);
3415
+ if (a.name === "key") {
3416
+ const attrName = resolvedKeyAttrName(node, loopDepth);
3417
+ return attrName ? renderTemplateAttrPart(a, attrName, wrapExpr, restSpreadNames) : "";
3418
+ }
3419
+ return renderTemplateAttrPart(a, toHTMLAttrName(a.name), wrapExpr, restSpreadNames);
3356
3420
  }).filter(Boolean);
3357
3421
  const hoistedScopeAttr = maybeHoistedScopeAttr(inHoistedChildren, node);
3358
3422
  if (hoistedScopeAttr)
@@ -3373,17 +3437,18 @@ function irToHtmlTemplate(node, restSpreadNames, loopDepth = 0, loopParams, bran
3373
3437
  case "expression": {
3374
3438
  if (node.expr === "null" || node.expr === "undefined")
3375
3439
  return "";
3440
+ const escapeForClient = (e) => node.escapeInClientTemplate ? `escapeText(${e})` : e;
3376
3441
  if (node.markerless) {
3377
- const bare = wrapInterpolation(wrapExpr(node.expr));
3442
+ const bare = escapeForClient(wrapInterpolation(wrapExpr(node.expr)));
3378
3443
  return `\${${bare}}`;
3379
3444
  }
3380
- const inner = wrapInterpolation(wrapExpr(node.expr));
3445
+ const inner = escapeForClient(wrapInterpolation(wrapExpr(node.expr)));
3381
3446
  const valueExpr = node.joinArrayChild ? `Array.isArray(${inner}) ? ${inner}.join('') : (${inner} ?? '')` : inner;
3382
3447
  if (node.slotId) {
3383
3448
  const slotted = branchSlotsVar || node.joinArrayChild ? valueExpr : escapeTextSlotExpr(valueExpr);
3384
3449
  return `<!--bf:${node.slotId}-->\${${slotted}}<!--/-->`;
3385
3450
  }
3386
- return `\${${valueExpr}}`;
3451
+ return `\${${bareSpliceExpr(node, valueExpr)}}`;
3387
3452
  }
3388
3453
  case "conditional": {
3389
3454
  const trueBranch = recurse(node.whenTrue);
@@ -3476,7 +3541,9 @@ function buildLoopSkeletonTemplate(node, safe) {
3476
3541
  if (a.name === "dangerouslySetInnerHTML")
3477
3542
  return null;
3478
3543
  if (a.name === "key") {
3479
- attrParts.push(`${keyAttrName(0)}=""`);
3544
+ if (resolvedKeyAttrName(node, 0)) {
3545
+ attrParts.push(`${keyAttrName2(0)}=""`);
3546
+ }
3480
3547
  continue;
3481
3548
  }
3482
3549
  const v = a.value;
@@ -3682,7 +3749,13 @@ function irToPlaceholderTemplate(node, restSpreadNames, loopDepth = 0, loopParam
3682
3749
  switch (node.type) {
3683
3750
  case "element": {
3684
3751
  const attrParts = node.attrs.map((a) => {
3685
- const attrName = a.name === "..." ? "..." : a.name === "key" ? keyAttrName(loopDepth) : toHTMLAttrName(a.name);
3752
+ if (a.clientOnly)
3753
+ return "";
3754
+ if (a.name === "key") {
3755
+ const attrName2 = resolvedKeyAttrName(node, loopDepth);
3756
+ return attrName2 ? renderTemplateAttrPart(a, attrName2, wrapExpr, restSpreadNames) : "";
3757
+ }
3758
+ const attrName = a.name === "..." ? "..." : toHTMLAttrName(a.name);
3686
3759
  return renderTemplateAttrPart(a, attrName, wrapExpr, restSpreadNames);
3687
3760
  }).filter(Boolean);
3688
3761
  if (node.slotId) {
@@ -3705,7 +3778,8 @@ function irToPlaceholderTemplate(node, restSpreadNames, loopDepth = 0, loopParam
3705
3778
  if (node.slotId) {
3706
3779
  return `<!--bf:${node.slotId}-->\${${node.joinArrayChild ? value : escapeTextSlotExpr(wrapped)}}<!--/-->`;
3707
3780
  }
3708
- return `\${${value}}`;
3781
+ const spliced = bareSpliceExpr(node, value);
3782
+ return `\${${node.escapeInClientTemplate ? `escapeText(${spliced})` : spliced}}`;
3709
3783
  }
3710
3784
  case "conditional": {
3711
3785
  const trueBranch = recurse(node.whenTrue);
@@ -3887,7 +3961,7 @@ function irToComponentTemplateWithOpts(node, opts) {
3887
3961
  if (a.name === "key") {
3888
3962
  if (loopDepth === 0)
3889
3963
  return "";
3890
- const keyName = keyAttrName(loopDepth);
3964
+ const keyName = keyAttrName2(loopDepth);
3891
3965
  switch (v.kind) {
3892
3966
  case "expression":
3893
3967
  return templateAttrExpr(keyName, transformExpr(v.expr, v.templateExpr), v.presenceOrUndefined);
@@ -3947,7 +4021,7 @@ function irToComponentTemplateWithOpts(node, opts) {
3947
4021
  const isMarkup = opts.markupSlotIds?.has(node.slotId) ?? false;
3948
4022
  return `<!--bf:${node.slotId}-->\${${node.joinArrayChild ? value : escapeTextSlotExpr(wrapped, isMarkup)}}<!--/-->`;
3949
4023
  }
3950
- return `\${${value}}`;
4024
+ return `\${${bareSpliceExpr(node, value)}}`;
3951
4025
  }
3952
4026
  case "conditional": {
3953
4027
  if (node.clientOnly && node.slotId) {
@@ -4230,7 +4304,27 @@ function generateCsrTemplateWithOpts(node, opts) {
4230
4304
  return "";
4231
4305
  return `\${spreadAttrs(${transformExpr(v.expr, v.templateExpr)})}`;
4232
4306
  }
4233
- const attrName = a.name === "key" ? keyAttrName(loopDepth) : toHTMLAttrName(a.name);
4307
+ if (a.name === "key") {
4308
+ const keyName = resolvedKeyAttrName(node, loopDepth);
4309
+ if (!keyName)
4310
+ return "";
4311
+ switch (v.kind) {
4312
+ case "boolean-attr":
4313
+ return keyName;
4314
+ case "literal":
4315
+ return `${keyName}="${escapeHtml(v.value)}"`;
4316
+ case "expression":
4317
+ return templateAttrExpr(keyName, transformExpr(v.expr, v.templateExpr), v.presenceOrUndefined);
4318
+ case "template": {
4319
+ const valueStr = attrValueToString(v, { useTemplate: true });
4320
+ return valueStr ? templateAttrExpr(keyName, transformExpr(valueStr)) : "";
4321
+ }
4322
+ case "boolean-shorthand":
4323
+ case "jsx-children":
4324
+ return "";
4325
+ }
4326
+ }
4327
+ const attrName = toHTMLAttrName(a.name);
4234
4328
  switch (v.kind) {
4235
4329
  case "boolean-attr":
4236
4330
  return attrName;
@@ -4278,7 +4372,7 @@ function generateCsrTemplateWithOpts(node, opts) {
4278
4372
  const isMarkup = opts.markupSlotIds?.has(node.slotId) ?? false;
4279
4373
  return `<!--bf:${node.slotId}-->\${${node.joinArrayChild ? value : escapeTextSlotExpr(expr, isMarkup)}}<!--/-->`;
4280
4374
  }
4281
- return `\${${value}}`;
4375
+ return `\${${bareSpliceExpr(node, value)}}`;
4282
4376
  }
4283
4377
  case "conditional": {
4284
4378
  if (node.clientOnly && node.slotId) {
@@ -4586,6 +4680,19 @@ function buildPropAliasMap(params) {
4586
4680
  }
4587
4681
  return map;
4588
4682
  }
4683
+ function resolveRestSpreadOriginCore(bindings, constantValues, name) {
4684
+ const visited = new Set;
4685
+ let current = name.trim();
4686
+ while (current !== undefined && !visited.has(current)) {
4687
+ if (bindings.restPropsName && current === bindings.restPropsName)
4688
+ return "rest";
4689
+ if (bindings.propsObjectName && current === bindings.propsObjectName)
4690
+ return "props";
4691
+ visited.add(current);
4692
+ current = constantValues.get(current)?.trim();
4693
+ }
4694
+ return null;
4695
+ }
4589
4696
 
4590
4697
  // ../jsx/src/instrumentation.ts
4591
4698
  var _enabled = false;
@@ -7744,6 +7851,16 @@ function importsBrowserOnlyClientApi(ctx) {
7744
7851
  }
7745
7852
  function listComponentFunctions(source, filePath) {
7746
7853
  const sourceFile = ts9.createSourceFile(filePath, source, ts9.ScriptTarget.Latest, true, ts9.ScriptKind.TSX);
7854
+ return listComponentFunctionsFromSourceFile(sourceFile);
7855
+ }
7856
+ function scanComponentFile(source, filePath) {
7857
+ const sourceFile = ts9.createSourceFile(filePath, source, ts9.ScriptTarget.Latest, true, ts9.ScriptKind.TSX);
7858
+ return {
7859
+ exports: listComponentFunctionsFromSourceFile(sourceFile),
7860
+ referencedComponents: [...collectJsxComponentTags(sourceFile)]
7861
+ };
7862
+ }
7863
+ function listComponentFunctionsFromSourceFile(sourceFile) {
7747
7864
  const componentNames = [];
7748
7865
  const hasUseClient = sourceFile.statements.some((stmt) => ts9.isExpressionStatement(stmt) && ts9.isStringLiteral(stmt.expression) && (stmt.expression.text === "use client" || stmt.expression.text === "'use client'"));
7749
7866
  const namedExports = collectNamedExports(sourceFile);
@@ -10110,10 +10227,44 @@ function attachParsedExpressions(node, analyzer, bound = EMPTY_BOUND) {
10110
10227
  break;
10111
10228
  }
10112
10229
  }
10230
+ function resolveRootKeyAttr(node) {
10231
+ if (!node)
10232
+ return;
10233
+ switch (node.type) {
10234
+ case "element":
10235
+ if (node.needsScope && !node.keyAttr)
10236
+ node.keyAttr = { name: BF_KEY };
10237
+ for (const c of node.children)
10238
+ resolveRootKeyAttr(c);
10239
+ return;
10240
+ case "fragment":
10241
+ case "component":
10242
+ case "provider":
10243
+ case "loop":
10244
+ for (const c of node.children)
10245
+ resolveRootKeyAttr(c);
10246
+ return;
10247
+ case "async":
10248
+ resolveRootKeyAttr(node.fallback);
10249
+ for (const c of node.children)
10250
+ resolveRootKeyAttr(c);
10251
+ return;
10252
+ case "conditional":
10253
+ resolveRootKeyAttr(node.whenTrue);
10254
+ resolveRootKeyAttr(node.whenFalse);
10255
+ return;
10256
+ case "if-statement":
10257
+ resolveRootKeyAttr(node.consequent);
10258
+ resolveRootKeyAttr(node.alternate);
10259
+ return;
10260
+ }
10261
+ }
10113
10262
  function jsxToIR(analyzer) {
10114
10263
  const root = buildIRRoot(analyzer);
10115
- if (root)
10264
+ if (root) {
10116
10265
  attachParsedExpressions(root, analyzer);
10266
+ resolveRootKeyAttr(root);
10267
+ }
10117
10268
  return root;
10118
10269
  }
10119
10270
  function buildIRRoot(analyzer) {
@@ -10302,6 +10453,7 @@ function lowerFormControlValueSsr(tagName, attrs, children) {
10302
10453
  type: "expression",
10303
10454
  expr,
10304
10455
  templateExpr: `escapeText(${templateExpr ?? expr})`,
10456
+ escapeInClientTemplate: true,
10305
10457
  typeInfo: null,
10306
10458
  reactive: false,
10307
10459
  slotId: null,
@@ -10339,7 +10491,7 @@ function transformHtmlElement(node, ctx, tagName) {
10339
10491
  ctx.isRoot = false;
10340
10492
  const children = transformChildren(node.children, ctx);
10341
10493
  lowerFormControlValueSsr(tagName, attrs, children);
10342
- const needsSlot = events.length > 0 || hasDynamicContent(children) || hasReactiveAttributes(attrs, ctx) || ref !== null;
10494
+ const needsSlot = events.length > 0 || hasDynamicContent(children) || hasReactiveAttributes(attrs, ctx) || ref !== null || forwardsCallerRestProps(attrs, ctx);
10343
10495
  const slotId = needsSlot ? generateSlotId(ctx) : null;
10344
10496
  if (slotId) {
10345
10497
  propagateSlotIdToLoops(children, slotId);
@@ -10372,7 +10524,7 @@ function transformSelfClosingElement(node, ctx) {
10372
10524
  const { attrs, events, ref } = processAttributes(node.attributes, ctx);
10373
10525
  const selfClosingChildren = [];
10374
10526
  lowerFormControlValueSsr(tagName, attrs, selfClosingChildren);
10375
- const needsSlot = events.length > 0 || hasReactiveAttributes(attrs, ctx) || ref !== null;
10527
+ const needsSlot = events.length > 0 || hasReactiveAttributes(attrs, ctx) || ref !== null || forwardsCallerRestProps(attrs, ctx);
10376
10528
  const slotId = needsSlot ? generateSlotId(ctx) : null;
10377
10529
  const needsScope = ctx.isRoot;
10378
10530
  ctx.isRoot = false;
@@ -10611,7 +10763,9 @@ function markDataKeyCarrier(children) {
10611
10763
  }
10612
10764
  function markCarrierIn(node) {
10613
10765
  if (node.type === "element") {
10614
- return { ...node, carriesDataKey: true };
10766
+ if (node.keyAttr)
10767
+ return null;
10768
+ return { ...node, keyAttr: { name: BF_KEY } };
10615
10769
  }
10616
10770
  if (node.type === "conditional") {
10617
10771
  const cond = node;
@@ -10686,7 +10840,7 @@ function transformExpressionInner(expr, ctx, node, isClientOnly) {
10686
10840
  if (isRenderNothingLiteral(expr, ctx)) {
10687
10841
  return null;
10688
10842
  }
10689
- checkBareSignalOrMemoIdentifier(expr, ctx);
10843
+ checkBareSignalOrMemoIdentifier(expr, ctx, { descendNested: true });
10690
10844
  if (ts13.isIdentifier(expr)) {
10691
10845
  const jsxNode = ctx.analyzer.jsxConstants.get(expr.text);
10692
10846
  if (jsxNode) {
@@ -11565,6 +11719,10 @@ function extractLoopKey(node) {
11565
11719
  return null;
11566
11720
  return normalizeKeyExpr(a) === normalizeKeyExpr(b) ? a : null;
11567
11721
  }
11722
+ if (node.type === "fragment") {
11723
+ const first = node.children.find((c) => !(c.type === "text" && typeof c.value === "string" && !c.value.trim()));
11724
+ return first ? extractLoopKey(first) : null;
11725
+ }
11568
11726
  return null;
11569
11727
  }
11570
11728
  function keyAttrValueToExpr(v) {
@@ -11755,7 +11913,7 @@ function leafIsWirelessElement(el) {
11755
11913
  }
11756
11914
  if (ts13.isJsxAttribute(attr)) {
11757
11915
  const name = attr.name.getText();
11758
- if (/^on[A-Z]/.test(name)) {
11916
+ if (isEventHandlerAttrName(name)) {
11759
11917
  ok = false;
11760
11918
  return;
11761
11919
  }
@@ -11803,6 +11961,22 @@ function tagLoopItemRootComponents(nodes) {
11803
11961
  }
11804
11962
  }
11805
11963
  }
11964
+ function applyLoopKeyAttr(node, name, value) {
11965
+ if (node.type === "element") {
11966
+ node.keyAttr = { name, value };
11967
+ return;
11968
+ }
11969
+ if (node.type === "conditional") {
11970
+ applyLoopKeyAttr(node.whenTrue, name, value);
11971
+ applyLoopKeyAttr(node.whenFalse, name, value);
11972
+ return;
11973
+ }
11974
+ if (node.type === "fragment") {
11975
+ const first = node.children.find((c) => !(c.type === "text" && typeof c.value === "string" && !c.value.trim()));
11976
+ if (first)
11977
+ applyLoopKeyAttr(first, name, value);
11978
+ }
11979
+ }
11806
11980
  function loopBodyItemConditional(children) {
11807
11981
  const real = children.filter((c) => !(c.type === "text" && typeof c.value === "string" && !c.value.trim()));
11808
11982
  if (real.length !== 1)
@@ -12033,7 +12207,7 @@ function transformMapCall(node, ctx, isClientOnly = false, method = "map") {
12033
12207
  children = [foldMultiReturnBranches(multiReturn, ctx, loc, ctx.getJS)];
12034
12208
  const pre = multiReturn.preamble ?? [];
12035
12209
  if (pre.length > 0) {
12036
- preamble = preambleFromValueStatements(pre, ctx);
12210
+ preamble = preambleFromValueStatements(pre, ctx, body.statements);
12037
12211
  if (!preamble.declarations && !isClientOnly && !(ctx.analyzer.acceptsCallbackBody?.("map") ?? false)) {
12038
12212
  ctx.analyzer.errors.push(createError(ErrorCodes.UNSUPPORTED_JSX_PATTERN, loc, {
12039
12213
  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.",
@@ -12120,7 +12294,7 @@ function transformMapCall(node, ctx, isClientOnly = false, method = "map") {
12120
12294
  valueStmts.push(stmt);
12121
12295
  }
12122
12296
  if (valueStmts.length > 0) {
12123
- preamble = preambleFromValueStatements(valueStmts, ctx);
12297
+ preamble = preambleFromValueStatements(valueStmts, ctx, body.statements);
12124
12298
  if (!preamble.declarations && !isClientOnly && !(ctx.analyzer.acceptsCallbackBody?.("map") ?? false)) {
12125
12299
  ctx.analyzer.errors.push(createError(ErrorCodes.UNSUPPORTED_JSX_PATTERN, getSourceLocation(body, ctx.sourceFile, ctx.filePath), {
12126
12300
  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.",
@@ -12185,6 +12359,14 @@ function transformMapCall(node, ctx, isClientOnly = false, method = "map") {
12185
12359
  const itemConditional = children.length > 0 ? loopBodyItemConditional(children) : null;
12186
12360
  const bodyIsItemConditional = itemConditional !== null;
12187
12361
  const key = bodyIsItemConditional ? extractItemConditionalKey(itemConditional) : children.length > 0 ? extractLoopKey(children[0]) : null;
12362
+ if (key !== null) {
12363
+ const resolvedKeyAttrName2 = keyAttrName(depth);
12364
+ if (bodyIsItemConditional) {
12365
+ applyLoopKeyAttr(itemConditional, resolvedKeyAttrName2, key);
12366
+ } else if (children.length > 0) {
12367
+ applyLoopKeyAttr(children[0], resolvedKeyAttrName2, key);
12368
+ }
12369
+ }
12188
12370
  const declaredNameSet = preamble && preamble.declaredNames.length > 0 ? new Set(preamble.declaredNames) : undefined;
12189
12371
  if (key && declaredNameSet) {
12190
12372
  const keyRefs = extractFreeIdentifiersFromText(key);
@@ -12575,7 +12757,7 @@ function computePreambleReactiveNames(statements, ctx) {
12575
12757
  }
12576
12758
  return reactiveNames;
12577
12759
  }
12578
- function preambleFromValueStatements(statements, ctx) {
12760
+ function preambleFromValueStatements(statements, ctx, bodyStatements) {
12579
12761
  const segments = [];
12580
12762
  const typedParts = [];
12581
12763
  const declared = new Set;
@@ -12595,11 +12777,11 @@ function preambleFromValueStatements(statements, ctx) {
12595
12777
  ssrText: tsxSourceText(typedParts.join(" ")),
12596
12778
  declaredNames: [...declared],
12597
12779
  builderNames: [],
12598
- declarations: neutralPreambleDeclarations(statements, ctx) ?? undefined,
12780
+ declarations: neutralPreambleDeclarations(statements, ctx, bodyStatements) ?? undefined,
12599
12781
  reactiveNames: reactiveNames.size > 0 ? [...reactiveNames] : undefined
12600
12782
  };
12601
12783
  }
12602
- function neutralPreambleDeclarations(statements, ctx) {
12784
+ function neutralPreambleDeclarations(statements, ctx, bodyStatements) {
12603
12785
  const out = [];
12604
12786
  for (const stmt of statements) {
12605
12787
  if (!ts13.isVariableStatement(stmt))
@@ -12609,6 +12791,11 @@ function neutralPreambleDeclarations(statements, ctx) {
12609
12791
  return null;
12610
12792
  if (!decl.initializer)
12611
12793
  return null;
12794
+ if (isFunctionLiteral(decl.initializer)) {
12795
+ if (everyReadIsEventHandlerPropValue(decl.name.text, bodyStatements))
12796
+ continue;
12797
+ return null;
12798
+ }
12612
12799
  const valueParsed = tsNodeToParsedExpr(decl.initializer);
12613
12800
  if (!isSupported(valueParsed).supported)
12614
12801
  return null;
@@ -12619,7 +12806,30 @@ function neutralPreambleDeclarations(statements, ctx) {
12619
12806
  });
12620
12807
  }
12621
12808
  }
12622
- return out.length > 0 ? out : null;
12809
+ return out;
12810
+ }
12811
+ function isFunctionLiteral(node) {
12812
+ return ts13.isArrowFunction(node) || ts13.isFunctionExpression(node);
12813
+ }
12814
+ function everyReadIsEventHandlerPropValue(name, bodyStatements) {
12815
+ const findDisallowedRead = (node) => {
12816
+ if (ts13.isIdentifier(node) && node.text === name) {
12817
+ const isBindingName = ts13.isVariableDeclaration(node.parent) && node.parent.name === node;
12818
+ const isPropertyName = ts13.isPropertyAccessExpression(node.parent) && node.parent.name === node;
12819
+ if (!isBindingName && !isPropertyName) {
12820
+ const jsxExpr = node.parent;
12821
+ const attr = jsxExpr.parent;
12822
+ const isEventHandlerAttrValue = ts13.isJsxExpression(jsxExpr) && ts13.isJsxAttribute(attr) && attr.initializer === jsxExpr && ts13.isIdentifier(attr.name) && isEventHandlerAttrName(attr.name.text);
12823
+ if (!isEventHandlerAttrValue)
12824
+ return true;
12825
+ }
12826
+ }
12827
+ return ts13.forEachChild(node, findDisallowedRead);
12828
+ };
12829
+ return !bodyStatements.some(findDisallowedRead);
12830
+ }
12831
+ function isEventHandlerAttrName(name) {
12832
+ return /^on[A-Z]/.test(name);
12623
12833
  }
12624
12834
  function trimPreambleSegments(segments) {
12625
12835
  const last = segments[segments.length - 1];
@@ -12816,7 +13026,7 @@ function processAttributes(attributes, ctx) {
12816
13026
  }
12817
13027
  continue;
12818
13028
  }
12819
- if (/^on[A-Z]/.test(rawName)) {
13029
+ if (isEventHandlerAttrName(rawName)) {
12820
13030
  if (attr.initializer && ts13.isJsxExpression(attr.initializer) && attr.initializer.expression) {
12821
13031
  const eventName = rawName.slice(2).toLowerCase();
12822
13032
  reportJsxBranchLocalInCallback(attr.initializer.expression, ctx);
@@ -12875,7 +13085,7 @@ function getAttributeValue(attr, ctx) {
12875
13085
  ctx.analyzer.errors.push(createError(ErrorCodes.STAGE_AWAIT_IN_TEMPLATE, getSourceLocation(expr, ctx.sourceFile, ctx.filePath)));
12876
13086
  return AttrValueOf.expression("undefined");
12877
13087
  }
12878
- checkBareSignalOrMemoIdentifier(expr, ctx);
13088
+ checkBareSignalOrMemoIdentifier(expr, ctx, { descendNested: isRenderedElementAttribute(attr, ctx) });
12879
13089
  if (attr.name.getText(ctx.sourceFile) === "style" && ts13.isObjectLiteralExpression(expr)) {
12880
13090
  const cssString = tryStaticStyleObjectToCss(expr);
12881
13091
  if (cssString !== null) {
@@ -13383,34 +13593,142 @@ function processComponentProps(attributes, ctx) {
13383
13593
  }
13384
13594
  return props;
13385
13595
  }
13386
- function checkBareSignalOrMemoIdentifier(expr, ctx) {
13387
- if (!ts13.isIdentifier(expr))
13596
+ function isRenderedElementAttribute(attr, ctx) {
13597
+ const tagName = attr.parent.parent.tagName.getText(ctx.sourceFile);
13598
+ return !/^[A-Z]/.test(tagName);
13599
+ }
13600
+ function checkBareSignalOrMemoIdentifier(expr, ctx, options) {
13601
+ const reactiveNames = new Map;
13602
+ for (const signal of ctx.analyzer.signals)
13603
+ reactiveNames.set(signal.getter, "signal");
13604
+ for (const memo of ctx.analyzer.memos)
13605
+ reactiveNames.set(memo.name, "memo");
13606
+ if (reactiveNames.size === 0)
13388
13607
  return;
13389
- const name = expr.text;
13390
- for (const signal of ctx.analyzer.signals) {
13391
- if (signal.getter === name) {
13392
- ctx.analyzer.errors.push(createError(ErrorCodes.SIGNAL_GETTER_NOT_CALLED, getSourceLocation(expr, ctx.sourceFile, ctx.filePath), {
13393
- message: `Signal getter '${name}' passed without calling it`,
13394
- suggestion: {
13395
- message: `Signal getters must be called to read the value. Use \`${name}()\` instead of \`${name}\`.`,
13396
- replacement: `${name}()`
13397
- }
13398
- }));
13608
+ const report = (id, name, kind) => {
13609
+ const label = kind === "signal" ? "Signal" : "Memo";
13610
+ ctx.analyzer.errors.push(createError(ErrorCodes.SIGNAL_GETTER_NOT_CALLED, getSourceLocation(id, ctx.sourceFile, ctx.filePath), {
13611
+ message: `${label} getter '${name}' passed without calling it`,
13612
+ suggestion: {
13613
+ message: `${label} getters must be called to read the value. Use \`${name}()\` instead of \`${name}\`.`,
13614
+ replacement: `${name}()`
13615
+ }
13616
+ }));
13617
+ };
13618
+ if (ts13.isIdentifier(expr)) {
13619
+ const kind = reactiveNames.get(expr.text);
13620
+ if (kind && !ctx.scope.isBound(expr.text))
13621
+ report(expr, expr.text, kind);
13622
+ return;
13623
+ }
13624
+ if (!options?.descendNested)
13625
+ return;
13626
+ const boundStack = [];
13627
+ const isBound = (name) => {
13628
+ for (let i = boundStack.length - 1;i >= 0; i--) {
13629
+ if (boundStack[i].has(name))
13630
+ return true;
13631
+ }
13632
+ return ctx.scope.isBound(name);
13633
+ };
13634
+ const visitBindingDefaults = (name, bound) => {
13635
+ if (ts13.isIdentifier(name)) {
13636
+ bound.add(name.text);
13399
13637
  return;
13400
13638
  }
13401
- }
13402
- for (const memo of ctx.analyzer.memos) {
13403
- if (memo.name === name) {
13404
- ctx.analyzer.errors.push(createError(ErrorCodes.SIGNAL_GETTER_NOT_CALLED, getSourceLocation(expr, ctx.sourceFile, ctx.filePath), {
13405
- message: `Memo getter '${name}' passed without calling it`,
13406
- suggestion: {
13407
- message: `Memo getters must be called to read the value. Use \`${name}()\` instead of \`${name}\`.`,
13408
- replacement: `${name}()`
13409
- }
13410
- }));
13639
+ for (const el of name.elements) {
13640
+ if (ts13.isOmittedExpression(el))
13641
+ continue;
13642
+ if (el.initializer)
13643
+ visit2(el.initializer);
13644
+ visitBindingDefaults(el.name, bound);
13645
+ }
13646
+ };
13647
+ const collectBindingNames3 = (name, out) => {
13648
+ if (ts13.isIdentifier(name))
13649
+ out.add(name.text);
13650
+ else if (ts13.isObjectBindingPattern(name)) {
13651
+ for (const el of name.elements)
13652
+ collectBindingNames3(el.name, out);
13653
+ } else if (ts13.isArrayBindingPattern(name)) {
13654
+ for (const el of name.elements) {
13655
+ if (!ts13.isOmittedExpression(el))
13656
+ collectBindingNames3(el.name, out);
13657
+ }
13658
+ }
13659
+ };
13660
+ const collectBlockDeclarations = (block, out) => {
13661
+ for (const stmt of block.statements) {
13662
+ if (ts13.isVariableStatement(stmt)) {
13663
+ for (const decl of stmt.declarationList.declarations)
13664
+ collectBindingNames3(decl.name, out);
13665
+ } else if (ts13.isFunctionDeclaration(stmt) && stmt.name) {
13666
+ out.add(stmt.name.text);
13667
+ }
13668
+ }
13669
+ };
13670
+ function visit2(node) {
13671
+ if (ts13.isJsxElement(node) || ts13.isJsxSelfClosingElement(node) || ts13.isJsxFragment(node)) {
13411
13672
  return;
13412
13673
  }
13674
+ if (ts13.isTypeNode(node))
13675
+ return;
13676
+ if (ts13.isCallExpression(node) && node.arguments.length === 0 && ts13.isIdentifier(node.expression)) {
13677
+ return;
13678
+ }
13679
+ if (ts13.isPropertyAccessExpression(node)) {
13680
+ visit2(node.expression);
13681
+ return;
13682
+ }
13683
+ if (ts13.isPropertyAssignment(node)) {
13684
+ if (ts13.isComputedPropertyName(node.name))
13685
+ visit2(node.name.expression);
13686
+ visit2(node.initializer);
13687
+ return;
13688
+ }
13689
+ if (ts13.isShorthandPropertyAssignment(node)) {
13690
+ if (ts13.isIdentifier(node.name) && !isBound(node.name.text)) {
13691
+ const kind = reactiveNames.get(node.name.text);
13692
+ if (kind)
13693
+ report(node.name, node.name.text, kind);
13694
+ }
13695
+ return;
13696
+ }
13697
+ if (ts13.isArrowFunction(node) || ts13.isFunctionExpression(node)) {
13698
+ const bound = new Set;
13699
+ boundStack.push(bound);
13700
+ for (const p of node.parameters) {
13701
+ if (p.initializer)
13702
+ visit2(p.initializer);
13703
+ visitBindingDefaults(p.name, bound);
13704
+ }
13705
+ if (node.body && ts13.isBlock(node.body))
13706
+ collectBlockDeclarations(node.body, bound);
13707
+ if (node.body)
13708
+ visit2(node.body);
13709
+ boundStack.pop();
13710
+ return;
13711
+ }
13712
+ if (ts13.isVariableDeclaration(node)) {
13713
+ if (node.initializer)
13714
+ visit2(node.initializer);
13715
+ const declared = new Set;
13716
+ boundStack.push(declared);
13717
+ visitBindingDefaults(node.name, declared);
13718
+ boundStack.pop();
13719
+ return;
13720
+ }
13721
+ if (ts13.isIdentifier(node)) {
13722
+ if (isBound(node.text))
13723
+ return;
13724
+ const kind = reactiveNames.get(node.text);
13725
+ if (kind)
13726
+ report(node, node.text, kind);
13727
+ return;
13728
+ }
13729
+ ts13.forEachChild(node, visit2);
13413
13730
  }
13731
+ visit2(expr);
13414
13732
  }
13415
13733
  function isArrayExprDirectPropRef(arrayExpr, ctx) {
13416
13734
  const propNames = new Set(ctx.patterns.props.map((p) => p.name));
@@ -13509,6 +13827,31 @@ function isPropsReference(expr, ctx, visited) {
13509
13827
  }
13510
13828
  return false;
13511
13829
  }
13830
+ function forwardsCallerRestProps(attrs, ctx) {
13831
+ for (const attr of attrs) {
13832
+ if (attr.value.kind !== "spread")
13833
+ continue;
13834
+ const constants = restSpreadConstantValues(ctx);
13835
+ for (const name of new Set([attr.value.expr, attr.value.templateExpr])) {
13836
+ if (!name)
13837
+ continue;
13838
+ if (resolveRestSpreadOriginCore(ctx.analyzer, constants, name) !== null)
13839
+ return true;
13840
+ }
13841
+ }
13842
+ return false;
13843
+ }
13844
+ function restSpreadConstantValues(ctx) {
13845
+ if (ctx._restSpreadConstantValues)
13846
+ return ctx._restSpreadConstantValues;
13847
+ const byName = new Map;
13848
+ for (const constant of ctx.analyzer.localConstants) {
13849
+ if (!byName.has(constant.name))
13850
+ byName.set(constant.name, constant.value);
13851
+ }
13852
+ ctx._restSpreadConstantValues = byName;
13853
+ return byName;
13854
+ }
13512
13855
  function hasReactiveAttributes(attrs, ctx) {
13513
13856
  for (const attr of attrs) {
13514
13857
  if (attr.name === "key")
@@ -13731,18 +14074,7 @@ function buildIfStatementChain(analyzer, ctx, opts) {
13731
14074
 
13732
14075
  // ../jsx/src/ir-to-client-js/prop-handling.ts
13733
14076
  function resolveRestSpreadOrigin(ctx, name) {
13734
- const byName = localConstantValues(ctx);
13735
- const visited = new Set;
13736
- let current = name.trim();
13737
- while (current !== undefined && !visited.has(current)) {
13738
- if (ctx.restPropsName && current === ctx.restPropsName)
13739
- return "rest";
13740
- if (ctx.propsObjectName && current === ctx.propsObjectName)
13741
- return "props";
13742
- visited.add(current);
13743
- current = byName.get(current)?.trim();
13744
- }
13745
- return null;
14077
+ return resolveRestSpreadOriginCore(ctx, localConstantValues(ctx), name);
13746
14078
  }
13747
14079
  var _localConstantValuesCache = new WeakMap;
13748
14080
  function localConstantValues(ctx) {
@@ -14638,8 +14970,8 @@ function collectReactiveChildProps(node, ctx) {
14638
14970
  continue;
14639
14971
  if (prop.value.kind === "jsx-children")
14640
14972
  continue;
14641
- const isEventHandler = prop.name.startsWith("on") && prop.name.length > 2 && prop.name[2] === prop.name[2].toUpperCase();
14642
- if (isEventHandler)
14973
+ const domKind = classifyDOMProp(prop.name).kind;
14974
+ if (domKind === "ref" || domKind === "event" || domKind === "skip")
14643
14975
  continue;
14644
14976
  if (prop.value.kind !== "expression" && prop.value.kind !== "template")
14645
14977
  continue;
@@ -15349,6 +15681,8 @@ function buildReferencesGraph(ctx, irRoot) {
15349
15681
  }
15350
15682
  for (const ev of el.events)
15351
15683
  addExprEdges(ROOT_SOURCE, ev.handler, "init-body");
15684
+ if (el.ref)
15685
+ addExprEdges(ROOT_SOURCE, el.ref, "init-body");
15352
15686
  descend();
15353
15687
  },
15354
15688
  component: ({ node: c, descend, descendJsxChildren }) => {
@@ -15556,6 +15890,9 @@ function propHasPropertyAccess(u) {
15556
15890
  return u.accessKinds.has("property") || u.accessKinds.has("index");
15557
15891
  }
15558
15892
 
15893
+ // ../jsx/src/ir-to-client-js/imports.ts
15894
+ import ts16 from "typescript";
15895
+
15559
15896
  // ../jsx/src/value-references.ts
15560
15897
  import ts15 from "typescript";
15561
15898
  function isValueReferenceIdentifier(id) {
@@ -15662,6 +15999,7 @@ var RUNTIME_IMPORT_CANDIDATES = [
15662
15999
  "escapeTextOrNode",
15663
16000
  "bfMarkup",
15664
16001
  "escapeTextOrMarkup",
16002
+ "markupOrEmpty",
15665
16003
  "qsa",
15666
16004
  "qsaItem",
15667
16005
  "qsaChildScope",
@@ -15728,6 +16066,79 @@ function makeValueUsageTest(generatedCode) {
15728
16066
  return generatedCode.includes(localName);
15729
16067
  };
15730
16068
  }
16069
+ function renderUsedImportLines(source, usedDefault, usedNamespace, usedNamed) {
16070
+ const lines = [];
16071
+ const defaultAndNamed = [
16072
+ usedDefault,
16073
+ usedNamed.length > 0 ? `{ ${usedNamed.join(", ")} }` : null
16074
+ ].filter((part) => part !== null).join(", ");
16075
+ if (defaultAndNamed)
16076
+ lines.push(`import ${defaultAndNamed} from '${source}'`);
16077
+ if (usedNamespace)
16078
+ lines.push(`import * as ${usedNamespace} from '${source}'`);
16079
+ return lines;
16080
+ }
16081
+ function mergeCompiledClientJsImports(codeBlobs) {
16082
+ const sourceOrder = [];
16083
+ const namedBySource = new Map;
16084
+ const defaultBySource = new Map;
16085
+ const otherImports = [];
16086
+ const seenOther = new Set;
16087
+ const codeSections = [];
16088
+ const ensureSource = (source) => {
16089
+ if (!namedBySource.has(source)) {
16090
+ namedBySource.set(source, new Set);
16091
+ sourceOrder.push(source);
16092
+ }
16093
+ return namedBySource.get(source);
16094
+ };
16095
+ for (const content of codeBlobs) {
16096
+ const sourceFile = ts16.createSourceFile("combine.js", content, ts16.ScriptTarget.Latest, false, ts16.ScriptKind.JS);
16097
+ const importSpans = [];
16098
+ for (const stmt of sourceFile.statements) {
16099
+ if (!ts16.isImportDeclaration(stmt))
16100
+ continue;
16101
+ const start = stmt.getStart(sourceFile);
16102
+ const end = stmt.getEnd();
16103
+ importSpans.push([start, end]);
16104
+ const clause = stmt.importClause;
16105
+ const bindings = clause?.namedBindings;
16106
+ const specifier = ts16.isStringLiteral(stmt.moduleSpecifier) ? stmt.moduleSpecifier.text : "";
16107
+ const isNamespace = !!bindings && ts16.isNamespaceImport(bindings);
16108
+ const isNamed = !!bindings && ts16.isNamedImports(bindings);
16109
+ if (!isNamespace && (clause?.name || isNamed)) {
16110
+ const set = ensureSource(specifier);
16111
+ if (clause?.name && !defaultBySource.has(specifier)) {
16112
+ defaultBySource.set(specifier, clause.name.text);
16113
+ }
16114
+ if (isNamed) {
16115
+ for (const el of bindings.elements) {
16116
+ set.add(el.propertyName ? `${el.propertyName.text} as ${el.name.text}` : el.name.text);
16117
+ }
16118
+ }
16119
+ } else {
16120
+ const stmtText = content.slice(start, end);
16121
+ if (!seenOther.has(stmtText)) {
16122
+ seenOther.add(stmtText);
16123
+ otherImports.push(stmtText);
16124
+ }
16125
+ }
16126
+ }
16127
+ let code = "";
16128
+ let cursor = 0;
16129
+ for (const [start, end] of importSpans) {
16130
+ code += content.slice(cursor, start);
16131
+ cursor = end;
16132
+ }
16133
+ code += content.slice(cursor);
16134
+ code = code.trim();
16135
+ if (code)
16136
+ codeSections.push(code);
16137
+ }
16138
+ const mergedImports = sourceOrder.flatMap((source) => renderUsedImportLines(source, defaultBySource.get(source) ?? null, null, [...namedBySource.get(source)]));
16139
+ return [...mergedImports, ...otherImports, "", ...codeSections].join(`
16140
+ `);
16141
+ }
15731
16142
  function collectExternalImports(ir, generatedCode, localImportPrefixes) {
15732
16143
  const componentNames = collectComponentNames(ir.root);
15733
16144
  const importLines = [];
@@ -15743,23 +16154,31 @@ function collectExternalImports(ir, generatedCode, localImportPrefixes) {
15743
16154
  importLines.push(`import '${imp.source}'`);
15744
16155
  continue;
15745
16156
  }
15746
- const usedSpecs = [];
16157
+ const usedNamed = [];
16158
+ let usedDefault = null;
16159
+ let usedNamespace = null;
15747
16160
  for (const spec of imp.specifiers) {
15748
16161
  if (spec.isTypeOnly)
15749
16162
  continue;
15750
16163
  const localName = spec.alias || spec.name;
15751
16164
  if (componentNames.has(localName))
15752
16165
  continue;
15753
- if (isUsedAsValue(localName)) {
15754
- usedSpecs.push(spec.alias ? `${spec.name} as ${spec.alias}` : spec.name);
16166
+ if (!isUsedAsValue(localName))
16167
+ continue;
16168
+ if (spec.isDefault) {
16169
+ usedDefault = localName;
16170
+ } else if (spec.isNamespace) {
16171
+ usedNamespace = localName;
16172
+ } else {
16173
+ usedNamed.push(spec.alias ? `${spec.name} as ${spec.alias}` : spec.name);
15755
16174
  }
15756
16175
  }
15757
- if (usedSpecs.length > 0) {
16176
+ if (usedDefault || usedNamespace || usedNamed.length > 0) {
15758
16177
  let source = imp.source;
15759
16178
  if (ir.metadata.clientSignalImportSources?.has(source)) {
15760
16179
  source = source.replace(/\.tsx?$/, "") + ".client.js";
15761
16180
  }
15762
- importLines.push(`import { ${usedSpecs.join(", ")} } from '${source}'`);
16181
+ importLines.push(...renderUsedImportLines(source, usedDefault, usedNamespace, usedNamed));
15763
16182
  }
15764
16183
  }
15765
16184
  return importLines;
@@ -15789,7 +16208,7 @@ function collectComponentNames(node) {
15789
16208
  }
15790
16209
 
15791
16210
  // ../jsx/src/relocate.ts
15792
- import ts16 from "typescript";
16211
+ import ts17 from "typescript";
15793
16212
 
15794
16213
  // ../jsx/src/lowering-registry.ts
15795
16214
  var plugins = [];
@@ -15817,19 +16236,19 @@ function classify(name, env) {
15817
16236
  function collectFreeRefs(node) {
15818
16237
  const refs = new Map;
15819
16238
  function visit3(n, parent) {
15820
- if (ts16.isIdentifier(n)) {
15821
- if (parent && ts16.isPropertyAccessExpression(parent) && parent.name === n)
16239
+ if (ts17.isIdentifier(n)) {
16240
+ if (parent && ts17.isPropertyAccessExpression(parent) && parent.name === n)
15822
16241
  return;
15823
- if (parent && ts16.isPropertyAssignment(parent) && parent.name === n)
16242
+ if (parent && ts17.isPropertyAssignment(parent) && parent.name === n)
15824
16243
  return;
15825
- if (parent && ts16.isShorthandPropertyAssignment(parent) && parent.name === n)
16244
+ if (parent && ts17.isShorthandPropertyAssignment(parent) && parent.name === n)
15826
16245
  return;
15827
16246
  const list = refs.get(n.text) ?? [];
15828
16247
  list.push(n);
15829
16248
  refs.set(n.text, list);
15830
16249
  return;
15831
16250
  }
15832
- ts16.forEachChild(n, (child) => visit3(child, n));
16251
+ ts17.forEachChild(n, (child) => visit3(child, n));
15833
16252
  }
15834
16253
  visit3(node);
15835
16254
  return refs;
@@ -15933,11 +16352,11 @@ function isInlinableInTemplate(value, env) {
15933
16352
  return { ok: true, rewrittenValue: r.text, decisions: r.decisions };
15934
16353
  }
15935
16354
  function getCalleeIdentifierPath(callee) {
15936
- if (ts16.isParenthesizedExpression(callee))
16355
+ if (ts17.isParenthesizedExpression(callee))
15937
16356
  return getCalleeIdentifierPath(callee.expression);
15938
- if (ts16.isIdentifier(callee))
16357
+ if (ts17.isIdentifier(callee))
15939
16358
  return callee.text;
15940
- if (ts16.isPropertyAccessExpression(callee)) {
16359
+ if (ts17.isPropertyAccessExpression(callee)) {
15941
16360
  const left = getCalleeIdentifierPath(callee.expression);
15942
16361
  if (left === null)
15943
16362
  return null;
@@ -15946,11 +16365,11 @@ function getCalleeIdentifierPath(callee) {
15946
16365
  return null;
15947
16366
  }
15948
16367
  function getCalleeLeftmostIdentifier(callee) {
15949
- if (ts16.isParenthesizedExpression(callee))
16368
+ if (ts17.isParenthesizedExpression(callee))
15950
16369
  return getCalleeLeftmostIdentifier(callee.expression);
15951
- if (ts16.isIdentifier(callee))
16370
+ if (ts17.isIdentifier(callee))
15952
16371
  return callee.text;
15953
- if (ts16.isPropertyAccessExpression(callee)) {
16372
+ if (ts17.isPropertyAccessExpression(callee)) {
15954
16373
  return getCalleeLeftmostIdentifier(callee.expression);
15955
16374
  }
15956
16375
  return null;
@@ -15998,12 +16417,12 @@ function isCallAcceptedByAdapter(call, env) {
15998
16417
  }
15999
16418
  function parseExpressionNode(text) {
16000
16419
  try {
16001
- const sf = ts16.createSourceFile("__inline_check__.ts", `(${text});`, ts16.ScriptTarget.Latest, false, ts16.ScriptKind.TS);
16420
+ const sf = ts17.createSourceFile("__inline_check__.ts", `(${text});`, ts17.ScriptTarget.Latest, false, ts17.ScriptKind.TS);
16002
16421
  const stmt = sf.statements[0];
16003
- if (!stmt || !ts16.isExpressionStatement(stmt))
16422
+ if (!stmt || !ts17.isExpressionStatement(stmt))
16004
16423
  return null;
16005
16424
  const inner = stmt.expression;
16006
- return ts16.isParenthesizedExpression(inner) ? inner.expression : inner;
16425
+ return ts17.isParenthesizedExpression(inner) ? inner.expression : inner;
16007
16426
  } catch {
16008
16427
  return null;
16009
16428
  }
@@ -16020,8 +16439,8 @@ function hasCallWithBridgedArg(node, decisions, env) {
16020
16439
  function visit3(n) {
16021
16440
  if (found)
16022
16441
  return;
16023
- if (ts16.isCallExpression(n) || ts16.isNewExpression(n)) {
16024
- const accepted = ts16.isCallExpression(n) && isCallAcceptedByAdapter(n, env);
16442
+ if (ts17.isCallExpression(n) || ts17.isNewExpression(n)) {
16443
+ const accepted = ts17.isCallExpression(n) && isCallAcceptedByAdapter(n, env);
16025
16444
  if (!accepted) {
16026
16445
  const args = n.arguments;
16027
16446
  if (args) {
@@ -16034,7 +16453,7 @@ function hasCallWithBridgedArg(node, decisions, env) {
16034
16453
  }
16035
16454
  }
16036
16455
  }
16037
- ts16.forEachChild(n, visit3);
16456
+ ts17.forEachChild(n, visit3);
16038
16457
  }
16039
16458
  visit3(node);
16040
16459
  return found;
@@ -16044,13 +16463,13 @@ function hasZeroArgCall(node, env) {
16044
16463
  function visit3(n) {
16045
16464
  if (found)
16046
16465
  return;
16047
- if (ts16.isCallExpression(n) && n.arguments.length === 0) {
16466
+ if (ts17.isCallExpression(n) && n.arguments.length === 0) {
16048
16467
  if (!isCallAcceptedByAdapter(n, env)) {
16049
16468
  found = true;
16050
16469
  return;
16051
16470
  }
16052
16471
  }
16053
- ts16.forEachChild(n, visit3);
16472
+ ts17.forEachChild(n, visit3);
16054
16473
  }
16055
16474
  visit3(node);
16056
16475
  return found;
@@ -16060,25 +16479,25 @@ function containsAnyIdentifier(node, names) {
16060
16479
  function visit3(n) {
16061
16480
  if (found)
16062
16481
  return;
16063
- if (ts16.isPropertyAccessExpression(n)) {
16482
+ if (ts17.isPropertyAccessExpression(n)) {
16064
16483
  visit3(n.expression);
16065
16484
  return;
16066
16485
  }
16067
- if (ts16.isPropertyAssignment(n)) {
16486
+ if (ts17.isPropertyAssignment(n)) {
16068
16487
  visit3(n.initializer);
16069
16488
  return;
16070
16489
  }
16071
- if (ts16.isShorthandPropertyAssignment(n)) {
16072
- if (ts16.isIdentifier(n.name) && names.has(n.name.text)) {
16490
+ if (ts17.isShorthandPropertyAssignment(n)) {
16491
+ if (ts17.isIdentifier(n.name) && names.has(n.name.text)) {
16073
16492
  found = true;
16074
16493
  }
16075
16494
  return;
16076
16495
  }
16077
- if (ts16.isIdentifier(n) && names.has(n.text)) {
16496
+ if (ts17.isIdentifier(n) && names.has(n.text)) {
16078
16497
  found = true;
16079
16498
  return;
16080
16499
  }
16081
- ts16.forEachChild(n, visit3);
16500
+ ts17.forEachChild(n, visit3);
16082
16501
  }
16083
16502
  visit3(node);
16084
16503
  return found;
@@ -17365,23 +17784,23 @@ function resolveFinalImports(generatedCode, ir, localImportPrefixes) {
17365
17784
  }
17366
17785
 
17367
17786
  // ../jsx/src/ir-to-client-js/prune-unused-prop-extractions.ts
17368
- import ts17 from "typescript";
17787
+ import ts18 from "typescript";
17369
17788
  function propExtractionName(stmt) {
17370
- if (!ts17.isVariableStatement(stmt))
17789
+ if (!ts18.isVariableStatement(stmt))
17371
17790
  return null;
17372
17791
  const decls = stmt.declarationList.declarations;
17373
17792
  if (decls.length !== 1)
17374
17793
  return null;
17375
17794
  const decl = decls[0];
17376
- if (!ts17.isIdentifier(decl.name) || !decl.initializer)
17795
+ if (!ts18.isIdentifier(decl.name) || !decl.initializer)
17377
17796
  return null;
17378
17797
  let core = decl.initializer;
17379
- if (ts17.isBinaryExpression(core) && core.operatorToken.kind === ts17.SyntaxKind.QuestionQuestionToken) {
17798
+ if (ts18.isBinaryExpression(core) && core.operatorToken.kind === ts18.SyntaxKind.QuestionQuestionToken) {
17380
17799
  core = core.left;
17381
17800
  }
17382
- if (!ts17.isPropertyAccessExpression(core))
17801
+ if (!ts18.isPropertyAccessExpression(core))
17383
17802
  return null;
17384
- if (!ts17.isIdentifier(core.expression) || core.expression.text !== PROPS_PARAM)
17803
+ if (!ts18.isIdentifier(core.expression) || core.expression.text !== PROPS_PARAM)
17385
17804
  return null;
17386
17805
  if (core.name.text !== decl.name.text)
17387
17806
  return null;
@@ -17394,10 +17813,10 @@ function pruneUnusedPropExtractions(code) {
17394
17813
  console.warn("[barefootjs] pruneUnusedPropExtractions: generated code did not parse; skipping prune");
17395
17814
  return code;
17396
17815
  }
17397
- const sourceFile = ts17.createSourceFile("generated.js", code, ts17.ScriptTarget.Latest, false, ts17.ScriptKind.JS);
17816
+ const sourceFile = ts18.createSourceFile("generated.js", code, ts18.ScriptTarget.Latest, false, ts18.ScriptKind.JS);
17398
17817
  const spans = [];
17399
17818
  for (const stmt of sourceFile.statements) {
17400
- if (!ts17.isFunctionDeclaration(stmt) || !stmt.name?.text.startsWith("init") || !stmt.body)
17819
+ if (!ts18.isFunctionDeclaration(stmt) || !stmt.name?.text.startsWith("init") || !stmt.body)
17401
17820
  continue;
17402
17821
  for (const inner of stmt.body.statements) {
17403
17822
  const name = propExtractionName(inner);
@@ -18856,7 +19275,7 @@ function analyzeLazyConditional(cond, indexParam, arms) {
18856
19275
  }
18857
19276
 
18858
19277
  // ../jsx/src/ir-to-client-js/control-flow/plan/lazy-preamble.ts
18859
- import ts18 from "typescript";
19278
+ import ts19 from "typescript";
18860
19279
  var NO_PREAMBLE = {
18861
19280
  lazySafe: true,
18862
19281
  facts: { declaredNames: new Set, freeNames: new Set }
@@ -18876,12 +19295,12 @@ function analyzeLazyPreamble(preamble, indexParam, primableNames) {
18876
19295
  if (text.trim().length === 0)
18877
19296
  return NO_PREAMBLE;
18878
19297
  const declaredNames = new Set;
18879
- const sf = ts18.createSourceFile("__lazy_preamble__.ts", text, ts18.ScriptTarget.Latest, true, ts18.ScriptKind.TS);
19298
+ const sf = ts19.createSourceFile("__lazy_preamble__.ts", text, ts19.ScriptTarget.Latest, true, ts19.ScriptKind.TS);
18880
19299
  for (const stmt of sf.statements) {
18881
- if (!ts18.isVariableStatement(stmt)) {
18882
- return NO2(`map-callback preamble has a non-declaration statement (${ts18.SyntaxKind[stmt.kind]})`);
19300
+ if (!ts19.isVariableStatement(stmt)) {
19301
+ return NO2(`map-callback preamble has a non-declaration statement (${ts19.SyntaxKind[stmt.kind]})`);
18883
19302
  }
18884
- const isConst = (stmt.declarationList.flags & ts18.NodeFlags.Const) !== 0;
19303
+ const isConst = (stmt.declarationList.flags & ts19.NodeFlags.Const) !== 0;
18885
19304
  if (!isConst)
18886
19305
  return NO2("map-callback preamble declares a mutable binding (let/var)");
18887
19306
  for (const decl of stmt.declarationList.declarations) {
@@ -18910,12 +19329,12 @@ function analyzeLazyPreamble(preamble, indexParam, primableNames) {
18910
19329
  return { lazySafe: true, facts: { declaredNames, freeNames } };
18911
19330
  }
18912
19331
  function collectBindingNames3(name, out) {
18913
- if (ts18.isIdentifier(name)) {
19332
+ if (ts19.isIdentifier(name)) {
18914
19333
  out.add(name.text);
18915
19334
  return;
18916
19335
  }
18917
19336
  for (const element of name.elements) {
18918
- if (ts18.isOmittedExpression(element))
19337
+ if (ts19.isOmittedExpression(element))
18919
19338
  continue;
18920
19339
  collectBindingNames3(element.name, out);
18921
19340
  }
@@ -18925,56 +19344,56 @@ function findImpureNode(root, primableNames) {
18925
19344
  const visit3 = (node) => {
18926
19345
  if (found)
18927
19346
  return;
18928
- if (ts18.isCallExpression(node)) {
19347
+ if (ts19.isCallExpression(node)) {
18929
19348
  const callee = node.expression;
18930
- const isSignalRead = ts18.isIdentifier(callee) && primableNames.has(callee.text) && node.arguments.length === 0 && node.questionDotToken === undefined;
19349
+ const isSignalRead = ts19.isIdentifier(callee) && primableNames.has(callee.text) && node.arguments.length === 0 && node.questionDotToken === undefined;
18931
19350
  if (!isSignalRead) {
18932
19351
  found = `call to ${callee.getText(callee.getSourceFile())}`;
18933
19352
  return;
18934
19353
  }
18935
19354
  }
18936
- if (ts18.isNewExpression(node)) {
19355
+ if (ts19.isNewExpression(node)) {
18937
19356
  found = "new expression";
18938
19357
  return;
18939
19358
  }
18940
- if (ts18.isTaggedTemplateExpression(node)) {
19359
+ if (ts19.isTaggedTemplateExpression(node)) {
18941
19360
  found = "tagged template";
18942
19361
  return;
18943
19362
  }
18944
- if (ts18.isAwaitExpression(node)) {
19363
+ if (ts19.isAwaitExpression(node)) {
18945
19364
  found = "await";
18946
19365
  return;
18947
19366
  }
18948
- if (ts18.isYieldExpression(node)) {
19367
+ if (ts19.isYieldExpression(node)) {
18949
19368
  found = "yield";
18950
19369
  return;
18951
19370
  }
18952
- if (ts18.isPrefixUnaryExpression(node) || ts18.isPostfixUnaryExpression(node)) {
19371
+ if (ts19.isPrefixUnaryExpression(node) || ts19.isPostfixUnaryExpression(node)) {
18953
19372
  const op = node.operator;
18954
- if (op === ts18.SyntaxKind.PlusPlusToken || op === ts18.SyntaxKind.MinusMinusToken) {
19373
+ if (op === ts19.SyntaxKind.PlusPlusToken || op === ts19.SyntaxKind.MinusMinusToken) {
18955
19374
  found = "increment/decrement";
18956
19375
  return;
18957
19376
  }
18958
19377
  }
18959
- if (ts18.isDeleteExpression(node)) {
19378
+ if (ts19.isDeleteExpression(node)) {
18960
19379
  found = "delete";
18961
19380
  return;
18962
19381
  }
18963
- if (ts18.isFunctionExpression(node) || ts18.isArrowFunction(node) || ts18.isClassExpression(node)) {
19382
+ if (ts19.isFunctionExpression(node) || ts19.isArrowFunction(node) || ts19.isClassExpression(node)) {
18964
19383
  found = "function or class expression";
18965
19384
  return;
18966
19385
  }
18967
- if (ts18.isBinaryExpression(node) && isAssignmentOperator2(node.operatorToken.kind)) {
19386
+ if (ts19.isBinaryExpression(node) && isAssignmentOperator2(node.operatorToken.kind)) {
18968
19387
  found = "assignment";
18969
19388
  return;
18970
19389
  }
18971
- ts18.forEachChild(node, visit3);
19390
+ ts19.forEachChild(node, visit3);
18972
19391
  };
18973
19392
  visit3(root);
18974
19393
  return found;
18975
19394
  }
18976
19395
  function isAssignmentOperator2(kind) {
18977
- return kind >= ts18.SyntaxKind.FirstAssignment && kind <= ts18.SyntaxKind.LastAssignment;
19396
+ return kind >= ts19.SyntaxKind.FirstAssignment && kind <= ts19.SyntaxKind.LastAssignment;
18978
19397
  }
18979
19398
 
18980
19399
  // ../jsx/src/ir-to-client-js/control-flow/plan/lazy-row-eligibility.ts
@@ -19504,7 +19923,7 @@ function buildArmBody(branch, options) {
19504
19923
  }
19505
19924
 
19506
19925
  // ../jsx/src/ir-to-client-js/emit-reactive.ts
19507
- import ts19 from "typescript";
19926
+ import ts20 from "typescript";
19508
19927
 
19509
19928
  // ../jsx/src/ir-to-client-js/control-flow/stringify/claim-plan.ts
19510
19929
  function slotSpecLiteral(slot) {
@@ -19616,20 +20035,20 @@ function lowerToLocaleCallsInReactiveExpr(expr, matcher) {
19616
20035
  return expr;
19617
20036
  let sourceFile;
19618
20037
  try {
19619
- sourceFile = ts19.createSourceFile("__reactive_expr__.ts", `(${expr});`, ts19.ScriptTarget.Latest, true, ts19.ScriptKind.TS);
20038
+ sourceFile = ts20.createSourceFile("__reactive_expr__.ts", `(${expr});`, ts20.ScriptTarget.Latest, true, ts20.ScriptKind.TS);
19620
20039
  } catch {
19621
20040
  return expr;
19622
20041
  }
19623
20042
  const stmt = sourceFile.statements[0];
19624
- if (!stmt || !ts19.isExpressionStatement(stmt))
20043
+ if (!stmt || !ts20.isExpressionStatement(stmt))
19625
20044
  return expr;
19626
- const root = ts19.isParenthesizedExpression(stmt.expression) ? stmt.expression.expression : stmt.expression;
20045
+ const root = ts20.isParenthesizedExpression(stmt.expression) ? stmt.expression.expression : stmt.expression;
19627
20046
  const candidates = [];
19628
20047
  const visit3 = (n) => {
19629
- if (ts19.isCallExpression(n) && n.arguments.length === 2 && ts19.isPropertyAccessExpression(n.expression) && !n.expression.questionDotToken && n.expression.name.text === "toLocaleDateString") {
20048
+ if (ts20.isCallExpression(n) && n.arguments.length === 2 && ts20.isPropertyAccessExpression(n.expression) && !n.expression.questionDotToken && n.expression.name.text === "toLocaleDateString") {
19630
20049
  candidates.push(n);
19631
20050
  }
19632
- ts19.forEachChild(n, visit3);
20051
+ ts20.forEachChild(n, visit3);
19633
20052
  };
19634
20053
  visit3(root);
19635
20054
  if (candidates.length === 0)
@@ -19665,20 +20084,20 @@ function lowerDateCallsInReactiveExpr(expr, matcher) {
19665
20084
  return expr;
19666
20085
  let sourceFile;
19667
20086
  try {
19668
- sourceFile = ts19.createSourceFile("__reactive_expr__.ts", `(${expr});`, ts19.ScriptTarget.Latest, true, ts19.ScriptKind.TS);
20087
+ sourceFile = ts20.createSourceFile("__reactive_expr__.ts", `(${expr});`, ts20.ScriptTarget.Latest, true, ts20.ScriptKind.TS);
19669
20088
  } catch {
19670
20089
  return expr;
19671
20090
  }
19672
20091
  const stmt = sourceFile.statements[0];
19673
- if (!stmt || !ts19.isExpressionStatement(stmt))
20092
+ if (!stmt || !ts20.isExpressionStatement(stmt))
19674
20093
  return expr;
19675
- const root = ts19.isParenthesizedExpression(stmt.expression) ? stmt.expression.expression : stmt.expression;
20094
+ const root = ts20.isParenthesizedExpression(stmt.expression) ? stmt.expression.expression : stmt.expression;
19676
20095
  const candidates = [];
19677
20096
  const visit3 = (n) => {
19678
- if (ts19.isCallExpression(n) && n.arguments.length === 0 && ts19.isPropertyAccessExpression(n.expression) && !n.expression.questionDotToken && DATE_METHODS.has(n.expression.name.text)) {
20097
+ if (ts20.isCallExpression(n) && n.arguments.length === 0 && ts20.isPropertyAccessExpression(n.expression) && !n.expression.questionDotToken && DATE_METHODS.has(n.expression.name.text)) {
19679
20098
  candidates.push(n);
19680
20099
  }
19681
- ts19.forEachChild(n, visit3);
20100
+ ts20.forEachChild(n, visit3);
19682
20101
  };
19683
20102
  visit3(root);
19684
20103
  if (candidates.length === 0)
@@ -19917,7 +20336,7 @@ function stringifyBranchInnerLoops(lines, plan, indent, pc) {
19917
20336
  lines.push(`${indent} let __bel${uid} = __existing ?? (() => { const __t = document.createElement('template'); __t.innerHTML = \`${innerHtml}\`; return __t.content${childPath}.cloneNode(true) })()`);
19918
20337
  }
19919
20338
  if (inner.wrappedKey) {
19920
- lines.push(`${indent} __bel${uid}.setAttribute('${keyAttrName(inner.keyDepth)}', String(${inner.wrappedKey}))`);
20339
+ lines.push(`${indent} __bel${uid}.setAttribute('${keyAttrName2(inner.keyDepth)}', String(${inner.wrappedKey}))`);
19921
20340
  }
19922
20341
  if (inner.legacyComponents.length > 0 || inner.legacyEvents.length > 0) {
19923
20342
  emitComponentAndEventSetup(lines, `${indent} `, `__bel${uid}`, [...inner.legacyComponents], [...inner.legacyEvents], inner.outerLoopParam, inner.outerLoopParamBindings);
@@ -19940,7 +20359,7 @@ function stringifyBranchInnerLoops(lines, plan, indent, pc) {
19940
20359
  stringifyLoopChildConditionals(lines, inner.nestedConditionals, `${indent} `, pc);
19941
20360
  }
19942
20361
  lines.push(`${indent} return __bel${uid}`);
19943
- lines.push(`${indent}}, '${inner.markerId}'${profileBindingId(pc, inner.slotId)}) }`);
20362
+ lines.push(`${indent}}, '${inner.markerId}'${mapArrayKeyArgs(profileBindingId(pc, inner.slotId), !!inner.wrappedKey, inner.keyDepth)}) }`);
19944
20363
  }
19945
20364
  }
19946
20365
  function stringifyLoopChildConditionals(lines, conditionals, indent, pc) {
@@ -20172,12 +20591,15 @@ function stringifyComponentLoop(lines, plan) {
20172
20591
  keyExpr,
20173
20592
  nestedComps,
20174
20593
  childConditionalEffects,
20175
- profileLoopId
20594
+ profileLoopId,
20595
+ mapPreambleWrapped
20176
20596
  } = plan;
20177
20597
  const loopBfId = profileLoopId ? `, ${JSON.stringify(profileLoopId)}` : "";
20178
20598
  lines.push(` mapArray(() => ${arrayExpr}, ${containerVar}, ${keyFn}, (${paramHead}, ${indexParam}, __existing) => {`);
20179
20599
  if (paramUnwrap)
20180
20600
  lines.push(` ${paramUnwrap}`);
20601
+ if (mapPreambleWrapped)
20602
+ lines.push(` ${mapPreambleWrapped}`);
20181
20603
  const scopedComp = nameForRegistryRef(componentName);
20182
20604
  if (nestedComps.length === 0) {
20183
20605
  lines.push(` if (__existing) { initChild('${scopedComp}', __existing, ${componentPropsExpr}); return __existing }`);
@@ -20749,7 +21171,7 @@ function emitReactive(lines, inner, indent, pc) {
20749
21171
  lines.push(`${indent} let __innerEl${uid} = __existing ?? (() => { const __t = document.createElement('template'); __t.innerHTML = \`${innerHtml}\`; return __t.content${childPath}.cloneNode(true) })()`);
20750
21172
  }
20751
21173
  if (emit.wrappedKey) {
20752
- lines.push(`${indent} __innerEl${uid}.setAttribute('${keyAttrName(inner.keyDepth)}', String(${emit.wrappedKey}))`);
21174
+ lines.push(`${indent} __innerEl${uid}.setAttribute('${keyAttrName2(inner.keyDepth)}', String(${emit.wrappedKey}))`);
20753
21175
  }
20754
21176
  if (emit.components.length > 0 || emit.events.length > 0) {
20755
21177
  emitComponentAndEventSetup(lines, `${indent} `, `__innerEl${uid}`, [...emit.components], [...emit.events], inner.outerLoopParam, inner.outerLoopParamBindings);
@@ -20789,7 +21211,7 @@ function emitReactive(lines, inner, indent, pc) {
20789
21211
  bodyIsMultiRoot: emit.bodyIsMultiRoot
20790
21212
  });
20791
21213
  lines.push(`${indent} return __innerEl${uid}`);
20792
- lines.push(`${indent}}, '${inner.markerId}'${profileBindingId(pc, inner.slotId)}) }`);
21214
+ lines.push(`${indent}}, '${inner.markerId}'${mapArrayKeyArgs(profileBindingId(pc, inner.slotId), !!emit.wrappedKey, inner.keyDepth)}) }`);
20793
21215
  }
20794
21216
  function emitStatic(lines, inner, indent, pc) {
20795
21217
  const uid = inner.uidSuffix;
@@ -20805,7 +21227,7 @@ function emitStatic(lines, inner, indent, pc) {
20805
21227
  lines.push(`${indent} ${stmt}`);
20806
21228
  }
20807
21229
  if (emit.rawKey) {
20808
- lines.push(`${indent} __innerEl${uid}.setAttribute('${keyAttrName(inner.keyDepth)}', String(${emit.rawKey}))`);
21230
+ lines.push(`${indent} __innerEl${uid}.setAttribute('${keyAttrName2(inner.keyDepth)}', String(${emit.rawKey}))`);
20809
21231
  }
20810
21232
  emitComponentAndEventSetup(lines, `${indent} `, `__innerEl${uid}`, [...emit.components], [...emit.events], inner.outerLoopParam, inner.outerLoopParamBindings);
20811
21233
  if (inner.childLevels.length > 0) {
@@ -20993,7 +21415,7 @@ function emitKeyedLookup(ls, ev, handlerCall, lookup) {
20993
21415
  }
20994
21416
  const evVar = varSlotId(ev.childSlotId);
20995
21417
  for (const nested of ev.nestedLoops) {
20996
- const dataAttr = keyAttrName(nested.depth);
21418
+ const dataAttr = keyAttrName2(nested.depth);
20997
21419
  ls.push(` const innerLi${nested.depth} = ${evVar}El.closest('[${dataAttr}]')`);
20998
21420
  ls.push(` const innerKey${nested.depth} = innerLi${nested.depth}?.getAttribute('${dataAttr}')`);
20999
21421
  }
@@ -21293,6 +21715,12 @@ function buildComponentLoopPlan(elem, profileComponentName) {
21293
21715
  const propsExpr = buildComponentPropsExpr2(elem.childComponent, elem.param);
21294
21716
  const keyExpr = wrapLoopParamAsAccessor(elem.key || "__idx", elem.param, elem.paramBindings);
21295
21717
  const { head: paramHead, unwrap: paramUnwrap } = destructureLoopParam(elem.param, elem.paramBindings);
21718
+ const mapPreambleWrapped = elem.preamble ? renderPreamble(elem.preamble, {
21719
+ transformJs: (text) => wrapLoopParamAsAccessor(text, elem.param, elem.paramBindings),
21720
+ renderLeaf: () => {
21721
+ internalInvariant(false, "component-root loop received a JSX-bearing preamble — Phase 1 should have refused it");
21722
+ }
21723
+ }) : "";
21296
21724
  const outerNestedComps = (elem.nestedComponents ?? []).filter((c) => !c.loopDepth);
21297
21725
  const nestedComps = outerNestedComps.map((comp) => {
21298
21726
  const isTextOnly = comp.children?.length ? comp.children.every((c) => c.type === "expression" || c.type === "text" || isTextOnlyConditional(c)) : false;
@@ -21310,6 +21738,7 @@ function buildComponentLoopPlan(elem, profileComponentName) {
21310
21738
  return {
21311
21739
  kind: "component",
21312
21740
  rowConstruction: "dom-ops",
21741
+ mapPreambleWrapped,
21313
21742
  containerVar: `_${varSlotId(elem.slotId)}`,
21314
21743
  markerId: elem.markerId,
21315
21744
  arrayExpr: buildChainedArrayExpr(elem),
@@ -21492,6 +21921,7 @@ function emitLoopUpdates(lines, ctx, unsafeLocalNames) {
21492
21921
  lazyScope
21493
21922
  });
21494
21923
  internalInvariant(!(elem.preamble && elem.preamble.builderNames.length > 0 && plan.rowConstruction === "dom-ops"), `loop variant '${plan.kind}' declares dom-ops row construction but received a JSX-bearing preamble — add a Phase-1 refusal (or wire renderPreamble support) for this shape`);
21924
+ internalInvariant(!(elem.preamble && elem.preamble.declaredNames.length > 0 && ("mapPreambleWrapped" in plan) && plan.mapPreambleWrapped === ""), `loop variant '${plan.kind}' has a preamble with declared names (${elem.preamble?.declaredNames.join(", ")}) but its plan's mapPreambleWrapped is empty — wire it up or the emitted call site references a name nothing declares`);
21495
21925
  stringifyLoop(lines, plan);
21496
21926
  emitLoopEventDelegation(lines, elem, plan.kind, ctx.profile ? ctx.componentName : undefined);
21497
21927
  }
@@ -21699,7 +22129,7 @@ var PHASES = [
21699
22129
  ];
21700
22130
 
21701
22131
  // ../jsx/src/ir-to-client-js/rewrite-props-object.ts
21702
- import ts20 from "typescript";
22132
+ import ts21 from "typescript";
21703
22133
  function rewritePropsObjectRef(code, propsObjectName, restPropsName = null) {
21704
22134
  let result = code;
21705
22135
  const seen = new Set;
@@ -21714,13 +22144,13 @@ function rewritePropsObjectRef(code, propsObjectName, restPropsName = null) {
21714
22144
  function rewriteOneName(code, srcPropsName) {
21715
22145
  if (!identifierPattern(srcPropsName).test(code))
21716
22146
  return code;
21717
- const sourceFile = ts20.createSourceFile("init-body.ts", code, ts20.ScriptTarget.Latest, true, ts20.ScriptKind.TS);
22147
+ const sourceFile = ts21.createSourceFile("init-body.ts", code, ts21.ScriptTarget.Latest, true, ts21.ScriptKind.TS);
21718
22148
  const spans = [];
21719
22149
  function visit3(node) {
21720
- if (ts20.isIdentifier(node) && node.text === srcPropsName && shouldRewrite(node)) {
22150
+ if (ts21.isIdentifier(node) && node.text === srcPropsName && shouldRewrite(node)) {
21721
22151
  spans.push([node.getStart(sourceFile), node.getEnd()]);
21722
22152
  }
21723
- ts20.forEachChild(node, visit3);
22153
+ ts21.forEachChild(node, visit3);
21724
22154
  }
21725
22155
  visit3(sourceFile);
21726
22156
  if (spans.length === 0)
@@ -21736,17 +22166,17 @@ function shouldRewrite(node) {
21736
22166
  const parent = node.parent;
21737
22167
  if (!parent)
21738
22168
  return true;
21739
- if (ts20.isPropertyAccessExpression(parent) && parent.name === node)
22169
+ if (ts21.isPropertyAccessExpression(parent) && parent.name === node)
21740
22170
  return false;
21741
- if (ts20.isPropertyAssignment(parent) && parent.name === node)
22171
+ if (ts21.isPropertyAssignment(parent) && parent.name === node)
21742
22172
  return false;
21743
- if (ts20.isShorthandPropertyAssignment(parent) && parent.name === node)
22173
+ if (ts21.isShorthandPropertyAssignment(parent) && parent.name === node)
21744
22174
  return false;
21745
- if (ts20.isPropertySignature(parent) && parent.name === node)
22175
+ if (ts21.isPropertySignature(parent) && parent.name === node)
21746
22176
  return false;
21747
- if (ts20.isPropertyDeclaration(parent) && parent.name === node)
22177
+ if (ts21.isPropertyDeclaration(parent) && parent.name === node)
21748
22178
  return false;
21749
- if (ts20.isBindingElement(parent) && parent.name === node)
22179
+ if (ts21.isBindingElement(parent) && parent.name === node)
21750
22180
  return false;
21751
22181
  return true;
21752
22182
  }
@@ -22057,7 +22487,7 @@ function createContext(ir, scope, adapterCapabilities, profile) {
22057
22487
  };
22058
22488
  }
22059
22489
  function needsClientJs(ctx) {
22060
- if (ctx.signals.length > 0 || ctx.memos.length > 0 || ctx.effects.length > 0 || ctx.onMounts.length > 0 || ctx.initStatements.length > 0 || ctx.interactiveElements.length > 0 || ctx.dynamicElements.length > 0 || ctx.conditionalElements.length > 0 || ctx.loopElements.length > 0 || ctx.refElements.length > 0 || ctx.childInits.length > 0 || ctx.reactiveAttrs.length > 0 || ctx.clientOnlyElements.length > 0 || ctx.clientOnlyConditionals.length > 0 || ctx.providerSetups.length > 0)
22490
+ if (ctx.signals.length > 0 || ctx.memos.length > 0 || ctx.effects.length > 0 || ctx.onMounts.length > 0 || ctx.initStatements.length > 0 || ctx.interactiveElements.length > 0 || ctx.dynamicElements.length > 0 || ctx.conditionalElements.length > 0 || ctx.loopElements.length > 0 || ctx.refElements.length > 0 || ctx.restAttrElements.length > 0 || ctx.childInits.length > 0 || ctx.reactiveAttrs.length > 0 || ctx.clientOnlyElements.length > 0 || ctx.clientOnlyConditionals.length > 0 || ctx.providerSetups.length > 0)
22061
22491
  return true;
22062
22492
  return hasInitScopeOnlyConstant(ctx);
22063
22493
  }
@@ -22395,7 +22825,7 @@ function walkIR2(node, visitor) {
22395
22825
  }
22396
22826
 
22397
22827
  // ../jsx/src/preprocess-inline-jsx-callbacks.ts
22398
- import ts21 from "typescript";
22828
+ import ts22 from "typescript";
22399
22829
  var SYNTHETIC_PREFIX = "BFInlineJsxCallback";
22400
22830
  var MAX_FIXPOINT_ITERATIONS = 16;
22401
22831
  function preprocessInlineJsxCallbacks(source, filePath) {
@@ -22417,8 +22847,8 @@ function preprocessInlineJsxCallbacks(source, filePath) {
22417
22847
  return { source: current, errors, syntheticNames };
22418
22848
  }
22419
22849
  function runSinglePass(source, filePath, startingCounter) {
22420
- const sourceFile = ts21.createSourceFile(filePath, source, ts21.ScriptTarget.Latest, true, ts21.ScriptKind.TSX);
22421
- const hasUseClient = sourceFile.statements.some((stmt) => ts21.isExpressionStatement(stmt) && ts21.isStringLiteral(stmt.expression) && (stmt.expression.text === "use client" || stmt.expression.text === "'use client'"));
22850
+ const sourceFile = ts22.createSourceFile(filePath, source, ts22.ScriptTarget.Latest, true, ts22.ScriptKind.TSX);
22851
+ const hasUseClient = sourceFile.statements.some((stmt) => ts22.isExpressionStatement(stmt) && ts22.isStringLiteral(stmt.expression) && (stmt.expression.text === "use client" || stmt.expression.text === "'use client'"));
22422
22852
  if (!hasUseClient) {
22423
22853
  return { source, errors: [], syntheticNames: [], counterAfter: startingCounter };
22424
22854
  }
@@ -22440,22 +22870,22 @@ function runSinglePass(source, filePath, startingCounter) {
22440
22870
  }
22441
22871
  }
22442
22872
  function visit3(node) {
22443
- if (ts21.isJsxAttribute(node) && node.initializer && ts21.isJsxExpression(node.initializer) && node.initializer.expression) {
22873
+ if (ts22.isJsxAttribute(node) && node.initializer && ts22.isJsxExpression(node.initializer) && node.initializer.expression) {
22444
22874
  if (tryHandleArrowValue(node.initializer.expression)) {
22445
22875
  return;
22446
22876
  }
22447
22877
  }
22448
- if (ts21.isPropertyAssignment(node) && node.initializer) {
22878
+ if (ts22.isPropertyAssignment(node) && node.initializer) {
22449
22879
  if (tryHandleArrowValue(node.initializer))
22450
22880
  return;
22451
22881
  }
22452
- ts21.forEachChild(node, visit3);
22882
+ ts22.forEachChild(node, visit3);
22453
22883
  }
22454
22884
  function tryHandleArrowValue(initializer) {
22455
22885
  let expr = initializer;
22456
- while (ts21.isParenthesizedExpression(expr))
22886
+ while (ts22.isParenthesizedExpression(expr))
22457
22887
  expr = expr.expression;
22458
- if (ts21.isArrowFunction(expr) && arrowBodyContainsJsx(expr)) {
22888
+ if (ts22.isArrowFunction(expr) && arrowBodyContainsJsx(expr)) {
22459
22889
  return handleInlineArrow(expr);
22460
22890
  }
22461
22891
  return false;
@@ -22492,7 +22922,7 @@ function runSinglePass(source, filePath, startingCounter) {
22492
22922
  replacements.push({ start: arrowStart, end: arrowEnd, text: name });
22493
22923
  return true;
22494
22924
  }
22495
- ts21.forEachChild(sourceFile, visit3);
22925
+ ts22.forEachChild(sourceFile, visit3);
22496
22926
  if (replacements.length === 0) {
22497
22927
  return { source, errors, syntheticNames, counterAfter: counter };
22498
22928
  }
@@ -22515,11 +22945,11 @@ function errorMessageForCapture(captures) {
22515
22945
  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.`;
22516
22946
  }
22517
22947
  function arrowBodyContainsJsx(arrow) {
22518
- if (ts21.isBlock(arrow.body)) {
22948
+ if (ts22.isBlock(arrow.body)) {
22519
22949
  return blockReturnsJsx(arrow.body);
22520
22950
  }
22521
22951
  let body = arrow.body;
22522
- while (ts21.isParenthesizedExpression(body))
22952
+ while (ts22.isParenthesizedExpression(body))
22523
22953
  body = body.expression;
22524
22954
  return isJsxLike(body);
22525
22955
  }
@@ -22528,24 +22958,24 @@ function blockReturnsJsx(block) {
22528
22958
  function visit3(n) {
22529
22959
  if (found)
22530
22960
  return;
22531
- if (ts21.isReturnStatement(n) && n.expression) {
22961
+ if (ts22.isReturnStatement(n) && n.expression) {
22532
22962
  let e = n.expression;
22533
- while (ts21.isParenthesizedExpression(e))
22963
+ while (ts22.isParenthesizedExpression(e))
22534
22964
  e = e.expression;
22535
22965
  if (isJsxLike(e)) {
22536
22966
  found = true;
22537
22967
  return;
22538
22968
  }
22539
22969
  }
22540
- if (ts21.isArrowFunction(n) || ts21.isFunctionDeclaration(n) || ts21.isFunctionExpression(n))
22970
+ if (ts22.isArrowFunction(n) || ts22.isFunctionDeclaration(n) || ts22.isFunctionExpression(n))
22541
22971
  return;
22542
- ts21.forEachChild(n, visit3);
22972
+ ts22.forEachChild(n, visit3);
22543
22973
  }
22544
- ts21.forEachChild(block, visit3);
22974
+ ts22.forEachChild(block, visit3);
22545
22975
  return found;
22546
22976
  }
22547
22977
  function isJsxLike(expr) {
22548
- return ts21.isJsxElement(expr) || ts21.isJsxSelfClosingElement(expr) || ts21.isJsxFragment(expr);
22978
+ return ts22.isJsxElement(expr) || ts22.isJsxSelfClosingElement(expr) || ts22.isJsxFragment(expr);
22549
22979
  }
22550
22980
  function collectArrowParamNames(arrow) {
22551
22981
  const names = new Set;
@@ -22555,13 +22985,13 @@ function collectArrowParamNames(arrow) {
22555
22985
  }
22556
22986
  function collectBindingNames4(name, out) {
22557
22987
  const push = Array.isArray(out) ? (n) => out.push(n) : (n) => out.add(n);
22558
- if (ts21.isIdentifier(name)) {
22988
+ if (ts22.isIdentifier(name)) {
22559
22989
  push(name.text);
22560
- } else if (ts21.isObjectBindingPattern(name)) {
22990
+ } else if (ts22.isObjectBindingPattern(name)) {
22561
22991
  name.elements.forEach((el) => collectBindingNames4(el.name, out));
22562
- } else if (ts21.isArrayBindingPattern(name)) {
22992
+ } else if (ts22.isArrayBindingPattern(name)) {
22563
22993
  name.elements.forEach((el) => {
22564
- if (!ts21.isOmittedExpression(el))
22994
+ if (!ts22.isOmittedExpression(el))
22565
22995
  collectBindingNames4(el.name, out);
22566
22996
  });
22567
22997
  }
@@ -22588,48 +23018,48 @@ function collectFreeIdentifiers(arrow) {
22588
23018
  return bound.includes(name);
22589
23019
  }
22590
23020
  function visit3(node) {
22591
- if (ts21.isIdentifier(node)) {
23021
+ if (ts22.isIdentifier(node)) {
22592
23022
  const parent = node.parent;
22593
- if (parent && ts21.isPropertyAccessExpression(parent) && parent.name === node)
23023
+ if (parent && ts22.isPropertyAccessExpression(parent) && parent.name === node)
22594
23024
  return;
22595
- if (parent && ts21.isPropertyAssignment(parent) && parent.name === node)
23025
+ if (parent && ts22.isPropertyAssignment(parent) && parent.name === node)
22596
23026
  return;
22597
- if (parent && ts21.isPropertySignature(parent) && parent.name === node)
23027
+ if (parent && ts22.isPropertySignature(parent) && parent.name === node)
22598
23028
  return;
22599
- if (parent && ts21.isPropertyDeclaration(parent) && parent.name === node)
23029
+ if (parent && ts22.isPropertyDeclaration(parent) && parent.name === node)
22600
23030
  return;
22601
- if (parent && ts21.isMethodDeclaration(parent) && parent.name === node)
23031
+ if (parent && ts22.isMethodDeclaration(parent) && parent.name === node)
22602
23032
  return;
22603
- if (parent && ts21.isMethodSignature(parent) && parent.name === node)
23033
+ if (parent && ts22.isMethodSignature(parent) && parent.name === node)
22604
23034
  return;
22605
- if (parent && ts21.isGetAccessorDeclaration(parent) && parent.name === node)
23035
+ if (parent && ts22.isGetAccessorDeclaration(parent) && parent.name === node)
22606
23036
  return;
22607
- if (parent && ts21.isSetAccessorDeclaration(parent) && parent.name === node)
23037
+ if (parent && ts22.isSetAccessorDeclaration(parent) && parent.name === node)
22608
23038
  return;
22609
- if (parent && ts21.isEnumMember(parent) && parent.name === node)
23039
+ if (parent && ts22.isEnumMember(parent) && parent.name === node)
22610
23040
  return;
22611
- if (parent && ts21.isBindingElement(parent) && parent.propertyName === node)
23041
+ if (parent && ts22.isBindingElement(parent) && parent.propertyName === node)
22612
23042
  return;
22613
- if (parent && ts21.isShorthandPropertyAssignment(parent) && parent.name === node) {
23043
+ if (parent && ts22.isShorthandPropertyAssignment(parent) && parent.name === node) {
22614
23044
  if (!isBound(node.text))
22615
23045
  ids.add(node.text);
22616
23046
  return;
22617
23047
  }
22618
- if (parent && ts21.isParameter(parent) && parent.name === node)
23048
+ if (parent && ts22.isParameter(parent) && parent.name === node)
22619
23049
  return;
22620
- if (parent && ts21.isVariableDeclaration(parent) && parent.name === node)
23050
+ if (parent && ts22.isVariableDeclaration(parent) && parent.name === node)
22621
23051
  return;
22622
- if (parent && ts21.isFunctionDeclaration(parent) && parent.name === node)
23052
+ if (parent && ts22.isFunctionDeclaration(parent) && parent.name === node)
22623
23053
  return;
22624
- if (parent && ts21.isClassDeclaration(parent) && parent.name === node)
23054
+ if (parent && ts22.isClassDeclaration(parent) && parent.name === node)
22625
23055
  return;
22626
- if (parent && ts21.isJsxAttribute(parent) && parent.name === node)
23056
+ if (parent && ts22.isJsxAttribute(parent) && parent.name === node)
22627
23057
  return;
22628
- if (parent && ts21.isJsxOpeningElement(parent) && parent.tagName === node) {
23058
+ if (parent && ts22.isJsxOpeningElement(parent) && parent.tagName === node) {
22629
23059
  if (/^[a-z]/.test(node.text))
22630
23060
  return;
22631
23061
  }
22632
- if (parent && ts21.isJsxClosingElement(parent) && parent.tagName === node) {
23062
+ if (parent && ts22.isJsxClosingElement(parent) && parent.tagName === node) {
22633
23063
  if (/^[a-z]/.test(node.text))
22634
23064
  return;
22635
23065
  }
@@ -22638,43 +23068,43 @@ function collectFreeIdentifiers(arrow) {
22638
23068
  ids.add(node.text);
22639
23069
  return;
22640
23070
  }
22641
- if (ts21.isVariableDeclaration(node)) {
23071
+ if (ts22.isVariableDeclaration(node)) {
22642
23072
  const declared = pushBindings(node.name);
22643
23073
  if (node.initializer)
22644
23074
  visit3(node.initializer);
22645
23075
  return;
22646
23076
  }
22647
- if (ts21.isFunctionDeclaration(node)) {
23077
+ if (ts22.isFunctionDeclaration(node)) {
22648
23078
  if (node.name)
22649
23079
  bound.push(node.name.text);
22650
23080
  visitInsideNewScope(node);
22651
23081
  return;
22652
23082
  }
22653
- if (ts21.isClassDeclaration(node)) {
23083
+ if (ts22.isClassDeclaration(node)) {
22654
23084
  if (node.name)
22655
23085
  bound.push(node.name.text);
22656
- ts21.forEachChild(node, visit3);
23086
+ ts22.forEachChild(node, visit3);
22657
23087
  return;
22658
23088
  }
22659
- if (ts21.isArrowFunction(node) || ts21.isFunctionExpression(node)) {
23089
+ if (ts22.isArrowFunction(node) || ts22.isFunctionExpression(node)) {
22660
23090
  visitInsideNewScope(node);
22661
23091
  return;
22662
23092
  }
22663
- if (ts21.isCatchClause(node)) {
23093
+ if (ts22.isCatchClause(node)) {
22664
23094
  const before = bound.length;
22665
23095
  if (node.variableDeclaration)
22666
23096
  pushBindings(node.variableDeclaration.name);
22667
- ts21.forEachChild(node, visit3);
23097
+ ts22.forEachChild(node, visit3);
22668
23098
  popN(bound.length - before);
22669
23099
  return;
22670
23100
  }
22671
- if (ts21.isBlock(node)) {
23101
+ if (ts22.isBlock(node)) {
22672
23102
  const before = bound.length;
22673
- ts21.forEachChild(node, visit3);
23103
+ ts22.forEachChild(node, visit3);
22674
23104
  popN(bound.length - before);
22675
23105
  return;
22676
23106
  }
22677
- ts21.forEachChild(node, visit3);
23107
+ ts22.forEachChild(node, visit3);
22678
23108
  }
22679
23109
  function visitInsideNewScope(fn) {
22680
23110
  const before = bound.length;
@@ -22697,29 +23127,29 @@ function collectFreeIdentifiers(arrow) {
22697
23127
  function collectModuleScopeNames(sourceFile) {
22698
23128
  const names = new Set;
22699
23129
  for (const stmt of sourceFile.statements) {
22700
- if (ts21.isFunctionDeclaration(stmt) && stmt.name)
23130
+ if (ts22.isFunctionDeclaration(stmt) && stmt.name)
22701
23131
  names.add(stmt.name.text);
22702
- else if (ts21.isClassDeclaration(stmt) && stmt.name)
23132
+ else if (ts22.isClassDeclaration(stmt) && stmt.name)
22703
23133
  names.add(stmt.name.text);
22704
- else if (ts21.isVariableStatement(stmt)) {
23134
+ else if (ts22.isVariableStatement(stmt)) {
22705
23135
  for (const decl of stmt.declarationList.declarations)
22706
23136
  collectBindingNames4(decl.name, names);
22707
- } else if (ts21.isImportDeclaration(stmt) && stmt.importClause) {
23137
+ } else if (ts22.isImportDeclaration(stmt) && stmt.importClause) {
22708
23138
  const ic = stmt.importClause;
22709
23139
  if (ic.name)
22710
23140
  names.add(ic.name.text);
22711
23141
  if (ic.namedBindings) {
22712
- if (ts21.isNamespaceImport(ic.namedBindings))
23142
+ if (ts22.isNamespaceImport(ic.namedBindings))
22713
23143
  names.add(ic.namedBindings.name.text);
22714
23144
  else
22715
23145
  for (const e of ic.namedBindings.elements)
22716
23146
  names.add(e.name.text);
22717
23147
  }
22718
- } else if (ts21.isTypeAliasDeclaration(stmt))
23148
+ } else if (ts22.isTypeAliasDeclaration(stmt))
22719
23149
  names.add(stmt.name.text);
22720
- else if (ts21.isInterfaceDeclaration(stmt))
23150
+ else if (ts22.isInterfaceDeclaration(stmt))
22721
23151
  names.add(stmt.name.text);
22722
- else if (ts21.isEnumDeclaration(stmt))
23152
+ else if (ts22.isEnumDeclaration(stmt))
22723
23153
  names.add(stmt.name.text);
22724
23154
  }
22725
23155
  return names;
@@ -22727,7 +23157,7 @@ function collectModuleScopeNames(sourceFile) {
22727
23157
  function buildSyntheticDeclaration(name, arrow, sourceFile) {
22728
23158
  const paramsText = arrow.parameters.length === 0 ? "" : arrow.parameters.map((p) => p.getText(sourceFile)).join(", ");
22729
23159
  let bodyText;
22730
- if (ts21.isBlock(arrow.body)) {
23160
+ if (ts22.isBlock(arrow.body)) {
22731
23161
  bodyText = arrow.body.getText(sourceFile);
22732
23162
  } else {
22733
23163
  const expr = arrow.body.getText(sourceFile);
@@ -22737,7 +23167,7 @@ function buildSyntheticDeclaration(name, arrow, sourceFile) {
22737
23167
  }
22738
23168
 
22739
23169
  // ../jsx/src/ssr-defaults.ts
22740
- import ts22 from "typescript";
23170
+ import ts23 from "typescript";
22741
23171
  var UNRESOLVED = Symbol("unresolved");
22742
23172
  var NO_RETURN = Symbol("no-return");
22743
23173
  function extractSsrDefaults(metadata) {
@@ -22841,11 +23271,11 @@ function collectPropRefs(expr, propsObjectName, out) {
22841
23271
  if (!node)
22842
23272
  return;
22843
23273
  const visit3 = (n) => {
22844
- if (ts22.isPropertyAccessExpression(n) && ts22.isIdentifier(n.expression) && n.expression.text === propsObjectName && ts22.isIdentifier(n.name)) {
23274
+ if (ts23.isPropertyAccessExpression(n) && ts23.isIdentifier(n.expression) && n.expression.text === propsObjectName && ts23.isIdentifier(n.name)) {
22845
23275
  out.add(n.name.text);
22846
23276
  return;
22847
23277
  }
22848
- ts22.forEachChild(n, visit3);
23278
+ ts23.forEachChild(n, visit3);
22849
23279
  };
22850
23280
  visit3(node);
22851
23281
  }
@@ -22883,23 +23313,23 @@ function tryStaticEval(expr, ctx) {
22883
23313
  }
22884
23314
  function evalStatementsForReturn(statements, ctx) {
22885
23315
  for (const stmt of statements) {
22886
- if (ts22.isVariableStatement(stmt)) {
23316
+ if (ts23.isVariableStatement(stmt)) {
22887
23317
  for (const d of stmt.declarationList.declarations) {
22888
- if (!ts22.isIdentifier(d.name) || !d.initializer)
23318
+ if (!ts23.isIdentifier(d.name) || !d.initializer)
22889
23319
  continue;
22890
23320
  const v = evalNode(d.initializer, ctx);
22891
23321
  if (v !== UNRESOLVED)
22892
23322
  ctx.bindings[d.name.text] = v;
22893
23323
  }
22894
- } else if (ts22.isReturnStatement(stmt)) {
23324
+ } else if (ts23.isReturnStatement(stmt)) {
22895
23325
  return stmt.expression ? evalNode(stmt.expression, ctx) : UNRESOLVED;
22896
- } else if (ts22.isIfStatement(stmt)) {
23326
+ } else if (ts23.isIfStatement(stmt)) {
22897
23327
  const cond = evalNode(stmt.expression, ctx);
22898
23328
  if (cond === UNRESOLVED)
22899
23329
  return UNRESOLVED;
22900
23330
  const branch = cond ? stmt.thenStatement : stmt.elseStatement;
22901
23331
  if (branch) {
22902
- const taken = evalStatementsForReturn(ts22.isBlock(branch) ? branch.statements : [branch], ctx);
23332
+ const taken = evalStatementsForReturn(ts23.isBlock(branch) ? branch.statements : [branch], ctx);
22903
23333
  if (taken !== NO_RETURN)
22904
23334
  return taken;
22905
23335
  }
@@ -22910,45 +23340,45 @@ function evalStatementsForReturn(statements, ctx) {
22910
23340
  return NO_RETURN;
22911
23341
  }
22912
23342
  function parseExpression2(expr) {
22913
- const sf = ts22.createSourceFile("__ssr_default__.ts", `(${expr})`, ts22.ScriptTarget.Latest, true, ts22.ScriptKind.TS);
23343
+ const sf = ts23.createSourceFile("__ssr_default__.ts", `(${expr})`, ts23.ScriptTarget.Latest, true, ts23.ScriptKind.TS);
22914
23344
  const stmt = sf.statements[0];
22915
- if (!stmt || !ts22.isExpressionStatement(stmt))
23345
+ if (!stmt || !ts23.isExpressionStatement(stmt))
22916
23346
  return null;
22917
- const inner = ts22.isParenthesizedExpression(stmt.expression) ? stmt.expression.expression : stmt.expression;
23347
+ const inner = ts23.isParenthesizedExpression(stmt.expression) ? stmt.expression.expression : stmt.expression;
22918
23348
  return inner;
22919
23349
  }
22920
23350
  function evalNode(node, ctx) {
22921
- if (ts22.isParenthesizedExpression(node))
23351
+ if (ts23.isParenthesizedExpression(node))
22922
23352
  return evalNode(node.expression, ctx);
22923
- if (ts22.isAsExpression(node))
23353
+ if (ts23.isAsExpression(node))
22924
23354
  return evalNode(node.expression, ctx);
22925
- if (ts22.isSatisfiesExpression(node))
23355
+ if (ts23.isSatisfiesExpression(node))
22926
23356
  return evalNode(node.expression, ctx);
22927
- if (ts22.isTypeAssertionExpression(node))
23357
+ if (ts23.isTypeAssertionExpression(node))
22928
23358
  return evalNode(node.expression, ctx);
22929
- if (ts22.isNonNullExpression(node))
23359
+ if (ts23.isNonNullExpression(node))
22930
23360
  return evalNode(node.expression, ctx);
22931
- if (ts22.isArrowFunction(node)) {
23361
+ if (ts23.isArrowFunction(node)) {
22932
23362
  if (node.parameters.length !== 0)
22933
23363
  return UNRESOLVED;
22934
- if (!ts22.isBlock(node.body))
23364
+ if (!ts23.isBlock(node.body))
22935
23365
  return evalNode(node.body, ctx);
22936
23366
  const localBindings = { ...ctx.bindings };
22937
23367
  const localCtx = { ...ctx, bindings: localBindings };
22938
23368
  const result = evalStatementsForReturn(node.body.statements, localCtx);
22939
23369
  return result === NO_RETURN ? UNRESOLVED : result;
22940
23370
  }
22941
- if (ts22.isNumericLiteral(node))
23371
+ if (ts23.isNumericLiteral(node))
22942
23372
  return Number(node.text);
22943
- if (ts22.isStringLiteralLike(node))
23373
+ if (ts23.isStringLiteralLike(node))
22944
23374
  return node.text;
22945
- if (node.kind === ts22.SyntaxKind.TrueKeyword)
23375
+ if (node.kind === ts23.SyntaxKind.TrueKeyword)
22946
23376
  return true;
22947
- if (node.kind === ts22.SyntaxKind.FalseKeyword)
23377
+ if (node.kind === ts23.SyntaxKind.FalseKeyword)
22948
23378
  return false;
22949
- if (node.kind === ts22.SyntaxKind.NullKeyword)
23379
+ if (node.kind === ts23.SyntaxKind.NullKeyword)
22950
23380
  return null;
22951
- if (ts22.isIdentifier(node)) {
23381
+ if (ts23.isIdentifier(node)) {
22952
23382
  if (node.text === "undefined")
22953
23383
  return;
22954
23384
  if (node.text in ctx.bindings)
@@ -22957,29 +23387,29 @@ function evalNode(node, ctx) {
22957
23387
  return;
22958
23388
  return UNRESOLVED;
22959
23389
  }
22960
- if (ts22.isPrefixUnaryExpression(node)) {
23390
+ if (ts23.isPrefixUnaryExpression(node)) {
22961
23391
  const arg = evalNode(node.operand, ctx);
22962
23392
  if (arg === UNRESOLVED)
22963
23393
  return UNRESOLVED;
22964
23394
  switch (node.operator) {
22965
- case ts22.SyntaxKind.MinusToken:
23395
+ case ts23.SyntaxKind.MinusToken:
22966
23396
  return typeof arg === "number" ? -arg : UNRESOLVED;
22967
- case ts22.SyntaxKind.PlusToken:
23397
+ case ts23.SyntaxKind.PlusToken:
22968
23398
  return typeof arg === "number" ? +arg : UNRESOLVED;
22969
- case ts22.SyntaxKind.ExclamationToken:
23399
+ case ts23.SyntaxKind.ExclamationToken:
22970
23400
  return !arg;
22971
23401
  }
22972
23402
  return UNRESOLVED;
22973
23403
  }
22974
- if (ts22.isObjectLiteralExpression(node)) {
23404
+ if (ts23.isObjectLiteralExpression(node)) {
22975
23405
  const obj = {};
22976
23406
  for (const prop of node.properties) {
22977
- if (!ts22.isPropertyAssignment(prop))
23407
+ if (!ts23.isPropertyAssignment(prop))
22978
23408
  return UNRESOLVED;
22979
23409
  let key;
22980
- if (ts22.isIdentifier(prop.name) || ts22.isStringLiteralLike(prop.name)) {
23410
+ if (ts23.isIdentifier(prop.name) || ts23.isStringLiteralLike(prop.name)) {
22981
23411
  key = prop.name.text;
22982
- } else if (ts22.isNumericLiteral(prop.name)) {
23412
+ } else if (ts23.isNumericLiteral(prop.name)) {
22983
23413
  key = prop.name.text;
22984
23414
  } else {
22985
23415
  return UNRESOLVED;
@@ -22991,10 +23421,10 @@ function evalNode(node, ctx) {
22991
23421
  }
22992
23422
  return obj;
22993
23423
  }
22994
- if (ts22.isArrayLiteralExpression(node)) {
23424
+ if (ts23.isArrayLiteralExpression(node)) {
22995
23425
  const arr = [];
22996
23426
  for (const elem of node.elements) {
22997
- if (ts22.isOmittedExpression(elem))
23427
+ if (ts23.isOmittedExpression(elem))
22998
23428
  return UNRESOLVED;
22999
23429
  const v = evalNode(elem, ctx);
23000
23430
  if (v === UNRESOLVED)
@@ -23003,7 +23433,7 @@ function evalNode(node, ctx) {
23003
23433
  }
23004
23434
  return arr;
23005
23435
  }
23006
- if (ts22.isElementAccessExpression(node)) {
23436
+ if (ts23.isElementAccessExpression(node)) {
23007
23437
  const base = evalNode(node.expression, ctx);
23008
23438
  if (base === undefined)
23009
23439
  return;
@@ -23017,7 +23447,7 @@ function evalNode(node, ctx) {
23017
23447
  const k = String(key);
23018
23448
  return Object.prototype.hasOwnProperty.call(base, k) ? base[k] : undefined;
23019
23449
  }
23020
- if (ts22.isPropertyAccessExpression(node)) {
23450
+ if (ts23.isPropertyAccessExpression(node)) {
23021
23451
  const baseResult = evalNode(node.expression, ctx);
23022
23452
  if (baseResult === undefined)
23023
23453
  return;
@@ -23030,13 +23460,13 @@ function evalNode(node, ctx) {
23030
23460
  const key = node.name.text;
23031
23461
  return Object.prototype.hasOwnProperty.call(baseResult, key) ? baseResult[key] : undefined;
23032
23462
  }
23033
- if (ts22.isCallExpression(node)) {
23034
- if (node.arguments.length === 0 && ts22.isIdentifier(node.expression) && node.expression.text in ctx.bindings) {
23463
+ if (ts23.isCallExpression(node)) {
23464
+ if (node.arguments.length === 0 && ts23.isIdentifier(node.expression) && node.expression.text in ctx.bindings) {
23035
23465
  return ctx.bindings[node.expression.text];
23036
23466
  }
23037
- if (ts22.isPropertyAccessExpression(node.expression) && node.expression.name.text === "map" && node.arguments.length === 1) {
23467
+ if (ts23.isPropertyAccessExpression(node.expression) && node.expression.name.text === "map" && node.arguments.length === 1) {
23038
23468
  const arrow = node.arguments[0];
23039
- if (ts22.isArrowFunction(arrow) && arrow.parameters.length === 1 && ts22.isIdentifier(arrow.parameters[0].name) && !ts22.isBlock(arrow.body)) {
23469
+ if (ts23.isArrowFunction(arrow) && arrow.parameters.length === 1 && ts23.isIdentifier(arrow.parameters[0].name) && !ts23.isBlock(arrow.body)) {
23040
23470
  const recv = evalNode(node.expression.expression, ctx);
23041
23471
  if (Array.isArray(recv)) {
23042
23472
  const paramName = arrow.parameters[0].name.text;
@@ -23053,7 +23483,7 @@ function evalNode(node, ctx) {
23053
23483
  }
23054
23484
  return UNRESOLVED;
23055
23485
  }
23056
- if (ts22.isPropertyAccessExpression(node.expression) && node.expression.name.text === "join") {
23486
+ if (ts23.isPropertyAccessExpression(node.expression) && node.expression.name.text === "join") {
23057
23487
  const recv = evalNode(node.expression.expression, ctx);
23058
23488
  if (Array.isArray(recv)) {
23059
23489
  let sep = ",";
@@ -23069,27 +23499,27 @@ function evalNode(node, ctx) {
23069
23499
  }
23070
23500
  return UNRESOLVED;
23071
23501
  }
23072
- if (ts22.isConditionalExpression(node)) {
23502
+ if (ts23.isConditionalExpression(node)) {
23073
23503
  const cond = evalNode(node.condition, ctx);
23074
23504
  if (cond === UNRESOLVED)
23075
23505
  return UNRESOLVED;
23076
23506
  return cond ? evalNode(node.whenTrue, ctx) : evalNode(node.whenFalse, ctx);
23077
23507
  }
23078
- if (ts22.isBinaryExpression(node)) {
23508
+ if (ts23.isBinaryExpression(node)) {
23079
23509
  const op = node.operatorToken.kind;
23080
- if (op === ts22.SyntaxKind.QuestionQuestionToken) {
23510
+ if (op === ts23.SyntaxKind.QuestionQuestionToken) {
23081
23511
  const l2 = evalNode(node.left, ctx);
23082
23512
  if (l2 !== UNRESOLVED && l2 !== null && l2 !== undefined)
23083
23513
  return l2;
23084
23514
  return evalNode(node.right, ctx);
23085
23515
  }
23086
- if (op === ts22.SyntaxKind.BarBarToken) {
23516
+ if (op === ts23.SyntaxKind.BarBarToken) {
23087
23517
  const l2 = evalNode(node.left, ctx);
23088
23518
  if (l2 !== UNRESOLVED && l2)
23089
23519
  return l2;
23090
23520
  return evalNode(node.right, ctx);
23091
23521
  }
23092
- if (op === ts22.SyntaxKind.AmpersandAmpersandToken) {
23522
+ if (op === ts23.SyntaxKind.AmpersandAmpersandToken) {
23093
23523
  const l2 = evalNode(node.left, ctx);
23094
23524
  if (l2 === UNRESOLVED)
23095
23525
  return UNRESOLVED;
@@ -23102,30 +23532,30 @@ function evalNode(node, ctx) {
23102
23532
  if (l === UNRESOLVED || r === UNRESOLVED)
23103
23533
  return UNRESOLVED;
23104
23534
  switch (op) {
23105
- case ts22.SyntaxKind.PlusToken:
23535
+ case ts23.SyntaxKind.PlusToken:
23106
23536
  if (typeof l === "string" || typeof r === "string")
23107
23537
  return `${l}${r}`;
23108
23538
  if (typeof l === "number" && typeof r === "number")
23109
23539
  return l + r;
23110
23540
  return UNRESOLVED;
23111
- case ts22.SyntaxKind.MinusToken:
23541
+ case ts23.SyntaxKind.MinusToken:
23112
23542
  return typeof l === "number" && typeof r === "number" ? l - r : UNRESOLVED;
23113
- case ts22.SyntaxKind.AsteriskToken:
23543
+ case ts23.SyntaxKind.AsteriskToken:
23114
23544
  return typeof l === "number" && typeof r === "number" ? l * r : UNRESOLVED;
23115
- case ts22.SyntaxKind.SlashToken:
23545
+ case ts23.SyntaxKind.SlashToken:
23116
23546
  return typeof l === "number" && typeof r === "number" && r !== 0 ? l / r : UNRESOLVED;
23117
- case ts22.SyntaxKind.PercentToken:
23547
+ case ts23.SyntaxKind.PercentToken:
23118
23548
  return typeof l === "number" && typeof r === "number" && r !== 0 ? l % r : UNRESOLVED;
23119
- case ts22.SyntaxKind.EqualsEqualsEqualsToken:
23120
- case ts22.SyntaxKind.EqualsEqualsToken:
23549
+ case ts23.SyntaxKind.EqualsEqualsEqualsToken:
23550
+ case ts23.SyntaxKind.EqualsEqualsToken:
23121
23551
  return l === r;
23122
- case ts22.SyntaxKind.ExclamationEqualsEqualsToken:
23123
- case ts22.SyntaxKind.ExclamationEqualsToken:
23552
+ case ts23.SyntaxKind.ExclamationEqualsEqualsToken:
23553
+ case ts23.SyntaxKind.ExclamationEqualsToken:
23124
23554
  return l !== r;
23125
23555
  }
23126
23556
  return UNRESOLVED;
23127
23557
  }
23128
- if (ts22.isTemplateExpression(node)) {
23558
+ if (ts23.isTemplateExpression(node)) {
23129
23559
  if (node.templateSpans.length === 0)
23130
23560
  return node.head.text;
23131
23561
  let acc = node.head.text;
@@ -23137,41 +23567,41 @@ function evalNode(node, ctx) {
23137
23567
  }
23138
23568
  return acc;
23139
23569
  }
23140
- if (ts22.isNoSubstitutionTemplateLiteral(node))
23570
+ if (ts23.isNoSubstitutionTemplateLiteral(node))
23141
23571
  return node.text;
23142
23572
  return UNRESOLVED;
23143
23573
  }
23144
23574
 
23145
23575
  // ../jsx/src/augment-inherited-props.ts
23146
- import ts23 from "typescript";
23576
+ import ts24 from "typescript";
23147
23577
  function parseStaticStringConst(source) {
23148
- const sf = ts23.createSourceFile("__const.ts", `const __x = (${source});`, ts23.ScriptTarget.Latest, false);
23578
+ const sf = ts24.createSourceFile("__const.ts", `const __x = (${source});`, ts24.ScriptTarget.Latest, false);
23149
23579
  const stmt = sf.statements[0];
23150
- if (!stmt || !ts23.isVariableStatement(stmt))
23580
+ if (!stmt || !ts24.isVariableStatement(stmt))
23151
23581
  return null;
23152
23582
  let init = stmt.declarationList.declarations[0]?.initializer;
23153
- while (init && ts23.isParenthesizedExpression(init))
23583
+ while (init && ts24.isParenthesizedExpression(init))
23154
23584
  init = init.expression;
23155
23585
  if (!init)
23156
23586
  return null;
23157
- if (ts23.isStringLiteral(init) || ts23.isNoSubstitutionTemplateLiteral(init)) {
23587
+ if (ts24.isStringLiteral(init) || ts24.isNoSubstitutionTemplateLiteral(init)) {
23158
23588
  return init.text;
23159
23589
  }
23160
23590
  return evalStringArrayJoin(source);
23161
23591
  }
23162
23592
  function evalTemplateOfStringConsts(source, resolved) {
23163
- const sf = ts23.createSourceFile("__const.ts", `const __x = (${source});`, ts23.ScriptTarget.Latest, false);
23593
+ const sf = ts24.createSourceFile("__const.ts", `const __x = (${source});`, ts24.ScriptTarget.Latest, false);
23164
23594
  const stmt = sf.statements[0];
23165
- if (!stmt || !ts23.isVariableStatement(stmt))
23595
+ if (!stmt || !ts24.isVariableStatement(stmt))
23166
23596
  return null;
23167
23597
  let init = stmt.declarationList.declarations[0]?.initializer;
23168
- while (init && ts23.isParenthesizedExpression(init))
23598
+ while (init && ts24.isParenthesizedExpression(init))
23169
23599
  init = init.expression;
23170
- if (!init || !ts23.isTemplateExpression(init))
23600
+ if (!init || !ts24.isTemplateExpression(init))
23171
23601
  return null;
23172
23602
  let out = init.head.text;
23173
23603
  for (const span of init.templateSpans) {
23174
- if (!ts23.isIdentifier(span.expression))
23604
+ if (!ts24.isIdentifier(span.expression))
23175
23605
  return null;
23176
23606
  const value = resolved.get(span.expression.text);
23177
23607
  if (value === undefined)
@@ -23199,28 +23629,28 @@ function collectModuleStringConsts(constants) {
23199
23629
  return map;
23200
23630
  }
23201
23631
  function evalStringArrayJoin(source) {
23202
- const sf = ts23.createSourceFile("__join.ts", `const __x = (${source});`, ts23.ScriptTarget.Latest, false);
23632
+ const sf = ts24.createSourceFile("__join.ts", `const __x = (${source});`, ts24.ScriptTarget.Latest, false);
23203
23633
  const stmt = sf.statements[0];
23204
- if (!stmt || !ts23.isVariableStatement(stmt))
23634
+ if (!stmt || !ts24.isVariableStatement(stmt))
23205
23635
  return null;
23206
23636
  let node = stmt.declarationList.declarations[0]?.initializer;
23207
- while (node && ts23.isParenthesizedExpression(node))
23637
+ while (node && ts24.isParenthesizedExpression(node))
23208
23638
  node = node.expression;
23209
- if (!node || !ts23.isCallExpression(node))
23639
+ if (!node || !ts24.isCallExpression(node))
23210
23640
  return null;
23211
23641
  const callee = node.expression;
23212
- if (!ts23.isPropertyAccessExpression(callee))
23642
+ if (!ts24.isPropertyAccessExpression(callee))
23213
23643
  return null;
23214
23644
  if (callee.name.text !== "join")
23215
23645
  return null;
23216
23646
  let recv = callee.expression;
23217
- while (ts23.isParenthesizedExpression(recv))
23647
+ while (ts24.isParenthesizedExpression(recv))
23218
23648
  recv = recv.expression;
23219
- if (!ts23.isArrayLiteralExpression(recv))
23649
+ if (!ts24.isArrayLiteralExpression(recv))
23220
23650
  return null;
23221
23651
  const parts = [];
23222
23652
  for (const el of recv.elements) {
23223
- if (ts23.isStringLiteral(el) || ts23.isNoSubstitutionTemplateLiteral(el)) {
23653
+ if (ts24.isStringLiteral(el) || ts24.isNoSubstitutionTemplateLiteral(el)) {
23224
23654
  parts.push(el.text);
23225
23655
  } else {
23226
23656
  return null;
@@ -23229,7 +23659,7 @@ function evalStringArrayJoin(source) {
23229
23659
  let sep = ",";
23230
23660
  if (node.arguments.length >= 1) {
23231
23661
  const arg = node.arguments[0];
23232
- if (ts23.isStringLiteral(arg) || ts23.isNoSubstitutionTemplateLiteral(arg))
23662
+ if (ts24.isStringLiteral(arg) || ts24.isNoSubstitutionTemplateLiteral(arg))
23233
23663
  sep = arg.text;
23234
23664
  else
23235
23665
  return null;
@@ -23589,31 +24019,54 @@ function walkNode2(node, meta, bindings, matchers, errors, seen) {
23589
24019
  function mergeTemplateImports(lines) {
23590
24020
  const result = [];
23591
24021
  const valueIdx = new Map;
24022
+ const valueDefault = new Map;
23592
24023
  const valueNames = new Map;
23593
24024
  const typeIdx = new Map;
23594
24025
  const typeNames = new Map;
23595
24026
  const seenOther = new Set;
23596
- const fold = (src, rawNames, idx, names, render) => {
23597
- if (!idx.has(src)) {
23598
- idx.set(src, result.length);
23599
- names.set(src, new Set);
24027
+ const foldType = (src, rawNames) => {
24028
+ if (!typeIdx.has(src)) {
24029
+ typeIdx.set(src, result.length);
24030
+ typeNames.set(src, new Set);
23600
24031
  result.push("");
23601
24032
  }
23602
- const set = names.get(src);
24033
+ const set = typeNames.get(src);
23603
24034
  for (const n of rawNames.split(",").map((s) => s.trim()).filter(Boolean))
23604
24035
  set.add(n);
23605
- result[idx.get(src)] = render(src, set);
24036
+ result[typeIdx.get(src)] = `import type { ${[...set].join(", ")} } from '${src}'`;
24037
+ };
24038
+ const foldValue = (src, defaultName, rawNames) => {
24039
+ if (!valueIdx.has(src)) {
24040
+ valueIdx.set(src, result.length);
24041
+ valueNames.set(src, new Set);
24042
+ result.push("");
24043
+ }
24044
+ if (defaultName && !valueDefault.has(src))
24045
+ valueDefault.set(src, defaultName);
24046
+ if (rawNames) {
24047
+ const set = valueNames.get(src);
24048
+ for (const n of rawNames.split(",").map((s) => s.trim()).filter(Boolean))
24049
+ set.add(n);
24050
+ }
24051
+ result[valueIdx.get(src)] = renderUsedImportLines(src, valueDefault.get(src) ?? null, null, [...valueNames.get(src)]).join(`
24052
+ `);
23606
24053
  };
23607
24054
  for (const raw of lines) {
23608
24055
  const line = raw.trim();
23609
24056
  if (!line)
23610
24057
  continue;
23611
24058
  const typeMatch = line.match(/^import\s+type\s*\{([^}]+)\}\s*from\s*['"]([^'"]+)['"]\s*;?$/);
23612
- const valueMatch = line.match(/^import\s*\{([^}]+)\}\s*from\s*['"]([^'"]+)['"]\s*;?$/);
23613
- if (valueMatch) {
23614
- fold(valueMatch[2], valueMatch[1], valueIdx, valueNames, (s, n) => `import { ${[...n].join(", ")} } from '${s}'`);
23615
- } else if (typeMatch) {
23616
- fold(typeMatch[2], typeMatch[1], typeIdx, typeNames, (s, n) => `import type { ${[...n].join(", ")} } from '${s}'`);
24059
+ const namedMatch = line.match(/^import\s*\{([^}]+)\}\s*from\s*['"]([^'"]+)['"]\s*;?$/);
24060
+ const defaultNamedMatch = line.match(/^import\s+([A-Za-z_$][\w$]*)\s*,\s*\{([^}]+)\}\s*from\s*['"]([^'"]+)['"]\s*;?$/);
24061
+ const defaultOnlyMatch = line.match(/^import\s+([A-Za-z_$][\w$]*)\s*from\s*['"]([^'"]+)['"]\s*;?$/);
24062
+ if (typeMatch) {
24063
+ foldType(typeMatch[2], typeMatch[1]);
24064
+ } else if (namedMatch) {
24065
+ foldValue(namedMatch[2], null, namedMatch[1]);
24066
+ } else if (defaultNamedMatch) {
24067
+ foldValue(defaultNamedMatch[3], defaultNamedMatch[1], defaultNamedMatch[2]);
24068
+ } else if (defaultOnlyMatch) {
24069
+ foldValue(defaultOnlyMatch[2], defaultOnlyMatch[1], null);
23617
24070
  } else if (!seenOther.has(line)) {
23618
24071
  seenOther.add(line);
23619
24072
  result.push(line);
@@ -23655,13 +24108,13 @@ function compileMultipleComponents(source, filePath, componentNames, options) {
23655
24108
  if (entries.some((e) => e.componentIR.metadata.isClientComponent)) {
23656
24109
  const topLevelNames = new Set;
23657
24110
  {
23658
- const sf = ts24.createSourceFile(filePath, source, ts24.ScriptTarget.Latest, true, ts24.ScriptKind.TSX);
24111
+ const sf = ts25.createSourceFile(filePath, source, ts25.ScriptTarget.Latest, true, ts25.ScriptKind.TSX);
23659
24112
  for (const stmt of sf.statements) {
23660
- if (ts24.isFunctionDeclaration(stmt) && stmt.name)
24113
+ if (ts25.isFunctionDeclaration(stmt) && stmt.name)
23661
24114
  topLevelNames.add(stmt.name.text);
23662
- else if (ts24.isVariableStatement(stmt)) {
24115
+ else if (ts25.isVariableStatement(stmt)) {
23663
24116
  for (const d of stmt.declarationList.declarations) {
23664
- if (ts24.isIdentifier(d.name))
24117
+ if (ts25.isIdentifier(d.name))
23665
24118
  topLevelNames.add(d.name.text);
23666
24119
  }
23667
24120
  }
@@ -23720,7 +24173,7 @@ function compileMultipleComponents(source, filePath, componentNames, options) {
23720
24173
  const moduleStatementSeen = new Set;
23721
24174
  const moduleStatementsOrdered = [];
23722
24175
  const collectModuleStatements = (block) => {
23723
- const sf = ts24.createSourceFile("__bf_module_decls.tsx", block, ts24.ScriptTarget.Latest, false, ts24.ScriptKind.TSX);
24176
+ const sf = ts25.createSourceFile("__bf_module_decls.tsx", block, ts25.ScriptTarget.Latest, false, ts25.ScriptKind.TSX);
23724
24177
  for (const stmt of sf.statements) {
23725
24178
  const text = stmt.getText(sf);
23726
24179
  if (moduleStatementSeen.has(text))
@@ -23809,32 +24262,9 @@ function compileMultipleComponents(source, filePath, componentNames, options) {
23809
24262
  }
23810
24263
  const clientJsOutputs2 = allOutputs.map((o) => o.clientJs).filter(Boolean);
23811
24264
  if (clientJsOutputs2.length > 0) {
23812
- const importsBySource = new Map;
23813
- const otherImports = [];
23814
- const allCode = [];
23815
- for (const js of clientJsOutputs2) {
23816
- for (const line of js.split(`
23817
- `)) {
23818
- if (line.startsWith("import ")) {
23819
- const match = line.match(/^import \{ ([^}]+) \} from ['"]([^'"]+)['"]$/);
23820
- if (match) {
23821
- const source2 = match[2];
23822
- if (!importsBySource.has(source2))
23823
- importsBySource.set(source2, new Set);
23824
- for (const n of match[1].split(",").map((n2) => n2.trim()))
23825
- importsBySource.get(source2).add(n);
23826
- } else if (!otherImports.includes(line)) {
23827
- otherImports.push(line);
23828
- }
23829
- }
23830
- }
23831
- allCode.push(js.replace(/^import .+\n/gm, "").trim());
23832
- }
23833
- const mergedClientImports = [...importsBySource].map(([src, names]) => `import { ${[...names].sort().join(", ")} } from '${src}'`);
23834
24265
  files.push({
23835
24266
  path: filePath.replace(/\.tsx?$/, ".client.js"),
23836
- content: [...mergedClientImports, ...otherImports, "", ...allCode.filter(Boolean)].join(`
23837
- `),
24267
+ content: mergeCompiledClientJsImports(clientJsOutputs2),
23838
24268
  type: "clientJs"
23839
24269
  });
23840
24270
  }
@@ -23905,53 +24335,9 @@ function compileMultipleComponents(source, filePath, componentNames, options) {
23905
24335
  }
23906
24336
  const clientJsOutputs = allOutputs.map((o) => o.clientJs).filter(Boolean);
23907
24337
  if (clientJsOutputs.length > 0) {
23908
- const importsBySource = new Map;
23909
- const otherImports = [];
23910
- const allCode = [];
23911
- for (const js of clientJsOutputs) {
23912
- const lines = js.split(`
23913
- `);
23914
- const codeLines = [];
23915
- for (const line of lines) {
23916
- if (line.startsWith("import ")) {
23917
- const match = line.match(/^import \{ ([^}]+) \} from ['"]([^'"]+)['"]$/);
23918
- if (match) {
23919
- const names = match[1].split(",").map((n) => n.trim());
23920
- const source2 = match[2];
23921
- if (!importsBySource.has(source2)) {
23922
- importsBySource.set(source2, new Set);
23923
- }
23924
- const set = importsBySource.get(source2);
23925
- for (const name of names) {
23926
- set.add(name);
23927
- }
23928
- } else {
23929
- if (!otherImports.includes(line)) {
23930
- otherImports.push(line);
23931
- }
23932
- }
23933
- } else {
23934
- codeLines.push(line);
23935
- }
23936
- }
23937
- allCode.push(codeLines.join(`
23938
- `).trim());
23939
- }
23940
- const mergedImports2 = [];
23941
- for (const [source2, names] of importsBySource) {
23942
- const sortedNames = [...names].sort();
23943
- mergedImports2.push(`import { ${sortedNames.join(", ")} } from '${source2}'`);
23944
- }
23945
- const combinedClientJs = [
23946
- ...mergedImports2,
23947
- ...otherImports,
23948
- "",
23949
- ...allCode.filter(Boolean)
23950
- ].join(`
23951
- `);
23952
24338
  files.push({
23953
24339
  path: filePath.replace(/\.tsx?$/, ".client.js"),
23954
- content: combinedClientJs,
24340
+ content: mergeCompiledClientJsImports(clientJsOutputs),
23955
24341
  type: "clientJs"
23956
24342
  });
23957
24343
  }
@@ -24024,10 +24410,24 @@ function compileJSX(source, filePath, options) {
24024
24410
  externalImportLines.push(`import '${imp.source}'`);
24025
24411
  continue;
24026
24412
  }
24027
- const used = imp.specifiers.filter((s2) => !s2.isDefault && !s2.isNamespace && !s2.isTypeOnly && isUsedAsValue(s2.alias || s2.name)).map((s2) => s2.alias ? `${s2.name} as ${s2.alias}` : s2.name);
24028
- if (used.length > 0) {
24029
- externalImportLines.push(`import { ${used.join(", ")} } from '${imp.source}'`);
24413
+ const usedNamed = [];
24414
+ let usedDefault = null;
24415
+ let usedNamespace = null;
24416
+ for (const s2 of imp.specifiers) {
24417
+ if (s2.isTypeOnly)
24418
+ continue;
24419
+ const localName = s2.alias || s2.name;
24420
+ if (!isUsedAsValue(localName))
24421
+ continue;
24422
+ if (s2.isDefault) {
24423
+ usedDefault = localName;
24424
+ } else if (s2.isNamespace) {
24425
+ usedNamespace = localName;
24426
+ } else {
24427
+ usedNamed.push(s2.alias ? `${s2.name} as ${s2.alias}` : s2.name);
24428
+ }
24030
24429
  }
24430
+ externalImportLines.push(...renderUsedImportLines(imp.source, usedDefault, usedNamespace, usedNamed));
24031
24431
  }
24032
24432
  const allImports = [runtimeImportLine, ...externalImportLines].filter(Boolean).join(`
24033
24433
  `);
@@ -24163,7 +24563,7 @@ function compileJSX(source, filePath, options) {
24163
24563
  return { files, errors };
24164
24564
  }
24165
24565
  // ../jsx/src/shared-program.ts
24166
- import ts25 from "typescript";
24566
+ import ts26 from "typescript";
24167
24567
  import path3 from "node:path";
24168
24568
  function commonParent(paths) {
24169
24569
  if (paths.length === 0)
@@ -24185,10 +24585,10 @@ function commonParent(paths) {
24185
24585
  function createProgramForCorpus(files, options = {}) {
24186
24586
  const baseUrl = options.baseUrl ?? commonParent(files);
24187
24587
  const compilerOptions = {
24188
- target: ts25.ScriptTarget.Latest,
24189
- module: ts25.ModuleKind.ESNext,
24190
- moduleResolution: ts25.ModuleResolutionKind.Bundler,
24191
- jsx: ts25.JsxEmit.ReactJSX,
24588
+ target: ts26.ScriptTarget.Latest,
24589
+ module: ts26.ModuleKind.ESNext,
24590
+ moduleResolution: ts26.ModuleResolutionKind.Bundler,
24591
+ jsx: ts26.JsxEmit.ReactJSX,
24192
24592
  strict: true,
24193
24593
  skipLibCheck: true,
24194
24594
  noEmit: true,
@@ -24198,7 +24598,7 @@ function createProgramForCorpus(files, options = {}) {
24198
24598
  ...options.compilerOptions
24199
24599
  };
24200
24600
  const absolute = files.map((f) => path3.resolve(f));
24201
- return ts25.createProgram(absolute, compilerOptions, undefined, options.oldProgram);
24601
+ return ts26.createProgram(absolute, compilerOptions, undefined, options.oldProgram);
24202
24602
  }
24203
24603
  // ../jsx/src/adapters/interface.ts
24204
24604
  class BaseAdapter {
@@ -24481,7 +24881,7 @@ class JsxAdapter extends BaseAdapter {
24481
24881
  }
24482
24882
 
24483
24883
  // ../jsx/src/adapters/template-imports.ts
24484
- import ts26 from "typescript";
24884
+ import ts27 from "typescript";
24485
24885
  var CLIENT_PACKAGE_SOURCES = new Set([
24486
24886
  "@barefootjs/client",
24487
24887
  "@barefootjs/client/runtime"
@@ -24874,11 +25274,11 @@ function registerBuiltinLoweringPlugins() {
24874
25274
  registerLoweringPlugin(plugin);
24875
25275
  }
24876
25276
  // ../jsx/src/combine-client-js.ts
24877
- import ts27 from "typescript";
24878
- // ../jsx/src/debug.ts
24879
25277
  import ts28 from "typescript";
24880
- // ../jsx/src/profiler.ts
25278
+ // ../jsx/src/debug.ts
24881
25279
  import ts29 from "typescript";
25280
+ // ../jsx/src/profiler.ts
25281
+ import ts30 from "typescript";
24882
25282
 
24883
25283
  // ../jsx/src/index.ts
24884
25284
  registerBuiltinLoweringPlugins();
@@ -25017,21 +25417,24 @@ async function discoverComponents(entries, readFile) {
25017
25417
  seen.add(absPath);
25018
25418
  const content = await readFile(absPath);
25019
25419
  const isClient = hasUseClientDirective(content);
25420
+ const scan = scanComponentFile(content, absPath);
25020
25421
  out.push({
25021
25422
  absPath,
25022
25423
  content,
25023
25424
  isClient,
25024
- exportedComponents: isClient ? listComponentFunctions(content, absPath) : [],
25425
+ exportedComponents: scan.exports,
25426
+ referencedComponents: scan.referencedComponents,
25025
25427
  cssLayerPrefix: entry.cssLayerPrefix
25026
25428
  });
25027
25429
  }
25028
25430
  }
25029
- return out;
25431
+ const clientEntryPaths = computeClientEntryPaths(out);
25432
+ return out.map((row) => ({ ...row, needsClientEntry: clientEntryPaths.has(row.absPath) }));
25030
25433
  }
25031
- function buildChildNameIndex(discovered) {
25434
+ function nameIndexOver(rows, include) {
25032
25435
  const index = new Map;
25033
- for (const c of discovered) {
25034
- if (!c.isClient)
25436
+ for (const c of rows) {
25437
+ if (!include(c))
25035
25438
  continue;
25036
25439
  const names = c.exportedComponents.length > 0 ? c.exportedComponents : [basename(c.absPath).replace(/\.tsx?$/, "")];
25037
25440
  for (const name of names) {
@@ -25041,6 +25444,44 @@ function buildChildNameIndex(discovered) {
25041
25444
  }
25042
25445
  return index;
25043
25446
  }
25447
+ function computeClientEntryPaths(rows) {
25448
+ const nameToPath = nameIndexOver(rows, () => true);
25449
+ const referencers = new Map;
25450
+ for (const row of rows) {
25451
+ for (const name of row.referencedComponents) {
25452
+ const target = nameToPath.get(name);
25453
+ if (!target || target === row.absPath)
25454
+ continue;
25455
+ let set = referencers.get(target);
25456
+ if (!set) {
25457
+ set = new Set;
25458
+ referencers.set(target, set);
25459
+ }
25460
+ set.add(row.absPath);
25461
+ }
25462
+ }
25463
+ const visited = new Set;
25464
+ const queue = [];
25465
+ for (const row of rows) {
25466
+ if (row.isClient && !visited.has(row.absPath)) {
25467
+ visited.add(row.absPath);
25468
+ queue.push(row.absPath);
25469
+ }
25470
+ }
25471
+ while (queue.length > 0) {
25472
+ const current = queue.shift();
25473
+ for (const referencer of referencers.get(current) ?? []) {
25474
+ if (visited.has(referencer))
25475
+ continue;
25476
+ visited.add(referencer);
25477
+ queue.push(referencer);
25478
+ }
25479
+ }
25480
+ return visited;
25481
+ }
25482
+ function buildChildNameIndex(discovered) {
25483
+ return nameIndexOver(discovered, (c) => c.needsClientEntry);
25484
+ }
25044
25485
 
25045
25486
  // src/resolve-client-js.ts
25046
25487
  import { existsSync } from "node:fs";
@@ -25375,7 +25816,7 @@ function barefoot(options) {
25375
25816
  const canonical = compileCanonical(component.absPath, content);
25376
25817
  reportErrors(canonical, content, projectDir);
25377
25818
  let result = canonical;
25378
- if (component.isClient) {
25819
+ if (component.needsClientEntry) {
25379
25820
  const { scriptAssets, preloadAssets } = resolveAssetsFor(component);
25380
25821
  if (scriptAssets.length > 0) {
25381
25822
  result = compileJSX(content, component.absPath, {
@@ -25461,7 +25902,7 @@ function barefoot(options) {
25461
25902
  const found = await discoverComponents(guessedEntries, (absPath) => readFile2(absPath, "utf8"));
25462
25903
  const input = {};
25463
25904
  for (const c of found) {
25464
- if (!c.isClient)
25905
+ if (!c.needsClientEntry)
25465
25906
  continue;
25466
25907
  input[safeRollupEntryName(guessedRoot, c.absPath, dirs)] = c.absPath;
25467
25908
  }