module.exports = AsyncCache;
var LRU = require('lru-cache');
function AsyncCache(opt) {
Iif (!opt || typeof opt !== 'object')
throw new Error('options must be an object');
Iif (!opt.load)
throw new Error('load function is required');
Iif (!(this instanceof AsyncCache))
return new AsyncCache(opt);
this._opt = opt;
this._cache = new LRU(opt);
this._load = opt.load;
this._loading = {};
this._stales = {};
this._allowStale = opt.stale;
}
Object.defineProperty(AsyncCache.prototype, 'itemCount', {
get: function() {
return this._cache.itemCount;
},
enumerable: true,
configurable: true
});
AsyncCache.prototype.get = function(key, cb) {
var stale = this._stales[key];
Iif (this._allowStale && stale !== undefined) {
return process.nextTick(function() {
cb(null, stale);
});
}
if (this._loading[key])
return this._loading[key].push(cb);
var has = this._cache.has(key);
var cached = this._cache.get(key);
if (has && void 0 !== cached)
return process.nextTick(function() {
cb(null, cached);
});
if (void 0 !== cached && this._allowStale && !has) {
this._stales[key] = cached;
process.nextTick(function() {
cb(null, cached);
});
}
else
this._loading[key] = [ cb ];
this._load(key, function(er, res) {
Eif (!er)
this._cache.set(key, res);
if (this._allowStale)
delete this._stales[key];
var cbs = this._loading[key];
if (!cbs)
return;
delete this._loading[key];
cbs.forEach(function (cb) {
cb(er, res);
});
}.bind(this));
};
AsyncCache.prototype.set = function(key, val) {
return this._cache.set(key, val);
};
AsyncCache.prototype.reset = function() {
return this._cache.reset();
};
AsyncCache.prototype.has = function(key) {
return this._cache.has(key);
};
AsyncCache.prototype.del = function(key) {
return this._cache.del(key);
};
AsyncCache.prototype.peek = function(key) {
return this._cache.peek(key);
};
|