npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

middleware-engine

v0.1.1

Published

A lightweight engine that provides middleware functionality to classes that extend it.

Downloads

6

Readme

Middleware-Engine

A lightweight engine that provides middleware functionality to classes that extend it.

Quick Start

You must extend the MiddlewareEngine class to use its functionality.

const MiddlewareEngine = require(`middleware-engine`);

class HelloWorld extends MiddlewareEngine {

	constructor () {
		super({ /* Config for Middleware-Engine goes here... */ });
	}

	printMessage (messages) {
		return Promise.resolve()
			.then(() => this.__executeHandler(`some-handler-id`, messages))
			.then(() => this.__executeMiddleware(messages))
			.then(() => this.__executeHandler(`another-handler-id`, messages))
			.then(() => console.log(messages.join(`\n`)));
	}

}

const instance = new HelloWorld();

instance.configure(`some-handler-id`, someHandlerMiddleware());  // Executed 1st.
instance.configure(`another-handler-id`, anotherHandlerMiddleware()); // Executed 4th.

instance.use(someMiddleware());  // Executed 2nd.
instance.use(someOtherMiddleware()); // Executed 3rd.

instance.printMessage([`This is a message.`, `This is yet another message.`])
	.catch(err => console.error(err));

For a fully-featured example take a look at the source code for the Ultimail module.

API Overview

const engine = new MiddlewareEngine(config);

You must extend the MiddlewareEngine class and call the this.__executeMiddleware() or this.__executeHandler() methods to use its functionality.

#### Config Options You can supply the following config to the constructor.

| Config | Default Value | Description | |--------------------------|---------------|-------------| | chainMiddlewareResults | false | Set to true to pass the result of the previous middleware execution to the next middleware function as the second to last parameter. | | throwOnMissingHandler | true | Set to false to prevent an error being thrown if you call this.__executeHandler() on a handler ID that hasn't been configured. | | throwOnMissingDependency | true | Set to false to prevent an error being thrown if you call this.__dep() for a dependency that hasn't been injected. |

engine.use(func1, func2, ...funcN);

Can be used externally by the consumer of your class. Add a number of middleware functions by providing one or more arguments. You can call .use() as many times as you like or with as many arguments as you like. The middleware is always executed in the order you add them.

engine.configure(handlerId, func1, func2, ...funcN);

Can be used externally by the consumer of your class. Add named handler middleware that should be executed at a specific point by your class, either before or after the general middleware added with .use(). You can only call this method once for each handlerId, if you call it a second time the handler will be replaced.

engine.isConfigured(handlerId);

Can be used externally by the consumer of your class. Returns true if the given handler ID has been configured with the .configure() method.

engine.requires()

Returns an array of required dependencies configured by your class (i.e. added to the this.requirements array).

engine.inject(dependencyName, dependencyObject);

Can be used externally by the consumer of your class. Allows you to inject a dependency into your class which can be accessed inside your class by calling this.__dep() (see below). You can inject as many dependencies as you like by calling this method multiple times.

engine.areDependenciesSatisfied()

Returns true if all the dependencies configured by your class have been injected.

engine.hasDependency(dependencyName)

Returns true if the given dependency has been injected.

this.__executeMiddleware(primaryValue, arg1, arg2, ...argN);

Only to be used internally by your class. Call this to execute all the middleware that has been added by the consumer via the .use() method. Middleware is always executed in the order it was added.

You can pass as many parameters as you like to this method and they will all be passed to each middleware function. You can use the primaryValue parameter to pass in an object/array that you want shared between each of the middleware functions (similar to how you can access the request and response objects in every Express.js middleware).

Default Middleware signature

function (primaryValue, arg1, arg2, ...argN, next, stop) { ... }.

You must call the next(err, result) callback at the end of every middleware or your application will hang. Alternatively, if you're waiting for all the middleware to complete and the promise to be resolved before continuing execution in your application you can use the stop() method to immediately resolve the promise. You can also pass an error to stop(err).

Alternative Middleware Signature

function (primaryValue, ...argN, previousResult, next, stop) { ... }

The result of the previous middleware execution will be available as the second to last parameter previousResult if the config option chainMiddlewareResults is set in the constructor.

this.__executeHandler(handlerId, primaryValue, arg1, arg2, ...argN);

Only to be used internally by your class. Call this to execute only the middleware functions configured as part of the named handler with .configure(). Middleware is always executed in the order it was added.

You can pass as many parameters as you like to this method and they will all be passed to each middleware function. You can use the primaryValue parameter to pass in an object/array that you want shared between each of the middleware functions (similar to how you can access the request and response objects in every Express.js middleware).

By default, if the handler ID has not been configured an error will be thrown. You can silently swallow the error instead by setting the throwOnMissingHandler config to false in the constructor.

Default Middleware signature

function (primaryValue, arg1, arg2, ...argN, next, stop) { ... }

You must call the next(err, result) callback at the end of every middleware or your application will hang. Alternatively, if you're waiting for all the middleware to complete and the promise to be resolved before continuing execution in your application you can use the stop() method to immediately resolve the promise. You can also pass an error to stop(err).

Alternative Middleware Signature

function (primaryValue, ...argN, previousResult, next, stop) { ... }.

The result of the previous middleware execution will be available as the second to last parameter previousResult if the config option chainMiddlewareResults is set to true in the constructor.

this.__dep(dependencyName);

Only to be used internally by your class. Returns the given injected dependency.