UNPKG

@openhps/core

Version:

Open Hybrid Positioning System - Core component

98 lines 2.9 kB
import { DataSerializer } from '../data/DataSerializer'; import { v4 as uuidv4 } from 'uuid'; import { ServiceProxy } from './_internal/ServiceProxy'; /** * A worker service proxy will forward function calls to an observable. * This observable can be a remote process or worker. It is mainly used * to proxy function calls from a worker thread to the main thread. */ export class WorkerServiceProxy extends ServiceProxy { constructor(options) { super(); this._promises = new Map(); this.options = options; this.uid = options.uid; if (this.options.responseObservable) { this.options.responseObservable.subscribe(this._onOutput.bind(this)); } } _onOutput(next) { if (this._promises.has(next.id)) { const promise = this._promises.get(next.id); if (next.success) { if (next.result === undefined) { promise.resolve(); } else if (Array.isArray(next.result)) { const result = []; next.result.forEach(r => { if (r['__type']) { result.push(DataSerializer.deserialize(r)); } else { result.push(r); } }); promise.resolve(result); } else { if (next.result['__type']) { promise.resolve(DataSerializer.deserialize(next.result)); } else { promise.resolve(next.result); } } } else { promise.reject(next.result); } this._promises.delete(next.id); } } get(target, p) { const ownResult = this[p]; if (ownResult) { return ownResult; } else if (p === 'target') { return target; } return this.createHandler(target, p); } /** * Create handler function for a specific property key * @param {Service} target Target service * @param {string|number|symbol} p Property * @returns {Function} Handler function */ createHandler(target, p) { return (...args) => new Promise((resolve, reject) => { const uuid = uuidv4(); this._promises.set(uuid, { resolve, reject }); const serializedArgs = []; args.forEach(arg => { if (DataSerializer.findTypeByName(arg.constructor.name)) { serializedArgs.push(DataSerializer.serialize(arg)); } else { serializedArgs.push(arg); } }); // Service call const call = { id: uuid, serviceUID: this.uid, method: p, parameters: serializedArgs }; if (this.options.callObservable) { // Forward call to observable this.options.callObservable.next(call); } else { // Forward call to promise this.options.callFunction(call).then(response => { this._onOutput(response); }).catch(response => { this._onOutput(response); }); } }); } }