@ddd-ts/event-tree 0.0.0-eventviz.14 → 0.0.0-eventviz.16
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/engine/config.d.ts +25 -0
- package/dist/engine/config.d.ts.map +1 -0
- package/dist/engine/config.mjs +28 -0
- package/dist/engine/defaults/_example.d.ts +2 -1
- package/dist/engine/defaults/_example.d.ts.map +1 -1
- package/dist/engine/defaults/_utils.d.ts +15 -0
- package/dist/engine/defaults/_utils.d.ts.map +1 -1
- package/dist/engine/defaults/_utils.mjs +52 -19
- package/dist/engine/defaults/command-handler.d.ts +2 -1
- package/dist/engine/defaults/command-handler.d.ts.map +1 -1
- package/dist/engine/defaults/command-handler.mjs +51 -29
- package/dist/engine/defaults/command.d.ts +2 -1
- package/dist/engine/defaults/command.d.ts.map +1 -1
- package/dist/engine/defaults/command.mjs +23 -22
- package/dist/engine/defaults/es-aggregate.d.ts +2 -1
- package/dist/engine/defaults/es-aggregate.d.ts.map +1 -1
- package/dist/engine/defaults/es-aggregate.mjs +72 -71
- package/dist/engine/defaults/event.d.ts +2 -1
- package/dist/engine/defaults/event.d.ts.map +1 -1
- package/dist/engine/defaults/event.mjs +29 -28
- package/dist/engine/defaults/index.d.ts +2 -7
- package/dist/engine/defaults/index.d.ts.map +1 -1
- package/dist/engine/defaults/index.mjs +21 -8
- package/dist/engine/defaults/method-index.d.ts +11 -0
- package/dist/engine/defaults/method-index.d.ts.map +1 -0
- package/dist/engine/defaults/method-index.mjs +24 -0
- package/dist/engine/defaults/projection.d.ts +2 -1
- package/dist/engine/defaults/projection.d.ts.map +1 -1
- package/dist/engine/defaults/projection.mjs +48 -47
- package/dist/engine/defaults/saga.d.ts +2 -1
- package/dist/engine/defaults/saga.d.ts.map +1 -1
- package/dist/engine/defaults/saga.mjs +67 -66
- package/dist/engine/defaults/scanner.d.ts +2 -1
- package/dist/engine/defaults/scanner.d.ts.map +1 -1
- package/dist/engine/defaults/scanner.mjs +24 -23
- package/dist/engine/engine.d.ts +27 -0
- package/dist/engine/engine.d.ts.map +1 -1
- package/dist/engine/engine.mjs +55 -3
- package/dist/index.mjs +3 -2
- package/dist/server/index.d.ts +2 -1
- package/dist/server/index.d.ts.map +1 -1
- package/package.json +3 -2
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Engine } from "./engine";
|
|
2
|
+
export interface EventTreeConfig {
|
|
3
|
+
/**
|
|
4
|
+
* A fully custom engine. When provided, defaults are not applied and `setup`
|
|
5
|
+
* is ignored — the engine is used as-is.
|
|
6
|
+
*/
|
|
7
|
+
engine?: Engine;
|
|
8
|
+
/**
|
|
9
|
+
* Hook to extend the default engine with extra parsers/scanners.
|
|
10
|
+
* Ignored when `engine` is provided.
|
|
11
|
+
*/
|
|
12
|
+
setup?: (engine: Engine) => void | Promise<void>;
|
|
13
|
+
}
|
|
14
|
+
export declare function defineConfig(config: EventTreeConfig): EventTreeConfig;
|
|
15
|
+
/**
|
|
16
|
+
* Loads the user's event-tree config (if any) and returns an Engine.
|
|
17
|
+
*
|
|
18
|
+
* Looks for `.config/ddd-ts/event-tree.{ts,js,mjs,cjs,json,…}` relative to
|
|
19
|
+
* `cwd`. The `.config/ddd-ts/` folder is the shared home for all ddd-ts tool
|
|
20
|
+
* configs.
|
|
21
|
+
*
|
|
22
|
+
* If no config is found, the default engine is returned.
|
|
23
|
+
*/
|
|
24
|
+
export declare function loadEngine(cwd?: string): Promise<Engine>;
|
|
25
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/engine/config.ts"],"names":[],"mappings":"AACA,OAAO,EAAuB,MAAM,EAAE,MAAM,UAAU,CAAC;AAEvD,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAClD;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,eAAe,GAAG,eAAe,CAErE;AAED;;;;;;;;GAQG;AACH,wBAAsB,UAAU,CAAC,GAAG,GAAE,MAAsB,GAAG,OAAO,CAAC,MAAM,CAAC,CAc7E"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { createDefaultEngine } from "./engine.mjs";
|
|
2
|
+
import { loadConfig } from "c12";
|
|
3
|
+
//#region src/engine/config.ts
|
|
4
|
+
function defineConfig(config) {
|
|
5
|
+
return config;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Loads the user's event-tree config (if any) and returns an Engine.
|
|
9
|
+
*
|
|
10
|
+
* Looks for `.config/ddd-ts/event-tree.{ts,js,mjs,cjs,json,…}` relative to
|
|
11
|
+
* `cwd`. The `.config/ddd-ts/` folder is the shared home for all ddd-ts tool
|
|
12
|
+
* configs.
|
|
13
|
+
*
|
|
14
|
+
* If no config is found, the default engine is returned.
|
|
15
|
+
*/
|
|
16
|
+
async function loadEngine(cwd = process.cwd()) {
|
|
17
|
+
const { config } = await loadConfig({
|
|
18
|
+
cwd,
|
|
19
|
+
configFile: ".config/ddd-ts/event-tree",
|
|
20
|
+
rcFile: false
|
|
21
|
+
});
|
|
22
|
+
if (config?.engine) return config.engine;
|
|
23
|
+
const engine = createDefaultEngine();
|
|
24
|
+
if (config?.setup) await config.setup(engine);
|
|
25
|
+
return engine;
|
|
26
|
+
}
|
|
27
|
+
//#endregion
|
|
28
|
+
export { defineConfig, loadEngine };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"_example.d.ts","sourceRoot":"","sources":["../../../src/engine/defaults/_example.ts"],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"_example.d.ts","sourceRoot":"","sources":["../../../src/engine/defaults/_example.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAExC,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,QAMlD"}
|
|
@@ -5,10 +5,25 @@ export declare function walkSubtree(node: Node | null | undefined, visit: (n: No
|
|
|
5
5
|
export declare function readStringLiteral(node: Node | null | undefined): string | null;
|
|
6
6
|
export declare function superGenericIdentifier(node: Class): string | null;
|
|
7
7
|
export declare function reactorEvents(decorators: Decorator[] | undefined, allowedCallees: Set<string>): string[];
|
|
8
|
+
/**
|
|
9
|
+
* Resolves the constructed type name from the ddd-ts construction idioms:
|
|
10
|
+
* `new X(...)`, `X.new(...)` and `X.parse(...)`. Events and commands are most
|
|
11
|
+
* often created through the static `.new()`/`.parse()` factories rather than
|
|
12
|
+
* the `new` operator, so both must be recognised.
|
|
13
|
+
*/
|
|
14
|
+
export declare function constructedName(node: Node | null | undefined): string | null;
|
|
8
15
|
export declare function methodEffects(method: MethodDefinition): {
|
|
9
16
|
sends: string[];
|
|
10
17
|
emits: string[];
|
|
11
18
|
};
|
|
19
|
+
/**
|
|
20
|
+
* Events applied within a method via the aggregate idiom `this.apply(Event.new(...))`
|
|
21
|
+
* (or `this.apply(new Event(...))`). Unlike `methodEffects`, this is scoped to
|
|
22
|
+
* `this.apply(...)` only, so it captures event-application methods (the
|
|
23
|
+
* behaviours a command handler delegates to) without sweeping up command
|
|
24
|
+
* dispatching or unrelated constructions.
|
|
25
|
+
*/
|
|
26
|
+
export declare function appliedEvents(method: MethodDefinition): string[];
|
|
12
27
|
export declare function classMethods(node: Class): MethodDefinition[];
|
|
13
28
|
export declare function methodName(method: MethodDefinition): string | null;
|
|
14
29
|
//# sourceMappingURL=_utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"_utils.d.ts","sourceRoot":"","sources":["../../../src/engine/defaults/_utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,KAAK,EACL,SAAS,EACT,gBAAgB,EAChB,IAAI,EACL,MAAM,YAAY,CAAC;AAEpB,wBAAgB,cAAc,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAM3E;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAQvE;AAOD,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,IAAI,KAAK,IAAI,QAYlF;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,SAAS,iBAK9D;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,KAAK,iBAKjD;AAED,wBAAgB,aAAa,CAC3B,UAAU,EAAE,SAAS,EAAE,GAAG,SAAS,EACnC,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,YAc5B;AAKD,wBAAgB,aAAa,CAAC,MAAM,EAAE,gBAAgB;;;
|
|
1
|
+
{"version":3,"file":"_utils.d.ts","sourceRoot":"","sources":["../../../src/engine/defaults/_utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,KAAK,EACL,SAAS,EACT,gBAAgB,EAChB,IAAI,EACL,MAAM,YAAY,CAAC;AAEpB,wBAAgB,cAAc,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAM3E;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAQvE;AAOD,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,IAAI,KAAK,IAAI,QAYlF;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,SAAS,iBAK9D;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,KAAK,iBAKjD;AAED,wBAAgB,aAAa,CAC3B,UAAU,EAAE,SAAS,EAAE,GAAG,SAAS,EACnC,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,YAc5B;AAKD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAU5E;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,gBAAgB;;;EAiCrD;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,EAAE,CAWhE;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,KAAK,sBAQvC;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,gBAAgB,iBAElD"}
|
|
@@ -59,40 +59,73 @@ const SEND_MEMBERS = new Set([
|
|
|
59
59
|
"dispatch",
|
|
60
60
|
"send"
|
|
61
61
|
]);
|
|
62
|
-
const EMIT_MEMBERS = new Set([
|
|
62
|
+
const EMIT_MEMBERS = new Set([
|
|
63
|
+
"publish",
|
|
64
|
+
"emit",
|
|
65
|
+
"apply"
|
|
66
|
+
]);
|
|
67
|
+
/**
|
|
68
|
+
* Resolves the constructed type name from the ddd-ts construction idioms:
|
|
69
|
+
* `new X(...)`, `X.new(...)` and `X.parse(...)`. Events and commands are most
|
|
70
|
+
* often created through the static `.new()`/`.parse()` factories rather than
|
|
71
|
+
* the `new` operator, so both must be recognised.
|
|
72
|
+
*/
|
|
73
|
+
function constructedName(node) {
|
|
74
|
+
if (!node) return null;
|
|
75
|
+
if (node.type === "NewExpression") return identifierName(node.callee);
|
|
76
|
+
if (node.type === "CallExpression" && node.callee.type === "MemberExpression") {
|
|
77
|
+
const factory = identifierName(node.callee.property);
|
|
78
|
+
if (factory === "new" || factory === "parse") return identifierName(node.callee.object);
|
|
79
|
+
}
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
63
82
|
function methodEffects(method) {
|
|
64
83
|
const sends = /* @__PURE__ */ new Set();
|
|
65
84
|
const emits = /* @__PURE__ */ new Set();
|
|
66
|
-
const
|
|
85
|
+
const consumed = /* @__PURE__ */ new WeakSet();
|
|
67
86
|
walkSubtree(method.value.body, (n) => {
|
|
68
87
|
if (n.type !== "CallExpression") return;
|
|
69
|
-
const a0 = n.arguments[0];
|
|
70
|
-
let arg0New = null;
|
|
71
|
-
if (a0?.type === "NewExpression") arg0New = identifierName(a0.callee);
|
|
72
|
-
else if (a0?.type === "Identifier") arg0New = a0.name;
|
|
73
|
-
if (!arg0New) return;
|
|
74
88
|
if (n.callee.type !== "MemberExpression") return;
|
|
75
89
|
const member = identifierName(n.callee.property);
|
|
76
90
|
if (!member) return;
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
91
|
+
const isSend = SEND_MEMBERS.has(member);
|
|
92
|
+
const isEmit = EMIT_MEMBERS.has(member);
|
|
93
|
+
if (!isSend && !isEmit) return;
|
|
94
|
+
const a0 = n.arguments[0];
|
|
95
|
+
const name = constructedName(a0) ?? (a0?.type === "Identifier" ? a0.name : null);
|
|
96
|
+
if (!name) return;
|
|
97
|
+
(isSend ? sends : emits).add(name);
|
|
98
|
+
if (a0 && (a0.type === "NewExpression" || a0.type === "CallExpression")) consumed.add(a0);
|
|
84
99
|
});
|
|
85
100
|
walkSubtree(method.value.body, (n) => {
|
|
86
|
-
if (n
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
if (id) emits.add(id);
|
|
101
|
+
if (consumed.has(n)) return;
|
|
102
|
+
const name = constructedName(n);
|
|
103
|
+
if (name) emits.add(name);
|
|
90
104
|
});
|
|
91
105
|
return {
|
|
92
106
|
sends: [...sends],
|
|
93
107
|
emits: [...emits]
|
|
94
108
|
};
|
|
95
109
|
}
|
|
110
|
+
/**
|
|
111
|
+
* Events applied within a method via the aggregate idiom `this.apply(Event.new(...))`
|
|
112
|
+
* (or `this.apply(new Event(...))`). Unlike `methodEffects`, this is scoped to
|
|
113
|
+
* `this.apply(...)` only, so it captures event-application methods (the
|
|
114
|
+
* behaviours a command handler delegates to) without sweeping up command
|
|
115
|
+
* dispatching or unrelated constructions.
|
|
116
|
+
*/
|
|
117
|
+
function appliedEvents(method) {
|
|
118
|
+
const events = /* @__PURE__ */ new Set();
|
|
119
|
+
walkSubtree(method.value.body, (n) => {
|
|
120
|
+
if (n.type !== "CallExpression") return;
|
|
121
|
+
if (n.callee.type !== "MemberExpression") return;
|
|
122
|
+
if (n.callee.object.type !== "ThisExpression") return;
|
|
123
|
+
if (identifierName(n.callee.property) !== "apply") return;
|
|
124
|
+
const name = constructedName(n.arguments[0]);
|
|
125
|
+
if (name) events.add(name);
|
|
126
|
+
});
|
|
127
|
+
return [...events];
|
|
128
|
+
}
|
|
96
129
|
function classMethods(node) {
|
|
97
130
|
const out = [];
|
|
98
131
|
for (const member of node.body.body) if (member.type === "MethodDefinition" || member.type === "TSAbstractMethodDefinition") out.push(member);
|
|
@@ -102,4 +135,4 @@ function methodName(method) {
|
|
|
102
135
|
return identifierName(method.key);
|
|
103
136
|
}
|
|
104
137
|
//#endregion
|
|
105
|
-
export { classMethods, identifierName, memberPath, methodEffects, methodName, reactorEvents, readStringLiteral, superGenericIdentifier, walkSubtree };
|
|
138
|
+
export { appliedEvents, classMethods, constructedName, identifierName, memberPath, methodEffects, methodName, reactorEvents, readStringLiteral, superGenericIdentifier, walkSubtree };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"command-handler.d.ts","sourceRoot":"","sources":["../../../src/engine/defaults/command-handler.ts"],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"command-handler.d.ts","sourceRoot":"","sources":["../../../src/engine/defaults/command-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAQxC,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,MAAM,QAsDzD"}
|
|
@@ -1,34 +1,56 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { identifierName, superGenericIdentifier, walkSubtree } from "./_utils.mjs";
|
|
1
|
+
import { constructedName, identifierName, superGenericIdentifier, walkSubtree } from "./_utils.mjs";
|
|
3
2
|
//#region src/engine/defaults/command-handler.ts
|
|
4
|
-
engine
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
3
|
+
function applyCommandHandlerDefaults(engine) {
|
|
4
|
+
engine.on((node, parent, ctx, file) => {
|
|
5
|
+
if (node.type !== "ClassDeclaration") return;
|
|
6
|
+
if (!node.id) return;
|
|
7
|
+
const sup = node.superClass;
|
|
8
|
+
if (sup?.type !== "Identifier" || sup.name !== "CommandHandler") return;
|
|
9
|
+
const command = superGenericIdentifier(node);
|
|
10
|
+
if (!command) return;
|
|
11
|
+
const seen = /* @__PURE__ */ new Set();
|
|
12
|
+
const invoked = /* @__PURE__ */ new Set();
|
|
13
|
+
walkSubtree(node.body, (n) => {
|
|
14
|
+
const created = constructedName(n);
|
|
15
|
+
if (created) {
|
|
16
|
+
if (!seen.has(created)) {
|
|
17
|
+
seen.add(created);
|
|
18
|
+
engine.saveEdge({
|
|
19
|
+
from: {
|
|
20
|
+
type: "command",
|
|
21
|
+
name: command
|
|
22
|
+
},
|
|
23
|
+
to: {
|
|
24
|
+
type: "event",
|
|
25
|
+
name: created
|
|
26
|
+
},
|
|
27
|
+
source: {
|
|
28
|
+
file,
|
|
29
|
+
start: n.start
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
if (n.type === "CallExpression" && n.callee.type === "MemberExpression" && n.callee.object.type === "Identifier") {
|
|
36
|
+
const method = identifierName(n.callee.property);
|
|
37
|
+
if (method && !invoked.has(method)) {
|
|
38
|
+
invoked.add(method);
|
|
39
|
+
engine.saveInvocation({
|
|
40
|
+
from: {
|
|
41
|
+
type: "command",
|
|
42
|
+
name: command
|
|
43
|
+
},
|
|
44
|
+
method,
|
|
45
|
+
source: {
|
|
46
|
+
file,
|
|
47
|
+
start: n.start
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
}
|
|
29
51
|
}
|
|
30
52
|
});
|
|
31
53
|
});
|
|
32
|
-
}
|
|
54
|
+
}
|
|
33
55
|
//#endregion
|
|
34
|
-
export {};
|
|
56
|
+
export { applyCommandHandlerDefaults };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../../src/engine/defaults/command.ts"],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../../src/engine/defaults/command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAIxC,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,QAyBlD"}
|
|
@@ -1,27 +1,28 @@
|
|
|
1
|
-
import { engine } from "../engine.mjs";
|
|
2
1
|
//#region src/engine/defaults/command.ts
|
|
3
2
|
const COMMAND_BASES = new Set(["$Command", "Command"]);
|
|
4
|
-
engine
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
if (
|
|
12
|
-
|
|
13
|
-
if (sup.
|
|
14
|
-
|
|
15
|
-
if (!base) return;
|
|
16
|
-
engine.saveNode({
|
|
17
|
-
type: "command",
|
|
18
|
-
name: node.id.name,
|
|
19
|
-
meta: { base },
|
|
20
|
-
source: {
|
|
21
|
-
file,
|
|
22
|
-
start: node.start
|
|
3
|
+
function applyCommandDefaults(engine) {
|
|
4
|
+
engine.on((node, parent, ctx, file) => {
|
|
5
|
+
if (node.type !== "ClassDeclaration") return;
|
|
6
|
+
if (!node.id) return;
|
|
7
|
+
const sup = node.superClass;
|
|
8
|
+
if (!sup) return;
|
|
9
|
+
let base = null;
|
|
10
|
+
if (sup.type === "Identifier") {
|
|
11
|
+
if (COMMAND_BASES.has(sup.name)) base = sup.name;
|
|
12
|
+
} else if (sup.type === "CallExpression") {
|
|
13
|
+
if (sup.callee?.type === "Identifier" && COMMAND_BASES.has(sup.callee.name)) base = sup.callee.name;
|
|
23
14
|
}
|
|
15
|
+
if (!base) return;
|
|
16
|
+
engine.saveNode({
|
|
17
|
+
type: "command",
|
|
18
|
+
name: node.id.name,
|
|
19
|
+
meta: { base },
|
|
20
|
+
source: {
|
|
21
|
+
file,
|
|
22
|
+
start: node.start
|
|
23
|
+
}
|
|
24
|
+
});
|
|
24
25
|
});
|
|
25
|
-
}
|
|
26
|
+
}
|
|
26
27
|
//#endregion
|
|
27
|
-
export {};
|
|
28
|
+
export { applyCommandDefaults };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"es-aggregate.d.ts","sourceRoot":"","sources":["../../../src/engine/defaults/es-aggregate.ts"],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"es-aggregate.d.ts","sourceRoot":"","sources":["../../../src/engine/defaults/es-aggregate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAUxC,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,QAwDtD"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { engine } from "../engine.mjs";
|
|
2
1
|
import { classMethods, methodEffects, methodName, reactorEvents } from "./_utils.mjs";
|
|
3
2
|
//#region src/engine/defaults/es-aggregate.ts
|
|
4
3
|
const REACTOR_DECORATORS = new Set([
|
|
@@ -6,75 +5,77 @@ const REACTOR_DECORATORS = new Set([
|
|
|
6
5
|
"on",
|
|
7
6
|
"On"
|
|
8
7
|
]);
|
|
9
|
-
engine
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
if (sup.
|
|
16
|
-
|
|
17
|
-
if (sup.
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
name: handlerName,
|
|
29
|
-
source: {
|
|
30
|
-
file,
|
|
31
|
-
start: method.start
|
|
32
|
-
}
|
|
33
|
-
});
|
|
34
|
-
for (const event of events) engine.saveEdge({
|
|
35
|
-
from: {
|
|
36
|
-
type: "event",
|
|
37
|
-
name: event
|
|
38
|
-
},
|
|
39
|
-
to: {
|
|
8
|
+
function applyEsAggregateDefaults(engine) {
|
|
9
|
+
engine.on((node, parent, ctx, file) => {
|
|
10
|
+
if (node.type !== "ClassDeclaration") return;
|
|
11
|
+
if (!node.id) return;
|
|
12
|
+
const sup = node.superClass;
|
|
13
|
+
if (!sup) return;
|
|
14
|
+
if (sup.type === "Identifier") {
|
|
15
|
+
if (sup.name !== "EsAggregate") return;
|
|
16
|
+
} else if (sup.type === "CallExpression") {
|
|
17
|
+
if (sup.callee?.type !== "Identifier" || sup.callee.name !== "EsAggregate") return;
|
|
18
|
+
} else return;
|
|
19
|
+
const className = node.id.name;
|
|
20
|
+
for (const method of classMethods(node)) {
|
|
21
|
+
const name = methodName(method);
|
|
22
|
+
if (!name) continue;
|
|
23
|
+
const events = reactorEvents(method.decorators, REACTOR_DECORATORS);
|
|
24
|
+
if (!events.length) continue;
|
|
25
|
+
const handlerName = `${className}.${name}`;
|
|
26
|
+
engine.saveNode({
|
|
40
27
|
type: "aggregate",
|
|
41
|
-
name: handlerName
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
28
|
+
name: handlerName,
|
|
29
|
+
source: {
|
|
30
|
+
file,
|
|
31
|
+
start: method.start
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
for (const event of events) engine.saveEdge({
|
|
35
|
+
from: {
|
|
36
|
+
type: "event",
|
|
37
|
+
name: event
|
|
38
|
+
},
|
|
39
|
+
to: {
|
|
40
|
+
type: "aggregate",
|
|
41
|
+
name: handlerName
|
|
42
|
+
},
|
|
43
|
+
source: {
|
|
44
|
+
file,
|
|
45
|
+
start: method.start
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
const effects = methodEffects(method);
|
|
49
|
+
for (const command of effects.sends) engine.saveEdge({
|
|
50
|
+
from: {
|
|
51
|
+
type: "aggregate",
|
|
52
|
+
name: handlerName
|
|
53
|
+
},
|
|
54
|
+
to: {
|
|
55
|
+
type: "command",
|
|
56
|
+
name: command
|
|
57
|
+
},
|
|
58
|
+
source: {
|
|
59
|
+
file,
|
|
60
|
+
start: method.start
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
for (const event of effects.emits) engine.saveEdge({
|
|
64
|
+
from: {
|
|
65
|
+
type: "aggregate",
|
|
66
|
+
name: handlerName
|
|
67
|
+
},
|
|
68
|
+
to: {
|
|
69
|
+
type: "event",
|
|
70
|
+
name: event
|
|
71
|
+
},
|
|
72
|
+
source: {
|
|
73
|
+
file,
|
|
74
|
+
start: method.start
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
}
|
|
79
80
|
//#endregion
|
|
80
|
-
export {};
|
|
81
|
+
export { applyEsAggregateDefaults };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event.d.ts","sourceRoot":"","sources":["../../../src/engine/defaults/event.ts"],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"event.d.ts","sourceRoot":"","sources":["../../../src/engine/defaults/event.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAKxC,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,QAkChD"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { engine } from "../engine.mjs";
|
|
2
1
|
import { readStringLiteral } from "./_utils.mjs";
|
|
3
2
|
//#region src/engine/defaults/event.ts
|
|
4
3
|
const EVENT_BASES = new Set([
|
|
@@ -6,42 +5,44 @@ const EVENT_BASES = new Set([
|
|
|
6
5
|
"OldEvent",
|
|
7
6
|
"Event"
|
|
8
7
|
]);
|
|
9
|
-
engine
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
if (
|
|
8
|
+
function applyEventDefaults(engine) {
|
|
9
|
+
engine.on((node, parent, ctx, file) => {
|
|
10
|
+
if (node.type !== "ClassDeclaration") return;
|
|
11
|
+
if (!node.id) return;
|
|
12
|
+
const sup = node.superClass;
|
|
13
|
+
if (!sup) return;
|
|
14
|
+
if (sup.type === "Identifier") {
|
|
15
|
+
if (!EVENT_BASES.has(sup.name)) return;
|
|
16
|
+
engine.saveNode({
|
|
17
|
+
type: "event",
|
|
18
|
+
name: node.id.name,
|
|
19
|
+
meta: {
|
|
20
|
+
alias: node.id.name,
|
|
21
|
+
base: sup.name
|
|
22
|
+
},
|
|
23
|
+
source: {
|
|
24
|
+
file,
|
|
25
|
+
start: node.start
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
if (sup.type !== "CallExpression") return;
|
|
31
|
+
if (sup.callee?.type !== "Identifier") return;
|
|
32
|
+
if (!EVENT_BASES.has(sup.callee.name)) return;
|
|
16
33
|
engine.saveNode({
|
|
17
34
|
type: "event",
|
|
18
35
|
name: node.id.name,
|
|
19
36
|
meta: {
|
|
20
|
-
alias: node.id.name,
|
|
21
|
-
base: sup.name
|
|
37
|
+
alias: readStringLiteral(sup.arguments?.[0]) ?? node.id.name,
|
|
38
|
+
base: sup.callee.name
|
|
22
39
|
},
|
|
23
40
|
source: {
|
|
24
41
|
file,
|
|
25
42
|
start: node.start
|
|
26
43
|
}
|
|
27
44
|
});
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
|
-
if (sup.type !== "CallExpression") return;
|
|
31
|
-
if (sup.callee?.type !== "Identifier") return;
|
|
32
|
-
if (!EVENT_BASES.has(sup.callee.name)) return;
|
|
33
|
-
engine.saveNode({
|
|
34
|
-
type: "event",
|
|
35
|
-
name: node.id.name,
|
|
36
|
-
meta: {
|
|
37
|
-
alias: readStringLiteral(sup.arguments?.[0]) ?? node.id.name,
|
|
38
|
-
base: sup.callee.name
|
|
39
|
-
},
|
|
40
|
-
source: {
|
|
41
|
-
file,
|
|
42
|
-
start: node.start
|
|
43
|
-
}
|
|
44
45
|
});
|
|
45
|
-
}
|
|
46
|
+
}
|
|
46
47
|
//#endregion
|
|
47
|
-
export {};
|
|
48
|
+
export { applyEventDefaults };
|
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
import "
|
|
2
|
-
|
|
3
|
-
import "./saga";
|
|
4
|
-
import "./es-aggregate";
|
|
5
|
-
import "./projection";
|
|
6
|
-
import "./command-handler";
|
|
7
|
-
import "./scanner";
|
|
1
|
+
import type { Engine } from "../engine";
|
|
2
|
+
export declare function applyDefaults(engine: Engine): void;
|
|
8
3
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/engine/defaults/index.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/engine/defaults/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAUxC,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,QAS3C"}
|
|
@@ -1,8 +1,21 @@
|
|
|
1
|
-
import "./
|
|
2
|
-
import "./command.mjs";
|
|
3
|
-
import "./
|
|
4
|
-
import "./
|
|
5
|
-
import "./
|
|
6
|
-
import "./
|
|
7
|
-
import "./
|
|
8
|
-
|
|
1
|
+
import { applyCommandDefaults } from "./command.mjs";
|
|
2
|
+
import { applyCommandHandlerDefaults } from "./command-handler.mjs";
|
|
3
|
+
import { applyEsAggregateDefaults } from "./es-aggregate.mjs";
|
|
4
|
+
import { applyEventDefaults } from "./event.mjs";
|
|
5
|
+
import { applyMethodIndexDefaults } from "./method-index.mjs";
|
|
6
|
+
import { applyProjectionDefaults } from "./projection.mjs";
|
|
7
|
+
import { applySagaDefaults } from "./saga.mjs";
|
|
8
|
+
import { applyScannerDefaults } from "./scanner.mjs";
|
|
9
|
+
//#region src/engine/defaults/index.ts
|
|
10
|
+
function applyDefaults(engine) {
|
|
11
|
+
applyEventDefaults(engine);
|
|
12
|
+
applyCommandDefaults(engine);
|
|
13
|
+
applySagaDefaults(engine);
|
|
14
|
+
applyEsAggregateDefaults(engine);
|
|
15
|
+
applyProjectionDefaults(engine);
|
|
16
|
+
applyCommandHandlerDefaults(engine);
|
|
17
|
+
applyMethodIndexDefaults(engine);
|
|
18
|
+
applyScannerDefaults(engine);
|
|
19
|
+
}
|
|
20
|
+
//#endregion
|
|
21
|
+
export { applyDefaults };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Engine } from "../engine";
|
|
2
|
+
/**
|
|
3
|
+
* Indexes aggregate/entity event-application methods (`this.apply(Event.new(...))`)
|
|
4
|
+
* by method name. The engine later joins these against recorded
|
|
5
|
+
* `receiver.method(...)` calls so a caller (e.g. a command handler) is linked to
|
|
6
|
+
* the events it ultimately produces, even when the emit happens in another
|
|
7
|
+
* class. Scoped to `this.apply(...)` so command-dispatch methods (every
|
|
8
|
+
* handler's `execute`, command buses, …) don't become catch-all matches.
|
|
9
|
+
*/
|
|
10
|
+
export declare function applyMethodIndexDefaults(engine: Engine): void;
|
|
11
|
+
//# sourceMappingURL=method-index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"method-index.d.ts","sourceRoot":"","sources":["../../../src/engine/defaults/method-index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAGxC;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,QAatD"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { appliedEvents, classMethods, methodName } from "./_utils.mjs";
|
|
2
|
+
//#region src/engine/defaults/method-index.ts
|
|
3
|
+
/**
|
|
4
|
+
* Indexes aggregate/entity event-application methods (`this.apply(Event.new(...))`)
|
|
5
|
+
* by method name. The engine later joins these against recorded
|
|
6
|
+
* `receiver.method(...)` calls so a caller (e.g. a command handler) is linked to
|
|
7
|
+
* the events it ultimately produces, even when the emit happens in another
|
|
8
|
+
* class. Scoped to `this.apply(...)` so command-dispatch methods (every
|
|
9
|
+
* handler's `execute`, command buses, …) don't become catch-all matches.
|
|
10
|
+
*/
|
|
11
|
+
function applyMethodIndexDefaults(engine) {
|
|
12
|
+
engine.on((node) => {
|
|
13
|
+
if (node.type !== "ClassDeclaration" || !node.id) return;
|
|
14
|
+
const owner = node.id.name;
|
|
15
|
+
for (const method of classMethods(node)) {
|
|
16
|
+
const name = methodName(method);
|
|
17
|
+
if (!name) continue;
|
|
18
|
+
const events = appliedEvents(method);
|
|
19
|
+
if (events.length) engine.indexBehaviour(name, owner, events);
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
//#endregion
|
|
24
|
+
export { applyMethodIndexDefaults };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"projection.d.ts","sourceRoot":"","sources":["../../../src/engine/defaults/projection.ts"],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"projection.d.ts","sourceRoot":"","sources":["../../../src/engine/defaults/projection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAYxC,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,QA8CrD"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { engine } from "../engine.mjs";
|
|
2
1
|
import { classMethods, memberPath, methodName, reactorEvents, readStringLiteral } from "./_utils.mjs";
|
|
3
2
|
//#region src/engine/defaults/projection.ts
|
|
4
3
|
const REACTOR_DECORATORS = new Set([
|
|
@@ -7,51 +6,53 @@ const REACTOR_DECORATORS = new Set([
|
|
|
7
6
|
"On"
|
|
8
7
|
]);
|
|
9
8
|
const PROJECTION_CALLEES = new Set(["Projection", "Projection.from"]);
|
|
10
|
-
engine
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
if (sup.
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
name: handlerName,
|
|
34
|
-
meta: { alias: `${projectionAlias}.${name}` },
|
|
35
|
-
source: {
|
|
36
|
-
file,
|
|
37
|
-
start: method.start
|
|
38
|
-
}
|
|
39
|
-
});
|
|
40
|
-
for (const event of events) engine.saveEdge({
|
|
41
|
-
from: {
|
|
42
|
-
type: "event",
|
|
43
|
-
name: event
|
|
44
|
-
},
|
|
45
|
-
to: {
|
|
9
|
+
function applyProjectionDefaults(engine) {
|
|
10
|
+
engine.on((node, parent, ctx, file) => {
|
|
11
|
+
if (node.type !== "ClassDeclaration") return;
|
|
12
|
+
if (!node.id) return;
|
|
13
|
+
const sup = node.superClass;
|
|
14
|
+
if (!sup) return;
|
|
15
|
+
let alias = null;
|
|
16
|
+
if (sup.type === "Identifier") {
|
|
17
|
+
if (sup.name !== "Projection") return;
|
|
18
|
+
} else if (sup.type === "CallExpression") {
|
|
19
|
+
const callee = memberPath(sup.callee);
|
|
20
|
+
if (!callee || !PROJECTION_CALLEES.has(callee)) return;
|
|
21
|
+
alias = readStringLiteral(sup.arguments?.[0]);
|
|
22
|
+
} else return;
|
|
23
|
+
const className = node.id.name;
|
|
24
|
+
const projectionAlias = alias ?? className;
|
|
25
|
+
for (const method of classMethods(node)) {
|
|
26
|
+
const name = methodName(method);
|
|
27
|
+
if (!name) continue;
|
|
28
|
+
const events = reactorEvents(method.decorators, REACTOR_DECORATORS);
|
|
29
|
+
if (!events.length) continue;
|
|
30
|
+
const handlerName = `${className}.${name}`;
|
|
31
|
+
engine.saveNode({
|
|
46
32
|
type: "projection",
|
|
47
|
-
name: handlerName
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
33
|
+
name: handlerName,
|
|
34
|
+
meta: { alias: `${projectionAlias}.${name}` },
|
|
35
|
+
source: {
|
|
36
|
+
file,
|
|
37
|
+
start: method.start
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
for (const event of events) engine.saveEdge({
|
|
41
|
+
from: {
|
|
42
|
+
type: "event",
|
|
43
|
+
name: event
|
|
44
|
+
},
|
|
45
|
+
to: {
|
|
46
|
+
type: "projection",
|
|
47
|
+
name: handlerName
|
|
48
|
+
},
|
|
49
|
+
source: {
|
|
50
|
+
file,
|
|
51
|
+
start: method.start
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
}
|
|
56
57
|
//#endregion
|
|
57
|
-
export {};
|
|
58
|
+
export { applyProjectionDefaults };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"saga.d.ts","sourceRoot":"","sources":["../../../src/engine/defaults/saga.ts"],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"saga.d.ts","sourceRoot":"","sources":["../../../src/engine/defaults/saga.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAUxC,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,QAiD/C"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { engine } from "../engine.mjs";
|
|
2
1
|
import { classMethods, methodEffects, methodName, reactorEvents } from "./_utils.mjs";
|
|
3
2
|
//#region src/engine/defaults/saga.ts
|
|
4
3
|
const REACTOR_DECORATORS = new Set([
|
|
@@ -6,70 +5,72 @@ const REACTOR_DECORATORS = new Set([
|
|
|
6
5
|
"on",
|
|
7
6
|
"On"
|
|
8
7
|
]);
|
|
9
|
-
engine
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
name: handlerName,
|
|
24
|
-
source: {
|
|
25
|
-
file,
|
|
26
|
-
start: method.start
|
|
27
|
-
}
|
|
28
|
-
});
|
|
29
|
-
for (const event of events) engine.saveEdge({
|
|
30
|
-
from: {
|
|
31
|
-
type: "event",
|
|
32
|
-
name: event
|
|
33
|
-
},
|
|
34
|
-
to: {
|
|
8
|
+
function applySagaDefaults(engine) {
|
|
9
|
+
engine.on((node, parent, ctx, file) => {
|
|
10
|
+
if (node.type !== "ClassDeclaration") return;
|
|
11
|
+
if (!node.id) return;
|
|
12
|
+
const sup = node.superClass;
|
|
13
|
+
if (sup?.type !== "Identifier" || sup.name !== "Saga") return;
|
|
14
|
+
const className = node.id.name;
|
|
15
|
+
for (const method of classMethods(node)) {
|
|
16
|
+
const name = methodName(method);
|
|
17
|
+
if (!name) continue;
|
|
18
|
+
const events = reactorEvents(method.decorators, REACTOR_DECORATORS);
|
|
19
|
+
if (!events.length) continue;
|
|
20
|
+
const handlerName = `${className}.${name}`;
|
|
21
|
+
engine.saveNode({
|
|
35
22
|
type: "saga",
|
|
36
|
-
name: handlerName
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
23
|
+
name: handlerName,
|
|
24
|
+
source: {
|
|
25
|
+
file,
|
|
26
|
+
start: method.start
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
for (const event of events) engine.saveEdge({
|
|
30
|
+
from: {
|
|
31
|
+
type: "event",
|
|
32
|
+
name: event
|
|
33
|
+
},
|
|
34
|
+
to: {
|
|
35
|
+
type: "saga",
|
|
36
|
+
name: handlerName
|
|
37
|
+
},
|
|
38
|
+
source: {
|
|
39
|
+
file,
|
|
40
|
+
start: method.start
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
const effects = methodEffects(method);
|
|
44
|
+
for (const command of effects.sends) engine.saveEdge({
|
|
45
|
+
from: {
|
|
46
|
+
type: "saga",
|
|
47
|
+
name: handlerName
|
|
48
|
+
},
|
|
49
|
+
to: {
|
|
50
|
+
type: "command",
|
|
51
|
+
name: command
|
|
52
|
+
},
|
|
53
|
+
source: {
|
|
54
|
+
file,
|
|
55
|
+
start: method.start
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
for (const event of effects.emits) engine.saveEdge({
|
|
59
|
+
from: {
|
|
60
|
+
type: "saga",
|
|
61
|
+
name: handlerName
|
|
62
|
+
},
|
|
63
|
+
to: {
|
|
64
|
+
type: "event",
|
|
65
|
+
name: event
|
|
66
|
+
},
|
|
67
|
+
source: {
|
|
68
|
+
file,
|
|
69
|
+
start: method.start
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
}
|
|
74
75
|
//#endregion
|
|
75
|
-
export {};
|
|
76
|
+
export { applySagaDefaults };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../../../src/engine/defaults/scanner.ts"],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../../../src/engine/defaults/scanner.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAExC,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,QAyBlD"}
|
|
@@ -1,27 +1,28 @@
|
|
|
1
|
-
import { engine } from "../engine.mjs";
|
|
2
1
|
import fs from "node:fs";
|
|
3
2
|
import { join } from "node:path";
|
|
4
3
|
//#region src/engine/defaults/scanner.ts
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
});
|
|
4
|
+
function applyScannerDefaults(engine) {
|
|
5
|
+
engine.scan(function* (root = process.cwd()) {
|
|
6
|
+
yield* fs.globSync("**/*.ts", {
|
|
7
|
+
cwd: root,
|
|
8
|
+
exclude: [
|
|
9
|
+
"**/node_modules/**",
|
|
10
|
+
"**/dist/**",
|
|
11
|
+
"**/build/**",
|
|
12
|
+
"**/.git/**",
|
|
13
|
+
"**/.turbo/**",
|
|
14
|
+
"**/coverage/**",
|
|
15
|
+
"**/.next/**",
|
|
16
|
+
"**/.cache/**",
|
|
17
|
+
"**/.vite/**",
|
|
18
|
+
"**/*.d.ts",
|
|
19
|
+
"**/*.spec.ts",
|
|
20
|
+
"**/*.test.ts",
|
|
21
|
+
"**/*.typecheck.spec.ts"
|
|
22
|
+
],
|
|
23
|
+
withFileTypes: false
|
|
24
|
+
}).map((p) => join(root, p));
|
|
25
|
+
});
|
|
26
|
+
}
|
|
26
27
|
//#endregion
|
|
27
|
-
export {};
|
|
28
|
+
export { applyScannerDefaults };
|
package/dist/engine/engine.d.ts
CHANGED
|
@@ -13,6 +13,32 @@ export declare class Engine {
|
|
|
13
13
|
private nodes;
|
|
14
14
|
saveNode(node: Node): void;
|
|
15
15
|
getNodes(): readonly Node[];
|
|
16
|
+
private behaviours;
|
|
17
|
+
indexBehaviour(method: string, owner: string, events: readonly string[]): void;
|
|
18
|
+
private invocations;
|
|
19
|
+
saveInvocation(invocation: {
|
|
20
|
+
from: {
|
|
21
|
+
type: "command";
|
|
22
|
+
name: string;
|
|
23
|
+
};
|
|
24
|
+
method: string;
|
|
25
|
+
source: {
|
|
26
|
+
file: string;
|
|
27
|
+
start: number;
|
|
28
|
+
};
|
|
29
|
+
}): void;
|
|
30
|
+
/**
|
|
31
|
+
* Expands recorded `receiver.method(...)` calls into edges from the caller to
|
|
32
|
+
* whatever the callee emits/sends. This links a command handler that
|
|
33
|
+
* delegates to an aggregate method (e.g. `message.destroy()` →
|
|
34
|
+
* `this.apply(SomeEvent.new(...))`) to the events it ultimately produces.
|
|
35
|
+
* Matching is by method name only — no receiver type resolution. To stay
|
|
36
|
+
* precise we attribute a method's events only when that name is declared in a
|
|
37
|
+
* single class; a name shared across classes (e.g. `enable`/`disable` on many
|
|
38
|
+
* feature aggregates) is ambiguous and skipped. Edges to unknown targets are
|
|
39
|
+
* dropped later by resolveEdges().
|
|
40
|
+
*/
|
|
41
|
+
private resolveInvocations;
|
|
16
42
|
/**
|
|
17
43
|
* Edge targets discovered from `new X()` calls are speculative: when a walker
|
|
18
44
|
* records them it only knows the constructor name, not whether `X` is a
|
|
@@ -29,6 +55,7 @@ export declare class Engine {
|
|
|
29
55
|
reset(): void;
|
|
30
56
|
run(root?: string): void;
|
|
31
57
|
}
|
|
58
|
+
export declare function createDefaultEngine(): Engine;
|
|
32
59
|
export declare const engine: Engine;
|
|
33
60
|
export {};
|
|
34
61
|
//# sourceMappingURL=engine.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/engine/engine.ts"],"names":[],"mappings":"AACA,OAAO,EAAgB,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/engine/engine.ts"],"names":[],"mappings":"AACA,OAAO,EAAgB,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAGpC,KAAK,SAAS,GAAG,CACf,GAAG,IAAI,EAAE,CAAC,GAAG,UAAU,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,KAChD,UAAU,CAAC,WAAW,CAAC,CAAC;AAE7B,qBAAa,MAAM;IACjB,OAAO,CAAC,UAAU,CAAmB;IAErC,EAAE,CAAC,MAAM,EAAE,SAAS;IAKpB,OAAO,CAAC,WAAW,CAIjB;IACF,IAAI,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,QAAQ,CAAC,MAAM,CAAC;IAKpD,OAAO,CAAC,KAAK,CAAc;IAC3B,QAAQ,CAAC,IAAI,EAAE,IAAI;IAGnB,QAAQ,IAAI,SAAS,IAAI,EAAE;IAI3B,OAAO,CAAC,KAAK,CAAc;IAC3B,QAAQ,CAAC,IAAI,EAAE,IAAI;IAGnB,QAAQ,IAAI,SAAS,IAAI,EAAE;IAS3B,OAAO,CAAC,UAAU,CAA+C;IACjE,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,MAAM,EAAE;IAiBvE,OAAO,CAAC,WAAW,CAIV;IACT,cAAc,CAAC,UAAU,EAAE;QACzB,IAAI,EAAE;YAAE,IAAI,EAAE,SAAS,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC;QACxC,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC;KACzC;IAID;;;;;;;;;;OAUG;IACH,OAAO,CAAC,kBAAkB;IAW1B;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,YAAY;IAiCpB,KAAK;IAOL,GAAG,CAAC,IAAI,GAAE,MAAsB;CAsBjC;AAED,wBAAgB,mBAAmB,IAAI,MAAM,CAI5C;AAED,eAAO,MAAM,MAAM,QAAwB,CAAC"}
|
package/dist/engine/engine.mjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { applyDefaults } from "./defaults/index.mjs";
|
|
1
2
|
import fs from "node:fs";
|
|
2
3
|
import { parseAndWalk } from "oxc-walker";
|
|
3
4
|
//#region src/engine/engine.ts
|
|
@@ -28,6 +29,50 @@ var Engine = class {
|
|
|
28
29
|
getNodes() {
|
|
29
30
|
return this.nodes;
|
|
30
31
|
}
|
|
32
|
+
behaviours = /* @__PURE__ */ new Map();
|
|
33
|
+
indexBehaviour(method, owner, events) {
|
|
34
|
+
let byOwner = this.behaviours.get(method);
|
|
35
|
+
if (!byOwner) {
|
|
36
|
+
byOwner = /* @__PURE__ */ new Map();
|
|
37
|
+
this.behaviours.set(method, byOwner);
|
|
38
|
+
}
|
|
39
|
+
let entry = byOwner.get(owner);
|
|
40
|
+
if (!entry) {
|
|
41
|
+
entry = /* @__PURE__ */ new Set();
|
|
42
|
+
byOwner.set(owner, entry);
|
|
43
|
+
}
|
|
44
|
+
for (const e of events) entry.add(e);
|
|
45
|
+
}
|
|
46
|
+
invocations = [];
|
|
47
|
+
saveInvocation(invocation) {
|
|
48
|
+
this.invocations.push(invocation);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Expands recorded `receiver.method(...)` calls into edges from the caller to
|
|
52
|
+
* whatever the callee emits/sends. This links a command handler that
|
|
53
|
+
* delegates to an aggregate method (e.g. `message.destroy()` →
|
|
54
|
+
* `this.apply(SomeEvent.new(...))`) to the events it ultimately produces.
|
|
55
|
+
* Matching is by method name only — no receiver type resolution. To stay
|
|
56
|
+
* precise we attribute a method's events only when that name is declared in a
|
|
57
|
+
* single class; a name shared across classes (e.g. `enable`/`disable` on many
|
|
58
|
+
* feature aggregates) is ambiguous and skipped. Edges to unknown targets are
|
|
59
|
+
* dropped later by resolveEdges().
|
|
60
|
+
*/
|
|
61
|
+
resolveInvocations() {
|
|
62
|
+
for (const { from, method, source } of this.invocations) {
|
|
63
|
+
const byOwner = this.behaviours.get(method);
|
|
64
|
+
if (!byOwner || byOwner.size !== 1) continue;
|
|
65
|
+
const [events] = byOwner.values();
|
|
66
|
+
for (const name of events) this.edges.push({
|
|
67
|
+
from,
|
|
68
|
+
to: {
|
|
69
|
+
type: "event",
|
|
70
|
+
name
|
|
71
|
+
},
|
|
72
|
+
source
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}
|
|
31
76
|
/**
|
|
32
77
|
* Edge targets discovered from `new X()` calls are speculative: when a walker
|
|
33
78
|
* records them it only knows the constructor name, not whether `X` is a
|
|
@@ -64,6 +109,8 @@ var Engine = class {
|
|
|
64
109
|
reset() {
|
|
65
110
|
this.edges = [];
|
|
66
111
|
this.nodes = [];
|
|
112
|
+
this.invocations = [];
|
|
113
|
+
this.behaviours = /* @__PURE__ */ new Map();
|
|
67
114
|
}
|
|
68
115
|
run(root = process.cwd()) {
|
|
69
116
|
for (const file of this.fileScanner(root)) {
|
|
@@ -77,10 +124,15 @@ var Engine = class {
|
|
|
77
124
|
}
|
|
78
125
|
} });
|
|
79
126
|
}
|
|
127
|
+
this.resolveInvocations();
|
|
80
128
|
this.resolveEdges();
|
|
81
129
|
}
|
|
82
130
|
};
|
|
83
|
-
|
|
84
|
-
|
|
131
|
+
function createDefaultEngine() {
|
|
132
|
+
const engine = new Engine();
|
|
133
|
+
applyDefaults(engine);
|
|
134
|
+
return engine;
|
|
135
|
+
}
|
|
136
|
+
const engine = createDefaultEngine();
|
|
85
137
|
//#endregion
|
|
86
|
-
export { Engine, engine };
|
|
138
|
+
export { Engine, createDefaultEngine, engine };
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
import { Engine, engine } from "./engine/engine.mjs";
|
|
2
|
-
|
|
1
|
+
import { Engine, createDefaultEngine, engine } from "./engine/engine.mjs";
|
|
2
|
+
import { defineConfig, loadEngine } from "./engine/config.mjs";
|
|
3
|
+
export { Engine, createDefaultEngine, defineConfig, engine, loadEngine };
|
package/dist/server/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
export { engine, Engine } from "../engine/engine";
|
|
1
|
+
export { engine, Engine, createDefaultEngine } from "../engine/engine";
|
|
2
|
+
export { defineConfig, loadEngine, type EventTreeConfig } from "../engine/config";
|
|
2
3
|
export type { Node } from "../node";
|
|
3
4
|
export type { Edge } from "../edge";
|
|
4
5
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAClF,YAAY,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AACpC,YAAY,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ddd-ts/event-tree",
|
|
3
|
-
"version": "0.0.0-eventviz.
|
|
3
|
+
"version": "0.0.0-eventviz.16",
|
|
4
4
|
"types": "dist/server/index.d.ts",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -10,11 +10,12 @@
|
|
|
10
10
|
"dist"
|
|
11
11
|
],
|
|
12
12
|
"dependencies": {
|
|
13
|
+
"c12": "^3.3.0",
|
|
13
14
|
"oxc-parser": "^0.128.0",
|
|
14
15
|
"oxc-walker": "^1.0.0"
|
|
15
16
|
},
|
|
16
17
|
"devDependencies": {
|
|
17
|
-
"@ddd-ts/tools": "0.0.0-eventviz.
|
|
18
|
+
"@ddd-ts/tools": "0.0.0-eventviz.16",
|
|
18
19
|
"@types/node": "^22.14.1"
|
|
19
20
|
},
|
|
20
21
|
"exports": {
|