@fluixi/compiler 1.0.0-alpha.82 → 1.0.0-alpha.84

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (188) hide show
  1. package/dist/analyze/expr-shape.cjs +62 -1
  2. package/dist/analyze/expr-shape.d.cts +14 -0
  3. package/dist/analyze/expr-shape.mjs +41 -1
  4. package/dist/analyze/intrinsics.cjs +80 -1
  5. package/dist/analyze/intrinsics.d.cts +66 -0
  6. package/dist/analyze/intrinsics.mjs +59 -1
  7. package/dist/analyze/paren.cjs +134 -0
  8. package/dist/analyze/paren.d.cts +23 -0
  9. package/dist/analyze/paren.d.ts +24 -0
  10. package/dist/analyze/paren.d.ts.map +1 -0
  11. package/dist/analyze/paren.js +168 -0
  12. package/dist/analyze/paren.mjs +113 -0
  13. package/dist/analyze/props-destructure.cjs +226 -1
  14. package/dist/analyze/props-destructure.d.cts +83 -0
  15. package/dist/analyze/props-destructure.mjs +205 -1
  16. package/dist/analyze/reactive-bindings.cjs +190 -1
  17. package/dist/analyze/reactive-bindings.d.cts +42 -0
  18. package/dist/analyze/reactive-bindings.mjs +167 -1
  19. package/dist/analyze/reactive-expr.cjs +38 -1
  20. package/dist/analyze/reactive-expr.d.cts +38 -0
  21. package/dist/analyze/reactive-expr.mjs +17 -1
  22. package/dist/analyze/static-graph.cjs +811 -0
  23. package/dist/analyze/static-graph.d.cts +102 -0
  24. package/dist/analyze/static-graph.d.ts +103 -0
  25. package/dist/analyze/static-graph.d.ts.map +1 -0
  26. package/dist/analyze/static-graph.js +869 -0
  27. package/dist/analyze/static-graph.mjs +793 -0
  28. package/dist/babel-NRW4EFTG.mjs +636 -0
  29. package/dist/chunk-3YKZ4GNH.mjs +11 -0
  30. package/dist/chunk-EZR7NZOY.mjs +1718 -0
  31. package/dist/chunk-FSSWUXUR.mjs +16 -0
  32. package/dist/chunk-MJV3UXIL.mjs +158 -0
  33. package/dist/chunk-R2VHAZAX.mjs +1078 -0
  34. package/dist/codegen/backend.cjs +18 -1
  35. package/dist/codegen/backend.d.cts +35 -0
  36. package/dist/codegen/backends/imperative.cjs +542 -1
  37. package/dist/codegen/backends/imperative.d.cts +11 -0
  38. package/dist/codegen/backends/imperative.d.ts.map +1 -1
  39. package/dist/codegen/backends/imperative.js +68 -13
  40. package/dist/codegen/backends/imperative.mjs +519 -1
  41. package/dist/codegen/contract.cjs +52 -1
  42. package/dist/codegen/contract.d.cts +24 -0
  43. package/dist/codegen/contract.mjs +31 -1
  44. package/dist/codegen/partial-template.cjs +176 -1
  45. package/dist/codegen/partial-template.d.cts +61 -0
  46. package/dist/codegen/partial-template.mjs +153 -1
  47. package/dist/codegen/serialize-static.cjs +125 -1
  48. package/dist/codegen/serialize-static.d.cts +38 -0
  49. package/dist/codegen/serialize-static.d.ts +16 -0
  50. package/dist/codegen/serialize-static.d.ts.map +1 -1
  51. package/dist/codegen/serialize-static.js +25 -0
  52. package/dist/codegen/serialize-static.mjs +104 -1
  53. package/dist/frontend/babel/build-ir-lit.cjs +1509 -1
  54. package/dist/frontend/babel/build-ir-lit.d.cts +26 -0
  55. package/dist/frontend/babel/build-ir-lit.mjs +1478 -1
  56. package/dist/frontend/babel/build-ir.cjs +1524 -1
  57. package/dist/frontend/babel/build-ir.d.cts +35 -0
  58. package/dist/frontend/babel/build-ir.mjs +1495 -1
  59. package/dist/frontend/babel/index.cjs +2186 -1
  60. package/dist/frontend/babel/index.d.cts +33 -0
  61. package/dist/frontend/babel/index.mjs +2156 -1
  62. package/dist/frontend/babel/lower-template.cjs +1507 -1
  63. package/dist/frontend/babel/lower-template.d.cts +23 -0
  64. package/dist/frontend/babel/lower-template.mjs +1478 -1
  65. package/dist/frontend/babel/plugin.cjs +2132 -1
  66. package/dist/frontend/babel/plugin.d.cts +95 -0
  67. package/dist/frontend/babel/plugin.mjs +2103 -1
  68. package/dist/frontend/babel/server-functions.cjs +110 -1
  69. package/dist/frontend/babel/server-functions.d.cts +10 -0
  70. package/dist/frontend/babel/server-functions.mjs +89 -1
  71. package/dist/frontend/babel/types.cjs +18 -1
  72. package/dist/frontend/babel/types.d.cts +33 -0
  73. package/dist/frontend/types.cjs +18 -1
  74. package/dist/frontend/types.d.cts +25 -0
  75. package/dist/frontend/vocabulary.cjs +98 -0
  76. package/dist/frontend/vocabulary.d.cts +79 -0
  77. package/dist/frontend/vocabulary.d.ts +80 -0
  78. package/dist/frontend/vocabulary.d.ts.map +1 -0
  79. package/dist/frontend/vocabulary.js +124 -0
  80. package/dist/frontend/vocabulary.mjs +77 -0
  81. package/dist/index.cjs +1594 -13
  82. package/dist/index.d.cts +27 -0
  83. package/dist/index.d.ts.map +1 -1
  84. package/dist/index.js +3 -0
  85. package/dist/index.mjs +1574 -13
  86. package/dist/integrations.cjs +4307 -25
  87. package/dist/integrations.d.cts +215 -0
  88. package/dist/integrations.d.ts +16 -0
  89. package/dist/integrations.d.ts.map +1 -1
  90. package/dist/integrations.js +21 -2
  91. package/dist/integrations.mjs +531 -17
  92. package/dist/ir/nodes.cjs +18 -1
  93. package/dist/ir/nodes.d.cts +168 -0
  94. package/dist/ir/nodes.d.ts +46 -0
  95. package/dist/ir/nodes.d.ts.map +1 -1
  96. package/dist/lower/compile-template.cjs +1356 -1
  97. package/dist/lower/compile-template.d.cts +69 -0
  98. package/dist/lower/compile-template.d.ts +12 -0
  99. package/dist/lower/compile-template.d.ts.map +1 -1
  100. package/dist/lower/compile-template.js +5 -1
  101. package/dist/lower/compile-template.mjs +1336 -1
  102. package/dist/lower/jsx.cjs +529 -1
  103. package/dist/lower/jsx.d.cts +25 -0
  104. package/dist/lower/jsx.d.ts +2 -0
  105. package/dist/lower/jsx.d.ts.map +1 -1
  106. package/dist/lower/jsx.js +27 -4
  107. package/dist/lower/jsx.mjs +506 -1
  108. package/dist/lower/template.cjs +1061 -1
  109. package/dist/lower/template.d.cts +53 -0
  110. package/dist/lower/template.d.ts +14 -1
  111. package/dist/lower/template.d.ts.map +1 -1
  112. package/dist/lower/template.js +106 -19
  113. package/dist/lower/template.mjs +1042 -1
  114. package/dist/lower/text.cjs +42 -1
  115. package/dist/lower/text.d.cts +10 -0
  116. package/dist/lower/text.mjs +21 -1
  117. package/dist/optimize/analyze-static.cjs +112 -1
  118. package/dist/optimize/analyze-static.d.cts +39 -0
  119. package/dist/optimize/analyze-static.mjs +91 -1
  120. package/dist/optimize/collapse-strategies.cjs +90 -1
  121. package/dist/optimize/collapse-strategies.d.cts +30 -0
  122. package/dist/optimize/collapse-strategies.mjs +67 -1
  123. package/dist/options.cjs +33 -1
  124. package/dist/options.d.cts +39 -0
  125. package/dist/options.mjs +12 -1
  126. package/dist/resolve/builtins.cjs +73 -1
  127. package/dist/resolve/builtins.d.cts +68 -0
  128. package/dist/resolve/builtins.mjs +53 -1
  129. package/dist/resolve/component-globals.cjs +233 -13
  130. package/dist/resolve/component-globals.d.cts +80 -0
  131. package/dist/resolve/component-globals.mjs +210 -13
  132. package/dist/resolve/component-resolver.cjs +80 -1
  133. package/dist/resolve/component-resolver.d.cts +68 -0
  134. package/dist/resolve/component-resolver.mjs +59 -1
  135. package/dist/resolve/load-directive.cjs +93 -1
  136. package/dist/resolve/load-directive.d.cts +53 -0
  137. package/dist/resolve/load-directive.mjs +72 -1
  138. package/dist/resolve/resolve-ir.cjs +108 -1
  139. package/dist/resolve/resolve-ir.d.cts +53 -0
  140. package/dist/resolve/resolve-ir.mjs +85 -1
  141. package/dist/resolve/write-globals.cjs +318 -13
  142. package/dist/resolve/write-globals.d.cts +30 -0
  143. package/dist/resolve/write-globals.mjs +297 -13
  144. package/dist/server-fns-4ZXN6DYU.mjs +78 -0
  145. package/dist/server-functions-V6D6DRIA.mjs +82 -0
  146. package/dist/transform/bindings.cjs +71 -1
  147. package/dist/transform/bindings.d.cts +16 -0
  148. package/dist/transform/bindings.mjs +50 -1
  149. package/dist/transform/index.cjs +2732 -8
  150. package/dist/transform/index.d.cts +15 -0
  151. package/dist/transform/index.mjs +3773 -17
  152. package/dist/transform/intrinsics.cjs +216 -3
  153. package/dist/transform/intrinsics.d.cts +21 -0
  154. package/dist/transform/intrinsics.mjs +193 -3
  155. package/dist/transform/props.cjs +441 -3
  156. package/dist/transform/props.d.cts +45 -0
  157. package/dist/transform/props.mjs +1482 -12
  158. package/dist/transform/server-fn-id.cjs +35 -1
  159. package/dist/transform/server-fn-id.d.cts +9 -0
  160. package/dist/transform/server-fn-id.mjs +14 -1
  161. package/dist/transform/server-fns.cjs +114 -2
  162. package/dist/transform/server-fns.d.cts +12 -0
  163. package/dist/transform/server-fns.mjs +1155 -11
  164. package/dist/transform/source-locations.cjs +330 -0
  165. package/dist/transform/source-locations.d.cts +43 -0
  166. package/dist/transform/source-locations.d.ts +44 -0
  167. package/dist/transform/source-locations.d.ts.map +1 -0
  168. package/dist/transform/source-locations.js +238 -0
  169. package/dist/transform/source-locations.mjs +307 -0
  170. package/dist/transform/templates.cjs +2701 -7
  171. package/dist/transform/templates.d.cts +69 -0
  172. package/dist/transform/templates.d.ts +12 -4
  173. package/dist/transform/templates.d.ts.map +1 -1
  174. package/dist/transform/templates.js +72 -7
  175. package/dist/transform/templates.mjs +3743 -16
  176. package/dist/transform-BT4MMASR.mjs +893 -0
  177. package/dist/tsconfig.lib.tsbuildinfo +1 -1
  178. package/package.json +6 -5
  179. package/dist/babel-4JUDAR2G.mjs +0 -1
  180. package/dist/chunk-3SAEGOMQ.mjs +0 -1
  181. package/dist/chunk-IBRM4W7I.mjs +0 -10
  182. package/dist/chunk-OHHZCYIQ.mjs +0 -1
  183. package/dist/chunk-PVR2SN3B.mjs +0 -1
  184. package/dist/chunk-QUIYULS2.mjs +0 -1
  185. package/dist/chunk-YR3SAEO7.mjs +0 -1
  186. package/dist/server-fns-6QM243HC.mjs +0 -2
  187. package/dist/server-functions-E3LKCZ4R.mjs +0 -1
  188. package/dist/transform-5WC4FWJE.mjs +0 -8
@@ -0,0 +1,636 @@
1
+ /*! @fluixi/compiler v1.0.0-alpha.84 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
2
+ import {
3
+ analyzeStatic,
4
+ buildJsxIR,
5
+ collapseStrategies,
6
+ imperativeBackend,
7
+ inlineTemplates,
8
+ isDeferred,
9
+ isReactiveShape,
10
+ lowerTemplate,
11
+ resolveComponentSources,
12
+ shapeOf
13
+ } from "./chunk-EZR7NZOY.mjs";
14
+ import {
15
+ CORE_CONTROL_FLOW,
16
+ ROUTER_COMPONENTS,
17
+ createComponentResolver
18
+ } from "./chunk-MJV3UXIL.mjs";
19
+ import "./chunk-3YKZ4GNH.mjs";
20
+
21
+ // src/frontend/babel/plugin.ts
22
+ import { declare } from "@babel/helper-plugin-utils";
23
+ import { types as t3, template as template2 } from "@babel/core";
24
+
25
+ // src/frontend/babel/build-ir.ts
26
+ import { types as t2, traverse, template } from "@babel/core";
27
+ import _generate2 from "@babel/generator";
28
+
29
+ // src/frontend/babel/lower-template.ts
30
+ import { types as t } from "@babel/core";
31
+ import _generate from "@babel/generator";
32
+ var generate = _generate.default ?? _generate;
33
+ function gen(node) {
34
+ return generate(node, { concise: true }).code;
35
+ }
36
+ function bindHole(expr, used, onNested) {
37
+ const hole = {
38
+ code: genExpr(expr, used, onNested),
39
+ reactive: isReactiveExpr(expr)
40
+ };
41
+ if (t.isArrowFunctionExpression(expr) && !t.isBlockStatement(expr.body)) {
42
+ const body = expr.body;
43
+ hole.arrow = {
44
+ params: expr.params.map((p) => gen(p)),
45
+ body: genExpr(body, used, onNested),
46
+ bodyReactive: isReactiveExpr(body)
47
+ };
48
+ }
49
+ if (t.isObjectExpression(expr)) hole.object = true;
50
+ return hole;
51
+ }
52
+ function lowerLitTemplate(node, used, opts = {}) {
53
+ const quasi = node.quasi;
54
+ const holes = quasi.expressions.map((e) => bindHole(e, used, opts.onNested));
55
+ return lowerTemplate(buildPieces(quasi), holes, used, opts);
56
+ }
57
+ function buildPieces(quasi) {
58
+ const pieces = [];
59
+ quasi.quasis.forEach((q, i) => {
60
+ const text = q.value.cooked ?? q.value.raw;
61
+ pieces.push({ kind: "static", text, start: q.start ?? 0 });
62
+ if (i < quasi.expressions.length) {
63
+ const e = quasi.expressions[i];
64
+ pieces.push({ kind: "hole", index: i, start: e.start ?? 0, end: e.end ?? 0 });
65
+ }
66
+ });
67
+ return pieces;
68
+ }
69
+
70
+ // src/frontend/babel/build-ir-lit.ts
71
+ function buildIRFromLit(node, used = /* @__PURE__ */ new Set(), opts = {}) {
72
+ const ir = lowerLitTemplate(node, used, opts);
73
+ analyzeStatic(ir);
74
+ return ir;
75
+ }
76
+
77
+ // src/frontend/babel/build-ir.ts
78
+ var generate2 = _generate2.default ?? _generate2;
79
+ function gen2(node) {
80
+ return generate2(node, { concise: true }).code;
81
+ }
82
+ function transformNestedJSX(node, used, onNested) {
83
+ const clone = t2.cloneNode(node, true);
84
+ const file = t2.file(t2.program([t2.expressionStatement(clone)]));
85
+ let changed = false;
86
+ const emitInto = (path, code, imports) => {
87
+ for (const s of imports) used.add(s);
88
+ path.replaceWith(template.expression(code, { placeholderPattern: false, plugins: ["typescript"] })());
89
+ path.skip();
90
+ changed = true;
91
+ };
92
+ traverse(file, {
93
+ "JSXElement|JSXFragment"(path) {
94
+ const jsx = path.node;
95
+ const nestedIR = buildIR(jsx, used, onNested);
96
+ onNested?.(nestedIR);
97
+ const { code, imports, templates } = imperativeBackend.emit(nestedIR, {});
98
+ emitInto(path, inlineTemplates(code, templates), imports);
99
+ },
100
+ // Nested lit templates compose: ${cond ? html`…` : html`…`},
101
+ // ${list.map(x => html`<li>${x}</li>`)}. Compile them the same way.
102
+ TaggedTemplateExpression(path) {
103
+ const tag = path.node.tag;
104
+ if (!t2.isIdentifier(tag) || tag.name !== "html" && tag.name !== "svg") return;
105
+ const ir = buildIRFromLit(path.node, used, { svg: tag.name === "svg", onNested });
106
+ onNested?.(ir);
107
+ const { code, imports, templates } = imperativeBackend.emit(ir, {});
108
+ emitInto(path, inlineTemplates(code, templates), imports);
109
+ }
110
+ });
111
+ return changed ? file.program.body[0].expression : node;
112
+ }
113
+ function genExpr(node, used, onNested) {
114
+ return gen2(transformNestedJSX(node, used, onNested));
115
+ }
116
+ function isReactiveExpr(node) {
117
+ return isReactiveShape(shapeOf(node));
118
+ }
119
+ function buildIR(node, used = /* @__PURE__ */ new Set(), onNested) {
120
+ const ir = buildJsxIR(node, {
121
+ code: (n) => (
122
+ // A member-expression tag (`<ns.Foo/>`) is not an Expression, so it cannot go
123
+ // through the nested-JSX compile — it only ever needs printing.
124
+ n.type === "JSXMemberExpression" ? gen2(n) : genExpr(n, used, onNested)
125
+ ),
126
+ used
127
+ });
128
+ return ir;
129
+ }
130
+
131
+ // src/frontend/babel/plugin.ts
132
+ var CORE_ONLY_CONTROL_FLOW = new Set(CORE_CONTROL_FLOW);
133
+ var ROUTER_COMPONENTS2 = new Set(ROUTER_COMPONENTS);
134
+ var plugin_default = declare((api, options = {}) => {
135
+ api.assertVersion(7);
136
+ const {
137
+ delegateEvents = true,
138
+ signalModule = "@fluixi/dom",
139
+ controlFlowModule = "@fluixi/dom",
140
+ routerModule = "@fluixi/core/router",
141
+ reactiveModule = "@fluixi/reactive/signal",
142
+ templateClone = true,
143
+ partialTemplates = true,
144
+ // `both` by default: JSX and html`` are compiled out of the box, so
145
+ // `fluixi()` needs no `format` option. Injected imports are deduped, so a
146
+ // file mixing the two styles won't redeclare a binding.
147
+ format = "both",
148
+ litTag = "html",
149
+ resolve: resolveRules = []
150
+ } = options;
151
+ const componentResolver = createComponentResolver(resolveRules);
152
+ const compileLit = format === "lit" || format === "both";
153
+ const pluginState = {
154
+ irImports: /* @__PURE__ */ new Set(),
155
+ libModule: "@fluixi/core",
156
+ controlFlowModule,
157
+ routerModule,
158
+ templateClone,
159
+ partialTemplates,
160
+ hasJSX: false,
161
+ hasLitHTML: false,
162
+ needsControlFlowImport: false,
163
+ needsCreateMemo: false,
164
+ controlFlowComponents: /* @__PURE__ */ new Set(),
165
+ resolvedComponents: /* @__PURE__ */ new Map(),
166
+ deferredComponents: /* @__PURE__ */ new Map(),
167
+ componentResolver,
168
+ delegatedEvents: /* @__PURE__ */ new Set(),
169
+ staticTemplates: /* @__PURE__ */ new Map(),
170
+ staticCounter: 0
171
+ };
172
+ return {
173
+ name: "@fluixi/babel-plugin-jsx",
174
+ manipulateOptions(opts, parserOpts) {
175
+ parserOpts.plugins.push("jsx", "typescript");
176
+ },
177
+ pre(state) {
178
+ Object.assign(state, pluginState);
179
+ },
180
+ visitor: {
181
+ Program: {
182
+ enter(path, state) {
183
+ Object.assign(state, {
184
+ hasJSX: false,
185
+ hasLitHTML: false,
186
+ hasLitIR: false,
187
+ needsControlFlowImport: false,
188
+ needsCreateMemo: false,
189
+ controlFlowComponents: /* @__PURE__ */ new Set(),
190
+ resolvedComponents: /* @__PURE__ */ new Map(),
191
+ deferredComponents: /* @__PURE__ */ new Map(),
192
+ componentResolver,
193
+ delegatedEvents: /* @__PURE__ */ new Set(),
194
+ staticTemplates: /* @__PURE__ */ new Map(),
195
+ staticCounter: 0,
196
+ libModule: "@fluixi/core",
197
+ controlFlowModule,
198
+ routerModule,
199
+ templateClone,
200
+ partialTemplates,
201
+ irImports: /* @__PURE__ */ new Set(),
202
+ needsCreateNativeElement: false,
203
+ needsInsert: false,
204
+ needsSpread: false,
205
+ needsCreateComponent: false,
206
+ needsMergeProps: false
207
+ });
208
+ },
209
+ exit(path, state) {
210
+ const imports = [];
211
+ if (state.hasJSX || state.hasLitIR) {
212
+ if (state.irImports.size > 0) {
213
+ const CF = /* @__PURE__ */ new Set([
214
+ "Show",
215
+ "For",
216
+ "Index",
217
+ "Switch",
218
+ "Match",
219
+ "Dynamic",
220
+ "ErrorBoundary",
221
+ "Portal",
222
+ "Suspense"
223
+ ]);
224
+ const REACTIVE = /* @__PURE__ */ new Set([
225
+ "createMemo",
226
+ "createEffect",
227
+ "createRenderEffect",
228
+ "createRoot",
229
+ "createSignal",
230
+ "onCleanup",
231
+ "batch",
232
+ "untrack"
233
+ ]);
234
+ const all = Array.from(state.irImports);
235
+ const spec = (n) => t3.importSpecifier(t3.identifier(n), t3.identifier(n));
236
+ const unbound = (s) => !path.scope.hasBinding(s);
237
+ const reactive = all.filter((s) => REACTIVE.has(s) && unbound(s));
238
+ const core = all.filter((s) => !CF.has(s) && !REACTIVE.has(s) && unbound(s));
239
+ const cf = all.filter((s) => CF.has(s) && unbound(s));
240
+ if (reactive.length > 0) {
241
+ imports.push(
242
+ t3.importDeclaration(reactive.map(spec), t3.stringLiteral(reactiveModule))
243
+ );
244
+ }
245
+ if (core.length > 0) {
246
+ imports.push(
247
+ t3.importDeclaration(core.map(spec), t3.stringLiteral(signalModule))
248
+ );
249
+ }
250
+ if (cf.length > 0) {
251
+ imports.push(
252
+ t3.importDeclaration(cf.map(spec), t3.stringLiteral(controlFlowModule))
253
+ );
254
+ }
255
+ }
256
+ if (state.needsCreateMemo && !path.scope.hasBinding("createMemo")) {
257
+ imports.push(
258
+ t3.importDeclaration(
259
+ [t3.importSpecifier(t3.identifier("createMemo"), t3.identifier("createMemo"))],
260
+ t3.stringLiteral(reactiveModule)
261
+ )
262
+ );
263
+ }
264
+ if (state.needsControlFlowImport && state.controlFlowComponents.size > 0) {
265
+ const unbound = Array.from(state.controlFlowComponents).filter(
266
+ (name) => !path.scope.hasBinding(name)
267
+ );
268
+ const coreModule = state.libModule ?? "@fluixi/core";
269
+ const fromRouter = unbound.filter((n) => ROUTER_COMPONENTS2.has(n));
270
+ const fromCore = unbound.filter((n) => CORE_ONLY_CONTROL_FLOW.has(n));
271
+ const fromDom = unbound.filter(
272
+ (n) => !CORE_ONLY_CONTROL_FLOW.has(n) && !ROUTER_COMPONENTS2.has(n)
273
+ );
274
+ const declFor = (names, mod) => t3.importDeclaration(
275
+ names.map((name) => t3.importSpecifier(t3.identifier(name), t3.identifier(name))),
276
+ t3.stringLiteral(mod)
277
+ );
278
+ if (fromDom.length > 0) imports.push(declFor(fromDom, controlFlowModule));
279
+ if (fromCore.length > 0) imports.push(declFor(fromCore, coreModule));
280
+ if (fromRouter.length > 0) imports.push(declFor(fromRouter, routerModule));
281
+ }
282
+ const deferredDecls = [];
283
+ if (state.deferredComponents.size > 0) {
284
+ for (const [local, entry] of state.deferredComponents) {
285
+ if (path.scope.hasBinding(local)) continue;
286
+ deferredDecls.push(
287
+ t3.variableDeclaration("const", [
288
+ t3.variableDeclarator(
289
+ t3.identifier(local),
290
+ t3.callExpression(t3.identifier("deferred"), [
291
+ t3.arrowFunctionExpression(
292
+ [],
293
+ t3.callExpression(t3.import(), [t3.stringLiteral(entry.module)])
294
+ ),
295
+ t3.objectExpression([
296
+ t3.objectProperty(
297
+ t3.identifier("strategy"),
298
+ strategyLiteral(entry.strategy)
299
+ ),
300
+ t3.objectProperty(
301
+ t3.identifier("export"),
302
+ t3.stringLiteral(entry.export)
303
+ )
304
+ ])
305
+ ])
306
+ )
307
+ ])
308
+ );
309
+ }
310
+ if (deferredDecls.length > 0 && !path.scope.hasBinding("deferred")) {
311
+ imports.push(
312
+ t3.importDeclaration(
313
+ [t3.importSpecifier(t3.identifier("deferred"), t3.identifier("deferred"))],
314
+ t3.stringLiteral(state.libModule ?? "@fluixi/core")
315
+ )
316
+ );
317
+ }
318
+ }
319
+ if (state.resolvedComponents.size > 0) {
320
+ const byModule = /* @__PURE__ */ new Map();
321
+ for (const [local, resolved] of state.resolvedComponents) {
322
+ if (path.scope.hasBinding(local)) continue;
323
+ const list = byModule.get(resolved.module) ?? [];
324
+ list.push({ local, exported: resolved.export });
325
+ byModule.set(resolved.module, list);
326
+ }
327
+ for (const [mod, entries] of byModule) {
328
+ imports.push(
329
+ t3.importDeclaration(
330
+ entries.map(
331
+ ({ local, exported }) => exported === "default" ? t3.importDefaultSpecifier(t3.identifier(local)) : t3.importSpecifier(t3.identifier(local), t3.identifier(exported))
332
+ ),
333
+ t3.stringLiteral(mod)
334
+ )
335
+ );
336
+ }
337
+ }
338
+ if (delegateEvents && state.delegatedEvents.size > 0) {
339
+ imports.push(
340
+ t3.importDeclaration(
341
+ [
342
+ t3.importSpecifier(
343
+ t3.identifier("delegateEvents"),
344
+ t3.identifier("delegateEvents")
345
+ )
346
+ ],
347
+ t3.stringLiteral(signalModule)
348
+ )
349
+ );
350
+ const eventsArray = t3.arrayExpression(
351
+ Array.from(state.delegatedEvents).map(
352
+ (event) => t3.stringLiteral(event)
353
+ )
354
+ );
355
+ const delegateCall = t3.expressionStatement(
356
+ t3.callExpression(t3.identifier("delegateEvents"), [eventsArray])
357
+ );
358
+ path.node.body.unshift(delegateCall);
359
+ }
360
+ if (deferredDecls.length > 0) {
361
+ path.node.body.unshift(...deferredDecls);
362
+ }
363
+ if (state.staticTemplates.size > 0) {
364
+ const decls = [];
365
+ for (const [key, name] of state.staticTemplates) {
366
+ const svg = key.startsWith("svg:");
367
+ const html = svg ? key.slice(4) : key;
368
+ decls.push(
369
+ t3.variableDeclaration("const", [
370
+ t3.variableDeclarator(
371
+ t3.identifier(name),
372
+ // Just the HTML. Parsing is deferred to `templateNode`, which
373
+ // knows whether this is a server render, a hydration or a fresh
374
+ // client render — a module-scope `createTemplate` would touch
375
+ // `document` at import time and break SSR outright.
376
+ t3.stringLiteral(html)
377
+ )
378
+ ])
379
+ );
380
+ }
381
+ path.node.body.unshift(...decls);
382
+ }
383
+ }
384
+ if (imports.length > 0) {
385
+ path.node.body.unshift(...dedupeImports(imports));
386
+ }
387
+ }
388
+ },
389
+ // Both JSX forms take the one path: build IR, run the imperative backend,
390
+ // splice the emitted code back in. It handles the whole subtree, so nothing
391
+ // below this node needs its own visitor.
392
+ JSXElement(path, state) {
393
+ state.hasJSX = true;
394
+ path.replaceWith(emitViaIR(path.node, state));
395
+ },
396
+ JSXFragment(path, state) {
397
+ state.hasJSX = true;
398
+ path.replaceWith(emitViaIR(path.node, state));
399
+ },
400
+ TaggedTemplateExpression(path, state) {
401
+ if (compileLit && t3.isIdentifier(path.node.tag) && (path.node.tag.name === litTag || path.node.tag.name === "svg")) {
402
+ path.replaceWith(emitLitViaIR(path.node, state));
403
+ }
404
+ }
405
+ }
406
+ };
407
+ });
408
+ function nestedHook(state) {
409
+ return (ir) => {
410
+ resolveComponentSources(ir, {
411
+ resolver: state.componentResolver,
412
+ modules: {
413
+ controlFlowModule: state.controlFlowModule,
414
+ coreModule: state.libModule,
415
+ routerModule: state.routerModule
416
+ },
417
+ strategyFor: (node) => node.load
418
+ });
419
+ collapseStrategies(ir);
420
+ collectRuntimeNeeds(ir, state);
421
+ };
422
+ }
423
+ function strategyLiteral(strategy) {
424
+ const props = [
425
+ t3.objectProperty(t3.identifier("kind"), t3.stringLiteral(strategy.kind))
426
+ ];
427
+ if (strategy.kind === "visible" && strategy.rootMargin) {
428
+ props.push(t3.objectProperty(t3.identifier("rootMargin"), t3.stringLiteral(strategy.rootMargin)));
429
+ }
430
+ if (strategy.kind === "interaction") {
431
+ props.push(
432
+ t3.objectProperty(
433
+ t3.identifier("events"),
434
+ t3.arrayExpression(strategy.events.map((e) => t3.stringLiteral(e)))
435
+ )
436
+ );
437
+ }
438
+ if (strategy.kind === "media") {
439
+ props.push(t3.objectProperty(t3.identifier("query"), t3.stringLiteral(strategy.query)));
440
+ }
441
+ return t3.objectExpression(props);
442
+ }
443
+ function adoptTemplates(code, templates, state) {
444
+ if (!templates || templates.length === 0) return code;
445
+ const rename = /* @__PURE__ */ new Map();
446
+ for (const tpl of templates) {
447
+ const key = `${tpl.svg ? "svg:" : ""}${tpl.html}`;
448
+ let name = state.staticTemplates.get(key);
449
+ if (!name) {
450
+ name = `_tmpl$${state.staticTemplates.size}`;
451
+ state.staticTemplates.set(key, name);
452
+ }
453
+ rename.set(tpl.id, name);
454
+ }
455
+ return code.replace(/_tmpl\$\d+/g, (id) => rename.get(id) ?? id);
456
+ }
457
+ function emitViaIR(node, state) {
458
+ const used = /* @__PURE__ */ new Set();
459
+ const ir = buildIR(node, used, nestedHook(state));
460
+ resolveComponentSources(ir, {
461
+ resolver: state.componentResolver,
462
+ modules: {
463
+ controlFlowModule: state.controlFlowModule,
464
+ coreModule: state.libModule,
465
+ routerModule: state.routerModule
466
+ },
467
+ strategyFor: (n) => n.load
468
+ });
469
+ collapseStrategies(ir);
470
+ const { code, imports, templates } = imperativeBackend.emit(ir, { templateClone: state.templateClone, partialTemplates: state.partialTemplates });
471
+ for (const s of imports) used.add(s);
472
+ for (const s of used) state.irImports.add(s);
473
+ collectRuntimeNeeds(ir, state);
474
+ const adopted = adoptTemplates(code, templates, state);
475
+ return template2.expression(adopted, { placeholderPattern: false, plugins: ["typescript"] })();
476
+ }
477
+ function dedupeImports(imports) {
478
+ const byModule = /* @__PURE__ */ new Map();
479
+ const out = [];
480
+ for (const decl of imports) {
481
+ const source = decl.source.value;
482
+ const allNamed = decl.specifiers.every((s) => t3.isImportSpecifier(s));
483
+ if (!allNamed) {
484
+ out.push(decl);
485
+ continue;
486
+ }
487
+ const existing = byModule.get(source);
488
+ if (!existing) {
489
+ const names = new Set(
490
+ decl.specifiers.map((s) => s.local.name)
491
+ );
492
+ byModule.set(source, { decl, names });
493
+ out.push(decl);
494
+ continue;
495
+ }
496
+ for (const s of decl.specifiers) {
497
+ if (!existing.names.has(s.local.name)) {
498
+ existing.names.add(s.local.name);
499
+ existing.decl.specifiers.push(s);
500
+ }
501
+ }
502
+ }
503
+ return out;
504
+ }
505
+ function emitLitViaIR(node, state) {
506
+ const used = /* @__PURE__ */ new Set();
507
+ const svg = t3.isIdentifier(node.tag) && node.tag.name === "svg";
508
+ const ir = buildIRFromLit(node, used, { svg, onNested: nestedHook(state) });
509
+ resolveComponentSources(ir, {
510
+ resolver: state.componentResolver,
511
+ modules: {
512
+ controlFlowModule: state.controlFlowModule,
513
+ coreModule: state.libModule,
514
+ routerModule: state.routerModule
515
+ },
516
+ strategyFor: (node2) => node2.load
517
+ });
518
+ collapseStrategies(ir);
519
+ const { code, imports, templates } = imperativeBackend.emit(ir, { templateClone: state.templateClone, partialTemplates: state.partialTemplates });
520
+ for (const s of imports) used.add(s);
521
+ for (const s of used) state.irImports.add(s);
522
+ collectRuntimeNeeds(ir, state);
523
+ state.hasLitIR = true;
524
+ const expression = template2.expression(adoptTemplates(code, templates, state), {
525
+ placeholderPattern: false,
526
+ plugins: ["typescript"]
527
+ })();
528
+ inheritLocation(expression, node);
529
+ return expression;
530
+ }
531
+ function inheritLocation(target, source) {
532
+ if (!source.loc) return;
533
+ const seen = /* @__PURE__ */ new Set();
534
+ const walk = (node) => {
535
+ if (seen.has(node)) return;
536
+ seen.add(node);
537
+ if (!node.loc) {
538
+ node.loc = source.loc;
539
+ node.start = source.start;
540
+ node.end = source.end;
541
+ }
542
+ for (const key of t3.VISITOR_KEYS[node.type] ?? []) {
543
+ const child = node[key];
544
+ if (Array.isArray(child)) {
545
+ for (const c of child) if (c && typeof c === "object" && "type" in c) walk(c);
546
+ } else if (child && typeof child === "object" && "type" in child) {
547
+ walk(child);
548
+ }
549
+ }
550
+ };
551
+ walk(target);
552
+ }
553
+ function collectRuntimeNeeds(node, state) {
554
+ if (node.kind === "component" && node.source) {
555
+ if (node.source.origin === "builtin") {
556
+ state.controlFlowComponents.add(node.name);
557
+ state.needsControlFlowImport = true;
558
+ } else if (isDeferred(node.source.loading) && !state.resolvedComponents.has(node.name)) {
559
+ state.deferredComponents.set(node.name, {
560
+ module: node.source.module,
561
+ export: node.source.export,
562
+ strategy: node.source.loading
563
+ });
564
+ } else {
565
+ state.deferredComponents.delete(node.name);
566
+ state.resolvedComponents.set(node.name, {
567
+ module: node.source.module,
568
+ export: node.source.export
569
+ });
570
+ }
571
+ }
572
+ if (node.kind === "element" || node.kind === "component" || node.kind === "control") {
573
+ if ("props" in node) {
574
+ for (const p of node.props) {
575
+ if (p.kind === "event" && p.event?.delegated) state.delegatedEvents.add(p.event.name);
576
+ }
577
+ }
578
+ }
579
+ if ("children" in node && node.children) {
580
+ for (const c of node.children) collectRuntimeNeeds(c, state);
581
+ }
582
+ }
583
+
584
+ // src/frontend/babel/index.ts
585
+ var babelPluginReactiveJSX = plugin_default;
586
+ function createPlugin(options) {
587
+ return [plugin_default, options];
588
+ }
589
+ function createPreset(options = {}) {
590
+ return {
591
+ plugins: [
592
+ [
593
+ plugin_default,
594
+ {
595
+ runtime: "automatic",
596
+ importSource: "@fluixi/jsx",
597
+ development: false,
598
+ detectReactivity: true,
599
+ useLitHTML: true,
600
+ hoistStatics: true,
601
+ delegateEvents: true,
602
+ optimizeControlFlow: true,
603
+ sourceMaps: true,
604
+ ...options
605
+ }
606
+ ]
607
+ ]
608
+ };
609
+ }
610
+ var presets = {
611
+ production: createPreset({
612
+ development: false,
613
+ hoistStatics: true,
614
+ delegateEvents: true,
615
+ optimizeControlFlow: true
616
+ }),
617
+ development: createPreset({
618
+ development: true,
619
+ hoistStatics: false,
620
+ sourceMaps: true
621
+ }),
622
+ minimal: createPreset({
623
+ detectReactivity: false,
624
+ useLitHTML: false,
625
+ hoistStatics: false,
626
+ delegateEvents: false,
627
+ optimizeControlFlow: false
628
+ })
629
+ };
630
+ export {
631
+ babelPluginReactiveJSX,
632
+ createPlugin,
633
+ createPreset,
634
+ plugin_default as default,
635
+ presets
636
+ };
@@ -0,0 +1,11 @@
1
+ /*! @fluixi/compiler v1.0.0-alpha.84 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
2
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
3
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
4
+ }) : x)(function(x) {
5
+ if (typeof require !== "undefined") return require.apply(this, arguments);
6
+ throw Error('Dynamic require of "' + x + '" is not supported');
7
+ });
8
+
9
+ export {
10
+ __require
11
+ };