UNPKG

univ-conv

Version:

The universal binary and text converter

200 lines 7.74 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ReadableStreamConverter = exports.createPartialReadableStream = void 0; const AbstractConverter_1 = require("./AbstractConverter"); const core_1 = require("./core"); const Environment_1 = require("./Environment"); function createReadableStream(u8) { return new ReadableStream({ start: (controller) => { controller.enqueue(u8); }, }); } function createPartialReadableStream(source, startEnd) { const reader = source.getReader(); const start = startEnd.start; const end = startEnd.end ?? Number.MAX_SAFE_INTEGER; return new ReadableStream({ start: async (controller) => { let iStart = 0; let res; do { res = await reader.read(); const value = res.value; if (value) { const u8 = value; const length = u8.byteLength; const iEnd = iStart + length; const u8End = (iEnd < end ? iEnd : end) - iStart; let chunk; if (iStart <= start && start < iEnd) { chunk = u8.subarray(start - iStart, u8End); } else if (start < iStart && iStart < end) { chunk = u8.subarray(0, u8End); } if (chunk) { controller.enqueue(chunk); } iStart += length; } } while (!res.done && iStart < end); controller.close(); reader.releaseLock(); (0, Environment_1.closeStream)(source); }, cancel: (e) => { reader.releaseLock(); (0, Environment_1.closeStream)(source, e); }, }); } exports.createPartialReadableStream = createPartialReadableStream; function createReadableStreamOfReader(readable, options) { const startEnd = (0, core_1.getStartEnd)(options); const start = startEnd.start; const end = startEnd.end ?? Number.MAX_SAFE_INTEGER; const bufferSize = options.bufferSize; const converter = (0, AbstractConverter_1._)()._of("uint8array"); let iStart = 0; return new ReadableStream({ start: async (controller) => { await (0, Environment_1.handleReadable)(readable, async (value) => { const u8 = await converter.from(value, { bufferSize }); const size = u8.byteLength; const iEnd = iStart + size; const u8End = (iEnd < end ? iEnd : end) - iStart; let chunk; if (iStart <= start && start < iEnd) { chunk = u8.subarray(start - iStart, u8End); } else if (start < iStart && iStart < end) { chunk = u8.subarray(0, u8End); } if (chunk) { controller.enqueue(chunk); } iStart += size; return iStart < end; }); }, cancel: (err) => { readable.destroy(err); }, }); } class ReadableStreamConverter extends AbstractConverter_1.AbstractConverter { constructor() { super(...arguments); this.type = "readablestream"; } empty() { return new ReadableStream({ start: (converter) => { converter.enqueue(core_1.EMPTY_UINT8_ARRAY); converter.close(); }, }); } is(input) { return (0, Environment_1.isReadableStream)(input); } async _from(input, options) { if (typeof input === "string" && options.inputStringType === "url") { if (input.startsWith("http:") || input.startsWith("https:")) { const resp = await fetch(input); if ((0, AbstractConverter_1._)().is("readable", resp.body, options)) { input = resp.body; } else { input = resp.body; } } else if (input.startsWith("file:") && Environment_1.fileURLToReadable) { input = await (0, Environment_1.fileURLToReadable)(input); } } if ((0, AbstractConverter_1._)().is("readable", input, options)) { return createReadableStreamOfReader(input, options); } if (Environment_1.hasStreamOnBlob) { if ((0, AbstractConverter_1._)().is("blob", input, options)) { input = input.stream(); } else { const blob = await (0, AbstractConverter_1._)().convert("blob", input, options); input = blob.stream(); } } if (this.is(input)) { return createPartialReadableStream(input, await this._getStartEnd(input, options)); } const u8 = await (0, AbstractConverter_1._)().convert("uint8array", input, options); const { start, end } = (0, core_1.getStartEnd)(options, u8.byteLength); return createReadableStream(u8.slice(start, end)); } _getStartEnd(_input, options) { return Promise.resolve((0, core_1.getStartEnd)(options)); } _isEmpty() { return false; } _merge(streams) { const end = streams.length; const process = (controller, i) => { if (i < end) { const stream = streams[i]; (0, Environment_1.handleReadableStream)(stream, (chunk) => { controller.enqueue(chunk); return Promise.resolve(true); }) .then(() => process(controller, ++i)) .catch((e) => { controller.error(e); for (let j = i; j < end; j++) { const s = streams[j]; (0, Environment_1.closeStream)(s); } }); } else { controller.close(); } }; return Promise.resolve(new ReadableStream({ start: (converter) => { process(converter, 0); }, })); } _size() { throw new Error("Cannot get size of ReadableStream"); } async _toArrayBuffer(input, options) { const u8 = await this._toUint8Array(input, options); return u8.buffer.slice(u8.byteOffset, u8.byteOffset + u8.byteLength); } async _toBase64(input, options) { const opts = { bufferSize: options.bufferSize }; const t = Environment_1.isBrowser ? "blob" : "uint8array"; const convertd = await (0, AbstractConverter_1._)().convert(t, input, opts); return await (0, AbstractConverter_1._)()._of(t).toBase64(convertd, options); } async _toText(input, options) { const opts = { bufferSize: options.bufferSize }; const t = Environment_1.isBrowser ? "blob" : "uint8array"; const convertd = await (0, AbstractConverter_1._)().convert(t, input, opts); return await (0, AbstractConverter_1._)()._of(t).toText(convertd, options); } async _toUint8Array(input, options) { const chunks = []; await (0, Environment_1.handleReadableStream)(input, async (chunk) => { chunks.push(chunk); return Promise.resolve(true); }); return await (0, AbstractConverter_1._)()._of("uint8array").merge(chunks, options); } } exports.ReadableStreamConverter = ReadableStreamConverter; //# sourceMappingURL=ReadableStreamConverter.js.map