@xtr-dev/rondevu-client 0.18.10 → 0.20.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +324 -47
- package/dist/{api.d.ts → api/client.d.ts} +17 -8
- package/dist/{api.js → api/client.js} +114 -81
- package/dist/{answerer-connection.d.ts → connections/answerer.d.ts} +13 -5
- package/dist/{answerer-connection.js → connections/answerer.js} +17 -32
- package/dist/{connection.d.ts → connections/base.d.ts} +26 -5
- package/dist/{connection.js → connections/base.js} +45 -4
- package/dist/{offerer-connection.d.ts → connections/offerer.d.ts} +30 -5
- package/dist/{offerer-connection.js → connections/offerer.js} +93 -32
- package/dist/core/index.d.ts +22 -0
- package/dist/core/index.js +17 -0
- package/dist/core/offer-pool.d.ts +94 -0
- package/dist/core/offer-pool.js +267 -0
- package/dist/{rondevu.d.ts → core/rondevu.d.ts} +77 -85
- package/dist/core/rondevu.js +600 -0
- package/dist/{node-crypto-adapter.d.ts → crypto/node.d.ts} +1 -1
- package/dist/{web-crypto-adapter.d.ts → crypto/web.d.ts} +1 -1
- package/dist/utils/async-lock.d.ts +42 -0
- package/dist/utils/async-lock.js +75 -0
- package/dist/{message-buffer.d.ts → utils/message-buffer.d.ts} +1 -1
- package/package.json +4 -4
- package/dist/index.d.ts +0 -13
- package/dist/index.js +0 -10
- package/dist/rondevu-signaler.d.ts +0 -112
- package/dist/rondevu-signaler.js +0 -401
- package/dist/rondevu.js +0 -847
- /package/dist/{rpc-batcher.d.ts → api/batcher.d.ts} +0 -0
- /package/dist/{rpc-batcher.js → api/batcher.js} +0 -0
- /package/dist/{connection-config.d.ts → connections/config.d.ts} +0 -0
- /package/dist/{connection-config.js → connections/config.js} +0 -0
- /package/dist/{connection-events.d.ts → connections/events.d.ts} +0 -0
- /package/dist/{connection-events.js → connections/events.js} +0 -0
- /package/dist/{types.d.ts → core/types.d.ts} +0 -0
- /package/dist/{types.js → core/types.js} +0 -0
- /package/dist/{crypto-adapter.d.ts → crypto/adapter.d.ts} +0 -0
- /package/dist/{crypto-adapter.js → crypto/adapter.js} +0 -0
- /package/dist/{node-crypto-adapter.js → crypto/node.js} +0 -0
- /package/dist/{web-crypto-adapter.js → crypto/web.js} +0 -0
- /package/dist/{exponential-backoff.d.ts → utils/exponential-backoff.d.ts} +0 -0
- /package/dist/{exponential-backoff.js → utils/exponential-backoff.js} +0 -0
- /package/dist/{message-buffer.js → utils/message-buffer.js} +0 -0
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import { RondevuAPI, Keypair, IceCandidate, BatcherOptions } from '
|
|
2
|
-
import { CryptoAdapter } from '
|
|
1
|
+
import { RondevuAPI, Keypair, IceCandidate, BatcherOptions } from '../api/client.js';
|
|
2
|
+
import { CryptoAdapter } from '../crypto/adapter.js';
|
|
3
3
|
import { EventEmitter } from 'eventemitter3';
|
|
4
|
+
import { OffererConnection } from '../connections/offerer.js';
|
|
5
|
+
import { AnswererConnection } from '../connections/answerer.js';
|
|
6
|
+
import { ConnectionConfig } from '../connections/config.js';
|
|
4
7
|
export type IceServerPreset = 'ipv4-turn' | 'hostname-turns' | 'google-stun' | 'relay-only';
|
|
5
8
|
export declare const ICE_SERVER_PRESETS: Record<IceServerPreset, RTCIceServer[]>;
|
|
6
9
|
export interface RondevuOptions {
|
|
@@ -32,6 +35,7 @@ export interface PublishServiceOptions {
|
|
|
32
35
|
maxOffers: number;
|
|
33
36
|
offerFactory?: OfferFactory;
|
|
34
37
|
ttl?: number;
|
|
38
|
+
connectionConfig?: Partial<ConnectionConfig>;
|
|
35
39
|
}
|
|
36
40
|
export interface ConnectionContext {
|
|
37
41
|
pc: RTCPeerConnection;
|
|
@@ -44,8 +48,8 @@ export interface ConnectToServiceOptions {
|
|
|
44
48
|
serviceFqn?: string;
|
|
45
49
|
service?: string;
|
|
46
50
|
username?: string;
|
|
47
|
-
onConnection?: (context: ConnectionContext) => void | Promise<void>;
|
|
48
51
|
rtcConfig?: RTCConfiguration;
|
|
52
|
+
connectionConfig?: Partial<ConnectionConfig>;
|
|
49
53
|
}
|
|
50
54
|
export interface ActiveOffer {
|
|
51
55
|
offerId: string;
|
|
@@ -101,14 +105,13 @@ export declare class ConnectionError extends RondevuError {
|
|
|
101
105
|
constructor(message: string, context?: Record<string, any>);
|
|
102
106
|
}
|
|
103
107
|
/**
|
|
104
|
-
* Rondevu - Complete WebRTC signaling client
|
|
108
|
+
* Rondevu - Complete WebRTC signaling client with durable connections
|
|
105
109
|
*
|
|
106
|
-
*
|
|
107
|
-
* -
|
|
108
|
-
* -
|
|
109
|
-
* -
|
|
110
|
-
* -
|
|
111
|
-
* - Keypair management
|
|
110
|
+
* v1.0.0 introduces breaking changes:
|
|
111
|
+
* - connectToService() now returns AnswererConnection instead of ConnectionContext
|
|
112
|
+
* - Automatic reconnection and message buffering built-in
|
|
113
|
+
* - Connection objects expose .send() method instead of raw DataChannel
|
|
114
|
+
* - Rich event system for connection lifecycle (connected, disconnected, reconnecting, etc.)
|
|
112
115
|
*
|
|
113
116
|
* @example
|
|
114
117
|
* ```typescript
|
|
@@ -119,39 +122,39 @@ export declare class ConnectionError extends RondevuError {
|
|
|
119
122
|
* iceServers: 'ipv4-turn' // Use preset: 'ipv4-turn', 'hostname-turns', 'google-stun', or 'relay-only'
|
|
120
123
|
* })
|
|
121
124
|
*
|
|
122
|
-
* // Or use custom ICE servers
|
|
123
|
-
* const rondevu2 = await Rondevu.connect({
|
|
124
|
-
* apiUrl: 'https://signal.example.com',
|
|
125
|
-
* username: 'bob',
|
|
126
|
-
* iceServers: [
|
|
127
|
-
* { urls: 'stun:stun.l.google.com:19302' },
|
|
128
|
-
* { urls: 'turn:turn.example.com:3478', username: 'user', credential: 'pass' }
|
|
129
|
-
* ]
|
|
130
|
-
* })
|
|
131
|
-
*
|
|
132
125
|
* // Publish a service with automatic offer management
|
|
133
126
|
* await rondevu.publishService({
|
|
134
127
|
* service: 'chat:2.0.0',
|
|
135
|
-
* maxOffers: 5
|
|
136
|
-
* offerFactory: async (pc) => {
|
|
137
|
-
* // pc is created by Rondevu with ICE handlers already attached
|
|
138
|
-
* const dc = pc.createDataChannel('chat')
|
|
139
|
-
* const offer = await pc.createOffer()
|
|
140
|
-
* await pc.setLocalDescription(offer)
|
|
141
|
-
* return { dc, offer }
|
|
142
|
-
* }
|
|
128
|
+
* maxOffers: 5 // Maintain up to 5 concurrent offers
|
|
143
129
|
* })
|
|
144
130
|
*
|
|
145
131
|
* // Start accepting connections (auto-fills offers and polls)
|
|
146
132
|
* await rondevu.startFilling()
|
|
147
133
|
*
|
|
148
|
-
* //
|
|
149
|
-
*
|
|
150
|
-
*
|
|
151
|
-
*
|
|
134
|
+
* // Listen for connections (v1.0.0 API)
|
|
135
|
+
* rondevu.on('connection:opened', (offerId, connection) => {
|
|
136
|
+
* connection.on('connected', () => console.log('Connected!'))
|
|
137
|
+
* connection.on('message', (data) => console.log('Received:', data))
|
|
138
|
+
* connection.send('Hello!')
|
|
139
|
+
* })
|
|
140
|
+
*
|
|
141
|
+
* // Connect to a service (v1.0.0 - returns AnswererConnection)
|
|
142
|
+
* const connection = await rondevu.connectToService({
|
|
143
|
+
* serviceFqn: 'chat:2.0.0@bob'
|
|
144
|
+
* })
|
|
145
|
+
*
|
|
146
|
+
* connection.on('connected', () => {
|
|
147
|
+
* console.log('Connected!')
|
|
148
|
+
* connection.send('Hello!')
|
|
149
|
+
* })
|
|
150
|
+
*
|
|
151
|
+
* connection.on('message', (data) => {
|
|
152
|
+
* console.log('Received:', data)
|
|
153
|
+
* })
|
|
152
154
|
*
|
|
153
|
-
*
|
|
154
|
-
*
|
|
155
|
+
* connection.on('reconnecting', (attempt) => {
|
|
156
|
+
* console.log(`Reconnecting, attempt ${attempt}`)
|
|
157
|
+
* })
|
|
155
158
|
* ```
|
|
156
159
|
*/
|
|
157
160
|
export declare class Rondevu extends EventEmitter {
|
|
@@ -169,14 +172,8 @@ export declare class Rondevu extends EventEmitter {
|
|
|
169
172
|
private rtcPeerConnection?;
|
|
170
173
|
private rtcIceCandidate?;
|
|
171
174
|
private currentService;
|
|
172
|
-
private
|
|
173
|
-
private
|
|
174
|
-
private ttl;
|
|
175
|
-
private activeOffers;
|
|
176
|
-
private filling;
|
|
177
|
-
private pollingInterval;
|
|
178
|
-
private lastPollTimestamp;
|
|
179
|
-
private isPolling;
|
|
175
|
+
private connectionConfig?;
|
|
176
|
+
private offerPool;
|
|
180
177
|
private constructor();
|
|
181
178
|
/**
|
|
182
179
|
* Internal debug logging - only logs if debug mode is enabled
|
|
@@ -215,32 +212,16 @@ export declare class Rondevu extends EventEmitter {
|
|
|
215
212
|
* ```typescript
|
|
216
213
|
* await rondevu.publishService({
|
|
217
214
|
* service: 'chat:2.0.0',
|
|
218
|
-
* maxOffers: 5
|
|
215
|
+
* maxOffers: 5,
|
|
216
|
+
* connectionConfig: {
|
|
217
|
+
* reconnectEnabled: true,
|
|
218
|
+
* bufferEnabled: true
|
|
219
|
+
* }
|
|
219
220
|
* })
|
|
220
221
|
* await rondevu.startFilling()
|
|
221
222
|
* ```
|
|
222
223
|
*/
|
|
223
224
|
publishService(options: PublishServiceOptions): Promise<void>;
|
|
224
|
-
/**
|
|
225
|
-
* Set up ICE candidate handler to send candidates to the server
|
|
226
|
-
*
|
|
227
|
-
* Note: This is used by connectToService() where the offerId is already known.
|
|
228
|
-
* For createOffer(), we use inline ICE handling with early candidate queuing
|
|
229
|
-
* since the offerId isn't available until after the factory completes.
|
|
230
|
-
*/
|
|
231
|
-
private setupIceCandidateHandler;
|
|
232
|
-
/**
|
|
233
|
-
* Create a single offer and publish it to the server
|
|
234
|
-
*/
|
|
235
|
-
private createOffer;
|
|
236
|
-
/**
|
|
237
|
-
* Fill offers to reach maxOffers count
|
|
238
|
-
*/
|
|
239
|
-
private fillOffers;
|
|
240
|
-
/**
|
|
241
|
-
* Poll for answers and ICE candidates (internal use for automatic offer management)
|
|
242
|
-
*/
|
|
243
|
-
private pollInternal;
|
|
244
225
|
/**
|
|
245
226
|
* Start filling offers and polling for answers/ICE
|
|
246
227
|
* Call this after publishService() to begin accepting connections
|
|
@@ -259,14 +240,14 @@ export declare class Rondevu extends EventEmitter {
|
|
|
259
240
|
/**
|
|
260
241
|
* Check if an offer is currently connected
|
|
261
242
|
* @param offerId - The offer ID to check
|
|
262
|
-
* @returns True if the offer exists and
|
|
243
|
+
* @returns True if the offer exists and is connected
|
|
263
244
|
*/
|
|
264
245
|
isConnected(offerId: string): boolean;
|
|
265
246
|
/**
|
|
266
247
|
* Disconnect all active offers
|
|
267
248
|
* Similar to stopFilling() but doesn't stop the polling/filling process
|
|
268
249
|
*/
|
|
269
|
-
disconnectAll():
|
|
250
|
+
disconnectAll(): void;
|
|
270
251
|
/**
|
|
271
252
|
* Get the current service status
|
|
272
253
|
* @returns Object with service state information
|
|
@@ -274,8 +255,6 @@ export declare class Rondevu extends EventEmitter {
|
|
|
274
255
|
getServiceStatus(): {
|
|
275
256
|
active: boolean;
|
|
276
257
|
offerCount: number;
|
|
277
|
-
maxOffers: number;
|
|
278
|
-
filling: boolean;
|
|
279
258
|
};
|
|
280
259
|
/**
|
|
281
260
|
* Resolve the full service FQN from various input options
|
|
@@ -283,41 +262,45 @@ export declare class Rondevu extends EventEmitter {
|
|
|
283
262
|
*/
|
|
284
263
|
private resolveServiceFqn;
|
|
285
264
|
/**
|
|
286
|
-
*
|
|
287
|
-
* Returns
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
/**
|
|
291
|
-
* Automatically connect to a service (answerer side)
|
|
292
|
-
* Handles the entire connection flow: discovery, WebRTC setup, answer exchange, ICE candidates
|
|
265
|
+
* Connect to a service (answerer side) - v1.0.0 API
|
|
266
|
+
* Returns an AnswererConnection with automatic reconnection and buffering
|
|
267
|
+
*
|
|
268
|
+
* BREAKING CHANGE: This now returns AnswererConnection instead of ConnectionContext
|
|
293
269
|
*
|
|
294
270
|
* @example
|
|
295
271
|
* ```typescript
|
|
296
272
|
* // Connect to specific user
|
|
297
273
|
* const connection = await rondevu.connectToService({
|
|
298
274
|
* serviceFqn: 'chat:2.0.0@alice',
|
|
299
|
-
*
|
|
300
|
-
*
|
|
301
|
-
*
|
|
302
|
-
* dc.addEventListener('open', () => dc.send('Hello!'))
|
|
275
|
+
* connectionConfig: {
|
|
276
|
+
* reconnectEnabled: true,
|
|
277
|
+
* bufferEnabled: true
|
|
303
278
|
* }
|
|
304
279
|
* })
|
|
305
280
|
*
|
|
281
|
+
* connection.on('connected', () => {
|
|
282
|
+
* console.log('Connected!')
|
|
283
|
+
* connection.send('Hello!')
|
|
284
|
+
* })
|
|
285
|
+
*
|
|
286
|
+
* connection.on('message', (data) => {
|
|
287
|
+
* console.log('Received:', data)
|
|
288
|
+
* })
|
|
289
|
+
*
|
|
290
|
+
* connection.on('reconnecting', (attempt) => {
|
|
291
|
+
* console.log(`Reconnecting, attempt ${attempt}`)
|
|
292
|
+
* })
|
|
293
|
+
*
|
|
306
294
|
* // Discover random service
|
|
307
295
|
* const connection = await rondevu.connectToService({
|
|
308
|
-
* service: 'chat:2.0.0'
|
|
309
|
-
* onConnection: ({ dc, peerUsername }) => {
|
|
310
|
-
* console.log('Connected to', peerUsername)
|
|
311
|
-
* }
|
|
296
|
+
* service: 'chat:2.0.0'
|
|
312
297
|
* })
|
|
313
298
|
* ```
|
|
314
299
|
*/
|
|
315
|
-
connectToService(options: ConnectToServiceOptions): Promise<
|
|
300
|
+
connectToService(options: ConnectToServiceOptions): Promise<AnswererConnection>;
|
|
316
301
|
/**
|
|
317
302
|
* Find a service - unified discovery method
|
|
318
303
|
*
|
|
319
|
-
* Replaces getService(), discoverService(), and discoverServices() with a single method.
|
|
320
|
-
*
|
|
321
304
|
* @param serviceFqn - Service identifier (e.g., 'chat:1.0.0' or 'chat:1.0.0@alice')
|
|
322
305
|
* @param options - Discovery options
|
|
323
306
|
*
|
|
@@ -399,6 +382,15 @@ export declare class Rondevu extends EventEmitter {
|
|
|
399
382
|
* Get the public key
|
|
400
383
|
*/
|
|
401
384
|
getPublicKey(): string;
|
|
385
|
+
/**
|
|
386
|
+
* Get active connections (for offerer side)
|
|
387
|
+
*/
|
|
388
|
+
getActiveConnections(): Map<string, OffererConnection>;
|
|
389
|
+
/**
|
|
390
|
+
* Get all active offers (legacy compatibility)
|
|
391
|
+
* @deprecated Use getActiveConnections() instead
|
|
392
|
+
*/
|
|
393
|
+
getActiveOffers(): ActiveOffer[];
|
|
402
394
|
/**
|
|
403
395
|
* Access to underlying API for advanced operations
|
|
404
396
|
* @deprecated Use direct methods on Rondevu instance instead
|