Comparing version 0.1.7 to 0.1.8
@@ -7,2 +7,39 @@ 'use strict'; | ||
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); | ||
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; /** | ||
* | ||
* Enforces a caching policy. Essentially the policy is a TTL cache. But in | ||
* addition you can define dependencies between different resources. | ||
* By default cache-policy tries to do work in a RESTful manner. | ||
* E.g. if we have a resource `/user/${id}`, and a PUT is done on that same | ||
* resource, cache-policy will invalidate the cached `/user/${id}`. | ||
* If you have a more complex URL scheme, you can define dependencies between | ||
* resources. E.g.: | ||
* { | ||
* "http://example.com": { | ||
* "/list-fish": { | ||
* "contains": [ "/fish", "/fish/*" ] | ||
* } | ||
* } | ||
* } | ||
* With the above policy, you set the `/list-fish` cache to be invalidated | ||
* whenever a POST is done on `/fish` or a PUT/PATH is done on `/fish/*`. | ||
*/ | ||
// $FlowFixMe | ||
// $FlowFixMe | ||
// $FlowFixMe | ||
// $FlowFixMe | ||
// $FlowFixMe | ||
// $FlowFixMe | ||
// $FlowFixMe | ||
var _Observable = require('rxjs/Observable'); | ||
@@ -26,60 +63,35 @@ | ||
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } | ||
// Arbitrary | ||
var DEFAULT_TTL = 210; | ||
// $FlowFixMe | ||
var mkCachePolicy = function mkCachePolicy(policy) { | ||
var defaultTtl = policy.ttl || DEFAULT_TTL; | ||
// $FlowFixMe | ||
var baseUrls = Object.keys(policy.resources || {}); | ||
var getBaseUrl = function getBaseUrl(url) { | ||
return baseUrls.find(function (baseUrl) { | ||
return url.indexOf(baseUrl) === 0; | ||
}); | ||
}; | ||
var getRessourcePolicy = function getRessourcePolicy(url, baseUrl) { | ||
var resources = policy.resources; | ||
// $FlowFixMe | ||
// $FlowFixMe | ||
// $FlowFixMe | ||
// $FlowFixMe | ||
const DEFAULT_TTL = 210; | ||
// $FlowFixMe | ||
/** | ||
* | ||
* Enforces a caching policy. Essentially the policy is a TTL cache. But in | ||
* addition you can define dependencies between different resources. | ||
* By default cache-policy tries to do work in a RESTful manner. | ||
* E.g. if we have a resource `/user/${id}`, and a PUT is done on that same | ||
* resource, cache-policy will invalidate the cached `/user/${id}`. | ||
* If you have a more complex URL scheme, you can define dependencies between | ||
* resources. E.g.: | ||
* { | ||
* "http://example.com": { | ||
* "/list-fish": { | ||
* "contains": [ "/fish", "/fish/*" ] | ||
* } | ||
* } | ||
* } | ||
* With the above policy, you set the `/list-fish` cache to be invalidated | ||
* whenever a POST is done on `/fish` or a PUT/PATH is done on `/fish/*`. | ||
*/ | ||
const mkCachePolicy = policy => { | ||
const defaultTtl = policy.ttl || DEFAULT_TTL; | ||
const baseUrls = Object.keys(policy.resources || {}); | ||
const getBaseUrl = url => baseUrls.find(baseUrl => url.indexOf(baseUrl) === 0); | ||
const getRessourcePolicy = (url, baseUrl) => { | ||
const { resources } = policy; | ||
if (typeof resources !== 'object') return undefined; | ||
const matchingBaseUrl = baseUrl || getBaseUrl(url); | ||
if ((typeof resources === 'undefined' ? 'undefined' : _typeof(resources)) !== 'object') return undefined; | ||
var matchingBaseUrl = baseUrl || getBaseUrl(url); | ||
if (matchingBaseUrl === undefined) return undefined; | ||
const path = url.replace(matchingBaseUrl, ''); | ||
var path = url.replace(matchingBaseUrl, ''); | ||
return resources[matchingBaseUrl][path]; | ||
}; | ||
const cacheInvalidationRules = baseUrls.reduce((rules, baseUrl) => { | ||
var cacheInvalidationRules = baseUrls.reduce(function (rules, baseUrl) { | ||
if (!policy.resources) return rules; | ||
const resourcePolicy = policy.resources[baseUrl]; | ||
var resourcePolicy = policy.resources[baseUrl]; | ||
if (!resourcePolicy) return rules; | ||
const paths = Object.keys(resourcePolicy); | ||
return rules.concat(paths.reduce((pathRules, path) => { | ||
const contains = resourcePolicy[path].contains; | ||
var paths = Object.keys(resourcePolicy); | ||
return rules.concat(paths.reduce(function (pathRules, path) { | ||
var contains = resourcePolicy[path].contains; | ||
if (!contains) return pathRules; | ||
return pathRules.concat(contains.reduce((containsRules, pattern) => { | ||
containsRules.push([new RegExp(`^${baseUrl}${pattern}$`), `${baseUrl}${path}`]); | ||
return pathRules.concat(contains.reduce(function (containsRules, pattern) { | ||
containsRules.push([new RegExp('^' + baseUrl + pattern + '$'), '' + baseUrl + path]); | ||
return containsRules; | ||
@@ -89,36 +101,72 @@ }, [])); | ||
}, []); | ||
const getContainerUrls = url => cacheInvalidationRules.filter(([pattern]) => pattern.test(url)).map(([, url]) => url); | ||
const dependantCacheUrls = url => [url, (0, _utils.dropLastSegment)(1, url), ...getContainerUrls(url)]; | ||
var getContainerUrls = function getContainerUrls(url) { | ||
return cacheInvalidationRules.filter(function (_ref) { | ||
var _ref2 = _slicedToArray(_ref, 1), | ||
pattern = _ref2[0]; | ||
return cache => ({ | ||
set: ([method, url], value) => { | ||
const resourcePolicy = getRessourcePolicy(url); | ||
const ttl = resourcePolicy && typeof resourcePolicy.ttl === 'number' ? resourcePolicy.ttl : defaultTtl; | ||
return cache.set(genKey([method, url]), { | ||
validUntil: Date.now() + ttl, | ||
value | ||
}).mapTo(value); | ||
}, | ||
return pattern.test(url); | ||
}).map(function (_ref3) { | ||
var _ref4 = _slicedToArray(_ref3, 2), | ||
url = _ref4[1]; | ||
get: ([method, url]) => { | ||
const key = genKey([method, url]); | ||
if (method === 'GET') { | ||
return cache.get(key).concatMap(item => { | ||
if (!item) return _Observable.Observable.of(undefined); | ||
return item.validUntil > Date.now() ? _Observable.Observable.of(item.value) : cache.delete(key).mapTo(undefined); | ||
}); | ||
} else if (method === 'PUT' || method === 'PATCH' || method === 'POST') { | ||
return _Observable.Observable.from(dependantCacheUrls(url).map(url => cache.delete(genKey(['GET', url])))).mergeAll().toArray().mapTo(undefined); | ||
} else { | ||
return _Observable.Observable.of(undefined); | ||
} | ||
}, | ||
has: cacheKey => cache.has(genKey(cacheKey)), | ||
delete: cacheKey => cache.delete(genKey(cacheKey)), | ||
clear: cache.clear | ||
}); | ||
return url; | ||
}); | ||
}; | ||
var dependantCacheUrls = function dependantCacheUrls(url) { | ||
return [url, (0, _utils.dropLastSegment)(1, url)].concat(_toConsumableArray(getContainerUrls(url))); | ||
}; | ||
return function (cache) { | ||
return { | ||
set: function set(_ref5, value) { | ||
var _ref6 = _slicedToArray(_ref5, 2), | ||
method = _ref6[0], | ||
url = _ref6[1]; | ||
var resourcePolicy = getRessourcePolicy(url); | ||
var ttl = resourcePolicy && typeof resourcePolicy.ttl === 'number' ? resourcePolicy.ttl : defaultTtl; | ||
return cache.set(genKey([method, url]), { | ||
validUntil: Date.now() + ttl, | ||
value: value | ||
}).mapTo(value); | ||
}, | ||
get: function get(_ref7) { | ||
var _ref8 = _slicedToArray(_ref7, 2), | ||
method = _ref8[0], | ||
url = _ref8[1]; | ||
var key = genKey([method, url]); | ||
if (method === 'GET') { | ||
return cache.get(key).concatMap(function (item) { | ||
if (!item) return _Observable.Observable.of(undefined); | ||
return item.validUntil > Date.now() ? _Observable.Observable.of(item.value) : cache.delete(key).mapTo(undefined); | ||
}); | ||
} else if (method === 'PUT' || method === 'PATCH' || method === 'POST') { | ||
return _Observable.Observable.from(dependantCacheUrls(url).map(function (url) { | ||
return cache.delete(genKey(['GET', url])); | ||
})).mergeAll().toArray().mapTo(undefined); | ||
} else { | ||
return _Observable.Observable.of(undefined); | ||
} | ||
}, | ||
has: function has(cacheKey) { | ||
return cache.has(genKey(cacheKey)); | ||
}, | ||
delete: function _delete(cacheKey) { | ||
return cache.delete(genKey(cacheKey)); | ||
}, | ||
clear: cache.clear | ||
}; | ||
}; | ||
}; | ||
const genKey = ([method, url]) => `${method}:${url}`; | ||
var genKey = function genKey(_ref9) { | ||
var _ref10 = _slicedToArray(_ref9, 2), | ||
method = _ref10[0], | ||
url = _ref10[1]; | ||
return method + ':' + url; | ||
}; | ||
exports.default = mkCachePolicy; |
10
index.js
@@ -11,3 +11,3 @@ 'use strict'; | ||
enumerable: true, | ||
get: function () { | ||
get: function get() { | ||
return _interopRequireDefault(_interface).default; | ||
@@ -21,3 +21,3 @@ } | ||
enumerable: true, | ||
get: function () { | ||
get: function get() { | ||
return _interopRequireDefault(_receiver).default; | ||
@@ -31,3 +31,3 @@ } | ||
enumerable: true, | ||
get: function () { | ||
get: function get() { | ||
return _interopRequireDefault(_memCache).default; | ||
@@ -41,3 +41,3 @@ } | ||
enumerable: true, | ||
get: function () { | ||
get: function get() { | ||
return _interopRequireDefault(_cachePolicy).default; | ||
@@ -51,3 +51,3 @@ } | ||
enumerable: true, | ||
get: function () { | ||
get: function get() { | ||
return _interopRequireDefault(_requestQueue).default; | ||
@@ -54,0 +54,0 @@ } |
@@ -34,9 +34,15 @@ 'use strict'; | ||
// $FlowFixMe | ||
const mkInterface = worker => { | ||
const postMessageToWorker = postMessageTo(worker); | ||
var mkInterface = function mkInterface(worker) { | ||
var postMessageToWorker = postMessageTo(worker); | ||
return { | ||
addRequest: (url, options) => postMessageToWorker((0, _message.msg)(_message.REQUEST, { url, options }), isCancelable(options)), | ||
clear: () => postMessageToWorker((0, _message.msg)(_message.CLEAR_CACHE)), | ||
invalidate: (url, method) => postMessageToWorker((0, _message.msg)(_message.INVALIDATE, { url, method })) | ||
addRequest: function addRequest(url, options) { | ||
return postMessageToWorker((0, _message.msg)(_message.REQUEST, { url: url, options: options }), isCancelable(options)); | ||
}, | ||
clear: function clear() { | ||
return postMessageToWorker((0, _message.msg)(_message.CLEAR_CACHE)); | ||
}, | ||
invalidate: function invalidate(url, method) { | ||
return postMessageToWorker((0, _message.msg)(_message.INVALIDATE, { url: url, method: method })); | ||
} | ||
}; | ||
@@ -47,22 +53,29 @@ }; | ||
const postMessageTo = worker => { | ||
const responseNotifications$ = _Observable.Observable.fromEvent(worker, 'message').pluck('data'); | ||
var postMessageTo = function postMessageTo(worker) { | ||
var responseNotifications$ = _Observable.Observable.fromEvent(worker, 'message').pluck('data'); | ||
return (message, cancelable) => _Observable.Observable.create(o => { | ||
let done = false; | ||
worker.postMessage(message); | ||
responseNotifications$.filter((0, _message.isResponseMsg)(message)).pluck('payload').map(({ kind, value, error }) => new _Notification.Notification(kind, value, error)).dematerialize().do(undefined, undefined, () => { | ||
done = true; | ||
}).subscribe(o); | ||
const teardown = () => { | ||
if (done) return; | ||
worker.postMessage((0, _message.unsubscribe)(message)); | ||
}; | ||
if (cancelable) { | ||
return teardown; | ||
} | ||
}); | ||
return function (message, cancelable) { | ||
return _Observable.Observable.create(function (o) { | ||
var done = false; | ||
worker.postMessage(message); | ||
responseNotifications$.filter((0, _message.isResponseMsg)(message)).pluck('payload').map(function (_ref) { | ||
var kind = _ref.kind, | ||
value = _ref.value, | ||
error = _ref.error; | ||
return new _Notification.Notification(kind, value, error); | ||
}).dematerialize().do(undefined, undefined, function () { | ||
done = true; | ||
}).subscribe(o); | ||
var teardown = function teardown() { | ||
if (done) return; | ||
worker.postMessage((0, _message.unsubscribe)(message)); | ||
}; | ||
if (cancelable) { | ||
return teardown; | ||
} | ||
}); | ||
}; | ||
}; | ||
const isCancelable = options => { | ||
var isCancelable = function isCancelable(options) { | ||
if (!options) return false; | ||
@@ -69,0 +82,0 @@ return options.cancelable === undefined ? options.method && options.method !== 'GET' : options.cancelable; |
@@ -8,25 +8,44 @@ 'use strict'; | ||
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; | ||
var _uuid = require('uuid'); | ||
const isMsg = exports.isMsg = message => typeof message === 'object'; | ||
var isMsg = exports.isMsg = function isMsg(message) { | ||
return (typeof message === 'undefined' ? 'undefined' : _typeof(message)) === 'object'; | ||
}; | ||
const isMsgType = exports.isMsgType = type => message => isMsg(message) && message.type === type; | ||
var isMsgType = exports.isMsgType = function isMsgType(type) { | ||
return function (message) { | ||
return isMsg(message) && message.type === type; | ||
}; | ||
}; | ||
const msg = exports.msg = (type, payload, id) => ({ | ||
type, | ||
payload, | ||
id: id || (0, _uuid.v4)() | ||
}); | ||
var msg = exports.msg = function msg(type, payload, id) { | ||
return { | ||
type: type, | ||
payload: payload, | ||
id: id || (0, _uuid.v4)() | ||
}; | ||
}; | ||
const unsubscribe = exports.unsubscribe = ({ id }) => ({ | ||
type: UNSUBSCRIBE, | ||
id | ||
}); | ||
var unsubscribe = exports.unsubscribe = function unsubscribe(_ref) { | ||
var id = _ref.id; | ||
return { | ||
type: UNSUBSCRIBE, | ||
id: id | ||
}; | ||
}; | ||
const isResponseMsg = exports.isResponseMsg = ({ type, id }) => message => isMsg(message) && message.id === id; | ||
var isResponseMsg = exports.isResponseMsg = function isResponseMsg(_ref2) { | ||
var type = _ref2.type, | ||
id = _ref2.id; | ||
return function (message) { | ||
return isMsg(message) && message.id === id; | ||
}; | ||
}; | ||
const REQUEST = exports.REQUEST = 'REQUEST'; | ||
const RESPONSE_NOTIFICATION = exports.RESPONSE_NOTIFICATION = 'RESPONSE_NOTIFICATION'; | ||
const UNSUBSCRIBE = exports.UNSUBSCRIBE = 'UNSUBSCRIBE'; | ||
const CLEAR_CACHE = exports.CLEAR_CACHE = 'CLEAR_CACHE'; | ||
const INVALIDATE = exports.INVALIDATE = 'INVALIDATE'; | ||
var REQUEST = exports.REQUEST = 'REQUEST'; | ||
var RESPONSE_NOTIFICATION = exports.RESPONSE_NOTIFICATION = 'RESPONSE_NOTIFICATION'; | ||
var UNSUBSCRIBE = exports.UNSUBSCRIBE = 'UNSUBSCRIBE'; | ||
var CLEAR_CACHE = exports.CLEAR_CACHE = 'CLEAR_CACHE'; | ||
var INVALIDATE = exports.INVALIDATE = 'INVALIDATE'; |
@@ -11,2 +11,4 @@ 'use strict'; | ||
const dropLastSegment = exports.dropLastSegment = (n, url) => url.split('/').slice(0, n * -1).join('/'); | ||
var dropLastSegment = exports.dropLastSegment = function dropLastSegment(n, url) { | ||
return url.split('/').slice(0, n * -1).join('/'); | ||
}; |
@@ -14,3 +14,3 @@ 'use strict'; | ||
// $FlowFixMe | ||
const undefinedValueError = 'undefined may not be passed as a value to setItem.'; | ||
var undefinedValueError = 'undefined may not be passed as a value to setItem.'; | ||
// $FlowFixMe | ||
@@ -31,11 +31,11 @@ /** | ||
const mkMemCache = () => { | ||
let store = {}; | ||
var mkMemCache = function mkMemCache() { | ||
var store = {}; | ||
const cache = { | ||
delete: key => { | ||
var cache = { | ||
delete: function _delete(key) { | ||
delete store[key]; | ||
return _Observable.Observable.of(true); | ||
}, | ||
set: (key, value) => { | ||
set: function set(key, value) { | ||
if (value === undefined) { | ||
@@ -47,10 +47,10 @@ return _Observable.Observable.throw(new Error(undefinedValueError)); | ||
}, | ||
has: key => { | ||
const item = store[key]; | ||
has: function has(key) { | ||
var item = store[key]; | ||
return _Observable.Observable.of(store.hasOwnProperty(key)); | ||
}, | ||
get: key => { | ||
get: function get(key) { | ||
return cache.has(key) ? _Observable.Observable.of(store[key]) : _Observable.Observable.of(undefined); | ||
}, | ||
clear: () => { | ||
clear: function clear() { | ||
store = {}; | ||
@@ -57,0 +57,0 @@ return _Observable.Observable.of(true); |
{ | ||
"name": "orq", | ||
"version": "0.1.7", | ||
"version": "0.1.8", | ||
"description": "HTTP Request Queue Optimized for Web Workers.", | ||
@@ -23,5 +23,5 @@ "main": "index.js", | ||
"devDependencies": { | ||
"@ava/babel-preset-stage-4": "^1.0.0", | ||
"ava": "^0.19.1", | ||
"babel-cli": "^6.24.1", | ||
"babel-preset-es2015": "6.24.1", | ||
"babel-preset-flow": "^6.23.0", | ||
@@ -28,0 +28,0 @@ "babel-register": "^6.24.1", |
@@ -31,3 +31,3 @@ 'use strict'; | ||
var _message = require('./lib/message'); | ||
var _message3 = require('./lib/message'); | ||
@@ -49,27 +49,40 @@ // $FlowFixMe | ||
// $FlowFixMe | ||
const mkRequestQueueReceiver = (worker, addRequest, cache) => { | ||
_Observable.Observable.fromEvent(worker, 'message').pluck('data').filter(_message.isMsg).groupBy(({ id }) => id).subscribe(message$ => { | ||
var mkRequestQueueReceiver = function mkRequestQueueReceiver(worker, addRequest, cache) { | ||
_Observable.Observable.fromEvent(worker, 'message').pluck('data').filter(_message3.isMsg).groupBy(function (_ref) { | ||
var id = _ref.id; | ||
return id; | ||
}).subscribe(function (message$) { | ||
// FIXME: this is fucked. find a better way! | ||
let message; | ||
let testSub; | ||
const done$ = new _Subject.Subject(); | ||
var message = void 0; | ||
var testSub = void 0; | ||
var done$ = new _Subject.Subject(); | ||
const sub = message$.takeUntil(done$).do(tmpMessage => { | ||
var sub = message$.takeUntil(done$).do(function (tmpMessage) { | ||
message = tmpMessage; | ||
}).do(() => { | ||
if (message.type === _message.UNSUBSCRIBE) { | ||
}).do(function () { | ||
if (message.type === _message3.UNSUBSCRIBE) { | ||
sub.unsubscribe(); | ||
} | ||
}).concatMap(() => { | ||
const { type, id, payload } = message; | ||
const options = Object.assign({ method: 'GET' }, payload && payload.options || {}); | ||
if (type === _message.REQUEST) { | ||
const { url } = payload; | ||
const { method } = options; | ||
return cache.get([method, url]).concatMap(cachedValue => cachedValue ? _Observable.Observable.of(cachedValue) : addRequest(url, options).concatMap(newValue => cache.set([method, url], newValue))); | ||
} else if (type === _message.INVALIDATE) { | ||
const { url } = payload; | ||
const { method } = options; | ||
return cache.delete([method, url]); | ||
} else if (type === _message.CLEAR_CACHE) { | ||
}).concatMap(function () { | ||
var _message = message, | ||
type = _message.type, | ||
id = _message.id, | ||
payload = _message.payload; | ||
var options = Object.assign({ method: 'GET' }, payload && payload.options || {}); | ||
if (type === _message3.REQUEST) { | ||
var _url = payload.url; | ||
var method = options.method; | ||
return cache.get([method, _url]).concatMap(function (cachedValue) { | ||
return cachedValue ? _Observable.Observable.of(cachedValue) : addRequest(_url, options).concatMap(function (newValue) { | ||
return cache.set([method, _url], newValue); | ||
}); | ||
}); | ||
} else if (type === _message3.INVALIDATE) { | ||
var _url2 = payload.url; | ||
var _method = options.method; | ||
return cache.delete([_method, _url2]); | ||
} else if (type === _message3.CLEAR_CACHE) { | ||
return cache.clear(); | ||
@@ -79,10 +92,13 @@ } else { | ||
} | ||
}).materialize().subscribe(notification => { | ||
const { type, id } = message; | ||
worker.postMessage((0, _message.msg)(type, notification, id)); | ||
}).materialize().subscribe(function (notification) { | ||
var _message2 = message, | ||
type = _message2.type, | ||
id = _message2.id; | ||
worker.postMessage((0, _message3.msg)(type, notification, id)); | ||
done$.next(true); | ||
}, error => { | ||
}, function (error) { | ||
console.error(error); | ||
}); | ||
}, error => { | ||
}, function (error) { | ||
console.error(error); | ||
@@ -89,0 +105,0 @@ }); |
@@ -8,2 +8,21 @@ 'use strict'; | ||
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); /** | ||
* request-queue manages request concurrency and eliminates duplicate requests. | ||
*/ | ||
// $FlowFixMe | ||
// $FlowFixMe | ||
// $FlowFixMe | ||
// $FlowFixMe | ||
// $FlowFixMe | ||
// $FlowFixMe | ||
// $FlowFixMe | ||
var _BehaviorSubject = require('rxjs/BehaviorSubject'); | ||
@@ -25,45 +44,50 @@ | ||
// $FlowFixMe | ||
var defaultOptions = { | ||
maxConcurrent: 4 | ||
}; | ||
// $FlowFixMe | ||
var mkRequestQueue = exports.mkRequestQueue = function mkRequestQueue(request) { | ||
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
// $FlowFixMe | ||
var _Object$assign = Object.assign({}, defaultOptions, options), | ||
maxConcurrent = _Object$assign.maxConcurrent; | ||
// $FlowFixMe | ||
var duplicateTracker = function (openRequests) { | ||
return { | ||
has: function has(needleUrl) { | ||
return openRequests.find(function (_ref) { | ||
var _ref2 = _slicedToArray(_ref, 2), | ||
url = _ref2[1]; | ||
// $FlowFixMe | ||
return needleUrl === url; | ||
}); | ||
}, | ||
get: function get(needleUrl) { | ||
var found = duplicateTracker.has(needleUrl); | ||
return found ? found[0] : undefined; | ||
}, | ||
add: function add(key, url) { | ||
openRequests.push([key, url]); | ||
}, | ||
drop: function drop(dropKey) { | ||
openRequests = openRequests.filter(function (_ref3) { | ||
var _ref4 = _slicedToArray(_ref3, 1), | ||
key = _ref4[0]; | ||
// $FlowFixMe | ||
/** | ||
* request-queue manages request concurrency and eliminates duplicate requests. | ||
*/ | ||
return key !== dropKey; | ||
}); | ||
} | ||
}; | ||
}([]); | ||
var test = Symbol(); | ||
const defaultOptions = { | ||
maxConcurrent: 4 | ||
}; | ||
// $FlowFixMe | ||
const mkRequestQueue = exports.mkRequestQueue = (request, options = {}) => { | ||
const { maxConcurrent } = Object.assign({}, defaultOptions, options); | ||
var requests$ = new _BehaviorSubject.BehaviorSubject(); | ||
var responses$ = requests$.mergeAll(maxConcurrent); | ||
const duplicateTracker = (openRequests => ({ | ||
has: needleUrl => openRequests.find(([, url]) => needleUrl === url), | ||
get: needleUrl => { | ||
const found = duplicateTracker.has(needleUrl); | ||
return found ? found[0] : undefined; | ||
}, | ||
add: (key, url) => { | ||
openRequests.push([key, url]); | ||
}, | ||
drop: dropKey => { | ||
openRequests = openRequests.filter(([key]) => key !== dropKey); | ||
} | ||
}))([]); | ||
const test = Symbol(); | ||
return function (url) { | ||
var reqOptions = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
var _reqOptions$method = reqOptions.method, | ||
method = _reqOptions$method === undefined ? 'GET' : _reqOptions$method; | ||
const requests$ = new _BehaviorSubject.BehaviorSubject(); | ||
const responses$ = requests$.mergeAll(maxConcurrent); | ||
return (url, reqOptions = {}) => { | ||
const { method = 'GET' } = reqOptions; | ||
let key = Symbol(`${method} ${url}`); | ||
var key = Symbol(method + ' ' + url); | ||
if (method === 'GET' && duplicateTracker.has(url)) { | ||
@@ -75,5 +99,19 @@ key = duplicateTracker.get(url); | ||
} | ||
requests$.next(request(url, reqOptions).share().materialize().map(notification => [key, notification]).do(n => duplicateTracker.drop(key))); | ||
requests$.next(request(url, reqOptions).share().materialize().map(function (notification) { | ||
return [key, notification]; | ||
}).do(function (n) { | ||
return duplicateTracker.drop(key); | ||
})); | ||
} | ||
return responses$.filter(([resKey]) => resKey === key).map(([, notification]) => notification).dematerialize(); | ||
return responses$.filter(function (_ref5) { | ||
var _ref6 = _slicedToArray(_ref5, 1), | ||
resKey = _ref6[0]; | ||
return resKey === key; | ||
}).map(function (_ref7) { | ||
var _ref8 = _slicedToArray(_ref7, 2), | ||
notification = _ref8[1]; | ||
return notification; | ||
}).dematerialize(); | ||
}; | ||
@@ -80,0 +118,0 @@ }; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
164574
526
15