import { createLazyPromise, type LazyPromise } from './createLazyPromise'; import type { MaybePromise } from './MaybePromise'; type Val = [val: MaybePromise | undefined, done: boolean, err?: any]; export function createAsyncIterator( fn: (next: (val: [MaybePromise | undefined, boolean] | undefined, err?: any) => void) => void, ): AsyncGenerator { const values: Array>> = []; let recv: (val: [MaybePromise | undefined, boolean] | undefined, err?: any) => void; { let next: LazyPromise>; values.push((next = createLazyPromise())); recv = (val, err) => { if (err !== undefined) { next.resolve([undefined, true, err]); } else if (val !== undefined) { next.resolve(val); } else { return; } values.push((next = createLazyPromise())); }; } fn(recv); return (async function* () { let value: Val[0]; let err: any; for (let i = 0, done = false; !done; i++) { let result = await values[i]; delete values[i]; [value, done, err] = result; if (err) { throw err; } if (value !== undefined) { yield value; } } })(); }