node-datachannel 0.32.3 → 0.33.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 (31) hide show
  1. package/BULDING.md +18 -25
  2. package/CMakeLists.txt +23 -9
  3. package/README.md +5 -6
  4. package/dist/cjs/lib/index.cjs.map +1 -1
  5. package/dist/cjs/lib/node-datachannel.cjs +87 -1
  6. package/dist/cjs/lib/node-datachannel.cjs.map +1 -1
  7. package/dist/esm/lib/index.mjs.map +1 -1
  8. package/dist/esm/lib/node-datachannel.mjs +67 -1
  9. package/dist/esm/lib/node-datachannel.mjs.map +1 -1
  10. package/dist/types/lib/index.d.ts +2 -2
  11. package/npm-artifacts/package-darwin-arm64/node_datachannel.node +0 -0
  12. package/npm-artifacts/package-darwin-arm64/package.json +20 -0
  13. package/npm-artifacts/package-darwin-x64/node_datachannel.node +0 -0
  14. package/npm-artifacts/package-darwin-x64/package.json +20 -0
  15. package/npm-artifacts/package-linux-arm64-gnu/node_datachannel.node +0 -0
  16. package/npm-artifacts/package-linux-arm64-gnu/package.json +23 -0
  17. package/npm-artifacts/package-linux-arm64-musl/node_datachannel.node +0 -0
  18. package/npm-artifacts/package-linux-arm64-musl/package.json +23 -0
  19. package/npm-artifacts/package-linux-x64-gnu/node_datachannel.node +0 -0
  20. package/npm-artifacts/package-linux-x64-gnu/package.json +23 -0
  21. package/npm-artifacts/package-linux-x64-musl/node_datachannel.node +0 -0
  22. package/npm-artifacts/package-linux-x64-musl/package.json +23 -0
  23. package/npm-artifacts/package-win32-arm64-msvc/node_datachannel.node +0 -0
  24. package/npm-artifacts/package-win32-arm64-msvc/package.json +20 -0
  25. package/npm-artifacts/package-win32-x64-msvc/node_datachannel.node +0 -0
  26. package/npm-artifacts/package-win32-x64-msvc/package.json +20 -0
  27. package/package.json +18 -9
  28. package/rollup.config.mjs +1 -6
  29. package/src/cpp/ice-udp-mux-listener-wrapper.cpp +16 -2
  30. package/src/lib/index.ts +2 -2
  31. package/src/lib/node-datachannel.ts +83 -2
package/BULDING.md CHANGED
@@ -6,28 +6,21 @@
6
6
  - [libdatachannel dependencies](https://github.com/paullouisageneau/libdatachannel/blob/master/README.md#dependencies)
7
7
 
8
8
  ## Building from source
9
-
10
- ```sh
11
- > git clone https://github.com/murat-dogan/node-datachannel.git
12
- > cd node-datachannel
13
- > npm i
14
- ```
15
-
16
- Other Options
17
-
18
- ```sh
19
- # Use GnuTLS instead of OpenSSL (Default False)
20
- > npm run install-gnu-tls
21
-
22
- # Use libnice instead of libjuice (Default False)
23
- # libnice-dev packet should be installed. (eg. sudo apt install libnice-dev)
24
- > npm run install-nice
25
- ```
26
-
27
- Compile without Media and Websocket
28
-
29
- ```sh
30
- npx cmake-js clean
31
- npx cmake-js configure --CDNO_MEDIA=ON --CDNO_WEBSOCKET=ON
32
- npx cmake-js build
33
- ```
9
+
10
+ ```sh
11
+ > git clone https://github.com/murat-dogan/node-datachannel.git
12
+ > cd node-datachannel
13
+ > npm install --ignore-scripts
14
+ > npm run compile
15
+ > npm run build:tsc
16
+ ```
17
+
18
+ ### Compile Options
19
+
20
+ Compile without Media and WebSocket:
21
+
22
+ ```sh
23
+ npx cmake-js clean
24
+ npx cmake-js configure --CDNO_MEDIA=ON --CDNO_WEBSOCKET=ON
25
+ npx cmake-js build
26
+ ```
package/CMakeLists.txt CHANGED
@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.15)
2
2
  cmake_policy(SET CMP0091 NEW)
3
3
  cmake_policy(SET CMP0042 NEW)
4
4
 
5
- project(node_datachannel VERSION 0.32.3)
5
+ project(node_datachannel VERSION 0.33.0)
6
6
 
7
7
  # compile_commands.json
8
8
  # -----------------------------------
@@ -14,12 +14,13 @@ add_definitions(-DNAPI_VERSION=8)
14
14
  include_directories(${CMAKE_JS_INC})
15
15
 
16
16
  if(WIN32)
17
- set(OPENSSL_MSVC_STATIC_RT TRUE)
18
17
  set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
18
+ else()
19
+ set(OPENSSL_USE_STATIC_LIBS TRUE)
19
20
  endif()
20
21
 
21
- if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Android")
22
- set(CMAKE_C_FLAGS "-Wno-error=unused-but-set-variable -Wno-error=strict-prototypes")
22
+ if(ANDROID OR CMAKE_SYSTEM_NAME STREQUAL "Android")
23
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-error=unused-but-set-variable -Wno-error=strict-prototypes")
23
24
  endif()
24
25
 
25
26
  # Add -frtti only for Linux and macOS
@@ -27,7 +28,6 @@ if (NOT CMAKE_SYSTEM_NAME STREQUAL "Windows")
27
28
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -frtti")
28
29
  endif()
29
30
 
30
- set(OPENSSL_USE_STATIC_LIBS TRUE)
31
31
  find_package(OpenSSL REQUIRED)
32
32
 
33
33
  include(FetchContent)
@@ -36,7 +36,7 @@ include(FetchContent)
36
36
  FetchContent_Declare(
37
37
  libdatachannel
38
38
  GIT_REPOSITORY https://github.com/paullouisageneau/libdatachannel.git
39
- GIT_TAG "v0.24.2"
39
+ GIT_TAG "v0.24.3"
40
40
  )
41
41
 
42
42
  option(NO_MEDIA "Disable media transport support in libdatachannel" OFF)
@@ -101,8 +101,19 @@ set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "" SUFFIX ".node")
101
101
  # ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/binary
102
102
  # )
103
103
 
104
+ if(NOT CMAKE_JS_INC)
105
+ execute_process(
106
+ COMMAND node -e "console.log(require('path').resolve(process.execPath, '..', '..', 'include', 'node'))"
107
+ OUTPUT_VARIABLE CMAKE_JS_INC
108
+ OUTPUT_STRIP_TRAILING_WHITESPACE
109
+ ERROR_QUIET
110
+ )
111
+ endif()
112
+
104
113
  target_include_directories(${PROJECT_NAME} PRIVATE
114
+ ${CMAKE_JS_INC}
105
115
  ${CMAKE_SOURCE_DIR}/node_modules/node-addon-api
116
+ ${CMAKE_SOURCE_DIR}/node_modules/node-api-headers/include
106
117
  ${CMAKE_BINARY_DIR}/_deps/libdatachannel-src/include
107
118
  ${CMAKE_BINARY_DIR}/_deps/libdatachannel-src/deps/plog
108
119
  )
@@ -115,8 +126,8 @@ set(LINK_LIBRARIES
115
126
 
116
127
  if(APPLE)
117
128
  #
118
- elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Android")
119
- list(APPEND LINK_LIBRARIES -static-libgcc)
129
+ elseif(ANDROID OR CMAKE_SYSTEM_NAME STREQUAL "Android")
130
+ # Android NDK uses libc++_static with -DANDROID_STL=c++_static
120
131
  elseif(UNIX)
121
132
  list(APPEND LINK_LIBRARIES -static-libgcc -static-libstdc++)
122
133
  endif()
@@ -128,7 +139,10 @@ endif()
128
139
 
129
140
  target_link_libraries(${PROJECT_NAME} PRIVATE ${LINK_LIBRARIES})
130
141
 
131
- if(UNIX AND NOT APPLE)
142
+ if(ANDROID OR CMAKE_SYSTEM_NAME STREQUAL "Android")
143
+ set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,undefs -Wl,--allow-shlib-undefined")
144
+ target_link_options(${PROJECT_NAME} PRIVATE -Wl,-z,undefs -Wl,--allow-shlib-undefined)
145
+ elseif(UNIX AND NOT APPLE)
132
146
  target_compile_options(${PROJECT_NAME} PRIVATE -fvisibility=hidden -fvisibility-inlines-hidden)
133
147
  target_link_options(${PROJECT_NAME} PRIVATE -Wl,--exclude-libs,ALL)
134
148
  endif()
package/README.md CHANGED
@@ -18,13 +18,12 @@ npm install node-datachannel
18
18
 
19
19
  ## Supported Platforms
20
20
 
21
- `node-datachannel` targets N-API version 8 and supports Node.js v18.20 and above. It is tested on Linux, Windows and MacOS. For N-API compatibility please check [here](https://nodejs.org/api/n-api.html#n_api_n_api_version_matrix).
21
+ `node-datachannel` targets N-API version 8 and supports Node.js **v18.20 and above** (including Node.js 20, 22, and 24+). Prebuilt binaries are distributed automatically via platform-specific npm packages (`optionalDependencies`).
22
22
 
23
- | | Linux [x64,armv7,arm64] (1) | Windows [x86,x64] | Mac [M1,x64] |
24
- | ------------------------- | :-------------------------: | :---------------: | :----------: |
25
- | N-API v8 (>= Node.js v18) | + | + | + |
26
-
27
- **(1)** For Linux musl + libc
23
+ | Architecture | Linux (glibc) | Linux (musl / Alpine) | macOS (Apple Silicon / Intel) | Windows | Android (Termux / Bionic) |
24
+ | :--- | :---: | :---: | :---: | :---: | :---: |
25
+ | **x64** | `@node-datachannel/linux-x64-gnu` | `@node-datachannel/linux-x64-musl` | `@node-datachannel/darwin-x64` | `@node-datachannel/win32-x64-msvc` | - |
26
+ | **arm64** | `@node-datachannel/linux-arm64-gnu` | `@node-datachannel/linux-arm64-musl` | `@node-datachannel/darwin-arm64` | `@node-datachannel/win32-arm64-msvc` | `@node-datachannel/android-arm64` |
28
27
 
29
28
  ## Electron
30
29
 
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../../../src/lib/index.ts"],"sourcesContent":["import nodeDataChannel from './node-datachannel';\nimport _DataChannelStream from './datachannel-stream';\nimport { WebSocketServer } from './websocket-server';\nimport {\n Channel,\n DataChannelInitConfig,\n DescriptionType,\n Direction,\n LogLevel,\n NalUnitSeparator,\n ObuPacketization,\n RtcConfig,\n RTCIceConnectionState,\n RTCIceGatheringState,\n RTCPeerConnectionState,\n RTCSignalingState,\n SctpSettings,\n SelectedCandidateInfo,\n} from './types';\nimport { WebSocket } from './websocket';\nimport type { CertificateFingerprint, IceUdpMuxRequest, LocalDescriptionInit } from './types';\n\nexport function preload(): void {\n nodeDataChannel.preload();\n}\nexport function initLogger(level: LogLevel, cb?: (level: LogLevel, message: string) => void): void {\n nodeDataChannel.initLogger(level, cb);\n}\nexport function cleanup(): void {\n nodeDataChannel.cleanup();\n}\nexport function setSctpSettings(settings: SctpSettings): void {\n nodeDataChannel.setSctpSettings(settings);\n}\nexport function getLibraryVersion(): string {\n return nodeDataChannel.getLibraryVersion();\n}\n\nexport interface Audio {\n addAudioCodec(payloadType: number, codec: string, profile?: string): void;\n addOpusCodec(payloadType: number, profile?: string): string;\n direction(): Direction;\n generateSdp(eol: string, addr: string, port: number): string;\n mid(): string;\n setDirection(dir: Direction): void;\n description(): string;\n removeFormat(fmt: string): void;\n addSSRC(ssrc: number, name?: string, msid?: string, trackID?: string): void;\n removeSSRC(ssrc: number): void;\n replaceSSRC(oldSsrc: number, ssrc: number, name?: string, msid?: string, trackID?: string): void;\n hasSSRC(ssrc: number): boolean;\n getSSRCs(): number[];\n getCNameForSsrc(ssrc: number): string;\n setBitrate(bitRate: number): void;\n getBitrate(): number;\n hasPayloadType(payloadType: number): boolean;\n addRTXCodec(payloadType: number, originalPayloadType: number, clockRate: number): void;\n addRTPMap(): void;\n parseSdpLine(line: string): void;\n}\nexport const Audio: {\n new (mid: string, dir: Direction): Audio;\n} = nodeDataChannel.Audio;\n\nexport interface Video {\n addVideoCodec(payloadType: number, codec: string, profile?: string): void;\n addH264Codec(payloadType: number, profile?: string): void;\n addH265Codec(payloadType: number): void;\n addVP8Codec(payloadType: number): void;\n addVP9Codec(payloadType: number): void;\n addAV1Codec(payloadType: number): void;\n direction(): Direction;\n generateSdp(eol: string, addr: string, port: number): string;\n mid(): string;\n setDirection(dir: Direction): void;\n description(): string;\n removeFormat(fmt: string): void;\n addSSRC(ssrc: number, name?: string, msid?: string, trackID?: string): void;\n removeSSRC(ssrc: number): void;\n replaceSSRC(oldSsrc: number, ssrc: number, name?: string, msid?: string, trackID?: string): void;\n hasSSRC(ssrc: number): boolean;\n getSSRCs(): number[];\n getCNameForSsrc(ssrc: number): string;\n setBitrate(bitRate: number): void;\n getBitrate(): number;\n hasPayloadType(payloadType: number): boolean;\n addRTXCodec(payloadType: number, originalPayloadType: number, clockRate: number): void;\n addRTPMap(): void;\n parseSdpLine(line: string): void;\n}\nexport const Video: {\n new (mid: string, dir: Direction): Video;\n} = nodeDataChannel.Video;\n\nexport interface Track {\n direction(): Direction;\n mid(): string;\n type(): string;\n close(): void;\n sendMessage(msg: string): boolean;\n sendMessageBinary(buffer: Buffer): boolean;\n isOpen(): boolean;\n isClosed(): boolean;\n bufferedAmount(): number;\n maxMessageSize(): number;\n requestBitrate(bitRate: number): boolean;\n setBufferedAmountLowThreshold(newSize: number): void;\n requestKeyframe(): boolean;\n setMediaHandler(handler: MediaHandler): void;\n onOpen(cb: () => void): void;\n onClosed(cb: () => void): void;\n onError(cb: (err: string) => void): void;\n onMessage(cb: (msg: Buffer) => void): void;\n}\nexport const Track: {\n new (): Track;\n} = nodeDataChannel.Track;\n\nexport interface DataChannel extends Channel {\n getLabel(): string;\n getId(): number;\n getProtocol(): string;\n\n // Channel implementation\n close(): void;\n sendMessage(msg: string): boolean;\n sendMessageBinary(buffer: Buffer | Uint8Array): boolean;\n isOpen(): boolean;\n bufferedAmount(): number;\n maxMessageSize(): number;\n setBufferedAmountLowThreshold(newSize: number): void;\n onOpen(cb: () => void): void;\n onClosed(cb: () => void): void;\n onError(cb: (err: string) => void): void;\n onBufferedAmountLow(cb: () => void): void;\n onMessage(cb: (msg: string | Buffer | ArrayBuffer) => void): void;\n}\nexport const DataChannel: {\n // DataChannel implementation\n} = nodeDataChannel.DataChannel;\n\nexport interface PeerConnection {\n close(): void;\n setLocalDescription(type?: DescriptionType, init?: LocalDescriptionInit): void;\n setRemoteDescription(sdp: string, type: DescriptionType): void;\n localDescription(): { type: DescriptionType; sdp: string } | null;\n remoteDescription(): { type: DescriptionType; sdp: string } | null;\n remoteFingerprint(): CertificateFingerprint;\n addRemoteCandidate(candidate: string, mid: string): void;\n createDataChannel(label: string, config?: DataChannelInitConfig): DataChannel;\n addTrack(media: Video | Audio): Track;\n hasMedia(): boolean;\n state(): RTCPeerConnectionState;\n iceState(): RTCIceConnectionState;\n signalingState(): RTCSignalingState;\n gatheringState(): RTCIceGatheringState;\n onLocalDescription(cb: (sdp: string, type: DescriptionType) => void): void;\n onLocalCandidate(cb: (candidate: string, mid: string) => void): void;\n onStateChange(cb: (state: string) => void): void;\n onIceStateChange(cb: (state: string) => void): void;\n onSignalingStateChange(cb: (state: string) => void): void;\n onGatheringStateChange(cb: (state: string) => void): void;\n onDataChannel(cb: (dc: DataChannel) => void): void;\n onTrack(cb: (track: Track) => void): void;\n bytesSent(): number;\n bytesReceived(): number;\n rtt(): number;\n getSelectedCandidatePair(): {\n local: SelectedCandidateInfo;\n remote: SelectedCandidateInfo;\n } | null;\n maxDataChannelId(): number;\n maxMessageSize(): number;\n}\nexport const PeerConnection: {\n new (peerName: string, config: RtcConfig): PeerConnection;\n} = nodeDataChannel.PeerConnection;\n\nexport interface IceUdpMuxListener {\n address?: string;\n port: number;\n stop(): void;\n onUnhandledStunRequest(cb: (req: IceUdpMuxRequest) => void): void;\n}\nexport const IceUdpMuxListener: {\n new (port: number, address?: string): IceUdpMuxListener;\n} = nodeDataChannel.IceUdpMuxListener;\n\nexport interface RtpPacketizationConfig {\n playoutDelayId: number,\n playoutDelayMin: number,\n playoutDelayMax: number,\n timestamp: number,\n get clockRate(): number\n}\n\nexport const RtpPacketizationConfig: {\n new(ssrc: number, cname: string, payloadType: number, clockRate: number, videoOrientationId?: number): RtpPacketizationConfig\n} = nodeDataChannel.RtpPacketizationConfig\n\nexport interface MediaHandler {\n addToChain(handler: MediaHandler): void\n}\n\nexport interface PacingHandler extends MediaHandler {}\n\nexport const PacingHandler: {\n new (bitsPerSecond: number, sendInterval: number): PacingHandler;\n} = nodeDataChannel.PacingHandler;\n\nexport interface RtcpReceivingSession extends MediaHandler {}\n\nexport const RtcpReceivingSession: {\n new (): RtcpReceivingSession;\n} = nodeDataChannel.RtcpReceivingSession;\n\nexport interface RtcpNackResponder extends MediaHandler {}\n\nexport const RtcpNackResponder: {\n new (maxSize?: number): RtcpNackResponder\n} = nodeDataChannel.RtcpNackResponder;\n\nexport interface RtcpSrReporter extends MediaHandler {\n get rtpConfig(): RtpPacketizationConfig\n}\n\nexport const RtcpSrReporter: {\n new (rtpConfig: RtpPacketizationConfig): RtcpSrReporter\n} = nodeDataChannel.RtcpSrReporter;\n\nexport interface RtpPacketizer extends MediaHandler {\n get rtpConfig(): RtpPacketizationConfig\n}\n\nexport const RtpPacketizer: {\n new (rtpConfig: RtpPacketizationConfig): RtpPacketizer\n} = nodeDataChannel.RtpPacketizer;\n\nexport interface H264RtpPacketizer extends RtpPacketizer {}\n\nexport const H264RtpPacketizer: {\n new (separator: NalUnitSeparator, rtpConfig: RtpPacketizationConfig, maxFragmentSize?: number): H264RtpPacketizer\n} = nodeDataChannel.H264RtpPacketizer\n\nexport interface H265RtpPacketizer extends RtpPacketizer {}\n\nexport const H265RtpPacketizer: {\n new (separator: NalUnitSeparator, rtpConfig: RtpPacketizationConfig, maxFragmentSize?: number): H265RtpPacketizer\n} = nodeDataChannel.H265RtpPacketizer\n\nexport interface AV1RtpPacketizer extends RtpPacketizer {}\n\nexport const AV1RtpPacketizer: {\n new (packetization: ObuPacketization, rtpConfig: RtpPacketizationConfig, maxFragmentSize?: number): AV1RtpPacketizer\n} = nodeDataChannel.AV1RtpPacketizer\n\nexport { WebSocketServer } from './websocket-server';\nexport { WebSocket } from './websocket';\n\nexport const DataChannelStream = _DataChannelStream;\n\nexport default {\n initLogger,\n cleanup,\n preload,\n setSctpSettings,\n getLibraryVersion,\n PacingHandler,\n RtcpReceivingSession,\n RtcpNackResponder,\n RtcpSrReporter,\n RtpPacketizationConfig,\n RtpPacketizer,\n H264RtpPacketizer,\n H265RtpPacketizer,\n AV1RtpPacketizer,\n Track,\n Video,\n Audio,\n DataChannel,\n PeerConnection,\n WebSocket,\n WebSocketServer,\n DataChannelStream,\n IceUdpMuxListener,\n};\n\n// Types\n// https://github.com/murat-dogan/node-datachannel/issues/300\nexport * from './types';\n"],"names":["nodeDataChannel","_DataChannelStream","WebSocket","WebSocketServer"],"mappings":";;;;;;;;;AAsBO,SAAS,OAAgB,GAAA;AAC9B,EAAAA,uBAAA,CAAgB,OAAQ,EAAA,CAAA;AAC1B,CAAA;AACgB,SAAA,UAAA,CAAW,OAAiB,EAAuD,EAAA;AACjG,EAAgBA,uBAAA,CAAA,UAAA,CAAW,OAAO,EAAE,CAAA,CAAA;AACtC,CAAA;AACO,SAAS,OAAgB,GAAA;AAC9B,EAAAA,uBAAA,CAAgB,OAAQ,EAAA,CAAA;AAC1B,CAAA;AACO,SAAS,gBAAgB,QAA8B,EAAA;AAC5D,EAAAA,uBAAA,CAAgB,gBAAgB,QAAQ,CAAA,CAAA;AAC1C,CAAA;AACO,SAAS,iBAA4B,GAAA;AAC1C,EAAA,OAAOA,wBAAgB,iBAAkB,EAAA,CAAA;AAC3C,CAAA;AAwBO,MAAM,QAETA,uBAAgB,CAAA,MAAA;AA4Bb,MAAM,QAETA,uBAAgB,CAAA,MAAA;AAsBb,MAAM,QAETA,uBAAgB,CAAA,MAAA;AAqBb,MAAM,cAETA,uBAAgB,CAAA,YAAA;AAmCb,MAAM,iBAETA,uBAAgB,CAAA,eAAA;AAQb,MAAM,oBAETA,uBAAgB,CAAA,kBAAA;AAUb,MAAM,yBAETA,uBAAgB,CAAA,uBAAA;AAQb,MAAM,gBAETA,uBAAgB,CAAA,cAAA;AAIb,MAAM,uBAETA,uBAAgB,CAAA,qBAAA;AAIb,MAAM,oBAETA,uBAAgB,CAAA,kBAAA;AAMb,MAAM,iBAETA,uBAAgB,CAAA,eAAA;AAMb,MAAM,gBAETA,uBAAgB,CAAA,cAAA;AAIb,MAAM,oBAETA,uBAAgB,CAAA,kBAAA;AAIb,MAAM,oBAETA,uBAAgB,CAAA,kBAAA;AAIb,MAAM,mBAETA,uBAAgB,CAAA,iBAAA;AAKb,MAAM,iBAAoB,GAAAC,0BAAA;AAEjC,QAAe;AAAA,EACb,UAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACA,eAAA;AAAA,EACA,iBAAA;AAAA,EACA,aAAA;AAAA,EACA,oBAAA;AAAA,EACA,iBAAA;AAAA,EACA,cAAA;AAAA,EACA,sBAAA;AAAA,EACA,aAAA;AAAA,EACA,iBAAA;AAAA,EACA,iBAAA;AAAA,EACA,gBAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA,EACA,WAAA;AAAA,EACA,cAAA;AAAA,aACAC,mBAAA;AAAA,mBACAC,+BAAA;AAAA,EACA,iBAAA;AAAA,EACA,iBAAA;AACF,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.cjs","sources":["../../../src/lib/index.ts"],"sourcesContent":["import nodeDataChannel from './node-datachannel';\nimport _DataChannelStream from './datachannel-stream';\nimport { WebSocketServer } from './websocket-server';\nimport {\n Channel,\n DataChannelInitConfig,\n DescriptionType,\n Direction,\n LogLevel,\n NalUnitSeparator,\n ObuPacketization,\n RtcConfig,\n RTCIceConnectionState,\n RTCIceGatheringState,\n RTCPeerConnectionState,\n RTCSignalingState,\n SctpSettings,\n SelectedCandidateInfo,\n} from './types';\nimport { WebSocket } from './websocket';\nimport type { CertificateFingerprint, IceUdpMuxRequest, LocalDescriptionInit } from './types';\n\nexport function preload(): void {\n nodeDataChannel.preload();\n}\nexport function initLogger(level: LogLevel, cb?: (level: LogLevel, message: string) => void): void {\n nodeDataChannel.initLogger(level, cb);\n}\nexport function cleanup(): void {\n nodeDataChannel.cleanup();\n}\nexport function setSctpSettings(settings: SctpSettings): void {\n nodeDataChannel.setSctpSettings(settings);\n}\nexport function getLibraryVersion(): string {\n return nodeDataChannel.getLibraryVersion();\n}\n\nexport interface Audio {\n addAudioCodec(payloadType: number, codec: string, profile?: string): void;\n addOpusCodec(payloadType: number, profile?: string): string;\n direction(): Direction;\n generateSdp(eol: string, addr: string, port: number): string;\n mid(): string;\n setDirection(dir: Direction): void;\n description(): string;\n removeFormat(fmt: string): void;\n addSSRC(ssrc: number, name?: string, msid?: string, trackID?: string): void;\n removeSSRC(ssrc: number): void;\n replaceSSRC(oldSsrc: number, ssrc: number, name?: string, msid?: string, trackID?: string): void;\n hasSSRC(ssrc: number): boolean;\n getSSRCs(): number[];\n getCNameForSsrc(ssrc: number): string;\n setBitrate(bitRate: number): void;\n getBitrate(): number;\n hasPayloadType(payloadType: number): boolean;\n addRTXCodec(payloadType: number, originalPayloadType: number, clockRate: number): void;\n addRTPMap(): void;\n parseSdpLine(line: string): void;\n}\nexport const Audio: {\n new (mid: string, dir: Direction): Audio;\n} = nodeDataChannel.Audio;\n\nexport interface Video {\n addVideoCodec(payloadType: number, codec: string, profile?: string): void;\n addH264Codec(payloadType: number, profile?: string): void;\n addH265Codec(payloadType: number): void;\n addVP8Codec(payloadType: number): void;\n addVP9Codec(payloadType: number): void;\n addAV1Codec(payloadType: number): void;\n direction(): Direction;\n generateSdp(eol: string, addr: string, port: number): string;\n mid(): string;\n setDirection(dir: Direction): void;\n description(): string;\n removeFormat(fmt: string): void;\n addSSRC(ssrc: number, name?: string, msid?: string, trackID?: string): void;\n removeSSRC(ssrc: number): void;\n replaceSSRC(oldSsrc: number, ssrc: number, name?: string, msid?: string, trackID?: string): void;\n hasSSRC(ssrc: number): boolean;\n getSSRCs(): number[];\n getCNameForSsrc(ssrc: number): string;\n setBitrate(bitRate: number): void;\n getBitrate(): number;\n hasPayloadType(payloadType: number): boolean;\n addRTXCodec(payloadType: number, originalPayloadType: number, clockRate: number): void;\n addRTPMap(): void;\n parseSdpLine(line: string): void;\n}\nexport const Video: {\n new (mid: string, dir: Direction): Video;\n} = nodeDataChannel.Video;\n\nexport interface Track {\n direction(): Direction;\n mid(): string;\n type(): string;\n close(): void;\n sendMessage(msg: string): boolean;\n sendMessageBinary(buffer: Buffer): boolean;\n isOpen(): boolean;\n isClosed(): boolean;\n bufferedAmount(): number;\n maxMessageSize(): number;\n requestBitrate(bitRate: number): boolean;\n setBufferedAmountLowThreshold(newSize: number): void;\n requestKeyframe(): boolean;\n setMediaHandler(handler: MediaHandler): void;\n onOpen(cb: () => void): void;\n onClosed(cb: () => void): void;\n onError(cb: (err: string) => void): void;\n onMessage(cb: (msg: Buffer) => void): void;\n}\nexport const Track: {\n new (): Track;\n} = nodeDataChannel.Track;\n\nexport interface DataChannel extends Channel {\n getLabel(): string;\n getId(): number;\n getProtocol(): string;\n\n // Channel implementation\n close(): void;\n sendMessage(msg: string): boolean;\n sendMessageBinary(buffer: Buffer | Uint8Array): boolean;\n isOpen(): boolean;\n bufferedAmount(): number;\n maxMessageSize(): number;\n setBufferedAmountLowThreshold(newSize: number): void;\n onOpen(cb: () => void): void;\n onClosed(cb: () => void): void;\n onError(cb: (err: string) => void): void;\n onBufferedAmountLow(cb: () => void): void;\n onMessage(cb: (msg: string | Buffer | ArrayBuffer) => void): void;\n}\nexport const DataChannel: {\n // DataChannel implementation\n} = nodeDataChannel.DataChannel;\n\nexport interface PeerConnection {\n close(): void;\n setLocalDescription(type?: DescriptionType, init?: LocalDescriptionInit): void;\n setRemoteDescription(sdp: string, type: DescriptionType): void;\n localDescription(): { type: DescriptionType; sdp: string } | null;\n remoteDescription(): { type: DescriptionType; sdp: string } | null;\n remoteFingerprint(): CertificateFingerprint;\n addRemoteCandidate(candidate: string, mid: string): void;\n createDataChannel(label: string, config?: DataChannelInitConfig): DataChannel;\n addTrack(media: Video | Audio): Track;\n hasMedia(): boolean;\n state(): RTCPeerConnectionState;\n iceState(): RTCIceConnectionState;\n signalingState(): RTCSignalingState;\n gatheringState(): RTCIceGatheringState;\n onLocalDescription(cb: (sdp: string, type: DescriptionType) => void): void;\n onLocalCandidate(cb: (candidate: string, mid: string) => void): void;\n onStateChange(cb: (state: string) => void): void;\n onIceStateChange(cb: (state: string) => void): void;\n onSignalingStateChange(cb: (state: string) => void): void;\n onGatheringStateChange(cb: (state: string) => void): void;\n onDataChannel(cb: (dc: DataChannel) => void): void;\n onTrack(cb: (track: Track) => void): void;\n bytesSent(): number;\n bytesReceived(): number;\n rtt(): number;\n getSelectedCandidatePair(): {\n local: SelectedCandidateInfo;\n remote: SelectedCandidateInfo;\n } | null;\n maxDataChannelId(): number;\n maxMessageSize(): number;\n}\nexport const PeerConnection: {\n new (peerName: string, config: RtcConfig): PeerConnection;\n} = nodeDataChannel.PeerConnection;\n\nexport interface IceUdpMuxListener {\n address(): string | undefined;\n port(): number;\n stop(): void;\n onUnhandledStunRequest(cb: (req: IceUdpMuxRequest) => void): void;\n}\nexport const IceUdpMuxListener: {\n new (port: number, address?: string): IceUdpMuxListener;\n} = nodeDataChannel.IceUdpMuxListener;\n\nexport interface RtpPacketizationConfig {\n playoutDelayId: number,\n playoutDelayMin: number,\n playoutDelayMax: number,\n timestamp: number,\n get clockRate(): number\n}\n\nexport const RtpPacketizationConfig: {\n new(ssrc: number, cname: string, payloadType: number, clockRate: number, videoOrientationId?: number): RtpPacketizationConfig\n} = nodeDataChannel.RtpPacketizationConfig\n\nexport interface MediaHandler {\n addToChain(handler: MediaHandler): void\n}\n\nexport interface PacingHandler extends MediaHandler {}\n\nexport const PacingHandler: {\n new (bitsPerSecond: number, sendInterval: number): PacingHandler;\n} = nodeDataChannel.PacingHandler;\n\nexport interface RtcpReceivingSession extends MediaHandler {}\n\nexport const RtcpReceivingSession: {\n new (): RtcpReceivingSession;\n} = nodeDataChannel.RtcpReceivingSession;\n\nexport interface RtcpNackResponder extends MediaHandler {}\n\nexport const RtcpNackResponder: {\n new (maxSize?: number): RtcpNackResponder\n} = nodeDataChannel.RtcpNackResponder;\n\nexport interface RtcpSrReporter extends MediaHandler {\n get rtpConfig(): RtpPacketizationConfig\n}\n\nexport const RtcpSrReporter: {\n new (rtpConfig: RtpPacketizationConfig): RtcpSrReporter\n} = nodeDataChannel.RtcpSrReporter;\n\nexport interface RtpPacketizer extends MediaHandler {\n get rtpConfig(): RtpPacketizationConfig\n}\n\nexport const RtpPacketizer: {\n new (rtpConfig: RtpPacketizationConfig): RtpPacketizer\n} = nodeDataChannel.RtpPacketizer;\n\nexport interface H264RtpPacketizer extends RtpPacketizer {}\n\nexport const H264RtpPacketizer: {\n new (separator: NalUnitSeparator, rtpConfig: RtpPacketizationConfig, maxFragmentSize?: number): H264RtpPacketizer\n} = nodeDataChannel.H264RtpPacketizer\n\nexport interface H265RtpPacketizer extends RtpPacketizer {}\n\nexport const H265RtpPacketizer: {\n new (separator: NalUnitSeparator, rtpConfig: RtpPacketizationConfig, maxFragmentSize?: number): H265RtpPacketizer\n} = nodeDataChannel.H265RtpPacketizer\n\nexport interface AV1RtpPacketizer extends RtpPacketizer {}\n\nexport const AV1RtpPacketizer: {\n new (packetization: ObuPacketization, rtpConfig: RtpPacketizationConfig, maxFragmentSize?: number): AV1RtpPacketizer\n} = nodeDataChannel.AV1RtpPacketizer\n\nexport { WebSocketServer } from './websocket-server';\nexport { WebSocket } from './websocket';\n\nexport const DataChannelStream = _DataChannelStream;\n\nexport default {\n initLogger,\n cleanup,\n preload,\n setSctpSettings,\n getLibraryVersion,\n PacingHandler,\n RtcpReceivingSession,\n RtcpNackResponder,\n RtcpSrReporter,\n RtpPacketizationConfig,\n RtpPacketizer,\n H264RtpPacketizer,\n H265RtpPacketizer,\n AV1RtpPacketizer,\n Track,\n Video,\n Audio,\n DataChannel,\n PeerConnection,\n WebSocket,\n WebSocketServer,\n DataChannelStream,\n IceUdpMuxListener,\n};\n\n// Types\n// https://github.com/murat-dogan/node-datachannel/issues/300\nexport * from './types';\n"],"names":["nodeDataChannel","_DataChannelStream","WebSocket","WebSocketServer"],"mappings":";;;;;;;;;AAsBO,SAAS,OAAgB,GAAA;AAC9B,EAAAA,uBAAA,CAAgB,OAAQ,EAAA,CAAA;AAC1B,CAAA;AACgB,SAAA,UAAA,CAAW,OAAiB,EAAuD,EAAA;AACjG,EAAgBA,uBAAA,CAAA,UAAA,CAAW,OAAO,EAAE,CAAA,CAAA;AACtC,CAAA;AACO,SAAS,OAAgB,GAAA;AAC9B,EAAAA,uBAAA,CAAgB,OAAQ,EAAA,CAAA;AAC1B,CAAA;AACO,SAAS,gBAAgB,QAA8B,EAAA;AAC5D,EAAAA,uBAAA,CAAgB,gBAAgB,QAAQ,CAAA,CAAA;AAC1C,CAAA;AACO,SAAS,iBAA4B,GAAA;AAC1C,EAAA,OAAOA,wBAAgB,iBAAkB,EAAA,CAAA;AAC3C,CAAA;AAwBO,MAAM,QAETA,uBAAgB,CAAA,MAAA;AA4Bb,MAAM,QAETA,uBAAgB,CAAA,MAAA;AAsBb,MAAM,QAETA,uBAAgB,CAAA,MAAA;AAqBb,MAAM,cAETA,uBAAgB,CAAA,YAAA;AAmCb,MAAM,iBAETA,uBAAgB,CAAA,eAAA;AAQb,MAAM,oBAETA,uBAAgB,CAAA,kBAAA;AAUb,MAAM,yBAETA,uBAAgB,CAAA,uBAAA;AAQb,MAAM,gBAETA,uBAAgB,CAAA,cAAA;AAIb,MAAM,uBAETA,uBAAgB,CAAA,qBAAA;AAIb,MAAM,oBAETA,uBAAgB,CAAA,kBAAA;AAMb,MAAM,iBAETA,uBAAgB,CAAA,eAAA;AAMb,MAAM,gBAETA,uBAAgB,CAAA,cAAA;AAIb,MAAM,oBAETA,uBAAgB,CAAA,kBAAA;AAIb,MAAM,oBAETA,uBAAgB,CAAA,kBAAA;AAIb,MAAM,mBAETA,uBAAgB,CAAA,iBAAA;AAKb,MAAM,iBAAoB,GAAAC,0BAAA;AAEjC,QAAe;AAAA,EACb,UAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACA,eAAA;AAAA,EACA,iBAAA;AAAA,EACA,aAAA;AAAA,EACA,oBAAA;AAAA,EACA,iBAAA;AAAA,EACA,cAAA;AAAA,EACA,sBAAA;AAAA,EACA,aAAA;AAAA,EACA,iBAAA;AAAA,EACA,iBAAA;AAAA,EACA,gBAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA,EACA,WAAA;AAAA,EACA,cAAA;AAAA,aACAC,mBAAA;AAAA,mBACAC,+BAAA;AAAA,EACA,iBAAA;AAAA,EACA,iBAAA;AACF,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -2,7 +2,93 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- const nodeDataChannel = require("../../../build/Release/node_datachannel.node");
5
+ var fs = require('fs');
6
+ var path = require('path');
7
+ var detectLibc = require('detect-libc');
8
+
9
+ function _interopNamespaceDefault(e) {
10
+ var n = Object.create(null);
11
+ if (e) {
12
+ Object.keys(e).forEach(function (k) {
13
+ if (k !== 'default') {
14
+ var d = Object.getOwnPropertyDescriptor(e, k);
15
+ Object.defineProperty(n, k, d.get ? d : {
16
+ enumerable: true,
17
+ get: function () { return e[k]; }
18
+ });
19
+ }
20
+ });
21
+ }
22
+ n.default = e;
23
+ return Object.freeze(n);
24
+ }
25
+
26
+ var fs__namespace = /*#__PURE__*/_interopNamespaceDefault(fs);
27
+ var path__namespace = /*#__PURE__*/_interopNamespaceDefault(path);
28
+
29
+ function getPackageName() {
30
+ const { platform, arch } = process;
31
+ if (platform === "linux") {
32
+ const libc = detectLibc.familySync();
33
+ if (libc === detectLibc.MUSL) {
34
+ if (arch === "x64") return "@node-datachannel/linux-x64-musl";
35
+ if (arch === "arm64") return "@node-datachannel/linux-arm64-musl";
36
+ } else {
37
+ if (arch === "x64") return "@node-datachannel/linux-x64-gnu";
38
+ if (arch === "arm64") return "@node-datachannel/linux-arm64-gnu";
39
+ }
40
+ } else if (platform === "darwin") {
41
+ if (arch === "arm64") return "@node-datachannel/darwin-arm64";
42
+ if (arch === "x64") return "@node-datachannel/darwin-x64";
43
+ } else if (platform === "win32") {
44
+ if (arch === "x64") return "@node-datachannel/win32-x64-msvc";
45
+ if (arch === "arm64") return "@node-datachannel/win32-arm64-msvc";
46
+ } else if (platform === "android") {
47
+ if (arch === "arm64") return "@node-datachannel/android-arm64";
48
+ }
49
+ return null;
50
+ }
51
+ function loadBinding() {
52
+ const candidateLocalPaths = [
53
+ path__namespace.resolve(__dirname, "../../build/node_datachannel.node"),
54
+ path__namespace.resolve(__dirname, "../../../build/node_datachannel.node"),
55
+ path__namespace.resolve(__dirname, "../../build/Release/node_datachannel.node"),
56
+ path__namespace.resolve(__dirname, "../../../build/Release/node_datachannel.node"),
57
+ path__namespace.resolve(__dirname, "../../build/Debug/node_datachannel.node"),
58
+ path__namespace.resolve(__dirname, "../../../build/Debug/node_datachannel.node")
59
+ ];
60
+ let localLoadError = null;
61
+ for (const candidate of candidateLocalPaths) {
62
+ if (fs__namespace.existsSync(candidate)) {
63
+ try {
64
+ return require(candidate);
65
+ } catch (err) {
66
+ localLoadError = err instanceof Error ? err : new Error(String(err));
67
+ }
68
+ }
69
+ }
70
+ if (localLoadError) {
71
+ throw new Error(
72
+ `Failed to load local native addon build: ${localLoadError.message}
73
+ Stack: ${localLoadError.stack}`
74
+ );
75
+ }
76
+ const pkgName = getPackageName();
77
+ if (pkgName) {
78
+ try {
79
+ return require(pkgName);
80
+ } catch (err) {
81
+ const errorMsg = err instanceof Error ? err.message : String(err);
82
+ throw new Error(
83
+ `Cannot load native addon for node-datachannel on ${process.platform} (${process.arch}). Attempted to require "${pkgName}". Please ensure optionalDependencies are installed (avoid --no-optional / --omit=optional) or compile locally with "npm run compile". (Error: ${errorMsg})`
84
+ );
85
+ }
86
+ }
87
+ throw new Error(
88
+ `Unsupported platform/architecture for node-datachannel: ${process.platform} (${process.arch}). Please compile from source using "npm run compile".`
89
+ );
90
+ }
91
+ const nodeDataChannel = loadBinding();
6
92
 
7
93
  exports.default = nodeDataChannel;
8
94
  //# sourceMappingURL=node-datachannel.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"node-datachannel.cjs","sources":["../../../src/lib/node-datachannel.ts"],"sourcesContent":["// @ts-expect-error no types\nimport nodeDataChannel = require('../../build/Release/node_datachannel.node');\nexport default nodeDataChannel;\n"],"names":[],"mappings":";;;;AACA,MAAO,kBAAkB,OAAoB,CAAA,8CAAA;;;;"}
1
+ {"version":3,"file":"node-datachannel.cjs","sources":["../../../src/lib/node-datachannel.ts"],"sourcesContent":["import * as fs from 'fs';\nimport * as path from 'path';\nimport { familySync, MUSL } from 'detect-libc';\n\nfunction getPackageName(): string | null {\n const { platform, arch } = process;\n if (platform === 'linux') {\n const libc = familySync();\n if (libc === MUSL) {\n if (arch === 'x64') return '@node-datachannel/linux-x64-musl';\n if (arch === 'arm64') return '@node-datachannel/linux-arm64-musl';\n } else {\n if (arch === 'x64') return '@node-datachannel/linux-x64-gnu';\n if (arch === 'arm64') return '@node-datachannel/linux-arm64-gnu';\n }\n } else if (platform === 'darwin') {\n if (arch === 'arm64') return '@node-datachannel/darwin-arm64';\n if (arch === 'x64') return '@node-datachannel/darwin-x64';\n } else if (platform === 'win32') {\n if (arch === 'x64') return '@node-datachannel/win32-x64-msvc';\n if (arch === 'arm64') return '@node-datachannel/win32-arm64-msvc';\n } else if (platform === 'android') {\n if (arch === 'arm64') return '@node-datachannel/android-arm64';\n }\n return null;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction loadBinding(): any {\n // 1. Try local build candidate paths for development, tests, and source builds\n const candidateLocalPaths = [\n path.resolve(__dirname, '../../build/node_datachannel.node'),\n path.resolve(__dirname, '../../../build/node_datachannel.node'),\n path.resolve(__dirname, '../../build/Release/node_datachannel.node'),\n path.resolve(__dirname, '../../../build/Release/node_datachannel.node'),\n path.resolve(__dirname, '../../build/Debug/node_datachannel.node'),\n path.resolve(__dirname, '../../../build/Debug/node_datachannel.node'),\n ];\n\n let localLoadError: Error | null = null;\n for (const candidate of candidateLocalPaths) {\n if (fs.existsSync(candidate)) {\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n return require(candidate);\n } catch (err: unknown) {\n localLoadError = err instanceof Error ? err : new Error(String(err));\n }\n }\n }\n\n if (localLoadError) {\n throw new Error(\n `Failed to load local native addon build: ${localLoadError.message}\\n` +\n `Stack: ${localLoadError.stack}`\n );\n }\n\n // 2. Try platform-specific optionalDependencies package\n const pkgName = getPackageName();\n if (pkgName) {\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n return require(pkgName);\n } catch (err: unknown) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n throw new Error(\n `Cannot load native addon for node-datachannel on ${process.platform} (${process.arch}). ` +\n `Attempted to require \"${pkgName}\". ` +\n `Please ensure optionalDependencies are installed (avoid --no-optional / --omit=optional) ` +\n `or compile locally with \"npm run compile\". (Error: ${errorMsg})`\n );\n }\n }\n\n throw new Error(\n `Unsupported platform/architecture for node-datachannel: ${process.platform} (${process.arch}). ` +\n `Please compile from source using \"npm run compile\".`\n );\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst nodeDataChannel: any = loadBinding();\nexport default nodeDataChannel;\n"],"names":["familySync","MUSL","path","fs"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIA,SAAS,cAAgC,GAAA;AACvC,EAAM,MAAA,EAAE,QAAU,EAAA,IAAA,EAAS,GAAA,OAAA,CAAA;AAC3B,EAAA,IAAI,aAAa,OAAS,EAAA;AACxB,IAAA,MAAM,OAAOA,qBAAW,EAAA,CAAA;AACxB,IAAA,IAAI,SAASC,eAAM,EAAA;AACjB,MAAI,IAAA,IAAA,KAAS,OAAc,OAAA,kCAAA,CAAA;AAC3B,MAAI,IAAA,IAAA,KAAS,SAAgB,OAAA,oCAAA,CAAA;AAAA,KACxB,MAAA;AACL,MAAI,IAAA,IAAA,KAAS,OAAc,OAAA,iCAAA,CAAA;AAC3B,MAAI,IAAA,IAAA,KAAS,SAAgB,OAAA,mCAAA,CAAA;AAAA,KAC/B;AAAA,GACF,MAAA,IAAW,aAAa,QAAU,EAAA;AAChC,IAAI,IAAA,IAAA,KAAS,SAAgB,OAAA,gCAAA,CAAA;AAC7B,IAAI,IAAA,IAAA,KAAS,OAAc,OAAA,8BAAA,CAAA;AAAA,GAC7B,MAAA,IAAW,aAAa,OAAS,EAAA;AAC/B,IAAI,IAAA,IAAA,KAAS,OAAc,OAAA,kCAAA,CAAA;AAC3B,IAAI,IAAA,IAAA,KAAS,SAAgB,OAAA,oCAAA,CAAA;AAAA,GAC/B,MAAA,IAAW,aAAa,SAAW,EAAA;AACjC,IAAI,IAAA,IAAA,KAAS,SAAgB,OAAA,iCAAA,CAAA;AAAA,GAC/B;AACA,EAAO,OAAA,IAAA,CAAA;AACT,CAAA;AAGA,SAAS,WAAmB,GAAA;AAE1B,EAAA,MAAM,mBAAsB,GAAA;AAAA,IAC1BC,eAAA,CAAK,OAAQ,CAAA,SAAA,EAAW,mCAAmC,CAAA;AAAA,IAC3DA,eAAA,CAAK,OAAQ,CAAA,SAAA,EAAW,sCAAsC,CAAA;AAAA,IAC9DA,eAAA,CAAK,OAAQ,CAAA,SAAA,EAAW,2CAA2C,CAAA;AAAA,IACnEA,eAAA,CAAK,OAAQ,CAAA,SAAA,EAAW,8CAA8C,CAAA;AAAA,IACtEA,eAAA,CAAK,OAAQ,CAAA,SAAA,EAAW,yCAAyC,CAAA;AAAA,IACjEA,eAAA,CAAK,OAAQ,CAAA,SAAA,EAAW,4CAA4C,CAAA;AAAA,GACtE,CAAA;AAEA,EAAA,IAAI,cAA+B,GAAA,IAAA,CAAA;AACnC,EAAA,KAAA,MAAW,aAAa,mBAAqB,EAAA;AAC3C,IAAI,IAAAC,aAAA,CAAG,UAAW,CAAA,SAAS,CAAG,EAAA;AAC5B,MAAI,IAAA;AAEF,QAAA,OAAO,QAAQ,SAAS,CAAA,CAAA;AAAA,eACjB,GAAc,EAAA;AACrB,QAAA,cAAA,GAAiB,eAAe,KAAQ,GAAA,GAAA,GAAM,IAAI,KAAM,CAAA,MAAA,CAAO,GAAG,CAAC,CAAA,CAAA;AAAA,OACrE;AAAA,KACF;AAAA,GACF;AAEA,EAAA,IAAI,cAAgB,EAAA;AAClB,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,yCAAA,EAA4C,eAAe,OAAO,CAAA;AAAA,OAAA,EACtD,eAAe,KAAK,CAAA,CAAA;AAAA,KAClC,CAAA;AAAA,GACF;AAGA,EAAA,MAAM,UAAU,cAAe,EAAA,CAAA;AAC/B,EAAA,IAAI,OAAS,EAAA;AACX,IAAI,IAAA;AAEF,MAAA,OAAO,QAAQ,OAAO,CAAA,CAAA;AAAA,aACf,GAAc,EAAA;AACrB,MAAA,MAAM,WAAW,GAAe,YAAA,KAAA,GAAQ,GAAI,CAAA,OAAA,GAAU,OAAO,GAAG,CAAA,CAAA;AAChE,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,CAAA,iDAAA,EAAoD,QAAQ,QAAQ,CAAA,EAAA,EAAK,QAAQ,IAAI,CAAA,yBAAA,EAC1D,OAAO,CAAA,+IAAA,EAEsB,QAAQ,CAAA,CAAA,CAAA;AAAA,OAClE,CAAA;AAAA,KACF;AAAA,GACF;AAEA,EAAA,MAAM,IAAI,KAAA;AAAA,IACR,CAA2D,wDAAA,EAAA,OAAA,CAAQ,QAAQ,CAAA,EAAA,EAAK,QAAQ,IAAI,CAAA,sDAAA,CAAA;AAAA,GAE9F,CAAA;AACF,CAAA;AAGA,MAAM,kBAAuB,WAAY;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../../../src/lib/index.ts"],"sourcesContent":["import nodeDataChannel from './node-datachannel';\nimport _DataChannelStream from './datachannel-stream';\nimport { WebSocketServer } from './websocket-server';\nimport {\n Channel,\n DataChannelInitConfig,\n DescriptionType,\n Direction,\n LogLevel,\n NalUnitSeparator,\n ObuPacketization,\n RtcConfig,\n RTCIceConnectionState,\n RTCIceGatheringState,\n RTCPeerConnectionState,\n RTCSignalingState,\n SctpSettings,\n SelectedCandidateInfo,\n} from './types';\nimport { WebSocket } from './websocket';\nimport type { CertificateFingerprint, IceUdpMuxRequest, LocalDescriptionInit } from './types';\n\nexport function preload(): void {\n nodeDataChannel.preload();\n}\nexport function initLogger(level: LogLevel, cb?: (level: LogLevel, message: string) => void): void {\n nodeDataChannel.initLogger(level, cb);\n}\nexport function cleanup(): void {\n nodeDataChannel.cleanup();\n}\nexport function setSctpSettings(settings: SctpSettings): void {\n nodeDataChannel.setSctpSettings(settings);\n}\nexport function getLibraryVersion(): string {\n return nodeDataChannel.getLibraryVersion();\n}\n\nexport interface Audio {\n addAudioCodec(payloadType: number, codec: string, profile?: string): void;\n addOpusCodec(payloadType: number, profile?: string): string;\n direction(): Direction;\n generateSdp(eol: string, addr: string, port: number): string;\n mid(): string;\n setDirection(dir: Direction): void;\n description(): string;\n removeFormat(fmt: string): void;\n addSSRC(ssrc: number, name?: string, msid?: string, trackID?: string): void;\n removeSSRC(ssrc: number): void;\n replaceSSRC(oldSsrc: number, ssrc: number, name?: string, msid?: string, trackID?: string): void;\n hasSSRC(ssrc: number): boolean;\n getSSRCs(): number[];\n getCNameForSsrc(ssrc: number): string;\n setBitrate(bitRate: number): void;\n getBitrate(): number;\n hasPayloadType(payloadType: number): boolean;\n addRTXCodec(payloadType: number, originalPayloadType: number, clockRate: number): void;\n addRTPMap(): void;\n parseSdpLine(line: string): void;\n}\nexport const Audio: {\n new (mid: string, dir: Direction): Audio;\n} = nodeDataChannel.Audio;\n\nexport interface Video {\n addVideoCodec(payloadType: number, codec: string, profile?: string): void;\n addH264Codec(payloadType: number, profile?: string): void;\n addH265Codec(payloadType: number): void;\n addVP8Codec(payloadType: number): void;\n addVP9Codec(payloadType: number): void;\n addAV1Codec(payloadType: number): void;\n direction(): Direction;\n generateSdp(eol: string, addr: string, port: number): string;\n mid(): string;\n setDirection(dir: Direction): void;\n description(): string;\n removeFormat(fmt: string): void;\n addSSRC(ssrc: number, name?: string, msid?: string, trackID?: string): void;\n removeSSRC(ssrc: number): void;\n replaceSSRC(oldSsrc: number, ssrc: number, name?: string, msid?: string, trackID?: string): void;\n hasSSRC(ssrc: number): boolean;\n getSSRCs(): number[];\n getCNameForSsrc(ssrc: number): string;\n setBitrate(bitRate: number): void;\n getBitrate(): number;\n hasPayloadType(payloadType: number): boolean;\n addRTXCodec(payloadType: number, originalPayloadType: number, clockRate: number): void;\n addRTPMap(): void;\n parseSdpLine(line: string): void;\n}\nexport const Video: {\n new (mid: string, dir: Direction): Video;\n} = nodeDataChannel.Video;\n\nexport interface Track {\n direction(): Direction;\n mid(): string;\n type(): string;\n close(): void;\n sendMessage(msg: string): boolean;\n sendMessageBinary(buffer: Buffer): boolean;\n isOpen(): boolean;\n isClosed(): boolean;\n bufferedAmount(): number;\n maxMessageSize(): number;\n requestBitrate(bitRate: number): boolean;\n setBufferedAmountLowThreshold(newSize: number): void;\n requestKeyframe(): boolean;\n setMediaHandler(handler: MediaHandler): void;\n onOpen(cb: () => void): void;\n onClosed(cb: () => void): void;\n onError(cb: (err: string) => void): void;\n onMessage(cb: (msg: Buffer) => void): void;\n}\nexport const Track: {\n new (): Track;\n} = nodeDataChannel.Track;\n\nexport interface DataChannel extends Channel {\n getLabel(): string;\n getId(): number;\n getProtocol(): string;\n\n // Channel implementation\n close(): void;\n sendMessage(msg: string): boolean;\n sendMessageBinary(buffer: Buffer | Uint8Array): boolean;\n isOpen(): boolean;\n bufferedAmount(): number;\n maxMessageSize(): number;\n setBufferedAmountLowThreshold(newSize: number): void;\n onOpen(cb: () => void): void;\n onClosed(cb: () => void): void;\n onError(cb: (err: string) => void): void;\n onBufferedAmountLow(cb: () => void): void;\n onMessage(cb: (msg: string | Buffer | ArrayBuffer) => void): void;\n}\nexport const DataChannel: {\n // DataChannel implementation\n} = nodeDataChannel.DataChannel;\n\nexport interface PeerConnection {\n close(): void;\n setLocalDescription(type?: DescriptionType, init?: LocalDescriptionInit): void;\n setRemoteDescription(sdp: string, type: DescriptionType): void;\n localDescription(): { type: DescriptionType; sdp: string } | null;\n remoteDescription(): { type: DescriptionType; sdp: string } | null;\n remoteFingerprint(): CertificateFingerprint;\n addRemoteCandidate(candidate: string, mid: string): void;\n createDataChannel(label: string, config?: DataChannelInitConfig): DataChannel;\n addTrack(media: Video | Audio): Track;\n hasMedia(): boolean;\n state(): RTCPeerConnectionState;\n iceState(): RTCIceConnectionState;\n signalingState(): RTCSignalingState;\n gatheringState(): RTCIceGatheringState;\n onLocalDescription(cb: (sdp: string, type: DescriptionType) => void): void;\n onLocalCandidate(cb: (candidate: string, mid: string) => void): void;\n onStateChange(cb: (state: string) => void): void;\n onIceStateChange(cb: (state: string) => void): void;\n onSignalingStateChange(cb: (state: string) => void): void;\n onGatheringStateChange(cb: (state: string) => void): void;\n onDataChannel(cb: (dc: DataChannel) => void): void;\n onTrack(cb: (track: Track) => void): void;\n bytesSent(): number;\n bytesReceived(): number;\n rtt(): number;\n getSelectedCandidatePair(): {\n local: SelectedCandidateInfo;\n remote: SelectedCandidateInfo;\n } | null;\n maxDataChannelId(): number;\n maxMessageSize(): number;\n}\nexport const PeerConnection: {\n new (peerName: string, config: RtcConfig): PeerConnection;\n} = nodeDataChannel.PeerConnection;\n\nexport interface IceUdpMuxListener {\n address?: string;\n port: number;\n stop(): void;\n onUnhandledStunRequest(cb: (req: IceUdpMuxRequest) => void): void;\n}\nexport const IceUdpMuxListener: {\n new (port: number, address?: string): IceUdpMuxListener;\n} = nodeDataChannel.IceUdpMuxListener;\n\nexport interface RtpPacketizationConfig {\n playoutDelayId: number,\n playoutDelayMin: number,\n playoutDelayMax: number,\n timestamp: number,\n get clockRate(): number\n}\n\nexport const RtpPacketizationConfig: {\n new(ssrc: number, cname: string, payloadType: number, clockRate: number, videoOrientationId?: number): RtpPacketizationConfig\n} = nodeDataChannel.RtpPacketizationConfig\n\nexport interface MediaHandler {\n addToChain(handler: MediaHandler): void\n}\n\nexport interface PacingHandler extends MediaHandler {}\n\nexport const PacingHandler: {\n new (bitsPerSecond: number, sendInterval: number): PacingHandler;\n} = nodeDataChannel.PacingHandler;\n\nexport interface RtcpReceivingSession extends MediaHandler {}\n\nexport const RtcpReceivingSession: {\n new (): RtcpReceivingSession;\n} = nodeDataChannel.RtcpReceivingSession;\n\nexport interface RtcpNackResponder extends MediaHandler {}\n\nexport const RtcpNackResponder: {\n new (maxSize?: number): RtcpNackResponder\n} = nodeDataChannel.RtcpNackResponder;\n\nexport interface RtcpSrReporter extends MediaHandler {\n get rtpConfig(): RtpPacketizationConfig\n}\n\nexport const RtcpSrReporter: {\n new (rtpConfig: RtpPacketizationConfig): RtcpSrReporter\n} = nodeDataChannel.RtcpSrReporter;\n\nexport interface RtpPacketizer extends MediaHandler {\n get rtpConfig(): RtpPacketizationConfig\n}\n\nexport const RtpPacketizer: {\n new (rtpConfig: RtpPacketizationConfig): RtpPacketizer\n} = nodeDataChannel.RtpPacketizer;\n\nexport interface H264RtpPacketizer extends RtpPacketizer {}\n\nexport const H264RtpPacketizer: {\n new (separator: NalUnitSeparator, rtpConfig: RtpPacketizationConfig, maxFragmentSize?: number): H264RtpPacketizer\n} = nodeDataChannel.H264RtpPacketizer\n\nexport interface H265RtpPacketizer extends RtpPacketizer {}\n\nexport const H265RtpPacketizer: {\n new (separator: NalUnitSeparator, rtpConfig: RtpPacketizationConfig, maxFragmentSize?: number): H265RtpPacketizer\n} = nodeDataChannel.H265RtpPacketizer\n\nexport interface AV1RtpPacketizer extends RtpPacketizer {}\n\nexport const AV1RtpPacketizer: {\n new (packetization: ObuPacketization, rtpConfig: RtpPacketizationConfig, maxFragmentSize?: number): AV1RtpPacketizer\n} = nodeDataChannel.AV1RtpPacketizer\n\nexport { WebSocketServer } from './websocket-server';\nexport { WebSocket } from './websocket';\n\nexport const DataChannelStream = _DataChannelStream;\n\nexport default {\n initLogger,\n cleanup,\n preload,\n setSctpSettings,\n getLibraryVersion,\n PacingHandler,\n RtcpReceivingSession,\n RtcpNackResponder,\n RtcpSrReporter,\n RtpPacketizationConfig,\n RtpPacketizer,\n H264RtpPacketizer,\n H265RtpPacketizer,\n AV1RtpPacketizer,\n Track,\n Video,\n Audio,\n DataChannel,\n PeerConnection,\n WebSocket,\n WebSocketServer,\n DataChannelStream,\n IceUdpMuxListener,\n};\n\n// Types\n// https://github.com/murat-dogan/node-datachannel/issues/300\nexport * from './types';\n"],"names":["_DataChannelStream"],"mappings":";;;;;AAsBO,SAAS,OAAgB,GAAA;AAC9B,EAAA,eAAA,CAAgB,OAAQ,EAAA,CAAA;AAC1B,CAAA;AACgB,SAAA,UAAA,CAAW,OAAiB,EAAuD,EAAA;AACjG,EAAgB,eAAA,CAAA,UAAA,CAAW,OAAO,EAAE,CAAA,CAAA;AACtC,CAAA;AACO,SAAS,OAAgB,GAAA;AAC9B,EAAA,eAAA,CAAgB,OAAQ,EAAA,CAAA;AAC1B,CAAA;AACO,SAAS,gBAAgB,QAA8B,EAAA;AAC5D,EAAA,eAAA,CAAgB,gBAAgB,QAAQ,CAAA,CAAA;AAC1C,CAAA;AACO,SAAS,iBAA4B,GAAA;AAC1C,EAAA,OAAO,gBAAgB,iBAAkB,EAAA,CAAA;AAC3C,CAAA;AAwBO,MAAM,QAET,eAAgB,CAAA,MAAA;AA4Bb,MAAM,QAET,eAAgB,CAAA,MAAA;AAsBb,MAAM,QAET,eAAgB,CAAA,MAAA;AAqBb,MAAM,cAET,eAAgB,CAAA,YAAA;AAmCb,MAAM,iBAET,eAAgB,CAAA,eAAA;AAQb,MAAM,oBAET,eAAgB,CAAA,kBAAA;AAUb,MAAM,yBAET,eAAgB,CAAA,uBAAA;AAQb,MAAM,gBAET,eAAgB,CAAA,cAAA;AAIb,MAAM,uBAET,eAAgB,CAAA,qBAAA;AAIb,MAAM,oBAET,eAAgB,CAAA,kBAAA;AAMb,MAAM,iBAET,eAAgB,CAAA,eAAA;AAMb,MAAM,gBAET,eAAgB,CAAA,cAAA;AAIb,MAAM,oBAET,eAAgB,CAAA,kBAAA;AAIb,MAAM,oBAET,eAAgB,CAAA,kBAAA;AAIb,MAAM,mBAET,eAAgB,CAAA,iBAAA;AAKb,MAAM,iBAAoB,GAAAA,oBAAA;AAEjC,QAAe;AAAA,EACb,UAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACA,eAAA;AAAA,EACA,iBAAA;AAAA,EACA,aAAA;AAAA,EACA,oBAAA;AAAA,EACA,iBAAA;AAAA,EACA,cAAA;AAAA,EACA,sBAAA;AAAA,EACA,aAAA;AAAA,EACA,iBAAA;AAAA,EACA,iBAAA;AAAA,EACA,gBAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA,EACA,WAAA;AAAA,EACA,cAAA;AAAA,EACA,SAAA;AAAA,EACA,eAAA;AAAA,EACA,iBAAA;AAAA,EACA,iBAAA;AACF,CAAA;;;;"}
1
+ {"version":3,"file":"index.mjs","sources":["../../../src/lib/index.ts"],"sourcesContent":["import nodeDataChannel from './node-datachannel';\nimport _DataChannelStream from './datachannel-stream';\nimport { WebSocketServer } from './websocket-server';\nimport {\n Channel,\n DataChannelInitConfig,\n DescriptionType,\n Direction,\n LogLevel,\n NalUnitSeparator,\n ObuPacketization,\n RtcConfig,\n RTCIceConnectionState,\n RTCIceGatheringState,\n RTCPeerConnectionState,\n RTCSignalingState,\n SctpSettings,\n SelectedCandidateInfo,\n} from './types';\nimport { WebSocket } from './websocket';\nimport type { CertificateFingerprint, IceUdpMuxRequest, LocalDescriptionInit } from './types';\n\nexport function preload(): void {\n nodeDataChannel.preload();\n}\nexport function initLogger(level: LogLevel, cb?: (level: LogLevel, message: string) => void): void {\n nodeDataChannel.initLogger(level, cb);\n}\nexport function cleanup(): void {\n nodeDataChannel.cleanup();\n}\nexport function setSctpSettings(settings: SctpSettings): void {\n nodeDataChannel.setSctpSettings(settings);\n}\nexport function getLibraryVersion(): string {\n return nodeDataChannel.getLibraryVersion();\n}\n\nexport interface Audio {\n addAudioCodec(payloadType: number, codec: string, profile?: string): void;\n addOpusCodec(payloadType: number, profile?: string): string;\n direction(): Direction;\n generateSdp(eol: string, addr: string, port: number): string;\n mid(): string;\n setDirection(dir: Direction): void;\n description(): string;\n removeFormat(fmt: string): void;\n addSSRC(ssrc: number, name?: string, msid?: string, trackID?: string): void;\n removeSSRC(ssrc: number): void;\n replaceSSRC(oldSsrc: number, ssrc: number, name?: string, msid?: string, trackID?: string): void;\n hasSSRC(ssrc: number): boolean;\n getSSRCs(): number[];\n getCNameForSsrc(ssrc: number): string;\n setBitrate(bitRate: number): void;\n getBitrate(): number;\n hasPayloadType(payloadType: number): boolean;\n addRTXCodec(payloadType: number, originalPayloadType: number, clockRate: number): void;\n addRTPMap(): void;\n parseSdpLine(line: string): void;\n}\nexport const Audio: {\n new (mid: string, dir: Direction): Audio;\n} = nodeDataChannel.Audio;\n\nexport interface Video {\n addVideoCodec(payloadType: number, codec: string, profile?: string): void;\n addH264Codec(payloadType: number, profile?: string): void;\n addH265Codec(payloadType: number): void;\n addVP8Codec(payloadType: number): void;\n addVP9Codec(payloadType: number): void;\n addAV1Codec(payloadType: number): void;\n direction(): Direction;\n generateSdp(eol: string, addr: string, port: number): string;\n mid(): string;\n setDirection(dir: Direction): void;\n description(): string;\n removeFormat(fmt: string): void;\n addSSRC(ssrc: number, name?: string, msid?: string, trackID?: string): void;\n removeSSRC(ssrc: number): void;\n replaceSSRC(oldSsrc: number, ssrc: number, name?: string, msid?: string, trackID?: string): void;\n hasSSRC(ssrc: number): boolean;\n getSSRCs(): number[];\n getCNameForSsrc(ssrc: number): string;\n setBitrate(bitRate: number): void;\n getBitrate(): number;\n hasPayloadType(payloadType: number): boolean;\n addRTXCodec(payloadType: number, originalPayloadType: number, clockRate: number): void;\n addRTPMap(): void;\n parseSdpLine(line: string): void;\n}\nexport const Video: {\n new (mid: string, dir: Direction): Video;\n} = nodeDataChannel.Video;\n\nexport interface Track {\n direction(): Direction;\n mid(): string;\n type(): string;\n close(): void;\n sendMessage(msg: string): boolean;\n sendMessageBinary(buffer: Buffer): boolean;\n isOpen(): boolean;\n isClosed(): boolean;\n bufferedAmount(): number;\n maxMessageSize(): number;\n requestBitrate(bitRate: number): boolean;\n setBufferedAmountLowThreshold(newSize: number): void;\n requestKeyframe(): boolean;\n setMediaHandler(handler: MediaHandler): void;\n onOpen(cb: () => void): void;\n onClosed(cb: () => void): void;\n onError(cb: (err: string) => void): void;\n onMessage(cb: (msg: Buffer) => void): void;\n}\nexport const Track: {\n new (): Track;\n} = nodeDataChannel.Track;\n\nexport interface DataChannel extends Channel {\n getLabel(): string;\n getId(): number;\n getProtocol(): string;\n\n // Channel implementation\n close(): void;\n sendMessage(msg: string): boolean;\n sendMessageBinary(buffer: Buffer | Uint8Array): boolean;\n isOpen(): boolean;\n bufferedAmount(): number;\n maxMessageSize(): number;\n setBufferedAmountLowThreshold(newSize: number): void;\n onOpen(cb: () => void): void;\n onClosed(cb: () => void): void;\n onError(cb: (err: string) => void): void;\n onBufferedAmountLow(cb: () => void): void;\n onMessage(cb: (msg: string | Buffer | ArrayBuffer) => void): void;\n}\nexport const DataChannel: {\n // DataChannel implementation\n} = nodeDataChannel.DataChannel;\n\nexport interface PeerConnection {\n close(): void;\n setLocalDescription(type?: DescriptionType, init?: LocalDescriptionInit): void;\n setRemoteDescription(sdp: string, type: DescriptionType): void;\n localDescription(): { type: DescriptionType; sdp: string } | null;\n remoteDescription(): { type: DescriptionType; sdp: string } | null;\n remoteFingerprint(): CertificateFingerprint;\n addRemoteCandidate(candidate: string, mid: string): void;\n createDataChannel(label: string, config?: DataChannelInitConfig): DataChannel;\n addTrack(media: Video | Audio): Track;\n hasMedia(): boolean;\n state(): RTCPeerConnectionState;\n iceState(): RTCIceConnectionState;\n signalingState(): RTCSignalingState;\n gatheringState(): RTCIceGatheringState;\n onLocalDescription(cb: (sdp: string, type: DescriptionType) => void): void;\n onLocalCandidate(cb: (candidate: string, mid: string) => void): void;\n onStateChange(cb: (state: string) => void): void;\n onIceStateChange(cb: (state: string) => void): void;\n onSignalingStateChange(cb: (state: string) => void): void;\n onGatheringStateChange(cb: (state: string) => void): void;\n onDataChannel(cb: (dc: DataChannel) => void): void;\n onTrack(cb: (track: Track) => void): void;\n bytesSent(): number;\n bytesReceived(): number;\n rtt(): number;\n getSelectedCandidatePair(): {\n local: SelectedCandidateInfo;\n remote: SelectedCandidateInfo;\n } | null;\n maxDataChannelId(): number;\n maxMessageSize(): number;\n}\nexport const PeerConnection: {\n new (peerName: string, config: RtcConfig): PeerConnection;\n} = nodeDataChannel.PeerConnection;\n\nexport interface IceUdpMuxListener {\n address(): string | undefined;\n port(): number;\n stop(): void;\n onUnhandledStunRequest(cb: (req: IceUdpMuxRequest) => void): void;\n}\nexport const IceUdpMuxListener: {\n new (port: number, address?: string): IceUdpMuxListener;\n} = nodeDataChannel.IceUdpMuxListener;\n\nexport interface RtpPacketizationConfig {\n playoutDelayId: number,\n playoutDelayMin: number,\n playoutDelayMax: number,\n timestamp: number,\n get clockRate(): number\n}\n\nexport const RtpPacketizationConfig: {\n new(ssrc: number, cname: string, payloadType: number, clockRate: number, videoOrientationId?: number): RtpPacketizationConfig\n} = nodeDataChannel.RtpPacketizationConfig\n\nexport interface MediaHandler {\n addToChain(handler: MediaHandler): void\n}\n\nexport interface PacingHandler extends MediaHandler {}\n\nexport const PacingHandler: {\n new (bitsPerSecond: number, sendInterval: number): PacingHandler;\n} = nodeDataChannel.PacingHandler;\n\nexport interface RtcpReceivingSession extends MediaHandler {}\n\nexport const RtcpReceivingSession: {\n new (): RtcpReceivingSession;\n} = nodeDataChannel.RtcpReceivingSession;\n\nexport interface RtcpNackResponder extends MediaHandler {}\n\nexport const RtcpNackResponder: {\n new (maxSize?: number): RtcpNackResponder\n} = nodeDataChannel.RtcpNackResponder;\n\nexport interface RtcpSrReporter extends MediaHandler {\n get rtpConfig(): RtpPacketizationConfig\n}\n\nexport const RtcpSrReporter: {\n new (rtpConfig: RtpPacketizationConfig): RtcpSrReporter\n} = nodeDataChannel.RtcpSrReporter;\n\nexport interface RtpPacketizer extends MediaHandler {\n get rtpConfig(): RtpPacketizationConfig\n}\n\nexport const RtpPacketizer: {\n new (rtpConfig: RtpPacketizationConfig): RtpPacketizer\n} = nodeDataChannel.RtpPacketizer;\n\nexport interface H264RtpPacketizer extends RtpPacketizer {}\n\nexport const H264RtpPacketizer: {\n new (separator: NalUnitSeparator, rtpConfig: RtpPacketizationConfig, maxFragmentSize?: number): H264RtpPacketizer\n} = nodeDataChannel.H264RtpPacketizer\n\nexport interface H265RtpPacketizer extends RtpPacketizer {}\n\nexport const H265RtpPacketizer: {\n new (separator: NalUnitSeparator, rtpConfig: RtpPacketizationConfig, maxFragmentSize?: number): H265RtpPacketizer\n} = nodeDataChannel.H265RtpPacketizer\n\nexport interface AV1RtpPacketizer extends RtpPacketizer {}\n\nexport const AV1RtpPacketizer: {\n new (packetization: ObuPacketization, rtpConfig: RtpPacketizationConfig, maxFragmentSize?: number): AV1RtpPacketizer\n} = nodeDataChannel.AV1RtpPacketizer\n\nexport { WebSocketServer } from './websocket-server';\nexport { WebSocket } from './websocket';\n\nexport const DataChannelStream = _DataChannelStream;\n\nexport default {\n initLogger,\n cleanup,\n preload,\n setSctpSettings,\n getLibraryVersion,\n PacingHandler,\n RtcpReceivingSession,\n RtcpNackResponder,\n RtcpSrReporter,\n RtpPacketizationConfig,\n RtpPacketizer,\n H264RtpPacketizer,\n H265RtpPacketizer,\n AV1RtpPacketizer,\n Track,\n Video,\n Audio,\n DataChannel,\n PeerConnection,\n WebSocket,\n WebSocketServer,\n DataChannelStream,\n IceUdpMuxListener,\n};\n\n// Types\n// https://github.com/murat-dogan/node-datachannel/issues/300\nexport * from './types';\n"],"names":["_DataChannelStream"],"mappings":";;;;;AAsBO,SAAS,OAAgB,GAAA;AAC9B,EAAA,eAAA,CAAgB,OAAQ,EAAA,CAAA;AAC1B,CAAA;AACgB,SAAA,UAAA,CAAW,OAAiB,EAAuD,EAAA;AACjG,EAAgB,eAAA,CAAA,UAAA,CAAW,OAAO,EAAE,CAAA,CAAA;AACtC,CAAA;AACO,SAAS,OAAgB,GAAA;AAC9B,EAAA,eAAA,CAAgB,OAAQ,EAAA,CAAA;AAC1B,CAAA;AACO,SAAS,gBAAgB,QAA8B,EAAA;AAC5D,EAAA,eAAA,CAAgB,gBAAgB,QAAQ,CAAA,CAAA;AAC1C,CAAA;AACO,SAAS,iBAA4B,GAAA;AAC1C,EAAA,OAAO,gBAAgB,iBAAkB,EAAA,CAAA;AAC3C,CAAA;AAwBO,MAAM,QAET,eAAgB,CAAA,MAAA;AA4Bb,MAAM,QAET,eAAgB,CAAA,MAAA;AAsBb,MAAM,QAET,eAAgB,CAAA,MAAA;AAqBb,MAAM,cAET,eAAgB,CAAA,YAAA;AAmCb,MAAM,iBAET,eAAgB,CAAA,eAAA;AAQb,MAAM,oBAET,eAAgB,CAAA,kBAAA;AAUb,MAAM,yBAET,eAAgB,CAAA,uBAAA;AAQb,MAAM,gBAET,eAAgB,CAAA,cAAA;AAIb,MAAM,uBAET,eAAgB,CAAA,qBAAA;AAIb,MAAM,oBAET,eAAgB,CAAA,kBAAA;AAMb,MAAM,iBAET,eAAgB,CAAA,eAAA;AAMb,MAAM,gBAET,eAAgB,CAAA,cAAA;AAIb,MAAM,oBAET,eAAgB,CAAA,kBAAA;AAIb,MAAM,oBAET,eAAgB,CAAA,kBAAA;AAIb,MAAM,mBAET,eAAgB,CAAA,iBAAA;AAKb,MAAM,iBAAoB,GAAAA,oBAAA;AAEjC,QAAe;AAAA,EACb,UAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACA,eAAA;AAAA,EACA,iBAAA;AAAA,EACA,aAAA;AAAA,EACA,oBAAA;AAAA,EACA,iBAAA;AAAA,EACA,cAAA;AAAA,EACA,sBAAA;AAAA,EACA,aAAA;AAAA,EACA,iBAAA;AAAA,EACA,iBAAA;AAAA,EACA,gBAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA,EACA,WAAA;AAAA,EACA,cAAA;AAAA,EACA,SAAA;AAAA,EACA,eAAA;AAAA,EACA,iBAAA;AAAA,EACA,iBAAA;AACF,CAAA;;;;"}
@@ -1,3 +1,7 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import { familySync, MUSL } from 'detect-libc';
4
+
1
5
 
2
6
  // -- Shims --
3
7
  import cjsUrl from 'node:url';
@@ -6,7 +10,69 @@ import cjsModule from 'node:module';
6
10
  const __filename = cjsUrl.fileURLToPath(import.meta.url);
7
11
  const __dirname = cjsPath.dirname(__filename);
8
12
  const require = cjsModule.createRequire(import.meta.url);
9
- const nodeDataChannel = require("../../../build/Release/node_datachannel.node");
13
+ function getPackageName() {
14
+ const { platform, arch } = process;
15
+ if (platform === "linux") {
16
+ const libc = familySync();
17
+ if (libc === MUSL) {
18
+ if (arch === "x64") return "@node-datachannel/linux-x64-musl";
19
+ if (arch === "arm64") return "@node-datachannel/linux-arm64-musl";
20
+ } else {
21
+ if (arch === "x64") return "@node-datachannel/linux-x64-gnu";
22
+ if (arch === "arm64") return "@node-datachannel/linux-arm64-gnu";
23
+ }
24
+ } else if (platform === "darwin") {
25
+ if (arch === "arm64") return "@node-datachannel/darwin-arm64";
26
+ if (arch === "x64") return "@node-datachannel/darwin-x64";
27
+ } else if (platform === "win32") {
28
+ if (arch === "x64") return "@node-datachannel/win32-x64-msvc";
29
+ if (arch === "arm64") return "@node-datachannel/win32-arm64-msvc";
30
+ } else if (platform === "android") {
31
+ if (arch === "arm64") return "@node-datachannel/android-arm64";
32
+ }
33
+ return null;
34
+ }
35
+ function loadBinding() {
36
+ const candidateLocalPaths = [
37
+ path.resolve(__dirname, "../../build/node_datachannel.node"),
38
+ path.resolve(__dirname, "../../../build/node_datachannel.node"),
39
+ path.resolve(__dirname, "../../build/Release/node_datachannel.node"),
40
+ path.resolve(__dirname, "../../../build/Release/node_datachannel.node"),
41
+ path.resolve(__dirname, "../../build/Debug/node_datachannel.node"),
42
+ path.resolve(__dirname, "../../../build/Debug/node_datachannel.node")
43
+ ];
44
+ let localLoadError = null;
45
+ for (const candidate of candidateLocalPaths) {
46
+ if (fs.existsSync(candidate)) {
47
+ try {
48
+ return require(candidate);
49
+ } catch (err) {
50
+ localLoadError = err instanceof Error ? err : new Error(String(err));
51
+ }
52
+ }
53
+ }
54
+ if (localLoadError) {
55
+ throw new Error(
56
+ `Failed to load local native addon build: ${localLoadError.message}
57
+ Stack: ${localLoadError.stack}`
58
+ );
59
+ }
60
+ const pkgName = getPackageName();
61
+ if (pkgName) {
62
+ try {
63
+ return require(pkgName);
64
+ } catch (err) {
65
+ const errorMsg = err instanceof Error ? err.message : String(err);
66
+ throw new Error(
67
+ `Cannot load native addon for node-datachannel on ${process.platform} (${process.arch}). Attempted to require "${pkgName}". Please ensure optionalDependencies are installed (avoid --no-optional / --omit=optional) or compile locally with "npm run compile". (Error: ${errorMsg})`
68
+ );
69
+ }
70
+ }
71
+ throw new Error(
72
+ `Unsupported platform/architecture for node-datachannel: ${process.platform} (${process.arch}). Please compile from source using "npm run compile".`
73
+ );
74
+ }
75
+ const nodeDataChannel = loadBinding();
10
76
 
11
77
  export { nodeDataChannel as default };
12
78
  //# sourceMappingURL=node-datachannel.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"node-datachannel.mjs","sources":["../../../src/lib/node-datachannel.ts"],"sourcesContent":["// @ts-expect-error no types\nimport nodeDataChannel = require('../../build/Release/node_datachannel.node');\nexport default nodeDataChannel;\n"],"names":[],"mappings":";;;;;;;;AACA;;"}
1
+ {"version":3,"file":"node-datachannel.mjs","sources":["../../../src/lib/node-datachannel.ts"],"sourcesContent":["import * as fs from 'fs';\nimport * as path from 'path';\nimport { familySync, MUSL } from 'detect-libc';\n\nfunction getPackageName(): string | null {\n const { platform, arch } = process;\n if (platform === 'linux') {\n const libc = familySync();\n if (libc === MUSL) {\n if (arch === 'x64') return '@node-datachannel/linux-x64-musl';\n if (arch === 'arm64') return '@node-datachannel/linux-arm64-musl';\n } else {\n if (arch === 'x64') return '@node-datachannel/linux-x64-gnu';\n if (arch === 'arm64') return '@node-datachannel/linux-arm64-gnu';\n }\n } else if (platform === 'darwin') {\n if (arch === 'arm64') return '@node-datachannel/darwin-arm64';\n if (arch === 'x64') return '@node-datachannel/darwin-x64';\n } else if (platform === 'win32') {\n if (arch === 'x64') return '@node-datachannel/win32-x64-msvc';\n if (arch === 'arm64') return '@node-datachannel/win32-arm64-msvc';\n } else if (platform === 'android') {\n if (arch === 'arm64') return '@node-datachannel/android-arm64';\n }\n return null;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction loadBinding(): any {\n // 1. Try local build candidate paths for development, tests, and source builds\n const candidateLocalPaths = [\n path.resolve(__dirname, '../../build/node_datachannel.node'),\n path.resolve(__dirname, '../../../build/node_datachannel.node'),\n path.resolve(__dirname, '../../build/Release/node_datachannel.node'),\n path.resolve(__dirname, '../../../build/Release/node_datachannel.node'),\n path.resolve(__dirname, '../../build/Debug/node_datachannel.node'),\n path.resolve(__dirname, '../../../build/Debug/node_datachannel.node'),\n ];\n\n let localLoadError: Error | null = null;\n for (const candidate of candidateLocalPaths) {\n if (fs.existsSync(candidate)) {\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n return require(candidate);\n } catch (err: unknown) {\n localLoadError = err instanceof Error ? err : new Error(String(err));\n }\n }\n }\n\n if (localLoadError) {\n throw new Error(\n `Failed to load local native addon build: ${localLoadError.message}\\n` +\n `Stack: ${localLoadError.stack}`\n );\n }\n\n // 2. Try platform-specific optionalDependencies package\n const pkgName = getPackageName();\n if (pkgName) {\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n return require(pkgName);\n } catch (err: unknown) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n throw new Error(\n `Cannot load native addon for node-datachannel on ${process.platform} (${process.arch}). ` +\n `Attempted to require \"${pkgName}\". ` +\n `Please ensure optionalDependencies are installed (avoid --no-optional / --omit=optional) ` +\n `or compile locally with \"npm run compile\". (Error: ${errorMsg})`\n );\n }\n }\n\n throw new Error(\n `Unsupported platform/architecture for node-datachannel: ${process.platform} (${process.arch}). ` +\n `Please compile from source using \"npm run compile\".`\n );\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst nodeDataChannel: any = loadBinding();\nexport default nodeDataChannel;\n"],"names":[],"mappings":";;;;;;;;;;;;AAIA;AACE;AACA;AACE;AACA;AACE;AACA;AAA6B;AAE7B;AACA;AAA6B;AAC/B;AAEA;AACA;AAA2B;AAE3B;AACA;AAA6B;AAE7B;AAA6B;AAE/B;AACF;AAGA;AAEE;AAA4B;AACiC;AACG;AACK;AACG;AACL;AACG;AAGtE;AACA;AACE;AACE;AAEE;AAAwB;AAExB;AAAmE;AACrE;AACF;AAGF;AACE;AAAU;AAC0D;AAClC;AAClC;AAIF;AACA;AACE;AAEE;AAAsB;AAEtB;AACA;AAAU;AAIwD;AAClE;AACF;AAGF;AAAU;AACoF;AAGhG;AAGA;;"}
@@ -147,8 +147,8 @@ declare const PeerConnection: {
147
147
  new (peerName: string, config: RtcConfig): PeerConnection;
148
148
  };
149
149
  interface IceUdpMuxListener {
150
- address?: string;
151
- port: number;
150
+ address(): string | undefined;
151
+ port(): number;
152
152
  stop(): void;
153
153
  onUnhandledStunRequest(cb: (req: IceUdpMuxRequest) => void): void;
154
154
  }
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "@node-datachannel/darwin-arm64",
3
+ "version": "0.33.1",
4
+ "description": "Prebuilt native binary for node-datachannel (macOS Apple Silicon)",
5
+ "main": "node_datachannel.node",
6
+ "files": [
7
+ "node_datachannel.node"
8
+ ],
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/murat-dogan/node-datachannel.git"
12
+ },
13
+ "license": "MPL 2.0",
14
+ "os": [
15
+ "darwin"
16
+ ],
17
+ "cpu": [
18
+ "arm64"
19
+ ]
20
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "@node-datachannel/darwin-x64",
3
+ "version": "0.33.1",
4
+ "description": "Prebuilt native binary for node-datachannel (macOS Intel)",
5
+ "main": "node_datachannel.node",
6
+ "files": [
7
+ "node_datachannel.node"
8
+ ],
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/murat-dogan/node-datachannel.git"
12
+ },
13
+ "license": "MPL 2.0",
14
+ "os": [
15
+ "darwin"
16
+ ],
17
+ "cpu": [
18
+ "x64"
19
+ ]
20
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "@node-datachannel/linux-arm64-gnu",
3
+ "version": "0.33.1",
4
+ "description": "Prebuilt native binary for node-datachannel (linux-arm64-gnu)",
5
+ "main": "node_datachannel.node",
6
+ "files": [
7
+ "node_datachannel.node"
8
+ ],
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/murat-dogan/node-datachannel.git"
12
+ },
13
+ "license": "MPL 2.0",
14
+ "os": [
15
+ "linux"
16
+ ],
17
+ "cpu": [
18
+ "arm64"
19
+ ],
20
+ "libc": [
21
+ "glibc"
22
+ ]
23
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "@node-datachannel/linux-arm64-musl",
3
+ "version": "0.33.1",
4
+ "description": "Prebuilt native binary for node-datachannel (linux-arm64-musl/alpine)",
5
+ "main": "node_datachannel.node",
6
+ "files": [
7
+ "node_datachannel.node"
8
+ ],
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/murat-dogan/node-datachannel.git"
12
+ },
13
+ "license": "MPL 2.0",
14
+ "os": [
15
+ "linux"
16
+ ],
17
+ "cpu": [
18
+ "arm64"
19
+ ],
20
+ "libc": [
21
+ "musl"
22
+ ]
23
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "@node-datachannel/linux-x64-gnu",
3
+ "version": "0.33.1",
4
+ "description": "Prebuilt native binary for node-datachannel (linux-x64-gnu)",
5
+ "main": "node_datachannel.node",
6
+ "files": [
7
+ "node_datachannel.node"
8
+ ],
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/murat-dogan/node-datachannel.git"
12
+ },
13
+ "license": "MPL 2.0",
14
+ "os": [
15
+ "linux"
16
+ ],
17
+ "cpu": [
18
+ "x64"
19
+ ],
20
+ "libc": [
21
+ "glibc"
22
+ ]
23
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "@node-datachannel/linux-x64-musl",
3
+ "version": "0.33.1",
4
+ "description": "Prebuilt native binary for node-datachannel (linux-x64-musl/alpine)",
5
+ "main": "node_datachannel.node",
6
+ "files": [
7
+ "node_datachannel.node"
8
+ ],
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/murat-dogan/node-datachannel.git"
12
+ },
13
+ "license": "MPL 2.0",
14
+ "os": [
15
+ "linux"
16
+ ],
17
+ "cpu": [
18
+ "x64"
19
+ ],
20
+ "libc": [
21
+ "musl"
22
+ ]
23
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "@node-datachannel/win32-arm64-msvc",
3
+ "version": "0.33.1",
4
+ "description": "Prebuilt native binary for node-datachannel (Windows ARM64)",
5
+ "main": "node_datachannel.node",
6
+ "files": [
7
+ "node_datachannel.node"
8
+ ],
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/murat-dogan/node-datachannel.git"
12
+ },
13
+ "license": "MPL 2.0",
14
+ "os": [
15
+ "win32"
16
+ ],
17
+ "cpu": [
18
+ "arm64"
19
+ ]
20
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "@node-datachannel/win32-x64-msvc",
3
+ "version": "0.33.1",
4
+ "description": "Prebuilt native binary for node-datachannel (Windows x64)",
5
+ "main": "node_datachannel.node",
6
+ "files": [
7
+ "node_datachannel.node"
8
+ ],
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/murat-dogan/node-datachannel.git"
12
+ },
13
+ "license": "MPL 2.0",
14
+ "os": [
15
+ "win32"
16
+ ],
17
+ "cpu": [
18
+ "x64"
19
+ ]
20
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-datachannel",
3
- "version": "0.32.3",
3
+ "version": "0.33.1",
4
4
  "description": "WebRTC For Node.js and Electron. libdatachannel node bindings.",
5
5
  "main": "./dist/cjs/lib/index.cjs",
6
6
  "module": "./dist/esm/lib/index.mjs",
@@ -33,24 +33,21 @@
33
33
  "node": ">=18.20.0"
34
34
  },
35
35
  "scripts": {
36
- "install": "prebuild-install -r napi || (npm install --ignore-scripts --production=false && npm run _prebuild)",
37
- "rebuild": "prebuild-install -r napi || cmake-js rebuild",
38
- "install:nice": "npm run clean && npm install --ignore-scripts --production=false && cmake-js configure --CDUSE_NICE=1 && cmake-js build",
39
- "install:gnu": "npm run clean && npm install --ignore-scripts --production=false && cmake-js configure --CDUSE_GNUTLS=1 && cmake-js build",
40
36
  "build": "npm run compile && npm run build:tsc",
41
37
  "compile": "cmake-js build",
38
+ "rebuild": "cmake-js rebuild",
42
39
  "build:debug": "npm run compile:debug && npm run build:tsc",
43
40
  "compile:debug": "cmake-js configure -D && cmake-js build -D",
44
41
  "build:tsc": "rimraf dist && rollup -c",
45
42
  "build:tsc:watch": "rollup -c -w",
46
- "clean": "rimraf dist build",
43
+ "clean": "rimraf dist build npm",
47
44
  "lint": "eslint . --ext .ts --ext .mts",
48
45
  "test": "NODE_OPTIONS=--experimental-vm-modules jest",
49
46
  "test:watch": "NODE_OPTIONS=--experimental-vm-modules jest --watch",
50
47
  "test:wpt": "npm run run:wpt:server & (sleep 8 && (npm run run:wpt:test | tee test/wpt-tests/last-test-results.md) )",
51
48
  "wpt:server": "cd test/wpt-tests/wpt && ./wpt serve",
52
49
  "wpt:test": "ts-node test/wpt-tests/index.ts",
53
- "_prebuild": "prebuild -r napi --backend cmake-js",
50
+ "package:platforms": "node scripts/prepare-platform-packages.js",
54
51
  "prepack": "npm run build:tsc",
55
52
  "prettier": "prettier --write .",
56
53
  "format-cpp": "find src/cpp \\( -name \"*.h\" -o -name \"*.cpp\" \\) -exec clang-format -i \"{}\" \\; "
@@ -97,6 +94,7 @@
97
94
  "@typescript-eslint/eslint-plugin": "^7.17.0",
98
95
  "@typescript-eslint/parser": "^7.17.0",
99
96
  "cmake-js": "^7.3.0",
97
+ "detect-libc": "^2.0.4",
100
98
  "eslint": "^8.57.0",
101
99
  "eslint-config-prettier": "^9.1.0",
102
100
  "eslint-plugin-jest": "^28.6.0",
@@ -104,7 +102,7 @@
104
102
  "jest": "^29.7.0",
105
103
  "jsdom": "^24.1.1",
106
104
  "node-addon-api": "^7.0.0",
107
- "prebuild": "^13.0.1",
105
+ "node-api-headers": "^1.4.0",
108
106
  "prettier": "^3.3.3",
109
107
  "puppeteer": "^22.14.0",
110
108
  "rimraf": "^5.0.9",
@@ -117,6 +115,17 @@
117
115
  "typescript": "5.4"
118
116
  },
119
117
  "dependencies": {
120
- "prebuild-install": "^7.1.3"
118
+ "detect-libc": "^2.0.4"
119
+ },
120
+ "optionalDependencies": {
121
+ "@node-datachannel/android-arm64": "0.33.1",
122
+ "@node-datachannel/darwin-arm64": "0.33.1",
123
+ "@node-datachannel/darwin-x64": "0.33.1",
124
+ "@node-datachannel/linux-arm64-gnu": "0.33.1",
125
+ "@node-datachannel/linux-arm64-musl": "0.33.1",
126
+ "@node-datachannel/linux-x64-gnu": "0.33.1",
127
+ "@node-datachannel/linux-x64-musl": "0.33.1",
128
+ "@node-datachannel/win32-arm64-msvc": "0.33.1",
129
+ "@node-datachannel/win32-x64-msvc": "0.33.1"
121
130
  }
122
131
  }
package/rollup.config.mjs CHANGED
@@ -10,17 +10,12 @@ const external = (id) => {
10
10
  const bundle = (config) => ({
11
11
  ...config,
12
12
  input: 'src/index.ts',
13
- external: ['events','stream'] // <-- suppresses the warning for these built-in modules
13
+ external: ['events', 'stream', 'fs', 'path', 'detect-libc'],
14
14
  });
15
15
 
16
16
  export default [
17
17
  bundle({
18
18
  plugins: [
19
- replace({
20
- include: 'src/lib/node-datachannel.ts',
21
- preventAssignment: true,
22
- "require('../../build": "require('../../../build",
23
- }),
24
19
  esmShim(),
25
20
  esbuild(),
26
21
  ],
@@ -62,8 +62,17 @@ IceUdpMuxListenerWrapper::IceUdpMuxListenerWrapper(const Napi::CallbackInfo &inf
62
62
  mAddress = info[1].As<Napi::String>().ToString();
63
63
  }
64
64
 
65
- iceUdpMuxListenerPtr = std::make_unique<rtc::IceUdpMuxListener>(mPort, mAddress);
66
- instances.insert(this);
65
+ try
66
+ {
67
+ iceUdpMuxListenerPtr = std::make_unique<rtc::IceUdpMuxListener>(mPort, mAddress);
68
+ mPort = iceUdpMuxListenerPtr->port();
69
+ instances.insert(this);
70
+ }
71
+ catch (const std::exception &e)
72
+ {
73
+ Napi::Error::New(env, e.what()).ThrowAsJavaScriptException();
74
+ return;
75
+ }
67
76
  }
68
77
 
69
78
  IceUdpMuxListenerWrapper::~IceUdpMuxListenerWrapper()
@@ -90,6 +99,11 @@ Napi::Value IceUdpMuxListenerWrapper::port(const Napi::CallbackInfo &info)
90
99
  {
91
100
  Napi::Env env = info.Env();
92
101
 
102
+ if (iceUdpMuxListenerPtr)
103
+ {
104
+ return Napi::Number::New(env, iceUdpMuxListenerPtr->port());
105
+ }
106
+
93
107
  return Napi::Number::New(env, mPort);
94
108
  }
95
109
 
package/src/lib/index.ts CHANGED
@@ -177,8 +177,8 @@ export const PeerConnection: {
177
177
  } = nodeDataChannel.PeerConnection;
178
178
 
179
179
  export interface IceUdpMuxListener {
180
- address?: string;
181
- port: number;
180
+ address(): string | undefined;
181
+ port(): number;
182
182
  stop(): void;
183
183
  onUnhandledStunRequest(cb: (req: IceUdpMuxRequest) => void): void;
184
184
  }
@@ -1,3 +1,84 @@
1
- // @ts-expect-error no types
2
- import nodeDataChannel = require('../../build/Release/node_datachannel.node');
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import { familySync, MUSL } from 'detect-libc';
4
+
5
+ function getPackageName(): string | null {
6
+ const { platform, arch } = process;
7
+ if (platform === 'linux') {
8
+ const libc = familySync();
9
+ if (libc === MUSL) {
10
+ if (arch === 'x64') return '@node-datachannel/linux-x64-musl';
11
+ if (arch === 'arm64') return '@node-datachannel/linux-arm64-musl';
12
+ } else {
13
+ if (arch === 'x64') return '@node-datachannel/linux-x64-gnu';
14
+ if (arch === 'arm64') return '@node-datachannel/linux-arm64-gnu';
15
+ }
16
+ } else if (platform === 'darwin') {
17
+ if (arch === 'arm64') return '@node-datachannel/darwin-arm64';
18
+ if (arch === 'x64') return '@node-datachannel/darwin-x64';
19
+ } else if (platform === 'win32') {
20
+ if (arch === 'x64') return '@node-datachannel/win32-x64-msvc';
21
+ if (arch === 'arm64') return '@node-datachannel/win32-arm64-msvc';
22
+ } else if (platform === 'android') {
23
+ if (arch === 'arm64') return '@node-datachannel/android-arm64';
24
+ }
25
+ return null;
26
+ }
27
+
28
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
29
+ function loadBinding(): any {
30
+ // 1. Try local build candidate paths for development, tests, and source builds
31
+ const candidateLocalPaths = [
32
+ path.resolve(__dirname, '../../build/node_datachannel.node'),
33
+ path.resolve(__dirname, '../../../build/node_datachannel.node'),
34
+ path.resolve(__dirname, '../../build/Release/node_datachannel.node'),
35
+ path.resolve(__dirname, '../../../build/Release/node_datachannel.node'),
36
+ path.resolve(__dirname, '../../build/Debug/node_datachannel.node'),
37
+ path.resolve(__dirname, '../../../build/Debug/node_datachannel.node'),
38
+ ];
39
+
40
+ let localLoadError: Error | null = null;
41
+ for (const candidate of candidateLocalPaths) {
42
+ if (fs.existsSync(candidate)) {
43
+ try {
44
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
45
+ return require(candidate);
46
+ } catch (err: unknown) {
47
+ localLoadError = err instanceof Error ? err : new Error(String(err));
48
+ }
49
+ }
50
+ }
51
+
52
+ if (localLoadError) {
53
+ throw new Error(
54
+ `Failed to load local native addon build: ${localLoadError.message}\n` +
55
+ `Stack: ${localLoadError.stack}`
56
+ );
57
+ }
58
+
59
+ // 2. Try platform-specific optionalDependencies package
60
+ const pkgName = getPackageName();
61
+ if (pkgName) {
62
+ try {
63
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
64
+ return require(pkgName);
65
+ } catch (err: unknown) {
66
+ const errorMsg = err instanceof Error ? err.message : String(err);
67
+ throw new Error(
68
+ `Cannot load native addon for node-datachannel on ${process.platform} (${process.arch}). ` +
69
+ `Attempted to require "${pkgName}". ` +
70
+ `Please ensure optionalDependencies are installed (avoid --no-optional / --omit=optional) ` +
71
+ `or compile locally with "npm run compile". (Error: ${errorMsg})`
72
+ );
73
+ }
74
+ }
75
+
76
+ throw new Error(
77
+ `Unsupported platform/architecture for node-datachannel: ${process.platform} (${process.arch}). ` +
78
+ `Please compile from source using "npm run compile".`
79
+ );
80
+ }
81
+
82
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
83
+ const nodeDataChannel: any = loadBinding();
3
84
  export default nodeDataChannel;