@akiroz/thalamus
Advanced tools
Comparing version 0.2.0 to 0.2.1
@@ -1,33 +0,99 @@ | ||
import * as MQTT from "mqtt"; | ||
export * from "mqtt"; | ||
export function connect(brokerUrl, opts) { | ||
const client = MQTT.connect(brokerUrl, opts); | ||
client.publishAsync = function (...args) { | ||
return new Promise((rsov, rjct) => { | ||
client.publish(...args, (err, res) => { | ||
if (err) | ||
rjct(err); | ||
else | ||
rsov(res); | ||
}); | ||
"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 __exportStar = (this && this.__exportStar) || function(m, exports) { | ||
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); | ||
}; | ||
var __read = (this && this.__read) || function (o, n) { | ||
var m = typeof Symbol === "function" && o[Symbol.iterator]; | ||
if (!m) return o; | ||
var i = m.call(o), r, ar = [], e; | ||
try { | ||
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); | ||
} | ||
catch (error) { e = { error: error }; } | ||
finally { | ||
try { | ||
if (r && !r.done && (m = i["return"])) m.call(i); | ||
} | ||
finally { if (e) throw e.error; } | ||
} | ||
return ar; | ||
}; | ||
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { | ||
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { | ||
if (ar || !(i in from)) { | ||
if (!ar) ar = Array.prototype.slice.call(from, 0, i); | ||
ar[i] = from[i]; | ||
} | ||
} | ||
return to.concat(ar || Array.prototype.slice.call(from)); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.connect = void 0; | ||
var MQTT = __importStar(require("mqtt")); | ||
__exportStar(require("mqtt"), exports); | ||
function connect(brokerUrl, opts) { | ||
var client = MQTT.connect(brokerUrl, opts); | ||
client.publishAsync = function () { | ||
var args = []; | ||
for (var _i = 0; _i < arguments.length; _i++) { | ||
args[_i] = arguments[_i]; | ||
} | ||
return new Promise(function (rsov, rjct) { | ||
client.publish.apply(client, __spreadArray(__spreadArray([], __read(args), false), [function (err, res) { | ||
if (err) | ||
rjct(err); | ||
else | ||
rsov(res); | ||
}], false)); | ||
}); | ||
}; | ||
client.subscribeAsync = function (...args) { | ||
return new Promise((rsov, rjct) => { | ||
client.subscribe(...args, (err, res) => { | ||
if (err) | ||
rjct(err); | ||
else | ||
rsov(res); | ||
}); | ||
client.subscribeAsync = function () { | ||
var args = []; | ||
for (var _i = 0; _i < arguments.length; _i++) { | ||
args[_i] = arguments[_i]; | ||
} | ||
return new Promise(function (rsov, rjct) { | ||
client.subscribe.apply(client, __spreadArray(__spreadArray([], __read(args), false), [function (err, res) { | ||
if (err) | ||
rjct(err); | ||
else | ||
rsov(res); | ||
}], false)); | ||
}); | ||
}; | ||
client.unsubscribeAsync = function (...args) { | ||
return new Promise((rsov, rjct) => { | ||
client.unsubscribe(...args, (err, res) => { | ||
if (err) | ||
rjct(err); | ||
else | ||
rsov(res); | ||
}); | ||
client.unsubscribeAsync = function () { | ||
var args = []; | ||
for (var _i = 0; _i < arguments.length; _i++) { | ||
args[_i] = arguments[_i]; | ||
} | ||
return new Promise(function (rsov, rjct) { | ||
client.unsubscribe.apply(client, __spreadArray(__spreadArray([], __read(args), false), [function (err, res) { | ||
if (err) | ||
rjct(err); | ||
else | ||
rsov(res); | ||
}], false)); | ||
}); | ||
@@ -37,1 +103,2 @@ }; | ||
} | ||
exports.connect = connect; |
@@ -0,1 +1,40 @@ | ||
"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 __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) { | ||
@@ -10,129 +49,312 @@ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
}; | ||
import { EventEmitter } from "events"; | ||
import MQEmitter from "mqemitter"; | ||
import * as MQTT from "./asyncWrapper"; | ||
import * as RPC from "./rpc"; | ||
export default class Thalamus extends EventEmitter { | ||
constructor(serverOptList = []) { | ||
super(); | ||
this.subDebounceWindow = 10; | ||
this.subDebounceState = null; | ||
this.emitter = MQEmitter(); | ||
this.persistantTopics = new Set(); | ||
this.handlers = new WeakMap(); | ||
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 (_) 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 }; | ||
} | ||
}; | ||
var __read = (this && this.__read) || function (o, n) { | ||
var m = typeof Symbol === "function" && o[Symbol.iterator]; | ||
if (!m) return o; | ||
var i = m.call(o), r, ar = [], e; | ||
try { | ||
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); | ||
} | ||
catch (error) { e = { error: error }; } | ||
finally { | ||
try { | ||
if (r && !r.done && (m = i["return"])) m.call(i); | ||
} | ||
finally { if (e) throw e.error; } | ||
} | ||
return ar; | ||
}; | ||
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { | ||
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { | ||
if (ar || !(i in from)) { | ||
if (!ar) ar = Array.prototype.slice.call(from, 0, i); | ||
ar[i] = from[i]; | ||
} | ||
} | ||
return to.concat(ar || Array.prototype.slice.call(from)); | ||
}; | ||
var __values = (this && this.__values) || function(o) { | ||
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; | ||
if (m) return m.call(o); | ||
if (o && typeof o.length === "number") return { | ||
next: function () { | ||
if (o && i >= o.length) o = void 0; | ||
return { value: o && o[i++], done: !o }; | ||
} | ||
}; | ||
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var events_1 = require("events"); | ||
var mqemitter_1 = __importDefault(require("mqemitter")); | ||
var MQTT = __importStar(require("./asyncWrapper")); | ||
var RPC = __importStar(require("./rpc")); | ||
var Thalamus = /** @class */ (function (_super) { | ||
__extends(Thalamus, _super); | ||
function Thalamus(serverOptList) { | ||
if (serverOptList === void 0) { serverOptList = []; } | ||
var _this = _super.call(this) || this; | ||
_this.subDebounceWindow = 10; | ||
_this.subDebounceState = null; | ||
_this.emitter = (0, mqemitter_1.default)(); | ||
_this.persistantTopics = new Set(); | ||
_this.handlers = new WeakMap(); | ||
if (serverOptList.length < 1) | ||
throw Error("No MQTT servers"); | ||
this.servers = serverOptList.map((opt) => { | ||
_this.servers = serverOptList.map(function (opt) { | ||
opt.resubscribe = false; // Disable MQTT.js resub, handle manually. | ||
return MQTT.connect(opt); | ||
}); | ||
for (let i = 0; i < this.servers.length; i++) { | ||
this.servers[i].on("connect", () => __awaiter(this, void 0, void 0, function* () { | ||
this.emit("connect", i); | ||
try { | ||
yield this.servers[i].subscribeAsync([...this.persistantTopics], { qos: 0 }); | ||
} | ||
catch (err) { | ||
console.warn(`[Thalamus] re-subscribe failed, reconnect...`, err); | ||
this.servers[i].reconnect(); | ||
} | ||
})); | ||
this.servers[i].on("close", () => this.emit("close", i)); | ||
this.servers[i].on("error", (err) => this.emit("error", err, i)); | ||
this.servers[i].on("message", (topic, message) => this.emitter.emit({ topic, message })); | ||
var _loop_1 = function (i) { | ||
this_1.servers[i].on("connect", function () { return __awaiter(_this, void 0, void 0, function () { | ||
var err_1; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
this.emit("connect", i); | ||
_a.label = 1; | ||
case 1: | ||
_a.trys.push([1, 3, , 4]); | ||
return [4 /*yield*/, this.servers[i].subscribeAsync(__spreadArray([], __read(this.persistantTopics), false), { qos: 0 })]; | ||
case 2: | ||
_a.sent(); | ||
return [3 /*break*/, 4]; | ||
case 3: | ||
err_1 = _a.sent(); | ||
console.warn("[Thalamus] re-subscribe failed, reconnect...", err_1); | ||
this.servers[i].reconnect(); | ||
return [3 /*break*/, 4]; | ||
case 4: return [2 /*return*/]; | ||
} | ||
}); | ||
}); }); | ||
this_1.servers[i].on("close", function () { return _this.emit("close", i); }); | ||
this_1.servers[i].on("error", function (err) { return _this.emit("error", err, i); }); | ||
this_1.servers[i].on("message", function (topic, message) { return _this.emitter.emit({ topic: topic, message: message }); }); | ||
}; | ||
var this_1 = this; | ||
for (var i = 0; i < _this.servers.length; i++) { | ||
_loop_1(i); | ||
} | ||
return _this; | ||
} | ||
publish(topic, payload) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
let published = false; | ||
for (let serv of this.servers) { | ||
if (serv.connected) { | ||
yield serv.publish(topic, Buffer.from(payload)); | ||
published = true; | ||
break; | ||
Thalamus.prototype.publish = function (topic, payload) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var published, _a, _b, serv, e_1_1; | ||
var e_1, _c; | ||
return __generator(this, function (_d) { | ||
switch (_d.label) { | ||
case 0: | ||
published = false; | ||
_d.label = 1; | ||
case 1: | ||
_d.trys.push([1, 6, 7, 8]); | ||
_a = __values(this.servers), _b = _a.next(); | ||
_d.label = 2; | ||
case 2: | ||
if (!!_b.done) return [3 /*break*/, 5]; | ||
serv = _b.value; | ||
if (!serv.connected) return [3 /*break*/, 4]; | ||
return [4 /*yield*/, serv.publish(topic, Buffer.from(payload))]; | ||
case 3: | ||
_d.sent(); | ||
published = true; | ||
return [3 /*break*/, 5]; | ||
case 4: | ||
_b = _a.next(); | ||
return [3 /*break*/, 2]; | ||
case 5: return [3 /*break*/, 8]; | ||
case 6: | ||
e_1_1 = _d.sent(); | ||
e_1 = { error: e_1_1 }; | ||
return [3 /*break*/, 8]; | ||
case 7: | ||
try { | ||
if (_b && !_b.done && (_c = _a.return)) _c.call(_a); | ||
} | ||
finally { if (e_1) throw e_1.error; } | ||
return [7 /*endfinally*/]; | ||
case 8: | ||
if (!!published) return [3 /*break*/, 10]; | ||
// Try publish on server 0 anyway | ||
return [4 /*yield*/, this.servers[0].publish(topic, Buffer.from(payload))]; | ||
case 9: | ||
// Try publish on server 0 anyway | ||
_d.sent(); | ||
_d.label = 10; | ||
case 10: return [2 /*return*/]; | ||
} | ||
} | ||
if (!published) { | ||
// Try publish on server 0 anyway | ||
yield this.servers[0].publish(topic, Buffer.from(payload)); | ||
} | ||
}); | ||
}); | ||
} | ||
doSubscribe() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
this.subDebounceState.doSubscribeLock = true; | ||
try { | ||
const conn = this.servers.filter(s => s.connected); | ||
yield Promise.all(conn.map((srv) => __awaiter(this, void 0, void 0, function* () { | ||
try { | ||
yield srv.subscribeAsync([...this.subDebounceState.topics], { qos: 0 }); | ||
} | ||
catch (err) { | ||
console.warn(`[Thalamus] doSubscribe failed, reconnect...`, err); | ||
srv.reconnect(); | ||
throw err; | ||
} | ||
}))); | ||
this.subDebounceState.event.emit("sub"); | ||
} | ||
catch (err) { | ||
this.subDebounceState.event.emit("err", err); | ||
} | ||
this.subDebounceState = null; | ||
}; | ||
Thalamus.prototype.doSubscribe = function () { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var conn, err_2; | ||
var _this = this; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
this.subDebounceState.doSubscribeLock = true; | ||
_a.label = 1; | ||
case 1: | ||
_a.trys.push([1, 3, , 4]); | ||
conn = this.servers.filter(function (s) { return s.connected; }); | ||
return [4 /*yield*/, Promise.all(conn.map(function (srv) { return __awaiter(_this, void 0, void 0, function () { | ||
var err_3; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
_a.trys.push([0, 2, , 3]); | ||
return [4 /*yield*/, srv.subscribeAsync(__spreadArray([], __read(this.subDebounceState.topics), false), { qos: 0 })]; | ||
case 1: | ||
_a.sent(); | ||
return [3 /*break*/, 3]; | ||
case 2: | ||
err_3 = _a.sent(); | ||
console.warn("[Thalamus] doSubscribe failed, reconnect...", err_3); | ||
srv.reconnect(); | ||
throw err_3; | ||
case 3: return [2 /*return*/]; | ||
} | ||
}); | ||
}); }))]; | ||
case 2: | ||
_a.sent(); | ||
this.subDebounceState.event.emit("sub"); | ||
return [3 /*break*/, 4]; | ||
case 3: | ||
err_2 = _a.sent(); | ||
this.subDebounceState.event.emit("err", err_2); | ||
return [3 /*break*/, 4]; | ||
case 4: | ||
this.subDebounceState = null; | ||
return [2 /*return*/]; | ||
} | ||
}); | ||
}); | ||
} | ||
subscribe(topic, handler, opts = { persistent: true }) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const h = ({ topic, message }, done) => (done(), handler(message, topic)); | ||
if (opts.persistent) { | ||
this.persistantTopics.add(topic); | ||
this.handlers.set(handler, h); | ||
this.emitter.on(topic, h); | ||
if (this.subDebounceState) { | ||
if (this.subDebounceState.doSubscribeLock) | ||
throw Error("doSubscribe in progress"); | ||
this.subDebounceState.topics.add(topic); | ||
clearTimeout(this.subDebounceState.timeout); | ||
this.subDebounceState.timeout = setTimeout(() => this.doSubscribe(), this.subDebounceWindow); | ||
}; | ||
Thalamus.prototype.subscribe = function (topic, handler, opts) { | ||
if (opts === void 0) { opts = { persistent: true }; } | ||
return __awaiter(this, void 0, void 0, function () { | ||
var h, ee_1, conn; | ||
var _this = this; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
h = function (_a, done) { | ||
var topic = _a.topic, message = _a.message; | ||
return (done(), handler(message, topic)); | ||
}; | ||
if (!opts.persistent) return [3 /*break*/, 2]; | ||
this.persistantTopics.add(topic); | ||
this.handlers.set(handler, h); | ||
this.emitter.on(topic, h); | ||
if (this.subDebounceState) { | ||
if (this.subDebounceState.doSubscribeLock) | ||
throw Error("doSubscribe in progress"); | ||
this.subDebounceState.topics.add(topic); | ||
clearTimeout(this.subDebounceState.timeout); | ||
this.subDebounceState.timeout = setTimeout(function () { return _this.doSubscribe(); }, this.subDebounceWindow); | ||
} | ||
else { | ||
ee_1 = new events_1.EventEmitter(); | ||
this.subDebounceState = { | ||
topics: new Set([topic]), | ||
event: ee_1, | ||
promise: new Promise(function (rsov, rjct) { | ||
ee_1.once("sub", rsov); | ||
ee_1.once("err", rjct); | ||
}), | ||
timeout: setTimeout(function () { return _this.doSubscribe(); }, this.subDebounceWindow), | ||
doSubscribeLock: false, | ||
}; | ||
} | ||
return [4 /*yield*/, this.subDebounceState.promise]; | ||
case 1: | ||
_a.sent(); | ||
return [3 /*break*/, 4]; | ||
case 2: | ||
conn = this.servers.filter(function (s) { return s.connected; }); | ||
return [4 /*yield*/, Promise.all(conn.map(function (s) { return s.subscribeAsync(topic, { qos: 0 }); }))]; | ||
case 3: | ||
_a.sent(); | ||
this.handlers.set(handler, h); | ||
this.emitter.on(topic, h); | ||
_a.label = 4; | ||
case 4: return [2 /*return*/]; | ||
} | ||
else { | ||
const ee = new EventEmitter(); | ||
this.subDebounceState = { | ||
topics: new Set([topic]), | ||
event: ee, | ||
promise: new Promise((rsov, rjct) => { | ||
ee.once("sub", rsov); | ||
ee.once("err", rjct); | ||
}), | ||
timeout: setTimeout(() => this.doSubscribe(), this.subDebounceWindow), | ||
doSubscribeLock: false, | ||
}; | ||
}); | ||
}); | ||
}; | ||
Thalamus.prototype.unsubscribe = function (topic, handler) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var conn; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
this.emitter.removeListener(topic, handler && this.handlers.get(handler)); | ||
conn = this.servers.filter(function (s) { return s.connected; }); | ||
return [4 /*yield*/, Promise.all(conn.map(function (s) { return s.unsubscribeAsync(topic); }))]; | ||
case 1: | ||
_a.sent(); | ||
return [2 /*return*/]; | ||
} | ||
yield this.subDebounceState.promise; | ||
} | ||
else { | ||
const conn = this.servers.filter(s => s.connected); | ||
yield Promise.all(conn.map(s => s.subscribeAsync(topic, { qos: 0 }))); | ||
this.handlers.set(handler, h); | ||
this.emitter.on(topic, h); | ||
} | ||
}); | ||
}); | ||
} | ||
unsubscribe(topic, handler) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
this.emitter.removeListener(topic, handler && this.handlers.get(handler)); | ||
const conn = this.servers.filter(s => s.connected); | ||
yield Promise.all(conn.map(s => s.unsubscribeAsync(topic))); | ||
}; | ||
Thalamus.prototype.register = function (topic, handler) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, RPC.register(this, topic, handler)]; | ||
case 1: | ||
_a.sent(); | ||
return [2 /*return*/]; | ||
} | ||
}); | ||
}); | ||
} | ||
register(topic, handler) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
yield RPC.register(this, topic, handler); | ||
}; | ||
Thalamus.prototype.call = function (topic, params, opt) { | ||
if (params === void 0) { params = {}; } | ||
if (opt === void 0) { opt = RPC.defaultCallOptions; } | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, RPC.call(this, topic, params, opt)]; | ||
case 1: return [2 /*return*/, _a.sent()]; | ||
} | ||
}); | ||
}); | ||
} | ||
call(topic, params = {}, opt = RPC.defaultCallOptions) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
return yield RPC.call(this, topic, params, opt); | ||
}); | ||
} | ||
} | ||
}; | ||
return Thalamus; | ||
}(events_1.EventEmitter)); | ||
exports.default = Thalamus; |
225
dist/rpc.js
@@ -0,1 +1,25 @@ | ||
"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 __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
@@ -10,7 +34,61 @@ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
}; | ||
import * as MsgPack from "@msgpack/msgpack"; | ||
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 (_) 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 }; | ||
} | ||
}; | ||
var __read = (this && this.__read) || function (o, n) { | ||
var m = typeof Symbol === "function" && o[Symbol.iterator]; | ||
if (!m) return o; | ||
var i = m.call(o), r, ar = [], e; | ||
try { | ||
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); | ||
} | ||
catch (error) { e = { error: error }; } | ||
finally { | ||
try { | ||
if (r && !r.done && (m = i["return"])) m.call(i); | ||
} | ||
finally { if (e) throw e.error; } | ||
} | ||
return ar; | ||
}; | ||
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { | ||
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { | ||
if (ar || !(i in from)) { | ||
if (!ar) ar = Array.prototype.slice.call(from, 0, i); | ||
ar[i] = from[i]; | ||
} | ||
} | ||
return to.concat(ar || Array.prototype.slice.call(from)); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.register = exports.call = exports.defaultCallOptions = void 0; | ||
var MsgPack = __importStar(require("@msgpack/msgpack")); | ||
function encodeBase64URL(data) { | ||
const base64 = Buffer | ||
var base64 = Buffer | ||
? Buffer.from(data).toString("base64") | ||
: btoa(String.fromCharCode(...data)); | ||
: btoa(String.fromCharCode.apply(String, __spreadArray([], __read(data), false))); | ||
return base64 | ||
@@ -23,3 +101,3 @@ .replace(/=/g, "") | ||
if (typeof window !== 'undefined') { | ||
const id = new Uint8Array(size); | ||
var id = new Uint8Array(size); | ||
if (window.crypto) | ||
@@ -29,3 +107,3 @@ window.crypto.getRandomValues(id); | ||
console.warn("[RiceRPC] No crypto module, using Math.random for call ID"); | ||
for (let i = 0; i < size; i++) { | ||
for (var i = 0; i < size; i++) { | ||
id[i] = Math.floor(Math.random() * 265); | ||
@@ -41,7 +119,7 @@ } | ||
// Dedups last 100 message received by ID | ||
const idDedup = { | ||
var idDedup = { | ||
arr: [], | ||
set: new Set(), | ||
max: 100, | ||
put(key) { | ||
put: function (key) { | ||
if (this.set.has(key)) | ||
@@ -52,64 +130,99 @@ return; | ||
if (this.arr.length > this.max) { | ||
const elem = this.arr.shift(); | ||
var elem = this.arr.shift(); | ||
this.set.delete(elem); | ||
} | ||
}, | ||
has(key) { | ||
has: function (key) { | ||
return this.set.has(key); | ||
} | ||
}; | ||
export const defaultCallOptions = { | ||
exports.defaultCallOptions = { | ||
timeout: 10000, | ||
idSize: 16, // bytes | ||
}; | ||
export function call(client, topic, params = {}, opt = defaultCallOptions) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
opt = Object.assign({}, defaultCallOptions, opt); | ||
const id = generateCallId(opt.idSize); | ||
const strId = encodeBase64URL(id); | ||
const responseTopic = `${topic}/${strId}`; | ||
const msg = yield new Promise((rsov, rjct) => { | ||
const timeoutId = setTimeout(() => { | ||
client.unsubscribe(responseTopic); | ||
rjct({ message: "timeout", data: { topic, params, opt, id } }); | ||
}, opt.timeout); | ||
client.subscribe(responseTopic, (msg) => __awaiter(this, void 0, void 0, function* () { | ||
clearTimeout(timeoutId); | ||
client.unsubscribe(responseTopic); | ||
rsov(msg); | ||
}), { persistent: false }).then(() => { | ||
return client.publish(topic, MsgPack.encode({ id, params })); | ||
}).catch((err) => { | ||
clearTimeout(timeoutId); | ||
client.unsubscribe(responseTopic); | ||
rjct({ message: "pub/sub error", data: err }); | ||
}); | ||
function call(client, topic, params, opt) { | ||
if (params === void 0) { params = {}; } | ||
if (opt === void 0) { opt = exports.defaultCallOptions; } | ||
return __awaiter(this, void 0, void 0, function () { | ||
var id, strId, responseTopic, msg, _a, result, error; | ||
var _this = this; | ||
return __generator(this, function (_b) { | ||
switch (_b.label) { | ||
case 0: | ||
opt = Object.assign({}, exports.defaultCallOptions, opt); | ||
id = generateCallId(opt.idSize); | ||
strId = encodeBase64URL(id); | ||
responseTopic = "".concat(topic, "/").concat(strId); | ||
return [4 /*yield*/, new Promise(function (rsov, rjct) { | ||
var timeoutId = setTimeout(function () { | ||
client.unsubscribe(responseTopic); | ||
rjct({ message: "timeout", data: { topic: topic, params: params, opt: opt, id: id } }); | ||
}, opt.timeout); | ||
client.subscribe(responseTopic, function (msg) { return __awaiter(_this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
clearTimeout(timeoutId); | ||
client.unsubscribe(responseTopic); | ||
rsov(msg); | ||
return [2 /*return*/]; | ||
}); | ||
}); }, { persistent: false }).then(function () { | ||
return client.publish(topic, MsgPack.encode({ id: id, params: params })); | ||
}).catch(function (err) { | ||
clearTimeout(timeoutId); | ||
client.unsubscribe(responseTopic); | ||
rjct({ message: "pub/sub error", data: err }); | ||
}); | ||
})]; | ||
case 1: | ||
msg = _b.sent(); | ||
_a = MsgPack.decode(msg), result = _a.result, error = _a.error; | ||
if (error) | ||
throw error; | ||
return [2 /*return*/, result]; | ||
} | ||
}); | ||
const { result, error } = MsgPack.decode(msg); | ||
if (error) | ||
throw error; | ||
return result; | ||
}); | ||
} | ||
export function register(client, topic, handler) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
yield client.subscribe(topic, (payload, msgTopic, ctx) => __awaiter(this, void 0, void 0, function* () { | ||
if (!(payload instanceof Uint8Array)) | ||
throw Error(`Invalid payload: ${payload}`); | ||
const msg = MsgPack.decode(payload); | ||
if (!msg) | ||
throw Error(`Invalid payload: ${payload}`); | ||
const { id, params } = msg; | ||
if (!id) | ||
throw Error("Missing id in RPC call"); | ||
const strId = encodeBase64URL(id); | ||
if (idDedup.has(strId)) | ||
throw Error("Duplicate call request"); | ||
idDedup.put(strId); | ||
const response = yield handler(params, msgTopic, ctx) | ||
.then((r) => ({ result: r || {} })) | ||
.catch((error) => ({ error })); | ||
yield client.publish(`${msgTopic}/${strId}`, MsgPack.encode(response)); | ||
})); | ||
exports.call = call; | ||
function register(client, topic, handler) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var _this = this; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, client.subscribe(topic, function (payload, msgTopic, ctx) { return __awaiter(_this, void 0, void 0, function () { | ||
var msg, id, params, strId, response; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
if (!(payload instanceof Uint8Array)) | ||
throw Error("Invalid payload: ".concat(payload)); | ||
msg = MsgPack.decode(payload); | ||
if (!msg) | ||
throw Error("Invalid payload: ".concat(payload)); | ||
id = msg.id, params = msg.params; | ||
if (!id) | ||
throw Error("Missing id in RPC call"); | ||
strId = encodeBase64URL(id); | ||
if (idDedup.has(strId)) | ||
throw Error("Duplicate call request"); | ||
idDedup.put(strId); | ||
return [4 /*yield*/, handler(params, msgTopic, ctx) | ||
.then(function (r) { return ({ result: r || {} }); }) | ||
.catch(function (error) { return ({ error: error }); })]; | ||
case 1: | ||
response = _a.sent(); | ||
return [4 /*yield*/, client.publish("".concat(msgTopic, "/").concat(strId), MsgPack.encode(response))]; | ||
case 2: | ||
_a.sent(); | ||
return [2 /*return*/]; | ||
} | ||
}); | ||
}); })]; | ||
case 1: | ||
_a.sent(); | ||
return [2 /*return*/]; | ||
} | ||
}); | ||
}); | ||
} | ||
exports.register = register; |
{ | ||
"name": "@akiroz/thalamus", | ||
"version": "0.2.0", | ||
"version": "0.2.1", | ||
"repository": "github:akiroz/Thalamus", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
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
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
38228
756