@barefootjs/hono 0.33.4 → 0.34.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"conformance-pins.d.ts","sourceRoot":"","sources":["../src/conformance-pins.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEtD,eAAO,MAAM,eAAe,EAAE,eAU7B,CAAA"}
1
+ {"version":3,"file":"conformance-pins.d.ts","sourceRoot":"","sources":["../src/conformance-pins.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEtD,eAAO,MAAM,eAAe,EAAE,eAiB7B,CAAA"}
package/dist/index.js CHANGED
@@ -667,7 +667,8 @@ var conformancePins = {
667
667
  "date-method-uncatalogued": [{ code: "BF021", severity: "error", issue: "https://github.com/piconic-ai/barefootjs/issues/2356" }],
668
668
  "rich-prop-client-read": [{ code: "BF049", severity: "error", issue: "https://github.com/piconic-ai/barefootjs/issues/2648" }],
669
669
  "jsx-element-prop-ternary": [{ code: "BF021", severity: "error", issue: "https://github.com/piconic-ai/barefootjs/issues/2667" }],
670
- "jsx-element-prop-array": [{ code: "BF021", severity: "error", issue: "https://github.com/piconic-ai/barefootjs/issues/2667" }]
670
+ "jsx-element-prop-array": [{ code: "BF021", severity: "error", issue: "https://github.com/piconic-ai/barefootjs/issues/2667" }],
671
+ "namespace-import-primitive": [{ code: "BF013", severity: "error", issue: "https://github.com/piconic-ai/barefootjs/issues/2771" }]
671
672
  };
672
673
  export {
673
674
  honoAdapter,
@@ -1 +1 @@
1
- {"version":3,"file":"test-render.d.ts","sourceRoot":"","sources":["../src/test-render.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAStD,MAAM,WAAW,aAAa;IAC5B,sBAAsB;IACtB,MAAM,EAAE,MAAM,CAAA;IACd,8BAA8B;IAC9B,OAAO,EAAE,eAAe,CAAA;IACxB,iCAAiC;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC/B,qDAAqD;IACrD,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACnC;;;;;;;;OAQG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACzC;;;;;;;OAOG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AA2BD,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAsLjF"}
1
+ {"version":3,"file":"test-render.d.ts","sourceRoot":"","sources":["../src/test-render.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAStD,MAAM,WAAW,aAAa;IAC5B,sBAAsB;IACtB,MAAM,EAAE,MAAM,CAAA;IACd,8BAA8B;IAC9B,OAAO,EAAE,eAAe,CAAA;IACxB,iCAAiC;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC/B,qDAAqD;IACrD,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACnC;;;;;;;;OAQG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACzC;;;;;;;OAOG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAkDD,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAqMjF"}
package/dist/vite.js CHANGED
@@ -8,10 +8,22 @@ import { devModuleUrl, loadManifest, resolveDevOrigin, resolveScriptAssets, toPo
8
8
  import ts25 from "typescript";
9
9
 
10
10
  // ../jsx/src/analyzer.ts
11
- import ts9 from "typescript";
11
+ import ts10 from "typescript";
12
12
 
13
13
  // ../jsx/src/expression-parser.ts
14
14
  import ts from "typescript";
15
+
16
+ // ../jsx/src/lowering-registry.ts
17
+ var plugins = [];
18
+ function registerLoweringPlugin(plugin) {
19
+ const existing = plugins.findIndex((p) => p.name === plugin.name);
20
+ if (existing >= 0)
21
+ plugins[existing] = plugin;
22
+ else
23
+ plugins.push(plugin);
24
+ }
25
+
26
+ // ../jsx/src/expression-parser.ts
15
27
  var UNSUPPORTED_METHODS = new Set([
16
28
  "filter",
17
29
  "map",
@@ -84,7 +96,7 @@ var EVAL_MATH_METHODS = new Set([
84
96
  ]);
85
97
 
86
98
  // ../jsx/src/prop-rewrite.ts
87
- import ts5 from "typescript";
99
+ import ts7 from "typescript";
88
100
 
89
101
  // ../jsx/src/ir-to-client-js/utils.ts
90
102
  import ts3 from "typescript";
@@ -242,18 +254,45 @@ function escapeHtml(text) {
242
254
  return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
243
255
  }
244
256
  // ../jsx/src/ir-to-client-js/csr-substitute.ts
257
+ import ts5 from "typescript";
258
+
259
+ // ../jsx/src/props-binding.ts
245
260
  import ts4 from "typescript";
261
+ function isIdentifierName(key) {
262
+ if (key.length === 0)
263
+ return false;
264
+ for (let i = 0;i < key.length; ) {
265
+ const cp = key.codePointAt(i);
266
+ const ok = i === 0 ? ts4.isIdentifierStart(cp, ts4.ScriptTarget.Latest) : ts4.isIdentifierPart(cp, ts4.ScriptTarget.Latest);
267
+ if (!ok)
268
+ return false;
269
+ i += cp > 65535 ? 2 : 1;
270
+ }
271
+ return true;
272
+ }
273
+ function propsDestructureBinding(p) {
274
+ const callerKey = p.sourceName ?? p.name;
275
+ const localName = p.name;
276
+ const binding = callerKey === localName ? localName : `${isIdentifierName(callerKey) ? callerKey : JSON.stringify(callerKey)}: ${localName}`;
277
+ return p.defaultValue ? `${binding} = ${p.defaultValue}` : binding;
278
+ }
279
+ var EMPTY_SET = new Set;
280
+
281
+ // ../jsx/src/ir-to-client-js/csr-substitute.ts
246
282
  function extractFreeIdentifiersFromText(text) {
247
283
  if (!text || text.trim().length === 0)
248
284
  return new Set;
249
- const sf = ts4.createSourceFile("__free_ids__.ts", `(${text});`, ts4.ScriptTarget.Latest, true, ts4.ScriptKind.TS);
285
+ const sf = ts5.createSourceFile("__free_ids__.ts", `(${text});`, ts5.ScriptTarget.Latest, true, ts5.ScriptKind.TS);
250
286
  const stmt = sf.statements[0];
251
- if (!stmt || !ts4.isExpressionStatement(stmt))
287
+ if (!stmt || !ts5.isExpressionStatement(stmt))
252
288
  return new Set;
253
- const expr = ts4.isParenthesizedExpression(stmt.expression) ? stmt.expression.expression : stmt.expression;
289
+ const expr = ts5.isParenthesizedExpression(stmt.expression) ? stmt.expression.expression : stmt.expression;
254
290
  return extractFreeIdentifiersFromNode(expr);
255
291
  }
256
292
 
293
+ // ../jsx/src/ir-to-client-js/rewrite-props-object.ts
294
+ import ts6 from "typescript";
295
+
257
296
  // ../jsx/src/scope/binding-scope.ts
258
297
  class BindingScope {
259
298
  frames;
@@ -375,27 +414,6 @@ var SKELETON_PATH_FORCE_CLOSE_GROUPS = [
375
414
  new Set(["li"])
376
415
  ];
377
416
 
378
- // ../jsx/src/props-binding.ts
379
- import ts6 from "typescript";
380
- function isIdentifierName(key) {
381
- if (key.length === 0)
382
- return false;
383
- for (let i = 0;i < key.length; ) {
384
- const cp = key.codePointAt(i);
385
- const ok = i === 0 ? ts6.isIdentifierStart(cp, ts6.ScriptTarget.Latest) : ts6.isIdentifierPart(cp, ts6.ScriptTarget.Latest);
386
- if (!ok)
387
- return false;
388
- i += cp > 65535 ? 2 : 1;
389
- }
390
- return true;
391
- }
392
- function propsDestructureBinding(p) {
393
- const callerKey = p.sourceName ?? p.name;
394
- const localName = p.name;
395
- const binding = callerKey === localName ? localName : `${isIdentifierName(callerKey) ? callerKey : JSON.stringify(callerKey)}: ${localName}`;
396
- return p.defaultValue ? `${binding} = ${p.defaultValue}` : binding;
397
- }
398
-
399
417
  // ../jsx/src/instrumentation.ts
400
418
  var _counters = freshCounters();
401
419
  function freshCounters() {
@@ -409,20 +427,21 @@ function freshCounters() {
409
427
  }
410
428
 
411
429
  // ../jsx/src/analyzer-context.ts
412
- import ts8 from "typescript";
430
+ import ts9 from "typescript";
413
431
 
414
432
  // ../jsx/src/strip-types.ts
415
- import ts7 from "typescript";
433
+ import ts8 from "typescript";
416
434
 
417
435
  // ../jsx/src/analyzer-context.ts
418
- var _typePrinter = ts8.createPrinter({ removeComments: true, omitTrailingSemicolon: true });
419
- var _blankTypeSourceFile = ts8.createSourceFile("__bf_types__.ts", "", ts8.ScriptTarget.Latest);
436
+ var _typePrinter = ts9.createPrinter({ removeComments: true, omitTrailingSemicolon: true });
437
+ var _blankTypeSourceFile = ts9.createSourceFile("__bf_types__.ts", "", ts9.ScriptTarget.Latest);
420
438
 
421
439
  // ../jsx/src/errors.ts
422
440
  var ErrorCodes = {
423
441
  MISSING_USE_CLIENT: "BF001",
424
442
  CLIENT_IMPORTING_SERVER: "BF003",
425
443
  SIGNAL_OUTSIDE_COMPONENT: "BF011",
444
+ PRIMITIVE_VIA_NAMESPACE_IMPORT: "BF013",
426
445
  UNSUPPORTED_JSX_PATTERN: "BF021",
427
446
  MISSING_KEY_IN_LIST: "BF023",
428
447
  MISSING_KEY_IN_NESTED_LIST: "BF024",
@@ -455,6 +474,7 @@ var errorMessages = {
455
474
  [ErrorCodes.MISSING_USE_CLIENT]: "'use client' directive required for components with createSignal or event handlers",
456
475
  [ErrorCodes.CLIENT_IMPORTING_SERVER]: "Client component cannot import server component",
457
476
  [ErrorCodes.SIGNAL_OUTSIDE_COMPONENT]: "Module-level reactive declaration (createSignal / createMemo) is not allowed. " + "The downstream codegen drops the declaration silently and every reference becomes a ReferenceError at SSR and at hydrate. " + "Move the declaration inside a component function so each mount gets its own state.",
477
+ [ErrorCodes.PRIMITIVE_VIA_NAMESPACE_IMPORT]: "Reactive primitive called through a namespace import of '@barefootjs/client' (import * as ns) is not recognized; " + "the declaration is dropped and its references throw ReferenceError at hydrate. Import the primitive by name instead.",
458
478
  [ErrorCodes.UNSUPPORTED_JSX_PATTERN]: "Unsupported JSX pattern",
459
479
  [ErrorCodes.MISSING_KEY_IN_LIST]: "Missing key attribute in list rendering. Add a key prop for efficient updates",
460
480
  [ErrorCodes.MISSING_KEY_IN_NESTED_LIST]: "Nested .map() loop requires key attribute for event delegation. Add a key prop to elements in the inner loop",
@@ -646,46 +666,46 @@ function extractFreeIdentifiersFromNode(node) {
646
666
  const ids = new Set;
647
667
  const boundNames = new Set;
648
668
  function addBindingNames(name, out) {
649
- if (ts9.isIdentifier(name))
669
+ if (ts10.isIdentifier(name))
650
670
  out.push(name.text);
651
- else if (ts9.isObjectBindingPattern(name))
671
+ else if (ts10.isObjectBindingPattern(name))
652
672
  name.elements.forEach((e) => addBindingNames(e.name, out));
653
- else if (ts9.isArrayBindingPattern(name))
673
+ else if (ts10.isArrayBindingPattern(name))
654
674
  name.elements.forEach((e) => {
655
- if (!ts9.isOmittedExpression(e))
675
+ if (!ts10.isOmittedExpression(e))
656
676
  addBindingNames(e.name, out);
657
677
  });
658
678
  }
659
679
  function visit(n) {
660
- if (ts9.isTypeNode(n))
680
+ if (ts10.isTypeNode(n))
661
681
  return;
662
- if (ts9.isIdentifier(n)) {
682
+ if (ts10.isIdentifier(n)) {
663
683
  const parent = n.parent;
664
- if (parent && ts9.isPropertyAccessExpression(parent) && parent.name === n)
684
+ if (parent && ts10.isPropertyAccessExpression(parent) && parent.name === n)
665
685
  return;
666
- if (parent && ts9.isPropertyAssignment(parent) && parent.name === n)
686
+ if (parent && ts10.isPropertyAssignment(parent) && parent.name === n)
667
687
  return;
668
- if (parent && ts9.isParameter(parent) && parent.name === n)
688
+ if (parent && ts10.isParameter(parent) && parent.name === n)
669
689
  return;
670
- if (parent && ts9.isVariableDeclaration(parent) && parent.name === n)
690
+ if (parent && ts10.isVariableDeclaration(parent) && parent.name === n)
671
691
  return;
672
692
  if (boundNames.has(n.text))
673
693
  return;
674
694
  ids.add(n.text);
675
695
  return;
676
696
  }
677
- if (ts9.isArrowFunction(n)) {
697
+ if (ts10.isArrowFunction(n)) {
678
698
  const params = [];
679
699
  for (const p of n.parameters)
680
700
  addBindingNames(p.name, params);
681
701
  for (const name of params)
682
702
  boundNames.add(name);
683
- ts9.forEachChild(n, visit);
703
+ ts10.forEachChild(n, visit);
684
704
  for (const name of params)
685
705
  boundNames.delete(name);
686
706
  return;
687
707
  }
688
- ts9.forEachChild(n, visit);
708
+ ts10.forEachChild(n, visit);
689
709
  }
690
710
  visit(node);
691
711
  return ids;
@@ -708,7 +728,7 @@ var REACTIVE_PRIMITIVES = new Set([
708
728
  ]);
709
729
 
710
730
  // ../jsx/src/jsx-to-ir.ts
711
- import ts13 from "typescript";
731
+ import ts14 from "typescript";
712
732
 
713
733
  // ../jsx/src/types.ts
714
734
  var SCOPE_FORBIDDEN = {
@@ -744,7 +764,7 @@ var REACTIVE_BINDING_KINDS = new Set([
744
764
  ]);
745
765
 
746
766
  // ../jsx/src/module-exports.ts
747
- import ts10 from "typescript";
767
+ import ts11 from "typescript";
748
768
  function formatParamWithType(p) {
749
769
  const rest = p.isRest ? "..." : "";
750
770
  const optional = p.optional ? "?" : "";
@@ -779,21 +799,21 @@ function findAssignedNames(bodyText, candidates) {
779
799
  const assigned = new Set;
780
800
  if (candidates.size === 0)
781
801
  return assigned;
782
- const sf = ts10.createSourceFile("bf-assignment-scan.tsx", bodyText, ts10.ScriptTarget.Latest, false, ts10.ScriptKind.TSX);
802
+ const sf = ts11.createSourceFile("bf-assignment-scan.tsx", bodyText, ts11.ScriptTarget.Latest, false, ts11.ScriptKind.TSX);
783
803
  const record = (target) => {
784
- if (ts10.isIdentifier(target) && candidates.has(target.text)) {
804
+ if (ts11.isIdentifier(target) && candidates.has(target.text)) {
785
805
  assigned.add(target.text);
786
806
  }
787
807
  };
788
808
  const visit = (node) => {
789
- if (ts10.isBinaryExpression(node) && isAssignmentOperator(node.operatorToken.kind)) {
809
+ if (ts11.isBinaryExpression(node) && isAssignmentOperator(node.operatorToken.kind)) {
790
810
  record(node.left);
791
- } else if ((ts10.isPrefixUnaryExpression(node) || ts10.isPostfixUnaryExpression(node)) && (node.operator === ts10.SyntaxKind.PlusPlusToken || node.operator === ts10.SyntaxKind.MinusMinusToken)) {
811
+ } else if ((ts11.isPrefixUnaryExpression(node) || ts11.isPostfixUnaryExpression(node)) && (node.operator === ts11.SyntaxKind.PlusPlusToken || node.operator === ts11.SyntaxKind.MinusMinusToken)) {
792
812
  record(node.operand);
793
813
  }
794
- ts10.forEachChild(node, visit);
814
+ ts11.forEachChild(node, visit);
795
815
  };
796
- ts10.forEachChild(sf, visit);
816
+ ts11.forEachChild(sf, visit);
797
817
  return assigned;
798
818
  }
799
819
  function closeOverWritersOfMutableBindings(primaryRefs, declarations, mutableNames) {
@@ -816,14 +836,14 @@ function closeOverWritersOfMutableBindings(primaryRefs, declarations, mutableNam
816
836
  return reachable;
817
837
  }
818
838
  function isAssignmentOperator(kind) {
819
- return kind >= ts10.SyntaxKind.FirstAssignment && kind <= ts10.SyntaxKind.LastAssignment;
839
+ return kind >= ts11.SyntaxKind.FirstAssignment && kind <= ts11.SyntaxKind.LastAssignment;
820
840
  }
821
841
 
822
842
  // ../jsx/src/reactivity-checker.ts
823
- import ts11 from "typescript";
843
+ import ts12 from "typescript";
824
844
 
825
845
  // ../jsx/src/free-refs.ts
826
- import ts12 from "typescript";
846
+ import ts13 from "typescript";
827
847
  var _bindingMapCache = new WeakMap;
828
848
 
829
849
  // ../jsx/src/to-locale-date-lowering.ts
@@ -1271,28 +1291,16 @@ var KEYWORDS_AND_GLOBALS = new Set([
1271
1291
  ]);
1272
1292
 
1273
1293
  // ../jsx/src/ir-to-client-js/walk-prop-accesses.ts
1274
- import ts14 from "typescript";
1275
-
1276
- // ../jsx/src/ir-to-client-js/imports.ts
1277
- import ts16 from "typescript";
1278
-
1279
- // ../jsx/src/value-references.ts
1280
1294
  import ts15 from "typescript";
1281
1295
 
1282
- // ../jsx/src/relocate.ts
1296
+ // ../jsx/src/ir-to-client-js/imports.ts
1283
1297
  import ts17 from "typescript";
1284
1298
 
1285
- // ../jsx/src/lowering-registry.ts
1286
- var plugins = [];
1287
- function registerLoweringPlugin(plugin) {
1288
- const existing = plugins.findIndex((p) => p.name === plugin.name);
1289
- if (existing >= 0)
1290
- plugins[existing] = plugin;
1291
- else
1292
- plugins.push(plugin);
1293
- }
1299
+ // ../jsx/src/value-references.ts
1300
+ import ts16 from "typescript";
1294
1301
 
1295
1302
  // ../jsx/src/relocate.ts
1303
+ import ts18 from "typescript";
1296
1304
  var REGISTRY_SAFE_BINDING_KINDS = new Set([
1297
1305
  "global",
1298
1306
  "module-import",
@@ -1459,10 +1467,10 @@ function formatDateLocalNames(metadata) {
1459
1467
  }
1460
1468
 
1461
1469
  // ../jsx/src/ir-to-client-js/prune-unused-prop-extractions.ts
1462
- import ts18 from "typescript";
1470
+ import ts19 from "typescript";
1463
1471
 
1464
1472
  // ../jsx/src/ir-to-client-js/control-flow/plan/lazy-preamble.ts
1465
- import ts19 from "typescript";
1473
+ import ts20 from "typescript";
1466
1474
  var NO_PREAMBLE = {
1467
1475
  lazySafe: true,
1468
1476
  facts: { declaredNames: new Set, freeNames: new Set }
@@ -1512,7 +1520,7 @@ var INERT_BINDING_GLOBALS = new Set([
1512
1520
  ]);
1513
1521
 
1514
1522
  // ../jsx/src/ir-to-client-js/emit-reactive.ts
1515
- import ts20 from "typescript";
1523
+ import ts21 from "typescript";
1516
1524
 
1517
1525
  // ../jsx/src/ir-to-client-js/control-flow/stringify/event-delegation.ts
1518
1526
  var NON_BUBBLING_EVENTS = new Set([
@@ -1526,9 +1534,6 @@ var NON_BUBBLING_EVENTS = new Set([
1526
1534
  "pointerleave"
1527
1535
  ]);
1528
1536
 
1529
- // ../jsx/src/ir-to-client-js/rewrite-props-object.ts
1530
- import ts21 from "typescript";
1531
-
1532
1537
  // ../jsx/src/ir-to-client-js/source-map.ts
1533
1538
  var BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1534
1539
  function encodeVLQ(value) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@barefootjs/hono",
3
- "version": "0.33.4",
3
+ "version": "0.34.0",
4
4
  "description": "Hono integration for BarefootJS",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -122,7 +122,7 @@
122
122
  },
123
123
  "devDependencies": {
124
124
  "@barefootjs/adapter-tests": "0.1.0",
125
- "@barefootjs/vite": "0.33.4",
125
+ "@barefootjs/vite": "0.34.0",
126
126
  "@types/jsdom": "^27.0.0",
127
127
  "hono": "^4.6.0",
128
128
  "jsdom": "^27.3.0",
@@ -21,4 +21,11 @@ export const conformancePins: ConformancePins = {
21
21
  // `rich-prop-client-read` above.
22
22
  'jsx-element-prop-ternary': [{ code: 'BF021', severity: 'error', issue: 'https://github.com/piconic-ai/barefootjs/issues/2667' }],
23
23
  'jsx-element-prop-array': [{ code: 'BF021', severity: 'error', issue: 'https://github.com/piconic-ai/barefootjs/issues/2667' }],
24
+ // #2771: a reactive primitive invoked through a namespace import
25
+ // (`import * as bf from '@barefootjs/client'`, `bf.createSignal(...)`)
26
+ // that the analyzer's checker-less fast path cannot recognize refuses
27
+ // loudly (BF013) instead of silently dropping the declaration — fired
28
+ // in the shared analyzer pass ahead of any adapter's `adapter.generate()`,
29
+ // so all nine adapters (including Hono) pin this identically.
30
+ 'namespace-import-primitive': [{ code: 'BF013', severity: 'error', issue: 'https://github.com/piconic-ai/barefootjs/issues/2771' }],
24
31
  }
@@ -70,6 +70,29 @@ function stripModuleExports(code: string): string {
70
70
  .replace(/\bexport\s+(default\s+)?/g, '')
71
71
  }
72
72
 
73
+ /**
74
+ * A single named-import line for a child that's being INLINED (its
75
+ * declarations are spliced in verbatim, see `stripModuleExports` above) —
76
+ * returns `const <local> = <declared>` for every aliased specifier
77
+ * (`{ Label as AliasedLabel }`), or `null` when every specifier is a bare,
78
+ * non-aliased name (nothing left to bind; dropping the whole line is
79
+ * correct). A default-import specifier (`import Label from …`) has no
80
+ * declared name to alias against and is left unhandled — dropped like
81
+ * before, matching what a bare inlined child needs.
82
+ */
83
+ function aliasDeclarationsFor(importLine: string): string | null {
84
+ const namedMatch = importLine.match(/\{([^}]*)\}/)
85
+ if (!namedMatch) return null
86
+ const aliases = namedMatch[1]
87
+ .split(',')
88
+ .map(spec => spec.trim())
89
+ .filter(Boolean)
90
+ .map(spec => spec.match(/^(\w+)\s+as\s+(\w+)$/))
91
+ .filter((m): m is RegExpMatchArray => m !== null)
92
+ .map(([, declared, local]) => `const ${local} = ${declared};`)
93
+ return aliases.length > 0 ? aliases.join(' ') : null
94
+ }
95
+
73
96
  export async function renderHonoComponent(options: RenderOptions): Promise<string> {
74
97
  const { source, adapter, props, components, componentModules, componentName: requestedName } = options
75
98
 
@@ -171,7 +194,22 @@ export async function renderHonoComponent(options: RenderOptions): Promise<strin
171
194
  const [, prefix, importPath, suffix] = importMatch
172
195
  const moduleKey = matchKey(importPath, moduleTempPaths.keys())
173
196
  if (moduleKey) return `${prefix}${moduleTempPaths.get(moduleKey)}${suffix}`
174
- if (matchKey(importPath, componentKeys)) return null
197
+ if (matchKey(importPath, componentKeys)) {
198
+ // The inlined child keeps its OWN declared name (`stripModuleExports`
199
+ // only removes `export `, it doesn't rename), but the parent's
200
+ // JSX still references whatever LOCAL name it imported the child
201
+ // under (#2777 — Hono correctly keeps the caller's local binding
202
+ // rather than the declared name). Dropping the import line
203
+ // unconditionally is only safe for a non-aliased specifier
204
+ // (`import { Label } from './label'`, where local === declared);
205
+ // an aliased one (`import { Label as AliasedLabel } from
206
+ // './label'`) needs a `const AliasedLabel = Label` left behind, or
207
+ // the parent's JSX throws `ReferenceError: AliasedLabel is not
208
+ // defined` — this harness inlines the child by literal source
209
+ // splice, not through a real module boundary, so there's no
210
+ // `import … as …` left to do the binding for us.
211
+ return aliasDeclarationsFor(line)
212
+ }
175
213
  return line
176
214
  })
177
215
  .filter((line): line is string => line !== null)