import { CrdtType, HexString } from "loro-protocol"; import { CrdtDocAdaptor } from "loro-adaptors"; export * from "loro-adaptors"; //#region src/client/index.d.ts type AuthProvider = () => Uint8Array | Promise; type AuthOption = Uint8Array | AuthProvider; /** * The websocket client's high-level connection status. * - `Connecting`: initial connect or a manual `connect()` in progress. * - `Connected`: the websocket is open and usable. * - `Disconnected`: the client is not connected. Call `connect()` to retry. */ declare const ClientStatus: { readonly Connecting: "connecting"; readonly Connected: "connected"; readonly Disconnected: "disconnected"; }; type ClientStatusValue = (typeof ClientStatus)[keyof typeof ClientStatus]; /** * Options for `LoroWebsocketClient`. * * Behavior summary: * - The client auto-connects on construction and retries on unexpected closures with an exponential backoff. * - Call `close()` to stop auto-reconnect and move to `Disconnected`. Call `connect()` to resume. * - Pings are sent periodically to keep the connection alive; `latency` estimates are updated on pong. */ interface LoroWebsocketClientOptions { /** WebSocket URL (ws:// or wss://). */ url: string; /** Optional custom ping interval. Defaults to 30s. Set with `disablePing` to stop timers. */ pingIntervalMs?: number; /** Ping timeout; after two consecutive misses the client will force-close and reconnect. Defaults to 10s. */ pingTimeoutMs?: number; /** Disable periodic ping/pong entirely. */ disablePing?: boolean; /** Optional callback for low-level ws close (before status transitions). */ onWsClose?: () => void; /** Optional callback for any client-level errors (socket error, decode/apply failures, send on closed, etc.). */ onError?: (error: Error) => void; /** * Reconnect policy (kept minimal). * - enabled: toggle auto-retry (default true) * - initialDelayMs: starting backoff delay (default 500) * - maxDelayMs: max backoff delay (default 15000) * - jitter: 0-1 multiplier applied randomly around the delay (default 0.25) * - maxAttempts: number | "infinite" (default "infinite") * - fatalCloseCodes: close codes that should not retry (default 4400-4499, 1008, 1011) * - fatalCloseReasons: close reasons that should not retry (default permission_changed, room_closed, auth_failed) */ reconnect?: { enabled?: boolean; initialDelayMs?: number; maxDelayMs?: number; jitter?: number; maxAttempts?: number | "infinite"; fatalCloseCodes?: number[]; fatalCloseReasons?: string[]; }; } declare const RoomJoinStatus: { readonly Connecting: "connecting"; readonly Joined: "joined"; readonly Reconnecting: "reconnecting"; readonly Disconnected: "disconnected"; readonly Error: "error"; }; type RoomJoinStatusValue = (typeof RoomJoinStatus)[keyof typeof RoomJoinStatus]; /** * Loro websocket client with auto-reconnect, connection status events, and latency tracking. * * Status model: * - `Connected`: ws open. * - `Disconnected`: socket closed. Auto-reconnect retries run unless `close()`/`destroy()` stop them. * - `Connecting`: initial or manual connect in progress. * * Events: * - `onStatusChange(cb)`: called whenever status changes. * - `onLatency(cb)`: called when a new RTT estimate is measured from ping/pong. */ declare class LoroWebsocketClient { private ops; private ws; private connectedPromise; private resolveConnected?; private rejectConnected?; private status; private statusListeners; private latencyListeners; private lastLatencyMs?; private awaitingPongSince?; private pendingRooms; private activeRooms; private preJoinUpdates; private sentUpdateBatches; private fragmentBatches; private roomAdaptors; private roomIds; private roomAuth; private roomStatusListeners; private socketListeners; private pingTimer?; private pingWaiters; private missedPongs; private shouldReconnect; private reconnectAttempts; private reconnectTimer?; private removeNetworkListeners?; private offline; private queuedJoins; constructor(ops: LoroWebsocketClientOptions); private resolveAuth; get socket(): WebSocket; private ensureConnectedPromise; private attachNetworkListeners; /** Current client status. */ getStatus(): ClientStatusValue; /** Latest measured RTT in ms (if any). */ getLatency(): number | undefined; /** Subscribe to status changes. Returns an unsubscribe function. */ onStatusChange(cb: (s: ClientStatusValue) => void): () => void; /** Subscribe to latency updates (RTT via ping/pong). Returns an unsubscribe function. */ onLatency(cb: (ms: number) => void): () => void; private setStatus; /** Initiate or resume connection. Resolves when `Connected`. */ connect(opts?: { resetBackoff?: boolean; }): Promise; private attachSocketListeners; private onSocketOpen; private onSocketError; private onSocketClose; private onSocketMessage; private scheduleReconnect; private clearReconnectTimer; private handleOnline; private handleOffline; private rejoinActiveRooms; private sendRejoinRequest; private handleMessage; private handleFragmentHeader; private handleFragment; private registerActiveRoom; private handleJoinError; cleanupRoom(roomId: string, crdtType: CrdtType): void; waitConnected(): Promise; ping(timeoutMs?: number): Promise; /** * Join a room. * - `auth` may be a `Uint8Array` or a provider function. * - The provider is invoked on the initial join and again on protocol-driven retries * (e.g. `VersionUnknown`) and reconnect rejoins, so it can refresh short-lived tokens. * If callers need a stable token, memoize in the provider. */ join({ roomId, crdtAdaptor, auth, onStatusChange }: { roomId: string; crdtAdaptor: CrdtDocAdaptor; auth?: AuthOption; onStatusChange?: (s: RoomJoinStatusValue) => void; }): Promise; /** * Manually close the connection and stop auto-reconnect. * To reconnect later, call `connect()`. */ close(): void; private sendUpdateOrFragments; /** @internal Send Leave on the current websocket. */ sendLeave(crdt: CrdtType, roomId: string): void; /** * Send additional updates to a specified room. * * This method allows sending updates that are not from the local peer's document, * such as updates received from other sources or peers. The updates will be * broadcast to the room and other connected clients. * * @param crdt - The CRDT type of the room * @param roomId - The room ID to send updates to * @param updates - Array of update payloads to send * @throws Error if not connected or room is not active */ sendExternalUpdates(crdt: CrdtType, roomId: string, updates: Uint8Array[]): void; consumeSentBatch(refId: HexString): { roomKey: string; updates: Uint8Array[]; } | undefined; private purgeSentBatchesForRoom; /** * Destroy the client, removing listeners and stopping timers. * After destroy, the instance should not be used. */ destroy(): void; private flushAndCloseWebSocket; private detachSocketListeners; private startPingTimer; private clearPingTimer; private handlePong; private rejectAllPingWaiters; /** Manual reconnect helper that resets backoff and attempts immediately. */ retryNow(): Promise; private getReconnectPolicy; private computeBackoffDelay; private safeSend; private logCbError; private emitError; private isFatalClose; private enqueueJoin; private sendJoinPayload; private flushQueuedJoins; private emitRoomStatus; private failAllPendingRooms; } interface LoroWebsocketClientRoom { /** * Leave the room. */ leave(): Promise; /** * This method returns a promise that resolves when the client document version is >= the server's version. */ waitForReachingServerVersion(): Promise; destroy(): Promise; } //#endregion export { AuthProvider, ClientStatus, ClientStatusValue, LoroWebsocketClient, LoroWebsocketClientOptions, LoroWebsocketClientRoom, RoomJoinStatus, RoomJoinStatusValue }; //# sourceMappingURL=index.d.ts.map