@lng2004/node-datachannel 0.31.0-20251228

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 (171) hide show
  1. package/.clang-format +17 -0
  2. package/.editorconfig +12 -0
  3. package/.eslintignore +8 -0
  4. package/.eslintrc.json +27 -0
  5. package/.gitmodules +3 -0
  6. package/.prettierignore +7 -0
  7. package/.prettierrc +13 -0
  8. package/API.md +247 -0
  9. package/BULDING.md +33 -0
  10. package/CMakeLists.txt +134 -0
  11. package/LICENSE +373 -0
  12. package/README.md +130 -0
  13. package/dist/cjs/index.cjs +11 -0
  14. package/dist/cjs/index.cjs.map +1 -0
  15. package/dist/cjs/lib/datachannel-stream.cjs +101 -0
  16. package/dist/cjs/lib/datachannel-stream.cjs.map +1 -0
  17. package/dist/cjs/lib/index.cjs +88 -0
  18. package/dist/cjs/lib/index.cjs.map +1 -0
  19. package/dist/cjs/lib/node-datachannel.cjs +8 -0
  20. package/dist/cjs/lib/node-datachannel.cjs.map +1 -0
  21. package/dist/cjs/lib/websocket-server.cjs +45 -0
  22. package/dist/cjs/lib/websocket-server.cjs.map +1 -0
  23. package/dist/cjs/lib/websocket.cjs +8 -0
  24. package/dist/cjs/lib/websocket.cjs.map +1 -0
  25. package/dist/cjs/polyfill/Events.cjs +86 -0
  26. package/dist/cjs/polyfill/Events.cjs.map +1 -0
  27. package/dist/cjs/polyfill/Exception.cjs +34 -0
  28. package/dist/cjs/polyfill/Exception.cjs.map +1 -0
  29. package/dist/cjs/polyfill/RTCCertificate.cjs +34 -0
  30. package/dist/cjs/polyfill/RTCCertificate.cjs.map +1 -0
  31. package/dist/cjs/polyfill/RTCDataChannel.cjs +214 -0
  32. package/dist/cjs/polyfill/RTCDataChannel.cjs.map +1 -0
  33. package/dist/cjs/polyfill/RTCDtlsTransport.cjs +53 -0
  34. package/dist/cjs/polyfill/RTCDtlsTransport.cjs.map +1 -0
  35. package/dist/cjs/polyfill/RTCError.cjs +83 -0
  36. package/dist/cjs/polyfill/RTCError.cjs.map +1 -0
  37. package/dist/cjs/polyfill/RTCIceCandidate.cjs +132 -0
  38. package/dist/cjs/polyfill/RTCIceCandidate.cjs.map +1 -0
  39. package/dist/cjs/polyfill/RTCIceTransport.cjs +94 -0
  40. package/dist/cjs/polyfill/RTCIceTransport.cjs.map +1 -0
  41. package/dist/cjs/polyfill/RTCPeerConnection.cjs +434 -0
  42. package/dist/cjs/polyfill/RTCPeerConnection.cjs.map +1 -0
  43. package/dist/cjs/polyfill/RTCSctpTransport.cjs +59 -0
  44. package/dist/cjs/polyfill/RTCSctpTransport.cjs.map +1 -0
  45. package/dist/cjs/polyfill/RTCSessionDescription.cjs +45 -0
  46. package/dist/cjs/polyfill/RTCSessionDescription.cjs.map +1 -0
  47. package/dist/cjs/polyfill/index.cjs +42 -0
  48. package/dist/cjs/polyfill/index.cjs.map +1 -0
  49. package/dist/esm/index.mjs +8 -0
  50. package/dist/esm/index.mjs.map +1 -0
  51. package/dist/esm/lib/datachannel-stream.mjs +78 -0
  52. package/dist/esm/lib/datachannel-stream.mjs.map +1 -0
  53. package/dist/esm/lib/index.mjs +62 -0
  54. package/dist/esm/lib/index.mjs.map +1 -0
  55. package/dist/esm/lib/node-datachannel.mjs +12 -0
  56. package/dist/esm/lib/node-datachannel.mjs.map +1 -0
  57. package/dist/esm/lib/websocket-server.mjs +43 -0
  58. package/dist/esm/lib/websocket-server.mjs.map +1 -0
  59. package/dist/esm/lib/websocket.mjs +6 -0
  60. package/dist/esm/lib/websocket.mjs.map +1 -0
  61. package/dist/esm/polyfill/Events.mjs +82 -0
  62. package/dist/esm/polyfill/Events.mjs.map +1 -0
  63. package/dist/esm/polyfill/Exception.mjs +28 -0
  64. package/dist/esm/polyfill/Exception.mjs.map +1 -0
  65. package/dist/esm/polyfill/RTCCertificate.mjs +30 -0
  66. package/dist/esm/polyfill/RTCCertificate.mjs.map +1 -0
  67. package/dist/esm/polyfill/RTCDataChannel.mjs +210 -0
  68. package/dist/esm/polyfill/RTCDataChannel.mjs.map +1 -0
  69. package/dist/esm/polyfill/RTCDtlsTransport.mjs +49 -0
  70. package/dist/esm/polyfill/RTCDtlsTransport.mjs.map +1 -0
  71. package/dist/esm/polyfill/RTCError.mjs +79 -0
  72. package/dist/esm/polyfill/RTCError.mjs.map +1 -0
  73. package/dist/esm/polyfill/RTCIceCandidate.mjs +128 -0
  74. package/dist/esm/polyfill/RTCIceCandidate.mjs.map +1 -0
  75. package/dist/esm/polyfill/RTCIceTransport.mjs +89 -0
  76. package/dist/esm/polyfill/RTCIceTransport.mjs.map +1 -0
  77. package/dist/esm/polyfill/RTCPeerConnection.mjs +430 -0
  78. package/dist/esm/polyfill/RTCPeerConnection.mjs.map +1 -0
  79. package/dist/esm/polyfill/RTCSctpTransport.mjs +55 -0
  80. package/dist/esm/polyfill/RTCSctpTransport.mjs.map +1 -0
  81. package/dist/esm/polyfill/RTCSessionDescription.mjs +41 -0
  82. package/dist/esm/polyfill/RTCSessionDescription.mjs.map +1 -0
  83. package/dist/esm/polyfill/index.mjs +27 -0
  84. package/dist/esm/polyfill/index.mjs.map +1 -0
  85. package/dist/types/lib/datachannel-stream.d.ts +24 -0
  86. package/dist/types/lib/index.d.ts +235 -0
  87. package/dist/types/lib/types.d.ts +118 -0
  88. package/dist/types/lib/websocket-server.d.ts +13 -0
  89. package/dist/types/lib/websocket.d.ts +25 -0
  90. package/dist/types/polyfill/Events.d.ts +15 -0
  91. package/dist/types/polyfill/RTCCertificate.d.ts +9 -0
  92. package/dist/types/polyfill/RTCDataChannel.d.ts +29 -0
  93. package/dist/types/polyfill/RTCDtlsTransport.d.ts +15 -0
  94. package/dist/types/polyfill/RTCError.d.ts +17 -0
  95. package/dist/types/polyfill/RTCIceCandidate.d.ts +21 -0
  96. package/dist/types/polyfill/RTCIceTransport.d.ts +30 -0
  97. package/dist/types/polyfill/RTCPeerConnection.d.ts +64 -0
  98. package/dist/types/polyfill/RTCSctpTransport.d.ts +15 -0
  99. package/dist/types/polyfill/RTCSessionDescription.d.ts +10 -0
  100. package/dist/types/polyfill/index.d.ts +26 -0
  101. package/jest.config.ts +14 -0
  102. package/package.json +121 -0
  103. package/rollup.config.mjs +72 -0
  104. package/src/cpp/data-channel-wrapper.cpp +530 -0
  105. package/src/cpp/data-channel-wrapper.h +63 -0
  106. package/src/cpp/ice-udp-mux-listener-wrapper.cpp +157 -0
  107. package/src/cpp/ice-udp-mux-listener-wrapper.h +43 -0
  108. package/src/cpp/main.cpp +58 -0
  109. package/src/cpp/media-audio-wrapper.cpp +457 -0
  110. package/src/cpp/media-audio-wrapper.h +52 -0
  111. package/src/cpp/media-av1packetization.cpp +24 -0
  112. package/src/cpp/media-av1packetization.h +11 -0
  113. package/src/cpp/media-av1rtppacketizer-wrapper.cpp +126 -0
  114. package/src/cpp/media-av1rtppacketizer-wrapper.h +29 -0
  115. package/src/cpp/media-direction.cpp +43 -0
  116. package/src/cpp/media-direction.h +10 -0
  117. package/src/cpp/media-h264rtppacketizer-wrapper.cpp +126 -0
  118. package/src/cpp/media-h264rtppacketizer-wrapper.h +30 -0
  119. package/src/cpp/media-h265rtppacketizer-wrapper.cpp +126 -0
  120. package/src/cpp/media-h265rtppacketizer-wrapper.h +30 -0
  121. package/src/cpp/media-h26xseparator.cpp +32 -0
  122. package/src/cpp/media-h26xseparator.h +11 -0
  123. package/src/cpp/media-mediahandler-helper.cpp +31 -0
  124. package/src/cpp/media-mediahandler-helper.h +11 -0
  125. package/src/cpp/media-pacinghandler-wrapper.cpp +79 -0
  126. package/src/cpp/media-pacinghandler-wrapper.h +28 -0
  127. package/src/cpp/media-rtcpnackresponder-wrapper.cpp +68 -0
  128. package/src/cpp/media-rtcpnackresponder-wrapper.h +28 -0
  129. package/src/cpp/media-rtcpreceivingsession-wrapper.cpp +57 -0
  130. package/src/cpp/media-rtcpreceivingsession-wrapper.h +28 -0
  131. package/src/cpp/media-rtcpsrreporter-wrapper.cpp +93 -0
  132. package/src/cpp/media-rtcpsrreporter-wrapper.h +30 -0
  133. package/src/cpp/media-rtppacketizationconfig-wrapper.cpp +167 -0
  134. package/src/cpp/media-rtppacketizationconfig-wrapper.h +35 -0
  135. package/src/cpp/media-rtppacketizer-wrapper.cpp +95 -0
  136. package/src/cpp/media-rtppacketizer-wrapper.h +30 -0
  137. package/src/cpp/media-track-wrapper.cpp +458 -0
  138. package/src/cpp/media-track-wrapper.h +61 -0
  139. package/src/cpp/media-video-wrapper.cpp +526 -0
  140. package/src/cpp/media-video-wrapper.h +56 -0
  141. package/src/cpp/peer-connection-wrapper.cpp +1298 -0
  142. package/src/cpp/peer-connection-wrapper.h +89 -0
  143. package/src/cpp/rtc-wrapper.cpp +205 -0
  144. package/src/cpp/rtc-wrapper.h +24 -0
  145. package/src/cpp/thread-safe-callback.cpp +57 -0
  146. package/src/cpp/thread-safe-callback.h +47 -0
  147. package/src/cpp/web-socket-server-wrapper.cpp +275 -0
  148. package/src/cpp/web-socket-server-wrapper.h +41 -0
  149. package/src/cpp/web-socket-wrapper.cpp +796 -0
  150. package/src/cpp/web-socket-wrapper.h +63 -0
  151. package/src/index.ts +9 -0
  152. package/src/lib/datachannel-stream.ts +100 -0
  153. package/src/lib/index.ts +283 -0
  154. package/src/lib/node-datachannel.ts +3 -0
  155. package/src/lib/types.ts +168 -0
  156. package/src/lib/websocket-server.ts +37 -0
  157. package/src/lib/websocket.ts +26 -0
  158. package/src/polyfill/Events.ts +82 -0
  159. package/src/polyfill/Exception.ts +37 -0
  160. package/src/polyfill/README.md +41 -0
  161. package/src/polyfill/RTCCertificate.ts +21 -0
  162. package/src/polyfill/RTCDataChannel.ts +225 -0
  163. package/src/polyfill/RTCDtlsTransport.ts +46 -0
  164. package/src/polyfill/RTCError.ts +78 -0
  165. package/src/polyfill/RTCIceCandidate.ts +128 -0
  166. package/src/polyfill/RTCIceTransport.ts +90 -0
  167. package/src/polyfill/RTCPeerConnection.ts +527 -0
  168. package/src/polyfill/RTCSctpTransport.ts +51 -0
  169. package/src/polyfill/RTCSessionDescription.ts +41 -0
  170. package/src/polyfill/index.ts +38 -0
  171. package/tsconfig.json +21 -0
@@ -0,0 +1,63 @@
1
+ #ifndef WEB_SOCKET_WRAPPER_H
2
+ #define WEB_SOCKET_WRAPPER_H
3
+
4
+ #include <memory>
5
+ #include <unordered_set>
6
+
7
+ #include <napi.h>
8
+ #include <rtc/rtc.hpp>
9
+
10
+ #include "thread-safe-callback.h"
11
+
12
+ class WebSocketWrapper : public Napi::ObjectWrap<WebSocketWrapper>
13
+ {
14
+ public:
15
+ static Napi::FunctionReference constructor;
16
+ static Napi::Object Init(Napi::Env env, Napi::Object exports);
17
+ WebSocketWrapper(const Napi::CallbackInfo &info);
18
+ ~WebSocketWrapper();
19
+
20
+ // Functions
21
+ void open(const Napi::CallbackInfo &info);
22
+ void close(const Napi::CallbackInfo &info);
23
+ void forceClose(const Napi::CallbackInfo &info);
24
+ Napi::Value sendMessage(const Napi::CallbackInfo &info);
25
+ Napi::Value sendMessageBinary(const Napi::CallbackInfo &info);
26
+ Napi::Value isOpen(const Napi::CallbackInfo &info);
27
+ Napi::Value bufferedAmount(const Napi::CallbackInfo &info);
28
+ Napi::Value maxMessageSize(const Napi::CallbackInfo &info);
29
+ void setBufferedAmountLowThreshold(const Napi::CallbackInfo &info);
30
+ Napi::Value remoteAddress(const Napi::CallbackInfo &info);
31
+ Napi::Value path(const Napi::CallbackInfo &info);
32
+
33
+ // Callbacks
34
+ void onOpen(const Napi::CallbackInfo &info);
35
+ void onClosed(const Napi::CallbackInfo &info);
36
+ void onError(const Napi::CallbackInfo &info);
37
+ void onBufferedAmountLow(const Napi::CallbackInfo &info);
38
+ void onMessage(const Napi::CallbackInfo &info);
39
+
40
+ // Close all existing WebSockets
41
+ static void CloseAll();
42
+
43
+ // Reset all Callbacks for existing WebSockets
44
+ static void CleanupAll();
45
+
46
+ private:
47
+ static std::unordered_set<WebSocketWrapper *> instances;
48
+
49
+ void doClose();
50
+ void doForceClose();
51
+ void doCleanup();
52
+
53
+ std::shared_ptr<rtc::WebSocket> mWebSocketPtr = nullptr;
54
+
55
+ // Callback Ptrs
56
+ std::unique_ptr<ThreadSafeCallback> mOnOpenCallback = nullptr;
57
+ std::unique_ptr<ThreadSafeCallback> mOnClosedCallback = nullptr;
58
+ std::unique_ptr<ThreadSafeCallback> mOnErrorCallback = nullptr;
59
+ std::unique_ptr<ThreadSafeCallback> mOnBufferedAmountLowCallback = nullptr;
60
+ std::unique_ptr<ThreadSafeCallback> mOnMessageCallback = nullptr;
61
+ };
62
+
63
+ #endif // WEB_SOCKET_WRAPPER_H
package/src/index.ts ADDED
@@ -0,0 +1,9 @@
1
+ // This file is created for builder process
2
+ // So builder can find and compile all files and folders
3
+ // Not intended to be imported directly
4
+
5
+ import n from './lib/index';
6
+ import p from './polyfill/index';
7
+
8
+ export const nodeDataChannel = n;
9
+ export const polyfill = p;
@@ -0,0 +1,100 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import * as stream from 'stream';
3
+
4
+ /**
5
+ * Turns a node-datachannel DataChannel into a real Node.js stream, complete with buffering,
6
+ * backpressure (up to a point - if the buffer fills up, messages are dropped), and
7
+ * support for piping data elsewhere.
8
+ *
9
+ * Read & written data may be either UTF-8 strings or Buffers - this difference exists at
10
+ * the protocol level, and is preserved here throughout.
11
+ */
12
+ export default class DataChannelStream extends stream.Duplex {
13
+ private _rawChannel: any;
14
+ private _readActive: boolean;
15
+
16
+ constructor(rawChannel: any, streamOptions?: Omit<stream.DuplexOptions, 'objectMode'>) {
17
+ super({
18
+ allowHalfOpen: false, // Default to autoclose on end().
19
+ ...streamOptions,
20
+ objectMode: true, // Preserve the string/buffer distinction (WebRTC treats them differently)
21
+ });
22
+
23
+ this._rawChannel = rawChannel;
24
+ this._readActive = true;
25
+
26
+ rawChannel.onMessage((msg: any) => {
27
+ if (!this._readActive) return; // If the buffer is full, drop messages.
28
+
29
+ // If the push is rejected, we pause reading until the next call to _read().
30
+ this._readActive = this.push(msg);
31
+ });
32
+
33
+ // When the DataChannel closes, the readable & writable ends close
34
+ rawChannel.onClosed(() => {
35
+ this.push(null);
36
+ this.destroy();
37
+ });
38
+
39
+ rawChannel.onError((errMsg: string) => {
40
+ this.destroy(new Error(`DataChannel error: ${errMsg}`));
41
+ });
42
+
43
+ // Buffer all writes until the DataChannel opens
44
+ if (!rawChannel.isOpen()) {
45
+ this.cork();
46
+ rawChannel.onOpen(() => this.uncork());
47
+ }
48
+ }
49
+
50
+ _read(): void {
51
+ // Stop dropping messages, if the buffer filling up meant we were doing so before.
52
+ this._readActive = true;
53
+ }
54
+
55
+ _write(chunk, _encoding, callback): void {
56
+ let sentOk;
57
+
58
+ try {
59
+ if (Buffer.isBuffer(chunk)) {
60
+ sentOk = this._rawChannel.sendMessageBinary(chunk);
61
+ } else if (typeof chunk === 'string') {
62
+ sentOk = this._rawChannel.sendMessage(chunk);
63
+ } else {
64
+ const typeName = chunk.constructor.name || typeof chunk;
65
+ throw new Error(`Cannot write ${typeName} to DataChannel stream`);
66
+ }
67
+ } catch (err) {
68
+ return callback(err);
69
+ }
70
+
71
+ if (sentOk) {
72
+ callback(null);
73
+ } else {
74
+ callback(new Error('Failed to write to DataChannel'));
75
+ }
76
+ }
77
+
78
+ _final(callback): void {
79
+ if (!this.allowHalfOpen) this.destroy();
80
+ callback(null);
81
+ }
82
+
83
+ _destroy(maybeErr, callback): void {
84
+ // When the stream is destroyed, we close the DataChannel.
85
+ this._rawChannel.close();
86
+ callback(maybeErr);
87
+ }
88
+
89
+ get label(): string {
90
+ return this._rawChannel.getLabel();
91
+ }
92
+
93
+ get id(): number {
94
+ return this._rawChannel.getId();
95
+ }
96
+
97
+ get protocol(): string {
98
+ return this._rawChannel.getProtocol();
99
+ }
100
+ }
@@ -0,0 +1,283 @@
1
+ import nodeDataChannel from './node-datachannel';
2
+ import _DataChannelStream from './datachannel-stream';
3
+ import { WebSocketServer } from './websocket-server';
4
+ import {
5
+ Channel,
6
+ DataChannelInitConfig,
7
+ DescriptionType,
8
+ Direction,
9
+ LogLevel,
10
+ NalUnitSeparator,
11
+ ObuPacketization,
12
+ RtcConfig,
13
+ RTCIceConnectionState,
14
+ RTCIceGatheringState,
15
+ RTCPeerConnectionState,
16
+ RTCSignalingState,
17
+ SctpSettings,
18
+ SelectedCandidateInfo,
19
+ } from './types';
20
+ import { WebSocket } from './websocket';
21
+ import type { CertificateFingerprint, IceUdpMuxRequest, LocalDescriptionInit } from './types';
22
+
23
+ export function preload(): void {
24
+ nodeDataChannel.preload();
25
+ }
26
+ export function initLogger(level: LogLevel): void {
27
+ nodeDataChannel.initLogger(level);
28
+ }
29
+ export function cleanup(): void {
30
+ nodeDataChannel.cleanup();
31
+ }
32
+ export function setSctpSettings(settings: SctpSettings): void {
33
+ nodeDataChannel.setSctpSettings(settings);
34
+ }
35
+ export function getLibraryVersion(): string {
36
+ return nodeDataChannel.getLibraryVersion();
37
+ }
38
+
39
+ export interface Audio {
40
+ addAudioCodec(payloadType: number, codec: string, profile?: string): void;
41
+ addOpusCodec(payloadType: number, profile?: string): string;
42
+ direction(): Direction;
43
+ generateSdp(eol: string, addr: string, port: number): string;
44
+ mid(): string;
45
+ setDirection(dir: Direction): void;
46
+ description(): string;
47
+ removeFormat(fmt: string): void;
48
+ addSSRC(ssrc: number, name?: string, msid?: string, trackID?: string): void;
49
+ removeSSRC(ssrc: number): void;
50
+ replaceSSRC(oldSsrc: number, ssrc: number, name?: string, msid?: string, trackID?: string): void;
51
+ hasSSRC(ssrc: number): boolean;
52
+ getSSRCs(): number[];
53
+ getCNameForSsrc(ssrc: number): string;
54
+ setBitrate(bitRate: number): void;
55
+ getBitrate(): number;
56
+ hasPayloadType(payloadType: number): boolean;
57
+ addRTXCodec(payloadType: number, originalPayloadType: number, clockRate: number): void;
58
+ addRTPMap(): void;
59
+ parseSdpLine(line: string): void;
60
+ }
61
+ export const Audio: {
62
+ new (mid: string, dir: Direction): Audio;
63
+ } = nodeDataChannel.Audio;
64
+
65
+ export interface Video {
66
+ addVideoCodec(payloadType: number, codec: string, profile?: string): void;
67
+ addH264Codec(payloadType: number, profile?: string): void;
68
+ addH265Codec(payloadType: number): void;
69
+ addVP8Codec(payloadType: number): void;
70
+ addVP9Codec(payloadType: number): void;
71
+ addAV1Codec(payloadType: number): void;
72
+ direction(): Direction;
73
+ generateSdp(eol: string, addr: string, port: number): string;
74
+ mid(): string;
75
+ setDirection(dir: Direction): void;
76
+ description(): string;
77
+ removeFormat(fmt: string): void;
78
+ addSSRC(ssrc: number, name?: string, msid?: string, trackID?: string): void;
79
+ removeSSRC(ssrc: number): void;
80
+ replaceSSRC(oldSsrc: number, ssrc: number, name?: string, msid?: string, trackID?: string): void;
81
+ hasSSRC(ssrc: number): boolean;
82
+ getSSRCs(): number[];
83
+ getCNameForSsrc(ssrc: number): string;
84
+ setBitrate(bitRate: number): void;
85
+ getBitrate(): number;
86
+ hasPayloadType(payloadType: number): boolean;
87
+ addRTXCodec(payloadType: number, originalPayloadType: number, clockRate: number): void;
88
+ addRTPMap(): void;
89
+ parseSdpLine(line: string): void;
90
+ }
91
+ export const Video: {
92
+ new (mid: string, dir: Direction): Video;
93
+ } = nodeDataChannel.Video;
94
+
95
+ export interface Track {
96
+ direction(): Direction;
97
+ mid(): string;
98
+ type(): string;
99
+ close(): void;
100
+ sendMessage(msg: string): boolean;
101
+ sendMessageBinary(buffer: Buffer): boolean;
102
+ isOpen(): boolean;
103
+ isClosed(): boolean;
104
+ bufferedAmount(): number;
105
+ maxMessageSize(): number;
106
+ requestBitrate(bitRate: number): boolean;
107
+ setBufferedAmountLowThreshold(newSize: number): void;
108
+ requestKeyframe(): boolean;
109
+ setMediaHandler(handler: MediaHandler): void;
110
+ onOpen(cb: () => void): void;
111
+ onClosed(cb: () => void): void;
112
+ onError(cb: (err: string) => void): void;
113
+ onMessage(cb: (msg: Buffer) => void): void;
114
+ }
115
+ export const Track: {
116
+ new (): Track;
117
+ } = nodeDataChannel.Track;
118
+
119
+ export interface DataChannel extends Channel {
120
+ getLabel(): string;
121
+ getId(): number;
122
+ getProtocol(): string;
123
+
124
+ // Channel implementation
125
+ close(): void;
126
+ sendMessage(msg: string): boolean;
127
+ sendMessageBinary(buffer: Buffer | Uint8Array): boolean;
128
+ isOpen(): boolean;
129
+ bufferedAmount(): number;
130
+ maxMessageSize(): number;
131
+ setBufferedAmountLowThreshold(newSize: number): void;
132
+ onOpen(cb: () => void): void;
133
+ onClosed(cb: () => void): void;
134
+ onError(cb: (err: string) => void): void;
135
+ onBufferedAmountLow(cb: () => void): void;
136
+ onMessage(cb: (msg: string | Buffer | ArrayBuffer) => void): void;
137
+ }
138
+ export const DataChannel: {
139
+ // DataChannel implementation
140
+ } = nodeDataChannel.DataChannel;
141
+
142
+ export interface PeerConnection {
143
+ close(): void;
144
+ setLocalDescription(type?: DescriptionType, init?: LocalDescriptionInit): void;
145
+ setRemoteDescription(sdp: string, type: DescriptionType): void;
146
+ localDescription(): { type: DescriptionType; sdp: string } | null;
147
+ remoteDescription(): { type: DescriptionType; sdp: string } | null;
148
+ remoteFingerprint(): CertificateFingerprint;
149
+ addRemoteCandidate(candidate: string, mid: string): void;
150
+ createDataChannel(label: string, config?: DataChannelInitConfig): DataChannel;
151
+ addTrack(media: Video | Audio): Track;
152
+ hasMedia(): boolean;
153
+ state(): RTCPeerConnectionState;
154
+ iceState(): RTCIceConnectionState;
155
+ signalingState(): RTCSignalingState;
156
+ gatheringState(): RTCIceGatheringState;
157
+ onLocalDescription(cb: (sdp: string, type: DescriptionType) => void): void;
158
+ onLocalCandidate(cb: (candidate: string, mid: string) => void): void;
159
+ onStateChange(cb: (state: string) => void): void;
160
+ onIceStateChange(cb: (state: string) => void): void;
161
+ onSignalingStateChange(cb: (state: string) => void): void;
162
+ onGatheringStateChange(cb: (state: string) => void): void;
163
+ onDataChannel(cb: (dc: DataChannel) => void): void;
164
+ onTrack(cb: (track: Track) => void): void;
165
+ bytesSent(): number;
166
+ bytesReceived(): number;
167
+ rtt(): number;
168
+ getSelectedCandidatePair(): {
169
+ local: SelectedCandidateInfo;
170
+ remote: SelectedCandidateInfo;
171
+ } | null;
172
+ maxDataChannelId(): number;
173
+ maxMessageSize(): number;
174
+ }
175
+ export const PeerConnection: {
176
+ new (peerName: string, config: RtcConfig): PeerConnection;
177
+ } = nodeDataChannel.PeerConnection;
178
+
179
+ export interface IceUdpMuxListener {
180
+ address?: string;
181
+ port: number;
182
+ stop(): void;
183
+ onUnhandledStunRequest(cb: (req: IceUdpMuxRequest) => void): void;
184
+ }
185
+ export const IceUdpMuxListener: {
186
+ new (port: number, address?: string): IceUdpMuxListener;
187
+ } = nodeDataChannel.IceUdpMuxListener;
188
+
189
+ export interface RtpPacketizationConfig {
190
+ playoutDelayId: number,
191
+ playoutDelayMin: number,
192
+ playoutDelayMax: number,
193
+ timestamp: number,
194
+ get clockRate(): number
195
+ }
196
+
197
+ export const RtpPacketizationConfig: {
198
+ new(ssrc: number, cname: string, payloadType: number, clockRate: number, videoOrientationId?: number): RtpPacketizationConfig
199
+ } = nodeDataChannel.RtpPacketizationConfig
200
+
201
+ export interface MediaHandler {
202
+ addToChain(handler: MediaHandler): void
203
+ }
204
+
205
+ export interface RtcpReceivingSession extends MediaHandler {}
206
+
207
+ export const RtcpReceivingSession: {
208
+ new (): RtcpReceivingSession;
209
+ } = nodeDataChannel.RtcpReceivingSession;
210
+
211
+ export interface RtcpNackResponder extends MediaHandler {}
212
+
213
+ export const RtcpNackResponder: {
214
+ new (maxSize?: number): RtcpNackResponder
215
+ } = nodeDataChannel.RtcpNackResponder;
216
+
217
+ export interface RtcpSrReporter extends MediaHandler {
218
+ get rtpConfig(): RtpPacketizationConfig
219
+ }
220
+
221
+ export const RtcpSrReporter: {
222
+ new (rtpConfig: RtpPacketizationConfig): RtcpSrReporter
223
+ } = nodeDataChannel.RtcpSrReporter;
224
+
225
+ export interface RtpPacketizer extends MediaHandler {
226
+ get rtpConfig(): RtpPacketizationConfig
227
+ }
228
+
229
+ export const RtpPacketizer: {
230
+ new (rtpConfig: RtpPacketizationConfig): RtpPacketizer
231
+ } = nodeDataChannel.RtpPacketizer;
232
+
233
+ export interface H264RtpPacketizer extends RtpPacketizer {}
234
+
235
+ export const H264RtpPacketizer: {
236
+ new (separator: NalUnitSeparator, rtpConfig: RtpPacketizationConfig, maxFragmentSize?: number): H264RtpPacketizer
237
+ } = nodeDataChannel.H264RtpPacketizer
238
+
239
+ export interface H265RtpPacketizer extends RtpPacketizer {}
240
+
241
+ export const H265RtpPacketizer: {
242
+ new (separator: NalUnitSeparator, rtpConfig: RtpPacketizationConfig, maxFragmentSize?: number): H265RtpPacketizer
243
+ } = nodeDataChannel.H265RtpPacketizer
244
+
245
+ export interface AV1RtpPacketizer extends RtpPacketizer {}
246
+
247
+ export const AV1RtpPacketizer: {
248
+ new (packetization: ObuPacketization, rtpConfig: RtpPacketizationConfig, maxFragmentSize?: number): AV1RtpPacketizer
249
+ } = nodeDataChannel.AV1RtpPacketizer
250
+
251
+ export { WebSocketServer } from './websocket-server';
252
+ export { WebSocket } from './websocket';
253
+
254
+ export const DataChannelStream = _DataChannelStream;
255
+
256
+ export default {
257
+ initLogger,
258
+ cleanup,
259
+ preload,
260
+ setSctpSettings,
261
+ getLibraryVersion,
262
+ RtcpReceivingSession,
263
+ RtcpNackResponder,
264
+ RtcpSrReporter,
265
+ RtpPacketizationConfig,
266
+ RtpPacketizer,
267
+ H264RtpPacketizer,
268
+ H265RtpPacketizer,
269
+ AV1RtpPacketizer,
270
+ Track,
271
+ Video,
272
+ Audio,
273
+ DataChannel,
274
+ PeerConnection,
275
+ WebSocket,
276
+ WebSocketServer,
277
+ DataChannelStream,
278
+ IceUdpMuxListener,
279
+ };
280
+
281
+ // Types
282
+ // https://github.com/murat-dogan/node-datachannel/issues/300
283
+ export * from './types';
@@ -0,0 +1,3 @@
1
+ // @ts-expect-error no types
2
+ import nodeDataChannel = require('../../build/Release/node_datachannel.node');
3
+ export default nodeDataChannel;
@@ -0,0 +1,168 @@
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 | ArrayBuffer) => 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 type RelayType = 'TurnUdp' | 'TurnTcp' | 'TurnTls';
51
+
52
+ export interface IceServer {
53
+ hostname: string;
54
+ port: number;
55
+ username?: string;
56
+ password?: string;
57
+ relayType?: RelayType;
58
+ }
59
+
60
+ export type TransportPolicy = 'all' | 'relay';
61
+
62
+ export interface RtcConfig {
63
+ iceServers: (string | IceServer)[];
64
+ proxyServer?: ProxyServer;
65
+ bindAddress?: string;
66
+ enableIceTcp?: boolean;
67
+ enableIceUdpMux?: boolean;
68
+ disableAutoNegotiation?: boolean;
69
+ forceMediaTransport?: boolean;
70
+ portRangeBegin?: number;
71
+ portRangeEnd?: number;
72
+ maxMessageSize?: number;
73
+ mtu?: number;
74
+ iceTransportPolicy?: TransportPolicy;
75
+ disableFingerprintVerification?: boolean;
76
+ disableAutoGathering?: boolean;
77
+ certificatePemFile?: string;
78
+ keyPemFile?: string;
79
+ keyPemPass?: string;
80
+ }
81
+
82
+ // Lowercase to match the description type string from libdatachannel
83
+ export type DescriptionType = 'unspec' | 'offer' | 'answer' | 'pranswer' | 'rollback';
84
+
85
+ export type RTCSdpType = 'answer' | 'offer' | 'pranswer' | 'rollback';
86
+
87
+ export type RTCIceTransportState =
88
+ | 'checking'
89
+ | 'closed'
90
+ | 'completed'
91
+ | 'connected'
92
+ | 'disconnected'
93
+ | 'failed'
94
+ | 'new';
95
+ export type RTCPeerConnectionState =
96
+ | 'closed'
97
+ | 'connected'
98
+ | 'connecting'
99
+ | 'disconnected'
100
+ | 'failed'
101
+ | 'new';
102
+ export type RTCIceConnectionState =
103
+ | 'checking'
104
+ | 'closed'
105
+ | 'completed'
106
+ | 'connected'
107
+ | 'disconnected'
108
+ | 'failed'
109
+ | 'new';
110
+ export type RTCIceGathererState = 'complete' | 'gathering' | 'new';
111
+ export type RTCIceGatheringState = 'complete' | 'gathering' | 'new';
112
+ export type RTCSignalingState =
113
+ | 'closed'
114
+ | 'have-local-offer'
115
+ | 'have-local-pranswer'
116
+ | 'have-remote-offer'
117
+ | 'have-remote-pranswer'
118
+ | 'stable';
119
+
120
+ export interface LocalDescriptionInit {
121
+ iceUfrag?: string;
122
+ icePwd?: string;
123
+ }
124
+
125
+ export interface DataChannelInitConfig {
126
+ protocol?: string;
127
+ negotiated?: boolean;
128
+ id?: number;
129
+ unordered?: boolean; // Reliability
130
+ maxPacketLifeTime?: number; // Reliability
131
+ maxRetransmits?: number; // Reliability
132
+ }
133
+
134
+ export interface CertificateFingerprint {
135
+ /**
136
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/RTCCertificate/getFingerprints#value
137
+ */
138
+ value: string;
139
+ /**
140
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/RTCCertificate/getFingerprints#algorithm
141
+ */
142
+ algorithm: 'sha-1' | 'sha-224' | 'sha-256' | 'sha-384' | 'sha-512' | 'md5' | 'md2';
143
+ }
144
+
145
+ export interface SelectedCandidateInfo {
146
+ address: string;
147
+ port: number;
148
+ type: string;
149
+ transportType: string;
150
+ candidate: string;
151
+ mid: string;
152
+ priority: number;
153
+ }
154
+
155
+ // Must be same as rtc enum class Direction
156
+ export type Direction = 'SendOnly' | 'RecvOnly' | 'SendRecv' | 'Inactive' | 'Unknown';
157
+
158
+ export interface IceUdpMuxRequest {
159
+ ufrag: string;
160
+ host: string;
161
+ port: number;
162
+ }
163
+
164
+ // Same as rtc::NalUnit::Separator
165
+ export type NalUnitSeparator = 'Length' | 'ShortStartSequence' | 'LongStartSequence' | 'StartSequence';
166
+
167
+ // Same as rtc::AV1RtpPacketizer::Packetization
168
+ export type ObuPacketization = 'Obu' | 'TemporalUnit';
@@ -0,0 +1,37 @@
1
+ import { EventEmitter } from 'events';
2
+ import nodeDataChannel from './node-datachannel';
3
+ import { WebSocketServerConfiguration } from './types';
4
+ import { WebSocket } from './websocket';
5
+
6
+ export class WebSocketServer extends EventEmitter {
7
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
8
+ #server: any;
9
+ #clients: WebSocket[] = [];
10
+
11
+ constructor(options: WebSocketServerConfiguration) {
12
+ super();
13
+ this.#server = new nodeDataChannel.WebSocketServer(options);
14
+
15
+ this.#server.onClient((client) => {
16
+ this.emit('client', client);
17
+ this.#clients.push(client);
18
+ });
19
+ }
20
+
21
+ port(): number {
22
+ return this.#server?.port() || 0;
23
+ }
24
+
25
+ stop(): void {
26
+ this.#clients.forEach((client) => {
27
+ client?.close();
28
+ });
29
+ this.#server?.stop();
30
+ this.#server = null;
31
+ this.removeAllListeners();
32
+ }
33
+
34
+ onClient(cb: (clientSocket: WebSocket) => void): void {
35
+ if (this.#server) this.on('client', cb);
36
+ }
37
+ }
@@ -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;