import { SignalStoreFeatureResult, SignalStoreFeature, EmptyFeatureResult } from '@ngrx/signals';

interface Config<T> {
    /**
     * These keys will not get saved to storage
     */
    excludeKeys: Array<keyof T>;
    /**
     * Serializer for the state, by default it uses `JSON.stringify()`
     * @param state the last state known before it gets saved to storage
     */
    serialize: (state: T) => string;
    /**
     * Deserializer for the state, by default it uses `JSON.parse()`
     * @param state the last state known from the storage location
     */
    deserialize: (state: string) => T;
    /**
     * Save to storage will only occur when this function returns true
     * @param state the last state known before it gets saved to storage
     */
    saveIf: (state: T) => boolean;
    /**
     * Removes the state from storage when this function returns true
     * @param state the last state known
     */
    removeIf: (state: T) => boolean;
    /**
     * Function that gets executed on a storage error (get/set)
     * @param error the error that occurred
     */
    error: (error: any) => void;
}

/**
 * The `withStorage` function that lets you save the state to localstorage/sessionstorage
 * and rehydrate the state upon page load.
 *
 * @param key the key under which the state should be saved into `Storage`
 * @param storage function that returns an implementation of the `Storage` interface, like: `sessionStorage` or `localStorage`
 *
 * @example
 *  export const CounterStore = signalStore(
 *     withState({
 *       count: 0
 *     }),
 *     withStorage('myKey', () => sessionStorage)
 *   )
 */
declare function withStorage<T extends SignalStoreFeatureResult>(key: string, storage: () => Storage, config?: Partial<Config<T['state']>>): SignalStoreFeature<T, EmptyFeatureResult>;

export { withStorage };
export type { Config };
