@xtr-dev/rondevu-client 0.9.2 → 0.10.0

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 (73) hide show
  1. package/dist/api.d.ts +147 -0
  2. package/dist/api.js +307 -0
  3. package/dist/bin.d.ts +35 -0
  4. package/dist/bin.js +35 -0
  5. package/dist/connection-manager.d.ts +104 -0
  6. package/dist/connection-manager.js +324 -0
  7. package/dist/connection.d.ts +112 -0
  8. package/dist/connection.js +194 -0
  9. package/dist/event-bus.d.ts +52 -0
  10. package/dist/event-bus.js +84 -0
  11. package/dist/index.d.ts +15 -11
  12. package/dist/index.js +9 -11
  13. package/dist/noop-signaler.d.ts +14 -0
  14. package/dist/noop-signaler.js +27 -0
  15. package/dist/rondevu-service.d.ts +81 -0
  16. package/dist/rondevu-service.js +131 -0
  17. package/dist/service-client.d.ts +92 -0
  18. package/dist/service-client.js +185 -0
  19. package/dist/service-host.d.ts +101 -0
  20. package/dist/service-host.js +185 -0
  21. package/dist/signaler.d.ts +25 -0
  22. package/dist/signaler.js +89 -0
  23. package/dist/types.d.ts +33 -0
  24. package/dist/types.js +2 -0
  25. package/dist/webrtc-context.d.ts +6 -0
  26. package/dist/webrtc-context.js +34 -0
  27. package/package.json +16 -2
  28. package/dist/auth.d.ts +0 -20
  29. package/dist/auth.js +0 -41
  30. package/dist/durable/channel.d.ts +0 -115
  31. package/dist/durable/channel.js +0 -301
  32. package/dist/durable/connection.d.ts +0 -125
  33. package/dist/durable/connection.js +0 -370
  34. package/dist/durable/reconnection.d.ts +0 -90
  35. package/dist/durable/reconnection.js +0 -127
  36. package/dist/durable/service.d.ts +0 -103
  37. package/dist/durable/service.js +0 -264
  38. package/dist/durable/types.d.ts +0 -149
  39. package/dist/durable/types.js +0 -28
  40. package/dist/event-emitter.d.ts +0 -54
  41. package/dist/event-emitter.js +0 -102
  42. package/dist/offer-pool.d.ts +0 -86
  43. package/dist/offer-pool.js +0 -145
  44. package/dist/offers.d.ts +0 -101
  45. package/dist/offers.js +0 -202
  46. package/dist/peer/answering-state.d.ts +0 -11
  47. package/dist/peer/answering-state.js +0 -39
  48. package/dist/peer/closed-state.d.ts +0 -8
  49. package/dist/peer/closed-state.js +0 -10
  50. package/dist/peer/connected-state.d.ts +0 -8
  51. package/dist/peer/connected-state.js +0 -11
  52. package/dist/peer/creating-offer-state.d.ts +0 -12
  53. package/dist/peer/creating-offer-state.js +0 -45
  54. package/dist/peer/exchanging-ice-state.d.ts +0 -17
  55. package/dist/peer/exchanging-ice-state.js +0 -64
  56. package/dist/peer/failed-state.d.ts +0 -10
  57. package/dist/peer/failed-state.js +0 -16
  58. package/dist/peer/idle-state.d.ts +0 -7
  59. package/dist/peer/idle-state.js +0 -14
  60. package/dist/peer/index.d.ts +0 -71
  61. package/dist/peer/index.js +0 -176
  62. package/dist/peer/state.d.ts +0 -23
  63. package/dist/peer/state.js +0 -63
  64. package/dist/peer/types.d.ts +0 -43
  65. package/dist/peer/types.js +0 -1
  66. package/dist/peer/waiting-for-answer-state.d.ts +0 -17
  67. package/dist/peer/waiting-for-answer-state.js +0 -60
  68. package/dist/rondevu.d.ts +0 -184
  69. package/dist/rondevu.js +0 -171
  70. package/dist/service-pool.d.ts +0 -123
  71. package/dist/service-pool.js +0 -488
  72. package/dist/usernames.d.ts +0 -79
  73. package/dist/usernames.js +0 -153
package/dist/api.d.ts ADDED
@@ -0,0 +1,147 @@
1
+ /**
2
+ * Rondevu API Client - Single class for all API endpoints
3
+ */
4
+ export interface Credentials {
5
+ peerId: string;
6
+ secret: string;
7
+ }
8
+ export interface Keypair {
9
+ publicKey: string;
10
+ privateKey: string;
11
+ }
12
+ export interface OfferRequest {
13
+ sdp: string;
14
+ topics?: string[];
15
+ ttl?: number;
16
+ secret?: string;
17
+ }
18
+ export interface Offer {
19
+ id: string;
20
+ peerId: string;
21
+ sdp: string;
22
+ topics: string[];
23
+ ttl: number;
24
+ createdAt: number;
25
+ expiresAt: number;
26
+ answererPeerId?: string;
27
+ }
28
+ export interface ServiceRequest {
29
+ username: string;
30
+ serviceFqn: string;
31
+ sdp: string;
32
+ ttl?: number;
33
+ isPublic?: boolean;
34
+ metadata?: Record<string, any>;
35
+ signature: string;
36
+ message: string;
37
+ }
38
+ export interface Service {
39
+ serviceId: string;
40
+ uuid: string;
41
+ offerId: string;
42
+ username: string;
43
+ serviceFqn: string;
44
+ isPublic: boolean;
45
+ metadata?: Record<string, any>;
46
+ createdAt: number;
47
+ expiresAt: number;
48
+ }
49
+ export interface IceCandidate {
50
+ candidate: RTCIceCandidateInit;
51
+ createdAt: number;
52
+ }
53
+ /**
54
+ * RondevuAPI - Complete API client for Rondevu signaling server
55
+ */
56
+ export declare class RondevuAPI {
57
+ private baseUrl;
58
+ private credentials?;
59
+ constructor(baseUrl: string, credentials?: Credentials | undefined);
60
+ /**
61
+ * Authentication header
62
+ */
63
+ private getAuthHeader;
64
+ /**
65
+ * Generate an Ed25519 keypair for username claiming and service publishing
66
+ */
67
+ static generateKeypair(): Promise<Keypair>;
68
+ /**
69
+ * Sign a message with an Ed25519 private key
70
+ */
71
+ static signMessage(message: string, privateKeyBase64: string): Promise<string>;
72
+ /**
73
+ * Verify a signature
74
+ */
75
+ static verifySignature(message: string, signatureBase64: string, publicKeyBase64: string): Promise<boolean>;
76
+ /**
77
+ * Register a new peer and get credentials
78
+ */
79
+ register(): Promise<Credentials>;
80
+ /**
81
+ * Create one or more offers
82
+ */
83
+ createOffers(offers: OfferRequest[]): Promise<Offer[]>;
84
+ /**
85
+ * Get offer by ID
86
+ */
87
+ getOffer(offerId: string): Promise<Offer>;
88
+ /**
89
+ * Answer an offer
90
+ */
91
+ answerOffer(offerId: string, sdp: string, secret?: string): Promise<void>;
92
+ /**
93
+ * Get answer for an offer (offerer polls this)
94
+ */
95
+ getAnswer(offerId: string): Promise<{
96
+ sdp: string;
97
+ } | null>;
98
+ /**
99
+ * Search offers by topic
100
+ */
101
+ searchOffers(topic: string): Promise<Offer[]>;
102
+ /**
103
+ * Add ICE candidates to an offer
104
+ */
105
+ addIceCandidates(offerId: string, candidates: RTCIceCandidateInit[]): Promise<void>;
106
+ /**
107
+ * Get ICE candidates for an offer (with polling support)
108
+ */
109
+ getIceCandidates(offerId: string, since?: number): Promise<IceCandidate[]>;
110
+ /**
111
+ * Publish a service
112
+ */
113
+ publishService(service: ServiceRequest): Promise<Service>;
114
+ /**
115
+ * Get service by UUID
116
+ */
117
+ getService(uuid: string): Promise<Service & {
118
+ offerId: string;
119
+ sdp: string;
120
+ }>;
121
+ /**
122
+ * Search services by username
123
+ */
124
+ searchServicesByUsername(username: string): Promise<Service[]>;
125
+ /**
126
+ * Search services by FQN
127
+ */
128
+ searchServicesByFqn(serviceFqn: string): Promise<Service[]>;
129
+ /**
130
+ * Search services by username AND FQN
131
+ */
132
+ searchServices(username: string, serviceFqn: string): Promise<Service[]>;
133
+ /**
134
+ * Check if username is available
135
+ */
136
+ checkUsername(username: string): Promise<{
137
+ available: boolean;
138
+ owner?: string;
139
+ }>;
140
+ /**
141
+ * Claim a username (requires Ed25519 signature)
142
+ */
143
+ claimUsername(username: string, publicKey: string, signature: string, message: string): Promise<{
144
+ success: boolean;
145
+ username: string;
146
+ }>;
147
+ }
package/dist/api.js ADDED
@@ -0,0 +1,307 @@
1
+ /**
2
+ * Rondevu API Client - Single class for all API endpoints
3
+ */
4
+ import * as ed25519 from '@noble/ed25519';
5
+ // Set SHA-512 hash function for ed25519 (required in @noble/ed25519 v3+)
6
+ ed25519.hashes.sha512Async = async (message) => {
7
+ return new Uint8Array(await crypto.subtle.digest('SHA-512', message));
8
+ };
9
+ /**
10
+ * Helper: Convert Uint8Array to base64 string
11
+ */
12
+ function bytesToBase64(bytes) {
13
+ const binString = Array.from(bytes, byte => String.fromCodePoint(byte)).join('');
14
+ return btoa(binString);
15
+ }
16
+ /**
17
+ * Helper: Convert base64 string to Uint8Array
18
+ */
19
+ function base64ToBytes(base64) {
20
+ const binString = atob(base64);
21
+ return Uint8Array.from(binString, char => char.codePointAt(0));
22
+ }
23
+ /**
24
+ * RondevuAPI - Complete API client for Rondevu signaling server
25
+ */
26
+ export class RondevuAPI {
27
+ constructor(baseUrl, credentials) {
28
+ this.baseUrl = baseUrl;
29
+ this.credentials = credentials;
30
+ }
31
+ /**
32
+ * Authentication header
33
+ */
34
+ getAuthHeader() {
35
+ if (!this.credentials) {
36
+ return {};
37
+ }
38
+ return {
39
+ Authorization: `Bearer ${this.credentials.peerId}:${this.credentials.secret}`,
40
+ };
41
+ }
42
+ // ============================================
43
+ // Ed25519 Cryptography Helpers
44
+ // ============================================
45
+ /**
46
+ * Generate an Ed25519 keypair for username claiming and service publishing
47
+ */
48
+ static async generateKeypair() {
49
+ const privateKey = ed25519.utils.randomSecretKey();
50
+ const publicKey = await ed25519.getPublicKeyAsync(privateKey);
51
+ return {
52
+ publicKey: bytesToBase64(publicKey),
53
+ privateKey: bytesToBase64(privateKey),
54
+ };
55
+ }
56
+ /**
57
+ * Sign a message with an Ed25519 private key
58
+ */
59
+ static async signMessage(message, privateKeyBase64) {
60
+ const privateKey = base64ToBytes(privateKeyBase64);
61
+ const encoder = new TextEncoder();
62
+ const messageBytes = encoder.encode(message);
63
+ const signature = await ed25519.signAsync(messageBytes, privateKey);
64
+ return bytesToBase64(signature);
65
+ }
66
+ /**
67
+ * Verify a signature
68
+ */
69
+ static async verifySignature(message, signatureBase64, publicKeyBase64) {
70
+ const publicKey = base64ToBytes(publicKeyBase64);
71
+ const signature = base64ToBytes(signatureBase64);
72
+ const encoder = new TextEncoder();
73
+ const messageBytes = encoder.encode(message);
74
+ return await ed25519.verifyAsync(signature, messageBytes, publicKey);
75
+ }
76
+ // ============================================
77
+ // Authentication
78
+ // ============================================
79
+ /**
80
+ * Register a new peer and get credentials
81
+ */
82
+ async register() {
83
+ const response = await fetch(`${this.baseUrl}/register`, {
84
+ method: 'POST',
85
+ headers: { 'Content-Type': 'application/json' },
86
+ });
87
+ if (!response.ok) {
88
+ const error = await response.json().catch(() => ({ error: 'Unknown error' }));
89
+ throw new Error(`Registration failed: ${error.error || response.statusText}`);
90
+ }
91
+ return await response.json();
92
+ }
93
+ // ============================================
94
+ // Offers
95
+ // ============================================
96
+ /**
97
+ * Create one or more offers
98
+ */
99
+ async createOffers(offers) {
100
+ const response = await fetch(`${this.baseUrl}/offers`, {
101
+ method: 'POST',
102
+ headers: {
103
+ 'Content-Type': 'application/json',
104
+ ...this.getAuthHeader(),
105
+ },
106
+ body: JSON.stringify({ offers }),
107
+ });
108
+ if (!response.ok) {
109
+ const error = await response.json().catch(() => ({ error: 'Unknown error' }));
110
+ throw new Error(`Failed to create offers: ${error.error || response.statusText}`);
111
+ }
112
+ return await response.json();
113
+ }
114
+ /**
115
+ * Get offer by ID
116
+ */
117
+ async getOffer(offerId) {
118
+ const response = await fetch(`${this.baseUrl}/offers/${offerId}`, {
119
+ headers: this.getAuthHeader(),
120
+ });
121
+ if (!response.ok) {
122
+ const error = await response.json().catch(() => ({ error: 'Unknown error' }));
123
+ throw new Error(`Failed to get offer: ${error.error || response.statusText}`);
124
+ }
125
+ return await response.json();
126
+ }
127
+ /**
128
+ * Answer an offer
129
+ */
130
+ async answerOffer(offerId, sdp, secret) {
131
+ const response = await fetch(`${this.baseUrl}/offers/${offerId}/answer`, {
132
+ method: 'POST',
133
+ headers: {
134
+ 'Content-Type': 'application/json',
135
+ ...this.getAuthHeader(),
136
+ },
137
+ body: JSON.stringify({ sdp, secret }),
138
+ });
139
+ if (!response.ok) {
140
+ const error = await response.json().catch(() => ({ error: 'Unknown error' }));
141
+ throw new Error(`Failed to answer offer: ${error.error || response.statusText}`);
142
+ }
143
+ }
144
+ /**
145
+ * Get answer for an offer (offerer polls this)
146
+ */
147
+ async getAnswer(offerId) {
148
+ const response = await fetch(`${this.baseUrl}/offers/${offerId}/answer`, {
149
+ headers: this.getAuthHeader(),
150
+ });
151
+ if (response.status === 404) {
152
+ return null; // No answer yet
153
+ }
154
+ if (!response.ok) {
155
+ const error = await response.json().catch(() => ({ error: 'Unknown error' }));
156
+ throw new Error(`Failed to get answer: ${error.error || response.statusText}`);
157
+ }
158
+ return await response.json();
159
+ }
160
+ /**
161
+ * Search offers by topic
162
+ */
163
+ async searchOffers(topic) {
164
+ const response = await fetch(`${this.baseUrl}/offers?topic=${encodeURIComponent(topic)}`, {
165
+ headers: this.getAuthHeader(),
166
+ });
167
+ if (!response.ok) {
168
+ const error = await response.json().catch(() => ({ error: 'Unknown error' }));
169
+ throw new Error(`Failed to search offers: ${error.error || response.statusText}`);
170
+ }
171
+ return await response.json();
172
+ }
173
+ // ============================================
174
+ // ICE Candidates
175
+ // ============================================
176
+ /**
177
+ * Add ICE candidates to an offer
178
+ */
179
+ async addIceCandidates(offerId, candidates) {
180
+ const response = await fetch(`${this.baseUrl}/offers/${offerId}/ice-candidates`, {
181
+ method: 'POST',
182
+ headers: {
183
+ 'Content-Type': 'application/json',
184
+ ...this.getAuthHeader(),
185
+ },
186
+ body: JSON.stringify({ candidates }),
187
+ });
188
+ if (!response.ok) {
189
+ const error = await response.json().catch(() => ({ error: 'Unknown error' }));
190
+ throw new Error(`Failed to add ICE candidates: ${error.error || response.statusText}`);
191
+ }
192
+ }
193
+ /**
194
+ * Get ICE candidates for an offer (with polling support)
195
+ */
196
+ async getIceCandidates(offerId, since = 0) {
197
+ const response = await fetch(`${this.baseUrl}/offers/${offerId}/ice-candidates?since=${since}`, { headers: this.getAuthHeader() });
198
+ if (!response.ok) {
199
+ const error = await response.json().catch(() => ({ error: 'Unknown error' }));
200
+ throw new Error(`Failed to get ICE candidates: ${error.error || response.statusText}`);
201
+ }
202
+ return await response.json();
203
+ }
204
+ // ============================================
205
+ // Services
206
+ // ============================================
207
+ /**
208
+ * Publish a service
209
+ */
210
+ async publishService(service) {
211
+ const response = await fetch(`${this.baseUrl}/services`, {
212
+ method: 'POST',
213
+ headers: {
214
+ 'Content-Type': 'application/json',
215
+ ...this.getAuthHeader(),
216
+ },
217
+ body: JSON.stringify(service),
218
+ });
219
+ if (!response.ok) {
220
+ const error = await response.json().catch(() => ({ error: 'Unknown error' }));
221
+ throw new Error(`Failed to publish service: ${error.error || response.statusText}`);
222
+ }
223
+ return await response.json();
224
+ }
225
+ /**
226
+ * Get service by UUID
227
+ */
228
+ async getService(uuid) {
229
+ const response = await fetch(`${this.baseUrl}/services/${uuid}`, {
230
+ headers: this.getAuthHeader(),
231
+ });
232
+ if (!response.ok) {
233
+ const error = await response.json().catch(() => ({ error: 'Unknown error' }));
234
+ throw new Error(`Failed to get service: ${error.error || response.statusText}`);
235
+ }
236
+ return await response.json();
237
+ }
238
+ /**
239
+ * Search services by username
240
+ */
241
+ async searchServicesByUsername(username) {
242
+ const response = await fetch(`${this.baseUrl}/services?username=${encodeURIComponent(username)}`, { headers: this.getAuthHeader() });
243
+ if (!response.ok) {
244
+ const error = await response.json().catch(() => ({ error: 'Unknown error' }));
245
+ throw new Error(`Failed to search services: ${error.error || response.statusText}`);
246
+ }
247
+ return await response.json();
248
+ }
249
+ /**
250
+ * Search services by FQN
251
+ */
252
+ async searchServicesByFqn(serviceFqn) {
253
+ const response = await fetch(`${this.baseUrl}/services?serviceFqn=${encodeURIComponent(serviceFqn)}`, { headers: this.getAuthHeader() });
254
+ if (!response.ok) {
255
+ const error = await response.json().catch(() => ({ error: 'Unknown error' }));
256
+ throw new Error(`Failed to search services: ${error.error || response.statusText}`);
257
+ }
258
+ return await response.json();
259
+ }
260
+ /**
261
+ * Search services by username AND FQN
262
+ */
263
+ async searchServices(username, serviceFqn) {
264
+ const response = await fetch(`${this.baseUrl}/services?username=${encodeURIComponent(username)}&serviceFqn=${encodeURIComponent(serviceFqn)}`, { headers: this.getAuthHeader() });
265
+ if (!response.ok) {
266
+ const error = await response.json().catch(() => ({ error: 'Unknown error' }));
267
+ throw new Error(`Failed to search services: ${error.error || response.statusText}`);
268
+ }
269
+ return await response.json();
270
+ }
271
+ // ============================================
272
+ // Usernames
273
+ // ============================================
274
+ /**
275
+ * Check if username is available
276
+ */
277
+ async checkUsername(username) {
278
+ const response = await fetch(`${this.baseUrl}/usernames/${encodeURIComponent(username)}/check`);
279
+ if (!response.ok) {
280
+ const error = await response.json().catch(() => ({ error: 'Unknown error' }));
281
+ throw new Error(`Failed to check username: ${error.error || response.statusText}`);
282
+ }
283
+ return await response.json();
284
+ }
285
+ /**
286
+ * Claim a username (requires Ed25519 signature)
287
+ */
288
+ async claimUsername(username, publicKey, signature, message) {
289
+ const response = await fetch(`${this.baseUrl}/usernames/${encodeURIComponent(username)}`, {
290
+ method: 'POST',
291
+ headers: {
292
+ 'Content-Type': 'application/json',
293
+ ...this.getAuthHeader(),
294
+ },
295
+ body: JSON.stringify({
296
+ publicKey,
297
+ signature,
298
+ message,
299
+ }),
300
+ });
301
+ if (!response.ok) {
302
+ const error = await response.json().catch(() => ({ error: 'Unknown error' }));
303
+ throw new Error(`Failed to claim username: ${error.error || response.statusText}`);
304
+ }
305
+ return await response.json();
306
+ }
307
+ }
package/dist/bin.d.ts ADDED
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Binnable - A cleanup function that can be synchronous or asynchronous
3
+ *
4
+ * Used to unsubscribe from events, close connections, or perform other cleanup operations.
5
+ */
6
+ export type Binnable = () => void | Promise<void>;
7
+ /**
8
+ * Create a cleanup function collector (garbage bin)
9
+ *
10
+ * Collects cleanup functions and provides a single `clean()` method to execute all of them.
11
+ * Useful for managing multiple cleanup operations in a single place.
12
+ *
13
+ * @returns A function that accepts cleanup functions and has a `clean()` method
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * const bin = createBin();
18
+ *
19
+ * // Add cleanup functions
20
+ * bin(
21
+ * () => console.log('Cleanup 1'),
22
+ * () => connection.close(),
23
+ * () => clearInterval(timer)
24
+ * );
25
+ *
26
+ * // Later, clean everything
27
+ * bin.clean(); // Executes all cleanup functions
28
+ * ```
29
+ */
30
+ export declare const createBin: () => ((...rubbish: Binnable[]) => number) & {
31
+ /**
32
+ * Execute all cleanup functions and clear the bin
33
+ */
34
+ clean: () => void;
35
+ };
package/dist/bin.js ADDED
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Create a cleanup function collector (garbage bin)
3
+ *
4
+ * Collects cleanup functions and provides a single `clean()` method to execute all of them.
5
+ * Useful for managing multiple cleanup operations in a single place.
6
+ *
7
+ * @returns A function that accepts cleanup functions and has a `clean()` method
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * const bin = createBin();
12
+ *
13
+ * // Add cleanup functions
14
+ * bin(
15
+ * () => console.log('Cleanup 1'),
16
+ * () => connection.close(),
17
+ * () => clearInterval(timer)
18
+ * );
19
+ *
20
+ * // Later, clean everything
21
+ * bin.clean(); // Executes all cleanup functions
22
+ * ```
23
+ */
24
+ export const createBin = () => {
25
+ const bin = [];
26
+ return Object.assign((...rubbish) => bin.push(...rubbish), {
27
+ /**
28
+ * Execute all cleanup functions and clear the bin
29
+ */
30
+ clean: () => {
31
+ bin.forEach(binnable => binnable());
32
+ bin.length = 0;
33
+ },
34
+ });
35
+ };
@@ -0,0 +1,104 @@
1
+ import { WebRTCRondevuConnection } from './connection.js';
2
+ import { Credentials } from './api.js';
3
+ import { ConnectionInterface } from './types.js';
4
+ export interface ConnectionManagerOptions {
5
+ apiUrl: string;
6
+ username: string;
7
+ credentials?: Credentials;
8
+ autoReconnect?: boolean;
9
+ reconnectDelay?: number;
10
+ maxReconnectAttempts?: number;
11
+ }
12
+ export interface HostServiceOptions {
13
+ service: string;
14
+ ttl?: number;
15
+ onConnection?: (connection: ConnectionInterface) => void;
16
+ }
17
+ export interface ConnectToServiceOptions {
18
+ username: string;
19
+ service: string;
20
+ onConnection?: (connection: ConnectionInterface) => void;
21
+ }
22
+ /**
23
+ * ConnectionManager - High-level connection management
24
+ *
25
+ * @example
26
+ * // Host a service
27
+ * const manager = new ConnectionManager({
28
+ * apiUrl: 'https://api.ronde.vu',
29
+ * credentials: await api.register()
30
+ * })
31
+ *
32
+ * await manager.hostService({
33
+ * service: 'chat.app@1.0.0',
34
+ * onConnection: (conn) => {
35
+ * conn.events.on('message', msg => console.log('Received:', msg))
36
+ * }
37
+ * })
38
+ *
39
+ * @example
40
+ * // Connect to a service
41
+ * const connection = await manager.connectToService({
42
+ * username: 'alice',
43
+ * service: 'chat.app@1.0.0'
44
+ * })
45
+ *
46
+ * await connection.sendMessage('Hello!')
47
+ */
48
+ export declare class ConnectionManager {
49
+ private readonly api;
50
+ private readonly username;
51
+ private readonly connections;
52
+ private readonly autoReconnect;
53
+ private readonly reconnectDelay;
54
+ private readonly maxReconnectAttempts;
55
+ private readonly bin;
56
+ constructor(options: ConnectionManagerOptions);
57
+ /**
58
+ * Host a service - Creates an offer and publishes it to the signaling server
59
+ *
60
+ * The service will automatically accept incoming connections and manage them.
61
+ * Each new connection triggers the onConnection callback.
62
+ *
63
+ * @param options - Service hosting options
64
+ * @returns Promise that resolves when the service is published
65
+ */
66
+ hostService(options: HostServiceOptions): Promise<void>;
67
+ /**
68
+ * Connect to a hosted service
69
+ *
70
+ * Searches for the service, retrieves the offer, and creates an answering connection.
71
+ *
72
+ * @param options - Connection options
73
+ * @returns The established connection
74
+ */
75
+ connectToService(options: ConnectToServiceOptions): Promise<WebRTCRondevuConnection>;
76
+ /**
77
+ * Get a connection by ID
78
+ */
79
+ getConnection(id: string): WebRTCRondevuConnection | undefined;
80
+ /**
81
+ * Get all managed connections
82
+ */
83
+ getAllConnections(): WebRTCRondevuConnection[];
84
+ /**
85
+ * Remove a connection
86
+ */
87
+ private removeConnection;
88
+ /**
89
+ * Schedule reconnection for a failed connection
90
+ */
91
+ private scheduleReconnect;
92
+ /**
93
+ * Attempt to reconnect a failed connection
94
+ */
95
+ private attemptReconnect;
96
+ /**
97
+ * Create a temporary signaler (used during initial offer creation)
98
+ */
99
+ private createTempSignaler;
100
+ /**
101
+ * Clean up all connections and resources
102
+ */
103
+ destroy(): void;
104
+ }