import type { LoaderDefinition, LoadOptions } from "./types.js";
/**
 * Load function type with form action support
 */
export type LoadFunction<T> = ((options?: LoadOptions) => Promise<T>) & {
    /** Form action for progressive enhancement - can be passed to form action prop */
    action: (formData: FormData) => Promise<void>;
};
/**
 * Result type for useLoader hook (strict - data is required)
 */
export interface UseLoaderResult<T> {
    /** The loaded data - guaranteed to exist when loader is registered on route */
    data: T;
    /** True while a load() is in progress */
    isLoading: boolean;
    /** Error from the most recent load attempt, null if successful */
    error: Error | null;
    /** Function to trigger a fetch (only works if loader is fetchable) */
    load: LoadFunction<T>;
    /** Alias for load */
    refetch: LoadFunction<T>;
}
/**
 * Result type for useFetchLoader hook (flexible - data is optional)
 */
export interface UseFetchLoaderResult<T> {
    /** The loaded data - may be undefined if not yet fetched or not in context */
    data: T | undefined;
    /** True while a load() is in progress */
    isLoading: boolean;
    /** Error from the most recent load attempt, null if successful */
    error: Error | null;
    /** Function to trigger a fetch (only works if loader is fetchable) */
    load: LoadFunction<T>;
    /** Alias for load */
    refetch: LoadFunction<T>;
}
/**
 * Options for useLoader hook
 */
export interface UseLoaderOptions {
    /**
     * If true (default), errors from load() will be thrown to the nearest error boundary.
     * If false, errors are only captured in the `error` state.
     * @default true
     */
    throwOnError?: boolean;
}
/**
 * Hook to access loader data from route context (strict version)
 *
 * Use this when the loader is registered on the route via `loader()`.
 * The data is guaranteed to exist - throws an error if not found.
 *
 * For on-demand fetching or when loader might not be in context,
 * use `useFetchLoader` instead.
 *
 * @param loader - The loader definition (must be registered on route)
 * @param options - Optional configuration
 * @returns Object with data (guaranteed), isLoading, error, load, and refetch
 * @throws Error if loader data is not found in context
 *
 * @example Basic usage - accessing route loader data
 * ```tsx
 * "use client";
 * import { useLoader } from "rsc-router/client";
 * import { CartLoader } from "../loaders/cart";
 *
 * // In route definition: loader(CartLoader)
 *
 * export function CartIcon() {
 *   const { data } = useLoader(CartLoader);
 *   // data is guaranteed to be CartData, not CartData | undefined
 *   return <span>Cart ({data.items.length})</span>;
 * }
 * ```
 */
export declare function useLoader<T>(loader: LoaderDefinition<T>, options?: UseLoaderOptions): UseLoaderResult<T>;
/**
 * Hook to access loader data with optional fetching (flexible version)
 *
 * Use this when:
 * - The loader might not be registered on the route
 * - You want to fetch data on-demand from the client
 * - You're building a reusable component that doesn't assume route context
 *
 * If the loader IS registered on the route, it will still get the initial
 * data from context - you just have to handle the `undefined` case in types.
 *
 * @param loader - The loader definition
 * @param options - Optional configuration
 * @returns Object with data (may be undefined), isLoading, error, load, and refetch
 *
 * @example On-demand fetching
 * ```tsx
 * "use client";
 * import { useFetchLoader } from "rsc-router/client";
 * import { SearchLoader } from "../loaders/search";
 *
 * export function SearchResults() {
 *   const { data, load, isLoading } = useFetchLoader(SearchLoader);
 *
 *   const handleSearch = async (query: string) => {
 *     await load({ params: { query } });
 *   };
 *
 *   return (
 *     <div>
 *       <button onClick={() => handleSearch("test")}>Search</button>
 *       {isLoading && <span>Loading...</span>}
 *       {data?.results.map(r => <div key={r.id}>{r.name}</div>)}
 *     </div>
 *   );
 * }
 * ```
 *
 * @example With route context (hybrid usage)
 * ```tsx
 * // Loader registered on route: loader(UserLoader)
 * // useFetchLoader still works - gets initial data from context
 * const { data, load } = useFetchLoader(UserLoader);
 * // data is UserData | undefined (even though it will have initial value)
 * ```
 */
export declare function useFetchLoader<T>(loader: LoaderDefinition<T>, options?: UseLoaderOptions): UseFetchLoaderResult<T>;
//# sourceMappingURL=use-loader.d.ts.map