import { logger } from "@coder/logger" /** * Event emitter callback. Called with the emitted value and a promise that * resolves when all emitters have finished. */ export type Callback> = (t: T, p: Promise) => R export interface Disposable { dispose(): void } export interface Event { (listener: Callback): Disposable } /** * Emitter typecasts for a single event type. */ export class Emitter { private listeners: Array> = [] public get event(): Event { return (cb: Callback): Disposable => { this.listeners.push(cb) return { dispose: (): void => { const i = this.listeners.indexOf(cb) if (i !== -1) { this.listeners.splice(i, 1) } }, } } } /** * Emit an event with a value. */ public async emit(value: T): Promise { let resolve: () => void const promise = new Promise((r) => (resolve = r)) await Promise.all( this.listeners.map(async (cb) => { try { await cb(value, promise) } catch (error) { logger.error(error.message) } }), ) resolve!() } public dispose(): void { this.listeners = [] } }