export interface Rec<Values = any> extends Record<string, Values> {
}
export interface Fn<Args extends any[] = any[], Return = any> {
    (...a: Args): Return;
}
export type AllTypes = undefined | null | boolean | number | string | Record<keyof any, any> | Fn | symbol | bigint;
export interface Pipe<This> {
    <T1>(operator1: Fn<[This], T1>): T1;
    <T1, T2>(operator1: Fn<[This], T1>, operator2: Fn<[T1], T2>): T2;
    <T1, T2, T3>(operator1: Fn<[This], T1>, operator2: Fn<[T1], T2>, operator3: Fn<[T2], T3>): T3;
    <T1, T2, T3, T4>(operator1: Fn<[This], T1>, operator2: Fn<[T1], T2>, operator3: Fn<[T2], T3>, operator4: Fn<[T3], T4>): T4;
    <T1, T2, T3, T4, T5>(operator1: Fn<[This], T1>, operator2: Fn<[T1], T2>, operator3: Fn<[T2], T3>, operator4: Fn<[T3], T4>, operator5: Fn<[T4], T5>): T5;
    <T1, T2, T3, T4, T5, T6>(operator1: Fn<[This], T1>, operator2: Fn<[T1], T2>, operator3: Fn<[T2], T3>, operator4: Fn<[T3], T4>, operator5: Fn<[T4], T5>, operator6: Fn<[T5], T6>): T6;
    <T1, T2, T3, T4, T5, T6, T7>(operator1: Fn<[This], T1>, operator2: Fn<[T1], T2>, operator3: Fn<[T2], T3>, operator4: Fn<[T3], T4>, operator5: Fn<[T4], T5>, operator6: Fn<[T5], T6>, operator7: Fn<[T6], T7>): T7;
    <T1, T2, T3, T4, T5, T6, T7, T8>(operator1: Fn<[This], T1>, operator2: Fn<[T1], T2>, operator3: Fn<[T2], T3>, operator4: Fn<[T3], T4>, operator5: Fn<[T4], T5>, operator6: Fn<[T5], T6>, operator7: Fn<[T6], T7>, operator8: Fn<[T7], T8>): T8;
    <T1, T2, T3, T4, T5, T6, T7, T8, T9>(operator1: Fn<[This], T1>, operator2: Fn<[T1], T2>, operator3: Fn<[T2], T3>, operator4: Fn<[T3], T4>, operator5: Fn<[T4], T5>, operator6: Fn<[T5], T6>, operator7: Fn<[T6], T7>, operator8: Fn<[T7], T8>, operator9: Fn<[T8], T9>): T9;
    <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(operator1: Fn<[This], T1>, operator2: Fn<[T1], T2>, operator3: Fn<[T2], T3>, operator4: Fn<[T3], T4>, operator5: Fn<[T4], T5>, operator6: Fn<[T5], T6>, operator7: Fn<[T6], T7>, operator8: Fn<[T7], T8>, operator9: Fn<[T8], T9>, operator10: Fn<[T9], T10>): T10;
    <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(operator1: Fn<[This], T1>, operator2: Fn<[T1], T2>, operator3: Fn<[T2], T3>, operator4: Fn<[T3], T4>, operator5: Fn<[T4], T5>, operator6: Fn<[T5], T6>, operator7: Fn<[T6], T7>, operator8: Fn<[T7], T8>, operator9: Fn<[T8], T9>, operator10: Fn<[T9], T10>, operator11: Fn<[T10], T11>): T11;
    <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(operator1: Fn<[This], T1>, operator2: Fn<[T1], T2>, operator3: Fn<[T2], T3>, operator4: Fn<[T3], T4>, operator5: Fn<[T4], T5>, operator6: Fn<[T5], T6>, operator7: Fn<[T6], T7>, operator8: Fn<[T7], T8>, operator9: Fn<[T8], T9>, operator10: Fn<[T9], T10>, operator11: Fn<[T10], T11>, operator12: Fn<[T11], T12>): T12;
}
export declare const callSafely: <I extends any[], O>(fn: (...a: I) => O, ...args: I) => O | Error;
export type AtomMaybe<T = unknown> = Atom<T> | T;
/** Main context of data storing and effects processing */
export interface Ctx {
    get<T>(atom: Atom<T>): T;
    get<T>(cb: Fn<[
        read: Fn<[proto: AtomProto], AtomCache<any> | undefined>,
        fn?: Fn
    ], T>): T;
    spy?: {
        <T>(anAtom: Atom<T>): T;
        <Params extends any[] = any[], Payload = any>(anAction: Action<Params, Payload>, cb: Fn<[call: {
            params: Params;
            payload: Payload;
        }]>): void;
        <T>(atom: Atom<T>, cb: Fn<[newState: T, prevState: undefined | T]>): void;
    };
    schedule<T = void>(cb: Fn<[Ctx], T>, step?: -1 | 0 | 1 | 2): Promise<Awaited<T>>;
    subscribe<T>(atom: Atom<T>, cb: Fn<[T]>): Unsubscribe;
    subscribe(cb: Fn<[patches: Logs, error?: Error]>): Unsubscribe;
    cause: AtomCache;
}
export interface CtxSpy extends Required<Ctx> {
}
export interface Logs extends Array<AtomCache> {
}
export interface Atom<State = any> {
    __reatom: AtomProto<State>;
    pipe: Pipe<this>;
    onChange: (cb: (ctx: Ctx, newState: State) => any) => Unsubscribe;
}
type Update<State> = State | Fn<[State, Ctx], State>;
export interface AtomMut<State = any> extends Atom<State> {
    (ctx: Ctx, update: Update<State>): State;
}
export interface AtomProto<State = any> {
    name: undefined | string;
    isAction: boolean;
    /** temporal cache of the last patch during transaction */
    patch: null | AtomCache;
    initState: Fn<[Ctx], State>;
    computer: null | Fn<[CtxSpy, unknown], unknown>;
    connectHooks: null | Set<Fn<[Ctx]>>;
    disconnectHooks: null | Set<Fn<[Ctx]>>;
    updateHooks: null | Set<Fn<[Ctx, AtomCache]>>;
    actual: boolean;
}
export interface AtomCache<State = any> {
    state: State;
    readonly proto: AtomProto;
    cause: null | AtomCache;
    pubs: Array<AtomCache>;
    readonly subs: Set<AtomProto>;
    readonly listeners: Set<Fn>;
    error?: unknown;
}
export interface Action<Params extends any[] = any[], Payload = any> extends Atom<Array<{
    params: Params;
    payload: Payload;
}>> {
    (ctx: Ctx, ...params: Params): Payload;
    onCall: (cb: (ctx: Ctx, payload: Payload, params: Params) => any) => Unsubscribe;
}
export type AtomState<T> = T extends Atom<infer State> ? State : never;
export type ActionParams<T> = T extends Action<infer Params, any> ? Params : never;
export type ActionPayload<T> = T extends Action<any, infer Payload> ? Payload : never;
type DefinitelyReturnType<T> = T extends Fn<any[], infer T> ? T : never;
export type IsAction<T> = T extends Fn & Atom<infer State extends Array<{
    payload: DefinitelyReturnType<T>;
}>> ? true : false;
export type AtomReturn<T extends Atom> = T extends Fn ? ReturnType<T> : AtomState<T>;
export type CtxParams<T, Else = never> = T extends Fn<[Ctx, ...infer Params]> ? Params : T extends [Ctx, ...infer Params] ? Params : Else;
export interface Unsubscribe {
    (): void;
}
type Falsy = false | 0 | '' | null | undefined;
/** Throws `Reatom error: ${message}` */
export declare function throwReatomError(condition: any, message: string): asserts condition is Falsy;
export declare const isAtom: (thing: any) => thing is Atom<any>;
export declare const isAction: (thing: any) => thing is Action<any[], any>;
export interface CtxOptions {
    /** Use it to delay or track late effects such as subscriptions notification */
    callLateEffect?: typeof callSafely;
    /** Use it to delay or track near effects such as API calls */
    callNearEffect?: typeof callSafely;
    /** Mange multiple contexts warning */
    restrictMultipleContexts?: boolean;
}
export declare const createCtx: ({ callLateEffect, callNearEffect, restrictMultipleContexts, }?: CtxOptions) => Ctx;
/**
 * @internal
 * @deprecated
 */
export declare let __count: (name: string) => string;
export declare function atom<T>(computed: (ctx: CtxSpy) => T, name?: string): Atom<T>;
export declare function atom<T>(initState: T, name?: string): AtomMut<T>;
export declare const action: {
    (name?: string): Action<[], void>;
    <T>(name?: string): Action<[T], T>;
    <Params extends any[] = any[], Res = void>(fn: (ctx: Ctx, ...params: Params) => Res, name?: string): Action<Params, Res>;
};
export declare const experimental_PLUGINS: Array<(anAtom: Atom) => Atom>;
/**
 * @internal
 * @deprecated
 */
export declare const __root: AtomProto<undefined>;
export declare const batch: <T>(ctx: Ctx, cb: Fn<[], T>) => T;
export {};
//# sourceMappingURL=atom.d.ts.map