@infectedbyjs/emitts
v1.0.6
Published
A type-safe event emitter for TypeScript with priority-based listeners, sequential/parallel execution strategies, and memory leak detection
Maintainers
Readme
EmitTS 🚀
A type-safe event emitter for TypeScript with priority-based listeners, sequential/parallel execution strategies, and memory leak detection. Provides full type inference for event names and payloads without type casting.
Features ✨
- 🎯 Fully Type-Safe: Complete TypeScript support with strict type checking
- ⚡ High Performance: Optimized for both small and large-scale applications
- 🎮 Priority Control: Execute listeners in order of importance
- 🔄 Flexible Execution: Choose between parallel or sequential execution
- 🐛 Debug Support: Built-in debugging capabilities
- 🛡️ Memory Safe: Memory leak detection with maxListeners warning
- 🔄 Promise-based API: Use promises for asynchronous operations
- 🔄 Zero Dependencies: No external dependencies
Installation 📦
npm install @infectedbyjs/emittsQuick Start 🚀
import {EmitTS} from "@infectedbyjs/emitts"
// Define your events
type AppEvents = {
greet: string
data: number
userJoined: {id: number; name: string}
}
// Create type-safe emitter
const emitter = new EmitTS<AppEvents>()
// TypeScript will infer correct types
emitter.on("greet", (name) => {
console.log(`Hello, ${name}!`)
})
emitter.on("userJoined", (user) => {
console.log(`User ${user.name} joined`)
})
// Priority-based listeners
emitter.on("data", () => console.log("Second"), 0)
emitter.on("data", () => console.log("First"), 100)
// Sequential execution
await emitter.emit("data", 42, {strategy: "sequential"})Advanced Usage 🔥
Priority-based Execution
emitter.on("dataUpdated", (data) => console.log("Second listener"), 1)
emitter.on("dataUpdated", (data) => console.log("First listener"), 2) // Higher priority
await emitter.emit("dataUpdated", {newValue: "test"})
// Output:
// First listener
// Second listenerSequential vs Parallel Execution
// Sequential execution (one after another)
await emitter.emit("dataUpdated", data, {strategy: "sequential"})
// Parallel execution (default)
await emitter.emit("dataUpdated", data, {strategy: "parallel"})One-time Listeners
// Automatically removes listener after first execution
emitter.once("userLoggedIn", (data) => console.log("This will run only once"))Promise-based Usage
// Wait for the next event
const data = await emitter.toPromise("dataUpdated")
console.log("Got data:", data)Debug Mode
const emitter = new EmitTS<MyEvents>({
debug: true,
logger: (operation, data) => {
console.log(`[DEBUG] ${operation}:`, data)
},
})API Reference 📚
EmitTS<Events>
Constructor Options
interface EmitTSOptions {
debug?: boolean // Enable debug logging
logger?: DebugLog // Custom debug logger
maxListeners?: number // Max listeners warning threshold (default: 10)
}Methods
| Method | Description | Type |
| ---------------- | ---------------------------------- | ------------------------------------------------------------------------------------------- |
| on | Subscribe to an event | (event: keyof Events, callback: EventCallback<Events[K]>, priority?: number) => CleanUpFn |
| once | Subscribe to an event once | (event: keyof Events, callback: EventCallback<Events[K]>, priority?: number) => void |
| off | Unsubscribe from an event | (event?: keyof Events, callback?: EventCallback<Events[K]>) => void |
| emit | Emit an event | (event: keyof Events, data: Events[K], options?: EmitOptions) => Promise<void> |
| toPromise | Convert next event to promise | (event: keyof Events) => Promise<Events[K]> |
| has | Check if event has listeners | (event: keyof Events) => boolean |
| isEmpty | Check if emitter has any listeners | () => boolean |
| listenersCount | Get number of listeners | (event: keyof Events) => number |
| clear | Remove all listeners | () => void |
Types
type EventCallback<T> = (data: T) => void | Promise<void>
type EmitOptions = {
strategy?: "parallel" | "sequential"
}
type CleanUpFn = () => voidBest Practices 💡
Type Safety
// Define event types for type safety interface MyEvents { event1: string event2: number } const emitter = new EmitTS<MyEvents>()Memory Management
// Always clean up listeners const cleanup = emitter.on("event", handler) // Later... cleanup()Error Handling
try { await emitter.emit("event", data) } catch (error) { console.error("Error in event handlers:", error) }Priority Usage
// Use priorities for critical handlers emitter.on("critical", handler, 100) // High priority emitter.on("normal", handler, 0) // Normal priority
Troubleshooting 🔧
Common Issues and Solutions
TypeScript Errors
// ❌ Error: Type 'string' is not assignable to type 'number' emitter.emit("data", "42") // Wrong type // ✅ Correct usage emitter.emit("data", 42) // Correct typeMemory Leaks
// ❌ Potential memory leak emitter.on("event", handler) // No cleanup // ✅ Proper cleanup const cleanup = emitter.on("event", handler) // When done: cleanup()Async Handler Issues
// ❌ Missing await emitter.emit("event", data) // Might not wait for handlers // ✅ Proper async handling await emitter.emit("event", data) // Waits for all handlers
Contributing 🤝
Contributions are welcome! Please feel free to submit a Pull Request.
License
MIT
