diff --git a/examples/query/react/infinite-queries/package.json b/examples/query/react/infinite-queries/package.json
index 933e07886d..e3c7934767 100644
--- a/examples/query/react/infinite-queries/package.json
+++ b/examples/query/react/infinite-queries/package.json
@@ -15,7 +15,7 @@
"type-check": "tsc --noEmit"
},
"dependencies": {
- "@reduxjs/toolkit": "https://pkg.csb.dev/reduxjs/redux-toolkit/commit/aa419c22/@reduxjs/toolkit/_pkg.tgz",
+ "@reduxjs/toolkit": "https://pkg.csb.dev/reduxjs/redux-toolkit/commit/c9cc8ca0/@reduxjs/toolkit/_pkg.tgz",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-intersection-observer": "^9.13.1",
diff --git a/examples/query/react/infinite-queries/src/App.tsx b/examples/query/react/infinite-queries/src/App.tsx
index af9d854e4d..442c3306d7 100644
--- a/examples/query/react/infinite-queries/src/App.tsx
+++ b/examples/query/react/infinite-queries/src/App.tsx
@@ -1,12 +1,16 @@
+import { BrowserRouter, Link, Route, Routes, useLocation } from "react-router"
import "./App.css"
-import { BrowserRouter, Routes, Route, Link } from "react-router"
-import { PaginationExample } from "./features/pagination/PaginationExample"
+import { Outlet } from "react-router"
+import BidirectionalCursorInfScroll from "./features/bidirectional-cursor-infinite-scroll/BidirectionalCursorInfScroll"
import {
- InfiniteScrollExample,
InfiniteScrollAbout,
+ InfiniteScrollExample,
} from "./features/infinite-scroll/InfiniteScrollExample"
+import LimitOffsetExample from "./features/limit-offset/LimitOffsetExample"
import { InfiniteScrollMaxPagesExample } from "./features/max-pages/InfiniteScrollMaxExample"
+import PaginationInfScrollExample from "./features/pagination-infinite-scroll/PaginationInfScrollExample"
+import { PaginationExample } from "./features/pagination/PaginationExample"
const Menu = () => {
return (
@@ -14,13 +18,30 @@ const Menu = () => {
Examples
-
- Pagination
+ Pagination
+
+ -
+ Infinite Scroll
-
- Infinite Scroll
+
+ Infinite Scroll + max pages
+
-
- Infinite Scroll + max pages
+
+ Bidirectional Cursor-Based Infinite Scroll
+
+
+ -
+
+ Limit and Offset Infinite Scroll
+
+
+ -
+
+ Pagination Infinite Scroll
+
@@ -32,18 +53,38 @@ const App = () => {
RTKQ Infinite Query Example Showcase
+
} />
- } />
- } />
- }
- />
}
- />
+ path="/examples"
+ element={
+
+ Back to Menu
+
+
+ }
+ >
+ } />
+ } />
+ }
+ />
+ }
+ />
+ }
+ />
+ } />
+ }
+ />
+
diff --git a/examples/query/react/infinite-queries/src/app/useIntersectionCallback.ts b/examples/query/react/infinite-queries/src/app/useIntersectionCallback.ts
new file mode 100644
index 0000000000..63834f0cef
--- /dev/null
+++ b/examples/query/react/infinite-queries/src/app/useIntersectionCallback.ts
@@ -0,0 +1,22 @@
+import { useCallback, useRef } from "react"
+
+export function useIntersectionCallback(onIntersectCallback: () => void) {
+ const intersectionObserverRef = useRef(null)
+
+ return useCallback(
+ (node: HTMLDivElement | null) => {
+ if (intersectionObserverRef.current) {
+ intersectionObserverRef.current.disconnect()
+ }
+
+ intersectionObserverRef.current = new IntersectionObserver(entries => {
+ if (entries[0].isIntersecting) {
+ onIntersectCallback()
+ }
+ })
+
+ if (node) intersectionObserverRef.current.observe(node)
+ },
+ [onIntersectCallback],
+ )
+}
diff --git a/examples/query/react/infinite-queries/src/features/bidirectional-cursor-infinite-scroll/BidirectionalCursorInfScroll.tsx b/examples/query/react/infinite-queries/src/features/bidirectional-cursor-infinite-scroll/BidirectionalCursorInfScroll.tsx
new file mode 100644
index 0000000000..5011057290
--- /dev/null
+++ b/examples/query/react/infinite-queries/src/features/bidirectional-cursor-infinite-scroll/BidirectionalCursorInfScroll.tsx
@@ -0,0 +1,136 @@
+import React, { useCallback, useEffect, useRef, useState } from "react"
+import { Link, useLocation } from "react-router"
+import { useIntersectionCallback } from "../../app/useIntersectionCallback"
+import { apiWithInfiniteScroll } from "./infiniteScrollApi"
+
+const limit = 10
+
+function BidirectionalCursorInfScroll({ startingProject = { id: 25 } }) {
+ const {
+ hasPreviousPage,
+ hasNextPage,
+ data,
+ error,
+ isFetching,
+ isLoading,
+ isError,
+ fetchNextPage,
+ fetchPreviousPage,
+ isFetchingNextPage,
+ isFetchingPreviousPage,
+ } =
+ apiWithInfiniteScroll.endpoints.getProjectsBidirectionalCursor.useInfiniteQuery(
+ limit,
+ {
+ initialPageParam: {
+ around: startingProject.id,
+ limit,
+ },
+ },
+ )
+
+ const beforeRef = useIntersectionCallback(fetchPreviousPage)
+ const afterRef = useIntersectionCallback(fetchNextPage)
+
+ const location = useLocation()
+
+ const startingProjectRef = useRef(null)
+ const [hasCentered, setHasCentered] = useState(false)
+
+ useEffect(() => {
+ if (hasCentered) return
+ const startingElement = startingProjectRef.current
+ if (startingElement) {
+ startingElement.scrollIntoView({
+ behavior: "auto",
+ block: "center",
+ })
+ setHasCentered(true)
+ }
+ }, [data?.pages, hasCentered])
+
+ return (
+
+
Bidirectional Cursor-Based Infinite Scroll
+ {isLoading ? (
+
Loading...
+ ) : isError ? (
+
Error: {error.message}
+ ) : null}
+ <>
+
+
+
+
+
+ {data?.pages.map(page => (
+
+ {page.projects.map((project, index, arr) => {
+ return (
+
+
{`Project ${project.id} (created at: ${project.createdAt})`}
+
{`Server Time: ${page.serverTime}`}
+
+ )
+ })}
+
+ ))}
+
+
+
+
+
+
+ {isFetching && !isFetchingPreviousPage && !isFetchingNextPage
+ ? "Background Updating..."
+ : null}
+
+ >
+
+
+
+ Go to another page
+
+
+ )
+}
+
+export default BidirectionalCursorInfScroll
diff --git a/examples/query/react/infinite-queries/src/features/bidirectional-cursor-infinite-scroll/infiniteScrollApi.ts b/examples/query/react/infinite-queries/src/features/bidirectional-cursor-infinite-scroll/infiniteScrollApi.ts
new file mode 100644
index 0000000000..2a51d0fe36
--- /dev/null
+++ b/examples/query/react/infinite-queries/src/features/bidirectional-cursor-infinite-scroll/infiniteScrollApi.ts
@@ -0,0 +1,82 @@
+import { baseApi } from "../baseApi"
+
+type Project = {
+ id: number
+ createdAt: string
+}
+
+type ProjectsCursorPaginated = {
+ projects: Project[]
+ serverTime: string
+ pageInfo: {
+ startCursor: number
+ endCursor: number
+ hasNextPage: boolean
+ hasPreviousPage: boolean
+ }
+}
+
+interface ProjectsInitialPageParam {
+ before?: number
+ around?: number
+ after?: number
+ limit: number
+}
+type QueryParamLimit = number
+
+export const apiWithInfiniteScroll = baseApi.injectEndpoints({
+ endpoints: builder => ({
+ getProjectsBidirectionalCursor: builder.infiniteQuery<
+ ProjectsCursorPaginated,
+ QueryParamLimit,
+ ProjectsInitialPageParam
+ >({
+ query: ({ before, after, around, limit }) => {
+ const params = new URLSearchParams()
+ params.append("limit", String(limit))
+ if (after != null) {
+ params.append("after", String(after))
+ } else if (before != null) {
+ params.append("before", String(before))
+ } else if (around != null) {
+ params.append("around", String(around))
+ }
+
+ return {
+ url: `https://example.com/api/projectsBidirectionalCursor?${params.toString()}`,
+ }
+ },
+ infiniteQueryOptions: {
+ initialPageParam: { limit: 10 },
+ getPreviousPageParam: (
+ firstPage,
+ allPages,
+ firstPageParam,
+ allPageParams,
+ ) => {
+ if (!firstPage.pageInfo.hasPreviousPage) {
+ return undefined
+ }
+ return {
+ before: firstPage.pageInfo.startCursor,
+ limit: firstPageParam.limit,
+ }
+ },
+ getNextPageParam: (
+ lastPage,
+ allPages,
+ lastPageParam,
+ allPageParams,
+ ) => {
+ if (!lastPage.pageInfo.hasNextPage) {
+ return undefined
+ }
+ return {
+ after: lastPage.pageInfo.endCursor,
+ limit: lastPageParam.limit,
+ }
+ },
+ },
+ }),
+ }),
+})
diff --git a/examples/query/react/infinite-queries/src/features/limit-offset/LimitOffsetExample.tsx b/examples/query/react/infinite-queries/src/features/limit-offset/LimitOffsetExample.tsx
new file mode 100644
index 0000000000..9610879fb2
--- /dev/null
+++ b/examples/query/react/infinite-queries/src/features/limit-offset/LimitOffsetExample.tsx
@@ -0,0 +1,129 @@
+import { createSelector } from "@reduxjs/toolkit"
+import {
+ BaseQueryFn,
+ TypedUseQueryStateResult,
+} from "@reduxjs/toolkit/query/react"
+import { Link, useLocation } from "react-router"
+import { useIntersectionCallback } from "../../app/useIntersectionCallback"
+import { apiWithInfiniteScroll, ProjectsResponse } from "./infiniteScrollApi"
+
+type ProjectsInfiniteQueryResult = TypedUseQueryStateResult<
+ { pages: ProjectsResponse[] },
+ unknown,
+ BaseQueryFn
+>
+
+const selectCombinedProjects = createSelector(
+ (res: ProjectsInfiniteQueryResult) => {
+ return res.data
+ },
+ data => data?.pages?.map(item => item?.projects)?.flat(),
+)
+
+function LimitOffsetExample() {
+ const {
+ combinedData,
+ hasPreviousPage,
+ hasNextPage,
+ // data,
+ error,
+ isFetching,
+ isLoading,
+ isError,
+ fetchNextPage,
+ fetchPreviousPage,
+ isFetchingNextPage,
+ isFetchingPreviousPage,
+ } = apiWithInfiniteScroll.endpoints.projectsLimitOffset.useInfiniteQuery(
+ undefined,
+ {
+ selectFromResult: result => {
+ return {
+ ...result,
+ combinedData: selectCombinedProjects(result),
+ }
+ },
+ },
+ )
+
+ const intersectionCallbackRef = useIntersectionCallback(fetchNextPage)
+ const location = useLocation()
+
+ return (
+
+
Limit and Offset Infinite Scroll
+ {isLoading ? (
+
Loading...
+ ) : isError ? (
+
Error: {error.message}
+ ) : null}
+
+ <>
+
+
+
+
+ {combinedData?.map((project, index, arr) => {
+ return (
+
+
+
{`Project ${project.id} (created at: ${project.createdAt})`}
+
+
+ )
+ })}
+
+
+
+
+
+
+
+ {isFetching && !isFetchingPreviousPage && !isFetchingNextPage
+ ? "Background Updating..."
+ : null}
+
+ >
+
+
+
+ Go to another page
+
+
+ )
+}
+
+export default LimitOffsetExample
diff --git a/examples/query/react/infinite-queries/src/features/limit-offset/infiniteScrollApi.ts b/examples/query/react/infinite-queries/src/features/limit-offset/infiniteScrollApi.ts
new file mode 100644
index 0000000000..27bd2998a7
--- /dev/null
+++ b/examples/query/react/infinite-queries/src/features/limit-offset/infiniteScrollApi.ts
@@ -0,0 +1,72 @@
+import { baseApi } from "../baseApi"
+
+type Project = {
+ id: number
+ createdAt: string
+}
+
+export type ProjectsResponse = {
+ projects: Project[]
+ numFound: number
+ serverTime: string
+}
+
+interface ProjectsInitialPageParam {
+ offset: number
+ limit: number
+}
+
+export const apiWithInfiniteScroll = baseApi.injectEndpoints({
+ endpoints: builder => ({
+ projectsLimitOffset: builder.infiniteQuery<
+ ProjectsResponse,
+ void,
+ ProjectsInitialPageParam
+ >({
+ infiniteQueryOptions: {
+ initialPageParam: {
+ offset: 0,
+ limit: 20,
+ },
+ getNextPageParam: (
+ lastPage,
+ allPages,
+ lastPageParam,
+ allPageParams,
+ ) => {
+ const nextOffset = lastPageParam.offset + lastPageParam.limit
+ const remainingItems = lastPage?.numFound - nextOffset
+
+ if (remainingItems <= 0) {
+ return undefined
+ }
+
+ return {
+ ...lastPageParam,
+ offset: nextOffset,
+ }
+ },
+ getPreviousPageParam: (
+ firstPage,
+ allPages,
+ firstPageParam,
+ allPageParams,
+ ) => {
+ const prevOffset = firstPageParam.offset - firstPageParam.limit
+ if (prevOffset < 0) return undefined
+
+ return {
+ ...firstPageParam,
+ offset: firstPageParam.offset - firstPageParam.limit,
+ }
+ },
+ },
+ query: ({ offset, limit }) => {
+ return {
+ url: `https://example.com/api/projectsLimitOffset?offset=${offset}&limit=${limit}`,
+ method: "GET",
+ }
+ },
+ }),
+ }),
+})
diff --git a/examples/query/react/infinite-queries/src/features/pagination-infinite-scroll/PaginationInfScrollExample.tsx b/examples/query/react/infinite-queries/src/features/pagination-infinite-scroll/PaginationInfScrollExample.tsx
new file mode 100644
index 0000000000..c461b0a09c
--- /dev/null
+++ b/examples/query/react/infinite-queries/src/features/pagination-infinite-scroll/PaginationInfScrollExample.tsx
@@ -0,0 +1,129 @@
+import { createSelector } from "@reduxjs/toolkit"
+import {
+ BaseQueryFn,
+ TypedUseQueryStateResult,
+} from "@reduxjs/toolkit/query/react"
+import { Link, useLocation } from "react-router"
+import { useIntersectionCallback } from "../../app/useIntersectionCallback"
+import { apiWithInfiniteScroll, ProjectsResponse } from "./infiniteScrollApi"
+
+type ProjectsInfiniteQueryResult = TypedUseQueryStateResult<
+ { pages: ProjectsResponse[] },
+ unknown,
+ BaseQueryFn
+>
+
+const selectCombinedProjects = createSelector(
+ (res: ProjectsInfiniteQueryResult) => {
+ return res.data
+ },
+ data => data?.pages?.map(item => item?.projects)?.flat(),
+)
+
+function PaginationInfScrollExample() {
+ const {
+ combinedData,
+ hasPreviousPage,
+ hasNextPage,
+ // data,
+ error,
+ isFetching,
+ isLoading,
+ isError,
+ fetchNextPage,
+ fetchPreviousPage,
+ isFetchingNextPage,
+ isFetchingPreviousPage,
+ } = apiWithInfiniteScroll.endpoints.projectsPaginated.useInfiniteQuery(
+ undefined,
+ {
+ selectFromResult: result => {
+ return {
+ ...result,
+ combinedData: selectCombinedProjects(result),
+ }
+ },
+ },
+ )
+
+ const intersectionCallbackRef = useIntersectionCallback(fetchNextPage)
+ const location = useLocation()
+
+ return (
+
+
Pagination Infinite Scroll
+ {isLoading ? (
+
Loading...
+ ) : isError ? (
+
Error: {error.message}
+ ) : null}
+
+ <>
+
+
+
+
+ {combinedData?.map((project, index, arr) => {
+ return (
+
+
+
{`Project ${project.id} (created at: ${project.createdAt})`}
+
+
+ )
+ })}
+
+
+
+
+
+
+
+ {isFetching && !isFetchingPreviousPage && !isFetchingNextPage
+ ? "Background Updating..."
+ : null}
+
+ >
+
+
+
+ Go to another page
+
+
+ )
+}
+
+export default PaginationInfScrollExample
diff --git a/examples/query/react/infinite-queries/src/features/pagination-infinite-scroll/infiniteScrollApi.ts b/examples/query/react/infinite-queries/src/features/pagination-infinite-scroll/infiniteScrollApi.ts
new file mode 100644
index 0000000000..c519dce5bb
--- /dev/null
+++ b/examples/query/react/infinite-queries/src/features/pagination-infinite-scroll/infiniteScrollApi.ts
@@ -0,0 +1,72 @@
+import { baseApi } from "../baseApi"
+
+type Project = {
+ id: number
+ createdAt: string
+}
+
+export type ProjectsResponse = {
+ projects: Project[]
+ serverTime: string
+ totalPages: number
+}
+
+interface ProjectsInitialPageParam {
+ page: number
+ size: number
+}
+
+export const apiWithInfiniteScroll = baseApi.injectEndpoints({
+ endpoints: builder => ({
+ projectsPaginated: builder.infiniteQuery<
+ ProjectsResponse,
+ void,
+ ProjectsInitialPageParam
+ >({
+ infiniteQueryOptions: {
+ initialPageParam: {
+ page: 0,
+ size: 20,
+ },
+ getNextPageParam: (
+ lastPage,
+ allPages,
+ lastPageParam,
+ allPageParams,
+ ) => {
+ const nextPage = lastPageParam.page + 1
+ const remainingPages = lastPage?.totalPages - nextPage
+
+ if (remainingPages <= 0) {
+ return undefined
+ }
+
+ return {
+ ...lastPageParam,
+ page: nextPage,
+ }
+ },
+ getPreviousPageParam: (
+ firstPage,
+ allPages,
+ firstPageParam,
+ allPageParams,
+ ) => {
+ const prevPage = firstPageParam.page - 1
+ if (prevPage < 0) return undefined
+
+ return {
+ ...firstPageParam,
+ page: prevPage,
+ }
+ },
+ },
+ query: ({ page, size }) => {
+ return {
+ url: `https://example.com/api/projectsPaginated?page=${page}&size=${size}`,
+ method: "GET",
+ }
+ },
+ }),
+ }),
+})
diff --git a/examples/query/react/infinite-queries/src/mocks/handlers.ts b/examples/query/react/infinite-queries/src/mocks/handlers.ts
index 75edcac3a6..f6d747268b 100644
--- a/examples/query/react/infinite-queries/src/mocks/handlers.ts
+++ b/examples/query/react/infinite-queries/src/mocks/handlers.ts
@@ -4,6 +4,13 @@ function delay(ms: number) {
return new Promise(resolve => setTimeout(resolve, ms))
}
+const projects = Array.from({ length: 50 }, (_, i) => {
+ return {
+ id: i,
+ createdAt: Date.now() + i * 1000,
+ }
+})
+
export const handlers = [
http.get("https://example.com/api/projects", async ({ request, params }) => {
const url = new URL(request.url)
@@ -69,4 +76,139 @@ export const handlers = [
})
},
),
+ http.get(
+ "https://example.com/api/projectsBidirectionalCursor",
+ async ({ request }) => {
+ const url = new URL(request.url)
+ const limit = parseInt(url.searchParams.get("limit") ?? "5", 10)
+ const aroundCursor = parseInt(url.searchParams.get("around") ?? "", 10)
+ const afterCursor = parseInt(url.searchParams.get("after") ?? "", 10)
+ const beforeCursor = parseInt(url.searchParams.get("before") ?? "", 10)
+
+ const validateCursor = (cursor: number, cursorType: string): number => {
+ const cursorIndex = projects.findIndex(project => project.id === cursor)
+ if (cursorIndex === -1) {
+ throw new Error(`Invalid \`${cursorType}\` cursor.`)
+ }
+ return cursorIndex
+ }
+
+ let resultProjects = []
+ try {
+ if (!isNaN(afterCursor)) {
+ const afterCursorIndex = validateCursor(afterCursor, "after")
+ const afterIndex = afterCursorIndex + 1
+ resultProjects = projects.slice(afterIndex, afterIndex + limit)
+ } else if (!isNaN(beforeCursor)) {
+ const beforeCursorIndex = validateCursor(beforeCursor, "before")
+ const startIndex = Math.max(0, beforeCursorIndex - limit)
+ resultProjects = projects.slice(startIndex, beforeCursorIndex)
+ } else if (!isNaN(aroundCursor)) {
+ const aroundCursorIndex = validateCursor(aroundCursor, "around")
+ const ceiledLimit = Math.ceil(limit / 2)
+
+ const beforeIndex = Math.max(0, aroundCursorIndex - ceiledLimit)
+ const afterIndex = Math.min(
+ projects.length - 1,
+ aroundCursorIndex + ceiledLimit,
+ )
+ const beforeProjects = projects.slice(beforeIndex, aroundCursorIndex)
+ const afterProjects = projects.slice(
+ aroundCursorIndex + 1,
+ afterIndex + 1,
+ )
+
+ resultProjects = [
+ ...beforeProjects,
+ projects[aroundCursorIndex],
+ ...afterProjects,
+ ]
+ } else {
+ resultProjects = projects.slice(0, limit)
+ }
+
+ const startCursor = resultProjects[0]?.id
+ const endCursor = resultProjects[resultProjects.length - 1]?.id
+
+ const hasNextPage = endCursor != null && endCursor < projects.length - 1
+ const hasPreviousPage = startCursor !== 0
+
+ await delay(1000)
+ return HttpResponse.json({
+ projects: resultProjects,
+ serverTime: Date.now(),
+ pageInfo: {
+ startCursor,
+ endCursor,
+ hasNextPage,
+ hasPreviousPage,
+ },
+ })
+ } catch (error) {
+ if (error instanceof Error) {
+ return HttpResponse.json({ message: error.message }, { status: 400 })
+ }
+ }
+ },
+ ),
+ http.get(
+ "https://example.com/api/projectsLimitOffset",
+ async ({ request }) => {
+ const url = new URL(request.url)
+ const limit = parseInt(url.searchParams.get("limit") ?? "5", 10)
+ let offset = parseInt(url.searchParams.get("offset") ?? "0", 10)
+
+ if (isNaN(offset) || offset < 0) {
+ offset = 0
+ }
+ if (isNaN(limit) || limit <= 0) {
+ return HttpResponse.json(
+ {
+ message:
+ "Invalid 'limit' parameter. It must be a positive integer.",
+ },
+ { status: 400 },
+ )
+ }
+
+ const result = projects.slice(offset, offset + limit)
+
+ await delay(1000)
+ return HttpResponse.json({
+ projects: result,
+ serverTime: Date.now(),
+ numFound: projects.length,
+ })
+ },
+ ),
+ http.get("https://example.com/api/projectsPaginated", async ({ request }) => {
+ const url = new URL(request.url)
+ const size = parseInt(url.searchParams.get("size") ?? "5", 10)
+ let page = parseInt(url.searchParams.get("page") ?? "0", 10)
+
+ if (isNaN(page) || page < 0) {
+ page = 0
+ }
+ if (isNaN(size) || size <= 0) {
+ return HttpResponse.json(
+ { message: "Invalid 'size' parameter. It must be a positive integer." },
+ { status: 400 },
+ )
+ }
+
+ const startIndex = page * size
+ const endIndex = startIndex + size
+ const result = projects.slice(startIndex, endIndex)
+
+ await delay(1000)
+ return HttpResponse.json({
+ projects: result,
+ serverTime: Date.now(),
+ totalPages: Math.ceil(projects.length / size), // totalPages is a parameter required for this example, but an API could include additional fields that can be used in certain scenarios, such as determining getNextPageParam or getPreviousPageParam.
+ // totalElements: projects.length,
+ // numberOfElements: result.length,
+ // isLast: endIndex >= projects.length,
+ // isFirst: page === 0,
+ })
+ }),
]
diff --git a/yarn.lock b/yarn.lock
index 61f07ffb9f..7154042430 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -7739,23 +7739,23 @@ __metadata:
languageName: unknown
linkType: soft
-"@reduxjs/toolkit@https://pkg.csb.dev/reduxjs/redux-toolkit/commit/aa419c22/@reduxjs/toolkit/_pkg.tgz":
- version: 2.4.0
- resolution: "@reduxjs/toolkit@https://pkg.csb.dev/reduxjs/redux-toolkit/commit/aa419c22/@reduxjs/toolkit/_pkg.tgz"
+"@reduxjs/toolkit@https://pkg.csb.dev/reduxjs/redux-toolkit/commit/c9cc8ca0/@reduxjs/toolkit/_pkg.tgz":
+ version: 2.5.0
+ resolution: "@reduxjs/toolkit@https://pkg.csb.dev/reduxjs/redux-toolkit/commit/c9cc8ca0/@reduxjs/toolkit/_pkg.tgz"
dependencies:
immer: "npm:^10.0.3"
redux: "npm:^5.0.1"
redux-thunk: "npm:^3.1.0"
reselect: "npm:^5.1.0"
peerDependencies:
- react: ^16.9.0 || ^17.0.0 || ^18
+ react: ^16.9.0 || ^17.0.0 || ^18 || ^19
react-redux: ^7.2.1 || ^8.1.3 || ^9.0.0
peerDependenciesMeta:
react:
optional: true
react-redux:
optional: true
- checksum: 10/83dd571381b1e16bb75731c7dedc51e90934039d5b73ac6d4115d8e2408bbf8ca679d2030aaa59b0aa67cd85e5747a967b2005604ce670134189c0e74abb98df
+ checksum: 10/89bff8594de9815bdfc909e2e3942cb3983b8f32b3335b49ab042288609c990d26ba9b3ca1f65439d8d409bb642b938354079517d0c26db976155430cd7df659
languageName: node
linkType: hard
@@ -32439,7 +32439,7 @@ __metadata:
version: 0.0.0-use.local
resolution: "vite-template-redux@workspace:examples/query/react/infinite-queries"
dependencies:
- "@reduxjs/toolkit": "https://pkg.csb.dev/reduxjs/redux-toolkit/commit/aa419c22/@reduxjs/toolkit/_pkg.tgz"
+ "@reduxjs/toolkit": "https://pkg.csb.dev/reduxjs/redux-toolkit/commit/c9cc8ca0/@reduxjs/toolkit/_pkg.tgz"
"@testing-library/dom": "npm:^9.3.4"
"@testing-library/jest-dom": "npm:^6.2.0"
"@testing-library/react": "npm:^14.1.2"