var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
    if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
    var g = generator.apply(thisArg, _arguments || []), i, q = [];
    return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
    function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }
    function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
    function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
    function fulfill(value) { resume("next", value); }
    function reject(value) { resume("throw", value); }
    function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
};
var __asyncValues = (this && this.__asyncValues) || function (o) {
    if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
    var m = o[Symbol.asyncIterator], i;
    return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
    function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
    function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
};
import { fileTypeFromBuffer } from 'file-type';
import { concat as uint8ArrayConcat } from 'uint8arrays/concat';
import { serializeError } from 'serialize-error';
export const getMimeFromUint8Array = (raw) => __awaiter(void 0, void 0, void 0, function* () {
    if (!raw) {
        return 'unknown';
    }
    const fileType = yield fileTypeFromBuffer(raw);
    return (fileType === null || fileType === void 0 ? void 0 : fileType.mime) || 'text/plain';
});
export function toAsyncIterableWithMime(stream, flush) {
    return __awaiter(this, void 0, void 0, function* () {
        const [firstChunkStream, fullStream] = stream.tee();
        const chunks = [];
        const firstReader = firstChunkStream.getReader();
        const { value } = yield firstReader.read();
        const mime = value ? yield getMimeFromUint8Array(value) : undefined;
        const restReader = fullStream.getReader();
        const asyncIterable = {
            [Symbol.asyncIterator]() {
                return __asyncGenerator(this, arguments, function* _a() {
                    while (true) {
                        const { done, value } = yield __await(restReader.read());
                        if (done) {
                            flush && flush(chunks, mime);
                            return yield __await(void 0);
                        }
                        flush && chunks.push(value);
                        yield yield __await(value);
                    }
                });
            },
        };
        return { mime, result: asyncIterable, firstChunk: value };
    });
}
export function toReadableStreamWithMime(stream, flush) {
    return __awaiter(this, void 0, void 0, function* () {
        const [firstChunkStream, fullStream] = stream.tee();
        const chunks = [];
        const firstReader = firstChunkStream.getReader();
        const { value } = yield firstReader.read();
        const mime = value ? yield getMimeFromUint8Array(value) : undefined;
        const modifiedStream = new ReadableStream({
            pull(controller) {
                return __awaiter(this, void 0, void 0, function* () {
                    const restReader = fullStream.getReader();
                    const { done, value } = yield restReader.read();
                    if (done) {
                        controller.close();
                        flush && flush(chunks, mime);
                    }
                    else {
                        controller.enqueue(value);
                        flush && chunks.push(value);
                    }
                    restReader.releaseLock();
                });
            },
            cancel() {
                firstChunkStream.cancel();
                fullStream.cancel();
            },
        });
        return { mime, result: modifiedStream, firstChunk: value };
    });
}
export const getResponseResult = (response, onProgress) => __awaiter(void 0, void 0, void 0, function* () {
    var _a, e_1, _b, _c;
    let bytesDownloaded = 0;
    try {
        if (response instanceof Uint8Array) {
            onProgress && onProgress(response.byteLength);
            return response;
        }
        const chunks = [];
        if (response instanceof ReadableStream) {
            const reader = response.getReader();
            const readStream = ({ done, value, }) => __awaiter(void 0, void 0, void 0, function* () {
                if (done) {
                    return uint8ArrayConcat(chunks);
                }
                chunks.push(value);
                bytesDownloaded += value.byteLength;
                onProgress && onProgress(bytesDownloaded);
                return reader.read().then(readStream);
            });
            const readArray = yield reader.read().then(readStream);
            return readArray;
        }
        const reader = response[Symbol.asyncIterator]();
        try {
            for (var _d = true, reader_1 = __asyncValues(reader), reader_1_1; reader_1_1 = yield reader_1.next(), _a = reader_1_1.done, !_a;) {
                _c = reader_1_1.value;
                _d = false;
                try {
                    const chunk = _c;
                    if (chunk instanceof Uint8Array) {
                        chunks.push(chunk);
                        bytesDownloaded += chunk.byteLength;
                        onProgress && onProgress(bytesDownloaded);
                    }
                }
                finally {
                    _d = true;
                }
            }
        }
        catch (e_1_1) { e_1 = { error: e_1_1 }; }
        finally {
            try {
                if (!_d && !_a && (_b = reader_1.return)) yield _b.call(reader_1);
            }
            finally { if (e_1) throw e_1.error; }
        }
        const result = uint8ArrayConcat(chunks);
        return result;
    }
    catch (error) {
        const serializedError = serializeError(error);
        console.error(`Error reading stream/iterable.\r\n Probably Hot reload error!`, JSON.stringify(serializedError, null, 2));
        return undefined;
    }
});
//# sourceMappingURL=stream.js.map