@xtr-dev/rondevu-client 0.18.10 → 0.21.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.
Files changed (70) hide show
  1. package/README.md +92 -117
  2. package/dist/api/batcher.d.ts +83 -0
  3. package/dist/api/batcher.js +155 -0
  4. package/dist/api/client.d.ts +198 -0
  5. package/dist/api/client.js +400 -0
  6. package/dist/{answerer-connection.d.ts → connections/answerer.d.ts} +25 -8
  7. package/dist/{answerer-connection.js → connections/answerer.js} +70 -48
  8. package/dist/{connection.d.ts → connections/base.d.ts} +30 -7
  9. package/dist/{connection.js → connections/base.js} +65 -14
  10. package/dist/connections/config.d.ts +51 -0
  11. package/dist/{connection-config.js → connections/config.js} +20 -0
  12. package/dist/{connection-events.d.ts → connections/events.d.ts} +6 -6
  13. package/dist/connections/offerer.d.ts +108 -0
  14. package/dist/connections/offerer.js +306 -0
  15. package/dist/core/ice-config.d.ts +35 -0
  16. package/dist/core/ice-config.js +111 -0
  17. package/dist/core/index.d.ts +22 -0
  18. package/dist/core/index.js +22 -0
  19. package/dist/core/offer-pool.d.ts +113 -0
  20. package/dist/core/offer-pool.js +281 -0
  21. package/dist/core/peer.d.ts +155 -0
  22. package/dist/core/peer.js +252 -0
  23. package/dist/core/polling-manager.d.ts +71 -0
  24. package/dist/core/polling-manager.js +122 -0
  25. package/dist/core/rondevu-errors.d.ts +59 -0
  26. package/dist/core/rondevu-errors.js +75 -0
  27. package/dist/core/rondevu-types.d.ts +125 -0
  28. package/dist/core/rondevu-types.js +6 -0
  29. package/dist/core/rondevu.d.ts +296 -0
  30. package/dist/core/rondevu.js +472 -0
  31. package/dist/crypto/adapter.d.ts +53 -0
  32. package/dist/crypto/node.d.ts +57 -0
  33. package/dist/crypto/node.js +149 -0
  34. package/dist/crypto/web.d.ts +38 -0
  35. package/dist/crypto/web.js +129 -0
  36. package/dist/utils/async-lock.d.ts +42 -0
  37. package/dist/utils/async-lock.js +75 -0
  38. package/dist/{message-buffer.d.ts → utils/message-buffer.d.ts} +1 -1
  39. package/dist/{message-buffer.js → utils/message-buffer.js} +4 -4
  40. package/dist/webrtc/adapter.d.ts +22 -0
  41. package/dist/webrtc/adapter.js +5 -0
  42. package/dist/webrtc/browser.d.ts +12 -0
  43. package/dist/webrtc/browser.js +15 -0
  44. package/dist/webrtc/node.d.ts +32 -0
  45. package/dist/webrtc/node.js +32 -0
  46. package/package.json +20 -9
  47. package/dist/api.d.ts +0 -146
  48. package/dist/api.js +0 -279
  49. package/dist/connection-config.d.ts +0 -21
  50. package/dist/crypto-adapter.d.ts +0 -37
  51. package/dist/index.d.ts +0 -13
  52. package/dist/index.js +0 -10
  53. package/dist/node-crypto-adapter.d.ts +0 -35
  54. package/dist/node-crypto-adapter.js +0 -78
  55. package/dist/offerer-connection.d.ts +0 -54
  56. package/dist/offerer-connection.js +0 -177
  57. package/dist/rondevu-signaler.d.ts +0 -112
  58. package/dist/rondevu-signaler.js +0 -401
  59. package/dist/rondevu.d.ts +0 -407
  60. package/dist/rondevu.js +0 -847
  61. package/dist/rpc-batcher.d.ts +0 -61
  62. package/dist/rpc-batcher.js +0 -111
  63. package/dist/web-crypto-adapter.d.ts +0 -16
  64. package/dist/web-crypto-adapter.js +0 -52
  65. /package/dist/{connection-events.js → connections/events.js} +0 -0
  66. /package/dist/{types.d.ts → core/types.d.ts} +0 -0
  67. /package/dist/{types.js → core/types.js} +0 -0
  68. /package/dist/{crypto-adapter.js → crypto/adapter.js} +0 -0
  69. /package/dist/{exponential-backoff.d.ts → utils/exponential-backoff.d.ts} +0 -0
  70. /package/dist/{exponential-backoff.js → utils/exponential-backoff.js} +0 -0
package/dist/rondevu.d.ts DELETED
@@ -1,407 +0,0 @@
1
- import { RondevuAPI, Keypair, IceCandidate, BatcherOptions } from './api.js';
2
- import { CryptoAdapter } from './crypto-adapter.js';
3
- import { EventEmitter } from 'eventemitter3';
4
- export type IceServerPreset = 'ipv4-turn' | 'hostname-turns' | 'google-stun' | 'relay-only';
5
- export declare const ICE_SERVER_PRESETS: Record<IceServerPreset, RTCIceServer[]>;
6
- export interface RondevuOptions {
7
- apiUrl: string;
8
- username?: string;
9
- keypair?: Keypair;
10
- cryptoAdapter?: CryptoAdapter;
11
- batching?: BatcherOptions | false;
12
- iceServers?: IceServerPreset | RTCIceServer[];
13
- debug?: boolean;
14
- rtcPeerConnection?: typeof RTCPeerConnection;
15
- rtcIceCandidate?: typeof RTCIceCandidate;
16
- }
17
- export interface OfferContext {
18
- dc?: RTCDataChannel;
19
- offer: RTCSessionDescriptionInit;
20
- }
21
- /**
22
- * Factory function for creating WebRTC offers.
23
- * Rondevu creates the RTCPeerConnection and passes it to the factory,
24
- * allowing ICE candidate handlers to be set up before setLocalDescription() is called.
25
- *
26
- * @param pc - The RTCPeerConnection created by Rondevu (already configured with ICE servers)
27
- * @returns Promise containing the data channel (optional) and offer SDP
28
- */
29
- export type OfferFactory = (pc: RTCPeerConnection) => Promise<OfferContext>;
30
- export interface PublishServiceOptions {
31
- service: string;
32
- maxOffers: number;
33
- offerFactory?: OfferFactory;
34
- ttl?: number;
35
- }
36
- export interface ConnectionContext {
37
- pc: RTCPeerConnection;
38
- dc: RTCDataChannel;
39
- serviceFqn: string;
40
- offerId: string;
41
- peerUsername: string;
42
- }
43
- export interface ConnectToServiceOptions {
44
- serviceFqn?: string;
45
- service?: string;
46
- username?: string;
47
- onConnection?: (context: ConnectionContext) => void | Promise<void>;
48
- rtcConfig?: RTCConfiguration;
49
- }
50
- export interface ActiveOffer {
51
- offerId: string;
52
- serviceFqn: string;
53
- pc: RTCPeerConnection;
54
- dc?: RTCDataChannel;
55
- answered: boolean;
56
- createdAt: number;
57
- }
58
- export interface FindServiceOptions {
59
- mode?: 'direct' | 'random' | 'paginated';
60
- limit?: number;
61
- offset?: number;
62
- }
63
- export interface ServiceResult {
64
- serviceId: string;
65
- username: string;
66
- serviceFqn: string;
67
- offerId: string;
68
- sdp: string;
69
- createdAt: number;
70
- expiresAt: number;
71
- }
72
- export interface PaginatedServiceResult {
73
- services: ServiceResult[];
74
- count: number;
75
- limit: number;
76
- offset: number;
77
- }
78
- /**
79
- * Base error class for Rondevu errors
80
- */
81
- export declare class RondevuError extends Error {
82
- context?: Record<string, any> | undefined;
83
- constructor(message: string, context?: Record<string, any> | undefined);
84
- }
85
- /**
86
- * Network-related errors (API calls, connectivity)
87
- */
88
- export declare class NetworkError extends RondevuError {
89
- constructor(message: string, context?: Record<string, any>);
90
- }
91
- /**
92
- * Validation errors (invalid input, malformed data)
93
- */
94
- export declare class ValidationError extends RondevuError {
95
- constructor(message: string, context?: Record<string, any>);
96
- }
97
- /**
98
- * WebRTC connection errors (peer connection failures, ICE issues)
99
- */
100
- export declare class ConnectionError extends RondevuError {
101
- constructor(message: string, context?: Record<string, any>);
102
- }
103
- /**
104
- * Rondevu - Complete WebRTC signaling client
105
- *
106
- * Provides a unified API for:
107
- * - Implicit username claiming (auto-claimed on first authenticated request)
108
- * - Service publishing with automatic signature generation
109
- * - Service discovery (direct, random, paginated)
110
- * - WebRTC signaling (offer/answer exchange, ICE relay)
111
- * - Keypair management
112
- *
113
- * @example
114
- * ```typescript
115
- * // Create and initialize Rondevu instance with preset ICE servers
116
- * const rondevu = await Rondevu.connect({
117
- * apiUrl: 'https://signal.example.com',
118
- * username: 'alice',
119
- * iceServers: 'ipv4-turn' // Use preset: 'ipv4-turn', 'hostname-turns', 'google-stun', or 'relay-only'
120
- * })
121
- *
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
- * // Publish a service with automatic offer management
133
- * await rondevu.publishService({
134
- * service: 'chat:2.0.0',
135
- * maxOffers: 5, // Maintain up to 5 concurrent offers
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
- * }
143
- * })
144
- *
145
- * // Start accepting connections (auto-fills offers and polls)
146
- * await rondevu.startFilling()
147
- *
148
- * // Access active connections
149
- * for (const offer of rondevu.getActiveOffers()) {
150
- * offer.dc?.addEventListener('message', (e) => console.log(e.data))
151
- * }
152
- *
153
- * // Stop when done
154
- * rondevu.stopFilling()
155
- * ```
156
- */
157
- export declare class Rondevu extends EventEmitter {
158
- private static readonly DEFAULT_TTL_MS;
159
- private static readonly POLLING_INTERVAL_MS;
160
- private api;
161
- private readonly apiUrl;
162
- private username;
163
- private keypair;
164
- private usernameClaimed;
165
- private cryptoAdapter?;
166
- private batchingOptions?;
167
- private iceServers;
168
- private debugEnabled;
169
- private rtcPeerConnection?;
170
- private rtcIceCandidate?;
171
- private currentService;
172
- private maxOffers;
173
- private offerFactory;
174
- private ttl;
175
- private activeOffers;
176
- private filling;
177
- private pollingInterval;
178
- private lastPollTimestamp;
179
- private isPolling;
180
- private constructor();
181
- /**
182
- * Internal debug logging - only logs if debug mode is enabled
183
- */
184
- private debug;
185
- /**
186
- * Create and initialize a Rondevu client
187
- *
188
- * @example
189
- * ```typescript
190
- * const rondevu = await Rondevu.connect({
191
- * apiUrl: 'https://api.ronde.vu',
192
- * username: 'alice'
193
- * })
194
- * ```
195
- */
196
- static connect(options: RondevuOptions): Promise<Rondevu>;
197
- /**
198
- * Generate an anonymous username with timestamp and random component
199
- */
200
- private static generateAnonymousUsername;
201
- /**
202
- * Check if username has been claimed (checks with server)
203
- */
204
- isUsernameClaimed(): Promise<boolean>;
205
- /**
206
- * Default offer factory - creates a simple data channel connection
207
- * The RTCPeerConnection is created by Rondevu and passed in
208
- */
209
- private defaultOfferFactory;
210
- /**
211
- * Publish a service with automatic offer management
212
- * Call startFilling() to begin accepting connections
213
- *
214
- * @example
215
- * ```typescript
216
- * await rondevu.publishService({
217
- * service: 'chat:2.0.0',
218
- * maxOffers: 5
219
- * })
220
- * await rondevu.startFilling()
221
- * ```
222
- */
223
- 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
- /**
245
- * Start filling offers and polling for answers/ICE
246
- * Call this after publishService() to begin accepting connections
247
- */
248
- startFilling(): Promise<void>;
249
- /**
250
- * Stop filling offers and polling
251
- * Closes all active peer connections
252
- */
253
- stopFilling(): void;
254
- /**
255
- * Get the count of active offers
256
- * @returns Number of active offers
257
- */
258
- getOfferCount(): number;
259
- /**
260
- * Check if an offer is currently connected
261
- * @param offerId - The offer ID to check
262
- * @returns True if the offer exists and has been answered
263
- */
264
- isConnected(offerId: string): boolean;
265
- /**
266
- * Disconnect all active offers
267
- * Similar to stopFilling() but doesn't stop the polling/filling process
268
- */
269
- disconnectAll(): Promise<void>;
270
- /**
271
- * Get the current service status
272
- * @returns Object with service state information
273
- */
274
- getServiceStatus(): {
275
- active: boolean;
276
- offerCount: number;
277
- maxOffers: number;
278
- filling: boolean;
279
- };
280
- /**
281
- * Resolve the full service FQN from various input options
282
- * Supports direct FQN, service+username, or service discovery
283
- */
284
- private resolveServiceFqn;
285
- /**
286
- * Start polling for remote ICE candidates
287
- * Returns the polling interval ID
288
- */
289
- private startIcePolling;
290
- /**
291
- * Automatically connect to a service (answerer side)
292
- * Handles the entire connection flow: discovery, WebRTC setup, answer exchange, ICE candidates
293
- *
294
- * @example
295
- * ```typescript
296
- * // Connect to specific user
297
- * const connection = await rondevu.connectToService({
298
- * serviceFqn: 'chat:2.0.0@alice',
299
- * onConnection: ({ dc, peerUsername }) => {
300
- * console.log('Connected to', peerUsername)
301
- * dc.addEventListener('message', (e) => console.log(e.data))
302
- * dc.addEventListener('open', () => dc.send('Hello!'))
303
- * }
304
- * })
305
- *
306
- * // Discover random service
307
- * const connection = await rondevu.connectToService({
308
- * service: 'chat:2.0.0',
309
- * onConnection: ({ dc, peerUsername }) => {
310
- * console.log('Connected to', peerUsername)
311
- * }
312
- * })
313
- * ```
314
- */
315
- connectToService(options: ConnectToServiceOptions): Promise<ConnectionContext>;
316
- /**
317
- * Find a service - unified discovery method
318
- *
319
- * Replaces getService(), discoverService(), and discoverServices() with a single method.
320
- *
321
- * @param serviceFqn - Service identifier (e.g., 'chat:1.0.0' or 'chat:1.0.0@alice')
322
- * @param options - Discovery options
323
- *
324
- * @example
325
- * ```typescript
326
- * // Direct lookup (has username)
327
- * const service = await rondevu.findService('chat:1.0.0@alice')
328
- *
329
- * // Random discovery (no username)
330
- * const service = await rondevu.findService('chat:1.0.0')
331
- *
332
- * // Paginated discovery
333
- * const result = await rondevu.findService('chat:1.0.0', {
334
- * mode: 'paginated',
335
- * limit: 20,
336
- * offset: 0
337
- * })
338
- * ```
339
- */
340
- findService(serviceFqn: string, options?: FindServiceOptions): Promise<ServiceResult | PaginatedServiceResult>;
341
- /**
342
- * Post answer SDP to specific offer
343
- */
344
- postOfferAnswer(serviceFqn: string, offerId: string, sdp: string): Promise<{
345
- success: boolean;
346
- offerId: string;
347
- }>;
348
- /**
349
- * Get answer SDP (offerer polls this)
350
- */
351
- getOfferAnswer(serviceFqn: string, offerId: string): Promise<{
352
- sdp: string;
353
- offerId: string;
354
- answererId: string;
355
- answeredAt: number;
356
- } | null>;
357
- /**
358
- * Combined polling for answers and ICE candidates
359
- * Returns all answered offers and ICE candidates for all peer's offers since timestamp
360
- */
361
- poll(since?: number): Promise<{
362
- answers: Array<{
363
- offerId: string;
364
- serviceId?: string;
365
- answererId: string;
366
- sdp: string;
367
- answeredAt: number;
368
- }>;
369
- iceCandidates: Record<string, Array<{
370
- candidate: RTCIceCandidateInit | null;
371
- role: 'offerer' | 'answerer';
372
- peerId: string;
373
- createdAt: number;
374
- }>>;
375
- }>;
376
- /**
377
- * Add ICE candidates to specific offer
378
- */
379
- addOfferIceCandidates(serviceFqn: string, offerId: string, candidates: RTCIceCandidateInit[]): Promise<{
380
- count: number;
381
- offerId: string;
382
- }>;
383
- /**
384
- * Get ICE candidates for specific offer (with polling support)
385
- */
386
- getOfferIceCandidates(serviceFqn: string, offerId: string, since?: number): Promise<{
387
- candidates: IceCandidate[];
388
- offerId: string;
389
- }>;
390
- /**
391
- * Get the current keypair (for backup/storage)
392
- */
393
- getKeypair(): Keypair;
394
- /**
395
- * Get the username
396
- */
397
- getUsername(): string;
398
- /**
399
- * Get the public key
400
- */
401
- getPublicKey(): string;
402
- /**
403
- * Access to underlying API for advanced operations
404
- * @deprecated Use direct methods on Rondevu instance instead
405
- */
406
- getAPIPublic(): RondevuAPI;
407
- }