@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
@@ -0,0 +1,45 @@
1
+ import MagicString from 'magic-string';
2
+ import { type DestructureBail } from '../analyze/props-destructure.cjs';
3
+ export interface PropsDiagnostic {
4
+ /** The binding we couldn't rewrite. */
5
+ name: string;
6
+ reason: DestructureBail;
7
+ /** Sentence for the message. */
8
+ message: string;
9
+ /** Character offset of the pattern it came from. */
10
+ start: number;
11
+ }
12
+ export interface PropsTransformOptions {
13
+ /** Name to give the props parameter. @default 'props' */
14
+ parameterName?: string;
15
+ /** Module `splitProps` is imported from when a rest needs it. @default '@fluixi/dom' */
16
+ runtimeModule?: string;
17
+ }
18
+ export interface PropsTransformResult {
19
+ code: string;
20
+ map: ReturnType<MagicString['generateMap']>;
21
+ diagnostics: PropsDiagnostic[];
22
+ /** How many bindings were rewritten. Zero means the source came back untouched. */
23
+ rewritten: number;
24
+ }
25
+ /** One span to replace. Same shape the template transform uses for its own edits. */
26
+ export interface PropsEdit {
27
+ start: number;
28
+ end: number;
29
+ code: string;
30
+ }
31
+ export interface PropsEditsResult {
32
+ edits: PropsEdit[];
33
+ diagnostics: PropsDiagnostic[];
34
+ /** Runtime symbols the emitted code needs: `splitProps`, when a pattern had a rest. */
35
+ used: Set<string>;
36
+ }
37
+ /**
38
+ * Work out the edits without applying them, so a caller that already has the source in a
39
+ * MagicString can fold them into its own. That's how the template transform picks this
40
+ * up: one string, one map, and holes get the rewrite because it slices them with the
41
+ * edits applied.
42
+ */
43
+ export declare function collectPropsEdits(program: unknown, code: string, options?: PropsTransformOptions): PropsEditsResult;
44
+ /** Run the rewrite on its own. The template transform folds the edits in instead. */
45
+ export declare function transformProps(code: string, filename?: string, options?: PropsTransformOptions): PropsTransformResult;
@@ -0,0 +1,46 @@
1
+ import MagicString from 'magic-string';
2
+ import { type DestructureBail } from '../analyze/props-destructure.js';
3
+ export interface PropsDiagnostic {
4
+ /** The binding we couldn't rewrite. */
5
+ name: string;
6
+ reason: DestructureBail;
7
+ /** Sentence for the message. */
8
+ message: string;
9
+ /** Character offset of the pattern it came from. */
10
+ start: number;
11
+ }
12
+ export interface PropsTransformOptions {
13
+ /** Name to give the props parameter. @default 'props' */
14
+ parameterName?: string;
15
+ /** Module `splitProps` is imported from when a rest needs it. @default '@fluixi/dom' */
16
+ runtimeModule?: string;
17
+ }
18
+ export interface PropsTransformResult {
19
+ code: string;
20
+ map: ReturnType<MagicString['generateMap']>;
21
+ diagnostics: PropsDiagnostic[];
22
+ /** How many bindings were rewritten. Zero means the source came back untouched. */
23
+ rewritten: number;
24
+ }
25
+ /** One span to replace. Same shape the template transform uses for its own edits. */
26
+ export interface PropsEdit {
27
+ start: number;
28
+ end: number;
29
+ code: string;
30
+ }
31
+ export interface PropsEditsResult {
32
+ edits: PropsEdit[];
33
+ diagnostics: PropsDiagnostic[];
34
+ /** Runtime symbols the emitted code needs: `splitProps`, when a pattern had a rest. */
35
+ used: Set<string>;
36
+ }
37
+ /**
38
+ * Work out the edits without applying them, so a caller that already has the source in a
39
+ * MagicString can fold them into its own. That's how the template transform picks this
40
+ * up: one string, one map, and holes get the rewrite because it slices them with the
41
+ * edits applied.
42
+ */
43
+ export declare function collectPropsEdits(program: unknown, code: string, options?: PropsTransformOptions): PropsEditsResult;
44
+ /** Run the rewrite on its own. The template transform folds the edits in instead. */
45
+ export declare function transformProps(code: string, filename?: string, options?: PropsTransformOptions): PropsTransformResult;
46
+ //# sourceMappingURL=props.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"props.d.ts","sourceRoot":"","sources":["../../src/transform/props.ts"],"names":[],"mappings":"AAaA,OAAO,WAAW,MAAM,cAAc,CAAC;AACvC,OAAO,EAAqC,KAAK,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAU1G,MAAM,WAAW,eAAe;IAC9B,uCAAuC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,eAAe,CAAC;IACxB,gCAAgC;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,oDAAoD;IACpD,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,qBAAqB;IACpC,yDAAyD;IACzD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,wFAAwF;IACxF,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,UAAU,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC;IAC5C,WAAW,EAAE,eAAe,EAAE,CAAC;IAC/B,mFAAmF;IACnF,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qFAAqF;AACrF,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,WAAW,EAAE,eAAe,EAAE,CAAC;IAC/B,uFAAuF;IACvF,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACnB;AA+ED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,qBAA0B,GAClC,gBAAgB,CAuFlB;AAgBD,qFAAqF;AACrF,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,QAAQ,SAAe,EACvB,OAAO,GAAE,qBAA0B,GAClC,oBAAoB,CA0BtB"}
@@ -0,0 +1,221 @@
1
+ /**
2
+ * Rewrite destructured component props into property reads.
3
+ *
4
+ * `function Card({ title, size = 'md' })` becomes `function Card(props)` with `title`
5
+ * rewritten to `props.title` wherever it's used, so the reads stay live. What can't be
6
+ * rewritten is left alone and reported: see analyze/props-destructure for the rules.
7
+ *
8
+ * Source in, source out, spans spliced with magic-string, so the author's formatting
9
+ * survives and the map comes out of the splice. It runs before templates are compiled,
10
+ * which is what makes JSX and html`` behave the same: both end up reading `props.title`
11
+ * from the same rewritten body, and neither one needs to know this happened.
12
+ */
13
+ import { parse } from '@babel/parser';
14
+ import MagicString from 'magic-string';
15
+ import { planPropsDestructure, explainBail } from '../analyze/props-destructure.js';
16
+ import { moduleBindings } from './bindings.js';
17
+ /** Walk everything under a node. Skips TS annotations, where a name isn't a value. */
18
+ function walk(root, visit, parent = null) {
19
+ if (!root || typeof root !== 'object' || typeof root.type !== 'string')
20
+ return;
21
+ if (root.type.startsWith('TS'))
22
+ return;
23
+ if (visit(root, parent) === false)
24
+ return;
25
+ for (const key of Object.keys(root)) {
26
+ if (key === 'loc' || key === 'leadingComments' || key === 'trailingComments')
27
+ continue;
28
+ const value = root[key];
29
+ if (Array.isArray(value)) {
30
+ for (const item of value)
31
+ walk(item, visit, root);
32
+ }
33
+ else if (value && typeof value === 'object') {
34
+ walk(value, visit, root);
35
+ }
36
+ }
37
+ }
38
+ /** A component by the same rule JSX uses: a capitalised name. */
39
+ function isComponentName(name) {
40
+ return !!name && name[0] >= 'A' && name[0] <= 'Z';
41
+ }
42
+ /** Component functions in a module, paired with the name they were declared under. */
43
+ function componentFunctions(program) {
44
+ const found = [];
45
+ walk(program, (node) => {
46
+ if (node.type === 'FunctionDeclaration' && isComponentName(node.id?.name)) {
47
+ found.push(node);
48
+ return;
49
+ }
50
+ if (node.type === 'VariableDeclarator' && isComponentName(node.id?.name)) {
51
+ const init = node.init;
52
+ if (init && (init.type === 'ArrowFunctionExpression' || init.type === 'FunctionExpression'))
53
+ found.push(init);
54
+ }
55
+ });
56
+ return found;
57
+ }
58
+ /** Names used anywhere in a function, so the parameter we introduce doesn't collide. */
59
+ function usedNames(fn) {
60
+ const names = new Set();
61
+ walk(fn, (node) => {
62
+ if (node.type === 'Identifier')
63
+ names.add(node.name);
64
+ });
65
+ return names;
66
+ }
67
+ /**
68
+ * Positions where an identifier isn't a reference to the binding: a property name, a
69
+ * non-computed object key, a label. A shorthand property is handled by the caller,
70
+ * since it needs the key written out.
71
+ */
72
+ function isReferencePosition(node, parent) {
73
+ if (!parent)
74
+ return true;
75
+ switch (parent.type) {
76
+ case 'MemberExpression':
77
+ case 'OptionalMemberExpression':
78
+ return !(parent.property === node && !parent.computed);
79
+ case 'ObjectProperty':
80
+ case 'ObjectMethod':
81
+ case 'ClassProperty':
82
+ case 'ClassMethod':
83
+ return !(parent.key === node && !parent.computed);
84
+ case 'LabeledStatement':
85
+ case 'BreakStatement':
86
+ case 'ContinueStatement':
87
+ return parent.label !== node;
88
+ case 'ImportSpecifier':
89
+ case 'ExportSpecifier':
90
+ return false;
91
+ default:
92
+ return true;
93
+ }
94
+ }
95
+ /**
96
+ * Work out the edits without applying them, so a caller that already has the source in a
97
+ * MagicString can fold them into its own. That's how the template transform picks this
98
+ * up: one string, one map, and holes get the rewrite because it slices them with the
99
+ * edits applied.
100
+ */
101
+ export function collectPropsEdits(program, code, options = {}) {
102
+ const edits = [];
103
+ const diagnostics = [];
104
+ const used = new Set();
105
+ for (const fn of componentFunctions(program)) {
106
+ const pattern = fn.params?.[0];
107
+ if (pattern?.type !== 'ObjectPattern')
108
+ continue;
109
+ const plan = planPropsDestructure(pattern, fn.body);
110
+ for (const b of plan.bails) {
111
+ diagnostics.push({ name: b.name, reason: b.reason, message: explainBail(b.reason), start: pattern.start });
112
+ }
113
+ // Whole function or nothing: half a rewrite would read as if the rest were fine too.
114
+ if (plan.bails.length > 0)
115
+ continue;
116
+ if (plan.reads.length === 0 && !plan.rest)
117
+ continue;
118
+ const taken = usedNames(fn);
119
+ let parameter = options.parameterName ?? 'props';
120
+ while (taken.has(parameter))
121
+ parameter = `_${parameter}`;
122
+ const replacement = new Map();
123
+ for (const read of plan.reads) {
124
+ const access = `${parameter}.${read.path.join('.')}`;
125
+ const fallback = read.fallback;
126
+ // A default only applies to `undefined`, so this can't collapse to `??`.
127
+ replacement.set(read.name, fallback ? `(${access} === undefined ? ${code.slice(fallback.start, fallback.end)} : ${access})` : access);
128
+ }
129
+ // The pattern's range covers its type annotation, so overwriting the whole span
130
+ // would take `: { title: string }` with it. Stop at the annotation and the type
131
+ // stays exactly as written.
132
+ const annotation = pattern.typeAnnotation;
133
+ edits.push({ start: pattern.start, end: annotation?.start ?? pattern.end, code: parameter });
134
+ // `...rest` becomes the splitProps call the author would have written. splitProps
135
+ // carries the getters over instead of reading them, which is the whole reason a
136
+ // plain rest can't be rewritten: so this hands the job to the runtime helper that
137
+ // does it properly rather than refusing the pattern.
138
+ if (plan.rest) {
139
+ const keys = plan.rest.keys.map((k) => JSON.stringify(k)).join(', ');
140
+ const body = fn.body;
141
+ edits.push({
142
+ start: body.start + 1,
143
+ end: body.start + 1,
144
+ code: `\n const [, ${plan.rest.name}] = splitProps(${parameter}, [${keys}]);`,
145
+ });
146
+ used.add('splitProps');
147
+ }
148
+ // Collect first, rewrite after: turning a node into a member below gives it new
149
+ // children, and a walk still in progress would descend into them and match again.
150
+ const matches = [];
151
+ walk(fn.body, (node, parent) => {
152
+ if (node.type !== 'Identifier')
153
+ return undefined;
154
+ const text = replacement.get(node.name);
155
+ if (!text)
156
+ return undefined;
157
+ const shorthand = parent?.type === 'ObjectProperty' && parent.shorthand && parent.value === node;
158
+ if (!shorthand && !isReferencePosition(node, parent))
159
+ return undefined;
160
+ const path = plan.reads.find((r) => r.name === node.name).path;
161
+ matches.push({ node, parent: shorthand ? parent : null, text, property: path[path.length - 1] });
162
+ return undefined;
163
+ });
164
+ for (const match of matches) {
165
+ if (match.parent) {
166
+ // `{ name }` needs the key spelled out, or the result isn't an object literal.
167
+ edits.push({ start: match.parent.start, end: match.parent.end, code: `${match.node.name}: ${match.text}` });
168
+ }
169
+ else {
170
+ edits.push({ start: match.node.start, end: match.node.end, code: match.text });
171
+ }
172
+ // Say it in the AST too, not only in the text. Whether a hole is wired reactively
173
+ // is decided from the expression's shape, and a bare identifier is not reactive ,
174
+ // so leaving the node as an Identifier emits `props.text` read once, which is the
175
+ // bug this whole pass exists to remove. A member read is reactive, which is what
176
+ // the emitted code now is.
177
+ asMemberRead(match.node, parameter, match.property);
178
+ }
179
+ }
180
+ return { edits, diagnostics, used };
181
+ }
182
+ /**
183
+ * Rewrite an identifier node into `<parameter>.<property>` in place, keeping its span so
184
+ * the text it maps to is unchanged. The synthetic children are zero-width at the node's
185
+ * own edges: nothing slices them, and they exist so shape analysis sees a member.
186
+ */
187
+ function asMemberRead(node, parameter, property) {
188
+ node.type = 'MemberExpression';
189
+ node.computed = false;
190
+ node.optional = false;
191
+ node.object = { type: 'Identifier', name: parameter, start: node.start, end: node.start };
192
+ node.property = { type: 'Identifier', name: property, start: node.end, end: node.end };
193
+ delete node['name'];
194
+ }
195
+ /** Run the rewrite on its own. The template transform folds the edits in instead. */
196
+ export function transformProps(code, filename = 'module.tsx', options = {}) {
197
+ const ast = parse(code, {
198
+ sourceType: 'module',
199
+ plugins: ['typescript', 'jsx'],
200
+ errorRecovery: true,
201
+ });
202
+ const { edits, diagnostics, used } = collectPropsEdits(ast.program, code, options);
203
+ const source = new MagicString(code);
204
+ for (const e of edits) {
205
+ if (e.start === e.end)
206
+ source.appendLeft(e.start, e.code);
207
+ else
208
+ source.overwrite(e.start, e.end, e.code);
209
+ }
210
+ // Standalone, there's no prologue to join, so the import goes in here, unless the
211
+ // module already has the name bound.
212
+ if (used.has('splitProps') && !moduleBindings(ast.program).has('splitProps')) {
213
+ source.prepend(`import { splitProps } from ${JSON.stringify(options.runtimeModule ?? '@fluixi/dom')};\n`);
214
+ }
215
+ return {
216
+ code: source.toString(),
217
+ map: source.generateMap({ source: filename, includeContent: true, hires: true }),
218
+ diagnostics,
219
+ rewritten: edits.filter((e) => e.code !== (options.parameterName ?? 'props')).length,
220
+ };
221
+ }