UNPKG

raptor-client

Version:

A transport-agnostic RPC client that follows the JSON-RPC 2.0 spec. Works in the browser and on the server.

88 lines (64 loc) 2.49 kB
var inherits = require('util').inherits var EventEmitter = require('events').EventEmitter function Client (sendMessage) { EventEmitter.call(this) this._nextId = 0 this._callbacks = new Map() this._sendMessage = sendMessage } inherits(Client, EventEmitter) Client.prototype._registerCallback = function (cb) { var id = this._nextId++ this._callbacks.set(id, cb) return id } Client.prototype._retrieveCallback = function (id) { var cb = this._callbacks.get(id) this._callbacks.delete(id) return cb } Client.prototype.send = function (method, params) { var self = this if (typeof method !== 'string') { throw new TypeError('Method must be a string') } if (params && typeof params !== 'object') { throw new TypeError('Params can only be provided as array or object') } var req = { jsonrpc: '2.0', method: method, params: params } var callback = new Promise(function (resolve, reject) { req.id = self._registerCallback({ resolve: resolve, reject: reject }) }) return Promise.resolve() .then(function () { return self._sendMessage(req) }) .then(function () { return callback }) } Client.prototype.notify = function (method, params) { var self = this if (typeof method !== 'string') { throw new TypeError('Method must be a string') } if (params && typeof params !== 'object') { throw new TypeError('Params can only be provided as array or object') } var req = { jsonrpc: '2.0', method: method, params: params } return Promise.resolve() .then(function () { return self._sendMessage(req) }) } Client.prototype.handleMessage = function (msg) { if (msg.hasOwnProperty('id') === false) { return this.emit('notification', msg) } if (this._callbacks.has(msg.id) === false) { return this.emit('error', new Error('Server responded to unknown request (id: ' + msg.id + ')')) } var hasError = msg.hasOwnProperty('error') var hasResult = msg.hasOwnProperty('result') if (hasResult && hasError) { return this.emit('error', new Error('Server responded with both result and error (id: ' + msg.id + ')')) } if (!hasResult && !hasError) { return this.emit('error', new Error('Server responded with neither result nor error (id: ' + msg.id + ')')) } var cb = this._retrieveCallback(msg.id) if (hasError) { var err = new Error(msg.error.message) err.rpcCode = msg.error.code err.rpcData = msg.error.data return cb.reject(err) } cb.resolve(msg.result) } module.exports = Client