@logicflow/engine 0.0.1 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +35 -0
- package/README.md +3 -15
- package/cjs/FlowModel.js +77 -55
- package/cjs/Scheduler.js +68 -96
- package/cjs/constant/constant.js +8 -8
- package/cjs/expression/browserVm.js +30 -22
- package/cjs/expression/nodeVm.js +1 -1
- package/cjs/index.js +34 -9
- package/cjs/nodes/BaseNode.js +10 -10
- package/cjs/recorder/index.js +33 -17
- package/cjs/util/ID.js +7 -3
- package/es/FlowModel.d.ts +59 -19
- package/es/FlowModel.js +77 -55
- package/es/Scheduler.d.ts +26 -15
- package/es/Scheduler.js +69 -97
- 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 +28 -22
- package/es/expression/nodeVm.js +1 -1
- package/es/index.d.ts +22 -11
- package/es/index.js +34 -9
- package/es/nodes/BaseNode.d.ts +19 -8
- package/es/nodes/BaseNode.js +11 -11
- package/es/recorder/index.d.ts +8 -4
- package/es/recorder/index.js +33 -17
- 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/types/EventEmitter.d.ts +0 -7
- package/types/FlowModel.d.ts +0 -104
- package/types/Scheduler.d.ts +0 -51
- package/types/constant/LogCode.d.ts +0 -12
- package/types/constant/constant.d.ts +0 -14
- package/types/expression/browserVm.d.ts +0 -2
- package/types/expression/index.d.ts +0 -2
- package/types/expression/nodeVm.d.ts +0 -2
- package/types/index.d.ts +0 -47
- package/types/nodes/BaseNode.d.ts +0 -109
- package/types/nodes/StartNode.d.ts +0 -5
- package/types/nodes/TaskNode.d.ts +0 -5
- package/types/recorder/index.d.ts +0 -9
- package/types/util/ID.d.ts +0 -2
- package/types/util/global.d.ts +0 -5
- package/types/util/storage.d.ts +0 -6
package/es/Scheduler.d.ts
CHANGED
|
@@ -1,25 +1,40 @@
|
|
|
1
1
|
import EventEmitter from './EventEmitter';
|
|
2
|
-
import type {
|
|
2
|
+
import type { ActionParam, NodeParam, ResumeParam } from './types.d';
|
|
3
3
|
import type FlowModel from './FlowModel';
|
|
4
4
|
import type Recorder from './recorder';
|
|
5
|
-
declare type
|
|
5
|
+
declare type ActionParamMap = Map<string, ActionParam>;
|
|
6
|
+
declare type ExecutionId = string;
|
|
6
7
|
/**
|
|
7
8
|
* 调度器
|
|
8
9
|
* 通过一个队列维护需要执行的节点,一个集合维护正在执行的节点
|
|
9
10
|
*/
|
|
10
11
|
export default class Scheduler extends EventEmitter {
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
/**
|
|
13
|
+
* 当前需要执行的节点队列
|
|
14
|
+
*/
|
|
15
|
+
nodeQueueMap: Map<ExecutionId, NodeParam[]>;
|
|
16
|
+
/**
|
|
17
|
+
* 当前正在执行的节点集合
|
|
18
|
+
* 在每个节点执行完成后,会从集合中删除。
|
|
19
|
+
* 同时会判断此集合中是否还存在和此节点相同的executionId,如果不存在,说明此流程已经执行完成。
|
|
20
|
+
*/
|
|
21
|
+
actionRunningMap: Map<ExecutionId, ActionParamMap>;
|
|
22
|
+
/**
|
|
23
|
+
* 流程模型,用于创建节点模型。
|
|
24
|
+
*/
|
|
13
25
|
flowModel: FlowModel;
|
|
26
|
+
/**
|
|
27
|
+
* 执行记录存储器
|
|
28
|
+
* 用于存储节点执行的结果。
|
|
29
|
+
*/
|
|
14
30
|
recorder: Recorder;
|
|
15
|
-
currentTask: TaskParam | null;
|
|
16
31
|
constructor(config: any);
|
|
17
32
|
/**
|
|
18
33
|
* 添加一个任务到队列中。
|
|
19
34
|
* 1. 由流程模型将所有的开始节点添加到队列中。
|
|
20
35
|
* 2. 当一个节点执行完成后,将后续的节点添加到队列中。
|
|
21
36
|
*/
|
|
22
|
-
|
|
37
|
+
addAction(nodeParam: NodeParam): void;
|
|
23
38
|
/**
|
|
24
39
|
* 调度器执行下一个任务
|
|
25
40
|
* 1. 提供给流程模型,用户开始执行第一个任务。
|
|
@@ -29,23 +44,19 @@ export default class Scheduler extends EventEmitter {
|
|
|
29
44
|
run(runParams: {
|
|
30
45
|
executionId: string;
|
|
31
46
|
nodeId?: string;
|
|
32
|
-
|
|
47
|
+
actionId?: string;
|
|
33
48
|
}): void;
|
|
34
49
|
/**
|
|
35
50
|
* 恢复某个任务的执行。
|
|
36
51
|
* 可以自定义节点手动实现流程中断,然后通过此方法恢复流程的执行。
|
|
37
52
|
*/
|
|
38
53
|
resume(resumeParam: ResumeParam): Promise<void>;
|
|
39
|
-
|
|
40
|
-
private
|
|
41
|
-
private
|
|
42
|
-
private hasRunningTask;
|
|
54
|
+
private pushActionToRunningMap;
|
|
55
|
+
private removeActionFromRunningMap;
|
|
56
|
+
private hasRunningAction;
|
|
43
57
|
private exec;
|
|
44
58
|
private interrupted;
|
|
45
59
|
private next;
|
|
46
|
-
|
|
47
|
-
* 为了防止多次添加导致
|
|
48
|
-
*/
|
|
49
|
-
private saveTaskResult;
|
|
60
|
+
private saveActionResult;
|
|
50
61
|
}
|
|
51
62
|
export {};
|
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,10 +70,9 @@ 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
|
-
_this.currentTask = null;
|
|
77
76
|
return _this;
|
|
78
77
|
}
|
|
79
78
|
/**
|
|
@@ -81,13 +80,13 @@ var Scheduler = /** @class */ (function (_super) {
|
|
|
81
80
|
* 1. 由流程模型将所有的开始节点添加到队列中。
|
|
82
81
|
* 2. 当一个节点执行完成后,将后续的节点添加到队列中。
|
|
83
82
|
*/
|
|
84
|
-
Scheduler.prototype.
|
|
83
|
+
Scheduler.prototype.addAction = function (nodeParam) {
|
|
85
84
|
var executionId = nodeParam.executionId;
|
|
86
85
|
if (!this.nodeQueueMap.has(executionId)) {
|
|
87
86
|
this.nodeQueueMap.set(executionId, []);
|
|
88
87
|
}
|
|
89
|
-
var
|
|
90
|
-
|
|
88
|
+
var currentActionQueue = this.nodeQueueMap.get(executionId);
|
|
89
|
+
currentActionQueue.push(nodeParam);
|
|
91
90
|
};
|
|
92
91
|
/**
|
|
93
92
|
* 调度器执行下一个任务
|
|
@@ -97,22 +96,21 @@ var Scheduler = /** @class */ (function (_super) {
|
|
|
97
96
|
*/
|
|
98
97
|
Scheduler.prototype.run = function (runParams) {
|
|
99
98
|
var nodeQueue = this.nodeQueueMap.get(runParams.executionId);
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
}
|
|
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);
|
|
109
107
|
}
|
|
110
|
-
|
|
111
|
-
// 当一个流程在nodeQueueMap和
|
|
108
|
+
if (!this.hasRunningAction(runParams.executionId)) {
|
|
109
|
+
// 当一个流程在nodeQueueMap和actionRunningMap中都不存在执行的节点时,说明这个流程已经执行完成。
|
|
112
110
|
this.emit(EVENT_INSTANCE_COMPLETE, {
|
|
113
111
|
executionId: runParams.executionId,
|
|
114
112
|
nodeId: runParams.nodeId,
|
|
115
|
-
|
|
113
|
+
actionId: runParams.actionId,
|
|
116
114
|
status: FlowStatus.COMPLETED,
|
|
117
115
|
});
|
|
118
116
|
}
|
|
@@ -127,12 +125,12 @@ var Scheduler = /** @class */ (function (_super) {
|
|
|
127
125
|
return __generator(this, function (_a) {
|
|
128
126
|
switch (_a.label) {
|
|
129
127
|
case 0:
|
|
130
|
-
this.
|
|
128
|
+
this.pushActionToRunningMap({
|
|
131
129
|
executionId: resumeParam.executionId,
|
|
132
130
|
nodeId: resumeParam.nodeId,
|
|
133
|
-
|
|
131
|
+
actionId: resumeParam.actionId,
|
|
134
132
|
});
|
|
135
|
-
model = this.flowModel.
|
|
133
|
+
model = this.flowModel.createAction(resumeParam.nodeId);
|
|
136
134
|
return [4 /*yield*/, model.resume(__assign(__assign({}, resumeParam), { next: this.next.bind(this) }))];
|
|
137
135
|
case 1:
|
|
138
136
|
_a.sent();
|
|
@@ -141,48 +139,44 @@ var Scheduler = /** @class */ (function (_super) {
|
|
|
141
139
|
});
|
|
142
140
|
});
|
|
143
141
|
};
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
};
|
|
148
|
-
Scheduler.prototype.pushTaskToRunningMap = function (taskParam) {
|
|
149
|
-
var executionId = taskParam.executionId, taskId = taskParam.taskId;
|
|
150
|
-
if (!this.taskRunningMap.has(executionId)) {
|
|
142
|
+
Scheduler.prototype.pushActionToRunningMap = function (actionParam) {
|
|
143
|
+
var executionId = actionParam.executionId, actionId = actionParam.actionId;
|
|
144
|
+
if (!this.actionRunningMap.has(executionId)) {
|
|
151
145
|
var runningMap = new Map();
|
|
152
|
-
this.
|
|
146
|
+
this.actionRunningMap.set(executionId, runningMap);
|
|
153
147
|
}
|
|
154
|
-
this.
|
|
148
|
+
this.actionRunningMap.get(executionId).set(actionId, actionParam);
|
|
155
149
|
};
|
|
156
|
-
Scheduler.prototype.
|
|
157
|
-
var executionId =
|
|
158
|
-
if (!
|
|
150
|
+
Scheduler.prototype.removeActionFromRunningMap = function (actionParam) {
|
|
151
|
+
var executionId = actionParam.executionId, actionId = actionParam.actionId;
|
|
152
|
+
if (!actionId)
|
|
159
153
|
return;
|
|
160
|
-
var runningMap = this.
|
|
154
|
+
var runningMap = this.actionRunningMap.get(executionId);
|
|
161
155
|
if (!runningMap)
|
|
162
156
|
return;
|
|
163
|
-
runningMap.delete(
|
|
157
|
+
runningMap.delete(actionId);
|
|
164
158
|
};
|
|
165
|
-
Scheduler.prototype.
|
|
166
|
-
var runningMap = this.
|
|
159
|
+
Scheduler.prototype.hasRunningAction = function (executionId) {
|
|
160
|
+
var runningMap = this.actionRunningMap.get(executionId);
|
|
167
161
|
if (!runningMap)
|
|
168
162
|
return false;
|
|
169
163
|
if (runningMap.size === 0) {
|
|
170
|
-
this.
|
|
164
|
+
this.actionRunningMap.delete(executionId);
|
|
171
165
|
return false;
|
|
172
166
|
}
|
|
173
167
|
return true;
|
|
174
168
|
};
|
|
175
|
-
Scheduler.prototype.exec = function (
|
|
169
|
+
Scheduler.prototype.exec = function (actionParam) {
|
|
176
170
|
return __awaiter(this, void 0, void 0, function () {
|
|
177
171
|
var model, execResult;
|
|
178
172
|
return __generator(this, function (_a) {
|
|
179
173
|
switch (_a.label) {
|
|
180
174
|
case 0:
|
|
181
|
-
model = this.flowModel.
|
|
175
|
+
model = this.flowModel.createAction(actionParam.nodeId);
|
|
182
176
|
return [4 /*yield*/, model.execute({
|
|
183
|
-
executionId:
|
|
184
|
-
|
|
185
|
-
nodeId:
|
|
177
|
+
executionId: actionParam.executionId,
|
|
178
|
+
actionId: actionParam.actionId,
|
|
179
|
+
nodeId: actionParam.nodeId,
|
|
186
180
|
next: this.next.bind(this),
|
|
187
181
|
})];
|
|
188
182
|
case 1:
|
|
@@ -190,12 +184,12 @@ var Scheduler = /** @class */ (function (_super) {
|
|
|
190
184
|
if (execResult && execResult.status === FlowStatus.INTERRUPTED) {
|
|
191
185
|
this.interrupted({
|
|
192
186
|
execResult: execResult,
|
|
193
|
-
|
|
187
|
+
actionParam: actionParam,
|
|
194
188
|
});
|
|
195
|
-
this.
|
|
196
|
-
executionId:
|
|
197
|
-
nodeId:
|
|
198
|
-
|
|
189
|
+
this.saveActionResult({
|
|
190
|
+
executionId: actionParam.executionId,
|
|
191
|
+
nodeId: actionParam.nodeId,
|
|
192
|
+
actionId: actionParam.actionId,
|
|
199
193
|
nodeType: execResult.nodeType,
|
|
200
194
|
properties: execResult.properties,
|
|
201
195
|
outgoing: [],
|
|
@@ -204,7 +198,7 @@ var Scheduler = /** @class */ (function (_super) {
|
|
|
204
198
|
detail: execResult.detail,
|
|
205
199
|
},
|
|
206
200
|
});
|
|
207
|
-
this.
|
|
201
|
+
this.removeActionFromRunningMap(actionParam);
|
|
208
202
|
}
|
|
209
203
|
return [2 /*return*/];
|
|
210
204
|
}
|
|
@@ -212,63 +206,41 @@ var Scheduler = /** @class */ (function (_super) {
|
|
|
212
206
|
});
|
|
213
207
|
};
|
|
214
208
|
Scheduler.prototype.interrupted = function (_a) {
|
|
215
|
-
var execResult = _a.execResult,
|
|
209
|
+
var execResult = _a.execResult, actionParam = _a.actionParam;
|
|
216
210
|
this.emit(EVENT_INSTANCE_INTERRUPTED, {
|
|
217
|
-
executionId:
|
|
211
|
+
executionId: actionParam.executionId,
|
|
218
212
|
status: FlowStatus.INTERRUPTED,
|
|
219
|
-
nodeId:
|
|
220
|
-
|
|
213
|
+
nodeId: actionParam.nodeId,
|
|
214
|
+
actionId: actionParam.actionId,
|
|
221
215
|
detail: execResult.detail,
|
|
222
216
|
});
|
|
223
217
|
};
|
|
224
218
|
Scheduler.prototype.next = function (data) {
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
_this.addTask({
|
|
233
|
-
executionId: data.executionId,
|
|
234
|
-
nodeId: item.target,
|
|
235
|
-
});
|
|
236
|
-
});
|
|
237
|
-
}
|
|
238
|
-
return [4 /*yield*/, this.saveTaskResult(data)];
|
|
239
|
-
case 1:
|
|
240
|
-
_a.sent();
|
|
241
|
-
this.removeTaskFromRunningMap(data);
|
|
242
|
-
this.run({
|
|
243
|
-
executionId: data.executionId,
|
|
244
|
-
nodeId: data.nodeId,
|
|
245
|
-
taskId: data.taskId,
|
|
246
|
-
});
|
|
247
|
-
return [2 /*return*/];
|
|
248
|
-
}
|
|
219
|
+
var _this = this;
|
|
220
|
+
if (data.outgoing && data.outgoing.length > 0) {
|
|
221
|
+
data.outgoing.forEach(function (item) {
|
|
222
|
+
_this.addAction({
|
|
223
|
+
executionId: data.executionId,
|
|
224
|
+
nodeId: item.target,
|
|
225
|
+
});
|
|
249
226
|
});
|
|
227
|
+
}
|
|
228
|
+
this.saveActionResult(data);
|
|
229
|
+
this.removeActionFromRunningMap(data);
|
|
230
|
+
this.run({
|
|
231
|
+
executionId: data.executionId,
|
|
232
|
+
nodeId: data.nodeId,
|
|
233
|
+
actionId: data.actionId,
|
|
250
234
|
});
|
|
251
235
|
};
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
executionId: data.executionId,
|
|
261
|
-
taskId: data.taskId,
|
|
262
|
-
nodeId: data.nodeId,
|
|
263
|
-
nodeType: data.nodeType,
|
|
264
|
-
timestamp: Date.now(),
|
|
265
|
-
properties: data.properties,
|
|
266
|
-
})];
|
|
267
|
-
case 1:
|
|
268
|
-
_a.sent();
|
|
269
|
-
return [2 /*return*/];
|
|
270
|
-
}
|
|
271
|
-
});
|
|
236
|
+
Scheduler.prototype.saveActionResult = function (data) {
|
|
237
|
+
this.recorder.addActionRecord({
|
|
238
|
+
executionId: data.executionId,
|
|
239
|
+
actionId: data.actionId,
|
|
240
|
+
nodeId: data.nodeId,
|
|
241
|
+
nodeType: data.nodeType,
|
|
242
|
+
timestamp: Date.now(),
|
|
243
|
+
properties: data.properties,
|
|
272
244
|
});
|
|
273
245
|
};
|
|
274
246
|
return Scheduler;
|
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,38 @@ 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
|
+
var iframeWindow = iframe.contentWindow;
|
|
45
|
+
iframeWindow.parent = null;
|
|
46
|
+
Object.keys(globalData).forEach(function (key) {
|
|
47
|
+
iframeWindow[key] = globalData[key];
|
|
48
|
+
});
|
|
49
|
+
return iframeWindow;
|
|
50
|
+
};
|
|
51
|
+
var runInContext = function (code, context) {
|
|
52
|
+
try {
|
|
53
|
+
var iframeEval = context.eval;
|
|
54
|
+
iframeEval.call(context, code);
|
|
55
|
+
}
|
|
56
|
+
catch (e) {
|
|
57
|
+
console.warn(getWarningMsg(WarningCode.EXPRESSION_EXEC_ERROR), { code: code, context: context, e: e });
|
|
58
|
+
}
|
|
59
|
+
return context;
|
|
60
|
+
};
|
|
38
61
|
var runInBrowserContext = function (code, globalData) {
|
|
39
62
|
if (globalData === void 0) { globalData = {}; }
|
|
40
63
|
return __awaiter(void 0, void 0, void 0, function () {
|
|
41
|
-
var
|
|
64
|
+
var context;
|
|
42
65
|
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];
|
|
66
|
+
context = createContext(globalData);
|
|
67
|
+
runInContext(code, context);
|
|
68
|
+
return [2 /*return*/, context];
|
|
63
69
|
});
|
|
64
70
|
});
|
|
65
71
|
};
|
|
66
|
-
export { runInBrowserContext, };
|
|
72
|
+
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,26 @@ 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>;
|
|
44
52
|
getExecutionRecord(executionId: any): Promise<any[]>;
|
|
53
|
+
getGlobalData(): Record<string, any>;
|
|
54
|
+
setGlobalData(data: any): void;
|
|
55
|
+
updateGlobalData(data: any): void;
|
|
45
56
|
}
|
|
46
57
|
export { Engine, TaskNode, StartNode, };
|
|
47
|
-
export type {
|
|
58
|
+
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;
|
|
@@ -138,18 +146,35 @@ var Engine = /** @class */ (function () {
|
|
|
138
146
|
var tasks, records, i;
|
|
139
147
|
return __generator(this, function (_a) {
|
|
140
148
|
switch (_a.label) {
|
|
141
|
-
case 0: return [4 /*yield*/, this.recorder.
|
|
149
|
+
case 0: return [4 /*yield*/, this.recorder.getExecutionActions(executionId)];
|
|
142
150
|
case 1:
|
|
143
151
|
tasks = _a.sent();
|
|
152
|
+
if (!tasks) {
|
|
153
|
+
return [2 /*return*/, null];
|
|
154
|
+
}
|
|
144
155
|
records = [];
|
|
145
156
|
for (i = 0; i < tasks.length; i++) {
|
|
146
|
-
records.push(this.recorder.
|
|
157
|
+
records.push(this.recorder.getActionRecord(tasks[i]));
|
|
147
158
|
}
|
|
148
159
|
return [2 /*return*/, Promise.all(records)];
|
|
149
160
|
}
|
|
150
161
|
});
|
|
151
162
|
});
|
|
152
163
|
};
|
|
164
|
+
Engine.prototype.getGlobalData = function () {
|
|
165
|
+
var _a;
|
|
166
|
+
return (_a = this.flowModel) === null || _a === void 0 ? void 0 : _a.globalData;
|
|
167
|
+
};
|
|
168
|
+
Engine.prototype.setGlobalData = function (data) {
|
|
169
|
+
if (this.flowModel) {
|
|
170
|
+
this.flowModel.globalData = data;
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
Engine.prototype.updateGlobalData = function (data) {
|
|
174
|
+
if (this.flowModel) {
|
|
175
|
+
Object.assign(this.flowModel.globalData, data);
|
|
176
|
+
}
|
|
177
|
+
};
|
|
153
178
|
return Engine;
|
|
154
179
|
}());
|
|
155
180
|
export default Engine;
|