@newdash/newdash
Version:
javascript/typescript utility library
108 lines (107 loc) • 3.09 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.cacheIt = void 0;
/* eslint-disable max-len */
const cacheProvider_1 = require("./cacheProvider");
const toHashCode_1 = require("./functional/toHashCode");
const isClass_1 = require("./isClass");
/**
* @private
* @ignore
* @internal
*/
const KEY_CACHE_PROPERTY = "__cache_storage";
/**
* @private
* @ignore
* @internal
*/
const KEY_CLEAR_CACHE_FUNCTION = "__cache_clear";
const defaultCacheItOptions = {
provider: cacheProvider_1.LRUCacheProvider,
providerArgs: undefined,
providerOptions: {},
};
/**
* @private
* @ignore
* @internal
* @param obj
* @param options
*/
function cacheItFunction(obj, options) {
const cacheProvider = options.providerOptions !== undefined ? new options.provider(options.providerOptions) : new options.provider(...options.providerArgs);
const clearCache = (...args) => {
cacheProvider.delete((0, toHashCode_1.toHashCode)(args));
};
return new Proxy(obj, {
apply: (target, ctx, args) => {
const producer = () => target.apply(ctx, args);
const key = (0, toHashCode_1.toHashCode)(args);
return cacheProvider.getOrCreate(key, producer);
},
get: (target, propertyName) => {
if (propertyName in target) {
return target[propertyName];
}
if (propertyName === KEY_CACHE_PROPERTY) {
return cacheProvider;
}
if (propertyName === KEY_CLEAR_CACHE_FUNCTION) {
return clearCache;
}
return undefined;
}
});
}
/**
* @private
* @ignore
* @internal
* @param obj
* @param options
*/
function cacheItClass(obj, options) {
return new Proxy(obj, {
construct: (target, args) => cacheItObject(new target(...args), options)
});
}
/**
* @private
* @ignore
* @internal
* @param obj
* @param options
*/
function cacheItObject(obj, options) {
const methodsCacheProvider = new cacheProvider_1.LRUCacheProvider(10240);
return new Proxy(obj, {
get: ((target, propertyName) => {
if (propertyName in target) {
const propertyValue = target[propertyName];
if (typeof propertyValue === "function") {
const producer = () => cacheItFunction(propertyValue, options);
return methodsCacheProvider.getOrCreate(propertyName, producer);
}
return propertyValue;
}
})
});
}
function cacheIt(obj, options) {
// assign default option
options = Object.assign({}, defaultCacheItOptions, options);
switch (typeof obj) {
case "object":
return cacheItObject(obj, options);
case "function":
if ((0, isClass_1.isClass)(obj)) {
return cacheItClass(obj, options);
}
return cacheItFunction(obj, options);
default:
return obj;
}
}
exports.cacheIt = cacheIt;
exports.default = cacheIt;