Skip to content
Snippets Groups Projects
index.js 4.34 KiB
Newer Older
  • Learn to ignore specific revisions
  • /* global Y */
    "use strict"
    
    
    import LioWebRTC from "liowebrtc"
    
    
    function extend(Y) {
      class WebRTC extends Y.AbstractConnector {
        constructor(y, options) {
          if (options === undefined) {
            throw new Error("Options must not be undefined!")
          }
    
          options.role = "slave"
          super(y, options)
          this.webrtcOptions = options
    
    
          if (options.onUserEvent) {
            this.onUserEvent(options.onUserEvent)
          }
    
    
          window.addEventListener("unload", () => {
            this.y.destroy()
          })
    
            url: this.webrtcOptions.url,
            dataOnly: true,
    
          this.webrtc.on("ready", () => {
            this.webrtc.joinRoom(this.webrtcOptions.room)
          })
    
          this.webrtc.on("joinedRoom", () => {
            this.checkAndEnsureUser()
    
          this.webrtc.on("channelOpen", (dataChannel, peer) => {
            this.checkAndEnsureUser()
    
    
            // Start a handshake to ensure both sides are able to use the channel
            function handshake(peer) {
              const _peer = this.webrtc.getPeerById(peer.id)
    
              if (!_peer || _peer !== peer) {
                return
              }
    
              if (this.peers.has(peer.id)) {
                return
              }
    
              console.log("ping", peer.id)
    
              // Initial message in the handshake
              this.webrtc.whisper(peer, "tw-ml", "tw")
    
              setTimeout(handshake.bind(this, peer), 500)
    
          this.webrtc.on("receivedPeerData", (type, message, peer) => {
            this.checkAndEnsureUser()
    
            // Message could have been forwarded but yjs only needs to know about directly connected peers
            const peerId = peer.forwardedBy ? peer.forwardedBy.id : peer.id
    
    
              console.log("receivedData", peerId, message)
    
              this.checkAndInsertPeer(peerId)
              this.receiveMessage(peerId, message)
            } else if (type === "tw-ml" && !peer.forwardedBy) {
              // Handshakes can only be sent and received directly
    
              if (message === "tw") {
                // Response message in the handshake
                this.webrtc.whisper(peer, "tw-ml", "ml")
              } else if (message == "ml") {
                // Handshake completed
                this.checkAndInsertPeer(peer.id)
              }
            }
    
          this.webrtc.on("channelClose", (dataChannel, peer) => {
            this.checkAndEnsureUser()
            this.checkAndRemovePeer(peer.id)
    
        // Ensure that y-js is up to date on the user's id
        checkAndEnsureUser() {
          const id = this.webrtc.getMyId()
    
          if (this.y.db.userId === id) {
            return
          }
    
          for (let f of this.userEventListeners) {
            f({ action: "userID", id: id })
          }
    
          this.setUserId(id)
        }
    
        // Ensure that y-js knows that the peer has joined
        checkAndInsertPeer(uid) {
          if (this.peers.has(uid)) {
            return
          }
    
          this.peers.add(uid)
    
          console.log("createdPeer", uid)
    
          this.userJoined(uid, "master")
        }
    
        // Ensure that y-js knows that the peer has left
        checkAndRemovePeer(uid) {
          if (!this.peers.has(uid)) {
            return
          }
    
          this.peers.delete(uid)
    
          console.log("removedPeer", uid)
    
          this.userLeft(uid)
        }
    
    
        connectToPeer(/*uid*/) {
          // currently deprecated
    
          super.disconnect()
        }
    
        reconnect() {
    
          // y-js db transactions can send messages after a peer has disconnected
          if (!this.peers.has(uid) || !this.webrtc.getPeerById(uid)) {
            return
          }
    
          console.log("send", uid, message)
    
    
          this.webrtc.whisper(this.webrtc.getPeerById(uid), "y-js", message)
    
          if (message.type !== "update") console.log("broadcast", message)
    
    
          this.webrtc.shout("y-js", message)
    
    
        isDisconnected() {
          return false
        }
      }
    
      Y.extend("webrtc", WebRTC)
    }
    
    
    Nayeem Rahman's avatar
    Nayeem Rahman committed
    export default extend
    
    if (typeof Y !== "undefined") {
      extend(Y)
    }