@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
package/dist/cli/index.js CHANGED
@@ -29,6 +29,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
29
29
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
30
30
  mod
31
31
  ));
32
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
32
33
 
33
34
  // src/babel/extractors/state-extractor.ts
34
35
  function typeNameToSlug(name) {
@@ -445,25 +446,25 @@ function inferTransitionStates(transitions, states) {
445
446
  const stateArray = Array.from(states.values());
446
447
  const startStates = stateArray.filter((s) => s.type === "START");
447
448
  const regularStates = stateArray.filter((s) => s.type === "REGULAR");
448
- const needsInference = transitions.filter((t22) => t22.from.length === 0 || !t22.to);
449
+ const needsInference = transitions.filter((t23) => t23.from.length === 0 || !t23.to);
449
450
  if (needsInference.length === 0) return;
450
451
  if (startStates.length === 1 && regularStates.length > 0) {
451
- needsInference.forEach((t22, idx) => {
452
- if (t22.from.length === 0) {
453
- t22.from = [startStates[0].name];
452
+ needsInference.forEach((t23, idx) => {
453
+ if (t23.from.length === 0) {
454
+ t23.from = [startStates[0].name];
454
455
  }
455
- if (!t22.to) {
456
- t22.to = regularStates[idx % regularStates.length]?.name || startStates[0].name;
456
+ if (!t23.to) {
457
+ t23.to = regularStates[idx % regularStates.length]?.name || startStates[0].name;
457
458
  }
458
459
  });
459
460
  } else {
460
461
  const allStateNames = stateArray.map((s) => s.name);
461
- needsInference.forEach((t22, idx) => {
462
- if (t22.from.length === 0 && allStateNames.length > 0) {
463
- t22.from = [allStateNames[0]];
462
+ needsInference.forEach((t23, idx) => {
463
+ if (t23.from.length === 0 && allStateNames.length > 0) {
464
+ t23.from = [allStateNames[0]];
464
465
  }
465
- if (!t22.to && allStateNames.length > 1) {
466
- t22.to = allStateNames[Math.min(idx + 1, allStateNames.length - 1)];
466
+ if (!t23.to && allStateNames.length > 1) {
467
+ t23.to = allStateNames[Math.min(idx + 1, allStateNames.length - 1)];
467
468
  }
468
469
  });
469
470
  }
@@ -651,11 +652,128 @@ var init_event_extractor = __esm({
651
652
  });
652
653
 
653
654
  // src/babel/transpilers/ts-to-expression.ts
655
+ var ts_to_expression_exports = {};
656
+ __export(ts_to_expression_exports, {
657
+ transpile: () => transpile,
658
+ transpileBlock: () => transpileBlock,
659
+ transpileExpression: () => transpileExpression
660
+ });
654
661
  function transpileExpression(node, options = {}) {
655
662
  const ctx = new TranspileContext(options);
656
663
  const expr = ctx.visit(node);
657
664
  return { expression: expr, pure: ctx.isPure };
658
665
  }
666
+ function transpile(node, options = {}) {
667
+ return transpileExpression(node, options).expression;
668
+ }
669
+ function transpileBlock(node, options = {}) {
670
+ const ctx = new TranspileContext(options);
671
+ const lines = visitStatements(node.body, ctx);
672
+ return { expression: lines, pure: ctx.isPure };
673
+ }
674
+ function visitStatements(stmts, ctx) {
675
+ return stmts.map((s) => visitStatement(s, ctx)).join("\n");
676
+ }
677
+ function visitStatement(stmt, ctx) {
678
+ if (t5.isVariableDeclaration(stmt)) {
679
+ const keyword = ctx.allMutable || stmt.kind !== "const" ? "let" : "const";
680
+ const decls = stmt.declarations.map((d) => {
681
+ const init2 = d.init ? ctx.visit(d.init) : "null";
682
+ const lhs = declaratorPattern(d.id);
683
+ return `${keyword} ${lhs} = ${init2}`;
684
+ });
685
+ return decls.join(";\n") + ";";
686
+ }
687
+ if (t5.isIfStatement(stmt)) {
688
+ const test2 = ctx.visit(stmt.test);
689
+ const consequent = visitBranchBody(stmt.consequent, ctx);
690
+ if (stmt.alternate) {
691
+ const alternate = visitBranchBody(stmt.alternate, ctx);
692
+ return `if (${test2}) ${consequent} else ${alternate}`;
693
+ }
694
+ return `if (${test2}) ${consequent}`;
695
+ }
696
+ if (t5.isForOfStatement(stmt)) {
697
+ const right = ctx.visit(stmt.right);
698
+ const varName = forOfPattern(stmt.left);
699
+ const body = visitBranchBody(stmt.body, ctx);
700
+ return `for (const ${varName} of ${right}) ${body}`;
701
+ }
702
+ if (t5.isWhileStatement(stmt)) {
703
+ const test2 = ctx.visit(stmt.test);
704
+ const body = visitBranchBody(stmt.body, ctx);
705
+ return `while (${test2}) ${body}`;
706
+ }
707
+ if (t5.isReturnStatement(stmt)) {
708
+ if (!stmt.argument) return "return;";
709
+ return `return ${ctx.visit(stmt.argument)};`;
710
+ }
711
+ if (t5.isExpressionStatement(stmt)) {
712
+ return ctx.visit(stmt.expression) + ";";
713
+ }
714
+ if (t5.isBlockStatement(stmt)) {
715
+ const inner = visitStatements(stmt.body, ctx);
716
+ return `{
717
+ ${indent(inner)}
718
+ }`;
719
+ }
720
+ if (t5.isFunctionDeclaration(stmt) && stmt.id) {
721
+ const name = stmt.id.name;
722
+ const params = stmt.params.map((p) => t5.isIdentifier(p) ? p.name : "_").join(", ");
723
+ const body = visitStatements(stmt.body.body, ctx);
724
+ return `function ${name}(${params}) {
725
+ ${indent(body)}
726
+ }`;
727
+ }
728
+ return ctx.opaque(`[${stmt.type}]`) + ";";
729
+ }
730
+ function visitBranchBody(node, ctx) {
731
+ if (t5.isBlockStatement(node)) {
732
+ const inner2 = visitStatements(node.body, ctx);
733
+ return `{
734
+ ${indent(inner2)}
735
+ }`;
736
+ }
737
+ const inner = visitStatement(node, ctx);
738
+ return `{
739
+ ${indent(inner)}
740
+ }`;
741
+ }
742
+ function declaratorPattern(node) {
743
+ if (t5.isIdentifier(node)) return node.name;
744
+ if (t5.isObjectPattern(node)) {
745
+ const props = node.properties.map((p) => {
746
+ if (t5.isRestElement(p)) {
747
+ return `...${t5.isIdentifier(p.argument) ? p.argument.name : "_"}`;
748
+ }
749
+ if (t5.isObjectProperty(p)) {
750
+ const key = t5.isIdentifier(p.key) ? p.key.name : "_";
751
+ const val = t5.isIdentifier(p.value) ? p.value.name : t5.isAssignmentPattern(p.value) && t5.isIdentifier(p.value.left) ? p.value.left.name : "_";
752
+ return key === val ? key : `${key}: ${val}`;
753
+ }
754
+ return "_";
755
+ });
756
+ return `{ ${props.join(", ")} }`;
757
+ }
758
+ if (t5.isArrayPattern(node)) {
759
+ const elems = node.elements.map(
760
+ (e) => e === null ? "" : t5.isIdentifier(e) ? e.name : "_"
761
+ );
762
+ return `[${elems.join(", ")}]`;
763
+ }
764
+ return "_";
765
+ }
766
+ function forOfPattern(left) {
767
+ if (t5.isVariableDeclaration(left)) {
768
+ const d = left.declarations[0];
769
+ if (d) return declaratorPattern(d.id);
770
+ }
771
+ if (t5.isIdentifier(left)) return left.name;
772
+ return "_";
773
+ }
774
+ function indent(code) {
775
+ return code.split("\n").map((l) => " " + l).join("\n");
776
+ }
659
777
  function fallbackGenerate(node) {
660
778
  if (t5.isIdentifier(node)) return node.name;
661
779
  if (t5.isStringLiteral(node)) return `"${node.value.replace(/"/g, '\\"')}"`;
@@ -675,6 +793,8 @@ var init_ts_to_expression = __esm({
675
793
  this.localFieldMap = options.localFieldMap ?? /* @__PURE__ */ new Map();
676
794
  this.derivedVarMap = options.derivedVarMap ?? /* @__PURE__ */ new Map();
677
795
  this.setterToFieldMap = options.setterToFieldMap ?? /* @__PURE__ */ new Map();
796
+ this.parameterMap = options.parameterMap ?? /* @__PURE__ */ new Map();
797
+ this.allMutable = options.allMutable ?? false;
678
798
  }
679
799
  /**
680
800
  * Emit an opaque JS fallback, marking the result as impure.
@@ -696,6 +816,8 @@ var init_ts_to_expression = __esm({
696
816
  if (snakeName) return `$local.${snakeName}`;
697
817
  const derivedInit = this.derivedVarMap.get(node.name);
698
818
  if (derivedInit) return `(${this.visit(derivedInit)})`;
819
+ const paramField = this.parameterMap.get(node.name);
820
+ if (paramField) return paramField;
699
821
  if (node.name === "undefined") return "null";
700
822
  if (node.name === "NaN") return "null";
701
823
  if (node.name === "Infinity") return "null";
@@ -743,6 +865,9 @@ var init_ts_to_expression = __esm({
743
865
  if (t5.isNewExpression(node)) {
744
866
  return this.visitNew(node);
745
867
  }
868
+ if (t5.isAssignmentExpression(node) && node.operator === "=" && t5.isIdentifier(node.left)) {
869
+ return `${node.left.name} = ${this.visit(node.right)}`;
870
+ }
746
871
  return this.opaque(fallbackGenerate(node));
747
872
  }
748
873
  // ---------------------------------------------------------------------------
@@ -943,6 +1068,11 @@ var init_ts_to_expression = __esm({
943
1068
  return this.visitArrayHigherOrder("some", obj, args2);
944
1069
  case "every":
945
1070
  return this.visitArrayHigherOrder("every", obj, args2);
1071
+ // --- Array push: arr.push(item) → arr = push(arr, item) ---
1072
+ case "push": {
1073
+ const [item] = this.visitArgsList(args2);
1074
+ return `${obj} = push(${obj}, ${item})`;
1075
+ }
946
1076
  // --- Array mutation-free methods ---
947
1077
  case "reverse":
948
1078
  return `reverse(${obj})`;
@@ -2422,7 +2552,7 @@ function resolveType(annotation) {
2422
2552
  }
2423
2553
  if (t11.isTSUnionType(annotation)) {
2424
2554
  const allLiterals = annotation.types.every(
2425
- (t22) => t11.isTSLiteralType(t22) && (t11.isStringLiteral(t22.literal) || t11.isNumericLiteral(t22.literal))
2555
+ (t23) => t11.isTSLiteralType(t23) && (t11.isStringLiteral(t23.literal) || t11.isNumericLiteral(t23.literal))
2426
2556
  );
2427
2557
  if (allLiterals) return "select";
2428
2558
  return "text";
@@ -2796,6 +2926,71 @@ function modelStateTypeToIR(type) {
2796
2926
  if (type === "final") return "END";
2797
2927
  return "REGULAR";
2798
2928
  }
2929
+ function parseActionArray(raw, actionCounter) {
2930
+ if (!Array.isArray(raw)) return [];
2931
+ const actions = [];
2932
+ for (const item of raw) {
2933
+ if (typeof item !== "object" || item === null) continue;
2934
+ const a = item;
2935
+ actions.push({
2936
+ id: a.id ? String(a.id) : `auto_${++actionCounter.value}`,
2937
+ type: String(a.type || a.action_type || "unknown"),
2938
+ mode: a.mode || "auto",
2939
+ config: a.config && typeof a.config === "object" ? a.config : {},
2940
+ ...a.condition ? { condition: String(a.condition) } : {}
2941
+ });
2942
+ }
2943
+ return actions;
2944
+ }
2945
+ function parseDuringArray(raw, actionCounter) {
2946
+ if (!Array.isArray(raw)) return [];
2947
+ const result = [];
2948
+ for (const item of raw) {
2949
+ if (typeof item !== "object" || item === null) continue;
2950
+ const d = item;
2951
+ result.push({
2952
+ id: d.id ? String(d.id) : `during_${++actionCounter.value}`,
2953
+ type: d.type || "interval",
2954
+ ...d.interval_ms != null ? { interval_ms: Number(d.interval_ms) } : {},
2955
+ ...d.cron ? { cron: String(d.cron) } : {},
2956
+ ...d.delay_ms != null ? { delay_ms: Number(d.delay_ms) } : {},
2957
+ ...d.condition ? { condition: String(d.condition) } : {},
2958
+ actions: parseActionArray(d.actions, actionCounter)
2959
+ });
2960
+ }
2961
+ return result;
2962
+ }
2963
+ function parseOnEventArray(raw, actionCounter) {
2964
+ if (!Array.isArray(raw)) return [];
2965
+ const result = [];
2966
+ for (const item of raw) {
2967
+ if (typeof item !== "object" || item === null) continue;
2968
+ const e = item;
2969
+ const actions = [];
2970
+ if (Array.isArray(e.actions)) {
2971
+ for (const a of e.actions) {
2972
+ if (typeof a !== "object" || a === null) continue;
2973
+ const act = a;
2974
+ actions.push({
2975
+ type: act.type || "set_field",
2976
+ ...act.field ? { field: String(act.field) } : {},
2977
+ ...act.expression ? { expression: String(act.expression) } : {},
2978
+ ...act.key ? { key: String(act.key) } : {},
2979
+ ...act.message ? { message: String(act.message) } : {},
2980
+ ...act.config && typeof act.config === "object" ? { config: act.config } : {},
2981
+ ...act.conditions && Array.isArray(act.conditions) ? { conditions: act.conditions.map(String) } : {}
2982
+ });
2983
+ }
2984
+ }
2985
+ result.push({
2986
+ match: String(e.match || ""),
2987
+ ...e.description ? { description: String(e.description) } : {},
2988
+ ...e.conditions && Array.isArray(e.conditions) ? { conditions: e.conditions.map(String) } : {},
2989
+ actions
2990
+ });
2991
+ }
2992
+ return result;
2993
+ }
2799
2994
  function extractDefineModelCall(programPath, compilerState, actionCounter) {
2800
2995
  for (const node of programPath.node.body) {
2801
2996
  if (!t11.isExportDefaultDeclaration(node)) continue;
@@ -2835,17 +3030,27 @@ function extractDefineModelCall(programPath, compilerState, actionCounter) {
2835
3030
  const statesObj = config.states;
2836
3031
  for (const [name, stateConfig] of Object.entries(statesObj)) {
2837
3032
  const stateType = modelStateTypeToIR(stateConfig.type);
3033
+ const on_enter = parseActionArray(stateConfig.on_enter, actionCounter);
3034
+ const on_exit = parseActionArray(stateConfig.on_exit, actionCounter);
3035
+ const during = parseDuringArray(stateConfig.during, actionCounter);
3036
+ const on_event = parseOnEventArray(stateConfig.on_event, actionCounter);
2838
3037
  if (!compilerState.states.has(name)) {
2839
3038
  compilerState.states.set(name, {
2840
3039
  name,
2841
3040
  type: stateType,
2842
3041
  description: stateConfig.description,
2843
- on_enter: [],
2844
- during: [],
2845
- on_exit: []
3042
+ on_enter,
3043
+ during,
3044
+ on_exit,
3045
+ ...on_event.length > 0 ? { on_event } : {}
2846
3046
  });
2847
3047
  } else {
2848
- compilerState.states.get(name).type = stateType;
3048
+ const existing = compilerState.states.get(name);
3049
+ existing.type = stateType;
3050
+ if (on_enter.length > 0) existing.on_enter = on_enter;
3051
+ if (on_exit.length > 0) existing.on_exit = on_exit;
3052
+ if (during.length > 0) existing.during = during;
3053
+ if (on_event.length > 0) existing.on_event = on_event;
2849
3054
  }
2850
3055
  }
2851
3056
  }
@@ -2883,13 +3088,21 @@ function extractDefineModelCall(programPath, compilerState, actionCounter) {
2883
3088
  if (transConfig.guard) {
2884
3089
  conditions.push(parseGuardExpression(String(transConfig.guard)));
2885
3090
  }
3091
+ if (transConfig.conditions && Array.isArray(transConfig.conditions)) {
3092
+ for (const cond of transConfig.conditions) {
3093
+ if (typeof cond === "object" && cond !== null) {
3094
+ conditions.push(cond);
3095
+ }
3096
+ }
3097
+ }
3098
+ const actions = parseActionArray(transConfig.actions, actionCounter);
2886
3099
  compilerState.transitions.push({
2887
3100
  name,
2888
3101
  from,
2889
3102
  to,
2890
3103
  description: transConfig.description,
2891
3104
  conditions: conditions.length > 0 ? conditions : void 0,
2892
- actions: [],
3105
+ actions,
2893
3106
  roles: transConfig.roles,
2894
3107
  auto: transConfig.auto,
2895
3108
  required_fields: transConfig.required_fields
@@ -3569,7 +3782,7 @@ var init_context_extractor = __esm({
3569
3782
 
3570
3783
  // ../player-core/dist/index.mjs
3571
3784
  function normalizeCategory(primary, ...tags) {
3572
- const uniqueTags = [...new Set(tags.filter((t22) => t22 !== primary))];
3785
+ const uniqueTags = [...new Set(tags.filter((t23) => t23 !== primary))];
3573
3786
  uniqueTags.sort();
3574
3787
  return [primary, ...uniqueTags];
3575
3788
  }
@@ -3849,6 +4062,18 @@ function emitIR(extracted) {
3849
4062
  });
3850
4063
  stateNames.add(transition.to);
3851
4064
  }
4065
+ for (const from of transition.from) {
4066
+ if (from && !stateNames.has(from)) {
4067
+ stateArray.push({
4068
+ name: from,
4069
+ type: "REGULAR",
4070
+ on_enter: [],
4071
+ during: [],
4072
+ on_exit: []
4073
+ });
4074
+ stateNames.add(from);
4075
+ }
4076
+ }
3852
4077
  }
3853
4078
  const fieldNames = new Set(fields.map((f) => f.name));
3854
4079
  let normalizedView;
@@ -4278,16 +4503,16 @@ function emitWorkflowDefinition(extracted) {
4278
4503
  ...f.editable_when && { editable_when: f.editable_when },
4279
4504
  ...f.state_home && { state_home: f.state_home }
4280
4505
  }));
4281
- const transitions = ir.transitions.map((t22) => ({
4282
- name: t22.name,
4283
- from: t22.from,
4284
- to: t22.to,
4285
- description: t22.description || "",
4286
- roles: t22.roles || [],
4287
- auto: t22.auto || false,
4288
- conditions: t22.conditions || [],
4289
- actions: (t22.actions || []).map(convertAction),
4290
- required_fields: t22.required_fields || [],
4506
+ const transitions = ir.transitions.map((t23) => ({
4507
+ name: t23.name,
4508
+ from: t23.from,
4509
+ to: t23.to,
4510
+ description: t23.description || "",
4511
+ roles: t23.roles || [],
4512
+ auto: t23.auto || false,
4513
+ conditions: t23.conditions || [],
4514
+ actions: (t23.actions || []).map(convertAction),
4515
+ required_fields: t23.required_fields || [],
4291
4516
  priority: 0
4292
4517
  }));
4293
4518
  const state_data = {};
@@ -4823,7 +5048,7 @@ function createVisitor(options = {}) {
4823
5048
  }
4824
5049
  }
4825
5050
  if (mode !== "strict") return;
4826
- if (source.startsWith("@mindmatrix/") || source === "react" || source.startsWith("react/") || source.startsWith(".") || source.startsWith("/")) {
5051
+ if (source.startsWith("@mindmatrix/") || source.startsWith("@mmapp/") || source === "react" || source.startsWith("react/") || source.startsWith(".") || source.startsWith("/")) {
4827
5052
  return;
4828
5053
  }
4829
5054
  const error = {
@@ -5403,7 +5628,7 @@ function compileModel(filename, source, options = {}) {
5403
5628
  ir,
5404
5629
  interfaceName,
5405
5630
  fieldNames: ir.fields.map((f) => f.name),
5406
- transitionNames: ir.transitions.map((t22) => t22.name),
5631
+ transitionNames: ir.transitions.map((t23) => t23.name),
5407
5632
  stateNames: ir.states.map((s) => s.name),
5408
5633
  hasFieldOptions: Object.keys(rawFieldOptions).length > 0,
5409
5634
  fieldOptions: rawFieldOptions
@@ -5803,6 +6028,520 @@ var init_action_compiler = __esm({
5803
6028
  }
5804
6029
  });
5805
6030
 
6031
+ // src/babel/extractors/action-extractor.ts
6032
+ function extractAction(source, filename) {
6033
+ let ast;
6034
+ try {
6035
+ ast = (0, import_parser.parse)(source, {
6036
+ sourceType: "module",
6037
+ plugins: ["typescript"],
6038
+ strictMode: false
6039
+ });
6040
+ } catch {
6041
+ return null;
6042
+ }
6043
+ const result = findDefaultExportedFunction(ast);
6044
+ if (!result) return null;
6045
+ const { name, params, body, returnTypeAnnotation, isAsync } = result;
6046
+ const slug = toKebabCase(name);
6047
+ const warnings = [];
6048
+ const fields = params.map((p) => paramToField(p));
6049
+ const parameterMap = /* @__PURE__ */ new Map();
6050
+ for (const p of params) {
6051
+ const snakeName = toSnakeCase3(p.name);
6052
+ if (snakeName !== p.name) {
6053
+ parameterMap.set(p.name, snakeName);
6054
+ }
6055
+ }
6056
+ const humanName = name.replace(/([A-Z])/g, " $1").replace(/^./, (s) => s.toUpperCase()).trim();
6057
+ const metadata = {
6058
+ source_file: filename,
6059
+ source_function: name,
6060
+ provenance: {
6061
+ frontend: "react-compiler",
6062
+ source: "action-extractor",
6063
+ compiler_version: "2.0.0"
6064
+ }
6065
+ };
6066
+ if (returnTypeAnnotation) {
6067
+ metadata.return_type = returnTypeAnnotation;
6068
+ }
6069
+ if (isAsync) {
6070
+ const segments = splitAtAwaits(body.body);
6071
+ const hasAwaits = segments.some((s) => s.kind === "await");
6072
+ if (hasAwaits) {
6073
+ const rewritten = rewriteAwaitReferences(segments);
6074
+ const { states: states2, transitions: transitions2, bodyIsPure } = generateMultiStateIR(rewritten, warnings, parameterMap);
6075
+ if (!bodyIsPure) {
6076
+ warnings.push(`Async action '${name}' body contains untranslatable JS \u2014 wrapped in $expr() markers`);
6077
+ }
6078
+ const ir2 = {
6079
+ slug,
6080
+ name: humanName,
6081
+ version: "0.1.0",
6082
+ category: "action",
6083
+ fields,
6084
+ states: states2,
6085
+ transitions: transitions2,
6086
+ roles: [],
6087
+ metadata: { ...metadata, async: true }
6088
+ };
6089
+ return { ir: ir2, bodyIsPure, warnings };
6090
+ }
6091
+ }
6092
+ const transpileResult = transpileBlock(body, { allMutable: true, parameterMap });
6093
+ const bodyExpr = transpileResult.expression;
6094
+ if (!transpileResult.pure) {
6095
+ warnings.push(`Action '${name}' body contains untranslatable JS \u2014 wrapped in $expr() markers`);
6096
+ }
6097
+ const states = [
6098
+ {
6099
+ name: "ready",
6100
+ type: "START",
6101
+ on_enter: [],
6102
+ during: [],
6103
+ on_exit: []
6104
+ },
6105
+ {
6106
+ name: "done",
6107
+ type: "END",
6108
+ on_enter: [],
6109
+ during: [],
6110
+ on_exit: []
6111
+ }
6112
+ ];
6113
+ const transitions = [
6114
+ {
6115
+ name: "execute",
6116
+ from: ["ready"],
6117
+ to: "done",
6118
+ actions: [
6119
+ {
6120
+ id: "body",
6121
+ type: "eval",
6122
+ mode: "auto",
6123
+ config: {
6124
+ expression: bodyExpr
6125
+ }
6126
+ }
6127
+ ]
6128
+ }
6129
+ ];
6130
+ const ir = {
6131
+ slug,
6132
+ name: humanName,
6133
+ version: "0.1.0",
6134
+ category: "action",
6135
+ fields,
6136
+ states,
6137
+ transitions,
6138
+ roles: [],
6139
+ metadata
6140
+ };
6141
+ return { ir, bodyIsPure: transpileResult.pure, warnings };
6142
+ }
6143
+ function findDefaultExportedFunction(ast) {
6144
+ const topLevelVars = /* @__PURE__ */ new Map();
6145
+ for (const node of ast.program.body) {
6146
+ if (t18.isVariableDeclaration(node)) {
6147
+ for (const decl of node.declarations) {
6148
+ if (t18.isIdentifier(decl.id) && decl.init) {
6149
+ if (t18.isArrowFunctionExpression(decl.init) || t18.isFunctionExpression(decl.init)) {
6150
+ topLevelVars.set(decl.id.name, decl.init);
6151
+ }
6152
+ }
6153
+ }
6154
+ }
6155
+ }
6156
+ for (const node of ast.program.body) {
6157
+ if (t18.isExportDefaultDeclaration(node)) {
6158
+ const decl = node.declaration;
6159
+ if (t18.isFunctionDeclaration(decl) && decl.body) {
6160
+ const name = decl.id?.name ?? inferNameFromFile(decl) ?? "action";
6161
+ return extractFromFunction(name, decl.params, decl.body, decl.returnType, decl.async);
6162
+ }
6163
+ if (t18.isArrowFunctionExpression(decl) || t18.isFunctionExpression(decl)) {
6164
+ const name = t18.isFunctionExpression(decl) && decl.id ? decl.id.name : "action";
6165
+ const body = ensureBlock(decl.body);
6166
+ if (!body) return null;
6167
+ return extractFromFunction(name, decl.params, body, decl.returnType, decl.async);
6168
+ }
6169
+ if (t18.isIdentifier(decl)) {
6170
+ const fn = topLevelVars.get(decl.name);
6171
+ if (fn) {
6172
+ const body = ensureBlock(fn.body);
6173
+ if (!body) return null;
6174
+ return extractFromFunction(decl.name, fn.params, body, fn.returnType, fn.async);
6175
+ }
6176
+ }
6177
+ }
6178
+ }
6179
+ return null;
6180
+ }
6181
+ function extractFromFunction(name, params, body, returnType, isAsync = false) {
6182
+ const extracted = params.map((p) => extractParam(p));
6183
+ const returnTypeAnnotation = returnType && t18.isTSTypeAnnotation(returnType) ? serializeTSType(returnType.typeAnnotation) : void 0;
6184
+ return { name, params: extracted, body, returnTypeAnnotation, isAsync };
6185
+ }
6186
+ function ensureBlock(body) {
6187
+ if (t18.isBlockStatement(body)) return body;
6188
+ const ret = t18.returnStatement(body);
6189
+ return t18.blockStatement([ret]);
6190
+ }
6191
+ function inferNameFromFile(_node) {
6192
+ return null;
6193
+ }
6194
+ function extractParam(param) {
6195
+ if (t18.isIdentifier(param)) {
6196
+ return {
6197
+ name: param.name,
6198
+ typeAnnotation: param.typeAnnotation ? param.typeAnnotation.typeAnnotation : null,
6199
+ optional: param.optional ?? false
6200
+ };
6201
+ }
6202
+ if (t18.isAssignmentPattern(param)) {
6203
+ const inner = param.left;
6204
+ if (t18.isIdentifier(inner)) {
6205
+ return {
6206
+ name: inner.name,
6207
+ typeAnnotation: inner.typeAnnotation ? inner.typeAnnotation.typeAnnotation : null,
6208
+ optional: true,
6209
+ defaultValue: param.right
6210
+ };
6211
+ }
6212
+ }
6213
+ if (t18.isRestElement(param)) {
6214
+ const arg = param.argument;
6215
+ return {
6216
+ name: t18.isIdentifier(arg) ? arg.name : "rest",
6217
+ typeAnnotation: null,
6218
+ optional: true
6219
+ };
6220
+ }
6221
+ return { name: "params", typeAnnotation: null, optional: false };
6222
+ }
6223
+ function paramToField(param) {
6224
+ const fieldType = param.typeAnnotation ? tsTypeToFieldType2(param.typeAnnotation) : "text";
6225
+ const field = {
6226
+ name: toSnakeCase3(param.name),
6227
+ type: fieldType,
6228
+ required: !param.optional
6229
+ };
6230
+ if (param.defaultValue !== void 0) {
6231
+ field.default_value = extractLiteralDefault(param.defaultValue);
6232
+ }
6233
+ return field;
6234
+ }
6235
+ function extractLiteralDefault(expr) {
6236
+ if (!expr) return void 0;
6237
+ if (t18.isStringLiteral(expr)) return expr.value;
6238
+ if (t18.isNumericLiteral(expr)) return expr.value;
6239
+ if (t18.isBooleanLiteral(expr)) return expr.value;
6240
+ if (t18.isNullLiteral(expr)) return null;
6241
+ if (t18.isArrayExpression(expr) && expr.elements.length === 0) return [];
6242
+ if (t18.isObjectExpression(expr) && expr.properties.length === 0) return {};
6243
+ return void 0;
6244
+ }
6245
+ function tsTypeToFieldType2(tsType) {
6246
+ if (t18.isTSStringKeyword(tsType)) return "text";
6247
+ if (t18.isTSNumberKeyword(tsType)) return "number";
6248
+ if (t18.isTSBooleanKeyword(tsType)) return "boolean";
6249
+ if (t18.isTSObjectKeyword(tsType)) return "json";
6250
+ if (t18.isTSAnyKeyword(tsType) || t18.isTSUnknownKeyword(tsType)) return "json";
6251
+ if (t18.isTSArrayType(tsType)) return "json";
6252
+ if (t18.isTSUnionType(tsType)) {
6253
+ const nonNullable = tsType.types.filter(
6254
+ (t23) => !t18.isTSNullKeyword(t23) && !t18.isTSUndefinedKeyword(t23)
6255
+ );
6256
+ if (nonNullable.length === 1) {
6257
+ return tsTypeToFieldType2(nonNullable[0]);
6258
+ }
6259
+ if (nonNullable.every((t23) => t18.isTSLiteralType(t23) && t18.isStringLiteral(t23.literal))) {
6260
+ return "select";
6261
+ }
6262
+ return "text";
6263
+ }
6264
+ if (t18.isTSTypeReference(tsType) && t18.isIdentifier(tsType.typeName)) {
6265
+ const name = tsType.typeName.name;
6266
+ if (name === "Date") return "datetime";
6267
+ if (name === "string") return "text";
6268
+ if (name === "number") return "number";
6269
+ if (name === "boolean") return "boolean";
6270
+ }
6271
+ return "text";
6272
+ }
6273
+ function serializeTSType(tsType) {
6274
+ if (t18.isTSStringKeyword(tsType)) return "string";
6275
+ if (t18.isTSNumberKeyword(tsType)) return "number";
6276
+ if (t18.isTSBooleanKeyword(tsType)) return "boolean";
6277
+ if (t18.isTSVoidKeyword(tsType)) return "void";
6278
+ if (t18.isTSAnyKeyword(tsType)) return "any";
6279
+ if (t18.isTSTypeReference(tsType) && t18.isIdentifier(tsType.typeName)) {
6280
+ return tsType.typeName.name;
6281
+ }
6282
+ if (t18.isTSArrayType(tsType)) return `${serializeTSType(tsType.elementType)}[]`;
6283
+ if (t18.isTSPromiseType(tsType)) {
6284
+ return `Promise<${tsType.typeParameter ? serializeTSType(tsType.typeParameter.params[0]) : "unknown"}>`;
6285
+ }
6286
+ return "unknown";
6287
+ }
6288
+ function splitAtAwaits(body) {
6289
+ const segments = [];
6290
+ let current = [];
6291
+ let index = 0;
6292
+ for (const stmt of body) {
6293
+ const awaitInfo = extractAwait(stmt);
6294
+ if (!awaitInfo) {
6295
+ current.push(stmt);
6296
+ continue;
6297
+ }
6298
+ if (current.length > 0) {
6299
+ segments.push({ index: index++, kind: "sync", statements: current });
6300
+ current = [];
6301
+ }
6302
+ segments.push({
6303
+ index: index++,
6304
+ kind: "await",
6305
+ statements: [stmt],
6306
+ awaitTarget: awaitInfo.callee,
6307
+ awaitArgs: awaitInfo.args,
6308
+ resultBinding: awaitInfo.binding
6309
+ });
6310
+ }
6311
+ if (current.length > 0) {
6312
+ segments.push({ index: index++, kind: "sync", statements: current });
6313
+ }
6314
+ return segments;
6315
+ }
6316
+ function extractAwait(stmt) {
6317
+ if (t18.isVariableDeclaration(stmt)) {
6318
+ const decl = stmt.declarations[0];
6319
+ if (decl?.init && t18.isAwaitExpression(decl.init)) {
6320
+ const arg = decl.init.argument;
6321
+ if (t18.isCallExpression(arg)) {
6322
+ return {
6323
+ callee: getCalleeName(arg.callee),
6324
+ args: arg.arguments,
6325
+ binding: t18.isIdentifier(decl.id) ? decl.id.name : void 0
6326
+ };
6327
+ }
6328
+ }
6329
+ }
6330
+ if (t18.isExpressionStatement(stmt) && t18.isAwaitExpression(stmt.expression)) {
6331
+ const arg = stmt.expression.argument;
6332
+ if (t18.isCallExpression(arg)) {
6333
+ return {
6334
+ callee: getCalleeName(arg.callee),
6335
+ args: arg.arguments,
6336
+ binding: void 0
6337
+ };
6338
+ }
6339
+ }
6340
+ if (t18.isReturnStatement(stmt) && stmt.argument && t18.isAwaitExpression(stmt.argument)) {
6341
+ const arg = stmt.argument.argument;
6342
+ if (t18.isCallExpression(arg)) {
6343
+ return {
6344
+ callee: getCalleeName(arg.callee),
6345
+ args: arg.arguments,
6346
+ binding: void 0
6347
+ };
6348
+ }
6349
+ }
6350
+ return null;
6351
+ }
6352
+ function getCalleeName(callee) {
6353
+ if (t18.isIdentifier(callee)) return callee.name;
6354
+ if (t18.isMemberExpression(callee) && t18.isIdentifier(callee.object) && t18.isIdentifier(callee.property)) {
6355
+ return `${callee.object.name}_${callee.property.name}`;
6356
+ }
6357
+ return "unknown_action";
6358
+ }
6359
+ function rewriteAwaitReferences(segments) {
6360
+ const bindings = /* @__PURE__ */ new Map();
6361
+ const slugCounts = /* @__PURE__ */ new Map();
6362
+ return segments.map((seg) => {
6363
+ if (seg.kind === "await" && seg.resultBinding) {
6364
+ const slug = toSnakeCase3(seg.awaitTarget ?? "unknown");
6365
+ const count = (slugCounts.get(slug) ?? 0) + 1;
6366
+ slugCounts.set(slug, count);
6367
+ const key = count > 1 ? `${slug}_${count}` : slug;
6368
+ bindings.set(seg.resultBinding, `action_results.${key}`);
6369
+ }
6370
+ if (seg.kind === "sync" && bindings.size > 0) {
6371
+ return {
6372
+ ...seg,
6373
+ statements: seg.statements.map(
6374
+ (stmt) => rewriteIdentifiersInStatement(stmt, bindings)
6375
+ )
6376
+ };
6377
+ }
6378
+ return seg;
6379
+ });
6380
+ }
6381
+ function rewriteIdentifiersInStatement(stmt, _bindings) {
6382
+ return stmt;
6383
+ }
6384
+ function generateMultiStateIR(segments, _warnings, parameterMap) {
6385
+ const states = [];
6386
+ const transitions = [];
6387
+ let bodyIsPure = true;
6388
+ const awaitBindings = /* @__PURE__ */ new Map();
6389
+ const slugCounts = /* @__PURE__ */ new Map();
6390
+ for (const seg of segments) {
6391
+ if (seg.kind === "await" && seg.resultBinding) {
6392
+ const slug = toSnakeCase3(seg.awaitTarget ?? "unknown");
6393
+ const count = (slugCounts.get(slug) ?? 0) + 1;
6394
+ slugCounts.set(slug, count);
6395
+ const key = count > 1 ? `${slug}_${count}` : slug;
6396
+ awaitBindings.set(seg.resultBinding, `action_results.${key}`);
6397
+ }
6398
+ }
6399
+ states.push({ name: "ready", type: "START", on_enter: [], during: [], on_exit: [] });
6400
+ const usedStateNames = /* @__PURE__ */ new Set();
6401
+ let prevState = "ready";
6402
+ let transitionCount = 0;
6403
+ let pendingSyncStmts = [];
6404
+ for (const seg of segments) {
6405
+ if (seg.kind === "sync") {
6406
+ pendingSyncStmts.push(...seg.statements);
6407
+ continue;
6408
+ }
6409
+ const targetSlug = toSnakeCase3(seg.awaitTarget ?? "unknown");
6410
+ let stateName = `awaiting_${targetSlug}`;
6411
+ if (usedStateNames.has(stateName)) {
6412
+ let suffix = 2;
6413
+ while (usedStateNames.has(`${stateName}_${suffix}`)) suffix++;
6414
+ stateName = `${stateName}_${suffix}`;
6415
+ }
6416
+ usedStateNames.add(stateName);
6417
+ states.push({ name: stateName, type: "REGULAR", on_enter: [], during: [], on_exit: [] });
6418
+ const actions = [];
6419
+ if (pendingSyncStmts.length > 0) {
6420
+ const block = t18.blockStatement(pendingSyncStmts);
6421
+ const transpiled = transpileBlock(block, {
6422
+ allMutable: true,
6423
+ derivedVarMap: buildDerivedVarMap(awaitBindings),
6424
+ parameterMap
6425
+ });
6426
+ if (!transpiled.pure) bodyIsPure = false;
6427
+ actions.push({
6428
+ id: `pre_${transitionCount}`,
6429
+ type: "eval",
6430
+ mode: "auto",
6431
+ config: { expression: transpiled.expression }
6432
+ });
6433
+ pendingSyncStmts = [];
6434
+ }
6435
+ const callConfig = {
6436
+ definition_slug: seg.awaitTarget,
6437
+ result_key: targetSlug
6438
+ };
6439
+ if (seg.awaitArgs && seg.awaitArgs.length > 0) {
6440
+ const params = {};
6441
+ for (let i = 0; i < seg.awaitArgs.length; i++) {
6442
+ const arg = seg.awaitArgs[i];
6443
+ if (t18.isObjectExpression(arg)) {
6444
+ for (const prop2 of arg.properties) {
6445
+ if (t18.isObjectProperty(prop2) && t18.isIdentifier(prop2.key)) {
6446
+ const { expression: valExpr } = transpileArgExpression(prop2.value, awaitBindings);
6447
+ params[prop2.key.name] = valExpr;
6448
+ }
6449
+ }
6450
+ } else {
6451
+ const { expression: valExpr } = transpileArgExpression(arg, awaitBindings);
6452
+ params[`arg${i}`] = valExpr;
6453
+ }
6454
+ }
6455
+ if (Object.keys(params).length > 0) {
6456
+ callConfig.params = params;
6457
+ }
6458
+ }
6459
+ actions.push({
6460
+ id: `call_${targetSlug}`,
6461
+ type: "call_workflow",
6462
+ mode: "auto",
6463
+ config: callConfig
6464
+ });
6465
+ const transName = transitionCount === 0 ? "execute" : `on_${getStateSuffix(prevState)}_complete`;
6466
+ transitions.push({
6467
+ name: transName,
6468
+ from: [prevState],
6469
+ to: stateName,
6470
+ actions
6471
+ });
6472
+ prevState = stateName;
6473
+ transitionCount++;
6474
+ }
6475
+ states.push({ name: "done", type: "END", on_enter: [], during: [], on_exit: [] });
6476
+ const finalActions = [];
6477
+ if (pendingSyncStmts.length > 0) {
6478
+ const block = t18.blockStatement(pendingSyncStmts);
6479
+ const transpiled = transpileBlock(block, {
6480
+ allMutable: true,
6481
+ derivedVarMap: buildDerivedVarMap(awaitBindings),
6482
+ parameterMap
6483
+ });
6484
+ if (!transpiled.pure) bodyIsPure = false;
6485
+ finalActions.push({
6486
+ id: "post_final",
6487
+ type: "eval",
6488
+ mode: "auto",
6489
+ config: { expression: transpiled.expression }
6490
+ });
6491
+ }
6492
+ const finalTransName = transitionCount === 0 ? "execute" : `on_${getStateSuffix(prevState)}_complete`;
6493
+ transitions.push({
6494
+ name: finalTransName,
6495
+ from: [prevState],
6496
+ to: "done",
6497
+ actions: finalActions
6498
+ });
6499
+ return { states, transitions, bodyIsPure };
6500
+ }
6501
+ function getStateSuffix(stateName) {
6502
+ return stateName.replace(/^awaiting_/, "");
6503
+ }
6504
+ function transpileArgExpression(expr, bindings) {
6505
+ if (t18.isIdentifier(expr)) {
6506
+ const replacement = bindings.get(expr.name);
6507
+ if (replacement) return { expression: replacement };
6508
+ return { expression: `state_data.${toSnakeCase3(expr.name)}` };
6509
+ }
6510
+ if (t18.isMemberExpression(expr) && t18.isIdentifier(expr.object)) {
6511
+ const replacement = bindings.get(expr.object.name);
6512
+ if (replacement && t18.isIdentifier(expr.property)) {
6513
+ return { expression: `${replacement}.${expr.property.name}` };
6514
+ }
6515
+ }
6516
+ if (t18.isStringLiteral(expr)) return { expression: `'${expr.value}'` };
6517
+ if (t18.isNumericLiteral(expr)) return { expression: String(expr.value) };
6518
+ if (t18.isBooleanLiteral(expr)) return { expression: String(expr.value) };
6519
+ const { transpile: transpile2 } = (init_ts_to_expression(), __toCommonJS(ts_to_expression_exports));
6520
+ return { expression: transpile2(expr, { derivedVarMap: buildDerivedVarMap(bindings) }) };
6521
+ }
6522
+ function buildDerivedVarMap(bindings) {
6523
+ const map = /* @__PURE__ */ new Map();
6524
+ for (const [varName, path] of bindings) {
6525
+ map.set(varName, t18.identifier(path));
6526
+ }
6527
+ return map;
6528
+ }
6529
+ function toKebabCase(name) {
6530
+ return name.replace(/([A-Z])/g, "-$1").toLowerCase().replace(/^-/, "");
6531
+ }
6532
+ function toSnakeCase3(name) {
6533
+ return name.replace(/([A-Z])/g, "_$1").toLowerCase().replace(/^_/, "");
6534
+ }
6535
+ var import_parser, t18;
6536
+ var init_action_extractor = __esm({
6537
+ "src/babel/extractors/action-extractor.ts"() {
6538
+ "use strict";
6539
+ import_parser = require("@babel/parser");
6540
+ t18 = __toESM(require("@babel/types"));
6541
+ init_ts_to_expression();
6542
+ }
6543
+ });
6544
+
5806
6545
  // src/incremental-compiler.ts
5807
6546
  function hashContent(content) {
5808
6547
  let hash = 5381;
@@ -6156,24 +6895,56 @@ function parseModuleManifest(source) {
6156
6895
  }
6157
6896
  if (contributions.length > 0) manifest.contributions = contributions;
6158
6897
  }
6898
+ const configSchemaBlock = extractObjectBlock(source, "configSchema");
6899
+ if (configSchemaBlock) {
6900
+ const configSchema = {};
6901
+ const modelSlugMatch = configSchemaBlock.match(/modelSlug:\s*['"]([^'"]+)['"]/);
6902
+ if (modelSlugMatch) configSchema.modelSlug = modelSlugMatch[1];
6903
+ const defaultsBlock = extractObjectBlock(configSchemaBlock, "defaults");
6904
+ if (defaultsBlock) {
6905
+ const defaults = {};
6906
+ const kvRegex = /(\w+):\s*(?:'([^']*)'|"([^"]*)"|(\d+(?:\.\d+)?)|(\btrue\b|\bfalse\b))/g;
6907
+ let kv;
6908
+ while ((kv = kvRegex.exec(defaultsBlock)) !== null) {
6909
+ const key = kv[1];
6910
+ const val = kv[2] ?? kv[3] ?? (kv[4] !== void 0 ? Number(kv[4]) : kv[5] === "true");
6911
+ defaults[key] = val;
6912
+ }
6913
+ configSchema.defaults = defaults;
6914
+ }
6915
+ manifest.configSchema = configSchema;
6916
+ }
6159
6917
  const depsBlock = extractArrayBlock(source, "dependencies");
6160
6918
  if (depsBlock) {
6161
6919
  const dependencies = [];
6162
- const depRegex = /\{\s*slug:\s*['"]([^'"]+)['"][^}]*\}/g;
6163
- let dm;
6164
- while ((dm = depRegex.exec(depsBlock)) !== null) {
6165
- const entry = { slug: dm[1] };
6166
- const verMatch = dm[0].match(/version:\s*['"]([^'"]+)['"]/);
6920
+ const depBlocks = extractNestedObjects(depsBlock);
6921
+ for (const block of depBlocks) {
6922
+ const slugMatch = block.match(/slug:\s*['"]([^'"]+)['"]/);
6923
+ if (!slugMatch) continue;
6924
+ const entry = { slug: slugMatch[1] };
6925
+ const verMatch = block.match(/version:\s*['"]([^'"]+)['"]/);
6167
6926
  if (verMatch) entry.version = verMatch[1];
6168
- const reqMatch = dm[0].match(/required:\s*(true|false)/);
6927
+ const reqMatch = block.match(/required:\s*(true|false)/);
6169
6928
  if (reqMatch) entry.required = reqMatch[1] === "true";
6170
- const prefixMatch = dm[0].match(/prefix:\s*['"]([^'"]+)['"]/);
6929
+ const prefixMatch = block.match(/prefix:\s*['"]([^'"]+)['"]/);
6171
6930
  if (prefixMatch) entry.routeConfig = { prefix: prefixMatch[1] };
6931
+ const configBlock = extractObjectBlock(block, "config");
6932
+ if (configBlock) {
6933
+ const config = {};
6934
+ const kvRegex = /(\w+):\s*(?:'([^']*)'|"([^"]*)"|(\d+(?:\.\d+)?)|(\btrue\b|\bfalse\b))/g;
6935
+ let kv;
6936
+ while ((kv = kvRegex.exec(configBlock)) !== null) {
6937
+ const key = kv[1];
6938
+ const val = kv[2] ?? kv[3] ?? (kv[4] !== void 0 ? Number(kv[4]) : kv[5] === "true");
6939
+ config[key] = val;
6940
+ }
6941
+ if (Object.keys(config).length > 0) entry.config = config;
6942
+ }
6172
6943
  dependencies.push(entry);
6173
6944
  }
6174
6945
  if (dependencies.length > 0) manifest.dependencies = dependencies;
6175
6946
  }
6176
- const hasRichFields = manifest.routes || manifest.actions || manifest.contributions || manifest.capabilities || manifest.dependencies;
6947
+ const hasRichFields = manifest.routes || manifest.actions || manifest.contributions || manifest.capabilities || manifest.dependencies || manifest.configSchema;
6177
6948
  return hasRichFields ? manifest : null;
6178
6949
  }
6179
6950
  function parseDependencyRouteConfigs(files) {
@@ -6269,6 +7040,9 @@ function isModelFile2(filename) {
6269
7040
  function isServerActionFile2(filename) {
6270
7041
  return /\.server\.(ts|tsx)$/.test(filename);
6271
7042
  }
7043
+ function isActionFile(filename) {
7044
+ return /^actions\/.*\.(ts|tsx)$/.test(filename) && !filename.endsWith(".server.ts") && !filename.endsWith(".test.ts") && !filename.endsWith(".test.tsx");
7045
+ }
6272
7046
  function isComponentFile(filename) {
6273
7047
  return /components\/.*\.(tsx?|jsx?)$/.test(filename) && !filename.endsWith(".test.ts") && !filename.endsWith(".test.tsx");
6274
7048
  }
@@ -6285,7 +7059,7 @@ function isModuleManifestFile(filename) {
6285
7059
  return /mm\.module\.(ts|tsx|js)$/.test(filename);
6286
7060
  }
6287
7061
  function isCompilableFile(filename) {
6288
- return isWorkflowFile(filename) || isModelFile2(filename) || isServerActionFile2(filename) || isPageFile2(filename) || isComponentFile(filename);
7062
+ return isWorkflowFile(filename) || isModelFile2(filename) || isServerActionFile2(filename) || isActionFile(filename) || isPageFile2(filename) || isComponentFile(filename);
6289
7063
  }
6290
7064
  function compileFile(filename, source, mode) {
6291
7065
  const errors = [];
@@ -6567,10 +7341,87 @@ function extractComponentProps(source) {
6567
7341
  if (!match) return [];
6568
7342
  return match[1].split(",").map((p) => p.trim().split(/[\s=:]/)[0].replace(/^\.{3}/, "").trim()).filter(Boolean);
6569
7343
  }
7344
+ function generateModuleTypeStubs(childDefinitions, _modelResults) {
7345
+ const stubs = {};
7346
+ for (const child of childDefinitions) {
7347
+ if (!child.slug) continue;
7348
+ const category = child.category;
7349
+ const isModel = category === "data" || Array.isArray(category) && category.includes("model") || Array.isArray(category) && category.includes("data");
7350
+ if (!isModel || !child.fields || child.fields.length === 0) continue;
7351
+ const interfaceName = slugToInterfaceName(child.slug) + "Fields";
7352
+ const lines = [
7353
+ `// Auto-generated type stub for model: ${child.slug}`,
7354
+ `// Do not edit \u2014 regenerated on each build.`,
7355
+ ``,
7356
+ `export interface ${interfaceName} {`
7357
+ ];
7358
+ for (const field of child.fields) {
7359
+ const tsType = irFieldTypeToTs(field.type || "string");
7360
+ const optional = field.required ? "" : "?";
7361
+ const desc = field.description;
7362
+ if (desc) {
7363
+ lines.push(` /** ${desc} */`);
7364
+ }
7365
+ lines.push(` ${field.name}${optional}: ${tsType};`);
7366
+ }
7367
+ lines.push(`}`);
7368
+ lines.push(``);
7369
+ lines.push(`export declare const ${slugToCamelCase(child.slug)}Slug: '${child.slug}';`);
7370
+ lines.push(``);
7371
+ stubs[`types/modules/${child.slug}.d.ts`] = lines.join("\n");
7372
+ }
7373
+ return stubs;
7374
+ }
7375
+ function slugToInterfaceName(slug) {
7376
+ return slug.split("-").map((s) => s.charAt(0).toUpperCase() + s.slice(1)).join("");
7377
+ }
7378
+ function slugToCamelCase(slug) {
7379
+ const parts = slug.split("-");
7380
+ return parts[0] + parts.slice(1).map((s) => s.charAt(0).toUpperCase() + s.slice(1)).join("");
7381
+ }
7382
+ function irFieldTypeToTs(type) {
7383
+ switch (type) {
7384
+ case "string":
7385
+ case "text":
7386
+ case "email":
7387
+ case "url":
7388
+ case "phone":
7389
+ case "slug":
7390
+ case "color":
7391
+ case "password":
7392
+ return "string";
7393
+ case "number":
7394
+ case "integer":
7395
+ case "float":
7396
+ case "currency":
7397
+ case "percent":
7398
+ return "number";
7399
+ case "boolean":
7400
+ case "toggle":
7401
+ return "boolean";
7402
+ case "date":
7403
+ case "datetime":
7404
+ case "timestamp":
7405
+ return "string";
7406
+ case "json":
7407
+ case "object":
7408
+ return "Record<string, unknown>";
7409
+ case "array":
7410
+ return "unknown[]";
7411
+ case "enum":
7412
+ return "string";
7413
+ case "file":
7414
+ case "image":
7415
+ return "string";
7416
+ default:
7417
+ return "unknown";
7418
+ }
7419
+ }
6570
7420
  function buildComposedResult(files, fileIRs, config, errors, warnings, options = {}) {
6571
7421
  const usePhase2 = options.usePhase2Modules !== false;
6572
7422
  const workflowIRs = [];
6573
7423
  const modelIRs = [];
7424
+ const actionDefinitionIRs = [];
6574
7425
  const serverActionEntries = [];
6575
7426
  let modelResults;
6576
7427
  let actionResult;
@@ -6609,6 +7460,17 @@ function buildComposedResult(files, fileIRs, config, errors, warnings, options =
6609
7460
  }
6610
7461
  }
6611
7462
  }
7463
+ for (const [filename, source] of Object.entries(files)) {
7464
+ if (isActionFile(filename)) {
7465
+ const result = extractAction(source, filename);
7466
+ if (result) {
7467
+ actionDefinitionIRs.push(result.ir);
7468
+ for (const w of result.warnings) {
7469
+ warnings.push({ file: filename, message: w, severity: "warning" });
7470
+ }
7471
+ }
7472
+ }
7473
+ }
6612
7474
  if (usePhase2) {
6613
7475
  const modelFiles = {};
6614
7476
  for (const [filename, source] of Object.entries(files)) {
@@ -6659,7 +7521,11 @@ function buildComposedResult(files, fileIRs, config, errors, warnings, options =
6659
7521
  });
6660
7522
  }
6661
7523
  }
6662
- const childDefinitions = [...workflowIRs, ...modelIRs];
7524
+ const childDefinitions = [
7525
+ ...workflowIRs,
7526
+ ...modelIRs,
7527
+ ...actionDefinitionIRs
7528
+ ];
6663
7529
  let routeTable = [];
6664
7530
  if (routeResult) {
6665
7531
  routeTable = routeResult.routes.map((r) => ({
@@ -6735,6 +7601,22 @@ function buildComposedResult(files, fileIRs, config, errors, warnings, options =
6735
7601
  }
6736
7602
  }
6737
7603
  }
7604
+ if (options.resolvedModules && options.resolvedModules.length > 0) {
7605
+ for (const mod of options.resolvedModules) {
7606
+ if (mod.serverActions && mod.serverActions.length > 0) {
7607
+ for (const action of mod.serverActions) {
7608
+ const namespacedName = `${mod.slug}:${action.name}`;
7609
+ if (!serverActionEntries.some((a) => a.name === namespacedName)) {
7610
+ serverActionEntries.push({
7611
+ ...action,
7612
+ name: namespacedName,
7613
+ sourceFile: `${mod.slug}/${action.sourceFile}`
7614
+ });
7615
+ }
7616
+ }
7617
+ }
7618
+ }
7619
+ }
6738
7620
  const allIRs = Object.values(fileIRs);
6739
7621
  const parentIR = mergeIRs(allIRs, config);
6740
7622
  if (!parentIR.metadata) parentIR.metadata = {};
@@ -6747,6 +7629,7 @@ function buildComposedResult(files, fileIRs, config, errors, warnings, options =
6747
7629
  parentMeta.composition = {
6748
7630
  workflowCount: workflowIRs.length,
6749
7631
  modelCount: modelIRs.length,
7632
+ actionCount: actionDefinitionIRs.length,
6750
7633
  serverActionCount: serverActionEntries.length,
6751
7634
  routeCount: routeTable.length,
6752
7635
  componentCount: Object.keys(componentDefinitions).length,
@@ -6778,6 +7661,20 @@ function buildComposedResult(files, fileIRs, config, errors, warnings, options =
6778
7661
  if (manifest?.contributions) {
6779
7662
  parentMeta.slot_contributions = manifest.contributions;
6780
7663
  }
7664
+ if (manifest?.configSchema) {
7665
+ parentMeta.configSchema = manifest.configSchema;
7666
+ }
7667
+ if (manifest?.dependencies) {
7668
+ const depConfigs = {};
7669
+ for (const dep of manifest.dependencies) {
7670
+ if (dep.config) {
7671
+ depConfigs[dep.slug] = dep.config;
7672
+ }
7673
+ }
7674
+ if (Object.keys(depConfigs).length > 0) {
7675
+ parentMeta.module_configs = depConfigs;
7676
+ }
7677
+ }
6781
7678
  const compilableFiles = Object.keys(files).filter(isCompilableFile);
6782
7679
  const importLinks = resolveImportLinks(files, compilableFiles);
6783
7680
  const pageExperiences = {};
@@ -6892,6 +7789,7 @@ function buildComposedResult(files, fileIRs, config, errors, warnings, options =
6892
7789
  }
6893
7790
  }
6894
7791
  }
7792
+ const typeStubs = generateModuleTypeStubs(childDefinitions, modelResults);
6895
7793
  return {
6896
7794
  ir: parentIR,
6897
7795
  childDefinitions,
@@ -6905,7 +7803,8 @@ function buildComposedResult(files, fileIRs, config, errors, warnings, options =
6905
7803
  importLinks,
6906
7804
  modelResults,
6907
7805
  actionResult,
6908
- routeResult
7806
+ routeResult,
7807
+ typeStubs
6909
7808
  };
6910
7809
  }
6911
7810
  function compileProject(files, options = {}) {
@@ -6949,6 +7848,7 @@ var init_project_compiler = __esm({
6949
7848
  init_model_compiler();
6950
7849
  init_route_extractor();
6951
7850
  init_action_compiler();
7851
+ init_action_extractor();
6952
7852
  init_incremental_compiler();
6953
7853
  IncrementalProjectCompiler = class {
6954
7854
  constructor() {
@@ -7167,10 +8067,10 @@ ${output}`);
7167
8067
  fileMap[rel] = (0, import_fs2.readFileSync)(f, "utf-8");
7168
8068
  }
7169
8069
  (0, import_fs2.mkdirSync)(outDir, { recursive: true });
7170
- const result = compileProject2(fileMap, { mode });
7171
- const errors = result.errors.filter((e) => e.severity === "error");
7172
- const warnings = result.errors.filter((e) => e.severity === "warning");
7173
- const definitions2 = [result.ir];
8070
+ const result2 = compileProject2(fileMap, { mode });
8071
+ const errors = result2.errors.filter((e) => e.severity === "error");
8072
+ const warnings = result2.errors.filter((e) => e.severity === "warning");
8073
+ const definitions2 = [result2.ir];
7174
8074
  const errorDetails2 = [];
7175
8075
  for (const err of errors) {
7176
8076
  errorDetails2.push({ file: err.file, message: err.message, line: err.line });
@@ -7179,11 +8079,11 @@ ${output}`);
7179
8079
  for (const warn of warnings) {
7180
8080
  console.warn(` ! ${warn.file}${warn.line ? `:${warn.line}` : ""} ${warn.message}`);
7181
8081
  }
7182
- const irPath = (0, import_path.join)(outDir, `${result.ir.slug}.workflow.json`);
7183
- (0, import_fs2.writeFileSync)(irPath, JSON.stringify(result.ir, null, 2), "utf-8");
8082
+ const irPath = (0, import_path.join)(outDir, `${result2.ir.slug}.workflow.json`);
8083
+ (0, import_fs2.writeFileSync)(irPath, JSON.stringify(result2.ir, null, 2), "utf-8");
7184
8084
  console.log(` + ${(0, import_path.basename)(irPath)}`);
7185
- const seenSlugs = /* @__PURE__ */ new Set([result.ir.slug]);
7186
- for (const child of result.childDefinitions) {
8085
+ const seenSlugs = /* @__PURE__ */ new Set([result2.ir.slug]);
8086
+ for (const child of result2.childDefinitions) {
7187
8087
  if (seenSlugs.has(child.slug)) continue;
7188
8088
  seenSlugs.add(child.slug);
7189
8089
  definitions2.push(child);
@@ -7213,14 +8113,14 @@ ${output}`);
7213
8113
  for (const file2 of allFiles) {
7214
8114
  try {
7215
8115
  const code = (0, import_fs2.readFileSync)(file2, "utf-8");
7216
- const result = (0, import_core4.transformSync)(code, {
8116
+ const result2 = (0, import_core4.transformSync)(code, {
7217
8117
  filename: file2,
7218
8118
  plugins: [[babelPlugin, { mode }]],
7219
8119
  parserOpts: { plugins: ["jsx", "typescript"], attachComment: true }
7220
8120
  });
7221
- const ir = result?.metadata?.mindmatrixIR;
7222
- const definition = result?.metadata?.mindmatrixDefinition;
7223
- const canonical = result?.metadata?.mindmatrixCanonical;
8121
+ const ir = result2?.metadata?.mindmatrixIR;
8122
+ const definition = result2?.metadata?.mindmatrixDefinition;
8123
+ const canonical = result2?.metadata?.mindmatrixCanonical;
7224
8124
  if (ir) {
7225
8125
  definitions.push(ir);
7226
8126
  const irErrors = ir.metadata?.errors;
@@ -7285,7 +8185,37 @@ ${output}`);
7285
8185
  }
7286
8186
  console.log(`
7287
8187
  [mindmatrix-react] Compiled ${compiled} workflows, ${errorCount} errors, ${warningCount} warnings`);
7288
- return { compiled, errors: errorCount, warnings: warningCount, definitions, errorDetails };
8188
+ const result = { compiled, errors: errorCount, warnings: warningCount, definitions, errorDetails };
8189
+ if (options.watch) {
8190
+ await startWatchMode(options);
8191
+ }
8192
+ return result;
8193
+ }
8194
+ async function startWatchMode(options) {
8195
+ const { watch: fsWatch } = await import("fs");
8196
+ const srcDir = options.src ?? "src/workflows";
8197
+ let debounce = null;
8198
+ console.log(`
8199
+ [mindmatrix-react] Watching ${srcDir} for changes... (Ctrl+C to stop)
8200
+ `);
8201
+ fsWatch(srcDir, { recursive: true }, (_event, filename) => {
8202
+ if (!filename) return;
8203
+ if (!filename.match(/\.(tsx?|jsx?)$/)) return;
8204
+ if (filename.includes("node_modules") || filename.includes("dist")) return;
8205
+ if (debounce) clearTimeout(debounce);
8206
+ debounce = setTimeout(async () => {
8207
+ const ts = (/* @__PURE__ */ new Date()).toLocaleTimeString();
8208
+ console.log(`
8209
+ [${ts}] Change detected: ${filename} \u2014 recompiling...`);
8210
+ try {
8211
+ await build({ ...options, watch: false, skipTypeCheck: true });
8212
+ } catch (e) {
8213
+ console.error(`[mindmatrix-react] Rebuild failed:`, e.message);
8214
+ }
8215
+ }, 300);
8216
+ });
8217
+ return new Promise(() => {
8218
+ });
7289
8219
  }
7290
8220
  var import_glob, import_fs2, import_core4, import_path, import_child_process;
7291
8221
  var init_build = __esm({
@@ -7349,10 +8279,10 @@ function emitRadiusShorthand(corners) {
7349
8279
  }
7350
8280
  function emitColorValue(color) {
7351
8281
  if (isTokenRef(color)) {
7352
- return t18.stringLiteral(`token:${color.name}`);
8282
+ return t19.stringLiteral(`token:${color.name}`);
7353
8283
  }
7354
8284
  if (typeof color === "string") {
7355
- return t18.stringLiteral(color);
8285
+ return t19.stringLiteral(color);
7356
8286
  }
7357
8287
  if (typeof color === "object" && color !== null) {
7358
8288
  const c = color;
@@ -7360,37 +8290,37 @@ function emitColorValue(color) {
7360
8290
  const a = typeof c.a === "number" ? c.a : 1;
7361
8291
  if (a === 1) {
7362
8292
  const hex = `#${hexByte(c.r)}${hexByte(c.g)}${hexByte(c.b)}`;
7363
- return t18.stringLiteral(hex);
8293
+ return t19.stringLiteral(hex);
7364
8294
  }
7365
- return t18.stringLiteral(`rgba(${c.r}, ${c.g}, ${c.b}, ${a})`);
8295
+ return t19.stringLiteral(`rgba(${c.r}, ${c.g}, ${c.b}, ${a})`);
7366
8296
  }
7367
8297
  }
7368
- return t18.stringLiteral("inherit");
8298
+ return t19.stringLiteral("inherit");
7369
8299
  }
7370
8300
  function hexByte(n) {
7371
8301
  return Math.round(n).toString(16).padStart(2, "0");
7372
8302
  }
7373
8303
  function prop(key, value) {
7374
- return t18.objectProperty(t18.identifier(key), valueToExpression(value));
8304
+ return t19.objectProperty(t19.identifier(key), valueToExpression(value));
7375
8305
  }
7376
8306
  function valueToExpression(value) {
7377
- if (typeof value === "string") return t18.stringLiteral(value);
7378
- if (typeof value === "number") return t18.numericLiteral(value);
7379
- if (typeof value === "boolean") return t18.booleanLiteral(value);
7380
- if (value === null) return t18.nullLiteral();
7381
- if (value === void 0) return t18.identifier("undefined");
8307
+ if (typeof value === "string") return t19.stringLiteral(value);
8308
+ if (typeof value === "number") return t19.numericLiteral(value);
8309
+ if (typeof value === "boolean") return t19.booleanLiteral(value);
8310
+ if (value === null) return t19.nullLiteral();
8311
+ if (value === void 0) return t19.identifier("undefined");
7382
8312
  if (Array.isArray(value)) {
7383
- return t18.arrayExpression(value.map((v) => valueToExpression(v)));
8313
+ return t19.arrayExpression(value.map((v) => valueToExpression(v)));
7384
8314
  }
7385
8315
  if (typeof value === "object") {
7386
8316
  const entries = Object.entries(value);
7387
- return t18.objectExpression(
8317
+ return t19.objectExpression(
7388
8318
  entries.map(
7389
- ([k, v]) => t18.objectProperty(t18.identifier(k), valueToExpression(v))
8319
+ ([k, v]) => t19.objectProperty(t19.identifier(k), valueToExpression(v))
7390
8320
  )
7391
8321
  );
7392
8322
  }
7393
- return t18.identifier("undefined");
8323
+ return t19.identifier("undefined");
7394
8324
  }
7395
8325
  function emitSxProp(style) {
7396
8326
  if (!style || typeof style !== "object") return null;
@@ -7402,8 +8332,8 @@ function emitSxProp(style) {
7402
8332
  props.push(...emitSpacingShorthand("m", style.margin));
7403
8333
  }
7404
8334
  if (style.backgroundColor) {
7405
- props.push(t18.objectProperty(
7406
- t18.identifier("bg"),
8335
+ props.push(t19.objectProperty(
8336
+ t19.identifier("bg"),
7407
8337
  emitColorValue(style.backgroundColor)
7408
8338
  ));
7409
8339
  }
@@ -7432,8 +8362,8 @@ function emitSxProp(style) {
7432
8362
  props.push(prop("opacity", style.opacity));
7433
8363
  }
7434
8364
  if (style.color) {
7435
- props.push(t18.objectProperty(
7436
- t18.identifier("color"),
8365
+ props.push(t19.objectProperty(
8366
+ t19.identifier("color"),
7437
8367
  emitColorValue(style.color)
7438
8368
  ));
7439
8369
  }
@@ -7448,9 +8378,9 @@ function emitSxProp(style) {
7448
8378
  const sxKey = STATE_TO_SX_KEY[state] || state;
7449
8379
  if (typeof override === "object" && override !== null) {
7450
8380
  const subProp = emitSxProp(override);
7451
- if (subProp && t18.isJSXExpressionContainer(subProp.value) && t18.isObjectExpression(subProp.value.expression)) {
7452
- props.push(t18.objectProperty(
7453
- t18.identifier(sxKey),
8381
+ if (subProp && t19.isJSXExpressionContainer(subProp.value) && t19.isObjectExpression(subProp.value.expression)) {
8382
+ props.push(t19.objectProperty(
8383
+ t19.identifier(sxKey),
7454
8384
  subProp.value.expression
7455
8385
  ));
7456
8386
  }
@@ -7458,16 +8388,16 @@ function emitSxProp(style) {
7458
8388
  }
7459
8389
  }
7460
8390
  if (props.length === 0) return null;
7461
- return t18.jsxAttribute(
7462
- t18.jsxIdentifier("sx"),
7463
- t18.jsxExpressionContainer(t18.objectExpression(props))
8391
+ return t19.jsxAttribute(
8392
+ t19.jsxIdentifier("sx"),
8393
+ t19.jsxExpressionContainer(t19.objectExpression(props))
7464
8394
  );
7465
8395
  }
7466
- var t18, STATE_TO_SX_KEY;
8396
+ var t19, STATE_TO_SX_KEY;
7467
8397
  var init_sx_emitter = __esm({
7468
8398
  "src/decompiler/sx-emitter.ts"() {
7469
8399
  "use strict";
7470
- t18 = __toESM(require("@babel/types"));
8400
+ t19 = __toESM(require("@babel/types"));
7471
8401
  STATE_TO_SX_KEY = {
7472
8402
  hovered: "hover",
7473
8403
  pressed: "pressed",
@@ -7616,34 +8546,34 @@ function splitTopLevelArgs(input) {
7616
8546
  }
7617
8547
  function emitBindingExpression(expr, symbols) {
7618
8548
  if (expr === "[Expression]" || expr === '"[Expression]"') {
7619
- return t19.nullLiteral();
8549
+ return t20.nullLiteral();
7620
8550
  }
7621
8551
  const resolved = resolveIRTokens(expr, symbols);
7622
8552
  const fieldsMatch = resolved.match(/^fields\.(\w+)$/);
7623
8553
  if (fieldsMatch) {
7624
- return t19.identifier(toCamelCase(fieldsMatch[1]));
8554
+ return t20.identifier(toCamelCase(fieldsMatch[1]));
7625
8555
  }
7626
8556
  const setFieldMatch = resolved.match(/^set_field\((\w+),\s*(.+)\)$/);
7627
8557
  if (setFieldMatch) {
7628
8558
  const setter = setterName(setFieldMatch[1]);
7629
- return t19.callExpression(
7630
- t19.identifier(setter),
8559
+ return t20.callExpression(
8560
+ t20.identifier(setter),
7631
8561
  [emitBindingExpression(setFieldMatch[2].trim(), symbols)]
7632
8562
  );
7633
8563
  }
7634
8564
  if (/^\w+$/.test(resolved)) {
7635
- return t19.identifier(toCamelCase(resolved));
8565
+ return t20.identifier(toCamelCase(resolved));
7636
8566
  }
7637
8567
  if (/^[\w$]+(?:\??\.[\w$]+)+$/.test(resolved)) {
7638
8568
  const parts = resolved.split(/(\??\.)/).filter(Boolean);
7639
- let node = t19.identifier(parts[0]);
8569
+ let node = t20.identifier(parts[0]);
7640
8570
  for (let i = 1; i < parts.length; i += 2) {
7641
8571
  const isOptional = parts[i] === "?.";
7642
8572
  const prop2 = parts[i + 1];
7643
8573
  if (!prop2) break;
7644
- node = t19.optionalMemberExpression(
8574
+ node = t20.optionalMemberExpression(
7645
8575
  node,
7646
- t19.identifier(prop2),
8576
+ t20.identifier(prop2),
7647
8577
  false,
7648
8578
  isOptional
7649
8579
  );
@@ -7652,34 +8582,34 @@ function emitBindingExpression(expr, symbols) {
7652
8582
  }
7653
8583
  if (/[=<>!+\-*/%&|^~?:,()[\]{}]/.test(resolved)) {
7654
8584
  try {
7655
- return (0, import_parser.parseExpression)(resolved, {
8585
+ return (0, import_parser2.parseExpression)(resolved, {
7656
8586
  plugins: ["typescript", "jsx"]
7657
8587
  });
7658
8588
  } catch {
7659
- return t19.stringLiteral(resolved);
8589
+ return t20.stringLiteral(resolved);
7660
8590
  }
7661
8591
  }
7662
- return t19.stringLiteral(resolved);
8592
+ return t20.stringLiteral(resolved);
7663
8593
  }
7664
8594
  function emitConfigAttribute(key, value) {
7665
8595
  if (typeof value === "string") {
7666
8596
  if (value.includes('"') || value.includes("\\") || value.includes("\n")) {
7667
- return t19.jsxAttribute(
7668
- t19.jsxIdentifier(key),
7669
- t19.jsxExpressionContainer(t19.stringLiteral(value))
8597
+ return t20.jsxAttribute(
8598
+ t20.jsxIdentifier(key),
8599
+ t20.jsxExpressionContainer(t20.stringLiteral(value))
7670
8600
  );
7671
8601
  }
7672
- return t19.jsxAttribute(
7673
- t19.jsxIdentifier(key),
7674
- t19.stringLiteral(value)
8602
+ return t20.jsxAttribute(
8603
+ t20.jsxIdentifier(key),
8604
+ t20.stringLiteral(value)
7675
8605
  );
7676
8606
  }
7677
8607
  if (typeof value === "boolean" && value === true) {
7678
- return t19.jsxAttribute(t19.jsxIdentifier(key), null);
8608
+ return t20.jsxAttribute(t20.jsxIdentifier(key), null);
7679
8609
  }
7680
- return t19.jsxAttribute(
7681
- t19.jsxIdentifier(key),
7682
- t19.jsxExpressionContainer(valueToExpression(value))
8610
+ return t20.jsxAttribute(
8611
+ t20.jsxIdentifier(key),
8612
+ t20.jsxExpressionContainer(valueToExpression(value))
7683
8613
  );
7684
8614
  }
7685
8615
  function toCamelCase(str) {
@@ -7694,9 +8624,9 @@ function buildJSXTree(node, imports, symbols) {
7694
8624
  const fragmentChildren = (node.children || []).map(
7695
8625
  (child) => buildJSXTree(child, imports, symbols)
7696
8626
  );
7697
- return t19.jsxFragment(
7698
- t19.jsxOpeningFragment(),
7699
- t19.jsxClosingFragment(),
8627
+ return t20.jsxFragment(
8628
+ t20.jsxOpeningFragment(),
8629
+ t20.jsxClosingFragment(),
7700
8630
  fragmentChildren
7701
8631
  );
7702
8632
  }
@@ -7714,13 +8644,13 @@ function buildJSXTree(node, imports, symbols) {
7714
8644
  if (node.bindings) {
7715
8645
  for (const [key, expr] of Object.entries(node.bindings)) {
7716
8646
  let emitted = emitBindingExpression(expr, symbols);
7717
- if (isEventHandlerKey(key) && !t19.isArrowFunctionExpression(emitted) && !t19.isFunctionExpression(emitted)) {
7718
- emitted = t19.arrowFunctionExpression([], emitted);
8647
+ if (isEventHandlerKey(key) && !t20.isArrowFunctionExpression(emitted) && !t20.isFunctionExpression(emitted)) {
8648
+ emitted = t20.arrowFunctionExpression([], emitted);
7719
8649
  }
7720
8650
  attributes.push(
7721
- t19.jsxAttribute(
7722
- t19.jsxIdentifier(key),
7723
- t19.jsxExpressionContainer(emitted)
8651
+ t20.jsxAttribute(
8652
+ t20.jsxIdentifier(key),
8653
+ t20.jsxExpressionContainer(emitted)
7724
8654
  )
7725
8655
  );
7726
8656
  }
@@ -7736,30 +8666,30 @@ function buildJSXTree(node, imports, symbols) {
7736
8666
  }
7737
8667
  }
7738
8668
  const isSelfClosing = jsxChildren.length === 0;
7739
- const element = t19.jsxElement(
7740
- t19.jsxOpeningElement(
7741
- t19.jsxIdentifier(componentName),
8669
+ const element = t20.jsxElement(
8670
+ t20.jsxOpeningElement(
8671
+ t20.jsxIdentifier(componentName),
7742
8672
  attributes,
7743
8673
  isSelfClosing
7744
8674
  ),
7745
- isSelfClosing ? null : t19.jsxClosingElement(t19.jsxIdentifier(componentName)),
8675
+ isSelfClosing ? null : t20.jsxClosingElement(t20.jsxIdentifier(componentName)),
7746
8676
  jsxChildren,
7747
8677
  isSelfClosing
7748
8678
  );
7749
8679
  if (node.visible_when) {
7750
8680
  addImport(imports, "@mindmatrix/react", "Show");
7751
- return t19.jsxElement(
7752
- t19.jsxOpeningElement(
7753
- t19.jsxIdentifier("Show"),
8681
+ return t20.jsxElement(
8682
+ t20.jsxOpeningElement(
8683
+ t20.jsxIdentifier("Show"),
7754
8684
  [
7755
- t19.jsxAttribute(
7756
- t19.jsxIdentifier("when"),
7757
- t19.jsxExpressionContainer(emitBindingExpression(node.visible_when, symbols))
8685
+ t20.jsxAttribute(
8686
+ t20.jsxIdentifier("when"),
8687
+ t20.jsxExpressionContainer(emitBindingExpression(node.visible_when, symbols))
7758
8688
  )
7759
8689
  ],
7760
8690
  false
7761
8691
  ),
7762
- t19.jsxClosingElement(t19.jsxIdentifier("Show")),
8692
+ t20.jsxClosingElement(t20.jsxIdentifier("Show")),
7763
8693
  [element],
7764
8694
  false
7765
8695
  );
@@ -7773,12 +8703,12 @@ function addImport(tracker, source, name) {
7773
8703
  if (!tracker.has(source)) tracker.set(source, /* @__PURE__ */ new Set());
7774
8704
  tracker.get(source).add(name);
7775
8705
  }
7776
- var t19, import_parser, REACT_ATOMS;
8706
+ var t20, import_parser2, REACT_ATOMS;
7777
8707
  var init_ast_builder = __esm({
7778
8708
  "src/decompiler/ast-builder.ts"() {
7779
8709
  "use strict";
7780
- t19 = __toESM(require("@babel/types"));
7781
- import_parser = require("@babel/parser");
8710
+ t20 = __toESM(require("@babel/types"));
8711
+ import_parser2 = require("@babel/parser");
7782
8712
  init_sx_emitter();
7783
8713
  REACT_ATOMS = /* @__PURE__ */ new Set([
7784
8714
  "Stack",
@@ -7830,8 +8760,8 @@ function fieldTypeAnnotation(field) {
7830
8760
  const validation = f.validation;
7831
8761
  const options = validation?.options || f.metadata?.options || f.options;
7832
8762
  if (options && Array.isArray(options) && options.length > 0 && (field.type === "select" || field.type === "text")) {
7833
- return t20.tsUnionType(
7834
- options.map((o) => t20.tsLiteralType(t20.stringLiteral(String(o))))
8763
+ return t21.tsUnionType(
8764
+ options.map((o) => t21.tsLiteralType(t21.stringLiteral(String(o))))
7835
8765
  );
7836
8766
  }
7837
8767
  switch (field.type) {
@@ -7841,25 +8771,25 @@ function fieldTypeAnnotation(field) {
7841
8771
  case "url":
7842
8772
  case "phone":
7843
8773
  case "color":
7844
- return t20.tsStringKeyword();
8774
+ return t21.tsStringKeyword();
7845
8775
  case "number":
7846
8776
  case "currency":
7847
8777
  case "percentage":
7848
8778
  case "rating":
7849
8779
  case "duration":
7850
8780
  case "auto_number":
7851
- return t20.tsNumberKeyword();
8781
+ return t21.tsNumberKeyword();
7852
8782
  case "boolean":
7853
- return t20.tsBooleanKeyword();
8783
+ return t21.tsBooleanKeyword();
7854
8784
  case "date":
7855
8785
  case "datetime":
7856
8786
  case "created_at":
7857
8787
  case "updated_at":
7858
- return t20.tsTypeReference(t20.identifier("Date"));
8788
+ return t21.tsTypeReference(t21.identifier("Date"));
7859
8789
  case "select":
7860
- return t20.tsStringKeyword();
8790
+ return t21.tsStringKeyword();
7861
8791
  case "multi_select":
7862
- return t20.tsArrayType(t20.tsStringKeyword());
8792
+ return t21.tsArrayType(t21.tsStringKeyword());
7863
8793
  // string[]
7864
8794
  case "json":
7865
8795
  return null;
@@ -7879,24 +8809,24 @@ function emitFieldDeclarations(fields, imports) {
7879
8809
  const defaultExpr = field.default_value !== void 0 ? valueToExpression(field.default_value) : inferDefaultFromType(field.type);
7880
8810
  const args2 = [defaultExpr];
7881
8811
  if (field.state_home?.scope === "ephemeral") {
7882
- args2.push(t20.objectExpression([
7883
- t20.objectProperty(t20.identifier("ephemeral"), t20.booleanLiteral(true))
8812
+ args2.push(t21.objectExpression([
8813
+ t21.objectProperty(t21.identifier("ephemeral"), t21.booleanLiteral(true))
7884
8814
  ]));
7885
8815
  }
7886
- const declaration = t20.variableDeclaration("const", [
7887
- t20.variableDeclarator(
7888
- t20.arrayPattern([
7889
- t20.identifier(camelName),
7890
- t20.identifier(setter)
8816
+ const declaration = t21.variableDeclaration("const", [
8817
+ t21.variableDeclarator(
8818
+ t21.arrayPattern([
8819
+ t21.identifier(camelName),
8820
+ t21.identifier(setter)
7891
8821
  ]),
7892
- t20.callExpression(t20.identifier("useState"), args2)
8822
+ t21.callExpression(t21.identifier("useState"), args2)
7893
8823
  )
7894
8824
  ]);
7895
8825
  if (field.default_value !== null) {
7896
8826
  const tsType = fieldTypeAnnotation(field);
7897
8827
  if (tsType) {
7898
8828
  const callExpr = declaration.declarations[0].init;
7899
- callExpr.typeParameters = t20.tsTypeParameterInstantiation([tsType]);
8829
+ callExpr.typeParameters = t21.tsTypeParameterInstantiation([tsType]);
7900
8830
  }
7901
8831
  }
7902
8832
  statements.push(declaration);
@@ -7912,22 +8842,22 @@ function inferDefaultFromType(fieldType) {
7912
8842
  case "phone":
7913
8843
  case "color":
7914
8844
  case "select":
7915
- return t20.stringLiteral("");
8845
+ return t21.stringLiteral("");
7916
8846
  case "number":
7917
8847
  case "currency":
7918
8848
  case "percentage":
7919
8849
  case "rating":
7920
8850
  case "duration":
7921
8851
  case "auto_number":
7922
- return t20.numericLiteral(0);
8852
+ return t21.numericLiteral(0);
7923
8853
  case "boolean":
7924
- return t20.booleanLiteral(false);
8854
+ return t21.booleanLiteral(false);
7925
8855
  case "multi_select":
7926
- return t20.arrayExpression([]);
8856
+ return t21.arrayExpression([]);
7927
8857
  case "json":
7928
- return t20.objectExpression([]);
8858
+ return t21.objectExpression([]);
7929
8859
  default:
7930
- return t20.nullLiteral();
8860
+ return t21.nullLiteral();
7931
8861
  }
7932
8862
  }
7933
8863
  function emitStateEffects(states, imports) {
@@ -7936,9 +8866,9 @@ function emitStateEffects(states, imports) {
7936
8866
  if (state.on_enter.length > 0) {
7937
8867
  addImport2(imports, "@mindmatrix/react", "useOnEnter");
7938
8868
  statements.push(
7939
- t20.expressionStatement(
7940
- t20.callExpression(t20.identifier("useOnEnter"), [
7941
- t20.stringLiteral(state.name),
8869
+ t21.expressionStatement(
8870
+ t21.callExpression(t21.identifier("useOnEnter"), [
8871
+ t21.stringLiteral(state.name),
7942
8872
  emitActionCallback(state.on_enter)
7943
8873
  ])
7944
8874
  )
@@ -7947,9 +8877,9 @@ function emitStateEffects(states, imports) {
7947
8877
  if (state.on_exit.length > 0) {
7948
8878
  addImport2(imports, "@mindmatrix/react", "useOnExit");
7949
8879
  statements.push(
7950
- t20.expressionStatement(
7951
- t20.callExpression(t20.identifier("useOnExit"), [
7952
- t20.stringLiteral(state.name),
8880
+ t21.expressionStatement(
8881
+ t21.callExpression(t21.identifier("useOnExit"), [
8882
+ t21.stringLiteral(state.name),
7953
8883
  emitActionCallback(state.on_exit)
7954
8884
  ])
7955
8885
  )
@@ -7959,15 +8889,15 @@ function emitStateEffects(states, imports) {
7959
8889
  addImport2(imports, "@mindmatrix/react", "useWhileIn");
7960
8890
  for (const during of state.during) {
7961
8891
  const args2 = [
7962
- t20.stringLiteral(state.name)
8892
+ t21.stringLiteral(state.name)
7963
8893
  ];
7964
8894
  if (during.interval_ms) {
7965
- args2.push(t20.numericLiteral(during.interval_ms));
8895
+ args2.push(t21.numericLiteral(during.interval_ms));
7966
8896
  }
7967
8897
  args2.push(emitActionCallback(during.actions));
7968
8898
  statements.push(
7969
- t20.expressionStatement(
7970
- t20.callExpression(t20.identifier("useWhileIn"), args2)
8899
+ t21.expressionStatement(
8900
+ t21.callExpression(t21.identifier("useWhileIn"), args2)
7971
8901
  )
7972
8902
  );
7973
8903
  }
@@ -7986,55 +8916,55 @@ function emitTransitionDeclarations(transitions, imports) {
7986
8916
  const fromArr = normalizeFrom(transition.from);
7987
8917
  if (fromArr.length === 1) {
7988
8918
  configProps.push(
7989
- t20.objectProperty(t20.identifier("from"), t20.stringLiteral(fromArr[0]))
8919
+ t21.objectProperty(t21.identifier("from"), t21.stringLiteral(fromArr[0]))
7990
8920
  );
7991
8921
  } else if (fromArr.length > 1) {
7992
8922
  configProps.push(
7993
- t20.objectProperty(
7994
- t20.identifier("from"),
7995
- t20.arrayExpression(fromArr.map((s) => t20.stringLiteral(s)))
8923
+ t21.objectProperty(
8924
+ t21.identifier("from"),
8925
+ t21.arrayExpression(fromArr.map((s) => t21.stringLiteral(s)))
7996
8926
  )
7997
8927
  );
7998
8928
  }
7999
8929
  configProps.push(
8000
- t20.objectProperty(t20.identifier("to"), t20.stringLiteral(transition.to))
8930
+ t21.objectProperty(t21.identifier("to"), t21.stringLiteral(transition.to))
8001
8931
  );
8002
8932
  if (transition.conditions && transition.conditions.length > 0) {
8003
8933
  configProps.push(
8004
- t20.objectProperty(
8005
- t20.identifier("when"),
8934
+ t21.objectProperty(
8935
+ t21.identifier("when"),
8006
8936
  emitConditionExpression(transition.conditions)
8007
8937
  )
8008
8938
  );
8009
8939
  }
8010
8940
  if (transition.roles && transition.roles.length > 0) {
8011
8941
  configProps.push(
8012
- t20.objectProperty(
8013
- t20.identifier("roles"),
8014
- t20.arrayExpression(transition.roles.map((r) => t20.stringLiteral(r)))
8942
+ t21.objectProperty(
8943
+ t21.identifier("roles"),
8944
+ t21.arrayExpression(transition.roles.map((r) => t21.stringLiteral(r)))
8015
8945
  )
8016
8946
  );
8017
8947
  }
8018
8948
  if (transition.auto) {
8019
8949
  configProps.push(
8020
- t20.objectProperty(t20.identifier("auto"), t20.booleanLiteral(true))
8950
+ t21.objectProperty(t21.identifier("auto"), t21.booleanLiteral(true))
8021
8951
  );
8022
8952
  }
8023
8953
  if (transition.required_fields && transition.required_fields.length > 0) {
8024
8954
  configProps.push(
8025
- t20.objectProperty(
8026
- t20.identifier("requiredFields"),
8027
- t20.arrayExpression(transition.required_fields.map((f) => t20.stringLiteral(f)))
8955
+ t21.objectProperty(
8956
+ t21.identifier("requiredFields"),
8957
+ t21.arrayExpression(transition.required_fields.map((f) => t21.stringLiteral(f)))
8028
8958
  )
8029
8959
  );
8030
8960
  }
8031
8961
  statements.push(
8032
- t20.variableDeclaration("const", [
8033
- t20.variableDeclarator(
8034
- t20.identifier(varName),
8035
- t20.callExpression(t20.identifier("useTransition"), [
8036
- t20.stringLiteral(transition.name),
8037
- t20.objectExpression(configProps)
8962
+ t21.variableDeclaration("const", [
8963
+ t21.variableDeclarator(
8964
+ t21.identifier(varName),
8965
+ t21.callExpression(t21.identifier("useTransition"), [
8966
+ t21.stringLiteral(transition.name),
8967
+ t21.objectExpression(configProps)
8038
8968
  ])
8039
8969
  )
8040
8970
  ])
@@ -8049,59 +8979,59 @@ function emitActionCallback(actions) {
8049
8979
  if (stmt) body.push(stmt);
8050
8980
  }
8051
8981
  if (body.length === 0) {
8052
- body.push(t20.emptyStatement());
8982
+ body.push(t21.emptyStatement());
8053
8983
  }
8054
- return t20.arrowFunctionExpression([], t20.blockStatement(body));
8984
+ return t21.arrowFunctionExpression([], t21.blockStatement(body));
8055
8985
  }
8056
8986
  function emitSingleAction(action) {
8057
8987
  switch (action.type) {
8058
8988
  case "set_field": {
8059
8989
  if (!action.config.field) return null;
8060
8990
  const setter = `set${toPascalCase(String(action.config.field))}`;
8061
- const expr = action.config.expression ? t20.identifier(String(action.config.expression)) : valueToExpression(action.config.value ?? null);
8062
- return t20.expressionStatement(
8063
- t20.callExpression(t20.identifier(setter), [expr])
8991
+ const expr = action.config.expression ? t21.identifier(String(action.config.expression)) : valueToExpression(action.config.value ?? null);
8992
+ return t21.expressionStatement(
8993
+ t21.callExpression(t21.identifier(setter), [expr])
8064
8994
  );
8065
8995
  }
8066
8996
  case "log_event":
8067
8997
  case "log": {
8068
8998
  const msg = action.config.message ?? action.config.event ?? action.type;
8069
- return t20.expressionStatement(
8070
- t20.callExpression(
8071
- t20.memberExpression(t20.identifier("console"), t20.identifier("log")),
8072
- [t20.stringLiteral(String(msg))]
8999
+ return t21.expressionStatement(
9000
+ t21.callExpression(
9001
+ t21.memberExpression(t21.identifier("console"), t21.identifier("log")),
9002
+ [t21.stringLiteral(String(msg))]
8073
9003
  )
8074
9004
  );
8075
9005
  }
8076
9006
  case "emit_event": {
8077
9007
  const eventName = String(action.config.event ?? action.config.name ?? "unknown");
8078
- const args2 = [t20.stringLiteral(eventName)];
9008
+ const args2 = [t21.stringLiteral(eventName)];
8079
9009
  if (action.config.payload) {
8080
9010
  args2.push(valueToExpression(action.config.payload));
8081
9011
  }
8082
- return t20.expressionStatement(
8083
- t20.callExpression(t20.identifier("emitEvent"), args2)
9012
+ return t21.expressionStatement(
9013
+ t21.callExpression(t21.identifier("emitEvent"), args2)
8084
9014
  );
8085
9015
  }
8086
9016
  case "call_workflow": {
8087
9017
  const slug = String(action.config.slug ?? action.config.workflow ?? "unknown");
8088
- const args2 = [t20.stringLiteral(slug)];
9018
+ const args2 = [t21.stringLiteral(slug)];
8089
9019
  if (action.config.params) {
8090
9020
  args2.push(valueToExpression(action.config.params));
8091
9021
  }
8092
- return t20.expressionStatement(
8093
- t20.callExpression(t20.identifier("callWorkflow"), args2)
9022
+ return t21.expressionStatement(
9023
+ t21.callExpression(t21.identifier("callWorkflow"), args2)
8094
9024
  );
8095
9025
  }
8096
9026
  case "spawn_instance":
8097
9027
  case "spawn_subworkflow": {
8098
9028
  const slug = String(action.config.slug ?? action.config.workflow ?? "unknown");
8099
- const args2 = [t20.stringLiteral(slug)];
9029
+ const args2 = [t21.stringLiteral(slug)];
8100
9030
  if (action.config.params || action.config.input) {
8101
9031
  args2.push(valueToExpression(action.config.params ?? action.config.input));
8102
9032
  }
8103
- return t20.expressionStatement(
8104
- t20.callExpression(t20.identifier("spawnInstance"), args2)
9033
+ return t21.expressionStatement(
9034
+ t21.callExpression(t21.identifier("spawnInstance"), args2)
8105
9035
  );
8106
9036
  }
8107
9037
  case "http_request":
@@ -8109,22 +9039,22 @@ function emitSingleAction(action) {
8109
9039
  case "call_webhook": {
8110
9040
  const url = String(action.config.url ?? "");
8111
9041
  const method = String(action.config.method ?? "POST");
8112
- return t20.expressionStatement(
8113
- t20.callExpression(t20.identifier("fetch"), [
8114
- t20.stringLiteral(url),
8115
- t20.objectExpression([
8116
- t20.objectProperty(t20.identifier("method"), t20.stringLiteral(method))
9042
+ return t21.expressionStatement(
9043
+ t21.callExpression(t21.identifier("fetch"), [
9044
+ t21.stringLiteral(url),
9045
+ t21.objectExpression([
9046
+ t21.objectProperty(t21.identifier("method"), t21.stringLiteral(method))
8117
9047
  ])
8118
9048
  ])
8119
9049
  );
8120
9050
  }
8121
9051
  case "delay": {
8122
9052
  const ms = Number(action.config.duration_ms ?? action.config.delay_ms ?? 1e3);
8123
- return t20.expressionStatement(
8124
- t20.awaitExpression(
8125
- t20.callExpression(
8126
- t20.identifier("delay"),
8127
- [t20.numericLiteral(ms)]
9053
+ return t21.expressionStatement(
9054
+ t21.awaitExpression(
9055
+ t21.callExpression(
9056
+ t21.identifier("delay"),
9057
+ [t21.numericLiteral(ms)]
8128
9058
  )
8129
9059
  )
8130
9060
  );
@@ -8132,17 +9062,17 @@ function emitSingleAction(action) {
8132
9062
  case "notify":
8133
9063
  case "send_notification": {
8134
9064
  const msg = String(action.config.message ?? action.config.body ?? "");
8135
- return t20.expressionStatement(
8136
- t20.callExpression(t20.identifier("notify"), [t20.stringLiteral(msg)])
9065
+ return t21.expressionStatement(
9066
+ t21.callExpression(t21.identifier("notify"), [t21.stringLiteral(msg)])
8137
9067
  );
8138
9068
  }
8139
9069
  case "noop":
8140
9070
  return null;
8141
9071
  default: {
8142
9072
  const comment = ` ${action.type}(${JSON.stringify(action.config)}) `;
8143
- const voidExpr = t20.unaryExpression("void", t20.numericLiteral(0));
8144
- t20.addComment(voidExpr, "leading", comment, false);
8145
- return t20.expressionStatement(voidExpr);
9073
+ const voidExpr = t21.unaryExpression("void", t21.numericLiteral(0));
9074
+ t21.addComment(voidExpr, "leading", comment, false);
9075
+ return t21.expressionStatement(voidExpr);
8146
9076
  }
8147
9077
  }
8148
9078
  }
@@ -8152,16 +9082,16 @@ function emitConditionExpression(conditions) {
8152
9082
  }
8153
9083
  let result = emitSingleCondition(conditions[0]);
8154
9084
  for (let i = 1; i < conditions.length; i++) {
8155
- result = t20.logicalExpression("&&", result, emitSingleCondition(conditions[i]));
9085
+ result = t21.logicalExpression("&&", result, emitSingleCondition(conditions[i]));
8156
9086
  }
8157
9087
  return result;
8158
9088
  }
8159
9089
  function emitSingleCondition(cond) {
8160
9090
  if (cond.expression) {
8161
- return t20.identifier(cond.expression);
9091
+ return t21.identifier(cond.expression);
8162
9092
  }
8163
9093
  if (cond.field && cond.operator) {
8164
- const fieldExpr = t20.identifier(toCamelCase2(cond.field));
9094
+ const fieldExpr = t21.identifier(toCamelCase2(cond.field));
8165
9095
  const valueExpr = valueToExpression(cond.value);
8166
9096
  const opMap = {
8167
9097
  eq: "===",
@@ -8173,25 +9103,25 @@ function emitSingleCondition(cond) {
8173
9103
  };
8174
9104
  const jsOp = opMap[cond.operator];
8175
9105
  if (jsOp) {
8176
- return t20.binaryExpression(jsOp, fieldExpr, valueExpr);
9106
+ return t21.binaryExpression(jsOp, fieldExpr, valueExpr);
8177
9107
  }
8178
9108
  if (cond.operator === "is_set") {
8179
- return t20.binaryExpression("!==", fieldExpr, t20.nullLiteral());
9109
+ return t21.binaryExpression("!==", fieldExpr, t21.nullLiteral());
8180
9110
  }
8181
9111
  if (cond.operator === "is_empty") {
8182
- return t20.binaryExpression("===", fieldExpr, t20.nullLiteral());
9112
+ return t21.binaryExpression("===", fieldExpr, t21.nullLiteral());
8183
9113
  }
8184
9114
  if (cond.operator === "contains" && typeof cond.value === "string") {
8185
- return t20.callExpression(
8186
- t20.memberExpression(fieldExpr, t20.identifier("includes")),
8187
- [t20.stringLiteral(cond.value)]
9115
+ return t21.callExpression(
9116
+ t21.memberExpression(fieldExpr, t21.identifier("includes")),
9117
+ [t21.stringLiteral(cond.value)]
8188
9118
  );
8189
9119
  }
8190
9120
  if (cond.operator === "in" && Array.isArray(cond.value)) {
8191
- return t20.callExpression(
8192
- t20.memberExpression(
8193
- t20.arrayExpression(cond.value.map((v) => valueToExpression(v))),
8194
- t20.identifier("includes")
9121
+ return t21.callExpression(
9122
+ t21.memberExpression(
9123
+ t21.arrayExpression(cond.value.map((v) => valueToExpression(v))),
9124
+ t21.identifier("includes")
8195
9125
  ),
8196
9126
  [fieldExpr]
8197
9127
  );
@@ -8200,14 +9130,14 @@ function emitSingleCondition(cond) {
8200
9130
  if (cond.OR && cond.OR.length > 0) {
8201
9131
  let result = emitSingleCondition(cond.OR[0]);
8202
9132
  for (let i = 1; i < cond.OR.length; i++) {
8203
- result = t20.logicalExpression("||", result, emitSingleCondition(cond.OR[i]));
9133
+ result = t21.logicalExpression("||", result, emitSingleCondition(cond.OR[i]));
8204
9134
  }
8205
9135
  return result;
8206
9136
  }
8207
9137
  if (cond.AND && cond.AND.length > 0) {
8208
9138
  return emitConditionExpression(cond.AND);
8209
9139
  }
8210
- return t20.booleanLiteral(true);
9140
+ return t21.booleanLiteral(true);
8211
9141
  }
8212
9142
  function emitRoleDeclarations(metadata, imports) {
8213
9143
  const roleDeps = metadata?.roleDependencies;
@@ -8217,10 +9147,10 @@ function emitRoleDeclarations(metadata, imports) {
8217
9147
  for (const role of roleDeps) {
8218
9148
  const varName = `is${toPascalCase(role)}`;
8219
9149
  statements.push(
8220
- t20.variableDeclaration("const", [
8221
- t20.variableDeclarator(
8222
- t20.identifier(varName),
8223
- t20.callExpression(t20.identifier("useRole"), [t20.stringLiteral(role)])
9150
+ t21.variableDeclaration("const", [
9151
+ t21.variableDeclarator(
9152
+ t21.identifier(varName),
9153
+ t21.callExpression(t21.identifier("useRole"), [t21.stringLiteral(role)])
8224
9154
  )
8225
9155
  ])
8226
9156
  );
@@ -8255,44 +9185,44 @@ function emitQueryDeclarations(metadata, imports) {
8255
9185
  const optionProps = [];
8256
9186
  if (ds.pageSize) {
8257
9187
  optionProps.push(
8258
- t20.objectProperty(t20.identifier("limit"), t20.numericLiteral(ds.pageSize))
9188
+ t21.objectProperty(t21.identifier("limit"), t21.numericLiteral(ds.pageSize))
8259
9189
  );
8260
9190
  }
8261
9191
  if (ds.sort) {
8262
9192
  optionProps.push(
8263
- t20.objectProperty(t20.identifier("orderBy"), t20.stringLiteral(ds.sort))
9193
+ t21.objectProperty(t21.identifier("orderBy"), t21.stringLiteral(ds.sort))
8264
9194
  );
8265
9195
  }
8266
9196
  if (ds.filter && Object.keys(ds.filter).length > 0) {
8267
9197
  optionProps.push(
8268
- t20.objectProperty(t20.identifier("filter"), valueToExpression(ds.filter))
9198
+ t21.objectProperty(t21.identifier("filter"), valueToExpression(ds.filter))
8269
9199
  );
8270
9200
  }
8271
9201
  if (ds.search) {
8272
9202
  optionProps.push(
8273
- t20.objectProperty(t20.identifier("search"), t20.stringLiteral(ds.search))
9203
+ t21.objectProperty(t21.identifier("search"), t21.stringLiteral(ds.search))
8274
9204
  );
8275
9205
  }
8276
9206
  if (ds.groupBy) {
8277
9207
  optionProps.push(
8278
- t20.objectProperty(t20.identifier("groupBy"), t20.stringLiteral(ds.groupBy))
9208
+ t21.objectProperty(t21.identifier("groupBy"), t21.stringLiteral(ds.groupBy))
8279
9209
  );
8280
9210
  }
8281
- const queryTarget = modelVarName ? t20.identifier(modelVarName) : t20.stringLiteral(slug);
9211
+ const queryTarget = modelVarName ? t21.identifier(modelVarName) : t21.stringLiteral(slug);
8282
9212
  const args2 = [queryTarget];
8283
9213
  if (optionProps.length > 0) {
8284
- args2.push(t20.objectExpression(optionProps));
9214
+ args2.push(t21.objectExpression(optionProps));
8285
9215
  }
8286
9216
  statements.push(
8287
- t20.variableDeclaration("const", [
8288
- t20.variableDeclarator(
8289
- t20.objectPattern([
8290
- t20.objectProperty(
8291
- t20.identifier("data"),
8292
- t20.identifier(varName)
9217
+ t21.variableDeclaration("const", [
9218
+ t21.variableDeclarator(
9219
+ t21.objectPattern([
9220
+ t21.objectProperty(
9221
+ t21.identifier("data"),
9222
+ t21.identifier(varName)
8293
9223
  )
8294
9224
  ]),
8295
- t20.callExpression(t20.identifier("useQuery"), args2)
9225
+ t21.callExpression(t21.identifier("useQuery"), args2)
8296
9226
  )
8297
9227
  ])
8298
9228
  );
@@ -8308,13 +9238,13 @@ function emitQueryDeclarations(metadata, imports) {
8308
9238
  addImport2(imports, modelPath, `default as ${modelVarName2}`);
8309
9239
  addedModelImports?.add(slug);
8310
9240
  }
8311
- const mutTarget = modelVarName2 ? t20.identifier(modelVarName2) : t20.stringLiteral(slug);
9241
+ const mutTarget = modelVarName2 ? t21.identifier(modelVarName2) : t21.stringLiteral(slug);
8312
9242
  const varName = `${toCamelCase2(slug.replace(/-/g, "_"))}Mutation`;
8313
9243
  statements.push(
8314
- t20.variableDeclaration("const", [
8315
- t20.variableDeclarator(
8316
- t20.identifier(varName),
8317
- t20.callExpression(t20.identifier("useMutation"), [mutTarget])
9244
+ t21.variableDeclaration("const", [
9245
+ t21.variableDeclarator(
9246
+ t21.identifier(varName),
9247
+ t21.callExpression(t21.identifier("useMutation"), [mutTarget])
8318
9248
  )
8319
9249
  ])
8320
9250
  );
@@ -8329,9 +9259,9 @@ function emitChangeWatchers(metadata, imports) {
8329
9259
  const statements = [];
8330
9260
  for (const watcher of watchers) {
8331
9261
  statements.push(
8332
- t20.expressionStatement(
8333
- t20.callExpression(t20.identifier("useOnChange"), [
8334
- t20.stringLiteral(watcher.field),
9262
+ t21.expressionStatement(
9263
+ t21.callExpression(t21.identifier("useOnChange"), [
9264
+ t21.stringLiteral(watcher.field),
8335
9265
  emitActionCallback(watcher.actions)
8336
9266
  ])
8337
9267
  )
@@ -8355,9 +9285,9 @@ function emitEventSubscriptions(onEvent, imports) {
8355
9285
  }
8356
9286
  }));
8357
9287
  statements.push(
8358
- t20.expressionStatement(
8359
- t20.callExpression(t20.identifier("useOnEvent"), [
8360
- t20.stringLiteral(sub.match),
9288
+ t21.expressionStatement(
9289
+ t21.callExpression(t21.identifier("useOnEvent"), [
9290
+ t21.stringLiteral(sub.match),
8361
9291
  emitActionCallback(actions)
8362
9292
  ])
8363
9293
  )
@@ -8372,9 +9302,9 @@ function emitTransitionEffects(metadata, imports) {
8372
9302
  const statements = [];
8373
9303
  for (const effect of effects) {
8374
9304
  statements.push(
8375
- t20.expressionStatement(
8376
- t20.callExpression(t20.identifier("useOnTransition"), [
8377
- t20.stringLiteral(effect.transition),
9305
+ t21.expressionStatement(
9306
+ t21.callExpression(t21.identifier("useOnTransition"), [
9307
+ t21.stringLiteral(effect.transition),
8378
9308
  emitActionCallback(effect.actions)
8379
9309
  ])
8380
9310
  )
@@ -8403,20 +9333,20 @@ function emitLocalDefaultDeclarations(experience, existingFields, imports) {
8403
9333
  const setter = `set${toPascalCase(key)}`;
8404
9334
  let defaultExpr;
8405
9335
  if (value === void 0 || value === null) {
8406
- defaultExpr = t20.identifier("undefined");
9336
+ defaultExpr = t21.identifier("undefined");
8407
9337
  } else if (typeof value === "string" && /^[a-zA-Z]\w*$/.test(value) && value !== key) {
8408
- defaultExpr = t20.identifier("undefined");
9338
+ defaultExpr = t21.identifier("undefined");
8409
9339
  } else {
8410
9340
  defaultExpr = valueToExpression(value);
8411
9341
  }
8412
9342
  statements.push(
8413
- t20.variableDeclaration("const", [
8414
- t20.variableDeclarator(
8415
- t20.arrayPattern([
8416
- t20.identifier(camelName),
8417
- t20.identifier(setter)
9343
+ t21.variableDeclaration("const", [
9344
+ t21.variableDeclarator(
9345
+ t21.arrayPattern([
9346
+ t21.identifier(camelName),
9347
+ t21.identifier(setter)
8418
9348
  ]),
8419
- t20.callExpression(t20.identifier("useState"), [defaultExpr])
9349
+ t21.callExpression(t21.identifier("useState"), [defaultExpr])
8420
9350
  )
8421
9351
  ])
8422
9352
  );
@@ -8444,31 +9374,31 @@ function normalizeFrom(from) {
8444
9374
  function correctFromFields(transitions) {
8445
9375
  if (transitions.length <= 1) return transitions;
8446
9376
  const fromValues = /* @__PURE__ */ new Set();
8447
- for (const t22 of transitions) {
8448
- const arr = normalizeFrom(t22.from);
9377
+ for (const t23 of transitions) {
9378
+ const arr = normalizeFrom(t23.from);
8449
9379
  for (const f of arr) fromValues.add(f);
8450
9380
  }
8451
9381
  if (fromValues.size !== 1) return transitions;
8452
9382
  const stateNames = /* @__PURE__ */ new Set([...fromValues]);
8453
- for (const t22 of transitions) {
8454
- stateNames.add(t22.to);
9383
+ for (const t23 of transitions) {
9384
+ stateNames.add(t23.to);
8455
9385
  }
8456
- const allNamesAreStates = transitions.every((t22) => stateNames.has(t22.name));
9386
+ const allNamesAreStates = transitions.every((t23) => stateNames.has(t23.name));
8457
9387
  if (!allNamesAreStates) return transitions;
8458
- return transitions.map((t22) => ({
8459
- ...t22,
8460
- from: [t22.name]
9388
+ return transitions.map((t23) => ({
9389
+ ...t23,
9390
+ from: [t23.name]
8461
9391
  }));
8462
9392
  }
8463
9393
  function addImport2(tracker, source, name) {
8464
9394
  if (!tracker.has(source)) tracker.set(source, /* @__PURE__ */ new Set());
8465
9395
  tracker.get(source).add(name);
8466
9396
  }
8467
- var t20;
9397
+ var t21;
8468
9398
  var init_state_emitter = __esm({
8469
9399
  "src/decompiler/state-emitter.ts"() {
8470
9400
  "use strict";
8471
- t20 = __toESM(require("@babel/types"));
9401
+ t21 = __toESM(require("@babel/types"));
8472
9402
  init_sx_emitter();
8473
9403
  }
8474
9404
  });
@@ -8661,12 +9591,12 @@ function emitImportStatements(tracker) {
8661
9591
  for (const name of names) {
8662
9592
  if (name.startsWith("default as ")) {
8663
9593
  const localName = name.slice("default as ".length);
8664
- specifiers.push(t21.importDefaultSpecifier(t21.identifier(localName)));
9594
+ specifiers.push(t22.importDefaultSpecifier(t22.identifier(localName)));
8665
9595
  } else {
8666
- specifiers.push(t21.importSpecifier(t21.identifier(name), t21.identifier(name)));
9596
+ specifiers.push(t22.importSpecifier(t22.identifier(name), t22.identifier(name)));
8667
9597
  }
8668
9598
  }
8669
- result.push(t21.importDeclaration(specifiers, t21.stringLiteral(source)));
9599
+ result.push(t22.importDeclaration(specifiers, t22.stringLiteral(source)));
8670
9600
  }
8671
9601
  return result;
8672
9602
  }
@@ -8721,24 +9651,24 @@ function decompile(definition, options) {
8721
9651
  componentBody.push(...effectHookStmts);
8722
9652
  if (definition.experience) {
8723
9653
  const jsxTree = buildJSXTree(definition.experience, imports, symbols);
8724
- componentBody.push(t21.returnStatement(jsxTree));
9654
+ componentBody.push(t22.returnStatement(jsxTree));
8725
9655
  } else {
8726
- componentBody.push(t21.returnStatement(t21.nullLiteral()));
9656
+ componentBody.push(t22.returnStatement(t22.nullLiteral()));
8727
9657
  }
8728
- const func = t21.functionDeclaration(
8729
- t21.identifier(componentName),
9658
+ const func = t22.functionDeclaration(
9659
+ t22.identifier(componentName),
8730
9660
  [],
8731
- t21.blockStatement(componentBody)
9661
+ t22.blockStatement(componentBody)
8732
9662
  );
8733
9663
  const programBody = [];
8734
9664
  programBody.push(...emitImportStatements(imports));
8735
- const exportDecl = t21.exportDefaultDeclaration(func);
9665
+ const exportDecl = t22.exportDefaultDeclaration(func);
8736
9666
  if (includeAnnotation) {
8737
- t21.addComment(exportDecl, "leading", buildWorkflowAnnotation(definition), false);
9667
+ t22.addComment(exportDecl, "leading", buildWorkflowAnnotation(definition), false);
8738
9668
  }
8739
9669
  programBody.push(exportDecl);
8740
- const program2 = t21.program(programBody);
8741
- const file2 = t21.file(program2);
9670
+ const program2 = t22.program(programBody);
9671
+ const file2 = t22.file(program2);
8742
9672
  const { code } = (0, import_generator.default)(file2, {
8743
9673
  retainLines: false,
8744
9674
  compact: false,
@@ -8750,11 +9680,11 @@ function decompile(definition, options) {
8750
9680
  componentName
8751
9681
  };
8752
9682
  }
8753
- var t21, import_generator;
9683
+ var t22, import_generator;
8754
9684
  var init_decompiler = __esm({
8755
9685
  "src/decompiler/index.ts"() {
8756
9686
  "use strict";
8757
- t21 = __toESM(require("@babel/types"));
9687
+ t22 = __toESM(require("@babel/types"));
8758
9688
  import_generator = __toESM(require("@babel/generator"));
8759
9689
  init_ast_builder();
8760
9690
  init_state_emitter();
@@ -8783,18 +9713,18 @@ function camelCase(str) {
8783
9713
  function correctTransitionFromFields(transitions) {
8784
9714
  if (transitions.length <= 1) return transitions;
8785
9715
  const fromValues = /* @__PURE__ */ new Set();
8786
- for (const t22 of transitions) {
8787
- const arr = Array.isArray(t22.from) ? t22.from : [t22.from];
9716
+ for (const t23 of transitions) {
9717
+ const arr = Array.isArray(t23.from) ? t23.from : [t23.from];
8788
9718
  for (const f of arr) fromValues.add(f);
8789
9719
  }
8790
9720
  if (fromValues.size !== 1) return transitions;
8791
9721
  const stateNames = /* @__PURE__ */ new Set([...fromValues]);
8792
- for (const t22 of transitions) {
8793
- stateNames.add(t22.to);
9722
+ for (const t23 of transitions) {
9723
+ stateNames.add(t23.to);
8794
9724
  }
8795
- const allNamesAreStates = transitions.every((t22) => stateNames.has(t22.name));
9725
+ const allNamesAreStates = transitions.every((t23) => stateNames.has(t23.name));
8796
9726
  if (!allNamesAreStates) return transitions;
8797
- return transitions.map((t22) => ({ ...t22, from: [t22.name] }));
9727
+ return transitions.map((t23) => ({ ...t23, from: [t23.name] }));
8798
9728
  }
8799
9729
  function fieldTypeToTS(fieldType, field) {
8800
9730
  const options = getFieldOptions(field);
@@ -8915,6 +9845,134 @@ function serializeDefault(value) {
8915
9845
  }
8916
9846
  return JSON.stringify(value);
8917
9847
  }
9848
+ function serializeValue(value, indent2) {
9849
+ const pad = " ".repeat(indent2);
9850
+ if (value === void 0 || value === null) return "null";
9851
+ if (typeof value === "string") return `'${esc2(value)}'`;
9852
+ if (typeof value === "number" || typeof value === "boolean") return String(value);
9853
+ if (Array.isArray(value)) {
9854
+ if (value.length === 0) return "[]";
9855
+ if (value.every((v) => typeof v === "string" || typeof v === "number" || typeof v === "boolean")) {
9856
+ return `[${value.map((v) => serializeValue(v, 0)).join(", ")}]`;
9857
+ }
9858
+ const items = value.map((v) => `${pad} ${serializeValue(v, indent2 + 2)},`);
9859
+ return `[
9860
+ ${items.join("\n")}
9861
+ ${pad}]`;
9862
+ }
9863
+ if (typeof value === "object") {
9864
+ return serializeObject(value, indent2);
9865
+ }
9866
+ return JSON.stringify(value);
9867
+ }
9868
+ function serializeObject(obj, indent2) {
9869
+ const pad = " ".repeat(indent2);
9870
+ const entries = Object.entries(obj).filter(([, v]) => v !== void 0);
9871
+ if (entries.length === 0) return "{}";
9872
+ const simple = entries.every(([, v]) => typeof v === "string" || typeof v === "number" || typeof v === "boolean" || v === null);
9873
+ if (simple && entries.length <= 3) {
9874
+ const parts = entries.map(([k, v]) => `${safeKey(k)}: ${serializeValue(v, 0)}`);
9875
+ return `{ ${parts.join(", ")} }`;
9876
+ }
9877
+ const lines = entries.map(([k, v]) => `${pad} ${safeKey(k)}: ${serializeValue(v, indent2 + 2)},`);
9878
+ return `{
9879
+ ${lines.join("\n")}
9880
+ ${pad}}`;
9881
+ }
9882
+ function serializeActions(actions, indent2) {
9883
+ const pad = " ".repeat(indent2);
9884
+ if (!actions || actions.length === 0) return [];
9885
+ const lines = [];
9886
+ lines.push(`${pad}[`);
9887
+ for (const action of actions) {
9888
+ const inner = indent2 + 2;
9889
+ const ip = " ".repeat(inner);
9890
+ lines.push(`${ip}{`);
9891
+ if (action.id) lines.push(`${ip} id: '${esc2(String(action.id))}',`);
9892
+ if (action.type) lines.push(`${ip} type: '${esc2(String(action.type))}',`);
9893
+ if (action.mode) lines.push(`${ip} mode: '${esc2(String(action.mode))}',`);
9894
+ if (action.condition) lines.push(`${ip} condition: '${esc2(String(action.condition))}',`);
9895
+ if (action.config && typeof action.config === "object" && Object.keys(action.config).length > 0) {
9896
+ lines.push(`${ip} config: ${serializeValue(action.config, inner + 2)},`);
9897
+ }
9898
+ lines.push(`${ip}},`);
9899
+ }
9900
+ lines.push(`${pad}]`);
9901
+ return lines;
9902
+ }
9903
+ function serializeConditions(conditions, indent2) {
9904
+ const pad = " ".repeat(indent2);
9905
+ if (!conditions || conditions.length === 0) return [];
9906
+ const lines = [];
9907
+ lines.push(`${pad}[`);
9908
+ for (const cond of conditions) {
9909
+ lines.push(`${" ".repeat(indent2 + 2)}${serializeObject(cond, indent2 + 2)},`);
9910
+ }
9911
+ lines.push(`${pad}]`);
9912
+ return lines;
9913
+ }
9914
+ function serializeDuring(during, indent2) {
9915
+ const pad = " ".repeat(indent2);
9916
+ if (!during || during.length === 0) return [];
9917
+ const lines = [];
9918
+ lines.push(`${pad}[`);
9919
+ for (const d of during) {
9920
+ const inner = indent2 + 2;
9921
+ const ip = " ".repeat(inner);
9922
+ lines.push(`${ip}{`);
9923
+ if (d.id) lines.push(`${ip} id: '${esc2(String(d.id))}',`);
9924
+ if (d.type) lines.push(`${ip} type: '${esc2(String(d.type))}',`);
9925
+ if (d.schedule && typeof d.schedule === "object") {
9926
+ lines.push(`${ip} schedule: ${serializeValue(d.schedule, inner + 2)},`);
9927
+ }
9928
+ if (d.interval_ms != null) lines.push(`${ip} interval_ms: ${d.interval_ms},`);
9929
+ if (d.cron) lines.push(`${ip} cron: '${esc2(String(d.cron))}',`);
9930
+ if (d.delay_ms != null) lines.push(`${ip} delay_ms: ${d.delay_ms},`);
9931
+ if (d.condition) lines.push(`${ip} condition: '${esc2(String(d.condition))}',`);
9932
+ if (d.actions && Array.isArray(d.actions) && d.actions.length > 0) {
9933
+ const actLines = serializeActions(d.actions, inner + 2);
9934
+ lines.push(`${ip} actions: ${actLines[0]?.trim()}`);
9935
+ for (let i = 1; i < actLines.length; i++) lines.push(actLines[i]);
9936
+ const lastIdx = lines.length - 1;
9937
+ if (!lines[lastIdx].trimEnd().endsWith(",")) lines[lastIdx] += ",";
9938
+ }
9939
+ lines.push(`${ip}},`);
9940
+ }
9941
+ lines.push(`${pad}]`);
9942
+ return lines;
9943
+ }
9944
+ function serializeOnEvent(events, indent2) {
9945
+ const pad = " ".repeat(indent2);
9946
+ if (!events || events.length === 0) return [];
9947
+ const lines = [];
9948
+ lines.push(`${pad}[`);
9949
+ for (const evt of events) {
9950
+ const inner = indent2 + 2;
9951
+ const ip = " ".repeat(inner);
9952
+ lines.push(`${ip}{`);
9953
+ if (evt.match) lines.push(`${ip} match: '${esc2(String(evt.match))}',`);
9954
+ if (evt.description) lines.push(`${ip} description: '${esc2(String(evt.description))}',`);
9955
+ if (evt.conditions && Array.isArray(evt.conditions) && evt.conditions.length > 0) {
9956
+ const conds = evt.conditions.map((c) => `'${esc2(c)}'`);
9957
+ if (conds.length === 1) {
9958
+ lines.push(`${ip} conditions: [${conds[0]}],`);
9959
+ } else {
9960
+ lines.push(`${ip} conditions: [`);
9961
+ for (const c of conds) lines.push(`${ip} ${c},`);
9962
+ lines.push(`${ip} ],`);
9963
+ }
9964
+ }
9965
+ if (evt.actions && Array.isArray(evt.actions) && evt.actions.length > 0) {
9966
+ const actLines = serializeActions(evt.actions, inner + 2);
9967
+ lines.push(`${ip} actions: ${actLines[0]?.trim()}`);
9968
+ for (let i = 1; i < actLines.length; i++) lines.push(actLines[i]);
9969
+ if (!lines[lines.length - 1].trimEnd().endsWith(",")) lines[lines.length - 1] += ",";
9970
+ }
9971
+ lines.push(`${ip}},`);
9972
+ }
9973
+ lines.push(`${pad}]`);
9974
+ return lines;
9975
+ }
8918
9976
  function generateModelFile(slug, fields, states, transitions, meta) {
8919
9977
  const typeName = pascalCase3(slug);
8920
9978
  const interfaceName = `${typeName}Fields`;
@@ -8968,17 +10026,49 @@ function generateModelFile(slug, fields, states, transitions, meta) {
8968
10026
  const sortedStates = [...validStates].sort((a, b) => a.name.localeCompare(b.name));
8969
10027
  lines.push(` states: {`);
8970
10028
  for (const state of sortedStates) {
8971
- const props = [];
8972
- if (state.type === "START") {
8973
- props.push(`type: 'initial'`);
8974
- } else if (state.type === "END") {
8975
- props.push(`type: 'final'`);
8976
- }
8977
- if (state.description) {
8978
- props.push(`description: '${esc2(state.description)}'`);
10029
+ const hasOnEnter = state.on_enter && state.on_enter.length > 0;
10030
+ const hasOnExit = state.on_exit && state.on_exit.length > 0;
10031
+ const hasDuring = state.during && state.during.length > 0;
10032
+ const hasOnEvent = state.on_event && state.on_event.length > 0;
10033
+ const hasLifecycle = hasOnEnter || hasOnExit || hasDuring || hasOnEvent;
10034
+ if (!hasLifecycle) {
10035
+ const props = [];
10036
+ if (state.type === "START") props.push(`type: 'initial'`);
10037
+ else if (state.type === "END") props.push(`type: 'final'`);
10038
+ if (state.description) props.push(`description: '${esc2(state.description)}'`);
10039
+ const body = props.length > 0 ? ` ${props.join(", ")} ` : "";
10040
+ lines.push(` ${safeKey(state.name)}: {${body}},`);
10041
+ continue;
8979
10042
  }
8980
- const body = props.length > 0 ? ` ${props.join(", ")} ` : "";
8981
- lines.push(` ${safeKey(state.name)}: {${body}},`);
10043
+ lines.push(` ${safeKey(state.name)}: {`);
10044
+ if (state.type === "START") lines.push(` type: 'initial',`);
10045
+ else if (state.type === "END") lines.push(` type: 'final',`);
10046
+ if (state.description) lines.push(` description: '${esc2(state.description)}',`);
10047
+ if (hasOnEnter) {
10048
+ const actLines = serializeActions(state.on_enter, 8);
10049
+ lines.push(` on_enter: ${actLines[0]?.trim()}`);
10050
+ for (let i = 1; i < actLines.length; i++) lines.push(actLines[i]);
10051
+ if (!lines[lines.length - 1].trimEnd().endsWith(",")) lines[lines.length - 1] += ",";
10052
+ }
10053
+ if (hasOnExit) {
10054
+ const actLines = serializeActions(state.on_exit, 8);
10055
+ lines.push(` on_exit: ${actLines[0]?.trim()}`);
10056
+ for (let i = 1; i < actLines.length; i++) lines.push(actLines[i]);
10057
+ if (!lines[lines.length - 1].trimEnd().endsWith(",")) lines[lines.length - 1] += ",";
10058
+ }
10059
+ if (hasDuring) {
10060
+ const durLines = serializeDuring(state.during, 8);
10061
+ lines.push(` during: ${durLines[0]?.trim()}`);
10062
+ for (let i = 1; i < durLines.length; i++) lines.push(durLines[i]);
10063
+ if (!lines[lines.length - 1].trimEnd().endsWith(",")) lines[lines.length - 1] += ",";
10064
+ }
10065
+ if (hasOnEvent) {
10066
+ const evtLines = serializeOnEvent(state.on_event, 8);
10067
+ lines.push(` on_event: ${evtLines[0]?.trim()}`);
10068
+ for (let i = 1; i < evtLines.length; i++) lines.push(evtLines[i]);
10069
+ if (!lines[lines.length - 1].trimEnd().endsWith(",")) lines[lines.length - 1] += ",";
10070
+ }
10071
+ lines.push(` },`);
8982
10072
  }
8983
10073
  lines.push(` },`);
8984
10074
  }
@@ -8988,23 +10078,51 @@ function generateModelFile(slug, fields, states, transitions, meta) {
8988
10078
  lines.push(` transitions: {`);
8989
10079
  for (const trans of sortedTrans) {
8990
10080
  const fromArr = Array.isArray(trans.from) ? trans.from : [trans.from];
8991
- const parts = [];
10081
+ const hasConditions = trans.conditions && trans.conditions.length > 0;
10082
+ const hasActions = trans.actions && trans.actions.length > 0;
10083
+ const hasRichContent = hasConditions || hasActions;
10084
+ if (!hasRichContent) {
10085
+ const parts = [];
10086
+ if (fromArr.length === 1) parts.push(`from: '${esc2(fromArr[0])}'`);
10087
+ else parts.push(`from: [${fromArr.map((f) => `'${esc2(f)}'`).join(", ")}]`);
10088
+ parts.push(`to: '${esc2(trans.to)}'`);
10089
+ if (trans.roles && trans.roles.length > 0) {
10090
+ parts.push(`roles: [${trans.roles.map((r) => `'${esc2(r)}'`).join(", ")}]`);
10091
+ }
10092
+ if (trans.auto) parts.push(`auto: true`);
10093
+ if (trans.required_fields && trans.required_fields.length > 0) {
10094
+ parts.push(`required_fields: [${trans.required_fields.map((f) => `'${esc2(f)}'`).join(", ")}]`);
10095
+ }
10096
+ lines.push(` ${safeKey(trans.name)}: { ${parts.join(", ")} },`);
10097
+ continue;
10098
+ }
10099
+ lines.push(` ${safeKey(trans.name)}: {`);
8992
10100
  if (fromArr.length === 1) {
8993
- parts.push(`from: '${esc2(fromArr[0])}'`);
10101
+ lines.push(` from: '${esc2(fromArr[0])}',`);
8994
10102
  } else {
8995
- parts.push(`from: [${fromArr.map((f) => `'${esc2(f)}'`).join(", ")}]`);
10103
+ lines.push(` from: [${fromArr.map((f) => `'${esc2(f)}'`).join(", ")}],`);
8996
10104
  }
8997
- parts.push(`to: '${esc2(trans.to)}'`);
10105
+ lines.push(` to: '${esc2(trans.to)}',`);
8998
10106
  if (trans.roles && trans.roles.length > 0) {
8999
- parts.push(`roles: [${trans.roles.map((r) => `'${esc2(r)}'`).join(", ")}]`);
9000
- }
9001
- if (trans.auto) {
9002
- parts.push(`auto: true`);
10107
+ lines.push(` roles: [${trans.roles.map((r) => `'${esc2(r)}'`).join(", ")}],`);
9003
10108
  }
10109
+ if (trans.auto) lines.push(` auto: true,`);
9004
10110
  if (trans.required_fields && trans.required_fields.length > 0) {
9005
- parts.push(`required_fields: [${trans.required_fields.map((f) => `'${esc2(f)}'`).join(", ")}]`);
10111
+ lines.push(` required_fields: [${trans.required_fields.map((f) => `'${esc2(f)}'`).join(", ")}],`);
10112
+ }
10113
+ if (hasConditions) {
10114
+ const condLines = serializeConditions(trans.conditions, 8);
10115
+ lines.push(` conditions: ${condLines[0]?.trim()}`);
10116
+ for (let i = 1; i < condLines.length; i++) lines.push(condLines[i]);
10117
+ if (!lines[lines.length - 1].trimEnd().endsWith(",")) lines[lines.length - 1] += ",";
9006
10118
  }
9007
- lines.push(` ${safeKey(trans.name)}: { ${parts.join(", ")} },`);
10119
+ if (hasActions) {
10120
+ const actLines = serializeActions(trans.actions, 8);
10121
+ lines.push(` actions: ${actLines[0]?.trim()}`);
10122
+ for (let i = 1; i < actLines.length; i++) lines.push(actLines[i]);
10123
+ if (!lines[lines.length - 1].trimEnd().endsWith(",")) lines[lines.length - 1] += ",";
10124
+ }
10125
+ lines.push(` },`);
9008
10126
  }
9009
10127
  lines.push(` },`);
9010
10128
  }
@@ -9406,8 +10524,22 @@ function generateMainWithPages(definition, pages, childViews) {
9406
10524
  delete strippedMeta.queries;
9407
10525
  delete strippedMeta.mutations;
9408
10526
  delete strippedMeta.mutationTargets;
10527
+ const strippedStates = definition.states.map((s) => ({
10528
+ ...s,
10529
+ on_enter: [],
10530
+ on_exit: [],
10531
+ during: [],
10532
+ on_event: void 0
10533
+ }));
10534
+ const strippedTransitions = definition.transitions.map((t23) => ({
10535
+ ...t23,
10536
+ actions: [],
10537
+ conditions: void 0
10538
+ }));
9409
10539
  const modifiedDef = {
9410
10540
  ...definition,
10541
+ states: strippedStates,
10542
+ transitions: strippedTransitions,
9411
10543
  experience: mainTree,
9412
10544
  metadata: strippedMeta
9413
10545
  };
@@ -9622,6 +10754,70 @@ ${typedProps.join("\n")}
9622
10754
  }
9623
10755
  return result.code;
9624
10756
  }
10757
+ function generateActionFile(child) {
10758
+ const isSimple = isSimpleActionDefinition(child);
10759
+ if (isSimple) {
10760
+ return generateSimpleActionFile(child);
10761
+ }
10762
+ return generateModelFile(
10763
+ child.slug,
10764
+ child.fields,
10765
+ child.states,
10766
+ child.transitions,
10767
+ {
10768
+ version: child.version,
10769
+ category: "action",
10770
+ description: child.description
10771
+ }
10772
+ );
10773
+ }
10774
+ function isSimpleActionDefinition(child) {
10775
+ const stateNames = child.states.map((s) => s.name);
10776
+ const hasReady = stateNames.includes("ready");
10777
+ const hasDone = stateNames.includes("done");
10778
+ if (!hasReady || !hasDone || stateNames.length !== 2) return false;
10779
+ if (child.transitions.length !== 1) return false;
10780
+ const exec = child.transitions[0];
10781
+ if (exec.name !== "execute") return false;
10782
+ if (exec.actions.length !== 1) return false;
10783
+ const action = exec.actions[0];
10784
+ if (action.type !== "eval") return false;
10785
+ const config = action.config;
10786
+ return typeof config.expression === "string";
10787
+ }
10788
+ function generateSimpleActionFile(child) {
10789
+ const exec = child.transitions[0];
10790
+ const evalAction = exec.actions[0];
10791
+ const expression = String(evalAction.config.expression || "");
10792
+ const params = child.fields.map((f) => {
10793
+ const paramName = camelCase(f.name);
10794
+ const tsType = fieldTypeToTS(f.type, f);
10795
+ const optional = f.required === false ? "?" : "";
10796
+ return `${paramName}${optional}: ${tsType}`;
10797
+ });
10798
+ const funcName = camelCase(child.slug);
10799
+ const meta = child.metadata;
10800
+ const sourceFn = typeof meta?.source_function === "string" ? meta.source_function : funcName;
10801
+ const returnType = typeof meta?.return_type === "string" ? meta.return_type : "void";
10802
+ const lines = [];
10803
+ const bodyLines = expression.split("\n").map((l) => ` ${l}`).join("\n");
10804
+ lines.push(`/**`);
10805
+ if (child.description) {
10806
+ lines.push(` * ${child.description}`);
10807
+ } else {
10808
+ lines.push(` * ${child.name || sourceFn}`);
10809
+ }
10810
+ lines.push(` */`);
10811
+ lines.push(`export default function ${sourceFn}(${params.join(", ")}): ${returnType} {`);
10812
+ if (bodyLines.trim()) {
10813
+ lines.push(bodyLines);
10814
+ } else {
10815
+ lines.push(` // TODO: implement`);
10816
+ }
10817
+ lines.push(`}`);
10818
+ lines.push(``);
10819
+ return lines.join("\n");
10820
+ }
9625
10821
  function emitServerActionsFromMetadata(definition, files) {
9626
10822
  const meta = definition.metadata;
9627
10823
  const serverActions = meta?.serverActions;
@@ -9685,10 +10881,10 @@ function reduceRouterTransitions(transitions, states) {
9685
10881
  }
9686
10882
  const kept = [];
9687
10883
  const seenKeys = /* @__PURE__ */ new Set();
9688
- for (const t22 of transitions) {
9689
- const fromArr = Array.isArray(t22.from) ? t22.from : [t22.from];
10884
+ for (const t23 of transitions) {
10885
+ const fromArr = Array.isArray(t23.from) ? t23.from : [t23.from];
9690
10886
  const fromState = fromArr[0];
9691
- const toState = t22.to;
10887
+ const toState = t23.to;
9692
10888
  if (!fromState || !stateNames.has(fromState) || !stateNames.has(toState)) continue;
9693
10889
  const fromRole = fromState.split("_")[0];
9694
10890
  const toRole = toState.split("_")[0];
@@ -9698,7 +10894,7 @@ function reduceRouterTransitions(transitions, states) {
9698
10894
  const crossRoleHome = homeStates.has(fromState) && homeStates.has(toState);
9699
10895
  if (sameRole || crossRoleHome) {
9700
10896
  seenKeys.add(key);
9701
- kept.push(t22);
10897
+ kept.push(t23);
9702
10898
  }
9703
10899
  }
9704
10900
  return kept;
@@ -9830,11 +11026,11 @@ function decompileProjectEnhanced(definition) {
9830
11026
  }
9831
11027
  }
9832
11028
  }
9833
- const transNames = new Set(existing.transitions.map((t22) => t22.name));
9834
- for (const t22 of child.transitions) {
9835
- if (!transNames.has(t22.name)) {
9836
- existing.transitions.push(t22);
9837
- transNames.add(t22.name);
11029
+ const transNames = new Set(existing.transitions.map((t23) => t23.name));
11030
+ for (const t23 of child.transitions) {
11031
+ if (!transNames.has(t23.name)) {
11032
+ existing.transitions.push(t23);
11033
+ transNames.add(t23.name);
9838
11034
  }
9839
11035
  }
9840
11036
  if (child.version && child.version !== "0.1.0" && (!existing.version || existing.version === "0.1.0")) {
@@ -9851,7 +11047,18 @@ function decompileProjectEnhanced(definition) {
9851
11047
  }
9852
11048
  for (const [childSlug, child] of mergedChildren) {
9853
11049
  const isRouter = childSlug.endsWith("-router") || child.category === "router";
11050
+ const isAction = child.category === "action";
9854
11051
  const childTransitions = isRouter ? reduceRouterTransitions(child.transitions, child.states) : child.transitions;
11052
+ if (isAction) {
11053
+ const actionFilePath = `actions/${childSlug}.ts`;
11054
+ files.push({
11055
+ path: actionFilePath,
11056
+ role: "model",
11057
+ content: generateActionFile({ ...child, transitions: childTransitions })
11058
+ });
11059
+ actionPaths.push(actionFilePath);
11060
+ continue;
11061
+ }
9855
11062
  if (child.fields.length > 0 && !emittedModelSlugs.has(childSlug)) {
9856
11063
  const childModelPath = `models/${childSlug}.ts`;
9857
11064
  files.push({
@@ -9891,7 +11098,23 @@ function decompileProjectEnhanced(definition) {
9891
11098
  const mainContent = generateMainWithPages(definition, extractedPages, extractedChildViews);
9892
11099
  files.push({ path: mainPath, role: "view-entry", content: mainContent });
9893
11100
  } else {
9894
- const mainResult = decompile(definition);
11101
+ const mainDef = decision.emitModels ? {
11102
+ ...definition,
11103
+ states: definition.states.map((s) => ({
11104
+ ...s,
11105
+ on_enter: [],
11106
+ on_exit: [],
11107
+ during: [],
11108
+ on_event: void 0
11109
+ })),
11110
+ // Also strip transition actions — model file has them
11111
+ transitions: definition.transitions.map((t23) => ({
11112
+ ...t23,
11113
+ actions: [],
11114
+ conditions: void 0
11115
+ }))
11116
+ } : definition;
11117
+ const mainResult = decompile(mainDef);
9895
11118
  files.push({ path: mainPath, role: "view-entry", content: mainResult.code });
9896
11119
  }
9897
11120
  entryPaths.push(mainPath);
@@ -10339,7 +11562,12 @@ function generatePackageJson2(name) {
10339
11562
  deploy: "mmrc deploy --build --src ."
10340
11563
  },
10341
11564
  dependencies: {
10342
- "@mindmatrix/react": "workspace:*"
11565
+ "@mmapp/react": "^0.1.0-alpha.1"
11566
+ },
11567
+ devDependencies: {
11568
+ typescript: "^5.5.0",
11569
+ "@types/react": "^18.0.0",
11570
+ react: "^18.0.0"
10343
11571
  }
10344
11572
  },
10345
11573
  null,
@@ -10351,7 +11579,7 @@ function generateMmConfig2(name, opts) {
10351
11579
  const desc = opts.description ?? `${title} blueprint.`;
10352
11580
  const icon = opts.icon ?? "box";
10353
11581
  const author = opts.author ?? "MindMatrix";
10354
- return `import { defineBlueprint } from '@mindmatrix/react';
11582
+ return `import { defineBlueprint } from '@mmapp/react';
10355
11583
 
10356
11584
  export default defineBlueprint({
10357
11585
  slug: '${name}',
@@ -10384,7 +11612,7 @@ function generateModel(name) {
10384
11612
  * States: draft \u2192 active \u2192 archived
10385
11613
  */
10386
11614
 
10387
- import { defineModel } from '@mindmatrix/react';
11615
+ import { defineModel } from '@mmapp/react';
10388
11616
 
10389
11617
  export interface ${pascal}ItemFields {
10390
11618
  title: string;
@@ -10437,6 +11665,28 @@ export default defineModel({
10437
11665
  });
10438
11666
  `;
10439
11667
  }
11668
+ function generateTsconfig() {
11669
+ return JSON.stringify(
11670
+ {
11671
+ compilerOptions: {
11672
+ target: "ES2020",
11673
+ module: "ESNext",
11674
+ moduleResolution: "bundler",
11675
+ jsx: "react-jsx",
11676
+ strict: true,
11677
+ esModuleInterop: true,
11678
+ skipLibCheck: true,
11679
+ forceConsistentCasingInFileNames: true,
11680
+ declaration: false,
11681
+ noEmit: true
11682
+ },
11683
+ include: ["**/*.ts", "**/*.tsx"],
11684
+ exclude: ["node_modules", "dist"]
11685
+ },
11686
+ null,
11687
+ 2
11688
+ );
11689
+ }
10440
11690
  function generateLayout(name) {
10441
11691
  const title = toTitleCase(name);
10442
11692
  return `/**
@@ -10453,8 +11703,8 @@ import {
10453
11703
  Icon,
10454
11704
  Button,
10455
11705
  Divider,
10456
- } from '@mindmatrix/react/atoms';
10457
- import { useRouter } from '@mindmatrix/react';
11706
+ } from '@mmapp/react/atoms';
11707
+ import { useRouter } from '@mmapp/react';
10458
11708
 
10459
11709
  export default function Layout({ children }: { children: React.ReactNode }) {
10460
11710
  const router = useRouter();
@@ -10513,11 +11763,12 @@ function generatePage(name) {
10513
11763
  * Index page \u2014 lists items with create and search.
10514
11764
  */
10515
11765
 
11766
+ import { useState } from 'react';
10516
11767
  import itemModel from '../models/item';
10517
11768
  import {
10518
- useQuery, useMutation, useRouter, useState,
10519
- Stack, Row, Text, Button, Icon, Card, Show, Each, TextInput, Badge,
10520
- } from '@mindmatrix/react';
11769
+ useQuery, useMutation, useRouter,
11770
+ Stack, Row, Text, Button, Icon, Card, Show, TextInput, Badge,
11771
+ } from '@mmapp/react';
10521
11772
 
10522
11773
  const PRIORITY_COLORS: Record<string, string> = {
10523
11774
  high: 'token:error',
@@ -10588,22 +11839,20 @@ export default function ${pascal}Home() {
10588
11839
  {/* Item list */}
10589
11840
  <Show when={!loading && filtered.length > 0}>
10590
11841
  <Stack gap={4}>
10591
- <Each items={filtered} keyField="id">
10592
- {(item) => (
10593
- <Card padding={12}>
10594
- <Row align="center" gap={12}>
10595
- <Stack flex={1} gap={2}>
10596
- <Text weight="medium" value={item.fields.title} />
10597
- <Show when={!!item.fields.description}>
10598
- <Text size="sm" variant="muted" value={item.fields.description} />
10599
- </Show>
10600
- </Stack>
10601
- <Badge value={item.fields.priority} />
10602
- <Badge value={item.state} variant={item.state === 'active' ? 'success' : 'default'} />
10603
- </Row>
10604
- </Card>
10605
- )}
10606
- </Each>
11842
+ {filtered.map((item: any) => (
11843
+ <Card key={item.id} padding={12}>
11844
+ <Row align="center" gap={12}>
11845
+ <Stack flex={1} gap={2}>
11846
+ <Text weight="medium" value={item.fields.title} />
11847
+ <Show when={!!item.fields.description}>
11848
+ <Text size="sm" variant="muted" value={item.fields.description} />
11849
+ </Show>
11850
+ </Stack>
11851
+ <Badge value={item.fields.priority} />
11852
+ <Badge value={item.state} variant={item.state === 'active' ? 'success' : 'default'} />
11853
+ </Row>
11854
+ </Card>
11855
+ ))}
10607
11856
  </Stack>
10608
11857
  </Show>
10609
11858
  </Stack>
@@ -10630,6 +11879,7 @@ async function init(options) {
10630
11879
  (0, import_fs7.mkdirSync)((0, import_path6.join)(blueprintDir, "app"), { recursive: true });
10631
11880
  const files = [
10632
11881
  ["package.json", generatePackageJson2(name)],
11882
+ ["tsconfig.json", generateTsconfig()],
10633
11883
  ["mm.config.ts", generateMmConfig2(name, options)],
10634
11884
  ["models/item.ts", generateModel(name)],
10635
11885
  ["app/layout.tsx", generateLayout(name)],
@@ -10831,7 +12081,7 @@ async function test(options = {}) {
10831
12081
  const t1 = performance.now();
10832
12082
  console.log(` \u2713 (${((t1 - t0) / 1e3).toFixed(1)}s)`);
10833
12083
  process.stdout.write(` Decompiling IR...`);
10834
- const t22 = performance.now();
12084
+ const t23 = performance.now();
10835
12085
  let decompFiles;
10836
12086
  try {
10837
12087
  const decompInput = {
@@ -10850,7 +12100,7 @@ async function test(options = {}) {
10850
12100
  process.exit(1);
10851
12101
  }
10852
12102
  const t32 = performance.now();
10853
- console.log(` \u2713 (${((t32 - t22) / 1e3).toFixed(1)}s)`);
12103
+ console.log(` \u2713 (${((t32 - t23) / 1e3).toFixed(1)}s)`);
10854
12104
  process.stdout.write(` Recompiling...`);
10855
12105
  const t42 = performance.now();
10856
12106
  let ir2;
@@ -10916,7 +12166,7 @@ async function test(options = {}) {
10916
12166
  diffs,
10917
12167
  timings: {
10918
12168
  compile: t1 - t0,
10919
- decompile: t32 - t22,
12169
+ decompile: t32 - t23,
10920
12170
  recompile: t52 - t42,
10921
12171
  compare: t72 - t62
10922
12172
  }
@@ -10945,11 +12195,11 @@ function compareFields(diffs, fields1, fields2) {
10945
12195
  }
10946
12196
  return { fieldMatch, fieldCount };
10947
12197
  }
10948
- function isCompatibleType(t1, t22) {
12198
+ function isCompatibleType(t1, t23) {
10949
12199
  const stringTypes = /* @__PURE__ */ new Set(["text", "rich_text", "email", "url", "phone", "color", "select"]);
10950
12200
  const numberTypes = /* @__PURE__ */ new Set(["number", "currency", "percentage", "rating", "duration"]);
10951
- if (stringTypes.has(t1) && stringTypes.has(t22)) return true;
10952
- if (numberTypes.has(t1) && numberTypes.has(t22)) return true;
12201
+ if (stringTypes.has(t1) && stringTypes.has(t23)) return true;
12202
+ if (numberTypes.has(t1) && numberTypes.has(t23)) return true;
10953
12203
  return false;
10954
12204
  }
10955
12205
  function compareStates(diffs, states1, states2) {
@@ -11001,8 +12251,8 @@ function compareStates(diffs, states1, states2) {
11001
12251
  return { stateMatch, stateCount };
11002
12252
  }
11003
12253
  function compareTransitions(diffs, transitions1, transitions2) {
11004
- const map1 = new Map(transitions1.map((t22) => [t22.name, t22]));
11005
- const map2 = new Map(transitions2.map((t22) => [t22.name, t22]));
12254
+ const map1 = new Map(transitions1.map((t23) => [t23.name, t23]));
12255
+ const map2 = new Map(transitions2.map((t23) => [t23.name, t23]));
11006
12256
  const transitionCount = map1.size;
11007
12257
  let transitionMatch = 0;
11008
12258
  if (transitions1.length !== transitions2.length) {
@@ -11014,36 +12264,36 @@ function compareTransitions(diffs, transitions1, transitions2) {
11014
12264
  });
11015
12265
  }
11016
12266
  for (const [name, t1] of map1) {
11017
- const t22 = map2.get(name);
11018
- if (!t22) {
12267
+ const t23 = map2.get(name);
12268
+ if (!t23) {
11019
12269
  diffs.push({ path: `transitions[${name}]`, expected: name, actual: void 0, severity: "error" });
11020
12270
  continue;
11021
12271
  }
11022
12272
  let matched = true;
11023
- if (t1.to !== t22.to) {
11024
- diffs.push({ path: `transitions[${name}].to`, expected: t1.to, actual: t22.to, severity: "error" });
12273
+ if (t1.to !== t23.to) {
12274
+ diffs.push({ path: `transitions[${name}].to`, expected: t1.to, actual: t23.to, severity: "error" });
11025
12275
  matched = false;
11026
12276
  }
11027
12277
  const from1 = [...t1.from].sort();
11028
- const from2 = [...t22.from].sort();
12278
+ const from2 = [...t23.from].sort();
11029
12279
  if (JSON.stringify(from1) !== JSON.stringify(from2)) {
11030
12280
  diffs.push({ path: `transitions[${name}].from`, expected: from1, actual: from2, severity: "error" });
11031
12281
  matched = false;
11032
12282
  }
11033
12283
  const roles1 = [...t1.roles ?? []].sort();
11034
- const roles2 = [...t22.roles ?? []].sort();
12284
+ const roles2 = [...t23.roles ?? []].sort();
11035
12285
  if (JSON.stringify(roles1) !== JSON.stringify(roles2)) {
11036
12286
  diffs.push({ path: `transitions[${name}].roles`, expected: roles1, actual: roles2, severity: "error" });
11037
12287
  matched = false;
11038
12288
  }
11039
12289
  const req1 = [...t1.required_fields ?? []].sort();
11040
- const req2 = [...t22.required_fields ?? []].sort();
12290
+ const req2 = [...t23.required_fields ?? []].sort();
11041
12291
  if (JSON.stringify(req1) !== JSON.stringify(req2)) {
11042
12292
  diffs.push({ path: `transitions[${name}].required_fields`, expected: req1, actual: req2, severity: "error" });
11043
12293
  matched = false;
11044
12294
  }
11045
- if (!!t1.auto !== !!t22.auto) {
11046
- diffs.push({ path: `transitions[${name}].auto`, expected: t1.auto, actual: t22.auto, severity: "error" });
12295
+ if (!!t1.auto !== !!t23.auto) {
12296
+ diffs.push({ path: `transitions[${name}].auto`, expected: t1.auto, actual: t23.auto, severity: "error" });
11047
12297
  matched = false;
11048
12298
  }
11049
12299
  if (matched) transitionMatch++;