// modules are defined as an array // [ module function, map of requires ] // // map of requires is short require name -> numeric require // // anything defined in a previous bundle is accessed via the // orig method which is the require for previous bundles (function ( modules, entry, mainEntry, parcelRequireName, externals, distDir, publicUrl, devServer ) { /* eslint-disable no-undef */ var globalObject = typeof globalThis !== 'undefined' ? globalThis : typeof self !== 'undefined' ? self : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : {}; /* eslint-enable no-undef */ // Save the require from previous bundle to this closure if any var previousRequire = typeof globalObject[parcelRequireName] === 'function' && globalObject[parcelRequireName]; var importMap = previousRequire.i || {}; var cache = previousRequire.cache || {}; // Do not use `require` to prevent Webpack from trying to bundle this call var nodeRequire = typeof module !== 'undefined' && typeof module.require === 'function' && module.require.bind(module); function newRequire(name, jumped) { if (!cache[name]) { if (!modules[name]) { if (externals[name]) { return externals[name]; } // if we cannot find the module within our internal map or // cache jump to the current global require ie. the last bundle // that was added to the page. var currentRequire = typeof globalObject[parcelRequireName] === 'function' && globalObject[parcelRequireName]; if (!jumped && currentRequire) { return currentRequire(name, true); } // If there are other bundles on this page the require from the // previous one is saved to 'previousRequire'. Repeat this as // many times as there are bundles until the module is found or // we exhaust the require chain. if (previousRequire) { return previousRequire(name, true); } // Try the node require function if it exists. if (nodeRequire && typeof name === 'string') { return nodeRequire(name); } var err = new Error("Cannot find module '" + name + "'"); err.code = 'MODULE_NOT_FOUND'; throw err; } localRequire.resolve = resolve; localRequire.cache = {}; var module = (cache[name] = new newRequire.Module(name)); modules[name][0].call( module.exports, localRequire, module, module.exports, globalObject ); } return cache[name].exports; function localRequire(x) { var res = localRequire.resolve(x); return res === false ? {} : newRequire(res); } function resolve(x) { var id = modules[name][1][x]; return id != null ? id : x; } } function Module(moduleName) { this.id = moduleName; this.bundle = newRequire; this.require = nodeRequire; this.exports = {}; } newRequire.isParcelRequire = true; newRequire.Module = Module; newRequire.modules = modules; newRequire.cache = cache; newRequire.parent = previousRequire; newRequire.distDir = distDir; newRequire.publicUrl = publicUrl; newRequire.devServer = devServer; newRequire.i = importMap; newRequire.register = function (id, exports) { modules[id] = [ function (require, module) { module.exports = exports; }, {}, ]; }; // Only insert newRequire.load when it is actually used. // The code in this file is linted against ES5, so dynamic import is not allowed. // INSERT_LOAD_HERE Object.defineProperty(newRequire, 'root', { get: function () { return globalObject[parcelRequireName]; }, }); globalObject[parcelRequireName] = newRequire; for (var i = 0; i < entry.length; i++) { newRequire(entry[i]); } if (mainEntry) { // Expose entry point to Node, AMD or browser globals // Based on https://github.com/ForbesLindesay/umd/blob/master/template.js var mainExports = newRequire(mainEntry); // CommonJS if (typeof exports === 'object' && typeof module !== 'undefined') { module.exports = mainExports; // RequireJS } else if (typeof define === 'function' && define.amd) { define(function () { return mainExports; }); } } })({"3FuxY":[function(require,module,exports,__globalThis) { var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js"); parcelHelpers.defineInteropFlag(exports); var _connection = require("./Connection"); var _eventPool = require("./EventPool"); var _eventPoolDefault = parcelHelpers.interopDefault(_eventPool); var _eventTarget = require("./EventTarget"); var _eventTargetDefault = parcelHelpers.interopDefault(_eventTarget); var _ippressure = require("./IPPressure"); var _peer = require("./Peer"); var _peerDefault = parcelHelpers.interopDefault(_peer); var _room = require("./Room"); var _roomDefault = parcelHelpers.interopDefault(_room); var _wstsprotocol = require("./WSTSProtocol"); var _wstsprotocolDefault = parcelHelpers.interopDefault(_wstsprotocol); class MWSE extends (0, _eventTargetDefault.default) { /*public static compress(message:string, callback:(e:any) => any) { let u : any= []; let C = new Gzip({ level: 9, mem: 12 },(stream,isLast) => { u.push(stream); if(isLast) { callback(u); } }); C.push(new TextEncoder().encode(message), true); }*/ constructor(options){ super(), this.rooms = new Map(), this.pairs = new Map(), this.peers = new Map(), this.writable = 1, this.readable = 1; MWSE.rtc = MWSE; this.server = new (0, _connection.Connection)(this, options); this.WSTSProtocol = new (0, _wstsprotocolDefault.default)(this); this.EventPooling = new (0, _eventPoolDefault.default)(this); this.virtualPressure = new (0, _ippressure.IPPressure)(this); this.server.connect(); this.me = new (0, _peerDefault.default)(this); this.me.scope(()=>{ this.peers.set('me', this.me); this.peers.set(this.me.socketId, this.me); }); this.server.onActive(async ()=>{ this.me.setSocketId('me'); await this.me.metadata(); this.emit('scope'); this.activeScope = true; }); this.server.onPassive(async ()=>{ this.emit('close'); }); this.packMessagingSystem(); } destroy() { this.server.disconnect(); } enableRecaiveData() { this.WSTSProtocol.SendOnly({ type: 'connection/packrecaive', value: 1 }); this.readable = 1; } disableRecaiveData() { this.WSTSProtocol.SendOnly({ type: 'connection/packrecaive', value: 0 }); this.readable = 0; } enableSendData() { this.WSTSProtocol.SendOnly({ type: 'connection/packsending', value: 1 }); this.writable = 1; } disableSendData() { this.WSTSProtocol.SendOnly({ type: 'connection/packsending', value: 0 }); this.writable = 0; } enableNotifyRoomInfo() { this.WSTSProtocol.SendOnly({ type: 'connection/roominfo', value: 1 }); } disableNotifyRoomInfo() { this.WSTSProtocol.SendOnly({ type: 'connection/roominfo', value: 0 }); } async request(peerId, pack) { let { pack: answer } = await this.EventPooling.request({ type: 'request/to', to: peerId, pack }); return answer; } async response(peerId, requestId, pack) { this.WSTSProtocol.SendOnly({ type: 'response/to', to: peerId, pack, id: requestId }); } packMessagingSystem() { this.EventPooling.signal('pack', (payload)=>{ if (this.readable) { let { from, pack } = payload; this.peer(from, true).emit('pack', pack); } }); this.EventPooling.signal('request', (payload)=>{ let { from, pack, id } = payload; let scope = { body: pack, response: (pack)=>{ this.response(from, id, pack); }, peer: this.peer(from, true) }; this.peer(from, true).emit('request', scope); this.peer('me').emit('request', scope); }); this.EventPooling.signal('pack/room', (payload)=>{ if (this.readable) { let { from, pack, sender } = payload; this.room(from).emit('message', pack, this.peer(sender)); } }); this.EventPooling.signal('room/joined', (payload)=>{ let { id, roomid } = payload; let room = this.room(roomid); let peer = this.peer(id, true); room.peers.set(peer.socketId, peer); room.emit('join', peer); }); this.EventPooling.signal('room/info', (payload)=>{ let { roomId, name, value } = payload; this.room(roomId).emit('updateinfo', name, value); }); this.EventPooling.signal('room/ejected', (payload)=>{ let { id, roomid } = payload; let room = this.room(roomid); let peer = this.peer(id, true); room.peers.delete(peer.socketId); room.emit('eject', peer); }); this.EventPooling.signal('room/closed', (payload)=>{ let { roomid } = payload; let room = this.room(roomid); room.peers.clear(); room.emit('close'); this.rooms.delete(roomid); }); this.EventPooling.signal("pair/info", (payload)=>{ let { from, name, value } = payload; let peer = this.peer(from, true); peer.info.info[name] = value; peer.emit("info", name, value); }); this.EventPooling.signal("request/pair", (payload)=>{ let { from, info } = payload; let peer = this.peer(from, true); peer.info.info = info; peer.emit("request/pair", peer); this.peer('me').emit('request/pair', peer); }); this.EventPooling.signal("peer/disconnect", (payload)=>{ let { id } = payload; let peer = this.peer(id, true); peer.emit("disconnect", peer); }); this.EventPooling.signal("accepted/pair", (payload)=>{ let { from, info } = payload; let peer = this.peer(from, true); peer.info.info = info; peer.emit("accepted/pair", peer); this.peer('me').emit('accepted/pairr', peer); }); this.EventPooling.signal("end/pair", (payload)=>{ let { from, info } = payload; let peer = this.peer(from, true); peer.emit("endPair", info); this.peer('me').emit('endPair', from, info); }); } room(options) { if (typeof options == "string") { if (this.rooms.has(options)) return this.rooms.get(options); } let room = new (0, _roomDefault.default)(this); room.setRoomOptions(options); this.emit('room'); return room; } peer(options, isActive = false) { if (typeof options == "string") { if (this.peers.has(options)) return this.peers.get(options); if (this.pairs.has(options)) return this.pairs.get(options); } let peer = new (0, _peerDefault.default)(this); peer.setPeerOptions(options); peer.active = isActive; this.peers.set(peer.socketId, peer); this.emit('peer', peer); return peer; } } exports.default = MWSE; window.MWSE = MWSE; },{"./Connection":"1vUh4","./EventPool":"602qx","./EventTarget":"faGYI","./IPPressure":"l0Hru","./Peer":"imPsO","./Room":"7JoU4","./WSTSProtocol":"i9gBw","@parcel/transformer-js/src/esmodule-helpers.js":"4KC4J"}],"1vUh4":[function(require,module,exports,__globalThis) { var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js"); parcelHelpers.defineInteropFlag(exports); parcelHelpers.export(exports, "Connection", ()=>Connection); class Connection { constructor(mwse, options){ this.autoPair = false; this.connected = false; this.autoReconnect = true; this.autoReconnectTimeout = 3000; this.recaivePackEvent = []; this.activeConnectionEvent = []; this.passiveConnectionEvent = []; if (options.endpoint == "auto") { const RootURL = document.currentScript.src; let scriptPath = new URL(RootURL); let isSecurity = scriptPath.protocol == "https:"; let dumeUrl = scriptPath.pathname.split('/').slice(0, -1).join('/') + '/'; let wsSocket = new URL(dumeUrl, scriptPath); wsSocket.protocol = isSecurity ? 'wss:' : 'ws:'; this.endpoint = new URL(wsSocket.href); } else try { // Testing this.endpoint = new URL(options.endpoint); } catch { throw new Error("endpoint is required"); } if (typeof options.autoReconnect == "boolean") this.autoReconnect = true; else if (options.autoReconnect) { this.autoReconnect = true; this.autoReconnectTimeout = options.autoReconnect.timeout; } } connect() { if (this.autoReconnectTimer) clearTimeout(this.autoReconnectTimer); this.ws = new WebSocket(this.endpoint.href); this.addWSEvents(); } disconnect() { /** * Eğer bilinerek elle kapatıldıysa otomatik tekrar bağlanmasının * önüne geçmek için autoReconnect bayrağını her zaman kapalı tutmak gerekir */ this.autoReconnect = false; this.ws.close(); } addWSEvents() { this.ws.addEventListener("open", ()=>this.eventOpen()); this.ws.addEventListener("close", ()=>this.eventClose()); this.ws.addEventListener("error", ()=>this.eventError()); this.ws.addEventListener("message", ({ data })=>this.eventMessage(data)); } eventOpen() { this.connected = true; for (const callback of this.activeConnectionEvent)callback(void 0); } eventClose() { for (const callback of this.passiveConnectionEvent)callback(void 0); this.connected = false; if (this.autoReconnect) this.autoReconnectTimer = setTimeout(()=>this.connect(), this.autoReconnectTimeout); } eventError() { this.connected = false; } onRecaivePack(func) { this.recaivePackEvent.push(func); } onActive(func) { if (this.connected) func(); else this.activeConnectionEvent.push(func); } onPassive(func) { if (!this.connected) func(); else this.passiveConnectionEvent.push(func); } eventMessage(data) { if (typeof data == "string") { let $data = JSON.parse(data); for (const callback of this.recaivePackEvent)callback($data); } } tranferToServer(data) { if (this.connected) this.ws.send(JSON.stringify(data)); } } },{"@parcel/transformer-js/src/esmodule-helpers.js":"4KC4J"}],"4KC4J":[function(require,module,exports,__globalThis) { exports.interopDefault = function(a) { return a && a.__esModule ? a : { default: a }; }; exports.defineInteropFlag = function(a) { Object.defineProperty(a, '__esModule', { value: true }); }; exports.exportAll = function(source, dest) { Object.keys(source).forEach(function(key) { if (key === 'default' || key === '__esModule' || Object.prototype.hasOwnProperty.call(dest, key)) return; Object.defineProperty(dest, key, { enumerable: true, get: function() { return source[key]; } }); }); return dest; }; exports.export = function(dest, destName, get) { Object.defineProperty(dest, destName, { enumerable: true, get: get }); }; },{}],"602qx":[function(require,module,exports,__globalThis) { var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js"); parcelHelpers.defineInteropFlag(exports); class EventPool { constructor(wsts){ this.events = new Map(); this.signals = new Map(); this.requests = new Map(); this.count = 0; this.wsts = wsts; } request(msg) { return new Promise((ok, rej)=>{ let id = ++this.count; this.events.set(id, [ (data)=>{ ok(data); }, (data)=>{ rej(data); } ]); this.wsts.WSTSProtocol.SendRequest(msg, id); }); } stream(msg, callback) { let id = ++this.count; this.wsts.WSTSProtocol.StartStream(msg, id); this.events.set(id, [ (data)=>{ callback(data); }, ()=>{} ]); } signal(event, callback) { let T = this.signals.get(event); if (!T) this.signals.set(event, [ callback ]); else T.push(callback); } } exports.default = EventPool; },{"@parcel/transformer-js/src/esmodule-helpers.js":"4KC4J"}],"faGYI":[function(require,module,exports,__globalThis) { var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js"); parcelHelpers.defineInteropFlag(exports); class EventTarget { emit(eventName, ...args) { if (this.events[eventName]) for (const callback of this.events[eventName])callback(...args); } on(eventName, callback) { if (this.events[eventName]) this.events[eventName].push(callback); else this.events[eventName] = [ callback ]; } scope(f) { if (this.activeScope) f(); else this.on('scope', f); } constructor(){ this.events = {}; this.activeScope = false; } } exports.default = EventTarget; },{"@parcel/transformer-js/src/esmodule-helpers.js":"4KC4J"}],"l0Hru":[function(require,module,exports,__globalThis) { var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js"); parcelHelpers.defineInteropFlag(exports); parcelHelpers.export(exports, "IPPressure", ()=>IPPressure); class IPPressure { constructor(mwse){ this.mwse = mwse; } async allocAPIPAddress() { let { status, ip } = await this.mwse.EventPooling.request({ type: 'alloc/APIPAddress' }); if (status == 'success') { this.APIPAddress = ip; return ip; } else throw new Error("Error Allocated Access Point IP Address"); } async allocAPNumber() { let { status, number } = await this.mwse.EventPooling.request({ type: 'alloc/APNumber' }); if (status == 'success') { this.APNumber = number; return number; } else throw new Error("Error Allocated Access Point Number"); } async allocAPShortCode() { let { status, code } = await this.mwse.EventPooling.request({ type: 'alloc/APShortCode' }); if (status == 'success') { this.APShortCode = code; return code; } else throw new Error("Error Allocated Access Point Short Code"); } async reallocAPIPAddress() { let { status, ip } = await this.mwse.EventPooling.request({ type: 'realloc/APIPAddress' }); if (status == 'success') { this.APIPAddress = ip; return ip; } else throw new Error("Error Reallocated Access Point IP Address"); } async reallocAPNumber() { let { status, number } = await this.mwse.EventPooling.request({ type: 'realloc/APNumber' }); if (status == 'success') { this.APNumber = number; return number; } else throw new Error("Error Reallocated Access Point Number"); } async reallocAPShortCode() { let { status, code } = await this.mwse.EventPooling.request({ type: 'realloc/APShortCode' }); if (status == 'success') { this.APShortCode = code; return code; } else throw new Error("Error Reallocated Access Point Short Code"); } async releaseAPIPAddress() { let { status } = await this.mwse.EventPooling.request({ type: 'release/APIPAddress' }); if (status == 'success') this.APIPAddress = undefined; else throw new Error("Error release Access Point IP Address"); } async releaseAPNumber() { let { status } = await this.mwse.EventPooling.request({ type: 'release/APNumber' }); if (status == 'success') this.APNumber = undefined; else throw new Error("Error release Access Point Number"); } async releaseAPShortCode() { let { status } = await this.mwse.EventPooling.request({ type: 'release/APShortCode' }); if (status == 'success') this.APShortCode = undefined; else throw new Error("Error release Access Point Short Code"); } async queryAPIPAddress(ip) { let { status, socket } = await this.mwse.EventPooling.request({ type: 'whois/APIPAddress', whois: ip }); if (status == "success") return socket; else return null; } async queryAPNumber(number) { let { status, socket } = await this.mwse.EventPooling.request({ type: 'whois/APNumber', whois: number }); if (status == "success") return socket; else return null; } async queryAPShortCode(code) { let { status, socket } = await this.mwse.EventPooling.request({ type: 'whois/APShortCode', whois: code }); if (status == "success") return socket; else return null; } } },{"@parcel/transformer-js/src/esmodule-helpers.js":"4KC4J"}],"imPsO":[function(require,module,exports,__globalThis) { var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js"); parcelHelpers.defineInteropFlag(exports); var _eventTarget = require("./EventTarget"); var _eventTargetDefault = parcelHelpers.interopDefault(_eventTarget); var _peerInfo = require("./PeerInfo"); var _webRTC = require("./WebRTC"); var _webRTCDefault = parcelHelpers.interopDefault(_webRTC); var IMessageSymbase = /*#__PURE__*/ function(IMessageSymbase) { IMessageSymbase[IMessageSymbase["PayloadMessagePack"] = -12873.54] = "PayloadMessagePack"; IMessageSymbase[IMessageSymbase["PayloadRTCBasePack"] = -12884.54] = "PayloadRTCBasePack"; return IMessageSymbase; }(IMessageSymbase || {}); class Peer extends (0, _eventTargetDefault.default) { constructor(wsts){ super(), this.options = {}, this.selfSocket = false, this.active = false, this.peerConnection = false, this.primaryChannel = "datachannel"; this.mwse = wsts; this.rtc = this.createRTC(); this.info = new (0, _peerInfo.PeerInfo)(this); this.on('pack', (data)=>{ if (data.type == ':rtcpack:') return this.rtc.emit("input", data.payload); this.emit("message", data); }); } createRTC(rtcConfig, rtcServers) { this.rtc = new (0, _webRTCDefault.default)(rtcConfig, rtcServers); this.rtc.peer = this; this.rtc.on("connected", ()=>{ this.peerConnection = true; }); this.rtc.on('disconnected', ()=>{ this.peerConnection = false; }); this.rtc.on("output", (payload)=>{ this.send({ type: ':rtcpack:', payload: payload }); }); this.rtc.on("message", (payload)=>{ this.emit("pack", payload); }); return this.rtc; } setPeerOptions(options) { if (typeof options == "string") this.setSocketId(options); else this.options = options; } setSocketId(uuid) { this.socketId = uuid; } async metadata() { if (this.socketId == 'me') { let result = await this.mwse.EventPooling.request({ type: 'my/socketid' }); this.selfSocket = true; this.active ||= true; this.socketId = result; this.emit('scope'); this.activeScope = true; return result; } } async request(pack) { if (this.active) return await this.mwse.request(this.socketId, pack); } equalTo(peer) { return this.socketId == peer.socketId; } async isReachable() { return await this.mwse.EventPooling.request({ type: 'is/reachable', to: this.socketId }); } async enablePairAuth() { await this.mwse.EventPooling.request({ type: 'auth/pair-system', value: 'everybody' }); } async disablePairAuth() { await this.mwse.EventPooling.request({ type: 'auth/pair-system', value: 'disable' }); } async enablePairInfo() { await this.mwse.EventPooling.request({ type: 'connection/pairinfo', value: true }); } async disablePairInfo() { await this.mwse.EventPooling.request({ type: 'connection/pairinfo', value: false }); } async requestPair() { let { message, status } = await this.mwse.EventPooling.request({ type: 'request/pair', to: this.socketId }); if (message == "ALREADY-PAIRED" || message == "ALREADY-REQUESTED") console.warn("Already paired or pair requested"); if (status == "fail") { console.error("Request Pair Error", status, message); return false; } return true; } async endPair() { await this.mwse.EventPooling.request({ type: 'end/pair', to: this.socketId }); this.forget(); } async acceptPair() { let { message, status } = await this.mwse.EventPooling.request({ type: 'accept/pair', to: this.socketId }); if (status == "fail") { console.error("Pair Error", status, message); return false; } return true; } async rejectPair() { let { message, status } = await this.mwse.EventPooling.request({ type: 'reject/pair', to: this.socketId }); if (status == "fail") { console.error("Pair Error", status, message); return false; } return true; } async getPairedList() { let { value } = await this.mwse.EventPooling.request({ type: 'pair/list', to: this.socketId }); return value; } async send(pack) { let isOpenedP2P = this.peerConnection && this.rtc?.active; let isOpenedServer = this.mwse.server.connected; let sendChannel; if (isOpenedP2P && isOpenedServer) { if (this.primaryChannel == "websocket") sendChannel = "websocket"; else sendChannel = "datachannel"; } else if (isOpenedServer) sendChannel = "websocket"; else sendChannel = "datachannel"; if (sendChannel == "websocket") { if (!this.mwse.writable) return console.warn("Socket is not writable"); await this.mwse.EventPooling.request({ type: 'pack/to', pack, to: this.socketId }); } else { if (pack.type != ':rtcpack:') this.rtc?.sendMessage(pack); else return console.warn("Socket is not writable"); } } async forget() { this.mwse.peers.delete(this.socketId); this.mwse.pairs.delete(this.socketId); } } exports.default = Peer; },{"./EventTarget":"faGYI","./PeerInfo":"4gWZ7","./WebRTC":"buLge","@parcel/transformer-js/src/esmodule-helpers.js":"4KC4J"}],"4gWZ7":[function(require,module,exports,__globalThis) { var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js"); parcelHelpers.defineInteropFlag(exports); parcelHelpers.export(exports, "PeerInfo", ()=>PeerInfo); class PeerInfo { constructor(mwse){ this.info = {}; this.peer = mwse; } async fetch(name) { if (name) { let rinfo = await this.peer.mwse.EventPooling.request({ type: "peer/info", peer: this.peer.socketId, name }); if (rinfo.status == "success") this.info = rinfo.info; else console.warn(rinfo.message); } else { let rinfo = await this.peer.mwse.EventPooling.request({ type: "peer/info", peer: this.peer.socketId }); if (rinfo.status == "success") this.info = rinfo.info; else console.warn(rinfo.message); } return this.info; } set(name, value) { this.info[name] = value; this.peer.mwse.WSTSProtocol.SendOnly({ type: "auth/info", name, value }); } get(name) { return name ? this.info[name] : this.info; } } },{"@parcel/transformer-js/src/esmodule-helpers.js":"4KC4J"}],"buLge":[function(require,module,exports,__globalThis) { var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js"); parcelHelpers.defineInteropFlag(exports); var _p2PfileSender = require("./P2PFileSender"); var _p2PfileSenderDefault = parcelHelpers.interopDefault(_p2PfileSender); class WebRTC { static{ this.channels = new Map(); } static{ this.requireGC = false; } static{ this.defaultRTCConfig = { iceCandidatePoolSize: 0, iceTransportPolicy: "all", rtcpMuxPolicy: "require" }; } isPolite() { let myId = this.peer?.mwse.peer('me').socketId; let peerId = this.peer?.socketId; return myId < peerId; } static{ this.defaultICEServers = [ { urls: "stun:stun.l.google.com:19302" }, { urls: "stun:stun1.l.google.com:19302" }, { urls: "stun:stun2.l.google.com:19302" }, { urls: "stun:stun3.l.google.com:19302" }, { urls: "stun:stun4.l.google.com:19302" } ]; } constructor(rtcConfig, rtcServers){ this.active = false; this.connectionStatus = "new"; this.iceStatus = "new"; this.gatheringStatus = "new"; this.signalingStatus = ""; this.recaivingStream = new Map(); this.sendingStream = new Map(); this.events = {}; this.makingOffer = false; this.ignoreOffer = false; this.isSettingRemoteAnswerPending = false; this.candicatePack = []; let config = {}; if (rtcConfig) Object.assign(config, WebRTC.defaultRTCConfig, rtcConfig); else Object.assign(config, WebRTC.defaultRTCConfig); config.iceServers = rtcServers || WebRTC.defaultICEServers; this.rtc = new RTCPeerConnection(config); this.rtc.addEventListener("connectionstatechange", ()=>{ this.eventConnectionState(); }); this.rtc.addEventListener("icecandidate", (...args)=>{ this.eventIcecandidate(...args); }); this.rtc.addEventListener("iceconnectionstatechange", ()=>{ this.eventICEConnectionState(); }); this.rtc.addEventListener("icegatheringstatechange", ()=>{ this.eventICEGatherinState(); }); this.rtc.addEventListener("negotiationneeded", ()=>{ this.eventNogationNeeded(); }); this.rtc.addEventListener("signalingstatechange", ()=>{ this.eventSignalingState(); }); this.rtc.addEventListener("track", (...args)=>{ this.eventTrack(...args); }); this.rtc.addEventListener("datachannel", (...args)=>{ this.eventDatachannel(...args); }); this.on('input', async (data)=>{ switch(data.type){ case "icecandidate": try { if (this.rtc.remoteDescription) await this.rtc.addIceCandidate(new RTCIceCandidate(data.value)); else this.candicatePack.push(new RTCIceCandidate(data.value)); } catch (error) { debugger; } finally{ console.log("ICE Canbet"); } break; case "offer": { let readyForOffer = !this.makingOffer && (this.rtc.signalingState == "stable" || this.isSettingRemoteAnswerPending); const offerCollision = !readyForOffer; this.ignoreOffer = !this.isPolite() && offerCollision; if (this.ignoreOffer) return; this.isSettingRemoteAnswerPending = false; await this.rtc.setRemoteDescription(new RTCSessionDescription(data.value)); this.isSettingRemoteAnswerPending = false; for (const candidate of this.candicatePack)await this.rtc.addIceCandidate(candidate); let answer = await this.rtc.createAnswer({ offerToReceiveAudio: true, offerToReceiveVideo: true }); await this.rtc.setLocalDescription(answer); this.send({ type: 'answer', value: answer }); break; } case "answer": await this.rtc.setRemoteDescription(new RTCSessionDescription(data.value)); for (const candidate of this.candicatePack)await this.rtc.addIceCandidate(candidate); break; case "streamInfo": { let { id, value } = data; let streamInfo = this.recaivingStream.get(id); if (!streamInfo) this.recaivingStream.set(id, value); else this.recaivingStream.set(id, { ...streamInfo, ...value }); this.send({ type: 'streamAccept', id }); break; } case "streamRemoved": { let { id } = data; this.emit('stream:stopped', this.recaivingStream.get(id)); this.recaivingStream.delete(id); break; } case "streamAccept": { let { id } = data; let sendingStream = this.sendingStream.get(id); let senders = []; if (sendingStream && sendingStream.stream) { for (const track of sendingStream.stream.getTracks())senders.push(this.rtc.addTrack(track, sendingStream.stream)); sendingStream.senders = senders; } this.emit('stream:accepted', sendingStream); break; } case "message": this.emit('message', data.payload); break; } }); } addEventListener(event, callback) { (this.events[event] || (this.events[event] = [])).push(callback); } on(event, callback) { this.addEventListener(event, callback); } async dispatch(event, ...args) { if (this.events[event]) for (const callback of this.events[event])await callback(...args); } async emit(event, ...args) { await this.dispatch(event, ...args); } connect() { if (!this.channel) this.createDefaultDataChannel(); } sendMessage(data) { if (data.type == ':rtcpack:') throw "WebRTC Kanal\u0131nda S\u0131zma"; this.send({ type: 'message', payload: data }); } createDefaultDataChannel() { let dt = this.rtc.createDataChannel(':default:', { ordered: true }); dt.addEventListener("open", ()=>{ this.channel = dt; WebRTC.channels.set(this.id, this); this.active = true; }); dt.addEventListener("message", ({ data })=>{ let pack = JSON.parse(data); this.emit('input', pack); }); dt.addEventListener("close", ()=>{ this.channel = undefined; this.active = false; }); } destroy() { this.active = false; if (this.channel) { this.channel.close(); this.channel = undefined; } if (this.rtc) this.rtc.close(); this.emit('disconnected'); WebRTC.channels.delete(this.id); } eventDatachannel(event) { if (event.channel.label == ':default:') { WebRTC.channels.set(this.id, this); this.channel = event.channel; this.active = true; event.channel.addEventListener("message", ({ data })=>{ let pack = JSON.parse(data); this.emit('input', pack); }); event.channel.addEventListener("close", ()=>{ this.channel = undefined; WebRTC.channels.delete(this.id); WebRTC.requireGC = true; this.active = false; }); } else this.emit('datachannel', event.channel); } send(data) { if (this.channel?.readyState == "open") this.channel.send(JSON.stringify(data)); else this.emit('output', data); } eventConnectionState() { this.connectionStatus = this.rtc.connectionState; if (this.connectionStatus == 'connected') { if (this.active == false) this.emit('connected'); } if (this.connectionStatus == 'failed') this.rtc.restartIce(); if (this.connectionStatus == "closed") { if (this.active) this.destroy(); } } eventIcecandidate(event) { if (event.candidate) this.send({ type: 'icecandidate', value: event.candidate }); } eventICEConnectionState() { this.iceStatus = this.rtc.iceConnectionState; } eventICEGatherinState() { this.gatheringStatus = this.rtc.iceGatheringState; } async eventNogationNeeded() { try { this.makingOffer = true; let offer = await this.rtc.createOffer({ iceRestart: true, offerToReceiveAudio: true, offerToReceiveVideo: true }); await this.rtc.setLocalDescription(offer); this.send({ type: 'offer', value: offer }); } catch (error) { console.error(`Nogation Error:`, error); } finally{ this.makingOffer = false; } } eventSignalingState() { this.signalingStatus = this.rtc.signalingState; } eventTrack(event) { let rtpRecaiver = event.receiver; if (event.streams.length) for (const stream of event.streams){ let streamInfo = this.recaivingStream.get(stream.id); (streamInfo.recaivers || (streamInfo.recaivers = [])).push(rtpRecaiver); if (this.recaivingStream.get(stream.id).stream == null) { streamInfo.stream = stream; this.emit('stream:added', this.recaivingStream.get(stream.id)); } else streamInfo.stream = stream; } } sendStream(stream, name, info) { this.send({ type: 'streamInfo', id: stream.id, value: { ...info, name: name } }); this.sendingStream.set(stream.id, { ...info, id: stream.id, name: name, stream }); } stopStream(_stream) { if (this.connectionStatus != 'connected') return; if (this.sendingStream.has(_stream.id)) { let { stream } = this.sendingStream.get(_stream.id); for (const track of stream.getTracks()){ for (const RTCPSender of this.rtc.getSenders())if (RTCPSender.track?.id == track.id) this.rtc.removeTrack(RTCPSender); } this.send({ type: 'streamRemoved', id: stream.id }); this.sendingStream.delete(_stream.id); } } stopAllStreams() { if (this.connectionStatus != 'connected') return; for (const [, { stream }] of this.sendingStream){ if (stream == undefined) continue; for (const track of stream.getTracks()){ for (const RTCPSender of this.rtc.getSenders())if (RTCPSender.track?.id == track.id) this.rtc.removeTrack(RTCPSender); } this.send({ type: 'streamRemoved', id: stream.id }); } this.sendingStream.clear(); } async SendFile(file, meta) { if (!this.peer) throw new Error("Peer is not ready"); this.FileTransportChannel = new (0, _p2PfileSenderDefault.default)(this, this.peer); await this.FileTransportChannel.SendFile(file, meta); } async RecaiveFile(chnlCount, filemeta, totalSize) { if (!this.peer) throw new Error("Peer is not ready"); this.FileTransportChannel = new (0, _p2PfileSenderDefault.default)(this, this.peer); return await new Promise((recaivedFile)=>{ if (this.FileTransportChannel) this.FileTransportChannel.RecaiveFile(this.rtc, filemeta, chnlCount, totalSize, (file)=>{ recaivedFile(file); }); }); } } exports.default = WebRTC; WebRTC.requireGC = false; setInterval(()=>{ if (WebRTC.requireGC == false) return; let img = document.createElement("img"); img.src = window.URL.createObjectURL(new Blob([ new ArrayBuffer(5e+7) ])); img.onerror = function() { window.URL.revokeObjectURL(this.src); }; WebRTC.requireGC = false; }, 3000); },{"./P2PFileSender":"ga16E","@parcel/transformer-js/src/esmodule-helpers.js":"4KC4J"}],"ga16E":[function(require,module,exports,__globalThis) { var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js"); parcelHelpers.defineInteropFlag(exports); class P2PFileSender { constructor(webrtc, peer){ this.totalSize = 0; this.isReady = false; this.isStarted = false; this.isSending = false; this.isRecaiving = false; this.processedSize = 0; this.bufferSizePerChannel = 10e6; this.bufferSizePerPack = 10e3; this.safeBufferSizePerPack = 9999; this.webrtc = webrtc; this.rtc = webrtc.rtc; this.peer = peer; } async RecaiveFile(_rtc, fileMetadata, channelCount, _totalSize, onEnded) { //let totals = {}; // let index = 0; /*setChannelStatus(Array.from({length:channelCount}).map((e, index) => { return { name: `${index+1}. Kanal`, current: 0, currentTotal: 0, total: 0 } }));*/ let parts = []; this.webrtc.on('datachannel', (datachannel)=>{ //let channelIndex = index++; let current = 0; let totalSize = 0; let currentPart = 0; let bufferAmount = []; datachannel.onmessage = function({ data }) { if (totalSize == 0) { let { size, part } = JSON.parse(data); totalSize = size; currentPart = part; /*updateChannelStatus(channelIndex, n => { return { ...n, total: totalSize, current: 0 } });*/ datachannel.send("READY"); } else { current += data.byteLength; bufferAmount.push(data); /*updateChannelStatus(channelIndex, n => { return { ...n, current: data.byteLength + n.current, currentTotal: data.byteLength + n.currentTotal, } }); setProcessedSize(n => n + data.byteLength);*/ if (current == totalSize) { parts[currentPart] = new Blob(bufferAmount); bufferAmount = []; //totals[datachannel.label] += totalSize; totalSize = 0; currentPart = 0; current = 0; datachannel.send("TOTAL_RECAIVED"); } } }; datachannel.onclose = ()=>{ channelCount--; if (channelCount == 0) { let file = new File(parts, fileMetadata.name, { type: fileMetadata.type, lastModified: +new Date }); onEnded(file); } }; }); } async SendFile(file, metadata) { this.isSending = true; this.isStarted = true; let buffer = await file.arrayBuffer(); let partCount = Math.ceil(buffer.byteLength / 10e6); let channelCount = Math.min(5, partCount); if (this.webrtc.iceStatus != "connected") throw new Error("WebRTC is a not ready"); this.peer.send({ type: 'file', name: file.name, size: file.size, mimetype: file.type, partCount, channelCount, metadata: metadata }); let channels = []; for(let channelIndex = 0; channelIndex < channelCount; channelIndex++){ let channel = this.rtc.createDataChannel("\\?\\file_" + channelIndex); channel.binaryType = "arraybuffer"; await new Promise((ok)=>{ channel.onopen = ()=>{ ok(void 0); }; }); channels.push(channel); } let currentPart = 0; let next = ()=>{ if (currentPart < partCount) { let bufferPart = buffer.slice(currentPart * 10e6, currentPart * 10e6 + 10e6); currentPart++; return [ bufferPart, currentPart - 1 ]; } return [ false, 0 ]; }; let spyChannelIndex = channels.length; await new Promise((ok)=>{ for(let channelIndex = 0; channelIndex < channels.length; channelIndex++)this.sendPartition(channels[channelIndex], next, channelIndex, ()=>{ spyChannelIndex--; if (spyChannelIndex == 0) { this.isSending = false; this.isStarted = false; ok(undefined); } }); }); } sendPartition(channel, nextblob10mb, _channelIndex, onEnded) { let [currentBuffer, currentPartition] = nextblob10mb(); let currentPart = 0; let next = ()=>{ if (!(currentBuffer instanceof ArrayBuffer)) return; let bufferPart = currentBuffer.slice(currentPart * 16e3, currentPart * 16e3 + 16e3); currentPart++; if (bufferPart.byteLength != 0) /* updateChannelStatus(channelIndex, n => { return { ...n, current: bufferPart.byteLength + n.current, currentTotal: bufferPart.byteLength + n.currentTotal } }); setProcessedSize(n => n + bufferPart.byteLength); */ return bufferPart; }; channel.addEventListener("message", ({ data })=>{ if (data == "READY") this.sendFileChannel(channel, next); if (data == "TOTAL_RECAIVED") { [currentBuffer, currentPartition] = nextblob10mb(); currentPart = 0; if (currentBuffer != false) /*updateChannelStatus(channelIndex, n => { return { ...n, total: currentBuffer.byteLength, current: 0, } });*/ channel.send(JSON.stringify({ size: currentBuffer.byteLength, part: currentPartition })); else { channel.close(); onEnded(); } } }); channel.send(JSON.stringify({ size: currentBuffer.byteLength, part: currentPartition })); } sendFileChannel(channel, getNextBlob) { channel.addEventListener("bufferedamountlow", function() { let buffer = getNextBlob(); if (buffer) channel.send(buffer); }); channel.bufferedAmountLowThreshold = 15999; let c = getNextBlob(); c && channel.send(c); } } exports.default = P2PFileSender; },{"@parcel/transformer-js/src/esmodule-helpers.js":"4KC4J"}],"7JoU4":[function(require,module,exports,__globalThis) { var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js"); parcelHelpers.defineInteropFlag(exports); var _eventTarget = require("./EventTarget"); var _eventTargetDefault = parcelHelpers.interopDefault(_eventTarget); var _roomInfo = require("./RoomInfo"); class Room extends (0, _eventTargetDefault.default) { constructor(wsts){ super(), this.peers = new Map(); this.mwse = wsts; this.info = new (0, _roomInfo.RoomInfo)(this); } setRoomOptions(options) { if (typeof options == "string") this.roomId = options; else { let defaultOptions = { joinType: "free", ifexistsJoin: true, accessType: "private", notifyActionInvite: true, notifyActionJoined: true, notifyActionEjected: true, autoFetchInfo: true }; Object.assign(defaultOptions, options); this.config = defaultOptions; } } setRoomId(uuid) { this.roomId = uuid; } async createRoom(roomOptions) { let config = this.config || roomOptions; let result = await this.mwse.EventPooling.request({ type: 'create-room', ...config }); if (result.status == 'fail') { if (result.message == "ALREADY-EXISTS" && this.config.ifexistsJoin) return this.join(); throw new Error(result.message || result.messages); } else { this.options = { ...this.config, ...result.room }; this.roomId = result.room.id; this.mwse.rooms.set(this.roomId, this); } } async join() { let result = await this.mwse.EventPooling.request({ type: 'joinroom', name: this.config.name, credential: this.config.credential, autoFetchInfo: this.config.autoFetchInfo || false }); if (result.status == 'fail') throw new Error(result.message); else { this.options = { ...this.config, ...result.room }; if (result.info) this.info.info = result.info; this.roomId = result.room.id; this.mwse.rooms.set(this.roomId, this); } } async eject() { let { type } = await this.mwse.EventPooling.request({ type: 'ejectroom', roomId: this.roomId }); this.peers.clear(); if (type == 'success') this.mwse.rooms.delete(this.roomId); } async send(pack, wom = false, handshake = false) { if (!this.mwse.writable) return console.warn("Socket is not writable"); if (handshake) { let { type } = await this.mwse.EventPooling.request({ type: 'pack/room', pack, to: this.roomId, wom, handshake }); if (type == "fail") throw new Error("Cant send message to room"); } else await this.mwse.EventPooling.request({ type: 'pack/room', pack, to: this.roomId, wom, handshake }); } async fetchPeers(filter, onlyNumber = false) { if (onlyNumber) { let { count } = await this.mwse.EventPooling.request({ type: 'room/peer-count', roomId: this.roomId, filter: filter || {} }); return count; } else { let { status, peers } = await this.mwse.EventPooling.request({ type: 'room-peers', roomId: this.roomId, filter: filter || {} }); let cup = []; if (status == 'fail') throw new Error("Cant using peers on room"); else if (status == 'success') for (const peerid of peers){ let peer = this.mwse.peer(peerid, true); cup.push(peer); this.peers.set(peerid, peer); } return cup; } } } exports.default = Room; },{"./EventTarget":"faGYI","./RoomInfo":"5x1BB","@parcel/transformer-js/src/esmodule-helpers.js":"4KC4J"}],"5x1BB":[function(require,module,exports,__globalThis) { var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js"); parcelHelpers.defineInteropFlag(exports); parcelHelpers.export(exports, "RoomInfo", ()=>RoomInfo); class RoomInfo { constructor(room){ this.info = {}; this.room = room; this.room.on('updateinfo', (name, value)=>{ this.info[name] = value; }); } async fetch(name) { if (name) { let rinfo = await this.room.mwse.EventPooling.request({ type: "room/getinfo", roomId: this.room.roomId, name }); if (rinfo.status == "success") this.info = rinfo.value; else console.warn(rinfo.message); } else { let rinfo = await this.room.mwse.EventPooling.request({ type: "room/info", roomId: this.room.roomId }); if (rinfo.status == "success") this.info = rinfo.value; else console.warn(rinfo.message); } return this.info; } set(name, value) { this.info[name] = value; this.room.mwse.WSTSProtocol.SendOnly({ type: "room/setinfo", roomId: this.room.roomId, name, value }); } get(name) { return name ? this.info[name] : this.info; } } },{"@parcel/transformer-js/src/esmodule-helpers.js":"4KC4J"}],"i9gBw":[function(require,module,exports,__globalThis) { var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js"); parcelHelpers.defineInteropFlag(exports); class WSTSProtocol { constructor(wsts){ this.mwse = wsts; this.addListener(); } addListener() { this.mwse.server?.onRecaivePack((pack)=>{ this.PackAnalyze(pack); }); } SendRaw(pack) { this.mwse.server.tranferToServer(pack); } SendOnly(pack) { this.mwse.server.tranferToServer([ pack, 'R' ]); } SendRequest(pack, id) { this.mwse.server.tranferToServer([ pack, id, 'R' ]); } StartStream(pack, id) { this.mwse.server.tranferToServer([ pack, id, 'S' ]); } PackAnalyze(data) { let [payload, id, action] = data; if (typeof id === 'number') { let callback = this.mwse.EventPooling.events.get(id); if (callback) { callback[0](payload, action); switch(action){ case 'E': this.mwse.EventPooling.events.delete(id); break; case 'S': default: break; } } else console.warn("Missing event sended from server"); } else { let signals = this.mwse.EventPooling.signals.get(id); if (signals) for (const callback of signals)callback(payload); else console.warn("Missing event sended from server"); } } } exports.default = WSTSProtocol; },{"@parcel/transformer-js/src/esmodule-helpers.js":"4KC4J"}]},["3FuxY"], "3FuxY", "parcelRequiref9d4", {}) //# sourceMappingURL=index.js.map