LibreNMS/lib/typeahead/src/bloodhound/transport.js

131 lines
3.0 KiB
JavaScript

/*
* typeahead.js
* https://github.com/twitter/typeahead.js
* Copyright 2013-2014 Twitter, Inc. and other contributors; Licensed MIT
*/
var Transport = (function() {
'use strict';
var pendingRequestsCount = 0,
pendingRequests = {},
maxPendingRequests = 6,
sharedCache = new LruCache(10);
// constructor
// -----------
function Transport(o) {
o = o || {};
this.cancelled = false;
this.lastReq = null;
this._send = o.transport;
this._get = o.limiter ? o.limiter(this._get) : this._get;
this._cache = o.cache === false ? new LruCache(0) : sharedCache;
}
// static methods
// --------------
Transport.setMaxPendingRequests = function setMaxPendingRequests(num) {
maxPendingRequests = num;
};
Transport.resetCache = function resetCache() {
sharedCache.reset();
};
// instance methods
// ----------------
_.mixin(Transport.prototype, {
// ### private
_fingerprint: function fingerprint(o) {
o = o || {};
return o.url + o.type + $.param(o.data || {});
},
_get: function(o, cb) {
var that = this, fingerprint, jqXhr;
fingerprint = this._fingerprint(o);
// #149: don't make a network request if there has been a cancellation
// or if the url doesn't match the last url Transport#get was invoked with
if (this.cancelled || fingerprint !== this.lastReq) { return; }
// a request is already in progress, piggyback off of it
if (jqXhr = pendingRequests[fingerprint]) {
jqXhr.done(done).fail(fail);
}
// under the pending request threshold, so fire off a request
else if (pendingRequestsCount < maxPendingRequests) {
pendingRequestsCount++;
pendingRequests[fingerprint] =
this._send(o).done(done).fail(fail).always(always);
}
// at the pending request threshold, so hang out in the on deck circle
else {
this.onDeckRequestArgs = [].slice.call(arguments, 0);
}
function done(resp) {
cb(null, resp);
that._cache.set(fingerprint, resp);
}
function fail() {
cb(true);
}
function always() {
pendingRequestsCount--;
delete pendingRequests[fingerprint];
// ensures request is always made for the last query
if (that.onDeckRequestArgs) {
that._get.apply(that, that.onDeckRequestArgs);
that.onDeckRequestArgs = null;
}
}
},
// ### public
get: function(o, cb) {
var resp, fingerprint;
cb = cb || $.noop;
o = _.isString(o) ? { url: o } : (o || {});
fingerprint = this._fingerprint(o);
this.cancelled = false;
this.lastReq = fingerprint;
// in-memory cache hit
if (resp = this._cache.get(fingerprint)) {
cb(null, resp);
}
// go to network
else {
this._get(o, cb);
}
},
cancel: function() {
this.cancelled = true;
}
});
return Transport;
})();