class RecentMonitor {
constructor(max, ...monitors) {
this.max = max;
this.nextId = 0;
monitors.forEach(m => m.monitorId = this.nextId++);
this.queue = new MultiMonitor(...monitors);
this._history = new Map();
this._done = new Map();
this.results = new EventQueue();
const watcher = this.queue.watcher();
Promise.resolve()
.then(async () => {
while (!this.ended) {
const v = await watcher.next();
if (v.value && v.value.terminated) {
this.ended = true;
this.results.end();
} else if (v.value && v.value.done) {
this._done.set(v.value.monitor.monitorId, v.value);
if (this._done.size > this.max) {
[...this._done.keys()].slice(0, this._done.size - this.max)
.forEach(k => {
this._done.delete(k);
this._history.delete(k);
});
}
this.results.notify(this._history);
} else {
this._history.delete(v.value.monitor.monitorId);
this._history.set(v.value.monitor.monitorId, {...v.value, id: v.value.monitor.monitorId});
const historyList = this._history.values();
if (this._history.length > this.max) {
const nhistory = new Map();
let ndone = 0;
for (const h of this._history) {
if (!h.done && !h.terminated) {
nhistory.set(h.monitor.monitorId, h);
} else if (++ndone <= this.max) {
nhistory.set(h.monitor.monitorId, h);
}
}
this._history = nhistory;
}
this.results.notify(this._history);
}
}
});
}
add(monitor) {
monitor.monitorId = this.nextId++;
return this.queue.add(monitor);
}
history() {
return [...this._history.values()];
}
watcher() {
return this.results.watcher();
}
end() {
this.queue.end();
}
}