Merge branch 'feat/inda-383-daily-stat' into 'main'
[ProtonMail-WebClient.git] / packages / components / hooks / helpers / cachedPromise.ts
blob276efa3d5d2321b0f57fae81f55019910780e636
1 import type { Cache } from '@proton/shared/lib/helpers/cache';
3 type CacheValue<V, D> =
4     | {
5           dependency: D;
6           promise: Promise<V>;
7       }
8     | {
9           dependency: D;
10           result: V;
11       };
13 /**
14  * Cache a promise by a key, and re-run it when the dependency changes.
15  */
16 export const cachedPromise = <K, V, D>(
17     cache: Cache<K, CacheValue<V, D>>,
18     key: K,
19     miss: () => Promise<V>,
20     dependency: D
21 ) => {
22     const cachedValue = cache.get(key);
23     if (cachedValue) {
24         const { dependency: oldDependency } = cachedValue;
26         if (dependency === oldDependency) {
27             return 'promise' in cachedValue ? cachedValue.promise : Promise.resolve(cachedValue.result);
28         }
29     }
31     const promise = miss();
33     cache.set(key, {
34         dependency,
35         promise,
36     });
38     promise.then((result) => {
39         const cachedValue = cache.get(key);
41         if (!cachedValue) {
42             throw new Error(`Cached value for ${key} was overwritten unexpectedly`);
43         }
45         if ('promise' in cachedValue && promise !== cachedValue.promise) {
46             return result;
47         }
49         cache.set(key, {
50             dependency,
51             result,
52         });
54         return result;
55     });
57     return promise;