events-constructor
v2.1.1
Published
Class for emitting events
Downloads
1,885
Readme
events-constructor
Class for emitting events with strong TypeScript support
Install
npm
npm install events-constructoryarn
yarn add events-constructorUsage
Basic Events
import Events from 'events-constructor';
const eventNames = ['event1', 'event2'];
const events = new Events(eventNames);
events.on('event1', (data) => {
console.log('event1 is called with data:', data);
});
events.trigger('event1', 'some data');Typed Events (TypeScript)
import { TypedEvents } from 'events-constructor';
type EventMap = {
userLoaded: { id: string; name: string };
logout: never;
};
const eventNames = ['userLoaded', 'logout'] as const;
const events = new TypedEvents<EventMap>(eventNames);
// TypeScript will enforce correct payload types
events.on('userLoaded', (user) => {
console.log('User loaded:', user.id, user.name);
});
// ✅ Correct - TypeScript knows the payload type
events.trigger('userLoaded', { id: '1', name: 'John' });
// ❌ TypeScript error - wrong payload type
events.trigger('userLoaded', { wrong: true });
// ✅ Correct - logout event has no payload
events.trigger('logout');
// ❌ TypeScript error - logout doesn't accept payload
events.trigger('logout', { data: 'wrong' });Race Conditions
Handle multiple events with onRace conditions:
// onceRace - triggers only once, then automatically unsubscribes
events.onceRace(['userLogin', 'userError'], (data, eventName) => {
console.log(`First event: ${eventName}`, data);
});
// onRace - triggers every time any of the events occur, stays active
const unsubscribe = events.onRace(['userLogin', 'userError'], (data, eventName) => {
console.log(`Event occurred: ${eventName}`, data);
});
// Manually unsubscribe when no longer needed
unsubscribe();API
Events (Base Class)
events.on
Add listener to event
events.on('event1', (data) => {
console.log('event1 is called with data:', data);
});events.once
Add a listener that will be called only once per event
events.once('event1', (data) => {
console.log('event1 is called with data:', data);
});events.off
Remove listener from event
events.off('event1', handler);events.trigger
Trigger event with data
events.trigger('event1', 'some data');events.emit
Alias for trigger (Node.js EventEmitter compatibility)
events.emit('event1', 'some data');events.wait
Wait for an event to be triggered (returns Promise)
const data = await events.wait('event1');
console.log('Event triggered with:', data);events.onceRace
Listen for the first occurrence of any event from a list (automatically unsubscribes after first trigger)
events.onceRace(['event1', 'event2'], (data, eventName) => {
console.log(`${eventName} was triggered first with:`, data);
});events.onRace
Listen for any occurrence of events from a list (stays active until manually unsubscribed)
const unsubscribe = events.onRace(['event1', 'event2'], (data, eventName) => {
console.log(`${eventName} was triggered with:`, data);
});
// Unsubscribe when no longer needed
unsubscribe();events.removeEventHandlers
Remove all listeners
events.removeEventHandlers();events.offAll
Remove all listeners for specific event or all events
// Remove all listeners for specific event
events.offAll('event1');
// Remove all listeners for all events
events.offAll();events.triggers
Get all triggers
events.triggers;events.eachTriggers
Iterate through all triggers
events.eachTriggers((trigger, eventName) => {
console.log(`Trigger for ${eventName}:`, trigger);
});events.deactivate()
Disable event handlers. The trigger method will not produce any effect.
events.on('event1', (data) => {
console.log('event1 is called with data:', data); //it's not called
});
events.deactivate();
events.trigger('event1', 'some data');events.activate()
Enable event handlers.
events.on('event1', (data) => {
console.log('event1 is called with data:', data);
});
events.deactivate();
events.trigger('event1', 'some data'); // no effect
events.activate();
events.trigger('event1', 'some data'); // handler is calledevents.hasHandlers
Check if event has any handlers
if (events.hasHandlers('event1')) {
console.log('Event has handlers');
}events.destroy()
Destroy the events instance and clean up all handlers
events.destroy();
// All handlers are removed and triggers are undefinedTypedEvents (TypeScript)
TypedEvents extends the base Events class with strong TypeScript support:
Type Safety
type EventMap = {
userLoaded: { id: string };
logout: never;
dataUpdated: { value: number };
};
const events = new TypedEvents<EventMap>(['userLoaded', 'logout', 'dataUpdated']);
// TypeScript enforces correct payload types
events.trigger('userLoaded', { id: '123' }); // ✅
events.trigger('logout'); // ✅ (no payload for 'never' type)
events.trigger('dataUpdated', { value: 42 }); // ✅
// TypeScript errors for incorrect usage
events.trigger('userLoaded', { wrong: true }); // ❌
events.trigger('logout', { data: 'wrong' }); // ❌eachTriggersTyped
Strongly typed version of eachTriggers
events.eachTriggersTyped((trigger, eventName) => {
// trigger is properly typed based on the event
if (eventName === 'userLoaded') {
trigger({ id: 'test' }); // TypeScript knows this is correct
}
});onRace (TypedEvents)
Strongly typed version of onRace with payload type safety
type EventMap = {
userLoaded: { id: string; name: string };
userError: { error: string };
logout: never;
};
const events = new TypedEvents<EventMap>(['userLoaded', 'userError', 'logout']);
const unsubscribe = events.onRace(['userLoaded', 'userError'], (data, eventName) => {
// TypeScript knows the exact payload type for each event
if (eventName === 'userLoaded') {
console.log('User loaded:', data.id, data.name); // data is { id: string; name: string }
} else if (eventName === 'userError') {
console.log('Error:', data.error); // data is { error: string }
}
});
// Unsubscribe when no longer needed
unsubscribe();Features
- Type Safety: Full TypeScript support with compile-time type checking
- Event Validation: Ensures only predefined events can be used
- Memory Management: Automatic cleanup of one-time listeners
- Error Handling: Built-in error handling with debug support
- Promise Support: Async/await support with
wait()method - Race Conditions: Handle multiple events with
onceRace()andonRace() - Lifecycle Management: Activate/deactivate events as needed
- Performance: Efficient event handling with Set-based listeners
Maintainer
👤 Krivega Dmitriy
- Website: https://krivega.com
- Github: @Krivega
Contributing
Contributions, issues and feature requests are welcome!
Feel free to check issues page. You can also take a look at the contributing guide.
📝 License
Copyright © 2025 Krivega Dmitriy.
This project is MIT licensed.
