mirror of
https://github.com/denoland/std.git
synced 2024-11-22 04:59:05 +00:00
d93b33aff8
Co-authored-by: Asher Gomez <ashersaupingomez@gmail.com>
85 lines
2.3 KiB
TypeScript
85 lines
2.3 KiB
TypeScript
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
|
// This module is browser compatible.
|
|
|
|
import { DEFAULT_CHUNK_SIZE } from "./_constants.ts";
|
|
import { isCloser } from "./_common.ts";
|
|
import type { Closer, Reader } from "./types.ts";
|
|
|
|
/** Options for {@linkcode toReadableStream}. */
|
|
export interface ToReadableStreamOptions {
|
|
/** If the `reader` is also a `Closer`, automatically close the `reader`
|
|
* when `EOF` is encountered, or a read error occurs.
|
|
*
|
|
* @default {true}
|
|
*/
|
|
autoClose?: boolean;
|
|
|
|
/**
|
|
* The size of chunks to allocate to read.
|
|
*
|
|
* @default {16640}
|
|
*/
|
|
chunkSize?: number;
|
|
|
|
/** The queuing strategy to create the {@linkcode ReadableStream} with. */
|
|
strategy?: QueuingStrategy<Uint8Array>;
|
|
}
|
|
|
|
/**
|
|
* Create a {@linkcode ReadableStream} of {@linkcode Uint8Array}s from a
|
|
* {@linkcode Reader}.
|
|
*
|
|
* When the pull algorithm is called on the stream, a chunk from the reader
|
|
* will be read. When `null` is returned from the reader, the stream will be
|
|
* closed along with the reader (if it is also a `Closer`).
|
|
*
|
|
* @example Usage
|
|
* ```ts no-assert
|
|
* import { toReadableStream } from "@std/io/to-readable-stream";
|
|
*
|
|
* const file = await Deno.open("./README.md", { read: true });
|
|
* const fileStream = toReadableStream(file);
|
|
* ```
|
|
*
|
|
* @param reader The reader to read from
|
|
* @param options The options
|
|
* @returns The readable stream
|
|
*/
|
|
export function toReadableStream(
|
|
reader: Reader | (Reader & Closer),
|
|
options?: ToReadableStreamOptions,
|
|
): ReadableStream<Uint8Array> {
|
|
const {
|
|
autoClose = true,
|
|
chunkSize = DEFAULT_CHUNK_SIZE,
|
|
strategy,
|
|
} = options ?? {};
|
|
|
|
return new ReadableStream({
|
|
async pull(controller) {
|
|
const chunk = new Uint8Array(chunkSize);
|
|
try {
|
|
const read = await reader.read(chunk);
|
|
if (read === null) {
|
|
if (isCloser(reader) && autoClose) {
|
|
reader.close();
|
|
}
|
|
controller.close();
|
|
return;
|
|
}
|
|
controller.enqueue(chunk.subarray(0, read));
|
|
} catch (e) {
|
|
controller.error(e);
|
|
if (isCloser(reader)) {
|
|
reader.close();
|
|
}
|
|
}
|
|
},
|
|
cancel() {
|
|
if (isCloser(reader) && autoClose) {
|
|
reader.close();
|
|
}
|
|
},
|
|
}, strategy);
|
|
}
|