huangyinfeng
2024-09-20 74a35fac4332a8b060a92c605524ed12faf2755a
提交 | 用户 | age
f57eb9 1 export interface Cache<V = any> {
V 2   value?: V;
3   timeoutId?: ReturnType<typeof setTimeout>;
4   time?: number;
5   alive?: number;
6 }
7
8 const NOT_ALIVE = 0;
9
10 export class Memory<T = any, V = any> {
11   private cache: { [key in keyof T]?: Cache<V> } = {};
12   private alive: number;
13
14   constructor(alive = NOT_ALIVE) {
15     // Unit second
16     this.alive = alive * 1000;
17   }
18
19   get getCache() {
20     return this.cache;
21   }
22
23   setCache(cache) {
24     this.cache = cache;
25   }
26
27   // get<K extends keyof T>(key: K) {
28   //   const item = this.getItem(key);
29   //   const time = item?.time;
f91d77 30   //   if (!isNil(time) && time < new Date().getTime()) {
f57eb9 31   //     this.remove(key);
V 32   //   }
33   //   return item?.value ?? undefined;
34   // }
35
36   get<K extends keyof T>(key: K) {
37     return this.cache[key];
38   }
39
40   set<K extends keyof T>(key: K, value: V, expires?: number) {
41     let item = this.get(key);
42
43     if (!expires || (expires as number) <= 0) {
44       expires = this.alive;
45     }
46     if (item) {
47       if (item.timeoutId) {
48         clearTimeout(item.timeoutId);
49         item.timeoutId = undefined;
50       }
51       item.value = value;
52     } else {
53       item = { value, alive: expires };
54       this.cache[key] = item;
55     }
56
57     if (!expires) {
58       return value;
59     }
159d90 60     const now = new Date().getTime();
0c633f 61     /**
C 62      * Prevent overflow of the setTimeout Maximum delay value
63      * Maximum delay value 2,147,483,647 ms
64      * https://developer.mozilla.org/en-US/docs/Web/API/setTimeout#maximum_delay_value
65      */
66     item.time = expires > now ? expires : now + expires;
159d90 67     item.timeoutId = setTimeout(
V 68       () => {
69         this.remove(key);
70       },
56a966 71       expires > now ? expires - now : expires,
159d90 72     );
f57eb9 73
V 74     return value;
75   }
76
77   remove<K extends keyof T>(key: K) {
78     const item = this.get(key);
79     Reflect.deleteProperty(this.cache, key);
80     if (item) {
81       clearTimeout(item.timeoutId!);
82       return item.value;
83     }
84   }
85
86   resetCache(cache: { [K in keyof T]: Cache }) {
87     Object.keys(cache).forEach((key) => {
00fca0 88       const k = key as any as keyof T;
f57eb9 89       const item = cache[k];
V 90       if (item && item.time) {
91         const now = new Date().getTime();
f6cef1 92         const expire = item.time;
f57eb9 93         if (expire > now) {
V 94           this.set(k, item.value, expire);
95         }
96       }
97     });
98   }
99
100   clear() {
101     Object.keys(this.cache).forEach((key) => {
102       const item = this.cache[key];
103       item.timeoutId && clearTimeout(item.timeoutId);
104     });
105     this.cache = {};
106   }
107 }