486
*/
487
export function peekReadable<T>(readable: Readable<T>, reducer: IReducer<T>, maxChunks: number): T | Readable<T> {
489
>
490
>
let chunk: T | null | undefined = undefined;
491
>
while ((chunk = readable.read()) !== null && chunks.length < maxChunks) {
492
>
chunks.push(chunk);
493
>
}
494
>
495
>
// If the last chunk is null, it means we reached the end of
496
>
// the readable and return all the data at once
497
>
if (chunk === null && chunks.length > 0) {
498
>
return reducer(chunks);
499
>
}
500
>
501
>
// Otherwise, we still have a chunk, it means we reached the maxChunks
502
>
// value and as such we return a new Readable that first returns
503
>
// the existing read chunks and then continues with reading from
504
>
// the underlying readable.
505
>
return {
506
>
read: () => {
507
>
508
>
// First consume chunks from our array
509
>
if (chunks.length > 0) {
510
>
return chunks.shift()!;
511
>
}
512
>
513
>
// Then ensure to return our last read chunk
514
>
if (typeof chunk !== 'undefined') {
515
>
const lastReadChunk = chunk;
516
>
517
>
// explicitly use undefined here to indicate that we consumed
518
>
// the chunk, which could have either been null or valued.
519
>
chunk = undefined;
520
>
521
>
return lastReadChunk;
522
>
}
523
>
524
>
// Finally delegate back to the Readable
525
>
return readable.read();
526
>
}
527
>
};
528
>
}
529
530
/**