You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

49 lines
1.2 KiB

module.exports = async function* iterateStream(stream) {
const contents = [];
stream.on('data', data => contents.push(data));
let resolveStreamEndedPromise;
const streamEndedPromise = new Promise(resolve => (resolveStreamEndedPromise = resolve));
let ended = false;
stream.on('end', () => {
ended = true;
resolveStreamEndedPromise();
});
let error = false;
stream.on('error', err => {
error = err;
resolveStreamEndedPromise();
});
while (!ended || contents.length > 0) {
if (contents.length === 0) {
stream.resume();
// eslint-disable-next-line no-await-in-loop
await Promise.race([once(stream, 'data'), streamEndedPromise]);
} else {
stream.pause();
const data = contents.shift();
yield data;
}
if (error) throw error;
}
resolveStreamEndedPromise();
};
function once(eventEmitter, type) {
// TODO: Use require('events').once when node v10 is dropped
return new Promise(resolve => {
let fired = false;
const handler = () => {
if (!fired) {
fired = true;
eventEmitter.removeListener(type, handler);
resolve();
}
};
eventEmitter.addListener(type, handler);
});
}