Creating Custom Events

What is the recommended way to implement event-driven communication between components?
class EventBus {
  static #instance;
  #listeners = new Map();

  static getInstance() {
    if (!EventBus.#instance) {
      EventBus.#instance = new EventBus();
    }
    return EventBus.#instance;
  }

  emit(eventName, detail) {
    const event = new CustomEvent(eventName, { detail });
    document.dispatchEvent(event);
  }

  on(eventName, callback) {
    if (!this.#listeners.has(eventName)) {
      this.#listeners.set(eventName, new Set());
    }
    const handlers = this.#listeners.get(eventName);
    handlers.add(callback);
    document.addEventListener(eventName, callback);
  }

  off(eventName, callback) {
    const handlers = this.#listeners.get(eventName);
    if (handlers) {
      handlers.delete(callback);
      document.removeEventListener(eventName, callback);
    }
  }
}
Next Question (12/20)