feat(providence): allow to clear cache of memoized function
This commit is contained in:
parent
1df3854196
commit
994a7b5266
2 changed files with 55 additions and 23 deletions
|
|
@ -24,30 +24,33 @@ function createCachableArg(arg) {
|
|||
|
||||
/**
|
||||
* @template T
|
||||
* @type {<T extends Function>(functionToMemoize:T, opts?:{ storage?:object; }) => T}
|
||||
* @type {<T extends Function>(functionToMemoize:T, opts?:{ cacheStorage?:object; }) => T & {clearCache:() => void}}
|
||||
*/
|
||||
export function memoize(functionToMemoize, { storage = {} } = {}) {
|
||||
return /** @type {* & T} */ (
|
||||
function memoizedFn() {
|
||||
// eslint-disable-next-line prefer-rest-params
|
||||
const args = [...arguments];
|
||||
const shouldSerialize = args.some(isObject);
|
||||
export function memoize(functionToMemoize, { cacheStorage = {} } = {}) {
|
||||
function memoizedFn() {
|
||||
// eslint-disable-next-line prefer-rest-params
|
||||
const args = [...arguments];
|
||||
const shouldSerialize = args.some(isObject);
|
||||
|
||||
const cachableArgs = shouldSerialize ? args.map(createCachableArg) : args;
|
||||
// Allow disabling of cache for testing purposes
|
||||
const cachableArgs = shouldSerialize ? args.map(createCachableArg) : args;
|
||||
// Allow disabling of cache for testing purposes
|
||||
// @ts-expect-error
|
||||
if (shouldCache && cachableArgs in cacheStorage) {
|
||||
// @ts-expect-error
|
||||
if (shouldCache && cachableArgs in storage) {
|
||||
// @ts-expect-error
|
||||
return storage[cachableArgs];
|
||||
}
|
||||
// @ts-expect-error
|
||||
const outcome = functionToMemoize.apply(this, args);
|
||||
// @ts-expect-error
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
storage[cachableArgs] = outcome;
|
||||
return outcome;
|
||||
return cacheStorage[cachableArgs];
|
||||
}
|
||||
);
|
||||
// @ts-expect-error
|
||||
const outcome = functionToMemoize.apply(this, args);
|
||||
// @ts-expect-error
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
cacheStorage[cachableArgs] = outcome;
|
||||
return outcome;
|
||||
}
|
||||
memoizedFn.clearCache = () => {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
cacheStorage = {};
|
||||
};
|
||||
return /** @type {* & T & {clearCache:() => void}} */ (memoizedFn);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -201,13 +201,13 @@ describe('Memoize', () => {
|
|||
sumCalled += 1;
|
||||
return { ...a, ...b };
|
||||
}
|
||||
const sumMemoized = memoize(sum, { serializeObjects: true });
|
||||
const sumMemoized = memoize(sum);
|
||||
let sum2Called = 0;
|
||||
function sum2(/** @type {object} a */ a, /** @type {object} a */ b) {
|
||||
sum2Called += 1;
|
||||
return { ...a, ...b };
|
||||
}
|
||||
const sum2Memoized = memoize(sum2, { serializeObjects: true });
|
||||
const sum2Memoized = memoize(sum2);
|
||||
|
||||
expect(sumMemoized({ x: 1 }, { y: 2 })).to.deep.equal({ x: 1, y: 2 });
|
||||
expect(sumCalled).to.equal(1);
|
||||
|
|
@ -233,7 +233,7 @@ describe('Memoize', () => {
|
|||
sumCalled += 1;
|
||||
return { ...a, ...b };
|
||||
}
|
||||
const sumMemoized = memoize(sum, { serializeObjects: true });
|
||||
const sumMemoized = memoize(sum);
|
||||
|
||||
// Put in cache for args combination
|
||||
const result = sumMemoized({ x: 1 }, { y: 2 });
|
||||
|
|
@ -313,4 +313,33 @@ describe('Memoize', () => {
|
|||
expect(sum2Called).to.equal(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Cache', () => {
|
||||
it(`"memoizedFn.clearCache()" clears the cache for a memoized fn"`, async () => {
|
||||
let sumCalled = 0;
|
||||
function sum(/** @type {string} a */ a, /** @type {string} a */ b) {
|
||||
sumCalled += 1;
|
||||
return a + b;
|
||||
}
|
||||
const sumMemoized = memoize(sum);
|
||||
|
||||
// Put in cache for args combination
|
||||
expect(sumMemoized('1', '2')).to.equal('12');
|
||||
expect(sumCalled).to.equal(1);
|
||||
|
||||
// Return from cache
|
||||
expect(sumMemoized('1', '2')).to.equal('12');
|
||||
expect(sumCalled).to.equal(1);
|
||||
|
||||
sumMemoized.clearCache();
|
||||
|
||||
// Now the original function is called again
|
||||
expect(sumMemoized('1', '2')).to.equal('12');
|
||||
expect(sumCalled).to.equal(3);
|
||||
|
||||
// Return from new cache again
|
||||
expect(sumMemoized('1', '2')).to.equal('12');
|
||||
expect(sumCalled).to.equal(3);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue