/** | |
* @returns {import('types').Deferred & { promise: Promise<any> }}} | |
*/ | |
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<any>; | |
* 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 }); | |
} | |
}; | |
} | |