@openhps/core
Version:
Open Hybrid Positioning System - Core component
114 lines • 3.92 kB
JavaScript
import { __decorate, __metadata } from "tslib";
import { Node } from '../Node';
import { NodeData } from '../service';
import { SerializableObject } from '../data/decorators';
/**
* Node that processes a dataframe or the contained objects.
*
* ## Usage
*
* ### Creating a ProcessingNode
* Processing nodes hide the push and pull functionalities from a regular node. When a push is received, this
* data frame is provided to the ```process()``` method that has to be implemented. When a pull is received, this pull is
* forwarded to all incoming nodes.
* ```typescript
* import { DataFrame, DataObject, ProcessingNode } from '@openhps/core';
*
* export class CustomProcessingNode<In extends DataFrame, Out extends DataFrame> extends ProcessingNode<In, Out> {
* // ...
* public process(data: In, options?: GraphOptions): Promise<Out> {
* return new Promise<Out>((resolve, reject) => {
* // ... process/manipulate the data frame
* data.addObject(new DataObject("custom_process_object"));
* resolve(data);
* });
* }
* }
* ```
*
*
<script type="application/ld+json">
{
"@context": "http://purl.org/poso/",
"@type": "PositioningTechnique",
}
</script>
* @category Processing node
*/
let ProcessingNode = class ProcessingNode extends Node {
constructor(options) {
super(options);
this.options.frameFilter = this.options.frameFilter || (() => true);
this.on('push', this._onPush.bind(this));
}
_onPush(frame, options) {
return new Promise((resolve, reject) => {
const processPromises = [];
if (Array.isArray(frame)) {
processPromises.push(this.processBulk(frame.filter(frame => this.options.frameFilter(frame))));
frame.filter(frame => !this.options.frameFilter(frame)).forEach(f => {
processPromises.push(Promise.resolve(f));
});
} else if (this.options.frameFilter(frame)) {
processPromises.push(this.process(frame, options));
} else {
processPromises.push(Promise.resolve(frame));
}
Promise.all(processPromises).then(results => {
const output = [];
results.forEach(res => {
if (Array.isArray(res)) {
output.push(...res.filter(res => res !== undefined));
} else if (res !== undefined) {
output.push(res);
}
});
if (output.length > 0) {
this.outlets.forEach(outlet => outlet.push(output.length === 1 ? output[0] : output, options));
}
resolve();
}).catch(ex => {
if (ex === undefined) {
this.logger('warn', `Exception thrown in processing node ${this.uid} but no exception given!`);
}
reject(ex);
});
});
}
findNodeDataService() {
return this.model.findDataService(NodeData);
}
/**
* Get node data
* @param {DataObject} dataObject Data object to get node data from
* @param {any} [defaultData] Default data
* @returns {Promise<any>} Promise with node data
*/
getNodeData(dataObject, defaultData = undefined) {
return new Promise((resolve, reject) => {
this.findNodeDataService().findData(this.uid, dataObject).then(data => {
if (!data) {
resolve(defaultData);
} else {
resolve(data);
}
}).catch(reject);
});
}
/**
* Set node data
* @param {DataObject} dataObject Data object to store data for
* @param {any} data Data to store
* @returns {Promise<any>} Promise with stored node data
*/
setNodeData(dataObject, data) {
return new Promise((resolve, reject) => {
this.findNodeDataService().insertData(this.uid, dataObject, data).then(resolve).catch(reject);
});
}
processBulk(frames) {
return Promise.all(frames.map(frame => this.process(frame)));
}
};
ProcessingNode = __decorate([SerializableObject(), __metadata("design:paramtypes", [Object])], ProcessingNode);
export { ProcessingNode };