import { Deferred } from "./Deferred"; export type NonPostableEvt = { waitFor: () => Promise; subscribe: (next: (data: T) => void) => { unsubscribe: () => void }; postCount: number; }; export type Evt = NonPostableEvt & { post: (data: T) => void; }; export function createEvt(): Evt { const listeners: Array<(data: T) => void> = []; let postCount = 0; const evt: Evt = { subscribe: next => { listeners.push(next); let isActive = true; return { unsubscribe: () => { if (!isActive) { return; } isActive = false; const i = listeners.indexOf(next); if (i >= 0) { listeners.splice(i, 1); } } }; }, waitFor: () => { const d = new Deferred(); const { unsubscribe } = evt.subscribe(data => { unsubscribe(); d.resolve(data); }); return d.pr; }, post: (data: T) => { postCount++; const snapshot = listeners.slice(); for (const l of snapshot) { try { l(data); } catch {} } }, get postCount() { return postCount; } }; return evt; }