UNPKG

happypandax-client

Version:

A javascript client library for communicating with HappyPanda X servers

941 lines (940 loc) 37.9 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 __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (g && (g = 0, op[0] && (_ = 0)), _) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Client = exports.finalize = exports.ServerDisconnectError = exports.ConnectionError = exports.TimeoutError = exports.ClientError = exports.AuthMissingCredentials = exports.AuthRequiredError = exports.AuthWrongCredentialsError = exports.AuthError = exports.ServerError = exports.log = exports.exception_codes = void 0; var net = __importStar(require("net")); var stream_1 = require("stream"); var ts_custom_error_1 = require("ts-custom-error"); var msgpack_1 = require("@msgpack/msgpack"); var encoding = "utf8"; var postfix = Buffer.from("<EOF>", encoding); exports.exception_codes = { AuthRequiredError: 407, AuthWrongCredentialsError: 411, AuthMissingCredentials: 412, ServerError: 400, AuthError: 406, ClientError: 500, ConnectionError: 501, ServerDisconnectError: 502, }; /** * The logger * @group Logging */ exports.log = { /** * Enable or disable logging */ enabled: true, /** * Can be set to a custom logger that will be used instead of console */ logger: undefined, d: function (msg) { if (!this.enabled) return; this.logger ? this.logger.debug(msg) : console.debug(msg); }, i: function (msg) { if (!this.enabled) return; this.logger ? this.logger.info(msg) : console.info(msg); }, w: function (msg) { if (!this.enabled) return; this.logger ? this.logger.warning(msg) : console.warn(msg); }, e: function (msg) { if (!this.enabled) return; this.logger ? this.logger.error(msg) : console.error(msg); }, }; var EError = /** @class */ (function (_super) { __extends(EError, _super); function EError(message) { var _this = _super.call(this, message) || this; _this.code = exports.exception_codes[_this.name]; Object.defineProperty(_this, "name", { value: "EError" }); return _this; } return EError; }(ts_custom_error_1.CustomError)); /** * Base class for all server errors * @extends Error * @category Errors */ var ServerError = /** @class */ (function (_super) { __extends(ServerError, _super); function ServerError(message) { var _this = _super.call(this, message) || this; Object.defineProperty(_this, "name", { value: "ServerError" }); return _this; } return ServerError; }(EError)); exports.ServerError = ServerError; /** * Base class for all authentication errors * @extends ServerError * @category Errors */ var AuthError = /** @class */ (function (_super) { __extends(AuthError, _super); function AuthError(message) { var _this = _super.call(this, message) || this; Object.defineProperty(_this, "name", { value: "AuthError" }); return _this; } return AuthError; }(ServerError)); exports.AuthError = AuthError; /** * Wrong credentials error * @extends AuthError * @category Errors */ var AuthWrongCredentialsError = /** @class */ (function (_super) { __extends(AuthWrongCredentialsError, _super); function AuthWrongCredentialsError(message) { var _this = _super.call(this, message) || this; Object.defineProperty(_this, "name", { value: "AuthWrongCredentialsError" }); return _this; } return AuthWrongCredentialsError; }(AuthError)); exports.AuthWrongCredentialsError = AuthWrongCredentialsError; /** * Authentication required error * @extends AuthError * @category Errors */ var AuthRequiredError = /** @class */ (function (_super) { __extends(AuthRequiredError, _super); function AuthRequiredError(message) { var _this = _super.call(this, message) || this; Object.defineProperty(_this, "name", { value: "AuthRequiredError" }); return _this; } return AuthRequiredError; }(AuthError)); exports.AuthRequiredError = AuthRequiredError; /** * Missing credentials error * @extends AuthError * @category Errors */ var AuthMissingCredentials = /** @class */ (function (_super) { __extends(AuthMissingCredentials, _super); function AuthMissingCredentials(message) { var _this = _super.call(this, message) || this; Object.defineProperty(_this, "name", { value: "AuthMissingCredentials" }); return _this; } return AuthMissingCredentials; }(AuthError)); exports.AuthMissingCredentials = AuthMissingCredentials; /** * Base class for all client errors * @extends ServerError * @category Errors */ var ClientError = /** @class */ (function (_super) { __extends(ClientError, _super); function ClientError(message) { var _this = _super.call(this, message) || this; Object.defineProperty(_this, "name", { value: "ClientError" }); return _this; } return ClientError; }(ServerError)); exports.ClientError = ClientError; /** * Timeout error * @extends ClientError * @category Errors */ var TimeoutError = /** @class */ (function (_super) { __extends(TimeoutError, _super); function TimeoutError(message) { var _this = _super.call(this, message) || this; Object.defineProperty(_this, "name", { value: "TimoutError" }); return _this; } return TimeoutError; }(ClientError)); exports.TimeoutError = TimeoutError; /** * Base class for all connection errors * @extends ClientError * @category Errors */ var ConnectionError = /** @class */ (function (_super) { __extends(ConnectionError, _super); function ConnectionError(message) { var _this = _super.call(this, message) || this; Object.defineProperty(_this, "name", { value: "ConnectionError" }); return _this; } return ConnectionError; }(ClientError)); exports.ConnectionError = ConnectionError; /** * Server disconnect error * @extends ConnectionError * @category Errors */ var ServerDisconnectError = /** @class */ (function (_super) { __extends(ServerDisconnectError, _super); function ServerDisconnectError() { return _super !== null && _super.apply(this, arguments) || this; } return ServerDisconnectError; }(ConnectionError)); exports.ServerDisconnectError = ServerDisconnectError; ; /** * A helper function that will wrap your message up like this: * ``` * msg = { * 'session': session_id, * 'name': name, * 'command': command, <--- your command is put here * 'data': data, # <--- your message is put here * } * ``` * @param {ServerCommand} command - message to wrap * @param {AnyJson} data - message to wrap * @param {string} session_id - optional, session id * @param {string} name - name of client * @param {AnyJson} msg_id - optional message id * @return {ServerMsg} */ function finalize(command, data, session_id, name, msg_id) { session_id = session_id || ""; var msg = { __id__: msg_id, command: command, session: session_id, name: name ? name : "js-client", data: data, }; return msg; } exports.finalize = finalize; var HPXTransform = /** @class */ (function (_super) { __extends(HPXTransform, _super); function HPXTransform(client_name, options) { var _this = _super.call(this, options) || this; _this._buffer = Buffer.from("", encoding); _this._client_name = client_name; return _this; } HPXTransform.prototype._end_of_msg = function (buffer) { var remaining_buffer = buffer; var idx = buffer.indexOf(postfix); var eof = false; var data = Buffer.from("", encoding); if (idx !== -1) { data = buffer.slice(0, idx); remaining_buffer = buffer.slice(idx + postfix.length); eof = true; } return { data: data, remaining_buffer: remaining_buffer, eof: eof }; }; HPXTransform.prototype._transform = function (chunk, enc, callback) { var err = null; if (!chunk.length) err = new ServerDisconnectError("Server disconnected for client '" + this._client_name + "'"); this._buffer = Buffer.concat([this._buffer, chunk]); var eof = true; while (eof && err == null) { var _a = this._end_of_msg(this._buffer), data = _a.data, remaining_buffer = _a.remaining_buffer, eof_ = _a.eof; eof = eof_; this._buffer = remaining_buffer; if (eof && data.length) { this.push(data); } } callback(err); }; return HPXTransform; }(stream_1.Transform)); /** * A class representing a HappyPanda X client */ var Client = /** @class */ (function () { /** * @param {Object} params - optional params * @param [params.name=js-client] {string} - name of client * @param [params.host] {string} - server host * @param [params.port] {integer} - server port * @param [params.user] {string} - username * @param [params.password] {string} - password * @param [params.session_id] {string} - a server session id * @param [params.timeout] {integer} - connection timeout */ function Client(_a) { var name = _a.name, host = _a.host, port = _a.port, session_id = _a.session_id, timeout = _a.timeout, user = _a.user, password = _a.password; this.name = name || "js-client"; this.endpoint = [host || "localhost", port || 7007]; // [host, port] this._alive = false; this._disconnected = false; // specifically used by _on_disconnect this._ready = false; this.session = session_id || ""; this.resolve_IPV4_localhost = true; // see https://github.com/nodejs/node/issues/40702 this.version = null; this.guest_allowed = false; this._id_counter = 0; this._last_user = user !== null && user !== void 0 ? user : ""; this._last_pass = password !== null && password !== void 0 ? password : ""; this._stream = new HPXTransform(this.name, { defaultEncoding: encoding, }); this._stream.on("data", this._recv.bind(this)); this._timeout = timeout || 5000; this._sock = null; // lol this._encoder = new msgpack_1.Encoder(undefined, undefined, undefined, undefined, undefined, undefined, true); this._decoder = new msgpack_1.Decoder(); this.__data_promises = {}; this.__data_promises_order = []; this._connecting = false; this._create_socket(); } Client.prototype._create_socket = function () { var _this = this; this._sock = new net.Socket(); this._sock.setTimeout(this.timeout, this._on_timeout.bind(this)); this._sock.on("data", function (data) { return _this._stream.write(data); }); this._sock.on("connect", this._on_connect.bind(this)); this._sock.on("close", this._on_disconnect.bind(this)); this._sock.on("end", this._on_disconnect.bind(this)); this._sock.on("error", this._on_error.bind(this)); }; /** * Add a listener to the underlying socket * @param {string} event - event name * @param {Function} listener - listener function * @return {Client} */ Client.prototype.on = function (event, listener) { var _a; (_a = this._sock) === null || _a === void 0 ? void 0 : _a.on(event, listener); return this; }; /** * Add a listener to the underlying socket * @param {string} event - event name * @param {Function} listener - listener function * @return {Client} */ Client.prototype.once = function () { var _a; var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } (_a = this._sock) === null || _a === void 0 ? void 0 : _a.once.apply(_a, args); return this; }; /** * Remove a listener from the underlying socket * @param {string} event - event name * @param {Function} listener - listener function * @return {Client} */ Client.prototype.off = function () { var _a; var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } (_a = this._sock) === null || _a === void 0 ? void 0 : _a.off.apply(_a, args); return this; }; /** * Check if server is still alive * @return {boolean} */ Client.prototype.alive = function () { var _a; return this._alive && !((_a = this._sock) === null || _a === void 0 ? void 0 : _a.destroyed); }; /** * Check if client is ready to exchange messages with server * @return {boolean} */ Client.prototype.ready = function () { return this._ready; }; Object.defineProperty(Client.prototype, "timeout", { /** * Get the timeout value * @return {number} */ get: function () { return this._timeout; }, set: function (t) { var _a; this._timeout = t; (_a = this._sock) === null || _a === void 0 ? void 0 : _a.setTimeout(this._timeout, this._on_timeout.bind(this)); }, enumerable: false, configurable: true }); Object.defineProperty(Client.prototype, "_connect_msg_id", { get: function () { return this.name + "_connect"; }, enumerable: false, configurable: true }); Object.defineProperty(Client.prototype, "_close_msg_id", { get: function () { return this.name + "_close"; }, enumerable: false, configurable: true }); Client.prototype._next_id = function () { this._id_counter = (this._id_counter + 1) % 99999; return this.name + "_msg_" + this._id_counter; }; Client.prototype._add_data_promise = function (msg_id, resolve, reject) { this.__data_promises[msg_id] = [resolve, reject]; this.__data_promises_order.push(msg_id); }; Client.prototype._get_data_promise = function (msg_id) { if (!msg_id) return; var v = this.__data_promises[msg_id]; if (v) { delete this.__data_promises[msg_id]; var idx = this.__data_promises_order.indexOf(msg_id); if (idx > -1) { this.__data_promises_order.splice(idx, 1); } } return v; }; Client.prototype._get_earliest_data_promise = function () { var msg_id = this.__data_promises_order.shift(); if (msg_id) { var v = this.__data_promises[msg_id]; if (v) { delete this.__data_promises[msg_id]; } return v; } }; Client.prototype._server_info = function (msg) { if (msg) { var serv_data = msg === null || msg === void 0 ? void 0 : msg.data; if (serv_data && (serv_data === null || serv_data === void 0 ? void 0 : serv_data.version)) { this.guest_allowed = serv_data.guest_allowed || false; this.version = serv_data.version; this._ready = true; } } }; /** * Set server address * @param {string} host - server host * @param {integer} port - server port */ Client.prototype.set_endpoint = function (host, port) { this.endpoint = [host, port]; }; /** * Perfom a handshake with the HPX server * @category async * @param {object} params - optinal params * @param [params.user] {string} - username * @param [params.password] {integer} - password * @param [params.ignore_err] {boolean} - ignore error * @throws {AuthError} * @returns {Promise} */ Client.prototype.handshake = function (params) { return __awaiter(this, void 0, void 0, function () { var user, password, ignore_err, d, data, serv_error, serv_data; return __generator(this, function (_a) { switch (_a.label) { case 0: user = params.user; password = params.password; if (user === undefined) { user = this._last_user; password = this._last_pass; } ignore_err = params.ignore_err; if (!this.alive()) return [3 /*break*/, 2]; if (password === undefined) password = null; if (user) { this._last_user = user; this._last_pass = password; } d = {}; if (user) { d.user = user; d.password = password; } exports.log.d("Client '".concat(this.name, "' handshaking server at ").concat(JSON.stringify(this.endpoint))); return [4 /*yield*/, this.send_raw(finalize("handshake", d, undefined, this.name))]; case 1: data = _a.sent(); if (!ignore_err && data) { serv_error = data.error; if (serv_error) { if (serv_error.code === exports.exception_codes["AuthWrongCredentialsError"]) throw new AuthWrongCredentialsError(serv_error.msg); else if (serv_error.code === exports.exception_codes["AuthRequiredError"]) throw new AuthRequiredError(serv_error.msg); else if (serv_error.code === exports.exception_codes["AuthMissingCredentials"]) throw new AuthMissingCredentials(serv_error.msg); else throw new AuthError(serv_error.code.toString() + ": " + serv_error.msg); } } serv_data = data.data; if (serv_data === "Authenticated") { this.session = data.session; return [2 /*return*/, true]; } _a.label = 2; case 2: return [2 /*return*/, false]; } }); }); }; /** * Forces client to request a new handshake, but doesn't invalidate previous session * @category async * @returns {Promise} */ Client.prototype.request_auth = function () { return __awaiter(this, void 0, void 0, function () { var data; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.send_raw(finalize("requestauth", null, undefined, this.name))]; case 1: data = _a.sent(); this._server_info(data); this.session = ""; return [2 /*return*/]; } }); }); }; /** * Logout and invalidates the session * @category async * @returns {Promise} */ Client.prototype.drop_auth = function () { return __awaiter(this, void 0, void 0, function () { var data; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.send_raw(finalize("dropauth", null, this.session, this.name))]; case 1: data = _a.sent(); this._server_info(data); this.session = ""; return [2 /*return*/]; } }); }); }; /** * Send the serverquit command * @category async * @returns {Promise} */ Client.prototype.server_quit = function () { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.send_raw(finalize("serverquit", null, this.session, this.name))]; case 1: return [2 /*return*/, _a.sent()]; } }); }); }; /** * Send the serverrestart command * @category async * @returns {Promise} */ Client.prototype.server_restart = function () { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.send_raw(finalize("serverrestart", null, this.session, this.name))]; case 1: return [2 /*return*/, _a.sent()]; } }); }); }; /** * Call a single function, this is even more of a shortcut than send * @category async * @param {ClientMsg<'call'>['data']} data - data * @returns {Promise} */ Client.prototype.call = function (data) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.send('call', data)]; case 1: return [2 /*return*/, _a.sent()]; } }); }); }; /** * Call a single function, this is even more of a shortcut than send * @category async * @param {string} fname - function name * @param [args] {object} - function arguments * @returns {Promise} */ Client.prototype.call_function = function (fname, args) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.send('call', [__assign({ fname: fname }, args)])]; case 1: return [2 /*return*/, _a.sent()]; } }); }); }; /** * Check if the client is still connected to the server * @return {boolean} */ Client.prototype.is_connected = function () { return this.alive(); }; /** * Connect to HPX server * @category async * @param {object} params - optional params * @param [params.host] {string} - server host * @param [params.port] {integer} - server port * @returns {Promise} */ Client.prototype.connect = function (params) { return __awaiter(this, void 0, void 0, function () { var host, port, p; var _this = this; return __generator(this, function (_a) { host = params === null || params === void 0 ? void 0 : params.host; port = params === null || params === void 0 ? void 0 : params.port; p = new Promise(function (resolve, reject) { var _a, _b; if (!_this._alive && !_this._connecting) { var endpoint = _this.endpoint; if (host !== undefined) endpoint[0] = host; if (port !== undefined) endpoint[1] = port; exports.log.d("Client '".concat(_this.name, "' connecting to server at: ").concat(JSON.stringify(endpoint))); _this._connecting = true; _this._disconnected = false; _this._add_data_promise(_this._connect_msg_id, resolve, reject); var h = endpoint[0]; if (_this.resolve_IPV4_localhost) { if (h === "localhost") h = "127.0.0.1"; } if ((_a = _this._sock) === null || _a === void 0 ? void 0 : _a.destroyed) { _this._create_socket(); } (_b = _this._sock) === null || _b === void 0 ? void 0 : _b.connect(endpoint[1], h); _this.endpoint = endpoint; } else reject(Error("Client '".concat(_this.name, "' already connected or trying to connect"))); }); return [2 /*return*/, p]; }); }); }; Client.prototype._on_timeout = function () { var _a; this._connecting = false; var err = new TimeoutError("timeout"); if (!this._ready) { this._disconnect(); (_a = this._sock) === null || _a === void 0 ? void 0 : _a.destroy(err); } exports.log.e("Client '".concat(this.name, "' timed out after ").concat(this.timeout, "ms")); var connect_p = this._get_data_promise(this._connect_msg_id); if (connect_p) { return connect_p[1](err); } var close_p = this._get_data_promise(this._close_msg_id); if (close_p) { return close_p[1](err); } var p = this._get_earliest_data_promise(); if (p) { return p[1](err); } }; Client.prototype._on_connect = function () { this._connecting = false; this._alive = true; exports.log.d("Client '".concat(this.name, "' successfully connected to server at: ").concat(JSON.stringify(this.endpoint))); }; Client.prototype._on_error = function (error) { this._connecting = false; this._disconnect(); exports.log.e("An error occured in client '".concat(this.name, "': ").concat(error.message)); var connect_p = this._get_data_promise(this._connect_msg_id); if (connect_p) { return connect_p[1](error); } var p = this._get_earliest_data_promise(); if (p) { return p[1](error); } }; Client.prototype._on_disconnect = function () { if (this._disconnected) { return; } exports.log.d("Client '".concat(this.name, "' disconnected from server at: ").concat(JSON.stringify(this.endpoint))); this._disconnect(); var p = this._get_data_promise(this._close_msg_id); if (p) { p[0](); } }; Client.prototype._disconnect = function () { this._alive = false; this._disconnected = true; this.session = ""; this._ready = false; }; /** * Like {@link send_raw}, but as a convenience, this method will wrap your message into the required message structure HPX expects and automatically sets the session and name * @category async * @param {JsonMap} data - the data part of the message * @param {ServerCommand} command - the command, defaults to 'call' * @returns {Promise} * @fullfil {Object} - message from server */ Client.prototype.send = function (command, data) { return __awaiter(this, void 0, void 0, function () { var msg_id; return __generator(this, function (_a) { msg_id = this._next_id(); return [2 /*return*/, this._send(finalize(command, data, this.session, this.name, msg_id), msg_id)]; }); }); }; /** * Send json-compatible Object to server. Receive json-compatible Object from server. * * Note that this method will not modify your message and expects you to add the name and session yourself. See the {@link finalize} function. * @category async * @param {Object} msg - message to send to the server * @returns {Promise} * @fullfil {Object} - message from server */ Client.prototype.send_raw = function (msg) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { if (!msg.__id__) { msg.__id__ = this._next_id(); } return [2 /*return*/, this._send(msg, msg.__id__)]; }); }); }; Client.prototype._send = function (msg_bytes, msg_id) { return __awaiter(this, void 0, void 0, function () { var p; var _this = this; return __generator(this, function (_a) { p = new Promise(function (resolve, reject) { var _a, _b; if (!_this._alive) { return reject(new ClientError("Client '".concat(_this.name, "' is not connected to server"))); } try { var d = _this._encoder.encode(msg_bytes); (_a = _this._sock) === null || _a === void 0 ? void 0 : _a.write(d); (_b = _this._sock) === null || _b === void 0 ? void 0 : _b.write(postfix); _this._add_data_promise(msg_id, resolve, reject); exports.log.d("Client '".concat(_this.name, "' sending ").concat(d.length.toString(), " bytes to server ").concat(JSON.stringify(_this.endpoint))); } catch (err) { reject(err); } }); return [2 /*return*/, p]; }); }); }; Client.prototype._recv = function (data) { exports.log.d("Client '".concat(this.name, "' recieved ").concat(data.length.toString(), " bytes from server")); if (!this._alive) { return; } var err; var parsed_data; try { parsed_data = this._decoder.decode(data); } catch (e) { err = e; } var connect_p = this._get_data_promise(this._connect_msg_id); if (connect_p) { if (err) { return connect_p[1](err); } this._server_info(parsed_data); return connect_p[0](parsed_data); } if (parsed_data) { var p = this._get_data_promise(parsed_data.__id__); if (p) { return p[0](parsed_data); } } else if (err) { var p = this._get_earliest_data_promise(); if (p) { return p[1](err); } } }; /** * Close the connection * @returns {Promise} */ Client.prototype.close = function () { return __awaiter(this, void 0, void 0, function () { var _this = this; return __generator(this, function (_a) { exports.log.d("Client '".concat(this.name, "' closing connection to server")); this._disconnect(); return [2 /*return*/, new Promise(function (resolve, reject) { var _a; _this._add_data_promise(_this._close_msg_id, resolve, reject); (_a = _this._sock) === null || _a === void 0 ? void 0 : _a.end(function () { setTimeout(function () { var _a; if (!_this._disconnected) { (_a = _this._sock) === null || _a === void 0 ? void 0 : _a.destroy(); _this._on_disconnect(); } var p = _this._get_data_promise(_this._close_msg_id); if (p) { return p[0](); } }, 1000); }); })]; }); }); }; return Client; }()); exports.Client = Client; exports.default = Client;