EventBus.ts•2.32 kB
/**
 * EventBus
 *
 * Implementation of the event bus pattern for domain events.
 * Provides publish-subscribe functionality for loose coupling between components.
 */
export class EventBus {
  private static instance: EventBus;
  private handlers: Map<string, Function[]> = new Map();
  private constructor() {}
  /**
   * Gets the singleton instance of EventBus.
   * @returns EventBus instance
   */
  public static getInstance(): EventBus {
    if (!EventBus.instance) {
      EventBus.instance = new EventBus();
    }
    return EventBus.instance;
  }
  /**
   * Registers an event handler for a specific event type.
   * @param eventType The event type to subscribe to
   * @param handler The handler function to be called when the event occurs
   */
  public subscribe(eventType: string, handler: Function): void {
    if (!this.handlers.has(eventType)) {
      this.handlers.set(eventType, []);
    }
    const eventHandlers = this.handlers.get(eventType)!;
    if (!eventHandlers.includes(handler)) {
      eventHandlers.push(handler);
    }
  }
  /**
   * Unregisters an event handler for a specific event type.
   * @param eventType The event type to unsubscribe from
   * @param handler The handler function to be removed
   */
  public unsubscribe(eventType: string, handler: Function): void {
    if (!this.handlers.has(eventType)) {
      return;
    }
    const eventHandlers = this.handlers.get(eventType)!;
    const index = eventHandlers.indexOf(handler);
    if (index !== -1) {
      eventHandlers.splice(index, 1);
    }
    // Remove the event type if there are no more handlers
    if (eventHandlers.length === 0) {
      this.handlers.delete(eventType);
    }
  }
  /**
   * Publishes an event to all registered handlers.
   * @param eventType The type of event to publish
   * @param event The event data
   */
  public publish(eventType: string, event: any): void {
    if (!this.handlers.has(eventType)) {
      return;
    }
    const eventHandlers = this.handlers.get(eventType)!;
    for (const handler of eventHandlers) {
      try {
        handler(event);
      } catch (error) {
        console.error(`Error in event handler for ${eventType}:`, error);
      }
    }
  }
  /**
   * Clears all event handlers.
   */
  public clear(): void {
    this.handlers.clear();
  }
}