UNPKG

peerjs

Version:
1,040 lines (1,000 loc) 88.6 kB
import {pack as $gCcbY$pack, unpack as $gCcbY$unpack} from "peerjs-js-binarypack"; import $gCcbY$webrtcadapter from "webrtc-adapter"; import {Encoder as $gCcbY$Encoder, decodeMultiStream as $gCcbY$decodeMultiStream} from "@msgpack/msgpack"; function $parcel$export(e, n, v, s) { Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true}); } class $fcbcc7538a6776d5$export$f1c5f4c9cb95390b { constructor(){ this.chunkedMTU = 16300 // The original 60000 bytes setting does not work when sending data from Firefox to Chrome, which is "cut off" after 16384 bytes and delivered individually. ; // Binary stuff this._dataCount = 1; this.chunk = (blob)=>{ const chunks = []; const size = blob.byteLength; const total = Math.ceil(size / this.chunkedMTU); let index = 0; let start = 0; while(start < size){ const end = Math.min(size, start + this.chunkedMTU); const b = blob.slice(start, end); const chunk = { __peerData: this._dataCount, n: index, data: b, total: total }; chunks.push(chunk); start = end; index++; } this._dataCount++; return chunks; }; } } function $fcbcc7538a6776d5$export$52c89ebcdc4f53f2(bufs) { let size = 0; for (const buf of bufs)size += buf.byteLength; const result = new Uint8Array(size); let offset = 0; for (const buf of bufs){ result.set(buf, offset); offset += buf.byteLength; } return result; } const $fb63e766cfafaab9$var$webRTCAdapter = //@ts-ignore (0, $gCcbY$webrtcadapter).default || (0, $gCcbY$webrtcadapter); const $fb63e766cfafaab9$export$25be9502477c137d = new class { isWebRTCSupported() { return typeof RTCPeerConnection !== "undefined"; } isBrowserSupported() { const browser = this.getBrowser(); const version = this.getVersion(); const validBrowser = this.supportedBrowsers.includes(browser); if (!validBrowser) return false; if (browser === "chrome") return version >= this.minChromeVersion; if (browser === "firefox") return version >= this.minFirefoxVersion; if (browser === "safari") return !this.isIOS && version >= this.minSafariVersion; return false; } getBrowser() { return $fb63e766cfafaab9$var$webRTCAdapter.browserDetails.browser; } getVersion() { return $fb63e766cfafaab9$var$webRTCAdapter.browserDetails.version || 0; } isUnifiedPlanSupported() { const browser = this.getBrowser(); const version = $fb63e766cfafaab9$var$webRTCAdapter.browserDetails.version || 0; if (browser === "chrome" && version < this.minChromeVersion) return false; if (browser === "firefox" && version >= this.minFirefoxVersion) return true; if (!window.RTCRtpTransceiver || !("currentDirection" in RTCRtpTransceiver.prototype)) return false; let tempPc; let supported = false; try { tempPc = new RTCPeerConnection(); tempPc.addTransceiver("audio"); supported = true; } catch (e) {} finally{ if (tempPc) tempPc.close(); } return supported; } toString() { return `Supports: browser:${this.getBrowser()} version:${this.getVersion()} isIOS:${this.isIOS} isWebRTCSupported:${this.isWebRTCSupported()} isBrowserSupported:${this.isBrowserSupported()} isUnifiedPlanSupported:${this.isUnifiedPlanSupported()}`; } constructor(){ this.isIOS = typeof navigator !== "undefined" ? [ "iPad", "iPhone", "iPod" ].includes(navigator.platform) : false; this.supportedBrowsers = [ "firefox", "chrome", "safari" ]; this.minFirefoxVersion = 59; this.minChromeVersion = 72; this.minSafariVersion = 605; } }(); const $9a84a32bf0bf36bb$export$f35f128fd59ea256 = (id)=>{ // Allow empty ids return !id || /^[A-Za-z0-9]+(?:[ _-][A-Za-z0-9]+)*$/.test(id); }; const $0e5fd1585784c252$export$4e61f672936bec77 = ()=>Math.random().toString(36).slice(2); const $4f4134156c446392$var$DEFAULT_CONFIG = { iceServers: [ { urls: "stun:stun.l.google.com:19302" }, { urls: [ "turn:eu-0.turn.peerjs.com:3478", "turn:us-0.turn.peerjs.com:3478" ], username: "peerjs", credential: "peerjsp" } ], sdpSemantics: "unified-plan" }; class $4f4134156c446392$export$f8f26dd395d7e1bd extends (0, $fcbcc7538a6776d5$export$f1c5f4c9cb95390b) { noop() {} blobToArrayBuffer(blob, cb) { const fr = new FileReader(); fr.onload = function(evt) { if (evt.target) cb(evt.target.result); }; fr.readAsArrayBuffer(blob); return fr; } binaryStringToArrayBuffer(binary) { const byteArray = new Uint8Array(binary.length); for(let i = 0; i < binary.length; i++)byteArray[i] = binary.charCodeAt(i) & 0xff; return byteArray.buffer; } isSecure() { return location.protocol === "https:"; } constructor(...args){ super(...args); this.CLOUD_HOST = "0.peerjs.com"; this.CLOUD_PORT = 443; // Browsers that need chunking: this.chunkedBrowsers = { Chrome: 1, chrome: 1 }; // Returns browser-agnostic default config this.defaultConfig = $4f4134156c446392$var$DEFAULT_CONFIG; this.browser = (0, $fb63e766cfafaab9$export$25be9502477c137d).getBrowser(); this.browserVersion = (0, $fb63e766cfafaab9$export$25be9502477c137d).getVersion(); this.pack = $gCcbY$pack; this.unpack = $gCcbY$unpack; /** * A hash of WebRTC features mapped to booleans that correspond to whether the feature is supported by the current browser. * * :::caution * Only the properties documented here are guaranteed to be present on `util.supports` * ::: */ this.supports = function() { const supported = { browser: (0, $fb63e766cfafaab9$export$25be9502477c137d).isBrowserSupported(), webRTC: (0, $fb63e766cfafaab9$export$25be9502477c137d).isWebRTCSupported(), audioVideo: false, data: false, binaryBlob: false, reliable: false }; if (!supported.webRTC) return supported; let pc; try { pc = new RTCPeerConnection($4f4134156c446392$var$DEFAULT_CONFIG); supported.audioVideo = true; let dc; try { dc = pc.createDataChannel("_PEERJSTEST", { ordered: true }); supported.data = true; supported.reliable = !!dc.ordered; // Binary test try { dc.binaryType = "blob"; supported.binaryBlob = !(0, $fb63e766cfafaab9$export$25be9502477c137d).isIOS; } catch (e) {} } catch (e) {} finally{ if (dc) dc.close(); } } catch (e) {} finally{ if (pc) pc.close(); } return supported; }(); // Ensure alphanumeric ids this.validateId = (0, $9a84a32bf0bf36bb$export$f35f128fd59ea256); this.randomToken = (0, $0e5fd1585784c252$export$4e61f672936bec77); } } const $4f4134156c446392$export$7debb50ef11d5e0b = new $4f4134156c446392$export$f8f26dd395d7e1bd(); const $257947e92926277a$var$LOG_PREFIX = "PeerJS: "; var $257947e92926277a$export$243e62d78d3b544d; (function(LogLevel) { /** * Prints no logs. */ LogLevel[LogLevel["Disabled"] = 0] = "Disabled"; /** * Prints only errors. */ LogLevel[LogLevel["Errors"] = 1] = "Errors"; /** * Prints errors and warnings. */ LogLevel[LogLevel["Warnings"] = 2] = "Warnings"; /** * Prints all logs. */ LogLevel[LogLevel["All"] = 3] = "All"; })($257947e92926277a$export$243e62d78d3b544d || ($257947e92926277a$export$243e62d78d3b544d = {})); class $257947e92926277a$var$Logger { get logLevel() { return this._logLevel; } set logLevel(logLevel) { this._logLevel = logLevel; } log(...args) { if (this._logLevel >= 3) this._print(3, ...args); } warn(...args) { if (this._logLevel >= 2) this._print(2, ...args); } error(...args) { if (this._logLevel >= 1) this._print(1, ...args); } setLogFunction(fn) { this._print = fn; } _print(logLevel, ...rest) { const copy = [ $257947e92926277a$var$LOG_PREFIX, ...rest ]; for(const i in copy)if (copy[i] instanceof Error) copy[i] = "(" + copy[i].name + ") " + copy[i].message; if (logLevel >= 3) console.log(...copy); else if (logLevel >= 2) console.warn("WARNING", ...copy); else if (logLevel >= 1) console.error("ERROR", ...copy); } constructor(){ this._logLevel = 0; } } var $257947e92926277a$export$2e2bcd8739ae039 = new $257947e92926277a$var$Logger(); var $c4dcfd1d1ea86647$exports = {}; "use strict"; var $c4dcfd1d1ea86647$var$has = Object.prototype.hasOwnProperty, $c4dcfd1d1ea86647$var$prefix = "~"; /** * Constructor to create a storage for our `EE` objects. * An `Events` instance is a plain object whose properties are event names. * * @constructor * @private */ function $c4dcfd1d1ea86647$var$Events() {} // // We try to not inherit from `Object.prototype`. In some engines creating an // instance in this way is faster than calling `Object.create(null)` directly. // If `Object.create(null)` is not supported we prefix the event names with a // character to make sure that the built-in object properties are not // overridden or used as an attack vector. // if (Object.create) { $c4dcfd1d1ea86647$var$Events.prototype = Object.create(null); // // This hack is needed because the `__proto__` property is still inherited in // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5. // if (!new $c4dcfd1d1ea86647$var$Events().__proto__) $c4dcfd1d1ea86647$var$prefix = false; } /** * Representation of a single event listener. * * @param {Function} fn The listener function. * @param {*} context The context to invoke the listener with. * @param {Boolean} [once=false] Specify if the listener is a one-time listener. * @constructor * @private */ function $c4dcfd1d1ea86647$var$EE(fn, context, once) { this.fn = fn; this.context = context; this.once = once || false; } /** * Add a listener for a given event. * * @param {EventEmitter} emitter Reference to the `EventEmitter` instance. * @param {(String|Symbol)} event The event name. * @param {Function} fn The listener function. * @param {*} context The context to invoke the listener with. * @param {Boolean} once Specify if the listener is a one-time listener. * @returns {EventEmitter} * @private */ function $c4dcfd1d1ea86647$var$addListener(emitter, event, fn, context, once) { if (typeof fn !== "function") throw new TypeError("The listener must be a function"); var listener = new $c4dcfd1d1ea86647$var$EE(fn, context || emitter, once), evt = $c4dcfd1d1ea86647$var$prefix ? $c4dcfd1d1ea86647$var$prefix + event : event; if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++; else if (!emitter._events[evt].fn) emitter._events[evt].push(listener); else emitter._events[evt] = [ emitter._events[evt], listener ]; return emitter; } /** * Clear event by name. * * @param {EventEmitter} emitter Reference to the `EventEmitter` instance. * @param {(String|Symbol)} evt The Event name. * @private */ function $c4dcfd1d1ea86647$var$clearEvent(emitter, evt) { if (--emitter._eventsCount === 0) emitter._events = new $c4dcfd1d1ea86647$var$Events(); else delete emitter._events[evt]; } /** * Minimal `EventEmitter` interface that is molded against the Node.js * `EventEmitter` interface. * * @constructor * @public */ function $c4dcfd1d1ea86647$var$EventEmitter() { this._events = new $c4dcfd1d1ea86647$var$Events(); this._eventsCount = 0; } /** * Return an array listing the events for which the emitter has registered * listeners. * * @returns {Array} * @public */ $c4dcfd1d1ea86647$var$EventEmitter.prototype.eventNames = function eventNames() { var names = [], events, name; if (this._eventsCount === 0) return names; for(name in events = this._events)if ($c4dcfd1d1ea86647$var$has.call(events, name)) names.push($c4dcfd1d1ea86647$var$prefix ? name.slice(1) : name); if (Object.getOwnPropertySymbols) return names.concat(Object.getOwnPropertySymbols(events)); return names; }; /** * Return the listeners registered for a given event. * * @param {(String|Symbol)} event The event name. * @returns {Array} The registered listeners. * @public */ $c4dcfd1d1ea86647$var$EventEmitter.prototype.listeners = function listeners(event) { var evt = $c4dcfd1d1ea86647$var$prefix ? $c4dcfd1d1ea86647$var$prefix + event : event, handlers = this._events[evt]; if (!handlers) return []; if (handlers.fn) return [ handlers.fn ]; for(var i = 0, l = handlers.length, ee = new Array(l); i < l; i++)ee[i] = handlers[i].fn; return ee; }; /** * Return the number of listeners listening to a given event. * * @param {(String|Symbol)} event The event name. * @returns {Number} The number of listeners. * @public */ $c4dcfd1d1ea86647$var$EventEmitter.prototype.listenerCount = function listenerCount(event) { var evt = $c4dcfd1d1ea86647$var$prefix ? $c4dcfd1d1ea86647$var$prefix + event : event, listeners = this._events[evt]; if (!listeners) return 0; if (listeners.fn) return 1; return listeners.length; }; /** * Calls each of the listeners registered for a given event. * * @param {(String|Symbol)} event The event name. * @returns {Boolean} `true` if the event had listeners, else `false`. * @public */ $c4dcfd1d1ea86647$var$EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) { var evt = $c4dcfd1d1ea86647$var$prefix ? $c4dcfd1d1ea86647$var$prefix + event : event; if (!this._events[evt]) return false; var listeners = this._events[evt], len = arguments.length, args, i; if (listeners.fn) { if (listeners.once) this.removeListener(event, listeners.fn, undefined, true); switch(len){ case 1: return listeners.fn.call(listeners.context), true; case 2: return listeners.fn.call(listeners.context, a1), true; case 3: return listeners.fn.call(listeners.context, a1, a2), true; case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true; case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true; case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true; } for(i = 1, args = new Array(len - 1); i < len; i++)args[i - 1] = arguments[i]; listeners.fn.apply(listeners.context, args); } else { var length = listeners.length, j; for(i = 0; i < length; i++){ if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true); switch(len){ case 1: listeners[i].fn.call(listeners[i].context); break; case 2: listeners[i].fn.call(listeners[i].context, a1); break; case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break; case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break; default: if (!args) for(j = 1, args = new Array(len - 1); j < len; j++)args[j - 1] = arguments[j]; listeners[i].fn.apply(listeners[i].context, args); } } } return true; }; /** * Add a listener for a given event. * * @param {(String|Symbol)} event The event name. * @param {Function} fn The listener function. * @param {*} [context=this] The context to invoke the listener with. * @returns {EventEmitter} `this`. * @public */ $c4dcfd1d1ea86647$var$EventEmitter.prototype.on = function on(event, fn, context) { return $c4dcfd1d1ea86647$var$addListener(this, event, fn, context, false); }; /** * Add a one-time listener for a given event. * * @param {(String|Symbol)} event The event name. * @param {Function} fn The listener function. * @param {*} [context=this] The context to invoke the listener with. * @returns {EventEmitter} `this`. * @public */ $c4dcfd1d1ea86647$var$EventEmitter.prototype.once = function once(event, fn, context) { return $c4dcfd1d1ea86647$var$addListener(this, event, fn, context, true); }; /** * Remove the listeners of a given event. * * @param {(String|Symbol)} event The event name. * @param {Function} fn Only remove the listeners that match this function. * @param {*} context Only remove the listeners that have this context. * @param {Boolean} once Only remove one-time listeners. * @returns {EventEmitter} `this`. * @public */ $c4dcfd1d1ea86647$var$EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) { var evt = $c4dcfd1d1ea86647$var$prefix ? $c4dcfd1d1ea86647$var$prefix + event : event; if (!this._events[evt]) return this; if (!fn) { $c4dcfd1d1ea86647$var$clearEvent(this, evt); return this; } var listeners = this._events[evt]; if (listeners.fn) { if (listeners.fn === fn && (!once || listeners.once) && (!context || listeners.context === context)) $c4dcfd1d1ea86647$var$clearEvent(this, evt); } else { for(var i = 0, events = [], length = listeners.length; i < length; i++)if (listeners[i].fn !== fn || once && !listeners[i].once || context && listeners[i].context !== context) events.push(listeners[i]); // // Reset the array, or remove it completely if we have no more listeners. // if (events.length) this._events[evt] = events.length === 1 ? events[0] : events; else $c4dcfd1d1ea86647$var$clearEvent(this, evt); } return this; }; /** * Remove all listeners, or those of the specified event. * * @param {(String|Symbol)} [event] The event name. * @returns {EventEmitter} `this`. * @public */ $c4dcfd1d1ea86647$var$EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) { var evt; if (event) { evt = $c4dcfd1d1ea86647$var$prefix ? $c4dcfd1d1ea86647$var$prefix + event : event; if (this._events[evt]) $c4dcfd1d1ea86647$var$clearEvent(this, evt); } else { this._events = new $c4dcfd1d1ea86647$var$Events(); this._eventsCount = 0; } return this; }; // // Alias methods names because people roll like that. // $c4dcfd1d1ea86647$var$EventEmitter.prototype.off = $c4dcfd1d1ea86647$var$EventEmitter.prototype.removeListener; $c4dcfd1d1ea86647$var$EventEmitter.prototype.addListener = $c4dcfd1d1ea86647$var$EventEmitter.prototype.on; // // Expose the prefix. // $c4dcfd1d1ea86647$var$EventEmitter.prefixed = $c4dcfd1d1ea86647$var$prefix; // // Allow `EventEmitter` to be imported as module namespace. // $c4dcfd1d1ea86647$var$EventEmitter.EventEmitter = $c4dcfd1d1ea86647$var$EventEmitter; $c4dcfd1d1ea86647$exports = $c4dcfd1d1ea86647$var$EventEmitter; var $78455e22dea96b8c$exports = {}; $parcel$export($78455e22dea96b8c$exports, "ConnectionType", () => $78455e22dea96b8c$export$3157d57b4135e3bc); $parcel$export($78455e22dea96b8c$exports, "PeerErrorType", () => $78455e22dea96b8c$export$9547aaa2e39030ff); $parcel$export($78455e22dea96b8c$exports, "BaseConnectionErrorType", () => $78455e22dea96b8c$export$7974935686149686); $parcel$export($78455e22dea96b8c$exports, "DataConnectionErrorType", () => $78455e22dea96b8c$export$49ae800c114df41d); $parcel$export($78455e22dea96b8c$exports, "SerializationType", () => $78455e22dea96b8c$export$89f507cf986a947); $parcel$export($78455e22dea96b8c$exports, "SocketEventType", () => $78455e22dea96b8c$export$3b5c4a4b6354f023); $parcel$export($78455e22dea96b8c$exports, "ServerMessageType", () => $78455e22dea96b8c$export$adb4a1754da6f10d); var $78455e22dea96b8c$export$3157d57b4135e3bc; (function(ConnectionType) { ConnectionType["Data"] = "data"; ConnectionType["Media"] = "media"; })($78455e22dea96b8c$export$3157d57b4135e3bc || ($78455e22dea96b8c$export$3157d57b4135e3bc = {})); var $78455e22dea96b8c$export$9547aaa2e39030ff; (function(PeerErrorType) { /** * The client's browser does not support some or all WebRTC features that you are trying to use. */ PeerErrorType["BrowserIncompatible"] = "browser-incompatible"; /** * You've already disconnected this peer from the server and can no longer make any new connections on it. */ PeerErrorType["Disconnected"] = "disconnected"; /** * The ID passed into the Peer constructor contains illegal characters. */ PeerErrorType["InvalidID"] = "invalid-id"; /** * The API key passed into the Peer constructor contains illegal characters or is not in the system (cloud server only). */ PeerErrorType["InvalidKey"] = "invalid-key"; /** * Lost or cannot establish a connection to the signalling server. */ PeerErrorType["Network"] = "network"; /** * The peer you're trying to connect to does not exist. */ PeerErrorType["PeerUnavailable"] = "peer-unavailable"; /** * PeerJS is being used securely, but the cloud server does not support SSL. Use a custom PeerServer. */ PeerErrorType["SslUnavailable"] = "ssl-unavailable"; /** * Unable to reach the server. */ PeerErrorType["ServerError"] = "server-error"; /** * An error from the underlying socket. */ PeerErrorType["SocketError"] = "socket-error"; /** * The underlying socket closed unexpectedly. */ PeerErrorType["SocketClosed"] = "socket-closed"; /** * The ID passed into the Peer constructor is already taken. * * :::caution * This error is not fatal if your peer has open peer-to-peer connections. * This can happen if you attempt to {@apilink Peer.reconnect} a peer that has been disconnected from the server, * but its old ID has now been taken. * ::: */ PeerErrorType["UnavailableID"] = "unavailable-id"; /** * Native WebRTC errors. */ PeerErrorType["WebRTC"] = "webrtc"; })($78455e22dea96b8c$export$9547aaa2e39030ff || ($78455e22dea96b8c$export$9547aaa2e39030ff = {})); var $78455e22dea96b8c$export$7974935686149686; (function(BaseConnectionErrorType) { BaseConnectionErrorType["NegotiationFailed"] = "negotiation-failed"; BaseConnectionErrorType["ConnectionClosed"] = "connection-closed"; })($78455e22dea96b8c$export$7974935686149686 || ($78455e22dea96b8c$export$7974935686149686 = {})); var $78455e22dea96b8c$export$49ae800c114df41d; (function(DataConnectionErrorType) { DataConnectionErrorType["NotOpenYet"] = "not-open-yet"; DataConnectionErrorType["MessageToBig"] = "message-too-big"; })($78455e22dea96b8c$export$49ae800c114df41d || ($78455e22dea96b8c$export$49ae800c114df41d = {})); var $78455e22dea96b8c$export$89f507cf986a947; (function(SerializationType) { SerializationType["Binary"] = "binary"; SerializationType["BinaryUTF8"] = "binary-utf8"; SerializationType["JSON"] = "json"; SerializationType["None"] = "raw"; })($78455e22dea96b8c$export$89f507cf986a947 || ($78455e22dea96b8c$export$89f507cf986a947 = {})); var $78455e22dea96b8c$export$3b5c4a4b6354f023; (function(SocketEventType) { SocketEventType["Message"] = "message"; SocketEventType["Disconnected"] = "disconnected"; SocketEventType["Error"] = "error"; SocketEventType["Close"] = "close"; })($78455e22dea96b8c$export$3b5c4a4b6354f023 || ($78455e22dea96b8c$export$3b5c4a4b6354f023 = {})); var $78455e22dea96b8c$export$adb4a1754da6f10d; (function(ServerMessageType) { ServerMessageType["Heartbeat"] = "HEARTBEAT"; ServerMessageType["Candidate"] = "CANDIDATE"; ServerMessageType["Offer"] = "OFFER"; ServerMessageType["Answer"] = "ANSWER"; ServerMessageType["Open"] = "OPEN"; ServerMessageType["Error"] = "ERROR"; ServerMessageType["IdTaken"] = "ID-TAKEN"; ServerMessageType["InvalidKey"] = "INVALID-KEY"; ServerMessageType["Leave"] = "LEAVE"; ServerMessageType["Expire"] = "EXPIRE"; })($78455e22dea96b8c$export$adb4a1754da6f10d || ($78455e22dea96b8c$export$adb4a1754da6f10d = {})); var $f5f881ec4575f1fc$exports = {}; $f5f881ec4575f1fc$exports = JSON.parse('{"name":"peerjs","version":"1.5.4","keywords":["peerjs","webrtc","p2p","rtc"],"description":"PeerJS client","homepage":"https://peerjs.com","bugs":{"url":"https://github.com/peers/peerjs/issues"},"repository":{"type":"git","url":"https://github.com/peers/peerjs"},"license":"MIT","contributors":["Michelle Bu <michelle@michellebu.com>","afrokick <devbyru@gmail.com>","ericz <really.ez@gmail.com>","Jairo <kidandcat@gmail.com>","Jonas Gloning <34194370+jonasgloning@users.noreply.github.com>","Jairo Caro-Accino Viciana <jairo@galax.be>","Carlos Caballero <carlos.caballero.gonzalez@gmail.com>","hc <hheennrryy@gmail.com>","Muhammad Asif <capripio@gmail.com>","PrashoonB <prashoonbhattacharjee@gmail.com>","Harsh Bardhan Mishra <47351025+HarshCasper@users.noreply.github.com>","akotynski <aleksanderkotbury@gmail.com>","lmb <i@lmb.io>","Jairooo <jairocaro@msn.com>","Moritz St\xfcckler <moritz.stueckler@gmail.com>","Simon <crydotsnakegithub@gmail.com>","Denis Lukov <denismassters@gmail.com>","Philipp Hancke <fippo@andyet.net>","Hans Oksendahl <hansoksendahl@gmail.com>","Jess <jessachandler@gmail.com>","khankuan <khankuan@gmail.com>","DUODVK <kurmanov.work@gmail.com>","XiZhao <kwang1imsa@gmail.com>","Matthias Lohr <matthias@lohr.me>","=frank tree <=frnktrb@googlemail.com>","Andre Eckardt <aeckardt@outlook.com>","Chris Cowan <agentme49@gmail.com>","Alex Chuev <alex@chuev.com>","alxnull <alxnull@e.mail.de>","Yemel Jardi <angel.jardi@gmail.com>","Ben Parnell <benjaminparnell.94@gmail.com>","Benny Lichtner <bennlich@gmail.com>","fresheneesz <bitetrudpublic@gmail.com>","bob.barstead@exaptive.com <bob.barstead@exaptive.com>","chandika <chandika@gmail.com>","emersion <contact@emersion.fr>","Christopher Van <cvan@users.noreply.github.com>","eddieherm <edhermoso@gmail.com>","Eduardo Pinho <enet4mikeenet@gmail.com>","Evandro Zanatta <ezanatta@tray.net.br>","Gardner Bickford <gardner@users.noreply.github.com>","Gian Luca <gianluca.cecchi@cynny.com>","PatrickJS <github@gdi2290.com>","jonnyf <github@jonathanfoss.co.uk>","Hizkia Felix <hizkifw@gmail.com>","Hristo Oskov <hristo.oskov@gmail.com>","Isaac Madwed <i.madwed@gmail.com>","Ilya Konanykhin <ilya.konanykhin@gmail.com>","jasonbarry <jasbarry@me.com>","Jonathan Burke <jonathan.burke.1311@googlemail.com>","Josh Hamit <josh.hamit@gmail.com>","Jordan Austin <jrax86@gmail.com>","Joel Wetzell <jwetzell@yahoo.com>","xizhao <kevin.wang@cloudera.com>","Alberto Torres <kungfoobar@gmail.com>","Jonathan Mayol <mayoljonathan@gmail.com>","Jefferson Felix <me@jsfelix.dev>","Rolf Erik Lekang <me@rolflekang.com>","Kevin Mai-Husan Chia <mhchia@users.noreply.github.com>","Pepijn de Vos <pepijndevos@gmail.com>","JooYoung <qkdlql@naver.com>","Tobias Speicher <rootcommander@gmail.com>","Steve Blaurock <sblaurock@gmail.com>","Kyrylo Shegeda <shegeda@ualberta.ca>","Diwank Singh Tomer <singh@diwank.name>","So\u0308ren Balko <Soeren.Balko@gmail.com>","Arpit Solanki <solankiarpit1997@gmail.com>","Yuki Ito <yuki@gnnk.net>","Artur Zayats <zag2art@gmail.com>"],"funding":{"type":"opencollective","url":"https://opencollective.com/peer"},"collective":{"type":"opencollective","url":"https://opencollective.com/peer"},"files":["dist/*"],"sideEffects":["lib/global.ts","lib/supports.ts"],"main":"dist/bundler.cjs","module":"dist/bundler.mjs","browser-minified":"dist/peerjs.min.js","browser-unminified":"dist/peerjs.js","browser-minified-msgpack":"dist/serializer.msgpack.mjs","types":"dist/types.d.ts","engines":{"node":">= 14"},"targets":{"types":{"source":"lib/exports.ts"},"main":{"source":"lib/exports.ts","sourceMap":{"inlineSources":true}},"module":{"source":"lib/exports.ts","includeNodeModules":["eventemitter3"],"sourceMap":{"inlineSources":true}},"browser-minified":{"context":"browser","outputFormat":"global","optimize":true,"engines":{"browsers":"chrome >= 83, edge >= 83, firefox >= 80, safari >= 15"},"source":"lib/global.ts"},"browser-unminified":{"context":"browser","outputFormat":"global","optimize":false,"engines":{"browsers":"chrome >= 83, edge >= 83, firefox >= 80, safari >= 15"},"source":"lib/global.ts"},"browser-minified-msgpack":{"context":"browser","outputFormat":"esmodule","isLibrary":true,"optimize":true,"engines":{"browsers":"chrome >= 83, edge >= 83, firefox >= 102, safari >= 15"},"source":"lib/dataconnection/StreamConnection/MsgPack.ts"}},"scripts":{"contributors":"git-authors-cli --print=false && prettier --write package.json && git add package.json package-lock.json && git commit -m \\"chore(contributors): update and sort contributors list\\"","check":"tsc --noEmit && tsc -p e2e/tsconfig.json --noEmit","watch":"parcel watch","build":"rm -rf dist && parcel build","prepublishOnly":"npm run build","test":"jest","test:watch":"jest --watch","coverage":"jest --coverage --collectCoverageFrom=\\"./lib/**\\"","format":"prettier --write .","format:check":"prettier --check .","semantic-release":"semantic-release","e2e":"wdio run e2e/wdio.local.conf.ts","e2e:bstack":"wdio run e2e/wdio.bstack.conf.ts"},"devDependencies":{"@parcel/config-default":"^2.9.3","@parcel/packager-ts":"^2.9.3","@parcel/transformer-typescript-tsc":"^2.9.3","@parcel/transformer-typescript-types":"^2.9.3","@semantic-release/changelog":"^6.0.1","@semantic-release/git":"^10.0.1","@swc/core":"^1.3.27","@swc/jest":"^0.2.24","@types/jasmine":"^4.3.4","@wdio/browserstack-service":"^8.11.2","@wdio/cli":"^8.11.2","@wdio/globals":"^8.11.2","@wdio/jasmine-framework":"^8.11.2","@wdio/local-runner":"^8.11.2","@wdio/spec-reporter":"^8.11.2","@wdio/types":"^8.10.4","http-server":"^14.1.1","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","mock-socket":"^9.0.0","parcel":"^2.9.3","prettier":"^3.0.0","semantic-release":"^21.0.0","ts-node":"^10.9.1","typescript":"^5.0.0","wdio-geckodriver-service":"^5.0.1"},"dependencies":{"@msgpack/msgpack":"^2.8.0","eventemitter3":"^4.0.7","peerjs-js-binarypack":"^2.1.0","webrtc-adapter":"^9.0.0"},"alias":{"process":false,"buffer":false}}'); class $8f5bfa60836d261d$export$4798917dbf149b79 extends (0, $c4dcfd1d1ea86647$exports.EventEmitter) { constructor(secure, host, port, path, key, pingInterval = 5000){ super(); this.pingInterval = pingInterval; this._disconnected = true; this._messagesQueue = []; const wsProtocol = secure ? "wss://" : "ws://"; this._baseUrl = wsProtocol + host + ":" + port + path + "peerjs?key=" + key; } start(id, token) { this._id = id; const wsUrl = `${this._baseUrl}&id=${id}&token=${token}`; if (!!this._socket || !this._disconnected) return; this._socket = new WebSocket(wsUrl + "&version=" + (0, $f5f881ec4575f1fc$exports.version)); this._disconnected = false; this._socket.onmessage = (event)=>{ let data; try { data = JSON.parse(event.data); (0, $257947e92926277a$export$2e2bcd8739ae039).log("Server message received:", data); } catch (e) { (0, $257947e92926277a$export$2e2bcd8739ae039).log("Invalid server message", event.data); return; } this.emit((0, $78455e22dea96b8c$export$3b5c4a4b6354f023).Message, data); }; this._socket.onclose = (event)=>{ if (this._disconnected) return; (0, $257947e92926277a$export$2e2bcd8739ae039).log("Socket closed.", event); this._cleanup(); this._disconnected = true; this.emit((0, $78455e22dea96b8c$export$3b5c4a4b6354f023).Disconnected); }; // Take care of the queue of connections if necessary and make sure Peer knows // socket is open. this._socket.onopen = ()=>{ if (this._disconnected) return; this._sendQueuedMessages(); (0, $257947e92926277a$export$2e2bcd8739ae039).log("Socket open"); this._scheduleHeartbeat(); }; } _scheduleHeartbeat() { this._wsPingTimer = setTimeout(()=>{ this._sendHeartbeat(); }, this.pingInterval); } _sendHeartbeat() { if (!this._wsOpen()) { (0, $257947e92926277a$export$2e2bcd8739ae039).log(`Cannot send heartbeat, because socket closed`); return; } const message = JSON.stringify({ type: (0, $78455e22dea96b8c$export$adb4a1754da6f10d).Heartbeat }); this._socket.send(message); this._scheduleHeartbeat(); } /** Is the websocket currently open? */ _wsOpen() { return !!this._socket && this._socket.readyState === 1; } /** Send queued messages. */ _sendQueuedMessages() { //Create copy of queue and clear it, //because send method push the message back to queue if smth will go wrong const copiedQueue = [ ...this._messagesQueue ]; this._messagesQueue = []; for (const message of copiedQueue)this.send(message); } /** Exposed send for DC & Peer. */ send(data) { if (this._disconnected) return; // If we didn't get an ID yet, we can't yet send anything so we should queue // up these messages. if (!this._id) { this._messagesQueue.push(data); return; } if (!data.type) { this.emit((0, $78455e22dea96b8c$export$3b5c4a4b6354f023).Error, "Invalid message"); return; } if (!this._wsOpen()) return; const message = JSON.stringify(data); this._socket.send(message); } close() { if (this._disconnected) return; this._cleanup(); this._disconnected = true; } _cleanup() { if (this._socket) { this._socket.onopen = this._socket.onmessage = this._socket.onclose = null; this._socket.close(); this._socket = undefined; } clearTimeout(this._wsPingTimer); } } class $b82fb8fc0514bfc1$export$89e6bb5ad64bf4a { constructor(connection){ this.connection = connection; } /** Returns a PeerConnection object set up correctly (for data, media). */ startConnection(options) { const peerConnection = this._startPeerConnection(); // Set the connection's PC. this.connection.peerConnection = peerConnection; if (this.connection.type === (0, $78455e22dea96b8c$export$3157d57b4135e3bc).Media && options._stream) this._addTracksToConnection(options._stream, peerConnection); // What do we need to do now? if (options.originator) { const dataConnection = this.connection; const config = { ordered: !!options.reliable }; const dataChannel = peerConnection.createDataChannel(dataConnection.label, config); dataConnection._initializeDataChannel(dataChannel); this._makeOffer(); } else this.handleSDP("OFFER", options.sdp); } /** Start a PC. */ _startPeerConnection() { (0, $257947e92926277a$export$2e2bcd8739ae039).log("Creating RTCPeerConnection."); const peerConnection = new RTCPeerConnection(this.connection.provider.options.config); this._setupListeners(peerConnection); return peerConnection; } /** Set up various WebRTC listeners. */ _setupListeners(peerConnection) { const peerId = this.connection.peer; const connectionId = this.connection.connectionId; const connectionType = this.connection.type; const provider = this.connection.provider; // ICE CANDIDATES. (0, $257947e92926277a$export$2e2bcd8739ae039).log("Listening for ICE candidates."); peerConnection.onicecandidate = (evt)=>{ if (!evt.candidate || !evt.candidate.candidate) return; (0, $257947e92926277a$export$2e2bcd8739ae039).log(`Received ICE candidates for ${peerId}:`, evt.candidate); provider.socket.send({ type: (0, $78455e22dea96b8c$export$adb4a1754da6f10d).Candidate, payload: { candidate: evt.candidate, type: connectionType, connectionId: connectionId }, dst: peerId }); }; peerConnection.oniceconnectionstatechange = ()=>{ switch(peerConnection.iceConnectionState){ case "failed": (0, $257947e92926277a$export$2e2bcd8739ae039).log("iceConnectionState is failed, closing connections to " + peerId); this.connection.emitError((0, $78455e22dea96b8c$export$7974935686149686).NegotiationFailed, "Negotiation of connection to " + peerId + " failed."); this.connection.close(); break; case "closed": (0, $257947e92926277a$export$2e2bcd8739ae039).log("iceConnectionState is closed, closing connections to " + peerId); this.connection.emitError((0, $78455e22dea96b8c$export$7974935686149686).ConnectionClosed, "Connection to " + peerId + " closed."); this.connection.close(); break; case "disconnected": (0, $257947e92926277a$export$2e2bcd8739ae039).log("iceConnectionState changed to disconnected on the connection with " + peerId); break; case "completed": peerConnection.onicecandidate = ()=>{}; break; } this.connection.emit("iceStateChanged", peerConnection.iceConnectionState); }; // DATACONNECTION. (0, $257947e92926277a$export$2e2bcd8739ae039).log("Listening for data channel"); // Fired between offer and answer, so options should already be saved // in the options hash. peerConnection.ondatachannel = (evt)=>{ (0, $257947e92926277a$export$2e2bcd8739ae039).log("Received data channel"); const dataChannel = evt.channel; const connection = provider.getConnection(peerId, connectionId); connection._initializeDataChannel(dataChannel); }; // MEDIACONNECTION. (0, $257947e92926277a$export$2e2bcd8739ae039).log("Listening for remote stream"); peerConnection.ontrack = (evt)=>{ (0, $257947e92926277a$export$2e2bcd8739ae039).log("Received remote stream"); const stream = evt.streams[0]; const connection = provider.getConnection(peerId, connectionId); if (connection.type === (0, $78455e22dea96b8c$export$3157d57b4135e3bc).Media) { const mediaConnection = connection; this._addStreamToMediaConnection(stream, mediaConnection); } }; } cleanup() { (0, $257947e92926277a$export$2e2bcd8739ae039).log("Cleaning up PeerConnection to " + this.connection.peer); const peerConnection = this.connection.peerConnection; if (!peerConnection) return; this.connection.peerConnection = null; //unsubscribe from all PeerConnection's events peerConnection.onicecandidate = peerConnection.oniceconnectionstatechange = peerConnection.ondatachannel = peerConnection.ontrack = ()=>{}; const peerConnectionNotClosed = peerConnection.signalingState !== "closed"; let dataChannelNotClosed = false; const dataChannel = this.connection.dataChannel; if (dataChannel) dataChannelNotClosed = !!dataChannel.readyState && dataChannel.readyState !== "closed"; if (peerConnectionNotClosed || dataChannelNotClosed) peerConnection.close(); } async _makeOffer() { const peerConnection = this.connection.peerConnection; const provider = this.connection.provider; try { const offer = await peerConnection.createOffer(this.connection.options.constraints); (0, $257947e92926277a$export$2e2bcd8739ae039).log("Created offer."); if (this.connection.options.sdpTransform && typeof this.connection.options.sdpTransform === "function") offer.sdp = this.connection.options.sdpTransform(offer.sdp) || offer.sdp; try { await peerConnection.setLocalDescription(offer); (0, $257947e92926277a$export$2e2bcd8739ae039).log("Set localDescription:", offer, `for:${this.connection.peer}`); let payload = { sdp: offer, type: this.connection.type, connectionId: this.connection.connectionId, metadata: this.connection.metadata }; if (this.connection.type === (0, $78455e22dea96b8c$export$3157d57b4135e3bc).Data) { const dataConnection = this.connection; payload = { ...payload, label: dataConnection.label, reliable: dataConnection.reliable, serialization: dataConnection.serialization }; } provider.socket.send({ type: (0, $78455e22dea96b8c$export$adb4a1754da6f10d).Offer, payload: payload, dst: this.connection.peer }); } catch (err) { // TODO: investigate why _makeOffer is being called from the answer if (err != "OperationError: Failed to set local offer sdp: Called in wrong state: kHaveRemoteOffer") { provider.emitError((0, $78455e22dea96b8c$export$9547aaa2e39030ff).WebRTC, err); (0, $257947e92926277a$export$2e2bcd8739ae039).log("Failed to setLocalDescription, ", err); } } } catch (err_1) { provider.emitError((0, $78455e22dea96b8c$export$9547aaa2e39030ff).WebRTC, err_1); (0, $257947e92926277a$export$2e2bcd8739ae039).log("Failed to createOffer, ", err_1); } } async _makeAnswer() { const peerConnection = this.connection.peerConnection; const provider = this.connection.provider; try { const answer = await peerConnection.createAnswer(); (0, $257947e92926277a$export$2e2bcd8739ae039).log("Created answer."); if (this.connection.options.sdpTransform && typeof this.connection.options.sdpTransform === "function") answer.sdp = this.connection.options.sdpTransform(answer.sdp) || answer.sdp; try { await peerConnection.setLocalDescription(answer); (0, $257947e92926277a$export$2e2bcd8739ae039).log(`Set localDescription:`, answer, `for:${this.connection.peer}`); provider.socket.send({ type: (0, $78455e22dea96b8c$export$adb4a1754da6f10d).Answer, payload: { sdp: answer, type: this.connection.type, connectionId: this.connection.connectionId }, dst: this.connection.peer }); } catch (err) { provider.emitError((0, $78455e22dea96b8c$export$9547aaa2e39030ff).WebRTC, err); (0, $257947e92926277a$export$2e2bcd8739ae039).log("Failed to setLocalDescription, ", err); } } catch (err_1) { provider.emitError((0, $78455e22dea96b8c$export$9547aaa2e39030ff).WebRTC, err_1); (0, $257947e92926277a$export$2e2bcd8739ae039).log("Failed to create answer, ", err_1); } } /** Handle an SDP. */ async handleSDP(type, sdp) { sdp = new RTCSessionDescription(sdp); const peerConnection = this.connection.peerConnection; const provider = this.connection.provider; (0, $257947e92926277a$export$2e2bcd8739ae039).log("Setting remote description", sdp); const self = this; try { await peerConnection.setRemoteDescription(sdp); (0, $257947e92926277a$export$2e2bcd8739ae039).log(`Set remoteDescription:${type} for:${this.connection.peer}`); if (type === "OFFER") await self._makeAnswer(); } catch (err) { provider.emitError((0, $78455e22dea96b8c$export$9547aaa2e39030ff).WebRTC, err); (0, $257947e92926277a$export$2e2bcd8739ae039).log("Failed to setRemoteDescription, ", err); } } /** Handle a candidate. */ async handleCandidate(ice) { (0, $257947e92926277a$export$2e2bcd8739ae039).log(`handleCandidate:`, ice); try { await this.connection.peerConnection.addIceCandidate(ice); (0, $257947e92926277a$export$2e2bcd8739ae039).log(`Added ICE candidate for:${this.connection.peer}`); } catch (err) { this.connection.provider.emitError((0, $78455e22dea96b8c$export$9547aaa2e39030ff).WebRTC, err); (0, $257947e92926277a$export$2e2bcd8739ae039).log("Failed to handleCandidate, ", err); } } _addTracksToConnection(stream, peerConnection) { (0, $257947e92926277a$export$2e2bcd8739ae039).log(`add tracks from stream ${stream.id} to peer connection`); if (!peerConnection.addTrack) return (0, $257947e92926277a$export$2e2bcd8739ae039).error(`Your browser does't support RTCPeerConnection#addTrack. Ignored.`); stream.getTracks().forEach((track)=>{ peerConnection.addTrack(track, stream); }); } _addStreamToMediaConnection(stream, mediaConnection) { (0, $257947e92926277a$export$2e2bcd8739ae039).log(`add stream ${stream.id} to media connection ${mediaConnection.connectionId}`); mediaConnection.addStream(stream); } } class $23779d1881157a18$export$6a678e589c8a4542 extends (0, $c4dcfd1d1ea86647$exports.EventEmitter) { /** * Emits a typed error message. * * @internal */ emitError(type, err) { (0, $257947e92926277a$export$2e2bcd8739ae039).error("Error:", err); // @ts-ignore this.emit("error", new $23779d1881157a18$export$98871882f492de82(`${type}`, err)); } } class $23779d1881157a18$export$98871882f492de82 extends Error { /** * @internal */ constructor(type, err){ if (typeof err === "string") super(err); else { super(); Object.assign(this, err); } this.type = type; } } class $5045192fc6d387ba$export$23a2a68283c24d80 extends (0, $23779d1881157a18$export$6a678e589c8a4542) { /** * Whether the media connection is active (e.g. your call has been answered). * You can check this if you want to set a maximum wait time for a one-sided call. */ get open() { return this._open; } constructor(/** * The ID of the peer on the other end of this connection. */ peer, provider, options){ super(); this.peer = peer; this.provider = provider; this.options = options; this._open = false; this.metadata = options.metadata; } } class $5c1d08c7c57da9a3$export$4a84e95a2324ac29 extends (0, $5045192fc6d387ba$export$23a2a68283c24d80) { static #_ = this.ID_PREFIX = "mc_"; /** * For media connections, this is always 'media'. */ get type() { return (0, $78455e22dea96b8c$export$3157d57b4135e3bc).Media; } get localStream() { return this._localStream; } get remoteStream() { return this._remoteStream; } constructor(peerId, provider, options){ super(peerId, provider, options); this._localStream = this.options._stream; this.connectionId = this.options.connectionId || $5c1d08c7c57da9a3$export$4a84e95a2324ac29.ID_PREFIX + (0, $4f4134156c446392$export$7debb50ef11d5e0b).randomToken(); this._negotiator = new (0, $b82fb8fc0514bfc1$export$89e6bb5ad64bf4a)(this); if (this._localStream) this._negotiator.startConnection({ _stream: this._localStream, originator: true }); } /** Called by the Negotiator when the DataChannel is ready. */ _initializeDataChannel(dc) { this.dataChannel = dc; this.dataChannel.onopen = ()=>{ (0, $257947e92926277a$export$2e2bcd8739ae039).log(`DC#${this.connectionId} dc connection success`); this.emit("willCloseOnRemote"); }; this.dataChannel.onclose = ()=>{ (0, $257947e92926277a$export$2e2bcd8739ae039).log(`DC#${this.connectionId} dc closed for:`, this.peer); this.close(); }; } addStream(remoteStream) { (0, $257947e92926277a$export$2e2bcd8739ae039).log("Receiving stream", remoteStream); this._remoteStream = remoteStream; super.emit("stream", remoteStream); // Should we call