memory.ts
2.42 KB
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
export interface Cache<V = any> {
value?: V
timeoutId?: ReturnType<typeof setTimeout>
time?: number
alive?: number
}
const NOT_ALIVE = 0
export class Memory<T = Record<string, any>> {
private cache: { [key in keyof T]?: Cache<T[key]> } = {}
private alive: number
constructor(alive = NOT_ALIVE) {
// Unit second
this.alive = alive * 1000
}
get getCache() {
return this.cache
}
setCache(cache: { [key in keyof T]?: Cache<T[key]> }) {
this.cache = cache
}
// get<K extends keyof T>(key: K) {
// const item = this.getItem(key);
// const time = item?.time;
// if (!isNullOrUnDef(time) && time < new Date().getTime()) {
// this.remove(key);
// }
// return item?.value ?? undefined;
// }
get<K extends keyof T>(key: K) {
return this.cache[key]
}
set<K extends keyof T>(key: K, value: T[K], expires?: number) {
let item = this.get(key)
if (!expires || (expires as number) <= 0)
expires = this.alive
if (item) {
if (item.timeoutId) {
clearTimeout(item.timeoutId)
item.timeoutId = undefined
}
item.value = value
}
else {
item = { value, alive: expires }
this.cache[key] = item
}
if (!expires)
return value
const now = new Date().getTime()
/**
* Prevent overflow of the setTimeout Maximum delay value
* Maximum delay value 2,147,483,647 ms
* https://developer.mozilla.org/en-US/docs/Web/API/setTimeout#maximum_delay_value
*/
item.time = expires > now ? expires : now + expires
item.timeoutId = setTimeout(
() => {
this.remove(key)
},
expires > now ? expires - now : expires,
)
return value
}
remove<K extends keyof T>(key: K) {
const item = this.get(key)
Reflect.deleteProperty(this.cache, key)
if (item) {
clearTimeout(item.timeoutId!)
return item.value
}
}
resetCache(cache: { [K in keyof T]: Cache }) {
Object.keys(cache).forEach((key) => {
const k = key as any as keyof T
const item = cache[k]
if (item && item.time) {
const now = new Date().getTime()
const expire = item.time
if (expire > now)
this.set(k, item.value, expire)
}
})
}
clear() {
Object.keys(this.cache).forEach((key) => {
const item = this.cache[key as keyof T]
item?.timeoutId && clearTimeout(item.timeoutId)
})
this.cache = {}
}
}