@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.
- package/README.md +92 -117
- package/dist/api/batcher.d.ts +83 -0
- package/dist/api/batcher.js +155 -0
- package/dist/api/client.d.ts +198 -0
- package/dist/api/client.js +400 -0
- package/dist/{answerer-connection.d.ts → connections/answerer.d.ts} +25 -8
- package/dist/{answerer-connection.js → connections/answerer.js} +70 -48
- package/dist/{connection.d.ts → connections/base.d.ts} +30 -7
- package/dist/{connection.js → connections/base.js} +65 -14
- package/dist/connections/config.d.ts +51 -0
- package/dist/{connection-config.js → connections/config.js} +20 -0
- package/dist/{connection-events.d.ts → connections/events.d.ts} +6 -6
- package/dist/connections/offerer.d.ts +108 -0
- package/dist/connections/offerer.js +306 -0
- package/dist/core/ice-config.d.ts +35 -0
- package/dist/core/ice-config.js +111 -0
- package/dist/core/index.d.ts +22 -0
- package/dist/core/index.js +22 -0
- package/dist/core/offer-pool.d.ts +113 -0
- package/dist/core/offer-pool.js +281 -0
- package/dist/core/peer.d.ts +155 -0
- package/dist/core/peer.js +252 -0
- package/dist/core/polling-manager.d.ts +71 -0
- package/dist/core/polling-manager.js +122 -0
- package/dist/core/rondevu-errors.d.ts +59 -0
- package/dist/core/rondevu-errors.js +75 -0
- package/dist/core/rondevu-types.d.ts +125 -0
- package/dist/core/rondevu-types.js +6 -0
- package/dist/core/rondevu.d.ts +296 -0
- package/dist/core/rondevu.js +472 -0
- package/dist/crypto/adapter.d.ts +53 -0
- package/dist/crypto/node.d.ts +57 -0
- package/dist/crypto/node.js +149 -0
- package/dist/crypto/web.d.ts +38 -0
- package/dist/crypto/web.js +129 -0
- 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/dist/{message-buffer.js → utils/message-buffer.js} +4 -4
- package/dist/webrtc/adapter.d.ts +22 -0
- package/dist/webrtc/adapter.js +5 -0
- package/dist/webrtc/browser.d.ts +12 -0
- package/dist/webrtc/browser.js +15 -0
- package/dist/webrtc/node.d.ts +32 -0
- package/dist/webrtc/node.js +32 -0
- package/package.json +20 -9
- package/dist/api.d.ts +0 -146
- package/dist/api.js +0 -279
- package/dist/connection-config.d.ts +0 -21
- package/dist/crypto-adapter.d.ts +0 -37
- package/dist/index.d.ts +0 -13
- package/dist/index.js +0 -10
- package/dist/node-crypto-adapter.d.ts +0 -35
- package/dist/node-crypto-adapter.js +0 -78
- package/dist/offerer-connection.d.ts +0 -54
- package/dist/offerer-connection.js +0 -177
- package/dist/rondevu-signaler.d.ts +0 -112
- package/dist/rondevu-signaler.js +0 -401
- package/dist/rondevu.d.ts +0 -407
- package/dist/rondevu.js +0 -847
- package/dist/rpc-batcher.d.ts +0 -61
- package/dist/rpc-batcher.js +0 -111
- package/dist/web-crypto-adapter.d.ts +0 -16
- package/dist/web-crypto-adapter.js +0 -52
- /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.js → crypto/adapter.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
|
@@ -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
|
+
}
|