{"version":3,"file":"use-cursor-query.cjs","names":[],"sources":["../../src/query/use-cursor-query.ts"],"sourcesContent":["import { useInfiniteQuery } from \"@tanstack/react-query\";\nimport type { InfiniteData, QueryKey, UseInfiniteQueryOptions } from \"@tanstack/react-query\";\n\nimport type { CursorPage, CursorParams } from \"./pagination\";\n\nexport interface UseCursorQueryOptions<T> extends Omit<\n    UseInfiniteQueryOptions<\n        CursorPage<T>,\n        Error,\n        InfiniteData<CursorPage<T>, string | null>,\n        QueryKey,\n        string | null\n    >,\n    \"queryKey\" | \"queryFn\" | \"initialPageParam\" | \"getNextPageParam\"\n> {\n    /** Base query key — `limit`/sort is appended for cache isolation. */\n    queryKey: QueryKey;\n    /** Fetcher receiving the cursor params; return the backend envelope. */\n    queryFn: (params: CursorParams) => Promise<CursorPage<T>> | CursorPage<T>;\n    /** Batch size sent as `limit`. Default: 20. */\n    limit?: number;\n    /** Initial `order_by`. */\n    orderBy?: string;\n    /** Initial `ascending`. Default: false. */\n    ascending?: boolean;\n}\n\nexport interface UseCursorQueryResult<T> {\n    /** All rows fetched so far, flattened across batches. */\n    items: T[];\n    /** The raw batches, in fetch order. */\n    pages: CursorPage<T>[];\n    hasNextPage: boolean;\n    isLoading: boolean;\n    isFetchingNextPage: boolean;\n    error: Error | null;\n    /** Fetch the next batch (no-op when exhausted). */\n    fetchNextPage: () => void;\n    /** Refetch from the first batch. */\n    refetch: () => void;\n}\n\n/**\n * Cursor-pagination hook over TanStack Query's `useInfiniteQuery` for the\n * Tempest `CursorPaginationSchema` envelope\n * (`{ items, next_cursor, has_more, limit }`).\n *\n * The opaque `next_cursor` is fed straight back as the next page param; the\n * loop stops when `has_more` is false (or `next_cursor` is null).\n *\n * @example\n * const feed = useCursorQuery<Post>({\n *     queryKey: [\"feed\"],\n *     limit: 30,\n *     queryFn: (params) => postsService.listPosts(params),\n * });\n * // feed.items, feed.fetchNextPage(), feed.hasNextPage\n */\nexport function useCursorQuery<T>(options: UseCursorQueryOptions<T>): UseCursorQueryResult<T> {\n    const { queryKey, queryFn, limit = 20, orderBy, ascending = false, ...queryOptions } = options;\n\n    const query = useInfiniteQuery<\n        CursorPage<T>,\n        Error,\n        InfiniteData<CursorPage<T>, string | null>,\n        QueryKey,\n        string | null\n    >({\n        ...queryOptions,\n        queryKey: [...queryKey, { limit, orderBy, ascending }],\n        initialPageParam: null,\n        queryFn: ({ pageParam }) =>\n            queryFn({ cursor: pageParam, limit, order_by: orderBy, ascending }),\n        getNextPageParam: (last) => (last.has_more ? last.next_cursor : undefined),\n    });\n\n    const pages = query.data?.pages ?? [];\n\n    return {\n        items: pages.flatMap((p) => p.items),\n        pages,\n        hasNextPage: query.hasNextPage,\n        isLoading: query.isLoading,\n        isFetchingNextPage: query.isFetchingNextPage,\n        error: query.error,\n        fetchNextPage: () => void query.fetchNextPage(),\n        refetch: () => void query.refetch(),\n    };\n}\n"],"mappings":"uCA0DA,SAAgB,EAAkB,EAA4D,CAC1F,GAAM,CAAE,WAAU,UAAS,QAAQ,GAAI,UAAS,YAAY,GAAO,GAAG,GAAiB,EAEjF,GAAA,EAAQ,EAAA,iBAAA,CAMZ,CACE,GAAG,EACH,SAAU,CAAC,GAAG,EAAU,CAAE,QAAO,UAAS,WAAU,CAAC,EACrD,iBAAkB,KAClB,SAAU,CAAE,eACR,EAAQ,CAAE,OAAQ,EAAW,QAAO,SAAU,EAAS,WAAU,CAAC,EACtE,iBAAmB,GAAU,EAAK,SAAW,EAAK,YAAc,IAAA,EACpE,CAAC,EAEK,EAAQ,EAAM,MAAM,OAAS,CAAC,EAEpC,MAAO,CACH,MAAO,EAAM,QAAS,GAAM,EAAE,KAAK,EACnC,QACA,YAAa,EAAM,YACnB,UAAW,EAAM,UACjB,mBAAoB,EAAM,mBAC1B,MAAO,EAAM,MACb,kBAAqB,KAAK,EAAM,cAAc,EAC9C,YAAe,KAAK,EAAM,QAAQ,CACtC,CACJ"}