domain-event.ts raw

   1  /**
   2   * Base class for all domain events.
   3   * Domain events capture significant occurrences in the domain that
   4   * domain experts care about.
   5   */
   6  export abstract class DomainEvent {
   7    readonly occurredAt: Date;
   8    readonly eventId: string;
   9  
  10    constructor() {
  11      this.occurredAt = new Date();
  12      this.eventId = crypto.randomUUID();
  13    }
  14  
  15    /**
  16     * Get the event type identifier.
  17     * Used for event routing and serialization.
  18     */
  19    abstract get eventType(): string;
  20  }
  21  
  22  /**
  23   * Interface for entities that can raise domain events.
  24   */
  25  export interface EventRaiser {
  26    /**
  27     * Pull all pending domain events from the entity.
  28     * This clears the internal event list.
  29     */
  30    pullDomainEvents(): DomainEvent[];
  31  }
  32  
  33  /**
  34   * Base class for aggregate roots that can raise domain events.
  35   */
  36  export abstract class AggregateRoot implements EventRaiser {
  37    private _domainEvents: DomainEvent[] = [];
  38  
  39    protected addDomainEvent(event: DomainEvent): void {
  40      this._domainEvents.push(event);
  41    }
  42  
  43    pullDomainEvents(): DomainEvent[] {
  44      const events = [...this._domainEvents];
  45      this._domainEvents = [];
  46      return events;
  47    }
  48  
  49    /**
  50     * Check if there are any pending domain events.
  51     */
  52    hasPendingEvents(): boolean {
  53      return this._domainEvents.length > 0;
  54    }
  55  }
  56