node-datachannel 0.12.0 → 0.20.0-alpha.2
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/.eslintignore +5 -1
- package/.eslintrc.json +27 -0
- package/.prettierrc +12 -0
- package/CMakeLists.txt +13 -13
- package/dist/cjs/index.cjs +11 -0
- package/dist/cjs/index.cjs.map +1 -0
- package/dist/cjs/lib/datachannel-stream.cjs +101 -0
- package/dist/cjs/lib/datachannel-stream.cjs.map +1 -0
- package/dist/cjs/lib/index.cjs +61 -0
- package/dist/cjs/lib/index.cjs.map +1 -0
- package/dist/cjs/lib/node-datachannel.cjs +14 -0
- package/dist/cjs/lib/node-datachannel.cjs.map +1 -0
- package/dist/cjs/lib/websocket-server.cjs +44 -0
- package/dist/cjs/lib/websocket-server.cjs.map +1 -0
- package/dist/cjs/lib/websocket.cjs +8 -0
- package/dist/cjs/lib/websocket.cjs.map +1 -0
- package/dist/cjs/polyfill/Events.cjs +37 -0
- package/dist/cjs/polyfill/Events.cjs.map +1 -0
- package/dist/cjs/polyfill/Exception.cjs +34 -0
- package/dist/cjs/polyfill/Exception.cjs.map +1 -0
- package/dist/cjs/polyfill/RTCCertificate.cjs +31 -0
- package/dist/cjs/polyfill/RTCCertificate.cjs.map +1 -0
- package/dist/cjs/polyfill/RTCDataChannel.cjs +179 -0
- package/dist/cjs/polyfill/RTCDataChannel.cjs.map +1 -0
- package/dist/cjs/polyfill/RTCDtlsTransport.cjs +52 -0
- package/dist/cjs/polyfill/RTCDtlsTransport.cjs.map +1 -0
- package/dist/cjs/polyfill/RTCError.cjs +76 -0
- package/dist/cjs/polyfill/RTCError.cjs.map +1 -0
- package/dist/cjs/polyfill/RTCIceCandidate.cjs +129 -0
- package/dist/cjs/polyfill/RTCIceCandidate.cjs.map +1 -0
- package/dist/cjs/polyfill/RTCIceTransport.cjs +84 -0
- package/dist/cjs/polyfill/RTCIceTransport.cjs.map +1 -0
- package/dist/cjs/polyfill/RTCPeerConnection.cjs +417 -0
- package/dist/cjs/polyfill/RTCPeerConnection.cjs.map +1 -0
- package/dist/cjs/polyfill/RTCSctpTransport.cjs +61 -0
- package/dist/cjs/polyfill/RTCSctpTransport.cjs.map +1 -0
- package/dist/cjs/polyfill/RTCSessionDescription.cjs +37 -0
- package/dist/cjs/polyfill/RTCSessionDescription.cjs.map +1 -0
- package/dist/cjs/polyfill/index.cjs +42 -0
- package/dist/cjs/polyfill/index.cjs.map +1 -0
- package/dist/esm/index.mjs +8 -0
- package/dist/esm/index.mjs.map +1 -0
- package/dist/esm/lib/datachannel-stream.mjs +78 -0
- package/dist/esm/lib/datachannel-stream.mjs.map +1 -0
- package/dist/esm/lib/index.mjs +44 -0
- package/dist/esm/lib/index.mjs.map +1 -0
- package/dist/esm/lib/node-datachannel.mjs +18 -0
- package/dist/esm/lib/node-datachannel.mjs.map +1 -0
- package/dist/esm/lib/websocket-server.mjs +42 -0
- package/dist/esm/lib/websocket-server.mjs.map +1 -0
- package/dist/esm/lib/websocket.mjs +6 -0
- package/dist/esm/lib/websocket.mjs.map +1 -0
- package/dist/esm/polyfill/Events.mjs +34 -0
- package/dist/esm/polyfill/Events.mjs.map +1 -0
- package/dist/esm/polyfill/Exception.mjs +28 -0
- package/dist/esm/polyfill/Exception.mjs.map +1 -0
- package/dist/esm/polyfill/RTCCertificate.mjs +27 -0
- package/dist/esm/polyfill/RTCCertificate.mjs.map +1 -0
- package/dist/esm/polyfill/RTCDataChannel.mjs +175 -0
- package/dist/esm/polyfill/RTCDataChannel.mjs.map +1 -0
- package/dist/esm/polyfill/RTCDtlsTransport.mjs +48 -0
- package/dist/esm/polyfill/RTCDtlsTransport.mjs.map +1 -0
- package/dist/esm/polyfill/RTCError.mjs +72 -0
- package/dist/esm/polyfill/RTCError.mjs.map +1 -0
- package/dist/esm/polyfill/RTCIceCandidate.mjs +125 -0
- package/dist/esm/polyfill/RTCIceCandidate.mjs.map +1 -0
- package/dist/esm/polyfill/RTCIceTransport.mjs +80 -0
- package/dist/esm/polyfill/RTCIceTransport.mjs.map +1 -0
- package/dist/esm/polyfill/RTCPeerConnection.mjs +413 -0
- package/dist/esm/polyfill/RTCPeerConnection.mjs.map +1 -0
- package/dist/esm/polyfill/RTCSctpTransport.mjs +57 -0
- package/dist/esm/polyfill/RTCSctpTransport.mjs.map +1 -0
- package/dist/esm/polyfill/RTCSessionDescription.mjs +33 -0
- package/dist/esm/polyfill/RTCSessionDescription.mjs.map +1 -0
- package/dist/esm/polyfill/index.mjs +27 -0
- package/dist/esm/polyfill/index.mjs.map +1 -0
- package/dist/types/lib/datachannel-stream.d.ts +24 -0
- package/dist/types/lib/index.d.ts +164 -0
- package/dist/types/lib/types.d.ts +106 -0
- package/dist/types/lib/websocket-server.d.ts +13 -0
- package/dist/types/lib/websocket.d.ts +25 -0
- package/dist/types/polyfill/Events.d.ts +15 -0
- package/dist/types/polyfill/RTCCertificate.d.ts +8 -0
- package/dist/types/polyfill/RTCDataChannel.d.ts +29 -0
- package/dist/types/polyfill/RTCDtlsTransport.d.ts +17 -0
- package/dist/types/polyfill/RTCError.d.ts +16 -0
- package/dist/types/polyfill/RTCIceCandidate.d.ts +21 -0
- package/dist/types/polyfill/RTCIceTransport.d.ts +24 -0
- package/dist/types/polyfill/RTCPeerConnection.d.ts +56 -0
- package/dist/types/polyfill/RTCSctpTransport.d.ts +17 -0
- package/dist/types/polyfill/RTCSessionDescription.d.ts +9 -0
- package/{polyfill → dist/types/polyfill}/index.d.ts +3 -14
- package/jest.config.ts +14 -0
- package/package.json +47 -43
- package/rollup.config.mjs +63 -0
- package/src/index.ts +10 -0
- package/{lib/datachannel-stream.js → src/lib/datachannel-stream.ts} +16 -11
- package/src/lib/index.ts +180 -0
- package/src/lib/node-datachannel.ts +13 -0
- package/src/lib/types.ts +126 -0
- package/{lib/websocket-server.js → src/lib/websocket-server.ts} +10 -8
- package/src/lib/websocket.ts +26 -0
- package/src/polyfill/Events.ts +33 -0
- package/src/polyfill/Exception.ts +37 -0
- package/src/polyfill/RTCCertificate.ts +17 -0
- package/{polyfill/RTCDataChannel.js → src/polyfill/RTCDataChannel.ts} +43 -40
- package/src/polyfill/RTCDtlsTransport.ts +47 -0
- package/src/polyfill/RTCError.ts +71 -0
- package/{polyfill/RTCIceCandidate.js → src/polyfill/RTCIceCandidate.ts} +35 -35
- package/{polyfill/RTCIceTransport.js → src/polyfill/RTCIceTransport.ts} +22 -20
- package/{polyfill/RTCPeerConnection.js → src/polyfill/RTCPeerConnection.ts} +128 -114
- package/{polyfill/RTCSctpTransport.js → src/polyfill/RTCSctpTransport.ts} +16 -14
- package/{polyfill/RTCSessionDescription.js → src/polyfill/RTCSessionDescription.ts} +7 -12
- package/{polyfill/index.js → src/polyfill/index.ts} +10 -10
- package/tsconfig.json +20 -13
- package/.eslintrc.cjs +0 -8
- package/.github/FUNDING.yml +0 -2
- package/.github/workflows/build-linux.yml +0 -109
- package/.github/workflows/build-mac-m1.yml +0 -38
- package/.github/workflows/build-mac-x64.yml +0 -40
- package/.github/workflows/build-win.yml +0 -74
- package/.github/workflows/lint.yml +0 -20
- package/.github/workflows/npm-publish-manual.yml +0 -23
- package/.prettierrc.cjs +0 -8
- package/build-containers/Dockerfile.alpine +0 -6
- package/build-containers/Dockerfile.debian +0 -7
- package/cmake/toolchain/ci.cmake +0 -23
- package/examples/client-server/README.md +0 -22
- package/examples/client-server/client-benchmark.js +0 -230
- package/examples/client-server/client-periodic.js +0 -189
- package/examples/client-server/client.js +0 -111
- package/examples/client-server/package-lock.json +0 -289
- package/examples/client-server/package.json +0 -16
- package/examples/client-server/signaling-server.js +0 -39
- package/examples/electron-demo/README.md +0 -58
- package/examples/electron-demo/forge.config.js +0 -49
- package/examples/electron-demo/package-lock.json +0 -15877
- package/examples/electron-demo/package.json +0 -44
- package/examples/electron-demo/src/index.css +0 -7
- package/examples/electron-demo/src/index.html +0 -29
- package/examples/electron-demo/src/main.js +0 -53
- package/examples/electron-demo/src/node-datachannel.js +0 -123
- package/examples/electron-demo/src/preload.js +0 -28
- package/examples/electron-demo/src/renderer.js +0 -58
- package/examples/electron-demo/webpack.main.config.js +0 -21
- package/examples/electron-demo/webpack.renderer.config.js +0 -13
- package/examples/electron-demo/webpack.rules.js +0 -35
- package/examples/media/README.md +0 -34
- package/examples/media/main.html +0 -45
- package/examples/media/media.js +0 -54
- package/examples/simple-peer-usage/main.js +0 -28
- package/examples/simple-peer-usage/package-lock.json +0 -317
- package/examples/simple-peer-usage/package.json +0 -16
- package/examples/websocket/websocket-client.js +0 -20
- package/examples/websocket/websocket-server.js +0 -22
- package/jest.config.cjs +0 -7
- package/lib/index.cjs +0 -194
- package/lib/index.d.cts +0 -300
- package/lib/index.d.ts +0 -300
- package/lib/index.js +0 -58
- package/lib/node-datachannel.js +0 -7
- package/polyfill/Events.d.ts +0 -9
- package/polyfill/Events.js +0 -29
- package/polyfill/Exception.js +0 -23
- package/polyfill/RTCCertificate.d.ts +0 -7
- package/polyfill/RTCCertificate.js +0 -17
- package/polyfill/RTCDataChannel.d.ts +0 -35
- package/polyfill/RTCDtlsTransport.d.ts +0 -10
- package/polyfill/RTCDtlsTransport.js +0 -47
- package/polyfill/RTCError.d.ts +0 -11
- package/polyfill/RTCError.js +0 -65
- package/polyfill/RTCIceCandidate.d.ts +0 -20
- package/polyfill/RTCIceTransport.d.ts +0 -18
- package/polyfill/RTCPeerConnection.d.ts +0 -62
- package/polyfill/RTCSctpTransport.d.ts +0 -10
- package/polyfill/RTCSessionDescription.d.ts +0 -8
- package/polyfill/index.cjs +0 -1333
- package/polyfill/index.d.cts +0 -37
- package/test/connectivity.js +0 -86
- package/test/jest-tests/basic.test.js +0 -37
- package/test/jest-tests/multiple-run.test.js +0 -73
- package/test/jest-tests/p2p.test.js +0 -99
- package/test/jest-tests/polyfill.test.js +0 -10
- package/test/jest-tests/streams.test.js +0 -48
- package/test/jest-tests/websocket.test.js +0 -69
- package/test/polyfill-connectivity.js +0 -89
- package/test/websockets.js +0 -50
- package/test/wpt-tests/README.md +0 -46
- package/test/wpt-tests/chrome-failed-tests.js +0 -42
- package/test/wpt-tests/index.js +0 -96
- package/test/wpt-tests/last-test-results.md +0 -301
- package/test/wpt-tests/package-lock.json +0 -1712
- package/test/wpt-tests/package.json +0 -19
- package/test/wpt-tests/wpt-test-list.js +0 -139
- package/test/wpt-tests/wpt.js +0 -131
- /package/src/{data-channel-wrapper.cpp → cpp/data-channel-wrapper.cpp} +0 -0
- /package/src/{data-channel-wrapper.h → cpp/data-channel-wrapper.h} +0 -0
- /package/src/{main.cpp → cpp/main.cpp} +0 -0
- /package/src/{media-audio-wrapper.cpp → cpp/media-audio-wrapper.cpp} +0 -0
- /package/src/{media-audio-wrapper.h → cpp/media-audio-wrapper.h} +0 -0
- /package/src/{media-direction.cpp → cpp/media-direction.cpp} +0 -0
- /package/src/{media-direction.h → cpp/media-direction.h} +0 -0
- /package/src/{media-rtcpreceivingsession-wrapper.cpp → cpp/media-rtcpreceivingsession-wrapper.cpp} +0 -0
- /package/src/{media-rtcpreceivingsession-wrapper.h → cpp/media-rtcpreceivingsession-wrapper.h} +0 -0
- /package/src/{media-track-wrapper.cpp → cpp/media-track-wrapper.cpp} +0 -0
- /package/src/{media-track-wrapper.h → cpp/media-track-wrapper.h} +0 -0
- /package/src/{media-video-wrapper.cpp → cpp/media-video-wrapper.cpp} +0 -0
- /package/src/{media-video-wrapper.h → cpp/media-video-wrapper.h} +0 -0
- /package/src/{peer-connection-wrapper.cpp → cpp/peer-connection-wrapper.cpp} +0 -0
- /package/src/{peer-connection-wrapper.h → cpp/peer-connection-wrapper.h} +0 -0
- /package/src/{rtc-wrapper.cpp → cpp/rtc-wrapper.cpp} +0 -0
- /package/src/{rtc-wrapper.h → cpp/rtc-wrapper.h} +0 -0
- /package/src/{thread-safe-callback.cpp → cpp/thread-safe-callback.cpp} +0 -0
- /package/src/{thread-safe-callback.h → cpp/thread-safe-callback.h} +0 -0
- /package/src/{web-socket-server-wrapper.cpp → cpp/web-socket-server-wrapper.cpp} +0 -0
- /package/src/{web-socket-server-wrapper.h → cpp/web-socket-server-wrapper.h} +0 -0
- /package/src/{web-socket-wrapper.cpp → cpp/web-socket-wrapper.cpp} +0 -0
- /package/src/{web-socket-wrapper.h → cpp/web-socket-wrapper.h} +0 -0
- /package/{polyfill → src/polyfill}/README.md +0 -0
package/polyfill/index.cjs
DELETED
|
@@ -1,1333 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
-
|
|
5
|
-
require('node-domexception');
|
|
6
|
-
var module$1 = require('module');
|
|
7
|
-
var stream = require('stream');
|
|
8
|
-
var events = require('events');
|
|
9
|
-
|
|
10
|
-
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
11
|
-
class RTCCertificate {
|
|
12
|
-
#expires;
|
|
13
|
-
#fingerprints;
|
|
14
|
-
|
|
15
|
-
constructor() {
|
|
16
|
-
this.#expires = null;
|
|
17
|
-
this.#fingerprints = [];
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
get expires() {
|
|
21
|
-
return this.#expires;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
getFingerprints() {
|
|
25
|
-
return this.#fingerprints;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
const InvalidStateError = (msg) => {
|
|
30
|
-
return new DOMException(msg, 'InvalidStateError');
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
const InvalidAccessError = (msg) => {
|
|
34
|
-
return new DOMException(msg, 'InvalidAccessError');
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
const NotFoundError = (msg) => {
|
|
38
|
-
return new DOMException(msg, 'NotFoundError');
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
const OperationError = (msg) => {
|
|
42
|
-
return new DOMException(msg, 'OperationError');
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
const SyntaxError = (msg) => {
|
|
46
|
-
return new DOMException(msg, 'SyntaxError');
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
class _RTCDataChannel extends EventTarget {
|
|
50
|
-
#dataChannel;
|
|
51
|
-
#readyState;
|
|
52
|
-
#bufferedAmountLowThreshold;
|
|
53
|
-
#binaryType;
|
|
54
|
-
#maxPacketLifeTime;
|
|
55
|
-
#maxRetransmits;
|
|
56
|
-
#negotiated;
|
|
57
|
-
#ordered;
|
|
58
|
-
|
|
59
|
-
#closeRequested = false;
|
|
60
|
-
|
|
61
|
-
onbufferedamountlow;
|
|
62
|
-
onclose;
|
|
63
|
-
onclosing;
|
|
64
|
-
onerror;
|
|
65
|
-
onmessage;
|
|
66
|
-
onopen;
|
|
67
|
-
|
|
68
|
-
constructor(dataChannel, opts = {}) {
|
|
69
|
-
super();
|
|
70
|
-
|
|
71
|
-
this.#dataChannel = dataChannel;
|
|
72
|
-
this.#binaryType = 'arraybuffer';
|
|
73
|
-
this.#readyState = this.#dataChannel.isOpen() ? 'open' : 'connecting';
|
|
74
|
-
this.#bufferedAmountLowThreshold = 0;
|
|
75
|
-
this.#maxPacketLifeTime = opts.maxPacketLifeTime || null;
|
|
76
|
-
this.#maxRetransmits = opts.maxRetransmits || null;
|
|
77
|
-
this.#negotiated = opts.negotiated || false;
|
|
78
|
-
this.#ordered = opts.ordered || true;
|
|
79
|
-
|
|
80
|
-
// forward dataChannel events
|
|
81
|
-
this.#dataChannel.onOpen(() => {
|
|
82
|
-
this.#readyState = 'open';
|
|
83
|
-
this.dispatchEvent(new Event('open', { channel: this }));
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
this.#dataChannel.onClosed(() => {
|
|
87
|
-
// Simulate closing event
|
|
88
|
-
if (!this.#closeRequested) {
|
|
89
|
-
this.#readyState = 'closing';
|
|
90
|
-
this.dispatchEvent(new Event('closing', { channel: this }));
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
setImmediate(() => {
|
|
94
|
-
this.#readyState = 'closed';
|
|
95
|
-
this.dispatchEvent(new Event('close', { channel: this }));
|
|
96
|
-
});
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
this.#dataChannel.onError((msg) => {
|
|
100
|
-
this.dispatchEvent(
|
|
101
|
-
new RTCErrorEvent('error', {
|
|
102
|
-
error: new RTCError(
|
|
103
|
-
{
|
|
104
|
-
errorDetail: 'data-channel-failure',
|
|
105
|
-
},
|
|
106
|
-
msg,
|
|
107
|
-
),
|
|
108
|
-
}),
|
|
109
|
-
);
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
this.#dataChannel.onBufferedAmountLow(() => {
|
|
113
|
-
this.dispatchEvent(new Event('bufferedamountlow', { channel: this }));
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
this.#dataChannel.onMessage((data) => {
|
|
117
|
-
if (ArrayBuffer.isView(data)) {
|
|
118
|
-
data = data.buffer;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
this.dispatchEvent(new MessageEvent('message', { data, channel: this }));
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
// forward events to properties
|
|
125
|
-
this.addEventListener('message', (e) => {
|
|
126
|
-
if (this.onmessage) this.onmessage(e);
|
|
127
|
-
});
|
|
128
|
-
this.addEventListener('bufferedamountlow', (e) => {
|
|
129
|
-
if (this.onbufferedamountlow) this.onbufferedamountlow(e);
|
|
130
|
-
});
|
|
131
|
-
this.addEventListener('error', (e) => {
|
|
132
|
-
if (this.onerror) this.onerror(e);
|
|
133
|
-
});
|
|
134
|
-
this.addEventListener('close', (e) => {
|
|
135
|
-
if (this.onclose) this.onclose(e);
|
|
136
|
-
});
|
|
137
|
-
this.addEventListener('closing', (e) => {
|
|
138
|
-
if (this.onclosing) this.onclosing(e);
|
|
139
|
-
});
|
|
140
|
-
this.addEventListener('open', (e) => {
|
|
141
|
-
if (this.onopen) this.onopen(e);
|
|
142
|
-
});
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
set binaryType(type) {
|
|
146
|
-
if (type !== 'blob' && type !== 'arraybuffer') {
|
|
147
|
-
throw new DOMException(
|
|
148
|
-
"Failed to set the 'binaryType' property on 'RTCDataChannel': Unknown binary type : " + type,
|
|
149
|
-
'TypeMismatchError',
|
|
150
|
-
);
|
|
151
|
-
}
|
|
152
|
-
this.#binaryType = type;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
get binaryType() {
|
|
156
|
-
return this.#binaryType;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
get bufferedAmount() {
|
|
160
|
-
return this.#dataChannel.bufferedAmount();
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
get bufferedAmountLowThreshold() {
|
|
164
|
-
return this.#bufferedAmountLowThreshold;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
set bufferedAmountLowThreshold(value) {
|
|
168
|
-
const number = Number(value) || 0;
|
|
169
|
-
this.#bufferedAmountLowThreshold = number;
|
|
170
|
-
this.#dataChannel.setBufferedAmountLowThreshold(number);
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
get id() {
|
|
174
|
-
return this.#dataChannel.getId();
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
get label() {
|
|
178
|
-
return this.#dataChannel.getLabel();
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
get maxPacketLifeTime() {
|
|
182
|
-
return this.#maxPacketLifeTime;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
get maxRetransmits() {
|
|
186
|
-
return this.#maxRetransmits;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
get negotiated() {
|
|
190
|
-
return this.#negotiated;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
get ordered() {
|
|
194
|
-
return this.#ordered;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
get protocol() {
|
|
198
|
-
return this.#dataChannel.getProtocol();
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
get readyState() {
|
|
202
|
-
return this.#readyState;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
send(data) {
|
|
206
|
-
if (this.#readyState !== 'open') {
|
|
207
|
-
throw InvalidStateError(
|
|
208
|
-
"Failed to execute 'send' on 'RTCDataChannel': RTCDataChannel.readyState is not 'open'",
|
|
209
|
-
);
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
// Needs network error, type error implemented
|
|
213
|
-
if (typeof data === 'string') {
|
|
214
|
-
this.#dataChannel.sendMessage(data);
|
|
215
|
-
} else if (data instanceof Blob) {
|
|
216
|
-
data.arrayBuffer().then((ab) => {
|
|
217
|
-
this.#dataChannel.sendMessageBinary(new Uint8Array(ab));
|
|
218
|
-
});
|
|
219
|
-
} else {
|
|
220
|
-
this.#dataChannel.sendMessageBinary(new Uint8Array(data));
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
close() {
|
|
225
|
-
this.#closeRequested = true;
|
|
226
|
-
this.#dataChannel.close();
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
// https://developer.mozilla.org/docs/Web/API/RTCIceCandidate
|
|
231
|
-
//
|
|
232
|
-
// Example: candidate:123456 1 UDP 123456 192.168.1.1 12345 typ host raddr=10.0.0.1 rport=54321 generation 0
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
class _RTCIceCandidate {
|
|
236
|
-
#address;
|
|
237
|
-
#candidate;
|
|
238
|
-
#component;
|
|
239
|
-
#foundation;
|
|
240
|
-
#port;
|
|
241
|
-
#priority;
|
|
242
|
-
#protocol;
|
|
243
|
-
#relatedAddress;
|
|
244
|
-
#relatedPort;
|
|
245
|
-
#sdpMLineIndex;
|
|
246
|
-
#sdpMid;
|
|
247
|
-
#tcpType;
|
|
248
|
-
#type;
|
|
249
|
-
#usernameFragment;
|
|
250
|
-
|
|
251
|
-
constructor({ candidate, sdpMLineIndex, sdpMid, usernameFragment }) {
|
|
252
|
-
if (sdpMLineIndex == null && sdpMid == null)
|
|
253
|
-
throw new TypeError('At least one of sdpMLineIndex or sdpMid must be specified');
|
|
254
|
-
|
|
255
|
-
this.#candidate = candidate === null ? 'null' : candidate ?? '';
|
|
256
|
-
this.#sdpMLineIndex = sdpMLineIndex ?? null;
|
|
257
|
-
this.#sdpMid = sdpMid ?? null;
|
|
258
|
-
this.#usernameFragment = usernameFragment ?? null;
|
|
259
|
-
|
|
260
|
-
if (candidate) {
|
|
261
|
-
const fields = candidate.split(' ');
|
|
262
|
-
this.#foundation = fields[0].replace('candidate:', ''); // remove text candidate:
|
|
263
|
-
this.#component = fields[1] == '1' ? 'rtp' : 'rtcp';
|
|
264
|
-
this.#protocol = fields[2];
|
|
265
|
-
this.#priority = parseInt(fields[3], 10);
|
|
266
|
-
this.#address = fields[4];
|
|
267
|
-
this.#port = parseInt(fields[5], 10);
|
|
268
|
-
this.#type = fields[7];
|
|
269
|
-
this.#tcpType = null;
|
|
270
|
-
this.#relatedAddress = null;
|
|
271
|
-
this.#relatedPort = null;
|
|
272
|
-
|
|
273
|
-
// Parse the candidate string to extract relatedPort and relatedAddress
|
|
274
|
-
for (let i = 8; i < fields.length; i++) {
|
|
275
|
-
const field = fields[i];
|
|
276
|
-
if (field === 'raddr') {
|
|
277
|
-
this.#relatedAddress = fields[i + 1];
|
|
278
|
-
} else if (field === 'rport') {
|
|
279
|
-
this.#relatedPort = parseInt(fields[i + 1], 10);
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
if (this.#protocol === 'tcp' && field === 'tcptype') {
|
|
283
|
-
this.#tcpType = fields[i + 1];
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
get address() {
|
|
290
|
-
return this.#address || null;
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
get candidate() {
|
|
294
|
-
return this.#candidate;
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
get component() {
|
|
298
|
-
return this.#component;
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
get foundation() {
|
|
302
|
-
return this.#foundation || null;
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
get port() {
|
|
306
|
-
return this.#port || null;
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
get priority() {
|
|
310
|
-
return this.#priority || null;
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
get protocol() {
|
|
314
|
-
return this.#protocol || null;
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
get relatedAddress() {
|
|
318
|
-
return this.#relatedAddress;
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
get relatedPort() {
|
|
322
|
-
return this.#relatedPort || null;
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
get sdpMLineIndex() {
|
|
326
|
-
return this.#sdpMLineIndex;
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
get sdpMid() {
|
|
330
|
-
return this.#sdpMid;
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
get tcpType() {
|
|
334
|
-
return this.#tcpType;
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
get type() {
|
|
338
|
-
return this.#type || null;
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
get usernameFragment() {
|
|
342
|
-
return this.#usernameFragment;
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
toJSON() {
|
|
346
|
-
return {
|
|
347
|
-
candidate: this.#candidate,
|
|
348
|
-
sdpMLineIndex: this.#sdpMLineIndex,
|
|
349
|
-
sdpMid: this.#sdpMid,
|
|
350
|
-
usernameFragment: this.#usernameFragment,
|
|
351
|
-
};
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
class _RTCIceTransport extends EventTarget {
|
|
356
|
-
#pc = null;
|
|
357
|
-
#extraFunctions = null;
|
|
358
|
-
|
|
359
|
-
ongatheringstatechange = null;
|
|
360
|
-
onselectedcandidatepairchange = null;
|
|
361
|
-
onstatechange = null;
|
|
362
|
-
|
|
363
|
-
constructor({ pc, extraFunctions }) {
|
|
364
|
-
super();
|
|
365
|
-
this.#pc = pc;
|
|
366
|
-
this.#extraFunctions = extraFunctions;
|
|
367
|
-
|
|
368
|
-
// forward peerConnection events
|
|
369
|
-
this.#pc.addEventListener('icegatheringstatechange', () => {
|
|
370
|
-
this.dispatchEvent(new Event('gatheringstatechange'));
|
|
371
|
-
});
|
|
372
|
-
this.#pc.addEventListener('iceconnectionstatechange', () => {
|
|
373
|
-
this.dispatchEvent(new Event('statechange'));
|
|
374
|
-
});
|
|
375
|
-
|
|
376
|
-
// forward events to properties
|
|
377
|
-
this.addEventListener('gatheringstatechange', (e) => {
|
|
378
|
-
if (this.ongatheringstatechange) this.ongatheringstatechange(e);
|
|
379
|
-
});
|
|
380
|
-
this.addEventListener('statechange', (e) => {
|
|
381
|
-
if (this.onstatechange) this.onstatechange(e);
|
|
382
|
-
});
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
get component() {
|
|
386
|
-
let cp = this.getSelectedCandidatePair();
|
|
387
|
-
if (!cp) return null;
|
|
388
|
-
return cp.local.component;
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
get gatheringState() {
|
|
392
|
-
return this.#pc ? this.#pc.iceGatheringState : 'new';
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
get role() {
|
|
396
|
-
return this.#pc.localDescription.type == 'offer' ? 'controlling' : 'controlled';
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
get state() {
|
|
400
|
-
return this.#pc ? this.#pc.iceConnectionState : 'new';
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
getLocalCandidates() {
|
|
404
|
-
return this.#pc ? this.#extraFunctions.localCandidates() : [];
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
getLocalParameters() {
|
|
408
|
-
/** */
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
getRemoteCandidates() {
|
|
412
|
-
return this.#pc ? this.#extraFunctions.remoteCandidates() : [];
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
getRemoteParameters() {
|
|
416
|
-
/** */
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
getSelectedCandidatePair() {
|
|
420
|
-
let cp = this.#extraFunctions.selectedCandidatePair();
|
|
421
|
-
if (!cp) return null;
|
|
422
|
-
return {
|
|
423
|
-
local: new _RTCIceCandidate({
|
|
424
|
-
candidate: cp.local.candidate,
|
|
425
|
-
sdpMid: cp.local.mid,
|
|
426
|
-
}),
|
|
427
|
-
remote: new _RTCIceCandidate({
|
|
428
|
-
candidate: cp.remote.candidate,
|
|
429
|
-
sdpMid: cp.remote.mid,
|
|
430
|
-
}),
|
|
431
|
-
};
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
class _RTCDtlsTransport extends EventTarget {
|
|
436
|
-
#pc = null;
|
|
437
|
-
#extraFunctions = null;
|
|
438
|
-
#iceTransport = null;
|
|
439
|
-
|
|
440
|
-
onerror = null;
|
|
441
|
-
onstatechange = null;
|
|
442
|
-
|
|
443
|
-
constructor({ pc, extraFunctions }) {
|
|
444
|
-
super();
|
|
445
|
-
this.#pc = pc;
|
|
446
|
-
this.#extraFunctions = extraFunctions;
|
|
447
|
-
|
|
448
|
-
this.#iceTransport = new _RTCIceTransport({ pc, extraFunctions });
|
|
449
|
-
|
|
450
|
-
// forward peerConnection events
|
|
451
|
-
this.#pc.addEventListener('connectionstatechange', () => {
|
|
452
|
-
this.dispatchEvent(new Event('statechange'));
|
|
453
|
-
});
|
|
454
|
-
|
|
455
|
-
// forward events to properties
|
|
456
|
-
this.addEventListener('statechange', (e) => {
|
|
457
|
-
if (this.onstatechange) this.onstatechange(e);
|
|
458
|
-
});
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
get iceTransport() {
|
|
462
|
-
return this.#iceTransport;
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
get state() {
|
|
466
|
-
// reduce state from new, connecting, connected, disconnected, failed, closed, unknown
|
|
467
|
-
// to RTCDtlsTRansport states new, connecting, connected, closed, failed
|
|
468
|
-
let state = this.#pc ? this.#pc.connectionState : 'new';
|
|
469
|
-
if (state === 'disconnected' || state === 'unknown') {
|
|
470
|
-
state = 'closed';
|
|
471
|
-
}
|
|
472
|
-
return state;
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
getRemoteCertificates() {
|
|
476
|
-
// TODO: implement
|
|
477
|
-
return new ArrayBuffer(0);
|
|
478
|
-
}
|
|
479
|
-
}
|
|
480
|
-
|
|
481
|
-
// createRequire is native in node version >= 12
|
|
482
|
-
const require$1 = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)));
|
|
483
|
-
|
|
484
|
-
const nodeDataChannel = require$1('../build/Release/node_datachannel.node');
|
|
485
|
-
|
|
486
|
-
/**
|
|
487
|
-
* Turns a node-datachannel DataChannel into a real Node.js stream, complete with buffering,
|
|
488
|
-
* backpressure (up to a point - if the buffer fills up, messages are dropped), and
|
|
489
|
-
* support for piping data elsewhere.
|
|
490
|
-
*
|
|
491
|
-
* Read & written data may be either UTF-8 strings or Buffers - this difference exists at
|
|
492
|
-
* the protocol level, and is preserved here throughout.
|
|
493
|
-
*/
|
|
494
|
-
class DataChannelStream extends stream.Duplex {
|
|
495
|
-
constructor(rawChannel, streamOptions) {
|
|
496
|
-
super({
|
|
497
|
-
allowHalfOpen: false, // Default to autoclose on end().
|
|
498
|
-
...streamOptions,
|
|
499
|
-
objectMode: true, // Preserve the string/buffer distinction (WebRTC treats them differently)
|
|
500
|
-
});
|
|
501
|
-
|
|
502
|
-
this._rawChannel = rawChannel;
|
|
503
|
-
this._readActive = true;
|
|
504
|
-
|
|
505
|
-
rawChannel.onMessage((msg) => {
|
|
506
|
-
if (!this._readActive) return; // If the buffer is full, drop messages.
|
|
507
|
-
|
|
508
|
-
// If the push is rejected, we pause reading until the next call to _read().
|
|
509
|
-
this._readActive = this.push(msg);
|
|
510
|
-
});
|
|
511
|
-
|
|
512
|
-
// When the DataChannel closes, the readable & writable ends close
|
|
513
|
-
rawChannel.onClosed(() => {
|
|
514
|
-
this.push(null);
|
|
515
|
-
this.destroy();
|
|
516
|
-
});
|
|
517
|
-
|
|
518
|
-
rawChannel.onError((errMsg) => {
|
|
519
|
-
this.destroy(new Error(`DataChannel error: ${errMsg}`));
|
|
520
|
-
});
|
|
521
|
-
|
|
522
|
-
// Buffer all writes until the DataChannel opens
|
|
523
|
-
if (!rawChannel.isOpen()) {
|
|
524
|
-
this.cork();
|
|
525
|
-
rawChannel.onOpen(() => this.uncork());
|
|
526
|
-
}
|
|
527
|
-
}
|
|
528
|
-
|
|
529
|
-
_read() {
|
|
530
|
-
// Stop dropping messages, if the buffer filling up meant we were doing so before.
|
|
531
|
-
this._readActive = true;
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
_write(chunk, encoding, callback) {
|
|
535
|
-
let sentOk;
|
|
536
|
-
|
|
537
|
-
try {
|
|
538
|
-
if (Buffer.isBuffer(chunk)) {
|
|
539
|
-
sentOk = this._rawChannel.sendMessageBinary(chunk);
|
|
540
|
-
} else if (typeof chunk === 'string') {
|
|
541
|
-
sentOk = this._rawChannel.sendMessage(chunk);
|
|
542
|
-
} else {
|
|
543
|
-
const typeName = chunk.constructor.name || typeof chunk;
|
|
544
|
-
throw new Error(`Cannot write ${typeName} to DataChannel stream`);
|
|
545
|
-
}
|
|
546
|
-
} catch (err) {
|
|
547
|
-
return callback(err);
|
|
548
|
-
}
|
|
549
|
-
|
|
550
|
-
if (sentOk) {
|
|
551
|
-
callback(null);
|
|
552
|
-
} else {
|
|
553
|
-
callback(new Error('Failed to write to DataChannel'));
|
|
554
|
-
}
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
_final(callback) {
|
|
558
|
-
if (!this.allowHalfOpen) this.destroy();
|
|
559
|
-
callback(null);
|
|
560
|
-
}
|
|
561
|
-
|
|
562
|
-
_destroy(maybeErr, callback) {
|
|
563
|
-
// When the stream is destroyed, we close the DataChannel.
|
|
564
|
-
this._rawChannel.close();
|
|
565
|
-
callback(maybeErr);
|
|
566
|
-
}
|
|
567
|
-
|
|
568
|
-
get label() {
|
|
569
|
-
return this._rawChannel.getLabel();
|
|
570
|
-
}
|
|
571
|
-
|
|
572
|
-
get id() {
|
|
573
|
-
return this._rawChannel.getId();
|
|
574
|
-
}
|
|
575
|
-
|
|
576
|
-
get protocol() {
|
|
577
|
-
return this._rawChannel.getProtocol();
|
|
578
|
-
}
|
|
579
|
-
}
|
|
580
|
-
|
|
581
|
-
class WebSocketServer extends events.EventEmitter {
|
|
582
|
-
#server;
|
|
583
|
-
#clients = [];
|
|
584
|
-
|
|
585
|
-
constructor(options) {
|
|
586
|
-
super();
|
|
587
|
-
this.#server = new nodeDataChannel.WebSocketServer(options);
|
|
588
|
-
|
|
589
|
-
this.#server.onClient((client) => {
|
|
590
|
-
this.emit('client', client);
|
|
591
|
-
this.#clients.push(client);
|
|
592
|
-
});
|
|
593
|
-
}
|
|
594
|
-
|
|
595
|
-
port() {
|
|
596
|
-
return this.#server?.port() || 0;
|
|
597
|
-
}
|
|
598
|
-
|
|
599
|
-
stop() {
|
|
600
|
-
this.#clients.forEach((client) => {
|
|
601
|
-
client?.close();
|
|
602
|
-
});
|
|
603
|
-
this.#server?.stop();
|
|
604
|
-
this.#server = null;
|
|
605
|
-
this.removeAllListeners();
|
|
606
|
-
}
|
|
607
|
-
|
|
608
|
-
onClient(cb) {
|
|
609
|
-
if (this.#server) this.on('client', cb);
|
|
610
|
-
}
|
|
611
|
-
}
|
|
612
|
-
|
|
613
|
-
const {
|
|
614
|
-
initLogger,
|
|
615
|
-
cleanup,
|
|
616
|
-
preload,
|
|
617
|
-
setSctpSettings,
|
|
618
|
-
RtcpReceivingSession,
|
|
619
|
-
Track,
|
|
620
|
-
Video,
|
|
621
|
-
Audio,
|
|
622
|
-
DataChannel,
|
|
623
|
-
PeerConnection,
|
|
624
|
-
WebSocket,
|
|
625
|
-
} = nodeDataChannel;
|
|
626
|
-
|
|
627
|
-
var NodeDataChannel = {
|
|
628
|
-
initLogger,
|
|
629
|
-
cleanup,
|
|
630
|
-
preload,
|
|
631
|
-
setSctpSettings,
|
|
632
|
-
RtcpReceivingSession,
|
|
633
|
-
Track,
|
|
634
|
-
Video,
|
|
635
|
-
Audio,
|
|
636
|
-
DataChannel,
|
|
637
|
-
PeerConnection,
|
|
638
|
-
WebSocket,
|
|
639
|
-
WebSocketServer,
|
|
640
|
-
DataChannelStream,
|
|
641
|
-
};
|
|
642
|
-
|
|
643
|
-
// https://developer.mozilla.org/docs/Web/API/RTCSessionDescription
|
|
644
|
-
//
|
|
645
|
-
// Example usage
|
|
646
|
-
// const init = {
|
|
647
|
-
// type: 'offer',
|
|
648
|
-
// 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'
|
|
649
|
-
// };
|
|
650
|
-
|
|
651
|
-
class _RTCSessionDescription {
|
|
652
|
-
#type;
|
|
653
|
-
#sdp;
|
|
654
|
-
|
|
655
|
-
constructor(init = {}) {
|
|
656
|
-
// Allow Empty Constructor
|
|
657
|
-
// if (!init || !init.type || !init.sdp) {
|
|
658
|
-
// throw new DOMException('Type and sdp properties are required.');
|
|
659
|
-
// }
|
|
660
|
-
|
|
661
|
-
this.#type = init ? init.type : null;
|
|
662
|
-
this.#sdp = init ? init.sdp : null;
|
|
663
|
-
}
|
|
664
|
-
|
|
665
|
-
get type() {
|
|
666
|
-
return this.#type;
|
|
667
|
-
}
|
|
668
|
-
|
|
669
|
-
get sdp() {
|
|
670
|
-
return this.#sdp;
|
|
671
|
-
}
|
|
672
|
-
|
|
673
|
-
toJSON() {
|
|
674
|
-
return {
|
|
675
|
-
sdp: this.#sdp,
|
|
676
|
-
type: this.#type,
|
|
677
|
-
};
|
|
678
|
-
}
|
|
679
|
-
}
|
|
680
|
-
|
|
681
|
-
class RTCPeerConnectionIceEvent extends Event {
|
|
682
|
-
#candidate;
|
|
683
|
-
|
|
684
|
-
constructor(candidate) {
|
|
685
|
-
super('icecandidate');
|
|
686
|
-
|
|
687
|
-
this.#candidate = candidate;
|
|
688
|
-
}
|
|
689
|
-
|
|
690
|
-
get candidate() {
|
|
691
|
-
return this.#candidate;
|
|
692
|
-
}
|
|
693
|
-
}
|
|
694
|
-
|
|
695
|
-
class RTCDataChannelEvent extends Event {
|
|
696
|
-
#channel;
|
|
697
|
-
|
|
698
|
-
constructor(type, eventInitDict) {
|
|
699
|
-
super(type);
|
|
700
|
-
|
|
701
|
-
if (type && !eventInitDict.channel) throw new TypeError('channel member is required');
|
|
702
|
-
|
|
703
|
-
this.#channel = eventInitDict?.channel;
|
|
704
|
-
}
|
|
705
|
-
|
|
706
|
-
get channel() {
|
|
707
|
-
return this.#channel;
|
|
708
|
-
}
|
|
709
|
-
}
|
|
710
|
-
|
|
711
|
-
class _RTCSctpTransport extends EventTarget {
|
|
712
|
-
#pc = null;
|
|
713
|
-
#extraFunctions = null;
|
|
714
|
-
#transport = null;
|
|
715
|
-
|
|
716
|
-
onstatechange = null;
|
|
717
|
-
|
|
718
|
-
constructor({ pc, extraFunctions }) {
|
|
719
|
-
super();
|
|
720
|
-
this.#pc = pc;
|
|
721
|
-
this.#extraFunctions = extraFunctions;
|
|
722
|
-
|
|
723
|
-
this.#transport = new _RTCDtlsTransport({ pc, extraFunctions });
|
|
724
|
-
|
|
725
|
-
// forward peerConnection events
|
|
726
|
-
this.#pc.addEventListener('connectionstatechange', () => {
|
|
727
|
-
this.dispatchEvent(new Event('statechange'));
|
|
728
|
-
});
|
|
729
|
-
|
|
730
|
-
// forward events to properties
|
|
731
|
-
this.addEventListener('statechange', (e) => {
|
|
732
|
-
if (this.onstatechange) this.onstatechange(e);
|
|
733
|
-
});
|
|
734
|
-
}
|
|
735
|
-
|
|
736
|
-
get maxChannels() {
|
|
737
|
-
if (this.state !== 'connected') return null;
|
|
738
|
-
return this.#pc ? this.#extraFunctions.maxDataChannelId() : 0;
|
|
739
|
-
}
|
|
740
|
-
|
|
741
|
-
get maxMessageSize() {
|
|
742
|
-
if (this.state !== 'connected') return null;
|
|
743
|
-
return this.#pc ? this.#extraFunctions.maxMessageSize() : 0;
|
|
744
|
-
}
|
|
745
|
-
|
|
746
|
-
get state() {
|
|
747
|
-
// reduce state from new, connecting, connected, disconnected, failed, closed, unknown
|
|
748
|
-
// to RTCSctpTransport states connecting, connected, closed
|
|
749
|
-
let state = this.#pc.connectionState;
|
|
750
|
-
if (state === 'new' || state === 'connecting') {
|
|
751
|
-
state = 'connecting';
|
|
752
|
-
} else if (state === 'disconnected' || state === 'failed' || state === 'closed' || state === 'unknown') {
|
|
753
|
-
state = 'closed';
|
|
754
|
-
}
|
|
755
|
-
return state;
|
|
756
|
-
}
|
|
757
|
-
|
|
758
|
-
get transport() {
|
|
759
|
-
return this.#transport;
|
|
760
|
-
}
|
|
761
|
-
}
|
|
762
|
-
|
|
763
|
-
class _RTCPeerConnection extends EventTarget {
|
|
764
|
-
static async generateCertificate() {
|
|
765
|
-
throw new DOMException('Not implemented');
|
|
766
|
-
}
|
|
767
|
-
|
|
768
|
-
#peerConnection;
|
|
769
|
-
#localOffer;
|
|
770
|
-
#localAnswer;
|
|
771
|
-
#dataChannels;
|
|
772
|
-
#dataChannelsClosed = 0;
|
|
773
|
-
#config;
|
|
774
|
-
#canTrickleIceCandidates;
|
|
775
|
-
#sctp;
|
|
776
|
-
|
|
777
|
-
#localCandidates = [];
|
|
778
|
-
#remoteCandidates = [];
|
|
779
|
-
|
|
780
|
-
onconnectionstatechange;
|
|
781
|
-
ondatachannel;
|
|
782
|
-
onicecandidate;
|
|
783
|
-
onicecandidateerror;
|
|
784
|
-
oniceconnectionstatechange;
|
|
785
|
-
onicegatheringstatechange;
|
|
786
|
-
onnegotiationneeded;
|
|
787
|
-
onsignalingstatechange;
|
|
788
|
-
ontrack;
|
|
789
|
-
|
|
790
|
-
_checkConfiguration(config) {
|
|
791
|
-
if (config && config.iceServers === undefined) config.iceServers = [];
|
|
792
|
-
if (config && config.iceTransportPolicy === undefined) config.iceTransportPolicy = 'all';
|
|
793
|
-
|
|
794
|
-
if (config?.iceServers === null) throw new TypeError('IceServers cannot be null');
|
|
795
|
-
|
|
796
|
-
// Check for all the properties of iceServers
|
|
797
|
-
if (Array.isArray(config?.iceServers)) {
|
|
798
|
-
for (let i = 0; i < config.iceServers.length; i++) {
|
|
799
|
-
if (config.iceServers[i] === null) throw new TypeError('IceServers cannot be null');
|
|
800
|
-
if (config.iceServers[i] === undefined) throw new TypeError('IceServers cannot be undefined');
|
|
801
|
-
if (Object.keys(config.iceServers[i]).length === 0) throw new TypeError('IceServers cannot be empty');
|
|
802
|
-
|
|
803
|
-
// If iceServers is string convert to array
|
|
804
|
-
if (typeof config.iceServers[i].urls === 'string')
|
|
805
|
-
config.iceServers[i].urls = [config.iceServers[i].urls];
|
|
806
|
-
|
|
807
|
-
// urls can not be empty
|
|
808
|
-
if (config.iceServers[i].urls?.some((url) => url == ''))
|
|
809
|
-
throw SyntaxError('IceServers urls cannot be empty');
|
|
810
|
-
|
|
811
|
-
// urls should be valid URLs and match the protocols "stun:|turn:|turns:"
|
|
812
|
-
if (
|
|
813
|
-
config.iceServers[i].urls?.some(
|
|
814
|
-
(url) => {
|
|
815
|
-
try {
|
|
816
|
-
const parsedURL = new URL(url);
|
|
817
|
-
|
|
818
|
-
return !/^(stun:|turn:|turns:)$/.test(parsedURL.protocol)
|
|
819
|
-
} catch (error) {
|
|
820
|
-
return true
|
|
821
|
-
}
|
|
822
|
-
},
|
|
823
|
-
)
|
|
824
|
-
)
|
|
825
|
-
throw SyntaxError('IceServers urls wrong format');
|
|
826
|
-
|
|
827
|
-
// If this is a turn server check for username and credential
|
|
828
|
-
if (config.iceServers[i].urls?.some((url) => url.startsWith('turn'))) {
|
|
829
|
-
if (!config.iceServers[i].username)
|
|
830
|
-
throw InvalidAccessError('IceServers username cannot be null');
|
|
831
|
-
if (!config.iceServers[i].credential)
|
|
832
|
-
throw InvalidAccessError('IceServers username cannot be undefined');
|
|
833
|
-
}
|
|
834
|
-
|
|
835
|
-
// length of urls can not be 0
|
|
836
|
-
if (config.iceServers[i].urls?.length === 0)
|
|
837
|
-
throw SyntaxError('IceServers urls cannot be empty');
|
|
838
|
-
}
|
|
839
|
-
}
|
|
840
|
-
|
|
841
|
-
if (
|
|
842
|
-
config &&
|
|
843
|
-
config.iceTransportPolicy &&
|
|
844
|
-
config.iceTransportPolicy !== 'all' &&
|
|
845
|
-
config.iceTransportPolicy !== 'relay'
|
|
846
|
-
)
|
|
847
|
-
throw new TypeError('IceTransportPolicy must be either "all" or "relay"');
|
|
848
|
-
}
|
|
849
|
-
|
|
850
|
-
setConfiguration(config) {
|
|
851
|
-
this._checkConfiguration(config);
|
|
852
|
-
this.#config = config;
|
|
853
|
-
}
|
|
854
|
-
|
|
855
|
-
constructor(config = { iceServers: [], iceTransportPolicy: 'all' }) {
|
|
856
|
-
super();
|
|
857
|
-
|
|
858
|
-
this._checkConfiguration(config);
|
|
859
|
-
this.#config = config;
|
|
860
|
-
this.#localOffer = createDeferredPromise();
|
|
861
|
-
this.#localAnswer = createDeferredPromise();
|
|
862
|
-
this.#dataChannels = new Set();
|
|
863
|
-
this.#canTrickleIceCandidates = null;
|
|
864
|
-
|
|
865
|
-
try {
|
|
866
|
-
this.#peerConnection = new NodeDataChannel.PeerConnection(
|
|
867
|
-
config?.peerIdentity ?? `peer-${getRandomString(7)}`,
|
|
868
|
-
{
|
|
869
|
-
...config,
|
|
870
|
-
iceServers:
|
|
871
|
-
config?.iceServers
|
|
872
|
-
?.map((server) => {
|
|
873
|
-
const urls = Array.isArray(server.urls) ? server.urls : [server.urls];
|
|
874
|
-
|
|
875
|
-
return urls.map((url) => {
|
|
876
|
-
if (server.username && server.credential) {
|
|
877
|
-
const [protocol, rest] = url.split(/:(.*)/);
|
|
878
|
-
return `${protocol}:${server.username}:${server.credential}@${rest}`;
|
|
879
|
-
}
|
|
880
|
-
return url;
|
|
881
|
-
});
|
|
882
|
-
})
|
|
883
|
-
.flat() ?? [],
|
|
884
|
-
},
|
|
885
|
-
);
|
|
886
|
-
} catch (error) {
|
|
887
|
-
if (!error || !error.message) throw NotFoundError('Unknown error');
|
|
888
|
-
throw SyntaxError(error.message);
|
|
889
|
-
}
|
|
890
|
-
|
|
891
|
-
// forward peerConnection events
|
|
892
|
-
this.#peerConnection.onStateChange(() => {
|
|
893
|
-
this.dispatchEvent(new Event('connectionstatechange'));
|
|
894
|
-
});
|
|
895
|
-
|
|
896
|
-
this.#peerConnection.onIceStateChange(() => {
|
|
897
|
-
this.dispatchEvent(new Event('iceconnectionstatechange'));
|
|
898
|
-
});
|
|
899
|
-
|
|
900
|
-
this.#peerConnection.onSignalingStateChange(() => {
|
|
901
|
-
this.dispatchEvent(new Event('signalingstatechange'));
|
|
902
|
-
});
|
|
903
|
-
|
|
904
|
-
this.#peerConnection.onGatheringStateChange(() => {
|
|
905
|
-
this.dispatchEvent(new Event('icegatheringstatechange'));
|
|
906
|
-
});
|
|
907
|
-
|
|
908
|
-
this.#peerConnection.onDataChannel((channel) => {
|
|
909
|
-
const dc = new _RTCDataChannel(channel);
|
|
910
|
-
this.#dataChannels.add(dc);
|
|
911
|
-
this.dispatchEvent(new RTCDataChannelEvent('datachannel', { channel: dc }));
|
|
912
|
-
});
|
|
913
|
-
|
|
914
|
-
this.#peerConnection.onLocalDescription((sdp, type) => {
|
|
915
|
-
if (type === 'offer') {
|
|
916
|
-
this.#localOffer.resolve({ sdp, type });
|
|
917
|
-
}
|
|
918
|
-
|
|
919
|
-
if (type === 'answer') {
|
|
920
|
-
this.#localAnswer.resolve({ sdp, type });
|
|
921
|
-
}
|
|
922
|
-
});
|
|
923
|
-
|
|
924
|
-
this.#peerConnection.onLocalCandidate((candidate, sdpMid) => {
|
|
925
|
-
if (sdpMid === 'unspec') {
|
|
926
|
-
this.#localAnswer.reject(new Error(`Invalid description type ${sdpMid}`));
|
|
927
|
-
return;
|
|
928
|
-
}
|
|
929
|
-
|
|
930
|
-
this.#localCandidates.push(new _RTCIceCandidate({ candidate, sdpMid }));
|
|
931
|
-
this.dispatchEvent(new RTCPeerConnectionIceEvent(new _RTCIceCandidate({ candidate, sdpMid })));
|
|
932
|
-
});
|
|
933
|
-
|
|
934
|
-
// forward events to properties
|
|
935
|
-
this.addEventListener('connectionstatechange', (e) => {
|
|
936
|
-
if (this.onconnectionstatechange) this.onconnectionstatechange(e);
|
|
937
|
-
});
|
|
938
|
-
this.addEventListener('signalingstatechange', (e) => {
|
|
939
|
-
if (this.onsignalingstatechange) this.onsignalingstatechange(e);
|
|
940
|
-
});
|
|
941
|
-
this.addEventListener('iceconnectionstatechange', (e) => {
|
|
942
|
-
if (this.oniceconnectionstatechange) this.oniceconnectionstatechange(e);
|
|
943
|
-
});
|
|
944
|
-
this.addEventListener('icegatheringstatechange', (e) => {
|
|
945
|
-
if (this.onicegatheringstatechange) this.onicegatheringstatechange(e);
|
|
946
|
-
});
|
|
947
|
-
this.addEventListener('datachannel', (e) => {
|
|
948
|
-
if (this.ondatachannel) this.ondatachannel(e);
|
|
949
|
-
});
|
|
950
|
-
this.addEventListener('icecandidate', (e) => {
|
|
951
|
-
if (this.onicecandidate) this.onicecandidate(e);
|
|
952
|
-
});
|
|
953
|
-
|
|
954
|
-
this.#sctp = new _RTCSctpTransport({
|
|
955
|
-
pc: this,
|
|
956
|
-
extraFunctions: {
|
|
957
|
-
maxDataChannelId: () => {
|
|
958
|
-
return this.#peerConnection.maxDataChannelId();
|
|
959
|
-
},
|
|
960
|
-
maxMessageSize: () => {
|
|
961
|
-
return this.#peerConnection.maxMessageSize();
|
|
962
|
-
},
|
|
963
|
-
localCandidates: () => {
|
|
964
|
-
return this.#localCandidates;
|
|
965
|
-
},
|
|
966
|
-
remoteCandidates: () => {
|
|
967
|
-
return this.#remoteCandidates;
|
|
968
|
-
},
|
|
969
|
-
selectedCandidatePair: () => {
|
|
970
|
-
return this.#peerConnection.getSelectedCandidatePair();
|
|
971
|
-
},
|
|
972
|
-
},
|
|
973
|
-
});
|
|
974
|
-
}
|
|
975
|
-
|
|
976
|
-
get canTrickleIceCandidates() {
|
|
977
|
-
return this.#canTrickleIceCandidates;
|
|
978
|
-
}
|
|
979
|
-
|
|
980
|
-
get connectionState() {
|
|
981
|
-
return this.#peerConnection.state();
|
|
982
|
-
}
|
|
983
|
-
|
|
984
|
-
get iceConnectionState() {
|
|
985
|
-
let state = this.#peerConnection.iceState();
|
|
986
|
-
// libdatachannel uses 'completed' instead of 'connected'
|
|
987
|
-
// see /webrtc/getstats.html
|
|
988
|
-
if (state == 'completed') state = 'connected';
|
|
989
|
-
return state;
|
|
990
|
-
}
|
|
991
|
-
|
|
992
|
-
get iceGatheringState() {
|
|
993
|
-
return this.#peerConnection.gatheringState();
|
|
994
|
-
}
|
|
995
|
-
|
|
996
|
-
get currentLocalDescription() {
|
|
997
|
-
return new _RTCSessionDescription(this.#peerConnection.localDescription());
|
|
998
|
-
}
|
|
999
|
-
|
|
1000
|
-
get currentRemoteDescription() {
|
|
1001
|
-
return new _RTCSessionDescription(this.#peerConnection.remoteDescription());
|
|
1002
|
-
}
|
|
1003
|
-
|
|
1004
|
-
get localDescription() {
|
|
1005
|
-
return new _RTCSessionDescription(this.#peerConnection.localDescription());
|
|
1006
|
-
}
|
|
1007
|
-
|
|
1008
|
-
get pendingLocalDescription() {
|
|
1009
|
-
return new _RTCSessionDescription(this.#peerConnection.localDescription());
|
|
1010
|
-
}
|
|
1011
|
-
|
|
1012
|
-
get pendingRemoteDescription() {
|
|
1013
|
-
return new _RTCSessionDescription(this.#peerConnection.remoteDescription());
|
|
1014
|
-
}
|
|
1015
|
-
|
|
1016
|
-
get remoteDescription() {
|
|
1017
|
-
return new _RTCSessionDescription(this.#peerConnection.remoteDescription());
|
|
1018
|
-
}
|
|
1019
|
-
|
|
1020
|
-
get sctp() {
|
|
1021
|
-
return this.#sctp;
|
|
1022
|
-
}
|
|
1023
|
-
|
|
1024
|
-
get signalingState() {
|
|
1025
|
-
return this.#peerConnection.signalingState();
|
|
1026
|
-
}
|
|
1027
|
-
|
|
1028
|
-
async addIceCandidate(candidate) {
|
|
1029
|
-
if (!candidate || !candidate.candidate) {
|
|
1030
|
-
return;
|
|
1031
|
-
}
|
|
1032
|
-
|
|
1033
|
-
if (candidate.sdpMid === null && candidate.sdpMLineIndex === null) {
|
|
1034
|
-
throw new TypeError('sdpMid must be set');
|
|
1035
|
-
}
|
|
1036
|
-
|
|
1037
|
-
if (candidate.sdpMid === undefined && candidate.sdpMLineIndex == undefined) {
|
|
1038
|
-
throw new TypeError('sdpMid must be set');
|
|
1039
|
-
}
|
|
1040
|
-
|
|
1041
|
-
// Reject if sdpMid format is not valid
|
|
1042
|
-
// ??
|
|
1043
|
-
if (candidate.sdpMid && candidate.sdpMid.length > 3) {
|
|
1044
|
-
// console.log(candidate.sdpMid);
|
|
1045
|
-
throw OperationError('Invalid sdpMid format');
|
|
1046
|
-
}
|
|
1047
|
-
|
|
1048
|
-
// We don't care about sdpMLineIndex, just for test
|
|
1049
|
-
if (!candidate.sdpMid && candidate.sdpMLineIndex > 1) {
|
|
1050
|
-
throw OperationError('This is only for test case.');
|
|
1051
|
-
}
|
|
1052
|
-
|
|
1053
|
-
try {
|
|
1054
|
-
this.#peerConnection.addRemoteCandidate(candidate.candidate, candidate.sdpMid || '0');
|
|
1055
|
-
this.#remoteCandidates.push(
|
|
1056
|
-
new _RTCIceCandidate({ candidate: candidate.candidate, sdpMid: candidate.sdpMid || '0' }),
|
|
1057
|
-
);
|
|
1058
|
-
} catch (error) {
|
|
1059
|
-
if (!error || !error.message) throw NotFoundError('Unknown error');
|
|
1060
|
-
|
|
1061
|
-
// Check error Message if contains specific message
|
|
1062
|
-
if (error.message.includes('remote candidate without remote description'))
|
|
1063
|
-
throw InvalidStateError(error.message);
|
|
1064
|
-
if (error.message.includes('Invalid candidate format')) throw OperationError(error.message);
|
|
1065
|
-
|
|
1066
|
-
throw NotFoundError(error.message);
|
|
1067
|
-
}
|
|
1068
|
-
}
|
|
1069
|
-
|
|
1070
|
-
addTrack(track, ...streams) {
|
|
1071
|
-
throw new DOMException('Not implemented');
|
|
1072
|
-
}
|
|
1073
|
-
|
|
1074
|
-
addTransceiver(trackOrKind, init) {
|
|
1075
|
-
throw new DOMException('Not implemented');
|
|
1076
|
-
}
|
|
1077
|
-
|
|
1078
|
-
close() {
|
|
1079
|
-
// close all channels before shutting down
|
|
1080
|
-
this.#dataChannels.forEach((channel) => {
|
|
1081
|
-
channel.close();
|
|
1082
|
-
this.#dataChannelsClosed++;
|
|
1083
|
-
});
|
|
1084
|
-
|
|
1085
|
-
this.#peerConnection.close();
|
|
1086
|
-
}
|
|
1087
|
-
|
|
1088
|
-
createAnswer() {
|
|
1089
|
-
return this.#localAnswer;
|
|
1090
|
-
}
|
|
1091
|
-
|
|
1092
|
-
createDataChannel(label, opts = {}) {
|
|
1093
|
-
const channel = this.#peerConnection.createDataChannel(label, opts);
|
|
1094
|
-
const dataChannel = new _RTCDataChannel(channel, opts);
|
|
1095
|
-
|
|
1096
|
-
// ensure we can close all channels when shutting down
|
|
1097
|
-
this.#dataChannels.add(dataChannel);
|
|
1098
|
-
dataChannel.addEventListener('close', () => {
|
|
1099
|
-
this.#dataChannels.delete(dataChannel);
|
|
1100
|
-
this.#dataChannelsClosed++;
|
|
1101
|
-
});
|
|
1102
|
-
|
|
1103
|
-
return dataChannel;
|
|
1104
|
-
}
|
|
1105
|
-
|
|
1106
|
-
createOffer() {
|
|
1107
|
-
return this.#localOffer;
|
|
1108
|
-
}
|
|
1109
|
-
|
|
1110
|
-
getConfiguration() {
|
|
1111
|
-
return this.#config;
|
|
1112
|
-
}
|
|
1113
|
-
|
|
1114
|
-
getReceivers() {
|
|
1115
|
-
throw new DOMException('Not implemented');
|
|
1116
|
-
}
|
|
1117
|
-
|
|
1118
|
-
getSenders() {
|
|
1119
|
-
throw new DOMException('Not implemented');
|
|
1120
|
-
}
|
|
1121
|
-
|
|
1122
|
-
getStats() {
|
|
1123
|
-
return new Promise((resolve) => {
|
|
1124
|
-
let report = new Map();
|
|
1125
|
-
let cp = this.#peerConnection.getSelectedCandidatePair();
|
|
1126
|
-
let bytesSent = this.#peerConnection.bytesSent();
|
|
1127
|
-
let bytesReceived = this.#peerConnection.bytesReceived();
|
|
1128
|
-
let rtt = this.#peerConnection.rtt();
|
|
1129
|
-
|
|
1130
|
-
let localIdRs = getRandomString(8);
|
|
1131
|
-
let localId = 'RTCIceCandidate_' + localIdRs;
|
|
1132
|
-
report.set(localId, {
|
|
1133
|
-
id: localId,
|
|
1134
|
-
type: 'local-candidate',
|
|
1135
|
-
timestamp: Date.now(),
|
|
1136
|
-
candidateType: cp.local.type,
|
|
1137
|
-
ip: cp.local.address,
|
|
1138
|
-
port: cp.local.port,
|
|
1139
|
-
});
|
|
1140
|
-
|
|
1141
|
-
let remoteIdRs = getRandomString(8);
|
|
1142
|
-
let remoteId = 'RTCIceCandidate_' + remoteIdRs;
|
|
1143
|
-
report.set(remoteId, {
|
|
1144
|
-
id: remoteId,
|
|
1145
|
-
type: 'remote-candidate',
|
|
1146
|
-
timestamp: Date.now(),
|
|
1147
|
-
candidateType: cp.remote.type,
|
|
1148
|
-
ip: cp.remote.address,
|
|
1149
|
-
port: cp.remote.port,
|
|
1150
|
-
});
|
|
1151
|
-
|
|
1152
|
-
let candidateId = 'RTCIceCandidatePair_' + localIdRs + '_' + remoteIdRs;
|
|
1153
|
-
report.set(candidateId, {
|
|
1154
|
-
id: candidateId,
|
|
1155
|
-
type: 'candidate-pair',
|
|
1156
|
-
timestamp: Date.now(),
|
|
1157
|
-
localCandidateId: localId,
|
|
1158
|
-
remoteCandidateId: remoteId,
|
|
1159
|
-
state: 'succeeded',
|
|
1160
|
-
nominated: true,
|
|
1161
|
-
writable: true,
|
|
1162
|
-
bytesSent: bytesSent,
|
|
1163
|
-
bytesReceived: bytesReceived,
|
|
1164
|
-
totalRoundTripTime: rtt,
|
|
1165
|
-
currentRoundTripTime: rtt,
|
|
1166
|
-
});
|
|
1167
|
-
|
|
1168
|
-
let transportId = 'RTCTransport_0_1';
|
|
1169
|
-
report.set(transportId, {
|
|
1170
|
-
id: transportId,
|
|
1171
|
-
timestamp: Date.now(),
|
|
1172
|
-
type: 'transport',
|
|
1173
|
-
bytesSent: bytesSent,
|
|
1174
|
-
bytesReceived: bytesReceived,
|
|
1175
|
-
dtlsState: 'connected',
|
|
1176
|
-
selectedCandidatePairId: candidateId,
|
|
1177
|
-
selectedCandidatePairChanges: 1,
|
|
1178
|
-
});
|
|
1179
|
-
|
|
1180
|
-
// peer-connection'
|
|
1181
|
-
report.set('P', {
|
|
1182
|
-
id: 'P',
|
|
1183
|
-
type: 'peer-connection',
|
|
1184
|
-
timestamp: Date.now(),
|
|
1185
|
-
dataChannelsOpened: this.#dataChannels.size,
|
|
1186
|
-
dataChannelsClosed: this.#dataChannelsClosed,
|
|
1187
|
-
});
|
|
1188
|
-
|
|
1189
|
-
return resolve(report);
|
|
1190
|
-
});
|
|
1191
|
-
}
|
|
1192
|
-
|
|
1193
|
-
getTransceivers() {
|
|
1194
|
-
return []; // throw new DOMException('Not implemented');
|
|
1195
|
-
}
|
|
1196
|
-
|
|
1197
|
-
removeTrack() {
|
|
1198
|
-
throw new DOMException('Not implemented');
|
|
1199
|
-
}
|
|
1200
|
-
|
|
1201
|
-
restartIce() {
|
|
1202
|
-
throw new DOMException('Not implemented');
|
|
1203
|
-
}
|
|
1204
|
-
|
|
1205
|
-
async setLocalDescription(description) {
|
|
1206
|
-
if (description?.type !== 'offer') {
|
|
1207
|
-
// any other type causes libdatachannel to throw
|
|
1208
|
-
return;
|
|
1209
|
-
}
|
|
1210
|
-
|
|
1211
|
-
this.#peerConnection.setLocalDescription(description?.type);
|
|
1212
|
-
}
|
|
1213
|
-
|
|
1214
|
-
async setRemoteDescription(description) {
|
|
1215
|
-
if (description.sdp == null) {
|
|
1216
|
-
throw new DOMException('Remote SDP must be set');
|
|
1217
|
-
}
|
|
1218
|
-
|
|
1219
|
-
this.#peerConnection.setRemoteDescription(description.sdp, description.type);
|
|
1220
|
-
}
|
|
1221
|
-
}
|
|
1222
|
-
|
|
1223
|
-
function createDeferredPromise() {
|
|
1224
|
-
let resolve, reject;
|
|
1225
|
-
|
|
1226
|
-
let promise = new Promise(function (_resolve, _reject) {
|
|
1227
|
-
resolve = _resolve;
|
|
1228
|
-
reject = _reject;
|
|
1229
|
-
});
|
|
1230
|
-
|
|
1231
|
-
promise.resolve = resolve;
|
|
1232
|
-
promise.reject = reject;
|
|
1233
|
-
return promise;
|
|
1234
|
-
}
|
|
1235
|
-
|
|
1236
|
-
function getRandomString(length) {
|
|
1237
|
-
return Math.random()
|
|
1238
|
-
.toString(36)
|
|
1239
|
-
.substring(2, 2 + length);
|
|
1240
|
-
}
|
|
1241
|
-
|
|
1242
|
-
let RTCError$1 = class RTCError extends DOMException {
|
|
1243
|
-
constructor(init, message = '') {
|
|
1244
|
-
super(message, 'OperationError');
|
|
1245
|
-
|
|
1246
|
-
if (!init || !init.errorDetail) throw new TypeError('Cannot construct RTCError, errorDetail is required');
|
|
1247
|
-
if (
|
|
1248
|
-
[
|
|
1249
|
-
'data-channel-failure',
|
|
1250
|
-
'dtls-failure',
|
|
1251
|
-
'fingerprint-failure',
|
|
1252
|
-
'hardware-encoder-error',
|
|
1253
|
-
'hardware-encoder-not-available',
|
|
1254
|
-
'sctp-failure',
|
|
1255
|
-
'sdp-syntax-error',
|
|
1256
|
-
].indexOf(init.errorDetail) === -1
|
|
1257
|
-
)
|
|
1258
|
-
throw new TypeError('Cannot construct RTCError, errorDetail is invalid');
|
|
1259
|
-
|
|
1260
|
-
this._errorDetail = init.errorDetail;
|
|
1261
|
-
this._receivedAlert = init.receivedAlert ?? null;
|
|
1262
|
-
this._sctpCauseCode = init.sctpCauseCode ?? null;
|
|
1263
|
-
this._sdpLineNumber = init.sdpLineNumber ?? null;
|
|
1264
|
-
this._sentAlert = init.sentAlert ?? null;
|
|
1265
|
-
}
|
|
1266
|
-
|
|
1267
|
-
get errorDetail() {
|
|
1268
|
-
return this._errorDetail;
|
|
1269
|
-
}
|
|
1270
|
-
|
|
1271
|
-
set errorDetail(value) {
|
|
1272
|
-
throw new TypeError('Cannot set errorDetail, it is read-only');
|
|
1273
|
-
}
|
|
1274
|
-
|
|
1275
|
-
get receivedAlert() {
|
|
1276
|
-
return this._receivedAlert;
|
|
1277
|
-
}
|
|
1278
|
-
|
|
1279
|
-
set receivedAlert(value) {
|
|
1280
|
-
throw new TypeError('Cannot set receivedAlert, it is read-only');
|
|
1281
|
-
}
|
|
1282
|
-
|
|
1283
|
-
get sctpCauseCode() {
|
|
1284
|
-
return this._sctpCauseCode;
|
|
1285
|
-
}
|
|
1286
|
-
|
|
1287
|
-
set sctpCauseCode(value) {
|
|
1288
|
-
throw new TypeError('Cannot set sctpCauseCode, it is read-only');
|
|
1289
|
-
}
|
|
1290
|
-
|
|
1291
|
-
get sdpLineNumber() {
|
|
1292
|
-
return this._sdpLineNumber;
|
|
1293
|
-
}
|
|
1294
|
-
|
|
1295
|
-
set sdpLineNumber(value) {
|
|
1296
|
-
throw new TypeError('Cannot set sdpLineNumber, it is read-only');
|
|
1297
|
-
}
|
|
1298
|
-
|
|
1299
|
-
get sentAlert() {
|
|
1300
|
-
return this._sentAlert;
|
|
1301
|
-
}
|
|
1302
|
-
|
|
1303
|
-
set sentAlert(value) {
|
|
1304
|
-
throw new TypeError('Cannot set sentAlert, it is read-only');
|
|
1305
|
-
}
|
|
1306
|
-
};
|
|
1307
|
-
|
|
1308
|
-
var index = {
|
|
1309
|
-
RTCCertificate,
|
|
1310
|
-
RTCDataChannel: _RTCDataChannel,
|
|
1311
|
-
RTCDtlsTransport: _RTCDtlsTransport,
|
|
1312
|
-
RTCIceCandidate: _RTCIceCandidate,
|
|
1313
|
-
RTCIceTransport: _RTCIceTransport,
|
|
1314
|
-
RTCPeerConnection: _RTCPeerConnection,
|
|
1315
|
-
RTCSctpTransport: _RTCSctpTransport,
|
|
1316
|
-
RTCSessionDescription: _RTCSessionDescription,
|
|
1317
|
-
RTCDataChannelEvent,
|
|
1318
|
-
RTCPeerConnectionIceEvent,
|
|
1319
|
-
RTCError: RTCError$1,
|
|
1320
|
-
};
|
|
1321
|
-
|
|
1322
|
-
exports.RTCCertificate = RTCCertificate;
|
|
1323
|
-
exports.RTCDataChannel = _RTCDataChannel;
|
|
1324
|
-
exports.RTCDataChannelEvent = RTCDataChannelEvent;
|
|
1325
|
-
exports.RTCDtlsTransport = _RTCDtlsTransport;
|
|
1326
|
-
exports.RTCError = RTCError$1;
|
|
1327
|
-
exports.RTCIceCandidate = _RTCIceCandidate;
|
|
1328
|
-
exports.RTCIceTransport = _RTCIceTransport;
|
|
1329
|
-
exports.RTCPeerConnection = _RTCPeerConnection;
|
|
1330
|
-
exports.RTCPeerConnectionIceEvent = RTCPeerConnectionIceEvent;
|
|
1331
|
-
exports.RTCSctpTransport = _RTCSctpTransport;
|
|
1332
|
-
exports.RTCSessionDescription = _RTCSessionDescription;
|
|
1333
|
-
exports.default = index;
|