/** * @returns {import('types').Deferred & { promise: Promise }}} */ function defer() { let fulfil; let reject; const promise = new Promise((f, r) => { fulfil = f; reject = r; }); // @ts-expect-error return { promise, fulfil, reject }; } /** * Create an async iterator and a function to push values into it * @returns {{ * iterator: AsyncIterable; * push: (value: any) => void; * done: () => void; * }} */ export function create_async_iterator() { const deferred = [defer()]; return { iterator: { [Symbol.asyncIterator]() { return { next: async () => { const next = await deferred[0].promise; if (!next.done) deferred.shift(); return next; } }; } }, push: (value) => { deferred[deferred.length - 1].fulfil({ value, done: false }); deferred.push(defer()); }, done: () => { deferred[deferred.length - 1].fulfil({ done: true }); } }; }