import { AgentInfo, BrowserLocation } from "../transport";
export declare const Partition: {
    Instance: "instance";
    Service: "service";
};
export declare const Persistence: {
    Session: "session";
    Local: "local";
    None: "none";
};
export type ActionHandler<TState, TArgs extends any[], TResult> = (state: TState, setState: SetStateFunction<TState>, target: BrowserLocation, ...args: TArgs) => Promise<TResult>;
export type ActionDefinition<TState, TArgs extends any[], TResult> = {
    handler: ActionHandler<TState, TArgs, TResult>;
    validate?: (...args: TArgs) => void;
};
export type ActionsConfig<TState> = {
    [K: string]: ActionDefinition<TState, any[], Partial<TState>>;
};
export type SetStateFunction<TState> = {
    (state: Partial<TState>): Promise<void>;
    (state: Partial<TState>, key: string): Promise<void>;
};
export type SetStateCallback<TConfig extends AnyConfig> = {
    (state: Partial<DerivedServiceState<TConfig>>): Promise<void>;
    (state: Partial<DerivedInstanceState<TConfig>>, key: string): Promise<void>;
};
export type ConfigItem<T> = {
    default: T;
    partition?: (typeof Partition)[keyof typeof Partition];
    persist?: (typeof Persistence)[keyof typeof Persistence];
};
export type AnyConfig = Record<string, ConfigItem<any> | ActionDefinition<any, any[], any>>;
export type StateConfig<T extends AnyConfig> = {
    [P in keyof T]: T[P] extends ConfigItem<any> ? T[P] : never;
};
export type ActionConfig<T extends AnyConfig> = {
    [P in keyof T]: T[P] extends ActionDefinition<any, any[], any> ? T[P] : never;
};
export type DerivedState<T extends AnyConfig> = {
    [P in keyof T]: T[P] extends ConfigItem<infer DefaultType> ? DefaultType : never;
};
export type DerivedInstanceState<T extends AnyConfig> = {
    [P in keyof T]: T[P] extends ConfigItem<infer DefaultType> & {
        partition: "instance";
    } ? DefaultType : never;
};
export type DerivedServiceState<T extends AnyConfig> = {
    [P in keyof T]: T[P] extends ConfigItem<infer DefaultType> ? T[P] extends {
        partition: "instance";
    } ? never : DefaultType : never;
};
type OmitNever<T> = {
    [K in keyof T as T[K] extends never ? never : K]: T[K];
};
export type MergeStateTypes<TInstance, TService> = OmitNever<TInstance> & OmitNever<TService>;
export declare const isStateItem: <T>(item: ConfigItem<T> | ActionDefinition<any, any[], any>) => item is ConfigItem<T>;
export declare const isActionItem: <TState, TArgs extends any[], TResult>(item: ConfigItem<any> | ActionDefinition<TState, TArgs, TResult>) => item is ActionDefinition<TState, TArgs, TResult>;
type StateSubscriber<TConfig extends AnyConfig> = {
    keys?: Array<keyof DerivedState<TConfig>>;
    callback: (changes: StateUpdate<TConfig>) => void;
};
type CrannAgent<TConfig extends AnyConfig> = {
    get: () => DerivedState<TConfig>;
    set: (update: StateUpdate<TConfig>) => void;
    subscribe: (callback: (changes: StateUpdate<TConfig>) => void, keys?: Array<keyof TConfig>) => () => void;
    getAgentInfo: () => AgentInfo;
    onReady: (callback: (info: ConnectionStatus) => void) => () => void;
};
type UseCrann<TConfig extends AnyConfig> = <K extends keyof DerivedState<TConfig>>(key: K) => [
    DerivedState<TConfig>[K],
    (value: DerivedState<TConfig>[K]) => void,
    (callback: (update: StateChangeUpdate<TConfig, K>) => void) => () => void
];
type ConnectReturn<TConfig extends AnyConfig> = {
    useCrann: UseCrann<TConfig>;
    get: CrannAgent<TConfig>["get"];
    set: CrannAgent<TConfig>["set"];
    subscribe: CrannAgent<TConfig>["subscribe"];
    getAgentInfo: CrannAgent<TConfig>["getAgentInfo"];
    onReady: CrannAgent<TConfig>["onReady"];
    callAction: (name: string, ...args: any[]) => Promise<any>;
    onDisconnect: (callback: () => void) => () => void;
    onReconnect: (callback: (info: AgentInfo) => void) => () => void;
};
export type StateChanges<T extends AnyConfig> = {
    [K in keyof DerivedState<T>]?: NonNullable<DerivedState<T>[K]>;
};
type StateChangeUpdate<TConfig extends AnyConfig, K extends keyof DerivedState<TConfig>> = {
    current: DerivedState<TConfig>[K];
    previous: DerivedState<TConfig>[K];
    state: DerivedState<TConfig>;
};
export type StateChangeListener<TConfig extends AnyConfig> = (state: DerivedInstanceState<TConfig> | DerivedState<TConfig>, changes: StateChanges<TConfig>, agent?: AgentInfo) => void;
type AgentSubscription<TConfig extends AnyConfig> = {
    (callback: (changes: StateUpdate<TConfig>) => void, key?: keyof DerivedState<TConfig>): number;
};
type StateUpdate<TConfig extends AnyConfig> = StateChanges<TConfig>;
export type CrannOptions = {
    debug?: boolean;
    storagePrefix?: string;
};
type ConnectionStatus = {
    connected: boolean;
    agent?: AgentInfo;
};
export type CrannConfig<TState> = {
    [K: string]: ConfigItem<any> | ActionsConfig<TState>;
};
export { StateSubscriber, CrannAgent, AgentSubscription, StateUpdate, DerivedState as State, ConnectReturn, UseCrann, ConnectionStatus, StateChangeUpdate, };
