A modern, lightweight Event Emitter for JavaScript and TypeScript, inspired by the Observer Pattern.
Key features:
- 🚀 Simple API:
add
,emit
,remove
,addOnce
,removeAll
- 🧑💻 TypeScript-first: Full type safety out of the box
- ✨ Both callback and Promise/async usage:
await emitter.addOnce()
- 🦺 Memory-safe: Listeners can auto-remove with
AbortController
- ⚡ Zero dependencies, production-ready, tiny footprint
Use it for events, hooks, signals, or decoupled reactive design!
npm install tahasoft-event-emitter
import { EventEmitter } from 'tahasoft-event-emitter';
/** @type {EventEmitter<string>} */
const onStatusChange = new EventEmitter();
onStatusChange.add(status => {
console.log('Status changed to:', status);
});
onStatusChange.emit('Ready');
class User {
constructor() {
/** @type {EventEmitter<string>} */
this.onStatusChange = new EventEmitter();
}
updateStatus(status) {
this.onStatusChange.emit(status);
}
}
const user = new User();
user.onStatusChange.add(status => {
console.log('New status:', status);
});
user.updateStatus('Active');
class User {
public onLogin = new EventEmitter<string>();
public login(userName: string, password: string) {
// validate...
this.onLogin.emit(userName);
}
}
const user = new User();
user.onLogin.add(name => {
console.log(`User ${name} has logged in`);
});
user.login('John', '1234abcd');
Execute a listener only once, then remove automatically:
onStatusChange.addOnce(status => {
console.log('This runs once for status:', status);
});
onStatusChange.emit('Online'); // Triggers above
onStatusChange.emit('Offline'); // Listener is not called again
Wait for the next event occurrence with a promise:
async function waitForStatus() {
const newStatus = await onStatusChange.addOnce();
console.log('Status awaited:', newStatus);
}
waitForStatus();
onStatusChange.emit('Loaded');
Auto-remove listeners using AbortSignal:
const controller = new AbortController();
onStatusChange.add(status => console.log('Listen once, then remove automatically if aborted:', status), {
signal: controller.signal
});
// Later...
controller.abort(); // Listener is removed
add(listener, options?)
addListener(listener, options?)
addEventListener(listener, options?)
subscribe(listener, options?)
options
can include { signal: AbortSignal }
for automatic removal.
remove(listener);
removeListener(listener);
removeEventListener(listener);
unsubscribe(listener);
removeAll();
removeAllListeners();
emit(arg);
dispatch(arg);
The arg
is passed to all listeners.
-
Callback form:
addOnce(listener, options?)
-
Promise form:
await addOnce(options?)
resolves with the next value emitted.
{ signal: AbortSignal }
– pass an AbortController signal for automatic listener removal:
const controller = new AbortController();
emitter.add(listener, { signal: controller.signal });
controller.abort(); // listener removed
- Strictly typed for single-argument events—works great with primitives or objects.
- Promise/async support for modern codebases.
-
Abortsafe: no memory leaks—auto-cleanup with
AbortController
. - Minimal and fast—~1KB gzipped, zero dependencies.
- Production ready—used in both Node.js and browser projects.
MIT
Powered by tahasoft-event-emitter – the robust TypeScript/JavaScript event emitter for modern apps.