UNPKG

co-compose

Version:

AdonisJS and Koa style middleware layer with ability to run parallel middleware

86 lines (85 loc) 2.44 kB
"use strict"; /* * co-compose * * (c) Harminder Virk <virk@adonisjs.com> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.Runnable = void 0; /** * Default final handler resolves the middleware chain right away */ const DEFAULT_FINAL_HANDLER = { fn: () => Promise.resolve(), args: [], }; /** * The default executor to execute middlewares. This method assumes middleware * as functions and calls them right away */ const DEFAULT_EXECUTOR = (fn, params) => fn(...params); /** * Runnable to execute an array of functions in sequence. The queue is * advanced only when the current function calls `next`. * * @example * ```js * const runner = new Runnable([async function fn1 (params, next) { * }]) * ``` */ class Runnable { constructor(list) { this.list = list; this.index = 0; this.params = []; this.executorFn = DEFAULT_EXECUTOR; this.registeredFinalHandler = DEFAULT_FINAL_HANDLER; } /** * Invoke one middleware at a time. Middleware fns will be executed * recursively until `next` is invoked. * * If one method doesn't call `next`, then the chain will be finished * automatically. */ invoke() { const fn = this.list[this.index++]; /** * Empty stack */ if (!fn) { return this.registeredFinalHandler.fn(...this.registeredFinalHandler.args); } return this.executorFn(fn, this.params); } /** * Final handler to be executed, when chain ends successfully */ finalHandler(fn, args) { this.registeredFinalHandler = { fn, args }; return this; } /** * Define custom resolver, which is invoked for all the middleware. * If this method is defined, then default executor is not called * and it's the responsibility of this method to call the * middleware and pass params to it */ executor(fn) { this.executorFn = fn; return this; } /** * Start the middleware queue and pass params to it. The `params` * array will be passed as spread arguments. */ async run(params) { this.params = params.concat(this.invoke.bind(this)); return this.invoke(); } } exports.Runnable = Runnable;