UNPKG

symple-client

Version:

Symple realtime messaging client

1 lines 11.8 kB
const Symple={parseAddress:function(e){var t={},e=e.split("|");return 0<e.length&&(t.user=e[0]),1<e.length&&(t.id=e[1]),t},buildAddress:function(e){return(e.user?e.user+"|":"")+(e.id||"")},filterObject:function(e,t,i){var n,s,o=[];for(n in e)e.hasOwnProperty(n)&&(s=e[n],t&&n!==t||i&&s!==i?"object"==typeof s&&(s=Symple.filterObject(s,t,i))&&(o=o.concat(s)):o.push(e));return o},deleteNested:function(e,t,i){for(var n in e){var s=e[n];t&&n!==t||i&&s!==i?"object"==typeof s&&Symple.deleteNested(s,t):delete e[n]}},countNested:function(e,t,i,n){for(var s in void 0===n&&(n=0),e){var o;e.hasOwnProperty(s)&&(o=e[s],t&&s!==t||i&&o!==i?"object"==typeof o&&(n=Symple.countNested(o,t,i,n)):n++)}return n},traverse:function(e,t){for(var i in e)e.hasOwnProperty(i)&&(t(i,i=e[i]),"object"==typeof i&&Symple.traverse(i,t))},randomString:function(e){return Math.random().toString(36).slice(2)},merge:function(t,i){for(var n in i)try{i[n].constructor===Object?t[n]=merge(t[n],i[n]):t[n]=i[n]}catch(e){t[n]=i[n]}return t}};Symple.extend=function(){for(var e=arguments[0],t=1;t<arguments.length;t++)e=function(e,t){for(var i in t)hasOwnProperty.call(t,i)&&(e[i]=t[i]);return e}(e,arguments[t]);return e},Symple.runVendorMethod=function(e,t){for(var i,n,s=0,o=["webkit","moz","ms","o",""];s<o.length&&!e[i];){if(i=t,""===o[s]&&(i=i.substr(0,1).toLowerCase()+i.substr(1)),"undefined"!=(n=typeof e[i=o[s]+i]))return o=[o[s]],"function"==n?e[i]():e[i];s++}},Symple.parseISODate=function(e){var t=Date.parse(e);if(isNaN(t)){var i,n=0,s=[1,4,5,6,7,10,11];if(i=/^(\d{4}|[+\-]\d{6})(?:-(\d{2})(?:-(\d{2}))?)?(?:T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{3}))?)?(?:(Z)|([+\-])(\d{2})(?::(\d{2}))?)?)?$/.exec(e)){for(var o,r=0;o=s[r];++r)i[o]=+i[o]||0;i[2]=(+i[2]||1)-1,i[3]=+i[3]||1,"Z"!==i[8]&&void 0!==i[9]&&(n=60*i[10]+i[11],"+"===i[9]&&(n=0-n)),t=Date.UTC(i[1],i[2],i[3],i[4],i[5]+n,i[6],i[7])}}return new Date(t)},Symple.isMobileDevice=function(){return"ontouchstart"in document.documentElement},Symple.iOSVersion=function(e,t){return parseFloat((""+(/CPU.*OS ([0-9_]{1,5})|(CPU like).*AppleWebKit.*Mobile/i.exec(navigator.userAgent)||[0,""])[1]).replace("undefined","3_2").replace("_",".").replace("_",""))||!1},Symple.match=function(e,t){var i,n=!0;for(i in e)if(!e.hasOwnProperty(i)||!t.hasOwnProperty(i)||t[i]!==e[i]){n=!1;break}return n},Symple.formatTime=function(e){function t(e){return e<10?"0"+e:e}return t(e.getHours()).toString()+":"+t(e.getMinutes()).toString()+":"+t(e.getSeconds()).toString()+" "+t(e.getDate()).toString()+"/"+t(e.getMonth()).toString()},Symple.hasClass=function(e,t){return-1!==(" "+e.className+" ").indexOf(" "+t+" ")};var initializing=!(Symple.log=function(){"undefined"!=typeof console&&void 0!==console.log&&console.log.apply(console,arguments)}),fnTest=/xyz/.test(function(){xyz})?/\b_super\b/:/.*/;Symple.Class=function(){},Symple.Class.extend=function(e){var t,s=this.prototype,i=(initializing=!0,new this);for(t in initializing=!1,e)i[t]="function"==typeof e[t]&&"function"==typeof s[t]&&fnTest.test(e[t])?function(i,n){return function(){var e=this._super,t=(this._super=s[i],n.apply(this,arguments));return this._super=e,t}}(t,e[t]):e[t];function n(){!initializing&&this.init&&this.init.apply(this,arguments)}return((n.prototype=i).constructor=n).extend=arguments.callee,n},Symple.Emitter=Symple.Class.extend({init:function(){this.listeners={}},on:function(e,t){void 0===this.listeners[e]&&(this.listeners[e]=[]),void 0!==t&&t.constructor===Function&&this.listeners[e].push(t)},clear:function(e,t){if(void 0!==this.listeners[e])for(var i=0;i<this.listeners[e].length;i++)this.listeners[e][i]===t&&this.listeners[e].splice(i,1)},emit:function(){var e=arguments[0],t=Array.prototype.slice.call(arguments,1);if(void 0!==this.listeners[e])for(var i=0;i<this.listeners[e].length;i++)this.listeners[e][i].constructor===Function&&this.listeners[e][i].apply(this,t)}}),Symple.Manager=Symple.Class.extend({init:function(e){this.options=e||{},this.key=this.options.key||"id",this.store=[]},add:function(e){this.store.push(e)},remove:function(e){for(var t=null,i=0;i<this.store.length;i++)if(this.store[i][this.key]===e){t=this.store[i],this.store.splice(i,1);break}return t},get:function(e){for(var t=0;t<this.store.length;t++)if(this.store[t][this.key]===e)return this.store[t];return null},find:function(e){for(var t=[],i=0;i<this.store.length;i++)Symple.match(e,this.store[i])&&t.push(this.store[i]);return t},findOne:function(e){e=this.find(e);return e.length?e[0]:void 0},last:function(){return this.store[this.store.length-1]},size:function(){return this.store.length}}),module.exports=Symple;const Symple=require("./symple"),io=require("socket.io-client")["io"];Symple.Client=Symple.Emitter.extend({init:function(e){this.options=Symple.extend({url:e.url||"http://localhost:4000",secure:!(!e.url||0!==e.url.indexOf("https")&&0!==e.url.indexOf("wss")),token:void 0,peer:{}},e),this._super(),this.options.auth=Symple.extend({token:this.options.token||"",user:this.options.peer.user||"",name:this.options.peer.name||"",type:this.options.peer.type||""},this.options.auth),this.peer=e.peer,this.peer.rooms=this.peer.rooms||[],this.roster=new Symple.Roster(this),this.socket=null},connect:function(){Symple.log("symple:client: connecting",this.options);var i=this;if(this.socket)throw"The client socket is not null";this.socket=io.connect(this.options.url,this.options),this.socket.on("connect",function(){Symple.log("symple:client: connected"),i.peer.id=i.socket.id,i.peer.online=!0,i.roster.add(i.peer),i.sendPresence({probe:!0}),i.emit("connect"),i.socket.on("message",function(e){if(Symple.log("symple:client: receive",e),"object"==typeof e){switch(e.type){case"message":e=new Symple.Message(e);break;case"command":e=new Symple.Command(e);break;case"event":e=new Symple.Event(e);break;case"presence":(e=new Symple.Presence(e)).data.online?i.roster.update(e.data):setTimeout(function(){i.roster.remove(e.data.id)}),e.probe&&i.sendPresence(new Symple.Presence({to:Symple.parseAddress(e.from).id}));break;default:e.type=e.type||"message"}var t;"string"!=typeof e.from?Symple.log("symple:client: invalid sender address",e):((t=i.roster.get(e.from))?e.from=t:Symple.log("symple:client: got message from unknown peer",e),i.emit(e.type,e))}})}),this.socket.on("error",function(){i.emit("connect")}),this.socket.on("connecting",function(){Symple.log("symple:client: connecting"),i.emit("connecting")}),this.socket.on("reconnecting",function(){Symple.log("symple:client: reconnecting"),i.emit("reconnecting")}),this.socket.on("connect_error",e=>{i.emit("connect_error"),i.setError("auth",e.message),Symple.log("symple:client: connect error",e)}),this.socket.on("connect_failed",function(){Symple.log("symple:client: connect failed"),i.emit("connect_failed"),i.setError("connect")}),this.socket.on("disconnect",function(){Symple.log("symple:client: disconnect"),i.peer.online=!1,i.emit("disconnect")})},disconnect:function(){this.socket&&this.socket.disconnect()},online:function(){return this.peer.online},join:function(e){this.socket.emit("join",e)},leave:function(e){this.socket.emit("leave",e)},send:function(e,t){if(!this.online())throw"Cannot send messages while offline";if("object"!=typeof e)throw"Message must be an object";if("string"!=typeof e.type&&(e.type="message"),e.id||(e.id=Symple.randomString(8)),t&&(e.to=t),e.to&&"object"==typeof e.to&&(e.to=Symple.buildAddress(e.to)),e.to&&"string"!=typeof e.to)throw"Message `to` attribute must be an address string";if(e.from=Symple.buildAddress(this.peer),e.from===e.to)throw"Message sender cannot match the recipient";Symple.log("symple:client: sending",e),this.socket.emit("message",e)},respond:function(e){this.send(e,e.from)},sendMessage:function(e,t){this.send(e,t)},sendPresence:function(e){(e=e||{}).data?e.data=Symple.merge(this.peer,e.data):e.data=this.peer,this.send(new Symple.Presence(e))},sendCommand:function(e,t,i,n){var s=this;e=new Symple.Command(e,t),this.send(e),i&&this.onResponse("command",{id:e.id},i,function(e){(n||202!==e.status&&406!==e.status)&&s.clear("command",i)})},addCapability:function(e,t){var i=this.peer;i&&(void 0===t&&(t=!0),void 0===i.capabilities&&(i.capabilities={}),i.capabilities[e]=t)},removeCapability:function(e){var t=this.peer;t&&void 0!==t.capabilities&&void 0!==t.capabilities[e]&&(delete t.capabilities[key],this.sendPresence())},hasCapability:function(e,t){e=this.roster.get(e);if(e){if(void 0!==e.capabilities&&void 0!==e.capabilities[t])return!1!==e.capabilities[t];if(void 0!==e.data&&void 0!==e.data.capabilities&&void 0!==e.data.capabilities[t])return!1!==e.data.capabilities[t]}return!1},getCapability:function(e,t){e=this.roster.get(e);if(e){if(void 0!==e.capabilities&&void 0!==e.capabilities[t])return e.capabilities[t];if(void 0!==e.data&&void 0!==e.data.capabilities&&void 0!==e.data.capabilities[t])return e.data.capabilities[t]}},setError:function(e,t){Symple.log("symple:client: fatal error",e,t),this.emit("error",e,t),this.socket&&this.socket.disconnect()},onResponse:function(e,t,i,n){void 0===this.listeners[e]&&(this.listeners[e]=[]),void 0!==i&&i.constructor===Function&&this.listeners[e].push({fn:i,after:n,filters:t})},clear:function(e,t){if(Symple.log("symple:client: clearing callback",e),void 0!==this.listeners[e])for(var i=0;i<this.listeners[e].length;i++)this.listeners[e][i].fn===t&&String(this.listeners[e][i].fn)===String(t)&&(this.listeners[e].splice(i,1),Symple.log("symple:client: cleared callback",e))},emit:function(){this.emitResponse.apply(this,arguments)||this._super.apply(this,arguments)},emitResponse:function(){var e=arguments[0],t=Array.prototype.slice.call(arguments,1);if(void 0!==this.listeners[e])for(var i=0;i<this.listeners[e].length;i++)if("object"==typeof this.listeners[e][i]&&"undefined"!==this.listeners[e][i].filters&&Symple.match(this.listeners[e][i].filters,t[0]))return this.listeners[e][i].fn.apply(this,t),"undefined"!==this.listeners[e][i].after&&this.listeners[e][i].after.apply(this,t),!0;return!1}}),Symple.Roster=Symple.Manager.extend({init:function(e){this._super(),this.client=e},add:function(e){if(Symple.log("symple:roster: adding",e),!e||!e.id||!e.user)throw"Cannot add invalid peer";this._super(e),this.client.emit("addPeer",e)},remove:function(e){e=Symple.parseAddress(e).id||e;var t=this._super(e);return Symple.log("symple:roster: removing",e,t),t&&this.client.emit("removePeer",t),t},get:function(e){return(peer=this._super(e))?peer:this.findOne(Symple.parseAddress(e))},update:function(e){if(e&&e.id){var t=this.get(e.id);if(t)for(var i in e)t[i]=e[i];else this.add(e)}}}),Symple.Message=function(e){"object"==typeof e&&this.fromJSON(e),this.type="message"},Symple.Message.prototype={fromJSON:function(e){for(var t in e)this[t]=e[t]},valid:function(){return this.id&&this.from}},Symple.Command=function(e){"object"==typeof e&&this.fromJSON(e),this.type="command"},Symple.Command.prototype={getData:function(e){return this.data?this.data[e]:null},params:function(){return this.node.split(":")},param:function(e){return this.params()[e-1]},matches:function(e){if((xparams=e.split(":")).length>this.params().length)return!1;for(var t=0;t<xparams.length;t++)if("*"!==xparams[t]&&xparams[t]!==this.params()[t])return!1;return!0},fromJSON:function(e){for(var t in e)this[t]=e[t]},valid:function(){return this.id&&this.from&&this.node}},Symple.Presence=function(e){"object"==typeof e&&this.fromJSON(e),this.type="presence"},Symple.Presence.prototype={fromJSON:function(e){for(var t in e)this[t]=e[t]},valid:function(){return this.id&&this.from}},Symple.Event=function(e){"object"==typeof e&&this.fromJSON(e),this.type="event"},Symple.Event.prototype={fromJSON:function(e){for(var t in e)this[t]=e[t]},valid:function(){return this.id&&this.from&&this.name}},module.exports=Symple;