Skip to content

Commit 4d23156

Browse files
committed
Use lru-cache@11.
1 parent db54e5c commit 4d23156

File tree

4 files changed

+52
-24
lines changed

4 files changed

+52
-24
lines changed

CHANGELOG.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,19 @@
11
# @digitalbazaar/lru-memoize ChangeLog
22

3+
## 4.0.0 - 2025-mm-dd
4+
5+
### Changed
6+
- **BREAKING**: Use `lru-cache@11`. This replaces `lru-cache@6` which has a
7+
number of breaking changes that impact any use of this library that
8+
previously accessed the underlying cache interface. The main interface
9+
of this module has only changed in that the options it accepts when
10+
creating the cache need to now conform to v11 of `lru-cache` instead of
11+
v6. The v6 `maxAge` option, if given, will be coerced to `ttl` to match
12+
v11.
13+
- **BREAKING**: The `delete()` method now returns `true` if the passed key was
14+
removed from the cache and `false` if not, matching the v11 `delete()`
15+
interface. Previously, `undefined` was returned in both cases.
16+
317
## 3.0.2 - 2023-08-27
418

519
### Fixed

lib/LruCache.js

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*!
2-
* Copyright (c) 2020-2023 Digital Bazaar, Inc. All rights reserved.
2+
* Copyright (c) 2020-2025 Digital Bazaar, Inc. All rights reserved.
33
*/
4-
import LRU from 'lru-cache';
4+
import {LRUCache as LRU} from 'lru-cache';
55

66
/**
77
* LruCache uses the npm module `lru-cache` to memoize promises.
@@ -10,8 +10,15 @@ import LRU from 'lru-cache';
1010
* @see https://en.wikipedia.org/wiki/Memoization
1111
* @param {object} cacheOptions - Options for `lru-cache`.
1212
* See the npm docs for more options.
13-
* @param {number} [cacheOptions.max] - The max size of the cache.
14-
* @param {number} [cacheOptions.maxAge] - The maxAge of an item in ms.
13+
* @param {number} [cacheOptions.max=1000] - The max number of items in the
14+
* cache. If no `max` is specified and no `maxSize` is specified, then `max`
15+
* will default to `1000`, ensuring the cache is bounded.
16+
* @param {number} [cacheOptions.maxSize] - An optional max size for the cache;
17+
* if provided, then the size of each item must be calculated via a provided
18+
* `sizeCalculation` function.
19+
* @param {number} [cacheOptions.ttl] - The time-to-live of an item in ms.
20+
* @param {Function} [cacheOptions.sizeCalculation] - A function that will
21+
* calculate the size of an item; see lru-cache documentation.
1522
* @param {boolean} [cacheOptions.updateAgeOnGet=false] - When using
1623
* time-expiring entries with maxAge, setting this to true will make
1724
* each entry's effective time update to the current time whenever it is
@@ -23,9 +30,13 @@ import LRU from 'lru-cache';
2330
* @returns {LruCache} The class.
2431
*/
2532
export class LruCache {
26-
constructor(cacheOptions = {}) {
27-
this.options = cacheOptions;
28-
this.cache = new LRU(cacheOptions);
33+
constructor(cacheOptions = {max: 1000}) {
34+
if(cacheOptions.maxAge !== undefined) {
35+
throw new TypeError(
36+
'"cacheOptions.maxAge" is no longer supported; use "ttl" instead.');
37+
}
38+
this.options = {max: 1000, ...cacheOptions};
39+
this.cache = new LRU(this.options);
2940
}
3041

3142
/**
@@ -36,7 +47,7 @@ export class LruCache {
3647
* @returns {undefined}
3748
*/
3849
delete(key) {
39-
return this.cache.del(key);
50+
return this.cache.delete(key);
4051
}
4152

4253
/**
@@ -61,24 +72,24 @@ export class LruCache {
6172
// cache miss
6273
const cacheOptions = {...this.options, ...options};
6374
promise = fn();
64-
// this version only supports `maxAge` and `disposeOnSettle`; a future
65-
// version will support more cache options
66-
const {maxAge} = cacheOptions;
67-
this.cache.set(key, promise, maxAge);
75+
// this version only supports passing `ttl` through to the underlying
76+
// lru-cache instance; a future version will support more cache options
77+
const {ttl} = cacheOptions;
78+
this.cache.set(key, promise, {ttl});
6879

6980
try {
7081
await promise;
7182
} catch(e) {
7283
// if the promise rejects, delete it if the cache entry hasn't changed
7384
if(promise === this.cache.get(key)) {
74-
this.cache.del(key);
85+
this.cache.delete(key);
7586
}
7687
throw e;
7788
}
7889

7990
// dispose promise once settled (provided the cache entry hasn't changed)
8091
if(cacheOptions.disposeOnSettle && promise === this.cache.get(key)) {
81-
this.cache.del(key);
92+
this.cache.delete(key);
8293
}
8394

8495
return promise;

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"lint": "eslint ."
1919
},
2020
"dependencies": {
21-
"lru-cache": "^6.0.0"
21+
"lru-cache": "^11.1.0"
2222
},
2323
"devDependencies": {
2424
"c8": "^10.1.3",

tests/10-api.spec.js

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
/*!
2-
* Copyright (c) 2020-2023 Digital Bazaar, Inc. All rights reserved.
2+
* Copyright (c) 2020-2025 Digital Bazaar, Inc. All rights reserved.
33
*/
44
import delay from 'delay';
55
import {LruCache} from '../lib/index.js';
66

77
describe('API', () => {
88
it('has the proper exports', async () => {
99
should.exist(LruCache);
10-
const m = new LruCache();
10+
const m = new LruCache({ttl: 10});
1111
should.exist(m);
1212
m.memoize.should.be.a('function');
1313
});
@@ -40,7 +40,7 @@ describe('API', () => {
4040
result2.should.eql(result);
4141
executedTestFn.should.be.false;
4242
});
43-
it('adds an item to the cache w/custom `maxAge`', async () => {
43+
it('adds an item to the cache w/custom `ttl`', async () => {
4444
const m = new LruCache();
4545
let executedTestFn = false;
4646
const testFn = async () => {
@@ -49,11 +49,11 @@ describe('API', () => {
4949
executedTestFn = true;
5050
return {success: true, timestamp: Date.now()};
5151
};
52-
const maxAge = 200;
52+
const ttl = 200;
5353
const result = await m.memoize({
5454
key: 'test1',
5555
fn: testFn,
56-
options: {maxAge}
56+
options: {ttl}
5757
});
5858
should.exist(result);
5959
result.success.should.be.true;
@@ -71,7 +71,7 @@ describe('API', () => {
7171
executedTestFn.should.be.false;
7272

7373
// third test should not find the expired result
74-
await delay(maxAge + 1);
74+
await delay(ttl + 1);
7575
executedTestFn = false;
7676
const result3 = await m.memoize({
7777
key: 'test1',
@@ -114,9 +114,12 @@ describe('API', () => {
114114
executedTestFn.should.be.false;
115115

116116
// delete the cached promise
117-
const r = m.delete('test1');
118-
// always returns undefined
119-
should.not.exist(r);
117+
const deleted1 = m.delete('test1');
118+
// should return `true` because `test1` was removed
119+
deleted1.should.equal(true);
120+
// should now return `false` because `test1` was already removed
121+
const deleted2 = m.delete('test1');
122+
deleted2.should.equal(false);
120123

121124
// after deleting the cache entry, testFn should be executed producing
122125
// a result with a new timestamp

0 commit comments

Comments
 (0)