type Subscriber<T> = (newValue: T) => void;
type Middleware<T> = (value: T, next: (newValue: T) => void) => void;
type NamedMiddleware<T> = {
    name?: string;
    fn: Middleware<T>;
};
interface Chunk<T> {
    /** Get the current value of the chunk. */
    get: () => T;
    /** Set a new value for the chunk & Update existing value efficiently. */
    set: (newValueOrUpdater: T | ((currentValue: T) => T)) => void;
    /** Subscribe to changes in the chunk. Returns an unsubscribe function. */
    subscribe: (callback: Subscriber<T>) => () => void;
    /** Create a derived chunk based on this chunk's value. */
    derive: <D>(fn: (value: T) => D) => Chunk<D>;
    /** Reset the chunk to its initial value. */
    reset: () => void;
    /** Destroy the chunk and all its subscribers. */
    destroy: () => void;
}
/**
 * Batch multiple chunk updates into a single re-render.
 * Useful for updating multiple chunks at once without causing multiple re-renders.
 */
declare function batch(callback: () => void): void;
declare function chunk<T>(initialValue: T, middleware?: (Middleware<T> | NamedMiddleware<T>)[]): Chunk<T>;

type AsyncChunkOpt<T, E extends Error> = {
    initialData?: T | null;
    onError?: (error: E) => void;
    retryCount?: number;
    retryDelay?: number;
};
type InferAsyncData<T> = T extends AsyncChunk<infer U, Error> ? U : never;
type CombinedData<T extends Record<string, AsyncChunk<any>>> = {
    [K in keyof T]: InferAsyncData<T[K]> | null;
};
type CombinedState<T extends Record<string, AsyncChunk<any>>> = {
    loading: boolean;
    error: Error | null;
    errors: Partial<{
        [K in keyof T]: Error;
    }>;
    data: CombinedData<T>;
};

interface AsyncState<T, E extends Error> {
    loading: boolean;
    error: E | null;
    data: T | null;
    lastFetched?: number;
}
interface RefreshConfig {
    /** Time in milliseconds after which data becomes stale */
    staleTime?: number;
    /** Time in milliseconds to cache data before considering it expired */
    cacheTime?: number;
    /** Auto-refresh interval in milliseconds */
    refetchInterval?: number;
}
interface AsyncChunkOptExtended<T, E extends Error> extends AsyncChunkOpt<T, E> {
    refresh?: RefreshConfig;
    /** Enable/disable the fetcher - useful for conditional fetching */
    enabled?: boolean;
}
interface AsyncChunk<T, E extends Error = Error> extends Chunk<AsyncState<T, E>> {
    /** Reload the data from the source. */
    reload: () => Promise<void>;
    /** Smart refresh - respects stale time */
    refresh: () => Promise<void>;
    /** Mutate the data directly. */
    mutate: (mutator: (currentData: T | null) => T) => void;
    /** Reset the state to the initial value. */
    reset: () => void;
    /** Clean up intervals and timeouts */
    cleanup: () => void;
}
declare function asyncChunk<T, E extends Error = Error>(fetcher: () => Promise<T>, options?: AsyncChunkOptExtended<T, E>): AsyncChunk<T, E>;
declare function asyncChunk<T, E extends Error = Error, P extends any[] = []>(fetcher: (...params: P) => Promise<T>, options?: AsyncChunkOptExtended<T, E>): AsyncChunk<T, E> & {
    /** Reload with new parameters */
    reload: (...params: P) => Promise<void>;
    /** Smart refresh with parameters */
    refresh: (...params: P) => Promise<void>;
    /** Set parameters for future calls */
    setParams: (...params: P) => void;
};

type ChunkValue<T> = T extends Chunk<infer U> ? U : never;
type DependencyValues<T extends Chunk<any>[]> = {
    [K in keyof T]: T[K] extends Chunk<any> ? ChunkValue<T[K]> : never;
};
interface Computed<T> extends Chunk<T> {
    /**
    * Checks if the computed value needs to be recalculated due to dependency changes.
    * @returns True if the computed value is dirty, false otherwise.
    */
    isDirty: () => boolean;
    /** Manually forces recalculation of the computed value from its dependencies. */
    recompute: () => void;
}
declare function computed<TDeps extends Chunk<any>[], TResult>(dependencies: [...TDeps], computeFn: (...args: DependencyValues<TDeps>) => TResult): Computed<TResult>;

interface SelectOptions {
    /**
     * Configuration options for selector functions.
     * @property {boolean} [useShallowEqual] - When true, performs a shallow equality check
     * on the derived selector results to prevent unnecessary updates.
     */
    useShallowEqual?: boolean;
}
/**
 * Creates a derived read-only chunk based on a selector function.
 * @param sourceChunk The source chunk to derive from.
 * @param selector A function that extracts part of the source value.
 * @param options Optional settings for shallow equality comparison.
 * @returns A read-only derived chunk.
 */
declare function select<T, S>(sourceChunk: Chunk<T>, selector: (value: T) => S, options?: SelectOptions): Chunk<S>;

declare function isValidChunkValue(value: unknown): boolean;
declare function isChunk<T>(value: unknown): value is Chunk<T>;
declare function once<T>(fn: () => T): () => T;
declare function combineAsyncChunks<T extends Record<string, AsyncChunk<any>>>(chunks: T): Chunk<CombinedState<T>>;

declare const logger: Middleware<any>;

declare const nonNegativeValidator: Middleware<number>;

interface ChunkWithHistory<T> extends Chunk<T> {
    /**
   * Reverts to the previous state (if available).
   */
    undo: () => void;
    /**
     * Moves to the next state (if available).
     */
    redo: () => void;
    /**
     * Returns true if there is a previous state to revert to.
     */
    canUndo: () => boolean;
    /**
     * Returns true if there is a next state to move to.
     */
    canRedo: () => boolean;
    /**
     * Returns an array of all the values in the history.
     */
    getHistory: () => T[];
    /**
     * Clears the history, keeping only the current value.
     */
    clearHistory: () => void;
}
declare function withHistory<T>(baseChunk: Chunk<T>, options?: {
    maxHistory?: number;
}): ChunkWithHistory<T>;

interface PersistOptions<T> {
    key: string;
    storage?: Storage;
    serialize?: (value: T) => string;
    deserialize?: (value: string) => T;
}
declare function withPersistence<T>(baseChunk: Chunk<T>, options: PersistOptions<T>): Chunk<T>;

declare const index_logger: typeof logger;
declare const index_nonNegativeValidator: typeof nonNegativeValidator;
declare const index_withHistory: typeof withHistory;
declare const index_withPersistence: typeof withPersistence;
declare namespace index {
  export { index_logger as logger, index_nonNegativeValidator as nonNegativeValidator, index_withHistory as withHistory, index_withPersistence as withPersistence };
}

export { type Chunk, type Middleware, asyncChunk, batch, chunk, combineAsyncChunks, computed, isChunk, isValidChunkValue, index as middleware, once, select };
