@nest-omni/core 3.1.1-18 → 3.1.1-20

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.
Files changed (41) hide show
  1. package/cache/cache-serialization.service.d.ts +4 -11
  2. package/cache/cache-serialization.service.js +29 -124
  3. package/cache/cache.constants.d.ts +2 -0
  4. package/cache/cache.constants.js +5 -0
  5. package/cache/cache.module.d.ts +2 -0
  6. package/cache/cache.module.js +49 -3
  7. package/cache/cache.service.d.ts +3 -1
  8. package/cache/cache.service.js +32 -4
  9. package/cache/examples/basic-usage.d.ts +58 -0
  10. package/cache/examples/basic-usage.js +379 -0
  11. package/cache/index.d.ts +2 -1
  12. package/cache/index.js +4 -1
  13. package/common/abstract.entity.d.ts +7 -0
  14. package/common/abstract.entity.js +12 -0
  15. package/common/boilerplate.polyfill.d.ts +0 -6
  16. package/common/dto/page-options.dto.d.ts +0 -3
  17. package/common/dto/page-options.dto.js +0 -12
  18. package/common/examples/paginate-and-map.example.d.ts +14 -0
  19. package/common/examples/paginate-and-map.example.js +158 -0
  20. package/decorators/examples/validation-decorators.example.d.ts +69 -0
  21. package/decorators/examples/validation-decorators.example.js +331 -0
  22. package/decorators/use-dto.decorator.d.ts +1 -0
  23. package/decorators/use-dto.decorator.js +10 -0
  24. package/decorators/validator.decorators.d.ts +8 -1
  25. package/decorators/validator.decorators.js +115 -0
  26. package/i18n/en_US/validation.json +4 -1
  27. package/i18n/zh_CN/validation.json +4 -1
  28. package/index.d.ts +1 -0
  29. package/index.js +1 -0
  30. package/package.json +1 -1
  31. package/redis-lock/examples/lock-strategy.examples.d.ts +73 -0
  32. package/redis-lock/examples/lock-strategy.examples.js +387 -0
  33. package/redis-lock/index.d.ts +2 -2
  34. package/redis-lock/index.js +4 -1
  35. package/redis-lock/redis-lock.decorator.d.ts +4 -0
  36. package/redis-lock/redis-lock.decorator.js +43 -7
  37. package/redis-lock/redis-lock.service.d.ts +19 -0
  38. package/redis-lock/redis-lock.service.js +131 -6
  39. package/setup/index.d.ts +0 -1
  40. package/setup/index.js +0 -1
  41. package/shared/serviceRegistryModule.js +2 -0
@@ -1,5 +1,21 @@
1
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 __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
9
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
10
+ return new (P || (P = Promise))(function (resolve, reject) {
11
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
12
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
13
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
14
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
15
+ });
16
+ };
2
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.AtLeastOneFieldConstraint = void 0;
3
19
  exports.IsPassword = IsPassword;
4
20
  exports.IsPhoneNumber = IsPhoneNumber;
5
21
  exports.IsTmpKey = IsTmpKey;
@@ -7,8 +23,12 @@ exports.IsUndefinable = IsUndefinable;
7
23
  exports.IsEmptyable = IsEmptyable;
8
24
  exports.IsNullable = IsNullable;
9
25
  exports.IsHttpUrl = IsHttpUrl;
26
+ exports.AtLeastOneField = AtLeastOneField;
27
+ exports.CustomValidation = CustomValidation;
28
+ exports.CustomValidationMethod = CustomValidationMethod;
10
29
  const class_validator_1 = require("class-validator");
11
30
  const lodash_1 = require("lodash");
31
+ const nestjs_i18n_1 = require("nestjs-i18n");
12
32
  function IsPassword(validationOptions) {
13
33
  return (object, propertyName) => {
14
34
  (0, class_validator_1.registerDecorator)({
@@ -76,3 +96,98 @@ function IsHttpUrl(validationOptions) {
76
96
  });
77
97
  };
78
98
  }
99
+ let AtLeastOneFieldConstraint = class AtLeastOneFieldConstraint {
100
+ validate(value, args) {
101
+ const object = args.object;
102
+ const [requiredProperties] = args.constraints;
103
+ return requiredProperties.some((property) => {
104
+ const propValue = object[property];
105
+ return (propValue !== null &&
106
+ propValue !== undefined &&
107
+ propValue !== '' &&
108
+ !(Array.isArray(propValue) && propValue.length === 0));
109
+ });
110
+ }
111
+ defaultMessage(args) {
112
+ const [requiredProperties] = args.constraints;
113
+ return `At least one of the following fields must be provided: ${requiredProperties.join(', ')}`;
114
+ }
115
+ };
116
+ exports.AtLeastOneFieldConstraint = AtLeastOneFieldConstraint;
117
+ exports.AtLeastOneFieldConstraint = AtLeastOneFieldConstraint = __decorate([
118
+ (0, class_validator_1.ValidatorConstraint)({ name: 'atLeastOneField', async: false })
119
+ ], AtLeastOneFieldConstraint);
120
+ function AtLeastOneField(properties, validationOptions) {
121
+ return function (object, propertyName) {
122
+ (0, class_validator_1.registerDecorator)({
123
+ target: object.constructor,
124
+ propertyName: propertyName,
125
+ options: Object.assign({ message: (0, nestjs_i18n_1.i18nValidationMessage)('validation.AT_LEAST_ONE_FIELD', {
126
+ properties: properties.join(', '),
127
+ }) }, validationOptions),
128
+ constraints: [properties],
129
+ validator: AtLeastOneFieldConstraint,
130
+ });
131
+ };
132
+ }
133
+ function CustomValidation(validationCallback, validationOptions) {
134
+ return function (object, propertyName) {
135
+ (0, class_validator_1.registerDecorator)({
136
+ name: 'customValidation',
137
+ target: object.constructor,
138
+ propertyName,
139
+ options: Object.assign({ message: (0, nestjs_i18n_1.i18nValidationMessage)('validation.CUSTOM_VALIDATION') }, validationOptions),
140
+ validator: {
141
+ validate(value, args) {
142
+ return __awaiter(this, void 0, void 0, function* () {
143
+ try {
144
+ return yield validationCallback(value, args);
145
+ }
146
+ catch (error) {
147
+ console.error('CustomValidation error:', error);
148
+ return false;
149
+ }
150
+ });
151
+ },
152
+ defaultMessage(args) {
153
+ return `Validation failed for ${args.property}`;
154
+ },
155
+ },
156
+ });
157
+ };
158
+ }
159
+ function CustomValidationMethod(methodName, validationOptions) {
160
+ return function (object, propertyName) {
161
+ (0, class_validator_1.registerDecorator)({
162
+ name: 'customValidationMethod',
163
+ target: object.constructor,
164
+ propertyName,
165
+ constraints: [methodName],
166
+ options: Object.assign({ message: (0, nestjs_i18n_1.i18nValidationMessage)('validation.CUSTOM_VALIDATION_METHOD') }, validationOptions),
167
+ validator: {
168
+ validate(value, args) {
169
+ return __awaiter(this, void 0, void 0, function* () {
170
+ const [method] = args.constraints;
171
+ const object = args.object;
172
+ if (typeof object[method] !== 'function') {
173
+ console.error(`CustomValidationMethod: Method '${method}' not found on object`);
174
+ return false;
175
+ }
176
+ try {
177
+ const result = yield object[method](value, args);
178
+ return Boolean(result);
179
+ }
180
+ catch (error) {
181
+ console.error(`CustomValidationMethod error in '${method}':`, error);
182
+ return false;
183
+ }
184
+ });
185
+ },
186
+ defaultMessage(args) {
187
+ const [method] = args.constraints;
188
+ return `Validation failed for ${args.property} using method ${method}`;
189
+ },
190
+ },
191
+ });
192
+ };
193
+ }
@@ -37,5 +37,8 @@
37
37
  "IS_IP": "{property} value `{value}` not a valid IP",
38
38
  "IS_OBJECT": "{property} value `{value}` not a valid Object",
39
39
  "IS_TIME_ZONE": "{property} value `{value}` must be a valid IANA time-zone",
40
- "IS_LOCALE": "{property} value `{value}` must be a valid locale"
40
+ "IS_LOCALE": "{property} value `{value}` must be a valid locale",
41
+ "AT_LEAST_ONE_FIELD": "At least one of the following fields must be provided: {properties}",
42
+ "CUSTOM_VALIDATION": "Custom validation failed for {property}",
43
+ "CUSTOM_VALIDATION_METHOD": "Validation failed for {property}"
41
44
  }
@@ -37,5 +37,8 @@
37
37
  "IS_IP": "{property} 值 `{value}` 必须是有效IP",
38
38
  "IS_OBJECT": "{property} 值 `{value}` 必须是有效对象",
39
39
  "IS_TIME_ZONE": "{property} 值 `{value}` 必须是有效时区",
40
- "IS_LOCALE": "{property} 值 `{value}` 必须是有效语言"
40
+ "IS_LOCALE": "{property} 值 `{value}` 必须是有效语言",
41
+ "AT_LEAST_ONE_FIELD": "以下字段中至少必须提供一个:{properties}",
42
+ "CUSTOM_VALIDATION": "{property}自定义验证失败",
43
+ "CUSTOM_VALIDATION_METHOD": "{property}验证失败"
41
44
  }
package/index.d.ts CHANGED
@@ -11,6 +11,7 @@ export * from './common';
11
11
  export * from './validator-json';
12
12
  export * from './helpers';
13
13
  export * from './providers';
14
+ export * from './redis-lock';
14
15
  export * from './cache';
15
16
  export * from './vault';
16
17
  export * from './setup';
package/index.js CHANGED
@@ -27,6 +27,7 @@ __exportStar(require("./common"), exports);
27
27
  __exportStar(require("./validator-json"), exports);
28
28
  __exportStar(require("./helpers"), exports);
29
29
  __exportStar(require("./providers"), exports);
30
+ __exportStar(require("./redis-lock"), exports);
30
31
  __exportStar(require("./cache"), exports);
31
32
  __exportStar(require("./vault"), exports);
32
33
  __exportStar(require("./setup"), exports);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nest-omni/core",
3
- "version": "3.1.1-18",
3
+ "version": "3.1.1-20",
4
4
  "description": "A comprehensive NestJS framework for building enterprise-grade applications with best practices",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -0,0 +1,73 @@
1
+ import { RedisLockService } from '../index';
2
+ export declare class SkipStrategyExample {
3
+ private readonly lockService;
4
+ private readonly logger;
5
+ constructor(lockService: RedisLockService);
6
+ scheduledTask(): Promise<void>;
7
+ processWithSkip(): Promise<{
8
+ skipped: boolean;
9
+ success?: undefined;
10
+ } | {
11
+ success: boolean;
12
+ skipped?: undefined;
13
+ }>;
14
+ processWithRetries(): Promise<{
15
+ skipped: boolean;
16
+ success?: undefined;
17
+ } | {
18
+ success: boolean;
19
+ skipped?: undefined;
20
+ }>;
21
+ private simulateLongRunning;
22
+ }
23
+ export declare class ThrowStrategyExample {
24
+ private readonly lockService;
25
+ private readonly logger;
26
+ constructor(lockService: RedisLockService);
27
+ criticalOperation(): Promise<void>;
28
+ processWithThrow(): Promise<{
29
+ success: boolean;
30
+ }>;
31
+ processPayment(orderId: string, amount: number): Promise<{
32
+ success: boolean;
33
+ }>;
34
+ private processData;
35
+ private chargePayment;
36
+ private updateOrderStatus;
37
+ }
38
+ export declare class WaitStrategyExample {
39
+ private readonly lockService;
40
+ private readonly logger;
41
+ constructor(lockService: RedisLockService);
42
+ sequentialTask(): Promise<void>;
43
+ processWithWaitTimeout(): Promise<{
44
+ timeout: boolean;
45
+ success?: undefined;
46
+ } | {
47
+ success: boolean;
48
+ timeout?: undefined;
49
+ }>;
50
+ processDataSequentially(userId: string, data: any): Promise<{
51
+ success: boolean;
52
+ }>;
53
+ processQueue(queueName: string, item: any): Promise<{
54
+ success: boolean;
55
+ }>;
56
+ runMigration(migrationName: string): Promise<{
57
+ success: boolean;
58
+ }>;
59
+ private processInOrder;
60
+ private validateData;
61
+ private saveData;
62
+ private notifyUser;
63
+ private processQueueItem;
64
+ private executeMigration;
65
+ }
66
+ export declare class CombinedStrategiesExample {
67
+ private readonly lockService;
68
+ private readonly logger;
69
+ constructor(lockService: RedisLockService);
70
+ cleanupOldData(): Promise<void>;
71
+ processPayment(orderId: string): Promise<void>;
72
+ generateReport(reportId: string): Promise<void>;
73
+ }
@@ -0,0 +1,387 @@
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 __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
12
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
13
+ return new (P || (P = Promise))(function (resolve, reject) {
14
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
15
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
16
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
17
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
18
+ });
19
+ };
20
+ var SkipStrategyExample_1, ThrowStrategyExample_1, WaitStrategyExample_1, CombinedStrategiesExample_1;
21
+ Object.defineProperty(exports, "__esModule", { value: true });
22
+ exports.CombinedStrategiesExample = exports.WaitStrategyExample = exports.ThrowStrategyExample = exports.SkipStrategyExample = void 0;
23
+ const common_1 = require("@nestjs/common");
24
+ const schedule_1 = require("@nestjs/schedule");
25
+ const index_1 = require("../index");
26
+ let SkipStrategyExample = SkipStrategyExample_1 = class SkipStrategyExample {
27
+ constructor(lockService) {
28
+ this.lockService = lockService;
29
+ this.logger = new common_1.Logger(SkipStrategyExample_1.name);
30
+ }
31
+ scheduledTask() {
32
+ return __awaiter(this, void 0, void 0, function* () {
33
+ this.logger.log('Executing scheduled task...');
34
+ yield this.simulateLongRunning();
35
+ this.logger.log('Scheduled task completed');
36
+ });
37
+ }
38
+ processWithSkip() {
39
+ return __awaiter(this, void 0, void 0, function* () {
40
+ const lockResult = yield this.lockService.acquireLock('process-task', {
41
+ strategy: index_1.LockStrategy.SKIP,
42
+ ttl: 30000,
43
+ });
44
+ if (!lockResult.acquired) {
45
+ this.logger.log('Task is already running, skipping...');
46
+ return { skipped: true };
47
+ }
48
+ try {
49
+ this.logger.log('Processing task...');
50
+ yield this.simulateLongRunning();
51
+ return { success: true };
52
+ }
53
+ finally {
54
+ yield this.lockService.releaseLock('process-task', lockResult.lockValue);
55
+ }
56
+ });
57
+ }
58
+ processWithRetries() {
59
+ return __awaiter(this, void 0, void 0, function* () {
60
+ const lockResult = yield this.lockService.acquireLock('retry-task', {
61
+ strategy: index_1.LockStrategy.SKIP,
62
+ ttl: 30000,
63
+ retryCount: 3,
64
+ retryDelay: 500,
65
+ });
66
+ if (!lockResult.acquired) {
67
+ this.logger.warn('Failed to acquire lock after 3 retries');
68
+ return { skipped: true };
69
+ }
70
+ try {
71
+ yield this.simulateLongRunning();
72
+ return { success: true };
73
+ }
74
+ finally {
75
+ yield this.lockService.releaseLock('retry-task', lockResult.lockValue);
76
+ }
77
+ });
78
+ }
79
+ simulateLongRunning() {
80
+ return __awaiter(this, void 0, void 0, function* () {
81
+ yield new Promise((resolve) => setTimeout(resolve, 5000));
82
+ });
83
+ }
84
+ };
85
+ exports.SkipStrategyExample = SkipStrategyExample;
86
+ __decorate([
87
+ (0, schedule_1.Cron)('* * * * *'),
88
+ (0, index_1.UseRedisLock)('scheduled-task', {
89
+ ttl: 60000,
90
+ strategy: index_1.LockStrategy.SKIP,
91
+ }),
92
+ __metadata("design:type", Function),
93
+ __metadata("design:paramtypes", []),
94
+ __metadata("design:returntype", Promise)
95
+ ], SkipStrategyExample.prototype, "scheduledTask", null);
96
+ exports.SkipStrategyExample = SkipStrategyExample = SkipStrategyExample_1 = __decorate([
97
+ (0, common_1.Injectable)(),
98
+ __metadata("design:paramtypes", [index_1.RedisLockService])
99
+ ], SkipStrategyExample);
100
+ let ThrowStrategyExample = ThrowStrategyExample_1 = class ThrowStrategyExample {
101
+ constructor(lockService) {
102
+ this.lockService = lockService;
103
+ this.logger = new common_1.Logger(ThrowStrategyExample_1.name);
104
+ }
105
+ criticalOperation() {
106
+ return __awaiter(this, void 0, void 0, function* () {
107
+ this.logger.log('Executing critical operation...');
108
+ yield this.processData();
109
+ this.logger.log('Critical operation completed');
110
+ });
111
+ }
112
+ processWithThrow() {
113
+ return __awaiter(this, void 0, void 0, function* () {
114
+ try {
115
+ const lockResult = yield this.lockService.acquireLock('exclusive-task', {
116
+ strategy: index_1.LockStrategy.THROW,
117
+ ttl: 30000,
118
+ });
119
+ try {
120
+ this.logger.log('Processing exclusive task...');
121
+ yield this.processData();
122
+ return { success: true };
123
+ }
124
+ finally {
125
+ yield this.lockService.releaseLock('exclusive-task', lockResult.lockValue);
126
+ }
127
+ }
128
+ catch (error) {
129
+ this.logger.error(`Failed to acquire lock: ${error.message}`);
130
+ throw new Error('Operation cannot proceed without exclusive access');
131
+ }
132
+ });
133
+ }
134
+ processPayment(orderId, amount) {
135
+ return __awaiter(this, void 0, void 0, function* () {
136
+ const lockKey = `payment:${orderId}`;
137
+ try {
138
+ const lockResult = yield this.lockService.acquireLock(lockKey, {
139
+ strategy: index_1.LockStrategy.THROW,
140
+ ttl: 60000,
141
+ });
142
+ try {
143
+ this.logger.log(`Processing payment for order ${orderId}...`);
144
+ yield this.chargePayment(orderId, amount);
145
+ yield this.updateOrderStatus(orderId, 'paid');
146
+ return { success: true };
147
+ }
148
+ finally {
149
+ yield this.lockService.releaseLock(lockKey, lockResult.lockValue);
150
+ }
151
+ }
152
+ catch (error) {
153
+ this.logger.error(`Payment processing failed for ${orderId}: ${error.message}`);
154
+ throw error;
155
+ }
156
+ });
157
+ }
158
+ processData() {
159
+ return __awaiter(this, void 0, void 0, function* () {
160
+ yield new Promise((resolve) => setTimeout(resolve, 2000));
161
+ });
162
+ }
163
+ chargePayment(orderId, amount) {
164
+ return __awaiter(this, void 0, void 0, function* () {
165
+ yield new Promise((resolve) => setTimeout(resolve, 1000));
166
+ });
167
+ }
168
+ updateOrderStatus(orderId, status) {
169
+ return __awaiter(this, void 0, void 0, function* () {
170
+ yield new Promise((resolve) => setTimeout(resolve, 500));
171
+ });
172
+ }
173
+ };
174
+ exports.ThrowStrategyExample = ThrowStrategyExample;
175
+ __decorate([
176
+ (0, index_1.UseRedisLock)('critical-operation', {
177
+ ttl: 60000,
178
+ strategy: index_1.LockStrategy.THROW,
179
+ }),
180
+ __metadata("design:type", Function),
181
+ __metadata("design:paramtypes", []),
182
+ __metadata("design:returntype", Promise)
183
+ ], ThrowStrategyExample.prototype, "criticalOperation", null);
184
+ exports.ThrowStrategyExample = ThrowStrategyExample = ThrowStrategyExample_1 = __decorate([
185
+ (0, common_1.Injectable)(),
186
+ __metadata("design:paramtypes", [index_1.RedisLockService])
187
+ ], ThrowStrategyExample);
188
+ let WaitStrategyExample = WaitStrategyExample_1 = class WaitStrategyExample {
189
+ constructor(lockService) {
190
+ this.lockService = lockService;
191
+ this.logger = new common_1.Logger(WaitStrategyExample_1.name);
192
+ }
193
+ sequentialTask() {
194
+ return __awaiter(this, void 0, void 0, function* () {
195
+ this.logger.log('Executing sequential task...');
196
+ yield this.processInOrder();
197
+ this.logger.log('Sequential task completed');
198
+ });
199
+ }
200
+ processWithWaitTimeout() {
201
+ return __awaiter(this, void 0, void 0, function* () {
202
+ const lockResult = yield this.lockService.acquireLock('wait-task', {
203
+ strategy: index_1.LockStrategy.WAIT,
204
+ waitTimeout: 30000,
205
+ retryDelay: 200,
206
+ ttl: 60000,
207
+ });
208
+ if (!lockResult.acquired) {
209
+ this.logger.warn('Timed out waiting for lock after 30 seconds');
210
+ return { timeout: true };
211
+ }
212
+ try {
213
+ this.logger.log('Lock acquired after waiting, processing...');
214
+ yield this.processInOrder();
215
+ return { success: true };
216
+ }
217
+ finally {
218
+ yield this.lockService.releaseLock('wait-task', lockResult.lockValue);
219
+ }
220
+ });
221
+ }
222
+ processDataSequentially(userId, data) {
223
+ return __awaiter(this, void 0, void 0, function* () {
224
+ const lockKey = `user-data:${userId}`;
225
+ const lockResult = yield this.lockService.acquireLock(lockKey, {
226
+ strategy: index_1.LockStrategy.WAIT,
227
+ retryDelay: 50,
228
+ ttl: 120000,
229
+ });
230
+ try {
231
+ this.logger.log(`Processing data for user ${userId}...`);
232
+ yield this.validateData(data);
233
+ yield this.saveData(userId, data);
234
+ yield this.notifyUser(userId);
235
+ return { success: true };
236
+ }
237
+ finally {
238
+ yield this.lockService.releaseLock(lockKey, lockResult.lockValue);
239
+ }
240
+ });
241
+ }
242
+ processQueue(queueName, item) {
243
+ return __awaiter(this, void 0, void 0, function* () {
244
+ const lockKey = `queue:${queueName}`;
245
+ this.logger.log(`Waiting for lock to process item in queue ${queueName}...`);
246
+ const lockResult = yield this.lockService.acquireLock(lockKey, {
247
+ strategy: index_1.LockStrategy.WAIT,
248
+ retryDelay: 100,
249
+ ttl: 60000,
250
+ });
251
+ try {
252
+ this.logger.log(`Lock acquired, processing item in queue ${queueName}...`);
253
+ yield this.processQueueItem(item);
254
+ return { success: true };
255
+ }
256
+ finally {
257
+ yield this.lockService.releaseLock(lockKey, lockResult.lockValue);
258
+ }
259
+ });
260
+ }
261
+ runMigration(migrationName) {
262
+ return __awaiter(this, void 0, void 0, function* () {
263
+ const lockKey = `migration:${migrationName}`;
264
+ this.logger.log(`Waiting to run migration ${migrationName}...`);
265
+ const lockResult = yield this.lockService.acquireLock(lockKey, {
266
+ strategy: index_1.LockStrategy.WAIT,
267
+ waitTimeout: 300000,
268
+ retryDelay: 1000,
269
+ ttl: 600000,
270
+ });
271
+ if (!lockResult.acquired) {
272
+ throw new Error(`Migration ${migrationName} timed out waiting for lock`);
273
+ }
274
+ try {
275
+ this.logger.log(`Running migration ${migrationName}...`);
276
+ yield this.executeMigration(migrationName);
277
+ this.logger.log(`Migration ${migrationName} completed successfully`);
278
+ return { success: true };
279
+ }
280
+ finally {
281
+ yield this.lockService.releaseLock(lockKey, lockResult.lockValue);
282
+ }
283
+ });
284
+ }
285
+ processInOrder() {
286
+ return __awaiter(this, void 0, void 0, function* () {
287
+ yield new Promise((resolve) => setTimeout(resolve, 2000));
288
+ });
289
+ }
290
+ validateData(data) {
291
+ return __awaiter(this, void 0, void 0, function* () {
292
+ yield new Promise((resolve) => setTimeout(resolve, 500));
293
+ });
294
+ }
295
+ saveData(userId, data) {
296
+ return __awaiter(this, void 0, void 0, function* () {
297
+ yield new Promise((resolve) => setTimeout(resolve, 1000));
298
+ });
299
+ }
300
+ notifyUser(userId) {
301
+ return __awaiter(this, void 0, void 0, function* () {
302
+ yield new Promise((resolve) => setTimeout(resolve, 500));
303
+ });
304
+ }
305
+ processQueueItem(item) {
306
+ return __awaiter(this, void 0, void 0, function* () {
307
+ yield new Promise((resolve) => setTimeout(resolve, 1500));
308
+ });
309
+ }
310
+ executeMigration(name) {
311
+ return __awaiter(this, void 0, void 0, function* () {
312
+ yield new Promise((resolve) => setTimeout(resolve, 5000));
313
+ });
314
+ }
315
+ };
316
+ exports.WaitStrategyExample = WaitStrategyExample;
317
+ __decorate([
318
+ (0, index_1.UseRedisLock)('sequential-task', {
319
+ ttl: 30000,
320
+ strategy: index_1.LockStrategy.WAIT,
321
+ retryDelay: 100,
322
+ }),
323
+ __metadata("design:type", Function),
324
+ __metadata("design:paramtypes", []),
325
+ __metadata("design:returntype", Promise)
326
+ ], WaitStrategyExample.prototype, "sequentialTask", null);
327
+ exports.WaitStrategyExample = WaitStrategyExample = WaitStrategyExample_1 = __decorate([
328
+ (0, common_1.Injectable)(),
329
+ __metadata("design:paramtypes", [index_1.RedisLockService])
330
+ ], WaitStrategyExample);
331
+ let CombinedStrategiesExample = CombinedStrategiesExample_1 = class CombinedStrategiesExample {
332
+ constructor(lockService) {
333
+ this.lockService = lockService;
334
+ this.logger = new common_1.Logger(CombinedStrategiesExample_1.name);
335
+ }
336
+ cleanupOldData() {
337
+ return __awaiter(this, void 0, void 0, function* () {
338
+ this.logger.log('Running cleanup...');
339
+ });
340
+ }
341
+ processPayment(orderId) {
342
+ return __awaiter(this, void 0, void 0, function* () {
343
+ const lockResult = yield this.lockService.acquireLock(`payment:${orderId}`, {
344
+ strategy: index_1.LockStrategy.THROW,
345
+ ttl: 60000,
346
+ });
347
+ try {
348
+ }
349
+ finally {
350
+ yield this.lockService.releaseLock(`payment:${orderId}`, lockResult.lockValue);
351
+ }
352
+ });
353
+ }
354
+ generateReport(reportId) {
355
+ return __awaiter(this, void 0, void 0, function* () {
356
+ const lockResult = yield this.lockService.acquireLock(`report:${reportId}`, {
357
+ strategy: index_1.LockStrategy.WAIT,
358
+ waitTimeout: 180000,
359
+ retryDelay: 500,
360
+ ttl: 300000,
361
+ });
362
+ if (!lockResult.acquired) {
363
+ throw new Error('Report generation timed out');
364
+ }
365
+ try {
366
+ }
367
+ finally {
368
+ yield this.lockService.releaseLock(`report:${reportId}`, lockResult.lockValue);
369
+ }
370
+ });
371
+ }
372
+ };
373
+ exports.CombinedStrategiesExample = CombinedStrategiesExample;
374
+ __decorate([
375
+ (0, schedule_1.Cron)('0 */6 * * *'),
376
+ (0, index_1.UseRedisLock)('cleanup-task', {
377
+ strategy: index_1.LockStrategy.SKIP,
378
+ ttl: 3600000,
379
+ }),
380
+ __metadata("design:type", Function),
381
+ __metadata("design:paramtypes", []),
382
+ __metadata("design:returntype", Promise)
383
+ ], CombinedStrategiesExample.prototype, "cleanupOldData", null);
384
+ exports.CombinedStrategiesExample = CombinedStrategiesExample = CombinedStrategiesExample_1 = __decorate([
385
+ (0, common_1.Injectable)(),
386
+ __metadata("design:paramtypes", [index_1.RedisLockService])
387
+ ], CombinedStrategiesExample);
@@ -1,4 +1,4 @@
1
1
  export { RedisLockModule, type RedisLockModuleOptions, REDIS_LOCK_SERVICE, } from './redis-lock.module';
2
- export { RedisLockService } from './redis-lock.service';
3
- export { UseRedisLock, UseRedisLockOrSkip, setLockService, getLockService, } from './redis-lock.decorator';
2
+ export { RedisLockService, LockStrategy } from './redis-lock.service';
3
+ export { UseRedisLock, UseRedisLockOrSkip, UseRedisLockSmart, UseRedisLockOrSkipSmart, setLockService, getLockService, } from './redis-lock.decorator';
4
4
  export type { LockOptions, LockResult } from './redis-lock.service';
@@ -1,13 +1,16 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getLockService = exports.setLockService = exports.UseRedisLockOrSkip = exports.UseRedisLock = exports.RedisLockService = exports.REDIS_LOCK_SERVICE = exports.RedisLockModule = void 0;
3
+ exports.getLockService = exports.setLockService = exports.UseRedisLockOrSkipSmart = exports.UseRedisLockSmart = exports.UseRedisLockOrSkip = exports.UseRedisLock = exports.LockStrategy = exports.RedisLockService = exports.REDIS_LOCK_SERVICE = exports.RedisLockModule = void 0;
4
4
  var redis_lock_module_1 = require("./redis-lock.module");
5
5
  Object.defineProperty(exports, "RedisLockModule", { enumerable: true, get: function () { return redis_lock_module_1.RedisLockModule; } });
6
6
  Object.defineProperty(exports, "REDIS_LOCK_SERVICE", { enumerable: true, get: function () { return redis_lock_module_1.REDIS_LOCK_SERVICE; } });
7
7
  var redis_lock_service_1 = require("./redis-lock.service");
8
8
  Object.defineProperty(exports, "RedisLockService", { enumerable: true, get: function () { return redis_lock_service_1.RedisLockService; } });
9
+ Object.defineProperty(exports, "LockStrategy", { enumerable: true, get: function () { return redis_lock_service_1.LockStrategy; } });
9
10
  var redis_lock_decorator_1 = require("./redis-lock.decorator");
10
11
  Object.defineProperty(exports, "UseRedisLock", { enumerable: true, get: function () { return redis_lock_decorator_1.UseRedisLock; } });
11
12
  Object.defineProperty(exports, "UseRedisLockOrSkip", { enumerable: true, get: function () { return redis_lock_decorator_1.UseRedisLockOrSkip; } });
13
+ Object.defineProperty(exports, "UseRedisLockSmart", { enumerable: true, get: function () { return redis_lock_decorator_1.UseRedisLockSmart; } });
14
+ Object.defineProperty(exports, "UseRedisLockOrSkipSmart", { enumerable: true, get: function () { return redis_lock_decorator_1.UseRedisLockOrSkipSmart; } });
12
15
  Object.defineProperty(exports, "setLockService", { enumerable: true, get: function () { return redis_lock_decorator_1.setLockService; } });
13
16
  Object.defineProperty(exports, "getLockService", { enumerable: true, get: function () { return redis_lock_decorator_1.getLockService; } });
@@ -6,3 +6,7 @@ export declare function UseRedisLock(lockKey: string, options?: LockOptions & {
6
6
  skipReturnValue?: any;
7
7
  }): MethodDecorator;
8
8
  export declare function UseRedisLockOrSkip(lockKey: string, ttl?: number): MethodDecorator;
9
+ export declare function UseRedisLockSmart(options?: LockOptions & {
10
+ skipReturnValue?: any;
11
+ }): MethodDecorator;
12
+ export declare function UseRedisLockOrSkipSmart(ttl?: number): MethodDecorator;