Event Interceptors for EventEmitter
`events-intercept` is a Node.js library designed to introduce middleware-like interception capabilities to the standard `EventEmitter`. It allows developers to define functions that execute before an event's registered handlers, providing opportunities to modify event arguments, prevent event propagation, or trigger additional events based on intercepted data. The library extends `events.EventEmitter`, adding methods such as `intercept`, `interceptors`, `removeInterceptor`, and `removeAllInterceptors` to manage these pre-handler hooks. The current and last stable version is 2.0.0, released in 2015. This package is no longer actively maintained, making it unsuitable for new projects requiring ongoing support or modern JavaScript features like ES Modules. Its primary differentiator, historically, was providing a structured, waterfall-like approach to event processing, akin to request middleware, directly within the `EventEmitter` paradigm.
Common errors
-
Error: Maximum number of interceptors exceeded
cause More than 10 interceptors (default limit) were added to a single event type, which the library flags as a potential memory leak.fixIf this is intentional, increase the limit: `emitter.setMaxInterceptors(N)` where `N` is your desired limit (0 for no limit). If unintentional, review your code to identify and remove redundant interceptors. -
RangeError: Maximum call stack size exceeded
cause An interceptor for an event is re-emitting the *same* event, leading to an uncontrolled recursive loop of interception and emission.fixInspect interceptors for the affected event. Ensure that `this.emit('eventName', ...)` inside an interceptor does not re-emit the `eventName` that triggered the interceptor itself. Emit a *different* event, or implement logic to prevent re-emission.
Warnings
- breaking The `events-intercept` package has been abandoned since 2015 and is no longer maintained. It does not receive security updates, bug fixes, or new features. Using it in new projects is strongly discouraged, and existing projects should consider migration.
- breaking This package is CommonJS-only and lacks native ES Module (ESM) support. It cannot be directly `import`ed in ESM contexts without relying on Node.js's CJS interoperability layers, which can lead to issues or suboptimal performance in modern build environments.
- gotcha Re-emitting the *same* event within its own interceptor can lead to an infinite loop, causing stack overflow errors or exhausting system resources.
- gotcha By default, a warning is emitted if more than 10 interceptors are added to a single event type, indicating a potential memory leak. While `setMaxInterceptors(n)` can change this limit (0 for no limit), a large number of interceptors can still impact performance and maintainability.
Install
-
npm install events-intercept -
yarn add events-intercept -
pnpm add events-intercept
Imports
- EventEmitter
import { EventEmitter } from 'events-intercept';const EventEmitter = require('events-intercept').EventEmitter; - eventsIntercept
import eventsIntercept from 'events-intercept';
const eventsIntercept = require('events-intercept');
Quickstart
const EventEmitter = require('events-intercept').EventEmitter;
const emitter = new EventEmitter();
emitter
.on('data', function(arg) {
console.log(`Handler received: ${arg}`);
})
.intercept('data', function(arg, done) {
// Interceptor 1: Modify data
console.log(`Interceptor 1 received: ${arg}`);
return done(null, 'intercepted_1_' + arg);
})
.intercept('data', function(arg, done) {
// Interceptor 2: Further modify data
console.log(`Interceptor 2 received: ${arg}`);
return done(null, 'intercepted_2_' + arg);
});
console.log('Emitting event with initial data...');
emitter.emit('data', 'initial data');
// Expected output:
// Emitting event with initial data...
// Interceptor 1 received: initial data
// Interceptor 2 received: intercepted_1_initial data
// Handler received: intercepted_2_initial data
console.log('\nEmitting another event, but intercepting to prevent original handler...');
emitter.intercept('no-callback-event', function(arg, done) {
console.log(`Interceptor for 'no-callback-event' received: ${arg}. Not calling done().`);
// Do not call done(), so the original 'no-callback-event' handler is never invoked.
this.emit('alternative-event', 'transformed ' + arg);
});
emitter.on('no-callback-event', () => console.log('This should not log!'));
emitter.on('alternative-event', (arg) => console.log(`Alternative event handler received: ${arg}`));
emitter.emit('no-callback-event', 'original data');