diff --git a/.eslintcache b/.eslintcache new file mode 100644 index 0000000000000000000000000000000000000000..37764a5679846af7d69aae1e6d2c03f529d705f9 --- /dev/null +++ b/.eslintcache @@ -0,0 +1 @@ +{"/Users/leon/liowebrtc/test/selenium/index.js":{"size":160,"mtime":1526638470508,"hashOfConfig":"1dw2gtw","results":{"filePath":"/Users/leon/liowebrtc/test/selenium/index.js","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0}}} \ No newline at end of file diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000000000000000000000000000000000000..ae8216972fdbf7eff01f7fe1d9b413afa7a4edf4 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,30 @@ +# Logs +logs +*.log + +# Runtime data +pids +*.pid +*.seed + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release +.eslintcache + +# Dependency directory +node_modules + +# OSX +.DS_Store diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000000000000000000000000000000000000..fa3083b87089a5ede14928a5646028cc556613e0 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,17 @@ +{ + "parser": "babel-eslint", + "parserOptions": { + "sourceType": "module", + "allowImportExportEverywhere": false, + "codeFrame": false + }, + "extends": "airbnb", + "rules": { + "max-len": 0, + "no-multi-assign": 0, + "no-restricted-syntax": 0, + "no-param-reassign": 0, + "no-shadow": 0, + "consistent-return": 0 + } +} diff --git a/package.json b/package.json index c00bd0acbf80330ff658004ac73eee623687e430..8d1f3c8521ec470f8a6b485fa24fa471d82f82eb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "liowebrtc", - "version": "0.1.7", + "version": "0.1.8", "repository": "https://github.com/lazorfuzz/liowebrtc", "main": "./dist/liowebrtc.js", "description": "An Electron-compatible WebRTC library that makes it easy to embed peer to peer communication into react components.", @@ -17,8 +17,14 @@ }, "devDependencies": { "babel-cli": "^6.26.0", + "babel-eslint": "^8.2.3", "babel-preset-env": "^1.7.0", "chromedriver": "^2.29.0", + "eslint": "^4.19.1", + "eslint-config-airbnb": "^16.1.0", + "eslint-plugin-import": "^2.7.0", + "eslint-plugin-jsx-a11y": "^6.0.2", + "eslint-plugin-react": "^7.4.0", "geckodriver": "^1.6.1", "request": "^2.72.0", "selenium-webdriver": "^3.0.1", @@ -30,7 +36,7 @@ "scripts": { "build": "babel src --presets babel-preset-env --out-dir dist", "test-travis": "test/run-selenium", - "lint": "jshint src", + "lint": "eslint --cache --fix .", "validate": "npm ls", "test-page": "echo \"open https://localhost:8443/test/\" && stupid-server -s", "test": "node test/selenium/index.js" diff --git a/src/liowebrtc.js b/src/liowebrtc.js index 6555da3fa09a4e24c862ffdc3b6fd02bb0ef379e..356b6a797ce2830ea7dabf908dd6fd6fd4905afd 100644 --- a/src/liowebrtc.js +++ b/src/liowebrtc.js @@ -25,32 +25,32 @@ class LioWebRTC extends WildEmitter { peerVolumeWhenSpeaking: 0.25, media: { video: true, - audio: true + audio: true, }, receiveMedia: { offerToReceiveAudio: 1, - offerToReceiveVideo: 1 + offerToReceiveVideo: 1, }, localVideo: { autoplay: true, mirror: false, - muted: true - } + muted: true, + }, }; let connection; this.logger = ((() => { - // we assume that if you're in debug mode and you didn't - // pass in a logger, you actually want to log as much as - // possible. + // we assume that if you're in debug mode and you didn't + // pass in a logger, you actually want to log as much as + // possible. if (opts.debug) { return opts.logger || console; } return opts.logger || mockconsole; })()); - // set our config from options - Object.keys(options).forEach(o => { + // set our config from options + Object.keys(options).forEach((o) => { this.config[o] = options[o]; }); @@ -61,13 +61,13 @@ class LioWebRTC extends WildEmitter { this.config.receiveMedia.offerToReceiveVideo = false; } - // attach detected support for convenience + // attach detected support for convenience this.capabilities = webrtcSupport; - // call WildEmitter constructor + // call WildEmitter constructor WildEmitter.call(this); - // create default SocketIoConnection if it's not passed in + // create default SocketIoConnection if it's not passed in if (this.config.connection === null) { connection = this.connection = new SocketIoConnection(this.config); } else { @@ -89,7 +89,7 @@ class LioWebRTC extends WildEmitter { peers.forEach((p) => { if (p.sid === message.sid) peer = p; }); - // if (!peer) peer = peers[0]; // fallback for old protocol versions + // if (!peer) peer = peers[0]; // fallback for old protocol versions } if (!peer) { peer = self.webrtc.createPeer({ @@ -98,7 +98,7 @@ class LioWebRTC extends WildEmitter { type: message.roomType, enableDataChannels: self.config.enableDataChannels && message.roomType !== 'screen', sharemyscreen: message.roomType === 'screen' && !message.broadcaster, - broadcaster: message.roomType === 'screen' && !message.broadcaster ? self.connection.getSessionid() : null + broadcaster: message.roomType === 'screen' && !message.broadcaster ? self.connection.getSessionid() : null, }); self.emit('createdPeer', peer); } @@ -122,28 +122,28 @@ class LioWebRTC extends WildEmitter { } }); - // instantiate our main WebRTC helper - // using same logger from logic here + // instantiate our main WebRTC helper + // using same logger from logic here opts.logger = this.logger; opts.debug = false; this.webrtc = new WebRTC(opts); - // attach a few methods from underlying lib to liowebrtc. + // attach a few methods from underlying lib to liowebrtc. ['mute', 'unmute', 'pauseVideo', 'resumeVideo', 'pause', 'resume', 'sendToAll', 'sendDirectlyToAll', 'getPeers', 'shout', 'whisper'].forEach((method) => { self[method] = self.webrtc[method].bind(self.webrtc); }); - // proxy events from WebRTC + // proxy events from WebRTC this.webrtc.on('*', function () { self.emit(...arguments); }); - // log all events in debug mode + // log all events in debug mode if (config.debug) { this.on('*', this.logger.log.bind(this.logger, 'LioWebRTC event:')); } - // check for readiness + // check for readiness this.webrtc.on('localStream', () => { self.testReadiness(); }); @@ -155,32 +155,32 @@ class LioWebRTC extends WildEmitter { this.webrtc.on('peerStreamAdded', this.handlePeerStreamAdded.bind(this)); this.webrtc.on('peerStreamRemoved', this.handlePeerStreamRemoved.bind(this)); - // echo cancellation attempts + // echo cancellation attempts if (this.config.adjustPeerVolume) { this.webrtc.on('speaking', this.setVolumeForAll.bind(this, this.config.peerVolumeWhenSpeaking)); this.webrtc.on('stoppedSpeaking', this.setVolumeForAll.bind(this, 1)); } connection.on('stunservers', (args) => { - // resets/overrides the config + // resets/overrides the config self.webrtc.config.peerConnectionConfig.iceServers = args; self.emit('stunservers', args); }); connection.on('turnservers', (args) => { - // appends to the config + // appends to the config self.webrtc.config.peerConnectionConfig.iceServers = self.webrtc.config.peerConnectionConfig.iceServers.concat(args); self.emit('turnservers', args); }); this.webrtc.on('iceFailed', (peer) => { - // local ice failure + // local ice failure }); this.webrtc.on('connectivityError', (peer) => { - // remote ice failure + // remote ice failure }); - // sending mute/unmute to all peers + // sending mute/unmute to all peers this.webrtc.on('audioOn', () => { self.webrtc.sendToAll('unmute', { name: 'audio' }); }); @@ -194,11 +194,11 @@ class LioWebRTC extends WildEmitter { self.webrtc.sendToAll('mute', { name: 'video' }); }); - // screensharing events + // screensharing events this.webrtc.on('localScreen', (stream) => { let item; - let el = document.createElement('video'); - let container = self.getRemoteVideoContainer(); + const el = document.createElement('video'); + const container = self.getRemoteVideoContainer(); el.oncontextmenu = () => false; el.id = 'localScreen'; @@ -220,7 +220,7 @@ class LioWebRTC extends WildEmitter { enableDataChannels: false, receiveMedia: { offerToReceiveAudio: 0, - offerToReceiveVideo: 0 + offerToReceiveVideo: 0, }, broadcaster: self.connection.getSessionid(), }); @@ -233,7 +233,7 @@ class LioWebRTC extends WildEmitter { if (self.getLocalScreen()) { self.stopScreenShare(); } - /* + /* self.connection.emit('unshareScreen'); self.webrtc.peers.forEach(function (peer) { if (peer.sharemyscreen) { @@ -278,10 +278,10 @@ class LioWebRTC extends WildEmitter { this.emit('videoAdded', peer.stream, peer); - // send our mute status to new peer if we're muted - // currently called with a small delay because it arrives before - // the video element is created otherwise (which happens after - // the async setRemoteDescription-createAnswer) + // send our mute status to new peer if we're muted + // currently called with a small delay because it arrives before + // the video element is created otherwise (which happens after + // the async setRemoteDescription-createAnswer) setTimeout(() => { if (!self.webrtc.isAudioEnabled()) { peer.send('mute', { name: 'audio' }); @@ -296,10 +296,14 @@ class LioWebRTC extends WildEmitter { this.emit('videoRemoved', peer); } - getDomId(peer) { + getId(peer) { return [peer.id, peer.type, peer.broadcaster ? 'broadcasting' : 'incoming'].join('_'); } + getContainerId(peer) { + return `container_${this.getId(peer)}`; + } + // set volume on video tag for all peers takse a value between 0 and 1 setVolumeForAll(volume) { this.webrtc.peers.forEach((peer) => { @@ -329,8 +333,8 @@ class LioWebRTC extends WildEmitter { enableDataChannels: self.config.enableDataChannels && type !== 'screen', receiveMedia: { offerToReceiveAudio: type !== 'screen' && !self.config.dataOnly && self.config.receiveMedia.offerToReceiveAudio ? 1 : 0, - offerToReceiveVideo: !self.config.dataOnly && self.config.receiveMedia.offerToReceiveVideo - } + offerToReceiveVideo: !self.config.dataOnly && self.config.receiveMedia.offerToReceiveVideo, + }, }); self.emit('createdPeer', peer); peer.start(); @@ -376,8 +380,8 @@ class LioWebRTC extends WildEmitter { container.removeChild(videoEl); } - // a hack to emit the event the removes the video - // element that we want + // a hack to emit the event the removes the video + // element that we want if (videoEl) { this.emit('videoRemoved', videoEl); } @@ -391,6 +395,10 @@ class LioWebRTC extends WildEmitter { }); } + attachStream(stream, el) { + attachMediaStream(stream, el); + } + testReadiness() { const self = this; if (this.sessionReady) { diff --git a/src/localmedia.js b/src/localmedia.js index f82762c06efabb4807c4a20df32aaf888ff99726..5106376c37bac3f9160f56d7234a476ae9a79c6d 100644 --- a/src/localmedia.js +++ b/src/localmedia.js @@ -4,11 +4,11 @@ import WildEmitter from 'wildemitter'; import mockconsole from 'mockconsole'; function isAllTracksEnded(stream) { - let isAllTracksEnded = true; - stream.getTracks().forEach(t => { - isAllTracksEnded = t.readyState === 'ended' && isAllTracksEnded; - }); - return isAllTracksEnded; + let isAllTracksEnded = true; + stream.getTracks().forEach((t) => { + isAllTracksEnded = t.readyState === 'ended' && isAllTracksEnded; + }); + return isAllTracksEnded; } function shouldWorkAroundFirefoxStopStream() { @@ -27,21 +27,21 @@ class LocalMedia extends WildEmitter { constructor(opts) { super(); const config = this.config = { - detectSpeakingEvents: false, - audioFallback: false, - media: { - audio: true, - video: true - }, - harkOptions: null, - logger: mockconsole + detectSpeakingEvents: false, + audioFallback: false, + media: { + audio: true, + video: true, + }, + harkOptions: null, + logger: mockconsole, }; let item; for (item in opts) { - if (opts.hasOwnProperty(item)) { - this.config[item] = opts[item]; - } + if (opts.hasOwnProperty(item)) { + this.config[item] = opts[item]; + } } this.logger = config.logger; @@ -52,7 +52,7 @@ class LocalMedia extends WildEmitter { this.localScreens = []; if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) { - this._logerror('Your browser does not support local media capture.'); + this._logerror('Your browser does not support local media capture.'); } this._audioMonitors = []; @@ -61,264 +61,264 @@ class LocalMedia extends WildEmitter { } start(mediaConstraints, cb) { - const self = this; - const constraints = mediaConstraints || this.config.media; + const self = this; + const constraints = mediaConstraints || this.config.media; - this.emit('localStreamRequested', constraints); - - navigator.mediaDevices.getUserMedia(constraints).then(stream => { - if (constraints.audio && self.config.detectSpeakingEvents) { - self._setupAudioMonitor(stream, self.config.harkOptions); - } - self.localStreams.push(stream); - - stream.getTracks().forEach(track => { - track.addEventListener('ended', () => { - if (isAllTracksEnded(stream)) { - self._removeStream(stream); - } - }); - }); + this.emit('localStreamRequested', constraints); - self.emit('localStream', stream); + navigator.mediaDevices.getUserMedia(constraints).then((stream) => { + if (constraints.audio && self.config.detectSpeakingEvents) { + self._setupAudioMonitor(stream, self.config.harkOptions); + } + self.localStreams.push(stream); - if (cb) { - return cb(null, stream); - } - }).catch(err => { - // Fallback for users without a camera - if (self.config.audioFallback && err.name === 'NotFoundError' && constraints.video !== false) { - constraints.video = false; - self.start(constraints, cb); - return; - } - - self.emit('localStreamRequestFailed', constraints); - - if (cb) { - return cb(err, null); + stream.getTracks().forEach((track) => { + track.addEventListener('ended', () => { + if (isAllTracksEnded(stream)) { + self._removeStream(stream); } + }); }); + + self.emit('localStream', stream); + + if (cb) { + return cb(null, stream); + } + }).catch((err) => { + // Fallback for users without a camera + if (self.config.audioFallback && err.name === 'NotFoundError' && constraints.video !== false) { + constraints.video = false; + self.start(constraints, cb); + return; + } + + self.emit('localStreamRequestFailed', constraints); + + if (cb) { + return cb(err, null); + } + }); } stop(stream) { - this.stopStream(stream); - this.stopScreenShare(stream); + this.stopStream(stream); + this.stopScreenShare(stream); } stopStream(stream) { - const self = this; - - if (stream) { - const idx = this.localStreams.indexOf(stream); - if (idx > -1) { - stream.getTracks().forEach(track => { track.stop(); }); + const self = this; - //Half-working fix for Firefox, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1208373 - if (shouldWorkAroundFirefoxStopStream()) { - this._removeStream(stream); - } - } - } else { - this.localStreams.forEach(stream => { - stream.getTracks().forEach(track => { track.stop(); }); + if (stream) { + const idx = this.localStreams.indexOf(stream); + if (idx > -1) { + stream.getTracks().forEach((track) => { track.stop(); }); - //Half-working fix for Firefox, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1208373 - if (shouldWorkAroundFirefoxStopStream()) { - self._removeStream(stream); - } - }); + // Half-working fix for Firefox, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1208373 + if (shouldWorkAroundFirefoxStopStream()) { + this._removeStream(stream); + } } + } else { + this.localStreams.forEach((stream) => { + stream.getTracks().forEach((track) => { track.stop(); }); + + // Half-working fix for Firefox, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1208373 + if (shouldWorkAroundFirefoxStopStream()) { + self._removeStream(stream); + } + }); + } } startScreenShare(constraints, cb) { - const self = this; + const self = this; - this.emit('localScreenRequested'); + this.emit('localScreenRequested'); - if (typeof constraints === 'function' && !cb) { - cb = constraints; - constraints = null; - } + if (typeof constraints === 'function' && !cb) { + cb = constraints; + constraints = null; + } - getScreenMedia(constraints, (err, stream) => { - if (!err) { - self.localScreens.push(stream); - - stream.getTracks().forEach(track => { - track.addEventListener('ended', () => { - let isAllTracksEnded = true; - stream.getTracks().forEach(t => { - isAllTracksEnded = t.readyState === 'ended' && isAllTracksEnded; - }); - - if (isAllTracksEnded) { - self._removeStream(stream); - } - }); - }); - - self.emit('localScreen', stream); - } else { - self.emit('localScreenRequestFailed'); - } + getScreenMedia(constraints, (err, stream) => { + if (!err) { + self.localScreens.push(stream); - // enable the callback - if (cb) { - return cb(err, stream); - } - }); + stream.getTracks().forEach((track) => { + track.addEventListener('ended', () => { + let isAllTracksEnded = true; + stream.getTracks().forEach((t) => { + isAllTracksEnded = t.readyState === 'ended' && isAllTracksEnded; + }); + + if (isAllTracksEnded) { + self._removeStream(stream); + } + }); + }); + + self.emit('localScreen', stream); + } else { + self.emit('localScreenRequestFailed'); + } + + // enable the callback + if (cb) { + return cb(err, stream); + } + }); } stopScreenShare(stream) { - const self = this; - - if (stream) { - const idx = this.localScreens.indexOf(stream); - if (idx > -1) { - stream.getTracks().forEach(track => { track.stop(); }); + const self = this; - //Half-working fix for Firefox, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1208373 - if (shouldWorkAroundFirefoxStopStream()) { - this._removeStream(stream); - } - } - } else { - this.localScreens.forEach(stream => { - stream.getTracks().forEach(track => { track.stop(); }); + if (stream) { + const idx = this.localScreens.indexOf(stream); + if (idx > -1) { + stream.getTracks().forEach((track) => { track.stop(); }); - //Half-working fix for Firefox, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1208373 - if (shouldWorkAroundFirefoxStopStream()) { - self._removeStream(stream); - } - }); + // Half-working fix for Firefox, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1208373 + if (shouldWorkAroundFirefoxStopStream()) { + this._removeStream(stream); + } } + } else { + this.localScreens.forEach((stream) => { + stream.getTracks().forEach((track) => { track.stop(); }); + + // Half-working fix for Firefox, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1208373 + if (shouldWorkAroundFirefoxStopStream()) { + self._removeStream(stream); + } + }); + } } // Audio controls mute() { - this._audioEnabled(false); - this.emit('audioOff'); + this._audioEnabled(false); + this.emit('audioOff'); } unmute() { - this._audioEnabled(true); - this.emit('audioOn'); + this._audioEnabled(true); + this.emit('audioOn'); } // Video controls pauseVideo() { - this._videoEnabled(false); - this.emit('videoOff'); + this._videoEnabled(false); + this.emit('videoOff'); } resumeVideo() { - this._videoEnabled(true); - this.emit('videoOn'); + this._videoEnabled(true); + this.emit('videoOn'); } // Combined controls pause() { - this.mute(); - this.pauseVideo(); + this.mute(); + this.pauseVideo(); } resume() { - this.unmute(); - this.resumeVideo(); + this.unmute(); + this.resumeVideo(); } // Internal methods for enabling/disabling audio/video _audioEnabled(bool) { - this.localStreams.forEach(stream => { - stream.getAudioTracks().forEach(track => { - track.enabled = !!bool; - }); + this.localStreams.forEach((stream) => { + stream.getAudioTracks().forEach((track) => { + track.enabled = !!bool; }); + }); } _videoEnabled(bool) { - this.localStreams.forEach(stream => { - stream.getVideoTracks().forEach(track => { - track.enabled = !!bool; - }); + this.localStreams.forEach((stream) => { + stream.getVideoTracks().forEach((track) => { + track.enabled = !!bool; }); + }); } // check if all audio streams are enabled isAudioEnabled() { - let enabled = true; - this.localStreams.forEach(stream => { - stream.getAudioTracks().forEach(track => { - enabled = enabled && track.enabled; - }); + let enabled = true; + this.localStreams.forEach((stream) => { + stream.getAudioTracks().forEach((track) => { + enabled = enabled && track.enabled; }); - return enabled; + }); + return enabled; } // check if all video streams are enabled isVideoEnabled() { - let enabled = true; - this.localStreams.forEach(stream => { - stream.getVideoTracks().forEach(track => { - enabled = enabled && track.enabled; - }); + let enabled = true; + this.localStreams.forEach((stream) => { + stream.getVideoTracks().forEach((track) => { + enabled = enabled && track.enabled; }); - return enabled; + }); + return enabled; } _removeStream(stream) { - let idx = this.localStreams.indexOf(stream); + let idx = this.localStreams.indexOf(stream); + if (idx > -1) { + this.localStreams.splice(idx, 1); + this.emit('localStreamStopped', stream); + } else { + idx = this.localScreens.indexOf(stream); if (idx > -1) { - this.localStreams.splice(idx, 1); - this.emit('localStreamStopped', stream); - } else { - idx = this.localScreens.indexOf(stream); - if (idx > -1) { - this.localScreens.splice(idx, 1); - this.emit('localScreenStopped', stream); - } + this.localScreens.splice(idx, 1); + this.emit('localScreenStopped', stream); } + } } _setupAudioMonitor(stream, harkOptions) { - this._log('Setup audio'); - const audio = hark(stream, harkOptions); - const self = this; - let timeout; + this._log('Setup audio'); + const audio = hark(stream, harkOptions); + const self = this; + let timeout; - audio.on('speaking', () => { - self.emit('speaking'); - }); + audio.on('speaking', () => { + self.emit('speaking'); + }); - audio.on('stopped_speaking', () => { - if (timeout) { - clearTimeout(timeout); - } + audio.on('stopped_speaking', () => { + if (timeout) { + clearTimeout(timeout); + } - timeout = setTimeout(() => { - self.emit('stoppedSpeaking'); - }, 1000); - }); - audio.on('volume_change', (volume, threshold) => { - self.emit('volumeChange', volume, threshold); - }); + timeout = setTimeout(() => { + self.emit('stoppedSpeaking'); + }, 1000); + }); + audio.on('volume_change', (volume, threshold) => { + self.emit('volumeChange', volume, threshold); + }); - this._audioMonitors.push({audio, stream}); + this._audioMonitors.push({ audio, stream }); } _stopAudioMonitor(stream) { - let idx = -1; - this._audioMonitors.forEach((monitors, i) => { - if (monitors.stream === stream) { - idx = i; - } - }); - - if (idx > -1) { - this._audioMonitors[idx].audio.stop(); - this._audioMonitors.splice(idx, 1); + let idx = -1; + this._audioMonitors.forEach((monitors, i) => { + if (monitors.stream === stream) { + idx = i; } + }); + + if (idx > -1) { + this._audioMonitors[idx].audio.stop(); + this._audioMonitors.splice(idx, 1); + } } } diff --git a/src/peer.js b/src/peer.js index cb7c28afbacae1b0719bee16da19a2032f88e312..bd9f37a3c22be29da5ab4cdc4003ba26a78d6a1b 100644 --- a/src/peer.js +++ b/src/peer.js @@ -30,7 +30,7 @@ class Peer extends WildEmitter { this.receiveMedia = options.receiveMedia || this.parent.config.receiveMedia; this.channels = {}; this.sid = options.sid || Date.now().toString(); - // Create an RTCPeerConnection via the polyfill + // Create an RTCPeerConnection via the polyfill this.pc = new PeerConnection(this.parent.config.peerConnectionConfig, this.parent.config.peerConnectionConstraints); this.pc.on('ice', this.onIceCandidate.bind(this)); this.pc.on('endOfCandidates', (event) => { @@ -47,17 +47,17 @@ class Peer extends WildEmitter { this.pc.on('addStream', this.handleRemoteStreamAdded.bind(this)); this.pc.on('addChannel', this.handleDataChannelAdded.bind(this)); this.pc.on('removeStream', this.handleStreamRemoved.bind(this)); - // Just fire negotiation needed events for now - // When browser re-negotiation handling seems to work - // we can use this as the trigger for starting the offer/answer process - // automatically. We'll just leave it be for now while this stabalizes. + // Just fire negotiation needed events for now + // When browser re-negotiation handling seems to work + // we can use this as the trigger for starting the offer/answer process + // automatically. We'll just leave it be for now while this stabalizes. this.pc.on('negotiationNeeded', this.emit.bind(this, 'negotiationNeeded')); this.pc.on('iceConnectionStateChange', this.emit.bind(this, 'iceConnectionStateChange')); this.pc.on('iceConnectionStateChange', () => { switch (self.pc.iceConnectionState) { case 'failed': - // currently, in chrome only the initiator goes to failed - // so we need to signal this to the peer + // currently, in chrome only the initiator goes to failed + // so we need to signal this to the peer if (self.pc.pc.localDescription.type === 'offer') { self.parent.emit('iceFailed', self); self.send('connectivityError'); @@ -68,7 +68,7 @@ class Peer extends WildEmitter { this.pc.on('signalingStateChange', this.emit.bind(this, 'signalingStateChange')); this.logger = this.parent.logger; - // handle screensharing/broadcast mode + // handle screensharing/broadcast mode if (options.type === 'screen') { if (this.parent.localScreens && this.parent.localScreens[0] && this.sharemyscreen) { this.logger.log('adding local screen stream to peer connection'); @@ -83,7 +83,7 @@ class Peer extends WildEmitter { this.on('channelOpen', (channel) => { if (channel.protocol === INBAND_FILETRANSFER_V1) { - channel.onmessage = event => { + channel.onmessage = (event) => { const metadata = JSON.parse(event.data); const receiver = new FileTransfer.Receiver(); receiver.receive(metadata, channel); @@ -95,7 +95,7 @@ class Peer extends WildEmitter { } }); - // proxy events to parent + // proxy events to parent this.on('*', function () { self.parent.emit(...arguments); }); @@ -115,9 +115,9 @@ class Peer extends WildEmitter { if (err) { return; } - // auto-accept + // auto-accept self.pc.answer((err, sessionDescription) => { - // self.send('answer', sessionDescription); + // self.send('answer', sessionDescription); }); }); } else if (message.type === 'answer') { @@ -133,8 +133,8 @@ class Peer extends WildEmitter { } else if (message.type === 'unmute') { this.parent.emit('unmute', { id: message.from, name: message.payload.name }); } else if (message.type === 'endOfCandidates') { - // Edge requires an end-of-candidates. Since only Edge will have mLines or tracks on the - // shim this will only be called in Edge. + // Edge requires an end-of-candidates. Since only Edge will have mLines or tracks on the + // shim this will only be called in Edge. const mLines = this.pc.pc.transceivers || []; mLines.forEach((mLine) => { if (mLine.iceTransport) { @@ -153,7 +153,7 @@ class Peer extends WildEmitter { roomType: this.type, type: messageType, payload, - prefix: webrtcSupport.prefix + prefix: webrtcSupport.prefix, }; this.logger.log('sending', messageType, message); this.parent.emit('message', message); @@ -164,7 +164,7 @@ class Peer extends WildEmitter { sendDirectly(messageType, payload, channel = 'liowebrtc') { const message = { type: messageType, - payload + payload, }; this.logger.log('sending via datachannel', channel, messageType, message); const dc = this.getDataChannel(channel); @@ -178,7 +178,7 @@ class Peer extends WildEmitter { const self = this; channel.onclose = this.emit.bind(this, 'channelClose', channel); channel.onerror = this.emit.bind(this, 'channelError', channel); - channel.onmessage = event => { + channel.onmessage = (event) => { self.emit('channelMessage', self, channel.label, JSON.parse(event.data), channel, event); }; channel.onopen = this.emit.bind(this, 'channelOpen', channel); @@ -189,7 +189,7 @@ class Peer extends WildEmitter { let channel = this.channels[name]; opts || (opts = {}); if (channel) return channel; - // if we don't have one by this label, create it + // if we don't have one by this label, create it channel = this.channels[name] = this.pc.createDataChannel(name, opts); this._observeDataChannel(channel); return channel; @@ -214,16 +214,16 @@ class Peer extends WildEmitter { start() { const self = this; - // well, the webrtc api requires that we either - // a) create a datachannel a prioris - // b) do a renegotiation later to add the SCTP m-line - // Let's do (a) first... + // well, the webrtc api requires that we either + // a) create a datachannel a prioris + // b) do a renegotiation later to add the SCTP m-line + // Let's do (a) first... if (this.enableDataChannels) { this.getDataChannel('liowebrtc'); } this.pc.offer(this.receiveMedia, (err, sessionDescription) => { - // self.send('offer', sessionDescription); + // self.send('offer', sessionDescription); }); } @@ -275,17 +275,17 @@ class Peer extends WildEmitter { sendFile(file) { const sender = new FileTransfer.Sender(); const dc = this.getDataChannel(`filetransfer${(new Date()).getTime()}`, { - protocol: INBAND_FILETRANSFER_V1 + protocol: INBAND_FILETRANSFER_V1, }); // override onopen dc.onopen = () => { dc.send(JSON.stringify({ size: file.size, - name: file.name + name: file.name, })); sender.send(file, dc); }; - // override onclose + // override onclose dc.onclose = () => { console.log('sender received transfer'); sender.emit('complete'); diff --git a/src/webrtc.js b/src/webrtc.js index 765f8dc11395d5e5459c6eb6915a9436f2e7f12f..05aa0b2ec90cad69aa3c660c84f6417e544a3ed5 100644 --- a/src/webrtc.js +++ b/src/webrtc.js @@ -12,47 +12,47 @@ class WebRTC extends LocalMedia { const config = this.config = { debug: false, peerConnectionConfig: { - iceServers: [{ urls: 'stun:stun.l.google.com:19302' }] + iceServers: [{ urls: 'stun:stun.l.google.com:19302' }], }, peerConnectionConstraints: { - optional: [] + optional: [], }, receiveMedia: { offerToReceiveAudio: 1, - offerToReceiveVideo: 1 + offerToReceiveVideo: 1, }, - enableDataChannels: true + enableDataChannels: true, }; let item; this.logger = ((() => { - // we assume that if you're in debug mode and you didn't - // pass in a logger, you actually want to log as much as - // possible. + // we assume that if you're in debug mode and you didn't + // pass in a logger, you actually want to log as much as + // possible. if (opts.debug) { return opts.logger || console; } - // or we'll use your logger which should have its own logic - // for output. Or we'll return the no-op. + // or we'll use your logger which should have its own logic + // for output. Or we'll return the no-op. return opts.logger || mockconsole; })()); - // set options + // set options for (item in options) { if (options.hasOwnProperty(item)) { this.config[item] = options[item]; } } - // check for support + // check for support if (!webrtcSupport.support) { this.logger.error('Your browser doesn\'t seem to support WebRTC'); } - // where we'll store our peer connections + // where we'll store our peer connections this.peers = []; - // call localMedia constructor + // call localMedia constructor // localMedia.call(this, this.config); this.on('speaking', () => { @@ -89,12 +89,12 @@ class WebRTC extends LocalMedia { } }); - // log events in debug mode + // log events in debug mode if (this.config.debug) { this.on('*', (event, val1, val2) => { let logger; - // if you didn't pass in a logger and you explicitly turning on debug - // we're just going to assume you're wanting log output with console + // if you didn't pass in a logger and you explicitly turning on debug + // we're just going to assume you're wanting log output with console if (self.config.logger === mockconsole) { logger = console; } else { @@ -122,7 +122,7 @@ class WebRTC extends LocalMedia { // fetches all Peer objects by session id and/or type getPeers(sessionId, type) { - return this.peers.filter((peer) => (!sessionId || peer.id === sessionId) && (!type || peer.type === type)); + return this.peers.filter(peer => (!sessionId || peer.id === sessionId) && (!type || peer.type === type)); } // sends message to all diff --git a/src/webrtcsupport.js b/src/webrtcsupport.js index 503428fe6926811e0c833eae64def47c1c86affa..4715e1fc9a8be81a271a224eb21211e940284ecd 100644 --- a/src/webrtcsupport.js +++ b/src/webrtcsupport.js @@ -38,5 +38,5 @@ export default { SessionDescription, IceCandidate, MediaStream, - getUserMedia + getUserMedia, }; diff --git a/test/index.html b/test/index.html index 3a163d3131b657f8303a76bddf7596ffa18ed61c..d64f423cbb0d729cc44e347f4c7906ab1b1687f9 100644 --- a/test/index.html +++ b/test/index.html @@ -81,7 +81,7 @@ if (remotes) { var d = document.createElement('div'); d.className = 'videoContainer'; - d.id = 'container_' + webrtc.getDomId(peer); + d.id = 'container_' + webrtc.getId(peer); d.appendChild(video); var vol = document.createElement('div'); vol.id = 'volume_' + peer.id; @@ -97,7 +97,7 @@ webrtc.on('videoRemoved', function (video, peer) { console.log('video removed ', peer); var remotes = document.getElementById('remotes'); - var el = document.getElementById('container_' + webrtc.getDomId(peer)); + var el = document.getElementById('container_' + webrtc.getId(peer)); if (remotes && el) { remotes.removeChild(el); } diff --git a/test/selenium/selenium-lib.js b/test/selenium/selenium-lib.js index 783060f2eef8364d7205c0e9aefb0c20cd1fe852..9d7f98be709cc7a3ea126f724b5fa148e02a313f 100644 --- a/test/selenium/selenium-lib.js +++ b/test/selenium/selenium-lib.js @@ -10,31 +10,31 @@ if (os.platform() === 'darwin') { } function buildDriver(browser) { - // Firefox options. - // http://selenium.googlecode.com/git/docs/api/javascript/module_selenium-webdriver_firefox.html + // Firefox options. + // http://selenium.googlecode.com/git/docs/api/javascript/module_selenium-webdriver_firefox.html const profile = new firefox.Profile(); profile.setPreference('media.navigator.streams.fake', true); profile.setPreference('media.navigator.permission.disabled', true); profile.setPreference('xpinstall.signatures.required', false); const firefoxOptions = new firefox.Options() - .setBinary(os.platform() === 'darwin' ? '' : 'browsers/bin/firefox-stable') - .setProfile(profile); + .setBinary(os.platform() === 'darwin' ? '' : 'browsers/bin/firefox-stable') + .setProfile(profile); // Chrome options. // http://selenium.googlecode.com/git/docs/api/javascript/module_selenium-webdriver_chrome_class_Options.html#addArguments const chromeOptions = new chrome.Options() - .setChromeBinaryPath(os.platform() === 'darwin' ? null : 'browsers/bin/chrome-stable') - .addArguments('allow-file-access-from-files') - .addArguments('use-fake-device-for-media-stream') - .addArguments('use-fake-ui-for-media-stream'); - // use-file-for-fake-audio-capture -- see https://code.google.com/p/chromium/issues/detail?id=421054 + .setChromeBinaryPath(os.platform() === 'darwin' ? null : 'browsers/bin/chrome-stable') + .addArguments('allow-file-access-from-files') + .addArguments('use-fake-device-for-media-stream') + .addArguments('use-fake-ui-for-media-stream'); + // use-file-for-fake-audio-capture -- see https://code.google.com/p/chromium/issues/detail?id=421054 const driver = new webdriver.Builder() - .forBrowser(browser || process.env.BROWSER || 'firefox') - .setFirefoxOptions(firefoxOptions) - .setChromeOptions(chromeOptions); + .forBrowser(browser || process.env.BROWSER || 'firefox') + .setFirefoxOptions(firefoxOptions) + .setChromeOptions(chromeOptions); if (browser === 'firefox') { driver.getCapabilities().set('marionette', true); @@ -44,5 +44,5 @@ function buildDriver(browser) { } module.exports = { - buildDriver + buildDriver, }; diff --git a/test/selenium/three.js b/test/selenium/three.js index b31cffc3ac7dea2978bccf53a3dd732f0ef98dd6..ed22cdff02a9e4b6df516aa3d27b22d01868d90b 100644 --- a/test/selenium/three.js +++ b/test/selenium/three.js @@ -7,32 +7,32 @@ const chrome = require('selenium-webdriver/chrome'); const firefox = require('selenium-webdriver/firefox'); function buildDriver(browser) { - // Firefox options. - // http://selenium.googlecode.com/git/docs/api/javascript/module_selenium-webdriver_firefox.html + // Firefox options. + // http://selenium.googlecode.com/git/docs/api/javascript/module_selenium-webdriver_firefox.html const profile = new firefox.Profile(); profile.setPreference('media.navigator.streams.fake', true); const firefoxOptions = new firefox.Options() - .setProfile(profile); + .setProfile(profile); // Chrome options. // http://selenium.googlecode.com/git/docs/api/javascript/module_selenium-webdriver_chrome_class_Options.html#addArguments const chromeOptions = new chrome.Options() - /* + /* .addArguments('enable-logging=1') .addArguments('v=1') .addArguments('vmodule=*libjingle/source/talk/*=4') .addArguments('user-data-dir=/some/where') */ - .addArguments('allow-file-access-from-files') - .addArguments('use-fake-device-for-media-stream') - .addArguments('use-fake-ui-for-media-stream'); - // use-file-for-fake-audio-capture -- see https://code.google.com/p/chromium/issues/detail?id=421054 + .addArguments('allow-file-access-from-files') + .addArguments('use-fake-device-for-media-stream') + .addArguments('use-fake-ui-for-media-stream'); + // use-file-for-fake-audio-capture -- see https://code.google.com/p/chromium/issues/detail?id=421054 return new webdriver.Builder() - .forBrowser(browser || process.env.BROWSER || 'firefox') - .setFirefoxOptions(firefoxOptions) - .setChromeOptions(chromeOptions) - .build(); + .forBrowser(browser || process.env.BROWSER || 'firefox') + .setFirefoxOptions(firefoxOptions) + .setChromeOptions(chromeOptions) + .build(); } function doJoin(driver, room) { @@ -58,7 +58,7 @@ function test3(browserA, browserB, browserC, t) { 'return connected === 2;' + '})()'), 15 * 1000) .then(() => { - // return userA.sleep(2000); + // return userA.sleep(2000); }) .then(() => { t.pass('Mesh connected'); diff --git a/yarn-error.log b/yarn-error.log index bf472b6923266a7bcc41198fb7b0cc94900fb4bd..3fe13bb2b4bf91433ce83de32f4bdcf686cbf2bb 100644 --- a/yarn-error.log +++ b/yarn-error.log @@ -1,5 +1,5 @@ Arguments: - /usr/local/bin/node /usr/local/bin/yarn remove babel-preset-2015 + /usr/local/bin/node /usr/local/bin/yarn lint PATH: /opt/local/bin:/opt/local/sbin:/Library/Frameworks/Python.framework/Versions/2.7/bin:/Library/Frameworks/Python.framework/Versions/2.7/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/MacGPG2/bin:/Library/Frameworks/Mono.framework/Versions/Current/Commands:/Applications/Postgres.app/Contents/Versions/latest/bin:/usr/local/sbin @@ -16,7 +16,7 @@ Platform: npm manifest: { "name": "liowebrtc", - "version": "0.1.6", + "version": "0.1.7", "repository": "https://github.com/lazorfuzz/liowebrtc", "main": "./dist/liowebrtc.js", "description": "An Electron-compatible WebRTC library that makes it easy to embed peer to peer communication into react components.", @@ -33,8 +33,14 @@ npm manifest: }, "devDependencies": { "babel-cli": "^6.26.0", - "babel-preset-es2015": "^6.24.1", + "babel-eslint": "^8.2.3", + "babel-preset-env": "^1.7.0", "chromedriver": "^2.29.0", + "eslint": "^4.19.1", + "eslint-config-airbnb": "^16.1.0", + "eslint-plugin-import": "^2.7.0", + "eslint-plugin-jsx-a11y": "^6.0.2", + "eslint-plugin-react": "^7.4.0", "geckodriver": "^1.6.1", "request": "^2.72.0", "selenium-webdriver": "^3.0.1", @@ -44,9 +50,9 @@ npm manifest: }, "license": "MIT", "scripts": { - "build": "babel src --presets babel-preset-es2015 --out-dir dist", + "build": "babel src --presets babel-preset-env --out-dir dist", "test-travis": "test/run-selenium", - "lint": "jshint src", + "lint": "eslint --cache --fix .", "validate": "npm ls", "test-page": "echo \"open https://localhost:8443/test/\" && stupid-server -s", "test": "node test/selenium/index.js" @@ -285,6 +291,14 @@ Lockfile: source-map "^0.5.7" trim-right "^1.0.1" + babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz#cce4517ada356f4220bcae8a02c2b346f9a56664" + dependencies: + babel-helper-explode-assignable-expression "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + babel-helper-call-delegate@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" @@ -303,6 +317,14 @@ Lockfile: babel-types "^6.26.0" lodash "^4.17.4" + babel-helper-explode-assignable-expression@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz#f25b82cf7dc10433c55f70592d5746400ac22caa" + dependencies: + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + babel-helper-function-name@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9" @@ -342,6 +364,16 @@ Lockfile: babel-types "^6.26.0" lodash "^4.17.4" + babel-helper-remap-async-to-generator@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz#5ec581827ad723fecdd381f1c928390676e4551b" + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + babel-helper-replace-supers@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a" @@ -372,6 +404,26 @@ Lockfile: dependencies: babel-runtime "^6.22.0" + babel-plugin-syntax-async-functions@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" + + babel-plugin-syntax-exponentiation-operator@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" + + babel-plugin-syntax-trailing-function-commas@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" + + babel-plugin-transform-async-to-generator@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz#6536e378aff6cb1d5517ac0e40eb3e9fc8d08761" + dependencies: + babel-helper-remap-async-to-generator "^6.24.1" + babel-plugin-syntax-async-functions "^6.8.0" + babel-runtime "^6.22.0" + babel-plugin-transform-es2015-arrow-functions@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221" @@ -384,7 +436,7 @@ Lockfile: dependencies: babel-runtime "^6.22.0" - babel-plugin-transform-es2015-block-scoping@^6.24.1: + babel-plugin-transform-es2015-block-scoping@^6.23.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz#d70f5299c1308d05c12f463813b0a09e73b1895f" dependencies: @@ -394,7 +446,7 @@ Lockfile: babel-types "^6.26.0" lodash "^4.17.4" - babel-plugin-transform-es2015-classes@^6.24.1: + babel-plugin-transform-es2015-classes@^6.23.0: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db" dependencies: @@ -408,33 +460,33 @@ Lockfile: babel-traverse "^6.24.1" babel-types "^6.24.1" - babel-plugin-transform-es2015-computed-properties@^6.24.1: + babel-plugin-transform-es2015-computed-properties@^6.22.0: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz#6fe2a8d16895d5634f4cd999b6d3480a308159b3" dependencies: babel-runtime "^6.22.0" babel-template "^6.24.1" - babel-plugin-transform-es2015-destructuring@^6.22.0: + babel-plugin-transform-es2015-destructuring@^6.23.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d" dependencies: babel-runtime "^6.22.0" - babel-plugin-transform-es2015-duplicate-keys@^6.24.1: + babel-plugin-transform-es2015-duplicate-keys@^6.22.0: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz#73eb3d310ca969e3ef9ec91c53741a6f1576423e" dependencies: babel-runtime "^6.22.0" babel-types "^6.24.1" - babel-plugin-transform-es2015-for-of@^6.22.0: + babel-plugin-transform-es2015-for-of@^6.23.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691" dependencies: babel-runtime "^6.22.0" - babel-plugin-transform-es2015-function-name@^6.24.1: + babel-plugin-transform-es2015-function-name@^6.22.0: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b" dependencies: @@ -448,7 +500,7 @@ Lockfile: dependencies: babel-runtime "^6.22.0" - babel-plugin-transform-es2015-modules-amd@^6.24.1: + babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015-modules-amd@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz#3b3e54017239842d6d19c3011c4bd2f00a00d154" dependencies: @@ -456,7 +508,7 @@ Lockfile: babel-runtime "^6.22.0" babel-template "^6.24.1" - babel-plugin-transform-es2015-modules-commonjs@^6.24.1: + babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.1: version "6.26.2" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz#58a793863a9e7ca870bdc5a881117ffac27db6f3" dependencies: @@ -465,7 +517,7 @@ Lockfile: babel-template "^6.26.0" babel-types "^6.26.0" - babel-plugin-transform-es2015-modules-systemjs@^6.24.1: + babel-plugin-transform-es2015-modules-systemjs@^6.23.0: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz#ff89a142b9119a906195f5f106ecf305d9407d23" dependencies: @@ -473,7 +525,7 @@ Lockfile: babel-runtime "^6.22.0" babel-template "^6.24.1" - babel-plugin-transform-es2015-modules-umd@^6.24.1: + babel-plugin-transform-es2015-modules-umd@^6.23.0: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz#ac997e6285cd18ed6176adb607d602344ad38468" dependencies: @@ -481,14 +533,14 @@ Lockfile: babel-runtime "^6.22.0" babel-template "^6.24.1" - babel-plugin-transform-es2015-object-super@^6.24.1: + babel-plugin-transform-es2015-object-super@^6.22.0: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz#24cef69ae21cb83a7f8603dad021f572eb278f8d" dependencies: babel-helper-replace-supers "^6.24.1" babel-runtime "^6.22.0" - babel-plugin-transform-es2015-parameters@^6.24.1: + babel-plugin-transform-es2015-parameters@^6.23.0: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b" dependencies: @@ -499,7 +551,7 @@ Lockfile: babel-traverse "^6.24.1" babel-types "^6.24.1" - babel-plugin-transform-es2015-shorthand-properties@^6.24.1: + babel-plugin-transform-es2015-shorthand-properties@^6.22.0: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz#24f875d6721c87661bbd99a4622e51f14de38aa0" dependencies: @@ -512,7 +564,7 @@ Lockfile: dependencies: babel-runtime "^6.22.0" - babel-plugin-transform-es2015-sticky-regex@^6.24.1: + babel-plugin-transform-es2015-sticky-regex@^6.22.0: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz#00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc" dependencies: @@ -526,13 +578,13 @@ Lockfile: dependencies: babel-runtime "^6.22.0" - babel-plugin-transform-es2015-typeof-symbol@^6.22.0: + babel-plugin-transform-es2015-typeof-symbol@^6.23.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz#dec09f1cddff94b52ac73d505c84df59dcceb372" dependencies: babel-runtime "^6.22.0" - babel-plugin-transform-es2015-unicode-regex@^6.24.1: + babel-plugin-transform-es2015-unicode-regex@^6.22.0: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz#d38b12f42ea7323f729387f18a7c5ae1faeb35e9" dependencies: @@ -540,7 +592,15 @@ Lockfile: babel-runtime "^6.22.0" regexpu-core "^2.0.0" - babel-plugin-transform-regenerator@^6.24.1: + babel-plugin-transform-exponentiation-operator@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz#2ab0c9c7f3098fa48907772bb813fe41e8de3a0e" + dependencies: + babel-helper-builder-binary-assignment-operator-visitor "^6.24.1" + babel-plugin-syntax-exponentiation-operator "^6.8.0" + babel-runtime "^6.22.0" + + babel-plugin-transform-regenerator@^6.22.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f" dependencies: @@ -561,34 +621,40 @@ Lockfile: core-js "^2.5.0" regenerator-runtime "^0.10.5" - babel-preset-es2015@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz#d44050d6bc2c9feea702aaf38d727a0210538939" + babel-preset-env@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.7.0.tgz#dea79fa4ebeb883cd35dab07e260c1c9c04df77a" dependencies: babel-plugin-check-es2015-constants "^6.22.0" + babel-plugin-syntax-trailing-function-commas "^6.22.0" + babel-plugin-transform-async-to-generator "^6.22.0" babel-plugin-transform-es2015-arrow-functions "^6.22.0" babel-plugin-transform-es2015-block-scoped-functions "^6.22.0" - babel-plugin-transform-es2015-block-scoping "^6.24.1" - babel-plugin-transform-es2015-classes "^6.24.1" - babel-plugin-transform-es2015-computed-properties "^6.24.1" - babel-plugin-transform-es2015-destructuring "^6.22.0" - babel-plugin-transform-es2015-duplicate-keys "^6.24.1" - babel-plugin-transform-es2015-for-of "^6.22.0" - babel-plugin-transform-es2015-function-name "^6.24.1" + babel-plugin-transform-es2015-block-scoping "^6.23.0" + babel-plugin-transform-es2015-classes "^6.23.0" + babel-plugin-transform-es2015-computed-properties "^6.22.0" + babel-plugin-transform-es2015-destructuring "^6.23.0" + babel-plugin-transform-es2015-duplicate-keys "^6.22.0" + babel-plugin-transform-es2015-for-of "^6.23.0" + babel-plugin-transform-es2015-function-name "^6.22.0" babel-plugin-transform-es2015-literals "^6.22.0" - babel-plugin-transform-es2015-modules-amd "^6.24.1" - babel-plugin-transform-es2015-modules-commonjs "^6.24.1" - babel-plugin-transform-es2015-modules-systemjs "^6.24.1" - babel-plugin-transform-es2015-modules-umd "^6.24.1" - babel-plugin-transform-es2015-object-super "^6.24.1" - babel-plugin-transform-es2015-parameters "^6.24.1" - babel-plugin-transform-es2015-shorthand-properties "^6.24.1" + babel-plugin-transform-es2015-modules-amd "^6.22.0" + babel-plugin-transform-es2015-modules-commonjs "^6.23.0" + babel-plugin-transform-es2015-modules-systemjs "^6.23.0" + babel-plugin-transform-es2015-modules-umd "^6.23.0" + babel-plugin-transform-es2015-object-super "^6.22.0" + babel-plugin-transform-es2015-parameters "^6.23.0" + babel-plugin-transform-es2015-shorthand-properties "^6.22.0" babel-plugin-transform-es2015-spread "^6.22.0" - babel-plugin-transform-es2015-sticky-regex "^6.24.1" + babel-plugin-transform-es2015-sticky-regex "^6.22.0" babel-plugin-transform-es2015-template-literals "^6.22.0" - babel-plugin-transform-es2015-typeof-symbol "^6.22.0" - babel-plugin-transform-es2015-unicode-regex "^6.24.1" - babel-plugin-transform-regenerator "^6.24.1" + babel-plugin-transform-es2015-typeof-symbol "^6.23.0" + babel-plugin-transform-es2015-unicode-regex "^6.22.0" + babel-plugin-transform-exponentiation-operator "^6.22.0" + babel-plugin-transform-regenerator "^6.22.0" + browserslist "^3.2.6" + invariant "^2.2.2" + semver "^5.3.0" babel-register@^6.26.0: version "6.26.0" @@ -810,6 +876,13 @@ Lockfile: vm-browserify "~0.0.1" xtend "^3.0.0" + browserslist@^3.2.6: + version "3.2.8" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-3.2.8.tgz#b0005361d6471f0f5952797a76fc985f1f978fc6" + dependencies: + caniuse-lite "^1.0.30000844" + electron-to-chromium "^1.3.47" + buffer-from@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.0.tgz#87fcaa3a298358e0ade6e442cfce840740d1ad04" @@ -844,6 +917,10 @@ Lockfile: version "1.2.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" + caniuse-lite@^1.0.30000844: + version "1.0.30000847" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000847.tgz#be77f439be29bbc57ae08004b1e470b653b1ec1d" + capture-stack-trace@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.0.tgz#4a6fa07399c26bba47f0b2496b4d0fb408c5550d" @@ -1181,6 +1258,10 @@ Lockfile: mime "1.2.x" optimist "~0.3.5" + electron-to-chromium@^1.3.47: + version "1.3.48" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.48.tgz#d3b0d8593814044e092ece2108fc3ac9aea4b900" + engine.io-client@1.5.4: version "1.5.4" resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-1.5.4.tgz#c6ad65a65752a29cb930c6911e579d2b28d1106c" @@ -3289,9 +3370,17 @@ Lockfile: fd-slicer "~1.0.1" Trace: - Error: This module isn't specified in a manifest. - at new MessageError (/usr/local/lib/node_modules/yarn/lib/cli.js:186:110) - at Object.<anonymous> (/usr/local/lib/node_modules/yarn/lib/cli.js:60445:15) - at Generator.next (<anonymous>) - at step (/usr/local/lib/node_modules/yarn/lib/cli.js:98:30) - at /usr/local/lib/node_modules/yarn/lib/cli.js:109:13 + Error: Command failed. + Exit code: 1 + Command: sh + Arguments: -c eslint --cache --fix . + Directory: /Users/leon/liowebrtc + Output: + + at ProcessTermError.MessageError (/usr/local/lib/node_modules/yarn/lib/cli.js:186:110) + at new ProcessTermError (/usr/local/lib/node_modules/yarn/lib/cli.js:226:113) + at ChildProcess.<anonymous> (/usr/local/lib/node_modules/yarn/lib/cli.js:30281:17) + at emitTwo (events.js:106:13) + at ChildProcess.emit (events.js:194:7) + at maybeClose (internal/child_process.js:899:16) + at Process.ChildProcess._handle.onexit (internal/child_process.js:226:5)