node-datachannel 0.12.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 (132) 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 +46 -43
  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/{polyfill/RTCIceCandidate.js → src/polyfill/RTCIceCandidate.ts} +35 -35
  22. package/{polyfill/RTCIceTransport.js → src/polyfill/RTCIceTransport.ts} +22 -20
  23. package/{polyfill/RTCPeerConnection.js → src/polyfill/RTCPeerConnection.ts} +128 -114
  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} +10 -10
  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 -109
  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 -15877
  50. package/examples/electron-demo/package.json +0 -44
  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 -21
  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/RTCError.d.ts +0 -11
  83. package/polyfill/RTCError.js +0 -65
  84. package/polyfill/RTCIceCandidate.d.ts +0 -20
  85. package/polyfill/RTCIceTransport.d.ts +0 -18
  86. package/polyfill/RTCPeerConnection.d.ts +0 -62
  87. package/polyfill/RTCSctpTransport.d.ts +0 -10
  88. package/polyfill/RTCSessionDescription.d.ts +0 -8
  89. package/polyfill/index.cjs +0 -1333
  90. package/polyfill/index.d.cts +0 -37
  91. package/polyfill/index.d.ts +0 -37
  92. package/test/connectivity.js +0 -86
  93. package/test/jest-tests/basic.test.js +0 -37
  94. package/test/jest-tests/multiple-run.test.js +0 -73
  95. package/test/jest-tests/p2p.test.js +0 -99
  96. package/test/jest-tests/polyfill.test.js +0 -10
  97. package/test/jest-tests/streams.test.js +0 -48
  98. package/test/jest-tests/websocket.test.js +0 -69
  99. package/test/polyfill-connectivity.js +0 -89
  100. package/test/websockets.js +0 -50
  101. package/test/wpt-tests/README.md +0 -46
  102. package/test/wpt-tests/chrome-failed-tests.js +0 -42
  103. package/test/wpt-tests/index.js +0 -96
  104. package/test/wpt-tests/last-test-results.md +0 -301
  105. package/test/wpt-tests/package-lock.json +0 -1712
  106. package/test/wpt-tests/package.json +0 -19
  107. package/test/wpt-tests/wpt-test-list.js +0 -139
  108. package/test/wpt-tests/wpt.js +0 -131
  109. /package/src/{data-channel-wrapper.cpp → cpp/data-channel-wrapper.cpp} +0 -0
  110. /package/src/{data-channel-wrapper.h → cpp/data-channel-wrapper.h} +0 -0
  111. /package/src/{main.cpp → cpp/main.cpp} +0 -0
  112. /package/src/{media-audio-wrapper.cpp → cpp/media-audio-wrapper.cpp} +0 -0
  113. /package/src/{media-audio-wrapper.h → cpp/media-audio-wrapper.h} +0 -0
  114. /package/src/{media-direction.cpp → cpp/media-direction.cpp} +0 -0
  115. /package/src/{media-direction.h → cpp/media-direction.h} +0 -0
  116. /package/src/{media-rtcpreceivingsession-wrapper.cpp → cpp/media-rtcpreceivingsession-wrapper.cpp} +0 -0
  117. /package/src/{media-rtcpreceivingsession-wrapper.h → cpp/media-rtcpreceivingsession-wrapper.h} +0 -0
  118. /package/src/{media-track-wrapper.cpp → cpp/media-track-wrapper.cpp} +0 -0
  119. /package/src/{media-track-wrapper.h → cpp/media-track-wrapper.h} +0 -0
  120. /package/src/{media-video-wrapper.cpp → cpp/media-video-wrapper.cpp} +0 -0
  121. /package/src/{media-video-wrapper.h → cpp/media-video-wrapper.h} +0 -0
  122. /package/src/{peer-connection-wrapper.cpp → cpp/peer-connection-wrapper.cpp} +0 -0
  123. /package/src/{peer-connection-wrapper.h → cpp/peer-connection-wrapper.h} +0 -0
  124. /package/src/{rtc-wrapper.cpp → cpp/rtc-wrapper.cpp} +0 -0
  125. /package/src/{rtc-wrapper.h → cpp/rtc-wrapper.h} +0 -0
  126. /package/src/{thread-safe-callback.cpp → cpp/thread-safe-callback.cpp} +0 -0
  127. /package/src/{thread-safe-callback.h → cpp/thread-safe-callback.h} +0 -0
  128. /package/src/{web-socket-server-wrapper.cpp → cpp/web-socket-server-wrapper.cpp} +0 -0
  129. /package/src/{web-socket-server-wrapper.h → cpp/web-socket-server-wrapper.h} +0 -0
  130. /package/src/{web-socket-wrapper.cpp → cpp/web-socket-wrapper.cpp} +0 -0
  131. /package/src/{web-socket-wrapper.h → cpp/web-socket-wrapper.h} +0 -0
  132. /package/{polyfill → src/polyfill}/README.md +0 -0
@@ -0,0 +1,126 @@
1
+ export interface Channel {
2
+ close(): void;
3
+ sendMessage(msg: string): boolean;
4
+ sendMessageBinary(buffer: Uint8Array): boolean;
5
+ isOpen(): boolean;
6
+ bufferedAmount(): number;
7
+ maxMessageSize(): number;
8
+ setBufferedAmountLowThreshold(newSize: number): void;
9
+ onOpen(cb: () => void): void;
10
+ onClosed(cb: () => void): void;
11
+ onError(cb: (err: string) => void): void;
12
+ onBufferedAmountLow(cb: () => void): void;
13
+ onMessage(cb: (msg: string | Buffer) => void): void;
14
+ }
15
+
16
+ export interface WebSocketServerConfiguration {
17
+ port?: number; // default 8080
18
+ enableTls?: boolean; // default = false;
19
+ certificatePemFile?: string;
20
+ keyPemFile?: string;
21
+ keyPemPass?: string;
22
+ bindAddress?: string;
23
+ connectionTimeout?: number; // milliseconds
24
+ maxMessageSize?: number;
25
+ }
26
+
27
+ // Enum in d.ts is tricky
28
+ export type LogLevel = 'Verbose' | 'Debug' | 'Info' | 'Warning' | 'Error' | 'Fatal';
29
+
30
+ // SCTP Settings
31
+ export interface SctpSettings {
32
+ recvBufferSize?: number;
33
+ sendBufferSize?: number;
34
+ maxChunksOnQueue?: number;
35
+ initialCongestionWindow?: number;
36
+ congestionControlModule?: number;
37
+ delayedSackTime?: number;
38
+ }
39
+
40
+ // Proxy Server
41
+ export type ProxyServerType = 'Socks5' | 'Http';
42
+ export interface ProxyServer {
43
+ type: ProxyServerType;
44
+ ip: string;
45
+ port: number;
46
+ username?: string;
47
+ password?: string;
48
+ }
49
+
50
+ export const enum RelayType {
51
+ TurnUdp = 'TurnUdp',
52
+ TurnTcp = 'TurnTcp',
53
+ TurnTls = 'TurnTls',
54
+ }
55
+
56
+ export interface IceServer {
57
+ hostname: string;
58
+ port: number;
59
+ username?: string;
60
+ password?: string;
61
+ relayType?: RelayType;
62
+ }
63
+
64
+ export type TransportPolicy = 'all' | 'relay';
65
+
66
+ export interface RtcConfig {
67
+ iceServers: (string | IceServer)[];
68
+ proxyServer?: ProxyServer;
69
+ bindAddress?: string;
70
+ enableIceTcp?: boolean;
71
+ enableIceUdpMux?: boolean;
72
+ disableAutoNegotiation?: boolean;
73
+ forceMediaTransport?: boolean;
74
+ portRangeBegin?: number;
75
+ portRangeEnd?: number;
76
+ maxMessageSize?: number;
77
+ mtu?: number;
78
+ iceTransportPolicy?: TransportPolicy;
79
+ }
80
+
81
+ // Lowercase to match the description type string from libdatachannel
82
+ export enum DescriptionType {
83
+ Unspec = 'unspec',
84
+ Offer = 'offer',
85
+ Answer = 'answer',
86
+ Pranswer = 'pranswer',
87
+ Rollback = 'rollback',
88
+ }
89
+
90
+ export type RTCSdpType = 'answer' | 'offer' | 'pranswer' | 'rollback';
91
+
92
+ export type RTCIceTransportState = "checking" | "closed" | "completed" | "connected" | "disconnected" | "failed" | "new";
93
+ export type RTCPeerConnectionState = "closed" | "connected" | "connecting" | "disconnected" | "failed" | "new";
94
+ export type RTCIceConnectionState = "checking" | "closed" | "completed" | "connected" | "disconnected" | "failed" | "new";
95
+ export type RTCIceGathererState = "complete" | "gathering" | "new";
96
+ export type RTCIceGatheringState = "complete" | "gathering" | "new";
97
+ export type RTCSignalingState = "closed" | "have-local-offer" | "have-local-pranswer" | "have-remote-offer" | "have-remote-pranswer" | "stable";
98
+
99
+
100
+ export interface DataChannelInitConfig {
101
+ protocol?: string;
102
+ negotiated?: boolean;
103
+ id?: number;
104
+ unordered?: boolean; // Reliability
105
+ maxPacketLifeTime?: number; // Reliability
106
+ maxRetransmits?: number; // Reliability
107
+ }
108
+
109
+ export interface SelectedCandidateInfo {
110
+ address: string;
111
+ port: number;
112
+ type: string;
113
+ transportType: string;
114
+ candidate: string;
115
+ mid: string;
116
+ priority: number;
117
+ }
118
+
119
+ // Must be same as rtc enum class Direction
120
+ export const enum Direction {
121
+ SendOnly = 'SendOnly',
122
+ RecvOnly = 'RecvOnly',
123
+ SendRecv = 'SendRecv',
124
+ Inactive = 'Inactive',
125
+ Unknown = 'Unknown',
126
+ }
@@ -1,11 +1,13 @@
1
1
  import { EventEmitter } from 'events';
2
- import nodeDataChannel from './node-datachannel.js';
2
+ import nodeDataChannel from './node-datachannel';
3
+ import { WebSocketServerConfiguration } from './types';
4
+ import { WebSocket } from './websocket';
3
5
 
4
- export default class WebSocketServer extends EventEmitter {
5
- #server;
6
- #clients = [];
6
+ export class WebSocketServer extends EventEmitter {
7
+ #server: any;
8
+ #clients: WebSocket[] = [];
7
9
 
8
- constructor(options) {
10
+ constructor(options: WebSocketServerConfiguration) {
9
11
  super();
10
12
  this.#server = new nodeDataChannel.WebSocketServer(options);
11
13
 
@@ -15,11 +17,11 @@ export default class WebSocketServer extends EventEmitter {
15
17
  });
16
18
  }
17
19
 
18
- port() {
20
+ port(): number {
19
21
  return this.#server?.port() || 0;
20
22
  }
21
23
 
22
- stop() {
24
+ stop(): void {
23
25
  this.#clients.forEach((client) => {
24
26
  client?.close();
25
27
  });
@@ -28,7 +30,7 @@ export default class WebSocketServer extends EventEmitter {
28
30
  this.removeAllListeners();
29
31
  }
30
32
 
31
- onClient(cb) {
33
+ onClient(cb: (clientSocket: WebSocket) => void): void {
32
34
  if (this.#server) this.on('client', cb);
33
35
  }
34
36
  }
@@ -0,0 +1,26 @@
1
+ import nodeDataChannel from './node-datachannel';
2
+ import { Channel, WebSocketServerConfiguration } from './types';
3
+
4
+ export interface WebSocket extends Channel {
5
+ open(url: string): void;
6
+ forceClose(): void;
7
+ remoteAddress(): string | undefined;
8
+ path(): string | undefined;
9
+
10
+ // Channel implementation
11
+ close(): void;
12
+ sendMessage(msg: string): boolean;
13
+ sendMessageBinary(buffer: Uint8Array): boolean;
14
+ isOpen(): boolean;
15
+ bufferedAmount(): number;
16
+ maxMessageSize(): number;
17
+ setBufferedAmountLowThreshold(newSize: number): void;
18
+ onOpen(cb: () => void): void;
19
+ onClosed(cb: () => void): void;
20
+ onError(cb: (err: string) => void): void;
21
+ onBufferedAmountLow(cb: () => void): void;
22
+ onMessage(cb: (msg: string | Buffer) => void): void;
23
+ }
24
+ export const WebSocket: {
25
+ new(config?: WebSocketServerConfiguration): WebSocket
26
+ } = nodeDataChannel.WebSocket
@@ -0,0 +1,33 @@
1
+ import RTCDataChannel from './RTCDataChannel';
2
+ import RTCIceCandidate from './RTCIceCandidate';
3
+
4
+
5
+ export class RTCPeerConnectionIceEvent extends Event implements globalThis.RTCPeerConnectionIceEvent {
6
+ #candidate: RTCIceCandidate;
7
+
8
+ constructor(candidate: RTCIceCandidate) {
9
+ super('icecandidate');
10
+
11
+ this.#candidate = candidate;
12
+ }
13
+
14
+ get candidate(): RTCIceCandidate {
15
+ return this.#candidate;
16
+ }
17
+ }
18
+
19
+ export class RTCDataChannelEvent extends Event implements globalThis.RTCDataChannelEvent {
20
+ #channel: RTCDataChannel;
21
+
22
+ constructor(type: string, eventInitDict: globalThis.RTCDataChannelEventInit) {
23
+ super(type);
24
+
25
+ if (type && !eventInitDict.channel) throw new TypeError('channel member is required');
26
+
27
+ this.#channel = eventInitDict?.channel as RTCDataChannel;
28
+ }
29
+
30
+ get channel(): RTCDataChannel {
31
+ return this.#channel;
32
+ }
33
+ }
@@ -0,0 +1,37 @@
1
+ /// <reference lib="dom" />
2
+
3
+ export class InvalidStateError extends DOMException {
4
+ constructor(msg: string) {
5
+ super(msg, 'InvalidStateError');
6
+ }
7
+ };
8
+
9
+ export class TypeError extends DOMException {
10
+ constructor(msg: string) {
11
+ super(msg, 'TypeError');
12
+ }
13
+ };
14
+
15
+ export class OperationError extends DOMException {
16
+ constructor(msg: string) {
17
+ super(msg, 'OperationError');
18
+ }
19
+ };
20
+
21
+ export class NotFoundError extends DOMException {
22
+ constructor(msg: string) {
23
+ super(msg, 'NotFoundError');
24
+ }
25
+ };
26
+
27
+ export class InvalidAccessError extends DOMException {
28
+ constructor(msg: string) {
29
+ super(msg, 'InvalidAccessError');
30
+ }
31
+ };
32
+
33
+ export class SyntaxError extends DOMException {
34
+ constructor(msg: string) {
35
+ super(msg, 'SyntaxError');
36
+ }
37
+ };
@@ -0,0 +1,17 @@
1
+ export default class RTCCertificate implements globalThis.RTCCertificate {
2
+ #expires: number;
3
+ #fingerprints: globalThis.RTCDtlsFingerprint[];
4
+
5
+ constructor() {
6
+ this.#expires = null;
7
+ this.#fingerprints = [];
8
+ }
9
+
10
+ get expires(): number {
11
+ return this.#expires;
12
+ }
13
+
14
+ getFingerprints(): globalThis.RTCDtlsFingerprint[] {
15
+ return this.#fingerprints;
16
+ }
17
+ }
@@ -1,26 +1,29 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
1
2
  import 'node-domexception';
2
- import * as exceptions from './Exception.js';
3
-
4
- export default class _RTCDataChannel extends EventTarget {
5
- #dataChannel;
6
- #readyState;
7
- #bufferedAmountLowThreshold;
8
- #binaryType;
9
- #maxPacketLifeTime;
10
- #maxRetransmits;
11
- #negotiated;
12
- #ordered;
3
+ import * as exceptions from './Exception';
4
+ import { DataChannel } from '../lib/index';
5
+
6
+ export default class RTCDataChannel extends EventTarget implements globalThis.RTCDataChannel {
7
+ #dataChannel: DataChannel;
8
+ #readyState: RTCDataChannelState;
9
+ #bufferedAmountLowThreshold: number;
10
+ #binaryType: BinaryType;
11
+ #maxPacketLifeTime: number | null;
12
+ #maxRetransmits: number | null;
13
+ #negotiated: boolean;
14
+ #ordered: boolean;
13
15
 
14
16
  #closeRequested = false;
15
17
 
16
- onbufferedamountlow;
17
- onclose;
18
- onclosing;
19
- onerror;
20
- onmessage;
21
- onopen;
18
+ // events
19
+ onbufferedamountlow: ((this: RTCDataChannel, ev: Event) => any) | null;
20
+ onclose: ((this: RTCDataChannel, ev: Event) => any) | null;
21
+ onclosing: ((this: RTCDataChannel, ev: Event) => any) | null;
22
+ onerror: ((this: RTCDataChannel, ev: Event) => any) | null;
23
+ onmessage: ((this: RTCDataChannel, ev: MessageEvent) => any) | null;
24
+ onopen: ((this: RTCDataChannel, ev: Event) => any) | null;
22
25
 
23
- constructor(dataChannel, opts = {}) {
26
+ constructor(dataChannel: DataChannel, opts: globalThis.RTCDataChannelInit = {}) {
24
27
  super();
25
28
 
26
29
  this.#dataChannel = dataChannel;
@@ -35,25 +38,25 @@ export default class _RTCDataChannel extends EventTarget {
35
38
  // forward dataChannel events
36
39
  this.#dataChannel.onOpen(() => {
37
40
  this.#readyState = 'open';
38
- this.dispatchEvent(new Event('open', { channel: this }));
41
+ this.dispatchEvent(new Event('open', {}));
39
42
  });
40
43
 
41
44
  this.#dataChannel.onClosed(() => {
42
45
  // Simulate closing event
43
46
  if (!this.#closeRequested) {
44
47
  this.#readyState = 'closing';
45
- this.dispatchEvent(new Event('closing', { channel: this }));
48
+ this.dispatchEvent(new Event('closing'));
46
49
  }
47
50
 
48
51
  setImmediate(() => {
49
52
  this.#readyState = 'closed';
50
- this.dispatchEvent(new Event('close', { channel: this }));
53
+ this.dispatchEvent(new Event('close'));
51
54
  });
52
55
  });
53
56
 
54
57
  this.#dataChannel.onError((msg) => {
55
58
  this.dispatchEvent(
56
- new RTCErrorEvent('error', {
59
+ new globalThis.RTCErrorEvent('error', {
57
60
  error: new RTCError(
58
61
  {
59
62
  errorDetail: 'data-channel-failure',
@@ -65,20 +68,20 @@ export default class _RTCDataChannel extends EventTarget {
65
68
  });
66
69
 
67
70
  this.#dataChannel.onBufferedAmountLow(() => {
68
- this.dispatchEvent(new Event('bufferedamountlow', { channel: this }));
71
+ this.dispatchEvent(new Event('bufferedamountlow'));
69
72
  });
70
73
 
71
74
  this.#dataChannel.onMessage((data) => {
72
75
  if (ArrayBuffer.isView(data)) {
73
- data = data.buffer;
76
+ data = Buffer.from(data.buffer);
74
77
  }
75
78
 
76
- this.dispatchEvent(new MessageEvent('message', { data, channel: this }));
79
+ this.dispatchEvent(new MessageEvent('message', { data }));
77
80
  });
78
81
 
79
82
  // forward events to properties
80
83
  this.addEventListener('message', (e) => {
81
- if (this.onmessage) this.onmessage(e);
84
+ if (this.onmessage) this.onmessage(e as MessageEvent);
82
85
  });
83
86
  this.addEventListener('bufferedamountlow', (e) => {
84
87
  if (this.onbufferedamountlow) this.onbufferedamountlow(e);
@@ -107,15 +110,15 @@ export default class _RTCDataChannel extends EventTarget {
107
110
  this.#binaryType = type;
108
111
  }
109
112
 
110
- get binaryType() {
113
+ get binaryType(): BinaryType {
111
114
  return this.#binaryType;
112
115
  }
113
116
 
114
- get bufferedAmount() {
117
+ get bufferedAmount(): number {
115
118
  return this.#dataChannel.bufferedAmount();
116
119
  }
117
120
 
118
- get bufferedAmountLowThreshold() {
121
+ get bufferedAmountLowThreshold(): number {
119
122
  return this.#bufferedAmountLowThreshold;
120
123
  }
121
124
 
@@ -125,41 +128,41 @@ export default class _RTCDataChannel extends EventTarget {
125
128
  this.#dataChannel.setBufferedAmountLowThreshold(number);
126
129
  }
127
130
 
128
- get id() {
131
+ get id(): number | null {
129
132
  return this.#dataChannel.getId();
130
133
  }
131
134
 
132
- get label() {
135
+ get label(): string {
133
136
  return this.#dataChannel.getLabel();
134
137
  }
135
138
 
136
- get maxPacketLifeTime() {
139
+ get maxPacketLifeTime(): number | null {
137
140
  return this.#maxPacketLifeTime;
138
141
  }
139
142
 
140
- get maxRetransmits() {
143
+ get maxRetransmits(): number | null {
141
144
  return this.#maxRetransmits;
142
145
  }
143
146
 
144
- get negotiated() {
147
+ get negotiated(): boolean {
145
148
  return this.#negotiated;
146
149
  }
147
150
 
148
- get ordered() {
151
+ get ordered(): boolean {
149
152
  return this.#ordered;
150
153
  }
151
154
 
152
- get protocol() {
155
+ get protocol(): string {
153
156
  return this.#dataChannel.getProtocol();
154
157
  }
155
158
 
156
- get readyState() {
159
+ get readyState(): globalThis.RTCDataChannelState {
157
160
  return this.#readyState;
158
161
  }
159
162
 
160
- send(data) {
163
+ send(data): void {
161
164
  if (this.#readyState !== 'open') {
162
- throw exceptions.InvalidStateError(
165
+ throw new exceptions.InvalidStateError(
163
166
  "Failed to execute 'send' on 'RTCDataChannel': RTCDataChannel.readyState is not 'open'",
164
167
  );
165
168
  }
@@ -176,7 +179,7 @@ export default class _RTCDataChannel extends EventTarget {
176
179
  }
177
180
  }
178
181
 
179
- close() {
182
+ close(): void {
180
183
  this.#closeRequested = true;
181
184
  this.#dataChannel.close();
182
185
  }
@@ -0,0 +1,47 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import RTCIceTransport from './RTCIceTransport';
3
+ import RTCPeerConnection from './RTCPeerConnection';
4
+
5
+ export default class RTCDtlsTransport extends EventTarget implements globalThis.RTCDtlsTransport {
6
+ #pc: RTCPeerConnection = null;
7
+ #iceTransport = null;
8
+
9
+ onstatechange: ((this: RTCDtlsTransport, ev: Event) => any) | null = null;
10
+ onerror: ((this: RTCDtlsTransport, ev: Event) => any) | null = null;
11
+
12
+ constructor(init: { pc: RTCPeerConnection, extraFunctions }) {
13
+ super();
14
+ this.#pc = init.pc;
15
+
16
+ this.#iceTransport = new RTCIceTransport({ pc: init.pc, extraFunctions: init.extraFunctions });
17
+
18
+ // forward peerConnection events
19
+ this.#pc.addEventListener('connectionstatechange', () => {
20
+ this.dispatchEvent(new Event('statechange'));
21
+ });
22
+
23
+ // forward events to properties
24
+ this.addEventListener('statechange', (e) => {
25
+ if (this.onstatechange) this.onstatechange(e);
26
+ });
27
+ }
28
+
29
+ get iceTransport(): RTCIceTransport {
30
+ return this.#iceTransport;
31
+ }
32
+
33
+ get state(): RTCDtlsTransportState {
34
+ // reduce state from new, connecting, connected, disconnected, failed, closed, unknown
35
+ // to RTCDtlsTRansport states new, connecting, connected, closed, failed
36
+ let state = this.#pc ? this.#pc.connectionState : 'new';
37
+ if (state === 'disconnected') {
38
+ state = 'closed';
39
+ }
40
+ return state;
41
+ }
42
+
43
+ getRemoteCertificates(): ArrayBuffer[] {
44
+ // TODO: implement
45
+ return [new ArrayBuffer(0)];
46
+ }
47
+ }
@@ -0,0 +1,71 @@
1
+ export default class RTCError extends DOMException implements globalThis.RTCError {
2
+ #errorDetail: RTCErrorDetailType;
3
+ #receivedAlert: number | null;
4
+ #sctpCauseCode: number | null;
5
+ #sdpLineNumber: number | null;
6
+ #sentAlert: number | null;
7
+
8
+ constructor(init: globalThis.RTCErrorInit, message?: string) {
9
+ super(message, 'OperationError');
10
+
11
+ if (!init || !init.errorDetail) throw new TypeError('Cannot construct RTCError, errorDetail is required');
12
+ if (
13
+ [
14
+ 'data-channel-failure',
15
+ 'dtls-failure',
16
+ 'fingerprint-failure',
17
+ 'hardware-encoder-error',
18
+ 'hardware-encoder-not-available',
19
+ 'sctp-failure',
20
+ 'sdp-syntax-error',
21
+ ].indexOf(init.errorDetail) === -1
22
+ )
23
+ throw new TypeError('Cannot construct RTCError, errorDetail is invalid');
24
+
25
+ this.#errorDetail = init.errorDetail;
26
+ this.#receivedAlert = init.receivedAlert ?? null;
27
+ this.#sctpCauseCode = init.sctpCauseCode ?? null;
28
+ this.#sdpLineNumber = init.sdpLineNumber ?? null;
29
+ this.#sentAlert = init.sentAlert ?? null;
30
+ }
31
+
32
+ get errorDetail(): globalThis.RTCErrorDetailType {
33
+ return this.#errorDetail;
34
+ }
35
+
36
+ set errorDetail(_value) {
37
+ throw new TypeError('Cannot set errorDetail, it is read-only');
38
+ }
39
+
40
+ get receivedAlert(): number | null {
41
+ return this.#receivedAlert;
42
+ }
43
+
44
+ set receivedAlert(_value) {
45
+ throw new TypeError('Cannot set receivedAlert, it is read-only');
46
+ }
47
+
48
+ get sctpCauseCode(): number | null {
49
+ return this.#sctpCauseCode;
50
+ }
51
+
52
+ set sctpCauseCode(_value) {
53
+ throw new TypeError('Cannot set sctpCauseCode, it is read-only');
54
+ }
55
+
56
+ get sdpLineNumber(): number | null {
57
+ return this.#sdpLineNumber;
58
+ }
59
+
60
+ set sdpLineNumber(_value) {
61
+ throw new TypeError('Cannot set sdpLineNumber, it is read-only');
62
+ }
63
+
64
+ get sentAlert(): number | null {
65
+ return this.#sentAlert;
66
+ }
67
+
68
+ set sentAlert(_value) {
69
+ throw new TypeError('Cannot set sentAlert, it is read-only');
70
+ }
71
+ }