import type { Atom, WritableAtom } from './atom';
import type { SuspensePromise } from './suspensePromise';
type AnyAtomValue = unknown;
type AnyAtom = Atom<AnyAtomValue>;
type OnUnmount = () => void;
type ReadError = unknown;
type Revision = number;
type ReadDependencies = Map<AnyAtom, Revision>;
/**
 * Immutable atom state, tracked for both mounted and unmounted atoms in a store.
 * @private This is for internal use and not considered part of the public API.
 */
export type AtomState<Value = AnyAtomValue> = {
    /**
     * Counts number of times atom has actually changed or recomputed.
     */
    r: Revision;
    /**
     * Validit(y) of the atom state.
     * Mounted atoms are considered invalidated when `y === false`.
     */
    y: boolean;
    /**
     * Maps from a dependency to the dependency's revision when it was last read.
     * We can skip recomputation of an atom by comparing the ReadDependencies revision
     * of each dependency to that dependencies's current revision.
     */
    d: ReadDependencies;
} & ({
    e: ReadError;
} | {
    p: SuspensePromise;
} | {
    v: Awaited<Value>;
});
/**
 * Represents a version of a store. A version contains a state for every atom
 * read during the version's lifetime.
 *
 * In concurrent React rendering, state can "branch" during transitions: the
 * current state may continue to be rendered while a new state is being built
 * concurrently. We key our atom state containers by this global version to
 * represent the state for each diverging branch.
 *
 * While a new version is being built, we read atom previous state from the
 * previous version.
 *
 * This is an INTERNAL type alias.
 */
export type VersionObject = {
    /**
     * "p"arent version.
     *
     * Once a version is committed completely, the `p` property is deleted so the
     * child version is independent, and the parent version can be garbage
     * collected.
     *
     * See [Provider] for more details on version data flow.
     */
    p?: VersionObject;
};
type Listeners = Set<(version?: VersionObject) => void>;
type Dependents = Set<AnyAtom>;
/**
 * State tracked for mounted atoms. An atom is considered "mounted" if it has a
 * subscriber, or is a transitive dependency of another atom that has a
 * subscriber.
 *
 * The mounted state of an atom is freed once it is no longer mounted.
 */
type Mounted = {
    /** The list of subscriber functions. */
    l: Listeners;
    /** Atoms that depend on *this* atom. Used to fan out invalidation. */
    t: Dependents;
    /** Function to run when the atom is unmounted. */
    u?: OnUnmount;
};
type StateListener = () => void;
/**
 * Read an atom's [AtomState], an internal data structure that is not considered
 * part of the public API. See [useAtom] for more details.
 *
 * Derived atom states may be recomputed if they are invalidated and any of
 * their transitive dependencies have changed.
 */
export declare const READ_ATOM = "r";
/**
 * Invoke an atom's [WritableAtom.write] method with an update value.
 * That `write` method may set one or more atoms.
 * The default `write` method of primitive atoms just sets the atom itself to
 * the update value.
 */
export declare const WRITE_ATOM = "w";
/**
 * Commit pending writes to an atom.
 * (The current implementation commits pending writes to all atoms; this is subject to change.)
 */
export declare const COMMIT_ATOM = "c";
/**
 * Add a subscriber function to an atom. Returns a function that removes the
 * subscriber.
 *
 * The subscriber is called in two cases:
 *
 * - For writable atoms, the subscriber is called whenever the atom is directly
 *   changed by `atom.write`.
 * - For derived atoms, the subscriber is called whenever the atom is
 *   *invalidated* (i.e. when it's possibly transitive dependencies change or
 *   become invalidated), **not** when the actual Value of the atom changes.
 *   Derived atoms are only recomputed on read.
 */
export declare const SUBSCRIBE_ATOM = "s";
/**
 * Bulk-apply new values to atoms.
 */
export declare const RESTORE_ATOMS = "h";
export declare const DEV_SUBSCRIBE_STATE = "n";
export declare const DEV_GET_MOUNTED_ATOMS = "l";
export declare const DEV_GET_ATOM_STATE = "a";
export declare const DEV_GET_MOUNTED = "m";
/**
 * Create a new store. Each store is an independent, isolated universe of atom
 * states.
 *
 * Jotai atoms are not themselves state containers. When you read or write an
 * atom, that state is stored in a store. You can think of a Store like a
 * multi-layered map from atoms to states, like this:
 *
 * ```
 * // Conceptually, a Store is a map from atoms to states.
 * // The real type is a bit different.
 * type Store = Map<VersionObject, Map<Atom, AtomState>>
 * ```
 *
 * @param initialValues An iterable where item is a pair of [an atom, its
 *   initial value]. Use to set initial state of writable atoms; useful for
 *   testing.
 *
 * @returns A store.
 */
export declare const createStore: (initialValues?: Iterable<readonly [AnyAtom, AnyAtomValue]>) => {
    r: <Value>(readingAtom: Atom<Value>, version?: VersionObject) => AtomState<Value>;
    w: <Value_1, Update, Result extends void | Promise<void>>(writingAtom: WritableAtom<Value_1, Update, Result>, update: Update, version?: VersionObject) => Result;
    c: (_atom: AnyAtom | null, version?: VersionObject) => void;
    s: (atom: AnyAtom, callback: (version?: VersionObject) => void, version?: VersionObject) => () => void;
    h: (values: Iterable<readonly [AnyAtom, AnyAtomValue]>, version?: VersionObject) => void;
    n: (l: StateListener) => () => void;
    l: () => IterableIterator<AnyAtom>;
    a: (a: AnyAtom) => AtomState<unknown> | undefined;
    m: (a: AnyAtom) => Mounted | undefined;
} | {
    r: <Value>(readingAtom: Atom<Value>, version?: VersionObject) => AtomState<Value>;
    w: <Value_1, Update, Result extends void | Promise<void>>(writingAtom: WritableAtom<Value_1, Update, Result>, update: Update, version?: VersionObject) => Result;
    c: (_atom: AnyAtom | null, version?: VersionObject) => void;
    s: (atom: AnyAtom, callback: (version?: VersionObject) => void, version?: VersionObject) => () => void;
    h: (values: Iterable<readonly [AnyAtom, AnyAtomValue]>, version?: VersionObject) => void;
    n?: never;
    l?: never;
    a?: never;
    m?: never;
};
export type Store = ReturnType<typeof createStore>;
export declare const createStoreForExport: (initialValues?: Iterable<readonly [AnyAtom, AnyAtomValue]>) => {
    get: <Value>(atom: Atom<Value>) => Awaited<Value> | undefined;
    asyncGet: <Value_1>(atom: Atom<Value_1>) => Promise<Awaited<Value_1>>;
    set: <Value_2, Update, Result extends void | Promise<void>>(atom: WritableAtom<Value_2, Update, Result>, update: Update) => Result;
    sub: (atom: AnyAtom, callback: () => void) => () => void;
    SECRET_INTERNAL_store: {
        r: <Value>(readingAtom: Atom<Value>, version?: VersionObject) => AtomState<Value>;
        w: <Value_1, Update, Result extends void | Promise<void>>(writingAtom: WritableAtom<Value_1, Update, Result>, update: Update, version?: VersionObject) => Result;
        c: (_atom: AnyAtom | null, version?: VersionObject) => void;
        s: (atom: AnyAtom, callback: (version?: VersionObject) => void, version?: VersionObject) => () => void;
        h: (values: Iterable<readonly [AnyAtom, AnyAtomValue]>, version?: VersionObject) => void;
        n: (l: StateListener) => () => void;
        l: () => IterableIterator<AnyAtom>;
        a: (a: AnyAtom) => AtomState<unknown> | undefined;
        m: (a: AnyAtom) => Mounted | undefined;
    } | {
        r: <Value>(readingAtom: Atom<Value>, version?: VersionObject) => AtomState<Value>;
        w: <Value_1, Update, Result extends void | Promise<void>>(writingAtom: WritableAtom<Value_1, Update, Result>, update: Update, version?: VersionObject) => Result;
        c: (_atom: AnyAtom | null, version?: VersionObject) => void;
        s: (atom: AnyAtom, callback: (version?: VersionObject) => void, version?: VersionObject) => () => void;
        h: (values: Iterable<readonly [AnyAtom, AnyAtomValue]>, version?: VersionObject) => void;
        n?: never;
        l?: never;
        a?: never;
        m?: never;
    };
};
export {};
