UNPKG

clusterws-client-js

Version:

JavaScript Client for ClusterWS - lightweight, fast and powerful framework for building scalable WebSockets applications in Node.js.

160 lines (151 loc) 7.34 kB
"use strict"; function logError(t) { return console.log(t); } function uint8ArrayToString(t) { for (var e = "", n = 65535, o = t.length, s = 0; s < o; s += n) s + n > o && (n = o - s), e += String.fromCharCode.apply(null, t.subarray(s, s + n)); return e; } function stringToArrayBuffer(t) { for (var e = t.length, n = new Uint8Array(e), o = 0; o < e; o++) n[o] = t.charCodeAt(o); return n.buffer; } var Channel = function() { function t(t, e) { this.name = e, this.socket = t, this.subscribe(); } return t.prototype.watch = function(t) { return "[object Function]" !== {}.toString.call(t) ? logError("Listener must be a function") : (this.listener = t, this); }, t.prototype.publish = function(t) { return this.socket.send(this.name, t, "publish"), this; }, t.prototype.unsubscribe = function() { this.socket.send("unsubscribe", this.name, "system"), this.socket.channels[this.name] = null; }, t.prototype.onMessage = function(t) { this.listener && this.listener.call(null, t); }, t.prototype.subscribe = function() { this.socket.send("subscribe", this.name, "system"); }, t; }(), EventEmitter = function() { function t() { this.events = {}; } return t.prototype.on = function(t, e) { if ("[object Function]" !== {}.toString.call(e)) return logError("Listener must be a function"); this.events[t] = e; }, t.prototype.off = function(t) { delete this.events[t]; }, t.prototype.emit = function(t) { for (var e, n = [], o = 1; o < arguments.length; o++) n[o - 1] = arguments[o]; this.events[t] && (e = this.events)[t].apply(e, n); }, t.prototype.removeAllEvents = function() { this.events = {}; }, t; }(); function decode(t, e) { var n = t.options.encodeDecodeEngine ? t.options.encodeDecodeEngine.decode(e["#"][2]) : e["#"][2], o = { e: function() { return t.events.emit(e["#"][1], n); }, p: function() { return t.channels[e["#"][1]] && t.channels[e["#"][1]].onMessage(n); }, s: { c: function() { t.useBinary = n.binary, t.resetPing(n.ping), t.events.emit("connect"); } } }; return "s" === e["#"][0] ? o[e["#"][0]][e["#"][1]] && o[e["#"][0]][e["#"][1]]() : o[e["#"][0]] && o[e["#"][0]](); } function encode(t, e, n) { var o = { emit: { "#": [ "e", t, e ] }, publish: { "#": [ "p", t, e ] }, system: { subscribe: { "#": [ "s", "s", e ] }, unsubscribe: { "#": [ "s", "u", e ] } } }; return JSON.stringify("system" === n ? o[n][t] : o[n]); } var Socket = window.MozWebSocket || window.WebSocket, ClusterWS = function() { function t(t) { return this.events = new EventEmitter(), this.channels = {}, this.pong = stringToArrayBuffer("A"), this.reconnectionAttempted = 0, this.hasStartedConnection = !1, this.options = { url: t.url, autoReconnect: t.autoReconnect || !1, autoReconnectOptions: t.autoReconnectOptions ? { attempts: t.autoReconnectOptions.attempts || 0, minInterval: t.autoReconnectOptions.minInterval || 1e3, maxInterval: t.autoReconnectOptions.maxInterval || 5e3 } : { attempts: 0, minInterval: 1e3, maxInterval: 5e3 }, encodeDecodeEngine: t.encodeDecodeEngine || !1, autoConnect: !1 !== t.autoConnect, autoResubscribe: !1 !== t.autoResubscribe }, this.options.url ? this.options.autoReconnectOptions.minInterval > this.options.autoReconnectOptions.maxInterval ? logError("minInterval option can not be more than maxInterval option") : void (this.options.autoConnect && this.create()) : logError("Url must be provided and it must be a string"); } return t.prototype.on = function(t, e) { this.events.on(t, e); }, t.prototype.off = function(t) { this.events.off(t); }, t.prototype.getState = function() { return this.websocket ? this.websocket.readyState : 0; }, t.prototype.resetPing = function(t) { var e = this; t && (this.pingInterval = t), clearTimeout(this.pingTimeout), this.pingTimeout = setTimeout(function() { return e.disconnect(4001, "Did not get pings"); }, 2 * this.pingInterval + 100); }, t.prototype.disconnect = function(t, e) { this.websocket.close(t || 1e3, e); }, t.prototype.send = function(t, e, n) { void 0 === n && (n = "emit"), e = this.options.encodeDecodeEngine ? this.options.encodeDecodeEngine.encode(e) : e, this.websocket.send(this.useBinary ? stringToArrayBuffer(encode(t, e, n)) : encode(t, e, n)); }, t.prototype.subscribe = function(t) { return this.channels[t] ? this.channels[t] : this.channels[t] = new Channel(this, t); }, t.prototype.getChannelByName = function(t) { return this.channels[t]; }, t.prototype.connect = function() { this.hasStartedConnection ? logError("The socket has already been created") : this.create(); }, t.prototype.create = function() { var t = this; this.hasStartedConnection = !0, this.websocket = new Socket(this.options.url), this.websocket.binaryType = "arraybuffer", this.websocket.onopen = function() { if (t.reconnectionAttempted = 0, t.options.autoResubscribe) for (var e = 0, n = Object.keys(t.channels), o = n.length; e < o; e++) t.channels.hasOwnProperty(n[e]) && t.channels[n[e]].subscribe(); }, this.websocket.onclose = function(e) { if (t.options.autoResubscribe || (t.channels = {}), clearTimeout(t.pingTimeout), t.events.emit("disconnect", e.code, e.reason), t.options.autoReconnect && 1e3 !== e.code && (0 === t.options.autoReconnectOptions.attempts || t.reconnectionAttempted < t.options.autoReconnectOptions.attempts)) t.websocket.readyState === t.websocket.CLOSED ? (t.reconnectionAttempted++, t.websocket = void 0, setTimeout(function() { return t.create(); }, Math.floor(Math.random() * (t.options.autoReconnectOptions.maxInterval - t.options.autoReconnectOptions.minInterval + 1)))) : console.log("Some thing went wrong with close event please contact developer"); else { t.events.removeAllEvents(); for (var n = 0, o = Object.keys(t), s = o.length; n < s; n++) t[o[n]] = null; } }, this.websocket.onmessage = function(e) { var n; if (57 === (n = e.data ? "string" != typeof e.data ? new Uint8Array(e.data) : e.data : "string" != typeof e ? new Uint8Array(e) : e)[0]) return t.websocket.send(t.pong), t.resetPing(); try { decode(t, JSON.parse("string" == typeof n ? n : uint8ArrayToString(n))); } catch (t) { return logError(t); } }, this.websocket.onerror = function(e) { return t.events.emit("error", e); }; }, t; }(); module.exports = ClusterWS, module.exports.default = ClusterWS;