import { Draft, Patch } from 'immer';

type StateTree = Record<string, any>;
type TransformGetters<G> = {
    [K in keyof G]: G[K] extends (...args: any[]) => infer R ? R : never;
};
type TransformActions<A> = A;
type SubscriptionCallback<S> = (state: S, prevState: S) => void;
interface PiniaCustomProperties<Id extends string = string, S extends StateTree = StateTree, G extends Record<string, any> = Record<string, any>, A extends Record<string, any> = Record<string, any>> {
}
interface StorePublicApi<S> {
    $patch: (updater: (draft: Draft<S>) => void) => void;
    $reset: () => void;
    $subscribe: (callback: SubscriptionCallback<S>) => () => void;
    $state: S;
}
type GetterContext<S, G> = Readonly<S> & TransformGetters<G>;
type ActionContext<S, G, A> = S & TransformGetters<G> & TransformActions<A> & StorePublicApi<S>;
type Store<Id extends string, S extends StateTree, G extends Record<string, any>, A extends Record<string, any>> = S & TransformGetters<G> & TransformActions<A> & StorePublicApi<S> & PiniaCustomProperties<Id, S, G, A>;
type StoreGeneric = Store<string, StateTree, Record<string, any>, Record<string, any>>;
type GettersImplementation<S> = {
    [K in string]: (state: S) => any;
};
interface DefineStoreOptions<S extends StateTree, G extends Record<string, any>, A extends Record<string, any>> {
    state: () => S;
    getters?: G & ThisType<GetterContext<S, G>> & GettersImplementation<S>;
    actions?: A & ThisType<ActionContext<S, G, A>>;
}
type StoreScope = {
    currentState: StateTree;
    listeners: Set<(state: any, prev: any, patches: Patch[]) => void>;
    getterCache: Map<string, any>;
    getterDependencies: Map<string, Set<string>>;
    subscribers: Map<string, Set<string>>;
    createStoreProxy: (onAccess?: (path: string[]) => void) => StoreGeneric;
};
interface Pinia {
    state: Record<string, StateTree>;
    use(plugin: PiniaPlugin): Pinia;
    _p: PiniaPlugin[];
    _s: Map<string, StoreGeneric>;
    _scopes: Map<string, StoreScope>;
}
interface PiniaPlugin {
    (context: PiniaPluginContext): Partial<PiniaCustomProperties> | void;
}
type PiniaPluginContext<Id extends string = string, S extends StateTree = StateTree, G extends Record<string, any> = Record<string, any>, A extends Record<string, any> = Record<string, any>> = {
    id: Id;
    store: Store<Id, S, G, A>;
    options: DefineStoreOptions<S, G, A>;
};
interface StoreDefinition<Id extends string, S extends StateTree, G extends Record<string, any>, A extends Record<string, any>> {
    useStore: () => Store<Id, S, G, A>;
    getStore: () => Store<Id, S, G, A>;
}

declare function createPinia(): Pinia;

declare function setActivePinia(pinia: Pinia): void;
declare function getActivePinia(): Pinia;

declare function defineStore<Id extends string, S extends StateTree, G extends Record<string, any> = {}, A extends Record<string, any> = {}>(id: Id, options: DefineStoreOptions<S, G, A>): StoreDefinition<Id, S, G, A>;

export { type DefineStoreOptions, type Pinia, type PiniaCustomProperties, type PiniaPlugin, type PiniaPluginContext, type StateTree, type Store, type StoreDefinition, type StoreGeneric, type SubscriptionCallback, createPinia, defineStore, getActivePinia, setActivePinia };
