medikoo / memoizee

Complete memoize/cache solution for JavaScript

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Different cache id resolution per argument

amaury1093 opened this issue · comments

My function has signature:

function myFunction(a: object, b: object): void;

const memoized = memoize(f);

If I understood well, when I memoize that, it memoizes by object reference:

memoize({ foo: 'bar' }, { bar: 'qux' });
memoize({ foo: 'bar' }, { bar: 'qux' }); // Cache NOT hit

I wish to memoize the 1st argument by its serialized version, and the 2nd argument by object reference. Namely, if:

const first = { foo: 'bar' };
const second = { bar: 'qux' };

The I want the 3 following tests to pass:

Test 1:

memoize(first, second);
memoize({ foo: 'bar' }, second); // Cache hit
memoize(first, second); // Cache hit

Test 2:

memoize(first, second);
memoize(first, { bar: 'qux' }); // Cache not hit
memoize({ foo: 'bar' }, { bar: 'qux' }); // Cache not hit

Test 3:

memoize({ foo: 'bar' }, second);
memoize({ foo: 'bar' }, second); // Cache hit
memoize(first, second); // Cache hit

Is that possible with the current version?

Is that possible with the current version?

Yes it is, but you need to provide your own normalizer, which can work as e.g.:

const idCounter = 0;
const idMap = new WeakMap();
const getObjectId = obj => {
  if (idMap.has(obj)) return iMap.get(obj);
  const id = ++idCounter;
  idMap.set(obj, id);
  return id;
};

const memoized = memoize(f, {
  normalizer: ([a, b]) => `${getObjectId(b)},${JSON.stringify(a)}`
});

Alternatively, if it would be the case where first argument is expected to be mapped by reference and second by serialized representation, it can be done more straightforward with weak mode:

const memoizeWeak = require("memoizee/weak");

const memoized = memoizeWeak(f, { normalizer: ([,b]) => JSON.stringify(b) });