@afterrealism/dendri-client 2.3.7

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.
@@ -0,0 +1,340 @@
1
+ import * as BinaryPack from 'peerjs-js-binarypack';
2
+ import { D as Dendri, S as SerializerMapping, a as DataConnection, b as SignalingTransport } from './store-RTivRmUW.cjs';
3
+ export { A as AckManager, c as AnswerOption, B as BaseConnectionErrorType, C as CallOption, d as ConnectionQuality, e as ConnectionState, f as ConnectionType, g as DataConnectionErrorType, h as DendriConnectOption, i as DendriError, j as DendriErrorType, k as DendriEvents, l as DendriOption, m as DendriOptions, n as DendriStore, o as DendriStoreOptions, p as DendriStoreSnapshot, H as HybridConnection, q as HybridConnectionOption, r as HybridSendOptions, L as LogLevel, M as MediaConnection, P as PresenceEvents, s as PresenceManager, R as Room, t as RoomEvents, u as RoomOptions, v as RpcError, w as RpcErrorCode, x as RpcHandler, y as RpcManager, z as RpcRequest, E as RpcResponse, F as SerializationType, G as ServerMessageType, I as SocketEventType, J as StoreListener, T as TransportEvents, K as TransportMode, N as createDendriStore, O as isRpcRequest, Q as isRpcResponse } from './store-RTivRmUW.cjs';
4
+ import 'eventemitter3';
5
+
6
+ declare class BinaryPackChunker {
7
+ readonly chunkedMTU = 16300;
8
+ private _dataCount;
9
+ chunk: (blob: ArrayBuffer) => {
10
+ __peerData: number;
11
+ n: number;
12
+ total: number;
13
+ data: ArrayBuffer;
14
+ }[];
15
+ }
16
+
17
+ interface UtilSupportsObj {
18
+ /**
19
+ * The current browser.
20
+ * This property can be useful in determining whether two peers can connect.
21
+ *
22
+ * ```ts
23
+ * if (util.browser === 'firefox') {
24
+ * // OK to peer with Firefox peers.
25
+ * }
26
+ * ```
27
+ *
28
+ * `util.browser` can currently have the values
29
+ * `'firefox', 'chrome', 'safari', 'edge', 'Not a supported browser.', 'Not a browser.' (unknown WebRTC-compatible agent).
30
+ */
31
+ browser: boolean;
32
+ webRTC: boolean;
33
+ /**
34
+ * True if the current browser supports media streams and PeerConnection.
35
+ */
36
+ audioVideo: boolean;
37
+ /**
38
+ * True if the current browser supports DataChannel and PeerConnection.
39
+ */
40
+ data: boolean;
41
+ binaryBlob: boolean;
42
+ /**
43
+ * True if the current browser supports reliable DataChannels.
44
+ */
45
+ reliable: boolean;
46
+ }
47
+ declare class Util extends BinaryPackChunker {
48
+ noop(): void;
49
+ readonly CLOUD_HOST = "signal.dendri.dev";
50
+ readonly CLOUD_PORT = 443;
51
+ readonly chunkedBrowsers: {
52
+ Chrome: number;
53
+ chrome: number;
54
+ };
55
+ readonly defaultConfig: RTCConfiguration;
56
+ readonly browser: string;
57
+ readonly browserVersion: number;
58
+ get isSafari(): boolean;
59
+ get isIOS(): boolean;
60
+ pack: typeof BinaryPack.pack;
61
+ unpack: typeof BinaryPack.unpack;
62
+ /**
63
+ * A hash of WebRTC features mapped to booleans that correspond to whether the feature is supported by the current browser.
64
+ *
65
+ * :::caution
66
+ * Only the properties documented here are guaranteed to be present on `util.supports`
67
+ * :::
68
+ */
69
+ readonly supports: UtilSupportsObj;
70
+ validateId: (id: string) => boolean;
71
+ randomToken: () => string;
72
+ blobToArrayBuffer(blob: Blob, cb: (arg: ArrayBuffer | null) => void): FileReader;
73
+ binaryStringToArrayBuffer(binary: string): ArrayBuffer | SharedArrayBuffer;
74
+ isSecure(): boolean;
75
+ }
76
+ /**
77
+ * Provides a variety of helpful utilities.
78
+ *
79
+ * :::caution
80
+ * Only the utilities documented here are guaranteed to be present on `util`.
81
+ * Undocumented utilities can be removed without warning.
82
+ * We don't consider these to be breaking changes.
83
+ * :::
84
+ */
85
+ declare const util: Util;
86
+
87
+ /**
88
+ * @experimental
89
+ */
90
+ declare class MsgPackDendri extends Dendri {
91
+ _serializers: SerializerMapping;
92
+ }
93
+
94
+ declare abstract class BufferedConnection extends DataConnection {
95
+ private _buffer;
96
+ private _bufferSize;
97
+ private _buffering;
98
+ private _bufferTimer;
99
+ private _messageHandler;
100
+ get bufferSize(): number;
101
+ _initializeDataChannel(dc: RTCDataChannel): void;
102
+ protected abstract _handleDataMessage(e: MessageEvent): void;
103
+ protected _bufferedSend(msg: ArrayBuffer): void;
104
+ private _trySend;
105
+ private _tryBuffer;
106
+ close(options?: {
107
+ flush?: boolean;
108
+ }): void;
109
+ }
110
+
111
+ declare abstract class StreamConnection extends DataConnection {
112
+ private _CHUNK_SIZE;
113
+ private _splitStream;
114
+ private _rawSendStream;
115
+ protected writer: WritableStreamDefaultWriter<Uint8Array<ArrayBufferLike>>;
116
+ private _readStreamMessageHandler;
117
+ private _readStreamController;
118
+ protected _rawReadStream: ReadableStream<ArrayBuffer>;
119
+ protected constructor(peerId: string, provider: Dendri, options: any);
120
+ _initializeDataChannel(dc: RTCDataChannel): void;
121
+ close(options?: {
122
+ flush?: boolean;
123
+ }): void;
124
+ }
125
+
126
+ declare class MsgPack extends StreamConnection {
127
+ readonly serialization = "MsgPack";
128
+ private _encoder;
129
+ constructor(peerId: string, provider: Dendri, options: any);
130
+ protected _send(data: unknown): Promise<void>;
131
+ }
132
+
133
+ /**
134
+ * E2E encryption for relay messages using ECDH + AES-256-GCM.
135
+ * Uses the Web Crypto API -- available in all modern browsers and Node.js 18+.
136
+ */
137
+ /** Encrypted payload structure sent over the relay. */
138
+ interface EncryptedPayload {
139
+ readonly iv: string;
140
+ readonly ciphertext: string;
141
+ }
142
+ declare class RelayEncryption {
143
+ private _keyPair;
144
+ private _sharedKey;
145
+ private _ready;
146
+ get ready(): boolean;
147
+ /** Generate ECDH key pair and return the public key as JWK. */
148
+ generateKeyPair(): Promise<JsonWebKey>;
149
+ /** Derive shared AES-256-GCM key from remote peer's public key. */
150
+ deriveSharedKey(remotePublicKeyJwk: JsonWebKey): Promise<void>;
151
+ /** Encrypt a message for relay. */
152
+ encrypt(data: string): Promise<EncryptedPayload>;
153
+ /** Decrypt a message from relay. */
154
+ decrypt(encrypted: EncryptedPayload): Promise<string>;
155
+ /** Reset encryption state. */
156
+ clear(): void;
157
+ }
158
+
159
+ /**
160
+ * Host migration utilities for star topology rooms.
161
+ *
162
+ * When the host disconnects, the peer with the lowest alphabetical ID
163
+ * among all remaining peers becomes the new host. This is deterministic:
164
+ * every peer arrives at the same answer independently.
165
+ */
166
+ interface HostMigrationOptions {
167
+ readonly roomId: string;
168
+ readonly myPeerId: string;
169
+ readonly knownPeers: readonly string[];
170
+ readonly onBecomeHost: () => void;
171
+ readonly onNewHost: (hostId: string) => void;
172
+ readonly migrationTimeout?: number;
173
+ }
174
+ /**
175
+ * Elect a new host from the given set of peer IDs.
176
+ * Deterministic: the lowest alphabetical ID always wins.
177
+ *
178
+ * @param myPeerId - The local peer's ID.
179
+ * @param peerIds - All other known peer IDs (excluding the departed host).
180
+ * @returns The peer ID that should become the new host.
181
+ */
182
+ declare function electNewHost(myPeerId: string, peerIds: readonly string[]): string;
183
+
184
+ /**
185
+ * HTTP Long Polling transport — works through any network that allows HTTPS.
186
+ * Client->Server: POST
187
+ * Server->Client: GET (held open until data available or timeout)
188
+ */
189
+ declare class PollingTransport extends SignalingTransport {
190
+ private _connected;
191
+ private _disconnected;
192
+ private _id?;
193
+ private _token?;
194
+ private _messagesQueue;
195
+ private _polling;
196
+ private _autoReconnect;
197
+ private _reconnectAttempt;
198
+ private _reconnectTimer?;
199
+ private _heartbeatTimer?;
200
+ private _lastSeq;
201
+ private _baseUrl;
202
+ private readonly _pingInterval;
203
+ private _abortController?;
204
+ /** Backoff schedule base delays in milliseconds. */
205
+ private static readonly BACKOFF_SCHEDULE;
206
+ /** Random jitter range in milliseconds (applied as +/-). */
207
+ private static readonly BACKOFF_JITTER;
208
+ constructor(secure: boolean, host: string, port: number, path: string, _key: string, pingInterval?: number, _jwt?: string);
209
+ get reconnectAttempt(): number;
210
+ start(id: string, token: string): void;
211
+ private _startPolling;
212
+ send(data: any): void;
213
+ private _postMessage;
214
+ close(): void;
215
+ /** Compute the backoff delay (with jitter) for the current attempt. */
216
+ private _getReconnectDelay;
217
+ private _scheduleReconnect;
218
+ private _startHeartbeat;
219
+ private _sendQueuedMessages;
220
+ private _cleanup;
221
+ }
222
+
223
+ /**
224
+ * Server-side API client for dendri signal server.
225
+ * Use this from your backend to manage peers and rooms programmatically.
226
+ */
227
+ declare class DendriServerAPI {
228
+ private readonly _baseUrl;
229
+ private readonly _key;
230
+ constructor(options: {
231
+ url: string;
232
+ key?: string;
233
+ });
234
+ /** Get server health and stats */
235
+ getHealth(): Promise<{
236
+ status: string;
237
+ clients: number;
238
+ rooms: number;
239
+ uptime_ms: number;
240
+ relay_enabled: boolean;
241
+ }>;
242
+ /** List all connected peer IDs */
243
+ listPeers(room?: string): Promise<string[]>;
244
+ /** Generate a new peer ID */
245
+ generatePeerId(): Promise<string>;
246
+ /** Get TURN credentials */
247
+ getTurnCredentials(): Promise<{
248
+ iceServers: RTCIceServer[];
249
+ }>;
250
+ /** Get analytics metadata */
251
+ getAnalytics(): Promise<{
252
+ dataset: string;
253
+ events_tracked: string[];
254
+ }>;
255
+ }
256
+
257
+ /**
258
+ * SSE + POST transport for environments where WebSocket is blocked.
259
+ * Server->Client: Server-Sent Events (fetch-based, supports custom headers)
260
+ * Client->Server: HTTP POST requests
261
+ */
262
+ declare class SSETransport extends SignalingTransport {
263
+ private _connected;
264
+ private _disconnected;
265
+ private _id?;
266
+ private _token?;
267
+ private _messagesQueue;
268
+ private _abortController?;
269
+ private _autoReconnect;
270
+ private _reconnectAttempt;
271
+ private _reconnectTimer?;
272
+ private _heartbeatTimer?;
273
+ private _lastSeq;
274
+ private _baseUrl;
275
+ private _jwt?;
276
+ private readonly _pingInterval;
277
+ /** Backoff schedule base delays in milliseconds. */
278
+ private static readonly BACKOFF_SCHEDULE;
279
+ /** Random jitter range in milliseconds (applied as +/-). */
280
+ private static readonly BACKOFF_JITTER;
281
+ constructor(secure: boolean, host: string, port: number, path: string, _key: string, pingInterval?: number, jwt?: string);
282
+ get reconnectAttempt(): number;
283
+ start(id: string, token: string): void;
284
+ private _connectSSE;
285
+ send(data: any): void;
286
+ private _postMessage;
287
+ close(): void;
288
+ private _handleDisconnect;
289
+ /** Compute the backoff delay (with jitter) for the current attempt. */
290
+ private _getReconnectDelay;
291
+ private _scheduleReconnect;
292
+ private _startHeartbeat;
293
+ private _sendQueuedMessages;
294
+ private _cleanup;
295
+ }
296
+
297
+ /**
298
+ * Callback signature for topic message handlers.
299
+ * @param data The payload received on this topic.
300
+ * @param peerId The ID of the peer that sent the message.
301
+ */
302
+ type TopicHandler = (data: unknown, peerId: string) => void;
303
+ /**
304
+ * Marker interface for messages that carry topic metadata.
305
+ * When a topic is specified the original payload is wrapped in this envelope
306
+ * so the receiver can extract and route it.
307
+ */
308
+ interface TopicEnvelope {
309
+ readonly __topic: string;
310
+ readonly __data: unknown;
311
+ /** If true, `__data` is base64-encoded bytes — receivers must decode before use. */
312
+ readonly __binary?: boolean;
313
+ }
314
+ /** Type-guard: does `value` look like a topic-wrapped envelope? */
315
+ declare function isTopicEnvelope(value: unknown): value is TopicEnvelope;
316
+ /**
317
+ * Manages per-topic subscriptions and dispatches incoming messages
318
+ * to the matching handlers.
319
+ *
320
+ * Designed for use inside Room and HybridConnection so that
321
+ * callers can filter messages by topic without manual switching logic.
322
+ */
323
+ declare class TopicManager {
324
+ private readonly _handlers;
325
+ private readonly _globalHandlers;
326
+ /** Subscribe to a specific topic. Returns an unsubscribe function. */
327
+ subscribe(topic: string, handler: TopicHandler): () => void;
328
+ /** Subscribe to ALL topics (including un-topiced messages). Returns an unsubscribe function. */
329
+ subscribeAll(handler: TopicHandler): () => void;
330
+ /**
331
+ * Dispatch a message to the appropriate handlers.
332
+ *
333
+ * @returns `true` if at least one handler was invoked, `false` otherwise.
334
+ */
335
+ dispatch(topic: string | undefined, data: unknown, peerId: string): boolean;
336
+ /** Remove all subscriptions. */
337
+ clear(): void;
338
+ }
339
+
340
+ export { BufferedConnection, DataConnection, Dendri, DendriServerAPI, type EncryptedPayload, type HostMigrationOptions, MsgPack, MsgPackDendri, PollingTransport, RelayEncryption, SSETransport, SerializerMapping, SignalingTransport, StreamConnection, type TopicEnvelope, type TopicHandler, TopicManager, Util, type UtilSupportsObj, Dendri as default, electNewHost, isTopicEnvelope, util };
@@ -0,0 +1,340 @@
1
+ import * as BinaryPack from 'peerjs-js-binarypack';
2
+ import { D as Dendri, S as SerializerMapping, a as DataConnection, b as SignalingTransport } from './store-RTivRmUW.js';
3
+ export { A as AckManager, c as AnswerOption, B as BaseConnectionErrorType, C as CallOption, d as ConnectionQuality, e as ConnectionState, f as ConnectionType, g as DataConnectionErrorType, h as DendriConnectOption, i as DendriError, j as DendriErrorType, k as DendriEvents, l as DendriOption, m as DendriOptions, n as DendriStore, o as DendriStoreOptions, p as DendriStoreSnapshot, H as HybridConnection, q as HybridConnectionOption, r as HybridSendOptions, L as LogLevel, M as MediaConnection, P as PresenceEvents, s as PresenceManager, R as Room, t as RoomEvents, u as RoomOptions, v as RpcError, w as RpcErrorCode, x as RpcHandler, y as RpcManager, z as RpcRequest, E as RpcResponse, F as SerializationType, G as ServerMessageType, I as SocketEventType, J as StoreListener, T as TransportEvents, K as TransportMode, N as createDendriStore, O as isRpcRequest, Q as isRpcResponse } from './store-RTivRmUW.js';
4
+ import 'eventemitter3';
5
+
6
+ declare class BinaryPackChunker {
7
+ readonly chunkedMTU = 16300;
8
+ private _dataCount;
9
+ chunk: (blob: ArrayBuffer) => {
10
+ __peerData: number;
11
+ n: number;
12
+ total: number;
13
+ data: ArrayBuffer;
14
+ }[];
15
+ }
16
+
17
+ interface UtilSupportsObj {
18
+ /**
19
+ * The current browser.
20
+ * This property can be useful in determining whether two peers can connect.
21
+ *
22
+ * ```ts
23
+ * if (util.browser === 'firefox') {
24
+ * // OK to peer with Firefox peers.
25
+ * }
26
+ * ```
27
+ *
28
+ * `util.browser` can currently have the values
29
+ * `'firefox', 'chrome', 'safari', 'edge', 'Not a supported browser.', 'Not a browser.' (unknown WebRTC-compatible agent).
30
+ */
31
+ browser: boolean;
32
+ webRTC: boolean;
33
+ /**
34
+ * True if the current browser supports media streams and PeerConnection.
35
+ */
36
+ audioVideo: boolean;
37
+ /**
38
+ * True if the current browser supports DataChannel and PeerConnection.
39
+ */
40
+ data: boolean;
41
+ binaryBlob: boolean;
42
+ /**
43
+ * True if the current browser supports reliable DataChannels.
44
+ */
45
+ reliable: boolean;
46
+ }
47
+ declare class Util extends BinaryPackChunker {
48
+ noop(): void;
49
+ readonly CLOUD_HOST = "signal.dendri.dev";
50
+ readonly CLOUD_PORT = 443;
51
+ readonly chunkedBrowsers: {
52
+ Chrome: number;
53
+ chrome: number;
54
+ };
55
+ readonly defaultConfig: RTCConfiguration;
56
+ readonly browser: string;
57
+ readonly browserVersion: number;
58
+ get isSafari(): boolean;
59
+ get isIOS(): boolean;
60
+ pack: typeof BinaryPack.pack;
61
+ unpack: typeof BinaryPack.unpack;
62
+ /**
63
+ * A hash of WebRTC features mapped to booleans that correspond to whether the feature is supported by the current browser.
64
+ *
65
+ * :::caution
66
+ * Only the properties documented here are guaranteed to be present on `util.supports`
67
+ * :::
68
+ */
69
+ readonly supports: UtilSupportsObj;
70
+ validateId: (id: string) => boolean;
71
+ randomToken: () => string;
72
+ blobToArrayBuffer(blob: Blob, cb: (arg: ArrayBuffer | null) => void): FileReader;
73
+ binaryStringToArrayBuffer(binary: string): ArrayBuffer | SharedArrayBuffer;
74
+ isSecure(): boolean;
75
+ }
76
+ /**
77
+ * Provides a variety of helpful utilities.
78
+ *
79
+ * :::caution
80
+ * Only the utilities documented here are guaranteed to be present on `util`.
81
+ * Undocumented utilities can be removed without warning.
82
+ * We don't consider these to be breaking changes.
83
+ * :::
84
+ */
85
+ declare const util: Util;
86
+
87
+ /**
88
+ * @experimental
89
+ */
90
+ declare class MsgPackDendri extends Dendri {
91
+ _serializers: SerializerMapping;
92
+ }
93
+
94
+ declare abstract class BufferedConnection extends DataConnection {
95
+ private _buffer;
96
+ private _bufferSize;
97
+ private _buffering;
98
+ private _bufferTimer;
99
+ private _messageHandler;
100
+ get bufferSize(): number;
101
+ _initializeDataChannel(dc: RTCDataChannel): void;
102
+ protected abstract _handleDataMessage(e: MessageEvent): void;
103
+ protected _bufferedSend(msg: ArrayBuffer): void;
104
+ private _trySend;
105
+ private _tryBuffer;
106
+ close(options?: {
107
+ flush?: boolean;
108
+ }): void;
109
+ }
110
+
111
+ declare abstract class StreamConnection extends DataConnection {
112
+ private _CHUNK_SIZE;
113
+ private _splitStream;
114
+ private _rawSendStream;
115
+ protected writer: WritableStreamDefaultWriter<Uint8Array<ArrayBufferLike>>;
116
+ private _readStreamMessageHandler;
117
+ private _readStreamController;
118
+ protected _rawReadStream: ReadableStream<ArrayBuffer>;
119
+ protected constructor(peerId: string, provider: Dendri, options: any);
120
+ _initializeDataChannel(dc: RTCDataChannel): void;
121
+ close(options?: {
122
+ flush?: boolean;
123
+ }): void;
124
+ }
125
+
126
+ declare class MsgPack extends StreamConnection {
127
+ readonly serialization = "MsgPack";
128
+ private _encoder;
129
+ constructor(peerId: string, provider: Dendri, options: any);
130
+ protected _send(data: unknown): Promise<void>;
131
+ }
132
+
133
+ /**
134
+ * E2E encryption for relay messages using ECDH + AES-256-GCM.
135
+ * Uses the Web Crypto API -- available in all modern browsers and Node.js 18+.
136
+ */
137
+ /** Encrypted payload structure sent over the relay. */
138
+ interface EncryptedPayload {
139
+ readonly iv: string;
140
+ readonly ciphertext: string;
141
+ }
142
+ declare class RelayEncryption {
143
+ private _keyPair;
144
+ private _sharedKey;
145
+ private _ready;
146
+ get ready(): boolean;
147
+ /** Generate ECDH key pair and return the public key as JWK. */
148
+ generateKeyPair(): Promise<JsonWebKey>;
149
+ /** Derive shared AES-256-GCM key from remote peer's public key. */
150
+ deriveSharedKey(remotePublicKeyJwk: JsonWebKey): Promise<void>;
151
+ /** Encrypt a message for relay. */
152
+ encrypt(data: string): Promise<EncryptedPayload>;
153
+ /** Decrypt a message from relay. */
154
+ decrypt(encrypted: EncryptedPayload): Promise<string>;
155
+ /** Reset encryption state. */
156
+ clear(): void;
157
+ }
158
+
159
+ /**
160
+ * Host migration utilities for star topology rooms.
161
+ *
162
+ * When the host disconnects, the peer with the lowest alphabetical ID
163
+ * among all remaining peers becomes the new host. This is deterministic:
164
+ * every peer arrives at the same answer independently.
165
+ */
166
+ interface HostMigrationOptions {
167
+ readonly roomId: string;
168
+ readonly myPeerId: string;
169
+ readonly knownPeers: readonly string[];
170
+ readonly onBecomeHost: () => void;
171
+ readonly onNewHost: (hostId: string) => void;
172
+ readonly migrationTimeout?: number;
173
+ }
174
+ /**
175
+ * Elect a new host from the given set of peer IDs.
176
+ * Deterministic: the lowest alphabetical ID always wins.
177
+ *
178
+ * @param myPeerId - The local peer's ID.
179
+ * @param peerIds - All other known peer IDs (excluding the departed host).
180
+ * @returns The peer ID that should become the new host.
181
+ */
182
+ declare function electNewHost(myPeerId: string, peerIds: readonly string[]): string;
183
+
184
+ /**
185
+ * HTTP Long Polling transport — works through any network that allows HTTPS.
186
+ * Client->Server: POST
187
+ * Server->Client: GET (held open until data available or timeout)
188
+ */
189
+ declare class PollingTransport extends SignalingTransport {
190
+ private _connected;
191
+ private _disconnected;
192
+ private _id?;
193
+ private _token?;
194
+ private _messagesQueue;
195
+ private _polling;
196
+ private _autoReconnect;
197
+ private _reconnectAttempt;
198
+ private _reconnectTimer?;
199
+ private _heartbeatTimer?;
200
+ private _lastSeq;
201
+ private _baseUrl;
202
+ private readonly _pingInterval;
203
+ private _abortController?;
204
+ /** Backoff schedule base delays in milliseconds. */
205
+ private static readonly BACKOFF_SCHEDULE;
206
+ /** Random jitter range in milliseconds (applied as +/-). */
207
+ private static readonly BACKOFF_JITTER;
208
+ constructor(secure: boolean, host: string, port: number, path: string, _key: string, pingInterval?: number, _jwt?: string);
209
+ get reconnectAttempt(): number;
210
+ start(id: string, token: string): void;
211
+ private _startPolling;
212
+ send(data: any): void;
213
+ private _postMessage;
214
+ close(): void;
215
+ /** Compute the backoff delay (with jitter) for the current attempt. */
216
+ private _getReconnectDelay;
217
+ private _scheduleReconnect;
218
+ private _startHeartbeat;
219
+ private _sendQueuedMessages;
220
+ private _cleanup;
221
+ }
222
+
223
+ /**
224
+ * Server-side API client for dendri signal server.
225
+ * Use this from your backend to manage peers and rooms programmatically.
226
+ */
227
+ declare class DendriServerAPI {
228
+ private readonly _baseUrl;
229
+ private readonly _key;
230
+ constructor(options: {
231
+ url: string;
232
+ key?: string;
233
+ });
234
+ /** Get server health and stats */
235
+ getHealth(): Promise<{
236
+ status: string;
237
+ clients: number;
238
+ rooms: number;
239
+ uptime_ms: number;
240
+ relay_enabled: boolean;
241
+ }>;
242
+ /** List all connected peer IDs */
243
+ listPeers(room?: string): Promise<string[]>;
244
+ /** Generate a new peer ID */
245
+ generatePeerId(): Promise<string>;
246
+ /** Get TURN credentials */
247
+ getTurnCredentials(): Promise<{
248
+ iceServers: RTCIceServer[];
249
+ }>;
250
+ /** Get analytics metadata */
251
+ getAnalytics(): Promise<{
252
+ dataset: string;
253
+ events_tracked: string[];
254
+ }>;
255
+ }
256
+
257
+ /**
258
+ * SSE + POST transport for environments where WebSocket is blocked.
259
+ * Server->Client: Server-Sent Events (fetch-based, supports custom headers)
260
+ * Client->Server: HTTP POST requests
261
+ */
262
+ declare class SSETransport extends SignalingTransport {
263
+ private _connected;
264
+ private _disconnected;
265
+ private _id?;
266
+ private _token?;
267
+ private _messagesQueue;
268
+ private _abortController?;
269
+ private _autoReconnect;
270
+ private _reconnectAttempt;
271
+ private _reconnectTimer?;
272
+ private _heartbeatTimer?;
273
+ private _lastSeq;
274
+ private _baseUrl;
275
+ private _jwt?;
276
+ private readonly _pingInterval;
277
+ /** Backoff schedule base delays in milliseconds. */
278
+ private static readonly BACKOFF_SCHEDULE;
279
+ /** Random jitter range in milliseconds (applied as +/-). */
280
+ private static readonly BACKOFF_JITTER;
281
+ constructor(secure: boolean, host: string, port: number, path: string, _key: string, pingInterval?: number, jwt?: string);
282
+ get reconnectAttempt(): number;
283
+ start(id: string, token: string): void;
284
+ private _connectSSE;
285
+ send(data: any): void;
286
+ private _postMessage;
287
+ close(): void;
288
+ private _handleDisconnect;
289
+ /** Compute the backoff delay (with jitter) for the current attempt. */
290
+ private _getReconnectDelay;
291
+ private _scheduleReconnect;
292
+ private _startHeartbeat;
293
+ private _sendQueuedMessages;
294
+ private _cleanup;
295
+ }
296
+
297
+ /**
298
+ * Callback signature for topic message handlers.
299
+ * @param data The payload received on this topic.
300
+ * @param peerId The ID of the peer that sent the message.
301
+ */
302
+ type TopicHandler = (data: unknown, peerId: string) => void;
303
+ /**
304
+ * Marker interface for messages that carry topic metadata.
305
+ * When a topic is specified the original payload is wrapped in this envelope
306
+ * so the receiver can extract and route it.
307
+ */
308
+ interface TopicEnvelope {
309
+ readonly __topic: string;
310
+ readonly __data: unknown;
311
+ /** If true, `__data` is base64-encoded bytes — receivers must decode before use. */
312
+ readonly __binary?: boolean;
313
+ }
314
+ /** Type-guard: does `value` look like a topic-wrapped envelope? */
315
+ declare function isTopicEnvelope(value: unknown): value is TopicEnvelope;
316
+ /**
317
+ * Manages per-topic subscriptions and dispatches incoming messages
318
+ * to the matching handlers.
319
+ *
320
+ * Designed for use inside Room and HybridConnection so that
321
+ * callers can filter messages by topic without manual switching logic.
322
+ */
323
+ declare class TopicManager {
324
+ private readonly _handlers;
325
+ private readonly _globalHandlers;
326
+ /** Subscribe to a specific topic. Returns an unsubscribe function. */
327
+ subscribe(topic: string, handler: TopicHandler): () => void;
328
+ /** Subscribe to ALL topics (including un-topiced messages). Returns an unsubscribe function. */
329
+ subscribeAll(handler: TopicHandler): () => void;
330
+ /**
331
+ * Dispatch a message to the appropriate handlers.
332
+ *
333
+ * @returns `true` if at least one handler was invoked, `false` otherwise.
334
+ */
335
+ dispatch(topic: string | undefined, data: unknown, peerId: string): boolean;
336
+ /** Remove all subscriptions. */
337
+ clear(): void;
338
+ }
339
+
340
+ export { BufferedConnection, DataConnection, Dendri, DendriServerAPI, type EncryptedPayload, type HostMigrationOptions, MsgPack, MsgPackDendri, PollingTransport, RelayEncryption, SSETransport, SerializerMapping, SignalingTransport, StreamConnection, type TopicEnvelope, type TopicHandler, TopicManager, Util, type UtilSupportsObj, Dendri as default, electNewHost, isTopicEnvelope, util };