/** * Offerer-side WebRTC connection with offer creation and answer processing */ import { RondevuConnection } from './base.js'; import { RondevuAPI, IceCandidate } from '../api/client.js'; import { ConnectionConfig } from './config.js'; import { WebRTCAdapter } from '../webrtc/adapter.js'; export interface OffererOptions { api: RondevuAPI; ownerPublicKey: string; offerId: string; pc: RTCPeerConnection; dc?: RTCDataChannel; webrtcAdapter?: WebRTCAdapter; config?: Partial; } /** * Offerer connection - manages already-created offers and waits for answers */ export declare class OffererConnection extends RondevuConnection { private api; private ownerPublicKey; private offerId; private _peerPublicKey; private rotationLock; private rotating; private rotationAttempts; private static readonly MAX_ROTATION_ATTEMPTS; private pendingIceCandidates; constructor(options: OffererOptions); /** * Initialize the connection - setup handlers for already-created offer */ initialize(): Promise; /** * Process an answer from the answerer */ processAnswer(sdp: string, answererPublicKey: string): Promise; /** * Rebind this connection to a new offer (when previous offer failed) * Keeps the same connection object alive but with new underlying WebRTC */ rebindToOffer(newOfferId: string, newPc: RTCPeerConnection, newDc?: RTCDataChannel): Promise; /** * Check if connection is currently rotating */ isRotating(): boolean; /** * Override onConnected to reset rotation attempts */ protected onConnected(): void; /** * Generate a hash fingerprint of SDP for deduplication */ private hashSdp; /** * Send buffered ICE candidates to the server in a single batch */ protected sendBufferedIceCandidates(candidates: RTCIceCandidate[]): void; /** * Get the API instance */ protected getApi(): any; /** * Get the owner public key */ protected getOwnerPublicKey(): string; /** * Offerers accept all ICE candidates (no filtering) */ protected getIceCandidateRole(): 'offerer' | null; /** * Attempt to reconnect (required by abstract base class) * * For OffererConnection, traditional reconnection is NOT used. * Instead, the OfferPool handles failures via offer rotation: * * 1. When this connection fails, the 'failed' event is emitted * 2. OfferPool detects the failure and calls createNewOfferForRotation() * 3. The new offer is published to the server * 4. This connection is rebound via rebindToOffer() * * This approach ensures the answerer always gets a fresh offer * rather than trying to reconnect to a stale one. * * @see OfferPool.createNewOfferForRotation() - creates replacement offer * @see OffererConnection.rebindToOffer() - rebinds connection to new offer */ protected attemptReconnect(): void; /** * Get the offer ID */ getOfferId(): string; /** * Get the peer public key (who answered this offer) * Returns null if no answer has been processed yet */ get peerPublicKey(): string | null; /** * Handle remote ICE candidates received from polling * Called by OfferPool when poll:ice event is received */ handleRemoteIceCandidates(candidates: IceCandidate[]): void; /** * Apply ICE candidates to the peer connection */ private applyIceCandidates; }