import { SerializableTevmState } from '@tevm/state';

/**
 * Interface for storage providers that can be used with sync-storage-persister
 * Provides a minimal subset of the Web Storage API (localStorage/sessionStorage)
 * for storing and retrieving data.
 *
 * @example
 * ```typescript
 * import { Storage } from '@tevm/sync-storage-persister'
 *
 * // Implement the Storage interface with localStorage
 * const webStorage: Storage = {
 *   getItem: (key) => localStorage.getItem(key),
 *   setItem: (key, value) => localStorage.setItem(key, value),
 *   removeItem: (key) => localStorage.removeItem(key)
 * }
 *
 * // Or create a custom in-memory implementation
 * const memoryStorage: Storage = {
 *   store: new Map<string, string>(),
 *   getItem: (key) => this.store.get(key) || null,
 *   setItem: (key, value) => this.store.set(key, value),
 *   removeItem: (key) => this.store.delete(key)
 * }
 * ```
 */
interface Storage {
    getItem: (key: string) => string | null;
    setItem: (key: string, value: string) => void;
    removeItem: (key: string) => void;
}

/**
 * Options for creating a sync storage persister.
 */
type CreateSyncStoragePersisterOptions = {
    /** The storage client used for setting and retrieving items from cache.
     * For SSR pass in `undefined`. Note that window.localStorage can be
     * `null` in Android WebViews depending on how they are configured.
     */
    storage: Storage;
    /** The key to use when storing the cache */
    key?: string;
    /** To avoid spamming, pass a time in ms to throttle saving the cache to disk */
    throttleTime?: number;
    /**
     * How to serialize the data to storage.
     * @default `JSON.stringify`
     */
    serialize?: (client: SerializableTevmState) => string;
    /**
     * How to deserialize the data from storage.
     * @default `JSON.parse`
     */
    deserialize?: (cachedString: string) => SerializableTevmState;
};

/**
 * Storage persister for client state
 */
type SyncStoragePersister = {
    /**
     * Persist serializable tevm state
     * @param state - State to be persisted
     * @param onError - Called when state fails to persist
     * @returns Error if one occurs during persistence
     */
    persistTevmState: (state: SerializableTevmState | undefined, onError?: (error: Error | undefined) => void) => Error | undefined;
    /**
     * Restores persisted state
     * @returns The persisted state if it exists
     */
    restoreState: () => SerializableTevmState | undefined;
    /**
     * Removes persisted state
     * @returns Error if one occurs during removal
     */
    removePersistedState: () => Error | undefined;
};

declare function createSyncStoragePersister({ storage, key, throttleTime, serialize, deserialize, }: CreateSyncStoragePersisterOptions): SyncStoragePersister;

/**
 * A persister that does nothing, useful as a default
 * @type {import('./SyncStoragePersister.js').SyncStoragePersister}
 */
declare const noopPersister: SyncStoragePersister;

export { type CreateSyncStoragePersisterOptions, type Storage, type SyncStoragePersister, createSyncStoragePersister, noopPersister };
