/** * Pagination and infinite-scroll composables for reactive data fetching. * * @module bquery/reactive */ import { Signal } from './core'; import { type AsyncDataState, type AsyncDataStatus, type UseFetchOptions } from './async-data'; /** Options for usePaginatedFetch(). */ export interface UsePaginatedFetchOptions extends UseFetchOptions { /** Initial page number (default: 1). */ initialPage?: number; } /** Return value of usePaginatedFetch(). */ export interface PaginatedState extends AsyncDataState { /** Current page number signal (writable). */ page: Signal; /** Go to the next page. */ next: () => Promise; /** Go to the previous page (minimum 1). */ prev: () => Promise; /** Jump to a specific page. */ goTo: (page: number) => Promise; } /** * Reactive paginated fetch composable. * * Takes a URL factory receiving the current page number, and exposes * `page`, `next()`, `prev()`, and `goTo()` helpers alongside the * standard `AsyncDataState`. * * @template TResponse - Raw parsed response type * @template TData - Stored response type after optional transformation * @param inputFactory - Function that receives the page number and returns a URL string, URL, or Request * @param options - Fetch and pagination options * @returns Paginated data state * * @example * ```ts * import { usePaginatedFetch } from '@bquery/bquery/reactive'; * * const users = usePaginatedFetch( * (page) => `/api/users?page=${page}`, * { baseUrl: 'https://api.example.com' } * ); * * // Navigate pages * await users.next(); * await users.prev(); * await users.goTo(5); * console.log(users.page.value); // 5 * ``` */ export declare const usePaginatedFetch: (inputFactory: (page: number) => string | URL | Request, options?: UsePaginatedFetchOptions) => PaginatedState; /** Options for useInfiniteFetch(). */ export interface UseInfiniteFetchOptions extends Omit, 'transform'> { /** Extract the cursor for the next page from a response. */ getNextCursor: (lastResponse: TResponse, allPages: TResponse[]) => TCursor | undefined; /** Transform all accumulated pages into the final data shape. */ transform?: (pages: TResponse[]) => TData; /** Initial cursor value (default: undefined, meaning first page). */ initialCursor?: TCursor; } /** Return value of useInfiniteFetch(). */ export interface InfiniteState { /** All accumulated page data, transformed. */ data: Signal; /** Raw accumulated pages. */ pages: Signal; /** Last error encountered. */ error: Signal; /** Current lifecycle status. */ status: Signal; /** Computed boolean that mirrors `status === 'pending'`. */ pending: { readonly value: boolean; peek(): boolean; }; /** Whether there are more pages to load. */ hasMore: { readonly value: boolean; peek(): boolean; }; /** Fetch the next page and append it to the accumulated data. */ fetchNextPage: () => Promise; /** Reset all pages and re-fetch from the initial cursor. */ refresh: () => Promise; /** Clear all accumulated data. */ clear: () => void; /** Dispose reactive watchers and prevent future executions. */ dispose: () => void; } /** * Reactive infinite-scroll / load-more composable. * * Accumulates pages of data and exposes `fetchNextPage()` to load * additional results. Uses a cursor-based approach with `getNextCursor()` * to determine pagination. * * @template TResponse - Raw parsed response type for a single page * @template TData - Transformed accumulated data type * @template TCursor - Cursor type used for pagination * @param inputFactory - Function receiving the cursor and returning a FetchInput * @param options - Fetch and infinite-scroll options * @returns Infinite data state with fetchNextPage(), hasMore, and accumulated pages * * @example * ```ts * import { useInfiniteFetch } from '@bquery/bquery/reactive'; * * const feed = useInfiniteFetch( * (cursor) => `/api/posts?cursor=${cursor ?? ''}`, * { * getNextCursor: (page) => page.length > 0 ? page[page.length - 1].id : undefined, * transform: (pages) => pages.flat(), * baseUrl: 'https://api.example.com', * } * ); * * // Load more pages * await feed.fetchNextPage(); * console.log(feed.data.value); // All accumulated posts * console.log(feed.hasMore.value); // true if more pages available * ``` */ export declare const useInfiniteFetch: (inputFactory: (cursor: TCursor | undefined) => string | URL | Request, options: UseInfiniteFetchOptions) => InfiniteState; //# sourceMappingURL=pagination.d.ts.map