@xtr-dev/rondevu-client 0.21.3 → 0.21.5
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/dist/api/client.d.ts +6 -1
- package/dist/api/client.js +5 -2
- package/dist/connections/answerer.d.ts +2 -0
- package/dist/connections/answerer.js +3 -2
- package/dist/core/offer-pool.d.ts +13 -2
- package/dist/core/offer-pool.js +27 -2
- package/dist/core/peer.js +1 -0
- package/dist/core/polling-manager.d.ts +1 -0
- package/dist/core/polling-manager.js +1 -0
- package/dist/core/rondevu.d.ts +7 -0
- package/dist/core/rondevu.js +13 -2
- package/package.json +1 -1
package/dist/api/client.d.ts
CHANGED
|
@@ -153,8 +153,11 @@ export declare class RondevuAPI {
|
|
|
153
153
|
}>;
|
|
154
154
|
/**
|
|
155
155
|
* Answer an offer
|
|
156
|
+
* @param offerId The offer ID to answer
|
|
157
|
+
* @param sdp The SDP answer
|
|
158
|
+
* @param matchedTags Optional tags that were used to discover this offer
|
|
156
159
|
*/
|
|
157
|
-
answerOffer(offerId: string, sdp: string): Promise<void>;
|
|
160
|
+
answerOffer(offerId: string, sdp: string, matchedTags?: string[]): Promise<void>;
|
|
158
161
|
/**
|
|
159
162
|
* Get answer for a specific offer (offerer polls this)
|
|
160
163
|
*/
|
|
@@ -163,6 +166,7 @@ export declare class RondevuAPI {
|
|
|
163
166
|
offerId: string;
|
|
164
167
|
answererId: string;
|
|
165
168
|
answeredAt: number;
|
|
169
|
+
matchedTags?: string[];
|
|
166
170
|
} | null>;
|
|
167
171
|
/**
|
|
168
172
|
* Combined polling for answers and ICE candidates
|
|
@@ -173,6 +177,7 @@ export declare class RondevuAPI {
|
|
|
173
177
|
answererId: string;
|
|
174
178
|
sdp: string;
|
|
175
179
|
answeredAt: number;
|
|
180
|
+
matchedTags?: string[];
|
|
176
181
|
}>;
|
|
177
182
|
iceCandidates: Record<string, Array<{
|
|
178
183
|
candidate: RTCIceCandidateInit | null;
|
package/dist/api/client.js
CHANGED
|
@@ -325,11 +325,14 @@ export class RondevuAPI {
|
|
|
325
325
|
// ============================================
|
|
326
326
|
/**
|
|
327
327
|
* Answer an offer
|
|
328
|
+
* @param offerId The offer ID to answer
|
|
329
|
+
* @param sdp The SDP answer
|
|
330
|
+
* @param matchedTags Optional tags that were used to discover this offer
|
|
328
331
|
*/
|
|
329
|
-
async answerOffer(offerId, sdp) {
|
|
332
|
+
async answerOffer(offerId, sdp, matchedTags) {
|
|
330
333
|
const request = {
|
|
331
334
|
method: 'answerOffer',
|
|
332
|
-
params: { offerId, sdp },
|
|
335
|
+
params: { offerId, sdp, matchedTags },
|
|
333
336
|
};
|
|
334
337
|
const authHeaders = await this.generateAuthHeaders(request);
|
|
335
338
|
await this.rpc(request, authHeaders);
|
|
@@ -14,6 +14,7 @@ export interface AnswererOptions {
|
|
|
14
14
|
rtcConfig?: RTCConfiguration;
|
|
15
15
|
webrtcAdapter?: WebRTCAdapter;
|
|
16
16
|
config?: Partial<ConnectionConfig>;
|
|
17
|
+
matchedTags?: string[];
|
|
17
18
|
}
|
|
18
19
|
/**
|
|
19
20
|
* Answerer connection - processes offers and creates answers
|
|
@@ -24,6 +25,7 @@ export declare class AnswererConnection extends RondevuConnection {
|
|
|
24
25
|
private tags;
|
|
25
26
|
private offerId;
|
|
26
27
|
private offerSdp;
|
|
28
|
+
private matchedTags?;
|
|
27
29
|
constructor(options: AnswererOptions);
|
|
28
30
|
/**
|
|
29
31
|
* Initialize the connection by processing offer and creating answer
|
|
@@ -14,6 +14,7 @@ export class AnswererConnection extends RondevuConnection {
|
|
|
14
14
|
this.tags = options.tags;
|
|
15
15
|
this.offerId = options.offerId;
|
|
16
16
|
this.offerSdp = options.offerSdp;
|
|
17
|
+
this.matchedTags = options.matchedTags;
|
|
17
18
|
}
|
|
18
19
|
/**
|
|
19
20
|
* Initialize the connection by processing offer and creating answer
|
|
@@ -43,8 +44,8 @@ export class AnswererConnection extends RondevuConnection {
|
|
|
43
44
|
const answer = await this.pc.createAnswer();
|
|
44
45
|
await this.pc.setLocalDescription(answer);
|
|
45
46
|
this.debug('Answer created, sending to server');
|
|
46
|
-
// Send answer to server
|
|
47
|
-
await this.api.answerOffer(this.offerId, answer.sdp);
|
|
47
|
+
// Send answer to server (including matched tags so offerer knows which tags we searched for)
|
|
48
|
+
await this.api.answerOffer(this.offerId, answer.sdp, this.matchedTags);
|
|
48
49
|
// Note: ICE candidate polling is handled by PollingManager
|
|
49
50
|
// Candidates are received via handleRemoteIceCandidates()
|
|
50
51
|
this.debug('Answer sent successfully');
|
|
@@ -22,7 +22,7 @@ export interface OfferPoolOptions {
|
|
|
22
22
|
debugEnabled?: boolean;
|
|
23
23
|
}
|
|
24
24
|
interface OfferPoolEvents {
|
|
25
|
-
'connection:opened': (offerId: string, connection: OffererConnection) => void;
|
|
25
|
+
'connection:opened': (offerId: string, connection: OffererConnection, matchedTags?: string[]) => void;
|
|
26
26
|
'offer:created': (offerId: string, tags: string[]) => void;
|
|
27
27
|
'offer:failed': (offerId: string, error: Error) => void;
|
|
28
28
|
'connection:rotated': (oldOfferId: string, newOfferId: string, connection: OffererConnection) => void;
|
|
@@ -34,7 +34,7 @@ interface OfferPoolEvents {
|
|
|
34
34
|
*/
|
|
35
35
|
export declare class OfferPool extends EventEmitter<OfferPoolEvents> {
|
|
36
36
|
private readonly api;
|
|
37
|
-
private
|
|
37
|
+
private tags;
|
|
38
38
|
private readonly ownerUsername;
|
|
39
39
|
private readonly maxOffers;
|
|
40
40
|
private readonly offerFactory;
|
|
@@ -45,6 +45,7 @@ export declare class OfferPool extends EventEmitter<OfferPoolEvents> {
|
|
|
45
45
|
private readonly connectionConfig?;
|
|
46
46
|
private readonly debugEnabled;
|
|
47
47
|
private readonly activeConnections;
|
|
48
|
+
private readonly matchedTagsByOffer;
|
|
48
49
|
private readonly fillLock;
|
|
49
50
|
private running;
|
|
50
51
|
constructor(options: OfferPoolOptions);
|
|
@@ -62,6 +63,16 @@ export declare class OfferPool extends EventEmitter<OfferPoolEvents> {
|
|
|
62
63
|
* Get count of active offers
|
|
63
64
|
*/
|
|
64
65
|
getOfferCount(): number;
|
|
66
|
+
/**
|
|
67
|
+
* Update tags for new offers
|
|
68
|
+
* Existing offers keep their old tags until they expire/rotate
|
|
69
|
+
* New offers created during fill will use the updated tags
|
|
70
|
+
*/
|
|
71
|
+
updateTags(newTags: string[]): void;
|
|
72
|
+
/**
|
|
73
|
+
* Get current tags
|
|
74
|
+
*/
|
|
75
|
+
getTags(): string[];
|
|
65
76
|
/**
|
|
66
77
|
* Get all active connections
|
|
67
78
|
*/
|
package/dist/core/offer-pool.js
CHANGED
|
@@ -11,6 +11,7 @@ export class OfferPool extends EventEmitter {
|
|
|
11
11
|
super();
|
|
12
12
|
// State
|
|
13
13
|
this.activeConnections = new Map();
|
|
14
|
+
this.matchedTagsByOffer = new Map(); // Track matchedTags from answers
|
|
14
15
|
this.fillLock = new AsyncLock();
|
|
15
16
|
this.running = false;
|
|
16
17
|
this.api = options.api;
|
|
@@ -62,6 +63,21 @@ export class OfferPool extends EventEmitter {
|
|
|
62
63
|
getOfferCount() {
|
|
63
64
|
return this.activeConnections.size;
|
|
64
65
|
}
|
|
66
|
+
/**
|
|
67
|
+
* Update tags for new offers
|
|
68
|
+
* Existing offers keep their old tags until they expire/rotate
|
|
69
|
+
* New offers created during fill will use the updated tags
|
|
70
|
+
*/
|
|
71
|
+
updateTags(newTags) {
|
|
72
|
+
this.debug(`Updating tags: ${newTags.join(', ')}`);
|
|
73
|
+
this.tags = newTags;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Get current tags
|
|
77
|
+
*/
|
|
78
|
+
getTags() {
|
|
79
|
+
return [...this.tags];
|
|
80
|
+
}
|
|
65
81
|
/**
|
|
66
82
|
* Get all active connections
|
|
67
83
|
*/
|
|
@@ -191,8 +207,13 @@ export class OfferPool extends EventEmitter {
|
|
|
191
207
|
});
|
|
192
208
|
// Setup connection event handlers
|
|
193
209
|
connection.on('connected', () => {
|
|
194
|
-
|
|
195
|
-
|
|
210
|
+
// Use getOfferId() to get current ID after potential rotations
|
|
211
|
+
const currentOfferId = connection.getOfferId();
|
|
212
|
+
this.debug(`Connection established for offer ${currentOfferId}`);
|
|
213
|
+
// Get and clean up matchedTags
|
|
214
|
+
const matchedTags = this.matchedTagsByOffer.get(currentOfferId);
|
|
215
|
+
this.matchedTagsByOffer.delete(currentOfferId);
|
|
216
|
+
this.emit('connection:opened', currentOfferId, connection, matchedTags);
|
|
196
217
|
});
|
|
197
218
|
connection.on('failed', async (error) => {
|
|
198
219
|
const currentOfferId = connection.getOfferId();
|
|
@@ -245,6 +266,10 @@ export class OfferPool extends EventEmitter {
|
|
|
245
266
|
const connection = this.activeConnections.get(data.offerId);
|
|
246
267
|
if (connection) {
|
|
247
268
|
this.debug(`Processing answer for offer ${data.offerId}`);
|
|
269
|
+
// Store matchedTags for when connection opens
|
|
270
|
+
if (data.matchedTags) {
|
|
271
|
+
this.matchedTagsByOffer.set(data.offerId, data.matchedTags);
|
|
272
|
+
}
|
|
248
273
|
try {
|
|
249
274
|
await connection.processAnswer(data.sdp, data.answererId);
|
|
250
275
|
// Create replacement offer
|
package/dist/core/peer.js
CHANGED
|
@@ -82,6 +82,7 @@ export class PollingManager extends EventEmitter {
|
|
|
82
82
|
answererId: answer.answererId,
|
|
83
83
|
sdp: answer.sdp,
|
|
84
84
|
answeredAt: answer.answeredAt,
|
|
85
|
+
matchedTags: answer.matchedTags,
|
|
85
86
|
});
|
|
86
87
|
// Update last poll timestamp
|
|
87
88
|
if (answer.answeredAt > this.lastPollTimestamp) {
|
package/dist/core/rondevu.d.ts
CHANGED
|
@@ -173,6 +173,13 @@ export declare class Rondevu extends EventEmitter {
|
|
|
173
173
|
* Similar to stopFilling() but doesn't stop the polling/filling process
|
|
174
174
|
*/
|
|
175
175
|
disconnectAll(): void;
|
|
176
|
+
/**
|
|
177
|
+
* Update tags for new offers
|
|
178
|
+
* Existing offers keep their old tags until they expire/rotate
|
|
179
|
+
* New offers created during fill will use the updated tags
|
|
180
|
+
* @param newTags - The new tags to use for future offers
|
|
181
|
+
*/
|
|
182
|
+
updateOfferTags(newTags: string[]): void;
|
|
176
183
|
/**
|
|
177
184
|
* Get the current publishing status
|
|
178
185
|
* @returns Object with publishing state information
|
package/dist/core/rondevu.js
CHANGED
|
@@ -222,8 +222,8 @@ export class Rondevu extends EventEmitter {
|
|
|
222
222
|
debugEnabled: this.debugEnabled,
|
|
223
223
|
});
|
|
224
224
|
// Forward events from OfferPool
|
|
225
|
-
this.offerPool.on('connection:opened', (offerId, connection) => {
|
|
226
|
-
this.emit('connection:opened', offerId, connection);
|
|
225
|
+
this.offerPool.on('connection:opened', (offerId, connection, matchedTags) => {
|
|
226
|
+
this.emit('connection:opened', offerId, connection, matchedTags);
|
|
227
227
|
});
|
|
228
228
|
this.offerPool.on('offer:created', (offerId, tags) => {
|
|
229
229
|
this.emit('offer:created', offerId, tags);
|
|
@@ -314,6 +314,17 @@ export class Rondevu extends EventEmitter {
|
|
|
314
314
|
this.debug('Disconnecting all offers');
|
|
315
315
|
this.offerPool?.disconnectAll();
|
|
316
316
|
}
|
|
317
|
+
/**
|
|
318
|
+
* Update tags for new offers
|
|
319
|
+
* Existing offers keep their old tags until they expire/rotate
|
|
320
|
+
* New offers created during fill will use the updated tags
|
|
321
|
+
* @param newTags - The new tags to use for future offers
|
|
322
|
+
*/
|
|
323
|
+
updateOfferTags(newTags) {
|
|
324
|
+
this.debug(`Updating offer tags: ${newTags.join(', ')}`);
|
|
325
|
+
this.currentTags = newTags;
|
|
326
|
+
this.offerPool?.updateTags(newTags);
|
|
327
|
+
}
|
|
317
328
|
/**
|
|
318
329
|
* Get the current publishing status
|
|
319
330
|
* @returns Object with publishing state information
|
package/package.json
CHANGED