declare abstract class Persistent<Value> {
    key: string;
    protected _value: Value;
    typeAssertion: (value: unknown) => value is Value;
    constructor(key: string, _value: Value, typeAssertion: (value: unknown) => value is Value);
    abstract get serialized(): string | null;
    abstract get value(): Value | null;
    abstract set value(value: Value | null);
    abstract clear(): void;
}

type PersistType = 'localStorage' | 'sessionStorage';
interface Options<State> {
    persist?: {
        type: PersistType;
        key: string;
        typeAssertion: (value: unknown) => value is State;
    };
}
interface Vanilla<State> {
    get: () => State;
    subscribe: (callback: () => void) => () => void;
    persistStore: Persistent<State> | null;
}
type SetAction<State> = (action: State | ((prev: State) => State)) => State;
interface VanillaStore<State> extends Vanilla<State> {
    set: SetAction<State>;
}
interface VanillaSelect<State> extends Vanilla<State> {
    set: () => void;
}

interface Subscription<Value> {
    getCurrentValue: () => Value;
    subscribe: (callback: () => void) => () => void;
}
declare const createVanillaStore: <State>(initialState: State, equalityFn?: (a: State, b: State) => boolean, options?: Options<State>) => VanillaStore<State>;

declare function useStore<State>(store: VanillaSelect<State>, initialValue?: State): [State, never];
declare function useStore<State>(store: VanillaStore<State>, initialValue?: State): [State, SetAction<State>];
declare const useGetStore: <State>(store: VanillaStore<State> | VanillaSelect<State>, initialValue?: State) => State;
declare function useSetStore<State>(store: VanillaSelect<State>, initialValue?: State): never;
declare function useSetStore<State>(store: VanillaStore<State>, initialValue?: State): SetAction<State>;
declare function useStoreSelector<State, Value>(store: VanillaSelect<State>, selector: (state: State) => Value, options?: {
    initialStoreValue?: State;
    isEqual?: (a: Value, b: Value) => boolean;
}): [Value, never];
declare function useStoreSelector<State, Value>(store: VanillaStore<State>, selector: (state: State) => Value, options?: {
    initialStoreValue?: State;
    isEqual?: (a: Value, b: Value) => boolean;
}): [Value, SetAction<State>];

declare class SessionStoragePersist<Value> extends Persistent<Value> {
    get serialized(): string | null;
    get value(): Value;
    set value(value: Value);
    clear(): void;
}

declare class LocalStoragePersist<Value> extends Persistent<Value> {
    get serialized(): string | null;
    get value(): Value;
    set value(value: Value);
    clear(): void;
}

declare const createVanillaSelect: <State, StoreState>(store: VanillaStore<StoreState>, selectFn: (state: StoreState) => State, equalityFn?: (a: State, b: State) => boolean, options?: Options<State>) => VanillaSelect<State>;

/**
 * @description compare two objects shallowly. inspired by https://github.com/facebook/react/blob/main/packages/shared/shallowEqual.js
 * @param a
 * @param b
 * @returns boolean
 */
declare function shallowEqual<T>(a: T, b: T): boolean;

export { LocalStoragePersist, type Options, type PersistType, SessionStoragePersist, type SetAction, type Subscription, type Vanilla, type VanillaSelect, type VanillaStore, createVanillaSelect, createVanillaStore, shallowEqual, useGetStore, useSetStore, useStore, useStoreSelector };
