middlewarer v1.0.0
Middlewarer
Middleware execution chain library.
Creates callable middleware chains, similar to those used by express#use.
Callbacks in the chain are passed a variable number of arguments followed by a next callback which can
be called to pass execution on to the next callback in the chain.
This library also exposes TypeScript helper types (and Async variants) Callable, Consumer, Provider, and Runnable,
similar to those from Java.
Installation
$ yarn add middlewareror, with NPM
$ npm install middlewarerUsage
CommonJS:
const { AsyncController, Controller } = require("middlewarer");ES Modules/TypeScript:
import { AsyncController, Controller } from "middlewarer";Controller#chain(callback: (...args, next) => any): Controller
Adds a callback to the chain. next is a callback which invokes the
next callback in the chain and should be called by your callback
except in conditions where the chain should be stopped. next does not accept any parameters.
If you wish to maintain a shared state between chain steps, you should modify an
external variable or pass a state object to Controller#run.
Controller#run(...args): Controller
Starts the chain execution. Note: if all functions in the chain are synchronous,
then this call will also be synchronous. However, if any function is
asynchronous in how it calls next(), then this function will return once that
async execution begins.
If you need to perform all asynchronous functions before returning from run,
use an AsyncController instead.
AsyncController#chain(callback: (...args, next) => Promise<any>): AsyncController
Identical to Controller#chain, except callback should be Promise-returning and next is asynchrnous, and thus should be called with await.
AsyncController#run(...args): Promise<AsyncController>
Similar to Controller#run. Executes and awaits all chained callbacks.
Synchronous Example
import { Controller, Runnable } from "middlewarer";
const controller = new Controller<[number]>(); // Callback parameter type array
controller
.chain((num, next) => {
console.log(`Chain 0: ${num}`);
next(); // Continues chain
})
.chain((num, next) => {
console.log(`Chain 1: ${num}`);
if (num === 42) next(); // Only continue chain if num is 42
})
.chain((num, next) => {
console.log(`The answer has been found. You just lost The Game.`);
});
// ... Later (or in function chain), call the controller
controller.run(4); // Will get to chain 0 and 1, but not the answer
controller.run(42); // Will trigger all three chained callbacksAsynchronous Example
import { AsyncController, Runnable } from "middlewarer";
// A dummy representing an asynchronous API call
async function checkAnswer(value: number): Promise<boolean> {
return value === 42;
}
const controller = new AsyncController<[number]>();
controller
.chain(async (num, next) => {
console.log(`Chain 0: ${num}`);
await next();
})
.chain(async (num, next) => {
console.log(`Chain 1: ${num}`);
if (await checkAnswer(num)) await next(); // Continue dependent on async API result
})
.chain(async (num, next) => {
console.log(`The answer has been found. You just lost The Game.`);
});
await controller.run(4);
await controller.run(42);License
Licensed under the GNU Affero General Public License v3.0 license.
See LICENSE in the root of this project or https://www.gnu.org/licenses/agpl-3.0.en.html for more info.
Copyright © 2020 Brenden Campbell.
5 years ago