Skip to content

Commit db6c2ec

Browse files
committed
cache.set(k, undefined) alias to cache.delete(k)
Fix: #290
1 parent 88bb31c commit db6c2ec

File tree

4 files changed

+60
-60
lines changed

4 files changed

+60
-60
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
11
# cringe lorg
22

3+
## 9.1.0
4+
5+
- `cache.set(key, undefined)` is now an alias for
6+
`cache.delete(key)`
7+
38
## 9.0.0
49

510
- Use named export only, no default export.
11+
- Bring back minimal polyfill. If this polyfill ends up being
12+
used, then a warning is printed, as it is not safe for use
13+
outside of LRUCache.
614

715
## 8.0.0
816

README.md

Lines changed: 43 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,10 @@ Returns the cache object.
568568
For the usage of the `status` option, see **Status Tracking**
569569
below.
570570

571+
If the value is `undefined`, then this is an alias for
572+
`cache.delete(key)`. `undefined` is never stored in the cache.
573+
See **Storing Undefined Values** below.
574+
571575
### `get(key, { updateAgeOnGet, allowStale, status } = {}) => value`
572576

573577
Return a value from the cache.
@@ -798,63 +802,6 @@ Evict the least recently used item, returning its value.
798802

799803
Returns `undefined` if cache is empty.
800804

801-
### Internal Methods and Properties
802-
803-
In order to optimize performance as much as possible, "private"
804-
members and methods are exposed on the object as normal
805-
properties, rather than being accessed via Symbols, private
806-
members, or closure variables.
807-
808-
**Do not use or rely on these.** They will change or be removed
809-
without notice. They will cause undefined behavior if used
810-
inappropriately. There is no need or reason to ever call them
811-
directly.
812-
813-
This documentation is here so that it is especially clear that
814-
this not "undocumented" because someone forgot; it _is_
815-
documented, and the documentation is telling you not to do it.
816-
817-
**Do not report bugs that stem from using these properties.**
818-
They will be ignored.
819-
820-
- `initializeTTLTracking()` Set up the cache for tracking TTLs
821-
- `updateItemAge(index)` Called when an item age is updated, by
822-
internal ID
823-
- `setItemTTL(index)` Called when an item ttl is updated, by
824-
internal ID
825-
- `isStale(index)` Called to check an item's staleness, by
826-
internal ID
827-
- `initializeSizeTracking()` Set up the cache for tracking item
828-
size. Called automatically when a size is specified.
829-
- `removeItemSize(index)` Updates the internal size calculation
830-
when an item is removed or modified, by internal ID
831-
- `addItemSize(index)` Updates the internal size calculation when
832-
an item is added or modified, by internal ID
833-
- `indexes()` An iterator over the non-stale internal IDs, from
834-
most recently to least recently used.
835-
- `rindexes()` An iterator over the non-stale internal IDs, from
836-
least recently to most recently used.
837-
- `newIndex()` Create a new internal ID, either reusing a deleted
838-
ID, evicting the least recently used ID, or walking to the end
839-
of the allotted space.
840-
- `evict()` Evict the least recently used internal ID, returning
841-
its ID. Does not do any bounds checking.
842-
- `connect(p, n)` Connect the `p` and `n` internal IDs in the
843-
linked list.
844-
- `moveToTail(index)` Move the specified internal ID to the most
845-
recently used position.
846-
- `keyMap` Map of keys to internal IDs
847-
- `keyList` List of keys by internal ID
848-
- `valList` List of values by internal ID
849-
- `sizes` List of calculated sizes by internal ID
850-
- `ttls` List of TTL values by internal ID
851-
- `starts` List of start time values by internal ID
852-
- `next` Array of "next" pointers by internal ID
853-
- `prev` Array of "previous" pointers by internal ID
854-
- `head` Internal ID of least recently used item
855-
- `tail` Internal ID of most recently used item
856-
- `free` Stack of deleted internal IDs
857-
858805
## Status Tracking
859806

860807
Occasionally, it may be useful to track the internal behavior of
@@ -1074,6 +1021,38 @@ const cache = {
10741021
If that isn't to your liking, check out
10751022
[@isaacs/ttlcache](http://npm.im/@isaacs/ttlcache).
10761023

1024+
## Storing Undefined Values
1025+
1026+
This cache never stores undefined values, as `undefined` is used
1027+
internally in a few places to indicate that a key is not in the
1028+
cache.
1029+
1030+
You may call `cache.set(key, undefined)`, but this is just an
1031+
an alias for `cache.delete(key)`. Note that this has the effect
1032+
that `cache.has(key)` will return _false_ after setting it to
1033+
undefined.
1034+
1035+
```js
1036+
cache.set(myKey, undefined)
1037+
cache.has(myKey) // false!
1038+
```
1039+
1040+
If you need to track `undefined` values, and still note that the
1041+
key is in the cache, an easy workaround is to use a sigil object
1042+
of your own.
1043+
1044+
```js
1045+
import { LRUCache } from 'lru-cache'
1046+
const undefinedValue = Symbol('undefined')
1047+
const cache = new LRUCache(...)
1048+
const mySet = (key, value) =>
1049+
cache.set(key, value === undefined ? undefinedValue : value)
1050+
const myGet = (key, value) => {
1051+
const v = cache.get(key)
1052+
return v === undefinedValue ? undefined : v
1053+
}
1054+
```
1055+
10771056
## Performance
10781057

10791058
As of January 2022, version 7 of this library is one of the most
@@ -1169,12 +1148,18 @@ before, it probably will not work in version 7 and above.
11691148
longer be set on the cache instance itself.
11701149
- Rewritten in TypeScript, so pretty much all the types moved
11711150
around a lot.
1172-
- The AbortController/AbortSignal polyfill is removed. For this
1151+
- The AbortController/AbortSignal polyfill was removed. For this
11731152
reason, **Node version 16.14.0 or higher is now required**.
11741153
- Internal properties were moved to actual private class
11751154
properties.
11761155
- Keys and values must not be `null` or `undefined`.
11771156
- Minified export available at `'lru-cache/min'`, for both CJS
11781157
and MJS builds.
11791158

1159+
## Changes in Version 9
1160+
1161+
- Named export only, no default export.
1162+
- AbortController polyfill returned, albeit with a warning when
1163+
used.
1164+
11801165
For more info, see the [change log](CHANGELOG.md).

src/index.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1585,12 +1585,19 @@ export class LRUCache<K extends {}, V extends {}, FC = unknown> {
15851585

15861586
/**
15871587
* Add a value to the cache.
1588+
*
1589+
* Note: if `undefined` is specified as a value, this is an alias for
1590+
* {@link LRUCache#delete}
15881591
*/
15891592
set(
15901593
k: K,
1591-
v: V | BackgroundFetch<V>,
1594+
v: V | BackgroundFetch<V> | undefined,
15921595
setOptions: LRUCache.SetOptions<K, V, FC> = {}
15931596
) {
1597+
if (v === undefined) {
1598+
this.delete(k)
1599+
return this
1600+
}
15941601
const {
15951602
ttl = this.ttl,
15961603
start,

test/basic.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ t.test('basic operation', t => {
106106
c.set(true, 'true', { status: s() })
107107
t.equal(c.has(true, { status: s() }), true)
108108
t.equal(c.get(true, { status: s() }), 'true')
109-
c.delete(true)
109+
c.set(true, undefined)
110110
t.equal(c.has(true, { status: s() }), false)
111111

112112
t.matchSnapshot(statuses, 'status tracking')

0 commit comments

Comments
 (0)