UNPKG

@rarible/action

Version:

Action is almost like async function, but actions can be divided into steps. It gives more control over action execution.

70 lines (69 loc) 2.25 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Execution = void 0; const tslib_1 = require("tslib"); class Execution { constructor(input, steps) { this.input = input; this.steps = steps; this.state = new Array(steps.length); this.promises = new Array(steps.length); } get ids() { return this.steps.map(s => s.id); } runAll() { return tslib_1.__awaiter(this, void 0, void 0, function* () { for (let i = 0; i < this.ids.length; i++) { yield this.run(i); } const last = this.state[this.ids.length - 1]; if (last.status === "resolved") { return last.value; } else { throw new Error("Should never happen"); } }); } run(idx) { if (idx === 0) { return this.runInternal(idx, this.input); } if (idx >= this.steps.length) { throw new Error(`Stage with index ${idx} not found`); } const prevState = this.state[idx - 1]; if (prevState == null) { throw new Error(`Stage ${idx - 1} hasn't been run yet`); } if (prevState.status !== "resolved") { throw new Error(`Stage ${idx - 1} status is: ${prevState.status}`); } return this.runInternal(idx, prevState.value); } runInternal(idx, input) { const state = this.state[idx]; if (state != null && (state.status === "pending" || state.status === "resolved")) { return this.promises[idx]; } else { this.state[idx] = { status: "pending" }; const promise = this.steps[idx].run(input); this.promises[idx] = promise .then(r => { this.state[idx] = { status: "resolved", value: r }; return r; }) .catch(err => { this.state[idx] = { status: "rejected", error: err }; return Promise.reject(err); }); return this.promises[idx]; } } get result() { return this.runAll(); } } exports.Execution = Execution;