@barefootjs/hono 0.30.6 → 0.31.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/vite.js ADDED
@@ -0,0 +1,2749 @@
1
+ // src/vite.ts
2
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
3
+ import { dirname, resolve } from "node:path";
4
+ import { barefoot as coreBarefoot } from "@barefootjs/vite";
5
+ import { devModuleUrl, loadManifest, resolveDevOrigin, resolveScriptAssets, toPosixRelative } from "@barefootjs/vite";
6
+
7
+ // ../jsx/src/analyzer.ts
8
+ import ts8 from "typescript";
9
+
10
+ // ../jsx/src/expression-parser.ts
11
+ import ts from "typescript";
12
+ var UNSUPPORTED_METHODS = new Set([
13
+ "filter",
14
+ "map",
15
+ "reduce",
16
+ "reduceRight",
17
+ "every",
18
+ "some",
19
+ "forEach",
20
+ "flatMap",
21
+ "fill",
22
+ "charAt",
23
+ "charCodeAt",
24
+ "codePointAt",
25
+ "normalize",
26
+ "substring",
27
+ "substr",
28
+ "match",
29
+ "matchAll",
30
+ "search"
31
+ ]);
32
+ var UNSUPPORTED_METHOD_REASONS = {
33
+ forEach: `'.forEach()' returns undefined and has no template-position meaning. ` + `Use it for side effects inside an event handler or createEffect callback ` + `(client JS), or use '.map(...)' if you meant to render each item.`
34
+ };
35
+ var LOWERED_ARRAY_METHODS = new Set([
36
+ "includes",
37
+ "indexOf",
38
+ "lastIndexOf",
39
+ "concat"
40
+ ]);
41
+ var CALLBACK_METHODS = new Set([
42
+ "filter",
43
+ "map",
44
+ "every",
45
+ "some",
46
+ "find",
47
+ "findIndex",
48
+ "findLast",
49
+ "findLastIndex",
50
+ "sort",
51
+ "toSorted",
52
+ "reduce",
53
+ "reduceRight",
54
+ "flatMap"
55
+ ]);
56
+ var IMPERATIVE_BLOCK_REASON = "Block body cannot be normalized to a value expression. Only pure " + "`const` bindings, value-producing `if` / early `return`, and a final " + "`return` are supported. Imperative shapes (raw `for` / `while` loops, " + "`break`, local re-assignment, side-effecting or I/O calls) are not. " + "Rewrite an accumulation loop as `.reduce(...)`, or move the imperative " + "body to a `/* @client */` value so it runs natively on the client.";
57
+ var CAPTURE_BLOCK_REASON = "Block body cannot be normalized: inlining a `const` binding would capture " + "one of its free variables under a nested callback parameter of the same " + "name (e.g. `const x = a; … list.map(a => a + x)`). Rename the inner " + "parameter, or move the body to a `/* @client */` value so it runs natively " + "on the client.";
58
+ var IMPURE_INLINE_BLOCK_REASON = "Block body cannot be normalized: a `const` whose initializer may have side " + "effects (a function or method call) is not used exactly once on every path, " + "so inlining it would drop the effect on some path or duplicate it on " + "another. Bind a pure value, use the binding exactly once unconditionally, " + "or move the body to a `/* @client */` value so it runs natively on the client.";
59
+ var EVAL_BINARY_OPS = new Set([
60
+ "+",
61
+ "-",
62
+ "*",
63
+ "/",
64
+ "%",
65
+ "<",
66
+ "<=",
67
+ ">",
68
+ ">=",
69
+ "===",
70
+ "!=="
71
+ ]);
72
+ var EVAL_UNARY_OPS = new Set(["!", "-", "+"]);
73
+ var EVAL_BUILTIN_IDENTS = new Set(["String", "Number", "Boolean"]);
74
+ var EVAL_MATH_METHODS = new Set([
75
+ "max",
76
+ "min",
77
+ "abs",
78
+ "floor",
79
+ "ceil",
80
+ "round"
81
+ ]);
82
+
83
+ // ../jsx/src/prop-rewrite.ts
84
+ import ts5 from "typescript";
85
+
86
+ // ../jsx/src/ir-to-client-js/utils.ts
87
+ import ts3 from "typescript";
88
+
89
+ // ../jsx/src/loop-chain.ts
90
+ function buildLoopChainExpr(opts) {
91
+ const sortExpr = opts.sortComparator ? `.toSorted((${opts.sortComparator.paramA}, ${opts.sortComparator.paramB}) => ${opts.sortComparator.raw})` : "";
92
+ const filterExpr = opts.filterPredicate ? `.filter(${opts.filterPredicate.param} => ${opts.filterPredicate.raw})` : "";
93
+ if (!sortExpr && !filterExpr)
94
+ return opts.base;
95
+ if (opts.chainOrder === "filter-sort") {
96
+ return `${opts.base}${filterExpr}${sortExpr}`;
97
+ }
98
+ return `${opts.base}${sortExpr}${filterExpr}`;
99
+ }
100
+
101
+ // ../jsx/src/scanner/js-scanner.ts
102
+ import ts2 from "typescript";
103
+
104
+ // ../shared/src/markers.ts
105
+ var BF_SCOPE = "bf-s";
106
+ var BF_SLOT = "bf";
107
+ var BF_HOST = "bf-h";
108
+ var BF_AT = "bf-m";
109
+ var BF_ROOT = "bf-r";
110
+ var BF_PROPS = "bf-p";
111
+ var BF_COND = "bf-c";
112
+ var BF_REGION = "bf-region";
113
+ // ../shared/src/dom-prop.ts
114
+ var BOOLEAN_ATTRS = new Set([
115
+ "checked",
116
+ "disabled",
117
+ "readonly",
118
+ "selected",
119
+ "required",
120
+ "hidden",
121
+ "autofocus",
122
+ "autoplay",
123
+ "controls",
124
+ "loop",
125
+ "muted",
126
+ "open",
127
+ "multiple",
128
+ "novalidate",
129
+ "formnovalidate"
130
+ ]);
131
+ var SVG_XML_CAMEL_ATTRS = new Set([
132
+ "allowReorder",
133
+ "attributeName",
134
+ "attributeType",
135
+ "autoReverse",
136
+ "baseFrequency",
137
+ "baseProfile",
138
+ "calcMode",
139
+ "clipPathUnits",
140
+ "contentScriptType",
141
+ "contentStyleType",
142
+ "diffuseConstant",
143
+ "edgeMode",
144
+ "externalResourcesRequired",
145
+ "filterRes",
146
+ "filterUnits",
147
+ "glyphRef",
148
+ "gradientTransform",
149
+ "gradientUnits",
150
+ "kernelMatrix",
151
+ "kernelUnitLength",
152
+ "keyPoints",
153
+ "keySplines",
154
+ "keyTimes",
155
+ "lengthAdjust",
156
+ "limitingConeAngle",
157
+ "markerHeight",
158
+ "markerUnits",
159
+ "markerWidth",
160
+ "maskContentUnits",
161
+ "maskUnits",
162
+ "numOctaves",
163
+ "pathLength",
164
+ "patternContentUnits",
165
+ "patternTransform",
166
+ "patternUnits",
167
+ "pointsAtX",
168
+ "pointsAtY",
169
+ "pointsAtZ",
170
+ "preserveAlpha",
171
+ "preserveAspectRatio",
172
+ "primitiveUnits",
173
+ "refX",
174
+ "refY",
175
+ "repeatCount",
176
+ "repeatDur",
177
+ "requiredExtensions",
178
+ "requiredFeatures",
179
+ "specularConstant",
180
+ "specularExponent",
181
+ "spreadMethod",
182
+ "startOffset",
183
+ "stdDeviation",
184
+ "stitchTiles",
185
+ "surfaceScale",
186
+ "systemLanguage",
187
+ "tableValues",
188
+ "targetX",
189
+ "targetY",
190
+ "textLength",
191
+ "viewBox",
192
+ "viewTarget",
193
+ "xChannelSelector",
194
+ "yChannelSelector",
195
+ "zoomAndPan"
196
+ ]);
197
+ function isBooleanAttr(name) {
198
+ return BOOLEAN_ATTRS.has(name.toLowerCase());
199
+ }
200
+ // ../shared/src/html-entities.ts
201
+ function escapeHtml(text) {
202
+ return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
203
+ }
204
+ // ../jsx/src/ir-to-client-js/csr-substitute.ts
205
+ import ts4 from "typescript";
206
+
207
+ // ../jsx/src/ir-to-client-js/html-template.ts
208
+ var VOID_ELEMENTS = new Set([
209
+ "area",
210
+ "base",
211
+ "br",
212
+ "col",
213
+ "embed",
214
+ "hr",
215
+ "img",
216
+ "input",
217
+ "link",
218
+ "meta",
219
+ "param",
220
+ "source",
221
+ "track",
222
+ "wbr"
223
+ ]);
224
+ var SKELETON_PATH_HAZARD_TAGS = new Set([
225
+ "table",
226
+ "thead",
227
+ "tbody",
228
+ "tfoot",
229
+ "caption",
230
+ "colgroup",
231
+ "col",
232
+ "select",
233
+ "optgroup",
234
+ "p",
235
+ "pre",
236
+ "textarea",
237
+ "listing",
238
+ "template",
239
+ "math"
240
+ ]);
241
+ var SKELETON_PATH_FORCE_CLOSE_GROUPS = [
242
+ new Set(["a"]),
243
+ new Set(["button"]),
244
+ new Set(["form"]),
245
+ new Set(["option"]),
246
+ new Set(["h1", "h2", "h3", "h4", "h5", "h6"]),
247
+ new Set(["dd", "dt"]),
248
+ new Set(["li"])
249
+ ];
250
+
251
+ // ../jsx/src/instrumentation.ts
252
+ var _counters = freshCounters();
253
+ function freshCounters() {
254
+ return {
255
+ programCreations: 0,
256
+ typeCheckerQueries: 0,
257
+ reactivityChecks: 0,
258
+ filesAnalyzed: 0,
259
+ freeRefsTypeLookupFailures: 0
260
+ };
261
+ }
262
+
263
+ // ../jsx/src/analyzer-context.ts
264
+ import ts7 from "typescript";
265
+
266
+ // ../jsx/src/strip-types.ts
267
+ import ts6 from "typescript";
268
+
269
+ // ../jsx/src/analyzer-context.ts
270
+ var _typePrinter = ts7.createPrinter({ removeComments: true, omitTrailingSemicolon: true });
271
+ var _blankTypeSourceFile = ts7.createSourceFile("__bf_types__.ts", "", ts7.ScriptTarget.Latest);
272
+
273
+ // ../jsx/src/errors.ts
274
+ var ErrorCodes = {
275
+ MISSING_USE_CLIENT: "BF001",
276
+ CLIENT_IMPORTING_SERVER: "BF003",
277
+ SIGNAL_OUTSIDE_COMPONENT: "BF011",
278
+ UNSUPPORTED_JSX_PATTERN: "BF021",
279
+ MISSING_KEY_IN_LIST: "BF023",
280
+ MISSING_KEY_IN_NESTED_LIST: "BF024",
281
+ UNSUPPORTED_DESTRUCTURE_REST: "BF025",
282
+ PROPS_DESTRUCTURING: "BF043",
283
+ SIGNAL_GETTER_NOT_CALLED: "BF044",
284
+ JSX_IN_LOCAL_FUNCTION: "BF045",
285
+ COMPONENT_REQUIRED_PROP_MISSING: "BF046",
286
+ JSX_BRANCH_LOCAL_IN_CALLBACK: "BF047",
287
+ SHARED_PROGRAM_REQUIRED: "BF050",
288
+ WRONG_PACKAGE_IMPORT: "BF051",
289
+ BUILTIN_REQUIRES_IMPORT: "BF054",
290
+ INLINED_IMPORT_MISSING_EXPORT: "BF055",
291
+ UNDECLARED_INIT_STATEMENT_REFERENCE: "BF052",
292
+ STRIPPED_CLIENT_IMPORT_REFERENCED: "BF053",
293
+ STAGE_REACTIVE_IN_TEMPLATE: "BF060",
294
+ STAGE_INIT_LOCAL_IN_TEMPLATE: "BF061",
295
+ STAGE_AWAIT_IN_TEMPLATE: "BF062",
296
+ INLINE_JSX_CALLBACK_CAPTURE: "BF080",
297
+ UNRECOGNIZED_REACTIVE_FACTORY: "BF110",
298
+ REACTIVE_FACTORY_RENAME_UNSUPPORTED: "BF111",
299
+ REACTIVE_FACTORY_MODULE_CAPTURE: "BF112",
300
+ REACTIVE_FACTORY_IMPORT_COLLISION: "BF113",
301
+ REACTIVE_FACTORY_PARAM_SHADOWED: "BF114"
302
+ };
303
+ var errorMessages = {
304
+ [ErrorCodes.MISSING_USE_CLIENT]: "'use client' directive required for components with createSignal or event handlers",
305
+ [ErrorCodes.CLIENT_IMPORTING_SERVER]: "Client component cannot import server component",
306
+ [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.",
307
+ [ErrorCodes.UNSUPPORTED_JSX_PATTERN]: "Unsupported JSX pattern",
308
+ [ErrorCodes.MISSING_KEY_IN_LIST]: "Missing key attribute in list rendering. Add a key prop for efficient updates",
309
+ [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",
310
+ [ErrorCodes.UNSUPPORTED_DESTRUCTURE_REST]: "Computed property key in .map() callback destructure is not supported. Rewrite the callback to destructure explicit bindings (e.g., `({ a, b }) => ...`) so the compiler can rewrite references to per-item signal accessors.",
311
+ [ErrorCodes.PROPS_DESTRUCTURING]: "Props destructuring in function parameters breaks reactivity. Use props object directly.",
312
+ [ErrorCodes.SIGNAL_GETTER_NOT_CALLED]: "Signal/memo getter passed without calling it. Use getter() to read the value.",
313
+ [ErrorCodes.JSX_IN_LOCAL_FUNCTION]: "Local function returns JSX but cannot be inlined. Extract it as a top-level PascalCase component or use a single return statement.",
314
+ [ErrorCodes.COMPONENT_REQUIRED_PROP_MISSING]: "Built-in component is missing a required prop.",
315
+ [ErrorCodes.JSX_BRANCH_LOCAL_IN_CALLBACK]: "JSX-typed local declared inside an `if`-block cannot be referenced from a callback body (ref / event handler). " + "Render it as a child instead: `<div ref={...}>{local}</div>`.",
316
+ [ErrorCodes.SHARED_PROGRAM_REQUIRED]: "Shared ts.Program required for type-based reactivity classification. This source imports a Reactive<T>-branded library (e.g. @barefootjs/form) whose getters cannot be classified by regex alone. Pass `options.program` (built via `createProgramForCorpus`) so the analyzer can resolve the brand through the TypeChecker.",
317
+ [ErrorCodes.WRONG_PACKAGE_IMPORT]: "Import from wrong package.",
318
+ [ErrorCodes.BUILTIN_REQUIRES_IMPORT]: "Built-in <Async> / <Region> must be imported from '@barefootjs/client'. " + "The compiler recognises these tags by their import (not by tag name), " + "so an unimported tag with this name is treated as an undeclared component.",
319
+ [ErrorCodes.UNDECLARED_INIT_STATEMENT_REFERENCE]: "Init statement references an undeclared identifier. Declare it at module scope, inside the component, or import it — otherwise ESM strict mode throws ReferenceError at runtime.",
320
+ [ErrorCodes.STRIPPED_CLIENT_IMPORT_REFERENCED]: "Import was stripped from the client bundle but its binding is still referenced. Client components ('use client' .tsx) are not callable as plain functions from imperative .ts modules — render them as JSX from a 'use client' parent instead. If the flagged name is a local shadow rather than the stripped import, please file an issue.",
321
+ [ErrorCodes.INLINED_IMPORT_MISSING_EXPORT]: "An inlined relative import requests a name the target module does not export. The client bundle would throw ReferenceError at load.",
322
+ [ErrorCodes.STAGE_REACTIVE_IN_TEMPLATE]: "Reactive binding (signal getter or memo) referenced from template scope. The template lambda runs at module scope without the reactive context, so the value cannot be evaluated at SSR. Wrap the JSX expression in /* @client */ to defer it to hydrate, or restructure so the template uses a prop or static value.",
323
+ [ErrorCodes.STAGE_INIT_LOCAL_IN_TEMPLATE]: "Init-scope local referenced from template scope. The template lambda runs at module scope (via render() / renderChild()) and cannot reach init-body locals. Wrap the JSX expression in /* @client */, or lift the value to a prop or module-scope const.",
324
+ [ErrorCodes.STAGE_AWAIT_IN_TEMPLATE]: "AwaitExpression in template scope. The generated template and init functions are synchronous — a bare `await` produces a SyntaxError at parse time. Move the await into the component body (before the return) or into an onMount/effect callback, and pass the resolved value to JSX.",
325
+ [ErrorCodes.INLINE_JSX_CALLBACK_CAPTURE]: "Inline JSX-returning arrow function captures a non-module identifier. 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.",
326
+ [ErrorCodes.UNRECOGNIZED_REACTIVE_FACTORY]: "Tuple destructuring of a non-reactive factory call. The compiler only recognizes createSignal / createMemo calls and same-file helpers that wrap them with a single `return [a, b]` exit.",
327
+ [ErrorCodes.REACTIVE_FACTORY_RENAME_UNSUPPORTED]: "Reactive factory object return/destructure must use shorthand properties only. " + "Property renames (`{ lists: myLists }`), defaults, and rest elements are not " + "supported — destructure with the factory's own property names.",
328
+ [ErrorCodes.REACTIVE_FACTORY_MODULE_CAPTURE]: "Imported reactive factory references bindings from its own module scope, so its " + "body cannot be inlined into the component file. Move those helpers into the " + "component file, pass them to the factory as parameters, or define the factory " + "in the component file.",
329
+ [ErrorCodes.REACTIVE_FACTORY_IMPORT_COLLISION]: "Inlining an imported reactive factory requires re-importing one of its helper " + "imports into this file, but that name is already bound here to something else. " + "Rename the conflicting binding in this file, or alias the import in the factory's own file.",
330
+ [ErrorCodes.REACTIVE_FACTORY_PARAM_SHADOWED]: "Reactive factory parameter is shadowed by a nested declaration inside the factory body, so argument substitution at the inline site would be ambiguous. Rename the inner binding so it does not collide with the parameter."
331
+ };
332
+
333
+ // ../jsx/src/rich-type-evidence.ts
334
+ var HOST_RICH_TYPE_NAMES = new Set([
335
+ "Date",
336
+ "Map",
337
+ "Set",
338
+ "WeakMap",
339
+ "WeakSet",
340
+ "URL",
341
+ "URLSearchParams",
342
+ "RegExp",
343
+ "Promise",
344
+ "Error",
345
+ "Symbol",
346
+ "BigInt",
347
+ "Function"
348
+ ]);
349
+ function baseTypeName(raw) {
350
+ const idx = raw.indexOf("<");
351
+ return (idx === -1 ? raw : raw.slice(0, idx)).trim();
352
+ }
353
+ function isNullishArm(t) {
354
+ return t.kind === "primitive" && (t.primitive === "null" || t.primitive === "undefined");
355
+ }
356
+ function stripUnion(type) {
357
+ if (!type || type.kind !== "union" || !type.unionTypes)
358
+ return type;
359
+ const nonNullish = type.unionTypes.filter((t) => !isNullishArm(t));
360
+ return nonNullish.length === 1 ? stripUnion(nonNullish[0]) : type;
361
+ }
362
+ function derefNamedType(type, meta) {
363
+ if (type.kind !== "interface")
364
+ return type;
365
+ if (type.properties && type.properties.length > 0)
366
+ return type;
367
+ const name = baseTypeName(type.raw);
368
+ const def = meta.typeDefinitions.find((d) => d.name === name);
369
+ if (!def?.properties)
370
+ return type;
371
+ return { ...type, properties: def.properties };
372
+ }
373
+ function lookupProperty(objType, propName, meta) {
374
+ const stripped = stripUnion(objType);
375
+ if (!stripped)
376
+ return null;
377
+ const deref = derefNamedType(stripped, meta);
378
+ const prop = deref.properties?.find((p) => p.name === propName);
379
+ return prop ? stripUnion(prop.type) : null;
380
+ }
381
+ function resolveReceiverType(expr, meta, bindings) {
382
+ if (expr.kind === "identifier") {
383
+ if (bindings.has(expr.name))
384
+ return stripUnion(bindings.get(expr.name) ?? null);
385
+ if (meta.propsObjectName !== null) {
386
+ return expr.name === meta.propsObjectName ? stripUnion(meta.propsType) : null;
387
+ }
388
+ const param = meta.propsParams.find((p) => p.name === expr.name && !p.isRest);
389
+ if (!param)
390
+ return null;
391
+ return lookupProperty(meta.propsType, param.sourceName ?? param.name, meta);
392
+ }
393
+ if (expr.kind === "member" && !expr.computed) {
394
+ const objType = resolveReceiverType(expr.object, meta, bindings);
395
+ return lookupProperty(objType, expr.property, meta);
396
+ }
397
+ return null;
398
+ }
399
+
400
+ // ../jsx/src/date-lowering.ts
401
+ var CATALOGUED_RICH_TYPE_NAMES = new Set(["Date"]);
402
+ var DATE_METHODS = new Set([
403
+ "getUTCFullYear",
404
+ "getUTCMonth",
405
+ "getUTCDate",
406
+ "getUTCHours",
407
+ "getUTCMinutes",
408
+ "getUTCSeconds",
409
+ "getTime",
410
+ "toISOString"
411
+ ]);
412
+ var EMPTY_BINDINGS = new Map;
413
+ function typeReachesDate(type, meta, seen) {
414
+ const stripped = stripUnion(type);
415
+ if (!stripped)
416
+ return false;
417
+ if (stripped.kind === "interface") {
418
+ const name = baseTypeName(stripped.raw);
419
+ if (name === "Date")
420
+ return true;
421
+ if (seen.has(name))
422
+ return false;
423
+ seen.add(name);
424
+ } else if (stripped.kind !== "object") {
425
+ return false;
426
+ }
427
+ const deref = derefNamedType(stripped, meta);
428
+ if (!deref.properties)
429
+ return false;
430
+ return deref.properties.some((p) => typeReachesDate(p.type, meta, seen));
431
+ }
432
+ function matchDateCall(callee, args, metadata) {
433
+ if (callee.kind !== "member" || callee.computed)
434
+ return null;
435
+ if (args.length !== 0 || !DATE_METHODS.has(callee.property))
436
+ return null;
437
+ const receiverType = resolveReceiverType(callee.object, metadata, EMPTY_BINDINGS);
438
+ if (!receiverType || receiverType.kind !== "interface")
439
+ return null;
440
+ const typeName = baseTypeName(receiverType.raw);
441
+ if (typeName !== "Date")
442
+ return null;
443
+ if (metadata.typeDefinitions.some((d) => d.name === typeName))
444
+ return null;
445
+ return {
446
+ kind: "helper-call",
447
+ helper: "date",
448
+ args: [callee.object, { kind: "literal", value: callee.property, literalType: "string" }]
449
+ };
450
+ }
451
+ var datePlugin = {
452
+ name: "date",
453
+ prepare(metadata) {
454
+ if (!metadata.propsType || !typeReachesDate(metadata.propsType, metadata, new Set))
455
+ return null;
456
+ return (callee, args) => matchDateCall(callee, args, metadata);
457
+ }
458
+ };
459
+
460
+ // ../jsx/src/analyzer.ts
461
+ var CLIENT_EXPORTS = new Set([
462
+ "createSignal",
463
+ "createEffect",
464
+ "createDisposableEffect",
465
+ "createMemo",
466
+ "createSelector",
467
+ "createRoot",
468
+ "onCleanup",
469
+ "onMount",
470
+ "untrack",
471
+ "batch",
472
+ "splitProps",
473
+ "forwardProps",
474
+ "unwrap",
475
+ "__slot",
476
+ "createContext",
477
+ "useContext",
478
+ "provideContext",
479
+ "createPortal",
480
+ "isSSRPortal",
481
+ "findSiblingSlot",
482
+ "cleanupPortalPlaceholder",
483
+ "createSearchParams",
484
+ "queryHref",
485
+ "formatDate",
486
+ "Async",
487
+ "Region"
488
+ ]);
489
+ var BROWSER_ONLY_CLIENT_APIS = new Set([
490
+ "useContext",
491
+ "provideContext",
492
+ "createPortal",
493
+ "isSSRPortal",
494
+ "findSiblingSlot",
495
+ "cleanupPortalPlaceholder"
496
+ ]);
497
+ var REACTIVE_PRIMITIVES = new Set([
498
+ "createSignal",
499
+ "createMemo",
500
+ "createEffect",
501
+ "createDisposableEffect",
502
+ "onMount",
503
+ "onCleanup"
504
+ ]);
505
+
506
+ // ../jsx/src/jsx-to-ir.ts
507
+ import ts11 from "typescript";
508
+
509
+ // ../jsx/src/types.ts
510
+ var SCOPE_FORBIDDEN = {
511
+ module: new Set([
512
+ "prop",
513
+ "signal-getter",
514
+ "signal-setter",
515
+ "memo-getter",
516
+ "reactive-brand",
517
+ "init-local",
518
+ "sub-init-local",
519
+ "render-item"
520
+ ]),
521
+ init: new Set([]),
522
+ template: new Set([
523
+ "prop",
524
+ "signal-getter",
525
+ "signal-setter",
526
+ "memo-getter",
527
+ "reactive-brand",
528
+ "init-local",
529
+ "sub-init-local",
530
+ "render-item"
531
+ ]),
532
+ "sub-init": new Set([]),
533
+ "render-item": new Set([])
534
+ };
535
+ var REACTIVE_BINDING_KINDS = new Set([
536
+ "prop",
537
+ "signal-getter",
538
+ "memo-getter",
539
+ "reactive-brand"
540
+ ]);
541
+
542
+ // ../jsx/src/module-exports.ts
543
+ function formatParamWithType(p) {
544
+ const rest = p.isRest ? "..." : "";
545
+ const optional = p.optional ? "?" : "";
546
+ const typeAnnotation = p.type?.raw && p.type.raw !== "unknown" ? `: ${p.type.raw}` : "";
547
+ const defaultPart = p.defaultValue !== undefined ? ` = ${p.defaultValue}` : "";
548
+ return `${rest}${p.name}${optional}${typeAnnotation}${defaultPart}`;
549
+ }
550
+ function findReachableNames(primaryRefs, declarations) {
551
+ const allNames = new Set(declarations.map((d) => d.name));
552
+ const bodyMap = new Map(declarations.map((d) => [d.name, d.body]));
553
+ const reachable = new Set;
554
+ const queue = [];
555
+ for (const name of allNames) {
556
+ if (new RegExp(`\\b${name}\\b`).test(primaryRefs)) {
557
+ reachable.add(name);
558
+ queue.push(name);
559
+ }
560
+ }
561
+ while (queue.length > 0) {
562
+ const current = queue.shift();
563
+ const body = bodyMap.get(current) || "";
564
+ for (const name of allNames) {
565
+ if (!reachable.has(name) && new RegExp(`\\b${name}\\b`).test(body)) {
566
+ reachable.add(name);
567
+ queue.push(name);
568
+ }
569
+ }
570
+ }
571
+ return reachable;
572
+ }
573
+
574
+ // ../jsx/src/reactivity-checker.ts
575
+ import ts9 from "typescript";
576
+
577
+ // ../jsx/src/free-refs.ts
578
+ import ts10 from "typescript";
579
+ var _bindingMapCache = new WeakMap;
580
+
581
+ // ../jsx/src/to-locale-date-lowering.ts
582
+ var TO_LOCALE_TZ_RE = /^(?:UTC|[+-](?:[01]\d|2[0-3]):[0-5]\d)$/;
583
+ var tzProbeCache = new Map;
584
+ function isBuildResolvableTimeZone(value) {
585
+ const cached = tzProbeCache.get(value);
586
+ if (cached !== undefined)
587
+ return cached;
588
+ let verified;
589
+ try {
590
+ verified = new Intl.DateTimeFormat("en-US", { timeZone: value }).resolvedOptions().timeZone === value;
591
+ } catch {
592
+ verified = false;
593
+ }
594
+ tzProbeCache.set(value, verified);
595
+ return verified;
596
+ }
597
+ var PROBE_UTC = new Date(Date.UTC(2001, 1, 3));
598
+ var formatCache = new Map;
599
+ var namesCache = new Map;
600
+ function deriveMonthNames(locale, ctx) {
601
+ return deriveNamesCached(`${locale}|m|${ctx}`, () => {
602
+ const months = (width) => Array.from({ length: 12 }, (_, m) => probePart(locale, ctx === "formatting" ? { month: width, day: "numeric" } : { month: width }, Date.UTC(2001, m, 15), "month"));
603
+ return [...months("long"), ...months("short")];
604
+ });
605
+ }
606
+ function deriveWeekdayNames(locale, ctx) {
607
+ return deriveNamesCached(`${locale}|w|${ctx}`, () => {
608
+ const weekdays = (width) => Array.from({ length: 7 }, (_, d) => probePart(locale, ctx === "formatting" ? { weekday: width, month: "numeric", day: "numeric" } : { weekday: width }, Date.UTC(2023, 0, 1 + d), "weekday"));
609
+ return [...weekdays("long"), ...weekdays("short")];
610
+ });
611
+ }
612
+ function probePart(locale, options, utc, type) {
613
+ const parts = new Intl.DateTimeFormat(locale, { ...options, timeZone: "UTC" }).formatToParts(new Date(utc));
614
+ const found = parts.find((p) => p.type === type);
615
+ if (!found || !found.value)
616
+ throw new Error("missing part");
617
+ return found.value;
618
+ }
619
+ function deriveNamesCached(key, derive) {
620
+ const cached = namesCache.get(key);
621
+ if (cached !== undefined)
622
+ return cached;
623
+ let derived;
624
+ try {
625
+ derived = derive();
626
+ } catch {
627
+ derived = null;
628
+ }
629
+ namesCache.set(key, derived);
630
+ return derived;
631
+ }
632
+ function resolveLocaleDateFormat(locale, probeOptions) {
633
+ const key = `${locale}|${JSON.stringify(probeOptions, Object.keys(probeOptions).sort())}`;
634
+ const cached = formatCache.get(key);
635
+ if (cached !== undefined)
636
+ return cached;
637
+ const derived = deriveFormat(locale, probeOptions);
638
+ formatCache.set(key, derived);
639
+ return derived;
640
+ }
641
+ var VERIFY_UTC = new Date(Date.UTC(2001, 4, 13));
642
+ function renderPatternAt(pattern, names, y, m, d, wd) {
643
+ const pad2 = (n) => String(n).padStart(2, "0");
644
+ return pattern.replace(/YYYY|MMMM|MMM|MM|DD|dddd|ddd|M|D/g, (token) => {
645
+ switch (token) {
646
+ case "YYYY":
647
+ return String(y).padStart(4, "0");
648
+ case "MMMM":
649
+ return names[m - 1] ?? "";
650
+ case "MMM":
651
+ return names[12 + m - 1] ?? "";
652
+ case "MM":
653
+ return pad2(m);
654
+ case "M":
655
+ return String(m);
656
+ case "DD":
657
+ return pad2(d);
658
+ case "D":
659
+ return String(d);
660
+ case "dddd":
661
+ return names[24 + wd] ?? "";
662
+ default:
663
+ return names[31 + wd] ?? "";
664
+ }
665
+ });
666
+ }
667
+ function deriveFormat(locale, probeOptions) {
668
+ let dtf;
669
+ let parts;
670
+ try {
671
+ dtf = new Intl.DateTimeFormat(locale, {
672
+ ...probeOptions,
673
+ timeZone: "UTC"
674
+ });
675
+ const resolved = dtf.resolvedOptions();
676
+ if (resolved.calendar !== "gregory" || resolved.numberingSystem !== "latn")
677
+ return null;
678
+ parts = dtf.formatToParts(PROBE_UTC);
679
+ } catch {
680
+ return null;
681
+ }
682
+ const monthTables = [
683
+ deriveMonthNames(locale, "formatting"),
684
+ deriveMonthNames(locale, "standalone")
685
+ ];
686
+ const weekdayTables = [
687
+ deriveWeekdayNames(locale, "formatting"),
688
+ deriveWeekdayNames(locale, "standalone")
689
+ ];
690
+ let monthTable = null;
691
+ let weekdayTable = null;
692
+ let pattern = "";
693
+ let usesNames = false;
694
+ for (const part of parts) {
695
+ switch (part.type) {
696
+ case "year":
697
+ if (part.value !== "2001")
698
+ return null;
699
+ pattern += "YYYY";
700
+ break;
701
+ case "month": {
702
+ if (part.value === "2") {
703
+ pattern += "M";
704
+ break;
705
+ }
706
+ if (part.value === "02") {
707
+ pattern += "MM";
708
+ break;
709
+ }
710
+ const wide = monthTables.find((t) => t && part.value === t[1]) ?? null;
711
+ const abbr = wide ? null : monthTables.find((t) => t && part.value === t[12 + 1]) ?? null;
712
+ if (wide)
713
+ pattern += "MMMM";
714
+ else if (abbr)
715
+ pattern += "MMM";
716
+ else
717
+ return null;
718
+ monthTable = wide ?? abbr;
719
+ usesNames = true;
720
+ break;
721
+ }
722
+ case "day":
723
+ if (part.value === "3")
724
+ pattern += "D";
725
+ else if (part.value === "03")
726
+ pattern += "DD";
727
+ else
728
+ return null;
729
+ break;
730
+ case "weekday": {
731
+ const wide = weekdayTables.find((t) => t && part.value === t[6]) ?? null;
732
+ const abbr = wide ? null : weekdayTables.find((t) => t && part.value === t[7 + 6]) ?? null;
733
+ if (wide)
734
+ pattern += "dddd";
735
+ else if (abbr)
736
+ pattern += "ddd";
737
+ else
738
+ return null;
739
+ weekdayTable = wide ?? abbr;
740
+ usesNames = true;
741
+ break;
742
+ }
743
+ case "literal":
744
+ if (/[YMD]/.test(part.value) || /ddd/.test(part.value))
745
+ return null;
746
+ pattern += part.value;
747
+ break;
748
+ default:
749
+ return null;
750
+ }
751
+ }
752
+ if (!/YYYY|MMMM|MMM|MM|M/.test(pattern) && !/DD|D/.test(pattern))
753
+ return null;
754
+ if (!usesNames)
755
+ return { pattern, names: null };
756
+ const names = [
757
+ ...monthTable ?? monthTables[0] ?? monthTables[1] ?? Array(24).fill(""),
758
+ ...weekdayTable ?? weekdayTables[0] ?? weekdayTables[1] ?? Array(14).fill("")
759
+ ];
760
+ if (renderPatternAt(pattern, names, 2001, 5, 13, 0) !== dtf.format(VERIFY_UTC))
761
+ return null;
762
+ return { pattern, names };
763
+ }
764
+ function unionMemberLiteral(member) {
765
+ if (member.kind === "primitive" && member.primitive === "string" && member.literalValue !== undefined) {
766
+ return member.literalValue;
767
+ }
768
+ return null;
769
+ }
770
+ function resolveLocaleUnionMembers(locale, metadata) {
771
+ let sourcePropName = null;
772
+ if (metadata.propsObjectName) {
773
+ if (locale.kind === "member" && !locale.computed && locale.object.kind === "identifier" && locale.object.name === metadata.propsObjectName) {
774
+ sourcePropName = locale.property;
775
+ }
776
+ } else if (locale.kind === "identifier") {
777
+ const name = locale.name;
778
+ const param = metadata.propsParams?.find((pp) => pp.name === name);
779
+ if (param)
780
+ sourcePropName = param.sourceName ?? param.name;
781
+ }
782
+ if (!sourcePropName)
783
+ return null;
784
+ const target = sourcePropName;
785
+ const prop = metadata.propsType?.properties?.find((p) => p.name === target);
786
+ if (!prop || prop.optional)
787
+ return null;
788
+ const type = prop.type;
789
+ if (type.kind !== "union" || !type.unionTypes || type.unionTypes.length === 0)
790
+ return null;
791
+ const members = [];
792
+ for (const member of type.unionTypes) {
793
+ const value = unionMemberLiteral(member);
794
+ if (value === null)
795
+ return null;
796
+ members.push(value);
797
+ }
798
+ return members;
799
+ }
800
+ var strLit = (value) => ({ kind: "literal", value, literalType: "string" });
801
+ function strArr(values) {
802
+ return {
803
+ kind: "array-literal",
804
+ elements: values.map((v) => strLit(v)),
805
+ raw: JSON.stringify(values)
806
+ };
807
+ }
808
+ function foldMembers(locale, members, leaves, allEqual) {
809
+ let expr = leaves[leaves.length - 1];
810
+ if (allEqual)
811
+ return expr;
812
+ for (let i = leaves.length - 2;i >= 0; i--) {
813
+ expr = {
814
+ kind: "conditional",
815
+ test: { kind: "binary", op: "===", left: locale, right: strLit(members[i]) },
816
+ consequent: leaves[i],
817
+ alternate: expr
818
+ };
819
+ }
820
+ return expr;
821
+ }
822
+ function matchToLocaleDateStringCall(callee, args, metadata) {
823
+ if (callee.kind !== "member" || callee.computed)
824
+ return null;
825
+ if (callee.property !== "toLocaleDateString" || args.length !== 2)
826
+ return null;
827
+ const [locale, options] = args;
828
+ if (options.kind !== "object-literal")
829
+ return null;
830
+ let tz = null;
831
+ const probeOptions = {};
832
+ for (const prop of options.properties) {
833
+ if (prop.value.kind !== "literal" || prop.value.literalType !== "string")
834
+ return null;
835
+ const value = String(prop.value.value);
836
+ if (prop.key === "timeZone") {
837
+ if (!TO_LOCALE_TZ_RE.test(value) && !isBuildResolvableTimeZone(value))
838
+ return null;
839
+ tz = value;
840
+ } else {
841
+ probeOptions[prop.key] = value;
842
+ }
843
+ }
844
+ if (tz === null)
845
+ return null;
846
+ const receiverType = resolveReceiverType(callee.object, metadata, new Map);
847
+ if (!receiverType || receiverType.kind !== "interface")
848
+ return null;
849
+ const typeName = baseTypeName(receiverType.raw);
850
+ if (typeName !== "Date")
851
+ return null;
852
+ if (metadata.typeDefinitions.some((d) => d.name === typeName))
853
+ return null;
854
+ if (locale.kind === "literal" && locale.literalType === "string") {
855
+ const format = resolveLocaleDateFormat(String(locale.value), probeOptions);
856
+ if (format === null)
857
+ return null;
858
+ return {
859
+ kind: "helper-call",
860
+ helper: "format_date",
861
+ args: [callee.object, strLit(format.pattern), strLit(tz), strArr(format.names ?? [])]
862
+ };
863
+ }
864
+ const members = resolveLocaleUnionMembers(locale, metadata);
865
+ if (!members)
866
+ return null;
867
+ const formats = [];
868
+ for (const member of members) {
869
+ const format = resolveLocaleDateFormat(member, probeOptions);
870
+ if (format === null)
871
+ return null;
872
+ formats.push(format);
873
+ }
874
+ const patterns = formats.map((f) => f.pattern);
875
+ const nameTables = formats.map((f) => JSON.stringify(f.names ?? []));
876
+ return {
877
+ kind: "helper-call",
878
+ helper: "format_date",
879
+ args: [
880
+ callee.object,
881
+ foldMembers(locale, members, patterns.map(strLit), new Set(patterns).size === 1),
882
+ strLit(tz),
883
+ foldMembers(locale, members, formats.map((f) => strArr(f.names ?? [])), new Set(nameTables).size === 1)
884
+ ]
885
+ };
886
+ }
887
+ var toLocaleDatePlugin = {
888
+ name: "toLocaleDateString",
889
+ prepare(metadata) {
890
+ if (!metadata.propsType || !typeReachesDate(metadata.propsType, metadata, new Set))
891
+ return null;
892
+ return (callee, args) => matchToLocaleDateStringCall(callee, args, metadata);
893
+ }
894
+ };
895
+
896
+ // ../jsx/src/jsx-to-ir.ts
897
+ var EMPTY_BOUND = new Set;
898
+ var constInitializerCache = new WeakMap;
899
+ var functionInfoExprCache = new WeakMap;
900
+
901
+ // ../jsx/src/ir-to-client-js/control-flow/stringify/template-parse.ts
902
+ var SVG_ROOT_TAGS = new Set([
903
+ "svg",
904
+ "path",
905
+ "circle",
906
+ "rect",
907
+ "line",
908
+ "polyline",
909
+ "polygon",
910
+ "ellipse",
911
+ "text",
912
+ "tspan",
913
+ "textPath",
914
+ "g",
915
+ "defs",
916
+ "use",
917
+ "symbol",
918
+ "switch",
919
+ "clipPath",
920
+ "mask",
921
+ "marker",
922
+ "pattern",
923
+ "linearGradient",
924
+ "radialGradient",
925
+ "stop",
926
+ "image",
927
+ "foreignObject",
928
+ "filter",
929
+ "feBlend",
930
+ "feColorMatrix",
931
+ "feComposite",
932
+ "feFlood",
933
+ "feGaussianBlur",
934
+ "feMerge",
935
+ "feMergeNode",
936
+ "feMorphology",
937
+ "feOffset",
938
+ "feTurbulence",
939
+ "animate",
940
+ "animateTransform",
941
+ "animateMotion"
942
+ ]);
943
+
944
+ // ../jsx/src/ir-to-client-js/collect-elements.ts
945
+ var EMPTY_RENDER_EXPRS = new Set(["null", "undefined", "false", "''", '""', "``"]);
946
+
947
+ // ../jsx/src/ir-to-client-js/identifiers.ts
948
+ var KEYWORDS_AND_GLOBALS = new Set([
949
+ "true",
950
+ "false",
951
+ "null",
952
+ "undefined",
953
+ "this",
954
+ "const",
955
+ "let",
956
+ "var",
957
+ "function",
958
+ "return",
959
+ "if",
960
+ "else",
961
+ "for",
962
+ "while",
963
+ "do",
964
+ "switch",
965
+ "case",
966
+ "break",
967
+ "continue",
968
+ "new",
969
+ "typeof",
970
+ "instanceof",
971
+ "void",
972
+ "delete",
973
+ "console",
974
+ "window",
975
+ "document",
976
+ "Math",
977
+ "String",
978
+ "Number",
979
+ "Array",
980
+ "Object",
981
+ "Boolean",
982
+ "Date",
983
+ "JSON",
984
+ "Promise",
985
+ "setTimeout",
986
+ "setInterval",
987
+ "clearTimeout",
988
+ "clearInterval"
989
+ ]);
990
+
991
+ // ../jsx/src/ir-to-client-js/walk-prop-accesses.ts
992
+ import ts12 from "typescript";
993
+
994
+ // ../jsx/src/value-references.ts
995
+ import ts13 from "typescript";
996
+
997
+ // ../jsx/src/relocate.ts
998
+ import ts14 from "typescript";
999
+
1000
+ // ../jsx/src/lowering-registry.ts
1001
+ var plugins = [];
1002
+ function registerLoweringPlugin(plugin) {
1003
+ const existing = plugins.findIndex((p) => p.name === plugin.name);
1004
+ if (existing >= 0)
1005
+ plugins[existing] = plugin;
1006
+ else
1007
+ plugins.push(plugin);
1008
+ }
1009
+
1010
+ // ../jsx/src/relocate.ts
1011
+ var REGISTRY_SAFE_BINDING_KINDS = new Set([
1012
+ "global",
1013
+ "module-import",
1014
+ "module-local"
1015
+ ]);
1016
+ var RESERVED_WORDS = new Set([
1017
+ "true",
1018
+ "false",
1019
+ "null",
1020
+ "undefined",
1021
+ "void",
1022
+ "typeof",
1023
+ "instanceof",
1024
+ "new",
1025
+ "delete",
1026
+ "in",
1027
+ "of",
1028
+ "this",
1029
+ "super",
1030
+ "return",
1031
+ "if",
1032
+ "else",
1033
+ "for",
1034
+ "while",
1035
+ "do",
1036
+ "switch",
1037
+ "case",
1038
+ "default",
1039
+ "break",
1040
+ "continue",
1041
+ "function",
1042
+ "class",
1043
+ "const",
1044
+ "let",
1045
+ "var",
1046
+ "async",
1047
+ "await",
1048
+ "try",
1049
+ "catch",
1050
+ "finally",
1051
+ "throw"
1052
+ ]);
1053
+
1054
+ // ../jsx/src/ir-to-client-js/compute-inlinability.ts
1055
+ var JS_BUILTINS = new Set([
1056
+ "true",
1057
+ "false",
1058
+ "null",
1059
+ "undefined",
1060
+ "NaN",
1061
+ "Infinity",
1062
+ "typeof",
1063
+ "instanceof",
1064
+ "void",
1065
+ "delete",
1066
+ "new",
1067
+ "in",
1068
+ "of",
1069
+ "this",
1070
+ "super",
1071
+ "return",
1072
+ "throw",
1073
+ "if",
1074
+ "else",
1075
+ "for",
1076
+ "while",
1077
+ "do",
1078
+ "switch",
1079
+ "case",
1080
+ "break",
1081
+ "continue",
1082
+ "try",
1083
+ "catch",
1084
+ "finally",
1085
+ "yield",
1086
+ "await",
1087
+ "async",
1088
+ "let",
1089
+ "const",
1090
+ "var",
1091
+ "function",
1092
+ "class",
1093
+ "Math",
1094
+ "JSON",
1095
+ "Object",
1096
+ "Array",
1097
+ "String",
1098
+ "Number",
1099
+ "Boolean",
1100
+ "Date",
1101
+ "RegExp",
1102
+ "Map",
1103
+ "Set",
1104
+ "WeakMap",
1105
+ "WeakSet",
1106
+ "Promise",
1107
+ "Error",
1108
+ "TypeError",
1109
+ "RangeError",
1110
+ "SyntaxError",
1111
+ "console",
1112
+ "window",
1113
+ "document",
1114
+ "globalThis",
1115
+ "navigator",
1116
+ "parseInt",
1117
+ "parseFloat",
1118
+ "isNaN",
1119
+ "isFinite",
1120
+ "encodeURIComponent",
1121
+ "decodeURIComponent",
1122
+ "encodeURI",
1123
+ "decodeURI",
1124
+ "setTimeout",
1125
+ "clearTimeout",
1126
+ "setInterval",
1127
+ "clearInterval",
1128
+ "requestAnimationFrame",
1129
+ "cancelAnimationFrame",
1130
+ "Symbol",
1131
+ "Proxy",
1132
+ "Reflect",
1133
+ "BigInt"
1134
+ ]);
1135
+
1136
+ // ../jsx/src/adapters/env-signal.ts
1137
+ var ENV_SIGNAL_CLIENT_FACTORY = {
1138
+ search: "createSearchParams"
1139
+ };
1140
+ var ENV_SIGNAL_READERS = new Map([
1141
+ ["search", { key: "search", canonicalName: "searchParams", methods: new Set(["get"]) }]
1142
+ ]);
1143
+ function queryHrefLocalNames(metadata) {
1144
+ const names = new Set;
1145
+ for (const imp of metadata.imports) {
1146
+ if (!CLIENT_HELPER_SOURCES.has(imp.source) || imp.isTypeOnly)
1147
+ continue;
1148
+ for (const s of imp.specifiers) {
1149
+ if (s.isTypeOnly || s.isNamespace || s.isDefault)
1150
+ continue;
1151
+ if (s.name === "queryHref")
1152
+ names.add(s.alias ?? s.name);
1153
+ }
1154
+ }
1155
+ return names;
1156
+ }
1157
+ var CLIENT_HELPER_SOURCES = new Set([
1158
+ "@barefootjs/client",
1159
+ "@barefootjs/client/runtime"
1160
+ ]);
1161
+ function formatDateLocalNames(metadata) {
1162
+ const names = new Set;
1163
+ for (const imp of metadata.imports) {
1164
+ if (!CLIENT_HELPER_SOURCES.has(imp.source) || imp.isTypeOnly)
1165
+ continue;
1166
+ for (const s of imp.specifiers) {
1167
+ if (s.isTypeOnly || s.isNamespace || s.isDefault)
1168
+ continue;
1169
+ if (s.name === "formatDate")
1170
+ names.add(s.alias ?? s.name);
1171
+ }
1172
+ }
1173
+ return names;
1174
+ }
1175
+
1176
+ // ../jsx/src/ir-to-client-js/prune-unused-prop-extractions.ts
1177
+ import ts15 from "typescript";
1178
+
1179
+ // ../jsx/src/ir-to-client-js/control-flow/plan/lazy-preamble.ts
1180
+ import ts16 from "typescript";
1181
+ var NO_PREAMBLE = {
1182
+ lazySafe: true,
1183
+ facts: { declaredNames: new Set, freeNames: new Set }
1184
+ };
1185
+
1186
+ // ../jsx/src/ir-to-client-js/control-flow/plan/lazy-row-eligibility.ts
1187
+ var PURE_SOURCE_GLOBALS = new Set([
1188
+ "Object",
1189
+ "Array",
1190
+ "JSON",
1191
+ "Number",
1192
+ "String",
1193
+ "Boolean"
1194
+ ]);
1195
+ var INERT_BINDING_GLOBALS = new Set([
1196
+ "Object",
1197
+ "Array",
1198
+ "JSON",
1199
+ "Number",
1200
+ "String",
1201
+ "Boolean",
1202
+ "Math",
1203
+ "Date",
1204
+ "Intl",
1205
+ "Symbol",
1206
+ "Map",
1207
+ "Set",
1208
+ "WeakMap",
1209
+ "WeakSet",
1210
+ "Promise",
1211
+ "RegExp",
1212
+ "Error",
1213
+ "BigInt",
1214
+ "console",
1215
+ "undefined",
1216
+ "NaN",
1217
+ "Infinity",
1218
+ "globalThis",
1219
+ "parseInt",
1220
+ "parseFloat",
1221
+ "isNaN",
1222
+ "isFinite",
1223
+ "encodeURIComponent",
1224
+ "decodeURIComponent",
1225
+ "encodeURI",
1226
+ "decodeURI"
1227
+ ]);
1228
+
1229
+ // ../jsx/src/ir-to-client-js/emit-reactive.ts
1230
+ import ts17 from "typescript";
1231
+
1232
+ // ../jsx/src/ir-to-client-js/control-flow/stringify/event-delegation.ts
1233
+ var NON_BUBBLING_EVENTS = new Set([
1234
+ "blur",
1235
+ "focus",
1236
+ "load",
1237
+ "unload",
1238
+ "mouseenter",
1239
+ "mouseleave",
1240
+ "pointerenter",
1241
+ "pointerleave"
1242
+ ]);
1243
+
1244
+ // ../jsx/src/ir-to-client-js/rewrite-props-object.ts
1245
+ import ts18 from "typescript";
1246
+
1247
+ // ../jsx/src/ir-to-client-js/source-map.ts
1248
+ var BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1249
+ function encodeVLQ(value) {
1250
+ let vlq = value < 0 ? (-value << 1) + 1 : value << 1;
1251
+ let encoded = "";
1252
+ do {
1253
+ let digit = vlq & 31;
1254
+ vlq >>>= 5;
1255
+ if (vlq > 0)
1256
+ digit |= 32;
1257
+ encoded += BASE64_CHARS[digit];
1258
+ } while (vlq > 0);
1259
+ return encoded;
1260
+ }
1261
+
1262
+ class SourceMapGenerator {
1263
+ sources = [];
1264
+ sourcesContent = [];
1265
+ sourceIndexMap = new Map;
1266
+ mappings = [];
1267
+ file;
1268
+ constructor(generatedFile) {
1269
+ this.file = generatedFile;
1270
+ }
1271
+ addSource(sourcePath, content) {
1272
+ const existing = this.sourceIndexMap.get(sourcePath);
1273
+ if (existing !== undefined)
1274
+ return existing;
1275
+ const index = this.sources.length;
1276
+ this.sources.push(sourcePath);
1277
+ this.sourcesContent.push(content ?? null);
1278
+ this.sourceIndexMap.set(sourcePath, index);
1279
+ return index;
1280
+ }
1281
+ addMappingFromLoc(generatedLine, generatedColumn, loc) {
1282
+ const sourceIndex = this.addSource(loc.file);
1283
+ this.mappings.push({
1284
+ generatedLine,
1285
+ generatedColumn,
1286
+ sourceIndex,
1287
+ originalLine: loc.start.line - 1,
1288
+ originalColumn: loc.start.column
1289
+ });
1290
+ }
1291
+ toJSON() {
1292
+ return {
1293
+ version: 3,
1294
+ file: this.file,
1295
+ sourceRoot: "",
1296
+ sources: this.sources,
1297
+ sourcesContent: this.sourcesContent,
1298
+ names: [],
1299
+ mappings: this.encodeMappings()
1300
+ };
1301
+ }
1302
+ toString() {
1303
+ return JSON.stringify(this.toJSON());
1304
+ }
1305
+ encodeMappings() {
1306
+ const sorted = [...this.mappings].sort((a, b) => a.generatedLine - b.generatedLine || a.generatedColumn - b.generatedColumn);
1307
+ const lines = [];
1308
+ let prevGeneratedColumn = 0;
1309
+ let prevSourceIndex = 0;
1310
+ let prevOriginalLine = 0;
1311
+ let prevOriginalColumn = 0;
1312
+ let prevGeneratedLine = 0;
1313
+ for (const mapping of sorted) {
1314
+ while (lines.length <= mapping.generatedLine) {
1315
+ lines.push([]);
1316
+ if (lines.length > 1) {
1317
+ prevGeneratedColumn = 0;
1318
+ }
1319
+ }
1320
+ if (mapping.generatedLine !== prevGeneratedLine) {
1321
+ prevGeneratedColumn = 0;
1322
+ prevGeneratedLine = mapping.generatedLine;
1323
+ }
1324
+ const segment = encodeVLQ(mapping.generatedColumn - prevGeneratedColumn) + encodeVLQ(mapping.sourceIndex - prevSourceIndex) + encodeVLQ(mapping.originalLine - prevOriginalLine) + encodeVLQ(mapping.originalColumn - prevOriginalColumn);
1325
+ lines[mapping.generatedLine].push(segment);
1326
+ prevGeneratedColumn = mapping.generatedColumn;
1327
+ prevSourceIndex = mapping.sourceIndex;
1328
+ prevOriginalLine = mapping.originalLine;
1329
+ prevOriginalColumn = mapping.originalColumn;
1330
+ }
1331
+ return lines.map((segments) => segments.join(",")).join(";");
1332
+ }
1333
+ }
1334
+
1335
+ // ../jsx/src/preprocess-inline-jsx-callbacks.ts
1336
+ import ts19 from "typescript";
1337
+
1338
+ // ../jsx/src/ssr-defaults.ts
1339
+ import ts20 from "typescript";
1340
+ var UNRESOLVED = Symbol("unresolved");
1341
+ var NO_RETURN = Symbol("no-return");
1342
+
1343
+ // ../jsx/src/augment-inherited-props.ts
1344
+ import ts21 from "typescript";
1345
+
1346
+ // ../jsx/src/rich-type-refusal.ts
1347
+ var EMPTY_BINDINGS2 = new Map;
1348
+ // ../jsx/src/shared-program.ts
1349
+ import ts22 from "typescript";
1350
+ // ../jsx/src/adapters/interface.ts
1351
+ class BaseAdapter {
1352
+ renderChildren(children) {
1353
+ return children.map((child) => this.renderNode(child)).join("");
1354
+ }
1355
+ renderAsync(node) {
1356
+ return this.renderNode(node.fallback) + this.renderChildren(node.children);
1357
+ }
1358
+ }
1359
+ // ../jsx/src/adapters/jsx-adapter.ts
1360
+ class JsxAdapter extends BaseAdapter {
1361
+ componentName = "";
1362
+ acceptsCallbackBody = () => true;
1363
+ formatImportSpecifiers(specifiers) {
1364
+ const defaultSpec = specifiers.find((s) => s.isDefault);
1365
+ const namespaceSpec = specifiers.find((s) => s.isNamespace);
1366
+ const namedSpecs = specifiers.filter((s) => !s.isDefault && !s.isNamespace);
1367
+ const parts = [];
1368
+ if (defaultSpec) {
1369
+ parts.push(defaultSpec.alias || defaultSpec.name);
1370
+ }
1371
+ if (namespaceSpec) {
1372
+ parts.push(`* as ${namespaceSpec.name}`);
1373
+ }
1374
+ if (namedSpecs.length > 0) {
1375
+ const named = namedSpecs.map((s) => s.alias ? `${s.name} as ${s.alias}` : s.name).join(", ");
1376
+ parts.push(`{ ${named} }`);
1377
+ }
1378
+ return parts.join(", ");
1379
+ }
1380
+ generateSignalInitializers(ir, jsxBody) {
1381
+ const lines = [];
1382
+ const { preserveTypes } = this.jsxConfig;
1383
+ const primaryRefs = [jsxBody];
1384
+ for (const signal of ir.metadata.signals) {
1385
+ if (signal.isModule)
1386
+ continue;
1387
+ primaryRefs.push(signal.initialValue);
1388
+ }
1389
+ for (const memo of ir.metadata.memos) {
1390
+ if (memo.isModule)
1391
+ continue;
1392
+ primaryRefs.push(memo.computation);
1393
+ }
1394
+ const primaryRefText = primaryRefs.join(`
1395
+ `);
1396
+ const localFunctions = ir.metadata.localFunctions.filter((f) => !f.isExported);
1397
+ const localConstants = ir.metadata.localConstants.filter((c) => !c.isExported && c.value);
1398
+ const declarations = [
1399
+ ...localFunctions.map((f) => ({ name: f.name, body: f.body })),
1400
+ ...localConstants.map((c) => ({ name: c.name, body: c.value }))
1401
+ ];
1402
+ const reachable = findReachableNames(primaryRefText, declarations);
1403
+ const reachableBodies = [...reachable].map((name) => {
1404
+ const func = localFunctions.find((f) => f.name === name);
1405
+ if (func)
1406
+ return func.body;
1407
+ const constant = localConstants.find((c) => c.name === name);
1408
+ return constant?.value ?? "";
1409
+ }).join(`
1410
+ `);
1411
+ const setterRefText = primaryRefText + `
1412
+ ` + reachableBodies;
1413
+ for (const signal of ir.metadata.signals) {
1414
+ if (signal.isModule)
1415
+ continue;
1416
+ if (signal.envReader) {
1417
+ const factory = signal.envFactory ?? ENV_SIGNAL_CLIENT_FACTORY[signal.envReader];
1418
+ if (factory) {
1419
+ lines.push(signal.setter ? ` const [${signal.getter}, ${signal.setter}] = ${factory}()` : ` const [${signal.getter}] = ${factory}()`);
1420
+ }
1421
+ continue;
1422
+ }
1423
+ const rawInitialValue = preserveTypes ? signal.typedInitialValue ?? signal.initialValue : signal.initialValue;
1424
+ const initialValue = rawInitialValue.trim().startsWith("{") ? `(${rawInitialValue})` : rawInitialValue;
1425
+ const needsTypeAssertion = preserveTypes && !signal.typedInitialValue && signal.type.kind !== "unknown" && signal.type.kind !== "primitive";
1426
+ if (needsTypeAssertion) {
1427
+ lines.push(` const ${signal.getter} = () => ${initialValue} as ${signal.type.raw}`);
1428
+ } else {
1429
+ lines.push(` const ${signal.getter} = () => ${initialValue}`);
1430
+ }
1431
+ if (signal.setter) {
1432
+ const setterUsed = new RegExp(`\\b${signal.setter}\\b`).test(setterRefText);
1433
+ if (setterUsed) {
1434
+ lines.push(` const ${signal.setter} = (..._args: any[]) => {}`);
1435
+ }
1436
+ }
1437
+ }
1438
+ for (const memo of ir.metadata.memos) {
1439
+ if (memo.isModule)
1440
+ continue;
1441
+ const computation = preserveTypes ? memo.typedComputation ?? memo.computation : memo.computation;
1442
+ lines.push(` const ${memo.name} = ${computation}`);
1443
+ }
1444
+ for (const constant of ir.metadata.localConstants) {
1445
+ if (constant.isExported)
1446
+ continue;
1447
+ const keyword = constant.declarationKind ?? "const";
1448
+ if (!constant.value) {
1449
+ lines.push(` ${keyword} ${constant.name}`);
1450
+ continue;
1451
+ }
1452
+ const value = constant.value.trim();
1453
+ if (/^createContext\b/.test(value) || /^new WeakMap\b/.test(value))
1454
+ continue;
1455
+ if (!reachable.has(constant.name))
1456
+ continue;
1457
+ const constValue = preserveTypes ? constant.typedValue ?? constant.value : constant.value;
1458
+ lines.push(` ${keyword} ${constant.name} = ${constValue}`);
1459
+ }
1460
+ for (const func of localFunctions) {
1461
+ if (!reachable.has(func.name))
1462
+ continue;
1463
+ const params = preserveTypes && func.typedParams !== undefined ? func.typedParams : func.params.map(formatParamWithType).join(", ");
1464
+ const returnAnnotation = preserveTypes && func.typedReturnType ? `: ${func.typedReturnType}` : "";
1465
+ const body = preserveTypes ? func.typedBody ?? func.body : func.body;
1466
+ const asyncKw = func.isAsync ? "async " : "";
1467
+ lines.push(` ${asyncKw}function ${func.name}(${params})${returnAnnotation} ${body}`);
1468
+ }
1469
+ return lines.join(`
1470
+ `);
1471
+ }
1472
+ renderNodeRaw(node) {
1473
+ if (node.type === "expression") {
1474
+ if (node.expr === "null" || node.expr === "undefined") {
1475
+ return "null";
1476
+ }
1477
+ return node.expr;
1478
+ }
1479
+ return this.renderNode(node);
1480
+ }
1481
+ renderScopeMarker(instanceIdExpr) {
1482
+ return `${BF_SCOPE}={${instanceIdExpr}}`;
1483
+ }
1484
+ renderSlotMarker(slotId) {
1485
+ return `${BF_SLOT}="${slotId}"`;
1486
+ }
1487
+ renderCondMarker(condId) {
1488
+ return `${BF_COND}="${condId}"`;
1489
+ }
1490
+ }
1491
+
1492
+ // ../jsx/src/adapters/template-imports.ts
1493
+ var CLIENT_PACKAGE_SOURCES = new Set([
1494
+ "@barefootjs/client",
1495
+ "@barefootjs/client/runtime"
1496
+ ]);
1497
+ function rewriteImportsForTemplate(imports, shimSource, rewriteRelative) {
1498
+ const remap = (imp) => {
1499
+ if (!rewriteRelative || !imp.source.startsWith("."))
1500
+ return imp;
1501
+ const next = rewriteRelative(imp.source);
1502
+ return next === imp.source ? imp : { ...imp, source: next };
1503
+ };
1504
+ if (!shimSource) {
1505
+ return imports.filter((imp) => !CLIENT_PACKAGE_SOURCES.has(imp.source)).map(remap);
1506
+ }
1507
+ const merged = new Map;
1508
+ const result = [];
1509
+ for (const imp of imports) {
1510
+ if (!CLIENT_PACKAGE_SOURCES.has(imp.source)) {
1511
+ result.push(remap(imp));
1512
+ continue;
1513
+ }
1514
+ const existing = merged.get(shimSource);
1515
+ if (existing) {
1516
+ const seen = new Set(existing.specifiers.map(specKey));
1517
+ for (const spec of imp.specifiers) {
1518
+ if (!seen.has(specKey(spec))) {
1519
+ existing.specifiers.push(spec);
1520
+ seen.add(specKey(spec));
1521
+ }
1522
+ }
1523
+ existing.isTypeOnly = existing.isTypeOnly && imp.isTypeOnly;
1524
+ } else {
1525
+ const rewritten = {
1526
+ ...imp,
1527
+ source: shimSource,
1528
+ specifiers: imp.specifiers.map((s) => ({ ...s }))
1529
+ };
1530
+ merged.set(shimSource, rewritten);
1531
+ result.push(rewritten);
1532
+ }
1533
+ }
1534
+ return result;
1535
+ }
1536
+ function specKey(s) {
1537
+ return `${s.isDefault ? "d" : ""}${s.isNamespace ? "n" : ""}:${s.name}:${s.alias ?? ""}`;
1538
+ }
1539
+
1540
+ // ../jsx/src/adapters/test-adapter.ts
1541
+ class TestAdapter extends JsxAdapter {
1542
+ name = "test";
1543
+ extension = ".test.tsx";
1544
+ jsxConfig = { preserveTypes: false };
1545
+ generate(ir) {
1546
+ this.componentName = ir.metadata.componentName;
1547
+ const imports = this.generateImports(ir);
1548
+ const types = this.generateTypes(ir);
1549
+ const component = this.generateComponent(ir);
1550
+ const defaultExport = ir.metadata.hasDefaultExport ? `
1551
+ export default ${this.componentName}` : "";
1552
+ const sections = {
1553
+ imports,
1554
+ types: types || "",
1555
+ component,
1556
+ defaultExport
1557
+ };
1558
+ const template = [imports, types, component].filter(Boolean).join(`
1559
+
1560
+ `) + defaultExport;
1561
+ return {
1562
+ template,
1563
+ sections,
1564
+ types: types || undefined,
1565
+ extension: this.extension
1566
+ };
1567
+ }
1568
+ generateImports(ir) {
1569
+ const lines = [];
1570
+ const templateImports = rewriteImportsForTemplate(ir.metadata.templateImports, undefined);
1571
+ for (const imp of templateImports) {
1572
+ if (imp.specifiers.length === 0) {
1573
+ if (!imp.isTypeOnly) {
1574
+ lines.push(`import '${imp.source}'`);
1575
+ }
1576
+ continue;
1577
+ }
1578
+ if (imp.isTypeOnly) {
1579
+ lines.push(`import type ${this.formatImportSpecifiers(imp.specifiers)} from '${imp.source}'`);
1580
+ } else {
1581
+ lines.push(`import ${this.formatImportSpecifiers(imp.specifiers)} from '${imp.source}'`);
1582
+ }
1583
+ }
1584
+ return lines.join(`
1585
+ `);
1586
+ }
1587
+ generateTypes(ir) {
1588
+ const lines = [];
1589
+ for (const typeDef of ir.metadata.typeDefinitions) {
1590
+ lines.push(typeDef.definition);
1591
+ }
1592
+ const propsTypeName = ir.metadata.propsType?.raw;
1593
+ if (propsTypeName && !ir.metadata.propsObjectName) {
1594
+ lines.push("");
1595
+ lines.push(`type ${this.componentName}PropsWithHydration = ${propsTypeName} & {`);
1596
+ lines.push(" __instanceId?: string");
1597
+ lines.push(" __bfScope?: string");
1598
+ lines.push("}");
1599
+ }
1600
+ return lines.length > 0 ? lines.join(`
1601
+ `) : null;
1602
+ }
1603
+ generateComponent(ir) {
1604
+ const name = ir.metadata.componentName;
1605
+ const propsTypeName = ir.metadata.propsType?.raw;
1606
+ const hasClientInteractivity = ir.metadata.signals.length > 0 || ir.metadata.memos.length > 0;
1607
+ const typeAnnotation = propsTypeName ? `: ${name}PropsWithHydration` : ": { __instanceId?: string; __bfScope?: string }";
1608
+ const jsxBody = this.renderNode(ir.root);
1609
+ const signalInits = this.generateSignalInitializers(ir, jsxBody);
1610
+ const scopeIdLine = hasClientInteractivity ? `(/_s\\d/.test(__bfScope || '') ? __bfScope : null) || __instanceId` : `__bfScope || __instanceId`;
1611
+ const bodyRefText = [jsxBody, signalInits, scopeIdLine].join(`
1612
+ `);
1613
+ const bfScopeAlias = /\b__bfScope\b/.test(bodyRefText) ? "__bfScope" : "__bfScope: _bfScope";
1614
+ const propsParams = ir.metadata.propsParams.map((p) => p.defaultValue ? `${p.name} = ${p.defaultValue}` : p.name).join(", ");
1615
+ const restPropsName = ir.metadata.restPropsName;
1616
+ const hydrationProps = `__instanceId, ${bfScopeAlias}`;
1617
+ const parts = [];
1618
+ if (propsParams) {
1619
+ parts.push(propsParams);
1620
+ }
1621
+ parts.push(hydrationProps);
1622
+ if (restPropsName) {
1623
+ parts.push(`...${restPropsName}`);
1624
+ }
1625
+ const fullPropsDestructure = `{ ${parts.join(", ")} }`;
1626
+ const hasRequiredProps = ir.metadata.propsParams.some((p) => !p.optional && p.defaultValue === undefined && !p.isRest);
1627
+ const propsTypeExpr = typeAnnotation.replace(/^:\s*/, "");
1628
+ const noArgDefault = hasRequiredProps ? "" : ` = {} as ${propsTypeExpr}`;
1629
+ const lines = [];
1630
+ const exportPrefix = ir.metadata.isExported === false ? "" : "export ";
1631
+ lines.push(`${exportPrefix}function ${name}(${fullPropsDestructure}${typeAnnotation}${noArgDefault}) {`);
1632
+ if (hasClientInteractivity) {
1633
+ lines.push(` const __scopeId = (/_s\\d/.test(__bfScope || '') ? __bfScope : null) || __instanceId || \`${name}_\${Math.random().toString(36).slice(2, 8)}\``);
1634
+ } else {
1635
+ lines.push(` const __scopeId = __bfScope || __instanceId || \`${name}_\${Math.random().toString(36).slice(2, 8)}\``);
1636
+ }
1637
+ if (signalInits) {
1638
+ lines.push(signalInits);
1639
+ }
1640
+ lines.push("");
1641
+ lines.push(` return (`);
1642
+ lines.push(` ${jsxBody}`);
1643
+ lines.push(` )`);
1644
+ lines.push(`}`);
1645
+ return lines.join(`
1646
+ `);
1647
+ }
1648
+ renderNode(node) {
1649
+ switch (node.type) {
1650
+ case "element":
1651
+ return this.renderElement(node);
1652
+ case "text":
1653
+ return node.value;
1654
+ case "expression":
1655
+ return this.renderExpression(node);
1656
+ case "conditional":
1657
+ return this.renderConditional(node);
1658
+ case "loop":
1659
+ return this.renderLoop(node);
1660
+ case "component":
1661
+ return this.renderComponent(node);
1662
+ case "fragment":
1663
+ return this.renderFragment(node);
1664
+ case "slot":
1665
+ return "{children}";
1666
+ default:
1667
+ return "";
1668
+ }
1669
+ }
1670
+ renderElement(element) {
1671
+ const tag = element.tag;
1672
+ const attrs = this.renderAttributes(element);
1673
+ const children = this.renderChildren(element.children);
1674
+ let hydrationAttrs = "";
1675
+ if (element.needsScope) {
1676
+ hydrationAttrs += " bf-s={__scopeId}";
1677
+ }
1678
+ if (element.slotId) {
1679
+ hydrationAttrs += ` bf="${element.slotId}"`;
1680
+ }
1681
+ if (children) {
1682
+ return `<${tag}${attrs}${hydrationAttrs}>${children}</${tag}>`;
1683
+ } else {
1684
+ return `<${tag}${attrs}${hydrationAttrs} />`;
1685
+ }
1686
+ }
1687
+ renderExpression(expr) {
1688
+ if (expr.expr === "null" || expr.expr === "undefined") {
1689
+ return "null";
1690
+ }
1691
+ if (expr.reactive && expr.slotId) {
1692
+ return `{bfText("${expr.slotId}")}{${expr.expr}}{bfTextEnd()}`;
1693
+ }
1694
+ return `{${expr.expr}}`;
1695
+ }
1696
+ renderConditional(cond) {
1697
+ const whenTrue = this.renderNodeRaw(cond.whenTrue);
1698
+ let whenFalse = this.renderNodeRaw(cond.whenFalse);
1699
+ if (!whenFalse || whenFalse === "" || whenFalse === "null") {
1700
+ whenFalse = "null";
1701
+ }
1702
+ return `{${cond.condition} ? ${whenTrue} : ${whenFalse}}`;
1703
+ }
1704
+ renderLoop(loop) {
1705
+ const indexParam = loop.index ? `, ${loop.index}` : "";
1706
+ const children = this.renderChildren(loop.children);
1707
+ const safeChildren = children.startsWith("{") ? `<>${children}</>` : children;
1708
+ const preamble = loop.preamble?.ssrText;
1709
+ if (preamble) {
1710
+ return `{${loop.array}.map((${loop.param}${indexParam}) => { ${preamble} return ${safeChildren} })}`;
1711
+ }
1712
+ return `{${loop.array}.map((${loop.param}${indexParam}) => ${safeChildren})}`;
1713
+ }
1714
+ renderComponent(comp) {
1715
+ const props = this.renderComponentProps(comp);
1716
+ const children = this.renderChildren(comp.children);
1717
+ const scopeAttr = " __bfScope={__scopeId}";
1718
+ if (children) {
1719
+ return `<${comp.name}${props}${scopeAttr}>${children}</${comp.name}>`;
1720
+ } else {
1721
+ return `<${comp.name}${props}${scopeAttr} />`;
1722
+ }
1723
+ }
1724
+ renderFragment(fragment) {
1725
+ const children = this.renderChildren(fragment.children);
1726
+ return `<>${children}</>`;
1727
+ }
1728
+ renderAttributes(element) {
1729
+ const parts = [];
1730
+ for (const attr of element.attrs) {
1731
+ const attrName = attr.name === "class" ? "className" : attr.name;
1732
+ switch (attr.value.kind) {
1733
+ case "spread":
1734
+ parts.push(`{...${attr.value.expr}}`);
1735
+ break;
1736
+ case "boolean-attr":
1737
+ parts.push(attrName);
1738
+ break;
1739
+ case "expression":
1740
+ parts.push(`${attrName}={${attr.value.expr}}`);
1741
+ break;
1742
+ case "template":
1743
+ parts.push(`${attrName}={${this.flattenTemplate(attr.value)}}`);
1744
+ break;
1745
+ case "literal":
1746
+ parts.push(`${attrName}="${attr.value.value}"`);
1747
+ break;
1748
+ case "boolean-shorthand":
1749
+ case "jsx-children":
1750
+ break;
1751
+ }
1752
+ }
1753
+ for (const event of element.events) {
1754
+ const handlerName = event.originalAttr ?? `on${event.name.charAt(0).toUpperCase()}${event.name.slice(1)}`;
1755
+ parts.push(`${handlerName}={() => {}}`);
1756
+ }
1757
+ return parts.length > 0 ? " " + parts.join(" ") : "";
1758
+ }
1759
+ flattenTemplate(value) {
1760
+ const v = value;
1761
+ return "`" + v.parts.map((p) => {
1762
+ if (p.type === "string")
1763
+ return p.value;
1764
+ if (p.type === "ternary")
1765
+ return `\${${p.condition} ? '${p.whenTrue}' : '${p.whenFalse}'}`;
1766
+ return `\${(${JSON.stringify(p.cases)})[${p.key}]}`;
1767
+ }).join("") + "`";
1768
+ }
1769
+ renderComponentProps(comp) {
1770
+ const parts = [];
1771
+ for (const prop of comp.props) {
1772
+ switch (prop.value.kind) {
1773
+ case "jsx-children": {
1774
+ const rendered = prop.value.children.map((c) => this.renderNode(c)).join("");
1775
+ parts.push(`${prop.name}={<>${rendered}</>}`);
1776
+ break;
1777
+ }
1778
+ case "spread":
1779
+ parts.push(`{...${prop.value.expr}}`);
1780
+ break;
1781
+ case "expression":
1782
+ parts.push(`${prop.name}={${prop.value.expr}}`);
1783
+ break;
1784
+ case "template":
1785
+ parts.push(`${prop.name}={${this.flattenTemplate(prop.value)}}`);
1786
+ break;
1787
+ case "boolean-shorthand":
1788
+ parts.push(prop.name);
1789
+ break;
1790
+ case "literal":
1791
+ parts.push(`${prop.name}="${prop.value.value}"`);
1792
+ break;
1793
+ case "boolean-attr":
1794
+ parts.push(prop.name);
1795
+ break;
1796
+ }
1797
+ }
1798
+ return parts.length > 0 ? " " + parts.join(" ") : "";
1799
+ }
1800
+ }
1801
+ var testAdapter = new TestAdapter;
1802
+ // ../jsx/src/query-href-lowering.ts
1803
+ function matchQueryHrefCall(callee, args, localNames) {
1804
+ if (callee.kind !== "identifier" || !localNames.has(callee.name))
1805
+ return null;
1806
+ if (args.length !== 2)
1807
+ return null;
1808
+ const [base, obj] = args;
1809
+ if (obj.kind !== "object-literal")
1810
+ return null;
1811
+ const triples = [];
1812
+ for (const p of obj.properties) {
1813
+ const v = p.value;
1814
+ if (v.kind === "conditional" && isOmitBranch(v.alternate)) {
1815
+ triples.push({ guard: v.test, key: p.key, value: v.consequent });
1816
+ } else {
1817
+ triples.push({ guard: null, key: p.key, value: v });
1818
+ }
1819
+ }
1820
+ return { base, triples };
1821
+ }
1822
+ var GUARD_BOOL_OPS = new Set([
1823
+ "==",
1824
+ "===",
1825
+ "!=",
1826
+ "!==",
1827
+ "<",
1828
+ ">",
1829
+ "<=",
1830
+ ">="
1831
+ ]);
1832
+ function isOmitBranch(node) {
1833
+ if (node.kind === "identifier")
1834
+ return node.name === "undefined";
1835
+ if (node.kind === "literal") {
1836
+ return node.literalType === "null" || node.literalType === "string" && node.value === "";
1837
+ }
1838
+ return false;
1839
+ }
1840
+ // ../jsx/src/format-date-lowering.ts
1841
+ var UTC_LITERAL = { kind: "literal", value: "UTC", literalType: "string" };
1842
+ var EMPTY_NAMES = { kind: "array-literal", elements: [], raw: "[]" };
1843
+ function matchFormatDateCall(callee, args, locals) {
1844
+ if (callee.kind !== "identifier" || !locals.has(callee.name))
1845
+ return null;
1846
+ if (args.length < 2 || args.length > 4)
1847
+ return null;
1848
+ return {
1849
+ kind: "helper-call",
1850
+ helper: "format_date",
1851
+ args: [args[0], args[1], args[2] ?? UTC_LITERAL, args[3] ?? EMPTY_NAMES]
1852
+ };
1853
+ }
1854
+ var formatDatePlugin = {
1855
+ name: "formatDate",
1856
+ prepare(metadata) {
1857
+ const locals = formatDateLocalNames(metadata);
1858
+ if (locals.size === 0)
1859
+ return null;
1860
+ return (callee, args) => matchFormatDateCall(callee, args, locals);
1861
+ }
1862
+ };
1863
+
1864
+ // ../jsx/src/builtin-lowering-plugins.ts
1865
+ var queryHrefPlugin = {
1866
+ name: "queryHref",
1867
+ prepare(metadata) {
1868
+ const locals = queryHrefLocalNames(metadata);
1869
+ if (locals.size === 0)
1870
+ return null;
1871
+ return (callee, args) => {
1872
+ const q = matchQueryHrefCall(callee, args, locals);
1873
+ return q ? { kind: "guard-list", helper: "query", base: q.base, triples: q.triples } : null;
1874
+ };
1875
+ }
1876
+ };
1877
+ var BUILTIN_LOWERING_PLUGINS = [
1878
+ queryHrefPlugin,
1879
+ datePlugin,
1880
+ formatDatePlugin,
1881
+ toLocaleDatePlugin
1882
+ ];
1883
+ function registerBuiltinLoweringPlugins() {
1884
+ for (const plugin of BUILTIN_LOWERING_PLUGINS)
1885
+ registerLoweringPlugin(plugin);
1886
+ }
1887
+ // ../jsx/src/adapters/ir-node-emitter.ts
1888
+ function emitIRNode(node, emitter, ctx) {
1889
+ const emit = (child, childCtx) => emitIRNode(child, emitter, childCtx);
1890
+ switch (node.type) {
1891
+ case "element":
1892
+ return emitter.emitElement(node, ctx, emit);
1893
+ case "text":
1894
+ return emitter.emitText(node);
1895
+ case "expression":
1896
+ return emitter.emitExpression(node);
1897
+ case "conditional":
1898
+ return emitter.emitConditional(node, ctx, emit);
1899
+ case "loop":
1900
+ return emitter.emitLoop(node, ctx, emit);
1901
+ case "component":
1902
+ return emitter.emitComponent(node, ctx, emit);
1903
+ case "fragment":
1904
+ return emitter.emitFragment(node, ctx, emit);
1905
+ case "slot":
1906
+ return emitter.emitSlot(node);
1907
+ case "if-statement":
1908
+ return emitter.emitIfStatement(node, ctx, emit);
1909
+ case "provider":
1910
+ return emitter.emitProvider(node, ctx, emit);
1911
+ case "async":
1912
+ return emitter.emitAsync(node, ctx, emit);
1913
+ default: {
1914
+ const _exhaustive = node;
1915
+ throw new Error(`emitIRNode: unhandled IRNode kind ${_exhaustive.type}`);
1916
+ }
1917
+ }
1918
+ }
1919
+ // ../jsx/src/adapters/attr-value-emitter.ts
1920
+ function emitAttrValue(value, emitter, name) {
1921
+ switch (value.kind) {
1922
+ case "literal":
1923
+ return emitter.emitLiteral(value, name);
1924
+ case "expression":
1925
+ return emitter.emitExpression(value, name);
1926
+ case "boolean-attr":
1927
+ return emitter.emitBooleanAttr(value, name);
1928
+ case "boolean-shorthand":
1929
+ return emitter.emitBooleanShorthand(value, name);
1930
+ case "template":
1931
+ return emitter.emitTemplate(value, name);
1932
+ case "spread":
1933
+ return emitter.emitSpread(value, name);
1934
+ case "jsx-children":
1935
+ return emitter.emitJsxChildren(value, name);
1936
+ default: {
1937
+ const _exhaustive = value;
1938
+ throw new Error(`emitAttrValue: unhandled AttrValue kind ${_exhaustive.kind}`);
1939
+ }
1940
+ }
1941
+ }
1942
+ // ../jsx/src/combine-client-js.ts
1943
+ import ts23 from "typescript";
1944
+ // ../jsx/src/debug.ts
1945
+ import ts24 from "typescript";
1946
+ // ../jsx/src/profiler.ts
1947
+ import ts25 from "typescript";
1948
+
1949
+ // ../jsx/src/index.ts
1950
+ registerBuiltinLoweringPlugins();
1951
+
1952
+ // src/adapter/hono-adapter.ts
1953
+ import ts26 from "typescript";
1954
+ function applyHonoLoopChain(loop) {
1955
+ return buildLoopChainExpr({
1956
+ base: loop.array,
1957
+ sortComparator: loop.sortComparator,
1958
+ filterPredicate: loop.filterPredicate,
1959
+ chainOrder: loop.chainOrder
1960
+ });
1961
+ }
1962
+ function isIdentifierName(key) {
1963
+ if (key.length === 0)
1964
+ return false;
1965
+ for (let i = 0;i < key.length; ) {
1966
+ const cp = key.codePointAt(i);
1967
+ const ok = i === 0 ? ts26.isIdentifierStart(cp, ts26.ScriptTarget.Latest) : ts26.isIdentifierPart(cp, ts26.ScriptTarget.Latest);
1968
+ if (!ok)
1969
+ return false;
1970
+ i += cp > 65535 ? 2 : 1;
1971
+ }
1972
+ return true;
1973
+ }
1974
+
1975
+ class HonoAdapter extends JsxAdapter {
1976
+ name = "hono";
1977
+ extension = ".tsx";
1978
+ clientShimSource = "@barefootjs/hono/client-shim";
1979
+ acceptsTemplateCall = () => true;
1980
+ jsxConfig = { preserveTypes: true };
1981
+ options;
1982
+ isClientComponent = false;
1983
+ hasClientInteractivity = false;
1984
+ currentComponentHasProps = false;
1985
+ rewriteRelativeImport;
1986
+ loopKeyStack = [];
1987
+ scriptAssets;
1988
+ preloadAssets;
1989
+ constructor(options = {}) {
1990
+ super();
1991
+ this.options = {
1992
+ clientJsBasePath: options.clientJsBasePath ?? "/static/components/",
1993
+ barefootJsPath: options.barefootJsPath ?? "/static/components/barefoot.js",
1994
+ clientJsFilename: options.clientJsFilename
1995
+ };
1996
+ if (options.name)
1997
+ this.name = options.name;
1998
+ }
1999
+ generate(ir, options) {
2000
+ this.componentName = ir.metadata.componentName;
2001
+ this.isClientComponent = ir.metadata.isClientComponent;
2002
+ this.rewriteRelativeImport = options?.rewriteRelativeImport;
2003
+ if (options?.skipScriptRegistration) {
2004
+ this.scriptAssets = undefined;
2005
+ this.preloadAssets = undefined;
2006
+ } else {
2007
+ this.scriptAssets = options?.scriptAssets;
2008
+ this.preloadAssets = options?.preloadAssets;
2009
+ }
2010
+ const component = this.generateComponent(ir);
2011
+ const types = this.generateTypes(ir, component);
2012
+ const componentCode = [types, component].filter(Boolean).join(`
2013
+ `);
2014
+ const imports = this.generateImports(ir, componentCode);
2015
+ const moduleConstants = this.generateModuleLevelContextBindings(ir);
2016
+ const defaultExport = ir.metadata.hasDefaultExport ? `
2017
+ export default ${this.componentName}` : "";
2018
+ const sections = {
2019
+ imports,
2020
+ types: types || "",
2021
+ component,
2022
+ defaultExport,
2023
+ moduleConstants
2024
+ };
2025
+ const template = [imports, moduleConstants, types, component].filter(Boolean).join(`
2026
+
2027
+ `) + defaultExport;
2028
+ const result = {
2029
+ template,
2030
+ sections,
2031
+ types: types || undefined,
2032
+ extension: this.extension
2033
+ };
2034
+ this.rewriteRelativeImport = undefined;
2035
+ this.scriptAssets = undefined;
2036
+ this.preloadAssets = undefined;
2037
+ return result;
2038
+ }
2039
+ hasScriptAssets() {
2040
+ return !!this.scriptAssets && this.scriptAssets.length > 0;
2041
+ }
2042
+ hasPreloadAssets() {
2043
+ return this.hasScriptAssets() && !!this.preloadAssets && this.preloadAssets.length > 0;
2044
+ }
2045
+ generateModuleLevelContextBindings(ir) {
2046
+ const lines = [];
2047
+ for (const c of ir.metadata.localConstants) {
2048
+ if (!c.isModule)
2049
+ continue;
2050
+ if (c.isExported)
2051
+ continue;
2052
+ if (c.systemConstructKind !== "createContext")
2053
+ continue;
2054
+ if (!c.value)
2055
+ continue;
2056
+ const keyword = c.declarationKind ?? "const";
2057
+ const value = this.jsxConfig.preserveTypes ? c.typedValue ?? c.value : c.value;
2058
+ lines.push(`${keyword} ${c.name} = ${value}`);
2059
+ }
2060
+ return lines.join(`
2061
+ `);
2062
+ }
2063
+ generateImports(ir, componentCode) {
2064
+ const lines = [];
2065
+ const utilImports = [];
2066
+ for (const util of ["bfComment", "bfText", "bfTextEnd"]) {
2067
+ if (new RegExp(`\\b${util}\\b`).test(componentCode)) {
2068
+ utilImports.push(util);
2069
+ }
2070
+ }
2071
+ if (utilImports.length > 0) {
2072
+ lines.push(`import { ${utilImports.join(", ")} } from '@barefootjs/hono/utils'`);
2073
+ }
2074
+ if (this.hasScriptAssets()) {
2075
+ const names = this.hasPreloadAssets() ? ["registerComponentScripts", "registerComponentPreloads", "wrapWithInlineScripts"] : ["registerComponentScripts", "wrapWithInlineScripts"];
2076
+ lines.push(`import { ${names.join(", ")} } from '@barefootjs/hono/scripts'`);
2077
+ }
2078
+ if (componentCode.includes("<__BfSuspense")) {
2079
+ lines.push(`import { Suspense as __BfSuspense } from 'hono/jsx/streaming'`);
2080
+ }
2081
+ if (componentCode.includes("<__BfErrorBoundary")) {
2082
+ lines.push(`import { ErrorBoundary as __BfErrorBoundary } from 'hono/jsx'`);
2083
+ }
2084
+ const templateImports = rewriteImportsForTemplate(ir.metadata.templateImports, this.clientShimSource, this.rewriteRelativeImport);
2085
+ for (const imp of templateImports) {
2086
+ if (imp.specifiers.length === 0) {
2087
+ if (!imp.isTypeOnly) {
2088
+ lines.push(`import '${imp.source}'`);
2089
+ }
2090
+ continue;
2091
+ }
2092
+ if (imp.isTypeOnly) {
2093
+ lines.push(`import type ${this.formatImportSpecifiers(imp.specifiers)} from '${imp.source}'`);
2094
+ } else {
2095
+ lines.push(`import ${this.formatImportSpecifiers(imp.specifiers)} from '${imp.source}'`);
2096
+ }
2097
+ }
2098
+ if (/\bprovideContextSSR\(/.test(componentCode)) {
2099
+ lines.push(`import { provideContextSSR } from '@barefootjs/hono/client-shim'`);
2100
+ }
2101
+ return lines.join(`
2102
+ `);
2103
+ }
2104
+ generateTypes(ir, componentBody) {
2105
+ const lines = [];
2106
+ if (componentBody && ir.metadata.typeDefinitions.length > 0) {
2107
+ const propsTypeName2 = this.getPropsTypeName(ir);
2108
+ const seedText = [
2109
+ componentBody,
2110
+ propsTypeName2 && !ir.metadata.propsObjectName ? propsTypeName2 : "",
2111
+ ...ir.metadata.namedExports.filter((block) => block.source === null).flatMap((block) => block.specifiers.map((s) => s.name))
2112
+ ].filter(Boolean).join(`
2113
+ `);
2114
+ const included = new Set;
2115
+ for (const typeDef of ir.metadata.typeDefinitions) {
2116
+ if (new RegExp(`\\b${typeDef.name}\\b`).test(seedText)) {
2117
+ included.add(typeDef.name);
2118
+ }
2119
+ }
2120
+ let changed = true;
2121
+ while (changed) {
2122
+ changed = false;
2123
+ for (const typeDef of ir.metadata.typeDefinitions) {
2124
+ if (included.has(typeDef.name))
2125
+ continue;
2126
+ for (const name of included) {
2127
+ const includedDef = ir.metadata.typeDefinitions.find((t) => t.name === name);
2128
+ if (includedDef && new RegExp(`\\b${typeDef.name}\\b`).test(includedDef.definition)) {
2129
+ included.add(typeDef.name);
2130
+ changed = true;
2131
+ break;
2132
+ }
2133
+ }
2134
+ }
2135
+ }
2136
+ for (const typeDef of ir.metadata.typeDefinitions) {
2137
+ if (included.has(typeDef.name))
2138
+ lines.push(typeDef.definition);
2139
+ }
2140
+ } else {
2141
+ for (const typeDef of ir.metadata.typeDefinitions) {
2142
+ lines.push(typeDef.definition);
2143
+ }
2144
+ }
2145
+ const propsTypeName = this.getPropsTypeName(ir);
2146
+ if (propsTypeName && !ir.metadata.propsObjectName) {
2147
+ lines.push("");
2148
+ lines.push(`type ${this.componentName}PropsWithHydration = ${propsTypeName} & {`);
2149
+ lines.push(" __instanceId?: string");
2150
+ lines.push(" __bfScope?: string");
2151
+ lines.push(" __bfChild?: boolean");
2152
+ lines.push(" __bfParentProps?: string");
2153
+ lines.push(" __bfParent?: string");
2154
+ lines.push(" __bfMount?: string");
2155
+ lines.push(' "data-key"?: string | number');
2156
+ lines.push("}");
2157
+ }
2158
+ return lines.length > 0 ? lines.join(`
2159
+ `) : null;
2160
+ }
2161
+ getPropsTypeName(ir) {
2162
+ if (ir.metadata.propsType?.raw) {
2163
+ return ir.metadata.propsType.raw;
2164
+ }
2165
+ return null;
2166
+ }
2167
+ generateComponent(ir) {
2168
+ const name = ir.metadata.componentName;
2169
+ const propsTypeName = this.getPropsTypeName(ir);
2170
+ const hasReactivePrimitives = ir.metadata.signals.some((s) => !s.envReader) || ir.metadata.memos.length > 0 || ir.metadata.effects.length > 0 || ir.metadata.onMounts.length > 0;
2171
+ if (hasReactivePrimitives && !ir.metadata.isClientComponent) {
2172
+ throw new Error(`Component "${name}" has reactive primitives (signals, memos, effects, or onMounts) ` + `but is not marked as a client component. Add "use client" directive at the top of the file.`);
2173
+ }
2174
+ const needsClientInit = ir.metadata.clientAnalysis?.needsInit ?? false;
2175
+ const hasClientInteractivity = ir.metadata.isClientComponent || needsClientInit;
2176
+ this.hasClientInteractivity = hasClientInteractivity;
2177
+ const propsObjectName = ir.metadata.propsObjectName;
2178
+ let fullPropsDestructure;
2179
+ let typeAnnotation;
2180
+ let propsExtraction = null;
2181
+ const HYDRATION_PROPS_TYPE = '{ __instanceId?: string; __bfScope?: string; __bfChild?: boolean; __bfParentProps?: string; __bfParent?: string; __bfMount?: string; "data-key"?: string | number }';
2182
+ if (propsObjectName) {
2183
+ fullPropsDestructure = `__allProps`;
2184
+ typeAnnotation = propsTypeName ? `: ${propsTypeName} & ${HYDRATION_PROPS_TYPE}` : `: Record<string, unknown> & ${HYDRATION_PROPS_TYPE}`;
2185
+ } else {
2186
+ fullPropsDestructure = "";
2187
+ typeAnnotation = propsTypeName ? `: ${name}PropsWithHydration` : `: ${HYDRATION_PROPS_TYPE}`;
2188
+ }
2189
+ const clientUsedProps = new Set(ir.metadata.clientAnalysis?.usedProps ?? []);
2190
+ const needsInit = ir.metadata.clientAnalysis?.needsInit ?? false;
2191
+ const propsToSerialize = ir.metadata.propsParams.filter((p) => {
2192
+ return !p.name.startsWith("on") && !p.name.startsWith("__") && clientUsedProps.has(p.name);
2193
+ });
2194
+ const hasPropsToSerialize = propsToSerialize.length > 0 && hasClientInteractivity && needsInit;
2195
+ const isIfStatement = ir.root.type === "if-statement";
2196
+ const isRootComponent = ir.root.type === "component";
2197
+ this.currentComponentHasProps = hasPropsToSerialize || hasClientInteractivity && isRootComponent;
2198
+ let jsxBody = isIfStatement ? "" : this.renderNode(ir.root, {
2199
+ isRootOfClientComponent: hasClientInteractivity && isRootComponent
2200
+ });
2201
+ if (!isIfStatement && hasClientInteractivity && isRootComponent) {
2202
+ jsxBody = this.wrapWithScopeComment(jsxBody);
2203
+ }
2204
+ const ifCode = isIfStatement ? this.renderIfStatement(ir.root, { isRootOfClientComponent: true }) : "";
2205
+ const fullBodyText = jsxBody + `
2206
+ ` + ifCode;
2207
+ const signalInits = this.generateSignalInitializers(ir, fullBodyText);
2208
+ const scopeIdLine = hasClientInteractivity ? `__instanceId` : `__bfScope || __instanceId`;
2209
+ const bodyRefText = [
2210
+ fullBodyText,
2211
+ signalInits,
2212
+ scopeIdLine,
2213
+ hasPropsToSerialize || hasClientInteractivity && isRootComponent ? "__bfParentProps" : ""
2214
+ ].join(`
2215
+ `);
2216
+ const bfScopeAlias = /\b__bfScope\b/.test(bodyRefText) ? "__bfScope" : "__bfScope: _bfScope";
2217
+ const bfChildAlias = /\b__bfChild\b/.test(bodyRefText) ? "__bfChild" : "__bfChild: _bfChild";
2218
+ const bfParentPropsAlias = /\b__bfParentProps\b/.test(bodyRefText) ? "__bfParentProps" : "__bfParentProps: _bfParentProps";
2219
+ const bfParentAlias = /\b__bfParent\b/.test(bodyRefText) ? "__bfParent" : "__bfParent: _bfParent";
2220
+ const bfMountAlias = /\b__bfMount\b/.test(bodyRefText) ? "__bfMount" : "__bfMount: _bfMount";
2221
+ const dataKeyAlias = /\b__dataKey\b/.test(bodyRefText) ? '"data-key": __dataKey' : '"data-key": _dataKey';
2222
+ if (propsObjectName) {
2223
+ propsExtraction = ` const { __instanceId, ${bfScopeAlias}, ${bfChildAlias}, ${bfParentPropsAlias}, ${bfParentAlias}, ${bfMountAlias}, ${dataKeyAlias}, ...${propsObjectName} } = __allProps`;
2224
+ } else {
2225
+ const hydrationProps = `__instanceId, ${bfScopeAlias}, ${bfChildAlias}, ${bfParentPropsAlias}, ${bfParentAlias}, ${bfMountAlias}, ${dataKeyAlias}`;
2226
+ const parts = [];
2227
+ const propsParams = ir.metadata.propsParams.map((p) => {
2228
+ const callerKey = p.sourceName ?? p.name;
2229
+ const localName = p.name;
2230
+ const binding = callerKey === localName ? localName : `${isIdentifierName(callerKey) ? callerKey : JSON.stringify(callerKey)}: ${localName}`;
2231
+ return p.defaultValue ? `${binding} = ${p.defaultValue}` : binding;
2232
+ }).join(", ");
2233
+ if (propsParams) {
2234
+ parts.push(propsParams);
2235
+ }
2236
+ parts.push(hydrationProps);
2237
+ const restPropsName = ir.metadata.restPropsName;
2238
+ if (restPropsName) {
2239
+ parts.push(`...${restPropsName}`);
2240
+ }
2241
+ fullPropsDestructure = `{ ${parts.join(", ")} }`;
2242
+ }
2243
+ const hasRequiredProps = ir.metadata.propsParams.some((p) => !p.optional && p.defaultValue === undefined && !p.isRest);
2244
+ const wantsNoArgDefault = propsObjectName ? !propsTypeName : !hasRequiredProps;
2245
+ const propsTypeExpr = typeAnnotation.replace(/^:\s*/, "");
2246
+ const noArgDefault = wantsNoArgDefault ? ` = {} as ${propsTypeExpr}` : "";
2247
+ const lines = [];
2248
+ const exportPrefix = ir.metadata.isExported === false ? "" : "export ";
2249
+ lines.push(`${exportPrefix}function ${name}(${fullPropsDestructure}${typeAnnotation}${noArgDefault}) {`);
2250
+ if (this.hasPreloadAssets()) {
2251
+ lines.push(` const __bfInlinePreloads = registerComponentPreloads(${JSON.stringify(this.preloadAssets)})`);
2252
+ }
2253
+ if (this.hasScriptAssets()) {
2254
+ lines.push(` const __bfInlineScripts = registerComponentScripts(${JSON.stringify(this.scriptAssets)})`);
2255
+ }
2256
+ if (propsExtraction) {
2257
+ lines.push(propsExtraction);
2258
+ }
2259
+ if (hasClientInteractivity) {
2260
+ lines.push(` const __scopeId = __instanceId || \`${name}_\${Math.random().toString(36).slice(2, 8)}\``);
2261
+ } else {
2262
+ lines.push(` const __scopeId = __bfScope || __instanceId || \`${name}_\${Math.random().toString(36).slice(2, 8)}\``);
2263
+ }
2264
+ if (signalInits) {
2265
+ lines.push(signalInits);
2266
+ }
2267
+ if (hasPropsToSerialize) {
2268
+ lines.push("");
2269
+ lines.push(` // Serialize props for client hydration`);
2270
+ lines.push(` const __hydrateProps: Record<string, unknown> = {}`);
2271
+ for (const p of propsToSerialize) {
2272
+ const propAccess = propsObjectName ? `${propsObjectName}.${p.name}` : p.name;
2273
+ lines.push(` if (typeof ${propAccess} !== 'function' && !(typeof ${propAccess} === 'object' && ${propAccess} !== null && 'isEscaped' in ${propAccess})) __hydrateProps['${p.name}'] = ${propAccess}`);
2274
+ }
2275
+ lines.push(` const __bfPropsJson = __bfParentProps || (Object.keys(__hydrateProps).length > 0 ? JSON.stringify(__hydrateProps) : undefined)`);
2276
+ } else if (hasClientInteractivity && isRootComponent) {
2277
+ lines.push("");
2278
+ lines.push(` const __bfPropsJson = __bfParentProps`);
2279
+ }
2280
+ lines.push("");
2281
+ if (isIfStatement) {
2282
+ lines.push(ifCode);
2283
+ lines.push(`}`);
2284
+ return lines.join(`
2285
+ `);
2286
+ }
2287
+ if (this.hasScriptAssets()) {
2288
+ lines.push(` return wrapWithInlineScripts((`);
2289
+ lines.push(` ${jsxBody}`);
2290
+ lines.push(this.hasPreloadAssets() ? ` ), __bfInlineScripts, __bfInlinePreloads)` : ` ), __bfInlineScripts)`);
2291
+ } else {
2292
+ lines.push(` return (`);
2293
+ lines.push(` ${jsxBody}`);
2294
+ lines.push(` )`);
2295
+ }
2296
+ lines.push(`}`);
2297
+ return lines.join(`
2298
+ `);
2299
+ }
2300
+ renderNode(node, ctx) {
2301
+ return emitIRNode(node, this, ctx ?? {});
2302
+ }
2303
+ emitElement(node, ctx, _emit) {
2304
+ return this.renderElement(node, ctx);
2305
+ }
2306
+ emitText(node) {
2307
+ return this.renderText(node);
2308
+ }
2309
+ emitExpression(node) {
2310
+ return this.renderExpression(node);
2311
+ }
2312
+ emitConditional(node, ctx, _emit) {
2313
+ return this.renderConditional(node, ctx);
2314
+ }
2315
+ emitLoop(node, _ctx, _emit) {
2316
+ return this.renderLoop(node);
2317
+ }
2318
+ emitComponent(node, ctx, _emit) {
2319
+ return this.renderComponent(node, ctx);
2320
+ }
2321
+ emitFragment(node, _ctx, _emit) {
2322
+ return this.renderFragment(node);
2323
+ }
2324
+ emitSlot(_node) {
2325
+ return "{children}";
2326
+ }
2327
+ emitIfStatement(_node, _ctx, _emit) {
2328
+ return "";
2329
+ }
2330
+ emitProvider(node, _ctx, _emit) {
2331
+ const children = this.renderChildren(node.children);
2332
+ const valueExpr = (() => {
2333
+ const v = node.valueProp.value;
2334
+ switch (v.kind) {
2335
+ case "literal":
2336
+ return JSON.stringify(v.value);
2337
+ case "expression":
2338
+ case "spread":
2339
+ return v.expr;
2340
+ case "template":
2341
+ return this.renderTemplateLiteralParts(v.parts);
2342
+ case "boolean-attr":
2343
+ case "boolean-shorthand":
2344
+ return "true";
2345
+ case "jsx-children":
2346
+ return "undefined";
2347
+ }
2348
+ })();
2349
+ return `<>{provideContextSSR(${node.contextName}, ${valueExpr}, <>${children}</>)}</>`;
2350
+ }
2351
+ emitAsync(node, _ctx, _emit) {
2352
+ return this.renderAsync(node);
2353
+ }
2354
+ renderElement(element, ctx) {
2355
+ const tag = element.tag;
2356
+ const attrs = this.renderAttributes(element);
2357
+ const children = this.renderChildren(element.children);
2358
+ let hydrationAttrs = "";
2359
+ if (element.needsScope) {
2360
+ hydrationAttrs += ` ${BF_SCOPE}={__scopeId}`;
2361
+ hydrationAttrs += ` {...(__bfParent ? { "${BF_HOST}": __bfParent } : {})}`;
2362
+ hydrationAttrs += ` {...(__bfMount ? { "${BF_AT}": __bfMount } : {})}`;
2363
+ hydrationAttrs += ` {...(!__bfChild ? { "${BF_ROOT}": "" } : {})}`;
2364
+ if (this.currentComponentHasProps) {
2365
+ hydrationAttrs += ` {...(!__bfChild && __bfPropsJson ? { "${BF_PROPS}": __bfPropsJson } : {})}`;
2366
+ }
2367
+ hydrationAttrs += ' {...(__dataKey !== undefined ? { "data-key": __dataKey } : {})}';
2368
+ }
2369
+ if (ctx?.isLoopItemRoot && this.loopKeyStack.length > 0) {
2370
+ const loop = this.loopKeyStack[this.loopKeyStack.length - 1];
2371
+ if (loop.key) {
2372
+ const keyAttrName2 = this.loopKeyStack.length === 1 ? "data-key" : `data-key-${this.loopKeyStack.length - 1}`;
2373
+ hydrationAttrs += ` ${keyAttrName2}={String(${loop.key})}`;
2374
+ }
2375
+ }
2376
+ if (element.slotId) {
2377
+ hydrationAttrs += ` bf="${element.slotId}"`;
2378
+ }
2379
+ if (element.regionId) {
2380
+ hydrationAttrs += ` ${BF_REGION}="${element.regionId}"`;
2381
+ }
2382
+ if (children) {
2383
+ return `<${tag}${attrs}${hydrationAttrs}>${children}</${tag}>`;
2384
+ } else {
2385
+ return `<${tag}${attrs}${hydrationAttrs} />`;
2386
+ }
2387
+ }
2388
+ renderText(text) {
2389
+ return escapeHtml(text.value).replace(/\{/g, "&#123;").replace(/\}/g, "&#125;");
2390
+ }
2391
+ renderExpression(expr) {
2392
+ if (expr.expr === "null" || expr.expr === "undefined") {
2393
+ return "null";
2394
+ }
2395
+ if (expr.clientOnly && expr.slotId) {
2396
+ if (expr.markerless)
2397
+ return "";
2398
+ return `{bfText("${expr.slotId}")}{bfTextEnd()}`;
2399
+ }
2400
+ if (expr.slotId) {
2401
+ return `{bfText("${expr.slotId}")}{${expr.expr}}{bfTextEnd()}`;
2402
+ }
2403
+ return `{${expr.expr}}`;
2404
+ }
2405
+ renderConditional(cond, ctx) {
2406
+ if (cond.clientOnly && cond.slotId) {
2407
+ return `{bfComment("cond-start:${cond.slotId}")}{bfComment("cond-end:${cond.slotId}")}`;
2408
+ }
2409
+ const branchCtx = ctx?.isLoopItemRoot ? { isLoopItemRoot: true } : undefined;
2410
+ const whenTrue = this.renderNodeRawCtx(cond.whenTrue, branchCtx);
2411
+ let whenFalse = this.renderNodeRawCtx(cond.whenFalse, branchCtx);
2412
+ if (!whenFalse || whenFalse === "" || whenFalse === "null") {
2413
+ whenFalse = "null";
2414
+ }
2415
+ if (cond.slotId) {
2416
+ const trueWithMarker = this.wrapWithCondMarker(cond.whenTrue, whenTrue, cond.slotId);
2417
+ const falseWithMarker = cond.whenFalse.type === "expression" && cond.whenFalse.expr === "null" ? `<>{bfComment("cond-start:${cond.slotId}")}{bfComment("cond-end:${cond.slotId}")}</>` : this.wrapWithCondMarker(cond.whenFalse, whenFalse, cond.slotId);
2418
+ return `{${cond.condition} ? ${trueWithMarker} : ${falseWithMarker}}`;
2419
+ }
2420
+ return `{${cond.condition} ? ${whenTrue} : ${whenFalse}}`;
2421
+ }
2422
+ renderNodeRawCtx(node, ctx) {
2423
+ if (node.type === "expression") {
2424
+ if (node.expr === "null" || node.expr === "undefined")
2425
+ return "null";
2426
+ return node.expr;
2427
+ }
2428
+ return this.renderNode(node, ctx);
2429
+ }
2430
+ wrapWithCondMarker(node, content, condId) {
2431
+ if (node.type === "component") {
2432
+ return `<>{bfComment("cond-start:${condId}")}${content}{bfComment("cond-end:${condId}")}</>`;
2433
+ }
2434
+ if (content.startsWith("<") && node.type !== "fragment") {
2435
+ const match = content.match(/^<(\w+)/);
2436
+ if (match) {
2437
+ return content.replace(`<${match[1]}`, `<${match[1]} bf-c="${condId}"`);
2438
+ }
2439
+ }
2440
+ if (node.type === "expression") {
2441
+ const exprSlotId = node.slotId;
2442
+ const inner = exprSlotId ? `{bfText("${exprSlotId}")}{${content}}{bfTextEnd()}` : `{${content}}`;
2443
+ return `<>{bfComment("cond-start:${condId}")}${inner}{bfComment("cond-end:${condId}")}</>`;
2444
+ }
2445
+ return `<>{bfComment("cond-start:${condId}")}${content}{bfComment("cond-end:${condId}")}</>`;
2446
+ }
2447
+ renderLoop(loop) {
2448
+ if (loop.clientOnly) {
2449
+ return `{bfComment('loop:${loop.markerId}')}{bfComment('/loop:${loop.markerId}')}`;
2450
+ }
2451
+ const paramAnnotation = loop.paramType ? `: ${loop.paramType}` : "";
2452
+ const indexAnnotation = loop.indexType ? `: ${loop.indexType}` : "";
2453
+ const indexParam = loop.index ? `, ${loop.index}${indexAnnotation}` : "";
2454
+ this.loopKeyStack.push({ key: loop.key, param: loop.param });
2455
+ const children = this.renderChildrenInLoop(loop.children);
2456
+ this.loopKeyStack.pop();
2457
+ let mapExpr;
2458
+ const preamble = loop.preamble?.ssrText;
2459
+ let safeChildren = children.startsWith("{") ? `<>${children}</>` : children;
2460
+ if (loop.bodyIsMultiRoot) {
2461
+ safeChildren = `<>{bfComment('bf-loop-i')}${children}</>`;
2462
+ } else if (loop.bodyIsItemConditional && loop.key) {
2463
+ safeChildren = `<>{bfComment('loop-i:' + String(${loop.key}))}${children}</>`;
2464
+ }
2465
+ let chainedArray = applyHonoLoopChain(loop);
2466
+ const iterMethod = loop.method ?? "map";
2467
+ let callbackParam;
2468
+ if (loop.iterationShape === "entries" && loop.index) {
2469
+ chainedArray = `[...${chainedArray}.entries()]`;
2470
+ callbackParam = `([${loop.index}${indexAnnotation}, ${loop.param}${paramAnnotation}])`;
2471
+ } else if (loop.iterationShape === "keys") {
2472
+ chainedArray = `[...${chainedArray}.keys()]`;
2473
+ callbackParam = `(${loop.param}${paramAnnotation})`;
2474
+ } else if (loop.objectIteration === "entries") {
2475
+ chainedArray = `Object.entries(${chainedArray})`;
2476
+ callbackParam = loop.index ? `([${loop.index}${indexAnnotation}, ${loop.param}${paramAnnotation}])` : `(${loop.param}${paramAnnotation}${indexParam})`;
2477
+ } else if (loop.objectIteration === "keys") {
2478
+ chainedArray = `Object.keys(${chainedArray})`;
2479
+ callbackParam = `(${loop.param}${paramAnnotation})`;
2480
+ } else if (loop.objectIteration === "values") {
2481
+ chainedArray = `Object.values(${chainedArray})`;
2482
+ callbackParam = `(${loop.param}${paramAnnotation})`;
2483
+ } else {
2484
+ callbackParam = `(${loop.param}${paramAnnotation}${indexParam})`;
2485
+ }
2486
+ if (loop.flatMapCallback) {
2487
+ mapExpr = `{${chainedArray}.flatMap(${loop.flatMapCallback.params} => ${loop.flatMapCallback.rawBody})}`;
2488
+ } else if (preamble) {
2489
+ mapExpr = `{${chainedArray}.${iterMethod}(${callbackParam} => { ${preamble} return ${safeChildren} })}`;
2490
+ } else {
2491
+ mapExpr = `{${chainedArray}.${iterMethod}(${callbackParam} => ${safeChildren})}`;
2492
+ }
2493
+ return `{bfComment('loop:${loop.markerId}')}${mapExpr}{bfComment('/loop:${loop.markerId}')}`;
2494
+ }
2495
+ renderChildrenInLoop(children) {
2496
+ return children.map((child) => this.renderNode(child, { isLoopItemRoot: true })).join("");
2497
+ }
2498
+ renderIfStatement(ifStmt, ctx) {
2499
+ const lines = [];
2500
+ for (const v of ifStmt.scopeVariables) {
2501
+ const init = this.jsxConfig.preserveTypes && v.typedInitializer || v.initializer;
2502
+ lines.push(` const ${v.name} = ${init}`);
2503
+ }
2504
+ const consequent = this.renderNode(ifStmt.consequent, ctx);
2505
+ const wrap = this.hasScriptAssets();
2506
+ const wrapPreload = this.hasPreloadAssets();
2507
+ const openReturn = wrap ? " return wrapWithInlineScripts((" : " return (";
2508
+ const closeReturn = wrap ? wrapPreload ? " ), __bfInlineScripts, __bfInlinePreloads)" : " ), __bfInlineScripts)" : " )";
2509
+ lines.unshift(` if (${ifStmt.condition}) {`);
2510
+ lines.push(openReturn);
2511
+ lines.push(` ${consequent}`);
2512
+ lines.push(closeReturn);
2513
+ lines.push(` }`);
2514
+ if (ifStmt.alternate) {
2515
+ if (ifStmt.alternate.type === "if-statement") {
2516
+ const elseIfCode = this.renderIfStatement(ifStmt.alternate, ctx);
2517
+ lines.push(elseIfCode.replace(/^\s*if/, " else if"));
2518
+ } else {
2519
+ const alternate = this.renderNode(ifStmt.alternate, ctx);
2520
+ lines.push(wrap ? " return wrapWithInlineScripts((" : " return (");
2521
+ lines.push(` ${alternate}`);
2522
+ lines.push(wrap ? wrapPreload ? " ), __bfInlineScripts, __bfInlinePreloads)" : " ), __bfInlineScripts)" : " )");
2523
+ }
2524
+ } else {
2525
+ lines.push(` return null`);
2526
+ }
2527
+ return lines.join(`
2528
+ `);
2529
+ }
2530
+ renderAsync(node) {
2531
+ const fallback = this.renderNode(node.fallback);
2532
+ const children = this.renderChildren(node.children);
2533
+ return `<__BfErrorBoundary fallback={<>${fallback}</>}>` + `<__BfSuspense fallback={<>${fallback}</>}>${children}</__BfSuspense>` + `</__BfErrorBoundary>`;
2534
+ }
2535
+ renderComponent(comp, ctx) {
2536
+ const props = this.renderComponentProps(comp);
2537
+ const children = this.renderChildren(comp.children);
2538
+ let scopeAttr;
2539
+ const bfChildAttr = comp.slotId && this.hasClientInteractivity ? " __bfChild={true}" : "";
2540
+ const bfMountAttr = comp.slotId ? ` __bfParent={__scopeId} __bfMount={'${comp.slotId}'}` : "";
2541
+ if (ctx?.isRootOfClientComponent) {
2542
+ const propsPassAttr = this.currentComponentHasProps ? " __bfParentProps={__bfPropsJson}" : "";
2543
+ if (comp.slotId) {
2544
+ scopeAttr = ` __instanceId={\`\${__scopeId}_${comp.slotId}\`}${propsPassAttr}${bfMountAttr}`;
2545
+ } else {
2546
+ scopeAttr = ` __instanceId={__scopeId}${propsPassAttr}`;
2547
+ }
2548
+ scopeAttr += ` ${BF_SCOPE}={__scopeId}`;
2549
+ } else if (comp.loopItemRoot) {
2550
+ if (comp.slotId) {
2551
+ scopeAttr = ` __bfScope={\`\${__scopeId}_${comp.slotId}\`}${bfChildAttr}${bfMountAttr}`;
2552
+ } else {
2553
+ scopeAttr = " __bfScope={__scopeId}";
2554
+ }
2555
+ } else if (comp.slotId) {
2556
+ scopeAttr = ` __instanceId={\`\${__scopeId}_${comp.slotId}\`}${bfChildAttr}${bfMountAttr}`;
2557
+ } else {
2558
+ scopeAttr = " __instanceId={__scopeId}";
2559
+ }
2560
+ if (children) {
2561
+ return `<${comp.name}${props}${scopeAttr}>${children}</${comp.name}>`;
2562
+ } else {
2563
+ return `<${comp.name}${props}${scopeAttr} />`;
2564
+ }
2565
+ }
2566
+ renderFragment(fragment) {
2567
+ const children = this.renderChildren(fragment.children);
2568
+ if (fragment.needsScopeComment) {
2569
+ return this.wrapWithScopeComment(children);
2570
+ }
2571
+ return `<>${children}</>`;
2572
+ }
2573
+ wrapWithScopeComment(body) {
2574
+ const hostExpr = '${__bfParent ? `|h=${__bfParent}|m=${__bfMount}` : ""}';
2575
+ const propsExpr = this.currentComponentHasProps ? '${__bfPropsJson ? `|${__bfPropsJson}` : ""}' : "";
2576
+ return `<>{bfComment(\`scope:\${__scopeId}${hostExpr}${propsExpr}\`)}${body}{bfComment(\`/scope:\${__scopeId}\`)}</>`;
2577
+ }
2578
+ elementAttrEmitter = {
2579
+ emitLiteral: (value, name) => `${name}="${escapeHtml(value.value)}"`,
2580
+ emitExpression: (value, name) => {
2581
+ if (isBooleanAttr(name) || value.presenceOrUndefined) {
2582
+ return `${name}={(${value.expr}) || undefined}`;
2583
+ }
2584
+ return `${name}={${value.expr}}`;
2585
+ },
2586
+ emitBooleanAttr: (_value, name) => name,
2587
+ emitBooleanShorthand: () => "",
2588
+ emitTemplate: (value, name) => `${name}={${this.renderTemplateLiteralParts(value.parts)}}`,
2589
+ emitSpread: (value) => `{...${value.expr}}`,
2590
+ emitJsxChildren: () => ""
2591
+ };
2592
+ componentPropEmitter = {
2593
+ emitLiteral: (value, name) => `${name}="${escapeHtml(value.value)}"`,
2594
+ emitExpression: (value, name) => `${name}={${value.expr}}`,
2595
+ emitBooleanAttr: (_value, name) => name,
2596
+ emitBooleanShorthand: (_value, name) => name,
2597
+ emitTemplate: (value, name) => `${name}={${this.renderTemplateLiteralParts(value.parts)}}`,
2598
+ emitSpread: (value) => `{...${value.expr}}`,
2599
+ emitJsxChildren: (value, name) => {
2600
+ const rendered = value.children.map((c) => this.renderNode(c)).join("");
2601
+ return `${name}={<>${rendered}</>}`;
2602
+ }
2603
+ };
2604
+ renderAttributes(element) {
2605
+ const parts = [];
2606
+ for (const attr of element.attrs) {
2607
+ if (attr.clientOnly)
2608
+ continue;
2609
+ const jsxName = attr.name === "class" ? "className" : attr.name;
2610
+ const lowered = emitAttrValue(attr.value, this.elementAttrEmitter, jsxName);
2611
+ if (lowered)
2612
+ parts.push(lowered);
2613
+ }
2614
+ for (const event of element.events) {
2615
+ const handlerName = event.originalAttr ?? `on${event.name.charAt(0).toUpperCase()}${event.name.slice(1)}`;
2616
+ parts.push(`${handlerName}={() => {}}`);
2617
+ }
2618
+ return parts.length > 0 ? " " + parts.join(" ") : "";
2619
+ }
2620
+ renderComponentProps(comp) {
2621
+ const parts = [];
2622
+ let keyValue = null;
2623
+ for (const prop of comp.props) {
2624
+ if (prop.name === "key") {
2625
+ keyValue = this.attrValueToJsExpr(prop.value);
2626
+ continue;
2627
+ }
2628
+ const lowered = emitAttrValue(prop.value, this.componentPropEmitter, prop.name);
2629
+ if (lowered)
2630
+ parts.push(lowered);
2631
+ }
2632
+ if (keyValue) {
2633
+ parts.push(`data-key={${keyValue}}`);
2634
+ }
2635
+ return parts.length > 0 ? " " + parts.join(" ") : "";
2636
+ }
2637
+ attrValueToJsExpr(value) {
2638
+ switch (value.kind) {
2639
+ case "literal":
2640
+ return JSON.stringify(value.value);
2641
+ case "expression":
2642
+ case "spread":
2643
+ return value.expr;
2644
+ case "template":
2645
+ return this.renderTemplateLiteralParts(value.parts);
2646
+ case "boolean-shorthand":
2647
+ case "boolean-attr":
2648
+ return "true";
2649
+ case "jsx-children":
2650
+ return "undefined";
2651
+ }
2652
+ }
2653
+ renderTemplateLiteralParts(parts) {
2654
+ let output = "`";
2655
+ for (const part of parts) {
2656
+ if (part.type === "string") {
2657
+ output += part.value;
2658
+ } else if (part.type === "ternary") {
2659
+ output += `\${${part.condition} ? '${part.whenTrue}' : '${part.whenFalse}'}`;
2660
+ } else if (part.type === "lookup") {
2661
+ const obj = "{" + Object.entries(part.cases).map(([k, v]) => `${JSON.stringify(k)}: ${JSON.stringify(v)}`).join(", ") + "}";
2662
+ output += `\${(${obj})[${part.key}]}`;
2663
+ }
2664
+ }
2665
+ output += "`";
2666
+ return output;
2667
+ }
2668
+ }
2669
+ var honoAdapter = new HonoAdapter;
2670
+ // src/vite.ts
2671
+ async function writeIfChanged(absPath, content, label) {
2672
+ const prev = await readFile(absPath, "utf-8").catch(() => null);
2673
+ if (prev === content)
2674
+ return;
2675
+ await mkdir(dirname(absPath), { recursive: true });
2676
+ await writeFile(absPath, content);
2677
+ console.log(`Generated: ${label}`);
2678
+ }
2679
+ function resolveAssetUrl(ctx, config, devServer, entryRelPath, manifest) {
2680
+ const absPath = resolve(ctx.projectDir, entryRelPath);
2681
+ if (ctx.mode === "dev") {
2682
+ if (!devServer)
2683
+ throw new Error(`[hono/vite] asset "${entryRelPath}": dev server not ready`);
2684
+ return devModuleUrl(config, resolveDevOrigin(devServer), absPath);
2685
+ }
2686
+ const manifestKey = toPosixRelative(config.root, absPath);
2687
+ const [url] = resolveScriptAssets(manifest ?? {}, manifestKey, config.base);
2688
+ if (!url) {
2689
+ throw new Error(`[hono/vite] asset "${entryRelPath}" was not found in the build manifest. ` + `Did you also add it to build.rollupOptions.input?`);
2690
+ }
2691
+ return url;
2692
+ }
2693
+ async function writeAssetMap(ctx, config, devServer, assets, assetsOutputFile) {
2694
+ const keys = Object.keys(assets);
2695
+ if (keys.length === 0)
2696
+ return;
2697
+ const manifest = ctx.mode === "build" ? await loadManifest(ctx.outDir, config.build.manifest) : undefined;
2698
+ const entries = keys.map((name) => ` ${JSON.stringify(name)}: ${JSON.stringify(resolveAssetUrl(ctx, config, devServer, assets[name], manifest))},`).join(`
2699
+ `);
2700
+ const content = [
2701
+ `// Code generated by BarefootJS. DO NOT EDIT.`,
2702
+ "",
2703
+ `/**`,
2704
+ ` * Maps a logical asset name (this map's key) to its resolved URL for`,
2705
+ ` * the current build: a Vite dev-server origin URL in dev, a`,
2706
+ ` * content-hashed manifest path in production. Regenerated by`,
2707
+ ` * @barefootjs/hono/vite's afterEmit hook every time templates are`,
2708
+ ` * (re)emitted.`,
2709
+ ` */`,
2710
+ `export const Assets: Record<string, string> = {`,
2711
+ entries,
2712
+ `}`
2713
+ ].join(`
2714
+ `) + `
2715
+ `;
2716
+ await writeIfChanged(resolve(ctx.projectDir, assetsOutputFile), content, assetsOutputFile);
2717
+ }
2718
+ function barefoot(options) {
2719
+ const assets = options.assets ?? {};
2720
+ const assetsOutputFile = options.assetsOutputFile ?? "dist/bf-assets.ts";
2721
+ let resolvedConfig;
2722
+ let devServer;
2723
+ const core = coreBarefoot({
2724
+ adapter: new HonoAdapter(options.adapterOptions),
2725
+ components: options.components,
2726
+ templates: options.templates,
2727
+ async afterEmit(ctx) {
2728
+ if (Object.keys(assets).length > 0 && resolvedConfig) {
2729
+ await writeAssetMap(ctx, resolvedConfig, devServer, assets, assetsOutputFile);
2730
+ }
2731
+ }
2732
+ });
2733
+ if (Object.keys(assets).length === 0)
2734
+ return [core];
2735
+ const honoAssetsConfigCapture = {
2736
+ name: "barefoot-hono-assets-config-capture",
2737
+ configResolved(config) {
2738
+ resolvedConfig = config;
2739
+ },
2740
+ configureServer(server) {
2741
+ devServer = server;
2742
+ }
2743
+ };
2744
+ return [core, honoAssetsConfigCapture];
2745
+ }
2746
+ export {
2747
+ barefoot as default,
2748
+ barefoot
2749
+ };