@supercharge/pipeline
Version:
Run a pipeline of async tasks
113 lines (112 loc) • 2.7 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Pipeline = void 0;
const classes_1 = require("@supercharge/classes");
class Pipeline {
/**
* Create a new pipeline instance for the given `pipeable`.
*/
constructor(pipeable) {
/**
* The array of class or function pipes.
*/
this.pipes = [];
/**
* The method called on each pipe.
*/
this.method = 'handle';
this.pipeable = pipeable;
}
/**
* Set the value that will be passed throught the pipeline.
*
* @param {*} pipeable
*
* @returns {Pipeline}
*/
static send(pipeable) {
return new this(pipeable);
}
/**
* Set the array of pipes.
*
* @param {Array} pipes
*
* @returns {Pipeline}
*/
through(...pipes) {
this.pipes = [].concat(...pipes);
return this;
}
/**
* Set the method name to call on the pipes.
*
* @param {String} method
*
* @returns {Pipeline}
*/
via(method) {
this.method = method;
return this;
}
/**
* Run the pipeline and return the result.
*
* @returns {*}
*/
async thenReturn() {
return await this.then((result) => {
return result;
});
}
/**
* Run the pipeline with a final destination `callback`.
*
* @param {Function} callback
*
* @returns {*}
*/
async then(callback) {
let intermediate = this.initial();
for (const pipe of this.pipes) {
intermediate = await this.handle(pipe, intermediate) || intermediate;
}
return callback(intermediate);
}
/**
* Returns the closure function to reduce the pipeline.
*
* @returns {Function}
*/
handle(pipe, intermediate) {
if (classes_1.isClass(pipe)) {
return this.handleClass(pipe, intermediate);
}
if (classes_1.isFunction(pipe)) {
// @ts-expect-error
return pipe(intermediate);
}
throw new Error(`Pipeline tasks must be classes or functions. Received ${typeof pipe}`);
}
/**
* Instantiate the given `Pipe` class and call the handle method.
*
* @param {Class} Pipe
* @param {*} parameters
*
* @returns {*}
*/
handleClass(Pipe, parameters) {
const instance = new Pipe(parameters);
return instance[this.method]();
}
/**
* Returns the initial pipeline value.
*
* @returns {*}
*/
initial() {
return this.pipeable;
}
}
exports.Pipeline = Pipeline;