@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/CHANGELOG.md
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Change Log
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
|
+
|
|
6
|
+
## [0.0.3](https://github.com/didi/LogicFlow/compare/@logicflow/engine@0.0.2...@logicflow/engine@0.0.3) (2023-08-18)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* **engine:** build error when use es-module ([3fbd88a](https://github.com/didi/LogicFlow/commit/3fbd88a8279602b907ab6f3e3a6353a46f64ee8c))
|
|
12
|
+
* **engine:** support es module umd and commonJs ([bb17159](https://github.com/didi/LogicFlow/commit/bb171597725b78b28cc2ad74350ab7728e580158))
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
## 0.0.2 (2023-08-10)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
### Bug Fixes
|
|
22
|
+
|
|
23
|
+
* **engine:** consistent expression evaluation in browser and nodejs ([8f24045](https://github.com/didi/LogicFlow/commit/8f240451dce588b6fa21e639c79e1a0782937ff9))
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
### Features
|
|
27
|
+
|
|
28
|
+
* add support for specifying the start node and multiple executions ([113ad88](https://github.com/didi/LogicFlow/commit/113ad880cdb564431933eeeed3b661c50fca2a9c))
|
|
29
|
+
* added expression evaluation functionality for Node.js and browser ([a7759f6](https://github.com/didi/LogicFlow/commit/a7759f69d4f7b294397c8502da654ea7c729d930))
|
|
30
|
+
* create logicflow eninge ([c7d80f4](https://github.com/didi/LogicFlow/commit/c7d80f4b4c19cf82af9be49dd8fd44433327db58))
|
|
31
|
+
* **engie:** support parallel execution within workflows ([8e17ea6](https://github.com/didi/LogicFlow/commit/8e17ea614c5c3567e532a67240cf8e0e9110b2bf))
|
|
32
|
+
* **engine:** add comments and sync storage execution ([6fa0904](https://github.com/didi/LogicFlow/commit/6fa0904ddee88254d4af5c246ff0247c988dfdd2))
|
|
33
|
+
* **engine:** add the ability to pause and resume workflows ([7c4e385](https://github.com/didi/LogicFlow/commit/7c4e3855ad0a7af4121de6552be61f690b4e0e6c))
|
|
34
|
+
* **engine:** added workflow scheduling feature ([c2a7044](https://github.com/didi/LogicFlow/commit/c2a704449772445387f324924491f15e526dfc4e))
|
|
35
|
+
* implemented execution record query functionality ([d73aa46](https://github.com/didi/LogicFlow/commit/d73aa46675f35bae5362e6024232d44cbfe5bcaa))
|
package/README.md
CHANGED
|
@@ -4,19 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
## 使用方式
|
|
6
6
|
|
|
7
|
-
```
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const flowModel = new LogicFlowEngine({
|
|
11
|
-
graphData: {
|
|
12
|
-
nodes: [],
|
|
13
|
-
edges: [],
|
|
14
|
-
},
|
|
15
|
-
global: {
|
|
16
|
-
// 全局数据
|
|
17
|
-
}
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
flowModel.execute();
|
|
21
|
-
|
|
7
|
+
```shell
|
|
8
|
+
npm test
|
|
22
9
|
```
|
|
10
|
+
|
package/cjs/FlowModel.js
CHANGED
|
@@ -70,7 +70,7 @@ var FlowModel = /** @class */ (function () {
|
|
|
70
70
|
// 流程包含的节点类型
|
|
71
71
|
this.nodeModelMap = nodeModelMap;
|
|
72
72
|
// 需要执行的队列
|
|
73
|
-
this.
|
|
73
|
+
this.executeList = [];
|
|
74
74
|
// 执行中的任务
|
|
75
75
|
this.executingInstance = null;
|
|
76
76
|
// 外部传入的上下文,最终会传递给每个节点
|
|
@@ -85,18 +85,53 @@ var FlowModel = /** @class */ (function () {
|
|
|
85
85
|
recorder: recorder,
|
|
86
86
|
});
|
|
87
87
|
this.scheduler.on(constant_1.EVENT_INSTANCE_COMPLETE, function (result) {
|
|
88
|
-
_this.
|
|
88
|
+
_this.onExecuteFinished(result);
|
|
89
89
|
});
|
|
90
90
|
this.scheduler.on(constant_1.EVENT_INSTANCE_INTERRUPTED, function (result) {
|
|
91
|
-
_this.
|
|
91
|
+
_this.onExecuteFinished(result);
|
|
92
92
|
});
|
|
93
93
|
}
|
|
94
94
|
FlowModel.prototype.setStartNodeType = function (startNodeType) {
|
|
95
95
|
this.startNodeType = startNodeType;
|
|
96
96
|
};
|
|
97
|
+
/**
|
|
98
|
+
* 解析LogicFlow图数据,将nodes和edges转换成节点格式。
|
|
99
|
+
* 例如:
|
|
100
|
+
* graphData: {
|
|
101
|
+
* nodes: [
|
|
102
|
+
* { id: 'node1', type: 'StartNode', properties: {} },
|
|
103
|
+
* { id: 'node2', type: 'TaskNode', properties: {} },
|
|
104
|
+
* ],
|
|
105
|
+
* edges: [
|
|
106
|
+
* { id: 'edge1', sourceNodeId: 'node1', targetNodeId: 'node2', properties: {} },
|
|
107
|
+
* ]
|
|
108
|
+
* }
|
|
109
|
+
* 转换成:
|
|
110
|
+
* nodeConfigMap: {
|
|
111
|
+
* node1: {
|
|
112
|
+
* id: 'node1',
|
|
113
|
+
* type: 'StartNode',
|
|
114
|
+
* properties: {},
|
|
115
|
+
* incoming: [],
|
|
116
|
+
* outgoing: [{ id: 'edge1', properties: {}, target: 'node2' }]
|
|
117
|
+
* },
|
|
118
|
+
* node2: {
|
|
119
|
+
* id: 'node2',
|
|
120
|
+
* type: 'TaskNode',
|
|
121
|
+
* properties: {},
|
|
122
|
+
* incoming: [{ id: 'edge1', properties: {}, source: 'node1' }],
|
|
123
|
+
* outgoing: [],
|
|
124
|
+
* }
|
|
125
|
+
* }
|
|
126
|
+
* 此格式方便后续执行时,根据节点id快速找到节点和执行初始化节点模型。
|
|
127
|
+
* 同时此方法还会找到所有的开始节点,方便后续执行时,从开始节点开始执行。
|
|
128
|
+
* @param graphData 流程图数据
|
|
129
|
+
*/
|
|
97
130
|
FlowModel.prototype.load = function (graphData) {
|
|
98
131
|
var _this = this;
|
|
99
132
|
var _a = graphData.nodes, nodes = _a === void 0 ? [] : _a, _b = graphData.edges, edges = _b === void 0 ? [] : _b;
|
|
133
|
+
this.startNodes = [];
|
|
134
|
+
this.nodeConfigMap = new Map();
|
|
100
135
|
nodes.forEach(function (node) {
|
|
101
136
|
if (_this.nodeModelMap.has(node.type)) {
|
|
102
137
|
var nodeConfig = {
|
|
@@ -135,24 +170,19 @@ var FlowModel = /** @class */ (function () {
|
|
|
135
170
|
});
|
|
136
171
|
};
|
|
137
172
|
/**
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
* 例如:
|
|
173
|
+
* 执行流程, 每次执行都会生成一个唯一的executionId,用于区分不同的执行。
|
|
174
|
+
* 同一次执行,这次执行内部的节点执行顺序为并行。内部并行是为了避免异步节点阻塞其他节点的执行。
|
|
175
|
+
* 多次执行,多次执行之间为串行,这里选择串行的原因是避免多次执行之间的数据冲突。
|
|
176
|
+
* example:
|
|
143
177
|
* 一个流程存在着两个开始节点,A和B,A和B的下一个节点都是C,C的下两个节点是D和E。
|
|
144
178
|
* 外部分别触发了A和B的执行,那么A和B的执行是串行的(也就是需要A执行完成后再执行B),但是D和E的执行是并行的。
|
|
145
179
|
* 如果希望A和B的执行是并行的,就不能使用同一个流程模型执行,应该初始化两个。
|
|
180
|
+
* TODO: 去掉此处的对列,直接使用调度器的队列。
|
|
146
181
|
*/
|
|
147
182
|
FlowModel.prototype.execute = function (params) {
|
|
148
183
|
return __awaiter(this, void 0, void 0, function () {
|
|
149
184
|
return __generator(this, function (_a) {
|
|
150
|
-
this.
|
|
151
|
-
if (this.isRunning) {
|
|
152
|
-
return [2 /*return*/];
|
|
153
|
-
}
|
|
154
|
-
this.isRunning = true;
|
|
155
|
-
this.createExecution();
|
|
185
|
+
this.createExecution(params);
|
|
156
186
|
return [2 /*return*/];
|
|
157
187
|
});
|
|
158
188
|
});
|
|
@@ -160,30 +190,26 @@ var FlowModel = /** @class */ (function () {
|
|
|
160
190
|
FlowModel.prototype.resume = function (params) {
|
|
161
191
|
return __awaiter(this, void 0, void 0, function () {
|
|
162
192
|
return __generator(this, function (_a) {
|
|
163
|
-
this.
|
|
164
|
-
if (this.isRunning) {
|
|
165
|
-
return [2 /*return*/];
|
|
166
|
-
}
|
|
167
|
-
this.isRunning = true;
|
|
168
|
-
this.createExecution();
|
|
193
|
+
this.createExecution(params);
|
|
169
194
|
return [2 /*return*/];
|
|
170
195
|
});
|
|
171
196
|
});
|
|
172
197
|
};
|
|
173
198
|
/**
|
|
174
|
-
*
|
|
199
|
+
* 创建节点实例, 每个节点实例都会有一个唯一的actionId。
|
|
200
|
+
* 通过executionId、nodeId、actionId可以唯一确定一个节点的某一次执行。
|
|
175
201
|
* @param nodeId 节点Id
|
|
176
202
|
* @returns 节点示例
|
|
177
203
|
*/
|
|
178
|
-
FlowModel.prototype.
|
|
204
|
+
FlowModel.prototype.createAction = function (nodeId) {
|
|
179
205
|
var nodeConfig = this.nodeConfigMap.get(nodeId);
|
|
180
206
|
var NodeModel = this.nodeModelMap.get(nodeConfig.type);
|
|
181
|
-
var
|
|
207
|
+
var action = new NodeModel({
|
|
182
208
|
nodeConfig: nodeConfig,
|
|
183
209
|
globalData: this.globalData,
|
|
184
210
|
context: this.context,
|
|
185
211
|
});
|
|
186
|
-
return
|
|
212
|
+
return action;
|
|
187
213
|
};
|
|
188
214
|
/**
|
|
189
215
|
* 更新流程全局数据
|
|
@@ -191,43 +217,40 @@ var FlowModel = /** @class */ (function () {
|
|
|
191
217
|
FlowModel.prototype.updateGlobalData = function (data) {
|
|
192
218
|
this.globalData = __assign(__assign({}, this.globalData), data);
|
|
193
219
|
};
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
var
|
|
200
|
-
if (
|
|
201
|
-
callback
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
if (this.executeQueue.length > 0) {
|
|
205
|
-
this.createExecution();
|
|
206
|
-
}
|
|
207
|
-
else {
|
|
208
|
-
this.isRunning = false;
|
|
220
|
+
/**
|
|
221
|
+
* 在执行完成后,通知外部此次执行完成。
|
|
222
|
+
* 如果还存在待执行的任务,那么继续执行。
|
|
223
|
+
*/
|
|
224
|
+
FlowModel.prototype.onExecuteFinished = function (result) {
|
|
225
|
+
var index = this.executeList.findIndex(function (i) { return i.executionId === result.executionId; });
|
|
226
|
+
if (index !== -1) {
|
|
227
|
+
var callback = this.executeList[index].callback;
|
|
228
|
+
this.executeList.splice(index, 1);
|
|
229
|
+
callback && callback(result);
|
|
209
230
|
}
|
|
210
231
|
};
|
|
211
|
-
|
|
232
|
+
/**
|
|
233
|
+
* 从待执行队列中取出需要执行的内容。
|
|
234
|
+
* 会依次判断是否有taskId、nodeId、executionId。
|
|
235
|
+
* 若存在taskId,那么表示恢复执行。
|
|
236
|
+
* 若存在nodeId,那么表示从指定节点开始执行。
|
|
237
|
+
* 若都不存在,那么新建一个executionId,从开始节点开始执行。
|
|
238
|
+
*/
|
|
239
|
+
FlowModel.prototype.createExecution = function (execParams) {
|
|
212
240
|
var _this = this;
|
|
213
|
-
|
|
214
|
-
this.executingInstance = execParams;
|
|
215
|
-
if (execParams.executionId) {
|
|
216
|
-
this.executionId = execParams.executionId;
|
|
217
|
-
}
|
|
218
|
-
else {
|
|
219
|
-
this.executionId = ID_1.createExecId();
|
|
220
|
-
}
|
|
241
|
+
this.executeList.push(execParams);
|
|
221
242
|
// 如果有taskId,那么表示恢复执行
|
|
222
|
-
if (execParams.
|
|
243
|
+
if (execParams.actionId && execParams.executionId && execParams.nodeId) {
|
|
223
244
|
this.scheduler.resume({
|
|
224
|
-
executionId:
|
|
225
|
-
|
|
245
|
+
executionId: execParams.executionId,
|
|
246
|
+
actionId: execParams.actionId,
|
|
226
247
|
nodeId: execParams.nodeId,
|
|
227
248
|
data: execParams.data,
|
|
228
249
|
});
|
|
229
250
|
return;
|
|
230
251
|
}
|
|
252
|
+
var executionId = ID_1.createExecId();
|
|
253
|
+
execParams.executionId = executionId;
|
|
231
254
|
if (execParams.nodeId) {
|
|
232
255
|
var nodeConfig = this.nodeConfigMap.get(execParams.nodeId);
|
|
233
256
|
if (!nodeConfig) {
|
|
@@ -237,14 +260,13 @@ var FlowModel = /** @class */ (function () {
|
|
|
237
260
|
this.startNodes = [nodeConfig];
|
|
238
261
|
}
|
|
239
262
|
this.startNodes.forEach(function (startNode) {
|
|
240
|
-
_this.scheduler.
|
|
241
|
-
executionId:
|
|
263
|
+
_this.scheduler.addAction({
|
|
264
|
+
executionId: executionId,
|
|
242
265
|
nodeId: startNode.id,
|
|
243
266
|
});
|
|
244
|
-
// 所有的开始节点都执行
|
|
245
267
|
});
|
|
246
268
|
this.scheduler.run({
|
|
247
|
-
executionId:
|
|
269
|
+
executionId: executionId,
|
|
248
270
|
});
|
|
249
271
|
};
|
|
250
272
|
return FlowModel;
|
package/cjs/Scheduler.js
CHANGED
|
@@ -72,10 +72,9 @@ var Scheduler = /** @class */ (function (_super) {
|
|
|
72
72
|
function Scheduler(config) {
|
|
73
73
|
var _this = _super.call(this) || this;
|
|
74
74
|
_this.nodeQueueMap = new Map();
|
|
75
|
-
_this.
|
|
75
|
+
_this.actionRunningMap = new Map();
|
|
76
76
|
_this.flowModel = config.flowModel;
|
|
77
77
|
_this.recorder = config.recorder;
|
|
78
|
-
_this.currentTask = null;
|
|
79
78
|
return _this;
|
|
80
79
|
}
|
|
81
80
|
/**
|
|
@@ -83,13 +82,13 @@ var Scheduler = /** @class */ (function (_super) {
|
|
|
83
82
|
* 1. 由流程模型将所有的开始节点添加到队列中。
|
|
84
83
|
* 2. 当一个节点执行完成后,将后续的节点添加到队列中。
|
|
85
84
|
*/
|
|
86
|
-
Scheduler.prototype.
|
|
85
|
+
Scheduler.prototype.addAction = function (nodeParam) {
|
|
87
86
|
var executionId = nodeParam.executionId;
|
|
88
87
|
if (!this.nodeQueueMap.has(executionId)) {
|
|
89
88
|
this.nodeQueueMap.set(executionId, []);
|
|
90
89
|
}
|
|
91
|
-
var
|
|
92
|
-
|
|
90
|
+
var currentActionQueue = this.nodeQueueMap.get(executionId);
|
|
91
|
+
currentActionQueue.push(nodeParam);
|
|
93
92
|
};
|
|
94
93
|
/**
|
|
95
94
|
* 调度器执行下一个任务
|
|
@@ -99,22 +98,21 @@ var Scheduler = /** @class */ (function (_super) {
|
|
|
99
98
|
*/
|
|
100
99
|
Scheduler.prototype.run = function (runParams) {
|
|
101
100
|
var nodeQueue = this.nodeQueueMap.get(runParams.executionId);
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
}
|
|
101
|
+
// 将同一个executionId当前待执行的节点一起执行
|
|
102
|
+
// 避免出现某一个节点执行时间过长,导致其他节点等待时间过长。
|
|
103
|
+
while (nodeQueue.length) {
|
|
104
|
+
var currentNode = nodeQueue.pop();
|
|
105
|
+
var actionId = ID_1.createActionId();
|
|
106
|
+
var actionParam = __assign(__assign({}, currentNode), { actionId: actionId });
|
|
107
|
+
this.pushActionToRunningMap(actionParam);
|
|
108
|
+
this.exec(actionParam);
|
|
111
109
|
}
|
|
112
|
-
|
|
113
|
-
// 当一个流程在nodeQueueMap和
|
|
110
|
+
if (!this.hasRunningAction(runParams.executionId)) {
|
|
111
|
+
// 当一个流程在nodeQueueMap和actionRunningMap中都不存在执行的节点时,说明这个流程已经执行完成。
|
|
114
112
|
this.emit(constant_1.EVENT_INSTANCE_COMPLETE, {
|
|
115
113
|
executionId: runParams.executionId,
|
|
116
114
|
nodeId: runParams.nodeId,
|
|
117
|
-
|
|
115
|
+
actionId: runParams.actionId,
|
|
118
116
|
status: constant_1.FlowStatus.COMPLETED,
|
|
119
117
|
});
|
|
120
118
|
}
|
|
@@ -129,12 +127,12 @@ var Scheduler = /** @class */ (function (_super) {
|
|
|
129
127
|
return __generator(this, function (_a) {
|
|
130
128
|
switch (_a.label) {
|
|
131
129
|
case 0:
|
|
132
|
-
this.
|
|
130
|
+
this.pushActionToRunningMap({
|
|
133
131
|
executionId: resumeParam.executionId,
|
|
134
132
|
nodeId: resumeParam.nodeId,
|
|
135
|
-
|
|
133
|
+
actionId: resumeParam.actionId,
|
|
136
134
|
});
|
|
137
|
-
model = this.flowModel.
|
|
135
|
+
model = this.flowModel.createAction(resumeParam.nodeId);
|
|
138
136
|
return [4 /*yield*/, model.resume(__assign(__assign({}, resumeParam), { next: this.next.bind(this) }))];
|
|
139
137
|
case 1:
|
|
140
138
|
_a.sent();
|
|
@@ -143,48 +141,44 @@ var Scheduler = /** @class */ (function (_super) {
|
|
|
143
141
|
});
|
|
144
142
|
});
|
|
145
143
|
};
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
};
|
|
150
|
-
Scheduler.prototype.pushTaskToRunningMap = function (taskParam) {
|
|
151
|
-
var executionId = taskParam.executionId, taskId = taskParam.taskId;
|
|
152
|
-
if (!this.taskRunningMap.has(executionId)) {
|
|
144
|
+
Scheduler.prototype.pushActionToRunningMap = function (actionParam) {
|
|
145
|
+
var executionId = actionParam.executionId, actionId = actionParam.actionId;
|
|
146
|
+
if (!this.actionRunningMap.has(executionId)) {
|
|
153
147
|
var runningMap = new Map();
|
|
154
|
-
this.
|
|
148
|
+
this.actionRunningMap.set(executionId, runningMap);
|
|
155
149
|
}
|
|
156
|
-
this.
|
|
150
|
+
this.actionRunningMap.get(executionId).set(actionId, actionParam);
|
|
157
151
|
};
|
|
158
|
-
Scheduler.prototype.
|
|
159
|
-
var executionId =
|
|
160
|
-
if (!
|
|
152
|
+
Scheduler.prototype.removeActionFromRunningMap = function (actionParam) {
|
|
153
|
+
var executionId = actionParam.executionId, actionId = actionParam.actionId;
|
|
154
|
+
if (!actionId)
|
|
161
155
|
return;
|
|
162
|
-
var runningMap = this.
|
|
156
|
+
var runningMap = this.actionRunningMap.get(executionId);
|
|
163
157
|
if (!runningMap)
|
|
164
158
|
return;
|
|
165
|
-
runningMap.delete(
|
|
159
|
+
runningMap.delete(actionId);
|
|
166
160
|
};
|
|
167
|
-
Scheduler.prototype.
|
|
168
|
-
var runningMap = this.
|
|
161
|
+
Scheduler.prototype.hasRunningAction = function (executionId) {
|
|
162
|
+
var runningMap = this.actionRunningMap.get(executionId);
|
|
169
163
|
if (!runningMap)
|
|
170
164
|
return false;
|
|
171
165
|
if (runningMap.size === 0) {
|
|
172
|
-
this.
|
|
166
|
+
this.actionRunningMap.delete(executionId);
|
|
173
167
|
return false;
|
|
174
168
|
}
|
|
175
169
|
return true;
|
|
176
170
|
};
|
|
177
|
-
Scheduler.prototype.exec = function (
|
|
171
|
+
Scheduler.prototype.exec = function (actionParam) {
|
|
178
172
|
return __awaiter(this, void 0, void 0, function () {
|
|
179
173
|
var model, execResult;
|
|
180
174
|
return __generator(this, function (_a) {
|
|
181
175
|
switch (_a.label) {
|
|
182
176
|
case 0:
|
|
183
|
-
model = this.flowModel.
|
|
177
|
+
model = this.flowModel.createAction(actionParam.nodeId);
|
|
184
178
|
return [4 /*yield*/, model.execute({
|
|
185
|
-
executionId:
|
|
186
|
-
|
|
187
|
-
nodeId:
|
|
179
|
+
executionId: actionParam.executionId,
|
|
180
|
+
actionId: actionParam.actionId,
|
|
181
|
+
nodeId: actionParam.nodeId,
|
|
188
182
|
next: this.next.bind(this),
|
|
189
183
|
})];
|
|
190
184
|
case 1:
|
|
@@ -192,12 +186,12 @@ var Scheduler = /** @class */ (function (_super) {
|
|
|
192
186
|
if (execResult && execResult.status === constant_1.FlowStatus.INTERRUPTED) {
|
|
193
187
|
this.interrupted({
|
|
194
188
|
execResult: execResult,
|
|
195
|
-
|
|
189
|
+
actionParam: actionParam,
|
|
196
190
|
});
|
|
197
|
-
this.
|
|
198
|
-
executionId:
|
|
199
|
-
nodeId:
|
|
200
|
-
|
|
191
|
+
this.saveActionResult({
|
|
192
|
+
executionId: actionParam.executionId,
|
|
193
|
+
nodeId: actionParam.nodeId,
|
|
194
|
+
actionId: actionParam.actionId,
|
|
201
195
|
nodeType: execResult.nodeType,
|
|
202
196
|
properties: execResult.properties,
|
|
203
197
|
outgoing: [],
|
|
@@ -206,7 +200,7 @@ var Scheduler = /** @class */ (function (_super) {
|
|
|
206
200
|
detail: execResult.detail,
|
|
207
201
|
},
|
|
208
202
|
});
|
|
209
|
-
this.
|
|
203
|
+
this.removeActionFromRunningMap(actionParam);
|
|
210
204
|
}
|
|
211
205
|
return [2 /*return*/];
|
|
212
206
|
}
|
|
@@ -214,63 +208,41 @@ var Scheduler = /** @class */ (function (_super) {
|
|
|
214
208
|
});
|
|
215
209
|
};
|
|
216
210
|
Scheduler.prototype.interrupted = function (_a) {
|
|
217
|
-
var execResult = _a.execResult,
|
|
211
|
+
var execResult = _a.execResult, actionParam = _a.actionParam;
|
|
218
212
|
this.emit(constant_1.EVENT_INSTANCE_INTERRUPTED, {
|
|
219
|
-
executionId:
|
|
213
|
+
executionId: actionParam.executionId,
|
|
220
214
|
status: constant_1.FlowStatus.INTERRUPTED,
|
|
221
|
-
nodeId:
|
|
222
|
-
|
|
215
|
+
nodeId: actionParam.nodeId,
|
|
216
|
+
actionId: actionParam.actionId,
|
|
223
217
|
detail: execResult.detail,
|
|
224
218
|
});
|
|
225
219
|
};
|
|
226
220
|
Scheduler.prototype.next = function (data) {
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
_this.addTask({
|
|
235
|
-
executionId: data.executionId,
|
|
236
|
-
nodeId: item.target,
|
|
237
|
-
});
|
|
238
|
-
});
|
|
239
|
-
}
|
|
240
|
-
return [4 /*yield*/, this.saveTaskResult(data)];
|
|
241
|
-
case 1:
|
|
242
|
-
_a.sent();
|
|
243
|
-
this.removeTaskFromRunningMap(data);
|
|
244
|
-
this.run({
|
|
245
|
-
executionId: data.executionId,
|
|
246
|
-
nodeId: data.nodeId,
|
|
247
|
-
taskId: data.taskId,
|
|
248
|
-
});
|
|
249
|
-
return [2 /*return*/];
|
|
250
|
-
}
|
|
221
|
+
var _this = this;
|
|
222
|
+
if (data.outgoing && data.outgoing.length > 0) {
|
|
223
|
+
data.outgoing.forEach(function (item) {
|
|
224
|
+
_this.addAction({
|
|
225
|
+
executionId: data.executionId,
|
|
226
|
+
nodeId: item.target,
|
|
227
|
+
});
|
|
251
228
|
});
|
|
229
|
+
}
|
|
230
|
+
this.saveActionResult(data);
|
|
231
|
+
this.removeActionFromRunningMap(data);
|
|
232
|
+
this.run({
|
|
233
|
+
executionId: data.executionId,
|
|
234
|
+
nodeId: data.nodeId,
|
|
235
|
+
actionId: data.actionId,
|
|
252
236
|
});
|
|
253
237
|
};
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
executionId: data.executionId,
|
|
263
|
-
taskId: data.taskId,
|
|
264
|
-
nodeId: data.nodeId,
|
|
265
|
-
nodeType: data.nodeType,
|
|
266
|
-
timestamp: Date.now(),
|
|
267
|
-
properties: data.properties,
|
|
268
|
-
})];
|
|
269
|
-
case 1:
|
|
270
|
-
_a.sent();
|
|
271
|
-
return [2 /*return*/];
|
|
272
|
-
}
|
|
273
|
-
});
|
|
238
|
+
Scheduler.prototype.saveActionResult = function (data) {
|
|
239
|
+
this.recorder.addActionRecord({
|
|
240
|
+
executionId: data.executionId,
|
|
241
|
+
actionId: data.actionId,
|
|
242
|
+
nodeId: data.nodeId,
|
|
243
|
+
nodeType: data.nodeType,
|
|
244
|
+
timestamp: Date.now(),
|
|
245
|
+
properties: data.properties,
|
|
274
246
|
});
|
|
275
247
|
};
|
|
276
248
|
return Scheduler;
|
package/cjs/constant/constant.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.ActionStatus = exports.FlowStatus = exports.EVENT_INSTANCE_INTERRUPTED = exports.EVENT_INSTANCE_COMPLETE = exports.BASE_START_NODE = void 0;
|
|
4
4
|
// baseType
|
|
5
5
|
exports.BASE_START_NODE = 'start';
|
|
6
6
|
// event name
|
|
@@ -14,10 +14,10 @@ var FlowStatus;
|
|
|
14
14
|
FlowStatus["RUNNING"] = "running";
|
|
15
15
|
FlowStatus["ERROR"] = "error";
|
|
16
16
|
})(FlowStatus = exports.FlowStatus || (exports.FlowStatus = {}));
|
|
17
|
-
//
|
|
18
|
-
var
|
|
19
|
-
(function (
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
})(
|
|
17
|
+
// action status
|
|
18
|
+
var ActionStatus;
|
|
19
|
+
(function (ActionStatus) {
|
|
20
|
+
ActionStatus["SUCCESS"] = "success";
|
|
21
|
+
ActionStatus["ERROR"] = "error";
|
|
22
|
+
ActionStatus["INTERRUPTED"] = "interrupted";
|
|
23
|
+
})(ActionStatus = exports.ActionStatus || (exports.ActionStatus = {}));
|
|
@@ -36,33 +36,41 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
36
36
|
}
|
|
37
37
|
};
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.runInBrowserContext = void 0;
|
|
39
|
+
exports.runInContext = exports.createContext = exports.runInBrowserContext = void 0;
|
|
40
40
|
var LogCode_1 = require("../constant/LogCode");
|
|
41
|
+
var createContext = function (globalData) {
|
|
42
|
+
var iframe = document.createElement('iframe');
|
|
43
|
+
iframe.style.display = 'none';
|
|
44
|
+
if (!document || !document.body) {
|
|
45
|
+
console.error(LogCode_1.getErrorMsg(LogCode_1.ErrorCode.NO_DOCUMENT_BODY));
|
|
46
|
+
}
|
|
47
|
+
var iframeWindow = iframe.contentWindow;
|
|
48
|
+
iframeWindow.parent = null;
|
|
49
|
+
Object.keys(globalData).forEach(function (key) {
|
|
50
|
+
iframeWindow[key] = globalData[key];
|
|
51
|
+
});
|
|
52
|
+
return iframeWindow;
|
|
53
|
+
};
|
|
54
|
+
exports.createContext = createContext;
|
|
55
|
+
var runInContext = function (code, context) {
|
|
56
|
+
try {
|
|
57
|
+
var iframeEval = context.eval;
|
|
58
|
+
iframeEval.call(context, code);
|
|
59
|
+
}
|
|
60
|
+
catch (e) {
|
|
61
|
+
console.warn(LogCode_1.getWarningMsg(LogCode_1.WarningCode.EXPRESSION_EXEC_ERROR), { code: code, context: context, e: e });
|
|
62
|
+
}
|
|
63
|
+
return context;
|
|
64
|
+
};
|
|
65
|
+
exports.runInContext = runInContext;
|
|
41
66
|
var runInBrowserContext = function (code, globalData) {
|
|
42
67
|
if (globalData === void 0) { globalData = {}; }
|
|
43
68
|
return __awaiter(void 0, void 0, void 0, function () {
|
|
44
|
-
var
|
|
69
|
+
var context;
|
|
45
70
|
return __generator(this, function (_a) {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
console.error(LogCode_1.getErrorMsg(LogCode_1.ErrorCode.NO_DOCUMENT_BODY));
|
|
50
|
-
}
|
|
51
|
-
document.body.appendChild(iframe);
|
|
52
|
-
iframeWindow = iframe.contentWindow;
|
|
53
|
-
iframeEval = iframeWindow.eval;
|
|
54
|
-
Object.keys(globalData).forEach(function (key) {
|
|
55
|
-
iframeWindow[key] = globalData[key];
|
|
56
|
-
});
|
|
57
|
-
res = null;
|
|
58
|
-
try {
|
|
59
|
-
res = iframeEval.call(iframeWindow, code);
|
|
60
|
-
}
|
|
61
|
-
catch (e) {
|
|
62
|
-
console.warn(LogCode_1.getWarningMsg(LogCode_1.WarningCode.EXPRESSION_EXEC_ERROR), { code: code, globalData: globalData, e: e });
|
|
63
|
-
}
|
|
64
|
-
document.body.removeChild(iframe);
|
|
65
|
-
return [2 /*return*/, res];
|
|
71
|
+
context = createContext(globalData);
|
|
72
|
+
runInContext(code, context);
|
|
73
|
+
return [2 /*return*/, context];
|
|
66
74
|
});
|
|
67
75
|
});
|
|
68
76
|
};
|
package/cjs/expression/nodeVm.js
CHANGED
|
@@ -37,7 +37,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
37
37
|
};
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
39
|
exports.runInNewContext = void 0;
|
|
40
|
-
|
|
40
|
+
/* eslint-disable global-require */
|
|
41
41
|
var vm = require('vm');
|
|
42
42
|
var runInNewContext = function (code, globalData) {
|
|
43
43
|
if (globalData === void 0) { globalData = {}; }
|