@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
@@ -0,0 +1,296 @@
1
+ import { Credential, IceCandidate } from '../api/client.js';
2
+ import { WebRTCAdapter } from '../webrtc/adapter.js';
3
+ import { EventEmitter } from 'eventemitter3';
4
+ import { OffererConnection } from '../connections/offerer.js';
5
+ import { Peer, PeerOptions } from './peer.js';
6
+ import type { RondevuOptions, OfferOptions, OfferHandle, DiscoverOptions, DiscoverResult } from './rondevu-types.js';
7
+ export type { RondevuOptions, OfferContext, OfferFactory, OfferOptions, OfferHandle, ConnectionContext, DiscoverOptions, DiscoveredOffer, DiscoverResult, } from './rondevu-types.js';
8
+ export { ICE_SERVER_PRESETS } from './ice-config.js';
9
+ export type { IceServerPreset, IcePresetConfig } from './ice-config.js';
10
+ export type { PollAnswerEvent, PollIceEvent } from './polling-manager.js';
11
+ /**
12
+ * Rondevu - Complete WebRTC signaling client with durable connections
13
+ *
14
+ * Uses a tags-based discovery system where offers have 1+ tags for matching.
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * // Create and initialize Rondevu instance with preset ICE servers
19
+ * const rondevu = await Rondevu.connect({
20
+ * apiUrl: 'https://signal.example.com',
21
+ * iceServers: 'ipv4-turn' // Use preset: 'ipv4-turn', 'hostname-turns', 'google-stun', or 'relay-only'
22
+ * })
23
+ *
24
+ * // Create offers with tags for discovery
25
+ * await rondevu.offer({
26
+ * tags: ['chat', 'video'],
27
+ * maxOffers: 5 // Maintain up to 5 concurrent offers
28
+ * })
29
+ *
30
+ * // Start accepting connections (auto-fills offers and polls)
31
+ * await rondevu.startFilling()
32
+ *
33
+ * // Listen for connections
34
+ * rondevu.on('connection:opened', (offerId, connection) => {
35
+ * connection.on('connected', () => console.log('Connected!'))
36
+ * connection.on('message', (data) => console.log('Received:', data))
37
+ * connection.send('Hello!')
38
+ * })
39
+ *
40
+ * // Connect by discovering offers with matching tags
41
+ * const connection = await rondevu.connect({
42
+ * tags: ['chat']
43
+ * })
44
+ *
45
+ * connection.on('connected', () => {
46
+ * console.log('Connected!')
47
+ * connection.send('Hello!')
48
+ * })
49
+ *
50
+ * connection.on('message', (data) => {
51
+ * console.log('Received:', data)
52
+ * })
53
+ *
54
+ * connection.on('reconnecting', (attempt) => {
55
+ * console.log(`Reconnecting, attempt ${attempt}`)
56
+ * })
57
+ * ```
58
+ */
59
+ export declare class Rondevu extends EventEmitter {
60
+ private static readonly DEFAULT_API_URL;
61
+ private static readonly DEFAULT_TTL_MS;
62
+ private static readonly POLLING_INTERVAL_MS;
63
+ private api;
64
+ private readonly apiUrl;
65
+ private credential;
66
+ private cryptoAdapter?;
67
+ private webrtcAdapter;
68
+ private iceServers;
69
+ private iceTransportPolicy?;
70
+ private debugEnabled;
71
+ private currentTags;
72
+ private connectionConfig?;
73
+ private offerPool;
74
+ private pollingManager;
75
+ private constructor();
76
+ /**
77
+ * Internal debug logging - only logs if debug mode is enabled
78
+ */
79
+ private debug;
80
+ /**
81
+ * Create and initialize a Rondevu client
82
+ *
83
+ * @example
84
+ * ```typescript
85
+ * const rondevu = await Rondevu.connect({}) // Uses default API URL
86
+ * // or
87
+ * const rondevu = await Rondevu.connect({
88
+ * apiUrl: 'https://custom.api.com'
89
+ * })
90
+ * ```
91
+ */
92
+ static connect(options?: RondevuOptions): Promise<Rondevu>;
93
+ /**
94
+ * Get the current credential name
95
+ */
96
+ getName(): string;
97
+ /**
98
+ * Get the full credential (name + secret)
99
+ * Use this to persist credentials for future sessions
100
+ *
101
+ * ⚠️ SECURITY WARNING:
102
+ * - The secret grants full access to this identity
103
+ * - Store credentials securely (encrypted storage, never in logs)
104
+ * - Never expose credentials in URLs, console output, or error messages
105
+ * - Treat the secret like a password or API key
106
+ */
107
+ getCredential(): Credential;
108
+ /**
109
+ * Get the WebRTC adapter for creating peer connections
110
+ * Used internally by offer pool and connections
111
+ */
112
+ getWebRTCAdapter(): WebRTCAdapter;
113
+ /**
114
+ * Default offer factory - creates a simple data channel connection
115
+ * The RTCPeerConnection is created by Rondevu and passed in
116
+ */
117
+ private defaultOfferFactory;
118
+ /**
119
+ * Create offers with tags for discovery (offerer/host side)
120
+ * Auto-starts filling by default. Use the returned object to cancel.
121
+ *
122
+ * @example
123
+ * ```typescript
124
+ * // Auto-start (default)
125
+ * const offer = await rondevu.offer({
126
+ * tags: ['chat', 'video'],
127
+ * maxOffers: 5
128
+ * })
129
+ * // Later: offer.cancel() to stop
130
+ *
131
+ * // Manual start
132
+ * await rondevu.offer({ tags: ['chat'], maxOffers: 5, autoStart: false })
133
+ * await rondevu.startFilling()
134
+ * ```
135
+ */
136
+ offer(options: OfferOptions): Promise<OfferHandle>;
137
+ /**
138
+ * Start filling offers and polling for answers/ICE
139
+ * Call this after offer() to begin accepting connections
140
+ */
141
+ startFilling(): Promise<void>;
142
+ /**
143
+ * Stop filling offers and polling
144
+ * Closes all active peer connections
145
+ */
146
+ stopFilling(): void;
147
+ /**
148
+ * Start the centralized polling manager
149
+ * Use this when you need polling without offers (e.g., answerer connections)
150
+ */
151
+ startPolling(): void;
152
+ /**
153
+ * Stop the centralized polling manager
154
+ */
155
+ stopPolling(): void;
156
+ /**
157
+ * Check if polling is active
158
+ */
159
+ isPolling(): boolean;
160
+ /**
161
+ * Get the count of active offers
162
+ * @returns Number of active offers
163
+ */
164
+ getOfferCount(): number;
165
+ /**
166
+ * Check if an offer is currently connected
167
+ * @param offerId - The offer ID to check
168
+ * @returns True if the offer exists and is connected
169
+ */
170
+ isConnected(offerId: string): boolean;
171
+ /**
172
+ * Disconnect all active offers
173
+ * Similar to stopFilling() but doesn't stop the polling/filling process
174
+ */
175
+ disconnectAll(): void;
176
+ /**
177
+ * Get the current publishing status
178
+ * @returns Object with publishing state information
179
+ */
180
+ getPublishStatus(): {
181
+ active: boolean;
182
+ offerCount: number;
183
+ tags: string[] | null;
184
+ };
185
+ /**
186
+ * Create a peer connection with simplified DX
187
+ * Returns a Peer object with clean state management and events
188
+ *
189
+ * @example
190
+ * ```typescript
191
+ * // Connect to any peer matching tags
192
+ * const peer = await rondevu.peer({ tags: ['chat'] })
193
+ *
194
+ * // Connect to specific user
195
+ * const peer = await rondevu.peer({
196
+ * username: 'alice',
197
+ * tags: ['chat']
198
+ * })
199
+ *
200
+ * peer.on('open', () => {
201
+ * console.log('Connected to', peer.peerUsername)
202
+ * peer.send('Hello!')
203
+ * })
204
+ *
205
+ * peer.on('message', (data) => {
206
+ * console.log('Received:', data)
207
+ * })
208
+ *
209
+ * peer.on('state', (state, prevState) => {
210
+ * console.log(`State: ${prevState} → ${state}`)
211
+ * })
212
+ *
213
+ * // Access underlying RTCPeerConnection
214
+ * if (peer.peerConnection) {
215
+ * console.log('ICE state:', peer.peerConnection.iceConnectionState)
216
+ * }
217
+ * ```
218
+ */
219
+ peer(options: PeerOptions): Promise<Peer>;
220
+ /**
221
+ * Discover offers by tags
222
+ *
223
+ * @param tags - Tags to search for (OR logic - matches any tag)
224
+ * @param options - Discovery options (pagination)
225
+ *
226
+ * @example
227
+ * ```typescript
228
+ * // Discover offers matching any of the tags
229
+ * const result = await rondevu.discover(['chat', 'video'])
230
+ *
231
+ * // Paginated discovery
232
+ * const result = await rondevu.discover(['chat'], {
233
+ * limit: 20,
234
+ * offset: 0
235
+ * })
236
+ *
237
+ * // Access offers
238
+ * for (const offer of result.offers) {
239
+ * console.log(offer.username, offer.tags)
240
+ * }
241
+ * ```
242
+ */
243
+ discover(tags: string[], options?: DiscoverOptions): Promise<DiscoverResult>;
244
+ /**
245
+ * Post answer SDP to specific offer
246
+ */
247
+ postOfferAnswer(offerId: string, sdp: string): Promise<{
248
+ success: boolean;
249
+ offerId: string;
250
+ }>;
251
+ /**
252
+ * Get answer SDP (offerer polls this)
253
+ */
254
+ getOfferAnswer(offerId: string): Promise<{
255
+ sdp: string;
256
+ offerId: string;
257
+ answererId: string;
258
+ answeredAt: number;
259
+ } | null>;
260
+ /**
261
+ * Combined polling for answers and ICE candidates
262
+ * Returns all answered offers and ICE candidates for all peer's offers since timestamp
263
+ */
264
+ poll(since?: number): Promise<{
265
+ answers: Array<{
266
+ offerId: string;
267
+ answererId: string;
268
+ sdp: string;
269
+ answeredAt: number;
270
+ }>;
271
+ iceCandidates: Record<string, Array<{
272
+ candidate: RTCIceCandidateInit | null;
273
+ role: 'offerer' | 'answerer';
274
+ peerId: string;
275
+ createdAt: number;
276
+ }>>;
277
+ }>;
278
+ /**
279
+ * Add ICE candidates to specific offer
280
+ */
281
+ addOfferIceCandidates(offerId: string, candidates: RTCIceCandidateInit[]): Promise<{
282
+ count: number;
283
+ offerId: string;
284
+ }>;
285
+ /**
286
+ * Get ICE candidates for specific offer (with polling support)
287
+ */
288
+ getOfferIceCandidates(offerId: string, since?: number): Promise<{
289
+ candidates: IceCandidate[];
290
+ offerId: string;
291
+ }>;
292
+ /**
293
+ * Get active connections (for offerer side)
294
+ */
295
+ getActiveConnections(): Map<string, OffererConnection>;
296
+ }