transitory
Version:
In-memory cache with high hit rates via LFU eviction. Supports time-based expiration, automatic loading and metrics.
240 lines • 8.14 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CacheBuilderImpl = void 0;
var BoundedCache_1 = require("../cache/bounded/BoundedCache");
var BoundlessCache_1 = require("../cache/boundless/BoundlessCache");
var ExpirationCache_1 = require("../cache/expiration/ExpirationCache");
var DefaultLoadingCache_1 = require("../cache/loading/DefaultLoadingCache");
var MetricsCache_1 = require("../cache/metrics/MetricsCache");
/**
* Builder for cache instances.
*/
var CacheBuilderImpl = /** @class */ (function () {
function CacheBuilderImpl() {
this.optMetrics = false;
}
/**
* Set a listener that will be called every time something is removed
* from the cache.
*
* @param listener -
* removal listener to use
* @returns self
*/
CacheBuilderImpl.prototype.withRemovalListener = function (listener) {
this.optRemovalListener = listener;
return this;
};
/**
* Set the maximum number of items to keep in the cache before evicting
* something.
*
* @param size -
* number of items to keep
* @returns self
*/
CacheBuilderImpl.prototype.maxSize = function (size) {
this.optMaxSize = size;
return this;
};
/**
* Set a function to use to determine the size of a cached object.
*
* @param weigher -
* function used to weight objects
* @returns self
*/
CacheBuilderImpl.prototype.withWeigher = function (weigher) {
if (typeof weigher !== 'function') {
throw new Error('Weigher should be a function that takes a key and value and returns a number');
}
this.optWeigher = weigher;
return this;
};
/**
* Change to a cache where get can also resolve values if provided with
* a function as the second argument.
*
* @returns self
*/
CacheBuilderImpl.prototype.loading = function () {
return new LoadingCacheBuilderImpl(this, null);
};
/**
* Change to a loading cache, where the get-method will return instances
* of Promise and automatically load unknown values.
*
* @param loader -
* function used to load objects
* @returns self
*/
CacheBuilderImpl.prototype.withLoader = function (loader) {
if (typeof loader !== 'function') {
throw new Error('Loader should be a function that takes a key and returns a value or a promise that resolves to a value');
}
return new LoadingCacheBuilderImpl(this, loader);
};
/**
* Set that the cache should expire items after some time.
*
* @param time -
* max time in milliseconds, or function that will be asked per key/value
* for expiration time
* @returns self
*/
CacheBuilderImpl.prototype.expireAfterWrite = function (time) {
var evaluator;
if (typeof time === 'function') {
evaluator = time;
}
else if (typeof time === 'number') {
evaluator = function () { return time; };
}
else {
throw new Error('expireAfterWrite needs either a maximum age as a number or a function that returns a number');
}
this.optMaxWriteAge = evaluator;
return this;
};
/**
* Set that the cache should expire items some time after they have been read.
*
* @param time -
* max time in milliseconds, or function will be asked per key/value
* for expiration time
* @returns self
*/
CacheBuilderImpl.prototype.expireAfterRead = function (time) {
var evaluator;
if (typeof time === 'function') {
evaluator = time;
}
else if (typeof time === 'number') {
evaluator = function () { return time; };
}
else {
throw new Error('expireAfterRead needs either a maximum age as a number or a function that returns a number');
}
this.optMaxNoReadAge = evaluator;
return this;
};
/**
* Activate tracking of metrics for this cache.
*
* @returns self
*/
CacheBuilderImpl.prototype.metrics = function () {
this.optMetrics = true;
return this;
};
/**
* Build and return the cache.
*
* @returns cache
*/
CacheBuilderImpl.prototype.build = function () {
var cache;
if (typeof this.optMaxWriteAge !== 'undefined' || typeof this.optMaxNoReadAge !== 'undefined') {
/*
* Requested expiration - wrap the base cache a bit as it needs
* custom types, a custom weigher if used and removal listeners
* are added on the expiration cache instead.
*/
var parentCache = void 0;
if (this.optMaxSize) {
parentCache = new BoundedCache_1.BoundedCache({
maxSize: this.optMaxSize,
weigher: createExpirableWeigher(this.optWeigher)
});
}
else {
parentCache = new BoundlessCache_1.BoundlessCache({});
}
cache = new ExpirationCache_1.ExpirationCache({
maxNoReadAge: this.optMaxNoReadAge,
maxWriteAge: this.optMaxWriteAge,
removalListener: this.optRemovalListener,
parent: parentCache
});
}
else {
if (this.optMaxSize) {
cache = new BoundedCache_1.BoundedCache({
maxSize: this.optMaxSize,
weigher: this.optWeigher,
removalListener: this.optRemovalListener
});
}
else {
cache = new BoundlessCache_1.BoundlessCache({
removalListener: this.optRemovalListener
});
}
}
if (this.optMetrics) {
// Collect metrics if requested
cache = new MetricsCache_1.MetricsCache({
parent: cache
});
}
return cache;
};
return CacheBuilderImpl;
}());
exports.CacheBuilderImpl = CacheBuilderImpl;
var LoadingCacheBuilderImpl = /** @class */ (function () {
function LoadingCacheBuilderImpl(parent, loader) {
this.parent = parent;
this.loader = loader;
}
LoadingCacheBuilderImpl.prototype.withRemovalListener = function (listener) {
this.parent.withRemovalListener(listener);
return this;
};
LoadingCacheBuilderImpl.prototype.maxSize = function (size) {
this.parent.maxSize(size);
return this;
};
LoadingCacheBuilderImpl.prototype.withWeigher = function (weigher) {
this.parent.withWeigher(weigher);
return this;
};
LoadingCacheBuilderImpl.prototype.loading = function () {
throw new Error('Already building a loading cache');
};
// eslint-disable-next-line @typescript-eslint/no-unused-vars
LoadingCacheBuilderImpl.prototype.withLoader = function (loader) {
throw new Error('Already building a loading cache');
};
LoadingCacheBuilderImpl.prototype.expireAfterWrite = function (time) {
this.parent.expireAfterWrite(time);
return this;
};
LoadingCacheBuilderImpl.prototype.expireAfterRead = function (time) {
this.parent.expireAfterRead(time);
return this;
};
LoadingCacheBuilderImpl.prototype.metrics = function () {
this.parent.metrics();
return this;
};
LoadingCacheBuilderImpl.prototype.build = function () {
return new DefaultLoadingCache_1.DefaultLoadingCache({
loader: this.loader,
parent: this.parent.build()
});
};
return LoadingCacheBuilderImpl;
}());
/**
* Helper function to create a weigher that uses an Expirable object.
*
* @param w -
* @returns weigher
*/
function createExpirableWeigher(w) {
if (!w)
return null;
return function (key, node) { return w(key, node.value); };
}
//# sourceMappingURL=CacheBuilder.js.map