@isaacs/ttlcache 1.2.2 → 1.3.0
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/README.md +18 -3
- package/index.d.ts +7 -0
- package/index.js +44 -15
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -53,9 +53,9 @@ where the `setTimeout` method does not return an object with an
|
|
|
53
53
|
`unref()` method, the process will stay open as long as any
|
|
54
54
|
unexpired entry exists in the cache.
|
|
55
55
|
|
|
56
|
-
You may
|
|
57
|
-
|
|
58
|
-
|
|
56
|
+
You may call `cache.cancelTimer()` to clear the timeout and
|
|
57
|
+
allow the process to exit normally. Be advised that canceling the
|
|
58
|
+
timer in this way will of course prevent anything from expiring.
|
|
59
59
|
|
|
60
60
|
## API
|
|
61
61
|
|
|
@@ -164,6 +164,14 @@ latest expiring.
|
|
|
164
164
|
Return an iterator that walks through each `value` from soonest expiring to
|
|
165
165
|
latest expiring.
|
|
166
166
|
|
|
167
|
+
### `cache.cancelTimer()`
|
|
168
|
+
|
|
169
|
+
Clear the internal timer, and stop automatically expiring items
|
|
170
|
+
when their TTL expires.
|
|
171
|
+
|
|
172
|
+
This allows the process to exit normally on Deno and other
|
|
173
|
+
platforms that lack Node's `Timer.unref()` method.
|
|
174
|
+
|
|
167
175
|
## Internal Methods
|
|
168
176
|
|
|
169
177
|
You should not ever call these, they are managed automatically.
|
|
@@ -188,6 +196,13 @@ automatically.
|
|
|
188
196
|
Called when an item is removed from the cache and should be disposed. Set
|
|
189
197
|
this on the constructor options.
|
|
190
198
|
|
|
199
|
+
### `setTimer`
|
|
200
|
+
|
|
201
|
+
**Internal**
|
|
202
|
+
|
|
203
|
+
Called when an with a ttl is added. This ensures that only one timer
|
|
204
|
+
is setup at once. Called automatically.
|
|
205
|
+
|
|
191
206
|
## Algorithm
|
|
192
207
|
|
|
193
208
|
The cache uses two `Map` objects. The first maps item keys to their
|
package/index.d.ts
CHANGED
|
@@ -86,6 +86,13 @@ declare class TTLCache<K, V> implements Iterable<[K, V]> {
|
|
|
86
86
|
* `cache.entries()`
|
|
87
87
|
*/
|
|
88
88
|
public [Symbol.iterator](): Iterator<[K, V]>
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Cancel the timer and stop automatically expiring entries.
|
|
92
|
+
* This allows the process to gracefully exit where Timer.unref()
|
|
93
|
+
* is not available.
|
|
94
|
+
*/
|
|
95
|
+
public cancelTimer(): void
|
|
89
96
|
}
|
|
90
97
|
|
|
91
98
|
declare namespace TTLCache {
|
package/index.js
CHANGED
|
@@ -50,19 +50,54 @@ class TTLCache {
|
|
|
50
50
|
this.dispose = dispose
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
this.
|
|
53
|
+
this.timer = undefined
|
|
54
|
+
this.timerExpiration = undefined
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
setTimer (expiration, ttl) {
|
|
58
|
+
if (this.timerExpiration < expiration) {
|
|
59
|
+
return
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (this.timer) {
|
|
63
|
+
clearTimeout(this.timer)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const t = setTimeout(() => {
|
|
67
|
+
this.timer = undefined
|
|
68
|
+
this.timerExpiration = undefined
|
|
69
|
+
this.purgeStale()
|
|
70
|
+
for (const exp in this.expirations) {
|
|
71
|
+
this.setTimer(exp, exp - now())
|
|
72
|
+
break
|
|
73
|
+
}
|
|
74
|
+
}, ttl)
|
|
75
|
+
|
|
76
|
+
/* istanbul ignore else - affordance for non-node envs */
|
|
77
|
+
if (t.unref) t.unref()
|
|
78
|
+
|
|
79
|
+
this.timerExpiration = expiration
|
|
80
|
+
this.timer = t
|
|
54
81
|
}
|
|
55
82
|
|
|
56
83
|
// hang onto the timer so we can clearTimeout if all items
|
|
57
84
|
// are deleted. Deno doesn't have Timer.unref(), so it
|
|
58
85
|
// hangs otherwise.
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
clearTimeout(
|
|
62
|
-
this.
|
|
86
|
+
cancelTimer() {
|
|
87
|
+
if (this.timer) {
|
|
88
|
+
clearTimeout(this.timer)
|
|
89
|
+
this.timerExpiration = undefined
|
|
90
|
+
this.timer = undefined
|
|
63
91
|
}
|
|
64
92
|
}
|
|
65
93
|
|
|
94
|
+
/* istanbul ignore next */
|
|
95
|
+
cancelTimers() {
|
|
96
|
+
process.emitWarning('TTLCache.cancelTimers has been renamed to ' +
|
|
97
|
+
'TTLCache.cancelTimer (no "s"), and will be removed in the next ' +
|
|
98
|
+
'major version update')
|
|
99
|
+
return this.cancelTimer()
|
|
100
|
+
}
|
|
66
101
|
|
|
67
102
|
clear() {
|
|
68
103
|
const entries =
|
|
@@ -70,7 +105,7 @@ class TTLCache {
|
|
|
70
105
|
this.data.clear()
|
|
71
106
|
this.expirationMap.clear()
|
|
72
107
|
// no need for any purging now
|
|
73
|
-
this.
|
|
108
|
+
this.cancelTimer()
|
|
74
109
|
this.expirations = Object.create(null)
|
|
75
110
|
for (const [key, val] of entries) {
|
|
76
111
|
this.dispose(val, key, 'delete')
|
|
@@ -93,14 +128,8 @@ class TTLCache {
|
|
|
93
128
|
const expiration = Math.floor(now() + ttl)
|
|
94
129
|
this.expirationMap.set(key, expiration)
|
|
95
130
|
if (!this.expirations[expiration]) {
|
|
96
|
-
const t = setTimeout(() => {
|
|
97
|
-
this.timers.delete(t)
|
|
98
|
-
this.purgeStale()
|
|
99
|
-
}, ttl)
|
|
100
|
-
/* istanbul ignore else - affordance for non-node envs */
|
|
101
|
-
if (t.unref) t.unref()
|
|
102
|
-
this.timers.add(t)
|
|
103
131
|
this.expirations[expiration] = []
|
|
132
|
+
this.setTimer(expiration, ttl)
|
|
104
133
|
}
|
|
105
134
|
this.expirations[expiration].push(key)
|
|
106
135
|
} else {
|
|
@@ -186,7 +215,7 @@ class TTLCache {
|
|
|
186
215
|
}
|
|
187
216
|
this.dispose(value, key, 'delete')
|
|
188
217
|
if (this.size === 0) {
|
|
189
|
-
this.
|
|
218
|
+
this.cancelTimer()
|
|
190
219
|
}
|
|
191
220
|
return true
|
|
192
221
|
}
|
|
@@ -246,7 +275,7 @@ class TTLCache {
|
|
|
246
275
|
}
|
|
247
276
|
}
|
|
248
277
|
if (this.size === 0) {
|
|
249
|
-
this.
|
|
278
|
+
this.cancelTimer()
|
|
250
279
|
}
|
|
251
280
|
}
|
|
252
281
|
|