Browse Source

refact(peerJS): From commonJS to ES6 modules

Carlos Caballero 6 years ago
parent
commit
6daf1f4740
8 changed files with 199 additions and 159 deletions
  1. 9 7
      lib/adapter.ts
  2. 67 45
      lib/dataconnection.ts
  3. 23 10
      lib/exports.ts
  4. 31 28
      lib/mediaconnection.ts
  5. 7 7
      lib/negotiator.ts
  6. 7 9
      lib/peer.ts
  7. 51 47
      lib/socket.ts
  8. 4 6
      lib/util.ts

+ 9 - 7
lib/adapter.ts

@@ -1,8 +1,10 @@
-require('webrtc-adapter');
+import webrtc from "webrtc-adapter";
 
-module.exports.RTCSessionDescription = window.RTCSessionDescription ||
-	window.mozRTCSessionDescription;
-module.exports.RTCPeerConnection = window.RTCPeerConnection ||
-	window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
-module.exports.RTCIceCandidate = window.RTCIceCandidate ||
-	window.mozRTCIceCandidate;
+export const RTCSessionDescription =
+  window.RTCSessionDescription || window.mozRTCSessionDescription;
+export const RTCPeerConnection =
+  window.RTCPeerConnection ||
+  window.mozRTCPeerConnection ||
+  window.webkitRTCPeerConnection;
+export const RTCIceCandidate =
+  window.RTCIceCandidate || window.mozRTCIceCandidate;

+ 67 - 45
lib/dataconnection.ts

@@ -1,27 +1,32 @@
-var util = require('./util');
-var EventEmitter = require('eventemitter3');
-var Negotiator = require('./negotiator');
-var Reliable = require('reliable');
+import { util } from "./util";
+import { EventEmitter } from "eventemitter3";
+import { Negotiator } from "./negotiator";
+import { Reliable } from "reliable";
 
 /**
  * Wraps a DataChannel between two Peers.
  */
-function DataConnection(peer, provider, options) {
-  if (!(this instanceof DataConnection)) return new DataConnection(peer, provider, options);
+export function DataConnection(peer, provider, options) {
+  if (!(this instanceof DataConnection))
+    return new DataConnection(peer, provider, options);
   EventEmitter.call(this);
 
-  this.options = util.extend({
-    serialization: 'binary',
-    reliable: false
-  }, options);
+  this.options = util.extend(
+    {
+      serialization: "binary",
+      reliable: false
+    },
+    options
+  );
 
   // Connection is not open yet.
   this.open = false;
-  this.type = 'data';
+  this.type = "data";
   this.peer = peer;
   this.provider = provider;
 
-  this.id = this.options.connectionId || DataConnection._idPrefix + util.randomToken();
+  this.id =
+    this.options.connectionId || DataConnection._idPrefix + util.randomToken();
 
   this.label = this.options.label || this.id;
   this.metadata = this.options.metadata;
@@ -50,24 +55,24 @@ function DataConnection(peer, provider, options) {
 
 util.inherits(DataConnection, EventEmitter);
 
-DataConnection._idPrefix = 'dc_';
+DataConnection._idPrefix = "dc_";
 
 /** Called by the Negotiator when the DataChannel is ready. */
 DataConnection.prototype.initialize = function(dc) {
   this._dc = this.dataChannel = dc;
   this._configureDataChannel();
-}
+};
 
 DataConnection.prototype._configureDataChannel = function() {
   var self = this;
   if (util.supports.sctp) {
-    this._dc.binaryType = 'arraybuffer';
+    this._dc.binaryType = "arraybuffer";
   }
   this._dc.onopen = function() {
-    util.log('Data channel connection success');
+    util.log("Data channel connection success");
     self.open = true;
-    self.emit('open');
-  }
+    self.emit("open");
+  };
 
   // Use the Reliable shim for non Firefox browsers
   if (!util.supports.sctp && this.reliable) {
@@ -76,7 +81,7 @@ DataConnection.prototype._configureDataChannel = function() {
 
   if (this._reliable) {
     this._reliable.onmessage = function(msg) {
-      self.emit('data', msg);
+      self.emit("data", msg);
     };
   } else {
     this._dc.onmessage = function(e) {
@@ -84,22 +89,22 @@ DataConnection.prototype._configureDataChannel = function() {
     };
   }
   this._dc.onclose = function(e) {
-    util.log('DataChannel closed for:', self.peer);
+    util.log("DataChannel closed for:", self.peer);
     self.close();
   };
-}
+};
 
 // Handles a DataChannel message.
 DataConnection.prototype._handleDataMessage = function(e) {
   var self = this;
   var data = e.data;
   var datatype = data.constructor;
-  if (this.serialization === 'binary' || this.serialization === 'binary-utf8') {
+  if (this.serialization === "binary" || this.serialization === "binary-utf8") {
     if (datatype === Blob) {
       // Datatype should never be blob
       util.blobToArrayBuffer(data, function(ab) {
         data = util.unpack(ab);
-        self.emit('data', data);
+        self.emit("data", data);
       });
       return;
     } else if (datatype === ArrayBuffer) {
@@ -109,7 +114,7 @@ DataConnection.prototype._handleDataMessage = function(e) {
       var ab = util.binaryStringToArrayBuffer(data);
       data = util.unpack(ab);
     }
-  } else if (this.serialization === 'json') {
+  } else if (this.serialization === "json") {
     data = JSON.parse(data);
   }
 
@@ -117,7 +122,11 @@ DataConnection.prototype._handleDataMessage = function(e) {
   // We're guaranteed that this isn't 0.
   if (data.__peerData) {
     var id = data.__peerData;
-    var chunkInfo = this._chunkedData[id] || {data: [], count: 0, total: data.total};
+    var chunkInfo = this._chunkedData[id] || {
+      data: [],
+      count: 0,
+      total: data.total
+    };
 
     chunkInfo.data[data.n] = data.data;
     chunkInfo.count += 1;
@@ -128,15 +137,15 @@ DataConnection.prototype._handleDataMessage = function(e) {
 
       // We've received all the chunks--time to construct the complete data.
       data = new Blob(chunkInfo.data);
-      this._handleDataMessage({data: data});
+      this._handleDataMessage({ data: data });
     }
 
     this._chunkedData[id] = chunkInfo;
     return;
   }
 
-  this.emit('data', data);
-}
+  this.emit("data", data);
+};
 
 /**
  * Exposed functionality for users.
@@ -149,13 +158,18 @@ DataConnection.prototype.close = function() {
   }
   this.open = false;
   Negotiator.cleanup(this);
-  this.emit('close');
-}
+  this.emit("close");
+};
 
 /** Allows user to send data. */
 DataConnection.prototype.send = function(data, chunked) {
   if (!this.open) {
-    this.emit('error', new Error('Connection is not open. You should listen for the `open` event before sending messages.'));
+    this.emit(
+      "error",
+      new Error(
+        "Connection is not open. You should listen for the `open` event before sending messages."
+      )
+    );
     return;
   }
   if (this._reliable) {
@@ -165,14 +179,19 @@ DataConnection.prototype.send = function(data, chunked) {
     return;
   }
   var self = this;
-  if (this.serialization === 'json') {
+  if (this.serialization === "json") {
     this._bufferedSend(JSON.stringify(data));
-  } else if (this.serialization === 'binary' || this.serialization === 'binary-utf8') {
+  } else if (
+    this.serialization === "binary" ||
+    this.serialization === "binary-utf8"
+  ) {
     var blob = util.pack(data);
 
     // For Chrome-Firefox interoperability, we need to make Firefox "chunk"
     // the data it sends out.
-    var needsChunking = util.chunkedBrowsers[this._peerBrowser] || util.chunkedBrowsers[util.browser];
+    var needsChunking =
+      util.chunkedBrowsers[this._peerBrowser] ||
+      util.chunkedBrowsers[util.browser];
     if (needsChunking && !chunked && blob.size > util.chunkedMTU) {
       this._sendChunks(blob);
       return;
@@ -195,14 +214,14 @@ DataConnection.prototype.send = function(data, chunked) {
   } else {
     this._bufferedSend(data);
   }
-}
+};
 
 DataConnection.prototype._bufferedSend = function(msg) {
   if (this._buffering || !this._trySend(msg)) {
     this._buffer.push(msg);
     this.bufferSize = this._buffer.length;
   }
-}
+};
 
 // Returns true if the send succeeds.
 DataConnection.prototype._trySend = function(msg) {
@@ -220,7 +239,7 @@ DataConnection.prototype._trySend = function(msg) {
     return false;
   }
   return true;
-}
+};
 
 // Try to send the first message in the buffer.
 DataConnection.prototype._tryBuffer = function() {
@@ -235,7 +254,7 @@ DataConnection.prototype._tryBuffer = function() {
     this.bufferSize = this._buffer.length;
     this._tryBuffer();
   }
-}
+};
 
 DataConnection.prototype._sendChunks = function(blob) {
   var blobs = util.chunk(blob);
@@ -243,25 +262,28 @@ DataConnection.prototype._sendChunks = function(blob) {
     var blob = blobs[i];
     this.send(blob, true);
   }
-}
+};
 
 DataConnection.prototype.handleMessage = function(message) {
   var payload = message.payload;
 
   switch (message.type) {
-    case 'ANSWER':
+    case "ANSWER":
       this._peerBrowser = payload.browser;
 
       // Forward to negotiator
       Negotiator.handleSDP(message.type, this, payload.sdp);
       break;
-    case 'CANDIDATE':
+    case "CANDIDATE":
       Negotiator.handleCandidate(this, payload.candidate);
       break;
     default:
-      util.warn('Unrecognized message type:', message.type, 'from peer:', this.peer);
+      util.warn(
+        "Unrecognized message type:",
+        message.type,
+        "from peer:",
+        this.peer
+      );
       break;
   }
-}
-
-module.exports = DataConnection;
+};

+ 23 - 10
lib/exports.ts

@@ -1,10 +1,23 @@
-window.Socket = require("./socket");
-window.MediaConnection = require("./mediaconnection");
-window.DataConnection = require("./dataconnection");
-window.Peer = require("./peer");
-window.RTCPeerConnection = require("./adapter").RTCPeerConnection;
-window.RTCSessionDescription = require("./adapter").RTCSessionDescription;
-window.RTCIceCandidate = require("./adapter").RTCIceCandidate;
-window.Negotiator = require("./negotiator");
-window.util = require("./util");
-window.BinaryPack = require("js-binarypack");
+import { util } from "./util";
+import {
+  RTCPeerConnection,
+  RTCSessionDescription,
+  RTCIceCandidate
+} from "./adapter";
+import { Socket } from "./socket";
+import { MediaConnection } from "./mediaconnection";
+import { DataConnection } from "./dataconnection";
+import { Peer } from "./peer";
+import { Negotiator } from "./negotiator";
+import jsBinarypack from "js-binarypack";
+
+window.Socket = Socket;
+window.MediaConnection = MediaConnection;
+window.DataConnection = DataConnection;
+window.Peer = Peer;
+window.RTCPeerConnection = RTCPeerConnection;
+window.RTCSessionDescription = RTCSessionDescription;
+window.RTCIceCandidate = RTCIceCandidate;
+window.Negotiator = Negotiator;
+window.util = util;
+window.BinaryPack = jsBinarypack;

+ 31 - 28
lib/mediaconnection.ts

@@ -1,75 +1,80 @@
-var util = require('./util');
-var EventEmitter = require('eventemitter3');
-var Negotiator = require('./negotiator');
+import { util } from "./util";
+import { EventEmitter } from "eventemitter3";
+import { Negotiator } from "./negotiator";
 
 /**
  * Wraps the streaming interface between two Peers.
  */
-function MediaConnection(peer, provider, options) {
-  if (!(this instanceof MediaConnection)) return new MediaConnection(peer, provider, options);
+export function MediaConnection(peer, provider, options) {
+  if (!(this instanceof MediaConnection))
+    return new MediaConnection(peer, provider, options);
   EventEmitter.call(this);
 
   this.options = util.extend({}, options);
 
   this.open = false;
-  this.type = 'media';
+  this.type = "media";
   this.peer = peer;
   this.provider = provider;
   this.metadata = this.options.metadata;
   this.localStream = this.options._stream;
 
-  this.id = this.options.connectionId || MediaConnection._idPrefix + util.randomToken();
+  this.id =
+    this.options.connectionId || MediaConnection._idPrefix + util.randomToken();
   if (this.localStream) {
-    Negotiator.startConnection(
-      this,
-      {_stream: this.localStream, originator: true}
-    );
+    Negotiator.startConnection(this, {
+      _stream: this.localStream,
+      originator: true
+    });
   }
-};
+}
 
 util.inherits(MediaConnection, EventEmitter);
 
-MediaConnection._idPrefix = 'mc_';
+MediaConnection._idPrefix = "mc_";
 
 MediaConnection.prototype.addStream = function(remoteStream) {
-  util.log('Receiving stream', remoteStream);
+  util.log("Receiving stream", remoteStream);
 
   this.remoteStream = remoteStream;
-  this.emit('stream', remoteStream); // Should we call this `open`?
-
+  this.emit("stream", remoteStream); // Should we call this `open`?
 };
 
 MediaConnection.prototype.handleMessage = function(message) {
   var payload = message.payload;
 
   switch (message.type) {
-    case 'ANSWER':
+    case "ANSWER":
       // Forward to negotiator
       Negotiator.handleSDP(message.type, this, payload.sdp);
       this.open = true;
       break;
-    case 'CANDIDATE':
+    case "CANDIDATE":
       Negotiator.handleCandidate(this, payload.candidate);
       break;
     default:
-      util.warn('Unrecognized message type:', message.type, 'from peer:', this.peer);
+      util.warn(
+        "Unrecognized message type:",
+        message.type,
+        "from peer:",
+        this.peer
+      );
       break;
   }
-}
+};
 
 MediaConnection.prototype.answer = function(stream) {
   if (this.localStream) {
-    util.warn('Local stream already exists on this MediaConnection. Are you answering a call twice?');
+    util.warn(
+      "Local stream already exists on this MediaConnection. Are you answering a call twice?"
+    );
     return;
   }
 
   this.options._payload._stream = stream;
 
   this.localStream = stream;
-  Negotiator.startConnection(
-    this,
-    this.options._payload
-  )
+  Negotiator.startConnection(this, this.options._payload);
   // Retrieve lost messages stored because PeerConnection not set up.
   var messages = this.provider._getMessages(this.id);
   for (var i = 0, ii = messages.length; i < ii; i += 1) {
@@ -89,7 +94,5 @@ MediaConnection.prototype.close = function() {
   }
   this.open = false;
   Negotiator.cleanup(this);
-  this.emit('close')
+  this.emit("close");
 };
-
-module.exports = MediaConnection;

+ 7 - 7
lib/negotiator.ts

@@ -1,12 +1,14 @@
-var util = require("./util");
-var RTCPeerConnection = require("./adapter").RTCPeerConnection;
-var RTCSessionDescription = require("./adapter").RTCSessionDescription;
-var RTCIceCandidate = require("./adapter").RTCIceCandidate;
+import { util } from "./util";
+import {
+  RTCPeerConnection,
+  RTCSessionDescription,
+  RTCIceCandidate
+} from "./adapter";
 
 /**
  * Manages all negotiations between Peers.
  */
-var Negotiator = {
+export const Negotiator = {
   pcs: {
     data: {},
     media: {}
@@ -341,5 +343,3 @@ Negotiator.handleCandidate = function(connection, ice) {
   );
   util.log("Added ICE candidate for:", connection.peer);
 };
-
-module.exports = Negotiator;

+ 7 - 9
lib/peer.ts

@@ -1,13 +1,13 @@
-var util = require("./util");
-var EventEmitter = require("eventemitter3");
-var Socket = require("./socket");
-var MediaConnection = require("./mediaconnection");
-var DataConnection = require("./dataconnection");
+import { util } from "./util";
+import { EventEmitter } from "eventemitter3";
+import { Socket } from "./socket";
+import { MediaConnection } from "./mediaconnection";
+import { DataConnection } from "./dataconnection";
 
 /**
  * A peer who can initiate connections with other peers.
  */
-function Peer(id, options) {
+export function Peer(id, options) {
   if (!(this instanceof Peer)) return new Peer(id, options);
   EventEmitter.call(this);
 
@@ -50,7 +50,7 @@ function Peer(id, options) {
   // Set whether we use SSL to same as current host
   if (options.secure === undefined && options.host !== util.CLOUD_HOST) {
     options.secure = util.isSecure();
-  } else if(options.host == util.CLOUD_HOST){
+  } else if (options.host == util.CLOUD_HOST) {
     options.secure = true;
   }
   // Set a custom log function if present
@@ -559,5 +559,3 @@ Peer.prototype.listAllPeers = function(cb) {
   };
   http.send(null);
 };
-
-module.exports = Peer;

+ 51 - 47
lib/socket.ts

@@ -1,12 +1,13 @@
-var util = require('./util');
-var EventEmitter = require('eventemitter3');
+import { util } from "./util";
+import { EventEmitter } from "eventemitter3";
 
 /**
  * An abstraction on top of WebSockets and XHR streaming to provide fastest
  * possible connection for peers.
  */
-function Socket(secure, host, port, path, key, wsport) {
-  if (!(this instanceof Socket)) return new Socket(secure, host, port, path, key, wsport);
+export function Socket(secure, host, port, path, key, wsport) {
+  if (!(this instanceof Socket))
+    return new Socket(secure, host, port, path, key, wsport);
 
   wsport = wsport || port;
 
@@ -16,26 +17,24 @@ function Socket(secure, host, port, path, key, wsport) {
   this.disconnected = false;
   this._queue = [];
 
-  var httpProtocol = secure ? 'https://' : 'http://';
-  var wsProtocol = secure ? 'wss://' : 'ws://';
-  this._httpUrl = httpProtocol + host + ':' + port + path + key;
-  this._wsUrl = wsProtocol + host + ':' + wsport + path + 'peerjs?key=' + key;
+  var httpProtocol = secure ? "https://" : "http://";
+  var wsProtocol = secure ? "wss://" : "ws://";
+  this._httpUrl = httpProtocol + host + ":" + port + path + key;
+  this._wsUrl = wsProtocol + host + ":" + wsport + path + "peerjs?key=" + key;
 }
 
 util.inherits(Socket, EventEmitter);
 
-
 /** Check in with ID or get one from server. */
 Socket.prototype.start = function(id, token) {
   this.id = id;
 
-  this._httpUrl += '/' + id + '/' + token;
-  this._wsUrl += '&id=' + id + '&token=' + token;
+  this._httpUrl += "/" + id + "/" + token;
+  this._wsUrl += "&id=" + id + "&token=" + token;
 
   this._startXhrStream();
   this._startWebSocket();
-}
-
+};
 
 /** Start up websocket communications. */
 Socket.prototype._startWebSocket = function(id) {
@@ -50,17 +49,17 @@ Socket.prototype._startWebSocket = function(id) {
   this._socket.onmessage = function(event) {
     try {
       var data = JSON.parse(event.data);
-    } catch(e) {
-      util.log('Invalid server message', event.data);
+    } catch (e) {
+      util.log("Invalid server message", event.data);
       return;
     }
-    self.emit('message', data);
+    self.emit("message", data);
   };
 
   this._socket.onclose = function(event) {
-    util.log('Socket closed.');
+    util.log("Socket closed.");
     self.disconnected = true;
-    self.emit('disconnected');
+    self.emit("disconnected");
   };
 
   // Take care of the queue of connections if necessary and make sure Peer knows
@@ -68,15 +67,15 @@ Socket.prototype._startWebSocket = function(id) {
   this._socket.onopen = function() {
     if (self._timeout) {
       clearTimeout(self._timeout);
-      setTimeout(function(){
+      setTimeout(function() {
         self._http.abort();
         self._http = null;
       }, 5000);
     }
     self._sendQueuedMessages();
-    util.log('Socket open');
+    util.log("Socket open");
   };
-}
+};
 
 /** Start XHR streaming. */
 Socket.prototype._startXhrStream = function(n) {
@@ -85,33 +84,40 @@ Socket.prototype._startXhrStream = function(n) {
     this._http = new XMLHttpRequest();
     this._http._index = 1;
     this._http._streamIndex = n || 0;
-    this._http.open('post', this._httpUrl + '/id?i=' + this._http._streamIndex, true);
+    this._http.open(
+      "post",
+      this._httpUrl + "/id?i=" + this._http._streamIndex,
+      true
+    );
     this._http.onerror = function() {
       // If we get an error, likely something went wrong.
       // Stop streaming.
       clearTimeout(self._timeout);
-      self.emit('disconnected');
-    }
+      self.emit("disconnected");
+    };
     this._http.onreadystatechange = function() {
       if (this.readyState == 2 && this.old) {
         this.old.abort();
         delete this.old;
-      } else if (this.readyState > 2 && this.status === 200 && this.responseText) {
+      } else if (
+        this.readyState > 2 &&
+        this.status === 200 &&
+        this.responseText
+      ) {
         self._handleStream(this);
       }
     };
     this._http.send(null);
     this._setHTTPTimeout();
-  } catch(e) {
-    util.log('XMLHttpRequest not available; defaulting to WebSockets');
+  } catch (e) {
+    util.log("XMLHttpRequest not available; defaulting to WebSockets");
   }
-}
-
+};
 
 /** Handles onreadystatechange response as a stream. */
 Socket.prototype._handleStream = function(http) {
   // 3 and 4 are loading/done state. All others are not relevant.
-  var messages = http.responseText.split('\n');
+  var messages = http.responseText.split("\n");
 
   // Check to see if anything needs to be processed on buffer.
   if (http._buffer) {
@@ -120,11 +126,11 @@ Socket.prototype._handleStream = function(http) {
       var bufferedMessage = messages[index];
       try {
         bufferedMessage = JSON.parse(bufferedMessage);
-      } catch(e) {
+      } catch (e) {
         http._buffer.shift(index);
         break;
       }
-      this.emit('message', bufferedMessage);
+      this.emit("message", bufferedMessage);
     }
   }
 
@@ -142,14 +148,14 @@ Socket.prototype._handleStream = function(http) {
     } else {
       try {
         message = JSON.parse(message);
-      } catch(e) {
-        util.log('Invalid server message', message);
+      } catch (e) {
+        util.log("Invalid server message", message);
         return;
       }
-      this.emit('message', message);
+      this.emit("message", message);
     }
   }
-}
+};
 
 Socket.prototype._setHTTPTimeout = function() {
   var self = this;
@@ -162,19 +168,19 @@ Socket.prototype._setHTTPTimeout = function() {
       old.abort();
     }
   }, 25000);
-}
+};
 
 /** Is the websocket currently open? */
 Socket.prototype._wsOpen = function() {
   return this._socket && this._socket.readyState == 1;
-}
+};
 
 /** Send queued messages. */
 Socket.prototype._sendQueuedMessages = function() {
   for (var i = 0, ii = this._queue.length; i < ii; i += 1) {
     this.send(this._queue[i]);
   }
-}
+};
 
 /** Exposed send for DC & Peer. */
 Socket.prototype.send = function(data) {
@@ -190,7 +196,7 @@ Socket.prototype.send = function(data) {
   }
 
   if (!data.type) {
-    this.emit('error', 'Invalid message');
+    this.emit("error", "Invalid message");
     return;
   }
 
@@ -199,18 +205,16 @@ Socket.prototype.send = function(data) {
     this._socket.send(message);
   } else {
     var http = new XMLHttpRequest();
-    var url = this._httpUrl + '/' + data.type.toLowerCase();
-    http.open('post', url, true);
-    http.setRequestHeader('Content-Type', 'application/json');
+    var url = this._httpUrl + "/" + data.type.toLowerCase();
+    http.open("post", url, true);
+    http.setRequestHeader("Content-Type", "application/json");
     http.send(message);
   }
-}
+};
 
 Socket.prototype.close = function() {
   if (!this.disconnected && this._wsOpen()) {
     this._socket.close();
     this.disconnected = true;
   }
-}
-
-module.exports = Socket;
+};

+ 4 - 6
lib/util.ts

@@ -1,10 +1,10 @@
-var defaultConfig = {'iceServers': [{ 'urls': 'stun:stun.l.google.com:19302' }]};
+var defaultConfig = { iceServers: [{ urls: "stun:stun.l.google.com:19302" }] };
 var dataCount = 1;
 
-var BinaryPack = require("js-binarypack");
-var RTCPeerConnection = require("./adapter").RTCPeerConnection;
+import BinaryPack from "js-binarypack";
+import { RTCPeerConnection } from "./adapter";
 
-var util = {
+export const util = {
   noop: function() {},
 
   CLOUD_HOST: "0.peerjs.com",
@@ -320,5 +320,3 @@ var util = {
     return location.protocol === "https:";
   }
 };
-
-module.exports = util;