UNPKG

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
"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