use whatwg streams (#103)
* use whatwg streams * could not use optional changing in v12 * could not use fs/promise in v12
This commit is contained in:
@@ -22,10 +22,8 @@ npm install fetch-blob
|
||||
- internal Buffer.from was replaced with TextEncoder/Decoder
|
||||
- internal buffers was replaced with Uint8Arrays
|
||||
- CommonJS was replaced with ESM
|
||||
- The node stream returned by calling `blob.stream()` was replaced with a simple generator function that yields Uint8Array (Breaking change)
|
||||
(Read "Differences from other blobs" for more info.)
|
||||
|
||||
All of this changes have made it dependency free of any core node modules, so it would be possible to just import it using http-import from a CDN without any bundling
|
||||
- The node stream returned by calling `blob.stream()` was replaced with whatwg streams
|
||||
- (Read "Differences from other blobs" for more info.)
|
||||
|
||||
</details>
|
||||
|
||||
@@ -36,48 +34,12 @@ npm install fetch-blob
|
||||
- This blob version is more arbitrary, it can be constructed with blob parts that isn't a instance of itself
|
||||
it has to look and behave as a blob to be accepted as a blob part.
|
||||
- The benefit of this is that you can create other types of blobs that don't contain any internal data that has to be read in other ways, such as the `BlobDataItem` created in `from.js` that wraps a file path into a blob-like item and read lazily (nodejs plans to [implement this][fs-blobs] as well)
|
||||
- The `blob.stream()` is the most noticeable differences. It returns a AsyncGeneratorFunction that yields Uint8Arrays
|
||||
- The `blob.stream()` is the most noticeable differences. It returns a WHATWG stream now. to keep it as a node stream you would have to do:
|
||||
|
||||
The reasoning behind `Blob.prototype.stream()` is that NodeJS readable stream
|
||||
isn't spec compatible with whatwg streams and we didn't want to import the hole whatwg stream polyfill for node
|
||||
or browserify NodeJS streams for the browsers and picking any flavor over the other. So we decided to opted out
|
||||
of any stream and just implement the bear minium of what both streams have in common which is the asyncIterator
|
||||
that both yields Uint8Array. this is the most isomorphic way with the use of `for-await-of` loops.
|
||||
It would be redundant to convert anything to whatwg streams and than convert it back to
|
||||
node streams since you work inside of Node.
|
||||
It will probably stay like this until nodejs get native support for whatwg<sup>[1][https://github.com/nodejs/whatwg-stream]</sup> streams and whatwg stream add the node
|
||||
equivalent for `Readable.from(iterable)`<sup>[2](https://github.com/whatwg/streams/issues/1018)</sup>
|
||||
|
||||
But for now if you really need a Node Stream then you can do so using this transformation
|
||||
```js
|
||||
import {Readable} from 'stream'
|
||||
const stream = Readable.from(blob.stream())
|
||||
```
|
||||
But if you don't need it to be a stream then you can just use the asyncIterator part of it that is isomorphic.
|
||||
```js
|
||||
for await (const chunk of blob.stream()) {
|
||||
console.log(chunk) // uInt8Array
|
||||
}
|
||||
```
|
||||
If you need to make some feature detection to fix this different behavior
|
||||
```js
|
||||
if (Blob.prototype.stream?.constructor?.name === 'AsyncGeneratorFunction') {
|
||||
// not spec compatible, monkey patch it...
|
||||
// (Alternative you could extend the Blob and use super.stream())
|
||||
let orig = Blob.prototype.stream
|
||||
Blob.prototype.stream = function () {
|
||||
const iterator = orig.call(this)
|
||||
return new ReadableStream({
|
||||
async pull (ctrl) {
|
||||
const next = await iterator.next()
|
||||
return next.done ? ctrl.close() : ctrl.enqueue(next.value)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
```
|
||||
Possible feature whatwg version: `ReadableStream.from(iterator)`
|
||||
It's also possible to delete this method and instead use `.slice()` and `.arrayBuffer()` since it has both a public and private stream method
|
||||
</details>
|
||||
|
||||
## Usage
|
||||
@@ -100,12 +62,8 @@ const blob = new Blob(['hello, world'])
|
||||
await blob.text()
|
||||
await blob.arrayBuffer()
|
||||
for await (let chunk of blob.stream()) { ... }
|
||||
|
||||
// turn the async iterator into a node stream
|
||||
stream.Readable.from(blob.stream())
|
||||
|
||||
// turn the async iterator into a whatwg stream (feature)
|
||||
globalThis.ReadableStream.from(blob.stream())
|
||||
blob.stream().getReader().read()
|
||||
blob.stream().getReader({mode: 'byob'}).read(view)
|
||||
```
|
||||
|
||||
### Blob part backed up by filesystem
|
||||
|
||||
Reference in New Issue
Block a user