import { Awareness } from 'y-protocols/awareness.js'; import { SyncManagerConfig, CollabConnectionConfig, CollabServices, CollabCallbacks, CollabStatus, CollabState } from './types'; export declare class SyncManager { private onCollabStateChange; private _status; private _context; private _awareness; private socketClient; private roomKey; private roomKeyBytes; private rotating; private roomKeyBytesPrev; private pendingRotationKey; private healingPromise; private healBackoffUntil; private staleAckRetries; private encryptMirror; private fileKeyEpoch; private mirrorIdleTimer; private readonly MIRROR_IDLE_MS; private isOwner; private joinOnly; private updateQueue; private contentTobeAppliedQueue; private isProcessing; private syncId; private floor; private updatesSinceSnapshot; private isAuthoringSnapshot; private readonly SNAPSHOT_THRESHOLD; private tailCompactTimer; private gapCatchUpTimer; private gapCatchUpInFlight; private gapCatchUpCooldownUntil; private readonly TAIL_COMPACT_PAGES; private readonly TAIL_COMPACT_ROWS; private flushTimer; private readonly FLUSH_INTERVAL_MS; private readonly MAX_QUEUE_SIZE; private _awarenessUpdateHandler; private ydoc; private callbacksRef; private onLocalUpdate?; constructor(config: SyncManagerConfig, onCollabStateChange: (state: CollabState) => void); /** Called by useSyncManager on every render to keep refs fresh */ updateRefs(_services: CollabServices | undefined, callbacks: CollabCallbacks | undefined, onLocalUpdate?: (updatedDocContent: string, updateChunk: string) => void): void; get isConnected(): boolean; get isReady(): boolean; get awareness(): Awareness | null; get status(): CollabStatus; get collabState(): CollabState; private beginSyncAttempt; private isCurrentSyncAttempt; private send; private runExitActions; private runEntryActions; connect(config: CollabConnectionConfig): Promise; disconnect(): Promise; /** Owner rename mid-session — see SocketClient.updateDocumentMeta. */ updateTitle(args: { encryptedTitle: string; documentTitle: string; }): Promise; terminateSession(): Promise; /** In-place roomKey migration on CUTOVER: pause dispatch, swap the key, re-auth the same * socket, re-broadcast awareness, then flush. See SocketClient.rekey for the wire side. */ rekey(newRoomKey: string, newAppLock?: string, newEditUcan?: string): Promise; private onDecryptMiss; private runGapCatchUp; private scheduleGapCatchUp; enqueueLocalUpdate(update: Uint8Array): void; private flushUpdates; private awaitFlush; /** * Fire-and-forget: merge all queued updates, encrypt, and emit via Socket.IO * without awaiting the server ACK. The server broadcasts to peers immediately * (before MongoDB write), so content reaches observers in near-real-time. */ private sendUpdateBatch; private sendUpdateBatchAttempt; private isRevocationResponse; private isSessionTerminatedResponse; private isSessionNotFoundResponse; private classifyRevocation; private handleWriteRevocation; private surfaceSessionTerminated; private maybeAuthorSnapshotAfterSend; private scheduleMirror; private authorMirror; buildPendingBeaconPayload(): string | null; fireBeacon(): void; forceCleanup(): void; private handleConnectionError; private handleReconnection; private connectSocket; private tryDecrypt; private decodeInto; private catchUpFloor; private authorSnapshot; private hydrate; private maybeCompactTail; private initializeAwareness; private cleanupAwareness; private broadcastLocalContents; private processUpdateQueue; private processNextUpdate; private handleRemoteContentUpdate; private applyRemoteYjsUpdate; private applyQueuedRemoteContents; private withRetry; private disconnectInternal; private resetInternalState; }