@marianmeres/webrtc 1.2.6 → 1.3.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/AGENTS.md +10 -0
- package/README.md +29 -0
- package/dist/types.d.ts +10 -0
- package/dist/webrtc-manager.d.ts +8 -1
- package/dist/webrtc-manager.js +46 -0
- package/package.json +1 -1
package/AGENTS.md
CHANGED
|
@@ -159,6 +159,15 @@ interface WebRtcManagerConfig {
|
|
|
159
159
|
}
|
|
160
160
|
```
|
|
161
161
|
|
|
162
|
+
### GatherIceCandidatesOptions Interface
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
interface GatherIceCandidatesOptions {
|
|
166
|
+
timeout?: number; // Timeout in ms (default: 10000)
|
|
167
|
+
onCandidate?: (candidate: RTCIceCandidate | null) => void; // Called for each candidate
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
162
171
|
### Properties (Getters)
|
|
163
172
|
|
|
164
173
|
| Property | Type | Description |
|
|
@@ -205,6 +214,7 @@ interface WebRtcManagerConfig {
|
|
|
205
214
|
| setRemoteDescription | `(description: RTCSessionDescriptionInit): Promise<boolean>` | Set remote SDP |
|
|
206
215
|
| addIceCandidate | `(candidate: RTCIceCandidateInit \| null): Promise<boolean>` | Add ICE candidate |
|
|
207
216
|
| iceRestart | `(): Promise<boolean>` | Perform ICE restart |
|
|
217
|
+
| gatherIceCandidates | `(options?: GatherIceCandidatesOptions): Promise<void>` | Wait for ICE gathering to complete |
|
|
208
218
|
| getLocalDescription | `(): RTCSessionDescription \| null` | Get local SDP |
|
|
209
219
|
| getRemoteDescription | `(): RTCSessionDescription \| null` | Get remote SDP |
|
|
210
220
|
| getStats | `(): Promise<RTCStatsReport \| null>` | Get connection statistics |
|
package/README.md
CHANGED
|
@@ -95,6 +95,35 @@ await manager.setLocalDescription(offer)
|
|
|
95
95
|
await manager.setRemoteDescription(answer)
|
|
96
96
|
await manager.addIceCandidate(candidate)
|
|
97
97
|
await manager.iceRestart() // Trigger ICE restart
|
|
98
|
+
await manager.gatherIceCandidates(options) // Wait for ICE gathering to complete
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### gatherIceCandidates(options?)
|
|
102
|
+
|
|
103
|
+
Wait for ICE gathering to complete. Useful for HTTP POST signaling patterns where you need all ICE candidates bundled in the local description before sending to the server.
|
|
104
|
+
|
|
105
|
+
**Options:** `timeout` (ms, default 10000), `onCandidate` (callback for each candidate)
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
const offer = await manager.createOffer();
|
|
109
|
+
await manager.setLocalDescription(offer);
|
|
110
|
+
await manager.gatherIceCandidates({ timeout: 5000 });
|
|
111
|
+
// Now manager.peerConnection.localDescription has all ICE candidates bundled
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
**Error Handling:** A timeout rejection does *not* transition the FSM to ERROR state. This is intentional - `gatherIceCandidates()` is a utility method, and a timeout means "gathering didn't complete in time", not "the connection failed". The consumer decides how to handle it:
|
|
115
|
+
|
|
116
|
+
```typescript
|
|
117
|
+
try {
|
|
118
|
+
await manager.gatherIceCandidates({ timeout: 5000 });
|
|
119
|
+
} catch (e) {
|
|
120
|
+
if (e.message === "ICE gathering timeout") {
|
|
121
|
+
// Options:
|
|
122
|
+
// 1. Retry with longer timeout
|
|
123
|
+
// 2. Proceed anyway - localDescription may have partial candidates
|
|
124
|
+
// 3. Treat as fatal: manager.reset()
|
|
125
|
+
}
|
|
126
|
+
}
|
|
98
127
|
```
|
|
99
128
|
|
|
100
129
|
### Data Channel Methods
|
package/dist/types.d.ts
CHANGED
|
@@ -156,3 +156,13 @@ export interface WebRtcEvents {
|
|
|
156
156
|
/** Emitted when an error occurs. Payload: the Error object. */
|
|
157
157
|
error: Error;
|
|
158
158
|
}
|
|
159
|
+
/**
|
|
160
|
+
* Options for waiting for ICE gathering to complete.
|
|
161
|
+
* Used with gatherIceCandidates() for HTTP POST signaling patterns.
|
|
162
|
+
*/
|
|
163
|
+
export interface GatherIceCandidatesOptions {
|
|
164
|
+
/** Timeout in milliseconds (default: 10000) */
|
|
165
|
+
timeout?: number;
|
|
166
|
+
/** Called for each ICE candidate as it's gathered */
|
|
167
|
+
onCandidate?: (candidate: RTCIceCandidate | null) => void;
|
|
168
|
+
}
|
package/dist/webrtc-manager.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type WebRtcFactory, type WebRtcManagerConfig, WebRtcState, type WebRtcEvents } from "./types.js";
|
|
1
|
+
import { type WebRtcFactory, type WebRtcManagerConfig, WebRtcState, type WebRtcEvents, type GatherIceCandidatesOptions } from "./types.js";
|
|
2
2
|
/**
|
|
3
3
|
* WebRTC connection manager with FSM-based lifecycle and event-driven architecture.
|
|
4
4
|
*
|
|
@@ -203,6 +203,13 @@ export declare class WebRtcManager<TContext = unknown> {
|
|
|
203
203
|
* @returns True if successful, false otherwise.
|
|
204
204
|
*/
|
|
205
205
|
iceRestart(): Promise<boolean>;
|
|
206
|
+
/**
|
|
207
|
+
* Wait for ICE gathering to complete.
|
|
208
|
+
* Use this for HTTP POST signaling patterns where you need all ICE candidates
|
|
209
|
+
* bundled in the local description before sending to the server.
|
|
210
|
+
* @param options - Optional configuration for timeout and candidate callback.
|
|
211
|
+
*/
|
|
212
|
+
gatherIceCandidates(options?: GatherIceCandidatesOptions): Promise<void>;
|
|
206
213
|
/**
|
|
207
214
|
* Returns the current local session description.
|
|
208
215
|
* @returns The local description, or null if not set.
|
package/dist/webrtc-manager.js
CHANGED
|
@@ -675,6 +675,52 @@ export class WebRtcManager {
|
|
|
675
675
|
return false;
|
|
676
676
|
}
|
|
677
677
|
}
|
|
678
|
+
/**
|
|
679
|
+
* Wait for ICE gathering to complete.
|
|
680
|
+
* Use this for HTTP POST signaling patterns where you need all ICE candidates
|
|
681
|
+
* bundled in the local description before sending to the server.
|
|
682
|
+
* @param options - Optional configuration for timeout and candidate callback.
|
|
683
|
+
*/
|
|
684
|
+
gatherIceCandidates(options = {}) {
|
|
685
|
+
const { timeout = 10000, onCandidate } = options;
|
|
686
|
+
if (!this.#pc) {
|
|
687
|
+
return Promise.reject(new Error("Peer connection not initialized"));
|
|
688
|
+
}
|
|
689
|
+
const pc = this.#pc;
|
|
690
|
+
if (pc.iceGatheringState === "complete") {
|
|
691
|
+
this.#logDebug("ICE gathering already complete");
|
|
692
|
+
return Promise.resolve();
|
|
693
|
+
}
|
|
694
|
+
this.#logDebug("Waiting for ICE gathering to complete...");
|
|
695
|
+
return new Promise((resolve, reject) => {
|
|
696
|
+
const timer = setTimeout(() => {
|
|
697
|
+
cleanup();
|
|
698
|
+
reject(new Error("ICE gathering timeout"));
|
|
699
|
+
}, timeout);
|
|
700
|
+
const cleanup = () => {
|
|
701
|
+
clearTimeout(timer);
|
|
702
|
+
pc.removeEventListener("icegatheringstatechange", checkState);
|
|
703
|
+
pc.removeEventListener("icecandidate", handleCandidate);
|
|
704
|
+
};
|
|
705
|
+
const checkState = () => {
|
|
706
|
+
if (pc.iceGatheringState === "complete") {
|
|
707
|
+
this.#logDebug("ICE gathering complete (via state change)");
|
|
708
|
+
cleanup();
|
|
709
|
+
resolve();
|
|
710
|
+
}
|
|
711
|
+
};
|
|
712
|
+
const handleCandidate = (event) => {
|
|
713
|
+
onCandidate?.(event.candidate);
|
|
714
|
+
if (event.candidate === null) {
|
|
715
|
+
this.#logDebug("ICE gathering complete (null candidate)");
|
|
716
|
+
cleanup();
|
|
717
|
+
resolve();
|
|
718
|
+
}
|
|
719
|
+
};
|
|
720
|
+
pc.addEventListener("icegatheringstatechange", checkState);
|
|
721
|
+
pc.addEventListener("icecandidate", handleCandidate);
|
|
722
|
+
});
|
|
723
|
+
}
|
|
678
724
|
/**
|
|
679
725
|
* Returns the current local session description.
|
|
680
726
|
* @returns The local description, or null if not set.
|