@openhps/core
Version:
Open Hybrid Positioning System - Core component
98 lines • 2.9 kB
JavaScript
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);
});
}
});
}
}