@xtr-dev/rondevu-client 0.8.3 → 0.9.2
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/README.md +402 -436
- package/dist/durable/channel.d.ts +115 -0
- package/dist/durable/channel.js +301 -0
- package/dist/durable/connection.d.ts +125 -0
- package/dist/durable/connection.js +370 -0
- package/dist/durable/reconnection.d.ts +90 -0
- package/dist/durable/reconnection.js +127 -0
- package/dist/durable/service.d.ts +103 -0
- package/dist/durable/service.js +264 -0
- package/dist/durable/types.d.ts +149 -0
- package/dist/durable/types.js +28 -0
- package/dist/index.d.ts +5 -10
- package/dist/index.js +5 -9
- package/dist/offer-pool.d.ts +15 -3
- package/dist/offer-pool.js +34 -8
- package/dist/peer/exchanging-ice-state.js +10 -2
- package/dist/peer/index.d.ts +1 -1
- package/dist/peer/index.js +25 -3
- package/dist/peer/state.js +9 -1
- package/dist/rondevu.d.ts +88 -13
- package/dist/rondevu.js +110 -27
- package/dist/service-pool.d.ts +11 -3
- package/dist/service-pool.js +193 -44
- package/package.json +2 -2
- package/dist/bloom.d.ts +0 -30
- package/dist/bloom.js +0 -73
- package/dist/client.d.ts +0 -126
- package/dist/client.js +0 -171
- package/dist/connection.d.ts +0 -127
- package/dist/connection.js +0 -295
- package/dist/discovery.d.ts +0 -93
- package/dist/discovery.js +0 -164
- package/dist/peer.d.ts +0 -111
- package/dist/peer.js +0 -392
- package/dist/services.d.ts +0 -79
- package/dist/services.js +0 -206
- package/dist/types.d.ts +0 -157
- package/dist/types.js +0 -4
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DurableChannel - Message queueing wrapper for RTCDataChannel
|
|
3
|
+
*
|
|
4
|
+
* Provides automatic message queuing during disconnections and transparent
|
|
5
|
+
* flushing when the connection is re-established.
|
|
6
|
+
*/
|
|
7
|
+
import { EventEmitter } from '../event-emitter.js';
|
|
8
|
+
import { DurableChannelState } from './types.js';
|
|
9
|
+
import type { DurableChannelConfig, DurableChannelEvents } from './types.js';
|
|
10
|
+
/**
|
|
11
|
+
* Durable channel that survives WebRTC peer connection drops
|
|
12
|
+
*
|
|
13
|
+
* The DurableChannel wraps an RTCDataChannel and provides:
|
|
14
|
+
* - Automatic message queuing during disconnections
|
|
15
|
+
* - Queue flushing on reconnection
|
|
16
|
+
* - Configurable queue size and message age limits
|
|
17
|
+
* - RTCDataChannel-compatible API
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* const channel = new DurableChannel('chat', connection, {
|
|
22
|
+
* maxQueueSize: 500,
|
|
23
|
+
* maxMessageAge: 30000
|
|
24
|
+
* });
|
|
25
|
+
*
|
|
26
|
+
* channel.on('message', (data) => {
|
|
27
|
+
* console.log('Received:', data);
|
|
28
|
+
* });
|
|
29
|
+
*
|
|
30
|
+
* channel.on('open', () => {
|
|
31
|
+
* channel.send('Hello!');
|
|
32
|
+
* });
|
|
33
|
+
*
|
|
34
|
+
* // Messages sent during disconnection are automatically queued
|
|
35
|
+
* channel.send('This will be queued if disconnected');
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export declare class DurableChannel extends EventEmitter<DurableChannelEvents> {
|
|
39
|
+
readonly label: string;
|
|
40
|
+
readonly config: DurableChannelConfig;
|
|
41
|
+
private _state;
|
|
42
|
+
private underlyingChannel?;
|
|
43
|
+
private messageQueue;
|
|
44
|
+
private queueProcessing;
|
|
45
|
+
private _bufferedAmountLowThreshold;
|
|
46
|
+
private openHandler?;
|
|
47
|
+
private messageHandler?;
|
|
48
|
+
private errorHandler?;
|
|
49
|
+
private closeHandler?;
|
|
50
|
+
private bufferedAmountLowHandler?;
|
|
51
|
+
constructor(label: string, config?: DurableChannelConfig);
|
|
52
|
+
/**
|
|
53
|
+
* Current channel state
|
|
54
|
+
*/
|
|
55
|
+
get readyState(): DurableChannelState;
|
|
56
|
+
/**
|
|
57
|
+
* Buffered amount from underlying channel (0 if no channel)
|
|
58
|
+
*/
|
|
59
|
+
get bufferedAmount(): number;
|
|
60
|
+
/**
|
|
61
|
+
* Buffered amount low threshold
|
|
62
|
+
*/
|
|
63
|
+
get bufferedAmountLowThreshold(): number;
|
|
64
|
+
set bufferedAmountLowThreshold(value: number);
|
|
65
|
+
/**
|
|
66
|
+
* Send data through the channel
|
|
67
|
+
*
|
|
68
|
+
* If the channel is open, sends immediately. Otherwise, queues the message
|
|
69
|
+
* for delivery when the channel reconnects.
|
|
70
|
+
*
|
|
71
|
+
* @param data - Data to send
|
|
72
|
+
*/
|
|
73
|
+
send(data: string | Blob | ArrayBuffer | ArrayBufferView): void;
|
|
74
|
+
/**
|
|
75
|
+
* Close the channel
|
|
76
|
+
*/
|
|
77
|
+
close(): void;
|
|
78
|
+
/**
|
|
79
|
+
* Attach to an underlying RTCDataChannel
|
|
80
|
+
*
|
|
81
|
+
* This is called when a WebRTC connection is established (or re-established).
|
|
82
|
+
* The channel will flush any queued messages and forward events.
|
|
83
|
+
*
|
|
84
|
+
* @param channel - RTCDataChannel to attach to
|
|
85
|
+
* @internal
|
|
86
|
+
*/
|
|
87
|
+
attachToChannel(channel: RTCDataChannel): void;
|
|
88
|
+
/**
|
|
89
|
+
* Detach from the underlying RTCDataChannel
|
|
90
|
+
*
|
|
91
|
+
* This is called when a WebRTC connection drops. The channel remains alive
|
|
92
|
+
* and continues queuing messages.
|
|
93
|
+
*
|
|
94
|
+
* @internal
|
|
95
|
+
*/
|
|
96
|
+
detachFromChannel(): void;
|
|
97
|
+
/**
|
|
98
|
+
* Enqueue a message for later delivery
|
|
99
|
+
*/
|
|
100
|
+
private enqueueMessage;
|
|
101
|
+
/**
|
|
102
|
+
* Flush all queued messages through the channel
|
|
103
|
+
*/
|
|
104
|
+
private flushQueue;
|
|
105
|
+
/**
|
|
106
|
+
* Remove messages older than maxMessageAge from the queue
|
|
107
|
+
*/
|
|
108
|
+
private pruneOldMessages;
|
|
109
|
+
/**
|
|
110
|
+
* Get the current queue size
|
|
111
|
+
*
|
|
112
|
+
* @internal
|
|
113
|
+
*/
|
|
114
|
+
getQueueSize(): number;
|
|
115
|
+
}
|
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DurableChannel - Message queueing wrapper for RTCDataChannel
|
|
3
|
+
*
|
|
4
|
+
* Provides automatic message queuing during disconnections and transparent
|
|
5
|
+
* flushing when the connection is re-established.
|
|
6
|
+
*/
|
|
7
|
+
import { EventEmitter } from '../event-emitter.js';
|
|
8
|
+
import { DurableChannelState } from './types.js';
|
|
9
|
+
/**
|
|
10
|
+
* Default configuration for durable channels
|
|
11
|
+
*/
|
|
12
|
+
const DEFAULT_CONFIG = {
|
|
13
|
+
maxQueueSize: 1000,
|
|
14
|
+
maxMessageAge: 60000, // 1 minute
|
|
15
|
+
ordered: true,
|
|
16
|
+
maxRetransmits: undefined
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Durable channel that survives WebRTC peer connection drops
|
|
20
|
+
*
|
|
21
|
+
* The DurableChannel wraps an RTCDataChannel and provides:
|
|
22
|
+
* - Automatic message queuing during disconnections
|
|
23
|
+
* - Queue flushing on reconnection
|
|
24
|
+
* - Configurable queue size and message age limits
|
|
25
|
+
* - RTCDataChannel-compatible API
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```typescript
|
|
29
|
+
* const channel = new DurableChannel('chat', connection, {
|
|
30
|
+
* maxQueueSize: 500,
|
|
31
|
+
* maxMessageAge: 30000
|
|
32
|
+
* });
|
|
33
|
+
*
|
|
34
|
+
* channel.on('message', (data) => {
|
|
35
|
+
* console.log('Received:', data);
|
|
36
|
+
* });
|
|
37
|
+
*
|
|
38
|
+
* channel.on('open', () => {
|
|
39
|
+
* channel.send('Hello!');
|
|
40
|
+
* });
|
|
41
|
+
*
|
|
42
|
+
* // Messages sent during disconnection are automatically queued
|
|
43
|
+
* channel.send('This will be queued if disconnected');
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export class DurableChannel extends EventEmitter {
|
|
47
|
+
constructor(label, config) {
|
|
48
|
+
super();
|
|
49
|
+
this.messageQueue = [];
|
|
50
|
+
this.queueProcessing = false;
|
|
51
|
+
this._bufferedAmountLowThreshold = 0;
|
|
52
|
+
this.label = label;
|
|
53
|
+
this.config = { ...DEFAULT_CONFIG, ...config };
|
|
54
|
+
this._state = DurableChannelState.CONNECTING;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Current channel state
|
|
58
|
+
*/
|
|
59
|
+
get readyState() {
|
|
60
|
+
return this._state;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Buffered amount from underlying channel (0 if no channel)
|
|
64
|
+
*/
|
|
65
|
+
get bufferedAmount() {
|
|
66
|
+
return this.underlyingChannel?.bufferedAmount ?? 0;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Buffered amount low threshold
|
|
70
|
+
*/
|
|
71
|
+
get bufferedAmountLowThreshold() {
|
|
72
|
+
return this._bufferedAmountLowThreshold;
|
|
73
|
+
}
|
|
74
|
+
set bufferedAmountLowThreshold(value) {
|
|
75
|
+
this._bufferedAmountLowThreshold = value;
|
|
76
|
+
if (this.underlyingChannel) {
|
|
77
|
+
this.underlyingChannel.bufferedAmountLowThreshold = value;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Send data through the channel
|
|
82
|
+
*
|
|
83
|
+
* If the channel is open, sends immediately. Otherwise, queues the message
|
|
84
|
+
* for delivery when the channel reconnects.
|
|
85
|
+
*
|
|
86
|
+
* @param data - Data to send
|
|
87
|
+
*/
|
|
88
|
+
send(data) {
|
|
89
|
+
if (this._state === DurableChannelState.OPEN && this.underlyingChannel) {
|
|
90
|
+
// Channel is open - send immediately
|
|
91
|
+
try {
|
|
92
|
+
this.underlyingChannel.send(data);
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
// Send failed - queue the message
|
|
96
|
+
this.enqueueMessage(data);
|
|
97
|
+
this.emit('error', error);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
else if (this._state !== DurableChannelState.CLOSED) {
|
|
101
|
+
// Channel is not open but not closed - queue the message
|
|
102
|
+
this.enqueueMessage(data);
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
// Channel is closed - throw error
|
|
106
|
+
throw new Error('Cannot send on closed channel');
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Close the channel
|
|
111
|
+
*/
|
|
112
|
+
close() {
|
|
113
|
+
if (this._state === DurableChannelState.CLOSED ||
|
|
114
|
+
this._state === DurableChannelState.CLOSING) {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
this._state = DurableChannelState.CLOSING;
|
|
118
|
+
if (this.underlyingChannel) {
|
|
119
|
+
this.underlyingChannel.close();
|
|
120
|
+
}
|
|
121
|
+
this._state = DurableChannelState.CLOSED;
|
|
122
|
+
this.emit('close');
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Attach to an underlying RTCDataChannel
|
|
126
|
+
*
|
|
127
|
+
* This is called when a WebRTC connection is established (or re-established).
|
|
128
|
+
* The channel will flush any queued messages and forward events.
|
|
129
|
+
*
|
|
130
|
+
* @param channel - RTCDataChannel to attach to
|
|
131
|
+
* @internal
|
|
132
|
+
*/
|
|
133
|
+
attachToChannel(channel) {
|
|
134
|
+
// Detach from any existing channel first
|
|
135
|
+
this.detachFromChannel();
|
|
136
|
+
this.underlyingChannel = channel;
|
|
137
|
+
// Set buffered amount low threshold
|
|
138
|
+
channel.bufferedAmountLowThreshold = this._bufferedAmountLowThreshold;
|
|
139
|
+
// Setup event handlers
|
|
140
|
+
this.openHandler = () => {
|
|
141
|
+
this._state = DurableChannelState.OPEN;
|
|
142
|
+
this.emit('open');
|
|
143
|
+
// Flush queued messages
|
|
144
|
+
this.flushQueue().catch(error => {
|
|
145
|
+
this.emit('error', error);
|
|
146
|
+
});
|
|
147
|
+
};
|
|
148
|
+
this.messageHandler = (event) => {
|
|
149
|
+
this.emit('message', event.data);
|
|
150
|
+
};
|
|
151
|
+
this.errorHandler = (event) => {
|
|
152
|
+
this.emit('error', new Error(`Channel error: ${event.type}`));
|
|
153
|
+
};
|
|
154
|
+
this.closeHandler = () => {
|
|
155
|
+
if (this._state !== DurableChannelState.CLOSING &&
|
|
156
|
+
this._state !== DurableChannelState.CLOSED) {
|
|
157
|
+
// Unexpected close - transition to connecting (will reconnect)
|
|
158
|
+
this._state = DurableChannelState.CONNECTING;
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
this.bufferedAmountLowHandler = () => {
|
|
162
|
+
this.emit('bufferedAmountLow');
|
|
163
|
+
};
|
|
164
|
+
// Attach handlers
|
|
165
|
+
channel.addEventListener('open', this.openHandler);
|
|
166
|
+
channel.addEventListener('message', this.messageHandler);
|
|
167
|
+
channel.addEventListener('error', this.errorHandler);
|
|
168
|
+
channel.addEventListener('close', this.closeHandler);
|
|
169
|
+
channel.addEventListener('bufferedamountlow', this.bufferedAmountLowHandler);
|
|
170
|
+
// If channel is already open, trigger open event
|
|
171
|
+
if (channel.readyState === 'open') {
|
|
172
|
+
this.openHandler();
|
|
173
|
+
}
|
|
174
|
+
else if (channel.readyState === 'connecting') {
|
|
175
|
+
this._state = DurableChannelState.CONNECTING;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Detach from the underlying RTCDataChannel
|
|
180
|
+
*
|
|
181
|
+
* This is called when a WebRTC connection drops. The channel remains alive
|
|
182
|
+
* and continues queuing messages.
|
|
183
|
+
*
|
|
184
|
+
* @internal
|
|
185
|
+
*/
|
|
186
|
+
detachFromChannel() {
|
|
187
|
+
if (!this.underlyingChannel) {
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
// Remove event listeners
|
|
191
|
+
if (this.openHandler) {
|
|
192
|
+
this.underlyingChannel.removeEventListener('open', this.openHandler);
|
|
193
|
+
}
|
|
194
|
+
if (this.messageHandler) {
|
|
195
|
+
this.underlyingChannel.removeEventListener('message', this.messageHandler);
|
|
196
|
+
}
|
|
197
|
+
if (this.errorHandler) {
|
|
198
|
+
this.underlyingChannel.removeEventListener('error', this.errorHandler);
|
|
199
|
+
}
|
|
200
|
+
if (this.closeHandler) {
|
|
201
|
+
this.underlyingChannel.removeEventListener('close', this.closeHandler);
|
|
202
|
+
}
|
|
203
|
+
if (this.bufferedAmountLowHandler) {
|
|
204
|
+
this.underlyingChannel.removeEventListener('bufferedamountlow', this.bufferedAmountLowHandler);
|
|
205
|
+
}
|
|
206
|
+
this.underlyingChannel = undefined;
|
|
207
|
+
this._state = DurableChannelState.CONNECTING;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Enqueue a message for later delivery
|
|
211
|
+
*/
|
|
212
|
+
enqueueMessage(data) {
|
|
213
|
+
// Prune old messages first
|
|
214
|
+
this.pruneOldMessages();
|
|
215
|
+
const message = {
|
|
216
|
+
data,
|
|
217
|
+
enqueuedAt: Date.now(),
|
|
218
|
+
id: `msg-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`
|
|
219
|
+
};
|
|
220
|
+
this.messageQueue.push(message);
|
|
221
|
+
// Handle overflow
|
|
222
|
+
const maxQueueSize = this.config.maxQueueSize ?? 1000;
|
|
223
|
+
if (this.messageQueue.length > maxQueueSize) {
|
|
224
|
+
const excess = this.messageQueue.length - maxQueueSize;
|
|
225
|
+
this.messageQueue.splice(0, excess);
|
|
226
|
+
this.emit('queueOverflow', excess);
|
|
227
|
+
console.warn(`DurableChannel[${this.label}]: Dropped ${excess} messages due to queue overflow`);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Flush all queued messages through the channel
|
|
232
|
+
*/
|
|
233
|
+
async flushQueue() {
|
|
234
|
+
if (this.queueProcessing || !this.underlyingChannel ||
|
|
235
|
+
this.underlyingChannel.readyState !== 'open') {
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
this.queueProcessing = true;
|
|
239
|
+
try {
|
|
240
|
+
// Prune old messages before flushing
|
|
241
|
+
this.pruneOldMessages();
|
|
242
|
+
// Send all queued messages
|
|
243
|
+
while (this.messageQueue.length > 0) {
|
|
244
|
+
const message = this.messageQueue.shift();
|
|
245
|
+
if (!message)
|
|
246
|
+
break;
|
|
247
|
+
try {
|
|
248
|
+
this.underlyingChannel.send(message.data);
|
|
249
|
+
}
|
|
250
|
+
catch (error) {
|
|
251
|
+
// Send failed - re-queue message
|
|
252
|
+
this.messageQueue.unshift(message);
|
|
253
|
+
throw error;
|
|
254
|
+
}
|
|
255
|
+
// If buffer is getting full, wait for it to drain
|
|
256
|
+
if (this.underlyingChannel.bufferedAmount > 16 * 1024 * 1024) { // 16MB
|
|
257
|
+
await new Promise((resolve) => {
|
|
258
|
+
const checkBuffer = () => {
|
|
259
|
+
if (!this.underlyingChannel ||
|
|
260
|
+
this.underlyingChannel.bufferedAmount < 8 * 1024 * 1024) {
|
|
261
|
+
resolve();
|
|
262
|
+
}
|
|
263
|
+
else {
|
|
264
|
+
setTimeout(checkBuffer, 100);
|
|
265
|
+
}
|
|
266
|
+
};
|
|
267
|
+
checkBuffer();
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
finally {
|
|
273
|
+
this.queueProcessing = false;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Remove messages older than maxMessageAge from the queue
|
|
278
|
+
*/
|
|
279
|
+
pruneOldMessages() {
|
|
280
|
+
const maxMessageAge = this.config.maxMessageAge ?? 60000;
|
|
281
|
+
if (maxMessageAge === Infinity || maxMessageAge <= 0) {
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
const now = Date.now();
|
|
285
|
+
const cutoff = now - maxMessageAge;
|
|
286
|
+
const originalLength = this.messageQueue.length;
|
|
287
|
+
this.messageQueue = this.messageQueue.filter(msg => msg.enqueuedAt >= cutoff);
|
|
288
|
+
const pruned = originalLength - this.messageQueue.length;
|
|
289
|
+
if (pruned > 0) {
|
|
290
|
+
console.warn(`DurableChannel[${this.label}]: Pruned ${pruned} old messages (older than ${maxMessageAge}ms)`);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Get the current queue size
|
|
295
|
+
*
|
|
296
|
+
* @internal
|
|
297
|
+
*/
|
|
298
|
+
getQueueSize() {
|
|
299
|
+
return this.messageQueue.length;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DurableConnection - WebRTC connection with automatic reconnection
|
|
3
|
+
*
|
|
4
|
+
* Manages the WebRTC peer lifecycle and automatically reconnects on
|
|
5
|
+
* connection drops with exponential backoff.
|
|
6
|
+
*/
|
|
7
|
+
import { EventEmitter } from '../event-emitter.js';
|
|
8
|
+
import type { RondevuOffers } from '../offers.js';
|
|
9
|
+
import { DurableChannel } from './channel.js';
|
|
10
|
+
import { DurableConnectionState } from './types.js';
|
|
11
|
+
import type { DurableConnectionConfig, DurableConnectionEvents, ConnectionInfo } from './types.js';
|
|
12
|
+
/**
|
|
13
|
+
* Durable WebRTC connection that automatically reconnects
|
|
14
|
+
*
|
|
15
|
+
* The DurableConnection manages the lifecycle of a WebRTC peer connection
|
|
16
|
+
* and provides:
|
|
17
|
+
* - Automatic reconnection with exponential backoff
|
|
18
|
+
* - Multiple durable channels that survive reconnections
|
|
19
|
+
* - Configurable retry limits and timeouts
|
|
20
|
+
* - High-level connection state events
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```typescript
|
|
24
|
+
* const connection = new DurableConnection(
|
|
25
|
+
* offersApi,
|
|
26
|
+
* { username: 'alice', serviceFqn: 'chat@1.0.0' },
|
|
27
|
+
* { maxReconnectAttempts: 5 }
|
|
28
|
+
* );
|
|
29
|
+
*
|
|
30
|
+
* connection.on('connected', () => {
|
|
31
|
+
* console.log('Connected!');
|
|
32
|
+
* });
|
|
33
|
+
*
|
|
34
|
+
* connection.on('reconnecting', (attempt, max, delay) => {
|
|
35
|
+
* console.log(`Reconnecting... (${attempt}/${max}, retry in ${delay}ms)`);
|
|
36
|
+
* });
|
|
37
|
+
*
|
|
38
|
+
* const channel = connection.createChannel('chat');
|
|
39
|
+
* channel.on('message', (data) => {
|
|
40
|
+
* console.log('Received:', data);
|
|
41
|
+
* });
|
|
42
|
+
*
|
|
43
|
+
* await connection.connect();
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export declare class DurableConnection extends EventEmitter<DurableConnectionEvents> {
|
|
47
|
+
private offersApi;
|
|
48
|
+
readonly connectionId: string;
|
|
49
|
+
readonly config: Required<DurableConnectionConfig>;
|
|
50
|
+
readonly connectionInfo: ConnectionInfo;
|
|
51
|
+
private _state;
|
|
52
|
+
private currentPeer?;
|
|
53
|
+
private channels;
|
|
54
|
+
private reconnectionScheduler?;
|
|
55
|
+
private peerConnectedHandler?;
|
|
56
|
+
private peerDisconnectedHandler?;
|
|
57
|
+
private peerFailedHandler?;
|
|
58
|
+
private peerDataChannelHandler?;
|
|
59
|
+
constructor(offersApi: RondevuOffers, connectionInfo: ConnectionInfo, config?: DurableConnectionConfig);
|
|
60
|
+
/**
|
|
61
|
+
* Current connection state
|
|
62
|
+
*/
|
|
63
|
+
getState(): DurableConnectionState;
|
|
64
|
+
/**
|
|
65
|
+
* Check if connection is currently connected
|
|
66
|
+
*/
|
|
67
|
+
isConnected(): boolean;
|
|
68
|
+
/**
|
|
69
|
+
* Create a durable channel on this connection
|
|
70
|
+
*
|
|
71
|
+
* The channel will be created on the current peer connection if available,
|
|
72
|
+
* otherwise it will be created when the connection is established.
|
|
73
|
+
*
|
|
74
|
+
* @param label - Channel label
|
|
75
|
+
* @param options - RTCDataChannel init options
|
|
76
|
+
* @returns DurableChannel instance
|
|
77
|
+
*/
|
|
78
|
+
createChannel(label: string, options?: RTCDataChannelInit): DurableChannel;
|
|
79
|
+
/**
|
|
80
|
+
* Get an existing channel by label
|
|
81
|
+
*/
|
|
82
|
+
getChannel(label: string): DurableChannel | undefined;
|
|
83
|
+
/**
|
|
84
|
+
* Establish the initial connection
|
|
85
|
+
*
|
|
86
|
+
* @returns Promise that resolves when connected
|
|
87
|
+
*/
|
|
88
|
+
connect(): Promise<void>;
|
|
89
|
+
/**
|
|
90
|
+
* Close the connection gracefully
|
|
91
|
+
*/
|
|
92
|
+
close(): Promise<void>;
|
|
93
|
+
/**
|
|
94
|
+
* Establish a WebRTC connection
|
|
95
|
+
*/
|
|
96
|
+
private establishConnection;
|
|
97
|
+
/**
|
|
98
|
+
* Connect to a service by UUID
|
|
99
|
+
*/
|
|
100
|
+
private connectByUuid;
|
|
101
|
+
/**
|
|
102
|
+
* Connect to a service by username and service FQN
|
|
103
|
+
*/
|
|
104
|
+
private connectByService;
|
|
105
|
+
/**
|
|
106
|
+
* Wait for peer connection to establish
|
|
107
|
+
*/
|
|
108
|
+
private waitForConnection;
|
|
109
|
+
/**
|
|
110
|
+
* Setup event handlers for peer
|
|
111
|
+
*/
|
|
112
|
+
private setupPeerHandlers;
|
|
113
|
+
/**
|
|
114
|
+
* Transition to connected state
|
|
115
|
+
*/
|
|
116
|
+
private transitionToConnected;
|
|
117
|
+
/**
|
|
118
|
+
* Create underlying RTCDataChannel and attach to durable channel
|
|
119
|
+
*/
|
|
120
|
+
private createAndAttachChannel;
|
|
121
|
+
/**
|
|
122
|
+
* Handle connection disconnection
|
|
123
|
+
*/
|
|
124
|
+
private handleDisconnection;
|
|
125
|
+
}
|