@mmapp/react-compiler 0.1.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (314) hide show
  1. package/README.md +107 -0
  2. package/compile-blueprint-chat.mjs +99 -0
  3. package/compile-blueprint-glass-console.mjs +98 -0
  4. package/compile-chat-defs.mjs +92 -0
  5. package/dist/babel/index.d.mts +3 -0
  6. package/dist/babel/index.d.ts +3 -0
  7. package/dist/babel/index.js +4851 -0
  8. package/dist/babel/index.mjs +7 -0
  9. package/dist/chunk-26U577GB.mjs +3465 -0
  10. package/dist/chunk-2FBDFAX6.mjs +2362 -0
  11. package/dist/chunk-2L4QSMXG.mjs +175 -0
  12. package/dist/chunk-2REDFOER.mjs +931 -0
  13. package/dist/chunk-46YKSHQR.mjs +175 -0
  14. package/dist/chunk-4XHK6FWL.mjs +2058 -0
  15. package/dist/chunk-5M7DKKBC.mjs +215 -0
  16. package/dist/chunk-5VNJ7C6N.mjs +154 -0
  17. package/dist/chunk-6CQOAAMV.mjs +1803 -0
  18. package/dist/chunk-6SEVAAVT.mjs +3516 -0
  19. package/dist/chunk-6YLR5ZDA.mjs +2829 -0
  20. package/dist/chunk-AOGY2GK6.mjs +3292 -0
  21. package/dist/chunk-AXXUXRNA.mjs +1434 -0
  22. package/dist/chunk-CHLVKMQW.mjs +175 -0
  23. package/dist/chunk-CKGOZAB7.mjs +939 -0
  24. package/dist/chunk-D34RAZUX.mjs +2223 -0
  25. package/dist/chunk-EQGA6A6D.mjs +121 -0
  26. package/dist/chunk-EY2CSXYA.mjs +822 -0
  27. package/dist/chunk-FIQ65CDR.mjs +925 -0
  28. package/dist/chunk-FOZXJFAR.mjs +186 -0
  29. package/dist/chunk-FX6URXWN.mjs +186 -0
  30. package/dist/chunk-G7SMOWOL.mjs +828 -0
  31. package/dist/chunk-GGB4G5YY.mjs +175 -0
  32. package/dist/chunk-HLRGCCIL.mjs +4839 -0
  33. package/dist/chunk-HOIUP6IF.mjs +690 -0
  34. package/dist/chunk-I3AU7GRD.mjs +120 -0
  35. package/dist/chunk-ILFGMUVD.mjs +1933 -0
  36. package/dist/chunk-IPTX5MJU.mjs +3223 -0
  37. package/dist/chunk-ITGUSH2Z.mjs +2783 -0
  38. package/dist/chunk-IXHBCAMF.mjs +3306 -0
  39. package/dist/chunk-J7TWJ3TM.mjs +2784 -0
  40. package/dist/chunk-JDPLDGVF.mjs +4810 -0
  41. package/dist/chunk-K53XP2DL.mjs +148 -0
  42. package/dist/chunk-K5HX2SVL.mjs +1902 -0
  43. package/dist/chunk-KFGYOOVS.mjs +214 -0
  44. package/dist/chunk-KFVVOS5N.mjs +925 -0
  45. package/dist/chunk-L2OZ4CDV.mjs +113 -0
  46. package/dist/chunk-MIZV3TAN.mjs +3293 -0
  47. package/dist/chunk-NKKLQE5V.mjs +148 -0
  48. package/dist/chunk-NOW23XFZ.mjs +186 -0
  49. package/dist/chunk-NRXQKQ74.mjs +148 -0
  50. package/dist/chunk-OWI6XWCD.mjs +3375 -0
  51. package/dist/chunk-PRUMNNDI.mjs +3192 -0
  52. package/dist/chunk-QTBD5B3F.mjs +148 -0
  53. package/dist/chunk-SKSDPPNT.mjs +3788 -0
  54. package/dist/chunk-SP2YUS33.mjs +186 -0
  55. package/dist/chunk-SU4E6E7B.mjs +3153 -0
  56. package/dist/chunk-SYUUKW5A.mjs +3379 -0
  57. package/dist/chunk-UL2XZEMA.mjs +3128 -0
  58. package/dist/chunk-XMWUHQVV.mjs +939 -0
  59. package/dist/chunk-XZNEDRGN.mjs +3876 -0
  60. package/dist/chunk-Y6FXYEAI.mjs +10 -0
  61. package/dist/chunk-YFS6JMYO.mjs +3342 -0
  62. package/dist/chunk-Z6AIQ4KL.mjs +113 -0
  63. package/dist/cli/index.d.mts +1 -0
  64. package/dist/cli/index.d.ts +1 -0
  65. package/dist/cli/index.js +11585 -0
  66. package/dist/cli/index.mjs +701 -0
  67. package/dist/codemod/cli.d.mts +1 -0
  68. package/dist/codemod/cli.d.ts +1 -0
  69. package/dist/codemod/cli.js +1104 -0
  70. package/dist/codemod/cli.mjs +157 -0
  71. package/dist/codemod/index.d.mts +148 -0
  72. package/dist/codemod/index.d.ts +148 -0
  73. package/dist/codemod/index.js +981 -0
  74. package/dist/codemod/index.mjs +25 -0
  75. package/dist/dev-server-Bs_sz2DG.d.mts +111 -0
  76. package/dist/dev-server-Bs_sz2DG.d.ts +111 -0
  77. package/dist/dev-server-CjoufJ-u.d.mts +109 -0
  78. package/dist/dev-server-CjoufJ-u.d.ts +109 -0
  79. package/dist/dev-server.d.mts +3 -0
  80. package/dist/dev-server.d.ts +3 -0
  81. package/dist/dev-server.js +7603 -0
  82. package/dist/dev-server.mjs +11 -0
  83. package/dist/envelope-DD7v0v6E.d.mts +265 -0
  84. package/dist/envelope-DD7v0v6E.d.ts +265 -0
  85. package/dist/envelope-vCVjrHlo.d.mts +265 -0
  86. package/dist/envelope-vCVjrHlo.d.ts +265 -0
  87. package/dist/envelope.d.mts +2 -0
  88. package/dist/envelope.d.ts +2 -0
  89. package/dist/envelope.js +5184 -0
  90. package/dist/envelope.mjs +9 -0
  91. package/dist/index-B5gSgvnd.d.mts +44 -0
  92. package/dist/index-B5gSgvnd.d.ts +44 -0
  93. package/dist/index-Bs0MnR54.d.mts +103 -0
  94. package/dist/index-Bs0MnR54.d.ts +103 -0
  95. package/dist/index-DR0nNc_f.d.mts +101 -0
  96. package/dist/index-DR0nNc_f.d.ts +101 -0
  97. package/dist/index-revho_gS.d.mts +104 -0
  98. package/dist/index-revho_gS.d.ts +104 -0
  99. package/dist/index.d.mts +1099 -0
  100. package/dist/index.d.ts +1099 -0
  101. package/dist/index.js +10162 -0
  102. package/dist/index.mjs +372 -0
  103. package/dist/init-IXEE2RCF.mjs +340 -0
  104. package/dist/project-compiler-EGJUTAJU.mjs +10 -0
  105. package/dist/project-compiler-VFR6CSDX.mjs +10 -0
  106. package/dist/project-decompiler-5GY2KSG4.mjs +7 -0
  107. package/dist/pull-A2QUHW4K.mjs +109 -0
  108. package/dist/pull-JBEQWVPE.mjs +109 -0
  109. package/dist/testing/index.d.mts +211 -0
  110. package/dist/testing/index.d.ts +211 -0
  111. package/dist/testing/index.js +5106 -0
  112. package/dist/testing/index.mjs +247 -0
  113. package/dist/vite/index.d.mts +59 -0
  114. package/dist/vite/index.d.ts +59 -0
  115. package/dist/vite/index.js +5023 -0
  116. package/dist/vite/index.mjs +8 -0
  117. package/examples/README.md +72 -0
  118. package/examples/authentication/main.workflow.tsx +139 -0
  119. package/examples/authentication/mm.config.ts +22 -0
  120. package/examples/authentication/models/auth.ts +45 -0
  121. package/examples/authentication/pages/LoginPage.tsx +79 -0
  122. package/examples/authentication/pages/SignupPage.tsx +87 -0
  123. package/examples/counter.workflow.tsx +65 -0
  124. package/examples/dashboard.workflow.tsx +419 -0
  125. package/examples/invoice-approval/actions/invoice.server.ts +72 -0
  126. package/examples/invoice-approval/main.workflow.tsx +168 -0
  127. package/examples/invoice-approval/mm.config.ts +18 -0
  128. package/examples/invoice-approval/models/invoice.ts +46 -0
  129. package/examples/invoice-approval/pages/InvoiceDetailPage.tsx +175 -0
  130. package/examples/invoice-approval/pages/InvoiceFormPage.tsx +198 -0
  131. package/examples/invoice-approval/pages/InvoiceListPage.tsx +141 -0
  132. package/examples/todo-app.workflow.tsx +131 -0
  133. package/examples/uber-app/actions/matching.server.ts +177 -0
  134. package/examples/uber-app/actions/notifications.server.ts +176 -0
  135. package/examples/uber-app/actions/payments.server.ts +184 -0
  136. package/examples/uber-app/actions/pricing.server.ts +176 -0
  137. package/examples/uber-app/app/admin/analytics.tsx +102 -0
  138. package/examples/uber-app/app/admin/fleet.tsx +102 -0
  139. package/examples/uber-app/app/admin/surge-pricing.tsx +95 -0
  140. package/examples/uber-app/app/driver/dashboard.tsx +87 -0
  141. package/examples/uber-app/app/driver/earnings.tsx +101 -0
  142. package/examples/uber-app/app/driver/navigation.tsx +94 -0
  143. package/examples/uber-app/app/driver/ride-acceptance.tsx +103 -0
  144. package/examples/uber-app/app/rider/home.tsx +109 -0
  145. package/examples/uber-app/app/rider/payment-methods.tsx +134 -0
  146. package/examples/uber-app/app/rider/ride-history.tsx +90 -0
  147. package/examples/uber-app/app/rider/ride-tracking.tsx +108 -0
  148. package/examples/uber-app/components/DriverCard.tsx +176 -0
  149. package/examples/uber-app/components/MapView.tsx +216 -0
  150. package/examples/uber-app/components/RatingStars.tsx +227 -0
  151. package/examples/uber-app/components/RideCard.tsx +167 -0
  152. package/examples/uber-app/mm.config.ts +30 -0
  153. package/examples/uber-app/models/location.model.ts +70 -0
  154. package/examples/uber-app/models/payment.model.ts +87 -0
  155. package/examples/uber-app/models/rating.model.ts +54 -0
  156. package/examples/uber-app/models/ride.model.ts +118 -0
  157. package/examples/uber-app/models/user.model.ts +66 -0
  158. package/examples/uber-app/models/vehicle.model.ts +63 -0
  159. package/examples/uber-app/tests/payment.test.tsx +129 -0
  160. package/examples/uber-app/tests/ride-flow.test.tsx +123 -0
  161. package/examples/uber-app/workflows/dispute-resolution.workflow.tsx +205 -0
  162. package/examples/uber-app/workflows/driver-onboarding.workflow.tsx +227 -0
  163. package/examples/uber-app/workflows/payment-processing.workflow.tsx +223 -0
  164. package/examples/uber-app/workflows/ride-request.workflow.tsx +194 -0
  165. package/package.json +77 -0
  166. package/package.json.backup +86 -0
  167. package/scripts/decompile.ts +226 -0
  168. package/scripts/seed-auth.ts +267 -0
  169. package/scripts/seed-uber.ts +248 -0
  170. package/scripts/validate-uber.ts +119 -0
  171. package/seed-blueprint-chat.mjs +444 -0
  172. package/seed-blueprint-glass-console.mjs +445 -0
  173. package/seed-compiled.mjs +318 -0
  174. package/src/RoundTripValidator.ts +400 -0
  175. package/src/__tests__/atom-rendering-coverage.test.ts +680 -0
  176. package/src/__tests__/auth-module-compilation.test.ts +247 -0
  177. package/src/__tests__/auth-template-compilation.test.ts +589 -0
  178. package/src/__tests__/change-extractor.test.ts +142 -0
  179. package/src/__tests__/cli-pull.test.ts +73 -0
  180. package/src/__tests__/cli-test.test.ts +72 -0
  181. package/src/__tests__/component-extractor.test.ts +331 -0
  182. package/src/__tests__/context-extractor.test.ts +145 -0
  183. package/src/__tests__/decompiler.test.ts +718 -0
  184. package/src/__tests__/define-blueprint.test.ts +133 -0
  185. package/src/__tests__/definition-validator.test.ts +519 -0
  186. package/src/__tests__/during-extractor.test.ts +152 -0
  187. package/src/__tests__/effect-extractor.test.ts +107 -0
  188. package/src/__tests__/event-emission.test.ts +127 -0
  189. package/src/__tests__/examples.test.ts +236 -0
  190. package/src/__tests__/full-blueprint-coverage.test.ts +1221 -0
  191. package/src/__tests__/golden-suite.test.ts +403 -0
  192. package/src/__tests__/grammar-island-extractor.test.ts +289 -0
  193. package/src/__tests__/instance-key.test.ts +82 -0
  194. package/src/__tests__/ir-migration.test.ts +255 -0
  195. package/src/__tests__/lock-file.test.ts +117 -0
  196. package/src/__tests__/model-extractor.test.ts +195 -0
  197. package/src/__tests__/model-field-acl.test.ts +237 -0
  198. package/src/__tests__/model-hooks.test.ts +130 -0
  199. package/src/__tests__/model-ref-resolution.test.ts +268 -0
  200. package/src/__tests__/model-roundtrip.test.ts +502 -0
  201. package/src/__tests__/model-runtime.test.ts +112 -0
  202. package/src/__tests__/model-transitions.test.ts +183 -0
  203. package/src/__tests__/nrt-action-trace.test.ts +391 -0
  204. package/src/__tests__/pipeline-hardening.test.ts +413 -0
  205. package/src/__tests__/project-compiler.test.ts +546 -0
  206. package/src/__tests__/project-decompiler.test.ts +343 -0
  207. package/src/__tests__/query-compilation.test.ts +145 -0
  208. package/src/__tests__/round-trip/PLAN.md +158 -0
  209. package/src/__tests__/round-trip/README.md +52 -0
  210. package/src/__tests__/round-trip/RESULTS.md +86 -0
  211. package/src/__tests__/round-trip/fixtures/data-heavy/main.workflow.tsx +55 -0
  212. package/src/__tests__/round-trip/fixtures/data-heavy/mm.config.ts +11 -0
  213. package/src/__tests__/round-trip/fixtures/data-heavy/models/contact.ts +54 -0
  214. package/src/__tests__/round-trip/fixtures/full-workflow/main.workflow.tsx +79 -0
  215. package/src/__tests__/round-trip/fixtures/full-workflow/mm.config.ts +12 -0
  216. package/src/__tests__/round-trip/fixtures/full-workflow/models/order.ts +50 -0
  217. package/src/__tests__/round-trip/fixtures/simple-crud/main.workflow.tsx +25 -0
  218. package/src/__tests__/round-trip/fixtures/simple-crud/mm.config.ts +11 -0
  219. package/src/__tests__/round-trip/fixtures/simple-crud/models/task.ts +32 -0
  220. package/src/__tests__/round-trip/fixtures/view-heavy/main.workflow.tsx +79 -0
  221. package/src/__tests__/round-trip/fixtures/view-heavy/mm.config.ts +10 -0
  222. package/src/__tests__/round-trip/round-trip.test.ts +2598 -0
  223. package/src/__tests__/round-trip-ir.test.ts +300 -0
  224. package/src/__tests__/round-trip.test.ts +1212 -0
  225. package/src/__tests__/route-merging.test.ts +372 -0
  226. package/src/__tests__/router-composition.test.ts +489 -0
  227. package/src/__tests__/router-extractor.test.ts +176 -0
  228. package/src/__tests__/server-action-extractor.test.ts +128 -0
  229. package/src/__tests__/smart-type-inference.test.ts +365 -0
  230. package/src/__tests__/source-envelope.test.ts +284 -0
  231. package/src/__tests__/source-fidelity.test.ts +516 -0
  232. package/src/__tests__/state-extractor.test.ts +115 -0
  233. package/src/__tests__/strict-mode.test.ts +227 -0
  234. package/src/__tests__/transition-effect-extractor.test.ts +119 -0
  235. package/src/__tests__/transition-extractor.test.ts +68 -0
  236. package/src/__tests__/ts-to-expression.test.ts +462 -0
  237. package/src/__tests__/type-generator.test.ts +201 -0
  238. package/src/__tests__/uber-validation.test.ts +502 -0
  239. package/src/action-compiler.ts +361 -0
  240. package/src/babel/emitters/experience-transform.ts +199 -0
  241. package/src/babel/emitters/ir-to-tsx-emitter.ts +110 -0
  242. package/src/babel/emitters/pure-form-emitter.ts +1023 -0
  243. package/src/babel/emitters/runtime-glue-emitter.ts +39 -0
  244. package/src/babel/extractors/change-extractor.ts +199 -0
  245. package/src/babel/extractors/component-extractor.ts +907 -0
  246. package/src/babel/extractors/computed-extractor.ts +262 -0
  247. package/src/babel/extractors/context-extractor.ts +277 -0
  248. package/src/babel/extractors/during-extractor.ts +295 -0
  249. package/src/babel/extractors/effect-extractor.ts +340 -0
  250. package/src/babel/extractors/event-extractor.ts +235 -0
  251. package/src/babel/extractors/grammar-island-extractor.ts +302 -0
  252. package/src/babel/extractors/model-extractor.ts +1018 -0
  253. package/src/babel/extractors/router-extractor.ts +303 -0
  254. package/src/babel/extractors/server-action-extractor.ts +173 -0
  255. package/src/babel/extractors/server-action-hook-extractor.ts +72 -0
  256. package/src/babel/extractors/server-state-extractor.ts +88 -0
  257. package/src/babel/extractors/state-extractor.ts +214 -0
  258. package/src/babel/extractors/transition-effect-extractor.ts +176 -0
  259. package/src/babel/extractors/transition-extractor.ts +143 -0
  260. package/src/babel/index.ts +24 -0
  261. package/src/babel/transpilers/ts-to-expression.ts +674 -0
  262. package/src/babel/visitor.ts +807 -0
  263. package/src/cli/auth.ts +255 -0
  264. package/src/cli/build.ts +288 -0
  265. package/src/cli/deploy.ts +206 -0
  266. package/src/cli/index.ts +328 -0
  267. package/src/cli/init.ts +388 -0
  268. package/src/cli/installer.ts +261 -0
  269. package/src/cli/lock-file.ts +94 -0
  270. package/src/cli/mmrc.ts +22 -0
  271. package/src/cli/pull.ts +172 -0
  272. package/src/cli/registry-client.ts +175 -0
  273. package/src/cli/test.ts +397 -0
  274. package/src/cli/type-generator.ts +243 -0
  275. package/src/codemod/__tests__/forward.test.ts +239 -0
  276. package/src/codemod/__tests__/reverse.test.ts +145 -0
  277. package/src/codemod/__tests__/round-trip.test.ts +137 -0
  278. package/src/codemod/annotation.ts +97 -0
  279. package/src/codemod/classify.ts +197 -0
  280. package/src/codemod/cli.ts +207 -0
  281. package/src/codemod/control-flow.ts +409 -0
  282. package/src/codemod/forward.ts +244 -0
  283. package/src/codemod/import-manager.ts +171 -0
  284. package/src/codemod/index.ts +120 -0
  285. package/src/codemod/reverse.ts +197 -0
  286. package/src/codemod/rules.ts +174 -0
  287. package/src/codemod/state-transform.ts +126 -0
  288. package/src/decompiler/ast-builder.ts +538 -0
  289. package/src/decompiler/config-generator.ts +151 -0
  290. package/src/decompiler/index.ts +315 -0
  291. package/src/decompiler/project-decompiler.ts +1776 -0
  292. package/src/decompiler/project.ts +862 -0
  293. package/src/decompiler/split-strategy.ts +140 -0
  294. package/src/decompiler/state-emitter.ts +1053 -0
  295. package/src/decompiler/sx-emitter.ts +318 -0
  296. package/src/decompiler/workspace-hydrator.ts +189 -0
  297. package/src/dev-server.ts +238 -0
  298. package/src/envelope/fs-tree.ts +217 -0
  299. package/src/envelope/source-envelope.ts +264 -0
  300. package/src/envelope.ts +315 -0
  301. package/src/incremental-compiler.ts +401 -0
  302. package/src/index.ts +99 -0
  303. package/src/model-compiler.ts +277 -0
  304. package/src/project-compiler.ts +1629 -0
  305. package/src/route-extractor.ts +333 -0
  306. package/src/testing/index.ts +32 -0
  307. package/src/testing/snapshot.ts +252 -0
  308. package/src/testing/test-utils.ts +226 -0
  309. package/src/types.ts +68 -0
  310. package/src/vite/index.ts +288 -0
  311. package/test-compile.mjs +142 -0
  312. package/tsconfig.json +25 -0
  313. package/tsup.config.ts +23 -0
  314. package/vitest.config.ts +9 -0
package/src/index.ts ADDED
@@ -0,0 +1,99 @@
1
+ /**
2
+ * Main entry point — @mindmatrix/react-compiler
3
+ *
4
+ * Exports all public APIs from extractors, emitters, and types.
5
+ */
6
+
7
+ export * from './types';
8
+ export { extractStates } from './babel/extractors/state-extractor';
9
+ export { extractEffects } from './babel/extractors/effect-extractor';
10
+ export { extractTransitions } from './babel/extractors/transition-extractor';
11
+ export { extractEvents } from './babel/extractors/event-extractor';
12
+ export { extractComponents } from './babel/extractors/component-extractor';
13
+ export { emitIR, emitPureForm, emitCanonical, emitCompiledOutput, compilerStateToWorkflow } from './babel/emitters/pure-form-emitter';
14
+ export { transformToFrontend } from './babel/emitters/experience-transform';
15
+ export type { FrontendExperienceNode, FrontendDataSource } from './babel/emitters/experience-transform';
16
+ export { decompileToTSX, normalizeDecompilerInput } from './babel/emitters/ir-to-tsx-emitter';
17
+ export { extractComputed } from './babel/extractors/computed-extractor';
18
+ export type { ComputedFieldExtraction } from './babel/extractors/computed-extractor';
19
+ export { createVisitor } from './babel/visitor';
20
+
21
+ // Re-export Babel plugin as default
22
+ export { default as babelPlugin } from './babel';
23
+
24
+ // Decompiler (IR → .workflow.tsx)
25
+ export { decompile, decompileProject, shouldDecompileAsProject } from './decompiler';
26
+ export type { DecompilerInput, DecompileOptions, DecompileResult, ProjectFile, DecompileProjectResult, DecompileProjectOptions } from './decompiler';
27
+
28
+ // Round-trip validator (IR → TSX → IR)
29
+ export { validateRoundTrip, validateSourceRoundTrip, compileSource } from './RoundTripValidator';
30
+ export type { RoundTripResult, RoundTripDiff } from './RoundTripValidator';
31
+
32
+ // Dev server (programmatic API)
33
+ export { createDevServer } from './dev-server';
34
+ export type { DevServerOptions, DevServerInstance } from './dev-server';
35
+
36
+ // CLI build/deploy (programmatic API)
37
+ export { build } from './cli/build';
38
+ export type { BuildOptions, BuildResult } from './cli/build';
39
+ export { deploy } from './cli/deploy';
40
+ export type { DeployOptions, DeployResult } from './cli/deploy';
41
+
42
+ // Envelope builder (content-addressed deployment bundles)
43
+ export { buildEnvelope } from './envelope';
44
+ export type { EnvelopeManifest, EnvelopeFile, BuildEnvelopeOptions, BuildEnvelopeResult } from './envelope';
45
+
46
+ // Source envelope (lower-level API)
47
+ export { createSourceEnvelope, computeEnvelopeId, envelopesEqual, diffEnvelopes } from './envelope/source-envelope';
48
+ export type { SourceEnvelope, SourceBinding, EnvelopeMetadata } from './envelope/source-envelope';
49
+ export { generateFsTree, detectFileRole, filterByRole, diffFsTrees } from './envelope/fs-tree';
50
+ export type { FsTree, FsTreeEntry, FileRole } from './envelope/fs-tree';
51
+
52
+ // Project compiler (multi-file → composed blueprint with child definitions)
53
+ export { compileProject, IncrementalProjectCompiler } from './project-compiler';
54
+ export type {
55
+ ProjectCompilerOptions,
56
+ ProjectCompilationResult,
57
+ ProjectCompilationError,
58
+ RouteTableEntry,
59
+ ServerActionEntry,
60
+ ImportLink,
61
+ } from './project-compiler';
62
+
63
+ // Phase 2: Model compiler
64
+ export { compileModel, compileModels } from './model-compiler';
65
+ export type { ModelCompilationResult, ModelCompilerOptions } from './model-compiler';
66
+
67
+ // Phase 2: Route extractor
68
+ export { extractRoutes } from './route-extractor';
69
+ export type {
70
+ RouteEntry,
71
+ LayoutEntry,
72
+ RouteExtractionResult,
73
+ RouteExtractorOptions,
74
+ } from './route-extractor';
75
+
76
+ // Phase 2: Action compiler
77
+ export { compileActions, resolveActionReferences } from './action-compiler';
78
+ export type {
79
+ ServerActionRegistration,
80
+ ActionCompilationResult,
81
+ ActionCompilerOptions,
82
+ } from './action-compiler';
83
+
84
+ // Phase 2: Incremental compiler utilities
85
+ export {
86
+ hashContent,
87
+ extractImports,
88
+ resolveImport,
89
+ buildDependencyGraph,
90
+ computeTransitiveDirtySet,
91
+ topologicalSort,
92
+ IncrementalCache,
93
+ } from './incremental-compiler';
94
+ export type {
95
+ FileHash,
96
+ IncrementalStats,
97
+ DependencyEdge,
98
+ DirtyFileSet,
99
+ } from './incremental-compiler';
@@ -0,0 +1,277 @@
1
+ /**
2
+ * Model Compiler — standalone module for compiling model files into IR.
3
+ *
4
+ * Extracts TypeScript interfaces from models/*.ts files and produces
5
+ * category='data' IRWorkflowDefinition objects. Handles:
6
+ * - Interface properties → IRFieldDefinition[]
7
+ * - Exported `transitions` arrays/objects → IRTransitionDefinition[]
8
+ * - Exported `fieldOptions` → field enrichment (validation, ACL, computed)
9
+ * - Exported `states` → explicit state declarations
10
+ * - JSDoc @workflow annotations for slug, version, category
11
+ *
12
+ * This module wraps the low-level Babel model-extractor with a clean
13
+ * file-level API for the ProjectCompiler to consume.
14
+ */
15
+
16
+ import { transformSync } from '@babel/core';
17
+ import type {
18
+ IRWorkflowDefinition,
19
+ } from '@mindmatrix/player-core';
20
+ import babelPlugin from './babel';
21
+
22
+ // =============================================================================
23
+ // Types
24
+ // =============================================================================
25
+
26
+ export interface ModelCompilationResult {
27
+ /** The compiled IR with category='data'. */
28
+ ir: IRWorkflowDefinition;
29
+ /** Interface name extracted from the model file. */
30
+ interfaceName: string;
31
+ /** Field names extracted from the interface. */
32
+ fieldNames: string[];
33
+ /** Transition names extracted from the model. */
34
+ transitionNames: string[];
35
+ /** State names (derived from transitions + explicit declarations). */
36
+ stateNames: string[];
37
+ /** Whether fieldOptions were present and applied. */
38
+ hasFieldOptions: boolean;
39
+ /** Raw field options map (for cross-file enrichment). */
40
+ fieldOptions: Record<string, Record<string, unknown>>;
41
+ }
42
+
43
+ export interface ModelCompilerOptions {
44
+ /** Compilation mode. Default: 'infer'. */
45
+ mode?: 'strict' | 'infer';
46
+ /** Override the slug (otherwise derived from interface name or @workflow). */
47
+ slugOverride?: string;
48
+ /** Override the category (defaults to 'data'). */
49
+ categoryOverride?: string;
50
+ }
51
+
52
+ // =============================================================================
53
+ // Interface Extraction (regex-based fast path)
54
+ // =============================================================================
55
+
56
+ /**
57
+ * Extracts the primary exported interface name from source code.
58
+ * Uses regex for speed — the full Babel parse handles the real extraction.
59
+ */
60
+ function extractInterfaceName(source: string): string {
61
+ const match = source.match(/export\s+interface\s+(\w+)/);
62
+ return match ? match[1] : 'Unknown';
63
+ }
64
+
65
+ /**
66
+ * Extracts @workflow JSDoc annotation metadata from source.
67
+ */
68
+ function extractWorkflowAnnotation(source: string): {
69
+ slug?: string;
70
+ version?: string;
71
+ category?: string;
72
+ description?: string;
73
+ } {
74
+ const result: Record<string, string> = {};
75
+ const workflowMatch = source.match(/@workflow\s+(.+)/);
76
+ if (workflowMatch) {
77
+ const attrs = workflowMatch[1];
78
+ const slugM = attrs.match(/slug="([^"]+)"/);
79
+ if (slugM) result.slug = slugM[1];
80
+ const versionM = attrs.match(/version="([^"]+)"/);
81
+ if (versionM) result.version = versionM[1];
82
+ const categoryM = attrs.match(/category="([^"]+)"/);
83
+ if (categoryM) result.category = categoryM[1];
84
+ }
85
+ const descMatch = source.match(/@description\s+(.+)/);
86
+ if (descMatch) result.description = descMatch[1].trim();
87
+ return result;
88
+ }
89
+
90
+ /**
91
+ * Extracts fieldOptions from source via regex (for metadata before full compile).
92
+ */
93
+ function extractFieldOptionsRaw(source: string): Record<string, Record<string, unknown>> {
94
+ const result: Record<string, Record<string, unknown>> = {};
95
+ const match = source.match(/export\s+const\s+fieldOptions\s*=\s*\{([\s\S]*?)\};/);
96
+ if (!match) return result;
97
+
98
+ const body = match[1];
99
+ const fieldRegex = /(\w+)\s*:\s*\{([^}]*)\}/g;
100
+ let fieldMatch;
101
+ while ((fieldMatch = fieldRegex.exec(body)) !== null) {
102
+ const fieldName = fieldMatch[1];
103
+ const optionsBody = fieldMatch[2];
104
+ const opts: Record<string, unknown> = {};
105
+
106
+ const kvRegex = /(\w+)\s*:\s*(?:'([^']*)'|"([^"]*)"|\[([^\]]*)\]|(\d+(?:\.\d+)?)|(\w+))/g;
107
+ let kvMatch;
108
+ while ((kvMatch = kvRegex.exec(optionsBody)) !== null) {
109
+ const key = kvMatch[1];
110
+ const strVal = kvMatch[2] ?? kvMatch[3];
111
+ const arrVal = kvMatch[4];
112
+ const numVal = kvMatch[5];
113
+ const identVal = kvMatch[6];
114
+
115
+ if (strVal !== undefined) {
116
+ opts[key] = strVal;
117
+ } else if (arrVal !== undefined) {
118
+ opts[key] = arrVal.split(',').map(s => s.trim().replace(/['"]/g, '')).filter(Boolean);
119
+ } else if (numVal !== undefined) {
120
+ opts[key] = Number(numVal);
121
+ } else if (identVal !== undefined) {
122
+ if (identVal === 'true') opts[key] = true;
123
+ else if (identVal === 'false') opts[key] = false;
124
+ else opts[key] = identVal;
125
+ }
126
+ }
127
+
128
+ result[fieldName] = opts;
129
+ }
130
+
131
+ return result;
132
+ }
133
+
134
+ // =============================================================================
135
+ // Main API
136
+ // =============================================================================
137
+
138
+ /**
139
+ * Compiles a single model file (models/*.ts) into an IRWorkflowDefinition
140
+ * with category='data'.
141
+ */
142
+ export function compileModel(
143
+ filename: string,
144
+ source: string,
145
+ options: ModelCompilerOptions = {},
146
+ ): ModelCompilationResult {
147
+ const mode = options.mode || 'infer';
148
+ const interfaceName = extractInterfaceName(source);
149
+ const annotation = extractWorkflowAnnotation(source);
150
+ const rawFieldOptions = extractFieldOptionsRaw(source);
151
+
152
+ const parserPlugins = filename.endsWith('.tsx')
153
+ ? (['typescript', 'jsx'] as const)
154
+ : (['typescript'] as const);
155
+
156
+ const babelResult = transformSync(source, {
157
+ filename,
158
+ plugins: [[babelPlugin, { mode }]],
159
+ parserOpts: { plugins: parserPlugins as any, attachComment: true },
160
+ });
161
+
162
+ const ir: IRWorkflowDefinition =
163
+ (babelResult as any)?.metadata?.mindmatrixIR ?? createEmptyModelIR(interfaceName);
164
+
165
+ // Enforce category
166
+ ir.category = options.categoryOverride || annotation.category || 'data';
167
+
168
+ // Apply slug override
169
+ if (options.slugOverride) {
170
+ ir.slug = options.slugOverride;
171
+ }
172
+
173
+ // Ensure states have at least a draft/idle state
174
+ if (ir.states.length === 0) {
175
+ ir.states.push({
176
+ name: 'draft',
177
+ type: 'START',
178
+ on_enter: [],
179
+ during: [],
180
+ on_exit: [],
181
+ });
182
+ }
183
+
184
+ // Ensure START state exists
185
+ const hasStart = ir.states.some(s => s.type === 'START');
186
+ if (!hasStart && ir.states.length > 0) {
187
+ ir.states[0].type = 'START';
188
+ }
189
+
190
+ // Add data provenance metadata
191
+ if (!ir.metadata) ir.metadata = {};
192
+ const meta = ir.metadata as Record<string, unknown>;
193
+ meta.sourceInterface = interfaceName;
194
+ meta.fieldOptions = rawFieldOptions;
195
+ meta.provenance = {
196
+ frontend: 'react-compiler',
197
+ source: 'model',
198
+ compiler_version: '2.0.0',
199
+ };
200
+
201
+ return {
202
+ ir,
203
+ interfaceName,
204
+ fieldNames: ir.fields.map(f => f.name),
205
+ transitionNames: ir.transitions.map(t => t.name),
206
+ stateNames: ir.states.map(s => s.name),
207
+ hasFieldOptions: Object.keys(rawFieldOptions).length > 0,
208
+ fieldOptions: rawFieldOptions,
209
+ };
210
+ }
211
+
212
+ /**
213
+ * Compiles multiple model files and returns all results keyed by filename.
214
+ */
215
+ export function compileModels(
216
+ files: Record<string, string>,
217
+ options: ModelCompilerOptions = {},
218
+ ): Map<string, ModelCompilationResult> {
219
+ const results = new Map<string, ModelCompilationResult>();
220
+
221
+ for (const [filename, source] of Object.entries(files)) {
222
+ try {
223
+ const compiled = compileModel(filename, source, options);
224
+ results.set(filename, compiled);
225
+ } catch (_err) {
226
+ const iface = extractInterfaceName(source);
227
+ results.set(filename, {
228
+ ir: createEmptyModelIR(iface),
229
+ interfaceName: iface,
230
+ fieldNames: [],
231
+ transitionNames: [],
232
+ stateNames: ['draft'],
233
+ hasFieldOptions: false,
234
+ fieldOptions: {},
235
+ });
236
+ }
237
+ }
238
+
239
+ return results;
240
+ }
241
+
242
+ /**
243
+ * Creates an empty model IR for error cases.
244
+ */
245
+ function createEmptyModelIR(interfaceName: string): IRWorkflowDefinition {
246
+ const slug = interfaceName
247
+ .replace(/([A-Z])/g, '-$1')
248
+ .toLowerCase()
249
+ .replace(/^-/, '');
250
+
251
+ return {
252
+ slug,
253
+ name: interfaceName,
254
+ version: '1.0.0',
255
+ description: 'Data model: ' + interfaceName,
256
+ category: 'data',
257
+ fields: [],
258
+ states: [{
259
+ name: 'draft',
260
+ type: 'START',
261
+ on_enter: [],
262
+ during: [],
263
+ on_exit: [],
264
+ }],
265
+ transitions: [],
266
+ roles: [],
267
+ tags: [{ tag_name: 'data' }, { tag_name: 'model' }],
268
+ metadata: {
269
+ sourceInterface: interfaceName,
270
+ provenance: {
271
+ frontend: 'react-compiler',
272
+ source: 'model',
273
+ compiler_version: '2.0.0',
274
+ },
275
+ },
276
+ };
277
+ }