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 🙏

© 2024 – Pkg Stats / Ryan Hefner

ctx-compose

v3.0.0

Published

Take off 'koa' from 'koa-compose' and make it universal.

Downloads

21

Readme

ctx-compose

NPM version Dependency Status License Downloads

:globe_with_meridians: Universal middleware composing library based on koajs/koa-compose. Works with asynchronous and synchronous middleware on browsers, Node.js and React-Native.

Create your own middleware-based module!

Installation

npm install ctx-compose

# or:
yarn add ctx-compose

Usage

Import this module with:

// Module import
import { compose, composeSync } from "ctx-compose";

// CommonJS import
const { compose, composeSync } = require("ctx-compose");

// Specific and lightweight import
const compose = require("ctx-compose/async");
const composeSync = require("ctx-compose/sync");

// "Functional" wrapper
const compose = require("ctx-compose/fp/async");
const composeSync = require("ctx-compose/fp/sync");

And it is used like this:

const middleware = [/* ... */];
const context = {}; // it gets mutated along the middlewares

// Asynchronous:
await compose(middleware)(context);

// Synchronous:
composeSync(middleware)(context);

console.log(context);

Asynchronous

The compose function works exactly as Koa middlewares and supports asynchronous and synchronous middleware.

const compose = require("ctx-compose/async");
const Bluebird = require("bluebird");

async function log(ctx, next) {
  console.log(">>>", ctx.value);
  await next();
  console.log("<<<", ctx.value);
}

async function increaser(ctx) {
  await Bluebird.delay(1000); // wait 1000ms
  ctx.value = ctx.value + 1;
}

const context = { value: 4 };
const middleware = [log, increaser];
compose(middleware)(context)
  .then(() => {
    console.log("Value:", context.value);
  })
  .catch(err => {
    console.error(err);
  });

Synchronous

The composeSync middleware works like this. It doesn't support async middleware:

const composeSync = require("ctx-compose/sync");

function log(ctx, next) {
  console.log(">>>", ctx.value);
  next();
  console.log("<<<", ctx.value);
}

function increaser(ctx) {
  ctx.value = ctx.value + 1;
}

const context = { value: 4 };
const middleware = [log, increaser];
try {
  composeSync(middleware)(context);
  console.log("Value:", context.value);
} catch (err) {
  console.error(err);
}

Console output:

>>> 4
<<< 5
Value: 5

Functional mode

For convenience, you can use this wrapper that creates a shallow copy of the context object before each layer of middleware (if needed) and return the final object as the result.

You can use a custom copy function as the second argument of compose. By default it uses:

function copy(ctx) {
  return Object.assign({}, ctx);
}

Asynchronous

const compose = require("ctx-compose/fp/async");
const Bluebird = require("bluebird");

async function log(ctx, next) {
  console.log(">>>", ctx.value);
  const nextCtx = await next();
  console.log("<<<", nextCtx.value);
  return nextCtx; // Explicit context return.
}

async function increaser(ctx) {
  await Bluebird.delay(1000); // wait 1000ms
  ctx.value = ctx.value + 1;
  return ctx; // Explicit context return.
}

const middleware = [log, increaser];
compose(middleware)({ value: 4 })
  .then(context => {
    console.log("Value:", context.value);
  })
  .catch(err => {
    console.error(err);
  });
const composeSync = require("ctx-compose/fp/sync");

function log(ctx, next) {
  console.log(">>>", ctx.value);
  const nextCtx = next();
  console.log("<<<", nextCtx.value);
  return nextCtx; // Explicit context return.
}

function increaser(ctx) {
  ctx.value = ctx.value + 1;
  return ctx; // Explicit context return.
}

const middleware = [log, increaser];
try {
  const context = composeSync(middleware)({ value: 4 });
  console.log("Value:", context.value);
} catch (err) {
  console.error(err);
}

License

MIT