npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@prodforcode/event-forge-nestjs

v1.1.0

Published

NestJS module for Universal Inbox-Outbox Pattern

Readme

@prodforcode/event-forge-nestjs

NestJS module for the Universal Inbox-Outbox Pattern with automatic lifecycle management.

Installation

npm install @prodforcode/event-forge-nestjs @prodforcode/event-forge-core
# or
pnpm add @prodforcode/event-forge-nestjs @prodforcode/event-forge-core

Features

  • Automatic Polling Management: Outbox polling starts automatically on application bootstrap and stops gracefully on shutdown
  • Configurable Lifecycle: Control automatic polling behavior via lifecycle.autoStart option
  • Dependency Injection: Full NestJS DI support for repositories and services
  • Database Agnostic: Works with any database adapter (TypeORM, Mongoose, etc.)

Quick Start

With Automatic Lifecycle (Default)

The simplest setup automatically manages polling lifecycle:

import { Module } from '@nestjs/common';
import { InboxOutboxModule } from '@prodforcode/event-forge-nestjs';
import { TypeOrmOutboxRepository } from '@prodforcode/event-forge-typeorm';
import { RabbitMQPublisher } from '@prodforcode/event-forge-rabbitmq';

@Module({
  imports: [
    InboxOutboxModule.forRootAsync({
      useFactory: () => ({
        outbox: {
          repository: TypeOrmOutboxRepository,
          config: {
            pollingIntervalMs: 1000,
            batchSize: 50,
          },
        },
        publisher: RabbitMQPublisher,
        // lifecycle.autoStart defaults to true - polling starts automatically
      }),
    }),
  ],
})
export class AppModule {}

With this configuration:

  • Outbox polling starts automatically when the application boots
  • Polling stops gracefully when the application shuts down
  • No manual lifecycle management required

With Manual Lifecycle Control

If you need custom startup logic, disable automatic lifecycle:

@Module({
  imports: [
    InboxOutboxModule.forRootAsync({
      useFactory: () => ({
        outbox: {
          repository: TypeOrmOutboxRepository,
        },
        publisher: RabbitMQPublisher,
        lifecycle: {
          autoStart: false, // Disable automatic polling
        },
      }),
    }),
  ],
})
export class AppModule {
  constructor(private readonly outboxService: OutboxService) {}

  onApplicationBootstrap() {
    // Custom startup logic here
    console.log('Running custom initialization...');

    // Manually start polling when ready
    this.outboxService.startPolling();
  }

  onApplicationShutdown() {
    // Custom shutdown logic
    this.outboxService.stopPolling();
  }
}

Configuration

Lifecycle Options

interface LifecycleOptions {
  /**
   * Whether to automatically start outbox polling on application bootstrap
   * @default true
   */
  autoStart?: boolean;
}

Module Options

InboxOutboxModule.forRootAsync({
  useFactory: () => ({
    outbox: {
      repository: OutboxRepositoryClass,
      config: {
        pollingIntervalMs: 1000,
        batchSize: 50,
        maxRetries: 5,
      },
    },
    inbox: {
      repository: InboxRepositoryClass,
    },
    publisher: PublisherClass,
    lifecycle: {
      autoStart: true, // Default behavior
    },
  }),
});

Advanced Usage

Accessing the Lifecycle Service

The EventForgeLifecycleService is exported and can be injected for advanced control:

import { Injectable } from '@nestjs/common';
import { EventForgeLifecycleService } from '@prodforcode/event-forge-nestjs';

@Injectable()
export class CustomService {
  constructor(
    private readonly lifecycleService: EventForgeLifecycleService,
  ) {}

  // The lifecycle service handles start/stop automatically
  // You typically don't need to interact with it directly
}

Health Checks

Integrate with NestJS health checks:

import { Injectable } from '@nestjs/common';
import { HealthIndicator, HealthIndicatorResult } from '@nestjs/terminus';
import { OutboxService } from '@prodforcode/event-forge-core';

@Injectable()
export class OutboxHealthIndicator extends HealthIndicator {
  constructor(private readonly outboxService: OutboxService) {
    super();
  }

  async isHealthy(key: string): Promise<HealthIndicatorResult> {
    // Check if polling is active
    const isPolling = this.outboxService.isPolling();

    return this.getStatus(key, isPolling, {
      polling: isPolling,
    });
  }
}

Migration from Manual Lifecycle

If you're migrating from manual lifecycle management:

Before (manual):

@Module({
  imports: [InboxOutboxModule.forRootAsync({...})],
})
export class AppModule {
  constructor(private readonly outboxService: OutboxService) {}

  onApplicationBootstrap() {
    this.outboxService.startPolling(); // Manual start
  }

  onApplicationShutdown() {
    this.outboxService.stopPolling(); // Manual stop
  }
}

After (automatic):

@Module({
  imports: [
    InboxOutboxModule.forRootAsync({
      // ... config ...
      // lifecycle.autoStart: true is the default
    }),
  ],
})
export class AppModule {
  // No lifecycle hooks needed!
}

API Reference

EventForgeLifecycleService

Implements NestJS lifecycle hooks to automatically manage outbox polling.

Methods:

  • onApplicationBootstrap(): Starts outbox polling automatically
  • onApplicationShutdown(): Stops outbox polling gracefully

Note: This service is automatically provided when lifecycle.autoStart is not false and an outbox configuration exists.

License

MIT