@naturalcycles/js-lib
Version:
Standard library for universal (browser + Node.js) javascript
60 lines (58 loc) • 2.44 kB
JavaScript
;
// Based on:
// https://github.com/mgechev/memo-decorator/blob/master/index.ts
// http://decodize.com/blog/2012/08/27/javascript-memoization-caching-results-for-better-performance/
// http://inlehmansterms.net/2015/03/01/javascript-memoization/
// https://community.risingstack.com/the-worlds-fastest-javascript-memoization-library/
Object.defineProperty(exports, "__esModule", { value: true });
exports.memoSimple = void 0;
const decorator_util_1 = require("./decorator.util");
const memo_util_1 = require("./memo.util");
// memoSimple decorator is NOT exported. Only used in benchmarks currently
/**
* Memoizes the method of the class, so it caches the output and returns the cached version if the "key"
* of the cache is the same. Key, by defaul, is calculated as `JSON.stringify(...args)`.
* Cache is stored indefinitely in internal Map.
* There is more advanced version of memo decorator called `memoCache`.
*
* Supports dropping it's cache by calling .dropCache() method of decorated function (useful in unit testing).
*/
const memoSimple = (opt = {}) => (target, key, descriptor) => {
if (typeof descriptor.value !== 'function') {
throw new TypeError('Memoization can be applied only to methods');
}
const originalFn = descriptor.value;
// console.log(`${key} len: ${originalFn.length}`)
// todo: optimization disabled until "default arg value" use case is solved (see memo.decorator.test.ts)
/*
let cache: MemoCache
// Function with 0 arguments
if (!originalFn.length) {
cache = new SingleValueMemoCache()
} else {
// Function with > 0 arguments
cache = new MapMemoCache()
// cache = new ObjectMemoCache()
}
*/
const cache = new memo_util_1.MapMemoCache();
const { logger = console } = opt;
const keyStr = String(key);
const methodSignature = (0, decorator_util_1._getTargetMethodSignature)(target, keyStr);
descriptor.value = function (...args) {
const ctx = this;
const cacheKey = (0, memo_util_1.jsonMemoSerializer)(args);
if (cache.has(cacheKey)) {
return cache.get(cacheKey);
}
const res = originalFn.apply(ctx, args);
cache.set(cacheKey, res);
return res;
};
descriptor.value.dropCache = () => {
logger.log(`${methodSignature} @memo.dropCache()`);
cache.clear();
};
return descriptor;
};
exports.memoSimple = memoSimple;