typescript-lru-cache
Advanced tools
Comparing version 1.1.1 to 1.2.0
@@ -13,2 +13,4 @@ export interface LRUCacheOptions<TKey, TValue> { | ||
}) => void; | ||
clone?: boolean; | ||
cloneFn?: (value: TValue) => TValue; | ||
} | ||
@@ -26,2 +28,4 @@ export interface LRUCacheSetEntryOptions<TKey, TValue> { | ||
}) => void; | ||
clone?: boolean; | ||
cloneFn?: (value: TValue) => TValue; | ||
} | ||
@@ -37,2 +41,4 @@ export interface LRUCacheEntry<TKey, TValue> { | ||
private readonly onEntryMarkedAsMostRecentlyUsed?; | ||
private readonly cloneFn?; | ||
private readonly clone?; | ||
private maxSizeInternal; | ||
@@ -39,0 +45,0 @@ private head; |
@@ -15,3 +15,3 @@ "use strict"; | ||
this.tail = null; | ||
const { maxSize = 25, entryExpirationTimeInMS = null, onEntryEvicted, onEntryMarkedAsMostRecentlyUsed } = options || {}; | ||
const { maxSize = 25, entryExpirationTimeInMS = null, onEntryEvicted, onEntryMarkedAsMostRecentlyUsed, cloneFn, clone } = options !== null && options !== void 0 ? options : {}; | ||
if (Number.isNaN(maxSize) || maxSize <= 0) { | ||
@@ -28,2 +28,4 @@ throw new Error('maxSize must be greater than 0.'); | ||
this.onEntryMarkedAsMostRecentlyUsed = onEntryMarkedAsMostRecentlyUsed; | ||
this.clone = clone; | ||
this.cloneFn = cloneFn; | ||
} | ||
@@ -111,2 +113,4 @@ /** | ||
onEntryMarkedAsMostRecentlyUsed: this.onEntryMarkedAsMostRecentlyUsed, | ||
clone: this.clone, | ||
cloneFn: this.cloneFn, | ||
...entryOptions | ||
@@ -113,0 +117,0 @@ }); |
@@ -14,6 +14,7 @@ export interface LRUCacheNodeOptions<TKey, TValue> { | ||
}) => void; | ||
clone?: boolean; | ||
cloneFn?: (value: TValue) => TValue; | ||
} | ||
export declare class LRUCacheNode<TKey, TValue> { | ||
readonly key: TKey; | ||
readonly value: TValue; | ||
readonly created: number; | ||
@@ -23,9 +24,14 @@ readonly entryExpirationTimeInMS: number | null; | ||
prev: LRUCacheNode<TKey, TValue> | null; | ||
private readonly internalValue; | ||
private readonly onEntryEvicted?; | ||
private readonly onEntryMarkedAsMostRecentlyUsed?; | ||
private readonly cloneFn; | ||
private readonly clone; | ||
constructor(key: TKey, value: TValue, options?: LRUCacheNodeOptions<TKey, TValue>); | ||
get value(): TValue; | ||
get isExpired(): boolean; | ||
invokeOnEvicted(): void; | ||
invokeOnEntryMarkedAsMostRecentlyUsed(): void; | ||
private defaultClone; | ||
} | ||
//# sourceMappingURL=LRUCacheNode.d.ts.map |
@@ -6,3 +6,3 @@ "use strict"; | ||
constructor(key, value, options) { | ||
const { entryExpirationTimeInMS = null, next = null, prev = null, onEntryEvicted, onEntryMarkedAsMostRecentlyUsed } = options || {}; | ||
const { entryExpirationTimeInMS = null, next = null, prev = null, onEntryEvicted, onEntryMarkedAsMostRecentlyUsed, clone, cloneFn } = options !== null && options !== void 0 ? options : {}; | ||
if (typeof entryExpirationTimeInMS === 'number' && | ||
@@ -12,4 +12,6 @@ (entryExpirationTimeInMS <= 0 || Number.isNaN(entryExpirationTimeInMS))) { | ||
} | ||
this.clone = clone !== null && clone !== void 0 ? clone : false; | ||
this.cloneFn = cloneFn !== null && cloneFn !== void 0 ? cloneFn : this.defaultClone; | ||
this.key = key; | ||
this.value = value; | ||
this.internalValue = this.clone ? this.cloneFn(value) : value; | ||
this.created = Date.now(); | ||
@@ -22,2 +24,5 @@ this.entryExpirationTimeInMS = entryExpirationTimeInMS; | ||
} | ||
get value() { | ||
return this.clone ? this.cloneFn(this.internalValue) : this.internalValue; | ||
} | ||
get isExpired() { | ||
@@ -38,4 +43,10 @@ return typeof this.entryExpirationTimeInMS === 'number' && Date.now() - this.created > this.entryExpirationTimeInMS; | ||
} | ||
defaultClone(value) { | ||
if (typeof value === 'boolean' || typeof value === 'string' || typeof value === 'number') { | ||
return value; | ||
} | ||
return JSON.parse(JSON.stringify(value)); | ||
} | ||
} | ||
exports.LRUCacheNode = LRUCacheNode; | ||
//# sourceMappingURL=LRUCacheNode.js.map |
{ | ||
"name": "typescript-lru-cache", | ||
"version": "1.1.1", | ||
"version": "1.2.0", | ||
"description": "LRU Cache", | ||
@@ -26,2 +26,3 @@ "author": "Robert Herber", | ||
"scripts": { | ||
"benchmark": "ts-node ./src/benchmark/index.ts", | ||
"build": "rm -rf ./dist && tsc", | ||
@@ -38,19 +39,21 @@ "lint": "eslint .", | ||
"devDependencies": { | ||
"@commitlint/cli": "^11.0.0", | ||
"@commitlint/config-conventional": "^11.0.0", | ||
"@types/jest": "^26.0.16", | ||
"@typescript-eslint/eslint-plugin": "^4.9.0", | ||
"@typescript-eslint/parser": "^4.9.0", | ||
"eslint": "^7.15.0", | ||
"eslint-config-prettier": "^6.15.0", | ||
"eslint-plugin-jest": "^24.1.3", | ||
"eslint-plugin-prettier": "^3.2.0", | ||
"husky": "^4.3.4", | ||
"@commitlint/cli": "^12.0.1", | ||
"@commitlint/config-conventional": "^12.0.1", | ||
"@types/benchmark": "^2.1.0", | ||
"@types/jest": "^26.0.21", | ||
"@typescript-eslint/eslint-plugin": "^4.18.0", | ||
"@typescript-eslint/parser": "^4.18.0", | ||
"benchmark": "^2.1.4", | ||
"eslint": "^7.22.0", | ||
"eslint-config-prettier": "^8.1.0", | ||
"eslint-plugin-jest": "^24.3.2", | ||
"eslint-plugin-prettier": "^3.3.1", | ||
"husky": "^4.3.8", | ||
"jest": "^26.6.3", | ||
"np": "^7.0.0", | ||
"np": "^7.4.0", | ||
"prettier": "^2.2.1", | ||
"ts-jest": "^26.4.4", | ||
"ts-node": "^9.1.0", | ||
"typescript": "^4.1.2" | ||
"ts-jest": "^26.5.4", | ||
"ts-node": "^9.1.1", | ||
"typescript": "^4.2.3" | ||
} | ||
} |
@@ -43,8 +43,46 @@ # typescript-lru-cache | ||
- `entryExpirationTimeInMS` The time to live for cache entries. Setting this to `null` will make entries never expire. Default value is `null`. | ||
- `onEntryEvicted` Function to be called whenever an entry is evicted from the cache (when evicted due to needing to make room, is expired, or deleted using delete()). Passed arguments are (key, value, isExpired) | ||
- `onEntryMarkedAsMostRecentlyUsed` Function to be called whenever an entry is marked as recently used (on set, get, find, etc). Passed arguments are (key, value) | ||
- `onEntryEvicted` Function to be called whenever an entry is evicted from the cache (when evicted due to needing to make room, is expired, or deleted using delete()). Passed argument is an object: | ||
```typescript | ||
{ | ||
key: TKey; | ||
value: TValue; | ||
isExpired: boolean; | ||
} | ||
``` | ||
- `onEntryMarkedAsMostRecentlyUsed` Function to be called whenever an entry is marked as recently used (on set, get, find, etc). Passed argument is an object: | ||
```typescript | ||
{ | ||
key: TKey; | ||
value: TValue; | ||
} | ||
``` | ||
- `clone` Clone values being set and fetched from the cache (clones on set and any retrievals). Useful to maintain immutability. NOTE! This does come with performance overhead (almost twice as slow). Defaults to false. | ||
- `cloneFn` Custom function to be used with the `clone` option. If not passed, `JSON.parse(JSON.stringify(value))` is used for cloning objects. | ||
Example using options: | ||
```typescript | ||
import { LRUCache } from 'typescript-lru-cache'; | ||
// Create a cache. Optional options object can be passed in. | ||
const cache = new LRUCache<string, string>({ | ||
maxSize: 100, | ||
entryExpirationTimeInMS: 5000, | ||
onEntryEvicted: ({ key, value, isExpired }) => | ||
console.log(`Entry with key ${key} and value ${value} was evicted from the cache. Expired: ${isExpired}`), | ||
onEntryMarkedAsMostRecentlyUsed: ({ key, value }) => | ||
console.log(`Entry with key ${key} and value ${value} was just marked as most recently used.`) | ||
}); | ||
// Set a value in the cache with a key | ||
cache.set('testKey', 'testValue'); | ||
// value will be 'testValue' | ||
const value = cache.get('testKey'); | ||
console.log(value); | ||
``` | ||
### LRUCache Set Entry Options: | ||
Pass in an optional options object as the third argument of the `set` method to configure options for just that entry. These options will override LRUCache options if applicable. | ||
Pass in an optional options object as the third argument of the `set` method to configure options for just that entry. These options will override LRUCache options if applicable (including callback methods like onEntryEvicted). | ||
@@ -54,4 +92,19 @@ The options object has the following properties: | ||
- `entryExpirationTimeInMS` The time to live for the entry. Setting this to `null` will make the entry never expire. | ||
- `onEntryEvicted` Function to be called whenever an entry is evicted from the cache (when evicted due to needing to make room, is expired, or deleted using delete()). Passed arguments are (key, value, isExpired) | ||
- `onEntryMarkedAsMostRecentlyUsed` Function to be called whenever an entry is marked as recently used (on set, get, find, etc). Passed arguments are (key, value) | ||
- `onEntryEvicted` Function to be called whenever _this_ entry is evicted from the cache (when evicted due to needing to make room, is expired, or deleted using delete()). Passed argument is an object: | ||
```typescript | ||
{ | ||
key: TKey; | ||
value: TValue; | ||
isExpired: boolean; | ||
} | ||
``` | ||
- `onEntryMarkedAsMostRecentlyUsed` Function to be called whenever _this_ entry is marked as recently used (on set, get, find, etc). Passed argument is an object: | ||
```typescript | ||
{ | ||
key: TKey; | ||
value: TValue; | ||
} | ||
``` | ||
- `clone` Clone values being set and fetched from the cache (clones on set and any retrievals). Useful to maintain immutability. NOTE! This does come with performance overhead (almost twice as slow). Defaults to false. | ||
- `cloneFn` Custom function to be used with the `clone` option. If not passed, `JSON.parse(JSON.stringify(value))` is used for cloning objects. | ||
@@ -124,3 +177,3 @@ Example: | ||
// Will be false | ||
const wasDeleted2 = cache.deleted('keyNotInCache'); | ||
const wasDeleted2 = cache.delete('keyNotInCache'); | ||
``` | ||
@@ -127,0 +180,0 @@ |
@@ -8,2 +8,4 @@ import { LRUCacheNode } from './LRUCacheNode'; | ||
onEntryMarkedAsMostRecentlyUsed?: (entry: { key: TKey; value: TValue }) => void; | ||
clone?: boolean; | ||
cloneFn?: (value: TValue) => TValue; | ||
} | ||
@@ -15,2 +17,4 @@ | ||
onEntryMarkedAsMostRecentlyUsed?: (entry: { key: TKey; value: TValue }) => void; | ||
clone?: boolean; | ||
cloneFn?: (value: TValue) => TValue; | ||
} | ||
@@ -32,2 +36,6 @@ | ||
private readonly cloneFn?: (value: TValue) => TValue; | ||
private readonly clone?: boolean; | ||
private maxSizeInternal: number; | ||
@@ -45,4 +53,10 @@ | ||
public constructor(options?: LRUCacheOptions<TKey, TValue>) { | ||
const { maxSize = 25, entryExpirationTimeInMS = null, onEntryEvicted, onEntryMarkedAsMostRecentlyUsed } = | ||
options || {}; | ||
const { | ||
maxSize = 25, | ||
entryExpirationTimeInMS = null, | ||
onEntryEvicted, | ||
onEntryMarkedAsMostRecentlyUsed, | ||
cloneFn, | ||
clone | ||
} = options ?? {}; | ||
@@ -64,2 +78,4 @@ if (Number.isNaN(maxSize) || maxSize <= 0) { | ||
this.onEntryMarkedAsMostRecentlyUsed = onEntryMarkedAsMostRecentlyUsed; | ||
this.clone = clone; | ||
this.cloneFn = cloneFn; | ||
} | ||
@@ -160,2 +176,4 @@ | ||
onEntryMarkedAsMostRecentlyUsed: this.onEntryMarkedAsMostRecentlyUsed, | ||
clone: this.clone, | ||
cloneFn: this.cloneFn, | ||
...entryOptions | ||
@@ -162,0 +180,0 @@ }); |
@@ -7,2 +7,4 @@ export interface LRUCacheNodeOptions<TKey, TValue> { | ||
onEntryMarkedAsMostRecentlyUsed?: (entry: { key: TKey; value: TValue }) => void; | ||
clone?: boolean; | ||
cloneFn?: (value: TValue) => TValue; | ||
} | ||
@@ -13,4 +15,2 @@ | ||
public readonly value: TValue; | ||
public readonly created: number; | ||
@@ -24,2 +24,4 @@ | ||
private readonly internalValue: TValue; | ||
private readonly onEntryEvicted?: (evictedEntry: { key: TKey; value: TValue; isExpired: boolean }) => void; | ||
@@ -29,2 +31,6 @@ | ||
private readonly cloneFn: (value: TValue) => TValue; | ||
private readonly clone: boolean; | ||
public constructor(key: TKey, value: TValue, options?: LRUCacheNodeOptions<TKey, TValue>) { | ||
@@ -36,4 +42,6 @@ const { | ||
onEntryEvicted, | ||
onEntryMarkedAsMostRecentlyUsed | ||
} = options || {}; | ||
onEntryMarkedAsMostRecentlyUsed, | ||
clone, | ||
cloneFn | ||
} = options ?? {}; | ||
@@ -47,4 +55,7 @@ if ( | ||
this.clone = clone ?? false; | ||
this.cloneFn = cloneFn ?? this.defaultClone; | ||
this.key = key; | ||
this.value = value; | ||
this.internalValue = this.clone ? this.cloneFn(value) : value; | ||
this.created = Date.now(); | ||
@@ -58,2 +69,6 @@ this.entryExpirationTimeInMS = entryExpirationTimeInMS; | ||
public get value(): TValue { | ||
return this.clone ? this.cloneFn(this.internalValue) : this.internalValue; | ||
} | ||
public get isExpired(): boolean { | ||
@@ -76,2 +91,10 @@ return typeof this.entryExpirationTimeInMS === 'number' && Date.now() - this.created > this.entryExpirationTimeInMS; | ||
} | ||
private defaultClone(value: TValue): TValue { | ||
if (typeof value === 'boolean' || typeof value === 'string' || typeof value === 'number') { | ||
return value; | ||
} | ||
return JSON.parse(JSON.stringify(value)); | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
70104
1141
364
18