import { Duration, Moment } from 'moment';
import React from 'react';
import { Animated, LayoutChangeEvent } from 'react-native';
import { BehaviorSubject, MonoTypeOperatorFunction, Observable } from 'rxjs';
export interface StreamSubscription {
    off?: () => void;
}
export declare type StreamCallback<T> = (item: T) => void;
export interface Stream<T, Opt> extends Partial<StreamSubscription> {
    on: (cb: StreamCallback<T>, options?: Opt) => StreamSubscription | undefined;
}
export interface StreamOptions<T> {
    filter?: (item: T) => boolean;
    keyExtractor?: (item: T) => string | number;
    sort?: (item: T) => string | number;
    deps?: React.DependencyList;
    throttle?: number;
    onOpen?: (sub: StreamSubscription | undefined) => void;
    onClose?: (sub: StreamSubscription | undefined) => void;
}
export interface ILayout {
    x: number;
    y: number;
    width: number;
    height: number;
}
/**
 * Returns the component layout.
 *
 * Usage:
 * ```
 *  const Component = () => {
 *      const [layout, onLayout] = useLayout();
 *      return <View onLayout={onLayout} />;
 *  };
 * ```
 *
 * Source: https://stackoverflow.com/a/57792001/328356
 */
export declare const useLayout: (options?: {
    filter?: ((layout: ILayout & {
        previous?: ILayout;
    }) => boolean) | undefined;
    dedupe?: boolean | undefined;
    updateOnChange?: boolean | undefined;
} | undefined) => [ILayout | undefined, (event: LayoutChangeEvent) => void];
export declare function usePrevious<T>(value: T): T;
export declare function latestAfterInteractions<T>(): MonoTypeOperatorFunction<T>;
export declare const onInteractionsEnd: () => Observable<void>;
export declare function animatedObservable(value: Animated.Value): Observable<number>;
export interface UsePromiseResult<T> {
    value?: T;
    error?: Error;
    loading: boolean;
    complete: boolean;
}
export declare function usePromise<T>(promise?: T | Promise<T> | (() => Promise<T> | T | undefined), dependencies?: any[], options?: {
    onComplete?: (result: UsePromiseResult<T>) => void;
}): UsePromiseResult<T>;
export declare function useImport<T>(importPromise: Promise<T> | (() => Promise<T> | undefined), options?: {
    onComplete?: (result: UsePromiseResult<T>) => void;
}): Partial<T>;
export interface UseObservableResult<T> {
    value?: T;
    error?: Error;
    complete: boolean;
}
export declare function useObservable<T>(observable?: Observable<T> | (() => Observable<T> | undefined), dependencies?: any[], options?: {
    onChange?: (value: T) => void;
    onUnmount?: () => any;
}): UseObservableResult<T>;
export declare function useBehaviorSubject<T>(subject: BehaviorSubject<T> | (() => BehaviorSubject<T>), dependencies?: any[], options?: {
    onChange?: (value: T) => void;
    onUnmount?: () => any;
}): T;
export declare type MaybeObservable<T> = Observable<T> | T;
export declare type ExctactMaybeObservableType<T> = T extends Observable<infer U> ? U : T;
export declare function useObservableIfNeeded<T>(maybeObservable?: MaybeObservable<T> | (() => MaybeObservable<T> | undefined), dependencies?: any[]): UseObservableResult<T>;
/**
 * Creates a behavior subject, which tracks the
 * specified `value`.
 *
 * @param value
 * @param options
 * @returns
 */
export declare function useValueAsBehaviorSubject<T>(value: T, options?: {
    serializer?: (value: T) => any;
}): BehaviorSubject<T>;
/**
 * Returns the date interval between now
 * and the specifed `duration` ago.
 *
 * The end of the current period is used as
 * the first value.
 *
 * Use only with durations composed of only
 * one date unit.
 *
 * Updates on significant time changes
 * automatically.
 *
 * @param duration
 */
export declare function useCurrentDateInterval(duration: Duration): {
    startDate: Moment;
    endDate: Moment;
};
/**
 * Prevents body scroll on web in this component.
 * Has no effect on other platforms.
 *
 * Credit: https://usehooks.com/useLockBodyScroll/
 */
export declare function useLockBodyScroll(): void;
