MCPcopy Create free account
hub / github.com/clientdb/clientdb / cachedComputed

Function cachedComputed

core/utils/cachedComputed.ts:23–67  ·  view source on GitHub ↗
(
  getter: (...args: A) => T,
  options: Options<T> = {}
)

Source from the content-addressed store, hash-verified

21 * Creates 'lazy computed', but with possibility of using multiple arguments
22 */
23export function cachedComputed<A extends any[], T>(
24 getter: (...args: A) => T,
25 options: Options<T> = {}
26) {
27 // For easier debugging - try to get name of getter function
28 const getterName = getter.name || undefined;
29
30 // TODO: cleanup map entries after lazy is disposed
31 const map = createDeepMap<CachedComputed<T>>({
32 checkEquality: options?.equalCompareArgs ?? false,
33 });
34
35 function getComputedForArgs(...args: A) {
36 return map.getOrCreate(args, () =>
37 cachedComputedWithoutArgs(() => getter(...args), {
38 name: getterName,
39 ...options,
40 })
41 );
42 }
43
44 function getValue(...args: A) {
45 /**
46 * This is guard for breaking cache by calling array methods inline.
47 *
48 * eg. const cachedIsItemBig = cachedComputed(item => item.isBig);
49 *
50 * and then doing things like
51 * array.filter(cachedIsItemBig) instead of array.filter(item => cachedIsItemBig(item))
52 *
53 * those 2 seem exactly the same and it is very easy to not notice it, but in first case, 'cachedIsItemBig' will actually be called with 3 arguments instead of 1
54 * as array.filter, or similar methods (map, etc) call with (item, index, arrayItself).
55 *
56 * We had performance regressions multiple times because of forgetting about it, so here is a warning for exactly this case.
57 */
58 if (IS_DEV && isArrayMethodInlineCall(...args)) {
59 console.warn(
60 `You might be using cached computed directly as array filter function or other array method. It will break caching. Use items.filter(item => cachedFunction(item)) instead of items.filter(cachedFunction)`
61 );
62 }
63 return getComputedForArgs(...args).get();
64 }
65
66 return getValue;
67}

Callers 2

createEntityStoreFunction · 0.90
createEntityQueryFunction · 0.90

Calls 1

createDeepMapFunction · 0.90

Tested by

no test coverage detected