@fluixi/compiler 1.0.0-alpha.100

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 (303) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +131 -0
  3. package/dist/analyze/expr-shape.cjs +62 -0
  4. package/dist/analyze/expr-shape.d.cts +14 -0
  5. package/dist/analyze/expr-shape.d.ts +15 -0
  6. package/dist/analyze/expr-shape.d.ts.map +1 -0
  7. package/dist/analyze/expr-shape.js +37 -0
  8. package/dist/analyze/expr-shape.mjs +41 -0
  9. package/dist/analyze/intrinsics.cjs +112 -0
  10. package/dist/analyze/intrinsics.d.cts +80 -0
  11. package/dist/analyze/intrinsics.d.ts +81 -0
  12. package/dist/analyze/intrinsics.d.ts.map +1 -0
  13. package/dist/analyze/intrinsics.js +126 -0
  14. package/dist/analyze/intrinsics.mjs +91 -0
  15. package/dist/analyze/paren.cjs +134 -0
  16. package/dist/analyze/paren.d.cts +23 -0
  17. package/dist/analyze/paren.d.ts +24 -0
  18. package/dist/analyze/paren.d.ts.map +1 -0
  19. package/dist/analyze/paren.js +168 -0
  20. package/dist/analyze/paren.mjs +113 -0
  21. package/dist/analyze/props-destructure.cjs +226 -0
  22. package/dist/analyze/props-destructure.d.cts +83 -0
  23. package/dist/analyze/props-destructure.d.ts +84 -0
  24. package/dist/analyze/props-destructure.d.ts.map +1 -0
  25. package/dist/analyze/props-destructure.js +272 -0
  26. package/dist/analyze/props-destructure.mjs +205 -0
  27. package/dist/analyze/reactive-bindings.cjs +210 -0
  28. package/dist/analyze/reactive-bindings.d.cts +42 -0
  29. package/dist/analyze/reactive-bindings.d.ts +43 -0
  30. package/dist/analyze/reactive-bindings.d.ts.map +1 -0
  31. package/dist/analyze/reactive-bindings.js +191 -0
  32. package/dist/analyze/reactive-bindings.mjs +187 -0
  33. package/dist/analyze/reactive-expr.cjs +38 -0
  34. package/dist/analyze/reactive-expr.d.cts +38 -0
  35. package/dist/analyze/reactive-expr.d.ts +39 -0
  36. package/dist/analyze/reactive-expr.d.ts.map +1 -0
  37. package/dist/analyze/reactive-expr.js +31 -0
  38. package/dist/analyze/reactive-expr.mjs +17 -0
  39. package/dist/analyze/static-graph.cjs +831 -0
  40. package/dist/analyze/static-graph.d.cts +102 -0
  41. package/dist/analyze/static-graph.d.ts +103 -0
  42. package/dist/analyze/static-graph.d.ts.map +1 -0
  43. package/dist/analyze/static-graph.js +871 -0
  44. package/dist/analyze/static-graph.mjs +813 -0
  45. package/dist/babel-I6BUWUCU.mjs +636 -0
  46. package/dist/chunk-3AICWNF7.mjs +92 -0
  47. package/dist/chunk-6CWJWGE2.mjs +2170 -0
  48. package/dist/chunk-C3XPDB4Y.mjs +16 -0
  49. package/dist/chunk-GX5XV6Z7.mjs +190 -0
  50. package/dist/chunk-HXEXPWJ2.mjs +999 -0
  51. package/dist/chunk-NU3W67UZ.mjs +584 -0
  52. package/dist/chunk-SKAVY75W.mjs +11 -0
  53. package/dist/codegen/backend.cjs +18 -0
  54. package/dist/codegen/backend.d.cts +35 -0
  55. package/dist/codegen/backend.d.ts +36 -0
  56. package/dist/codegen/backend.d.ts.map +1 -0
  57. package/dist/codegen/backend.js +1 -0
  58. package/dist/codegen/backend.mjs +0 -0
  59. package/dist/codegen/backends/imperative.cjs +577 -0
  60. package/dist/codegen/backends/imperative.d.cts +11 -0
  61. package/dist/codegen/backends/imperative.d.ts +12 -0
  62. package/dist/codegen/backends/imperative.d.ts.map +1 -0
  63. package/dist/codegen/backends/imperative.js +362 -0
  64. package/dist/codegen/backends/imperative.mjs +554 -0
  65. package/dist/codegen/contract.cjs +52 -0
  66. package/dist/codegen/contract.d.cts +24 -0
  67. package/dist/codegen/contract.d.ts +25 -0
  68. package/dist/codegen/contract.d.ts.map +1 -0
  69. package/dist/codegen/contract.js +30 -0
  70. package/dist/codegen/contract.mjs +31 -0
  71. package/dist/codegen/partial-template.cjs +176 -0
  72. package/dist/codegen/partial-template.d.cts +61 -0
  73. package/dist/codegen/partial-template.d.ts +62 -0
  74. package/dist/codegen/partial-template.d.ts.map +1 -0
  75. package/dist/codegen/partial-template.js +0 -0
  76. package/dist/codegen/partial-template.mjs +153 -0
  77. package/dist/codegen/serialize-static.cjs +125 -0
  78. package/dist/codegen/serialize-static.d.cts +38 -0
  79. package/dist/codegen/serialize-static.d.ts +39 -0
  80. package/dist/codegen/serialize-static.d.ts.map +1 -0
  81. package/dist/codegen/serialize-static.js +165 -0
  82. package/dist/codegen/serialize-static.mjs +104 -0
  83. package/dist/frontend/babel/build-ir-lit.cjs +1933 -0
  84. package/dist/frontend/babel/build-ir-lit.d.cts +26 -0
  85. package/dist/frontend/babel/build-ir-lit.d.ts +27 -0
  86. package/dist/frontend/babel/build-ir-lit.d.ts.map +1 -0
  87. package/dist/frontend/babel/build-ir-lit.js +13 -0
  88. package/dist/frontend/babel/build-ir-lit.mjs +1902 -0
  89. package/dist/frontend/babel/build-ir.cjs +1948 -0
  90. package/dist/frontend/babel/build-ir.d.cts +35 -0
  91. package/dist/frontend/babel/build-ir.d.ts +36 -0
  92. package/dist/frontend/babel/build-ir.d.ts.map +1 -0
  93. package/dist/frontend/babel/build-ir.js +124 -0
  94. package/dist/frontend/babel/build-ir.mjs +1919 -0
  95. package/dist/frontend/babel/index.cjs +2610 -0
  96. package/dist/frontend/babel/index.d.cts +33 -0
  97. package/dist/frontend/babel/index.d.ts +34 -0
  98. package/dist/frontend/babel/index.d.ts.map +1 -0
  99. package/dist/frontend/babel/index.js +65 -0
  100. package/dist/frontend/babel/index.mjs +2580 -0
  101. package/dist/frontend/babel/lower-template.cjs +1931 -0
  102. package/dist/frontend/babel/lower-template.d.cts +23 -0
  103. package/dist/frontend/babel/lower-template.d.ts +24 -0
  104. package/dist/frontend/babel/lower-template.d.ts.map +1 -0
  105. package/dist/frontend/babel/lower-template.js +64 -0
  106. package/dist/frontend/babel/lower-template.mjs +1902 -0
  107. package/dist/frontend/babel/plugin.cjs +2556 -0
  108. package/dist/frontend/babel/plugin.d.cts +95 -0
  109. package/dist/frontend/babel/plugin.d.ts +96 -0
  110. package/dist/frontend/babel/plugin.d.ts.map +1 -0
  111. package/dist/frontend/babel/plugin.js +523 -0
  112. package/dist/frontend/babel/plugin.mjs +2527 -0
  113. package/dist/frontend/babel/server-functions.cjs +110 -0
  114. package/dist/frontend/babel/server-functions.d.cts +10 -0
  115. package/dist/frontend/babel/server-functions.d.ts +11 -0
  116. package/dist/frontend/babel/server-functions.d.ts.map +1 -0
  117. package/dist/frontend/babel/server-functions.js +81 -0
  118. package/dist/frontend/babel/server-functions.mjs +89 -0
  119. package/dist/frontend/babel/types.cjs +18 -0
  120. package/dist/frontend/babel/types.d.cts +33 -0
  121. package/dist/frontend/babel/types.d.ts +34 -0
  122. package/dist/frontend/babel/types.d.ts.map +1 -0
  123. package/dist/frontend/babel/types.js +1 -0
  124. package/dist/frontend/babel/types.mjs +0 -0
  125. package/dist/frontend/types.cjs +18 -0
  126. package/dist/frontend/types.d.cts +25 -0
  127. package/dist/frontend/types.d.ts +26 -0
  128. package/dist/frontend/types.d.ts.map +1 -0
  129. package/dist/frontend/types.js +1 -0
  130. package/dist/frontend/types.mjs +0 -0
  131. package/dist/frontend/vocabulary.cjs +98 -0
  132. package/dist/frontend/vocabulary.d.cts +79 -0
  133. package/dist/frontend/vocabulary.d.ts +80 -0
  134. package/dist/frontend/vocabulary.d.ts.map +1 -0
  135. package/dist/frontend/vocabulary.js +124 -0
  136. package/dist/frontend/vocabulary.mjs +77 -0
  137. package/dist/index.cjs +1957 -0
  138. package/dist/index.d.cts +27 -0
  139. package/dist/index.d.ts +28 -0
  140. package/dist/index.d.ts.map +1 -0
  141. package/dist/index.js +38 -0
  142. package/dist/index.mjs +1949 -0
  143. package/dist/integrations.cjs +5705 -0
  144. package/dist/integrations.d.cts +215 -0
  145. package/dist/integrations.d.ts +216 -0
  146. package/dist/integrations.d.ts.map +1 -0
  147. package/dist/integrations.js +566 -0
  148. package/dist/integrations.mjs +810 -0
  149. package/dist/ir/nodes.cjs +18 -0
  150. package/dist/ir/nodes.d.cts +168 -0
  151. package/dist/ir/nodes.d.ts +169 -0
  152. package/dist/ir/nodes.d.ts.map +1 -0
  153. package/dist/ir/nodes.js +1 -0
  154. package/dist/ir/nodes.mjs +0 -0
  155. package/dist/lower/compile-template.cjs +1670 -0
  156. package/dist/lower/compile-template.d.cts +82 -0
  157. package/dist/lower/compile-template.d.ts +83 -0
  158. package/dist/lower/compile-template.d.ts.map +1 -0
  159. package/dist/lower/compile-template.js +79 -0
  160. package/dist/lower/compile-template.mjs +1662 -0
  161. package/dist/lower/entities.cjs +288 -0
  162. package/dist/lower/entities.d.cts +1 -0
  163. package/dist/lower/entities.d.ts +2 -0
  164. package/dist/lower/entities.d.ts.map +1 -0
  165. package/dist/lower/entities.js +54 -0
  166. package/dist/lower/entities.mjs +267 -0
  167. package/dist/lower/jsx.cjs +1101 -0
  168. package/dist/lower/jsx.d.cts +33 -0
  169. package/dist/lower/jsx.d.ts +34 -0
  170. package/dist/lower/jsx.d.ts.map +1 -0
  171. package/dist/lower/jsx.js +414 -0
  172. package/dist/lower/jsx.mjs +1078 -0
  173. package/dist/lower/template.cjs +1354 -0
  174. package/dist/lower/template.d.cts +53 -0
  175. package/dist/lower/template.d.ts +54 -0
  176. package/dist/lower/template.d.ts.map +1 -0
  177. package/dist/lower/template.js +542 -0
  178. package/dist/lower/template.mjs +1335 -0
  179. package/dist/lower/text.cjs +42 -0
  180. package/dist/lower/text.d.cts +10 -0
  181. package/dist/lower/text.d.ts +11 -0
  182. package/dist/lower/text.d.ts.map +1 -0
  183. package/dist/lower/text.js +31 -0
  184. package/dist/lower/text.mjs +21 -0
  185. package/dist/optimize/analyze-static.cjs +112 -0
  186. package/dist/optimize/analyze-static.d.cts +39 -0
  187. package/dist/optimize/analyze-static.d.ts +40 -0
  188. package/dist/optimize/analyze-static.d.ts.map +1 -0
  189. package/dist/optimize/analyze-static.js +131 -0
  190. package/dist/optimize/analyze-static.mjs +91 -0
  191. package/dist/optimize/collapse-strategies.cjs +90 -0
  192. package/dist/optimize/collapse-strategies.d.cts +30 -0
  193. package/dist/optimize/collapse-strategies.d.ts +31 -0
  194. package/dist/optimize/collapse-strategies.d.ts.map +1 -0
  195. package/dist/optimize/collapse-strategies.js +33 -0
  196. package/dist/optimize/collapse-strategies.mjs +67 -0
  197. package/dist/options.cjs +33 -0
  198. package/dist/options.d.cts +39 -0
  199. package/dist/options.d.ts +40 -0
  200. package/dist/options.d.ts.map +1 -0
  201. package/dist/options.js +8 -0
  202. package/dist/options.mjs +12 -0
  203. package/dist/resolve/builtins.cjs +73 -0
  204. package/dist/resolve/builtins.d.cts +68 -0
  205. package/dist/resolve/builtins.d.ts +69 -0
  206. package/dist/resolve/builtins.d.ts.map +1 -0
  207. package/dist/resolve/builtins.js +64 -0
  208. package/dist/resolve/builtins.mjs +53 -0
  209. package/dist/resolve/component-globals.cjs +272 -0
  210. package/dist/resolve/component-globals.d.cts +88 -0
  211. package/dist/resolve/component-globals.d.ts +89 -0
  212. package/dist/resolve/component-globals.d.ts.map +1 -0
  213. package/dist/resolve/component-globals.js +160 -0
  214. package/dist/resolve/component-globals.mjs +249 -0
  215. package/dist/resolve/component-resolver.cjs +80 -0
  216. package/dist/resolve/component-resolver.d.cts +68 -0
  217. package/dist/resolve/component-resolver.d.ts +69 -0
  218. package/dist/resolve/component-resolver.d.ts.map +1 -0
  219. package/dist/resolve/component-resolver.js +95 -0
  220. package/dist/resolve/component-resolver.mjs +59 -0
  221. package/dist/resolve/load-directive.cjs +93 -0
  222. package/dist/resolve/load-directive.d.cts +53 -0
  223. package/dist/resolve/load-directive.d.ts +54 -0
  224. package/dist/resolve/load-directive.d.ts.map +1 -0
  225. package/dist/resolve/load-directive.js +93 -0
  226. package/dist/resolve/load-directive.mjs +72 -0
  227. package/dist/resolve/resolve-ir.cjs +108 -0
  228. package/dist/resolve/resolve-ir.d.cts +53 -0
  229. package/dist/resolve/resolve-ir.d.ts +54 -0
  230. package/dist/resolve/resolve-ir.d.ts.map +1 -0
  231. package/dist/resolve/resolve-ir.js +58 -0
  232. package/dist/resolve/resolve-ir.mjs +85 -0
  233. package/dist/resolve/write-globals.cjs +383 -0
  234. package/dist/resolve/write-globals.d.cts +36 -0
  235. package/dist/resolve/write-globals.d.ts +37 -0
  236. package/dist/resolve/write-globals.d.ts.map +1 -0
  237. package/dist/resolve/write-globals.js +169 -0
  238. package/dist/resolve/write-globals.mjs +362 -0
  239. package/dist/server-fns-VZLHMQTC.mjs +79 -0
  240. package/dist/server-functions-UAZKOLZW.mjs +82 -0
  241. package/dist/transform/bindings.cjs +71 -0
  242. package/dist/transform/bindings.d.cts +16 -0
  243. package/dist/transform/bindings.d.ts +17 -0
  244. package/dist/transform/bindings.d.ts.map +1 -0
  245. package/dist/transform/bindings.js +69 -0
  246. package/dist/transform/bindings.mjs +50 -0
  247. package/dist/transform/index.cjs +3837 -0
  248. package/dist/transform/index.d.cts +15 -0
  249. package/dist/transform/index.d.ts +16 -0
  250. package/dist/transform/index.d.ts.map +1 -0
  251. package/dist/transform/index.js +12 -0
  252. package/dist/transform/index.mjs +4882 -0
  253. package/dist/transform/intrinsics.cjs +261 -0
  254. package/dist/transform/intrinsics.d.cts +33 -0
  255. package/dist/transform/intrinsics.d.ts +34 -0
  256. package/dist/transform/intrinsics.d.ts.map +1 -0
  257. package/dist/transform/intrinsics.js +120 -0
  258. package/dist/transform/intrinsics.mjs +238 -0
  259. package/dist/transform/props.cjs +441 -0
  260. package/dist/transform/props.d.cts +45 -0
  261. package/dist/transform/props.d.ts +46 -0
  262. package/dist/transform/props.d.ts.map +1 -0
  263. package/dist/transform/props.js +221 -0
  264. package/dist/transform/props.mjs +1487 -0
  265. package/dist/transform/server-fn-id.cjs +35 -0
  266. package/dist/transform/server-fn-id.d.cts +9 -0
  267. package/dist/transform/server-fn-id.d.ts +10 -0
  268. package/dist/transform/server-fn-id.d.ts.map +1 -0
  269. package/dist/transform/server-fn-id.js +18 -0
  270. package/dist/transform/server-fn-id.mjs +14 -0
  271. package/dist/transform/server-fns.cjs +114 -0
  272. package/dist/transform/server-fns.d.cts +12 -0
  273. package/dist/transform/server-fns.d.ts +13 -0
  274. package/dist/transform/server-fns.d.ts.map +1 -0
  275. package/dist/transform/server-fns.js +94 -0
  276. package/dist/transform/server-fns.mjs +1160 -0
  277. package/dist/transform/source-locations.cjs +393 -0
  278. package/dist/transform/source-locations.d.cts +48 -0
  279. package/dist/transform/source-locations.d.ts +49 -0
  280. package/dist/transform/source-locations.d.ts.map +1 -0
  281. package/dist/transform/source-locations.js +303 -0
  282. package/dist/transform/source-locations.mjs +370 -0
  283. package/dist/transform/styles.cjs +606 -0
  284. package/dist/transform/styles.d.cts +237 -0
  285. package/dist/transform/styles.d.ts +238 -0
  286. package/dist/transform/styles.d.ts.map +1 -0
  287. package/dist/transform/styles.js +743 -0
  288. package/dist/transform/styles.mjs +671 -0
  289. package/dist/transform/templates.cjs +3806 -0
  290. package/dist/transform/templates.d.cts +82 -0
  291. package/dist/transform/templates.d.ts +83 -0
  292. package/dist/transform/templates.d.ts.map +1 -0
  293. package/dist/transform/templates.js +613 -0
  294. package/dist/transform/templates.mjs +4852 -0
  295. package/dist/transform-3W45L3EA.mjs +951 -0
  296. package/dist/tsconfig.lib.tsbuildinfo +1 -0
  297. package/dist/vite-styles.cjs +223 -0
  298. package/dist/vite-styles.d.cts +68 -0
  299. package/dist/vite-styles.d.ts +69 -0
  300. package/dist/vite-styles.d.ts.map +1 -0
  301. package/dist/vite-styles.js +241 -0
  302. package/dist/vite-styles.mjs +214 -0
  303. package/package.json +141 -0
package/dist/index.mjs ADDED
@@ -0,0 +1,1949 @@
1
+ /*! @fluixi/compiler v1.0.0-alpha.100 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
2
+
3
+ // src/analyze/reactive-expr.ts
4
+ var STABLE_MEMBER = "children";
5
+ function isReactiveShape(shape) {
6
+ switch (shape.kind) {
7
+ case "call":
8
+ return true;
9
+ case "member":
10
+ return shape.property !== STABLE_MEMBER;
11
+ case "compound":
12
+ return shape.parts.some(isReactiveShape);
13
+ case "opaque":
14
+ return false;
15
+ }
16
+ }
17
+
18
+ // src/lower/template.ts
19
+ import {
20
+ parseTemplate
21
+ } from "@fluixi/template-parser";
22
+
23
+ // src/resolve/load-directive.ts
24
+ var EAGER = { kind: "eager" };
25
+ var DEFAULT_INTERACTION_EVENTS = ["pointerdown", "focusin", "keydown"];
26
+ var STRATEGIES = /* @__PURE__ */ new Set(["eager", "idle", "visible", "interaction", "media", "never"]);
27
+ var LoadDirectiveError = class extends Error {
28
+ };
29
+ function parseLoadDirective(name, value) {
30
+ const strategy = name.slice("load:".length);
31
+ if (!STRATEGIES.has(strategy)) {
32
+ throw new LoadDirectiveError(
33
+ `Unknown load strategy 'load:${strategy}'. Expected one of ${[...STRATEGIES].join(", ")}.`
34
+ );
35
+ }
36
+ switch (strategy) {
37
+ case "eager":
38
+ return EAGER;
39
+ case "idle":
40
+ return { kind: "idle" };
41
+ case "never":
42
+ return { kind: "never" };
43
+ case "visible":
44
+ return value ? { kind: "visible", rootMargin: value } : { kind: "visible" };
45
+ case "interaction":
46
+ return {
47
+ kind: "interaction",
48
+ events: value ? splitEvents(value) : [...DEFAULT_INTERACTION_EVENTS]
49
+ };
50
+ case "media":
51
+ if (!value) {
52
+ throw new LoadDirectiveError(
53
+ `'load:media' needs a query, e.g. load:media="(min-width: 1024px)".`
54
+ );
55
+ }
56
+ return { kind: "media", query: value };
57
+ default:
58
+ throw new LoadDirectiveError(`Unhandled load strategy '${strategy}'.`);
59
+ }
60
+ }
61
+ function splitEvents(value) {
62
+ const events = value.split(/[\s,]+/).map((e) => e.trim()).filter(Boolean);
63
+ if (events.length === 0) {
64
+ throw new LoadDirectiveError(`'load:interaction' was given no event names.`);
65
+ }
66
+ return events;
67
+ }
68
+ function isDeferred(strategy) {
69
+ return strategy.kind !== "eager" && strategy.kind !== "never";
70
+ }
71
+
72
+ // src/codegen/serialize-static.ts
73
+ var VOID_ELEMENTS = /* @__PURE__ */ new Set([
74
+ "area",
75
+ "base",
76
+ "br",
77
+ "col",
78
+ "embed",
79
+ "hr",
80
+ "img",
81
+ "input",
82
+ "link",
83
+ "meta",
84
+ "param",
85
+ "source",
86
+ "track",
87
+ "wbr"
88
+ ]);
89
+ var HTML_NAME = {
90
+ className: "class",
91
+ htmlFor: "for"
92
+ };
93
+ var PROPERTY_ONLY = /* @__PURE__ */ new Set([
94
+ "innerHTML",
95
+ "outerHTML",
96
+ "innerText",
97
+ "textContent",
98
+ "value",
99
+ "checked",
100
+ "selected",
101
+ "muted",
102
+ "defaultValue",
103
+ "defaultChecked",
104
+ "children",
105
+ "ref"
106
+ ]);
107
+ var RAW_TEXT_ELEMENTS = /* @__PURE__ */ new Set(["script", "style", "textarea", "title"]);
108
+ function isRawTextElement(tag) {
109
+ return RAW_TEXT_ELEMENTS.has(tag);
110
+ }
111
+ function htmlAttrName(name) {
112
+ return HTML_NAME[name] ?? name;
113
+ }
114
+ function isPlainLiteralAttr(prop) {
115
+ if (prop.kind !== "attr") return false;
116
+ if (prop.expr !== void 0) return false;
117
+ if (prop.name.includes(":")) return false;
118
+ return !PROPERTY_ONLY.has(prop.name);
119
+ }
120
+ function isSerializable(node) {
121
+ if (!node.static) return false;
122
+ if (isRawTextElement(node.tag)) return false;
123
+ for (const prop of node.props) {
124
+ if (!isPlainLiteralAttr(prop)) return false;
125
+ }
126
+ for (const child of node.children) {
127
+ if (child.kind === "text") continue;
128
+ if (child.kind === "element" && isSerializable(child)) continue;
129
+ return false;
130
+ }
131
+ return true;
132
+ }
133
+ function serializeStatic(node) {
134
+ const attrs = node.props.map(serializeProp).filter(Boolean).join("");
135
+ const open = `<${node.tag}${attrs}>`;
136
+ if (VOID_ELEMENTS.has(node.tag)) return open;
137
+ return `${open}${node.children.map(serializeChild).join("")}</${node.tag}>`;
138
+ }
139
+ function serializeChild(child) {
140
+ if (child.kind === "text") return escapeText(child.value);
141
+ if (child.kind !== "element") throw new Error(`serializeStatic: unexpected ${child.kind}`);
142
+ return serializeStatic(child);
143
+ }
144
+ function serializeProp(prop) {
145
+ const name = HTML_NAME[prop.name] ?? prop.name;
146
+ const value = prop.literal;
147
+ if (value === true || value === void 0) return ` ${name}`;
148
+ if (value === false || value === null) return "";
149
+ return ` ${name}="${escapeAttr(String(value))}"`;
150
+ }
151
+ function escapeAttr(value) {
152
+ return value.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
153
+ }
154
+ function escapeText(value) {
155
+ return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
156
+ }
157
+ function templatePositions(root) {
158
+ const pos = [];
159
+ let file;
160
+ const walk2 = (el) => {
161
+ file ??= el.at?.file;
162
+ pos.push(el.at?.line ?? 0, el.at?.column ?? 0);
163
+ for (const child of el.children) if (child.kind === "element") walk2(child);
164
+ };
165
+ walk2(root);
166
+ return file && pos.some((n) => n !== 0) ? { file, pos } : void 0;
167
+ }
168
+
169
+ // src/codegen/partial-template.ts
170
+ var HOLE_START = "<!--fx-->";
171
+ var HOLE_END = "<!--fx/-->";
172
+ function isHole(node) {
173
+ return node.kind === "expr" || node.kind === "component" || node.kind === "control";
174
+ }
175
+ function isTemplateChild(node) {
176
+ return node.kind === "text" || node.kind === "element" && isTemplateElement(node);
177
+ }
178
+ function isTemplateElement(node) {
179
+ if (node.svg) return false;
180
+ if (isRawTextElement(node.tag)) return false;
181
+ if (!node.props.every((p) => isPlainLiteralAttr(p))) return false;
182
+ return node.children.every((c) => isTemplateChild(c) || isHole(c));
183
+ }
184
+ function containsHole(node) {
185
+ if (isHole(node)) return true;
186
+ const children = node.children;
187
+ return children ? children.some(containsHole) : false;
188
+ }
189
+ function addressable(el) {
190
+ for (let i = 0; i < el.children.length; i++) {
191
+ const child = el.children[i];
192
+ if (child.kind === "text") {
193
+ if (child.value === "") return false;
194
+ if (el.children[i + 1]?.kind === "text") return false;
195
+ }
196
+ }
197
+ return el.children.every((c) => c.kind !== "element" || addressable(c));
198
+ }
199
+ function planPartialTemplate(root) {
200
+ if (!isTemplateElement(root)) return null;
201
+ if (!addressable(root)) return null;
202
+ if (!root.children.some(containsHole)) return null;
203
+ const steps = [];
204
+ const holes = [];
205
+ let refCount = 0;
206
+ const declare = (expr) => {
207
+ const ref = `_n$${refCount++}`;
208
+ steps.push({ ref, expr });
209
+ return ref;
210
+ };
211
+ walk2(root, "_el$");
212
+ return { html: serializeWithMarkers(root), tag: root.tag, steps, holes };
213
+ function walk2(el, elementRef) {
214
+ let last = -1;
215
+ el.children.forEach((child, i) => {
216
+ if (containsHole(child)) last = i;
217
+ });
218
+ let previous = null;
219
+ for (let i = 0; i <= last; i++) {
220
+ const child = el.children[i];
221
+ const expr = previous ? `${previous}.nextSibling` : `${elementRef}.firstChild`;
222
+ if (isHole(child)) {
223
+ const startRef = declare(expr);
224
+ const endRef = declare(`holeEnd(${startRef})`);
225
+ holes.push({ parentRef: elementRef, startRef, endRef, node: child });
226
+ previous = endRef;
227
+ continue;
228
+ }
229
+ const ref = declare(expr);
230
+ if (child.kind === "element" && containsHole(child)) walk2(child, ref);
231
+ previous = ref;
232
+ }
233
+ }
234
+ }
235
+ function serializeWithMarkers(el) {
236
+ return serializeStatic(withSentinels(el)).split(SENTINEL).join(HOLE_START + HOLE_END);
237
+ }
238
+ function withSentinels(el) {
239
+ return {
240
+ ...el,
241
+ children: el.children.map(
242
+ (child) => isHole(child) ? { kind: "text", value: SENTINEL } : child.kind === "element" ? withSentinels(child) : child
243
+ )
244
+ };
245
+ }
246
+ var SENTINEL = "\0fx-hole\0";
247
+
248
+ // src/codegen/contract.ts
249
+ var RUNTIME_CONTRACT_V1 = {
250
+ version: 1,
251
+ module: "@fluixi/dom",
252
+ symbols: [
253
+ "createNativeElement",
254
+ "insert",
255
+ "spread",
256
+ "setAttribute",
257
+ "delegateEvents",
258
+ "createComponent",
259
+ "createMemo",
260
+ "untrack",
261
+ "Show",
262
+ "For",
263
+ "Index",
264
+ "Switch",
265
+ "Match",
266
+ "Dynamic",
267
+ "ErrorBoundary"
268
+ ]
269
+ };
270
+ var RUNTIME_CONTRACT_V2 = {
271
+ version: 2,
272
+ module: "@fluixi/dom",
273
+ symbols: [...RUNTIME_CONTRACT_V1.symbols, "template", "cloneTemplate", "walk"]
274
+ };
275
+
276
+ // src/analyze/intrinsics.ts
277
+ var REACTIVE_MODULE = "@fluixi/reactive/signal";
278
+ var INTRINSICS = {
279
+ $signal: { export: "signal", module: REACTIVE_MODULE, returns: "signal-handle" },
280
+ $memo: { export: "memo", module: REACTIVE_MODULE, returns: "memo-handle" },
281
+ $effect: { export: "effect", module: REACTIVE_MODULE, returns: "effect" },
282
+ $store: { export: "store", module: "@fluixi/reactive/store", returns: "store-handle" },
283
+ $resource: { export: "resource", module: REACTIVE_MODULE, returns: "resource-handle" },
284
+ $cachedResource: { export: "cachedResource", module: "@fluixi/reactive/cached-resource", returns: "resource-handle" },
285
+ // No short runtime form for these yet, so the intrinsic stands for the `create*`
286
+ // name. Still worth having: no import to write, and when a shorter form is
287
+ // designed, the change is this line rather than a compiler pass.
288
+ $selector: { export: "createSelector", module: REACTIVE_MODULE, returns: "memo-accessor" },
289
+ $deferred: { export: "createDeferred", module: REACTIVE_MODULE, returns: "memo-accessor" },
290
+ // Not value constructors, but the compiler has to know them: they change what a read
291
+ // does. `untrack` suppresses dependency collection, which is exactly the kind of thing
292
+ // dependency analysis must not guess at.
293
+ $untrack: { export: "untrack", module: REACTIVE_MODULE, returns: "plain" },
294
+ $untrackStore: { export: "untrackStore", module: "@fluixi/reactive/store", returns: "plain" },
295
+ // Scopes, scheduling and lifecycle: no value to classify, but the same authoring promise,
296
+ // no import to write. `$cleanup` registers a callback on the current owner (`onCleanup`).
297
+ $batch: { export: "batch", module: REACTIVE_MODULE, returns: "plain" },
298
+ $cleanup: { export: "onCleanup", module: REACTIVE_MODULE, returns: "plain" },
299
+ $root: { export: "root", module: REACTIVE_MODULE, returns: "plain" },
300
+ $context: { export: "context", module: REACTIVE_MODULE, returns: "plain" },
301
+ $renderEffect: { export: "renderEffect", module: REACTIVE_MODULE, returns: "effect" },
302
+ $computed: { export: "computed", module: REACTIVE_MODULE, returns: "effect" },
303
+ // Storage for where the code runs, and a signal kept in it. `$persisted` is a signal
304
+ // handle as far as reads go: the same accessor with `set` on it.
305
+ $storage: { export: "useStorage", module: "@fluixi/core/storage", returns: "plain" },
306
+ $asyncStorage: { export: "useAsyncStorage", module: "@fluixi/core/storage", returns: "plain" },
307
+ $persisted: { export: "persisted", module: "@fluixi/core/storage", returns: "signal-handle" },
308
+ // An environment variable, public or server-only; the browser build refuses a secret.
309
+ $env: { export: "env", module: "@fluixi/start/env", returns: "plain" }
310
+ };
311
+ var TAG_INTRINSICS = {
312
+ $html: { export: "html", module: "@fluixi/core" },
313
+ $svg: { export: "svg", module: "@fluixi/core" },
314
+ $css: { export: "css", module: "@fluixi/core" }
315
+ };
316
+ var INTRINSIC_CALL = new RegExp(`\\$(?:${Object.keys(INTRINSICS).map((n) => n.slice(1)).join("|")})\\s*\\(`);
317
+
318
+ // src/transform/source-locations.ts
319
+ var SOURCE_MARKER = "__fx_source";
320
+ var HOLE_MARKER = "__fx_hole";
321
+ var markHole = (accessor, line, column, name) => `(globalThis.${HOLE_MARKER} ?? ((f) => f))(${accessor},${line},${column}${name === void 0 ? "" : `,${JSON.stringify(name)}`})`;
322
+ var PROPS_MARKER = "__fx_props";
323
+ var markProps = (object, at) => `(globalThis.${PROPS_MARKER} ?? ((p) => p))(${object},${JSON.stringify(at)})`;
324
+
325
+ // src/analyze/paren.ts
326
+ function skipQuoted(src, start) {
327
+ const quote = src[start];
328
+ for (let i = start + 1; i < src.length; i++) {
329
+ const c = src[i];
330
+ if (c === "\\") i++;
331
+ else if (c === quote) return i + 1;
332
+ else if (c === "\n") return -1;
333
+ }
334
+ return -1;
335
+ }
336
+ function skipTemplate(src, start) {
337
+ let i = start + 1;
338
+ while (i < src.length) {
339
+ const c = src[i];
340
+ if (c === "\\") {
341
+ i += 2;
342
+ } else if (c === "`") {
343
+ return i + 1;
344
+ } else if (c === "$" && src[i + 1] === "{") {
345
+ let depth = 1;
346
+ i += 2;
347
+ while (i < src.length && depth > 0) {
348
+ const k = src[i];
349
+ if (k === "\\") i += 2;
350
+ else if (k === "`") {
351
+ const end = skipTemplate(src, i);
352
+ if (end < 0) return -1;
353
+ i = end;
354
+ } else if (k === '"' || k === "'") {
355
+ const end = skipQuoted(src, i);
356
+ if (end < 0) return -1;
357
+ i = end;
358
+ } else {
359
+ if (k === "{") depth++;
360
+ else if (k === "}") depth--;
361
+ i++;
362
+ }
363
+ }
364
+ } else {
365
+ i++;
366
+ }
367
+ }
368
+ return -1;
369
+ }
370
+ function skipRegex(src, start) {
371
+ let inClass = false;
372
+ for (let i = start + 1; i < src.length; i++) {
373
+ const c = src[i];
374
+ if (c === "\\") i++;
375
+ else if (c === "[") inClass = true;
376
+ else if (c === "]") inClass = false;
377
+ else if (c === "\n") return -1;
378
+ else if (c === "/" && !inClass) {
379
+ let end = i + 1;
380
+ while (end < src.length && /[a-z]/i.test(src[end])) end++;
381
+ return end;
382
+ }
383
+ }
384
+ return -1;
385
+ }
386
+ function divides(prev) {
387
+ return prev !== "" && /[A-Za-z0-9_$)\]]/.test(prev);
388
+ }
389
+ function topLevelComma(src) {
390
+ let depth = 0;
391
+ let prev = "";
392
+ let i = 0;
393
+ while (i < src.length) {
394
+ const c = src[i];
395
+ if (c === '"' || c === "'") {
396
+ const end = skipQuoted(src, i);
397
+ if (end < 0) return null;
398
+ i = end;
399
+ prev = c;
400
+ } else if (c === "`") {
401
+ const end = skipTemplate(src, i);
402
+ if (end < 0) return null;
403
+ i = end;
404
+ prev = c;
405
+ } else if (c === "/" && src[i + 1] === "/") {
406
+ return null;
407
+ } else if (c === "/" && src[i + 1] === "*") {
408
+ const end = src.indexOf("*/", i + 2);
409
+ if (end < 0) return null;
410
+ i = end + 2;
411
+ } else if (c === "/" && !divides(prev)) {
412
+ const end = skipRegex(src, i);
413
+ if (end < 0) return null;
414
+ i = end;
415
+ prev = "/";
416
+ } else {
417
+ if (c === "(" || c === "[" || c === "{") depth++;
418
+ else if (c === ")" || c === "]" || c === "}") {
419
+ depth--;
420
+ if (depth < 0) return null;
421
+ } else if (c === "," && depth === 0) return true;
422
+ if (!/\s/.test(c)) prev = c;
423
+ i++;
424
+ }
425
+ }
426
+ return depth === 0 ? false : null;
427
+ }
428
+ function paren(code, position) {
429
+ const src = code.trim();
430
+ if (src === "") return `(${code})`;
431
+ if (position === "arrowBody" && src[0] === "{") return `(${code})`;
432
+ return topLevelComma(src) === false ? code : `(${code})`;
433
+ }
434
+
435
+ // src/codegen/backends/imperative.ts
436
+ var CONTROL_COMPONENT = {
437
+ show: "Show",
438
+ for: "For",
439
+ index: "Index",
440
+ switch: "Switch",
441
+ match: "Match",
442
+ dynamic: "Dynamic",
443
+ errorBoundary: "ErrorBoundary",
444
+ suspense: "Suspense"
445
+ };
446
+ function isIdent(name) {
447
+ return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(name);
448
+ }
449
+ function propKey(name) {
450
+ return isIdent(name) ? name : JSON.stringify(name);
451
+ }
452
+ function propValue(p) {
453
+ if (p.expr !== void 0) {
454
+ if (p.name === "ref" && p.at)
455
+ return markHole(paren(p.expr, "value"), p.at.line, p.at.column, p.expr);
456
+ if (!p.reactive) return paren(p.expr, "value");
457
+ const accessor = `() => ${paren(p.expr, "arrowBody")}`;
458
+ return p.at ? markHole(accessor, p.at.line, p.at.column, p.directive) : accessor;
459
+ }
460
+ return JSON.stringify(p.literal ?? true);
461
+ }
462
+ function componentPropValue(p) {
463
+ if (p.expr !== void 0) return paren(p.expr, "value");
464
+ return JSON.stringify(p.literal ?? true);
465
+ }
466
+ function emitProps(props, childrenExpr, used) {
467
+ const spreads = props.filter((p) => p.kind === "spread");
468
+ const normal = props.filter((p) => p.kind !== "spread");
469
+ const entries = normal.map((p) => `${propKey(p.name)}: ${propValue(p)}`);
470
+ if (childrenExpr != null) entries.push(`children: ${childrenExpr}`);
471
+ const obj = `{ ${entries.join(", ")} }`;
472
+ if (spreads.length > 0) {
473
+ used.add("mergeProps");
474
+ return `mergeProps(${spreads.map((s) => s.expr).join(", ")}, ${obj})`;
475
+ }
476
+ return obj;
477
+ }
478
+ function markBind(code, at) {
479
+ return at ? markHole(code, at.line, at.column) : code;
480
+ }
481
+ function emitChildren(children, used, templates) {
482
+ if (children.length === 1) return emitNode(children[0], used, templates);
483
+ let deferred = false;
484
+ const items = children.map((child) => {
485
+ const code = emitNode(child, used, templates);
486
+ if (child.kind === "element" && deferred) {
487
+ used.add("deferElement");
488
+ return `deferElement(() => ${paren(code, "arrowBody")})`;
489
+ }
490
+ if (child.kind === "component" || child.kind === "control" || child.kind === "expr" && child.reactive) deferred = true;
491
+ return code;
492
+ });
493
+ return `[${items.join(", ")}]`;
494
+ }
495
+ function emitComponent(name, props, children, used, templates, at) {
496
+ used.add("createMemo");
497
+ used.add("createComponent");
498
+ const spreads = props.filter((p) => p.kind === "spread");
499
+ const normal = props.filter((p) => p.kind !== "spread");
500
+ const bodies = normal.map((p) => [p.name, componentPropValue(p)]);
501
+ if (children.length > 0) {
502
+ bodies.push(["children", emitChildren(children, used, templates)]);
503
+ }
504
+ let obj = `{ ${bodies.map(([name2, body]) => `get ${propKey(name2)}() { return ${body}; }`).join(", ")} }`;
505
+ if (bodies.some(([, body]) => /\bthis\b/.test(body))) {
506
+ const thunks = bodies.map(([name2, body]) => `${JSON.stringify(name2)}: () => (${body})`);
507
+ const getters = bodies.map(([name2]) => `get ${propKey(name2)}() { return _$t[${JSON.stringify(name2)}](); }`);
508
+ obj = `((_$t) => ({ ${getters.join(", ")} }))({ ${thunks.join(", ")} })`;
509
+ }
510
+ if (spreads.length > 0) {
511
+ used.add("mergeProps");
512
+ obj = `mergeProps(${spreads.map((s) => s.expr).join(", ")}, ${obj})`;
513
+ }
514
+ const propAt = {};
515
+ for (const p of normal) if (p.at) propAt[p.name] = [p.at.line, p.at.column];
516
+ if (Object.keys(propAt).length) obj = markProps(obj, propAt);
517
+ const mark = at ? `globalThis.${SOURCE_MARKER}?.(${JSON.stringify(at.file)},${at.line},${at.column},${JSON.stringify(name)}), ` : "";
518
+ return `createMemo(${paren(`${mark}() => createComponent(${name}, ${obj})`, "value")})`;
519
+ }
520
+ function staticAttrAssignment(el, prop) {
521
+ const name = htmlAttrName(prop.name);
522
+ const value = prop.literal;
523
+ if (value === true || value === void 0) return `${el}.setAttribute(${JSON.stringify(name)}, "");`;
524
+ if (value === false || value === null) return "";
525
+ return `${el}.setAttribute(${JSON.stringify(name)}, ${JSON.stringify(String(value))});`;
526
+ }
527
+ var partial = false;
528
+ function emitNode(node, used, templates) {
529
+ switch (node.kind) {
530
+ case "text":
531
+ return JSON.stringify(node.value);
532
+ case "expr": {
533
+ if (!node.reactive) return paren(node.code, "value");
534
+ const accessor = `() => ${paren(node.code, "arrowBody")}`;
535
+ return node.at ? markHole(accessor, node.at.line, node.at.column) : accessor;
536
+ }
537
+ case "fragment":
538
+ if (node.children.length === 0) return "null";
539
+ return emitChildren(node.children, used, templates);
540
+ case "component":
541
+ return markBind(emitComponent(node.name, node.props, node.children, used, templates, node.at), node.bindAt ?? node.at);
542
+ case "control": {
543
+ const name = CONTROL_COMPONENT[node.control] ?? node.control;
544
+ used.add(name);
545
+ return markBind(emitComponent(name, node.props, node.children, used, templates), node.bindAt);
546
+ }
547
+ case "element": {
548
+ if (templates && node.static && !node.svg && isSerializable(node)) {
549
+ used.add("templateNode");
550
+ const id = `_tmpl$${templates.length}`;
551
+ templates.push({ id, html: serializeStatic(node), tag: node.tag, svg: false });
552
+ const at = templatePositions(node);
553
+ return at ? `templateNode(${id}, ${JSON.stringify(node.tag)}, false, false, ${JSON.stringify(at)})` : `templateNode(${id}, ${JSON.stringify(node.tag)})`;
554
+ }
555
+ if (templates && partial) {
556
+ const plan = planPartialTemplate(node);
557
+ if (plan) {
558
+ used.add("templateNode");
559
+ used.add("insert");
560
+ used.add("holeEnd");
561
+ used.add("holeContent");
562
+ used.add("holeScope");
563
+ const id = `_tmpl$${templates.length}`;
564
+ templates.push({ id, html: plan.html, tag: plan.tag, svg: false });
565
+ const at = templatePositions(node);
566
+ const lines = [
567
+ `const _el$ = templateNode(${id}, ${JSON.stringify(plan.tag)}, true${at ? `, false, ${JSON.stringify(at)}` : ""});`
568
+ ];
569
+ for (const step of plan.steps) lines.push(`const ${step.ref} = ${step.expr};`);
570
+ for (const hole of plan.holes) {
571
+ lines.push(
572
+ `insert(${hole.parentRef}, holeScope(${hole.startRef}, () => ${paren(emitNode(hole.node, used, templates), "arrowBody")}), ${hole.endRef}, holeContent(${hole.startRef}, ${hole.endRef}));`
573
+ );
574
+ }
575
+ lines.push("return _el$;");
576
+ return `(() => { ${lines.join(" ")} })()`;
577
+ }
578
+ }
579
+ used.add("createNativeElement");
580
+ const tag = JSON.stringify(node.tag);
581
+ const el = "_el$";
582
+ const parts = [];
583
+ const createArgs = node.at ? `${tag}, ${node.svg}, ${JSON.stringify(node.at)}` : node.svg ? `${tag}, true` : tag;
584
+ parts.push(`const ${el} = createNativeElement(${createArgs});`);
585
+ if (node.props.length > 0) {
586
+ if (!node.svg && node.props.every(isPlainLiteralAttr)) {
587
+ for (const p of node.props) parts.push(staticAttrAssignment(el, p));
588
+ } else {
589
+ used.add("spread");
590
+ const svgFlag = node.svg ? ", isSVG: true" : "";
591
+ const accessors = node.props.filter((p) => p.kind !== "spread" && p.expr !== void 0 && p.reactive && p.name !== "ref").map((p) => p.name);
592
+ const customFlag = node.tag.includes("-") ? `, isCustomElement: true, accessors: ${JSON.stringify(accessors)}` : "";
593
+ parts.push(
594
+ `spread({ element: ${el}, props: ${emitProps(node.props, null, used)}${svgFlag}${customFlag} });`
595
+ );
596
+ }
597
+ }
598
+ for (const child of node.children) {
599
+ used.add("insert");
600
+ const childCode = emitNode(child, used, templates);
601
+ const anchored = child.kind === "expr" && (child.reactive || !isLiteralCode(child.code)) || child.kind === "component" || child.kind === "control";
602
+ parts.push(anchored ? `insert(${el}, ${childCode}, null);` : `insert(${el}, ${childCode});`);
603
+ }
604
+ parts.push(`return ${el};`);
605
+ return `(() => { ${parts.join(" ")} })()`;
606
+ }
607
+ }
608
+ }
609
+ var LITERAL = /^\s*(?:'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"|`[^`$]*`|-?\d[\d_.eE+-]*|true|false|null|undefined)\s*$/;
610
+ var isLiteralCode = (code) => LITERAL.test(code);
611
+ function inlineTemplates(code, templates) {
612
+ if (!templates || templates.length === 0) return code;
613
+ const byId = new Map(templates.map((t) => [t.id, JSON.stringify(t.html)]));
614
+ return code.replace(/_tmpl\$\d+/g, (id) => byId.get(id) ?? id);
615
+ }
616
+ var imperativeBackend = {
617
+ name: "imperative",
618
+ contract: RUNTIME_CONTRACT_V1,
619
+ emit(node, options) {
620
+ const used = /* @__PURE__ */ new Set();
621
+ const templates = options?.templateClone !== false ? [] : void 0;
622
+ partial = options?.partialTemplates === true;
623
+ const code = emitNode(node, used, templates);
624
+ return { code, imports: Array.from(used), templates };
625
+ }
626
+ };
627
+
628
+ // src/lower/text.ts
629
+ function cleanTemplateText(value) {
630
+ const lines = value.split(/\r\n|\n|\r/);
631
+ let lastNonEmpty = 0;
632
+ for (let i = 0; i < lines.length; i++) {
633
+ if (/[^ \t]/.test(lines[i])) lastNonEmpty = i;
634
+ }
635
+ let out = "";
636
+ for (let i = 0; i < lines.length; i++) {
637
+ let line = lines[i].replace(/\t/g, " ");
638
+ if (i !== 0) line = line.replace(/^ +/, "");
639
+ if (i !== lines.length - 1) line = line.replace(/ +$/, "");
640
+ if (!line) continue;
641
+ if (i !== lastNonEmpty) line += " ";
642
+ out += line;
643
+ }
644
+ return out;
645
+ }
646
+
647
+ // src/lower/entities.ts
648
+ var NAMED = {
649
+ quot: 34,
650
+ amp: 38,
651
+ apos: 39,
652
+ lt: 60,
653
+ gt: 62,
654
+ nbsp: 160,
655
+ iexcl: 161,
656
+ cent: 162,
657
+ pound: 163,
658
+ curren: 164,
659
+ yen: 165,
660
+ brvbar: 166,
661
+ sect: 167,
662
+ uml: 168,
663
+ copy: 169,
664
+ ordf: 170,
665
+ laquo: 171,
666
+ not: 172,
667
+ shy: 173,
668
+ reg: 174,
669
+ macr: 175,
670
+ deg: 176,
671
+ plusmn: 177,
672
+ sup2: 178,
673
+ sup3: 179,
674
+ acute: 180,
675
+ micro: 181,
676
+ para: 182,
677
+ middot: 183,
678
+ cedil: 184,
679
+ sup1: 185,
680
+ ordm: 186,
681
+ raquo: 187,
682
+ frac14: 188,
683
+ frac12: 189,
684
+ frac34: 190,
685
+ iquest: 191,
686
+ Agrave: 192,
687
+ Aacute: 193,
688
+ Acirc: 194,
689
+ Atilde: 195,
690
+ Auml: 196,
691
+ Aring: 197,
692
+ AElig: 198,
693
+ Ccedil: 199,
694
+ Egrave: 200,
695
+ Eacute: 201,
696
+ Ecirc: 202,
697
+ Euml: 203,
698
+ Igrave: 204,
699
+ Iacute: 205,
700
+ Icirc: 206,
701
+ Iuml: 207,
702
+ ETH: 208,
703
+ Ntilde: 209,
704
+ Ograve: 210,
705
+ Oacute: 211,
706
+ Ocirc: 212,
707
+ Otilde: 213,
708
+ Ouml: 214,
709
+ times: 215,
710
+ Oslash: 216,
711
+ Ugrave: 217,
712
+ Uacute: 218,
713
+ Ucirc: 219,
714
+ Uuml: 220,
715
+ Yacute: 221,
716
+ THORN: 222,
717
+ szlig: 223,
718
+ agrave: 224,
719
+ aacute: 225,
720
+ acirc: 226,
721
+ atilde: 227,
722
+ auml: 228,
723
+ aring: 229,
724
+ aelig: 230,
725
+ ccedil: 231,
726
+ egrave: 232,
727
+ eacute: 233,
728
+ ecirc: 234,
729
+ euml: 235,
730
+ igrave: 236,
731
+ iacute: 237,
732
+ icirc: 238,
733
+ iuml: 239,
734
+ eth: 240,
735
+ ntilde: 241,
736
+ ograve: 242,
737
+ oacute: 243,
738
+ ocirc: 244,
739
+ otilde: 245,
740
+ ouml: 246,
741
+ divide: 247,
742
+ oslash: 248,
743
+ ugrave: 249,
744
+ uacute: 250,
745
+ ucirc: 251,
746
+ uuml: 252,
747
+ yacute: 253,
748
+ thorn: 254,
749
+ yuml: 255,
750
+ OElig: 338,
751
+ oelig: 339,
752
+ Scaron: 352,
753
+ scaron: 353,
754
+ Yuml: 376,
755
+ fnof: 402,
756
+ circ: 710,
757
+ tilde: 732,
758
+ Alpha: 913,
759
+ Beta: 914,
760
+ Gamma: 915,
761
+ Delta: 916,
762
+ Epsilon: 917,
763
+ Zeta: 918,
764
+ Eta: 919,
765
+ Theta: 920,
766
+ Iota: 921,
767
+ Kappa: 922,
768
+ Lambda: 923,
769
+ Mu: 924,
770
+ Nu: 925,
771
+ Xi: 926,
772
+ Omicron: 927,
773
+ Pi: 928,
774
+ Rho: 929,
775
+ Sigma: 931,
776
+ Tau: 932,
777
+ Upsilon: 933,
778
+ Phi: 934,
779
+ Chi: 935,
780
+ Psi: 936,
781
+ Omega: 937,
782
+ alpha: 945,
783
+ beta: 946,
784
+ gamma: 947,
785
+ delta: 948,
786
+ epsilon: 949,
787
+ zeta: 950,
788
+ eta: 951,
789
+ theta: 952,
790
+ iota: 953,
791
+ kappa: 954,
792
+ lambda: 955,
793
+ mu: 956,
794
+ nu: 957,
795
+ xi: 958,
796
+ omicron: 959,
797
+ pi: 960,
798
+ rho: 961,
799
+ sigmaf: 962,
800
+ sigma: 963,
801
+ tau: 964,
802
+ upsilon: 965,
803
+ phi: 966,
804
+ chi: 967,
805
+ psi: 968,
806
+ omega: 969,
807
+ thetasym: 977,
808
+ upsih: 978,
809
+ piv: 982,
810
+ ensp: 8194,
811
+ emsp: 8195,
812
+ thinsp: 8201,
813
+ zwnj: 8204,
814
+ zwj: 8205,
815
+ lrm: 8206,
816
+ rlm: 8207,
817
+ ndash: 8211,
818
+ mdash: 8212,
819
+ lsquo: 8216,
820
+ rsquo: 8217,
821
+ sbquo: 8218,
822
+ ldquo: 8220,
823
+ rdquo: 8221,
824
+ bdquo: 8222,
825
+ dagger: 8224,
826
+ Dagger: 8225,
827
+ bull: 8226,
828
+ hellip: 8230,
829
+ permil: 8240,
830
+ prime: 8242,
831
+ Prime: 8243,
832
+ lsaquo: 8249,
833
+ rsaquo: 8250,
834
+ oline: 8254,
835
+ frasl: 8260,
836
+ euro: 8364,
837
+ image: 8465,
838
+ weierp: 8472,
839
+ real: 8476,
840
+ trade: 8482,
841
+ alefsym: 8501,
842
+ larr: 8592,
843
+ uarr: 8593,
844
+ rarr: 8594,
845
+ darr: 8595,
846
+ harr: 8596,
847
+ crarr: 8629,
848
+ lArr: 8656,
849
+ uArr: 8657,
850
+ rArr: 8658,
851
+ dArr: 8659,
852
+ hArr: 8660,
853
+ forall: 8704,
854
+ part: 8706,
855
+ exist: 8707,
856
+ empty: 8709,
857
+ nabla: 8711,
858
+ isin: 8712,
859
+ notin: 8713,
860
+ ni: 8715,
861
+ prod: 8719,
862
+ sum: 8721,
863
+ minus: 8722,
864
+ lowast: 8727,
865
+ radic: 8730,
866
+ prop: 8733,
867
+ infin: 8734,
868
+ ang: 8736,
869
+ and: 8743,
870
+ or: 8744,
871
+ cap: 8745,
872
+ cup: 8746,
873
+ int: 8747,
874
+ there4: 8756,
875
+ sim: 8764,
876
+ cong: 8773,
877
+ asymp: 8776,
878
+ ne: 8800,
879
+ equiv: 8801,
880
+ le: 8804,
881
+ ge: 8805,
882
+ sub: 8834,
883
+ sup: 8835,
884
+ nsub: 8836,
885
+ sube: 8838,
886
+ supe: 8839,
887
+ oplus: 8853,
888
+ otimes: 8855,
889
+ perp: 8869,
890
+ sdot: 8901,
891
+ lceil: 8968,
892
+ rceil: 8969,
893
+ lfloor: 8970,
894
+ rfloor: 8971,
895
+ lang: 9001,
896
+ rang: 9002,
897
+ loz: 9674,
898
+ spades: 9824,
899
+ clubs: 9827,
900
+ hearts: 9829,
901
+ diams: 9830
902
+ };
903
+ var REFERENCE = /&(?:#[xX]([0-9a-fA-F]{1,6})|#([0-9]{1,7})|([a-zA-Z][a-zA-Z0-9]{1,31}));/g;
904
+ function decodeEntities(value) {
905
+ if (!value.includes("&")) return value;
906
+ return value.replace(REFERENCE, (match, hex, dec, name) => {
907
+ const code = hex ? parseInt(hex, 16) : dec ? parseInt(dec, 10) : Object.prototype.hasOwnProperty.call(NAMED, name) ? NAMED[name] : void 0;
908
+ return code !== void 0 && code <= 1114111 ? String.fromCodePoint(code) : match;
909
+ });
910
+ }
911
+
912
+ // src/lower/template.ts
913
+ var DELEGATED = /* @__PURE__ */ new Set([
914
+ "click",
915
+ "dblclick",
916
+ "input",
917
+ "change",
918
+ "submit",
919
+ "focus",
920
+ "blur",
921
+ "keydown",
922
+ "keyup",
923
+ "keypress",
924
+ "mousedown",
925
+ "mouseup"
926
+ ]);
927
+ function escapeTemplate(s) {
928
+ return s.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$\{/g, "\\${");
929
+ }
930
+ var CONTAINER = "container";
931
+ function capitalize(s) {
932
+ return s.charAt(0).toUpperCase() + s.slice(1);
933
+ }
934
+ var Lowerer = class {
935
+ constructor(holes, used, sourceFile, positionAt) {
936
+ this.holes = holes;
937
+ this.used = used;
938
+ this.sourceFile = sourceFile;
939
+ this.positionAt = positionAt;
940
+ }
941
+ /**
942
+ * Where a tag is written, for the mark a component node carries.
943
+ *
944
+ * The parser reports offsets, and they are offsets into the file: the pieces it was given
945
+ * carry the positions the front-end recorded. Only built when the host asked for source
946
+ * locations, which is the only time either of these is set.
947
+ */
948
+ tagAt(node) {
949
+ const start = node.loc?.start;
950
+ if (!this.sourceFile || !this.positionAt || start == null) return void 0;
951
+ const { line, column } = this.positionAt(start);
952
+ return { file: this.sourceFile, line, column };
953
+ }
954
+ hole(i) {
955
+ return this.holes[i] ?? { code: "undefined", reactive: false };
956
+ }
957
+ /** Emit a nested IR subtree to code (for `Show` fallback / `For` children). */
958
+ emit(node) {
959
+ const { code, imports, templates } = imperativeBackend.emit(node, {});
960
+ for (const s of imports) this.used.add(s);
961
+ return inlineTemplates(code, templates);
962
+ }
963
+ // --- content ------------------------------------------------------------
964
+ lowerRoot(children) {
965
+ const nodes = this.lowerChildren(children);
966
+ if (nodes.length === 1) return nodes[0];
967
+ return { kind: "fragment", children: nodes };
968
+ }
969
+ /** Lower a sibling list, handling text-drop and if/else/each restructuring. */
970
+ lowerChildren(children) {
971
+ const out = [];
972
+ for (let i = 0; i < children.length; i++) {
973
+ const child = children[i];
974
+ if (child.kind === "Element" || child.kind === "Component") {
975
+ const ifDir = child.attributes.find((a) => a.kind === "IfDirective");
976
+ if (ifDir && ifDir.kind === "IfDirective") {
977
+ let elseIdx = i + 1;
978
+ if (elseIdx < children.length && this.isBlankText(children[elseIdx])) elseIdx++;
979
+ const elseNode = children[elseIdx];
980
+ const hasElse = elseNode && (elseNode.kind === "Element" || elseNode.kind === "Component") && elseNode.attributes.some((a) => a.kind === "ElseDirective");
981
+ out.push(this.lowerIf(child, ifDir.hole, hasElse ? elseNode : null));
982
+ if (hasElse) i = elseIdx;
983
+ continue;
984
+ }
985
+ }
986
+ const node = this.lowerNode(child);
987
+ if (node) out.push(node);
988
+ }
989
+ return out;
990
+ }
991
+ isBlankText(n) {
992
+ return n.kind === "Text" && !n.raw && cleanTemplateText(n.value) === "";
993
+ }
994
+ lowerNode(node) {
995
+ switch (node.kind) {
996
+ case "Text": {
997
+ if (node.raw) return { kind: "text", value: node.value };
998
+ const cleaned = decodeEntities(cleanTemplateText(node.value));
999
+ return cleaned ? { kind: "text", value: cleaned } : null;
1000
+ }
1001
+ case "Comment":
1002
+ return null;
1003
+ // dropped, like JSX comments
1004
+ case "Expression": {
1005
+ const h = this.hole(node.hole);
1006
+ return { kind: "expr", code: h.code, reactive: h.reactive, ...h.at ? { at: h.at } : {} };
1007
+ }
1008
+ case "Fragment":
1009
+ return { kind: "fragment", children: this.lowerChildren(node.children) };
1010
+ case "Element":
1011
+ return this.lowerElement(node);
1012
+ case "Component":
1013
+ return this.lowerComponent(node);
1014
+ default:
1015
+ return null;
1016
+ }
1017
+ }
1018
+ lowerElement(el) {
1019
+ const isAttr = el.attributes.find((a) => a.kind === "Attribute" && a.name === "is");
1020
+ if (el.tag === "component" && isAttr && isAttr.value && isAttr.value.kind === "hole") {
1021
+ const rest = el.attributes.filter((a) => a !== isAttr);
1022
+ const node = this.lowerComponent({ ...el, kind: "Component", tag: "Dynamic", tagHole: null, attributes: rest });
1023
+ node.props.unshift({ name: "component", kind: "attr", expr: `() => ${paren(this.hole(isAttr.value.hole).code, "arrowBody")}` });
1024
+ return node;
1025
+ }
1026
+ const each = this.lowerEach(el);
1027
+ const children = each ? [each] : this.lowerChildren(el.children);
1028
+ if (el.tag === CONTAINER) return children.length === 1 ? children[0] : { kind: "fragment", children };
1029
+ const at = this.tagAt(el);
1030
+ return {
1031
+ kind: "element",
1032
+ tag: el.tag,
1033
+ svg: el.namespace === "svg",
1034
+ props: this.lowerAttributes(el.attributes, true),
1035
+ children,
1036
+ static: false,
1037
+ ...at ? { at } : {}
1038
+ };
1039
+ }
1040
+ lowerComponent(el) {
1041
+ const name = el.tagHole != null ? this.hole(el.tagHole).code : el.tag;
1042
+ const props = this.lowerAttributes(el.attributes);
1043
+ const { slots, rest } = this.partitionSlots(el.children);
1044
+ for (const [slotName, nodes] of slots) {
1045
+ const ir = nodes.length === 1 ? nodes[0] : { kind: "fragment", children: nodes };
1046
+ const slotProp = {
1047
+ name: slotName,
1048
+ kind: "attr",
1049
+ expr: this.emit(ir),
1050
+ jsxElement: true
1051
+ };
1052
+ const clash = props.findIndex((p) => p.name === slotName);
1053
+ if (clash >= 0) props[clash] = slotProp;
1054
+ else props.push(slotProp);
1055
+ }
1056
+ const loadAttr = el.attributes.find((a) => a.kind === "LoadDirective");
1057
+ const load = loadAttr ? parseLoadDirective(`load:${loadAttr.strategy}`, loadAttr.modifier) : void 0;
1058
+ const bindAt = props.find((p) => p.at && p.reactive)?.at;
1059
+ const at = this.tagAt(el);
1060
+ return {
1061
+ kind: "component",
1062
+ name,
1063
+ props,
1064
+ children: this.lowerChildren(rest),
1065
+ ...at ? { at } : {},
1066
+ ...bindAt ? { bindAt } : {},
1067
+ ...load ? { load } : {}
1068
+ };
1069
+ }
1070
+ /** Split a component's children into named slots (`slot="x"`) and the rest. */
1071
+ partitionSlots(children) {
1072
+ const slots = /* @__PURE__ */ new Map();
1073
+ const rest = [];
1074
+ for (const child of children) {
1075
+ if (child.kind === "Element" || child.kind === "Component") {
1076
+ const slot = child.attributes.find(
1077
+ (a) => a.kind === "Attribute" && a.name === "slot"
1078
+ );
1079
+ if (slot && slot.value && slot.value.kind === "static") {
1080
+ const stripped = { ...child, attributes: child.attributes.filter((a) => a !== slot) };
1081
+ const ir = stripped.kind === "Element" ? this.lowerElement(stripped) : this.lowerComponent(stripped);
1082
+ const bucket = slots.get(slot.value.value) ?? [];
1083
+ bucket.push(ir);
1084
+ slots.set(slot.value.value, bucket);
1085
+ continue;
1086
+ }
1087
+ }
1088
+ rest.push(child);
1089
+ }
1090
+ return { slots, rest };
1091
+ }
1092
+ // --- control-flow sugar -------------------------------------------------
1093
+ /** `<el if=${cond}>…</el>` (+ optional `<el else>`) → `<Show when fallback>`. */
1094
+ lowerIf(el, condHole, elseEl) {
1095
+ const cond = this.hole(condHole);
1096
+ const props = [
1097
+ { name: "when", kind: "attr", expr: cond.code, reactive: cond.reactive, ...cond.at ? { at: cond.at } : {} }
1098
+ ];
1099
+ if (elseEl) {
1100
+ const elseIR = this.stripAndLower(elseEl, (a) => a.kind === "ElseDirective");
1101
+ props.push({ name: "fallback", kind: "attr", expr: this.emit(elseIR), jsxElement: true });
1102
+ }
1103
+ const child = this.stripAndLower(el, (a) => a.kind === "IfDirective");
1104
+ const at = this.tagAt(el);
1105
+ return { kind: "component", name: "Show", props, children: [child], ...at ? { at } : {}, ...cond.at ? { bindAt: cond.at } : {} };
1106
+ }
1107
+ /**
1108
+ * `<el each=${items} key?>${item => …}</el>` → `<el><For each>{item => …}</For></el>`: the
1109
+ * content is repeated per item. Content that is not a `${item => …}` arrow is repeated as
1110
+ * it is. Null when the element has no `each`.
1111
+ */
1112
+ lowerEach(el) {
1113
+ const eachDir = el.attributes.find((a) => a.kind === "EachDirective");
1114
+ if (!eachDir || eachDir.kind !== "EachDirective") return null;
1115
+ const each = this.hole(eachDir.hole);
1116
+ const props = [{ name: "each", kind: "attr", expr: each.code, reactive: each.reactive, ...each.at ? { at: each.at } : {} }];
1117
+ if (eachDir.key) {
1118
+ const by = "static" in eachDir.key ? `(item) => item[${JSON.stringify(eachDir.key.static)}]` : this.hole(eachDir.key.hole).code;
1119
+ props.push({ name: "by", kind: "attr", expr: by });
1120
+ }
1121
+ const arrow = this.itemArrow(el);
1122
+ let childrenCode;
1123
+ if (arrow) {
1124
+ const body = arrow.bodyReactive ? `() => ${paren(arrow.body, "arrowBody")}` : paren(arrow.body, "arrowBody");
1125
+ childrenCode = `(${arrow.params.join(", ")}) => ${body}`;
1126
+ } else {
1127
+ const content = this.lowerChildren(el.children);
1128
+ const ir = content.length === 1 ? content[0] : { kind: "fragment", children: content };
1129
+ childrenCode = `() => ${paren(this.emit(ir), "arrowBody")}`;
1130
+ }
1131
+ const children = [{ kind: "expr", code: childrenCode, reactive: false }];
1132
+ const at = this.tagAt(el);
1133
+ return { kind: "component", name: "For", props, children, ...at ? { at } : {}, ...each.at ? { bindAt: each.at } : {} };
1134
+ }
1135
+ /** The single `${item => expr}` child arrow, if that's the element's content. */
1136
+ itemArrow(el) {
1137
+ const kids = el.children.filter((c) => !this.isBlankText(c));
1138
+ if (kids.length !== 1 || kids[0].kind !== "Expression") return null;
1139
+ return this.hole(kids[0].hole).arrow ?? null;
1140
+ }
1141
+ /** Lower an element to IR, dropping the directive attribute matched by `drop`. */
1142
+ stripAndLower(el, drop) {
1143
+ const clone = { ...el, attributes: el.attributes.filter((a) => !drop(a)) };
1144
+ return clone.kind === "Element" ? this.lowerElement(clone) : this.lowerComponent(clone);
1145
+ }
1146
+ // --- attributes ---------------------------------------------------------
1147
+ /**
1148
+ * `element`: a DOM element, where each class:/style: value that moves is its own accessor.
1149
+ * A component gets the object as before, rebuilt whole when any value moves.
1150
+ */
1151
+ lowerAttributes(attrs, element = false) {
1152
+ let anyReactive = false;
1153
+ const entry = (name, h) => {
1154
+ anyReactive ||= h.reactive;
1155
+ if (!element || !h.reactive) return `${JSON.stringify(name)}: ${h.code}`;
1156
+ const accessor = `() => ${paren(h.code, "arrowBody")}`;
1157
+ return `${JSON.stringify(name)}: ${h.at ? markHole(accessor, h.at.line, h.at.column) : accessor}`;
1158
+ };
1159
+ const props = [];
1160
+ const classEntries = [];
1161
+ let classAt;
1162
+ const styleEntries = [];
1163
+ let styleAt;
1164
+ const usePairs = [];
1165
+ for (const a of attrs) {
1166
+ switch (a.kind) {
1167
+ case "IfDirective":
1168
+ case "EachDirective":
1169
+ case "ElseDirective":
1170
+ break;
1171
+ // handled as control-flow at the parent level
1172
+ case "Attribute":
1173
+ props.push(this.plainAttr(a));
1174
+ break;
1175
+ case "PropertyBinding":
1176
+ props.push({
1177
+ name: a.name,
1178
+ kind: "prop",
1179
+ expr: this.hole(a.hole).code,
1180
+ reactive: this.hole(a.hole).reactive,
1181
+ ...this.hole(a.hole).at ? { at: this.hole(a.hole).at } : {}
1182
+ });
1183
+ break;
1184
+ case "EventBinding":
1185
+ props.push(this.eventProp(a));
1186
+ break;
1187
+ case "RefBinding":
1188
+ props.push({
1189
+ name: "ref",
1190
+ kind: "ref",
1191
+ expr: this.hole(a.hole).code,
1192
+ reactive: this.hole(a.hole).reactive,
1193
+ // Which variable ends up holding the element, and where it was written.
1194
+ ...this.hole(a.hole).at ? { at: this.hole(a.hole).at } : {}
1195
+ });
1196
+ break;
1197
+ case "Spread":
1198
+ props.push({ name: "", kind: "spread", expr: this.hole(a.hole).code });
1199
+ break;
1200
+ case "ClassDirective": {
1201
+ const h = this.hole(a.hole);
1202
+ classEntries.push(entry(a.name, h));
1203
+ classAt ??= h.at;
1204
+ break;
1205
+ }
1206
+ case "StyleDirective": {
1207
+ const h = this.hole(a.hole);
1208
+ styleEntries.push(entry(a.name, h));
1209
+ styleAt ??= h.at;
1210
+ break;
1211
+ }
1212
+ case "BindDirective":
1213
+ props.push(...this.bindProps(a.name, this.hole(a.hole)));
1214
+ break;
1215
+ case "UseDirective": {
1216
+ const dir = a.name ?? (a.hole != null ? this.hole(a.hole).code : null);
1217
+ if (!dir) break;
1218
+ usePairs.push(a.name != null && a.hole != null ? `[${dir}, () => ${paren(this.hole(a.hole).code, "arrowBody")}]` : `[${dir}]`);
1219
+ break;
1220
+ }
1221
+ }
1222
+ }
1223
+ if (classEntries.length > 0) {
1224
+ props.push({
1225
+ name: "classList",
1226
+ kind: "attr",
1227
+ expr: `{ ${classEntries.join(", ")} }`,
1228
+ reactive: !element && anyReactive,
1229
+ ...classAt ? { at: classAt } : {}
1230
+ });
1231
+ }
1232
+ if (styleEntries.length > 0) {
1233
+ const entries = `{ ${styleEntries.join(", ")} }`;
1234
+ const base = props.findIndex((p) => p.name === "style");
1235
+ if (base === -1) props.push({ name: "style", kind: "attr", expr: entries, reactive: !element && anyReactive, ...styleAt ? { at: styleAt } : {} });
1236
+ else {
1237
+ const prop = props[base];
1238
+ const value = prop.expr === void 0 ? JSON.stringify(prop.literal) : prop.reactive ? `() => ${paren(prop.expr, "arrowBody")}` : prop.expr;
1239
+ props[base] = { name: "style", kind: "attr", expr: `[${value}, ${entries}]`, reactive: false, ...prop.at ? { at: prop.at } : {} };
1240
+ }
1241
+ }
1242
+ if (usePairs.length > 0) {
1243
+ props.push({ name: "use", kind: "attr", expr: `[${usePairs.join(", ")}]` });
1244
+ }
1245
+ return props;
1246
+ }
1247
+ /**
1248
+ * Lower an event binding. Plain `@click`/`onClick` (no modifiers) stays a
1249
+ * DELEGATED handler (unchanged, byte-identical with JSX). `on:click` or any
1250
+ * modifier (`.capture`/`.once`/`.passive`/`.prevent`/`.stop`/`.self`) emits a
1251
+ * NATIVE `on:name` prop the runtime attaches via addEventListener.
1252
+ */
1253
+ eventProp(a) {
1254
+ const dom = a.name.toLowerCase();
1255
+ const handler = this.hole(a.hole).code;
1256
+ const native = a.syntax === "colon" || a.modifiers.length > 0;
1257
+ if (!native) {
1258
+ return {
1259
+ name: "on" + capitalize(a.name),
1260
+ kind: "event",
1261
+ event: { name: dom, delegated: DELEGATED.has(dom) },
1262
+ expr: handler
1263
+ };
1264
+ }
1265
+ const wrapped = this.wrapHandler(handler, a.modifiers);
1266
+ const options = this.eventOptions(a.modifiers);
1267
+ const value = options ? `[${wrapped}, ${options}]` : wrapped;
1268
+ return { name: "on:" + dom, kind: "attr", expr: value };
1269
+ }
1270
+ /** Wrap a handler for `.prevent`/`.stop`/`.self` (no wrap when none apply). */
1271
+ wrapHandler(handler, mods) {
1272
+ const guard = mods.includes("self") ? "if (e.target !== e.currentTarget) return; " : "";
1273
+ const pre = [];
1274
+ if (mods.includes("prevent")) pre.push("e.preventDefault();");
1275
+ if (mods.includes("stop")) pre.push("e.stopPropagation();");
1276
+ if (!guard && pre.length === 0) return handler;
1277
+ return `(e) => { ${guard}${pre.join(" ")} return (${handler})(e); }`;
1278
+ }
1279
+ /** addEventListener options object from `.capture`/`.once`/`.passive`, or null. */
1280
+ eventOptions(mods) {
1281
+ const opts = [];
1282
+ if (mods.includes("capture")) opts.push("capture: true");
1283
+ if (mods.includes("once")) opts.push("once: true");
1284
+ if (mods.includes("passive")) opts.push("passive: true");
1285
+ return opts.length ? `{ ${opts.join(", ")} }` : null;
1286
+ }
1287
+ /** `bind:value=${sig}` → `value={read()}` + `onInput={e => write(e…value)}`. */
1288
+ bindProps(prop, h) {
1289
+ const sigCode = h.code;
1290
+ const checked = prop === "checked";
1291
+ const evt = checked ? "change" : "input";
1292
+ const accessor = checked ? "checked" : "value";
1293
+ this.used.add("bindPair");
1294
+ const sig = `bindPair(${sigCode})`;
1295
+ return [
1296
+ {
1297
+ name: prop,
1298
+ kind: "attr",
1299
+ expr: `${sig}[0]()`,
1300
+ reactive: true,
1301
+ directive: `bind:${prop}`,
1302
+ ...h.at ? { at: h.at } : {}
1303
+ },
1304
+ {
1305
+ name: "on" + capitalize(evt),
1306
+ kind: "event",
1307
+ event: { name: evt, delegated: DELEGATED.has(evt) },
1308
+ // delegated handler: `target` is the bound element (currentTarget is the root)
1309
+ expr: `(e) => ${sig}[1](e.target.${accessor})`
1310
+ }
1311
+ ];
1312
+ }
1313
+ /** A plain attribute (incl. lit `?bool`, mixed values), old `mkProp` behavior. */
1314
+ plainAttr(a) {
1315
+ const v = a.value;
1316
+ let name = a.name;
1317
+ if (a.name === "class") {
1318
+ name = v && v.kind === "hole" && this.hole(v.hole).object ? "classList" : "className";
1319
+ } else if (a.name === "html") {
1320
+ name = "innerHTML";
1321
+ }
1322
+ const kind = "attr";
1323
+ const base = { name, kind };
1324
+ if (v == null) {
1325
+ base.literal = true;
1326
+ return base;
1327
+ }
1328
+ if (v.kind === "static") {
1329
+ base.literal = decodeEntities(v.value);
1330
+ return base;
1331
+ }
1332
+ if (v.kind === "hole") {
1333
+ const h = this.hole(v.hole);
1334
+ base.expr = h.code;
1335
+ base.reactive = h.reactive;
1336
+ if (h.at) base.at = h.at;
1337
+ return base;
1338
+ }
1339
+ let reactive = false;
1340
+ let at;
1341
+ const body = v.parts.map((p) => {
1342
+ if ("text" in p) return escapeTemplate(decodeEntities(p.text));
1343
+ const h = this.hole(p.hole);
1344
+ reactive = reactive || h.reactive;
1345
+ at ??= h.at;
1346
+ return "${" + h.code + "}";
1347
+ }).join("");
1348
+ base.expr = "`" + body + "`";
1349
+ base.reactive = reactive;
1350
+ if (at) base.at = at;
1351
+ return base;
1352
+ }
1353
+ };
1354
+ function lowerTemplate(pieces, holes, used, opts = {}) {
1355
+ const { root } = parseTemplate(pieces, { svg: opts.svg });
1356
+ return new Lowerer(holes, used, opts.sourceFile, opts.positionAt).lowerRoot(root.children);
1357
+ }
1358
+
1359
+ // ../../node_modules/.pnpm/@jridgewell+sourcemap-codec@1.6.0/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs
1360
+ var comma = ",".charCodeAt(0);
1361
+ var semicolon = ";".charCodeAt(0);
1362
+ var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1363
+ var intToChar = new Uint8Array(64);
1364
+ var charToInt = new Uint8Array(128);
1365
+ for (let i = 0; i < chars.length; i++) {
1366
+ const c = chars.charCodeAt(i);
1367
+ intToChar[i] = c;
1368
+ charToInt[c] = i;
1369
+ }
1370
+ var bufLength = 1024 * 16;
1371
+
1372
+ // src/transform/styles.ts
1373
+ var SCOPE_ATTR = "data-fx-s";
1374
+ function applyTemplateStyles(ir, t) {
1375
+ const walk2 = (node) => {
1376
+ const children = node.children;
1377
+ if (children) {
1378
+ for (let i = children.length - 1; i >= 0; i--) {
1379
+ const child = children[i];
1380
+ if (child.kind === "element" && child.tag === "style" && t.owner) children.splice(i, 1);
1381
+ else walk2(child);
1382
+ }
1383
+ }
1384
+ if (t.scope && node.kind === "element" && node.tag !== "style" && node.props && !node.props.some((p) => p.name === SCOPE_ATTR)) {
1385
+ node.props.unshift({ name: SCOPE_ATTR, kind: "attr", literal: t.scope });
1386
+ }
1387
+ };
1388
+ walk2(ir);
1389
+ }
1390
+
1391
+ // src/optimize/analyze-static.ts
1392
+ function propReason(prop) {
1393
+ switch (prop.kind) {
1394
+ case "event":
1395
+ return "event";
1396
+ case "ref":
1397
+ return "ref";
1398
+ case "spread":
1399
+ return "spread";
1400
+ case "class":
1401
+ case "style":
1402
+ return "class-or-style-directive";
1403
+ case "attr":
1404
+ case "prop":
1405
+ if (prop.reactive) return "reactive-prop";
1406
+ if (prop.expr !== void 0) return "expression-prop";
1407
+ return void 0;
1408
+ /* c8 ignore next 2 */
1409
+ default:
1410
+ return "expression-prop";
1411
+ }
1412
+ }
1413
+ function analyzeStatic(root) {
1414
+ const staticElements = [];
1415
+ const reasons = /* @__PURE__ */ new Map();
1416
+ const visit = (node) => {
1417
+ switch (node.kind) {
1418
+ case "text":
1419
+ return true;
1420
+ case "expr":
1421
+ return false;
1422
+ case "component":
1423
+ case "control":
1424
+ for (const child of node.children) visit(child);
1425
+ return false;
1426
+ case "fragment":
1427
+ for (const child of node.children) visit(child);
1428
+ return false;
1429
+ case "element": {
1430
+ let childrenStatic = true;
1431
+ for (const child of node.children) {
1432
+ if (!visit(child)) childrenStatic = false;
1433
+ }
1434
+ let reason;
1435
+ for (const prop of node.props) {
1436
+ reason = propReason(prop);
1437
+ if (reason) break;
1438
+ }
1439
+ if (!reason && !childrenStatic) {
1440
+ reason = childReason(node);
1441
+ }
1442
+ node.static = !reason;
1443
+ if (reason) reasons.set(node, reason);
1444
+ else staticElements.push(node);
1445
+ return node.static;
1446
+ }
1447
+ /* c8 ignore next 2 */
1448
+ default:
1449
+ return false;
1450
+ }
1451
+ };
1452
+ for (const node of Array.isArray(root) ? root : [root]) visit(node);
1453
+ return { staticElements, reasons };
1454
+ }
1455
+ function childReason(node) {
1456
+ for (const child of node.children) {
1457
+ if (child.kind === "expr") return "expression-child";
1458
+ if (child.kind === "component") return "component-child";
1459
+ if (child.kind === "control") return "control-child";
1460
+ if (child.kind === "element" && !child.static) return "expression-child";
1461
+ if (child.kind === "fragment") return "expression-child";
1462
+ }
1463
+ return "expression-child";
1464
+ }
1465
+
1466
+ // src/resolve/builtins.ts
1467
+ var DOM_CONTROL_FLOW = [
1468
+ "Show",
1469
+ "For",
1470
+ "Index",
1471
+ "Switch",
1472
+ "Match",
1473
+ "Portal",
1474
+ "Dynamic",
1475
+ "ErrorBoundary"
1476
+ ];
1477
+ var CORE_CONTROL_FLOW = ["Suspense", "SuspenseList", "Await"];
1478
+ var ROUTER_COMPONENTS = ["Router", "Outlet", "Redirect", "Link"];
1479
+ var BUILTIN_COMPONENTS = [
1480
+ ...DOM_CONTROL_FLOW,
1481
+ ...CORE_CONTROL_FLOW,
1482
+ ...ROUTER_COMPONENTS
1483
+ ];
1484
+ var RESERVED_COMPONENTS = /* @__PURE__ */ new Set([
1485
+ ...DOM_CONTROL_FLOW,
1486
+ ...CORE_CONTROL_FLOW
1487
+ ]);
1488
+ function builtinComponentMap(modules = {}) {
1489
+ const {
1490
+ controlFlowModule = "@fluixi/dom",
1491
+ coreModule = "@fluixi/core",
1492
+ routerModule = "@fluixi/core/router"
1493
+ } = modules;
1494
+ const map = {};
1495
+ for (const name of DOM_CONTROL_FLOW) map[name] = controlFlowModule;
1496
+ for (const name of CORE_CONTROL_FLOW) map[name] = coreModule;
1497
+ for (const name of ROUTER_COMPONENTS) map[name] = routerModule;
1498
+ return map;
1499
+ }
1500
+ function builtinComponents(modules = {}) {
1501
+ return { components: builtinComponentMap(modules) };
1502
+ }
1503
+ function routerComponents(routerModule) {
1504
+ const module = routerModule ?? "@fluixi/core/router";
1505
+ return { components: Object.fromEntries(ROUTER_COMPONENTS.map((n) => [n, module])) };
1506
+ }
1507
+
1508
+ // src/resolve/resolve-ir.ts
1509
+ function resolveComponentSources(root, options = {}) {
1510
+ const { resolver, isBound, modules, strategyFor } = options;
1511
+ const builtins = builtinComponentMap(modules);
1512
+ const resolved = /* @__PURE__ */ new Map();
1513
+ const unresolved = /* @__PURE__ */ new Set();
1514
+ const annotate = (node) => {
1515
+ const { name } = node;
1516
+ if (!name || name.includes(".")) return;
1517
+ if (isBound?.(name)) return;
1518
+ const source = sourceFor(name);
1519
+ if (!source) {
1520
+ unresolved.add(name);
1521
+ return;
1522
+ }
1523
+ const loading = source.origin === "builtin" && RESERVED_COMPONENTS.has(name) ? EAGER : strategyFor?.(node) ?? EAGER;
1524
+ node.source = { ...source, loading };
1525
+ resolved.set(name, node.source);
1526
+ };
1527
+ const sourceFor = (name) => {
1528
+ if (RESERVED_COMPONENTS.has(name)) {
1529
+ return { module: builtins[name], export: name, origin: "builtin" };
1530
+ }
1531
+ const rule = resolver?.resolve(name);
1532
+ if (rule) return { module: rule.module, export: rule.export, origin: "rule" };
1533
+ if (ROUTER_COMPONENTS.includes(name)) {
1534
+ return { module: builtins[name], export: name, origin: "builtin" };
1535
+ }
1536
+ return void 0;
1537
+ };
1538
+ walk(root, (node) => {
1539
+ if (node.kind === "component") annotate(node);
1540
+ });
1541
+ return { resolved, unresolved: [...unresolved] };
1542
+ }
1543
+ function walk(root, visit) {
1544
+ const nodes = Array.isArray(root) ? root : [root];
1545
+ for (const node of nodes) {
1546
+ visit(node);
1547
+ const children = node.children;
1548
+ if (children) walk(children, visit);
1549
+ }
1550
+ }
1551
+
1552
+ // src/optimize/collapse-strategies.ts
1553
+ function collapseStrategies(root) {
1554
+ const components = [];
1555
+ walk(root, (node) => {
1556
+ if (node.kind === "component" && node.source) components.push(node);
1557
+ });
1558
+ const eager = /* @__PURE__ */ new Set();
1559
+ const never = /* @__PURE__ */ new Set();
1560
+ for (const node of components) {
1561
+ const { module, loading } = node.source;
1562
+ if (loading.kind === "eager") eager.add(module);
1563
+ if (loading.kind === "never") never.add(module);
1564
+ }
1565
+ const collapsed = /* @__PURE__ */ new Map();
1566
+ for (const node of components) {
1567
+ const source = node.source;
1568
+ if (!isDeferred(source.loading)) continue;
1569
+ if (!eager.has(source.module)) continue;
1570
+ source.loading = { kind: "eager" };
1571
+ collapsed.set(source.module, (collapsed.get(source.module) ?? 0) + 1);
1572
+ }
1573
+ return {
1574
+ collapsed,
1575
+ conflicted: [...never].filter((m) => eager.has(m))
1576
+ };
1577
+ }
1578
+
1579
+ // src/resolve/component-resolver.ts
1580
+ var isMapRule = (rule) => "components" in rule;
1581
+ function substitute(template, match) {
1582
+ return template.replace(/\$(\d+)/g, (whole, index) => {
1583
+ const group = match[Number(index)];
1584
+ return group ?? whole;
1585
+ });
1586
+ }
1587
+ function normalise(name, entry) {
1588
+ return typeof entry === "string" ? { module: entry, export: name } : entry;
1589
+ }
1590
+ function createComponentResolver(rules = []) {
1591
+ const exact = /* @__PURE__ */ new Map();
1592
+ const conflicts = [];
1593
+ const patterns = [];
1594
+ for (const rule of rules) {
1595
+ if (!isMapRule(rule)) {
1596
+ patterns.push(rule);
1597
+ continue;
1598
+ }
1599
+ for (const [name, entry] of Object.entries(rule.components)) {
1600
+ const resolved = normalise(name, entry);
1601
+ const existing = exact.get(name);
1602
+ if (existing && existing.module !== resolved.module) {
1603
+ const conflict = conflicts.find((c) => c.name === name);
1604
+ if (conflict) conflict.modules.push(resolved.module);
1605
+ else conflicts.push({ name, modules: [existing.module, resolved.module] });
1606
+ continue;
1607
+ }
1608
+ exact.set(name, resolved);
1609
+ }
1610
+ }
1611
+ const cache = /* @__PURE__ */ new Map();
1612
+ const resolve = (name) => {
1613
+ if (cache.has(name)) return cache.get(name);
1614
+ let result = exact.get(name);
1615
+ if (!result) {
1616
+ for (const rule of patterns) {
1617
+ const match = name.match(new RegExp(rule.match.source, rule.match.flags.replace("g", "")));
1618
+ if (!match) continue;
1619
+ result = {
1620
+ module: substitute(rule.module, match),
1621
+ export: rule.export ? substitute(rule.export, match) : name
1622
+ };
1623
+ break;
1624
+ }
1625
+ }
1626
+ cache.set(name, result);
1627
+ return result;
1628
+ };
1629
+ return {
1630
+ resolve,
1631
+ names: () => [...exact.keys()],
1632
+ conflicts: () => conflicts
1633
+ };
1634
+ }
1635
+
1636
+ // src/lower/compile-template.ts
1637
+ function toPieces(source) {
1638
+ const pieces = [];
1639
+ let offset = 0;
1640
+ source.statics.forEach((text, i) => {
1641
+ pieces.push({ kind: "static", text, start: offset });
1642
+ offset += text.length;
1643
+ if (i < source.holes.length) {
1644
+ const end = offset + source.holes[i].code.length;
1645
+ pieces.push({ kind: "hole", index: i, start: offset, end });
1646
+ offset = end;
1647
+ }
1648
+ });
1649
+ return pieces;
1650
+ }
1651
+ function compileTemplate(source, options = {}) {
1652
+ if (source.statics.length !== source.holes.length + 1) {
1653
+ throw new Error(
1654
+ `[fluixi] compileTemplate: ${source.statics.length} static runs for ${source.holes.length} holes — a template always has exactly one more.`
1655
+ );
1656
+ }
1657
+ return compilePieces(toPieces(source), source.holes, options);
1658
+ }
1659
+ function compilePieces(pieces, holes, options = {}) {
1660
+ const used = /* @__PURE__ */ new Set();
1661
+ const ir = lowerTemplate(pieces, [...holes], used, {
1662
+ svg: options.svg,
1663
+ ...options.sourceFile ? { sourceFile: options.sourceFile } : {},
1664
+ ...options.positionAt ? { positionAt: options.positionAt } : {}
1665
+ });
1666
+ if (options.templateStyles) applyTemplateStyles(ir, options.templateStyles);
1667
+ analyzeStatic(ir);
1668
+ resolveComponentSources(ir, {
1669
+ resolver: createComponentResolver(options.resolve ?? []),
1670
+ modules: {
1671
+ controlFlowModule: options.controlFlowModule ?? "@fluixi/dom",
1672
+ coreModule: options.coreModule ?? "@fluixi/core",
1673
+ routerModule: options.routerModule ?? "@fluixi/core/router"
1674
+ },
1675
+ strategyFor: (node) => node.load
1676
+ });
1677
+ collapseStrategies(ir);
1678
+ const { code, imports, templates } = imperativeBackend.emit(ir, {
1679
+ templateClone: options.templateClone,
1680
+ partialTemplates: options.partialTemplates
1681
+ });
1682
+ for (const symbol of imports) used.add(symbol);
1683
+ if (options.hoistTemplates) return { code, imports: [...used], ir, templates };
1684
+ return { code: inlineTemplates(code, templates), imports: [...used], ir };
1685
+ }
1686
+
1687
+ // src/resolve/component-globals.ts
1688
+ var DOM_GLOBALS = /* @__PURE__ */ new Set([
1689
+ "Text",
1690
+ "Image",
1691
+ "Option",
1692
+ "Audio",
1693
+ "Comment",
1694
+ "Range",
1695
+ "Selection",
1696
+ "Notification",
1697
+ "Event",
1698
+ "Document",
1699
+ "Element",
1700
+ "Node",
1701
+ "Screen",
1702
+ "Window",
1703
+ "Location",
1704
+ "History",
1705
+ "Storage",
1706
+ "Response",
1707
+ "Request",
1708
+ "Headers"
1709
+ ]);
1710
+ function packageOf(specifier) {
1711
+ if (specifier.startsWith(".") || specifier.startsWith("/")) return void 0;
1712
+ if (/^[~@]\//.test(specifier)) return void 0;
1713
+ const parts = specifier.split("/");
1714
+ return specifier.startsWith("@") ? parts.slice(0, 2).join("/") : parts[0];
1715
+ }
1716
+ function namespaceAlias(module) {
1717
+ return `_${module.replace(/[^A-Za-z0-9]/g, "_")}`;
1718
+ }
1719
+ function componentGlobals(rules, options = {}) {
1720
+ const {
1721
+ available: availableList,
1722
+ builtins = true,
1723
+ intrinsics = true,
1724
+ generator = "@fluixi/compiler",
1725
+ specifier = (module) => module,
1726
+ candidates = []
1727
+ } = options;
1728
+ const all = [...rules];
1729
+ if (builtins) {
1730
+ all.push({ components: builtinComponentMap() });
1731
+ }
1732
+ const resolver = createComponentResolver(all);
1733
+ const available = availableList ? new Set(availableList) : void 0;
1734
+ const declared = [];
1735
+ const shadowedByDom = [];
1736
+ const unavailable = [];
1737
+ const resolved = /* @__PURE__ */ new Map();
1738
+ const names = /* @__PURE__ */ new Set([...resolver.names(), ...[...candidates].filter((n) => /^[A-Za-z_$][\w$]*$/.test(n))]);
1739
+ for (const name of [...names].sort()) {
1740
+ const target = resolver.resolve(name);
1741
+ if (!target) continue;
1742
+ const pkg = packageOf(target.module);
1743
+ if (DOM_GLOBALS.has(name)) shadowedByDom.push(name);
1744
+ else if (available && pkg && !available.has(pkg)) unavailable.push(name);
1745
+ else {
1746
+ declared.push(name);
1747
+ resolved.set(name, target);
1748
+ }
1749
+ }
1750
+ const usableIntrinsics = intrinsics ? Object.entries({ ...INTRINSICS, ...TAG_INTRINSICS }).filter(([, i]) => {
1751
+ const pkg = packageOf(i.module);
1752
+ return !available || !pkg || available.has(pkg);
1753
+ }) : [];
1754
+ const intrinsicModules = [...new Set(usableIntrinsics.map(([, i]) => i.module))];
1755
+ const modules = [
1756
+ .../* @__PURE__ */ new Set([...declared.map((name) => resolved.get(name).module), ...intrinsicModules])
1757
+ ].sort();
1758
+ const imports = modules.map(
1759
+ (m) => `import * as ${namespaceAlias(m)} from '${specifier(m)}';`
1760
+ );
1761
+ const lines = declared.map((name) => {
1762
+ const target = resolved.get(name);
1763
+ const ns = namespaceAlias(target.module);
1764
+ return target.export === "default" ? ` const ${name}: typeof ${ns}.default;` : ` export import ${name} = ${ns}.${target.export};`;
1765
+ });
1766
+ const note = shadowedByDom.length > 0 ? `//
1767
+ // Import these explicitly: lib.dom already declares the name, so an ambient
1768
+ // declaration cannot win:
1769
+ ` + shadowedByDom.map((n) => {
1770
+ const module = resolver.resolve(n)?.module;
1771
+ return `// import { ${n} } from '${module ? specifier(module) : ""}';
1772
+ `;
1773
+ }).join("") : "";
1774
+ const intrinsicLines = usableIntrinsics.map(
1775
+ ([name, intrinsic]) => ` const ${name}: typeof ${namespaceAlias(intrinsic.module)}.${intrinsic.export};`
1776
+ );
1777
+ const patternRules = rules.filter((rule) => "match" in rule).length;
1778
+ const patternNote = patternRules === 0 ? "" : options.candidates ? `//
1779
+ // ${patternRules} pattern rule${patternRules === 1 ? "" : "s"}: declared for the files the module path
1780
+ // points at. A name with no such file still resolves at build time; declare it by hand.
1781
+ ` : `//
1782
+ // ${patternRules} pattern rule${patternRules === 1 ? "" : "s"} cannot be declared:
1783
+ // a pattern matches unboundedly many names, so there is no list to emit. Those
1784
+ // tags still resolve at build time; declare them by hand if the editor needs them.
1785
+ `;
1786
+ const source = `// GENERATED by ${generator}, do not edit.
1787
+ //
1788
+ // The components \`resolve\` supplies without an import. This describes what the
1789
+ // compiler already does; it does not enable it.
1790
+ ` + note + patternNote + (imports.length > 0 ? `
1791
+ ${imports.join("\n")}
1792
+ ` : "\n") + `
1793
+ declare global {
1794
+ ${[...lines, ...intrinsicLines].join("\n")}
1795
+ }
1796
+ `;
1797
+ return { source, declared, shadowedByDom, unavailable, patternRules };
1798
+ }
1799
+
1800
+ // src/resolve/write-globals.ts
1801
+ import { mkdirSync, readdirSync, readFileSync, writeFileSync } from "node:fs";
1802
+ import { basename, dirname, relative, sep, resolve as resolvePath } from "node:path";
1803
+ var GENERATED_MARKER = "GENERATED by @fluixi/compiler";
1804
+ var DEFAULT_GLOBALS_PATH = "fluixi.d.ts";
1805
+ function coveredByInclude(root, target) {
1806
+ let config;
1807
+ try {
1808
+ const raw = readFileSync(resolvePath(root, "tsconfig.json"), "utf8");
1809
+ config = JSON.parse(raw.replace(/^\s*\/\/.*$/gm, ""));
1810
+ } catch {
1811
+ return void 0;
1812
+ }
1813
+ if (config.extends !== void 0) return void 0;
1814
+ if (!Array.isArray(config.include)) return true;
1815
+ const relative2 = relativePosix(root, target);
1816
+ return config.include.some((entry) => {
1817
+ if (typeof entry !== "string") return false;
1818
+ const pattern = entry.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*\*\//g, "(?:.*/)?").replace(/\*/g, "[^/]*");
1819
+ return new RegExp(`^${pattern}(?:/.*)?$`).test(relative2);
1820
+ });
1821
+ }
1822
+ function relativePosix(from, to) {
1823
+ return relative(from, to).split(sep).join("/");
1824
+ }
1825
+ function forTypeScript(module, outDir, root) {
1826
+ if (!module.startsWith("/")) return module;
1827
+ const absolute = resolvePath(root, module.slice(1));
1828
+ let rel = relative(outDir, absolute).split(sep).join("/");
1829
+ if (!rel.startsWith(".")) rel = `./${rel}`;
1830
+ return rel.replace(/\.(tsx|ts|jsx|mts|cts)$/, ".js");
1831
+ }
1832
+ function projectDependencies(root) {
1833
+ try {
1834
+ const manifest = JSON.parse(readFileSync(resolvePath(root, "package.json"), "utf8"));
1835
+ return [
1836
+ ...Object.keys(manifest.dependencies ?? {}),
1837
+ ...Object.keys(manifest.devDependencies ?? {}),
1838
+ ...Object.keys(manifest.peerDependencies ?? {})
1839
+ ];
1840
+ } catch {
1841
+ return void 0;
1842
+ }
1843
+ }
1844
+ function patternCandidates(rules, root) {
1845
+ const out = [];
1846
+ for (const rule of rules) {
1847
+ if (!("match" in rule) || !rule.module.startsWith("/")) continue;
1848
+ const dir = dirname(rule.module);
1849
+ const file = basename(rule.module);
1850
+ const group = file.match(/\$\d+/);
1851
+ if (dir.includes("$") || !group || file.indexOf("$", group.index + 1) !== -1) continue;
1852
+ const before = file.slice(0, group.index);
1853
+ const after = file.slice(group.index + group[0].length);
1854
+ let entries;
1855
+ try {
1856
+ entries = readdirSync(resolvePath(root, dir.slice(1)));
1857
+ } catch {
1858
+ continue;
1859
+ }
1860
+ for (const entry of entries) {
1861
+ if (entry.length > before.length + after.length && entry.startsWith(before) && entry.endsWith(after)) {
1862
+ out.push(entry.slice(before.length, entry.length - after.length));
1863
+ }
1864
+ }
1865
+ }
1866
+ return out;
1867
+ }
1868
+ function writeComponentGlobals(options, root) {
1869
+ if (options.globals === false) return { status: "skipped", reason: "disabled" };
1870
+ const rules = options.resolve ?? [];
1871
+ const target = resolvePath(root, options.globals ?? DEFAULT_GLOBALS_PATH);
1872
+ let existing;
1873
+ try {
1874
+ existing = readFileSync(target, "utf8");
1875
+ } catch {
1876
+ existing = void 0;
1877
+ }
1878
+ if (existing !== void 0 && !existing.includes(GENERATED_MARKER)) {
1879
+ return { status: "skipped", reason: "foreign-file", path: target };
1880
+ }
1881
+ const { source, declared } = componentGlobals(rules, {
1882
+ available: projectDependencies(root),
1883
+ candidates: patternCandidates(rules, root),
1884
+ specifier: (module) => forTypeScript(module, dirname(target), root)
1885
+ });
1886
+ if (existing === source) {
1887
+ return {
1888
+ status: "unchanged",
1889
+ path: target,
1890
+ declared: declared.length,
1891
+ warning: warnIfUnreachable(root, target)
1892
+ };
1893
+ }
1894
+ mkdirSync(dirname(target), { recursive: true });
1895
+ writeFileSync(target, source);
1896
+ return {
1897
+ status: "written",
1898
+ path: target,
1899
+ declared: declared.length,
1900
+ warning: warnIfUnreachable(root, target)
1901
+ };
1902
+ }
1903
+ function warnIfUnreachable(root, target) {
1904
+ if (coveredByInclude(root, target) !== false) return void 0;
1905
+ const relative2 = relativePosix(root, target);
1906
+ return `[fluixi] ${relative2} is not covered by "include" in tsconfig.json, so TypeScript will ignore it and every resolved component stays "Cannot find name". Add "${relative2}" to "include".`;
1907
+ }
1908
+
1909
+ // src/options.ts
1910
+ var defaultOptions = {
1911
+ backend: "imperative",
1912
+ moduleName: "@fluixi/dom",
1913
+ delegateEvents: true,
1914
+ hydratable: false,
1915
+ sourceMaps: true,
1916
+ dev: false
1917
+ };
1918
+
1919
+ // src/index.ts
1920
+ var backends = {
1921
+ imperative: imperativeBackend
1922
+ };
1923
+ export {
1924
+ BUILTIN_COMPONENTS,
1925
+ CORE_CONTROL_FLOW,
1926
+ DEFAULT_GLOBALS_PATH,
1927
+ DOM_CONTROL_FLOW,
1928
+ RESERVED_COMPONENTS,
1929
+ ROUTER_COMPONENTS,
1930
+ RUNTIME_CONTRACT_V1,
1931
+ RUNTIME_CONTRACT_V2,
1932
+ backends,
1933
+ builtinComponentMap,
1934
+ builtinComponents,
1935
+ cleanTemplateText,
1936
+ compilePieces,
1937
+ compileTemplate,
1938
+ componentGlobals,
1939
+ createComponentResolver,
1940
+ defaultOptions,
1941
+ imperativeBackend,
1942
+ isReactiveShape,
1943
+ lowerTemplate,
1944
+ patternCandidates,
1945
+ resolveComponentSources,
1946
+ routerComponents,
1947
+ walk,
1948
+ writeComponentGlobals
1949
+ };