@nocobase/plugin-workflow 0.7.0-alpha.6 → 0.7.0-alpha.62

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.
Files changed (141) hide show
  1. package/lib/actions/index.d.ts +3 -1
  2. package/lib/actions/index.js +33 -26
  3. package/{esm/actions/flow_nodes.d.ts → lib/actions/nodes.d.ts} +1 -0
  4. package/lib/actions/nodes.js +321 -0
  5. package/lib/actions/workflows.d.ts +3 -0
  6. package/lib/actions/workflows.js +271 -0
  7. package/lib/calculators/index.js +143 -91
  8. package/lib/collections/executions.js +40 -38
  9. package/lib/collections/flow_nodes.js +60 -72
  10. package/lib/collections/jobs.js +45 -47
  11. package/lib/collections/workflows.js +70 -63
  12. package/lib/constants.js +22 -17
  13. package/lib/index.js +71 -22
  14. package/lib/instructions/calculation.js +34 -29
  15. package/lib/instructions/condition.js +94 -87
  16. package/lib/instructions/create.d.ts +1 -1
  17. package/lib/instructions/create.js +43 -25
  18. package/lib/instructions/destroy.js +42 -25
  19. package/lib/instructions/index.js +46 -25
  20. package/lib/instructions/parallel.js +99 -84
  21. package/lib/instructions/prompt.js +21 -13
  22. package/lib/instructions/query.js +46 -25
  23. package/lib/instructions/update.d.ts +2 -1
  24. package/lib/instructions/update.js +44 -25
  25. package/lib/models/Execution.d.ts +3 -2
  26. package/lib/models/Execution.js +400 -241
  27. package/lib/models/FlowNode.js +18 -5
  28. package/lib/models/Job.js +18 -5
  29. package/lib/models/Workflow.d.ts +4 -5
  30. package/lib/models/Workflow.js +94 -72
  31. package/lib/server.d.ts +7 -2
  32. package/lib/server.js +114 -65
  33. package/lib/triggers/collection.d.ts +16 -0
  34. package/lib/triggers/collection.js +162 -0
  35. package/lib/triggers/index.d.ts +3 -6
  36. package/lib/triggers/index.js +14 -11
  37. package/package.json +7 -12
  38. package/esm/actions/flow_nodes.js +0 -139
  39. package/esm/actions/flow_nodes.js.map +0 -1
  40. package/esm/actions/index.d.ts +0 -1
  41. package/esm/actions/index.js +0 -8
  42. package/esm/actions/index.js.map +0 -1
  43. package/esm/calculators/index.d.ts +0 -38
  44. package/esm/calculators/index.js +0 -128
  45. package/esm/calculators/index.js.map +0 -1
  46. package/esm/collections/executions.d.ts +0 -3
  47. package/esm/collections/executions.js +0 -38
  48. package/esm/collections/executions.js.map +0 -1
  49. package/esm/collections/flow_nodes.d.ts +0 -3
  50. package/esm/collections/flow_nodes.js +0 -72
  51. package/esm/collections/flow_nodes.js.map +0 -1
  52. package/esm/collections/jobs.d.ts +0 -3
  53. package/esm/collections/jobs.js +0 -47
  54. package/esm/collections/jobs.js.map +0 -1
  55. package/esm/collections/workflows.d.ts +0 -3
  56. package/esm/collections/workflows.js +0 -63
  57. package/esm/collections/workflows.js.map +0 -1
  58. package/esm/constants.d.ts +0 -17
  59. package/esm/constants.js +0 -18
  60. package/esm/constants.js.map +0 -1
  61. package/esm/index.d.ts +0 -5
  62. package/esm/index.js +0 -6
  63. package/esm/index.js.map +0 -1
  64. package/esm/instructions/calculation.d.ts +0 -8
  65. package/esm/instructions/calculation.js +0 -55
  66. package/esm/instructions/calculation.js.map +0 -1
  67. package/esm/instructions/condition.d.ts +0 -5
  68. package/esm/instructions/condition.js +0 -99
  69. package/esm/instructions/condition.js.map +0 -1
  70. package/esm/instructions/create.d.ts +0 -8
  71. package/esm/instructions/create.js +0 -25
  72. package/esm/instructions/create.js.map +0 -1
  73. package/esm/instructions/destroy.d.ts +0 -8
  74. package/esm/instructions/destroy.js +0 -25
  75. package/esm/instructions/destroy.js.map +0 -1
  76. package/esm/instructions/index.d.ts +0 -15
  77. package/esm/instructions/index.js +0 -20
  78. package/esm/instructions/index.js.map +0 -1
  79. package/esm/instructions/parallel.d.ts +0 -13
  80. package/esm/instructions/parallel.js +0 -88
  81. package/esm/instructions/parallel.js.map +0 -1
  82. package/esm/instructions/prompt.d.ts +0 -7
  83. package/esm/instructions/prompt.js +0 -13
  84. package/esm/instructions/prompt.js.map +0 -1
  85. package/esm/instructions/query.d.ts +0 -8
  86. package/esm/instructions/query.js +0 -25
  87. package/esm/instructions/query.js.map +0 -1
  88. package/esm/instructions/update.d.ts +0 -8
  89. package/esm/instructions/update.js +0 -25
  90. package/esm/instructions/update.js.map +0 -1
  91. package/esm/models/Execution.d.ts +0 -50
  92. package/esm/models/Execution.js +0 -250
  93. package/esm/models/Execution.js.map +0 -1
  94. package/esm/models/FlowNode.d.ts +0 -17
  95. package/esm/models/FlowNode.js +0 -4
  96. package/esm/models/FlowNode.js.map +0 -1
  97. package/esm/models/Job.d.ts +0 -15
  98. package/esm/models/Job.js +0 -4
  99. package/esm/models/Job.js.map +0 -1
  100. package/esm/models/Workflow.d.ts +0 -27
  101. package/esm/models/Workflow.js +0 -72
  102. package/esm/models/Workflow.js.map +0 -1
  103. package/esm/server.d.ts +0 -5
  104. package/esm/server.js +0 -62
  105. package/esm/server.js.map +0 -1
  106. package/esm/triggers/index.d.ts +0 -9
  107. package/esm/triggers/index.js +0 -6
  108. package/esm/triggers/index.js.map +0 -1
  109. package/esm/triggers/model.d.ts +0 -12
  110. package/esm/triggers/model.js +0 -47
  111. package/esm/triggers/model.js.map +0 -1
  112. package/lib/actions/flow_nodes.d.ts +0 -3
  113. package/lib/actions/flow_nodes.js +0 -163
  114. package/lib/actions/flow_nodes.js.map +0 -1
  115. package/lib/actions/index.js.map +0 -1
  116. package/lib/calculators/index.js.map +0 -1
  117. package/lib/collections/executions.js.map +0 -1
  118. package/lib/collections/flow_nodes.js.map +0 -1
  119. package/lib/collections/jobs.js.map +0 -1
  120. package/lib/collections/workflows.js.map +0 -1
  121. package/lib/constants.js.map +0 -1
  122. package/lib/index.js.map +0 -1
  123. package/lib/instructions/calculation.js.map +0 -1
  124. package/lib/instructions/condition.js.map +0 -1
  125. package/lib/instructions/create.js.map +0 -1
  126. package/lib/instructions/destroy.js.map +0 -1
  127. package/lib/instructions/index.js.map +0 -1
  128. package/lib/instructions/parallel.js.map +0 -1
  129. package/lib/instructions/prompt.js.map +0 -1
  130. package/lib/instructions/query.js.map +0 -1
  131. package/lib/instructions/update.js.map +0 -1
  132. package/lib/models/Execution.js.map +0 -1
  133. package/lib/models/FlowNode.js.map +0 -1
  134. package/lib/models/Job.js.map +0 -1
  135. package/lib/models/Workflow.js.map +0 -1
  136. package/lib/server.js.map +0 -1
  137. package/lib/triggers/index.js.map +0 -1
  138. package/lib/triggers/model.d.ts +0 -12
  139. package/lib/triggers/model.js +0 -49
  140. package/lib/triggers/model.js.map +0 -1
  141. package/tsconfig.build.json +0 -9
@@ -1,256 +1,415 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+
8
+ function _database() {
9
+ const data = require("@nocobase/database");
10
+
11
+ _database = function _database() {
12
+ return data;
13
+ };
14
+
15
+ return data;
16
+ }
17
+
18
+ function _jsonTemplates() {
19
+ const data = _interopRequireDefault(require("json-templates"));
20
+
21
+ _jsonTemplates = function _jsonTemplates() {
22
+ return data;
23
+ };
24
+
25
+ return data;
26
+ }
27
+
28
+ var _constants = require("../constants");
29
+
30
+ var _instructions = _interopRequireDefault(require("../instructions"));
31
+
32
+ var _calculators = _interopRequireDefault(require("../calculators"));
33
+
34
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
35
+
36
+ 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(_e2) { throw _e2; }, 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(_e3) { didErr = true; err = _e3; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
37
+
38
+ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
39
+
40
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
41
+
42
+ 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); }
43
+
44
+ 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; }
45
+
46
+ function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
47
+
48
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
49
+
50
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
51
+
52
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
53
+
54
+ function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
55
+
56
+ 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); } }
57
+
58
+ 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); }); }; }
59
+
60
+ class ExecutionModel extends _database().Model {
61
+ constructor(...args) {
62
+ super(...args);
63
+ this.options = void 0;
64
+ this.tx = void 0;
65
+ this.nodes = [];
66
+ this.nodesMap = new Map();
67
+ this.jobsMap = new Map();
68
+ this.jobsMapByNodeId = {};
69
+ }
70
+
71
+ // make dual linked nodes list then cache
72
+ makeNodes(nodes = []) {
73
+ this.nodes = nodes;
74
+ nodes.forEach(node => {
75
+ this.nodesMap.set(node.id, node);
9
76
  });
10
- };
11
- var __importDefault = (this && this.__importDefault) || function (mod) {
12
- return (mod && mod.__esModule) ? mod : { "default": mod };
13
- };
14
- Object.defineProperty(exports, "__esModule", { value: true });
15
- const database_1 = require("@nocobase/database");
16
- const json_templates_1 = __importDefault(require("json-templates"));
17
- const constants_1 = require("../constants");
18
- const instructions_1 = __importDefault(require("../instructions"));
19
- const calculators_1 = __importDefault(require("../calculators"));
20
- class ExecutionModel extends database_1.Model {
21
- constructor() {
22
- super(...arguments);
23
- this.nodes = [];
24
- this.nodesMap = new Map();
25
- this.jobsMap = new Map();
26
- this.jobsMapByNodeId = {};
27
- }
28
- // make dual linked nodes list then cache
29
- makeNodes(nodes = []) {
30
- this.nodes = nodes;
31
- nodes.forEach((node) => {
32
- this.nodesMap.set(node.id, node);
33
- });
34
- nodes.forEach((node) => {
35
- if (node.upstreamId) {
36
- node.upstream = this.nodesMap.get(node.upstreamId);
37
- }
38
- if (node.downstreamId) {
39
- node.downstream = this.nodesMap.get(node.downstreamId);
40
- }
41
- });
42
- }
43
- makeJobs(jobs) {
44
- jobs.forEach((job) => {
45
- this.jobsMap.set(job.id, job);
46
- // TODO: should consider cycle, and from previous job
47
- this.jobsMapByNodeId[job.nodeId] = job.result;
48
- });
49
- }
50
- getTransaction() {
51
- const { sequelize } = this.constructor.database;
52
- // @ts-ignore
53
- if (!this.useTransaction) {
54
- return undefined;
55
- }
56
- const { options } = this;
77
+ nodes.forEach(node => {
78
+ if (node.upstreamId) {
79
+ node.upstream = this.nodesMap.get(node.upstreamId);
80
+ }
81
+
82
+ if (node.downstreamId) {
83
+ node.downstream = this.nodesMap.get(node.downstreamId);
84
+ }
85
+ });
86
+ }
87
+
88
+ makeJobs(jobs) {
89
+ jobs.forEach(job => {
90
+ this.jobsMap.set(job.id, job); // TODO: should consider cycle, and from previous job
91
+
92
+ this.jobsMapByNodeId[job.nodeId] = job.result;
93
+ });
94
+ }
95
+
96
+ getTransaction() {
97
+ var _this = this;
98
+
99
+ return _asyncToGenerator(function* () {
100
+ const sequelize = _this.constructor.database.sequelize;
101
+
102
+ if (!_this.useTransaction) {
103
+ return undefined;
104
+ }
105
+
106
+ const options = _this.options; // @ts-ignore
107
+
108
+ const transaction = options.transaction && !options.transaction.finished ? options.transaction : sequelize.transaction(); // @ts-ignore
109
+
110
+ if (_this.transaction !== transaction.id) {
57
111
  // @ts-ignore
58
- return options.transaction && !options.transaction.finished
59
- ? options.transaction
60
- : sequelize.transaction();
61
- }
62
- prepare(options, commit = false) {
63
- return __awaiter(this, void 0, void 0, function* () {
64
- this.options = options || {};
65
- // @ts-ignore
66
- const transaction = yield this.getTransaction();
67
- this.transaction = transaction;
68
- if (!this.workflow) {
69
- this.workflow = yield this.getWorkflow({ transaction });
70
- }
71
- const nodes = yield this.workflow.getNodes({ transaction });
72
- this.makeNodes(nodes);
73
- const jobs = yield this.getJobs({
74
- order: [['id', 'ASC']],
75
- transaction,
76
- });
77
- this.makeJobs(jobs);
78
- if (commit) {
79
- yield this.commit();
80
- }
112
+ yield _this.update({
113
+ transaction: transaction.id
114
+ }, {
115
+ transaction
81
116
  });
82
- }
83
- start(options) {
84
- return __awaiter(this, void 0, void 0, function* () {
85
- if (this.status !== constants_1.EXECUTION_STATUS.STARTED) {
86
- throw new Error(`execution was ended with status ${this.status}`);
87
- }
88
- yield this.prepare(options);
89
- if (this.nodes.length) {
90
- const head = this.nodes.find(item => !item.upstream);
91
- yield this.run(head, { result: this.context });
92
- }
93
- else {
94
- yield this.exit(null);
95
- }
96
- yield this.commit();
117
+ }
118
+
119
+ return transaction;
120
+ })();
121
+ }
122
+
123
+ prepare(options, commit = false) {
124
+ var _this2 = this;
125
+
126
+ return _asyncToGenerator(function* () {
127
+ _this2.options = options || {};
128
+ const transaction = yield _this2.getTransaction();
129
+ _this2.tx = transaction;
130
+
131
+ if (!_this2.workflow) {
132
+ _this2.workflow = yield _this2.getWorkflow({
133
+ transaction
97
134
  });
98
- }
99
- resume(job, options) {
100
- return __awaiter(this, void 0, void 0, function* () {
101
- if (this.status !== constants_1.EXECUTION_STATUS.STARTED) {
102
- throw new Error(`execution was ended with status ${this.status}`);
103
- }
104
- yield this.prepare(options);
105
- const node = this.nodesMap.get(job.nodeId);
106
- yield this.recall(node, job);
107
- yield this.commit();
108
- });
109
- }
110
- commit() {
111
- return __awaiter(this, void 0, void 0, function* () {
112
- // @ts-ignore
113
- if (this.transaction && (!this.options.transaction || this.options.transaction.finished)) {
114
- yield this.transaction.commit();
115
- }
135
+ }
136
+
137
+ const nodes = yield _this2.workflow.getNodes({
138
+ transaction
139
+ });
140
+
141
+ _this2.makeNodes(nodes);
142
+
143
+ const jobs = yield _this2.getJobs({
144
+ order: [['id', 'ASC']],
145
+ transaction
146
+ });
147
+
148
+ _this2.makeJobs(jobs);
149
+
150
+ if (commit) {
151
+ yield _this2.commit();
152
+ }
153
+ })();
154
+ }
155
+
156
+ start(options) {
157
+ var _this3 = this;
158
+
159
+ return _asyncToGenerator(function* () {
160
+ if (_this3.status !== _constants.EXECUTION_STATUS.STARTED) {
161
+ throw new Error(`execution was ended with status ${_this3.status}`);
162
+ }
163
+
164
+ yield _this3.prepare(options);
165
+
166
+ if (_this3.nodes.length) {
167
+ const head = _this3.nodes.find(item => !item.upstream);
168
+
169
+ yield _this3.run(head, {
170
+ result: _this3.context
116
171
  });
117
- }
118
- exec(instruction, node, prevJob) {
119
- return __awaiter(this, void 0, void 0, function* () {
120
- let job;
121
- try {
122
- // call instruction to get result and status
123
- job = yield instruction.call(node, prevJob, this);
124
- if (!job) {
125
- return null;
126
- }
127
- }
128
- catch (err) {
129
- // for uncaught error, set to rejected
130
- job = {
131
- result: err instanceof Error
132
- ? { message: err.message, stack: process.env.NODE_ENV === 'production' ? [] : err.stack }
133
- : err,
134
- status: constants_1.JOB_STATUS.REJECTED,
135
- };
136
- // if previous job is from resuming
137
- if (prevJob && prevJob.nodeId === node.id) {
138
- prevJob.set(job);
139
- job = prevJob;
140
- }
141
- }
142
- let savedJob;
143
- // TODO(optimize): many checking of resuming or new could be improved
144
- // could be implemented separately in exec() / resume()
145
- if (job instanceof database_1.Model) {
146
- savedJob = (yield job.save({ transaction: this.transaction }));
147
- }
148
- else {
149
- const upstreamId = prevJob instanceof database_1.Model ? prevJob.get('id') : null;
150
- savedJob = yield this.saveJob(Object.assign({ nodeId: node.id, upstreamId }, job));
151
- }
152
- if (savedJob.status === constants_1.JOB_STATUS.RESOLVED && node.downstream) {
153
- // run next node
154
- return this.run(node.downstream, savedJob);
155
- }
156
- // all nodes in scope have been executed
157
- return this.end(node, savedJob);
158
- });
159
- }
160
- run(node, input) {
161
- return __awaiter(this, void 0, void 0, function* () {
162
- const { run } = instructions_1.default.get(node.type);
163
- if (typeof run !== 'function') {
164
- return Promise.reject(new Error('`run` should be implemented for customized execution of the node'));
165
- }
166
- return this.exec(run, node, input);
167
- });
168
- }
169
- // parent node should take over the control
170
- end(node, job) {
171
- const parentNode = this.findBranchParentNode(node);
172
- // no parent, means on main flow
173
- if (parentNode) {
174
- return this.recall(parentNode, job);
172
+ } else {
173
+ yield _this3.exit(null);
174
+ }
175
+
176
+ yield _this3.commit();
177
+ })();
178
+ }
179
+
180
+ resume(job, options) {
181
+ var _this4 = this;
182
+
183
+ return _asyncToGenerator(function* () {
184
+ if (_this4.status !== _constants.EXECUTION_STATUS.STARTED) {
185
+ throw new Error(`execution was ended with status ${_this4.status}`);
186
+ }
187
+
188
+ yield _this4.prepare(options);
189
+
190
+ const node = _this4.nodesMap.get(job.nodeId);
191
+
192
+ yield _this4.recall(node, job);
193
+ yield _this4.commit();
194
+ })();
195
+ }
196
+
197
+ commit() {
198
+ var _this5 = this;
199
+
200
+ return _asyncToGenerator(function* () {
201
+ // @ts-ignore
202
+ if (_this5.tx && (!_this5.options.transaction || _this5.options.transaction.finished)) {
203
+ yield _this5.tx.commit();
204
+ }
205
+ })();
206
+ }
207
+
208
+ exec(instruction, node, prevJob) {
209
+ var _this6 = this;
210
+
211
+ return _asyncToGenerator(function* () {
212
+ let job;
213
+
214
+ try {
215
+ // call instruction to get result and status
216
+ job = yield instruction.call(node, prevJob, _this6);
217
+
218
+ if (!job) {
219
+ return null;
175
220
  }
176
- // really done for all nodes
177
- // * should mark execution as done with last job status
178
- return this.exit(job);
179
- }
180
- recall(node, job) {
181
- return __awaiter(this, void 0, void 0, function* () {
182
- const { resume } = instructions_1.default.get(node.type);
183
- if (typeof resume !== 'function') {
184
- return Promise.reject(new Error('`resume` should be implemented because the node made branch'));
185
- }
186
- return this.exec(resume, node, job);
187
- });
188
- }
189
- exit(job) {
190
- return __awaiter(this, void 0, void 0, function* () {
191
- const status = job ? ExecutionModel.StatusMap[job.status] : constants_1.EXECUTION_STATUS.RESOLVED;
192
- yield this.update({ status }, { transaction: this.transaction });
193
- return null;
194
- });
195
- }
196
- // TODO(optimize)
197
- saveJob(payload) {
198
- return __awaiter(this, void 0, void 0, function* () {
199
- const { database } = this.constructor;
200
- const { model } = database.getCollection('jobs');
201
- const [job] = (yield model.upsert(Object.assign(Object.assign({}, payload), { executionId: this.id }), { transaction: this.transaction }));
202
- this.jobsMap.set(job.id, job);
203
- this.jobsMapByNodeId[job.nodeId] = job.result;
204
- return job;
205
- });
206
- }
207
- // find the first node in current branch
208
- findBranchStartNode(node) {
209
- for (let n = node; n; n = n.upstream) {
210
- if (n.branchIndex !== null) {
211
- return n;
212
- }
221
+ } catch (err) {
222
+ // for uncaught error, set to rejected
223
+ job = {
224
+ result: err instanceof Error ? {
225
+ message: err.message,
226
+ stack: process.env.NODE_ENV === 'production' ? [] : err.stack
227
+ } : err,
228
+ status: _constants.JOB_STATUS.REJECTED
229
+ }; // if previous job is from resuming
230
+
231
+ if (prevJob && prevJob.nodeId === node.id) {
232
+ prevJob.set(job);
233
+ job = prevJob;
213
234
  }
214
- return null;
235
+ }
236
+
237
+ let savedJob; // TODO(optimize): many checking of resuming or new could be improved
238
+ // could be implemented separately in exec() / resume()
239
+
240
+ if (job instanceof _database().Model) {
241
+ savedJob = yield job.save({
242
+ transaction: _this6.tx
243
+ });
244
+ } else {
245
+ const upstreamId = prevJob instanceof _database().Model ? prevJob.get('id') : null;
246
+ savedJob = yield _this6.saveJob(_objectSpread({
247
+ nodeId: node.id,
248
+ upstreamId
249
+ }, job));
250
+ }
251
+
252
+ if (savedJob.status === _constants.JOB_STATUS.RESOLVED && node.downstream) {
253
+ // run next node
254
+ return _this6.run(node.downstream, savedJob);
255
+ } // all nodes in scope have been executed
256
+
257
+
258
+ return _this6.end(node, savedJob);
259
+ })();
260
+ }
261
+
262
+ run(node, input) {
263
+ var _this7 = this;
264
+
265
+ return _asyncToGenerator(function* () {
266
+ const _instructions$get = _instructions.default.get(node.type),
267
+ run = _instructions$get.run;
268
+
269
+ if (typeof run !== 'function') {
270
+ return Promise.reject(new Error('`run` should be implemented for customized execution of the node'));
271
+ }
272
+
273
+ return _this7.exec(run, node, input);
274
+ })();
275
+ } // parent node should take over the control
276
+
277
+
278
+ end(node, job) {
279
+ const parentNode = this.findBranchParentNode(node); // no parent, means on main flow
280
+
281
+ if (parentNode) {
282
+ return this.recall(parentNode, job);
283
+ } // really done for all nodes
284
+ // * should mark execution as done with last job status
285
+
286
+
287
+ return this.exit(job);
288
+ }
289
+
290
+ recall(node, job) {
291
+ var _this8 = this;
292
+
293
+ return _asyncToGenerator(function* () {
294
+ const _instructions$get2 = _instructions.default.get(node.type),
295
+ resume = _instructions$get2.resume;
296
+
297
+ if (typeof resume !== 'function') {
298
+ return Promise.reject(new Error('`resume` should be implemented because the node made branch'));
299
+ }
300
+
301
+ return _this8.exec(resume, node, job);
302
+ })();
303
+ }
304
+
305
+ exit(job) {
306
+ var _this9 = this;
307
+
308
+ return _asyncToGenerator(function* () {
309
+ const status = job ? ExecutionModel.StatusMap[job.status] : _constants.EXECUTION_STATUS.RESOLVED;
310
+ yield _this9.update({
311
+ status
312
+ }, {
313
+ transaction: _this9.tx
314
+ });
315
+ return null;
316
+ })();
317
+ } // TODO(optimize)
318
+
319
+
320
+ saveJob(payload) {
321
+ var _this10 = this;
322
+
323
+ return _asyncToGenerator(function* () {
324
+ const database = _this10.constructor.database;
325
+
326
+ const _database$getCollecti = database.getCollection('jobs'),
327
+ model = _database$getCollecti.model;
328
+
329
+ const _yield$model$upsert = yield model.upsert(_objectSpread(_objectSpread({}, payload), {}, {
330
+ executionId: _this10.id
331
+ }), {
332
+ transaction: _this10.tx
333
+ }),
334
+ _yield$model$upsert2 = _slicedToArray(_yield$model$upsert, 1),
335
+ job = _yield$model$upsert2[0];
336
+
337
+ _this10.jobsMap.set(job.id, job);
338
+
339
+ _this10.jobsMapByNodeId[job.nodeId] = job.result;
340
+ return job;
341
+ })();
342
+ } // find the first node in current branch
343
+
344
+
345
+ findBranchStartNode(node) {
346
+ for (let n = node; n; n = n.upstream) {
347
+ if (n.branchIndex !== null) {
348
+ return n;
349
+ }
215
350
  }
216
- // find the node start current branch
217
- findBranchParentNode(node) {
218
- for (let n = node; n; n = n.upstream) {
219
- if (n.branchIndex !== null) {
220
- return n.upstream;
221
- }
222
- }
223
- return null;
351
+
352
+ return null;
353
+ } // find the node start current branch
354
+
355
+
356
+ findBranchParentNode(node) {
357
+ for (let n = node; n; n = n.upstream) {
358
+ if (n.branchIndex !== null) {
359
+ return n.upstream;
360
+ }
224
361
  }
225
- findBranchParentJob(job, node) {
226
- for (let j = job; j; j = this.jobsMap.get(j.upstreamId)) {
227
- if (j.nodeId === node.id) {
228
- return j;
229
- }
230
- }
231
- return null;
362
+
363
+ return null;
364
+ }
365
+
366
+ findBranchParentJob(job, node) {
367
+ for (let j = job; j; j = this.jobsMap.get(j.upstreamId)) {
368
+ if (j.nodeId === node.id) {
369
+ return j;
370
+ }
232
371
  }
233
- getParsedValue(value, node) {
234
- const injectedFns = {};
235
- const scope = {
236
- execution: this,
237
- node
238
- };
239
- for (let [name, fn] of calculators_1.default.getEntities()) {
240
- injectedFns[name] = fn.bind(scope);
241
- }
242
- return (0, json_templates_1.default)(value)({
243
- $context: this.context,
244
- $jobsMapByNodeId: this.jobsMapByNodeId,
245
- $fn: injectedFns
246
- });
372
+
373
+ return null;
374
+ }
375
+
376
+ getParsedValue(value, node) {
377
+ const injectedFns = {};
378
+ const scope = {
379
+ execution: this,
380
+ node
381
+ };
382
+
383
+ var _iterator = _createForOfIteratorHelper(_calculators.default.getEntities()),
384
+ _step;
385
+
386
+ try {
387
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
388
+ let _step$value = _slicedToArray(_step.value, 2),
389
+ name = _step$value[0],
390
+ fn = _step$value[1];
391
+
392
+ injectedFns[name] = fn.bind(scope);
393
+ }
394
+ } catch (err) {
395
+ _iterator.e(err);
396
+ } finally {
397
+ _iterator.f();
247
398
  }
399
+
400
+ return (0, _jsonTemplates().default)(value)({
401
+ $context: this.context,
402
+ $jobsMapByNodeId: this.jobsMapByNodeId,
403
+ $fn: injectedFns
404
+ });
405
+ }
406
+
248
407
  }
408
+
249
409
  exports.default = ExecutionModel;
250
410
  ExecutionModel.StatusMap = {
251
- [constants_1.JOB_STATUS.PENDING]: constants_1.EXECUTION_STATUS.STARTED,
252
- [constants_1.JOB_STATUS.RESOLVED]: constants_1.EXECUTION_STATUS.RESOLVED,
253
- [constants_1.JOB_STATUS.REJECTED]: constants_1.EXECUTION_STATUS.REJECTED,
254
- [constants_1.JOB_STATUS.CANCELLED]: constants_1.EXECUTION_STATUS.CANCELLED,
255
- };
256
- //# sourceMappingURL=Execution.js.map
411
+ [_constants.JOB_STATUS.PENDING]: _constants.EXECUTION_STATUS.STARTED,
412
+ [_constants.JOB_STATUS.RESOLVED]: _constants.EXECUTION_STATUS.RESOLVED,
413
+ [_constants.JOB_STATUS.REJECTED]: _constants.EXECUTION_STATUS.REJECTED,
414
+ [_constants.JOB_STATUS.CANCELLED]: _constants.EXECUTION_STATUS.CANCELLED
415
+ };