import { Observable } from '../Observable'; 
 | 
import { SchedulerLike } from '../types'; 
 | 
import { async as asyncScheduler } from '../scheduler/async'; 
 | 
import { isScheduler } from '../util/isScheduler'; 
 | 
import { isValidDate } from '../util/isDate'; 
 | 
  
 | 
/** 
 | 
 * Creates an observable that will wait for a specified time period, or exact date, before 
 | 
 * emitting the number 0. 
 | 
 * 
 | 
 * <span class="informal">Used to emit a notification after a delay.</span> 
 | 
 * 
 | 
 * This observable is useful for creating delays in code, or racing against other values 
 | 
 * for ad-hoc timeouts. 
 | 
 * 
 | 
 * The `delay` is specified by default in milliseconds, however providing a custom scheduler could 
 | 
 * create a different behavior. 
 | 
 * 
 | 
 * ## Examples 
 | 
 * 
 | 
 * Wait 3 seconds and start another observable 
 | 
 * 
 | 
 * You might want to use `timer` to delay subscription to an 
 | 
 * observable by a set amount of time. Here we use a timer with 
 | 
 * {@link concatMapTo} or {@link concatMap} in order to wait 
 | 
 * a few seconds and start a subscription to a source. 
 | 
 * 
 | 
 * ```ts 
 | 
 * import { of, timer, concatMap } from 'rxjs'; 
 | 
 * 
 | 
 * // This could be any observable 
 | 
 * const source = of(1, 2, 3); 
 | 
 * 
 | 
 * timer(3000) 
 | 
 *   .pipe(concatMap(() => source)) 
 | 
 *   .subscribe(console.log); 
 | 
 * ``` 
 | 
 * 
 | 
 * Take all values until the start of the next minute 
 | 
 * 
 | 
 * Using a `Date` as the trigger for the first emission, you can 
 | 
 * do things like wait until midnight to fire an event, or in this case, 
 | 
 * wait until a new minute starts (chosen so the example wouldn't take 
 | 
 * too long to run) in order to stop watching a stream. Leveraging 
 | 
 * {@link takeUntil}. 
 | 
 * 
 | 
 * ```ts 
 | 
 * import { interval, takeUntil, timer } from 'rxjs'; 
 | 
 * 
 | 
 * // Build a Date object that marks the 
 | 
 * // next minute. 
 | 
 * const currentDate = new Date(); 
 | 
 * const startOfNextMinute = new Date( 
 | 
 *   currentDate.getFullYear(), 
 | 
 *   currentDate.getMonth(), 
 | 
 *   currentDate.getDate(), 
 | 
 *   currentDate.getHours(), 
 | 
 *   currentDate.getMinutes() + 1 
 | 
 * ); 
 | 
 * 
 | 
 * // This could be any observable stream 
 | 
 * const source = interval(1000); 
 | 
 * 
 | 
 * const result = source.pipe( 
 | 
 *   takeUntil(timer(startOfNextMinute)) 
 | 
 * ); 
 | 
 * 
 | 
 * result.subscribe(console.log); 
 | 
 * ``` 
 | 
 * 
 | 
 * ### Known Limitations 
 | 
 * 
 | 
 * - The {@link asyncScheduler} uses `setTimeout` which has limitations for how far in the future it can be scheduled. 
 | 
 * 
 | 
 * - If a `scheduler` is provided that returns a timestamp other than an epoch from `now()`, and 
 | 
 * a `Date` object is passed to the `dueTime` argument, the calculation for when the first emission 
 | 
 * should occur will be incorrect. In this case, it would be best to do your own calculations 
 | 
 * ahead of time, and pass a `number` in as the `dueTime`. 
 | 
 * 
 | 
 * @param due If a `number`, the amount of time in milliseconds to wait before emitting. 
 | 
 * If a `Date`, the exact time at which to emit. 
 | 
 * @param scheduler The scheduler to use to schedule the delay. Defaults to {@link asyncScheduler}. 
 | 
 */ 
 | 
export function timer(due: number | Date, scheduler?: SchedulerLike): Observable<0>; 
 | 
  
 | 
/** 
 | 
 * Creates an observable that starts an interval after a specified delay, emitting incrementing numbers -- starting at `0` -- 
 | 
 * on each interval after words. 
 | 
 * 
 | 
 * The `delay` and `intervalDuration` are specified by default in milliseconds, however providing a custom scheduler could 
 | 
 * create a different behavior. 
 | 
 * 
 | 
 * ## Example 
 | 
 * 
 | 
 * ### Start an interval that starts right away 
 | 
 * 
 | 
 * Since {@link interval} waits for the passed delay before starting, 
 | 
 * sometimes that's not ideal. You may want to start an interval immediately. 
 | 
 * `timer` works well for this. Here we have both side-by-side so you can 
 | 
 * see them in comparison. 
 | 
 * 
 | 
 * Note that this observable will never complete. 
 | 
 * 
 | 
 * ```ts 
 | 
 * import { timer, interval } from 'rxjs'; 
 | 
 * 
 | 
 * timer(0, 1000).subscribe(n => console.log('timer', n)); 
 | 
 * interval(1000).subscribe(n => console.log('interval', n)); 
 | 
 * ``` 
 | 
 * 
 | 
 * ### Known Limitations 
 | 
 * 
 | 
 * - The {@link asyncScheduler} uses `setTimeout` which has limitations for how far in the future it can be scheduled. 
 | 
 * 
 | 
 * - If a `scheduler` is provided that returns a timestamp other than an epoch from `now()`, and 
 | 
 * a `Date` object is passed to the `dueTime` argument, the calculation for when the first emission 
 | 
 * should occur will be incorrect. In this case, it would be best to do your own calculations 
 | 
 * ahead of time, and pass a `number` in as the `startDue`. 
 | 
 * @param startDue If a `number`, is the time to wait before starting the interval. 
 | 
 * If a `Date`, is the exact time at which to start the interval. 
 | 
 * @param intervalDuration The delay between each value emitted in the interval. Passing a 
 | 
 * negative number here will result in immediate completion after the first value is emitted, as though 
 | 
 * no `intervalDuration` was passed at all. 
 | 
 * @param scheduler The scheduler to use to schedule the delay. Defaults to {@link asyncScheduler}. 
 | 
 */ 
 | 
export function timer(startDue: number | Date, intervalDuration: number, scheduler?: SchedulerLike): Observable<number>; 
 | 
  
 | 
/** 
 | 
 * @deprecated The signature allowing `undefined` to be passed for `intervalDuration` will be removed in v8. Use the `timer(dueTime, scheduler?)` signature instead. 
 | 
 */ 
 | 
export function timer(dueTime: number | Date, unused: undefined, scheduler?: SchedulerLike): Observable<0>; 
 | 
  
 | 
export function timer( 
 | 
  dueTime: number | Date = 0, 
 | 
  intervalOrScheduler?: number | SchedulerLike, 
 | 
  scheduler: SchedulerLike = asyncScheduler 
 | 
): Observable<number> { 
 | 
  // Since negative intervalDuration is treated as though no 
 | 
  // interval was specified at all, we start with a negative number. 
 | 
  let intervalDuration = -1; 
 | 
  
 | 
  if (intervalOrScheduler != null) { 
 | 
    // If we have a second argument, and it's a scheduler, 
 | 
    // override the scheduler we had defaulted. Otherwise, 
 | 
    // it must be an interval. 
 | 
    if (isScheduler(intervalOrScheduler)) { 
 | 
      scheduler = intervalOrScheduler; 
 | 
    } else { 
 | 
      // Note that this *could* be negative, in which case 
 | 
      // it's like not passing an intervalDuration at all. 
 | 
      intervalDuration = intervalOrScheduler; 
 | 
    } 
 | 
  } 
 | 
  
 | 
  return new Observable((subscriber) => { 
 | 
    // If a valid date is passed, calculate how long to wait before 
 | 
    // executing the first value... otherwise, if it's a number just schedule 
 | 
    // that many milliseconds (or scheduler-specified unit size) in the future. 
 | 
    let due = isValidDate(dueTime) ? +dueTime - scheduler!.now() : dueTime; 
 | 
  
 | 
    if (due < 0) { 
 | 
      // Ensure we don't schedule in the future. 
 | 
      due = 0; 
 | 
    } 
 | 
  
 | 
    // The incrementing value we emit. 
 | 
    let n = 0; 
 | 
  
 | 
    // Start the timer. 
 | 
    return scheduler.schedule(function () { 
 | 
      if (!subscriber.closed) { 
 | 
        // Emit the next value and increment. 
 | 
        subscriber.next(n++); 
 | 
  
 | 
        if (0 <= intervalDuration) { 
 | 
          // If we have a interval after the initial timer, 
 | 
          // reschedule with the period. 
 | 
          this.schedule(undefined, intervalDuration); 
 | 
        } else { 
 | 
          // We didn't have an interval. So just complete. 
 | 
          subscriber.complete(); 
 | 
        } 
 | 
      } 
 | 
    }, due); 
 | 
  }); 
 | 
} 
 |