/**
 * IteratorFuncs a simple single file package to make working with JS iterators easier.
 *
 * The documentation lives online [here](https://drew887.github.io/iteratorFuncs/modules.html).
 *
 * If you've ever had a generator, or a Set, or a Map that you've needed to map/filter/reduce over in JS, you've been hit
 * by the pain of having to either convert to an Array with `Array.from` and then use the method you need, or write a
 * for...of loop and do your logic in there.
 *
 * While the for...of loop is almost certainly the "proper" or "js way" of doing things, and is what you normally get as
 * an answer when searching for this, it can be a little disappointing or jarring for those of us wanting a more fp like
 * approach that js normally lets you take.
 *
 * So this package is simply to help facilitate these patterns for IterableIterators.
 *
 * tldr:
```typescript
const set = new Set([1, 2, 3, 4, 5]);

const mappedAndFiltered =
  mapIterator(set, (item) => item * 2)
  .filter((item) => item > 5);

console.log(Array.from(mappedAndFiltered)); // logs out [6, 8, 10]
```
 *
 * @packageDocumentation
 */
/**
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */
/**
 * We override the default Iterable interface since it doesn't allow forwarding of the other 2 type params that Iterator can take
 */
export interface Iterable<TValue, TReturn = any, TNext = any> {
    [Symbol.iterator](): Iterator<TValue, TReturn, TNext>;
}
/**
 * We override the default IterableIterator interface since it doesn't allow forwarding of the other 2 type params that Iterator can take
 */
export interface IterableIterator<TValue, TReturn = any, TNext = any> extends Iterator<TValue, TReturn, TNext> {
    [Symbol.iterator](): IterableIterator<TValue, TReturn, TNext>;
}
/**
 * Type alias to simplify this union
 * TODO: Come up with a better name
 */
export type IteratorArg<TIteratorValue, TIteratorReturn, TIteratorNext> = Iterable<TIteratorValue, TIteratorReturn, TIteratorNext> | IterableIterator<TIteratorValue, TIteratorReturn, TIteratorNext>;
/**
 * An AugmentedIterator represents one of the IterableIterators we return.
 * This abstract class is exported only to provide type/intellisense information,
 * and should be only implemented internally.
 */
export declare abstract class AugmentedIterator<TValue, TReturn = any, TNext = any> implements IterableIterator<TValue, TReturn, TNext> {
    [Symbol.iterator](): this;
    abstract next(...args: [] | [TNext]): IteratorResult<TValue, TReturn>;
    map<TMapperReturn>(mapper: (item: TValue) => TMapperReturn): AugmentedIterator<TMapperReturn, TReturn, TNext>;
    filter(filter: (item: TValue) => boolean): AugmentedIterator<TValue, TReturn, TNext>;
    reduce<TReducerReturn>(reducer: (carry: TReducerReturn, item: TValue) => TReducerReturn, initial: TReducerReturn): AugmentedIterator<TReducerReturn, TReturn, TNext>;
}
/**
 * Given an Iterable or IterableIterator, a reducer, and an initial value, return a new IterableIterator that yields
 * values that are automatically piped through said reducer.
 * @param {Iterable} iterator - The iterator you wish to reduce over
 * @param {Function} reducer - A function to use to reduce the elements iterator produces
 * @param initial The initial value to pass to reducer with the first element
 * @typeParam TValue - The value returned from the iterator
 * @typeParam TReducerReturn - The return type of your reducer function
 * @typeParam TReturn - If your iterator has a return type it must be the same as TIteratorValue, otherwise undefined
 * @typeParam TNext - The type your iterator is expecting as what's passed to its next function. For generators this is the type returned after a yield.
 *
 * @example
const set: Set<number> = new Set([1, 2, 3, 4, 5]);

const summingIterator = reduceIterator(
  set.values(),
  (carry: number, item: number): number => {
    return carry + item;
  },
  0,
);
// summingIterator will now yield the sum for each value seen thus far

const finalValues = Array.from(summingIterator);
// finalValues will now be [1,3,6,10,15];
 */
export declare function reduceIterator<TValue, TReducerReturn, TReturn = TValue | undefined, TNext = any>(iterator: IteratorArg<TValue, TReturn, TNext>, reducer: (carry: TReducerReturn, arg: TValue) => TReducerReturn, initial: TReducerReturn): AugmentedIterator<TReducerReturn, TReturn, TNext>;
/**
 * Given an IteratorArg and a mapping function, returns a new IterableIterator that yields values from the initial iterator
 * but passed through the mapping function.
 * @param {Iterable} iterator - The iterator you wish to map elements from
 * @param {Function} mapper - A function to use to map the elements iterator produces
 * @typeParam TValue - The value returned from the iterator
 * @typeParam TMapperReturn - The return type of your reducer function
 * @typeParam TReturn - If your iterator has a return type it must be the same as TIteratorValue, otherwise undefined
 * @typeParam TNext - The type your iterator is expecting as what's passed to its next function. For generators this is the type returned after a yield.
 * @example
const set = new Set([1, 2, 3, 4, 5]);

const mapped = mapIterator(set, (item) => item * 2);

console.log(Array.from(mapped)); // logs out [2, 4, 6, 8, 10]
 */
export declare function mapIterator<TValue, TMapperReturn, TReturn = TValue | undefined, TNext = any>(iterator: IteratorArg<TValue, TReturn, TNext>, mapper: (arg: TValue) => TMapperReturn): AugmentedIterator<TMapperReturn, TReturn, TNext>;
/**
 * Given an IteratorArg and a filtering function it will return a new IterableIterator that when polled will eagerly pull
 * values from iterator and pass them to filterer until filterer returns true for an item, or we reach the end of iterator;
 * it will then yield this value itself.
 *
 * **NOTE:** if iterator relies on values being passed to next, the returned IterableIterator will re-use the same next
 * until a value passes the filterer.
 * value until an item is raised that passes the filterer. This can lead to strange behaviours.
 * @param {Iterable} iterator - The iterator you wish to map elements from
 * @param {Function} filterer - Only values for which this function returns true are yielded.
 * @typeParam TValue - The value returned from the iterator
 * @typeParam TReturn - If your iterator has a return type it must be the same as TIteratorValue, otherwise undefined
 * @typeParam TNext - The type your iterator is expecting as what's passed to its next function. For generators this is the type returned after a yield.
 *
 * @example
const set = new Set([1, 2, 3, 4, 5]);

const filtered = filterIterator(set, (item) => item % 2 === 0);

console.log(Array.from(filtered)); // logs out [2, 4]
 */
export declare function filterIterator<TValue, TReturn = TValue | undefined, TNext = any>(iterator: IteratorArg<TValue, TReturn, TNext>, filterer: (arg: TValue) => boolean): AugmentedIterator<TValue, TReturn, TNext>;
/**
 * Given an iterator, eagerly reduce over its results until it finishes and return the result
 * @param {Iterable} iterator - The iterator you wish to reduce over
 * @param {Function} reducer - A function to use to reduce the elements iterator produces
 * @param initial The initial value to pass to reducer with the first element. Also returned if iterator never yields a value
 * @typeParam TValue - The type of values that iterator will yield and that initial must be
 * @typeParam TReturn - The type of values that reducer will return
 *
 * @example
 const set: Set<number> = new Set([1, 2, 3, 4, 5]);

 const sum = eagerlyReduceIterator(
   set.values(),
   (carry: number, item: number): number => {
     return carry + item;
   },
   0,
 );
 // sum is now 15
 */
export declare function eagerlyReduceIterator<TValue, TReturn>(iterator: Iterable<TValue>, reducer: (carry: TReturn, arg: TValue) => TReturn, initial: TReturn): TReturn;
/**
 * Eagerly Map over an iterator and return an array of results
 * @param {Iterable} iterator - The iterator you wish to map over
 * @param {Function} mapper - The function you want to use to process any elements yielded from iterator
 * @typeParam TValue - The type of values that iterator will yield
 * @typeParam TReturn - The type of values that mapper will return
 *
 * @example
 const set: Set<number> = new Set([1, 2, 3, 4, 5]);

 const squaredValues = mapIteratorToArray(
   set.values(),
   (item: number): number => {
     return item * item;
   },
 );
 */
export declare function mapIteratorToArray<TValue, TReturn>(iterator: Iterable<TValue>, mapper: (arg: TValue) => TReturn): Array<TReturn>;
/**
 * Eagerly Filter over an iterator and return an array of results
 * @param {Iterable} iterator - The iterator you wish to filter over
 * @param {Function} filter - Your filtering function
 * @typeParam TValue - The type of values that iterator will yield
 *
 * @example
 const set: Set<number> = new Set([1, 2, 3, 4, 5]);

 const evenValues = filterIteratorToArray(
   set.values(),
   (item: number): boolean => {
     return item % 2 === 0;
   },
 );
 // evenValues = [2, 4];
 */
export declare function filterIteratorToArray<TValue>(iterator: Iterable<TValue>, filter: (arg: TValue) => boolean): Array<TValue>;
