export class ClientDriver{ /* (0) Constants & Enums ---------------------------------------------------------*/ static get STATE(){ return Object.freeze({ OPENING: 0, OPENED: 1, CONNECTING: 2, CONNECTED: 3, CLOSED: 4 }); } /* (1) Creates a client driver * * @_resource Target resource (typically an URL) * ---------------------------------------------------------*/ constructor(_resource){ /* (1) Default attributes values */ this.error = false; this.state = ClientDriver.STATE.OPENING; this.stack = []; this.callback = { onready: function(){}, onclose: function(){}, onreceive: function(){} }; /* (2) Fail: invalid _resource */ if( typeof _resource !== 'string' ) return ( this.error = true ); /* (3) Set explicit attributes */ this.resource = _resource; return; } /* (2) Binds the client to the resource * * @return bound Whether the binding has been successful * ---------------------------------------------------------*/ bind(){ /* (1) Fail: not OPENING OR error */ if( this.error || this.state !== ClientDriver.STATE.OPENING ) return false; /* (2) By default return success */ return true; } /* (3) Send request * * @_request Request data * * @return sent Whether the request has been successful * ---------------------------------------------------------*/ send(_request){ /* (1) Fail: if error */ if( this.error ) return false; /* (2) Fail: invalid _request */ if( !(_request instanceof Object) ) return false; /* (3) If not already connected -> stack request */ if( this.state < ClientDriver.STATE.CONNECTED ){ this.stack.push(_request); return false; } /* (4) By default return success */ return true; } /* (4) Bind event to connection opened * * @_callback Callback launched when connection is opened * * @return bound Whether the callback has successfully been bound * ---------------------------------------------------------*/ onready(_callback){ /* (1) Fail: already CONNECTED OR error */ if( this.error || this.state >= ClientDriver.STATE.CONNECTED ) return false; /* (2) Fail: invalid _callback */ if( !(_callback instanceof Function) ) return false; /* (3) Register _callback */ this.callback.onready = function(cback){ // call callback cback(); // if request(s) in stack -> pop & send them while( this.stack.length > 0 ) this.send(this.stack.shift()); }.bind(this, _callback); /* (5) By default return success */ return true; } /* (5) Bind event to connection closed * * @_callback Callback launched when connection is closed * * @return bound Whether the callback has successfully been bound * ---------------------------------------------------------*/ onclose(_callback){ /* (1) Fail: already CLOSED OR error */ if( this.error || this.state === ClientDriver.STATE.CLOSED ) return false; /* (2) Fail: invalid _callback */ if( !(_callback instanceof Function) ) return false; /* (3) Register _callback */ this.callback.onclose = _callback; /* (4) By default return success */ return true; } /* (6) Bind event to message reception * * @_callback Callback launched when a message is received * * @return bound Whether the callback has successfully been bound * ---------------------------------------------------------*/ onreceive(_callback){ /* (1) Fail: already CONNECTED OR error */ if( this.error || this.state >= ClientDriver.STATE.CONNECTED ) return false; /* (2) Fail: invalid _callback */ if( !(_callback instanceof Function) ) return false; /* (3) Register _callback */ this.callback.onreceive = _callback; /* (4) By default return success */ return true; } }