UNPKG

@openhps/core

Version:

Open Hybrid Positioning System - Core component

220 lines 9.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.WorkerBase = void 0; const tslib_1 = require("tslib"); require("reflect-metadata"); const observable_1 = require("threads/observable"); const __1 = require(".."); // external @openhps/core class WorkerBase { constructor() { this.pullOutput = new observable_1.Subject(); this.pushOutput = new observable_1.Subject(); this.serviceOutputCall = new observable_1.Subject(); this.serviceOutputResponse = new observable_1.Subject(); this.eventOutput = new observable_1.Subject(); this.customMethods = new Map(); } setShape(shape) { this.shape = shape; } init(config) { return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () { this.config = config; const importFn = typeof process !== 'object' ? config.type === 'module' ? (file) => Promise.resolve(`${file}`).then(s => require(s)) // ES6 : (file) => Promise.resolve(importScripts(/* webpackIgnore: true */ file)) // CJS : (file) => Promise.resolve(require(/* webpackIgnore: true */ file)); // eslint-disable-line // Set global dir name __dirname = config.directory; // eslint-disable-line // Load external scripts if (config.imports && config.imports.length > 0) { config.imports.forEach((importFile) => { importFn(importFile); }); } // Create model const modelBuilder = __1.ModelBuilder.create(); // Add remote worker services if not already added this.config.services.forEach((service) => { if (service.dataType) { const DataType = __1.DataSerializer.findTypeByName(service.dataType); modelBuilder.addService(new __1.DummyDataService(service.uid, DataType), new __1.WorkerServiceProxy({ uid: service.uid, callObservable: this.serviceOutputCall, responseObservable: this.serviceOutputResponse, })); } else { modelBuilder.addService(new __1.DummyService(service.uid), new __1.WorkerServiceProxy({ uid: service.uid, callObservable: this.serviceOutputCall, responseObservable: this.serviceOutputResponse, })); } }); this._initModel(modelBuilder); // eslint-disable-next-line const path = this.config.imports.length > 0 ? undefined : (typeof process !== 'object' ? undefined : require('path')); try { if (this.config.serialized) { const traversalBuilder = modelBuilder.from(); const modelOrNode = __1.ModelSerializer.deserializeNode(this.config.serialized); traversalBuilder.via(modelOrNode); traversalBuilder.to(); } else if (this.config.builder) { const traversalBuilder = modelBuilder.from(); const builderCallback = eval(this.config.builder); builderCallback(traversalBuilder, modelBuilder, this.config.args); traversalBuilder.to(); } else if (this.config.shape) { const graph = yield importFn(path ? path.join(__dirname, this.config.shape) : this.config.shape); if (graph) { modelBuilder.addShape(graph.default); } } else if (this.shape) { modelBuilder.addShape(this.shape); } } catch (ex) { // Error deserializing, did you import the nodes? reject(ex); return; } modelBuilder .build() .then((m) => { this.model = m; // Load methods this.config.methods.forEach((serializedMethod) => { const method = eval(serializedMethod.handlerFn); this.customMethods.set(serializedMethod.name, (model, ...args) => { return Promise.resolve(method(model, ...args)); }); }); resolve(); }) .catch(reject); })); } invokeMethod(methodName, ...args) { return new Promise((resolve, reject) => { const method = this.customMethods.get(methodName); if (!method) { return reject(new Error(`Unable to invoke unknown method '${methodName}'!`)); } method(this.model, ...args.map((a) => __1.DataSerializer.deserialize(a))) .then((result) => { resolve(__1.DataSerializer.serialize(result)); }) .catch(reject); }); } /** * Pull from this work * @param {PullOptions} [options] Pull options * @returns {Promise<void>} Pull promise */ pull(options) { return this.model.pull(options); } /** * Push to this worker * @param {DataFrame} frame Data frame * @param {PushOptions} [options] Push options * @returns {Promise<void>} Push promise */ push(frame, options) { return this.model.push(__1.DataSerializer.deserialize(frame), options); } /** * Init the model internal input and internal output * @param {ModelBuilder} modelBuilder Model builder */ _initModel(modelBuilder) { const internalSource = new __1.CallbackSourceNode((options) => { // Send a pull request to the main thread this.pullOutput.next(options); return undefined; }); const internalSink = new __1.CallbackSinkNode((frame) => { // Serialize the frame and transmit it to the main thread this.pushOutput.next(__1.DataSerializer.serialize(frame)); }); modelBuilder.graph.deleteNode(modelBuilder.graph.internalSource); modelBuilder.graph.internalSource = internalSource; internalSource.on('error', (event) => { this.eventOutput.next({ name: 'error', event, }); }); internalSource.on('completed', (event) => { this.eventOutput.next({ name: 'completed', event, }); }); modelBuilder.graph.addNode(modelBuilder.graph.internalSource); modelBuilder.graph.deleteNode(modelBuilder.graph.internalSink); modelBuilder.graph.internalSink = internalSink; modelBuilder.graph.addNode(modelBuilder.graph.internalSink); } findAllServices() { return new Promise((resolve) => { const services = this.model.findAllServices(); const servicesArray = services .filter((service) => !(service instanceof __1.DummyDataService || service instanceof __1.DummyService)) .map((service) => { // Services are wrapped in a proxy. Get prototype const serviceBase = Object.getPrototypeOf(service); return { uid: service.uid, type: serviceBase.constructor.name, dataType: service instanceof __1.DataService ? service.driver.dataType.name : undefined, }; }); resolve(servicesArray); }); } callService(call) { return new Promise((resolve, reject) => { const service = this.model.findDataService(call.serviceUID) || this.model.findService(call.serviceUID); if (service[call.method]) { const serializedParams = call.parameters; const params = []; serializedParams.forEach((param) => { if (param['__type']) { params.push(__1.DataSerializer.deserialize(param)); } else { params.push(param); } }); const promise = service[call.method](...params); Promise.resolve(promise) .then((_) => { if (Array.isArray(_)) { const result = []; _.forEach((r) => { result.push(__1.DataSerializer.serialize(r)); }); resolve({ id: call.id, success: true, result }); } else { const result = __1.DataSerializer.serialize(_); resolve({ id: call.id, success: true, result }); } }) .catch((ex) => { reject({ id: call.id, success: false, result: ex }); }); } }); } } exports.WorkerBase = WorkerBase; //# sourceMappingURL=WorkerBase.js.map