Ware Middleware Composer

raw JSON →
1.3.0 verified Thu Apr 23 auth: no javascript abandoned

Ware is a lightweight JavaScript library designed to easily create and manage a middleware layer for applications. It provides a simple API for composing synchronous, asynchronous, and generator functions into a sequential processing pipeline. The package's current stable version is 1.3.0, released in May 2015. Due to its age, development is no longer active, and the library is considered abandoned. It predates modern `async/await` syntax, relying instead on Node.js's older generator-based asynchronous patterns and explicit `next()` calls for flow control. Its primary differentiator was its simplicity and ability to handle various function types for request/response processing, similar to frameworks like Express but without the opinionated structure, allowing for flexible custom middleware stacks.

error TypeError: ware is not a function
cause Attempting to `import { ware } from 'ware'` or `import Ware from 'ware'` in an ES Module context.
fix
Change the import statement to const ware = require('ware'); as it is a CommonJS module.
error Error: next() called multiple times
cause A middleware function is calling `next()` more than once, which can lead to unexpected behavior or errors in the middleware chain.
fix
Review the problematic middleware function to ensure next() is called exactly once. This often happens in conditional logic or error handling where next() might be called in multiple branches.
error Application hangs or does not proceed past a certain middleware
cause A middleware function failed to call `next()` or resolve its asynchronous operation, causing the middleware chain to stop.
fix
Inspect the last executing middleware function. Ensure that next() is called for synchronous operations, or that a Promise is returned and resolved for asynchronous operations.
breaking The package has not been updated since 2015 (version 1.3.0) and uses older Node.js patterns like generator functions. It does not natively support modern `async/await` syntax, which might lead to unexpected behavior or require manual Promise wrapping for asynchronous middleware.
fix For new projects, consider modern middleware solutions that natively support `async/await` or robust Promise-based composition. If using `ware`, wrap `async/await` logic in explicit Promises or use callback-style asynchronous functions.
gotcha Middleware functions are expected to call `next()` to pass control to the next function in the chain. Failing to call `next()` (or resolve a Promise in an async function) will halt the middleware execution prematurely, potentially leaving requests hanging or state unupdated.
fix Always ensure that each middleware function either calls `next()` (for synchronous or callback-based asynchronous functions) or returns a Promise that resolves (for Promise-based asynchronous functions) to allow the chain to continue.
breaking Ware is a CommonJS module and does not natively support ES Modules (`import`/`export`). Attempting to `import ware from 'ware'` in an ESM context will result in a runtime error.
fix In an ES Modules environment, you must use `const ware = require('ware')` after installing a CommonJS interop loader or configure your bundler to handle CommonJS modules.
npm install ware
yarn add ware
pnpm add ware

This example demonstrates chaining synchronous and asynchronous middleware functions, showing execution flow and context modification.

const ware = require('ware');

const myMiddleware = ware()
  .use(function (ctx, next) {
    ctx.log = [];
    ctx.log.push('Middleware 1: Before next()');
    next();
    ctx.log.push('Middleware 1: After next()');
  })
  .use(function (ctx, next) {
    return new Promise(resolve => {
      setTimeout(() => {
        ctx.log.push('Middleware 2: Async operation');
        next();
        resolve();
      }, 50);
    });
  })
  .use(function (ctx) {
    ctx.log.push('Middleware 3: Final step');
    ctx.result = 'Processed';
  });

const context = {};
myMiddleware.run(context, function (err, finalContext) {
  if (err) {
    console.error('Error in middleware chain:', err);
  } else {
    console.log('Final Context:', finalContext);
    console.log('Execution Log:', finalContext.log);
    // Expected output for log:
    // [
    //   'Middleware 1: Before next()',
    //   'Middleware 2: Async operation',
    //   'Middleware 3: Final step',
    //   'Middleware 1: After next()'
    // ]
  }
});