@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,269 @@
1
+ "use strict";
2
+ /**
3
+ * Abstract base protocol implementation
4
+ * @packageDocumentation
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.BaseProtocol = void 0;
8
+ const CommunicationError_js_1 = require("../errors/CommunicationError.js");
9
+ /**
10
+ * Abstract base protocol implementation
11
+ * Provides common functionality for all protocol implementations
12
+ */
13
+ class BaseProtocol {
14
+ /**
15
+ * Create a new base protocol instance
16
+ * @param name Protocol name
17
+ * @param config Protocol configuration
18
+ */
19
+ constructor(name, config) {
20
+ /** Protocol interceptors */
21
+ this.interceptors = [];
22
+ /** Protocol metrics */
23
+ this.metrics = {};
24
+ /** Whether protocol is connected (for stateful protocols) */
25
+ this.connected = false;
26
+ /** Protocol start time */
27
+ this.startTime = Date.now();
28
+ /** Total requests sent */
29
+ this.totalRequests = 0;
30
+ /** Total successful requests */
31
+ this.successfulRequests = 0;
32
+ /** Total failed requests */
33
+ this.failedRequests = 0;
34
+ this.name = name;
35
+ this.config = { ...config };
36
+ this.version = config.options?.version || '1.0.0';
37
+ }
38
+ /**
39
+ * Configure the protocol with new settings
40
+ * @param config Configuration object
41
+ */
42
+ configure(config) {
43
+ this.config = { ...this.config, ...config };
44
+ this.onConfigure(config);
45
+ }
46
+ /**
47
+ * Hook for protocol configuration changes
48
+ * @param newConfig New configuration
49
+ */
50
+ onConfigure(newConfig) {
51
+ // Can be overridden by subclasses
52
+ }
53
+ /**
54
+ * Connect to the service (for stateful protocols)
55
+ * @returns Promise that resolves when connected
56
+ */
57
+ async connect() {
58
+ this.connected = true;
59
+ await this.onConnect?.();
60
+ }
61
+ /**
62
+ * Hook for connection logic
63
+ */
64
+ async onConnect() {
65
+ // Can be overridden by subclasses
66
+ }
67
+ /**
68
+ * Disconnect from the service (for stateful protocols)
69
+ * @returns Promise that resolves when disconnected
70
+ */
71
+ async disconnect() {
72
+ this.connected = false;
73
+ await this.onDisconnect?.();
74
+ }
75
+ /**
76
+ * Hook for disconnection logic
77
+ */
78
+ async onDisconnect() {
79
+ // Can be overridden by subclasses
80
+ }
81
+ /**
82
+ * Check if the protocol is currently connected
83
+ * @returns True if connected, false otherwise
84
+ */
85
+ isConnected() {
86
+ return this.connected;
87
+ }
88
+ /**
89
+ * Add an interceptor to the protocol
90
+ * @param interceptor Interceptor to add
91
+ */
92
+ addInterceptor(interceptor) {
93
+ this.interceptors.push(interceptor);
94
+ interceptor.initialize?.({ protocol: this.name });
95
+ this.onInterceptorAdded(interceptor);
96
+ }
97
+ /**
98
+ * Hook for interceptor addition
99
+ * @param interceptor Added interceptor
100
+ */
101
+ onInterceptorAdded(interceptor) {
102
+ // Can be overridden by subclasses
103
+ }
104
+ /**
105
+ * Remove an interceptor from the protocol
106
+ * @param interceptorId Interceptor identifier
107
+ */
108
+ removeInterceptor(interceptorId) {
109
+ const index = this.interceptors.findIndex(i => i.name === interceptorId);
110
+ if (index !== -1) {
111
+ const interceptor = this.interceptors[index];
112
+ interceptor.cleanup?.();
113
+ this.interceptors.splice(index, 1);
114
+ this.onInterceptorRemoved(interceptorId);
115
+ }
116
+ }
117
+ /**
118
+ * Hook for interceptor removal
119
+ * @param interceptorId Removed interceptor ID
120
+ */
121
+ onInterceptorRemoved(interceptorId) {
122
+ // Can be overridden by subclasses
123
+ }
124
+ /**
125
+ * Get all interceptors
126
+ */
127
+ getInterceptors() {
128
+ return [...this.interceptors];
129
+ }
130
+ /**
131
+ * Execute request interceptors
132
+ * @param request Original request
133
+ * @param context Request context
134
+ * @returns Modified request
135
+ */
136
+ async executeRequestInterceptors(request, context) {
137
+ let modifiedRequest = request;
138
+ for (const interceptor of this.interceptors) {
139
+ if (interceptor.enabled && interceptor.onRequest) {
140
+ const result = await interceptor.onRequest(modifiedRequest, context);
141
+ if (result !== undefined) {
142
+ modifiedRequest = result;
143
+ }
144
+ }
145
+ }
146
+ return modifiedRequest;
147
+ }
148
+ /**
149
+ * Execute response interceptors
150
+ * @param response Original response
151
+ * @param context Request context
152
+ * @returns Modified response
153
+ */
154
+ async executeResponseInterceptors(response, context) {
155
+ let modifiedResponse = response;
156
+ for (const interceptor of this.interceptors) {
157
+ if (interceptor.enabled && interceptor.onResponse) {
158
+ const result = await interceptor.onResponse(modifiedResponse, context);
159
+ if (result !== undefined) {
160
+ modifiedResponse = result;
161
+ }
162
+ }
163
+ }
164
+ return modifiedResponse;
165
+ }
166
+ /**
167
+ * Execute error interceptors
168
+ * @param error Original error
169
+ * @param context Request context
170
+ * @returns Modified error or response
171
+ */
172
+ async executeErrorInterceptors(error, context) {
173
+ let result = error;
174
+ for (const interceptor of this.interceptors) {
175
+ if (interceptor.enabled && interceptor.onError) {
176
+ const interceptorResult = await interceptor.onError(result instanceof CommunicationError_js_1.CommunicationError ? result : error, context);
177
+ if (interceptorResult !== undefined) {
178
+ result = interceptorResult;
179
+ }
180
+ }
181
+ }
182
+ return result;
183
+ }
184
+ /**
185
+ * Update request metrics
186
+ * @param success Whether request was successful
187
+ * @param duration Request duration in milliseconds
188
+ */
189
+ updateMetrics(success, duration) {
190
+ this.totalRequests++;
191
+ if (success) {
192
+ this.successfulRequests++;
193
+ }
194
+ else {
195
+ this.failedRequests++;
196
+ }
197
+ this.metrics = {
198
+ ...this.metrics,
199
+ totalRequests: this.totalRequests,
200
+ successfulRequests: this.successfulRequests,
201
+ failedRequests: this.failedRequests,
202
+ successRate: this.totalRequests > 0 ? this.successfulRequests / this.totalRequests : 0,
203
+ averageResponseTime: this.calculateAverageResponseTime(duration),
204
+ uptime: Date.now() - this.startTime,
205
+ };
206
+ }
207
+ /**
208
+ * Calculate average response time
209
+ * @param newDuration New request duration
210
+ * @returns Average response time
211
+ */
212
+ calculateAverageResponseTime(newDuration) {
213
+ const currentAverage = this.metrics.averageResponseTime || 0;
214
+ const totalDuration = currentAverage * (this.totalRequests - 1) + newDuration;
215
+ return totalDuration / this.totalRequests;
216
+ }
217
+ /**
218
+ * Get protocol metrics
219
+ */
220
+ getMetrics() {
221
+ return { ...this.metrics };
222
+ }
223
+ /**
224
+ * Reset protocol metrics
225
+ */
226
+ resetMetrics() {
227
+ this.totalRequests = 0;
228
+ this.successfulRequests = 0;
229
+ this.failedRequests = 0;
230
+ this.metrics = {
231
+ uptime: Date.now() - this.startTime,
232
+ };
233
+ }
234
+ /**
235
+ * Health check for the protocol
236
+ * @returns Promise resolving to health status
237
+ */
238
+ async healthCheck() {
239
+ const healthy = this.connected !== false;
240
+ return {
241
+ healthy,
242
+ message: healthy ? 'Protocol is healthy' : 'Protocol is not connected',
243
+ details: {
244
+ name: this.name,
245
+ version: this.version,
246
+ connected: this.connected,
247
+ totalRequests: this.totalRequests,
248
+ successRate: this.metrics.successRate,
249
+ uptime: this.metrics.uptime,
250
+ },
251
+ };
252
+ }
253
+ /**
254
+ * Create request context
255
+ * @param request Request object
256
+ * @param attempt Attempt number
257
+ * @returns Request context
258
+ */
259
+ createRequestContext(request, attempt = 1) {
260
+ return {
261
+ protocol: this.name,
262
+ requestId: request.id || `req_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
263
+ attempt,
264
+ startTime: Date.now(),
265
+ isRetry: attempt > 1,
266
+ };
267
+ }
268
+ }
269
+ exports.BaseProtocol = BaseProtocol;
@@ -0,0 +1,255 @@
1
+ "use strict";
2
+ /**
3
+ * Abstract base retry strategy implementation
4
+ * @packageDocumentation
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.BaseRetryStrategy = void 0;
8
+ /**
9
+ * Abstract base retry strategy implementation
10
+ * Provides common functionality for all retry strategy implementations
11
+ */
12
+ class BaseRetryStrategy {
13
+ /**
14
+ * Create a new base retry strategy instance
15
+ * @param name Strategy name
16
+ * @param config Strategy configuration
17
+ */
18
+ constructor(name, config) {
19
+ /** Total retry attempts made */
20
+ this.totalAttempts = 0;
21
+ /** Successful retries */
22
+ this.successfulRetries = 0;
23
+ /** Failed retries */
24
+ this.failedRetries = 0;
25
+ /** Retry statistics */
26
+ this.stats = {
27
+ totalExecutions: 0,
28
+ totalAttempts: 0,
29
+ successfulRetries: 0,
30
+ failedRetries: 0,
31
+ successRate: 0,
32
+ averageAttempts: 0,
33
+ averageDelay: 0,
34
+ totalTimeSpent: 0,
35
+ };
36
+ this.name = name;
37
+ this.config = { ...config };
38
+ this.initialize();
39
+ }
40
+ /**
41
+ * Initialize retry strategy
42
+ */
43
+ initialize() {
44
+ // Can be overridden by subclasses
45
+ }
46
+ /**
47
+ * Determine if a retry should be attempted
48
+ * @param error Error that occurred
49
+ * @param context Current retry context
50
+ * @returns Retry decision
51
+ */
52
+ shouldRetry(error, context) {
53
+ // Check max attempts
54
+ if (context.attempt >= context.maxAttempts) {
55
+ return {
56
+ shouldRetry: false,
57
+ reason: 'Max attempts reached',
58
+ };
59
+ }
60
+ // Check retry on status codes (for HTTP errors)
61
+ if (error.statusCode && this.config.retryOnStatus?.includes(error.statusCode)) {
62
+ return {
63
+ shouldRetry: true,
64
+ delay: this.calculateDelay(context.attempt, context),
65
+ reason: `Status code ${error.statusCode} is retryable`,
66
+ };
67
+ }
68
+ // Check retry on error types
69
+ if (this.config.retryOnErrors?.includes(error.code)) {
70
+ return {
71
+ shouldRetry: true,
72
+ delay: this.calculateDelay(context.attempt, context),
73
+ reason: `Error code ${error.code} is retryable`,
74
+ };
75
+ }
76
+ // Check if error is retryable based on type
77
+ if (this.isRetryableError(error)) {
78
+ return {
79
+ shouldRetry: true,
80
+ delay: this.calculateDelay(context.attempt, context),
81
+ reason: 'Error is retryable',
82
+ };
83
+ }
84
+ return {
85
+ shouldRetry: false,
86
+ reason: 'Error is not retryable',
87
+ };
88
+ }
89
+ /**
90
+ * Check if an error is retryable
91
+ * @param error Error to check
92
+ * @returns True if error is retryable
93
+ */
94
+ isRetryableError(error) {
95
+ // Default implementation: retry on network errors, timeouts, and 5xx errors
96
+ const networkErrors = ['ECONNREFUSED', 'ECONNRESET', 'ETIMEDOUT', 'ENOTFOUND'];
97
+ const timeoutErrors = ['TIMEOUT', 'TIMEOUT_EXCEEDED'];
98
+ return (networkErrors.some(code => error.code?.includes(code)) ||
99
+ timeoutErrors.some(code => error.code?.includes(code)) ||
100
+ (error?.statusCode >= 500 && error?.statusCode < 600));
101
+ }
102
+ /**
103
+ * Calculate delay for next retry attempt
104
+ * @param attempt Current attempt number
105
+ * @param context Current retry context
106
+ * @returns Delay in milliseconds
107
+ */
108
+ calculateDelay(attempt, context) {
109
+ const backoff = this.config?.backoff || {};
110
+ const strategy = this.config.backoffStrategy || 'exponential';
111
+ switch (strategy) {
112
+ case 'fixed':
113
+ return backoff.initialDelay || 1000;
114
+ case 'exponential':
115
+ const baseDelay = backoff.initialDelay || 100;
116
+ const multiplier = backoff.multiplier || 2;
117
+ return Math.min(baseDelay * Math.pow(multiplier, attempt - 1), backoff.maxDelay || 30000);
118
+ case 'linear':
119
+ const linearDelay = backoff.initialDelay || 100;
120
+ const increment = backoff.multiplier || 1000;
121
+ return Math.min(linearDelay + (increment * (attempt - 1)), backoff.maxDelay || 30000);
122
+ case 'jitter':
123
+ const jitterDelay = backoff.initialDelay || 100;
124
+ const jitterMultiplier = backoff.multiplier || 2;
125
+ const base = jitterDelay * Math.pow(jitterMultiplier, attempt - 1);
126
+ const jitter = backoff.jitter || 0.3;
127
+ const jitterValue = base * jitter * Math.random();
128
+ return Math.min(base + jitterValue, backoff.maxDelay || 30000);
129
+ case 'fibonacci':
130
+ const fibDelay = backoff.initialDelay || 100;
131
+ let a = 0, b = 1;
132
+ for (let i = 0; i < attempt; i++) {
133
+ [a, b] = [b, a + b];
134
+ }
135
+ return Math.min(fibDelay * a, backoff.maxDelay || 30000);
136
+ default:
137
+ // Custom strategy or fallback
138
+ if (backoff.custom) {
139
+ return backoff.custom(attempt);
140
+ }
141
+ return backoff.initialDelay || 1000;
142
+ }
143
+ }
144
+ /**
145
+ * Create retry context
146
+ * @param initialContext Initial context values
147
+ * @returns Complete retry context
148
+ */
149
+ createRetryContext(initialContext) {
150
+ const defaultContext = {
151
+ attempt: 1,
152
+ maxAttempts: this.config.maxAttempts || 3,
153
+ lastError: undefined,
154
+ startTime: Date.now(),
155
+ elapsedTime: 0,
156
+ data: new Map(),
157
+ isRetry: false,
158
+ };
159
+ return {
160
+ ...defaultContext,
161
+ ...initialContext,
162
+ };
163
+ }
164
+ /**
165
+ * Update retry context after attempt
166
+ * @param context Current context
167
+ * @param error Error from attempt (if any)
168
+ * @returns Updated context
169
+ */
170
+ updateRetryContext(context, error) {
171
+ return {
172
+ ...context,
173
+ attempt: context.attempt + 1,
174
+ lastError: error,
175
+ elapsedTime: Date.now() - context.startTime,
176
+ isRetry: context.attempt > 1,
177
+ };
178
+ }
179
+ /**
180
+ * Update retry statistics
181
+ * @param success Whether retry was successful
182
+ * @param attempts Number of attempts
183
+ * @param totalDelay Total delay time
184
+ */
185
+ updateStats(success, attempts, totalDelay) {
186
+ this.totalAttempts += attempts;
187
+ this.stats.totalExecutions++;
188
+ this.stats.totalAttempts += attempts;
189
+ this.stats.totalTimeSpent += totalDelay;
190
+ if (success) {
191
+ this.successfulRetries++;
192
+ this.stats.successfulRetries++;
193
+ }
194
+ else {
195
+ this.failedRetries++;
196
+ this.stats.failedRetries++;
197
+ }
198
+ // Update calculated stats
199
+ const totalExecutions = this.stats.totalExecutions;
200
+ const totalAttempts = this.stats.totalAttempts;
201
+ this.stats.successRate = totalExecutions > 0 ?
202
+ this.stats.successfulRetries / totalExecutions : 0;
203
+ this.stats.averageAttempts = totalExecutions > 0 ?
204
+ totalAttempts / totalExecutions : 0;
205
+ this.stats.averageDelay = totalAttempts > 0 ?
206
+ this.stats.totalTimeSpent / totalAttempts : 0;
207
+ }
208
+ /**
209
+ * Update retry strategy configuration
210
+ * @param config New configuration
211
+ */
212
+ updateConfig(config) {
213
+ this.config = { ...this.config, ...config };
214
+ }
215
+ /**
216
+ * Get retry strategy statistics
217
+ */
218
+ getStats() {
219
+ return { ...this.stats };
220
+ }
221
+ /**
222
+ * Reset retry strategy statistics
223
+ */
224
+ resetStats() {
225
+ this.totalAttempts = 0;
226
+ this.successfulRetries = 0;
227
+ this.failedRetries = 0;
228
+ this.stats = {
229
+ totalExecutions: 0,
230
+ totalAttempts: 0,
231
+ successfulRetries: 0,
232
+ failedRetries: 0,
233
+ successRate: 0,
234
+ averageAttempts: 0,
235
+ averageDelay: 0,
236
+ totalTimeSpent: 0,
237
+ };
238
+ }
239
+ /**
240
+ * Health check for the retry strategy
241
+ */
242
+ healthCheck() {
243
+ const healthy = true; // Retry strategy is always healthy
244
+ return {
245
+ healthy,
246
+ message: 'Retry strategy is operational',
247
+ details: {
248
+ name: this.name,
249
+ config: this.config,
250
+ statistics: this.getStats(),
251
+ },
252
+ };
253
+ }
254
+ }
255
+ exports.BaseRetryStrategy = BaseRetryStrategy;