/**
  {@include ../doc/delay.md}

  @module
 */
/**
  A `Strategy` is any iterable iterator which yields numbers. You can implement
  it using the `IterableIterator` interface, i.e. `implements Strategy`, or you
  can write a generator function which produces `Generator<number>`.

  ## Examples

  You can define your own generator functions or iterable iterators and pass
  them as the strategy for the delay, or you can implement a class which
  implements this interface. If you are able to target ES2025 (including by
  using a polyfill), you can also provide subclasses of `Iterator`.

  ```ts
  function* randomInRange(min: number, max: number): Strategy<number> {
    while (true) {
      let scaled = Math.random() * (max - min + 1);
      let scaledInt = Math.floor(scaled);
      let startingAtMin = scaledInt + min;
      yield startingAtMin
    }
  }

  //
  class RandomInteger implements Strategy {
    #nextValue: number;

    constructor(initial: number) {
      this.#nextValue = initial;
    }

    next(): IteratorResult<number, void> {
      this.#nextValue = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);
      return { done: false, value: this.#nextValue };
    }

    return(value: number): IteratorResult<number, void> {
      return { done: false, value };
    }

    throw(_error: unknown): IteratorResult<number, void> {
      return { done: true, value: undefined };
    }

    [Symbol.iterator](): Generator<number, any, unknown> {
      return this;
    }
  }

  class Range extends Iterator {
    readonly #start: number;
    readonly #end: number;
    readonly #step: number;

    constructor(start: number, end: number, step = 1) {
      this.#start = start;
      this.#end = end;
      this.#step = step;
    }

    *[Symbol.iterator]() {
      for (let value = this.#start; value <= this.#end; value += this.#step) {
        yield value;
      }
    }
  }
  ```

  Then you can use any of these as a retry strategy (note that these examples
  assume you have access to [the ES2025 iterator helper methods][helpers]):

  [helpers]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator#iterator_helper_methods

  ```ts
  import * as Task from 'true-myth/task';
  import { someRetryableTask } from 'somewhere/in/your-app';

  let usingRandomInRange = Task.withRetries(
    someRetryableTask,
    randomInRange(1, 100).take(10)
  );

  let usingRandomInteger = Task.withRetries(
    someRetryableTask,
    new RandomInteger().take(10)
  );

  let usingRangeIterator = Task.withRetries(
    someRetryableTask,
    new Range(1, 100, 5).take(10)
  );
  ```
 */
export interface Strategy extends Iterable<number> {
}
/**
  Generate an infinite iterable of integers beginning with `base` and increasing
  exponentially until reaching `Number.MAX_SAFE_INTEGER`, after which the
  generator will continue yielding `Number.MAX_SAFE_INTEGER` forever.

  By default, this increases exponentially by a factor of 2; you may optionally
  pass `{ factor: someOtherValue }` to change the exponentiation factor.

  If you pass a non-integral value as `base`, it will be rounded to the nearest
  integral value using `Math.round`.
 */
export declare function exponential(options?: {
    /** Initial delay duration in milliseconds. Default is `1`. */
    from?: number;
    /**
      Exponentiation factor. Default is `2`.
  
      > [!IMPORTANT]
      > Setting this to a value less than `1` will cause the delay intervals to
      > *decay* rather than *increase*. This is rarely what you want!
     */
    withFactor?: number;
}): Strategy;
/**
  Generate an infinite iterable of integers beginning with `base` and
  increasing as a Fibonacci sequence (1, 1, 2, 3, 5, 8, 13, ...) until reaching
  `Number.MAX_SAFE_INTEGER`, after which the generator will continue yielding
  `Number.MAX_SAFE_INTEGER` forever.

  If you pass a non-integral value as the `from` property on the configuration
  argument, it will be rounded to the nearest integral value using `Math.round`.
 */
export declare function fibonacci(options?: {
    /** Initial delay duration in milliseconds. Default is `1`. */
    from: number;
}): Strategy;
/**
  Generate an infinite iterable of the same integer value in milliseconds.

  If you pass a non-integral value, like `{ at: 2.5 }`, it will be rounded to
  the nearest integral value using `Math.round`, i.e. `3` in that case.
 */
export declare function fixed(options?: {
    /** Delay duration in milliseconds. Default is `1` (immediate). */
    at: number;
}): Strategy;
/** Generate an infinite iterable of the value `0`. */
export declare function immediate(): Generator<number, void, unknown>;
/**
  Generate an infinite iterable of integers beginning with `base` and increasing
  linearly (1, 2, 3, 4, 5, 5, 7, ...) until reaching `Number.MAX_SAFE_INTEGER`,
  after which the generator will continue yielding `Number.MAX_SAFE_INTEGER`
  forever.

  By default, this increases by a step size of 1; you may optionally pass
  `{ step: someOtherValue }` to change the step size.

  If you pass a non-integral value as `base`, it will be rounded to the nearest
  integral value using `Math.round`.
 */
export declare function linear(options?: {
    /** Initial delay duration in milliseconds. Default is `0`. */
    from?: number;
    /**
        Step size by which to increase the value. Default is `1`.
  
        > [!IMPORTANT]
        > Setting this to a value less than `1` will cause the delay intervals to
        > *decay* rather than *increase*. This is rarely what you want!
       */
    withStepSize?: number;
}): Strategy;
/**
  A “no-op” strategy, for if you need to call supply a {@linkcode Strategy} to
  a function but do not actually want to retry at all.

  You should never use this directly with `Task.withRetries`; in the case where
  you would, invoke the `Task` that would be retried directly (i.e. without
  using `withRetries` at all) instead.
 */
export declare function none(): Strategy;
/**
  Apply fully random jitter proportional to the number passed in. The resulting
  value will never be larger than 2×n, and never less than 0.

  This is useful for making sure your retries generally follow a given
  {@linkcode Strategy}, but if multiple tasks start at the same time, they do
  not all retry at exactly the same time.

  @param n The value to apply random jitter to.
*/
export declare function jitter(n: number): number;
//# sourceMappingURL=delay.d.ts.map