better-sse 0.13.0 → 0.14.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2020 Matthew
3
+ Copyright (c) 2024 Matthew W.
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -27,20 +27,20 @@ Compared to WebSockets it has comparable performance and bandwidth usage, especi
27
27
 
28
28
  ## Highlights
29
29
 
30
- * Compatible with all popular Node HTTP frameworks ([http](https://nodejs.org/api/http.html), [Express](https://nodejs.org/api/http.html), [Koa](https://www.npmjs.com/package/koa), [Fastify](https://www.npmjs.com/package/fastify), etc.)
30
+ * Compatible with all popular Node HTTP frameworks ([Express](https://nodejs.org/api/http.html), [Fastify](https://fastify.dev/), [Nest](https://nestjs.com/), [Next.js](https://nextjs.org/), etc.)
31
31
  * Fully written in TypeScript (+ ships with types directly).
32
32
  * [Thoroughly tested](./src/Session.test.ts) (+ 100% code coverage!).
33
- * [Comprehensively documented](./docs) with guides and API documentation.
34
- * [Channels](./docs/channels.md) allow you to broadcast events to many clients at once.
33
+ * [Comprehensively documented](https://matthewwid.github.io/better-sse) with guides and API documentation.
34
+ * [Channels](https://matthewwid.github.io/better-sse/guides/channels) allow you to broadcast events to many clients at once.
35
35
  * Configurable reconnection time, message serialization and data sanitization (with good defaults).
36
36
  * Trust or ignore the client-given last event ID.
37
37
  * Automatically send keep-alive pings to keep connections open.
38
38
  * Add or override the response status code and headers.
39
- * Fine-grained control by either sending [individual fields](./docs/api.md#eventbuffer) of events or by sending [full events with simple helpers](./docs/api.md#sessionpush-data-unknown-eventname-string-eventid-string--this).
39
+ * Send [individual fields](https://matthewwid.github.io/better-sse/guides/batching#send-individual-event-fields) of events or send [full events with simple helpers](https://matthewwid.github.io/better-sse/reference/api/#sessionpush-data-unknown-eventname-string-eventid-string--this).
40
40
  * Pipe [streams](https://nodejs.org/api/stream.html#stream_readable_streams) and [iterables](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators) directly from the server to the client as a series of events.
41
41
  * Support for popular EventSource polyfills [`event-source-polyfill`](https://www.npmjs.com/package/event-source-polyfill) and [`eventsource-polyfill`](https://www.npmjs.com/package/eventsource-polyfill).
42
42
 
43
- [See a comparison with other Node SSE libraries in the documentation.](./docs/comparison.md)
43
+ [See a comparison with other Node SSE libraries in the documentation.](https://matthewwid.github.io/better-sse/reference/comparison)
44
44
 
45
45
  # Installation
46
46
 
@@ -61,11 +61,11 @@ _Better SSE ships with types built in. No need to install from DefinitelyTyped f
61
61
 
62
62
  The following example shows usage with [Express](http://expressjs.com/), but Better SSE works with any web-server framework that uses the underlying Node [HTTP module](https://nodejs.org/api/http.html).
63
63
 
64
- See the [Recipes](./docs/recipes.md) section of the documentation for use with other frameworks and libraries.
64
+ See the [Recipes](https://matthewwid.github.io/better-sse/reference/recipes/) section of the documentation for use with other frameworks and libraries.
65
65
 
66
66
  ---
67
67
 
68
- Use [sessions](./docs/api.md#session) to push events to clients:
68
+ Use [sessions](https://matthewwid.github.io/better-sse/reference/api/#sessionstate) to push events to clients:
69
69
 
70
70
  ```typescript
71
71
  // Server
@@ -83,13 +83,11 @@ app.get("/sse", async (req, res) => {
83
83
  const sse = new EventSource("/sse");
84
84
 
85
85
  sse.addEventListener("message", ({ data }) => {
86
- console.log(data);
86
+ console.log(JSON.parse(data));
87
87
  });
88
88
  ```
89
89
 
90
- ---
91
-
92
- Use [channels](./docs/channels.md) to send events to many clients at once:
90
+ Use [channels](https://matthewwid.github.io/better-sse/reference/api/#channelstate-sessionstate) to send events to many clients at once:
93
91
 
94
92
  ```typescript
95
93
  import { createSession, createChannel } from "better-sse";
@@ -105,9 +103,7 @@ app.get("/sse", async (req, res) => {
105
103
  });
106
104
  ```
107
105
 
108
- ---
109
-
110
- Loop over sync and async [iterables](./docs/api.md#sessioniterate-iterable-iterable--asynciterable-options-object--promisevoid) and send each value as an event:
106
+ Loop over sync and async [iterables](https://matthewwid.github.io/better-sse/reference/api/#sessioniterate-iterable-iterable--asynciterable-options-object--promisevoid) and send each value as an event:
111
107
 
112
108
  ```typescript
113
109
  const session = await createSession(req, res);
@@ -117,9 +113,7 @@ const list = [1, 2, 3];
117
113
  await session.iterate(list);
118
114
  ```
119
115
 
120
- ---
121
-
122
- Pipe [readable stream](#sessionstream-stream-readable-options-object--promiseboolean) data to the client as a stream of events:
116
+ Pipe [readable stream](https://matthewwid.github.io/better-sse/reference/api/#sessionstream-stream-readable-options-object--promiseboolean) data to the client as a stream of events:
123
117
 
124
118
  ```typescript
125
119
  const session = await createSession(req, res);
@@ -131,11 +125,11 @@ await session.stream(stream);
131
125
 
132
126
  ---
133
127
 
134
- Check the [API documentation](./docs/api.md) and [live examples](./examples) for information on getting more fine-tuned control over your data such as managing event IDs, data serialization, event filtering, dispatch controls and more!
128
+ Check the [API documentation](https://matthewwid.github.io/better-sse/reference/api) and [live examples](./examples) for information on getting more fine-tuned control over your data such as managing event IDs, data serialization, event filtering, dispatch controls and more!
135
129
 
136
130
  # Documentation
137
131
 
138
- API documentation, getting started guides and usage with other frameworks is [available on GitHub](./docs).
132
+ API documentation, getting started guides and usage with other frameworks is [available on the documentation website](https://matthewwid.github.io/better-sse/).
139
133
 
140
134
  # Contributing
141
135
 
@@ -0,0 +1,485 @@
1
+ import * as stream from 'stream';
2
+ import * as http from 'http';
3
+ import { OutgoingHttpHeaders, IncomingMessage, ServerResponse } from 'http';
4
+ import * as http2 from 'http2';
5
+ import { Http2ServerRequest, Http2ServerResponse } from 'http2';
6
+ import { EventEmitter } from 'events';
7
+
8
+ interface IterateOptions {
9
+ /**
10
+ * Event name/type to be emitted when iterable data is sent to the client.
11
+ *
12
+ * Defaults to `"iteration"`.
13
+ */
14
+ eventName?: string;
15
+ }
16
+
17
+ interface StreamOptions {
18
+ /**
19
+ * Event name/type to be emitted when stream data is sent to the client.
20
+ *
21
+ * Defaults to `"stream"`.
22
+ */
23
+ eventName?: string;
24
+ }
25
+
26
+ /**
27
+ * Serialize arbitrary data to a string that can be sent over the wire to the client.
28
+ */
29
+ interface SerializerFunction {
30
+ (data: unknown): string;
31
+ }
32
+
33
+ interface SanitizerFunction {
34
+ (text: string): string;
35
+ }
36
+
37
+ interface EventBufferOptions {
38
+ /**
39
+ * Serialize data to a string that can be written.
40
+ *
41
+ * Defaults to `JSON.stringify`.
42
+ */
43
+ serializer?: SerializerFunction;
44
+ /**
45
+ * Sanitize values so as to not prematurely dispatch events when writing fields whose text inadvertently contains newlines.
46
+ *
47
+ * By default, CR, LF and CRLF characters are replaced with a single LF character (`\n`) and then any trailing LF characters are stripped so as to prevent a blank line being written and accidentally dispatching the event before `.dispatch()` is called.
48
+ */
49
+ sanitizer?: SanitizerFunction;
50
+ }
51
+ /**
52
+ * An `EventBuffer` allows you to write raw spec-compliant SSE fields into a text buffer that can be sent directly over the wire.
53
+ */
54
+ declare class EventBuffer {
55
+ private buffer;
56
+ private serialize;
57
+ private sanitize;
58
+ constructor(options?: EventBufferOptions);
59
+ /**
60
+ * Write a line with a field key and value appended with a newline character.
61
+ */
62
+ private writeField;
63
+ /**
64
+ * Write an event name field (also referred to as the event "type" in the specification).
65
+ *
66
+ * @param type - Event name/type.
67
+ */
68
+ event(type: string): this;
69
+ /**
70
+ * Write arbitrary data into a data field.
71
+ *
72
+ * Data is serialized to a string using the given `serializer` function option or JSON stringification by default.
73
+ *
74
+ * @param data - Data to serialize and write.
75
+ */
76
+ data: (data: unknown) => this;
77
+ /**
78
+ * Write an event ID field.
79
+ *
80
+ * Defaults to an empty string if no argument is given.
81
+ *
82
+ * @param id - Identification string to write.
83
+ */
84
+ id: (id?: string) => this;
85
+ /**
86
+ * Write a retry field that suggests a reconnection time with the given milliseconds.
87
+ *
88
+ * @param time - Time in milliseconds to retry.
89
+ */
90
+ retry: (time: number) => this;
91
+ /**
92
+ * Write a comment (an ignored field).
93
+ *
94
+ * This will not fire an event but is often used to keep the connection alive.
95
+ *
96
+ * @param text - Text of the comment. Otherwise writes an empty field value.
97
+ */
98
+ comment: (text?: string) => this;
99
+ /**
100
+ * Indicate that the event has finished being created by writing an additional newline character.
101
+ */
102
+ dispatch: () => this;
103
+ /**
104
+ * Create, write and dispatch an event with the given data all at once.
105
+ *
106
+ * This is equivalent to calling the methods `event`, `id`, `data` and `dispatch` in that order.
107
+ *
108
+ * If no event name is given, the event name is set to `"message"`.
109
+ *
110
+ * If no event ID is given, the event ID is set to a unique string generated using a cryptographic pseudorandom number generator.
111
+ *
112
+ * @param data - Data to write.
113
+ * @param eventName - Event name to write.
114
+ * @param eventId - Event ID to write.
115
+ */
116
+ push: (data: unknown, eventName?: string, eventId?: string) => this;
117
+ /**
118
+ * Pipe readable stream data as a series of events into the buffer.
119
+ *
120
+ * This uses the `push` method under the hood.
121
+ *
122
+ * If no event name is given in the `options` object, the event name is set to `"stream"`.
123
+ *
124
+ * @param stream - Readable stream to consume data from.
125
+ * @param options - Event name to use for each event created.
126
+ *
127
+ * @returns A promise that resolves or rejects based on the success of the stream write finishing.
128
+ */
129
+ stream: (stream: stream.Readable, options?: StreamOptions) => Promise<boolean>;
130
+ /**
131
+ * Iterate over an iterable and write yielded values as events into the buffer.
132
+ *
133
+ * This uses the `push` method under the hood.
134
+ *
135
+ * If no event name is given in the `options` object, the event name is set to `"iteration"`.
136
+ *
137
+ * @param iterable - Iterable to consume data from.
138
+ *
139
+ * @returns A promise that resolves once all data has been successfully yielded from the iterable.
140
+ */
141
+ iterate: <DataType = unknown>(iterable: Iterable<DataType> | AsyncIterable<DataType>, options?: IterateOptions) => Promise<void>;
142
+ /**
143
+ * Clear the contents of the buffer.
144
+ */
145
+ clear: () => this;
146
+ /**
147
+ * Get a copy of the buffer contents.
148
+ */
149
+ read: () => string;
150
+ }
151
+
152
+ interface EventMap {
153
+ [name: string | symbol]: (...args: any[]) => void;
154
+ }
155
+ /**
156
+ * Get event names type
157
+ */
158
+ type EventNames<T> = keyof {
159
+ [K in keyof T as string extends K ? never : number extends K ? never : K]: never;
160
+ } | (string & {});
161
+ /**
162
+ * Wraps the EventEmitter class to add types that map event names
163
+ * to types of arguments in the event handler callback.
164
+ */
165
+ declare class TypedEmitter<Events extends EventMap> extends EventEmitter {
166
+ addListener<EventName extends EventNames<Events>>(event: EventName, listener: Events[EventName]): this;
167
+ prependListener<EventName extends EventNames<Events>>(event: EventName, listener: Events[EventName]): this;
168
+ prependOnceListener<EventName extends EventNames<Events>>(event: EventName, listener: Events[EventName]): this;
169
+ on<EventName extends EventNames<Events>>(event: EventName, listener: Events[EventName]): this;
170
+ once<EventName extends EventNames<Events>>(event: EventName, listener: Events[EventName]): this;
171
+ emit<EventName extends EventNames<Events>>(event: EventName, ...args: Parameters<Events[EventName]>): boolean;
172
+ off<EventName extends EventNames<Events>>(event: EventName, listener: Events[EventName]): this;
173
+ removeListener<EventName extends EventNames<Events>>(event: EventName, listener: Events[EventName]): this;
174
+ }
175
+
176
+ interface SessionOptions<State = DefaultSessionState> extends Pick<EventBufferOptions, "serializer" | "sanitizer"> {
177
+ /**
178
+ * Whether to trust or ignore the last event ID given by the client in the `Last-Event-ID` request header.
179
+ *
180
+ * When set to `false`, the `lastId` property will always be initialized to an empty string.
181
+ *
182
+ * Defaults to `true`.
183
+ */
184
+ trustClientEventId?: boolean;
185
+ /**
186
+ * Time in milliseconds for the client to wait before attempting to reconnect if the connection is closed.
187
+ *
188
+ * This is a request to the client browser, and does not guarantee that the client will actually respect the given time.
189
+ *
190
+ * Equivalent to immediately calling `.retry().dispatch().flush()` after a connection is made.
191
+ *
192
+ * Give as `null` to avoid sending an explicit reconnection time and allow the client browser to decide itself.
193
+ *
194
+ * Defaults to `2000` milliseconds.
195
+ *
196
+ * @see https://html.spec.whatwg.org/multipage/server-sent-events.html#concept-event-stream-reconnection-time
197
+ */
198
+ retry?: number | null;
199
+ /**
200
+ * Time in milliseconds interval for the session to send a comment to keep the connection alive.
201
+ *
202
+ * Give as `null` to disable the connection keep-alive mechanism.
203
+ *
204
+ * Defaults to `10000` milliseconds (`10` seconds).
205
+ */
206
+ keepAlive?: number | null;
207
+ /**
208
+ * Status code to be sent to the client.
209
+ *
210
+ * Event stream requests can be redirected using HTTP 301 and 307 status codes.
211
+ * Make sure to set `Location` header when using these status codes using the `headers` property.
212
+ *
213
+ * A client can be asked to stop reconnecting by using 204 status code.
214
+ *
215
+ * Defaults to `200`.
216
+ */
217
+ statusCode?: number;
218
+ /**
219
+ * Additional headers to be sent along with the response.
220
+ */
221
+ headers?: OutgoingHttpHeaders;
222
+ /**
223
+ * Custom state for this session.
224
+ *
225
+ * Use this object to safely store information related to the session and user.
226
+ */
227
+ state?: State;
228
+ }
229
+ interface DefaultSessionState {
230
+ [key: string]: unknown;
231
+ }
232
+ interface SessionEvents extends EventMap {
233
+ connected: () => void;
234
+ disconnected: () => void;
235
+ push: (data: unknown, eventName: string, eventId: string) => void;
236
+ }
237
+ /**
238
+ * A `Session` represents an open connection between the server and a client.
239
+ *
240
+ * It extends from the {@link https://nodejs.org/api/events.html#events_class_eventemitter | EventEmitter} class.
241
+ *
242
+ * It emits the `connected` event after it has connected and sent all headers to the client, and the
243
+ * `disconnected` event after the connection has been closed.
244
+ *
245
+ * Note that creating a new session will immediately send the initial status code and headers to the client.
246
+ * Attempting to write additional headers after you have created a new session will result in an error.
247
+ *
248
+ * @param req - The Node HTTP {@link https://nodejs.org/api/http.html#http_class_http_incomingmessage | ServerResponse} object.
249
+ * @param res - The Node HTTP {@link https://nodejs.org/api/http.html#http_class_http_serverresponse | IncomingMessage} object.
250
+ * @param options - Options given to the session instance.
251
+ */
252
+ declare class Session<State = DefaultSessionState> extends TypedEmitter<SessionEvents> {
253
+ /**
254
+ * The last event ID sent to the client.
255
+ *
256
+ * This is initialized to the last event ID given by the user, and otherwise is equal to the last number given to the `.id` method.
257
+ *
258
+ * For security reasons, keep in mind that the client can provide *any* initial ID here. Use the `trustClientEventId` constructor option to ignore the client-given initial ID.
259
+ *
260
+ * @readonly
261
+ */
262
+ lastId: string;
263
+ /**
264
+ * Indicates whether the session and underlying connection is open or not.
265
+ *
266
+ * @readonly
267
+ */
268
+ isConnected: boolean;
269
+ /**
270
+ * Custom state for this session.
271
+ *
272
+ * Use this object to safely store information related to the session and user.
273
+ *
274
+ * Use [module augmentation and declaration merging](https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation)
275
+ * to safely add new properties to the `DefaultSessionState` interface.
276
+ */
277
+ state: State;
278
+ private buffer;
279
+ /**
280
+ * Raw HTTP request.
281
+ */
282
+ private req;
283
+ /**
284
+ * Raw HTTP response that is the minimal interface needed and forms the
285
+ * intersection between the HTTP/1.1 and HTTP/2 server response interfaces.
286
+ */
287
+ private res;
288
+ private serialize;
289
+ private sanitize;
290
+ private trustClientEventId;
291
+ private initialRetry;
292
+ private keepAliveInterval;
293
+ private keepAliveTimer?;
294
+ private statusCode;
295
+ private headers;
296
+ constructor(req: IncomingMessage | Http2ServerRequest, res: ServerResponse | Http2ServerResponse, options?: SessionOptions<State>);
297
+ private initialize;
298
+ private onDisconnected;
299
+ private keepAlive;
300
+ /**
301
+ * @deprecated see https://github.com/MatthewWid/better-sse/issues/52
302
+ */
303
+ event(type: string): this;
304
+ /**
305
+ * @deprecated see https://github.com/MatthewWid/better-sse/issues/52
306
+ */
307
+ data: (data: unknown) => this;
308
+ /**
309
+ * @deprecated see https://github.com/MatthewWid/better-sse/issues/52
310
+ */
311
+ id: (id?: string) => this;
312
+ /**
313
+ * @deprecated see https://github.com/MatthewWid/better-sse/issues/52
314
+ */
315
+ retry: (time: number) => this;
316
+ /**
317
+ * @deprecated see https://github.com/MatthewWid/better-sse/issues/52
318
+ */
319
+ comment: (text?: string) => this;
320
+ /**
321
+ * @deprecated see https://github.com/MatthewWid/better-sse/issues/52
322
+ */
323
+ dispatch: () => this;
324
+ /**
325
+ * Flush the contents of the internal buffer to the client and clear the buffer.
326
+ *
327
+ * @deprecated see https://github.com/MatthewWid/better-sse/issues/52
328
+ */
329
+ flush: () => this;
330
+ /**
331
+ * Push an event to the client.
332
+ *
333
+ * If no event name is given, the event name is set to `"message"`.
334
+ *
335
+ * If no event ID is given, the event ID (and thus the `lastId` property) is set to a unique string generated using a cryptographic pseudorandom number generator.
336
+ *
337
+ * Emits the `push` event with the given data, event name and event ID in that order.
338
+ *
339
+ * @param data - Data to write.
340
+ * @param eventName - Event name to write.
341
+ * @param eventId - Event ID to write.
342
+ */
343
+ push: (data: unknown, eventName?: string, eventId?: string) => this;
344
+ /**
345
+ * Pipe readable stream data as a series of events to the client.
346
+ *
347
+ * This uses the `push` method under the hood.
348
+ *
349
+ * If no event name is given in the `options` object, the event name is set to `"stream"`.
350
+ *
351
+ * @param stream - Readable stream to consume data from.
352
+ * @param options - Options to alter how the stream is flushed to the client.
353
+ *
354
+ * @returns A promise that resolves or rejects based on the success of the stream write finishing.
355
+ */
356
+ stream: (stream: stream.Readable, options?: StreamOptions) => Promise<boolean>;
357
+ /**
358
+ * Iterate over an iterable and send yielded values as events to the client.
359
+ *
360
+ * This uses the `push` method under the hood.
361
+ *
362
+ * If no event name is given in the `options` object, the event name is set to `"iteration"`.
363
+ *
364
+ * @param iterable - Iterable to consume data from.
365
+ *
366
+ * @returns A promise that resolves once all data has been successfully yielded from the iterable.
367
+ */
368
+ iterate: <DataType = unknown>(iterable: Iterable<DataType> | AsyncIterable<DataType>, options?: IterateOptions) => Promise<void>;
369
+ /**
370
+ * Batch and send multiple events at once.
371
+ *
372
+ * If given an `EventBuffer` instance, its contents will be sent to the client.
373
+ *
374
+ * If given a callback, it will be passed an instance of `EventBuffer` which uses the same serializer and sanitizer as the session.
375
+ * Once its execution completes - or once it resolves if it returns a promise - the contents of the passed `EventBuffer` will be sent to the client.
376
+ *
377
+ * @param batcher - Event buffer to get contents from, or callback that takes an event buffer to write to.
378
+ *
379
+ * @returns A promise that resolves once all data from the event buffer has been successfully sent to the client.
380
+ *
381
+ * @see EventBuffer
382
+ */
383
+ batch: (batcher: EventBuffer | ((buffer: EventBuffer) => void | Promise<void>)) => Promise<void>;
384
+ }
385
+
386
+ /**
387
+ * Create a new session and return the session instance once it has connected.
388
+ */
389
+ declare const createSession: <State = DefaultSessionState>(req: http.IncomingMessage | http2.Http2ServerRequest, res: http.ServerResponse<http.IncomingMessage> | http2.Http2ServerResponse<http2.Http2ServerRequest>, options?: SessionOptions<State> | undefined) => Promise<Session<State>>;
390
+
391
+ interface ChannelOptions<State = DefaultChannelState> {
392
+ /**
393
+ * Custom state for this channel.
394
+ *
395
+ * Use this object to safely store information related to the channel.
396
+ */
397
+ state?: State;
398
+ }
399
+ interface BroadcastOptions<SessionState = DefaultSessionState> {
400
+ /**
401
+ * Unique ID for the event being broadcast.
402
+ *
403
+ * If no event ID is given, the event ID is set to a unique string generated using a cryptographic pseudorandom number generator.
404
+ */
405
+ eventId?: string;
406
+ /**
407
+ * Filter sessions that should receive the event.
408
+ *
409
+ * Called with each session and should return `true` to allow the event to be sent and otherwise return `false` to prevent the session from receiving the event.
410
+ */
411
+ filter?: (session: Session<SessionState>) => boolean;
412
+ }
413
+ interface ChannelEvents<SessionState = DefaultSessionState> extends EventMap {
414
+ "session-registered": (session: Session<SessionState>) => void;
415
+ "session-deregistered": (session: Session<SessionState>) => void;
416
+ "session-disconnected": (session: Session<SessionState>) => void;
417
+ broadcast: (data: unknown, eventName: string, eventId: string) => void;
418
+ }
419
+ interface DefaultChannelState {
420
+ [key: string]: unknown;
421
+ }
422
+ /**
423
+ * A `Channel` is used to broadcast events to many sessions at once.
424
+ *
425
+ * It extends from the {@link https://nodejs.org/api/events.html#events_class_eventemitter | EventEmitter} class.
426
+ *
427
+ * You may use the second generic argument `SessionState` to enforce that only sessions with the same state type may be registered with this channel.
428
+ */
429
+ declare class Channel<State = DefaultChannelState, SessionState = DefaultSessionState> extends TypedEmitter<ChannelEvents<SessionState>> {
430
+ /**
431
+ * Custom state for this channel.
432
+ *
433
+ * Use this object to safely store information related to the channel.
434
+ */
435
+ state: State;
436
+ private sessions;
437
+ constructor(options?: ChannelOptions<State>);
438
+ /**
439
+ * List of the currently active sessions subscribed to this channel.
440
+ */
441
+ get activeSessions(): ReadonlyArray<Session<SessionState>>;
442
+ /**
443
+ * Number of sessions subscribed to this channel.
444
+ */
445
+ get sessionCount(): number;
446
+ /**
447
+ * Register a session so that it can start receiving events from this channel.
448
+ *
449
+ * If the session was already registered to begin with this method does nothing.
450
+ *
451
+ * @param session - Session to register.
452
+ */
453
+ register(session: Session<SessionState>): this;
454
+ /**
455
+ * Deregister a session so that it no longer receives events from this channel.
456
+ *
457
+ * If the session was not registered to begin with this method does nothing.
458
+ *
459
+ * @param session - Session to deregister.
460
+ */
461
+ deregister(session: Session<SessionState>): this;
462
+ /**
463
+ * Broadcast an event to every active session registered with this channel.
464
+ *
465
+ * Under the hood this calls the `push` method on every active session.
466
+ *
467
+ * If no event name is given, the event name is set to `"message"`.
468
+ *
469
+ * Note that the broadcasted event will have the same ID across all receiving sessions instead of generating a unique ID for each.
470
+ *
471
+ * @param data - Data to write.
472
+ * @param eventName - Event name to write.
473
+ */
474
+ broadcast: (data: unknown, eventName?: string, options?: BroadcastOptions<SessionState>) => this;
475
+ }
476
+
477
+ declare const createChannel: <State = DefaultChannelState, SessionState = DefaultSessionState>(options?: ChannelOptions<State> | undefined) => Channel<State, SessionState>;
478
+
479
+ declare const createEventBuffer: (options?: EventBufferOptions | undefined) => EventBuffer;
480
+
481
+ declare class SseError extends Error {
482
+ constructor(message: string);
483
+ }
484
+
485
+ export { type BroadcastOptions, Channel, type ChannelEvents, type ChannelOptions, type DefaultChannelState, type DefaultSessionState, EventBuffer, type EventBufferOptions, type IterateOptions, Session, type SessionEvents, type SessionOptions, SseError, type StreamOptions, createChannel, createEventBuffer, createSession };