-
-
Notifications
You must be signed in to change notification settings - Fork 378
/
ValetudoEventStore.js
132 lines (111 loc) · 3.3 KB
/
ValetudoEventStore.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
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;