UNPKG

@devgrid/netron

Version:
94 lines 3.56 kB
import { Reference } from './reference'; import { isNetronService, isServiceInterface } from './predicates'; const INTERNAL_READ_PROPERTIES = ['$def', '$peer', 'waitForAssigned', '$pendingPromises', 'then']; const INTERNAL_WRITE_PROPERTIES = ['$def', '$peer']; export 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'); } 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}'`); } 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'); } if (!$def?.meta.properties[prop]) { throw new Error(`Unknown member: '${prop}'`); } if (this.$def?.meta.properties[prop]?.readonly) { throw new Error(`Property is not writable: ${prop}`); } 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 (isServiceInterface(value)) { if (!value.$def) { throw new Error('Service interface is not valid'); } return new Reference(value.$def.id); } else if (isNetronService(value)) { throw Error('Unsupported value type'); } return value; } $processArgs(args) { return args.map((arg) => this.$processValue(arg)); } static create(def, peer) { return new Interface(def, peer); } } //# sourceMappingURL=interface.js.map