@devgrid/netron
Version:
Event bus, streams and remote object invocation.
165 lines • 6.04 kB
JavaScript
import { Interface } from './interface';
import { Definition } from './definition';
import { ServiceStub } from './service-stub';
import { AbstractPeer } from './abstract-peer';
import { isServiceInterface, isServiceDefinition } from './predicates';
import { getServiceMetadata, getServiceEventName, NETRON_EVENT_SERVICE_EXPOSE, NETRON_EVENT_SERVICE_UNEXPOSE, } from './common';
export class LocalPeer extends AbstractPeer {
constructor(netron) {
super(netron, netron.id);
this.stubs = new Map();
this.serviceInstances = new Map();
}
async exposeService(instance) {
const meta = getServiceMetadata(instance);
if (!meta) {
throw new Error('Invalid service');
}
if (this.netron.services.has(meta.name)) {
throw new Error(`Service already exposed: ${meta.name}`);
}
const stub = new ServiceStub(this, instance, meta);
const def = stub.definition;
this.stubs.set(def.id, stub);
this.netron.services.set(meta.name, stub);
this.serviceInstances.set(instance, stub);
this.netron.emitSpecial(NETRON_EVENT_SERVICE_EXPOSE, getServiceEventName(def.meta.name), {
name: def.meta.name,
peerId: this.id,
definition: def,
});
return def;
}
exposeRemoteService(peer, meta) {
const def = new Definition(Definition.nextId(), peer.id, meta);
const iInstance = Interface.create(def, peer);
const stub = new ServiceStub(this, iInstance, def);
this.stubs.set(def.id, stub);
this.netron.services.set(meta.name, stub);
this.serviceInstances.set(iInstance, stub);
peer.definitions.set(def.id, def);
this.netron.emitSpecial(NETRON_EVENT_SERVICE_EXPOSE, getServiceEventName(def.meta.name), {
name: def.meta.name,
peerId: this.id,
remotePeerId: peer.id,
definition: def,
});
return def;
}
async unexposeService(serviceName) {
const def = this.getDefinitionByServiceName(serviceName);
const defId = def.id;
for (const i of this.interfaces.values()) {
if (i.instance.$def?.parentId === defId) {
this.releaseInterface(i.instance);
}
}
this.netron.services.delete(serviceName);
const stub = this.stubs.get(defId);
if (stub) {
this.serviceInstances.delete(stub.instance);
this.stubs.delete(defId);
}
this.netron.emitSpecial(NETRON_EVENT_SERVICE_UNEXPOSE, getServiceEventName(serviceName), {
name: serviceName,
peerId: this.id,
defId,
});
}
unexposeRemoteService(peer, serviceName) {
const def = this.getDefinitionByServiceName(serviceName);
const defId = def.id;
for (const i of this.interfaces.values()) {
if (i.instance.$def?.parentId === defId) {
this.releaseInterface(i.instance);
}
}
peer.definitions.delete(defId);
this.netron.services.delete(serviceName);
const stub = this.stubs.get(defId);
if (stub) {
this.serviceInstances.delete(stub.instance);
this.stubs.delete(defId);
}
this.netron.emitSpecial(NETRON_EVENT_SERVICE_UNEXPOSE, getServiceEventName(serviceName), {
name: serviceName,
peerId: this.id,
remotePeerId: peer.id,
defId,
});
return def.id;
}
async releaseInterfaceInternal(iInstance) {
this.unrefService(iInstance.$def?.id);
}
refService(instance, parentDef) {
const existingStub = this.serviceInstances.get(instance);
if (existingStub) {
return existingStub.definition;
}
const meta = isServiceInterface(instance) ? instance.$def.meta : getServiceMetadata(instance);
const stub = new ServiceStub(this, instance, meta);
stub.definition.parentId = parentDef.id;
this.serviceInstances.set(instance, stub);
this.stubs.set(stub.definition.id, stub);
return stub.definition;
}
unrefService(defId) {
if (defId) {
const stub = this.stubs.get(defId);
if (stub) {
this.serviceInstances.delete(stub.instance);
this.stubs.delete(stub.definition.id);
}
}
}
subscribe(eventName, handler) {
this.netron.on(eventName, handler);
}
unsubscribe(eventName, handler) {
this.netron.removeListener(eventName, handler);
}
async set(defId, name, value) {
return this.getStubByDefinitionId(defId).set(name, value);
}
async get(defId, name) {
return this.processResult(await this.getStubByDefinitionId(defId).get(name));
}
async call(defId, method, args) {
return this.processResult(await this.getStubByDefinitionId(defId).call(method, args));
}
hasStub(defId) {
return this.stubs.has(defId);
}
getServiceNames() {
return this.netron.getServiceNames();
}
getStubByDefinitionId(defId) {
const stub = this.stubs.get(defId);
if (stub === void 0) {
throw new Error(`Unknown definition: ${defId}.`);
}
return stub;
}
getDefinitionById(defId) {
const stub = this.stubs.get(defId);
if (stub === void 0) {
throw new Error(`Unknown definition: ${defId}.`);
}
return stub.definition;
}
getDefinitionByServiceName(name) {
const stub = this.netron.services.get(name);
if (stub === void 0) {
throw new Error(`Unknown service: ${name}.`);
}
return stub.definition;
}
processResult(result) {
if (isServiceDefinition(result)) {
return this.queryInterfaceByDefId(result.id, result);
}
return result;
}
}
//# sourceMappingURL=local-peer.js.map