UNPKG

10.4 kBMarkdownView Raw
1# get-stream
2
3> Get a stream as a string, Buffer, ArrayBuffer or array
4
5## Features
6
7- Works in any JavaScript environment ([Node.js](#nodejs-streams), [browsers](#browser-support), etc.).
8- Supports [text streams](#getstreamstream-options), [binary streams](#getstreamasbufferstream-options) and [object streams](#getstreamasarraystream-options).
9- Supports [async iterables](#async-iterables).
10- Can set a [maximum stream size](#maxbuffer).
11- Returns [partially read data](#errors) when the stream errors.
12- [Fast](#benchmarks).
13
14## Install
15
16```sh
17npm install get-stream
18```
19
20## Usage
21
22### Node.js streams
23
24```js
25import fs from 'node:fs';
26import getStream from 'get-stream';
27
28const stream = fs.createReadStream('unicorn.txt');
29
30console.log(await getStream(stream));
31/*
32 ,,))))))));,
33 __)))))))))))))),
34\|/ -\(((((''''((((((((.
35-*-==//////(('' . `)))))),
36/|\ ))| o ;-. '((((( ,(,
37 ( `| / ) ;))))' ,_))^;(~
38 | | | ,))((((_ _____------~~~-. %,;(;(>';'~
39 o_); ; )))(((` ~---~ `:: \ %%~~)(v;(`('~
40 ; ''''```` `: `:::|\,__,%% );`'; ~
41 | _ ) / `:|`----' `-'
42 ______/\/~ | / /
43 /~;;.____/;;' / ___--,-( `;;;/
44 / // _;______;'------~~~~~ /;;/\ /
45 // | | / ; \;;,\
46 (<_ | ; /',/-----' _>
47 \_| ||_ //~;~~~~~~~~~
48 `\_| (,~~
49 \~\
50 ~~
51*/
52```
53
54### Web streams
55
56```js
57import getStream from 'get-stream';
58
59const {body: readableStream} = await fetch('https://example.com');
60console.log(await getStream(readableStream));
61```
62
63This works in any browser, even [the ones](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream#browser_compatibility) not supporting `ReadableStream.values()` yet.
64
65### Async iterables
66
67```js
68import {opendir} from 'node:fs/promises';
69import {getStreamAsArray} from 'get-stream';
70
71const asyncIterable = await opendir(directory);
72console.log(await getStreamAsArray(asyncIterable));
73```
74
75## API
76
77The following methods read the stream's contents and return it as a promise.
78
79### getStream(stream, options?)
80
81`stream`: [`stream.Readable`](https://nodejs.org/api/stream.html#class-streamreadable), [`ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream), or [`AsyncIterable<string | Buffer | ArrayBuffer | DataView | TypedArray>`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#the_async_iterator_and_async_iterable_protocols)\
82`options`: [`Options`](#options)
83
84Get the given `stream` as a string.
85
86### getStreamAsBuffer(stream, options?)
87
88Get the given `stream` as a Node.js [`Buffer`](https://nodejs.org/api/buffer.html#class-buffer).
89
90```js
91import {getStreamAsBuffer} from 'get-stream';
92
93const stream = fs.createReadStream('unicorn.png');
94console.log(await getStreamAsBuffer(stream));
95```
96
97### getStreamAsArrayBuffer(stream, options?)
98
99Get the given `stream` as an [`ArrayBuffer`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer).
100
101```js
102import {getStreamAsArrayBuffer} from 'get-stream';
103
104const {body: readableStream} = await fetch('https://example.com');
105console.log(await getStreamAsArrayBuffer(readableStream));
106```
107
108### getStreamAsArray(stream, options?)
109
110Get the given `stream` as an array. Unlike [other methods](#api), this supports [streams of objects](https://nodejs.org/api/stream.html#object-mode).
111
112```js
113import {getStreamAsArray} from 'get-stream';
114
115const {body: readableStream} = await fetch('https://example.com');
116console.log(await getStreamAsArray(readableStream));
117```
118
119#### options
120
121Type: `object`
122
123##### maxBuffer
124
125Type: `number`\
126Default: `Infinity`
127
128Maximum length of the stream. If exceeded, the promise will be rejected with a `MaxBufferError`.
129
130Depending on the [method](#api), the length is measured with [`string.length`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/length), [`buffer.length`](https://nodejs.org/api/buffer.html#buflength), [`arrayBuffer.byteLength`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer/byteLength) or [`array.length`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/length).
131
132## Errors
133
134If the stream errors, the returned promise will be rejected with the `error`. Any contents already read from the stream will be set to `error.bufferedData`, which is a `string`, a `Buffer`, an `ArrayBuffer` or an array depending on the [method used](#api).
135
136```js
137import getStream from 'get-stream';
138
139try {
140 await getStream(streamThatErrorsAtTheEnd('unicorn'));
141} catch (error) {
142 console.log(error.bufferedData);
143 //=> 'unicorn'
144}
145```
146
147## Browser support
148
149For this module to work in browsers, a bundler must be used that either:
150- Supports the [`exports.browser`](https://nodejs.org/api/packages.html#community-conditions-definitions) field in `package.json`
151- Strips or ignores `node:*` imports
152
153Most bundlers (such as [Webpack](https://webpack.js.org/guides/package-exports/#target-environment)) support either of these.
154
155Additionally, browsers support [web streams](#web-streams) and [async iterables](#async-iterables), but not [Node.js streams](#nodejs-streams).
156
157## Tips
158
159### Alternatives
160
161If you do not need the [`maxBuffer`](#maxbuffer) option, [`error.bufferedData`](#errors), nor browser support, you can use the following methods instead of this package.
162
163#### [`streamConsumers.text()`](https://nodejs.org/api/webstreams.html#streamconsumerstextstream)
164
165```js
166import fs from 'node:fs';
167import {text} from 'node:stream/consumers';
168
169const stream = fs.createReadStream('unicorn.txt', {encoding: 'utf8'});
170console.log(await text(stream))
171```
172
173#### [`streamConsumers.buffer()`](https://nodejs.org/api/webstreams.html#streamconsumersbufferstream)
174
175```js
176import {buffer} from 'node:stream/consumers';
177
178console.log(await buffer(stream))
179```
180
181#### [`streamConsumers.arrayBuffer()`](https://nodejs.org/api/webstreams.html#streamconsumersarraybufferstream)
182
183```js
184import {arrayBuffer} from 'node:stream/consumers';
185
186console.log(await arrayBuffer(stream))
187```
188
189#### [`readable.toArray()`](https://nodejs.org/api/stream.html#readabletoarrayoptions)
190
191```js
192console.log(await stream.toArray())
193```
194
195#### [`Array.fromAsync()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fromAsync)
196
197If your [environment supports it](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fromAsync#browser_compatibility):
198
199```js
200console.log(await Array.fromAsync(stream))
201```
202
203### Non-UTF-8 encoding
204
205When all of the following conditions apply:
206 - [`getStream()`](#getstreamstream-options) is used (as opposed to [`getStreamAsBuffer()`](#getstreamasbufferstream-options) or [`getStreamAsArrayBuffer()`](#getstreamasarraybufferstream-options))
207 - The stream is binary (not text)
208 - The stream's encoding is not UTF-8 (for example, it is UTF-16, hexadecimal, or Base64)
209
210Then the stream must be decoded using a transform stream like [`TextDecoderStream`](https://developer.mozilla.org/en-US/docs/Web/API/TextDecoderStream) or [`b64`](https://github.com/hapijs/b64).
211
212```js
213import getStream from 'get-stream';
214
215const textDecoderStream = new TextDecoderStream('utf-16le');
216const {body: readableStream} = await fetch('https://example.com');
217console.log(await getStream(readableStream.pipeThrough(textDecoderStream)));
218```
219
220### Blobs
221
222[`getStreamAsArrayBuffer()`](#getstreamasarraybufferstream-options) can be used to create [Blobs](https://developer.mozilla.org/en-US/docs/Web/API/Blob).
223
224```js
225import {getStreamAsArrayBuffer} from 'get-stream';
226
227const stream = fs.createReadStream('unicorn.txt');
228console.log(new Blob([await getStreamAsArrayBuffer(stream)]));
229```
230
231### JSON streaming
232
233[`getStreamAsArray()`](#getstreamasarraystream-options) can be combined with JSON streaming utilities to parse JSON incrementally.
234
235```js
236import fs from 'node:fs';
237import {compose as composeStreams} from 'node:stream';
238import {getStreamAsArray} from 'get-stream';
239import streamJson from 'stream-json';
240import streamJsonArray from 'stream-json/streamers/StreamArray.js';
241
242const stream = fs.createReadStream('big-array-of-objects.json');
243console.log(await getStreamAsArray(
244 composeStreams(stream, streamJson.parser(), streamJsonArray.streamArray()),
245));
246```
247
248## Benchmarks
249
250### Node.js stream (100 MB, binary)
251
252- `getStream()`: 142ms
253- `text()`: 139ms
254- `getStreamAsBuffer()`: 106ms
255- `buffer()`: 83ms
256- `getStreamAsArrayBuffer()`: 105ms
257- `arrayBuffer()`: 81ms
258- `getStreamAsArray()`: 24ms
259- `stream.toArray()`: 21ms
260
261### Node.js stream (100 MB, text)
262
263- `getStream()`: 90ms
264- `text()`: 89ms
265- `getStreamAsBuffer()`: 127ms
266- `buffer()`: 192ms
267- `getStreamAsArrayBuffer()`: 129ms
268- `arrayBuffer()`: 195ms
269- `getStreamAsArray()`: 89ms
270- `stream.toArray()`: 90ms
271
272### Web ReadableStream (100 MB, binary)
273
274- `getStream()`: 223ms
275- `text()`: 221ms
276- `getStreamAsBuffer()`: 182ms
277- `buffer()`: 153ms
278- `getStreamAsArrayBuffer()`: 171ms
279- `arrayBuffer()`: 155ms
280- `getStreamAsArray()`: 83ms
281
282### Web ReadableStream (100 MB, text)
283
284- `getStream()`: 141ms
285- `text()`: 139ms
286- `getStreamAsBuffer()`: 91ms
287- `buffer()`: 80ms
288- `getStreamAsArrayBuffer()`: 89ms
289- `arrayBuffer()`: 81ms
290- `getStreamAsArray()`: 21ms
291
292[Benchmarks' source file](benchmarks/index.js).
293
294## FAQ
295
296### How is this different from [`concat-stream`](https://github.com/maxogden/concat-stream)?
297
298This module accepts a stream instead of being one and returns a promise instead of using a callback. The API is simpler and it only supports returning a string, `Buffer`, an `ArrayBuffer` or an array. It doesn't have a fragile type inference. You explicitly choose what you want. And it doesn't depend on the huge `readable-stream` package.
299
300## Related
301
302- [get-stdin](https://github.com/sindresorhus/get-stdin) - Get stdin as a string or buffer
303- [into-stream](https://github.com/sindresorhus/into-stream) - The opposite of this package