@isaacs/ttlcache 1.4.1 → 2.0.1
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/LICENSE.md +55 -0
- package/README.md +37 -38
- package/dist/commonjs/index.d.ts +46 -0
- package/dist/commonjs/index.d.ts.map +1 -0
- package/dist/commonjs/index.js +290 -0
- package/dist/commonjs/index.js.map +1 -0
- package/dist/commonjs/package.json +3 -0
- package/dist/esm/index.d.ts +46 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +286 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/package.json +3 -0
- package/package.json +42 -24
- package/LICENSE +0 -15
- package/index.d.ts +0 -231
- package/index.js +0 -324
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export type DisposeReason = 'set' | 'delete' | 'stale' | 'evict';
|
|
2
|
+
export type DisposeFunction<K, V> = (val: V, key: K, reason: DisposeReason) => unknown;
|
|
3
|
+
export type TTLCacheOptions<K, V> = {
|
|
4
|
+
max?: number;
|
|
5
|
+
ttl?: number;
|
|
6
|
+
updateAgeOnGet?: boolean;
|
|
7
|
+
checkAgeOnGet?: boolean;
|
|
8
|
+
noUpdateTTL?: boolean;
|
|
9
|
+
dispose?: DisposeFunction<K, V>;
|
|
10
|
+
noDisposeOnSet?: boolean;
|
|
11
|
+
};
|
|
12
|
+
export type SetOptions<K, V> = Pick<TTLCacheOptions<K, V>, 'ttl' | 'noUpdateTTL' | 'noDisposeOnSet'>;
|
|
13
|
+
export type GetOptions<K, V> = Pick<TTLCacheOptions<K, V>, 'updateAgeOnGet' | 'ttl' | 'checkAgeOnGet'>;
|
|
14
|
+
export declare class TTLCache<K = unknown, V = unknown> {
|
|
15
|
+
expirations: Record<number, K[]>;
|
|
16
|
+
data: Map<K, V>;
|
|
17
|
+
expirationMap: Map<K, number>;
|
|
18
|
+
ttl?: number;
|
|
19
|
+
max: number;
|
|
20
|
+
updateAgeOnGet: boolean;
|
|
21
|
+
noUpdateTTL: boolean;
|
|
22
|
+
noDisposeOnSet: boolean;
|
|
23
|
+
checkAgeOnGet: boolean;
|
|
24
|
+
dispose: DisposeFunction<K, V>;
|
|
25
|
+
timer?: ReturnType<typeof setTimeout>;
|
|
26
|
+
timerExpiration?: number;
|
|
27
|
+
constructor({ max, ttl, updateAgeOnGet, checkAgeOnGet, noUpdateTTL, dispose, noDisposeOnSet, }?: TTLCacheOptions<K, V>);
|
|
28
|
+
setTimer(expiration: number, ttl: number): void;
|
|
29
|
+
cancelTimer(): void;
|
|
30
|
+
cancelTimers(): void;
|
|
31
|
+
clear(): void;
|
|
32
|
+
setTTL(key: K, ttl?: number | undefined): void;
|
|
33
|
+
set(key: K, val: V, { ttl, noUpdateTTL, noDisposeOnSet, }?: SetOptions<K, V>): this;
|
|
34
|
+
has(key: K): boolean;
|
|
35
|
+
getRemainingTTL(key: K): number;
|
|
36
|
+
get(key: K, { updateAgeOnGet, ttl, checkAgeOnGet, }?: GetOptions<K, V>): V | undefined;
|
|
37
|
+
delete(key: K): boolean;
|
|
38
|
+
purgeToCapacity(): void;
|
|
39
|
+
get size(): number;
|
|
40
|
+
purgeStale(): void;
|
|
41
|
+
entries(): Generator<[K, V], void, unknown>;
|
|
42
|
+
keys(): Generator<K, void, unknown>;
|
|
43
|
+
values(): Generator<V, void, unknown>;
|
|
44
|
+
[Symbol.iterator](): Generator<[K, V], void, unknown>;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAoBA,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,QAAQ,GAAG,OAAO,GAAG,OAAO,CAAA;AAEhE,MAAM,MAAM,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAClC,GAAG,EAAE,CAAC,EACN,GAAG,EAAE,CAAC,EACN,MAAM,EAAE,aAAa,KAClB,OAAO,CAAA;AAEZ,MAAM,MAAM,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI;IAClC,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,OAAO,CAAC,EAAE,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;IAC/B,cAAc,CAAC,EAAE,OAAO,CAAA;CACzB,CAAA;AAED,MAAM,MAAM,UAAU,CAAC,CAAC,EAAE,CAAC,IAAI,IAAI,CACjC,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,EACrB,KAAK,GAAG,aAAa,GAAG,gBAAgB,CACzC,CAAA;AACD,MAAM,MAAM,UAAU,CAAC,CAAC,EAAE,CAAC,IAAI,IAAI,CACjC,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,EACrB,gBAAgB,GAAG,KAAK,GAAG,eAAe,CAC3C,CAAA;AAED,qBAAa,QAAQ,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO;IAC5C,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAAsB;IACtD,IAAI,YAAkB;IACtB,aAAa,iBAAuB;IACpC,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,MAAM,CAAA;IACX,cAAc,EAAE,OAAO,CAAA;IACvB,WAAW,EAAE,OAAO,CAAA;IACpB,cAAc,EAAE,OAAO,CAAA;IACvB,aAAa,EAAE,OAAO,CAAA;IACtB,OAAO,EAAE,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;IAC9B,KAAK,CAAC,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,CAAA;IACrC,eAAe,CAAC,EAAE,MAAM,CAAA;gBAEZ,EACV,GAAc,EACd,GAAG,EACH,cAAsB,EACtB,aAAqB,EACrB,WAAmB,EACnB,OAAO,EACP,cAAsB,GACvB,GAAE,eAAe,CAAC,CAAC,EAAE,CAAC,CAAM;IA4B7B,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM;IA+BxC,WAAW;IASX,YAAY;IAUZ,KAAK;IAaL,MAAM,CAAC,GAAG,EAAE,CAAC,EAAE,GAAG,qBAAW;IAyB7B,GAAG,CACD,GAAG,EAAE,CAAC,EACN,GAAG,EAAE,CAAC,EACN,EACE,GAAc,EACd,WAA8B,EAC9B,cAAoC,GACrC,GAAE,UAAU,CAAC,CAAC,EAAE,CAAC,CAAM;IA6B1B,GAAG,CAAC,GAAG,EAAE,CAAC;IAIV,eAAe,CAAC,GAAG,EAAE,CAAC;IAStB,GAAG,CACD,GAAG,EAAE,CAAC,EACN,EACE,cAAoC,EACpC,GAAc,EACd,aAAkC,GACnC,GAAE,UAAU,CAAC,CAAC,EAAE,CAAC,CAAM;IAa1B,MAAM,CAAC,GAAG,EAAE,CAAC;IAuBb,eAAe;IA8Bf,IAAI,IAAI,WAEP;IAED,UAAU;IA4BT,OAAO;IAOP,IAAI;IAOJ,MAAM;IAOP,CAAC,MAAM,CAAC,QAAQ,CAAC;CAGlB"}
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
// A simple TTL cache with max capacity option, ms resolution,
|
|
2
|
+
// autopurge, and reasonably optimized performance
|
|
3
|
+
// Relies on the fact that integer Object keys are kept sorted,
|
|
4
|
+
// and managed very efficiently by V8.
|
|
5
|
+
/* c8 ignore start */
|
|
6
|
+
const perf = typeof performance === 'object' &&
|
|
7
|
+
performance &&
|
|
8
|
+
typeof performance.now === 'function'
|
|
9
|
+
? performance
|
|
10
|
+
: Date;
|
|
11
|
+
/* c8 ignore stop */
|
|
12
|
+
const now = () => perf.now();
|
|
13
|
+
const isPosInt = (n) => !!n && n === Math.floor(n) && n > 0 && isFinite(n);
|
|
14
|
+
const isPosIntOrInf = (n) => n === Infinity || isPosInt(n);
|
|
15
|
+
export class TTLCache {
|
|
16
|
+
expirations = Object.create(null);
|
|
17
|
+
data = new Map();
|
|
18
|
+
expirationMap = new Map();
|
|
19
|
+
ttl;
|
|
20
|
+
max;
|
|
21
|
+
updateAgeOnGet;
|
|
22
|
+
noUpdateTTL;
|
|
23
|
+
noDisposeOnSet;
|
|
24
|
+
checkAgeOnGet;
|
|
25
|
+
dispose;
|
|
26
|
+
timer;
|
|
27
|
+
timerExpiration;
|
|
28
|
+
constructor({ max = Infinity, ttl, updateAgeOnGet = false, checkAgeOnGet = false, noUpdateTTL = false, dispose, noDisposeOnSet = false, } = {}) {
|
|
29
|
+
if (ttl !== undefined && !isPosIntOrInf(ttl)) {
|
|
30
|
+
throw new TypeError('ttl must be positive integer or Infinity if set');
|
|
31
|
+
}
|
|
32
|
+
if (!isPosIntOrInf(max)) {
|
|
33
|
+
throw new TypeError('max must be positive integer or Infinity');
|
|
34
|
+
}
|
|
35
|
+
this.ttl = ttl;
|
|
36
|
+
this.max = max;
|
|
37
|
+
this.updateAgeOnGet = !!updateAgeOnGet;
|
|
38
|
+
this.checkAgeOnGet = !!checkAgeOnGet;
|
|
39
|
+
this.noUpdateTTL = !!noUpdateTTL;
|
|
40
|
+
this.noDisposeOnSet = !!noDisposeOnSet;
|
|
41
|
+
if (dispose !== undefined) {
|
|
42
|
+
if (typeof dispose !== 'function') {
|
|
43
|
+
throw new TypeError('dispose must be function if set');
|
|
44
|
+
}
|
|
45
|
+
this.dispose = dispose;
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
this.dispose = (_, __, ___) => { };
|
|
49
|
+
}
|
|
50
|
+
this.timer = undefined;
|
|
51
|
+
this.timerExpiration = undefined;
|
|
52
|
+
}
|
|
53
|
+
setTimer(expiration, ttl) {
|
|
54
|
+
if (this.timerExpiration && this.timerExpiration < expiration) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
if (this.timer) {
|
|
58
|
+
clearTimeout(this.timer);
|
|
59
|
+
}
|
|
60
|
+
const t = setTimeout(() => {
|
|
61
|
+
this.timer = undefined;
|
|
62
|
+
this.timerExpiration = undefined;
|
|
63
|
+
this.purgeStale();
|
|
64
|
+
for (const exp in this.expirations) {
|
|
65
|
+
const e = Number(exp);
|
|
66
|
+
this.setTimer(e, e - now());
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
}, ttl);
|
|
70
|
+
/* c8 ignore start - affordance for non-node envs */
|
|
71
|
+
if (t.unref)
|
|
72
|
+
t.unref();
|
|
73
|
+
/* c8 ignore stop */
|
|
74
|
+
this.timerExpiration = expiration;
|
|
75
|
+
this.timer = t;
|
|
76
|
+
}
|
|
77
|
+
// hang onto the timer so we can clearTimeout if all items
|
|
78
|
+
// are deleted. Deno doesn't have Timer.unref(), so it
|
|
79
|
+
// hangs otherwise.
|
|
80
|
+
cancelTimer() {
|
|
81
|
+
if (this.timer) {
|
|
82
|
+
clearTimeout(this.timer);
|
|
83
|
+
this.timerExpiration = undefined;
|
|
84
|
+
this.timer = undefined;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/* c8 ignore start */
|
|
88
|
+
cancelTimers() {
|
|
89
|
+
process.emitWarning('TTLCache.cancelTimers has been renamed to ' +
|
|
90
|
+
'TTLCache.cancelTimer (no "s"), and will be removed in the next ' +
|
|
91
|
+
'major version update');
|
|
92
|
+
return this.cancelTimer();
|
|
93
|
+
}
|
|
94
|
+
/* c8 ignore stop */
|
|
95
|
+
clear() {
|
|
96
|
+
const entries = this.dispose !== TTLCache.prototype.dispose ? [...this] : [];
|
|
97
|
+
this.data.clear();
|
|
98
|
+
this.expirationMap.clear();
|
|
99
|
+
// no need for any purging now
|
|
100
|
+
this.cancelTimer();
|
|
101
|
+
this.expirations = Object.create(null);
|
|
102
|
+
for (const [key, val] of entries) {
|
|
103
|
+
this.dispose(val, key, 'delete');
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
setTTL(key, ttl = this.ttl) {
|
|
107
|
+
const current = this.expirationMap.get(key);
|
|
108
|
+
if (current !== undefined) {
|
|
109
|
+
// remove from the expirations list, so it isn't purged
|
|
110
|
+
const exp = this.expirations[current];
|
|
111
|
+
if (!exp || exp.length <= 1) {
|
|
112
|
+
delete this.expirations[current];
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
this.expirations[current] = exp.filter(k => k !== key);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
if (ttl && ttl !== Infinity) {
|
|
119
|
+
const expiration = Math.floor(now() + ttl);
|
|
120
|
+
this.expirationMap.set(key, expiration);
|
|
121
|
+
if (!this.expirations[expiration]) {
|
|
122
|
+
this.expirations[expiration] = [];
|
|
123
|
+
this.setTimer(expiration, ttl);
|
|
124
|
+
}
|
|
125
|
+
this.expirations[expiration].push(key);
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
this.expirationMap.set(key, Infinity);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
set(key, val, { ttl = this.ttl, noUpdateTTL = this.noUpdateTTL, noDisposeOnSet = this.noDisposeOnSet, } = {}) {
|
|
132
|
+
if (!isPosIntOrInf(ttl)) {
|
|
133
|
+
throw new TypeError('ttl must be positive integer or Infinity');
|
|
134
|
+
}
|
|
135
|
+
if (this.expirationMap.has(key)) {
|
|
136
|
+
if (!noUpdateTTL) {
|
|
137
|
+
this.setTTL(key, ttl);
|
|
138
|
+
}
|
|
139
|
+
// has old value
|
|
140
|
+
const oldValue = this.data.get(key);
|
|
141
|
+
if (oldValue !== undefined && oldValue !== val) {
|
|
142
|
+
this.data.set(key, val);
|
|
143
|
+
if (!noDisposeOnSet) {
|
|
144
|
+
this.dispose(oldValue, key, 'set');
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
this.setTTL(key, ttl);
|
|
150
|
+
this.data.set(key, val);
|
|
151
|
+
}
|
|
152
|
+
while (this.size > this.max) {
|
|
153
|
+
this.purgeToCapacity();
|
|
154
|
+
}
|
|
155
|
+
return this;
|
|
156
|
+
}
|
|
157
|
+
has(key) {
|
|
158
|
+
return this.data.has(key);
|
|
159
|
+
}
|
|
160
|
+
getRemainingTTL(key) {
|
|
161
|
+
const expiration = this.expirationMap.get(key);
|
|
162
|
+
return expiration === Infinity
|
|
163
|
+
? expiration
|
|
164
|
+
: expiration !== undefined
|
|
165
|
+
? Math.max(0, Math.ceil(expiration - now()))
|
|
166
|
+
: 0;
|
|
167
|
+
}
|
|
168
|
+
get(key, { updateAgeOnGet = this.updateAgeOnGet, ttl = this.ttl, checkAgeOnGet = this.checkAgeOnGet, } = {}) {
|
|
169
|
+
const val = this.data.get(key);
|
|
170
|
+
if (checkAgeOnGet && this.getRemainingTTL(key) === 0) {
|
|
171
|
+
this.delete(key);
|
|
172
|
+
return undefined;
|
|
173
|
+
}
|
|
174
|
+
if (updateAgeOnGet) {
|
|
175
|
+
this.setTTL(key, ttl);
|
|
176
|
+
}
|
|
177
|
+
return val;
|
|
178
|
+
}
|
|
179
|
+
delete(key) {
|
|
180
|
+
const current = this.expirationMap.get(key);
|
|
181
|
+
if (current !== undefined) {
|
|
182
|
+
const value = this.data.get(key);
|
|
183
|
+
this.data.delete(key);
|
|
184
|
+
this.expirationMap.delete(key);
|
|
185
|
+
const exp = this.expirations[current];
|
|
186
|
+
if (exp) {
|
|
187
|
+
if (exp.length <= 1) {
|
|
188
|
+
delete this.expirations[current];
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
this.expirations[current] = exp.filter(k => k !== key);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
this.dispose(value, key, 'delete');
|
|
195
|
+
if (this.size === 0) {
|
|
196
|
+
this.cancelTimer();
|
|
197
|
+
}
|
|
198
|
+
return true;
|
|
199
|
+
}
|
|
200
|
+
return false;
|
|
201
|
+
}
|
|
202
|
+
purgeToCapacity() {
|
|
203
|
+
for (const exp in this.expirations) {
|
|
204
|
+
const keys = this.expirations[exp];
|
|
205
|
+
if (this.size - keys.length >= this.max) {
|
|
206
|
+
delete this.expirations[exp];
|
|
207
|
+
const entries = [];
|
|
208
|
+
for (const key of keys) {
|
|
209
|
+
entries.push([key, this.data.get(key)]);
|
|
210
|
+
this.data.delete(key);
|
|
211
|
+
this.expirationMap.delete(key);
|
|
212
|
+
}
|
|
213
|
+
for (const [key, val] of entries) {
|
|
214
|
+
this.dispose(val, key, 'evict');
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
const s = this.size - this.max;
|
|
219
|
+
const entries = [];
|
|
220
|
+
for (const key of keys.splice(0, s)) {
|
|
221
|
+
entries.push([key, this.data.get(key)]);
|
|
222
|
+
this.data.delete(key);
|
|
223
|
+
this.expirationMap.delete(key);
|
|
224
|
+
}
|
|
225
|
+
for (const [key, val] of entries) {
|
|
226
|
+
this.dispose(val, key, 'evict');
|
|
227
|
+
}
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
get size() {
|
|
233
|
+
return this.data.size;
|
|
234
|
+
}
|
|
235
|
+
purgeStale() {
|
|
236
|
+
const n = Math.ceil(now());
|
|
237
|
+
for (const exp in this.expirations) {
|
|
238
|
+
if (exp === 'Infinity' || Number(exp) > n) {
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
/* c8 ignore start
|
|
242
|
+
* mysterious need for a guard here?
|
|
243
|
+
* https://github.com/isaacs/ttlcache/issues/26 */
|
|
244
|
+
const keys = [...(this.expirations[exp] || [])];
|
|
245
|
+
/* c8 ignore stop */
|
|
246
|
+
const entries = [];
|
|
247
|
+
delete this.expirations[exp];
|
|
248
|
+
for (const key of keys) {
|
|
249
|
+
entries.push([key, this.data.get(key)]);
|
|
250
|
+
this.data.delete(key);
|
|
251
|
+
this.expirationMap.delete(key);
|
|
252
|
+
}
|
|
253
|
+
for (const [key, val] of entries) {
|
|
254
|
+
this.dispose(val, key, 'stale');
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
if (this.size === 0) {
|
|
258
|
+
this.cancelTimer();
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
*entries() {
|
|
262
|
+
for (const exp in this.expirations) {
|
|
263
|
+
for (const key of this.expirations[exp]) {
|
|
264
|
+
yield [key, this.data.get(key)];
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
*keys() {
|
|
269
|
+
for (const exp in this.expirations) {
|
|
270
|
+
for (const key of this.expirations[exp]) {
|
|
271
|
+
yield key;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
*values() {
|
|
276
|
+
for (const exp in this.expirations) {
|
|
277
|
+
for (const key of this.expirations[exp]) {
|
|
278
|
+
yield this.data.get(key);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
[Symbol.iterator]() {
|
|
283
|
+
return this.entries();
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["// A simple TTL cache with max capacity option, ms resolution,\n// autopurge, and reasonably optimized performance\n// Relies on the fact that integer Object keys are kept sorted,\n// and managed very efficiently by V8.\n\n/* c8 ignore start */\nconst perf =\n typeof performance === 'object' &&\n performance &&\n typeof performance.now === 'function'\n ? performance\n : Date\n/* c8 ignore stop */\n\nconst now = () => perf.now()\nconst isPosInt = (n: any): n is number =>\n !!n && n === Math.floor(n) && n > 0 && isFinite(n)\nconst isPosIntOrInf = (n: any): n is number =>\n n === Infinity || isPosInt(n)\n\nexport type DisposeReason = 'set' | 'delete' | 'stale' | 'evict'\n\nexport type DisposeFunction<K, V> = (\n val: V,\n key: K,\n reason: DisposeReason,\n) => unknown\n\nexport type TTLCacheOptions<K, V> = {\n max?: number\n ttl?: number\n updateAgeOnGet?: boolean\n checkAgeOnGet?: boolean\n noUpdateTTL?: boolean\n dispose?: DisposeFunction<K, V>\n noDisposeOnSet?: boolean\n}\n\nexport type SetOptions<K, V> = Pick<\n TTLCacheOptions<K, V>,\n 'ttl' | 'noUpdateTTL' | 'noDisposeOnSet'\n>\nexport type GetOptions<K, V> = Pick<\n TTLCacheOptions<K, V>,\n 'updateAgeOnGet' | 'ttl' | 'checkAgeOnGet'\n>\n\nexport class TTLCache<K = unknown, V = unknown> {\n expirations: Record<number, K[]> = Object.create(null)\n data = new Map<K, V>()\n expirationMap = new Map<K, number>()\n ttl?: number\n max: number\n updateAgeOnGet: boolean\n noUpdateTTL: boolean\n noDisposeOnSet: boolean\n checkAgeOnGet: boolean\n dispose: DisposeFunction<K, V>\n timer?: ReturnType<typeof setTimeout>\n timerExpiration?: number\n\n constructor({\n max = Infinity,\n ttl,\n updateAgeOnGet = false,\n checkAgeOnGet = false,\n noUpdateTTL = false,\n dispose,\n noDisposeOnSet = false,\n }: TTLCacheOptions<K, V> = {}) {\n if (ttl !== undefined && !isPosIntOrInf(ttl)) {\n throw new TypeError(\n 'ttl must be positive integer or Infinity if set',\n )\n }\n if (!isPosIntOrInf(max)) {\n throw new TypeError('max must be positive integer or Infinity')\n }\n this.ttl = ttl\n this.max = max\n this.updateAgeOnGet = !!updateAgeOnGet\n this.checkAgeOnGet = !!checkAgeOnGet\n this.noUpdateTTL = !!noUpdateTTL\n this.noDisposeOnSet = !!noDisposeOnSet\n if (dispose !== undefined) {\n if (typeof dispose !== 'function') {\n throw new TypeError('dispose must be function if set')\n }\n this.dispose = dispose\n } else {\n this.dispose = (_, __, ___) => {}\n }\n\n this.timer = undefined\n this.timerExpiration = undefined\n }\n\n setTimer(expiration: number, ttl: number) {\n if (this.timerExpiration && this.timerExpiration < expiration) {\n return\n }\n\n if (this.timer) {\n clearTimeout(this.timer)\n }\n\n const t = setTimeout(() => {\n this.timer = undefined\n this.timerExpiration = undefined\n this.purgeStale()\n for (const exp in this.expirations) {\n const e = Number(exp)\n this.setTimer(e, e - now())\n break\n }\n }, ttl)\n\n /* c8 ignore start - affordance for non-node envs */\n if (t.unref) t.unref()\n /* c8 ignore stop */\n\n this.timerExpiration = expiration\n this.timer = t\n }\n\n // hang onto the timer so we can clearTimeout if all items\n // are deleted. Deno doesn't have Timer.unref(), so it\n // hangs otherwise.\n cancelTimer() {\n if (this.timer) {\n clearTimeout(this.timer)\n this.timerExpiration = undefined\n this.timer = undefined\n }\n }\n\n /* c8 ignore start */\n cancelTimers() {\n process.emitWarning(\n 'TTLCache.cancelTimers has been renamed to ' +\n 'TTLCache.cancelTimer (no \"s\"), and will be removed in the next ' +\n 'major version update',\n )\n return this.cancelTimer()\n }\n /* c8 ignore stop */\n\n clear() {\n const entries =\n this.dispose !== TTLCache.prototype.dispose ? [...this] : []\n this.data.clear()\n this.expirationMap.clear()\n // no need for any purging now\n this.cancelTimer()\n this.expirations = Object.create(null)\n for (const [key, val] of entries as [K, V][]) {\n this.dispose(val, key, 'delete')\n }\n }\n\n setTTL(key: K, ttl = this.ttl) {\n const current = this.expirationMap.get(key)\n if (current !== undefined) {\n // remove from the expirations list, so it isn't purged\n const exp = this.expirations[current]\n if (!exp || exp.length <= 1) {\n delete this.expirations[current]\n } else {\n this.expirations[current] = exp.filter(k => k !== key)\n }\n }\n\n if (ttl && ttl !== Infinity) {\n const expiration = Math.floor(now() + ttl)\n this.expirationMap.set(key, expiration)\n if (!this.expirations[expiration]) {\n this.expirations[expiration] = []\n this.setTimer(expiration, ttl)\n }\n this.expirations[expiration].push(key)\n } else {\n this.expirationMap.set(key, Infinity)\n }\n }\n\n set(\n key: K,\n val: V,\n {\n ttl = this.ttl,\n noUpdateTTL = this.noUpdateTTL,\n noDisposeOnSet = this.noDisposeOnSet,\n }: SetOptions<K, V> = {},\n ) {\n if (!isPosIntOrInf(ttl)) {\n throw new TypeError('ttl must be positive integer or Infinity')\n }\n if (this.expirationMap.has(key)) {\n if (!noUpdateTTL) {\n this.setTTL(key, ttl)\n }\n // has old value\n const oldValue = this.data.get(key)\n if (oldValue !== undefined && oldValue !== val) {\n this.data.set(key, val)\n if (!noDisposeOnSet) {\n this.dispose(oldValue, key, 'set')\n }\n }\n } else {\n this.setTTL(key, ttl)\n this.data.set(key, val)\n }\n\n while (this.size > this.max) {\n this.purgeToCapacity()\n }\n\n return this\n }\n\n has(key: K) {\n return this.data.has(key)\n }\n\n getRemainingTTL(key: K) {\n const expiration = this.expirationMap.get(key)\n return expiration === Infinity\n ? expiration\n : expiration !== undefined\n ? Math.max(0, Math.ceil(expiration - now()))\n : 0\n }\n\n get(\n key: K,\n {\n updateAgeOnGet = this.updateAgeOnGet,\n ttl = this.ttl,\n checkAgeOnGet = this.checkAgeOnGet,\n }: GetOptions<K, V> = {},\n ) {\n const val = this.data.get(key)\n if (checkAgeOnGet && this.getRemainingTTL(key) === 0) {\n this.delete(key)\n return undefined\n }\n if (updateAgeOnGet) {\n this.setTTL(key, ttl)\n }\n return val\n }\n\n delete(key: K) {\n const current = this.expirationMap.get(key)\n if (current !== undefined) {\n const value = this.data.get(key) as V\n this.data.delete(key)\n this.expirationMap.delete(key)\n const exp = this.expirations[current]\n if (exp) {\n if (exp.length <= 1) {\n delete this.expirations[current]\n } else {\n this.expirations[current] = exp.filter(k => k !== key)\n }\n }\n this.dispose(value, key, 'delete')\n if (this.size === 0) {\n this.cancelTimer()\n }\n return true\n }\n return false\n }\n\n purgeToCapacity() {\n for (const exp in this.expirations) {\n const keys = this.expirations[exp] as K[]\n if (this.size - keys.length >= this.max) {\n delete this.expirations[exp]\n const entries: [K, V][] = []\n for (const key of keys) {\n entries.push([key, this.data.get(key) as V])\n this.data.delete(key)\n this.expirationMap.delete(key)\n }\n for (const [key, val] of entries) {\n this.dispose(val, key, 'evict')\n }\n } else {\n const s = this.size - this.max\n const entries: [K, V][] = []\n for (const key of keys.splice(0, s)) {\n entries.push([key, this.data.get(key) as V])\n this.data.delete(key)\n this.expirationMap.delete(key)\n }\n for (const [key, val] of entries) {\n this.dispose(val, key, 'evict')\n }\n return\n }\n }\n }\n\n get size() {\n return this.data.size\n }\n\n purgeStale() {\n const n = Math.ceil(now())\n for (const exp in this.expirations) {\n if (exp === 'Infinity' || Number(exp) > n) {\n return\n }\n\n /* c8 ignore start\n * mysterious need for a guard here?\n * https://github.com/isaacs/ttlcache/issues/26 */\n const keys = [...(this.expirations[exp] || [])]\n /* c8 ignore stop */\n const entries: [K, V][] = []\n delete this.expirations[exp]\n for (const key of keys) {\n entries.push([key, this.data.get(key) as V])\n this.data.delete(key)\n this.expirationMap.delete(key)\n }\n for (const [key, val] of entries) {\n this.dispose(val, key, 'stale')\n }\n }\n if (this.size === 0) {\n this.cancelTimer()\n }\n }\n\n *entries() {\n for (const exp in this.expirations) {\n for (const key of this.expirations[exp] as K[]) {\n yield [key, this.data.get(key)] as [K, V]\n }\n }\n }\n *keys() {\n for (const exp in this.expirations) {\n for (const key of this.expirations[exp] as K[]) {\n yield key\n }\n }\n }\n *values() {\n for (const exp in this.expirations) {\n for (const key of this.expirations[exp] as K[]) {\n yield this.data.get(key) as V\n }\n }\n }\n [Symbol.iterator]() {\n return this.entries()\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,13 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@isaacs/ttlcache",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"files": [
|
|
5
|
-
"
|
|
6
|
-
"index.d.ts"
|
|
5
|
+
"dist"
|
|
7
6
|
],
|
|
8
|
-
"main": "index.js",
|
|
7
|
+
"main": "./dist/commonjs/index.js",
|
|
9
8
|
"exports": {
|
|
10
|
-
".": "./
|
|
9
|
+
"./package.json": "./package.json",
|
|
10
|
+
".": {
|
|
11
|
+
"import": {
|
|
12
|
+
"types": "./dist/esm/index.d.ts",
|
|
13
|
+
"default": "./dist/esm/index.js"
|
|
14
|
+
},
|
|
15
|
+
"require": {
|
|
16
|
+
"types": "./dist/commonjs/index.d.ts",
|
|
17
|
+
"default": "./dist/commonjs/index.js"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
11
20
|
},
|
|
12
21
|
"description": "The time-based use-recency-unaware cousin of [`lru-cache`](http://npm.im/lru-cache)",
|
|
13
22
|
"repository": {
|
|
@@ -15,36 +24,37 @@
|
|
|
15
24
|
"url": "git+https://github.com/isaacs/ttlcache"
|
|
16
25
|
},
|
|
17
26
|
"author": "Isaac Z. Schlueter <i@izs.me> (https://izs.me)",
|
|
18
|
-
"license": "
|
|
27
|
+
"license": "BlueOak-1.0.0",
|
|
19
28
|
"scripts": {
|
|
29
|
+
"prepare": "tshy",
|
|
30
|
+
"pretest": "npm run prepare",
|
|
31
|
+
"presnap": "npm run prepare",
|
|
20
32
|
"test": "tap",
|
|
21
33
|
"snap": "tap",
|
|
22
34
|
"preversion": "npm test",
|
|
23
35
|
"postversion": "npm publish",
|
|
24
|
-
"prepublishOnly": "git push origin --follow-tags"
|
|
36
|
+
"prepublishOnly": "git push origin --follow-tags",
|
|
37
|
+
"format": "prettier --write .",
|
|
38
|
+
"typedoc": "typedoc --tsconfig ./.tshy/esm.json ./src/*.ts"
|
|
39
|
+
},
|
|
40
|
+
"tshy": {
|
|
41
|
+
"exports": {
|
|
42
|
+
"./package.json": "./package.json",
|
|
43
|
+
".": "./src/index.ts"
|
|
44
|
+
}
|
|
25
45
|
},
|
|
26
46
|
"devDependencies": {
|
|
27
|
-
"@
|
|
28
|
-
"@types/
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"typescript": "^
|
|
47
|
+
"@tapjs/clock": "^3.0.2",
|
|
48
|
+
"@types/node": "^24.9.1",
|
|
49
|
+
"prettier": "^3.6.2",
|
|
50
|
+
"tap": "^21.1.1",
|
|
51
|
+
"tshy": "^3.0.3",
|
|
52
|
+
"typedoc": "^0.28.14",
|
|
53
|
+
"typescript": "^5.9.3"
|
|
34
54
|
},
|
|
35
55
|
"engines": {
|
|
36
56
|
"node": ">=12"
|
|
37
57
|
},
|
|
38
|
-
"tap": {
|
|
39
|
-
"nyc-arg": [
|
|
40
|
-
"--include=index.js"
|
|
41
|
-
],
|
|
42
|
-
"node-arg": [
|
|
43
|
-
"--require",
|
|
44
|
-
"ts-node/register"
|
|
45
|
-
],
|
|
46
|
-
"ts": false
|
|
47
|
-
},
|
|
48
58
|
"prettier": {
|
|
49
59
|
"semi": false,
|
|
50
60
|
"printWidth": 70,
|
|
@@ -55,5 +65,13 @@
|
|
|
55
65
|
"bracketSameLine": true,
|
|
56
66
|
"arrowParens": "avoid",
|
|
57
67
|
"endOfLine": "lf"
|
|
68
|
+
},
|
|
69
|
+
"type": "module",
|
|
70
|
+
"types": "./dist/commonjs/index.d.ts",
|
|
71
|
+
"module": "./dist/esm/index.js",
|
|
72
|
+
"tap": {
|
|
73
|
+
"plugin": [
|
|
74
|
+
"@tapjs/clock"
|
|
75
|
+
]
|
|
58
76
|
}
|
|
59
77
|
}
|
package/LICENSE
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
The ISC License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2022-2023 - Isaac Z. Schlueter and Contributors
|
|
4
|
-
|
|
5
|
-
Permission to use, copy, modify, and/or distribute this software for any
|
|
6
|
-
purpose with or without fee is hereby granted, provided that the above
|
|
7
|
-
copyright notice and this permission notice appear in all copies.
|
|
8
|
-
|
|
9
|
-
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
10
|
-
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
11
|
-
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
12
|
-
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
13
|
-
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
14
|
-
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
|
15
|
-
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|