forked from sindresorhus/p-memoize
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
65 lines (52 loc) · 1.54 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import mimicFunction from 'mimic-fn';
import mapAgeCleaner from 'map-age-cleaner';
const cacheStore = new WeakMap();
export default function pMemoize(fn, {
cachePromiseRejection = false,
maxAge,
cacheKey,
cache = new Map(),
} = {}) {
if (Number.isSafeInteger(maxAge)) {
mapAgeCleaner(cache);
} else if (typeof maxAge !== 'undefined') {
throw new TypeError('maxAge is not a safe integer.');
}
const memoized = async function (...arguments_) {
const key = cacheKey ? cacheKey(arguments_) : arguments_[0];
const cacheItem = cache.get(key);
if (cacheItem) {
return cacheItem.data;
}
const promise = fn.apply(this, arguments_);
cache.set(key, {
data: promise,
// We cannot use `Infinity` because of https://github.com/SamVerschueren/map-age-cleaner/issues/8
maxAge: 2_147_483_647, // This is the largest number `setTimeout` can handle.
});
const [{reason}] = await Promise.allSettled([promise]);
if (!cachePromiseRejection && reason) {
cache.delete(key);
} else if (maxAge) {
// Promise fulfilled, so start the timer
cache.set(key, {
data: promise,
maxAge: Date.now() + maxAge,
});
}
return promise;
};
mimicFunction(memoized, fn);
cacheStore.set(memoized, cache);
return memoized;
}
export function pMemoizeClear(memoized) {
if (!cacheStore.has(memoized)) {
throw new Error('Cannot clear a function that was not memoized!');
}
const cache = cacheStore.get(memoized);
if (typeof cache.clear !== 'function') {
throw new TypeError('The cache Map can\'t be cleared!');
}
cache.clear();
}