@mmapp/react-compiler 0.1.0-alpha.1 → 0.1.0-alpha.3

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 (251) hide show
  1. package/ATOM-PIPELINE.md +144 -0
  2. package/README.md +88 -40
  3. package/dist/babel/index.js +113 -6
  4. package/dist/babel/index.mjs +2 -2
  5. package/dist/chunk-3USIFFE4.mjs +2190 -0
  6. package/dist/chunk-45YMGEVT.mjs +186 -0
  7. package/dist/chunk-4FN2AISW.mjs +148 -0
  8. package/dist/chunk-4OPI5L7G.mjs +2593 -0
  9. package/dist/chunk-4RYTKOOJ.mjs +186 -0
  10. package/dist/chunk-5RKTOVR5.mjs +244 -0
  11. package/dist/chunk-5YDMOO4X.mjs +214 -0
  12. package/dist/chunk-64ZWEMLJ.mjs +148 -0
  13. package/dist/chunk-6XP4KSWQ.mjs +2190 -0
  14. package/dist/chunk-72QWL54I.mjs +175 -0
  15. package/dist/chunk-7B4TRI7C.mjs +4835 -0
  16. package/dist/chunk-7ZKGHTNB.mjs +4952 -0
  17. package/dist/chunk-CIESM3BP.mjs +33 -0
  18. package/dist/chunk-DE3ZGQAC.mjs +148 -0
  19. package/dist/chunk-DMCY3BBG.mjs +1933 -0
  20. package/dist/chunk-DPIK3PJS.mjs +244 -0
  21. package/dist/chunk-E5IVH4RE.mjs +186 -0
  22. package/dist/chunk-E6FZNUR5.mjs +4953 -0
  23. package/dist/chunk-EJRBDQDP.mjs +2607 -0
  24. package/dist/chunk-ELO4TXJL.mjs +186 -0
  25. package/dist/chunk-FKRO52XH.mjs +3446 -0
  26. package/dist/chunk-FL4YAKU6.mjs +4941 -0
  27. package/dist/chunk-FYT47UBU.mjs +5076 -0
  28. package/dist/chunk-GCLGPOJZ.mjs +148 -0
  29. package/dist/chunk-GXB4JOP7.mjs +5072 -0
  30. package/dist/chunk-HFXOUMTD.mjs +175 -0
  31. package/dist/chunk-HWIZ47US.mjs +214 -0
  32. package/dist/chunk-IB7MNPQL.mjs +4953 -0
  33. package/dist/chunk-ICSIHQCG.mjs +148 -0
  34. package/dist/chunk-JLA5VNQ3.mjs +186 -0
  35. package/dist/chunk-JQLWFCTM.mjs +214 -0
  36. package/dist/chunk-KFJJCQAL.mjs +148 -0
  37. package/dist/chunk-KJUIIEQE.mjs +186 -0
  38. package/dist/chunk-KNWTHRVQ.mjs +175 -0
  39. package/dist/chunk-KSG4XSZF.mjs +175 -0
  40. package/dist/chunk-LF5N6DOU.mjs +175 -0
  41. package/dist/chunk-LJQCM2IM.mjs +214 -0
  42. package/dist/chunk-NW6555WJ.mjs +186 -0
  43. package/dist/chunk-OMZE6VLQ.mjs +214 -0
  44. package/dist/chunk-P4BR7WVO.mjs +2190 -0
  45. package/dist/chunk-QQHVYH2X.mjs +244 -0
  46. package/dist/chunk-S5QLWLLT.mjs +186 -0
  47. package/dist/chunk-SCWGT2FY.mjs +2190 -0
  48. package/dist/chunk-SMKJUSB3.mjs +2190 -0
  49. package/dist/chunk-VCAY2KGM.mjs +175 -0
  50. package/dist/chunk-WECAV6QB.mjs +148 -0
  51. package/dist/chunk-WMKBXUCE.mjs +3228 -0
  52. package/dist/chunk-XAJ5BKKL.mjs +4947 -0
  53. package/dist/chunk-XG2X7AEA.mjs +175 -0
  54. package/dist/chunk-XG7Z23NQ.mjs +148 -0
  55. package/dist/chunk-XWZAOCQ7.mjs +2607 -0
  56. package/dist/chunk-Y6MA7ULW.mjs +148 -0
  57. package/dist/chunk-YMS7Q7LG.mjs +214 -0
  58. package/dist/chunk-ZA37XTGA.mjs +175 -0
  59. package/dist/cli/index.js +1616 -366
  60. package/dist/cli/index.mjs +8 -8
  61. package/dist/codemod/cli.mjs +1 -1
  62. package/dist/codemod/index.mjs +1 -1
  63. package/dist/dev-server-RmGHIntF.d.mts +113 -0
  64. package/dist/dev-server-RmGHIntF.d.ts +113 -0
  65. package/dist/dev-server.d.mts +1 -1
  66. package/dist/dev-server.d.ts +1 -1
  67. package/dist/dev-server.js +982 -53
  68. package/dist/dev-server.mjs +5 -5
  69. package/dist/envelope.js +113 -6
  70. package/dist/envelope.mjs +3 -3
  71. package/dist/index.d.mts +5 -1
  72. package/dist/index.d.ts +5 -1
  73. package/dist/index.js +992 -63
  74. package/dist/index.mjs +8 -8
  75. package/{src/cli/init.ts → dist/init-7JQMAAXS.mjs} +70 -95
  76. package/dist/init-EHO4VQ22.mjs +369 -0
  77. package/dist/init-UC3FWPIW.mjs +367 -0
  78. package/dist/init-UNSMVKIK.mjs +366 -0
  79. package/dist/init-UNV5XIDE.mjs +367 -0
  80. package/dist/project-compiler-2P4N4DR7.mjs +10 -0
  81. package/dist/project-compiler-D2LCC27O.mjs +10 -0
  82. package/dist/project-compiler-EJ3GANJE.mjs +10 -0
  83. package/dist/project-compiler-LOQKVRZJ.mjs +10 -0
  84. package/dist/project-compiler-RQ6OQKRM.mjs +10 -0
  85. package/dist/project-compiler-VWNNCHGO.mjs +10 -0
  86. package/dist/project-compiler-XVAAU4C5.mjs +10 -0
  87. package/dist/project-compiler-YES5FGMD.mjs +10 -0
  88. package/dist/project-compiler-ZKMQDLGU.mjs +10 -0
  89. package/dist/project-decompiler-FLXCEJHS.mjs +7 -0
  90. package/dist/project-decompiler-VLPR22QF.mjs +7 -0
  91. package/dist/pull-FUS5QYZS.mjs +109 -0
  92. package/dist/pull-LD5ENLGY.mjs +109 -0
  93. package/dist/testing/index.js +113 -6
  94. package/dist/testing/index.mjs +2 -2
  95. package/dist/vite/index.js +113 -6
  96. package/dist/vite/index.mjs +3 -3
  97. package/examples/uber-app/app/admin/fleet.tsx +19 -19
  98. package/package.json +4 -3
  99. package/compile-blueprint-chat.mjs +0 -99
  100. package/compile-blueprint-glass-console.mjs +0 -98
  101. package/compile-chat-defs.mjs +0 -92
  102. package/examples/uber-app/tests/payment.test.tsx +0 -129
  103. package/examples/uber-app/tests/ride-flow.test.tsx +0 -123
  104. package/package.json.backup +0 -86
  105. package/scripts/decompile.ts +0 -226
  106. package/scripts/seed-auth.ts +0 -267
  107. package/scripts/seed-uber.ts +0 -248
  108. package/scripts/validate-uber.ts +0 -119
  109. package/seed-blueprint-chat.mjs +0 -444
  110. package/seed-blueprint-glass-console.mjs +0 -445
  111. package/seed-compiled.mjs +0 -318
  112. package/src/RoundTripValidator.ts +0 -400
  113. package/src/__tests__/atom-rendering-coverage.test.ts +0 -680
  114. package/src/__tests__/auth-module-compilation.test.ts +0 -247
  115. package/src/__tests__/auth-template-compilation.test.ts +0 -589
  116. package/src/__tests__/change-extractor.test.ts +0 -142
  117. package/src/__tests__/cli-pull.test.ts +0 -73
  118. package/src/__tests__/cli-test.test.ts +0 -72
  119. package/src/__tests__/component-extractor.test.ts +0 -331
  120. package/src/__tests__/context-extractor.test.ts +0 -145
  121. package/src/__tests__/decompiler.test.ts +0 -718
  122. package/src/__tests__/define-blueprint.test.ts +0 -133
  123. package/src/__tests__/definition-validator.test.ts +0 -519
  124. package/src/__tests__/during-extractor.test.ts +0 -152
  125. package/src/__tests__/effect-extractor.test.ts +0 -107
  126. package/src/__tests__/event-emission.test.ts +0 -127
  127. package/src/__tests__/examples.test.ts +0 -236
  128. package/src/__tests__/full-blueprint-coverage.test.ts +0 -1221
  129. package/src/__tests__/golden-suite.test.ts +0 -403
  130. package/src/__tests__/grammar-island-extractor.test.ts +0 -289
  131. package/src/__tests__/instance-key.test.ts +0 -82
  132. package/src/__tests__/ir-migration.test.ts +0 -255
  133. package/src/__tests__/lock-file.test.ts +0 -117
  134. package/src/__tests__/model-extractor.test.ts +0 -195
  135. package/src/__tests__/model-field-acl.test.ts +0 -237
  136. package/src/__tests__/model-hooks.test.ts +0 -130
  137. package/src/__tests__/model-ref-resolution.test.ts +0 -268
  138. package/src/__tests__/model-roundtrip.test.ts +0 -502
  139. package/src/__tests__/model-runtime.test.ts +0 -112
  140. package/src/__tests__/model-transitions.test.ts +0 -183
  141. package/src/__tests__/nrt-action-trace.test.ts +0 -391
  142. package/src/__tests__/pipeline-hardening.test.ts +0 -413
  143. package/src/__tests__/project-compiler.test.ts +0 -546
  144. package/src/__tests__/project-decompiler.test.ts +0 -343
  145. package/src/__tests__/query-compilation.test.ts +0 -145
  146. package/src/__tests__/round-trip/PLAN.md +0 -158
  147. package/src/__tests__/round-trip/README.md +0 -52
  148. package/src/__tests__/round-trip/RESULTS.md +0 -86
  149. package/src/__tests__/round-trip/fixtures/data-heavy/main.workflow.tsx +0 -55
  150. package/src/__tests__/round-trip/fixtures/data-heavy/mm.config.ts +0 -11
  151. package/src/__tests__/round-trip/fixtures/data-heavy/models/contact.ts +0 -54
  152. package/src/__tests__/round-trip/fixtures/full-workflow/main.workflow.tsx +0 -79
  153. package/src/__tests__/round-trip/fixtures/full-workflow/mm.config.ts +0 -12
  154. package/src/__tests__/round-trip/fixtures/full-workflow/models/order.ts +0 -50
  155. package/src/__tests__/round-trip/fixtures/simple-crud/main.workflow.tsx +0 -25
  156. package/src/__tests__/round-trip/fixtures/simple-crud/mm.config.ts +0 -11
  157. package/src/__tests__/round-trip/fixtures/simple-crud/models/task.ts +0 -32
  158. package/src/__tests__/round-trip/fixtures/view-heavy/main.workflow.tsx +0 -79
  159. package/src/__tests__/round-trip/fixtures/view-heavy/mm.config.ts +0 -10
  160. package/src/__tests__/round-trip/round-trip.test.ts +0 -2598
  161. package/src/__tests__/round-trip-ir.test.ts +0 -300
  162. package/src/__tests__/round-trip.test.ts +0 -1212
  163. package/src/__tests__/route-merging.test.ts +0 -372
  164. package/src/__tests__/router-composition.test.ts +0 -489
  165. package/src/__tests__/router-extractor.test.ts +0 -176
  166. package/src/__tests__/server-action-extractor.test.ts +0 -128
  167. package/src/__tests__/smart-type-inference.test.ts +0 -365
  168. package/src/__tests__/source-envelope.test.ts +0 -284
  169. package/src/__tests__/source-fidelity.test.ts +0 -516
  170. package/src/__tests__/state-extractor.test.ts +0 -115
  171. package/src/__tests__/strict-mode.test.ts +0 -227
  172. package/src/__tests__/transition-effect-extractor.test.ts +0 -119
  173. package/src/__tests__/transition-extractor.test.ts +0 -68
  174. package/src/__tests__/ts-to-expression.test.ts +0 -462
  175. package/src/__tests__/type-generator.test.ts +0 -201
  176. package/src/__tests__/uber-validation.test.ts +0 -502
  177. package/src/action-compiler.ts +0 -361
  178. package/src/babel/emitters/experience-transform.ts +0 -199
  179. package/src/babel/emitters/ir-to-tsx-emitter.ts +0 -110
  180. package/src/babel/emitters/pure-form-emitter.ts +0 -1023
  181. package/src/babel/emitters/runtime-glue-emitter.ts +0 -39
  182. package/src/babel/extractors/change-extractor.ts +0 -199
  183. package/src/babel/extractors/component-extractor.ts +0 -907
  184. package/src/babel/extractors/computed-extractor.ts +0 -262
  185. package/src/babel/extractors/context-extractor.ts +0 -277
  186. package/src/babel/extractors/during-extractor.ts +0 -295
  187. package/src/babel/extractors/effect-extractor.ts +0 -340
  188. package/src/babel/extractors/event-extractor.ts +0 -235
  189. package/src/babel/extractors/grammar-island-extractor.ts +0 -302
  190. package/src/babel/extractors/model-extractor.ts +0 -1018
  191. package/src/babel/extractors/router-extractor.ts +0 -303
  192. package/src/babel/extractors/server-action-extractor.ts +0 -173
  193. package/src/babel/extractors/server-action-hook-extractor.ts +0 -72
  194. package/src/babel/extractors/server-state-extractor.ts +0 -88
  195. package/src/babel/extractors/state-extractor.ts +0 -214
  196. package/src/babel/extractors/transition-effect-extractor.ts +0 -176
  197. package/src/babel/extractors/transition-extractor.ts +0 -143
  198. package/src/babel/index.ts +0 -24
  199. package/src/babel/transpilers/ts-to-expression.ts +0 -674
  200. package/src/babel/visitor.ts +0 -807
  201. package/src/cli/auth.ts +0 -255
  202. package/src/cli/build.ts +0 -288
  203. package/src/cli/deploy.ts +0 -206
  204. package/src/cli/index.ts +0 -328
  205. package/src/cli/installer.ts +0 -261
  206. package/src/cli/lock-file.ts +0 -94
  207. package/src/cli/mmrc.ts +0 -22
  208. package/src/cli/pull.ts +0 -172
  209. package/src/cli/registry-client.ts +0 -175
  210. package/src/cli/test.ts +0 -397
  211. package/src/cli/type-generator.ts +0 -243
  212. package/src/codemod/__tests__/forward.test.ts +0 -239
  213. package/src/codemod/__tests__/reverse.test.ts +0 -145
  214. package/src/codemod/__tests__/round-trip.test.ts +0 -137
  215. package/src/codemod/annotation.ts +0 -97
  216. package/src/codemod/classify.ts +0 -197
  217. package/src/codemod/cli.ts +0 -207
  218. package/src/codemod/control-flow.ts +0 -409
  219. package/src/codemod/forward.ts +0 -244
  220. package/src/codemod/import-manager.ts +0 -171
  221. package/src/codemod/index.ts +0 -120
  222. package/src/codemod/reverse.ts +0 -197
  223. package/src/codemod/rules.ts +0 -174
  224. package/src/codemod/state-transform.ts +0 -126
  225. package/src/decompiler/ast-builder.ts +0 -538
  226. package/src/decompiler/config-generator.ts +0 -151
  227. package/src/decompiler/index.ts +0 -315
  228. package/src/decompiler/project-decompiler.ts +0 -1776
  229. package/src/decompiler/project.ts +0 -862
  230. package/src/decompiler/split-strategy.ts +0 -140
  231. package/src/decompiler/state-emitter.ts +0 -1053
  232. package/src/decompiler/sx-emitter.ts +0 -318
  233. package/src/decompiler/workspace-hydrator.ts +0 -189
  234. package/src/dev-server.ts +0 -238
  235. package/src/envelope/fs-tree.ts +0 -217
  236. package/src/envelope/source-envelope.ts +0 -264
  237. package/src/envelope.ts +0 -315
  238. package/src/incremental-compiler.ts +0 -401
  239. package/src/index.ts +0 -99
  240. package/src/model-compiler.ts +0 -277
  241. package/src/project-compiler.ts +0 -1629
  242. package/src/route-extractor.ts +0 -333
  243. package/src/testing/index.ts +0 -32
  244. package/src/testing/snapshot.ts +0 -252
  245. package/src/testing/test-utils.ts +0 -226
  246. package/src/types.ts +0 -68
  247. package/src/vite/index.ts +0 -288
  248. package/test-compile.mjs +0 -142
  249. package/tsconfig.json +0 -25
  250. package/tsup.config.ts +0 -23
  251. package/vitest.config.ts +0 -9
@@ -0,0 +1,109 @@
1
+ import {
2
+ decompileProjectEnhanced
3
+ } from "./chunk-FKRO52XH.mjs";
4
+ import "./chunk-CIESM3BP.mjs";
5
+
6
+ // src/cli/pull.ts
7
+ import { mkdirSync, writeFileSync } from "fs";
8
+ import { join, dirname } from "path";
9
+ async function pull(options) {
10
+ const { slug, apiUrl, token } = options;
11
+ const outDir = options.outDir ?? slug;
12
+ console.log(`[mmrc pull] Fetching "${slug}" from ${apiUrl}...`);
13
+ const ir = await fetchDefinition(apiUrl, token, slug);
14
+ if (!ir) {
15
+ throw new Error(`Definition "${slug}" not found`);
16
+ }
17
+ console.log(` Found: ${ir.name || ir.slug} (${ir.category || "workflow"}, v${ir.version || "1.0.0"})`);
18
+ console.log(` Fields: ${ir.fields?.length ?? 0}, States: ${ir.states?.length ?? 0}, Transitions: ${ir.transitions?.length ?? 0}`);
19
+ const result = decompileProjectEnhanced(ir);
20
+ mkdirSync(outDir, { recursive: true });
21
+ const filesWritten = [];
22
+ for (const file of result.files) {
23
+ const filePath = join(outDir, file.path);
24
+ mkdirSync(dirname(filePath), { recursive: true });
25
+ writeFileSync(filePath, file.content, "utf-8");
26
+ filesWritten.push(file.path);
27
+ console.log(` + ${file.path}`);
28
+ }
29
+ console.log(`
30
+ [mmrc pull] Scaffolded ${filesWritten.length} files in ${outDir}/`);
31
+ console.log(` Entry: ${result.entryFile}`);
32
+ console.log(`
33
+ Next steps:`);
34
+ console.log(` cd ${outDir}`);
35
+ console.log(` mmrc dev --src .`);
36
+ console.log(` # Edit files, then deploy back:`);
37
+ console.log(` mmrc deploy --src . --api-url ${apiUrl} --token <token>`);
38
+ return { slug, filesWritten, outDir };
39
+ }
40
+ async function fetchDefinition(apiUrl, token, slug) {
41
+ const bySlug = await tryFetch(`${apiUrl}/workflow/definitions?slug=${encodeURIComponent(slug)}`, token);
42
+ if (bySlug) return bySlug;
43
+ const bySearch = await tryFetch(`${apiUrl}/workflow/catalog/search?q=${encodeURIComponent(slug)}`, token);
44
+ if (bySearch) return bySearch;
45
+ const modulesRes = await fetch(`${apiUrl}/modules`, {
46
+ headers: { Authorization: `Bearer ${token}` }
47
+ });
48
+ if (modulesRes.ok) {
49
+ const modules = await modulesRes.json();
50
+ const mod = modules.find((m) => m.module_id === slug || m.name?.toLowerCase() === slug.toLowerCase());
51
+ if (mod) {
52
+ const fullRes = await fetch(`${apiUrl}/workflow/definitions/${mod.module_id}`, {
53
+ headers: { Authorization: `Bearer ${token}` }
54
+ });
55
+ if (fullRes.ok) {
56
+ return normalizeApiResponse(await fullRes.json());
57
+ }
58
+ }
59
+ }
60
+ return null;
61
+ }
62
+ async function tryFetch(url, token) {
63
+ try {
64
+ const res = await fetch(url, {
65
+ headers: { Authorization: `Bearer ${token}` }
66
+ });
67
+ if (!res.ok) return null;
68
+ const data = await res.json();
69
+ if (Array.isArray(data)) {
70
+ if (data.length === 0) return null;
71
+ return normalizeApiResponse(data[0]);
72
+ }
73
+ const items = data.items ?? data.data;
74
+ if (items && Array.isArray(items)) {
75
+ if (items.length === 0) return null;
76
+ return normalizeApiResponse(items[0]);
77
+ }
78
+ return normalizeApiResponse(data);
79
+ } catch {
80
+ return null;
81
+ }
82
+ }
83
+ function normalizeApiResponse(def) {
84
+ const ir = {
85
+ slug: def.slug,
86
+ name: def.name,
87
+ version: def.version || "1.0.0",
88
+ description: def.description || "",
89
+ category: def.category || "workflow",
90
+ fields: def.fields || [],
91
+ states: def.states || [],
92
+ transitions: def.transitions || [],
93
+ roles: def.roles || [],
94
+ on_event: def.on_event || [],
95
+ metadata: {
96
+ ...def.metadata || {}
97
+ }
98
+ };
99
+ const experience = def.view || def.experience || def.metadata?.experience;
100
+ if (experience) {
101
+ ir.experience = experience;
102
+ ir.metadata.experience = experience;
103
+ ir.view = experience;
104
+ }
105
+ return ir;
106
+ }
107
+ export {
108
+ pull
109
+ };
@@ -663,6 +663,8 @@ var TranspileContext = class {
663
663
  this.localFieldMap = options.localFieldMap ?? /* @__PURE__ */ new Map();
664
664
  this.derivedVarMap = options.derivedVarMap ?? /* @__PURE__ */ new Map();
665
665
  this.setterToFieldMap = options.setterToFieldMap ?? /* @__PURE__ */ new Map();
666
+ this.parameterMap = options.parameterMap ?? /* @__PURE__ */ new Map();
667
+ this.allMutable = options.allMutable ?? false;
666
668
  }
667
669
  /**
668
670
  * Emit an opaque JS fallback, marking the result as impure.
@@ -684,6 +686,8 @@ var TranspileContext = class {
684
686
  if (snakeName) return `$local.${snakeName}`;
685
687
  const derivedInit = this.derivedVarMap.get(node.name);
686
688
  if (derivedInit) return `(${this.visit(derivedInit)})`;
689
+ const paramField = this.parameterMap.get(node.name);
690
+ if (paramField) return paramField;
687
691
  if (node.name === "undefined") return "null";
688
692
  if (node.name === "NaN") return "null";
689
693
  if (node.name === "Infinity") return "null";
@@ -731,6 +735,9 @@ var TranspileContext = class {
731
735
  if (t5.isNewExpression(node)) {
732
736
  return this.visitNew(node);
733
737
  }
738
+ if (t5.isAssignmentExpression(node) && node.operator === "=" && t5.isIdentifier(node.left)) {
739
+ return `${node.left.name} = ${this.visit(node.right)}`;
740
+ }
734
741
  return this.opaque(fallbackGenerate(node));
735
742
  }
736
743
  // ---------------------------------------------------------------------------
@@ -931,6 +938,11 @@ var TranspileContext = class {
931
938
  return this.visitArrayHigherOrder("some", obj, args);
932
939
  case "every":
933
940
  return this.visitArrayHigherOrder("every", obj, args);
941
+ // --- Array push: arr.push(item) → arr = push(arr, item) ---
942
+ case "push": {
943
+ const [item] = this.visitArgsList(args);
944
+ return `${obj} = push(${obj}, ${item})`;
945
+ }
934
946
  // --- Array mutation-free methods ---
935
947
  case "reverse":
936
948
  return `reverse(${obj})`;
@@ -2766,6 +2778,71 @@ function modelStateTypeToIR(type) {
2766
2778
  if (type === "final") return "END";
2767
2779
  return "REGULAR";
2768
2780
  }
2781
+ function parseActionArray(raw, actionCounter) {
2782
+ if (!Array.isArray(raw)) return [];
2783
+ const actions = [];
2784
+ for (const item of raw) {
2785
+ if (typeof item !== "object" || item === null) continue;
2786
+ const a = item;
2787
+ actions.push({
2788
+ id: a.id ? String(a.id) : `auto_${++actionCounter.value}`,
2789
+ type: String(a.type || a.action_type || "unknown"),
2790
+ mode: a.mode || "auto",
2791
+ config: a.config && typeof a.config === "object" ? a.config : {},
2792
+ ...a.condition ? { condition: String(a.condition) } : {}
2793
+ });
2794
+ }
2795
+ return actions;
2796
+ }
2797
+ function parseDuringArray(raw, actionCounter) {
2798
+ if (!Array.isArray(raw)) return [];
2799
+ const result = [];
2800
+ for (const item of raw) {
2801
+ if (typeof item !== "object" || item === null) continue;
2802
+ const d = item;
2803
+ result.push({
2804
+ id: d.id ? String(d.id) : `during_${++actionCounter.value}`,
2805
+ type: d.type || "interval",
2806
+ ...d.interval_ms != null ? { interval_ms: Number(d.interval_ms) } : {},
2807
+ ...d.cron ? { cron: String(d.cron) } : {},
2808
+ ...d.delay_ms != null ? { delay_ms: Number(d.delay_ms) } : {},
2809
+ ...d.condition ? { condition: String(d.condition) } : {},
2810
+ actions: parseActionArray(d.actions, actionCounter)
2811
+ });
2812
+ }
2813
+ return result;
2814
+ }
2815
+ function parseOnEventArray(raw, actionCounter) {
2816
+ if (!Array.isArray(raw)) return [];
2817
+ const result = [];
2818
+ for (const item of raw) {
2819
+ if (typeof item !== "object" || item === null) continue;
2820
+ const e = item;
2821
+ const actions = [];
2822
+ if (Array.isArray(e.actions)) {
2823
+ for (const a of e.actions) {
2824
+ if (typeof a !== "object" || a === null) continue;
2825
+ const act = a;
2826
+ actions.push({
2827
+ type: act.type || "set_field",
2828
+ ...act.field ? { field: String(act.field) } : {},
2829
+ ...act.expression ? { expression: String(act.expression) } : {},
2830
+ ...act.key ? { key: String(act.key) } : {},
2831
+ ...act.message ? { message: String(act.message) } : {},
2832
+ ...act.config && typeof act.config === "object" ? { config: act.config } : {},
2833
+ ...act.conditions && Array.isArray(act.conditions) ? { conditions: act.conditions.map(String) } : {}
2834
+ });
2835
+ }
2836
+ }
2837
+ result.push({
2838
+ match: String(e.match || ""),
2839
+ ...e.description ? { description: String(e.description) } : {},
2840
+ ...e.conditions && Array.isArray(e.conditions) ? { conditions: e.conditions.map(String) } : {},
2841
+ actions
2842
+ });
2843
+ }
2844
+ return result;
2845
+ }
2769
2846
  function extractDefineModelCall(programPath, compilerState, actionCounter) {
2770
2847
  for (const node of programPath.node.body) {
2771
2848
  if (!t11.isExportDefaultDeclaration(node)) continue;
@@ -2805,17 +2882,27 @@ function extractDefineModelCall(programPath, compilerState, actionCounter) {
2805
2882
  const statesObj = config.states;
2806
2883
  for (const [name, stateConfig] of Object.entries(statesObj)) {
2807
2884
  const stateType = modelStateTypeToIR(stateConfig.type);
2885
+ const on_enter = parseActionArray(stateConfig.on_enter, actionCounter);
2886
+ const on_exit = parseActionArray(stateConfig.on_exit, actionCounter);
2887
+ const during = parseDuringArray(stateConfig.during, actionCounter);
2888
+ const on_event = parseOnEventArray(stateConfig.on_event, actionCounter);
2808
2889
  if (!compilerState.states.has(name)) {
2809
2890
  compilerState.states.set(name, {
2810
2891
  name,
2811
2892
  type: stateType,
2812
2893
  description: stateConfig.description,
2813
- on_enter: [],
2814
- during: [],
2815
- on_exit: []
2894
+ on_enter,
2895
+ during,
2896
+ on_exit,
2897
+ ...on_event.length > 0 ? { on_event } : {}
2816
2898
  });
2817
2899
  } else {
2818
- compilerState.states.get(name).type = stateType;
2900
+ const existing = compilerState.states.get(name);
2901
+ existing.type = stateType;
2902
+ if (on_enter.length > 0) existing.on_enter = on_enter;
2903
+ if (on_exit.length > 0) existing.on_exit = on_exit;
2904
+ if (during.length > 0) existing.during = during;
2905
+ if (on_event.length > 0) existing.on_event = on_event;
2819
2906
  }
2820
2907
  }
2821
2908
  }
@@ -2853,13 +2940,21 @@ function extractDefineModelCall(programPath, compilerState, actionCounter) {
2853
2940
  if (transConfig.guard) {
2854
2941
  conditions.push(parseGuardExpression(String(transConfig.guard)));
2855
2942
  }
2943
+ if (transConfig.conditions && Array.isArray(transConfig.conditions)) {
2944
+ for (const cond of transConfig.conditions) {
2945
+ if (typeof cond === "object" && cond !== null) {
2946
+ conditions.push(cond);
2947
+ }
2948
+ }
2949
+ }
2950
+ const actions = parseActionArray(transConfig.actions, actionCounter);
2856
2951
  compilerState.transitions.push({
2857
2952
  name,
2858
2953
  from,
2859
2954
  to,
2860
2955
  description: transConfig.description,
2861
2956
  conditions: conditions.length > 0 ? conditions : void 0,
2862
- actions: [],
2957
+ actions,
2863
2958
  roles: transConfig.roles,
2864
2959
  auto: transConfig.auto,
2865
2960
  required_fields: transConfig.required_fields
@@ -3785,6 +3880,18 @@ function emitIR(extracted) {
3785
3880
  });
3786
3881
  stateNames.add(transition.to);
3787
3882
  }
3883
+ for (const from of transition.from) {
3884
+ if (from && !stateNames.has(from)) {
3885
+ stateArray.push({
3886
+ name: from,
3887
+ type: "REGULAR",
3888
+ on_enter: [],
3889
+ during: [],
3890
+ on_exit: []
3891
+ });
3892
+ stateNames.add(from);
3893
+ }
3894
+ }
3788
3895
  }
3789
3896
  const fieldNames = new Set(fields.map((f) => f.name));
3790
3897
  let normalizedView;
@@ -4737,7 +4844,7 @@ function createVisitor(options = {}) {
4737
4844
  }
4738
4845
  }
4739
4846
  if (mode !== "strict") return;
4740
- if (source.startsWith("@mindmatrix/") || source === "react" || source.startsWith("react/") || source.startsWith(".") || source.startsWith("/")) {
4847
+ if (source.startsWith("@mindmatrix/") || source.startsWith("@mmapp/") || source === "react" || source.startsWith("react/") || source.startsWith(".") || source.startsWith("/")) {
4741
4848
  return;
4742
4849
  }
4743
4850
  const error = {
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  babelPlugin
3
- } from "../chunk-HLRGCCIL.mjs";
3
+ } from "../chunk-FYT47UBU.mjs";
4
4
  import {
5
5
  __require
6
- } from "../chunk-Y6FXYEAI.mjs";
6
+ } from "../chunk-CIESM3BP.mjs";
7
7
 
8
8
  // src/testing/test-utils.ts
9
9
  import { transformSync } from "@babel/core";
@@ -652,6 +652,8 @@ var TranspileContext = class {
652
652
  this.localFieldMap = options.localFieldMap ?? /* @__PURE__ */ new Map();
653
653
  this.derivedVarMap = options.derivedVarMap ?? /* @__PURE__ */ new Map();
654
654
  this.setterToFieldMap = options.setterToFieldMap ?? /* @__PURE__ */ new Map();
655
+ this.parameterMap = options.parameterMap ?? /* @__PURE__ */ new Map();
656
+ this.allMutable = options.allMutable ?? false;
655
657
  }
656
658
  /**
657
659
  * Emit an opaque JS fallback, marking the result as impure.
@@ -673,6 +675,8 @@ var TranspileContext = class {
673
675
  if (snakeName) return `$local.${snakeName}`;
674
676
  const derivedInit = this.derivedVarMap.get(node.name);
675
677
  if (derivedInit) return `(${this.visit(derivedInit)})`;
678
+ const paramField = this.parameterMap.get(node.name);
679
+ if (paramField) return paramField;
676
680
  if (node.name === "undefined") return "null";
677
681
  if (node.name === "NaN") return "null";
678
682
  if (node.name === "Infinity") return "null";
@@ -720,6 +724,9 @@ var TranspileContext = class {
720
724
  if (t5.isNewExpression(node)) {
721
725
  return this.visitNew(node);
722
726
  }
727
+ if (t5.isAssignmentExpression(node) && node.operator === "=" && t5.isIdentifier(node.left)) {
728
+ return `${node.left.name} = ${this.visit(node.right)}`;
729
+ }
723
730
  return this.opaque(fallbackGenerate(node));
724
731
  }
725
732
  // ---------------------------------------------------------------------------
@@ -920,6 +927,11 @@ var TranspileContext = class {
920
927
  return this.visitArrayHigherOrder("some", obj, args);
921
928
  case "every":
922
929
  return this.visitArrayHigherOrder("every", obj, args);
930
+ // --- Array push: arr.push(item) → arr = push(arr, item) ---
931
+ case "push": {
932
+ const [item] = this.visitArgsList(args);
933
+ return `${obj} = push(${obj}, ${item})`;
934
+ }
923
935
  // --- Array mutation-free methods ---
924
936
  case "reverse":
925
937
  return `reverse(${obj})`;
@@ -2755,6 +2767,71 @@ function modelStateTypeToIR(type) {
2755
2767
  if (type === "final") return "END";
2756
2768
  return "REGULAR";
2757
2769
  }
2770
+ function parseActionArray(raw, actionCounter) {
2771
+ if (!Array.isArray(raw)) return [];
2772
+ const actions = [];
2773
+ for (const item of raw) {
2774
+ if (typeof item !== "object" || item === null) continue;
2775
+ const a = item;
2776
+ actions.push({
2777
+ id: a.id ? String(a.id) : `auto_${++actionCounter.value}`,
2778
+ type: String(a.type || a.action_type || "unknown"),
2779
+ mode: a.mode || "auto",
2780
+ config: a.config && typeof a.config === "object" ? a.config : {},
2781
+ ...a.condition ? { condition: String(a.condition) } : {}
2782
+ });
2783
+ }
2784
+ return actions;
2785
+ }
2786
+ function parseDuringArray(raw, actionCounter) {
2787
+ if (!Array.isArray(raw)) return [];
2788
+ const result = [];
2789
+ for (const item of raw) {
2790
+ if (typeof item !== "object" || item === null) continue;
2791
+ const d = item;
2792
+ result.push({
2793
+ id: d.id ? String(d.id) : `during_${++actionCounter.value}`,
2794
+ type: d.type || "interval",
2795
+ ...d.interval_ms != null ? { interval_ms: Number(d.interval_ms) } : {},
2796
+ ...d.cron ? { cron: String(d.cron) } : {},
2797
+ ...d.delay_ms != null ? { delay_ms: Number(d.delay_ms) } : {},
2798
+ ...d.condition ? { condition: String(d.condition) } : {},
2799
+ actions: parseActionArray(d.actions, actionCounter)
2800
+ });
2801
+ }
2802
+ return result;
2803
+ }
2804
+ function parseOnEventArray(raw, actionCounter) {
2805
+ if (!Array.isArray(raw)) return [];
2806
+ const result = [];
2807
+ for (const item of raw) {
2808
+ if (typeof item !== "object" || item === null) continue;
2809
+ const e = item;
2810
+ const actions = [];
2811
+ if (Array.isArray(e.actions)) {
2812
+ for (const a of e.actions) {
2813
+ if (typeof a !== "object" || a === null) continue;
2814
+ const act = a;
2815
+ actions.push({
2816
+ type: act.type || "set_field",
2817
+ ...act.field ? { field: String(act.field) } : {},
2818
+ ...act.expression ? { expression: String(act.expression) } : {},
2819
+ ...act.key ? { key: String(act.key) } : {},
2820
+ ...act.message ? { message: String(act.message) } : {},
2821
+ ...act.config && typeof act.config === "object" ? { config: act.config } : {},
2822
+ ...act.conditions && Array.isArray(act.conditions) ? { conditions: act.conditions.map(String) } : {}
2823
+ });
2824
+ }
2825
+ }
2826
+ result.push({
2827
+ match: String(e.match || ""),
2828
+ ...e.description ? { description: String(e.description) } : {},
2829
+ ...e.conditions && Array.isArray(e.conditions) ? { conditions: e.conditions.map(String) } : {},
2830
+ actions
2831
+ });
2832
+ }
2833
+ return result;
2834
+ }
2758
2835
  function extractDefineModelCall(programPath, compilerState, actionCounter) {
2759
2836
  for (const node of programPath.node.body) {
2760
2837
  if (!t11.isExportDefaultDeclaration(node)) continue;
@@ -2794,17 +2871,27 @@ function extractDefineModelCall(programPath, compilerState, actionCounter) {
2794
2871
  const statesObj = config.states;
2795
2872
  for (const [name, stateConfig] of Object.entries(statesObj)) {
2796
2873
  const stateType = modelStateTypeToIR(stateConfig.type);
2874
+ const on_enter = parseActionArray(stateConfig.on_enter, actionCounter);
2875
+ const on_exit = parseActionArray(stateConfig.on_exit, actionCounter);
2876
+ const during = parseDuringArray(stateConfig.during, actionCounter);
2877
+ const on_event = parseOnEventArray(stateConfig.on_event, actionCounter);
2797
2878
  if (!compilerState.states.has(name)) {
2798
2879
  compilerState.states.set(name, {
2799
2880
  name,
2800
2881
  type: stateType,
2801
2882
  description: stateConfig.description,
2802
- on_enter: [],
2803
- during: [],
2804
- on_exit: []
2883
+ on_enter,
2884
+ during,
2885
+ on_exit,
2886
+ ...on_event.length > 0 ? { on_event } : {}
2805
2887
  });
2806
2888
  } else {
2807
- compilerState.states.get(name).type = stateType;
2889
+ const existing = compilerState.states.get(name);
2890
+ existing.type = stateType;
2891
+ if (on_enter.length > 0) existing.on_enter = on_enter;
2892
+ if (on_exit.length > 0) existing.on_exit = on_exit;
2893
+ if (during.length > 0) existing.during = during;
2894
+ if (on_event.length > 0) existing.on_event = on_event;
2808
2895
  }
2809
2896
  }
2810
2897
  }
@@ -2842,13 +2929,21 @@ function extractDefineModelCall(programPath, compilerState, actionCounter) {
2842
2929
  if (transConfig.guard) {
2843
2930
  conditions.push(parseGuardExpression(String(transConfig.guard)));
2844
2931
  }
2932
+ if (transConfig.conditions && Array.isArray(transConfig.conditions)) {
2933
+ for (const cond of transConfig.conditions) {
2934
+ if (typeof cond === "object" && cond !== null) {
2935
+ conditions.push(cond);
2936
+ }
2937
+ }
2938
+ }
2939
+ const actions = parseActionArray(transConfig.actions, actionCounter);
2845
2940
  compilerState.transitions.push({
2846
2941
  name,
2847
2942
  from,
2848
2943
  to,
2849
2944
  description: transConfig.description,
2850
2945
  conditions: conditions.length > 0 ? conditions : void 0,
2851
- actions: [],
2946
+ actions,
2852
2947
  roles: transConfig.roles,
2853
2948
  auto: transConfig.auto,
2854
2949
  required_fields: transConfig.required_fields
@@ -3774,6 +3869,18 @@ function emitIR(extracted) {
3774
3869
  });
3775
3870
  stateNames.add(transition.to);
3776
3871
  }
3872
+ for (const from of transition.from) {
3873
+ if (from && !stateNames.has(from)) {
3874
+ stateArray.push({
3875
+ name: from,
3876
+ type: "REGULAR",
3877
+ on_enter: [],
3878
+ during: [],
3879
+ on_exit: []
3880
+ });
3881
+ stateNames.add(from);
3882
+ }
3883
+ }
3777
3884
  }
3778
3885
  const fieldNames = new Set(fields.map((f) => f.name));
3779
3886
  let normalizedView;
@@ -4726,7 +4833,7 @@ function createVisitor(options = {}) {
4726
4833
  }
4727
4834
  }
4728
4835
  if (mode !== "strict") return;
4729
- if (source.startsWith("@mindmatrix/") || source === "react" || source.startsWith("react/") || source.startsWith(".") || source.startsWith("/")) {
4836
+ if (source.startsWith("@mindmatrix/") || source.startsWith("@mmapp/") || source === "react" || source.startsWith("react/") || source.startsWith(".") || source.startsWith("/")) {
4730
4837
  return;
4731
4838
  }
4732
4839
  const error = {
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  mindmatrixReact
3
- } from "../chunk-46YKSHQR.mjs";
4
- import "../chunk-HLRGCCIL.mjs";
5
- import "../chunk-Y6FXYEAI.mjs";
3
+ } from "../chunk-72QWL54I.mjs";
4
+ import "../chunk-FYT47UBU.mjs";
5
+ import "../chunk-CIESM3BP.mjs";
6
6
  export {
7
7
  mindmatrixReact
8
8
  };
@@ -40,19 +40,19 @@ export default function FleetManagement() {
40
40
 
41
41
  return (
42
42
  <Show when={isAdmin} fallback={<Text>Access denied. Admin role required.</Text>}>
43
- <Stack gap=lg>
44
- <Row justify=between align=center>
43
+ <Stack gap="lg">
44
+ <Row justify="between" align="center">
45
45
  <Heading level={2}>Fleet Management</Heading>
46
46
  <Button onClick={() => setShowAddForm(true)}>Add Vehicle</Button>
47
47
  </Row>
48
48
 
49
- <Row gap=md>
50
- <Badge color=green>Active: {statusCounts.active}</Badge>
51
- <Badge color=yellow>Maintenance: {statusCounts.maintenance}</Badge>
52
- <Badge color=gray>Retired: {statusCounts.retired}</Badge>
49
+ <Row gap="md">
50
+ <Badge color="green">Active: {statusCounts.active}</Badge>
51
+ <Badge color="yellow">Maintenance: {statusCounts.maintenance}</Badge>
52
+ <Badge color="gray">Retired: {statusCounts.retired}</Badge>
53
53
  </Row>
54
54
 
55
- <Row gap=sm>
55
+ <Row gap="sm">
56
56
  {(['all', 'sedan', 'suv', 'van', 'luxury'] as const).map((t) => (
57
57
  <Button key={t} variant={filterType === t ? 'primary' : 'ghost'} onClick={() => setFilterType(t)}>
58
58
  {t.charAt(0).toUpperCase() + t.slice(1)}
@@ -62,16 +62,16 @@ export default function FleetManagement() {
62
62
 
63
63
  <Show when={showAddForm}>
64
64
  <Card>
65
- <Stack gap=sm>
66
- <Input label=License Plate value={newPlate} onChange={setNewPlate} />
67
- <Row gap=sm>
65
+ <Stack gap="sm">
66
+ <Input label="License Plate" value={newPlate} onChange={setNewPlate} />
67
+ <Row gap="sm">
68
68
  {(['sedan', 'suv', 'van', 'luxury'] as const).map((t) => (
69
69
  <Button key={t} variant={newType === t ? 'primary' : 'ghost'} onClick={() => setNewType(t)}>{t}</Button>
70
70
  ))}
71
71
  </Row>
72
- <Row gap=sm>
72
+ <Row gap="sm">
73
73
  <Button onClick={handleAddVehicle}>Save</Button>
74
- <Button variant=ghost onClick={() => setShowAddForm(false)}>Cancel</Button>
74
+ <Button variant="ghost" onClick={() => setShowAddForm(false)}>Cancel</Button>
75
75
  </Row>
76
76
  </Stack>
77
77
  </Card>
@@ -80,15 +80,15 @@ export default function FleetManagement() {
80
80
  <Each items={filteredVehicles}>
81
81
  {(vehicle: Vehicle) => (
82
82
  <Card key={vehicle.id}>
83
- <Row justify=between align=center>
84
- <Stack gap=xs>
85
- <Text weight=bold>{vehicle.plate} — {vehicle.type}</Text>
86
- <Text size=sm color=muted>{vehicle.assignedDriver?.name ?? 'Unassigned'}</Text>
83
+ <Row justify="between" align="center">
84
+ <Stack gap="xs">
85
+ <Text weight="bold">{vehicle.plate} — {vehicle.type}</Text>
86
+ <Text size="sm" color="muted">{vehicle.assignedDriver?.name ?? 'Unassigned'}</Text>
87
87
  </Stack>
88
- <Row gap=sm align=center>
88
+ <Row gap="sm" align="center">
89
89
  <Badge color={statusColor(vehicle.status)}>{vehicle.status}</Badge>
90
- <Button size=sm onClick={() => assignDriver({ vehicleId: vehicle.id })}>Assign</Button>
91
- <Button size=sm variant=ghost onClick={() => updateStatus({ vehicleId: vehicle.id, status: 'maintenance' })}>
90
+ <Button size="sm" onClick={() => assignDriver({ vehicleId: vehicle.id })}>Assign</Button>
91
+ <Button size="sm" variant="ghost" onClick={() => updateStatus({ vehicleId: vehicle.id, status: 'maintenance' })}>
92
92
  Service
93
93
  </Button>
94
94
  </Row>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mmapp/react-compiler",
3
- "version": "0.1.0-alpha.1",
3
+ "version": "0.1.0-alpha.3",
4
4
  "description": "Babel plugin + Vite integration for compiling React workflows to Pure Form IR",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -55,7 +55,8 @@
55
55
  "seed:chat:compile": "node seed-blueprint-chat.mjs --compile-only",
56
56
  "seed:chat:seed": "node seed-blueprint-chat.mjs --seed-only",
57
57
  "test": "vitest run",
58
- "test:watch": "vitest"
58
+ "test:watch": "vitest",
59
+ "publish:alpha": "cd ../.. && ./scripts/publish-npm.sh"
59
60
  },
60
61
  "dependencies": {
61
62
  "@babel/core": "^7.24.0",
@@ -66,7 +67,7 @@
66
67
  "@babel/traverse": "^7.24.0",
67
68
  "@babel/types": "^7.24.0",
68
69
  "glob": "^10.3.10",
69
- "@mmapp/player-core": "^0.1.0-alpha.1"
70
+ "@mmapp/player-core": "^0.1.0-alpha.3"
70
71
  },
71
72
  "peerDependencies": {
72
73
  "vite": ">=5.0.0"