@nocobase/plugin-workflow 0.9.1-alpha.2 → 0.9.2-alpha.2
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/lib/client/AddButton.js +17 -64
- package/lib/client/Branch.js +0 -13
- package/lib/client/ExecutionCanvas.js +16 -63
- package/lib/client/ExecutionLink.js +3 -21
- package/lib/client/ExecutionPage.js +1 -19
- package/lib/client/ExecutionResourceProvider.js +6 -23
- package/lib/client/FlowContext.js +0 -8
- package/lib/client/WorkflowCanvas.js +56 -127
- package/lib/client/WorkflowLink.js +3 -21
- package/lib/client/WorkflowPage.js +1 -19
- package/lib/client/WorkflowProvider.js +24 -47
- package/lib/client/WorkflowShortcut.js +0 -16
- package/lib/client/components/CollectionBlockInitializer.js +12 -22
- package/lib/client/components/CollectionFieldInitializers.js +5 -24
- package/lib/client/components/CollectionFieldset.js +31 -79
- package/lib/client/components/Duration.js +0 -14
- package/lib/client/components/DynamicExpression.d.ts +4 -0
- package/lib/client/components/DynamicExpression.js +102 -0
- package/lib/client/components/FieldsSelect.d.ts +2 -0
- package/lib/client/components/FieldsSelect.js +66 -0
- package/lib/client/components/FilterDynamicComponent.js +1 -10
- package/lib/client/components/NullRender.js +0 -1
- package/lib/client/components/OpenDrawer.js +10 -35
- package/lib/client/components/RadioWithTooltip.js +5 -27
- package/lib/client/components/renderEngineReference.d.ts +1 -0
- package/lib/client/components/renderEngineReference.js +55 -0
- package/lib/client/constants.js +0 -9
- package/lib/client/index.js +0 -6
- package/lib/client/interfaces/expression.d.ts +3 -0
- package/lib/client/interfaces/expression.js +37 -0
- package/lib/client/locale/index.js +5 -15
- package/lib/client/locale/pt-BR.d.ts +130 -0
- package/lib/client/locale/pt-BR.js +136 -0
- package/lib/client/locale/zh-CN.d.ts +16 -1
- package/lib/client/locale/zh-CN.js +17 -2
- package/lib/client/nodes/calculation.d.ts +54 -3
- package/lib/client/nodes/calculation.js +136 -63
- package/lib/client/nodes/condition.d.ts +1 -1
- package/lib/client/nodes/condition.js +21 -76
- package/lib/client/nodes/create.d.ts +35 -9
- package/lib/client/nodes/create.js +13 -19
- package/lib/client/nodes/delay.d.ts +1 -3
- package/lib/client/nodes/delay.js +3 -10
- package/lib/client/nodes/destroy.d.ts +1 -6
- package/lib/client/nodes/destroy.js +12 -9
- package/lib/client/nodes/index.d.ts +2 -2
- package/lib/client/nodes/index.js +45 -147
- package/lib/client/nodes/manual/AssigneesSelect.js +6 -17
- package/lib/client/nodes/manual/ModeConfig.js +0 -27
- package/lib/client/nodes/manual/SchemaConfig.js +87 -449
- package/lib/client/nodes/manual/WorkflowTodo.js +99 -163
- package/lib/client/nodes/manual/WorkflowTodoBlockInitializer.js +4 -20
- package/lib/client/nodes/manual/forms/customForm.d.ts +40 -0
- package/lib/client/nodes/manual/forms/customForm.js +411 -0
- package/lib/client/nodes/manual/index.d.ts +12 -1
- package/lib/client/nodes/manual/index.js +54 -41
- package/lib/client/nodes/parallel.js +7 -41
- package/lib/client/nodes/query.d.ts +28 -7
- package/lib/client/nodes/query.js +15 -22
- package/lib/client/nodes/request.d.ts +2 -3
- package/lib/client/nodes/request.js +5 -22
- package/lib/client/nodes/update.d.ts +1 -6
- package/lib/client/nodes/update.js +8 -16
- package/lib/client/schemas/collection.d.ts +20 -4
- package/lib/client/schemas/collection.js +26 -22
- package/lib/client/schemas/executions.js +3 -18
- package/lib/client/schemas/workflows.js +10 -33
- package/lib/client/style.js +24 -21
- package/lib/client/triggers/collection.d.ts +24 -20
- package/lib/client/triggers/collection.js +34 -123
- package/lib/client/triggers/index.d.ts +2 -5
- package/lib/client/triggers/index.js +34 -105
- package/lib/client/triggers/schedule/DateFieldsSelect.js +6 -29
- package/lib/client/triggers/schedule/EndsByField.js +1 -18
- package/lib/client/triggers/schedule/OnField.js +10 -38
- package/lib/client/triggers/schedule/RepeatField.js +4 -32
- package/lib/client/triggers/schedule/ScheduleConfig.js +10 -51
- package/lib/client/triggers/schedule/index.d.ts +21 -0
- package/lib/client/triggers/schedule/index.js +21 -22
- package/lib/client/triggers/schedule/locale/Cron.zh-CN.js +8 -4
- package/lib/client/utils.d.ts +1 -0
- package/lib/client/utils.js +31 -10
- package/lib/client/variable.d.ts +7 -6
- package/lib/client/variable.js +132 -71
- package/lib/index.js +0 -2
- package/lib/server/Plugin.d.ts +7 -7
- package/lib/server/Plugin.js +76 -111
- package/lib/server/Processor.d.ts +2 -0
- package/lib/server/Processor.js +62 -125
- package/lib/server/actions/index.js +3 -10
- package/lib/server/actions/nodes.js +34 -87
- package/lib/server/actions/workflows.js +46 -96
- package/lib/server/collections/executions.js +1 -1
- package/lib/server/collections/flow_nodes.js +7 -4
- package/lib/server/collections/jobs.js +1 -1
- package/lib/server/collections/workflows.js +3 -4
- package/lib/server/fields/expression-field.d.ts +8 -0
- package/lib/server/fields/expression-field.js +26 -0
- package/lib/server/fields/index.d.ts +1 -0
- package/lib/server/fields/index.js +12 -0
- package/lib/server/functions/index.js +3 -14
- package/lib/server/index.js +0 -6
- package/lib/server/instructions/calculation.js +22 -17
- package/lib/server/instructions/condition.js +8 -52
- package/lib/server/instructions/create.js +31 -15
- package/lib/server/instructions/delay.js +4 -32
- package/lib/server/instructions/destroy.js +6 -12
- package/lib/server/instructions/index.js +6 -23
- package/lib/server/instructions/manual/actions.js +22 -31
- package/lib/server/instructions/manual/collecions/users_jobs.js +1 -1
- package/lib/server/instructions/manual/index.d.ts +13 -12
- package/lib/server/instructions/manual/index.js +9 -47
- package/lib/server/instructions/parallel.js +9 -36
- package/lib/server/instructions/query.js +17 -15
- package/lib/server/instructions/request.js +7 -30
- package/lib/server/instructions/update.js +8 -14
- package/lib/server/migrations/20221129153547-calculation-variables.js +3 -27
- package/lib/server/migrations/20230221032941-change-request-body-type.js +3 -26
- package/lib/server/migrations/20230221071831-calculation-expression.js +1 -33
- package/lib/server/migrations/20230221121203-condition-calculation.js +5 -28
- package/lib/server/migrations/20230221162902-jsonb-to-json.js +3 -18
- package/lib/server/migrations/20230411034722-manual-multi-form.d.ts +4 -0
- package/lib/server/migrations/20230411034722-manual-multi-form.js +303 -0
- package/lib/server/models/Execution.js +0 -5
- package/lib/server/models/FlowNode.js +0 -5
- package/lib/server/models/Job.js +0 -5
- package/lib/server/models/Workflow.js +0 -5
- package/lib/server/triggers/collection.js +39 -61
- package/lib/server/triggers/index.js +3 -22
- package/lib/server/triggers/schedule.js +72 -194
- package/package.json +14 -11
|
@@ -4,82 +4,59 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = exports.SCHEDULE_MODE = void 0;
|
|
7
|
-
|
|
8
7
|
function _cronParser() {
|
|
9
8
|
const data = _interopRequireDefault(require("cron-parser"));
|
|
10
|
-
|
|
11
9
|
_cronParser = function _cronParser() {
|
|
12
10
|
return data;
|
|
13
11
|
};
|
|
14
|
-
|
|
15
12
|
return data;
|
|
16
13
|
}
|
|
17
|
-
|
|
18
14
|
function _sequelize() {
|
|
19
15
|
const data = require("sequelize");
|
|
20
|
-
|
|
21
16
|
_sequelize = function _sequelize() {
|
|
22
17
|
return data;
|
|
23
18
|
};
|
|
24
|
-
|
|
25
19
|
return data;
|
|
26
20
|
}
|
|
27
|
-
|
|
28
21
|
var _ = require("..");
|
|
29
|
-
|
|
30
22
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
31
|
-
|
|
32
23
|
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
|
|
33
|
-
|
|
34
24
|
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
35
|
-
|
|
36
25
|
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
|
|
37
|
-
|
|
38
26
|
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
|
|
39
|
-
|
|
40
27
|
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
|
|
41
|
-
|
|
42
28
|
function _asyncIterator(iterable) { var method, async, sync, retry = 2; for ("undefined" != typeof Symbol && (async = Symbol.asyncIterator, sync = Symbol.iterator); retry--;) { if (async && null != (method = iterable[async])) return method.call(iterable); if (sync && null != (method = iterable[sync])) return new AsyncFromSyncIterator(method.call(iterable)); async = "@@asyncIterator", sync = "@@iterator"; } throw new TypeError("Object is not async iterable"); }
|
|
43
|
-
|
|
44
29
|
function AsyncFromSyncIterator(s) { function AsyncFromSyncIteratorContinuation(r) { if (Object(r) !== r) return Promise.reject(new TypeError(r + " is not an object.")); var done = r.done; return Promise.resolve(r.value).then(function (value) { return { value: value, done: done }; }); } return AsyncFromSyncIterator = function AsyncFromSyncIterator(s) { this.s = s, this.n = s.next; }, AsyncFromSyncIterator.prototype = { s: null, n: null, next: function next() { return AsyncFromSyncIteratorContinuation(this.n.apply(this.s, arguments)); }, return: function _return(value) { var ret = this.s.return; return void 0 === ret ? Promise.resolve({ value: value, done: !0 }) : AsyncFromSyncIteratorContinuation(ret.apply(this.s, arguments)); }, throw: function _throw(value) { var thr = this.s.return; return void 0 === thr ? Promise.reject(value) : AsyncFromSyncIteratorContinuation(thr.apply(this.s, arguments)); } }, new AsyncFromSyncIterator(s); }
|
|
45
|
-
|
|
46
30
|
const SCHEDULE_MODE = {
|
|
47
31
|
CONSTANT: 0,
|
|
48
32
|
COLLECTION_FIELD: 1
|
|
49
33
|
};
|
|
50
34
|
exports.SCHEDULE_MODE = SCHEDULE_MODE;
|
|
51
35
|
const ScheduleModes = new Map();
|
|
52
|
-
|
|
53
36
|
function parseDateWithoutMs(date) {
|
|
54
37
|
return Math.floor(Date.parse(date) / 1000) * 1000;
|
|
55
38
|
}
|
|
56
|
-
|
|
57
39
|
ScheduleModes.set(SCHEDULE_MODE.CONSTANT, {
|
|
58
40
|
shouldCache(workflow, now) {
|
|
59
41
|
const _workflow$config = workflow.config,
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
const timestamp = now.getTime();
|
|
64
|
-
|
|
42
|
+
startsOn = _workflow$config.startsOn,
|
|
43
|
+
endsOn = _workflow$config.endsOn,
|
|
44
|
+
repeat = _workflow$config.repeat;
|
|
45
|
+
const timestamp = now.getTime();
|
|
46
|
+
// NOTE: align to second start
|
|
65
47
|
const startTime = parseDateWithoutMs(startsOn);
|
|
66
|
-
|
|
67
48
|
if (!startTime || startTime > timestamp + this.cacheCycle) {
|
|
68
49
|
return false;
|
|
69
50
|
}
|
|
70
|
-
|
|
71
51
|
if (repeat) {
|
|
72
52
|
if (typeof repeat === 'number') {
|
|
73
53
|
const next = timestamp - (timestamp - startTime) % repeat + repeat;
|
|
74
|
-
|
|
75
54
|
if (next <= timestamp || next > timestamp + this.cacheCycle) {
|
|
76
55
|
return false;
|
|
77
56
|
}
|
|
78
57
|
}
|
|
79
|
-
|
|
80
58
|
if (endsOn) {
|
|
81
59
|
const endTime = parseDateWithoutMs(endsOn);
|
|
82
|
-
|
|
83
60
|
if (!endTime || endTime <= timestamp) {
|
|
84
61
|
return false;
|
|
85
62
|
}
|
|
@@ -89,33 +66,27 @@ ScheduleModes.set(SCHEDULE_MODE.CONSTANT, {
|
|
|
89
66
|
return false;
|
|
90
67
|
}
|
|
91
68
|
}
|
|
92
|
-
|
|
93
69
|
return true;
|
|
94
70
|
},
|
|
95
|
-
|
|
96
71
|
trigger(workflow, now) {
|
|
97
72
|
const _workflow$config2 = workflow.config,
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
const timestamp = now.getTime();
|
|
102
|
-
|
|
73
|
+
startsOn = _workflow$config2.startsOn,
|
|
74
|
+
endsOn = _workflow$config2.endsOn,
|
|
75
|
+
repeat = _workflow$config2.repeat;
|
|
76
|
+
const timestamp = now.getTime();
|
|
77
|
+
// NOTE: align to second start
|
|
103
78
|
const startTime = parseDateWithoutMs(startsOn);
|
|
104
|
-
|
|
105
79
|
if (!startTime || startTime > timestamp) {
|
|
106
80
|
return;
|
|
107
81
|
}
|
|
108
|
-
|
|
109
82
|
if (repeat) {
|
|
110
83
|
if (typeof repeat === 'number') {
|
|
111
84
|
if (Math.round(timestamp - startTime) % repeat) {
|
|
112
85
|
return;
|
|
113
86
|
}
|
|
114
87
|
}
|
|
115
|
-
|
|
116
88
|
if (endsOn) {
|
|
117
89
|
const endTime = parseDateWithoutMs(endsOn);
|
|
118
|
-
|
|
119
90
|
if (!endTime || endTime < timestamp) {
|
|
120
91
|
return;
|
|
121
92
|
}
|
|
@@ -125,99 +96,80 @@ ScheduleModes.set(SCHEDULE_MODE.CONSTANT, {
|
|
|
125
96
|
return;
|
|
126
97
|
}
|
|
127
98
|
}
|
|
128
|
-
|
|
129
99
|
return this.plugin.trigger(workflow, {
|
|
130
100
|
date: now
|
|
131
101
|
});
|
|
132
102
|
}
|
|
133
|
-
|
|
134
103
|
});
|
|
135
|
-
|
|
136
104
|
function getOnTimestampWithOffset(on, now) {
|
|
137
105
|
switch (typeof on) {
|
|
138
106
|
case 'string':
|
|
139
107
|
return parseDateWithoutMs(on);
|
|
140
|
-
|
|
141
108
|
case 'object':
|
|
142
109
|
const field = on.field,
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
110
|
+
_on$offset = on.offset,
|
|
111
|
+
offset = _on$offset === void 0 ? 0 : _on$offset,
|
|
112
|
+
_on$unit = on.unit,
|
|
113
|
+
unit = _on$unit === void 0 ? 1000 : _on$unit;
|
|
148
114
|
if (!field) {
|
|
149
115
|
return null;
|
|
150
116
|
}
|
|
151
|
-
|
|
152
|
-
|
|
117
|
+
const timestamp = now.getTime();
|
|
118
|
+
// onDate + offset > now
|
|
153
119
|
// onDate > now - offset
|
|
154
|
-
|
|
155
120
|
return timestamp - offset * unit;
|
|
156
|
-
|
|
157
121
|
default:
|
|
158
122
|
return null;
|
|
159
123
|
}
|
|
160
124
|
}
|
|
161
|
-
|
|
162
125
|
function getDataOptionTime(data, on, dir = 1) {
|
|
163
126
|
if (!on) {
|
|
164
127
|
return null;
|
|
165
128
|
}
|
|
166
|
-
|
|
167
129
|
switch (typeof on) {
|
|
168
130
|
case 'string':
|
|
169
131
|
const time = parseDateWithoutMs(on);
|
|
170
132
|
return time ? time : null;
|
|
171
|
-
|
|
172
133
|
case 'object':
|
|
173
134
|
const field = on.field,
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
135
|
+
_on$offset2 = on.offset,
|
|
136
|
+
offset = _on$offset2 === void 0 ? 0 : _on$offset2,
|
|
137
|
+
_on$unit2 = on.unit,
|
|
138
|
+
unit = _on$unit2 === void 0 ? 1000 : _on$unit2;
|
|
178
139
|
return data.get(field) ? data.get(field).getTime() - offset * unit * dir : null;
|
|
179
|
-
|
|
180
140
|
default:
|
|
181
141
|
return null;
|
|
182
142
|
}
|
|
183
143
|
}
|
|
184
|
-
|
|
185
144
|
function getHookId(workflow, type) {
|
|
186
145
|
return `${type}#${workflow.id}`;
|
|
187
146
|
}
|
|
188
|
-
|
|
189
147
|
const DialectTimestampFnMap = {
|
|
190
148
|
postgres(col) {
|
|
191
149
|
return `CAST(FLOOR(extract(epoch from "${col}")) AS INTEGER)`;
|
|
192
150
|
},
|
|
193
|
-
|
|
194
151
|
mysql(col) {
|
|
195
152
|
return `CAST(FLOOR(UNIX_TIMESTAMP(\`${col}\`)) AS SIGNED INTEGER)`;
|
|
196
153
|
},
|
|
197
|
-
|
|
198
154
|
sqlite(col) {
|
|
199
155
|
return `CAST(FLOOR(unixepoch(${col})) AS INTEGER)`;
|
|
200
156
|
}
|
|
201
|
-
|
|
202
157
|
};
|
|
203
158
|
DialectTimestampFnMap.mariadb = DialectTimestampFnMap.mysql;
|
|
204
159
|
ScheduleModes.set(SCHEDULE_MODE.COLLECTION_FIELD, {
|
|
205
160
|
on(workflow) {
|
|
206
161
|
var _this = this;
|
|
207
|
-
|
|
208
162
|
const _workflow$config3 = workflow.config,
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
163
|
+
collection = _workflow$config3.collection,
|
|
164
|
+
startsOn = _workflow$config3.startsOn,
|
|
165
|
+
endsOn = _workflow$config3.endsOn,
|
|
166
|
+
repeat = _workflow$config3.repeat;
|
|
213
167
|
const event = `${collection}.afterSave`;
|
|
214
168
|
const name = getHookId(workflow, event);
|
|
215
|
-
|
|
216
169
|
if (this.events.has(name)) {
|
|
217
170
|
return;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
|
|
171
|
+
}
|
|
172
|
+
// NOTE: toggle cache depends on new date
|
|
221
173
|
const listener = /*#__PURE__*/function () {
|
|
222
174
|
var _ref = _asyncToGenerator(function* (data, options) {
|
|
223
175
|
const now = new Date();
|
|
@@ -225,91 +177,75 @@ ScheduleModes.set(SCHEDULE_MODE.COLLECTION_FIELD, {
|
|
|
225
177
|
const timestamp = now.getTime();
|
|
226
178
|
const startTime = getDataOptionTime(data, startsOn);
|
|
227
179
|
const endTime = getDataOptionTime(data, endsOn, -1);
|
|
228
|
-
|
|
229
180
|
if (!startTime) {
|
|
230
181
|
return;
|
|
231
182
|
}
|
|
232
|
-
|
|
233
183
|
if (startTime && startTime > timestamp + _this.cacheCycle) {
|
|
234
184
|
return;
|
|
235
185
|
}
|
|
236
|
-
|
|
237
186
|
if (endTime && endTime <= timestamp) {
|
|
238
187
|
return;
|
|
239
188
|
}
|
|
240
|
-
|
|
241
189
|
if (!matchNext.call(_this, workflow, now)) {
|
|
242
190
|
return;
|
|
243
191
|
}
|
|
244
|
-
|
|
245
192
|
if (typeof repeat === 'number' && repeat > _this.cacheCycle && (timestamp - startTime) % repeat > _this.cacheCycle) {
|
|
246
193
|
return;
|
|
247
194
|
}
|
|
248
|
-
|
|
249
195
|
_this.setCache(workflow);
|
|
250
196
|
});
|
|
251
|
-
|
|
252
197
|
return function listener(_x, _x2) {
|
|
253
198
|
return _ref.apply(this, arguments);
|
|
254
199
|
};
|
|
255
200
|
}();
|
|
256
|
-
|
|
257
201
|
this.events.set(name, listener);
|
|
258
202
|
this.plugin.app.db.on(event, listener);
|
|
259
203
|
},
|
|
260
|
-
|
|
261
204
|
off(workflow) {
|
|
262
205
|
const collection = workflow.config.collection;
|
|
263
206
|
const event = `${collection}.afterSave`;
|
|
264
207
|
const name = getHookId(workflow, event);
|
|
265
|
-
|
|
266
208
|
if (this.events.has(name)) {
|
|
267
209
|
const listener = this.events.get(name);
|
|
268
210
|
this.events.delete(name);
|
|
269
211
|
this.plugin.app.db.off(event, listener);
|
|
270
212
|
}
|
|
271
213
|
},
|
|
272
|
-
|
|
273
214
|
shouldCache(workflow, now) {
|
|
274
215
|
var _this2 = this;
|
|
275
|
-
|
|
276
216
|
return _asyncToGenerator(function* () {
|
|
277
217
|
const db = _this2.plugin.app.db;
|
|
278
218
|
const _workflow$config4 = workflow.config,
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
219
|
+
startsOn = _workflow$config4.startsOn,
|
|
220
|
+
endsOn = _workflow$config4.endsOn,
|
|
221
|
+
repeat = _workflow$config4.repeat,
|
|
222
|
+
collection = _workflow$config4.collection;
|
|
283
223
|
const timestamp = now.getTime();
|
|
284
224
|
const startTimestamp = getOnTimestampWithOffset(startsOn, now);
|
|
285
|
-
|
|
286
225
|
if (!startTimestamp) {
|
|
287
226
|
return false;
|
|
288
227
|
}
|
|
289
|
-
|
|
290
228
|
const conditions = [{
|
|
291
229
|
[startsOn.field]: {
|
|
292
230
|
[_sequelize().Op.lt]: new Date(startTimestamp + _this2.cacheCycle)
|
|
293
231
|
}
|
|
294
|
-
}];
|
|
232
|
+
}];
|
|
233
|
+
// when repeat is number, means repeat after startsOn
|
|
295
234
|
// (now - startsOn) % repeat <= cacheCycle
|
|
296
|
-
|
|
297
235
|
if (repeat) {
|
|
298
236
|
const tsFn = DialectTimestampFnMap[db.options.dialect];
|
|
299
|
-
|
|
300
237
|
if (typeof repeat === 'number' && repeat > _this2.cacheCycle && tsFn) {
|
|
301
238
|
conditions.push((0, _sequelize().where)((0, _sequelize().fn)('MOD', (0, _sequelize().literal)(`${Math.round(timestamp / 1000)} - ${tsFn(startsOn.field)}`), Math.round(repeat / 1000)), {
|
|
302
239
|
[_sequelize().Op.lt]: Math.round(_this2.cacheCycle / 1000)
|
|
303
|
-
}));
|
|
240
|
+
}));
|
|
241
|
+
// conditions.push(literal(`mod(${timestamp} - ${tsFn(startsOn.field)} * 1000, ${repeat}) < ${this.cacheCycle}`));
|
|
304
242
|
}
|
|
305
243
|
|
|
306
244
|
if (endsOn) {
|
|
307
245
|
const endTimestamp = getOnTimestampWithOffset(endsOn, now);
|
|
308
|
-
|
|
309
246
|
if (!endTimestamp) {
|
|
310
247
|
return false;
|
|
311
248
|
}
|
|
312
|
-
|
|
313
249
|
if (typeof endsOn === 'string') {
|
|
314
250
|
if (endTimestamp <= timestamp) {
|
|
315
251
|
return false;
|
|
@@ -329,10 +265,8 @@ ScheduleModes.set(SCHEDULE_MODE.COLLECTION_FIELD, {
|
|
|
329
265
|
}
|
|
330
266
|
});
|
|
331
267
|
}
|
|
332
|
-
|
|
333
268
|
const _db$getCollection = db.getCollection(collection),
|
|
334
|
-
|
|
335
|
-
|
|
269
|
+
model = _db$getCollection.model;
|
|
336
270
|
const count = yield model.count({
|
|
337
271
|
where: {
|
|
338
272
|
[_sequelize().Op.and]: conditions
|
|
@@ -341,29 +275,25 @@ ScheduleModes.set(SCHEDULE_MODE.COLLECTION_FIELD, {
|
|
|
341
275
|
return Boolean(count);
|
|
342
276
|
})();
|
|
343
277
|
},
|
|
344
|
-
|
|
345
278
|
trigger(workflow, now) {
|
|
346
279
|
var _this3 = this;
|
|
347
|
-
|
|
348
280
|
return _asyncToGenerator(function* () {
|
|
349
281
|
const _workflow$config5 = workflow.config,
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
282
|
+
startsOn = _workflow$config5.startsOn,
|
|
283
|
+
repeat = _workflow$config5.repeat,
|
|
284
|
+
endsOn = _workflow$config5.endsOn,
|
|
285
|
+
collection = _workflow$config5.collection,
|
|
286
|
+
appends = _workflow$config5.appends;
|
|
354
287
|
const timestamp = now.getTime();
|
|
355
288
|
const startTimestamp = getOnTimestampWithOffset(startsOn, now);
|
|
356
|
-
|
|
357
289
|
if (!startTimestamp) {
|
|
358
290
|
return false;
|
|
359
291
|
}
|
|
360
|
-
|
|
361
292
|
const conditions = [{
|
|
362
293
|
[startsOn.field]: {
|
|
363
294
|
[_sequelize().Op.lt]: new Date(startTimestamp + _this3.interval)
|
|
364
295
|
}
|
|
365
296
|
}];
|
|
366
|
-
|
|
367
297
|
if (repeat) {
|
|
368
298
|
// startsOn not after now
|
|
369
299
|
conditions.push({
|
|
@@ -372,20 +302,18 @@ ScheduleModes.set(SCHEDULE_MODE.COLLECTION_FIELD, {
|
|
|
372
302
|
}
|
|
373
303
|
});
|
|
374
304
|
const tsFn = DialectTimestampFnMap[_this3.plugin.app.db.options.dialect];
|
|
375
|
-
|
|
376
305
|
if (typeof repeat === 'number' && tsFn) {
|
|
377
306
|
conditions.push((0, _sequelize().where)((0, _sequelize().fn)('MOD', (0, _sequelize().literal)(`${Math.round(timestamp / 1000)} - ${tsFn(startsOn.field)}`), Math.round(repeat / 1000)), {
|
|
378
307
|
[_sequelize().Op.eq]: 0
|
|
379
|
-
}));
|
|
308
|
+
}));
|
|
309
|
+
// conditions.push(literal(`MOD(CAST(${timestamp} AS BIGINT) - CAST((FLOOR(${tsFn(startsOn.field)}) AS BIGINT) * 1000), ${repeat}) = 0`));
|
|
380
310
|
}
|
|
381
311
|
|
|
382
312
|
if (endsOn) {
|
|
383
313
|
const endTimestamp = getOnTimestampWithOffset(endsOn, now);
|
|
384
|
-
|
|
385
314
|
if (!endTimestamp) {
|
|
386
315
|
return false;
|
|
387
316
|
}
|
|
388
|
-
|
|
389
317
|
if (typeof endsOn === 'string') {
|
|
390
318
|
if (endTimestamp <= timestamp) {
|
|
391
319
|
return false;
|
|
@@ -406,103 +334,88 @@ ScheduleModes.set(SCHEDULE_MODE.COLLECTION_FIELD, {
|
|
|
406
334
|
}
|
|
407
335
|
});
|
|
408
336
|
}
|
|
409
|
-
|
|
410
|
-
const
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
[_sequelize().Op.and]: conditions
|
|
416
|
-
}
|
|
337
|
+
const repo = _this3.plugin.app.db.getRepository(collection);
|
|
338
|
+
const instances = yield repo.find({
|
|
339
|
+
filter: {
|
|
340
|
+
$and: conditions
|
|
341
|
+
},
|
|
342
|
+
appends
|
|
417
343
|
});
|
|
418
344
|
instances.forEach(item => {
|
|
419
345
|
_this3.plugin.trigger(workflow, {
|
|
420
346
|
date: now,
|
|
421
|
-
data: item.
|
|
347
|
+
data: item.toJSON()
|
|
422
348
|
});
|
|
423
349
|
});
|
|
424
350
|
})();
|
|
425
351
|
}
|
|
426
|
-
|
|
427
352
|
});
|
|
428
|
-
|
|
429
353
|
function matchNext(workflow, now, range = this.cacheCycle) {
|
|
430
|
-
const repeat = workflow.config.repeat;
|
|
354
|
+
const repeat = workflow.config.repeat;
|
|
355
|
+
// no repeat means no need to rerun
|
|
431
356
|
// but if in current cycle, should be put in cache
|
|
432
357
|
// no repeat but in current cycle means startsOn has been configured
|
|
433
358
|
// so we need to more info to determine if necessary config items
|
|
434
|
-
|
|
435
359
|
if (typeof repeat !== 'string') {
|
|
436
360
|
return true;
|
|
437
361
|
}
|
|
438
|
-
|
|
439
362
|
const currentDate = new Date(now);
|
|
440
363
|
currentDate.setMilliseconds(-1);
|
|
441
364
|
const timestamp = now.getTime();
|
|
442
|
-
|
|
443
365
|
const interval = _cronParser().default.parseExpression(repeat, {
|
|
444
366
|
currentDate
|
|
445
367
|
});
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
368
|
+
let next = interval.next();
|
|
369
|
+
// NOTE: cache all workflows will be matched in current cycle
|
|
449
370
|
if (next.getTime() - timestamp <= range) {
|
|
450
371
|
return true;
|
|
451
372
|
}
|
|
452
|
-
|
|
453
373
|
return false;
|
|
454
374
|
}
|
|
455
|
-
|
|
456
375
|
class ScheduleTrigger extends _.Trigger {
|
|
457
|
-
// running interval, default to 1s
|
|
458
|
-
// caching workflows in range, default to 1min
|
|
459
376
|
constructor(plugin) {
|
|
460
377
|
super(plugin);
|
|
461
378
|
this.events = new Map();
|
|
462
379
|
this.timer = null;
|
|
463
380
|
this.cache = new Map();
|
|
381
|
+
// running interval, default to 1s
|
|
464
382
|
this.interval = 1000;
|
|
383
|
+
// caching workflows in range, default to 1min
|
|
465
384
|
this.cacheCycle = 60000;
|
|
466
|
-
|
|
467
385
|
this.run = () => {
|
|
468
|
-
const now = new Date();
|
|
469
|
-
|
|
386
|
+
const now = new Date();
|
|
387
|
+
// 1001 to avoid 999
|
|
470
388
|
const nextInterval = 1001 - now.getMilliseconds();
|
|
471
|
-
now.setMilliseconds(0);
|
|
472
|
-
|
|
473
|
-
this.onTick(now);
|
|
474
|
-
|
|
389
|
+
now.setMilliseconds(0);
|
|
390
|
+
// NOTE: trigger `onTick` for high interval jobs which are cached in last 1 min
|
|
391
|
+
this.onTick(now);
|
|
392
|
+
// NOTE: reload when second match cache cycle
|
|
475
393
|
if (!(now.getTime() % this.cacheCycle)) {
|
|
476
394
|
this.reload();
|
|
477
395
|
}
|
|
478
|
-
|
|
479
396
|
this.timer = setTimeout(this.run, nextInterval);
|
|
480
397
|
};
|
|
481
|
-
|
|
482
398
|
plugin.app.on('beforeStop', () => {
|
|
483
399
|
if (this.timer) {
|
|
484
400
|
clearInterval(this.timer);
|
|
485
401
|
}
|
|
486
402
|
});
|
|
487
403
|
}
|
|
488
|
-
|
|
489
404
|
init() {
|
|
490
405
|
if (this.timer) {
|
|
491
406
|
return;
|
|
492
407
|
}
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
408
|
+
const now = new Date();
|
|
409
|
+
// NOTE: assign to this.timer to avoid duplicated initialization
|
|
410
|
+
this.timer = setTimeout(this.run,
|
|
411
|
+
// NOTE:
|
|
497
412
|
// try to align to system time on each second starts,
|
|
498
413
|
// after at least 1 second initialized for anything to get ready.
|
|
499
414
|
// so jobs in 2 seconds will be missed at first start.
|
|
500
415
|
1000 - now.getMilliseconds());
|
|
501
416
|
}
|
|
502
|
-
|
|
503
417
|
onTick(now) {
|
|
504
418
|
var _this4 = this;
|
|
505
|
-
|
|
506
419
|
return _asyncToGenerator(function* () {
|
|
507
420
|
// NOTE: trigger workflows in sequence when sqlite due to only one transaction
|
|
508
421
|
const isSqlite = _this4.plugin.app.db.options.dialect === 'sqlite';
|
|
@@ -510,24 +423,18 @@ class ScheduleTrigger extends _.Trigger {
|
|
|
510
423
|
if (!_this4.shouldTrigger(workflow, now)) {
|
|
511
424
|
return prev;
|
|
512
425
|
}
|
|
513
|
-
|
|
514
426
|
if (isSqlite) {
|
|
515
427
|
return prev.then(() => _this4.trigger(workflow, now));
|
|
516
428
|
}
|
|
517
|
-
|
|
518
429
|
_this4.trigger(workflow, now);
|
|
519
|
-
|
|
520
430
|
return null;
|
|
521
431
|
}, isSqlite ? Promise.resolve() : null);
|
|
522
432
|
})();
|
|
523
433
|
}
|
|
524
|
-
|
|
525
434
|
reload() {
|
|
526
435
|
var _this5 = this;
|
|
527
|
-
|
|
528
436
|
return _asyncToGenerator(function* () {
|
|
529
437
|
const WorkflowModel = _this5.plugin.app.db.getCollection('workflows').model;
|
|
530
|
-
|
|
531
438
|
const workflows = yield WorkflowModel.findAll({
|
|
532
439
|
where: {
|
|
533
440
|
enabled: true,
|
|
@@ -541,55 +448,45 @@ class ScheduleTrigger extends _.Trigger {
|
|
|
541
448
|
order: [['createdAt', 'DESC']]
|
|
542
449
|
}],
|
|
543
450
|
group: ['id']
|
|
544
|
-
});
|
|
545
|
-
|
|
451
|
+
});
|
|
452
|
+
// NOTE: clear cached jobs in last cycle
|
|
546
453
|
_this5.cache = new Map();
|
|
547
|
-
|
|
548
454
|
_this5.inspect(workflows);
|
|
549
455
|
})();
|
|
550
456
|
}
|
|
551
|
-
|
|
552
457
|
inspect(workflows) {
|
|
553
458
|
var _this6 = this;
|
|
554
|
-
|
|
555
459
|
const now = new Date();
|
|
556
460
|
now.setMilliseconds(0);
|
|
557
461
|
workflows.forEach( /*#__PURE__*/function () {
|
|
558
462
|
var _ref2 = _asyncToGenerator(function* (workflow) {
|
|
559
463
|
const should = yield _this6.shouldCache(workflow, now);
|
|
560
|
-
|
|
561
464
|
if (should) {
|
|
562
465
|
_this6.plugin.app.logger.info('caching scheduled workflow will run in next minute:', workflow.id);
|
|
563
466
|
}
|
|
564
|
-
|
|
565
467
|
_this6.setCache(workflow, !should);
|
|
566
468
|
});
|
|
567
|
-
|
|
568
469
|
return function (_x3) {
|
|
569
470
|
return _ref2.apply(this, arguments);
|
|
570
471
|
};
|
|
571
472
|
}());
|
|
572
473
|
}
|
|
573
|
-
|
|
574
474
|
setCache(workflow, out = false) {
|
|
575
475
|
out ? this.cache.delete(workflow.id) : this.cache.set(workflow.id, workflow);
|
|
576
476
|
}
|
|
577
|
-
|
|
578
477
|
shouldCache(workflow, now) {
|
|
579
478
|
var _this7 = this;
|
|
580
|
-
|
|
581
479
|
return _asyncToGenerator(function* () {
|
|
582
480
|
var _iteratorAbruptCompletion = false;
|
|
583
481
|
var _didIteratorError = false;
|
|
584
|
-
|
|
585
482
|
var _iteratorError;
|
|
586
|
-
|
|
587
483
|
try {
|
|
588
484
|
for (var _iterator = _asyncIterator(_this7.constructor.CacheRules), _step; _iteratorAbruptCompletion = !(_step = yield _iterator.next()).done; _iteratorAbruptCompletion = false) {
|
|
589
485
|
const rule = _step.value;
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
486
|
+
{
|
|
487
|
+
if (!(yield rule.call(_this7, workflow, now))) {
|
|
488
|
+
return false;
|
|
489
|
+
}
|
|
593
490
|
}
|
|
594
491
|
}
|
|
595
492
|
} catch (err) {
|
|
@@ -606,19 +503,15 @@ class ScheduleTrigger extends _.Trigger {
|
|
|
606
503
|
}
|
|
607
504
|
}
|
|
608
505
|
}
|
|
609
|
-
|
|
610
506
|
return true;
|
|
611
507
|
})();
|
|
612
508
|
}
|
|
613
|
-
|
|
614
509
|
shouldTrigger(workflow, now) {
|
|
615
510
|
var _iterator2 = _createForOfIteratorHelper(this.constructor.TriggerRules),
|
|
616
|
-
|
|
617
|
-
|
|
511
|
+
_step2;
|
|
618
512
|
try {
|
|
619
513
|
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
620
514
|
const rule = _step2.value;
|
|
621
|
-
|
|
622
515
|
if (!rule.call(this, workflow, now)) {
|
|
623
516
|
return false;
|
|
624
517
|
}
|
|
@@ -628,51 +521,38 @@ class ScheduleTrigger extends _.Trigger {
|
|
|
628
521
|
} finally {
|
|
629
522
|
_iterator2.f();
|
|
630
523
|
}
|
|
631
|
-
|
|
632
524
|
return true;
|
|
633
525
|
}
|
|
634
|
-
|
|
635
526
|
trigger(workflow, date) {
|
|
636
527
|
var _this8 = this;
|
|
637
|
-
|
|
638
528
|
return _asyncToGenerator(function* () {
|
|
639
529
|
const mode = workflow.config.mode;
|
|
640
530
|
const modeHandlers = ScheduleModes.get(mode);
|
|
641
|
-
|
|
642
531
|
if (!modeHandlers) {
|
|
643
532
|
return;
|
|
644
533
|
}
|
|
645
|
-
|
|
646
534
|
return modeHandlers.trigger.call(_this8, workflow, date);
|
|
647
535
|
})();
|
|
648
536
|
}
|
|
649
|
-
|
|
650
537
|
on(workflow) {
|
|
651
538
|
// NOTE: lazy initialization
|
|
652
539
|
this.init();
|
|
653
540
|
const mode = workflow.config.mode;
|
|
654
541
|
const modeHandlers = ScheduleModes.get(mode);
|
|
655
|
-
|
|
656
542
|
if (modeHandlers && modeHandlers.on) {
|
|
657
543
|
modeHandlers.on.call(this, workflow);
|
|
658
544
|
}
|
|
659
|
-
|
|
660
545
|
this.inspect([workflow]);
|
|
661
546
|
}
|
|
662
|
-
|
|
663
547
|
off(workflow) {
|
|
664
548
|
const mode = workflow.config.mode;
|
|
665
549
|
const modeHandlers = ScheduleModes.get(mode);
|
|
666
|
-
|
|
667
550
|
if (modeHandlers && modeHandlers.off) {
|
|
668
551
|
modeHandlers.off.call(this, workflow);
|
|
669
552
|
}
|
|
670
|
-
|
|
671
553
|
this.cache.delete(workflow.id);
|
|
672
554
|
}
|
|
673
|
-
|
|
674
555
|
}
|
|
675
|
-
|
|
676
556
|
exports.default = ScheduleTrigger;
|
|
677
557
|
ScheduleTrigger.CacheRules = [({
|
|
678
558
|
config,
|
|
@@ -680,11 +560,9 @@ ScheduleTrigger.CacheRules = [({
|
|
|
680
560
|
}) => (config.limit ? allExecuted < config.limit : true) && config.startsOn, matchNext, function (workflow, now) {
|
|
681
561
|
const mode = workflow.config.mode;
|
|
682
562
|
const modeHandlers = ScheduleModes.get(mode);
|
|
683
|
-
|
|
684
563
|
if (!modeHandlers) {
|
|
685
564
|
return false;
|
|
686
565
|
}
|
|
687
|
-
|
|
688
566
|
return modeHandlers.shouldCache.call(this, workflow, now);
|
|
689
567
|
}];
|
|
690
568
|
ScheduleTrigger.TriggerRules = [({
|