Registry / http-networking / composition

composition

JSON →
library8!6.75309jsnpmunverified

The `composition` package provides a utility for composing asynchronous middleware functions in a manner similar to Koa. It uniquely supports mixing both traditional generator functions (using `yield next`) and modern `async/await` functions within the same middleware stack. Each composed middleware function is expected to return a Promise or handle `next()` correctly to ensure the control flow propagates. The package is currently at version 2.3.0, indicating a stable release focused on robust async control flow. While no explicit release cadence is documented, utilities of this nature tend to be stable with updates driven by significant changes in JavaScript's asynchronous patterns or bug fixes. Its key differentiator is the seamless interoperability between generator-based and promise-based async middleware, making it suitable for projects transitioning or requiring compatibility across different asynchronous programming styles.

npm install composition
INSTALL
IMPORT
SIG · COMPOSITION
C
composition
http-networkingjavascriptv8!6.75309
Install
Import
Disk
Pass rate
0/ 6
Env Coverage0 / 6
glibc
1822
musl
1822
Install & Compatibility
Where this runs
tested against v? · npm install
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
node 18226 runs
build_error
glibc
node 18226 runs
build_error
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

compose
import compose from 'composition';
import { compose } from 'composition';
The primary export 'compose' is a default export for ESM modules.
compose
const compose = require('composition');
const { compose } = require('composition');
For CommonJS environments, 'compose' is the `module.exports` default, not a named export.
MiddlewareFunction
import type { MiddlewareFunction } from 'composition';
For TypeScript users, `MiddlewareFunction` might be available as a type import to define the signature of middleware functions for better type checking, assuming type declarations are provided.

Demonstrates how to compose a stack of mixed generator, promise-returning, and async/await middleware functions, illustrating the control flow, context passing, and handling of return values and errors.

var compose = require('composition'); var stack = []; // Middleware 1: A generator function stack.push(function* (next) { console.log('Middleware 1 (generator): Before calling next()'); yield next; console.log('Middleware 1 (generator): After next() returned'); }); // Middleware 2: A regular function returning a Promise stack.push(function (next) { console.log('Middleware 2 (promise): Before calling next()'); return Promise.resolve('Data from Middleware 2').then((data) => { console.log('Middleware 2 (promise): Received data:', data); return next(); // Ensure next is called and its result is returned as a Promise }).then(() => { console.log('Middleware 2 (promise): After next() returned'); return 'Modified by Middleware 2'; }); }); // Middleware 3: An async/await function stack.push(async function (next) { console.log('Middleware 3 (async/await): Before calling next()'); const result = await next(); // Await the result of the downstream middleware console.log('Middleware 3 (async/await): After next() returned with:', result); return 'Final value from Middleware 3'; }); // Compose the middleware stack into a single function var fn = compose(stack); // Invoke the composed function, which returns a Promise fn.call({ customContext: 'hello' }).then(function (finalVal) { console.log('Composed function resolved with final value:', finalVal); }).catch(function (err) { console.error('Composed function caught an error:', err.stack); process.exit(1); });
Debug
Known issues
gotchaMiddleware functions must explicitly call `next()` and ensure their return value, or the result of `next()`, is a Promise that is either returned or awaited. Failure to do so will break the middleware chain, preventing subsequent middleware from executing or causing unexpected behavior.
fix
For `async/await` middleware, ensure `await next();` is used. For generator middleware, use `yield next;`. For plain promise-returning functions, ensure `return next().then(...)` or `return Promise.resolve().then(() => next())` is used to propagate control.
affects: >=1.0.0
gotchaMixing generator functions and `async/await` functions within the same stack requires a Node.js environment that supports both. Older Node.js versions (e.g., prior to v7.6.0) may not support `async/await` natively, and generators themselves require specific syntax support.
fix
Use Node.js v7.6.0 or higher for native `async/await` support. For environments with limited feature support, transpile code using Babel or a similar tool to ensure compatibility with your target runtime.
affects: <=7.0.0
gotchaThe `this` context for middleware functions is explicitly set when the composed function is invoked (e.g., `fn.call(thisArg)`). If middleware relies on a specific `this` context and it's not provided or is incorrect, it can lead to `TypeError` or unexpected runtime errors.
fix
Always pass the desired `this` context to the composed function via `fn.call(yourContext)` or `fn.apply(yourContext)`. If no specific context is required, passing `null` or `{}` is acceptable.
affects: >=1.0.0
Errors
Common errors & fixes
TypeError: next is not a function
A middleware function in the stack failed to correctly call `next()`, or the `next` argument was not properly propagated through the middleware chain.
fix
Review all middleware functions to ensure `next` is correctly invoked and awaited/yielded. Verify that the function signature includes `next` as a parameter if it's being called.
UnhandledPromiseRejectionWarning: Unhandled promise rejection.
A Promise within the middleware chain rejected, and the rejection was not explicitly caught by a `.catch()` block in the composed function's invocation or any preceding middleware.
fix
Add a `.catch()` handler to the invocation of the composed function (e.g., `fn().catch(err => console.error(err))`) to gracefully handle any errors that propagate out of the middleware stack.
SyntaxError: await is only valid in async functions and the top level bodies of modules
Attempting to use the `await` keyword outside of an `async` function in an environment that does not support top-level await, or within a non-async middleware function.
fix
Ensure `await` is only used inside functions declared with the `async` keyword. If using `async/await` in older Node.js versions, ensure you are using Node.js v7.6.0 or newer.
Upgrade
Version history
8!6.75309latest on npm
Audit
Dependencies

No dependency data recorded yet.

Agent activity
20 hits · last 30 days
node
18
OpenAI (training)
1
Resources
composition — npm install composition · libregistry