@unlaxer/tramli 1.2.1 → 1.3.0
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/flow-instance.d.ts
CHANGED
|
@@ -24,6 +24,14 @@ export declare class FlowInstance<S extends string> {
|
|
|
24
24
|
get exitState(): string | null;
|
|
25
25
|
get isCompleted(): boolean;
|
|
26
26
|
get activeSubFlow(): FlowInstance<any> | null;
|
|
27
|
+
/** State path from root to deepest active sub-flow. */
|
|
28
|
+
statePath(): string[];
|
|
29
|
+
/** State path as slash-separated string. */
|
|
30
|
+
statePathString(): string;
|
|
31
|
+
/** Types required by the next external transition (including in active sub-flows). */
|
|
32
|
+
waitingFor(): string[];
|
|
33
|
+
/** Return a copy with the given version. For FlowStore optimistic locking. */
|
|
34
|
+
withVersion(newVersion: number): FlowInstance<S>;
|
|
27
35
|
/** @internal */ transitionTo(state: S): void;
|
|
28
36
|
/** @internal */ incrementGuardFailure(): void;
|
|
29
37
|
/** @internal */ complete(exitState: string): void;
|
package/dist/flow-instance.js
CHANGED
|
@@ -47,6 +47,30 @@ export class FlowInstance {
|
|
|
47
47
|
get exitState() { return this._exitState; }
|
|
48
48
|
get isCompleted() { return this._exitState !== null; }
|
|
49
49
|
get activeSubFlow() { return this._activeSubFlow; }
|
|
50
|
+
/** State path from root to deepest active sub-flow. */
|
|
51
|
+
statePath() {
|
|
52
|
+
const path = [this._currentState];
|
|
53
|
+
if (this._activeSubFlow)
|
|
54
|
+
path.push(...this._activeSubFlow.statePath());
|
|
55
|
+
return path;
|
|
56
|
+
}
|
|
57
|
+
/** State path as slash-separated string. */
|
|
58
|
+
statePathString() { return this.statePath().join('/'); }
|
|
59
|
+
/** Types required by the next external transition (including in active sub-flows). */
|
|
60
|
+
waitingFor() {
|
|
61
|
+
if (this._activeSubFlow)
|
|
62
|
+
return this._activeSubFlow.waitingFor();
|
|
63
|
+
const ext = this.definition.externalFrom(this._currentState);
|
|
64
|
+
if (!ext?.guard)
|
|
65
|
+
return [];
|
|
66
|
+
return [...ext.guard.requires];
|
|
67
|
+
}
|
|
68
|
+
/** Return a copy with the given version. For FlowStore optimistic locking. */
|
|
69
|
+
withVersion(newVersion) {
|
|
70
|
+
const copy = FlowInstance.restore(this.id, this.sessionId, this.definition, this.context, this._currentState, this.createdAt, this.expiresAt, this._guardFailureCount, newVersion, this._exitState);
|
|
71
|
+
copy.setActiveSubFlow(this._activeSubFlow);
|
|
72
|
+
return copy;
|
|
73
|
+
}
|
|
50
74
|
/** @internal */ transitionTo(state) { this._currentState = state; }
|
|
51
75
|
/** @internal */ incrementGuardFailure() { this._guardFailureCount++; }
|
|
52
76
|
/** @internal */ complete(exitState) { this._exitState = exitState; }
|
|
@@ -14,7 +14,8 @@ export class InMemoryFlowStore {
|
|
|
14
14
|
this.flows.set(flow.id, flow);
|
|
15
15
|
}
|
|
16
16
|
recordTransition(flowId, from, to, trigger, _ctx) {
|
|
17
|
-
|
|
17
|
+
const subFlow = trigger.startsWith('subFlow:') ? trigger.substring(8, trigger.indexOf('/')) : null;
|
|
18
|
+
this._transitionLog.push({ flowId, from, to, trigger, subFlow, timestamp: new Date() });
|
|
18
19
|
}
|
|
19
20
|
get transitionLog() {
|
|
20
21
|
return this._transitionLog;
|
|
@@ -5,6 +5,25 @@ export class MermaidGenerator {
|
|
|
5
5
|
lines.push(` [*] --> ${def.initialState}`);
|
|
6
6
|
const seen = new Set();
|
|
7
7
|
for (const t of def.transitions) {
|
|
8
|
+
if (t.type === 'sub_flow' && t.subFlowDefinition) {
|
|
9
|
+
const subDef = t.subFlowDefinition;
|
|
10
|
+
lines.push(` state ${t.from} {`);
|
|
11
|
+
if (subDef.initialState)
|
|
12
|
+
lines.push(` [*] --> ${subDef.initialState}`);
|
|
13
|
+
for (const st of subDef.transitions) {
|
|
14
|
+
const sLabel = this.transitionLabel(st);
|
|
15
|
+
lines.push(sLabel ? ` ${st.from} --> ${st.to}: ${sLabel}` : ` ${st.from} --> ${st.to}`);
|
|
16
|
+
}
|
|
17
|
+
for (const term of subDef.terminalStates)
|
|
18
|
+
lines.push(` ${term} --> [*]`);
|
|
19
|
+
lines.push(' }');
|
|
20
|
+
if (t.exitMappings) {
|
|
21
|
+
for (const [exitName, target] of t.exitMappings) {
|
|
22
|
+
lines.push(` ${t.from} --> ${target}: ${exitName}`);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
8
27
|
const key = `${t.from}->${t.to}`;
|
|
9
28
|
if (seen.has(key))
|
|
10
29
|
continue;
|