import type { RelayFileClient } from "./client.js"; import type { EventOrigin, FilesystemEvent } from "./types.js"; /** * WebSocket auth source for {@link RelayFileSyncOptions.token}. * * The function form is preferred for production: it is re-invoked on every * (re)connect, so token rotation/refresh propagates without restarting the * sync. The plain string form is kept for backward compatibility and tests. */ export type RelayFileSyncTokenProvider = string | (() => string | undefined | Promise); export type RelayFileSyncState = "idle" | "connecting" | "open" | "polling" | "reconnecting" | "closed"; export type RelayFileSyncStart = "now" | "legacy"; export interface RelayFileSyncPong { type: "pong"; timestamp?: string; } export interface RelayFileSyncReconnectOptions { enabled?: boolean; minDelayMs?: number; maxDelayMs?: number; } export interface RelayFileSyncOptions { client: RelayFileClient; workspaceId: string; baseUrl?: string; /** * WebSocket auth token. Accepts either a literal string or a (sync/async) * factory. The factory form is re-invoked on every (re)connect so token * rotation propagates transparently. * * If omitted, sync resolves the token via `client.getToken()` on each * connect — i.e. the same JWT the REST methods are using. Callers should * normally NOT pass this and let it inherit from the client. */ token?: RelayFileSyncTokenProvider; from?: RelayFileSyncStart; cursor?: string; paths?: string[]; preferPolling?: boolean; pollIntervalMs?: number; pingIntervalMs?: number; pongTimeoutMs?: number; reconnect?: boolean | RelayFileSyncReconnectOptions; signal?: AbortSignal; webSocketFactory?: (url: string) => RelayFileSyncSocket; onEvent?: (event: FilesystemEvent) => void; /** * Notification hook invoked when the sync degrades to HTTP polling because * the WebSocket failed to open or was rejected by the server. Live events * will be delayed by `pollIntervalMs` while in this mode. Use this to * surface a UI banner or alert; the SDK also emits `console.warn` and an * `error` event regardless of whether this is wired. */ onPollingFallback?: (info: { reason: string; cause?: unknown; }) => void; } export interface RelayFileSyncSocket { addEventListener(type: "open", handler: (event: Event) => void): void; addEventListener(type: "message", handler: (event: MessageEvent) => void): void; addEventListener(type: "error", handler: (event: Event | ErrorEvent) => void): void; addEventListener(type: "close", handler: (event: CloseEvent) => void): void; close(code?: number, reason?: string): void; send(data: string): void; } type RelayFileSyncEventName = "event" | "error" | "state" | "open" | "close" | "pong"; type RelayFileSyncHandlerMap = { event: (event: FilesystemEvent) => void; error: (error: Event | Error) => void; state: (state: RelayFileSyncState) => void; open: (event: Event) => void; close: (event: CloseEvent) => void; pong: (event: RelayFileSyncPong) => void; }; interface RelayFileSyncWireEvent { type: string; id?: string; eventId?: string; path?: string; revision?: string; digest?: string; contentHash?: string; origin?: EventOrigin; provider?: string; correlationId?: string; timestamp?: string; ts?: string; occurredAt?: string; resource?: { path?: unknown; provider?: unknown; }; } export declare function normalizeFilesystemEvent(message?: RelayFileSyncWireEvent | null): FilesystemEvent; export declare function normalizeError(event: unknown): unknown; export declare class RelayFileSync { private readonly client; private readonly workspaceId; private readonly baseUrl?; private readonly tokenProvider?; private readonly pollIntervalMs; private readonly pingIntervalMs; private readonly pongTimeoutMs; private readonly reconnect; private readonly preferPolling; private readonly signal?; private readonly webSocketFactory; private readonly onPollingFallback?; private readonly handlers; private state; private cursor?; private readonly from; private readonly paths; private readonly polledEventIds; private readonly polledEventOrder; private firstPollComplete; private socket?; private started; private stopped; private pollingPromise?; private reconnectTimer?; private pingTimer?; private errorRecoveryTimer?; private currentSocketHasOpened; private lastFrameAt; private lastPingSentAt; private reconnectAttempts; private pollingReprobeAttempts; private pollingReprobeEnabled; private readonly abortHandler?; constructor(options: RelayFileSyncOptions); static connect(options: RelayFileSyncOptions): RelayFileSync; getState(): RelayFileSyncState; start(): void; stop(): Promise; on(event: TEventName, handler: RelayFileSyncHandlerMap[TEventName]): () => void; private shouldUsePolling; private resolveWsTokenMaybeSync; private openWebSocket; private openWebSocketWithToken; private startPolling; private pollLoop; private rememberPolledEvent; private handleSocketMessage; private emitFilesystemEvent; private startPingLoop; private forceReconnect; private scheduleReconnect; private computeReconnectDelayMs; private computeReprobeDelayMs; private sleep; private isAbortError; private setState; private clearReconnectTimer; private clearPingTimer; private clearErrorRecoveryTimer; private emit; } export {};