import { Utils } from '../common/Utils';
const __ = {
private: Symbol('private'),
}
/**
* @class AsyncSelector
* The async selector.
* @memberof THING
*/
class AsyncSelector {
constructor(param = {}) {
this[__.private] = {};
let _private = this[__.private];
_private.queryResolves = new Map();
_private.queryOrderID = 1;
_private.commands = [];
_private.worker = null;
// Create selector worker
_private.worker = new Worker(param['workerUrl']);
_private.worker.onmessage = (ev) => {
let data = ev.data;
let type = data.type;
switch (type) {
case 'queryResult':
let queryOrderID = data.queryOrderID;
let orderIDs = data.orderIDs;
let resolve = _private.queryResolves.get(queryOrderID);
if (resolve) {
_private.queryResolves.delete(queryOrderID);
resolve({ orderIDs });
}
break;
default:
break;
}
}
}
// #region Private
_flushCommands() {
let _private = this[__.private];
let commands = _private.commands;
// Flush commands
if (commands.length) {
_private.worker.postMessage({
type: 'commands',
commands
});
commands.length = 0;
}
}
// #endregion
addObject(object) {
let _private = this[__.private];
let parent = object.parent;
_private.commands.push({
type: 'addObject',
object: {
types: object.__types,
orderId: object.orderId,
parentObjectOrderID: parent ? parent.orderId : null,
id: object.id,
uuid: object.uuid,
name: object.name,
queryable: object.queryable,
}
});
}
removeObject(object) {
let _private = this[__.private];
_private.commands.push({
type: 'removeObject',
orderId: object.orderId
});
}
updateObjectAttribute(object, key, value) {
let _private = this[__.private];
_private.commands.push({
type: key,
orderId: object.orderId,
value
});
}
queryAsync(root, recursive, condition) {
let _private = this[__.private];
return new Promise((resolve, reject) => {
this._flushCommands();
// Create query parameters
let param = {
type: 'query',
queryOrderID: _private.queryOrderID++,
rootOrderID: root.orderId,
recursive,
condition
};
// Wait for query result
_private.queryResolves.set(param.queryOrderID, resolve);
// Start to query in background thread
_private.worker.postMessage(param);
});
}
selectAsync(objects, condition) {
let _private = this[__.private];
return new Promise((resolve, reject) => {
this._flushCommands();
// Create query parameters
let param = {
type: 'select',
queryOrderID: _private.queryOrderID++,
objectOrderIDs: objects.map(object => { return object.orderId; }),
condition
};
// Wait for query result
_private.queryResolves.set(param.queryOrderID, resolve);
// Start to query in background thread
_private.worker.postMessage(param);
});
}
}
export { AsyncSelector };