import { WithDerived, Derived } from './shared/c7f3bced';
export { Derived, Watcher, isDerived, no, noto, o, watch, when } from './shared/c7f3bced';
import { Auto, Falsy, ObserverTarget, Change } from './shared/ed456245';
export { Auto, AutoConfig, Change, ChangeObserver, auto, shallowChanges } from './shared/ed456245';
import * as React from 'react';
import { ReactElement, Ref, RefAttributes } from 'react';

declare function useO<T extends object>(state: Exclude<T, Function>, deps?: readonly any[]): WithDerived<T>;
/**
 * Create an observable getter that is managed by React.
 * This lets you memoize an expensive combination of observable values.
 */
declare function useO<T>(create: () => () => T, deps?: readonly any[]): Derived<T>;
/** Create observable component state. */
declare function useO<T>(create: () => Exclude<T, Function>, deps?: readonly any[]): T;
/** Memoize an object and return its observable proxy. Non-objects are returned as-is. */
declare function useO<T>(state: T, deps?: readonly any[]): T;

declare type EffectReturn = void | (() => void | undefined);
/** Wrap a `useEffect` call with magic observable tracking */
declare function useAuto(effect: () => EffectReturn, deps?: readonly any[]): Auto;
/**
 * Combine a `useEffect` call with an `Auto` instance that invokes an
 * unobserved side `effect` when the `compute` function returns a new value.
 */
declare function useAuto<T>(compute: () => T, effect: (value: T) => EffectReturn, deps?: readonly any[]): Auto;

interface Component<P = any> {
    (props: P): ReactElement | null;
    displayName?: string;
}
interface RefForwardingComponent<T = any, P = any> {
    (props: P, ref: Ref<T>): ReactElement | null;
    displayName?: string;
}
declare type RefForwardingAuto<T extends RefForwardingComponent> = T & ((props: T extends RefForwardingComponent<infer U, infer P> ? P & RefAttributes<U> : never) => ReactElement | null);
/** Wrap a component with magic observable tracking */
declare function withAuto<T extends Component>(render: T): T;
/** Wrap a component with `forwardRef` and magic observable tracking */
declare function withAuto<T extends RefForwardingComponent>(render: T): RefForwardingAuto<T>;
declare namespace withAuto {
    var dev: (render: any) => React.ForwardRefExoticComponent<Pick<any, string | number | symbol> & React.RefAttributes<unknown>>;
}

/**
 * Create an observable getter that is managed by React.
 * This lets you memoize an expensive combination of observable values.
 *
 * If the `compute` argument changes over the course of a component's lifetime,
 * its value should be added to the `deps` array.
 *
 * When `deps` are changed, the derived state is reset. This is useful when
 * the `compute` function is using a variable from another function scope.
 */
declare function useDerived<T>(compute: () => T, deps?: readonly any[]): Derived<T>;
declare function useDerived<T>(compute: (() => T) | Falsy, deps?: readonly any[]): Derived<T> | null;
declare function useDerived<T>(compute: () => T, discard: (memo: T, oldMemo: T | undefined) => boolean, deps?: readonly any[]): Derived<T>;
declare function useDerived<T>(compute: (() => T) | Falsy, discard: (memo: T, oldMemo: T | undefined) => boolean, deps?: readonly any[]): Derived<T> | null;

/** Listen for shallow changes to an observable object. */
declare function useChanges(target: ObserverTarget, onChange: (change: Change) => void, deps?: readonly any[]): void;

declare type UnmountFn = () => undefined | void;
declare type Source<T = any> = {
    [key: string]: T;
} | ReadonlyArray<T> | ReadonlySet<T> | ReadonlyMap<any, T>;
declare type Effect<T extends Source> = T extends Source<infer U> ? T extends ReadonlyMap<infer P, U> ? (value: U, key: P) => UnmountFn | void : T extends ReadonlyArray<U> | ReadonlySet<U> ? (value: U) => UnmountFn | void : (value: U, key: string) => UnmountFn | void : never;
/**
 * Create a layout effect for every key of your `values` object.
 *
 * Values are passed to your `effect` function as they are added and replaced.
 * The `effect` can return a cleanup function to call for removed values.
 *
 * Map objects use their keys
 */
declare function useEffects<T extends Source>(source: T, effect: Effect<T>, deps?: readonly any[]): void;

/**
 * An alternative to `withAuto` that re-renders the caller
 * when the given observable value is changed.
 *
 * If you pass an object without a key, the entire object
 * is observed.
 *
 * ⚠️ This hook has performance drawbacks! It cannot automatically
 * batch React updates, so you need to wrap changes with `batchedUpdates`
 * to avoid multiple re-renders. It also cannot wait for ancestor
 * components to re-render first, which also leads to excessive re-renders.
 */
declare function useBinding<T extends object, P extends keyof T>(target: T extends ReadonlyMap<any, any> ? never : T, key: P): T[P];
declare function useBinding<K, V>(target: ReadonlyMap<K, V>, key: K): V | undefined;
declare function useBinding<T>(target: Derived<T>): T;
declare function useBinding<T extends object>(target: T): T;

export { useAuto, useBinding, useChanges, useDerived, useEffects, useO, withAuto };
