2020-11-06 23:13:12 -05:00
'use strict' ;
module . exports = function ( opts ) {
const LRU = require ( 'lru-cache' ) ;
const pubsub = require ( './pubsub' ) ;
2022-08-10 13:24:16 -04:00
// lru-cache@7 deprecations
const winston = require ( 'winston' ) ;
const chalk = require ( 'chalk' ) ;
2020-11-06 23:13:12 -05:00
2022-08-10 13:24:16 -04:00
// sometimes we kept passing in `length` with no corresponding `maxSize`.
// This is now enforced in v7; drop superfluous property
if ( opts . hasOwnProperty ( 'length' ) && ! opts . hasOwnProperty ( 'maxSize' ) ) {
winston . warn ( ` [cache/init( ${ opts . name } )] ${ chalk . white . bgRed . bold ( 'DEPRECATION' ) } ${ chalk . yellow ( 'length' ) } was passed in without a corresponding ${ chalk . yellow ( 'maxSize' ) } . Both are now required as of lru-cache@7.0.0. ` ) ;
delete opts . length ;
}
const deprecations = new Map ( [
[ 'stale' , 'allowStale' ] ,
[ 'maxAge' , 'ttl' ] ,
[ 'length' , 'sizeCalculation' ] ,
] ) ;
deprecations . forEach ( ( newProp , oldProp ) => {
if ( opts . hasOwnProperty ( oldProp ) && ! opts . hasOwnProperty ( newProp ) ) {
winston . warn ( ` [cache/init ( ${ opts . name } )] ${ chalk . white . bgRed . bold ( 'DEPRECATION' ) } The option ${ chalk . yellow ( oldProp ) } has been deprecated as of lru-cache@7.0.0. Please change this to ${ chalk . yellow ( newProp ) } instead. ` ) ;
opts [ newProp ] = opts [ oldProp ] ;
delete opts [ oldProp ] ;
}
} ) ;
const lruCache = new LRU ( opts ) ;
const cache = { } ;
2020-11-06 23:13:12 -05:00
cache . name = opts . name ;
cache . hits = 0 ;
cache . misses = 0 ;
cache . enabled = opts . hasOwnProperty ( 'enabled' ) ? opts . enabled : true ;
2022-08-10 13:24:16 -04:00
const cacheSet = lruCache . set ;
2020-11-06 23:13:12 -05:00
2022-08-10 13:24:16 -04:00
// backwards compatibility
const propertyMap = new Map ( [
[ 'length' , 'calculatedSize' ] ,
[ 'max' , 'max' ] ,
[ 'maxSize' , 'maxSize' ] ,
[ 'itemCount' , 'size' ] ,
] ) ;
propertyMap . forEach ( ( lruProp , cacheProp ) => {
Object . defineProperty ( cache , cacheProp , {
get : function ( ) {
return lruCache [ lruProp ] ;
} ,
configurable : true ,
enumerable : true ,
} ) ;
} ) ;
2020-11-06 23:13:12 -05:00
2022-08-10 13:24:16 -04:00
cache . set = function ( key , value , ttl ) {
2020-11-06 23:13:12 -05:00
if ( ! cache . enabled ) {
return ;
}
2022-08-10 13:24:16 -04:00
const opts = { } ;
if ( ttl ) {
opts . ttl = ttl ;
}
cacheSet . apply ( lruCache , [ key , value , opts ] ) ;
2020-11-06 23:13:12 -05:00
} ;
cache . get = function ( key ) {
if ( ! cache . enabled ) {
return undefined ;
}
2022-08-10 13:24:16 -04:00
const data = lruCache . get ( key ) ;
2020-11-06 23:13:12 -05:00
if ( data === undefined ) {
cache . misses += 1 ;
} else {
cache . hits += 1 ;
}
return data ;
} ;
cache . del = function ( keys ) {
if ( ! Array . isArray ( keys ) ) {
keys = [ keys ] ;
}
2021-02-03 23:59:08 -07:00
pubsub . publish ( ` ${ cache . name } :cache:del ` , keys ) ;
2022-08-10 13:24:16 -04:00
keys . forEach ( key => lruCache . delete ( key ) ) ;
2020-11-06 23:13:12 -05:00
} ;
2022-08-10 13:24:16 -04:00
cache . delete = cache . del ;
2020-11-06 23:13:12 -05:00
cache . reset = function ( ) {
2021-02-03 23:59:08 -07:00
pubsub . publish ( ` ${ cache . name } :cache:reset ` ) ;
2020-11-06 23:13:12 -05:00
localReset ( ) ;
} ;
2022-08-10 13:24:16 -04:00
cache . clear = cache . reset ;
2020-11-06 23:13:12 -05:00
function localReset ( ) {
2022-08-10 13:24:16 -04:00
lruCache . clear ( ) ;
2020-11-06 23:13:12 -05:00
cache . hits = 0 ;
cache . misses = 0 ;
}
2021-02-04 00:01:39 -07:00
pubsub . on ( ` ${ cache . name } :cache:reset ` , ( ) => {
2020-11-06 23:13:12 -05:00
localReset ( ) ;
} ) ;
2021-02-04 00:01:39 -07:00
pubsub . on ( ` ${ cache . name } :cache:del ` , ( keys ) => {
2020-11-06 23:13:12 -05:00
if ( Array . isArray ( keys ) ) {
2022-08-10 13:24:16 -04:00
keys . forEach ( key => lruCache . delete ( key ) ) ;
2020-11-06 23:13:12 -05:00
}
} ) ;
cache . getUnCachedKeys = function ( keys , cachedData ) {
if ( ! cache . enabled ) {
return keys ;
}
let data ;
let isCached ;
2021-02-04 00:01:39 -07:00
const unCachedKeys = keys . filter ( ( key ) => {
2020-11-06 23:13:12 -05:00
data = cache . get ( key ) ;
isCached = data !== undefined ;
if ( isCached ) {
cachedData [ key ] = data ;
}
return ! isCached ;
} ) ;
2020-11-08 08:35:40 -05:00
const hits = keys . length - unCachedKeys . length ;
const misses = keys . length - hits ;
2020-11-06 23:13:12 -05:00
cache . hits += hits ;
cache . misses += misses ;
return unCachedKeys ;
} ;
2022-08-10 13:24:16 -04:00
cache . dump = function ( ) {
return lruCache . dump ( ) ;
} ;
cache . peek = function ( key ) {
return lruCache . peek ( key ) ;
} ;
2020-11-06 23:13:12 -05:00
return cache ;
} ;