import type { z } from 'zod';
import type { SSEEventDefinition } from '../defineEvent.js';
import type { SSEMessage } from '../sseTypes.js';
import type { SSERoomManager } from './SSERoomManager.js';
import type { BroadcastResult, PreDeliveryFilter, RoomBroadcastOptions } from './types.js';
/**
 * Shared, non-generic room broadcaster that can be registered once in DI
 * and used by multiple controllers and domain services.
 *
 * Controllers register their `sendEvent` callback via `registerSender()`.
 * Domain services receive the broadcaster directly from the DI container.
 *
 * Requires `sseRoomManager` to be registered in the DI container.
 *
 * @example
 * ```typescript
 * // In your DI module's resolveDependencies()
 * sseRoomManager: asValue(new SSERoomManager()),
 * sseRoomBroadcaster: asSingletonClass(SSERoomBroadcaster),
 *
 * // In a domain service
 * class MetricsService {
 *   private readonly sseRoomBroadcaster: SSERoomBroadcaster
 *   constructor(deps: { sseRoomBroadcaster: SSERoomBroadcaster }) {
 *     this.sseRoomBroadcaster = deps.sseRoomBroadcaster
 *   }
 * }
 * ```
 */
export declare class SSERoomBroadcaster {
    private readonly _roomManager;
    private readonly senders;
    private readonly dedupCache;
    private preDeliveryFilter?;
    constructor(deps: {
        sseRoomManager: SSERoomManager;
    });
    /**
     * Set a pre-delivery filter that runs before sending to each connection.
     * Used by SSESubscriptionManager for resolver pipeline evaluation.
     * Only one filter can be active at a time — calling this method twice throws,
     * to prevent silently replacing an already-installed filter (which is almost
     * always a wiring bug, e.g. registering two SSESubscriptionManagers).
     */
    setPreDeliveryFilter(filter: PreDeliveryFilter): void;
    /**
     * Public getter for the underlying room manager.
     * Used by the route builder for `session.rooms`.
     */
    get roomManager(): SSERoomManager;
    /**
     * Register a sender callback (typically from a controller's sendEvent).
     * When broadcasting, each registered sender is tried — the first to return `true` wins.
     */
    registerSender(sendFn: (connId: string, msg: SSEMessage) => Promise<boolean>): void;
    /**
     * Broadcast a type-safe event to all connections in one or more rooms.
     *
     * Domain services use this method with `defineEvent()`-based event definitions
     * for compile-time data validation.
     *
     * @param room - Room name or array of room names
     * @param event - Event definition created by `defineEvent()`
     * @param data - Event data (must match the schema from the event definition)
     * @param options - Broadcast options (local, id, retry)
     * @returns Number of local connections the message was successfully delivered to.
     *          For separate `delivered`/`filtered` counts, call {@link broadcastMessage}.
     */
    broadcastToRoom<T extends z.ZodType>(room: string | string[], event: SSEEventDefinition<string, T>, data: z.input<T>, options?: RoomBroadcastOptions & {
        id?: string;
        retry?: number;
        metadata?: Record<string, unknown>;
    }): Promise<number>;
    /**
     * Lower-level broadcast API — sends a raw SSEMessage to all connections in one or more rooms.
     *
     * The controller's typed `broadcastToRoom()` delegates here after constructing the message.
     *
     * @param room - Room name or array of room names
     * @param message - The SSE message to broadcast
     * @param options - Broadcast options (local)
     * @returns `delivered` is the number of local connections the message was sent to;
     *          `filtered` is the number of local connections skipped by the pre-delivery
     *          filter. Returning both per-call (rather than tracking on the broadcaster)
     *          avoids races between concurrent broadcasts.
     */
    broadcastMessage(room: string | string[], message: SSEMessage, options?: RoomBroadcastOptions & {
        metadata?: Record<string, unknown>;
    }): Promise<BroadcastResult>;
    /**
     * Get all connection IDs in a room.
     *
     * @param room - The room to query
     * @returns Array of connection IDs
     */
    getConnectionsInRoom(room: string): string[];
    /**
     * Get the number of connections in a room.
     *
     * @param room - The room to query
     * @returns Number of connections
     */
    getConnectionCountInRoom(room: string): number;
    /**
     * Clean up dedup cache for a disconnected connection.
     * Called by the controller when a connection is unregistered.
     */
    cleanupConnection(connectionId: string): void;
    /**
     * Try each registered sender until one succeeds (only the owning controller can send).
     */
    private sendToConnection;
    /**
     * Handle broadcasts from other nodes (via adapter).
     * Deduplicates messages per-connection based on message ID.
     */
    private handleRemoteBroadcast;
    /**
     * Check if a message has already been delivered to a connection (deduplication).
     * Returns true if the message is a duplicate and should be skipped.
     */
    private isDuplicateMessage;
    /**
     * Collect unique connection IDs from multiple rooms.
     */
    private collectRoomConnections;
}
