Skip to content

Commit 64bf9ab

Browse files
committed
feat: Refactor cachedFunction to use selectorToCacheKey
1 parent 91c2b9b commit 64bf9ab

File tree

5 files changed

+330
-111
lines changed

5 files changed

+330
-111
lines changed

src/index.d.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export type CachedFunctionInitializerOptions =
99
{store: FactoryStore; config: FactoryConfig} |
1010
{store: Store};
1111

12-
export type CachedFunctionOptions<F extends AnyFunction> =
13-
CachedFunctionInitializerOptions &
14-
{selector?: ArgumentPaths<F>; ttl?: number};
12+
export type CachedFunctionOptions<F extends AnyFunction> = CachedFunctionInitializerOptions & {
13+
selector: ArgumentPaths<F>;
14+
ttl?: number;
15+
};

src/index.ts

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,59 @@
1-
21
import _ from 'lodash';
32
import {type Cache, caching} from 'cache-manager';
43
import type {CachedFunctionInitializerOptions, CachedFunctionOptions} from './index.d';
54
import type {AnyFunction, ArgumentPaths} from './paths.d';
65

76
let cache: Cache | undefined;
87

9-
export async function getOrInitializeCache(options: CachedFunctionInitializerOptions) {
10-
if (!('store' in options)) {
8+
export async function initializeCache(options?: CachedFunctionInitializerOptions) {
9+
if (!cache && !options) {
10+
throw new Error('cache is not initialized and no options provided');
11+
}
12+
13+
if (options && !('store' in options)) {
1114
throw new Error('store is required');
1215
}
1316

14-
cache ||= await ('config' in options ? caching(options.store, options.config) : caching(options.store));
17+
cache ||= await ('config' in options! ? caching(options.store, options.config) : caching(options!.store));
1518
return cache;
1619
}
1720

21+
export function resetCache() {
22+
cache = undefined;
23+
}
24+
1825
export function selectorToCacheKey<F extends AnyFunction>(arguments_: Parameters<F>, selector: ArgumentPaths<F>) {
1926
const selectors = _.castArray(selector);
20-
const values = _.at(arguments_, selectors);
27+
const values = selectors.map(path => {
28+
const value = _.get(arguments_, path) as unknown;
29+
if (value === undefined) {
30+
throw new Error(`Path "${path}" does not exist in the provided arguments.`);
31+
}
32+
33+
if (typeof value === 'function' || value instanceof Function) {
34+
throw new TypeError(`Path "${path}" points to a function, which is not serializable.`);
35+
}
36+
37+
return value;
38+
});
2139
const result = _.zipObject(selectors, values);
2240
return JSON.stringify(result);
2341
}
2442

2543
export function cachedFunction<F extends AnyFunction>(function_: F, options: CachedFunctionOptions<F>) {
26-
return (...arguments_: Parameters<F>): ReturnType<F> => {
44+
return async (...arguments_: Parameters<F>): Promise<ReturnType<F>> => {
2745
const cacheKey = selectorToCacheKey(arguments_, options.selector);
28-
console.log({cacheKey});
29-
return function_(...arguments_);
46+
47+
const cache = await initializeCache(options);
48+
49+
const cacheValue = await cache.get<ReturnType<F>>(cacheKey);
50+
if (cacheValue !== undefined) {
51+
return cacheValue;
52+
}
53+
54+
const result = await function_(...arguments_) as ReturnType<F>;
55+
await cache.set(cacheKey, result, options.ttl);
56+
57+
return result;
3058
};
3159
}

tests/cache.test.ts

Lines changed: 0 additions & 82 deletions
This file was deleted.

0 commit comments

Comments
 (0)