@logicflow/engine 0.0.11-beta.0 → 0.0.12
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/README.md +5 -2
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/es/EventEmitter.d.ts +34 -4
- package/es/EventEmitter.js +70 -48
- package/es/EventEmitter.js.map +1 -0
- package/es/FlowModel.d.ts +75 -73
- package/es/FlowModel.js +130 -173
- package/es/FlowModel.js.map +1 -0
- package/es/Scheduler.d.ts +50 -34
- package/es/Scheduler.js +134 -209
- package/es/Scheduler.js.map +1 -0
- package/es/constant/{constant.js → index.js} +8 -7
- package/es/constant/index.js.map +1 -0
- package/es/constant/logCode.js +29 -0
- package/es/constant/logCode.js.map +1 -0
- package/es/index.d.ts +135 -38
- package/es/index.js +92 -144
- package/es/index.js.map +1 -0
- package/es/nodes/base.d.ts +108 -0
- package/es/nodes/base.js +151 -0
- package/es/nodes/base.js.map +1 -0
- package/es/nodes/index.d.ts +3 -0
- package/es/nodes/index.js +4 -0
- package/es/nodes/index.js.map +1 -0
- package/es/nodes/{StartNode.d.ts → start.d.ts} +3 -2
- package/es/nodes/start.js +11 -0
- package/es/nodes/start.js.map +1 -0
- package/es/nodes/{TaskNode.d.ts → task.d.ts} +3 -2
- package/es/nodes/task.js +11 -0
- package/es/nodes/task.js.map +1 -0
- package/es/platform/browser/browserVm.d.ts +1 -0
- package/es/platform/browser/browserVm.js +66 -0
- package/es/platform/browser/browserVm.js.map +1 -0
- package/es/platform/browser/index.d.ts +4 -0
- package/es/platform/browser/index.js +23 -0
- package/es/platform/browser/index.js.map +1 -0
- package/es/platform/index.d.ts +1 -0
- package/es/platform/index.js +2 -0
- package/es/platform/index.js.map +1 -0
- package/es/platform/node/index.d.ts +4 -0
- package/es/platform/node/index.js +23 -0
- package/es/platform/node/index.js.map +1 -0
- package/es/platform/node/nodeVm.d.ts +1 -0
- package/es/platform/node/nodeVm.js +10 -0
- package/es/platform/node/nodeVm.js.map +1 -0
- package/es/recorder/index.d.ts +36 -10
- package/es/recorder/index.js +82 -135
- package/es/recorder/index.js.map +1 -0
- package/es/utils/global.d.ts +5 -0
- package/es/utils/global.js +27 -0
- package/es/utils/global.js.map +1 -0
- package/es/utils/id.js +14 -0
- package/es/utils/id.js.map +1 -0
- package/es/utils/index.d.ts +4 -0
- package/es/utils/index.js +5 -0
- package/es/utils/index.js.map +1 -0
- package/es/{util → utils}/storage.js +17 -16
- package/es/utils/storage.js.map +1 -0
- package/lib/EventEmitter.d.ts +37 -0
- package/lib/EventEmitter.js +94 -0
- package/lib/EventEmitter.js.map +1 -0
- package/lib/FlowModel.d.ts +146 -0
- package/lib/FlowModel.js +236 -0
- package/lib/FlowModel.js.map +1 -0
- package/lib/Scheduler.d.ts +78 -0
- package/lib/Scheduler.js +179 -0
- package/lib/Scheduler.js.map +1 -0
- package/lib/constant/index.d.ts +16 -0
- package/{cjs/constant/constant.js → lib/constant/index.js} +4 -3
- package/lib/constant/index.js.map +1 -0
- package/lib/constant/logCode.d.ts +12 -0
- package/{cjs/constant/LogCode.js → lib/constant/logCode.js} +16 -13
- package/lib/constant/logCode.js.map +1 -0
- package/lib/index.d.ts +157 -0
- package/lib/index.js +159 -0
- package/lib/index.js.map +1 -0
- package/lib/nodes/base.d.ts +108 -0
- package/lib/nodes/base.js +154 -0
- package/lib/nodes/base.js.map +1 -0
- package/lib/nodes/index.d.ts +3 -0
- package/lib/nodes/index.js +7 -0
- package/lib/nodes/index.js.map +1 -0
- package/lib/nodes/start.d.ts +6 -0
- package/lib/nodes/start.js +15 -0
- package/lib/nodes/start.js.map +1 -0
- package/lib/nodes/task.d.ts +6 -0
- package/lib/nodes/task.js +15 -0
- package/lib/nodes/task.js.map +1 -0
- package/lib/platform/browser/browserVm.d.ts +1 -0
- package/lib/platform/browser/browserVm.js +70 -0
- package/lib/platform/browser/browserVm.js.map +1 -0
- package/lib/platform/browser/index.d.ts +4 -0
- package/lib/platform/browser/index.js +28 -0
- package/lib/platform/browser/index.js.map +1 -0
- package/lib/platform/index.d.ts +1 -0
- package/lib/platform/index.js +5 -0
- package/lib/platform/index.js.map +1 -0
- package/lib/platform/node/index.d.ts +4 -0
- package/lib/platform/node/index.js +28 -0
- package/lib/platform/node/index.js.map +1 -0
- package/lib/platform/node/nodeVm.d.ts +1 -0
- package/lib/platform/node/nodeVm.js +14 -0
- package/lib/platform/node/nodeVm.js.map +1 -0
- package/lib/recorder/index.d.ts +46 -0
- package/lib/recorder/index.js +117 -0
- package/lib/recorder/index.js.map +1 -0
- package/lib/utils/global.d.ts +5 -0
- package/lib/utils/global.js +31 -0
- package/lib/utils/global.js.map +1 -0
- package/lib/utils/id.d.ts +3 -0
- package/lib/utils/id.js +20 -0
- package/lib/utils/id.js.map +1 -0
- package/lib/utils/index.d.ts +4 -0
- package/lib/utils/index.js +9 -0
- package/lib/utils/index.js.map +1 -0
- package/lib/utils/storage.d.ts +7 -0
- package/{cjs/util → lib/utils}/storage.js +18 -17
- package/lib/utils/storage.js.map +1 -0
- package/package.json +30 -71
- package/src/EventEmitter.ts +103 -0
- package/src/FlowModel.ts +325 -0
- package/src/Scheduler.ts +244 -0
- package/src/constant/index.ts +23 -0
- package/src/constant/logCode.ts +34 -0
- package/src/index.ts +300 -0
- package/src/nodes/base.ts +236 -0
- package/src/nodes/index.ts +3 -0
- package/src/nodes/start.ts +8 -0
- package/src/nodes/task.ts +8 -0
- package/src/platform/browser/browserVm.ts +68 -0
- package/src/platform/browser/index.ts +28 -0
- package/src/platform/index.ts +1 -0
- package/src/platform/node/index.ts +28 -0
- package/src/platform/node/nodeVm.ts +14 -0
- package/src/recorder/index.ts +137 -0
- package/src/typings.d.ts +0 -0
- package/src/utils/global.ts +41 -0
- package/src/utils/id.ts +16 -0
- package/src/utils/index.ts +5 -0
- package/src/utils/storage.ts +55 -0
- package/cjs/EventEmitter.js +0 -70
- package/cjs/FlowModel.js +0 -277
- package/cjs/Scheduler.js +0 -252
- package/cjs/expression/browserVm.js +0 -81
- package/cjs/expression/index.js +0 -57
- package/cjs/index.js +0 -210
- package/cjs/nodes/BaseNode.js +0 -252
- package/cjs/nodes/StartNode.js +0 -27
- package/cjs/nodes/TaskNode.js +0 -27
- package/cjs/recorder/index.js +0 -168
- package/cjs/util/ID.js +0 -16
- package/cjs/util/global.js +0 -32
- package/es/constant/LogCode.js +0 -28
- package/es/expression/browserVm.d.ts +0 -4
- package/es/expression/browserVm.js +0 -76
- package/es/expression/index.d.ts +0 -2
- package/es/expression/index.js +0 -54
- package/es/nodes/BaseNode.d.ts +0 -110
- package/es/nodes/BaseNode.js +0 -250
- package/es/nodes/StartNode.js +0 -25
- package/es/nodes/TaskNode.js +0 -25
- package/es/util/ID.js +0 -13
- package/es/util/global.d.ts +0 -5
- package/es/util/global.js +0 -26
- package/lib/main.js +0 -1
- /package/es/constant/{constant.d.ts → index.d.ts} +0 -0
- /package/es/constant/{LogCode.d.ts → logCode.d.ts} +0 -0
- /package/es/{util/ID.d.ts → utils/id.d.ts} +0 -0
- /package/es/{util → utils}/storage.d.ts +0 -0
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { Engine } from '..'
|
|
2
|
+
import { storage } from '../utils'
|
|
3
|
+
|
|
4
|
+
export const MAX_RECORDER = 100
|
|
5
|
+
export const MAX_INSTANCE = 100
|
|
6
|
+
export const LOGICFLOW_ENGINE_INSTANCES = 'LOGICFLOW_ENGINE_INSTANCES'
|
|
7
|
+
|
|
8
|
+
export class Recorder implements Recorder.Base {
|
|
9
|
+
instanceId: Engine.Key
|
|
10
|
+
maxRecorder: number
|
|
11
|
+
|
|
12
|
+
constructor({ instanceId }) {
|
|
13
|
+
this.instanceId = instanceId
|
|
14
|
+
this.maxRecorder = MAX_RECORDER
|
|
15
|
+
|
|
16
|
+
const instances = this.getItem(LOGICFLOW_ENGINE_INSTANCES) || []
|
|
17
|
+
if (instances.indexOf(instanceId) === -1) {
|
|
18
|
+
instances.push(instanceId)
|
|
19
|
+
}
|
|
20
|
+
if (instances.length > MAX_INSTANCE) {
|
|
21
|
+
const clearInstance = instances.shift()
|
|
22
|
+
this.clearInstance(clearInstance)
|
|
23
|
+
}
|
|
24
|
+
this.setItem(LOGICFLOW_ENGINE_INSTANCES, instances)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
setMaxRecorderNumber(max: number) {
|
|
28
|
+
this.maxRecorder = max
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// 将存储 storage 的方法收敛到此处,并在此处做异常处理 - setItem
|
|
32
|
+
setItem(key: string | number, value: unknown) {
|
|
33
|
+
try {
|
|
34
|
+
storage.setItem(key, value)
|
|
35
|
+
} catch (error) {
|
|
36
|
+
console.error('Ops, something wrong with storage.setItem !!!')
|
|
37
|
+
storage.clear()
|
|
38
|
+
storage.setItem(key, value)
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// getItem 方法
|
|
43
|
+
getItem(key: string | number) {
|
|
44
|
+
return storage.getItem(key)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async getExecutionActions(executionId: Engine.Key) {
|
|
48
|
+
return this.getItem(executionId)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
async getExecutionList() {
|
|
52
|
+
return this.getItem(this.instanceId) || []
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
private addExecution(executionId: Engine.Key) {
|
|
56
|
+
const instanceExecutions = this.getItem(this.instanceId) || []
|
|
57
|
+
if (instanceExecutions.length >= this.maxRecorder) {
|
|
58
|
+
const toBeRemovedItem = instanceExecutions.shift()
|
|
59
|
+
this.popExecution(toBeRemovedItem)
|
|
60
|
+
}
|
|
61
|
+
instanceExecutions.push(executionId)
|
|
62
|
+
this.setItem(this.instanceId, instanceExecutions)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
private popExecution(executionId: Engine.Key) {
|
|
66
|
+
const instanceData = this.getItem(executionId) || []
|
|
67
|
+
instanceData.forEach((actionId) => {
|
|
68
|
+
storage.removeItem(actionId)
|
|
69
|
+
})
|
|
70
|
+
storage.removeItem(executionId)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
private pushActionToExecution(executionId: Engine.Key, actionId: Engine.Key) {
|
|
74
|
+
const actions = this.getItem(executionId) || []
|
|
75
|
+
actions.push(actionId)
|
|
76
|
+
this.setItem(executionId, actions)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* @param {Object} action
|
|
81
|
+
* {
|
|
82
|
+
* actionId: '',
|
|
83
|
+
* nodeId: '',
|
|
84
|
+
* executionId: '',
|
|
85
|
+
* nodeType: '',
|
|
86
|
+
* timestamp: '',
|
|
87
|
+
* properties: {},
|
|
88
|
+
* }
|
|
89
|
+
*/
|
|
90
|
+
async addActionRecord(action: Recorder.Info) {
|
|
91
|
+
const { executionId, actionId } = action
|
|
92
|
+
const instanceData = await this.getExecutionActions(executionId)
|
|
93
|
+
|
|
94
|
+
if (!instanceData) {
|
|
95
|
+
this.addExecution(executionId)
|
|
96
|
+
}
|
|
97
|
+
this.pushActionToExecution(executionId, actionId)
|
|
98
|
+
this.setItem(actionId, action)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
async getActionRecord(actionId: Engine.Key): Promise<Recorder.Info> {
|
|
102
|
+
return this.getItem(actionId)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
clear() {
|
|
106
|
+
this.clearInstance(this.instanceId)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
clearInstance(instanceId: Engine.Key) {
|
|
110
|
+
const instanceExecutions = this.getItem(instanceId) || []
|
|
111
|
+
// TODO: 完善类型定义
|
|
112
|
+
instanceExecutions.forEach((executionId) => {
|
|
113
|
+
storage.removeItem(executionId)
|
|
114
|
+
const instanceData = this.getItem(executionId) || []
|
|
115
|
+
instanceData.forEach((actionId) => {
|
|
116
|
+
storage.removeItem(actionId)
|
|
117
|
+
})
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
storage.removeItem(instanceId)
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export namespace Recorder {
|
|
125
|
+
export interface Base {
|
|
126
|
+
addActionRecord: (action: Info) => Promise<void>
|
|
127
|
+
getActionRecord: (actionId: Engine.Key) => Promise<Info>
|
|
128
|
+
getExecutionActions: (executionId: Engine.Key) => Promise<string[]>
|
|
129
|
+
clear: () => void
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export type Info = {
|
|
133
|
+
timestamp: number
|
|
134
|
+
} & Engine.NextActionParam
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export default Recorder
|
package/src/typings.d.ts
ADDED
|
File without changes
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// 判断当前环境是否为服务端
|
|
2
|
+
// const isServer = typeof window === undefined;
|
|
3
|
+
|
|
4
|
+
// const isServer = process.env.BROWSER === true;
|
|
5
|
+
|
|
6
|
+
const isInBrowser = typeof window === 'object' && window.window === window
|
|
7
|
+
|
|
8
|
+
const isInNodeJS = typeof global === 'object' && global.global === global
|
|
9
|
+
|
|
10
|
+
const isInWebWorker =
|
|
11
|
+
!isInBrowser && typeof self === 'object' && self.constructor
|
|
12
|
+
|
|
13
|
+
const globalScope: any = (() => {
|
|
14
|
+
if (isInBrowser) {
|
|
15
|
+
return window
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (typeof self === 'object' && self.self === self) {
|
|
19
|
+
return self
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (isInNodeJS) {
|
|
23
|
+
return global
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (typeof globalThis === 'object') {
|
|
27
|
+
return globalThis
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return {
|
|
31
|
+
eval: () => undefined,
|
|
32
|
+
} as Record<string, unknown>
|
|
33
|
+
})()
|
|
34
|
+
|
|
35
|
+
export {
|
|
36
|
+
// 环境相关方法
|
|
37
|
+
globalScope,
|
|
38
|
+
isInWebWorker,
|
|
39
|
+
isInBrowser,
|
|
40
|
+
isInNodeJS,
|
|
41
|
+
}
|
package/src/utils/id.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { v4 as uuidV4 } from 'uuid'
|
|
2
|
+
|
|
3
|
+
export const createExecId = (): string => {
|
|
4
|
+
const uuid = uuidV4()
|
|
5
|
+
return `exec-${uuid}`
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export const createActionId = (): string => {
|
|
9
|
+
const uuid = uuidV4()
|
|
10
|
+
return `action-${uuid}`
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const createEngineId = (): string => {
|
|
14
|
+
const uuid = uuidV4()
|
|
15
|
+
return `engine-${uuid}`
|
|
16
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 存储执行记录
|
|
3
|
+
*/
|
|
4
|
+
import { globalScope } from './global'
|
|
5
|
+
|
|
6
|
+
if (!globalScope.sessionStorage) {
|
|
7
|
+
const storage = {
|
|
8
|
+
data: {} as Record<string, unknown>,
|
|
9
|
+
|
|
10
|
+
setItem(key, value) {
|
|
11
|
+
storage.data[key] = value
|
|
12
|
+
},
|
|
13
|
+
|
|
14
|
+
getItem(key) {
|
|
15
|
+
return storage.data[key]
|
|
16
|
+
},
|
|
17
|
+
|
|
18
|
+
removeItem(key) {
|
|
19
|
+
delete storage.data[key]
|
|
20
|
+
},
|
|
21
|
+
|
|
22
|
+
clear() {
|
|
23
|
+
storage.data = {}
|
|
24
|
+
},
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
globalScope.sessionStorage = storage
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export default {
|
|
31
|
+
setItem(key, value) {
|
|
32
|
+
if (typeof value === 'object') {
|
|
33
|
+
value = JSON.stringify(value)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
globalScope.sessionStorage.setItem(key, value)
|
|
37
|
+
},
|
|
38
|
+
|
|
39
|
+
getItem(key) {
|
|
40
|
+
const value = globalScope.sessionStorage.getItem(key)
|
|
41
|
+
try {
|
|
42
|
+
return JSON.parse(value)
|
|
43
|
+
} catch (error) {
|
|
44
|
+
return value
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
|
|
48
|
+
removeItem(key) {
|
|
49
|
+
globalScope.sessionStorage.removeItem(key)
|
|
50
|
+
},
|
|
51
|
+
|
|
52
|
+
clear() {
|
|
53
|
+
globalScope.sessionStorage.clear()
|
|
54
|
+
},
|
|
55
|
+
}
|
package/cjs/EventEmitter.js
DELETED
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
var EventEmitter = /** @class */ (function () {
|
|
4
|
-
function EventEmitter() {
|
|
5
|
-
this._events = {};
|
|
6
|
-
}
|
|
7
|
-
EventEmitter.prototype.on = function (evKey, callback, once) {
|
|
8
|
-
if (once === void 0) { once = false; }
|
|
9
|
-
evKey = evKey.trim();
|
|
10
|
-
if (!this._events[evKey]) {
|
|
11
|
-
this._events[evKey] = [];
|
|
12
|
-
}
|
|
13
|
-
this._events[evKey].push({
|
|
14
|
-
callback: callback,
|
|
15
|
-
once: !!once,
|
|
16
|
-
});
|
|
17
|
-
};
|
|
18
|
-
EventEmitter.prototype.emit = function (evt, eventArgs) {
|
|
19
|
-
var _this = this;
|
|
20
|
-
var events = this._events[evt] || [];
|
|
21
|
-
// 实际的处理 emit 方法
|
|
22
|
-
var doEmit = function (es) {
|
|
23
|
-
var length = es.length;
|
|
24
|
-
for (var i = 0; i < length; i++) {
|
|
25
|
-
if (!es[i]) {
|
|
26
|
-
// eslint-disable-next-line no-continue
|
|
27
|
-
continue;
|
|
28
|
-
}
|
|
29
|
-
var _a = es[i], callback = _a.callback, once = _a.once;
|
|
30
|
-
if (once) {
|
|
31
|
-
es.splice(i, 1);
|
|
32
|
-
if (es.length === 0) {
|
|
33
|
-
delete _this._events[evt];
|
|
34
|
-
}
|
|
35
|
-
length--;
|
|
36
|
-
i--;
|
|
37
|
-
}
|
|
38
|
-
callback.apply(_this, [eventArgs]);
|
|
39
|
-
}
|
|
40
|
-
};
|
|
41
|
-
doEmit(events);
|
|
42
|
-
};
|
|
43
|
-
EventEmitter.prototype.off = function (evt, callback) {
|
|
44
|
-
if (!evt) {
|
|
45
|
-
// evt 为空全部清除
|
|
46
|
-
this._events = {};
|
|
47
|
-
}
|
|
48
|
-
if (!callback) {
|
|
49
|
-
// evt 存在,callback 为空,清除事件所有方法
|
|
50
|
-
delete this._events[evt];
|
|
51
|
-
}
|
|
52
|
-
else {
|
|
53
|
-
// evt 存在,callback 存在,清除匹配的
|
|
54
|
-
var events = this._events[evt] || [];
|
|
55
|
-
var length_1 = events.length;
|
|
56
|
-
for (var i = 0; i < length_1; i++) {
|
|
57
|
-
if (events[i].callback === callback) {
|
|
58
|
-
events.splice(i, 1);
|
|
59
|
-
length_1--;
|
|
60
|
-
i--;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
if (events.length === 0) {
|
|
64
|
-
delete this._events[evt];
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
};
|
|
68
|
-
return EventEmitter;
|
|
69
|
-
}());
|
|
70
|
-
exports.default = EventEmitter;
|
package/cjs/FlowModel.js
DELETED
|
@@ -1,277 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __assign = (this && this.__assign) || function () {
|
|
3
|
-
__assign = Object.assign || function(t) {
|
|
4
|
-
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
-
s = arguments[i];
|
|
6
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
-
t[p] = s[p];
|
|
8
|
-
}
|
|
9
|
-
return t;
|
|
10
|
-
};
|
|
11
|
-
return __assign.apply(this, arguments);
|
|
12
|
-
};
|
|
13
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
14
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
15
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
16
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
17
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
18
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
19
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
20
|
-
});
|
|
21
|
-
};
|
|
22
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
23
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
24
|
-
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
25
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
26
|
-
function step(op) {
|
|
27
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
28
|
-
while (_) try {
|
|
29
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
30
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
31
|
-
switch (op[0]) {
|
|
32
|
-
case 0: case 1: t = op; break;
|
|
33
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
34
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
35
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
36
|
-
default:
|
|
37
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
38
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
39
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
40
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
41
|
-
if (t[2]) _.ops.pop();
|
|
42
|
-
_.trys.pop(); continue;
|
|
43
|
-
}
|
|
44
|
-
op = body.call(thisArg, _);
|
|
45
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
46
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
50
|
-
var constant_1 = require("./constant/constant");
|
|
51
|
-
var ID_1 = require("./util/ID");
|
|
52
|
-
var Scheduler_1 = require("./Scheduler");
|
|
53
|
-
var LogCode_1 = require("./constant/LogCode");
|
|
54
|
-
var FlowModel = /** @class */ (function () {
|
|
55
|
-
function FlowModel(_a) {
|
|
56
|
-
var _this = this;
|
|
57
|
-
var nodeModelMap = _a.nodeModelMap, recorder = _a.recorder, _b = _a.context, context = _b === void 0 ? {} : _b, _c = _a.globalData, globalData = _c === void 0 ? {} : _c, _d = _a.startNodeType, startNodeType = _d === void 0 ? 'StartNode' : _d;
|
|
58
|
-
/**
|
|
59
|
-
* 当前流程模型中的所有节点,边会被转换成节点的incoming和outgoing属性。
|
|
60
|
-
*/
|
|
61
|
-
this.nodeConfigMap = new Map();
|
|
62
|
-
/**
|
|
63
|
-
* 当前流程中开始节点组成的数组。
|
|
64
|
-
*/
|
|
65
|
-
this.startNodes = [];
|
|
66
|
-
/**
|
|
67
|
-
* 用于存储全局数据,可以在流程中共享。
|
|
68
|
-
*/
|
|
69
|
-
this.globalData = {};
|
|
70
|
-
// 流程包含的节点类型
|
|
71
|
-
this.nodeModelMap = nodeModelMap;
|
|
72
|
-
// 需要执行的队列
|
|
73
|
-
this.executeList = [];
|
|
74
|
-
// 执行中的任务
|
|
75
|
-
this.executingInstance = null;
|
|
76
|
-
// 外部传入的上下文,最终会传递给每个节点
|
|
77
|
-
this.context = context;
|
|
78
|
-
// 用于存储全局数据,可以在流程中共享。
|
|
79
|
-
this.globalData = globalData;
|
|
80
|
-
// 开始节点类型,在执行流程时,会从这些节点开始执行。
|
|
81
|
-
this.startNodeType = startNodeType;
|
|
82
|
-
this.isRunning = false;
|
|
83
|
-
this.scheduler = new Scheduler_1.default({
|
|
84
|
-
flowModel: this,
|
|
85
|
-
recorder: recorder,
|
|
86
|
-
});
|
|
87
|
-
this.scheduler.on(constant_1.EVENT_INSTANCE_COMPLETE, function (result) {
|
|
88
|
-
_this.onExecuteFinished(result);
|
|
89
|
-
});
|
|
90
|
-
this.scheduler.on(constant_1.EVENT_INSTANCE_INTERRUPTED, function (result) {
|
|
91
|
-
_this.onExecuteFinished(result);
|
|
92
|
-
});
|
|
93
|
-
this.scheduler.on(constant_1.EVENT_INSTANCE_ERROR, function (result) {
|
|
94
|
-
_this.onExecuteFinished(result);
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
FlowModel.prototype.setStartNodeType = function (startNodeType) {
|
|
98
|
-
this.startNodeType = startNodeType;
|
|
99
|
-
};
|
|
100
|
-
/**
|
|
101
|
-
* 解析LogicFlow图数据,将nodes和edges转换成节点格式。
|
|
102
|
-
* 例如:
|
|
103
|
-
* graphData: {
|
|
104
|
-
* nodes: [
|
|
105
|
-
* { id: 'node1', type: 'StartNode', properties: {} },
|
|
106
|
-
* { id: 'node2', type: 'TaskNode', properties: {} },
|
|
107
|
-
* ],
|
|
108
|
-
* edges: [
|
|
109
|
-
* { id: 'edge1', sourceNodeId: 'node1', targetNodeId: 'node2', properties: {} },
|
|
110
|
-
* ]
|
|
111
|
-
* }
|
|
112
|
-
* 转换成:
|
|
113
|
-
* nodeConfigMap: {
|
|
114
|
-
* node1: {
|
|
115
|
-
* id: 'node1',
|
|
116
|
-
* type: 'StartNode',
|
|
117
|
-
* properties: {},
|
|
118
|
-
* incoming: [],
|
|
119
|
-
* outgoing: [{ id: 'edge1', properties: {}, target: 'node2' }]
|
|
120
|
-
* },
|
|
121
|
-
* node2: {
|
|
122
|
-
* id: 'node2',
|
|
123
|
-
* type: 'TaskNode',
|
|
124
|
-
* properties: {},
|
|
125
|
-
* incoming: [{ id: 'edge1', properties: {}, source: 'node1' }],
|
|
126
|
-
* outgoing: [],
|
|
127
|
-
* }
|
|
128
|
-
* }
|
|
129
|
-
* 此格式方便后续执行时,根据节点id快速找到节点和执行初始化节点模型。
|
|
130
|
-
* 同时此方法还会找到所有的开始节点,方便后续执行时,从开始节点开始执行。
|
|
131
|
-
* @param graphData 流程图数据
|
|
132
|
-
*/
|
|
133
|
-
FlowModel.prototype.load = function (graphData) {
|
|
134
|
-
var _this = this;
|
|
135
|
-
var _a = graphData.nodes, nodes = _a === void 0 ? [] : _a, _b = graphData.edges, edges = _b === void 0 ? [] : _b;
|
|
136
|
-
this.startNodes = [];
|
|
137
|
-
this.nodeConfigMap = new Map();
|
|
138
|
-
nodes.forEach(function (node) {
|
|
139
|
-
if (_this.nodeModelMap.has(node.type)) {
|
|
140
|
-
var nodeConfig = {
|
|
141
|
-
id: node.id,
|
|
142
|
-
type: node.type,
|
|
143
|
-
properties: node.properties,
|
|
144
|
-
incoming: [],
|
|
145
|
-
outgoing: [],
|
|
146
|
-
};
|
|
147
|
-
_this.nodeConfigMap.set(node.id, nodeConfig);
|
|
148
|
-
if (node.type === _this.startNodeType) {
|
|
149
|
-
_this.startNodes.push(nodeConfig);
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
else {
|
|
153
|
-
console.warn("\u672A\u8BC6\u522B\u7684\u8282\u70B9\u7C7B\u578B: " + node.type);
|
|
154
|
-
}
|
|
155
|
-
});
|
|
156
|
-
edges.forEach(function (edge) {
|
|
157
|
-
var sourceNode = _this.nodeConfigMap.get(edge.sourceNodeId);
|
|
158
|
-
var targetNode = _this.nodeConfigMap.get(edge.targetNodeId);
|
|
159
|
-
if (sourceNode) {
|
|
160
|
-
sourceNode.outgoing.push({
|
|
161
|
-
id: edge.id,
|
|
162
|
-
properties: edge.properties,
|
|
163
|
-
target: edge.targetNodeId,
|
|
164
|
-
});
|
|
165
|
-
}
|
|
166
|
-
if (targetNode && targetNode.type !== _this.startNodeType) {
|
|
167
|
-
targetNode.incoming.push({
|
|
168
|
-
id: edge.id,
|
|
169
|
-
properties: edge.properties,
|
|
170
|
-
source: edge.sourceNodeId,
|
|
171
|
-
});
|
|
172
|
-
}
|
|
173
|
-
});
|
|
174
|
-
};
|
|
175
|
-
/**
|
|
176
|
-
* 执行流程, 每次执行都会生成一个唯一的executionId,用于区分不同的执行。
|
|
177
|
-
* 同一次执行,这次执行内部的节点执行顺序为并行。内部并行是为了避免异步节点阻塞其他节点的执行。
|
|
178
|
-
* 多次执行,多次执行之间为串行,这里选择串行的原因是避免多次执行之间的数据冲突。
|
|
179
|
-
* example:
|
|
180
|
-
* 一个流程存在着两个开始节点,A和B,A和B的下一个节点都是C,C的下两个节点是D和E。
|
|
181
|
-
* 外部分别触发了A和B的执行,那么A和B的执行是串行的(也就是需要A执行完成后再执行B),但是D和E的执行是并行的。
|
|
182
|
-
* 如果希望A和B的执行是并行的,就不能使用同一个流程模型执行,应该初始化两个。
|
|
183
|
-
* TODO: 去掉此处的对列,直接使用调度器的队列。
|
|
184
|
-
*/
|
|
185
|
-
FlowModel.prototype.execute = function (params) {
|
|
186
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
187
|
-
return __generator(this, function (_a) {
|
|
188
|
-
this.createExecution(params);
|
|
189
|
-
return [2 /*return*/];
|
|
190
|
-
});
|
|
191
|
-
});
|
|
192
|
-
};
|
|
193
|
-
FlowModel.prototype.resume = function (params) {
|
|
194
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
195
|
-
return __generator(this, function (_a) {
|
|
196
|
-
this.createExecution(params);
|
|
197
|
-
return [2 /*return*/];
|
|
198
|
-
});
|
|
199
|
-
});
|
|
200
|
-
};
|
|
201
|
-
/**
|
|
202
|
-
* 创建节点实例, 每个节点实例都会有一个唯一的actionId。
|
|
203
|
-
* 通过executionId、nodeId、actionId可以唯一确定一个节点的某一次执行。
|
|
204
|
-
* @param nodeId 节点Id
|
|
205
|
-
* @returns 节点示例
|
|
206
|
-
*/
|
|
207
|
-
FlowModel.prototype.createAction = function (nodeId) {
|
|
208
|
-
var nodeConfig = this.nodeConfigMap.get(nodeId);
|
|
209
|
-
var NodeModel = this.nodeModelMap.get(nodeConfig.type);
|
|
210
|
-
var action = new NodeModel({
|
|
211
|
-
nodeConfig: nodeConfig,
|
|
212
|
-
globalData: this.globalData,
|
|
213
|
-
context: this.context,
|
|
214
|
-
});
|
|
215
|
-
return action;
|
|
216
|
-
};
|
|
217
|
-
/**
|
|
218
|
-
* 更新流程全局数据
|
|
219
|
-
*/
|
|
220
|
-
FlowModel.prototype.updateGlobalData = function (data) {
|
|
221
|
-
this.globalData = __assign(__assign({}, this.globalData), data);
|
|
222
|
-
};
|
|
223
|
-
/**
|
|
224
|
-
* 在执行完成后,通知外部此次执行完成。
|
|
225
|
-
* 如果还存在待执行的任务,那么继续执行。
|
|
226
|
-
*/
|
|
227
|
-
FlowModel.prototype.onExecuteFinished = function (result) {
|
|
228
|
-
var index = this.executeList.findIndex(function (i) { return i.executionId === result.executionId; });
|
|
229
|
-
if (index !== -1) {
|
|
230
|
-
var callback = this.executeList[index].callback;
|
|
231
|
-
this.executeList.splice(index, 1);
|
|
232
|
-
callback && callback(result);
|
|
233
|
-
}
|
|
234
|
-
};
|
|
235
|
-
/**
|
|
236
|
-
* 从待执行队列中取出需要执行的内容。
|
|
237
|
-
* 会依次判断是否有taskId、nodeId、executionId。
|
|
238
|
-
* 若存在taskId,那么表示恢复执行。
|
|
239
|
-
* 若存在nodeId,那么表示从指定节点开始执行。
|
|
240
|
-
* 若都不存在,那么新建一个executionId,从开始节点开始执行。
|
|
241
|
-
*/
|
|
242
|
-
FlowModel.prototype.createExecution = function (execParams) {
|
|
243
|
-
var _this = this;
|
|
244
|
-
this.executeList.push(execParams);
|
|
245
|
-
// 如果有taskId,那么表示恢复执行
|
|
246
|
-
if (execParams.actionId && execParams.executionId && execParams.nodeId) {
|
|
247
|
-
this.scheduler.resume({
|
|
248
|
-
executionId: execParams.executionId,
|
|
249
|
-
actionId: execParams.actionId,
|
|
250
|
-
nodeId: execParams.nodeId,
|
|
251
|
-
data: execParams.data,
|
|
252
|
-
});
|
|
253
|
-
return;
|
|
254
|
-
}
|
|
255
|
-
var executionId = ID_1.createExecId();
|
|
256
|
-
execParams.executionId = executionId;
|
|
257
|
-
if (execParams.nodeId) {
|
|
258
|
-
var nodeConfig = this.nodeConfigMap.get(execParams.nodeId);
|
|
259
|
-
if (!nodeConfig) {
|
|
260
|
-
execParams.onError(new Error(LogCode_1.getErrorMsg(LogCode_1.ErrorCode.NONE_NODE_ID) + "(" + execParams.nodeId + ")"));
|
|
261
|
-
return;
|
|
262
|
-
}
|
|
263
|
-
this.startNodes = [nodeConfig];
|
|
264
|
-
}
|
|
265
|
-
this.startNodes.forEach(function (startNode) {
|
|
266
|
-
_this.scheduler.addAction({
|
|
267
|
-
executionId: executionId,
|
|
268
|
-
nodeId: startNode.id,
|
|
269
|
-
});
|
|
270
|
-
});
|
|
271
|
-
this.scheduler.run({
|
|
272
|
-
executionId: executionId,
|
|
273
|
-
});
|
|
274
|
-
};
|
|
275
|
-
return FlowModel;
|
|
276
|
-
}());
|
|
277
|
-
exports.default = FlowModel;
|