import { StateTree, SubscriptionCallback } from 'pinia';
import { UnwrapRef } from 'vue';
export interface IStorage {
    getItem: (key: string) => any | Promise<any>;
    setItem: (key: string, value: any) => void | Promise<void>;
    removeItem: (key: string) => void | Promise<void>;
}
/**
 * @description
 * PluginOptions and StoreOptions shares CommonOptions interface,
 *
 * @example
 *
 * You could pass most commonly used option to PluginOptions:
 *
 * `store1` will persist to and rehydrate from `localStorage`, and
 * `store2` will persist to and rehydrate from `sessionStorage`:
 *
 * ```
 * const plugin = createPersistedStatePlugin({ storage: localStorage })
 * const store1 = defineStore('store-1', () => {})
 * const store2 = defineStore('store-2', () => {}, { persistedState: { storage: sessionStorage } })
 * ```
 */
export interface CommonOptions<S extends StateTree = StateTree> {
    /**
     * Whether to persist store.
     * @default true
     */
    persist?: boolean;
    /**
     * Where to store persisted state.
     *
     * @default localStorage
     */
    storage?: IStorage;
    /**
     * To ensure storage is available.
     */
    assertStorage?: (storage: IStorage) => void | Promise<void> | never;
    /**
     * A function for merging state when rehydrating state.
     *
     * @default (state, savedState) => savedState
     */
    merge?: (state: UnwrapRef<S>, savedState: UnwrapRef<S>) => UnwrapRef<S>;
    /**
     * When rehydrating, overwrite initial state (patch otherwise).
     *
     * @default false
     */
    overwrite?: boolean;
    /**
     * This method will be called right before `storage.setItem`.
     *
     * @default JSON.stringify
     */
    serialize?: (state: UnwrapRef<S>) => any;
    /**
     * This method will be called right after `storage.getItem`.
     *
     * @default JSON.parse
     */
    deserialize?: (value: any) => any;
    /**
     * A function that will be called to filter any mutations which will trigger setState on storage eventually.
     *
     * @default () => true
     */
    filter?: (mutation: Parameters<SubscriptionCallback<S>>['0'], state: Parameters<SubscriptionCallback<S>>['1']) => boolean;
}
export type PluginOptions<S extends StateTree> = CommonOptions<S>;
export type StoreOptions<S extends StateTree> = CommonOptions<S> & {
    /**
     * The key to store the persisted state under.
     *
     * @default store.$id
     */
    key?: string;
    /**
     * An array of any paths to partially persist the state.
     *
     * Use dot-notation `['key', 'nested.key', ['special.key']]` for nested fields.
     *
     * @default undefined
     *
     */
    includePaths?: (string | string[])[];
    /**
     * Opposite to `includePaths`, An array of any paths to exclude.
     *
     * Use dot-notation `['key', 'nested.key', ['special.key']]` for nested fields.
     *
     * Warning: Due to deep copying, `excludePaths` may cause performance issues, if possible, please use `includePaths` instead.
     * @default undefined
     */
    excludePaths?: (string | string[])[];
    /**
     * The `migrate` function enables versioning store. This will be called after `deserialize` but before actually overwriting/patching the store.
     *
     * @default {value => value}
     */
    migrate?: (value: any) => any | Promise<any>;
    /**
     * This function gives you the opportunity to perform some tasks before actually overwriting/patching the store, such as cleaning up the old state.
     *
     * @default {value => value}
     */
    beforeHydrate?: (oldState: UnwrapRef<S>) => void;
};
declare module 'pinia' {
    interface DefineStoreOptionsBase<S extends StateTree, Store> {
        persistedState?: StoreOptions<S>;
    }
    interface PiniaCustomProperties<Id extends string = string, S extends StateTree = StateTree, G = _GettersTree<S>, A = _ActionsTree> {
        $persistedState: {
            /**
             * Whether store is hydrated
             */
            isReady: () => Promise<void>;
            /**
             * Whether store is persisting
             */
            pending: boolean;
        };
    }
}
