@felixgeelhaar/govee-api-client 1.1.0 → 2.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.
- package/README.md +160 -7
- package/dist/GoveeClient.d.ts +31 -0
- package/dist/GoveeClient.d.ts.map +1 -1
- package/dist/GoveeClient.js +33 -0
- package/dist/GoveeClient.js.map +1 -1
- package/dist/errors/ValidationError.d.ts +28 -0
- package/dist/errors/ValidationError.d.ts.map +1 -0
- package/dist/errors/ValidationError.js +44 -0
- package/dist/errors/ValidationError.js.map +1 -0
- package/dist/errors/index.d.ts +1 -0
- package/dist/errors/index.d.ts.map +1 -1
- package/dist/errors/index.js +1 -0
- package/dist/errors/index.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/GoveeDeviceRepository.js +1 -1
- package/dist/infrastructure/GoveeDeviceRepository.js.map +1 -1
- package/dist/infrastructure/SlidingWindowRateLimiter.d.ts +83 -0
- package/dist/infrastructure/SlidingWindowRateLimiter.d.ts.map +1 -0
- package/dist/infrastructure/SlidingWindowRateLimiter.js +218 -0
- package/dist/infrastructure/SlidingWindowRateLimiter.js.map +1 -0
- package/dist/infrastructure/index.d.ts +2 -0
- package/dist/infrastructure/index.d.ts.map +1 -1
- package/dist/infrastructure/index.js +2 -0
- package/dist/infrastructure/index.js.map +1 -1
- package/dist/infrastructure/response-schemas.d.ts +82 -0
- package/dist/infrastructure/response-schemas.d.ts.map +1 -0
- package/dist/infrastructure/response-schemas.js +59 -0
- package/dist/infrastructure/response-schemas.js.map +1 -0
- package/dist/infrastructure/retry/IntegrationGuide.d.ts +133 -0
- package/dist/infrastructure/retry/IntegrationGuide.d.ts.map +1 -0
- package/dist/infrastructure/retry/IntegrationGuide.js +295 -0
- package/dist/infrastructure/retry/IntegrationGuide.js.map +1 -0
- package/dist/infrastructure/retry/RetryConfigPresets.d.ts +114 -0
- package/dist/infrastructure/retry/RetryConfigPresets.d.ts.map +1 -0
- package/dist/infrastructure/retry/RetryConfigPresets.js +406 -0
- package/dist/infrastructure/retry/RetryConfigPresets.js.map +1 -0
- package/dist/infrastructure/retry/RetryPolicy.d.ts +148 -0
- package/dist/infrastructure/retry/RetryPolicy.d.ts.map +1 -0
- package/dist/infrastructure/retry/RetryPolicy.js +373 -0
- package/dist/infrastructure/retry/RetryPolicy.js.map +1 -0
- package/dist/infrastructure/retry/RetryableRepository.d.ts +75 -0
- package/dist/infrastructure/retry/RetryableRepository.d.ts.map +1 -0
- package/dist/infrastructure/retry/RetryableRepository.js +142 -0
- package/dist/infrastructure/retry/RetryableRepository.js.map +1 -0
- package/dist/infrastructure/retry/RetryableRequest.d.ts +132 -0
- package/dist/infrastructure/retry/RetryableRequest.d.ts.map +1 -0
- package/dist/infrastructure/retry/RetryableRequest.js +248 -0
- package/dist/infrastructure/retry/RetryableRequest.js.map +1 -0
- package/dist/infrastructure/retry/index.d.ts +35 -0
- package/dist/infrastructure/retry/index.d.ts.map +1 -0
- package/dist/infrastructure/retry/index.js +36 -0
- package/dist/infrastructure/retry/index.js.map +1 -0
- package/dist/services/GoveeControlService.d.ts +53 -0
- package/dist/services/GoveeControlService.d.ts.map +1 -1
- package/dist/services/GoveeControlService.js +138 -12
- package/dist/services/GoveeControlService.js.map +1 -1
- package/package.json +16 -13
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { Logger } from 'pino';
|
|
2
|
+
import { GoveeApiClientError } from '../../errors';
|
|
3
|
+
import { RetryPolicy } from './RetryPolicy';
|
|
4
|
+
/**
|
|
5
|
+
* Represents a request that can be retried
|
|
6
|
+
*/
|
|
7
|
+
export interface RetryableRequest<T> {
|
|
8
|
+
/** Unique identifier for this request */
|
|
9
|
+
id: string;
|
|
10
|
+
/** Function that executes the actual request */
|
|
11
|
+
execute: () => Promise<T>;
|
|
12
|
+
/** Human-readable description of the request */
|
|
13
|
+
description?: string;
|
|
14
|
+
/** Custom context data for the request */
|
|
15
|
+
context?: Record<string, unknown>;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Result of a retry operation
|
|
19
|
+
*/
|
|
20
|
+
export interface RetryResult<T> {
|
|
21
|
+
/** Whether the operation ultimately succeeded */
|
|
22
|
+
success: boolean;
|
|
23
|
+
/** The result if successful */
|
|
24
|
+
data?: T;
|
|
25
|
+
/** The final error if failed */
|
|
26
|
+
error?: GoveeApiClientError;
|
|
27
|
+
/** Number of attempts made */
|
|
28
|
+
totalAttempts: number;
|
|
29
|
+
/** Total time spent including retries */
|
|
30
|
+
totalTimeMs: number;
|
|
31
|
+
/** Details of each retry attempt */
|
|
32
|
+
attempts: RetryAttempt[];
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Details of a single retry attempt
|
|
36
|
+
*/
|
|
37
|
+
export interface RetryAttempt {
|
|
38
|
+
/** Attempt number (1-based) */
|
|
39
|
+
attemptNumber: number;
|
|
40
|
+
/** Timestamp when attempt started */
|
|
41
|
+
startTime: Date;
|
|
42
|
+
/** Duration of this attempt */
|
|
43
|
+
durationMs: number;
|
|
44
|
+
/** Whether this attempt succeeded */
|
|
45
|
+
success: boolean;
|
|
46
|
+
/** Error encountered (if any) */
|
|
47
|
+
error?: GoveeApiClientError;
|
|
48
|
+
/** Delay before this attempt (0 for first attempt) */
|
|
49
|
+
delayBeforeAttemptMs: number;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Configuration for retry executor
|
|
53
|
+
*/
|
|
54
|
+
export interface RetryExecutorConfig {
|
|
55
|
+
/** Retry policy to use */
|
|
56
|
+
retryPolicy: RetryPolicy;
|
|
57
|
+
/** Logger for retry operations */
|
|
58
|
+
logger?: Logger;
|
|
59
|
+
/** Enable detailed request logging */
|
|
60
|
+
enableRequestLogging?: boolean;
|
|
61
|
+
/** Enable performance tracking */
|
|
62
|
+
enablePerformanceTracking?: boolean;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Enterprise-grade retry executor with comprehensive logging and metrics
|
|
66
|
+
*/
|
|
67
|
+
export declare class RetryExecutor {
|
|
68
|
+
private readonly retryPolicy;
|
|
69
|
+
private readonly logger?;
|
|
70
|
+
private readonly enableRequestLogging;
|
|
71
|
+
private readonly enablePerformanceTracking;
|
|
72
|
+
constructor(retryPolicy: RetryPolicy, config?: Omit<RetryExecutorConfig, 'retryPolicy'>);
|
|
73
|
+
/**
|
|
74
|
+
* Executes a request with retry logic
|
|
75
|
+
*/
|
|
76
|
+
execute<T>(request: RetryableRequest<T>): Promise<T>;
|
|
77
|
+
/**
|
|
78
|
+
* Executes a request with detailed retry result information
|
|
79
|
+
*/
|
|
80
|
+
executeWithResult<T>(request: RetryableRequest<T>): Promise<RetryResult<T>>;
|
|
81
|
+
/**
|
|
82
|
+
* Executes a single attempt of the request
|
|
83
|
+
*/
|
|
84
|
+
private executeAttempt;
|
|
85
|
+
/**
|
|
86
|
+
* Normalizes any error to a GoveeApiClientError
|
|
87
|
+
*/
|
|
88
|
+
private normalizeError;
|
|
89
|
+
/**
|
|
90
|
+
* Utility function for sleeping
|
|
91
|
+
*/
|
|
92
|
+
private sleep;
|
|
93
|
+
/**
|
|
94
|
+
* Logging methods for different stages of retry execution
|
|
95
|
+
*/
|
|
96
|
+
private logRequestStart;
|
|
97
|
+
private logRequestSuccess;
|
|
98
|
+
private logRequestFailure;
|
|
99
|
+
private logRetryAttempt;
|
|
100
|
+
private logAttemptSuccess;
|
|
101
|
+
private logAttemptFailure;
|
|
102
|
+
/**
|
|
103
|
+
* Gets current retry policy metrics
|
|
104
|
+
*/
|
|
105
|
+
getMetrics(): Readonly<import("./RetryPolicy").RetryMetrics>;
|
|
106
|
+
/**
|
|
107
|
+
* Resets retry policy metrics
|
|
108
|
+
*/
|
|
109
|
+
resetMetrics(): void;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Factory for creating common retry executors
|
|
113
|
+
*/
|
|
114
|
+
export declare class RetryExecutorFactory {
|
|
115
|
+
/**
|
|
116
|
+
* Creates a retry executor optimized for Govee API operations
|
|
117
|
+
*/
|
|
118
|
+
static createForGoveeApi(logger?: Logger): RetryExecutor;
|
|
119
|
+
/**
|
|
120
|
+
* Creates a conservative retry executor for production environments
|
|
121
|
+
*/
|
|
122
|
+
static createConservative(logger?: Logger): RetryExecutor;
|
|
123
|
+
/**
|
|
124
|
+
* Creates an aggressive retry executor for development/testing
|
|
125
|
+
*/
|
|
126
|
+
static createAggressive(logger?: Logger): RetryExecutor;
|
|
127
|
+
/**
|
|
128
|
+
* Creates a custom retry executor with specific policy
|
|
129
|
+
*/
|
|
130
|
+
static createCustom(retryPolicy: RetryPolicy, logger?: Logger): RetryExecutor;
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=RetryableRequest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RetryableRequest.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/retry/RetryableRequest.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
import { GoveeApiClientError, NetworkError } from '../../errors';
|
|
2
|
+
import { RetryPolicy } from './RetryPolicy';
|
|
3
|
+
/**
|
|
4
|
+
* Enterprise-grade retry executor with comprehensive logging and metrics
|
|
5
|
+
*/
|
|
6
|
+
export class RetryExecutor {
|
|
7
|
+
constructor(retryPolicy, config = {}) {
|
|
8
|
+
this.retryPolicy = retryPolicy;
|
|
9
|
+
this.logger = config.logger;
|
|
10
|
+
this.enableRequestLogging = config.enableRequestLogging ?? true;
|
|
11
|
+
this.enablePerformanceTracking = config.enablePerformanceTracking ?? true;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Executes a request with retry logic
|
|
15
|
+
*/
|
|
16
|
+
async execute(request) {
|
|
17
|
+
const result = await this.executeWithResult(request);
|
|
18
|
+
if (result.success) {
|
|
19
|
+
return result.data;
|
|
20
|
+
}
|
|
21
|
+
throw result.error || new Error('Request failed without specific error');
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Executes a request with detailed retry result information
|
|
25
|
+
*/
|
|
26
|
+
async executeWithResult(request) {
|
|
27
|
+
const startTime = Date.now();
|
|
28
|
+
const attempts = [];
|
|
29
|
+
let attemptNumber = 0;
|
|
30
|
+
let lastError;
|
|
31
|
+
this.logRequestStart(request);
|
|
32
|
+
while (true) {
|
|
33
|
+
attemptNumber++;
|
|
34
|
+
const attemptStartTime = new Date();
|
|
35
|
+
const delayMs = attemptNumber === 1 ? 0 : this.retryPolicy.calculateDelay(attemptNumber - 1, lastError);
|
|
36
|
+
// Apply delay before retry attempts
|
|
37
|
+
if (delayMs > 0) {
|
|
38
|
+
this.logger?.debug({ requestId: request.id, attemptNumber, delayMs }, 'Waiting before retry attempt');
|
|
39
|
+
await this.sleep(delayMs);
|
|
40
|
+
}
|
|
41
|
+
const attemptResult = await this.executeAttempt(request, attemptNumber);
|
|
42
|
+
attempts.push({
|
|
43
|
+
attemptNumber,
|
|
44
|
+
startTime: attemptStartTime,
|
|
45
|
+
durationMs: attemptResult.durationMs,
|
|
46
|
+
success: attemptResult.success,
|
|
47
|
+
error: attemptResult.error,
|
|
48
|
+
delayBeforeAttemptMs: delayMs,
|
|
49
|
+
});
|
|
50
|
+
if (attemptResult.success) {
|
|
51
|
+
// Success - record and return
|
|
52
|
+
this.retryPolicy.recordSuccess();
|
|
53
|
+
const totalTimeMs = Date.now() - startTime;
|
|
54
|
+
this.logRequestSuccess(request, attemptNumber, totalTimeMs);
|
|
55
|
+
return {
|
|
56
|
+
success: true,
|
|
57
|
+
data: attemptResult.data,
|
|
58
|
+
totalAttempts: attemptNumber,
|
|
59
|
+
totalTimeMs,
|
|
60
|
+
attempts,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
// Failure - record each failed attempt
|
|
64
|
+
lastError = attemptResult.error;
|
|
65
|
+
this.retryPolicy.recordFailure(lastError);
|
|
66
|
+
const elapsedTimeMs = Date.now() - startTime;
|
|
67
|
+
if (!this.retryPolicy.shouldRetry(lastError, attemptNumber, elapsedTimeMs)) {
|
|
68
|
+
// No more retries - return failure
|
|
69
|
+
const totalTimeMs = Date.now() - startTime;
|
|
70
|
+
this.logRequestFailure(request, attemptNumber, totalTimeMs, lastError);
|
|
71
|
+
return {
|
|
72
|
+
success: false,
|
|
73
|
+
error: lastError,
|
|
74
|
+
totalAttempts: attemptNumber,
|
|
75
|
+
totalTimeMs,
|
|
76
|
+
attempts,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
// Continue retrying
|
|
80
|
+
this.logRetryAttempt(request, attemptNumber, lastError);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Executes a single attempt of the request
|
|
85
|
+
*/
|
|
86
|
+
async executeAttempt(request, attemptNumber) {
|
|
87
|
+
const startTime = Date.now();
|
|
88
|
+
try {
|
|
89
|
+
const data = await request.execute();
|
|
90
|
+
const durationMs = Date.now() - startTime;
|
|
91
|
+
this.logAttemptSuccess(request, attemptNumber, durationMs);
|
|
92
|
+
return {
|
|
93
|
+
success: true,
|
|
94
|
+
data,
|
|
95
|
+
durationMs,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
const durationMs = Date.now() - startTime;
|
|
100
|
+
const goveeError = this.normalizeError(error);
|
|
101
|
+
this.logAttemptFailure(request, attemptNumber, durationMs, goveeError);
|
|
102
|
+
return {
|
|
103
|
+
success: false,
|
|
104
|
+
error: goveeError,
|
|
105
|
+
durationMs,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Normalizes any error to a GoveeApiClientError
|
|
111
|
+
*/
|
|
112
|
+
normalizeError(error) {
|
|
113
|
+
if (error instanceof GoveeApiClientError) {
|
|
114
|
+
return error;
|
|
115
|
+
}
|
|
116
|
+
if (error instanceof Error) {
|
|
117
|
+
return new NetworkError(`Unexpected error: ${error.message}`, 'unknown', error);
|
|
118
|
+
}
|
|
119
|
+
return new NetworkError('Unknown error occurred', 'unknown');
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Utility function for sleeping
|
|
123
|
+
*/
|
|
124
|
+
sleep(ms) {
|
|
125
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Logging methods for different stages of retry execution
|
|
129
|
+
*/
|
|
130
|
+
logRequestStart(request) {
|
|
131
|
+
if (!this.enableRequestLogging || !this.logger)
|
|
132
|
+
return;
|
|
133
|
+
this.logger.info({
|
|
134
|
+
requestId: request.id,
|
|
135
|
+
description: request.description,
|
|
136
|
+
context: request.context,
|
|
137
|
+
}, 'Starting retryable request');
|
|
138
|
+
}
|
|
139
|
+
logRequestSuccess(request, totalAttempts, totalTimeMs) {
|
|
140
|
+
if (!this.enableRequestLogging || !this.logger)
|
|
141
|
+
return;
|
|
142
|
+
this.logger.info({
|
|
143
|
+
requestId: request.id,
|
|
144
|
+
totalAttempts,
|
|
145
|
+
totalTimeMs,
|
|
146
|
+
retriesNeeded: totalAttempts - 1,
|
|
147
|
+
}, 'Retryable request completed successfully');
|
|
148
|
+
}
|
|
149
|
+
logRequestFailure(request, totalAttempts, totalTimeMs, finalError) {
|
|
150
|
+
if (!this.logger)
|
|
151
|
+
return;
|
|
152
|
+
this.logger.error({
|
|
153
|
+
requestId: request.id,
|
|
154
|
+
totalAttempts,
|
|
155
|
+
totalTimeMs,
|
|
156
|
+
finalError: finalError.toObject(),
|
|
157
|
+
}, 'Retryable request failed after all attempts');
|
|
158
|
+
}
|
|
159
|
+
logRetryAttempt(request, attemptNumber, error) {
|
|
160
|
+
if (!this.enableRequestLogging || !this.logger)
|
|
161
|
+
return;
|
|
162
|
+
this.logger.warn({
|
|
163
|
+
requestId: request.id,
|
|
164
|
+
attemptNumber,
|
|
165
|
+
error: error.toObject(),
|
|
166
|
+
}, 'Request attempt failed, will retry');
|
|
167
|
+
}
|
|
168
|
+
logAttemptSuccess(request, attemptNumber, durationMs) {
|
|
169
|
+
if (!this.enableRequestLogging || !this.logger)
|
|
170
|
+
return;
|
|
171
|
+
this.logger.debug({
|
|
172
|
+
requestId: request.id,
|
|
173
|
+
attemptNumber,
|
|
174
|
+
durationMs,
|
|
175
|
+
}, 'Request attempt succeeded');
|
|
176
|
+
}
|
|
177
|
+
logAttemptFailure(request, attemptNumber, durationMs, error) {
|
|
178
|
+
if (!this.enableRequestLogging || !this.logger)
|
|
179
|
+
return;
|
|
180
|
+
this.logger.debug({
|
|
181
|
+
requestId: request.id,
|
|
182
|
+
attemptNumber,
|
|
183
|
+
durationMs,
|
|
184
|
+
error: error.toObject(),
|
|
185
|
+
}, 'Request attempt failed');
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Gets current retry policy metrics
|
|
189
|
+
*/
|
|
190
|
+
getMetrics() {
|
|
191
|
+
return this.retryPolicy.getMetrics();
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Resets retry policy metrics
|
|
195
|
+
*/
|
|
196
|
+
resetMetrics() {
|
|
197
|
+
this.retryPolicy.reset();
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Factory for creating common retry executors
|
|
202
|
+
*/
|
|
203
|
+
export class RetryExecutorFactory {
|
|
204
|
+
/**
|
|
205
|
+
* Creates a retry executor optimized for Govee API operations
|
|
206
|
+
*/
|
|
207
|
+
static createForGoveeApi(logger) {
|
|
208
|
+
const retryPolicy = RetryPolicy.createGoveeOptimized(logger);
|
|
209
|
+
return new RetryExecutor(retryPolicy, {
|
|
210
|
+
logger,
|
|
211
|
+
enableRequestLogging: true,
|
|
212
|
+
enablePerformanceTracking: true,
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Creates a conservative retry executor for production environments
|
|
217
|
+
*/
|
|
218
|
+
static createConservative(logger) {
|
|
219
|
+
const retryPolicy = RetryPolicy.createConservative(logger);
|
|
220
|
+
return new RetryExecutor(retryPolicy, {
|
|
221
|
+
logger,
|
|
222
|
+
enableRequestLogging: true,
|
|
223
|
+
enablePerformanceTracking: true,
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Creates an aggressive retry executor for development/testing
|
|
228
|
+
*/
|
|
229
|
+
static createAggressive(logger) {
|
|
230
|
+
const retryPolicy = RetryPolicy.createAggressive(logger);
|
|
231
|
+
return new RetryExecutor(retryPolicy, {
|
|
232
|
+
logger,
|
|
233
|
+
enableRequestLogging: true,
|
|
234
|
+
enablePerformanceTracking: true,
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Creates a custom retry executor with specific policy
|
|
239
|
+
*/
|
|
240
|
+
static createCustom(retryPolicy, logger) {
|
|
241
|
+
return new RetryExecutor(retryPolicy, {
|
|
242
|
+
logger,
|
|
243
|
+
enableRequestLogging: true,
|
|
244
|
+
enablePerformanceTracking: true,
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
//# sourceMappingURL=RetryableRequest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RetryableRequest.js","sourceRoot":"","sources":["../../../src/infrastructure/retry/RetryableRequest.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Retry infrastructure for Govee API client
|
|
3
|
+
*
|
|
4
|
+
* This module provides enterprise-grade retry logic with:
|
|
5
|
+
* - Exponential backoff with configurable strategies
|
|
6
|
+
* - Jitter algorithms to prevent thundering herd
|
|
7
|
+
* - Circuit breaker pattern for resilience
|
|
8
|
+
* - Comprehensive retry metrics and observability
|
|
9
|
+
* - Type-safe error handling integration
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* import { RetryPolicy, RetryExecutor, RetryableRepository } from './infrastructure/retry';
|
|
14
|
+
* import { GoveeDeviceRepository } from './infrastructure/GoveeDeviceRepository';
|
|
15
|
+
*
|
|
16
|
+
* // Create retry-enabled repository
|
|
17
|
+
* const baseRepository = new GoveeDeviceRepository(config);
|
|
18
|
+
* const retryableRepository = new RetryableRepository({
|
|
19
|
+
* repository: baseRepository,
|
|
20
|
+
* retryExecutor: RetryExecutor.createForGoveeApi(logger)
|
|
21
|
+
* });
|
|
22
|
+
*
|
|
23
|
+
* // Use with automatic retries
|
|
24
|
+
* const devices = await retryableRepository.findAll();
|
|
25
|
+
* const metrics = retryableRepository.getRetryMetrics();
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export { RetryPolicy } from './RetryPolicy';
|
|
29
|
+
export type { BackoffStrategy, JitterConfig, RetryCondition, CircuitBreakerConfig, RetryPolicyConfig, RetryMetrics, } from './RetryPolicy';
|
|
30
|
+
export { RetryExecutor, RetryExecutorFactory } from './RetryableRequest';
|
|
31
|
+
export type { RetryableRequest, RetryResult, RetryAttempt, RetryExecutorConfig, } from './RetryableRequest';
|
|
32
|
+
export { RetryableRepository } from './RetryableRepository';
|
|
33
|
+
export type { RetryableRepositoryConfig } from './RetryableRepository';
|
|
34
|
+
export { RetryConfigPresets, RetryConfigBuilder } from './RetryConfigPresets';
|
|
35
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/retry/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAGH,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,YAAY,EACV,eAAe,EACf,YAAY,EACZ,cAAc,EACd,oBAAoB,EACpB,iBAAiB,EACjB,YAAY,GACb,MAAM,eAAe,CAAC;AAGvB,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AACzE,YAAY,EACV,gBAAgB,EAChB,WAAW,EACX,YAAY,EACZ,mBAAmB,GACpB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,YAAY,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAGvE,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Retry infrastructure for Govee API client
|
|
3
|
+
*
|
|
4
|
+
* This module provides enterprise-grade retry logic with:
|
|
5
|
+
* - Exponential backoff with configurable strategies
|
|
6
|
+
* - Jitter algorithms to prevent thundering herd
|
|
7
|
+
* - Circuit breaker pattern for resilience
|
|
8
|
+
* - Comprehensive retry metrics and observability
|
|
9
|
+
* - Type-safe error handling integration
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* import { RetryPolicy, RetryExecutor, RetryableRepository } from './infrastructure/retry';
|
|
14
|
+
* import { GoveeDeviceRepository } from './infrastructure/GoveeDeviceRepository';
|
|
15
|
+
*
|
|
16
|
+
* // Create retry-enabled repository
|
|
17
|
+
* const baseRepository = new GoveeDeviceRepository(config);
|
|
18
|
+
* const retryableRepository = new RetryableRepository({
|
|
19
|
+
* repository: baseRepository,
|
|
20
|
+
* retryExecutor: RetryExecutor.createForGoveeApi(logger)
|
|
21
|
+
* });
|
|
22
|
+
*
|
|
23
|
+
* // Use with automatic retries
|
|
24
|
+
* const devices = await retryableRepository.findAll();
|
|
25
|
+
* const metrics = retryableRepository.getRetryMetrics();
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
// Core retry policy and execution
|
|
29
|
+
export { RetryPolicy } from './RetryPolicy';
|
|
30
|
+
// Retryable request execution
|
|
31
|
+
export { RetryExecutor, RetryExecutorFactory } from './RetryableRequest';
|
|
32
|
+
// Repository integration
|
|
33
|
+
export { RetryableRepository } from './RetryableRepository';
|
|
34
|
+
// Configuration presets and builders
|
|
35
|
+
export { RetryConfigPresets, RetryConfigBuilder } from './RetryConfigPresets';
|
|
36
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/infrastructure/retry/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,kCAAkC;AAClC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAU5C,8BAA8B;AAC9B,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAQzE,yBAAyB;AACzB,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAG5D,qCAAqC;AACrC,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -4,16 +4,26 @@ import { GoveeDevice } from '../domain/entities/GoveeDevice';
|
|
|
4
4
|
import { DeviceState } from '../domain/entities/DeviceState';
|
|
5
5
|
import { Command } from '../domain/entities/Command';
|
|
6
6
|
import { ColorRgb, ColorTemperature, Brightness } from '../domain/value-objects';
|
|
7
|
+
import { SlidingWindowRateLimiterConfig } from '../infrastructure';
|
|
8
|
+
import { RetryPolicy } from '../infrastructure/retry';
|
|
7
9
|
export interface GoveeControlServiceConfig {
|
|
8
10
|
repository: IGoveeDeviceRepository;
|
|
9
11
|
rateLimit?: number;
|
|
10
12
|
logger?: Logger;
|
|
13
|
+
rateLimiterConfig?: Partial<SlidingWindowRateLimiterConfig>;
|
|
14
|
+
enableRetries?: boolean;
|
|
15
|
+
retryPolicy?: 'development' | 'testing' | 'production' | 'custom' | RetryPolicy;
|
|
11
16
|
}
|
|
12
17
|
export declare class GoveeControlService {
|
|
13
18
|
private readonly repository;
|
|
14
19
|
private readonly logger;
|
|
15
20
|
private readonly rateLimiter;
|
|
21
|
+
private readonly enableRetries;
|
|
16
22
|
constructor(config: GoveeControlServiceConfig);
|
|
23
|
+
/**
|
|
24
|
+
* Creates a retry-enabled repository wrapper
|
|
25
|
+
*/
|
|
26
|
+
private createRetryableRepository;
|
|
17
27
|
private validateConfig;
|
|
18
28
|
/**
|
|
19
29
|
* Retrieves all devices associated with the configured API key
|
|
@@ -83,6 +93,49 @@ export declare class GoveeControlService {
|
|
|
83
93
|
* Convenience method to find devices by model
|
|
84
94
|
*/
|
|
85
95
|
findDevicesByModel(model: string): Promise<GoveeDevice[]>;
|
|
96
|
+
/**
|
|
97
|
+
* Gets current rate limiter statistics for monitoring and debugging
|
|
98
|
+
*/
|
|
99
|
+
getRateLimiterStats(): {
|
|
100
|
+
currentRequests: number;
|
|
101
|
+
maxRequests: number;
|
|
102
|
+
queueSize: number;
|
|
103
|
+
windowMs: number;
|
|
104
|
+
utilizationPercent: number;
|
|
105
|
+
canExecuteImmediately: boolean;
|
|
106
|
+
nextAvailableSlot: number;
|
|
107
|
+
};
|
|
108
|
+
/**
|
|
109
|
+
* Gets retry metrics if retry functionality is enabled
|
|
110
|
+
*/
|
|
111
|
+
getRetryMetrics(): Readonly<import("../infrastructure").RetryMetrics> | null;
|
|
112
|
+
/**
|
|
113
|
+
* Resets retry metrics if retry functionality is enabled
|
|
114
|
+
*/
|
|
115
|
+
resetRetryMetrics(): void;
|
|
116
|
+
/**
|
|
117
|
+
* Gets comprehensive service statistics including rate limiter and retry metrics
|
|
118
|
+
*/
|
|
119
|
+
getServiceStats(): {
|
|
120
|
+
rateLimiter: {
|
|
121
|
+
currentRequests: number;
|
|
122
|
+
maxRequests: number;
|
|
123
|
+
queueSize: number;
|
|
124
|
+
windowMs: number;
|
|
125
|
+
utilizationPercent: number;
|
|
126
|
+
canExecuteImmediately: boolean;
|
|
127
|
+
nextAvailableSlot: number;
|
|
128
|
+
};
|
|
129
|
+
retries: Readonly<import("../infrastructure").RetryMetrics> | null;
|
|
130
|
+
configuration: {
|
|
131
|
+
enableRetries: boolean;
|
|
132
|
+
rateLimit: number;
|
|
133
|
+
};
|
|
134
|
+
};
|
|
135
|
+
/**
|
|
136
|
+
* Checks if retry functionality is enabled
|
|
137
|
+
*/
|
|
138
|
+
isRetryEnabled(): boolean;
|
|
86
139
|
private validateDeviceParams;
|
|
87
140
|
}
|
|
88
141
|
//# sourceMappingURL=GoveeControlService.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GoveeControlService.d.ts","sourceRoot":"","sources":["../../src/services/GoveeControlService.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"GoveeControlService.d.ts","sourceRoot":"","sources":["../../src/services/GoveeControlService.ts"],"names":[],"mappings":"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"}
|