/**
 * How to use Emitter:
 *
 * Create an emitter:
 *    const chat = new Emitter<{ username: string, message: string }>()
 *
 * Listen to events:
 *    const off = chat.on((data) => {
 *      const {username, message} = data;
 *      console.log(`${username} said "${message}"`);
 *    })
 *
 * Emit an event:
 *    chat.emit({ username: "Chad", message: "Hey everyone, how's it going?" });
 *
 * Remove a specific listener:
 *    off(); // The off function is returned when you add a listener
 *
 * Remove all listeners:
 *    chat.removeAllListeners()
 */
export class Emitter<T = void> {
  private listeners: Array<(data: T) => void> = []

  on(listener: (data: T) => void) {
    this.listeners.push(listener)

    return () => {
      this.listeners = this.listeners.filter((l) => l !== listener)
    }
  }

  emit(data: T) {
    for (const listener of this.listeners) {
      listener(data)
    }
  }

  removeAllListeners() {
    this.listeners = []
  }
}
