diff --git a/src/connection.ts b/src/connection.ts index f9012b3..bc1d0e8 100644 --- a/src/connection.ts +++ b/src/connection.ts @@ -1,4 +1,4 @@ -import { RondevuOffers } from './offers.js'; +import { RondevuOffers, RTCIceCandidateInit } from './offers.js'; /** * Events emitted by RondevuConnection @@ -60,11 +60,7 @@ export class RondevuConnection { private lastIceTimestamp: number = Date.now(); private eventListeners: Map> = new Map(); private dataChannel?: RTCDataChannel; - private pendingIceCandidates: Array<{ - candidate: string; - sdpMid: string | null; - sdpMLineIndex: number | null; - }> = []; + private pendingIceCandidates: RTCIceCandidateInit[] = []; /** * Current connection state @@ -107,10 +103,12 @@ export class RondevuConnection { private setupPeerConnection(): void { this.pc.onicecandidate = async (event) => { if (event.candidate) { - const candidateData = { + // Convert RTCIceCandidate to RTCIceCandidateInit (plain object) + const candidateData: RTCIceCandidateInit = { candidate: event.candidate.candidate, sdpMid: event.candidate.sdpMid, sdpMLineIndex: event.candidate.sdpMLineIndex, + usernameFragment: event.candidate.usernameFragment, }; if (this.offerId) { @@ -282,14 +280,10 @@ export class RondevuConnection { this.lastIceTimestamp ); - for (const candidate of candidates) { - // Create ICE candidate with all fields - await this.pc.addIceCandidate(new RTCIceCandidate({ - candidate: candidate.candidate, - sdpMid: candidate.sdpMid ?? undefined, - sdpMLineIndex: candidate.sdpMLineIndex ?? undefined, - })); - this.lastIceTimestamp = candidate.createdAt; + for (const cand of candidates) { + // Use the candidate object directly - it's already RTCIceCandidateInit + await this.pc.addIceCandidate(new RTCIceCandidate(cand.candidate)); + this.lastIceTimestamp = cand.createdAt; } } catch (err) { console.error('Error polling for ICE candidates:', err); diff --git a/src/offers.ts b/src/offers.ts index 52b65b8..921d862 100644 --- a/src/offers.ts +++ b/src/offers.ts @@ -24,10 +24,18 @@ export interface Offer { answeredAt?: number; } +/** + * RTCIceCandidateInit interface for environments without native WebRTC types + */ +export interface RTCIceCandidateInit { + candidate?: string; + sdpMid?: string | null; + sdpMLineIndex?: number | null; + usernameFragment?: string | null; +} + export interface IceCandidate { - candidate: string; - sdpMid: string | null; - sdpMLineIndex: number | null; + candidate: RTCIceCandidateInit; // Full candidate object peerId: string; role: 'offerer' | 'answerer'; createdAt: number; @@ -282,11 +290,7 @@ export class RondevuOffers { */ async addIceCandidates( offerId: string, - candidates: Array<{ - candidate: string; - sdpMid?: string | null; - sdpMLineIndex?: number | null; - }> + candidates: RTCIceCandidateInit[] ): Promise { const response = await this.fetchFn(`${this.baseUrl}/offers/${encodeURIComponent(offerId)}/ice-candidates`, { method: 'POST',