Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

peer-lite

Package Overview
Dependencies
Maintainers
1
Versions
11
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

peer-lite - npm Package Compare versions

Comparing version 2.0.0-beta.0 to 2.0.0

4

dist/index.es.js

@@ -1,8 +0,8 @@

class EventEmitter{constructor(){this.listeners={};}on(a,b){return this.listeners[a]=this.listeners[a]||[],this.listeners[a].push(b),this}off(c,d){let a=this.listeners[c];if(!a)return this;for(let b=a.length;b>0;b-=1)if(a[b]===d){a.splice(b,1);break}return this}emit(d){for(var b=arguments.length,e=new Array(b>1?b-1:0),a=1;a<b;a++)e[a-1]=arguments[a];let c=this.listeners[d];return !!c&&(c.forEach(a=>{a(...e);}),!0)}}
class EventEmitter{constructor(){this.eventMap={};}emit(d){for(var b=arguments.length,e=new Array(b>1?b-1:0),a=1;a<b;a++)e[a-1]=arguments[a];let c=this.eventMap[d];return !!c&&(c.forEach(a=>{a(...e);}),!0)}on(a,c){var b;return this.eventMap[a]=null!==(b=this.eventMap[a])&& void 0!==b?b:[],this.eventMap[a].push(c),this}off(d,e){var b;let c=null!==(b=this.eventMap[d])&& void 0!==b?b:[];for(let a=c.length;a>0;a-=1)if(c[a]===e){c.splice(a,1);break}return this}offAll(a){if(a){let b=this.eventMap[a];if(!b)return this;delete this.eventMap[a];}else this.eventMap={};return this}}
function getDefaultCamConstraints(){let a={},b=navigator.mediaDevices.getSupportedConstraints();b.facingMode&&(a.facingMode="user"),b.frameRate&&(a.frameRate={max:30});let c=!(Object.keys(a).length>0)||a;return {audio:!0,video:c}}function randomHex(b){let a=new Uint8Array(b);return crypto.getRandomValues(a),Array.from(a).map(a=>a.toString(16).padStart(2,"0")).join("")}function filterByTrack(a){return b=>b===a}function removeTracks(a,b){a.getTracks().filter(b).forEach(b=>{b.stop(),a.removeTrack(b);});}function removeTracksFromPeer(a,b){a.getSenders().filter(a=>a.track&&b(a.track)).forEach(b=>a.removeTrack(b));}
class g{constructor(b){this.streamLocal=new MediaStream,this.channels=new Map,this.channelsPending=new Map,this.emitter=new EventEmitter,this.polite=!0,this.isActive=!1,this.makingOffer=!1,this.ignoreOffer=!1,this.options={batchCandidates:!0,batchCandidatesTimeout:200,name:"peer",config:{iceServers:[{urls:["stun:stun.l.google.com:19302"]}]},offerOptions:{},enableDataChannels:!1,channelLabel:randomHex(20),channelOptions:{},sdpTransform:a=>a},this.options={...this.options,...b},this.peer=this.init();}init(){if("new"===this.status())return this.peer;this.destroy(),this.peer=new RTCPeerConnection(this.options.config),this.streamLocal.getTracks().forEach(a=>this.peer.addTrack(a,this.streamLocal));let{channelLabel:a,channelOptions:b,enableDataChannels:c}=this.options;c&&this.addDataChannel(a,b);let d=[],e;function f(){clearTimeout(e),d.length=0;}return this.peer.onicecandidate=a=>{(null==a?void 0:a.candidate)&&(this.options.batchCandidates?(clearTimeout(e),d.push(a.candidate),"complete"===this.peer.iceGatheringState?this.emit("onicecandidates",d):e=setTimeout(()=>{d.length&&(this.emit("onicecandidates",d),f());},this.options.batchCandidatesTimeout)):this.emit("onicecandidates",[a.candidate]));},this.peer.ontrack=a=>{a.streams&&this.emit("streamRemote",a.streams[0]);},this.peer.oniceconnectionstatechange=()=>{switch(this.emit("status",this.status()),this.status()){case"closed":case"failed":case"disconnected":f(),this.destroy();break;case"checking":this.emit("connecting");break;case"connected":this.emit("connected");}},this.peer.onnegotiationneeded=async()=>{try{if(!this.isActive)return;this.makingOffer=!0;let{offerOptions:c,sdpTransform:d}=this.options;this.createDataChannels();let a=await this.peer.createOffer(c);if("stable"!==this.peer.signalingState)return;a.sdp=a.sdp&&d(a.sdp),await this.peer.setLocalDescription(a),this.peer.localDescription&&this.emit("signal",this.peer.localDescription);}catch(b){b instanceof Error&&this.error("Failed in negotiationNeeded",b);}finally{this.makingOffer=!1;}},this.peer.ondatachannel=b=>{let{channel:a}=b;this.options.enableDataChannels&&(this.channels.set(a.label,a),this.addDataChannelEvents(a));},this.peer}start(){let{polite:b=!0}=arguments.length>0&& void 0!==arguments[0]?arguments[0]:{};try{"have-local-offer"===this.peer.signalingState&&this.destroy(),this.isClosed()&&this.init(),this.isActive=!0,this.polite=b,this.peer.restartIce();}catch(a){if(a instanceof Error)throw this.error("Failed to start",a),a}}async signal(b){try{this.isClosed()&&this.init(),this.isActive=!0;let d="offer"===b.type&&(this.makingOffer||"stable"!==this.peer.signalingState);if(this.ignoreOffer=!this.polite&&d,this.ignoreOffer)return;if(await this.peer.setRemoteDescription(b),"offer"===b.type){this.createDataChannels();let a=await this.peer.createAnswer();a.sdp=a.sdp&&this.options.sdpTransform(a.sdp),await this.peer.setLocalDescription(a),this.emit("signal",a);}this.polite=!0;}catch(c){if(c instanceof Error)throw this.error("Failed to signal",c),c}}async addIceCandidate(b){try{await this.peer.addIceCandidate(b);}catch(a){if(!this.ignoreOffer&&a instanceof Error)throw this.error("Failed to addIceCandidate",a),a}}send(b){let c=arguments.length>1&& void 0!==arguments[1]?arguments[1]:this.options.channelLabel,a=this.channels.get(c);return (null==a?void 0:a.readyState)==="open"&&!!b&&(a.send(b),this.emit("channelData",{channel:a,data:b,source:"outgoing"}),!0)}addDataChannel(){let a=arguments.length>0&& void 0!==arguments[0]?arguments[0]:this.options.channelLabel,b=arguments.length>1&& void 0!==arguments[1]?arguments[1]:{};if(!this.options.enableDataChannels){this.error('Failed to addDataChannel as "enableDataChannels" is false');return}if(this.isClosed()){this.error("Failed to addDataChannel as peer connection is closed");return}this.channels.has(a)||this.channelsPending.set(a,b),this.isActive&&this.createDataChannels();}getDataChannel(){let a=arguments.length>0&& void 0!==arguments[0]?arguments[0]:this.options.channelLabel;return this.channels.get(a)}createDataChannels(){try{Array.from(this.channelsPending.entries()).forEach(c=>{let[a,d]=c,b=this.peer.createDataChannel(a,d);this.channels.set(a,b),this.addDataChannelEvents(b);}),this.channelsPending.clear();}catch(a){if(a instanceof Error)throw this.error("Failed to createDataChannels",a),a}}addDataChannelEvents(a){a.onopen=()=>this.emit("channelOpen",{channel:a}),a.onerror=b=>{this.emit("channelError",{channel:a,event:b});},a.onclose=()=>{this.channels.delete(a.label),this.emit("channelClosed",{channel:a});},a.onmessage=b=>{this.emit("channelData",{channel:a,data:b.data,source:"incoming"});};}destroy(){this.isClosed()||(this.polite=!0,this.isActive=!1,this.makingOffer=!1,this.ignoreOffer=!1,this.channels.clear(),this.channelsPending.clear(),this.peer.close(),this.emit("disconnected"));}status(){var a,b;return null!==(b=null===(a=this.peer)|| void 0===a?void 0:a.iceConnectionState)&& void 0!==b?b:"closed"}isConnected(){return "connected"===this.status()}isClosed(){return "closed"===this.status()}get(){return this.peer}getStreamLocal(){return this.streamLocal}error(a,b){this.emit("error",{name:this.options.name,message:a,error:b});}addStream(a){let b=arguments.length>1&& void 0!==arguments[1]&&arguments[1];b&&this.removeTracks(this.streamLocal.getTracks()),a.getTracks().forEach(a=>this.addTrack(a));}removeStream(a){this.removeTracks(a.getTracks());}addTrack(b){try{this.streamLocal.addTrack(b),this.emit("streamLocal",this.streamLocal),this.isClosed()||this.peer.addTrack(b,this.streamLocal);}catch(a){if(a instanceof Error)throw this.error("Failed to addTrack",a),a}}removeTracks(a){a.forEach(a=>this.removeTrack(a));}removeTrack(a){removeTracks(this.streamLocal,filterByTrack(a)),this.isClosed()||removeTracksFromPeer(this.peer,filterByTrack(a));}async replaceTrack(c,d){try{if(!this.isClosed()){let[f]=this.peer.getSenders().filter(a=>a.track===c);f?(removeTracks(this.streamLocal,filterByTrack(c)),this.streamLocal.addTrack(d),await f.replaceTrack(d),this.emit("streamLocal",this.streamLocal)):this.error(`Failed to find track to replace: ${c.id}`);}}catch(a){if(a instanceof Error)throw this.error("Failed to replaceTrack",a),a}}on(a,b){return this.emitter.on(a,b)}off(a,b){return this.emitter.off(a,b)}emit(d){for(var b=arguments.length,c=new Array(b>1?b-1:0),a=1;a<b;a++)c[a-1]=arguments[a];return this.emitter.emit(d,...c)}static getUserMedia(a){return navigator.mediaDevices.getUserMedia({...getDefaultCamConstraints(),...a})}}
class g{constructor(b){this.streamLocal=new MediaStream,this.channels=new Map,this.channelsPending=new Map,this.emitter=new EventEmitter,this.polite=!0,this.isActive=!1,this.makingOffer=!1,this.ignoreOffer=!1,this.options={batchCandidates:!0,batchCandidatesTimeout:200,id:randomHex(4),config:{iceServers:[{urls:["stun:stun.l.google.com:19302"]}]},offerOptions:{},enableDataChannels:!1,channelLabel:randomHex(20),channelOptions:{},sdpTransform:a=>a},this.options={...this.options,...b},this.peer=this.init();}init(){if("new"===this.status())return this.peer;this.destroy(),this.peer=new RTCPeerConnection(this.options.config),this.streamLocal.getTracks().forEach(a=>this.peer.addTrack(a,this.streamLocal));let{channelLabel:a,channelOptions:b,enableDataChannels:c}=this.options;c&&this.addDataChannel(a,b);let d=[],e;function f(){clearTimeout(e),d.length=0;}return this.peer.onicecandidate=a=>{(null==a?void 0:a.candidate)&&(this.options.batchCandidates?(clearTimeout(e),d.push(a.candidate),"complete"===this.peer.iceGatheringState?this.emit("onicecandidates",d):e=setTimeout(()=>{d.length&&(this.emit("onicecandidates",d),f());},this.options.batchCandidatesTimeout)):this.emit("onicecandidates",[a.candidate]));},this.peer.ontrack=a=>{a.streams&&this.emit("streamRemote",a.streams[0]);},this.peer.oniceconnectionstatechange=()=>{switch(this.emit("status",this.status()),this.status()){case"closed":case"failed":case"disconnected":f(),this.destroy();break;case"checking":this.emit("connecting");break;case"connected":this.emit("connected");}},this.peer.onnegotiationneeded=async()=>{try{if(!this.isActive)return;this.makingOffer=!0;let{offerOptions:c,sdpTransform:d}=this.options;this.createDataChannels();let a=await this.peer.createOffer(c);if("stable"!==this.peer.signalingState)return;a.sdp=a.sdp&&d(a.sdp),await this.peer.setLocalDescription(a),this.peer.localDescription&&this.emit("signal",this.peer.localDescription);}catch(b){b instanceof Error&&this.error("Failed in negotiationNeeded",b);}finally{this.makingOffer=!1;}},this.peer.ondatachannel=b=>{let{channel:a}=b;this.options.enableDataChannels&&(this.channels.set(a.label,a),this.addDataChannelEvents(a));},this.peer}start(){let{polite:b=!0}=arguments.length>0&& void 0!==arguments[0]?arguments[0]:{};try{"have-local-offer"===this.peer.signalingState&&this.destroy(),this.isClosed()&&this.init(),this.isActive=!0,this.polite=b,this.peer.restartIce();}catch(a){if(a instanceof Error)throw this.error("Failed to start",a),a}}async signal(b){try{this.isClosed()&&this.init(),this.isActive=!0;let d="offer"===b.type&&(this.makingOffer||"stable"!==this.peer.signalingState);if(this.ignoreOffer=!this.polite&&d,this.ignoreOffer)return;if(await this.peer.setRemoteDescription(b),"offer"===b.type){this.createDataChannels();let a=await this.peer.createAnswer();a.sdp=a.sdp&&this.options.sdpTransform(a.sdp),await this.peer.setLocalDescription(a),this.emit("signal",a);}this.polite=!0;}catch(c){if(c instanceof Error)throw this.error("Failed to signal",c),c}}async addIceCandidate(b){try{await this.peer.addIceCandidate(b);}catch(a){if(!this.ignoreOffer&&a instanceof Error)throw this.error("Failed to addIceCandidate",a),a}}send(b){let c=arguments.length>1&& void 0!==arguments[1]?arguments[1]:this.options.channelLabel,a=this.channels.get(c);return (null==a?void 0:a.readyState)==="open"&&!!b&&(a.send(b),this.emit("channelData",{channel:a,data:b,source:"outgoing"}),!0)}addDataChannel(){let a=arguments.length>0&& void 0!==arguments[0]?arguments[0]:this.options.channelLabel,b=arguments.length>1&& void 0!==arguments[1]?arguments[1]:{};if(!this.options.enableDataChannels){this.error('Failed to addDataChannel as "enableDataChannels" is false');return}if(this.isClosed()){this.error("Failed to addDataChannel as peer connection is closed");return}this.channels.has(a)||this.channelsPending.set(a,b),this.isActive&&this.createDataChannels();}getDataChannel(){let a=arguments.length>0&& void 0!==arguments[0]?arguments[0]:this.options.channelLabel;return this.channels.get(a)}createDataChannels(){try{Array.from(this.channelsPending.entries()).forEach(c=>{let[a,d]=c,b=this.peer.createDataChannel(a,d);this.channels.set(a,b),this.addDataChannelEvents(b);}),this.channelsPending.clear();}catch(a){if(a instanceof Error)throw this.error("Failed to createDataChannels",a),a}}addDataChannelEvents(a){a.onopen=()=>this.emit("channelOpen",{channel:a}),a.onerror=b=>{this.emit("channelError",{channel:a,event:b});},a.onclose=()=>{this.channels.delete(a.label),this.emit("channelClosed",{channel:a});},a.onmessage=b=>{this.emit("channelData",{channel:a,data:b.data,source:"incoming"});};}destroy(){this.isClosed()||(this.polite=!0,this.isActive=!1,this.makingOffer=!1,this.ignoreOffer=!1,this.channels.clear(),this.channelsPending.clear(),this.peer.close(),this.emit("disconnected"));}status(){var a,b;return null!==(b=null===(a=this.peer)|| void 0===a?void 0:a.iceConnectionState)&& void 0!==b?b:"closed"}isConnected(){return "connected"===this.status()}isClosed(){return "closed"===this.status()}get(){return this.peer}getStreamLocal(){return this.streamLocal}error(a,b){this.emit("error",{id:this.options.id,message:a,error:b});}addStream(a){let b=arguments.length>1&& void 0!==arguments[1]&&arguments[1];b&&this.removeTracks(this.streamLocal.getTracks()),a.getTracks().forEach(a=>this.addTrack(a));}removeStream(a){this.removeTracks(a.getTracks());}addTrack(b){try{this.streamLocal.addTrack(b),this.emit("streamLocal",this.streamLocal),this.isClosed()||this.peer.addTrack(b,this.streamLocal);}catch(a){if(a instanceof Error)throw this.error("Failed to addTrack",a),a}}removeTrack(a){removeTracks(this.streamLocal,filterByTrack(a)),this.isClosed()||removeTracksFromPeer(this.peer,filterByTrack(a));}removeTracks(a){a.forEach(a=>this.removeTrack(a));}async replaceTrack(c,d){try{if(!this.isClosed()){let[f]=this.peer.getSenders().filter(a=>a.track===c);f?(removeTracks(this.streamLocal,filterByTrack(c)),this.streamLocal.addTrack(d),await f.replaceTrack(d),this.emit("streamLocal",this.streamLocal)):this.error(`Failed to find track to replace: ${c.id}`);}}catch(a){if(a instanceof Error)throw this.error("Failed to replaceTrack",a),a}}on(a,b){return this.emitter.on(a,b)}off(a,b){return this.emitter.off(a,b)}offAll(a){return this.emitter.offAll(a)}emit(d){for(var b=arguments.length,c=new Array(b>1?b-1:0),a=1;a<b;a++)c[a-1]=arguments[a];return this.emitter.emit(d,...c)}static getUserMedia(a){return navigator.mediaDevices.getUserMedia({...getDefaultCamConstraints(),...a})}}
export { g as default };
//# sourceMappingURL=index.es.js.map

@@ -7,7 +7,7 @@ (function (global, factory) {

class EventEmitter{constructor(){this.listeners={};}on(a,b){return this.listeners[a]=this.listeners[a]||[],this.listeners[a].push(b),this}off(c,d){let a=this.listeners[c];if(!a)return this;for(let b=a.length;b>0;b-=1)if(a[b]===d){a.splice(b,1);break}return this}emit(d){for(var b=arguments.length,e=new Array(b>1?b-1:0),a=1;a<b;a++)e[a-1]=arguments[a];let c=this.listeners[d];return !!c&&(c.forEach(a=>{a(...e);}),!0)}}
class EventEmitter{constructor(){this.eventMap={};}emit(d){for(var b=arguments.length,e=new Array(b>1?b-1:0),a=1;a<b;a++)e[a-1]=arguments[a];let c=this.eventMap[d];return !!c&&(c.forEach(a=>{a(...e);}),!0)}on(a,c){var b;return this.eventMap[a]=null!==(b=this.eventMap[a])&& void 0!==b?b:[],this.eventMap[a].push(c),this}off(d,e){var b;let c=null!==(b=this.eventMap[d])&& void 0!==b?b:[];for(let a=c.length;a>0;a-=1)if(c[a]===e){c.splice(a,1);break}return this}offAll(a){if(a){let b=this.eventMap[a];if(!b)return this;delete this.eventMap[a];}else this.eventMap={};return this}}
function getDefaultCamConstraints(){let a={},b=navigator.mediaDevices.getSupportedConstraints();b.facingMode&&(a.facingMode="user"),b.frameRate&&(a.frameRate={max:30});let c=!(Object.keys(a).length>0)||a;return {audio:!0,video:c}}function randomHex(b){let a=new Uint8Array(b);return crypto.getRandomValues(a),Array.from(a).map(a=>a.toString(16).padStart(2,"0")).join("")}function filterByTrack(a){return b=>b===a}function removeTracks(a,b){a.getTracks().filter(b).forEach(b=>{b.stop(),a.removeTrack(b);});}function removeTracksFromPeer(a,b){a.getSenders().filter(a=>a.track&&b(a.track)).forEach(b=>a.removeTrack(b));}
class g{constructor(b){this.streamLocal=new MediaStream,this.channels=new Map,this.channelsPending=new Map,this.emitter=new EventEmitter,this.polite=!0,this.isActive=!1,this.makingOffer=!1,this.ignoreOffer=!1,this.options={batchCandidates:!0,batchCandidatesTimeout:200,name:"peer",config:{iceServers:[{urls:["stun:stun.l.google.com:19302"]}]},offerOptions:{},enableDataChannels:!1,channelLabel:randomHex(20),channelOptions:{},sdpTransform:a=>a},this.options={...this.options,...b},this.peer=this.init();}init(){if("new"===this.status())return this.peer;this.destroy(),this.peer=new RTCPeerConnection(this.options.config),this.streamLocal.getTracks().forEach(a=>this.peer.addTrack(a,this.streamLocal));let{channelLabel:a,channelOptions:b,enableDataChannels:c}=this.options;c&&this.addDataChannel(a,b);let d=[],e;function f(){clearTimeout(e),d.length=0;}return this.peer.onicecandidate=a=>{(null==a?void 0:a.candidate)&&(this.options.batchCandidates?(clearTimeout(e),d.push(a.candidate),"complete"===this.peer.iceGatheringState?this.emit("onicecandidates",d):e=setTimeout(()=>{d.length&&(this.emit("onicecandidates",d),f());},this.options.batchCandidatesTimeout)):this.emit("onicecandidates",[a.candidate]));},this.peer.ontrack=a=>{a.streams&&this.emit("streamRemote",a.streams[0]);},this.peer.oniceconnectionstatechange=()=>{switch(this.emit("status",this.status()),this.status()){case"closed":case"failed":case"disconnected":f(),this.destroy();break;case"checking":this.emit("connecting");break;case"connected":this.emit("connected");}},this.peer.onnegotiationneeded=async()=>{try{if(!this.isActive)return;this.makingOffer=!0;let{offerOptions:c,sdpTransform:d}=this.options;this.createDataChannels();let a=await this.peer.createOffer(c);if("stable"!==this.peer.signalingState)return;a.sdp=a.sdp&&d(a.sdp),await this.peer.setLocalDescription(a),this.peer.localDescription&&this.emit("signal",this.peer.localDescription);}catch(b){b instanceof Error&&this.error("Failed in negotiationNeeded",b);}finally{this.makingOffer=!1;}},this.peer.ondatachannel=b=>{let{channel:a}=b;this.options.enableDataChannels&&(this.channels.set(a.label,a),this.addDataChannelEvents(a));},this.peer}start(){let{polite:b=!0}=arguments.length>0&& void 0!==arguments[0]?arguments[0]:{};try{"have-local-offer"===this.peer.signalingState&&this.destroy(),this.isClosed()&&this.init(),this.isActive=!0,this.polite=b,this.peer.restartIce();}catch(a){if(a instanceof Error)throw this.error("Failed to start",a),a}}async signal(b){try{this.isClosed()&&this.init(),this.isActive=!0;let d="offer"===b.type&&(this.makingOffer||"stable"!==this.peer.signalingState);if(this.ignoreOffer=!this.polite&&d,this.ignoreOffer)return;if(await this.peer.setRemoteDescription(b),"offer"===b.type){this.createDataChannels();let a=await this.peer.createAnswer();a.sdp=a.sdp&&this.options.sdpTransform(a.sdp),await this.peer.setLocalDescription(a),this.emit("signal",a);}this.polite=!0;}catch(c){if(c instanceof Error)throw this.error("Failed to signal",c),c}}async addIceCandidate(b){try{await this.peer.addIceCandidate(b);}catch(a){if(!this.ignoreOffer&&a instanceof Error)throw this.error("Failed to addIceCandidate",a),a}}send(b){let c=arguments.length>1&& void 0!==arguments[1]?arguments[1]:this.options.channelLabel,a=this.channels.get(c);return (null==a?void 0:a.readyState)==="open"&&!!b&&(a.send(b),this.emit("channelData",{channel:a,data:b,source:"outgoing"}),!0)}addDataChannel(){let a=arguments.length>0&& void 0!==arguments[0]?arguments[0]:this.options.channelLabel,b=arguments.length>1&& void 0!==arguments[1]?arguments[1]:{};if(!this.options.enableDataChannels){this.error('Failed to addDataChannel as "enableDataChannels" is false');return}if(this.isClosed()){this.error("Failed to addDataChannel as peer connection is closed");return}this.channels.has(a)||this.channelsPending.set(a,b),this.isActive&&this.createDataChannels();}getDataChannel(){let a=arguments.length>0&& void 0!==arguments[0]?arguments[0]:this.options.channelLabel;return this.channels.get(a)}createDataChannels(){try{Array.from(this.channelsPending.entries()).forEach(c=>{let[a,d]=c,b=this.peer.createDataChannel(a,d);this.channels.set(a,b),this.addDataChannelEvents(b);}),this.channelsPending.clear();}catch(a){if(a instanceof Error)throw this.error("Failed to createDataChannels",a),a}}addDataChannelEvents(a){a.onopen=()=>this.emit("channelOpen",{channel:a}),a.onerror=b=>{this.emit("channelError",{channel:a,event:b});},a.onclose=()=>{this.channels.delete(a.label),this.emit("channelClosed",{channel:a});},a.onmessage=b=>{this.emit("channelData",{channel:a,data:b.data,source:"incoming"});};}destroy(){this.isClosed()||(this.polite=!0,this.isActive=!1,this.makingOffer=!1,this.ignoreOffer=!1,this.channels.clear(),this.channelsPending.clear(),this.peer.close(),this.emit("disconnected"));}status(){var a,b;return null!==(b=null===(a=this.peer)|| void 0===a?void 0:a.iceConnectionState)&& void 0!==b?b:"closed"}isConnected(){return "connected"===this.status()}isClosed(){return "closed"===this.status()}get(){return this.peer}getStreamLocal(){return this.streamLocal}error(a,b){this.emit("error",{name:this.options.name,message:a,error:b});}addStream(a){let b=arguments.length>1&& void 0!==arguments[1]&&arguments[1];b&&this.removeTracks(this.streamLocal.getTracks()),a.getTracks().forEach(a=>this.addTrack(a));}removeStream(a){this.removeTracks(a.getTracks());}addTrack(b){try{this.streamLocal.addTrack(b),this.emit("streamLocal",this.streamLocal),this.isClosed()||this.peer.addTrack(b,this.streamLocal);}catch(a){if(a instanceof Error)throw this.error("Failed to addTrack",a),a}}removeTracks(a){a.forEach(a=>this.removeTrack(a));}removeTrack(a){removeTracks(this.streamLocal,filterByTrack(a)),this.isClosed()||removeTracksFromPeer(this.peer,filterByTrack(a));}async replaceTrack(c,d){try{if(!this.isClosed()){let[f]=this.peer.getSenders().filter(a=>a.track===c);f?(removeTracks(this.streamLocal,filterByTrack(c)),this.streamLocal.addTrack(d),await f.replaceTrack(d),this.emit("streamLocal",this.streamLocal)):this.error(`Failed to find track to replace: ${c.id}`);}}catch(a){if(a instanceof Error)throw this.error("Failed to replaceTrack",a),a}}on(a,b){return this.emitter.on(a,b)}off(a,b){return this.emitter.off(a,b)}emit(d){for(var b=arguments.length,c=new Array(b>1?b-1:0),a=1;a<b;a++)c[a-1]=arguments[a];return this.emitter.emit(d,...c)}static getUserMedia(a){return navigator.mediaDevices.getUserMedia({...getDefaultCamConstraints(),...a})}}
class g{constructor(b){this.streamLocal=new MediaStream,this.channels=new Map,this.channelsPending=new Map,this.emitter=new EventEmitter,this.polite=!0,this.isActive=!1,this.makingOffer=!1,this.ignoreOffer=!1,this.options={batchCandidates:!0,batchCandidatesTimeout:200,id:randomHex(4),config:{iceServers:[{urls:["stun:stun.l.google.com:19302"]}]},offerOptions:{},enableDataChannels:!1,channelLabel:randomHex(20),channelOptions:{},sdpTransform:a=>a},this.options={...this.options,...b},this.peer=this.init();}init(){if("new"===this.status())return this.peer;this.destroy(),this.peer=new RTCPeerConnection(this.options.config),this.streamLocal.getTracks().forEach(a=>this.peer.addTrack(a,this.streamLocal));let{channelLabel:a,channelOptions:b,enableDataChannels:c}=this.options;c&&this.addDataChannel(a,b);let d=[],e;function f(){clearTimeout(e),d.length=0;}return this.peer.onicecandidate=a=>{(null==a?void 0:a.candidate)&&(this.options.batchCandidates?(clearTimeout(e),d.push(a.candidate),"complete"===this.peer.iceGatheringState?this.emit("onicecandidates",d):e=setTimeout(()=>{d.length&&(this.emit("onicecandidates",d),f());},this.options.batchCandidatesTimeout)):this.emit("onicecandidates",[a.candidate]));},this.peer.ontrack=a=>{a.streams&&this.emit("streamRemote",a.streams[0]);},this.peer.oniceconnectionstatechange=()=>{switch(this.emit("status",this.status()),this.status()){case"closed":case"failed":case"disconnected":f(),this.destroy();break;case"checking":this.emit("connecting");break;case"connected":this.emit("connected");}},this.peer.onnegotiationneeded=async()=>{try{if(!this.isActive)return;this.makingOffer=!0;let{offerOptions:c,sdpTransform:d}=this.options;this.createDataChannels();let a=await this.peer.createOffer(c);if("stable"!==this.peer.signalingState)return;a.sdp=a.sdp&&d(a.sdp),await this.peer.setLocalDescription(a),this.peer.localDescription&&this.emit("signal",this.peer.localDescription);}catch(b){b instanceof Error&&this.error("Failed in negotiationNeeded",b);}finally{this.makingOffer=!1;}},this.peer.ondatachannel=b=>{let{channel:a}=b;this.options.enableDataChannels&&(this.channels.set(a.label,a),this.addDataChannelEvents(a));},this.peer}start(){let{polite:b=!0}=arguments.length>0&& void 0!==arguments[0]?arguments[0]:{};try{"have-local-offer"===this.peer.signalingState&&this.destroy(),this.isClosed()&&this.init(),this.isActive=!0,this.polite=b,this.peer.restartIce();}catch(a){if(a instanceof Error)throw this.error("Failed to start",a),a}}async signal(b){try{this.isClosed()&&this.init(),this.isActive=!0;let d="offer"===b.type&&(this.makingOffer||"stable"!==this.peer.signalingState);if(this.ignoreOffer=!this.polite&&d,this.ignoreOffer)return;if(await this.peer.setRemoteDescription(b),"offer"===b.type){this.createDataChannels();let a=await this.peer.createAnswer();a.sdp=a.sdp&&this.options.sdpTransform(a.sdp),await this.peer.setLocalDescription(a),this.emit("signal",a);}this.polite=!0;}catch(c){if(c instanceof Error)throw this.error("Failed to signal",c),c}}async addIceCandidate(b){try{await this.peer.addIceCandidate(b);}catch(a){if(!this.ignoreOffer&&a instanceof Error)throw this.error("Failed to addIceCandidate",a),a}}send(b){let c=arguments.length>1&& void 0!==arguments[1]?arguments[1]:this.options.channelLabel,a=this.channels.get(c);return (null==a?void 0:a.readyState)==="open"&&!!b&&(a.send(b),this.emit("channelData",{channel:a,data:b,source:"outgoing"}),!0)}addDataChannel(){let a=arguments.length>0&& void 0!==arguments[0]?arguments[0]:this.options.channelLabel,b=arguments.length>1&& void 0!==arguments[1]?arguments[1]:{};if(!this.options.enableDataChannels){this.error('Failed to addDataChannel as "enableDataChannels" is false');return}if(this.isClosed()){this.error("Failed to addDataChannel as peer connection is closed");return}this.channels.has(a)||this.channelsPending.set(a,b),this.isActive&&this.createDataChannels();}getDataChannel(){let a=arguments.length>0&& void 0!==arguments[0]?arguments[0]:this.options.channelLabel;return this.channels.get(a)}createDataChannels(){try{Array.from(this.channelsPending.entries()).forEach(c=>{let[a,d]=c,b=this.peer.createDataChannel(a,d);this.channels.set(a,b),this.addDataChannelEvents(b);}),this.channelsPending.clear();}catch(a){if(a instanceof Error)throw this.error("Failed to createDataChannels",a),a}}addDataChannelEvents(a){a.onopen=()=>this.emit("channelOpen",{channel:a}),a.onerror=b=>{this.emit("channelError",{channel:a,event:b});},a.onclose=()=>{this.channels.delete(a.label),this.emit("channelClosed",{channel:a});},a.onmessage=b=>{this.emit("channelData",{channel:a,data:b.data,source:"incoming"});};}destroy(){this.isClosed()||(this.polite=!0,this.isActive=!1,this.makingOffer=!1,this.ignoreOffer=!1,this.channels.clear(),this.channelsPending.clear(),this.peer.close(),this.emit("disconnected"));}status(){var a,b;return null!==(b=null===(a=this.peer)|| void 0===a?void 0:a.iceConnectionState)&& void 0!==b?b:"closed"}isConnected(){return "connected"===this.status()}isClosed(){return "closed"===this.status()}get(){return this.peer}getStreamLocal(){return this.streamLocal}error(a,b){this.emit("error",{id:this.options.id,message:a,error:b});}addStream(a){let b=arguments.length>1&& void 0!==arguments[1]&&arguments[1];b&&this.removeTracks(this.streamLocal.getTracks()),a.getTracks().forEach(a=>this.addTrack(a));}removeStream(a){this.removeTracks(a.getTracks());}addTrack(b){try{this.streamLocal.addTrack(b),this.emit("streamLocal",this.streamLocal),this.isClosed()||this.peer.addTrack(b,this.streamLocal);}catch(a){if(a instanceof Error)throw this.error("Failed to addTrack",a),a}}removeTrack(a){removeTracks(this.streamLocal,filterByTrack(a)),this.isClosed()||removeTracksFromPeer(this.peer,filterByTrack(a));}removeTracks(a){a.forEach(a=>this.removeTrack(a));}async replaceTrack(c,d){try{if(!this.isClosed()){let[f]=this.peer.getSenders().filter(a=>a.track===c);f?(removeTracks(this.streamLocal,filterByTrack(c)),this.streamLocal.addTrack(d),await f.replaceTrack(d),this.emit("streamLocal",this.streamLocal)):this.error(`Failed to find track to replace: ${c.id}`);}}catch(a){if(a instanceof Error)throw this.error("Failed to replaceTrack",a),a}}on(a,b){return this.emitter.on(a,b)}off(a,b){return this.emitter.off(a,b)}offAll(a){return this.emitter.offAll(a)}emit(d){for(var b=arguments.length,c=new Array(b>1?b-1:0),a=1;a<b;a++)c[a-1]=arguments[a];return this.emitter.emit(d,...c)}static getUserMedia(a){return navigator.mediaDevices.getUserMedia({...getDefaultCamConstraints(),...a})}}

@@ -14,0 +14,0 @@ return g;

declare type ListenerFunction = (...args: any[]) => void;
export declare class EventEmitter {
private listeners;
on(eventName: string, listener: ListenerFunction): this;
off(eventName: string, listener: ListenerFunction): this;
emit(eventName: string, ...args: any[]): boolean;
private eventMap;
emit(event: string, ...args: any[]): boolean;
on(event: string, listener: ListenerFunction): this;
off(event: string, listener: ListenerFunction): this;
offAll(event?: string): this;
}
export {};

@@ -52,12 +52,13 @@ import { PeerEvents, PeerOptions, TypedEmitter } from './types';

addTrack(track: MediaStreamTrack): void;
/** Remove track on peer */
removeTrack(track: MediaStreamTrack): void;
/** Remove tracks on peer */
removeTracks(tracks: MediaStreamTrack[]): void;
/** Remove track on peer */
removeTrack(track: MediaStreamTrack): void;
/** Replace track with another track on peer */
replaceTrack(track: MediaStreamTrack, newTrack: MediaStreamTrack): Promise<void>;
on<E extends keyof PeerEvents>(event: E, cb: PeerEvents[E]): TypedEmitter<PeerEvents>;
off<E extends keyof PeerEvents>(event: E, cb: PeerEvents[E]): TypedEmitter<PeerEvents>;
on<E extends keyof PeerEvents>(event: E, listener: PeerEvents[E]): TypedEmitter<PeerEvents>;
off<E extends keyof PeerEvents>(event: E, listener: PeerEvents[E]): TypedEmitter<PeerEvents>;
offAll<E extends keyof PeerEvents>(event?: E): TypedEmitter<PeerEvents>;
private emit;
static getUserMedia(constraints?: MediaStreamConstraints): Promise<MediaStream>;
}

@@ -6,2 +6,3 @@ export declare type Arguments<T> = [T] extends [(...args: infer U) => any] ? U : [T] extends [void] ? [] : [T];

off<E extends keyof Events>(event: E, listener: Events[E]): this;
offAll<E extends keyof Events>(event?: E): this;
emit<E extends keyof Events>(event: E, ...args: Arguments<Events[E]>): boolean;

@@ -11,3 +12,3 @@ }

error: (data: {
name: string;
id: string;
message: string;

@@ -45,4 +46,4 @@ error?: Error;

batchCandidatesTimeout?: number;
/** Peer name used when emitting errors */
name?: string;
/** Peer id used when emitting errors */
id?: string;
/** RTCPeerConnection options */

@@ -49,0 +50,0 @@ config?: RTCConfiguration;

{
"name": "peer-lite",
"description": "Lightweight WebRTC browser library that supports video, audio and data channels",
"version": "2.0.0-beta.0",
"version": "2.0.0",
"license": "MIT",

@@ -24,3 +24,5 @@ "keywords": [

"build": "rollup --config build/rollup.config.ts --configPlugin typescript",
"test": "playwright test",
"test": "yarn test:playwright && yarn test:jest",
"test:playwright": "playwright test ./test/peer.spec.ts",
"test:jest": "jest",
"prepublishOnly": "npm run build",

@@ -34,7 +36,9 @@ "lint": "eslint . --ext .tsx --ext .ts --ext .js"

"@rollup/plugin-typescript": "^8.3.2",
"@swc/core": "^1.2.194",
"@types/node": "^17.0.35",
"@swc/core": "^1.2.196",
"@swc/jest": "^0.2.21",
"@types/jest": "^28.1.0",
"@types/node": "^17.0.38",
"@types/webrtc": "^0.0.32",
"@typescript-eslint/eslint-plugin": "^5.26.0",
"@typescript-eslint/parser": "^5.26.0",
"@typescript-eslint/eslint-plugin": "^5.27.0",
"@typescript-eslint/parser": "^5.27.0",
"eslint": "^8.16.0",

@@ -45,2 +49,3 @@ "eslint-config-airbnb": "^19.0.4",

"eslint-plugin-import": "^2.26.0",
"eslint-plugin-jest": "^26.4.6",
"eslint-plugin-jsx-a11y": "^6.5.1",

@@ -50,6 +55,7 @@ "eslint-plugin-playwright": "^0.9.0",

"eslint-plugin-react": "^7.30.0",
"jest": "^28.1.0",
"playwright": "^1.22.2",
"prettier": "^2.6.2",
"rimraf": "^3.0.2",
"rollup": "^2.75.0",
"rollup": "^2.75.5",
"rollup-plugin-swc": "^0.2.1",

@@ -60,3 +66,13 @@ "typescript": "^4.7.2"

"dist"
]
],
"jest": {
"modulePathIgnorePatterns": [
"./test/peer.spec.ts"
],
"transform": {
"^.+\\.(t|j)sx?$": [
"@swc/jest"
]
}
}
}

@@ -10,3 +10,4 @@ # PeerLite

* Zero dependencies
* Using modern WebRTC APIs with TypeScript Types
* Ships with TypeScript definitions
* Uses modern WebRTC APIs
* ["Perfect negotiation"](https://developer.mozilla.org/en-US/docs/Web/API/WebRTC_API/Perfect_negotiation) pattern

@@ -115,6 +116,5 @@ * Support for [renegotiation](https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/onnegotiationneeded) of connection

### Peer Options
## Peer Options
```typescript
export interface PeerOptions {
interface PeerOptions {
/** Enable support for batching ICECandidates */

@@ -124,4 +124,4 @@ batchCandidates?: boolean;

batchCandidatesTimeout?: number;
/** Peer name used when emitting errors */
name?: string;
/** Peer id used when emitting errors */
id?: string;
/** RTCPeerConnection options */

@@ -142,6 +142,57 @@ config?: RTCConfiguration;

### Peer Events
## Peer API
```typescript
export interface PeerEvents {
error: (data: { name: string; message: string; error?: Error }) => void;
interface Peer {
/** Create a peer instance */
constructor(options?: PeerOptions);
/** Initialize the peer */
init(): RTCPeerConnection;
/** Start the RTCPeerConnection signalling */
start({ polite }?: {
polite?: boolean | undefined;
}): void;
/** Process a RTCSessionDescriptionInit on peer */
signal(description: RTCSessionDescriptionInit): Promise<void>;
/** Add RTCIceCandidate to peer */
addIceCandidate(candidate: RTCIceCandidate): Promise<void>;
/** Send data to connected peer using an RTCDataChannel */
send(data: string | Blob | ArrayBuffer | ArrayBufferView, label?: string): boolean;
/** Add RTCDataChannel to peer */
addDataChannel(label?: string, options?: RTCDataChannelInit): void;
/** Get RTCDataChannel added to peer */
getDataChannel(label?: string): RTCDataChannel | undefined;
/** Close peer if active */
destroy(): void;
/** Return the ICEConnectionState of the peer */
status(): RTCIceConnectionState;
/** Return true if the peer is connected */
isConnected(): boolean;
/** Return true if the peer is closed */
isClosed(): boolean;
/** Return the RTCPeerConnection */
get(): RTCPeerConnection;
/** Return the local stream */
getStreamLocal(): MediaStream;
/** Add stream to peer */
addStream(stream: MediaStream, replace?: boolean): void;
/** Remove stream from peer */
removeStream(stream: MediaStream): void;
/** Add track to peer */
addTrack(track: MediaStreamTrack): void;
/** Remove track on peer */
removeTrack(track: MediaStreamTrack): void;
/** Remove tracks on peer */
removeTracks(tracks: MediaStreamTrack[]): void;
/** Replace track with another track on peer */
replaceTrack(track: MediaStreamTrack, newTrack: MediaStreamTrack): Promise<void>;
on<E extends keyof PeerEvents>(event: E, listener: PeerEvents[E]): TypedEmitter<PeerEvents>;
off<E extends keyof PeerEvents>(event: E, listener: PeerEvents[E]): TypedEmitter<PeerEvents>;
offAll<E extends keyof PeerEvents>(event?: E): TypedEmitter<PeerEvents>;
}
```
## Peer Events
```typescript
interface PeerEvents {
error: (data: { id: string; message: string; error?: Error }) => void;
// Connection Status

@@ -175,3 +226,3 @@ connecting: VoidFunction;

Run Tests (Chrome only)
**Run Tests (Chrome only)**
```bash

@@ -181,3 +232,3 @@ yarn test

Run Tests (Chrome + Firefox)
**Run Tests (Chrome + Firefox)**
```bash

@@ -184,0 +235,0 @@ CI=true yarn test

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc