/* 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) } this.initialiseConnection() window.addEventListener("unload", () => { this.y.destroy() }) } initialiseConnection() { this.webrtc = new LioWebRTC({ url: this.webrtcOptions.url, dataOnly: true, /*network: { minPeers: 4, maxPeers: 8, },*/ }) this.peers = new Set() this.webrtc.on("ready", () => { this.webrtc.joinRoom(this.webrtcOptions.room) }) this.webrtc.on("joinedRoom", () => { this.checkAndEnsureUser() }) this.webrtc.on("leftRoom", () => { console.log("LEFT ROOM") }) 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) } setTimeout(handshake.bind(this, peer), 100) }) this.webrtc.on("receivedPeerData", (type, message, peer) => { this.checkAndEnsureUser() if (message.type !== "update") { console.log("receivedData", peer.id, message) } if (type === "y-js") { this.checkAndInsertPeer(peer.id) this.receiveMessage(peer.id, message) } else if (type === "tw-ml") { 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 (const 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 } disconnect() { this.webrtc.quit() super.disconnect() } reconnect() { this.initialiseConnection() super.reconnect() } send(uid, message) { // 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) } broadcast(message) { if (message.type !== "update") console.log("broadcast", message) this.webrtc.shout("y-js", message) } isDisconnected() { return false } } Y.extend("webrtc", WebRTC) } export default extend if (typeof Y !== "undefined") { extend(Y) }