rpc-websockets
Advanced tools
Comparing version 7.10.0 to 7.11.0
"use strict"; | ||
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.Client = void 0; | ||
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); | ||
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); | ||
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); | ||
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); | ||
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); | ||
var _websocket = _interopRequireDefault(require("./lib/client/websocket.browser")); | ||
var _client = _interopRequireDefault(require("./lib/client")); | ||
function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2["default"])(o), (0, _possibleConstructorReturn2["default"])(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2["default"])(t).constructor) : o.apply(t, e)); } | ||
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); } | ||
var Client = exports.Client = /*#__PURE__*/function (_CommonClient) { | ||
function Client() { | ||
var address = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "ws://localhost:8080"; | ||
var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, | ||
_ref$autoconnect = _ref.autoconnect, | ||
autoconnect = _ref$autoconnect === void 0 ? true : _ref$autoconnect, | ||
_ref$reconnect = _ref.reconnect, | ||
reconnect = _ref$reconnect === void 0 ? true : _ref$reconnect, | ||
_ref$reconnect_interv = _ref.reconnect_interval, | ||
reconnect_interval = _ref$reconnect_interv === void 0 ? 1000 : _ref$reconnect_interv, | ||
_ref$max_reconnects = _ref.max_reconnects, | ||
max_reconnects = _ref$max_reconnects === void 0 ? 5 : _ref$max_reconnects; | ||
var generate_request_id = arguments.length > 2 ? arguments[2] : undefined; | ||
(0, _classCallCheck2["default"])(this, Client); | ||
return _callSuper(this, Client, [_websocket["default"], address, { | ||
autoconnect: autoconnect, | ||
reconnect: reconnect, | ||
reconnect_interval: reconnect_interval, | ||
max_reconnects: max_reconnects | ||
}, generate_request_id]); | ||
} | ||
(0, _inherits2["default"])(Client, _CommonClient); | ||
return (0, _createClass2["default"])(Client); | ||
}(_client["default"]); | ||
const websocket_browser_1 = __importDefault(require("./lib/client/websocket.browser")); | ||
const client_1 = __importDefault(require("./lib/client")); | ||
class Client extends client_1.default { | ||
constructor(address = "ws://localhost:8080", { autoconnect = true, reconnect = true, reconnect_interval = 1000, max_reconnects = 5 } = {}, generate_request_id) { | ||
super(websocket_browser_1.default, address, { | ||
autoconnect, | ||
reconnect, | ||
reconnect_interval, | ||
max_reconnects | ||
}, generate_request_id); | ||
} | ||
} | ||
exports.Client = Client; |
"use strict"; | ||
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
exports.Client = void 0; | ||
Object.defineProperty(exports, "Server", { | ||
enumerable: true, | ||
get: function get() { | ||
return _server["default"]; | ||
} | ||
}); | ||
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); | ||
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); | ||
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); | ||
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); | ||
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); | ||
var _websocket = _interopRequireDefault(require("./lib/client/websocket")); | ||
var _client = _interopRequireDefault(require("./lib/client")); | ||
var _server = _interopRequireDefault(require("./lib/server")); | ||
function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2["default"])(o), (0, _possibleConstructorReturn2["default"])(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2["default"])(t).constructor) : o.apply(t, e)); } | ||
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); } | ||
var __rest = void 0 && (void 0).__rest || function (s, e) { | ||
var t = {}; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; | ||
if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { | ||
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; | ||
} | ||
return t; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
var Client = exports.Client = /*#__PURE__*/function (_CommonClient) { | ||
function Client() { | ||
var address = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "ws://localhost:8080"; | ||
var _a = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
var generate_request_id = arguments.length > 2 ? arguments[2] : undefined; | ||
(0, _classCallCheck2["default"])(this, Client); | ||
var _a$autoconnect = _a.autoconnect, | ||
autoconnect = _a$autoconnect === void 0 ? true : _a$autoconnect, | ||
_a$reconnect = _a.reconnect, | ||
reconnect = _a$reconnect === void 0 ? true : _a$reconnect, | ||
_a$reconnect_interval = _a.reconnect_interval, | ||
reconnect_interval = _a$reconnect_interval === void 0 ? 1000 : _a$reconnect_interval, | ||
_a$max_reconnects = _a.max_reconnects, | ||
max_reconnects = _a$max_reconnects === void 0 ? 5 : _a$max_reconnects, | ||
rest_options = __rest(_a, ["autoconnect", "reconnect", "reconnect_interval", "max_reconnects"]); | ||
return _callSuper(this, Client, [_websocket["default"], address, Object.assign({ | ||
autoconnect: autoconnect, | ||
reconnect: reconnect, | ||
reconnect_interval: reconnect_interval, | ||
max_reconnects: max_reconnects | ||
}, rest_options), generate_request_id]); | ||
} | ||
(0, _inherits2["default"])(Client, _CommonClient); | ||
return (0, _createClass2["default"])(Client); | ||
}(_client["default"]); | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.Server = exports.Client = void 0; | ||
const websocket_1 = __importDefault(require("./lib/client/websocket")); | ||
const client_1 = __importDefault(require("./lib/client")); | ||
class Client extends client_1.default { | ||
constructor(address = "ws://localhost:8080", { autoconnect = true, reconnect = true, reconnect_interval = 1000, max_reconnects = 5, ...rest_options } = {}, generate_request_id) { | ||
super(websocket_1.default, address, { | ||
autoconnect, | ||
reconnect, | ||
reconnect_interval, | ||
max_reconnects, | ||
...rest_options | ||
}, generate_request_id); | ||
} | ||
} | ||
exports.Client = Client; | ||
var server_1 = require("./lib/server"); | ||
Object.defineProperty(exports, "Server", { enumerable: true, get: function () { return __importDefault(server_1).default; } }); |
@@ -7,99 +7,78 @@ /** | ||
"use strict"; | ||
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
exports["default"] = void 0; | ||
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator")); | ||
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator")); | ||
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof")); | ||
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); | ||
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); | ||
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); | ||
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); | ||
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); | ||
var _eventemitter = require("eventemitter3"); | ||
var _utils = require("./utils"); | ||
function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2["default"])(o), (0, _possibleConstructorReturn2["default"])(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2["default"])(t).constructor) : o.apply(t, e)); } | ||
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); } | ||
var __rest = void 0 && (void 0).__rest || function (s, e) { | ||
var t = {}; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; | ||
if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { | ||
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; | ||
} | ||
return t; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
// @ts-ignore | ||
var CommonClient = exports["default"] = /*#__PURE__*/function (_EventEmitter) { | ||
/** | ||
* Instantiate a Client class. | ||
* @constructor | ||
* @param {webSocketFactory} webSocketFactory - factory method for WebSocket | ||
* @param {String} address - url to a websocket server | ||
* @param {Object} options - ws options object with reconnect parameters | ||
* @param {Function} generate_request_id - custom generation request Id | ||
* @param {DataPack} dataPack - data pack contains encoder and decoder | ||
* @return {CommonClient} | ||
*/ | ||
function CommonClient(webSocketFactory) { | ||
var _this; | ||
var address = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "ws://localhost:8080"; | ||
var _a = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; | ||
var generate_request_id = arguments.length > 3 ? arguments[3] : undefined; | ||
var dataPack = arguments.length > 4 ? arguments[4] : undefined; | ||
(0, _classCallCheck2["default"])(this, CommonClient); | ||
var _a$autoconnect = _a.autoconnect, | ||
autoconnect = _a$autoconnect === void 0 ? true : _a$autoconnect, | ||
_a$reconnect = _a.reconnect, | ||
reconnect = _a$reconnect === void 0 ? true : _a$reconnect, | ||
_a$reconnect_interval = _a.reconnect_interval, | ||
reconnect_interval = _a$reconnect_interval === void 0 ? 1000 : _a$reconnect_interval, | ||
_a$max_reconnects = _a.max_reconnects, | ||
max_reconnects = _a$max_reconnects === void 0 ? 5 : _a$max_reconnects, | ||
rest_options = __rest(_a, ["autoconnect", "reconnect", "reconnect_interval", "max_reconnects"]); | ||
_this = _callSuper(this, CommonClient); | ||
_this.webSocketFactory = webSocketFactory; | ||
_this.queue = {}; | ||
_this.rpc_id = 0; | ||
_this.address = address; | ||
_this.autoconnect = autoconnect; | ||
_this.ready = false; | ||
_this.reconnect = reconnect; | ||
_this.reconnect_timer_id = undefined; | ||
_this.reconnect_interval = reconnect_interval; | ||
_this.max_reconnects = max_reconnects; | ||
_this.rest_options = rest_options; | ||
_this.current_reconnects = 0; | ||
_this.generate_request_id = generate_request_id || function () { | ||
return ++_this.rpc_id; | ||
}; | ||
if (!dataPack) _this.dataPack = new _utils.DefaultDataPack();else _this.dataPack = dataPack; | ||
if (_this.autoconnect) _this._connect(_this.address, Object.assign({ | ||
autoconnect: _this.autoconnect, | ||
reconnect: _this.reconnect, | ||
reconnect_interval: _this.reconnect_interval, | ||
max_reconnects: _this.max_reconnects | ||
}, _this.rest_options)); | ||
return _this; | ||
} | ||
/** | ||
* Connects to a defined server if not connected already. | ||
* @method | ||
* @return {Undefined} | ||
*/ | ||
(0, _inherits2["default"])(CommonClient, _EventEmitter); | ||
return (0, _createClass2["default"])(CommonClient, [{ | ||
key: "connect", | ||
value: function connect() { | ||
if (this.socket) return; | ||
this._connect(this.address, Object.assign({ | ||
autoconnect: this.autoconnect, | ||
reconnect: this.reconnect, | ||
reconnect_interval: this.reconnect_interval, | ||
max_reconnects: this.max_reconnects | ||
}, this.rest_options)); | ||
const eventemitter3_1 = require("eventemitter3"); | ||
const utils_1 = require("./utils"); | ||
class CommonClient extends eventemitter3_1.EventEmitter { | ||
address; | ||
rpc_id; | ||
queue; | ||
options; | ||
autoconnect; | ||
ready; | ||
reconnect; | ||
reconnect_timer_id; | ||
reconnect_interval; | ||
max_reconnects; | ||
rest_options; | ||
current_reconnects; | ||
generate_request_id; | ||
socket; | ||
webSocketFactory; | ||
dataPack; | ||
/** | ||
* Instantiate a Client class. | ||
* @constructor | ||
* @param {webSocketFactory} webSocketFactory - factory method for WebSocket | ||
* @param {String} address - url to a websocket server | ||
* @param {Object} options - ws options object with reconnect parameters | ||
* @param {Function} generate_request_id - custom generation request Id | ||
* @param {DataPack} dataPack - data pack contains encoder and decoder | ||
* @return {CommonClient} | ||
*/ | ||
constructor(webSocketFactory, address = "ws://localhost:8080", { autoconnect = true, reconnect = true, reconnect_interval = 1000, max_reconnects = 5, ...rest_options } = {}, generate_request_id, dataPack) { | ||
super(); | ||
this.webSocketFactory = webSocketFactory; | ||
this.queue = {}; | ||
this.rpc_id = 0; | ||
this.address = address; | ||
this.autoconnect = autoconnect; | ||
this.ready = false; | ||
this.reconnect = reconnect; | ||
this.reconnect_timer_id = undefined; | ||
this.reconnect_interval = reconnect_interval; | ||
this.max_reconnects = max_reconnects; | ||
this.rest_options = rest_options; | ||
this.current_reconnects = 0; | ||
this.generate_request_id = generate_request_id || (() => ++this.rpc_id); | ||
if (!dataPack) | ||
this.dataPack = new utils_1.DefaultDataPack(); | ||
else | ||
this.dataPack = dataPack; | ||
if (this.autoconnect) | ||
this._connect(this.address, { | ||
autoconnect: this.autoconnect, | ||
reconnect: this.reconnect, | ||
reconnect_interval: this.reconnect_interval, | ||
max_reconnects: this.max_reconnects, | ||
...this.rest_options | ||
}); | ||
} | ||
/** | ||
* Connects to a defined server if not connected already. | ||
* @method | ||
* @return {Undefined} | ||
*/ | ||
connect() { | ||
if (this.socket) | ||
return; | ||
this._connect(this.address, { | ||
autoconnect: this.autoconnect, | ||
reconnect: this.reconnect, | ||
reconnect_interval: this.reconnect_interval, | ||
max_reconnects: this.max_reconnects, | ||
...this.rest_options | ||
}); | ||
} | ||
/** | ||
* Calls a registered RPC method on server. | ||
@@ -113,32 +92,29 @@ * @method | ||
*/ | ||
}, { | ||
key: "call", | ||
value: function call(method, params, timeout, ws_opts) { | ||
var _this2 = this; | ||
if (!ws_opts && "object" === (0, _typeof2["default"])(timeout)) { | ||
ws_opts = timeout; | ||
timeout = null; | ||
} | ||
return new Promise(function (resolve, reject) { | ||
if (!_this2.ready) return reject(new Error("socket not ready")); | ||
var rpc_id = _this2.generate_request_id(method, params); | ||
var message = { | ||
jsonrpc: "2.0", | ||
method: method, | ||
params: params || undefined, | ||
id: rpc_id | ||
}; | ||
_this2.socket.send(_this2.dataPack.encode(message), ws_opts, function (error) { | ||
if (error) return reject(error); | ||
_this2.queue[rpc_id] = { | ||
promise: [resolve, reject] | ||
}; | ||
if (timeout) { | ||
_this2.queue[rpc_id].timeout = setTimeout(function () { | ||
delete _this2.queue[rpc_id]; | ||
reject(new Error("reply timeout")); | ||
}, timeout); | ||
} | ||
call(method, params, timeout, ws_opts) { | ||
if (!ws_opts && "object" === typeof timeout) { | ||
ws_opts = timeout; | ||
timeout = null; | ||
} | ||
return new Promise((resolve, reject) => { | ||
if (!this.ready) | ||
return reject(new Error("socket not ready")); | ||
const rpc_id = this.generate_request_id(method, params); | ||
const message = { | ||
jsonrpc: "2.0", | ||
method: method, | ||
params: params || undefined, | ||
id: rpc_id | ||
}; | ||
this.socket.send(this.dataPack.encode(message), ws_opts, (error) => { | ||
if (error) | ||
return reject(error); | ||
this.queue[rpc_id] = { promise: [resolve, reject] }; | ||
if (timeout) { | ||
this.queue[rpc_id].timeout = setTimeout(() => { | ||
delete this.queue[rpc_id]; | ||
reject(new Error("reply timeout")); | ||
}, timeout); | ||
} | ||
}); | ||
}); | ||
}); | ||
} | ||
@@ -151,32 +127,8 @@ /** | ||
*/ | ||
}, { | ||
key: "login", | ||
value: (function () { | ||
var _login = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee(params) { | ||
var resp; | ||
return _regenerator["default"].wrap(function _callee$(_context) { | ||
while (1) switch (_context.prev = _context.next) { | ||
case 0: | ||
_context.next = 2; | ||
return this.call("rpc.login", params); | ||
case 2: | ||
resp = _context.sent; | ||
if (resp) { | ||
_context.next = 5; | ||
break; | ||
} | ||
throw new Error("authentication failed"); | ||
case 5: | ||
return _context.abrupt("return", resp); | ||
case 6: | ||
case "end": | ||
return _context.stop(); | ||
} | ||
}, _callee, this); | ||
})); | ||
function login(_x) { | ||
return _login.apply(this, arguments); | ||
} | ||
return login; | ||
}() | ||
async login(params) { | ||
const resp = await this.call("rpc.login", params); | ||
if (!resp) | ||
throw new Error("authentication failed"); | ||
return resp; | ||
} | ||
/** | ||
@@ -187,25 +139,5 @@ * Fetches a list of client's methods registered on server. | ||
*/ | ||
) | ||
}, { | ||
key: "listMethods", | ||
value: (function () { | ||
var _listMethods = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee2() { | ||
return _regenerator["default"].wrap(function _callee2$(_context2) { | ||
while (1) switch (_context2.prev = _context2.next) { | ||
case 0: | ||
_context2.next = 2; | ||
return this.call("__listMethods"); | ||
case 2: | ||
return _context2.abrupt("return", _context2.sent); | ||
case 3: | ||
case "end": | ||
return _context2.stop(); | ||
} | ||
}, _callee2, this); | ||
})); | ||
function listMethods() { | ||
return _listMethods.apply(this, arguments); | ||
} | ||
return listMethods; | ||
}() | ||
async listMethods() { | ||
return await this.call("__listMethods"); | ||
} | ||
/** | ||
@@ -218,19 +150,17 @@ * Sends a JSON-RPC 2.0 notification to server. | ||
*/ | ||
) | ||
}, { | ||
key: "notify", | ||
value: function notify(method, params) { | ||
var _this3 = this; | ||
return new Promise(function (resolve, reject) { | ||
if (!_this3.ready) return reject(new Error("socket not ready")); | ||
var message = { | ||
jsonrpc: "2.0", | ||
method: method, | ||
params: params | ||
}; | ||
_this3.socket.send(_this3.dataPack.encode(message), function (error) { | ||
if (error) return reject(error); | ||
resolve(); | ||
notify(method, params) { | ||
return new Promise((resolve, reject) => { | ||
if (!this.ready) | ||
return reject(new Error("socket not ready")); | ||
const message = { | ||
jsonrpc: "2.0", | ||
method: method, | ||
params | ||
}; | ||
this.socket.send(this.dataPack.encode(message), (error) => { | ||
if (error) | ||
return reject(error); | ||
resolve(); | ||
}); | ||
}); | ||
}); | ||
} | ||
@@ -244,33 +174,10 @@ /** | ||
*/ | ||
}, { | ||
key: "subscribe", | ||
value: (function () { | ||
var _subscribe = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee3(event) { | ||
var result; | ||
return _regenerator["default"].wrap(function _callee3$(_context3) { | ||
while (1) switch (_context3.prev = _context3.next) { | ||
case 0: | ||
if (typeof event === "string") event = [event]; | ||
_context3.next = 3; | ||
return this.call("rpc.on", event); | ||
case 3: | ||
result = _context3.sent; | ||
if (!(typeof event === "string" && result[event] !== "ok")) { | ||
_context3.next = 6; | ||
break; | ||
} | ||
throw new Error("Failed subscribing to an event '" + event + "' with: " + result[event]); | ||
case 6: | ||
return _context3.abrupt("return", result); | ||
case 7: | ||
case "end": | ||
return _context3.stop(); | ||
} | ||
}, _callee3, this); | ||
})); | ||
function subscribe(_x2) { | ||
return _subscribe.apply(this, arguments); | ||
} | ||
return subscribe; | ||
}() | ||
async subscribe(event) { | ||
if (typeof event === "string") | ||
event = [event]; | ||
const result = await this.call("rpc.on", event); | ||
if (typeof event === "string" && result[event] !== "ok") | ||
throw new Error("Failed subscribing to an event '" + event + "' with: " + result[event]); | ||
return result; | ||
} | ||
/** | ||
@@ -283,34 +190,10 @@ * Unsubscribes from a defined event. | ||
*/ | ||
) | ||
}, { | ||
key: "unsubscribe", | ||
value: (function () { | ||
var _unsubscribe = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee4(event) { | ||
var result; | ||
return _regenerator["default"].wrap(function _callee4$(_context4) { | ||
while (1) switch (_context4.prev = _context4.next) { | ||
case 0: | ||
if (typeof event === "string") event = [event]; | ||
_context4.next = 3; | ||
return this.call("rpc.off", event); | ||
case 3: | ||
result = _context4.sent; | ||
if (!(typeof event === "string" && result[event] !== "ok")) { | ||
_context4.next = 6; | ||
break; | ||
} | ||
throw new Error("Failed unsubscribing from an event with: " + result); | ||
case 6: | ||
return _context4.abrupt("return", result); | ||
case 7: | ||
case "end": | ||
return _context4.stop(); | ||
} | ||
}, _callee4, this); | ||
})); | ||
function unsubscribe(_x3) { | ||
return _unsubscribe.apply(this, arguments); | ||
} | ||
return unsubscribe; | ||
}() | ||
async unsubscribe(event) { | ||
if (typeof event === "string") | ||
event = [event]; | ||
const result = await this.call("rpc.off", event); | ||
if (typeof event === "string" && result[event] !== "ok") | ||
throw new Error("Failed unsubscribing from an event with: " + result); | ||
return result; | ||
} | ||
/** | ||
@@ -323,7 +206,4 @@ * Closes a WebSocket connection gracefully. | ||
*/ | ||
) | ||
}, { | ||
key: "close", | ||
value: function close(code, data) { | ||
this.socket.close(code || 1000, data); | ||
close(code, data) { | ||
this.socket.close(code || 1000, data); | ||
} | ||
@@ -336,6 +216,4 @@ /** | ||
*/ | ||
}, { | ||
key: "setAutoReconnect", | ||
value: function setAutoReconnect(reconnect) { | ||
this.reconnect = reconnect; | ||
setAutoReconnect(reconnect) { | ||
this.reconnect = reconnect; | ||
} | ||
@@ -348,6 +226,4 @@ /** | ||
*/ | ||
}, { | ||
key: "setReconnectInterval", | ||
value: function setReconnectInterval(interval) { | ||
this.reconnect_interval = interval; | ||
setReconnectInterval(interval) { | ||
this.reconnect_interval = interval; | ||
} | ||
@@ -360,6 +236,4 @@ /** | ||
*/ | ||
}, { | ||
key: "setMaxReconnects", | ||
value: function setMaxReconnects(max_reconnects) { | ||
this.max_reconnects = max_reconnects; | ||
setMaxReconnects(max_reconnects) { | ||
this.max_reconnects = max_reconnects; | ||
} | ||
@@ -374,71 +248,71 @@ /** | ||
*/ | ||
}, { | ||
key: "_connect", | ||
value: function _connect(address, options) { | ||
var _this4 = this; | ||
clearTimeout(this.reconnect_timer_id); | ||
this.socket = this.webSocketFactory(address, options); | ||
this.socket.addEventListener("open", function () { | ||
_this4.ready = true; | ||
_this4.emit("open"); | ||
_this4.current_reconnects = 0; | ||
}); | ||
this.socket.addEventListener("message", function (_ref) { | ||
var message = _ref.data; | ||
if (message instanceof ArrayBuffer) message = Buffer.from(message).toString(); | ||
try { | ||
message = _this4.dataPack.decode(message); | ||
} catch (error) { | ||
return; | ||
} | ||
// check if any listeners are attached and forward event | ||
if (message.notification && _this4.listeners(message.notification).length) { | ||
if (!Object.keys(message.params).length) return _this4.emit(message.notification); | ||
var args = [message.notification]; | ||
if (message.params.constructor === Object) args.push(message.params);else | ||
// using for-loop instead of unshift/spread because performance is better | ||
for (var i = 0; i < message.params.length; i++) args.push(message.params[i]); | ||
// run as microtask so that pending queue messages are resolved first | ||
// eslint-disable-next-line prefer-spread | ||
return Promise.resolve().then(function () { | ||
_this4.emit.apply(_this4, args); | ||
}); | ||
} | ||
if (!_this4.queue[message.id]) { | ||
// general JSON RPC 2.0 events | ||
if (message.method) { | ||
// run as microtask so that pending queue messages are resolved first | ||
return Promise.resolve().then(function () { | ||
_this4.emit(message.method, message === null || message === void 0 ? void 0 : message.params); | ||
}); | ||
} | ||
return; | ||
} | ||
// reject early since server's response is invalid | ||
if ("error" in message === "result" in message) _this4.queue[message.id].promise[1](new Error("Server response malformed. Response must include either \"result\"" + " or \"error\", but not both.")); | ||
if (_this4.queue[message.id].timeout) clearTimeout(_this4.queue[message.id].timeout); | ||
if (message.error) _this4.queue[message.id].promise[1](message.error);else _this4.queue[message.id].promise[0](message.result); | ||
delete _this4.queue[message.id]; | ||
}); | ||
this.socket.addEventListener("error", function (error) { | ||
return _this4.emit("error", error); | ||
}); | ||
this.socket.addEventListener("close", function (_ref2) { | ||
var code = _ref2.code, | ||
reason = _ref2.reason; | ||
if (_this4.ready) | ||
// Delay close event until internal state is updated | ||
setTimeout(function () { | ||
return _this4.emit("close", code, reason); | ||
}, 0); | ||
_this4.ready = false; | ||
_this4.socket = undefined; | ||
if (code === 1000) return; | ||
_this4.current_reconnects++; | ||
if (_this4.reconnect && (_this4.max_reconnects > _this4.current_reconnects || _this4.max_reconnects === 0)) _this4.reconnect_timer_id = setTimeout(function () { | ||
return _this4._connect(address, options); | ||
}, _this4.reconnect_interval); | ||
}); | ||
_connect(address, options) { | ||
clearTimeout(this.reconnect_timer_id); | ||
this.socket = this.webSocketFactory(address, options); | ||
this.socket.addEventListener("open", () => { | ||
this.ready = true; | ||
this.emit("open"); | ||
this.current_reconnects = 0; | ||
}); | ||
this.socket.addEventListener("message", ({ data: message }) => { | ||
if (message instanceof ArrayBuffer) | ||
message = Buffer.from(message).toString(); | ||
try { | ||
message = this.dataPack.decode(message); | ||
} | ||
catch (error) { | ||
return; | ||
} | ||
// check if any listeners are attached and forward event | ||
if (message.notification && this.listeners(message.notification).length) { | ||
if (!Object.keys(message.params).length) | ||
return this.emit(message.notification); | ||
const args = [message.notification]; | ||
if (message.params.constructor === Object) | ||
args.push(message.params); | ||
else | ||
// using for-loop instead of unshift/spread because performance is better | ||
for (let i = 0; i < message.params.length; i++) | ||
args.push(message.params[i]); | ||
// run as microtask so that pending queue messages are resolved first | ||
// eslint-disable-next-line prefer-spread | ||
return Promise.resolve().then(() => { this.emit.apply(this, args); }); | ||
} | ||
if (!this.queue[message.id]) { | ||
// general JSON RPC 2.0 events | ||
if (message.method) { | ||
// run as microtask so that pending queue messages are resolved first | ||
return Promise.resolve().then(() => { | ||
this.emit(message.method, message?.params); | ||
}); | ||
} | ||
return; | ||
} | ||
// reject early since server's response is invalid | ||
if ("error" in message === "result" in message) | ||
this.queue[message.id].promise[1](new Error("Server response malformed. Response must include either \"result\"" + | ||
" or \"error\", but not both.")); | ||
if (this.queue[message.id].timeout) | ||
clearTimeout(this.queue[message.id].timeout); | ||
if (message.error) | ||
this.queue[message.id].promise[1](message.error); | ||
else | ||
this.queue[message.id].promise[0](message.result); | ||
delete this.queue[message.id]; | ||
}); | ||
this.socket.addEventListener("error", (error) => this.emit("error", error)); | ||
this.socket.addEventListener("close", ({ code, reason }) => { | ||
if (this.ready) // Delay close event until internal state is updated | ||
setTimeout(() => this.emit("close", code, reason), 0); | ||
this.ready = false; | ||
this.socket = undefined; | ||
if (code === 1000) | ||
return; | ||
this.current_reconnects++; | ||
if (this.reconnect && ((this.max_reconnects > this.current_reconnects) || | ||
this.max_reconnects === 0)) | ||
this.reconnect_timer_id = setTimeout(() => this._connect(address, options), this.reconnect_interval); | ||
}); | ||
} | ||
}]); | ||
}(_eventemitter.EventEmitter); | ||
} | ||
exports.default = CommonClient; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
Object.defineProperty(exports, "__esModule", { value: true }); |
@@ -6,64 +6,42 @@ /** | ||
"use strict"; | ||
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
exports["default"] = _default; | ||
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); | ||
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); | ||
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); | ||
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); | ||
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); | ||
var _eventemitter = require("eventemitter3"); | ||
function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2["default"])(o), (0, _possibleConstructorReturn2["default"])(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2["default"])(t).constructor) : o.apply(t, e)); } | ||
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); } | ||
var WebSocketBrowserImpl = /*#__PURE__*/function (_EventEmitter) { | ||
/** Instantiate a WebSocket class | ||
* @constructor | ||
* @param {String} address - url to a websocket server | ||
* @param {(Object)} options - websocket options | ||
* @param {(String|Array)} protocols - a list of protocols | ||
* @return {WebSocketBrowserImpl} - returns a WebSocket instance | ||
*/ | ||
function WebSocketBrowserImpl(address, options, protocols) { | ||
var _this; | ||
(0, _classCallCheck2["default"])(this, WebSocketBrowserImpl); | ||
_this = _callSuper(this, WebSocketBrowserImpl); | ||
_this.socket = new window.WebSocket(address, protocols); | ||
_this.socket.onopen = function () { | ||
return _this.emit("open"); | ||
}; | ||
_this.socket.onmessage = function (event) { | ||
return _this.emit("message", event.data); | ||
}; | ||
_this.socket.onerror = function (error) { | ||
return _this.emit("error", error); | ||
}; | ||
_this.socket.onclose = function (event) { | ||
_this.emit("close", event.code, event.reason); | ||
}; | ||
return _this; | ||
} | ||
/** | ||
* Sends data through a websocket connection | ||
* @method | ||
* @param {(String|Object)} data - data to be sent via websocket | ||
* @param {Object} optionsOrCallback - ws options | ||
* @param {Function} callback - a callback called once the data is sent | ||
* @return {Undefined} | ||
*/ | ||
(0, _inherits2["default"])(WebSocketBrowserImpl, _EventEmitter); | ||
return (0, _createClass2["default"])(WebSocketBrowserImpl, [{ | ||
key: "send", | ||
value: function send(data, optionsOrCallback, callback) { | ||
var cb = callback || optionsOrCallback; | ||
try { | ||
this.socket.send(data); | ||
cb(); | ||
} catch (error) { | ||
cb(error); | ||
} | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const eventemitter3_1 = require("eventemitter3"); | ||
class WebSocketBrowserImpl extends eventemitter3_1.EventEmitter { | ||
socket; | ||
/** Instantiate a WebSocket class | ||
* @constructor | ||
* @param {String} address - url to a websocket server | ||
* @param {(Object)} options - websocket options | ||
* @param {(String|Array)} protocols - a list of protocols | ||
* @return {WebSocketBrowserImpl} - returns a WebSocket instance | ||
*/ | ||
constructor(address, options, protocols) { | ||
super(); | ||
this.socket = new window.WebSocket(address, protocols); | ||
this.socket.onopen = () => this.emit("open"); | ||
this.socket.onmessage = (event) => this.emit("message", event.data); | ||
this.socket.onerror = (error) => this.emit("error", error); | ||
this.socket.onclose = (event) => { | ||
this.emit("close", event.code, event.reason); | ||
}; | ||
} | ||
/** | ||
* Sends data through a websocket connection | ||
* @method | ||
* @param {(String|Object)} data - data to be sent via websocket | ||
* @param {Object} optionsOrCallback - ws options | ||
* @param {Function} callback - a callback called once the data is sent | ||
* @return {Undefined} | ||
*/ | ||
send(data, optionsOrCallback, callback) { | ||
const cb = callback || optionsOrCallback; | ||
try { | ||
this.socket.send(data); | ||
cb(); | ||
} | ||
catch (error) { | ||
cb(error); | ||
} | ||
} | ||
/** | ||
* Closes an underlying socket | ||
@@ -76,14 +54,9 @@ * @method | ||
*/ | ||
}, { | ||
key: "close", | ||
value: function close(code, reason) { | ||
this.socket.close(code, reason); | ||
close(code, reason) { | ||
this.socket.close(code, reason); | ||
} | ||
}, { | ||
key: "addEventListener", | ||
value: function addEventListener(type, listener, options) { | ||
this.socket.addEventListener(type, listener, options); | ||
addEventListener(type, listener, options) { | ||
this.socket.addEventListener(type, listener, options); | ||
} | ||
}]); | ||
}(_eventemitter.EventEmitter); | ||
} | ||
/** | ||
@@ -96,4 +69,5 @@ * factory method for common WebSocket instance | ||
*/ | ||
function _default(address, options) { | ||
return new WebSocketBrowserImpl(address, options); | ||
} | ||
function default_1(address, options) { | ||
return new WebSocketBrowserImpl(address, options); | ||
} | ||
exports.default = default_1; |
/* A wrapper for the "qaap/uws-bindings" library. */ | ||
"use strict"; | ||
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
exports["default"] = _default; | ||
var _ws = _interopRequireDefault(require("ws")); | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const ws_1 = __importDefault(require("ws")); | ||
/** | ||
@@ -17,4 +15,5 @@ * factory method for common WebSocket instance | ||
*/ | ||
function _default(address, options) { | ||
return new _ws["default"](address, options); | ||
} | ||
function default_1(address, options) { | ||
return new ws_1.default(address, options); | ||
} | ||
exports.default = default_1; |
@@ -6,122 +6,118 @@ /** | ||
"use strict"; | ||
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 __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
// @ts-ignore | ||
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); | ||
var _typeof3 = require("@babel/runtime/helpers/typeof"); | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
exports["default"] = void 0; | ||
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator")); | ||
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof")); | ||
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator")); | ||
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); | ||
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray")); | ||
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); | ||
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); | ||
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); | ||
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); | ||
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); | ||
var _eventemitter = require("eventemitter3"); | ||
var _ws = require("ws"); | ||
var _uuid = require("uuid"); | ||
var _url = _interopRequireDefault(require("url")); | ||
var utils = _interopRequireWildcard(require("./utils")); | ||
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); } | ||
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof3(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; } | ||
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; } | ||
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } | ||
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; } | ||
function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2["default"])(o), (0, _possibleConstructorReturn2["default"])(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2["default"])(t).constructor) : o.apply(t, e)); } | ||
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); } | ||
var Server = exports["default"] = /*#__PURE__*/function (_EventEmitter) { | ||
/** | ||
* Instantiate a Server class. | ||
* @constructor | ||
* @param {Object} options - ws constructor's parameters with rpc | ||
* @param {DataPack} dataPack - data pack contains encoder and decoder | ||
* @return {Server} - returns a new Server instance | ||
*/ | ||
function Server(options, dataPack) { | ||
var _this; | ||
(0, _classCallCheck2["default"])(this, Server); | ||
_this = _callSuper(this, Server); | ||
const eventemitter3_1 = require("eventemitter3"); | ||
const ws_1 = require("ws"); | ||
const uuid_1 = require("uuid"); | ||
const url_1 = __importDefault(require("url")); | ||
const utils = __importStar(require("./utils")); | ||
class Server extends eventemitter3_1.EventEmitter { | ||
namespaces; | ||
dataPack; | ||
wss; | ||
/** | ||
* Stores all connected sockets with a universally unique identifier | ||
* in the appropriate namespace. | ||
* Stores all rpc methods to specific namespaces. "/" by default. | ||
* Stores all events as keys and subscribed users in array as value | ||
* @private | ||
* @name namespaces | ||
* @param {Object} namespaces.rpc_methods | ||
* @param {Map} namespaces.clients | ||
* @param {Object} namespaces.events | ||
* Instantiate a Server class. | ||
* @constructor | ||
* @param {Object} options - ws constructor's parameters with rpc | ||
* @param {DataPack} dataPack - data pack contains encoder and decoder | ||
* @return {Server} - returns a new Server instance | ||
*/ | ||
_this.namespaces = {}; | ||
if (!dataPack) _this.dataPack = new utils.DefaultDataPack();else _this.dataPack = dataPack; | ||
_this.wss = new _ws.Server(options); | ||
_this.wss.on("listening", function () { | ||
return _this.emit("listening"); | ||
}); | ||
_this.wss.on("connection", function (socket, request) { | ||
var u = _url["default"].parse(request.url, true); | ||
var ns = u.pathname; | ||
if (u.query.socket_id) socket._id = u.query.socket_id;else socket._id = (0, _uuid.v1)(); | ||
// unauthenticated by default | ||
socket["_authenticated"] = false; | ||
// propagate socket errors | ||
socket.on("error", function (error) { | ||
return _this.emit("socket-error", socket, error); | ||
}); | ||
// cleanup after the socket gets disconnected | ||
socket.on("close", function () { | ||
_this.namespaces[ns].clients["delete"](socket._id); | ||
for (var _i = 0, _Object$keys = Object.keys(_this.namespaces[ns].events); _i < _Object$keys.length; _i++) { | ||
var event = _Object$keys[_i]; | ||
var index = _this.namespaces[ns].events[event].sockets.indexOf(socket._id); | ||
if (index >= 0) _this.namespaces[ns].events[event].sockets.splice(index, 1); | ||
} | ||
_this.emit("disconnection", socket); | ||
}); | ||
if (!_this.namespaces[ns]) _this._generateNamespace(ns); | ||
// store socket and method | ||
_this.namespaces[ns].clients.set(socket._id, socket); | ||
_this.emit("connection", socket, request); | ||
return _this._handleRPC(socket, ns); | ||
}); | ||
_this.wss.on("error", function (error) { | ||
return _this.emit("error", error); | ||
}); | ||
return _this; | ||
} | ||
/** | ||
* Registers an RPC method. | ||
* @method | ||
* @param {String} name - method name | ||
* @param {Function} fn - a callee function | ||
* @param {String} ns - namespace identifier | ||
* @throws {TypeError} | ||
* @return {Object} - returns an IMethod object | ||
*/ | ||
(0, _inherits2["default"])(Server, _EventEmitter); | ||
return (0, _createClass2["default"])(Server, [{ | ||
key: "register", | ||
value: function register(name, fn) { | ||
var _this2 = this; | ||
var ns = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : "/"; | ||
if (!this.namespaces[ns]) this._generateNamespace(ns); | ||
this.namespaces[ns].rpc_methods[name] = { | ||
fn: fn, | ||
"protected": false | ||
}; | ||
return { | ||
"protected": function _protected() { | ||
return _this2._makeProtectedMethod(name, ns); | ||
}, | ||
"public": function _public() { | ||
return _this2._makePublicMethod(name, ns); | ||
} | ||
}; | ||
constructor(options, dataPack) { | ||
super(); | ||
/** | ||
* Stores all connected sockets with a universally unique identifier | ||
* in the appropriate namespace. | ||
* Stores all rpc methods to specific namespaces. "/" by default. | ||
* Stores all events as keys and subscribed users in array as value | ||
* @private | ||
* @name namespaces | ||
* @param {Object} namespaces.rpc_methods | ||
* @param {Map} namespaces.clients | ||
* @param {Object} namespaces.events | ||
*/ | ||
this.namespaces = {}; | ||
if (!dataPack) | ||
this.dataPack = new utils.DefaultDataPack(); | ||
else | ||
this.dataPack = dataPack; | ||
this.wss = new ws_1.Server(options); | ||
this.wss.on("listening", () => this.emit("listening")); | ||
this.wss.on("connection", (socket, request) => { | ||
const u = url_1.default.parse(request.url, true); | ||
const ns = u.pathname; | ||
if (u.query.socket_id) | ||
socket._id = u.query.socket_id; | ||
else | ||
socket._id = (0, uuid_1.v1)(); | ||
// unauthenticated by default | ||
socket["_authenticated"] = false; | ||
// propagate socket errors | ||
socket.on("error", (error) => this.emit("socket-error", socket, error)); | ||
// cleanup after the socket gets disconnected | ||
socket.on("close", () => { | ||
this.namespaces[ns].clients.delete(socket._id); | ||
for (const event of Object.keys(this.namespaces[ns].events)) { | ||
const index = this.namespaces[ns].events[event].sockets.indexOf(socket._id); | ||
if (index >= 0) | ||
this.namespaces[ns].events[event].sockets.splice(index, 1); | ||
} | ||
this.emit("disconnection", socket); | ||
}); | ||
if (!this.namespaces[ns]) | ||
this._generateNamespace(ns); | ||
// store socket and method | ||
this.namespaces[ns].clients.set(socket._id, socket); | ||
this.emit("connection", socket, request); | ||
return this._handleRPC(socket, ns); | ||
}); | ||
this.wss.on("error", (error) => this.emit("error", error)); | ||
} | ||
/** | ||
* Registers an RPC method. | ||
* @method | ||
* @param {String} name - method name | ||
* @param {Function} fn - a callee function | ||
* @param {String} ns - namespace identifier | ||
* @throws {TypeError} | ||
* @return {Object} - returns an IMethod object | ||
*/ | ||
register(name, fn, ns = "/") { | ||
if (!this.namespaces[ns]) | ||
this._generateNamespace(ns); | ||
this.namespaces[ns].rpc_methods[name] = { | ||
fn: fn, | ||
protected: false | ||
}; | ||
return { | ||
protected: () => this._makeProtectedMethod(name, ns), | ||
public: () => this._makePublicMethod(name, ns) | ||
}; | ||
} | ||
/** | ||
* Sets an auth method. | ||
@@ -134,7 +130,4 @@ * @method | ||
*/ | ||
}, { | ||
key: "setAuth", | ||
value: function setAuth(fn) { | ||
var ns = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "/"; | ||
this.register("rpc.login", fn, ns); | ||
setAuth(fn, ns = "/") { | ||
this.register("rpc.login", fn, ns); | ||
} | ||
@@ -148,7 +141,4 @@ /** | ||
*/ | ||
}, { | ||
key: "_makeProtectedMethod", | ||
value: function _makeProtectedMethod(name) { | ||
var ns = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "/"; | ||
this.namespaces[ns].rpc_methods[name]["protected"] = true; | ||
_makeProtectedMethod(name, ns = "/") { | ||
this.namespaces[ns].rpc_methods[name].protected = true; | ||
} | ||
@@ -162,7 +152,4 @@ /** | ||
*/ | ||
}, { | ||
key: "_makePublicMethod", | ||
value: function _makePublicMethod(name) { | ||
var ns = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "/"; | ||
this.namespaces[ns].rpc_methods[name]["protected"] = false; | ||
_makePublicMethod(name, ns = "/") { | ||
this.namespaces[ns].rpc_methods[name].protected = false; | ||
} | ||
@@ -176,7 +163,4 @@ /** | ||
*/ | ||
}, { | ||
key: "_makeProtectedEvent", | ||
value: function _makeProtectedEvent(name) { | ||
var ns = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "/"; | ||
this.namespaces[ns].events[name]["protected"] = true; | ||
_makeProtectedEvent(name, ns = "/") { | ||
this.namespaces[ns].events[name].protected = true; | ||
} | ||
@@ -190,7 +174,4 @@ /** | ||
*/ | ||
}, { | ||
key: "_makePublicEvent", | ||
value: function _makePublicEvent(name) { | ||
var ns = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "/"; | ||
this.namespaces[ns].events[name]["protected"] = false; | ||
_makePublicEvent(name, ns = "/") { | ||
this.namespaces[ns].events[name].protected = false; | ||
} | ||
@@ -204,23 +185,11 @@ /** | ||
*/ | ||
}, { | ||
key: "closeNamespace", | ||
value: function closeNamespace(ns) { | ||
var namespace = this.namespaces[ns]; | ||
if (namespace) { | ||
delete namespace.rpc_methods; | ||
delete namespace.events; | ||
var _iterator = _createForOfIteratorHelper(namespace.clients.values()), | ||
_step; | ||
try { | ||
for (_iterator.s(); !(_step = _iterator.n()).done;) { | ||
var socket = _step.value; | ||
socket.close(); | ||
} | ||
} catch (err) { | ||
_iterator.e(err); | ||
} finally { | ||
_iterator.f(); | ||
closeNamespace(ns) { | ||
const namespace = this.namespaces[ns]; | ||
if (namespace) { | ||
delete namespace.rpc_methods; | ||
delete namespace.events; | ||
for (const socket of namespace.clients.values()) | ||
socket.close(); | ||
delete this.namespaces[ns]; | ||
} | ||
delete this.namespaces[ns]; | ||
} | ||
} | ||
@@ -235,48 +204,33 @@ /** | ||
*/ | ||
}, { | ||
key: "event", | ||
value: function event(name) { | ||
var _this3 = this; | ||
var ns = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "/"; | ||
if (!this.namespaces[ns]) this._generateNamespace(ns);else { | ||
var index = this.namespaces[ns].events[name]; | ||
if (index !== undefined) throw new Error("Already registered event ".concat(ns).concat(name)); | ||
} | ||
this.namespaces[ns].events[name] = { | ||
sockets: [], | ||
"protected": false | ||
}; | ||
// forward emitted event to subscribers | ||
this.on(name, function () { | ||
for (var _len = arguments.length, params = new Array(_len), _key = 0; _key < _len; _key++) { | ||
params[_key] = arguments[_key]; | ||
event(name, ns = "/") { | ||
if (!this.namespaces[ns]) | ||
this._generateNamespace(ns); | ||
else { | ||
const index = this.namespaces[ns].events[name]; | ||
if (index !== undefined) | ||
throw new Error(`Already registered event ${ns}${name}`); | ||
} | ||
// flatten an object if no spreading is wanted | ||
if (params.length === 1 && params[0] instanceof Object) params = params[0]; | ||
var _iterator2 = _createForOfIteratorHelper(_this3.namespaces[ns].events[name].sockets), | ||
_step2; | ||
try { | ||
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { | ||
var socket_id = _step2.value; | ||
var socket = _this3.namespaces[ns].clients.get(socket_id); | ||
if (!socket) continue; | ||
socket.send(_this3.dataPack.encode({ | ||
notification: name, | ||
params: params | ||
})); | ||
} | ||
} catch (err) { | ||
_iterator2.e(err); | ||
} finally { | ||
_iterator2.f(); | ||
} | ||
}); | ||
return { | ||
"protected": function _protected() { | ||
return _this3._makeProtectedEvent(name, ns); | ||
}, | ||
"public": function _public() { | ||
return _this3._makePublicEvent(name, ns); | ||
} | ||
}; | ||
this.namespaces[ns].events[name] = { | ||
sockets: [], | ||
protected: false | ||
}; | ||
// forward emitted event to subscribers | ||
this.on(name, (...params) => { | ||
// flatten an object if no spreading is wanted | ||
if (params.length === 1 && params[0] instanceof Object) | ||
params = params[0]; | ||
for (const socket_id of this.namespaces[ns].events[name].sockets) { | ||
const socket = this.namespaces[ns].clients.get(socket_id); | ||
if (!socket) | ||
continue; | ||
socket.send(this.dataPack.encode({ | ||
notification: name, | ||
params | ||
})); | ||
} | ||
}); | ||
return { | ||
protected: () => this._makeProtectedEvent(name, ns), | ||
public: () => this._makePublicEvent(name, ns) | ||
}; | ||
} | ||
@@ -290,77 +244,79 @@ /** | ||
*/ | ||
}, { | ||
key: "of", | ||
value: function of(name) { | ||
if (!this.namespaces[name]) this._generateNamespace(name); | ||
var self = this; | ||
return { | ||
// self.register convenience method | ||
register: function register(fn_name, fn) { | ||
if (arguments.length !== 2) throw new Error("must provide exactly two arguments"); | ||
if (typeof fn_name !== "string") throw new Error("name must be a string"); | ||
if (typeof fn !== "function") throw new Error("handler must be a function"); | ||
return self.register(fn_name, fn, name); | ||
}, | ||
// self.event convenience method | ||
event: function event(ev_name) { | ||
if (arguments.length !== 1) throw new Error("must provide exactly one argument"); | ||
if (typeof ev_name !== "string") throw new Error("name must be a string"); | ||
return self.event(ev_name, name); | ||
}, | ||
// self.eventList convenience method | ||
get eventList() { | ||
return Object.keys(self.namespaces[name].events); | ||
}, | ||
/** | ||
* Emits a specified event to this namespace. | ||
* @inner | ||
* @method | ||
* @param {String} event - event name | ||
* @param {Array} params - event parameters | ||
* @return {Undefined} | ||
*/ | ||
emit: function emit(event) { | ||
var socket_ids = (0, _toConsumableArray2["default"])(self.namespaces[name].clients.keys()); | ||
for (var _len2 = arguments.length, params = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { | ||
params[_key2 - 1] = arguments[_key2]; | ||
} | ||
for (var i = 0, id; id = socket_ids[i]; ++i) { | ||
self.namespaces[name].clients.get(id).send(self.dataPack.encode({ | ||
notification: event, | ||
params: params || [] | ||
})); | ||
} | ||
}, | ||
/** | ||
* Returns a name of this namespace. | ||
* @inner | ||
* @method | ||
* @kind constant | ||
* @return {String} | ||
*/ | ||
get name() { | ||
return name; | ||
}, | ||
/** | ||
* Returns a hash of websocket objects connected to this namespace. | ||
* @inner | ||
* @method | ||
* @return {Object} | ||
*/ | ||
connected: function connected() { | ||
var socket_ids = (0, _toConsumableArray2["default"])(self.namespaces[name].clients.keys()); | ||
return socket_ids.reduce(function (acc, curr) { | ||
return Object.assign(Object.assign({}, acc), (0, _defineProperty2["default"])({}, curr, self.namespaces[name].clients.get(curr))); | ||
}, {}); | ||
}, | ||
/** | ||
* Returns a list of client unique identifiers connected to this namespace. | ||
* @inner | ||
* @method | ||
* @return {Array} | ||
*/ | ||
clients: function clients() { | ||
return self.namespaces[name]; | ||
} | ||
}; | ||
of(name) { | ||
if (!this.namespaces[name]) | ||
this._generateNamespace(name); | ||
const self = this; | ||
return { | ||
// self.register convenience method | ||
register(fn_name, fn) { | ||
if (arguments.length !== 2) | ||
throw new Error("must provide exactly two arguments"); | ||
if (typeof fn_name !== "string") | ||
throw new Error("name must be a string"); | ||
if (typeof fn !== "function") | ||
throw new Error("handler must be a function"); | ||
return self.register(fn_name, fn, name); | ||
}, | ||
// self.event convenience method | ||
event(ev_name) { | ||
if (arguments.length !== 1) | ||
throw new Error("must provide exactly one argument"); | ||
if (typeof ev_name !== "string") | ||
throw new Error("name must be a string"); | ||
return self.event(ev_name, name); | ||
}, | ||
// self.eventList convenience method | ||
get eventList() { | ||
return Object.keys(self.namespaces[name].events); | ||
}, | ||
/** | ||
* Emits a specified event to this namespace. | ||
* @inner | ||
* @method | ||
* @param {String} event - event name | ||
* @param {Array} params - event parameters | ||
* @return {Undefined} | ||
*/ | ||
emit(event, ...params) { | ||
const socket_ids = [...self.namespaces[name].clients.keys()]; | ||
for (let i = 0, id; id = socket_ids[i]; ++i) { | ||
self.namespaces[name].clients.get(id).send(self.dataPack.encode({ | ||
notification: event, | ||
params: params || [] | ||
})); | ||
} | ||
}, | ||
/** | ||
* Returns a name of this namespace. | ||
* @inner | ||
* @method | ||
* @kind constant | ||
* @return {String} | ||
*/ | ||
get name() { | ||
return name; | ||
}, | ||
/** | ||
* Returns a hash of websocket objects connected to this namespace. | ||
* @inner | ||
* @method | ||
* @return {Object} | ||
*/ | ||
connected() { | ||
const socket_ids = [...self.namespaces[name].clients.keys()]; | ||
return socket_ids.reduce((acc, curr) => ({ | ||
...acc, | ||
[curr]: self.namespaces[name].clients.get(curr) | ||
}), {}); | ||
}, | ||
/** | ||
* Returns a list of client unique identifiers connected to this namespace. | ||
* @inner | ||
* @method | ||
* @return {Array} | ||
*/ | ||
clients() { | ||
return self.namespaces[name]; | ||
} | ||
}; | ||
} | ||
@@ -374,8 +330,6 @@ /** | ||
*/ | ||
}, { | ||
key: "eventList", | ||
value: function eventList() { | ||
var ns = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "/"; | ||
if (!this.namespaces[ns]) return []; | ||
return Object.keys(this.namespaces[ns].events); | ||
eventList(ns = "/") { | ||
if (!this.namespaces[ns]) | ||
return []; | ||
return Object.keys(this.namespaces[ns].events); | ||
} | ||
@@ -390,10 +344,8 @@ /** | ||
*/ | ||
}, { | ||
key: "createError", | ||
value: function createError(code, message, data) { | ||
return { | ||
code: code, | ||
message: message, | ||
data: data || null | ||
}; | ||
createError(code, message, data) { | ||
return { | ||
code: code, | ||
message: message, | ||
data: data || null | ||
}; | ||
} | ||
@@ -405,15 +357,13 @@ /** | ||
*/ | ||
}, { | ||
key: "close", | ||
value: function close() { | ||
var _this4 = this; | ||
return new Promise(function (resolve, reject) { | ||
try { | ||
_this4.wss.close(); | ||
_this4.emit("close"); | ||
resolve(); | ||
} catch (error) { | ||
reject(error); | ||
} | ||
}); | ||
close() { | ||
return new Promise((resolve, reject) => { | ||
try { | ||
this.wss.close(); | ||
this.emit("close"); | ||
resolve(); | ||
} | ||
catch (error) { | ||
reject(error); | ||
} | ||
}); | ||
} | ||
@@ -427,116 +377,45 @@ /** | ||
*/ | ||
}, { | ||
key: "_handleRPC", | ||
value: function _handleRPC(socket) { | ||
var _this5 = this; | ||
var ns = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "/"; | ||
socket.on("message", /*#__PURE__*/function () { | ||
var _ref = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee(data) { | ||
var msg_options, parsedData, responses, _iterator3, _step3, message, _response, response; | ||
return _regenerator["default"].wrap(function _callee$(_context) { | ||
while (1) switch (_context.prev = _context.next) { | ||
case 0: | ||
msg_options = {}; | ||
if (data instanceof ArrayBuffer) { | ||
msg_options.binary = true; | ||
data = Buffer.from(data).toString(); | ||
_handleRPC(socket, ns = "/") { | ||
socket.on("message", async (data) => { | ||
const msg_options = {}; | ||
if (data instanceof ArrayBuffer) { | ||
msg_options.binary = true; | ||
data = Buffer.from(data).toString(); | ||
} | ||
if (socket.readyState !== 1) | ||
return; // TODO: should have debug logs here | ||
let parsedData; | ||
try { | ||
parsedData = this.dataPack.decode(data); | ||
} | ||
catch (error) { | ||
return socket.send(this.dataPack.encode({ | ||
jsonrpc: "2.0", | ||
error: utils.createError(-32700, error.toString()), | ||
id: null | ||
}), msg_options); | ||
} | ||
if (Array.isArray(parsedData)) { | ||
if (!parsedData.length) | ||
return socket.send(this.dataPack.encode({ | ||
jsonrpc: "2.0", | ||
error: utils.createError(-32600, "Invalid array"), | ||
id: null | ||
}), msg_options); | ||
const responses = []; | ||
for (const message of parsedData) { | ||
const response = await this._runMethod(message, socket._id, ns); | ||
if (!response) | ||
continue; | ||
responses.push(response); | ||
} | ||
if (!(socket.readyState !== 1)) { | ||
_context.next = 4; | ||
break; | ||
} | ||
return _context.abrupt("return"); | ||
case 4: | ||
_context.prev = 4; | ||
parsedData = _this5.dataPack.decode(data); | ||
_context.next = 11; | ||
break; | ||
case 8: | ||
_context.prev = 8; | ||
_context.t0 = _context["catch"](4); | ||
return _context.abrupt("return", socket.send(_this5.dataPack.encode({ | ||
jsonrpc: "2.0", | ||
error: utils.createError(-32700, _context.t0.toString()), | ||
id: null | ||
}), msg_options)); | ||
case 11: | ||
if (!Array.isArray(parsedData)) { | ||
_context.next = 39; | ||
break; | ||
} | ||
if (parsedData.length) { | ||
_context.next = 14; | ||
break; | ||
} | ||
return _context.abrupt("return", socket.send(_this5.dataPack.encode({ | ||
jsonrpc: "2.0", | ||
error: utils.createError(-32600, "Invalid array"), | ||
id: null | ||
}), msg_options)); | ||
case 14: | ||
responses = []; | ||
_iterator3 = _createForOfIteratorHelper(parsedData); | ||
_context.prev = 16; | ||
_iterator3.s(); | ||
case 18: | ||
if ((_step3 = _iterator3.n()).done) { | ||
_context.next = 28; | ||
break; | ||
} | ||
message = _step3.value; | ||
_context.next = 22; | ||
return _this5._runMethod(message, socket._id, ns); | ||
case 22: | ||
_response = _context.sent; | ||
if (_response) { | ||
_context.next = 25; | ||
break; | ||
} | ||
return _context.abrupt("continue", 26); | ||
case 25: | ||
responses.push(_response); | ||
case 26: | ||
_context.next = 18; | ||
break; | ||
case 28: | ||
_context.next = 33; | ||
break; | ||
case 30: | ||
_context.prev = 30; | ||
_context.t1 = _context["catch"](16); | ||
_iterator3.e(_context.t1); | ||
case 33: | ||
_context.prev = 33; | ||
_iterator3.f(); | ||
return _context.finish(33); | ||
case 36: | ||
if (responses.length) { | ||
_context.next = 38; | ||
break; | ||
} | ||
return _context.abrupt("return"); | ||
case 38: | ||
return _context.abrupt("return", socket.send(_this5.dataPack.encode(responses), msg_options)); | ||
case 39: | ||
_context.next = 41; | ||
return _this5._runMethod(parsedData, socket._id, ns); | ||
case 41: | ||
response = _context.sent; | ||
if (response) { | ||
_context.next = 44; | ||
break; | ||
} | ||
return _context.abrupt("return"); | ||
case 44: | ||
return _context.abrupt("return", socket.send(_this5.dataPack.encode(response), msg_options)); | ||
case 45: | ||
case "end": | ||
return _context.stop(); | ||
if (!responses.length) | ||
return; | ||
return socket.send(this.dataPack.encode(responses), msg_options); | ||
} | ||
}, _callee, null, [[4, 8], [16, 30, 33, 36]]); | ||
})); | ||
return function (_x) { | ||
return _ref.apply(this, arguments); | ||
}; | ||
}()); | ||
const response = await this._runMethod(parsedData, socket._id, ns); | ||
if (!response) | ||
return; | ||
return socket.send(this.dataPack.encode(response), msg_options); | ||
}); | ||
} | ||
@@ -551,313 +430,162 @@ /** | ||
*/ | ||
}, { | ||
key: "_runMethod", | ||
value: (function () { | ||
var _runMethod2 = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee2(message, socket_id) { | ||
var ns, | ||
results, | ||
event_names, | ||
_iterator4, | ||
_step4, | ||
name, | ||
index, | ||
namespace, | ||
socket_index, | ||
_results, | ||
_iterator5, | ||
_step5, | ||
_name, | ||
_index, | ||
response, | ||
s, | ||
_args2 = arguments; | ||
return _regenerator["default"].wrap(function _callee2$(_context2) { | ||
while (1) switch (_context2.prev = _context2.next) { | ||
case 0: | ||
ns = _args2.length > 2 && _args2[2] !== undefined ? _args2[2] : "/"; | ||
if (!((0, _typeof2["default"])(message) !== "object" || message === null)) { | ||
_context2.next = 3; | ||
break; | ||
} | ||
return _context2.abrupt("return", { | ||
async _runMethod(message, socket_id, ns = "/") { | ||
if (typeof message !== "object" || message === null) | ||
return { | ||
jsonrpc: "2.0", | ||
error: utils.createError(-32600), | ||
id: null | ||
}); | ||
case 3: | ||
if (!(message.jsonrpc !== "2.0")) { | ||
_context2.next = 5; | ||
break; | ||
} | ||
return _context2.abrupt("return", { | ||
}; | ||
if (message.jsonrpc !== "2.0") | ||
return { | ||
jsonrpc: "2.0", | ||
error: utils.createError(-32600, "Invalid JSON RPC version"), | ||
id: message.id || null | ||
}); | ||
case 5: | ||
if (message.method) { | ||
_context2.next = 7; | ||
break; | ||
} | ||
return _context2.abrupt("return", { | ||
}; | ||
if (!message.method) | ||
return { | ||
jsonrpc: "2.0", | ||
error: utils.createError(-32602, "Method not specified"), | ||
id: message.id || null | ||
}); | ||
case 7: | ||
if (!(typeof message.method !== "string")) { | ||
_context2.next = 9; | ||
break; | ||
} | ||
return _context2.abrupt("return", { | ||
}; | ||
if (typeof message.method !== "string") | ||
return { | ||
jsonrpc: "2.0", | ||
error: utils.createError(-32600, "Invalid method name"), | ||
id: message.id || null | ||
}); | ||
case 9: | ||
if (!(message.params && typeof message.params === "string")) { | ||
_context2.next = 11; | ||
break; | ||
} | ||
return _context2.abrupt("return", { | ||
}; | ||
if (message.params && typeof message.params === "string") | ||
return { | ||
jsonrpc: "2.0", | ||
error: utils.createError(-32600), | ||
id: message.id || null | ||
}); | ||
case 11: | ||
if (!(message.method === "rpc.on")) { | ||
_context2.next = 47; | ||
break; | ||
} | ||
if (message.params) { | ||
_context2.next = 14; | ||
break; | ||
} | ||
return _context2.abrupt("return", { | ||
}; | ||
if (message.method === "rpc.on") { | ||
if (!message.params) | ||
return { | ||
jsonrpc: "2.0", | ||
error: utils.createError(-32000), | ||
id: message.id || null | ||
}; | ||
const results = {}; | ||
const event_names = Object.keys(this.namespaces[ns].events); | ||
for (const name of message.params) { | ||
const index = event_names.indexOf(name); | ||
const namespace = this.namespaces[ns]; | ||
if (index === -1) { | ||
results[name] = "provided event invalid"; | ||
continue; | ||
} | ||
// reject request if event is protected and if client is not authenticated | ||
if (namespace.events[event_names[index]].protected === true && | ||
namespace.clients.get(socket_id)["_authenticated"] === false) { | ||
return { | ||
jsonrpc: "2.0", | ||
error: utils.createError(-32606), | ||
id: message.id || null | ||
}; | ||
} | ||
const socket_index = namespace.events[event_names[index]].sockets.indexOf(socket_id); | ||
if (socket_index >= 0) { | ||
results[name] = "socket has already been subscribed to event"; | ||
continue; | ||
} | ||
namespace.events[event_names[index]].sockets.push(socket_id); | ||
results[name] = "ok"; | ||
} | ||
return { | ||
jsonrpc: "2.0", | ||
error: utils.createError(-32000), | ||
result: results, | ||
id: message.id || null | ||
}); | ||
case 14: | ||
results = {}; | ||
event_names = Object.keys(this.namespaces[ns].events); | ||
_iterator4 = _createForOfIteratorHelper(message.params); | ||
_context2.prev = 17; | ||
_iterator4.s(); | ||
case 19: | ||
if ((_step4 = _iterator4.n()).done) { | ||
_context2.next = 36; | ||
break; | ||
} | ||
name = _step4.value; | ||
index = event_names.indexOf(name); | ||
namespace = this.namespaces[ns]; | ||
if (!(index === -1)) { | ||
_context2.next = 26; | ||
break; | ||
} | ||
results[name] = "provided event invalid"; | ||
return _context2.abrupt("continue", 34); | ||
case 26: | ||
if (!(namespace.events[event_names[index]]["protected"] === true && namespace.clients.get(socket_id)["_authenticated"] === false)) { | ||
_context2.next = 28; | ||
break; | ||
} | ||
return _context2.abrupt("return", { | ||
}; | ||
} | ||
else if (message.method === "rpc.off") { | ||
if (!message.params) | ||
return { | ||
jsonrpc: "2.0", | ||
error: utils.createError(-32000), | ||
id: message.id || null | ||
}; | ||
const results = {}; | ||
for (const name of message.params) { | ||
if (!this.namespaces[ns].events[name]) { | ||
results[name] = "provided event invalid"; | ||
continue; | ||
} | ||
const index = this.namespaces[ns].events[name].sockets.indexOf(socket_id); | ||
if (index === -1) { | ||
results[name] = "not subscribed"; | ||
continue; | ||
} | ||
this.namespaces[ns].events[name].sockets.splice(index, 1); | ||
results[name] = "ok"; | ||
} | ||
return { | ||
jsonrpc: "2.0", | ||
error: utils.createError(-32606), | ||
id: message.id || null | ||
}); | ||
case 28: | ||
socket_index = namespace.events[event_names[index]].sockets.indexOf(socket_id); | ||
if (!(socket_index >= 0)) { | ||
_context2.next = 32; | ||
break; | ||
} | ||
results[name] = "socket has already been subscribed to event"; | ||
return _context2.abrupt("continue", 34); | ||
case 32: | ||
namespace.events[event_names[index]].sockets.push(socket_id); | ||
results[name] = "ok"; | ||
case 34: | ||
_context2.next = 19; | ||
break; | ||
case 36: | ||
_context2.next = 41; | ||
break; | ||
case 38: | ||
_context2.prev = 38; | ||
_context2.t0 = _context2["catch"](17); | ||
_iterator4.e(_context2.t0); | ||
case 41: | ||
_context2.prev = 41; | ||
_iterator4.f(); | ||
return _context2.finish(41); | ||
case 44: | ||
return _context2.abrupt("return", { | ||
jsonrpc: "2.0", | ||
result: results, | ||
id: message.id || null | ||
}); | ||
case 47: | ||
if (!(message.method === "rpc.off")) { | ||
_context2.next = 78; | ||
break; | ||
} | ||
if (message.params) { | ||
_context2.next = 50; | ||
break; | ||
} | ||
return _context2.abrupt("return", { | ||
}; | ||
} | ||
else if (message.method === "rpc.login") { | ||
if (!message.params) | ||
return { | ||
jsonrpc: "2.0", | ||
error: utils.createError(-32604), | ||
id: message.id || null | ||
}; | ||
} | ||
if (!this.namespaces[ns].rpc_methods[message.method]) { | ||
return { | ||
jsonrpc: "2.0", | ||
error: utils.createError(-32000), | ||
id: message.id || null | ||
}); | ||
case 50: | ||
_results = {}; | ||
_iterator5 = _createForOfIteratorHelper(message.params); | ||
_context2.prev = 52; | ||
_iterator5.s(); | ||
case 54: | ||
if ((_step5 = _iterator5.n()).done) { | ||
_context2.next = 67; | ||
break; | ||
} | ||
_name = _step5.value; | ||
if (this.namespaces[ns].events[_name]) { | ||
_context2.next = 59; | ||
break; | ||
} | ||
_results[_name] = "provided event invalid"; | ||
return _context2.abrupt("continue", 65); | ||
case 59: | ||
_index = this.namespaces[ns].events[_name].sockets.indexOf(socket_id); | ||
if (!(_index === -1)) { | ||
_context2.next = 63; | ||
break; | ||
} | ||
_results[_name] = "not subscribed"; | ||
return _context2.abrupt("continue", 65); | ||
case 63: | ||
this.namespaces[ns].events[_name].sockets.splice(_index, 1); | ||
_results[_name] = "ok"; | ||
case 65: | ||
_context2.next = 54; | ||
break; | ||
case 67: | ||
_context2.next = 72; | ||
break; | ||
case 69: | ||
_context2.prev = 69; | ||
_context2.t1 = _context2["catch"](52); | ||
_iterator5.e(_context2.t1); | ||
case 72: | ||
_context2.prev = 72; | ||
_iterator5.f(); | ||
return _context2.finish(72); | ||
case 75: | ||
return _context2.abrupt("return", { | ||
jsonrpc: "2.0", | ||
result: _results, | ||
id: message.id || null | ||
}); | ||
case 78: | ||
if (!(message.method === "rpc.login")) { | ||
_context2.next = 81; | ||
break; | ||
} | ||
if (message.params) { | ||
_context2.next = 81; | ||
break; | ||
} | ||
return _context2.abrupt("return", { | ||
jsonrpc: "2.0", | ||
error: utils.createError(-32604), | ||
id: message.id || null | ||
}); | ||
case 81: | ||
if (this.namespaces[ns].rpc_methods[message.method]) { | ||
_context2.next = 83; | ||
break; | ||
} | ||
return _context2.abrupt("return", { | ||
jsonrpc: "2.0", | ||
error: utils.createError(-32601), | ||
id: message.id || null | ||
}); | ||
case 83: | ||
response = null; // reject request if method is protected and if client is not authenticated | ||
if (!(this.namespaces[ns].rpc_methods[message.method]["protected"] === true && this.namespaces[ns].clients.get(socket_id)["_authenticated"] === false)) { | ||
_context2.next = 86; | ||
break; | ||
} | ||
return _context2.abrupt("return", { | ||
}; | ||
} | ||
let response = null; | ||
// reject request if method is protected and if client is not authenticated | ||
if (this.namespaces[ns].rpc_methods[message.method].protected === true && | ||
this.namespaces[ns].clients.get(socket_id)["_authenticated"] === false) { | ||
return { | ||
jsonrpc: "2.0", | ||
error: utils.createError(-32605), | ||
id: message.id || null | ||
}); | ||
case 86: | ||
_context2.prev = 86; | ||
_context2.next = 89; | ||
return this.namespaces[ns].rpc_methods[message.method].fn(message.params, socket_id); | ||
case 89: | ||
response = _context2.sent; | ||
_context2.next = 99; | ||
break; | ||
case 92: | ||
_context2.prev = 92; | ||
_context2.t2 = _context2["catch"](86); | ||
if (message.id) { | ||
_context2.next = 96; | ||
break; | ||
} | ||
return _context2.abrupt("return"); | ||
case 96: | ||
if (!(_context2.t2 instanceof Error)) { | ||
_context2.next = 98; | ||
break; | ||
} | ||
return _context2.abrupt("return", { | ||
}; | ||
} | ||
try { | ||
response = await this.namespaces[ns].rpc_methods[message.method] | ||
.fn(message.params, socket_id); | ||
} | ||
catch (error) { | ||
if (!message.id) | ||
return; | ||
if (error instanceof Error) | ||
return { | ||
jsonrpc: "2.0", | ||
error: { | ||
code: -32000, | ||
message: error.name, | ||
data: error.message | ||
}, | ||
id: message.id | ||
}; | ||
return { | ||
jsonrpc: "2.0", | ||
error: { | ||
code: -32000, | ||
message: _context2.t2.name, | ||
data: _context2.t2.message | ||
}, | ||
error: error, | ||
id: message.id | ||
}); | ||
case 98: | ||
return _context2.abrupt("return", { | ||
jsonrpc: "2.0", | ||
error: _context2.t2, | ||
id: message.id | ||
}); | ||
case 99: | ||
if (message.id) { | ||
_context2.next = 101; | ||
break; | ||
} | ||
return _context2.abrupt("return"); | ||
case 101: | ||
// if login middleware returned true, set connection as authenticated | ||
if (message.method === "rpc.login" && response === true) { | ||
s = this.namespaces[ns].clients.get(socket_id); | ||
s["_authenticated"] = true; | ||
this.namespaces[ns].clients.set(socket_id, s); | ||
} | ||
return _context2.abrupt("return", { | ||
jsonrpc: "2.0", | ||
result: response, | ||
id: message.id | ||
}); | ||
case 103: | ||
case "end": | ||
return _context2.stop(); | ||
} | ||
}, _callee2, this, [[17, 38, 41, 44], [52, 69, 72, 75], [86, 92]]); | ||
})); | ||
function _runMethod(_x2, _x3) { | ||
return _runMethod2.apply(this, arguments); | ||
} | ||
return _runMethod; | ||
}() | ||
}; | ||
} | ||
// client sent a notification, so we won't need a reply | ||
if (!message.id) | ||
return; | ||
// if login middleware returned true, set connection as authenticated | ||
if (message.method === "rpc.login" && response === true) { | ||
const s = this.namespaces[ns].clients.get(socket_id); | ||
s["_authenticated"] = true; | ||
this.namespaces[ns].clients.set(socket_id, s); | ||
} | ||
return { | ||
jsonrpc: "2.0", | ||
result: response, | ||
id: message.id | ||
}; | ||
} | ||
/** | ||
@@ -870,21 +598,15 @@ * Generate a new namespace store. | ||
*/ | ||
) | ||
}, { | ||
key: "_generateNamespace", | ||
value: function _generateNamespace(name) { | ||
var _this6 = this; | ||
this.namespaces[name] = { | ||
rpc_methods: { | ||
"__listMethods": { | ||
fn: function fn() { | ||
return Object.keys(_this6.namespaces[name].rpc_methods); | ||
_generateNamespace(name) { | ||
this.namespaces[name] = { | ||
rpc_methods: { | ||
"__listMethods": { | ||
fn: () => Object.keys(this.namespaces[name].rpc_methods), | ||
protected: false | ||
} | ||
}, | ||
"protected": false | ||
} | ||
}, | ||
clients: new Map(), | ||
events: {} | ||
}; | ||
clients: new Map(), | ||
events: {} | ||
}; | ||
} | ||
}]); | ||
}(_eventemitter.EventEmitter); | ||
} | ||
exports.default = Server; |
"use strict"; | ||
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
exports.DefaultDataPack = void 0; | ||
exports.createError = createError; | ||
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); | ||
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); | ||
var errors = new Map([[-32000, "Event not provided"], [-32600, "Invalid Request"], [-32601, "Method not found"], [-32602, "Invalid params"], [-32603, "Internal error"], [-32604, "Params not found"], [-32605, "Method forbidden"], [-32606, "Event forbidden"], [-32700, "Parse error"]]); | ||
var DefaultDataPack = exports.DefaultDataPack = /*#__PURE__*/function () { | ||
function DefaultDataPack() { | ||
(0, _classCallCheck2["default"])(this, DefaultDataPack); | ||
} | ||
return (0, _createClass2["default"])(DefaultDataPack, [{ | ||
key: "encode", | ||
value: function encode(value) { | ||
return JSON.stringify(value); | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.createError = exports.DefaultDataPack = void 0; | ||
const errors = new Map([ | ||
[-32000, "Event not provided"], | ||
[-32600, "Invalid Request"], | ||
[-32601, "Method not found"], | ||
[-32602, "Invalid params"], | ||
[-32603, "Internal error"], | ||
[-32604, "Params not found"], | ||
[-32605, "Method forbidden"], | ||
[-32606, "Event forbidden"], | ||
[-32700, "Parse error"] | ||
]); | ||
class DefaultDataPack { | ||
encode(value) { | ||
return JSON.stringify(value); | ||
} | ||
}, { | ||
key: "decode", | ||
value: function decode(value) { | ||
return JSON.parse(value); | ||
decode(value) { | ||
return JSON.parse(value); | ||
} | ||
}]); | ||
}(); | ||
} | ||
exports.DefaultDataPack = DefaultDataPack; | ||
/** | ||
@@ -35,8 +31,10 @@ * Creates a JSON-RPC 2.0-compliant error. | ||
function createError(code, details) { | ||
var error = { | ||
code: code, | ||
message: errors.get(code) || "Internal Server Error" | ||
}; | ||
if (details) error["data"] = details; | ||
return error; | ||
} | ||
const error = { | ||
code: code, | ||
message: errors.get(code) || "Internal Server Error" | ||
}; | ||
if (details) | ||
error["data"] = details; | ||
return error; | ||
} | ||
exports.createError = createError; |
{ | ||
"name": "rpc-websockets", | ||
"version": "7.10.0", | ||
"version": "7.11.0", | ||
"description": "JSON-RPC 2.0 implementation over WebSockets for Node.js", | ||
"main": "./dist/index.js", | ||
"scripts": { | ||
"build": "tsc && mkdir -p ./dist && eslint --fix -c ./.eslintrc './src/**/*.ts' && babel ./build-ts -d ./dist --copy-files && browserify -s RPCWebSocket ./dist/index.browser.js > ./dist/index.browser-bundle.js", | ||
"build": "tsc && mkdir -p ./dist && eslint --fix -c ./.eslintrc './src/**/*.ts' && ./build-browser-bundle.mjs", | ||
"pretest": "npm run-script build", | ||
@@ -20,3 +20,2 @@ "test": "mocha --exit test/*spec.js", | ||
"dependencies": { | ||
"@babel/runtime": "^7.17.2", | ||
"eventemitter3": "^4.0.7", | ||
@@ -31,7 +30,5 @@ "uuid": "^8.3.2", | ||
"devDependencies": { | ||
"@babel/cli": "^7.17.0", | ||
"@babel/core": "^7.17.2", | ||
"@babel/core": "^7.24.5", | ||
"@babel/plugin-transform-runtime": "^7.17.0", | ||
"@babel/preset-env": "^7.16.11", | ||
"@babel/preset-typescript": "^7.16.7", | ||
"@types/uuid": "^8.3.4", | ||
@@ -43,5 +40,6 @@ "@types/ws": "^8.2.2", | ||
"babel-eslint": "^10.1.0", | ||
"browserify": "^17.0.0", | ||
"chai": "^4.3.6", | ||
"coveralls": "^3.1.1", | ||
"esbuild": "^0.20.2", | ||
"esbuild-plugin-babel": "^0.2.3", | ||
"eslint": "^8.8.0", | ||
@@ -48,0 +46,0 @@ "istanbul": "^0.4.5", |
{ | ||
"compilerOptions": { | ||
"outDir": "./build-ts", | ||
"outDir": "./dist", | ||
"declaration": true, | ||
"allowUnreachableCode": false, | ||
"noImplicitAny": true, | ||
"target": "es2017", | ||
"module": "CommonJS", | ||
"target": "ESNext", | ||
"esModuleInterop": true, | ||
"moduleResolution": "node", | ||
@@ -9,0 +11,0 @@ "allowSyntheticDefaultImports": true, |
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Deprecated
MaintenanceThe maintainer of the package marked it as deprecated. This could indicate that a single version should not be used, or that the package is no longer maintained and any new vulnerabilities will not be fixed.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
5
18
0
5274145
44
1663
1
- Removed@babel/runtime@^7.17.2
- Removed@babel/runtime@7.26.0(transitive)
- Removedregenerator-runtime@0.14.1(transitive)