feat: Replace RondevuConnection with RondevuPeer state machine

- Created type-safe EventEmitter with generics
- Implemented state pattern for peer connection lifecycle
- Added comprehensive timeout handling for all connection phases
- Removed client-provided offer IDs (server generates hash-based IDs)
- Replaced RondevuConnection with RondevuPeer throughout
- Added states: idle, creating-offer, waiting-for-answer, answering, exchanging-ice, connected, failed, closed
- Configurable timeouts: ICE gathering, waiting for answer, creating answer, ICE connection
- Better error handling with 'failed' event and error details

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-16 16:33:44 +01:00
parent 14d3f943da
commit 280c8c284f
6 changed files with 693 additions and 432 deletions

View File

@@ -5,7 +5,6 @@ import { RondevuAuth } from './auth.js';
declare const Buffer: any;
export interface CreateOfferRequest {
id?: string;
sdp: string;
topics: string[];
ttl?: number;
@@ -24,18 +23,8 @@ 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: RTCIceCandidateInit; // Full candidate object
candidate: any; // Full candidate object as plain JSON - don't enforce structure
peerId: string;
role: 'offerer' | 'answerer';
createdAt: number;
@@ -290,7 +279,7 @@ export class RondevuOffers {
*/
async addIceCandidates(
offerId: string,
candidates: RTCIceCandidateInit[]
candidates: any[]
): Promise<void> {
const response = await this.fetchFn(`${this.baseUrl}/offers/${encodeURIComponent(offerId)}/ice-candidates`, {
method: 'POST',