import { PeerID, Adapter, GeneratedChannel } from '@loro-extended/repo'; type ConnectionState = "disconnected" | "connecting" | "connected" | "reconnecting"; interface HttpPollingClientOptions { /** * URL for polling (GET requests). * Can be a string or a function that receives the peerId and returns the URL. * The URL should include the peerId as a query parameter. * * @example * pollUrl: (peerId) => `/api/poll?peerId=${peerId}` */ pollUrl: string | ((peerId: PeerID) => string); /** * URL for sending messages (POST requests). * Can be a string or a function that receives the peerId and returns the URL. * * @example * postUrl: () => `/api/sync` */ postUrl: string | ((peerId: PeerID) => string); /** * Retry options for POST requests. */ postRetry?: { maxAttempts?: number; baseDelay?: number; maxDelay?: number; }; /** * How long to ask the server to wait for messages (hint, not guarantee). * Server may return sooner due to: messages available, infra timeout, server config. * Set to 0 for regular polling behavior (server returns immediately). * * @default 30000 (30 seconds) */ serverWaitHint?: number; /** * Minimum time between poll requests (prevents hammering on errors/cuts). * This acts as a rate limiter when errors occur. * * @default 100 (100ms) */ minPollInterval?: number; /** * Optional delay after successful response before re-polling. * Set to 0 for immediate re-poll (real-time feel with long-polling). * Set to a higher value for battery-friendly regular polling. * * @default 0 (immediate re-poll) */ pollDelay?: number; /** * Optional fetch options (headers, credentials, etc.). * These will be merged with the default options for each request. */ fetchOptions?: RequestInit; } /** * HTTP Polling client network adapter. * * This adapter connects to a server using HTTP polling with optional long-polling support. * It's resilient to infrastructure limitations - if long-polling connections are cut short, * it gracefully degrades to regular polling behavior. * * @example * ```typescript * const adapter = new HttpPollingClientNetworkAdapter({ * pollUrl: (peerId) => `/api/poll?peerId=${peerId}`, * postUrl: () => `/api/sync`, * serverWaitHint: 30000, // Ask server to wait up to 30s * minPollInterval: 100, // Rate limit on errors * pollDelay: 0, // Immediate re-poll * }) * * const repo = new Repo({ * identity: { name: "client", type: "user" }, * adapters: [adapter] * }) * ``` */ declare class HttpPollingClientNetworkAdapter extends Adapter { private peerId?; private pollUrl; private postUrl; private serverWaitHint; private minPollInterval; private pollDelay; private fetchOptions?; private postRetryOptions; private serverChannel?; private isPolling; private shouldStop; private pollAbortController?; connectionState: ConnectionState; private listeners; constructor(options: HttpPollingClientOptions); /** * Subscribe to connection state changes. * @param listener Callback function that receives the new state * @returns Unsubscribe function */ subscribe(listener: (state: ConnectionState) => void): () => void; private setConnectionState; protected generate(): GeneratedChannel; onStart(): Promise; onStop(): Promise; /** * Start the polling loop. */ private startPolling; /** * Stop the polling loop. */ private stopPolling; /** * The main polling loop. * Uses async/await instead of setInterval for better control. */ private pollLoop; /** * Perform a single poll request. */ private poll; /** * Sleep for the specified duration. */ private sleep; private sendWithRetry; } export { type ConnectionState, HttpPollingClientNetworkAdapter, type HttpPollingClientOptions };