@fluyappgocore/commons-backend 1.0.202

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 (137) hide show
  1. package/build/classes/BacklogManager.d.ts +129 -0
  2. package/build/classes/BacklogManager.js +417 -0
  3. package/build/classes/BacklogMonitor.d.ts +102 -0
  4. package/build/classes/BacklogMonitor.js +222 -0
  5. package/build/classes/HttpResponse.d.ts +7 -0
  6. package/build/classes/HttpResponse.js +13 -0
  7. package/build/classes/index.d.ts +3 -0
  8. package/build/classes/index.js +15 -0
  9. package/build/dtos/file.dto.d.ts +5 -0
  10. package/build/dtos/file.dto.js +25 -0
  11. package/build/dtos/index.d.ts +1 -0
  12. package/build/dtos/index.js +13 -0
  13. package/build/events/BatchEnhancedListener.d.ts +106 -0
  14. package/build/events/BatchEnhancedListener.js +307 -0
  15. package/build/events/EnhancedListener.d.ts +75 -0
  16. package/build/events/EnhancedListener.js +185 -0
  17. package/build/events/baseListener.d.ts +19 -0
  18. package/build/events/baseListener.js +90 -0
  19. package/build/events/basePublisher.d.ts +14 -0
  20. package/build/events/basePublisher.js +84 -0
  21. package/build/events/config.d.ts +7 -0
  22. package/build/events/config.js +14 -0
  23. package/build/events/createClient.d.ts +38 -0
  24. package/build/events/createClient.js +416 -0
  25. package/build/events/index.d.ts +6 -0
  26. package/build/events/index.js +18 -0
  27. package/build/events/interfaces/agent.event.d.ts +7 -0
  28. package/build/events/interfaces/agent.event.js +2 -0
  29. package/build/events/interfaces/agentCrud.event.d.ts +7 -0
  30. package/build/events/interfaces/agentCrud.event.js +2 -0
  31. package/build/events/interfaces/agentTracking.event.d.ts +7 -0
  32. package/build/events/interfaces/agentTracking.event.js +2 -0
  33. package/build/events/interfaces/audit.event.d.ts +7 -0
  34. package/build/events/interfaces/audit.event.js +2 -0
  35. package/build/events/interfaces/branch.event.d.ts +7 -0
  36. package/build/events/interfaces/branch.event.js +2 -0
  37. package/build/events/interfaces/deleteTracking.event.d.ts +7 -0
  38. package/build/events/interfaces/deleteTracking.event.js +2 -0
  39. package/build/events/interfaces/department.event.d.ts +7 -0
  40. package/build/events/interfaces/department.event.js +2 -0
  41. package/build/events/interfaces/entity.event.d.ts +7 -0
  42. package/build/events/interfaces/entity.event.js +2 -0
  43. package/build/events/interfaces/index.d.ts +23 -0
  44. package/build/events/interfaces/index.js +35 -0
  45. package/build/events/interfaces/manualMatch.event.d.ts +7 -0
  46. package/build/events/interfaces/manualMatch.event.js +2 -0
  47. package/build/events/interfaces/match.event.d.ts +7 -0
  48. package/build/events/interfaces/match.event.js +2 -0
  49. package/build/events/interfaces/monitor.event.d.ts +7 -0
  50. package/build/events/interfaces/monitor.event.js +2 -0
  51. package/build/events/interfaces/notification.event.d.ts +7 -0
  52. package/build/events/interfaces/notification.event.js +2 -0
  53. package/build/events/interfaces/object.event.d.ts +7 -0
  54. package/build/events/interfaces/object.event.js +2 -0
  55. package/build/events/interfaces/payments.event.d.ts +7 -0
  56. package/build/events/interfaces/payments.event.js +2 -0
  57. package/build/events/interfaces/planning.event.d.ts +7 -0
  58. package/build/events/interfaces/planning.event.js +2 -0
  59. package/build/events/interfaces/service.event.d.ts +7 -0
  60. package/build/events/interfaces/service.event.js +2 -0
  61. package/build/events/interfaces/subscription.event.d.ts +7 -0
  62. package/build/events/interfaces/subscription.event.js +2 -0
  63. package/build/events/interfaces/ticket.event.d.ts +7 -0
  64. package/build/events/interfaces/ticket.event.js +2 -0
  65. package/build/events/interfaces/ticketNote.event.d.ts +7 -0
  66. package/build/events/interfaces/ticketNote.event.js +2 -0
  67. package/build/events/interfaces/ticketTracking.event.d.ts +7 -0
  68. package/build/events/interfaces/ticketTracking.event.js +2 -0
  69. package/build/events/interfaces/ticketxTopics.event.d.ts +7 -0
  70. package/build/events/interfaces/ticketxTopics.event.js +2 -0
  71. package/build/events/interfaces/topics.event.d.ts +7 -0
  72. package/build/events/interfaces/topics.event.js +2 -0
  73. package/build/events/interfaces/waitingList.event.d.ts +7 -0
  74. package/build/events/interfaces/waitingList.event.js +2 -0
  75. package/build/exceptions/AuthenticationTokenMissingException.d.ts +5 -0
  76. package/build/exceptions/AuthenticationTokenMissingException.js +27 -0
  77. package/build/exceptions/HttpException.d.ts +5 -0
  78. package/build/exceptions/HttpException.js +27 -0
  79. package/build/exceptions/MongoErrorException.d.ts +4 -0
  80. package/build/exceptions/MongoErrorException.js +27 -0
  81. package/build/exceptions/MulterException.d.ts +4 -0
  82. package/build/exceptions/MulterException.js +27 -0
  83. package/build/exceptions/QwizardException.d.ts +5 -0
  84. package/build/exceptions/QwizardException.js +27 -0
  85. package/build/exceptions/RecordingServerException.d.ts +5 -0
  86. package/build/exceptions/RecordingServerException.js +27 -0
  87. package/build/exceptions/UserNotFoundException.d.ts +4 -0
  88. package/build/exceptions/UserNotFoundException.js +27 -0
  89. package/build/exceptions/UserWithThatEmailAlreadyExistsException.d.ts +4 -0
  90. package/build/exceptions/UserWithThatEmailAlreadyExistsException.js +27 -0
  91. package/build/exceptions/WrongAnonymousAuthException.d.ts +5 -0
  92. package/build/exceptions/WrongAnonymousAuthException.js +27 -0
  93. package/build/exceptions/WrongAuthenticationTokenException.d.ts +5 -0
  94. package/build/exceptions/WrongAuthenticationTokenException.js +27 -0
  95. package/build/exceptions/WrongBusinessAuthException.d.ts +5 -0
  96. package/build/exceptions/WrongBusinessAuthException.js +27 -0
  97. package/build/exceptions/WrongCredentialsException.d.ts +4 -0
  98. package/build/exceptions/WrongCredentialsException.js +27 -0
  99. package/build/exceptions/WrongRoomException.d.ts +4 -0
  100. package/build/exceptions/WrongRoomException.js +27 -0
  101. package/build/exceptions/index.d.ts +16 -0
  102. package/build/exceptions/index.js +28 -0
  103. package/build/exceptions/invalidToken.exception.d.ts +4 -0
  104. package/build/exceptions/invalidToken.exception.js +27 -0
  105. package/build/exceptions/missingToken.exception.d.ts +4 -0
  106. package/build/exceptions/missingToken.exception.js +27 -0
  107. package/build/exceptions/wrongAuth.exception.d.ts +5 -0
  108. package/build/exceptions/wrongAuth.exception.js +27 -0
  109. package/build/index.d.ts +12 -0
  110. package/build/index.js +32 -0
  111. package/build/interfaces/controller.interface.d.ts +5 -0
  112. package/build/interfaces/controller.interface.js +2 -0
  113. package/build/interfaces/index.d.ts +3 -0
  114. package/build/interfaces/index.js +15 -0
  115. package/build/interfaces/requesWithUser.interface.d.ts +11 -0
  116. package/build/interfaces/requesWithUser.interface.js +2 -0
  117. package/build/interfaces/token.interface.d.ts +12 -0
  118. package/build/interfaces/token.interface.js +2 -0
  119. package/build/lib/ensureDatabase.d.ts +11 -0
  120. package/build/lib/ensureDatabase.js +97 -0
  121. package/build/lib/functions.d.ts +89 -0
  122. package/build/lib/functions.js +214 -0
  123. package/build/lib/helpers.d.ts +29 -0
  124. package/build/lib/helpers.js +33 -0
  125. package/build/lib/index.d.ts +4 -0
  126. package/build/lib/index.js +16 -0
  127. package/build/lib/logger.d.ts +2 -0
  128. package/build/lib/logger.js +41 -0
  129. package/build/middlewares/auth.middleware.d.ts +6 -0
  130. package/build/middlewares/auth.middleware.js +287 -0
  131. package/build/middlewares/error.middleware.d.ts +3 -0
  132. package/build/middlewares/error.middleware.js +14 -0
  133. package/build/middlewares/index.d.ts +3 -0
  134. package/build/middlewares/index.js +15 -0
  135. package/build/middlewares/validation.middleware.d.ts +2 -0
  136. package/build/middlewares/validation.middleware.js +22 -0
  137. package/package.json +45 -0
@@ -0,0 +1,129 @@
1
+ export declare type CircuitBreakerState = 'OPEN' | 'CLOSED' | 'HALF_OPEN';
2
+ export interface CircuitBreakerEvent {
3
+ listenerName: string;
4
+ state: CircuitBreakerState;
5
+ previousState: CircuitBreakerState;
6
+ timestamp: Date;
7
+ failureRate: number;
8
+ failedCount: number;
9
+ processedCount: number;
10
+ }
11
+ export declare type CircuitBreakerCallback = (event: CircuitBreakerEvent) => void | Promise<void>;
12
+ export interface BacklogConfig {
13
+ maxConcurrent: number;
14
+ rateLimitMs: number;
15
+ circuitBreakerThreshold: number;
16
+ circuitBreakerResetTime: number;
17
+ maxRetries: number;
18
+ backlogRecoveryBatchSize: number;
19
+ enableBacklogRecovery: boolean;
20
+ listenerName?: string;
21
+ onCircuitBreakerStateChange?: CircuitBreakerCallback;
22
+ }
23
+ export interface ProcessingStats {
24
+ processed: number;
25
+ failed: number;
26
+ retries: number;
27
+ circuitBreakerTrips: number;
28
+ lastProcessedAt: Date;
29
+ averageProcessingTime: number;
30
+ }
31
+ export declare class BacklogManager {
32
+ private config;
33
+ private stats;
34
+ private processingQueue;
35
+ private activeProcessing;
36
+ private circuitBreakerOpen;
37
+ private circuitBreakerOpenTime?;
38
+ private lastProcessTime;
39
+ private processingTimes;
40
+ private circuitBreakerState;
41
+ constructor(config?: Partial<BacklogConfig>);
42
+ /**
43
+ * Procesa un mensaje con rate limiting y circuit breaker
44
+ */
45
+ processMessage<T>(messageData: T, processor: (data: T) => Promise<void>, context?: string): Promise<boolean>;
46
+ /**
47
+ * Ejecuta el procesamiento con reintentos
48
+ */
49
+ private executeWithRetry;
50
+ /**
51
+ * Procesa el siguiente mensaje en cola
52
+ */
53
+ private processNextInQueue;
54
+ /**
55
+ * Actualiza métricas de éxito
56
+ */
57
+ private updateSuccessMetrics;
58
+ /**
59
+ * Actualiza métricas de fallo
60
+ */
61
+ private updateFailureMetrics;
62
+ /**
63
+ * Verifica si debe activar circuit breaker
64
+ */
65
+ private checkCircuitBreaker;
66
+ /**
67
+ * Notifica cambio de estado del circuit breaker
68
+ */
69
+ private notifyCircuitBreakerStateChange;
70
+ /**
71
+ * Verifica si debe resetear circuit breaker
72
+ */
73
+ private checkCircuitBreakerReset;
74
+ /**
75
+ * Obtiene estadísticas actuales
76
+ */
77
+ getStats(): ProcessingStats & {
78
+ queueSize: number;
79
+ activeProcessing: number;
80
+ circuitBreakerOpen: boolean;
81
+ config: BacklogConfig;
82
+ };
83
+ /**
84
+ * Resetea estadísticas
85
+ */
86
+ resetStats(): void;
87
+ /**
88
+ * Actualiza configuración en tiempo real
89
+ */
90
+ updateConfig(newConfig: Partial<BacklogConfig>): void;
91
+ /**
92
+ * Utility sleep function
93
+ */
94
+ private sleep;
95
+ /**
96
+ * Fuerza el cierre del circuit breaker (para testing/debugging)
97
+ */
98
+ forceCircuitBreakerOpen(): void;
99
+ /**
100
+ * Fuerza la apertura del circuit breaker (para testing/debugging)
101
+ */
102
+ forceCircuitBreakerClose(): void;
103
+ /**
104
+ * Registra un callback para cambios de estado del circuit breaker
105
+ */
106
+ onCircuitBreakerStateChange(callback: CircuitBreakerCallback): void;
107
+ /**
108
+ * Obtiene el estado actual del circuit breaker
109
+ */
110
+ getCircuitBreakerState(): CircuitBreakerState;
111
+ /**
112
+ * Verifica si el BacklogManager está en capacidad máxima
113
+ * Usado para control de flujo en eachBatch
114
+ */
115
+ isAtMaxCapacity(): boolean;
116
+ /**
117
+ * Obtiene la capacidad disponible actual
118
+ */
119
+ getAvailableCapacity(): number;
120
+ /**
121
+ * Verifica si puede procesar un número específico de mensajes
122
+ */
123
+ canProcessBatch(batchSize: number): boolean;
124
+ /**
125
+ * Espera hasta que haya capacidad disponible
126
+ * Usado en eachBatch para pausar el procesamiento
127
+ */
128
+ waitForCapacity(minCapacity?: number, timeoutMs?: number): Promise<boolean>;
129
+ }
@@ -0,0 +1,417 @@
1
+ "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
14
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
15
+ return new (P || (P = Promise))(function (resolve, reject) {
16
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
17
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
18
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
19
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
20
+ });
21
+ };
22
+ var __generator = (this && this.__generator) || function (thisArg, body) {
23
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
24
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
25
+ function verb(n) { return function (v) { return step([n, v]); }; }
26
+ function step(op) {
27
+ if (f) throw new TypeError("Generator is already executing.");
28
+ while (_) try {
29
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
30
+ if (y = 0, t) op = [op[0] & 2, t.value];
31
+ switch (op[0]) {
32
+ case 0: case 1: t = op; break;
33
+ case 4: _.label++; return { value: op[1], done: false };
34
+ case 5: _.label++; y = op[1]; op = [0]; continue;
35
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
36
+ default:
37
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
38
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
39
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
40
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
41
+ if (t[2]) _.ops.pop();
42
+ _.trys.pop(); continue;
43
+ }
44
+ op = body.call(thisArg, _);
45
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
46
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
47
+ }
48
+ };
49
+ Object.defineProperty(exports, "__esModule", { value: true });
50
+ exports.BacklogManager = void 0;
51
+ var BacklogManager = /** @class */ (function () {
52
+ function BacklogManager(config) {
53
+ var _this = this;
54
+ if (config === void 0) { config = {}; }
55
+ this.processingQueue = [];
56
+ this.activeProcessing = 0;
57
+ this.circuitBreakerOpen = false;
58
+ this.lastProcessTime = 0;
59
+ this.processingTimes = [];
60
+ this.circuitBreakerState = 'CLOSED';
61
+ this.config = {
62
+ maxConcurrent: config.maxConcurrent || 5,
63
+ rateLimitMs: config.rateLimitMs || 100,
64
+ circuitBreakerThreshold: config.circuitBreakerThreshold || 10,
65
+ circuitBreakerResetTime: config.circuitBreakerResetTime || 60000,
66
+ maxRetries: config.maxRetries || 3,
67
+ backlogRecoveryBatchSize: config.backlogRecoveryBatchSize || 50,
68
+ enableBacklogRecovery: config.enableBacklogRecovery || true
69
+ };
70
+ this.stats = {
71
+ processed: 0,
72
+ failed: 0,
73
+ retries: 0,
74
+ circuitBreakerTrips: 0,
75
+ lastProcessedAt: new Date(),
76
+ averageProcessingTime: 0
77
+ };
78
+ // Auto-reset circuit breaker
79
+ setInterval(function () {
80
+ _this.checkCircuitBreakerReset();
81
+ }, 10000);
82
+ }
83
+ /**
84
+ * Procesa un mensaje con rate limiting y circuit breaker
85
+ */
86
+ BacklogManager.prototype.processMessage = function (messageData, processor, context) {
87
+ if (context === void 0) { context = 'unknown'; }
88
+ return __awaiter(this, void 0, void 0, function () {
89
+ var now, timeSinceLastProcess;
90
+ var _this = this;
91
+ return __generator(this, function (_a) {
92
+ switch (_a.label) {
93
+ case 0:
94
+ // Circuit breaker check
95
+ if (this.circuitBreakerOpen) {
96
+ console.log("\uD83D\uDEAB Circuit breaker open for " + context + ", skipping message");
97
+ return [2 /*return*/, false];
98
+ }
99
+ now = Date.now();
100
+ timeSinceLastProcess = now - this.lastProcessTime;
101
+ if (!(timeSinceLastProcess < this.config.rateLimitMs)) return [3 /*break*/, 2];
102
+ return [4 /*yield*/, this.sleep(this.config.rateLimitMs - timeSinceLastProcess)];
103
+ case 1:
104
+ _a.sent();
105
+ _a.label = 2;
106
+ case 2:
107
+ // Concurrency control
108
+ if (this.activeProcessing >= this.config.maxConcurrent) {
109
+ console.log("\u23F3 Max concurrency reached for " + context + ", queuing message");
110
+ return [2 /*return*/, new Promise(function (resolve) {
111
+ _this.processingQueue.push(function () { return __awaiter(_this, void 0, void 0, function () {
112
+ var result;
113
+ return __generator(this, function (_a) {
114
+ switch (_a.label) {
115
+ case 0: return [4 /*yield*/, this.executeWithRetry(messageData, processor, context)];
116
+ case 1:
117
+ result = _a.sent();
118
+ resolve(result);
119
+ return [2 /*return*/];
120
+ }
121
+ });
122
+ }); });
123
+ })];
124
+ }
125
+ return [4 /*yield*/, this.executeWithRetry(messageData, processor, context)];
126
+ case 3: return [2 /*return*/, _a.sent()];
127
+ }
128
+ });
129
+ });
130
+ };
131
+ /**
132
+ * Ejecuta el procesamiento con reintentos
133
+ */
134
+ BacklogManager.prototype.executeWithRetry = function (messageData, processor, context, attempt) {
135
+ if (attempt === void 0) { attempt = 1; }
136
+ return __awaiter(this, void 0, void 0, function () {
137
+ var startTime, processingTime, error_1, processingTime, backoffDelay;
138
+ return __generator(this, function (_a) {
139
+ switch (_a.label) {
140
+ case 0:
141
+ this.activeProcessing++;
142
+ startTime = Date.now();
143
+ _a.label = 1;
144
+ case 1:
145
+ _a.trys.push([1, 3, 7, 8]);
146
+ return [4 /*yield*/, processor(messageData)];
147
+ case 2:
148
+ _a.sent();
149
+ processingTime = Date.now() - startTime;
150
+ this.updateSuccessMetrics(processingTime);
151
+ console.log("\u2705 " + context + " processed successfully (" + processingTime + "ms)");
152
+ return [2 /*return*/, true];
153
+ case 3:
154
+ error_1 = _a.sent();
155
+ processingTime = Date.now() - startTime;
156
+ console.error("\u274C " + context + " failed (attempt " + attempt + "/" + this.config.maxRetries + "):", error_1);
157
+ if (!(attempt < this.config.maxRetries)) return [3 /*break*/, 6];
158
+ this.stats.retries++;
159
+ backoffDelay = Math.min(1000 * Math.pow(2, attempt - 1), 10000);
160
+ return [4 /*yield*/, this.sleep(backoffDelay)];
161
+ case 4:
162
+ _a.sent();
163
+ return [4 /*yield*/, this.executeWithRetry(messageData, processor, context, attempt + 1)];
164
+ case 5: return [2 /*return*/, _a.sent()];
165
+ case 6:
166
+ // Max retries exceeded
167
+ this.updateFailureMetrics();
168
+ this.checkCircuitBreaker();
169
+ return [2 /*return*/, false];
170
+ case 7:
171
+ this.activeProcessing--;
172
+ this.lastProcessTime = Date.now();
173
+ this.processNextInQueue();
174
+ return [7 /*endfinally*/];
175
+ case 8: return [2 /*return*/];
176
+ }
177
+ });
178
+ });
179
+ };
180
+ /**
181
+ * Procesa el siguiente mensaje en cola
182
+ */
183
+ BacklogManager.prototype.processNextInQueue = function () {
184
+ return __awaiter(this, void 0, void 0, function () {
185
+ var nextProcessor;
186
+ return __generator(this, function (_a) {
187
+ switch (_a.label) {
188
+ case 0:
189
+ if (!(this.processingQueue.length > 0 && this.activeProcessing < this.config.maxConcurrent)) return [3 /*break*/, 2];
190
+ nextProcessor = this.processingQueue.shift();
191
+ if (!nextProcessor) return [3 /*break*/, 2];
192
+ return [4 /*yield*/, nextProcessor()];
193
+ case 1:
194
+ _a.sent();
195
+ _a.label = 2;
196
+ case 2: return [2 /*return*/];
197
+ }
198
+ });
199
+ });
200
+ };
201
+ /**
202
+ * Actualiza métricas de éxito
203
+ */
204
+ BacklogManager.prototype.updateSuccessMetrics = function (processingTime) {
205
+ this.stats.processed++;
206
+ this.stats.lastProcessedAt = new Date();
207
+ // Mantener últimos 100 tiempos para promedio
208
+ this.processingTimes.push(processingTime);
209
+ if (this.processingTimes.length > 100) {
210
+ this.processingTimes.shift();
211
+ }
212
+ this.stats.averageProcessingTime =
213
+ this.processingTimes.reduce(function (a, b) { return a + b; }, 0) / this.processingTimes.length;
214
+ };
215
+ /**
216
+ * Actualiza métricas de fallo
217
+ */
218
+ BacklogManager.prototype.updateFailureMetrics = function () {
219
+ this.stats.failed++;
220
+ };
221
+ /**
222
+ * Verifica si debe activar circuit breaker
223
+ */
224
+ BacklogManager.prototype.checkCircuitBreaker = function () {
225
+ var recentFailureRate = this.stats.failed / (this.stats.processed + this.stats.failed);
226
+ console.log(recentFailureRate, this.stats.failed, this.stats.processed);
227
+ console.log(recentFailureRate > 0.5 && this.stats.failed >= this.config.circuitBreakerThreshold);
228
+ console.log(this.stats.failed >= this.config.circuitBreakerThreshold);
229
+ console.log(this.config);
230
+ if (recentFailureRate > 0.5 && this.stats.failed >= this.config.circuitBreakerThreshold) {
231
+ var previousState = this.circuitBreakerState;
232
+ this.circuitBreakerOpen = true;
233
+ this.circuitBreakerOpenTime = new Date();
234
+ this.circuitBreakerState = 'OPEN';
235
+ this.stats.circuitBreakerTrips++;
236
+ console.log("\uD83D\uDD34 Circuit breaker activated! Failure rate: " + (recentFailureRate * 100).toFixed(1) + "%");
237
+ // Notificar cambio de estado
238
+ this.notifyCircuitBreakerStateChange(previousState, 'OPEN', recentFailureRate);
239
+ }
240
+ };
241
+ /**
242
+ * Notifica cambio de estado del circuit breaker
243
+ */
244
+ BacklogManager.prototype.notifyCircuitBreakerStateChange = function (previousState, newState, failureRate) {
245
+ if (this.config.onCircuitBreakerStateChange && previousState !== newState) {
246
+ var event_1 = {
247
+ listenerName: this.config.listenerName || 'unknown',
248
+ state: newState,
249
+ previousState: previousState,
250
+ timestamp: new Date(),
251
+ failureRate: failureRate,
252
+ failedCount: this.stats.failed,
253
+ processedCount: this.stats.processed
254
+ };
255
+ try {
256
+ var result = this.config.onCircuitBreakerStateChange(event_1);
257
+ if (result instanceof Promise) {
258
+ result.catch(function (err) { return console.error('Error in circuit breaker callback:', err); });
259
+ }
260
+ }
261
+ catch (err) {
262
+ console.error('Error in circuit breaker callback:', err);
263
+ }
264
+ }
265
+ };
266
+ /**
267
+ * Verifica si debe resetear circuit breaker
268
+ */
269
+ BacklogManager.prototype.checkCircuitBreakerReset = function () {
270
+ if (this.circuitBreakerOpen && this.circuitBreakerOpenTime) {
271
+ var timeSinceOpen = Date.now() - this.circuitBreakerOpenTime.getTime();
272
+ if (timeSinceOpen >= this.config.circuitBreakerResetTime) {
273
+ var previousState = this.circuitBreakerState;
274
+ var failureRate = this.stats.failed / (this.stats.processed + this.stats.failed);
275
+ this.circuitBreakerOpen = false;
276
+ this.circuitBreakerOpenTime = undefined;
277
+ this.circuitBreakerState = 'CLOSED';
278
+ // Reset failure stats for fresh start
279
+ this.stats.failed = Math.floor(this.stats.failed * 0.5);
280
+ console.log("\uD83D\uDFE2 Circuit breaker reset after " + timeSinceOpen + "ms");
281
+ // Notificar cambio de estado
282
+ this.notifyCircuitBreakerStateChange(previousState, 'CLOSED', failureRate);
283
+ }
284
+ }
285
+ };
286
+ /**
287
+ * Obtiene estadísticas actuales
288
+ */
289
+ BacklogManager.prototype.getStats = function () {
290
+ return __assign(__assign({}, this.stats), { queueSize: this.processingQueue.length, activeProcessing: this.activeProcessing, circuitBreakerOpen: this.circuitBreakerOpen, config: this.config });
291
+ };
292
+ /**
293
+ * Resetea estadísticas
294
+ */
295
+ BacklogManager.prototype.resetStats = function () {
296
+ this.stats = {
297
+ processed: 0,
298
+ failed: 0,
299
+ retries: 0,
300
+ circuitBreakerTrips: 0,
301
+ lastProcessedAt: new Date(),
302
+ averageProcessingTime: 0
303
+ };
304
+ this.processingTimes = [];
305
+ };
306
+ /**
307
+ * Actualiza configuración en tiempo real
308
+ */
309
+ BacklogManager.prototype.updateConfig = function (newConfig) {
310
+ this.config = __assign(__assign({}, this.config), newConfig);
311
+ console.log("\uD83D\uDD27 BacklogManager config updated:", newConfig);
312
+ };
313
+ /**
314
+ * Utility sleep function
315
+ */
316
+ BacklogManager.prototype.sleep = function (ms) {
317
+ return new Promise(function (resolve) { return setTimeout(resolve, ms); });
318
+ };
319
+ /**
320
+ * Fuerza el cierre del circuit breaker (para testing/debugging)
321
+ */
322
+ BacklogManager.prototype.forceCircuitBreakerOpen = function () {
323
+ var previousState = this.circuitBreakerState;
324
+ var failureRate = this.stats.failed / (this.stats.processed + this.stats.failed) || 0;
325
+ this.circuitBreakerOpen = true;
326
+ this.circuitBreakerOpenTime = new Date();
327
+ this.circuitBreakerState = 'OPEN';
328
+ this.stats.circuitBreakerTrips++;
329
+ this.notifyCircuitBreakerStateChange(previousState, 'OPEN', failureRate);
330
+ };
331
+ /**
332
+ * Fuerza la apertura del circuit breaker (para testing/debugging)
333
+ */
334
+ BacklogManager.prototype.forceCircuitBreakerClose = function () {
335
+ var previousState = this.circuitBreakerState;
336
+ var failureRate = this.stats.failed / (this.stats.processed + this.stats.failed) || 0;
337
+ this.circuitBreakerOpen = false;
338
+ this.circuitBreakerOpenTime = undefined;
339
+ this.circuitBreakerState = 'CLOSED';
340
+ this.notifyCircuitBreakerStateChange(previousState, 'CLOSED', failureRate);
341
+ };
342
+ /**
343
+ * Registra un callback para cambios de estado del circuit breaker
344
+ */
345
+ BacklogManager.prototype.onCircuitBreakerStateChange = function (callback) {
346
+ this.config.onCircuitBreakerStateChange = callback;
347
+ };
348
+ /**
349
+ * Obtiene el estado actual del circuit breaker
350
+ */
351
+ BacklogManager.prototype.getCircuitBreakerState = function () {
352
+ return this.circuitBreakerState;
353
+ };
354
+ /**
355
+ * Verifica si el BacklogManager está en capacidad máxima
356
+ * Usado para control de flujo en eachBatch
357
+ */
358
+ BacklogManager.prototype.isAtMaxCapacity = function () {
359
+ console.log(this.activeProcessing, this.config.maxConcurrent, this.processingQueue.length, this.config.backlogRecoveryBatchSize, this.circuitBreakerOpen);
360
+ console.log(this.activeProcessing >= this.config.maxConcurrent);
361
+ console.log(this.processingQueue.length >= this.config.backlogRecoveryBatchSize);
362
+ console.log(this.circuitBreakerOpen);
363
+ return this.activeProcessing >= this.config.maxConcurrent ||
364
+ this.processingQueue.length >= this.config.backlogRecoveryBatchSize ||
365
+ this.circuitBreakerOpen;
366
+ };
367
+ /**
368
+ * Obtiene la capacidad disponible actual
369
+ */
370
+ BacklogManager.prototype.getAvailableCapacity = function () {
371
+ if (this.circuitBreakerOpen) {
372
+ return 0;
373
+ }
374
+ var processingCapacity = Math.max(0, this.config.maxConcurrent - this.activeProcessing);
375
+ var queueCapacity = Math.max(0, this.config.backlogRecoveryBatchSize - this.processingQueue.length);
376
+ return Math.min(processingCapacity, queueCapacity);
377
+ };
378
+ /**
379
+ * Verifica si puede procesar un número específico de mensajes
380
+ */
381
+ BacklogManager.prototype.canProcessBatch = function (batchSize) {
382
+ return this.getAvailableCapacity() >= batchSize && !this.circuitBreakerOpen;
383
+ };
384
+ /**
385
+ * Espera hasta que haya capacidad disponible
386
+ * Usado en eachBatch para pausar el procesamiento
387
+ */
388
+ BacklogManager.prototype.waitForCapacity = function (minCapacity, timeoutMs) {
389
+ if (minCapacity === void 0) { minCapacity = 1; }
390
+ if (timeoutMs === void 0) { timeoutMs = 30000; }
391
+ return __awaiter(this, void 0, void 0, function () {
392
+ var startTime;
393
+ return __generator(this, function (_a) {
394
+ switch (_a.label) {
395
+ case 0:
396
+ startTime = Date.now();
397
+ _a.label = 1;
398
+ case 1:
399
+ if (!(this.getAvailableCapacity() < minCapacity && !this.circuitBreakerOpen)) return [3 /*break*/, 3];
400
+ if (Date.now() - startTime > timeoutMs) {
401
+ console.warn("\u23F0 Timeout waiting for capacity after " + timeoutMs + "ms");
402
+ return [2 /*return*/, false];
403
+ }
404
+ // Esperar un poco antes de verificar de nuevo
405
+ return [4 /*yield*/, this.sleep(200)];
406
+ case 2:
407
+ // Esperar un poco antes de verificar de nuevo
408
+ _a.sent();
409
+ return [3 /*break*/, 1];
410
+ case 3: return [2 /*return*/, !this.circuitBreakerOpen];
411
+ }
412
+ });
413
+ });
414
+ };
415
+ return BacklogManager;
416
+ }());
417
+ exports.BacklogManager = BacklogManager;
@@ -0,0 +1,102 @@
1
+ export interface MonitorableListener {
2
+ groupName: string;
3
+ topic: string;
4
+ getStats(): {
5
+ listenerName: string;
6
+ topic: string;
7
+ groupName: string;
8
+ processed: number;
9
+ failed: number;
10
+ retries: number;
11
+ queueSize: number;
12
+ activeProcessing: number;
13
+ circuitBreakerOpen: boolean;
14
+ averageProcessingTime: number;
15
+ lastProcessedAt: Date;
16
+ config: any;
17
+ };
18
+ updateBacklogConfig(newConfig: any): void;
19
+ resetStats(): void;
20
+ forceCircuitBreaker(open: boolean): void;
21
+ }
22
+ export interface ListenerStats {
23
+ listenerName: string;
24
+ topic: string;
25
+ groupName: string;
26
+ processed: number;
27
+ failed: number;
28
+ retries: number;
29
+ queueSize: number;
30
+ activeProcessing: number;
31
+ circuitBreakerOpen: boolean;
32
+ averageProcessingTime: number;
33
+ successRate: number;
34
+ lastProcessedAt: Date;
35
+ config: any;
36
+ }
37
+ export interface SystemStats {
38
+ totalListeners: number;
39
+ activeListeners: number;
40
+ totalProcessed: number;
41
+ totalFailed: number;
42
+ totalRetries: number;
43
+ totalQueueSize: number;
44
+ totalActiveProcessing: number;
45
+ circuitBreakersOpen: number;
46
+ overallSuccessRate: number;
47
+ systemHealth: 'healthy' | 'degraded' | 'critical';
48
+ }
49
+ export declare class BacklogMonitor {
50
+ private static instance;
51
+ private listeners;
52
+ private constructor();
53
+ static getInstance(): BacklogMonitor;
54
+ /**
55
+ * Registra un listener para monitoreo (EnhancedListener o BatchEnhancedListener)
56
+ */
57
+ registerListener(listener: MonitorableListener): void;
58
+ /**
59
+ * Desregistra un listener
60
+ */
61
+ unregisterListener(groupName: string, topic: string): void;
62
+ /**
63
+ * Obtiene estadísticas de un listener específico
64
+ */
65
+ getListenerStats(groupName: string, topic: string): ListenerStats | null;
66
+ /**
67
+ * Obtiene estadísticas de todos los listeners
68
+ */
69
+ getAllListenersStats(): ListenerStats[];
70
+ /**
71
+ * Obtiene estadísticas del sistema completo
72
+ */
73
+ getSystemStats(): SystemStats;
74
+ /**
75
+ * Actualiza configuración de un listener específico
76
+ */
77
+ updateListenerConfig(groupName: string, topic: string, newConfig: any): boolean;
78
+ /**
79
+ * Actualiza configuración de todos los listeners
80
+ */
81
+ updateAllListenersConfig(newConfig: any): number;
82
+ /**
83
+ * Resetea estadísticas de un listener específico
84
+ */
85
+ resetListenerStats(groupName: string, topic: string): boolean;
86
+ /**
87
+ * Resetea estadísticas de todos los listeners
88
+ */
89
+ resetAllStats(): number;
90
+ /**
91
+ * Fuerza circuit breaker para un listener específico
92
+ */
93
+ forceCircuitBreaker(groupName: string, topic: string, open: boolean): boolean;
94
+ /**
95
+ * Obtiene resumen de salud del sistema
96
+ */
97
+ getHealthSummary(): {
98
+ status: string;
99
+ message: string;
100
+ details: any;
101
+ };
102
+ }