Skip to content

Commit 91a423e

Browse files
authored
Merge pull request #347 from achingbrain/fix/memoize-datachannel-fields
fix: memoize RTCDataChannel fields
2 parents 25249e8 + 1e84d6b commit 91a423e

File tree

3 files changed

+70
-3
lines changed

3 files changed

+70
-3
lines changed

src/polyfill/RTCDataChannel.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ export default class RTCDataChannel extends EventTarget implements globalThis.RT
1111
#maxRetransmits: number | null;
1212
#negotiated: boolean;
1313
#ordered: boolean;
14+
#id: number
15+
#label: string
16+
#protocol: string
1417

1518
#closeRequested = false;
1619

@@ -33,6 +36,9 @@ export default class RTCDataChannel extends EventTarget implements globalThis.RT
3336
this.#maxRetransmits = opts.maxRetransmits || null;
3437
this.#negotiated = opts.negotiated || false;
3538
this.#ordered = opts.ordered || true;
39+
this.#id = this.#dataChannel.getId();
40+
this.#label = this.#dataChannel.getLabel();
41+
this.#protocol = this.#dataChannel.getProtocol();
3642

3743
// forward dataChannel events
3844
this.#dataChannel.onOpen(() => {
@@ -131,11 +137,11 @@ export default class RTCDataChannel extends EventTarget implements globalThis.RT
131137
}
132138

133139
get id(): number | null {
134-
return this.#dataChannel.getId();
140+
return this.#id;
135141
}
136142

137143
get label(): string {
138-
return this.#dataChannel.getLabel();
144+
return this.#label;
139145
}
140146

141147
get maxPacketLifeTime(): number | null {
@@ -155,7 +161,7 @@ export default class RTCDataChannel extends EventTarget implements globalThis.RT
155161
}
156162

157163
get protocol(): string {
158-
return this.#dataChannel.getProtocol();
164+
return this.#protocol
159165
}
160166

161167
get readyState(): globalThis.RTCDataChannelState {

test/fixtures/event-promise.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
export interface EventPromiseOptions {
2+
errorEvent?: string
3+
}
4+
5+
export async function eventPromise <T = unknown> (emitter: EventTarget, event: string, opts?: EventPromiseOptions): Promise<T> {
6+
return new Promise<T>((resolve, reject) => {
7+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
8+
emitter.addEventListener(event, (evt: any) => {
9+
resolve(evt);
10+
});
11+
emitter.addEventListener(opts?.errorEvent ?? 'error', (err) => {
12+
reject(err);
13+
});
14+
});
15+
}

test/jest-tests/polyfill.test.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import { expect, jest } from '@jest/globals';
33
import { RTCPeerConnection } from '../../src/polyfill/index';
44
import { PeerConnection } from '../../src/lib/index';
5+
import { eventPromise } from '../fixtures/event-promise';
56

67
describe('polyfill', () => {
78
// Default is 5000 ms but we need more
@@ -226,6 +227,51 @@ describe('polyfill', () => {
226227
});
227228
});
228229

230+
test('it can access datachannel informational fields after closing', async () => {
231+
const peer1 = new RTCPeerConnection();
232+
const peer2 = new RTCPeerConnection();
233+
234+
const label = 'label'
235+
const protocol = 'protocol'
236+
237+
const dc: RTCDataChannel = peer1.createDataChannel(label, {
238+
protocol
239+
});
240+
241+
// Actions
242+
const peer1Offer = await peer1.createOffer();
243+
await peer2.setRemoteDescription(peer1Offer);
244+
245+
const peer2Answer = await peer2.createAnswer();
246+
await peer1.setRemoteDescription(peer2Answer);
247+
248+
peer1.addEventListener('icecandidate', (e: RTCPeerConnectionIceEvent) => {
249+
peer2.addIceCandidate(e.candidate);
250+
});
251+
252+
peer2.addEventListener('icecandidate', (e: RTCPeerConnectionIceEvent) => {
253+
peer1.addIceCandidate(e.candidate);
254+
});
255+
256+
await eventPromise(dc, 'open');
257+
258+
const id = dc.id;
259+
expect(dc.label).toEqual(label);
260+
expect(dc.protocol).toEqual(protocol);
261+
262+
peer1.close();
263+
peer2.close();
264+
265+
if (dc.readyState !== 'closed') {
266+
await eventPromise(dc, 'close');
267+
}
268+
269+
expect(dc.readyState).toEqual('closed');
270+
expect(dc.id).toEqual(id);
271+
expect(dc.label).toEqual(label);
272+
expect(dc.protocol).toEqual(protocol);
273+
});
274+
229275
test('it should accept a preconfigured PeerConnection', () => {
230276
const peerConnection = new PeerConnection('Peer', {
231277
iceServers: [],

0 commit comments

Comments
 (0)