Skip to content

Commit 477d91b

Browse files
author
Sebastian Kippe
authored
Merge pull request #1140 from DougReeder/wireclient-fetch
WireClient uses fetch() if available, instead of XHR
2 parents bb881b0 + ea8d674 commit 477d91b

File tree

4 files changed

+684
-314
lines changed

4 files changed

+684
-314
lines changed

src/util.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,10 @@ var util = {
3535
}
3636
},
3737

38-
globalContext: (typeof(window) !== 'undefined' ? window : global),
38+
globalContext: (typeof(window) !== 'undefined' ? window : (typeof self === 'object' ? self : global)),
3939

4040
getGlobalContext () {
41-
return (typeof(window) !== 'undefined' ? window : global);
41+
return (typeof(window) !== 'undefined' ? window : (typeof self === 'object' ? self : global));
4242
},
4343

4444
extend (target) {

src/wireclient.js

Lines changed: 75 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ const Authorize = require('./authorize');
77
const config = require('./config');
88

99
/**
10-
* This file exposes a get/put/delete interface on top of XMLHttpRequest.
10+
* This file exposes a get/put/delete interface on top of fetch() or XMLHttpRequest.
1111
* It requires to be configured with parameters about the remotestorage server to
1212
* connect to.
1313
* Each instance of WireClient is always associated with a single remotestorage
@@ -486,8 +486,80 @@ WireClient.prototype = {
486486
WireClient.isArrayBufferView = isArrayBufferView;
487487

488488
// Shared request function used by WireClient, GoogleDrive and Dropbox.
489-
// TODO: Should we use fetch ?
490489
WireClient.request = function (method, url, options) {
490+
if (typeof fetch === 'function') {
491+
return WireClient._fetchRequest(method, url, options);
492+
} else if (typeof XMLHttpRequest === 'function') {
493+
return WireClient._xhrRequest(method, url, options);
494+
} else {
495+
log('[WireClient] add a polyfill for fetch or XMLHttpRequest');
496+
return Promise.reject('[WireClient] add a polyfill for fetch or XMLHttpRequest');
497+
}
498+
};
499+
500+
/** options includes body, headers and responseType */
501+
WireClient._fetchRequest = function (method, url, options) {
502+
var syntheticXhr;
503+
var responseHeaders = {};
504+
var abortController;
505+
if (typeof AbortController === 'function') {
506+
abortController = new AbortController();
507+
}
508+
var networkPromise = fetch(url, {
509+
method: method,
510+
headers: options.headers,
511+
body: options.body,
512+
signal: abortController ? abortController.signal : undefined
513+
}).then(function (response) {
514+
log('[WireClient fetch]', response);
515+
516+
response.headers.forEach(function (value, headerName) {
517+
responseHeaders[headerName.toUpperCase()] = value;
518+
});
519+
520+
syntheticXhr = {
521+
readyState: 4,
522+
status: response.status,
523+
statusText: response.statusText,
524+
response: undefined,
525+
getResponseHeader: function (headerName) {
526+
return responseHeaders[headerName.toUpperCase()] || null;
527+
},
528+
// responseText: 'foo',
529+
responseType: options.responseType,
530+
responseURL: url,
531+
};
532+
switch (options.responseType) {
533+
case 'arraybuffer':
534+
return response.arrayBuffer();
535+
case 'blob':
536+
return response.blob();
537+
case 'json':
538+
return response.json();
539+
case '':
540+
case 'text':
541+
return response.text();
542+
default: // document
543+
throw new Error("responseType 'document' is not currently supported using fetch");
544+
}
545+
}).then(function (processedBody) {
546+
syntheticXhr.response = processedBody;
547+
return syntheticXhr;
548+
});
549+
550+
var timeoutPromise = new Promise(function (resolve, reject) {
551+
setTimeout(function () {
552+
reject('timeout');
553+
if (abortController) {
554+
abortController.abort();
555+
}
556+
}, config.requestTimeout);
557+
});
558+
559+
return Promise.race([networkPromise, timeoutPromise]);
560+
};
561+
562+
WireClient._xhrRequest = function (method, url, options) {
491563
return new Promise ((resolve, reject) => {
492564

493565
log('[WireClient]', method, url);
@@ -550,7 +622,7 @@ WireClient._rs_init = function (remoteStorage) {
550622
};
551623

552624
WireClient._rs_supported = function () {
553-
return !! XMLHttpRequest;
625+
return typeof fetch === 'function' || typeof XMLHttpRequest === 'function';
554626
};
555627

556628
WireClient._rs_cleanup = function () {

0 commit comments

Comments
 (0)