@daisugi/kintsugi
Version:
Kintsugi is a set of utilities to help build a fault tolerant services.
60 lines • 2.54 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.buildCacheKey = buildCacheKey;
exports.calculateCacheMaxAgeMs = calculateCacheMaxAgeMs;
exports.shouldInvalidateCache = shouldInvalidateCache;
exports.shouldCache = shouldCache;
exports.withCache = withCache;
const ayamari_1 = require("@daisugi/ayamari");
const enc_to_fnv1a_js_1 = require("./enc_to_fnv1a.js");
const random_between_js_1 = require("./random_between.js");
const simple_memory_store_js_1 = require("./simple_memory_store.js");
const stringify_args_js_1 = require("./stringify_args.js");
const defaultMaxAgeMs = 1000 * 60 * 60 * 4; // 4h.
const defaultVersion = 'v1';
function buildCacheKey(fnHash, version, args) {
return `${fnHash}:${version}:${(0, stringify_args_js_1.stringifyArgs)(args)}`;
}
function calculateCacheMaxAgeMs(maxAgeMs) {
return (0, random_between_js_1.randomBetween)(maxAgeMs * 0.75, maxAgeMs);
}
function shouldInvalidateCache() {
return false;
}
function shouldCache(response) {
if (response.isSuccess) {
return true;
}
// Cache NotFound by default.
// https://docs.fastly.com/en/guides/http-code-codes-cached-by-default
if (response.isFailure &&
response.getError().code === ayamari_1.Ayamari.errCode.NotFound) {
return true;
}
return false;
}
function withCache(fn, opts = {}) {
const cacheStore = opts.cacheStore || new simple_memory_store_js_1.SimpleMemoryStore();
const version = opts.version || defaultVersion;
const maxAgeMs = opts.maxAgeMs || defaultMaxAgeMs;
const _buildCacheKey = opts.buildCacheKey || buildCacheKey;
const _calculateCacheMaxAgeMs = opts.calculateCacheMaxAgeMs || calculateCacheMaxAgeMs;
const _shouldCache = opts.shouldCache || shouldCache;
const _shouldInvalidateCache = opts.shouldInvalidateCache || shouldInvalidateCache;
const fnHash = (0, enc_to_fnv1a_js_1.encToFNV1A)(fn.toString());
return async function (...args) {
const cacheKey = _buildCacheKey(fnHash, version, args);
if (!_shouldInvalidateCache(args)) {
const cacheResponse = await cacheStore.get(cacheKey);
if (cacheResponse.isSuccess) {
return cacheResponse.getValue();
}
}
const response = await fn.apply(this, args);
if (_shouldCache(response)) {
cacheStore.set(cacheKey, response, _calculateCacheMaxAgeMs(maxAgeMs)); // Silent fail.
}
return response;
};
}
//# sourceMappingURL=with_cache.js.map