node-datachannel
Advanced tools
Comparing version 0.5.0-dev to 0.5.0
@@ -38,3 +38,3 @@ cmake_minimum_required(VERSION 3.15) | ||
GIT_REPOSITORY https://github.com/paullouisageneau/libdatachannel.git | ||
GIT_TAG "v0.19.1" | ||
GIT_TAG "v0.19.2" | ||
) | ||
@@ -41,0 +41,0 @@ |
@@ -31,3 +31,3 @@ { | ||
"css-loader": "^6.8.1", | ||
"electron": "26.2.0", | ||
"electron": "26.2.4", | ||
"node-loader": "^2.0.0", | ||
@@ -38,3 +38,3 @@ "style-loader": "^3.3.3" | ||
"electron-squirrel-startup": "^1.0.0", | ||
"node-datachannel": "0.5.0" | ||
"node-datachannel": "0.5.0-dev" | ||
}, | ||
@@ -41,0 +41,0 @@ "cmake-js": { |
@@ -101,2 +101,5 @@ import * as stream from 'stream'; | ||
transportType: string; | ||
candidate: string; | ||
mid: string; | ||
priority: number; | ||
} | ||
@@ -236,2 +239,4 @@ | ||
getSelectedCandidatePair(): { local: SelectedCandidateInfo; remote: SelectedCandidateInfo } | null; | ||
maxDataChannelId(): number; | ||
maxMessageSize(): number; | ||
} | ||
@@ -238,0 +243,0 @@ |
@@ -6,4 +6,35 @@ // createRequire is native in node version >= 12 | ||
const nodeDataChannel = require('../build/Release/node_datachannel.node'); | ||
import DataChannelStream from './datachannel-stream.js'; | ||
export default nodeDataChannel; | ||
export { default as DataChannelStream } from './datachannel-stream.js'; | ||
const { | ||
initLogger, | ||
cleanup, | ||
preload, | ||
setSctpSettings, | ||
RtcpReceivingSession, | ||
Track, | ||
Video, | ||
Audio, | ||
DataChannel, | ||
PeerConnection, | ||
} = nodeDataChannel; | ||
export { | ||
initLogger, | ||
cleanup, | ||
preload, | ||
setSctpSettings, | ||
RtcpReceivingSession, | ||
Track, | ||
Video, | ||
Audio, | ||
DataChannel, | ||
PeerConnection, | ||
// Extra exports | ||
DataChannelStream, | ||
}; | ||
export default { | ||
...nodeDataChannel, | ||
DataChannelStream, | ||
}; |
{ | ||
"name": "node-datachannel", | ||
"version": "0.5.0-dev", | ||
"version": "0.5.0", | ||
"description": "libdatachannel node bindings", | ||
@@ -63,3 +63,2 @@ "type": "module", | ||
"license": "MPL 2.0", | ||
"gypfile": true, | ||
"bugs": { | ||
@@ -83,5 +82,2 @@ "url": "https://github.com/murat-dogan/node-datachannel/issues" | ||
}, | ||
"bundledDependencies": [ | ||
"prebuild-install" | ||
], | ||
"dependencies": { | ||
@@ -88,0 +84,0 @@ "node-domexception": "^2.0.1", |
@@ -0,10 +1,27 @@ | ||
import RTCIceTransport from './RTCIceTransport.js'; | ||
export default class _RTCDtlsTransport extends EventTarget { | ||
#pc = null; | ||
#extraFunctions = null; | ||
#iceTransport = null; | ||
#state = null; | ||
onerror = createEmptyFunction(); | ||
onstatechange = createEmptyFunction(); | ||
onerror = null; | ||
onstatechange = null; | ||
constructor() { | ||
constructor({ pc, extraFunctions }) { | ||
super(); | ||
this.#pc = pc; | ||
this.#extraFunctions = extraFunctions; | ||
this.#iceTransport = new RTCIceTransport({ pc, extraFunctions }); | ||
// forward peerConnection events | ||
this.#pc.addEventListener('connectionstatechange', () => { | ||
this.dispatchEvent(new Event('statechange')); | ||
}); | ||
// forward events to properties | ||
this.addEventListener('statechange', (e) => { | ||
if (this.onstatechange) this.onstatechange(e); | ||
}); | ||
} | ||
@@ -17,14 +34,15 @@ | ||
get state() { | ||
return this.#state; | ||
// reduce state from new, connecting, connected, disconnected, failed, closed, unknown | ||
// to RTCDtlsTRansport states new, connecting, connected, closed, failed | ||
let state = this.#pc ? this.#pc.connectionState : 'new'; | ||
if (state === 'disconnected' || state === 'unknown') { | ||
state = 'closed'; | ||
} | ||
return state; | ||
} | ||
getRemoteCertificates() { | ||
/** */ | ||
// TODO: implement | ||
return new ArrayBuffer(0); | ||
} | ||
} | ||
function createEmptyFunction() { | ||
return () => { | ||
/** */ | ||
}; | ||
} |
@@ -37,3 +37,3 @@ // https://developer.mozilla.org/docs/Web/API/RTCIceCandidate | ||
this.#foundation = fields[0]; | ||
this.#component = fields[1]; | ||
this.#component = fields[1] == '1' ? 'rtp' : 'rtcp'; | ||
this.#protocol = fields[2]; | ||
@@ -40,0 +40,0 @@ this.#priority = parseInt(fields[3], 10); |
@@ -0,32 +1,54 @@ | ||
import RTCIceCandidate from './RTCIceCandidate.js'; | ||
export default class _RTCIceTransport extends EventTarget { | ||
#component = null; | ||
#gatheringState = null; | ||
#role = null; | ||
#state = null; | ||
#pc = null; | ||
#extraFunctions = null; | ||
ongatheringstatechange = createEmptyFunction(); | ||
onselectedcandidatepairchange = createEmptyFunction(); | ||
onstatechange = createEmptyFunction(); | ||
ongatheringstatechange = null; | ||
onselectedcandidatepairchange = null; | ||
onstatechange = null; | ||
constructor() { | ||
constructor({ pc, extraFunctions }) { | ||
super(); | ||
this.#pc = pc; | ||
this.#extraFunctions = extraFunctions; | ||
// forward peerConnection events | ||
this.#pc.addEventListener('icegatheringstatechange', () => { | ||
this.dispatchEvent(new Event('gatheringstatechange')); | ||
}); | ||
this.#pc.addEventListener('iceconnectionstatechange', () => { | ||
console.log('*********'); | ||
this.dispatchEvent(new Event('statechange')); | ||
}); | ||
// forward events to properties | ||
this.addEventListener('gatheringstatechange', (e) => { | ||
if (this.ongatheringstatechange) this.ongatheringstatechange(e); | ||
}); | ||
this.addEventListener('statechange', (e) => { | ||
if (this.onstatechange) this.onstatechange(e); | ||
}); | ||
} | ||
get component() { | ||
return this.#component; | ||
let cp = this.getSelectedCandidatePair(); | ||
if (!cp) return null; | ||
return cp.local.component; | ||
} | ||
get gatheringState() { | ||
return this.#gatheringState; | ||
return this.#pc ? this.#pc.iceGatheringState : 'new'; | ||
} | ||
get role() { | ||
return this.#role; | ||
return this.#pc.localDescription.type == 'offer' ? 'controlling' : 'controlled'; | ||
} | ||
get state() { | ||
return this.#state; | ||
return this.#pc ? this.#pc.iceConnectionState : 'new'; | ||
} | ||
getLocalCandidates() { | ||
/** */ | ||
return this.#pc ? this.#extraFunctions.localCandidates() : []; | ||
} | ||
@@ -39,3 +61,3 @@ | ||
getRemoteCandidates() { | ||
/** */ | ||
return this.#pc ? this.#extraFunctions.remoteCandidates() : []; | ||
} | ||
@@ -48,10 +70,15 @@ | ||
getSelectedCandidatePair() { | ||
/** */ | ||
let cp = this.#extraFunctions.selectedCandidatePair(); | ||
if (!cp) return null; | ||
return { | ||
local: new RTCIceCandidate({ | ||
candidate: cp.local.candidate, | ||
sdpMid: cp.local.mid, | ||
}), | ||
remote: new RTCIceCandidate({ | ||
candidate: cp.remote.candidate, | ||
sdpMid: cp.remote.mid, | ||
}), | ||
}; | ||
} | ||
} | ||
function createEmptyFunction() { | ||
return () => { | ||
/** */ | ||
}; | ||
} |
@@ -6,2 +6,3 @@ import NodeDataChannel from '../lib/index.js'; | ||
import { RTCDataChannelEvent, RTCPeerConnectionIceEvent } from './Events.js'; | ||
import RTCSctpTransport from './RTCSctpTransport.js'; | ||
import DOMException from 'node-domexception'; | ||
@@ -18,2 +19,5 @@ | ||
#localCandidates = []; | ||
#remoteCandidates = []; | ||
onconnectionstatechange; | ||
@@ -37,26 +41,20 @@ ondatachannel; | ||
this.#canTrickleIceCandidates = null; | ||
this.#sctp = null; | ||
const iceServers = init ? init.iceServers : []; | ||
this.#peerConnection = new NodeDataChannel.PeerConnection(init?.peerIdentity ?? `peer-${getRandomString(7)}`, { | ||
...init, | ||
iceServers: init?.iceServers | ||
?.map((server) => { | ||
const urls = Array.isArray(server.urls) ? server.urls : [server.urls]; | ||
this.#peerConnection = new NodeDataChannel.PeerConnection( | ||
init && init.peerIdentity ? init.peerIdentity : `peer-${getRandomString(7)}`, | ||
{ | ||
iceServers: iceServers | ||
.map((server) => { | ||
const urls = Array.isArray(server.urls) ? server.urls : [server.urls]; | ||
return urls.map((url) => { | ||
if (server.username && server.credential) { | ||
const [protocol, rest] = url.split(/:(.*)/); | ||
return `${protocol}:${server.username}:${server.credential}@${rest}`; | ||
} | ||
return url; | ||
}); | ||
}) | ||
.flat(), | ||
}); | ||
return urls.map((url) => { | ||
if (server.username && server.credential) { | ||
const [protocol, rest] = url.split(/:(.*)/); | ||
return `${protocol}:${server.username}:${server.credential}@${rest}`; | ||
} | ||
return url; | ||
}); | ||
}) | ||
.flat(), | ||
iceTransportPolicy: init ? init.iceTransportPolicy : undefined, | ||
}, | ||
); | ||
// forward peerConnection events | ||
@@ -101,2 +99,3 @@ this.#peerConnection.onStateChange(() => { | ||
this.#localCandidates.push(new RTCIceCandidate({ candidate, sdpMid })); | ||
this.dispatchEvent(new RTCPeerConnectionIceEvent(new RTCIceCandidate({ candidate, sdpMid }))); | ||
@@ -124,2 +123,23 @@ }); | ||
}); | ||
this.#sctp = new RTCSctpTransport({ | ||
pc: this, | ||
extraFunctions: { | ||
maxDataChannelId: () => { | ||
return this.#peerConnection.maxDataChannelId(); | ||
}, | ||
maxMessageSize: () => { | ||
return this.#peerConnection.maxMessageSize(); | ||
}, | ||
localCandidates: () => { | ||
return this.#localCandidates; | ||
}, | ||
remoteCandidates: () => { | ||
return this.#remoteCandidates; | ||
}, | ||
selectedCandidatePair: () => { | ||
return this.#peerConnection.getSelectedCandidatePair(); | ||
}, | ||
}, | ||
}); | ||
} | ||
@@ -184,2 +204,5 @@ | ||
this.#remoteCandidates.push( | ||
new RTCIceCandidate({ candidate: candidate.candidate, sdpMid: candidate.sdpMid || '0' }), | ||
); | ||
this.#peerConnection.addRemoteCandidate(candidate.candidate, candidate.sdpMid || '0'); | ||
@@ -186,0 +209,0 @@ } |
@@ -0,23 +1,48 @@ | ||
import RTCDtlsTransport from './RTCDtlsTransport.js'; | ||
export default class _RTCSctpTransport extends EventTarget { | ||
#maxChannels = null; | ||
#maxMessageSize = null; | ||
#state = null; | ||
#pc = null; | ||
#extraFunctions = null; | ||
#transport = null; | ||
onstatechange = createEmptyFunction(); | ||
onstatechange = null; | ||
constructor(init = {}) { | ||
constructor({ pc, extraFunctions }) { | ||
super(); | ||
this.#pc = pc; | ||
this.#extraFunctions = extraFunctions; | ||
this.#transport = new RTCDtlsTransport({ pc, extraFunctions }); | ||
// forward peerConnection events | ||
this.#pc.addEventListener('connectionstatechange', () => { | ||
this.dispatchEvent(new Event('statechange')); | ||
}); | ||
// forward events to properties | ||
this.addEventListener('statechange', (e) => { | ||
if (this.onstatechange) this.onstatechange(e); | ||
}); | ||
} | ||
get maxChannels() { | ||
return this.#maxChannels; | ||
if (this.state !== 'connected') return null; | ||
return this.#pc ? this.#extraFunctions.maxDataChannelId() : 0; | ||
} | ||
get maxMessageSize() { | ||
return this.#maxMessageSize; | ||
if (this.state !== 'connected') return null; | ||
return this.#pc ? this.#extraFunctions.maxMessageSize() : 0; | ||
} | ||
get state() { | ||
return this.#state; | ||
// reduce state from new, connecting, connected, disconnected, failed, closed, unknown | ||
// to RTCSctpTransport states connecting, connected, closed | ||
let state = this.#pc.connectionState; | ||
if (state === 'new' || state === 'connecting') { | ||
state = 'connecting'; | ||
} else if (state === 'disconnected' || state === 'failed' || state === 'closed' || state === 'unknown') { | ||
state = 'closed'; | ||
} | ||
return state; | ||
} | ||
@@ -29,7 +54,1 @@ | ||
} | ||
function createEmptyFunction() { | ||
return () => { | ||
/** */ | ||
}; | ||
} |
@@ -1,2 +0,2 @@ | ||
import nodeDataChannel from '../lib/index.js'; | ||
import * as nodeDataChannel from '../lib/index.js'; | ||
@@ -3,0 +3,0 @@ nodeDataChannel.initLogger('Debug'); |
import polyfill from '../polyfill/index.js'; | ||
import nodeDataChannel from '../lib/index.js'; | ||
import * as nodeDataChannel from '../lib/index.js'; | ||
@@ -74,2 +74,3 @@ nodeDataChannel.initLogger('Info'); | ||
.then((desc) => { | ||
// console.log(122222, desc); | ||
peer2.setRemoteDescription(desc); | ||
@@ -76,0 +77,0 @@ }) |
import { jest } from '@jest/globals'; | ||
import nodeDataChannel, { DataChannelStream } from '../lib/index.js'; | ||
import * as nodeDataChannel from '../lib'; | ||
@@ -157,3 +157,3 @@ describe('Module Definition', () => { | ||
const echoStream = new DataChannelStream(echoPeer.createDataChannel('echo-channel')); | ||
const echoStream = new nodeDataChannel.DataChannelStream(echoPeer.createDataChannel('echo-channel')); | ||
echoStream.pipe(echoStream); // Echo all received data back to the client | ||
@@ -160,0 +160,0 @@ |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Mixed license
License(Experimental) Package contains multiple licenses.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 4 instances in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 7 instances in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 2 instances in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
Mixed license
License(Experimental) Package contains multiple licenses.
Found 1 instance in 1 package
1
6
1
998223
92
19217