import type { Frame, Page } from "puppeteer-core"; import type { Nullable, VideoState } from "../types/index.js"; /** * Recovery metrics tracked throughout the stream's lifetime. Returned when the monitor stops for inclusion in termination logs. */ export interface RecoveryMetrics { currentRecoveryStartTime: Nullable; currentRecoveryMethod: Nullable; pageNavigationAttempts: number; pageNavigationSuccesses: number; playUnmuteAttempts: number; playUnmuteSuccesses: number; sourceReloadAttempts: number; sourceReloadSuccesses: number; tabReplacementAttempts: number; tabReplacementSuccesses: number; totalRecoveryTimeMs: number; } export declare const RECOVERY_METHODS: { readonly pageNavigation: "page navigation"; readonly playUnmute: "play/unmute"; readonly sourceReload: "source reload"; readonly tabReplacement: "tab replacement"; }; /** * Creates a new RecoveryMetrics object with all counters initialized to zero. * @returns A fresh RecoveryMetrics object. */ export declare function createRecoveryMetrics(): RecoveryMetrics; /** * Gets the total number of recovery attempts across all methods. Iterates over ATTEMPT_FIELDS to sum all attempt counters, ensuring new recovery methods are * automatically included without code changes. * @param metrics - The recovery metrics object. * @returns Total recovery attempts. */ export declare function getTotalRecoveryAttempts(metrics: RecoveryMetrics): number; /** * Formats recovery duration from start time to now. * @param startTime - The timestamp when recovery started. * @returns Formatted duration string like "2.1s". */ export declare function formatRecoveryDuration(startTime: number): string; /** * Maps issue category to user-friendly description for logging. * @param category - The issue category from getIssueCategory(). * @returns User-friendly description. */ export declare function getIssueDescription(category: "paused" | "buffering" | "other"): string; /** * Maps recovery level to method name. * @param level - The recovery level (1, 2, or 3). * @returns The recovery method name. */ export declare function getRecoveryMethod(level: number): string; /** * Records a recovery attempt in the metrics. Uses the ATTEMPT_FIELDS mapping to find the correct counter field, eliminating the need for if/else chains. This * makes adding new recovery methods trivial - just add an entry to ATTEMPT_FIELDS. * * Note: Tab replacement calls this once per logical attempt even though it may internally retry the onTabReplacement callback. The retry is an implementation * detail of executeTabReplacement, not a separate recovery attempt from the monitor's perspective. The circuit breaker likewise records one failure per logical * attempt, not per callback invocation. * @param metrics - The metrics object to update. * @param method - The recovery method being attempted. */ export declare function recordRecoveryAttempt(metrics: RecoveryMetrics, method: string): void; /** * Records a successful recovery in the metrics and clears the pending recovery state. Uses the SUCCESS_FIELDS mapping to find the correct counter field, * eliminating the need for if/else chains. This makes adding new recovery methods trivial - just add an entry to SUCCESS_FIELDS. * @param metrics - The metrics object to update. * @param method - The recovery method that succeeded. */ export declare function recordRecoverySuccess(metrics: RecoveryMetrics, method: string): void; /** * Capitalizes the first letter of a string. * @param str - The string to capitalize. * @returns The string with the first letter capitalized. */ export declare function capitalize(str: string): string; /** * Formats the recovery metrics summary for the termination log. Uses the SUCCESS_FIELDS mapping to iterate over all recovery methods, eliminating hardcoded * checks for each method type. This ensures new recovery methods are automatically included in the summary. * @param metrics - The recovery metrics object. * @returns Formatted summary string, or empty string if no recoveries occurred. */ export declare function formatRecoveryMetricsSummary(metrics: RecoveryMetrics): string; /** * Circuit breaker state for tracking failures within a time window. The circuit breaker prevents endless recovery attempts on fundamentally broken streams by * terminating after a threshold of failures within a configured window. */ export interface CircuitBreakerState { firstFailureTime: Nullable; totalFailureCount: number; } /** * Result from checking circuit breaker state. */ export interface CircuitBreakerResult { shouldTrip: boolean; totalCount: number; withinWindow: boolean; } /** * Records a failure and checks whether the circuit breaker should trip. This centralizes the circuit breaker logic that was previously duplicated in multiple * recovery paths. The function updates the state in place and returns whether the breaker should trip. * @param state - The circuit breaker state to update. * @param now - The current timestamp. * @returns Result indicating whether the circuit breaker should trip and diagnostic info. */ export declare function checkCircuitBreaker(state: CircuitBreakerState, now: number): CircuitBreakerResult; /** * Resets the circuit breaker state. Called when sustained healthy playback is achieved. * @param state - The circuit breaker state to reset. */ export declare function resetCircuitBreaker(state: CircuitBreakerState): void; /** * Result from tab replacement recovery. When a browser tab becomes unresponsive (consecutive evaluate timeouts), the recovery handler closes the old tab, creates a * new one with fresh capture, and returns the new page and context. The monitor then updates its internal references to continue monitoring the new tab. */ export interface TabReplacementResult { context: Frame | Page; page: Page; } /** * Formats the issue type for diagnostic logging. Returns a human-readable string describing what triggered the recovery. Multiple issues can occur simultaneously * (e.g., "paused, stalled"), so we collect all applicable issues into a comma-separated list. * @param state - The video state object containing paused, ended, hasError, etc. * @param isStalled - Whether the video is stalled (not progressing). * @param isBuffering - Whether the video is actively buffering. * @returns A description of the issue. */ export declare function formatIssueType(state: VideoState, isStalled: boolean, isBuffering: boolean): string; /** * Determines the issue category for recovery path selection. This is separate from formatIssueType (which is for logging) because recovery decisions need a single * category, not a list of all issues. The categories are: * - "paused": Video is paused but not buffering. L1 (play/unmute) may help. * - "buffering": Video is buffering or stalled with low readyState. Skip L1, go to L2 (source reload). * - "other": Error, ended, or unknown state. Skip L1, go to L2 (source reload). * @param state - The video state object. * @param isStalled - Whether the video is stalled (not progressing). * @param isBuffering - Whether the video is actively buffering. * @returns The issue category for recovery path selection. */ export declare function getIssueCategory(state: VideoState, isStalled: boolean, isBuffering: boolean): "paused" | "buffering" | "other";