Skip to content

Commit 176cad2

Browse files
committed
feat: accept preconfigured PeerConnection as polyfill arg
There are cases where we need to use methods on `PeerConnection` that are not available on `RTCPeerConnection`, but then we wish to pass the `RTCPeerConnection` on to other code for it to use in a polmorphic node/browser way. Add an option to the polyfilled `RTCPeerConnection` to pass a preconfigured `PeerConnection` instance in, instead of always creating one.
1 parent a862c23 commit 176cad2

File tree

3 files changed

+50
-19
lines changed

3 files changed

+50
-19
lines changed

polyfill/RTCPeerConnection.d.ts

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
/// <reference lib="dom" />
22

3+
import { PeerConnection } from '../lib/index.js';
4+
5+
export interface _RTCConfiguration extends RTCConfiguration {
6+
peerConnection?: PeerConnection;
7+
}
8+
39
export default class _RTCPeerConnection extends EventTarget implements RTCPeerConnection {
4-
constructor(config?: RTCConfiguration);
10+
constructor(config?: _RTCConfiguration);
511

612
// events
713
onconnectionstatechange: ((this: RTCPeerConnection, ev: Event) => any) | null;

polyfill/RTCPeerConnection.js

+19-17
Original file line numberDiff line numberDiff line change
@@ -41,23 +41,25 @@ export default class _RTCPeerConnection extends EventTarget {
4141
this.#dataChannels = new Set();
4242
this.#canTrickleIceCandidates = null;
4343

44-
this.#peerConnection = new NodeDataChannel.PeerConnection(init?.peerIdentity ?? `peer-${getRandomString(7)}`, {
45-
...init,
46-
iceServers:
47-
init?.iceServers
48-
?.map((server) => {
49-
const urls = Array.isArray(server.urls) ? server.urls : [server.urls];
50-
51-
return urls.map((url) => {
52-
if (server.username && server.credential) {
53-
const [protocol, rest] = url.split(/:(.*)/);
54-
return `${protocol}:${server.username}:${server.credential}@${rest}`;
55-
}
56-
return url;
57-
});
58-
})
59-
.flat() ?? [],
60-
});
44+
this.#peerConnection =
45+
init.peerConnection ??
46+
new NodeDataChannel.PeerConnection(init?.peerIdentity ?? `peer-${getRandomString(7)}`, {
47+
...init,
48+
iceServers:
49+
init?.iceServers
50+
?.map((server) => {
51+
const urls = Array.isArray(server.urls) ? server.urls : [server.urls];
52+
53+
return urls.map((url) => {
54+
if (server.username && server.credential) {
55+
const [protocol, rest] = url.split(/:(.*)/);
56+
return `${protocol}:${server.username}:${server.credential}@${rest}`;
57+
}
58+
return url;
59+
});
60+
})
61+
.flat() ?? [],
62+
});
6163

6264
// forward peerConnection events
6365
this.#peerConnection.onStateChange(() => {

test/jest-tests/polyfill.test.js

+24-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,33 @@
1-
import { expect } from '@jest/globals';
1+
import { expect, jest } from '@jest/globals';
22
import polyfill from '../../polyfill/index.js';
3+
import { PeerConnection } from '../../lib';
34

45
describe('polyfill', () => {
56
test('generateCertificate should throw', () => {
67
expect(async () => {
78
await polyfill.RTCPeerConnection.generateCertificate({});
89
}).rejects.toEqual(new DOMException('Not implemented'));
910
});
11+
12+
test('it should accept a preconfigured PeerConnection', () => {
13+
const peerConnection = new PeerConnection('Peer', {
14+
iceServers: [],
15+
});
16+
17+
// have to override write-only method in order to spy on it
18+
const originalFunc = peerConnection.state.bind(peerConnection);
19+
Object.defineProperty(peerConnection, 'state', {
20+
value: originalFunc,
21+
writable: true,
22+
enumerable: true,
23+
});
24+
25+
const spy = jest.spyOn(peerConnection, 'state');
26+
const rtcPeerConnection = new polyfill.RTCPeerConnection({
27+
peerConnection,
28+
});
29+
const connectionState = rtcPeerConnection.connectionState;
30+
expect(spy).toHaveBeenCalled();
31+
expect(connectionState).toEqual(originalFunc());
32+
});
1033
});

0 commit comments

Comments
 (0)