NestboltNestbolt

@nestbolt/factory

Events

Listen to seeder lifecycle events -- track when seeders start, complete, and when the full seed process finishes.

The factory package emits events during seeder execution. These events let you track progress, log timing, or trigger side effects when seeders run.

Prerequisites

Events require @nestjs/event-emitter to be installed and registered:

npm install @nestjs/event-emitter

Register the EventEmitterModule in your root module:

import { Module } from "@nestjs/common";
import { EventEmitterModule } from "@nestjs/event-emitter";
import { FactoryModule } from "@nestbolt/factory";

@Module({
  imports: [
    EventEmitterModule.forRoot(),
    FactoryModule.forRoot({
      // ... your config
    }),
  ],
})
export class AppModule {}

If @nestjs/event-emitter is not installed, the package works normally but no events are emitted. The event emitter is injected as an optional dependency.

Event Constants

All event names are exported as the FACTORY_EVENTS constant object:

import { FACTORY_EVENTS } from "@nestbolt/factory";

console.log(FACTORY_EVENTS.SEEDER_STARTED);     // "factory.seeder.started"
console.log(FACTORY_EVENTS.SEEDER_COMPLETED);   // "factory.seeder.completed"
console.log(FACTORY_EVENTS.SEED_ALL_STARTED);   // "factory.seed.all.started"
console.log(FACTORY_EVENTS.SEED_ALL_COMPLETED); // "factory.seed.all.completed"

Use these constants instead of raw strings to avoid typos and enable IDE autocompletion.

Events Reference

factory.seeder.started

Emitted before a seeder's run() method is called.

Event string: "factory.seeder.started" Constant: FACTORY_EVENTS.SEEDER_STARTED

Payload: SeederStartedEvent

interface SeederStartedEvent {
  seederClass: string; // The class name of the seeder
}

factory.seeder.completed

Emitted after a seeder's run() method completes.

Event string: "factory.seeder.completed" Constant: FACTORY_EVENTS.SEEDER_COMPLETED

Payload: SeederCompletedEvent

interface SeederCompletedEvent {
  seederClass: string; // The class name of the seeder
}

factory.seed.all.started

Emitted before seed() begins running all registered seeders.

Event string: "factory.seed.all.started" Constant: FACTORY_EVENTS.SEED_ALL_STARTED

Payload: SeedAllStartedEvent

interface SeedAllStartedEvent {
  seederCount: number; // Total number of seeders to run
}

factory.seed.all.completed

Emitted after seed() has finished running all registered seeders.

Event string: "factory.seed.all.completed" Constant: FACTORY_EVENTS.SEED_ALL_COMPLETED

Payload: SeedAllCompletedEvent

interface SeedAllCompletedEvent {
  seederCount: number; // Total number of seeders that ran
}

Example Listener

import { Injectable, Logger } from "@nestjs/common";
import { OnEvent } from "@nestjs/event-emitter";
import {
  FACTORY_EVENTS,
  SeederStartedEvent,
  SeederCompletedEvent,
  SeedAllStartedEvent,
  SeedAllCompletedEvent,
} from "@nestbolt/factory";

@Injectable()
export class SeederEventListener {
  private readonly logger = new Logger(SeederEventListener.name);

  @OnEvent(FACTORY_EVENTS.SEED_ALL_STARTED)
  handleSeedAllStarted(event: SeedAllStartedEvent): void {
    this.logger.log(`Starting seed: ${event.seederCount} seeders to run`);
  }

  @OnEvent(FACTORY_EVENTS.SEEDER_STARTED)
  handleSeederStarted(event: SeederStartedEvent): void {
    this.logger.log(`Running seeder: ${event.seederClass}`);
  }

  @OnEvent(FACTORY_EVENTS.SEEDER_COMPLETED)
  handleSeederCompleted(event: SeederCompletedEvent): void {
    this.logger.log(`Completed seeder: ${event.seederClass}`);
  }

  @OnEvent(FACTORY_EVENTS.SEED_ALL_COMPLETED)
  handleSeedAllCompleted(event: SeedAllCompletedEvent): void {
    this.logger.log(`Seed complete: ${event.seederCount} seeders ran`);
  }
}

Register the listener in a module:

import { Module } from "@nestjs/common";
import { SeederEventListener } from "./seeder-event.listener";

@Module({
  providers: [SeederEventListener],
})
export class SeederEventsModule {}

Event Timing

Events are emitted at the following points during seeder execution:

  1. factory.seed.all.started -- Before any seeder runs (only when calling seed()).
  2. factory.seeder.started -- Before each individual seeder's run() method.
  3. factory.seeder.completed -- After each individual seeder's run() method completes.
  4. factory.seed.all.completed -- After all seeders have completed (only when calling seed()).

When calling runSeeder() directly, only factory.seeder.started and factory.seeder.completed are emitted -- the seed.all.* events are not fired.

Practical Use Cases

Timing Seeders

@OnEvent(FACTORY_EVENTS.SEEDER_STARTED)
handleStart(event: SeederStartedEvent): void {
  this.timers.set(event.seederClass, Date.now());
}

@OnEvent(FACTORY_EVENTS.SEEDER_COMPLETED)
handleComplete(event: SeederCompletedEvent): void {
  const start = this.timers.get(event.seederClass);
  if (start) {
    const duration = Date.now() - start;
    this.logger.log(`${event.seederClass} completed in ${duration}ms`);
  }
}

Progress Tracking

@OnEvent(FACTORY_EVENTS.SEED_ALL_STARTED)
handleSeedStart(event: SeedAllStartedEvent): void {
  this.total = event.seederCount;
  this.completed = 0;
}

@OnEvent(FACTORY_EVENTS.SEEDER_COMPLETED)
handleSeederComplete(event: SeederCompletedEvent): void {
  this.completed++;
  this.logger.log(`Progress: ${this.completed}/${this.total}`);
}