@openhps/core
Version:
Open Hybrid Positioning System - Core component
202 lines • 6.68 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.GraphNode = void 0;
const tslib_1 = require("tslib");
const uuid_1 = require("uuid");
const decorators_1 = require("../../data/decorators");
const AsyncEventEmitter_1 = require("../../_internal/AsyncEventEmitter");
const PushPromise_1 = require("../PushPromise");
const PullPromise_1 = require("../PullPromise");
let GraphNode = class GraphNode extends AsyncEventEmitter_1.AsyncEventEmitter {
constructor() {
super();
/**
* Unique identifier of node.
*/
this.uid = (0, uuid_1.v4)();
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_1.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_1.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));
}
};
exports.GraphNode = GraphNode;
tslib_1.__decorate([
(0, decorators_1.SerializableMember)(),
tslib_1.__metadata("design:type", String)
], GraphNode.prototype, "name", void 0);
tslib_1.__decorate([
(0, decorators_1.SerializableMember)(),
tslib_1.__metadata("design:type", String)
], GraphNode.prototype, "uid", void 0);
exports.GraphNode = GraphNode = tslib_1.__decorate([
(0, decorators_1.SerializableObject)(),
tslib_1.__metadata("design:paramtypes", [])
], GraphNode);
//# sourceMappingURL=GraphNode.js.map