@trifrost/core
Version:
Blazingly fast, runtime-agnostic server framework for modern edge and node environments
91 lines (90 loc) • 4 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Sym_TriFrostSkipCache = exports.Sym_TriFrostCached = void 0;
exports.cache = cache;
exports.cacheSkip = cacheSkip;
exports.cacheSkipped = cacheSkipped;
exports.cacheFn = cacheFn;
const string_1 = require("@valkyriestudios/utils/string");
exports.Sym_TriFrostCached = Symbol('trifrost.cache.cached');
exports.Sym_TriFrostSkipCache = Symbol('trifrost.cache.skip');
function cache(key, opts) {
return function (method) {
/* Prevent re-decoration */
if (Reflect.get(method, exports.Sym_TriFrostCached))
return method;
const wrapped = async function (...args) {
const ctx = Array.isArray(args) && args.length ? args[0] : undefined;
/* Get trifrost cache either from passed ctx, this.cache or this.ctx.cache */
const trifrost_cache = ctx?.cache ?? this?.cache ?? this?.ctx?.cache;
/* No viable cache found */
if (typeof trifrost_cache?.get !== 'function' || typeof trifrost_cache?.set !== 'function')
return method.call(this, ...args);
/* Determine cache key */
const ckey = typeof key === 'function' ? key(...args.slice(0, key.length)) : (0, string_1.isNeString)(key) ? key : null;
if (!ckey)
return method.call(this, ...args);
/* Retrieve from cache, if exists -> return */
const cached = await trifrost_cache.get(ckey);
if (cached !== null && cached !== undefined)
return cached;
/* Run method */
const result = await method.call(this, ...args);
if (Object.prototype.toString.call(result) === '[object Object]' &&
Reflect.get(result, exports.Sym_TriFrostSkipCache))
return result.value;
/* Cache */
await trifrost_cache.set(ckey, result, opts);
return result;
};
/* Set to prevent re-decoration */
Reflect.set(wrapped, exports.Sym_TriFrostCached, true);
return wrapped;
};
}
/**
* Marks a value as "do not cache", will still return the value directly from the method.
*/
function cacheSkip(value) {
const v = { value };
Reflect.set(v, exports.Sym_TriFrostSkipCache, true);
return v;
}
/**
* Returns whether or not a value is a cache skip value
*/
function cacheSkipped(v) {
return (Object.prototype.toString.call(v) === '[object Object]' && Reflect.get(v, exports.Sym_TriFrostSkipCache) === true);
}
function cacheFn(key, opts) {
return function (fn) {
/* Prevent re-decoration */
if (Reflect.get(fn, exports.Sym_TriFrostCached))
return fn;
const wrapped = async function (...args) {
const ctx = Array.isArray(args) && args.length ? args[0] : undefined;
const trifrost_cache = ctx?.cache ?? this?.cache ?? this?.ctx?.cache;
/* No viable cache found */
if (typeof trifrost_cache?.get !== 'function' || typeof trifrost_cache?.set !== 'function')
return fn.apply(this, args);
/* Determine cache key */
const ckey = typeof key === 'function' ? key(...args.slice(0, key.length)) : (0, string_1.isNeString)(key) ? key : null;
if (!ckey)
return fn.apply(this, args);
/* Retrieve from cache, if exists -> return */
const cached = await trifrost_cache.get(ckey);
if (cached !== null && cached !== undefined)
return cached;
/* Run method */
const result = await fn.apply(this, args);
if (cacheSkipped(result))
return result.value;
/* Cache */
await trifrost_cache.set(ckey, result, opts);
return result;
};
/* Set to prevent re-decoration */
Reflect.set(wrapped, exports.Sym_TriFrostCached, true);
return wrapped;
};
}