2022-03-27 07:51:48 +00:00
|
|
|
import calculators, { calculate, Operand } from "../calculators";
|
2022-01-25 18:27:23 +00:00
|
|
|
import { JOB_STATUS } from "../constants";
|
2022-01-09 14:22:26 +00:00
|
|
|
|
|
|
|
type BaseCalculation = {
|
|
|
|
not?: boolean;
|
|
|
|
};
|
|
|
|
|
|
|
|
type SingleCalculation = BaseCalculation & {
|
|
|
|
calculation: string;
|
|
|
|
operands?: Operand[];
|
|
|
|
};
|
|
|
|
|
|
|
|
type GroupCalculationOptions = {
|
|
|
|
type: 'and' | 'or';
|
|
|
|
calculations: Calculation[]
|
|
|
|
};
|
|
|
|
|
|
|
|
type GroupCalculation = BaseCalculation & {
|
|
|
|
group: GroupCalculationOptions
|
|
|
|
};
|
|
|
|
|
|
|
|
// TODO(type)
|
|
|
|
type Calculation = SingleCalculation | GroupCalculation;
|
|
|
|
|
2022-02-27 14:58:41 +00:00
|
|
|
// @calculation: {
|
|
|
|
// not: false,
|
|
|
|
// group: {
|
|
|
|
// type: 'and',
|
|
|
|
// calculations: [
|
|
|
|
// {
|
|
|
|
// calculator: 'time.equal',
|
|
|
|
// operands: [{ value: '{{$context.time}}' }, { value: '{{$fn.now}}' }]
|
|
|
|
// },
|
|
|
|
// {
|
|
|
|
// calculator: 'value.equal',
|
|
|
|
// operands: [{ value: '{{$jobsMapByNodeId.213}}' }, { value: 1 }]
|
|
|
|
// },
|
|
|
|
// {
|
|
|
|
// group: {
|
|
|
|
// type: 'or',
|
|
|
|
// calculations: [
|
|
|
|
// {
|
|
|
|
// calculator: 'value.equal',
|
|
|
|
// operands: [{ value: '{{$jobsMapByNodeId.213}}' }, { value: 1 }]
|
|
|
|
// }
|
|
|
|
// ]
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// ]
|
|
|
|
// }
|
|
|
|
// }
|
2022-06-20 15:29:21 +00:00
|
|
|
function logicCalculate(calculation, input, processor) {
|
2022-02-27 14:58:41 +00:00
|
|
|
if (!calculation) {
|
2022-01-09 14:22:26 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2022-02-27 14:58:41 +00:00
|
|
|
const { not, group } = calculation;
|
2022-01-09 14:22:26 +00:00
|
|
|
let result;
|
|
|
|
if (group) {
|
|
|
|
const method = group.type === 'and' ? 'every' : 'some';
|
2022-06-20 15:29:21 +00:00
|
|
|
result = group.calculations[method](item => logicCalculate(item, input, processor));
|
2022-01-09 14:22:26 +00:00
|
|
|
} else {
|
2022-06-20 15:29:21 +00:00
|
|
|
const args = calculation.operands.map(operand => calculate(operand, input, processor));
|
2022-02-27 14:58:41 +00:00
|
|
|
const fn = calculators.get(calculation.calculator);
|
2022-01-09 14:22:26 +00:00
|
|
|
if (!fn) {
|
2022-02-27 14:58:41 +00:00
|
|
|
throw new Error(`no calculator function registered for "${calculation.calculator}"`);
|
2022-01-09 14:22:26 +00:00
|
|
|
}
|
|
|
|
result = fn(...args);
|
|
|
|
}
|
|
|
|
|
|
|
|
return not ? !result : result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export default {
|
2022-06-20 15:29:21 +00:00
|
|
|
async run(this, prevJob, processor) {
|
|
|
|
// TODO(optimize): loading of jobs could be reduced and turned into incrementally in processor
|
|
|
|
// const jobs = await processor.getJobs();
|
2022-02-27 14:58:41 +00:00
|
|
|
const { calculation, rejectOnFalse } = this.config || {};
|
2022-06-20 15:29:21 +00:00
|
|
|
const result = logicCalculate(calculation, prevJob, processor);
|
2022-01-25 18:27:23 +00:00
|
|
|
|
2022-02-27 14:58:41 +00:00
|
|
|
if (!result && rejectOnFalse) {
|
2022-01-25 18:27:23 +00:00
|
|
|
return {
|
|
|
|
status: JOB_STATUS.REJECTED,
|
|
|
|
result
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
const job = {
|
|
|
|
status: JOB_STATUS.RESOLVED,
|
|
|
|
result,
|
|
|
|
// TODO(optimize): try unify the building of job
|
2022-01-27 16:25:26 +00:00
|
|
|
nodeId: this.id,
|
2022-02-27 14:58:41 +00:00
|
|
|
upstreamId: prevJob && prevJob.id || null
|
2022-01-25 18:27:23 +00:00
|
|
|
};
|
|
|
|
|
2022-06-20 15:29:21 +00:00
|
|
|
const branchNode = processor.nodes
|
2022-01-27 16:25:26 +00:00
|
|
|
.find(item => item.upstream === this && Boolean(item.branchIndex) === result);
|
2022-01-25 18:27:23 +00:00
|
|
|
|
|
|
|
if (!branchNode) {
|
|
|
|
return job;
|
|
|
|
}
|
|
|
|
|
2022-06-20 15:29:21 +00:00
|
|
|
const savedJob = await processor.saveJob(job);
|
2022-01-25 18:27:23 +00:00
|
|
|
|
2022-06-20 15:29:21 +00:00
|
|
|
return processor.run(branchNode, savedJob);
|
2022-01-25 18:27:23 +00:00
|
|
|
},
|
|
|
|
|
2022-06-20 15:29:21 +00:00
|
|
|
async resume(this, branchJob, processor) {
|
2022-01-25 18:27:23 +00:00
|
|
|
if (branchJob.status === JOB_STATUS.RESOLVED) {
|
2022-02-01 04:04:08 +00:00
|
|
|
// return to continue this.downstream
|
|
|
|
return branchJob;
|
2022-01-25 18:27:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// pass control to upper scope by ending current scope
|
2022-06-20 15:29:21 +00:00
|
|
|
return processor.end(this, branchJob);
|
2022-01-09 14:22:26 +00:00
|
|
|
}
|
2022-02-27 14:58:41 +00:00
|
|
|
};
|