1+
2+ /* eslint-disable @typescript-eslint/no-explicit-any */
3+
14import _ from 'lodash' ;
2- import { type Cache , caching , type Store } from 'cache-manager' ;
5+ import {
6+ type Cache , caching , type Store ,
7+ } from 'cache-manager' ;
38import type { CachedFunctionInitializerOptions , CachedFunctionOptions } from './index.d' ;
4- import type { AnyFunction , ArgumentPaths } from './paths.d' ;
9+ import type { AnyFunction as CacheableFunction , ArgumentPaths } from './paths.d' ;
510
611let cache : Cache | undefined ;
712
@@ -19,11 +24,14 @@ export async function getOrInitializeCache<S extends Store>(options?: CachedFunc
1924 return cache as Cache < S > ;
2025}
2126
27+ /**
28+ * @deprecated To close any open connections, please retrieve the cache object from `getOrInitializeCache` and close it directly.
29+ */
2230export function resetCache ( ) {
2331 cache = undefined ;
2432}
2533
26- export function selectorToCacheKey < F extends AnyFunction > ( arguments_ : Parameters < F > , selector : ArgumentPaths < F > ) {
34+ export function selectorToCacheKey < F extends CacheableFunction > ( arguments_ : Parameters < F > , selector : ArgumentPaths < F > ) {
2735 const selectors = _ . castArray ( selector ) ;
2836 if ( selectors . length === 0 ) {
2937 return JSON . stringify ( arguments_ ) ;
@@ -45,26 +53,47 @@ export function selectorToCacheKey<F extends AnyFunction>(arguments_: Parameters
4553 return JSON . stringify ( result ) ;
4654}
4755
48- export function cachedFunction < F extends AnyFunction > ( function_ : F , options : CachedFunctionOptions < F > ) {
56+ export function cachedFunction < F extends CacheableFunction > ( function_ : F , options ? : CachedFunctionOptions < F > ) {
4957 return async ( ...arguments_ : Parameters < F > ) : Promise < ReturnType < F > > => {
50- const selector = options . selector ?? function_ . cacheKeys ?? [ ] ;
51- const cacheKey = selectorToCacheKey ( arguments_ , selector ) ;
58+ const cacheOptions = _ . merge ( { } , options ?? { } , function_ . cacheOptions ?? { } ) ;
59+ if ( _ . keys ( cacheOptions ) . length === 0 ) {
60+ throw new Error ( 'No cache options provided, either use the @CacheOptions decorator or provide options to cachedFunction directly.' ) ;
61+ }
62+
63+ const cacheKey = selectorToCacheKey ( arguments_ , cacheOptions . selector ! ) ;
5264 const cache = await getOrInitializeCache ( options as CachedFunctionInitializerOptions ) ;
5365
5466 const cacheValue = await cache . get < ReturnType < F > > ( cacheKey ) ;
55- if ( cacheValue !== undefined ) {
67+ if ( ! cacheOptions . force && cacheValue !== undefined ) {
5668 return cacheValue ;
5769 }
5870
5971 const result = await function_ ( ...arguments_ ) as ReturnType < F > ;
60- await cache . set ( cacheKey , result , options . ttl ) ;
72+ await cache . set ( cacheKey , result , cacheOptions . ttl ) ;
6173
6274 return result ;
6375 } ;
6476}
6577
66- export function cacheKeys < F extends AnyFunction > ( function_ : F , ...selector : Array < ArgumentPaths < F > > ) {
67- const selectors = _ ( selector ) . flatMap ( ) . value ( ) ;
68- function_ . cacheKeys = selectors ;
69- return function_ ;
78+ // eslint-disable-next-line @typescript-eslint/naming-convention
79+ export function CacheOptions < F extends CacheableFunction > (
80+ selectorOrOptions : ArgumentPaths < F > | CachedFunctionOptions < F > ,
81+ ttl ?: number ,
82+ ) {
83+ const options = ( _ . isArrayLike ( selectorOrOptions ) || _ . isString ( selectorOrOptions ) )
84+ ? { selector : selectorOrOptions , ttl}
85+ : selectorOrOptions as CachedFunctionOptions < F > ;
86+
87+ return (
88+ _target : any ,
89+ _propertyKey : string | symbol ,
90+ descriptor : TypedPropertyDescriptor < F > ,
91+ ) : any => {
92+ if ( ! descriptor . value ) {
93+ return ;
94+ }
95+
96+ descriptor . value . cacheOptions = options ;
97+ return descriptor ;
98+ } ;
7099}
0 commit comments