Skip to content

Commit a8f96bf

Browse files
committed
chore: address remaining issues
- address jsdom use case as per ipfs/js-ipfs#3238 - remove onDownloadProgress since we don't need it
1 parent b19d5f7 commit a8f96bf

File tree

5 files changed

+24
-52
lines changed

5 files changed

+24
-52
lines changed

src/http.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,8 @@ const defaults = {
7070
* @prop {function(URLSearchParams): URLSearchParams } [transformSearchParams]
7171
* @prop {function(any): any} [transform] - When iterating the response body, transform each chunk with this function.
7272
* @prop {function(Response): Promise<void>} [handleError] - Handle errors
73-
* @prop {function({total:number, loaded:number, lengthComputable:boolean}):void} [onUploadProgress] - Can be passed to track upload progress
74-
* @prop {function({total:number, loaded:number, lengthComputable:boolean}):void} [onDownloadProgress] - Can be passed to track download progress
73+
* @prop {function({total:number, loaded:number, lengthComputable:boolean}):void} [onUploadProgress] - Can be passed to track upload progress.
74+
* Note that if this option in passed undelying request will be performed using `XMLHttpRequest` and response will not be streamed.
7575
*/
7676

7777
class HTTP {

src/http/fetch.browser.js

+8-7
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22
/* eslint-env browser */
33

44
const { TimeoutError, AbortError } = require('./error')
5+
const Response = require('./response')
56

67
/**
78
* @typedef {RequestInit & ExtraFetchOptions} FetchOptions
89
* @typedef {Object} ExtraFetchOptions
910
* @property {number} [timeout]
1011
* @property {URLSearchParams} [searchParams]
1112
* @property {function({total:number, loaded:number, lengthComputable:boolean}):void} [onUploadProgress]
12-
* @property {function({total:number, loaded:number, lengthComputable:boolean}):void} [onDownloadProgress]
1313
* @property {string} [overrideMimeType]
1414
* @returns {Promise<Response>}
1515
*/
@@ -42,15 +42,16 @@ const fetchWithProgress = (url, options = {}) => {
4242
options.signal.onabort = () => request.abort()
4343
}
4444

45-
if (options.onDownloadProgress) {
46-
request.onprogress = options.onDownloadProgress
47-
}
48-
4945
if (options.onUploadProgress) {
5046
request.upload.onprogress = options.onUploadProgress
5147
}
5248

53-
request.responseType = 'blob'
49+
// Note: Need to use `arraybuffer` here instead of `blob` because `Blob`
50+
// instances coming from JSDOM are not compatible with `Response` from
51+
// node-fetch (which is the setup we get when testing with jest because
52+
// it uses JSDOM which does not provide a global fetch
53+
// https://github.com/jsdom/jsdom/issues/1724)
54+
request.responseType = 'arraybuffer'
5455

5556
return new Promise((resolve, reject) => {
5657
/**
@@ -97,7 +98,7 @@ const fetchWithProgress = (url, options = {}) => {
9798
const fetchWithStreaming = fetch
9899

99100
const fetchWith = (url, options = {}) =>
100-
(options.onDownloadProgress != null || options.onUploadProgress != null)
101+
(options.onUploadProgress != null)
101102
? fetchWithProgress(url, options)
102103
: fetchWithStreaming(url, options)
103104

src/http/fetch.node.js

+2-34
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,9 @@ const { Request, Response, Headers } = nodeFetch
2929
* @param {FetchOptions} [options]
3030
* @returns {Promise<Response>}
3131
*/
32-
const fetch = async (url, options = {}) => {
33-
const { onDownloadProgress } = options
32+
const fetch = (url, options = {}) =>
33+
nodeFetch(url, withUploadProgress(options))
3434

35-
const response = await nodeFetch(url, withUploadProgress(options))
36-
37-
if (onDownloadProgress) {
38-
return withDownloadProgress(response, onDownloadProgress)
39-
} else {
40-
return response
41-
}
42-
}
4335
exports.fetch = fetch
4436
exports.Request = Request
4537
exports.Headers = Headers
@@ -94,40 +86,16 @@ const iterateBodyWithProgress = async function * (body, onUploadProgress) {
9486
} else if (Buffer.isBuffer(body)) {
9587
const total = body.byteLength
9688
const lengthComputable = true
97-
onUploadProgress({ total, loaded: 0, lengthComputable })
9889
yield body
9990
onUploadProgress({ total, loaded: total, lengthComputable })
10091
} else {
10192
const total = 0
10293
const lengthComputable = false
10394
let loaded = 0
104-
onUploadProgress({ total, loaded, lengthComputable })
10595
for await (const chunk of body) {
10696
loaded += chunk.byteLength
10797
yield chunk
10898
onUploadProgress({ total, loaded, lengthComputable })
10999
}
110100
}
111101
}
112-
113-
/**
114-
* Takes node-fetch response and tracks download progress for it.
115-
* @param {Response} response
116-
* @param {function(LoadProgress):void} onDownloadProgress
117-
* @returns {Response}
118-
*/
119-
const withDownloadProgress = (response, onDownloadProgress) => {
120-
/** @type {Readable} */
121-
// @ts-ignore - Unlike standard Response, in node-fetch response body is
122-
// node Readable stream.
123-
const { body } = response
124-
const length = parseInt(response.headers.get('Content-Length'))
125-
const lengthComputable = !isNaN(length)
126-
const total = isNaN(length) ? 0 : length
127-
let loaded = 0
128-
body.on('data', (chunk) => {
129-
loaded += chunk.length
130-
onDownloadProgress({ lengthComputable, total, loaded })
131-
})
132-
return response
133-
}

src/http/response.js

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
'use strict'
2+
3+
// JSDOM has `XMLHttpRequest` but it does not have a `fetch` or `Response` so
4+
// we workaround by pulling in node-fetch.
5+
// See: https://github.com/jsdom/jsdom/issues/1724
6+
if (typeof Response !== 'undefined') {
7+
/* eslint-env browser */
8+
module.exports = Response
9+
} else {
10+
module.exports = require('node-fetch').Response
11+
}

test/http.spec.js

+1-9
Original file line numberDiff line numberDiff line change
@@ -155,27 +155,19 @@ describe('http', function () {
155155

156156
it('progress events', async () => {
157157
let upload = 0
158-
let download = 0
159158
const body = new Uint8Array(1000000 / 2)
160159
const request = await HTTP.post(`${process.env.ECHO_SERVER}/echo`, {
161160
body,
162161
onUploadProgress: (progress) => {
163162
expect(progress).to.have.property('lengthComputable').to.be.a('boolean')
164163
expect(progress).to.have.property('total', body.byteLength)
165-
expect(progress).to.have.property('loaded').to.be.a('number')
164+
expect(progress).to.have.property('loaded').to.be.greaterThan(0)
166165
upload += 1
167-
},
168-
onDownloadProgress: (progress) => {
169-
expect(progress).to.have.property('lengthComputable').to.be.a('boolean')
170-
expect(progress).to.have.property('total').to.be.a('number')
171-
expect(progress).to.have.property('loaded').to.be.a('number')
172-
download += 1
173166
}
174167
})
175168
await all(request.iterator())
176169

177170
expect(upload).to.be.greaterThan(0)
178-
expect(download).to.be.greaterThan(0)
179171
})
180172

181173
it('makes a GET request with unprintable characters', async function () {

0 commit comments

Comments
 (0)