JAVASCRIPT   52

api.js

Guest on 3rd August 2021 11:05:11 AM

  1. var Stream      = require('stream').Stream,
  2.     util        = require('util'),
  3.     EventTarget = require('./api/event_target'),
  4.     Event       = require('./api/event');
  5.  
  6. var API = function(options) {
  7.   options = options || {};
  8.  
  9.   this.readable = this.writable = true;
  10.  
  11.   var headers = options.headers;
  12.   if (headers) {
  13.     for (var name in headers) this._driver.setHeader(name, headers[name]);
  14.   }
  15.  
  16.   this._ping          = options.ping;
  17.   this._pingId        = 0;
  18.   this.readyState     = API.CONNECTING;
  19.   this.bufferedAmount = 0;
  20.   this.protocol       = '';
  21.   this.url            = this._driver.url;
  22.   this.version        = this._driver.version;
  23.  
  24.   var self = this;
  25.  
  26.   this._stream.setTimeout(0);
  27.   this._stream.setNoDelay(true);
  28.  
  29.   ['close', 'end'].forEach(function(event) {
  30.     this._stream.on(event, function() { self._finalize('', 1006) });
  31.   }, this);
  32.  
  33.   this._stream.on('error', function(error) {
  34.     var event = new Event('error', {message: 'Network error: ' + self.url + ': ' + error.message});
  35.     event.initEvent('error', false, false);
  36.     self.dispatchEvent(event);
  37.     self._finalize('', 1006);
  38.   });
  39.  
  40.   this._driver.on('open',    function(e) { self._open() });
  41.   this._driver.on('message', function(e) { self._receiveMessage(e.data) });
  42.   this._driver.on('close',   function(e) { self._finalize(e.reason, e.code) });
  43.  
  44.   this._driver.on('error', function(error) {
  45.     var event = new Event('error', {message: error.message});
  46.     event.initEvent('error', false, false);
  47.     self.dispatchEvent(event);
  48.   });
  49.   this.on('error', function() {});
  50.  
  51.   this._driver.messages.on('drain', function() {
  52.     self.emit('drain');
  53.   });
  54.  
  55.   if (this._ping)
  56.     this._pingTimer = setInterval(function() {
  57.       self._pingId += 1;
  58.       self.ping(self._pingId.toString());
  59.     }, this._ping * 1000);
  60.  
  61.   this._stream.pipe(this._driver.io);
  62.   this._driver.io.pipe(this._stream);
  63. };
  64. util.inherits(API, Stream);
  65.  
  66. API.CONNECTING = 0;
  67. API.OPEN       = 1;
  68. API.CLOSING    = 2;
  69. API.CLOSED     = 3;
  70.  
  71. var instance = {
  72.   write: function(data) {
  73.     return this.send(data);
  74.   },
  75.  
  76.   end: function(data) {
  77.     if (data !== undefined) this.send(data);
  78.     this.close();
  79.   },
  80.  
  81.   pause: function() {
  82.     return this._driver.messages.pause();
  83.   },
  84.  
  85.   resume: function() {
  86.     return this._driver.messages.resume();
  87.   },
  88.  
  89.   send: function(data) {
  90.     if (this.readyState > API.OPEN) return false;
  91.     if (!(data instanceof Buffer)) data = String(data);
  92.     return this._driver.messages.write(data);
  93.   },
  94.  
  95.   ping: function(message, callback) {
  96.     if (this.readyState > API.OPEN) return false;
  97.     return this._driver.ping(message, callback);
  98.   },
  99.  
  100.   close: function() {
  101.     if (this.readyState !== API.CLOSED) this.readyState = API.CLOSING;
  102.     this._driver.close();
  103.   },
  104.  
  105.  _open: function() {
  106.     if (this.readyState !== API.CONNECTING) return;
  107.  
  108.     this.readyState = API.OPEN;
  109.     this.protocol = this._driver.protocol || '';
  110.  
  111.     var event = new Event('open');
  112.     event.initEvent('open', false, false);
  113.     this.dispatchEvent(event);
  114.   },
  115.  
  116.   _receiveMessage: function(data) {
  117.     if (this.readyState > API.OPEN) return false;
  118.  
  119.     if (this.readable) this.emit('data', data);
  120.  
  121.     var event = new Event('message', {data: data});
  122.     event.initEvent('message', false, false);
  123.     this.dispatchEvent(event);
  124.   },
  125.  
  126.   _finalize: function(reason, code) {
  127.     if (this.readyState === API.CLOSED) return;
  128.  
  129.     if (this._pingTimer) clearInterval(this._pingTimer);
  130.     if (this._stream) this._stream.end();
  131.  
  132.     if (this.readable) this.emit('end');
  133.     this.readable = this.writable = false;
  134.  
  135.     this.readyState = API.CLOSED;
  136.     var event = new Event('close', {code: code || 1000, reason: reason || ''});
  137.     event.initEvent('close', false, false);
  138.     this.dispatchEvent(event);
  139.   }
  140. };
  141.  
  142. for (var method in instance) API.prototype[method] = instance[method];
  143. for (var key in EventTarget) API.prototype[key] = EventTarget[key];
  144.  
  145. module.exports = API;

Raw Paste


Login or Register to edit or fork this paste. It's free.