class Defmulti {
constructor(dispatchFn, defaultDispatchValue = "default") {
this.dispatchFn = dispatchFn;
this.defaultDispatchValue = defaultDispatchValue;
this.dispatchMap = {};
Object.defineProperties(this, {
_list: { value: [], writable: true }
});
}
get value() {
return this;
}
addMethod(dispatchVal, method) {
this.dispatchMap[dispatchVal] = method;
this.dispatchEvent({ value: this.dispatchMap });
return method;
}
addMethodObserved(dispatchVal, method) {
this.dispatchMap[dispatchVal] = method;
this.dispatchEvent({ value: this.dispatchMap });
return Generators.observe(next => {
next(method);
return () => this.removeMethod(dispatchVal);
});
}
removeMethod(dispatchVal) {
delete this.dispatchMap[dispatchVal];
this.dispatchEvent({ value: this.dispatchMap });
}
removeAllMethods() {
this.dispatchMap = {};
this.dispatchEvent({ value: this.dispatchMap });
}
dispatch(...args) {
const dval = this.dispatchFn(...args);
const fn =
this.dispatchMap[dval] || this.dispatchMap[this.defaultDispatchValue];
if (fn) return fn(...args);
else throw `No function defined for dispatch value ${dval}`;
}
addEventListener(type, listener) {
if (type != "input" || this._list.includes(listener)) return;
this._list = [listener].concat(this._list);
}
removeEventListener(type, listener) {
if (type != "input") return;
this._list = this._list.filter(l => l !== listener);
}
dispatchEvent(event) {
const p = Promise.resolve(event);
this._list.forEach(l => p.then(l));
}
}