beaverjs
Version:
An abstraction around WebExtension messaging
76 lines • 2.56 kB
JavaScript
export class BaseEventHandler {
constructor() {
this.eventMap = new Map();
queueMicrotask(() => this.setup());
}
insertEvent(key, eventHandler) {
// all the "as ..." are necessary because Typescript doesn't like inserting EventMap[K] into EventMap[keyof EventMap]
// even though K extends keyof EventMap. This is probably due to the definition of `eventMap`
if (this.eventMap.has(key)) {
const entry = this.eventMap.get(key);
if (Array.isArray(entry)) {
// 2 or more entries
entry.push(eventHandler);
}
else {
// only one entry
this.eventMap.set(key, [
entry,
eventHandler,
]);
}
}
else {
this.eventMap.set(key, eventHandler);
}
}
on(key, fn) {
this.insertEvent(key, fn);
return this;
}
once(key, fn) {
this.insertEvent(key, { fn, once: true });
return this;
}
emit(key, data, ...args) {
const serialized = this.serialize(key, data);
this.sendEvent(serialized, ...args);
}
handleEvent(key, data, sender) {
const entry = this.eventMap.get(key);
if (!entry)
return;
if (typeof entry === 'function') {
// "fast path" - no cleanup or anything
entry(data, sender);
return;
}
if (Array.isArray(entry)) {
const result = entry.filter(value => {
if (typeof value === 'function') {
value(data, sender);
return true;
}
value.fn(data, sender);
return value.once;
});
if (result.length === 0)
this.eventMap.delete(key);
else if (result.length === 1)
this.eventMap.set(key, result[0]);
else
this.eventMap.set(key, result);
}
else {
if (entry.once)
this.eventMap.delete(key);
entry.fn(data, sender);
}
}
handleSerialized(serialized, sender) {
const deserialized = this.deserialize(serialized);
// another function for better type checking
this.handleEvent(deserialized.type, deserialized.data, sender);
}
}
//# sourceMappingURL=BaseEventHandler.js.map