Skip to content
Permalink
Browse files

Internally use stream API if onProgress is called

  • Loading branch information...
dangdennis committed Nov 1, 2018
1 parent 5fb1e5b commit e75b4c35e5566b415608442197dfd878d46c3b17
Showing with 28 additions and 48 deletions.
  1. +17 −24 index.js
  2. +10 −6 readme.md
  3. +1 −1 test/_require.js
  4. +0 −17 test/stream.js
@@ -109,13 +109,7 @@ const timeout = (promise, ms) => Promise.race([
]);

class Ky {
constructor(input, {
timeout = 10000,
hooks,
throwHttpErrors = true,
json,
...otherOptions
}) {
constructor(input, {timeout = 10000, hooks = {beforeRequest: []}, throwHttpErrors = true, json, ...otherOptions}) {
this._retryCount = 0;

this._options = {
@@ -142,7 +136,7 @@ class Ky {
}, hooks);
this._throwHttpErrors = throwHttpErrors;

const headers = new _globalThis.Headers(this._options.headers || {});
const headers = new self.Headers(this._options.headers || {});

if (json) {
headers.set('content-type', 'application/json');
@@ -173,13 +167,12 @@ class Ky {
if (!response.ok) {
throw new HTTPError(response);
}

if (response.body && this._options.stream) {
let progressCallback = null;
if (this._options.streamProgressCallback) {
progressCallback = this._options.streamProgressCallback;
// If an onProgress is passed, use stream API internally
if (this._options.onProgress) {
if (typeof this._options.onProgress !== 'function') {
throw new TypeError('The `onProgress` argument must be a function');
}
return this._stream(response.clone(), progressCallback)[type]();
return this._stream(response.clone(), this._options.onProgress)[type]();
}

return response.clone()[type]();
@@ -252,12 +245,12 @@ class Ky {
await hook(this._options);
}

return timeout(_globalThis.fetch(this._input, this._options), this._timeout);
return timeout(self.fetch(this._input, this._options), this._timeout);
}

_stream(response, progressCallback) {
const contentByteLength = response.headers.get('content-length') || 1;
let contentBytesLoaded = 0;
_stream(response, onProgress) {
const bytesTotal = response.headers.get('content-length') || 1;
let bytesLoaded = 0;

return new Response(
new ReadableStream({
@@ -269,16 +262,16 @@ class Ky {
const {done, value} = await reader.read();
try {
if (done) {
if (progressCallback) {
progressCallback(100, contentByteLength);
if (onProgress) {
onProgress(100, bytesTotal, bytesTotal);
}
controller.close();
return;
}
if (progressCallback) {
contentBytesLoaded += value.byteLength;
const percentCompleted = contentByteLength === 0 ? null : Math.floor(contentBytesLoaded / contentByteLength * 100);
progressCallback(percentCompleted, contentBytesLoaded);
if (onProgress) {
bytesLoaded += value.byteLength;
const percent = bytesTotal === 0 ? 0 : Math.floor(bytesLoaded / bytesTotal * 100);
onProgress(percent, bytesLoaded, bytesTotal);
}
controller.enqueue(value);
read();
@@ -60,7 +60,7 @@ With plain `fetch`, it would be:
(async () => {
class HTTPError extends Error {}
const response = await fetch('https://example.com', {
const response = await fetch('https://some-api.com', {
method: 'POST',
body: JSON.stringify({foo: true}),
headers: {
@@ -118,9 +118,15 @@ When specified, `prefixUrl` will be prepended to `input`. The prefix can be any

Useful when used with [`ky.extend()`](#kyextenddefaultoptions) to create niche-specific Ky-instances.

```js
import ky from 'ky';
#### prefixUrl

Type: `string` [`URL`](https://developer.mozilla.org/en-US/docs/Web/API/URL)

When specified, `prefixUrl` will be prepended to `input`. The prefix can be any valid URL, either relative or absolute. A trailing slash `/` is optional, one will be added automatically, if needed, when joining `prefixUrl` and `input`. The `input` argument cannot start with a `/` when using this option.

Useful when used with [`ky.extend()`](#kyextenddefaultoptions) to create niche-specific Ky-instances.

```js
// On https://example.com
(async () => {
@@ -132,7 +138,7 @@ import ky from 'ky';
})();
```

##### retry
#### retry

Type: `number`<br>
Default: `2`
@@ -202,8 +208,6 @@ Setting this to `false` may be useful if you are checking for resource availabil
Create a new `ky` instance with some defaults overridden with your own.

```js
import ky from 'ky';
// On https://my-site.com
const api = ky.extend({prefixUrl: 'https://example.com/api'});
@@ -1,5 +1,5 @@
import {URL} from 'url';
import fetch, {Headers, Response} from 'node-fetch';
import fetch, {Headers} from 'node-fetch';

global.self = {
fetch,

This file was deleted.

0 comments on commit e75b4c3

Please sign in to comment.
You can’t perform that action at this time.