@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.
- package/ATOM-PIPELINE.md +144 -0
- package/README.md +88 -40
- package/dist/babel/index.js +113 -6
- package/dist/babel/index.mjs +2 -2
- package/dist/chunk-3USIFFE4.mjs +2190 -0
- package/dist/chunk-45YMGEVT.mjs +186 -0
- package/dist/chunk-4FN2AISW.mjs +148 -0
- package/dist/chunk-4OPI5L7G.mjs +2593 -0
- package/dist/chunk-4RYTKOOJ.mjs +186 -0
- package/dist/chunk-5RKTOVR5.mjs +244 -0
- package/dist/chunk-5YDMOO4X.mjs +214 -0
- package/dist/chunk-64ZWEMLJ.mjs +148 -0
- package/dist/chunk-6XP4KSWQ.mjs +2190 -0
- package/dist/chunk-72QWL54I.mjs +175 -0
- package/dist/chunk-7B4TRI7C.mjs +4835 -0
- package/dist/chunk-7ZKGHTNB.mjs +4952 -0
- package/dist/chunk-CIESM3BP.mjs +33 -0
- package/dist/chunk-DE3ZGQAC.mjs +148 -0
- package/dist/chunk-DMCY3BBG.mjs +1933 -0
- package/dist/chunk-DPIK3PJS.mjs +244 -0
- package/dist/chunk-E5IVH4RE.mjs +186 -0
- package/dist/chunk-E6FZNUR5.mjs +4953 -0
- package/dist/chunk-EJRBDQDP.mjs +2607 -0
- package/dist/chunk-ELO4TXJL.mjs +186 -0
- package/dist/chunk-FKRO52XH.mjs +3446 -0
- package/dist/chunk-FL4YAKU6.mjs +4941 -0
- package/dist/chunk-FYT47UBU.mjs +5076 -0
- package/dist/chunk-GCLGPOJZ.mjs +148 -0
- package/dist/chunk-GXB4JOP7.mjs +5072 -0
- package/dist/chunk-HFXOUMTD.mjs +175 -0
- package/dist/chunk-HWIZ47US.mjs +214 -0
- package/dist/chunk-IB7MNPQL.mjs +4953 -0
- package/dist/chunk-ICSIHQCG.mjs +148 -0
- package/dist/chunk-JLA5VNQ3.mjs +186 -0
- package/dist/chunk-JQLWFCTM.mjs +214 -0
- package/dist/chunk-KFJJCQAL.mjs +148 -0
- package/dist/chunk-KJUIIEQE.mjs +186 -0
- package/dist/chunk-KNWTHRVQ.mjs +175 -0
- package/dist/chunk-KSG4XSZF.mjs +175 -0
- package/dist/chunk-LF5N6DOU.mjs +175 -0
- package/dist/chunk-LJQCM2IM.mjs +214 -0
- package/dist/chunk-NW6555WJ.mjs +186 -0
- package/dist/chunk-OMZE6VLQ.mjs +214 -0
- package/dist/chunk-P4BR7WVO.mjs +2190 -0
- package/dist/chunk-QQHVYH2X.mjs +244 -0
- package/dist/chunk-S5QLWLLT.mjs +186 -0
- package/dist/chunk-SCWGT2FY.mjs +2190 -0
- package/dist/chunk-SMKJUSB3.mjs +2190 -0
- package/dist/chunk-VCAY2KGM.mjs +175 -0
- package/dist/chunk-WECAV6QB.mjs +148 -0
- package/dist/chunk-WMKBXUCE.mjs +3228 -0
- package/dist/chunk-XAJ5BKKL.mjs +4947 -0
- package/dist/chunk-XG2X7AEA.mjs +175 -0
- package/dist/chunk-XG7Z23NQ.mjs +148 -0
- package/dist/chunk-XWZAOCQ7.mjs +2607 -0
- package/dist/chunk-Y6MA7ULW.mjs +148 -0
- package/dist/chunk-YMS7Q7LG.mjs +214 -0
- package/dist/chunk-ZA37XTGA.mjs +175 -0
- package/dist/cli/index.js +1616 -366
- package/dist/cli/index.mjs +8 -8
- package/dist/codemod/cli.mjs +1 -1
- package/dist/codemod/index.mjs +1 -1
- package/dist/dev-server-RmGHIntF.d.mts +113 -0
- package/dist/dev-server-RmGHIntF.d.ts +113 -0
- package/dist/dev-server.d.mts +1 -1
- package/dist/dev-server.d.ts +1 -1
- package/dist/dev-server.js +982 -53
- package/dist/dev-server.mjs +5 -5
- package/dist/envelope.js +113 -6
- package/dist/envelope.mjs +3 -3
- package/dist/index.d.mts +5 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +992 -63
- package/dist/index.mjs +8 -8
- package/{src/cli/init.ts → dist/init-7JQMAAXS.mjs} +70 -95
- package/dist/init-EHO4VQ22.mjs +369 -0
- package/dist/init-UC3FWPIW.mjs +367 -0
- package/dist/init-UNSMVKIK.mjs +366 -0
- package/dist/init-UNV5XIDE.mjs +367 -0
- package/dist/project-compiler-2P4N4DR7.mjs +10 -0
- package/dist/project-compiler-D2LCC27O.mjs +10 -0
- package/dist/project-compiler-EJ3GANJE.mjs +10 -0
- package/dist/project-compiler-LOQKVRZJ.mjs +10 -0
- package/dist/project-compiler-RQ6OQKRM.mjs +10 -0
- package/dist/project-compiler-VWNNCHGO.mjs +10 -0
- package/dist/project-compiler-XVAAU4C5.mjs +10 -0
- package/dist/project-compiler-YES5FGMD.mjs +10 -0
- package/dist/project-compiler-ZKMQDLGU.mjs +10 -0
- package/dist/project-decompiler-FLXCEJHS.mjs +7 -0
- package/dist/project-decompiler-VLPR22QF.mjs +7 -0
- package/dist/pull-FUS5QYZS.mjs +109 -0
- package/dist/pull-LD5ENLGY.mjs +109 -0
- package/dist/testing/index.js +113 -6
- package/dist/testing/index.mjs +2 -2
- package/dist/vite/index.js +113 -6
- package/dist/vite/index.mjs +3 -3
- package/examples/uber-app/app/admin/fleet.tsx +19 -19
- package/package.json +4 -3
- package/compile-blueprint-chat.mjs +0 -99
- package/compile-blueprint-glass-console.mjs +0 -98
- package/compile-chat-defs.mjs +0 -92
- package/examples/uber-app/tests/payment.test.tsx +0 -129
- package/examples/uber-app/tests/ride-flow.test.tsx +0 -123
- package/package.json.backup +0 -86
- package/scripts/decompile.ts +0 -226
- package/scripts/seed-auth.ts +0 -267
- package/scripts/seed-uber.ts +0 -248
- package/scripts/validate-uber.ts +0 -119
- package/seed-blueprint-chat.mjs +0 -444
- package/seed-blueprint-glass-console.mjs +0 -445
- package/seed-compiled.mjs +0 -318
- package/src/RoundTripValidator.ts +0 -400
- package/src/__tests__/atom-rendering-coverage.test.ts +0 -680
- package/src/__tests__/auth-module-compilation.test.ts +0 -247
- package/src/__tests__/auth-template-compilation.test.ts +0 -589
- package/src/__tests__/change-extractor.test.ts +0 -142
- package/src/__tests__/cli-pull.test.ts +0 -73
- package/src/__tests__/cli-test.test.ts +0 -72
- package/src/__tests__/component-extractor.test.ts +0 -331
- package/src/__tests__/context-extractor.test.ts +0 -145
- package/src/__tests__/decompiler.test.ts +0 -718
- package/src/__tests__/define-blueprint.test.ts +0 -133
- package/src/__tests__/definition-validator.test.ts +0 -519
- package/src/__tests__/during-extractor.test.ts +0 -152
- package/src/__tests__/effect-extractor.test.ts +0 -107
- package/src/__tests__/event-emission.test.ts +0 -127
- package/src/__tests__/examples.test.ts +0 -236
- package/src/__tests__/full-blueprint-coverage.test.ts +0 -1221
- package/src/__tests__/golden-suite.test.ts +0 -403
- package/src/__tests__/grammar-island-extractor.test.ts +0 -289
- package/src/__tests__/instance-key.test.ts +0 -82
- package/src/__tests__/ir-migration.test.ts +0 -255
- package/src/__tests__/lock-file.test.ts +0 -117
- package/src/__tests__/model-extractor.test.ts +0 -195
- package/src/__tests__/model-field-acl.test.ts +0 -237
- package/src/__tests__/model-hooks.test.ts +0 -130
- package/src/__tests__/model-ref-resolution.test.ts +0 -268
- package/src/__tests__/model-roundtrip.test.ts +0 -502
- package/src/__tests__/model-runtime.test.ts +0 -112
- package/src/__tests__/model-transitions.test.ts +0 -183
- package/src/__tests__/nrt-action-trace.test.ts +0 -391
- package/src/__tests__/pipeline-hardening.test.ts +0 -413
- package/src/__tests__/project-compiler.test.ts +0 -546
- package/src/__tests__/project-decompiler.test.ts +0 -343
- package/src/__tests__/query-compilation.test.ts +0 -145
- package/src/__tests__/round-trip/PLAN.md +0 -158
- package/src/__tests__/round-trip/README.md +0 -52
- package/src/__tests__/round-trip/RESULTS.md +0 -86
- package/src/__tests__/round-trip/fixtures/data-heavy/main.workflow.tsx +0 -55
- package/src/__tests__/round-trip/fixtures/data-heavy/mm.config.ts +0 -11
- package/src/__tests__/round-trip/fixtures/data-heavy/models/contact.ts +0 -54
- package/src/__tests__/round-trip/fixtures/full-workflow/main.workflow.tsx +0 -79
- package/src/__tests__/round-trip/fixtures/full-workflow/mm.config.ts +0 -12
- package/src/__tests__/round-trip/fixtures/full-workflow/models/order.ts +0 -50
- package/src/__tests__/round-trip/fixtures/simple-crud/main.workflow.tsx +0 -25
- package/src/__tests__/round-trip/fixtures/simple-crud/mm.config.ts +0 -11
- package/src/__tests__/round-trip/fixtures/simple-crud/models/task.ts +0 -32
- package/src/__tests__/round-trip/fixtures/view-heavy/main.workflow.tsx +0 -79
- package/src/__tests__/round-trip/fixtures/view-heavy/mm.config.ts +0 -10
- package/src/__tests__/round-trip/round-trip.test.ts +0 -2598
- package/src/__tests__/round-trip-ir.test.ts +0 -300
- package/src/__tests__/round-trip.test.ts +0 -1212
- package/src/__tests__/route-merging.test.ts +0 -372
- package/src/__tests__/router-composition.test.ts +0 -489
- package/src/__tests__/router-extractor.test.ts +0 -176
- package/src/__tests__/server-action-extractor.test.ts +0 -128
- package/src/__tests__/smart-type-inference.test.ts +0 -365
- package/src/__tests__/source-envelope.test.ts +0 -284
- package/src/__tests__/source-fidelity.test.ts +0 -516
- package/src/__tests__/state-extractor.test.ts +0 -115
- package/src/__tests__/strict-mode.test.ts +0 -227
- package/src/__tests__/transition-effect-extractor.test.ts +0 -119
- package/src/__tests__/transition-extractor.test.ts +0 -68
- package/src/__tests__/ts-to-expression.test.ts +0 -462
- package/src/__tests__/type-generator.test.ts +0 -201
- package/src/__tests__/uber-validation.test.ts +0 -502
- package/src/action-compiler.ts +0 -361
- package/src/babel/emitters/experience-transform.ts +0 -199
- package/src/babel/emitters/ir-to-tsx-emitter.ts +0 -110
- package/src/babel/emitters/pure-form-emitter.ts +0 -1023
- package/src/babel/emitters/runtime-glue-emitter.ts +0 -39
- package/src/babel/extractors/change-extractor.ts +0 -199
- package/src/babel/extractors/component-extractor.ts +0 -907
- package/src/babel/extractors/computed-extractor.ts +0 -262
- package/src/babel/extractors/context-extractor.ts +0 -277
- package/src/babel/extractors/during-extractor.ts +0 -295
- package/src/babel/extractors/effect-extractor.ts +0 -340
- package/src/babel/extractors/event-extractor.ts +0 -235
- package/src/babel/extractors/grammar-island-extractor.ts +0 -302
- package/src/babel/extractors/model-extractor.ts +0 -1018
- package/src/babel/extractors/router-extractor.ts +0 -303
- package/src/babel/extractors/server-action-extractor.ts +0 -173
- package/src/babel/extractors/server-action-hook-extractor.ts +0 -72
- package/src/babel/extractors/server-state-extractor.ts +0 -88
- package/src/babel/extractors/state-extractor.ts +0 -214
- package/src/babel/extractors/transition-effect-extractor.ts +0 -176
- package/src/babel/extractors/transition-extractor.ts +0 -143
- package/src/babel/index.ts +0 -24
- package/src/babel/transpilers/ts-to-expression.ts +0 -674
- package/src/babel/visitor.ts +0 -807
- package/src/cli/auth.ts +0 -255
- package/src/cli/build.ts +0 -288
- package/src/cli/deploy.ts +0 -206
- package/src/cli/index.ts +0 -328
- package/src/cli/installer.ts +0 -261
- package/src/cli/lock-file.ts +0 -94
- package/src/cli/mmrc.ts +0 -22
- package/src/cli/pull.ts +0 -172
- package/src/cli/registry-client.ts +0 -175
- package/src/cli/test.ts +0 -397
- package/src/cli/type-generator.ts +0 -243
- package/src/codemod/__tests__/forward.test.ts +0 -239
- package/src/codemod/__tests__/reverse.test.ts +0 -145
- package/src/codemod/__tests__/round-trip.test.ts +0 -137
- package/src/codemod/annotation.ts +0 -97
- package/src/codemod/classify.ts +0 -197
- package/src/codemod/cli.ts +0 -207
- package/src/codemod/control-flow.ts +0 -409
- package/src/codemod/forward.ts +0 -244
- package/src/codemod/import-manager.ts +0 -171
- package/src/codemod/index.ts +0 -120
- package/src/codemod/reverse.ts +0 -197
- package/src/codemod/rules.ts +0 -174
- package/src/codemod/state-transform.ts +0 -126
- package/src/decompiler/ast-builder.ts +0 -538
- package/src/decompiler/config-generator.ts +0 -151
- package/src/decompiler/index.ts +0 -315
- package/src/decompiler/project-decompiler.ts +0 -1776
- package/src/decompiler/project.ts +0 -862
- package/src/decompiler/split-strategy.ts +0 -140
- package/src/decompiler/state-emitter.ts +0 -1053
- package/src/decompiler/sx-emitter.ts +0 -318
- package/src/decompiler/workspace-hydrator.ts +0 -189
- package/src/dev-server.ts +0 -238
- package/src/envelope/fs-tree.ts +0 -217
- package/src/envelope/source-envelope.ts +0 -264
- package/src/envelope.ts +0 -315
- package/src/incremental-compiler.ts +0 -401
- package/src/index.ts +0 -99
- package/src/model-compiler.ts +0 -277
- package/src/project-compiler.ts +0 -1629
- package/src/route-extractor.ts +0 -333
- package/src/testing/index.ts +0 -32
- package/src/testing/snapshot.ts +0 -252
- package/src/testing/test-utils.ts +0 -226
- package/src/types.ts +0 -68
- package/src/vite/index.ts +0 -288
- package/test-compile.mjs +0 -142
- package/tsconfig.json +0 -25
- package/tsup.config.ts +0 -23
- package/vitest.config.ts +0 -9
package/dist/dev-server.js
CHANGED
|
@@ -445,25 +445,25 @@ function inferTransitionStates(transitions, states) {
|
|
|
445
445
|
const stateArray = Array.from(states.values());
|
|
446
446
|
const startStates = stateArray.filter((s) => s.type === "START");
|
|
447
447
|
const regularStates = stateArray.filter((s) => s.type === "REGULAR");
|
|
448
|
-
const needsInference = transitions.filter((
|
|
448
|
+
const needsInference = transitions.filter((t19) => t19.from.length === 0 || !t19.to);
|
|
449
449
|
if (needsInference.length === 0) return;
|
|
450
450
|
if (startStates.length === 1 && regularStates.length > 0) {
|
|
451
|
-
needsInference.forEach((
|
|
452
|
-
if (
|
|
453
|
-
|
|
451
|
+
needsInference.forEach((t19, idx) => {
|
|
452
|
+
if (t19.from.length === 0) {
|
|
453
|
+
t19.from = [startStates[0].name];
|
|
454
454
|
}
|
|
455
|
-
if (!
|
|
456
|
-
|
|
455
|
+
if (!t19.to) {
|
|
456
|
+
t19.to = regularStates[idx % regularStates.length]?.name || startStates[0].name;
|
|
457
457
|
}
|
|
458
458
|
});
|
|
459
459
|
} else {
|
|
460
460
|
const allStateNames = stateArray.map((s) => s.name);
|
|
461
|
-
needsInference.forEach((
|
|
462
|
-
if (
|
|
463
|
-
|
|
461
|
+
needsInference.forEach((t19, idx) => {
|
|
462
|
+
if (t19.from.length === 0 && allStateNames.length > 0) {
|
|
463
|
+
t19.from = [allStateNames[0]];
|
|
464
464
|
}
|
|
465
|
-
if (!
|
|
466
|
-
|
|
465
|
+
if (!t19.to && allStateNames.length > 1) {
|
|
466
|
+
t19.to = allStateNames[Math.min(idx + 1, allStateNames.length - 1)];
|
|
467
467
|
}
|
|
468
468
|
});
|
|
469
469
|
}
|
|
@@ -651,11 +651,128 @@ var init_event_extractor = __esm({
|
|
|
651
651
|
});
|
|
652
652
|
|
|
653
653
|
// src/babel/transpilers/ts-to-expression.ts
|
|
654
|
+
var ts_to_expression_exports = {};
|
|
655
|
+
__export(ts_to_expression_exports, {
|
|
656
|
+
transpile: () => transpile,
|
|
657
|
+
transpileBlock: () => transpileBlock,
|
|
658
|
+
transpileExpression: () => transpileExpression
|
|
659
|
+
});
|
|
654
660
|
function transpileExpression(node, options = {}) {
|
|
655
661
|
const ctx = new TranspileContext(options);
|
|
656
662
|
const expr = ctx.visit(node);
|
|
657
663
|
return { expression: expr, pure: ctx.isPure };
|
|
658
664
|
}
|
|
665
|
+
function transpile(node, options = {}) {
|
|
666
|
+
return transpileExpression(node, options).expression;
|
|
667
|
+
}
|
|
668
|
+
function transpileBlock(node, options = {}) {
|
|
669
|
+
const ctx = new TranspileContext(options);
|
|
670
|
+
const lines = visitStatements(node.body, ctx);
|
|
671
|
+
return { expression: lines, pure: ctx.isPure };
|
|
672
|
+
}
|
|
673
|
+
function visitStatements(stmts, ctx) {
|
|
674
|
+
return stmts.map((s) => visitStatement(s, ctx)).join("\n");
|
|
675
|
+
}
|
|
676
|
+
function visitStatement(stmt, ctx) {
|
|
677
|
+
if (t5.isVariableDeclaration(stmt)) {
|
|
678
|
+
const keyword = ctx.allMutable || stmt.kind !== "const" ? "let" : "const";
|
|
679
|
+
const decls = stmt.declarations.map((d) => {
|
|
680
|
+
const init = d.init ? ctx.visit(d.init) : "null";
|
|
681
|
+
const lhs = declaratorPattern(d.id);
|
|
682
|
+
return `${keyword} ${lhs} = ${init}`;
|
|
683
|
+
});
|
|
684
|
+
return decls.join(";\n") + ";";
|
|
685
|
+
}
|
|
686
|
+
if (t5.isIfStatement(stmt)) {
|
|
687
|
+
const test = ctx.visit(stmt.test);
|
|
688
|
+
const consequent = visitBranchBody(stmt.consequent, ctx);
|
|
689
|
+
if (stmt.alternate) {
|
|
690
|
+
const alternate = visitBranchBody(stmt.alternate, ctx);
|
|
691
|
+
return `if (${test}) ${consequent} else ${alternate}`;
|
|
692
|
+
}
|
|
693
|
+
return `if (${test}) ${consequent}`;
|
|
694
|
+
}
|
|
695
|
+
if (t5.isForOfStatement(stmt)) {
|
|
696
|
+
const right = ctx.visit(stmt.right);
|
|
697
|
+
const varName = forOfPattern(stmt.left);
|
|
698
|
+
const body = visitBranchBody(stmt.body, ctx);
|
|
699
|
+
return `for (const ${varName} of ${right}) ${body}`;
|
|
700
|
+
}
|
|
701
|
+
if (t5.isWhileStatement(stmt)) {
|
|
702
|
+
const test = ctx.visit(stmt.test);
|
|
703
|
+
const body = visitBranchBody(stmt.body, ctx);
|
|
704
|
+
return `while (${test}) ${body}`;
|
|
705
|
+
}
|
|
706
|
+
if (t5.isReturnStatement(stmt)) {
|
|
707
|
+
if (!stmt.argument) return "return;";
|
|
708
|
+
return `return ${ctx.visit(stmt.argument)};`;
|
|
709
|
+
}
|
|
710
|
+
if (t5.isExpressionStatement(stmt)) {
|
|
711
|
+
return ctx.visit(stmt.expression) + ";";
|
|
712
|
+
}
|
|
713
|
+
if (t5.isBlockStatement(stmt)) {
|
|
714
|
+
const inner = visitStatements(stmt.body, ctx);
|
|
715
|
+
return `{
|
|
716
|
+
${indent(inner)}
|
|
717
|
+
}`;
|
|
718
|
+
}
|
|
719
|
+
if (t5.isFunctionDeclaration(stmt) && stmt.id) {
|
|
720
|
+
const name = stmt.id.name;
|
|
721
|
+
const params = stmt.params.map((p) => t5.isIdentifier(p) ? p.name : "_").join(", ");
|
|
722
|
+
const body = visitStatements(stmt.body.body, ctx);
|
|
723
|
+
return `function ${name}(${params}) {
|
|
724
|
+
${indent(body)}
|
|
725
|
+
}`;
|
|
726
|
+
}
|
|
727
|
+
return ctx.opaque(`[${stmt.type}]`) + ";";
|
|
728
|
+
}
|
|
729
|
+
function visitBranchBody(node, ctx) {
|
|
730
|
+
if (t5.isBlockStatement(node)) {
|
|
731
|
+
const inner2 = visitStatements(node.body, ctx);
|
|
732
|
+
return `{
|
|
733
|
+
${indent(inner2)}
|
|
734
|
+
}`;
|
|
735
|
+
}
|
|
736
|
+
const inner = visitStatement(node, ctx);
|
|
737
|
+
return `{
|
|
738
|
+
${indent(inner)}
|
|
739
|
+
}`;
|
|
740
|
+
}
|
|
741
|
+
function declaratorPattern(node) {
|
|
742
|
+
if (t5.isIdentifier(node)) return node.name;
|
|
743
|
+
if (t5.isObjectPattern(node)) {
|
|
744
|
+
const props = node.properties.map((p) => {
|
|
745
|
+
if (t5.isRestElement(p)) {
|
|
746
|
+
return `...${t5.isIdentifier(p.argument) ? p.argument.name : "_"}`;
|
|
747
|
+
}
|
|
748
|
+
if (t5.isObjectProperty(p)) {
|
|
749
|
+
const key = t5.isIdentifier(p.key) ? p.key.name : "_";
|
|
750
|
+
const val = t5.isIdentifier(p.value) ? p.value.name : t5.isAssignmentPattern(p.value) && t5.isIdentifier(p.value.left) ? p.value.left.name : "_";
|
|
751
|
+
return key === val ? key : `${key}: ${val}`;
|
|
752
|
+
}
|
|
753
|
+
return "_";
|
|
754
|
+
});
|
|
755
|
+
return `{ ${props.join(", ")} }`;
|
|
756
|
+
}
|
|
757
|
+
if (t5.isArrayPattern(node)) {
|
|
758
|
+
const elems = node.elements.map(
|
|
759
|
+
(e) => e === null ? "" : t5.isIdentifier(e) ? e.name : "_"
|
|
760
|
+
);
|
|
761
|
+
return `[${elems.join(", ")}]`;
|
|
762
|
+
}
|
|
763
|
+
return "_";
|
|
764
|
+
}
|
|
765
|
+
function forOfPattern(left) {
|
|
766
|
+
if (t5.isVariableDeclaration(left)) {
|
|
767
|
+
const d = left.declarations[0];
|
|
768
|
+
if (d) return declaratorPattern(d.id);
|
|
769
|
+
}
|
|
770
|
+
if (t5.isIdentifier(left)) return left.name;
|
|
771
|
+
return "_";
|
|
772
|
+
}
|
|
773
|
+
function indent(code) {
|
|
774
|
+
return code.split("\n").map((l) => " " + l).join("\n");
|
|
775
|
+
}
|
|
659
776
|
function fallbackGenerate(node) {
|
|
660
777
|
if (t5.isIdentifier(node)) return node.name;
|
|
661
778
|
if (t5.isStringLiteral(node)) return `"${node.value.replace(/"/g, '\\"')}"`;
|
|
@@ -675,6 +792,8 @@ var init_ts_to_expression = __esm({
|
|
|
675
792
|
this.localFieldMap = options.localFieldMap ?? /* @__PURE__ */ new Map();
|
|
676
793
|
this.derivedVarMap = options.derivedVarMap ?? /* @__PURE__ */ new Map();
|
|
677
794
|
this.setterToFieldMap = options.setterToFieldMap ?? /* @__PURE__ */ new Map();
|
|
795
|
+
this.parameterMap = options.parameterMap ?? /* @__PURE__ */ new Map();
|
|
796
|
+
this.allMutable = options.allMutable ?? false;
|
|
678
797
|
}
|
|
679
798
|
/**
|
|
680
799
|
* Emit an opaque JS fallback, marking the result as impure.
|
|
@@ -696,6 +815,8 @@ var init_ts_to_expression = __esm({
|
|
|
696
815
|
if (snakeName) return `$local.${snakeName}`;
|
|
697
816
|
const derivedInit = this.derivedVarMap.get(node.name);
|
|
698
817
|
if (derivedInit) return `(${this.visit(derivedInit)})`;
|
|
818
|
+
const paramField = this.parameterMap.get(node.name);
|
|
819
|
+
if (paramField) return paramField;
|
|
699
820
|
if (node.name === "undefined") return "null";
|
|
700
821
|
if (node.name === "NaN") return "null";
|
|
701
822
|
if (node.name === "Infinity") return "null";
|
|
@@ -743,6 +864,9 @@ var init_ts_to_expression = __esm({
|
|
|
743
864
|
if (t5.isNewExpression(node)) {
|
|
744
865
|
return this.visitNew(node);
|
|
745
866
|
}
|
|
867
|
+
if (t5.isAssignmentExpression(node) && node.operator === "=" && t5.isIdentifier(node.left)) {
|
|
868
|
+
return `${node.left.name} = ${this.visit(node.right)}`;
|
|
869
|
+
}
|
|
746
870
|
return this.opaque(fallbackGenerate(node));
|
|
747
871
|
}
|
|
748
872
|
// ---------------------------------------------------------------------------
|
|
@@ -943,6 +1067,11 @@ var init_ts_to_expression = __esm({
|
|
|
943
1067
|
return this.visitArrayHigherOrder("some", obj, args);
|
|
944
1068
|
case "every":
|
|
945
1069
|
return this.visitArrayHigherOrder("every", obj, args);
|
|
1070
|
+
// --- Array push: arr.push(item) → arr = push(arr, item) ---
|
|
1071
|
+
case "push": {
|
|
1072
|
+
const [item] = this.visitArgsList(args);
|
|
1073
|
+
return `${obj} = push(${obj}, ${item})`;
|
|
1074
|
+
}
|
|
946
1075
|
// --- Array mutation-free methods ---
|
|
947
1076
|
case "reverse":
|
|
948
1077
|
return `reverse(${obj})`;
|
|
@@ -2796,6 +2925,71 @@ function modelStateTypeToIR(type) {
|
|
|
2796
2925
|
if (type === "final") return "END";
|
|
2797
2926
|
return "REGULAR";
|
|
2798
2927
|
}
|
|
2928
|
+
function parseActionArray(raw, actionCounter) {
|
|
2929
|
+
if (!Array.isArray(raw)) return [];
|
|
2930
|
+
const actions = [];
|
|
2931
|
+
for (const item of raw) {
|
|
2932
|
+
if (typeof item !== "object" || item === null) continue;
|
|
2933
|
+
const a = item;
|
|
2934
|
+
actions.push({
|
|
2935
|
+
id: a.id ? String(a.id) : `auto_${++actionCounter.value}`,
|
|
2936
|
+
type: String(a.type || a.action_type || "unknown"),
|
|
2937
|
+
mode: a.mode || "auto",
|
|
2938
|
+
config: a.config && typeof a.config === "object" ? a.config : {},
|
|
2939
|
+
...a.condition ? { condition: String(a.condition) } : {}
|
|
2940
|
+
});
|
|
2941
|
+
}
|
|
2942
|
+
return actions;
|
|
2943
|
+
}
|
|
2944
|
+
function parseDuringArray(raw, actionCounter) {
|
|
2945
|
+
if (!Array.isArray(raw)) return [];
|
|
2946
|
+
const result = [];
|
|
2947
|
+
for (const item of raw) {
|
|
2948
|
+
if (typeof item !== "object" || item === null) continue;
|
|
2949
|
+
const d = item;
|
|
2950
|
+
result.push({
|
|
2951
|
+
id: d.id ? String(d.id) : `during_${++actionCounter.value}`,
|
|
2952
|
+
type: d.type || "interval",
|
|
2953
|
+
...d.interval_ms != null ? { interval_ms: Number(d.interval_ms) } : {},
|
|
2954
|
+
...d.cron ? { cron: String(d.cron) } : {},
|
|
2955
|
+
...d.delay_ms != null ? { delay_ms: Number(d.delay_ms) } : {},
|
|
2956
|
+
...d.condition ? { condition: String(d.condition) } : {},
|
|
2957
|
+
actions: parseActionArray(d.actions, actionCounter)
|
|
2958
|
+
});
|
|
2959
|
+
}
|
|
2960
|
+
return result;
|
|
2961
|
+
}
|
|
2962
|
+
function parseOnEventArray(raw, actionCounter) {
|
|
2963
|
+
if (!Array.isArray(raw)) return [];
|
|
2964
|
+
const result = [];
|
|
2965
|
+
for (const item of raw) {
|
|
2966
|
+
if (typeof item !== "object" || item === null) continue;
|
|
2967
|
+
const e = item;
|
|
2968
|
+
const actions = [];
|
|
2969
|
+
if (Array.isArray(e.actions)) {
|
|
2970
|
+
for (const a of e.actions) {
|
|
2971
|
+
if (typeof a !== "object" || a === null) continue;
|
|
2972
|
+
const act = a;
|
|
2973
|
+
actions.push({
|
|
2974
|
+
type: act.type || "set_field",
|
|
2975
|
+
...act.field ? { field: String(act.field) } : {},
|
|
2976
|
+
...act.expression ? { expression: String(act.expression) } : {},
|
|
2977
|
+
...act.key ? { key: String(act.key) } : {},
|
|
2978
|
+
...act.message ? { message: String(act.message) } : {},
|
|
2979
|
+
...act.config && typeof act.config === "object" ? { config: act.config } : {},
|
|
2980
|
+
...act.conditions && Array.isArray(act.conditions) ? { conditions: act.conditions.map(String) } : {}
|
|
2981
|
+
});
|
|
2982
|
+
}
|
|
2983
|
+
}
|
|
2984
|
+
result.push({
|
|
2985
|
+
match: String(e.match || ""),
|
|
2986
|
+
...e.description ? { description: String(e.description) } : {},
|
|
2987
|
+
...e.conditions && Array.isArray(e.conditions) ? { conditions: e.conditions.map(String) } : {},
|
|
2988
|
+
actions
|
|
2989
|
+
});
|
|
2990
|
+
}
|
|
2991
|
+
return result;
|
|
2992
|
+
}
|
|
2799
2993
|
function extractDefineModelCall(programPath, compilerState, actionCounter) {
|
|
2800
2994
|
for (const node of programPath.node.body) {
|
|
2801
2995
|
if (!t11.isExportDefaultDeclaration(node)) continue;
|
|
@@ -2835,17 +3029,27 @@ function extractDefineModelCall(programPath, compilerState, actionCounter) {
|
|
|
2835
3029
|
const statesObj = config.states;
|
|
2836
3030
|
for (const [name, stateConfig] of Object.entries(statesObj)) {
|
|
2837
3031
|
const stateType = modelStateTypeToIR(stateConfig.type);
|
|
3032
|
+
const on_enter = parseActionArray(stateConfig.on_enter, actionCounter);
|
|
3033
|
+
const on_exit = parseActionArray(stateConfig.on_exit, actionCounter);
|
|
3034
|
+
const during = parseDuringArray(stateConfig.during, actionCounter);
|
|
3035
|
+
const on_event = parseOnEventArray(stateConfig.on_event, actionCounter);
|
|
2838
3036
|
if (!compilerState.states.has(name)) {
|
|
2839
3037
|
compilerState.states.set(name, {
|
|
2840
3038
|
name,
|
|
2841
3039
|
type: stateType,
|
|
2842
3040
|
description: stateConfig.description,
|
|
2843
|
-
on_enter
|
|
2844
|
-
during
|
|
2845
|
-
on_exit
|
|
3041
|
+
on_enter,
|
|
3042
|
+
during,
|
|
3043
|
+
on_exit,
|
|
3044
|
+
...on_event.length > 0 ? { on_event } : {}
|
|
2846
3045
|
});
|
|
2847
3046
|
} else {
|
|
2848
|
-
compilerState.states.get(name)
|
|
3047
|
+
const existing = compilerState.states.get(name);
|
|
3048
|
+
existing.type = stateType;
|
|
3049
|
+
if (on_enter.length > 0) existing.on_enter = on_enter;
|
|
3050
|
+
if (on_exit.length > 0) existing.on_exit = on_exit;
|
|
3051
|
+
if (during.length > 0) existing.during = during;
|
|
3052
|
+
if (on_event.length > 0) existing.on_event = on_event;
|
|
2849
3053
|
}
|
|
2850
3054
|
}
|
|
2851
3055
|
}
|
|
@@ -2883,13 +3087,21 @@ function extractDefineModelCall(programPath, compilerState, actionCounter) {
|
|
|
2883
3087
|
if (transConfig.guard) {
|
|
2884
3088
|
conditions.push(parseGuardExpression(String(transConfig.guard)));
|
|
2885
3089
|
}
|
|
3090
|
+
if (transConfig.conditions && Array.isArray(transConfig.conditions)) {
|
|
3091
|
+
for (const cond of transConfig.conditions) {
|
|
3092
|
+
if (typeof cond === "object" && cond !== null) {
|
|
3093
|
+
conditions.push(cond);
|
|
3094
|
+
}
|
|
3095
|
+
}
|
|
3096
|
+
}
|
|
3097
|
+
const actions = parseActionArray(transConfig.actions, actionCounter);
|
|
2886
3098
|
compilerState.transitions.push({
|
|
2887
3099
|
name,
|
|
2888
3100
|
from,
|
|
2889
3101
|
to,
|
|
2890
3102
|
description: transConfig.description,
|
|
2891
3103
|
conditions: conditions.length > 0 ? conditions : void 0,
|
|
2892
|
-
actions
|
|
3104
|
+
actions,
|
|
2893
3105
|
roles: transConfig.roles,
|
|
2894
3106
|
auto: transConfig.auto,
|
|
2895
3107
|
required_fields: transConfig.required_fields
|
|
@@ -3569,7 +3781,7 @@ var init_context_extractor = __esm({
|
|
|
3569
3781
|
|
|
3570
3782
|
// ../player-core/dist/index.mjs
|
|
3571
3783
|
function normalizeCategory(primary, ...tags) {
|
|
3572
|
-
const uniqueTags = [...new Set(tags.filter((
|
|
3784
|
+
const uniqueTags = [...new Set(tags.filter((t19) => t19 !== primary))];
|
|
3573
3785
|
uniqueTags.sort();
|
|
3574
3786
|
return [primary, ...uniqueTags];
|
|
3575
3787
|
}
|
|
@@ -3849,6 +4061,18 @@ function emitIR(extracted) {
|
|
|
3849
4061
|
});
|
|
3850
4062
|
stateNames.add(transition.to);
|
|
3851
4063
|
}
|
|
4064
|
+
for (const from of transition.from) {
|
|
4065
|
+
if (from && !stateNames.has(from)) {
|
|
4066
|
+
stateArray.push({
|
|
4067
|
+
name: from,
|
|
4068
|
+
type: "REGULAR",
|
|
4069
|
+
on_enter: [],
|
|
4070
|
+
during: [],
|
|
4071
|
+
on_exit: []
|
|
4072
|
+
});
|
|
4073
|
+
stateNames.add(from);
|
|
4074
|
+
}
|
|
4075
|
+
}
|
|
3852
4076
|
}
|
|
3853
4077
|
const fieldNames = new Set(fields.map((f) => f.name));
|
|
3854
4078
|
let normalizedView;
|
|
@@ -4278,16 +4502,16 @@ function emitWorkflowDefinition(extracted) {
|
|
|
4278
4502
|
...f.editable_when && { editable_when: f.editable_when },
|
|
4279
4503
|
...f.state_home && { state_home: f.state_home }
|
|
4280
4504
|
}));
|
|
4281
|
-
const transitions = ir.transitions.map((
|
|
4282
|
-
name:
|
|
4283
|
-
from:
|
|
4284
|
-
to:
|
|
4285
|
-
description:
|
|
4286
|
-
roles:
|
|
4287
|
-
auto:
|
|
4288
|
-
conditions:
|
|
4289
|
-
actions: (
|
|
4290
|
-
required_fields:
|
|
4505
|
+
const transitions = ir.transitions.map((t19) => ({
|
|
4506
|
+
name: t19.name,
|
|
4507
|
+
from: t19.from,
|
|
4508
|
+
to: t19.to,
|
|
4509
|
+
description: t19.description || "",
|
|
4510
|
+
roles: t19.roles || [],
|
|
4511
|
+
auto: t19.auto || false,
|
|
4512
|
+
conditions: t19.conditions || [],
|
|
4513
|
+
actions: (t19.actions || []).map(convertAction),
|
|
4514
|
+
required_fields: t19.required_fields || [],
|
|
4291
4515
|
priority: 0
|
|
4292
4516
|
}));
|
|
4293
4517
|
const state_data = {};
|
|
@@ -4823,7 +5047,7 @@ function createVisitor(options = {}) {
|
|
|
4823
5047
|
}
|
|
4824
5048
|
}
|
|
4825
5049
|
if (mode !== "strict") return;
|
|
4826
|
-
if (source.startsWith("@mindmatrix/") || source === "react" || source.startsWith("react/") || source.startsWith(".") || source.startsWith("/")) {
|
|
5050
|
+
if (source.startsWith("@mindmatrix/") || source.startsWith("@mmapp/") || source === "react" || source.startsWith("react/") || source.startsWith(".") || source.startsWith("/")) {
|
|
4827
5051
|
return;
|
|
4828
5052
|
}
|
|
4829
5053
|
const error = {
|
|
@@ -5237,7 +5461,7 @@ function compileModel(filename, source, options = {}) {
|
|
|
5237
5461
|
ir,
|
|
5238
5462
|
interfaceName,
|
|
5239
5463
|
fieldNames: ir.fields.map((f) => f.name),
|
|
5240
|
-
transitionNames: ir.transitions.map((
|
|
5464
|
+
transitionNames: ir.transitions.map((t19) => t19.name),
|
|
5241
5465
|
stateNames: ir.states.map((s) => s.name),
|
|
5242
5466
|
hasFieldOptions: Object.keys(rawFieldOptions).length > 0,
|
|
5243
5467
|
fieldOptions: rawFieldOptions
|
|
@@ -5637,6 +5861,520 @@ var init_action_compiler = __esm({
|
|
|
5637
5861
|
}
|
|
5638
5862
|
});
|
|
5639
5863
|
|
|
5864
|
+
// src/babel/extractors/action-extractor.ts
|
|
5865
|
+
function extractAction(source, filename) {
|
|
5866
|
+
let ast;
|
|
5867
|
+
try {
|
|
5868
|
+
ast = (0, import_parser.parse)(source, {
|
|
5869
|
+
sourceType: "module",
|
|
5870
|
+
plugins: ["typescript"],
|
|
5871
|
+
strictMode: false
|
|
5872
|
+
});
|
|
5873
|
+
} catch {
|
|
5874
|
+
return null;
|
|
5875
|
+
}
|
|
5876
|
+
const result = findDefaultExportedFunction(ast);
|
|
5877
|
+
if (!result) return null;
|
|
5878
|
+
const { name, params, body, returnTypeAnnotation, isAsync } = result;
|
|
5879
|
+
const slug = toKebabCase(name);
|
|
5880
|
+
const warnings = [];
|
|
5881
|
+
const fields = params.map((p) => paramToField(p));
|
|
5882
|
+
const parameterMap = /* @__PURE__ */ new Map();
|
|
5883
|
+
for (const p of params) {
|
|
5884
|
+
const snakeName = toSnakeCase3(p.name);
|
|
5885
|
+
if (snakeName !== p.name) {
|
|
5886
|
+
parameterMap.set(p.name, snakeName);
|
|
5887
|
+
}
|
|
5888
|
+
}
|
|
5889
|
+
const humanName = name.replace(/([A-Z])/g, " $1").replace(/^./, (s) => s.toUpperCase()).trim();
|
|
5890
|
+
const metadata = {
|
|
5891
|
+
source_file: filename,
|
|
5892
|
+
source_function: name,
|
|
5893
|
+
provenance: {
|
|
5894
|
+
frontend: "react-compiler",
|
|
5895
|
+
source: "action-extractor",
|
|
5896
|
+
compiler_version: "2.0.0"
|
|
5897
|
+
}
|
|
5898
|
+
};
|
|
5899
|
+
if (returnTypeAnnotation) {
|
|
5900
|
+
metadata.return_type = returnTypeAnnotation;
|
|
5901
|
+
}
|
|
5902
|
+
if (isAsync) {
|
|
5903
|
+
const segments = splitAtAwaits(body.body);
|
|
5904
|
+
const hasAwaits = segments.some((s) => s.kind === "await");
|
|
5905
|
+
if (hasAwaits) {
|
|
5906
|
+
const rewritten = rewriteAwaitReferences(segments);
|
|
5907
|
+
const { states: states2, transitions: transitions2, bodyIsPure } = generateMultiStateIR(rewritten, warnings, parameterMap);
|
|
5908
|
+
if (!bodyIsPure) {
|
|
5909
|
+
warnings.push(`Async action '${name}' body contains untranslatable JS \u2014 wrapped in $expr() markers`);
|
|
5910
|
+
}
|
|
5911
|
+
const ir2 = {
|
|
5912
|
+
slug,
|
|
5913
|
+
name: humanName,
|
|
5914
|
+
version: "0.1.0",
|
|
5915
|
+
category: "action",
|
|
5916
|
+
fields,
|
|
5917
|
+
states: states2,
|
|
5918
|
+
transitions: transitions2,
|
|
5919
|
+
roles: [],
|
|
5920
|
+
metadata: { ...metadata, async: true }
|
|
5921
|
+
};
|
|
5922
|
+
return { ir: ir2, bodyIsPure, warnings };
|
|
5923
|
+
}
|
|
5924
|
+
}
|
|
5925
|
+
const transpileResult = transpileBlock(body, { allMutable: true, parameterMap });
|
|
5926
|
+
const bodyExpr = transpileResult.expression;
|
|
5927
|
+
if (!transpileResult.pure) {
|
|
5928
|
+
warnings.push(`Action '${name}' body contains untranslatable JS \u2014 wrapped in $expr() markers`);
|
|
5929
|
+
}
|
|
5930
|
+
const states = [
|
|
5931
|
+
{
|
|
5932
|
+
name: "ready",
|
|
5933
|
+
type: "START",
|
|
5934
|
+
on_enter: [],
|
|
5935
|
+
during: [],
|
|
5936
|
+
on_exit: []
|
|
5937
|
+
},
|
|
5938
|
+
{
|
|
5939
|
+
name: "done",
|
|
5940
|
+
type: "END",
|
|
5941
|
+
on_enter: [],
|
|
5942
|
+
during: [],
|
|
5943
|
+
on_exit: []
|
|
5944
|
+
}
|
|
5945
|
+
];
|
|
5946
|
+
const transitions = [
|
|
5947
|
+
{
|
|
5948
|
+
name: "execute",
|
|
5949
|
+
from: ["ready"],
|
|
5950
|
+
to: "done",
|
|
5951
|
+
actions: [
|
|
5952
|
+
{
|
|
5953
|
+
id: "body",
|
|
5954
|
+
type: "eval",
|
|
5955
|
+
mode: "auto",
|
|
5956
|
+
config: {
|
|
5957
|
+
expression: bodyExpr
|
|
5958
|
+
}
|
|
5959
|
+
}
|
|
5960
|
+
]
|
|
5961
|
+
}
|
|
5962
|
+
];
|
|
5963
|
+
const ir = {
|
|
5964
|
+
slug,
|
|
5965
|
+
name: humanName,
|
|
5966
|
+
version: "0.1.0",
|
|
5967
|
+
category: "action",
|
|
5968
|
+
fields,
|
|
5969
|
+
states,
|
|
5970
|
+
transitions,
|
|
5971
|
+
roles: [],
|
|
5972
|
+
metadata
|
|
5973
|
+
};
|
|
5974
|
+
return { ir, bodyIsPure: transpileResult.pure, warnings };
|
|
5975
|
+
}
|
|
5976
|
+
function findDefaultExportedFunction(ast) {
|
|
5977
|
+
const topLevelVars = /* @__PURE__ */ new Map();
|
|
5978
|
+
for (const node of ast.program.body) {
|
|
5979
|
+
if (t18.isVariableDeclaration(node)) {
|
|
5980
|
+
for (const decl of node.declarations) {
|
|
5981
|
+
if (t18.isIdentifier(decl.id) && decl.init) {
|
|
5982
|
+
if (t18.isArrowFunctionExpression(decl.init) || t18.isFunctionExpression(decl.init)) {
|
|
5983
|
+
topLevelVars.set(decl.id.name, decl.init);
|
|
5984
|
+
}
|
|
5985
|
+
}
|
|
5986
|
+
}
|
|
5987
|
+
}
|
|
5988
|
+
}
|
|
5989
|
+
for (const node of ast.program.body) {
|
|
5990
|
+
if (t18.isExportDefaultDeclaration(node)) {
|
|
5991
|
+
const decl = node.declaration;
|
|
5992
|
+
if (t18.isFunctionDeclaration(decl) && decl.body) {
|
|
5993
|
+
const name = decl.id?.name ?? inferNameFromFile(decl) ?? "action";
|
|
5994
|
+
return extractFromFunction(name, decl.params, decl.body, decl.returnType, decl.async);
|
|
5995
|
+
}
|
|
5996
|
+
if (t18.isArrowFunctionExpression(decl) || t18.isFunctionExpression(decl)) {
|
|
5997
|
+
const name = t18.isFunctionExpression(decl) && decl.id ? decl.id.name : "action";
|
|
5998
|
+
const body = ensureBlock(decl.body);
|
|
5999
|
+
if (!body) return null;
|
|
6000
|
+
return extractFromFunction(name, decl.params, body, decl.returnType, decl.async);
|
|
6001
|
+
}
|
|
6002
|
+
if (t18.isIdentifier(decl)) {
|
|
6003
|
+
const fn = topLevelVars.get(decl.name);
|
|
6004
|
+
if (fn) {
|
|
6005
|
+
const body = ensureBlock(fn.body);
|
|
6006
|
+
if (!body) return null;
|
|
6007
|
+
return extractFromFunction(decl.name, fn.params, body, fn.returnType, fn.async);
|
|
6008
|
+
}
|
|
6009
|
+
}
|
|
6010
|
+
}
|
|
6011
|
+
}
|
|
6012
|
+
return null;
|
|
6013
|
+
}
|
|
6014
|
+
function extractFromFunction(name, params, body, returnType, isAsync = false) {
|
|
6015
|
+
const extracted = params.map((p) => extractParam(p));
|
|
6016
|
+
const returnTypeAnnotation = returnType && t18.isTSTypeAnnotation(returnType) ? serializeTSType(returnType.typeAnnotation) : void 0;
|
|
6017
|
+
return { name, params: extracted, body, returnTypeAnnotation, isAsync };
|
|
6018
|
+
}
|
|
6019
|
+
function ensureBlock(body) {
|
|
6020
|
+
if (t18.isBlockStatement(body)) return body;
|
|
6021
|
+
const ret = t18.returnStatement(body);
|
|
6022
|
+
return t18.blockStatement([ret]);
|
|
6023
|
+
}
|
|
6024
|
+
function inferNameFromFile(_node) {
|
|
6025
|
+
return null;
|
|
6026
|
+
}
|
|
6027
|
+
function extractParam(param) {
|
|
6028
|
+
if (t18.isIdentifier(param)) {
|
|
6029
|
+
return {
|
|
6030
|
+
name: param.name,
|
|
6031
|
+
typeAnnotation: param.typeAnnotation ? param.typeAnnotation.typeAnnotation : null,
|
|
6032
|
+
optional: param.optional ?? false
|
|
6033
|
+
};
|
|
6034
|
+
}
|
|
6035
|
+
if (t18.isAssignmentPattern(param)) {
|
|
6036
|
+
const inner = param.left;
|
|
6037
|
+
if (t18.isIdentifier(inner)) {
|
|
6038
|
+
return {
|
|
6039
|
+
name: inner.name,
|
|
6040
|
+
typeAnnotation: inner.typeAnnotation ? inner.typeAnnotation.typeAnnotation : null,
|
|
6041
|
+
optional: true,
|
|
6042
|
+
defaultValue: param.right
|
|
6043
|
+
};
|
|
6044
|
+
}
|
|
6045
|
+
}
|
|
6046
|
+
if (t18.isRestElement(param)) {
|
|
6047
|
+
const arg = param.argument;
|
|
6048
|
+
return {
|
|
6049
|
+
name: t18.isIdentifier(arg) ? arg.name : "rest",
|
|
6050
|
+
typeAnnotation: null,
|
|
6051
|
+
optional: true
|
|
6052
|
+
};
|
|
6053
|
+
}
|
|
6054
|
+
return { name: "params", typeAnnotation: null, optional: false };
|
|
6055
|
+
}
|
|
6056
|
+
function paramToField(param) {
|
|
6057
|
+
const fieldType = param.typeAnnotation ? tsTypeToFieldType2(param.typeAnnotation) : "text";
|
|
6058
|
+
const field = {
|
|
6059
|
+
name: toSnakeCase3(param.name),
|
|
6060
|
+
type: fieldType,
|
|
6061
|
+
required: !param.optional
|
|
6062
|
+
};
|
|
6063
|
+
if (param.defaultValue !== void 0) {
|
|
6064
|
+
field.default_value = extractLiteralDefault(param.defaultValue);
|
|
6065
|
+
}
|
|
6066
|
+
return field;
|
|
6067
|
+
}
|
|
6068
|
+
function extractLiteralDefault(expr) {
|
|
6069
|
+
if (!expr) return void 0;
|
|
6070
|
+
if (t18.isStringLiteral(expr)) return expr.value;
|
|
6071
|
+
if (t18.isNumericLiteral(expr)) return expr.value;
|
|
6072
|
+
if (t18.isBooleanLiteral(expr)) return expr.value;
|
|
6073
|
+
if (t18.isNullLiteral(expr)) return null;
|
|
6074
|
+
if (t18.isArrayExpression(expr) && expr.elements.length === 0) return [];
|
|
6075
|
+
if (t18.isObjectExpression(expr) && expr.properties.length === 0) return {};
|
|
6076
|
+
return void 0;
|
|
6077
|
+
}
|
|
6078
|
+
function tsTypeToFieldType2(tsType) {
|
|
6079
|
+
if (t18.isTSStringKeyword(tsType)) return "text";
|
|
6080
|
+
if (t18.isTSNumberKeyword(tsType)) return "number";
|
|
6081
|
+
if (t18.isTSBooleanKeyword(tsType)) return "boolean";
|
|
6082
|
+
if (t18.isTSObjectKeyword(tsType)) return "json";
|
|
6083
|
+
if (t18.isTSAnyKeyword(tsType) || t18.isTSUnknownKeyword(tsType)) return "json";
|
|
6084
|
+
if (t18.isTSArrayType(tsType)) return "json";
|
|
6085
|
+
if (t18.isTSUnionType(tsType)) {
|
|
6086
|
+
const nonNullable = tsType.types.filter(
|
|
6087
|
+
(t22) => !t18.isTSNullKeyword(t22) && !t18.isTSUndefinedKeyword(t22)
|
|
6088
|
+
);
|
|
6089
|
+
if (nonNullable.length === 1) {
|
|
6090
|
+
return tsTypeToFieldType2(nonNullable[0]);
|
|
6091
|
+
}
|
|
6092
|
+
if (nonNullable.every((t22) => t18.isTSLiteralType(t22) && t18.isStringLiteral(t22.literal))) {
|
|
6093
|
+
return "select";
|
|
6094
|
+
}
|
|
6095
|
+
return "text";
|
|
6096
|
+
}
|
|
6097
|
+
if (t18.isTSTypeReference(tsType) && t18.isIdentifier(tsType.typeName)) {
|
|
6098
|
+
const name = tsType.typeName.name;
|
|
6099
|
+
if (name === "Date") return "datetime";
|
|
6100
|
+
if (name === "string") return "text";
|
|
6101
|
+
if (name === "number") return "number";
|
|
6102
|
+
if (name === "boolean") return "boolean";
|
|
6103
|
+
}
|
|
6104
|
+
return "text";
|
|
6105
|
+
}
|
|
6106
|
+
function serializeTSType(tsType) {
|
|
6107
|
+
if (t18.isTSStringKeyword(tsType)) return "string";
|
|
6108
|
+
if (t18.isTSNumberKeyword(tsType)) return "number";
|
|
6109
|
+
if (t18.isTSBooleanKeyword(tsType)) return "boolean";
|
|
6110
|
+
if (t18.isTSVoidKeyword(tsType)) return "void";
|
|
6111
|
+
if (t18.isTSAnyKeyword(tsType)) return "any";
|
|
6112
|
+
if (t18.isTSTypeReference(tsType) && t18.isIdentifier(tsType.typeName)) {
|
|
6113
|
+
return tsType.typeName.name;
|
|
6114
|
+
}
|
|
6115
|
+
if (t18.isTSArrayType(tsType)) return `${serializeTSType(tsType.elementType)}[]`;
|
|
6116
|
+
if (t18.isTSPromiseType(tsType)) {
|
|
6117
|
+
return `Promise<${tsType.typeParameter ? serializeTSType(tsType.typeParameter.params[0]) : "unknown"}>`;
|
|
6118
|
+
}
|
|
6119
|
+
return "unknown";
|
|
6120
|
+
}
|
|
6121
|
+
function splitAtAwaits(body) {
|
|
6122
|
+
const segments = [];
|
|
6123
|
+
let current = [];
|
|
6124
|
+
let index = 0;
|
|
6125
|
+
for (const stmt of body) {
|
|
6126
|
+
const awaitInfo = extractAwait(stmt);
|
|
6127
|
+
if (!awaitInfo) {
|
|
6128
|
+
current.push(stmt);
|
|
6129
|
+
continue;
|
|
6130
|
+
}
|
|
6131
|
+
if (current.length > 0) {
|
|
6132
|
+
segments.push({ index: index++, kind: "sync", statements: current });
|
|
6133
|
+
current = [];
|
|
6134
|
+
}
|
|
6135
|
+
segments.push({
|
|
6136
|
+
index: index++,
|
|
6137
|
+
kind: "await",
|
|
6138
|
+
statements: [stmt],
|
|
6139
|
+
awaitTarget: awaitInfo.callee,
|
|
6140
|
+
awaitArgs: awaitInfo.args,
|
|
6141
|
+
resultBinding: awaitInfo.binding
|
|
6142
|
+
});
|
|
6143
|
+
}
|
|
6144
|
+
if (current.length > 0) {
|
|
6145
|
+
segments.push({ index: index++, kind: "sync", statements: current });
|
|
6146
|
+
}
|
|
6147
|
+
return segments;
|
|
6148
|
+
}
|
|
6149
|
+
function extractAwait(stmt) {
|
|
6150
|
+
if (t18.isVariableDeclaration(stmt)) {
|
|
6151
|
+
const decl = stmt.declarations[0];
|
|
6152
|
+
if (decl?.init && t18.isAwaitExpression(decl.init)) {
|
|
6153
|
+
const arg = decl.init.argument;
|
|
6154
|
+
if (t18.isCallExpression(arg)) {
|
|
6155
|
+
return {
|
|
6156
|
+
callee: getCalleeName(arg.callee),
|
|
6157
|
+
args: arg.arguments,
|
|
6158
|
+
binding: t18.isIdentifier(decl.id) ? decl.id.name : void 0
|
|
6159
|
+
};
|
|
6160
|
+
}
|
|
6161
|
+
}
|
|
6162
|
+
}
|
|
6163
|
+
if (t18.isExpressionStatement(stmt) && t18.isAwaitExpression(stmt.expression)) {
|
|
6164
|
+
const arg = stmt.expression.argument;
|
|
6165
|
+
if (t18.isCallExpression(arg)) {
|
|
6166
|
+
return {
|
|
6167
|
+
callee: getCalleeName(arg.callee),
|
|
6168
|
+
args: arg.arguments,
|
|
6169
|
+
binding: void 0
|
|
6170
|
+
};
|
|
6171
|
+
}
|
|
6172
|
+
}
|
|
6173
|
+
if (t18.isReturnStatement(stmt) && stmt.argument && t18.isAwaitExpression(stmt.argument)) {
|
|
6174
|
+
const arg = stmt.argument.argument;
|
|
6175
|
+
if (t18.isCallExpression(arg)) {
|
|
6176
|
+
return {
|
|
6177
|
+
callee: getCalleeName(arg.callee),
|
|
6178
|
+
args: arg.arguments,
|
|
6179
|
+
binding: void 0
|
|
6180
|
+
};
|
|
6181
|
+
}
|
|
6182
|
+
}
|
|
6183
|
+
return null;
|
|
6184
|
+
}
|
|
6185
|
+
function getCalleeName(callee) {
|
|
6186
|
+
if (t18.isIdentifier(callee)) return callee.name;
|
|
6187
|
+
if (t18.isMemberExpression(callee) && t18.isIdentifier(callee.object) && t18.isIdentifier(callee.property)) {
|
|
6188
|
+
return `${callee.object.name}_${callee.property.name}`;
|
|
6189
|
+
}
|
|
6190
|
+
return "unknown_action";
|
|
6191
|
+
}
|
|
6192
|
+
function rewriteAwaitReferences(segments) {
|
|
6193
|
+
const bindings = /* @__PURE__ */ new Map();
|
|
6194
|
+
const slugCounts = /* @__PURE__ */ new Map();
|
|
6195
|
+
return segments.map((seg) => {
|
|
6196
|
+
if (seg.kind === "await" && seg.resultBinding) {
|
|
6197
|
+
const slug = toSnakeCase3(seg.awaitTarget ?? "unknown");
|
|
6198
|
+
const count = (slugCounts.get(slug) ?? 0) + 1;
|
|
6199
|
+
slugCounts.set(slug, count);
|
|
6200
|
+
const key = count > 1 ? `${slug}_${count}` : slug;
|
|
6201
|
+
bindings.set(seg.resultBinding, `action_results.${key}`);
|
|
6202
|
+
}
|
|
6203
|
+
if (seg.kind === "sync" && bindings.size > 0) {
|
|
6204
|
+
return {
|
|
6205
|
+
...seg,
|
|
6206
|
+
statements: seg.statements.map(
|
|
6207
|
+
(stmt) => rewriteIdentifiersInStatement(stmt, bindings)
|
|
6208
|
+
)
|
|
6209
|
+
};
|
|
6210
|
+
}
|
|
6211
|
+
return seg;
|
|
6212
|
+
});
|
|
6213
|
+
}
|
|
6214
|
+
function rewriteIdentifiersInStatement(stmt, _bindings) {
|
|
6215
|
+
return stmt;
|
|
6216
|
+
}
|
|
6217
|
+
function generateMultiStateIR(segments, _warnings, parameterMap) {
|
|
6218
|
+
const states = [];
|
|
6219
|
+
const transitions = [];
|
|
6220
|
+
let bodyIsPure = true;
|
|
6221
|
+
const awaitBindings = /* @__PURE__ */ new Map();
|
|
6222
|
+
const slugCounts = /* @__PURE__ */ new Map();
|
|
6223
|
+
for (const seg of segments) {
|
|
6224
|
+
if (seg.kind === "await" && seg.resultBinding) {
|
|
6225
|
+
const slug = toSnakeCase3(seg.awaitTarget ?? "unknown");
|
|
6226
|
+
const count = (slugCounts.get(slug) ?? 0) + 1;
|
|
6227
|
+
slugCounts.set(slug, count);
|
|
6228
|
+
const key = count > 1 ? `${slug}_${count}` : slug;
|
|
6229
|
+
awaitBindings.set(seg.resultBinding, `action_results.${key}`);
|
|
6230
|
+
}
|
|
6231
|
+
}
|
|
6232
|
+
states.push({ name: "ready", type: "START", on_enter: [], during: [], on_exit: [] });
|
|
6233
|
+
const usedStateNames = /* @__PURE__ */ new Set();
|
|
6234
|
+
let prevState = "ready";
|
|
6235
|
+
let transitionCount = 0;
|
|
6236
|
+
let pendingSyncStmts = [];
|
|
6237
|
+
for (const seg of segments) {
|
|
6238
|
+
if (seg.kind === "sync") {
|
|
6239
|
+
pendingSyncStmts.push(...seg.statements);
|
|
6240
|
+
continue;
|
|
6241
|
+
}
|
|
6242
|
+
const targetSlug = toSnakeCase3(seg.awaitTarget ?? "unknown");
|
|
6243
|
+
let stateName = `awaiting_${targetSlug}`;
|
|
6244
|
+
if (usedStateNames.has(stateName)) {
|
|
6245
|
+
let suffix = 2;
|
|
6246
|
+
while (usedStateNames.has(`${stateName}_${suffix}`)) suffix++;
|
|
6247
|
+
stateName = `${stateName}_${suffix}`;
|
|
6248
|
+
}
|
|
6249
|
+
usedStateNames.add(stateName);
|
|
6250
|
+
states.push({ name: stateName, type: "REGULAR", on_enter: [], during: [], on_exit: [] });
|
|
6251
|
+
const actions = [];
|
|
6252
|
+
if (pendingSyncStmts.length > 0) {
|
|
6253
|
+
const block = t18.blockStatement(pendingSyncStmts);
|
|
6254
|
+
const transpiled = transpileBlock(block, {
|
|
6255
|
+
allMutable: true,
|
|
6256
|
+
derivedVarMap: buildDerivedVarMap(awaitBindings),
|
|
6257
|
+
parameterMap
|
|
6258
|
+
});
|
|
6259
|
+
if (!transpiled.pure) bodyIsPure = false;
|
|
6260
|
+
actions.push({
|
|
6261
|
+
id: `pre_${transitionCount}`,
|
|
6262
|
+
type: "eval",
|
|
6263
|
+
mode: "auto",
|
|
6264
|
+
config: { expression: transpiled.expression }
|
|
6265
|
+
});
|
|
6266
|
+
pendingSyncStmts = [];
|
|
6267
|
+
}
|
|
6268
|
+
const callConfig = {
|
|
6269
|
+
definition_slug: seg.awaitTarget,
|
|
6270
|
+
result_key: targetSlug
|
|
6271
|
+
};
|
|
6272
|
+
if (seg.awaitArgs && seg.awaitArgs.length > 0) {
|
|
6273
|
+
const params = {};
|
|
6274
|
+
for (let i = 0; i < seg.awaitArgs.length; i++) {
|
|
6275
|
+
const arg = seg.awaitArgs[i];
|
|
6276
|
+
if (t18.isObjectExpression(arg)) {
|
|
6277
|
+
for (const prop of arg.properties) {
|
|
6278
|
+
if (t18.isObjectProperty(prop) && t18.isIdentifier(prop.key)) {
|
|
6279
|
+
const { expression: valExpr } = transpileArgExpression(prop.value, awaitBindings);
|
|
6280
|
+
params[prop.key.name] = valExpr;
|
|
6281
|
+
}
|
|
6282
|
+
}
|
|
6283
|
+
} else {
|
|
6284
|
+
const { expression: valExpr } = transpileArgExpression(arg, awaitBindings);
|
|
6285
|
+
params[`arg${i}`] = valExpr;
|
|
6286
|
+
}
|
|
6287
|
+
}
|
|
6288
|
+
if (Object.keys(params).length > 0) {
|
|
6289
|
+
callConfig.params = params;
|
|
6290
|
+
}
|
|
6291
|
+
}
|
|
6292
|
+
actions.push({
|
|
6293
|
+
id: `call_${targetSlug}`,
|
|
6294
|
+
type: "call_workflow",
|
|
6295
|
+
mode: "auto",
|
|
6296
|
+
config: callConfig
|
|
6297
|
+
});
|
|
6298
|
+
const transName = transitionCount === 0 ? "execute" : `on_${getStateSuffix(prevState)}_complete`;
|
|
6299
|
+
transitions.push({
|
|
6300
|
+
name: transName,
|
|
6301
|
+
from: [prevState],
|
|
6302
|
+
to: stateName,
|
|
6303
|
+
actions
|
|
6304
|
+
});
|
|
6305
|
+
prevState = stateName;
|
|
6306
|
+
transitionCount++;
|
|
6307
|
+
}
|
|
6308
|
+
states.push({ name: "done", type: "END", on_enter: [], during: [], on_exit: [] });
|
|
6309
|
+
const finalActions = [];
|
|
6310
|
+
if (pendingSyncStmts.length > 0) {
|
|
6311
|
+
const block = t18.blockStatement(pendingSyncStmts);
|
|
6312
|
+
const transpiled = transpileBlock(block, {
|
|
6313
|
+
allMutable: true,
|
|
6314
|
+
derivedVarMap: buildDerivedVarMap(awaitBindings),
|
|
6315
|
+
parameterMap
|
|
6316
|
+
});
|
|
6317
|
+
if (!transpiled.pure) bodyIsPure = false;
|
|
6318
|
+
finalActions.push({
|
|
6319
|
+
id: "post_final",
|
|
6320
|
+
type: "eval",
|
|
6321
|
+
mode: "auto",
|
|
6322
|
+
config: { expression: transpiled.expression }
|
|
6323
|
+
});
|
|
6324
|
+
}
|
|
6325
|
+
const finalTransName = transitionCount === 0 ? "execute" : `on_${getStateSuffix(prevState)}_complete`;
|
|
6326
|
+
transitions.push({
|
|
6327
|
+
name: finalTransName,
|
|
6328
|
+
from: [prevState],
|
|
6329
|
+
to: "done",
|
|
6330
|
+
actions: finalActions
|
|
6331
|
+
});
|
|
6332
|
+
return { states, transitions, bodyIsPure };
|
|
6333
|
+
}
|
|
6334
|
+
function getStateSuffix(stateName) {
|
|
6335
|
+
return stateName.replace(/^awaiting_/, "");
|
|
6336
|
+
}
|
|
6337
|
+
function transpileArgExpression(expr, bindings) {
|
|
6338
|
+
if (t18.isIdentifier(expr)) {
|
|
6339
|
+
const replacement = bindings.get(expr.name);
|
|
6340
|
+
if (replacement) return { expression: replacement };
|
|
6341
|
+
return { expression: `state_data.${toSnakeCase3(expr.name)}` };
|
|
6342
|
+
}
|
|
6343
|
+
if (t18.isMemberExpression(expr) && t18.isIdentifier(expr.object)) {
|
|
6344
|
+
const replacement = bindings.get(expr.object.name);
|
|
6345
|
+
if (replacement && t18.isIdentifier(expr.property)) {
|
|
6346
|
+
return { expression: `${replacement}.${expr.property.name}` };
|
|
6347
|
+
}
|
|
6348
|
+
}
|
|
6349
|
+
if (t18.isStringLiteral(expr)) return { expression: `'${expr.value}'` };
|
|
6350
|
+
if (t18.isNumericLiteral(expr)) return { expression: String(expr.value) };
|
|
6351
|
+
if (t18.isBooleanLiteral(expr)) return { expression: String(expr.value) };
|
|
6352
|
+
const { transpile: transpile2 } = (init_ts_to_expression(), __toCommonJS(ts_to_expression_exports));
|
|
6353
|
+
return { expression: transpile2(expr, { derivedVarMap: buildDerivedVarMap(bindings) }) };
|
|
6354
|
+
}
|
|
6355
|
+
function buildDerivedVarMap(bindings) {
|
|
6356
|
+
const map = /* @__PURE__ */ new Map();
|
|
6357
|
+
for (const [varName, path] of bindings) {
|
|
6358
|
+
map.set(varName, t18.identifier(path));
|
|
6359
|
+
}
|
|
6360
|
+
return map;
|
|
6361
|
+
}
|
|
6362
|
+
function toKebabCase(name) {
|
|
6363
|
+
return name.replace(/([A-Z])/g, "-$1").toLowerCase().replace(/^-/, "");
|
|
6364
|
+
}
|
|
6365
|
+
function toSnakeCase3(name) {
|
|
6366
|
+
return name.replace(/([A-Z])/g, "_$1").toLowerCase().replace(/^_/, "");
|
|
6367
|
+
}
|
|
6368
|
+
var import_parser, t18;
|
|
6369
|
+
var init_action_extractor = __esm({
|
|
6370
|
+
"src/babel/extractors/action-extractor.ts"() {
|
|
6371
|
+
"use strict";
|
|
6372
|
+
import_parser = require("@babel/parser");
|
|
6373
|
+
t18 = __toESM(require("@babel/types"));
|
|
6374
|
+
init_ts_to_expression();
|
|
6375
|
+
}
|
|
6376
|
+
});
|
|
6377
|
+
|
|
5640
6378
|
// src/incremental-compiler.ts
|
|
5641
6379
|
function hashContent(content) {
|
|
5642
6380
|
let hash = 5381;
|
|
@@ -5990,24 +6728,56 @@ function parseModuleManifest(source) {
|
|
|
5990
6728
|
}
|
|
5991
6729
|
if (contributions.length > 0) manifest.contributions = contributions;
|
|
5992
6730
|
}
|
|
6731
|
+
const configSchemaBlock = extractObjectBlock(source, "configSchema");
|
|
6732
|
+
if (configSchemaBlock) {
|
|
6733
|
+
const configSchema = {};
|
|
6734
|
+
const modelSlugMatch = configSchemaBlock.match(/modelSlug:\s*['"]([^'"]+)['"]/);
|
|
6735
|
+
if (modelSlugMatch) configSchema.modelSlug = modelSlugMatch[1];
|
|
6736
|
+
const defaultsBlock = extractObjectBlock(configSchemaBlock, "defaults");
|
|
6737
|
+
if (defaultsBlock) {
|
|
6738
|
+
const defaults = {};
|
|
6739
|
+
const kvRegex = /(\w+):\s*(?:'([^']*)'|"([^"]*)"|(\d+(?:\.\d+)?)|(\btrue\b|\bfalse\b))/g;
|
|
6740
|
+
let kv;
|
|
6741
|
+
while ((kv = kvRegex.exec(defaultsBlock)) !== null) {
|
|
6742
|
+
const key = kv[1];
|
|
6743
|
+
const val = kv[2] ?? kv[3] ?? (kv[4] !== void 0 ? Number(kv[4]) : kv[5] === "true");
|
|
6744
|
+
defaults[key] = val;
|
|
6745
|
+
}
|
|
6746
|
+
configSchema.defaults = defaults;
|
|
6747
|
+
}
|
|
6748
|
+
manifest.configSchema = configSchema;
|
|
6749
|
+
}
|
|
5993
6750
|
const depsBlock = extractArrayBlock(source, "dependencies");
|
|
5994
6751
|
if (depsBlock) {
|
|
5995
6752
|
const dependencies = [];
|
|
5996
|
-
const
|
|
5997
|
-
|
|
5998
|
-
|
|
5999
|
-
|
|
6000
|
-
const
|
|
6753
|
+
const depBlocks = extractNestedObjects(depsBlock);
|
|
6754
|
+
for (const block of depBlocks) {
|
|
6755
|
+
const slugMatch = block.match(/slug:\s*['"]([^'"]+)['"]/);
|
|
6756
|
+
if (!slugMatch) continue;
|
|
6757
|
+
const entry = { slug: slugMatch[1] };
|
|
6758
|
+
const verMatch = block.match(/version:\s*['"]([^'"]+)['"]/);
|
|
6001
6759
|
if (verMatch) entry.version = verMatch[1];
|
|
6002
|
-
const reqMatch =
|
|
6760
|
+
const reqMatch = block.match(/required:\s*(true|false)/);
|
|
6003
6761
|
if (reqMatch) entry.required = reqMatch[1] === "true";
|
|
6004
|
-
const prefixMatch =
|
|
6762
|
+
const prefixMatch = block.match(/prefix:\s*['"]([^'"]+)['"]/);
|
|
6005
6763
|
if (prefixMatch) entry.routeConfig = { prefix: prefixMatch[1] };
|
|
6764
|
+
const configBlock = extractObjectBlock(block, "config");
|
|
6765
|
+
if (configBlock) {
|
|
6766
|
+
const config = {};
|
|
6767
|
+
const kvRegex = /(\w+):\s*(?:'([^']*)'|"([^"]*)"|(\d+(?:\.\d+)?)|(\btrue\b|\bfalse\b))/g;
|
|
6768
|
+
let kv;
|
|
6769
|
+
while ((kv = kvRegex.exec(configBlock)) !== null) {
|
|
6770
|
+
const key = kv[1];
|
|
6771
|
+
const val = kv[2] ?? kv[3] ?? (kv[4] !== void 0 ? Number(kv[4]) : kv[5] === "true");
|
|
6772
|
+
config[key] = val;
|
|
6773
|
+
}
|
|
6774
|
+
if (Object.keys(config).length > 0) entry.config = config;
|
|
6775
|
+
}
|
|
6006
6776
|
dependencies.push(entry);
|
|
6007
6777
|
}
|
|
6008
6778
|
if (dependencies.length > 0) manifest.dependencies = dependencies;
|
|
6009
6779
|
}
|
|
6010
|
-
const hasRichFields = manifest.routes || manifest.actions || manifest.contributions || manifest.capabilities || manifest.dependencies;
|
|
6780
|
+
const hasRichFields = manifest.routes || manifest.actions || manifest.contributions || manifest.capabilities || manifest.dependencies || manifest.configSchema;
|
|
6011
6781
|
return hasRichFields ? manifest : null;
|
|
6012
6782
|
}
|
|
6013
6783
|
function parseDependencyRouteConfigs(files) {
|
|
@@ -6103,6 +6873,9 @@ function isModelFile2(filename) {
|
|
|
6103
6873
|
function isServerActionFile2(filename) {
|
|
6104
6874
|
return /\.server\.(ts|tsx)$/.test(filename);
|
|
6105
6875
|
}
|
|
6876
|
+
function isActionFile(filename) {
|
|
6877
|
+
return /^actions\/.*\.(ts|tsx)$/.test(filename) && !filename.endsWith(".server.ts") && !filename.endsWith(".test.ts") && !filename.endsWith(".test.tsx");
|
|
6878
|
+
}
|
|
6106
6879
|
function isComponentFile(filename) {
|
|
6107
6880
|
return /components\/.*\.(tsx?|jsx?)$/.test(filename) && !filename.endsWith(".test.ts") && !filename.endsWith(".test.tsx");
|
|
6108
6881
|
}
|
|
@@ -6119,7 +6892,7 @@ function isModuleManifestFile(filename) {
|
|
|
6119
6892
|
return /mm\.module\.(ts|tsx|js)$/.test(filename);
|
|
6120
6893
|
}
|
|
6121
6894
|
function isCompilableFile(filename) {
|
|
6122
|
-
return isWorkflowFile(filename) || isModelFile2(filename) || isServerActionFile2(filename) || isPageFile2(filename) || isComponentFile(filename);
|
|
6895
|
+
return isWorkflowFile(filename) || isModelFile2(filename) || isServerActionFile2(filename) || isActionFile(filename) || isPageFile2(filename) || isComponentFile(filename);
|
|
6123
6896
|
}
|
|
6124
6897
|
function compileFile(filename, source, mode) {
|
|
6125
6898
|
const errors = [];
|
|
@@ -6401,10 +7174,87 @@ function extractComponentProps(source) {
|
|
|
6401
7174
|
if (!match) return [];
|
|
6402
7175
|
return match[1].split(",").map((p) => p.trim().split(/[\s=:]/)[0].replace(/^\.{3}/, "").trim()).filter(Boolean);
|
|
6403
7176
|
}
|
|
7177
|
+
function generateModuleTypeStubs(childDefinitions, _modelResults) {
|
|
7178
|
+
const stubs = {};
|
|
7179
|
+
for (const child of childDefinitions) {
|
|
7180
|
+
if (!child.slug) continue;
|
|
7181
|
+
const category = child.category;
|
|
7182
|
+
const isModel = category === "data" || Array.isArray(category) && category.includes("model") || Array.isArray(category) && category.includes("data");
|
|
7183
|
+
if (!isModel || !child.fields || child.fields.length === 0) continue;
|
|
7184
|
+
const interfaceName = slugToInterfaceName(child.slug) + "Fields";
|
|
7185
|
+
const lines = [
|
|
7186
|
+
`// Auto-generated type stub for model: ${child.slug}`,
|
|
7187
|
+
`// Do not edit \u2014 regenerated on each build.`,
|
|
7188
|
+
``,
|
|
7189
|
+
`export interface ${interfaceName} {`
|
|
7190
|
+
];
|
|
7191
|
+
for (const field of child.fields) {
|
|
7192
|
+
const tsType = irFieldTypeToTs(field.type || "string");
|
|
7193
|
+
const optional = field.required ? "" : "?";
|
|
7194
|
+
const desc = field.description;
|
|
7195
|
+
if (desc) {
|
|
7196
|
+
lines.push(` /** ${desc} */`);
|
|
7197
|
+
}
|
|
7198
|
+
lines.push(` ${field.name}${optional}: ${tsType};`);
|
|
7199
|
+
}
|
|
7200
|
+
lines.push(`}`);
|
|
7201
|
+
lines.push(``);
|
|
7202
|
+
lines.push(`export declare const ${slugToCamelCase(child.slug)}Slug: '${child.slug}';`);
|
|
7203
|
+
lines.push(``);
|
|
7204
|
+
stubs[`types/modules/${child.slug}.d.ts`] = lines.join("\n");
|
|
7205
|
+
}
|
|
7206
|
+
return stubs;
|
|
7207
|
+
}
|
|
7208
|
+
function slugToInterfaceName(slug) {
|
|
7209
|
+
return slug.split("-").map((s) => s.charAt(0).toUpperCase() + s.slice(1)).join("");
|
|
7210
|
+
}
|
|
7211
|
+
function slugToCamelCase(slug) {
|
|
7212
|
+
const parts = slug.split("-");
|
|
7213
|
+
return parts[0] + parts.slice(1).map((s) => s.charAt(0).toUpperCase() + s.slice(1)).join("");
|
|
7214
|
+
}
|
|
7215
|
+
function irFieldTypeToTs(type) {
|
|
7216
|
+
switch (type) {
|
|
7217
|
+
case "string":
|
|
7218
|
+
case "text":
|
|
7219
|
+
case "email":
|
|
7220
|
+
case "url":
|
|
7221
|
+
case "phone":
|
|
7222
|
+
case "slug":
|
|
7223
|
+
case "color":
|
|
7224
|
+
case "password":
|
|
7225
|
+
return "string";
|
|
7226
|
+
case "number":
|
|
7227
|
+
case "integer":
|
|
7228
|
+
case "float":
|
|
7229
|
+
case "currency":
|
|
7230
|
+
case "percent":
|
|
7231
|
+
return "number";
|
|
7232
|
+
case "boolean":
|
|
7233
|
+
case "toggle":
|
|
7234
|
+
return "boolean";
|
|
7235
|
+
case "date":
|
|
7236
|
+
case "datetime":
|
|
7237
|
+
case "timestamp":
|
|
7238
|
+
return "string";
|
|
7239
|
+
case "json":
|
|
7240
|
+
case "object":
|
|
7241
|
+
return "Record<string, unknown>";
|
|
7242
|
+
case "array":
|
|
7243
|
+
return "unknown[]";
|
|
7244
|
+
case "enum":
|
|
7245
|
+
return "string";
|
|
7246
|
+
case "file":
|
|
7247
|
+
case "image":
|
|
7248
|
+
return "string";
|
|
7249
|
+
default:
|
|
7250
|
+
return "unknown";
|
|
7251
|
+
}
|
|
7252
|
+
}
|
|
6404
7253
|
function buildComposedResult(files, fileIRs, config, errors, warnings, options = {}) {
|
|
6405
7254
|
const usePhase2 = options.usePhase2Modules !== false;
|
|
6406
7255
|
const workflowIRs = [];
|
|
6407
7256
|
const modelIRs = [];
|
|
7257
|
+
const actionDefinitionIRs = [];
|
|
6408
7258
|
const serverActionEntries = [];
|
|
6409
7259
|
let modelResults;
|
|
6410
7260
|
let actionResult;
|
|
@@ -6443,6 +7293,17 @@ function buildComposedResult(files, fileIRs, config, errors, warnings, options =
|
|
|
6443
7293
|
}
|
|
6444
7294
|
}
|
|
6445
7295
|
}
|
|
7296
|
+
for (const [filename, source] of Object.entries(files)) {
|
|
7297
|
+
if (isActionFile(filename)) {
|
|
7298
|
+
const result = extractAction(source, filename);
|
|
7299
|
+
if (result) {
|
|
7300
|
+
actionDefinitionIRs.push(result.ir);
|
|
7301
|
+
for (const w of result.warnings) {
|
|
7302
|
+
warnings.push({ file: filename, message: w, severity: "warning" });
|
|
7303
|
+
}
|
|
7304
|
+
}
|
|
7305
|
+
}
|
|
7306
|
+
}
|
|
6446
7307
|
if (usePhase2) {
|
|
6447
7308
|
const modelFiles = {};
|
|
6448
7309
|
for (const [filename, source] of Object.entries(files)) {
|
|
@@ -6493,7 +7354,11 @@ function buildComposedResult(files, fileIRs, config, errors, warnings, options =
|
|
|
6493
7354
|
});
|
|
6494
7355
|
}
|
|
6495
7356
|
}
|
|
6496
|
-
const childDefinitions = [
|
|
7357
|
+
const childDefinitions = [
|
|
7358
|
+
...workflowIRs,
|
|
7359
|
+
...modelIRs,
|
|
7360
|
+
...actionDefinitionIRs
|
|
7361
|
+
];
|
|
6497
7362
|
let routeTable = [];
|
|
6498
7363
|
if (routeResult) {
|
|
6499
7364
|
routeTable = routeResult.routes.map((r) => ({
|
|
@@ -6569,6 +7434,22 @@ function buildComposedResult(files, fileIRs, config, errors, warnings, options =
|
|
|
6569
7434
|
}
|
|
6570
7435
|
}
|
|
6571
7436
|
}
|
|
7437
|
+
if (options.resolvedModules && options.resolvedModules.length > 0) {
|
|
7438
|
+
for (const mod of options.resolvedModules) {
|
|
7439
|
+
if (mod.serverActions && mod.serverActions.length > 0) {
|
|
7440
|
+
for (const action of mod.serverActions) {
|
|
7441
|
+
const namespacedName = `${mod.slug}:${action.name}`;
|
|
7442
|
+
if (!serverActionEntries.some((a) => a.name === namespacedName)) {
|
|
7443
|
+
serverActionEntries.push({
|
|
7444
|
+
...action,
|
|
7445
|
+
name: namespacedName,
|
|
7446
|
+
sourceFile: `${mod.slug}/${action.sourceFile}`
|
|
7447
|
+
});
|
|
7448
|
+
}
|
|
7449
|
+
}
|
|
7450
|
+
}
|
|
7451
|
+
}
|
|
7452
|
+
}
|
|
6572
7453
|
const allIRs = Object.values(fileIRs);
|
|
6573
7454
|
const parentIR = mergeIRs(allIRs, config);
|
|
6574
7455
|
if (!parentIR.metadata) parentIR.metadata = {};
|
|
@@ -6581,6 +7462,7 @@ function buildComposedResult(files, fileIRs, config, errors, warnings, options =
|
|
|
6581
7462
|
parentMeta.composition = {
|
|
6582
7463
|
workflowCount: workflowIRs.length,
|
|
6583
7464
|
modelCount: modelIRs.length,
|
|
7465
|
+
actionCount: actionDefinitionIRs.length,
|
|
6584
7466
|
serverActionCount: serverActionEntries.length,
|
|
6585
7467
|
routeCount: routeTable.length,
|
|
6586
7468
|
componentCount: Object.keys(componentDefinitions).length,
|
|
@@ -6612,6 +7494,20 @@ function buildComposedResult(files, fileIRs, config, errors, warnings, options =
|
|
|
6612
7494
|
if (manifest?.contributions) {
|
|
6613
7495
|
parentMeta.slot_contributions = manifest.contributions;
|
|
6614
7496
|
}
|
|
7497
|
+
if (manifest?.configSchema) {
|
|
7498
|
+
parentMeta.configSchema = manifest.configSchema;
|
|
7499
|
+
}
|
|
7500
|
+
if (manifest?.dependencies) {
|
|
7501
|
+
const depConfigs = {};
|
|
7502
|
+
for (const dep of manifest.dependencies) {
|
|
7503
|
+
if (dep.config) {
|
|
7504
|
+
depConfigs[dep.slug] = dep.config;
|
|
7505
|
+
}
|
|
7506
|
+
}
|
|
7507
|
+
if (Object.keys(depConfigs).length > 0) {
|
|
7508
|
+
parentMeta.module_configs = depConfigs;
|
|
7509
|
+
}
|
|
7510
|
+
}
|
|
6615
7511
|
const compilableFiles = Object.keys(files).filter(isCompilableFile);
|
|
6616
7512
|
const importLinks = resolveImportLinks(files, compilableFiles);
|
|
6617
7513
|
const pageExperiences = {};
|
|
@@ -6726,6 +7622,7 @@ function buildComposedResult(files, fileIRs, config, errors, warnings, options =
|
|
|
6726
7622
|
}
|
|
6727
7623
|
}
|
|
6728
7624
|
}
|
|
7625
|
+
const typeStubs = generateModuleTypeStubs(childDefinitions, modelResults);
|
|
6729
7626
|
return {
|
|
6730
7627
|
ir: parentIR,
|
|
6731
7628
|
childDefinitions,
|
|
@@ -6739,7 +7636,8 @@ function buildComposedResult(files, fileIRs, config, errors, warnings, options =
|
|
|
6739
7636
|
importLinks,
|
|
6740
7637
|
modelResults,
|
|
6741
7638
|
actionResult,
|
|
6742
|
-
routeResult
|
|
7639
|
+
routeResult,
|
|
7640
|
+
typeStubs
|
|
6743
7641
|
};
|
|
6744
7642
|
}
|
|
6745
7643
|
function compileProject(files, options = {}) {
|
|
@@ -6783,6 +7681,7 @@ var init_project_compiler = __esm({
|
|
|
6783
7681
|
init_model_compiler();
|
|
6784
7682
|
init_route_extractor();
|
|
6785
7683
|
init_action_compiler();
|
|
7684
|
+
init_action_extractor();
|
|
6786
7685
|
init_incremental_compiler();
|
|
6787
7686
|
IncrementalProjectCompiler = class {
|
|
6788
7687
|
constructor() {
|
|
@@ -7339,10 +8238,10 @@ ${output}`);
|
|
|
7339
8238
|
fileMap[rel] = (0, import_fs3.readFileSync)(f, "utf-8");
|
|
7340
8239
|
}
|
|
7341
8240
|
(0, import_fs3.mkdirSync)(outDir, { recursive: true });
|
|
7342
|
-
const
|
|
7343
|
-
const errors =
|
|
7344
|
-
const warnings =
|
|
7345
|
-
const definitions2 = [
|
|
8241
|
+
const result2 = compileProject2(fileMap, { mode });
|
|
8242
|
+
const errors = result2.errors.filter((e) => e.severity === "error");
|
|
8243
|
+
const warnings = result2.errors.filter((e) => e.severity === "warning");
|
|
8244
|
+
const definitions2 = [result2.ir];
|
|
7346
8245
|
const errorDetails2 = [];
|
|
7347
8246
|
for (const err of errors) {
|
|
7348
8247
|
errorDetails2.push({ file: err.file, message: err.message, line: err.line });
|
|
@@ -7351,11 +8250,11 @@ ${output}`);
|
|
|
7351
8250
|
for (const warn of warnings) {
|
|
7352
8251
|
console.warn(` ! ${warn.file}${warn.line ? `:${warn.line}` : ""} ${warn.message}`);
|
|
7353
8252
|
}
|
|
7354
|
-
const irPath = (0, import_path2.join)(outDir, `${
|
|
7355
|
-
(0, import_fs3.writeFileSync)(irPath, JSON.stringify(
|
|
8253
|
+
const irPath = (0, import_path2.join)(outDir, `${result2.ir.slug}.workflow.json`);
|
|
8254
|
+
(0, import_fs3.writeFileSync)(irPath, JSON.stringify(result2.ir, null, 2), "utf-8");
|
|
7356
8255
|
console.log(` + ${(0, import_path2.basename)(irPath)}`);
|
|
7357
|
-
const seenSlugs = /* @__PURE__ */ new Set([
|
|
7358
|
-
for (const child of
|
|
8256
|
+
const seenSlugs = /* @__PURE__ */ new Set([result2.ir.slug]);
|
|
8257
|
+
for (const child of result2.childDefinitions) {
|
|
7359
8258
|
if (seenSlugs.has(child.slug)) continue;
|
|
7360
8259
|
seenSlugs.add(child.slug);
|
|
7361
8260
|
definitions2.push(child);
|
|
@@ -7385,14 +8284,14 @@ ${output}`);
|
|
|
7385
8284
|
for (const file of allFiles) {
|
|
7386
8285
|
try {
|
|
7387
8286
|
const code = (0, import_fs3.readFileSync)(file, "utf-8");
|
|
7388
|
-
const
|
|
8287
|
+
const result2 = (0, import_core5.transformSync)(code, {
|
|
7389
8288
|
filename: file,
|
|
7390
8289
|
plugins: [[babelPlugin, { mode }]],
|
|
7391
8290
|
parserOpts: { plugins: ["jsx", "typescript"], attachComment: true }
|
|
7392
8291
|
});
|
|
7393
|
-
const ir =
|
|
7394
|
-
const definition =
|
|
7395
|
-
const canonical =
|
|
8292
|
+
const ir = result2?.metadata?.mindmatrixIR;
|
|
8293
|
+
const definition = result2?.metadata?.mindmatrixDefinition;
|
|
8294
|
+
const canonical = result2?.metadata?.mindmatrixCanonical;
|
|
7396
8295
|
if (ir) {
|
|
7397
8296
|
definitions.push(ir);
|
|
7398
8297
|
const irErrors = ir.metadata?.errors;
|
|
@@ -7457,7 +8356,37 @@ ${output}`);
|
|
|
7457
8356
|
}
|
|
7458
8357
|
console.log(`
|
|
7459
8358
|
[mindmatrix-react] Compiled ${compiled} workflows, ${errorCount} errors, ${warningCount} warnings`);
|
|
7460
|
-
|
|
8359
|
+
const result = { compiled, errors: errorCount, warnings: warningCount, definitions, errorDetails };
|
|
8360
|
+
if (options.watch) {
|
|
8361
|
+
await startWatchMode(options);
|
|
8362
|
+
}
|
|
8363
|
+
return result;
|
|
8364
|
+
}
|
|
8365
|
+
async function startWatchMode(options) {
|
|
8366
|
+
const { watch: fsWatch } = await import("fs");
|
|
8367
|
+
const srcDir = options.src ?? "src/workflows";
|
|
8368
|
+
let debounce = null;
|
|
8369
|
+
console.log(`
|
|
8370
|
+
[mindmatrix-react] Watching ${srcDir} for changes... (Ctrl+C to stop)
|
|
8371
|
+
`);
|
|
8372
|
+
fsWatch(srcDir, { recursive: true }, (_event, filename) => {
|
|
8373
|
+
if (!filename) return;
|
|
8374
|
+
if (!filename.match(/\.(tsx?|jsx?)$/)) return;
|
|
8375
|
+
if (filename.includes("node_modules") || filename.includes("dist")) return;
|
|
8376
|
+
if (debounce) clearTimeout(debounce);
|
|
8377
|
+
debounce = setTimeout(async () => {
|
|
8378
|
+
const ts = (/* @__PURE__ */ new Date()).toLocaleTimeString();
|
|
8379
|
+
console.log(`
|
|
8380
|
+
[${ts}] Change detected: ${filename} \u2014 recompiling...`);
|
|
8381
|
+
try {
|
|
8382
|
+
await build({ ...options, watch: false, skipTypeCheck: true });
|
|
8383
|
+
} catch (e) {
|
|
8384
|
+
console.error(`[mindmatrix-react] Rebuild failed:`, e.message);
|
|
8385
|
+
}
|
|
8386
|
+
}, 300);
|
|
8387
|
+
});
|
|
8388
|
+
return new Promise(() => {
|
|
8389
|
+
});
|
|
7461
8390
|
}
|
|
7462
8391
|
|
|
7463
8392
|
// src/dev-server.ts
|