import { isSseEvent, type SseEvent } from "@dada/shared-contracts";

interface Connection {
  close: () => void;
  send: (event: SseEvent) => void;
}

export class EventHub {
  readonly #connections = new Set<Connection>();

  get subscriberCount() {
    return this.#connections.size;
  }

  connect(send: Connection["send"], close: Connection["close"]) {
    const connection = { close, send };
    this.#connections.add(connection);
    return () => this.#connections.delete(connection);
  }

  publish(event: SseEvent) {
    if (!isSseEvent(event)) throw new Error("SSE event does not match the frozen non-sensitive schema.");
    for (const connection of this.#connections) connection.send(event);
  }

  disconnectAll() {
    const connections = [...this.#connections];
    this.#connections.clear();
    for (const connection of connections) connection.close();
  }
}
