diff --git a/packages/smooth-api-ts/src/index.ts b/packages/smooth-api-ts/src/index.ts index 3f3b743..53102eb 100644 --- a/packages/smooth-api-ts/src/index.ts +++ b/packages/smooth-api-ts/src/index.ts @@ -57,9 +57,17 @@ export function createSmoothFetch(globalConfig: SmoothFetchConfig) { const retryOn = globalConfig.retryOn ?? DEFAULT_RETRY_ON; const breaker = new CircuitBreakerState( globalConfig.circuitBreaker, - globalConfig.onCircuitStateChange - ? (event) => safeInvoke(globalConfig.onCircuitStateChange, event) - : undefined + (event) => { + if (globalConfig.onCircuitStateChange) { + safeInvoke(globalConfig.onCircuitStateChange, event); + } + if (event.to === 'OPEN' && globalConfig.onCircuitOpen) { + safeInvoke(globalConfig.onCircuitOpen, { + domain: event.domain, + failureCount: event.failureCount, + }); + } + } ); const deduplicator = globalConfig.deduplication ? new RequestDeduplicator(globalConfig.deduplication.keyFn) diff --git a/packages/smooth-api-ts/src/types.ts b/packages/smooth-api-ts/src/types.ts index c6e4494..321d156 100644 --- a/packages/smooth-api-ts/src/types.ts +++ b/packages/smooth-api-ts/src/types.ts @@ -55,6 +55,11 @@ export interface CircuitStateChangeEvent { failureCount: number; } +export interface CircuitOpenEvent { + domain: string; + failureCount: number; +} + /** * Custom predicate function to determine if an attempt should be retried. * Receives either (response, undefined) on HTTP completion or (undefined, error) on network/catch errors. @@ -88,8 +93,16 @@ export interface FailureContext { export type RequestSuccessContext = SuccessContext; export type RequestFailureContext = FailureContext; +export interface MetricsHooks { + onRetry?: (context: RetryContext) => void | Promise; + onFailure?: (context: FailureContext) => void | Promise; + onSuccess?: (context: SuccessContext) => void | Promise; + onCircuitOpen?: (event: CircuitOpenEvent) => void | Promise; + onCircuitStateChange?: (event: CircuitStateChangeEvent) => void | Promise; +} + // T types the fallback payload so callers get inference at the use site. -export interface SmoothFetchConfig { +export interface SmoothFetchConfig extends MetricsHooks { backoff?: Partial; circuitBreaker?: Partial; fallback?: T; // returned immediately on an OPEN circuit, no network IO @@ -113,10 +126,6 @@ export interface SmoothFetchConfig { * Must be a positive finite number. */ timeoutMs?: number; - onRetry?: (context: RetryContext) => void | Promise; - onCircuitStateChange?: (event: CircuitStateChangeEvent) => void | Promise; - onSuccess?: (context: SuccessContext) => void | Promise; - onFailure?: (context: FailureContext) => void | Promise; } /** @deprecated use SmoothFetchConfig instead */