@rschedule/rschedule
Version:
A typescript library for working with recurring dates and events.
69 lines (54 loc) • 2.13 kB
text/typescript
import { DateAdapter } from '../date-adapter';
import { DateTime } from '../date-time';
import { IRunArgs } from '../interfaces';
import { IOperatorConfig, Operator, OperatorFnOutput } from './interface';
import { IterableWrapper, streamPastEnd, streamPastSkipToDate } from './utilities';
const UNIQUE_OPERATOR_ID = Symbol.for('cba869a4-13bf-407a-9648-18cc66261231');
/**
* An operator function which deduplicates an occurrence stream. Occurrence
* `duration` is currently ignored.
*/
export function unique<T extends typeof DateAdapter>(): OperatorFnOutput<T> {
return (options: IOperatorConfig<T>) => new UniqueOperator([], options);
}
export class UniqueOperator<T extends typeof DateAdapter> extends Operator<T> {
static isUniqueOperator(object: unknown): object is UniqueOperator<any> {
return !!(super.isOperator(object) && (object as any)[UNIQUE_OPERATOR_ID]);
}
protected readonly [UNIQUE_OPERATOR_ID] = true;
/** Not actually used but necessary for IRunnable interface */
set(_: 'timezone', value: string | null) {
return new UniqueOperator([], {
...this.config,
base: this.config.base && this.config.base.set('timezone', value),
timezone: value,
});
}
/** @internal */
*_run(args: IRunArgs = {}): IterableIterator<DateTime> {
if (!this.config.base) return;
const stream = new IterableWrapper(this.config.base._run(args));
while (!stream.done) {
const yieldArgs = yield this.normalizeRunOutput(stream.value);
const lastValue = stream.value;
stream.picked();
if (yieldArgs && yieldArgs.skipToDate) {
while (
!streamPastEnd(stream, args) &&
!streamPastSkipToDate(stream, yieldArgs.skipToDate, args)
) {
stream.picked();
}
}
while (!streamPastEnd(stream, args) && stream.value.isEqual(lastValue)) {
stream.picked();
}
}
}
protected calculateIsInfinite() {
return !!(this.config.base && this.config.base.isInfinite);
}
protected calculateHasDuration() {
return !!(this.config.base && this.config.base.hasDuration);
}
}