import { Arr } from "../types.ts"; import { pushIter, addIterUtils } from "./util/mod.ts"; type Listener = { push: (arg: T) => void; done: () => void }; export type IterSource = ReturnType>; export function fromCallback( source: (listener: (...values: T) => void) => void, disconnect?: () => void ) { let isDone = false; let listeners: Listener[] = []; function trigger(...values: T) { if (isDone) { return; } for (const listener of listeners) { listener.push(values); } } source(trigger); function done() { disconnect?.(); if (isDone) { return; } for (const listener of listeners) { listener.done(); } listeners = []; isDone = true; } function addListener(listener: Listener) { listeners.push(listener); return () => { removeListener(listener); }; } function removeListener(listener: Listener) { const index = listeners.indexOf(listener); listeners.splice(index, 1); } return { iterator: () => { const { push, done, getIterator } = pushIter(); addListener({ push, done }); return addIterUtils(getIterator()); }, disconnect: done, }; }