UNPKG

@glitterprotocol/glitter-sdk

Version:

The JavaScript SDK for Glitter

216 lines 8.08 kB
"use strict"; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.WebSocketClient = void 0; var events_1 = require("events"); var ws_1 = __importDefault(require("ws")); var hash_1 = require("../util/hash"); var escapeSingleQuotes = function (str) { return str.replace(/'/g, "\\'"); }; function makeQueryParams(query) { var queryBuilder = []; for (var _i = 0, _a = Object.keys(query); _i < _a.length; _i++) { var key = _a[_i]; var queryItem = void 0; var value = query[key]; // if value is scalar if (!Array.isArray(value)) { switch (typeof value) { case 'number': queryItem = "".concat(key, "=").concat(value); break; case 'string': queryItem = "".concat(key, "='").concat(escapeSingleQuotes(value), "'"); break; default: // Date queryItem = "".concat(key, "=").concat(value.toISOString()); } } else { switch (value[0]) { case '>': case '<': case '<=': case '>=': if (typeof value[1] !== 'number') { queryItem = "".concat(key).concat(value[0]).concat(value[1].toISOString()); } else { queryItem = "".concat(key).concat(value[0]).concat(value[1]); } break; case 'CONTAINS': queryItem = "".concat(key, " CONTAINS '").concat(escapeSingleQuotes(value[1]), "'"); break; case 'EXISTS': queryItem = "".concat(key, " EXISTS"); break; } } queryBuilder.push(queryItem); } return queryBuilder.join(' AND '); } /** * An object repesenting a connection to a glitter node's WebSocket RPC endpoint. * This allows for subscribing to Tendermint events through WebSocket. * * ### Events * **error** emitted when error raises * **connect** emitted after connection establishment * **reconnect** emitted upon every attempt of reconnection * **destroyed** emitted when socket has been destroyed * * ### Example * * ```ts * import { WebSocketClient } from '@glitter/glitter.js'; * * const wsclient = new WebSocketClient("ws://localhost:26657/websocket"); * * wsclient.subscribe('NewBlock', {}, (data) => { * console.log(data.value); * * // close after receiving one block. * wsclient.destroy(); * }) * * wsclient.subscribe( * 'Tx', * { * 'message.action': 'send', * 'message.sender': ['CONTAINS', 'glitter1...'], * }, * (data) => { * console.log(data.value); * * // close after receiving one send Tx * wsclient.destroy(); * }); * * wsclient.start(); * ``` */ var WebSocketClient = /** @class */ (function (_super) { __extends(WebSocketClient, _super); /** * WebSocketClient constructor * @param URL The WebSocket endpoint URL on the Tendermint RPC server. * Ex: ws://localhost:26657/websocket * @param reconnectCount 0 for not to attempt reconnect, -1 for infinite, > 0 for number of times to attempt * @param reconnectInterval retry interval in milliseconds */ function WebSocketClient(URL, reconnectCount, reconnectInterval) { if (reconnectCount === void 0) { reconnectCount = 0; } if (reconnectInterval === void 0) { reconnectInterval = 1000; } var _this = _super.call(this) || this; _this.URL = URL; _this.reconnectCount = reconnectCount; _this.reconnectInterval = reconnectInterval; _this._reconnectCount = _this.reconnectCount; _this.isConnected = false; _this.shouldAttemptReconnect = !!_this.reconnectInterval; return _this; } /** * Destroys class as well as socket */ WebSocketClient.prototype.destroy = function () { this.shouldAttemptReconnect = false; this.reconnectTimeoutId && clearTimeout(this.reconnectTimeoutId); this.socket && this.socket.close(); }; WebSocketClient.prototype.start = function () { this.socket = new ws_1.default(this.URL); this.socket.onopen = this.onOpen.bind(this); this.socket.onmessage = this.onMessage.bind(this); this.socket.onclose = this.onClose.bind(this); this.socket.onerror = function () { return undefined; }; }; WebSocketClient.prototype.onOpen = function () { this.isConnected = true; this.emit('connect'); // reset reconnectCount after connection establishment this._reconnectCount = this.reconnectCount; this.socket.send(JSON.stringify({ jsonrpc: '2.0', method: 'subscribe', params: [this.queryParams], id: 1, })); }; WebSocketClient.prototype.onMessage = function (message) { try { var parsedData = JSON.parse(message.data.toString()); if (this.callback && parsedData.result && parsedData.result.query === this.queryParams) { // this.emit('message', parsedData.result.data); this.callback(parsedData.result.data); } } catch (err) { this.emit('error', err); } }; WebSocketClient.prototype.onClose = function () { var _this = this; this.isConnected = false; if (this.shouldAttemptReconnect && (this._reconnectCount > 0 || this._reconnectCount === -1)) { if (this._reconnectCount !== -1) { this._reconnectCount--; } this.reconnectTimeoutId && clearTimeout(this.reconnectTimeoutId); this.reconnectTimeoutId = setTimeout(function () { _this.emit('reconnect'); _this.start(); }, this.reconnectInterval); } else { this.emit('destroyed'); } }; WebSocketClient.prototype.subscribe = function (event, query, callback) { this.queryParams = makeQueryParams(__assign({ 'tm.event': event }, query)); this.callback = callback; }; WebSocketClient.prototype.subscribeTx = function (query, callback) { var newCallback = function (d) { d.value.TxResult.txhash = (0, hash_1.hashToHex)(d.value.TxResult.tx); return callback(d); }; this.subscribe('Tx', query, newCallback); }; return WebSocketClient; }(events_1.EventEmitter)); exports.WebSocketClient = WebSocketClient; //# sourceMappingURL=WebSocketClient.js.map