From 7d425a8713b7924f7cd5f2ae9b586b1b105a2817 Mon Sep 17 00:00:00 2001 From: Dmitrii Goriunov Date: Mon, 18 Dec 2017 21:58:39 +1300 Subject: [PATCH 01/21] Remove redundant code, change the way you pass url param --- dist/browser/ClusterWS.js | 30 ++++++++++++++---------------- dist/browser/ClusterWS.min.js | 2 +- dist/index.d.ts | 4 ---- dist/index.js | 30 ++++++++++++++---------------- src/index.ts | 9 ++------- src/utils/utils.ts | 4 ---- 6 files changed, 31 insertions(+), 48 deletions(-) diff --git a/dist/browser/ClusterWS.js b/dist/browser/ClusterWS.js index 531456e..6cf360d 100644 --- a/dist/browser/ClusterWS.js +++ b/dist/browser/ClusterWS.js @@ -7,12 +7,12 @@ return function(e) { function t(o) { if (n[o]) return n[o].exports; - var r = n[o] = { + var i = n[o] = { i: o, l: !1, exports: {} }; - return e[o].call(r.exports, r, r.exports, t), r.l = !0, r.exports; + return e[o].call(i.exports, i, i.exports, t), i.l = !0, i.exports; } var n = {}; return t.m = e, t.c = n, t.d = function(e, n, o) { @@ -44,19 +44,17 @@ Object.defineProperty(t, "__esModule", { value: !0 }); - var o = n(2), r = n(3), i = n(4), s = n(0), c = function() { + var o = n(2), i = n(3), r = n(4), s = n(0), c = function() { function e(e) { - return this.channels = {}, this.missedPing = 0, this.events = new r.EventEmitter(), - this.useBinary = !1, e.url && "string" == typeof e.url ? e.port && "number" == typeof e.port ? (this.options = { + return this.channels = {}, this.missedPing = 0, this.events = new i.EventEmitter(), + this.useBinary = !1, e.url && "string" == typeof e.url ? (this.options = { url: e.url, - port: e.port, autoReconnect: e.autoReconnect || !1, reconnectionIntervalMin: e.reconnectionIntervalMin || 1e3, reconnectionIntervalMax: e.reconnectionIntervalMax || 5e3, - reconnectionAttempts: e.reconnectionAttempts || 0, - secure: e.secure || !1 - }, this.options.reconnectionIntervalMin > this.options.reconnectionIntervalMax ? s.logError("reconnectionIntervalMin can not be more then reconnectionIntervalMax") : (this.reconnection = new i.Reconnection(this), - void this.create())) : s.logError("Port must be provided and it must be number") : s.logError("Url must be provided and it must be string"); + reconnectionAttempts: e.reconnectionAttempts || 0 + }, this.options.reconnectionIntervalMin > this.options.reconnectionIntervalMax ? s.logError("reconnectionIntervalMin can not be more then reconnectionIntervalMax") : (this.reconnection = new r.Reconnection(this), + void this.create())) : s.logError("Url must be provided and it must be string"); } return e.buffer = function(e) { for (var t = e.length, n = new Uint8Array(t), o = 0; o < t; o++) n[o] = e.charCodeAt(o); @@ -111,8 +109,8 @@ } } }, e.prototype.create = function() { - var t = this, n = window.MozWebSocket || window.WebSocket, o = this.options.secure ? "wss://" : "ws://"; - this.websocket = new n(o + this.options.url + ":" + this.options.port), this.websocket.binaryType = "arraybuffer", + var t = this, n = window.MozWebSocket || window.WebSocket; + this.websocket = new n(this.options.url), this.websocket.binaryType = "arraybuffer", this.websocket.onopen = function() { return t.reconnection.isConnected(); }, this.websocket.onerror = function(e) { @@ -155,7 +153,7 @@ Object.defineProperty(t, "__esModule", { value: !0 }); - var o = n(0), r = function() { + var o = n(0), i = function() { function e(e, t) { this.socket = e, this.channel = t, this.subscribe(); } @@ -172,13 +170,13 @@ this.socket.send("subscribe", this.channel, "system"); }, e; }(); - t.Channel = r; + t.Channel = i; }, function(e, t, n) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); - var o = n(0), r = function() { + var o = n(0), i = function() { function e() { this.events = {}; } @@ -193,7 +191,7 @@ this.events = {}; }, e; }(); - t.EventEmitter = r; + t.EventEmitter = i; }, function(e, t, n) { "use strict"; Object.defineProperty(t, "__esModule", { diff --git a/dist/browser/ClusterWS.min.js b/dist/browser/ClusterWS.min.js index 49b28ef..e0e85dc 100644 --- a/dist/browser/ClusterWS.min.js +++ b/dist/browser/ClusterWS.min.js @@ -1 +1 @@ -!function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var n=t();for(var o in n)("object"==typeof exports?exports:e)[o]=n[o]}}("undefined"!=typeof self?self:this,function(){return function(e){function t(o){if(n[o])return n[o].exports;var r=n[o]={i:o,l:!1,exports:{}};return e[o].call(r.exports,r,r.exports,t),r.l=!0,r.exports}var n={};return t.m=e,t.c=n,t.d=function(e,n,o){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:o})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=1)}([function(e,t,n){"use strict";function o(e){return console.log(e)}Object.defineProperty(t,"__esModule",{value:!0}),t.logError=o},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=n(2),r=n(3),i=n(4),s=n(0);t.ClusterWS=function(){function e(e){return this.channels={},this.missedPing=0,this.events=new r.EventEmitter,this.useBinary=!1,e.url&&"string"==typeof e.url?e.port&&"number"==typeof e.port?(this.options={url:e.url,port:e.port,autoReconnect:e.autoReconnect||!1,reconnectionIntervalMin:e.reconnectionIntervalMin||1e3,reconnectionIntervalMax:e.reconnectionIntervalMax||5e3,reconnectionAttempts:e.reconnectionAttempts||0,secure:e.secure||!1},this.options.reconnectionIntervalMin>this.options.reconnectionIntervalMax?s.logError("reconnectionIntervalMin can not be more then reconnectionIntervalMax"):(this.reconnection=new i.Reconnection(this),void this.create())):s.logError("Port must be provided and it must be number"):s.logError("Url must be provided and it must be string")}return e.buffer=function(e){for(var t=e.length,n=new Uint8Array(t),o=0;t>o;o++)n[o]=e.charCodeAt(o);return n.buffer},e.decode=function(e,t){switch(t["#"][0]){case"e":return e.events.emit(t["#"][1],t["#"][2]);case"p":return e.channels[t["#"][1]]?e.channels[t["#"][1]].onMessage(t["#"][2]):"";case"s":switch(t["#"][1]){case"c":e.pingInterval=setInterval(function(){return e.missedPing++>2?e.disconnect(4001,"Did not get pings"):""},t["#"][2].ping),e.useBinary=t["#"][2].binary,e.events.emit("connect")}}},e.encode=function(e,t,n){switch(n){case"ping":return e;case"emit":return JSON.stringify({"#":["e",e,t]});case"publish":return JSON.stringify({"#":["p",e,t]});case"system":switch(e){case"subscribe":return JSON.stringify({"#":["s","s",t]});case"unsubscribe":return JSON.stringify({"#":["s","u",t]});case"configuration":return JSON.stringify({"#":["s","c",t]})}}},e.prototype.create=function(){var t=this;this.websocket=new(window.MozWebSocket||window.WebSocket)((this.options.secure?"wss://":"ws://")+this.options.url+":"+this.options.port),this.websocket.binaryType="arraybuffer",this.websocket.onopen=function(){return t.reconnection.isConnected()},this.websocket.onerror=function(e){return t.events.emit("error",e.message)},this.websocket.onmessage=function(n){var o=n.data;if(t.useBinary&&"string"!=typeof o&&(o=String.fromCharCode.apply(null,new Uint8Array(o))),"#0"===o)return t.missedPing=0,t.send("#1",null,"ping");try{o=JSON.parse(o)}catch(e){return s.logError(e)}e.decode(t,o)},this.websocket.onclose=function(e){if(t.missedPing=0,clearInterval(t.pingInterval),t.events.emit("disconnect",e.code,e.reason),!t.reconnection.inReconnectionState){if(t.options.autoReconnect&&1e3!==e.code)return t.reconnection.reconnect();t.events.removeAllEvents();for(var n in t)t.hasOwnProperty(n)&&delete t[n]}}},e.prototype.on=function(e,t){this.events.on(e,t)},e.prototype.send=function(t,n,o){void 0===o&&(o="emit"),this.websocket.send(this.useBinary?e.buffer(e.encode(t,n,o)):e.encode(t,n,o))},e.prototype.disconnect=function(e,t){this.websocket.close(e||1e3,t)},e.prototype.getState=function(){return this.websocket.readyState},e.prototype.subscribe=function(e){return this.channels[e]?this.channels[e]:this.channels[e]=new o.Channel(this,e)},e.prototype.getChannelByName=function(e){return this.channels[e]},e}()},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=n(0);t.Channel=function(){function e(e,t){this.socket=e,this.channel=t,this.subscribe()}return e.prototype.watch=function(e){return"[object Function]"!=={}.toString.call(e)?o.logError("Listener must be a function"):(this.listener=e,this)},e.prototype.publish=function(e){return this.socket.send(this.channel,e,"publish"),this},e.prototype.unsubscribe=function(){this.socket.send("unsubscribe",this.channel,"system"),this.socket.channels[this.channel]=null},e.prototype.onMessage=function(e){this.listener&&this.listener.call(null,e)},e.prototype.subscribe=function(){this.socket.send("subscribe",this.channel,"system")},e}()},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=n(0);t.EventEmitter=function(){function e(){this.events={}}return e.prototype.on=function(e,t){if("[object Function]"!=={}.toString.call(t))return o.logError("Listener must be a function");this.events[e]||(this.events[e]=t)},e.prototype.emit=function(e){for(var t=[],n=1;arguments.length>n;n++)t[n-1]=arguments[n];this.events[e]&&(o=this.events[e]).call.apply(o,[null].concat(t));var o},e.prototype.removeAllEvents=function(){this.events={}},e}()},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Reconnection=function(){function e(e){this.socket=e,this.inReconnectionState=!1,this.reconnectionAttempted=0,this.autoReconnect=this.socket.options.autoReconnect}return e.prototype.isConnected=function(){clearTimeout(this.timer),clearInterval(this.interval),this.inReconnectionState=!1,this.reconnectionAttempted=0;for(var e in this.socket.channels)this.socket.channels.hasOwnProperty(e)&&this.socket.channels[e].subscribe()},e.prototype.reconnect=function(){var e=this;this.inReconnectionState=!0,this.interval=setInterval(function(){e.socket.getState()===e.socket.websocket.CLOSED&&(e.reconnectionAttempted++,0===e.socket.options.reconnectionAttempts||e.socket.options.reconnectionAttempts>e.reconnectionAttempted||(clearInterval(e.interval),e.autoReconnect=!1,e.inReconnectionState=!1),clearTimeout(e.timer),e.timer=setTimeout(function(){return e.socket.create()},Math.floor(Math.random()*(e.socket.options.reconnectionIntervalMax-e.socket.options.reconnectionIntervalMin+1))))},this.socket.options.reconnectionIntervalMin)},e}()}])}); \ No newline at end of file +!function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var n=t();for(var o in n)("object"==typeof exports?exports:e)[o]=n[o]}}("undefined"!=typeof self?self:this,function(){return function(e){function t(o){if(n[o])return n[o].exports;var i=n[o]={i:o,l:!1,exports:{}};return e[o].call(i.exports,i,i.exports,t),i.l=!0,i.exports}var n={};return t.m=e,t.c=n,t.d=function(e,n,o){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:o})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=1)}([function(e,t,n){"use strict";function o(e){return console.log(e)}Object.defineProperty(t,"__esModule",{value:!0}),t.logError=o},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=n(2),i=n(3),r=n(4),s=n(0);t.ClusterWS=function(){function e(e){return this.channels={},this.missedPing=0,this.events=new i.EventEmitter,this.useBinary=!1,e.url&&"string"==typeof e.url?(this.options={url:e.url,autoReconnect:e.autoReconnect||!1,reconnectionIntervalMin:e.reconnectionIntervalMin||1e3,reconnectionIntervalMax:e.reconnectionIntervalMax||5e3,reconnectionAttempts:e.reconnectionAttempts||0},this.options.reconnectionIntervalMin>this.options.reconnectionIntervalMax?s.logError("reconnectionIntervalMin can not be more then reconnectionIntervalMax"):(this.reconnection=new r.Reconnection(this),void this.create())):s.logError("Url must be provided and it must be string")}return e.buffer=function(e){for(var t=e.length,n=new Uint8Array(t),o=0;t>o;o++)n[o]=e.charCodeAt(o);return n.buffer},e.decode=function(e,t){switch(t["#"][0]){case"e":return e.events.emit(t["#"][1],t["#"][2]);case"p":return e.channels[t["#"][1]]?e.channels[t["#"][1]].onMessage(t["#"][2]):"";case"s":switch(t["#"][1]){case"c":e.pingInterval=setInterval(function(){return e.missedPing++>2?e.disconnect(4001,"Did not get pings"):""},t["#"][2].ping),e.useBinary=t["#"][2].binary,e.events.emit("connect")}}},e.encode=function(e,t,n){switch(n){case"ping":return e;case"emit":return JSON.stringify({"#":["e",e,t]});case"publish":return JSON.stringify({"#":["p",e,t]});case"system":switch(e){case"subscribe":return JSON.stringify({"#":["s","s",t]});case"unsubscribe":return JSON.stringify({"#":["s","u",t]});case"configuration":return JSON.stringify({"#":["s","c",t]})}}},e.prototype.create=function(){var t=this;this.websocket=new(window.MozWebSocket||window.WebSocket)(this.options.url),this.websocket.binaryType="arraybuffer",this.websocket.onopen=function(){return t.reconnection.isConnected()},this.websocket.onerror=function(e){return t.events.emit("error",e.message)},this.websocket.onmessage=function(n){var o=n.data;if(t.useBinary&&"string"!=typeof o&&(o=String.fromCharCode.apply(null,new Uint8Array(o))),"#0"===o)return t.missedPing=0,t.send("#1",null,"ping");try{o=JSON.parse(o)}catch(e){return s.logError(e)}e.decode(t,o)},this.websocket.onclose=function(e){if(t.missedPing=0,clearInterval(t.pingInterval),t.events.emit("disconnect",e.code,e.reason),!t.reconnection.inReconnectionState){if(t.options.autoReconnect&&1e3!==e.code)return t.reconnection.reconnect();t.events.removeAllEvents();for(var n in t)t.hasOwnProperty(n)&&delete t[n]}}},e.prototype.on=function(e,t){this.events.on(e,t)},e.prototype.send=function(t,n,o){void 0===o&&(o="emit"),this.websocket.send(this.useBinary?e.buffer(e.encode(t,n,o)):e.encode(t,n,o))},e.prototype.disconnect=function(e,t){this.websocket.close(e||1e3,t)},e.prototype.getState=function(){return this.websocket.readyState},e.prototype.subscribe=function(e){return this.channels[e]?this.channels[e]:this.channels[e]=new o.Channel(this,e)},e.prototype.getChannelByName=function(e){return this.channels[e]},e}()},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=n(0);t.Channel=function(){function e(e,t){this.socket=e,this.channel=t,this.subscribe()}return e.prototype.watch=function(e){return"[object Function]"!=={}.toString.call(e)?o.logError("Listener must be a function"):(this.listener=e,this)},e.prototype.publish=function(e){return this.socket.send(this.channel,e,"publish"),this},e.prototype.unsubscribe=function(){this.socket.send("unsubscribe",this.channel,"system"),this.socket.channels[this.channel]=null},e.prototype.onMessage=function(e){this.listener&&this.listener.call(null,e)},e.prototype.subscribe=function(){this.socket.send("subscribe",this.channel,"system")},e}()},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=n(0);t.EventEmitter=function(){function e(){this.events={}}return e.prototype.on=function(e,t){if("[object Function]"!=={}.toString.call(t))return o.logError("Listener must be a function");this.events[e]||(this.events[e]=t)},e.prototype.emit=function(e){for(var t=[],n=1;arguments.length>n;n++)t[n-1]=arguments[n];this.events[e]&&(o=this.events[e]).call.apply(o,[null].concat(t));var o},e.prototype.removeAllEvents=function(){this.events={}},e}()},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Reconnection=function(){function e(e){this.socket=e,this.inReconnectionState=!1,this.reconnectionAttempted=0,this.autoReconnect=this.socket.options.autoReconnect}return e.prototype.isConnected=function(){clearTimeout(this.timer),clearInterval(this.interval),this.inReconnectionState=!1,this.reconnectionAttempted=0;for(var e in this.socket.channels)this.socket.channels.hasOwnProperty(e)&&this.socket.channels[e].subscribe()},e.prototype.reconnect=function(){var e=this;this.inReconnectionState=!0,this.interval=setInterval(function(){e.socket.getState()===e.socket.websocket.CLOSED&&(e.reconnectionAttempted++,0===e.socket.options.reconnectionAttempts||e.socket.options.reconnectionAttempts>e.reconnectionAttempted||(clearInterval(e.interval),e.autoReconnect=!1,e.inReconnectionState=!1),clearTimeout(e.timer),e.timer=setTimeout(function(){return e.socket.create()},Math.floor(Math.random()*(e.socket.options.reconnectionIntervalMax-e.socket.options.reconnectionIntervalMin+1))))},this.socket.options.reconnectionIntervalMin)},e}()}])}); \ No newline at end of file diff --git a/dist/index.d.ts b/dist/index.d.ts index 5f3c80b..6578427 100644 --- a/dist/index.d.ts +++ b/dist/index.d.ts @@ -44,21 +44,17 @@ export interface IObject { } export interface IUserOptions { url: string; - port: number; autoReconnect?: boolean; reconnectionIntervalMin?: number; reconnectionIntervalMax?: number; reconnectionAttempts?: number; - secure?: boolean; } export interface IOptions { url: string; - port: number; autoReconnect: boolean; reconnectionIntervalMin: number; reconnectionIntervalMax: number; reconnectionAttempts: number; - secure: boolean; } export function logError(data: T): any; diff --git a/dist/index.js b/dist/index.js index 531456e..6cf360d 100644 --- a/dist/index.js +++ b/dist/index.js @@ -7,12 +7,12 @@ return function(e) { function t(o) { if (n[o]) return n[o].exports; - var r = n[o] = { + var i = n[o] = { i: o, l: !1, exports: {} }; - return e[o].call(r.exports, r, r.exports, t), r.l = !0, r.exports; + return e[o].call(i.exports, i, i.exports, t), i.l = !0, i.exports; } var n = {}; return t.m = e, t.c = n, t.d = function(e, n, o) { @@ -44,19 +44,17 @@ Object.defineProperty(t, "__esModule", { value: !0 }); - var o = n(2), r = n(3), i = n(4), s = n(0), c = function() { + var o = n(2), i = n(3), r = n(4), s = n(0), c = function() { function e(e) { - return this.channels = {}, this.missedPing = 0, this.events = new r.EventEmitter(), - this.useBinary = !1, e.url && "string" == typeof e.url ? e.port && "number" == typeof e.port ? (this.options = { + return this.channels = {}, this.missedPing = 0, this.events = new i.EventEmitter(), + this.useBinary = !1, e.url && "string" == typeof e.url ? (this.options = { url: e.url, - port: e.port, autoReconnect: e.autoReconnect || !1, reconnectionIntervalMin: e.reconnectionIntervalMin || 1e3, reconnectionIntervalMax: e.reconnectionIntervalMax || 5e3, - reconnectionAttempts: e.reconnectionAttempts || 0, - secure: e.secure || !1 - }, this.options.reconnectionIntervalMin > this.options.reconnectionIntervalMax ? s.logError("reconnectionIntervalMin can not be more then reconnectionIntervalMax") : (this.reconnection = new i.Reconnection(this), - void this.create())) : s.logError("Port must be provided and it must be number") : s.logError("Url must be provided and it must be string"); + reconnectionAttempts: e.reconnectionAttempts || 0 + }, this.options.reconnectionIntervalMin > this.options.reconnectionIntervalMax ? s.logError("reconnectionIntervalMin can not be more then reconnectionIntervalMax") : (this.reconnection = new r.Reconnection(this), + void this.create())) : s.logError("Url must be provided and it must be string"); } return e.buffer = function(e) { for (var t = e.length, n = new Uint8Array(t), o = 0; o < t; o++) n[o] = e.charCodeAt(o); @@ -111,8 +109,8 @@ } } }, e.prototype.create = function() { - var t = this, n = window.MozWebSocket || window.WebSocket, o = this.options.secure ? "wss://" : "ws://"; - this.websocket = new n(o + this.options.url + ":" + this.options.port), this.websocket.binaryType = "arraybuffer", + var t = this, n = window.MozWebSocket || window.WebSocket; + this.websocket = new n(this.options.url), this.websocket.binaryType = "arraybuffer", this.websocket.onopen = function() { return t.reconnection.isConnected(); }, this.websocket.onerror = function(e) { @@ -155,7 +153,7 @@ Object.defineProperty(t, "__esModule", { value: !0 }); - var o = n(0), r = function() { + var o = n(0), i = function() { function e(e, t) { this.socket = e, this.channel = t, this.subscribe(); } @@ -172,13 +170,13 @@ this.socket.send("subscribe", this.channel, "system"); }, e; }(); - t.Channel = r; + t.Channel = i; }, function(e, t, n) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); - var o = n(0), r = function() { + var o = n(0), i = function() { function e() { this.events = {}; } @@ -193,7 +191,7 @@ this.events = {}; }, e; }(); - t.EventEmitter = r; + t.EventEmitter = i; }, function(e, t, n) { "use strict"; Object.defineProperty(t, "__esModule", { diff --git a/src/index.ts b/src/index.ts index 0120af2..0ca9085 100644 --- a/src/index.ts +++ b/src/index.ts @@ -56,17 +56,13 @@ export class ClusterWS { constructor(configuration: IUserOptions) { if (!configuration.url || typeof configuration.url !== 'string') return logError('Url must be provided and it must be string') - if (!configuration.port || typeof configuration.port !== 'number') - return logError('Port must be provided and it must be number') this.options = { url: configuration.url, - port: configuration.port, autoReconnect: configuration.autoReconnect || false, reconnectionIntervalMin: configuration.reconnectionIntervalMin || 1000, reconnectionIntervalMax: configuration.reconnectionIntervalMax || 5000, - reconnectionAttempts: configuration.reconnectionAttempts || 0, - secure: configuration.secure || false + reconnectionAttempts: configuration.reconnectionAttempts || 0 } if (this.options.reconnectionIntervalMin > this.options.reconnectionIntervalMax) @@ -78,8 +74,7 @@ export class ClusterWS { public create(): void { const Socket: any = window.MozWebSocket || window.WebSocket - const protocol: string = this.options.secure ? 'wss://' : 'ws://' - this.websocket = new Socket(protocol + this.options.url + ':' + this.options.port) + this.websocket = new Socket(this.options.url) this.websocket.binaryType = 'arraybuffer' this.websocket.onopen = (): void => this.reconnection.isConnected() diff --git a/src/utils/utils.ts b/src/utils/utils.ts index 577d49d..7fa638b 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -7,22 +7,18 @@ export interface IObject { export interface IUserOptions { url: string - port: number autoReconnect?: boolean reconnectionIntervalMin?: number reconnectionIntervalMax?: number reconnectionAttempts?: number - secure?: boolean } export interface IOptions { url: string - port: number autoReconnect: boolean reconnectionIntervalMin: number reconnectionIntervalMax: number reconnectionAttempts: number - secure: boolean } export function logError(data: T): any { From 96ab141358bb8649336c329f48b4e6aed7c070f3 Mon Sep 17 00:00:00 2001 From: Dmitrii Goriunov Date: Fri, 22 Dec 2017 00:58:37 +1300 Subject: [PATCH 02/21] Code clean up --- dist/browser/ClusterWS.js | 2 +- dist/browser/ClusterWS.min.js | 2 +- dist/index.js | 2 +- src/index.ts | 14 ++++++++++---- 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/dist/browser/ClusterWS.js b/dist/browser/ClusterWS.js index 6cf360d..6f268b0 100644 --- a/dist/browser/ClusterWS.js +++ b/dist/browser/ClusterWS.js @@ -130,7 +130,7 @@ !t.reconnection.inReconnectionState) { if (t.options.autoReconnect && 1e3 !== e.code) return t.reconnection.reconnect(); t.events.removeAllEvents(); - for (var n in t) t.hasOwnProperty(n) && delete t[n]; + for (var n in t) t[n] && delete t[n]; } }; }, e.prototype.on = function(e, t) { diff --git a/dist/browser/ClusterWS.min.js b/dist/browser/ClusterWS.min.js index e0e85dc..7abe509 100644 --- a/dist/browser/ClusterWS.min.js +++ b/dist/browser/ClusterWS.min.js @@ -1 +1 @@ -!function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var n=t();for(var o in n)("object"==typeof exports?exports:e)[o]=n[o]}}("undefined"!=typeof self?self:this,function(){return function(e){function t(o){if(n[o])return n[o].exports;var i=n[o]={i:o,l:!1,exports:{}};return e[o].call(i.exports,i,i.exports,t),i.l=!0,i.exports}var n={};return t.m=e,t.c=n,t.d=function(e,n,o){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:o})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=1)}([function(e,t,n){"use strict";function o(e){return console.log(e)}Object.defineProperty(t,"__esModule",{value:!0}),t.logError=o},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=n(2),i=n(3),r=n(4),s=n(0);t.ClusterWS=function(){function e(e){return this.channels={},this.missedPing=0,this.events=new i.EventEmitter,this.useBinary=!1,e.url&&"string"==typeof e.url?(this.options={url:e.url,autoReconnect:e.autoReconnect||!1,reconnectionIntervalMin:e.reconnectionIntervalMin||1e3,reconnectionIntervalMax:e.reconnectionIntervalMax||5e3,reconnectionAttempts:e.reconnectionAttempts||0},this.options.reconnectionIntervalMin>this.options.reconnectionIntervalMax?s.logError("reconnectionIntervalMin can not be more then reconnectionIntervalMax"):(this.reconnection=new r.Reconnection(this),void this.create())):s.logError("Url must be provided and it must be string")}return e.buffer=function(e){for(var t=e.length,n=new Uint8Array(t),o=0;t>o;o++)n[o]=e.charCodeAt(o);return n.buffer},e.decode=function(e,t){switch(t["#"][0]){case"e":return e.events.emit(t["#"][1],t["#"][2]);case"p":return e.channels[t["#"][1]]?e.channels[t["#"][1]].onMessage(t["#"][2]):"";case"s":switch(t["#"][1]){case"c":e.pingInterval=setInterval(function(){return e.missedPing++>2?e.disconnect(4001,"Did not get pings"):""},t["#"][2].ping),e.useBinary=t["#"][2].binary,e.events.emit("connect")}}},e.encode=function(e,t,n){switch(n){case"ping":return e;case"emit":return JSON.stringify({"#":["e",e,t]});case"publish":return JSON.stringify({"#":["p",e,t]});case"system":switch(e){case"subscribe":return JSON.stringify({"#":["s","s",t]});case"unsubscribe":return JSON.stringify({"#":["s","u",t]});case"configuration":return JSON.stringify({"#":["s","c",t]})}}},e.prototype.create=function(){var t=this;this.websocket=new(window.MozWebSocket||window.WebSocket)(this.options.url),this.websocket.binaryType="arraybuffer",this.websocket.onopen=function(){return t.reconnection.isConnected()},this.websocket.onerror=function(e){return t.events.emit("error",e.message)},this.websocket.onmessage=function(n){var o=n.data;if(t.useBinary&&"string"!=typeof o&&(o=String.fromCharCode.apply(null,new Uint8Array(o))),"#0"===o)return t.missedPing=0,t.send("#1",null,"ping");try{o=JSON.parse(o)}catch(e){return s.logError(e)}e.decode(t,o)},this.websocket.onclose=function(e){if(t.missedPing=0,clearInterval(t.pingInterval),t.events.emit("disconnect",e.code,e.reason),!t.reconnection.inReconnectionState){if(t.options.autoReconnect&&1e3!==e.code)return t.reconnection.reconnect();t.events.removeAllEvents();for(var n in t)t.hasOwnProperty(n)&&delete t[n]}}},e.prototype.on=function(e,t){this.events.on(e,t)},e.prototype.send=function(t,n,o){void 0===o&&(o="emit"),this.websocket.send(this.useBinary?e.buffer(e.encode(t,n,o)):e.encode(t,n,o))},e.prototype.disconnect=function(e,t){this.websocket.close(e||1e3,t)},e.prototype.getState=function(){return this.websocket.readyState},e.prototype.subscribe=function(e){return this.channels[e]?this.channels[e]:this.channels[e]=new o.Channel(this,e)},e.prototype.getChannelByName=function(e){return this.channels[e]},e}()},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=n(0);t.Channel=function(){function e(e,t){this.socket=e,this.channel=t,this.subscribe()}return e.prototype.watch=function(e){return"[object Function]"!=={}.toString.call(e)?o.logError("Listener must be a function"):(this.listener=e,this)},e.prototype.publish=function(e){return this.socket.send(this.channel,e,"publish"),this},e.prototype.unsubscribe=function(){this.socket.send("unsubscribe",this.channel,"system"),this.socket.channels[this.channel]=null},e.prototype.onMessage=function(e){this.listener&&this.listener.call(null,e)},e.prototype.subscribe=function(){this.socket.send("subscribe",this.channel,"system")},e}()},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=n(0);t.EventEmitter=function(){function e(){this.events={}}return e.prototype.on=function(e,t){if("[object Function]"!=={}.toString.call(t))return o.logError("Listener must be a function");this.events[e]||(this.events[e]=t)},e.prototype.emit=function(e){for(var t=[],n=1;arguments.length>n;n++)t[n-1]=arguments[n];this.events[e]&&(o=this.events[e]).call.apply(o,[null].concat(t));var o},e.prototype.removeAllEvents=function(){this.events={}},e}()},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Reconnection=function(){function e(e){this.socket=e,this.inReconnectionState=!1,this.reconnectionAttempted=0,this.autoReconnect=this.socket.options.autoReconnect}return e.prototype.isConnected=function(){clearTimeout(this.timer),clearInterval(this.interval),this.inReconnectionState=!1,this.reconnectionAttempted=0;for(var e in this.socket.channels)this.socket.channels.hasOwnProperty(e)&&this.socket.channels[e].subscribe()},e.prototype.reconnect=function(){var e=this;this.inReconnectionState=!0,this.interval=setInterval(function(){e.socket.getState()===e.socket.websocket.CLOSED&&(e.reconnectionAttempted++,0===e.socket.options.reconnectionAttempts||e.socket.options.reconnectionAttempts>e.reconnectionAttempted||(clearInterval(e.interval),e.autoReconnect=!1,e.inReconnectionState=!1),clearTimeout(e.timer),e.timer=setTimeout(function(){return e.socket.create()},Math.floor(Math.random()*(e.socket.options.reconnectionIntervalMax-e.socket.options.reconnectionIntervalMin+1))))},this.socket.options.reconnectionIntervalMin)},e}()}])}); \ No newline at end of file +!function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var n=t();for(var o in n)("object"==typeof exports?exports:e)[o]=n[o]}}("undefined"!=typeof self?self:this,function(){return function(e){function t(o){if(n[o])return n[o].exports;var i=n[o]={i:o,l:!1,exports:{}};return e[o].call(i.exports,i,i.exports,t),i.l=!0,i.exports}var n={};return t.m=e,t.c=n,t.d=function(e,n,o){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:o})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=1)}([function(e,t,n){"use strict";function o(e){return console.log(e)}Object.defineProperty(t,"__esModule",{value:!0}),t.logError=o},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=n(2),i=n(3),r=n(4),s=n(0);t.ClusterWS=function(){function e(e){return this.channels={},this.missedPing=0,this.events=new i.EventEmitter,this.useBinary=!1,e.url&&"string"==typeof e.url?(this.options={url:e.url,autoReconnect:e.autoReconnect||!1,reconnectionIntervalMin:e.reconnectionIntervalMin||1e3,reconnectionIntervalMax:e.reconnectionIntervalMax||5e3,reconnectionAttempts:e.reconnectionAttempts||0},this.options.reconnectionIntervalMin>this.options.reconnectionIntervalMax?s.logError("reconnectionIntervalMin can not be more then reconnectionIntervalMax"):(this.reconnection=new r.Reconnection(this),void this.create())):s.logError("Url must be provided and it must be string")}return e.buffer=function(e){for(var t=e.length,n=new Uint8Array(t),o=0;t>o;o++)n[o]=e.charCodeAt(o);return n.buffer},e.decode=function(e,t){switch(t["#"][0]){case"e":return e.events.emit(t["#"][1],t["#"][2]);case"p":return e.channels[t["#"][1]]?e.channels[t["#"][1]].onMessage(t["#"][2]):"";case"s":switch(t["#"][1]){case"c":e.pingInterval=setInterval(function(){return e.missedPing++>2?e.disconnect(4001,"Did not get pings"):""},t["#"][2].ping),e.useBinary=t["#"][2].binary,e.events.emit("connect")}}},e.encode=function(e,t,n){switch(n){case"ping":return e;case"emit":return JSON.stringify({"#":["e",e,t]});case"publish":return JSON.stringify({"#":["p",e,t]});case"system":switch(e){case"subscribe":return JSON.stringify({"#":["s","s",t]});case"unsubscribe":return JSON.stringify({"#":["s","u",t]});case"configuration":return JSON.stringify({"#":["s","c",t]})}}},e.prototype.create=function(){var t=this;this.websocket=new(window.MozWebSocket||window.WebSocket)(this.options.url),this.websocket.binaryType="arraybuffer",this.websocket.onopen=function(){return t.reconnection.isConnected()},this.websocket.onerror=function(e){return t.events.emit("error",e.message)},this.websocket.onmessage=function(n){var o=n.data;if(t.useBinary&&"string"!=typeof o&&(o=String.fromCharCode.apply(null,new Uint8Array(o))),"#0"===o)return t.missedPing=0,t.send("#1",null,"ping");try{o=JSON.parse(o)}catch(e){return s.logError(e)}e.decode(t,o)},this.websocket.onclose=function(e){if(t.missedPing=0,clearInterval(t.pingInterval),t.events.emit("disconnect",e.code,e.reason),!t.reconnection.inReconnectionState){if(t.options.autoReconnect&&1e3!==e.code)return t.reconnection.reconnect();t.events.removeAllEvents();for(var n in t)t[n]&&delete t[n]}}},e.prototype.on=function(e,t){this.events.on(e,t)},e.prototype.send=function(t,n,o){void 0===o&&(o="emit"),this.websocket.send(this.useBinary?e.buffer(e.encode(t,n,o)):e.encode(t,n,o))},e.prototype.disconnect=function(e,t){this.websocket.close(e||1e3,t)},e.prototype.getState=function(){return this.websocket.readyState},e.prototype.subscribe=function(e){return this.channels[e]?this.channels[e]:this.channels[e]=new o.Channel(this,e)},e.prototype.getChannelByName=function(e){return this.channels[e]},e}()},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=n(0);t.Channel=function(){function e(e,t){this.socket=e,this.channel=t,this.subscribe()}return e.prototype.watch=function(e){return"[object Function]"!=={}.toString.call(e)?o.logError("Listener must be a function"):(this.listener=e,this)},e.prototype.publish=function(e){return this.socket.send(this.channel,e,"publish"),this},e.prototype.unsubscribe=function(){this.socket.send("unsubscribe",this.channel,"system"),this.socket.channels[this.channel]=null},e.prototype.onMessage=function(e){this.listener&&this.listener.call(null,e)},e.prototype.subscribe=function(){this.socket.send("subscribe",this.channel,"system")},e}()},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=n(0);t.EventEmitter=function(){function e(){this.events={}}return e.prototype.on=function(e,t){if("[object Function]"!=={}.toString.call(t))return o.logError("Listener must be a function");this.events[e]||(this.events[e]=t)},e.prototype.emit=function(e){for(var t=[],n=1;arguments.length>n;n++)t[n-1]=arguments[n];this.events[e]&&(o=this.events[e]).call.apply(o,[null].concat(t));var o},e.prototype.removeAllEvents=function(){this.events={}},e}()},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Reconnection=function(){function e(e){this.socket=e,this.inReconnectionState=!1,this.reconnectionAttempted=0,this.autoReconnect=this.socket.options.autoReconnect}return e.prototype.isConnected=function(){clearTimeout(this.timer),clearInterval(this.interval),this.inReconnectionState=!1,this.reconnectionAttempted=0;for(var e in this.socket.channels)this.socket.channels.hasOwnProperty(e)&&this.socket.channels[e].subscribe()},e.prototype.reconnect=function(){var e=this;this.inReconnectionState=!0,this.interval=setInterval(function(){e.socket.getState()===e.socket.websocket.CLOSED&&(e.reconnectionAttempted++,0===e.socket.options.reconnectionAttempts||e.socket.options.reconnectionAttempts>e.reconnectionAttempted||(clearInterval(e.interval),e.autoReconnect=!1,e.inReconnectionState=!1),clearTimeout(e.timer),e.timer=setTimeout(function(){return e.socket.create()},Math.floor(Math.random()*(e.socket.options.reconnectionIntervalMax-e.socket.options.reconnectionIntervalMin+1))))},this.socket.options.reconnectionIntervalMin)},e}()}])}); \ No newline at end of file diff --git a/dist/index.js b/dist/index.js index 6cf360d..6f268b0 100644 --- a/dist/index.js +++ b/dist/index.js @@ -130,7 +130,7 @@ !t.reconnection.inReconnectionState) { if (t.options.autoReconnect && 1e3 !== e.code) return t.reconnection.reconnect(); t.events.removeAllEvents(); - for (var n in t) t.hasOwnProperty(n) && delete t[n]; + for (var n in t) t[n] && delete t[n]; } }; }, e.prototype.on = function(e, t) { diff --git a/src/index.ts b/src/index.ts index 0ca9085..6456d41 100644 --- a/src/index.ts +++ b/src/index.ts @@ -86,7 +86,9 @@ export class ClusterWS { this.missedPing = 0 return this.send('#1', null, 'ping') } - try { data = JSON.parse(data) } catch (e) { return logError(e) } + try { + data = JSON.parse(data) + } catch (e) { return logError(e) } ClusterWS.decode(this, data) } this.websocket.onclose = (event: CloseEvent): void => { @@ -98,7 +100,7 @@ export class ClusterWS { if (this.options.autoReconnect && event.code !== 1000) return this.reconnection.reconnect() this.events.removeAllEvents() - for (const key in this) this.hasOwnProperty(key) ? delete this[key] : '' + for (const key in this) this[key] ? delete this[key] : null } } @@ -107,7 +109,9 @@ export class ClusterWS { } public send(event: string, data: any, type: string = 'emit'): void { - this.websocket.send(this.useBinary ? ClusterWS.buffer(ClusterWS.encode(event, data, type)) : ClusterWS.encode(event, data, type)) + this.websocket.send(this.useBinary ? + ClusterWS.buffer(ClusterWS.encode(event, data, type)) : + ClusterWS.encode(event, data, type)) } public disconnect(code?: number, msg?: any): void { @@ -119,7 +123,9 @@ export class ClusterWS { } public subscribe(channel: string): void { - return this.channels[channel] ? this.channels[channel] : this.channels[channel] = new Channel(this, channel) + return this.channels[channel] ? + this.channels[channel] : + this.channels[channel] = new Channel(this, channel) } public getChannelByName(channelName: string): Channel { From 9bf29966d0c48a7c80edc23b12ca637d0a9d7b52 Mon Sep 17 00:00:00 2001 From: Dmitrii Goriunov Date: Sun, 24 Dec 2017 20:04:04 +1300 Subject: [PATCH 03/21] Code improvments and clean up --- dist/browser/ClusterWS.js | 10 +++++----- dist/browser/ClusterWS.min.js | 2 +- dist/index.js | 10 +++++----- src/index.ts | 10 +++++----- src/modules/reconnection.ts | 2 +- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/dist/browser/ClusterWS.js b/dist/browser/ClusterWS.js index 6f268b0..c497ffd 100644 --- a/dist/browser/ClusterWS.js +++ b/dist/browser/ClusterWS.js @@ -65,13 +65,13 @@ return e.events.emit(t["#"][1], t["#"][2]); case "p": - return e.channels[t["#"][1]] ? e.channels[t["#"][1]].onMessage(t["#"][2]) : ""; + return e.channels[t["#"][1]] ? e.channels[t["#"][1]].onMessage(t["#"][2]) : null; case "s": switch (t["#"][1]) { case "c": e.pingInterval = setInterval(function() { - return e.missedPing++ > 2 ? e.disconnect(4001, "Did not get pings") : ""; + return e.missedPing++ > 2 ? e.disconnect(4001, "Did not get pings") : null; }, t["#"][2].ping), e.useBinary = t["#"][2].binary, e.events.emit("connect"); } } @@ -117,7 +117,7 @@ return t.events.emit("error", e.message); }, this.websocket.onmessage = function(n) { var o = n.data; - if (t.useBinary && "string" != typeof o && (o = String.fromCharCode.apply(null, new Uint8Array(o))), + if ("string" != typeof o && (o = String.fromCharCode.apply(null, new Uint8Array(o))), "#0" === o) return t.missedPing = 0, t.send("#1", null, "ping"); try { o = JSON.parse(o); @@ -130,7 +130,7 @@ !t.reconnection.inReconnectionState) { if (t.options.autoReconnect && 1e3 !== e.code) return t.reconnection.reconnect(); t.events.removeAllEvents(); - for (var n in t) t[n] && delete t[n]; + for (var n in t) t[n] && (t[n] = null); } }; }, e.prototype.on = function(e, t) { @@ -205,7 +205,7 @@ return e.prototype.isConnected = function() { clearTimeout(this.timer), clearInterval(this.interval), this.inReconnectionState = !1, this.reconnectionAttempted = 0; - for (var e in this.socket.channels) this.socket.channels.hasOwnProperty(e) && this.socket.channels[e].subscribe(); + for (var e in this.socket.channels) this.socket.channels[e] && this.socket.channels[e].subscribe(); }, e.prototype.reconnect = function() { var e = this; this.inReconnectionState = !0, this.interval = setInterval(function() { diff --git a/dist/browser/ClusterWS.min.js b/dist/browser/ClusterWS.min.js index 7abe509..2e53b32 100644 --- a/dist/browser/ClusterWS.min.js +++ b/dist/browser/ClusterWS.min.js @@ -1 +1 @@ -!function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var n=t();for(var o in n)("object"==typeof exports?exports:e)[o]=n[o]}}("undefined"!=typeof self?self:this,function(){return function(e){function t(o){if(n[o])return n[o].exports;var i=n[o]={i:o,l:!1,exports:{}};return e[o].call(i.exports,i,i.exports,t),i.l=!0,i.exports}var n={};return t.m=e,t.c=n,t.d=function(e,n,o){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:o})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=1)}([function(e,t,n){"use strict";function o(e){return console.log(e)}Object.defineProperty(t,"__esModule",{value:!0}),t.logError=o},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=n(2),i=n(3),r=n(4),s=n(0);t.ClusterWS=function(){function e(e){return this.channels={},this.missedPing=0,this.events=new i.EventEmitter,this.useBinary=!1,e.url&&"string"==typeof e.url?(this.options={url:e.url,autoReconnect:e.autoReconnect||!1,reconnectionIntervalMin:e.reconnectionIntervalMin||1e3,reconnectionIntervalMax:e.reconnectionIntervalMax||5e3,reconnectionAttempts:e.reconnectionAttempts||0},this.options.reconnectionIntervalMin>this.options.reconnectionIntervalMax?s.logError("reconnectionIntervalMin can not be more then reconnectionIntervalMax"):(this.reconnection=new r.Reconnection(this),void this.create())):s.logError("Url must be provided and it must be string")}return e.buffer=function(e){for(var t=e.length,n=new Uint8Array(t),o=0;t>o;o++)n[o]=e.charCodeAt(o);return n.buffer},e.decode=function(e,t){switch(t["#"][0]){case"e":return e.events.emit(t["#"][1],t["#"][2]);case"p":return e.channels[t["#"][1]]?e.channels[t["#"][1]].onMessage(t["#"][2]):"";case"s":switch(t["#"][1]){case"c":e.pingInterval=setInterval(function(){return e.missedPing++>2?e.disconnect(4001,"Did not get pings"):""},t["#"][2].ping),e.useBinary=t["#"][2].binary,e.events.emit("connect")}}},e.encode=function(e,t,n){switch(n){case"ping":return e;case"emit":return JSON.stringify({"#":["e",e,t]});case"publish":return JSON.stringify({"#":["p",e,t]});case"system":switch(e){case"subscribe":return JSON.stringify({"#":["s","s",t]});case"unsubscribe":return JSON.stringify({"#":["s","u",t]});case"configuration":return JSON.stringify({"#":["s","c",t]})}}},e.prototype.create=function(){var t=this;this.websocket=new(window.MozWebSocket||window.WebSocket)(this.options.url),this.websocket.binaryType="arraybuffer",this.websocket.onopen=function(){return t.reconnection.isConnected()},this.websocket.onerror=function(e){return t.events.emit("error",e.message)},this.websocket.onmessage=function(n){var o=n.data;if(t.useBinary&&"string"!=typeof o&&(o=String.fromCharCode.apply(null,new Uint8Array(o))),"#0"===o)return t.missedPing=0,t.send("#1",null,"ping");try{o=JSON.parse(o)}catch(e){return s.logError(e)}e.decode(t,o)},this.websocket.onclose=function(e){if(t.missedPing=0,clearInterval(t.pingInterval),t.events.emit("disconnect",e.code,e.reason),!t.reconnection.inReconnectionState){if(t.options.autoReconnect&&1e3!==e.code)return t.reconnection.reconnect();t.events.removeAllEvents();for(var n in t)t[n]&&delete t[n]}}},e.prototype.on=function(e,t){this.events.on(e,t)},e.prototype.send=function(t,n,o){void 0===o&&(o="emit"),this.websocket.send(this.useBinary?e.buffer(e.encode(t,n,o)):e.encode(t,n,o))},e.prototype.disconnect=function(e,t){this.websocket.close(e||1e3,t)},e.prototype.getState=function(){return this.websocket.readyState},e.prototype.subscribe=function(e){return this.channels[e]?this.channels[e]:this.channels[e]=new o.Channel(this,e)},e.prototype.getChannelByName=function(e){return this.channels[e]},e}()},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=n(0);t.Channel=function(){function e(e,t){this.socket=e,this.channel=t,this.subscribe()}return e.prototype.watch=function(e){return"[object Function]"!=={}.toString.call(e)?o.logError("Listener must be a function"):(this.listener=e,this)},e.prototype.publish=function(e){return this.socket.send(this.channel,e,"publish"),this},e.prototype.unsubscribe=function(){this.socket.send("unsubscribe",this.channel,"system"),this.socket.channels[this.channel]=null},e.prototype.onMessage=function(e){this.listener&&this.listener.call(null,e)},e.prototype.subscribe=function(){this.socket.send("subscribe",this.channel,"system")},e}()},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=n(0);t.EventEmitter=function(){function e(){this.events={}}return e.prototype.on=function(e,t){if("[object Function]"!=={}.toString.call(t))return o.logError("Listener must be a function");this.events[e]||(this.events[e]=t)},e.prototype.emit=function(e){for(var t=[],n=1;arguments.length>n;n++)t[n-1]=arguments[n];this.events[e]&&(o=this.events[e]).call.apply(o,[null].concat(t));var o},e.prototype.removeAllEvents=function(){this.events={}},e}()},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Reconnection=function(){function e(e){this.socket=e,this.inReconnectionState=!1,this.reconnectionAttempted=0,this.autoReconnect=this.socket.options.autoReconnect}return e.prototype.isConnected=function(){clearTimeout(this.timer),clearInterval(this.interval),this.inReconnectionState=!1,this.reconnectionAttempted=0;for(var e in this.socket.channels)this.socket.channels.hasOwnProperty(e)&&this.socket.channels[e].subscribe()},e.prototype.reconnect=function(){var e=this;this.inReconnectionState=!0,this.interval=setInterval(function(){e.socket.getState()===e.socket.websocket.CLOSED&&(e.reconnectionAttempted++,0===e.socket.options.reconnectionAttempts||e.socket.options.reconnectionAttempts>e.reconnectionAttempted||(clearInterval(e.interval),e.autoReconnect=!1,e.inReconnectionState=!1),clearTimeout(e.timer),e.timer=setTimeout(function(){return e.socket.create()},Math.floor(Math.random()*(e.socket.options.reconnectionIntervalMax-e.socket.options.reconnectionIntervalMin+1))))},this.socket.options.reconnectionIntervalMin)},e}()}])}); \ No newline at end of file +!function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var n=t();for(var o in n)("object"==typeof exports?exports:e)[o]=n[o]}}("undefined"!=typeof self?self:this,function(){return function(e){function t(o){if(n[o])return n[o].exports;var i=n[o]={i:o,l:!1,exports:{}};return e[o].call(i.exports,i,i.exports,t),i.l=!0,i.exports}var n={};return t.m=e,t.c=n,t.d=function(e,n,o){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:o})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=1)}([function(e,t,n){"use strict";function o(e){return console.log(e)}Object.defineProperty(t,"__esModule",{value:!0}),t.logError=o},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=n(2),i=n(3),r=n(4),s=n(0);t.ClusterWS=function(){function e(e){return this.channels={},this.missedPing=0,this.events=new i.EventEmitter,this.useBinary=!1,e.url&&"string"==typeof e.url?(this.options={url:e.url,autoReconnect:e.autoReconnect||!1,reconnectionIntervalMin:e.reconnectionIntervalMin||1e3,reconnectionIntervalMax:e.reconnectionIntervalMax||5e3,reconnectionAttempts:e.reconnectionAttempts||0},this.options.reconnectionIntervalMin>this.options.reconnectionIntervalMax?s.logError("reconnectionIntervalMin can not be more then reconnectionIntervalMax"):(this.reconnection=new r.Reconnection(this),void this.create())):s.logError("Url must be provided and it must be string")}return e.buffer=function(e){for(var t=e.length,n=new Uint8Array(t),o=0;t>o;o++)n[o]=e.charCodeAt(o);return n.buffer},e.decode=function(e,t){switch(t["#"][0]){case"e":return e.events.emit(t["#"][1],t["#"][2]);case"p":return e.channels[t["#"][1]]?e.channels[t["#"][1]].onMessage(t["#"][2]):null;case"s":switch(t["#"][1]){case"c":e.pingInterval=setInterval(function(){return e.missedPing++>2?e.disconnect(4001,"Did not get pings"):null},t["#"][2].ping),e.useBinary=t["#"][2].binary,e.events.emit("connect")}}},e.encode=function(e,t,n){switch(n){case"ping":return e;case"emit":return JSON.stringify({"#":["e",e,t]});case"publish":return JSON.stringify({"#":["p",e,t]});case"system":switch(e){case"subscribe":return JSON.stringify({"#":["s","s",t]});case"unsubscribe":return JSON.stringify({"#":["s","u",t]});case"configuration":return JSON.stringify({"#":["s","c",t]})}}},e.prototype.create=function(){var t=this;this.websocket=new(window.MozWebSocket||window.WebSocket)(this.options.url),this.websocket.binaryType="arraybuffer",this.websocket.onopen=function(){return t.reconnection.isConnected()},this.websocket.onerror=function(e){return t.events.emit("error",e.message)},this.websocket.onmessage=function(n){var o=n.data;if("string"!=typeof o&&(o=String.fromCharCode.apply(null,new Uint8Array(o))),"#0"===o)return t.missedPing=0,t.send("#1",null,"ping");try{o=JSON.parse(o)}catch(e){return s.logError(e)}e.decode(t,o)},this.websocket.onclose=function(e){if(t.missedPing=0,clearInterval(t.pingInterval),t.events.emit("disconnect",e.code,e.reason),!t.reconnection.inReconnectionState){if(t.options.autoReconnect&&1e3!==e.code)return t.reconnection.reconnect();t.events.removeAllEvents();for(var n in t)t[n]&&(t[n]=null)}}},e.prototype.on=function(e,t){this.events.on(e,t)},e.prototype.send=function(t,n,o){void 0===o&&(o="emit"),this.websocket.send(this.useBinary?e.buffer(e.encode(t,n,o)):e.encode(t,n,o))},e.prototype.disconnect=function(e,t){this.websocket.close(e||1e3,t)},e.prototype.getState=function(){return this.websocket.readyState},e.prototype.subscribe=function(e){return this.channels[e]?this.channels[e]:this.channels[e]=new o.Channel(this,e)},e.prototype.getChannelByName=function(e){return this.channels[e]},e}()},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=n(0);t.Channel=function(){function e(e,t){this.socket=e,this.channel=t,this.subscribe()}return e.prototype.watch=function(e){return"[object Function]"!=={}.toString.call(e)?o.logError("Listener must be a function"):(this.listener=e,this)},e.prototype.publish=function(e){return this.socket.send(this.channel,e,"publish"),this},e.prototype.unsubscribe=function(){this.socket.send("unsubscribe",this.channel,"system"),this.socket.channels[this.channel]=null},e.prototype.onMessage=function(e){this.listener&&this.listener.call(null,e)},e.prototype.subscribe=function(){this.socket.send("subscribe",this.channel,"system")},e}()},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=n(0);t.EventEmitter=function(){function e(){this.events={}}return e.prototype.on=function(e,t){if("[object Function]"!=={}.toString.call(t))return o.logError("Listener must be a function");this.events[e]||(this.events[e]=t)},e.prototype.emit=function(e){for(var t=[],n=1;arguments.length>n;n++)t[n-1]=arguments[n];this.events[e]&&(o=this.events[e]).call.apply(o,[null].concat(t));var o},e.prototype.removeAllEvents=function(){this.events={}},e}()},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Reconnection=function(){function e(e){this.socket=e,this.inReconnectionState=!1,this.reconnectionAttempted=0,this.autoReconnect=this.socket.options.autoReconnect}return e.prototype.isConnected=function(){clearTimeout(this.timer),clearInterval(this.interval),this.inReconnectionState=!1,this.reconnectionAttempted=0;for(var e in this.socket.channels)this.socket.channels[e]&&this.socket.channels[e].subscribe()},e.prototype.reconnect=function(){var e=this;this.inReconnectionState=!0,this.interval=setInterval(function(){e.socket.getState()===e.socket.websocket.CLOSED&&(e.reconnectionAttempted++,0===e.socket.options.reconnectionAttempts||e.socket.options.reconnectionAttempts>e.reconnectionAttempted||(clearInterval(e.interval),e.autoReconnect=!1,e.inReconnectionState=!1),clearTimeout(e.timer),e.timer=setTimeout(function(){return e.socket.create()},Math.floor(Math.random()*(e.socket.options.reconnectionIntervalMax-e.socket.options.reconnectionIntervalMin+1))))},this.socket.options.reconnectionIntervalMin)},e}()}])}); \ No newline at end of file diff --git a/dist/index.js b/dist/index.js index 6f268b0..c497ffd 100644 --- a/dist/index.js +++ b/dist/index.js @@ -65,13 +65,13 @@ return e.events.emit(t["#"][1], t["#"][2]); case "p": - return e.channels[t["#"][1]] ? e.channels[t["#"][1]].onMessage(t["#"][2]) : ""; + return e.channels[t["#"][1]] ? e.channels[t["#"][1]].onMessage(t["#"][2]) : null; case "s": switch (t["#"][1]) { case "c": e.pingInterval = setInterval(function() { - return e.missedPing++ > 2 ? e.disconnect(4001, "Did not get pings") : ""; + return e.missedPing++ > 2 ? e.disconnect(4001, "Did not get pings") : null; }, t["#"][2].ping), e.useBinary = t["#"][2].binary, e.events.emit("connect"); } } @@ -117,7 +117,7 @@ return t.events.emit("error", e.message); }, this.websocket.onmessage = function(n) { var o = n.data; - if (t.useBinary && "string" != typeof o && (o = String.fromCharCode.apply(null, new Uint8Array(o))), + if ("string" != typeof o && (o = String.fromCharCode.apply(null, new Uint8Array(o))), "#0" === o) return t.missedPing = 0, t.send("#1", null, "ping"); try { o = JSON.parse(o); @@ -130,7 +130,7 @@ !t.reconnection.inReconnectionState) { if (t.options.autoReconnect && 1e3 !== e.code) return t.reconnection.reconnect(); t.events.removeAllEvents(); - for (var n in t) t[n] && delete t[n]; + for (var n in t) t[n] && (t[n] = null); } }; }, e.prototype.on = function(e, t) { @@ -205,7 +205,7 @@ return e.prototype.isConnected = function() { clearTimeout(this.timer), clearInterval(this.interval), this.inReconnectionState = !1, this.reconnectionAttempted = 0; - for (var e in this.socket.channels) this.socket.channels.hasOwnProperty(e) && this.socket.channels[e].subscribe(); + for (var e in this.socket.channels) this.socket.channels[e] && this.socket.channels[e].subscribe(); }, e.prototype.reconnect = function() { var e = this; this.inReconnectionState = !0, this.interval = setInterval(function() { diff --git a/src/index.ts b/src/index.ts index 6456d41..60fa052 100644 --- a/src/index.ts +++ b/src/index.ts @@ -13,14 +13,14 @@ export class ClusterWS { return uint.buffer } - private static decode(socket: ClusterWS, message: TSocketMessage): any { + private static decode(socket: ClusterWS, message: TSocketMessage): null | void { switch (message['#'][0]) { case 'e': return socket.events.emit(message['#'][1], message['#'][2]) - case 'p': return socket.channels[message['#'][1]] ? socket.channels[message['#'][1]].onMessage(message['#'][2]) : '' + case 'p': return socket.channels[message['#'][1]] ? socket.channels[message['#'][1]].onMessage(message['#'][2]) : null case 's': switch (message['#'][1]) { case 'c': - socket.pingInterval = setInterval((): void | string => socket.missedPing++ > 2 ? socket.disconnect(4001, 'Did not get pings') : '', message['#'][2].ping) + socket.pingInterval = setInterval((): void | null => socket.missedPing++ > 2 ? socket.disconnect(4001, 'Did not get pings') : null, message['#'][2].ping) socket.useBinary = message['#'][2].binary socket.events.emit('connect') default: break @@ -81,7 +81,7 @@ export class ClusterWS { this.websocket.onerror = (err: TSocketMessage): void => this.events.emit('error', err.message) this.websocket.onmessage = (message: TSocketMessage): void => { let data: string = message.data - if (this.useBinary && typeof data !== 'string') data = String.fromCharCode.apply(null, new Uint8Array(data)) + if (typeof data !== 'string') data = String.fromCharCode.apply(null, new Uint8Array(data)) if (data === '#0') { this.missedPing = 0 return this.send('#1', null, 'ping') @@ -100,7 +100,7 @@ export class ClusterWS { if (this.options.autoReconnect && event.code !== 1000) return this.reconnection.reconnect() this.events.removeAllEvents() - for (const key in this) this[key] ? delete this[key] : null + for (const key in this) this[key] ? this[key] = null : null } } diff --git a/src/modules/reconnection.ts b/src/modules/reconnection.ts index 950a3b3..5fd03f7 100644 --- a/src/modules/reconnection.ts +++ b/src/modules/reconnection.ts @@ -18,7 +18,7 @@ export class Reconnection { this.inReconnectionState = false this.reconnectionAttempted = 0 - for (const key in this.socket.channels) this.socket.channels.hasOwnProperty(key) ? this.socket.channels[key].subscribe() : '' + for (const key in this.socket.channels) this.socket.channels[key] ? this.socket.channels[key].subscribe() : null } public reconnect(): void { From acfcb772e5276854c02da1e8a94a2d60c523bb80 Mon Sep 17 00:00:00 2001 From: Gobb Date: Fri, 29 Dec 2017 18:49:20 +0100 Subject: [PATCH 04/21] Fixing wrong typing for ClusterWS.subscribe(...) method. --- dist/index.d.ts | 2 +- src/index.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dist/index.d.ts b/dist/index.d.ts index 6578427..7c09167 100644 --- a/dist/index.d.ts +++ b/dist/index.d.ts @@ -10,7 +10,7 @@ export class ClusterWS { send(event: string, data: any, type?: string): void; disconnect(code?: number, msg?: any): void; getState(): number; - subscribe(channel: string): void; + subscribe(channel: string): Channel; getChannelByName(channelName: string): Channel; } diff --git a/src/index.ts b/src/index.ts index 60fa052..51d1dce 100644 --- a/src/index.ts +++ b/src/index.ts @@ -122,7 +122,7 @@ export class ClusterWS { return this.websocket.readyState } - public subscribe(channel: string): void { + public subscribe(channel: string): Channel { return this.channels[channel] ? this.channels[channel] : this.channels[channel] = new Channel(this, channel) From 6ffb1e1d19d90ce83e4d275db2078baa3ed5cff6 Mon Sep 17 00:00:00 2001 From: Dmitrii Goriunov Date: Sun, 31 Dec 2017 19:33:41 +1300 Subject: [PATCH 05/21] Move to rollup, change way we import library --- .builder/rollup.config.js | 74 +++++++ .builder/tsconfig.json | 10 + .builder/tslint.json | 118 +++++++++++ .gitignore | 5 +- dist/browser/ClusterWS.js | 351 ++++++++++++++------------------- dist/browser/ClusterWS.min.js | 2 +- dist/index.d.ts | 2 +- dist/index.js | 360 ++++++++++++++-------------------- dist/package.json | 3 +- package.json | 15 +- src/index.ts | 5 +- src/modules/channel.ts | 2 +- src/modules/reconnection.ts | 9 +- 13 files changed, 521 insertions(+), 435 deletions(-) create mode 100644 .builder/rollup.config.js create mode 100644 .builder/tsconfig.json create mode 100644 .builder/tslint.json diff --git a/.builder/rollup.config.js b/.builder/rollup.config.js new file mode 100644 index 0000000..823553f --- /dev/null +++ b/.builder/rollup.config.js @@ -0,0 +1,74 @@ +const fs = require('fs') +const path = require('path') +const rollup = require('rollup').rollup +const uglify = require('rollup-plugin-uglify') +const typescriptPlugin = require('rollup-plugin-typescript2') + + +const copyPlugin = function (options) { + return { + ongenerate() { + const targDir = path.dirname(options.targ); + if (!fs.existsSync(targDir)) { + fs.mkdirSync(targDir) + } + if (options.remove) { + let json = fs.readFileSync(options.src) + let parsed = JSON.parse(json) + options.remove.forEach(element => delete parsed[element]) + fs.writeFileSync(options.targ, JSON.stringify(parsed, null, '\t')) + } else { + fs.writeFileSync(options.targ, fs.readFileSync(options.src)) + } + } + } +} + +return rollup({ + input: './src/index.ts', + plugins: [ + typescriptPlugin({ + useTsconfigDeclarationDir: true, + tsconfig: './.builder/tsconfig.json', + cacheRoot: './.builder/cache', + tsconfigOverride: process.env.NPM ? { + compilerOptions: { declaration: true, declarationDir: '../src' } + } : {} + }), + uglify({ + mangle: true, + output: { + beautify: process.env.NPM || process.env.BEAUTY || false + } + }), + !process.env.NPM || copyPlugin({ + src: './package.json', + targ: './dist/package.json', + remove: ['devDependencies', 'scripts'] + }), + !process.env.NPM || copyPlugin({ + src: './README.md', + targ: './dist/README.md', + }), + !process.env.NPM || copyPlugin({ + src: './LICENSE', + targ: './dist/LICENSE', + }) + ] +}).then((bundle) => { + bundle.write({ format: process.env.NPM ? 'cjs' : 'iife', file: process.env.NPM ? './dist/index.js' : (process.env.BEAUTY ? './dist/browser/ClusterWS.js' : './dist/browser/ClusterWS.min.js'), name: 'ClusterWS' }).then(() => { + if (process.env.NPM) { + const dts = require('dts-bundle') + dts.bundle({ + externals: false, + referenceExternals: false, + name: "index", + main: './src/**/*.d.ts', + out: '../dist/index.d.ts', + removeSource: true, + outputAsModuleFolder: true, + emitOnIncludedFileNotFound: true + }) + } + }) +}) diff --git a/.builder/tsconfig.json b/.builder/tsconfig.json new file mode 100644 index 0000000..2fe3059 --- /dev/null +++ b/.builder/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "target": "es5", + "module": "commonjs", + "removeComments": true + }, + "include": [ + "../src/**/*.ts" + ] +} \ No newline at end of file diff --git a/.builder/tslint.json b/.builder/tslint.json new file mode 100644 index 0000000..2259cc9 --- /dev/null +++ b/.builder/tslint.json @@ -0,0 +1,118 @@ +{ + "extends": "tslint:recommended", + "rules": { + "no-unused-expression": false, + "eofline": false, + "ordered-imports": false, + "quotemark": [ + true, + "single" + ], + "no-console": [ + false + ], + "trailing-comma": [ + false + ], + "max-line-length": [true, 150], + "no-any": false, + "no-empty-interface": true, + "only-arrow-functions": [ + true, + "allow-declarations", + "allow-named-functions" + ], + "typedef": [ + true, + "call-signature", + "arrow-call-signature", + "parameter", + "arrow-parameter", + "property-declaration", + "variable-declaration", + "member-variable-declaration", + "object-destructuring", + "array-destructuring" + ], + "typedef-whitespace": [ + true, + { + "call-signature": "nospace", + "index-signature": "nospace", + "parameter": "nospace", + "property-declaration": "nospace", + "variable-declaration": "nospace" + }, + { + "call-signature": "onespace", + "index-signature": "onespace", + "parameter": "onespace", + "property-declaration": "onespace", + "variable-declaration": "onespace" + } + ], + "curly": [ + true, + "as-needed" + ], + "no-empty": [ + true, + "allow-empty-catch" + ], + "no-eval": true, + "no-var-keyword": true, + "cyclomatic-complexity": [ + true, + 20 + ], + "no-duplicate-imports": true, + "arrow-return-shorthand": [ + true, + "multiline" + ], + "class-name": true, + "import-spacing": true, + "jsdoc-format": true, + "newline-before-return": false, + "no-unnecessary-callback-wrapper": true, + "object-literal-shorthand": true, + "object-literal-key-quotes": [ + true, + "consistent" + ], + "number-literal-format": true, + "one-variable-per-declaration": [ + true, + "ignore-for-loop" + ], + "prefer-method-signature": true, + "prefer-switch": [ + true, + { + "min-cases": 2 + } + ], + "switch-final-break": [ + true, + "always" + ], + "whitespace": [ + true, + "check-branch", + "check-decl", + "check-operator", + "check-module", + "check-separator", + "check-rest-spread", + "check-type", + "check-typecast", + "check-type-operator", + "check-preblock" + ], + "prefer-const": true, + "semicolon": [ + true, + "never" + ] + } +} \ No newline at end of file diff --git a/.gitignore b/.gitignore index 3bcb4e6..8451e94 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,8 @@ - .npm .idea/ .vscode/ +.builder/cache/ node_modules/ -package-lock.json \ No newline at end of file +package-lock.json + diff --git a/dist/browser/ClusterWS.js b/dist/browser/ClusterWS.js index c497ffd..d3225e5 100644 --- a/dist/browser/ClusterWS.js +++ b/dist/browser/ClusterWS.js @@ -1,222 +1,159 @@ -!function(e, t) { - if ("object" == typeof exports && "object" == typeof module) module.exports = t(); else if ("function" == typeof define && define.amd) define([], t); else { - var n = t(); - for (var o in n) ("object" == typeof exports ? exports : e)[o] = n[o]; +var ClusterWS = function() { + "use strict"; + function t(t) { + return console.log(t); } -}("undefined" != typeof self ? self : this, function() { - return function(e) { - function t(o) { - if (n[o]) return n[o].exports; - var i = n[o] = { - i: o, - l: !1, - exports: {} - }; - return e[o].call(i.exports, i, i.exports, t), i.l = !0, i.exports; + var n = function() { + function n(t, n) { + this.socket = t, this.channel = n, this.subscribe(); } - var n = {}; - return t.m = e, t.c = n, t.d = function(e, n, o) { - t.o(e, n) || Object.defineProperty(e, n, { - configurable: !1, - enumerable: !0, - get: o - }); - }, t.n = function(e) { - var n = e && e.__esModule ? function() { - return e.default; - } : function() { - return e; - }; - return t.d(n, "a", n), n; - }, t.o = function(e, t) { - return Object.prototype.hasOwnProperty.call(e, t); - }, t.p = "", t(t.s = 1); - }([ function(e, t, n) { - "use strict"; - function o(e) { - return console.log(e); + return n.prototype.watch = function(n) { + return "[object Function]" !== {}.toString.call(n) ? t("Listener must be a function") : (this.listener = n, + this); + }, n.prototype.publish = function(t) { + return this.socket.send(this.channel, t, "publish"), this; + }, n.prototype.unsubscribe = function() { + this.socket.send("unsubscribe", this.channel, "system"), this.socket.channels[this.channel] = null; + }, n.prototype.onMessage = function(t) { + this.listener && this.listener.call(null, t); + }, n.prototype.subscribe = function() { + this.socket.send("subscribe", this.channel, "system"); + }, n; + }(), e = function() { + function n() { + this.events = {}; } - Object.defineProperty(t, "__esModule", { - value: !0 - }), t.logError = o; - }, function(e, t, n) { - "use strict"; - Object.defineProperty(t, "__esModule", { - value: !0 - }); - var o = n(2), i = n(3), r = n(4), s = n(0), c = function() { - function e(e) { - return this.channels = {}, this.missedPing = 0, this.events = new i.EventEmitter(), - this.useBinary = !1, e.url && "string" == typeof e.url ? (this.options = { - url: e.url, - autoReconnect: e.autoReconnect || !1, - reconnectionIntervalMin: e.reconnectionIntervalMin || 1e3, - reconnectionIntervalMax: e.reconnectionIntervalMax || 5e3, - reconnectionAttempts: e.reconnectionAttempts || 0 - }, this.options.reconnectionIntervalMin > this.options.reconnectionIntervalMax ? s.logError("reconnectionIntervalMin can not be more then reconnectionIntervalMax") : (this.reconnection = new r.Reconnection(this), - void this.create())) : s.logError("Url must be provided and it must be string"); - } - return e.buffer = function(e) { - for (var t = e.length, n = new Uint8Array(t), o = 0; o < t; o++) n[o] = e.charCodeAt(o); - return n.buffer; - }, e.decode = function(e, t) { - switch (t["#"][0]) { - case "e": - return e.events.emit(t["#"][1], t["#"][2]); + return n.prototype.on = function(n, e) { + if ("[object Function]" !== {}.toString.call(e)) return t("Listener must be a function"); + this.events[n] || (this.events[n] = e); + }, n.prototype.emit = function(t) { + for (var n = [], e = 1; e < arguments.length; e++) n[e - 1] = arguments[e]; + this.events[t] && (o = this.events[t]).call.apply(o, [ null ].concat(n)); + var o; + }, n.prototype.removeAllEvents = function() { + this.events = {}; + }, n; + }(), o = function() { + function t(t) { + this.socket = t, this.inReconnectionState = !1, this.reconnectionAttempted = 0, + this.autoReconnect = this.socket.options.autoReconnect; + } + return t.prototype.isConnected = function() { + clearTimeout(this.timer), clearInterval(this.interval), this.inReconnectionState = !1, + this.reconnectionAttempted = 0; + for (var t in this.socket.channels) this.socket.channels[t] && this.socket.channels[t].subscribe(); + }, t.prototype.reconnect = function() { + var t = this; + this.inReconnectionState = !0, this.interval = setInterval(function() { + t.socket.getState() === t.socket.websocket.CLOSED && (t.reconnectionAttempted++, + 0 !== t.socket.options.reconnectionAttempts && t.reconnectionAttempted >= t.socket.options.reconnectionAttempts && (clearInterval(t.interval), + t.autoReconnect = !1, t.inReconnectionState = !1), clearTimeout(t.timer), t.timer = setTimeout(function() { + return t.socket.create(); + }, Math.floor(Math.random() * (t.socket.options.reconnectionIntervalMax - t.socket.options.reconnectionIntervalMin + 1)))); + }, this.socket.options.reconnectionIntervalMin); + }, t; + }(); + return function() { + function i(n) { + return this.channels = {}, this.missedPing = 0, this.events = new e(), this.useBinary = !1, + n.url && "string" == typeof n.url ? (this.options = { + url: n.url, + autoReconnect: n.autoReconnect || !1, + reconnectionIntervalMin: n.reconnectionIntervalMin || 1e3, + reconnectionIntervalMax: n.reconnectionIntervalMax || 5e3, + reconnectionAttempts: n.reconnectionAttempts || 0 + }, this.options.reconnectionIntervalMin > this.options.reconnectionIntervalMax ? t("reconnectionIntervalMin can not be more then reconnectionIntervalMax") : (this.reconnection = new o(this), + void this.create())) : t("Url must be provided and it must be string"); + } + return i.buffer = function(t) { + for (var n = t.length, e = new Uint8Array(n), o = 0; o < n; o++) e[o] = t.charCodeAt(o); + return e.buffer; + }, i.decode = function(t, n) { + switch (n["#"][0]) { + case "e": + return t.events.emit(n["#"][1], n["#"][2]); - case "p": - return e.channels[t["#"][1]] ? e.channels[t["#"][1]].onMessage(t["#"][2]) : null; + case "p": + return t.channels[n["#"][1]] ? t.channels[n["#"][1]].onMessage(n["#"][2]) : null; - case "s": - switch (t["#"][1]) { - case "c": - e.pingInterval = setInterval(function() { - return e.missedPing++ > 2 ? e.disconnect(4001, "Did not get pings") : null; - }, t["#"][2].ping), e.useBinary = t["#"][2].binary, e.events.emit("connect"); - } + case "s": + switch (n["#"][1]) { + case "c": + t.pingInterval = setInterval(function() { + return t.missedPing++ > 2 ? t.disconnect(4001, "Did not get pings") : null; + }, n["#"][2].ping), t.useBinary = n["#"][2].binary, t.events.emit("connect"); } - }, e.encode = function(e, t, n) { - switch (n) { - case "ping": - return e; + } + }, i.encode = function(t, n, e) { + switch (e) { + case "ping": + return t; + + case "emit": + return JSON.stringify({ + "#": [ "e", t, n ] + }); - case "emit": + case "publish": + return JSON.stringify({ + "#": [ "p", t, n ] + }); + + case "system": + switch (t) { + case "subscribe": return JSON.stringify({ - "#": [ "e", e, t ] + "#": [ "s", "s", n ] }); - case "publish": + case "unsubscribe": return JSON.stringify({ - "#": [ "p", e, t ] + "#": [ "s", "u", n ] }); - case "system": - switch (e) { - case "subscribe": - return JSON.stringify({ - "#": [ "s", "s", t ] - }); - - case "unsubscribe": - return JSON.stringify({ - "#": [ "s", "u", t ] - }); - - case "configuration": - return JSON.stringify({ - "#": [ "s", "c", t ] - }); - } + case "configuration": + return JSON.stringify({ + "#": [ "s", "c", n ] + }); } - }, e.prototype.create = function() { - var t = this, n = window.MozWebSocket || window.WebSocket; - this.websocket = new n(this.options.url), this.websocket.binaryType = "arraybuffer", - this.websocket.onopen = function() { - return t.reconnection.isConnected(); - }, this.websocket.onerror = function(e) { - return t.events.emit("error", e.message); - }, this.websocket.onmessage = function(n) { - var o = n.data; - if ("string" != typeof o && (o = String.fromCharCode.apply(null, new Uint8Array(o))), - "#0" === o) return t.missedPing = 0, t.send("#1", null, "ping"); - try { - o = JSON.parse(o); - } catch (e) { - return s.logError(e); - } - e.decode(t, o); - }, this.websocket.onclose = function(e) { - if (t.missedPing = 0, clearInterval(t.pingInterval), t.events.emit("disconnect", e.code, e.reason), - !t.reconnection.inReconnectionState) { - if (t.options.autoReconnect && 1e3 !== e.code) return t.reconnection.reconnect(); - t.events.removeAllEvents(); - for (var n in t) t[n] && (t[n] = null); - } - }; - }, e.prototype.on = function(e, t) { - this.events.on(e, t); - }, e.prototype.send = function(t, n, o) { - void 0 === o && (o = "emit"), this.websocket.send(this.useBinary ? e.buffer(e.encode(t, n, o)) : e.encode(t, n, o)); - }, e.prototype.disconnect = function(e, t) { - this.websocket.close(e || 1e3, t); - }, e.prototype.getState = function() { - return this.websocket.readyState; - }, e.prototype.subscribe = function(e) { - return this.channels[e] ? this.channels[e] : this.channels[e] = new o.Channel(this, e); - }, e.prototype.getChannelByName = function(e) { - return this.channels[e]; - }, e; - }(); - t.ClusterWS = c; - }, function(e, t, n) { - "use strict"; - Object.defineProperty(t, "__esModule", { - value: !0 - }); - var o = n(0), i = function() { - function e(e, t) { - this.socket = e, this.channel = t, this.subscribe(); - } - return e.prototype.watch = function(e) { - return "[object Function]" !== {}.toString.call(e) ? o.logError("Listener must be a function") : (this.listener = e, - this); - }, e.prototype.publish = function(e) { - return this.socket.send(this.channel, e, "publish"), this; - }, e.prototype.unsubscribe = function() { - this.socket.send("unsubscribe", this.channel, "system"), this.socket.channels[this.channel] = null; - }, e.prototype.onMessage = function(e) { - this.listener && this.listener.call(null, e); - }, e.prototype.subscribe = function() { - this.socket.send("subscribe", this.channel, "system"); - }, e; - }(); - t.Channel = i; - }, function(e, t, n) { - "use strict"; - Object.defineProperty(t, "__esModule", { - value: !0 - }); - var o = n(0), i = function() { - function e() { - this.events = {}; } - return e.prototype.on = function(e, t) { - if ("[object Function]" !== {}.toString.call(t)) return o.logError("Listener must be a function"); - this.events[e] || (this.events[e] = t); - }, e.prototype.emit = function(e) { - for (var t = [], n = 1; n < arguments.length; n++) t[n - 1] = arguments[n]; - this.events[e] && (o = this.events[e]).call.apply(o, [ null ].concat(t)); - var o; - }, e.prototype.removeAllEvents = function() { - this.events = {}; - }, e; - }(); - t.EventEmitter = i; - }, function(e, t, n) { - "use strict"; - Object.defineProperty(t, "__esModule", { - value: !0 - }); - var o = function() { - function e(e) { - this.socket = e, this.inReconnectionState = !1, this.reconnectionAttempted = 0, - this.autoReconnect = this.socket.options.autoReconnect; - } - return e.prototype.isConnected = function() { - clearTimeout(this.timer), clearInterval(this.interval), this.inReconnectionState = !1, - this.reconnectionAttempted = 0; - for (var e in this.socket.channels) this.socket.channels[e] && this.socket.channels[e].subscribe(); - }, e.prototype.reconnect = function() { - var e = this; - this.inReconnectionState = !0, this.interval = setInterval(function() { - e.socket.getState() === e.socket.websocket.CLOSED && (e.reconnectionAttempted++, - 0 !== e.socket.options.reconnectionAttempts && e.reconnectionAttempted >= e.socket.options.reconnectionAttempts && (clearInterval(e.interval), - e.autoReconnect = !1, e.inReconnectionState = !1), clearTimeout(e.timer), e.timer = setTimeout(function() { - return e.socket.create(); - }, Math.floor(Math.random() * (e.socket.options.reconnectionIntervalMax - e.socket.options.reconnectionIntervalMin + 1)))); - }, this.socket.options.reconnectionIntervalMin); - }, e; - }(); - t.Reconnection = o; - } ]); -}); \ No newline at end of file + }, i.prototype.create = function() { + var n = this, e = window.MozWebSocket || window.WebSocket; + this.websocket = new e(this.options.url), this.websocket.binaryType = "arraybuffer", + this.websocket.onopen = function() { + return n.reconnection.isConnected(); + }, this.websocket.onerror = function(t) { + return n.events.emit("error", t.message); + }, this.websocket.onmessage = function(e) { + var o = e.data; + if ("string" != typeof o && (o = String.fromCharCode.apply(null, new Uint8Array(o))), + "#0" === o) return n.missedPing = 0, n.send("#1", null, "ping"); + try { + o = JSON.parse(o); + } catch (n) { + return t(n); + } + i.decode(n, o); + }, this.websocket.onclose = function(t) { + if (n.missedPing = 0, clearInterval(n.pingInterval), n.events.emit("disconnect", t.code, t.reason), + !n.reconnection.inReconnectionState) { + if (n.options.autoReconnect && 1e3 !== t.code) return n.reconnection.reconnect(); + n.events.removeAllEvents(); + for (var e in n) n[e] && (n[e] = null); + } + }; + }, i.prototype.on = function(t, n) { + this.events.on(t, n); + }, i.prototype.send = function(t, n, e) { + void 0 === e && (e = "emit"), this.websocket.send(this.useBinary ? i.buffer(i.encode(t, n, e)) : i.encode(t, n, e)); + }, i.prototype.disconnect = function(t, n) { + this.websocket.close(t || 1e3, n); + }, i.prototype.getState = function() { + return this.websocket.readyState; + }, i.prototype.subscribe = function(t) { + return this.channels[t] ? this.channels[t] : this.channels[t] = new n(this, t); + }, i.prototype.getChannelByName = function(t) { + return this.channels[t]; + }, i; + }(); +}(); diff --git a/dist/browser/ClusterWS.min.js b/dist/browser/ClusterWS.min.js index 2e53b32..a45c38a 100644 --- a/dist/browser/ClusterWS.min.js +++ b/dist/browser/ClusterWS.min.js @@ -1 +1 @@ -!function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var n=t();for(var o in n)("object"==typeof exports?exports:e)[o]=n[o]}}("undefined"!=typeof self?self:this,function(){return function(e){function t(o){if(n[o])return n[o].exports;var i=n[o]={i:o,l:!1,exports:{}};return e[o].call(i.exports,i,i.exports,t),i.l=!0,i.exports}var n={};return t.m=e,t.c=n,t.d=function(e,n,o){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:o})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=1)}([function(e,t,n){"use strict";function o(e){return console.log(e)}Object.defineProperty(t,"__esModule",{value:!0}),t.logError=o},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=n(2),i=n(3),r=n(4),s=n(0);t.ClusterWS=function(){function e(e){return this.channels={},this.missedPing=0,this.events=new i.EventEmitter,this.useBinary=!1,e.url&&"string"==typeof e.url?(this.options={url:e.url,autoReconnect:e.autoReconnect||!1,reconnectionIntervalMin:e.reconnectionIntervalMin||1e3,reconnectionIntervalMax:e.reconnectionIntervalMax||5e3,reconnectionAttempts:e.reconnectionAttempts||0},this.options.reconnectionIntervalMin>this.options.reconnectionIntervalMax?s.logError("reconnectionIntervalMin can not be more then reconnectionIntervalMax"):(this.reconnection=new r.Reconnection(this),void this.create())):s.logError("Url must be provided and it must be string")}return e.buffer=function(e){for(var t=e.length,n=new Uint8Array(t),o=0;t>o;o++)n[o]=e.charCodeAt(o);return n.buffer},e.decode=function(e,t){switch(t["#"][0]){case"e":return e.events.emit(t["#"][1],t["#"][2]);case"p":return e.channels[t["#"][1]]?e.channels[t["#"][1]].onMessage(t["#"][2]):null;case"s":switch(t["#"][1]){case"c":e.pingInterval=setInterval(function(){return e.missedPing++>2?e.disconnect(4001,"Did not get pings"):null},t["#"][2].ping),e.useBinary=t["#"][2].binary,e.events.emit("connect")}}},e.encode=function(e,t,n){switch(n){case"ping":return e;case"emit":return JSON.stringify({"#":["e",e,t]});case"publish":return JSON.stringify({"#":["p",e,t]});case"system":switch(e){case"subscribe":return JSON.stringify({"#":["s","s",t]});case"unsubscribe":return JSON.stringify({"#":["s","u",t]});case"configuration":return JSON.stringify({"#":["s","c",t]})}}},e.prototype.create=function(){var t=this;this.websocket=new(window.MozWebSocket||window.WebSocket)(this.options.url),this.websocket.binaryType="arraybuffer",this.websocket.onopen=function(){return t.reconnection.isConnected()},this.websocket.onerror=function(e){return t.events.emit("error",e.message)},this.websocket.onmessage=function(n){var o=n.data;if("string"!=typeof o&&(o=String.fromCharCode.apply(null,new Uint8Array(o))),"#0"===o)return t.missedPing=0,t.send("#1",null,"ping");try{o=JSON.parse(o)}catch(e){return s.logError(e)}e.decode(t,o)},this.websocket.onclose=function(e){if(t.missedPing=0,clearInterval(t.pingInterval),t.events.emit("disconnect",e.code,e.reason),!t.reconnection.inReconnectionState){if(t.options.autoReconnect&&1e3!==e.code)return t.reconnection.reconnect();t.events.removeAllEvents();for(var n in t)t[n]&&(t[n]=null)}}},e.prototype.on=function(e,t){this.events.on(e,t)},e.prototype.send=function(t,n,o){void 0===o&&(o="emit"),this.websocket.send(this.useBinary?e.buffer(e.encode(t,n,o)):e.encode(t,n,o))},e.prototype.disconnect=function(e,t){this.websocket.close(e||1e3,t)},e.prototype.getState=function(){return this.websocket.readyState},e.prototype.subscribe=function(e){return this.channels[e]?this.channels[e]:this.channels[e]=new o.Channel(this,e)},e.prototype.getChannelByName=function(e){return this.channels[e]},e}()},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=n(0);t.Channel=function(){function e(e,t){this.socket=e,this.channel=t,this.subscribe()}return e.prototype.watch=function(e){return"[object Function]"!=={}.toString.call(e)?o.logError("Listener must be a function"):(this.listener=e,this)},e.prototype.publish=function(e){return this.socket.send(this.channel,e,"publish"),this},e.prototype.unsubscribe=function(){this.socket.send("unsubscribe",this.channel,"system"),this.socket.channels[this.channel]=null},e.prototype.onMessage=function(e){this.listener&&this.listener.call(null,e)},e.prototype.subscribe=function(){this.socket.send("subscribe",this.channel,"system")},e}()},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=n(0);t.EventEmitter=function(){function e(){this.events={}}return e.prototype.on=function(e,t){if("[object Function]"!=={}.toString.call(t))return o.logError("Listener must be a function");this.events[e]||(this.events[e]=t)},e.prototype.emit=function(e){for(var t=[],n=1;arguments.length>n;n++)t[n-1]=arguments[n];this.events[e]&&(o=this.events[e]).call.apply(o,[null].concat(t));var o},e.prototype.removeAllEvents=function(){this.events={}},e}()},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Reconnection=function(){function e(e){this.socket=e,this.inReconnectionState=!1,this.reconnectionAttempted=0,this.autoReconnect=this.socket.options.autoReconnect}return e.prototype.isConnected=function(){clearTimeout(this.timer),clearInterval(this.interval),this.inReconnectionState=!1,this.reconnectionAttempted=0;for(var e in this.socket.channels)this.socket.channels[e]&&this.socket.channels[e].subscribe()},e.prototype.reconnect=function(){var e=this;this.inReconnectionState=!0,this.interval=setInterval(function(){e.socket.getState()===e.socket.websocket.CLOSED&&(e.reconnectionAttempted++,0===e.socket.options.reconnectionAttempts||e.socket.options.reconnectionAttempts>e.reconnectionAttempted||(clearInterval(e.interval),e.autoReconnect=!1,e.inReconnectionState=!1),clearTimeout(e.timer),e.timer=setTimeout(function(){return e.socket.create()},Math.floor(Math.random()*(e.socket.options.reconnectionIntervalMax-e.socket.options.reconnectionIntervalMin+1))))},this.socket.options.reconnectionIntervalMin)},e}()}])}); \ No newline at end of file +var ClusterWS=function(){"use strict";function t(t){return console.log(t)}var n=function(){function n(t,n){this.socket=t,this.channel=n,this.subscribe()}return n.prototype.watch=function(n){return"[object Function]"!=={}.toString.call(n)?t("Listener must be a function"):(this.listener=n,this)},n.prototype.publish=function(t){return this.socket.send(this.channel,t,"publish"),this},n.prototype.unsubscribe=function(){this.socket.send("unsubscribe",this.channel,"system"),this.socket.channels[this.channel]=null},n.prototype.onMessage=function(t){this.listener&&this.listener.call(null,t)},n.prototype.subscribe=function(){this.socket.send("subscribe",this.channel,"system")},n}(),e=function(){function n(){this.events={}}return n.prototype.on=function(n,e){if("[object Function]"!=={}.toString.call(e))return t("Listener must be a function");this.events[n]||(this.events[n]=e)},n.prototype.emit=function(t){for(var n=[],e=1;e=t.socket.options.reconnectionAttempts&&(clearInterval(t.interval),t.autoReconnect=!1,t.inReconnectionState=!1),clearTimeout(t.timer),t.timer=setTimeout(function(){return t.socket.create()},Math.floor(Math.random()*(t.socket.options.reconnectionIntervalMax-t.socket.options.reconnectionIntervalMin+1))))},this.socket.options.reconnectionIntervalMin)},t}();return function(){function i(n){return this.channels={},this.missedPing=0,this.events=new e,this.useBinary=!1,n.url&&"string"==typeof n.url?(this.options={url:n.url,autoReconnect:n.autoReconnect||!1,reconnectionIntervalMin:n.reconnectionIntervalMin||1e3,reconnectionIntervalMax:n.reconnectionIntervalMax||5e3,reconnectionAttempts:n.reconnectionAttempts||0},this.options.reconnectionIntervalMin>this.options.reconnectionIntervalMax?t("reconnectionIntervalMin can not be more then reconnectionIntervalMax"):(this.reconnection=new o(this),void this.create())):t("Url must be provided and it must be string")}return i.buffer=function(t){for(var n=t.length,e=new Uint8Array(n),o=0;o2?t.disconnect(4001,"Did not get pings"):null},n["#"][2].ping),t.useBinary=n["#"][2].binary,t.events.emit("connect")}}},i.encode=function(t,n,e){switch(e){case"ping":return t;case"emit":return JSON.stringify({"#":["e",t,n]});case"publish":return JSON.stringify({"#":["p",t,n]});case"system":switch(t){case"subscribe":return JSON.stringify({"#":["s","s",n]});case"unsubscribe":return JSON.stringify({"#":["s","u",n]});case"configuration":return JSON.stringify({"#":["s","c",n]})}}},i.prototype.create=function(){var n=this,e=window.MozWebSocket||window.WebSocket;this.websocket=new e(this.options.url),this.websocket.binaryType="arraybuffer",this.websocket.onopen=function(){return n.reconnection.isConnected()},this.websocket.onerror=function(t){return n.events.emit("error",t.message)},this.websocket.onmessage=function(e){var o=e.data;if("string"!=typeof o&&(o=String.fromCharCode.apply(null,new Uint8Array(o))),"#0"===o)return n.missedPing=0,n.send("#1",null,"ping");try{o=JSON.parse(o)}catch(n){return t(n)}i.decode(n,o)},this.websocket.onclose=function(t){if(n.missedPing=0,clearInterval(n.pingInterval),n.events.emit("disconnect",t.code,t.reason),!n.reconnection.inReconnectionState){if(n.options.autoReconnect&&1e3!==t.code)return n.reconnection.reconnect();n.events.removeAllEvents();for(var e in n)n[e]&&(n[e]=null)}}},i.prototype.on=function(t,n){this.events.on(t,n)},i.prototype.send=function(t,n,e){void 0===e&&(e="emit"),this.websocket.send(this.useBinary?i.buffer(i.encode(t,n,e)):i.encode(t,n,e))},i.prototype.disconnect=function(t,n){this.websocket.close(t||1e3,n)},i.prototype.getState=function(){return this.websocket.readyState},i.prototype.subscribe=function(t){return this.channels[t]?this.channels[t]:this.channels[t]=new n(this,t)},i.prototype.getChannelByName=function(t){return this.channels[t]},i}()}(); diff --git a/dist/index.d.ts b/dist/index.d.ts index 7c09167..9bba2da 100644 --- a/dist/index.d.ts +++ b/dist/index.d.ts @@ -1,6 +1,6 @@ // Generated by dts-bundle v0.7.3 -export class ClusterWS { +export default class ClusterWS { options: IOptions; channels: IObject; websocket: WebSocket; diff --git a/dist/index.js b/dist/index.js index c497ffd..9b08284 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1,222 +1,160 @@ -!function(e, t) { - if ("object" == typeof exports && "object" == typeof module) module.exports = t(); else if ("function" == typeof define && define.amd) define([], t); else { - var n = t(); - for (var o in n) ("object" == typeof exports ? exports : e)[o] = n[o]; +"use strict"; + +function logError(t) { + return console.log(t); +} + +var Channel = function() { + function t(t, e) { + this.socket = t, this.channel = e, this.subscribe(); } -}("undefined" != typeof self ? self : this, function() { - return function(e) { - function t(o) { - if (n[o]) return n[o].exports; - var i = n[o] = { - i: o, - l: !1, - exports: {} - }; - return e[o].call(i.exports, i, i.exports, t), i.l = !0, i.exports; - } - var n = {}; - return t.m = e, t.c = n, t.d = function(e, n, o) { - t.o(e, n) || Object.defineProperty(e, n, { - configurable: !1, - enumerable: !0, - get: o - }); - }, t.n = function(e) { - var n = e && e.__esModule ? function() { - return e.default; - } : function() { - return e; - }; - return t.d(n, "a", n), n; - }, t.o = function(e, t) { - return Object.prototype.hasOwnProperty.call(e, t); - }, t.p = "", t(t.s = 1); - }([ function(e, t, n) { - "use strict"; - function o(e) { - return console.log(e); - } - Object.defineProperty(t, "__esModule", { - value: !0 - }), t.logError = o; - }, function(e, t, n) { - "use strict"; - Object.defineProperty(t, "__esModule", { - value: !0 - }); - var o = n(2), i = n(3), r = n(4), s = n(0), c = function() { - function e(e) { - return this.channels = {}, this.missedPing = 0, this.events = new i.EventEmitter(), - this.useBinary = !1, e.url && "string" == typeof e.url ? (this.options = { - url: e.url, - autoReconnect: e.autoReconnect || !1, - reconnectionIntervalMin: e.reconnectionIntervalMin || 1e3, - reconnectionIntervalMax: e.reconnectionIntervalMax || 5e3, - reconnectionAttempts: e.reconnectionAttempts || 0 - }, this.options.reconnectionIntervalMin > this.options.reconnectionIntervalMax ? s.logError("reconnectionIntervalMin can not be more then reconnectionIntervalMax") : (this.reconnection = new r.Reconnection(this), - void this.create())) : s.logError("Url must be provided and it must be string"); - } - return e.buffer = function(e) { - for (var t = e.length, n = new Uint8Array(t), o = 0; o < t; o++) n[o] = e.charCodeAt(o); - return n.buffer; - }, e.decode = function(e, t) { - switch (t["#"][0]) { - case "e": - return e.events.emit(t["#"][1], t["#"][2]); + 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.channel, t, "publish"), this; + }, t.prototype.unsubscribe = function() { + this.socket.send("unsubscribe", this.channel, "system"), this.socket.channels[this.channel] = null; + }, t.prototype.onMessage = function(t) { + this.listener && this.listener.call(null, t); + }, t.prototype.subscribe = function() { + this.socket.send("subscribe", this.channel, "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] || (this.events[t] = e); + }, t.prototype.emit = function(t) { + for (var e = [], n = 1; n < arguments.length; n++) e[n - 1] = arguments[n]; + this.events[t] && (o = this.events[t]).call.apply(o, [ null ].concat(e)); + var o; + }, t.prototype.removeAllEvents = function() { + this.events = {}; + }, t; +}(), Reconnection = function() { + function t(t) { + this.socket = t, this.inReconnectionState = !1, this.reconnectionAttempted = 0, + this.autoReconnect = this.socket.options.autoReconnect; + } + return t.prototype.isConnected = function() { + clearTimeout(this.timer), clearInterval(this.interval), this.inReconnectionState = !1, + this.reconnectionAttempted = 0; + for (var t in this.socket.channels) this.socket.channels[t] && this.socket.channels[t].subscribe(); + }, t.prototype.reconnect = function() { + var t = this; + this.inReconnectionState = !0, this.interval = setInterval(function() { + t.socket.getState() === t.socket.websocket.CLOSED && (t.reconnectionAttempted++, + 0 !== t.socket.options.reconnectionAttempts && t.reconnectionAttempted >= t.socket.options.reconnectionAttempts && (clearInterval(t.interval), + t.autoReconnect = !1, t.inReconnectionState = !1), clearTimeout(t.timer), t.timer = setTimeout(function() { + return t.socket.create(); + }, Math.floor(Math.random() * (t.socket.options.reconnectionIntervalMax - t.socket.options.reconnectionIntervalMin + 1)))); + }, this.socket.options.reconnectionIntervalMin); + }, t; +}(), ClusterWS = function() { + function t(t) { + return this.channels = {}, this.missedPing = 0, this.events = new EventEmitter(), + this.useBinary = !1, t.url && "string" == typeof t.url ? (this.options = { + url: t.url, + autoReconnect: t.autoReconnect || !1, + reconnectionIntervalMin: t.reconnectionIntervalMin || 1e3, + reconnectionIntervalMax: t.reconnectionIntervalMax || 5e3, + reconnectionAttempts: t.reconnectionAttempts || 0 + }, this.options.reconnectionIntervalMin > this.options.reconnectionIntervalMax ? logError("reconnectionIntervalMin can not be more then reconnectionIntervalMax") : (this.reconnection = new Reconnection(this), + void this.create())) : logError("Url must be provided and it must be string"); + } + return t.buffer = function(t) { + for (var e = t.length, n = new Uint8Array(e), o = 0; o < e; o++) n[o] = t.charCodeAt(o); + return n.buffer; + }, t.decode = function(t, e) { + switch (e["#"][0]) { + case "e": + return t.events.emit(e["#"][1], e["#"][2]); - case "p": - return e.channels[t["#"][1]] ? e.channels[t["#"][1]].onMessage(t["#"][2]) : null; + case "p": + return t.channels[e["#"][1]] ? t.channels[e["#"][1]].onMessage(e["#"][2]) : null; - case "s": - switch (t["#"][1]) { - case "c": - e.pingInterval = setInterval(function() { - return e.missedPing++ > 2 ? e.disconnect(4001, "Did not get pings") : null; - }, t["#"][2].ping), e.useBinary = t["#"][2].binary, e.events.emit("connect"); - } - } - }, e.encode = function(e, t, n) { - switch (n) { - case "ping": - return e; + case "s": + switch (e["#"][1]) { + case "c": + t.pingInterval = setInterval(function() { + return t.missedPing++ > 2 ? t.disconnect(4001, "Did not get pings") : null; + }, e["#"][2].ping), t.useBinary = e["#"][2].binary, t.events.emit("connect"); + } + } + }, t.encode = function(t, e, n) { + switch (n) { + case "ping": + return t; - case "emit": - return JSON.stringify({ - "#": [ "e", e, t ] - }); + case "emit": + return JSON.stringify({ + "#": [ "e", t, e ] + }); - case "publish": - return JSON.stringify({ - "#": [ "p", e, t ] - }); + case "publish": + return JSON.stringify({ + "#": [ "p", t, e ] + }); - case "system": - switch (e) { - case "subscribe": - return JSON.stringify({ - "#": [ "s", "s", t ] - }); + case "system": + switch (t) { + case "subscribe": + return JSON.stringify({ + "#": [ "s", "s", e ] + }); - case "unsubscribe": - return JSON.stringify({ - "#": [ "s", "u", t ] - }); + case "unsubscribe": + return JSON.stringify({ + "#": [ "s", "u", e ] + }); - case "configuration": - return JSON.stringify({ - "#": [ "s", "c", t ] - }); - } - } - }, e.prototype.create = function() { - var t = this, n = window.MozWebSocket || window.WebSocket; - this.websocket = new n(this.options.url), this.websocket.binaryType = "arraybuffer", - this.websocket.onopen = function() { - return t.reconnection.isConnected(); - }, this.websocket.onerror = function(e) { - return t.events.emit("error", e.message); - }, this.websocket.onmessage = function(n) { - var o = n.data; - if ("string" != typeof o && (o = String.fromCharCode.apply(null, new Uint8Array(o))), - "#0" === o) return t.missedPing = 0, t.send("#1", null, "ping"); - try { - o = JSON.parse(o); - } catch (e) { - return s.logError(e); - } - e.decode(t, o); - }, this.websocket.onclose = function(e) { - if (t.missedPing = 0, clearInterval(t.pingInterval), t.events.emit("disconnect", e.code, e.reason), - !t.reconnection.inReconnectionState) { - if (t.options.autoReconnect && 1e3 !== e.code) return t.reconnection.reconnect(); - t.events.removeAllEvents(); - for (var n in t) t[n] && (t[n] = null); - } - }; - }, e.prototype.on = function(e, t) { - this.events.on(e, t); - }, e.prototype.send = function(t, n, o) { - void 0 === o && (o = "emit"), this.websocket.send(this.useBinary ? e.buffer(e.encode(t, n, o)) : e.encode(t, n, o)); - }, e.prototype.disconnect = function(e, t) { - this.websocket.close(e || 1e3, t); - }, e.prototype.getState = function() { - return this.websocket.readyState; - }, e.prototype.subscribe = function(e) { - return this.channels[e] ? this.channels[e] : this.channels[e] = new o.Channel(this, e); - }, e.prototype.getChannelByName = function(e) { - return this.channels[e]; - }, e; - }(); - t.ClusterWS = c; - }, function(e, t, n) { - "use strict"; - Object.defineProperty(t, "__esModule", { - value: !0 - }); - var o = n(0), i = function() { - function e(e, t) { - this.socket = e, this.channel = t, this.subscribe(); + case "configuration": + return JSON.stringify({ + "#": [ "s", "c", e ] + }); } - return e.prototype.watch = function(e) { - return "[object Function]" !== {}.toString.call(e) ? o.logError("Listener must be a function") : (this.listener = e, - this); - }, e.prototype.publish = function(e) { - return this.socket.send(this.channel, e, "publish"), this; - }, e.prototype.unsubscribe = function() { - this.socket.send("unsubscribe", this.channel, "system"), this.socket.channels[this.channel] = null; - }, e.prototype.onMessage = function(e) { - this.listener && this.listener.call(null, e); - }, e.prototype.subscribe = function() { - this.socket.send("subscribe", this.channel, "system"); - }, e; - }(); - t.Channel = i; - }, function(e, t, n) { - "use strict"; - Object.defineProperty(t, "__esModule", { - value: !0 - }); - var o = n(0), i = function() { - function e() { - this.events = {}; + } + }, t.prototype.create = function() { + var e = this, n = window.MozWebSocket || window.WebSocket; + this.websocket = new n(this.options.url), this.websocket.binaryType = "arraybuffer", + this.websocket.onopen = function() { + return e.reconnection.isConnected(); + }, this.websocket.onerror = function(t) { + return e.events.emit("error", t.message); + }, this.websocket.onmessage = function(n) { + var o = n.data; + if ("string" != typeof o && (o = String.fromCharCode.apply(null, new Uint8Array(o))), + "#0" === o) return e.missedPing = 0, e.send("#1", null, "ping"); + try { + o = JSON.parse(o); + } catch (t) { + return logError(t); } - return e.prototype.on = function(e, t) { - if ("[object Function]" !== {}.toString.call(t)) return o.logError("Listener must be a function"); - this.events[e] || (this.events[e] = t); - }, e.prototype.emit = function(e) { - for (var t = [], n = 1; n < arguments.length; n++) t[n - 1] = arguments[n]; - this.events[e] && (o = this.events[e]).call.apply(o, [ null ].concat(t)); - var o; - }, e.prototype.removeAllEvents = function() { - this.events = {}; - }, e; - }(); - t.EventEmitter = i; - }, function(e, t, n) { - "use strict"; - Object.defineProperty(t, "__esModule", { - value: !0 - }); - var o = function() { - function e(e) { - this.socket = e, this.inReconnectionState = !1, this.reconnectionAttempted = 0, - this.autoReconnect = this.socket.options.autoReconnect; + t.decode(e, o); + }, this.websocket.onclose = function(t) { + if (e.missedPing = 0, clearInterval(e.pingInterval), e.events.emit("disconnect", t.code, t.reason), + !e.reconnection.inReconnectionState) { + if (e.options.autoReconnect && 1e3 !== t.code) return e.reconnection.reconnect(); + e.events.removeAllEvents(); + for (var n in e) e[n] && (e[n] = null); } - return e.prototype.isConnected = function() { - clearTimeout(this.timer), clearInterval(this.interval), this.inReconnectionState = !1, - this.reconnectionAttempted = 0; - for (var e in this.socket.channels) this.socket.channels[e] && this.socket.channels[e].subscribe(); - }, e.prototype.reconnect = function() { - var e = this; - this.inReconnectionState = !0, this.interval = setInterval(function() { - e.socket.getState() === e.socket.websocket.CLOSED && (e.reconnectionAttempted++, - 0 !== e.socket.options.reconnectionAttempts && e.reconnectionAttempted >= e.socket.options.reconnectionAttempts && (clearInterval(e.interval), - e.autoReconnect = !1, e.inReconnectionState = !1), clearTimeout(e.timer), e.timer = setTimeout(function() { - return e.socket.create(); - }, Math.floor(Math.random() * (e.socket.options.reconnectionIntervalMax - e.socket.options.reconnectionIntervalMin + 1)))); - }, this.socket.options.reconnectionIntervalMin); - }, e; - }(); - t.Reconnection = o; - } ]); -}); \ No newline at end of file + }; + }, t.prototype.on = function(t, e) { + this.events.on(t, e); + }, t.prototype.send = function(e, n, o) { + void 0 === o && (o = "emit"), this.websocket.send(this.useBinary ? t.buffer(t.encode(e, n, o)) : t.encode(e, n, o)); + }, t.prototype.disconnect = function(t, e) { + this.websocket.close(t || 1e3, e); + }, t.prototype.getState = function() { + return this.websocket.readyState; + }, 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; +}(); + +module.exports = ClusterWS; diff --git a/dist/package.json b/dist/package.json index 919699d..cd2ae79 100644 --- a/dist/package.json +++ b/dist/package.json @@ -8,6 +8,5 @@ "repository": { "type": "git", "url": "https://github.com/ClusterWS/ClusterWS-Client-JS" - }, - "types": "./index.d.ts" + } } \ No newline at end of file diff --git a/package.json b/package.json index 571c405..af2b6f9 100644 --- a/package.json +++ b/package.json @@ -5,9 +5,10 @@ "main": "index.js", "author": "Dmitrii Goriunov ", "scripts": { - "build": "ts-builder --client", - "build:watch": "ts-builder --client --watch", - "build:prod": "ts-builder --client --prod", + "lint": "tslint -c ./.builder/tslint.json ./src/**/*.ts", + "build:npm": "npm run lint && cross-env NPM=true node ./.builder/rollup.config.js", + "build:browser": "npm run lint && cross-env BEAUTY=true node ./.builder/rollup.config.js && node ./.builder/rollup.config.js ", + "build:prod": "npm run build:npm && npm run build:browser", "publish": "npm run build:prod && cd dist && npm publish && cd .." }, "license": "MIT", @@ -16,6 +17,12 @@ "url": "https://github.com/ClusterWS/ClusterWS-Client-JS" }, "devDependencies": { - "ts-builder": "^0.2.20" + "cross-env": "^5.1.3", + "dts-bundle": "^0.7.3", + "rollup": "^0.53.1", + "rollup-plugin-typescript2": "^0.9.0", + "rollup-plugin-uglify": "^2.0.1", + "tslint": "^5.8.0", + "typescript": "^2.6.2" } } \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 51d1dce..4c0af04 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,7 +5,7 @@ import { IObject, TSocketMessage, TListener, IUserOptions, IOptions, logError } declare const window: any -export class ClusterWS { +export default class ClusterWS { private static buffer(str: string): ByteString { const length: number = str.length const uint: any = new Uint8Array(length) @@ -20,7 +20,8 @@ export class ClusterWS { case 's': switch (message['#'][1]) { case 'c': - socket.pingInterval = setInterval((): void | null => socket.missedPing++ > 2 ? socket.disconnect(4001, 'Did not get pings') : null, message['#'][2].ping) + socket.pingInterval = setInterval((): void | null => socket.missedPing++ > 2 ? + socket.disconnect(4001, 'Did not get pings') : null, message['#'][2].ping) socket.useBinary = message['#'][2].binary socket.events.emit('connect') default: break diff --git a/src/modules/channel.ts b/src/modules/channel.ts index d3c6069..999b9a6 100644 --- a/src/modules/channel.ts +++ b/src/modules/channel.ts @@ -1,4 +1,4 @@ -import { ClusterWS } from '../index' +import ClusterWS from '../index' import { TListener, logError } from '../utils/utils' export class Channel { diff --git a/src/modules/reconnection.ts b/src/modules/reconnection.ts index 5fd03f7..5ccaa2b 100644 --- a/src/modules/reconnection.ts +++ b/src/modules/reconnection.ts @@ -1,11 +1,11 @@ -import { ClusterWS } from '../index' +import ClusterWS from '../index' export class Reconnection { public inReconnectionState: boolean = false private reconnectionAttempted: number = 0 private autoReconnect: boolean - private interval: NodeJS.Timer - private timer: NodeJS.Timer + private interval: any + private timer: any constructor(public socket: ClusterWS) { this.autoReconnect = this.socket.options.autoReconnect @@ -32,7 +32,8 @@ export class Reconnection { this.inReconnectionState = false } clearTimeout(this.timer) - this.timer = setTimeout((): void => this.socket.create(), Math.floor(Math.random() * (this.socket.options.reconnectionIntervalMax - this.socket.options.reconnectionIntervalMin + 1))) + this.timer = setTimeout((): void => this.socket.create(), + Math.floor(Math.random() * (this.socket.options.reconnectionIntervalMax - this.socket.options.reconnectionIntervalMin + 1))) } }, this.socket.options.reconnectionIntervalMin) } From b52f649feed1211b07e2e586c9318ee5e3b473c0 Mon Sep 17 00:00:00 2001 From: Dmitrii Goriunov Date: Mon, 1 Jan 2018 00:03:55 +1300 Subject: [PATCH 06/21] Move all build logic to ts-builder --- .builder/rollup.config.js | 74 ------------------------ .builder/tsconfig.json | 10 ---- .builder/tslint.json | 118 -------------------------------------- dist/package.json | 2 +- package.json | 15 ++--- 5 files changed, 5 insertions(+), 214 deletions(-) delete mode 100644 .builder/rollup.config.js delete mode 100644 .builder/tsconfig.json delete mode 100644 .builder/tslint.json diff --git a/.builder/rollup.config.js b/.builder/rollup.config.js deleted file mode 100644 index 823553f..0000000 --- a/.builder/rollup.config.js +++ /dev/null @@ -1,74 +0,0 @@ -const fs = require('fs') -const path = require('path') -const rollup = require('rollup').rollup -const uglify = require('rollup-plugin-uglify') -const typescriptPlugin = require('rollup-plugin-typescript2') - - -const copyPlugin = function (options) { - return { - ongenerate() { - const targDir = path.dirname(options.targ); - if (!fs.existsSync(targDir)) { - fs.mkdirSync(targDir) - } - if (options.remove) { - let json = fs.readFileSync(options.src) - let parsed = JSON.parse(json) - options.remove.forEach(element => delete parsed[element]) - fs.writeFileSync(options.targ, JSON.stringify(parsed, null, '\t')) - } else { - fs.writeFileSync(options.targ, fs.readFileSync(options.src)) - } - } - } -} - -return rollup({ - input: './src/index.ts', - plugins: [ - typescriptPlugin({ - useTsconfigDeclarationDir: true, - tsconfig: './.builder/tsconfig.json', - cacheRoot: './.builder/cache', - tsconfigOverride: process.env.NPM ? { - compilerOptions: { declaration: true, declarationDir: '../src' } - } : {} - }), - uglify({ - mangle: true, - output: { - beautify: process.env.NPM || process.env.BEAUTY || false - } - }), - !process.env.NPM || copyPlugin({ - src: './package.json', - targ: './dist/package.json', - remove: ['devDependencies', 'scripts'] - }), - !process.env.NPM || copyPlugin({ - src: './README.md', - targ: './dist/README.md', - }), - !process.env.NPM || copyPlugin({ - src: './LICENSE', - targ: './dist/LICENSE', - }) - ] -}).then((bundle) => { - bundle.write({ format: process.env.NPM ? 'cjs' : 'iife', file: process.env.NPM ? './dist/index.js' : (process.env.BEAUTY ? './dist/browser/ClusterWS.js' : './dist/browser/ClusterWS.min.js'), name: 'ClusterWS' }).then(() => { - if (process.env.NPM) { - const dts = require('dts-bundle') - dts.bundle({ - externals: false, - referenceExternals: false, - name: "index", - main: './src/**/*.d.ts', - out: '../dist/index.d.ts', - removeSource: true, - outputAsModuleFolder: true, - emitOnIncludedFileNotFound: true - }) - } - }) -}) diff --git a/.builder/tsconfig.json b/.builder/tsconfig.json deleted file mode 100644 index 2fe3059..0000000 --- a/.builder/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "compilerOptions": { - "target": "es5", - "module": "commonjs", - "removeComments": true - }, - "include": [ - "../src/**/*.ts" - ] -} \ No newline at end of file diff --git a/.builder/tslint.json b/.builder/tslint.json deleted file mode 100644 index 2259cc9..0000000 --- a/.builder/tslint.json +++ /dev/null @@ -1,118 +0,0 @@ -{ - "extends": "tslint:recommended", - "rules": { - "no-unused-expression": false, - "eofline": false, - "ordered-imports": false, - "quotemark": [ - true, - "single" - ], - "no-console": [ - false - ], - "trailing-comma": [ - false - ], - "max-line-length": [true, 150], - "no-any": false, - "no-empty-interface": true, - "only-arrow-functions": [ - true, - "allow-declarations", - "allow-named-functions" - ], - "typedef": [ - true, - "call-signature", - "arrow-call-signature", - "parameter", - "arrow-parameter", - "property-declaration", - "variable-declaration", - "member-variable-declaration", - "object-destructuring", - "array-destructuring" - ], - "typedef-whitespace": [ - true, - { - "call-signature": "nospace", - "index-signature": "nospace", - "parameter": "nospace", - "property-declaration": "nospace", - "variable-declaration": "nospace" - }, - { - "call-signature": "onespace", - "index-signature": "onespace", - "parameter": "onespace", - "property-declaration": "onespace", - "variable-declaration": "onespace" - } - ], - "curly": [ - true, - "as-needed" - ], - "no-empty": [ - true, - "allow-empty-catch" - ], - "no-eval": true, - "no-var-keyword": true, - "cyclomatic-complexity": [ - true, - 20 - ], - "no-duplicate-imports": true, - "arrow-return-shorthand": [ - true, - "multiline" - ], - "class-name": true, - "import-spacing": true, - "jsdoc-format": true, - "newline-before-return": false, - "no-unnecessary-callback-wrapper": true, - "object-literal-shorthand": true, - "object-literal-key-quotes": [ - true, - "consistent" - ], - "number-literal-format": true, - "one-variable-per-declaration": [ - true, - "ignore-for-loop" - ], - "prefer-method-signature": true, - "prefer-switch": [ - true, - { - "min-cases": 2 - } - ], - "switch-final-break": [ - true, - "always" - ], - "whitespace": [ - true, - "check-branch", - "check-decl", - "check-operator", - "check-module", - "check-separator", - "check-rest-spread", - "check-type", - "check-typecast", - "check-type-operator", - "check-preblock" - ], - "prefer-const": true, - "semicolon": [ - true, - "never" - ] - } -} \ No newline at end of file diff --git a/dist/package.json b/dist/package.json index cd2ae79..978ebcd 100644 --- a/dist/package.json +++ b/dist/package.json @@ -1,6 +1,6 @@ { "name": "clusterws-client-js", - "version": "1.4.0", + "version": "1.5.0", "description": "JavaScript Client for ClusterWS - lightweight, fast and powerful framework for building horizontally & vertically scalable WebSocket applications in Node.js.", "main": "index.js", "author": "Dmitrii Goriunov ", diff --git a/package.json b/package.json index af2b6f9..053e3ee 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,12 @@ { "name": "clusterws-client-js", - "version": "1.4.0", + "version": "1.5.0", "description": "JavaScript Client for ClusterWS - lightweight, fast and powerful framework for building horizontally & vertically scalable WebSocket applications in Node.js.", "main": "index.js", "author": "Dmitrii Goriunov ", "scripts": { - "lint": "tslint -c ./.builder/tslint.json ./src/**/*.ts", - "build:npm": "npm run lint && cross-env NPM=true node ./.builder/rollup.config.js", - "build:browser": "npm run lint && cross-env BEAUTY=true node ./.builder/rollup.config.js && node ./.builder/rollup.config.js ", + "build:npm": "ts-builder -npm -folder src -mainfile index.ts -outfolder dist -outfile index.js", + "build:browser": "ts-builder -format iife -folder src -mainfile index.ts -outfolder dist/browser -outfile clusterws.js && ts-builder -prod -format iife -folder src -mainfile index.ts -outfolder dist/browser -outfile clusterws.min.js", "build:prod": "npm run build:npm && npm run build:browser", "publish": "npm run build:prod && cd dist && npm publish && cd .." }, @@ -17,12 +16,6 @@ "url": "https://github.com/ClusterWS/ClusterWS-Client-JS" }, "devDependencies": { - "cross-env": "^5.1.3", - "dts-bundle": "^0.7.3", - "rollup": "^0.53.1", - "rollup-plugin-typescript2": "^0.9.0", - "rollup-plugin-uglify": "^2.0.1", - "tslint": "^5.8.0", - "typescript": "^2.6.2" + "ts-builder": "^0.5.4" } } \ No newline at end of file From 5a6f00b41efa5360d8ba8fc3963ecaa68016efa0 Mon Sep 17 00:00:00 2001 From: Dmitrii Goriunov Date: Mon, 1 Jan 2018 02:14:08 +1300 Subject: [PATCH 07/21] Update ts-builder --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 053e3ee..cba4caf 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,6 @@ "url": "https://github.com/ClusterWS/ClusterWS-Client-JS" }, "devDependencies": { - "ts-builder": "^0.5.4" + "ts-builder": "^0.5.7" } -} \ No newline at end of file +} From 3cf422d430173f597c7dc2a0889b6c7b2478c076 Mon Sep 17 00:00:00 2001 From: Dmitrii Goriunov Date: Mon, 1 Jan 2018 02:40:21 +1300 Subject: [PATCH 08/21] Moved all github stuff in .github folder --- LICENSE => .github/LICENSE | 0 README.md => .github/README.md | 0 package.json | 2 +- 3 files changed, 1 insertion(+), 1 deletion(-) rename LICENSE => .github/LICENSE (100%) rename README.md => .github/README.md (100%) diff --git a/LICENSE b/.github/LICENSE similarity index 100% rename from LICENSE rename to .github/LICENSE diff --git a/README.md b/.github/README.md similarity index 100% rename from README.md rename to .github/README.md diff --git a/package.json b/package.json index cba4caf..4f48f54 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,6 @@ "url": "https://github.com/ClusterWS/ClusterWS-Client-JS" }, "devDependencies": { - "ts-builder": "^0.5.7" + "ts-builder": "^0.5.8" } } From a9ca08ed8bf58fa75afe889fde598789d5151899 Mon Sep 17 00:00:00 2001 From: Dmitrii Goriunov Date: Mon, 1 Jan 2018 03:31:17 +1300 Subject: [PATCH 09/21] Added pull req data and issue template --- .github/ISSUE_TEMPLATE.md | 15 +++++++++++++++ .github/PULL_REQUEST_TEMPLATE.md | 8 ++++++++ 2 files changed, 23 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE.md create mode 100644 .github/PULL_REQUEST_TEMPLATE.md diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000..3a08b31 --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,15 @@ +### Submitting + +- [ ] Bug +- [ ] Question +- [ ] Suggetion +- [ ] Other + +### Details + \ No newline at end of file diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..0837183 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,8 @@ +### Submitting + +- [ ] Bug fix +- [ ] Feature +- [ ] Other + +### Details + \ No newline at end of file From dde780503fe7ae194c5d9e0ade7456c61c0bb84c Mon Sep 17 00:00:00 2001 From: Dmitrii Goriunov Date: Mon, 1 Jan 2018 03:36:40 +1300 Subject: [PATCH 10/21] remove dist --- dist/LICENSE | 21 ----- dist/README.md | 162 ---------------------------------- dist/browser/ClusterWS.js | 159 --------------------------------- dist/browser/ClusterWS.min.js | 1 - dist/index.d.ts | 60 ------------- dist/index.js | 160 --------------------------------- dist/package.json | 12 --- 7 files changed, 575 deletions(-) delete mode 100644 dist/LICENSE delete mode 100644 dist/README.md delete mode 100644 dist/browser/ClusterWS.js delete mode 100644 dist/browser/ClusterWS.min.js delete mode 100644 dist/index.d.ts delete mode 100644 dist/index.js delete mode 100644 dist/package.json diff --git a/dist/LICENSE b/dist/LICENSE deleted file mode 100644 index 478e041..0000000 --- a/dist/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2017 ClusterWS - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/dist/README.md b/dist/README.md deleted file mode 100644 index deccd66..0000000 --- a/dist/README.md +++ /dev/null @@ -1,162 +0,0 @@ -

ClusterWS JavaScript Client

-
WebSocket & Node JS Cluster
- -

- Node.js -

- -

- - -

- -**This README, logo and animation will be changed soon, we are currently implementing new GUIDES in wikis and working with new logo and animation** - -## Overview -This is official JavaScript client for [ClusterWS](https://github.com/ClusterWS/ClusterWS). - -[ClusterWS](https://github.com/ClusterWS/ClusterWS) - is a minimal **Node JS http & real-time** framework which allows to scale WebSocket ([uWS](https://github.com/uNetworking/uWebSockets) - one of the fastest WebSocket libraries) between **Workers** in [Node JS Cluster](https://nodejs.org/api/cluster.html) and utilize all available CPU. - -**Current minified version is under 6KB.** - -**This library requires [ClusterWS](https://github.com/ClusterWS/ClusterWS) on the server** - -## Installation -To install ClusterWS Client JS run: -```js -npm install --save clusterws-client-js -``` -or use globally: - -1. Find `ClusterWS.(min).js` in `dist/browser` folder. -2. Use standard script tag to import library ``. -3. Done, now you can use it as `ClusterWS`. - - -## Socket -### 1. Connecting -You can connect to the server with the following code: -```js -var cws = new ClusterWS({ - url: 'localhost', - port: 80 -}) -``` - -in case if you are using builders like `webpack` and `npm` then you need to import library at the top with: -```js -var ClusterWS = require('clusterws-client-js').ClusterWS -``` - -*All available options of ClusterWS:* -```js -{ - url: '{string} url of the server without http or https. (must be provided)', - port: '{number} port of the server. (must be provided)', - autoReconnect: '{boolean} allow to auto-reconnect to the server on lost connection. (default false)', - reconnectionIntervalMin: '{number} how long min time waut. (default 1000) in ms', - reconnectionIntervalMax: '{number} how long max time wait. (default 5000) in ms', - reconnectionAttempts: '{number} how many times to try, 0 means without limit. (default 0)', - secure: '{boolean} user secure connection or not wss/ws. (default false)' -} -``` - -*Auto reconnect count random time between Max and Min interval value this will reduce amount of users which are connection at the same time on reconnection and reduce server load on restart of the server* - -### 2. Listen on events -To listen on events from the server you should use `on` method witch is provided by `cws` -```js -/** - event name: string - can be any string you wish - data: any - is what you send from the client -*/ -cws.on('event name', function(data){ - // in here you can write any logic -}) -``` - -*Also `cws` gets **Reserved Events** such as `'connect'`, `'disconnect'` and `'error'`* -```js -cws.on('connect', function(){ - // in here you can write any logic -}) - -/** - err: any - display the problem with your weboscket -*/ -cws.on('error', function(err){ - // in here you can write any logic -}) - -/** - code: number - represent the reason in number - reason: string - reason why your socket was disconnected -*/ -cws.on('disconnect', function(code, reason){ - // in here you can write any logic -}) -``` - -### 3. Send events -To send events to the server use `send` method witch is provided by `cws` -```js -/** - event name: string - can be any string you wish (client must listen on this event name) - data: any - is what you want to send to the client -*/ -cws.send('event name', data) -``` - -*Avoid emitting **Reserved Events** such as `'connect'`, `'connection'`, `'disconnect'` and `'error'`. Also avoid emitting event and events with `'#'` at the start.* - -## Pub/Sub -You can `subscribe`, `watch`, `unsubscribe` and `publish`, `getChannelByName` to/from the channels -```js -/** - channel name: string - can be any string you wish -*/ -var channel = cws.subscribe('channel name') - -/** - data: any - is what you get when you or some one else publish to the channel -*/ -channel.watch(function(data){ - // in here you can write any logic -}) - -/** - data: any - is what you want to publish to the channel (everyone who is subscribe will get it) -*/ -channel.publish(data) - -/** - This method is used to unsubscribe from the channel -*/ -channel.unsubscribe() - -/** - Also you can chain everything in one expression -*/ -var channel = cws.subscribe('channel name').watch(function(data){ - // in here you can write any logic -}).publish(data) - - -/** - You can get channel by channel name only if you were subscribed before - You can use any methods as with usual channel -*/ -cws.getChannelByName('channel name') - -``` - -**To make sure that user is connected to the server before subscribing, do it on `connect` event or on any other events which you emit from the server, otherwise subscription may not work properly** - -## See Also -* [Medium ClusterWS](https://medium.com/clusterws) -* [ClusterWS Tests](https://github.com/ClusterWS/ClusterWS-Tests) -* [ClusterWS Example Chat](https://github.com/goriunov/ClusterWS-Chat-Example) - -*Docs are still under development. If you have found any errors please submit pull request or leave issue* - -## Happy coding !!! :sunglasses: \ No newline at end of file diff --git a/dist/browser/ClusterWS.js b/dist/browser/ClusterWS.js deleted file mode 100644 index d3225e5..0000000 --- a/dist/browser/ClusterWS.js +++ /dev/null @@ -1,159 +0,0 @@ -var ClusterWS = function() { - "use strict"; - function t(t) { - return console.log(t); - } - var n = function() { - function n(t, n) { - this.socket = t, this.channel = n, this.subscribe(); - } - return n.prototype.watch = function(n) { - return "[object Function]" !== {}.toString.call(n) ? t("Listener must be a function") : (this.listener = n, - this); - }, n.prototype.publish = function(t) { - return this.socket.send(this.channel, t, "publish"), this; - }, n.prototype.unsubscribe = function() { - this.socket.send("unsubscribe", this.channel, "system"), this.socket.channels[this.channel] = null; - }, n.prototype.onMessage = function(t) { - this.listener && this.listener.call(null, t); - }, n.prototype.subscribe = function() { - this.socket.send("subscribe", this.channel, "system"); - }, n; - }(), e = function() { - function n() { - this.events = {}; - } - return n.prototype.on = function(n, e) { - if ("[object Function]" !== {}.toString.call(e)) return t("Listener must be a function"); - this.events[n] || (this.events[n] = e); - }, n.prototype.emit = function(t) { - for (var n = [], e = 1; e < arguments.length; e++) n[e - 1] = arguments[e]; - this.events[t] && (o = this.events[t]).call.apply(o, [ null ].concat(n)); - var o; - }, n.prototype.removeAllEvents = function() { - this.events = {}; - }, n; - }(), o = function() { - function t(t) { - this.socket = t, this.inReconnectionState = !1, this.reconnectionAttempted = 0, - this.autoReconnect = this.socket.options.autoReconnect; - } - return t.prototype.isConnected = function() { - clearTimeout(this.timer), clearInterval(this.interval), this.inReconnectionState = !1, - this.reconnectionAttempted = 0; - for (var t in this.socket.channels) this.socket.channels[t] && this.socket.channels[t].subscribe(); - }, t.prototype.reconnect = function() { - var t = this; - this.inReconnectionState = !0, this.interval = setInterval(function() { - t.socket.getState() === t.socket.websocket.CLOSED && (t.reconnectionAttempted++, - 0 !== t.socket.options.reconnectionAttempts && t.reconnectionAttempted >= t.socket.options.reconnectionAttempts && (clearInterval(t.interval), - t.autoReconnect = !1, t.inReconnectionState = !1), clearTimeout(t.timer), t.timer = setTimeout(function() { - return t.socket.create(); - }, Math.floor(Math.random() * (t.socket.options.reconnectionIntervalMax - t.socket.options.reconnectionIntervalMin + 1)))); - }, this.socket.options.reconnectionIntervalMin); - }, t; - }(); - return function() { - function i(n) { - return this.channels = {}, this.missedPing = 0, this.events = new e(), this.useBinary = !1, - n.url && "string" == typeof n.url ? (this.options = { - url: n.url, - autoReconnect: n.autoReconnect || !1, - reconnectionIntervalMin: n.reconnectionIntervalMin || 1e3, - reconnectionIntervalMax: n.reconnectionIntervalMax || 5e3, - reconnectionAttempts: n.reconnectionAttempts || 0 - }, this.options.reconnectionIntervalMin > this.options.reconnectionIntervalMax ? t("reconnectionIntervalMin can not be more then reconnectionIntervalMax") : (this.reconnection = new o(this), - void this.create())) : t("Url must be provided and it must be string"); - } - return i.buffer = function(t) { - for (var n = t.length, e = new Uint8Array(n), o = 0; o < n; o++) e[o] = t.charCodeAt(o); - return e.buffer; - }, i.decode = function(t, n) { - switch (n["#"][0]) { - case "e": - return t.events.emit(n["#"][1], n["#"][2]); - - case "p": - return t.channels[n["#"][1]] ? t.channels[n["#"][1]].onMessage(n["#"][2]) : null; - - case "s": - switch (n["#"][1]) { - case "c": - t.pingInterval = setInterval(function() { - return t.missedPing++ > 2 ? t.disconnect(4001, "Did not get pings") : null; - }, n["#"][2].ping), t.useBinary = n["#"][2].binary, t.events.emit("connect"); - } - } - }, i.encode = function(t, n, e) { - switch (e) { - case "ping": - return t; - - case "emit": - return JSON.stringify({ - "#": [ "e", t, n ] - }); - - case "publish": - return JSON.stringify({ - "#": [ "p", t, n ] - }); - - case "system": - switch (t) { - case "subscribe": - return JSON.stringify({ - "#": [ "s", "s", n ] - }); - - case "unsubscribe": - return JSON.stringify({ - "#": [ "s", "u", n ] - }); - - case "configuration": - return JSON.stringify({ - "#": [ "s", "c", n ] - }); - } - } - }, i.prototype.create = function() { - var n = this, e = window.MozWebSocket || window.WebSocket; - this.websocket = new e(this.options.url), this.websocket.binaryType = "arraybuffer", - this.websocket.onopen = function() { - return n.reconnection.isConnected(); - }, this.websocket.onerror = function(t) { - return n.events.emit("error", t.message); - }, this.websocket.onmessage = function(e) { - var o = e.data; - if ("string" != typeof o && (o = String.fromCharCode.apply(null, new Uint8Array(o))), - "#0" === o) return n.missedPing = 0, n.send("#1", null, "ping"); - try { - o = JSON.parse(o); - } catch (n) { - return t(n); - } - i.decode(n, o); - }, this.websocket.onclose = function(t) { - if (n.missedPing = 0, clearInterval(n.pingInterval), n.events.emit("disconnect", t.code, t.reason), - !n.reconnection.inReconnectionState) { - if (n.options.autoReconnect && 1e3 !== t.code) return n.reconnection.reconnect(); - n.events.removeAllEvents(); - for (var e in n) n[e] && (n[e] = null); - } - }; - }, i.prototype.on = function(t, n) { - this.events.on(t, n); - }, i.prototype.send = function(t, n, e) { - void 0 === e && (e = "emit"), this.websocket.send(this.useBinary ? i.buffer(i.encode(t, n, e)) : i.encode(t, n, e)); - }, i.prototype.disconnect = function(t, n) { - this.websocket.close(t || 1e3, n); - }, i.prototype.getState = function() { - return this.websocket.readyState; - }, i.prototype.subscribe = function(t) { - return this.channels[t] ? this.channels[t] : this.channels[t] = new n(this, t); - }, i.prototype.getChannelByName = function(t) { - return this.channels[t]; - }, i; - }(); -}(); diff --git a/dist/browser/ClusterWS.min.js b/dist/browser/ClusterWS.min.js deleted file mode 100644 index a45c38a..0000000 --- a/dist/browser/ClusterWS.min.js +++ /dev/null @@ -1 +0,0 @@ -var ClusterWS=function(){"use strict";function t(t){return console.log(t)}var n=function(){function n(t,n){this.socket=t,this.channel=n,this.subscribe()}return n.prototype.watch=function(n){return"[object Function]"!=={}.toString.call(n)?t("Listener must be a function"):(this.listener=n,this)},n.prototype.publish=function(t){return this.socket.send(this.channel,t,"publish"),this},n.prototype.unsubscribe=function(){this.socket.send("unsubscribe",this.channel,"system"),this.socket.channels[this.channel]=null},n.prototype.onMessage=function(t){this.listener&&this.listener.call(null,t)},n.prototype.subscribe=function(){this.socket.send("subscribe",this.channel,"system")},n}(),e=function(){function n(){this.events={}}return n.prototype.on=function(n,e){if("[object Function]"!=={}.toString.call(e))return t("Listener must be a function");this.events[n]||(this.events[n]=e)},n.prototype.emit=function(t){for(var n=[],e=1;e=t.socket.options.reconnectionAttempts&&(clearInterval(t.interval),t.autoReconnect=!1,t.inReconnectionState=!1),clearTimeout(t.timer),t.timer=setTimeout(function(){return t.socket.create()},Math.floor(Math.random()*(t.socket.options.reconnectionIntervalMax-t.socket.options.reconnectionIntervalMin+1))))},this.socket.options.reconnectionIntervalMin)},t}();return function(){function i(n){return this.channels={},this.missedPing=0,this.events=new e,this.useBinary=!1,n.url&&"string"==typeof n.url?(this.options={url:n.url,autoReconnect:n.autoReconnect||!1,reconnectionIntervalMin:n.reconnectionIntervalMin||1e3,reconnectionIntervalMax:n.reconnectionIntervalMax||5e3,reconnectionAttempts:n.reconnectionAttempts||0},this.options.reconnectionIntervalMin>this.options.reconnectionIntervalMax?t("reconnectionIntervalMin can not be more then reconnectionIntervalMax"):(this.reconnection=new o(this),void this.create())):t("Url must be provided and it must be string")}return i.buffer=function(t){for(var n=t.length,e=new Uint8Array(n),o=0;o2?t.disconnect(4001,"Did not get pings"):null},n["#"][2].ping),t.useBinary=n["#"][2].binary,t.events.emit("connect")}}},i.encode=function(t,n,e){switch(e){case"ping":return t;case"emit":return JSON.stringify({"#":["e",t,n]});case"publish":return JSON.stringify({"#":["p",t,n]});case"system":switch(t){case"subscribe":return JSON.stringify({"#":["s","s",n]});case"unsubscribe":return JSON.stringify({"#":["s","u",n]});case"configuration":return JSON.stringify({"#":["s","c",n]})}}},i.prototype.create=function(){var n=this,e=window.MozWebSocket||window.WebSocket;this.websocket=new e(this.options.url),this.websocket.binaryType="arraybuffer",this.websocket.onopen=function(){return n.reconnection.isConnected()},this.websocket.onerror=function(t){return n.events.emit("error",t.message)},this.websocket.onmessage=function(e){var o=e.data;if("string"!=typeof o&&(o=String.fromCharCode.apply(null,new Uint8Array(o))),"#0"===o)return n.missedPing=0,n.send("#1",null,"ping");try{o=JSON.parse(o)}catch(n){return t(n)}i.decode(n,o)},this.websocket.onclose=function(t){if(n.missedPing=0,clearInterval(n.pingInterval),n.events.emit("disconnect",t.code,t.reason),!n.reconnection.inReconnectionState){if(n.options.autoReconnect&&1e3!==t.code)return n.reconnection.reconnect();n.events.removeAllEvents();for(var e in n)n[e]&&(n[e]=null)}}},i.prototype.on=function(t,n){this.events.on(t,n)},i.prototype.send=function(t,n,e){void 0===e&&(e="emit"),this.websocket.send(this.useBinary?i.buffer(i.encode(t,n,e)):i.encode(t,n,e))},i.prototype.disconnect=function(t,n){this.websocket.close(t||1e3,n)},i.prototype.getState=function(){return this.websocket.readyState},i.prototype.subscribe=function(t){return this.channels[t]?this.channels[t]:this.channels[t]=new n(this,t)},i.prototype.getChannelByName=function(t){return this.channels[t]},i}()}(); diff --git a/dist/index.d.ts b/dist/index.d.ts deleted file mode 100644 index 9bba2da..0000000 --- a/dist/index.d.ts +++ /dev/null @@ -1,60 +0,0 @@ -// Generated by dts-bundle v0.7.3 - -export default class ClusterWS { - options: IOptions; - channels: IObject; - websocket: WebSocket; - constructor(configuration: IUserOptions); - create(): void; - on(event: string, listener: TListener): void; - send(event: string, data: any, type?: string): void; - disconnect(code?: number, msg?: any): void; - getState(): number; - subscribe(channel: string): Channel; - getChannelByName(channelName: string): Channel; -} - -export class Channel { - constructor(socket: ClusterWS, channel: string); - watch(listener: TListener): Channel; - publish(data: any): Channel; - unsubscribe(): void; - onMessage(data: any): void; - subscribe(): void; -} - -export class Reconnection { - socket: ClusterWS; - inReconnectionState: boolean; - constructor(socket: ClusterWS); - isConnected(): void; - reconnect(): void; -} - -export class EventEmitter { - on(event: string, listener: TListener): void; - emit(event: string, ...args: any[]): void; - removeAllEvents(): void; -} - -export type TListener = (...args: any[]) => void; -export type TSocketMessage = any; -export interface IObject { - [propName: string]: any; -} -export interface IUserOptions { - url: string; - autoReconnect?: boolean; - reconnectionIntervalMin?: number; - reconnectionIntervalMax?: number; - reconnectionAttempts?: number; -} -export interface IOptions { - url: string; - autoReconnect: boolean; - reconnectionIntervalMin: number; - reconnectionIntervalMax: number; - reconnectionAttempts: number; -} -export function logError(data: T): any; - diff --git a/dist/index.js b/dist/index.js deleted file mode 100644 index 9b08284..0000000 --- a/dist/index.js +++ /dev/null @@ -1,160 +0,0 @@ -"use strict"; - -function logError(t) { - return console.log(t); -} - -var Channel = function() { - function t(t, e) { - this.socket = t, this.channel = e, 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.channel, t, "publish"), this; - }, t.prototype.unsubscribe = function() { - this.socket.send("unsubscribe", this.channel, "system"), this.socket.channels[this.channel] = null; - }, t.prototype.onMessage = function(t) { - this.listener && this.listener.call(null, t); - }, t.prototype.subscribe = function() { - this.socket.send("subscribe", this.channel, "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] || (this.events[t] = e); - }, t.prototype.emit = function(t) { - for (var e = [], n = 1; n < arguments.length; n++) e[n - 1] = arguments[n]; - this.events[t] && (o = this.events[t]).call.apply(o, [ null ].concat(e)); - var o; - }, t.prototype.removeAllEvents = function() { - this.events = {}; - }, t; -}(), Reconnection = function() { - function t(t) { - this.socket = t, this.inReconnectionState = !1, this.reconnectionAttempted = 0, - this.autoReconnect = this.socket.options.autoReconnect; - } - return t.prototype.isConnected = function() { - clearTimeout(this.timer), clearInterval(this.interval), this.inReconnectionState = !1, - this.reconnectionAttempted = 0; - for (var t in this.socket.channels) this.socket.channels[t] && this.socket.channels[t].subscribe(); - }, t.prototype.reconnect = function() { - var t = this; - this.inReconnectionState = !0, this.interval = setInterval(function() { - t.socket.getState() === t.socket.websocket.CLOSED && (t.reconnectionAttempted++, - 0 !== t.socket.options.reconnectionAttempts && t.reconnectionAttempted >= t.socket.options.reconnectionAttempts && (clearInterval(t.interval), - t.autoReconnect = !1, t.inReconnectionState = !1), clearTimeout(t.timer), t.timer = setTimeout(function() { - return t.socket.create(); - }, Math.floor(Math.random() * (t.socket.options.reconnectionIntervalMax - t.socket.options.reconnectionIntervalMin + 1)))); - }, this.socket.options.reconnectionIntervalMin); - }, t; -}(), ClusterWS = function() { - function t(t) { - return this.channels = {}, this.missedPing = 0, this.events = new EventEmitter(), - this.useBinary = !1, t.url && "string" == typeof t.url ? (this.options = { - url: t.url, - autoReconnect: t.autoReconnect || !1, - reconnectionIntervalMin: t.reconnectionIntervalMin || 1e3, - reconnectionIntervalMax: t.reconnectionIntervalMax || 5e3, - reconnectionAttempts: t.reconnectionAttempts || 0 - }, this.options.reconnectionIntervalMin > this.options.reconnectionIntervalMax ? logError("reconnectionIntervalMin can not be more then reconnectionIntervalMax") : (this.reconnection = new Reconnection(this), - void this.create())) : logError("Url must be provided and it must be string"); - } - return t.buffer = function(t) { - for (var e = t.length, n = new Uint8Array(e), o = 0; o < e; o++) n[o] = t.charCodeAt(o); - return n.buffer; - }, t.decode = function(t, e) { - switch (e["#"][0]) { - case "e": - return t.events.emit(e["#"][1], e["#"][2]); - - case "p": - return t.channels[e["#"][1]] ? t.channels[e["#"][1]].onMessage(e["#"][2]) : null; - - case "s": - switch (e["#"][1]) { - case "c": - t.pingInterval = setInterval(function() { - return t.missedPing++ > 2 ? t.disconnect(4001, "Did not get pings") : null; - }, e["#"][2].ping), t.useBinary = e["#"][2].binary, t.events.emit("connect"); - } - } - }, t.encode = function(t, e, n) { - switch (n) { - case "ping": - return t; - - case "emit": - return JSON.stringify({ - "#": [ "e", t, e ] - }); - - case "publish": - return JSON.stringify({ - "#": [ "p", t, e ] - }); - - case "system": - switch (t) { - case "subscribe": - return JSON.stringify({ - "#": [ "s", "s", e ] - }); - - case "unsubscribe": - return JSON.stringify({ - "#": [ "s", "u", e ] - }); - - case "configuration": - return JSON.stringify({ - "#": [ "s", "c", e ] - }); - } - } - }, t.prototype.create = function() { - var e = this, n = window.MozWebSocket || window.WebSocket; - this.websocket = new n(this.options.url), this.websocket.binaryType = "arraybuffer", - this.websocket.onopen = function() { - return e.reconnection.isConnected(); - }, this.websocket.onerror = function(t) { - return e.events.emit("error", t.message); - }, this.websocket.onmessage = function(n) { - var o = n.data; - if ("string" != typeof o && (o = String.fromCharCode.apply(null, new Uint8Array(o))), - "#0" === o) return e.missedPing = 0, e.send("#1", null, "ping"); - try { - o = JSON.parse(o); - } catch (t) { - return logError(t); - } - t.decode(e, o); - }, this.websocket.onclose = function(t) { - if (e.missedPing = 0, clearInterval(e.pingInterval), e.events.emit("disconnect", t.code, t.reason), - !e.reconnection.inReconnectionState) { - if (e.options.autoReconnect && 1e3 !== t.code) return e.reconnection.reconnect(); - e.events.removeAllEvents(); - for (var n in e) e[n] && (e[n] = null); - } - }; - }, t.prototype.on = function(t, e) { - this.events.on(t, e); - }, t.prototype.send = function(e, n, o) { - void 0 === o && (o = "emit"), this.websocket.send(this.useBinary ? t.buffer(t.encode(e, n, o)) : t.encode(e, n, o)); - }, t.prototype.disconnect = function(t, e) { - this.websocket.close(t || 1e3, e); - }, t.prototype.getState = function() { - return this.websocket.readyState; - }, 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; -}(); - -module.exports = ClusterWS; diff --git a/dist/package.json b/dist/package.json deleted file mode 100644 index 978ebcd..0000000 --- a/dist/package.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "clusterws-client-js", - "version": "1.5.0", - "description": "JavaScript Client for ClusterWS - lightweight, fast and powerful framework for building horizontally & vertically scalable WebSocket applications in Node.js.", - "main": "index.js", - "author": "Dmitrii Goriunov ", - "license": "MIT", - "repository": { - "type": "git", - "url": "https://github.com/ClusterWS/ClusterWS-Client-JS" - } -} \ No newline at end of file From 64f1b38cc00a39fc51f3ef95d167779747fda74a Mon Sep 17 00:00:00 2001 From: Dmitrii Goriunov Date: Mon, 1 Jan 2018 03:37:31 +1300 Subject: [PATCH 11/21] Update for dist --- dist/LICENSE | 21 +++++ dist/README.md | 162 ++++++++++++++++++++++++++++++++++ dist/browser/clusterws.js | 159 +++++++++++++++++++++++++++++++++ dist/browser/clusterws.min.js | 1 + dist/index.d.ts | 60 +++++++++++++ dist/index.js | 160 +++++++++++++++++++++++++++++++++ dist/package.json | 12 +++ 7 files changed, 575 insertions(+) create mode 100644 dist/LICENSE create mode 100644 dist/README.md create mode 100644 dist/browser/clusterws.js create mode 100644 dist/browser/clusterws.min.js create mode 100644 dist/index.d.ts create mode 100644 dist/index.js create mode 100644 dist/package.json diff --git a/dist/LICENSE b/dist/LICENSE new file mode 100644 index 0000000..478e041 --- /dev/null +++ b/dist/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 ClusterWS + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/dist/README.md b/dist/README.md new file mode 100644 index 0000000..deccd66 --- /dev/null +++ b/dist/README.md @@ -0,0 +1,162 @@ +

ClusterWS JavaScript Client

+
WebSocket & Node JS Cluster
+ +

+ Node.js +

+ +

+ + +

+ +**This README, logo and animation will be changed soon, we are currently implementing new GUIDES in wikis and working with new logo and animation** + +## Overview +This is official JavaScript client for [ClusterWS](https://github.com/ClusterWS/ClusterWS). + +[ClusterWS](https://github.com/ClusterWS/ClusterWS) - is a minimal **Node JS http & real-time** framework which allows to scale WebSocket ([uWS](https://github.com/uNetworking/uWebSockets) - one of the fastest WebSocket libraries) between **Workers** in [Node JS Cluster](https://nodejs.org/api/cluster.html) and utilize all available CPU. + +**Current minified version is under 6KB.** + +**This library requires [ClusterWS](https://github.com/ClusterWS/ClusterWS) on the server** + +## Installation +To install ClusterWS Client JS run: +```js +npm install --save clusterws-client-js +``` +or use globally: + +1. Find `ClusterWS.(min).js` in `dist/browser` folder. +2. Use standard script tag to import library ``. +3. Done, now you can use it as `ClusterWS`. + + +## Socket +### 1. Connecting +You can connect to the server with the following code: +```js +var cws = new ClusterWS({ + url: 'localhost', + port: 80 +}) +``` + +in case if you are using builders like `webpack` and `npm` then you need to import library at the top with: +```js +var ClusterWS = require('clusterws-client-js').ClusterWS +``` + +*All available options of ClusterWS:* +```js +{ + url: '{string} url of the server without http or https. (must be provided)', + port: '{number} port of the server. (must be provided)', + autoReconnect: '{boolean} allow to auto-reconnect to the server on lost connection. (default false)', + reconnectionIntervalMin: '{number} how long min time waut. (default 1000) in ms', + reconnectionIntervalMax: '{number} how long max time wait. (default 5000) in ms', + reconnectionAttempts: '{number} how many times to try, 0 means without limit. (default 0)', + secure: '{boolean} user secure connection or not wss/ws. (default false)' +} +``` + +*Auto reconnect count random time between Max and Min interval value this will reduce amount of users which are connection at the same time on reconnection and reduce server load on restart of the server* + +### 2. Listen on events +To listen on events from the server you should use `on` method witch is provided by `cws` +```js +/** + event name: string - can be any string you wish + data: any - is what you send from the client +*/ +cws.on('event name', function(data){ + // in here you can write any logic +}) +``` + +*Also `cws` gets **Reserved Events** such as `'connect'`, `'disconnect'` and `'error'`* +```js +cws.on('connect', function(){ + // in here you can write any logic +}) + +/** + err: any - display the problem with your weboscket +*/ +cws.on('error', function(err){ + // in here you can write any logic +}) + +/** + code: number - represent the reason in number + reason: string - reason why your socket was disconnected +*/ +cws.on('disconnect', function(code, reason){ + // in here you can write any logic +}) +``` + +### 3. Send events +To send events to the server use `send` method witch is provided by `cws` +```js +/** + event name: string - can be any string you wish (client must listen on this event name) + data: any - is what you want to send to the client +*/ +cws.send('event name', data) +``` + +*Avoid emitting **Reserved Events** such as `'connect'`, `'connection'`, `'disconnect'` and `'error'`. Also avoid emitting event and events with `'#'` at the start.* + +## Pub/Sub +You can `subscribe`, `watch`, `unsubscribe` and `publish`, `getChannelByName` to/from the channels +```js +/** + channel name: string - can be any string you wish +*/ +var channel = cws.subscribe('channel name') + +/** + data: any - is what you get when you or some one else publish to the channel +*/ +channel.watch(function(data){ + // in here you can write any logic +}) + +/** + data: any - is what you want to publish to the channel (everyone who is subscribe will get it) +*/ +channel.publish(data) + +/** + This method is used to unsubscribe from the channel +*/ +channel.unsubscribe() + +/** + Also you can chain everything in one expression +*/ +var channel = cws.subscribe('channel name').watch(function(data){ + // in here you can write any logic +}).publish(data) + + +/** + You can get channel by channel name only if you were subscribed before + You can use any methods as with usual channel +*/ +cws.getChannelByName('channel name') + +``` + +**To make sure that user is connected to the server before subscribing, do it on `connect` event or on any other events which you emit from the server, otherwise subscription may not work properly** + +## See Also +* [Medium ClusterWS](https://medium.com/clusterws) +* [ClusterWS Tests](https://github.com/ClusterWS/ClusterWS-Tests) +* [ClusterWS Example Chat](https://github.com/goriunov/ClusterWS-Chat-Example) + +*Docs are still under development. If you have found any errors please submit pull request or leave issue* + +## Happy coding !!! :sunglasses: \ No newline at end of file diff --git a/dist/browser/clusterws.js b/dist/browser/clusterws.js new file mode 100644 index 0000000..d3225e5 --- /dev/null +++ b/dist/browser/clusterws.js @@ -0,0 +1,159 @@ +var ClusterWS = function() { + "use strict"; + function t(t) { + return console.log(t); + } + var n = function() { + function n(t, n) { + this.socket = t, this.channel = n, this.subscribe(); + } + return n.prototype.watch = function(n) { + return "[object Function]" !== {}.toString.call(n) ? t("Listener must be a function") : (this.listener = n, + this); + }, n.prototype.publish = function(t) { + return this.socket.send(this.channel, t, "publish"), this; + }, n.prototype.unsubscribe = function() { + this.socket.send("unsubscribe", this.channel, "system"), this.socket.channels[this.channel] = null; + }, n.prototype.onMessage = function(t) { + this.listener && this.listener.call(null, t); + }, n.prototype.subscribe = function() { + this.socket.send("subscribe", this.channel, "system"); + }, n; + }(), e = function() { + function n() { + this.events = {}; + } + return n.prototype.on = function(n, e) { + if ("[object Function]" !== {}.toString.call(e)) return t("Listener must be a function"); + this.events[n] || (this.events[n] = e); + }, n.prototype.emit = function(t) { + for (var n = [], e = 1; e < arguments.length; e++) n[e - 1] = arguments[e]; + this.events[t] && (o = this.events[t]).call.apply(o, [ null ].concat(n)); + var o; + }, n.prototype.removeAllEvents = function() { + this.events = {}; + }, n; + }(), o = function() { + function t(t) { + this.socket = t, this.inReconnectionState = !1, this.reconnectionAttempted = 0, + this.autoReconnect = this.socket.options.autoReconnect; + } + return t.prototype.isConnected = function() { + clearTimeout(this.timer), clearInterval(this.interval), this.inReconnectionState = !1, + this.reconnectionAttempted = 0; + for (var t in this.socket.channels) this.socket.channels[t] && this.socket.channels[t].subscribe(); + }, t.prototype.reconnect = function() { + var t = this; + this.inReconnectionState = !0, this.interval = setInterval(function() { + t.socket.getState() === t.socket.websocket.CLOSED && (t.reconnectionAttempted++, + 0 !== t.socket.options.reconnectionAttempts && t.reconnectionAttempted >= t.socket.options.reconnectionAttempts && (clearInterval(t.interval), + t.autoReconnect = !1, t.inReconnectionState = !1), clearTimeout(t.timer), t.timer = setTimeout(function() { + return t.socket.create(); + }, Math.floor(Math.random() * (t.socket.options.reconnectionIntervalMax - t.socket.options.reconnectionIntervalMin + 1)))); + }, this.socket.options.reconnectionIntervalMin); + }, t; + }(); + return function() { + function i(n) { + return this.channels = {}, this.missedPing = 0, this.events = new e(), this.useBinary = !1, + n.url && "string" == typeof n.url ? (this.options = { + url: n.url, + autoReconnect: n.autoReconnect || !1, + reconnectionIntervalMin: n.reconnectionIntervalMin || 1e3, + reconnectionIntervalMax: n.reconnectionIntervalMax || 5e3, + reconnectionAttempts: n.reconnectionAttempts || 0 + }, this.options.reconnectionIntervalMin > this.options.reconnectionIntervalMax ? t("reconnectionIntervalMin can not be more then reconnectionIntervalMax") : (this.reconnection = new o(this), + void this.create())) : t("Url must be provided and it must be string"); + } + return i.buffer = function(t) { + for (var n = t.length, e = new Uint8Array(n), o = 0; o < n; o++) e[o] = t.charCodeAt(o); + return e.buffer; + }, i.decode = function(t, n) { + switch (n["#"][0]) { + case "e": + return t.events.emit(n["#"][1], n["#"][2]); + + case "p": + return t.channels[n["#"][1]] ? t.channels[n["#"][1]].onMessage(n["#"][2]) : null; + + case "s": + switch (n["#"][1]) { + case "c": + t.pingInterval = setInterval(function() { + return t.missedPing++ > 2 ? t.disconnect(4001, "Did not get pings") : null; + }, n["#"][2].ping), t.useBinary = n["#"][2].binary, t.events.emit("connect"); + } + } + }, i.encode = function(t, n, e) { + switch (e) { + case "ping": + return t; + + case "emit": + return JSON.stringify({ + "#": [ "e", t, n ] + }); + + case "publish": + return JSON.stringify({ + "#": [ "p", t, n ] + }); + + case "system": + switch (t) { + case "subscribe": + return JSON.stringify({ + "#": [ "s", "s", n ] + }); + + case "unsubscribe": + return JSON.stringify({ + "#": [ "s", "u", n ] + }); + + case "configuration": + return JSON.stringify({ + "#": [ "s", "c", n ] + }); + } + } + }, i.prototype.create = function() { + var n = this, e = window.MozWebSocket || window.WebSocket; + this.websocket = new e(this.options.url), this.websocket.binaryType = "arraybuffer", + this.websocket.onopen = function() { + return n.reconnection.isConnected(); + }, this.websocket.onerror = function(t) { + return n.events.emit("error", t.message); + }, this.websocket.onmessage = function(e) { + var o = e.data; + if ("string" != typeof o && (o = String.fromCharCode.apply(null, new Uint8Array(o))), + "#0" === o) return n.missedPing = 0, n.send("#1", null, "ping"); + try { + o = JSON.parse(o); + } catch (n) { + return t(n); + } + i.decode(n, o); + }, this.websocket.onclose = function(t) { + if (n.missedPing = 0, clearInterval(n.pingInterval), n.events.emit("disconnect", t.code, t.reason), + !n.reconnection.inReconnectionState) { + if (n.options.autoReconnect && 1e3 !== t.code) return n.reconnection.reconnect(); + n.events.removeAllEvents(); + for (var e in n) n[e] && (n[e] = null); + } + }; + }, i.prototype.on = function(t, n) { + this.events.on(t, n); + }, i.prototype.send = function(t, n, e) { + void 0 === e && (e = "emit"), this.websocket.send(this.useBinary ? i.buffer(i.encode(t, n, e)) : i.encode(t, n, e)); + }, i.prototype.disconnect = function(t, n) { + this.websocket.close(t || 1e3, n); + }, i.prototype.getState = function() { + return this.websocket.readyState; + }, i.prototype.subscribe = function(t) { + return this.channels[t] ? this.channels[t] : this.channels[t] = new n(this, t); + }, i.prototype.getChannelByName = function(t) { + return this.channels[t]; + }, i; + }(); +}(); diff --git a/dist/browser/clusterws.min.js b/dist/browser/clusterws.min.js new file mode 100644 index 0000000..a45c38a --- /dev/null +++ b/dist/browser/clusterws.min.js @@ -0,0 +1 @@ +var ClusterWS=function(){"use strict";function t(t){return console.log(t)}var n=function(){function n(t,n){this.socket=t,this.channel=n,this.subscribe()}return n.prototype.watch=function(n){return"[object Function]"!=={}.toString.call(n)?t("Listener must be a function"):(this.listener=n,this)},n.prototype.publish=function(t){return this.socket.send(this.channel,t,"publish"),this},n.prototype.unsubscribe=function(){this.socket.send("unsubscribe",this.channel,"system"),this.socket.channels[this.channel]=null},n.prototype.onMessage=function(t){this.listener&&this.listener.call(null,t)},n.prototype.subscribe=function(){this.socket.send("subscribe",this.channel,"system")},n}(),e=function(){function n(){this.events={}}return n.prototype.on=function(n,e){if("[object Function]"!=={}.toString.call(e))return t("Listener must be a function");this.events[n]||(this.events[n]=e)},n.prototype.emit=function(t){for(var n=[],e=1;e=t.socket.options.reconnectionAttempts&&(clearInterval(t.interval),t.autoReconnect=!1,t.inReconnectionState=!1),clearTimeout(t.timer),t.timer=setTimeout(function(){return t.socket.create()},Math.floor(Math.random()*(t.socket.options.reconnectionIntervalMax-t.socket.options.reconnectionIntervalMin+1))))},this.socket.options.reconnectionIntervalMin)},t}();return function(){function i(n){return this.channels={},this.missedPing=0,this.events=new e,this.useBinary=!1,n.url&&"string"==typeof n.url?(this.options={url:n.url,autoReconnect:n.autoReconnect||!1,reconnectionIntervalMin:n.reconnectionIntervalMin||1e3,reconnectionIntervalMax:n.reconnectionIntervalMax||5e3,reconnectionAttempts:n.reconnectionAttempts||0},this.options.reconnectionIntervalMin>this.options.reconnectionIntervalMax?t("reconnectionIntervalMin can not be more then reconnectionIntervalMax"):(this.reconnection=new o(this),void this.create())):t("Url must be provided and it must be string")}return i.buffer=function(t){for(var n=t.length,e=new Uint8Array(n),o=0;o2?t.disconnect(4001,"Did not get pings"):null},n["#"][2].ping),t.useBinary=n["#"][2].binary,t.events.emit("connect")}}},i.encode=function(t,n,e){switch(e){case"ping":return t;case"emit":return JSON.stringify({"#":["e",t,n]});case"publish":return JSON.stringify({"#":["p",t,n]});case"system":switch(t){case"subscribe":return JSON.stringify({"#":["s","s",n]});case"unsubscribe":return JSON.stringify({"#":["s","u",n]});case"configuration":return JSON.stringify({"#":["s","c",n]})}}},i.prototype.create=function(){var n=this,e=window.MozWebSocket||window.WebSocket;this.websocket=new e(this.options.url),this.websocket.binaryType="arraybuffer",this.websocket.onopen=function(){return n.reconnection.isConnected()},this.websocket.onerror=function(t){return n.events.emit("error",t.message)},this.websocket.onmessage=function(e){var o=e.data;if("string"!=typeof o&&(o=String.fromCharCode.apply(null,new Uint8Array(o))),"#0"===o)return n.missedPing=0,n.send("#1",null,"ping");try{o=JSON.parse(o)}catch(n){return t(n)}i.decode(n,o)},this.websocket.onclose=function(t){if(n.missedPing=0,clearInterval(n.pingInterval),n.events.emit("disconnect",t.code,t.reason),!n.reconnection.inReconnectionState){if(n.options.autoReconnect&&1e3!==t.code)return n.reconnection.reconnect();n.events.removeAllEvents();for(var e in n)n[e]&&(n[e]=null)}}},i.prototype.on=function(t,n){this.events.on(t,n)},i.prototype.send=function(t,n,e){void 0===e&&(e="emit"),this.websocket.send(this.useBinary?i.buffer(i.encode(t,n,e)):i.encode(t,n,e))},i.prototype.disconnect=function(t,n){this.websocket.close(t||1e3,n)},i.prototype.getState=function(){return this.websocket.readyState},i.prototype.subscribe=function(t){return this.channels[t]?this.channels[t]:this.channels[t]=new n(this,t)},i.prototype.getChannelByName=function(t){return this.channels[t]},i}()}(); diff --git a/dist/index.d.ts b/dist/index.d.ts new file mode 100644 index 0000000..9bba2da --- /dev/null +++ b/dist/index.d.ts @@ -0,0 +1,60 @@ +// Generated by dts-bundle v0.7.3 + +export default class ClusterWS { + options: IOptions; + channels: IObject; + websocket: WebSocket; + constructor(configuration: IUserOptions); + create(): void; + on(event: string, listener: TListener): void; + send(event: string, data: any, type?: string): void; + disconnect(code?: number, msg?: any): void; + getState(): number; + subscribe(channel: string): Channel; + getChannelByName(channelName: string): Channel; +} + +export class Channel { + constructor(socket: ClusterWS, channel: string); + watch(listener: TListener): Channel; + publish(data: any): Channel; + unsubscribe(): void; + onMessage(data: any): void; + subscribe(): void; +} + +export class Reconnection { + socket: ClusterWS; + inReconnectionState: boolean; + constructor(socket: ClusterWS); + isConnected(): void; + reconnect(): void; +} + +export class EventEmitter { + on(event: string, listener: TListener): void; + emit(event: string, ...args: any[]): void; + removeAllEvents(): void; +} + +export type TListener = (...args: any[]) => void; +export type TSocketMessage = any; +export interface IObject { + [propName: string]: any; +} +export interface IUserOptions { + url: string; + autoReconnect?: boolean; + reconnectionIntervalMin?: number; + reconnectionIntervalMax?: number; + reconnectionAttempts?: number; +} +export interface IOptions { + url: string; + autoReconnect: boolean; + reconnectionIntervalMin: number; + reconnectionIntervalMax: number; + reconnectionAttempts: number; +} +export function logError(data: T): any; + diff --git a/dist/index.js b/dist/index.js new file mode 100644 index 0000000..9b08284 --- /dev/null +++ b/dist/index.js @@ -0,0 +1,160 @@ +"use strict"; + +function logError(t) { + return console.log(t); +} + +var Channel = function() { + function t(t, e) { + this.socket = t, this.channel = e, 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.channel, t, "publish"), this; + }, t.prototype.unsubscribe = function() { + this.socket.send("unsubscribe", this.channel, "system"), this.socket.channels[this.channel] = null; + }, t.prototype.onMessage = function(t) { + this.listener && this.listener.call(null, t); + }, t.prototype.subscribe = function() { + this.socket.send("subscribe", this.channel, "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] || (this.events[t] = e); + }, t.prototype.emit = function(t) { + for (var e = [], n = 1; n < arguments.length; n++) e[n - 1] = arguments[n]; + this.events[t] && (o = this.events[t]).call.apply(o, [ null ].concat(e)); + var o; + }, t.prototype.removeAllEvents = function() { + this.events = {}; + }, t; +}(), Reconnection = function() { + function t(t) { + this.socket = t, this.inReconnectionState = !1, this.reconnectionAttempted = 0, + this.autoReconnect = this.socket.options.autoReconnect; + } + return t.prototype.isConnected = function() { + clearTimeout(this.timer), clearInterval(this.interval), this.inReconnectionState = !1, + this.reconnectionAttempted = 0; + for (var t in this.socket.channels) this.socket.channels[t] && this.socket.channels[t].subscribe(); + }, t.prototype.reconnect = function() { + var t = this; + this.inReconnectionState = !0, this.interval = setInterval(function() { + t.socket.getState() === t.socket.websocket.CLOSED && (t.reconnectionAttempted++, + 0 !== t.socket.options.reconnectionAttempts && t.reconnectionAttempted >= t.socket.options.reconnectionAttempts && (clearInterval(t.interval), + t.autoReconnect = !1, t.inReconnectionState = !1), clearTimeout(t.timer), t.timer = setTimeout(function() { + return t.socket.create(); + }, Math.floor(Math.random() * (t.socket.options.reconnectionIntervalMax - t.socket.options.reconnectionIntervalMin + 1)))); + }, this.socket.options.reconnectionIntervalMin); + }, t; +}(), ClusterWS = function() { + function t(t) { + return this.channels = {}, this.missedPing = 0, this.events = new EventEmitter(), + this.useBinary = !1, t.url && "string" == typeof t.url ? (this.options = { + url: t.url, + autoReconnect: t.autoReconnect || !1, + reconnectionIntervalMin: t.reconnectionIntervalMin || 1e3, + reconnectionIntervalMax: t.reconnectionIntervalMax || 5e3, + reconnectionAttempts: t.reconnectionAttempts || 0 + }, this.options.reconnectionIntervalMin > this.options.reconnectionIntervalMax ? logError("reconnectionIntervalMin can not be more then reconnectionIntervalMax") : (this.reconnection = new Reconnection(this), + void this.create())) : logError("Url must be provided and it must be string"); + } + return t.buffer = function(t) { + for (var e = t.length, n = new Uint8Array(e), o = 0; o < e; o++) n[o] = t.charCodeAt(o); + return n.buffer; + }, t.decode = function(t, e) { + switch (e["#"][0]) { + case "e": + return t.events.emit(e["#"][1], e["#"][2]); + + case "p": + return t.channels[e["#"][1]] ? t.channels[e["#"][1]].onMessage(e["#"][2]) : null; + + case "s": + switch (e["#"][1]) { + case "c": + t.pingInterval = setInterval(function() { + return t.missedPing++ > 2 ? t.disconnect(4001, "Did not get pings") : null; + }, e["#"][2].ping), t.useBinary = e["#"][2].binary, t.events.emit("connect"); + } + } + }, t.encode = function(t, e, n) { + switch (n) { + case "ping": + return t; + + case "emit": + return JSON.stringify({ + "#": [ "e", t, e ] + }); + + case "publish": + return JSON.stringify({ + "#": [ "p", t, e ] + }); + + case "system": + switch (t) { + case "subscribe": + return JSON.stringify({ + "#": [ "s", "s", e ] + }); + + case "unsubscribe": + return JSON.stringify({ + "#": [ "s", "u", e ] + }); + + case "configuration": + return JSON.stringify({ + "#": [ "s", "c", e ] + }); + } + } + }, t.prototype.create = function() { + var e = this, n = window.MozWebSocket || window.WebSocket; + this.websocket = new n(this.options.url), this.websocket.binaryType = "arraybuffer", + this.websocket.onopen = function() { + return e.reconnection.isConnected(); + }, this.websocket.onerror = function(t) { + return e.events.emit("error", t.message); + }, this.websocket.onmessage = function(n) { + var o = n.data; + if ("string" != typeof o && (o = String.fromCharCode.apply(null, new Uint8Array(o))), + "#0" === o) return e.missedPing = 0, e.send("#1", null, "ping"); + try { + o = JSON.parse(o); + } catch (t) { + return logError(t); + } + t.decode(e, o); + }, this.websocket.onclose = function(t) { + if (e.missedPing = 0, clearInterval(e.pingInterval), e.events.emit("disconnect", t.code, t.reason), + !e.reconnection.inReconnectionState) { + if (e.options.autoReconnect && 1e3 !== t.code) return e.reconnection.reconnect(); + e.events.removeAllEvents(); + for (var n in e) e[n] && (e[n] = null); + } + }; + }, t.prototype.on = function(t, e) { + this.events.on(t, e); + }, t.prototype.send = function(e, n, o) { + void 0 === o && (o = "emit"), this.websocket.send(this.useBinary ? t.buffer(t.encode(e, n, o)) : t.encode(e, n, o)); + }, t.prototype.disconnect = function(t, e) { + this.websocket.close(t || 1e3, e); + }, t.prototype.getState = function() { + return this.websocket.readyState; + }, 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; +}(); + +module.exports = ClusterWS; diff --git a/dist/package.json b/dist/package.json new file mode 100644 index 0000000..978ebcd --- /dev/null +++ b/dist/package.json @@ -0,0 +1,12 @@ +{ + "name": "clusterws-client-js", + "version": "1.5.0", + "description": "JavaScript Client for ClusterWS - lightweight, fast and powerful framework for building horizontally & vertically scalable WebSocket applications in Node.js.", + "main": "index.js", + "author": "Dmitrii Goriunov ", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/ClusterWS/ClusterWS-Client-JS" + } +} \ No newline at end of file From 389109a419c331b28806d684c887f2775e6071d0 Mon Sep 17 00:00:00 2001 From: Dmitrii Goriunov Date: Mon, 1 Jan 2018 03:50:06 +1300 Subject: [PATCH 12/21] Added cod of conduct --- .github/CODE_OF_CONDUCT.md | 46 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 .github/CODE_OF_CONDUCT.md diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..63cf2c9 --- /dev/null +++ b/.github/CODE_OF_CONDUCT.md @@ -0,0 +1,46 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team . The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] + +[homepage]: http://contributor-covenant.org +[version]: http://contributor-covenant.org/version/1/4/ \ No newline at end of file From ab4c504e402cc8b136cfd51295ae18d4706e3abe Mon Sep 17 00:00:00 2001 From: Dmitrii Goriunov Date: Mon, 1 Jan 2018 03:58:52 +1300 Subject: [PATCH 13/21] Move all data to docs --- {.github => docs}/CODE_OF_CONDUCT.md | 0 {.github => docs}/ISSUE_TEMPLATE.md | 0 {.github => docs}/LICENSE | 0 {.github => docs}/PULL_REQUEST_TEMPLATE.md | 0 {.github => docs}/README.md | 0 package.json | 2 +- 6 files changed, 1 insertion(+), 1 deletion(-) rename {.github => docs}/CODE_OF_CONDUCT.md (100%) rename {.github => docs}/ISSUE_TEMPLATE.md (100%) rename {.github => docs}/LICENSE (100%) rename {.github => docs}/PULL_REQUEST_TEMPLATE.md (100%) rename {.github => docs}/README.md (100%) diff --git a/.github/CODE_OF_CONDUCT.md b/docs/CODE_OF_CONDUCT.md similarity index 100% rename from .github/CODE_OF_CONDUCT.md rename to docs/CODE_OF_CONDUCT.md diff --git a/.github/ISSUE_TEMPLATE.md b/docs/ISSUE_TEMPLATE.md similarity index 100% rename from .github/ISSUE_TEMPLATE.md rename to docs/ISSUE_TEMPLATE.md diff --git a/.github/LICENSE b/docs/LICENSE similarity index 100% rename from .github/LICENSE rename to docs/LICENSE diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/docs/PULL_REQUEST_TEMPLATE.md similarity index 100% rename from .github/PULL_REQUEST_TEMPLATE.md rename to docs/PULL_REQUEST_TEMPLATE.md diff --git a/.github/README.md b/docs/README.md similarity index 100% rename from .github/README.md rename to docs/README.md diff --git a/package.json b/package.json index 4f48f54..06f2d79 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,6 @@ "url": "https://github.com/ClusterWS/ClusterWS-Client-JS" }, "devDependencies": { - "ts-builder": "^0.5.8" + "ts-builder": "^0.5.9" } } From f009c44e5768dc3c85b57a05a492e8ee1ba80417 Mon Sep 17 00:00:00 2001 From: Dmitrii Goriunov Date: Wed, 3 Jan 2018 21:00:53 +1300 Subject: [PATCH 14/21] Code style improvments, better size and perfomance --- dist/browser/clusterws.js | 226 +++++++++--------- dist/browser/clusterws.min.js | 2 +- dist/index.d.ts | 58 +++-- dist/index.js | 171 ++++++------- package.json | 2 +- src/index.ts | 108 +++------ src/modules/channel.ts | 34 --- src/modules/channel/channel.ts | 35 +++ src/modules/emitter/emitter.ts | 19 ++ src/modules/parser/parser.ts | 40 ++++ .../{ => reconnection}/reconnection.ts | 6 +- src/utils/emitter.ts | 18 -- src/utils/utils.ts | 25 +- 13 files changed, 380 insertions(+), 364 deletions(-) delete mode 100644 src/modules/channel.ts create mode 100644 src/modules/channel/channel.ts create mode 100644 src/modules/emitter/emitter.ts create mode 100644 src/modules/parser/parser.ts rename src/modules/{ => reconnection}/reconnection.ts (87%) delete mode 100644 src/utils/emitter.ts diff --git a/dist/browser/clusterws.js b/dist/browser/clusterws.js index d3225e5..ca72cd7 100644 --- a/dist/browser/clusterws.js +++ b/dist/browser/clusterws.js @@ -1,39 +1,73 @@ var ClusterWS = function() { "use strict"; - function t(t) { + function t(t, n, e) { + switch (e) { + case "ping": + return t; + + case "emit": + return JSON.stringify({ + "#": [ "e", t, n ] + }); + + case "publish": + return JSON.stringify({ + "#": [ "p", t, n ] + }); + + case "system": + switch (t) { + case "subscribe": + return JSON.stringify({ + "#": [ "s", "s", n ] + }); + + case "unsubscribe": + return JSON.stringify({ + "#": [ "s", "u", n ] + }); + + case "configuration": + return JSON.stringify({ + "#": [ "s", "c", n ] + }); + } + } + } + function n(t) { return console.log(t); } - var n = function() { - function n(t, n) { - this.socket = t, this.channel = n, this.subscribe(); + var e = function() { + function t(t, n) { + this.socket = t, this.name = n, this.subscribe(); } - return n.prototype.watch = function(n) { - return "[object Function]" !== {}.toString.call(n) ? t("Listener must be a function") : (this.listener = n, + return t.prototype.watch = function(t) { + return "[object Function]" !== {}.toString.call(t) ? n("Listener must be a function") : (this.listener = t, this); - }, n.prototype.publish = function(t) { - return this.socket.send(this.channel, t, "publish"), this; - }, n.prototype.unsubscribe = function() { - this.socket.send("unsubscribe", this.channel, "system"), this.socket.channels[this.channel] = null; - }, n.prototype.onMessage = function(t) { + }, 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); - }, n.prototype.subscribe = function() { - this.socket.send("subscribe", this.channel, "system"); - }, n; - }(), e = function() { - function n() { + }, t.prototype.subscribe = function() { + this.socket.send("subscribe", this.name, "system"); + }, t; + }(), o = function() { + function t() { this.events = {}; } - return n.prototype.on = function(n, e) { - if ("[object Function]" !== {}.toString.call(e)) return t("Listener must be a function"); - this.events[n] || (this.events[n] = e); - }, n.prototype.emit = function(t) { + return t.prototype.on = function(t, e) { + if ("[object Function]" !== {}.toString.call(e)) return n("Listener must be a function"); + this.events[t] = e; + }, t.prototype.emit = function(t) { for (var n = [], e = 1; e < arguments.length; e++) n[e - 1] = arguments[e]; this.events[t] && (o = this.events[t]).call.apply(o, [ null ].concat(n)); var o; - }, n.prototype.removeAllEvents = function() { + }, t.prototype.removeAllEvents = function() { this.events = {}; - }, n; - }(), o = function() { + }, t; + }(), i = function() { function t(t) { this.socket = t, this.inReconnectionState = !1, this.reconnectionAttempted = 0, this.autoReconnect = this.socket.options.autoReconnect; @@ -44,116 +78,80 @@ var ClusterWS = function() { for (var t in this.socket.channels) this.socket.channels[t] && this.socket.channels[t].subscribe(); }, t.prototype.reconnect = function() { var t = this; - this.inReconnectionState = !0, this.interval = setInterval(function() { + this.inReconnectionState || (this.inReconnectionState = !0, this.interval = setInterval(function() { t.socket.getState() === t.socket.websocket.CLOSED && (t.reconnectionAttempted++, 0 !== t.socket.options.reconnectionAttempts && t.reconnectionAttempted >= t.socket.options.reconnectionAttempts && (clearInterval(t.interval), t.autoReconnect = !1, t.inReconnectionState = !1), clearTimeout(t.timer), t.timer = setTimeout(function() { return t.socket.create(); }, Math.floor(Math.random() * (t.socket.options.reconnectionIntervalMax - t.socket.options.reconnectionIntervalMin + 1)))); - }, this.socket.options.reconnectionIntervalMin); + }, this.socket.options.reconnectionIntervalMin)); }, t; }(); return function() { - function i(n) { - return this.channels = {}, this.missedPing = 0, this.events = new e(), this.useBinary = !1, - n.url && "string" == typeof n.url ? (this.options = { - url: n.url, - autoReconnect: n.autoReconnect || !1, - reconnectionIntervalMin: n.reconnectionIntervalMin || 1e3, - reconnectionIntervalMax: n.reconnectionIntervalMax || 5e3, - reconnectionAttempts: n.reconnectionAttempts || 0 - }, this.options.reconnectionIntervalMin > this.options.reconnectionIntervalMax ? t("reconnectionIntervalMin can not be more then reconnectionIntervalMax") : (this.reconnection = new o(this), - void this.create())) : t("Url must be provided and it must be string"); + function s(t) { + return this.channels = {}, this.events = new o(), this.missedPing = 0, this.useBinary = !1, + t.url ? (this.options = { + url: t.url, + autoReconnect: t.autoReconnect || !1, + reconnectionAttempts: t.reconnectionAttempts || 0, + reconnectionIntervalMin: t.reconnectionIntervalMin || 1e3, + reconnectionIntervalMax: t.reconnectionIntervalMax || 5e3 + }, this.options.reconnectionIntervalMin > this.options.reconnectionIntervalMax ? n("reconnectionIntervalMin can not be more then reconnectionIntervalMax") : (this.reconnection = new i(this), + void this.create())) : n("Url must be provided and it must be string"); } - return i.buffer = function(t) { - for (var n = t.length, e = new Uint8Array(n), o = 0; o < n; o++) e[o] = t.charCodeAt(o); - return e.buffer; - }, i.decode = function(t, n) { - switch (n["#"][0]) { - case "e": - return t.events.emit(n["#"][1], n["#"][2]); - - case "p": - return t.channels[n["#"][1]] ? t.channels[n["#"][1]].onMessage(n["#"][2]) : null; - - case "s": - switch (n["#"][1]) { - case "c": - t.pingInterval = setInterval(function() { - return t.missedPing++ > 2 ? t.disconnect(4001, "Did not get pings") : null; - }, n["#"][2].ping), t.useBinary = n["#"][2].binary, t.events.emit("connect"); - } - } - }, i.encode = function(t, n, e) { - switch (e) { - case "ping": - return t; - - case "emit": - return JSON.stringify({ - "#": [ "e", t, n ] - }); - - case "publish": - return JSON.stringify({ - "#": [ "p", t, n ] - }); - - case "system": - switch (t) { - case "subscribe": - return JSON.stringify({ - "#": [ "s", "s", n ] - }); - - case "unsubscribe": - return JSON.stringify({ - "#": [ "s", "u", n ] - }); - - case "configuration": - return JSON.stringify({ - "#": [ "s", "c", n ] - }); - } - } - }, i.prototype.create = function() { - var n = this, e = window.MozWebSocket || window.WebSocket; + return s.prototype.create = function() { + var t = this, e = window.MozWebSocket || window.WebSocket; this.websocket = new e(this.options.url), this.websocket.binaryType = "arraybuffer", this.websocket.onopen = function() { - return n.reconnection.isConnected(); - }, this.websocket.onerror = function(t) { - return n.events.emit("error", t.message); + return t.reconnection.isConnected(); + }, this.websocket.onerror = function(n) { + return t.events.emit("error", n.message); }, this.websocket.onmessage = function(e) { - var o = e.data; - if ("string" != typeof o && (o = String.fromCharCode.apply(null, new Uint8Array(o))), - "#0" === o) return n.missedPing = 0, n.send("#1", null, "ping"); + var o = "string" != typeof e.data ? String.fromCharCode.apply(null, new Uint8Array(e.data)) : e.data; + if ("#0" === o) return t.missedPing = 0, t.send("#1", null, "ping"); try { o = JSON.parse(o); - } catch (n) { - return t(n); - } - i.decode(n, o); - }, this.websocket.onclose = function(t) { - if (n.missedPing = 0, clearInterval(n.pingInterval), n.events.emit("disconnect", t.code, t.reason), - !n.reconnection.inReconnectionState) { - if (n.options.autoReconnect && 1e3 !== t.code) return n.reconnection.reconnect(); - n.events.removeAllEvents(); - for (var e in n) n[e] && (n[e] = null); + } catch (t) { + return n(t); } + !function(t, n) { + switch (n["#"][0]) { + case "e": + return t.events.emit(n["#"][1], n["#"][2]); + + case "p": + t.channels[n["#"][1]] && t.channels[n["#"][1]].onMessage(n["#"][2]); + + case "s": + switch (n["#"][1]) { + case "c": + t.pingInterval = setInterval(function() { + return t.missedPing++ > 2 && t.disconnect(4001, "Did not get pings"); + }, n["#"][2].ping), t.useBinary = n["#"][2].binary, t.events.emit("connect"); + } + } + }(t, o); + }, this.websocket.onclose = function(n) { + if (t.missedPing = 0, clearInterval(t.pingInterval), t.events.emit("disconnect", n.code, n.reason), + t.options.autoReconnect && 1e3 !== n.code) return t.reconnection.reconnect(); + t.events.removeAllEvents(); + for (var e in t) t[e] && (t[e] = null); }; - }, i.prototype.on = function(t, n) { + }, s.prototype.on = function(t, n) { this.events.on(t, n); - }, i.prototype.send = function(t, n, e) { - void 0 === e && (e = "emit"), this.websocket.send(this.useBinary ? i.buffer(i.encode(t, n, e)) : i.encode(t, n, e)); - }, i.prototype.disconnect = function(t, n) { + }, s.prototype.send = function(n, e, o) { + void 0 === o && (o = "emit"), this.websocket.send(this.useBinary ? function(t) { + for (var n = t.length, e = new Uint8Array(n), o = 0; o < n; o++) e[o] = t.charCodeAt(o); + return e.buffer; + }(t(n, e, o)) : t(n, e, o)); + }, s.prototype.disconnect = function(t, n) { this.websocket.close(t || 1e3, n); - }, i.prototype.getState = function() { + }, s.prototype.getState = function() { return this.websocket.readyState; - }, i.prototype.subscribe = function(t) { - return this.channels[t] ? this.channels[t] : this.channels[t] = new n(this, t); - }, i.prototype.getChannelByName = function(t) { + }, s.prototype.subscribe = function(t) { + return this.channels[t] ? this.channels[t] : this.channels[t] = new e(this, t); + }, s.prototype.getChannelByName = function(t) { return this.channels[t]; - }, i; + }, s; }(); }(); diff --git a/dist/browser/clusterws.min.js b/dist/browser/clusterws.min.js index a45c38a..09d3771 100644 --- a/dist/browser/clusterws.min.js +++ b/dist/browser/clusterws.min.js @@ -1 +1 @@ -var ClusterWS=function(){"use strict";function t(t){return console.log(t)}var n=function(){function n(t,n){this.socket=t,this.channel=n,this.subscribe()}return n.prototype.watch=function(n){return"[object Function]"!=={}.toString.call(n)?t("Listener must be a function"):(this.listener=n,this)},n.prototype.publish=function(t){return this.socket.send(this.channel,t,"publish"),this},n.prototype.unsubscribe=function(){this.socket.send("unsubscribe",this.channel,"system"),this.socket.channels[this.channel]=null},n.prototype.onMessage=function(t){this.listener&&this.listener.call(null,t)},n.prototype.subscribe=function(){this.socket.send("subscribe",this.channel,"system")},n}(),e=function(){function n(){this.events={}}return n.prototype.on=function(n,e){if("[object Function]"!=={}.toString.call(e))return t("Listener must be a function");this.events[n]||(this.events[n]=e)},n.prototype.emit=function(t){for(var n=[],e=1;e=t.socket.options.reconnectionAttempts&&(clearInterval(t.interval),t.autoReconnect=!1,t.inReconnectionState=!1),clearTimeout(t.timer),t.timer=setTimeout(function(){return t.socket.create()},Math.floor(Math.random()*(t.socket.options.reconnectionIntervalMax-t.socket.options.reconnectionIntervalMin+1))))},this.socket.options.reconnectionIntervalMin)},t}();return function(){function i(n){return this.channels={},this.missedPing=0,this.events=new e,this.useBinary=!1,n.url&&"string"==typeof n.url?(this.options={url:n.url,autoReconnect:n.autoReconnect||!1,reconnectionIntervalMin:n.reconnectionIntervalMin||1e3,reconnectionIntervalMax:n.reconnectionIntervalMax||5e3,reconnectionAttempts:n.reconnectionAttempts||0},this.options.reconnectionIntervalMin>this.options.reconnectionIntervalMax?t("reconnectionIntervalMin can not be more then reconnectionIntervalMax"):(this.reconnection=new o(this),void this.create())):t("Url must be provided and it must be string")}return i.buffer=function(t){for(var n=t.length,e=new Uint8Array(n),o=0;o2?t.disconnect(4001,"Did not get pings"):null},n["#"][2].ping),t.useBinary=n["#"][2].binary,t.events.emit("connect")}}},i.encode=function(t,n,e){switch(e){case"ping":return t;case"emit":return JSON.stringify({"#":["e",t,n]});case"publish":return JSON.stringify({"#":["p",t,n]});case"system":switch(t){case"subscribe":return JSON.stringify({"#":["s","s",n]});case"unsubscribe":return JSON.stringify({"#":["s","u",n]});case"configuration":return JSON.stringify({"#":["s","c",n]})}}},i.prototype.create=function(){var n=this,e=window.MozWebSocket||window.WebSocket;this.websocket=new e(this.options.url),this.websocket.binaryType="arraybuffer",this.websocket.onopen=function(){return n.reconnection.isConnected()},this.websocket.onerror=function(t){return n.events.emit("error",t.message)},this.websocket.onmessage=function(e){var o=e.data;if("string"!=typeof o&&(o=String.fromCharCode.apply(null,new Uint8Array(o))),"#0"===o)return n.missedPing=0,n.send("#1",null,"ping");try{o=JSON.parse(o)}catch(n){return t(n)}i.decode(n,o)},this.websocket.onclose=function(t){if(n.missedPing=0,clearInterval(n.pingInterval),n.events.emit("disconnect",t.code,t.reason),!n.reconnection.inReconnectionState){if(n.options.autoReconnect&&1e3!==t.code)return n.reconnection.reconnect();n.events.removeAllEvents();for(var e in n)n[e]&&(n[e]=null)}}},i.prototype.on=function(t,n){this.events.on(t,n)},i.prototype.send=function(t,n,e){void 0===e&&(e="emit"),this.websocket.send(this.useBinary?i.buffer(i.encode(t,n,e)):i.encode(t,n,e))},i.prototype.disconnect=function(t,n){this.websocket.close(t||1e3,n)},i.prototype.getState=function(){return this.websocket.readyState},i.prototype.subscribe=function(t){return this.channels[t]?this.channels[t]:this.channels[t]=new n(this,t)},i.prototype.getChannelByName=function(t){return this.channels[t]},i}()}(); +var ClusterWS=function(){"use strict";function t(t,n,e){switch(e){case"ping":return t;case"emit":return JSON.stringify({"#":["e",t,n]});case"publish":return JSON.stringify({"#":["p",t,n]});case"system":switch(t){case"subscribe":return JSON.stringify({"#":["s","s",n]});case"unsubscribe":return JSON.stringify({"#":["s","u",n]});case"configuration":return JSON.stringify({"#":["s","c",n]})}}}function n(t){return console.log(t)}var e=function(){function t(t,n){this.socket=t,this.name=n,this.subscribe()}return t.prototype.watch=function(t){return"[object Function]"!=={}.toString.call(t)?n("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}(),o=function(){function t(){this.events={}}return t.prototype.on=function(t,e){if("[object Function]"!=={}.toString.call(e))return n("Listener must be a function");this.events[t]=e},t.prototype.emit=function(t){for(var n=[],e=1;e=t.socket.options.reconnectionAttempts&&(clearInterval(t.interval),t.autoReconnect=!1,t.inReconnectionState=!1),clearTimeout(t.timer),t.timer=setTimeout(function(){return t.socket.create()},Math.floor(Math.random()*(t.socket.options.reconnectionIntervalMax-t.socket.options.reconnectionIntervalMin+1))))},this.socket.options.reconnectionIntervalMin))},t}();return function(){function s(t){return this.channels={},this.events=new o,this.missedPing=0,this.useBinary=!1,t.url?(this.options={url:t.url,autoReconnect:t.autoReconnect||!1,reconnectionAttempts:t.reconnectionAttempts||0,reconnectionIntervalMin:t.reconnectionIntervalMin||1e3,reconnectionIntervalMax:t.reconnectionIntervalMax||5e3},this.options.reconnectionIntervalMin>this.options.reconnectionIntervalMax?n("reconnectionIntervalMin can not be more then reconnectionIntervalMax"):(this.reconnection=new i(this),void this.create())):n("Url must be provided and it must be string")}return s.prototype.create=function(){var t=this,e=window.MozWebSocket||window.WebSocket;this.websocket=new e(this.options.url),this.websocket.binaryType="arraybuffer",this.websocket.onopen=function(){return t.reconnection.isConnected()},this.websocket.onerror=function(n){return t.events.emit("error",n.message)},this.websocket.onmessage=function(e){var o="string"!=typeof e.data?String.fromCharCode.apply(null,new Uint8Array(e.data)):e.data;if("#0"===o)return t.missedPing=0,t.send("#1",null,"ping");try{o=JSON.parse(o)}catch(t){return n(t)}!function(t,n){switch(n["#"][0]){case"e":return t.events.emit(n["#"][1],n["#"][2]);case"p":t.channels[n["#"][1]]&&t.channels[n["#"][1]].onMessage(n["#"][2]);case"s":switch(n["#"][1]){case"c":t.pingInterval=setInterval(function(){return t.missedPing++>2&&t.disconnect(4001,"Did not get pings")},n["#"][2].ping),t.useBinary=n["#"][2].binary,t.events.emit("connect")}}}(t,o)},this.websocket.onclose=function(n){if(t.missedPing=0,clearInterval(t.pingInterval),t.events.emit("disconnect",n.code,n.reason),t.options.autoReconnect&&1e3!==n.code)return t.reconnection.reconnect();t.events.removeAllEvents();for(var e in t)t[e]&&(t[e]=null)}},s.prototype.on=function(t,n){this.events.on(t,n)},s.prototype.send=function(n,e,o){void 0===o&&(o="emit"),this.websocket.send(this.useBinary?function(t){for(var n=t.length,e=new Uint8Array(n),o=0;o void; -export type TSocketMessage = any; -export interface IObject { +export type Listener = (...args: any[]) => void; +export interface CustomObject { [propName: string]: any; } -export interface IUserOptions { - url: string; - autoReconnect?: boolean; - reconnectionIntervalMin?: number; - reconnectionIntervalMax?: number; - reconnectionAttempts?: number; -} -export interface IOptions { +export interface Options { url: string; autoReconnect: boolean; + reconnectionAttempts: number; reconnectionIntervalMin: number; reconnectionIntervalMax: number; - reconnectionAttempts: number; +} +export interface Configurations { + url: string; + autoReconnect?: boolean; + reconnectionAttempts?: number; + reconnectionIntervalMin?: number; + reconnectionIntervalMax?: number; } export function logError(data: T): any; diff --git a/dist/index.js b/dist/index.js index 9b08284..d6b3569 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1,24 +1,82 @@ "use strict"; +function buffer(t) { + for (var e = t.length, n = new Uint8Array(e), o = 0; o < e; o++) n[o] = t.charCodeAt(o); + return n.buffer; +} + +function decode(t, e) { + switch (e["#"][0]) { + case "e": + return t.events.emit(e["#"][1], e["#"][2]); + + case "p": + t.channels[e["#"][1]] && t.channels[e["#"][1]].onMessage(e["#"][2]); + + case "s": + switch (e["#"][1]) { + case "c": + t.pingInterval = setInterval(function() { + return t.missedPing++ > 2 && t.disconnect(4001, "Did not get pings"); + }, e["#"][2].ping), t.useBinary = e["#"][2].binary, t.events.emit("connect"); + } + } +} + +function encode(t, e, n) { + switch (n) { + case "ping": + return t; + + case "emit": + return JSON.stringify({ + "#": [ "e", t, e ] + }); + + case "publish": + return JSON.stringify({ + "#": [ "p", t, e ] + }); + + case "system": + switch (t) { + case "subscribe": + return JSON.stringify({ + "#": [ "s", "s", e ] + }); + + case "unsubscribe": + return JSON.stringify({ + "#": [ "s", "u", e ] + }); + + case "configuration": + return JSON.stringify({ + "#": [ "s", "c", e ] + }); + } + } +} + function logError(t) { return console.log(t); } var Channel = function() { function t(t, e) { - this.socket = t, this.channel = e, this.subscribe(); + this.socket = t, this.name = e, 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.channel, t, "publish"), this; + return this.socket.send(this.name, t, "publish"), this; }, t.prototype.unsubscribe = function() { - this.socket.send("unsubscribe", this.channel, "system"), this.socket.channels[this.channel] = null; + 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.channel, "system"); + this.socket.send("subscribe", this.name, "system"); }, t; }(), EventEmitter = function() { function t() { @@ -26,7 +84,7 @@ var Channel = function() { } return t.prototype.on = function(t, e) { if ("[object Function]" !== {}.toString.call(e)) return logError("Listener must be a function"); - this.events[t] || (this.events[t] = e); + this.events[t] = e; }, t.prototype.emit = function(t) { for (var e = [], n = 1; n < arguments.length; n++) e[n - 1] = arguments[n]; this.events[t] && (o = this.events[t]).call.apply(o, [ null ].concat(e)); @@ -45,107 +103,52 @@ var Channel = function() { for (var t in this.socket.channels) this.socket.channels[t] && this.socket.channels[t].subscribe(); }, t.prototype.reconnect = function() { var t = this; - this.inReconnectionState = !0, this.interval = setInterval(function() { + this.inReconnectionState || (this.inReconnectionState = !0, this.interval = setInterval(function() { t.socket.getState() === t.socket.websocket.CLOSED && (t.reconnectionAttempted++, 0 !== t.socket.options.reconnectionAttempts && t.reconnectionAttempted >= t.socket.options.reconnectionAttempts && (clearInterval(t.interval), t.autoReconnect = !1, t.inReconnectionState = !1), clearTimeout(t.timer), t.timer = setTimeout(function() { return t.socket.create(); }, Math.floor(Math.random() * (t.socket.options.reconnectionIntervalMax - t.socket.options.reconnectionIntervalMin + 1)))); - }, this.socket.options.reconnectionIntervalMin); + }, this.socket.options.reconnectionIntervalMin)); }, t; }(), ClusterWS = function() { function t(t) { - return this.channels = {}, this.missedPing = 0, this.events = new EventEmitter(), - this.useBinary = !1, t.url && "string" == typeof t.url ? (this.options = { + return this.channels = {}, this.events = new EventEmitter(), this.missedPing = 0, + this.useBinary = !1, t.url ? (this.options = { url: t.url, autoReconnect: t.autoReconnect || !1, + reconnectionAttempts: t.reconnectionAttempts || 0, reconnectionIntervalMin: t.reconnectionIntervalMin || 1e3, - reconnectionIntervalMax: t.reconnectionIntervalMax || 5e3, - reconnectionAttempts: t.reconnectionAttempts || 0 + reconnectionIntervalMax: t.reconnectionIntervalMax || 5e3 }, this.options.reconnectionIntervalMin > this.options.reconnectionIntervalMax ? logError("reconnectionIntervalMin can not be more then reconnectionIntervalMax") : (this.reconnection = new Reconnection(this), void this.create())) : logError("Url must be provided and it must be string"); } - return t.buffer = function(t) { - for (var e = t.length, n = new Uint8Array(e), o = 0; o < e; o++) n[o] = t.charCodeAt(o); - return n.buffer; - }, t.decode = function(t, e) { - switch (e["#"][0]) { - case "e": - return t.events.emit(e["#"][1], e["#"][2]); - - case "p": - return t.channels[e["#"][1]] ? t.channels[e["#"][1]].onMessage(e["#"][2]) : null; - - case "s": - switch (e["#"][1]) { - case "c": - t.pingInterval = setInterval(function() { - return t.missedPing++ > 2 ? t.disconnect(4001, "Did not get pings") : null; - }, e["#"][2].ping), t.useBinary = e["#"][2].binary, t.events.emit("connect"); - } - } - }, t.encode = function(t, e, n) { - switch (n) { - case "ping": - return t; - - case "emit": - return JSON.stringify({ - "#": [ "e", t, e ] - }); - - case "publish": - return JSON.stringify({ - "#": [ "p", t, e ] - }); - - case "system": - switch (t) { - case "subscribe": - return JSON.stringify({ - "#": [ "s", "s", e ] - }); - - case "unsubscribe": - return JSON.stringify({ - "#": [ "s", "u", e ] - }); - - case "configuration": - return JSON.stringify({ - "#": [ "s", "c", e ] - }); - } - } - }, t.prototype.create = function() { - var e = this, n = window.MozWebSocket || window.WebSocket; - this.websocket = new n(this.options.url), this.websocket.binaryType = "arraybuffer", + return t.prototype.create = function() { + var t = this, e = window.MozWebSocket || window.WebSocket; + this.websocket = new e(this.options.url), this.websocket.binaryType = "arraybuffer", this.websocket.onopen = function() { - return e.reconnection.isConnected(); - }, this.websocket.onerror = function(t) { - return e.events.emit("error", t.message); - }, this.websocket.onmessage = function(n) { - var o = n.data; - if ("string" != typeof o && (o = String.fromCharCode.apply(null, new Uint8Array(o))), - "#0" === o) return e.missedPing = 0, e.send("#1", null, "ping"); + return t.reconnection.isConnected(); + }, this.websocket.onerror = function(e) { + return t.events.emit("error", e.message); + }, this.websocket.onmessage = function(e) { + var n = "string" != typeof e.data ? String.fromCharCode.apply(null, new Uint8Array(e.data)) : e.data; + if ("#0" === n) return t.missedPing = 0, t.send("#1", null, "ping"); try { - o = JSON.parse(o); + n = JSON.parse(n); } catch (t) { return logError(t); } - t.decode(e, o); - }, this.websocket.onclose = function(t) { - if (e.missedPing = 0, clearInterval(e.pingInterval), e.events.emit("disconnect", t.code, t.reason), - !e.reconnection.inReconnectionState) { - if (e.options.autoReconnect && 1e3 !== t.code) return e.reconnection.reconnect(); - e.events.removeAllEvents(); - for (var n in e) e[n] && (e[n] = null); - } + decode(t, n); + }, this.websocket.onclose = function(e) { + if (t.missedPing = 0, clearInterval(t.pingInterval), t.events.emit("disconnect", e.code, e.reason), + t.options.autoReconnect && 1e3 !== e.code) return t.reconnection.reconnect(); + t.events.removeAllEvents(); + for (var n in t) t[n] && (t[n] = null); }; }, t.prototype.on = function(t, e) { this.events.on(t, e); - }, t.prototype.send = function(e, n, o) { - void 0 === o && (o = "emit"), this.websocket.send(this.useBinary ? t.buffer(t.encode(e, n, o)) : t.encode(e, n, o)); + }, t.prototype.send = function(t, e, n) { + void 0 === n && (n = "emit"), this.websocket.send(this.useBinary ? buffer(encode(t, e, n)) : encode(t, e, n)); }, t.prototype.disconnect = function(t, e) { this.websocket.close(t || 1e3, e); }, t.prototype.getState = function() { diff --git a/package.json b/package.json index 06f2d79..3d22475 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,6 @@ "url": "https://github.com/ClusterWS/ClusterWS-Client-JS" }, "devDependencies": { - "ts-builder": "^0.5.9" + "ts-builder": "^0.5.11" } } diff --git a/src/index.ts b/src/index.ts index 4c0af04..3456cf3 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,69 +1,33 @@ -import { Channel } from './modules/channel' -import { EventEmitter } from './utils/emitter' -import { Reconnection } from './modules/reconnection' -import { IObject, TSocketMessage, TListener, IUserOptions, IOptions, logError } from './utils/utils' +import { buffer, decode, encode } from './modules/parser/parser' +import { Channel } from './modules/channel/channel' +import { EventEmitter } from './modules/emitter/emitter' +import { Options, Configurations, logError, Listener, CustomObject } from './utils/utils' +import { Reconnection } from './modules/reconnection/reconnection' declare const window: any export default class ClusterWS { - private static buffer(str: string): ByteString { - const length: number = str.length - const uint: any = new Uint8Array(length) - for (let i: number = 0; i < length; i++) uint[i] = str.charCodeAt(i) - return uint.buffer - } - - private static decode(socket: ClusterWS, message: TSocketMessage): null | void { - switch (message['#'][0]) { - case 'e': return socket.events.emit(message['#'][1], message['#'][2]) - case 'p': return socket.channels[message['#'][1]] ? socket.channels[message['#'][1]].onMessage(message['#'][2]) : null - case 's': - switch (message['#'][1]) { - case 'c': - socket.pingInterval = setInterval((): void | null => socket.missedPing++ > 2 ? - socket.disconnect(4001, 'Did not get pings') : null, message['#'][2].ping) - socket.useBinary = message['#'][2].binary - socket.events.emit('connect') - default: break - } - default: break - } - } + public options: Options + public websocket: WebSocket + public channels: CustomObject = {} - private static encode(event: string, data: any, type: string): any { - switch (type) { - case 'ping': return event - case 'emit': return JSON.stringify({ '#': ['e', event, data] }) - case 'publish': return JSON.stringify({ '#': ['p', event, data] }) - case 'system': switch (event) { - case 'subscribe': return JSON.stringify({ '#': ['s', 's', data] }) - case 'unsubscribe': return JSON.stringify({ '#': ['s', 'u', data] }) - case 'configuration': return JSON.stringify({ '#': ['s', 'c', data] }) - default: break - } - default: break - } - } + public events: EventEmitter = new EventEmitter() + public missedPing: number = 0 + public useBinary: boolean = false + public pingInterval: any - public options: IOptions - public channels: IObject = {} - public websocket: WebSocket - private missedPing: number = 0 - private events: EventEmitter = new EventEmitter() - private useBinary: boolean = false - private pingInterval: number private reconnection: Reconnection - constructor(configuration: IUserOptions) { - if (!configuration.url || typeof configuration.url !== 'string') + constructor(configurations: Configurations) { + if (!configurations.url) return logError('Url must be provided and it must be string') this.options = { - url: configuration.url, - autoReconnect: configuration.autoReconnect || false, - reconnectionIntervalMin: configuration.reconnectionIntervalMin || 1000, - reconnectionIntervalMax: configuration.reconnectionIntervalMax || 5000, - reconnectionAttempts: configuration.reconnectionAttempts || 0 + url: configurations.url, + autoReconnect: configurations.autoReconnect || false, + reconnectionAttempts: configurations.reconnectionAttempts || 0, + reconnectionIntervalMin: configurations.reconnectionIntervalMin || 1000, + reconnectionIntervalMax: configurations.reconnectionIntervalMax || 5000 } if (this.options.reconnectionIntervalMin > this.options.reconnectionIntervalMax) @@ -75,44 +39,45 @@ export default class ClusterWS { public create(): void { const Socket: any = window.MozWebSocket || window.WebSocket + this.websocket = new Socket(this.options.url) this.websocket.binaryType = 'arraybuffer' - this.websocket.onopen = (): void => this.reconnection.isConnected() - this.websocket.onerror = (err: TSocketMessage): void => this.events.emit('error', err.message) - this.websocket.onmessage = (message: TSocketMessage): void => { - let data: string = message.data - if (typeof data !== 'string') data = String.fromCharCode.apply(null, new Uint8Array(data)) + this.websocket.onerror = (err: any): void => this.events.emit('error', err.message) + this.websocket.onmessage = (message: any): void => { + let data: string = typeof message.data !== 'string' ? + String.fromCharCode.apply(null, new Uint8Array(message.data)) : message.data + if (data === '#0') { this.missedPing = 0 return this.send('#1', null, 'ping') - } - try { + } else try { data = JSON.parse(data) } catch (e) { return logError(e) } - ClusterWS.decode(this, data) + + decode(this, data) } this.websocket.onclose = (event: CloseEvent): void => { this.missedPing = 0 clearInterval(this.pingInterval) this.events.emit('disconnect', event.code, event.reason) - if (this.reconnection.inReconnectionState) return if (this.options.autoReconnect && event.code !== 1000) return this.reconnection.reconnect() this.events.removeAllEvents() - for (const key in this) this[key] ? this[key] = null : null + for (const key in this) + this[key] ? this[key] = null : null } } - public on(event: string, listener: TListener): void { + public on(event: string, listener: Listener): void { this.events.on(event, listener) } public send(event: string, data: any, type: string = 'emit'): void { this.websocket.send(this.useBinary ? - ClusterWS.buffer(ClusterWS.encode(event, data, type)) : - ClusterWS.encode(event, data, type)) + buffer(encode(event, data, type)) : + encode(event, data, type)) } public disconnect(code?: number, msg?: any): void { @@ -123,10 +88,9 @@ export default class ClusterWS { return this.websocket.readyState } - public subscribe(channel: string): Channel { - return this.channels[channel] ? - this.channels[channel] : - this.channels[channel] = new Channel(this, channel) + public subscribe(channelName: string): Channel { + return this.channels[channelName] ? this.channels[channelName] : + this.channels[channelName] = new Channel(this, channelName) } public getChannelByName(channelName: string): Channel { diff --git a/src/modules/channel.ts b/src/modules/channel.ts deleted file mode 100644 index 999b9a6..0000000 --- a/src/modules/channel.ts +++ /dev/null @@ -1,34 +0,0 @@ -import ClusterWS from '../index' -import { TListener, logError } from '../utils/utils' - -export class Channel { - private listener: TListener - - constructor(private socket: ClusterWS, private channel: string) { - this.subscribe() - } - - public watch(listener: TListener): Channel { - if ({}.toString.call(listener) !== '[object Function]') return logError('Listener must be a function') - this.listener = listener - return this - } - - public publish(data: any): Channel { - this.socket.send(this.channel, data, 'publish') - return this - } - - public unsubscribe(): void { - this.socket.send('unsubscribe', this.channel, 'system') - this.socket.channels[this.channel] = null - } - - public onMessage(data: any): void { - if (this.listener) this.listener.call(null, data) - } - - public subscribe(): void { - this.socket.send('subscribe', this.channel, 'system') - } -} \ No newline at end of file diff --git a/src/modules/channel/channel.ts b/src/modules/channel/channel.ts new file mode 100644 index 0000000..c5b37db --- /dev/null +++ b/src/modules/channel/channel.ts @@ -0,0 +1,35 @@ +import ClusterWS from '../../index' +import { Listener, logError } from '../../utils/utils' + +export class Channel { + private listener: Listener + + constructor(private socket: ClusterWS, public name: string) { + this.subscribe() + } + + public watch(listener: Listener): Channel { + if ({}.toString.call(listener) !== '[object Function]') + return logError('Listener must be a function') + this.listener = listener + return this + } + + public publish(data: any): Channel { + this.socket.send(this.name, data, 'publish') + return this + } + + public unsubscribe(): void { + this.socket.send('unsubscribe', this.name, 'system') + this.socket.channels[this.name] = null + } + + public onMessage(data: any): void { + this.listener && this.listener.call(null, data) + } + + public subscribe(): void { + this.socket.send('subscribe', this.name, 'system') + } +} \ No newline at end of file diff --git a/src/modules/emitter/emitter.ts b/src/modules/emitter/emitter.ts new file mode 100644 index 0000000..cb18f25 --- /dev/null +++ b/src/modules/emitter/emitter.ts @@ -0,0 +1,19 @@ +import { Listener, logError } from '../../utils/utils' + +export class EventEmitter { + private events: any = {} + + public on(event: string, listener: Listener): void { + if ({}.toString.call(listener) !== '[object Function]') + return logError('Listener must be a function') + this.events[event] = listener + } + + public emit(event: string, ...args: any[]): void { + if (this.events[event]) this.events[event].call(null, ...args) + } + + public removeAllEvents(): void { + this.events = {} + } +} \ No newline at end of file diff --git a/src/modules/parser/parser.ts b/src/modules/parser/parser.ts new file mode 100644 index 0000000..da854dc --- /dev/null +++ b/src/modules/parser/parser.ts @@ -0,0 +1,40 @@ +import ClusterWS from '../../index' + +export function buffer(str: string): ByteString { + const length: number = str.length + const uint: any = new Uint8Array(length) + for (let i: number = 0; i < length; i++) uint[i] = str.charCodeAt(i) + return uint.buffer +} + +export function decode(socket: ClusterWS, message: any): any { + switch (message['#'][0]) { + case 'e': return socket.events.emit(message['#'][1], message['#'][2]) + case 'p': socket.channels[message['#'][1]] && socket.channels[message['#'][1]].onMessage(message['#'][2]) + case 's': + switch (message['#'][1]) { + case 'c': + socket.pingInterval = setInterval((): void => + socket.missedPing++ > 2 && socket.disconnect(4001, 'Did not get pings'), message['#'][2].ping) + socket.useBinary = message['#'][2].binary + socket.events.emit('connect') + default: break + } + default: break + } +} + +export function encode(event: string, data: any, type: string): any { + switch (type) { + case 'ping': return event + case 'emit': return JSON.stringify({ '#': ['e', event, data] }) + case 'publish': return JSON.stringify({ '#': ['p', event, data] }) + case 'system': switch (event) { + case 'subscribe': return JSON.stringify({ '#': ['s', 's', data] }) + case 'unsubscribe': return JSON.stringify({ '#': ['s', 'u', data] }) + case 'configuration': return JSON.stringify({ '#': ['s', 'c', data] }) + default: break + } + default: break + } +} \ No newline at end of file diff --git a/src/modules/reconnection.ts b/src/modules/reconnection/reconnection.ts similarity index 87% rename from src/modules/reconnection.ts rename to src/modules/reconnection/reconnection.ts index 5ccaa2b..7e63b79 100644 --- a/src/modules/reconnection.ts +++ b/src/modules/reconnection/reconnection.ts @@ -1,4 +1,4 @@ -import ClusterWS from '../index' +import ClusterWS from '../../index' export class Reconnection { public inReconnectionState: boolean = false @@ -18,10 +18,12 @@ export class Reconnection { this.inReconnectionState = false this.reconnectionAttempted = 0 - for (const key in this.socket.channels) this.socket.channels[key] ? this.socket.channels[key].subscribe() : null + for (const key in this.socket.channels) + this.socket.channels[key] && this.socket.channels[key].subscribe() } public reconnect(): void { + if (this.inReconnectionState) return this.inReconnectionState = true this.interval = setInterval((): void => { if (this.socket.getState() === this.socket.websocket.CLOSED) { diff --git a/src/utils/emitter.ts b/src/utils/emitter.ts deleted file mode 100644 index 21b29ff..0000000 --- a/src/utils/emitter.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { TListener, logError } from './utils' - -export class EventEmitter { - private events: any = {} - - public on(event: string, listener: TListener): void { - if ({}.toString.call(listener) !== '[object Function]') return logError('Listener must be a function') - if (!this.events[event]) this.events[event] = listener - } - - public emit(event: string, ...args: any[]): void { - if (this.events[event]) this.events[event].call(null, ...args) - } - - public removeAllEvents(): void { - this.events = {} - } -} \ No newline at end of file diff --git a/src/utils/utils.ts b/src/utils/utils.ts index 7fa638b..567b73a 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -1,24 +1,23 @@ -export type TListener = (...args: any[]) => void -export type TSocketMessage = any +export type Listener = (...args: any[]) => void -export interface IObject { +export interface CustomObject { [propName: string]: any } -export interface IUserOptions { - url: string - autoReconnect?: boolean - reconnectionIntervalMin?: number - reconnectionIntervalMax?: number - reconnectionAttempts?: number -} - -export interface IOptions { +export interface Options { url: string autoReconnect: boolean + reconnectionAttempts: number reconnectionIntervalMin: number reconnectionIntervalMax: number - reconnectionAttempts: number +} + +export interface Configurations { + url: string + autoReconnect?: boolean + reconnectionAttempts?: number + reconnectionIntervalMin?: number + reconnectionIntervalMax?: number } export function logError(data: T): any { From 06f763b0eb0e2c65c904b78ead1d9e58c44eed92 Mon Sep 17 00:00:00 2001 From: Dmitrii Goriunov Date: Wed, 3 Jan 2018 21:12:52 +1300 Subject: [PATCH 15/21] remove seporate file for parser --- dist/browser/clusterws.js | 221 +++++++++++++++++----------------- dist/browser/clusterws.min.js | 2 +- dist/index.d.ts | 8 -- dist/index.js | 144 +++++++++++----------- src/index.ts | 54 +++++++-- src/modules/parser/parser.ts | 40 ------ 6 files changed, 226 insertions(+), 243 deletions(-) delete mode 100644 src/modules/parser/parser.ts diff --git a/dist/browser/clusterws.js b/dist/browser/clusterws.js index ca72cd7..50fbd2d 100644 --- a/dist/browser/clusterws.js +++ b/dist/browser/clusterws.js @@ -1,73 +1,39 @@ var ClusterWS = function() { "use strict"; - function t(t, n, e) { - switch (e) { - case "ping": - return t; - - case "emit": - return JSON.stringify({ - "#": [ "e", t, n ] - }); - - case "publish": - return JSON.stringify({ - "#": [ "p", t, n ] - }); - - case "system": - switch (t) { - case "subscribe": - return JSON.stringify({ - "#": [ "s", "s", n ] - }); - - case "unsubscribe": - return JSON.stringify({ - "#": [ "s", "u", n ] - }); - - case "configuration": - return JSON.stringify({ - "#": [ "s", "c", n ] - }); - } - } - } - function n(t) { + function t(t) { return console.log(t); } var e = function() { - function t(t, n) { - this.socket = t, this.name = n, this.subscribe(); + function e(t, e) { + this.socket = t, this.name = e, this.subscribe(); } - return t.prototype.watch = function(t) { - return "[object Function]" !== {}.toString.call(t) ? n("Listener must be a function") : (this.listener = t, + return e.prototype.watch = function(e) { + return "[object Function]" !== {}.toString.call(e) ? t("Listener must be a function") : (this.listener = e, this); - }, t.prototype.publish = function(t) { + }, e.prototype.publish = function(t) { return this.socket.send(this.name, t, "publish"), this; - }, t.prototype.unsubscribe = function() { + }, e.prototype.unsubscribe = function() { this.socket.send("unsubscribe", this.name, "system"), this.socket.channels[this.name] = null; - }, t.prototype.onMessage = function(t) { + }, e.prototype.onMessage = function(t) { this.listener && this.listener.call(null, t); - }, t.prototype.subscribe = function() { + }, e.prototype.subscribe = function() { this.socket.send("subscribe", this.name, "system"); - }, t; - }(), o = function() { - function t() { + }, e; + }(), n = function() { + function e() { this.events = {}; } - return t.prototype.on = function(t, e) { - if ("[object Function]" !== {}.toString.call(e)) return n("Listener must be a function"); - this.events[t] = e; - }, t.prototype.emit = function(t) { - for (var n = [], e = 1; e < arguments.length; e++) n[e - 1] = arguments[e]; - this.events[t] && (o = this.events[t]).call.apply(o, [ null ].concat(n)); + return e.prototype.on = function(e, n) { + if ("[object Function]" !== {}.toString.call(n)) return t("Listener must be a function"); + this.events[e] = n; + }, e.prototype.emit = function(t) { + for (var e = [], n = 1; n < arguments.length; n++) e[n - 1] = arguments[n]; + this.events[t] && (o = this.events[t]).call.apply(o, [ null ].concat(e)); var o; - }, t.prototype.removeAllEvents = function() { + }, e.prototype.removeAllEvents = function() { this.events = {}; - }, t; - }(), i = function() { + }, e; + }(), o = function() { function t(t) { this.socket = t, this.inReconnectionState = !1, this.reconnectionAttempted = 0, this.autoReconnect = this.socket.options.autoReconnect; @@ -88,70 +54,103 @@ var ClusterWS = function() { }, t; }(); return function() { - function s(t) { - return this.channels = {}, this.events = new o(), this.missedPing = 0, this.useBinary = !1, - t.url ? (this.options = { - url: t.url, - autoReconnect: t.autoReconnect || !1, - reconnectionAttempts: t.reconnectionAttempts || 0, - reconnectionIntervalMin: t.reconnectionIntervalMin || 1e3, - reconnectionIntervalMax: t.reconnectionIntervalMax || 5e3 - }, this.options.reconnectionIntervalMin > this.options.reconnectionIntervalMax ? n("reconnectionIntervalMin can not be more then reconnectionIntervalMax") : (this.reconnection = new i(this), - void this.create())) : n("Url must be provided and it must be string"); + function i(e) { + return this.channels = {}, this.events = new n(), this.missedPing = 0, this.useBinary = !1, + e.url ? (this.options = { + url: e.url, + autoReconnect: e.autoReconnect || !1, + reconnectionAttempts: e.reconnectionAttempts || 0, + reconnectionIntervalMin: e.reconnectionIntervalMin || 1e3, + reconnectionIntervalMax: e.reconnectionIntervalMax || 5e3 + }, this.options.reconnectionIntervalMin > this.options.reconnectionIntervalMax ? t("reconnectionIntervalMin can not be more then reconnectionIntervalMax") : (this.reconnection = new o(this), + void this.create())) : t("Url must be provided and it must be string"); } - return s.prototype.create = function() { - var t = this, e = window.MozWebSocket || window.WebSocket; - this.websocket = new e(this.options.url), this.websocket.binaryType = "arraybuffer", + return i.prototype.create = function() { + var e = this, n = window.MozWebSocket || window.WebSocket; + this.websocket = new n(this.options.url), this.websocket.binaryType = "arraybuffer", this.websocket.onopen = function() { - return t.reconnection.isConnected(); - }, this.websocket.onerror = function(n) { - return t.events.emit("error", n.message); - }, this.websocket.onmessage = function(e) { - var o = "string" != typeof e.data ? String.fromCharCode.apply(null, new Uint8Array(e.data)) : e.data; - if ("#0" === o) return t.missedPing = 0, t.send("#1", null, "ping"); + return e.reconnection.isConnected(); + }, this.websocket.onerror = function(t) { + return e.events.emit("error", t.message); + }, this.websocket.onmessage = function(n) { + var o = "string" != typeof n.data ? String.fromCharCode.apply(null, new Uint8Array(n.data)) : n.data; + if ("#0" === o) return e.missedPing = 0, e.send("#1", null, "ping"); try { o = JSON.parse(o); - } catch (t) { - return n(t); + } catch (e) { + return t(e); } - !function(t, n) { - switch (n["#"][0]) { - case "e": - return t.events.emit(n["#"][1], n["#"][2]); - - case "p": - t.channels[n["#"][1]] && t.channels[n["#"][1]].onMessage(n["#"][2]); - - case "s": - switch (n["#"][1]) { - case "c": - t.pingInterval = setInterval(function() { - return t.missedPing++ > 2 && t.disconnect(4001, "Did not get pings"); - }, n["#"][2].ping), t.useBinary = n["#"][2].binary, t.events.emit("connect"); - } - } - }(t, o); - }, this.websocket.onclose = function(n) { - if (t.missedPing = 0, clearInterval(t.pingInterval), t.events.emit("disconnect", n.code, n.reason), - t.options.autoReconnect && 1e3 !== n.code) return t.reconnection.reconnect(); - t.events.removeAllEvents(); - for (var e in t) t[e] && (t[e] = null); + i.decode(e, o); + }, this.websocket.onclose = function(t) { + if (e.missedPing = 0, clearInterval(e.pingInterval), e.events.emit("disconnect", t.code, t.reason), + e.options.autoReconnect && 1e3 !== t.code) return e.reconnection.reconnect(); + e.events.removeAllEvents(); + for (var n in e) e[n] && (e[n] = null); }; - }, s.prototype.on = function(t, n) { - this.events.on(t, n); - }, s.prototype.send = function(n, e, o) { - void 0 === o && (o = "emit"), this.websocket.send(this.useBinary ? function(t) { - for (var n = t.length, e = new Uint8Array(n), o = 0; o < n; o++) e[o] = t.charCodeAt(o); - return e.buffer; - }(t(n, e, o)) : t(n, e, o)); - }, s.prototype.disconnect = function(t, n) { - this.websocket.close(t || 1e3, n); - }, s.prototype.getState = function() { + }, i.prototype.on = function(t, e) { + this.events.on(t, e); + }, i.prototype.send = function(t, e, n) { + void 0 === n && (n = "emit"), this.websocket.send(this.useBinary ? i.buffer(i.encode(t, e, n)) : i.encode(t, e, n)); + }, i.prototype.disconnect = function(t, e) { + this.websocket.close(t || 1e3, e); + }, i.prototype.getState = function() { return this.websocket.readyState; - }, s.prototype.subscribe = function(t) { + }, i.prototype.subscribe = function(t) { return this.channels[t] ? this.channels[t] : this.channels[t] = new e(this, t); - }, s.prototype.getChannelByName = function(t) { + }, i.prototype.getChannelByName = function(t) { return this.channels[t]; - }, s; + }, i.buffer = function(t) { + for (var e = t.length, n = new Uint8Array(e), o = 0; o < e; o++) n[o] = t.charCodeAt(o); + return n.buffer; + }, i.decode = function(t, e) { + switch (e["#"][0]) { + case "e": + return t.events.emit(e["#"][1], e["#"][2]); + + case "p": + t.channels[e["#"][1]] && t.channels[e["#"][1]].onMessage(e["#"][2]); + + case "s": + switch (e["#"][1]) { + case "c": + t.pingInterval = setInterval(function() { + return t.missedPing++ > 2 && t.disconnect(4001, "Did not get pings"); + }, e["#"][2].ping), t.useBinary = e["#"][2].binary, t.events.emit("connect"); + } + } + }, i.encode = function(t, e, n) { + switch (n) { + case "ping": + return t; + + case "emit": + return JSON.stringify({ + "#": [ "e", t, e ] + }); + + case "publish": + return JSON.stringify({ + "#": [ "p", t, e ] + }); + + case "system": + switch (t) { + case "subscribe": + return JSON.stringify({ + "#": [ "s", "s", e ] + }); + + case "unsubscribe": + return JSON.stringify({ + "#": [ "s", "u", e ] + }); + + case "configuration": + return JSON.stringify({ + "#": [ "s", "c", e ] + }); + } + } + }, i; }(); }(); diff --git a/dist/browser/clusterws.min.js b/dist/browser/clusterws.min.js index 09d3771..7b60443 100644 --- a/dist/browser/clusterws.min.js +++ b/dist/browser/clusterws.min.js @@ -1 +1 @@ -var ClusterWS=function(){"use strict";function t(t,n,e){switch(e){case"ping":return t;case"emit":return JSON.stringify({"#":["e",t,n]});case"publish":return JSON.stringify({"#":["p",t,n]});case"system":switch(t){case"subscribe":return JSON.stringify({"#":["s","s",n]});case"unsubscribe":return JSON.stringify({"#":["s","u",n]});case"configuration":return JSON.stringify({"#":["s","c",n]})}}}function n(t){return console.log(t)}var e=function(){function t(t,n){this.socket=t,this.name=n,this.subscribe()}return t.prototype.watch=function(t){return"[object Function]"!=={}.toString.call(t)?n("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}(),o=function(){function t(){this.events={}}return t.prototype.on=function(t,e){if("[object Function]"!=={}.toString.call(e))return n("Listener must be a function");this.events[t]=e},t.prototype.emit=function(t){for(var n=[],e=1;e=t.socket.options.reconnectionAttempts&&(clearInterval(t.interval),t.autoReconnect=!1,t.inReconnectionState=!1),clearTimeout(t.timer),t.timer=setTimeout(function(){return t.socket.create()},Math.floor(Math.random()*(t.socket.options.reconnectionIntervalMax-t.socket.options.reconnectionIntervalMin+1))))},this.socket.options.reconnectionIntervalMin))},t}();return function(){function s(t){return this.channels={},this.events=new o,this.missedPing=0,this.useBinary=!1,t.url?(this.options={url:t.url,autoReconnect:t.autoReconnect||!1,reconnectionAttempts:t.reconnectionAttempts||0,reconnectionIntervalMin:t.reconnectionIntervalMin||1e3,reconnectionIntervalMax:t.reconnectionIntervalMax||5e3},this.options.reconnectionIntervalMin>this.options.reconnectionIntervalMax?n("reconnectionIntervalMin can not be more then reconnectionIntervalMax"):(this.reconnection=new i(this),void this.create())):n("Url must be provided and it must be string")}return s.prototype.create=function(){var t=this,e=window.MozWebSocket||window.WebSocket;this.websocket=new e(this.options.url),this.websocket.binaryType="arraybuffer",this.websocket.onopen=function(){return t.reconnection.isConnected()},this.websocket.onerror=function(n){return t.events.emit("error",n.message)},this.websocket.onmessage=function(e){var o="string"!=typeof e.data?String.fromCharCode.apply(null,new Uint8Array(e.data)):e.data;if("#0"===o)return t.missedPing=0,t.send("#1",null,"ping");try{o=JSON.parse(o)}catch(t){return n(t)}!function(t,n){switch(n["#"][0]){case"e":return t.events.emit(n["#"][1],n["#"][2]);case"p":t.channels[n["#"][1]]&&t.channels[n["#"][1]].onMessage(n["#"][2]);case"s":switch(n["#"][1]){case"c":t.pingInterval=setInterval(function(){return t.missedPing++>2&&t.disconnect(4001,"Did not get pings")},n["#"][2].ping),t.useBinary=n["#"][2].binary,t.events.emit("connect")}}}(t,o)},this.websocket.onclose=function(n){if(t.missedPing=0,clearInterval(t.pingInterval),t.events.emit("disconnect",n.code,n.reason),t.options.autoReconnect&&1e3!==n.code)return t.reconnection.reconnect();t.events.removeAllEvents();for(var e in t)t[e]&&(t[e]=null)}},s.prototype.on=function(t,n){this.events.on(t,n)},s.prototype.send=function(n,e,o){void 0===o&&(o="emit"),this.websocket.send(this.useBinary?function(t){for(var n=t.length,e=new Uint8Array(n),o=0;o=t.socket.options.reconnectionAttempts&&(clearInterval(t.interval),t.autoReconnect=!1,t.inReconnectionState=!1),clearTimeout(t.timer),t.timer=setTimeout(function(){return t.socket.create()},Math.floor(Math.random()*(t.socket.options.reconnectionIntervalMax-t.socket.options.reconnectionIntervalMin+1))))},this.socket.options.reconnectionIntervalMin))},t}();return function(){function i(e){return this.channels={},this.events=new n,this.missedPing=0,this.useBinary=!1,e.url?(this.options={url:e.url,autoReconnect:e.autoReconnect||!1,reconnectionAttempts:e.reconnectionAttempts||0,reconnectionIntervalMin:e.reconnectionIntervalMin||1e3,reconnectionIntervalMax:e.reconnectionIntervalMax||5e3},this.options.reconnectionIntervalMin>this.options.reconnectionIntervalMax?t("reconnectionIntervalMin can not be more then reconnectionIntervalMax"):(this.reconnection=new o(this),void this.create())):t("Url must be provided and it must be string")}return i.prototype.create=function(){var e=this,n=window.MozWebSocket||window.WebSocket;this.websocket=new n(this.options.url),this.websocket.binaryType="arraybuffer",this.websocket.onopen=function(){return e.reconnection.isConnected()},this.websocket.onerror=function(t){return e.events.emit("error",t.message)},this.websocket.onmessage=function(n){var o="string"!=typeof n.data?String.fromCharCode.apply(null,new Uint8Array(n.data)):n.data;if("#0"===o)return e.missedPing=0,e.send("#1",null,"ping");try{o=JSON.parse(o)}catch(e){return t(e)}i.decode(e,o)},this.websocket.onclose=function(t){if(e.missedPing=0,clearInterval(e.pingInterval),e.events.emit("disconnect",t.code,t.reason),e.options.autoReconnect&&1e3!==t.code)return e.reconnection.reconnect();e.events.removeAllEvents();for(var n in e)e[n]&&(e[n]=null)}},i.prototype.on=function(t,e){this.events.on(t,e)},i.prototype.send=function(t,e,n){void 0===n&&(n="emit"),this.websocket.send(this.useBinary?i.buffer(i.encode(t,e,n)):i.encode(t,e,n))},i.prototype.disconnect=function(t,e){this.websocket.close(t||1e3,e)},i.prototype.getState=function(){return this.websocket.readyState},i.prototype.subscribe=function(t){return this.channels[t]?this.channels[t]:this.channels[t]=new e(this,t)},i.prototype.getChannelByName=function(t){return this.channels[t]},i.buffer=function(t){for(var e=t.length,n=new Uint8Array(e),o=0;o2&&t.disconnect(4001,"Did not get pings")},e["#"][2].ping),t.useBinary=e["#"][2].binary,t.events.emit("connect")}}},i.encode=function(t,e,n){switch(n){case"ping":return t;case"emit":return JSON.stringify({"#":["e",t,e]});case"publish":return JSON.stringify({"#":["p",t,e]});case"system":switch(t){case"subscribe":return JSON.stringify({"#":["s","s",e]});case"unsubscribe":return JSON.stringify({"#":["s","u",e]});case"configuration":return JSON.stringify({"#":["s","c",e]})}}},i}()}(); diff --git a/dist/index.d.ts b/dist/index.d.ts index 672bc4b..10937cd 100644 --- a/dist/index.d.ts +++ b/dist/index.d.ts @@ -4,10 +4,6 @@ export default class ClusterWS { options: Options; websocket: WebSocket; channels: CustomObject; - events: EventEmitter; - missedPing: number; - useBinary: boolean; - pingInterval: any; constructor(configurations: Configurations); create(): void; on(event: string, listener: Listener): void; @@ -34,10 +30,6 @@ export class EventEmitter { removeAllEvents(): void; } -export function buffer(str: string): ByteString; -export function decode(socket: ClusterWS, message: any): any; -export function encode(event: string, data: any, type: string): any; - export class Reconnection { socket: ClusterWS; inReconnectionState: boolean; diff --git a/dist/index.js b/dist/index.js index d6b3569..d349c3f 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1,63 +1,5 @@ "use strict"; -function buffer(t) { - for (var e = t.length, n = new Uint8Array(e), o = 0; o < e; o++) n[o] = t.charCodeAt(o); - return n.buffer; -} - -function decode(t, e) { - switch (e["#"][0]) { - case "e": - return t.events.emit(e["#"][1], e["#"][2]); - - case "p": - t.channels[e["#"][1]] && t.channels[e["#"][1]].onMessage(e["#"][2]); - - case "s": - switch (e["#"][1]) { - case "c": - t.pingInterval = setInterval(function() { - return t.missedPing++ > 2 && t.disconnect(4001, "Did not get pings"); - }, e["#"][2].ping), t.useBinary = e["#"][2].binary, t.events.emit("connect"); - } - } -} - -function encode(t, e, n) { - switch (n) { - case "ping": - return t; - - case "emit": - return JSON.stringify({ - "#": [ "e", t, e ] - }); - - case "publish": - return JSON.stringify({ - "#": [ "p", t, e ] - }); - - case "system": - switch (t) { - case "subscribe": - return JSON.stringify({ - "#": [ "s", "s", e ] - }); - - case "unsubscribe": - return JSON.stringify({ - "#": [ "s", "u", e ] - }); - - case "configuration": - return JSON.stringify({ - "#": [ "s", "c", e ] - }); - } - } -} - function logError(t) { return console.log(t); } @@ -124,31 +66,31 @@ var Channel = function() { void this.create())) : logError("Url must be provided and it must be string"); } return t.prototype.create = function() { - var t = this, e = window.MozWebSocket || window.WebSocket; - this.websocket = new e(this.options.url), this.websocket.binaryType = "arraybuffer", + var e = this, n = window.MozWebSocket || window.WebSocket; + this.websocket = new n(this.options.url), this.websocket.binaryType = "arraybuffer", this.websocket.onopen = function() { - return t.reconnection.isConnected(); - }, this.websocket.onerror = function(e) { - return t.events.emit("error", e.message); - }, this.websocket.onmessage = function(e) { - var n = "string" != typeof e.data ? String.fromCharCode.apply(null, new Uint8Array(e.data)) : e.data; - if ("#0" === n) return t.missedPing = 0, t.send("#1", null, "ping"); + return e.reconnection.isConnected(); + }, this.websocket.onerror = function(t) { + return e.events.emit("error", t.message); + }, this.websocket.onmessage = function(n) { + var o = "string" != typeof n.data ? String.fromCharCode.apply(null, new Uint8Array(n.data)) : n.data; + if ("#0" === o) return e.missedPing = 0, e.send("#1", null, "ping"); try { - n = JSON.parse(n); + o = JSON.parse(o); } catch (t) { return logError(t); } - decode(t, n); - }, this.websocket.onclose = function(e) { - if (t.missedPing = 0, clearInterval(t.pingInterval), t.events.emit("disconnect", e.code, e.reason), - t.options.autoReconnect && 1e3 !== e.code) return t.reconnection.reconnect(); - t.events.removeAllEvents(); - for (var n in t) t[n] && (t[n] = null); + t.decode(e, o); + }, this.websocket.onclose = function(t) { + if (e.missedPing = 0, clearInterval(e.pingInterval), e.events.emit("disconnect", t.code, t.reason), + e.options.autoReconnect && 1e3 !== t.code) return e.reconnection.reconnect(); + e.events.removeAllEvents(); + for (var n in e) e[n] && (e[n] = null); }; }, t.prototype.on = function(t, e) { this.events.on(t, e); - }, t.prototype.send = function(t, e, n) { - void 0 === n && (n = "emit"), this.websocket.send(this.useBinary ? buffer(encode(t, e, n)) : encode(t, e, n)); + }, t.prototype.send = function(e, n, o) { + void 0 === o && (o = "emit"), this.websocket.send(this.useBinary ? t.buffer(t.encode(e, n, o)) : t.encode(e, n, o)); }, t.prototype.disconnect = function(t, e) { this.websocket.close(t || 1e3, e); }, t.prototype.getState = function() { @@ -157,6 +99,58 @@ var Channel = function() { return this.channels[t] ? this.channels[t] : this.channels[t] = new Channel(this, t); }, t.prototype.getChannelByName = function(t) { return this.channels[t]; + }, t.buffer = function(t) { + for (var e = t.length, n = new Uint8Array(e), o = 0; o < e; o++) n[o] = t.charCodeAt(o); + return n.buffer; + }, t.decode = function(t, e) { + switch (e["#"][0]) { + case "e": + return t.events.emit(e["#"][1], e["#"][2]); + + case "p": + t.channels[e["#"][1]] && t.channels[e["#"][1]].onMessage(e["#"][2]); + + case "s": + switch (e["#"][1]) { + case "c": + t.pingInterval = setInterval(function() { + return t.missedPing++ > 2 && t.disconnect(4001, "Did not get pings"); + }, e["#"][2].ping), t.useBinary = e["#"][2].binary, t.events.emit("connect"); + } + } + }, t.encode = function(t, e, n) { + switch (n) { + case "ping": + return t; + + case "emit": + return JSON.stringify({ + "#": [ "e", t, e ] + }); + + case "publish": + return JSON.stringify({ + "#": [ "p", t, e ] + }); + + case "system": + switch (t) { + case "subscribe": + return JSON.stringify({ + "#": [ "s", "s", e ] + }); + + case "unsubscribe": + return JSON.stringify({ + "#": [ "s", "u", e ] + }); + + case "configuration": + return JSON.stringify({ + "#": [ "s", "c", e ] + }); + } + } }, t; }(); diff --git a/src/index.ts b/src/index.ts index 3456cf3..240b754 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,3 @@ -import { buffer, decode, encode } from './modules/parser/parser' import { Channel } from './modules/channel/channel' import { EventEmitter } from './modules/emitter/emitter' import { Options, Configurations, logError, Listener, CustomObject } from './utils/utils' @@ -11,10 +10,10 @@ export default class ClusterWS { public websocket: WebSocket public channels: CustomObject = {} - public events: EventEmitter = new EventEmitter() - public missedPing: number = 0 - public useBinary: boolean = false - public pingInterval: any + private events: EventEmitter = new EventEmitter() + private missedPing: number = 0 + private useBinary: boolean = false + private pingInterval: any private reconnection: Reconnection @@ -55,7 +54,7 @@ export default class ClusterWS { data = JSON.parse(data) } catch (e) { return logError(e) } - decode(this, data) + ClusterWS.decode(this, data) } this.websocket.onclose = (event: CloseEvent): void => { this.missedPing = 0 @@ -76,8 +75,8 @@ export default class ClusterWS { public send(event: string, data: any, type: string = 'emit'): void { this.websocket.send(this.useBinary ? - buffer(encode(event, data, type)) : - encode(event, data, type)) + ClusterWS.buffer(ClusterWS.encode(event, data, type)) : + ClusterWS.encode(event, data, type)) } public disconnect(code?: number, msg?: any): void { @@ -96,4 +95,43 @@ export default class ClusterWS { public getChannelByName(channelName: string): Channel { return this.channels[channelName] } + + private static buffer(str: string): ByteString { + const length: number = str.length + const uint: any = new Uint8Array(length) + for (let i: number = 0; i < length; i++) uint[i] = str.charCodeAt(i) + return uint.buffer + } + + private static decode(socket: ClusterWS, message: any): any { + switch (message['#'][0]) { + case 'e': return socket.events.emit(message['#'][1], message['#'][2]) + case 'p': socket.channels[message['#'][1]] && socket.channels[message['#'][1]].onMessage(message['#'][2]) + case 's': + switch (message['#'][1]) { + case 'c': + socket.pingInterval = setInterval((): void => + socket.missedPing++ > 2 && socket.disconnect(4001, 'Did not get pings'), message['#'][2].ping) + socket.useBinary = message['#'][2].binary + socket.events.emit('connect') + default: break + } + default: break + } + } + + private static encode(event: string, data: any, type: string): any { + switch (type) { + case 'ping': return event + case 'emit': return JSON.stringify({ '#': ['e', event, data] }) + case 'publish': return JSON.stringify({ '#': ['p', event, data] }) + case 'system': switch (event) { + case 'subscribe': return JSON.stringify({ '#': ['s', 's', data] }) + case 'unsubscribe': return JSON.stringify({ '#': ['s', 'u', data] }) + case 'configuration': return JSON.stringify({ '#': ['s', 'c', data] }) + default: break + } + default: break + } + } } \ No newline at end of file diff --git a/src/modules/parser/parser.ts b/src/modules/parser/parser.ts deleted file mode 100644 index da854dc..0000000 --- a/src/modules/parser/parser.ts +++ /dev/null @@ -1,40 +0,0 @@ -import ClusterWS from '../../index' - -export function buffer(str: string): ByteString { - const length: number = str.length - const uint: any = new Uint8Array(length) - for (let i: number = 0; i < length; i++) uint[i] = str.charCodeAt(i) - return uint.buffer -} - -export function decode(socket: ClusterWS, message: any): any { - switch (message['#'][0]) { - case 'e': return socket.events.emit(message['#'][1], message['#'][2]) - case 'p': socket.channels[message['#'][1]] && socket.channels[message['#'][1]].onMessage(message['#'][2]) - case 's': - switch (message['#'][1]) { - case 'c': - socket.pingInterval = setInterval((): void => - socket.missedPing++ > 2 && socket.disconnect(4001, 'Did not get pings'), message['#'][2].ping) - socket.useBinary = message['#'][2].binary - socket.events.emit('connect') - default: break - } - default: break - } -} - -export function encode(event: string, data: any, type: string): any { - switch (type) { - case 'ping': return event - case 'emit': return JSON.stringify({ '#': ['e', event, data] }) - case 'publish': return JSON.stringify({ '#': ['p', event, data] }) - case 'system': switch (event) { - case 'subscribe': return JSON.stringify({ '#': ['s', 's', data] }) - case 'unsubscribe': return JSON.stringify({ '#': ['s', 'u', data] }) - case 'configuration': return JSON.stringify({ '#': ['s', 'c', data] }) - default: break - } - default: break - } -} \ No newline at end of file From 1e65a1800ede2204c3a907fded23ae226cb91b9c Mon Sep 17 00:00:00 2001 From: Dmitrii Goriunov Date: Wed, 3 Jan 2018 21:22:59 +1300 Subject: [PATCH 16/21] Roll back with out static files --- dist/browser/clusterws.js | 213 +++++++++++++++++----------------- dist/browser/clusterws.min.js | 2 +- dist/index.d.ts | 8 ++ dist/index.js | 148 ++++++++++++----------- src/index.ts | 56 ++------- src/modules/parser/parser.ts | 40 +++++++ 6 files changed, 243 insertions(+), 224 deletions(-) create mode 100644 src/modules/parser/parser.ts diff --git a/dist/browser/clusterws.js b/dist/browser/clusterws.js index 50fbd2d..f9c3fb0 100644 --- a/dist/browser/clusterws.js +++ b/dist/browser/clusterws.js @@ -3,36 +3,36 @@ var ClusterWS = function() { function t(t) { return console.log(t); } - var e = function() { - function e(t, e) { - this.socket = t, this.name = e, this.subscribe(); + var n = function() { + function n(t, n) { + this.socket = t, this.name = n, this.subscribe(); } - return e.prototype.watch = function(e) { - return "[object Function]" !== {}.toString.call(e) ? t("Listener must be a function") : (this.listener = e, + return n.prototype.watch = function(n) { + return "[object Function]" !== {}.toString.call(n) ? t("Listener must be a function") : (this.listener = n, this); - }, e.prototype.publish = function(t) { + }, n.prototype.publish = function(t) { return this.socket.send(this.name, t, "publish"), this; - }, e.prototype.unsubscribe = function() { + }, n.prototype.unsubscribe = function() { this.socket.send("unsubscribe", this.name, "system"), this.socket.channels[this.name] = null; - }, e.prototype.onMessage = function(t) { + }, n.prototype.onMessage = function(t) { this.listener && this.listener.call(null, t); - }, e.prototype.subscribe = function() { + }, n.prototype.subscribe = function() { this.socket.send("subscribe", this.name, "system"); - }, e; - }(), n = function() { - function e() { + }, n; + }(), e = function() { + function n() { this.events = {}; } - return e.prototype.on = function(e, n) { - if ("[object Function]" !== {}.toString.call(n)) return t("Listener must be a function"); - this.events[e] = n; - }, e.prototype.emit = function(t) { - for (var e = [], n = 1; n < arguments.length; n++) e[n - 1] = arguments[n]; - this.events[t] && (o = this.events[t]).call.apply(o, [ null ].concat(e)); + return n.prototype.on = function(n, e) { + if ("[object Function]" !== {}.toString.call(e)) return t("Listener must be a function"); + this.events[n] = e; + }, n.prototype.emit = function(t) { + for (var n = [], e = 1; e < arguments.length; e++) n[e - 1] = arguments[e]; + this.events[t] && (o = this.events[t]).call.apply(o, [ null ].concat(n)); var o; - }, e.prototype.removeAllEvents = function() { + }, n.prototype.removeAllEvents = function() { this.events = {}; - }, e; + }, n; }(), o = function() { function t(t) { this.socket = t, this.inReconnectionState = !1, this.reconnectionAttempted = 0, @@ -53,104 +53,105 @@ var ClusterWS = function() { }, this.socket.options.reconnectionIntervalMin)); }, t; }(); + function i(t, n, e) { + switch (e) { + case "ping": + return t; + + case "emit": + return JSON.stringify({ + "#": [ "e", t, n ] + }); + + case "publish": + return JSON.stringify({ + "#": [ "p", t, n ] + }); + + case "system": + switch (t) { + case "subscribe": + return JSON.stringify({ + "#": [ "s", "s", n ] + }); + + case "unsubscribe": + return JSON.stringify({ + "#": [ "s", "u", n ] + }); + + case "configuration": + return JSON.stringify({ + "#": [ "s", "c", n ] + }); + } + } + } return function() { - function i(e) { - return this.channels = {}, this.events = new n(), this.missedPing = 0, this.useBinary = !1, - e.url ? (this.options = { - url: e.url, - autoReconnect: e.autoReconnect || !1, - reconnectionAttempts: e.reconnectionAttempts || 0, - reconnectionIntervalMin: e.reconnectionIntervalMin || 1e3, - reconnectionIntervalMax: e.reconnectionIntervalMax || 5e3 + function s(n) { + return this.channels = {}, this.events = new e(), this.missedPing = 0, this.useBinary = !1, + n.url ? (this.options = { + url: n.url, + autoReconnect: n.autoReconnect || !1, + reconnectionAttempts: n.reconnectionAttempts || 0, + reconnectionIntervalMin: n.reconnectionIntervalMin || 1e3, + reconnectionIntervalMax: n.reconnectionIntervalMax || 5e3 }, this.options.reconnectionIntervalMin > this.options.reconnectionIntervalMax ? t("reconnectionIntervalMin can not be more then reconnectionIntervalMax") : (this.reconnection = new o(this), void this.create())) : t("Url must be provided and it must be string"); } - return i.prototype.create = function() { - var e = this, n = window.MozWebSocket || window.WebSocket; - this.websocket = new n(this.options.url), this.websocket.binaryType = "arraybuffer", + return s.prototype.create = function() { + var n = this, e = window.MozWebSocket || window.WebSocket; + this.websocket = new e(this.options.url), this.websocket.binaryType = "arraybuffer", this.websocket.onopen = function() { - return e.reconnection.isConnected(); + return n.reconnection.isConnected(); }, this.websocket.onerror = function(t) { - return e.events.emit("error", t.message); - }, this.websocket.onmessage = function(n) { - var o = "string" != typeof n.data ? String.fromCharCode.apply(null, new Uint8Array(n.data)) : n.data; - if ("#0" === o) return e.missedPing = 0, e.send("#1", null, "ping"); + return n.events.emit("error", t.message); + }, this.websocket.onmessage = function(e) { + var o = "string" != typeof e.data ? String.fromCharCode.apply(null, new Uint8Array(e.data)) : e.data; + if ("#0" === o) return n.missedPing = 0, n.send("#1", null, "ping"); try { o = JSON.parse(o); - } catch (e) { - return t(e); + } catch (n) { + return t(n); } - i.decode(e, o); + !function(t, n) { + switch (n["#"][0]) { + case "e": + return t.events.emit(n["#"][1], n["#"][2]); + + case "p": + t.channels[n["#"][1]] && t.channels[n["#"][1]].onMessage(n["#"][2]); + + case "s": + switch (n["#"][1]) { + case "c": + t.pingInterval = setInterval(function() { + return t.missedPing++ > 2 && t.disconnect(4001, "Did not get pings"); + }, n["#"][2].ping), t.useBinary = n["#"][2].binary, t.events.emit("connect"); + } + } + }(n, o); }, this.websocket.onclose = function(t) { - if (e.missedPing = 0, clearInterval(e.pingInterval), e.events.emit("disconnect", t.code, t.reason), - e.options.autoReconnect && 1e3 !== t.code) return e.reconnection.reconnect(); - e.events.removeAllEvents(); - for (var n in e) e[n] && (e[n] = null); + if (n.missedPing = 0, clearInterval(n.pingInterval), n.events.emit("disconnect", t.code, t.reason), + n.options.autoReconnect && 1e3 !== t.code) return n.reconnection.reconnect(); + n.events.removeAllEvents(); + for (var e in n) n[e] && (n[e] = null); }; - }, i.prototype.on = function(t, e) { - this.events.on(t, e); - }, i.prototype.send = function(t, e, n) { - void 0 === n && (n = "emit"), this.websocket.send(this.useBinary ? i.buffer(i.encode(t, e, n)) : i.encode(t, e, n)); - }, i.prototype.disconnect = function(t, e) { - this.websocket.close(t || 1e3, e); - }, i.prototype.getState = function() { + }, s.prototype.on = function(t, n) { + this.events.on(t, n); + }, s.prototype.send = function(t, n, e) { + void 0 === e && (e = "emit"), this.websocket.send(this.useBinary ? function(t) { + for (var n = t.length, e = new Uint8Array(n), o = 0; o < n; o++) e[o] = t.charCodeAt(o); + return e.buffer; + }(i(t, n, e)) : i(t, n, e)); + }, s.prototype.disconnect = function(t, n) { + this.websocket.close(t || 1e3, n); + }, s.prototype.getState = function() { return this.websocket.readyState; - }, i.prototype.subscribe = function(t) { - return this.channels[t] ? this.channels[t] : this.channels[t] = new e(this, t); - }, i.prototype.getChannelByName = function(t) { + }, s.prototype.subscribe = function(t) { + return this.channels[t] ? this.channels[t] : this.channels[t] = new n(this, t); + }, s.prototype.getChannelByName = function(t) { return this.channels[t]; - }, i.buffer = function(t) { - for (var e = t.length, n = new Uint8Array(e), o = 0; o < e; o++) n[o] = t.charCodeAt(o); - return n.buffer; - }, i.decode = function(t, e) { - switch (e["#"][0]) { - case "e": - return t.events.emit(e["#"][1], e["#"][2]); - - case "p": - t.channels[e["#"][1]] && t.channels[e["#"][1]].onMessage(e["#"][2]); - - case "s": - switch (e["#"][1]) { - case "c": - t.pingInterval = setInterval(function() { - return t.missedPing++ > 2 && t.disconnect(4001, "Did not get pings"); - }, e["#"][2].ping), t.useBinary = e["#"][2].binary, t.events.emit("connect"); - } - } - }, i.encode = function(t, e, n) { - switch (n) { - case "ping": - return t; - - case "emit": - return JSON.stringify({ - "#": [ "e", t, e ] - }); - - case "publish": - return JSON.stringify({ - "#": [ "p", t, e ] - }); - - case "system": - switch (t) { - case "subscribe": - return JSON.stringify({ - "#": [ "s", "s", e ] - }); - - case "unsubscribe": - return JSON.stringify({ - "#": [ "s", "u", e ] - }); - - case "configuration": - return JSON.stringify({ - "#": [ "s", "c", e ] - }); - } - } - }, i; + }, s; }(); }(); diff --git a/dist/browser/clusterws.min.js b/dist/browser/clusterws.min.js index 7b60443..2120f81 100644 --- a/dist/browser/clusterws.min.js +++ b/dist/browser/clusterws.min.js @@ -1 +1 @@ -var ClusterWS=function(){"use strict";function t(t){return console.log(t)}var e=function(){function e(t,e){this.socket=t,this.name=e,this.subscribe()}return e.prototype.watch=function(e){return"[object Function]"!=={}.toString.call(e)?t("Listener must be a function"):(this.listener=e,this)},e.prototype.publish=function(t){return this.socket.send(this.name,t,"publish"),this},e.prototype.unsubscribe=function(){this.socket.send("unsubscribe",this.name,"system"),this.socket.channels[this.name]=null},e.prototype.onMessage=function(t){this.listener&&this.listener.call(null,t)},e.prototype.subscribe=function(){this.socket.send("subscribe",this.name,"system")},e}(),n=function(){function e(){this.events={}}return e.prototype.on=function(e,n){if("[object Function]"!=={}.toString.call(n))return t("Listener must be a function");this.events[e]=n},e.prototype.emit=function(t){for(var e=[],n=1;n=t.socket.options.reconnectionAttempts&&(clearInterval(t.interval),t.autoReconnect=!1,t.inReconnectionState=!1),clearTimeout(t.timer),t.timer=setTimeout(function(){return t.socket.create()},Math.floor(Math.random()*(t.socket.options.reconnectionIntervalMax-t.socket.options.reconnectionIntervalMin+1))))},this.socket.options.reconnectionIntervalMin))},t}();return function(){function i(e){return this.channels={},this.events=new n,this.missedPing=0,this.useBinary=!1,e.url?(this.options={url:e.url,autoReconnect:e.autoReconnect||!1,reconnectionAttempts:e.reconnectionAttempts||0,reconnectionIntervalMin:e.reconnectionIntervalMin||1e3,reconnectionIntervalMax:e.reconnectionIntervalMax||5e3},this.options.reconnectionIntervalMin>this.options.reconnectionIntervalMax?t("reconnectionIntervalMin can not be more then reconnectionIntervalMax"):(this.reconnection=new o(this),void this.create())):t("Url must be provided and it must be string")}return i.prototype.create=function(){var e=this,n=window.MozWebSocket||window.WebSocket;this.websocket=new n(this.options.url),this.websocket.binaryType="arraybuffer",this.websocket.onopen=function(){return e.reconnection.isConnected()},this.websocket.onerror=function(t){return e.events.emit("error",t.message)},this.websocket.onmessage=function(n){var o="string"!=typeof n.data?String.fromCharCode.apply(null,new Uint8Array(n.data)):n.data;if("#0"===o)return e.missedPing=0,e.send("#1",null,"ping");try{o=JSON.parse(o)}catch(e){return t(e)}i.decode(e,o)},this.websocket.onclose=function(t){if(e.missedPing=0,clearInterval(e.pingInterval),e.events.emit("disconnect",t.code,t.reason),e.options.autoReconnect&&1e3!==t.code)return e.reconnection.reconnect();e.events.removeAllEvents();for(var n in e)e[n]&&(e[n]=null)}},i.prototype.on=function(t,e){this.events.on(t,e)},i.prototype.send=function(t,e,n){void 0===n&&(n="emit"),this.websocket.send(this.useBinary?i.buffer(i.encode(t,e,n)):i.encode(t,e,n))},i.prototype.disconnect=function(t,e){this.websocket.close(t||1e3,e)},i.prototype.getState=function(){return this.websocket.readyState},i.prototype.subscribe=function(t){return this.channels[t]?this.channels[t]:this.channels[t]=new e(this,t)},i.prototype.getChannelByName=function(t){return this.channels[t]},i.buffer=function(t){for(var e=t.length,n=new Uint8Array(e),o=0;o2&&t.disconnect(4001,"Did not get pings")},e["#"][2].ping),t.useBinary=e["#"][2].binary,t.events.emit("connect")}}},i.encode=function(t,e,n){switch(n){case"ping":return t;case"emit":return JSON.stringify({"#":["e",t,e]});case"publish":return JSON.stringify({"#":["p",t,e]});case"system":switch(t){case"subscribe":return JSON.stringify({"#":["s","s",e]});case"unsubscribe":return JSON.stringify({"#":["s","u",e]});case"configuration":return JSON.stringify({"#":["s","c",e]})}}},i}()}(); +var ClusterWS=function(){"use strict";function t(t){return console.log(t)}var n=function(){function n(t,n){this.socket=t,this.name=n,this.subscribe()}return n.prototype.watch=function(n){return"[object Function]"!=={}.toString.call(n)?t("Listener must be a function"):(this.listener=n,this)},n.prototype.publish=function(t){return this.socket.send(this.name,t,"publish"),this},n.prototype.unsubscribe=function(){this.socket.send("unsubscribe",this.name,"system"),this.socket.channels[this.name]=null},n.prototype.onMessage=function(t){this.listener&&this.listener.call(null,t)},n.prototype.subscribe=function(){this.socket.send("subscribe",this.name,"system")},n}(),e=function(){function n(){this.events={}}return n.prototype.on=function(n,e){if("[object Function]"!=={}.toString.call(e))return t("Listener must be a function");this.events[n]=e},n.prototype.emit=function(t){for(var n=[],e=1;e=t.socket.options.reconnectionAttempts&&(clearInterval(t.interval),t.autoReconnect=!1,t.inReconnectionState=!1),clearTimeout(t.timer),t.timer=setTimeout(function(){return t.socket.create()},Math.floor(Math.random()*(t.socket.options.reconnectionIntervalMax-t.socket.options.reconnectionIntervalMin+1))))},this.socket.options.reconnectionIntervalMin))},t}();function i(t,n,e){switch(e){case"ping":return t;case"emit":return JSON.stringify({"#":["e",t,n]});case"publish":return JSON.stringify({"#":["p",t,n]});case"system":switch(t){case"subscribe":return JSON.stringify({"#":["s","s",n]});case"unsubscribe":return JSON.stringify({"#":["s","u",n]});case"configuration":return JSON.stringify({"#":["s","c",n]})}}}return function(){function s(n){return this.channels={},this.events=new e,this.missedPing=0,this.useBinary=!1,n.url?(this.options={url:n.url,autoReconnect:n.autoReconnect||!1,reconnectionAttempts:n.reconnectionAttempts||0,reconnectionIntervalMin:n.reconnectionIntervalMin||1e3,reconnectionIntervalMax:n.reconnectionIntervalMax||5e3},this.options.reconnectionIntervalMin>this.options.reconnectionIntervalMax?t("reconnectionIntervalMin can not be more then reconnectionIntervalMax"):(this.reconnection=new o(this),void this.create())):t("Url must be provided and it must be string")}return s.prototype.create=function(){var n=this,e=window.MozWebSocket||window.WebSocket;this.websocket=new e(this.options.url),this.websocket.binaryType="arraybuffer",this.websocket.onopen=function(){return n.reconnection.isConnected()},this.websocket.onerror=function(t){return n.events.emit("error",t.message)},this.websocket.onmessage=function(e){var o="string"!=typeof e.data?String.fromCharCode.apply(null,new Uint8Array(e.data)):e.data;if("#0"===o)return n.missedPing=0,n.send("#1",null,"ping");try{o=JSON.parse(o)}catch(n){return t(n)}!function(t,n){switch(n["#"][0]){case"e":return t.events.emit(n["#"][1],n["#"][2]);case"p":t.channels[n["#"][1]]&&t.channels[n["#"][1]].onMessage(n["#"][2]);case"s":switch(n["#"][1]){case"c":t.pingInterval=setInterval(function(){return t.missedPing++>2&&t.disconnect(4001,"Did not get pings")},n["#"][2].ping),t.useBinary=n["#"][2].binary,t.events.emit("connect")}}}(n,o)},this.websocket.onclose=function(t){if(n.missedPing=0,clearInterval(n.pingInterval),n.events.emit("disconnect",t.code,t.reason),n.options.autoReconnect&&1e3!==t.code)return n.reconnection.reconnect();n.events.removeAllEvents();for(var e in n)n[e]&&(n[e]=null)}},s.prototype.on=function(t,n){this.events.on(t,n)},s.prototype.send=function(t,n,e){void 0===e&&(e="emit"),this.websocket.send(this.useBinary?function(t){for(var n=t.length,e=new Uint8Array(n),o=0;o 2 && t.disconnect(4001, "Did not get pings"); + }, e["#"][2].ping), t.useBinary = e["#"][2].binary, t.events.emit("connect"); + } + } +} + +function encode(t, e, n) { + switch (n) { + case "ping": + return t; + + case "emit": + return JSON.stringify({ + "#": [ "e", t, e ] + }); + + case "publish": + return JSON.stringify({ + "#": [ "p", t, e ] + }); + + case "system": + switch (t) { + case "subscribe": + return JSON.stringify({ + "#": [ "s", "s", e ] + }); + + case "unsubscribe": + return JSON.stringify({ + "#": [ "s", "u", e ] + }); + + case "configuration": + return JSON.stringify({ + "#": [ "s", "c", e ] + }); + } + } +} + +var ClusterWS = function() { function t(t) { return this.channels = {}, this.events = new EventEmitter(), this.missedPing = 0, this.useBinary = !1, t.url ? (this.options = { @@ -66,31 +126,31 @@ var Channel = function() { void this.create())) : logError("Url must be provided and it must be string"); } return t.prototype.create = function() { - var e = this, n = window.MozWebSocket || window.WebSocket; - this.websocket = new n(this.options.url), this.websocket.binaryType = "arraybuffer", + var t = this, e = window.MozWebSocket || window.WebSocket; + this.websocket = new e(this.options.url), this.websocket.binaryType = "arraybuffer", this.websocket.onopen = function() { - return e.reconnection.isConnected(); - }, this.websocket.onerror = function(t) { - return e.events.emit("error", t.message); - }, this.websocket.onmessage = function(n) { - var o = "string" != typeof n.data ? String.fromCharCode.apply(null, new Uint8Array(n.data)) : n.data; - if ("#0" === o) return e.missedPing = 0, e.send("#1", null, "ping"); + return t.reconnection.isConnected(); + }, this.websocket.onerror = function(e) { + return t.events.emit("error", e.message); + }, this.websocket.onmessage = function(e) { + var n = "string" != typeof e.data ? String.fromCharCode.apply(null, new Uint8Array(e.data)) : e.data; + if ("#0" === n) return t.missedPing = 0, t.send("#1", null, "ping"); try { - o = JSON.parse(o); + n = JSON.parse(n); } catch (t) { return logError(t); } - t.decode(e, o); - }, this.websocket.onclose = function(t) { - if (e.missedPing = 0, clearInterval(e.pingInterval), e.events.emit("disconnect", t.code, t.reason), - e.options.autoReconnect && 1e3 !== t.code) return e.reconnection.reconnect(); - e.events.removeAllEvents(); - for (var n in e) e[n] && (e[n] = null); + decode(t, n); + }, this.websocket.onclose = function(e) { + if (t.missedPing = 0, clearInterval(t.pingInterval), t.events.emit("disconnect", e.code, e.reason), + t.options.autoReconnect && 1e3 !== e.code) return t.reconnection.reconnect(); + t.events.removeAllEvents(); + for (var n in t) t[n] && (t[n] = null); }; }, t.prototype.on = function(t, e) { this.events.on(t, e); - }, t.prototype.send = function(e, n, o) { - void 0 === o && (o = "emit"), this.websocket.send(this.useBinary ? t.buffer(t.encode(e, n, o)) : t.encode(e, n, o)); + }, t.prototype.send = function(t, e, n) { + void 0 === n && (n = "emit"), this.websocket.send(this.useBinary ? buffer(encode(t, e, n)) : encode(t, e, n)); }, t.prototype.disconnect = function(t, e) { this.websocket.close(t || 1e3, e); }, t.prototype.getState = function() { @@ -99,58 +159,6 @@ var Channel = function() { return this.channels[t] ? this.channels[t] : this.channels[t] = new Channel(this, t); }, t.prototype.getChannelByName = function(t) { return this.channels[t]; - }, t.buffer = function(t) { - for (var e = t.length, n = new Uint8Array(e), o = 0; o < e; o++) n[o] = t.charCodeAt(o); - return n.buffer; - }, t.decode = function(t, e) { - switch (e["#"][0]) { - case "e": - return t.events.emit(e["#"][1], e["#"][2]); - - case "p": - t.channels[e["#"][1]] && t.channels[e["#"][1]].onMessage(e["#"][2]); - - case "s": - switch (e["#"][1]) { - case "c": - t.pingInterval = setInterval(function() { - return t.missedPing++ > 2 && t.disconnect(4001, "Did not get pings"); - }, e["#"][2].ping), t.useBinary = e["#"][2].binary, t.events.emit("connect"); - } - } - }, t.encode = function(t, e, n) { - switch (n) { - case "ping": - return t; - - case "emit": - return JSON.stringify({ - "#": [ "e", t, e ] - }); - - case "publish": - return JSON.stringify({ - "#": [ "p", t, e ] - }); - - case "system": - switch (t) { - case "subscribe": - return JSON.stringify({ - "#": [ "s", "s", e ] - }); - - case "unsubscribe": - return JSON.stringify({ - "#": [ "s", "u", e ] - }); - - case "configuration": - return JSON.stringify({ - "#": [ "s", "c", e ] - }); - } - } }, t; }(); diff --git a/src/index.ts b/src/index.ts index 240b754..07859e8 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,7 +1,8 @@ import { Channel } from './modules/channel/channel' import { EventEmitter } from './modules/emitter/emitter' -import { Options, Configurations, logError, Listener, CustomObject } from './utils/utils' import { Reconnection } from './modules/reconnection/reconnection' +import { buffer, decode, encode } from './modules/parser/parser' +import { Options, Configurations, logError, Listener, CustomObject } from './utils/utils' declare const window: any @@ -10,10 +11,10 @@ export default class ClusterWS { public websocket: WebSocket public channels: CustomObject = {} - private events: EventEmitter = new EventEmitter() - private missedPing: number = 0 - private useBinary: boolean = false - private pingInterval: any + public events: EventEmitter = new EventEmitter() + public missedPing: number = 0 + public useBinary: boolean = false + public pingInterval: any private reconnection: Reconnection @@ -54,7 +55,7 @@ export default class ClusterWS { data = JSON.parse(data) } catch (e) { return logError(e) } - ClusterWS.decode(this, data) + decode(this, data) } this.websocket.onclose = (event: CloseEvent): void => { this.missedPing = 0 @@ -75,8 +76,8 @@ export default class ClusterWS { public send(event: string, data: any, type: string = 'emit'): void { this.websocket.send(this.useBinary ? - ClusterWS.buffer(ClusterWS.encode(event, data, type)) : - ClusterWS.encode(event, data, type)) + buffer(encode(event, data, type)) : + encode(event, data, type)) } public disconnect(code?: number, msg?: any): void { @@ -95,43 +96,4 @@ export default class ClusterWS { public getChannelByName(channelName: string): Channel { return this.channels[channelName] } - - private static buffer(str: string): ByteString { - const length: number = str.length - const uint: any = new Uint8Array(length) - for (let i: number = 0; i < length; i++) uint[i] = str.charCodeAt(i) - return uint.buffer - } - - private static decode(socket: ClusterWS, message: any): any { - switch (message['#'][0]) { - case 'e': return socket.events.emit(message['#'][1], message['#'][2]) - case 'p': socket.channels[message['#'][1]] && socket.channels[message['#'][1]].onMessage(message['#'][2]) - case 's': - switch (message['#'][1]) { - case 'c': - socket.pingInterval = setInterval((): void => - socket.missedPing++ > 2 && socket.disconnect(4001, 'Did not get pings'), message['#'][2].ping) - socket.useBinary = message['#'][2].binary - socket.events.emit('connect') - default: break - } - default: break - } - } - - private static encode(event: string, data: any, type: string): any { - switch (type) { - case 'ping': return event - case 'emit': return JSON.stringify({ '#': ['e', event, data] }) - case 'publish': return JSON.stringify({ '#': ['p', event, data] }) - case 'system': switch (event) { - case 'subscribe': return JSON.stringify({ '#': ['s', 's', data] }) - case 'unsubscribe': return JSON.stringify({ '#': ['s', 'u', data] }) - case 'configuration': return JSON.stringify({ '#': ['s', 'c', data] }) - default: break - } - default: break - } - } } \ No newline at end of file diff --git a/src/modules/parser/parser.ts b/src/modules/parser/parser.ts new file mode 100644 index 0000000..da854dc --- /dev/null +++ b/src/modules/parser/parser.ts @@ -0,0 +1,40 @@ +import ClusterWS from '../../index' + +export function buffer(str: string): ByteString { + const length: number = str.length + const uint: any = new Uint8Array(length) + for (let i: number = 0; i < length; i++) uint[i] = str.charCodeAt(i) + return uint.buffer +} + +export function decode(socket: ClusterWS, message: any): any { + switch (message['#'][0]) { + case 'e': return socket.events.emit(message['#'][1], message['#'][2]) + case 'p': socket.channels[message['#'][1]] && socket.channels[message['#'][1]].onMessage(message['#'][2]) + case 's': + switch (message['#'][1]) { + case 'c': + socket.pingInterval = setInterval((): void => + socket.missedPing++ > 2 && socket.disconnect(4001, 'Did not get pings'), message['#'][2].ping) + socket.useBinary = message['#'][2].binary + socket.events.emit('connect') + default: break + } + default: break + } +} + +export function encode(event: string, data: any, type: string): any { + switch (type) { + case 'ping': return event + case 'emit': return JSON.stringify({ '#': ['e', event, data] }) + case 'publish': return JSON.stringify({ '#': ['p', event, data] }) + case 'system': switch (event) { + case 'subscribe': return JSON.stringify({ '#': ['s', 's', data] }) + case 'unsubscribe': return JSON.stringify({ '#': ['s', 'u', data] }) + case 'configuration': return JSON.stringify({ '#': ['s', 'c', data] }) + default: break + } + default: break + } +} \ No newline at end of file From 6e3fde5672812dc961e70146ebd8b439ab82c272 Mon Sep 17 00:00:00 2001 From: Dmitrii Goriunov Date: Fri, 5 Jan 2018 20:26:41 +1300 Subject: [PATCH 17/21] Update README --- dist/README.md | 154 +---------------------------------------------- docs/README.md | 160 +++---------------------------------------------- 2 files changed, 12 insertions(+), 302 deletions(-) diff --git a/dist/README.md b/dist/README.md index deccd66..e86c4d1 100644 --- a/dist/README.md +++ b/dist/README.md @@ -1,8 +1,8 @@

ClusterWS JavaScript Client

-
WebSocket & Node JS Cluster
+
Build Scalable Node.js WebSocket Applications

- Node.js +

@@ -10,153 +10,5 @@

-**This README, logo and animation will be changed soon, we are currently implementing new GUIDES in wikis and working with new logo and animation** +*Official JavaScript client library for [ClusterWS](https://github.com/ClusterWS/ClusterWS)* -## Overview -This is official JavaScript client for [ClusterWS](https://github.com/ClusterWS/ClusterWS). - -[ClusterWS](https://github.com/ClusterWS/ClusterWS) - is a minimal **Node JS http & real-time** framework which allows to scale WebSocket ([uWS](https://github.com/uNetworking/uWebSockets) - one of the fastest WebSocket libraries) between **Workers** in [Node JS Cluster](https://nodejs.org/api/cluster.html) and utilize all available CPU. - -**Current minified version is under 6KB.** - -**This library requires [ClusterWS](https://github.com/ClusterWS/ClusterWS) on the server** - -## Installation -To install ClusterWS Client JS run: -```js -npm install --save clusterws-client-js -``` -or use globally: - -1. Find `ClusterWS.(min).js` in `dist/browser` folder. -2. Use standard script tag to import library ``. -3. Done, now you can use it as `ClusterWS`. - - -## Socket -### 1. Connecting -You can connect to the server with the following code: -```js -var cws = new ClusterWS({ - url: 'localhost', - port: 80 -}) -``` - -in case if you are using builders like `webpack` and `npm` then you need to import library at the top with: -```js -var ClusterWS = require('clusterws-client-js').ClusterWS -``` - -*All available options of ClusterWS:* -```js -{ - url: '{string} url of the server without http or https. (must be provided)', - port: '{number} port of the server. (must be provided)', - autoReconnect: '{boolean} allow to auto-reconnect to the server on lost connection. (default false)', - reconnectionIntervalMin: '{number} how long min time waut. (default 1000) in ms', - reconnectionIntervalMax: '{number} how long max time wait. (default 5000) in ms', - reconnectionAttempts: '{number} how many times to try, 0 means without limit. (default 0)', - secure: '{boolean} user secure connection or not wss/ws. (default false)' -} -``` - -*Auto reconnect count random time between Max and Min interval value this will reduce amount of users which are connection at the same time on reconnection and reduce server load on restart of the server* - -### 2. Listen on events -To listen on events from the server you should use `on` method witch is provided by `cws` -```js -/** - event name: string - can be any string you wish - data: any - is what you send from the client -*/ -cws.on('event name', function(data){ - // in here you can write any logic -}) -``` - -*Also `cws` gets **Reserved Events** such as `'connect'`, `'disconnect'` and `'error'`* -```js -cws.on('connect', function(){ - // in here you can write any logic -}) - -/** - err: any - display the problem with your weboscket -*/ -cws.on('error', function(err){ - // in here you can write any logic -}) - -/** - code: number - represent the reason in number - reason: string - reason why your socket was disconnected -*/ -cws.on('disconnect', function(code, reason){ - // in here you can write any logic -}) -``` - -### 3. Send events -To send events to the server use `send` method witch is provided by `cws` -```js -/** - event name: string - can be any string you wish (client must listen on this event name) - data: any - is what you want to send to the client -*/ -cws.send('event name', data) -``` - -*Avoid emitting **Reserved Events** such as `'connect'`, `'connection'`, `'disconnect'` and `'error'`. Also avoid emitting event and events with `'#'` at the start.* - -## Pub/Sub -You can `subscribe`, `watch`, `unsubscribe` and `publish`, `getChannelByName` to/from the channels -```js -/** - channel name: string - can be any string you wish -*/ -var channel = cws.subscribe('channel name') - -/** - data: any - is what you get when you or some one else publish to the channel -*/ -channel.watch(function(data){ - // in here you can write any logic -}) - -/** - data: any - is what you want to publish to the channel (everyone who is subscribe will get it) -*/ -channel.publish(data) - -/** - This method is used to unsubscribe from the channel -*/ -channel.unsubscribe() - -/** - Also you can chain everything in one expression -*/ -var channel = cws.subscribe('channel name').watch(function(data){ - // in here you can write any logic -}).publish(data) - - -/** - You can get channel by channel name only if you were subscribed before - You can use any methods as with usual channel -*/ -cws.getChannelByName('channel name') - -``` - -**To make sure that user is connected to the server before subscribing, do it on `connect` event or on any other events which you emit from the server, otherwise subscription may not work properly** - -## See Also -* [Medium ClusterWS](https://medium.com/clusterws) -* [ClusterWS Tests](https://github.com/ClusterWS/ClusterWS-Tests) -* [ClusterWS Example Chat](https://github.com/goriunov/ClusterWS-Chat-Example) - -*Docs are still under development. If you have found any errors please submit pull request or leave issue* - -## Happy coding !!! :sunglasses: \ No newline at end of file diff --git a/docs/README.md b/docs/README.md index deccd66..33dc987 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,8 +1,8 @@

ClusterWS JavaScript Client

-
WebSocket & Node JS Cluster
+
Build Scalable Node.js WebSocket Applications

- Node.js +

@@ -10,153 +10,11 @@

-**This README, logo and animation will be changed soon, we are currently implementing new GUIDES in wikis and working with new logo and animation** - -## Overview -This is official JavaScript client for [ClusterWS](https://github.com/ClusterWS/ClusterWS). - -[ClusterWS](https://github.com/ClusterWS/ClusterWS) - is a minimal **Node JS http & real-time** framework which allows to scale WebSocket ([uWS](https://github.com/uNetworking/uWebSockets) - one of the fastest WebSocket libraries) between **Workers** in [Node JS Cluster](https://nodejs.org/api/cluster.html) and utilize all available CPU. - -**Current minified version is under 6KB.** - -**This library requires [ClusterWS](https://github.com/ClusterWS/ClusterWS) on the server** - -## Installation -To install ClusterWS Client JS run: -```js -npm install --save clusterws-client-js -``` -or use globally: - -1. Find `ClusterWS.(min).js` in `dist/browser` folder. -2. Use standard script tag to import library ``. -3. Done, now you can use it as `ClusterWS`. - - -## Socket -### 1. Connecting -You can connect to the server with the following code: -```js -var cws = new ClusterWS({ - url: 'localhost', - port: 80 -}) -``` - -in case if you are using builders like `webpack` and `npm` then you need to import library at the top with: -```js -var ClusterWS = require('clusterws-client-js').ClusterWS -``` - -*All available options of ClusterWS:* -```js -{ - url: '{string} url of the server without http or https. (must be provided)', - port: '{number} port of the server. (must be provided)', - autoReconnect: '{boolean} allow to auto-reconnect to the server on lost connection. (default false)', - reconnectionIntervalMin: '{number} how long min time waut. (default 1000) in ms', - reconnectionIntervalMax: '{number} how long max time wait. (default 5000) in ms', - reconnectionAttempts: '{number} how many times to try, 0 means without limit. (default 0)', - secure: '{boolean} user secure connection or not wss/ws. (default false)' -} -``` - -*Auto reconnect count random time between Max and Min interval value this will reduce amount of users which are connection at the same time on reconnection and reduce server load on restart of the server* - -### 2. Listen on events -To listen on events from the server you should use `on` method witch is provided by `cws` -```js -/** - event name: string - can be any string you wish - data: any - is what you send from the client -*/ -cws.on('event name', function(data){ - // in here you can write any logic -}) -``` - -*Also `cws` gets **Reserved Events** such as `'connect'`, `'disconnect'` and `'error'`* -```js -cws.on('connect', function(){ - // in here you can write any logic -}) - -/** - err: any - display the problem with your weboscket -*/ -cws.on('error', function(err){ - // in here you can write any logic -}) - -/** - code: number - represent the reason in number - reason: string - reason why your socket was disconnected -*/ -cws.on('disconnect', function(code, reason){ - // in here you can write any logic -}) -``` - -### 3. Send events -To send events to the server use `send` method witch is provided by `cws` -```js -/** - event name: string - can be any string you wish (client must listen on this event name) - data: any - is what you want to send to the client -*/ -cws.send('event name', data) -``` - -*Avoid emitting **Reserved Events** such as `'connect'`, `'connection'`, `'disconnect'` and `'error'`. Also avoid emitting event and events with `'#'` at the start.* - -## Pub/Sub -You can `subscribe`, `watch`, `unsubscribe` and `publish`, `getChannelByName` to/from the channels -```js -/** - channel name: string - can be any string you wish -*/ -var channel = cws.subscribe('channel name') - -/** - data: any - is what you get when you or some one else publish to the channel -*/ -channel.watch(function(data){ - // in here you can write any logic -}) - -/** - data: any - is what you want to publish to the channel (everyone who is subscribe will get it) -*/ -channel.publish(data) - -/** - This method is used to unsubscribe from the channel -*/ -channel.unsubscribe() - -/** - Also you can chain everything in one expression -*/ -var channel = cws.subscribe('channel name').watch(function(data){ - // in here you can write any logic -}).publish(data) - - -/** - You can get channel by channel name only if you were subscribed before - You can use any methods as with usual channel -*/ -cws.getChannelByName('channel name') - -``` - -**To make sure that user is connected to the server before subscribing, do it on `connect` event or on any other events which you emit from the server, otherwise subscription may not work properly** - -## See Also -* [Medium ClusterWS](https://medium.com/clusterws) -* [ClusterWS Tests](https://github.com/ClusterWS/ClusterWS-Tests) -* [ClusterWS Example Chat](https://github.com/goriunov/ClusterWS-Chat-Example) - -*Docs are still under development. If you have found any errors please submit pull request or leave issue* +

+ Official JavaScript client library for ClusterWS uWebSockets +

-## Happy coding !!! :sunglasses: \ No newline at end of file +

+

+ ClusterWS's JavaScript Client Documentation +

From 2a1357b5bba7cb617721b20b9b034bf789e9d63c Mon Sep 17 00:00:00 2001 From: Dmitrii Goriunov Date: Fri, 5 Jan 2018 20:27:56 +1300 Subject: [PATCH 18/21] Fix README bugs --- docs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index 33dc987..976a6a5 100644 --- a/docs/README.md +++ b/docs/README.md @@ -11,7 +11,7 @@

- Official JavaScript client library for ClusterWS uWebSockets + Official JavaScript client library for ClusterWS

From 10774fe952aa8c745849e415d4996a9c8bceb67b Mon Sep 17 00:00:00 2001 From: Dmitrii Goriunov Date: Fri, 5 Jan 2018 20:28:42 +1300 Subject: [PATCH 19/21] Fix README bugs --- docs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index 976a6a5..d16e576 100644 --- a/docs/README.md +++ b/docs/README.md @@ -11,7 +11,7 @@

- Official JavaScript client library for ClusterWS + Official JavaScript Client library for ClusterWS - lightweight, fast and powerful framework for building horizontally & vertically scalable WebSocket applications in Node.js

From 5b17421b066f9ddebee273e4608917ff98504df1 Mon Sep 17 00:00:00 2001 From: Dmitrii Goriunov Date: Fri, 5 Jan 2018 20:29:51 +1300 Subject: [PATCH 20/21] Fix link to wiki --- docs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index d16e576..ae37cf8 100644 --- a/docs/README.md +++ b/docs/README.md @@ -16,5 +16,5 @@

- ClusterWS's JavaScript Client Documentation + ClusterWS JavaScript Client Documentation

From d3dfe6b90c9806866ffcab97cf8dc2f5877cc30d Mon Sep 17 00:00:00 2001 From: Dmitrii Goriunov Date: Sat, 6 Jan 2018 06:17:27 +1300 Subject: [PATCH 21/21] New version 1.5.0 is ready --- dist/README.md | 8 +++++++- dist/package.json | 2 +- package.json | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/dist/README.md b/dist/README.md index e86c4d1..ae37cf8 100644 --- a/dist/README.md +++ b/dist/README.md @@ -10,5 +10,11 @@

-*Official JavaScript client library for [ClusterWS](https://github.com/ClusterWS/ClusterWS)* +

+ Official JavaScript Client library for ClusterWS - lightweight, fast and powerful framework for building horizontally & vertically scalable WebSocket applications in Node.js +

+

+

+ ClusterWS JavaScript Client Documentation +

diff --git a/dist/package.json b/dist/package.json index 978ebcd..dd98aa6 100644 --- a/dist/package.json +++ b/dist/package.json @@ -3,7 +3,7 @@ "version": "1.5.0", "description": "JavaScript Client for ClusterWS - lightweight, fast and powerful framework for building horizontally & vertically scalable WebSocket applications in Node.js.", "main": "index.js", - "author": "Dmitrii Goriunov ", + "author": "Dmitrii Goriunov", "license": "MIT", "repository": { "type": "git", diff --git a/package.json b/package.json index 3d22475..4664d68 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "version": "1.5.0", "description": "JavaScript Client for ClusterWS - lightweight, fast and powerful framework for building horizontally & vertically scalable WebSocket applications in Node.js.", "main": "index.js", - "author": "Dmitrii Goriunov ", + "author": "Dmitrii Goriunov", "scripts": { "build:npm": "ts-builder -npm -folder src -mainfile index.ts -outfolder dist -outfile index.js", "build:browser": "ts-builder -format iife -folder src -mainfile index.ts -outfolder dist/browser -outfile clusterws.js && ts-builder -prod -format iife -folder src -mainfile index.ts -outfolder dist/browser -outfile clusterws.min.js",