// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { __asyncGenerator, __asyncValues, __await } from "tslib";
import { Readable } from "stream";
import { isBlob, isNodeReadableStream, isWebReadableStream } from "./typeGuards";
function streamAsyncIterator() {
    return __asyncGenerator(this, arguments, function* streamAsyncIterator_1() {
        const reader = this.getReader();
        try {
            while (true) {
                const { done, value } = yield __await(reader.read());
                if (done) {
                    return yield __await(void 0);
                }
                yield yield __await(value);
            }
        }
        finally {
            reader.releaseLock();
        }
    });
}
function makeAsyncIterable(webStream) {
    if (!webStream[Symbol.asyncIterator]) {
        webStream[Symbol.asyncIterator] = streamAsyncIterator.bind(webStream);
    }
    if (!webStream.values) {
        webStream.values = streamAsyncIterator.bind(webStream);
    }
}
function nodeStreamFromWebStream(webStream) {
    makeAsyncIterable(webStream);
    return Readable.fromWeb(webStream);
}
export function toWebStream(stream) {
    return isWebReadableStream(stream)
        ? stream
        : Readable.toWeb(Readable.from(stream));
}
export function toStream(source) {
    if (source instanceof Uint8Array) {
        return Readable.from(Buffer.from(source));
    }
    else if (isBlob(source)) {
        return nodeStreamFromWebStream(source.stream());
    }
    else if (isNodeReadableStream(source)) {
        return source;
    }
    else {
        return nodeStreamFromWebStream(source);
    }
}
export function concatenateStreams(sources) {
    if (sources.some(isWebReadableStream)) {
        throw new Error("Was not expecting a Web stream here");
    }
    return Readable.from((function () {
        return __asyncGenerator(this, arguments, function* () {
            var _a, e_1, _b, _c;
            for (const stream of sources) {
                try {
                    for (var _d = true, stream_1 = (e_1 = void 0, __asyncValues(stream)), stream_1_1; stream_1_1 = yield __await(stream_1.next()), _a = stream_1_1.done, !_a; _d = true) {
                        _c = stream_1_1.value;
                        _d = false;
                        const chunk = _c;
                        yield yield __await(chunk);
                    }
                }
                catch (e_1_1) { e_1 = { error: e_1_1 }; }
                finally {
                    try {
                        if (!_d && !_a && (_b = stream_1.return)) yield __await(_b.call(stream_1));
                    }
                    finally { if (e_1) throw e_1.error; }
                }
            }
        });
    })());
}
//# sourceMappingURL=stream.js.map