Skip to content

Instantly share code, notes, and snippets.

@alber70g
Created September 14, 2023 13:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alber70g/e196b9297a75c34e947e5c38655afe10 to your computer and use it in GitHub Desktop.
Save alber70g/e196b9297a75c34e947e5c38655afe10 to your computer and use it in GitHub Desktop.
Memoize function and Logger Proxy
/**
* function to memoize calls to a function
*
* @param {(args) => any} fn function that is executed if the key is not found in the cache
* @param {(args) => string)} keyGenFn function that accepts arguments and returns a string to identify the key in the cache
* @param {{toCache: (args) => any, fromCache: (args) => any}} options custom functions to store and retrieve values from the cache
*/
function memoizeFn(fn, options = {}, keyGenFn = (args) => args.join(',')) {
this.cache = {};
const _cache = {
toCache: (key, value) => (this.cache[key] = value),
isInCache: (key) => key in this.cache,
getFromCache: (key) => this.cache[key],
...options,
};
const cache = createLoggerProxy('cache', _cache);
const func = function (...args) {
const key = keyGenFn(args);
if (cache.isInCache(key)) {
return cache.getFromCache(key);
} else {
const result = fn.apply(this, args);
cache.toCache(key, result);
return result;
}
};
return func;
}
export const memoize = createLoggerProxy('memoize', memoizeFn);
export function memoizeToLocalStorage(fn) {
const cache = {
toCache: (key, value) => localStorage.setItem(key, value),
isInCache: (key) => key in localStorage,
getFromCache: (key) => localStorage.getItem(key),
};
return memoize(fn, undefined, cache);
}
export function createLoggerProxy(name, obj, logger = console.log) {
let current = name;
return new Proxy(obj, {
get: (target, prop) => {
current += `.${prop}`;
if (typeof target[prop] === 'function') {
return new Proxy(target[prop], {
apply(applyTarget, thisArg, args) {
current += `(${args.map(JSON.stringify).join(', ')})`;
console.log(current);
current = name;
return Reflect.apply(applyTarget, thisArg, args);
},
});
}
return target[prop];
},
apply: (target, thisArg, args) => {
current += `(${args.map(JSON.stringify).join(', ')})`;
logger(current);
current = name;
return target.apply(thisArg, args);
},
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment