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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@8pattern/jmiddleware

v0.0.3

Published

Organize your functions just like Koa or Express

Readme

jMiddleware

Platform: Node/Web

Organize your functions just like Koa or Express

If you are familar with the middleware framework of Koa or Express, Differences From Koa may be more suitable to acquaint the package.

Hello, jMiddleware

  import JMiddleware from '@8pattern/jmiddleware'
  const jMiddleware = new JMiddleware();
  jMiddleware.use(async (_, next) => {
    const start = Date.now();
    await next();
    console.log(Date.now() - start);
  });
  jMiddleware.startAsync();

Usage

  • Install
  npm i @8pattern/jmiddleware
  • Import
  import JMiddleware from '@8pattern/jmiddleware'
  • Instantiate
  const jMiddleware = new JMiddleware();
  • Register middlewares
  jMiddleware.use((_, next) => {
    const start = Date.now();
    next();
    console.log(Date.now() - start);
  });
  • Start
  jMiddleware.startSync();

APIs

Constructor

Context

Type: any

Default: undefined

A variable with any types can be defined when getting the instance, which can't be re-asigned in middlewares.

  const Context = {};
  const jMiddleware = new JMiddleware(Context);
  jMiddleware.use((_, next, ctx) => {
    console.assert(ctx === Context);
    next();
  });
  jMiddleware.startSync();

It is not necessary.

  const jMiddleware = new JMiddleware();
  jMiddleware.use((_, next, ctx) => {
    console.assert(ctx === undefined);
    next();
  });
  jMiddleware.startSync();

Middleware

Middlewares will receive three parameters and also can return a value.

Parameter: value

Type: unknown

Default: last asigned value

If a middleware want to change the value of the next one, it can tranfer a value to the callback function.

  jMiddleware.use((_, next) => {
    next(1);
  });
  jMiddleware.use<number>(v => {
    console.assert(v === 1);
  });
  jMiddleware.startSync();

If not receiving a value from the previous middleware, the last one will make effect.

  jMiddleware.use((_, next) => {
    next(1);
  });
  jMiddleware.use((v, next) => {
    console.assert(v === 1);
    next(); // not tranfer a value
  });
  jMiddleware.use<number>(v => {
    console.assert(v === 1);
  });
  jMiddleware.startSync();

Parameter: callback function

Type: (val?: any) => unknown

Default: -

It will transfer control to the next middleware. It can change the value of the next middleware by the argument and receiving the return from the next middleware.

  jMiddleware.use((_, next) => {
    const res = next(1);
    console.assert(res === 2)
  });
  jMiddleware.use<number>(v => {
    console.assert(v === 1);
    return 2;
  });
  jMiddleware.startSync();

Parameter: context

Type: any

Default: undefined

It is defined when instantiation.

  const Context = {};
  const jMiddleware = new JMiddleware(Context);
  jMiddleware.use((_, next, ctx) => {
    console.assert(ctx === context);
    next();
  });
  jMiddleware.startSync();

Return

Type: any

Default: undefined

Any middlewares are able to return a value to the previous one (for the first middleware, its return value will be regarded as the final result).

  jMiddleware.use((v, next) => {
    const val = `1-before ${v}`;
    const res = next(val);
    return `${res} 1-after`;
  });
  jMiddleware.use((v, next) => {
    const val = `2-before ${v}`;
    const res = next(val);
    return `${res} 2-after`;
  });
  const res = jMiddleware.startSync('0');
  console.log(res); // 2-before 1-before 0 2-after 1-after

Entry

When defining the middlewares, the package provides two methods to start the process: startSync and startAsync. The only difference is the startAsync regards all middlewares as asynchronous methods but startSync regards middlewares as synchronous methods.

  jMiddleware.use((_, next) => next());
  console.assert(jMiddleware.startSync() === undefined);
  console.assert(jMiddleware.startAsync() instanceof Promise);

Differences From Koa

The package is inspired by Koa, but it isn't designed for web applications, which accounts for some diferences.

Parameters

In Koa, middlewares receive two parameters: a context and a callback function. And the context parameter is a complex object to fit web applications. But in this package, middlewares have three parameters.

The first parameter is a variable can be asigned with any types.

  // Koa
  app.use(ctx => {
    ctx.body = 'Hello Koa';
  });

  // jMiddleware
  jMiddleware.use(val => {
    console.log(val); // 'any value'
  });
  jMiddleware.startAsync('any value');

The second parameter is a callback function which can transfer the value to the next middleware.

  // Koa
  app.use(async (ctx, next) => {
    await next();
  });

  // jMiddleware
  jMiddleware.use(async (val, next) => {
    await next('any value from prev middleware')
  });
  jMiddleware.use(val => {
    console.log(val); // 'any value from prev middleware'
  });
  jMiddleware.startAsync();

Since the package aims to organize functions in a way of middlewares, we make its parameters more flexiable. If you are familar with the way of Koa, you can asign a object as the initial value.

  // jMiddleware
  jMiddleware.use(val => {
    val.body = 'Hello';
  });
  jMiddleware.startAsync({});

The third parameter is a varaible which only can be assigned when instantiation.

  // jMiddleware
  const jMiddleware = new JMiddleware('any value');
  jMiddleware.use((_, next, ctx) => {
    console.log(ctx); // any value;
  });
  jMiddleware.startAsync();

Async or Sync

In Koa,middlewares are designed as asynchronous methods. But in the package, asynchronous and synchronous methods are both allowed. Besides some scenarios where synchronous methods are more suitable, async / await keywords can be avoided when using synchronous methods. The switch are how you start the middlewares.

  // Async
  jMiddleware.use(async (_, next) => {
    await next();
  }); 
  jMiddleware.startAsync();

  // Sync
  jMiddleware.use((_, next) => {
    next();
  }); 
  jMiddleware.startSync();

Return

Koa doesn't need return values, which are allowed in this package. The rule is any middleware will return a value to its previous middleware (for the first middleware, its return value will be regarded as the final result).

  jMiddleware.use((v, next) => {
    const val = `1-before ${v}`;
    const res = next(val);
    return `${res} 1-after`;
  });
  jMiddleware.use((v, next) => {
    const val = `2-before ${v}`;
    const res = next(val);
    return `${res} 2-after`;
  });
  const res = jMiddleware.startSync('0');
  console.log(res); // 2-before 1-before 0 2-after 1-after