@mondart/nestjs-common-module-bottleneck 3.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.
Files changed (45) hide show
  1. package/dist/bottleneck.module.d.ts +9 -0
  2. package/dist/bottleneck.module.d.ts.map +1 -0
  3. package/dist/bottleneck.module.js +110 -0
  4. package/dist/bottleneck.module.js.map +1 -0
  5. package/dist/constants/bottleneck.const.d.ts +4 -0
  6. package/dist/constants/bottleneck.const.d.ts.map +1 -0
  7. package/dist/constants/bottleneck.const.js +7 -0
  8. package/dist/constants/bottleneck.const.js.map +1 -0
  9. package/dist/cqrs-wrapper/queued-command-bus.d.ts +9 -0
  10. package/dist/cqrs-wrapper/queued-command-bus.d.ts.map +1 -0
  11. package/dist/cqrs-wrapper/queued-command-bus.js +32 -0
  12. package/dist/cqrs-wrapper/queued-command-bus.js.map +1 -0
  13. package/dist/cqrs-wrapper/queued-query-bus.d.ts +9 -0
  14. package/dist/cqrs-wrapper/queued-query-bus.d.ts.map +1 -0
  15. package/dist/cqrs-wrapper/queued-query-bus.js +32 -0
  16. package/dist/cqrs-wrapper/queued-query-bus.js.map +1 -0
  17. package/dist/decorators/config-bottleneck.decorator.d.ts +3 -0
  18. package/dist/decorators/config-bottleneck.decorator.d.ts.map +1 -0
  19. package/dist/decorators/config-bottleneck.decorator.js +8 -0
  20. package/dist/decorators/config-bottleneck.decorator.js.map +1 -0
  21. package/dist/decorators/skip-bottleneck.decorator.d.ts +2 -0
  22. package/dist/decorators/skip-bottleneck.decorator.d.ts.map +1 -0
  23. package/dist/decorators/skip-bottleneck.decorator.js +8 -0
  24. package/dist/decorators/skip-bottleneck.decorator.js.map +1 -0
  25. package/dist/decorators/use-bottleneck.decorator.d.ts +2 -0
  26. package/dist/decorators/use-bottleneck.decorator.d.ts.map +1 -0
  27. package/dist/decorators/use-bottleneck.decorator.js +8 -0
  28. package/dist/decorators/use-bottleneck.decorator.js.map +1 -0
  29. package/dist/index.d.ts +11 -0
  30. package/dist/index.d.ts.map +1 -0
  31. package/dist/index.js +27 -0
  32. package/dist/index.js.map +1 -0
  33. package/dist/interceptors/bottleneck.interceptor.d.ts +13 -0
  34. package/dist/interceptors/bottleneck.interceptor.d.ts.map +1 -0
  35. package/dist/interceptors/bottleneck.interceptor.js +83 -0
  36. package/dist/interceptors/bottleneck.interceptor.js.map +1 -0
  37. package/dist/interfaces/bottleneck-options.interface.d.ts +40 -0
  38. package/dist/interfaces/bottleneck-options.interface.d.ts.map +1 -0
  39. package/dist/interfaces/bottleneck-options.interface.js +5 -0
  40. package/dist/interfaces/bottleneck-options.interface.js.map +1 -0
  41. package/dist/services/bottleneck.service.d.ts +15 -0
  42. package/dist/services/bottleneck.service.d.ts.map +1 -0
  43. package/dist/services/bottleneck.service.js +97 -0
  44. package/dist/services/bottleneck.service.js.map +1 -0
  45. package/package.json +34 -0
@@ -0,0 +1,9 @@
1
+ import { DynamicModule } from '@nestjs/common';
2
+ import { BottleneckModuleAsyncOptions, BottleneckModuleOptions } from './interfaces/bottleneck-options.interface';
3
+ export declare class BottleneckModule {
4
+ static register(options: BottleneckModuleOptions): DynamicModule;
5
+ static registerAsync(options: BottleneckModuleAsyncOptions): DynamicModule;
6
+ private static createAsyncOptionsProvider;
7
+ private static createAsyncProviders;
8
+ }
9
+ //# sourceMappingURL=bottleneck.module.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bottleneck.module.d.ts","sourceRoot":"","sources":["../src/bottleneck.module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAA4B,MAAM,gBAAgB,CAAC;AAEzE,OAAO,EAEL,4BAA4B,EAE5B,uBAAuB,EACxB,MAAM,2CAA2C,CAAC;AAOnD,qBAEa,gBAAgB;IAC3B,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,uBAAuB,GAAG,aAAa;IAsBhE,MAAM,CAAC,aAAa,CAAC,OAAO,EAAE,4BAA4B,GAAG,aAAa;IAY1E,OAAO,CAAC,MAAM,CAAC,0BAA0B;IAYzC,OAAO,CAAC,MAAM,CAAC,oBAAoB;CAiDpC"}
@@ -0,0 +1,110 @@
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 BottleneckModule_1;
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.BottleneckModule = void 0;
11
+ const common_1 = require("@nestjs/common");
12
+ const bottleneck_service_1 = require("./services/bottleneck.service");
13
+ const bottleneck_options_interface_1 = require("./interfaces/bottleneck-options.interface");
14
+ const bottleneck_interceptor_1 = require("./interceptors/bottleneck.interceptor");
15
+ const core_1 = require("@nestjs/core");
16
+ const queued_command_bus_1 = require("./cqrs-wrapper/queued-command-bus");
17
+ const queued_query_bus_1 = require("./cqrs-wrapper/queued-query-bus");
18
+ const cqrs_1 = require("@nestjs/cqrs");
19
+ let BottleneckModule = BottleneckModule_1 = class BottleneckModule {
20
+ static register(options) {
21
+ return {
22
+ module: BottleneckModule_1,
23
+ imports: [cqrs_1.CqrsModule],
24
+ providers: [
25
+ bottleneck_service_1.BottleneckService,
26
+ queued_command_bus_1.QueuedCommandBus,
27
+ queued_query_bus_1.QueuedQueryBus,
28
+ {
29
+ provide: core_1.APP_INTERCEPTOR,
30
+ useClass: bottleneck_interceptor_1.BottleneckInterceptor,
31
+ },
32
+ {
33
+ provide: bottleneck_options_interface_1.BOTTLENECK_MODULE_OPTIONS,
34
+ useValue: options,
35
+ },
36
+ ],
37
+ controllers: [],
38
+ exports: [],
39
+ };
40
+ }
41
+ static registerAsync(options) {
42
+ const asyncOptionsProvider = this.createAsyncOptionsProvider(options);
43
+ return {
44
+ module: BottleneckModule_1,
45
+ imports: [...(options.imports || []), asyncOptionsProvider],
46
+ providers: [],
47
+ controllers: [],
48
+ exports: [],
49
+ };
50
+ }
51
+ static createAsyncOptionsProvider(options) {
52
+ const providers = this.createAsyncProviders(options);
53
+ return {
54
+ module: BottleneckModule_1,
55
+ imports: [cqrs_1.CqrsModule],
56
+ providers,
57
+ exports: [bottleneck_options_interface_1.BOTTLENECK_MODULE_OPTIONS, queued_command_bus_1.QueuedCommandBus, queued_query_bus_1.QueuedQueryBus],
58
+ };
59
+ }
60
+ static createAsyncProviders(options) {
61
+ if (options.useFactory) {
62
+ return [
63
+ bottleneck_service_1.BottleneckService,
64
+ queued_command_bus_1.QueuedCommandBus,
65
+ queued_query_bus_1.QueuedQueryBus,
66
+ {
67
+ provide: core_1.APP_INTERCEPTOR,
68
+ useClass: bottleneck_interceptor_1.BottleneckInterceptor,
69
+ },
70
+ {
71
+ provide: bottleneck_options_interface_1.BOTTLENECK_MODULE_OPTIONS,
72
+ useFactory: options.useFactory,
73
+ inject: options.inject || [],
74
+ },
75
+ ];
76
+ }
77
+ const useClass = options.useClass || options.useExisting;
78
+ if (useClass) {
79
+ return [
80
+ bottleneck_service_1.BottleneckService,
81
+ queued_command_bus_1.QueuedCommandBus,
82
+ queued_query_bus_1.QueuedQueryBus,
83
+ {
84
+ provide: bottleneck_options_interface_1.BOTTLENECK_MODULE_OPTIONS,
85
+ useFactory: async (optionsFactory) => await optionsFactory.createModuleOptions(),
86
+ inject: [options.useExisting || options.useClass],
87
+ },
88
+ {
89
+ provide: core_1.APP_INTERCEPTOR,
90
+ useClass: bottleneck_interceptor_1.BottleneckInterceptor,
91
+ },
92
+ ...(options.useClass
93
+ ? [
94
+ {
95
+ provide: options.useClass,
96
+ useClass: options.useClass,
97
+ },
98
+ ]
99
+ : []),
100
+ ];
101
+ }
102
+ throw new Error('Invalid BottleneckModuleAsyncOptions');
103
+ }
104
+ };
105
+ exports.BottleneckModule = BottleneckModule;
106
+ exports.BottleneckModule = BottleneckModule = BottleneckModule_1 = __decorate([
107
+ (0, common_1.Global)(),
108
+ (0, common_1.Module)({})
109
+ ], BottleneckModule);
110
+ //# sourceMappingURL=bottleneck.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bottleneck.module.js","sourceRoot":"","sources":["../src/bottleneck.module.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export declare const SKIP_CART_BOTTLENECK_KEY = "skipCartBottleneck";
2
+ export declare const USE_CART_BOTTLENECK_KEY = "useCartBottleneck";
3
+ export declare const CONFIG_CART_BOTTLENECK_KEY = "configCartBottleneck";
4
+ //# sourceMappingURL=bottleneck.const.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bottleneck.const.d.ts","sourceRoot":"","sources":["../../src/constants/bottleneck.const.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,wBAAwB,uBAAuB,CAAC;AAC7D,eAAO,MAAM,uBAAuB,sBAAsB,CAAC;AAC3D,eAAO,MAAM,0BAA0B,yBAAyB,CAAC"}
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CONFIG_CART_BOTTLENECK_KEY = exports.USE_CART_BOTTLENECK_KEY = exports.SKIP_CART_BOTTLENECK_KEY = void 0;
4
+ exports.SKIP_CART_BOTTLENECK_KEY = 'skipCartBottleneck';
5
+ exports.USE_CART_BOTTLENECK_KEY = 'useCartBottleneck';
6
+ exports.CONFIG_CART_BOTTLENECK_KEY = 'configCartBottleneck';
7
+ //# sourceMappingURL=bottleneck.const.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bottleneck.const.js","sourceRoot":"","sources":["../../src/constants/bottleneck.const.ts"],"names":[],"mappings":";;;AAAa,QAAA,wBAAwB,GAAG,oBAAoB,CAAC;AAChD,QAAA,uBAAuB,GAAG,mBAAmB,CAAC;AAC9C,QAAA,0BAA0B,GAAG,sBAAsB,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { CommandBus } from '@nestjs/cqrs';
2
+ import { BottleneckService } from '../services/bottleneck.service';
3
+ export declare class QueuedCommandBus {
4
+ private readonly commandBus;
5
+ private readonly bottleneckService;
6
+ constructor(commandBus: CommandBus, bottleneckService: BottleneckService);
7
+ execute<TCommand, TResult = any>(command: TCommand): Promise<TResult>;
8
+ }
9
+ //# sourceMappingURL=queued-command-bus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queued-command-bus.d.ts","sourceRoot":"","sources":["../../src/cqrs-wrapper/queued-command-bus.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AAEnE,qBACa,gBAAgB;IAEzB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,iBAAiB;gBADjB,UAAU,EAAE,UAAU,EACtB,iBAAiB,EAAE,iBAAiB;IAGjD,OAAO,CAAC,QAAQ,EAAE,OAAO,GAAG,GAAG,EAAE,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;CAS5E"}
@@ -0,0 +1,32 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.QueuedCommandBus = void 0;
13
+ const common_1 = require("@nestjs/common");
14
+ const cqrs_1 = require("@nestjs/cqrs");
15
+ const bottleneck_service_1 = require("../services/bottleneck.service");
16
+ let QueuedCommandBus = class QueuedCommandBus {
17
+ constructor(commandBus, bottleneckService) {
18
+ this.commandBus = commandBus;
19
+ this.bottleneckService = bottleneckService;
20
+ }
21
+ async execute(command) {
22
+ const key = `${command.constructor.name}:${JSON.stringify(command)}`;
23
+ return this.bottleneckService.runQueuedTask(key, async () => this.commandBus.execute(command));
24
+ }
25
+ };
26
+ exports.QueuedCommandBus = QueuedCommandBus;
27
+ exports.QueuedCommandBus = QueuedCommandBus = __decorate([
28
+ (0, common_1.Injectable)(),
29
+ __metadata("design:paramtypes", [cqrs_1.CommandBus,
30
+ bottleneck_service_1.BottleneckService])
31
+ ], QueuedCommandBus);
32
+ //# sourceMappingURL=queued-command-bus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queued-command-bus.js","sourceRoot":"","sources":["../../src/cqrs-wrapper/queued-command-bus.ts"],"names":[],"mappings":";;;;;;;;;;;;AACA,2CAA4C;AAC5C,uCAA0C;AAC1C,uEAAmE;AAG5D,IAAM,gBAAgB,GAAtB,MAAM,gBAAgB;IAC3B,YACmB,UAAsB,EACtB,iBAAoC;QADpC,eAAU,GAAV,UAAU,CAAY;QACtB,sBAAiB,GAAjB,iBAAiB,CAAmB;IACpD,CAAC;IAEJ,KAAK,CAAC,OAAO,CAA0B,OAAiB;QAEtD,MAAM,GAAG,GAAG,GAAG,OAAO,CAAC,WAAW,CAAC,IAAI,IAAI,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;QAGrE,OAAO,IAAI,CAAC,iBAAiB,CAAC,aAAa,CAAC,GAAG,EAAE,KAAK,IAAI,EAAE,CAC1D,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,CACjC,CAAC;IACJ,CAAC;CACF,CAAA;AAfY,4CAAgB;2BAAhB,gBAAgB;IAD5B,IAAA,mBAAU,GAAE;qCAGoB,iBAAU;QACH,sCAAiB;GAH5C,gBAAgB,CAe5B"}
@@ -0,0 +1,9 @@
1
+ import { QueryBus } from '@nestjs/cqrs';
2
+ import { BottleneckService } from '../services/bottleneck.service';
3
+ export declare class QueuedQueryBus {
4
+ private readonly queryBus;
5
+ private readonly bottleneckService;
6
+ constructor(queryBus: QueryBus, bottleneckService: BottleneckService);
7
+ execute<TCommand, TResult = any>(command: TCommand): Promise<TResult>;
8
+ }
9
+ //# sourceMappingURL=queued-query-bus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queued-query-bus.d.ts","sourceRoot":"","sources":["../../src/cqrs-wrapper/queued-query-bus.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AAEnE,qBACa,cAAc;IAEvB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,iBAAiB;gBADjB,QAAQ,EAAE,QAAQ,EAClB,iBAAiB,EAAE,iBAAiB;IAGjD,OAAO,CAAC,QAAQ,EAAE,OAAO,GAAG,GAAG,EAAE,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;CAS5E"}
@@ -0,0 +1,32 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.QueuedQueryBus = void 0;
13
+ const common_1 = require("@nestjs/common");
14
+ const cqrs_1 = require("@nestjs/cqrs");
15
+ const bottleneck_service_1 = require("../services/bottleneck.service");
16
+ let QueuedQueryBus = class QueuedQueryBus {
17
+ constructor(queryBus, bottleneckService) {
18
+ this.queryBus = queryBus;
19
+ this.bottleneckService = bottleneckService;
20
+ }
21
+ async execute(command) {
22
+ const key = `${command.constructor.name}:${JSON.stringify(command)}`;
23
+ return this.bottleneckService.runQueuedTask(key, async () => this.queryBus.execute(command));
24
+ }
25
+ };
26
+ exports.QueuedQueryBus = QueuedQueryBus;
27
+ exports.QueuedQueryBus = QueuedQueryBus = __decorate([
28
+ (0, common_1.Injectable)(),
29
+ __metadata("design:paramtypes", [cqrs_1.QueryBus,
30
+ bottleneck_service_1.BottleneckService])
31
+ ], QueuedQueryBus);
32
+ //# sourceMappingURL=queued-query-bus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queued-query-bus.js","sourceRoot":"","sources":["../../src/cqrs-wrapper/queued-query-bus.ts"],"names":[],"mappings":";;;;;;;;;;;;AACA,2CAA4C;AAC5C,uCAAwC;AACxC,uEAAmE;AAG5D,IAAM,cAAc,GAApB,MAAM,cAAc;IACzB,YACmB,QAAkB,EAClB,iBAAoC;QADpC,aAAQ,GAAR,QAAQ,CAAU;QAClB,sBAAiB,GAAjB,iBAAiB,CAAmB;IACpD,CAAC;IAEJ,KAAK,CAAC,OAAO,CAA0B,OAAiB;QAEtD,MAAM,GAAG,GAAG,GAAG,OAAO,CAAC,WAAW,CAAC,IAAI,IAAI,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;QAGrE,OAAO,IAAI,CAAC,iBAAiB,CAAC,aAAa,CAAC,GAAG,EAAE,KAAK,IAAI,EAAE,CAC1D,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,CAC/B,CAAC;IACJ,CAAC;CACF,CAAA;AAfY,wCAAc;yBAAd,cAAc;IAD1B,IAAA,mBAAU,GAAE;qCAGkB,eAAQ;QACC,sCAAiB;GAH5C,cAAc,CAe1B"}
@@ -0,0 +1,3 @@
1
+ import { BottleneckModuleOptions } from '../interfaces/bottleneck-options.interface';
2
+ export declare const ConfigBottleneckDecorator: (config?: BottleneckModuleOptions) => import("@nestjs/common").CustomDecorator<string>;
3
+ //# sourceMappingURL=config-bottleneck.decorator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-bottleneck.decorator.d.ts","sourceRoot":"","sources":["../../src/decorators/config-bottleneck.decorator.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,uBAAuB,EAAE,MAAM,4CAA4C,CAAC;AAErF,eAAO,MAAM,yBAAyB,GAAI,SAAS,uBAAuB,qDACzB,CAAC"}
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ConfigBottleneckDecorator = void 0;
4
+ const common_1 = require("@nestjs/common");
5
+ const bottleneck_const_1 = require("../constants/bottleneck.const");
6
+ const ConfigBottleneckDecorator = (config) => (0, common_1.SetMetadata)(bottleneck_const_1.CONFIG_CART_BOTTLENECK_KEY, config);
7
+ exports.ConfigBottleneckDecorator = ConfigBottleneckDecorator;
8
+ //# sourceMappingURL=config-bottleneck.decorator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-bottleneck.decorator.js","sourceRoot":"","sources":["../../src/decorators/config-bottleneck.decorator.ts"],"names":[],"mappings":";;;AAAA,2CAA6C;AAC7C,oEAA2E;AAGpE,MAAM,yBAAyB,GAAG,CAAC,MAAgC,EAAE,EAAE,CAC5E,IAAA,oBAAW,EAAC,6CAA0B,EAAE,MAAM,CAAC,CAAC;AADrC,QAAA,yBAAyB,6BACY"}
@@ -0,0 +1,2 @@
1
+ export declare const SkipBottleneckDecorator: () => import("@nestjs/common").CustomDecorator<string>;
2
+ //# sourceMappingURL=skip-bottleneck.decorator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skip-bottleneck.decorator.d.ts","sourceRoot":"","sources":["../../src/decorators/skip-bottleneck.decorator.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,uBAAuB,wDACS,CAAC"}
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SkipBottleneckDecorator = void 0;
4
+ const common_1 = require("@nestjs/common");
5
+ const bottleneck_const_1 = require("../constants/bottleneck.const");
6
+ const SkipBottleneckDecorator = () => (0, common_1.SetMetadata)(bottleneck_const_1.SKIP_CART_BOTTLENECK_KEY, true);
7
+ exports.SkipBottleneckDecorator = SkipBottleneckDecorator;
8
+ //# sourceMappingURL=skip-bottleneck.decorator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skip-bottleneck.decorator.js","sourceRoot":"","sources":["../../src/decorators/skip-bottleneck.decorator.ts"],"names":[],"mappings":";;;AAAA,2CAA6C;AAC7C,oEAAyE;AAElE,MAAM,uBAAuB,GAAG,GAAG,EAAE,CAC1C,IAAA,oBAAW,EAAC,2CAAwB,EAAE,IAAI,CAAC,CAAC;AADjC,QAAA,uBAAuB,2BACU"}
@@ -0,0 +1,2 @@
1
+ export declare const UseBottleneckDecorator: () => import("@nestjs/common").CustomDecorator<string>;
2
+ //# sourceMappingURL=use-bottleneck.decorator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-bottleneck.decorator.d.ts","sourceRoot":"","sources":["../../src/decorators/use-bottleneck.decorator.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,sBAAsB,wDACS,CAAC"}
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.UseBottleneckDecorator = void 0;
4
+ const common_1 = require("@nestjs/common");
5
+ const bottleneck_const_1 = require("../constants/bottleneck.const");
6
+ const UseBottleneckDecorator = () => (0, common_1.SetMetadata)(bottleneck_const_1.USE_CART_BOTTLENECK_KEY, true);
7
+ exports.UseBottleneckDecorator = UseBottleneckDecorator;
8
+ //# sourceMappingURL=use-bottleneck.decorator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-bottleneck.decorator.js","sourceRoot":"","sources":["../../src/decorators/use-bottleneck.decorator.ts"],"names":[],"mappings":";;;AAAA,2CAA6C;AAC7C,oEAAwE;AAEjE,MAAM,sBAAsB,GAAG,GAAG,EAAE,CACzC,IAAA,oBAAW,EAAC,0CAAuB,EAAE,IAAI,CAAC,CAAC;AADhC,QAAA,sBAAsB,0BACU"}
@@ -0,0 +1,11 @@
1
+ export * from './bottleneck.module';
2
+ export * from './services/bottleneck.service';
3
+ export * from './interceptors/bottleneck.interceptor';
4
+ export * from './constants/bottleneck.const';
5
+ export * from './interfaces/bottleneck-options.interface';
6
+ export * from './decorators/config-bottleneck.decorator';
7
+ export * from './cqrs-wrapper/queued-command-bus';
8
+ export * from './cqrs-wrapper/queued-query-bus';
9
+ export * from './decorators/skip-bottleneck.decorator';
10
+ export * from './decorators/use-bottleneck.decorator';
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,uCAAuC,CAAC;AACtD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,2CAA2C,CAAC;AAC1D,cAAc,0CAA0C,CAAC;AACzD,cAAc,mCAAmC,CAAC;AAClD,cAAc,iCAAiC,CAAC;AAChD,cAAc,wCAAwC,CAAC;AACvD,cAAc,uCAAuC,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,27 @@
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("./bottleneck.module"), exports);
18
+ __exportStar(require("./services/bottleneck.service"), exports);
19
+ __exportStar(require("./interceptors/bottleneck.interceptor"), exports);
20
+ __exportStar(require("./constants/bottleneck.const"), exports);
21
+ __exportStar(require("./interfaces/bottleneck-options.interface"), exports);
22
+ __exportStar(require("./decorators/config-bottleneck.decorator"), exports);
23
+ __exportStar(require("./cqrs-wrapper/queued-command-bus"), exports);
24
+ __exportStar(require("./cqrs-wrapper/queued-query-bus"), exports);
25
+ __exportStar(require("./decorators/skip-bottleneck.decorator"), exports);
26
+ __exportStar(require("./decorators/use-bottleneck.decorator"), exports);
27
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,sDAAoC;AACpC,gEAA8C;AAC9C,wEAAsD;AACtD,+DAA6C;AAC7C,4EAA0D;AAC1D,2EAAyD;AACzD,oEAAkD;AAClD,kEAAgD;AAChD,yEAAuD;AACvD,wEAAsD"}
@@ -0,0 +1,13 @@
1
+ import { CallHandler, ExecutionContext, NestInterceptor } from '@nestjs/common';
2
+ import { BottleneckService } from '../services/bottleneck.service';
3
+ import { Reflector } from '@nestjs/core';
4
+ import { BottleneckModuleOptions } from '../interfaces/bottleneck-options.interface';
5
+ export declare class BottleneckInterceptor implements NestInterceptor {
6
+ private readonly options;
7
+ private readonly bottleneckService;
8
+ private readonly reflector;
9
+ private readonly logger;
10
+ constructor(options: BottleneckModuleOptions, bottleneckService: BottleneckService, reflector: Reflector);
11
+ intercept(ctx: ExecutionContext, next: CallHandler): import("rxjs").Observable<any>;
12
+ }
13
+ //# sourceMappingURL=bottleneck.interceptor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bottleneck.interceptor.d.ts","sourceRoot":"","sources":["../../src/interceptors/bottleneck.interceptor.ts"],"names":[],"mappings":"AACA,OAAO,EACL,WAAW,EACX,gBAAgB,EAIhB,eAAe,EAEhB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAOzC,OAAO,EAEL,uBAAuB,EACxB,MAAM,4CAA4C,CAAC;AAEpD,qBACa,qBAAsB,YAAW,eAAe;IAKzD,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAClC,OAAO,CAAC,QAAQ,CAAC,SAAS;IAN5B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkD;gBAItD,OAAO,EAAE,uBAAuB,EAChC,iBAAiB,EAAE,iBAAiB,EACpC,SAAS,EAAE,SAAS;IAGvC,SAAS,CAAC,GAAG,EAAE,gBAAgB,EAAE,IAAI,EAAE,WAAW;CA2FnD"}
@@ -0,0 +1,83 @@
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
+ var BottleneckInterceptor_1;
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.BottleneckInterceptor = void 0;
17
+ const common_1 = require("@nestjs/common");
18
+ const rxjs_1 = require("rxjs");
19
+ const bottleneck_service_1 = require("../services/bottleneck.service");
20
+ const core_1 = require("@nestjs/core");
21
+ const bottleneck_const_1 = require("../constants/bottleneck.const");
22
+ const bottleneck_options_interface_1 = require("../interfaces/bottleneck-options.interface");
23
+ let BottleneckInterceptor = BottleneckInterceptor_1 = class BottleneckInterceptor {
24
+ constructor(options, bottleneckService, reflector) {
25
+ this.options = options;
26
+ this.bottleneckService = bottleneckService;
27
+ this.reflector = reflector;
28
+ this.logger = new common_1.Logger(BottleneckInterceptor_1.name);
29
+ }
30
+ intercept(ctx, next) {
31
+ const host = ctx.getType();
32
+ if (host !== 'http') {
33
+ return next.handle();
34
+ }
35
+ const skip = this.reflector.getAllAndOverride(bottleneck_const_1.SKIP_CART_BOTTLENECK_KEY, [ctx.getHandler(), ctx.getClass()]);
36
+ const useBottleneck = this.reflector.getAllAndOverride(bottleneck_const_1.USE_CART_BOTTLENECK_KEY, [ctx.getHandler(), ctx.getClass()]);
37
+ const config = this.reflector.getAllAndOverride(bottleneck_const_1.CONFIG_CART_BOTTLENECK_KEY, [ctx.getHandler(), ctx.getClass()]);
38
+ const { basePath, paramKey, useGlobal, maxConcurrent, minTime, ...rest } = {
39
+ ...this.options,
40
+ ...config,
41
+ };
42
+ const url = ctx?.switchToHttp()?.getRequest()?.url;
43
+ if (skip || !(useBottleneck || useGlobal)) {
44
+ this.logger.debug(`🚀 Skipping Bottleneck for request: ${url}`);
45
+ return next.handle();
46
+ }
47
+ const req = ctx.switchToHttp().getRequest();
48
+ const param = req.params?.[paramKey];
49
+ if (!param) {
50
+ throw new common_1.ServiceUnavailableException(`${paramKey} is required in request: ${url}`);
51
+ }
52
+ const key = `${basePath}/${paramKey}:${param}`;
53
+ const bottleneckOptions = {
54
+ maxQueueSize: 100,
55
+ maxConcurrent: maxConcurrent || 1,
56
+ minTime: minTime || 0,
57
+ ...rest,
58
+ };
59
+ const method = req.method || 'UNKNOWN';
60
+ const start = Date.now();
61
+ this.logger.debug(`🔁 [Bottleneck] Scheduling job for key="${key}" method=${method} url=${url}`);
62
+ return (0, rxjs_1.from)(this.bottleneckService
63
+ .scheduleForKey(key, async () => (0, rxjs_1.lastValueFrom)(next.handle()), bottleneckOptions)
64
+ .catch((err) => {
65
+ if (String(err?.message || '').includes('This limiter is at max capacity')) {
66
+ throw new common_1.ServiceUnavailableException('Too many requests queued for this order. Try again soon.');
67
+ }
68
+ throw err;
69
+ })
70
+ .finally(() => {
71
+ const duration = Date.now() - start;
72
+ this.logger.debug(`✅ [Bottleneck] Finished job for key="${key}" method=${method} url=${url} duration=${duration}ms`);
73
+ }));
74
+ }
75
+ };
76
+ exports.BottleneckInterceptor = BottleneckInterceptor;
77
+ exports.BottleneckInterceptor = BottleneckInterceptor = BottleneckInterceptor_1 = __decorate([
78
+ (0, common_1.Injectable)(),
79
+ __param(0, (0, common_1.Inject)(bottleneck_options_interface_1.BOTTLENECK_MODULE_OPTIONS)),
80
+ __metadata("design:paramtypes", [Object, bottleneck_service_1.BottleneckService,
81
+ core_1.Reflector])
82
+ ], BottleneckInterceptor);
83
+ //# sourceMappingURL=bottleneck.interceptor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bottleneck.interceptor.js","sourceRoot":"","sources":["../../src/interceptors/bottleneck.interceptor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ import { ModuleMetadata, Type } from '@nestjs/common';
2
+ export declare const BOTTLENECK_MODULE_OPTIONS = "BOTTLENECK_MODULE_OPTIONS";
3
+ export interface BottleneckModuleOptions {
4
+ appName?: string;
5
+ basePath?: string;
6
+ paramKey?: string;
7
+ useGlobal?: boolean;
8
+ maxConcurrent?: number | null;
9
+ minTime?: number | null;
10
+ highWater?: number | null;
11
+ penalty?: number | null;
12
+ reservoir?: number | null;
13
+ reservoirRefreshInterval?: number | null;
14
+ reservoirRefreshAmount?: number | null;
15
+ reservoirIncreaseAmount?: number | null;
16
+ reservoirIncreaseInterval?: number | null;
17
+ reservoirIncreaseMaximum?: number | null;
18
+ rejectOnDrop?: boolean | null;
19
+ trackDoneStatus?: boolean | null;
20
+ useRedis?: boolean;
21
+ redis?: {
22
+ host: string;
23
+ port: number;
24
+ username?: string;
25
+ password?: string;
26
+ database?: number;
27
+ ttl?: number;
28
+ tls?: boolean;
29
+ };
30
+ }
31
+ export interface BottleneckModuleFactory {
32
+ createModuleOptions: () => Promise<BottleneckModuleOptions> | BottleneckModuleOptions;
33
+ }
34
+ export interface BottleneckModuleAsyncOptions extends Pick<ModuleMetadata, 'imports'> {
35
+ inject?: any[];
36
+ useClass?: Type<BottleneckModuleFactory>;
37
+ useExisting?: Type<BottleneckModuleFactory>;
38
+ useFactory?: (...args: any[]) => Promise<BottleneckModuleOptions> | BottleneckModuleOptions;
39
+ }
40
+ //# sourceMappingURL=bottleneck-options.interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bottleneck-options.interface.d.ts","sourceRoot":"","sources":["../../src/interfaces/bottleneck-options.interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAEtD,eAAO,MAAM,yBAAyB,8BAA8B,CAAC;AAErE,MAAM,WAAW,uBAAuB;IACtC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,wBAAwB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC,sBAAsB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,uBAAuB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,yBAAyB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1C,wBAAwB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC,YAAY,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC9B,eAAe,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,GAAG,CAAC,EAAE,OAAO,CAAC;KACf,CAAC;CACH;AAED,MAAM,WAAW,uBAAuB;IACtC,mBAAmB,EAAE,MACjB,OAAO,CAAC,uBAAuB,CAAC,GAChC,uBAAuB,CAAC;CAC7B;AAED,MAAM,WAAW,4BACf,SAAQ,IAAI,CAAC,cAAc,EAAE,SAAS,CAAC;IACvC,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC;IACf,QAAQ,CAAC,EAAE,IAAI,CAAC,uBAAuB,CAAC,CAAC;IACzC,WAAW,CAAC,EAAE,IAAI,CAAC,uBAAuB,CAAC,CAAC;IAC5C,UAAU,CAAC,EAAE,CACX,GAAG,IAAI,EAAE,GAAG,EAAE,KACX,OAAO,CAAC,uBAAuB,CAAC,GAAG,uBAAuB,CAAC;CACjE"}
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BOTTLENECK_MODULE_OPTIONS = void 0;
4
+ exports.BOTTLENECK_MODULE_OPTIONS = 'BOTTLENECK_MODULE_OPTIONS';
5
+ //# sourceMappingURL=bottleneck-options.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bottleneck-options.interface.js","sourceRoot":"","sources":["../../src/interfaces/bottleneck-options.interface.ts"],"names":[],"mappings":";;;AAEa,QAAA,yBAAyB,GAAG,2BAA2B,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { OnModuleDestroy } from '@nestjs/common';
2
+ import Bottleneck from 'bottleneck';
3
+ import { BottleneckModuleOptions } from '../interfaces/bottleneck-options.interface';
4
+ export declare class BottleneckService implements OnModuleDestroy {
5
+ private readonly options;
6
+ private readonly logger;
7
+ private readonly group;
8
+ private readonly cache;
9
+ constructor(options: BottleneckModuleOptions);
10
+ private getLimiter;
11
+ scheduleForKey<T>(key: string, task: () => Promise<T>, opts?: Bottleneck.ConstructorOptions): Promise<T>;
12
+ runQueuedTask<T>(key: string, fn: () => Promise<T>): Promise<T>;
13
+ onModuleDestroy(): Promise<void>;
14
+ }
15
+ //# sourceMappingURL=bottleneck.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bottleneck.service.d.ts","sourceRoot":"","sources":["../../src/services/bottleneck.service.ts"],"names":[],"mappings":"AACA,OAAO,EAA8B,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAC7E,OAAO,UAAU,MAAM,YAAY,CAAC;AACpC,OAAO,EAEL,uBAAuB,EACxB,MAAM,4CAA4C,CAAC;AAGpD,qBACa,iBAAkB,YAAW,eAAe;IASrD,OAAO,CAAC,QAAQ,CAAC,OAAO;IAR1B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAEpB;IACH,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAmB;IACzC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAmC;gBAItC,OAAO,EAAE,uBAAuB;IAsCnD,OAAO,CAAC,UAAU;IAYlB,cAAc,CAAC,CAAC,EACd,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACtB,IAAI,CAAC,EAAE,UAAU,CAAC,kBAAkB,GACnC,OAAO,CAAC,CAAC,CAAC;IAYP,aAAa,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAoB/D,eAAe;CAGtB"}
@@ -0,0 +1,97 @@
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
+ var __importDefault = (this && this.__importDefault) || function (mod) {
15
+ return (mod && mod.__esModule) ? mod : { "default": mod };
16
+ };
17
+ var BottleneckService_1;
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ exports.BottleneckService = void 0;
20
+ const common_1 = require("@nestjs/common");
21
+ const bottleneck_1 = __importDefault(require("bottleneck"));
22
+ const bottleneck_options_interface_1 = require("../interfaces/bottleneck-options.interface");
23
+ const ioredis_1 = __importDefault(require("ioredis"));
24
+ let BottleneckService = BottleneckService_1 = class BottleneckService {
25
+ constructor(options) {
26
+ this.options = options;
27
+ this.logger = new common_1.Logger(BottleneckService_1.name, {
28
+ timestamp: true,
29
+ });
30
+ this.cache = new Map();
31
+ const { useRedis, redis, appName, ...rest } = this.options;
32
+ const redisOptions = useRedis && redis
33
+ ? {
34
+ datastore: 'ioredis',
35
+ Redis: ioredis_1.default,
36
+ clientOptions: {
37
+ host: redis.host,
38
+ port: redis.port,
39
+ username: redis.username,
40
+ password: redis.password,
41
+ db: redis.database,
42
+ tls: redis.tls ? {} : undefined,
43
+ },
44
+ timeout: redis.ttl,
45
+ }
46
+ : undefined;
47
+ this.group = new bottleneck_1.default.Group({
48
+ id: `bottleneck-${appName ?? 'app'}`,
49
+ maxConcurrent: 1,
50
+ minTime: 0,
51
+ clearDatastore: true,
52
+ ...redisOptions,
53
+ ...rest,
54
+ });
55
+ this.group.on('idle', (key) => {
56
+ setTimeout(() => this.group.deleteKey(key).catch(() => { }), 30_000);
57
+ });
58
+ }
59
+ getLimiter(key, opts) {
60
+ const limiter = this.group.key(key);
61
+ if (opts)
62
+ limiter.updateSettings(opts);
63
+ return limiter;
64
+ }
65
+ scheduleForKey(key, task, opts) {
66
+ const limiter = this.getLimiter(key, opts);
67
+ this.logger.debug(`Scheduling task for key ${key}`);
68
+ return limiter.schedule(task);
69
+ }
70
+ async runQueuedTask(key, fn) {
71
+ if (this.cache.has(key)) {
72
+ this.logger.debug(`Cache hit for key ${key}`);
73
+ return this.cache.get(key);
74
+ }
75
+ const limiter = this.getLimiter(key);
76
+ const taskPromise = limiter.schedule(async () => {
77
+ try {
78
+ return await fn();
79
+ }
80
+ finally {
81
+ this.cache.delete(key);
82
+ }
83
+ });
84
+ this.cache.set(key, taskPromise);
85
+ return taskPromise;
86
+ }
87
+ async onModuleDestroy() {
88
+ await this.group.disconnect();
89
+ }
90
+ };
91
+ exports.BottleneckService = BottleneckService;
92
+ exports.BottleneckService = BottleneckService = BottleneckService_1 = __decorate([
93
+ (0, common_1.Injectable)(),
94
+ __param(0, (0, common_1.Inject)(bottleneck_options_interface_1.BOTTLENECK_MODULE_OPTIONS)),
95
+ __metadata("design:paramtypes", [Object])
96
+ ], BottleneckService);
97
+ //# sourceMappingURL=bottleneck.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bottleneck.service.js","sourceRoot":"","sources":["../../src/services/bottleneck.service.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "@mondart/nestjs-common-module-bottleneck",
3
+ "version": "3.0.0",
4
+ "description": "Bottleneck throttling and queue utilities for NestJS.",
5
+ "author": {
6
+ "name": "Mondart"
7
+ },
8
+ "license": "MIT",
9
+ "type": "commonjs",
10
+ "main": "dist/index.js",
11
+ "types": "dist/index.d.ts",
12
+ "files": [
13
+ "dist",
14
+ "README.md"
15
+ ],
16
+ "scripts": {
17
+ "build": "tsc -p tsconfig.json"
18
+ },
19
+ "dependencies": {
20
+ "@mondart/nestjs-common-module-core": "^3.0.0",
21
+ "bottleneck": "^2.19.5",
22
+ "@nestjs/cqrs": "^11.0.1"
23
+ },
24
+ "peerDependencies": {
25
+ "@nestjs/common": "^11.1.10",
26
+ "@nestjs/core": "^11.1.10",
27
+ "@nestjs/cqrs": "^11.0.1",
28
+ "reflect-metadata": "^0.2.0",
29
+ "rxjs": "^7.8.2"
30
+ },
31
+ "publishConfig": {
32
+ "access": "public"
33
+ }
34
+ }