diff --git a/README.md b/README.md index c0bd52b..f6561b0 100644 --- a/README.md +++ b/README.md @@ -49,8 +49,8 @@ const rondevu = await Rondevu.connect({ await rondevu.publishService({ service: 'chat:1.0.0', maxOffers: 5, // Maintain up to 5 concurrent offers - offerFactory: async (rtcConfig) => { - const pc = new RTCPeerConnection(rtcConfig) + offerFactory: async (pc) => { + // pc is created by Rondevu with ICE handlers already attached const dc = pc.createDataChannel('chat') dc.addEventListener('open', () => { @@ -64,7 +64,7 @@ await rondevu.publishService({ const offer = await pc.createOffer() await pc.setLocalDescription(offer) - return { pc, dc, offer } + return { dc, offer } } }) diff --git a/src/rondevu.ts b/src/rondevu.ts index 90ce68b..a6b9a0a 100644 --- a/src/rondevu.ts +++ b/src/rondevu.ts @@ -382,6 +382,10 @@ export class Rondevu { /** * Set up ICE candidate handler to send candidates to the server + * + * Note: This is used by connectToService() where the offerId is already known. + * For createOffer(), we use inline ICE handling with early candidate queuing + * since the offerId isn't available until after the factory completes. */ private setupIceCandidateHandler( pc: RTCPeerConnection, @@ -434,7 +438,7 @@ export class Rondevu { // This ensures we capture all candidates, even those generated immediately // when setLocalDescription() is called in the factory const earlyIceCandidates: RTCIceCandidateInit[] = [] - let offerId: string | null = null + let offerId: string | undefined pc.onicecandidate = async (event) => { if (event.candidate) { @@ -461,7 +465,17 @@ export class Rondevu { // 3. Call the factory with the pc - factory creates data channel and offer // When factory calls setLocalDescription(), ICE gathering starts and // candidates are captured by the handler we set up above - const { dc, offer } = await this.offerFactory(pc) + let dc: RTCDataChannel | undefined + let offer: RTCSessionDescriptionInit + try { + const factoryResult = await this.offerFactory(pc) + dc = factoryResult.dc + offer = factoryResult.offer + } catch (err) { + // Clean up the connection if factory fails + pc.close() + throw err + } // 4. Publish to server to get offerId const result = await this.api.publishService({