/** * @module ServerSentEvents * SSE client that dispatches received events as DOM events. * * By default it uses the browser's built-in EventSource, which reconnects on its own. * Set a request option like `method`, `body`, `headers` or `signal`, or `autoReconnect: false`, * and it switches to a fetch based transport that can send data to the server and can tell you * why the stream ended. * * @example * const sse = new SSEClient('/api/events', { * eventTypes: ['user-updated', 'order-created'] * }); * sse.connect(); * * document.addEventListener('user-updated', (e: SSEDataEvent) => { * console.log('User updated:', e.data); * }); */ import { HttpResponse } from './http'; /** * Event dispatched when an SSE message is received. * The event name matches the SSE event type. */ export declare class SSEDataEvent extends Event { data: unknown; constructor(eventName: string, data: unknown, eventInit?: EventInit); } /** * Factory function for creating custom event instances. * * @example * const factory: SSEEventFactory = (eventName, data) => { * switch (eventName) { * case 'user-updated': * return new UserUpdatedEvent(data as User); * default: * return new SSEDataEvent(eventName, data); * } * }; */ export type SSEEventFactory = (eventName: string, data: unknown) => Event; /** * Why a stream stopped. * * `completed` = the server sent one of your `terminalEvents` and then closed. * `truncated` = the server closed cleanly but never sent a terminal event, so the result is * incomplete and you may want to offer a retry. * `aborted` = you stopped it yourself, through `disconnect()` or an `AbortSignal`. * `failed` = the request never started or died. `error` and `response` say why. */ export type SSECloseReason = 'completed' | 'truncated' | 'aborted' | 'failed'; /** * Details about a stream that has stopped. */ export interface SSECloseResult { /** * Why the stream stopped. */ reason: SSECloseReason; /** * Name of the last event received before the stream stopped. */ lastEventName?: string; /** * Set when the reason is `failed`. */ error?: Error; /** * Set when the server answered with a non 2xx status. `body` holds the raw response text. */ response?: HttpResponse; } /** * Passed to `onError` when the fetch transport fails. * * It extends Event so that the `onError` signature is the same for both transports. */ export declare class SSEErrorEvent extends Event { error: Error; response?: HttpResponse | undefined; constructor(error: Error, response?: HttpResponse | undefined); } /** * Configuration options for SSEClient. */ export interface SSEOptions { /** * Target element or CSS selector for event dispatching. * Defaults to document. */ target?: string | Element; /** * Whether to send credentials with the request (default: false). */ withCredentials?: boolean; /** * Specific SSE event types to listen for. * If not specified, listens to the default 'message' event. * * @example * eventTypes: ['user-updated', 'order-created'] */ eventTypes?: string[]; /** * Factory function for creating custom event instances. * If not provided, SSEDataEvent is used. * * @example * eventFactory: (name, data) => new MyCustomEvent(name, data) */ eventFactory?: SSEEventFactory; /** * HTTP method for the request (default: 'GET'). * Setting it selects the fetch transport. */ method?: 'GET' | 'POST' | 'PUT' | 'DELETE'; /** * Data to send to the server. * Setting it selects the fetch transport, since EventSource cannot send a body. * * @example * body: JSON.stringify({ matchId: 42 }) */ body?: BodyInit; /** * Extra request headers. * Setting them selects the fetch transport, since EventSource cannot send headers. */ headers?: Record; /** * Signal used to cancel the stream. Closes with reason `aborted`. * Setting it selects the fetch transport. */ signal?: AbortSignal; /** * Whether the browser should reconnect when the stream drops (default: true). * * Set to false to select the fetch transport, which never reconnects. A request that sends * data is not always safe to repeat, so reconnection is not available there. */ autoReconnect?: boolean; /** * Names of the events the server sends last. Receiving one of them means the result is * complete, so the stream closes with reason `completed` instead of `truncated`. * * @example * terminalEvents: ['verdict'] */ terminalEvents?: string[]; /** * Callback when the stream stops, for any reason. Called once per `connect()`. * * On the EventSource transport it is only called for `disconnect()`, because EventSource * cannot tell a finished server from a broken one. */ onClose?: (client: SSEClient, result: SSECloseResult) => void; /** * Callback when connection is established. */ onConnect?: (client: SSEClient) => void; /** * Callback when an error occurs. * On the EventSource transport the browser reconnects afterwards. * On the fetch transport the argument is an SSEErrorEvent and there is no reconnect. */ onError?: (client: SSEClient, error: Event) => void; } /** * Server-Sent Events client that dispatches received events as DOM events. * * @example * const sse = new SSEClient('/api/events', { * target: '#notifications', * eventTypes: ['notification', 'alert'] * }); * * sse.connect(); * * document.querySelector('#notifications') * .addEventListener('notification', (e: SSEDataEvent) => { * showNotification(e.data); * }); * * sse.disconnect(); * * @example * const sse = new SSEClient('/api/verdict', { * method: 'POST', * body: JSON.stringify({ matchId: 42 }), * eventTypes: ['token', 'verdict'], * terminalEvents: ['verdict'], * onClose: (client, result) => { * if (result.reason === 'truncated') { * showRetryButton(); * } * } * }); * * sse.connect(); */ export declare class SSEClient { private url; private options?; private eventSource?; private abortController?; private streaming; private target; /** * Whether the client is currently connected. */ get connected(): boolean; constructor(url: string, options?: SSEOptions | undefined); /** * Establish connection to the SSE endpoint. * * Can be called again after the stream has closed, which is how you retry a truncated result. */ connect(): void; /** * Close the connection. Closes with reason `aborted`. */ disconnect(): void; private usesFetchTransport; private connectViaEventSource; private connectViaFetch; private streamResponse; private bridgeSignal; private buildHeaders; private readErrorResponse; private reportFailure; private finish; private acceptsEvent; private resolveTarget; private dispatchEvent; }