@node-ts-cache/core 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +763 -0
- package/dist/decorator/cache.decorator.d.ts +7 -0
- package/dist/decorator/cache.decorator.js +63 -0
- package/dist/decorator/cache.decorator.js.map +1 -0
- package/dist/decorator/multicache.decorator.d.ts +8 -0
- package/dist/decorator/multicache.decorator.js +110 -0
- package/dist/decorator/multicache.decorator.js.map +1 -0
- package/dist/decorator/synccache.decorator.d.ts +3 -0
- package/dist/decorator/synccache.decorator.js +43 -0
- package/dist/decorator/synccache.decorator.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/storage/fs/fs.json.storage.d.ts +11 -0
- package/dist/storage/fs/fs.json.storage.js +47 -0
- package/dist/storage/fs/fs.json.storage.js.map +1 -0
- package/dist/storage/fs/index.d.ts +1 -0
- package/dist/storage/fs/index.js +2 -0
- package/dist/storage/fs/index.js.map +1 -0
- package/dist/storage/memory/index.d.ts +1 -0
- package/dist/storage/memory/index.js +2 -0
- package/dist/storage/memory/index.js.map +1 -0
- package/dist/storage/memory/memory.storage.d.ts +7 -0
- package/dist/storage/memory/memory.storage.js +15 -0
- package/dist/storage/memory/memory.storage.js.map +1 -0
- package/dist/strategy/caching/abstract.base.strategy.d.ts +8 -0
- package/dist/strategy/caching/abstract.base.strategy.js +6 -0
- package/dist/strategy/caching/abstract.base.strategy.js.map +1 -0
- package/dist/strategy/caching/expiration.strategy.d.ts +11 -0
- package/dist/strategy/caching/expiration.strategy.js +43 -0
- package/dist/strategy/caching/expiration.strategy.js.map +1 -0
- package/dist/strategy/key/json.stringify.strategy.d.ts +4 -0
- package/dist/strategy/key/json.stringify.strategy.js +6 -0
- package/dist/strategy/key/json.stringify.strategy.js.map +1 -0
- package/dist/types/cache.types.d.ts +57 -0
- package/dist/types/cache.types.js +2 -0
- package/dist/types/cache.types.js.map +1 -0
- package/dist/types/key.strategy.types.d.ts +6 -0
- package/dist/types/key.strategy.types.js +2 -0
- package/dist/types/key.strategy.types.js.map +1 -0
- package/package.json +58 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { IAsyncKeyStrategy } from '../types/key.strategy.types.js';
|
|
2
|
+
import { IAsynchronousCacheType, ISynchronousCacheType, ICacheOptions } from '../types/cache.types.js';
|
|
3
|
+
export declare function Cache(cachingStrategy: IAsynchronousCacheType | ISynchronousCacheType, options?: ICacheOptions, keyStrategy?: IAsyncKeyStrategy): (target: Object & {
|
|
4
|
+
__cache_decarator_pending_results?: {
|
|
5
|
+
[key: string]: Promise<unknown> | undefined;
|
|
6
|
+
} | undefined;
|
|
7
|
+
}, methodName: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { JSONStringifyKeyStrategy } from '../strategy/key/json.stringify.strategy.js';
|
|
2
|
+
const defaultKeyStrategy = new JSONStringifyKeyStrategy();
|
|
3
|
+
export function Cache(cachingStrategy, options, keyStrategy = defaultKeyStrategy) {
|
|
4
|
+
return function (
|
|
5
|
+
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
6
|
+
target, methodName, descriptor) {
|
|
7
|
+
const originalMethod = descriptor.value;
|
|
8
|
+
const className = target.constructor.name;
|
|
9
|
+
descriptor.value = async function (...args) {
|
|
10
|
+
const cacheKey = await keyStrategy.getKey(className, methodName, args);
|
|
11
|
+
const runMethod = async () => {
|
|
12
|
+
const methodCall = originalMethod.apply(this, args);
|
|
13
|
+
let methodResult;
|
|
14
|
+
const isAsync = methodCall?.constructor?.name === 'AsyncFunction' ||
|
|
15
|
+
methodCall?.constructor?.name === 'Promise';
|
|
16
|
+
if (isAsync) {
|
|
17
|
+
methodResult = await methodCall;
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
methodResult = methodCall;
|
|
21
|
+
}
|
|
22
|
+
return methodResult;
|
|
23
|
+
};
|
|
24
|
+
if (!cacheKey || process.env.DISABLE_CACHE_DECORATOR) {
|
|
25
|
+
// do not cache this function, execute function
|
|
26
|
+
return runMethod();
|
|
27
|
+
}
|
|
28
|
+
if (!target.__cache_decarator_pending_results) {
|
|
29
|
+
target.__cache_decarator_pending_results = {};
|
|
30
|
+
}
|
|
31
|
+
if (!target.__cache_decarator_pending_results[cacheKey]) {
|
|
32
|
+
target.__cache_decarator_pending_results[cacheKey] = (async () => {
|
|
33
|
+
try {
|
|
34
|
+
try {
|
|
35
|
+
const entry = await cachingStrategy.getItem(cacheKey);
|
|
36
|
+
if (entry !== undefined) {
|
|
37
|
+
return entry;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
catch (err) {
|
|
41
|
+
console.warn('@node-ts-cache/core: reading cache failed', cacheKey, err);
|
|
42
|
+
}
|
|
43
|
+
const methodResult = await runMethod();
|
|
44
|
+
try {
|
|
45
|
+
await cachingStrategy.setItem(cacheKey, methodResult, options);
|
|
46
|
+
}
|
|
47
|
+
catch (err) {
|
|
48
|
+
console.warn('@node-ts-cache/core: writing result to cache failed', cacheKey, err);
|
|
49
|
+
}
|
|
50
|
+
return methodResult;
|
|
51
|
+
}
|
|
52
|
+
finally {
|
|
53
|
+
// reset pending result object
|
|
54
|
+
target.__cache_decarator_pending_results[cacheKey] = undefined;
|
|
55
|
+
}
|
|
56
|
+
})();
|
|
57
|
+
}
|
|
58
|
+
return target.__cache_decarator_pending_results[cacheKey];
|
|
59
|
+
};
|
|
60
|
+
return descriptor;
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=cache.decorator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.decorator.js","sourceRoot":"","sources":["../../src/decorator/cache.decorator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,4CAA4C,CAAC;AAQtF,MAAM,kBAAkB,GAAG,IAAI,wBAAwB,EAAE,CAAC;AAE1D,MAAM,UAAU,KAAK,CACpB,eAA+D,EAC/D,OAAuB,EACvB,cAAiC,kBAAkB;IAEnD,OAAO;IACN,wDAAwD;IACxD,MAIC,EACD,UAAkB,EAClB,UAA8B;QAE9B,MAAM,cAAc,GAAG,UAAU,CAAC,KAAK,CAAC;QACxC,MAAM,SAAS,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC;QAE1C,UAAU,CAAC,KAAK,GAAG,KAAK,WAAW,GAAG,IAAe;YACpD,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,MAAM,CAAC,SAAS,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC;YAEvE,MAAM,SAAS,GAAG,KAAK,IAAI,EAAE;gBAC5B,MAAM,UAAU,GAAG,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;gBAEpD,IAAI,YAAY,CAAC;gBAEjB,MAAM,OAAO,GACZ,UAAU,EAAE,WAAW,EAAE,IAAI,KAAK,eAAe;oBACjD,UAAU,EAAE,WAAW,EAAE,IAAI,KAAK,SAAS,CAAC;gBAC7C,IAAI,OAAO,EAAE;oBACZ,YAAY,GAAG,MAAM,UAAU,CAAC;iBAChC;qBAAM;oBACN,YAAY,GAAG,UAAU,CAAC;iBAC1B;gBACD,OAAO,YAAY,CAAC;YACrB,CAAC,CAAC;YAEF,IAAI,CAAC,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,uBAAuB,EAAE;gBACrD,+CAA+C;gBAC/C,OAAO,SAAS,EAAE,CAAC;aACnB;YAED,IAAI,CAAC,MAAM,CAAC,iCAAiC,EAAE;gBAC9C,MAAM,CAAC,iCAAiC,GAAG,EAAE,CAAC;aAC9C;YAED,IAAI,CAAC,MAAM,CAAC,iCAAiC,CAAC,QAAQ,CAAC,EAAE;gBACxD,MAAM,CAAC,iCAAiC,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE;oBAChE,IAAI;wBACH,IAAI;4BACH,MAAM,KAAK,GAAG,MAAM,eAAe,CAAC,OAAO,CAAU,QAAQ,CAAC,CAAC;4BAC/D,IAAI,KAAK,KAAK,SAAS,EAAE;gCACxB,OAAO,KAAK,CAAC;6BACb;yBACD;wBAAC,OAAO,GAAG,EAAE;4BACb,OAAO,CAAC,IAAI,CAAC,2CAA2C,EAAE,QAAQ,EAAE,GAAG,CAAC,CAAC;yBACzE;wBAED,MAAM,YAAY,GAAG,MAAM,SAAS,EAAE,CAAC;wBAEvC,IAAI;4BACH,MAAM,eAAe,CAAC,OAAO,CAAC,QAAQ,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC;yBAC/D;wBAAC,OAAO,GAAG,EAAE;4BACb,OAAO,CAAC,IAAI,CAAC,qDAAqD,EAAE,QAAQ,EAAE,GAAG,CAAC,CAAC;yBACnF;wBACD,OAAO,YAAY,CAAC;qBACpB;4BAAS;wBACT,8BAA8B;wBAC9B,MAAM,CAAC,iCAAkC,CAAC,QAAQ,CAAC,GAAG,SAAS,CAAC;qBAChE;gBACF,CAAC,CAAC,EAAE,CAAC;aACL;YAED,OAAO,MAAM,CAAC,iCAAiC,CAAC,QAAQ,CAAC,CAAC;QAC3D,CAAC,CAAC;QAEF,OAAO,UAAU,CAAC;IACnB,CAAC,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { IMultiIAsynchronousCacheType, IMultiSynchronousCacheType } from '../types/cache.types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Key strategy interface for multi-cache operations
|
|
4
|
+
*/
|
|
5
|
+
export interface IMultiCacheKeyStrategy {
|
|
6
|
+
getKey(className: string, methodName: string, parameter: unknown, args: unknown[], phase: 'read' | 'write'): string | undefined;
|
|
7
|
+
}
|
|
8
|
+
export declare function MultiCache(cachingStrategies: (IMultiIAsynchronousCacheType | IMultiSynchronousCacheType)[], parameterIndex?: number, keyStrategy?: IMultiCacheKeyStrategy): (target: Object, methodName: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
const defaultKeyStrategy = {
|
|
2
|
+
getKey(className, methodName, parameter, args, _phase) {
|
|
3
|
+
return `${className}:${methodName}:${JSON.stringify(parameter)}:${JSON.stringify(args)}`;
|
|
4
|
+
}
|
|
5
|
+
};
|
|
6
|
+
export function MultiCache(cachingStrategies, parameterIndex = 0, keyStrategy = defaultKeyStrategy) {
|
|
7
|
+
return function (
|
|
8
|
+
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
9
|
+
target, methodName, descriptor) {
|
|
10
|
+
const originalMethod = descriptor.value;
|
|
11
|
+
const className = target.constructor.name;
|
|
12
|
+
descriptor.value = async function (...args) {
|
|
13
|
+
const runMethod = async (newSet) => {
|
|
14
|
+
const newArgs = [...args];
|
|
15
|
+
newArgs[parameterIndex] = newSet;
|
|
16
|
+
const methodCall = originalMethod.apply(this, newArgs);
|
|
17
|
+
let methodResult;
|
|
18
|
+
const isAsync = methodCall?.constructor?.name === 'AsyncFunction' ||
|
|
19
|
+
methodCall?.constructor?.name === 'Promise';
|
|
20
|
+
if (isAsync) {
|
|
21
|
+
methodResult = await methodCall;
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
methodResult = methodCall;
|
|
25
|
+
}
|
|
26
|
+
return methodResult;
|
|
27
|
+
};
|
|
28
|
+
const parameters = args[parameterIndex];
|
|
29
|
+
const cacheKeys = parameters.map((parameter) => keyStrategy.getKey(className, methodName, parameter, args, 'read'));
|
|
30
|
+
let result = [];
|
|
31
|
+
if (!process.env.DISABLE_CACHE_DECORATOR) {
|
|
32
|
+
let currentCachingStrategy = 0;
|
|
33
|
+
do {
|
|
34
|
+
// console.log('cacheKeys', cacheKeys, currentCachingStrategy)
|
|
35
|
+
const foundEntries = await cachingStrategies[currentCachingStrategy].getItems(cacheKeys.filter((key) => key !== undefined));
|
|
36
|
+
// console.log('foundEntries', foundEntries);
|
|
37
|
+
// remove all found entries from cacheKeys
|
|
38
|
+
Object.keys(foundEntries).forEach(entry => {
|
|
39
|
+
if (foundEntries[entry] === undefined)
|
|
40
|
+
return;
|
|
41
|
+
// remove entry from cacheKey
|
|
42
|
+
cacheKeys[cacheKeys.indexOf(entry)] = undefined;
|
|
43
|
+
});
|
|
44
|
+
// save back to strategies before this strategy
|
|
45
|
+
if (currentCachingStrategy > 0) {
|
|
46
|
+
const setCache = Object.keys(foundEntries)
|
|
47
|
+
.map(key => ({
|
|
48
|
+
key,
|
|
49
|
+
content: foundEntries[key]
|
|
50
|
+
}))
|
|
51
|
+
.filter(f => f.content !== undefined);
|
|
52
|
+
if (setCache.length > 0) {
|
|
53
|
+
let saveCurrentCachingStrategy = currentCachingStrategy - 1;
|
|
54
|
+
do {
|
|
55
|
+
await cachingStrategies[saveCurrentCachingStrategy].setItems(setCache);
|
|
56
|
+
saveCurrentCachingStrategy--;
|
|
57
|
+
} while (saveCurrentCachingStrategy >= 0);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
// save to final result
|
|
61
|
+
result = [...result, ...Object.values(foundEntries).filter(f => f !== undefined)];
|
|
62
|
+
// console.log('result', result);
|
|
63
|
+
currentCachingStrategy++;
|
|
64
|
+
} while (cacheKeys.filter(key => key !== undefined).length > 0 &&
|
|
65
|
+
currentCachingStrategy < cachingStrategies.length);
|
|
66
|
+
}
|
|
67
|
+
if (cacheKeys.filter(key => key !== undefined).length > 0) {
|
|
68
|
+
// use original method to resolve them
|
|
69
|
+
const missingKeys = cacheKeys
|
|
70
|
+
.map((key, i) => {
|
|
71
|
+
if (key !== undefined) {
|
|
72
|
+
return parameters[i];
|
|
73
|
+
}
|
|
74
|
+
return undefined;
|
|
75
|
+
})
|
|
76
|
+
.filter(k => k !== undefined);
|
|
77
|
+
const originalMethodResult = (await runMethod(missingKeys));
|
|
78
|
+
if (originalMethodResult.length !== missingKeys.length) {
|
|
79
|
+
throw new Error(`input and output has different size! input: ${cacheKeys.length}, returned ${originalMethodResult.length}`);
|
|
80
|
+
}
|
|
81
|
+
// console.log('originalMethodResult', originalMethodResult);
|
|
82
|
+
if (!process.env.DISABLE_CACHE_DECORATOR) {
|
|
83
|
+
// save back to all caching strategies
|
|
84
|
+
const saveToCache = originalMethodResult
|
|
85
|
+
.map((content, i) => {
|
|
86
|
+
const key = keyStrategy.getKey(className, methodName, missingKeys[i], args, 'write');
|
|
87
|
+
if (key === undefined) {
|
|
88
|
+
return undefined;
|
|
89
|
+
}
|
|
90
|
+
return {
|
|
91
|
+
key,
|
|
92
|
+
content
|
|
93
|
+
};
|
|
94
|
+
})
|
|
95
|
+
.filter((f) => f !== undefined);
|
|
96
|
+
// console.log('saveToCache', saveToCache);
|
|
97
|
+
let saveCurrentCachingStrategy = cachingStrategies.length - 1;
|
|
98
|
+
do {
|
|
99
|
+
await cachingStrategies[saveCurrentCachingStrategy].setItems(saveToCache);
|
|
100
|
+
saveCurrentCachingStrategy--;
|
|
101
|
+
} while (saveCurrentCachingStrategy >= 0);
|
|
102
|
+
}
|
|
103
|
+
result = [...result, ...originalMethodResult];
|
|
104
|
+
}
|
|
105
|
+
return result;
|
|
106
|
+
};
|
|
107
|
+
return descriptor;
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=multicache.decorator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"multicache.decorator.js","sourceRoot":"","sources":["../../src/decorator/multicache.decorator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { ISyncKeyStrategy } from '../types/key.strategy.types.js';
|
|
2
|
+
import { ISynchronousCacheType, ICacheOptions } from '../types/cache.types.js';
|
|
3
|
+
export declare function SyncCache(cachingStrategy: ISynchronousCacheType, options?: ICacheOptions, keyStrategy?: ISyncKeyStrategy): (target: Object, methodName: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { JSONStringifyKeyStrategy } from '../strategy/key/json.stringify.strategy.js';
|
|
2
|
+
const defaultKeyStrategy = new JSONStringifyKeyStrategy();
|
|
3
|
+
export function SyncCache(cachingStrategy, options, keyStrategy = defaultKeyStrategy) {
|
|
4
|
+
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
5
|
+
return function (target, methodName, descriptor) {
|
|
6
|
+
const originalMethod = descriptor.value;
|
|
7
|
+
const className = target.constructor.name;
|
|
8
|
+
descriptor.value = function (...args) {
|
|
9
|
+
const runMethod = () => {
|
|
10
|
+
const methodResult = originalMethod.apply(this, args);
|
|
11
|
+
const isAsync = methodResult?.constructor?.name === 'AsyncFunction' ||
|
|
12
|
+
methodResult?.constructor?.name === 'Promise';
|
|
13
|
+
if (isAsync) {
|
|
14
|
+
throw new Error('async function detected, use @Cache instead');
|
|
15
|
+
}
|
|
16
|
+
return methodResult;
|
|
17
|
+
};
|
|
18
|
+
const cacheKey = keyStrategy.getKey(className, methodName, args);
|
|
19
|
+
if (!cacheKey) {
|
|
20
|
+
return runMethod();
|
|
21
|
+
}
|
|
22
|
+
try {
|
|
23
|
+
const entry = cachingStrategy.getItem(cacheKey);
|
|
24
|
+
if (entry !== undefined) {
|
|
25
|
+
return entry;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
catch (err) {
|
|
29
|
+
console.warn('@node-ts-cache/core: reading cache failed', cacheKey, err);
|
|
30
|
+
}
|
|
31
|
+
const methodResult = runMethod();
|
|
32
|
+
try {
|
|
33
|
+
cachingStrategy.setItem(cacheKey, methodResult, options);
|
|
34
|
+
}
|
|
35
|
+
catch (err) {
|
|
36
|
+
console.warn('@node-ts-cache/core: writing result to cache failed', cacheKey, err);
|
|
37
|
+
}
|
|
38
|
+
return methodResult;
|
|
39
|
+
};
|
|
40
|
+
return descriptor;
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=synccache.decorator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"synccache.decorator.js","sourceRoot":"","sources":["../../src/decorator/synccache.decorator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,4CAA4C,CAAC;AAItF,MAAM,kBAAkB,GAAG,IAAI,wBAAwB,EAAE,CAAC;AAE1D,MAAM,UAAU,SAAS,CACxB,eAAsC,EACtC,OAAuB,EACvB,cAAgC,kBAAkB;IAElD,wDAAwD;IACxD,OAAO,UAAU,MAAc,EAAE,UAAkB,EAAE,UAA8B;QAClF,MAAM,cAAc,GAAG,UAAU,CAAC,KAAK,CAAC;QACxC,MAAM,SAAS,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC;QAE1C,UAAU,CAAC,KAAK,GAAG,UAAU,GAAG,IAAe;YAC9C,MAAM,SAAS,GAAG,GAAG,EAAE;gBACtB,MAAM,YAAY,GAAG,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;gBAEtD,MAAM,OAAO,GACZ,YAAY,EAAE,WAAW,EAAE,IAAI,KAAK,eAAe;oBACnD,YAAY,EAAE,WAAW,EAAE,IAAI,KAAK,SAAS,CAAC;gBAE/C,IAAI,OAAO,EAAE;oBACZ,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;iBAC/D;gBAED,OAAO,YAAY,CAAC;YACrB,CAAC,CAAC;YAEF,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,CAAC,SAAS,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC;YAEjE,IAAI,CAAC,QAAQ,EAAE;gBACd,OAAO,SAAS,EAAE,CAAC;aACnB;YAED,IAAI;gBACH,MAAM,KAAK,GAAG,eAAe,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;gBAChD,IAAI,KAAK,KAAK,SAAS,EAAE;oBACxB,OAAO,KAAK,CAAC;iBACb;aACD;YAAC,OAAO,GAAG,EAAE;gBACb,OAAO,CAAC,IAAI,CAAC,2CAA2C,EAAE,QAAQ,EAAE,GAAG,CAAC,CAAC;aACzE;YACD,MAAM,YAAY,GAAG,SAAS,EAAE,CAAC;YAEjC,IAAI;gBACH,eAAe,CAAC,OAAO,CAAC,QAAQ,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC;aACzD;YAAC,OAAO,GAAG,EAAE;gBACb,OAAO,CAAC,IAAI,CAAC,qDAAqD,EAAE,QAAQ,EAAE,GAAG,CAAC,CAAC;aACnF;YACD,OAAO,YAAY,CAAC;QACrB,CAAC,CAAC;QAEF,OAAO,UAAU,CAAC;IACnB,CAAC,CAAC;AACH,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { ISynchronousCacheType, IAsynchronousCacheType, IMultiIAsynchronousCacheType, IMultiSynchronousCacheType } from './types/cache.types.js';
|
|
2
|
+
export { ExpirationStrategy } from './strategy/caching/expiration.strategy.js';
|
|
3
|
+
export { ISyncKeyStrategy, IAsyncKeyStrategy } from './types/key.strategy.types.js';
|
|
4
|
+
export { Cache } from './decorator/cache.decorator.js';
|
|
5
|
+
export { SyncCache } from './decorator/synccache.decorator.js';
|
|
6
|
+
export { MultiCache } from './decorator/multicache.decorator.js';
|
|
7
|
+
export { FsJsonStorage } from './storage/fs/index.js';
|
|
8
|
+
export { MemoryStorage } from './storage/memory/index.js';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { ExpirationStrategy } from './strategy/caching/expiration.strategy.js';
|
|
2
|
+
export { Cache } from './decorator/cache.decorator.js';
|
|
3
|
+
export { SyncCache } from './decorator/synccache.decorator.js';
|
|
4
|
+
export { MultiCache } from './decorator/multicache.decorator.js';
|
|
5
|
+
export { FsJsonStorage } from './storage/fs/index.js';
|
|
6
|
+
export { MemoryStorage } from './storage/memory/index.js';
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,kBAAkB,EAAE,MAAM,2CAA2C,CAAC;AAE/E,OAAO,EAAE,KAAK,EAAE,MAAM,gCAAgC,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,oCAAoC,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,MAAM,qCAAqC,CAAC;AAEjE,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { IAsynchronousCacheType } from '../../types/cache.types.js';
|
|
2
|
+
export declare class FsJsonStorage implements IAsynchronousCacheType {
|
|
3
|
+
jsonFilePath: string;
|
|
4
|
+
constructor(jsonFilePath: string);
|
|
5
|
+
getItem<T>(key: string): Promise<T | undefined>;
|
|
6
|
+
setItem<T = unknown>(key: string, content: T | undefined): Promise<void>;
|
|
7
|
+
clear(): Promise<void>;
|
|
8
|
+
private createEmptyCache;
|
|
9
|
+
private setCache;
|
|
10
|
+
private getCacheObject;
|
|
11
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { existsSync, writeFileSync, writeFile, readFile } from 'fs';
|
|
2
|
+
export class FsJsonStorage {
|
|
3
|
+
constructor(jsonFilePath) {
|
|
4
|
+
this.jsonFilePath = jsonFilePath;
|
|
5
|
+
if (!existsSync(this.jsonFilePath)) {
|
|
6
|
+
this.createEmptyCache();
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
async getItem(key) {
|
|
10
|
+
return (await this.getCacheObject())[key];
|
|
11
|
+
}
|
|
12
|
+
async setItem(key, content) {
|
|
13
|
+
const cache = await this.getCacheObject();
|
|
14
|
+
cache[key] = content;
|
|
15
|
+
await this.setCache(cache);
|
|
16
|
+
}
|
|
17
|
+
async clear() {
|
|
18
|
+
await this.createEmptyCache();
|
|
19
|
+
}
|
|
20
|
+
createEmptyCache() {
|
|
21
|
+
writeFileSync(this.jsonFilePath, JSON.stringify({}));
|
|
22
|
+
}
|
|
23
|
+
async setCache(newCache) {
|
|
24
|
+
await new Promise((resolve, reject) => {
|
|
25
|
+
writeFile(this.jsonFilePath, JSON.stringify(newCache), err => {
|
|
26
|
+
if (err) {
|
|
27
|
+
reject(err);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
resolve();
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
async getCacheObject() {
|
|
35
|
+
const fileContent = await new Promise((resolve, reject) => {
|
|
36
|
+
readFile(this.jsonFilePath, (err, result) => {
|
|
37
|
+
if (err) {
|
|
38
|
+
reject(err);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
resolve(result);
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
return JSON.parse(fileContent.toString());
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=fs.json.storage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fs.json.storage.js","sourceRoot":"","sources":["../../../src/storage/fs/fs.json.storage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;AAKpE,MAAM,OAAO,aAAa;IACzB,YAAmB,YAAoB;QAApB,iBAAY,GAAZ,YAAY,CAAQ;QACtC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE;YACnC,IAAI,CAAC,gBAAgB,EAAE,CAAC;SACxB;IACF,CAAC;IAEM,KAAK,CAAC,OAAO,CAAI,GAAW;QAClC,OAAO,CAAC,MAAM,IAAI,CAAC,cAAc,EAAE,CAAC,CAAC,GAAG,CAAkB,CAAC;IAC5D,CAAC;IAEM,KAAK,CAAC,OAAO,CAAc,GAAW,EAAE,OAAsB;QACpE,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,cAAc,EAAE,CAAC;QAC1C,KAAK,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC;QACrB,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC5B,CAAC;IAEM,KAAK,CAAC,KAAK;QACjB,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC;IAC/B,CAAC;IAEO,gBAAgB;QACvB,aAAa,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC;IACtD,CAAC;IAEO,KAAK,CAAC,QAAQ,CAAC,QAAqB;QAC3C,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC3C,SAAS,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,GAAG,CAAC,EAAE;gBAC5D,IAAI,GAAG,EAAE;oBACR,MAAM,CAAC,GAAG,CAAC,CAAC;oBACZ,OAAO;iBACP;gBACD,OAAO,EAAE,CAAC;YACX,CAAC,CAAC,CAAC;QACJ,CAAC,CAAC,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,cAAc;QAC3B,MAAM,WAAW,GAAW,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACjE,QAAQ,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE;gBAC3C,IAAI,GAAG,EAAE;oBACR,MAAM,CAAC,GAAG,CAAC,CAAC;oBACZ,OAAO;iBACP;gBACD,OAAO,CAAC,MAAM,CAAC,CAAC;YACjB,CAAC,CAAC,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,OAAO,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAgB,CAAC;IAC1D,CAAC;CACD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { FsJsonStorage } from './fs.json.storage.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/storage/fs/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { MemoryStorage } from './memory.storage.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/storage/memory/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ISynchronousCacheType } from '../../types/cache.types.js';
|
|
2
|
+
export declare class MemoryStorage implements ISynchronousCacheType {
|
|
3
|
+
private memCache;
|
|
4
|
+
getItem<T>(key: string): T | undefined;
|
|
5
|
+
setItem<T = unknown>(key: string, content: T | undefined): void;
|
|
6
|
+
clear(): void;
|
|
7
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export class MemoryStorage {
|
|
2
|
+
constructor() {
|
|
3
|
+
this.memCache = {};
|
|
4
|
+
}
|
|
5
|
+
getItem(key) {
|
|
6
|
+
return this.memCache[key];
|
|
7
|
+
}
|
|
8
|
+
setItem(key, content) {
|
|
9
|
+
this.memCache[key] = content;
|
|
10
|
+
}
|
|
11
|
+
clear() {
|
|
12
|
+
this.memCache = {};
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=memory.storage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory.storage.js","sourceRoot":"","sources":["../../../src/storage/memory/memory.storage.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,aAAa;IAA1B;QACS,aAAQ,GAA4B,EAAE,CAAC;IAahD,CAAC;IAXO,OAAO,CAAI,GAAW;QAC5B,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAkB,CAAC;IAC5C,CAAC;IAEM,OAAO,CAAc,GAAW,EAAE,OAAsB;QAC9D,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC;IAC9B,CAAC;IAEM,KAAK;QACX,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;IACpB,CAAC;CACD"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { IAsynchronousCacheType, ISynchronousCacheType, ICacheOptions } from '../../types/cache.types.js';
|
|
2
|
+
export declare abstract class AbstractBaseStrategy implements IAsynchronousCacheType {
|
|
3
|
+
protected storage: IAsynchronousCacheType | ISynchronousCacheType;
|
|
4
|
+
constructor(storage: IAsynchronousCacheType | ISynchronousCacheType);
|
|
5
|
+
abstract getItem<T>(key: string): Promise<T | undefined>;
|
|
6
|
+
abstract setItem<T = unknown>(key: string, content: T | undefined, options?: ICacheOptions): Promise<void>;
|
|
7
|
+
abstract clear(): Promise<void>;
|
|
8
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"abstract.base.strategy.js","sourceRoot":"","sources":["../../../src/strategy/caching/abstract.base.strategy.ts"],"names":[],"mappings":"AAMA,MAAM,OAAgB,oBAAoB;IACzC,YAAsB,OAAuD;QAAvD,YAAO,GAAP,OAAO,CAAgD;IAAG,CAAC;CAWjF"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { AbstractBaseStrategy } from './abstract.base.strategy.js';
|
|
2
|
+
import { ICacheOptions } from '../../types/cache.types.js';
|
|
3
|
+
export declare class ExpirationStrategy extends AbstractBaseStrategy {
|
|
4
|
+
getItem<T>(key: string): Promise<T | undefined>;
|
|
5
|
+
/** Type guard to check if item has valid meta with ttl */
|
|
6
|
+
private hasValidMeta;
|
|
7
|
+
setItem<T = unknown>(key: string, content: T | undefined, options?: ICacheOptions): Promise<void>;
|
|
8
|
+
clear(): Promise<void>;
|
|
9
|
+
private isItemExpired;
|
|
10
|
+
private unsetKey;
|
|
11
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { AbstractBaseStrategy } from './abstract.base.strategy.js';
|
|
2
|
+
export class ExpirationStrategy extends AbstractBaseStrategy {
|
|
3
|
+
async getItem(key) {
|
|
4
|
+
const item = await this.storage.getItem(key);
|
|
5
|
+
if (item && this.hasValidMeta(item) && this.isItemExpired(item)) {
|
|
6
|
+
await this.storage.setItem(key, undefined);
|
|
7
|
+
return undefined;
|
|
8
|
+
}
|
|
9
|
+
return item ? item.content : undefined;
|
|
10
|
+
}
|
|
11
|
+
/** Type guard to check if item has valid meta with ttl */
|
|
12
|
+
hasValidMeta(item) {
|
|
13
|
+
return item.meta !== false && typeof item.meta.ttl === 'number';
|
|
14
|
+
}
|
|
15
|
+
async setItem(key, content, options) {
|
|
16
|
+
const mergedOptions = {
|
|
17
|
+
ttl: 60,
|
|
18
|
+
isLazy: true,
|
|
19
|
+
isCachedForever: false,
|
|
20
|
+
...options
|
|
21
|
+
};
|
|
22
|
+
const meta = !mergedOptions.isCachedForever && {
|
|
23
|
+
ttl: mergedOptions.ttl * 1000,
|
|
24
|
+
createdAt: Date.now()
|
|
25
|
+
};
|
|
26
|
+
if (meta && !mergedOptions.isLazy) {
|
|
27
|
+
setTimeout(() => {
|
|
28
|
+
this.unsetKey(key);
|
|
29
|
+
}, meta.ttl);
|
|
30
|
+
}
|
|
31
|
+
await this.storage.setItem(key, { meta, content });
|
|
32
|
+
}
|
|
33
|
+
async clear() {
|
|
34
|
+
await this.storage.clear();
|
|
35
|
+
}
|
|
36
|
+
isItemExpired(item) {
|
|
37
|
+
return Date.now() > item.meta.createdAt + item.meta.ttl;
|
|
38
|
+
}
|
|
39
|
+
async unsetKey(key) {
|
|
40
|
+
await this.storage.setItem(key, undefined);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=expiration.strategy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expiration.strategy.js","sourceRoot":"","sources":["../../../src/strategy/caching/expiration.strategy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAoBnE,MAAM,OAAO,kBAAmB,SAAQ,oBAAoB;IACpD,KAAK,CAAC,OAAO,CAAI,GAAW;QAClC,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAwB,GAAG,CAAC,CAAC;QACpE,IAAI,IAAI,IAAI,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE;YAChE,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;YAC3C,OAAO,SAAS,CAAC;SACjB;QACD,OAAO,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;IACxC,CAAC;IAED,0DAA0D;IAClD,YAAY,CACnB,IAAiC;QAEjC,OAAO,IAAI,CAAC,IAAI,KAAK,KAAK,IAAI,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,KAAK,QAAQ,CAAC;IACjE,CAAC;IAEM,KAAK,CAAC,OAAO,CACnB,GAAW,EACX,OAAsB,EACtB,OAAuB;QAEvB,MAAM,aAAa,GAAuB;YACzC,GAAG,EAAE,EAAE;YACP,MAAM,EAAE,IAAI;YACZ,eAAe,EAAE,KAAK;YACtB,GAAG,OAAO;SACV,CAAC;QAEF,MAAM,IAAI,GAAG,CAAC,aAAa,CAAC,eAAe,IAAI;YAC9C,GAAG,EAAE,aAAa,CAAC,GAAG,GAAG,IAAI;YAC7B,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;SACrB,CAAC;QAEF,IAAI,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE;YAClC,UAAU,CAAC,GAAG,EAAE;gBACf,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;YACpB,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;SACb;QACD,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;IACpD,CAAC;IAEM,KAAK,CAAC,KAAK;QACjB,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;IAC5B,CAAC;IAEO,aAAa,CAAC,IAAsC;QAC3D,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;IACzD,CAAC;IAEO,KAAK,CAAC,QAAQ,CAAC,GAAW;QACjC,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IAC5C,CAAC;CACD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json.stringify.strategy.js","sourceRoot":"","sources":["../../../src/strategy/key/json.stringify.strategy.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,wBAAwB;IAC7B,MAAM,CAAC,SAAiB,EAAE,UAAkB,EAAE,IAAe;QACnE,OAAO,GAAG,SAAS,IAAI,UAAU,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;IAC7D,CAAC;CACD"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cache options for setting items
|
|
3
|
+
*/
|
|
4
|
+
export interface ICacheOptions {
|
|
5
|
+
/** Time to live in seconds */
|
|
6
|
+
ttl?: number;
|
|
7
|
+
/** If true, expiration check happens only on read */
|
|
8
|
+
isLazy?: boolean;
|
|
9
|
+
/** If true, item never expires */
|
|
10
|
+
isCachedForever?: boolean;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Metadata stored with cache entries
|
|
14
|
+
*/
|
|
15
|
+
export interface ICacheMeta {
|
|
16
|
+
/** Timestamp when the item was created */
|
|
17
|
+
createdAt?: number;
|
|
18
|
+
/** Time to live in milliseconds */
|
|
19
|
+
ttl?: number;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Structure of a cache entry
|
|
23
|
+
*/
|
|
24
|
+
export interface ICacheEntry<T = unknown, M extends ICacheMeta = ICacheMeta> {
|
|
25
|
+
content: T;
|
|
26
|
+
meta: M | false;
|
|
27
|
+
}
|
|
28
|
+
export interface IMultiIAsynchronousCacheType<C = unknown> {
|
|
29
|
+
getItems<T>(keys: string[]): Promise<{
|
|
30
|
+
[key: string]: T | undefined;
|
|
31
|
+
}>;
|
|
32
|
+
setItems<T extends C = C>(values: {
|
|
33
|
+
key: string;
|
|
34
|
+
content: T | undefined;
|
|
35
|
+
}[], options?: ICacheOptions): Promise<void>;
|
|
36
|
+
clear(): Promise<void>;
|
|
37
|
+
}
|
|
38
|
+
export interface IMultiSynchronousCacheType<C = unknown> {
|
|
39
|
+
getItems<T>(keys: string[]): {
|
|
40
|
+
[key: string]: T | undefined;
|
|
41
|
+
};
|
|
42
|
+
setItems<T extends C = C>(values: {
|
|
43
|
+
key: string;
|
|
44
|
+
content: T | undefined;
|
|
45
|
+
}[], options?: ICacheOptions): void;
|
|
46
|
+
clear(): void;
|
|
47
|
+
}
|
|
48
|
+
export interface IAsynchronousCacheType<C = unknown> {
|
|
49
|
+
getItem<T>(key: string): Promise<T | undefined>;
|
|
50
|
+
setItem<T extends C = C>(key: string, content: T | undefined, options?: ICacheOptions): Promise<void>;
|
|
51
|
+
clear(): Promise<void>;
|
|
52
|
+
}
|
|
53
|
+
export interface ISynchronousCacheType<C = unknown> {
|
|
54
|
+
getItem<T>(key: string): T | undefined;
|
|
55
|
+
setItem<T extends C = C>(key: string, content: T | undefined, options?: ICacheOptions): void;
|
|
56
|
+
clear(): void;
|
|
57
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.types.js","sourceRoot":"","sources":["../../src/types/cache.types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export interface ISyncKeyStrategy {
|
|
2
|
+
getKey(className: string, methodName: string, args: unknown[]): string | undefined;
|
|
3
|
+
}
|
|
4
|
+
export interface IAsyncKeyStrategy {
|
|
5
|
+
getKey(className: string, methodName: string, args: unknown[]): Promise<string | undefined> | string | undefined;
|
|
6
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"key.strategy.types.js","sourceRoot":"","sources":["../../src/types/key.strategy.types.ts"],"names":[],"mappings":""}
|