UNPKG

@openhps/core

Version:

Open Hybrid Positioning System - Core component

179 lines 5.42 kB
import { __decorate, __metadata } from "tslib"; import { v4 as uuidv4 } from 'uuid'; import { SerializableMember, SerializableObject } from '../../data/decorators'; import { AsyncEventEmitter } from '../../_internal/AsyncEventEmitter'; import { PushPromise } from '../PushPromise'; import { PullPromise } from '../PullPromise'; let GraphNode = class GraphNode extends AsyncEventEmitter { constructor() { super(); /** * Unique identifier of node. */ this.uid = uuidv4(); this._ready = false; this._available = true; this.prependOnceListener('ready', () => { this._ready = true; }); this.on('error', this._onError.bind(this)); this.on('completed', this._onCompleted.bind(this)); } get inletNode() { return this; } get outletNode() { return this; } /** * Graph logger * @param {string} level Logging level * @param {string} message Message * @param {any} data Data to include in log */ logger(level, message, data) { if (typeof message === 'object') { this.graph.logger(level, JSON.stringify(message)); } else { this.graph.logger(level, message, data); } } isReady() { return this._ready; } /** * Check if the node is available for accepting push requests * @returns {boolean} Is the node available to push */ isAvailable() { return this._available; } /** * Get the outgoing edges * @returns {Array<Outlet<DataFrame>>} Outgoing edges */ get outlets() { return this.graph.edges.filter(edge => edge.inputNode.uid === this.uid); } /** * Get the incoming edges * @returns {Array<Inlet<DataFrame>>} Incoming edges */ get inlets() { return this.graph.edges.filter(edge => edge.outputNode.uid === this.uid); } emit(name, ...args) { if (name === 'ready') { return super.emit('ready', this); } return super.emit(name, ...args); } on(name, listener) { return super.on(name, listener); } once(name, listener) { return super.once(name, listener); } /** * Send a pull request to the node * @param {PullOptions} [options] Pull options * @returns {Promise<void>} Pull promise */ pull(options) { return new PullPromise((resolve, reject) => { const callbackPromises = []; this.listeners('pull').forEach(callback => { callbackPromises.push(callback(options)); }); if (callbackPromises.length === 0) { this.inlets.forEach(inlet => { callbackPromises.push(inlet.pull(options)); }); } Promise.all(callbackPromises).then(() => { resolve(); }).catch(reject); }); } /** * Push data to the node * @param {DataFrame | DataFrame[]} data Data frame to push * @param {PushOptions} [options] Push options * @returns {PushPromise<void>} Push promise */ push(data, options = {}) { return new PushPromise((resolve, reject, completed) => { if (data === null || data === undefined) { return reject(new Error('Node received null data frame!')); } const listeners = this.listeners('push'); if (listeners.length === 0) { // Forward push, resolve before outlets resolve const pushPromises = this.outlets.map(outlet => outlet.push(data, options)); // Resolve resolve(); Promise.all(pushPromises).then(() => { completed(); }).catch(() => { // Do nothing, promimse is already resolved }); } else { this._available = false; Promise.all(listeners.map(callback => callback(data, options))).then(() => { this._available = true; this.emit('available'); resolve(); completed(); }).catch(reject); } }); } /** * Promise once the node is available * @returns {Promise} Promise when the node is available */ onceAvailable() { return new Promise(resolve => { if (this.isAvailable()) { resolve(); } else { this.once('available', () => { resolve(); }); } }); } /** * Promise once the frame is completed * @param {string} frameUID Frame UID * @returns {Promise} Promise when the frame is completed */ onceCompleted(frameUID) { return new Promise((resolve, reject) => { const completedListener = function (event) { if (event.frameUID === frameUID) { this.removeListener('completed', completedListener); this.removeListener('error', completedListener); if (event.error) { reject(event); } else { resolve(event); } } }; this.on('completed', completedListener.bind(this)); this.on('error', completedListener.bind(this)); }); } _onError(error) { this.inlets.forEach(inlet => inlet.emit('error', error)); } _onCompleted(event) { this.logger('debug', `Node ${this.name} completed frame ${event.frameUID}`); this.inlets.forEach(inlet => inlet.emit('completed', event)); } }; __decorate([SerializableMember(), __metadata("design:type", String)], GraphNode.prototype, "name", void 0); __decorate([SerializableMember(), __metadata("design:type", String)], GraphNode.prototype, "uid", void 0); GraphNode = __decorate([SerializableObject(), __metadata("design:paramtypes", [])], GraphNode); export { GraphNode };