const EventEmitter = require('events').EventEmitter
, absMethod = 'Abstract method'
, { Observable, fromEvent } = require('rxjs')
, { filter } = require('rxjs/operators')
, { Schedule, ScheduleEvent, PreliminaryScheduleEvent } = require('./Schedule');
/**
* Generic scheduler class that can emit events of type T. The purpose
* of this scheduler is to notify when an event occurs or something should
* be executed. It shall be used as base-class to other schedulers. It is
* not to be used for executing jobs, use an appropriate queue for that.
* Although providing Observables, Schedulers never error or complete.
*
* @author Sebastian Hönel <development@hoenel.net>
* @extends {EventEmitter}
* @template T
*/
class Scheduler extends EventEmitter {
/**
* @param {Symbol} schedulerSymbol The symbol that is used for emitting
* events from this Scheduler.
*/
constructor(schedulerSymbol) {
super();
/** @protected */
this._symbol = schedulerSymbol;
/**
* @protected
* @type {Observable<T>}
*/
this._observable = fromEvent(this, schedulerSymbol);
};
/**
* Returns the same Observable<T> to every subscriber. Note that this Observable
* never errors or drains. You will need to observe a particular Schedule to get
* its errors or completion. The Observable never errors or completes.
*
* @template T Must be of type ScheduleEvent or more derived.
* @type {Observable<T|ScheduleEvent>}
*/
get observable() {
return this._observable;
};
/**
* @template T Must be of type ScheduleEvent or more derived.
* @param {T|Schedule} schedule
* @returns {Observable<T|ScheduleEvent>} An Observable for the designated schedule.
*/
getObservableForSchedule(schedule) {
return this.observable.pipe(filter(evt => evt.schedule === schedule));
};
/**
* Add a Schedule to this scheduler. This is an abstract method.
*
* @param {Schedule} schedule
* @returns {this}
*/
addSchedule(schedule) {
throw new Error(absMethod);
};
/**
* Remove a Schedule from this scheduler. This is an abstract method.
*
* @param {Schedule} schedule
* @returns {this}
*/
removeSchedule(schedule) {
throw new Error(absMethod);
};
/**
* Removes all Schedules from this scheduler. This is an abstract methdod.
*
* @returns {Array<Schedule>} All Schedules as array.
*/
removeAllSchedules() {
throw new Error(absMethod);
};
/**
* Returns a value indicating whether this Scheduler has the given
* Schedule. This is an abstract method.
*
* @param {Schedule} schedule
* @returns {this}
*/
hasSchedule(schedule) {
throw new Error(absMethod);
};
/**
* A generator that supposedly yields all schedules' preliminary events.
*
* @template T Must be of type PreliminaryScheduleEvent or more derived.
* @param {Date} [after] Optional. Defaults to undefined.
* @param {Date} [before] Optional. Defaults to undefined.
* @returns {IterableIterator<PreliminaryScheduleEvent<T|Schedule, any>>}
*/
*preliminaryEvents(after, before) {
};
};
module.exports = Object.freeze({
Scheduler
});