"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.WebStreamToNodeStream = WebStreamToNodeStream;
const stream_1 = require("stream");
const events_1 = require("events");
/**
 * Background async task to pull data from the browser stream and push it into the node stream.
 */
async function pull(webStream, nodeStream) {
    const reader = webStream.getReader();
    const abortController = new AbortController();
    try {
        while (true) {
            const { value, done } = await reader.read();
            if (done) {
                break;
            }
            if (!nodeStream.writable) {
                break;
            }
            const canWrite = nodeStream.write(value);
            if (!canWrite) {
                try {
                    await (0, events_1.once)(nodeStream, 'drain', abortController);
                }
                catch (e) {
                    if (e.name === 'AbortError') {
                        break;
                    }
                    throw e;
                }
            }
        }
    }
    catch (e) {
        nodeStream.destroy(e);
        abortController.abort();
    }
    finally {
        nodeStream.end();
        try {
            await reader.cancel();
        }
        catch (_) {
            /**
             * `reader.cancel` can actually throw if called on a response
             * body reader of a "cancelled" fetch. Do nothing.
             */
        }
        reader.releaseLock();
    }
}
/**
 * Convert browser ReadableStream to Node stream.Readable.
 */
function WebStreamToNodeStream(webStream, nodeStreamOptions) {
    if ('pipe' in webStream) {
        return webStream;
    }
    // use PassThrough so we can write to it
    const nodeStream = new stream_1.PassThrough(nodeStreamOptions);
    pull(webStream, nodeStream);
    return nodeStream;
}
//# sourceMappingURL=WebStreamToNodeStream.js.map