Closed sigmaxipi closed 2 months ago
However, I can't pipe from an arbitrary iterable to a Deno stream:
const stringStream = ReadableStream.from([1,2,3]); await stringStream.pipeTo(Deno.stdout.writable);
fails with
error: Uncaught (in promise) TypeError: expected typed ArrayBufferView at Object.write (ext:deno_web/06_streams.js:1146:20) at Module.invokeCallbackFunction (ext:deno_webidl/00_webidl.js:981:16) at WritableStreamDefaultController.writeAlgorithm (ext:deno_web/06_streams.js:3914:14) at writableStreamDefaultControllerProcessWrite (ext:deno_web/06_streams.js:4484:55) at writableStreamDefaultControllerAdvanceQueueIfNeeded (ext:deno_web/06_streams.js:4387:5) at writableStreamDefaultControllerWrite (ext:deno_web/06_streams.js:4531:3) at writableStreamDefaultWriterWrite (ext:deno_web/06_streams.js:4678:3) at Object.chunkSteps (ext:deno_web/06_streams.js:2742:17) at readableStreamFulfillReadRequest (ext:deno_web/06_streams.js:2584:17) at readableStreamDefaultControllerEnqueue (ext:deno_web/06_streams.js:1755:5)
This code looks to be working as expected. Deno.stout.writable
expects the chunks to be of type Uint8Array
, but you're providing it chunks of type number
.
It seems unexpected since I thought the purpose of the stream API was to allow combining of arbitrary streams. Should there be an implicit conversion from the iterable emitted from ReadableStream.from
to the Deno.stdout.writable
WritableStream<Uint8Array>
stream? Or should this conversion be done via an explicit TransformStream
before the .writable
?
Also, it's possible that I'm misunderstanding the Stream API, but I didn't find anything about the nature of the data types involved other than it needs to be an iterable.
Looking at the Stream API docs and Deno source code some more, it appears that I misinterpreted the API. What I should have done was something like
await ReadableStream.from([new Uint8Array(new TextEncoder().encode("TEXT").buffer)]).pipeTo(Deno.stdout.writable);
It seems unexpected since I thought the purpose of the stream API was to allow combining of arbitrary streams.
The purpose of streams is to allow working with large amounts of data in a linear fashion while maintaining a small memory footprint. If you had a large CSV file for example, instead of loading it all into memory, assuming JavaScript would allow an object that big, you could consume it row by row as if the information was on a conveyor belt.
All streams expect information to be in a certain form. Just like a function with signature (a: number, b: number) => number
, it would make no sense to pass it two arrays.
Looking at the Stream API docs and Deno source code some more, it appears that I misinterpreted the API. What I should have done was something like
await ReadableStream.from([new Uint8Array(new TextEncoder().encode("TEXT").buffer)]).pipeTo(Deno.stdout.writable);
new TextEncoder().encode()
returns a Uint8Array
So you could have just done
await ReadableStream.from([new TextEncoder().encode('TEXT')])
.pipeTo(Deno.stdout.writable, { preventClose: true })
or alternatively you could pipe it through TextEncoderStream
await ReadableStream.from(['TEXT'])
.pipeThroug(new TextEncoderStream())
.pipeTo(Deno.stdout.writable, { preventClose: true })
Version: Deno 1.45.5 on Linux and OSX
The basic use case of an echo from stdin -> stdout works:
Similarly, echoing to
console.log
works (though it outputs an unwanted encoding as expected)I can also
pipeTo
from an arbitrary iterable as expected:However, I can't pipe from an arbitrary iterable to a Deno stream:
fails with
The only thing I've been able to use
.pipeTo(Deno.stdout.writable)
with is Deno streams like a file orDeno.stdin
. This appears to go against the spec forReadableStream.from
which takes in an arbitrary iterable.