murlock 4.3.1 → 4.4.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/README.md CHANGED
@@ -69,7 +69,15 @@ import { MurLock } from 'murlock';
69
69
  @Injectable()
70
70
  export class AppService {
71
71
  @MurLock(5000, 'userId')
72
- async someFunction({ userId, firstName, lastName }: { userId: string, firstName: string, lastName: string} ): Promise<void> {
72
+ async someFunction({
73
+ userId,
74
+ firstName,
75
+ lastName,
76
+ }: {
77
+ userId: string;
78
+ firstName: string;
79
+ lastName: string;
80
+ }): Promise<void> {
73
81
  // Some critical section that only one request should be able to execute at a time
74
82
  }
75
83
  }
@@ -83,7 +91,10 @@ import { MurLock } from 'murlock';
83
91
  @Injectable()
84
92
  export class AppService {
85
93
  @MurLock(5000, '0.userId', '1.transactionId')
86
- async someFunction({ userId, firstName, lastName }: UserDTO, { balance, transactionId }: TransactionDTO ): Promise<void> {
94
+ async someFunction(
95
+ { userId, firstName, lastName }: UserDTO,
96
+ { balance, transactionId }: TransactionDTO
97
+ ): Promise<void> {
87
98
  // Some critical section that only one request should be able to execute at a time
88
99
  }
89
100
  }
@@ -130,7 +141,7 @@ You can override the global wait parameter per decorator, allowing fine-grained
130
141
 
131
142
  ```typescript
132
143
  @MurLock(
133
- 5000,
144
+ 5000,
134
145
  (retries) => (Math.floor(Math.random() * 50) + 50) * retries,
135
146
  'user.id',
136
147
  )
@@ -151,6 +162,113 @@ async anotherFunction(user: User): Promise<void> {
151
162
  - If no wait is provided in decorator, MurLock will fallback to global wait from forRoot().
152
163
  - Allows dynamic retry logic per critical section.
153
164
 
165
+ ## Decorator Composition
166
+
167
+ When using `@MurLock` with other decorators (such as `@Transactional` from typeorm-transactional), you may encounter issues with parameter name extraction if the other decorator wraps the method before `@MurLock` is applied.
168
+
169
+ ### Problem
170
+
171
+ TypeScript decorators execute in bottom-up order. If another decorator wraps the method before `@MurLock`, the parameter names cannot be extracted from the wrapped function:
172
+
173
+ ```typescript
174
+ // This may fail if @Transactional wraps the method before @MurLock executes
175
+ @MurLock(5000, 'userData.id')
176
+ @Transactional()
177
+ async process(userData: { id: string }, options: string[] = []): Promise<any> {
178
+ // Error: Parameter userData not found in method arguments
179
+ }
180
+ ```
181
+
182
+ ### Solution: Using SetParamNames
183
+
184
+ Use the `SetParamNames` decorator to explicitly specify parameter names. **Important**: `SetParamNames` must be placed **below** `@MurLock` in the code (it will execute before `@MurLock` due to TypeScript's bottom-up decorator execution order).
185
+
186
+ #### Option 1: Object Format (Recommended)
187
+
188
+ The object format allows you to specify only the parameters you need, with explicit index mapping. This provides O(1) lookup performance and doesn't require specifying all parameters:
189
+
190
+ ```typescript
191
+ import { MurLock, SetParamNames } from 'murlock';
192
+
193
+ class MyService {
194
+ @MurLock(5000, 'userData.id')
195
+ @SetParamNames({ userData: 0 }) // Only specify needed params with their indices
196
+ @Transactional()
197
+ async process(
198
+ userData: { id: string },
199
+ options: string[],
200
+ context: any
201
+ ): Promise<any> {
202
+ // This will work correctly - only userData is needed for the lock key
203
+ }
204
+ }
205
+ ```
206
+
207
+ **Benefits of Object Format:**
208
+
209
+ - **Partial specification**: Only specify the parameters you actually use in the lock key
210
+ - **Order independent**: Parameter indices are explicit, so declaration order doesn't matter
211
+ - **O(1) lookup**: Direct property access instead of array indexOf search
212
+ - **Self-documenting**: The index mapping clearly shows which argument position each name refers to
213
+
214
+ ```typescript
215
+ // Example: Only need the third parameter for the lock key
216
+ @MurLock(5000, 'context.tenantId')
217
+ @SetParamNames({ context: 2 }) // context is at index 2
218
+ @Transactional()
219
+ async process(userData: any, options: any, context: { tenantId: string }): Promise<any> {
220
+ // ...
221
+ }
222
+ ```
223
+
224
+ #### Option 2: Array Format (Legacy)
225
+
226
+ The array format requires specifying ALL parameters in order:
227
+
228
+ ```typescript
229
+ import { MurLock, SetParamNames } from 'murlock';
230
+
231
+ class MyService {
232
+ @MurLock(5000, 'userData.id')
233
+ @SetParamNames('userData', 'options') // Must specify ALL params in order
234
+ @Transactional()
235
+ async process(
236
+ userData: { id: string },
237
+ options: string[] = []
238
+ ): Promise<any> {
239
+ // This will work correctly
240
+ }
241
+ }
242
+ ```
243
+
244
+ > **Note**: The array format uses `indexOf` to find parameters, so all parameters must be specified in the correct order. If you only need one parameter, the object format is recommended.
245
+
246
+ **Decorator Execution Order** (bottom-up):
247
+
248
+ 1. `@Transactional()` executes first and wraps the method
249
+ 2. `@SetParamNames` executes second and stores parameter names in metadata
250
+ 3. `@MurLock` executes last and reads parameter names from metadata
251
+
252
+ If you place `@SetParamNames` above `@MurLock`, it will execute after `@MurLock`, and the metadata won't be available when `@MurLock` needs it.
253
+
254
+ ### Alternative: Using Parameter Indices
255
+
256
+ As a workaround, you can use parameter indices instead of names:
257
+
258
+ ```typescript
259
+ @MurLock(5000, '0.id') // Uses index 0 for userData
260
+ @Transactional()
261
+ async process(userData: { id: string }, options: string[] = []): Promise<any> {
262
+ // This works, but name-based keys are more readable
263
+ }
264
+ ```
265
+
266
+ ### How It Works
267
+
268
+ - `SetParamNames` stores parameter names in metadata before the method is wrapped
269
+ - `@MurLock` reads the parameter names from metadata when the function is already wrapped
270
+ - This allows decorator composition to work correctly regardless of execution order
271
+
154
272
  ## Blocking Mode
155
273
 
156
274
  MurLock supports a blocking mode where it will continuously retry to acquire the lock until successful. This is useful for critical operations that must eventually succeed.
@@ -189,7 +307,7 @@ MurLock includes robust Redis connection handling:
189
307
  @Module({
190
308
  imports: [
191
309
  MurLockModule.forRoot({
192
- redisOptions: {
310
+ redisOptions: {
193
311
  url: 'redis://localhost:6379',
194
312
  socket: {
195
313
  keepAlive: false,
@@ -222,7 +340,7 @@ import { MurLockModule } from 'murlock';
222
340
  wait: configService.get('MURLOCK_WAIT'),
223
341
  maxAttempts: configService.get('MURLOCK_MAX_ATTEMPTS'),
224
342
  logLevel: configService.get('LOG_LEVEL'),
225
- lockKeyPrefix: 'custom'
343
+ lockKeyPrefix: 'custom',
226
344
  }),
227
345
  inject: [ConfigService],
228
346
  }),
@@ -277,7 +395,7 @@ import { MurLockService } from 'murlock';
277
395
  @Injectable()
278
396
  export class YourService {
279
397
  constructor(private murLockService: MurLockService) {}
280
-
398
+
281
399
  // Your methods where you want to use the lock
282
400
  }
283
401
  ```
@@ -1,3 +1,7 @@
1
1
  import 'reflect-metadata';
2
+ export declare const PARAM_NAMES_KEY: unique symbol;
3
+ export declare const PARAM_INDEX_MAP_KEY: unique symbol;
4
+ export type ParamIndexMap = Record<string, number>;
5
+ export declare function SetParamNames(mappingOrFirstParam: ParamIndexMap | string, ...restParamNames: string[]): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
2
6
  export declare function MurLock(releaseTime: number, wait: number | ((retries: number) => number), ...keyParams: string[]): any;
3
7
  export declare function MurLock(releaseTime: number, ...keyParams: string[]): any;
@@ -9,19 +9,83 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  });
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.MurLock = void 0;
13
- require("reflect-metadata");
12
+ exports.MurLock = exports.SetParamNames = exports.PARAM_INDEX_MAP_KEY = exports.PARAM_NAMES_KEY = void 0;
14
13
  const common_1 = require("@nestjs/common");
14
+ require("reflect-metadata");
15
15
  const exceptions_1 = require("../exceptions");
16
16
  const murlock_service_1 = require("../murlock.service");
17
+ exports.PARAM_NAMES_KEY = Symbol('murlock:param-names');
18
+ exports.PARAM_INDEX_MAP_KEY = Symbol('murlock:param-index-map');
19
+ function SetParamNames(mappingOrFirstParam, ...restParamNames) {
20
+ return function (target, propertyKey, descriptor) {
21
+ if (typeof mappingOrFirstParam === 'object') {
22
+ Reflect.defineMetadata(exports.PARAM_INDEX_MAP_KEY, mappingOrFirstParam, target, propertyKey);
23
+ }
24
+ else {
25
+ const paramNames = [mappingOrFirstParam, ...restParamNames];
26
+ Reflect.defineMetadata(exports.PARAM_NAMES_KEY, paramNames, target, propertyKey);
27
+ }
28
+ return descriptor;
29
+ };
30
+ }
31
+ exports.SetParamNames = SetParamNames;
17
32
  function getParameterNames(func) {
18
33
  const STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/gm;
19
- const ARGUMENT_NAMES = /([^\s,]+)/g;
20
34
  const fnStr = func.toString().replace(STRIP_COMMENTS, '');
21
- const result = fnStr
22
- .slice(fnStr.indexOf('(') + 1, fnStr.indexOf(')'))
23
- .match(ARGUMENT_NAMES);
24
- return result || [];
35
+ const paramsStr = fnStr.slice(fnStr.indexOf('(') + 1, fnStr.indexOf(')'));
36
+ if (!paramsStr.trim()) {
37
+ return [];
38
+ }
39
+ const params = [];
40
+ let current = '';
41
+ let depth = 0;
42
+ let inString = false;
43
+ let stringChar = '';
44
+ for (let i = 0; i < paramsStr.length; i++) {
45
+ const char = paramsStr[i];
46
+ if (!inString && (char === '"' || char === "'" || char === '`')) {
47
+ inString = true;
48
+ stringChar = char;
49
+ }
50
+ else if (inString && char === stringChar && paramsStr[i - 1] !== '\\') {
51
+ inString = false;
52
+ }
53
+ else if (!inString) {
54
+ if (char === '(' || char === '[' || char === '{') {
55
+ depth++;
56
+ }
57
+ else if (char === ')' || char === ']' || char === '}') {
58
+ depth--;
59
+ }
60
+ else if (char === ',' && depth === 0) {
61
+ const paramName = current.split('=')[0].trim().split(':')[0].trim();
62
+ if (paramName) {
63
+ params.push(paramName);
64
+ }
65
+ current = '';
66
+ continue;
67
+ }
68
+ }
69
+ current += char;
70
+ }
71
+ if (current.trim()) {
72
+ const paramName = current.split('=')[0].trim().split(':')[0].trim();
73
+ if (paramName) {
74
+ params.push(paramName);
75
+ }
76
+ }
77
+ return params;
78
+ }
79
+ function getParameterNamesWithFallback(func, target, propertyKey) {
80
+ const paramNames = getParameterNames(func);
81
+ if (paramNames.length > 0 && !paramNames.includes('...args')) {
82
+ return paramNames;
83
+ }
84
+ const metadataParamNames = Reflect.getMetadata(exports.PARAM_NAMES_KEY, target, propertyKey);
85
+ if (metadataParamNames && metadataParamNames.length > 0) {
86
+ return metadataParamNames;
87
+ }
88
+ return paramNames;
25
89
  }
26
90
  function MurLock(releaseTime, waitOrKeyParam, ...keyParams) {
27
91
  let wait;
@@ -39,18 +103,33 @@ function MurLock(releaseTime, waitOrKeyParam, ...keyParams) {
39
103
  return (target, propertyKey, descriptor) => {
40
104
  injectMurlockService(target, 'murlockServiceDecorator');
41
105
  const originalMethod = descriptor.value;
42
- const methodParameterNames = getParameterNames(originalMethod);
106
+ const methodParameterNames = getParameterNamesWithFallback(originalMethod, target, propertyKey);
107
+ const paramIndexMap = Reflect.getMetadata(exports.PARAM_INDEX_MAP_KEY, target, propertyKey);
108
+ if (methodParameterNames.length > 0 &&
109
+ !methodParameterNames.includes('...args')) {
110
+ const existingMetadata = Reflect.getMetadata(exports.PARAM_NAMES_KEY, target, propertyKey);
111
+ if (!existingMetadata) {
112
+ Reflect.defineMetadata(exports.PARAM_NAMES_KEY, methodParameterNames, target, propertyKey);
113
+ }
114
+ }
115
+ function resolveParameterIndex(source) {
116
+ if (isNumber(source)) {
117
+ return Number(source);
118
+ }
119
+ if (paramIndexMap && source in paramIndexMap) {
120
+ return paramIndexMap[source];
121
+ }
122
+ return methodParameterNames.indexOf(source);
123
+ }
43
124
  function constructLockKey(args, lockKeyPrefix = 'default') {
44
- let lockKeyElements = [];
125
+ const lockKeyElements = [];
45
126
  if (lockKeyPrefix != 'custom') {
46
127
  lockKeyElements.push(target.constructor.name);
47
128
  lockKeyElements.push(propertyKey);
48
129
  }
49
130
  lockKeyElements.push(...keyParams.map((keyParam) => {
50
131
  const [source, path] = keyParam.split('.');
51
- const parameterIndex = isNumber(source)
52
- ? Number(source)
53
- : methodParameterNames.indexOf(source);
132
+ const parameterIndex = resolveParameterIndex(source);
54
133
  if (parameterIndex >= 0) {
55
134
  const parameterValue = findParameterValue({
56
135
  args,
@@ -1 +1 @@
1
- {"version":3,"file":"murlock.decorator.js","sourceRoot":"","sources":["../../lib/decorators/murlock.decorator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"murlock.decorator.js","sourceRoot":"","sources":["../../lib/decorators/murlock.decorator.ts"],"names":[],"mappings":"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"}