@logicflow/engine 0.0.2 → 0.0.4
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/CHANGELOG.md +28 -0
- package/cjs/FlowModel.js +24 -38
- package/cjs/Scheduler.js +53 -54
- package/cjs/constant/constant.js +8 -8
- package/cjs/expression/browserVm.js +34 -22
- package/cjs/expression/nodeVm.js +1 -1
- package/cjs/index.js +47 -9
- package/cjs/nodes/BaseNode.js +10 -10
- package/cjs/recorder/index.js +52 -22
- package/cjs/util/ID.js +7 -3
- package/es/FlowModel.d.ts +11 -11
- package/es/FlowModel.js +24 -38
- package/es/Scheduler.d.ts +9 -9
- package/es/Scheduler.js +54 -55
- package/es/constant/constant.d.ts +1 -1
- package/es/constant/constant.js +7 -7
- package/es/expression/browserVm.d.ts +3 -1
- package/es/expression/browserVm.js +32 -22
- package/es/expression/nodeVm.js +1 -1
- package/es/index.d.ts +23 -11
- package/es/index.js +47 -9
- package/es/nodes/BaseNode.d.ts +19 -8
- package/es/nodes/BaseNode.js +11 -11
- package/es/recorder/index.d.ts +9 -4
- package/es/recorder/index.js +52 -22
- package/es/util/ID.d.ts +2 -1
- package/es/util/ID.js +6 -2
- package/lib/main.js +1 -1
- package/package.json +4 -1
package/es/Scheduler.js
CHANGED
|
@@ -60,7 +60,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
60
60
|
};
|
|
61
61
|
import EventEmitter from './EventEmitter';
|
|
62
62
|
import { EVENT_INSTANCE_COMPLETE, EVENT_INSTANCE_INTERRUPTED, FlowStatus, } from './constant/constant';
|
|
63
|
-
import {
|
|
63
|
+
import { createActionId } from './util/ID';
|
|
64
64
|
/**
|
|
65
65
|
* 调度器
|
|
66
66
|
* 通过一个队列维护需要执行的节点,一个集合维护正在执行的节点
|
|
@@ -70,7 +70,7 @@ var Scheduler = /** @class */ (function (_super) {
|
|
|
70
70
|
function Scheduler(config) {
|
|
71
71
|
var _this = _super.call(this) || this;
|
|
72
72
|
_this.nodeQueueMap = new Map();
|
|
73
|
-
_this.
|
|
73
|
+
_this.actionRunningMap = new Map();
|
|
74
74
|
_this.flowModel = config.flowModel;
|
|
75
75
|
_this.recorder = config.recorder;
|
|
76
76
|
return _this;
|
|
@@ -80,13 +80,13 @@ var Scheduler = /** @class */ (function (_super) {
|
|
|
80
80
|
* 1. 由流程模型将所有的开始节点添加到队列中。
|
|
81
81
|
* 2. 当一个节点执行完成后,将后续的节点添加到队列中。
|
|
82
82
|
*/
|
|
83
|
-
Scheduler.prototype.
|
|
83
|
+
Scheduler.prototype.addAction = function (nodeParam) {
|
|
84
84
|
var executionId = nodeParam.executionId;
|
|
85
85
|
if (!this.nodeQueueMap.has(executionId)) {
|
|
86
86
|
this.nodeQueueMap.set(executionId, []);
|
|
87
87
|
}
|
|
88
|
-
var
|
|
89
|
-
|
|
88
|
+
var currentActionQueue = this.nodeQueueMap.get(executionId);
|
|
89
|
+
currentActionQueue.push(nodeParam);
|
|
90
90
|
};
|
|
91
91
|
/**
|
|
92
92
|
* 调度器执行下一个任务
|
|
@@ -96,22 +96,21 @@ var Scheduler = /** @class */ (function (_super) {
|
|
|
96
96
|
*/
|
|
97
97
|
Scheduler.prototype.run = function (runParams) {
|
|
98
98
|
var nodeQueue = this.nodeQueueMap.get(runParams.executionId);
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
}
|
|
99
|
+
// 将同一个executionId当前待执行的节点一起执行
|
|
100
|
+
// 避免出现某一个节点执行时间过长,导致其他节点等待时间过长。
|
|
101
|
+
while (nodeQueue.length) {
|
|
102
|
+
var currentNode = nodeQueue.pop();
|
|
103
|
+
var actionId = createActionId();
|
|
104
|
+
var actionParam = __assign(__assign({}, currentNode), { actionId: actionId });
|
|
105
|
+
this.pushActionToRunningMap(actionParam);
|
|
106
|
+
this.exec(actionParam);
|
|
108
107
|
}
|
|
109
|
-
|
|
110
|
-
// 当一个流程在nodeQueueMap和
|
|
108
|
+
if (!this.hasRunningAction(runParams.executionId)) {
|
|
109
|
+
// 当一个流程在nodeQueueMap和actionRunningMap中都不存在执行的节点时,说明这个流程已经执行完成。
|
|
111
110
|
this.emit(EVENT_INSTANCE_COMPLETE, {
|
|
112
111
|
executionId: runParams.executionId,
|
|
113
112
|
nodeId: runParams.nodeId,
|
|
114
|
-
|
|
113
|
+
actionId: runParams.actionId,
|
|
115
114
|
status: FlowStatus.COMPLETED,
|
|
116
115
|
});
|
|
117
116
|
}
|
|
@@ -126,12 +125,12 @@ var Scheduler = /** @class */ (function (_super) {
|
|
|
126
125
|
return __generator(this, function (_a) {
|
|
127
126
|
switch (_a.label) {
|
|
128
127
|
case 0:
|
|
129
|
-
this.
|
|
128
|
+
this.pushActionToRunningMap({
|
|
130
129
|
executionId: resumeParam.executionId,
|
|
131
130
|
nodeId: resumeParam.nodeId,
|
|
132
|
-
|
|
131
|
+
actionId: resumeParam.actionId,
|
|
133
132
|
});
|
|
134
|
-
model = this.flowModel.
|
|
133
|
+
model = this.flowModel.createAction(resumeParam.nodeId);
|
|
135
134
|
return [4 /*yield*/, model.resume(__assign(__assign({}, resumeParam), { next: this.next.bind(this) }))];
|
|
136
135
|
case 1:
|
|
137
136
|
_a.sent();
|
|
@@ -140,44 +139,44 @@ var Scheduler = /** @class */ (function (_super) {
|
|
|
140
139
|
});
|
|
141
140
|
});
|
|
142
141
|
};
|
|
143
|
-
Scheduler.prototype.
|
|
144
|
-
var executionId =
|
|
145
|
-
if (!this.
|
|
142
|
+
Scheduler.prototype.pushActionToRunningMap = function (actionParam) {
|
|
143
|
+
var executionId = actionParam.executionId, actionId = actionParam.actionId;
|
|
144
|
+
if (!this.actionRunningMap.has(executionId)) {
|
|
146
145
|
var runningMap = new Map();
|
|
147
|
-
this.
|
|
146
|
+
this.actionRunningMap.set(executionId, runningMap);
|
|
148
147
|
}
|
|
149
|
-
this.
|
|
148
|
+
this.actionRunningMap.get(executionId).set(actionId, actionParam);
|
|
150
149
|
};
|
|
151
|
-
Scheduler.prototype.
|
|
152
|
-
var executionId =
|
|
153
|
-
if (!
|
|
150
|
+
Scheduler.prototype.removeActionFromRunningMap = function (actionParam) {
|
|
151
|
+
var executionId = actionParam.executionId, actionId = actionParam.actionId;
|
|
152
|
+
if (!actionId)
|
|
154
153
|
return;
|
|
155
|
-
var runningMap = this.
|
|
154
|
+
var runningMap = this.actionRunningMap.get(executionId);
|
|
156
155
|
if (!runningMap)
|
|
157
156
|
return;
|
|
158
|
-
runningMap.delete(
|
|
157
|
+
runningMap.delete(actionId);
|
|
159
158
|
};
|
|
160
|
-
Scheduler.prototype.
|
|
161
|
-
var runningMap = this.
|
|
159
|
+
Scheduler.prototype.hasRunningAction = function (executionId) {
|
|
160
|
+
var runningMap = this.actionRunningMap.get(executionId);
|
|
162
161
|
if (!runningMap)
|
|
163
162
|
return false;
|
|
164
163
|
if (runningMap.size === 0) {
|
|
165
|
-
this.
|
|
164
|
+
this.actionRunningMap.delete(executionId);
|
|
166
165
|
return false;
|
|
167
166
|
}
|
|
168
167
|
return true;
|
|
169
168
|
};
|
|
170
|
-
Scheduler.prototype.exec = function (
|
|
169
|
+
Scheduler.prototype.exec = function (actionParam) {
|
|
171
170
|
return __awaiter(this, void 0, void 0, function () {
|
|
172
171
|
var model, execResult;
|
|
173
172
|
return __generator(this, function (_a) {
|
|
174
173
|
switch (_a.label) {
|
|
175
174
|
case 0:
|
|
176
|
-
model = this.flowModel.
|
|
175
|
+
model = this.flowModel.createAction(actionParam.nodeId);
|
|
177
176
|
return [4 /*yield*/, model.execute({
|
|
178
|
-
executionId:
|
|
179
|
-
|
|
180
|
-
nodeId:
|
|
177
|
+
executionId: actionParam.executionId,
|
|
178
|
+
actionId: actionParam.actionId,
|
|
179
|
+
nodeId: actionParam.nodeId,
|
|
181
180
|
next: this.next.bind(this),
|
|
182
181
|
})];
|
|
183
182
|
case 1:
|
|
@@ -185,12 +184,12 @@ var Scheduler = /** @class */ (function (_super) {
|
|
|
185
184
|
if (execResult && execResult.status === FlowStatus.INTERRUPTED) {
|
|
186
185
|
this.interrupted({
|
|
187
186
|
execResult: execResult,
|
|
188
|
-
|
|
187
|
+
actionParam: actionParam,
|
|
189
188
|
});
|
|
190
|
-
this.
|
|
191
|
-
executionId:
|
|
192
|
-
nodeId:
|
|
193
|
-
|
|
189
|
+
this.saveActionResult({
|
|
190
|
+
executionId: actionParam.executionId,
|
|
191
|
+
nodeId: actionParam.nodeId,
|
|
192
|
+
actionId: actionParam.actionId,
|
|
194
193
|
nodeType: execResult.nodeType,
|
|
195
194
|
properties: execResult.properties,
|
|
196
195
|
outgoing: [],
|
|
@@ -199,7 +198,7 @@ var Scheduler = /** @class */ (function (_super) {
|
|
|
199
198
|
detail: execResult.detail,
|
|
200
199
|
},
|
|
201
200
|
});
|
|
202
|
-
this.
|
|
201
|
+
this.removeActionFromRunningMap(actionParam);
|
|
203
202
|
}
|
|
204
203
|
return [2 /*return*/];
|
|
205
204
|
}
|
|
@@ -207,12 +206,12 @@ var Scheduler = /** @class */ (function (_super) {
|
|
|
207
206
|
});
|
|
208
207
|
};
|
|
209
208
|
Scheduler.prototype.interrupted = function (_a) {
|
|
210
|
-
var execResult = _a.execResult,
|
|
209
|
+
var execResult = _a.execResult, actionParam = _a.actionParam;
|
|
211
210
|
this.emit(EVENT_INSTANCE_INTERRUPTED, {
|
|
212
|
-
executionId:
|
|
211
|
+
executionId: actionParam.executionId,
|
|
213
212
|
status: FlowStatus.INTERRUPTED,
|
|
214
|
-
nodeId:
|
|
215
|
-
|
|
213
|
+
nodeId: actionParam.nodeId,
|
|
214
|
+
actionId: actionParam.actionId,
|
|
216
215
|
detail: execResult.detail,
|
|
217
216
|
});
|
|
218
217
|
};
|
|
@@ -220,24 +219,24 @@ var Scheduler = /** @class */ (function (_super) {
|
|
|
220
219
|
var _this = this;
|
|
221
220
|
if (data.outgoing && data.outgoing.length > 0) {
|
|
222
221
|
data.outgoing.forEach(function (item) {
|
|
223
|
-
_this.
|
|
222
|
+
_this.addAction({
|
|
224
223
|
executionId: data.executionId,
|
|
225
224
|
nodeId: item.target,
|
|
226
225
|
});
|
|
227
226
|
});
|
|
228
227
|
}
|
|
229
|
-
this.
|
|
230
|
-
this.
|
|
228
|
+
this.saveActionResult(data);
|
|
229
|
+
this.removeActionFromRunningMap(data);
|
|
231
230
|
this.run({
|
|
232
231
|
executionId: data.executionId,
|
|
233
232
|
nodeId: data.nodeId,
|
|
234
|
-
|
|
233
|
+
actionId: data.actionId,
|
|
235
234
|
});
|
|
236
235
|
};
|
|
237
|
-
Scheduler.prototype.
|
|
238
|
-
this.recorder.
|
|
236
|
+
Scheduler.prototype.saveActionResult = function (data) {
|
|
237
|
+
this.recorder.addActionRecord({
|
|
239
238
|
executionId: data.executionId,
|
|
240
|
-
|
|
239
|
+
actionId: data.actionId,
|
|
241
240
|
nodeId: data.nodeId,
|
|
242
241
|
nodeType: data.nodeType,
|
|
243
242
|
timestamp: Date.now(),
|
package/es/constant/constant.js
CHANGED
|
@@ -11,10 +11,10 @@ export var FlowStatus;
|
|
|
11
11
|
FlowStatus["RUNNING"] = "running";
|
|
12
12
|
FlowStatus["ERROR"] = "error";
|
|
13
13
|
})(FlowStatus || (FlowStatus = {}));
|
|
14
|
-
//
|
|
15
|
-
export var
|
|
16
|
-
(function (
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
})(
|
|
14
|
+
// action status
|
|
15
|
+
export var ActionStatus;
|
|
16
|
+
(function (ActionStatus) {
|
|
17
|
+
ActionStatus["SUCCESS"] = "success";
|
|
18
|
+
ActionStatus["ERROR"] = "error";
|
|
19
|
+
ActionStatus["INTERRUPTED"] = "interrupted";
|
|
20
|
+
})(ActionStatus || (ActionStatus = {}));
|
|
@@ -1,2 +1,4 @@
|
|
|
1
|
+
declare const createContext: (globalData: any) => any;
|
|
2
|
+
declare const runInContext: (code: any, context: any) => any;
|
|
1
3
|
declare const runInBrowserContext: (code: string, globalData?: any) => Promise<any>;
|
|
2
|
-
export { runInBrowserContext, };
|
|
4
|
+
export { runInBrowserContext, createContext, runInContext, };
|
|
@@ -35,32 +35,42 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
35
35
|
}
|
|
36
36
|
};
|
|
37
37
|
import { ErrorCode, WarningCode, getErrorMsg, getWarningMsg, } from '../constant/LogCode';
|
|
38
|
+
var createContext = function (globalData) {
|
|
39
|
+
var iframe = document.createElement('iframe');
|
|
40
|
+
iframe.style.display = 'none';
|
|
41
|
+
if (!document || !document.body) {
|
|
42
|
+
console.error(getErrorMsg(ErrorCode.NO_DOCUMENT_BODY));
|
|
43
|
+
}
|
|
44
|
+
document.body.appendChild(iframe);
|
|
45
|
+
var iframeWindow = iframe.contentWindow;
|
|
46
|
+
iframeWindow.parent = null;
|
|
47
|
+
Object.keys(globalData).forEach(function (key) {
|
|
48
|
+
iframeWindow[key] = globalData[key];
|
|
49
|
+
});
|
|
50
|
+
return iframeWindow;
|
|
51
|
+
};
|
|
52
|
+
var runInContext = function (code, context) {
|
|
53
|
+
try {
|
|
54
|
+
var iframeEval = context.eval;
|
|
55
|
+
iframeEval.call(context, code);
|
|
56
|
+
if (context.frameElement) {
|
|
57
|
+
document.body.removeChild(context.frameElement);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
catch (e) {
|
|
61
|
+
console.warn(getWarningMsg(WarningCode.EXPRESSION_EXEC_ERROR), { code: code, context: context, e: e });
|
|
62
|
+
}
|
|
63
|
+
return context;
|
|
64
|
+
};
|
|
38
65
|
var runInBrowserContext = function (code, globalData) {
|
|
39
66
|
if (globalData === void 0) { globalData = {}; }
|
|
40
67
|
return __awaiter(void 0, void 0, void 0, function () {
|
|
41
|
-
var
|
|
68
|
+
var context;
|
|
42
69
|
return __generator(this, function (_a) {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
console.error(getErrorMsg(ErrorCode.NO_DOCUMENT_BODY));
|
|
47
|
-
}
|
|
48
|
-
document.body.appendChild(iframe);
|
|
49
|
-
iframeWindow = iframe.contentWindow;
|
|
50
|
-
iframeEval = iframeWindow.eval;
|
|
51
|
-
Object.keys(globalData).forEach(function (key) {
|
|
52
|
-
iframeWindow[key] = globalData[key];
|
|
53
|
-
});
|
|
54
|
-
res = null;
|
|
55
|
-
try {
|
|
56
|
-
res = iframeEval.call(iframeWindow, code);
|
|
57
|
-
}
|
|
58
|
-
catch (e) {
|
|
59
|
-
console.warn(getWarningMsg(WarningCode.EXPRESSION_EXEC_ERROR), { code: code, globalData: globalData, e: e });
|
|
60
|
-
}
|
|
61
|
-
document.body.removeChild(iframe);
|
|
62
|
-
return [2 /*return*/, res];
|
|
70
|
+
context = createContext(globalData);
|
|
71
|
+
runInContext(code, context);
|
|
72
|
+
return [2 /*return*/, context];
|
|
63
73
|
});
|
|
64
74
|
});
|
|
65
75
|
};
|
|
66
|
-
export { runInBrowserContext, };
|
|
76
|
+
export { runInBrowserContext, createContext, runInContext, };
|
package/es/expression/nodeVm.js
CHANGED
|
@@ -34,7 +34,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
34
34
|
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
35
35
|
}
|
|
36
36
|
};
|
|
37
|
-
|
|
37
|
+
/* eslint-disable global-require */
|
|
38
38
|
var vm = require('vm');
|
|
39
39
|
var runInNewContext = function (code, globalData) {
|
|
40
40
|
if (globalData === void 0) { globalData = {}; }
|
package/es/index.d.ts
CHANGED
|
@@ -1,18 +1,21 @@
|
|
|
1
|
-
import type { ResumeParams, GraphConfigData } from './types.d';
|
|
2
|
-
import FlowModel, {
|
|
1
|
+
import type { ResumeParams, GraphConfigData, EngineConstructorOptions } from './types.d';
|
|
2
|
+
import FlowModel, { ActionParams } from './FlowModel';
|
|
3
3
|
import StartNode from './nodes/StartNode';
|
|
4
4
|
import TaskNode from './nodes/TaskNode';
|
|
5
5
|
import Recorder from './recorder';
|
|
6
|
+
import { NodeConstructor } from './nodes/BaseNode';
|
|
6
7
|
export default class Engine {
|
|
8
|
+
id: string;
|
|
7
9
|
global: Record<string, any>;
|
|
8
10
|
graphData: GraphConfigData;
|
|
9
|
-
nodeModelMap: Map<string,
|
|
11
|
+
nodeModelMap: Map<string, NodeConstructor>;
|
|
10
12
|
flowModel: FlowModel;
|
|
11
13
|
recorder: Recorder;
|
|
12
|
-
|
|
14
|
+
context: Record<string, any>;
|
|
15
|
+
constructor(options?: EngineConstructorOptions);
|
|
13
16
|
/**
|
|
14
17
|
* 注册节点
|
|
15
|
-
* @param nodeConfig { type: 'custom-node', model:
|
|
18
|
+
* @param nodeConfig { type: 'custom-node', model: NodeClass }
|
|
16
19
|
*/
|
|
17
20
|
register(nodeConfig: any): void;
|
|
18
21
|
/**
|
|
@@ -20,8 +23,8 @@ export default class Engine {
|
|
|
20
23
|
* 注意:由于执行记录不会主动删除,所以需要自行清理。
|
|
21
24
|
* nodejs环境建议自定义为持久化存储。
|
|
22
25
|
* engine.setCustomRecorder({
|
|
23
|
-
* async
|
|
24
|
-
* async getTask(
|
|
26
|
+
* async addActionRecord(task) {}
|
|
27
|
+
* async getTask(actionId) {}
|
|
25
28
|
* async getExecutionTasks(executionId) {}
|
|
26
29
|
* clear() {}
|
|
27
30
|
* });
|
|
@@ -30,18 +33,27 @@ export default class Engine {
|
|
|
30
33
|
/**
|
|
31
34
|
* 加载流程图数据
|
|
32
35
|
*/
|
|
33
|
-
load({ graphData, startNodeType, globalData,
|
|
36
|
+
load({ graphData, startNodeType, globalData, }: {
|
|
34
37
|
graphData: any;
|
|
35
38
|
startNodeType?: string;
|
|
36
39
|
globalData?: {};
|
|
37
|
-
context?: {};
|
|
38
40
|
}): FlowModel;
|
|
39
41
|
/**
|
|
40
42
|
* 执行流程,允许多次调用。
|
|
41
43
|
*/
|
|
42
|
-
execute(execParam?:
|
|
44
|
+
execute(execParam?: ActionParams): Promise<unknown>;
|
|
45
|
+
/**
|
|
46
|
+
* 恢复执行
|
|
47
|
+
* 注意此方法只能恢复节点后面的执行,不能恢复流程其他分支的执行。
|
|
48
|
+
* 同理,中断执行也只能中断节点后面的执行,不会中断其他分支的执行。
|
|
49
|
+
* 在实际项目中,如果存在中断节点,建议流程所有的节点都是排他网关,这样可以保证执行的过程不存在分支。
|
|
50
|
+
*/
|
|
43
51
|
resume(resumeParam: ResumeParams): Promise<unknown>;
|
|
52
|
+
getExecutionList(): Promise<any>;
|
|
44
53
|
getExecutionRecord(executionId: any): Promise<any[]>;
|
|
54
|
+
getGlobalData(): Record<string, any>;
|
|
55
|
+
setGlobalData(data: any): void;
|
|
56
|
+
updateGlobalData(data: any): void;
|
|
45
57
|
}
|
|
46
58
|
export { Engine, TaskNode, StartNode, };
|
|
47
|
-
export type {
|
|
59
|
+
export type { ActionParams, };
|
package/es/index.js
CHANGED
|
@@ -49,11 +49,12 @@ import FlowModel from './FlowModel';
|
|
|
49
49
|
import StartNode from './nodes/StartNode';
|
|
50
50
|
import TaskNode from './nodes/TaskNode';
|
|
51
51
|
import Recorder from './recorder';
|
|
52
|
+
import { createEngineId } from './util/ID';
|
|
52
53
|
var Engine = /** @class */ (function () {
|
|
53
|
-
function Engine() {
|
|
54
|
+
function Engine(options) {
|
|
54
55
|
this.nodeModelMap = new Map();
|
|
56
|
+
this.id = createEngineId();
|
|
55
57
|
this.recorder = new Recorder();
|
|
56
|
-
// register node
|
|
57
58
|
this.register({
|
|
58
59
|
type: StartNode.nodeTypeName,
|
|
59
60
|
model: StartNode,
|
|
@@ -62,10 +63,11 @@ var Engine = /** @class */ (function () {
|
|
|
62
63
|
type: TaskNode.nodeTypeName,
|
|
63
64
|
model: TaskNode,
|
|
64
65
|
});
|
|
66
|
+
this.context = (options === null || options === void 0 ? void 0 : options.context) || {};
|
|
65
67
|
}
|
|
66
68
|
/**
|
|
67
69
|
* 注册节点
|
|
68
|
-
* @param nodeConfig { type: 'custom-node', model:
|
|
70
|
+
* @param nodeConfig { type: 'custom-node', model: NodeClass }
|
|
69
71
|
*/
|
|
70
72
|
Engine.prototype.register = function (nodeConfig) {
|
|
71
73
|
this.nodeModelMap.set(nodeConfig.type, nodeConfig.model);
|
|
@@ -75,8 +77,8 @@ var Engine = /** @class */ (function () {
|
|
|
75
77
|
* 注意:由于执行记录不会主动删除,所以需要自行清理。
|
|
76
78
|
* nodejs环境建议自定义为持久化存储。
|
|
77
79
|
* engine.setCustomRecorder({
|
|
78
|
-
* async
|
|
79
|
-
* async getTask(
|
|
80
|
+
* async addActionRecord(task) {}
|
|
81
|
+
* async getTask(actionId) {}
|
|
80
82
|
* async getExecutionTasks(executionId) {}
|
|
81
83
|
* clear() {}
|
|
82
84
|
* });
|
|
@@ -88,11 +90,11 @@ var Engine = /** @class */ (function () {
|
|
|
88
90
|
* 加载流程图数据
|
|
89
91
|
*/
|
|
90
92
|
Engine.prototype.load = function (_a) {
|
|
91
|
-
var graphData = _a.graphData, _b = _a.startNodeType, startNodeType = _b === void 0 ? 'StartNode' : _b, _c = _a.globalData, globalData = _c === void 0 ? {} : _c
|
|
93
|
+
var graphData = _a.graphData, _b = _a.startNodeType, startNodeType = _b === void 0 ? 'StartNode' : _b, _c = _a.globalData, globalData = _c === void 0 ? {} : _c;
|
|
92
94
|
this.flowModel = new FlowModel({
|
|
93
95
|
nodeModelMap: this.nodeModelMap,
|
|
94
96
|
recorder: this.recorder,
|
|
95
|
-
context: context,
|
|
97
|
+
context: this.context,
|
|
96
98
|
globalData: globalData,
|
|
97
99
|
startNodeType: startNodeType,
|
|
98
100
|
});
|
|
@@ -119,6 +121,12 @@ var Engine = /** @class */ (function () {
|
|
|
119
121
|
});
|
|
120
122
|
});
|
|
121
123
|
};
|
|
124
|
+
/**
|
|
125
|
+
* 恢复执行
|
|
126
|
+
* 注意此方法只能恢复节点后面的执行,不能恢复流程其他分支的执行。
|
|
127
|
+
* 同理,中断执行也只能中断节点后面的执行,不会中断其他分支的执行。
|
|
128
|
+
* 在实际项目中,如果存在中断节点,建议流程所有的节点都是排他网关,这样可以保证执行的过程不存在分支。
|
|
129
|
+
*/
|
|
122
130
|
Engine.prototype.resume = function (resumeParam) {
|
|
123
131
|
return __awaiter(this, void 0, void 0, function () {
|
|
124
132
|
var _this = this;
|
|
@@ -133,23 +141,53 @@ var Engine = /** @class */ (function () {
|
|
|
133
141
|
});
|
|
134
142
|
});
|
|
135
143
|
};
|
|
144
|
+
Engine.prototype.getExecutionList = function () {
|
|
145
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
146
|
+
var executionIds;
|
|
147
|
+
return __generator(this, function (_a) {
|
|
148
|
+
switch (_a.label) {
|
|
149
|
+
case 0: return [4 /*yield*/, this.recorder.getExecutionList()];
|
|
150
|
+
case 1:
|
|
151
|
+
executionIds = _a.sent();
|
|
152
|
+
return [2 /*return*/, executionIds];
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
};
|
|
136
157
|
Engine.prototype.getExecutionRecord = function (executionId) {
|
|
137
158
|
return __awaiter(this, void 0, void 0, function () {
|
|
138
159
|
var tasks, records, i;
|
|
139
160
|
return __generator(this, function (_a) {
|
|
140
161
|
switch (_a.label) {
|
|
141
|
-
case 0: return [4 /*yield*/, this.recorder.
|
|
162
|
+
case 0: return [4 /*yield*/, this.recorder.getExecutionActions(executionId)];
|
|
142
163
|
case 1:
|
|
143
164
|
tasks = _a.sent();
|
|
165
|
+
if (!tasks) {
|
|
166
|
+
return [2 /*return*/, null];
|
|
167
|
+
}
|
|
144
168
|
records = [];
|
|
145
169
|
for (i = 0; i < tasks.length; i++) {
|
|
146
|
-
records.push(this.recorder.
|
|
170
|
+
records.push(this.recorder.getActionRecord(tasks[i]));
|
|
147
171
|
}
|
|
148
172
|
return [2 /*return*/, Promise.all(records)];
|
|
149
173
|
}
|
|
150
174
|
});
|
|
151
175
|
});
|
|
152
176
|
};
|
|
177
|
+
Engine.prototype.getGlobalData = function () {
|
|
178
|
+
var _a;
|
|
179
|
+
return (_a = this.flowModel) === null || _a === void 0 ? void 0 : _a.globalData;
|
|
180
|
+
};
|
|
181
|
+
Engine.prototype.setGlobalData = function (data) {
|
|
182
|
+
if (this.flowModel) {
|
|
183
|
+
this.flowModel.globalData = data;
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
Engine.prototype.updateGlobalData = function (data) {
|
|
187
|
+
if (this.flowModel) {
|
|
188
|
+
Object.assign(this.flowModel.globalData, data);
|
|
189
|
+
}
|
|
190
|
+
};
|
|
153
191
|
return Engine;
|
|
154
192
|
}());
|
|
155
193
|
export default Engine;
|
package/es/nodes/BaseNode.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ export interface BaseNodeInterface {
|
|
|
5
5
|
nodeId: string;
|
|
6
6
|
type: string;
|
|
7
7
|
readonly baseType: string;
|
|
8
|
-
execute(
|
|
8
|
+
execute(actionParam: any): Promise<NodeExecResult>;
|
|
9
9
|
}
|
|
10
10
|
export declare type NodeConstructor = {
|
|
11
11
|
new (config: {
|
|
@@ -13,6 +13,17 @@ export declare type NodeConstructor = {
|
|
|
13
13
|
context: Record<string, any>;
|
|
14
14
|
globalData: Record<string, any>;
|
|
15
15
|
}): BaseNode;
|
|
16
|
+
action(params: {
|
|
17
|
+
executionId: string;
|
|
18
|
+
actionId: string;
|
|
19
|
+
nodeId: string;
|
|
20
|
+
}): Promise<ActionResult>;
|
|
21
|
+
onResume(params: {
|
|
22
|
+
executionId: string;
|
|
23
|
+
actionId: string;
|
|
24
|
+
nodeId: string;
|
|
25
|
+
data?: Record<string, any>;
|
|
26
|
+
}): Promise<void>;
|
|
16
27
|
};
|
|
17
28
|
export declare type IncomingConfig = {
|
|
18
29
|
id: string;
|
|
@@ -31,10 +42,10 @@ export declare type NodeConfig = {
|
|
|
31
42
|
incoming: IncomingConfig[];
|
|
32
43
|
outgoing: OutgoingConfig[];
|
|
33
44
|
};
|
|
34
|
-
export declare type
|
|
45
|
+
export declare type NextActionParam = {
|
|
35
46
|
executionId: string;
|
|
36
47
|
nodeId: string;
|
|
37
|
-
|
|
48
|
+
actionId: string;
|
|
38
49
|
nodeType: string;
|
|
39
50
|
outgoing: OutgoingConfig[];
|
|
40
51
|
properties?: Record<string, any>;
|
|
@@ -71,7 +82,7 @@ export default class BaseNode implements BaseNodeInterface {
|
|
|
71
82
|
globalData: any;
|
|
72
83
|
});
|
|
73
84
|
/**
|
|
74
|
-
* 节点的每一次执行都会生成一个唯一的
|
|
85
|
+
* 节点的每一次执行都会生成一个唯一的actionId
|
|
75
86
|
*/
|
|
76
87
|
execute(params: ExecParams): Promise<NodeExecResult>;
|
|
77
88
|
/**
|
|
@@ -85,24 +96,24 @@ export default class BaseNode implements BaseNodeInterface {
|
|
|
85
96
|
* 节点的执行逻辑
|
|
86
97
|
* @overridable 可以自定义节点重写此方法。
|
|
87
98
|
* @param params.executionId 流程执行记录ID
|
|
88
|
-
* @param params.
|
|
99
|
+
* @param params.actionId 此节点执行记录ID
|
|
89
100
|
* @param params.nodeId 节点ID
|
|
90
101
|
*/
|
|
91
102
|
action(params: {
|
|
92
103
|
executionId: string;
|
|
93
|
-
|
|
104
|
+
actionId: string;
|
|
94
105
|
nodeId: string;
|
|
95
106
|
}): Promise<ActionResult>;
|
|
96
107
|
/**
|
|
97
108
|
* 节点的重新恢复执行逻辑
|
|
98
109
|
* @overridable 可以自定义节点重写此方法。
|
|
99
110
|
* @param params.executionId 流程执行记录ID
|
|
100
|
-
* @param params.
|
|
111
|
+
* @param params.actionId 此节点执行记录ID
|
|
101
112
|
* @param params.nodeId 节点ID
|
|
102
113
|
*/
|
|
103
114
|
onResume(params: {
|
|
104
115
|
executionId: string;
|
|
105
|
-
|
|
116
|
+
actionId: string;
|
|
106
117
|
nodeId: string;
|
|
107
118
|
data?: Record<string, any>;
|
|
108
119
|
}): Promise<void>;
|