midder
v1.1.0
Published
My take on Event Emitters based on pain points I found with the base implementation in Node.js and the browser.
Maintainers
Readme
Midder
My take on EventEmitter that works in both browser and Node, with some enhancements
Features
- Type-Safe: Full TypeScript support with strongly typed events
- Operation System: Transform, filter, and tap into events with simple API
- Universal: Works in both Node.js and browsers
- Targeted Emission: Emit to specific listeners
- Promise Support: Await on once(), because it's annoying to do otherwise
- AbortSignal: Cancel listeners with standard web APIs
- Wildcard Events: Listen to all events with
*
Installation
npm install midderBuilding
npm run buildTest
npm run testExample
npm run exampleQuick Start
import { EventEmitter } from 'midder';
// Define your event types
interface MyEvents {
userLogin: { userId: string; timestamp: number };
dataUpdate: { id: string; value: any };
}
const emitter = new EventEmitter<MyEvents>();
// Add listeners
const listenerId = emitter.on('userLogin', (data) => {
console.log(`User ${data.userId} logged in at ${data.timestamp}`);
});
// Emit events
emitter.emit('userLogin', {
userId: 'user123',
timestamp: Date.now()
});Operation System
Transform and process events with powerful operation:
emitter.operation('userLogin')
.transform((data) => ({ ...data, processed: true }))
.filter((data) => {
console.log(data.processed); // Type safe transformation
return data.userId.length > 0;
})
.tap((data) => console.log('Processing:', data.userId))
.log('User login processed');ID or reference based controls
const emitter = new EventEmitter<EventMap>();
const id = emitter.on('data', (data) => {
// ...
});
const callback = (data) => JSON.stringify(data);
emitter.on('data', callback);
// Targeted emissions based on ID (because why not)
emitter.emitToListener('data', { hello: 'world!' }, id);
// Both supported
emitter.off('data', id);
emitter.off('data', callback);
Promise-based once()
// Wait for next event
const userData = await emitter.once('userLogin');
// With timeout
const userData = await emitter.once('userLogin', { timeout: 5000 });
// With AbortSignal
const controller = new AbortController();
const userData = await emitter.once('userLogin', { signal: controller.signal });API Reference
EventEmitter Methods
on(event, listener, signal?)- Add event listeneroff(event, idOrHandler)- Remove event listeneronce(event, options?)- Promise-based single-use listeneremit(event, data)- Emit event to all listenersemitToListener(event, data, listenerId)- Emit to specific listeneroperation(event)- Get operation builder for eventlistenerCount(event)- Get number of listenersremoveAllListeners(event?)- Remove all listenerseventNames()- Get list of events with listeners
Operation Methods
transform(handler)- Transform event datafilter(predicate)- Filter events conditionallytap(handler)- Execute side effectsdebounce(delayMs)- Add debounce to eventsthrottle(delayMs)- Add throttle to eventslog(message?)- Log events to console
License
MIT © [kjkwan1]
