@stackguide/mcp-server 3.8.1 → 3.10.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 (58) hide show
  1. package/dist/handlers/prompts.d.ts.map +1 -1
  2. package/dist/handlers/prompts.js +13 -2
  3. package/dist/handlers/prompts.js.map +1 -1
  4. package/dist/handlers/review.d.ts +2 -1
  5. package/dist/handlers/review.d.ts.map +1 -1
  6. package/dist/handlers/review.js +106 -17
  7. package/dist/handlers/review.js.map +1 -1
  8. package/dist/services/codeAnalyzer.d.ts +24 -1
  9. package/dist/services/codeAnalyzer.d.ts.map +1 -1
  10. package/dist/services/codeAnalyzer.js +57 -2
  11. package/dist/services/codeAnalyzer.js.map +1 -1
  12. package/dist/services/cursorDirectory.d.ts.map +1 -1
  13. package/dist/services/cursorDirectory.js +45 -10
  14. package/dist/services/cursorDirectory.js.map +1 -1
  15. package/dist/services/httpClient.d.ts +33 -2
  16. package/dist/services/httpClient.d.ts.map +1 -1
  17. package/dist/services/httpClient.js +117 -17
  18. package/dist/services/httpClient.js.map +1 -1
  19. package/dist/services/projectFs.d.ts.map +1 -1
  20. package/dist/services/projectFs.js +25 -4
  21. package/dist/services/projectFs.js.map +1 -1
  22. package/dist/services/rulesEngine.d.ts +2 -2
  23. package/dist/services/rulesEngine.d.ts.map +1 -1
  24. package/dist/services/rulesEngine.js +42 -2
  25. package/dist/services/rulesEngine.js.map +1 -1
  26. package/dist/services/webDocumentation.d.ts +2 -0
  27. package/dist/services/webDocumentation.d.ts.map +1 -1
  28. package/dist/services/webDocumentation.js +88 -27
  29. package/dist/services/webDocumentation.js.map +1 -1
  30. package/dist/storage/sqlite.d.ts +1 -1
  31. package/dist/storage/sqlite.d.ts.map +1 -1
  32. package/dist/storage/sqlite.js +200 -24
  33. package/dist/storage/sqlite.js.map +1 -1
  34. package/dist/storage/types.d.ts +32 -2
  35. package/dist/storage/types.d.ts.map +1 -1
  36. package/dist/storage/types.js +4 -2
  37. package/dist/storage/types.js.map +1 -1
  38. package/dist/utils/circuitBreaker.d.ts +144 -0
  39. package/dist/utils/circuitBreaker.d.ts.map +1 -0
  40. package/dist/utils/circuitBreaker.js +329 -0
  41. package/dist/utils/circuitBreaker.js.map +1 -0
  42. package/dist/utils/resilienceMetrics.d.ts +104 -0
  43. package/dist/utils/resilienceMetrics.d.ts.map +1 -0
  44. package/dist/utils/resilienceMetrics.js +260 -0
  45. package/dist/utils/resilienceMetrics.js.map +1 -0
  46. package/dist/utils/safeFetch.d.ts +12 -0
  47. package/dist/utils/safeFetch.d.ts.map +1 -0
  48. package/dist/utils/safeFetch.js +107 -0
  49. package/dist/utils/safeFetch.js.map +1 -0
  50. package/dist/validation/index.d.ts +1 -1
  51. package/dist/validation/index.d.ts.map +1 -1
  52. package/dist/validation/index.js +1 -1
  53. package/dist/validation/index.js.map +1 -1
  54. package/dist/validation/schemas.d.ts +8 -1
  55. package/dist/validation/schemas.d.ts.map +1 -1
  56. package/dist/validation/schemas.js +47 -5
  57. package/dist/validation/schemas.js.map +1 -1
  58. package/package.json +1 -1
@@ -0,0 +1,144 @@
1
+ /**
2
+ * Circuit Breaker Pattern Implementation
3
+ * Protects against cascading failures in external service calls
4
+ * @version 3.8.2
5
+ */
6
+ export type CircuitState = 'CLOSED' | 'OPEN' | 'HALF_OPEN';
7
+ export interface CircuitBreakerOptions {
8
+ /** Name for logging/metrics */
9
+ name: string;
10
+ /** Number of failures before opening circuit */
11
+ failureThreshold?: number;
12
+ /** Time in ms before attempting recovery (half-open) */
13
+ resetTimeoutMs?: number;
14
+ /** Number of successful calls in half-open to close circuit */
15
+ successThreshold?: number;
16
+ /** Time window in ms for counting failures */
17
+ failureWindowMs?: number;
18
+ /** Timeout for individual calls */
19
+ callTimeoutMs?: number;
20
+ /** Custom function to determine if error should count as failure */
21
+ isFailure?: (error: Error) => boolean;
22
+ /** Callback when circuit opens */
23
+ onOpen?: (name: string, failures: number) => void;
24
+ /** Callback when circuit closes */
25
+ onClose?: (name: string) => void;
26
+ /** Callback when circuit half-opens */
27
+ onHalfOpen?: (name: string) => void;
28
+ }
29
+ export interface CircuitBreakerMetrics {
30
+ name: string;
31
+ state: CircuitState;
32
+ failures: number;
33
+ successes: number;
34
+ totalCalls: number;
35
+ rejectedCalls: number;
36
+ lastFailure: string | null;
37
+ lastSuccess: string | null;
38
+ lastStateChange: string;
39
+ consecutiveSuccesses: number;
40
+ failureRate: number;
41
+ }
42
+ export declare class CircuitBreaker {
43
+ private state;
44
+ private failures;
45
+ private successes;
46
+ private totalCalls;
47
+ private rejectedCalls;
48
+ private consecutiveSuccesses;
49
+ private lastFailure;
50
+ private lastSuccess;
51
+ private lastStateChange;
52
+ private openedAt;
53
+ private readonly name;
54
+ private readonly failureThreshold;
55
+ private readonly resetTimeoutMs;
56
+ private readonly successThreshold;
57
+ private readonly failureWindowMs;
58
+ private readonly callTimeoutMs;
59
+ private readonly isFailure;
60
+ private readonly onOpen?;
61
+ private readonly onClose?;
62
+ private readonly onHalfOpen?;
63
+ constructor(options: CircuitBreakerOptions);
64
+ /**
65
+ * Execute a function through the circuit breaker
66
+ */
67
+ execute<T>(fn: () => Promise<T>): Promise<T>;
68
+ /**
69
+ * Get current circuit state
70
+ */
71
+ getState(): CircuitState;
72
+ /**
73
+ * Get circuit breaker metrics
74
+ */
75
+ getMetrics(): CircuitBreakerMetrics;
76
+ /**
77
+ * Manually reset the circuit breaker
78
+ */
79
+ reset(): void;
80
+ /**
81
+ * Force the circuit open (for testing or emergency)
82
+ */
83
+ forceOpen(): void;
84
+ private onSuccess;
85
+ private onError;
86
+ private transitionTo;
87
+ private shouldAttemptReset;
88
+ private getRemainingResetTime;
89
+ private getRecentFailures;
90
+ private pruneOldFailures;
91
+ }
92
+ export declare class CircuitOpenError extends Error {
93
+ readonly circuitName: string;
94
+ readonly remainingMs: number;
95
+ constructor(circuitName: string, remainingMs: number);
96
+ }
97
+ declare class CircuitBreakerRegistry {
98
+ private circuits;
99
+ /**
100
+ * Get or create a circuit breaker by name
101
+ */
102
+ getOrCreate(options: CircuitBreakerOptions): CircuitBreaker;
103
+ /**
104
+ * Get circuit breaker by name
105
+ */
106
+ get(name: string): CircuitBreaker | undefined;
107
+ /**
108
+ * Get all circuit breakers
109
+ */
110
+ getAll(): CircuitBreaker[];
111
+ /**
112
+ * Get metrics for all circuits
113
+ */
114
+ getAllMetrics(): CircuitBreakerMetrics[];
115
+ /**
116
+ * Get health summary
117
+ */
118
+ getHealthSummary(): {
119
+ total: number;
120
+ closed: number;
121
+ open: number;
122
+ halfOpen: number;
123
+ healthy: boolean;
124
+ };
125
+ /**
126
+ * Reset all circuit breakers
127
+ */
128
+ resetAll(): void;
129
+ /**
130
+ * Clear all circuit breakers
131
+ */
132
+ clear(): void;
133
+ }
134
+ export declare const circuitBreakerRegistry: CircuitBreakerRegistry;
135
+ /**
136
+ * Create a circuit breaker with default options for external services
137
+ */
138
+ export declare function createServiceCircuitBreaker(serviceName: string, options?: Partial<CircuitBreakerOptions>): CircuitBreaker;
139
+ /**
140
+ * Wrap an async function with circuit breaker protection
141
+ */
142
+ export declare function withCircuitBreaker<T extends (...args: unknown[]) => Promise<unknown>>(fn: T, circuitName: string, options?: Partial<CircuitBreakerOptions>): T;
143
+ export {};
144
+ //# sourceMappingURL=circuitBreaker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"circuitBreaker.d.ts","sourceRoot":"","sources":["../../src/utils/circuitBreaker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,329 @@
1
+ /**
2
+ * Circuit Breaker Pattern Implementation
3
+ * Protects against cascading failures in external service calls
4
+ * @version 3.8.2
5
+ */
6
+ import { logger } from './logger.js';
7
+ // ============================================================================
8
+ // Circuit Breaker Implementation
9
+ // ============================================================================
10
+ export class CircuitBreaker {
11
+ state = 'CLOSED';
12
+ failures = [];
13
+ successes = 0;
14
+ totalCalls = 0;
15
+ rejectedCalls = 0;
16
+ consecutiveSuccesses = 0;
17
+ lastFailure = null;
18
+ lastSuccess = null;
19
+ lastStateChange = new Date();
20
+ openedAt = null;
21
+ name;
22
+ failureThreshold;
23
+ resetTimeoutMs;
24
+ successThreshold;
25
+ failureWindowMs;
26
+ callTimeoutMs;
27
+ isFailure;
28
+ onOpen;
29
+ onClose;
30
+ onHalfOpen;
31
+ constructor(options) {
32
+ this.name = options.name;
33
+ this.failureThreshold = options.failureThreshold ?? 5;
34
+ this.resetTimeoutMs = options.resetTimeoutMs ?? 30000; // 30 seconds
35
+ this.successThreshold = options.successThreshold ?? 2;
36
+ this.failureWindowMs = options.failureWindowMs ?? 60000; // 1 minute
37
+ this.callTimeoutMs = options.callTimeoutMs ?? 10000; // 10 seconds
38
+ this.isFailure = options.isFailure ?? (() => true);
39
+ this.onOpen = options.onOpen;
40
+ this.onClose = options.onClose;
41
+ this.onHalfOpen = options.onHalfOpen;
42
+ logger.debug('Circuit breaker initialized', { name: this.name, state: this.state });
43
+ }
44
+ /**
45
+ * Execute a function through the circuit breaker
46
+ */
47
+ async execute(fn) {
48
+ this.totalCalls++;
49
+ // Check if circuit is open
50
+ if (this.state === 'OPEN') {
51
+ if (this.shouldAttemptReset()) {
52
+ this.transitionTo('HALF_OPEN');
53
+ }
54
+ else {
55
+ this.rejectedCalls++;
56
+ throw new CircuitOpenError(this.name, this.getRemainingResetTime());
57
+ }
58
+ }
59
+ // Apply timeout wrapper
60
+ const timeoutPromise = new Promise((_, reject) => {
61
+ setTimeout(() => {
62
+ reject(new Error(`Circuit breaker timeout (${this.callTimeoutMs}ms)`));
63
+ }, this.callTimeoutMs);
64
+ });
65
+ try {
66
+ const result = await Promise.race([fn(), timeoutPromise]);
67
+ this.onSuccess();
68
+ return result;
69
+ }
70
+ catch (error) {
71
+ this.onError(error);
72
+ throw error;
73
+ }
74
+ }
75
+ /**
76
+ * Get current circuit state
77
+ */
78
+ getState() {
79
+ // Check for automatic half-open transition
80
+ if (this.state === 'OPEN' && this.shouldAttemptReset()) {
81
+ this.transitionTo('HALF_OPEN');
82
+ }
83
+ return this.state;
84
+ }
85
+ /**
86
+ * Get circuit breaker metrics
87
+ */
88
+ getMetrics() {
89
+ const recentFailures = this.getRecentFailures();
90
+ return {
91
+ name: this.name,
92
+ state: this.getState(),
93
+ failures: recentFailures.length,
94
+ successes: this.successes,
95
+ totalCalls: this.totalCalls,
96
+ rejectedCalls: this.rejectedCalls,
97
+ lastFailure: this.lastFailure?.toISOString() ?? null,
98
+ lastSuccess: this.lastSuccess?.toISOString() ?? null,
99
+ lastStateChange: this.lastStateChange.toISOString(),
100
+ consecutiveSuccesses: this.consecutiveSuccesses,
101
+ failureRate: this.totalCalls > 0
102
+ ? Math.round((recentFailures.length / Math.min(this.totalCalls, 100)) * 100)
103
+ : 0
104
+ };
105
+ }
106
+ /**
107
+ * Manually reset the circuit breaker
108
+ */
109
+ reset() {
110
+ this.failures = [];
111
+ this.consecutiveSuccesses = 0;
112
+ this.transitionTo('CLOSED');
113
+ logger.info('Circuit breaker manually reset', { name: this.name });
114
+ }
115
+ /**
116
+ * Force the circuit open (for testing or emergency)
117
+ */
118
+ forceOpen() {
119
+ this.transitionTo('OPEN');
120
+ this.openedAt = Date.now();
121
+ logger.warn('Circuit breaker forced open', { name: this.name });
122
+ }
123
+ // ============================================================================
124
+ // Private Methods
125
+ // ============================================================================
126
+ onSuccess() {
127
+ this.successes++;
128
+ this.consecutiveSuccesses++;
129
+ this.lastSuccess = new Date();
130
+ if (this.state === 'HALF_OPEN') {
131
+ if (this.consecutiveSuccesses >= this.successThreshold) {
132
+ this.transitionTo('CLOSED');
133
+ }
134
+ }
135
+ // Clear old failures on success
136
+ this.pruneOldFailures();
137
+ }
138
+ onError(error) {
139
+ this.lastFailure = new Date();
140
+ this.consecutiveSuccesses = 0;
141
+ // Check if this error counts as a failure
142
+ if (!this.isFailure(error)) {
143
+ return;
144
+ }
145
+ this.failures.push({
146
+ timestamp: Date.now(),
147
+ error: error.message
148
+ });
149
+ this.pruneOldFailures();
150
+ if (this.state === 'HALF_OPEN') {
151
+ // Any failure in half-open state opens the circuit
152
+ this.transitionTo('OPEN');
153
+ }
154
+ else if (this.state === 'CLOSED') {
155
+ // Check if we've exceeded failure threshold
156
+ if (this.getRecentFailures().length >= this.failureThreshold) {
157
+ this.transitionTo('OPEN');
158
+ }
159
+ }
160
+ }
161
+ transitionTo(newState) {
162
+ if (this.state === newState)
163
+ return;
164
+ const oldState = this.state;
165
+ this.state = newState;
166
+ this.lastStateChange = new Date();
167
+ logger.info('Circuit breaker state transition', {
168
+ name: this.name,
169
+ from: oldState,
170
+ to: newState
171
+ });
172
+ switch (newState) {
173
+ case 'OPEN':
174
+ this.openedAt = Date.now();
175
+ this.consecutiveSuccesses = 0;
176
+ this.onOpen?.(this.name, this.getRecentFailures().length);
177
+ break;
178
+ case 'HALF_OPEN':
179
+ this.consecutiveSuccesses = 0;
180
+ this.onHalfOpen?.(this.name);
181
+ break;
182
+ case 'CLOSED':
183
+ this.failures = [];
184
+ this.openedAt = null;
185
+ this.onClose?.(this.name);
186
+ break;
187
+ }
188
+ }
189
+ shouldAttemptReset() {
190
+ if (this.openedAt === null)
191
+ return false;
192
+ return Date.now() - this.openedAt >= this.resetTimeoutMs;
193
+ }
194
+ getRemainingResetTime() {
195
+ if (this.openedAt === null)
196
+ return 0;
197
+ const elapsed = Date.now() - this.openedAt;
198
+ return Math.max(0, this.resetTimeoutMs - elapsed);
199
+ }
200
+ getRecentFailures() {
201
+ const cutoff = Date.now() - this.failureWindowMs;
202
+ return this.failures.filter(f => f.timestamp >= cutoff);
203
+ }
204
+ pruneOldFailures() {
205
+ const cutoff = Date.now() - this.failureWindowMs;
206
+ this.failures = this.failures.filter(f => f.timestamp >= cutoff);
207
+ }
208
+ }
209
+ // ============================================================================
210
+ // Circuit Breaker Error
211
+ // ============================================================================
212
+ export class CircuitOpenError extends Error {
213
+ circuitName;
214
+ remainingMs;
215
+ constructor(circuitName, remainingMs) {
216
+ super(`Circuit breaker '${circuitName}' is OPEN. Retry after ${Math.ceil(remainingMs / 1000)}s`);
217
+ this.name = 'CircuitOpenError';
218
+ this.circuitName = circuitName;
219
+ this.remainingMs = remainingMs;
220
+ }
221
+ }
222
+ // ============================================================================
223
+ // Circuit Breaker Registry
224
+ // ============================================================================
225
+ class CircuitBreakerRegistry {
226
+ circuits = new Map();
227
+ /**
228
+ * Get or create a circuit breaker by name
229
+ */
230
+ getOrCreate(options) {
231
+ const existing = this.circuits.get(options.name);
232
+ if (existing) {
233
+ return existing;
234
+ }
235
+ const circuit = new CircuitBreaker(options);
236
+ this.circuits.set(options.name, circuit);
237
+ return circuit;
238
+ }
239
+ /**
240
+ * Get circuit breaker by name
241
+ */
242
+ get(name) {
243
+ return this.circuits.get(name);
244
+ }
245
+ /**
246
+ * Get all circuit breakers
247
+ */
248
+ getAll() {
249
+ return Array.from(this.circuits.values());
250
+ }
251
+ /**
252
+ * Get metrics for all circuits
253
+ */
254
+ getAllMetrics() {
255
+ return this.getAll().map(c => c.getMetrics());
256
+ }
257
+ /**
258
+ * Get health summary
259
+ */
260
+ getHealthSummary() {
261
+ const metrics = this.getAllMetrics();
262
+ const closed = metrics.filter(m => m.state === 'CLOSED').length;
263
+ const open = metrics.filter(m => m.state === 'OPEN').length;
264
+ const halfOpen = metrics.filter(m => m.state === 'HALF_OPEN').length;
265
+ return {
266
+ total: metrics.length,
267
+ closed,
268
+ open,
269
+ halfOpen,
270
+ healthy: open === 0
271
+ };
272
+ }
273
+ /**
274
+ * Reset all circuit breakers
275
+ */
276
+ resetAll() {
277
+ this.circuits.forEach(circuit => circuit.reset());
278
+ logger.info('All circuit breakers reset', { count: this.circuits.size });
279
+ }
280
+ /**
281
+ * Clear all circuit breakers
282
+ */
283
+ clear() {
284
+ this.circuits.clear();
285
+ }
286
+ }
287
+ // ============================================================================
288
+ // Singleton Registry Export
289
+ // ============================================================================
290
+ export const circuitBreakerRegistry = new CircuitBreakerRegistry();
291
+ /**
292
+ * Create a circuit breaker with default options for external services
293
+ */
294
+ export function createServiceCircuitBreaker(serviceName, options = {}) {
295
+ return circuitBreakerRegistry.getOrCreate({
296
+ name: serviceName,
297
+ failureThreshold: 5,
298
+ resetTimeoutMs: 30000,
299
+ successThreshold: 2,
300
+ failureWindowMs: 60000,
301
+ callTimeoutMs: 10000,
302
+ ...options,
303
+ onOpen: (name, failures) => {
304
+ logger.error('Circuit breaker opened', { service: name, failures });
305
+ options.onOpen?.(name, failures);
306
+ },
307
+ onClose: (name) => {
308
+ logger.info('Circuit breaker closed', { service: name });
309
+ options.onClose?.(name);
310
+ },
311
+ onHalfOpen: (name) => {
312
+ logger.info('Circuit breaker half-open', { service: name });
313
+ options.onHalfOpen?.(name);
314
+ }
315
+ });
316
+ }
317
+ // ============================================================================
318
+ // Decorator/Wrapper Helper
319
+ // ============================================================================
320
+ /**
321
+ * Wrap an async function with circuit breaker protection
322
+ */
323
+ export function withCircuitBreaker(fn, circuitName, options = {}) {
324
+ const circuit = createServiceCircuitBreaker(circuitName, options);
325
+ return (async (...args) => {
326
+ return circuit.execute(() => fn(...args));
327
+ });
328
+ }
329
+ //# sourceMappingURL=circuitBreaker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"circuitBreaker.js","sourceRoot":"","sources":["../../src/utils/circuitBreaker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,104 @@
1
+ /**
2
+ * Resilience Metrics - Centralized metrics collection for service health
3
+ * @version 3.8.2
4
+ */
5
+ import { type CircuitBreakerMetrics } from './circuitBreaker.js';
6
+ export interface ServiceMetrics {
7
+ name: string;
8
+ totalRequests: number;
9
+ successfulRequests: number;
10
+ failedRequests: number;
11
+ timeouts: number;
12
+ averageLatencyMs: number;
13
+ p95LatencyMs: number;
14
+ p99LatencyMs: number;
15
+ lastRequestAt: string | null;
16
+ lastErrorAt: string | null;
17
+ lastError: string | null;
18
+ successRate: number;
19
+ requestsPerMinute: number;
20
+ }
21
+ export interface OverallHealthMetrics {
22
+ timestamp: string;
23
+ uptime: number;
24
+ services: ServiceMetrics[];
25
+ circuits: CircuitBreakerMetrics[];
26
+ summary: {
27
+ totalServices: number;
28
+ healthyServices: number;
29
+ degradedServices: number;
30
+ unhealthyServices: number;
31
+ overallHealthScore: number;
32
+ status: 'healthy' | 'degraded' | 'unhealthy';
33
+ };
34
+ }
35
+ declare class ServiceMetricsCollector {
36
+ private requests;
37
+ private readonly name;
38
+ private readonly maxRecords;
39
+ private readonly windowMs;
40
+ constructor(name: string, maxRecords?: number, windowMs?: number);
41
+ recordSuccess(latencyMs: number): void;
42
+ recordFailure(latencyMs: number, error: string): void;
43
+ recordTimeout(latencyMs: number): void;
44
+ private addRecord;
45
+ private pruneOldRecords;
46
+ getMetrics(): ServiceMetrics;
47
+ private percentile;
48
+ reset(): void;
49
+ }
50
+ declare class ResilienceMetricsRegistry {
51
+ private collectors;
52
+ private startTime;
53
+ /**
54
+ * Get or create a metrics collector for a service
55
+ */
56
+ getOrCreate(serviceName: string): ServiceMetricsCollector;
57
+ /**
58
+ * Record a successful request
59
+ */
60
+ recordSuccess(serviceName: string, latencyMs: number): void;
61
+ /**
62
+ * Record a failed request
63
+ */
64
+ recordFailure(serviceName: string, latencyMs: number, error: string): void;
65
+ /**
66
+ * Record a timeout
67
+ */
68
+ recordTimeout(serviceName: string, latencyMs: number): void;
69
+ /**
70
+ * Get metrics for all services
71
+ */
72
+ getAllServiceMetrics(): ServiceMetrics[];
73
+ /**
74
+ * Get overall health metrics
75
+ */
76
+ getOverallHealth(): OverallHealthMetrics;
77
+ /**
78
+ * Get a quick health check
79
+ */
80
+ quickHealthCheck(): {
81
+ healthy: boolean;
82
+ score: number;
83
+ issues: string[];
84
+ };
85
+ /**
86
+ * Reset all metrics
87
+ */
88
+ reset(): void;
89
+ /**
90
+ * Clear all collectors
91
+ */
92
+ clear(): void;
93
+ }
94
+ export declare const resilienceMetrics: ResilienceMetricsRegistry;
95
+ /**
96
+ * Time an async operation and record metrics
97
+ */
98
+ export declare function withMetrics<T>(serviceName: string, fn: () => Promise<T>): Promise<T>;
99
+ /**
100
+ * Combine circuit breaker and metrics for a service call
101
+ */
102
+ export declare function withResilience<T>(serviceName: string, fn: () => Promise<T>, circuitOptions?: Parameters<typeof import('./circuitBreaker.js').createServiceCircuitBreaker>[1]): Promise<T>;
103
+ export {};
104
+ //# sourceMappingURL=resilienceMetrics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resilienceMetrics.d.ts","sourceRoot":"","sources":["../../src/utils/resilienceMetrics.ts"],"names":[],"mappings":"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"}