import { type DataIssue, type ServiceResult } from "./entityDiagnostics.js"; /** * Why the fallback fired. Useful for telemetry: per-entity warnings * (`array-missing-slots`) look different from total-failures (`primary-threw`, * `result-undefined`) even though both surface as a fallback event. */ export type FallbackTrigger = "primary-threw" | "result-undefined" | "array-missing-slots" | "custom-shouldFallback" | "circuit-open"; export interface FallbackInfo { method: TKey; args: unknown[]; primaryName: string; secondaryName: string; /** Discriminator for what actually caused the fallback. */ trigger: FallbackTrigger; /** Error thrown by primary, if it threw. Undefined when fallback was triggered by a result code. */ primaryError?: unknown; /** Issues from a primary `ServiceResult`, if any. Undefined when primary threw or circuit was open. */ primaryIssues?: DataIssue[]; /** * For `trigger === "array-missing-slots"`: indices in the primary result array * that were `undefined`. Lets callers see which inputs the primary dropped. */ missingIndices?: number[]; } export interface FallbackAdapterOptions { /** Method names on the adapter that should be wrapped with fallback logic. */ methods: readonly TKey[]; /** * Override the default failure-detection logic for `ServiceResult` returns. * Default: fall back when `result === undefined`, or when `result` is an array * containing any `undefined` slot. Per-item warnings (e.g. SOURCE_UNAVAILABLE * on a nested entity) on an otherwise complete response do NOT trigger fallback. */ shouldFallback?: (primary: ServiceResult) => boolean; /** Names attached to FALLBACK_USED diagnostics for traceability. */ adapterNames: { primary: string; secondary: string; }; /** * Open a circuit after N consecutive primary failures; skip primary for `cooldownMs`. * Optional — defaults to no breaker (predictable, no surprise behavior). */ circuitBreaker?: { failures: number; cooldownMs: number; }; /** * Optional callback invoked after the secondary call completes (or fails to complete). * Useful for telemetry / surfacing fallback events to UI. Exceptions thrown by this * callback are caught and ignored so they don't disrupt the data flow. */ onFallback?: (info: FallbackInfo) => void; } /** * Wraps two adapters of the same interface with primary→secondary fallback. * * For each method in `options.methods`, runs `primary`. Fallback to `secondary` * fires when the primary throws, or (for `ServiceResult` returns) when `result` * is `undefined`, or when `result` is an array containing any `undefined` slot. * Per-item warnings on a fully-populated response do NOT trigger fallback — * the secondary can't recover information the primary already returned. Pass * `shouldFallback` to override. * * Methods NOT in `options.methods` pass through to `primary` unchanged — this keeps * setters (`setConfig`, `setPlugins`, etc.) and internal state on the primary instance. */ export declare function createFallbackAdapter(primary: T, secondary: T, options: FallbackAdapterOptions): T; //# sourceMappingURL=fallbackAdapter.d.ts.map