Web streams (ReadableStream) support, blob & arrayBuffer accessors, ES6#140
Web streams (ReadableStream) support, blob & arrayBuffer accessors, ES6#140gwicke wants to merge 13 commits intonode-fetch:masterfrom
Conversation
- Return a Node `Buffer` from the Response.blob() constructor. The `Buffer`
signature is pretty much the same as `Blob`, so for now this might be a good
compromise (until there is better `Blob` support on Node).
- Return an `ArrayBuffer` from `Response.arrayBuffer()`. This is cheap, as
Node's `Buffer` is implemented in terms of `ArrayBuffer` already.
- Clean up `Body` state a bit:
- Move _decode related vars to the closure, so that they are GC'ed as soon
as possible. This is especially interesting for the _raw response chunks.
The fetch spec prescribes the use of a ReadableStream (from the streams spec) as response & request bodies. With ReadableStream exposed in recent Chrome, client-side code is starting to take advantage of streaming content transformations. To more faithfully implement the fetch spec & support isomorphic stream processing code, this patch adds support for ReadableStream, using the whatwg reference implementation: - `Response.body` is now a ReadableStream. - The `Body` constructor dynamically converts Node streams to `ReadableStream`, but still accepts FormData. - Requests accept ReadableStream, Node stream, or FormData bodies.
Apart from being cleaner, this will let us leverage ES6 getters & setters for lazy ReadableStream construction & type conversion.
- Remove charset detection, as this differs from the spec & browser implementations. Resolves #1. - Use ES6 getters for Request.body / Response.body access. This lets us avoid constructing a ReadableStream in the large number of cases where the full body is consumed with `.text()`, `.json()` or `.blob()`. - Add a fast path avoiding stream construction for request bodies in index.js.
- Convert to basic ES6. - Convert `fetch` into a regular function. This is in line with the spec & browser implementations, where calling `fetch` as a constructor is explicitly not supported. (Example: Chrome returns "TypeError: fetch is not a constructor".) Additionally, constructors masquerading as functions is no longer supported in ES6.
|
Thx for the PR, but as great as it might be, I won't be merging it due to multiple breaking change. I will however keep it open for future reference. |
Upstream [is not keen on incorporating breaking changes](node-fetch#140) like the removal of charset detection & the introduction of ReadableStream. In the meantime, we need a spec conforming `fetch` compatible polyfill that can be used in ServiceWorker code. So, for now, the path of least resistance seems to be to rename the project to node-fetch-polyfill & bump the version to 2.0.0 to signal breaking API changes.
|
I think this would be a good starting point of v 2.0 or at least some of it Could maybe wish for a v2.0 brach that we can push to instead and also that this PR was broken down to a few smaller pull requests instead of one big. or perhaps just keep this as a reference like you said |
| class Body { | ||
| constructor(body, opts) { | ||
| opts = opts || {}; | ||
| opts = opts || {}; |
TimothyGu
left a comment
There was a problem hiding this comment.
I just did some very preliminary review on Body.
Was there a reason why you changed the code formatting? It makes finding the difference in code a lot harder, when there are unrelated changes mixed in.
|
|
||
| set body(val) { | ||
| this._rawBody = val; | ||
| } |
There was a problem hiding this comment.
This goes against the WHATWG spec, which specifies that
readonly attribute ReadableStream? body;The readonly annotation means that the setter should be left blank.
| /** | ||
| * Accumulate the body & return a Buffer. | ||
| * | ||
| * @return Promise |
There was a problem hiding this comment.
Make clear what the type of the encapsulated data in the Promise is as well.
| constructor(body, opts) { | ||
| opts = opts || {}; | ||
| this._rawBody = body; | ||
| this.bodyUsed = false; |
There was a problem hiding this comment.
Since the Fetch spec declares bodyUsed as readonly you might want to do the getter/setter dance similar to rawBody and body.
| class Body { | ||
| constructor(body, opts) { | ||
| opts = opts || {}; | ||
| this._rawBody = body; |
There was a problem hiding this comment.
You could make rawBody a Symbol
Incorporates some changes from #140, by Gabriel Wicke <gwicke@wikimedia.org>.
Incorporates some changes from #140, by Gabriel Wicke <gwicke@wikimedia.org>.
Elements of this commit come from #140 by Gabriel Wicke <gwicke@wikimedia.org>.
Incorporates some changes from #140, by Gabriel Wicke <gwicke@wikimedia.org>.
|
This PR is pretty old btw. Current work is in the master branch of https://github.com/gwicke/node-fetch-polyfill. |
Incorporates some changes from #140, by Gabriel Wicke <gwicke@wikimedia.org>.
Incorporates some changes from #140, by Gabriel Wicke <gwicke@wikimedia.org>.
bodyas WhatWGReadableStream, in line with the spec & browser implementations.ReadableStreamonly when needed.