@xtr-dev/rondevu-client 0.9.1 → 0.10.0
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.d.ts +147 -0
- package/dist/api.js +307 -0
- package/dist/bin.d.ts +35 -0
- package/dist/bin.js +35 -0
- package/dist/connection-manager.d.ts +104 -0
- package/dist/connection-manager.js +324 -0
- package/dist/connection.d.ts +112 -0
- package/dist/connection.js +194 -0
- package/dist/event-bus.d.ts +52 -0
- package/dist/event-bus.js +84 -0
- package/dist/index.d.ts +15 -11
- package/dist/index.js +9 -11
- package/dist/noop-signaler.d.ts +14 -0
- package/dist/noop-signaler.js +27 -0
- package/dist/rondevu-service.d.ts +81 -0
- package/dist/rondevu-service.js +131 -0
- package/dist/service-client.d.ts +92 -0
- package/dist/service-client.js +185 -0
- package/dist/service-host.d.ts +101 -0
- package/dist/service-host.js +185 -0
- package/dist/signaler.d.ts +25 -0
- package/dist/signaler.js +89 -0
- package/dist/types.d.ts +33 -0
- package/dist/types.js +2 -0
- package/dist/webrtc-context.d.ts +6 -0
- package/dist/webrtc-context.js +34 -0
- package/package.json +16 -2
- package/dist/auth.d.ts +0 -20
- package/dist/auth.js +0 -41
- package/dist/durable/channel.d.ts +0 -115
- package/dist/durable/channel.js +0 -301
- package/dist/durable/connection.d.ts +0 -125
- package/dist/durable/connection.js +0 -370
- package/dist/durable/reconnection.d.ts +0 -90
- package/dist/durable/reconnection.js +0 -127
- package/dist/durable/service.d.ts +0 -103
- package/dist/durable/service.js +0 -264
- package/dist/durable/types.d.ts +0 -149
- package/dist/durable/types.js +0 -28
- package/dist/event-emitter.d.ts +0 -54
- package/dist/event-emitter.js +0 -102
- package/dist/offer-pool.d.ts +0 -86
- package/dist/offer-pool.js +0 -145
- package/dist/offers.d.ts +0 -101
- package/dist/offers.js +0 -202
- package/dist/peer/answering-state.d.ts +0 -11
- package/dist/peer/answering-state.js +0 -39
- package/dist/peer/closed-state.d.ts +0 -8
- package/dist/peer/closed-state.js +0 -10
- package/dist/peer/connected-state.d.ts +0 -8
- package/dist/peer/connected-state.js +0 -11
- package/dist/peer/creating-offer-state.d.ts +0 -12
- package/dist/peer/creating-offer-state.js +0 -45
- package/dist/peer/exchanging-ice-state.d.ts +0 -17
- package/dist/peer/exchanging-ice-state.js +0 -64
- package/dist/peer/failed-state.d.ts +0 -10
- package/dist/peer/failed-state.js +0 -16
- package/dist/peer/idle-state.d.ts +0 -7
- package/dist/peer/idle-state.js +0 -14
- package/dist/peer/index.d.ts +0 -71
- package/dist/peer/index.js +0 -176
- package/dist/peer/state.d.ts +0 -23
- package/dist/peer/state.js +0 -63
- package/dist/peer/types.d.ts +0 -43
- package/dist/peer/types.js +0 -1
- package/dist/peer/waiting-for-answer-state.d.ts +0 -17
- package/dist/peer/waiting-for-answer-state.js +0 -60
- package/dist/rondevu.d.ts +0 -184
- package/dist/rondevu.js +0 -171
- package/dist/service-pool.d.ts +0 -123
- package/dist/service-pool.js +0 -417
- package/dist/usernames.d.ts +0 -79
- package/dist/usernames.js +0 -153
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { PeerState } from './state.js';
|
|
2
|
-
/**
|
|
3
|
-
* Failed state - connection attempt failed
|
|
4
|
-
*/
|
|
5
|
-
export class FailedState extends PeerState {
|
|
6
|
-
constructor(peer, error) {
|
|
7
|
-
super(peer);
|
|
8
|
-
this.error = error;
|
|
9
|
-
peer.emitEvent('failed', error);
|
|
10
|
-
}
|
|
11
|
-
get name() { return 'failed'; }
|
|
12
|
-
cleanup() {
|
|
13
|
-
// Connection is failed, clean up resources
|
|
14
|
-
this.peer.pc.close();
|
|
15
|
-
}
|
|
16
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { PeerState } from './state.js';
|
|
2
|
-
import type { PeerOptions } from './types.js';
|
|
3
|
-
export declare class IdleState extends PeerState {
|
|
4
|
-
get name(): string;
|
|
5
|
-
createOffer(options: PeerOptions): Promise<string>;
|
|
6
|
-
answer(offerId: string, offerSdp: string, options: PeerOptions): Promise<void>;
|
|
7
|
-
}
|
package/dist/peer/idle-state.js
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { PeerState } from './state.js';
|
|
2
|
-
export class IdleState extends PeerState {
|
|
3
|
-
get name() { return 'idle'; }
|
|
4
|
-
async createOffer(options) {
|
|
5
|
-
const { CreatingOfferState } = await import('./creating-offer-state.js');
|
|
6
|
-
this.peer.setState(new CreatingOfferState(this.peer, options));
|
|
7
|
-
return this.peer.state.createOffer(options);
|
|
8
|
-
}
|
|
9
|
-
async answer(offerId, offerSdp, options) {
|
|
10
|
-
const { AnsweringState } = await import('./answering-state.js');
|
|
11
|
-
this.peer.setState(new AnsweringState(this.peer));
|
|
12
|
-
return this.peer.state.answer(offerId, offerSdp, options);
|
|
13
|
-
}
|
|
14
|
-
}
|
package/dist/peer/index.d.ts
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import { RondevuOffers } from '../offers.js';
|
|
2
|
-
import { EventEmitter } from '../event-emitter.js';
|
|
3
|
-
import type { PeerOptions, PeerEvents } from './types.js';
|
|
4
|
-
import { PeerState } from './state.js';
|
|
5
|
-
export type { PeerTimeouts, PeerOptions, PeerEvents } from './types.js';
|
|
6
|
-
/**
|
|
7
|
-
* High-level WebRTC peer connection manager with state-based lifecycle
|
|
8
|
-
* Handles offer/answer exchange, ICE candidates, timeouts, and error recovery
|
|
9
|
-
*/
|
|
10
|
-
export default class RondevuPeer extends EventEmitter<PeerEvents> {
|
|
11
|
-
pc: RTCPeerConnection;
|
|
12
|
-
offersApi: RondevuOffers;
|
|
13
|
-
offerId?: string;
|
|
14
|
-
role?: 'offerer' | 'answerer';
|
|
15
|
-
RTCPeerConnection: typeof RTCPeerConnection;
|
|
16
|
-
RTCSessionDescription: typeof RTCSessionDescription;
|
|
17
|
-
RTCIceCandidate: typeof RTCIceCandidate;
|
|
18
|
-
private _state;
|
|
19
|
-
private connectionStateChangeHandler?;
|
|
20
|
-
private dataChannelHandler?;
|
|
21
|
-
private trackHandler?;
|
|
22
|
-
private iceCandidateErrorHandler?;
|
|
23
|
-
/**
|
|
24
|
-
* Current connection state name
|
|
25
|
-
*/
|
|
26
|
-
get stateName(): string;
|
|
27
|
-
/**
|
|
28
|
-
* Current state object (internal use)
|
|
29
|
-
*/
|
|
30
|
-
get state(): PeerState;
|
|
31
|
-
/**
|
|
32
|
-
* RTCPeerConnection state
|
|
33
|
-
*/
|
|
34
|
-
get connectionState(): RTCPeerConnectionState;
|
|
35
|
-
constructor(offersApi: RondevuOffers, rtcConfig?: RTCConfiguration, existingPeerConnection?: RTCPeerConnection, rtcPeerConnection?: typeof RTCPeerConnection, rtcSessionDescription?: typeof RTCSessionDescription, rtcIceCandidate?: typeof RTCIceCandidate);
|
|
36
|
-
/**
|
|
37
|
-
* Set up peer connection event handlers
|
|
38
|
-
*/
|
|
39
|
-
private setupPeerConnection;
|
|
40
|
-
/**
|
|
41
|
-
* Set new state and emit state change event
|
|
42
|
-
*/
|
|
43
|
-
setState(newState: PeerState): void;
|
|
44
|
-
/**
|
|
45
|
-
* Emit event (exposed for PeerState classes)
|
|
46
|
-
* @internal
|
|
47
|
-
*/
|
|
48
|
-
emitEvent<K extends keyof PeerEvents>(event: K, ...args: Parameters<PeerEvents[K]>): void;
|
|
49
|
-
/**
|
|
50
|
-
* Create an offer and advertise on topics
|
|
51
|
-
*/
|
|
52
|
-
createOffer(options: PeerOptions): Promise<string>;
|
|
53
|
-
/**
|
|
54
|
-
* Answer an existing offer
|
|
55
|
-
*/
|
|
56
|
-
answer(offerId: string, offerSdp: string, options: PeerOptions): Promise<void>;
|
|
57
|
-
/**
|
|
58
|
-
* Add a media track to the connection
|
|
59
|
-
*/
|
|
60
|
-
addTrack(track: MediaStreamTrack, ...streams: MediaStream[]): RTCRtpSender;
|
|
61
|
-
/**
|
|
62
|
-
* Create a data channel for sending and receiving arbitrary data
|
|
63
|
-
* This should typically be called by the offerer before creating the offer
|
|
64
|
-
* The answerer will receive the channel via the 'datachannel' event
|
|
65
|
-
*/
|
|
66
|
-
createDataChannel(label: string, options?: RTCDataChannelInit): RTCDataChannel;
|
|
67
|
-
/**
|
|
68
|
-
* Close the connection and clean up
|
|
69
|
-
*/
|
|
70
|
-
close(): Promise<void>;
|
|
71
|
-
}
|
package/dist/peer/index.js
DELETED
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
import { EventEmitter } from '../event-emitter.js';
|
|
2
|
-
import { IdleState } from './idle-state.js';
|
|
3
|
-
import { ConnectedState } from './connected-state.js';
|
|
4
|
-
import { FailedState } from './failed-state.js';
|
|
5
|
-
import { ClosedState } from './closed-state.js';
|
|
6
|
-
/**
|
|
7
|
-
* High-level WebRTC peer connection manager with state-based lifecycle
|
|
8
|
-
* Handles offer/answer exchange, ICE candidates, timeouts, and error recovery
|
|
9
|
-
*/
|
|
10
|
-
export default class RondevuPeer extends EventEmitter {
|
|
11
|
-
/**
|
|
12
|
-
* Current connection state name
|
|
13
|
-
*/
|
|
14
|
-
get stateName() {
|
|
15
|
-
return this._state.name;
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* Current state object (internal use)
|
|
19
|
-
*/
|
|
20
|
-
get state() {
|
|
21
|
-
return this._state;
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* RTCPeerConnection state
|
|
25
|
-
*/
|
|
26
|
-
get connectionState() {
|
|
27
|
-
return this.pc.connectionState;
|
|
28
|
-
}
|
|
29
|
-
constructor(offersApi, rtcConfig = {
|
|
30
|
-
iceServers: [
|
|
31
|
-
{ urls: 'stun:stun.l.google.com:19302' },
|
|
32
|
-
{ urls: 'stun:stun1.l.google.com:19302' }
|
|
33
|
-
]
|
|
34
|
-
}, existingPeerConnection, rtcPeerConnection, rtcSessionDescription, rtcIceCandidate) {
|
|
35
|
-
super();
|
|
36
|
-
this.offersApi = offersApi;
|
|
37
|
-
// Use provided polyfills or fall back to globals
|
|
38
|
-
this.RTCPeerConnection = rtcPeerConnection || (typeof globalThis.RTCPeerConnection !== 'undefined'
|
|
39
|
-
? globalThis.RTCPeerConnection
|
|
40
|
-
: (() => {
|
|
41
|
-
throw new Error('RTCPeerConnection is not available. Please provide it in the Rondevu constructor options for Node.js environments.');
|
|
42
|
-
}));
|
|
43
|
-
this.RTCSessionDescription = rtcSessionDescription || (typeof globalThis.RTCSessionDescription !== 'undefined'
|
|
44
|
-
? globalThis.RTCSessionDescription
|
|
45
|
-
: (() => {
|
|
46
|
-
throw new Error('RTCSessionDescription is not available. Please provide it in the Rondevu constructor options for Node.js environments.');
|
|
47
|
-
}));
|
|
48
|
-
this.RTCIceCandidate = rtcIceCandidate || (typeof globalThis.RTCIceCandidate !== 'undefined'
|
|
49
|
-
? globalThis.RTCIceCandidate
|
|
50
|
-
: (() => {
|
|
51
|
-
throw new Error('RTCIceCandidate is not available. Please provide it in the Rondevu constructor options for Node.js environments.');
|
|
52
|
-
}));
|
|
53
|
-
// Use existing peer connection if provided, otherwise create new one
|
|
54
|
-
this.pc = existingPeerConnection || new this.RTCPeerConnection(rtcConfig);
|
|
55
|
-
this._state = new IdleState(this);
|
|
56
|
-
this.setupPeerConnection();
|
|
57
|
-
}
|
|
58
|
-
/**
|
|
59
|
-
* Set up peer connection event handlers
|
|
60
|
-
*/
|
|
61
|
-
setupPeerConnection() {
|
|
62
|
-
this.connectionStateChangeHandler = () => {
|
|
63
|
-
console.log(`🔌 Connection state changed: ${this.pc.connectionState}`);
|
|
64
|
-
switch (this.pc.connectionState) {
|
|
65
|
-
case 'connected':
|
|
66
|
-
console.log('✅ WebRTC connection established');
|
|
67
|
-
this.setState(new ConnectedState(this));
|
|
68
|
-
this.emitEvent('connected');
|
|
69
|
-
break;
|
|
70
|
-
case 'disconnected':
|
|
71
|
-
console.log('⚠️ WebRTC connection disconnected');
|
|
72
|
-
this.emitEvent('disconnected');
|
|
73
|
-
break;
|
|
74
|
-
case 'failed':
|
|
75
|
-
console.log('❌ WebRTC connection failed');
|
|
76
|
-
this.setState(new FailedState(this, new Error('Connection failed')));
|
|
77
|
-
break;
|
|
78
|
-
case 'closed':
|
|
79
|
-
console.log('🔒 WebRTC connection closed');
|
|
80
|
-
this.setState(new ClosedState(this));
|
|
81
|
-
this.emitEvent('disconnected');
|
|
82
|
-
break;
|
|
83
|
-
}
|
|
84
|
-
};
|
|
85
|
-
this.pc.addEventListener('connectionstatechange', this.connectionStateChangeHandler);
|
|
86
|
-
// Add ICE connection state logging
|
|
87
|
-
const iceConnectionStateHandler = () => {
|
|
88
|
-
console.log(`🧊 ICE connection state: ${this.pc.iceConnectionState}`);
|
|
89
|
-
};
|
|
90
|
-
this.pc.addEventListener('iceconnectionstatechange', iceConnectionStateHandler);
|
|
91
|
-
// Add ICE gathering state logging
|
|
92
|
-
const iceGatheringStateHandler = () => {
|
|
93
|
-
console.log(`🔍 ICE gathering state: ${this.pc.iceGatheringState}`);
|
|
94
|
-
};
|
|
95
|
-
this.pc.addEventListener('icegatheringstatechange', iceGatheringStateHandler);
|
|
96
|
-
this.dataChannelHandler = (event) => {
|
|
97
|
-
this.emitEvent('datachannel', event.channel);
|
|
98
|
-
};
|
|
99
|
-
this.pc.addEventListener('datachannel', this.dataChannelHandler);
|
|
100
|
-
this.trackHandler = (event) => {
|
|
101
|
-
this.emitEvent('track', event);
|
|
102
|
-
};
|
|
103
|
-
this.pc.addEventListener('track', this.trackHandler);
|
|
104
|
-
this.iceCandidateErrorHandler = (event) => {
|
|
105
|
-
const iceError = event;
|
|
106
|
-
console.error(`❌ ICE candidate error: ${iceError.errorText || 'Unknown error'}`, {
|
|
107
|
-
errorCode: iceError.errorCode,
|
|
108
|
-
url: iceError.url,
|
|
109
|
-
address: iceError.address,
|
|
110
|
-
port: iceError.port
|
|
111
|
-
});
|
|
112
|
-
};
|
|
113
|
-
this.pc.addEventListener('icecandidateerror', this.iceCandidateErrorHandler);
|
|
114
|
-
}
|
|
115
|
-
/**
|
|
116
|
-
* Set new state and emit state change event
|
|
117
|
-
*/
|
|
118
|
-
setState(newState) {
|
|
119
|
-
this._state.cleanup();
|
|
120
|
-
this._state = newState;
|
|
121
|
-
this.emitEvent('state', newState.name);
|
|
122
|
-
}
|
|
123
|
-
/**
|
|
124
|
-
* Emit event (exposed for PeerState classes)
|
|
125
|
-
* @internal
|
|
126
|
-
*/
|
|
127
|
-
emitEvent(event, ...args) {
|
|
128
|
-
this.emit(event, ...args);
|
|
129
|
-
}
|
|
130
|
-
/**
|
|
131
|
-
* Create an offer and advertise on topics
|
|
132
|
-
*/
|
|
133
|
-
async createOffer(options) {
|
|
134
|
-
return this._state.createOffer(options);
|
|
135
|
-
}
|
|
136
|
-
/**
|
|
137
|
-
* Answer an existing offer
|
|
138
|
-
*/
|
|
139
|
-
async answer(offerId, offerSdp, options) {
|
|
140
|
-
return this._state.answer(offerId, offerSdp, options);
|
|
141
|
-
}
|
|
142
|
-
/**
|
|
143
|
-
* Add a media track to the connection
|
|
144
|
-
*/
|
|
145
|
-
addTrack(track, ...streams) {
|
|
146
|
-
return this.pc.addTrack(track, ...streams);
|
|
147
|
-
}
|
|
148
|
-
/**
|
|
149
|
-
* Create a data channel for sending and receiving arbitrary data
|
|
150
|
-
* This should typically be called by the offerer before creating the offer
|
|
151
|
-
* The answerer will receive the channel via the 'datachannel' event
|
|
152
|
-
*/
|
|
153
|
-
createDataChannel(label, options) {
|
|
154
|
-
return this.pc.createDataChannel(label, options);
|
|
155
|
-
}
|
|
156
|
-
/**
|
|
157
|
-
* Close the connection and clean up
|
|
158
|
-
*/
|
|
159
|
-
async close() {
|
|
160
|
-
// Remove RTCPeerConnection event listeners
|
|
161
|
-
if (this.connectionStateChangeHandler) {
|
|
162
|
-
this.pc.removeEventListener('connectionstatechange', this.connectionStateChangeHandler);
|
|
163
|
-
}
|
|
164
|
-
if (this.dataChannelHandler) {
|
|
165
|
-
this.pc.removeEventListener('datachannel', this.dataChannelHandler);
|
|
166
|
-
}
|
|
167
|
-
if (this.trackHandler) {
|
|
168
|
-
this.pc.removeEventListener('track', this.trackHandler);
|
|
169
|
-
}
|
|
170
|
-
if (this.iceCandidateErrorHandler) {
|
|
171
|
-
this.pc.removeEventListener('icecandidateerror', this.iceCandidateErrorHandler);
|
|
172
|
-
}
|
|
173
|
-
await this._state.close();
|
|
174
|
-
this.removeAllListeners();
|
|
175
|
-
}
|
|
176
|
-
}
|
package/dist/peer/state.d.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import type { PeerOptions } from './types.js';
|
|
2
|
-
import type RondevuPeer from './index.js';
|
|
3
|
-
/**
|
|
4
|
-
* Base class for peer connection states
|
|
5
|
-
* Implements the State pattern for managing WebRTC connection lifecycle
|
|
6
|
-
*/
|
|
7
|
-
export declare abstract class PeerState {
|
|
8
|
-
protected peer: RondevuPeer;
|
|
9
|
-
protected iceCandidateHandler?: (event: RTCPeerConnectionIceEvent) => void;
|
|
10
|
-
constructor(peer: RondevuPeer);
|
|
11
|
-
abstract get name(): string;
|
|
12
|
-
createOffer(options: PeerOptions): Promise<string>;
|
|
13
|
-
answer(offerId: string, offerSdp: string, options: PeerOptions): Promise<void>;
|
|
14
|
-
handleAnswer(sdp: string): Promise<void>;
|
|
15
|
-
handleIceCandidate(candidate: any): Promise<void>;
|
|
16
|
-
/**
|
|
17
|
-
* Setup trickle ICE candidate handler
|
|
18
|
-
* Sends local ICE candidates to server as they are discovered
|
|
19
|
-
*/
|
|
20
|
-
protected setupIceCandidateHandler(): void;
|
|
21
|
-
cleanup(): void;
|
|
22
|
-
close(): Promise<void>;
|
|
23
|
-
}
|
package/dist/peer/state.js
DELETED
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Base class for peer connection states
|
|
3
|
-
* Implements the State pattern for managing WebRTC connection lifecycle
|
|
4
|
-
*/
|
|
5
|
-
export class PeerState {
|
|
6
|
-
constructor(peer) {
|
|
7
|
-
this.peer = peer;
|
|
8
|
-
}
|
|
9
|
-
async createOffer(options) {
|
|
10
|
-
throw new Error(`Cannot create offer in ${this.name} state`);
|
|
11
|
-
}
|
|
12
|
-
async answer(offerId, offerSdp, options) {
|
|
13
|
-
throw new Error(`Cannot answer in ${this.name} state`);
|
|
14
|
-
}
|
|
15
|
-
async handleAnswer(sdp) {
|
|
16
|
-
throw new Error(`Cannot handle answer in ${this.name} state`);
|
|
17
|
-
}
|
|
18
|
-
async handleIceCandidate(candidate) {
|
|
19
|
-
// ICE candidates can arrive in multiple states, so default is to add them
|
|
20
|
-
if (this.peer.pc.remoteDescription) {
|
|
21
|
-
await this.peer.pc.addIceCandidate(new this.peer.RTCIceCandidate(candidate));
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* Setup trickle ICE candidate handler
|
|
26
|
-
* Sends local ICE candidates to server as they are discovered
|
|
27
|
-
*/
|
|
28
|
-
setupIceCandidateHandler() {
|
|
29
|
-
this.iceCandidateHandler = async (event) => {
|
|
30
|
-
if (event.candidate && this.peer.offerId) {
|
|
31
|
-
const candidateData = event.candidate.toJSON();
|
|
32
|
-
if (candidateData.candidate && candidateData.candidate !== '') {
|
|
33
|
-
const type = candidateData.candidate.includes('typ host') ? 'host' :
|
|
34
|
-
candidateData.candidate.includes('typ srflx') ? 'srflx' :
|
|
35
|
-
candidateData.candidate.includes('typ relay') ? 'relay' : 'unknown';
|
|
36
|
-
console.log(`🧊 Generated ${type} ICE candidate:`, candidateData.candidate);
|
|
37
|
-
try {
|
|
38
|
-
await this.peer.offersApi.addIceCandidates(this.peer.offerId, [candidateData]);
|
|
39
|
-
console.log(`✅ Sent ${type} ICE candidate to server`);
|
|
40
|
-
}
|
|
41
|
-
catch (err) {
|
|
42
|
-
console.error(`❌ Error sending ${type} ICE candidate:`, err);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
else if (!event.candidate) {
|
|
47
|
-
console.log('🧊 ICE gathering complete (null candidate)');
|
|
48
|
-
}
|
|
49
|
-
};
|
|
50
|
-
this.peer.pc.addEventListener('icecandidate', this.iceCandidateHandler);
|
|
51
|
-
}
|
|
52
|
-
cleanup() {
|
|
53
|
-
// Clean up ICE candidate handler if it exists
|
|
54
|
-
if (this.iceCandidateHandler) {
|
|
55
|
-
this.peer.pc.removeEventListener('icecandidate', this.iceCandidateHandler);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
async close() {
|
|
59
|
-
this.cleanup();
|
|
60
|
-
const { ClosedState } = await import('./closed-state.js');
|
|
61
|
-
this.peer.setState(new ClosedState(this.peer));
|
|
62
|
-
}
|
|
63
|
-
}
|
package/dist/peer/types.d.ts
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Timeout configurations for different connection phases
|
|
3
|
-
*/
|
|
4
|
-
export interface PeerTimeouts {
|
|
5
|
-
/** Timeout for ICE gathering (default: 10000ms) */
|
|
6
|
-
iceGathering?: number;
|
|
7
|
-
/** Timeout for waiting for answer (default: 30000ms) */
|
|
8
|
-
waitingForAnswer?: number;
|
|
9
|
-
/** Timeout for creating answer (default: 10000ms) */
|
|
10
|
-
creatingAnswer?: number;
|
|
11
|
-
/** Timeout for ICE connection (default: 30000ms) */
|
|
12
|
-
iceConnection?: number;
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* Options for creating a peer connection
|
|
16
|
-
*/
|
|
17
|
-
export interface PeerOptions {
|
|
18
|
-
/** RTCConfiguration for the peer connection */
|
|
19
|
-
rtcConfig?: RTCConfiguration;
|
|
20
|
-
/** Topics to advertise this connection under */
|
|
21
|
-
topics: string[];
|
|
22
|
-
/** How long the offer should live (milliseconds) */
|
|
23
|
-
ttl?: number;
|
|
24
|
-
/** Optional secret to protect the offer (max 128 characters) */
|
|
25
|
-
secret?: string;
|
|
26
|
-
/** Whether to create a data channel automatically (for offerer) */
|
|
27
|
-
createDataChannel?: boolean;
|
|
28
|
-
/** Label for the automatically created data channel */
|
|
29
|
-
dataChannelLabel?: string;
|
|
30
|
-
/** Timeout configurations */
|
|
31
|
-
timeouts?: PeerTimeouts;
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Events emitted by RondevuPeer
|
|
35
|
-
*/
|
|
36
|
-
export interface PeerEvents extends Record<string, (...args: any[]) => void> {
|
|
37
|
-
'state': (state: string) => void;
|
|
38
|
-
'connected': () => void;
|
|
39
|
-
'disconnected': () => void;
|
|
40
|
-
'failed': (error: Error) => void;
|
|
41
|
-
'datachannel': (channel: RTCDataChannel) => void;
|
|
42
|
-
'track': (event: RTCTrackEvent) => void;
|
|
43
|
-
}
|
package/dist/peer/types.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { PeerState } from './state.js';
|
|
2
|
-
import type { PeerOptions } from './types.js';
|
|
3
|
-
import type RondevuPeer from './index.js';
|
|
4
|
-
/**
|
|
5
|
-
* Waiting for answer from another peer
|
|
6
|
-
*/
|
|
7
|
-
export declare class WaitingForAnswerState extends PeerState {
|
|
8
|
-
private offerId;
|
|
9
|
-
private options;
|
|
10
|
-
private pollingInterval?;
|
|
11
|
-
private timeout?;
|
|
12
|
-
constructor(peer: RondevuPeer, offerId: string, options: PeerOptions);
|
|
13
|
-
get name(): string;
|
|
14
|
-
private startPolling;
|
|
15
|
-
handleAnswer(sdp: string): Promise<void>;
|
|
16
|
-
cleanup(): void;
|
|
17
|
-
}
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { PeerState } from './state.js';
|
|
2
|
-
/**
|
|
3
|
-
* Waiting for answer from another peer
|
|
4
|
-
*/
|
|
5
|
-
export class WaitingForAnswerState extends PeerState {
|
|
6
|
-
constructor(peer, offerId, options) {
|
|
7
|
-
super(peer);
|
|
8
|
-
this.offerId = offerId;
|
|
9
|
-
this.options = options;
|
|
10
|
-
this.startPolling();
|
|
11
|
-
}
|
|
12
|
-
get name() { return 'waiting-for-answer'; }
|
|
13
|
-
startPolling() {
|
|
14
|
-
const answerTimeout = this.options.timeouts?.waitingForAnswer || 30000;
|
|
15
|
-
this.timeout = setTimeout(async () => {
|
|
16
|
-
this.cleanup();
|
|
17
|
-
const { FailedState } = await import('./failed-state.js');
|
|
18
|
-
this.peer.setState(new FailedState(this.peer, new Error('Timeout waiting for answer')));
|
|
19
|
-
}, answerTimeout);
|
|
20
|
-
this.pollingInterval = setInterval(async () => {
|
|
21
|
-
try {
|
|
22
|
-
const answers = await this.peer.offersApi.getAnswers();
|
|
23
|
-
const myAnswer = answers.find((a) => a.offerId === this.offerId);
|
|
24
|
-
if (myAnswer) {
|
|
25
|
-
this.cleanup();
|
|
26
|
-
await this.handleAnswer(myAnswer.sdp);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
catch (err) {
|
|
30
|
-
console.error('Error polling for answers:', err);
|
|
31
|
-
if (err instanceof Error && err.message.includes('not found')) {
|
|
32
|
-
this.cleanup();
|
|
33
|
-
const { FailedState } = await import('./failed-state.js');
|
|
34
|
-
this.peer.setState(new FailedState(this.peer, new Error('Offer expired or not found')));
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}, 2000);
|
|
38
|
-
}
|
|
39
|
-
async handleAnswer(sdp) {
|
|
40
|
-
try {
|
|
41
|
-
await this.peer.pc.setRemoteDescription({
|
|
42
|
-
type: 'answer',
|
|
43
|
-
sdp
|
|
44
|
-
});
|
|
45
|
-
// Transition to exchanging ICE
|
|
46
|
-
const { ExchangingIceState } = await import('./exchanging-ice-state.js');
|
|
47
|
-
this.peer.setState(new ExchangingIceState(this.peer, this.offerId, this.options));
|
|
48
|
-
}
|
|
49
|
-
catch (error) {
|
|
50
|
-
const { FailedState } = await import('./failed-state.js');
|
|
51
|
-
this.peer.setState(new FailedState(this.peer, error));
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
cleanup() {
|
|
55
|
-
if (this.pollingInterval)
|
|
56
|
-
clearInterval(this.pollingInterval);
|
|
57
|
-
if (this.timeout)
|
|
58
|
-
clearTimeout(this.timeout);
|
|
59
|
-
}
|
|
60
|
-
}
|