UNPKG

@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

102 lines 4.16 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Interface = void 0; const reference_1 = require("./reference"); const stream_reference_1 = require("./stream-reference"); const predicates_1 = require("./predicates"); const INTERNAL_READ_PROPERTIES = ['$def', '$peer', 'waitForAssigned', '$pendingPromises', 'then']; const INTERNAL_WRITE_PROPERTIES = ['$def', '$peer']; class Interface { constructor($def, $peer) { this.$def = $def; this.$peer = $peer; this.$pendingPromises = new Map(); return new Proxy(this, { get: (target, prop) => { if (!this.$def) { throw new Error('Invalid interface: Service definition is missing'); } if (this.$def?.meta.methods[prop]) { return async function (...args) { const processedArgs = target.$processArgs(args); return $peer?.call($def.id, prop, processedArgs); }; } if ($def?.meta.properties[prop]) { return $peer?.get($def.id, prop); } if (!INTERNAL_READ_PROPERTIES.includes(prop)) { throw new Error(`Unknown member: '${prop}' is not defined in the service interface`); } return Reflect.get(target, prop); }, set: (target, prop, value) => { if (INTERNAL_WRITE_PROPERTIES.includes(prop)) { Reflect.set(target, prop, value); return true; } if (!this.$def) { throw new Error('Invalid interface: Service definition is missing'); } if (!$def?.meta.properties[prop]) { throw new Error(`Unknown member: '${prop}' is not defined in the service interface`); } if (this.$def?.meta.properties[prop]?.readonly) { throw new Error(`Property is not writable: '${prop}' is marked as readonly`); } let resolvePromise = () => { }; let rejectPromise = () => { }; const promise = new Promise((resolve, reject) => { resolvePromise = resolve; rejectPromise = reject; }); this.$pendingPromises.set(prop, promise); (async () => { try { value = await this.$processValue(value); await $peer?.set($def.id, prop, value); resolvePromise(); this.$pendingPromises.delete(prop); } catch (error) { rejectPromise(error); } })(); return true; }, }); } async waitForAssigned(prop) { try { const promise = this.$pendingPromises.get(prop); return promise ? await promise : Promise.resolve(); } catch (error) { this.$pendingPromises.delete(prop); return Promise.reject(error); } } $processValue(value) { if ((0, predicates_1.isServiceInterface)(value)) { if (!value.$def) { throw new Error('Service interface is not valid: Missing service definition'); } return new reference_1.Reference(value.$def.id); } else if ((0, predicates_1.isNetronService)(value)) { throw Error('Unsupported value type: Direct service exposure is not yet implemented'); } else if ((0, predicates_1.isNetronStream)(value)) { return stream_reference_1.StreamReference.from(value); } return value; } $processArgs(args) { return args.map((arg) => this.$processValue(arg)); } static create(def, peer) { return new Interface(def, peer); } } exports.Interface = Interface; //# sourceMappingURL=interface.js.map