mirror of https://github.com/Hypfer/Valetudo.git
133 lines
3.3 KiB
JavaScript
133 lines
3.3 KiB
JavaScript
const EventEmitter = require("events").EventEmitter;
|
|
|
|
class ValetudoEventStore {
|
|
/**
|
|
*
|
|
* @param {object} options
|
|
*/
|
|
constructor(options) {
|
|
/** @private */
|
|
this.eventEmitter = new EventEmitter();
|
|
|
|
this.events = new Map();
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param {import("./valetudo_events/ValetudoEventHandlerFactory")} factory
|
|
*/
|
|
setEventHandlerFactory(factory) {
|
|
this.eventHandlerFactory = factory;
|
|
}
|
|
|
|
/**
|
|
* @public
|
|
*
|
|
* @param {string} id
|
|
* @returns {import("./valetudo_events/events/ValetudoEvent")}
|
|
*/
|
|
getById(id) {
|
|
// noinspection JSValidateTypes
|
|
return this.events.get(id);
|
|
}
|
|
|
|
/**
|
|
* @public
|
|
* @returns {Array<import("./valetudo_events/events/ValetudoEvent")>}
|
|
*/
|
|
getAll() {
|
|
// noinspection JSValidateTypes
|
|
return Array.from(this.events.values()).reverse();
|
|
}
|
|
|
|
/**
|
|
* @public
|
|
* @param {import("./valetudo_events/events/ValetudoEvent")} event
|
|
*/
|
|
raise(event) {
|
|
if (!this.events.has(event.id)) {
|
|
if (this.events.size >= LIMIT) {
|
|
this.events.delete(this.events.keys().next()?.value);
|
|
}
|
|
}
|
|
|
|
this.events.set(event.id, event);
|
|
this.eventEmitter.emit(EVENT_RAISED, event);
|
|
this.eventEmitter.emit(EVENTS_UPDATED, event);
|
|
}
|
|
|
|
/**
|
|
* Sometimes, events might stop being relevant due to external circumstances
|
|
* In these situations, this can be called to set them processed without an interaction
|
|
*
|
|
* @public
|
|
* @param {string} event_id
|
|
* @return {void}
|
|
*/
|
|
setProcessed(event_id) {
|
|
const event = this.getById(event_id);
|
|
|
|
if (!event) {
|
|
throw new Error("No such Event");
|
|
}
|
|
|
|
if (event.processed === true) {
|
|
return;
|
|
}
|
|
|
|
event.processed = true;
|
|
//Even though this isn't required as we're interfacing with it by reference. Just for good measure
|
|
this.events.set(event.id, event);
|
|
this.eventEmitter.emit(EVENTS_UPDATED, event);
|
|
}
|
|
|
|
/**
|
|
* @param {*} listener
|
|
* @public
|
|
*/
|
|
onEventRaised(listener) {
|
|
this.eventEmitter.on(EVENT_RAISED, listener);
|
|
}
|
|
|
|
/**
|
|
* @param {*} listener
|
|
* @public
|
|
*/
|
|
onEventsUpdated(listener) {
|
|
this.eventEmitter.on(EVENTS_UPDATED, listener);
|
|
}
|
|
|
|
/**
|
|
* @param {import("./valetudo_events/events/ValetudoEvent")} event
|
|
* @param {import("./valetudo_events/handlers/ValetudoEventHandler").INTERACTIONS} interaction
|
|
*/
|
|
async interact(event, interaction) {
|
|
if (!this.eventHandlerFactory) {
|
|
throw new Error("Missing Event handler Factory");
|
|
}
|
|
|
|
if (event.processed === true) {
|
|
throw new Error("Event is already processed");
|
|
}
|
|
|
|
const handler = this.eventHandlerFactory.getHandlerForEvent(event);
|
|
|
|
if (handler) {
|
|
const result = await handler.interact(interaction);
|
|
|
|
if (result === true) {
|
|
this.setProcessed(event.id);
|
|
}
|
|
} else {
|
|
throw new Error("Missing Handler for Event: " + event.__class);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
const LIMIT = 50;
|
|
const EVENT_RAISED = "event_raised";
|
|
const EVENTS_UPDATED = "events_updated";
|
|
|
|
module.exports = ValetudoEventStore;
|