@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.
- package/LICENSE +21 -0
- package/README.md +141 -0
- package/dist/chunk-MJW5M75V.js +7785 -0
- package/dist/chunk-MJW5M75V.js.map +1 -0
- package/dist/dendri.browser.global.js +6565 -0
- package/dist/dendri.browser.global.js.map +1 -0
- package/dist/dendri.cjs +9725 -0
- package/dist/dendri.cjs.map +1 -0
- package/dist/dendri.d.cts +340 -0
- package/dist/dendri.d.ts +340 -0
- package/dist/dendri.js +1907 -0
- package/dist/dendri.js.map +1 -0
- package/dist/dendri.min.global.js +56 -0
- package/dist/dendri.min.global.js.map +1 -0
- package/dist/serializer.msgpack.cjs +4 -0
- package/dist/serializer.msgpack.cjs.map +1 -0
- package/dist/serializer.msgpack.d.cts +936 -0
- package/dist/serializer.msgpack.d.ts +936 -0
- package/dist/serializer.msgpack.js +4 -0
- package/dist/serializer.msgpack.js.map +1 -0
- package/dist/store-RTivRmUW.d.cts +1378 -0
- package/dist/store-RTivRmUW.d.ts +1378 -0
- package/dist/store.cjs +7685 -0
- package/dist/store.cjs.map +1 -0
- package/dist/store.d.cts +2 -0
- package/dist/store.d.ts +2 -0
- package/dist/store.js +3 -0
- package/dist/store.js.map +1 -0
- package/package.json +100 -0
|
@@ -0,0 +1,936 @@
|
|
|
1
|
+
import { EventEmitter, ValidEventTypes } from 'eventemitter3';
|
|
2
|
+
|
|
3
|
+
interface EventsWithError<ErrorType extends string> {
|
|
4
|
+
error: (error: DendriError<`${ErrorType}`>) => void;
|
|
5
|
+
}
|
|
6
|
+
declare class EventEmitterWithError<ErrorType extends string, Events extends EventsWithError<ErrorType>> extends EventEmitter<Events, never> {
|
|
7
|
+
/**
|
|
8
|
+
* Emits a typed error message.
|
|
9
|
+
*
|
|
10
|
+
* @internal
|
|
11
|
+
*/
|
|
12
|
+
emitError(type: ErrorType, err: string | Error, retryable?: boolean): void;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* A DendriError is emitted whenever an error occurs.
|
|
16
|
+
* It always has a `.type`, which can be used to identify the error.
|
|
17
|
+
*/
|
|
18
|
+
declare class DendriError<T extends string> extends Error {
|
|
19
|
+
type: T;
|
|
20
|
+
/** Whether the operation that caused this error can be retried. */
|
|
21
|
+
retryable: boolean;
|
|
22
|
+
/** Structured context about the error. */
|
|
23
|
+
details?: Record<string, unknown>;
|
|
24
|
+
/**
|
|
25
|
+
* @internal
|
|
26
|
+
*/
|
|
27
|
+
constructor(type: T, err: Error | string);
|
|
28
|
+
/** Set the retryable flag (fluent API). */
|
|
29
|
+
setRetryable(retryable: boolean): this;
|
|
30
|
+
/** Set structured details (fluent API). */
|
|
31
|
+
setDetails(details: Record<string, unknown>): this;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
declare enum ConnectionType {
|
|
35
|
+
Data = "data",
|
|
36
|
+
Media = "media"
|
|
37
|
+
}
|
|
38
|
+
declare enum DendriErrorType {
|
|
39
|
+
/**
|
|
40
|
+
* The client's browser does not support some or all WebRTC features that you are trying to use.
|
|
41
|
+
*/
|
|
42
|
+
BrowserIncompatible = "browser-incompatible",
|
|
43
|
+
/**
|
|
44
|
+
* You've already disconnected this peer from the server and can no longer make any new connections on it.
|
|
45
|
+
*/
|
|
46
|
+
Disconnected = "disconnected",
|
|
47
|
+
/**
|
|
48
|
+
* The ID passed into the Peer constructor contains illegal characters.
|
|
49
|
+
*/
|
|
50
|
+
InvalidID = "invalid-id",
|
|
51
|
+
/**
|
|
52
|
+
* The API key passed into the Peer constructor contains illegal characters or is not in the system (cloud server only).
|
|
53
|
+
*/
|
|
54
|
+
InvalidKey = "invalid-key",
|
|
55
|
+
/**
|
|
56
|
+
* Lost or cannot establish a connection to the signalling server.
|
|
57
|
+
*/
|
|
58
|
+
Network = "network",
|
|
59
|
+
/**
|
|
60
|
+
* The peer you're trying to connect to does not exist.
|
|
61
|
+
*/
|
|
62
|
+
PeerUnavailable = "peer-unavailable",
|
|
63
|
+
/**
|
|
64
|
+
* Dendri is being used securely, but the cloud server does not support SSL. Use a custom DendriServer.
|
|
65
|
+
*/
|
|
66
|
+
SslUnavailable = "ssl-unavailable",
|
|
67
|
+
/**
|
|
68
|
+
* Unable to reach the server.
|
|
69
|
+
*/
|
|
70
|
+
ServerError = "server-error",
|
|
71
|
+
/**
|
|
72
|
+
* An error from the underlying socket.
|
|
73
|
+
*/
|
|
74
|
+
SocketError = "socket-error",
|
|
75
|
+
/**
|
|
76
|
+
* The underlying socket closed unexpectedly.
|
|
77
|
+
*/
|
|
78
|
+
SocketClosed = "socket-closed",
|
|
79
|
+
/**
|
|
80
|
+
* The ID passed into the Peer constructor is already taken.
|
|
81
|
+
*
|
|
82
|
+
* :::caution
|
|
83
|
+
* This error is not fatal if your peer has open peer-to-peer connections.
|
|
84
|
+
* This can happen if you attempt to {@apilink Dendri.reconnect} a peer that has been disconnected from the server,
|
|
85
|
+
* but its old ID has now been taken.
|
|
86
|
+
* :::
|
|
87
|
+
*/
|
|
88
|
+
UnavailableID = "unavailable-id",
|
|
89
|
+
/**
|
|
90
|
+
* Native WebRTC errors.
|
|
91
|
+
*/
|
|
92
|
+
WebRTC = "webrtc"
|
|
93
|
+
}
|
|
94
|
+
declare enum BaseConnectionErrorType {
|
|
95
|
+
NegotiationFailed = "negotiation-failed",
|
|
96
|
+
ConnectionClosed = "connection-closed"
|
|
97
|
+
}
|
|
98
|
+
declare enum DataConnectionErrorType {
|
|
99
|
+
NotOpenYet = "not-open-yet",
|
|
100
|
+
MessageTooBig = "message-too-big",
|
|
101
|
+
/** @deprecated Use {@link MessageTooBig} instead */
|
|
102
|
+
MessageToBig = "message-too-big"
|
|
103
|
+
}
|
|
104
|
+
declare enum SocketEventType {
|
|
105
|
+
Message = "message",
|
|
106
|
+
Disconnected = "disconnected",
|
|
107
|
+
Error = "error",
|
|
108
|
+
Close = "close",
|
|
109
|
+
Reconnected = "reconnected",
|
|
110
|
+
ReconnectAttempt = "reconnect-attempt"
|
|
111
|
+
}
|
|
112
|
+
declare enum ServerMessageType {
|
|
113
|
+
Heartbeat = "HEARTBEAT",
|
|
114
|
+
Candidate = "CANDIDATE",
|
|
115
|
+
Offer = "OFFER",
|
|
116
|
+
Answer = "ANSWER",
|
|
117
|
+
Open = "OPEN",// The connection to the server is open.
|
|
118
|
+
Error = "ERROR",// Server error.
|
|
119
|
+
IdTaken = "ID-TAKEN",// The selected ID is taken.
|
|
120
|
+
InvalidKey = "INVALID-KEY",// The given API key cannot be found.
|
|
121
|
+
Leave = "LEAVE",// Another peer has closed its connection to this peer.
|
|
122
|
+
Expire = "EXPIRE",// The offer sent to a peer has expired without response.
|
|
123
|
+
Data = "DATA",// Relayed data message via WebSocket.
|
|
124
|
+
Ack = "ACK",// Server acknowledgement with sequence number.
|
|
125
|
+
RoomJoin = "ROOM-JOIN",// A peer joined a room.
|
|
126
|
+
RoomLeave = "ROOM-LEAVE",// A peer left a room.
|
|
127
|
+
RoomPeers = "ROOM-PEERS",// List of peers in a room.
|
|
128
|
+
HostMigrate = "HOST-MIGRATE",// Host migration notification.
|
|
129
|
+
PresenceUpdate = "PRESENCE-UPDATE",// Presence data broadcast.
|
|
130
|
+
KeyExchange = "KEY-EXCHANGE"
|
|
131
|
+
}
|
|
132
|
+
declare enum TransportMode {
|
|
133
|
+
WebRTC = "webrtc",
|
|
134
|
+
WebSocketRelay = "ws-relay",
|
|
135
|
+
Reconnecting = "reconnecting"
|
|
136
|
+
}
|
|
137
|
+
declare enum ConnectionState {
|
|
138
|
+
/** Initial state, not yet connected */
|
|
139
|
+
Initialized = "initialized",
|
|
140
|
+
/** Attempting to connect to signaling server */
|
|
141
|
+
Connecting = "connecting",
|
|
142
|
+
/** Connected and ready */
|
|
143
|
+
Connected = "connected",
|
|
144
|
+
/** Temporarily disconnected, will auto-reconnect */
|
|
145
|
+
Disconnected = "disconnected",
|
|
146
|
+
/** Extended offline, slower retry schedule */
|
|
147
|
+
Suspended = "suspended",
|
|
148
|
+
/** Explicitly closed by user */
|
|
149
|
+
Closed = "closed",
|
|
150
|
+
/** Unrecoverable error */
|
|
151
|
+
Failed = "failed"
|
|
152
|
+
}
|
|
153
|
+
declare enum ConnectionQuality {
|
|
154
|
+
Excellent = "excellent",
|
|
155
|
+
Good = "good",
|
|
156
|
+
Poor = "poor",
|
|
157
|
+
Unknown = "unknown"
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
interface ServerMessage {
|
|
161
|
+
type: ServerMessageType;
|
|
162
|
+
payload: any;
|
|
163
|
+
src: string;
|
|
164
|
+
/** Server-assigned sequence number for reliable ordering / replay. */
|
|
165
|
+
seq?: number;
|
|
166
|
+
/** Room name associated with this message. */
|
|
167
|
+
room?: string;
|
|
168
|
+
/** Server-assigned timestamp (epoch ms). */
|
|
169
|
+
timestamp?: number;
|
|
170
|
+
/** ACK identifier for delivery confirmation. */
|
|
171
|
+
ackId?: string;
|
|
172
|
+
/** Optional topic for data multiplexing / filtering. */
|
|
173
|
+
topic?: string;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
interface BaseConnectionEvents<ErrorType extends string = BaseConnectionErrorType> extends EventsWithError<ErrorType> {
|
|
177
|
+
/**
|
|
178
|
+
* Emitted when either you or the remote peer closes the connection.
|
|
179
|
+
*
|
|
180
|
+
* ```ts
|
|
181
|
+
* connection.on('close', () => { ... });
|
|
182
|
+
* ```
|
|
183
|
+
*/
|
|
184
|
+
close: () => void;
|
|
185
|
+
/**
|
|
186
|
+
* ```ts
|
|
187
|
+
* connection.on('error', (error) => { ... });
|
|
188
|
+
* ```
|
|
189
|
+
*/
|
|
190
|
+
error: (error: DendriError<`${ErrorType}`>) => void;
|
|
191
|
+
iceStateChanged: (state: RTCIceConnectionState) => void;
|
|
192
|
+
}
|
|
193
|
+
declare abstract class BaseConnection<SubClassEvents extends ValidEventTypes, ErrorType extends string = never> extends EventEmitterWithError<ErrorType | BaseConnectionErrorType, SubClassEvents & BaseConnectionEvents<BaseConnectionErrorType | ErrorType>> {
|
|
194
|
+
/**
|
|
195
|
+
* The ID of the peer on the other end of this connection.
|
|
196
|
+
*/
|
|
197
|
+
readonly peer: string;
|
|
198
|
+
provider: Dendri | null;
|
|
199
|
+
readonly options: any;
|
|
200
|
+
protected _open: boolean;
|
|
201
|
+
/**
|
|
202
|
+
* Any type of metadata associated with the connection,
|
|
203
|
+
* passed in by whoever initiated the connection.
|
|
204
|
+
*/
|
|
205
|
+
readonly metadata: any;
|
|
206
|
+
connectionId: string;
|
|
207
|
+
peerConnection: RTCPeerConnection | null;
|
|
208
|
+
dataChannel: RTCDataChannel | null;
|
|
209
|
+
abstract get type(): ConnectionType;
|
|
210
|
+
/**
|
|
211
|
+
* The optional label passed in or assigned by Dendri when the connection was initiated.
|
|
212
|
+
*/
|
|
213
|
+
label: string;
|
|
214
|
+
/**
|
|
215
|
+
* Whether the media connection is active (e.g. your call has been answered).
|
|
216
|
+
* You can check this if you want to set a maximum wait time for a one-sided call.
|
|
217
|
+
*/
|
|
218
|
+
get open(): boolean;
|
|
219
|
+
protected constructor(
|
|
220
|
+
/**
|
|
221
|
+
* The ID of the peer on the other end of this connection.
|
|
222
|
+
*/
|
|
223
|
+
peer: string, provider: Dendri | null, options: any);
|
|
224
|
+
abstract close(): void;
|
|
225
|
+
/**
|
|
226
|
+
* @internal
|
|
227
|
+
*/
|
|
228
|
+
abstract handleMessage(message: ServerMessage): void;
|
|
229
|
+
/**
|
|
230
|
+
* Called by the Negotiator when the DataChannel is ready.
|
|
231
|
+
* @internal
|
|
232
|
+
* */
|
|
233
|
+
abstract _initializeDataChannel(dc: RTCDataChannel): void;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
interface DataConnectionEvents extends EventsWithError<DataConnectionErrorType | BaseConnectionErrorType>, BaseConnectionEvents<DataConnectionErrorType | BaseConnectionErrorType> {
|
|
237
|
+
/**
|
|
238
|
+
* Emitted when data is received from the remote peer.
|
|
239
|
+
*/
|
|
240
|
+
data: (data: unknown) => void;
|
|
241
|
+
/**
|
|
242
|
+
* Emitted when the connection is established and ready-to-use.
|
|
243
|
+
*/
|
|
244
|
+
open: () => void;
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Wraps a DataChannel between two Peers.
|
|
248
|
+
*/
|
|
249
|
+
declare abstract class DataConnection extends BaseConnection<DataConnectionEvents, DataConnectionErrorType> {
|
|
250
|
+
protected static readonly ID_PREFIX = "dc_";
|
|
251
|
+
protected static readonly MAX_BUFFERED_AMOUNT: number;
|
|
252
|
+
private _negotiator;
|
|
253
|
+
abstract readonly serialization: string;
|
|
254
|
+
readonly reliable: boolean;
|
|
255
|
+
get type(): ConnectionType;
|
|
256
|
+
constructor(peerId: string, provider: Dendri, options: any);
|
|
257
|
+
/** Called by the Negotiator when the DataChannel is ready. */
|
|
258
|
+
_initializeDataChannel(dc: RTCDataChannel): void;
|
|
259
|
+
/**
|
|
260
|
+
* Exposed functionality for users.
|
|
261
|
+
*/
|
|
262
|
+
private _flushCloseTimeout;
|
|
263
|
+
/** Allows user to close connection. */
|
|
264
|
+
close(options?: {
|
|
265
|
+
flush?: boolean;
|
|
266
|
+
}): void;
|
|
267
|
+
protected abstract _send(data: any, chunked: boolean): void | Promise<void>;
|
|
268
|
+
/** Allows user to send data. */
|
|
269
|
+
send(data: any, chunked?: boolean): void | Promise<void>;
|
|
270
|
+
handleMessage(message: ServerMessage): Promise<void>;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* ACK-based message delivery confirmation manager.
|
|
275
|
+
*
|
|
276
|
+
* Tracks outgoing messages that expect an acknowledgement and resolves/rejects
|
|
277
|
+
* the corresponding promise when the ACK arrives or the timeout fires.
|
|
278
|
+
*/
|
|
279
|
+
declare class AckManager {
|
|
280
|
+
private readonly _pending;
|
|
281
|
+
private _counter;
|
|
282
|
+
/** Generate a unique ack ID. */
|
|
283
|
+
nextId(): string;
|
|
284
|
+
/**
|
|
285
|
+
* Register a pending ACK with timeout. When `peerId` is supplied, the
|
|
286
|
+
* ACK can be rejected early by {@link rejectAllForPeer} when that peer
|
|
287
|
+
* disconnects, so callers don't wait out the full timeout after the
|
|
288
|
+
* transport layer already knows the target is gone.
|
|
289
|
+
*/
|
|
290
|
+
waitForAck(ackId: string, timeoutMs?: number, peerId?: string): Promise<void>;
|
|
291
|
+
/** Handle an incoming ACK message. Returns true if the ackId was pending. */
|
|
292
|
+
handleAck(ackId: string): boolean;
|
|
293
|
+
/**
|
|
294
|
+
* Reject every pending ACK whose `peerId` matches. Called from the
|
|
295
|
+
* close path of a per-peer connection so broadcastWithAck promises
|
|
296
|
+
* resolve with a clear error immediately instead of stalling until
|
|
297
|
+
* the timeout.
|
|
298
|
+
*/
|
|
299
|
+
rejectAllForPeer(peerId: string): number;
|
|
300
|
+
/** Clean up all pending ACKs (e.g. on disconnect). */
|
|
301
|
+
clear(): void;
|
|
302
|
+
/** Number of ACKs currently awaiting confirmation. */
|
|
303
|
+
get pendingCount(): number;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
interface AnswerOption {
|
|
307
|
+
/**
|
|
308
|
+
* Function which runs before create answer to modify sdp answer message.
|
|
309
|
+
*/
|
|
310
|
+
sdpTransform?: (sdp: string) => string;
|
|
311
|
+
}
|
|
312
|
+
interface DendriOption {
|
|
313
|
+
key?: string;
|
|
314
|
+
host?: string;
|
|
315
|
+
port?: number;
|
|
316
|
+
path?: string;
|
|
317
|
+
secure?: boolean;
|
|
318
|
+
token?: string;
|
|
319
|
+
config?: RTCConfiguration;
|
|
320
|
+
debug?: number;
|
|
321
|
+
referrerPolicy?: ReferrerPolicy;
|
|
322
|
+
/** Auto-fetch TURN credentials from the signaling server's GET /turn endpoint. */
|
|
323
|
+
fetchTurnCredentials?: boolean;
|
|
324
|
+
/** Optional JWT for authenticated connections. */
|
|
325
|
+
jwt?: string;
|
|
326
|
+
/** Enable WebSocket relay fallback when WebRTC is unavailable. */
|
|
327
|
+
enableRelay?: boolean;
|
|
328
|
+
/** Optional function to validate connection metadata before accepting. */
|
|
329
|
+
validateMetadata?: (metadata: unknown) => boolean;
|
|
330
|
+
/** Signaling transport: 'websocket' (default), 'sse', 'polling', or 'auto' (tries WS then SSE then polling) */
|
|
331
|
+
signalingTransport?: "websocket" | "sse" | "polling" | "auto";
|
|
332
|
+
}
|
|
333
|
+
interface DendriConnectOption {
|
|
334
|
+
/**
|
|
335
|
+
* A unique label by which you want to identify this data connection.
|
|
336
|
+
* If left unspecified, a label will be generated at random.
|
|
337
|
+
*
|
|
338
|
+
* Can be accessed with {@apilink DataConnection.label}
|
|
339
|
+
*/
|
|
340
|
+
label?: string;
|
|
341
|
+
/**
|
|
342
|
+
* Metadata associated with the connection, passed in by whoever initiated the connection.
|
|
343
|
+
*
|
|
344
|
+
* Can be accessed with {@apilink DataConnection.metadata}.
|
|
345
|
+
* Can be any serializable type.
|
|
346
|
+
*/
|
|
347
|
+
metadata?: any;
|
|
348
|
+
serialization?: string;
|
|
349
|
+
reliable?: boolean;
|
|
350
|
+
}
|
|
351
|
+
interface HybridConnectionOption {
|
|
352
|
+
/** Milliseconds before falling back to WebSocket relay (default 10000). */
|
|
353
|
+
iceTimeout?: number;
|
|
354
|
+
/** Periodically retry WebRTC when on relay (default true). */
|
|
355
|
+
autoUpgrade?: boolean;
|
|
356
|
+
/** Milliseconds between upgrade attempts (default 60000). */
|
|
357
|
+
upgradeInterval?: number;
|
|
358
|
+
/** Max consecutive upgrade failures before stopping (default 5). */
|
|
359
|
+
maxUpgradeAttempts?: number;
|
|
360
|
+
/** Poll getStats() for connection quality metrics (default false). */
|
|
361
|
+
enableMetrics?: boolean;
|
|
362
|
+
/** Encrypt relay (WebSocket) messages with ECDH + AES-256-GCM (default true). */
|
|
363
|
+
encryptRelay?: boolean;
|
|
364
|
+
}
|
|
365
|
+
interface CallOption {
|
|
366
|
+
/**
|
|
367
|
+
* Metadata associated with the connection, passed in by whoever initiated the connection.
|
|
368
|
+
*
|
|
369
|
+
* Can be accessed with {@apilink MediaConnection.metadata}.
|
|
370
|
+
* Can be any serializable type.
|
|
371
|
+
*/
|
|
372
|
+
metadata?: any;
|
|
373
|
+
/**
|
|
374
|
+
* Function which runs before create offer to modify sdp offer message.
|
|
375
|
+
*/
|
|
376
|
+
sdpTransform?: (sdp: string) => string;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
/** Options accepted by {@link HybridConnection.send}. */
|
|
380
|
+
interface HybridSendOptions {
|
|
381
|
+
/** When set, the message is tagged with this topic string. */
|
|
382
|
+
readonly topic?: string;
|
|
383
|
+
}
|
|
384
|
+
interface HybridConnectionEvents {
|
|
385
|
+
open: () => void;
|
|
386
|
+
data: (data: unknown) => void;
|
|
387
|
+
close: () => void;
|
|
388
|
+
error: (err: Error) => void;
|
|
389
|
+
transportChanged: (mode: TransportMode) => void;
|
|
390
|
+
qualityChanged: (quality: ConnectionQuality) => void;
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* Wraps both a WebRTC DataConnection and a WebSocket relay,
|
|
394
|
+
* switching transparently between them.
|
|
395
|
+
*
|
|
396
|
+
* - Attempts WebRTC first; falls back to WS relay on ICE timeout.
|
|
397
|
+
* - Periodically retries WebRTC upgrade when on relay.
|
|
398
|
+
* - Emits `transportChanged` whenever the active transport switches.
|
|
399
|
+
*/
|
|
400
|
+
declare class HybridConnection extends EventEmitter<HybridConnectionEvents> {
|
|
401
|
+
readonly peer: string;
|
|
402
|
+
private readonly _provider;
|
|
403
|
+
private readonly _options;
|
|
404
|
+
private _dataConnection;
|
|
405
|
+
private _mode;
|
|
406
|
+
private _iceTimer;
|
|
407
|
+
private _upgradeTimer;
|
|
408
|
+
private _upgradeAttempts;
|
|
409
|
+
private _open;
|
|
410
|
+
private _closed;
|
|
411
|
+
private readonly _ackManager;
|
|
412
|
+
private readonly _topics;
|
|
413
|
+
private readonly _encryption;
|
|
414
|
+
private readonly _encryptRelay;
|
|
415
|
+
private _keyExchangeSent;
|
|
416
|
+
private _pendingRelayQueue;
|
|
417
|
+
private _expectedSeq;
|
|
418
|
+
private _reorderBuffer;
|
|
419
|
+
private readonly _reorderTimeout;
|
|
420
|
+
private _reorderTimers;
|
|
421
|
+
constructor(peer: string, provider: Dendri, options?: HybridConnectionOption);
|
|
422
|
+
get mode(): TransportMode;
|
|
423
|
+
get open(): boolean;
|
|
424
|
+
/** Start connection: try WebRTC first, fall back to WS relay on timeout. */
|
|
425
|
+
start(): void;
|
|
426
|
+
/** Send data through the best available transport, optionally tagged with a topic. */
|
|
427
|
+
send(data: unknown, options?: HybridSendOptions): void;
|
|
428
|
+
/**
|
|
429
|
+
* Send data with delivery confirmation (at-least-once guarantee).
|
|
430
|
+
* Resolves when the remote peer ACKs, rejects on timeout.
|
|
431
|
+
*/
|
|
432
|
+
sendWithAck(data: unknown, timeoutMs?: number): Promise<void>;
|
|
433
|
+
/**
|
|
434
|
+
* @internal
|
|
435
|
+
* Expose the AckManager so the Dendri instance can route incoming ACKs.
|
|
436
|
+
*/
|
|
437
|
+
get ackManager(): AckManager;
|
|
438
|
+
/**
|
|
439
|
+
* Subscribe to messages on a specific topic.
|
|
440
|
+
* Returns an unsubscribe function.
|
|
441
|
+
*/
|
|
442
|
+
subscribe(topic: string, handler: (data: unknown, peerId: string) => void): () => void;
|
|
443
|
+
/**
|
|
444
|
+
* Subscribe to all incoming data regardless of topic.
|
|
445
|
+
* Returns an unsubscribe function.
|
|
446
|
+
*/
|
|
447
|
+
onData(handler: (data: unknown, peerId: string) => void): () => void;
|
|
448
|
+
/**
|
|
449
|
+
* Handle a DATA message received via WebSocket relay.
|
|
450
|
+
* Called by Dendri._handleMessage when routing relay data.
|
|
451
|
+
*
|
|
452
|
+
* @param payload - The message payload.
|
|
453
|
+
* @param seq - Optional server-assigned sequence number for ordering.
|
|
454
|
+
*/
|
|
455
|
+
handleRelayData(payload: unknown, seq?: number): void;
|
|
456
|
+
/** Close connection and clean up all resources. */
|
|
457
|
+
close(): void;
|
|
458
|
+
/**
|
|
459
|
+
* Initiate the ECDH key exchange by generating a key pair and sending
|
|
460
|
+
* the public key to the remote peer via signaling.
|
|
461
|
+
*/
|
|
462
|
+
initiateKeyExchange(): void;
|
|
463
|
+
/**
|
|
464
|
+
* Handle an incoming KEY_EXCHANGE message from the remote peer.
|
|
465
|
+
* Derives the shared secret and sends our public key back if we haven't yet.
|
|
466
|
+
*/
|
|
467
|
+
handleKeyExchange(payload: {
|
|
468
|
+
publicKey: JsonWebKey;
|
|
469
|
+
}): void;
|
|
470
|
+
/**
|
|
471
|
+
* Send a payload via WebSocket relay, encrypting it if encryption is ready.
|
|
472
|
+
* If encryption is enabled but not yet ready, the message is queued.
|
|
473
|
+
*/
|
|
474
|
+
private _sendRelay;
|
|
475
|
+
/** Flush messages that were queued while waiting for key exchange. */
|
|
476
|
+
private _flushPendingRelayQueue;
|
|
477
|
+
/**
|
|
478
|
+
* Enforce ordered delivery for sequenced relay messages.
|
|
479
|
+
* Messages without a seq or when not in relay mode are delivered immediately.
|
|
480
|
+
*/
|
|
481
|
+
private _deliverInOrder;
|
|
482
|
+
/** Flush consecutive messages from the reorder buffer. */
|
|
483
|
+
private _flushReorderBuffer;
|
|
484
|
+
/**
|
|
485
|
+
* Force-flush the reorder buffer when a timeout fires.
|
|
486
|
+
* Skips past any gaps by advancing _expectedSeq to the lowest buffered
|
|
487
|
+
* sequence, then delivers all consecutive messages from there.
|
|
488
|
+
*/
|
|
489
|
+
private _forceFlushReorderBuffer;
|
|
490
|
+
/**
|
|
491
|
+
* Route an incoming payload through the TopicManager (if applicable)
|
|
492
|
+
* and emit the generic `data` event.
|
|
493
|
+
*
|
|
494
|
+
* If the payload is a topic envelope, the inner data is extracted and
|
|
495
|
+
* dispatched to topic-specific handlers. The raw `data` event always fires
|
|
496
|
+
* with the unwrapped payload so legacy listeners still work.
|
|
497
|
+
*/
|
|
498
|
+
private _dispatchIncoming;
|
|
499
|
+
/** Attempt a WebRTC connection with ICE timeout. */
|
|
500
|
+
private _attemptWebRTC;
|
|
501
|
+
/** Switch to WebSocket relay and optionally schedule periodic upgrade attempts. */
|
|
502
|
+
private _fallbackToRelay;
|
|
503
|
+
/** Update the transport mode and emit if changed. */
|
|
504
|
+
private _setMode;
|
|
505
|
+
private _clearIceTimer;
|
|
506
|
+
private _clearUpgradeTimer;
|
|
507
|
+
/**
|
|
508
|
+
* Periodically retry WebRTC when on relay.
|
|
509
|
+
* Respects `autoUpgrade`, `upgradeInterval`, and `maxUpgradeAttempts` options.
|
|
510
|
+
*/
|
|
511
|
+
private _scheduleUpgrade;
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
declare enum LogLevel {
|
|
515
|
+
/**
|
|
516
|
+
* Prints no logs.
|
|
517
|
+
*/
|
|
518
|
+
Disabled = 0,
|
|
519
|
+
/**
|
|
520
|
+
* Prints only errors.
|
|
521
|
+
*/
|
|
522
|
+
Errors = 1,
|
|
523
|
+
/**
|
|
524
|
+
* Prints errors and warnings.
|
|
525
|
+
*/
|
|
526
|
+
Warnings = 2,
|
|
527
|
+
/**
|
|
528
|
+
* Prints all logs.
|
|
529
|
+
*/
|
|
530
|
+
All = 3
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
interface MediaConnectionEvents extends BaseConnectionEvents<never> {
|
|
534
|
+
/**
|
|
535
|
+
* Emitted when a connection to the Dendri server is established.
|
|
536
|
+
*
|
|
537
|
+
* ```ts
|
|
538
|
+
* mediaConnection.on('stream', (stream) => { ... });
|
|
539
|
+
* ```
|
|
540
|
+
*/
|
|
541
|
+
stream: (stream: MediaStream) => void;
|
|
542
|
+
/**
|
|
543
|
+
* Emitted when the auxiliary data channel is established.
|
|
544
|
+
* After this event, hanging up will close the connection cleanly on the remote peer.
|
|
545
|
+
* @beta
|
|
546
|
+
*/
|
|
547
|
+
willCloseOnRemote: () => void;
|
|
548
|
+
}
|
|
549
|
+
/**
|
|
550
|
+
* Wraps WebRTC's media streams.
|
|
551
|
+
* To get one, use {@apilink Dendri.call} or listen for the {@apilink DendriEvents | `call`} event.
|
|
552
|
+
*/
|
|
553
|
+
declare class MediaConnection extends BaseConnection<MediaConnectionEvents> {
|
|
554
|
+
private static readonly ID_PREFIX;
|
|
555
|
+
readonly label: string;
|
|
556
|
+
private _negotiator;
|
|
557
|
+
private _localStream;
|
|
558
|
+
private _remoteStream;
|
|
559
|
+
/**
|
|
560
|
+
* For media connections, this is always 'media'.
|
|
561
|
+
*/
|
|
562
|
+
get type(): ConnectionType;
|
|
563
|
+
get localStream(): MediaStream | null | undefined;
|
|
564
|
+
get remoteStream(): MediaStream | null;
|
|
565
|
+
constructor(peerId: string, provider: Dendri, options: any);
|
|
566
|
+
/** Called by the Negotiator when the DataChannel is ready. */
|
|
567
|
+
_initializeDataChannel(dc: RTCDataChannel): void;
|
|
568
|
+
addStream(remoteStream: MediaStream): void;
|
|
569
|
+
/**
|
|
570
|
+
* @internal
|
|
571
|
+
*/
|
|
572
|
+
handleMessage(message: ServerMessage): void;
|
|
573
|
+
/**
|
|
574
|
+
* When receiving a {@apilink DendriEvents | `call`} event on a peer, you can call
|
|
575
|
+
* `answer` on the media connection provided by the callback to accept the call
|
|
576
|
+
* and optionally send your own media stream.
|
|
577
|
+
|
|
578
|
+
*
|
|
579
|
+
* @param stream A WebRTC media stream.
|
|
580
|
+
* @param options
|
|
581
|
+
* @returns
|
|
582
|
+
*/
|
|
583
|
+
answer(stream?: MediaStream, options?: AnswerOption): void;
|
|
584
|
+
/**
|
|
585
|
+
* Exposed functionality for users.
|
|
586
|
+
*/
|
|
587
|
+
/**
|
|
588
|
+
* Closes the media connection.
|
|
589
|
+
*/
|
|
590
|
+
close(): void;
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
/**
|
|
594
|
+
* Events emitted by all signaling transports.
|
|
595
|
+
*/
|
|
596
|
+
interface TransportEvents {
|
|
597
|
+
[SocketEventType.Message]: (data: any) => void;
|
|
598
|
+
[SocketEventType.Disconnected]: () => void;
|
|
599
|
+
[SocketEventType.Error]: (error: string) => void;
|
|
600
|
+
[SocketEventType.Reconnected]: () => void;
|
|
601
|
+
[SocketEventType.ReconnectAttempt]: (attempt: number) => void;
|
|
602
|
+
}
|
|
603
|
+
/**
|
|
604
|
+
* Abstract signaling transport. WebSocket, SSE+POST, and Long Polling
|
|
605
|
+
* all implement this interface so the Dendri class is transport-agnostic.
|
|
606
|
+
*/
|
|
607
|
+
declare abstract class SignalingTransport extends EventEmitter<TransportEvents> {
|
|
608
|
+
abstract start(id: string, token: string): void;
|
|
609
|
+
abstract send(data: any): void;
|
|
610
|
+
abstract close(): void;
|
|
611
|
+
abstract get reconnectAttempt(): number;
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
declare class DendriOptions implements DendriOption {
|
|
615
|
+
/**
|
|
616
|
+
* Prints log messages depending on the debug level passed in.
|
|
617
|
+
*/
|
|
618
|
+
debug?: LogLevel;
|
|
619
|
+
/**
|
|
620
|
+
* Server host for your Dendri signaling server.
|
|
621
|
+
* Also accepts `'/'` to signify relative hostname.
|
|
622
|
+
*/
|
|
623
|
+
host: string;
|
|
624
|
+
/**
|
|
625
|
+
* Server port. Defaults to `443`.
|
|
626
|
+
*/
|
|
627
|
+
port?: number;
|
|
628
|
+
/**
|
|
629
|
+
* The path where your self-hosted Dendri server is running. Defaults to `'/'`
|
|
630
|
+
*/
|
|
631
|
+
path?: string;
|
|
632
|
+
/**
|
|
633
|
+
* API key for the Dendri server.
|
|
634
|
+
* This is not used anymore.
|
|
635
|
+
* @deprecated
|
|
636
|
+
*/
|
|
637
|
+
key?: string;
|
|
638
|
+
token?: string;
|
|
639
|
+
/**
|
|
640
|
+
* Configuration hash passed to RTCPeerConnection.
|
|
641
|
+
* This hash contains any custom ICE/TURN server configuration.
|
|
642
|
+
*
|
|
643
|
+
* Defaults to {@apilink util.defaultConfig}
|
|
644
|
+
*/
|
|
645
|
+
config?: any;
|
|
646
|
+
/**
|
|
647
|
+
* Set to true `true` if you're using TLS.
|
|
648
|
+
* :::danger
|
|
649
|
+
* If possible *always use TLS*
|
|
650
|
+
* :::
|
|
651
|
+
*/
|
|
652
|
+
secure?: boolean;
|
|
653
|
+
pingInterval?: number;
|
|
654
|
+
referrerPolicy?: ReferrerPolicy;
|
|
655
|
+
logFunction?: (logLevel: LogLevel, ...rest: any[]) => void;
|
|
656
|
+
serializers?: SerializerMapping;
|
|
657
|
+
/** Auto-fetch TURN credentials from the signaling server's GET /turn endpoint. */
|
|
658
|
+
fetchTurnCredentials?: boolean;
|
|
659
|
+
/** Optional JWT for authenticated connections. */
|
|
660
|
+
jwt?: string;
|
|
661
|
+
/** Enable WebSocket relay fallback when WebRTC is unavailable. */
|
|
662
|
+
enableRelay?: boolean;
|
|
663
|
+
/** Optional function to validate connection metadata before accepting. */
|
|
664
|
+
validateMetadata?: (metadata: unknown) => boolean;
|
|
665
|
+
/** Signaling transport: 'websocket' (default), 'sse', 'polling', or 'auto' (tries WS then SSE then polling) */
|
|
666
|
+
signalingTransport?: "websocket" | "sse" | "polling" | "auto";
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
interface SerializerMapping {
|
|
670
|
+
[key: string]: new (peerId: string, provider: Dendri, options: any) => DataConnection;
|
|
671
|
+
}
|
|
672
|
+
interface DendriEvents {
|
|
673
|
+
/**
|
|
674
|
+
* Emitted when a connection to the Dendri server is established.
|
|
675
|
+
*
|
|
676
|
+
* You may use the peer before this is emitted, but messages to the server will be queued. <code>id</code> is the brokering ID of the peer (which was either provided in the constructor or assigned by the server).<span class='tip'>You should not wait for this event before connecting to other peers if connection speed is important.</span>
|
|
677
|
+
*/
|
|
678
|
+
open: (id: string) => void;
|
|
679
|
+
/**
|
|
680
|
+
* Emitted when a new data connection is established from a remote peer.
|
|
681
|
+
*/
|
|
682
|
+
connection: (dataConnection: DataConnection) => void;
|
|
683
|
+
/**
|
|
684
|
+
* Emitted when a remote peer attempts to call you.
|
|
685
|
+
*/
|
|
686
|
+
call: (mediaConnection: MediaConnection) => void;
|
|
687
|
+
/**
|
|
688
|
+
* Emitted when the peer is destroyed and can no longer accept or create any new connections.
|
|
689
|
+
*/
|
|
690
|
+
close: () => void;
|
|
691
|
+
/**
|
|
692
|
+
* Emitted when the peer is disconnected from the signalling server
|
|
693
|
+
*/
|
|
694
|
+
disconnected: (currentId: string) => void;
|
|
695
|
+
/**
|
|
696
|
+
* Errors on the peer are almost always fatal and will destroy the peer.
|
|
697
|
+
*
|
|
698
|
+
* Errors from the underlying socket and PeerConnections are forwarded here.
|
|
699
|
+
*/
|
|
700
|
+
error: (error: DendriError<`${DendriErrorType}`>) => void;
|
|
701
|
+
/**
|
|
702
|
+
* Emitted when the server sends a ROOM_PEERS message with the current
|
|
703
|
+
* list of peers in a room.
|
|
704
|
+
*/
|
|
705
|
+
roomPeers: (room: string, peers: string[]) => void;
|
|
706
|
+
/**
|
|
707
|
+
* Emitted when the connection state machine transitions to a new state.
|
|
708
|
+
*/
|
|
709
|
+
connectionStateChanged: (state: ConnectionState, previousState: ConnectionState) => void;
|
|
710
|
+
/**
|
|
711
|
+
* Emitted when a PRESENCE_UPDATE message is received from the server.
|
|
712
|
+
*/
|
|
713
|
+
presenceUpdate: (peerId: string, room: string, data: unknown) => void;
|
|
714
|
+
/**
|
|
715
|
+
* Emitted when the underlying signaling socket finishes a successful
|
|
716
|
+
* reconnection. Consumers (e.g. Room) should re-send server-side
|
|
717
|
+
* state (joinRoom, presence) so it survives server-side state loss
|
|
718
|
+
* such as a Durable Object hibernation + wake-up cycle.
|
|
719
|
+
*/
|
|
720
|
+
reconnected: () => void;
|
|
721
|
+
}
|
|
722
|
+
/**
|
|
723
|
+
* A peer who can initiate connections with other peers.
|
|
724
|
+
*/
|
|
725
|
+
declare class Dendri extends EventEmitterWithError<DendriErrorType, DendriEvents> {
|
|
726
|
+
private static readonly DEFAULT_KEY;
|
|
727
|
+
protected readonly _serializers: SerializerMapping;
|
|
728
|
+
private readonly _options;
|
|
729
|
+
private readonly _api;
|
|
730
|
+
private readonly _socket;
|
|
731
|
+
private _id;
|
|
732
|
+
private _lastServerId;
|
|
733
|
+
private _connectionState;
|
|
734
|
+
/** Number of consecutive reconnection failures that triggers the Suspended state. */
|
|
735
|
+
private static readonly SUSPEND_THRESHOLD;
|
|
736
|
+
private readonly _connections;
|
|
737
|
+
private readonly _lostMessages;
|
|
738
|
+
private readonly _lostMessageGeneration;
|
|
739
|
+
private readonly _hybridConnections;
|
|
740
|
+
/**
|
|
741
|
+
* The brokering ID of this peer
|
|
742
|
+
*
|
|
743
|
+
* If no ID was specified in {@apilink Dendri | the constructor},
|
|
744
|
+
* this will be `undefined` until the {@apilink DendriEvents | `open`} event is emitted.
|
|
745
|
+
*/
|
|
746
|
+
get id(): string | null;
|
|
747
|
+
get options(): DendriOptions;
|
|
748
|
+
/**
|
|
749
|
+
* The current connection state of this peer.
|
|
750
|
+
*/
|
|
751
|
+
get connectionState(): ConnectionState;
|
|
752
|
+
get open(): boolean;
|
|
753
|
+
/**
|
|
754
|
+
* @internal
|
|
755
|
+
*/
|
|
756
|
+
get socket(): SignalingTransport;
|
|
757
|
+
/**
|
|
758
|
+
* A hash of all connections associated with this peer, keyed by the remote peer's ID.
|
|
759
|
+
* @deprecated
|
|
760
|
+
* Return type will change from Object to Map<string,[]>
|
|
761
|
+
*/
|
|
762
|
+
get connections(): Object;
|
|
763
|
+
/**
|
|
764
|
+
* true if this peer and all of its connections can no longer be used.
|
|
765
|
+
*/
|
|
766
|
+
get destroyed(): boolean;
|
|
767
|
+
/**
|
|
768
|
+
* false if there is an active connection to the Dendri server.
|
|
769
|
+
*
|
|
770
|
+
* Also returns true for terminal states (Closed/Failed) to preserve
|
|
771
|
+
* backward compatibility: the original boolean was set during
|
|
772
|
+
* disconnect() and never cleared by destroy().
|
|
773
|
+
*/
|
|
774
|
+
get disconnected(): boolean;
|
|
775
|
+
/**
|
|
776
|
+
* A peer can connect to other peers and listen for connections.
|
|
777
|
+
*/
|
|
778
|
+
constructor(options: DendriOptions);
|
|
779
|
+
/**
|
|
780
|
+
* A peer can connect to other peers and listen for connections.
|
|
781
|
+
* @param id Other peers can connect to this peer using the provided ID.
|
|
782
|
+
* If no ID is given, one will be generated by the brokering server.
|
|
783
|
+
* The ID must start and end with an alphanumeric character (lower or upper case character or a digit). In the middle of the ID spaces, dashes (-) and underscores (_) are allowed. Use {@apilink DendriOptions.metadata } to send identifying information.
|
|
784
|
+
* @param options for specifying details about Dendri server
|
|
785
|
+
*/
|
|
786
|
+
constructor(id: string, options?: DendriOptions);
|
|
787
|
+
/**
|
|
788
|
+
* Transition to a new connection state. Invalid transitions are logged and ignored.
|
|
789
|
+
*/
|
|
790
|
+
private _setState;
|
|
791
|
+
private static _isValidTransition;
|
|
792
|
+
private _createServerConnection;
|
|
793
|
+
/** Initialize a connection with the server. */
|
|
794
|
+
private _initialize;
|
|
795
|
+
/** Handles messages from the server. */
|
|
796
|
+
private _handleMessage;
|
|
797
|
+
private static readonly MAX_LOST_MESSAGES;
|
|
798
|
+
private static readonly LOST_MESSAGE_TTL;
|
|
799
|
+
/** Stores messages without a set up connection, to be claimed later. */
|
|
800
|
+
private _storeMessage;
|
|
801
|
+
/**
|
|
802
|
+
* Retrieve messages from lost message store
|
|
803
|
+
* @internal
|
|
804
|
+
*/
|
|
805
|
+
_getMessages(connectionId: string): ServerMessage[];
|
|
806
|
+
/**
|
|
807
|
+
* Connects to the remote peer specified by id and returns a data connection.
|
|
808
|
+
* @param peer The brokering ID of the remote peer (their {@apilink Dendri.id}).
|
|
809
|
+
* @param options for specifying details about the data connection
|
|
810
|
+
*/
|
|
811
|
+
connect(peer: string, options?: DendriConnectOption): DataConnection | undefined;
|
|
812
|
+
/**
|
|
813
|
+
* Calls the remote peer specified by id and returns a media connection.
|
|
814
|
+
* @param peer The brokering ID of the remote peer (their peer.id).
|
|
815
|
+
* @param stream The caller's media stream
|
|
816
|
+
* @param options Metadata associated with the connection, passed in by whoever initiated the connection.
|
|
817
|
+
*/
|
|
818
|
+
call(peer: string, stream: MediaStream, options?: CallOption): MediaConnection | undefined;
|
|
819
|
+
/**
|
|
820
|
+
* Create a hybrid connection that uses WebRTC when possible
|
|
821
|
+
* and transparently falls back to WebSocket relay.
|
|
822
|
+
*
|
|
823
|
+
* @param peer The brokering ID of the remote peer.
|
|
824
|
+
* @param options HybridConnection-specific options (ICE timeout, upgrade behaviour, etc.)
|
|
825
|
+
*/
|
|
826
|
+
connectHybrid(peer: string, options?: HybridConnectionOption): HybridConnection | undefined;
|
|
827
|
+
/**
|
|
828
|
+
* Join a room on the signaling server.
|
|
829
|
+
* The server will respond with a ROOM_PEERS message listing current members.
|
|
830
|
+
*/
|
|
831
|
+
joinRoom(roomName: string): void;
|
|
832
|
+
/**
|
|
833
|
+
* Leave a room on the signaling server.
|
|
834
|
+
*/
|
|
835
|
+
leaveRoom(roomName: string): void;
|
|
836
|
+
/** Auto-fetch TURN credentials when the option is enabled. */
|
|
837
|
+
private _fetchTurnIfEnabled;
|
|
838
|
+
/** Add a data/media connection to this peer. */
|
|
839
|
+
private _addConnection;
|
|
840
|
+
_removeConnection(connection: DataConnection | MediaConnection): void;
|
|
841
|
+
/** Retrieve a data/media connection for this peer. */
|
|
842
|
+
getConnection(peerId: string, connectionId: string): null | DataConnection | MediaConnection;
|
|
843
|
+
/** Error types that indicate an unrecoverable problem. */
|
|
844
|
+
private static readonly FATAL_ERROR_TYPES;
|
|
845
|
+
private _delayedAbort;
|
|
846
|
+
/**
|
|
847
|
+
* Emits an error message and destroys the Dendri instance.
|
|
848
|
+
* The Dendri instance is not destroyed if it's in a disconnected state, in which case
|
|
849
|
+
* it retains its disconnected state and its existing connections.
|
|
850
|
+
*/
|
|
851
|
+
private _abort;
|
|
852
|
+
/**
|
|
853
|
+
* Destroys the Dendri instance: closes all active connections as well as the connection
|
|
854
|
+
* to the server.
|
|
855
|
+
*
|
|
856
|
+
* :::caution
|
|
857
|
+
* This cannot be undone; the respective peer object will no longer be able
|
|
858
|
+
* to create or receive any connections, its ID will be forfeited on the server,
|
|
859
|
+
* and all of its data and media connections will be closed.
|
|
860
|
+
* :::
|
|
861
|
+
*/
|
|
862
|
+
destroy(): void;
|
|
863
|
+
/** Internal destroy that transitions to the given terminal state. */
|
|
864
|
+
private _destroyWithState;
|
|
865
|
+
/** Disconnects every connection on this peer. */
|
|
866
|
+
private _cleanup;
|
|
867
|
+
/** Closes all connections to this peer. */
|
|
868
|
+
private _cleanupPeer;
|
|
869
|
+
/**
|
|
870
|
+
* Disconnects the Dendri instance's connection to the Dendri server. Does not close any
|
|
871
|
+
* active connections.
|
|
872
|
+
* Warning: The peer can no longer create or accept connections after being
|
|
873
|
+
* disconnected. It also cannot reconnect to the server.
|
|
874
|
+
*/
|
|
875
|
+
disconnect(): void;
|
|
876
|
+
/** Attempts to reconnect with the same ID.
|
|
877
|
+
*
|
|
878
|
+
* Only {@apilink Dendri.disconnect | disconnected peers} can be reconnected.
|
|
879
|
+
* Destroyed peers cannot be reconnected.
|
|
880
|
+
* If the connection fails (as an example, if the peer's old ID is now taken),
|
|
881
|
+
* the peer's existing connections will not close, but any associated errors events will fire.
|
|
882
|
+
*/
|
|
883
|
+
reconnect(): void;
|
|
884
|
+
/**
|
|
885
|
+
* Get a list of available peer IDs. If you're running your own server, you'll
|
|
886
|
+
* want to set allow_discovery: true in the Dendri server options.
|
|
887
|
+
*/
|
|
888
|
+
listAllPeers(cb?: (_: any[]) => void): void;
|
|
889
|
+
/** Returns a snapshot of the current connection state for debugging. */
|
|
890
|
+
diagnostics(): {
|
|
891
|
+
peerId: string | null;
|
|
892
|
+
connectionState: ConnectionState;
|
|
893
|
+
serverConnected: boolean;
|
|
894
|
+
connections: Array<{
|
|
895
|
+
peerId: string;
|
|
896
|
+
type: string;
|
|
897
|
+
open: boolean;
|
|
898
|
+
}>;
|
|
899
|
+
hybridConnections: Array<{
|
|
900
|
+
peerId: string;
|
|
901
|
+
mode: TransportMode;
|
|
902
|
+
open: boolean;
|
|
903
|
+
}>;
|
|
904
|
+
socket: {
|
|
905
|
+
connected: boolean;
|
|
906
|
+
autoReconnect: boolean;
|
|
907
|
+
reconnectAttempt: number;
|
|
908
|
+
lastSeq: number;
|
|
909
|
+
};
|
|
910
|
+
pendingMessages: number;
|
|
911
|
+
};
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
declare abstract class StreamConnection extends DataConnection {
|
|
915
|
+
private _CHUNK_SIZE;
|
|
916
|
+
private _splitStream;
|
|
917
|
+
private _rawSendStream;
|
|
918
|
+
protected writer: WritableStreamDefaultWriter<Uint8Array<ArrayBufferLike>>;
|
|
919
|
+
private _readStreamMessageHandler;
|
|
920
|
+
private _readStreamController;
|
|
921
|
+
protected _rawReadStream: ReadableStream<ArrayBuffer>;
|
|
922
|
+
protected constructor(peerId: string, provider: Dendri, options: any);
|
|
923
|
+
_initializeDataChannel(dc: RTCDataChannel): void;
|
|
924
|
+
close(options?: {
|
|
925
|
+
flush?: boolean;
|
|
926
|
+
}): void;
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
declare class MsgPack extends StreamConnection {
|
|
930
|
+
readonly serialization = "MsgPack";
|
|
931
|
+
private _encoder;
|
|
932
|
+
constructor(peerId: string, provider: Dendri, options: any);
|
|
933
|
+
protected _send(data: unknown): Promise<void>;
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
export { MsgPack };
|