@devgrid/netron
Version:
A powerful TypeScript library for building distributed systems with event bus, streaming capabilities, and remote object invocation. Features WebSocket-based bidirectional communication between Node.js and browser environments, service discovery, and type
106 lines • 3.61 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AbstractPeer = void 0;
const semver_1 = __importDefault(require("semver"));
const interface_1 = require("./interface");
const predicates_1 = require("./predicates");
class AbstractPeer {
constructor(netron, id) {
this.netron = netron;
this.id = id;
this.abilities = {};
this.interfaces = new Map();
}
unexposeAllServices() {
for (const ctxId of this.getServiceNames()) {
this.unexposeService(ctxId);
}
}
async queryInterface(qualifiedName) {
let name;
let version;
if (qualifiedName.includes('@')) {
[name, version] = qualifiedName.split('@');
}
else {
name = qualifiedName;
version = '*';
}
let def;
if (version === '*' || !version) {
def = this.findLatestServiceVersion(name);
}
else {
const exactKey = `${name}@${version}`;
def = this.getDefinitionByServiceName(exactKey);
}
return this.queryInterfaceByDefId(def.id, def);
}
queryInterfaceByDefId(defId, def) {
if (!def) {
def = this.getDefinitionById(defId);
}
let iInfo = this.interfaces.get(defId);
if (iInfo !== void 0) {
iInfo.refCount++;
return iInfo.instance;
}
const instance = interface_1.Interface.create(def, this);
iInfo = { instance, refCount: 1 };
this.interfaces.set(def.id, iInfo);
return instance;
}
async releaseInterface(iInstance, released = new Set()) {
if (!(0, predicates_1.isServiceInterface)(iInstance) || !iInstance.$def) {
throw new Error('Invalid interface');
}
const defId = iInstance.$def.id;
if (released.has(defId))
return;
released.add(defId);
const iInfo = this.interfaces.get(defId);
if (!iInfo) {
throw new Error('Invalid interface');
}
iInfo.refCount--;
if (iInfo.refCount === 0) {
this.interfaces.delete(defId);
for (const i of this.interfaces.values()) {
if (i.instance.$def?.parentId === defId) {
this.releaseInterface(i.instance);
}
}
await this.releaseInterfaceInternal(iInstance);
iInstance.$def = undefined;
iInstance.$peer = undefined;
}
}
findLatestServiceVersion(serviceName) {
if (!serviceName.includes('@')) {
try {
return this.getDefinitionByServiceName(serviceName);
}
catch (_) {
}
}
const regex = new RegExp(`^${serviceName}@([^@]+)$`);
const candidates = Array.from(this.getServiceNames())
.map((key) => {
const match = key.match(regex);
if (match)
return { version: match[1], key };
return null;
})
.filter((x) => x !== null)
.sort((a, b) => semver_1.default.rcompare(a.version, b.version));
if (candidates.length === 0) {
throw new Error(`Unknown service: ${serviceName}`);
}
return this.getDefinitionByServiceName(candidates[0].key);
}
}
exports.AbstractPeer = AbstractPeer;
//# sourceMappingURL=abstract-peer.js.map