@raphaabreu/nestjs-sync-cqrs
v1.0.0
Published
Synchronous event bus for @nestjs/cqrs — awaits all event handlers before returning
Downloads
32
Readme
@raphaabreu/nestjs-sync-cqrs
Synchronous event bus for @nestjs/cqrs — awaits all event handlers before returning, instead of the default fire-and-forget behavior.
Why?
The default EventBus from @nestjs/cqrs dispatches events asynchronously via RxJS Subjects. This means the publisher has no way to know when handlers have finished (or failed). SyncEventBus overrides publish() to await all handlers using Promise.allSettled, so:
- Handlers run and complete before the publisher continues.
- Errors in individual handlers are logged but do not prevent other handlers from running.
- You can rely on side-effects being complete after
publish()resolves.
Installation
npm install @raphaabreu/nestjs-sync-cqrsUsage
Replace CqrsModule with SyncCqrsModule in your application module:
import { Module } from '@nestjs/common';
import { SyncCqrsModule } from '@raphaabreu/nestjs-sync-cqrs';
@Module({
imports: [SyncCqrsModule],
})
export class AppModule {}That's it. All your existing @EventsHandler() decorated classes will now be invoked synchronously when events are published. Commands and queries continue to work exactly as before.
Using EventBus directly
Since SyncCqrsModule provides SyncEventBus as both itself and as the EventBus token, you can inject either:
import { Injectable } from '@nestjs/common';
import { EventBus } from '@nestjs/cqrs';
@Injectable()
export class OrderService {
constructor(private readonly eventBus: EventBus) {}
async placeOrder(order: Order) {
// ... business logic ...
// All handlers will complete before this resolves
await this.eventBus.publish(new OrderPlacedEvent(order.id));
}
}How it works
SyncEventBus extends the EventBus from @nestjs/cqrs and overrides two methods:
bind()— Builds a direct map from event classes to handler instances usingReflectmetadata, supporting multiple handlers per event type.publish()— Looks up handlers by event constructor, runs them all withPromise.allSettled, and logs any rejections.
License
MIT
