Add RTCConfiguration support to ServiceHost and ServiceClient

- WebRTCContext now accepts optional RTCConfiguration
- ServiceHost and ServiceClient accept optional rtcConfiguration option
- Allows custom STUN/TURN server configuration
- Version bump to 0.10.1

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-07 19:43:34 +01:00
parent 54355323d9
commit fbd3be57d4
4 changed files with 42 additions and 31 deletions

View File

@@ -1,6 +1,6 @@
{
"name": "@xtr-dev/rondevu-client",
"version": "0.10.0",
"version": "0.10.1",
"description": "TypeScript client for Rondevu with durable WebRTC connections, automatic reconnection, and message queuing",
"type": "module",
"main": "dist/index.js",

View File

@@ -13,6 +13,7 @@ export interface ServiceClientOptions {
autoReconnect?: boolean
reconnectDelay?: number
maxReconnectAttempts?: number
rtcConfiguration?: RTCConfiguration
}
export interface ServiceClientEvents {
@@ -59,6 +60,7 @@ export class ServiceClient {
private readonly autoReconnect: boolean
private readonly reconnectDelay: number
private readonly maxReconnectAttempts: number
private readonly rtcConfiguration?: RTCConfiguration
private connection: WebRTCRondevuConnection | null = null
private reconnectAttempts = 0
private reconnectTimeout: ReturnType<typeof setTimeout> | null = null
@@ -74,6 +76,7 @@ export class ServiceClient {
this.autoReconnect = options.autoReconnect !== false
this.reconnectDelay = options.reconnectDelay || 2000
this.maxReconnectAttempts = options.maxReconnectAttempts || 5
this.rtcConfiguration = options.rtcConfiguration
}
/**
@@ -111,7 +114,7 @@ export class ServiceClient {
this.rondevuService.getAPI(),
serviceDetails.offerId
)
const context = new WebRTCContext(signaler)
const context = new WebRTCContext(signaler, this.rtcConfiguration)
// Create connection (answerer role)
const conn = new WebRTCRondevuConnection({

View File

@@ -14,6 +14,7 @@ export interface ServiceHostOptions {
ttl?: number
isPublic?: boolean
metadata?: Record<string, any>
rtcConfiguration?: RTCConfiguration
}
export interface ServiceHostEvents {
@@ -62,6 +63,7 @@ export class ServiceHost {
private readonly ttl: number
private readonly isPublic: boolean
private readonly metadata?: Record<string, any>
private readonly rtcConfiguration?: RTCConfiguration
private readonly bin = createBin()
private isStarted = false
@@ -74,6 +76,7 @@ export class ServiceHost {
this.ttl = options.ttl || 300000
this.isPublic = options.isPublic !== false
this.metadata = options.metadata
this.rtcConfiguration = options.rtcConfiguration
}
/**
@@ -140,7 +143,7 @@ export class ServiceHost {
private async createOffer(): Promise<void> {
try {
// Create temporary context with NoOp signaler
const tempContext = new WebRTCContext(new NoOpSignaler())
const tempContext = new WebRTCContext(new NoOpSignaler(), this.rtcConfiguration)
// Create connection (offerer role)
const conn = new WebRTCRondevuConnection({

View File

@@ -1,35 +1,40 @@
import { Signaler } from './types'
const DEFAULT_RTC_CONFIGURATION: RTCConfiguration = {
iceServers: [
{
urls: 'stun:stun.relay.metered.ca:80',
},
{
urls: 'turn:standard.relay.metered.ca:80',
username: 'c53a9c971da5e6f3bc959d8d',
credential: 'QaccPqtPPaxyokXp',
},
{
urls: 'turn:standard.relay.metered.ca:80?transport=tcp',
username: 'c53a9c971da5e6f3bc959d8d',
credential: 'QaccPqtPPaxyokXp',
},
{
urls: 'turn:standard.relay.metered.ca:443',
username: 'c53a9c971da5e6f3bc959d8d',
credential: 'QaccPqtPPaxyokXp',
},
{
urls: 'turns:standard.relay.metered.ca:443?transport=tcp',
username: 'c53a9c971da5e6f3bc959d8d',
credential: 'QaccPqtPPaxyokXp',
},
],
}
export class WebRTCContext {
constructor(public readonly signaler: Signaler) {}
constructor(
public readonly signaler: Signaler,
private readonly config?: RTCConfiguration
) {}
createPeerConnection(): RTCPeerConnection {
return new RTCPeerConnection({
iceServers: [
{
urls: 'stun:stun.relay.metered.ca:80',
},
{
urls: 'turn:standard.relay.metered.ca:80',
username: 'c53a9c971da5e6f3bc959d8d',
credential: 'QaccPqtPPaxyokXp',
},
{
urls: 'turn:standard.relay.metered.ca:80?transport=tcp',
username: 'c53a9c971da5e6f3bc959d8d',
credential: 'QaccPqtPPaxyokXp',
},
{
urls: 'turn:standard.relay.metered.ca:443',
username: 'c53a9c971da5e6f3bc959d8d',
credential: 'QaccPqtPPaxyokXp',
},
{
urls: 'turns:standard.relay.metered.ca:443?transport=tcp',
username: 'c53a9c971da5e6f3bc959d8d',
credential: 'QaccPqtPPaxyokXp',
},
],
})
return new RTCPeerConnection(this.config || DEFAULT_RTC_CONFIGURATION)
}
}