Created
February 1, 2016 11:30
-
-
Save mosson/04b6d8ead8a2fad388ff to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
import request from 'superagent'; | |
import _ from 'lodash'; | |
import URL from 'url'; | |
import Promise from 'bluebird'; | |
const global = Function("return this")(); | |
const methods = { | |
GET : 'get', | |
POST : 'post', | |
PUT : 'put', | |
PATCH : 'patch', | |
DELETE : 'del', | |
OPTIONS: 'options' | |
}; | |
function noop() { | |
} | |
class RequestWithCache { | |
constructor(method, url) { | |
this.method = method; | |
this.url = url; | |
if (!this.constructor._cache) this.constructor._cache = {}; | |
} | |
query(data) { | |
this.query = data; | |
return this; | |
} | |
send(data) { | |
this.data = data; | |
return this; | |
} | |
end(fn) { | |
return new Promise((fulfill, reject) => { | |
fn = fn || noop; | |
let cacheKey = this.resolveEndpoint('GET'); | |
let cache = this.constructor._cache[cacheKey]; | |
if (this.method === 'GET' && cache && new Date() - cache[0] < 1000 * 60) { | |
fulfill(fn(null, this.constructor._cache[cacheKey][1])); | |
} else { | |
if (this.method === 'POST') cacheKey = null; | |
if (cacheKey && this.constructor._cache[cacheKey]) { | |
delete this.constructor._cache[cacheKey]; | |
} | |
this._end(fn, cacheKey, fulfill); | |
} | |
}); | |
} | |
_end(fn, cacheKey, fulfill) { | |
fn = fn || noop; | |
let req = request[methods[this.method]](this.url); | |
if (this.query) req = req.query(this.query); | |
if (this.data) req = req.send(this.data); | |
req.end((err, res) => { | |
if (!err && cacheKey) | |
this.constructor._cache[cacheKey] = [new Date(), res]; | |
fulfill(fn(err, res)); | |
}); | |
} | |
resolveEndpoint(method) { | |
let url = URL.parse(this.url); | |
if (this.query) url.query = this.query; | |
return `${method}_${url.format()}`; | |
} | |
get endpoint() { | |
let url = URL.parse(this.url); | |
if (this.query) url.query = this.query; | |
return `${this.method}_${url.format()}`; | |
} | |
} | |
class RequestXDomain { | |
constructor(method, url) { | |
this.method = method; | |
this.url = url; | |
this.constructor._cache = {}; | |
} | |
query(data) { | |
this.query = data; | |
return this; | |
} | |
send(data) { | |
this.data = data; | |
return this; | |
} | |
end(fn) { | |
fn = fn || noop; | |
let cache = this.constructor._cache[this.endpoint]; | |
if (this.method === 'GET' && cache && new Date() - cache[0] < 1000 * 60) { | |
fn(null, this.constructor._cache[this.endpoint][1]); | |
} else { | |
this._end(fn); | |
} | |
return this; | |
} | |
_end(fn) { | |
fn = fn || noop; | |
let xdr = new XDomainRequest(); | |
xdr.open(this.method, this.url, true); | |
xdr.onerror = function () { | |
fn(xdr.responseText, null); | |
}; | |
xdr.onload = function () { | |
fn(null, {text: xdr.responseText}); | |
}; | |
xdr.withCredentials = true; // to support sending cookies with CORS | |
setTimeout(() => { | |
if (this.data) { | |
xdr.send(this.data); | |
} else { | |
xdr.send(); | |
} | |
}, 1000); | |
} | |
get endpoint() { | |
let url = URL.parse(this.url); | |
if (this.query) url.query = this.query; | |
return `${this.method}_${url.format()}`; | |
} | |
} | |
_.each(methods, (method, key) => { | |
if (_.isEmpty(method)) return; | |
RequestWithCache[method] = function (url) { | |
return new RequestWithCache(key, url); | |
}; | |
RequestXDomain[method] = function (url) { | |
return new RequestXDomain(key, url); | |
}; | |
}); | |
function Request() { | |
if (typeof process !== "undefined" && typeof require !== "undefined") { | |
return RequestWithCache; | |
} else { | |
var xhr = new XMLHttpRequest(); | |
if ("withCredentials" in xhr) { | |
return RequestWithCache; | |
} else if (typeof global.XDomainRequest !== "undefined") { | |
return RequestXDomain; | |
} | |
} | |
} | |
export default Request; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment