{"id":17727,"library":"js-middleware","title":"JavaScript Middleware Pattern Implementation","description":"js-middleware is a versatile JavaScript library designed to implement a powerful middleware pattern, allowing developers to inject custom logic into the execution flow of any object's methods. It aims to bring the scalability and maintainability benefits seen in frameworks like ReduxJS and ExpressJS to general-purpose JavaScript objects. The package is currently at version 0.3.1, with a recent patch 0.3.2, indicating it's actively maintained, though possibly with a slower release cadence. Its primary differentiator is the ability to apply middleware to arbitrary methods of any class or object instance, providing a flexible mechanism to modify arguments, perform side effects, or control method execution. This approach fosters highly modular and testable code by separating cross-cutting concerns from core business logic, making it suitable for extending existing objects without direct modification.","status":"active","version":"0.3.1","language":"javascript","source_language":"en","source_url":"https://github.com/unbug/js-middleware","tags":["javascript","middleware","javascript middleware","redux middleware","express middleware","middleware pattern"],"install":[{"cmd":"npm install js-middleware","lang":"bash","label":"npm"},{"cmd":"yarn add js-middleware","lang":"bash","label":"yarn"},{"cmd":"pnpm add js-middleware","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"MiddlewareManager is a named export, not a default export.","wrong":"import MiddlewareManager from 'js-middleware';","symbol":"MiddlewareManager","correct":"import { MiddlewareManager } from 'js-middleware';"},{"note":"When using CommonJS, MiddlewareManager is a named property of the module export.","wrong":"const MiddlewareManager = require('js-middleware');","symbol":"MiddlewareManager (CommonJS)","correct":"const { MiddlewareManager } = require('js-middleware');"},{"note":"When included directly via a script tag in the browser, MiddlewareManager is exposed globally on the window object.","symbol":"MiddlewareManager (Browser Global)","correct":"const manager = new window.MiddlewareManager(targetObject);"}],"quickstart":{"code":"class Person {\n  walk(step) {\n    this.step = step;\n    console.log(`Person walked ${step} steps.`);\n  }\n  speak(word) {\n    this.word = word;\n    console.log(`Person spoke: ${word}`);\n  }\n}\n\nconst logger = target => next => (...args) => {\n  console.log(`[Logger Middleware] Calling ${target.constructor.name}'s method with args: ${JSON.stringify(args)}.`);\n  const result = next(...args);\n  console.log(`[Logger Middleware] Method finished.`);\n  return result;\n};\n\nconst argModifier = target => next => (step) => {\n    if (typeof step === 'number') {\n        step = step * 2; // Double the steps\n        console.log(`[ArgModifier Middleware] Doubling steps to: ${step}`);\n    }\n    return next(step);\n};\n\nconst p = new Person();\nconst middlewareManager = new MiddlewareManager(p);\n\nmiddlewareManager.use('walk', logger);\nmiddlewareManager.use('walk', argModifier);\n\nconsole.log('--- Calling walk (with middleware) ---');\np.walk(5); // Will log 'walk start, steps: 5.', 'Doubling steps to: 10', 'Person walked 10 steps.', 'walk end.'\n\nmiddlewareManager.use('speak', logger);\nconsole.log('\\n--- Calling speak (with middleware) ---');\np.speak('Hello World');","lang":"javascript","description":"Demonstrates how to initialize MiddlewareManager, apply multiple middleware functions to a target object's method, and observe their effects on method arguments and execution flow."},"warnings":[{"fix":"Always ensure `next(...args)` is called at some point within your middleware function, unless you explicitly intend to terminate the chain early and handle the response yourself.","message":"Failing to call `next()` within a middleware function will halt the middleware chain and prevent the original target function from executing. This can lead to silent failures or processes hanging indefinitely.","severity":"gotcha","affected_versions":">=0.1.0"},{"fix":"Rename your methods to not use leading/trailing underscores if you intend for middleware to apply to them. Alternatively, if applying middleware via an object, use the `middlewareMethods` property in the middleware class/object to explicitly define which methods should be targeted.","message":"By default, methods on the target object that start or end with an underscore (`_method` or `method_`) are excluded from middleware application. This is a design choice to prevent unintended interception of internal methods.","severity":"gotcha","affected_versions":">=0.1.0"},{"fix":"If immutability is desired for arguments, create a copy of the arguments before modification within the middleware, e.g., `const newArgs = [...args];`.","message":"Middleware functions can directly mutate the arguments passed to them, which can lead to unexpected side effects if not handled carefully. The pattern allows for modification, but consumers should be aware of this potential for state changes.","severity":"gotcha","affected_versions":">=0.1.0"},{"fix":"For asynchronous operations within middleware, ensure that the asynchronous task is fully completed before `next()` is called, or manage promises explicitly. For simple cases, `async/await` directly within the middleware function body should work, but `next()` itself is not `awaitable` without custom wrapping.","message":"The current implementation examples primarily demonstrate synchronous middleware. While it might be possible to integrate asynchronous operations, the provided `next()` mechanism is synchronous. Expecting `await next()` without specific async handling by the library could lead to issues.","severity":"gotcha","affected_versions":">=0.1.0"},{"fix":"To avoid global conflicts, use the npm package and a bundler (like Webpack or Rollup) to scope the import, or encapsulate the usage within an IIFE (Immediately Invoked Function Expression) in browser environments.","message":"When using the library in a browser environment by including `dist/middleware.min.js`, the `MiddlewareManager` constructor is exposed as `window.MiddlewareManager`. This global variable could potentially clash with other libraries that also define `MiddlewareManager` globally.","severity":"gotcha","affected_versions":">=0.1.0"}],"env_vars":null,"last_verified":"2026-04-23T00:00:00.000Z","next_check":"2026-07-22T00:00:00.000Z","problems":[{"fix":"Ensure your middleware follows the `target => next => (...args) => { /* ... */ return next(...args); }` signature. Double-check that `next` is correctly passed and invoked.","cause":"The middleware function did not correctly return a function that accepts `next`, or `next` was not properly called.","error":"TypeError: next is not a function"},{"fix":"Review all middleware functions applied to the method and ensure that `next(...args)` is called in each middleware unless an explicit termination of the chain is intended (e.g., for short-circuiting).","cause":"A middleware in the chain failed to call `next()`, thereby preventing subsequent middleware and the original target function from executing.","error":"Target function 'myMethod' not called / Process hangs indefinitely"},{"fix":"Rename the method to remove leading/trailing underscores, or explicitly define the method as a middleware target using the `middlewareMethods` property in a middleware object/class passed to `use()`.","cause":"The target method's name starts or ends with an underscore (`_`), which makes it exempt from middleware application by default.","error":"Middleware not applying to 'my_internal_method'"}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null}