/// <reference types="node" />
import { Readable, Transform, Writable } from 'stream';
import { ObjectTransform, ObjectStreamOptions } from '.';
/**
 * This is a class to facilitate the transformation of data in a stream. The generic type represent the type of the data in the stream.
 * All methods allow to keep a strongly typed system.
 */
export default class ObjectStream<T> {
    private readonly stream;
    private readonly intermediateOperations;
    private readonly options?;
    private constructor();
    static ofReadable<T>(readable: Readable): ObjectStream<T>;
    /**
     * Returns an {@link ObjectStream} consisting of the results of applying the given function to each element of this stream.
     * To use an async function, see {@link mapAsync} instead.
     * <p>
     *  This is an <strong>intermediate operation</strong>.
     * <p/>
     * @param mapFn Function that is called for every element of the stream.
     * The mapFn function accepts one argument which is the current element processed in the stream.
     * @return the new {@link ObjectStream}.
     */
    map<R>(mapFn: (value: T) => R): ObjectStream<R>;
    /**
     * Returns an {@link ObjectStream} consisting of the results of resolving the given function to each element of this stream.
     * To use a sync operation, see {@link map} instead.
     * <p>
     *  This is an <strong>intermediate operation</strong>.
     * <p/>
     * @param mapFn Function that is called for every element of the stream to transform each element with the resolve value af this function.
     * The mapFn function accepts one argument which is the current element processed in the stream.
     * @return the new {@link ObjectStream}.
     */
    mapAsync<R>(mapFn: (value: T) => Promise<R>): ObjectStream<R>;
    /**
     * Returns an {@link ObjectStream} consisting of replacing each element by all the elements of the array returned by the mapFn.
     * <p>
     *  This is an <strong>intermediate operation</strong>.
     * <p/>
     * @param mapFn Function that is called for every element of the stream. Each time mapFn executes, all the element in the returned array are pushed to the result stream.
     * The mapFn function accepts one argument which is the current element processed in the stream.
     * @return the new {@link ObjectStream}.
     */
    flatMap<R>(mapFn: (value: T) => R[]): ObjectStream<R>;
    /**
     * Returns an {@link ObjectStream} consisting of replacing each element by all the elements of the array resolved by the mapFn.
     * <p>
     *  This is an <strong>intermediate operation</strong>.
     * <p/>
     * @param mapFn Function that is called for every element of the stream. Each time mapFn executes, all the element in the resolved array are pushed to the result stream.
     * The mapFn function accepts one argument which is the current element processed in the stream.
     * @return the new {@link ObjectStream}.
     */
    flatMapAsync<R>(mapFn: (value: T) => Promise<R[]>): ObjectStream<R>;
    /**
     * Returns an {@link ObjectStream} consisting of the elements that pass the test implemented by the provided filterFn.
     * <p>
     *  This is an <strong>intermediate operation</strong>.
     * <p/>
     * @param filterFn Function that is a predicate, to test each element of the stream. Return a value that coerces to true to keep the element, or to false otherwise.
     * It accepts one argument which is the element processed in the stream.
     * @return the new {@link ObjectStream}.
     */
    filter<S extends T>(filterFn: ((value: T) => value is S) | ((value: T) => boolean)): ObjectStream<S>;
    /**
     * Returns an {@link ObjectStream} consisting of elements grouped by the result of getKeyFn.
     * Each time the getKeyFn returns a different key, it considers the group is complete and push it to the result stream.
     * This means for the result to be accurate your stream needs to be ordered by your key first or else you will have multiple {@link GroupingByKey} for the same key.
     * This behaviour is to avoid loading all data into memory.
     *
     * <strong>NOTE</strong> : If a lot of elements are in the same group, that means that all these elements will be into memory.
     * <p>
     *  This is an <strong>intermediate operation</strong>.
     * <p/>
     * @param getKeyFn Function that is called for each element to know if current element should be grouped with the previous one.
     * @return the new {@link ObjectStream}.
     */
    groupByKey(getKeyFn: (value: T) => string): ObjectStream<GroupingByKey<T>>;
    /**
     * Returns an {@link ObjectStream} consisting of an array of elements whose size depends on chunkSize.
     * <p>
     *  This is an <strong>intermediate operation</strong>.
     * <p/>
     * @param chunkSize size of the chunks
     * @return the new {@link ObjectStream}.
     */
    groupByChunk(chunkSize: number): ObjectStream<T[]>;
    /**
     * Returns an {@link ObjectStream} consisting of the elements pushed in the given parameter.
     * This method is to add a generic operation in case none of the existing ones correspond to your needs.
     * <p>
     *  This is an <strong>intermediate operation</strong>.
     * <p/>
     * @param objectTransform {@link ObjectTransform} which represents the transformation to apply.
     * @param options {@link ObjectStreamOptions} to override for current and next operation.
     * @return the new {@link ObjectStream}.
     */
    transformWith<R>(objectTransform: ObjectTransform<T, R>, options?: ObjectStreamOptions): ObjectStream<R>;
    /**
     * Returns an {@link ObjectStream} consisting of the elements transformed by the given Transform parameter.
     * <p>
     *  This is an <strong>intermediate operation</strong>.
     * <p/>
     * @param transform which is a {@link Transform}.
     * @param options {@link ObjectStreamOptions} to override for next operations
     * @return the new {@link ObjectStream}.
     */
    applyTransform<R>(transform: Transform, options?: ObjectStreamOptions): ObjectStream<R>;
    /**
     * Return all the elements of the stream in an array.
     * <p>
     *  This is a <strong>terminal operation</strong>.
     * <p/>
     * @return a Promise which is
     * - resolved once all the stream is processed with an array containing all the elements of the stream
     * - or rejected with the error raised during the processing of the stream if there is one.
     */
    toArray(): Promise<T[]>;
    /**
     * Apply the given function to each element of the stream before closing it.
     * <p>
     *  This is a <strong>terminal operation</strong>.
     * <p/>
     * @param fn Function that is called for each element of the stream. It can be an async function.
     * @return a Promise which is
     * - resolved once all the stream is processed
     * - or rejected with the error raised during the processing of the stream if there is one.
     */
    forEach(fn: (value: T) => void | Promise<void>): Promise<void>;
    /**
     * Pass each element to the writable stream.
     * <p>
     *  This is a <strong>terminal operation</strong>.
     * <p/>
     * @param writable Writable stream to write data to their destination.
     * @return a Promise which is
     * - resolved once all the stream is processed
     * - or rejected with the error raised during the processing of the stream if there is one.
     */
    writeTo(writable: Writable): Promise<void>;
}
export interface GroupingByKey<T> {
    key: string;
    groupedValues: T[];
}
