node-datachannel 0.11.0 → 0.20.0-alpha.1

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.
Files changed (131) hide show
  1. package/.eslintignore +5 -1
  2. package/.eslintrc.json +27 -0
  3. package/.prettierrc +12 -0
  4. package/CMakeLists.txt +13 -13
  5. package/jest.config.ts +14 -0
  6. package/package.json +47 -44
  7. package/rollup.config.mjs +63 -0
  8. package/src/index.ts +10 -0
  9. package/{lib/datachannel-stream.js → src/lib/datachannel-stream.ts} +16 -11
  10. package/src/lib/index.ts +180 -0
  11. package/src/lib/node-datachannel.ts +13 -0
  12. package/src/lib/types.ts +126 -0
  13. package/{lib/websocket-server.js → src/lib/websocket-server.ts} +10 -8
  14. package/src/lib/websocket.ts +26 -0
  15. package/src/polyfill/Events.ts +33 -0
  16. package/src/polyfill/Exception.ts +37 -0
  17. package/src/polyfill/RTCCertificate.ts +17 -0
  18. package/{polyfill/RTCDataChannel.js → src/polyfill/RTCDataChannel.ts} +43 -40
  19. package/src/polyfill/RTCDtlsTransport.ts +47 -0
  20. package/src/polyfill/RTCError.ts +71 -0
  21. package/src/polyfill/RTCIceCandidate.ts +125 -0
  22. package/{polyfill/RTCIceTransport.js → src/polyfill/RTCIceTransport.ts} +22 -20
  23. package/{polyfill/RTCPeerConnection.js → src/polyfill/RTCPeerConnection.ts} +137 -115
  24. package/{polyfill/RTCSctpTransport.js → src/polyfill/RTCSctpTransport.ts} +16 -14
  25. package/{polyfill/RTCSessionDescription.js → src/polyfill/RTCSessionDescription.ts} +7 -12
  26. package/{polyfill/index.js → src/polyfill/index.ts} +12 -9
  27. package/tsconfig.json +20 -13
  28. package/.eslintrc.cjs +0 -8
  29. package/.github/FUNDING.yml +0 -2
  30. package/.github/workflows/build-linux.yml +0 -104
  31. package/.github/workflows/build-mac-m1.yml +0 -38
  32. package/.github/workflows/build-mac-x64.yml +0 -40
  33. package/.github/workflows/build-win.yml +0 -74
  34. package/.github/workflows/lint.yml +0 -20
  35. package/.github/workflows/npm-publish-manual.yml +0 -23
  36. package/.prettierrc.cjs +0 -8
  37. package/build-containers/Dockerfile.alpine +0 -6
  38. package/build-containers/Dockerfile.debian +0 -7
  39. package/cmake/toolchain/ci.cmake +0 -23
  40. package/examples/client-server/README.md +0 -22
  41. package/examples/client-server/client-benchmark.js +0 -230
  42. package/examples/client-server/client-periodic.js +0 -189
  43. package/examples/client-server/client.js +0 -111
  44. package/examples/client-server/package-lock.json +0 -289
  45. package/examples/client-server/package.json +0 -16
  46. package/examples/client-server/signaling-server.js +0 -39
  47. package/examples/electron-demo/README.md +0 -58
  48. package/examples/electron-demo/forge.config.js +0 -49
  49. package/examples/electron-demo/package-lock.json +0 -15933
  50. package/examples/electron-demo/package.json +0 -43
  51. package/examples/electron-demo/src/index.css +0 -7
  52. package/examples/electron-demo/src/index.html +0 -29
  53. package/examples/electron-demo/src/main.js +0 -53
  54. package/examples/electron-demo/src/node-datachannel.js +0 -123
  55. package/examples/electron-demo/src/preload.js +0 -28
  56. package/examples/electron-demo/src/renderer.js +0 -58
  57. package/examples/electron-demo/webpack.main.config.js +0 -11
  58. package/examples/electron-demo/webpack.renderer.config.js +0 -13
  59. package/examples/electron-demo/webpack.rules.js +0 -35
  60. package/examples/media/README.md +0 -34
  61. package/examples/media/main.html +0 -45
  62. package/examples/media/media.js +0 -54
  63. package/examples/simple-peer-usage/main.js +0 -28
  64. package/examples/simple-peer-usage/package-lock.json +0 -317
  65. package/examples/simple-peer-usage/package.json +0 -16
  66. package/examples/websocket/websocket-client.js +0 -20
  67. package/examples/websocket/websocket-server.js +0 -22
  68. package/jest.config.cjs +0 -7
  69. package/lib/index.cjs +0 -194
  70. package/lib/index.d.cts +0 -300
  71. package/lib/index.d.ts +0 -300
  72. package/lib/index.js +0 -58
  73. package/lib/node-datachannel.js +0 -7
  74. package/polyfill/Events.d.ts +0 -9
  75. package/polyfill/Events.js +0 -29
  76. package/polyfill/Exception.js +0 -23
  77. package/polyfill/RTCCertificate.d.ts +0 -7
  78. package/polyfill/RTCCertificate.js +0 -17
  79. package/polyfill/RTCDataChannel.d.ts +0 -35
  80. package/polyfill/RTCDtlsTransport.d.ts +0 -10
  81. package/polyfill/RTCDtlsTransport.js +0 -47
  82. package/polyfill/RTCIceCandidate.d.ts +0 -20
  83. package/polyfill/RTCIceCandidate.js +0 -126
  84. package/polyfill/RTCIceTransport.d.ts +0 -18
  85. package/polyfill/RTCPeerConnection.d.ts +0 -62
  86. package/polyfill/RTCSctpTransport.d.ts +0 -10
  87. package/polyfill/RTCSessionDescription.d.ts +0 -8
  88. package/polyfill/index.cjs +0 -1258
  89. package/polyfill/index.d.cts +0 -37
  90. package/polyfill/index.d.ts +0 -37
  91. package/test/connectivity.js +0 -86
  92. package/test/jest-tests/basic.test.js +0 -37
  93. package/test/jest-tests/multiple-run.test.js +0 -73
  94. package/test/jest-tests/p2p.test.js +0 -99
  95. package/test/jest-tests/polyfill.test.js +0 -10
  96. package/test/jest-tests/streams.test.js +0 -48
  97. package/test/jest-tests/websocket.test.js +0 -69
  98. package/test/polyfill-connectivity.js +0 -89
  99. package/test/websockets.js +0 -50
  100. package/test/wpt-tests/README.md +0 -46
  101. package/test/wpt-tests/chrome-failed-tests.js +0 -42
  102. package/test/wpt-tests/index.js +0 -96
  103. package/test/wpt-tests/last-test-results.md +0 -205
  104. package/test/wpt-tests/package-lock.json +0 -1712
  105. package/test/wpt-tests/package.json +0 -19
  106. package/test/wpt-tests/wpt-test-list.js +0 -137
  107. package/test/wpt-tests/wpt.js +0 -131
  108. /package/src/{data-channel-wrapper.cpp → cpp/data-channel-wrapper.cpp} +0 -0
  109. /package/src/{data-channel-wrapper.h → cpp/data-channel-wrapper.h} +0 -0
  110. /package/src/{main.cpp → cpp/main.cpp} +0 -0
  111. /package/src/{media-audio-wrapper.cpp → cpp/media-audio-wrapper.cpp} +0 -0
  112. /package/src/{media-audio-wrapper.h → cpp/media-audio-wrapper.h} +0 -0
  113. /package/src/{media-direction.cpp → cpp/media-direction.cpp} +0 -0
  114. /package/src/{media-direction.h → cpp/media-direction.h} +0 -0
  115. /package/src/{media-rtcpreceivingsession-wrapper.cpp → cpp/media-rtcpreceivingsession-wrapper.cpp} +0 -0
  116. /package/src/{media-rtcpreceivingsession-wrapper.h → cpp/media-rtcpreceivingsession-wrapper.h} +0 -0
  117. /package/src/{media-track-wrapper.cpp → cpp/media-track-wrapper.cpp} +0 -0
  118. /package/src/{media-track-wrapper.h → cpp/media-track-wrapper.h} +0 -0
  119. /package/src/{media-video-wrapper.cpp → cpp/media-video-wrapper.cpp} +0 -0
  120. /package/src/{media-video-wrapper.h → cpp/media-video-wrapper.h} +0 -0
  121. /package/src/{peer-connection-wrapper.cpp → cpp/peer-connection-wrapper.cpp} +0 -0
  122. /package/src/{peer-connection-wrapper.h → cpp/peer-connection-wrapper.h} +0 -0
  123. /package/src/{rtc-wrapper.cpp → cpp/rtc-wrapper.cpp} +0 -0
  124. /package/src/{rtc-wrapper.h → cpp/rtc-wrapper.h} +0 -0
  125. /package/src/{thread-safe-callback.cpp → cpp/thread-safe-callback.cpp} +0 -0
  126. /package/src/{thread-safe-callback.h → cpp/thread-safe-callback.h} +0 -0
  127. /package/src/{web-socket-server-wrapper.cpp → cpp/web-socket-server-wrapper.cpp} +0 -0
  128. /package/src/{web-socket-server-wrapper.h → cpp/web-socket-server-wrapper.h} +0 -0
  129. /package/src/{web-socket-wrapper.cpp → cpp/web-socket-wrapper.cpp} +0 -0
  130. /package/src/{web-socket-wrapper.h → cpp/web-socket-wrapper.h} +0 -0
  131. /package/{polyfill → src/polyfill}/README.md +0 -0
@@ -1,40 +1,49 @@
1
- import NodeDataChannel from '../lib/index.js';
2
- import RTCSessionDescription from './RTCSessionDescription.js';
3
- import RTCDataChannel from './RTCDataChannel.js';
4
- import RTCIceCandidate from './RTCIceCandidate.js';
5
- import { RTCDataChannelEvent, RTCPeerConnectionIceEvent } from './Events.js';
6
- import RTCSctpTransport from './RTCSctpTransport.js';
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
7
2
  import 'node-domexception';
8
- import * as exceptions from './Exception.js';
3
+ import { SelectedCandidateInfo } from '../lib/types';
4
+ import { PeerConnection } from '../lib/index';
5
+ import RTCSessionDescription from './RTCSessionDescription';
6
+ import RTCDataChannel from './RTCDataChannel';
7
+ import RTCIceCandidate from './RTCIceCandidate';
8
+ import { RTCDataChannelEvent, RTCPeerConnectionIceEvent } from './Events';
9
+ import RTCSctpTransport from './RTCSctpTransport';
10
+ import * as exceptions from './Exception';
11
+ import RTCCertificate from './RTCCertificate';
12
+
13
+ // extend RTCConfiguration with peerIdentity
14
+ interface RTCConfiguration extends globalThis.RTCConfiguration {
15
+ peerIdentity?: string;
16
+ }
9
17
 
10
- export default class _RTCPeerConnection extends EventTarget {
11
- static async generateCertificate() {
18
+ export default class RTCPeerConnection extends EventTarget implements globalThis.RTCPeerConnection {
19
+ static async generateCertificate(): Promise<RTCCertificate> {
12
20
  throw new DOMException('Not implemented');
13
21
  }
14
22
 
15
- #peerConnection;
16
- #localOffer;
17
- #localAnswer;
18
- #dataChannels;
23
+ #peerConnection: PeerConnection;
24
+ #localOffer: any;
25
+ #localAnswer: any;
26
+ #dataChannels: Set<RTCDataChannel>;
19
27
  #dataChannelsClosed = 0;
20
- #config;
21
- #canTrickleIceCandidates;
22
- #sctp;
23
-
24
- #localCandidates = [];
25
- #remoteCandidates = [];
26
-
27
- onconnectionstatechange;
28
- ondatachannel;
29
- onicecandidate;
30
- onicecandidateerror;
31
- oniceconnectionstatechange;
32
- onicegatheringstatechange;
33
- onnegotiationneeded;
34
- onsignalingstatechange;
35
- ontrack;
36
-
37
- _checkConfiguration(config) {
28
+ #config: RTCConfiguration;
29
+ #canTrickleIceCandidates: boolean | null;
30
+ #sctp: RTCSctpTransport;
31
+
32
+ #localCandidates: RTCIceCandidate[] = [];
33
+ #remoteCandidates: RTCIceCandidate[] = [];
34
+
35
+ // events
36
+ onconnectionstatechange: ((this: RTCPeerConnection, ev: Event) => any) | null;
37
+ ondatachannel: ((this: RTCPeerConnection, ev: RTCDataChannelEvent) => any) | null;
38
+ onicecandidate: ((this: RTCPeerConnection, ev: RTCPeerConnectionIceEvent) => any) | null;
39
+ onicecandidateerror: ((this: RTCPeerConnection, ev: Event) => any) | null;
40
+ oniceconnectionstatechange: ((this: RTCPeerConnection, ev: Event) => any) | null;
41
+ onicegatheringstatechange: ((this: RTCPeerConnection, ev: Event) => any) | null;
42
+ onnegotiationneeded: ((this: RTCPeerConnection, ev: Event) => any) | null;
43
+ onsignalingstatechange: ((this: RTCPeerConnection, ev: Event) => any) | null;
44
+ ontrack: ((this: RTCPeerConnection, ev: globalThis.RTCTrackEvent) => any) | null;
45
+
46
+ private _checkConfiguration(config: RTCConfiguration): void {
38
47
  if (config && config.iceServers === undefined) config.iceServers = [];
39
48
  if (config && config.iceTransportPolicy === undefined) config.iceTransportPolicy = 'all';
40
49
 
@@ -49,31 +58,39 @@ export default class _RTCPeerConnection extends EventTarget {
49
58
 
50
59
  // If iceServers is string convert to array
51
60
  if (typeof config.iceServers[i].urls === 'string')
52
- config.iceServers[i].urls = [config.iceServers[i].urls];
61
+ config.iceServers[i].urls = [config.iceServers[i].urls as string];
53
62
 
54
63
  // urls can not be empty
55
- if (config.iceServers[i].urls?.some((url) => url == ''))
56
- throw exceptions.SyntaxError('IceServers urls cannot be empty');
64
+ if ((config.iceServers[i].urls as string[])?.some((url) => url == ''))
65
+ throw new exceptions.SyntaxError('IceServers urls cannot be empty');
57
66
 
58
- // urls should match the regex "stun\:\w*|turn\:\w*|turns\:\w*"
67
+ // urls should be valid URLs and match the protocols "stun:|turn:|turns:"
59
68
  if (
60
- config.iceServers[i].urls?.some(
61
- (url) => !/^(stun:[\w,\.,:]*|turn:[\w,\.,:]*|turns:[\w,\.,:]*)$/.test(url),
69
+ (config.iceServers[i].urls as string[])?.some(
70
+ (url) => {
71
+ try {
72
+ const parsedURL = new URL(url)
73
+
74
+ return !/^(stun:|turn:|turns:)$/.test(parsedURL.protocol)
75
+ } catch (error) {
76
+ return true
77
+ }
78
+ },
62
79
  )
63
80
  )
64
- throw exceptions.SyntaxError('IceServers urls wrong format');
81
+ throw new exceptions.SyntaxError('IceServers urls wrong format');
65
82
 
66
83
  // If this is a turn server check for username and credential
67
- if (config.iceServers[i].urls?.some((url) => url.startsWith('turn'))) {
84
+ if ((config.iceServers[i].urls as string[])?.some((url) => url.startsWith('turn'))) {
68
85
  if (!config.iceServers[i].username)
69
- throw exceptions.InvalidAccessError('IceServers username cannot be null');
86
+ throw new exceptions.InvalidAccessError('IceServers username cannot be null');
70
87
  if (!config.iceServers[i].credential)
71
- throw exceptions.InvalidAccessError('IceServers username cannot be undefined');
88
+ throw new exceptions.InvalidAccessError('IceServers username cannot be undefined');
72
89
  }
73
90
 
74
91
  // length of urls can not be 0
75
92
  if (config.iceServers[i].urls?.length === 0)
76
- throw exceptions.SyntaxError('IceServers urls cannot be empty');
93
+ throw new exceptions.SyntaxError('IceServers urls cannot be empty');
77
94
  }
78
95
  }
79
96
 
@@ -86,12 +103,14 @@ export default class _RTCPeerConnection extends EventTarget {
86
103
  throw new TypeError('IceTransportPolicy must be either "all" or "relay"');
87
104
  }
88
105
 
89
- setConfiguration(config) {
106
+ setConfiguration(config: RTCConfiguration): void {
90
107
  this._checkConfiguration(config);
91
108
  this.#config = config;
92
109
  }
93
110
 
94
- constructor(config = { iceServers: [], iceTransportPolicy: 'all' }) {
111
+
112
+
113
+ constructor(config: RTCConfiguration = { iceServers: [], iceTransportPolicy: 'all' }) {
95
114
  super();
96
115
 
97
116
  this._checkConfiguration(config);
@@ -102,8 +121,8 @@ export default class _RTCPeerConnection extends EventTarget {
102
121
  this.#canTrickleIceCandidates = null;
103
122
 
104
123
  try {
105
- this.#peerConnection = new NodeDataChannel.PeerConnection(
106
- config?.peerIdentity ?? `peer-${getRandomString(7)}`,
124
+ const peerIdentity = (config as any)?.peerIdentity ?? `peer-${getRandomString(7)}`;
125
+ this.#peerConnection = new PeerConnection(peerIdentity,
107
126
  {
108
127
  ...config,
109
128
  iceServers:
@@ -123,8 +142,8 @@ export default class _RTCPeerConnection extends EventTarget {
123
142
  },
124
143
  );
125
144
  } catch (error) {
126
- if (!error || !error.message) throw exceptions.NotFoundError('Unknown error');
127
- throw exceptions.SyntaxError(error.message);
145
+ if (!error || !error.message) throw new exceptions.NotFoundError('Unknown error');
146
+ throw new exceptions.SyntaxError(error.message);
128
147
  }
129
148
 
130
149
  // forward peerConnection events
@@ -184,43 +203,43 @@ export default class _RTCPeerConnection extends EventTarget {
184
203
  if (this.onicegatheringstatechange) this.onicegatheringstatechange(e);
185
204
  });
186
205
  this.addEventListener('datachannel', (e) => {
187
- if (this.ondatachannel) this.ondatachannel(e);
206
+ if (this.ondatachannel) this.ondatachannel(e as RTCDataChannelEvent);
188
207
  });
189
208
  this.addEventListener('icecandidate', (e) => {
190
- if (this.onicecandidate) this.onicecandidate(e);
209
+ if (this.onicecandidate) this.onicecandidate(e as RTCPeerConnectionIceEvent);
191
210
  });
192
211
 
193
212
  this.#sctp = new RTCSctpTransport({
194
213
  pc: this,
195
214
  extraFunctions: {
196
- maxDataChannelId: () => {
215
+ maxDataChannelId: (): number => {
197
216
  return this.#peerConnection.maxDataChannelId();
198
217
  },
199
- maxMessageSize: () => {
218
+ maxMessageSize: (): number => {
200
219
  return this.#peerConnection.maxMessageSize();
201
220
  },
202
- localCandidates: () => {
221
+ localCandidates: (): RTCIceCandidate[] => {
203
222
  return this.#localCandidates;
204
223
  },
205
- remoteCandidates: () => {
224
+ remoteCandidates: (): RTCIceCandidate[] => {
206
225
  return this.#remoteCandidates;
207
226
  },
208
- selectedCandidatePair: () => {
227
+ selectedCandidatePair: (): { local: SelectedCandidateInfo; remote: SelectedCandidateInfo } | null => {
209
228
  return this.#peerConnection.getSelectedCandidatePair();
210
229
  },
211
230
  },
212
231
  });
213
232
  }
214
233
 
215
- get canTrickleIceCandidates() {
234
+ get canTrickleIceCandidates(): boolean | null {
216
235
  return this.#canTrickleIceCandidates;
217
236
  }
218
237
 
219
- get connectionState() {
238
+ get connectionState(): globalThis.RTCPeerConnectionState {
220
239
  return this.#peerConnection.state();
221
240
  }
222
241
 
223
- get iceConnectionState() {
242
+ get iceConnectionState(): globalThis.RTCIceConnectionState {
224
243
  let state = this.#peerConnection.iceState();
225
244
  // libdatachannel uses 'completed' instead of 'connected'
226
245
  // see /webrtc/getstats.html
@@ -228,43 +247,43 @@ export default class _RTCPeerConnection extends EventTarget {
228
247
  return state;
229
248
  }
230
249
 
231
- get iceGatheringState() {
250
+ get iceGatheringState(): globalThis.RTCIceGatheringState {
232
251
  return this.#peerConnection.gatheringState();
233
252
  }
234
253
 
235
- get currentLocalDescription() {
236
- return new RTCSessionDescription(this.#peerConnection.localDescription());
254
+ get currentLocalDescription(): RTCSessionDescription {
255
+ return new RTCSessionDescription(this.#peerConnection.localDescription() as any);
237
256
  }
238
257
 
239
- get currentRemoteDescription() {
240
- return new RTCSessionDescription(this.#peerConnection.remoteDescription());
258
+ get currentRemoteDescription(): RTCSessionDescription {
259
+ return new RTCSessionDescription(this.#peerConnection.remoteDescription() as any);
241
260
  }
242
261
 
243
- get localDescription() {
244
- return new RTCSessionDescription(this.#peerConnection.localDescription());
262
+ get localDescription(): RTCSessionDescription {
263
+ return new RTCSessionDescription(this.#peerConnection.localDescription() as any);
245
264
  }
246
265
 
247
- get pendingLocalDescription() {
248
- return new RTCSessionDescription(this.#peerConnection.localDescription());
266
+ get pendingLocalDescription(): RTCSessionDescription {
267
+ return new RTCSessionDescription(this.#peerConnection.localDescription() as any);
249
268
  }
250
269
 
251
- get pendingRemoteDescription() {
252
- return new RTCSessionDescription(this.#peerConnection.remoteDescription());
270
+ get pendingRemoteDescription(): RTCSessionDescription {
271
+ return new RTCSessionDescription(this.#peerConnection.remoteDescription() as any);
253
272
  }
254
273
 
255
- get remoteDescription() {
256
- return new RTCSessionDescription(this.#peerConnection.remoteDescription());
274
+ get remoteDescription(): RTCSessionDescription {
275
+ return new RTCSessionDescription(this.#peerConnection.remoteDescription() as any);
257
276
  }
258
277
 
259
- get sctp() {
278
+ get sctp(): RTCSctpTransport {
260
279
  return this.#sctp;
261
280
  }
262
281
 
263
- get signalingState() {
282
+ get signalingState(): globalThis.RTCSignalingState {
264
283
  return this.#peerConnection.signalingState();
265
284
  }
266
285
 
267
- async addIceCandidate(candidate) {
286
+ async addIceCandidate(candidate?: globalThis.RTCIceCandidateInit | RTCIceCandidate): Promise<void> {
268
287
  if (!candidate || !candidate.candidate) {
269
288
  return;
270
289
  }
@@ -281,12 +300,12 @@ export default class _RTCPeerConnection extends EventTarget {
281
300
  // ??
282
301
  if (candidate.sdpMid && candidate.sdpMid.length > 3) {
283
302
  // console.log(candidate.sdpMid);
284
- throw exceptions.OperationError('Invalid sdpMid format');
303
+ throw new exceptions.OperationError('Invalid sdpMid format');
285
304
  }
286
305
 
287
306
  // We don't care about sdpMLineIndex, just for test
288
307
  if (!candidate.sdpMid && candidate.sdpMLineIndex > 1) {
289
- throw exceptions.OperationError('This is only for test case.');
308
+ throw new exceptions.OperationError('This is only for test case.');
290
309
  }
291
310
 
292
311
  try {
@@ -295,26 +314,28 @@ export default class _RTCPeerConnection extends EventTarget {
295
314
  new RTCIceCandidate({ candidate: candidate.candidate, sdpMid: candidate.sdpMid || '0' }),
296
315
  );
297
316
  } catch (error) {
298
- if (!error || !error.message) throw exceptions.NotFoundError('Unknown error');
317
+ if (!error || !error.message) throw new exceptions.NotFoundError('Unknown error');
299
318
 
300
319
  // Check error Message if contains specific message
301
320
  if (error.message.includes('remote candidate without remote description'))
302
- throw exceptions.InvalidStateError(error.message);
303
- if (error.message.includes('Invalid candidate format')) throw exceptions.OperationError(error.message);
321
+ throw new exceptions.InvalidStateError(error.message);
322
+ if (error.message.includes('Invalid candidate format')) throw new exceptions.OperationError(error.message);
304
323
 
305
- throw exceptions.NotFoundError(error.message);
324
+ throw new exceptions.NotFoundError(error.message);
306
325
  }
307
326
  }
308
327
 
309
- addTrack(track, ...streams) {
328
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
329
+ addTrack(_track, ..._streams): globalThis.RTCRtpSender {
310
330
  throw new DOMException('Not implemented');
311
331
  }
312
332
 
313
- addTransceiver(trackOrKind, init) {
333
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
334
+ addTransceiver(_trackOrKind, _init): globalThis.RTCRtpTransceiver {
314
335
  throw new DOMException('Not implemented');
315
336
  }
316
337
 
317
- close() {
338
+ close(): void {
318
339
  // close all channels before shutting down
319
340
  this.#dataChannels.forEach((channel) => {
320
341
  channel.close();
@@ -324,11 +345,12 @@ export default class _RTCPeerConnection extends EventTarget {
324
345
  this.#peerConnection.close();
325
346
  }
326
347
 
327
- createAnswer() {
348
+ createAnswer(): Promise<globalThis.RTCSessionDescriptionInit | any> {
328
349
  return this.#localAnswer;
329
350
  }
330
351
 
331
- createDataChannel(label, opts = {}) {
352
+
353
+ createDataChannel(label, opts = {}): RTCDataChannel {
332
354
  const channel = this.#peerConnection.createDataChannel(label, opts);
333
355
  const dataChannel = new RTCDataChannel(channel, opts);
334
356
 
@@ -342,32 +364,32 @@ export default class _RTCPeerConnection extends EventTarget {
342
364
  return dataChannel;
343
365
  }
344
366
 
345
- createOffer() {
367
+ createOffer(): Promise<globalThis.RTCSessionDescriptionInit | any> {
346
368
  return this.#localOffer;
347
369
  }
348
370
 
349
- getConfiguration() {
371
+ getConfiguration(): globalThis.RTCConfiguration {
350
372
  return this.#config;
351
373
  }
352
374
 
353
- getReceivers() {
375
+ getReceivers(): globalThis.RTCRtpReceiver[] {
354
376
  throw new DOMException('Not implemented');
355
377
  }
356
378
 
357
- getSenders() {
379
+ getSenders(): globalThis.RTCRtpSender[] {
358
380
  throw new DOMException('Not implemented');
359
381
  }
360
382
 
361
- getStats() {
383
+ getStats(): Promise<globalThis.RTCStatsReport> {
362
384
  return new Promise((resolve) => {
363
- let report = new Map();
364
- let cp = this.#peerConnection.getSelectedCandidatePair();
365
- let bytesSent = this.#peerConnection.bytesSent();
366
- let bytesReceived = this.#peerConnection.bytesReceived();
367
- let rtt = this.#peerConnection.rtt();
368
-
369
- let localIdRs = getRandomString(8);
370
- let localId = 'RTCIceCandidate_' + localIdRs;
385
+ const report = new Map();
386
+ const cp = this.#peerConnection.getSelectedCandidatePair();
387
+ const bytesSent = this.#peerConnection.bytesSent();
388
+ const bytesReceived = this.#peerConnection.bytesReceived();
389
+ const rtt = this.#peerConnection.rtt();
390
+
391
+ const localIdRs = getRandomString(8);
392
+ const localId = 'RTCIceCandidate_' + localIdRs;
371
393
  report.set(localId, {
372
394
  id: localId,
373
395
  type: 'local-candidate',
@@ -377,8 +399,8 @@ export default class _RTCPeerConnection extends EventTarget {
377
399
  port: cp.local.port,
378
400
  });
379
401
 
380
- let remoteIdRs = getRandomString(8);
381
- let remoteId = 'RTCIceCandidate_' + remoteIdRs;
402
+ const remoteIdRs = getRandomString(8);
403
+ const remoteId = 'RTCIceCandidate_' + remoteIdRs;
382
404
  report.set(remoteId, {
383
405
  id: remoteId,
384
406
  type: 'remote-candidate',
@@ -388,7 +410,7 @@ export default class _RTCPeerConnection extends EventTarget {
388
410
  port: cp.remote.port,
389
411
  });
390
412
 
391
- let candidateId = 'RTCIceCandidatePair_' + localIdRs + '_' + remoteIdRs;
413
+ const candidateId = 'RTCIceCandidatePair_' + localIdRs + '_' + remoteIdRs;
392
414
  report.set(candidateId, {
393
415
  id: candidateId,
394
416
  type: 'candidate-pair',
@@ -404,7 +426,7 @@ export default class _RTCPeerConnection extends EventTarget {
404
426
  currentRoundTripTime: rtt,
405
427
  });
406
428
 
407
- let transportId = 'RTCTransport_0_1';
429
+ const transportId = 'RTCTransport_0_1';
408
430
  report.set(transportId, {
409
431
  id: transportId,
410
432
  timestamp: Date.now(),
@@ -429,50 +451,50 @@ export default class _RTCPeerConnection extends EventTarget {
429
451
  });
430
452
  }
431
453
 
432
- getTransceivers() {
454
+ getTransceivers(): globalThis.RTCRtpTransceiver[] {
433
455
  return []; // throw new DOMException('Not implemented');
434
456
  }
435
457
 
436
- removeTrack() {
458
+ removeTrack(): void {
437
459
  throw new DOMException('Not implemented');
438
460
  }
439
461
 
440
- restartIce() {
462
+ restartIce(): Promise<void> {
441
463
  throw new DOMException('Not implemented');
442
464
  }
443
465
 
444
- async setLocalDescription(description) {
466
+ async setLocalDescription(description: globalThis.RTCSessionDescriptionInit): Promise<void> {
445
467
  if (description?.type !== 'offer') {
446
468
  // any other type causes libdatachannel to throw
447
469
  return;
448
470
  }
449
471
 
450
- this.#peerConnection.setLocalDescription(description?.type);
472
+ this.#peerConnection.setLocalDescription(description?.type as any);
451
473
  }
452
474
 
453
- async setRemoteDescription(description) {
475
+ async setRemoteDescription(description: globalThis.RTCSessionDescriptionInit): Promise<void> {
454
476
  if (description.sdp == null) {
455
477
  throw new DOMException('Remote SDP must be set');
456
478
  }
457
479
 
458
- this.#peerConnection.setRemoteDescription(description.sdp, description.type);
480
+ this.#peerConnection.setRemoteDescription(description.sdp, description.type as any);
459
481
  }
460
482
  }
461
483
 
462
- function createDeferredPromise() {
463
- let resolve, reject;
484
+ function createDeferredPromise(): any {
485
+ let resolve: any, reject: any;
464
486
 
465
- let promise = new Promise(function (_resolve, _reject) {
487
+ const promise = new Promise(function (_resolve, _reject) {
466
488
  resolve = _resolve;
467
489
  reject = _reject;
468
490
  });
469
491
 
470
- promise.resolve = resolve;
471
- promise.reject = reject;
492
+ (promise as any).resolve = resolve;
493
+ (promise as any).reject = reject;
472
494
  return promise;
473
495
  }
474
496
 
475
- function getRandomString(length) {
497
+ function getRandomString(length): string {
476
498
  return Math.random()
477
499
  .toString(36)
478
500
  .substring(2, 2 + length);
@@ -1,18 +1,20 @@
1
- import RTCDtlsTransport from './RTCDtlsTransport.js';
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import RTCDtlsTransport from './RTCDtlsTransport';
3
+ import RTCPeerConnection from './RTCPeerConnection';
2
4
 
3
- export default class _RTCSctpTransport extends EventTarget {
4
- #pc = null;
5
+ export default class RTCSctpTransport extends EventTarget implements globalThis.RTCSctpTransport {
6
+ #pc: RTCPeerConnection = null;
5
7
  #extraFunctions = null;
6
- #transport = null;
8
+ #transport: RTCDtlsTransport = null;
7
9
 
8
- onstatechange = null;
10
+ onstatechange: ((this: RTCSctpTransport, ev: Event) => any) | null = null;
9
11
 
10
- constructor({ pc, extraFunctions }) {
12
+ constructor(initial: { pc: RTCPeerConnection, extraFunctions }) {
11
13
  super();
12
- this.#pc = pc;
13
- this.#extraFunctions = extraFunctions;
14
+ this.#pc = initial.pc;
15
+ this.#extraFunctions = initial.extraFunctions;
14
16
 
15
- this.#transport = new RTCDtlsTransport({ pc, extraFunctions });
17
+ this.#transport = new RTCDtlsTransport({ pc: initial.pc, extraFunctions: initial.extraFunctions });
16
18
 
17
19
  // forward peerConnection events
18
20
  this.#pc.addEventListener('connectionstatechange', () => {
@@ -25,29 +27,29 @@ export default class _RTCSctpTransport extends EventTarget {
25
27
  });
26
28
  }
27
29
 
28
- get maxChannels() {
30
+ get maxChannels(): number | null {
29
31
  if (this.state !== 'connected') return null;
30
32
  return this.#pc ? this.#extraFunctions.maxDataChannelId() : 0;
31
33
  }
32
34
 
33
- get maxMessageSize() {
35
+ get maxMessageSize(): number {
34
36
  if (this.state !== 'connected') return null;
35
37
  return this.#pc ? this.#extraFunctions.maxMessageSize() : 0;
36
38
  }
37
39
 
38
- get state() {
40
+ get state(): globalThis.RTCSctpTransportState {
39
41
  // reduce state from new, connecting, connected, disconnected, failed, closed, unknown
40
42
  // to RTCSctpTransport states connecting, connected, closed
41
43
  let state = this.#pc.connectionState;
42
44
  if (state === 'new' || state === 'connecting') {
43
45
  state = 'connecting';
44
- } else if (state === 'disconnected' || state === 'failed' || state === 'closed' || state === 'unknown') {
46
+ } else if (state === 'disconnected' || state === 'failed' || state === 'closed') {
45
47
  state = 'closed';
46
48
  }
47
49
  return state;
48
50
  }
49
51
 
50
- get transport() {
52
+ get transport(): RTCDtlsTransport {
51
53
  return this.#transport;
52
54
  }
53
55
  }
@@ -6,29 +6,24 @@
6
6
  // sdp: 'v=0\r\no=- 1234567890 1234567890 IN IP4 192.168.1.1\r\ns=-\r\nt=0 0\r\na=ice-ufrag:abcd\r\na=ice-pwd:efgh\r\n'
7
7
  // };
8
8
 
9
- export default class _RTCSessionDescription {
10
- #type;
11
- #sdp;
12
-
13
- constructor(init = {}) {
14
- // Allow Empty Constructor
15
- // if (!init || !init.type || !init.sdp) {
16
- // throw new DOMException('Type and sdp properties are required.');
17
- // }
9
+ export default class RTCSessionDescription implements globalThis.RTCSessionDescriptionInit {
10
+ #type: globalThis.RTCSdpType;
11
+ #sdp: string;
18
12
 
13
+ constructor(init: globalThis.RTCSessionDescriptionInit) {
19
14
  this.#type = init ? init.type : null;
20
15
  this.#sdp = init ? init.sdp : null;
21
16
  }
22
17
 
23
- get type() {
18
+ get type(): globalThis.RTCSdpType {
24
19
  return this.#type;
25
20
  }
26
21
 
27
- get sdp() {
22
+ get sdp(): string {
28
23
  return this.#sdp;
29
24
  }
30
25
 
31
- toJSON() {
26
+ toJSON(): globalThis.RTCSessionDescriptionInit {
32
27
  return {
33
28
  sdp: this.#sdp,
34
29
  type: this.#type,
@@ -1,12 +1,13 @@
1
- import RTCCertificate from './RTCCertificate.js';
2
- import RTCDataChannel from './RTCDataChannel.js';
3
- import RTCDtlsTransport from './RTCDtlsTransport.js';
4
- import RTCIceCandidate from './RTCIceCandidate.js';
5
- import RTCIceTransport from './RTCIceTransport.js';
6
- import RTCPeerConnection from './RTCPeerConnection.js';
7
- import RTCSctpTransport from './RTCSctpTransport.js';
8
- import RTCSessionDescription from './RTCSessionDescription.js';
9
- import { RTCDataChannelEvent, RTCPeerConnectionIceEvent } from './Events.js';
1
+ import RTCCertificate from './RTCCertificate';
2
+ import RTCDataChannel from './RTCDataChannel';
3
+ import RTCDtlsTransport from './RTCDtlsTransport';
4
+ import RTCIceCandidate from './RTCIceCandidate';
5
+ import RTCIceTransport from './RTCIceTransport';
6
+ import RTCPeerConnection from './RTCPeerConnection';
7
+ import RTCSctpTransport from './RTCSctpTransport';
8
+ import RTCSessionDescription from './RTCSessionDescription';
9
+ import { RTCDataChannelEvent, RTCPeerConnectionIceEvent } from './Events';
10
+ import RTCError from './RTCError';
10
11
 
11
12
  export {
12
13
  RTCCertificate,
@@ -19,6 +20,7 @@ export {
19
20
  RTCSessionDescription,
20
21
  RTCDataChannelEvent,
21
22
  RTCPeerConnectionIceEvent,
23
+ RTCError,
22
24
  };
23
25
 
24
26
  export default {
@@ -32,4 +34,5 @@ export default {
32
34
  RTCSessionDescription,
33
35
  RTCDataChannelEvent,
34
36
  RTCPeerConnectionIceEvent,
37
+ RTCError,
35
38
  };
package/tsconfig.json CHANGED
@@ -1,14 +1,21 @@
1
1
  {
2
- "compilerOptions": {
3
- "target": "es5",
4
- "module": "commonjs",
5
- "declaration": true,
6
- "strict": true,
7
- "esModuleInterop": true,
8
- "noEmit": true
9
- },
10
- "exclude": [
11
- "node_modules",
12
- "build"
13
- ]
14
- }
2
+ "compilerOptions": {
3
+ "target": "ESNext",
4
+ "moduleResolution": "Node",
5
+ "rootDir": ".",
6
+ "importsNotUsedAsValues": "remove",
7
+ "esModuleInterop": true,
8
+ "skipLibCheck": true,
9
+ "forceConsistentCasingInFileNames": true,
10
+ "noImplicitAny": false,
11
+ "noImplicitThis": false,
12
+ "noImplicitReturns": true,
13
+ "strictNullChecks": false,
14
+ "noUnusedLocals": true,
15
+ "alwaysStrict": true,
16
+ "outDir": "./dist",
17
+ "module": "CommonJS"
18
+ },
19
+ "include": ["src/**/*", "test/**/*"],
20
+ "exclude": ["node_modules", "dist", "src/cpp", "test/wpt-tests/wpt"]
21
+ }