You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Package:@node-ts/bus-nestjs in packages/bus-nestjs. Peers @nestjs/common and @nestjs/core^11.0.0 || ^12.0.0 (only APIs both have), @node-ts/bus-core ^2.0.0. CI tests Nest 12.
Configuration:BusModule.forRoot({ configure }) and forRootAsync({ imports, inject, useFactory }) take a factory that returns an unbuilt BusConfiguration, so every builder method works and nothing is duplicated. The module adds the Nest container adapter, the discovered handlers and workflows, withInterruptSignals([]) and Nest's Logger (unless withLogger() is used), then builds.
Registration:BusModule.forFeature({ handlers, workflows }) and forFeatureAsync({ inject, useFactory }) register class and function handlers and workflows (function handlers get dependencies through inject). @BusHandler() and @BusWorkflow(), made with DiscoveryService.createDecorator(), are optional sugar for classes. No decorators on messages.
Injection and several buses: the default bus is injected as BusInstance. Named buses use forRoot({ name }), getBusToken(name) and @InjectBus(name), with forFeature({ bus }) and @BusHandler({ bus }). Each bus has its own container adapter.
Lifecycle: built in the provider factory; initialize() and start() in onApplicationBootstrap (start() skipped for buses that don't poll, through a small public getter in bus-core); stop() in onModuleDestroy; dispose() in onApplicationShutdown. lifecycle: 'manual' leaves starting to the app. Graceful SIGTERM needs app.enableShutdownHooks().
Provisioning:bus provision also accepts a module that exports a built, uninitialized BusInstance (or a function returning one), and bus.mjs exits explicitly. createBusForProvisioning(AppModule, { bus? }) boots the app with the bus' lifecycle off and returns the bus.
Scopes: singleton providers are resolved with moduleRef.get. Request-scoped and transient ones are resolved with one ContextId per received message, with { message, attributes } registered as REQUEST. Bootstrap fails with a named error if a class handler or workflow isn't a provider.
Tests: Nest 12 is ESM-only, so Jest runs with NODE_OPTIONS=--experimental-vm-modules (falling back to transformIgnorePatterns if an existing suite breaks). Tests use Test.createTestingModule with InMemoryQueue and the existing handlerContext() fakes.
Activity
npm create bus-apptemplates #269examples/with docker compose #252adenhertog commentedon Oct 7, 2026
Accepted design (maintainer, 2026-10-07)
@node-ts/bus-nestjsinpackages/bus-nestjs. Peers@nestjs/commonand@nestjs/core^11.0.0 || ^12.0.0(only APIs both have),@node-ts/bus-core ^2.0.0. CI tests Nest 12.BusModule.forRoot({ configure })andforRootAsync({ imports, inject, useFactory })take a factory that returns an unbuiltBusConfiguration, so every builder method works and nothing is duplicated. The module adds the Nest container adapter, the discovered handlers and workflows,withInterruptSignals([])and Nest'sLogger(unlesswithLogger()is used), then builds.BusModule.forFeature({ handlers, workflows })andforFeatureAsync({ inject, useFactory })register class and function handlers and workflows (function handlers get dependencies throughinject).@BusHandler()and@BusWorkflow(), made withDiscoveryService.createDecorator(), are optional sugar for classes. No decorators on messages.BusInstance. Named buses useforRoot({ name }),getBusToken(name)and@InjectBus(name), withforFeature({ bus })and@BusHandler({ bus }). Each bus has its own container adapter.initialize()andstart()inonApplicationBootstrap(start()skipped for buses that don't poll, through a small public getter in bus-core);stop()inonModuleDestroy;dispose()inonApplicationShutdown.lifecycle: 'manual'leaves starting to the app. Graceful SIGTERM needsapp.enableShutdownHooks().bus provisionalso accepts a module that exports a built, uninitializedBusInstance(or a function returning one), andbus.mjsexits explicitly.createBusForProvisioning(AppModule, { bus? })boots the app with the bus' lifecycle off and returns the bus.moduleRef.get. Request-scoped and transient ones are resolved with oneContextIdper received message, with{ message, attributes }registered asREQUEST. Bootstrap fails with a named error if a class handler or workflow isn't a provider.NODE_OPTIONS=--experimental-vm-modules(falling back totransformIgnorePatternsif an existing suite breaks). Tests useTest.createTestingModulewithInMemoryQueueand the existinghandlerContext()fakes.