@naman_deep_singh/communication-core 1.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 (134) hide show
  1. package/README.md +345 -0
  2. package/dist/cjs/abstract/BaseCircuitBreaker.js +253 -0
  3. package/dist/cjs/abstract/BaseClient.js +298 -0
  4. package/dist/cjs/abstract/BaseCompressionManager.js +377 -0
  5. package/dist/cjs/abstract/BaseConnectionPool.js +543 -0
  6. package/dist/cjs/abstract/BaseInterceptor.js +235 -0
  7. package/dist/cjs/abstract/BaseLoadBalancer.js +269 -0
  8. package/dist/cjs/abstract/BaseProtocol.js +269 -0
  9. package/dist/cjs/abstract/BaseRetryStrategy.js +255 -0
  10. package/dist/cjs/abstract/BaseSerializer.js +341 -0
  11. package/dist/cjs/abstract/BaseServiceDiscoverer.js +254 -0
  12. package/dist/cjs/abstract/BaseTimeoutManager.js +295 -0
  13. package/dist/cjs/abstract/index.js +25 -0
  14. package/dist/cjs/errors/CircuitBreakerError.js +16 -0
  15. package/dist/cjs/errors/CommunicationError.js +15 -0
  16. package/dist/cjs/errors/ConnectionError.js +15 -0
  17. package/dist/cjs/errors/DiscoveryError.js +15 -0
  18. package/dist/cjs/errors/LoadBalancerError.js +15 -0
  19. package/dist/cjs/errors/ProtocolError.js +15 -0
  20. package/dist/cjs/errors/RetryError.js +16 -0
  21. package/dist/cjs/errors/SerializationError.js +15 -0
  22. package/dist/cjs/errors/ServiceUnavailableError.js +15 -0
  23. package/dist/cjs/errors/TimeoutError.js +16 -0
  24. package/dist/cjs/errors/communicationErrorCodes.js +35 -0
  25. package/dist/cjs/errors/index.js +31 -0
  26. package/dist/cjs/index.js +38 -0
  27. package/dist/cjs/interfaces/CircuitBreaker.interface.js +6 -0
  28. package/dist/cjs/interfaces/Client.interface.js +6 -0
  29. package/dist/cjs/interfaces/Compression.interface.js +6 -0
  30. package/dist/cjs/interfaces/ConnectionPool.interface.js +6 -0
  31. package/dist/cjs/interfaces/Interceptor.interface.js +6 -0
  32. package/dist/cjs/interfaces/LoadBalancer.interface.js +2 -0
  33. package/dist/cjs/interfaces/Protocol.interface.js +6 -0
  34. package/dist/cjs/interfaces/RetryStrategy.interface.js +6 -0
  35. package/dist/cjs/interfaces/Serializer.interface.js +2 -0
  36. package/dist/cjs/interfaces/ServiceDiscovery.interface.js +6 -0
  37. package/dist/cjs/interfaces/Timeout.interface.js +6 -0
  38. package/dist/cjs/interfaces/index.js +6 -0
  39. package/dist/cjs/types/config.js +6 -0
  40. package/dist/cjs/types/events.js +6 -0
  41. package/dist/cjs/types/index.js +6 -0
  42. package/dist/cjs/types/request.js +6 -0
  43. package/dist/cjs/types/response.js +6 -0
  44. package/dist/cjs/types/service.js +6 -0
  45. package/dist/cjs/utils.js +200 -0
  46. package/dist/esm/abstract/BaseCircuitBreaker.js +249 -0
  47. package/dist/esm/abstract/BaseClient.js +294 -0
  48. package/dist/esm/abstract/BaseCompressionManager.js +373 -0
  49. package/dist/esm/abstract/BaseConnectionPool.js +539 -0
  50. package/dist/esm/abstract/BaseInterceptor.js +231 -0
  51. package/dist/esm/abstract/BaseLoadBalancer.js +265 -0
  52. package/dist/esm/abstract/BaseProtocol.js +265 -0
  53. package/dist/esm/abstract/BaseRetryStrategy.js +251 -0
  54. package/dist/esm/abstract/BaseSerializer.js +337 -0
  55. package/dist/esm/abstract/BaseServiceDiscoverer.js +250 -0
  56. package/dist/esm/abstract/BaseTimeoutManager.js +291 -0
  57. package/dist/esm/abstract/index.js +11 -0
  58. package/dist/esm/errors/CircuitBreakerError.js +12 -0
  59. package/dist/esm/errors/CommunicationError.js +11 -0
  60. package/dist/esm/errors/ConnectionError.js +11 -0
  61. package/dist/esm/errors/DiscoveryError.js +11 -0
  62. package/dist/esm/errors/LoadBalancerError.js +11 -0
  63. package/dist/esm/errors/ProtocolError.js +11 -0
  64. package/dist/esm/errors/RetryError.js +12 -0
  65. package/dist/esm/errors/SerializationError.js +11 -0
  66. package/dist/esm/errors/ServiceUnavailableError.js +11 -0
  67. package/dist/esm/errors/TimeoutError.js +12 -0
  68. package/dist/esm/errors/communicationErrorCodes.js +32 -0
  69. package/dist/esm/errors/index.js +17 -0
  70. package/dist/esm/index.js +18 -0
  71. package/dist/esm/interfaces/CircuitBreaker.interface.js +5 -0
  72. package/dist/esm/interfaces/Client.interface.js +5 -0
  73. package/dist/esm/interfaces/Compression.interface.js +5 -0
  74. package/dist/esm/interfaces/ConnectionPool.interface.js +5 -0
  75. package/dist/esm/interfaces/Interceptor.interface.js +5 -0
  76. package/dist/esm/interfaces/LoadBalancer.interface.js +1 -0
  77. package/dist/esm/interfaces/Protocol.interface.js +5 -0
  78. package/dist/esm/interfaces/RetryStrategy.interface.js +5 -0
  79. package/dist/esm/interfaces/Serializer.interface.js +1 -0
  80. package/dist/esm/interfaces/ServiceDiscovery.interface.js +5 -0
  81. package/dist/esm/interfaces/Timeout.interface.js +5 -0
  82. package/dist/esm/interfaces/index.js +5 -0
  83. package/dist/esm/types/config.js +5 -0
  84. package/dist/esm/types/events.js +5 -0
  85. package/dist/esm/types/index.js +5 -0
  86. package/dist/esm/types/request.js +5 -0
  87. package/dist/esm/types/response.js +5 -0
  88. package/dist/esm/types/service.js +5 -0
  89. package/dist/esm/utils.js +193 -0
  90. package/dist/types/abstract/BaseCircuitBreaker.d.ts +167 -0
  91. package/dist/types/abstract/BaseClient.d.ts +197 -0
  92. package/dist/types/abstract/BaseCompressionManager.d.ts +180 -0
  93. package/dist/types/abstract/BaseConnectionPool.d.ts +210 -0
  94. package/dist/types/abstract/BaseInterceptor.d.ts +150 -0
  95. package/dist/types/abstract/BaseLoadBalancer.d.ts +167 -0
  96. package/dist/types/abstract/BaseProtocol.d.ts +163 -0
  97. package/dist/types/abstract/BaseRetryStrategy.d.ts +130 -0
  98. package/dist/types/abstract/BaseSerializer.d.ts +181 -0
  99. package/dist/types/abstract/BaseServiceDiscoverer.d.ts +161 -0
  100. package/dist/types/abstract/BaseTimeoutManager.d.ts +145 -0
  101. package/dist/types/abstract/index.d.ts +11 -0
  102. package/dist/types/errors/CircuitBreakerError.d.ts +8 -0
  103. package/dist/types/errors/CommunicationError.d.ts +10 -0
  104. package/dist/types/errors/ConnectionError.d.ts +9 -0
  105. package/dist/types/errors/DiscoveryError.d.ts +9 -0
  106. package/dist/types/errors/LoadBalancerError.d.ts +9 -0
  107. package/dist/types/errors/ProtocolError.d.ts +9 -0
  108. package/dist/types/errors/RetryError.d.ts +11 -0
  109. package/dist/types/errors/SerializationError.d.ts +9 -0
  110. package/dist/types/errors/ServiceUnavailableError.d.ts +12 -0
  111. package/dist/types/errors/TimeoutError.d.ts +11 -0
  112. package/dist/types/errors/communicationErrorCodes.d.ts +27 -0
  113. package/dist/types/errors/index.d.ts +11 -0
  114. package/dist/types/index.d.ts +13 -0
  115. package/dist/types/interfaces/CircuitBreaker.interface.d.ts +150 -0
  116. package/dist/types/interfaces/Client.interface.d.ts +153 -0
  117. package/dist/types/interfaces/Compression.interface.d.ts +190 -0
  118. package/dist/types/interfaces/ConnectionPool.interface.d.ts +191 -0
  119. package/dist/types/interfaces/Interceptor.interface.d.ts +220 -0
  120. package/dist/types/interfaces/LoadBalancer.interface.d.ts +153 -0
  121. package/dist/types/interfaces/Protocol.interface.d.ts +117 -0
  122. package/dist/types/interfaces/RetryStrategy.interface.d.ts +160 -0
  123. package/dist/types/interfaces/Serializer.interface.d.ts +176 -0
  124. package/dist/types/interfaces/ServiceDiscovery.interface.d.ts +189 -0
  125. package/dist/types/interfaces/Timeout.interface.d.ts +135 -0
  126. package/dist/types/interfaces/index.d.ts +15 -0
  127. package/dist/types/types/config.d.ts +540 -0
  128. package/dist/types/types/events.d.ts +204 -0
  129. package/dist/types/types/index.d.ts +9 -0
  130. package/dist/types/types/request.d.ts +143 -0
  131. package/dist/types/types/response.d.ts +155 -0
  132. package/dist/types/types/service.d.ts +279 -0
  133. package/dist/types/utils.d.ts +179 -0
  134. package/package.json +88 -0
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ /**
3
+ * Service discovery interface for communication layer
4
+ * @packageDocumentation
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ /**
3
+ * Timeout interface for communication layer
4
+ * @packageDocumentation
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ /**
3
+ * Interface definitions for communication layer
4
+ * @packageDocumentation
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ /**
3
+ * Configuration types for communication layer
4
+ * @packageDocumentation
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ /**
3
+ * Event types for communication layer
4
+ * @packageDocumentation
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ /**
3
+ * Type definitions for communication layer
4
+ * @packageDocumentation
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ /**
3
+ * Request types and interfaces for communication layer
4
+ * @packageDocumentation
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ /**
3
+ * Response types and interfaces for communication layer
4
+ * @packageDocumentation
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ /**
3
+ * Service discovery and instance types
4
+ * @packageDocumentation
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,200 @@
1
+ "use strict";
2
+ /**
3
+ * Utilities integration with @naman_deep_singh/utils package
4
+ * @packageDocumentation
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.CompressionUtils = exports.ConnectionPoolUtils = exports.TimeoutUtils = exports.BaseConnection = void 0;
8
+ const utils_1 = require("@naman_deep_singh/utils");
9
+ /**
10
+ * Base connection implementation that satisfies both interfaces
11
+ */
12
+ class BaseConnection {
13
+ }
14
+ exports.BaseConnection = BaseConnection;
15
+ /**
16
+ * Timeout utilities wrapper
17
+ */
18
+ class TimeoutUtils {
19
+ /**
20
+ * Execute with timeout
21
+ */
22
+ static async withTimeout(promise, timeoutMs, errorMessage) {
23
+ return utils_1.TimeoutManager.withTimeout(promise, timeoutMs, errorMessage);
24
+ }
25
+ /**
26
+ * Create delay
27
+ */
28
+ static async delay(ms) {
29
+ return utils_1.TimeoutManager.delay(ms);
30
+ }
31
+ /**
32
+ * Retry with timeout
33
+ */
34
+ static async retryWithTimeout(fn, options) {
35
+ return utils_1.TimeoutManager.retryWithTimeout(fn, options);
36
+ }
37
+ /**
38
+ * Create a timeout promise
39
+ */
40
+ static createTimeout(timeoutMs, message) {
41
+ return new Promise((_, reject) => {
42
+ setTimeout(() => {
43
+ reject(new Error(message || `Timeout after ${timeoutMs}ms`));
44
+ }, timeoutMs);
45
+ });
46
+ }
47
+ /**
48
+ * Create an abort signal for timeout
49
+ */
50
+ static createAbortSignal(timeoutMs) {
51
+ const controller = new AbortController();
52
+ setTimeout(() => controller.abort(), timeoutMs);
53
+ return controller.signal;
54
+ }
55
+ /**
56
+ * Race promises with timeout
57
+ */
58
+ static async raceWithTimeout(promises, timeoutMs, errorMessage) {
59
+ const timeoutPromise = this.createTimeout(timeoutMs, errorMessage);
60
+ return Promise.race([...promises, timeoutPromise]);
61
+ }
62
+ }
63
+ exports.TimeoutUtils = TimeoutUtils;
64
+ /**
65
+ * Connection pool wrapper
66
+ */
67
+ class ConnectionPoolUtils {
68
+ /**
69
+ * Create a generic connection pool
70
+ */
71
+ static createPool(config) {
72
+ return new utils_1.GenericPool({
73
+ name: config.name,
74
+ minConnections: config.minConnections,
75
+ maxConnections: config.maxConnections,
76
+ createConnection: config.createConnection,
77
+ validateConnection: config.validateConnection,
78
+ idleTimeoutMs: config.idleTimeout,
79
+ maxLifetimeMs: config.maxLifetime,
80
+ acquireTimeoutMs: config.acquireTimeout,
81
+ });
82
+ }
83
+ /**
84
+ * Create a simple pool with basic configuration
85
+ */
86
+ static createSimplePool(name, createConnection, options) {
87
+ return new utils_1.GenericPool({
88
+ name,
89
+ minConnections: options?.minConnections,
90
+ maxConnections: options?.maxConnections,
91
+ createConnection,
92
+ idleTimeoutMs: options?.idleTimeout,
93
+ });
94
+ }
95
+ /**
96
+ * Create an adapter to convert property-based isHealthy to function-based
97
+ */
98
+ static createConnectionAdapter(connection, closeFn = async () => { }, healthCheckFn = async () => true, resetFn = async () => { }) {
99
+ // Handle isHealthy conversion
100
+ const getIsHealthy = () => {
101
+ if (typeof connection.isHealthy === 'function') {
102
+ return connection.isHealthy();
103
+ }
104
+ return connection.isHealthy ?? true;
105
+ };
106
+ return {
107
+ id: connection.id || `conn-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
108
+ // isHealthy must be a function
109
+ isHealthy: getIsHealthy,
110
+ createdAt: connection.createdAt || Date.now(),
111
+ lastUsedAt: connection.lastUsedAt || Date.now(),
112
+ usageCount: connection.usageCount || 0,
113
+ metadata: connection.metadata || {},
114
+ close: closeFn,
115
+ healthCheck: healthCheckFn,
116
+ reset: resetFn,
117
+ };
118
+ }
119
+ }
120
+ exports.ConnectionPoolUtils = ConnectionPoolUtils;
121
+ /**
122
+ * Compression utilities wrapper
123
+ */
124
+ class CompressionUtils {
125
+ /**
126
+ * Compress data
127
+ */
128
+ static async compress(data, options) {
129
+ const result = await utils_1.Compression.compress(Buffer.from(data), {
130
+ algorithm: options?.algorithm || 'gzip',
131
+ level: options?.level || 6,
132
+ });
133
+ return Buffer.from(result);
134
+ }
135
+ /**
136
+ * Decompress data
137
+ */
138
+ static async decompress(data, options) {
139
+ const result = await utils_1.Compression.decompress(Buffer.from(data), {
140
+ algorithm: options?.algorithm || 'gzip',
141
+ });
142
+ return Buffer.from(result);
143
+ }
144
+ /**
145
+ * Compress data with metrics
146
+ */
147
+ static async compressWithMetrics(data, options) {
148
+ const startTime = Date.now();
149
+ const originalSize = Buffer.from(data).length;
150
+ const compressed = await utils_1.Compression.compress(Buffer.from(data), {
151
+ algorithm: options?.algorithm || 'gzip',
152
+ level: options?.level || 6,
153
+ });
154
+ const compressionTime = Date.now() - startTime;
155
+ const compressedSize = compressed.length;
156
+ const compressionRatio = compressedSize / originalSize;
157
+ return {
158
+ data: Buffer.from(compressed),
159
+ originalSize,
160
+ compressedSize,
161
+ compressionRatio,
162
+ compressionTime,
163
+ };
164
+ }
165
+ /**
166
+ * Get optimal compression level based on data size
167
+ */
168
+ static getOptimalLevel(dataSize) {
169
+ if (dataSize < 1024)
170
+ return 1; // Small data, fast compression
171
+ if (dataSize < 10240)
172
+ return 6; // Medium data, balanced
173
+ return 9; // Large data, best compression
174
+ }
175
+ /**
176
+ * Estimate compression ratio for data type
177
+ */
178
+ static estimateCompressionRatio(contentType) {
179
+ if (!contentType)
180
+ return 0.7;
181
+ const type = contentType.toLowerCase();
182
+ if (type.includes('json') || type.includes('xml'))
183
+ return 0.3;
184
+ if (type.includes('text'))
185
+ return 0.4;
186
+ if (type.includes('image') || type.includes('video'))
187
+ return 0.95;
188
+ return 0.7;
189
+ }
190
+ }
191
+ exports.CompressionUtils = CompressionUtils;
192
+ /**
193
+ * Compression algorithm type
194
+ */
195
+ CompressionUtils.Algorithm = {
196
+ GZIP: 'gzip',
197
+ DEFLATE: 'deflate',
198
+ BROTLI: 'brotli',
199
+ NONE: 'none',
200
+ };
@@ -0,0 +1,249 @@
1
+ /**
2
+ * Abstract base circuit breaker implementation
3
+ * @packageDocumentation
4
+ */
5
+ /**
6
+ * Abstract base circuit breaker implementation
7
+ * Provides common functionality for all circuit breaker implementations
8
+ */
9
+ export class BaseCircuitBreaker {
10
+ /**
11
+ * Create a new base circuit breaker instance
12
+ * @param name Circuit breaker name
13
+ * @param config Circuit breaker configuration
14
+ */
15
+ constructor(name, config) {
16
+ /** Current state */
17
+ this.state = 'closed';
18
+ /** Failure count */
19
+ this.failureCount = 0;
20
+ /** Success count */
21
+ this.successCount = 0;
22
+ /** Circuit breaker statistics */
23
+ this.stats = {
24
+ totalExecutions: 0,
25
+ totalSuccesses: 0,
26
+ totalFailures: 0,
27
+ successRate: 0,
28
+ failureRate: 0,
29
+ totalTimeOpen: 0,
30
+ totalTimeClosed: 0,
31
+ lastStateChange: Date.now(),
32
+ };
33
+ /** Time when current state was entered */
34
+ this.stateEnteredTime = Date.now();
35
+ this.name = name;
36
+ this.config = { ...config };
37
+ this.initialize();
38
+ }
39
+ /**
40
+ * Initialize circuit breaker
41
+ */
42
+ initialize() {
43
+ // Can be overridden by subclasses
44
+ }
45
+ /**
46
+ * Check if circuit breaker should allow execution
47
+ * @returns True if execution is allowed
48
+ */
49
+ shouldAllowExecution() {
50
+ switch (this.state) {
51
+ case 'closed':
52
+ return true;
53
+ case 'open':
54
+ if (this.nextResetTime && Date.now() >= this.nextResetTime) {
55
+ this.transitionToHalfOpen();
56
+ return true;
57
+ }
58
+ return false;
59
+ case 'half-open':
60
+ return this.failureCount < (this.config.halfOpenMaxAttempts || 1);
61
+ default:
62
+ return false;
63
+ }
64
+ }
65
+ /**
66
+ * Transition circuit breaker to closed state
67
+ */
68
+ transitionToClosed() {
69
+ const previousState = this.state;
70
+ this.state = 'closed';
71
+ this.failureCount = 0;
72
+ this.successCount = 0;
73
+ this.nextResetTime = undefined;
74
+ this.updateStateTime(previousState);
75
+ this.onStateChange('closed', previousState);
76
+ }
77
+ /**
78
+ * Transition circuit breaker to open state
79
+ * @param error Optional error that caused the transition
80
+ */
81
+ transitionToOpen(error) {
82
+ const previousState = this.state;
83
+ this.state = 'open';
84
+ this.nextResetTime = Date.now() + (this.config.resetTimeout || 30000);
85
+ this.updateStateTime(previousState);
86
+ this.onStateChange('open', previousState, error);
87
+ }
88
+ /**
89
+ * Transition circuit breaker to half-open state
90
+ */
91
+ transitionToHalfOpen() {
92
+ const previousState = this.state;
93
+ this.state = 'half-open';
94
+ this.failureCount = 0;
95
+ this.successCount = 0;
96
+ this.updateStateTime(previousState);
97
+ this.onStateChange('half-open', previousState);
98
+ }
99
+ /**
100
+ * Update state timing statistics
101
+ * @param previousState Previous state
102
+ */
103
+ updateStateTime(previousState) {
104
+ const now = Date.now();
105
+ const timeInState = now - this.stateEnteredTime;
106
+ if (previousState === 'open') {
107
+ this.stats.totalTimeOpen += timeInState;
108
+ }
109
+ else if (previousState === 'closed') {
110
+ this.stats.totalTimeClosed += timeInState;
111
+ }
112
+ this.stateEnteredTime = now;
113
+ this.stats.lastStateChange = now;
114
+ }
115
+ /**
116
+ * Hook for state changes
117
+ * @param newState New state
118
+ * @param previousState Previous state
119
+ * @param error Optional error that caused state change
120
+ */
121
+ onStateChange(newState, previousState, error) {
122
+ // Can be overridden by subclasses
123
+ // Emit events, log, etc.
124
+ }
125
+ /**
126
+ * Check if failure threshold is reached
127
+ * @returns True if failure threshold reached
128
+ */
129
+ isFailureThresholdReached() {
130
+ return this.failureCount >= (this.config.failureThreshold || 5);
131
+ }
132
+ /**
133
+ * Check if success threshold is reached
134
+ * @returns True if success threshold reached
135
+ */
136
+ isSuccessThresholdReached() {
137
+ return this.successCount >= (this.config.successThreshold || 1);
138
+ }
139
+ /**
140
+ * Manually trip the circuit breaker to open state
141
+ * @param error Error that caused the trip
142
+ */
143
+ trip(error) {
144
+ this.transitionToOpen(error);
145
+ }
146
+ /**
147
+ * Manually reset the circuit breaker to closed state
148
+ */
149
+ reset() {
150
+ this.transitionToClosed();
151
+ }
152
+ /**
153
+ * Check if circuit breaker is currently open
154
+ */
155
+ isOpen() {
156
+ return this.state === 'open';
157
+ }
158
+ /**
159
+ * Check if circuit breaker is currently closed
160
+ */
161
+ isClosed() {
162
+ return this.state === 'closed';
163
+ }
164
+ /**
165
+ * Check if circuit breaker is in half-open state
166
+ */
167
+ isHalfOpen() {
168
+ return this.state === 'half-open';
169
+ }
170
+ /**
171
+ * Record a successful execution
172
+ */
173
+ recordSuccess() {
174
+ this.successCount++;
175
+ this.lastSuccessTime = Date.now();
176
+ this.stats.totalSuccesses++;
177
+ if (this.state === 'half-open' && this.isSuccessThresholdReached()) {
178
+ this.transitionToClosed();
179
+ }
180
+ }
181
+ /**
182
+ * Record a failed execution
183
+ * @param error Error that occurred
184
+ */
185
+ recordFailure(error) {
186
+ this.failureCount++;
187
+ this.lastFailureTime = Date.now();
188
+ this.stats.totalFailures++;
189
+ if (this.state === 'half-open') {
190
+ this.transitionToOpen(error);
191
+ }
192
+ else if (this.state === 'closed' && this.isFailureThresholdReached()) {
193
+ this.transitionToOpen(error);
194
+ }
195
+ }
196
+ /**
197
+ * Get circuit breaker statistics
198
+ */
199
+ getStats() {
200
+ const total = this.stats.totalSuccesses + this.stats.totalFailures;
201
+ return {
202
+ ...this.stats,
203
+ successRate: total > 0 ? this.stats.totalSuccesses / total : 0,
204
+ failureRate: total > 0 ? this.stats.totalFailures / total : 0,
205
+ };
206
+ }
207
+ /**
208
+ * Reset circuit breaker statistics
209
+ */
210
+ resetStats() {
211
+ this.stats = {
212
+ totalExecutions: 0,
213
+ totalSuccesses: 0,
214
+ totalFailures: 0,
215
+ successRate: 0,
216
+ failureRate: 0,
217
+ totalTimeOpen: 0,
218
+ totalTimeClosed: 0,
219
+ lastStateChange: Date.now(),
220
+ };
221
+ }
222
+ /**
223
+ * Update circuit breaker configuration
224
+ * @param config New configuration
225
+ */
226
+ updateConfig(config) {
227
+ this.config = { ...this.config, ...config };
228
+ }
229
+ /**
230
+ * Health check for the circuit breaker
231
+ */
232
+ healthCheck() {
233
+ const healthy = this.state === 'closed' || this.state === 'half-open';
234
+ return {
235
+ healthy,
236
+ state: this.state,
237
+ message: healthy ? 'Circuit breaker is operational' : 'Circuit breaker is open',
238
+ details: {
239
+ name: this.name,
240
+ failureCount: this.failureCount,
241
+ successCount: this.successCount,
242
+ lastFailureTime: this.lastFailureTime,
243
+ lastSuccessTime: this.lastSuccessTime,
244
+ nextResetTime: this.nextResetTime,
245
+ config: this.config,
246
+ },
247
+ };
248
+ }
249
+ }