Musique/node_modules/memoizee/ext/max-age.js

90 lines
2.7 KiB
JavaScript

/* eslint consistent-this: 0 */
// Timeout cached values
"use strict";
var aFrom = require("es5-ext/array/from")
, forEach = require("es5-ext/object/for-each")
, nextTick = require("next-tick")
, isPromise = require("is-promise")
, timeout = require("timers-ext/valid-timeout")
, extensions = require("../lib/registered-extensions");
var noop = Function.prototype, max = Math.max, min = Math.min, create = Object.create;
extensions.maxAge = function (maxAge, conf, options) {
var timeouts, postfix, preFetchAge, preFetchTimeouts;
maxAge = timeout(maxAge);
if (!maxAge) return;
timeouts = create(null);
postfix =
(options.async && extensions.async) || (options.promise && extensions.promise)
? "async"
: "";
conf.on("set" + postfix, function (id) {
timeouts[id] = setTimeout(function () { conf.delete(id); }, maxAge);
if (typeof timeouts[id].unref === "function") timeouts[id].unref();
if (!preFetchTimeouts) return;
if (preFetchTimeouts[id]) {
if (preFetchTimeouts[id] !== "nextTick") clearTimeout(preFetchTimeouts[id]);
}
preFetchTimeouts[id] = setTimeout(function () {
delete preFetchTimeouts[id];
}, preFetchAge);
if (typeof preFetchTimeouts[id].unref === "function") preFetchTimeouts[id].unref();
});
conf.on("delete" + postfix, function (id) {
clearTimeout(timeouts[id]);
delete timeouts[id];
if (!preFetchTimeouts) return;
if (preFetchTimeouts[id] !== "nextTick") clearTimeout(preFetchTimeouts[id]);
delete preFetchTimeouts[id];
});
if (options.preFetch) {
if (options.preFetch === true || isNaN(options.preFetch)) {
preFetchAge = 0.333;
} else {
preFetchAge = max(min(Number(options.preFetch), 1), 0);
}
if (preFetchAge) {
preFetchTimeouts = {};
preFetchAge = (1 - preFetchAge) * maxAge;
conf.on("get" + postfix, function (id, args, context) {
if (!preFetchTimeouts[id]) {
preFetchTimeouts[id] = "nextTick";
nextTick(function () {
var result;
if (preFetchTimeouts[id] !== "nextTick") return;
delete preFetchTimeouts[id];
conf.delete(id);
if (options.async) {
args = aFrom(args);
args.push(noop);
}
result = conf.memoized.apply(context, args);
if (options.promise) {
// Supress eventual error warnings
if (isPromise(result)) {
if (typeof result.done === "function") result.done(noop, noop);
else result.then(noop, noop);
}
}
});
}
});
}
}
conf.on("clear" + postfix, function () {
forEach(timeouts, function (id) { clearTimeout(id); });
timeouts = {};
if (preFetchTimeouts) {
forEach(preFetchTimeouts, function (id) { if (id !== "nextTick") clearTimeout(id); });
preFetchTimeouts = {};
}
});
};