/**
 * Realtime gateway for `@actuate-media/realtime` rooms.
 *
 * The gateway is **transport-agnostic by design**: it does not depend on
 * `ws`, `uWebSockets.js`, Cloudflare Workers, or any specific framework.
 * Consumers create a `WebSocketLike` adapter around their server's socket
 * primitive and pass it to `gateway.handleConnection(socket, req)`.
 *
 * Responsibilities:
 *   1. Authenticate the connection (delegated to `options.authenticate`).
 *   2. Look up (or lazily create) the `Room` for the document.
 *   3. Pump bytes between the socket and the room.
 *   4. Persist edits via the configured `DocumentPersistence`.
 *   5. Reap idle rooms (no connections + no pending writes) to bound memory.
 *
 * The companion file `persistence.ts` provides
 * `createPrismaDocumentPersistence(db)` which the gateway uses by default
 * when callers don't supply their own.
 */
import { type DocumentPersistence } from '@actuate-media/realtime';
/**
 * Minimal contract the gateway needs from a real WebSocket implementation.
 * Compatible with `ws.WebSocket`, browser-native `WebSocket`, the
 * Cloudflare Workers `WebSocket` Hibernation API, and Bun's WebSocket.
 *
 * Adapter authors typically just wrap their library's socket in a thin
 * shim that conforms to this shape.
 */
export interface WebSocketLike {
    /** Send a binary frame. */
    send(data: Uint8Array): void;
    /** Close the socket. Idempotent. */
    close(code?: number, reason?: string): void;
    /** Subscribe to inbound binary frames. */
    on(event: 'message', handler: (data: Uint8Array) => void): void;
    /** Subscribe to close events. */
    on(event: 'close', handler: () => void): void;
    /** Subscribe to error events. */
    on(event: 'error', handler: (err: Error) => void): void;
}
/** Information about the inbound HTTP upgrade request. */
export interface UpgradeRequestInfo {
    /** Path + query, e.g. `/api/cms/realtime/sync?documentId=doc_1`. */
    url: string;
    /** Lowercased header bag. Authentication usually reads `cookie` or `authorization`. */
    headers: Readonly<Record<string, string | undefined>>;
}
/**
 * Outcome of the authentication / routing decision. Return `null` to reject
 * the connection (the gateway will close it with code 4401).
 *
 * `connectionId` should be globally unique within the gateway instance —
 * usually a `crypto.randomUUID()` or `req.headers['sec-websocket-key']`.
 */
export interface AuthenticatedConnection {
    documentId: string;
    connectionId: string;
    /** Tag returned via `room.onUpdate` so applications can audit edits. */
    userId?: string;
}
export interface AttachRealtimeGatewayOptions {
    /**
     * Validate the upgrade request and map it to a documentId. Return `null`
     * to reject. Throws are treated as 401 and the connection is closed.
     */
    authenticate: (req: UpgradeRequestInfo) => Promise<AuthenticatedConnection | null>;
    /** Storage adapter. Defaults to a noop in-memory persistence (rooms are not durable). */
    persistence?: DocumentPersistence;
    /**
     * Reap a room after it has had zero connections for this many ms. Default 60000.
     * Set to `Infinity` to disable reaping.
     */
    idleTimeoutMs?: number;
    /** Debounce window for persistence writes (ms). Forwarded to `bindPersistence`. */
    persistenceDebounceMs?: number;
    /** Maximum time between writes (ms). Forwarded to `bindPersistence`. */
    persistenceMaxIdleMs?: number;
    /** Called whenever a room is created. Useful for metrics. */
    onRoomOpen?: (documentId: string) => void;
    /** Called whenever a room is destroyed. Useful for metrics. */
    onRoomClose?: (documentId: string) => void;
    /** Called when a persistence save fails. Defaults to console.error. */
    onPersistenceError?: (documentId: string, err: unknown) => void;
}
export interface RealtimeGateway {
    /** Number of currently active rooms. Useful for /health endpoints. */
    readonly roomCount: number;
    /** Number of currently connected sockets across all rooms. */
    readonly connectionCount: number;
    /**
     * Bind an authenticated socket to its room. Call this from your HTTP
     * upgrade handler after `wss.handleUpgrade(...)` has produced a socket.
     */
    handleConnection(socket: WebSocketLike, req: UpgradeRequestInfo): Promise<void>;
    /**
     * Force-close every connection, flush every room, and tear everything
     * down. Call from your process's SIGTERM handler.
     */
    shutdown(): Promise<void>;
}
/**
 * Create a realtime gateway. The returned object is intended to live for the
 * lifetime of the server process — one per node. Calling
 * `shutdown()` is mandatory for graceful exit (it flushes pending writes).
 */
export declare function createRealtimeGateway(opts: AttachRealtimeGatewayOptions): RealtimeGateway;
//# sourceMappingURL=gateway.d.ts.map