Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Web streams (ReadableStream) support, blob & arrayBuffer accessors, ES6 #140

Closed
wants to merge 13 commits into from

Conversation

gwicke
Copy link

@gwicke gwicke commented Aug 3, 2016

  • Expose body as WhatWG ReadableStream, in line with the spec & browser implementations.
  • Remove charset detection, in line with the spec & browser implementations.
  • Add missing blob & arrayBuffer accessors in the response.
  • Migrate to a ES6 subset compatible with Node 4.
    • Use ES6 accessors to lazily construct a ReadableStream only when needed.
  • Drop Node 0.10 & 0.12 support, and test Node 4 (LTS) & 6.

gwicke added 12 commits July 28, 2016 15:03
- 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.
@coveralls
Copy link

coveralls commented Aug 3, 2016

Coverage Status

Coverage decreased (-1.8%) to 98.208% when pulling f11ad21 on gwicke:blob_and_streams into 952aa2a on bitinn:master.

@bitinn
Copy link
Collaborator

bitinn commented Aug 3, 2016

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.

@coveralls
Copy link

coveralls commented Aug 3, 2016

Coverage Status

Coverage decreased (-1.8%) to 98.208% when pulling d459135 on gwicke:blob_and_streams into 952aa2a on bitinn:master.

gwicke added a commit to gwicke/node-fetch-polyfill that referenced this pull request Aug 3, 2016
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.
@jimmywarting
Copy link
Collaborator

jimmywarting commented Aug 27, 2016

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

@@ -15,37 +15,37 @@ const webStreams = require('node-web-streams');
*/
class Body {
constructor(body, opts) {
opts = opts || {};
opts = opts || {};
Copy link
Contributor

@dandv dandv Sep 24, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 ← click

Copy link
Collaborator

@TimothyGu TimothyGu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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;
}
Copy link
Collaborator

@TimothyGu TimothyGu Oct 4, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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;
Copy link
Collaborator

@TimothyGu TimothyGu Oct 4, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could make rawBody a Symbol

@TimothyGu TimothyGu mentioned this pull request Oct 4, 2016
8 tasks
TimothyGu added a commit that referenced this pull request Oct 9, 2016
Incorporates some changes from #140, by Gabriel Wicke
<gwicke@wikimedia.org>.
TimothyGu added a commit that referenced this pull request Oct 9, 2016
Incorporates some changes from #140, by Gabriel Wicke
<gwicke@wikimedia.org>.
TimothyGu added a commit that referenced this pull request Oct 9, 2016
Elements of this commit come from #140 by Gabriel Wicke
<gwicke@wikimedia.org>.
TimothyGu added a commit that referenced this pull request Oct 9, 2016
Incorporates some changes from #140, by Gabriel Wicke
<gwicke@wikimedia.org>.
TimothyGu added a commit that referenced this pull request Oct 9, 2016
Elements of this commit come from #140 by @gwicke.
@gwicke
Copy link
Author

gwicke commented Oct 9, 2016

This PR is pretty old btw. Current work is in the master branch of https://github.com/gwicke/node-fetch-polyfill.

@gwicke gwicke closed this Oct 9, 2016
TimothyGu added a commit that referenced this pull request Oct 9, 2016
Elements of this commit come from #140 by @gwicke.
TimothyGu added a commit that referenced this pull request Oct 10, 2016
Elements of this commit come from #140 by @gwicke.
TimothyGu added a commit that referenced this pull request Oct 10, 2016
Incorporates some changes from #140, by Gabriel Wicke
<gwicke@wikimedia.org>.
TimothyGu added a commit that referenced this pull request Oct 13, 2016
Incorporates some changes from #140, by Gabriel Wicke
<gwicke@wikimedia.org>.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants