Marionette JS Client

API Docs for: 1.7.1
Show:

File: lib/marionette/drivers/abstract.js

  1. (function(module, ns) {

  2.   /**
  3.    *
  4.    * Abstract driver that will handle
  5.    * all common tasks between implementations.
  6.    * Such as error handling, request/response queuing
  7.    * and timeouts.
  8.    *
  9.    * @constructor
  10.    * @class Marionette.Drivers.Abstract
  11.    * @param {Object} options set options on prototype.
  12.    */
  13.   function Abstract(options) {
  14.     this._sendQueue = [];
  15.     this._responseQueue = [];
  16.   }

  17.   Abstract.prototype = {

  18.     /**
  19.      * Timeout for commands
  20.      *
  21.      * @property timeout
  22.      * @type Numeric
  23.      */
  24.     timeout: 10000,

  25.     /**
  26.      * Waiting for a command to finish?
  27.      *
  28.      * @private
  29.      * @property _waiting
  30.      * @type Boolean
  31.      */
  32.     _waiting: true,

  33.     /**
  34.      * Is system ready for commands?
  35.      *
  36.      * @property ready
  37.      * @type Boolean
  38.      */
  39.     ready: false,

  40.     /**
  41.      * Connection id for the server.
  42.      *
  43.      * @property connectionId
  44.      * @type Numeric
  45.      */
  46.     connectionId: null,

  47.     /**
  48.      * We just set the script timeout.
  49.      * If you need to do something in the driver.
  50.      *
  51.      * @method setScriptTiemout
  52.      * @param {Integer} the timeout value.
  53.      */
  54.     setScriptTimeout: function setScriptTimeout(timeout) {
  55.     },

  56.     /**
  57.      * Sends remote command to server.
  58.      * Each command will be queued while waiting for
  59.      * any pending commands. This ensures order of
  60.      * response is correct.
  61.      *
  62.      *
  63.      * @method send
  64.      * @param {Object} command remote command to send to marionette.
  65.      * @param {Function} callback executed when response comes back.
  66.      */
  67.     send: function send(cmd, callback) {
  68.       if (!this.ready) {
  69.         throw new Error('connection is not ready');
  70.       }

  71.       if (typeof(callback) === 'undefined') {
  72.         throw new Error('callback is required');
  73.       }

  74.       this._responseQueue.push(callback);
  75.       this._sendQueue.push(cmd);

  76.       this._nextCommand();

  77.       return this;
  78.     },

  79.     /**
  80.      * Connects to a remote server.
  81.      * Requires a _connect function to be defined.
  82.      *
  83.      *     MyClass.prototype._connect = function _connect(){
  84.      *       //open a socket to marrionete accept response
  85.      *       //you *must* call _onDeviceResponse with the first
  86.      *       //response from marionette it looks like this:
  87.      *       //{ from: 'root', applicationType: 'gecko', traits: [] }
  88.      *       this.connectionId = result.id;
  89.      *     }
  90.      *
  91.      * @method connect
  92.      * @param {Function} callback executes
  93.      *   after successfully connecting to the server.
  94.      */
  95.     connect: function connect(callback) {
  96.       this.ready = true;
  97.       this._responseQueue.push(function(data) {
  98.         this.applicationType = data.applicationType;
  99.         this.traits = data.traits;
  100.         callback();
  101.       }.bind(this));
  102.       this._connect();
  103.     },

  104.     /**
  105.      * Destroys connection to server
  106.      *
  107.      * Will immediately close connection to server
  108.      * closing any pending responses.
  109.      *
  110.      * @method close
  111.      */
  112.     close: function() {
  113.       this.ready = false;
  114.       this._responseQueue.length = 0;
  115.       if (this._close) {
  116.         this._close();
  117.       }
  118.     },

  119.     /**
  120.      * Checks queue if not waiting for a response
  121.      * Sends command to websocket server
  122.      *
  123.      * @private
  124.      * @method _nextCommand
  125.      */
  126.     _nextCommand: function _nextCommand() {
  127.       var nextCmd;
  128.       if (!this._waiting && this._sendQueue.length) {
  129.         this._waiting = true;
  130.         nextCmd = this._sendQueue.shift();
  131.         this._sendCommand(nextCmd);
  132.       }
  133.     },

  134.     /**
  135.      * Handles responses from devices.
  136.      * Will only respond to the event if the connectionId
  137.      * is equal to the event id and the client is ready.
  138.      *
  139.      * @param {Object} data response from server.
  140.      * @private
  141.      * @method _onDeviceResponse
  142.      */
  143.     _onDeviceResponse: function _onDeviceResponse(data) {
  144.       var cb;
  145.       if (this.ready && data.id === this.connectionId) {
  146.         this._waiting = false;
  147.         cb = this._responseQueue.shift();
  148.         cb(data.response);

  149.         this._nextCommand();
  150.       }
  151.     }

  152.   };

  153.   module.exports = Abstract;

  154. }.apply(
  155.   this,
  156.   (this.Marionette) ?
  157.     [Marionette('drivers/abstract'), Marionette] :
  158.     [module, require('../marionette')]
  159. ));

  160.