UNPKG

minsky-kit

Version:
183 lines (144 loc) 5.24 kB
// imports import EventDispatcher from './EventDispatcher'; import Ticker from './Ticker'; import MQDefinition from './MQDefinition'; // private static // class definition export default class MQManager extends EventDispatcher { // constructor constructor (args = {}, objectName = 'MQ MGR') { args.debug = args.debug || false; // call super constructor super(args, objectName); // set properties this._definitions = []; this._matchChangedDefinitions = []; // debouncer this.debouncer = new Ticker({ timeout: args.debounce || 0, }); // prep some listeners this.blm.add('onMqMatchChange', onMqMatchChange); this.blm.add('onMqWeightChange', onMqWeightChange); // add listeners this.debouncer.on('timeout', this.blm.add('onDebounceTimeout', onDebounceTimeout)); } // methods add (mqDefinitions) { this.log('add', mqDefinitions); // force it to be an array mqDefinitions = forceArray(mqDefinitions); // create instances or just add them if they are already an instance mqDefinitions.forEach((definition) => { // make sure it's an instance if (!instanceOfMQDefinition(definition)) { // clone definition for altering const defClone = { ...definition }; // force debug state defClone.debug = this._debug; // use clone defintiion to create instance definition = new MQDefinition(defClone); } // add listeners definition.on('matchChange', this.blm.get('onMqMatchChange')); definition.on('weightChange', this.blm.get('onMqWeightChange')); // apply weight if none is given if (!definition.weight) { definition.weight = this._definitions.length ? this._definitions[this._definitions.length - 1].weight + 1 : 0; } // add to list this._definitions.push(definition); }); // re-order list by weight fixOrderOfDefinitions(this._definitions); } get (mqDefinition) { if (!instanceOfMQDefinition(mqDefinition)) { const keys = Object.keys(mqDefinition); return this._definitions.filter((def) => { for (const k of keys) { if (this.mqDefinitions[k] !== def[k]) return false; } return []; }); } if (this._definitions.indexOf(mqDefinition)) { return [mqDefinition]; } return []; } remove (mqDefinitions) { this.log('remove', mqDefinitions); // force it to be an array mqDefinitions = forceArray(mqDefinitions); for (const def of mqDefinitions) { if (!instanceOfMQDefinition(def)) { if (this.get(def).length) { this.log('Given definition was not a correct instance, filtering will be done + all matching will be removed.'); this.remove(def); } } else { const index = this._definitions.indexOf(def); if (index > -1) this._definitions.splice(index, 1); } } // re-order list by weight fixOrderOfDefinitions(this._definitions); } check () { this.log('check'); this._definitions.forEach((def) => def.check()); } resetMatches () { this.log('reset matches'); this._definitions.forEach((def) => def.resetMatch()); } destroy () { // call super super.destroy(); } // statics get matchingDefinitions () { return this._definitions.filter((def) => def.matches); } } // utils function fixOrderOfDefinitions (definitions) { // re-order list by weight return definitions.sort((def1, def2) => def1.weight - def2.weight); } function instanceOfMQDefinition (definition) { return definition instanceof MQDefinition; } function forceArray (item) { if (!Array.isArray(item)) item = [item]; return item; } function dispatchMatchChanges () { this.dispatch('matchChanges', { definitions: fixOrderOfDefinitions(this._matchChangedDefinitions.slice()), }); // reset length for new list this._matchChangedDefinitions.length = 0; } // event handlers function onMqMatchChange (e) { this.log('MQ Match Change', e.currentTarget.name, e.currentTarget._query); // keep definition for debounced dispatch, make sure it happens only once if (this._matchChangedDefinitions.indexOf(e.currentTarget) === -1) this._matchChangedDefinitions.push(e.currentTarget); // instant dispatch this.dispatch('singleMatchChange', { definition: e.currentTarget, }); // start debouncer this.debouncer.start(true); } function onMqWeightChange (e) { this.log('MQ Weight Change', e.currentTarget.name, e.currentTarget._query); // re-order items fixOrderOfDefinitions(this._definitions); } function onDebounceTimeout () { dispatchMatchChanges.call(this); }