import type { ChannelSelectionStrategy, ResolvedSiteProfile } from "./profiles.js"; import type { Frame, Page } from "puppeteer-core"; import type { Nullable } from "./shared.js"; export interface ChannelSelectionProfile extends ResolvedSiteProfile { channelSelector: string; } export declare function isChannelSelectionProfile(profile: ResolvedSiteProfile): profile is ChannelSelectionProfile; /** * Result of attempting to select a channel from a multi-channel player UI. */ export interface ChannelSelectorResult { directTune?: boolean; reason?: string; success: boolean; } /** * The strategy function signature. All strategies take the Puppeteer page and a narrowed profile with guaranteed non-null channelSelector. */ export type ChannelStrategyHandler = (page: Page, profile: ChannelSelectionProfile) => Promise; /** * The complete contract for a channel selection strategy. Each provider file exports a single object implementing this interface. The coordinator accesses all * provider behavior through these hooks — no strategy-specific imports or hardcoded strategy name checks outside the registry. */ export interface ChannelStrategyEntry { /** * Resets all module-level caches (row positions, discovered URLs, watch URLs). Called on browser restart when cached state may be stale. */ clearCache?: () => void; /** * Selects the target channel in the provider's guide UI. Receives a Puppeteer page and a profile with a guaranteed non-null channelSelector. Must handle its * own retry logic (e.g., overlay dismiss) and return a result indicating success or failure with a diagnostic reason. */ execute: ChannelStrategyHandler; /** * Removes a cached watch URL after it failed to produce a working stream. Called by the coordinator when a cached direct navigation fails. */ invalidateDirectUrl?: (channelSelector: string) => void; /** * Returns a watch URL for direct navigation, bypassing guide page loading. Implementations may perform async work such as fetching current asset IDs from * provider APIs. The page parameter allows setting up response interception or accessing browser context when needed (e.g., cold cache setup). */ resolveDirectUrl?: (channelSelector: string, page: Page) => Promise>; } /** * Standardized output shape for a channel discovered from a provider's guide. Produced by each provider's discoverChannels implementation and returned as * a JSON array from the GET /providers/:slug/channels endpoint. Mirrors the shape of channel definitions in channels/index.ts so discovery output can be * used directly to populate new entries. */ export interface DiscoveredChannel { affiliate?: string; channelSelector: string; name: string; stationId?: string; tier?: string; } /** * Unified provider contract that bundles identity metadata, tuning strategy, and channel discovery into a single registry entry. Each provider tuning file * exports one ProviderModule. The coordinator builds its strategy dispatch lookup from provider modules at evaluation time. Generic strategies (thumbnailRow, * tileClick) remain bare ChannelStrategyEntry objects — they are not providers. */ export interface ProviderModule { /** * Discovers all available channels from the provider's guide. The route handler navigates to guideUrl before calling this function unless handlesOwnNavigation * is set. Returns a standardized DiscoveredChannel array. */ discoverChannels: (page: Page) => Promise; /** * Returns cached discovered channels if the provider has already fully enumerated its lineup from a previous tune or discovery call, or null if no enumeration * has occurred. When non-null, the route handler can skip browser page creation entirely and return the cached result immediately. */ getCachedChannels: () => Nullable; guideUrl: string; handlesOwnNavigation?: boolean; label: string; slug: string; strategy: ChannelStrategyEntry; strategyName: ChannelSelectionStrategy; validatePrecache?: (channels: DiscoveredChannel[]) => boolean; validateTune?: (channelSelector: string) => boolean; } /** * Coordinates for a click target, used when clicking channel selector elements. */ export interface ClickTarget { x: number; y: number; } /** * Result of tuning to a channel, containing the video context needed for monitoring. */ export interface TuneResult { context: Frame | Page; directTune?: boolean; } /** * Browser chrome dimensions (toolbars, borders) calculated by comparing window.outerHeight/Width to window.innerHeight/Width. Used to set window size such that * the viewport (content area) matches our target dimensions. */ export interface UiSize { height: number; width: number; }