import { UnsubscribeCallback } from "./types"; type Subscriber = (...payload: T) => void; export class Emitter { public subscribers: Subscriber[] = []; /** * Attaches subscriber * * @returns unsubscribe function */ on(...handlers: Subscriber[] | Subscriber[][]): UnsubscribeCallback { const _handlers = handlers .flat() .filter((item) => typeof item === "function"); this.subscribers.push(..._handlers); return () => this.off(_handlers); } once(...handlers: Subscriber[] | Subscriber[][]): UnsubscribeCallback { const _handlers = handlers .flat() .filter((item) => typeof item === "function"); _handlers.push(() => detach()); const detach = this.on(..._handlers); return detach; } off(...handlers: Subscriber[] | Subscriber[][]) { const _handlers = handlers.flat(); this.subscribers = this.subscribers.filter( (handler) => !_handlers.includes(handler), ); } trigger(...payload: T) { for (const handler of this.subscribers) { handler(...payload); } return this; } clear() { this.subscribers = []; } }