@logicflow/engine 0.0.2 → 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 +12 -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 +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 +41 -20
- 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 +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 +41 -20
- 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/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,18 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
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
|
+
|
|
6
18
|
## 0.0.2 (2023-08-10)
|
|
7
19
|
|
|
8
20
|
|
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,10 +85,10 @@ 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) {
|
|
@@ -177,16 +177,12 @@ var FlowModel = /** @class */ (function () {
|
|
|
177
177
|
* 一个流程存在着两个开始节点,A和B,A和B的下一个节点都是C,C的下两个节点是D和E。
|
|
178
178
|
* 外部分别触发了A和B的执行,那么A和B的执行是串行的(也就是需要A执行完成后再执行B),但是D和E的执行是并行的。
|
|
179
179
|
* 如果希望A和B的执行是并行的,就不能使用同一个流程模型执行,应该初始化两个。
|
|
180
|
+
* TODO: 去掉此处的对列,直接使用调度器的队列。
|
|
180
181
|
*/
|
|
181
182
|
FlowModel.prototype.execute = function (params) {
|
|
182
183
|
return __awaiter(this, void 0, void 0, function () {
|
|
183
184
|
return __generator(this, function (_a) {
|
|
184
|
-
this.
|
|
185
|
-
if (this.isRunning) {
|
|
186
|
-
return [2 /*return*/];
|
|
187
|
-
}
|
|
188
|
-
this.isRunning = true;
|
|
189
|
-
this.createExecution();
|
|
185
|
+
this.createExecution(params);
|
|
190
186
|
return [2 /*return*/];
|
|
191
187
|
});
|
|
192
188
|
});
|
|
@@ -194,31 +190,26 @@ var FlowModel = /** @class */ (function () {
|
|
|
194
190
|
FlowModel.prototype.resume = function (params) {
|
|
195
191
|
return __awaiter(this, void 0, void 0, function () {
|
|
196
192
|
return __generator(this, function (_a) {
|
|
197
|
-
this.
|
|
198
|
-
if (this.isRunning) {
|
|
199
|
-
return [2 /*return*/];
|
|
200
|
-
}
|
|
201
|
-
this.isRunning = true;
|
|
202
|
-
this.createExecution();
|
|
193
|
+
this.createExecution(params);
|
|
203
194
|
return [2 /*return*/];
|
|
204
195
|
});
|
|
205
196
|
});
|
|
206
197
|
};
|
|
207
198
|
/**
|
|
208
|
-
* 创建节点实例, 每个节点实例都会有一个唯一的
|
|
209
|
-
* 通过executionId、nodeId、
|
|
199
|
+
* 创建节点实例, 每个节点实例都会有一个唯一的actionId。
|
|
200
|
+
* 通过executionId、nodeId、actionId可以唯一确定一个节点的某一次执行。
|
|
210
201
|
* @param nodeId 节点Id
|
|
211
202
|
* @returns 节点示例
|
|
212
203
|
*/
|
|
213
|
-
FlowModel.prototype.
|
|
204
|
+
FlowModel.prototype.createAction = function (nodeId) {
|
|
214
205
|
var nodeConfig = this.nodeConfigMap.get(nodeId);
|
|
215
206
|
var NodeModel = this.nodeModelMap.get(nodeConfig.type);
|
|
216
|
-
var
|
|
207
|
+
var action = new NodeModel({
|
|
217
208
|
nodeConfig: nodeConfig,
|
|
218
209
|
globalData: this.globalData,
|
|
219
210
|
context: this.context,
|
|
220
211
|
});
|
|
221
|
-
return
|
|
212
|
+
return action;
|
|
222
213
|
};
|
|
223
214
|
/**
|
|
224
215
|
* 更新流程全局数据
|
|
@@ -230,17 +221,12 @@ var FlowModel = /** @class */ (function () {
|
|
|
230
221
|
* 在执行完成后,通知外部此次执行完成。
|
|
231
222
|
* 如果还存在待执行的任务,那么继续执行。
|
|
232
223
|
*/
|
|
233
|
-
FlowModel.prototype.
|
|
234
|
-
var
|
|
235
|
-
if (
|
|
236
|
-
callback
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
if (this.executeQueue.length > 0) {
|
|
240
|
-
this.createExecution();
|
|
241
|
-
}
|
|
242
|
-
else {
|
|
243
|
-
this.isRunning = false;
|
|
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);
|
|
244
230
|
}
|
|
245
231
|
};
|
|
246
232
|
/**
|
|
@@ -250,21 +236,21 @@ var FlowModel = /** @class */ (function () {
|
|
|
250
236
|
* 若存在nodeId,那么表示从指定节点开始执行。
|
|
251
237
|
* 若都不存在,那么新建一个executionId,从开始节点开始执行。
|
|
252
238
|
*/
|
|
253
|
-
FlowModel.prototype.createExecution = function () {
|
|
239
|
+
FlowModel.prototype.createExecution = function (execParams) {
|
|
254
240
|
var _this = this;
|
|
255
|
-
|
|
256
|
-
this.executingInstance = execParams;
|
|
241
|
+
this.executeList.push(execParams);
|
|
257
242
|
// 如果有taskId,那么表示恢复执行
|
|
258
|
-
if (execParams.
|
|
243
|
+
if (execParams.actionId && execParams.executionId && execParams.nodeId) {
|
|
259
244
|
this.scheduler.resume({
|
|
260
245
|
executionId: execParams.executionId,
|
|
261
|
-
|
|
246
|
+
actionId: execParams.actionId,
|
|
262
247
|
nodeId: execParams.nodeId,
|
|
263
248
|
data: execParams.data,
|
|
264
249
|
});
|
|
265
250
|
return;
|
|
266
251
|
}
|
|
267
|
-
var executionId =
|
|
252
|
+
var executionId = ID_1.createExecId();
|
|
253
|
+
execParams.executionId = executionId;
|
|
268
254
|
if (execParams.nodeId) {
|
|
269
255
|
var nodeConfig = this.nodeConfigMap.get(execParams.nodeId);
|
|
270
256
|
if (!nodeConfig) {
|
|
@@ -274,7 +260,7 @@ var FlowModel = /** @class */ (function () {
|
|
|
274
260
|
this.startNodes = [nodeConfig];
|
|
275
261
|
}
|
|
276
262
|
this.startNodes.forEach(function (startNode) {
|
|
277
|
-
_this.scheduler.
|
|
263
|
+
_this.scheduler.addAction({
|
|
278
264
|
executionId: executionId,
|
|
279
265
|
nodeId: startNode.id,
|
|
280
266
|
});
|
package/cjs/Scheduler.js
CHANGED
|
@@ -72,7 +72,7 @@ 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
78
|
return _this;
|
|
@@ -82,13 +82,13 @@ var Scheduler = /** @class */ (function (_super) {
|
|
|
82
82
|
* 1. 由流程模型将所有的开始节点添加到队列中。
|
|
83
83
|
* 2. 当一个节点执行完成后,将后续的节点添加到队列中。
|
|
84
84
|
*/
|
|
85
|
-
Scheduler.prototype.
|
|
85
|
+
Scheduler.prototype.addAction = function (nodeParam) {
|
|
86
86
|
var executionId = nodeParam.executionId;
|
|
87
87
|
if (!this.nodeQueueMap.has(executionId)) {
|
|
88
88
|
this.nodeQueueMap.set(executionId, []);
|
|
89
89
|
}
|
|
90
|
-
var
|
|
91
|
-
|
|
90
|
+
var currentActionQueue = this.nodeQueueMap.get(executionId);
|
|
91
|
+
currentActionQueue.push(nodeParam);
|
|
92
92
|
};
|
|
93
93
|
/**
|
|
94
94
|
* 调度器执行下一个任务
|
|
@@ -98,22 +98,21 @@ var Scheduler = /** @class */ (function (_super) {
|
|
|
98
98
|
*/
|
|
99
99
|
Scheduler.prototype.run = function (runParams) {
|
|
100
100
|
var nodeQueue = this.nodeQueueMap.get(runParams.executionId);
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
}
|
|
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);
|
|
110
109
|
}
|
|
111
|
-
|
|
112
|
-
// 当一个流程在nodeQueueMap和
|
|
110
|
+
if (!this.hasRunningAction(runParams.executionId)) {
|
|
111
|
+
// 当一个流程在nodeQueueMap和actionRunningMap中都不存在执行的节点时,说明这个流程已经执行完成。
|
|
113
112
|
this.emit(constant_1.EVENT_INSTANCE_COMPLETE, {
|
|
114
113
|
executionId: runParams.executionId,
|
|
115
114
|
nodeId: runParams.nodeId,
|
|
116
|
-
|
|
115
|
+
actionId: runParams.actionId,
|
|
117
116
|
status: constant_1.FlowStatus.COMPLETED,
|
|
118
117
|
});
|
|
119
118
|
}
|
|
@@ -128,12 +127,12 @@ var Scheduler = /** @class */ (function (_super) {
|
|
|
128
127
|
return __generator(this, function (_a) {
|
|
129
128
|
switch (_a.label) {
|
|
130
129
|
case 0:
|
|
131
|
-
this.
|
|
130
|
+
this.pushActionToRunningMap({
|
|
132
131
|
executionId: resumeParam.executionId,
|
|
133
132
|
nodeId: resumeParam.nodeId,
|
|
134
|
-
|
|
133
|
+
actionId: resumeParam.actionId,
|
|
135
134
|
});
|
|
136
|
-
model = this.flowModel.
|
|
135
|
+
model = this.flowModel.createAction(resumeParam.nodeId);
|
|
137
136
|
return [4 /*yield*/, model.resume(__assign(__assign({}, resumeParam), { next: this.next.bind(this) }))];
|
|
138
137
|
case 1:
|
|
139
138
|
_a.sent();
|
|
@@ -142,44 +141,44 @@ var Scheduler = /** @class */ (function (_super) {
|
|
|
142
141
|
});
|
|
143
142
|
});
|
|
144
143
|
};
|
|
145
|
-
Scheduler.prototype.
|
|
146
|
-
var executionId =
|
|
147
|
-
if (!this.
|
|
144
|
+
Scheduler.prototype.pushActionToRunningMap = function (actionParam) {
|
|
145
|
+
var executionId = actionParam.executionId, actionId = actionParam.actionId;
|
|
146
|
+
if (!this.actionRunningMap.has(executionId)) {
|
|
148
147
|
var runningMap = new Map();
|
|
149
|
-
this.
|
|
148
|
+
this.actionRunningMap.set(executionId, runningMap);
|
|
150
149
|
}
|
|
151
|
-
this.
|
|
150
|
+
this.actionRunningMap.get(executionId).set(actionId, actionParam);
|
|
152
151
|
};
|
|
153
|
-
Scheduler.prototype.
|
|
154
|
-
var executionId =
|
|
155
|
-
if (!
|
|
152
|
+
Scheduler.prototype.removeActionFromRunningMap = function (actionParam) {
|
|
153
|
+
var executionId = actionParam.executionId, actionId = actionParam.actionId;
|
|
154
|
+
if (!actionId)
|
|
156
155
|
return;
|
|
157
|
-
var runningMap = this.
|
|
156
|
+
var runningMap = this.actionRunningMap.get(executionId);
|
|
158
157
|
if (!runningMap)
|
|
159
158
|
return;
|
|
160
|
-
runningMap.delete(
|
|
159
|
+
runningMap.delete(actionId);
|
|
161
160
|
};
|
|
162
|
-
Scheduler.prototype.
|
|
163
|
-
var runningMap = this.
|
|
161
|
+
Scheduler.prototype.hasRunningAction = function (executionId) {
|
|
162
|
+
var runningMap = this.actionRunningMap.get(executionId);
|
|
164
163
|
if (!runningMap)
|
|
165
164
|
return false;
|
|
166
165
|
if (runningMap.size === 0) {
|
|
167
|
-
this.
|
|
166
|
+
this.actionRunningMap.delete(executionId);
|
|
168
167
|
return false;
|
|
169
168
|
}
|
|
170
169
|
return true;
|
|
171
170
|
};
|
|
172
|
-
Scheduler.prototype.exec = function (
|
|
171
|
+
Scheduler.prototype.exec = function (actionParam) {
|
|
173
172
|
return __awaiter(this, void 0, void 0, function () {
|
|
174
173
|
var model, execResult;
|
|
175
174
|
return __generator(this, function (_a) {
|
|
176
175
|
switch (_a.label) {
|
|
177
176
|
case 0:
|
|
178
|
-
model = this.flowModel.
|
|
177
|
+
model = this.flowModel.createAction(actionParam.nodeId);
|
|
179
178
|
return [4 /*yield*/, model.execute({
|
|
180
|
-
executionId:
|
|
181
|
-
|
|
182
|
-
nodeId:
|
|
179
|
+
executionId: actionParam.executionId,
|
|
180
|
+
actionId: actionParam.actionId,
|
|
181
|
+
nodeId: actionParam.nodeId,
|
|
183
182
|
next: this.next.bind(this),
|
|
184
183
|
})];
|
|
185
184
|
case 1:
|
|
@@ -187,12 +186,12 @@ var Scheduler = /** @class */ (function (_super) {
|
|
|
187
186
|
if (execResult && execResult.status === constant_1.FlowStatus.INTERRUPTED) {
|
|
188
187
|
this.interrupted({
|
|
189
188
|
execResult: execResult,
|
|
190
|
-
|
|
189
|
+
actionParam: actionParam,
|
|
191
190
|
});
|
|
192
|
-
this.
|
|
193
|
-
executionId:
|
|
194
|
-
nodeId:
|
|
195
|
-
|
|
191
|
+
this.saveActionResult({
|
|
192
|
+
executionId: actionParam.executionId,
|
|
193
|
+
nodeId: actionParam.nodeId,
|
|
194
|
+
actionId: actionParam.actionId,
|
|
196
195
|
nodeType: execResult.nodeType,
|
|
197
196
|
properties: execResult.properties,
|
|
198
197
|
outgoing: [],
|
|
@@ -201,7 +200,7 @@ var Scheduler = /** @class */ (function (_super) {
|
|
|
201
200
|
detail: execResult.detail,
|
|
202
201
|
},
|
|
203
202
|
});
|
|
204
|
-
this.
|
|
203
|
+
this.removeActionFromRunningMap(actionParam);
|
|
205
204
|
}
|
|
206
205
|
return [2 /*return*/];
|
|
207
206
|
}
|
|
@@ -209,12 +208,12 @@ var Scheduler = /** @class */ (function (_super) {
|
|
|
209
208
|
});
|
|
210
209
|
};
|
|
211
210
|
Scheduler.prototype.interrupted = function (_a) {
|
|
212
|
-
var execResult = _a.execResult,
|
|
211
|
+
var execResult = _a.execResult, actionParam = _a.actionParam;
|
|
213
212
|
this.emit(constant_1.EVENT_INSTANCE_INTERRUPTED, {
|
|
214
|
-
executionId:
|
|
213
|
+
executionId: actionParam.executionId,
|
|
215
214
|
status: constant_1.FlowStatus.INTERRUPTED,
|
|
216
|
-
nodeId:
|
|
217
|
-
|
|
215
|
+
nodeId: actionParam.nodeId,
|
|
216
|
+
actionId: actionParam.actionId,
|
|
218
217
|
detail: execResult.detail,
|
|
219
218
|
});
|
|
220
219
|
};
|
|
@@ -222,24 +221,24 @@ var Scheduler = /** @class */ (function (_super) {
|
|
|
222
221
|
var _this = this;
|
|
223
222
|
if (data.outgoing && data.outgoing.length > 0) {
|
|
224
223
|
data.outgoing.forEach(function (item) {
|
|
225
|
-
_this.
|
|
224
|
+
_this.addAction({
|
|
226
225
|
executionId: data.executionId,
|
|
227
226
|
nodeId: item.target,
|
|
228
227
|
});
|
|
229
228
|
});
|
|
230
229
|
}
|
|
231
|
-
this.
|
|
232
|
-
this.
|
|
230
|
+
this.saveActionResult(data);
|
|
231
|
+
this.removeActionFromRunningMap(data);
|
|
233
232
|
this.run({
|
|
234
233
|
executionId: data.executionId,
|
|
235
234
|
nodeId: data.nodeId,
|
|
236
|
-
|
|
235
|
+
actionId: data.actionId,
|
|
237
236
|
});
|
|
238
237
|
};
|
|
239
|
-
Scheduler.prototype.
|
|
240
|
-
this.recorder.
|
|
238
|
+
Scheduler.prototype.saveActionResult = function (data) {
|
|
239
|
+
this.recorder.addActionRecord({
|
|
241
240
|
executionId: data.executionId,
|
|
242
|
-
|
|
241
|
+
actionId: data.actionId,
|
|
243
242
|
nodeId: data.nodeId,
|
|
244
243
|
nodeType: data.nodeType,
|
|
245
244
|
timestamp: Date.now(),
|
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 = {}; }
|
package/cjs/index.js
CHANGED
|
@@ -54,11 +54,12 @@ exports.StartNode = StartNode_1.default;
|
|
|
54
54
|
var TaskNode_1 = require("./nodes/TaskNode");
|
|
55
55
|
exports.TaskNode = TaskNode_1.default;
|
|
56
56
|
var recorder_1 = require("./recorder");
|
|
57
|
+
var ID_1 = require("./util/ID");
|
|
57
58
|
var Engine = /** @class */ (function () {
|
|
58
|
-
function Engine() {
|
|
59
|
+
function Engine(options) {
|
|
59
60
|
this.nodeModelMap = new Map();
|
|
61
|
+
this.id = ID_1.createEngineId();
|
|
60
62
|
this.recorder = new recorder_1.default();
|
|
61
|
-
// register node
|
|
62
63
|
this.register({
|
|
63
64
|
type: StartNode_1.default.nodeTypeName,
|
|
64
65
|
model: StartNode_1.default,
|
|
@@ -67,10 +68,11 @@ var Engine = /** @class */ (function () {
|
|
|
67
68
|
type: TaskNode_1.default.nodeTypeName,
|
|
68
69
|
model: TaskNode_1.default,
|
|
69
70
|
});
|
|
71
|
+
this.context = (options === null || options === void 0 ? void 0 : options.context) || {};
|
|
70
72
|
}
|
|
71
73
|
/**
|
|
72
74
|
* 注册节点
|
|
73
|
-
* @param nodeConfig { type: 'custom-node', model:
|
|
75
|
+
* @param nodeConfig { type: 'custom-node', model: NodeClass }
|
|
74
76
|
*/
|
|
75
77
|
Engine.prototype.register = function (nodeConfig) {
|
|
76
78
|
this.nodeModelMap.set(nodeConfig.type, nodeConfig.model);
|
|
@@ -80,8 +82,8 @@ var Engine = /** @class */ (function () {
|
|
|
80
82
|
* 注意:由于执行记录不会主动删除,所以需要自行清理。
|
|
81
83
|
* nodejs环境建议自定义为持久化存储。
|
|
82
84
|
* engine.setCustomRecorder({
|
|
83
|
-
* async
|
|
84
|
-
* async getTask(
|
|
85
|
+
* async addActionRecord(task) {}
|
|
86
|
+
* async getTask(actionId) {}
|
|
85
87
|
* async getExecutionTasks(executionId) {}
|
|
86
88
|
* clear() {}
|
|
87
89
|
* });
|
|
@@ -93,11 +95,11 @@ var Engine = /** @class */ (function () {
|
|
|
93
95
|
* 加载流程图数据
|
|
94
96
|
*/
|
|
95
97
|
Engine.prototype.load = function (_a) {
|
|
96
|
-
var graphData = _a.graphData, _b = _a.startNodeType, startNodeType = _b === void 0 ? 'StartNode' : _b, _c = _a.globalData, globalData = _c === void 0 ? {} : _c
|
|
98
|
+
var graphData = _a.graphData, _b = _a.startNodeType, startNodeType = _b === void 0 ? 'StartNode' : _b, _c = _a.globalData, globalData = _c === void 0 ? {} : _c;
|
|
97
99
|
this.flowModel = new FlowModel_1.default({
|
|
98
100
|
nodeModelMap: this.nodeModelMap,
|
|
99
101
|
recorder: this.recorder,
|
|
100
|
-
context: context,
|
|
102
|
+
context: this.context,
|
|
101
103
|
globalData: globalData,
|
|
102
104
|
startNodeType: startNodeType,
|
|
103
105
|
});
|
|
@@ -124,6 +126,12 @@ var Engine = /** @class */ (function () {
|
|
|
124
126
|
});
|
|
125
127
|
});
|
|
126
128
|
};
|
|
129
|
+
/**
|
|
130
|
+
* 恢复执行
|
|
131
|
+
* 注意此方法只能恢复节点后面的执行,不能恢复流程其他分支的执行。
|
|
132
|
+
* 同理,中断执行也只能中断节点后面的执行,不会中断其他分支的执行。
|
|
133
|
+
* 在实际项目中,如果存在中断节点,建议流程所有的节点都是排他网关,这样可以保证执行的过程不存在分支。
|
|
134
|
+
*/
|
|
127
135
|
Engine.prototype.resume = function (resumeParam) {
|
|
128
136
|
return __awaiter(this, void 0, void 0, function () {
|
|
129
137
|
var _this = this;
|
|
@@ -143,18 +151,35 @@ var Engine = /** @class */ (function () {
|
|
|
143
151
|
var tasks, records, i;
|
|
144
152
|
return __generator(this, function (_a) {
|
|
145
153
|
switch (_a.label) {
|
|
146
|
-
case 0: return [4 /*yield*/, this.recorder.
|
|
154
|
+
case 0: return [4 /*yield*/, this.recorder.getExecutionActions(executionId)];
|
|
147
155
|
case 1:
|
|
148
156
|
tasks = _a.sent();
|
|
157
|
+
if (!tasks) {
|
|
158
|
+
return [2 /*return*/, null];
|
|
159
|
+
}
|
|
149
160
|
records = [];
|
|
150
161
|
for (i = 0; i < tasks.length; i++) {
|
|
151
|
-
records.push(this.recorder.
|
|
162
|
+
records.push(this.recorder.getActionRecord(tasks[i]));
|
|
152
163
|
}
|
|
153
164
|
return [2 /*return*/, Promise.all(records)];
|
|
154
165
|
}
|
|
155
166
|
});
|
|
156
167
|
});
|
|
157
168
|
};
|
|
169
|
+
Engine.prototype.getGlobalData = function () {
|
|
170
|
+
var _a;
|
|
171
|
+
return (_a = this.flowModel) === null || _a === void 0 ? void 0 : _a.globalData;
|
|
172
|
+
};
|
|
173
|
+
Engine.prototype.setGlobalData = function (data) {
|
|
174
|
+
if (this.flowModel) {
|
|
175
|
+
this.flowModel.globalData = data;
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
Engine.prototype.updateGlobalData = function (data) {
|
|
179
|
+
if (this.flowModel) {
|
|
180
|
+
Object.assign(this.flowModel.globalData, data);
|
|
181
|
+
}
|
|
182
|
+
};
|
|
158
183
|
return Engine;
|
|
159
184
|
}());
|
|
160
185
|
exports.Engine = Engine;
|
package/cjs/nodes/BaseNode.js
CHANGED
|
@@ -67,13 +67,13 @@ var BaseNode = /** @class */ (function () {
|
|
|
67
67
|
this.incoming = nodeConfig.incoming;
|
|
68
68
|
this.nodeId = nodeConfig.id;
|
|
69
69
|
this.type = nodeConfig.type;
|
|
70
|
-
this.properties = nodeConfig.properties;
|
|
70
|
+
this.properties = nodeConfig.properties || {};
|
|
71
71
|
this.context = context;
|
|
72
72
|
this.globalData = globalData;
|
|
73
73
|
this.baseType = 'base';
|
|
74
74
|
}
|
|
75
75
|
/**
|
|
76
|
-
* 节点的每一次执行都会生成一个唯一的
|
|
76
|
+
* 节点的每一次执行都会生成一个唯一的actionId
|
|
77
77
|
*/
|
|
78
78
|
BaseNode.prototype.execute = function (params) {
|
|
79
79
|
return __awaiter(this, void 0, void 0, function () {
|
|
@@ -82,18 +82,18 @@ var BaseNode = /** @class */ (function () {
|
|
|
82
82
|
switch (_a.label) {
|
|
83
83
|
case 0: return [4 /*yield*/, this.action({
|
|
84
84
|
executionId: params.executionId,
|
|
85
|
-
|
|
85
|
+
actionId: params.actionId,
|
|
86
86
|
nodeId: this.nodeId,
|
|
87
87
|
})];
|
|
88
88
|
case 1:
|
|
89
89
|
r = _a.sent();
|
|
90
|
-
if (!(!r || r.status === constant_1.
|
|
90
|
+
if (!(!r || r.status === constant_1.ActionStatus.SUCCESS)) return [3 /*break*/, 3];
|
|
91
91
|
return [4 /*yield*/, this.getOutgoing()];
|
|
92
92
|
case 2:
|
|
93
93
|
outgoing = _a.sent();
|
|
94
94
|
params.next({
|
|
95
95
|
executionId: params.executionId,
|
|
96
|
-
|
|
96
|
+
actionId: params.actionId,
|
|
97
97
|
nodeId: this.nodeId,
|
|
98
98
|
nodeType: this.type,
|
|
99
99
|
properties: this.properties,
|
|
@@ -104,7 +104,7 @@ var BaseNode = /** @class */ (function () {
|
|
|
104
104
|
status: r && r.status,
|
|
105
105
|
detail: r && r.detail,
|
|
106
106
|
executionId: params.executionId,
|
|
107
|
-
|
|
107
|
+
actionId: params.actionId,
|
|
108
108
|
nodeId: this.nodeId,
|
|
109
109
|
nodeType: this.type,
|
|
110
110
|
properties: this.properties,
|
|
@@ -128,14 +128,14 @@ var BaseNode = /** @class */ (function () {
|
|
|
128
128
|
return [4 /*yield*/, this.onResume({
|
|
129
129
|
executionId: params.executionId,
|
|
130
130
|
nodeId: params.nodeId,
|
|
131
|
-
|
|
131
|
+
actionId: params.actionId,
|
|
132
132
|
data: params.data,
|
|
133
133
|
})];
|
|
134
134
|
case 2:
|
|
135
135
|
_a.sent();
|
|
136
136
|
params.next({
|
|
137
137
|
executionId: params.executionId,
|
|
138
|
-
|
|
138
|
+
actionId: params.actionId,
|
|
139
139
|
nodeId: this.nodeId,
|
|
140
140
|
nodeType: this.type,
|
|
141
141
|
properties: this.properties,
|
|
@@ -213,7 +213,7 @@ var BaseNode = /** @class */ (function () {
|
|
|
213
213
|
* 节点的执行逻辑
|
|
214
214
|
* @overridable 可以自定义节点重写此方法。
|
|
215
215
|
* @param params.executionId 流程执行记录ID
|
|
216
|
-
* @param params.
|
|
216
|
+
* @param params.actionId 此节点执行记录ID
|
|
217
217
|
* @param params.nodeId 节点ID
|
|
218
218
|
*/
|
|
219
219
|
BaseNode.prototype.action = function (params) {
|
|
@@ -227,7 +227,7 @@ var BaseNode = /** @class */ (function () {
|
|
|
227
227
|
* 节点的重新恢复执行逻辑
|
|
228
228
|
* @overridable 可以自定义节点重写此方法。
|
|
229
229
|
* @param params.executionId 流程执行记录ID
|
|
230
|
-
* @param params.
|
|
230
|
+
* @param params.actionId 此节点执行记录ID
|
|
231
231
|
* @param params.nodeId 节点ID
|
|
232
232
|
*/
|
|
233
233
|
BaseNode.prototype.onResume = function (params) {
|