|
|
import {getAsyncIterable} from './stream.js';
export const getStreamContents = async (stream, {init, convertChunk, getSize, truncateChunk, addChunk, getFinalChunk, finalize}, {maxBuffer = Number.POSITIVE_INFINITY} = {}) => { const asyncIterable = getAsyncIterable(stream);
const state = init(); state.length = 0;
try { for await (const chunk of asyncIterable) { const chunkType = getChunkType(chunk); const convertedChunk = convertChunk[chunkType](chunk, state); appendChunk({ convertedChunk, state, getSize, truncateChunk, addChunk, maxBuffer, }); }
appendFinalChunk({ state, convertChunk, getSize, truncateChunk, addChunk, getFinalChunk, maxBuffer, }); return finalize(state); } catch (error) { const normalizedError = typeof error === 'object' && error !== null ? error : new Error(error); normalizedError.bufferedData = finalize(state); throw normalizedError; }};
const appendFinalChunk = ({state, getSize, truncateChunk, addChunk, getFinalChunk, maxBuffer}) => { const convertedChunk = getFinalChunk(state); if (convertedChunk !== undefined) { appendChunk({ convertedChunk, state, getSize, truncateChunk, addChunk, maxBuffer, }); }};
const appendChunk = ({convertedChunk, state, getSize, truncateChunk, addChunk, maxBuffer}) => { const chunkSize = getSize(convertedChunk); const newLength = state.length + chunkSize;
if (newLength <= maxBuffer) { addNewChunk(convertedChunk, state, addChunk, newLength); return; }
const truncatedChunk = truncateChunk(convertedChunk, maxBuffer - state.length);
if (truncatedChunk !== undefined) { addNewChunk(truncatedChunk, state, addChunk, maxBuffer); }
throw new MaxBufferError();};
const addNewChunk = (convertedChunk, state, addChunk, newLength) => { state.contents = addChunk(convertedChunk, state, newLength); state.length = newLength;};
const getChunkType = chunk => { const typeOfChunk = typeof chunk;
if (typeOfChunk === 'string') { return 'string'; }
if (typeOfChunk !== 'object' || chunk === null) { return 'others'; }
if (globalThis.Buffer?.isBuffer(chunk)) { return 'buffer'; }
const prototypeName = objectToString.call(chunk);
if (prototypeName === '[object ArrayBuffer]') { return 'arrayBuffer'; }
if (prototypeName === '[object DataView]') { return 'dataView'; }
if ( Number.isInteger(chunk.byteLength) && Number.isInteger(chunk.byteOffset) && objectToString.call(chunk.buffer) === '[object ArrayBuffer]' ) { return 'typedArray'; }
return 'others';};
const {toString: objectToString} = Object.prototype;
export class MaxBufferError extends Error { name = 'MaxBufferError';
constructor() { super('maxBuffer exceeded'); }}
|