diff --git a/io/iterate_reader_test.ts b/io/iterate_reader_test.ts index ac806a83319a..c59a36e1b50d 100644 --- a/io/iterate_reader_test.ts +++ b/io/iterate_reader_test.ts @@ -2,7 +2,7 @@ import { assertEquals } from "@std/assert/assert-equals"; // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. import { iterateReader, iterateReaderSync } from "./iterate_reader.ts"; -import { readerFromIterable } from "@std/streams/reader-from-iterable"; +import { readerFromStreamReader } from "./reader_from_stream_reader.ts"; import { delay } from "@std/async/delay"; import type { Reader, ReaderSync } from "./types.ts"; @@ -45,7 +45,9 @@ Deno.test("iterateReader()", async () => { Deno.test("iterateReader() works with slow consumer", async () => { const a = new Uint8Array([97]); const b = new Uint8Array([98]); - const iter = iterateReader(readerFromIterable([a, b])); + const iter = iterateReader( + readerFromStreamReader(ReadableStream.from([a, b]).getReader()), + ); const promises = []; for await (const bytes of iter) { promises.push(delay(10).then(() => bytes)); diff --git a/streams/deno.json b/streams/deno.json index f2fcc7223f07..d03c1fac1de9 100644 --- a/streams/deno.json +++ b/streams/deno.json @@ -8,13 +8,9 @@ "./concat-readable-streams": "./concat_readable_streams.ts", "./delimiter-stream": "./delimiter_stream.ts", "./early-zip-readable-streams": "./early_zip_readable_streams.ts", - "./iterate-reader": "./iterate_reader.ts", "./limited-bytes-transform-stream": "./limited_bytes_transform_stream.ts", "./limited-transform-stream": "./limited_transform_stream.ts", "./merge-readable-streams": "./merge_readable_streams.ts", - "./readable-stream-from-reader": "./readable_stream_from_reader.ts", - "./reader-from-iterable": "./reader_from_iterable.ts", - "./reader-from-stream-reader": "./reader_from_stream_reader.ts", "./text-delimiter-stream": "./text_delimiter_stream.ts", "./text-line-stream": "./text_line_stream.ts", "./to-array-buffer": "./to_array_buffer.ts", @@ -22,8 +18,6 @@ "./to-json": "./to_json.ts", "./to-text": "./to_text.ts", "./to-transform-stream": "./to_transform_stream.ts", - "./writable-stream-from-writer": "./writable_stream_from_writer.ts", - "./writer-from-stream-writer": "./writer_from_stream_writer.ts", "./zip-readable-streams": "./zip_readable_streams.ts" } } diff --git a/streams/iterate_reader.ts b/streams/iterate_reader.ts deleted file mode 100644 index 3ef3c38e30de..000000000000 --- a/streams/iterate_reader.ts +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. -// This module is browser compatible. - -import { - iterateReader as _iterateReader, - iterateReaderSync as _iterateReaderSync, -} from "@std/io/iterate-reader"; -import type { Reader, ReaderSync } from "@std/io/types"; - -export type { Reader, ReaderSync }; - -/** - * Turns a {@linkcode https://jsr.io/@std/io/doc/types/~/Reader | Reader}, `r`, into an async iterator. - * - * @param r A reader to turn into an async iterator. - * @param options Options for the iterateReader function. - * @returns An async iterator that yields Uint8Array. - * - * @example Convert a `Deno.FsFile` into an async iterator and iterate over it - * ```ts no-assert no-eval - * import { iterateReader } from "@std/streams/iterate-reader"; - * - * using f = await Deno.open("./README.md"); - * for await (const chunk of iterateReader(f)) { - * console.log(chunk); - * } - * ``` - * - * @example Specify a buffer size of 1MiB - * ```ts no-assert no-eval - * import { iterateReader } from "@std/streams/iterate-reader"; - * - * using f = await Deno.open("./README.md"); - * const it = iterateReader(f, { - * bufSize: 1024 * 1024 - * }); - * for await (const chunk of it) { - * console.log(chunk); - * } - * ``` - * - * @deprecated This will be removed in 1.0.0. Import from - * {@link https://jsr.io/@std/io | @std/io} instead. - */ -export function iterateReader( - r: Reader, - options?: { - bufSize?: number; - }, -): AsyncIterableIterator { - return _iterateReader(r, options); -} - -/** - * Turns a {@linkcode https://jsr.io/@std/io/doc/types/~/ReaderSync | ReaderSync}, `r`, into an iterator. - * - * @param r A reader to turn into an iterator. - * @param options Options for the iterateReaderSync function. - * @returns An iterator that yields Uint8Array. - * - * @example Convert a `Deno.FsFile` into an iterator and iterate over it - * ```ts no-eval no-assert - * import { iterateReaderSync } from "@std/streams/iterate-reader"; - * - * using f = Deno.openSync("./README.md"); - * for (const chunk of iterateReaderSync(f)) { - * console.log(chunk); - * } - * ``` - * - * @example Specify a buffer size of 1MiB - * ```ts no-eval no-assert - * import { iterateReaderSync } from "@std/streams/iterate-reader"; - * - * using f = await Deno.open("./README.md"); - * const iter = iterateReaderSync(f, { - * bufSize: 1024 * 1024 - * }); - * for (const chunk of iter) { - * console.log(chunk); - * } - * ``` - * - * Iterator uses an internal buffer of fixed size for efficiency; it returns - * a view on that buffer on each iteration. It is therefore caller's - * responsibility to copy contents of the buffer if needed; otherwise the - * next iteration will overwrite contents of previously returned chunk. - * - * @deprecated This will be removed in 1.0.0. Import from - * {@link https://jsr.io/@std/io | @std/io} instead. - */ -export function iterateReaderSync( - r: ReaderSync, - options?: { - bufSize?: number; - }, -): IterableIterator { - return _iterateReaderSync(r, options); -} diff --git a/streams/iterate_reader_test.ts b/streams/iterate_reader_test.ts deleted file mode 100644 index e116c6d98722..000000000000 --- a/streams/iterate_reader_test.ts +++ /dev/null @@ -1,111 +0,0 @@ -import { assertEquals } from "@std/assert"; -// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. - -import { iterateReader, iterateReaderSync } from "./iterate_reader.ts"; -import { readerFromIterable } from "./reader_from_iterable.ts"; -import { delay } from "@std/async/delay"; -import type { Reader, ReaderSync } from "@std/io/types"; - -Deno.test("iterateReader()", async () => { - // ref: https://github.com/denoland/deno/issues/2330 - const encoder = new TextEncoder(); - - class TestReader implements Reader { - #offset = 0; - #buf: Uint8Array; - - constructor(s: string) { - this.#buf = new Uint8Array(encoder.encode(s)); - } - - read(p: Uint8Array): Promise { - const n = Math.min(p.byteLength, this.#buf.byteLength - this.#offset); - p.set(this.#buf.slice(this.#offset, this.#offset + n)); - this.#offset += n; - - if (n === 0) { - return Promise.resolve(null); - } - - return Promise.resolve(n); - } - } - - const reader = new TestReader("hello world!"); - - let totalSize = 0; - await Array.fromAsync( - iterateReader(reader), - (buf) => totalSize += buf.byteLength, - ); - - assertEquals(totalSize, 12); -}); - -Deno.test("iterateReader() works with slow consumer", async () => { - const a = new Uint8Array([97]); - const b = new Uint8Array([98]); - const iter = iterateReader(readerFromIterable([a, b])); - const promises = []; - for await (const bytes of iter) { - promises.push(delay(10).then(() => bytes)); - } - assertEquals([a, b], await Promise.all(promises)); -}); - -Deno.test("iterateReaderSync()", () => { - // ref: https://github.com/denoland/deno/issues/2330 - const encoder = new TextEncoder(); - - class TestReader implements ReaderSync { - #offset = 0; - #buf: Uint8Array; - - constructor(s: string) { - this.#buf = new Uint8Array(encoder.encode(s)); - } - - readSync(p: Uint8Array): number | null { - const n = Math.min(p.byteLength, this.#buf.byteLength - this.#offset); - p.set(this.#buf.slice(this.#offset, this.#offset + n)); - this.#offset += n; - - if (n === 0) { - return null; - } - - return n; - } - } - - const reader = new TestReader("hello world!"); - - let totalSize = 0; - for (const buf of iterateReaderSync(reader)) { - totalSize += buf.byteLength; - } - - assertEquals(totalSize, 12); -}); - -Deno.test("iterateReaderSync() works with slow consumer", async () => { - const a = new Uint8Array([97]); - const b = new Uint8Array([98]); - const data = [a, b]; - const readerSync = { - readSync(u8: Uint8Array) { - const bytes = data.shift(); - if (bytes) { - u8.set(bytes); - return bytes.length; - } - return null; - }, - }; - const iter = iterateReaderSync(readerSync); - const promises = []; - for (const bytes of iter) { - promises.push(delay(10).then(() => bytes)); - } - assertEquals([a, b], await Promise.all(promises)); -}); diff --git a/streams/mod.ts b/streams/mod.ts index 21778ab9f5bd..a9f9178dc511 100644 --- a/streams/mod.ts +++ b/streams/mod.ts @@ -23,13 +23,9 @@ export * from "./byte_slice_stream.ts"; export * from "./concat_readable_streams.ts"; export * from "./delimiter_stream.ts"; export * from "./early_zip_readable_streams.ts"; -export * from "./iterate_reader.ts"; export * from "./limited_bytes_transform_stream.ts"; export * from "./limited_transform_stream.ts"; export * from "./merge_readable_streams.ts"; -export * from "./readable_stream_from_reader.ts"; -export * from "./reader_from_iterable.ts"; -export * from "./reader_from_stream_reader.ts"; export * from "./text_delimiter_stream.ts"; export * from "./text_line_stream.ts"; export * from "./to_array_buffer.ts"; @@ -37,6 +33,4 @@ export * from "./to_blob.ts"; export * from "./to_json.ts"; export * from "./to_text.ts"; export * from "./to_transform_stream.ts"; -export * from "./writable_stream_from_writer.ts"; -export * from "./writer_from_stream_writer.ts"; export * from "./zip_readable_streams.ts"; diff --git a/streams/readable_stream_from_reader.ts b/streams/readable_stream_from_reader.ts deleted file mode 100644 index 88670f0e362c..000000000000 --- a/streams/readable_stream_from_reader.ts +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. -// This module is browser compatible. - -import { toReadableStream } from "@std/io/to-readable-stream"; -import type { Closer, Reader } from "@std/io/types"; -export type { Closer }; - -/** - * Options for {@linkcode readableStreamFromReader}. - * - * @deprecated This will be removed in 1.0.0. Use {@linkcode https://jsr.io/@std/io/doc/~/toReadableStream | toReadableStream} instead. - */ -export interface ReadableStreamFromReaderOptions { - /** 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, the default is ~16KiB, which is - * the maximum size that Deno operations can currently support. */ - chunkSize?: number; - - /** The queuing strategy to create the `ReadableStream` with. */ - strategy?: { highWaterMark?: number | undefined; size?: undefined }; -} - -/** - * Create a {@linkcode ReadableStream} of {@linkcode Uint8Array}s from a - * {@linkcode https://jsr.io/@std/io/doc/types/~/Reader | 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 {@linkcode https://jsr.io/@std/io/doc/types/~/Closer | Closer}). - * - * @param reader A reader to convert into a `ReadableStream`. - * @param options Options for the `readableStreamFromReader` function. - * @returns A `ReadableStream` of `Uint8Array`s. - * - * @example Convert a `Deno.FsFile` into a readable stream: - * ```ts no-eval no-assert - * import { readableStreamFromReader } from "@std/streams/readable-stream-from-reader"; - * - * using file = await Deno.open("./README.md", { read: true }); - * const fileStream = readableStreamFromReader(file); - * ``` - * - * @deprecated This will be removed in 1.0.0. Use {@linkcode https://jsr.io/@std/io/doc/~/toReadableStream | toReadableStream} instead. - */ -export function readableStreamFromReader( - reader: Reader | (Reader & Closer), - options: ReadableStreamFromReaderOptions = {}, -): ReadableStream { - return toReadableStream(reader, options); -} diff --git a/streams/readable_stream_from_reader_test.ts b/streams/readable_stream_from_reader_test.ts deleted file mode 100644 index 1ec1d6fc739c..000000000000 --- a/streams/readable_stream_from_reader_test.ts +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. - -import { assertEquals } from "@std/assert"; -import { readableStreamFromReader } from "./readable_stream_from_reader.ts"; -import { Buffer } from "@std/io/buffer"; -import { concat } from "@std/bytes/concat"; -import { copy } from "@std/bytes/copy"; -import type { Closer, Reader } from "@std/io/types"; - -class MockReaderCloser implements Reader, Closer { - chunks: Uint8Array[] = []; - closeCall = 0; - - read(p: Uint8Array): Promise { - if (this.closeCall) { - throw new Error("already closed"); - } - if (p.length === 0) { - return Promise.resolve(0); - } - const chunk = this.chunks.shift(); - if (chunk) { - const copied = copy(chunk, p); - if (copied < chunk.length) { - this.chunks.unshift(chunk.subarray(copied)); - } - return Promise.resolve(copied); - } - return Promise.resolve(null); - } - - close() { - this.closeCall++; - } -} - -Deno.test("readableStreamFromReader()", async function () { - const encoder = new TextEncoder(); - const reader = new Buffer(encoder.encode("hello deno land")); - const stream = readableStreamFromReader(reader); - const actual = await Array.fromAsync(stream); - const decoder = new TextDecoder(); - assertEquals(decoder.decode(concat(actual)), "hello deno land"); -}); - -Deno.test({ - name: "readableStreamFromReader() auto closes closer", - async fn() {}, -}); - -Deno.test("readableStreamFromReader() calls close", async function () { - const encoder = new TextEncoder(); - const reader = new MockReaderCloser(); - reader.chunks = [ - encoder.encode("hello "), - encoder.encode("deno "), - encoder.encode("land"), - ]; - const stream = readableStreamFromReader(reader); - const actual = await Array.fromAsync(stream); - const decoder = new TextDecoder(); - assertEquals(decoder.decode(concat(actual)), "hello deno land"); - assertEquals(reader.closeCall, 1); -}); - -Deno.test("readableStreamFromReader() doesn't call close with autoClose false", async function () { - const encoder = new TextEncoder(); - const reader = new MockReaderCloser(); - reader.chunks = [ - encoder.encode("hello "), - encoder.encode("deno "), - encoder.encode("land"), - ]; - const stream = readableStreamFromReader(reader, { autoClose: false }); - const actual = await Array.fromAsync(stream); - const decoder = new TextDecoder(); - assertEquals(decoder.decode(concat(actual)), "hello deno land"); - assertEquals(reader.closeCall, 0); -}); - -Deno.test("readableStreamFromReader() handles chunkSize", async function () { - const encoder = new TextEncoder(); - const reader = new MockReaderCloser(); - reader.chunks = [ - encoder.encode("hello "), - encoder.encode("deno "), - encoder.encode("land"), - ]; - const stream = readableStreamFromReader(reader, { chunkSize: 2 }); - const actual = await Array.fromAsync(stream); - const decoder = new TextDecoder(); - assertEquals(actual.length, 8); - assertEquals(decoder.decode(concat(actual)), "hello deno land"); - assertEquals(reader.closeCall, 1); -}); diff --git a/streams/reader_from_iterable.ts b/streams/reader_from_iterable.ts deleted file mode 100644 index 16be4f070ba3..000000000000 --- a/streams/reader_from_iterable.ts +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. -// This module is browser compatible. - -import { Buffer } from "@std/io/buffer"; -import { writeAll } from "@std/io/write-all"; -import type { Reader } from "@std/io/types"; - -/** - * Create a {@linkcode https://jsr.io/@std/io/doc/types/~/Reader | Reader} from an iterable of {@linkcode Uint8Array}s. - * - * @param iterable An iterable or async iterable of `Uint8Array`s to convert into a `Reader`. - * @returns A `Reader` that reads from the iterable. - * - * @example Write `Deno.build` information to the blackhole 3 times every second - * ```ts no-eval no-assert - * import { readerFromIterable } from "@std/streams/reader-from-iterable"; - * import { copy } from "@std/io/copy"; - * import { delay } from "@std/async/delay"; - * import { devNull } from "node:os"; - * - * const reader = readerFromIterable((async function* () { - * for (let i = 0; i < 3; i++) { - * await delay(1000); - * const message = `data: ${JSON.stringify(Deno.build)}\n\n`; - * yield new TextEncoder().encode(message); - * } - * })()); - * - * using blackhole = await Deno.open(devNull, { write: true }); - * await copy(reader, blackhole); - * ``` - * - * @deprecated This will be removed in 1.0.0. Use {@linkcode ReadableStream.from} instead. - */ -export function readerFromIterable( - iterable: Iterable | AsyncIterable, -): Reader { - const iterator: Iterator | AsyncIterator = - (iterable as AsyncIterable)[Symbol.asyncIterator]?.() ?? - (iterable as Iterable)[Symbol.iterator]?.(); - const buffer = new Buffer(); - return { - async read(p: Uint8Array): Promise { - if (buffer.length === 0) { - const result = await iterator.next(); - if (result.done) { - return null; - } else { - if (result.value.byteLength <= p.byteLength) { - p.set(result.value); - return result.value.byteLength; - } - p.set(result.value.subarray(0, p.byteLength)); - await writeAll(buffer, result.value.subarray(p.byteLength)); - return p.byteLength; - } - } else { - const n = await buffer.read(p); - if (n === null) { - return this.read(p); - } - return n; - } - }, - }; -} diff --git a/streams/reader_from_iterable_test.ts b/streams/reader_from_iterable_test.ts deleted file mode 100644 index 98de336c7ae6..000000000000 --- a/streams/reader_from_iterable_test.ts +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. - -import { assertEquals } from "@std/assert"; -import { readerFromIterable } from "./reader_from_iterable.ts"; - -Deno.test("readerFromIterable()", async function () { - const reader = readerFromIterable((function* () { - const encoder = new TextEncoder(); - for (const string of ["hello", "deno", "foo"]) { - yield encoder.encode(string); - } - })()); - - const readStrings = []; - const decoder = new TextDecoder(); - const p = new Uint8Array(4); - while (true) { - const n = await reader.read(p); - if (n === null) { - break; - } - readStrings.push(decoder.decode(p.slice(0, n))); - } - assertEquals(readStrings, ["hell", "o", "deno", "foo"]); -}); diff --git a/streams/reader_from_stream_reader.ts b/streams/reader_from_stream_reader.ts deleted file mode 100644 index fb646e27f5d6..000000000000 --- a/streams/reader_from_stream_reader.ts +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. -// This module is browser compatible. - -import { readerFromStreamReader as _readerFromStreamReader } from "@std/io/reader-from-stream-reader"; -import type { Reader } from "@std/io/types"; - -/** - * Create a {@linkcode https://jsr.io/@std/io/doc/types/~/Reader | Reader} from a {@linkcode ReadableStreamDefaultReader}. - * - * @param streamReader A `ReadableStreamDefaultReader` to convert into a `Reader`. - * @returns A `Reader` that reads from the `streamReader`. - * - * @example Copy the response body of a fetch request to the blackhole - * ```ts no-eval no-assert - * import { copy } from "@std/io/copy"; - * import { readerFromStreamReader } from "@std/streams/reader-from-stream-reader"; - * import { devNull } from "node:os"; - * - * const res = await fetch("https://deno.land"); - * using blackhole = await Deno.open(devNull, { write: true }); - * - * const reader = readerFromStreamReader(res.body!.getReader()); - * await copy(reader, blackhole); - * ``` - * - * @deprecated This will be removed in 1.0.0. Import from - * {@link https://jsr.io/@std/io | @std/io} instead. - */ -export function readerFromStreamReader( - streamReader: ReadableStreamDefaultReader, -): Reader { - return _readerFromStreamReader(streamReader); -} diff --git a/streams/reader_from_stream_reader_test.ts b/streams/reader_from_stream_reader_test.ts deleted file mode 100644 index 4d5ae6b7cd22..000000000000 --- a/streams/reader_from_stream_reader_test.ts +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. - -import { assert, assertEquals } from "@std/assert"; -import { copy } from "@std/io/copy"; -import { readerFromStreamReader } from "./reader_from_stream_reader.ts"; -import { Buffer } from "@std/io/buffer"; - -function repeat(c: string, bytes: number): Uint8Array { - assertEquals(c.length, 1); - const ui8 = new Uint8Array(bytes); - ui8.fill(c.charCodeAt(0)); - return ui8; -} - -Deno.test("readerFromStreamReader()", async function () { - const chunks: string[] = ["hello", "deno", "land"]; - const expected = chunks.slice(); - const readChunks: Uint8Array[] = []; - const readableStream = ReadableStream.from(chunks) - .pipeThrough(new TextEncoderStream()); - - const decoder = new TextDecoder(); - const reader = readerFromStreamReader(readableStream.getReader()); - - let i = 0; - - while (true) { - const b = new Uint8Array(1024); - const n = await reader.read(b); - - if (n === null) break; - - readChunks.push(b.subarray(0, n)); - assert(i < expected.length); - - i++; - } - - assertEquals( - expected, - readChunks.map((chunk) => decoder.decode(chunk)), - ); -}); - -Deno.test("readerFromStreamReader() handles big chunks", async function () { - const bufSize = 1024; - const chunkSize = 3 * bufSize; - const writer = new Buffer(); - - // A readable stream can enqueue chunks bigger than Copy bufSize - // Reader returned by toReader should enqueue exceeding bytes - const chunks: string[] = [ - "a".repeat(chunkSize), - "b".repeat(chunkSize), - "c".repeat(chunkSize), - ]; - const expected = chunks.slice(); - const readableStream = ReadableStream.from(chunks) - .pipeThrough(new TextEncoderStream()); - - const reader = readerFromStreamReader(readableStream.getReader()); - const n = await copy(reader, writer, { bufSize }); - - const expectedWritten = chunkSize * expected.length; - assertEquals(n, chunkSize * expected.length); - assertEquals(writer.length, expectedWritten); -}); - -Deno.test("readerFromStreamReader() handles irregular chunks", async function () { - const bufSize = 1024; - const chunkSize = 3 * bufSize; - const writer = new Buffer(); - - // A readable stream can enqueue chunks bigger than Copy bufSize - // Reader returned by toReader should enqueue exceeding bytes - const chunks: Uint8Array[] = [ - repeat("a", chunkSize), - repeat("b", chunkSize + 253), - repeat("c", chunkSize + 8), - ]; - const expected = new Uint8Array( - chunks - .slice() - .map((chunk) => [...chunk]) - .flat(), - ); - const readableStream = ReadableStream.from(chunks); - - const reader = readerFromStreamReader(readableStream.getReader()); - - const n = await copy(reader, writer, { bufSize }); - assertEquals(n, expected.length); - assertEquals(expected, writer.bytes()); -}); diff --git a/streams/writable_stream_from_writer.ts b/streams/writable_stream_from_writer.ts deleted file mode 100644 index 5f3bb6246478..000000000000 --- a/streams/writable_stream_from_writer.ts +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. -// This module is browser compatible. - -import type { Writer } from "@std/io/types"; -import { toWritableStream } from "@std/io/to-writable-stream"; - -/** - * Options for {@linkcode writableStreamFromWriter}. - * - * @deprecated This will be removed in 1.0.0. Use {@linkcode https://jsr.io/@std/io/doc/~/toWritableStream | toWritableStream} instead. - */ -export interface WritableStreamFromWriterOptions { - /** - * If the `writer` is also a `Closer`, automatically close the `writer` - * when the stream is closed, aborted, or a write error occurs. - * - * @default {true} - */ - autoClose?: boolean; -} - -/** - * Create a {@linkcode WritableStream} from a {@linkcode https://jsr.io/@std/io/doc/types/~/Writer | Writer}. - * - * @param writer A `Writer` to convert into a `WritableStream`. - * @param options Options for the `writableStreamFromWriter` function. - * @returns A `WritableStream` of `Uint8Array`s. - * - * @example Convert `Deno.stdout` into a writable stream - * ```ts no-eval no-assert - * // Note that you can directly get the writer from `Deno.stdout` by - * // `Deno.stdout.writable`. This example is just for demonstration purposes; - * // definitely not a recommended way. - * - * import { writableStreamFromWriter } from "@std/streams/writable-stream-from-writer"; - * - * const stdoutStream = writableStreamFromWriter(Deno.stdout); - * ``` - * - * @deprecated This will be removed in 1.0.0. Use {@linkcode https://jsr.io/@std/io/doc/~/toWritableStream | toWritableStream} instead. - */ -export function writableStreamFromWriter( - writer: Writer, - options: WritableStreamFromWriterOptions = {}, -): WritableStream { - return toWritableStream(writer, options); -} diff --git a/streams/writable_stream_from_writer_test.ts b/streams/writable_stream_from_writer_test.ts deleted file mode 100644 index ac806ee7af6d..000000000000 --- a/streams/writable_stream_from_writer_test.ts +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. - -import { assertEquals } from "@std/assert"; -import { writableStreamFromWriter } from "./writable_stream_from_writer.ts"; -import type { Closer, Writer } from "@std/io/types"; - -class MockWriterCloser implements Writer, Closer { - chunks: Uint8Array[] = []; - closeCall = 0; - - write(p: Uint8Array): Promise { - if (this.closeCall) { - throw new Error("already closed"); - } - if (p.length) { - this.chunks.push(p); - } - return Promise.resolve(p.length); - } - - close() { - this.closeCall++; - } -} - -Deno.test("writableStreamFromWriter()", async function () { - const written: string[] = []; - const chunks: string[] = ["hello", "deno", "land"]; - const decoder = new TextDecoder(); - - // deno-lint-ignore require-await - async function write(p: Uint8Array): Promise { - written.push(decoder.decode(p)); - return p.length; - } - - const writableStream = writableStreamFromWriter({ write }); - - const encoder = new TextEncoder(); - const streamWriter = writableStream.getWriter(); - for (const chunk of chunks) { - await streamWriter.write(encoder.encode(chunk)); - } - - assertEquals(written, chunks); -}); - -Deno.test("writableStreamFromWriter() calls close on close", async function () { - const written: string[] = []; - const chunks: string[] = ["hello", "deno", "land"]; - const decoder = new TextDecoder(); - - const writer = new MockWriterCloser(); - const writableStream = writableStreamFromWriter(writer); - - const encoder = new TextEncoder(); - const streamWriter = writableStream.getWriter(); - for (const chunk of chunks) { - await streamWriter.write(encoder.encode(chunk)); - } - await streamWriter.close(); - - for (const chunk of writer.chunks) { - written.push(decoder.decode(chunk)); - } - - assertEquals(written, chunks); - assertEquals(writer.closeCall, 1); -}); - -Deno.test("writableStreamFromWriter() calls close on abort", async function () { - const written: string[] = []; - const chunks: string[] = ["hello", "deno", "land"]; - const decoder = new TextDecoder(); - - const writer = new MockWriterCloser(); - const writableStream = writableStreamFromWriter(writer); - - const encoder = new TextEncoder(); - const streamWriter = writableStream.getWriter(); - for (const chunk of chunks) { - await streamWriter.write(encoder.encode(chunk)); - } - await streamWriter.abort(); - - for (const chunk of writer.chunks) { - written.push(decoder.decode(chunk)); - } - - assertEquals(written, chunks); - assertEquals(writer.closeCall, 1); -}); - -Deno.test("writableStreamFromWriter() doesn't call close with autoClose false", async function () { - const written: string[] = []; - const chunks: string[] = ["hello", "deno", "land"]; - const decoder = new TextDecoder(); - - const writer = new MockWriterCloser(); - const writableStream = writableStreamFromWriter(writer, { autoClose: false }); - - const encoder = new TextEncoder(); - const streamWriter = writableStream.getWriter(); - for (const chunk of chunks) { - await streamWriter.write(encoder.encode(chunk)); - } - await streamWriter.close(); - - for (const chunk of writer.chunks) { - written.push(decoder.decode(chunk)); - } - - assertEquals(written, chunks); - assertEquals(writer.closeCall, 0); -}); diff --git a/streams/writer_from_stream_writer.ts b/streams/writer_from_stream_writer.ts deleted file mode 100644 index a12b7f5b97e7..000000000000 --- a/streams/writer_from_stream_writer.ts +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. -// This module is browser compatible. - -import type { Writer } from "@std/io/types"; - -export type { Writer }; - -/** - * Create a {@linkcode https://jsr.io/@std/io/doc/types/~/Writer | Writer} from a {@linkcode WritableStreamDefaultWriter}. - * - * @param streamWriter A `WritableStreamDefaultWriter` to convert into a `Writer`. - * @returns A `Writer` that writes to the `WritableStreamDefaultWriter`. - * - * @example Read from a file and write to stdout using a writable stream - * ```ts no-eval no-assert - * import { copy } from "@std/io/copy"; - * import { writerFromStreamWriter } from "@std/streams/writer-from-stream-writer"; - * - * using file = await Deno.open("./README.md", { read: true }); - * - * const writableStream = new WritableStream({ - * write(chunk): void { - * console.log(chunk); - * }, - * }); - * const writer = writerFromStreamWriter(writableStream.getWriter()); - * await copy(file, writer); - * ``` - * - * @deprecated This will be removed in 1.0.0. Use {@linkcode WritableStreamDefaultWriter} directly. - */ -export function writerFromStreamWriter( - streamWriter: WritableStreamDefaultWriter, -): Writer { - return { - async write(p: Uint8Array): Promise { - await streamWriter.ready; - await streamWriter.write(p); - return p.length; - }, - }; -} diff --git a/streams/writer_from_stream_writer_test.ts b/streams/writer_from_stream_writer_test.ts deleted file mode 100644 index bea1dba2bff4..000000000000 --- a/streams/writer_from_stream_writer_test.ts +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. - -import { assertEquals } from "@std/assert"; -import { writerFromStreamWriter } from "./writer_from_stream_writer.ts"; - -Deno.test("writerFromStreamWriter()", async function () { - const written: string[] = []; - const chunks: string[] = ["hello", "deno", "land"]; - const writableStream = new WritableStream({ - write(chunk) { - const decoder = new TextDecoder(); - written.push(decoder.decode(chunk)); - }, - }); - - const encoder = new TextEncoder(); - const writer = writerFromStreamWriter(writableStream.getWriter()); - - for (const chunk of chunks) { - const n = await writer.write(encoder.encode(chunk)); - // stream writers always write all the bytes - assertEquals(n, chunk.length); - } - - assertEquals(written, chunks); -});