@mmapp/react-compiler 0.1.0-alpha.17 → 0.1.0-alpha.19
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/dist/babel/index.d.mts +1 -1
- package/dist/babel/index.d.ts +1 -1
- package/dist/babel/index.js +9 -6
- package/dist/babel/index.mjs +1 -1
- package/dist/chunk-26U577GB.mjs +3465 -0
- package/dist/chunk-2FBDFAX6.mjs +2362 -0
- package/dist/chunk-2REDFOER.mjs +931 -0
- package/dist/{chunk-FPAMQXKB.mjs → chunk-2UTXM2QX.mjs} +10 -20
- package/dist/chunk-2YDQTFAL.mjs +879 -0
- package/dist/chunk-2ZRKQE74.mjs +175 -0
- package/dist/chunk-3QHG2JWV.mjs +154 -0
- package/dist/chunk-466OWSTT.mjs +186 -0
- package/dist/chunk-467SFYOD.mjs +3127 -0
- package/dist/chunk-4AIJO7DZ.mjs +214 -0
- package/dist/chunk-4D43TZYL.mjs +7495 -0
- package/dist/chunk-4HX4PI4R.mjs +734 -0
- package/dist/chunk-4VU56NTZ.mjs +544 -0
- package/dist/chunk-4XHK6FWL.mjs +2058 -0
- package/dist/chunk-52C2JKH2.mjs +186 -0
- package/dist/chunk-52XHYD2V.mjs +214 -0
- package/dist/chunk-5GUFFFGL.mjs +148 -0
- package/dist/chunk-5N2FDDS6.mjs +214 -0
- package/dist/chunk-5ZSJXWZT.mjs +1646 -0
- package/dist/chunk-6CQOAAMV.mjs +1803 -0
- package/dist/chunk-6SEVAAVT.mjs +3516 -0
- package/dist/chunk-6YLR5ZDA.mjs +2829 -0
- package/dist/chunk-77UJB356.mjs +244 -0
- package/dist/chunk-7QOAJPQF.mjs +774 -0
- package/dist/chunk-A5RCMIBP.mjs +1795 -0
- package/dist/chunk-A63R3GKH.mjs +1803 -0
- package/dist/chunk-ABNTZXF5.mjs +951 -0
- package/dist/chunk-ADHWW56I.mjs +214 -0
- package/dist/chunk-AOGY2GK6.mjs +3292 -0
- package/dist/chunk-AXXUXRNA.mjs +1434 -0
- package/dist/chunk-BZLU5YK5.mjs +1025 -0
- package/dist/chunk-C7XCDDBH.mjs +1802 -0
- package/dist/chunk-CHLVKMQW.mjs +175 -0
- package/dist/chunk-CKGOZAB7.mjs +939 -0
- package/dist/chunk-CSXYDIVC.mjs +214 -0
- package/dist/chunk-CXTV4VGG.mjs +148 -0
- package/dist/chunk-D34RAZUX.mjs +2223 -0
- package/dist/chunk-DDIC7WM6.mjs +3127 -0
- package/dist/chunk-DPUQOBU6.mjs +4810 -0
- package/dist/chunk-E6MDVTGT.mjs +148 -0
- package/dist/chunk-EGKMUEM6.mjs +544 -0
- package/dist/chunk-EO6SYNCG.mjs +175 -0
- package/dist/chunk-EQGA6A6D.mjs +121 -0
- package/dist/chunk-EY2CSXYA.mjs +822 -0
- package/dist/chunk-FF5BQVII.mjs +148 -0
- package/dist/chunk-FIQ65CDR.mjs +925 -0
- package/dist/chunk-FOZXJFAR.mjs +186 -0
- package/dist/chunk-G2IAZ5Q6.mjs +148 -0
- package/dist/chunk-G7SMOWOL.mjs +828 -0
- package/dist/chunk-GK7NU6DO.mjs +214 -0
- package/dist/chunk-GMW45YVD.mjs +868 -0
- package/dist/chunk-HDSCPEHY.mjs +4061 -0
- package/dist/chunk-HJELFNEA.mjs +186 -0
- package/dist/chunk-HOIUP6IF.mjs +690 -0
- package/dist/chunk-HRJGDPNE.mjs +148 -0
- package/dist/chunk-I3AU7GRD.mjs +120 -0
- package/dist/chunk-I3VQQJZ6.mjs +2843 -0
- package/dist/chunk-IPTX5MJU.mjs +3223 -0
- package/dist/chunk-ITGUSH2Z.mjs +2783 -0
- package/dist/chunk-IXHBCAMF.mjs +3306 -0
- package/dist/chunk-J7JUAHS4.mjs +186 -0
- package/dist/chunk-J7TWJ3TM.mjs +2784 -0
- package/dist/chunk-JDPLDGVF.mjs +4810 -0
- package/dist/chunk-JK72MQ4N.mjs +877 -0
- package/dist/chunk-K2HHCAS2.mjs +148 -0
- package/dist/chunk-K5HX2SVL.mjs +1902 -0
- package/dist/chunk-KAUEQ2F3.mjs +148 -0
- package/dist/chunk-KFVVOS5N.mjs +925 -0
- package/dist/chunk-KIH4AN3Y.mjs +154 -0
- package/dist/chunk-KPDMN5IX.mjs +175 -0
- package/dist/chunk-LZL2IRCH.mjs +186 -0
- package/dist/chunk-MIZV3TAN.mjs +3293 -0
- package/dist/chunk-MRH4J7IX.mjs +2846 -0
- package/dist/chunk-NKBL5GUC.mjs +186 -0
- package/dist/chunk-NQCNSCF6.mjs +148 -0
- package/dist/chunk-NRP5J3BR.mjs +4811 -0
- package/dist/chunk-NTB7OEX2.mjs +2918 -0
- package/dist/chunk-NUPJYPFU.mjs +801 -0
- package/dist/chunk-NVQUTSQX.mjs +3128 -0
- package/dist/chunk-OGMG64EY.mjs +148 -0
- package/dist/chunk-OL5B2HTH.mjs +175 -0
- package/dist/chunk-OPJKP747.mjs +7506 -0
- package/dist/chunk-OQLGGBNE.mjs +2918 -0
- package/dist/chunk-OW4AQUDL.mjs +544 -0
- package/dist/chunk-OWI6XWCD.mjs +3375 -0
- package/dist/chunk-OZT2EAF2.mjs +2776 -0
- package/dist/chunk-PBRBRKIQ.mjs +175 -0
- package/dist/chunk-PRUMNNDI.mjs +3192 -0
- package/dist/chunk-QPNHDTSM.mjs +4839 -0
- package/dist/chunk-RNEIAJDR.mjs +897 -0
- package/dist/chunk-RY7POBNT.mjs +3127 -0
- package/dist/chunk-S6FJ4DXL.mjs +1813 -0
- package/dist/chunk-SU4E6E7B.mjs +3153 -0
- package/dist/chunk-SYUUKW5A.mjs +3379 -0
- package/dist/chunk-THB5SX2S.mjs +113 -0
- package/dist/chunk-THFYE5ZX.mjs +244 -0
- package/dist/chunk-TK3QMXIP.mjs +2921 -0
- package/dist/chunk-TRR2NPAV.mjs +248 -0
- package/dist/chunk-TTTTOT7P.mjs +1803 -0
- package/dist/chunk-TXONBY6A.mjs +7509 -0
- package/dist/chunk-U2PX3JSY.mjs +1933 -0
- package/dist/chunk-UASOWKDI.mjs +186 -0
- package/dist/chunk-UDDTWG5J.mjs +734 -0
- package/dist/chunk-UIWLAQCL.mjs +175 -0
- package/dist/chunk-UL2XZEMA.mjs +3128 -0
- package/dist/chunk-US3AVDAI.mjs +3456 -0
- package/dist/chunk-V5DIDOTT.mjs +148 -0
- package/dist/chunk-VLTKQDJ3.mjs +244 -0
- package/dist/chunk-VVC42PTS.mjs +175 -0
- package/dist/chunk-VX3T3NIR.mjs +897 -0
- package/dist/chunk-WBYMW4NQ.mjs +3450 -0
- package/dist/chunk-XMWUHQVV.mjs +939 -0
- package/dist/chunk-Y6FXYEAI.mjs +10 -0
- package/dist/chunk-YCWC2SCO.mjs +148 -0
- package/dist/chunk-YFS6JMYO.mjs +3342 -0
- package/dist/chunk-ZE67HOSN.mjs +148 -0
- package/dist/chunk-ZSK5TPIV.mjs +148 -0
- package/dist/cli/index.js +317 -656
- package/dist/cli/index.mjs +8 -8
- package/dist/config-PL24KEWL.mjs +219 -0
- package/dist/dev-server-Bs_sz2DG.d.mts +111 -0
- package/dist/dev-server-Bs_sz2DG.d.ts +111 -0
- package/dist/dev-server-RmGHIntF.d.mts +113 -0
- package/dist/dev-server-RmGHIntF.d.ts +113 -0
- package/dist/dev-server.js +194 -526
- package/dist/dev-server.mjs +4 -4
- package/dist/engine-binary-KQB23JDR.mjs +97 -0
- package/dist/envelope-DD7v0v6E.d.mts +265 -0
- package/dist/envelope-DD7v0v6E.d.ts +265 -0
- package/dist/envelope.js +9 -6
- package/dist/envelope.mjs +2 -2
- package/dist/index-B5gSgvnd.d.mts +44 -0
- package/dist/index-B5gSgvnd.d.ts +44 -0
- package/dist/index-Bs0MnR54.d.mts +103 -0
- package/dist/index-Bs0MnR54.d.ts +103 -0
- package/dist/index-DR0nNc_f.d.mts +101 -0
- package/dist/index-DR0nNc_f.d.ts +101 -0
- package/dist/index-revho_gS.d.mts +104 -0
- package/dist/index-revho_gS.d.ts +104 -0
- package/dist/index-vQjwYekL.d.mts +104 -0
- package/dist/index-vQjwYekL.d.ts +104 -0
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +198 -528
- package/dist/index.mjs +9 -8
- package/dist/init-2XLTUF7O.mjs +407 -0
- package/dist/init-7FJENUDK.mjs +407 -0
- package/dist/init-DQDX3QK6.mjs +369 -0
- package/dist/init-K3GVM4JS.mjs +538 -0
- package/dist/init-NXS5BJN3.mjs +454 -0
- package/dist/init-UC3FWPIW.mjs +367 -0
- package/dist/init-UNV5XIDE.mjs +367 -0
- package/dist/project-compiler-2HOPO7GC.mjs +10 -0
- package/dist/project-compiler-D245L5QR.mjs +10 -0
- package/dist/project-compiler-FUQRMB4X.mjs +10 -0
- package/dist/project-compiler-LA5OBI5P.mjs +10 -0
- package/dist/project-compiler-OP2VVGJQ.mjs +10 -0
- package/dist/project-compiler-PZNFE6AH.mjs +10 -0
- package/dist/project-compiler-QBVF6MFI.mjs +10 -0
- package/dist/project-compiler-VFR6CSDX.mjs +10 -0
- package/dist/project-compiler-WMJZA4UH.mjs +10 -0
- package/dist/project-compiler-XXS27TZT.mjs +10 -0
- package/dist/project-compiler-YYGDSHY5.mjs +10 -0
- package/dist/project-decompiler-5GY2KSG4.mjs +7 -0
- package/dist/project-decompiler-7I2OMUVY.mjs +7 -0
- package/dist/project-decompiler-US7GAVIC.mjs +7 -0
- package/dist/pull-2Q53HF3H.mjs +107 -0
- package/dist/pull-5AFHD3QG.mjs +109 -0
- package/dist/pull-65GUSX6F.mjs +109 -0
- package/dist/pull-6LVI4LMM.mjs +109 -0
- package/dist/pull-A2QUHW4K.mjs +109 -0
- package/dist/pull-B6T5BUKV.mjs +109 -0
- package/dist/pull-CKHWZT33.mjs +109 -0
- package/dist/pull-GM74ERRT.mjs +109 -0
- package/dist/pull-JBEQWVPE.mjs +109 -0
- package/dist/pull-P44LDRWB.mjs +109 -0
- package/dist/pull-W2US3T3E.mjs +109 -0
- package/dist/testing/index.js +9 -6
- package/dist/testing/index.mjs +1 -1
- package/dist/verify-3PPS4XAM.mjs +1833 -0
- package/dist/verify-GKEH5FZQ.mjs +1833 -0
- package/dist/verify-HDKUNHZ4.mjs +1833 -0
- package/dist/verify-SEIXUGN4.mjs +1833 -0
- package/dist/vite/index.js +10 -7
- package/dist/vite/index.mjs +2 -2
- package/package.json +2 -2
package/dist/dev-server.js
CHANGED
|
@@ -6468,7 +6468,8 @@ function convertOnEvent(sub) {
|
|
|
6468
6468
|
};
|
|
6469
6469
|
}
|
|
6470
6470
|
function emitIR(extracted) {
|
|
6471
|
-
const { slug, name, version, description, category, fields, states, transitions } = extracted;
|
|
6471
|
+
const { slug, name, version, description, category: rawCategory, fields, states, transitions } = extracted;
|
|
6472
|
+
const category = Array.isArray(rawCategory) ? rawCategory : [rawCategory];
|
|
6472
6473
|
const stateArray = Array.from(states.values());
|
|
6473
6474
|
if (stateArray.length === 0) {
|
|
6474
6475
|
stateArray.push({
|
|
@@ -6856,13 +6857,15 @@ function emitCanonical(extracted, sourceFilename) {
|
|
|
6856
6857
|
}
|
|
6857
6858
|
]
|
|
6858
6859
|
});
|
|
6859
|
-
const
|
|
6860
|
+
const rawCat = extracted.category;
|
|
6860
6861
|
let categoryArray;
|
|
6861
|
-
if (
|
|
6862
|
-
|
|
6862
|
+
if (Array.isArray(rawCat)) {
|
|
6863
|
+
categoryArray = rawCat;
|
|
6864
|
+
} else if (rawCat.includes("/")) {
|
|
6865
|
+
const [primary, ...tags] = rawCat.split("/");
|
|
6863
6866
|
categoryArray = (0, import_player_core.normalizeCategory)(primary, ...tags);
|
|
6864
6867
|
} else {
|
|
6865
|
-
categoryArray = [
|
|
6868
|
+
categoryArray = [rawCat];
|
|
6866
6869
|
}
|
|
6867
6870
|
return {
|
|
6868
6871
|
slug: ir.slug,
|
|
@@ -7009,7 +7012,7 @@ function compilerStateToWorkflow(state, metadata) {
|
|
|
7009
7012
|
name: metadata.name || "Workflow",
|
|
7010
7013
|
version: metadata.version || "0.1.0",
|
|
7011
7014
|
description: metadata.description,
|
|
7012
|
-
category: metadata.category || "workflow",
|
|
7015
|
+
category: metadata.categoryArray ? metadata.categoryArray : [metadata.category || "workflow"],
|
|
7013
7016
|
fields: state.fields || [],
|
|
7014
7017
|
states: state.states || /* @__PURE__ */ new Map(),
|
|
7015
7018
|
transitions: state.transitions || [],
|
|
@@ -7787,7 +7790,7 @@ function extractRouterWorkflow(pages, options = {}) {
|
|
|
7787
7790
|
name: "Router",
|
|
7788
7791
|
version: "1.0.0",
|
|
7789
7792
|
description: "Auto-derived router workflow from file-based routing",
|
|
7790
|
-
category: "router",
|
|
7793
|
+
category: ["router"],
|
|
7791
7794
|
fields,
|
|
7792
7795
|
states,
|
|
7793
7796
|
transitions,
|
|
@@ -7886,7 +7889,8 @@ function compileModel(filename, source, options = {}) {
|
|
|
7886
7889
|
parserOpts: { plugins: parserPlugins, attachComment: true }
|
|
7887
7890
|
});
|
|
7888
7891
|
const ir = babelResult?.metadata?.mindmatrixIR ?? createEmptyModelIR(interfaceName);
|
|
7889
|
-
|
|
7892
|
+
const catOverride = options.categoryOverride || annotation.category || "data";
|
|
7893
|
+
ir.category = Array.isArray(catOverride) ? catOverride : [catOverride];
|
|
7890
7894
|
if (options.slugOverride) {
|
|
7891
7895
|
ir.slug = options.slugOverride;
|
|
7892
7896
|
}
|
|
@@ -7950,7 +7954,7 @@ function createEmptyModelIR(interfaceName) {
|
|
|
7950
7954
|
name: interfaceName,
|
|
7951
7955
|
version: "1.0.0",
|
|
7952
7956
|
description: "Data model: " + interfaceName,
|
|
7953
|
-
category: "data",
|
|
7957
|
+
category: ["data"],
|
|
7954
7958
|
fields: [],
|
|
7955
7959
|
states: [{
|
|
7956
7960
|
name: "draft",
|
|
@@ -8118,7 +8122,7 @@ function buildRouterIR(routes, layouts, allParams, slugPrefix) {
|
|
|
8118
8122
|
name: "Router",
|
|
8119
8123
|
version: "1.0.0",
|
|
8120
8124
|
description: "Auto-generated router from app/ directory structure",
|
|
8121
|
-
category: "router",
|
|
8125
|
+
category: ["router"],
|
|
8122
8126
|
fields,
|
|
8123
8127
|
states,
|
|
8124
8128
|
transitions,
|
|
@@ -8367,7 +8371,7 @@ function extractAction(source, filename) {
|
|
|
8367
8371
|
slug,
|
|
8368
8372
|
name: humanName,
|
|
8369
8373
|
version: "0.1.0",
|
|
8370
|
-
category: "action",
|
|
8374
|
+
category: ["action"],
|
|
8371
8375
|
fields,
|
|
8372
8376
|
states: states2,
|
|
8373
8377
|
transitions: transitions2,
|
|
@@ -8419,7 +8423,7 @@ function extractAction(source, filename) {
|
|
|
8419
8423
|
slug,
|
|
8420
8424
|
name: humanName,
|
|
8421
8425
|
version: "0.1.0",
|
|
8422
|
-
category: "action",
|
|
8426
|
+
category: ["action"],
|
|
8423
8427
|
fields,
|
|
8424
8428
|
states,
|
|
8425
8429
|
transitions,
|
|
@@ -9856,7 +9860,7 @@ function applyConfig(ir, config) {
|
|
|
9856
9860
|
if (config.name) ir.name = config.name;
|
|
9857
9861
|
if (config.version) ir.version = config.version;
|
|
9858
9862
|
if (config.description !== void 0) ir.description = config.description;
|
|
9859
|
-
if (config.category) ir.category = config.category;
|
|
9863
|
+
if (config.category) ir.category = Array.isArray(config.category) ? config.category : [config.category];
|
|
9860
9864
|
if (!ir.metadata) ir.metadata = {};
|
|
9861
9865
|
ir.metadata.stable_id = "def-" + ir.slug;
|
|
9862
9866
|
ir.metadata.provenance = {
|
|
@@ -9872,7 +9876,7 @@ function createEmptyIR(config) {
|
|
|
9872
9876
|
name: config.name || "Project",
|
|
9873
9877
|
version: config.version || "0.1.0",
|
|
9874
9878
|
description: config.description,
|
|
9875
|
-
category: config.category || "workflow",
|
|
9879
|
+
category: Array.isArray(config.category) ? config.category : [config.category || "workflow"],
|
|
9876
9880
|
fields: [],
|
|
9877
9881
|
states: [{
|
|
9878
9882
|
name: "draft",
|
|
@@ -10030,8 +10034,10 @@ function buildComposedResult(files, fileIRs, config, errors, warnings, options =
|
|
|
10030
10034
|
if (isWorkflowFile(filename)) {
|
|
10031
10035
|
workflowIRs.push(ir);
|
|
10032
10036
|
} else if (isModelFile2(filename)) {
|
|
10033
|
-
|
|
10034
|
-
|
|
10037
|
+
const cat = ir.category;
|
|
10038
|
+
const isDefault = !cat || cat === "workflow" || Array.isArray(cat) && cat.length === 1 && cat[0] === "workflow";
|
|
10039
|
+
if (isDefault) {
|
|
10040
|
+
ir.category = ["data"];
|
|
10035
10041
|
}
|
|
10036
10042
|
modelIRs.push(ir);
|
|
10037
10043
|
} else if (isServerActionFile2(filename)) {
|
|
@@ -11171,7 +11177,7 @@ function mindmatrixReact(options) {
|
|
|
11171
11177
|
slug: ir.slug,
|
|
11172
11178
|
name: ir.name,
|
|
11173
11179
|
version: ir.version,
|
|
11174
|
-
category: ir.category || "workflow",
|
|
11180
|
+
category: ir.category || ["workflow"],
|
|
11175
11181
|
fields: ir.fields || [],
|
|
11176
11182
|
states: ir.states || [],
|
|
11177
11183
|
transitions: ir.transitions || [],
|
|
@@ -11705,425 +11711,6 @@ async function startWatchMode(options) {
|
|
|
11705
11711
|
});
|
|
11706
11712
|
}
|
|
11707
11713
|
|
|
11708
|
-
// src/cli/local-server.ts
|
|
11709
|
-
var http = __toESM(require("http"));
|
|
11710
|
-
var import_node_crypto = require("crypto");
|
|
11711
|
-
var MemoryStore = class {
|
|
11712
|
-
constructor() {
|
|
11713
|
-
this.definitions = /* @__PURE__ */ new Map();
|
|
11714
|
-
this.instances = /* @__PURE__ */ new Map();
|
|
11715
|
-
this.slugIndex = /* @__PURE__ */ new Map();
|
|
11716
|
-
}
|
|
11717
|
-
// slug → id
|
|
11718
|
-
// ── Definitions ──────────────────────────────────────────────────────
|
|
11719
|
-
createDefinition(input) {
|
|
11720
|
-
if (this.slugIndex.has(input.slug)) {
|
|
11721
|
-
const existing = this.definitions.get(this.slugIndex.get(input.slug));
|
|
11722
|
-
if (existing) return existing;
|
|
11723
|
-
}
|
|
11724
|
-
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
11725
|
-
const def = {
|
|
11726
|
-
id: input.id ?? (0, import_node_crypto.randomUUID)(),
|
|
11727
|
-
slug: input.slug,
|
|
11728
|
-
name: input.name,
|
|
11729
|
-
version: input.version ?? "1.0.0",
|
|
11730
|
-
description: input.description ?? null,
|
|
11731
|
-
category: input.category ?? "workflow",
|
|
11732
|
-
fields: input.fields ?? [],
|
|
11733
|
-
states: input.states ?? [],
|
|
11734
|
-
transitions: input.transitions ?? [],
|
|
11735
|
-
roles: input.roles ?? [],
|
|
11736
|
-
experience: input.experience ?? null,
|
|
11737
|
-
metadata: input.metadata ?? {},
|
|
11738
|
-
child_definitions: input.child_definitions ?? [],
|
|
11739
|
-
is_immutable: input.is_immutable ?? false,
|
|
11740
|
-
tags: input.tags ?? [],
|
|
11741
|
-
inline_tags: input.inline_tags ?? [],
|
|
11742
|
-
created_at: now,
|
|
11743
|
-
updated_at: now
|
|
11744
|
-
};
|
|
11745
|
-
this.definitions.set(def.id, def);
|
|
11746
|
-
this.slugIndex.set(def.slug, def.id);
|
|
11747
|
-
return def;
|
|
11748
|
-
}
|
|
11749
|
-
getDefinition(idOrSlug) {
|
|
11750
|
-
const byId = this.definitions.get(idOrSlug);
|
|
11751
|
-
if (byId) return byId;
|
|
11752
|
-
const id = this.slugIndex.get(idOrSlug);
|
|
11753
|
-
if (id) return this.definitions.get(id);
|
|
11754
|
-
return void 0;
|
|
11755
|
-
}
|
|
11756
|
-
listDefinitions(opts) {
|
|
11757
|
-
let items = Array.from(this.definitions.values());
|
|
11758
|
-
if (opts?.category) {
|
|
11759
|
-
items = items.filter((d) => d.category === opts.category);
|
|
11760
|
-
}
|
|
11761
|
-
const total = items.length;
|
|
11762
|
-
const offset = opts?.offset ?? 0;
|
|
11763
|
-
const limit = opts?.limit ?? 50;
|
|
11764
|
-
items = items.slice(offset, offset + limit);
|
|
11765
|
-
return { items, total };
|
|
11766
|
-
}
|
|
11767
|
-
patchDefinition(id, patch) {
|
|
11768
|
-
const def = this.definitions.get(id);
|
|
11769
|
-
if (!def) return void 0;
|
|
11770
|
-
Object.assign(def, patch, { updated_at: (/* @__PURE__ */ new Date()).toISOString() });
|
|
11771
|
-
return def;
|
|
11772
|
-
}
|
|
11773
|
-
deleteDefinition(id) {
|
|
11774
|
-
const def = this.definitions.get(id);
|
|
11775
|
-
if (!def) return false;
|
|
11776
|
-
this.slugIndex.delete(def.slug);
|
|
11777
|
-
this.definitions.delete(id);
|
|
11778
|
-
return true;
|
|
11779
|
-
}
|
|
11780
|
-
// ── Instances ────────────────────────────────────────────────────────
|
|
11781
|
-
createInstance(input) {
|
|
11782
|
-
const def = this.getDefinition(input.definition_id) ?? this.getDefinition(input.definition_slug);
|
|
11783
|
-
if (!def) return null;
|
|
11784
|
-
const initialState = def.states.find((s) => s.type === "START" || s.type === "initial");
|
|
11785
|
-
const stateName = initialState?.name ?? "initial";
|
|
11786
|
-
const stateData = {};
|
|
11787
|
-
for (const field of def.fields) {
|
|
11788
|
-
if (field.default_value !== void 0) {
|
|
11789
|
-
stateData[field.name] = field.default_value;
|
|
11790
|
-
}
|
|
11791
|
-
}
|
|
11792
|
-
Object.assign(stateData, input.state_data ?? {});
|
|
11793
|
-
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
11794
|
-
const inst = {
|
|
11795
|
-
id: (0, import_node_crypto.randomUUID)(),
|
|
11796
|
-
definition_id: def.id,
|
|
11797
|
-
definition_slug: def.slug,
|
|
11798
|
-
current_state: stateName,
|
|
11799
|
-
state_data: stateData,
|
|
11800
|
-
execution_lock_version: 0,
|
|
11801
|
-
event_log: [{
|
|
11802
|
-
event_type: "transition",
|
|
11803
|
-
message: `Instance created in state '${stateName}'`,
|
|
11804
|
-
timestamp: now
|
|
11805
|
-
}],
|
|
11806
|
-
created_at: now,
|
|
11807
|
-
updated_at: now
|
|
11808
|
-
};
|
|
11809
|
-
this.instances.set(inst.id, inst);
|
|
11810
|
-
return inst;
|
|
11811
|
-
}
|
|
11812
|
-
getInstance(id) {
|
|
11813
|
-
return this.instances.get(id);
|
|
11814
|
-
}
|
|
11815
|
-
listInstances(opts) {
|
|
11816
|
-
let items = Array.from(this.instances.values());
|
|
11817
|
-
if (opts?.definition_id) {
|
|
11818
|
-
items = items.filter((i) => i.definition_id === opts.definition_id);
|
|
11819
|
-
}
|
|
11820
|
-
const total = items.length;
|
|
11821
|
-
const offset = opts?.offset ?? 0;
|
|
11822
|
-
const limit = opts?.limit ?? 50;
|
|
11823
|
-
items = items.slice(offset, offset + limit);
|
|
11824
|
-
return { items, total };
|
|
11825
|
-
}
|
|
11826
|
-
// ── Execute Action (Transition) ──────────────────────────────────────
|
|
11827
|
-
executeAction(input) {
|
|
11828
|
-
const def = this.getDefinition(input.definition_id);
|
|
11829
|
-
if (!def) return { success: false, error: "Definition not found" };
|
|
11830
|
-
let inst;
|
|
11831
|
-
if (input.instance_id) {
|
|
11832
|
-
const existing = this.instances.get(input.instance_id);
|
|
11833
|
-
if (!existing) return { success: false, error: "Instance not found" };
|
|
11834
|
-
inst = existing;
|
|
11835
|
-
} else {
|
|
11836
|
-
const created = this.createInstance({
|
|
11837
|
-
definition_id: def.id,
|
|
11838
|
-
definition_slug: def.slug,
|
|
11839
|
-
state_data: input.payload
|
|
11840
|
-
});
|
|
11841
|
-
if (!created) return { success: false, error: "Failed to create instance" };
|
|
11842
|
-
inst = created;
|
|
11843
|
-
}
|
|
11844
|
-
if (input.payload && input.instance_id) {
|
|
11845
|
-
Object.assign(inst.state_data, input.payload);
|
|
11846
|
-
}
|
|
11847
|
-
const transition = def.transitions.find((t23) => t23.name === input.action_name && t23.from.includes(inst.current_state));
|
|
11848
|
-
if (!transition) {
|
|
11849
|
-
return {
|
|
11850
|
-
success: false,
|
|
11851
|
-
instance_id: inst.id,
|
|
11852
|
-
from_state: inst.current_state,
|
|
11853
|
-
to_state: null,
|
|
11854
|
-
state_data: inst.state_data,
|
|
11855
|
-
error: `No transition '${input.action_name}' from state '${inst.current_state}'`
|
|
11856
|
-
};
|
|
11857
|
-
}
|
|
11858
|
-
const fromState = inst.current_state;
|
|
11859
|
-
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
11860
|
-
const events = [];
|
|
11861
|
-
let lastEvalResult = null;
|
|
11862
|
-
events.push({ event_type: "transition", message: `Transition '${transition.name}' started: ${fromState} \u2192 ${transition.to}`, timestamp: now });
|
|
11863
|
-
for (const action of transition.actions ?? []) {
|
|
11864
|
-
try {
|
|
11865
|
-
if (action.type === "set_field") {
|
|
11866
|
-
const field = action.config?.field;
|
|
11867
|
-
if (action.config?.expression) {
|
|
11868
|
-
const expr = action.config.expression;
|
|
11869
|
-
const result = this.evaluateSimpleExpression(expr, inst.state_data);
|
|
11870
|
-
inst.state_data[field] = result;
|
|
11871
|
-
} else if (action.config?.value !== void 0) {
|
|
11872
|
-
inst.state_data[field] = action.config.value;
|
|
11873
|
-
}
|
|
11874
|
-
events.push({ event_type: "action_executed", message: `transition action 'set_field' succeeded`, timestamp: now });
|
|
11875
|
-
} else if (action.type === "eval") {
|
|
11876
|
-
const expr = action.config?.expression;
|
|
11877
|
-
lastEvalResult = this.evaluateSimpleExpression(expr, inst.state_data);
|
|
11878
|
-
events.push({ event_type: "action_executed", message: `transition action 'eval' succeeded`, timestamp: now });
|
|
11879
|
-
} else {
|
|
11880
|
-
events.push({ event_type: "action_executed", message: `transition action '${action.type}' succeeded (no-op in local mode)`, timestamp: now });
|
|
11881
|
-
}
|
|
11882
|
-
} catch (err) {
|
|
11883
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
11884
|
-
events.push({ event_type: "action_failed", message: `transition action '${action.type}' failed: ${msg}`, timestamp: now });
|
|
11885
|
-
return {
|
|
11886
|
-
success: false,
|
|
11887
|
-
instance_id: inst.id,
|
|
11888
|
-
from_state: fromState,
|
|
11889
|
-
to_state: null,
|
|
11890
|
-
state_data: inst.state_data,
|
|
11891
|
-
event_log: events,
|
|
11892
|
-
error: `transition action failed: ${msg}`
|
|
11893
|
-
};
|
|
11894
|
-
}
|
|
11895
|
-
}
|
|
11896
|
-
inst.current_state = transition.to;
|
|
11897
|
-
inst.execution_lock_version++;
|
|
11898
|
-
inst.updated_at = now;
|
|
11899
|
-
events.push({ event_type: "transition", message: `State changed: ${fromState} \u2192 ${transition.to}`, timestamp: now });
|
|
11900
|
-
inst.event_log.push(...events);
|
|
11901
|
-
return {
|
|
11902
|
-
success: true,
|
|
11903
|
-
instance_id: inst.id,
|
|
11904
|
-
from_state: fromState,
|
|
11905
|
-
to_state: transition.to,
|
|
11906
|
-
state_data: inst.state_data,
|
|
11907
|
-
result: lastEvalResult,
|
|
11908
|
-
event_log: events
|
|
11909
|
-
};
|
|
11910
|
-
}
|
|
11911
|
-
/**
|
|
11912
|
-
* Minimal expression evaluator for local dev mode.
|
|
11913
|
-
* Handles: field references, arithmetic, string literals, simple comparisons.
|
|
11914
|
-
* Does NOT handle: while loops, if/else, function calls, multi-statement blocks.
|
|
11915
|
-
* For full evaluation, use mm-napi when available.
|
|
11916
|
-
*/
|
|
11917
|
-
evaluateSimpleExpression(expr, context) {
|
|
11918
|
-
if (context[expr] !== void 0) return context[expr];
|
|
11919
|
-
const arithMatch = expr.match(/^(\w+)\s*([+\-*/])\s*(\d+(?:\.\d+)?)$/);
|
|
11920
|
-
if (arithMatch) {
|
|
11921
|
-
const [, field, op, numStr] = arithMatch;
|
|
11922
|
-
const left = Number(context[field] ?? 0);
|
|
11923
|
-
const right = Number(numStr);
|
|
11924
|
-
switch (op) {
|
|
11925
|
-
case "+":
|
|
11926
|
-
return left + right;
|
|
11927
|
-
case "-":
|
|
11928
|
-
return left - right;
|
|
11929
|
-
case "*":
|
|
11930
|
-
return left * right;
|
|
11931
|
-
case "/":
|
|
11932
|
-
return right !== 0 ? left / right : 0;
|
|
11933
|
-
}
|
|
11934
|
-
}
|
|
11935
|
-
if (/^\d+(\.\d+)?$/.test(expr.trim())) {
|
|
11936
|
-
return Number(expr.trim());
|
|
11937
|
-
}
|
|
11938
|
-
const strMatch = expr.match(/^["'](.*)["']$/);
|
|
11939
|
-
if (strMatch) return strMatch[1];
|
|
11940
|
-
try {
|
|
11941
|
-
const keys = Object.keys(context);
|
|
11942
|
-
const values = Object.values(context);
|
|
11943
|
-
const fn = new Function(...keys, `"use strict"; return (${expr});`);
|
|
11944
|
-
return fn(...values);
|
|
11945
|
-
} catch {
|
|
11946
|
-
return null;
|
|
11947
|
-
}
|
|
11948
|
-
}
|
|
11949
|
-
};
|
|
11950
|
-
async function startLocalServer(options = {}) {
|
|
11951
|
-
const { port = 4200, noAuth = true } = options;
|
|
11952
|
-
const store = new MemoryStore();
|
|
11953
|
-
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
11954
|
-
function json(res, status, body) {
|
|
11955
|
-
const data = JSON.stringify(body);
|
|
11956
|
-
res.writeHead(status, {
|
|
11957
|
-
"Content-Type": "application/json",
|
|
11958
|
-
"Access-Control-Allow-Origin": "*",
|
|
11959
|
-
"Access-Control-Allow-Methods": "GET, POST, PATCH, PUT, DELETE, OPTIONS",
|
|
11960
|
-
"Access-Control-Allow-Headers": "Content-Type, Authorization",
|
|
11961
|
-
"Content-Length": Buffer.byteLength(data)
|
|
11962
|
-
});
|
|
11963
|
-
res.end(data);
|
|
11964
|
-
}
|
|
11965
|
-
function readBody(req) {
|
|
11966
|
-
return new Promise((resolve2, reject) => {
|
|
11967
|
-
const chunks = [];
|
|
11968
|
-
req.on("data", (chunk) => chunks.push(chunk));
|
|
11969
|
-
req.on("end", () => resolve2(Buffer.concat(chunks).toString()));
|
|
11970
|
-
req.on("error", reject);
|
|
11971
|
-
});
|
|
11972
|
-
}
|
|
11973
|
-
function parseQuery(url) {
|
|
11974
|
-
const idx = url.indexOf("?");
|
|
11975
|
-
if (idx === -1) return {};
|
|
11976
|
-
const params = {};
|
|
11977
|
-
const qs = url.slice(idx + 1);
|
|
11978
|
-
for (const pair of qs.split("&")) {
|
|
11979
|
-
const [k, v] = pair.split("=");
|
|
11980
|
-
if (k) params[decodeURIComponent(k)] = decodeURIComponent(v ?? "");
|
|
11981
|
-
}
|
|
11982
|
-
return params;
|
|
11983
|
-
}
|
|
11984
|
-
const server = http.createServer(async (req, res) => {
|
|
11985
|
-
const method = req.method?.toUpperCase() ?? "GET";
|
|
11986
|
-
const rawUrl = req.url ?? "/";
|
|
11987
|
-
const queryStart = rawUrl.indexOf("?");
|
|
11988
|
-
const path = queryStart >= 0 ? rawUrl.slice(0, queryStart) : rawUrl;
|
|
11989
|
-
const query = parseQuery(rawUrl);
|
|
11990
|
-
if (method === "OPTIONS") {
|
|
11991
|
-
res.writeHead(204, {
|
|
11992
|
-
"Access-Control-Allow-Origin": "*",
|
|
11993
|
-
"Access-Control-Allow-Methods": "GET, POST, PATCH, PUT, DELETE, OPTIONS",
|
|
11994
|
-
"Access-Control-Allow-Headers": "Content-Type, Authorization",
|
|
11995
|
-
"Access-Control-Max-Age": "86400"
|
|
11996
|
-
});
|
|
11997
|
-
res.end();
|
|
11998
|
-
return;
|
|
11999
|
-
}
|
|
12000
|
-
try {
|
|
12001
|
-
if (path === "/health" && method === "GET") {
|
|
12002
|
-
return json(res, 200, {
|
|
12003
|
-
status: "ok",
|
|
12004
|
-
service: "mm-local-dev",
|
|
12005
|
-
mode: "in-memory",
|
|
12006
|
-
started_at: startedAt,
|
|
12007
|
-
definitions: store.definitions.size,
|
|
12008
|
-
instances: store.instances.size
|
|
12009
|
-
});
|
|
12010
|
-
}
|
|
12011
|
-
if (path === "/api/v1/auth/login" && (method === "POST" || method === "GET")) {
|
|
12012
|
-
return json(res, 200, {
|
|
12013
|
-
token: "dev-token-local",
|
|
12014
|
-
user: {
|
|
12015
|
-
id: "dev-user-001",
|
|
12016
|
-
email: "dev@localhost",
|
|
12017
|
-
role: "admin",
|
|
12018
|
-
name: "Local Developer"
|
|
12019
|
-
}
|
|
12020
|
-
});
|
|
12021
|
-
}
|
|
12022
|
-
if (path === "/api/v1/workflow/definitions" && method === "GET") {
|
|
12023
|
-
const result = store.listDefinitions({
|
|
12024
|
-
category: query.category,
|
|
12025
|
-
limit: query.limit ? parseInt(query.limit, 10) : void 0,
|
|
12026
|
-
offset: query.offset ? parseInt(query.offset, 10) : void 0
|
|
12027
|
-
});
|
|
12028
|
-
if (query.slug) {
|
|
12029
|
-
const def = store.getDefinition(query.slug);
|
|
12030
|
-
return json(res, 200, { items: def ? [def] : [], total: def ? 1 : 0 });
|
|
12031
|
-
}
|
|
12032
|
-
return json(res, 200, result);
|
|
12033
|
-
}
|
|
12034
|
-
const defMatch = path.match(/^\/api\/v1\/workflow\/definitions\/([^/]+)$/);
|
|
12035
|
-
if (defMatch && method === "GET") {
|
|
12036
|
-
const def = store.getDefinition(defMatch[1]);
|
|
12037
|
-
if (!def) return json(res, 404, { error: "Not found" });
|
|
12038
|
-
return json(res, 200, def);
|
|
12039
|
-
}
|
|
12040
|
-
if (path === "/api/v1/workflow/definitions" && method === "POST") {
|
|
12041
|
-
const body = JSON.parse(await readBody(req));
|
|
12042
|
-
const def = store.createDefinition(body);
|
|
12043
|
-
return json(res, 201, def);
|
|
12044
|
-
}
|
|
12045
|
-
if (defMatch && method === "PATCH") {
|
|
12046
|
-
const body = JSON.parse(await readBody(req));
|
|
12047
|
-
const updated = store.patchDefinition(defMatch[1], body);
|
|
12048
|
-
if (!updated) return json(res, 404, { error: "Not found" });
|
|
12049
|
-
return json(res, 200, updated);
|
|
12050
|
-
}
|
|
12051
|
-
if (defMatch && method === "DELETE") {
|
|
12052
|
-
const deleted = store.deleteDefinition(defMatch[1]);
|
|
12053
|
-
if (!deleted) return json(res, 404, { error: "Not found" });
|
|
12054
|
-
return json(res, 204, null);
|
|
12055
|
-
}
|
|
12056
|
-
if (path === "/api/v1/workflow/instances" && method === "GET") {
|
|
12057
|
-
const result = store.listInstances({
|
|
12058
|
-
definition_id: query.definition_id,
|
|
12059
|
-
limit: query.limit ? parseInt(query.limit, 10) : void 0,
|
|
12060
|
-
offset: query.offset ? parseInt(query.offset, 10) : void 0
|
|
12061
|
-
});
|
|
12062
|
-
return json(res, 200, result);
|
|
12063
|
-
}
|
|
12064
|
-
if (path === "/api/v1/workflow/instances" && method === "POST") {
|
|
12065
|
-
const body = JSON.parse(await readBody(req));
|
|
12066
|
-
const inst = store.createInstance(body);
|
|
12067
|
-
if (!inst) return json(res, 404, { error: "Definition not found" });
|
|
12068
|
-
return json(res, 201, inst);
|
|
12069
|
-
}
|
|
12070
|
-
const instMatch = path.match(/^\/api\/v1\/workflow\/instances\/([^/]+)$/);
|
|
12071
|
-
if (instMatch && method === "GET") {
|
|
12072
|
-
const inst = store.getInstance(instMatch[1]);
|
|
12073
|
-
if (!inst) return json(res, 404, { error: "Not found" });
|
|
12074
|
-
return json(res, 200, inst);
|
|
12075
|
-
}
|
|
12076
|
-
if (path === "/api/v1/workflow/execute-action" && method === "POST") {
|
|
12077
|
-
const body = JSON.parse(await readBody(req));
|
|
12078
|
-
const result = store.executeAction(body);
|
|
12079
|
-
return json(res, 200, result);
|
|
12080
|
-
}
|
|
12081
|
-
const dataMatch = path.match(/^\/api\/v1\/data\/([^/]+)$/);
|
|
12082
|
-
if (dataMatch && method === "GET") {
|
|
12083
|
-
const def = store.getDefinition(dataMatch[1]);
|
|
12084
|
-
if (!def) return json(res, 404, { error: "Not found" });
|
|
12085
|
-
const instances = store.listInstances({ definition_id: def.id });
|
|
12086
|
-
return json(res, 200, instances);
|
|
12087
|
-
}
|
|
12088
|
-
if (path.startsWith("/api/v1/")) {
|
|
12089
|
-
return json(res, 501, { error: "Not implemented in local dev mode", path, method });
|
|
12090
|
-
}
|
|
12091
|
-
return json(res, 404, { error: "Not found", path });
|
|
12092
|
-
} catch (err) {
|
|
12093
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
12094
|
-
console.error(`[mm-local] ${method} ${path} \u2014 Error: ${message}`);
|
|
12095
|
-
return json(res, 500, { error: message });
|
|
12096
|
-
}
|
|
12097
|
-
});
|
|
12098
|
-
return new Promise((resolve2, reject) => {
|
|
12099
|
-
server.on("error", (err) => {
|
|
12100
|
-
if (err.code === "EADDRINUSE") {
|
|
12101
|
-
reject(new Error(`Port ${port} is already in use. Is another server running?`));
|
|
12102
|
-
} else {
|
|
12103
|
-
reject(err);
|
|
12104
|
-
}
|
|
12105
|
-
});
|
|
12106
|
-
server.listen(port, () => {
|
|
12107
|
-
console.log(`[mm-local] Local API server running at http://localhost:${port}`);
|
|
12108
|
-
console.log(`[mm-local] Mode: in-memory (data lost on restart)`);
|
|
12109
|
-
console.log(`[mm-local] Auth: disabled (all requests accepted)`);
|
|
12110
|
-
resolve2({
|
|
12111
|
-
server,
|
|
12112
|
-
port,
|
|
12113
|
-
store,
|
|
12114
|
-
async close() {
|
|
12115
|
-
return new Promise((res) => {
|
|
12116
|
-
server.close(() => {
|
|
12117
|
-
console.log("[mm-local] Local API server stopped");
|
|
12118
|
-
res();
|
|
12119
|
-
});
|
|
12120
|
-
});
|
|
12121
|
-
}
|
|
12122
|
-
});
|
|
12123
|
-
});
|
|
12124
|
-
});
|
|
12125
|
-
}
|
|
12126
|
-
|
|
12127
11714
|
// src/dev-server.ts
|
|
12128
11715
|
var currentErrors = null;
|
|
12129
11716
|
function escapeHtml(s) {
|
|
@@ -12300,34 +11887,33 @@ async function createDevServer(options = {}) {
|
|
|
12300
11887
|
open = false
|
|
12301
11888
|
} = options;
|
|
12302
11889
|
const clients = /* @__PURE__ */ new Set();
|
|
12303
|
-
let localServer = null;
|
|
12304
11890
|
let apiUrl;
|
|
12305
|
-
|
|
12306
|
-
|
|
12307
|
-
|
|
12308
|
-
|
|
12309
|
-
|
|
12310
|
-
|
|
12311
|
-
|
|
12312
|
-
|
|
12313
|
-
|
|
12314
|
-
apiUrl = defaultRemote;
|
|
12315
|
-
} else {
|
|
12316
|
-
const localHealth = await checkBackendHealth("http://localhost:4200/api/v1");
|
|
12317
|
-
if (localHealth.ok) {
|
|
12318
|
-
apiUrl = "http://localhost:4200/api/v1";
|
|
11891
|
+
if (rawApiUrl === "local" || rawApiUrl === "auto") {
|
|
11892
|
+
const localHealth = await checkBackendHealth("http://localhost:4200/api/v1");
|
|
11893
|
+
if (localHealth.ok) {
|
|
11894
|
+
apiUrl = "http://localhost:4200/api/v1";
|
|
11895
|
+
} else if (rawApiUrl === "auto") {
|
|
11896
|
+
const defaultRemote = "https://dev.mindmatrix.club/api/v1";
|
|
11897
|
+
const remoteHealth = await checkBackendHealth(defaultRemote);
|
|
11898
|
+
if (remoteHealth.ok) {
|
|
11899
|
+
apiUrl = defaultRemote;
|
|
12319
11900
|
} else {
|
|
12320
|
-
console.
|
|
12321
|
-
|
|
11901
|
+
console.error("[mm-dev] No backend detected. Start the engine first:");
|
|
11902
|
+
console.error(" mmrc dev (auto-starts engine)");
|
|
11903
|
+
console.error(" mmrc engine start (manual start)");
|
|
11904
|
+
console.error("[mm-dev] Or specify a remote API: mmrc dev --api-url https://...");
|
|
12322
11905
|
apiUrl = "http://localhost:4200/api/v1";
|
|
12323
|
-
isLocalMode = true;
|
|
12324
11906
|
}
|
|
11907
|
+
} else {
|
|
11908
|
+
console.error("[mm-dev] Local engine not running on port 4200.");
|
|
11909
|
+
console.error(" Start it with: mmrc dev (or mmrc engine start)");
|
|
11910
|
+
apiUrl = "http://localhost:4200/api/v1";
|
|
12325
11911
|
}
|
|
12326
11912
|
} else {
|
|
12327
11913
|
apiUrl = rawApiUrl;
|
|
12328
11914
|
}
|
|
12329
|
-
const token =
|
|
12330
|
-
const health =
|
|
11915
|
+
const token = await resolveDevToken(apiUrl, explicitToken);
|
|
11916
|
+
const health = await checkBackendHealth(apiUrl);
|
|
12331
11917
|
let initialSlug, initialCompiled = 0, initialDeployed = false, initialErrors = 0;
|
|
12332
11918
|
if (token && health.ok) {
|
|
12333
11919
|
const r = await initialBuildDeploy(src, outDir, mode, apiUrl, token);
|
|
@@ -12387,74 +11973,163 @@ createRoot(document.getElementById('root')).render(React.createElement(App));
|
|
|
12387
11973
|
`;
|
|
12388
11974
|
}
|
|
12389
11975
|
};
|
|
12390
|
-
const
|
|
11976
|
+
const { existsSync: fsExists } = await import("fs");
|
|
11977
|
+
const projectIndexPath = require("path").join(process.cwd(), "index.html");
|
|
11978
|
+
const hasProjectIndex = fsExists(projectIndexPath);
|
|
11979
|
+
if (!hasProjectIndex) {
|
|
11980
|
+
const { writeFileSync: fsWrite } = await import("fs");
|
|
11981
|
+
fsWrite(projectIndexPath, `<!DOCTYPE html>
|
|
12391
11982
|
<html lang="en">
|
|
12392
11983
|
<head>
|
|
12393
11984
|
<meta charset="UTF-8">
|
|
12394
11985
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
12395
11986
|
<title>MindMatrix Dev</title>
|
|
12396
|
-
<style>
|
|
12397
|
-
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
12398
|
-
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: #fafafa; color: #111; }
|
|
12399
|
-
#root { min-height: 100vh; }
|
|
12400
|
-
.mm-loading { display: flex; align-items: center; justify-content: center; min-height: 100vh; flex-direction: column; gap: 12px; }
|
|
12401
|
-
.mm-loading h1 { font-size: 20px; font-weight: 600; color: #333; }
|
|
12402
|
-
.mm-loading p { color: #888; font-size: 14px; }
|
|
12403
|
-
</style>
|
|
12404
11987
|
</head>
|
|
12405
11988
|
<body>
|
|
12406
|
-
<div id="root">
|
|
12407
|
-
|
|
12408
|
-
|
|
12409
|
-
|
|
12410
|
-
|
|
12411
|
-
|
|
12412
|
-
|
|
12413
|
-
|
|
12414
|
-
|
|
11989
|
+
<div id="root"></div>
|
|
11990
|
+
<script type="module" src="/__mm_dev_entry.tsx"></script>
|
|
11991
|
+
</body>
|
|
11992
|
+
</html>`, "utf-8");
|
|
11993
|
+
}
|
|
11994
|
+
const devEntryPlugin = {
|
|
11995
|
+
name: "mindmatrix-dev-entry",
|
|
11996
|
+
resolveId(id) {
|
|
11997
|
+
if (id === "/__mm_dev_entry.tsx") return id;
|
|
11998
|
+
return null;
|
|
11999
|
+
},
|
|
12000
|
+
load(id) {
|
|
12001
|
+
if (id !== "/__mm_dev_entry.tsx") return null;
|
|
12002
|
+
return `
|
|
12003
|
+
import React, { useState, useEffect } from 'react';
|
|
12004
|
+
import { createRoot } from 'react-dom/client';
|
|
12005
|
+
import { DevPlayer } from '@mmapp/react/player';
|
|
12006
|
+
import { PlayerProvider, ExperienceRenderer, createApiResolver } from '@mmapp/react/player';
|
|
12415
12007
|
|
|
12416
|
-
|
|
12417
|
-
|
|
12418
|
-
|
|
12008
|
+
// Detect API base URL \u2014 proxy through dev server or use direct URL
|
|
12009
|
+
const API_BASE = window.location.origin + '/api/v1';
|
|
12010
|
+
const resolver = createApiResolver({ baseUrl: API_BASE, token: () => localStorage.getItem('auth_token') });
|
|
12419
12011
|
|
|
12420
|
-
|
|
12421
|
-
|
|
12422
|
-
|
|
12423
|
-
|
|
12424
|
-
|
|
12425
|
-
|
|
12012
|
+
/**
|
|
12013
|
+
* Prepare experience tree for rendering.
|
|
12014
|
+
* Attaches metadata.dataSources to the root node and remaps
|
|
12015
|
+
* dataSource slugs to use definition-relative naming.
|
|
12016
|
+
*
|
|
12017
|
+
* @param definition - The main blueprint definition
|
|
12018
|
+
* @param allDefinitions - ALL definitions from the API (used for slug resolution)
|
|
12019
|
+
*/
|
|
12020
|
+
function prepareTree(definition, allDefinitions) {
|
|
12021
|
+
const exp = definition.experience;
|
|
12022
|
+
if (!exp || typeof exp !== 'object') return null;
|
|
12426
12023
|
|
|
12427
|
-
|
|
12428
|
-
|
|
12429
|
-
|
|
12430
|
-
React.createElement('p', { style: { color: '#888', marginTop: 8 } }, 'The engine is running but the API returned an error. This may be an auth issue in SQLite mode.')
|
|
12431
|
-
);
|
|
12024
|
+
const meta = definition.metadata || {};
|
|
12025
|
+
const dataSources = meta.dataSources || [];
|
|
12026
|
+
const mutationTargets = meta.mutationTargets || [];
|
|
12432
12027
|
|
|
12433
|
-
|
|
12434
|
-
|
|
12435
|
-
|
|
12436
|
-
|
|
12437
|
-
|
|
12438
|
-
|
|
12439
|
-
|
|
12440
|
-
|
|
12441
|
-
|
|
12442
|
-
|
|
12443
|
-
|
|
12444
|
-
|
|
12445
|
-
|
|
12446
|
-
|
|
12028
|
+
// Build a slug map from ALL deployed definitions
|
|
12029
|
+
// This resolves bare model names (e.g. "item") to full slugs (e.g. "tutorial-1-item")
|
|
12030
|
+
const blueprintSlug = definition.slug || '';
|
|
12031
|
+
const allSlugs = (allDefinitions || []).map(d => d.slug).filter(Boolean);
|
|
12032
|
+
|
|
12033
|
+
function resolveSlug(bareSlug) {
|
|
12034
|
+
if (!bareSlug) return bareSlug;
|
|
12035
|
+
// Already a full slug (contains hyphen matching a known definition)
|
|
12036
|
+
if (allSlugs.includes(bareSlug)) return bareSlug;
|
|
12037
|
+
// Try blueprint-prefixed slug: "item" \u2192 "tutorial-1-item"
|
|
12038
|
+
const prefixed = blueprintSlug + '-' + bareSlug;
|
|
12039
|
+
if (allSlugs.includes(prefixed)) return prefixed;
|
|
12040
|
+
// Try matching by suffix across all definitions
|
|
12041
|
+
const match = allSlugs.find(s => s.endsWith('-' + bareSlug));
|
|
12042
|
+
if (match) return match;
|
|
12043
|
+
// Return original (will attempt as-is)
|
|
12044
|
+
return bareSlug;
|
|
12045
|
+
}
|
|
12046
|
+
|
|
12047
|
+
// Clone root node and attach dataSources
|
|
12048
|
+
const root = { ...exp };
|
|
12049
|
+
if (dataSources.length > 0 && !root.dataSources) {
|
|
12050
|
+
root.dataSources = dataSources.map(ds => ({
|
|
12051
|
+
...ds,
|
|
12052
|
+
slug: resolveSlug(ds.slug),
|
|
12053
|
+
}));
|
|
12054
|
+
}
|
|
12055
|
+
|
|
12056
|
+
// Remap mutation targets the same way
|
|
12057
|
+
if (mutationTargets.length > 0) {
|
|
12058
|
+
const resolvedTargets = mutationTargets.map(t => resolveSlug(t));
|
|
12059
|
+
root.config = { ...(root.config || {}), _mutationTargets: resolvedTargets };
|
|
12060
|
+
}
|
|
12061
|
+
|
|
12062
|
+
return root;
|
|
12063
|
+
}
|
|
12064
|
+
|
|
12065
|
+
function App() {
|
|
12066
|
+
const [tree, setTree] = useState(null);
|
|
12067
|
+
const [error, setError] = useState(null);
|
|
12068
|
+
|
|
12069
|
+
useEffect(() => {
|
|
12070
|
+
async function loadTree() {
|
|
12071
|
+
try {
|
|
12072
|
+
const res = await fetch(API_BASE + '/workflow/definitions');
|
|
12073
|
+
const json = await res.json();
|
|
12074
|
+
const items = json.items || json.data || [];
|
|
12075
|
+
// Find the main blueprint definition (has experience tree)
|
|
12076
|
+
const main = items.find(d => d.experience && !(Array.isArray(d.category) ? d.category.includes('data') : d.category === 'data')) || items.find(d => d.experience) || items[0];
|
|
12077
|
+
if (main?.experience) {
|
|
12078
|
+
const prepared = prepareTree(main, items);
|
|
12079
|
+
if (prepared) {
|
|
12080
|
+
setTree(prepared);
|
|
12081
|
+
return;
|
|
12082
|
+
}
|
|
12083
|
+
}
|
|
12084
|
+
if (main) {
|
|
12085
|
+
// No experience tree \u2014 show definition info
|
|
12086
|
+
setTree({
|
|
12087
|
+
type: 'Stack',
|
|
12088
|
+
props: { style: { padding: 40, gap: 16 } },
|
|
12089
|
+
children: [
|
|
12090
|
+
{ type: 'Text', props: { children: main.name || main.slug, style: { fontSize: 24, fontWeight: 'bold' } } },
|
|
12091
|
+
{ type: 'Text', props: { children: (main.states?.length || 0) + ' states, ' + (main.fields?.length || 0) + ' fields', style: { color: '#666' } } },
|
|
12092
|
+
...items.map((d, i) => ({
|
|
12093
|
+
type: 'Card',
|
|
12094
|
+
props: { key: i, style: { padding: 16, border: '1px solid #ddd', borderRadius: 8 } },
|
|
12095
|
+
children: [
|
|
12096
|
+
{ type: 'Text', props: { children: d.name || d.slug, style: { fontWeight: 600 } } },
|
|
12097
|
+
{ type: 'Text', props: { children: 'slug: ' + d.slug + ' | ' + (d.states?.length || 0) + ' states', style: { fontSize: 13, color: '#888' } } },
|
|
12098
|
+
],
|
|
12099
|
+
})),
|
|
12100
|
+
],
|
|
12101
|
+
});
|
|
12102
|
+
}
|
|
12103
|
+
} catch (e) {
|
|
12104
|
+
setError(e.message);
|
|
12105
|
+
}
|
|
12447
12106
|
}
|
|
12107
|
+
loadTree();
|
|
12108
|
+
}, []);
|
|
12448
12109
|
|
|
12449
|
-
|
|
12450
|
-
|
|
12451
|
-
|
|
12452
|
-
|
|
12453
|
-
|
|
12454
|
-
|
|
12455
|
-
|
|
12456
|
-
|
|
12457
|
-
|
|
12110
|
+
if (error) return React.createElement('div', { style: { padding: 40 } },
|
|
12111
|
+
React.createElement('h1', null, 'MindMatrix Dev'),
|
|
12112
|
+
React.createElement('p', { style: { color: '#c00' } }, 'Error: ' + error)
|
|
12113
|
+
);
|
|
12114
|
+
|
|
12115
|
+
if (!tree) return React.createElement('div', { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', minHeight: '100vh' } },
|
|
12116
|
+
React.createElement('p', null, 'Loading...')
|
|
12117
|
+
);
|
|
12118
|
+
|
|
12119
|
+
// If tree has 'component' field, use ExperienceRenderer; otherwise legacy DevPlayer
|
|
12120
|
+
if (tree.component) {
|
|
12121
|
+
return React.createElement(PlayerProvider, { resolver },
|
|
12122
|
+
React.createElement(ExperienceRenderer, { tree, className: 'mm-experience-root' })
|
|
12123
|
+
);
|
|
12124
|
+
}
|
|
12125
|
+
|
|
12126
|
+
return React.createElement(DevPlayer, { tree, title: document.title || 'MindMatrix Dev' });
|
|
12127
|
+
}
|
|
12128
|
+
|
|
12129
|
+
createRoot(document.getElementById('root')).render(React.createElement(App));
|
|
12130
|
+
`;
|
|
12131
|
+
}
|
|
12132
|
+
};
|
|
12458
12133
|
let deployInFlight = false;
|
|
12459
12134
|
const compileDeployPlugin = {
|
|
12460
12135
|
name: "mindmatrix-dev-compile-deploy",
|
|
@@ -12485,16 +12160,16 @@ createRoot(document.getElementById('root')).render(React.createElement(App));
|
|
|
12485
12160
|
}
|
|
12486
12161
|
};
|
|
12487
12162
|
const viteConfig = {
|
|
12488
|
-
//
|
|
12489
|
-
root:
|
|
12490
|
-
// Pre-bundle React
|
|
12163
|
+
// Use the blueprint directory as Vite root (has node_modules with React).
|
|
12164
|
+
root: process.cwd(),
|
|
12165
|
+
// Pre-bundle React and the player for fast dev startup.
|
|
12491
12166
|
optimizeDeps: { include: ["react", "react-dom/client"] },
|
|
12492
12167
|
server: {
|
|
12493
12168
|
port,
|
|
12494
12169
|
open,
|
|
12495
12170
|
host: true,
|
|
12496
12171
|
// Allow serving files from the real project directory (fs.allow).
|
|
12497
|
-
fs: { allow: [
|
|
12172
|
+
fs: { allow: [process.cwd(), ".."] },
|
|
12498
12173
|
proxy: {
|
|
12499
12174
|
"/api": { target: proxyTarget, changeOrigin: true, secure: true, ws: true },
|
|
12500
12175
|
"/health": { target: proxyTarget, changeOrigin: true, secure: true },
|
|
@@ -12504,6 +12179,7 @@ createRoot(document.getElementById('root')).render(React.createElement(App));
|
|
|
12504
12179
|
plugins: [
|
|
12505
12180
|
mindmatrixReact(pluginOpts),
|
|
12506
12181
|
compileDeployPlugin,
|
|
12182
|
+
devEntryPlugin,
|
|
12507
12183
|
devPlayerPlugin,
|
|
12508
12184
|
{ name: "mindmatrix-error-overlay", configureServer(server) {
|
|
12509
12185
|
server.middlewares.use(errorOverlayMiddleware());
|
|
@@ -12511,8 +12187,8 @@ createRoot(document.getElementById('root')).render(React.createElement(App));
|
|
|
12511
12187
|
],
|
|
12512
12188
|
logLevel: "warn"
|
|
12513
12189
|
};
|
|
12514
|
-
const { createServer
|
|
12515
|
-
const vite = await
|
|
12190
|
+
const { createServer } = await import("vite");
|
|
12191
|
+
const vite = await createServer(viteConfig);
|
|
12516
12192
|
await vite.listen();
|
|
12517
12193
|
const resolvedPort = vite.config.server.port ?? port;
|
|
12518
12194
|
if (enableWs && vite.httpServer) {
|
|
@@ -12530,7 +12206,7 @@ createRoot(document.getElementById('root')).render(React.createElement(App));
|
|
|
12530
12206
|
} catch {
|
|
12531
12207
|
}
|
|
12532
12208
|
}
|
|
12533
|
-
printBanner({ port: resolvedPort, apiUrl
|
|
12209
|
+
printBanner({ port: resolvedPort, apiUrl, src, include, health, token: !!token, compiled: initialCompiled, deployed: initialDeployed, slug: initialSlug, errors: initialErrors });
|
|
12534
12210
|
return {
|
|
12535
12211
|
vite,
|
|
12536
12212
|
port: resolvedPort,
|
|
@@ -12562,14 +12238,6 @@ createRoot(document.getElementById('root')).render(React.createElement(App));
|
|
|
12562
12238
|
clients.clear();
|
|
12563
12239
|
currentErrors = null;
|
|
12564
12240
|
await vite.close();
|
|
12565
|
-
if (localServer) {
|
|
12566
|
-
await localServer.close();
|
|
12567
|
-
}
|
|
12568
|
-
try {
|
|
12569
|
-
const { rmSync } = await import("fs");
|
|
12570
|
-
rmSync(devRoot, { recursive: true, force: true });
|
|
12571
|
-
} catch {
|
|
12572
|
-
}
|
|
12573
12241
|
}
|
|
12574
12242
|
};
|
|
12575
12243
|
}
|