@isaacs/ttlcache 1.0.3 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +48 -23
- package/package.json +28 -3
package/index.js
CHANGED
|
@@ -3,18 +3,24 @@
|
|
|
3
3
|
// Relies on the fact that integer Object keys are kept sorted,
|
|
4
4
|
// and managed very efficiently by V8.
|
|
5
5
|
|
|
6
|
-
const maybeReqPerfHooks =
|
|
6
|
+
const maybeReqPerfHooks = fallback => {
|
|
7
7
|
try {
|
|
8
8
|
return require('perf_hooks').performance
|
|
9
9
|
} catch (e) {
|
|
10
10
|
return fallback
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
|
-
const {now} = maybeReqPerfHooks(Date)
|
|
13
|
+
const { now } = maybeReqPerfHooks(Date)
|
|
14
14
|
const isPosInt = n => n && n === Math.floor(n) && n > 0 && isFinite(n)
|
|
15
15
|
|
|
16
16
|
class TTLCache {
|
|
17
|
-
constructor
|
|
17
|
+
constructor({
|
|
18
|
+
max = Infinity,
|
|
19
|
+
ttl,
|
|
20
|
+
updateAgeOnGet = false,
|
|
21
|
+
noUpdateTTL = false,
|
|
22
|
+
dispose,
|
|
23
|
+
}) {
|
|
18
24
|
// {[expirationTime]: [keys]}
|
|
19
25
|
this.expirations = Object.create(null)
|
|
20
26
|
// {key=>val}
|
|
@@ -29,8 +35,8 @@ class TTLCache {
|
|
|
29
35
|
}
|
|
30
36
|
this.ttl = ttl
|
|
31
37
|
this.max = max
|
|
32
|
-
this.updateAgeOnGet = updateAgeOnGet
|
|
33
|
-
this.noUpdateTTL = noUpdateTTL
|
|
38
|
+
this.updateAgeOnGet = updateAgeOnGet
|
|
39
|
+
this.noUpdateTTL = noUpdateTTL
|
|
34
40
|
if (dispose !== undefined) {
|
|
35
41
|
if (typeof dispose !== 'function') {
|
|
36
42
|
throw new TypeError('dispose must be function if set')
|
|
@@ -39,8 +45,9 @@ class TTLCache {
|
|
|
39
45
|
}
|
|
40
46
|
}
|
|
41
47
|
|
|
42
|
-
clear
|
|
43
|
-
const entries =
|
|
48
|
+
clear() {
|
|
49
|
+
const entries =
|
|
50
|
+
this.dispose !== TTLCache.prototype.dispose ? [...this] : []
|
|
44
51
|
this.data.clear()
|
|
45
52
|
this.expirationMap.clear()
|
|
46
53
|
this.expirations = Object.create(null)
|
|
@@ -49,13 +56,22 @@ class TTLCache {
|
|
|
49
56
|
}
|
|
50
57
|
}
|
|
51
58
|
|
|
52
|
-
set
|
|
59
|
+
set(
|
|
60
|
+
key,
|
|
61
|
+
val,
|
|
62
|
+
{
|
|
63
|
+
ttl = this.ttl,
|
|
64
|
+
noUpdateTTL = this.noUpdateTTL,
|
|
65
|
+
noDisposeOnSet = this.noDisposeOnSet,
|
|
66
|
+
} = {}
|
|
67
|
+
) {
|
|
53
68
|
if (!isPosInt(ttl)) {
|
|
54
69
|
throw new TypeError('ttl must be positive integer')
|
|
55
70
|
}
|
|
56
71
|
const current = this.expirationMap.get(key)
|
|
57
72
|
const time = now()
|
|
58
|
-
const oldValue =
|
|
73
|
+
const oldValue =
|
|
74
|
+
current === undefined ? undefined : this.data.get(key)
|
|
59
75
|
if (current !== undefined) {
|
|
60
76
|
// we aren't updating the ttl, so just set the data
|
|
61
77
|
if (noUpdateTTL && current > time) {
|
|
@@ -98,26 +114,35 @@ class TTLCache {
|
|
|
98
114
|
return this
|
|
99
115
|
}
|
|
100
116
|
|
|
101
|
-
has
|
|
117
|
+
has(key) {
|
|
102
118
|
return this.data.has(key)
|
|
103
119
|
}
|
|
104
120
|
|
|
105
|
-
getRemainingTTL
|
|
121
|
+
getRemainingTTL(key) {
|
|
106
122
|
const expiration = this.expirationMap.get(key)
|
|
107
|
-
return expiration !== undefined
|
|
123
|
+
return expiration !== undefined
|
|
124
|
+
? Math.max(0, expiration - now())
|
|
125
|
+
: 0
|
|
108
126
|
}
|
|
109
127
|
|
|
110
|
-
get
|
|
128
|
+
get(
|
|
129
|
+
key,
|
|
130
|
+
{ updateAgeOnGet = this.updateAgeOnGet, ttl = this.ttl } = {}
|
|
131
|
+
) {
|
|
111
132
|
const val = this.data.get(key)
|
|
112
133
|
if (updateAgeOnGet) {
|
|
113
|
-
this.set(key, val, {
|
|
134
|
+
this.set(key, val, {
|
|
135
|
+
noUpdateTTL: false,
|
|
136
|
+
noDisposeOnSet: true,
|
|
137
|
+
ttl,
|
|
138
|
+
})
|
|
114
139
|
}
|
|
115
140
|
return val
|
|
116
141
|
}
|
|
117
142
|
|
|
118
|
-
dispose
|
|
143
|
+
dispose(_, __) {}
|
|
119
144
|
|
|
120
|
-
delete
|
|
145
|
+
delete(key) {
|
|
121
146
|
const current = this.expirationMap.get(key)
|
|
122
147
|
if (current !== undefined) {
|
|
123
148
|
const value = this.data.get(key)
|
|
@@ -135,7 +160,7 @@ class TTLCache {
|
|
|
135
160
|
return false
|
|
136
161
|
}
|
|
137
162
|
|
|
138
|
-
purgeToCapacity
|
|
163
|
+
purgeToCapacity() {
|
|
139
164
|
for (const exp in this.expirations) {
|
|
140
165
|
const keys = this.expirations[exp]
|
|
141
166
|
if (this.size - keys.length >= this.max) {
|
|
@@ -159,11 +184,11 @@ class TTLCache {
|
|
|
159
184
|
}
|
|
160
185
|
}
|
|
161
186
|
|
|
162
|
-
get size
|
|
187
|
+
get size() {
|
|
163
188
|
return this.data.size
|
|
164
189
|
}
|
|
165
190
|
|
|
166
|
-
purgeStale
|
|
191
|
+
purgeStale() {
|
|
167
192
|
const n = now()
|
|
168
193
|
for (const exp in this.expirations) {
|
|
169
194
|
if (exp > n) {
|
|
@@ -179,28 +204,28 @@ class TTLCache {
|
|
|
179
204
|
}
|
|
180
205
|
}
|
|
181
206
|
|
|
182
|
-
*entries
|
|
207
|
+
*entries() {
|
|
183
208
|
for (const exp in this.expirations) {
|
|
184
209
|
for (const key of this.expirations[exp]) {
|
|
185
210
|
yield [key, this.data.get(key)]
|
|
186
211
|
}
|
|
187
212
|
}
|
|
188
213
|
}
|
|
189
|
-
*keys
|
|
214
|
+
*keys() {
|
|
190
215
|
for (const exp in this.expirations) {
|
|
191
216
|
for (const key of this.expirations[exp]) {
|
|
192
217
|
yield key
|
|
193
218
|
}
|
|
194
219
|
}
|
|
195
220
|
}
|
|
196
|
-
*values
|
|
221
|
+
*values() {
|
|
197
222
|
for (const exp in this.expirations) {
|
|
198
223
|
for (const key of this.expirations[exp]) {
|
|
199
224
|
yield this.data.get(key)
|
|
200
225
|
}
|
|
201
226
|
}
|
|
202
227
|
}
|
|
203
|
-
[Symbol.iterator]
|
|
228
|
+
[Symbol.iterator]() {
|
|
204
229
|
return this.entries()
|
|
205
230
|
}
|
|
206
231
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@isaacs/ttlcache",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"files": [
|
|
5
5
|
"index.js"
|
|
6
6
|
],
|
|
@@ -23,10 +23,35 @@
|
|
|
23
23
|
"prepublishOnly": "git push origin --follow-tags"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
|
-
"
|
|
27
|
-
"tap": "^
|
|
26
|
+
"@types/node": "^17.0.42",
|
|
27
|
+
"@types/tap": "^15.0.7",
|
|
28
|
+
"clock-mock": "^1.0.6",
|
|
29
|
+
"prettier": "^2.7.0",
|
|
30
|
+
"tap": "^16.0.1",
|
|
31
|
+
"ts-node": "^10.8.1"
|
|
28
32
|
},
|
|
29
33
|
"engines": {
|
|
30
34
|
"node": ">=12"
|
|
35
|
+
},
|
|
36
|
+
"tap": {
|
|
37
|
+
"nyc-arg": [
|
|
38
|
+
"--include=index.js"
|
|
39
|
+
],
|
|
40
|
+
"node-arg": [
|
|
41
|
+
"--require",
|
|
42
|
+
"ts-node/register"
|
|
43
|
+
],
|
|
44
|
+
"ts": false
|
|
45
|
+
},
|
|
46
|
+
"prettier": {
|
|
47
|
+
"semi": false,
|
|
48
|
+
"printWidth": 70,
|
|
49
|
+
"tabWidth": 2,
|
|
50
|
+
"useTabs": false,
|
|
51
|
+
"singleQuote": true,
|
|
52
|
+
"jsxSingleQuote": false,
|
|
53
|
+
"bracketSameLine": true,
|
|
54
|
+
"arrowParens": "avoid",
|
|
55
|
+
"endOfLine": "lf"
|
|
31
56
|
}
|
|
32
57
|
}
|