////
// Custom event system

type Events = {
  "apps:change": {},
  "session:update": Record<string, string>,
}

export function fire<K extends keyof Events>(eventName: K, detail: Events[K]) {
  window.dispatchEvent(new CustomEvent(eventName, { detail }))
}

export function on<K extends keyof Events>(eventName: K, handler: (e: CustomEvent<Events[K]>) => void) {
  const listener = handler as EventListener
  window.addEventListener(eventName, listener)

  // cleanup
  return () => window.removeEventListener(eventName, listener)
}

export function once<K extends keyof Events>(eventName: K, handler: (e: CustomEvent<Events[K]>) => void) {
  const listener = handler as EventListener;
  window.addEventListener(eventName, listener, { once: true })

  // cleanup
  return () => window.removeEventListener(eventName, listener)
}

export function off<K extends keyof Events>(eventName: K, handler: (e: CustomEvent<Events[K]>) => void) {
  window.removeEventListener(eventName, handler as EventListener)
}