@takepack/event
v1.0.0
Published
A lightweight event handling library for NestJS applications with type-safe event handling
Downloads
6
Maintainers
Readme
@takepack/event
A lightweight event handling library for NestJS applications, providing a clean abstraction with type-safe event handling similar to @nestjs/cqrs.
Features
- Type-safe event handling: Use event classes instead of string-based event names
- Decorator-based: Simple and intuitive API using decorators
- Lightweight: Minimal dependencies, works with NestJS core
- Event Bus pattern: Clean separation between event publishers and listeners
Installation
npm install @takepack/event @nestjs/event-emitter
# or
yarn add @takepack/event @nestjs/event-emitter
# or
pnpm add @takepack/event @nestjs/event-emitterUsage
1. Define an Event
Create an event class and decorate it with @Event():
import { Event } from '@takepack/event';
@Event('user.created') // Optional: specify custom event name
export class UserCreatedEvent {
constructor(
public readonly userId: string,
public readonly email: string,
public readonly username: string,
) {}
}2. Publish Events
Use EventBus to publish events:
import { Injectable } from '@nestjs/common';
import { EventBus } from '@takepack/event';
import { UserCreatedEvent } from './events';
@Injectable()
export class UserService {
constructor(private readonly eventBus: EventBus) {}
async createUser(data: CreateUserDto) {
// ... create user logic
// Publish event
this.eventBus.publish(
new UserCreatedEvent(user.id, user.email, user.username)
);
return user;
}
}3. Handle Events
Create a listener using @OnEventClass() decorator:
import { Injectable, Logger } from '@nestjs/common';
import { OnEventClass } from '@takepack/event';
import { UserCreatedEvent } from '../users/events';
@Injectable()
export class UserCreatedListener {
private readonly logger = new Logger(UserCreatedListener.name);
@OnEventClass(UserCreatedEvent)
async handleUserCreatedEvent(event: UserCreatedEvent) {
this.logger.log(`User created: ${event.email}`);
// Handle the event...
}
}4. Register in Module
Import EventsModule in your AppModule:
import { Module } from '@nestjs/common';
import { EventsModule } from '@takepack/event';
@Module({
imports: [
EventsModule, // This is a global module
// ... other modules
],
})
export class AppModule {}API Reference
Decorators
@Event(eventName?: string)
Marks a class as an event. The event name is used internally for event routing.
- Parameters:
eventName(optional): Custom event name. If not provided, uses the class name.
@OnEventClass(eventClass: any)
Decorator for event handler methods. Automatically resolves the event name from the event class.
- Parameters:
eventClass: The event class to listen for.
EventBus
publish(event: any): void
Publishes a single event.
- Parameters:
event: An instance of an event class decorated with@Event().
publishAll(events: any[]): void
Publishes multiple events.
- Parameters:
events: An array of event instances.
Benefits over String-based Events
- Type Safety: Compile-time checking of event structure
- Refactoring Support: IDE can help rename and find usages
- Cleaner Code: No magic strings scattered in the codebase
- Auto-completion: IDE provides better suggestions
- Self-documenting: Event classes serve as documentation
Example: Complete Flow
// 1. Define the event
@Event('order.created')
export class OrderCreatedEvent {
constructor(
public readonly orderId: string,
public readonly customerId: string,
public readonly amount: number,
) {}
}
// 2. Publish from service
@Injectable()
export class OrderService {
constructor(private readonly eventBus: EventBus) {}
async createOrder(data: CreateOrderDto) {
const order = await this.orderRepository.save(data);
this.eventBus.publish(
new OrderCreatedEvent(order.id, order.customerId, order.amount)
);
return order;
}
}
// 3. Handle in multiple listeners
@Injectable()
export class EmailListener {
@OnEventClass(OrderCreatedEvent)
async sendConfirmationEmail(event: OrderCreatedEvent) {
// Send email...
}
}
@Injectable()
export class NotificationListener {
@OnEventClass(OrderCreatedEvent)
async sendPushNotification(event: OrderCreatedEvent) {
// Send notification...
}
}
@Injectable()
export class AnalyticsListener {
@OnEventClass(OrderCreatedEvent)
async trackOrderCreated(event: OrderCreatedEvent) {
// Track in analytics...
}
}Requirements
- NestJS 10.x or 11.x
- TypeScript 5.x
- Node.js 18+
License
MIT
Author
Takepack
