import { DecafController } from "../controllers.d.cts"; import { DecafRequestContext } from "../request/index.d.cts"; import { MessageEvent } from "@nestjs/common"; import { Observable } from "rxjs"; import { DecafServerCtx } from "../constants.d.cts"; import { ObserverSubscriptionRegistry } from "./ObserverSubscriptionRegistry.d.cts"; import type { ObserverEventsOptions } from "../types.d.cts"; /** * @description SSE controller exposing Decaf observer events as a Server-Sent Events stream * @summary Registers observers against all listening adapters and streams the events they * emit back to the client over SSE. In broadcast mode (the default) every stream gets * every event and a requester may open any number of streams (tabs, devices). When * {@link ObserverEventsOptions.subscriptionMode} is enabled, events are filtered by the * requester's topic subscriptions held in the {@link ObserverSubscriptionRegistry}, and a * requester (one client, see {@link resolveRequesterFingerprint}) holds a single stream: * a newer stream takes over and ends the previous one. * @class EventsController * @param {DecafRequestContext} clientContext - The active request context * @param {string[]} flavours - The adapter flavours to observe events on (injected via {@link LISTENING_ADAPTERS_FLAVOURS}) * @param {ObserverEventsOptions} options - Observer events configuration (injected via {@link OBSERVER_EVENTS_OPTIONS}) * @param {ObserverSubscriptionRegistry} registry - The topic-subscription registry * @memberOf module:for-nest.events * @mermaid * sequenceDiagram * participant Client * participant Controller as EventsController * participant Registry as ObserverSubscriptionRegistry * participant Adapters * Client->>Controller: listen() * Controller->>Controller: resolveFingerprint() * opt subscription mode * Controller->>Registry: claimConnection(fingerprint, evict) * end * loop for each adapter * Controller->>Adapters: observe(observer, filter) * end * Adapters-->>Controller: refresh(args) * Controller->>Client: SSE message * Client->>Controller: disconnect * opt subscription mode and claim still current * Controller->>Registry: claim.release(), remove(fingerprint) * end */ export declare class EventsController extends DecafController { private readonly options; private readonly registry; private readonly adapters; constructor(clientContext: DecafRequestContext, flavours: string[], options: ObserverEventsOptions, registry: ObserverSubscriptionRegistry); /** * @description Resolves the request's requester fingerprint * @summary Delegates to {@link resolveRequesterFingerprint}, falling back to a * freshly generated id so every anonymous SSE connection still gets a stable key. * @returns {string} The resolved fingerprint value */ private resolveFingerprint; /** * @description Streams observer events for all models over SSE * @summary Opens the heartbeat-augmented SSE stream for the requesting client. * See {@link EventsController} for the broadcast and subscription semantics. * @returns {Observable} The merged event and heartbeat SSE stream */ listen(): Observable; /** * @description Streams observer events for a single model over SSE * @summary Streams the raw observer arguments, without heartbeat. In * subscription mode only events whose topic targets the given model (or topic * prefix) and match the requester's subscriptions are sent; in broadcast mode * the stream is not filtered. * @param {string} model - The model name (or topic prefix) to observe events for * @returns {Observable} The SSE stream for the model */ listenForModel(model: string): Observable; /** * @description Builds the SSE stream for the requesting client * @summary Registers an observer on every listening adapter and, optionally, * merges its events with a `heartbeat` every 15 seconds. In subscription mode * events are filtered to the `scope` model and to the requester's subscriptions, * and the stream claims the requester's fingerprint: a newer stream from the * same client ends this one, and closing the current stream drops the client's * subscriptions (a reconnecting client subscribes again). * @param {Object} [options] - Stream options * @param {string} [options.scope] - Model (or topic prefix) the stream is restricted to in subscription mode * @param {boolean} [options.raw] - Send the raw observer arguments instead of the normalized event * @param {boolean} [options.heartbeat] - Emit a heartbeat every 15 seconds * @returns {Observable} The SSE stream */ private stream; }