@podkopaev-tech/nest-infra-modules 0.0.6 → 0.0.9
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/dist/src/modules/cache/cache.module.d.ts +1 -1
- package/dist/src/modules/cache/cache.module.js +2 -1
- package/dist/src/modules/cache/cache.module.js.map +1 -1
- package/dist/src/modules/cache/cache.service.d.ts +11 -0
- package/dist/src/modules/cache/cache.service.js +133 -0
- package/dist/src/modules/cache/cache.service.js.map +1 -0
- package/dist/src/modules/cache/constant.d.ts +2 -0
- package/dist/src/modules/cache/constant.js +8 -0
- package/dist/src/modules/cache/constant.js.map +1 -0
- package/dist/src/modules/cache/decorators/memoize-async.decorator.d.ts +4 -16
- package/dist/src/modules/cache/decorators/memoize-async.decorator.js +5 -121
- package/dist/src/modules/cache/decorators/memoize-async.decorator.js.map +1 -1
- package/dist/src/modules/cache/types.d.ts +13 -1
- package/dist/src/modules/redis/redis.module.d.ts +2 -0
- package/dist/src/modules/redis/redis.module.js +2 -1
- package/dist/src/modules/redis/redis.module.js.map +1 -1
- package/dist/src/modules/redis/types.d.ts +7 -7
- package/dist/src/shared/types/class.types.d.ts +3 -0
- package/dist/src/shared/types/class.types.js +3 -0
- package/dist/src/shared/types/class.types.js.map +1 -0
- package/dist/src/shared/types/index.d.ts +1 -0
- package/dist/src/shared/types/index.js +18 -0
- package/dist/src/shared/types/index.js.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -2
|
@@ -2,6 +2,6 @@ import { DynamicModule } from '@nestjs/common';
|
|
|
2
2
|
import { CacheModuleOptions } from './types';
|
|
3
3
|
export declare class CacheModule {
|
|
4
4
|
static isEnabled: boolean;
|
|
5
|
-
static
|
|
5
|
+
static redisToken: string | symbol;
|
|
6
6
|
static forRootAsync(options: CacheModuleOptions): DynamicModule;
|
|
7
7
|
}
|
|
@@ -5,7 +5,8 @@ const cache_manager_1 = require("@nestjs/cache-manager");
|
|
|
5
5
|
const redis_1 = require("@keyv/redis");
|
|
6
6
|
class CacheModule {
|
|
7
7
|
static forRootAsync(options) {
|
|
8
|
-
this.
|
|
8
|
+
this.redisToken = options.redisToken;
|
|
9
|
+
this.isEnabled = true;
|
|
9
10
|
return {
|
|
10
11
|
module: CacheModule,
|
|
11
12
|
global: true,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache.module.js","sourceRoot":"","sources":["../../../../src/modules/cache/cache.module.ts"],"names":[],"mappings":";;;AACA,yDAAuE;AAGvE,uCAA6D;AAE7D,MAAa,WAAW;IAItB,MAAM,CAAC,YAAY,CAAC,OAA2B;QAC7C,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"cache.module.js","sourceRoot":"","sources":["../../../../src/modules/cache/cache.module.ts"],"names":[],"mappings":";;;AACA,yDAAuE;AAGvE,uCAA6D;AAE7D,MAAa,WAAW;IAItB,MAAM,CAAC,YAAY,CAAC,OAA2B;QAC7C,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;QACrC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,OAAO;YACL,MAAM,EAAE,WAAW;YACnB,MAAM,EAAE,IAAI;YACZ,OAAO,EAAE;gBACP,2BAAe,CAAC,aAAa,CAAC;oBAC5B,QAAQ,EAAE,IAAI;oBACd,UAAU,EAAE,CAAC,WAAyB,EAAE,EAAE;wBACxC,IAAI,CAAC,WAAW,EAAE,CAAC;4BACjB,OAAO;gCACL,GAAG,EAAE,OAAO,CAAC,UAAU;gCACvB,MAAM,EAAE,SAAS;6BAClB,CAAC;wBACJ,CAAC;wBACD,OAAO;4BACL,GAAG,EAAE,OAAO,CAAC,UAAU;4BACvB,MAAM,EAAE;gCACN,IAAA,kBAAU,EACR,WAAW,CAAC,OAAwC,CACrD;6BACF;yBACF,CAAC;oBACJ,CAAC;oBACD,MAAM,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC;iBAC7B,CAAC;aACH;YACD,OAAO,EAAE,EAAE;SACZ,CAAC;IACJ,CAAC;;AAlCH,kCAmCC;AAlCQ,qBAAS,GAAG,KAAK,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Cache } from '@nestjs/cache-manager';
|
|
2
|
+
import { IRedisClient } from "../redis";
|
|
3
|
+
import { AsyncMethod } from "../../shared/types";
|
|
4
|
+
import { AsyncMemoizeConfig } from "./types";
|
|
5
|
+
export declare class CacheService {
|
|
6
|
+
private readonly cacheManager;
|
|
7
|
+
private readonly redisClient;
|
|
8
|
+
constructor(cacheManager: Cache, redisClient: IRedisClient);
|
|
9
|
+
private readonly redlock;
|
|
10
|
+
memoizeAsyncify<T = any, D = any, A extends any[] = any[]>(originalMethod: AsyncMethod<D, A>, inputs?: AsyncMemoizeConfig<T, D, A>): AsyncMethod<D, A>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.CacheService = void 0;
|
|
16
|
+
const cache_manager_1 = require("@nestjs/cache-manager");
|
|
17
|
+
const common_1 = require("@nestjs/common");
|
|
18
|
+
const cache_module_1 = require("./cache.module");
|
|
19
|
+
const redlock_1 = require("redlock");
|
|
20
|
+
let CacheService = class CacheService {
|
|
21
|
+
constructor(cacheManager, redisClient) {
|
|
22
|
+
this.cacheManager = cacheManager;
|
|
23
|
+
this.redisClient = redisClient;
|
|
24
|
+
this.redlock = new redlock_1.default([this.redisClient], {
|
|
25
|
+
retryCount: 3,
|
|
26
|
+
retryDelay: 250,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
memoizeAsyncify(originalMethod, inputs) {
|
|
30
|
+
const promCache = new Map();
|
|
31
|
+
const resolvedConfig = {
|
|
32
|
+
expirationTimeMs: 0,
|
|
33
|
+
...(inputs || {}),
|
|
34
|
+
lock: {
|
|
35
|
+
duration: 10000,
|
|
36
|
+
retryCount: 3,
|
|
37
|
+
retryDelay: 250,
|
|
38
|
+
...(inputs?.lock || {}),
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
const cache = this.cacheManager;
|
|
42
|
+
const redlock = this.redlock;
|
|
43
|
+
return async function (...args) {
|
|
44
|
+
const keyResolver = typeof resolvedConfig.keyResolver === 'string'
|
|
45
|
+
? () => resolvedConfig.keyResolver
|
|
46
|
+
: resolvedConfig.keyResolver;
|
|
47
|
+
let key;
|
|
48
|
+
if (keyResolver) {
|
|
49
|
+
key = keyResolver.apply(this, args);
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
key = `${this.constructor.name}:${originalMethod.name}:${JSON.stringify(args)}`;
|
|
53
|
+
}
|
|
54
|
+
if (promCache.has(key)) {
|
|
55
|
+
return promCache.get(key);
|
|
56
|
+
}
|
|
57
|
+
const lockKey = `lock:${key}`;
|
|
58
|
+
let finalLock;
|
|
59
|
+
try {
|
|
60
|
+
finalLock = await redlock.acquire([lockKey], resolvedConfig.lock.duration);
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
console.error(`Error while acquiring lock for key: ${key}`);
|
|
64
|
+
console.error(error);
|
|
65
|
+
throw error;
|
|
66
|
+
}
|
|
67
|
+
const prom = new Promise(async (resolve, reject) => {
|
|
68
|
+
let data;
|
|
69
|
+
if (typeof resolvedConfig.expirationTimeMs !== 'number' ||
|
|
70
|
+
resolvedConfig.expirationTimeMs > 0) {
|
|
71
|
+
data = await cache.get(key).catch((e) => {
|
|
72
|
+
console.error(`Error while getting cache for key: ${key}`);
|
|
73
|
+
console.error(e);
|
|
74
|
+
return undefined;
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
if (data) {
|
|
78
|
+
let dataValue = typeof data === 'string' && data.startsWith(memoizeTypesPrefix)
|
|
79
|
+
? memoizeTypes.get(data)
|
|
80
|
+
: data;
|
|
81
|
+
if (!!resolvedConfig.cacheWrapperClass && !!dataValue) {
|
|
82
|
+
if (Array.isArray(dataValue)) {
|
|
83
|
+
dataValue = dataValue.map((value) => new resolvedConfig.cacheWrapperClass(value));
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
dataValue = new resolvedConfig.cacheWrapperClass(dataValue);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
resolve(dataValue);
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
try {
|
|
93
|
+
data = (await originalMethod.apply(this, args));
|
|
94
|
+
resolve(data);
|
|
95
|
+
const expirationTimeMs = typeof resolvedConfig.expirationTimeMs === 'number'
|
|
96
|
+
? resolvedConfig.expirationTimeMs
|
|
97
|
+
: resolvedConfig.expirationTimeMs.apply(this, [data]);
|
|
98
|
+
if (expirationTimeMs > 0) {
|
|
99
|
+
const dataValue = memoizeTypes.has(data)
|
|
100
|
+
? memoizeTypes.get(data)
|
|
101
|
+
: data;
|
|
102
|
+
if (typeof resolvedConfig.memoizeIf !== 'function' ||
|
|
103
|
+
resolvedConfig.memoizeIf.apply(this, [dataValue])) {
|
|
104
|
+
await cache.set(key, dataValue, expirationTimeMs).catch((e) => {
|
|
105
|
+
console.error(`Error while setting cache for key: ${key}`);
|
|
106
|
+
console.error(e);
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
catch (e) {
|
|
112
|
+
reject(e instanceof Error ? e : new Error(String(e)));
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
await finalLock.release().catch((e) => {
|
|
116
|
+
console.error(`Error while release lock for key: ${key}`);
|
|
117
|
+
console.error(e);
|
|
118
|
+
});
|
|
119
|
+
promCache.delete(key);
|
|
120
|
+
});
|
|
121
|
+
promCache.set(key, prom);
|
|
122
|
+
return prom;
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
exports.CacheService = CacheService;
|
|
127
|
+
exports.CacheService = CacheService = __decorate([
|
|
128
|
+
(0, common_1.Injectable)(),
|
|
129
|
+
__param(0, (0, common_1.Inject)(cache_manager_1.CACHE_MANAGER)),
|
|
130
|
+
__param(1, (0, common_1.Inject)((0, common_1.forwardRef)(() => cache_module_1.CacheModule.redisToken))),
|
|
131
|
+
__metadata("design:paramtypes", [Function, Object])
|
|
132
|
+
], CacheService);
|
|
133
|
+
//# sourceMappingURL=cache.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.service.js","sourceRoot":"","sources":["../../../../src/modules/cache/cache.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
const memoizeTypesPrefix = '__memoize-types:';
|
|
2
|
+
const memoizeTypes = new Map([
|
|
3
|
+
[memoizeTypesPrefix + 'null', null],
|
|
4
|
+
[null, memoizeTypesPrefix + 'null'],
|
|
5
|
+
[memoizeTypesPrefix + 'undefined', undefined],
|
|
6
|
+
[undefined, memoizeTypesPrefix + 'undefined'],
|
|
7
|
+
]);
|
|
8
|
+
//# sourceMappingURL=constant.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constant.js","sourceRoot":"","sources":["../../../../src/modules/cache/constant.ts"],"names":[],"mappings":"AAAA,MAAM,kBAAkB,GAAG,kBAAkB,CAAC;AAC9C,MAAM,YAAY,GAAG,IAAI,GAAG,CAG1B;IACA,CAAC,kBAAkB,GAAG,MAAM,EAAE,IAAI,CAAC;IACnC,CAAC,IAAI,EAAE,kBAAkB,GAAG,MAAM,CAAC;IACnC,CAAC,kBAAkB,GAAG,WAAW,EAAE,SAAS,CAAC;IAC7C,CAAC,SAAS,EAAE,kBAAkB,GAAG,WAAW,CAAC;CAC9C,CAAC,CAAC"}
|
|
@@ -1,17 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
type
|
|
4
|
-
type
|
|
5
|
-
interface AsyncMemoizeConfig<T = any, D = any, A extends any[] = any[]> {
|
|
6
|
-
lock?: {
|
|
7
|
-
duration?: number;
|
|
8
|
-
retryCount?: number;
|
|
9
|
-
retryDelay?: number;
|
|
10
|
-
};
|
|
11
|
-
keyResolver?: ((this: T, ...args: A) => string) | string;
|
|
12
|
-
expirationTimeMs?: number | ((this: T, data: D) => number);
|
|
13
|
-
memoizeIf?: (this: T, ...args: A) => boolean;
|
|
14
|
-
cacheWrapperClass?: ClassWithConstructor;
|
|
15
|
-
}
|
|
1
|
+
import { AsyncMemoizeConfig } from '../types';
|
|
2
|
+
import { Method } from '../../../shared/types';
|
|
3
|
+
export type Memoizable<T, D> = (target: T, propertyName: string | symbol | keyof T, descriptor: TypedPropertyDescriptor<Method<D>>) => TypedPropertyDescriptor<Method<D>>;
|
|
4
|
+
export type AsyncMemoizable<T, D> = Memoizable<T, Promise<D>>;
|
|
16
5
|
export declare function MemoizeAsync<T = any, D = any>(inputs?: AsyncMemoizeConfig<T, D, any[]>): AsyncMemoizable<T, D>;
|
|
17
|
-
export {};
|
|
@@ -2,131 +2,15 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.MemoizeAsync = MemoizeAsync;
|
|
4
4
|
const common_1 = require("@nestjs/common");
|
|
5
|
-
const
|
|
6
|
-
const redlock_1 = require("redlock");
|
|
7
|
-
const ioredis_1 = require("@nestjs-modules/ioredis");
|
|
8
|
-
const memoizeTypesPrefix = '__memoize-types:';
|
|
9
|
-
const memoizeTypes = new Map([
|
|
10
|
-
[memoizeTypesPrefix + 'null', null],
|
|
11
|
-
[null, memoizeTypesPrefix + 'null'],
|
|
12
|
-
[memoizeTypesPrefix + 'undefined', undefined],
|
|
13
|
-
[undefined, memoizeTypesPrefix + 'undefined'],
|
|
14
|
-
]);
|
|
15
|
-
function memoizeAsyncify(originalMethod, inputs) {
|
|
16
|
-
const promCache = new Map();
|
|
17
|
-
const resolvedConfig = {
|
|
18
|
-
expirationTimeMs: 0,
|
|
19
|
-
...(inputs || {}),
|
|
20
|
-
lock: {
|
|
21
|
-
duration: 10000,
|
|
22
|
-
retryCount: 3,
|
|
23
|
-
retryDelay: 250,
|
|
24
|
-
...(inputs?.lock || {}),
|
|
25
|
-
},
|
|
26
|
-
};
|
|
27
|
-
return async function (...args) {
|
|
28
|
-
const redis = this._redisService;
|
|
29
|
-
const cache = this._cacheManager;
|
|
30
|
-
if (!this._redlock) {
|
|
31
|
-
this._redlock = new redlock_1.default([redis], {
|
|
32
|
-
retryCount: resolvedConfig.lock.retryCount,
|
|
33
|
-
retryDelay: resolvedConfig.lock.retryDelay,
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
const redlock = this._redlock;
|
|
37
|
-
const keyResolver = typeof resolvedConfig.keyResolver === 'string'
|
|
38
|
-
? () => resolvedConfig.keyResolver
|
|
39
|
-
: resolvedConfig.keyResolver;
|
|
40
|
-
let key;
|
|
41
|
-
if (keyResolver) {
|
|
42
|
-
key = keyResolver.apply(this, args);
|
|
43
|
-
}
|
|
44
|
-
else {
|
|
45
|
-
key = `${this.constructor.name}:${originalMethod.name}:${JSON.stringify(args)}`;
|
|
46
|
-
}
|
|
47
|
-
if (promCache.has(key)) {
|
|
48
|
-
return promCache.get(key);
|
|
49
|
-
}
|
|
50
|
-
const lockKey = `lock:${key}`;
|
|
51
|
-
let finalLock;
|
|
52
|
-
try {
|
|
53
|
-
finalLock = await redlock.acquire([lockKey], resolvedConfig.lock.duration);
|
|
54
|
-
}
|
|
55
|
-
catch (error) {
|
|
56
|
-
console.error(`Error while acquiring lock for key: ${key}`);
|
|
57
|
-
console.error(error);
|
|
58
|
-
throw error;
|
|
59
|
-
}
|
|
60
|
-
const prom = new Promise(async (resolve, reject) => {
|
|
61
|
-
let data;
|
|
62
|
-
if (typeof resolvedConfig.expirationTimeMs !== 'number' ||
|
|
63
|
-
resolvedConfig.expirationTimeMs > 0) {
|
|
64
|
-
data = await cache.get(key).catch((e) => {
|
|
65
|
-
console.error(`Error while getting cache for key: ${key}`);
|
|
66
|
-
console.error(e);
|
|
67
|
-
return undefined;
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
if (data) {
|
|
71
|
-
let dataValue = typeof data === 'string' && data.startsWith(memoizeTypesPrefix)
|
|
72
|
-
? memoizeTypes.get(data)
|
|
73
|
-
: data;
|
|
74
|
-
if (!!resolvedConfig.cacheWrapperClass && !!dataValue) {
|
|
75
|
-
if (Array.isArray(dataValue)) {
|
|
76
|
-
dataValue = dataValue.map((value) => new resolvedConfig.cacheWrapperClass(value));
|
|
77
|
-
}
|
|
78
|
-
else {
|
|
79
|
-
dataValue = new resolvedConfig.cacheWrapperClass(dataValue);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
resolve(dataValue);
|
|
83
|
-
}
|
|
84
|
-
else {
|
|
85
|
-
try {
|
|
86
|
-
data = (await originalMethod.apply(this, args));
|
|
87
|
-
resolve(data);
|
|
88
|
-
const expirationTimeMs = typeof resolvedConfig.expirationTimeMs === 'number'
|
|
89
|
-
? resolvedConfig.expirationTimeMs
|
|
90
|
-
: resolvedConfig.expirationTimeMs.apply(this, [data]);
|
|
91
|
-
if (expirationTimeMs > 0) {
|
|
92
|
-
const dataValue = memoizeTypes.has(data)
|
|
93
|
-
? memoizeTypes.get(data)
|
|
94
|
-
: data;
|
|
95
|
-
if (typeof resolvedConfig.memoizeIf !== 'function' ||
|
|
96
|
-
resolvedConfig.memoizeIf.apply(this, [dataValue])) {
|
|
97
|
-
await cache.set(key, dataValue, expirationTimeMs).catch((e) => {
|
|
98
|
-
console.error(`Error while setting cache for key: ${key}`);
|
|
99
|
-
console.error(e);
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
catch (e) {
|
|
105
|
-
reject(e instanceof Error ? e : new Error(String(e)));
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
await finalLock.release().catch((e) => {
|
|
109
|
-
console.error(`Error while release lock for key: ${key}`);
|
|
110
|
-
console.error(e);
|
|
111
|
-
});
|
|
112
|
-
promCache.delete(key);
|
|
113
|
-
});
|
|
114
|
-
promCache.set(key, prom);
|
|
115
|
-
return prom;
|
|
116
|
-
};
|
|
117
|
-
}
|
|
5
|
+
const cache_service_1 = require("../cache.service");
|
|
118
6
|
function MemoizeAsync(inputs) {
|
|
119
|
-
const
|
|
120
|
-
const cacheManagerInjector = (0, common_1.Inject)(cache_manager_1.CACHE_MANAGER);
|
|
7
|
+
const cacheServiceInjector = (0, common_1.Inject)(cache_service_1.CacheService);
|
|
121
8
|
return (_target, _propertyName, descriptor) => {
|
|
122
|
-
if (!('
|
|
123
|
-
|
|
124
|
-
}
|
|
125
|
-
if (!('_cacheManager' in _target)) {
|
|
126
|
-
cacheManagerInjector(_target, '_cacheManager');
|
|
9
|
+
if (!('_cacheService' in _target)) {
|
|
10
|
+
cacheServiceInjector(_target, '_cacheService');
|
|
127
11
|
}
|
|
128
12
|
if (descriptor.value) {
|
|
129
|
-
descriptor.value = memoizeAsyncify(descriptor.value, inputs);
|
|
13
|
+
descriptor.value = _target._cacheService.memoizeAsyncify(descriptor.value, inputs);
|
|
130
14
|
return descriptor;
|
|
131
15
|
}
|
|
132
16
|
throw new Error('@MemoizeAsync is applicable only on a methods.');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memoize-async.decorator.js","sourceRoot":"","sources":["../../../../../src/modules/cache/decorators/memoize-async.decorator.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"memoize-async.decorator.js","sourceRoot":"","sources":["../../../../../src/modules/cache/decorators/memoize-async.decorator.ts"],"names":[],"mappings":";;AAeA,oCAuBC;AArCD,2CAAwC;AACxC,oDAAgD;AAahD,SAAgB,YAAY,CAC1B,MAAwC;IAExC,MAAM,oBAAoB,GAAG,IAAA,eAAM,EAAC,4BAAY,CAAC,CAAC;IAElD,OAAO,CACL,OAAY,EACZ,aAAwC,EACxC,UAAmD,EACV,EAAE;QAE3C,IAAI,CAAC,CAAC,eAAe,IAAI,OAAO,CAAC,EAAE,CAAC;YAClC,oBAAoB,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;QACjD,CAAC;QAED,IAAI,UAAU,CAAC,KAAK,EAAE,CAAC;YACrB,UAAU,CAAC,KAAK,GAAG,OAAO,CAAC,aAAa,CAAC,eAAe,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YAEnF,OAAO,UAAU,CAAC;QACpB,CAAC;QAED,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;IACpE,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -1,4 +1,16 @@
|
|
|
1
|
+
import { ClassWithConstructor } from "../../shared/types";
|
|
1
2
|
export type CacheModuleOptions = {
|
|
2
3
|
defaultTtl: number;
|
|
3
|
-
redisToken
|
|
4
|
+
redisToken: string | symbol;
|
|
4
5
|
};
|
|
6
|
+
export interface AsyncMemoizeConfig<T = any, D = any, A extends any[] = any[]> {
|
|
7
|
+
lock?: {
|
|
8
|
+
duration?: number;
|
|
9
|
+
retryCount?: number;
|
|
10
|
+
retryDelay?: number;
|
|
11
|
+
};
|
|
12
|
+
keyResolver?: ((this: T, ...args: A) => string) | string;
|
|
13
|
+
expirationTimeMs?: number | ((this: T, data: D) => number);
|
|
14
|
+
memoizeIf?: (this: T, ...args: A) => boolean;
|
|
15
|
+
cacheWrapperClass?: ClassWithConstructor;
|
|
16
|
+
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { DynamicModule } from '@nestjs/common';
|
|
2
2
|
import { RedisModuleOptions } from './types';
|
|
3
3
|
export declare class RedisModule {
|
|
4
|
+
static isEnabled: boolean;
|
|
5
|
+
static redisToken: string | symbol;
|
|
4
6
|
static forRootAsync(options: RedisModuleOptions): Promise<DynamicModule>;
|
|
5
7
|
}
|
|
@@ -4,6 +4,7 @@ exports.RedisModule = void 0;
|
|
|
4
4
|
const ioredis_1 = require("ioredis");
|
|
5
5
|
class RedisModule {
|
|
6
6
|
static async forRootAsync(options) {
|
|
7
|
+
this.isEnabled = true;
|
|
7
8
|
const clientProviders = [];
|
|
8
9
|
for (const { token, options: clientOptions } of options) {
|
|
9
10
|
const client = new ioredis_1.default(clientOptions);
|
|
@@ -16,11 +17,11 @@ class RedisModule {
|
|
|
16
17
|
return {
|
|
17
18
|
module: RedisModule,
|
|
18
19
|
global: true,
|
|
19
|
-
imports: [],
|
|
20
20
|
exports: clientProviders,
|
|
21
21
|
providers: clientProviders,
|
|
22
22
|
};
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
25
|
exports.RedisModule = RedisModule;
|
|
26
|
+
RedisModule.isEnabled = false;
|
|
26
27
|
//# sourceMappingURL=redis.module.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redis.module.js","sourceRoot":"","sources":["../../../../src/modules/redis/redis.module.ts"],"names":[],"mappings":";;;AACA,qCAA4B;AAG5B,MAAa,WAAW;
|
|
1
|
+
{"version":3,"file":"redis.module.js","sourceRoot":"","sources":["../../../../src/modules/redis/redis.module.ts"],"names":[],"mappings":";;;AACA,qCAA4B;AAG5B,MAAa,WAAW;IAItB,MAAM,CAAC,KAAK,CAAC,YAAY,CACvB,OAA2B;QAE3B,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QAEtB,MAAM,eAAe,GAAe,EAAE,CAAC;QACvC,KAAK,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,IAAI,OAAO,EAAE,CAAC;YACxD,MAAM,MAAM,GAAG,IAAI,iBAAK,CAAC,aAAa,CAAC,CAAC;YACxC,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;YACpB,eAAe,CAAC,IAAI,CAAC;gBACnB,OAAO,EAAE,KAAK;gBACd,QAAQ,EAAE,MAAM;aACjB,CAAC,CAAC;QACL,CAAC;QAED,OAAO;YACL,MAAM,EAAE,WAAW;YACnB,MAAM,EAAE,IAAI;YACZ,OAAO,EAAE,eAAe;YACxB,SAAS,EAAE,eAAe;SAC3B,CAAC;IACJ,CAAC;;AAzBH,kCA0BC;AAzBQ,qBAAS,GAAG,KAAK,CAAC"}
|
|
@@ -3,14 +3,14 @@ export type RedisModuleOptions = {
|
|
|
3
3
|
token: string | symbol;
|
|
4
4
|
options: IRedisClientOptions;
|
|
5
5
|
}[];
|
|
6
|
-
export
|
|
6
|
+
export interface IRedisClient extends Redis {
|
|
7
|
+
}
|
|
7
8
|
export interface IRedisClientOptions {
|
|
8
9
|
host: string;
|
|
9
10
|
port: number;
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
collectRedisInfo: boolean;
|
|
11
|
+
username?: string;
|
|
12
|
+
password?: string;
|
|
13
|
+
db?: number;
|
|
14
|
+
enableReadyCheck?: boolean;
|
|
15
|
+
collectRedisInfo?: boolean;
|
|
16
16
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"class.types.js","sourceRoot":"","sources":["../../../../src/shared/types/class.types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './class.types';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./class.types"), exports);
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/shared/types/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,gDAA8B"}
|