@nocobase/plugin-workflow 0.7.0-alpha.34 → 0.7.0-alpha.57

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 (132) hide show
  1. package/lib/actions/index.js +31 -32
  2. package/lib/actions/nodes.js +310 -182
  3. package/lib/actions/workflows.js +260 -157
  4. package/lib/calculators/index.js +142 -90
  5. package/lib/collections/executions.js +40 -43
  6. package/lib/collections/flow_nodes.js +60 -65
  7. package/lib/collections/jobs.js +45 -47
  8. package/lib/collections/workflows.js +78 -87
  9. package/lib/constants.js +22 -17
  10. package/lib/index.js +71 -22
  11. package/lib/instructions/calculation.js +34 -29
  12. package/lib/instructions/condition.js +94 -87
  13. package/lib/instructions/create.js +43 -26
  14. package/lib/instructions/destroy.js +42 -25
  15. package/lib/instructions/index.js +46 -25
  16. package/lib/instructions/parallel.js +99 -84
  17. package/lib/instructions/prompt.js +21 -13
  18. package/lib/instructions/query.js +47 -29
  19. package/lib/instructions/update.js +44 -25
  20. package/lib/models/Execution.js +401 -248
  21. package/lib/models/FlowNode.js +18 -5
  22. package/lib/models/Job.js +18 -5
  23. package/lib/models/Workflow.js +132 -88
  24. package/lib/server.js +93 -66
  25. package/lib/triggers/collection.js +113 -51
  26. package/lib/triggers/index.js +25 -11
  27. package/package.json +7 -12
  28. package/esm/actions/index.d.ts +0 -1
  29. package/esm/actions/index.js +0 -14
  30. package/esm/actions/index.js.map +0 -1
  31. package/esm/actions/nodes.d.ts +0 -4
  32. package/esm/actions/nodes.js +0 -187
  33. package/esm/actions/nodes.js.map +0 -1
  34. package/esm/actions/workflows.d.ts +0 -3
  35. package/esm/actions/workflows.js +0 -163
  36. package/esm/actions/workflows.js.map +0 -1
  37. package/esm/calculators/index.d.ts +0 -38
  38. package/esm/calculators/index.js +0 -128
  39. package/esm/calculators/index.js.map +0 -1
  40. package/esm/collections/executions.d.ts +0 -3
  41. package/esm/collections/executions.js +0 -43
  42. package/esm/collections/executions.js.map +0 -1
  43. package/esm/collections/flow_nodes.d.ts +0 -3
  44. package/esm/collections/flow_nodes.js +0 -65
  45. package/esm/collections/flow_nodes.js.map +0 -1
  46. package/esm/collections/jobs.d.ts +0 -3
  47. package/esm/collections/jobs.js +0 -47
  48. package/esm/collections/jobs.js.map +0 -1
  49. package/esm/collections/workflows.d.ts +0 -3
  50. package/esm/collections/workflows.js +0 -87
  51. package/esm/collections/workflows.js.map +0 -1
  52. package/esm/constants.d.ts +0 -17
  53. package/esm/constants.js +0 -18
  54. package/esm/constants.js.map +0 -1
  55. package/esm/index.d.ts +0 -5
  56. package/esm/index.js +0 -6
  57. package/esm/index.js.map +0 -1
  58. package/esm/instructions/calculation.d.ts +0 -8
  59. package/esm/instructions/calculation.js +0 -55
  60. package/esm/instructions/calculation.js.map +0 -1
  61. package/esm/instructions/condition.d.ts +0 -5
  62. package/esm/instructions/condition.js +0 -99
  63. package/esm/instructions/condition.js.map +0 -1
  64. package/esm/instructions/create.d.ts +0 -8
  65. package/esm/instructions/create.js +0 -26
  66. package/esm/instructions/create.js.map +0 -1
  67. package/esm/instructions/destroy.d.ts +0 -8
  68. package/esm/instructions/destroy.js +0 -25
  69. package/esm/instructions/destroy.js.map +0 -1
  70. package/esm/instructions/index.d.ts +0 -15
  71. package/esm/instructions/index.js +0 -20
  72. package/esm/instructions/index.js.map +0 -1
  73. package/esm/instructions/parallel.d.ts +0 -13
  74. package/esm/instructions/parallel.js +0 -88
  75. package/esm/instructions/parallel.js.map +0 -1
  76. package/esm/instructions/prompt.d.ts +0 -7
  77. package/esm/instructions/prompt.js +0 -13
  78. package/esm/instructions/prompt.js.map +0 -1
  79. package/esm/instructions/query.d.ts +0 -8
  80. package/esm/instructions/query.js +0 -29
  81. package/esm/instructions/query.js.map +0 -1
  82. package/esm/instructions/update.d.ts +0 -9
  83. package/esm/instructions/update.js +0 -25
  84. package/esm/instructions/update.js.map +0 -1
  85. package/esm/models/Execution.d.ts +0 -51
  86. package/esm/models/Execution.js +0 -256
  87. package/esm/models/Execution.js.map +0 -1
  88. package/esm/models/FlowNode.d.ts +0 -17
  89. package/esm/models/FlowNode.js +0 -4
  90. package/esm/models/FlowNode.js.map +0 -1
  91. package/esm/models/Job.d.ts +0 -15
  92. package/esm/models/Job.js +0 -4
  93. package/esm/models/Job.js.map +0 -1
  94. package/esm/models/Workflow.d.ts +0 -29
  95. package/esm/models/Workflow.js +0 -88
  96. package/esm/models/Workflow.js.map +0 -1
  97. package/esm/server.d.ts +0 -5
  98. package/esm/server.js +0 -62
  99. package/esm/server.js.map +0 -1
  100. package/esm/triggers/collection.d.ts +0 -12
  101. package/esm/triggers/collection.js +0 -61
  102. package/esm/triggers/collection.js.map +0 -1
  103. package/esm/triggers/index.d.ts +0 -9
  104. package/esm/triggers/index.js +0 -6
  105. package/esm/triggers/index.js.map +0 -1
  106. package/lib/actions/index.js.map +0 -1
  107. package/lib/actions/nodes.js.map +0 -1
  108. package/lib/actions/workflows.js.map +0 -1
  109. package/lib/calculators/index.js.map +0 -1
  110. package/lib/collections/executions.js.map +0 -1
  111. package/lib/collections/flow_nodes.js.map +0 -1
  112. package/lib/collections/jobs.js.map +0 -1
  113. package/lib/collections/workflows.js.map +0 -1
  114. package/lib/constants.js.map +0 -1
  115. package/lib/index.js.map +0 -1
  116. package/lib/instructions/calculation.js.map +0 -1
  117. package/lib/instructions/condition.js.map +0 -1
  118. package/lib/instructions/create.js.map +0 -1
  119. package/lib/instructions/destroy.js.map +0 -1
  120. package/lib/instructions/index.js.map +0 -1
  121. package/lib/instructions/parallel.js.map +0 -1
  122. package/lib/instructions/prompt.js.map +0 -1
  123. package/lib/instructions/query.js.map +0 -1
  124. package/lib/instructions/update.js.map +0 -1
  125. package/lib/models/Execution.js.map +0 -1
  126. package/lib/models/FlowNode.js.map +0 -1
  127. package/lib/models/Job.js.map +0 -1
  128. package/lib/models/Workflow.js.map +0 -1
  129. package/lib/server.js.map +0 -1
  130. package/lib/triggers/collection.js.map +0 -1
  131. package/lib/triggers/index.js.map +0 -1
  132. package/tsconfig.build.json +0 -9
@@ -1,15 +0,0 @@
1
- import { Registry } from '@nocobase/utils';
2
- import ExecutionModel from '../models/Execution';
3
- import FlowNodeModel from '../models/FlowNode';
4
- export interface Job {
5
- status: number;
6
- result?: unknown;
7
- [key: string]: unknown;
8
- }
9
- export declare type InstructionResult = Job | Promise<Job>;
10
- export interface Instruction {
11
- run(this: FlowNodeModel, input: any, execution: ExecutionModel): InstructionResult;
12
- resume?(this: FlowNodeModel, input: any, execution: ExecutionModel): InstructionResult;
13
- }
14
- export declare const instructions: Registry<Instruction>;
15
- export default instructions;
@@ -1,20 +0,0 @@
1
- import { Registry } from '@nocobase/utils';
2
- import prompt from './prompt';
3
- import calculation from './calculation';
4
- import condition from './condition';
5
- import parallel from './parallel';
6
- import query from './query';
7
- import create from './create';
8
- import update from './update';
9
- import destroy from './destroy';
10
- export const instructions = new Registry();
11
- instructions.register('prompt', prompt);
12
- instructions.register('calculation', calculation);
13
- instructions.register('condition', condition);
14
- instructions.register('parallel', parallel);
15
- instructions.register('query', query);
16
- instructions.register('create', create);
17
- instructions.register('update', update);
18
- instructions.register('destroy', destroy);
19
- export default instructions;
20
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/instructions/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAK3C,OAAO,MAAM,MAAM,UAAU,CAAC;AAC9B,OAAO,WAAW,MAAM,eAAe,CAAC;AACxC,OAAO,SAAS,MAAM,aAAa,CAAC;AACpC,OAAO,QAAQ,MAAM,YAAY,CAAC;AAClC,OAAO,KAAK,MAAM,SAAS,CAAC;AAC5B,OAAO,MAAM,MAAM,UAAU,CAAC;AAC9B,OAAO,MAAM,MAAM,UAAU,CAAC;AAC9B,OAAO,OAAO,MAAM,WAAW,CAAC;AA+BhC,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,QAAQ,EAAe,CAAC;AAExD,YAAY,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;AACxC,YAAY,CAAC,QAAQ,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC;AAClD,YAAY,CAAC,QAAQ,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;AAC9C,YAAY,CAAC,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;AAC5C,YAAY,CAAC,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;AACtC,YAAY,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;AACxC,YAAY,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;AACxC,YAAY,CAAC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;AAE1C,eAAe,YAAY,CAAC","sourcesContent":["import { Registry } from '@nocobase/utils';\n\nimport ExecutionModel from '../models/Execution';\nimport FlowNodeModel from '../models/FlowNode';\n\nimport prompt from './prompt';\nimport calculation from './calculation';\nimport condition from './condition';\nimport parallel from './parallel';\nimport query from './query';\nimport create from './create';\nimport update from './update';\nimport destroy from './destroy';\n\nexport interface Job {\n status: number;\n result?: unknown;\n [key: string]: unknown;\n}\n\nexport type InstructionResult = Job | Promise<Job>;\n\n// what should a instruction do?\n// - base on input and context, do any calculations or system call (io), and produce a result or pending.\nexport interface Instruction {\n run(\n this: FlowNodeModel,\n // what should input to be?\n // - just use previously output result for convenience?\n input: any,\n // what should context to be?\n // - could be the workflow execution object (containing context data)\n execution: ExecutionModel\n ): InstructionResult;\n\n // for start node in main flow (or branch) to resume when manual sub branch triggered\n resume?(\n this: FlowNodeModel,\n input: any,\n execution: ExecutionModel\n ): InstructionResult\n}\n\nexport const instructions = new Registry<Instruction>();\n\ninstructions.register('prompt', prompt);\ninstructions.register('calculation', calculation);\ninstructions.register('condition', condition);\ninstructions.register('parallel', parallel);\ninstructions.register('query', query);\ninstructions.register('create', create);\ninstructions.register('update', update);\ninstructions.register('destroy', destroy);\n\nexport default instructions;\n"]}
@@ -1,13 +0,0 @@
1
- import ExecutionModel from "../models/Execution";
2
- import FlowNodeModel from "../models/FlowNode";
3
- import JobModel from "../models/Job";
4
- export declare const PARALLEL_MODE: {
5
- readonly ALL: "all";
6
- readonly ANY: "any";
7
- readonly RACE: "race";
8
- };
9
- declare const _default: {
10
- run(this: FlowNodeModel, prevJob: JobModel, execution: ExecutionModel): Promise<any>;
11
- resume(this: any, branchJob: any, execution: ExecutionModel): Promise<any>;
12
- };
13
- export default _default;
@@ -1,88 +0,0 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
- import { JOB_STATUS } from "../constants";
11
- export const PARALLEL_MODE = {
12
- ALL: 'all',
13
- ANY: 'any',
14
- RACE: 'race'
15
- };
16
- const StatusGetters = {
17
- [PARALLEL_MODE.ALL](result) {
18
- if (result.some(j => j && j.status === JOB_STATUS.REJECTED)) {
19
- return JOB_STATUS.REJECTED;
20
- }
21
- if (result.every(j => j && j.status === JOB_STATUS.RESOLVED)) {
22
- return JOB_STATUS.RESOLVED;
23
- }
24
- return JOB_STATUS.PENDING;
25
- },
26
- [PARALLEL_MODE.ANY](result) {
27
- return result.some(j => j && j.status === JOB_STATUS.RESOLVED)
28
- ? JOB_STATUS.RESOLVED
29
- : (result.some(j => j && j.status === JOB_STATUS.PENDING)
30
- ? JOB_STATUS.PENDING
31
- : JOB_STATUS.REJECTED);
32
- },
33
- [PARALLEL_MODE.RACE](result) {
34
- return result.some(j => j && j.status === JOB_STATUS.RESOLVED)
35
- ? JOB_STATUS.RESOLVED
36
- : (result.some(j => j && j.status === JOB_STATUS.REJECTED)
37
- ? JOB_STATUS.REJECTED
38
- : JOB_STATUS.PENDING);
39
- }
40
- };
41
- export default {
42
- run(prevJob, execution) {
43
- var _a;
44
- return __awaiter(this, void 0, void 0, function* () {
45
- const branches = execution.nodes
46
- .filter(item => item.upstream === this && item.branchIndex !== null)
47
- .sort((a, b) => a.branchIndex - b.branchIndex);
48
- const job = yield execution.saveJob({
49
- status: JOB_STATUS.PENDING,
50
- result: Array(branches.length).fill(null),
51
- nodeId: this.id,
52
- upstreamId: (_a = prevJob === null || prevJob === void 0 ? void 0 : prevJob.id) !== null && _a !== void 0 ? _a : null
53
- });
54
- // NOTE:
55
- // use `reduce` but not `Promise.all` here to avoid racing manupulating db.
56
- // for users, this is almost equivalent to `Promise.all`,
57
- // because of the delay is not significant sensible.
58
- // another better aspect of this is, it could handle sequenced branches in future.
59
- yield branches.reduce((promise, branch) => promise.then(() => execution.run(branch, job)), Promise.resolve());
60
- return execution.end(this, job);
61
- });
62
- },
63
- resume(branchJob, execution) {
64
- return __awaiter(this, void 0, void 0, function* () {
65
- const job = execution.findBranchParentJob(branchJob, this);
66
- const { result, status } = job;
67
- // if parallel has been done (resolved / rejected), do not care newly executed branch jobs.
68
- if (status !== JOB_STATUS.PENDING) {
69
- return null;
70
- }
71
- // find the index of the node which start the branch
72
- const jobNode = execution.nodesMap.get(branchJob.nodeId);
73
- const { branchIndex } = execution.findBranchStartNode(jobNode);
74
- const { mode = PARALLEL_MODE.ALL } = this.config || {};
75
- const newResult = [...result.slice(0, branchIndex), branchJob.get(), ...result.slice(branchIndex + 1)];
76
- job.set({
77
- result: newResult,
78
- status: StatusGetters[mode](newResult)
79
- });
80
- if (job.status === JOB_STATUS.PENDING) {
81
- yield job.save({ transaction: execution.tx });
82
- return execution.end(this, job);
83
- }
84
- return job;
85
- });
86
- }
87
- };
88
- //# sourceMappingURL=parallel.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"parallel.js","sourceRoot":"","sources":["../../src/instructions/parallel.ts"],"names":[],"mappings":"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","sourcesContent":["import { JOB_STATUS } from \"../constants\";\nimport ExecutionModel from \"../models/Execution\";\nimport FlowNodeModel from \"../models/FlowNode\";\nimport JobModel from \"../models/Job\";\n\nexport const PARALLEL_MODE = {\n ALL: 'all',\n ANY: 'any',\n RACE: 'race'\n} as const;\n\nconst StatusGetters = {\n [PARALLEL_MODE.ALL](result) {\n if (result.some(j => j && j.status === JOB_STATUS.REJECTED)) {\n return JOB_STATUS.REJECTED;\n }\n if (result.every(j => j && j.status === JOB_STATUS.RESOLVED)) {\n return JOB_STATUS.RESOLVED;\n }\n return JOB_STATUS.PENDING;\n },\n [PARALLEL_MODE.ANY](result) {\n return result.some(j => j && j.status === JOB_STATUS.RESOLVED)\n ? JOB_STATUS.RESOLVED\n : (\n result.some(j => j && j.status === JOB_STATUS.PENDING)\n ? JOB_STATUS.PENDING\n : JOB_STATUS.REJECTED\n )\n },\n [PARALLEL_MODE.RACE](result) {\n return result.some(j => j && j.status === JOB_STATUS.RESOLVED)\n ? JOB_STATUS.RESOLVED\n : (\n result.some(j => j && j.status === JOB_STATUS.REJECTED)\n ? JOB_STATUS.REJECTED\n : JOB_STATUS.PENDING\n )\n }\n};\n\nexport default {\n async run(this: FlowNodeModel, prevJob: JobModel, execution: ExecutionModel) {\n const branches = execution.nodes\n .filter(item => item.upstream === this && item.branchIndex !== null)\n .sort((a, b) => a.branchIndex - b.branchIndex);\n\n const job = await execution.saveJob({\n status: JOB_STATUS.PENDING,\n result: Array(branches.length).fill(null),\n nodeId: this.id,\n upstreamId: prevJob?.id ?? null\n });\n\n // NOTE:\n // use `reduce` but not `Promise.all` here to avoid racing manupulating db.\n // for users, this is almost equivalent to `Promise.all`,\n // because of the delay is not significant sensible.\n // another better aspect of this is, it could handle sequenced branches in future.\n await branches.reduce((promise: Promise<any>, branch) => promise.then(() => execution.run(branch, job)), Promise.resolve());\n\n return execution.end(this, job);\n },\n\n async resume(this, branchJob, execution: ExecutionModel) {\n const job = execution.findBranchParentJob(branchJob, this);\n\n const { result, status } = job;\n // if parallel has been done (resolved / rejected), do not care newly executed branch jobs.\n if (status !== JOB_STATUS.PENDING) {\n return null;\n }\n\n // find the index of the node which start the branch\n const jobNode = execution.nodesMap.get(branchJob.nodeId);\n const { branchIndex } = execution.findBranchStartNode(jobNode);\n const { mode = PARALLEL_MODE.ALL } = this.config || {};\n\n const newResult = [...result.slice(0, branchIndex), branchJob.get(), ...result.slice(branchIndex + 1)];\n job.set({\n result: newResult,\n status: StatusGetters[mode](newResult)\n });\n\n if (job.status === JOB_STATUS.PENDING) {\n await job.save({ transaction: execution.tx });\n return execution.end(this, job);\n }\n\n return job;\n }\n};\n"]}
@@ -1,7 +0,0 @@
1
- declare const _default: {
2
- run(this: any, input: any, execution: any): {
3
- status: number;
4
- };
5
- resume(this: any, job: any, execution: any): any;
6
- };
7
- export default _default;
@@ -1,13 +0,0 @@
1
- import { JOB_STATUS } from "../constants";
2
- export default {
3
- run(input, execution) {
4
- return {
5
- status: JOB_STATUS.PENDING
6
- };
7
- },
8
- resume(job, execution) {
9
- job.set('status', JOB_STATUS.RESOLVED);
10
- return job;
11
- }
12
- };
13
- //# sourceMappingURL=prompt.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../src/instructions/prompt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,eAAe;IACb,GAAG,CAAO,KAAK,EAAE,SAAS;QACxB,OAAO;YACL,MAAM,EAAE,UAAU,CAAC,OAAO;SAC3B,CAAC;IACJ,CAAC;IAED,MAAM,CAAO,GAAG,EAAE,SAAS;QACzB,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC;QACvC,OAAO,GAAG,CAAC;IACb,CAAC;CACF,CAAC","sourcesContent":["import { JOB_STATUS } from \"../constants\";\n\nexport default {\n run(this, input, execution) {\n return {\n status: JOB_STATUS.PENDING\n };\n },\n\n resume(this, job, execution) {\n job.set('status', JOB_STATUS.RESOLVED);\n return job;\n }\n};\n"]}
@@ -1,8 +0,0 @@
1
- import FlowNodeModel from "../models/FlowNode";
2
- declare const _default: {
3
- run(this: FlowNodeModel, input: any, execution: any): Promise<{
4
- result: any;
5
- status: number;
6
- }>;
7
- };
8
- export default _default;
@@ -1,29 +0,0 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
- import { JOB_STATUS } from "../constants";
11
- export default {
12
- run(input, execution) {
13
- return __awaiter(this, void 0, void 0, function* () {
14
- const { collection, multiple, params = {} } = this.config;
15
- const repo = this.constructor.database.getRepository(collection);
16
- const options = execution.getParsedValue(params);
17
- const result = yield (multiple ? repo.find : repo.findOne).call(repo, Object.assign(Object.assign({}, options), {
18
- // NOTE: `raw` to avoid getting undefined value from Proxied model instance (#380)
19
- // e.g. Object.prototype.hasOwnProperty.call(result, 'id') // false
20
- // so the properties can not be get by json-templates(object-path)
21
- raw: true, transaction: execution.tx }));
22
- return {
23
- result,
24
- status: JOB_STATUS.RESOLVED
25
- };
26
- });
27
- }
28
- };
29
- //# sourceMappingURL=query.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"query.js","sourceRoot":"","sources":["../../src/instructions/query.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAG1C,eAAe;IACP,GAAG,CAAsB,KAAK,EAAE,SAAS;;YAC7C,MAAM,EACJ,UAAU,EACV,QAAQ,EACR,MAAM,GAAG,EAAE,EACZ,GAAG,IAAI,CAAC,MAAM,CAAC;YAEhB,MAAM,IAAI,GAA0B,IAAI,CAAC,WAAY,CAAC,QAAQ,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;YACzF,MAAM,OAAO,GAAG,SAAS,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;YACjD,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,kCAC/D,OAAO;gBACV,kFAAkF;gBAClF,mEAAmE;gBACnE,kEAAkE;gBAClE,GAAG,EAAE,IAAI,EACT,WAAW,EAAE,SAAS,CAAC,EAAE,IACzB,CAAC;YAEH,OAAO;gBACL,MAAM;gBACN,MAAM,EAAE,UAAU,CAAC,QAAQ;aAC5B,CAAC;QACJ,CAAC;KAAA;CACF,CAAC","sourcesContent":["import { JOB_STATUS } from \"../constants\";\nimport FlowNodeModel from \"../models/FlowNode\";\n\nexport default {\n async run(this: FlowNodeModel, input, execution) {\n const {\n collection,\n multiple,\n params = {}\n } = this.config;\n\n const repo = (<typeof FlowNodeModel>this.constructor).database.getRepository(collection);\n const options = execution.getParsedValue(params);\n const result = await (multiple ? repo.find : repo.findOne).call(repo, {\n ...options,\n // NOTE: `raw` to avoid getting undefined value from Proxied model instance (#380)\n // e.g. Object.prototype.hasOwnProperty.call(result, 'id') // false\n // so the properties can not be get by json-templates(object-path)\n raw: true,\n transaction: execution.tx\n });\n\n return {\n result,\n status: JOB_STATUS.RESOLVED\n };\n }\n};\n"]}
@@ -1,9 +0,0 @@
1
- import ExecutionModel from "../models/Execution";
2
- import FlowNodeModel from "../models/FlowNode";
3
- declare const _default: {
4
- run(this: FlowNodeModel, input: any, execution: ExecutionModel): Promise<{
5
- result: import("@nocobase/database").Model<any, any> | import("@nocobase/database").Model<any, any>[];
6
- status: number;
7
- }>;
8
- };
9
- export default _default;
@@ -1,25 +0,0 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
- import { JOB_STATUS } from "../constants";
11
- export default {
12
- run(input, execution) {
13
- return __awaiter(this, void 0, void 0, function* () {
14
- const { collection, multiple = false, params = {} } = this.config;
15
- const repo = this.constructor.database.getRepository(collection);
16
- const options = execution.getParsedValue(params);
17
- const result = yield repo.update(Object.assign(Object.assign({}, options), { transaction: execution.tx }));
18
- return {
19
- result: multiple ? result : (result[0] || null),
20
- status: JOB_STATUS.RESOLVED
21
- };
22
- });
23
- }
24
- };
25
- //# sourceMappingURL=update.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"update.js","sourceRoot":"","sources":["../../src/instructions/update.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAI1C,eAAe;IACP,GAAG,CAAsB,KAAK,EAAE,SAAyB;;YAC7D,MAAM,EACJ,UAAU,EACV,QAAQ,GAAG,KAAK,EAChB,MAAM,GAAG,EAAE,EACZ,GAAG,IAAI,CAAC,MAAM,CAAC;YAEhB,MAAM,IAAI,GAA0B,IAAI,CAAC,WAAY,CAAC,QAAQ,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;YACzF,MAAM,OAAO,GAAG,SAAS,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;YACjD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,iCAC3B,OAAO,KACV,WAAW,EAAE,SAAS,CAAC,EAAE,IACzB,CAAC;YAEH,OAAO;gBACL,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;gBAC/C,MAAM,EAAE,UAAU,CAAC,QAAQ;aAC5B,CAAC;QACJ,CAAC;KAAA;CACF,CAAA","sourcesContent":["import { JOB_STATUS } from \"../constants\";\nimport ExecutionModel from \"../models/Execution\";\nimport FlowNodeModel from \"../models/FlowNode\";\n\nexport default {\n async run(this: FlowNodeModel, input, execution: ExecutionModel) {\n const {\n collection,\n multiple = false,\n params = {}\n } = this.config;\n\n const repo = (<typeof FlowNodeModel>this.constructor).database.getRepository(collection);\n const options = execution.getParsedValue(params);\n const result = await repo.update({\n ...options,\n transaction: execution.tx\n });\n\n return {\n result: multiple ? result : (result[0] || null),\n status: JOB_STATUS.RESOLVED\n };\n }\n}\n"]}
@@ -1,51 +0,0 @@
1
- import { Database, Model } from '@nocobase/database';
2
- import { BelongsToGetAssociationMixin, HasManyGetAssociationsMixin, Transaction } from 'sequelize';
3
- import WorkflowModel from './Workflow';
4
- import FlowNodeModel from './FlowNode';
5
- import JobModel from './Job';
6
- export interface ExecutionOptions {
7
- transaction?: Transaction;
8
- }
9
- export default class ExecutionModel extends Model {
10
- static readonly database: Database;
11
- id: number;
12
- title: string;
13
- context: any;
14
- status: number;
15
- useTransaction: boolean;
16
- transaction: string;
17
- createdAt: Date;
18
- updatedAt: Date;
19
- workflow?: WorkflowModel;
20
- getWorkflow: BelongsToGetAssociationMixin<WorkflowModel>;
21
- jobs?: JobModel[];
22
- getJobs: HasManyGetAssociationsMixin<JobModel>;
23
- options: ExecutionOptions;
24
- tx: Transaction;
25
- nodes: Array<FlowNodeModel>;
26
- nodesMap: Map<number, FlowNodeModel>;
27
- jobsMap: Map<number, JobModel>;
28
- jobsMapByNodeId: {
29
- [key: number]: any;
30
- };
31
- static StatusMap: {
32
- [x: number]: number;
33
- };
34
- makeNodes(nodes?: any[]): void;
35
- makeJobs(jobs: Array<JobModel>): void;
36
- getTransaction(): Promise<Transaction>;
37
- prepare(options: any, commit?: boolean): Promise<void>;
38
- start(options: ExecutionOptions): Promise<void>;
39
- resume(job: JobModel, options: ExecutionOptions): Promise<void>;
40
- private commit;
41
- private exec;
42
- run(node: any, input?: any): any;
43
- end(node: any, job: any): any;
44
- recall(node: any, job: any): any;
45
- exit(job: JobModel | null): Promise<any>;
46
- saveJob(payload: any): Promise<JobModel>;
47
- findBranchStartNode(node: FlowNodeModel): FlowNodeModel | null;
48
- findBranchParentNode(node: FlowNodeModel): FlowNodeModel | null;
49
- findBranchParentJob(job: JobModel, node: FlowNodeModel): JobModel | null;
50
- getParsedValue(value: any, node?: any): any;
51
- }
@@ -1,256 +0,0 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
- import { Model } from '@nocobase/database';
11
- import parse from 'json-templates';
12
- import { EXECUTION_STATUS, JOB_STATUS } from '../constants';
13
- import instructions from '../instructions';
14
- import calculators from '../calculators';
15
- export default class ExecutionModel extends Model {
16
- constructor() {
17
- super(...arguments);
18
- this.nodes = [];
19
- this.nodesMap = new Map();
20
- this.jobsMap = new Map();
21
- this.jobsMapByNodeId = {};
22
- }
23
- // make dual linked nodes list then cache
24
- makeNodes(nodes = []) {
25
- this.nodes = nodes;
26
- nodes.forEach((node) => {
27
- this.nodesMap.set(node.id, node);
28
- });
29
- nodes.forEach((node) => {
30
- if (node.upstreamId) {
31
- node.upstream = this.nodesMap.get(node.upstreamId);
32
- }
33
- if (node.downstreamId) {
34
- node.downstream = this.nodesMap.get(node.downstreamId);
35
- }
36
- });
37
- }
38
- makeJobs(jobs) {
39
- jobs.forEach((job) => {
40
- this.jobsMap.set(job.id, job);
41
- // TODO: should consider cycle, and from previous job
42
- this.jobsMapByNodeId[job.nodeId] = job.result;
43
- });
44
- }
45
- getTransaction() {
46
- return __awaiter(this, void 0, void 0, function* () {
47
- const { sequelize } = this.constructor.database;
48
- if (!this.useTransaction) {
49
- return undefined;
50
- }
51
- const { options } = this;
52
- // @ts-ignore
53
- const transaction = options.transaction && !options.transaction.finished
54
- ? options.transaction
55
- : sequelize.transaction();
56
- // @ts-ignore
57
- if (this.transaction !== transaction.id) {
58
- // @ts-ignore
59
- yield this.update({ transaction: transaction.id }, { transaction });
60
- }
61
- return transaction;
62
- });
63
- }
64
- prepare(options, commit = false) {
65
- return __awaiter(this, void 0, void 0, function* () {
66
- this.options = options || {};
67
- const transaction = yield this.getTransaction();
68
- this.tx = transaction;
69
- if (!this.workflow) {
70
- this.workflow = yield this.getWorkflow({ transaction });
71
- }
72
- const nodes = yield this.workflow.getNodes({ transaction });
73
- this.makeNodes(nodes);
74
- const jobs = yield this.getJobs({
75
- order: [['id', 'ASC']],
76
- transaction,
77
- });
78
- this.makeJobs(jobs);
79
- if (commit) {
80
- yield this.commit();
81
- }
82
- });
83
- }
84
- start(options) {
85
- return __awaiter(this, void 0, void 0, function* () {
86
- if (this.status !== EXECUTION_STATUS.STARTED) {
87
- throw new Error(`execution was ended with status ${this.status}`);
88
- }
89
- yield this.prepare(options);
90
- if (this.nodes.length) {
91
- const head = this.nodes.find(item => !item.upstream);
92
- yield this.run(head, { result: this.context });
93
- }
94
- else {
95
- yield this.exit(null);
96
- }
97
- yield this.commit();
98
- });
99
- }
100
- resume(job, options) {
101
- return __awaiter(this, void 0, void 0, function* () {
102
- if (this.status !== EXECUTION_STATUS.STARTED) {
103
- throw new Error(`execution was ended with status ${this.status}`);
104
- }
105
- yield this.prepare(options);
106
- const node = this.nodesMap.get(job.nodeId);
107
- yield this.recall(node, job);
108
- yield this.commit();
109
- });
110
- }
111
- commit() {
112
- return __awaiter(this, void 0, void 0, function* () {
113
- // @ts-ignore
114
- if (this.tx && (!this.options.transaction || this.options.transaction.finished)) {
115
- yield this.tx.commit();
116
- }
117
- });
118
- }
119
- exec(instruction, node, prevJob) {
120
- return __awaiter(this, void 0, void 0, function* () {
121
- let job;
122
- try {
123
- // call instruction to get result and status
124
- job = yield instruction.call(node, prevJob, this);
125
- if (!job) {
126
- return null;
127
- }
128
- }
129
- catch (err) {
130
- // for uncaught error, set to rejected
131
- job = {
132
- result: err instanceof Error
133
- ? { message: err.message, stack: process.env.NODE_ENV === 'production' ? [] : err.stack }
134
- : err,
135
- status: JOB_STATUS.REJECTED,
136
- };
137
- // if previous job is from resuming
138
- if (prevJob && prevJob.nodeId === node.id) {
139
- prevJob.set(job);
140
- job = prevJob;
141
- }
142
- }
143
- let savedJob;
144
- // TODO(optimize): many checking of resuming or new could be improved
145
- // could be implemented separately in exec() / resume()
146
- if (job instanceof Model) {
147
- savedJob = (yield job.save({ transaction: this.tx }));
148
- }
149
- else {
150
- const upstreamId = prevJob instanceof Model ? prevJob.get('id') : null;
151
- savedJob = yield this.saveJob(Object.assign({ nodeId: node.id, upstreamId }, job));
152
- }
153
- if (savedJob.status === JOB_STATUS.RESOLVED && node.downstream) {
154
- // run next node
155
- return this.run(node.downstream, savedJob);
156
- }
157
- // all nodes in scope have been executed
158
- return this.end(node, savedJob);
159
- });
160
- }
161
- run(node, input) {
162
- return __awaiter(this, void 0, void 0, function* () {
163
- const { run } = instructions.get(node.type);
164
- if (typeof run !== 'function') {
165
- return Promise.reject(new Error('`run` should be implemented for customized execution of the node'));
166
- }
167
- return this.exec(run, node, input);
168
- });
169
- }
170
- // parent node should take over the control
171
- end(node, job) {
172
- const parentNode = this.findBranchParentNode(node);
173
- // no parent, means on main flow
174
- if (parentNode) {
175
- return this.recall(parentNode, job);
176
- }
177
- // really done for all nodes
178
- // * should mark execution as done with last job status
179
- return this.exit(job);
180
- }
181
- recall(node, job) {
182
- return __awaiter(this, void 0, void 0, function* () {
183
- const { resume } = instructions.get(node.type);
184
- if (typeof resume !== 'function') {
185
- return Promise.reject(new Error('`resume` should be implemented because the node made branch'));
186
- }
187
- return this.exec(resume, node, job);
188
- });
189
- }
190
- exit(job) {
191
- return __awaiter(this, void 0, void 0, function* () {
192
- const status = job ? ExecutionModel.StatusMap[job.status] : EXECUTION_STATUS.RESOLVED;
193
- yield this.update({ status }, { transaction: this.tx });
194
- return null;
195
- });
196
- }
197
- // TODO(optimize)
198
- saveJob(payload) {
199
- return __awaiter(this, void 0, void 0, function* () {
200
- const { database } = this.constructor;
201
- const { model } = database.getCollection('jobs');
202
- const [job] = (yield model.upsert(Object.assign(Object.assign({}, payload), { executionId: this.id }), { transaction: this.tx }));
203
- this.jobsMap.set(job.id, job);
204
- this.jobsMapByNodeId[job.nodeId] = job.result;
205
- return job;
206
- });
207
- }
208
- // find the first node in current branch
209
- findBranchStartNode(node) {
210
- for (let n = node; n; n = n.upstream) {
211
- if (n.branchIndex !== null) {
212
- return n;
213
- }
214
- }
215
- return null;
216
- }
217
- // find the node start current branch
218
- findBranchParentNode(node) {
219
- for (let n = node; n; n = n.upstream) {
220
- if (n.branchIndex !== null) {
221
- return n.upstream;
222
- }
223
- }
224
- return null;
225
- }
226
- findBranchParentJob(job, node) {
227
- for (let j = job; j; j = this.jobsMap.get(j.upstreamId)) {
228
- if (j.nodeId === node.id) {
229
- return j;
230
- }
231
- }
232
- return null;
233
- }
234
- getParsedValue(value, node) {
235
- const injectedFns = {};
236
- const scope = {
237
- execution: this,
238
- node
239
- };
240
- for (let [name, fn] of calculators.getEntities()) {
241
- injectedFns[name] = fn.bind(scope);
242
- }
243
- return parse(value)({
244
- $context: this.context,
245
- $jobsMapByNodeId: this.jobsMapByNodeId,
246
- $fn: injectedFns
247
- });
248
- }
249
- }
250
- ExecutionModel.StatusMap = {
251
- [JOB_STATUS.PENDING]: EXECUTION_STATUS.STARTED,
252
- [JOB_STATUS.RESOLVED]: EXECUTION_STATUS.RESOLVED,
253
- [JOB_STATUS.REJECTED]: EXECUTION_STATUS.REJECTED,
254
- [JOB_STATUS.CANCELLED]: EXECUTION_STATUS.CANCELLED,
255
- };
256
- //# sourceMappingURL=Execution.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Execution.js","sourceRoot":"","sources":["../../src/models/Execution.ts"],"names":[],"mappings":"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","sourcesContent":["import { Database, Model } from '@nocobase/database';\nimport parse from 'json-templates';\nimport { BelongsToGetAssociationMixin, HasManyGetAssociationsMixin, Transaction } from 'sequelize';\nimport { EXECUTION_STATUS, JOB_STATUS } from '../constants';\nimport instructions from '../instructions';\nimport WorkflowModel from './Workflow';\nimport FlowNodeModel from './FlowNode';\nimport JobModel from './Job';\nimport calculators from '../calculators';\n\nexport interface ExecutionOptions {\n transaction?: Transaction;\n}\n\nexport default class ExecutionModel extends Model {\n declare static readonly database: Database;\n\n declare id: number;\n declare title: string;\n declare context: any;\n declare status: number;\n // NOTE: this duplicated column is for transaction in preparing cycle from workflow\n declare useTransaction: boolean;\n declare transaction: string;\n\n declare createdAt: Date;\n declare updatedAt: Date;\n\n declare workflow?: WorkflowModel;\n declare getWorkflow: BelongsToGetAssociationMixin<WorkflowModel>;\n\n declare jobs?: JobModel[];\n declare getJobs: HasManyGetAssociationsMixin<JobModel>;\n\n options: ExecutionOptions;\n\n tx: Transaction;\n\n nodes: Array<FlowNodeModel> = [];\n nodesMap = new Map<number, FlowNodeModel>();\n jobsMap = new Map<number, JobModel>();\n jobsMapByNodeId: { [key: number]: any } = {};\n\n static StatusMap = {\n [JOB_STATUS.PENDING]: EXECUTION_STATUS.STARTED,\n [JOB_STATUS.RESOLVED]: EXECUTION_STATUS.RESOLVED,\n [JOB_STATUS.REJECTED]: EXECUTION_STATUS.REJECTED,\n [JOB_STATUS.CANCELLED]: EXECUTION_STATUS.CANCELLED,\n };\n\n // make dual linked nodes list then cache\n makeNodes(nodes = []) {\n this.nodes = nodes;\n\n nodes.forEach((node) => {\n this.nodesMap.set(node.id, node);\n });\n\n nodes.forEach((node) => {\n if (node.upstreamId) {\n node.upstream = this.nodesMap.get(node.upstreamId);\n }\n\n if (node.downstreamId) {\n node.downstream = this.nodesMap.get(node.downstreamId);\n }\n });\n }\n\n makeJobs(jobs: Array<JobModel>) {\n jobs.forEach((job) => {\n this.jobsMap.set(job.id, job);\n // TODO: should consider cycle, and from previous job\n this.jobsMapByNodeId[job.nodeId] = job.result;\n });\n }\n\n async getTransaction() {\n const { sequelize } = (<typeof ExecutionModel>this.constructor).database;\n\n if (!this.useTransaction) {\n return undefined;\n }\n\n const { options } = this;\n\n // @ts-ignore\n const transaction = options.transaction && !options.transaction.finished\n ? options.transaction\n : sequelize.transaction();\n\n // @ts-ignore\n if (this.transaction !== transaction.id) {\n // @ts-ignore\n await this.update({ transaction: transaction.id }, { transaction });\n }\n return transaction;\n }\n\n async prepare(options, commit = false) {\n this.options = options || {};\n const transaction = await this.getTransaction();\n this.tx = transaction;\n\n if (!this.workflow) {\n this.workflow = await this.getWorkflow({ transaction });\n }\n\n const nodes = await this.workflow.getNodes({ transaction });\n\n this.makeNodes(nodes);\n\n const jobs = await this.getJobs({\n order: [['id', 'ASC']],\n transaction,\n });\n\n this.makeJobs(jobs);\n\n if (commit) {\n await this.commit();\n }\n }\n\n public async start(options: ExecutionOptions) {\n if (this.status !== EXECUTION_STATUS.STARTED) {\n throw new Error(`execution was ended with status ${this.status}`);\n }\n await this.prepare(options);\n if (this.nodes.length) {\n const head = this.nodes.find(item => !item.upstream);\n await this.run(head, { result: this.context });\n } else {\n await this.exit(null);\n }\n await this.commit();\n }\n\n public async resume(job: JobModel, options: ExecutionOptions) {\n if (this.status !== EXECUTION_STATUS.STARTED) {\n throw new Error(`execution was ended with status ${this.status}`);\n }\n await this.prepare(options);\n const node = this.nodesMap.get(job.nodeId);\n await this.recall(node, job);\n await this.commit();\n }\n\n private async commit() {\n // @ts-ignore\n if (this.tx && (!this.options.transaction || this.options.transaction.finished)) {\n await this.tx.commit();\n }\n }\n\n private async exec(instruction: Function, node: FlowNodeModel, prevJob) {\n let job;\n try {\n // call instruction to get result and status\n job = await instruction.call(node, prevJob, this);\n if (!job) {\n return null;\n }\n } catch (err) {\n // for uncaught error, set to rejected\n job = {\n result: err instanceof Error\n ? { message: err.message, stack: process.env.NODE_ENV === 'production' ? [] : err.stack }\n : err,\n status: JOB_STATUS.REJECTED,\n };\n // if previous job is from resuming\n if (prevJob && prevJob.nodeId === node.id) {\n prevJob.set(job);\n job = prevJob;\n }\n }\n\n let savedJob;\n // TODO(optimize): many checking of resuming or new could be improved\n // could be implemented separately in exec() / resume()\n if (job instanceof Model) {\n savedJob = (await job.save({ transaction: this.tx })) as unknown as JobModel;\n } else {\n const upstreamId = prevJob instanceof Model ? prevJob.get('id') : null;\n savedJob = await this.saveJob({\n nodeId: node.id,\n upstreamId,\n ...job,\n });\n }\n\n if (savedJob.status === JOB_STATUS.RESOLVED && node.downstream) {\n // run next node\n return this.run(node.downstream, savedJob);\n }\n\n // all nodes in scope have been executed\n return this.end(node, savedJob);\n }\n\n public async run(node, input?) {\n const { run } = instructions.get(node.type);\n if (typeof run !== 'function') {\n return Promise.reject(new Error('`run` should be implemented for customized execution of the node'));\n }\n\n return this.exec(run, node, input);\n }\n\n // parent node should take over the control\n public end(node, job) {\n const parentNode = this.findBranchParentNode(node);\n // no parent, means on main flow\n if (parentNode) {\n return this.recall(parentNode, job);\n }\n\n // really done for all nodes\n // * should mark execution as done with last job status\n return this.exit(job);\n }\n\n async recall(node, job) {\n const { resume } = instructions.get(node.type);\n if (typeof resume !== 'function') {\n return Promise.reject(new Error('`resume` should be implemented because the node made branch'));\n }\n\n return this.exec(resume, node, job);\n }\n\n async exit(job: JobModel | null) {\n const status = job ? ExecutionModel.StatusMap[job.status] : EXECUTION_STATUS.RESOLVED;\n await this.update({ status }, { transaction: this.tx });\n return null;\n }\n\n // TODO(optimize)\n async saveJob(payload) {\n const { database } = <typeof ExecutionModel>this.constructor;\n const { model } = database.getCollection('jobs');\n const [job] = (await model.upsert(\n {\n ...payload,\n executionId: this.id,\n },\n { transaction: this.tx },\n )) as unknown as [JobModel, boolean | null];\n this.jobsMap.set(job.id, job);\n this.jobsMapByNodeId[job.nodeId] = job.result;\n\n return job;\n }\n\n // find the first node in current branch\n findBranchStartNode(node: FlowNodeModel): FlowNodeModel | null {\n for (let n = node; n; n = n.upstream) {\n if (n.branchIndex !== null) {\n return n;\n }\n }\n return null;\n }\n\n // find the node start current branch\n findBranchParentNode(node: FlowNodeModel): FlowNodeModel | null {\n for (let n = node; n; n = n.upstream) {\n if (n.branchIndex !== null) {\n return n.upstream;\n }\n }\n return null;\n }\n\n findBranchParentJob(job: JobModel, node: FlowNodeModel): JobModel | null {\n for (let j = job; j; j = this.jobsMap.get(j.upstreamId)) {\n if (j.nodeId === node.id) {\n return j;\n }\n }\n return null;\n }\n\n public getParsedValue(value, node?) {\n const injectedFns = {};\n const scope = {\n execution: this,\n node\n };\n for (let [name, fn] of calculators.getEntities()) {\n injectedFns[name] = fn.bind(scope);\n }\n\n return parse(value)({\n $context: this.context,\n $jobsMapByNodeId: this.jobsMapByNodeId,\n $fn: injectedFns\n });\n }\n}\n"]}
@@ -1,17 +0,0 @@
1
- import { Database, Model } from '@nocobase/database';
2
- import { BelongsToGetAssociationMixin } from 'sequelize';
3
- import WorkflowModel from './Workflow';
4
- export default class FlowNodeModel extends Model {
5
- static readonly database: Database;
6
- id: number;
7
- title: string;
8
- branchIndex: null | number;
9
- type: string;
10
- config: any;
11
- createdAt: Date;
12
- updatedAt: Date;
13
- upstream: FlowNodeModel;
14
- downstream: FlowNodeModel;
15
- workflow?: WorkflowModel;
16
- getWorkflow: BelongsToGetAssociationMixin<WorkflowModel>;
17
- }
@@ -1,4 +0,0 @@
1
- import { Model } from '@nocobase/database';
2
- export default class FlowNodeModel extends Model {
3
- }
4
- //# sourceMappingURL=FlowNode.js.map