@tanstack/query-core 5.56.0 → 5.56.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/legacy/infiniteQueryBehavior.cjs +14 -17
- package/build/legacy/infiniteQueryBehavior.cjs.map +1 -1
- package/build/legacy/infiniteQueryBehavior.js +14 -17
- package/build/legacy/infiniteQueryBehavior.js.map +1 -1
- package/build/modern/infiniteQueryBehavior.cjs +10 -13
- package/build/modern/infiniteQueryBehavior.cjs.map +1 -1
- package/build/modern/infiniteQueryBehavior.js +10 -13
- package/build/modern/infiniteQueryBehavior.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/infiniteQueryBehavior.test.tsx +74 -1
- package/src/infiniteQueryBehavior.ts +15 -18
|
@@ -29,13 +29,14 @@ var import_utils = require("./utils.cjs");
|
|
|
29
29
|
function infiniteQueryBehavior(pages) {
|
|
30
30
|
return {
|
|
31
31
|
onFetch: (context, query) => {
|
|
32
|
+
var _a, _b, _c, _d, _e;
|
|
33
|
+
const options = context.options;
|
|
34
|
+
const direction = (_c = (_b = (_a = context.fetchOptions) == null ? void 0 : _a.meta) == null ? void 0 : _b.fetchMore) == null ? void 0 : _c.direction;
|
|
35
|
+
const oldPages = ((_d = context.state.data) == null ? void 0 : _d.pages) || [];
|
|
36
|
+
const oldPageParams = ((_e = context.state.data) == null ? void 0 : _e.pageParams) || [];
|
|
37
|
+
let result = { pages: [], pageParams: [] };
|
|
38
|
+
let currentPage = 0;
|
|
32
39
|
const fetchFn = async () => {
|
|
33
|
-
var _a, _b, _c, _d, _e;
|
|
34
|
-
const options = context.options;
|
|
35
|
-
const direction = (_c = (_b = (_a = context.fetchOptions) == null ? void 0 : _a.meta) == null ? void 0 : _b.fetchMore) == null ? void 0 : _c.direction;
|
|
36
|
-
const oldPages = ((_d = context.state.data) == null ? void 0 : _d.pages) || [];
|
|
37
|
-
const oldPageParams = ((_e = context.state.data) == null ? void 0 : _e.pageParams) || [];
|
|
38
|
-
const empty = { pages: [], pageParams: [] };
|
|
39
40
|
let cancelled = false;
|
|
40
41
|
const addSignalProperty = (object) => {
|
|
41
42
|
Object.defineProperty(object, "signal", {
|
|
@@ -77,7 +78,6 @@ function infiniteQueryBehavior(pages) {
|
|
|
77
78
|
pageParams: addTo(data.pageParams, param, maxPages)
|
|
78
79
|
};
|
|
79
80
|
};
|
|
80
|
-
let result;
|
|
81
81
|
if (direction && oldPages.length) {
|
|
82
82
|
const previous = direction === "backward";
|
|
83
83
|
const pageParamFn = previous ? getPreviousPageParam : getNextPageParam;
|
|
@@ -88,26 +88,23 @@ function infiniteQueryBehavior(pages) {
|
|
|
88
88
|
const param = pageParamFn(options, oldData);
|
|
89
89
|
result = await fetchPage(oldData, param, previous);
|
|
90
90
|
} else {
|
|
91
|
-
result = await fetchPage(
|
|
92
|
-
empty,
|
|
93
|
-
oldPageParams[0] ?? options.initialPageParam
|
|
94
|
-
);
|
|
95
91
|
const remainingPages = pages ?? oldPages.length;
|
|
96
|
-
|
|
97
|
-
const param = getNextPageParam(options, result);
|
|
92
|
+
do {
|
|
93
|
+
const param = currentPage === 0 ? oldPageParams[0] ?? options.initialPageParam : getNextPageParam(options, result);
|
|
98
94
|
if (param == null) {
|
|
99
95
|
break;
|
|
100
96
|
}
|
|
101
97
|
result = await fetchPage(result, param);
|
|
102
|
-
|
|
98
|
+
currentPage++;
|
|
99
|
+
} while (currentPage < remainingPages);
|
|
103
100
|
}
|
|
104
101
|
return result;
|
|
105
102
|
};
|
|
106
103
|
if (context.options.persister) {
|
|
107
104
|
context.fetchFn = () => {
|
|
108
|
-
var
|
|
109
|
-
return (
|
|
110
|
-
|
|
105
|
+
var _a2, _b2;
|
|
106
|
+
return (_b2 = (_a2 = context.options).persister) == null ? void 0 : _b2.call(
|
|
107
|
+
_a2,
|
|
111
108
|
fetchFn,
|
|
112
109
|
{
|
|
113
110
|
queryKey: context.queryKey,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/infiniteQueryBehavior.ts"],"sourcesContent":["import { addToEnd, addToStart, ensureQueryFn } from './utils'\nimport type { QueryBehavior } from './query'\nimport type {\n InfiniteData,\n InfiniteQueryPageParamsOptions,\n OmitKeyof,\n QueryFunctionContext,\n QueryKey,\n} from './types'\n\nexport function infiniteQueryBehavior<TQueryFnData, TError, TData, TPageParam>(\n pages?: number,\n): QueryBehavior<TQueryFnData, TError, InfiniteData<TData, TPageParam>> {\n return {\n onFetch: (context, query) => {\n const
|
|
1
|
+
{"version":3,"sources":["../../src/infiniteQueryBehavior.ts"],"sourcesContent":["import { addToEnd, addToStart, ensureQueryFn } from './utils'\nimport type { QueryBehavior } from './query'\nimport type {\n InfiniteData,\n InfiniteQueryPageParamsOptions,\n OmitKeyof,\n QueryFunctionContext,\n QueryKey,\n} from './types'\n\nexport function infiniteQueryBehavior<TQueryFnData, TError, TData, TPageParam>(\n pages?: number,\n): QueryBehavior<TQueryFnData, TError, InfiniteData<TData, TPageParam>> {\n return {\n onFetch: (context, query) => {\n const options = context.options as InfiniteQueryPageParamsOptions<TData>\n const direction = context.fetchOptions?.meta?.fetchMore?.direction\n const oldPages = context.state.data?.pages || []\n const oldPageParams = context.state.data?.pageParams || []\n let result: InfiniteData<unknown> = { pages: [], pageParams: [] }\n let currentPage = 0\n\n const fetchFn = async () => {\n let cancelled = false\n const addSignalProperty = (object: unknown) => {\n Object.defineProperty(object, 'signal', {\n enumerable: true,\n get: () => {\n if (context.signal.aborted) {\n cancelled = true\n } else {\n context.signal.addEventListener('abort', () => {\n cancelled = true\n })\n }\n return context.signal\n },\n })\n }\n\n const queryFn = ensureQueryFn(context.options, context.fetchOptions)\n\n // Create function to fetch a page\n const fetchPage = async (\n data: InfiniteData<unknown>,\n param: unknown,\n previous?: boolean,\n ): Promise<InfiniteData<unknown>> => {\n if (cancelled) {\n return Promise.reject()\n }\n\n if (param == null && data.pages.length) {\n return Promise.resolve(data)\n }\n\n const queryFnContext: OmitKeyof<\n QueryFunctionContext<QueryKey, unknown>,\n 'signal'\n > = {\n queryKey: context.queryKey,\n pageParam: param,\n direction: previous ? 'backward' : 'forward',\n meta: context.options.meta,\n }\n\n addSignalProperty(queryFnContext)\n\n const page = await queryFn(\n queryFnContext as QueryFunctionContext<QueryKey, unknown>,\n )\n\n const { maxPages } = context.options\n const addTo = previous ? addToStart : addToEnd\n\n return {\n pages: addTo(data.pages, page, maxPages),\n pageParams: addTo(data.pageParams, param, maxPages),\n }\n }\n\n // fetch next / previous page?\n if (direction && oldPages.length) {\n const previous = direction === 'backward'\n const pageParamFn = previous ? getPreviousPageParam : getNextPageParam\n const oldData = {\n pages: oldPages,\n pageParams: oldPageParams,\n }\n const param = pageParamFn(options, oldData)\n\n result = await fetchPage(oldData, param, previous)\n } else {\n const remainingPages = pages ?? oldPages.length\n\n // Fetch all pages\n do {\n const param =\n currentPage === 0\n ? (oldPageParams[0] ?? options.initialPageParam)\n : getNextPageParam(options, result)\n if (param == null) {\n break\n }\n result = await fetchPage(result, param)\n currentPage++\n } while (currentPage < remainingPages)\n }\n\n return result\n }\n if (context.options.persister) {\n context.fetchFn = () => {\n return context.options.persister?.(\n fetchFn as any,\n {\n queryKey: context.queryKey,\n meta: context.options.meta,\n signal: context.signal,\n },\n query,\n )\n }\n } else {\n context.fetchFn = fetchFn\n }\n },\n }\n}\n\nfunction getNextPageParam(\n options: InfiniteQueryPageParamsOptions<any>,\n { pages, pageParams }: InfiniteData<unknown>,\n): unknown | undefined {\n const lastIndex = pages.length - 1\n return pages.length > 0\n ? options.getNextPageParam(\n pages[lastIndex],\n pages,\n pageParams[lastIndex],\n pageParams,\n )\n : undefined\n}\n\nfunction getPreviousPageParam(\n options: InfiniteQueryPageParamsOptions<any>,\n { pages, pageParams }: InfiniteData<unknown>,\n): unknown | undefined {\n return pages.length > 0\n ? options.getPreviousPageParam?.(pages[0], pages, pageParams[0], pageParams)\n : undefined\n}\n\n/**\n * Checks if there is a next page.\n */\nexport function hasNextPage(\n options: InfiniteQueryPageParamsOptions<any, any>,\n data?: InfiniteData<unknown>,\n): boolean {\n if (!data) return false\n return getNextPageParam(options, data) != null\n}\n\n/**\n * Checks if there is a previous page.\n */\nexport function hasPreviousPage(\n options: InfiniteQueryPageParamsOptions<any, any>,\n data?: InfiniteData<unknown>,\n): boolean {\n if (!data || !options.getPreviousPageParam) return false\n return getPreviousPageParam(options, data) != null\n}\n"],"mappings":"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","names":["_a","_b"]}
|
|
@@ -5,13 +5,14 @@ import { addToEnd, addToStart, ensureQueryFn } from "./utils.js";
|
|
|
5
5
|
function infiniteQueryBehavior(pages) {
|
|
6
6
|
return {
|
|
7
7
|
onFetch: (context, query) => {
|
|
8
|
+
var _a, _b, _c, _d, _e;
|
|
9
|
+
const options = context.options;
|
|
10
|
+
const direction = (_c = (_b = (_a = context.fetchOptions) == null ? void 0 : _a.meta) == null ? void 0 : _b.fetchMore) == null ? void 0 : _c.direction;
|
|
11
|
+
const oldPages = ((_d = context.state.data) == null ? void 0 : _d.pages) || [];
|
|
12
|
+
const oldPageParams = ((_e = context.state.data) == null ? void 0 : _e.pageParams) || [];
|
|
13
|
+
let result = { pages: [], pageParams: [] };
|
|
14
|
+
let currentPage = 0;
|
|
8
15
|
const fetchFn = async () => {
|
|
9
|
-
var _a, _b, _c, _d, _e;
|
|
10
|
-
const options = context.options;
|
|
11
|
-
const direction = (_c = (_b = (_a = context.fetchOptions) == null ? void 0 : _a.meta) == null ? void 0 : _b.fetchMore) == null ? void 0 : _c.direction;
|
|
12
|
-
const oldPages = ((_d = context.state.data) == null ? void 0 : _d.pages) || [];
|
|
13
|
-
const oldPageParams = ((_e = context.state.data) == null ? void 0 : _e.pageParams) || [];
|
|
14
|
-
const empty = { pages: [], pageParams: [] };
|
|
15
16
|
let cancelled = false;
|
|
16
17
|
const addSignalProperty = (object) => {
|
|
17
18
|
Object.defineProperty(object, "signal", {
|
|
@@ -53,7 +54,6 @@ function infiniteQueryBehavior(pages) {
|
|
|
53
54
|
pageParams: addTo(data.pageParams, param, maxPages)
|
|
54
55
|
};
|
|
55
56
|
};
|
|
56
|
-
let result;
|
|
57
57
|
if (direction && oldPages.length) {
|
|
58
58
|
const previous = direction === "backward";
|
|
59
59
|
const pageParamFn = previous ? getPreviousPageParam : getNextPageParam;
|
|
@@ -64,26 +64,23 @@ function infiniteQueryBehavior(pages) {
|
|
|
64
64
|
const param = pageParamFn(options, oldData);
|
|
65
65
|
result = await fetchPage(oldData, param, previous);
|
|
66
66
|
} else {
|
|
67
|
-
result = await fetchPage(
|
|
68
|
-
empty,
|
|
69
|
-
oldPageParams[0] ?? options.initialPageParam
|
|
70
|
-
);
|
|
71
67
|
const remainingPages = pages ?? oldPages.length;
|
|
72
|
-
|
|
73
|
-
const param = getNextPageParam(options, result);
|
|
68
|
+
do {
|
|
69
|
+
const param = currentPage === 0 ? oldPageParams[0] ?? options.initialPageParam : getNextPageParam(options, result);
|
|
74
70
|
if (param == null) {
|
|
75
71
|
break;
|
|
76
72
|
}
|
|
77
73
|
result = await fetchPage(result, param);
|
|
78
|
-
|
|
74
|
+
currentPage++;
|
|
75
|
+
} while (currentPage < remainingPages);
|
|
79
76
|
}
|
|
80
77
|
return result;
|
|
81
78
|
};
|
|
82
79
|
if (context.options.persister) {
|
|
83
80
|
context.fetchFn = () => {
|
|
84
|
-
var
|
|
85
|
-
return (
|
|
86
|
-
|
|
81
|
+
var _a2, _b2;
|
|
82
|
+
return (_b2 = (_a2 = context.options).persister) == null ? void 0 : _b2.call(
|
|
83
|
+
_a2,
|
|
87
84
|
fetchFn,
|
|
88
85
|
{
|
|
89
86
|
queryKey: context.queryKey,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/infiniteQueryBehavior.ts"],"sourcesContent":["import { addToEnd, addToStart, ensureQueryFn } from './utils'\nimport type { QueryBehavior } from './query'\nimport type {\n InfiniteData,\n InfiniteQueryPageParamsOptions,\n OmitKeyof,\n QueryFunctionContext,\n QueryKey,\n} from './types'\n\nexport function infiniteQueryBehavior<TQueryFnData, TError, TData, TPageParam>(\n pages?: number,\n): QueryBehavior<TQueryFnData, TError, InfiniteData<TData, TPageParam>> {\n return {\n onFetch: (context, query) => {\n const
|
|
1
|
+
{"version":3,"sources":["../../src/infiniteQueryBehavior.ts"],"sourcesContent":["import { addToEnd, addToStart, ensureQueryFn } from './utils'\nimport type { QueryBehavior } from './query'\nimport type {\n InfiniteData,\n InfiniteQueryPageParamsOptions,\n OmitKeyof,\n QueryFunctionContext,\n QueryKey,\n} from './types'\n\nexport function infiniteQueryBehavior<TQueryFnData, TError, TData, TPageParam>(\n pages?: number,\n): QueryBehavior<TQueryFnData, TError, InfiniteData<TData, TPageParam>> {\n return {\n onFetch: (context, query) => {\n const options = context.options as InfiniteQueryPageParamsOptions<TData>\n const direction = context.fetchOptions?.meta?.fetchMore?.direction\n const oldPages = context.state.data?.pages || []\n const oldPageParams = context.state.data?.pageParams || []\n let result: InfiniteData<unknown> = { pages: [], pageParams: [] }\n let currentPage = 0\n\n const fetchFn = async () => {\n let cancelled = false\n const addSignalProperty = (object: unknown) => {\n Object.defineProperty(object, 'signal', {\n enumerable: true,\n get: () => {\n if (context.signal.aborted) {\n cancelled = true\n } else {\n context.signal.addEventListener('abort', () => {\n cancelled = true\n })\n }\n return context.signal\n },\n })\n }\n\n const queryFn = ensureQueryFn(context.options, context.fetchOptions)\n\n // Create function to fetch a page\n const fetchPage = async (\n data: InfiniteData<unknown>,\n param: unknown,\n previous?: boolean,\n ): Promise<InfiniteData<unknown>> => {\n if (cancelled) {\n return Promise.reject()\n }\n\n if (param == null && data.pages.length) {\n return Promise.resolve(data)\n }\n\n const queryFnContext: OmitKeyof<\n QueryFunctionContext<QueryKey, unknown>,\n 'signal'\n > = {\n queryKey: context.queryKey,\n pageParam: param,\n direction: previous ? 'backward' : 'forward',\n meta: context.options.meta,\n }\n\n addSignalProperty(queryFnContext)\n\n const page = await queryFn(\n queryFnContext as QueryFunctionContext<QueryKey, unknown>,\n )\n\n const { maxPages } = context.options\n const addTo = previous ? addToStart : addToEnd\n\n return {\n pages: addTo(data.pages, page, maxPages),\n pageParams: addTo(data.pageParams, param, maxPages),\n }\n }\n\n // fetch next / previous page?\n if (direction && oldPages.length) {\n const previous = direction === 'backward'\n const pageParamFn = previous ? getPreviousPageParam : getNextPageParam\n const oldData = {\n pages: oldPages,\n pageParams: oldPageParams,\n }\n const param = pageParamFn(options, oldData)\n\n result = await fetchPage(oldData, param, previous)\n } else {\n const remainingPages = pages ?? oldPages.length\n\n // Fetch all pages\n do {\n const param =\n currentPage === 0\n ? (oldPageParams[0] ?? options.initialPageParam)\n : getNextPageParam(options, result)\n if (param == null) {\n break\n }\n result = await fetchPage(result, param)\n currentPage++\n } while (currentPage < remainingPages)\n }\n\n return result\n }\n if (context.options.persister) {\n context.fetchFn = () => {\n return context.options.persister?.(\n fetchFn as any,\n {\n queryKey: context.queryKey,\n meta: context.options.meta,\n signal: context.signal,\n },\n query,\n )\n }\n } else {\n context.fetchFn = fetchFn\n }\n },\n }\n}\n\nfunction getNextPageParam(\n options: InfiniteQueryPageParamsOptions<any>,\n { pages, pageParams }: InfiniteData<unknown>,\n): unknown | undefined {\n const lastIndex = pages.length - 1\n return pages.length > 0\n ? options.getNextPageParam(\n pages[lastIndex],\n pages,\n pageParams[lastIndex],\n pageParams,\n )\n : undefined\n}\n\nfunction getPreviousPageParam(\n options: InfiniteQueryPageParamsOptions<any>,\n { pages, pageParams }: InfiniteData<unknown>,\n): unknown | undefined {\n return pages.length > 0\n ? options.getPreviousPageParam?.(pages[0], pages, pageParams[0], pageParams)\n : undefined\n}\n\n/**\n * Checks if there is a next page.\n */\nexport function hasNextPage(\n options: InfiniteQueryPageParamsOptions<any, any>,\n data?: InfiniteData<unknown>,\n): boolean {\n if (!data) return false\n return getNextPageParam(options, data) != null\n}\n\n/**\n * Checks if there is a previous page.\n */\nexport function hasPreviousPage(\n options: InfiniteQueryPageParamsOptions<any, any>,\n data?: InfiniteData<unknown>,\n): boolean {\n if (!data || !options.getPreviousPageParam) return false\n return getPreviousPageParam(options, data) != null\n}\n"],"mappings":"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","names":["_a","_b"]}
|
|
@@ -29,12 +29,13 @@ var import_utils = require("./utils.cjs");
|
|
|
29
29
|
function infiniteQueryBehavior(pages) {
|
|
30
30
|
return {
|
|
31
31
|
onFetch: (context, query) => {
|
|
32
|
+
const options = context.options;
|
|
33
|
+
const direction = context.fetchOptions?.meta?.fetchMore?.direction;
|
|
34
|
+
const oldPages = context.state.data?.pages || [];
|
|
35
|
+
const oldPageParams = context.state.data?.pageParams || [];
|
|
36
|
+
let result = { pages: [], pageParams: [] };
|
|
37
|
+
let currentPage = 0;
|
|
32
38
|
const fetchFn = async () => {
|
|
33
|
-
const options = context.options;
|
|
34
|
-
const direction = context.fetchOptions?.meta?.fetchMore?.direction;
|
|
35
|
-
const oldPages = context.state.data?.pages || [];
|
|
36
|
-
const oldPageParams = context.state.data?.pageParams || [];
|
|
37
|
-
const empty = { pages: [], pageParams: [] };
|
|
38
39
|
let cancelled = false;
|
|
39
40
|
const addSignalProperty = (object) => {
|
|
40
41
|
Object.defineProperty(object, "signal", {
|
|
@@ -76,7 +77,6 @@ function infiniteQueryBehavior(pages) {
|
|
|
76
77
|
pageParams: addTo(data.pageParams, param, maxPages)
|
|
77
78
|
};
|
|
78
79
|
};
|
|
79
|
-
let result;
|
|
80
80
|
if (direction && oldPages.length) {
|
|
81
81
|
const previous = direction === "backward";
|
|
82
82
|
const pageParamFn = previous ? getPreviousPageParam : getNextPageParam;
|
|
@@ -87,18 +87,15 @@ function infiniteQueryBehavior(pages) {
|
|
|
87
87
|
const param = pageParamFn(options, oldData);
|
|
88
88
|
result = await fetchPage(oldData, param, previous);
|
|
89
89
|
} else {
|
|
90
|
-
result = await fetchPage(
|
|
91
|
-
empty,
|
|
92
|
-
oldPageParams[0] ?? options.initialPageParam
|
|
93
|
-
);
|
|
94
90
|
const remainingPages = pages ?? oldPages.length;
|
|
95
|
-
|
|
96
|
-
const param = getNextPageParam(options, result);
|
|
91
|
+
do {
|
|
92
|
+
const param = currentPage === 0 ? oldPageParams[0] ?? options.initialPageParam : getNextPageParam(options, result);
|
|
97
93
|
if (param == null) {
|
|
98
94
|
break;
|
|
99
95
|
}
|
|
100
96
|
result = await fetchPage(result, param);
|
|
101
|
-
|
|
97
|
+
currentPage++;
|
|
98
|
+
} while (currentPage < remainingPages);
|
|
102
99
|
}
|
|
103
100
|
return result;
|
|
104
101
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/infiniteQueryBehavior.ts"],"sourcesContent":["import { addToEnd, addToStart, ensureQueryFn } from './utils'\nimport type { QueryBehavior } from './query'\nimport type {\n InfiniteData,\n InfiniteQueryPageParamsOptions,\n OmitKeyof,\n QueryFunctionContext,\n QueryKey,\n} from './types'\n\nexport function infiniteQueryBehavior<TQueryFnData, TError, TData, TPageParam>(\n pages?: number,\n): QueryBehavior<TQueryFnData, TError, InfiniteData<TData, TPageParam>> {\n return {\n onFetch: (context, query) => {\n const
|
|
1
|
+
{"version":3,"sources":["../../src/infiniteQueryBehavior.ts"],"sourcesContent":["import { addToEnd, addToStart, ensureQueryFn } from './utils'\nimport type { QueryBehavior } from './query'\nimport type {\n InfiniteData,\n InfiniteQueryPageParamsOptions,\n OmitKeyof,\n QueryFunctionContext,\n QueryKey,\n} from './types'\n\nexport function infiniteQueryBehavior<TQueryFnData, TError, TData, TPageParam>(\n pages?: number,\n): QueryBehavior<TQueryFnData, TError, InfiniteData<TData, TPageParam>> {\n return {\n onFetch: (context, query) => {\n const options = context.options as InfiniteQueryPageParamsOptions<TData>\n const direction = context.fetchOptions?.meta?.fetchMore?.direction\n const oldPages = context.state.data?.pages || []\n const oldPageParams = context.state.data?.pageParams || []\n let result: InfiniteData<unknown> = { pages: [], pageParams: [] }\n let currentPage = 0\n\n const fetchFn = async () => {\n let cancelled = false\n const addSignalProperty = (object: unknown) => {\n Object.defineProperty(object, 'signal', {\n enumerable: true,\n get: () => {\n if (context.signal.aborted) {\n cancelled = true\n } else {\n context.signal.addEventListener('abort', () => {\n cancelled = true\n })\n }\n return context.signal\n },\n })\n }\n\n const queryFn = ensureQueryFn(context.options, context.fetchOptions)\n\n // Create function to fetch a page\n const fetchPage = async (\n data: InfiniteData<unknown>,\n param: unknown,\n previous?: boolean,\n ): Promise<InfiniteData<unknown>> => {\n if (cancelled) {\n return Promise.reject()\n }\n\n if (param == null && data.pages.length) {\n return Promise.resolve(data)\n }\n\n const queryFnContext: OmitKeyof<\n QueryFunctionContext<QueryKey, unknown>,\n 'signal'\n > = {\n queryKey: context.queryKey,\n pageParam: param,\n direction: previous ? 'backward' : 'forward',\n meta: context.options.meta,\n }\n\n addSignalProperty(queryFnContext)\n\n const page = await queryFn(\n queryFnContext as QueryFunctionContext<QueryKey, unknown>,\n )\n\n const { maxPages } = context.options\n const addTo = previous ? addToStart : addToEnd\n\n return {\n pages: addTo(data.pages, page, maxPages),\n pageParams: addTo(data.pageParams, param, maxPages),\n }\n }\n\n // fetch next / previous page?\n if (direction && oldPages.length) {\n const previous = direction === 'backward'\n const pageParamFn = previous ? getPreviousPageParam : getNextPageParam\n const oldData = {\n pages: oldPages,\n pageParams: oldPageParams,\n }\n const param = pageParamFn(options, oldData)\n\n result = await fetchPage(oldData, param, previous)\n } else {\n const remainingPages = pages ?? oldPages.length\n\n // Fetch all pages\n do {\n const param =\n currentPage === 0\n ? (oldPageParams[0] ?? options.initialPageParam)\n : getNextPageParam(options, result)\n if (param == null) {\n break\n }\n result = await fetchPage(result, param)\n currentPage++\n } while (currentPage < remainingPages)\n }\n\n return result\n }\n if (context.options.persister) {\n context.fetchFn = () => {\n return context.options.persister?.(\n fetchFn as any,\n {\n queryKey: context.queryKey,\n meta: context.options.meta,\n signal: context.signal,\n },\n query,\n )\n }\n } else {\n context.fetchFn = fetchFn\n }\n },\n }\n}\n\nfunction getNextPageParam(\n options: InfiniteQueryPageParamsOptions<any>,\n { pages, pageParams }: InfiniteData<unknown>,\n): unknown | undefined {\n const lastIndex = pages.length - 1\n return pages.length > 0\n ? options.getNextPageParam(\n pages[lastIndex],\n pages,\n pageParams[lastIndex],\n pageParams,\n )\n : undefined\n}\n\nfunction getPreviousPageParam(\n options: InfiniteQueryPageParamsOptions<any>,\n { pages, pageParams }: InfiniteData<unknown>,\n): unknown | undefined {\n return pages.length > 0\n ? options.getPreviousPageParam?.(pages[0], pages, pageParams[0], pageParams)\n : undefined\n}\n\n/**\n * Checks if there is a next page.\n */\nexport function hasNextPage(\n options: InfiniteQueryPageParamsOptions<any, any>,\n data?: InfiniteData<unknown>,\n): boolean {\n if (!data) return false\n return getNextPageParam(options, data) != null\n}\n\n/**\n * Checks if there is a previous page.\n */\nexport function hasPreviousPage(\n options: InfiniteQueryPageParamsOptions<any, any>,\n data?: InfiniteData<unknown>,\n): boolean {\n if (!data || !options.getPreviousPageParam) return false\n return getPreviousPageParam(options, data) != null\n}\n"],"mappings":"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","names":[]}
|
|
@@ -3,12 +3,13 @@ import { addToEnd, addToStart, ensureQueryFn } from "./utils.js";
|
|
|
3
3
|
function infiniteQueryBehavior(pages) {
|
|
4
4
|
return {
|
|
5
5
|
onFetch: (context, query) => {
|
|
6
|
+
const options = context.options;
|
|
7
|
+
const direction = context.fetchOptions?.meta?.fetchMore?.direction;
|
|
8
|
+
const oldPages = context.state.data?.pages || [];
|
|
9
|
+
const oldPageParams = context.state.data?.pageParams || [];
|
|
10
|
+
let result = { pages: [], pageParams: [] };
|
|
11
|
+
let currentPage = 0;
|
|
6
12
|
const fetchFn = async () => {
|
|
7
|
-
const options = context.options;
|
|
8
|
-
const direction = context.fetchOptions?.meta?.fetchMore?.direction;
|
|
9
|
-
const oldPages = context.state.data?.pages || [];
|
|
10
|
-
const oldPageParams = context.state.data?.pageParams || [];
|
|
11
|
-
const empty = { pages: [], pageParams: [] };
|
|
12
13
|
let cancelled = false;
|
|
13
14
|
const addSignalProperty = (object) => {
|
|
14
15
|
Object.defineProperty(object, "signal", {
|
|
@@ -50,7 +51,6 @@ function infiniteQueryBehavior(pages) {
|
|
|
50
51
|
pageParams: addTo(data.pageParams, param, maxPages)
|
|
51
52
|
};
|
|
52
53
|
};
|
|
53
|
-
let result;
|
|
54
54
|
if (direction && oldPages.length) {
|
|
55
55
|
const previous = direction === "backward";
|
|
56
56
|
const pageParamFn = previous ? getPreviousPageParam : getNextPageParam;
|
|
@@ -61,18 +61,15 @@ function infiniteQueryBehavior(pages) {
|
|
|
61
61
|
const param = pageParamFn(options, oldData);
|
|
62
62
|
result = await fetchPage(oldData, param, previous);
|
|
63
63
|
} else {
|
|
64
|
-
result = await fetchPage(
|
|
65
|
-
empty,
|
|
66
|
-
oldPageParams[0] ?? options.initialPageParam
|
|
67
|
-
);
|
|
68
64
|
const remainingPages = pages ?? oldPages.length;
|
|
69
|
-
|
|
70
|
-
const param = getNextPageParam(options, result);
|
|
65
|
+
do {
|
|
66
|
+
const param = currentPage === 0 ? oldPageParams[0] ?? options.initialPageParam : getNextPageParam(options, result);
|
|
71
67
|
if (param == null) {
|
|
72
68
|
break;
|
|
73
69
|
}
|
|
74
70
|
result = await fetchPage(result, param);
|
|
75
|
-
|
|
71
|
+
currentPage++;
|
|
72
|
+
} while (currentPage < remainingPages);
|
|
76
73
|
}
|
|
77
74
|
return result;
|
|
78
75
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/infiniteQueryBehavior.ts"],"sourcesContent":["import { addToEnd, addToStart, ensureQueryFn } from './utils'\nimport type { QueryBehavior } from './query'\nimport type {\n InfiniteData,\n InfiniteQueryPageParamsOptions,\n OmitKeyof,\n QueryFunctionContext,\n QueryKey,\n} from './types'\n\nexport function infiniteQueryBehavior<TQueryFnData, TError, TData, TPageParam>(\n pages?: number,\n): QueryBehavior<TQueryFnData, TError, InfiniteData<TData, TPageParam>> {\n return {\n onFetch: (context, query) => {\n const
|
|
1
|
+
{"version":3,"sources":["../../src/infiniteQueryBehavior.ts"],"sourcesContent":["import { addToEnd, addToStart, ensureQueryFn } from './utils'\nimport type { QueryBehavior } from './query'\nimport type {\n InfiniteData,\n InfiniteQueryPageParamsOptions,\n OmitKeyof,\n QueryFunctionContext,\n QueryKey,\n} from './types'\n\nexport function infiniteQueryBehavior<TQueryFnData, TError, TData, TPageParam>(\n pages?: number,\n): QueryBehavior<TQueryFnData, TError, InfiniteData<TData, TPageParam>> {\n return {\n onFetch: (context, query) => {\n const options = context.options as InfiniteQueryPageParamsOptions<TData>\n const direction = context.fetchOptions?.meta?.fetchMore?.direction\n const oldPages = context.state.data?.pages || []\n const oldPageParams = context.state.data?.pageParams || []\n let result: InfiniteData<unknown> = { pages: [], pageParams: [] }\n let currentPage = 0\n\n const fetchFn = async () => {\n let cancelled = false\n const addSignalProperty = (object: unknown) => {\n Object.defineProperty(object, 'signal', {\n enumerable: true,\n get: () => {\n if (context.signal.aborted) {\n cancelled = true\n } else {\n context.signal.addEventListener('abort', () => {\n cancelled = true\n })\n }\n return context.signal\n },\n })\n }\n\n const queryFn = ensureQueryFn(context.options, context.fetchOptions)\n\n // Create function to fetch a page\n const fetchPage = async (\n data: InfiniteData<unknown>,\n param: unknown,\n previous?: boolean,\n ): Promise<InfiniteData<unknown>> => {\n if (cancelled) {\n return Promise.reject()\n }\n\n if (param == null && data.pages.length) {\n return Promise.resolve(data)\n }\n\n const queryFnContext: OmitKeyof<\n QueryFunctionContext<QueryKey, unknown>,\n 'signal'\n > = {\n queryKey: context.queryKey,\n pageParam: param,\n direction: previous ? 'backward' : 'forward',\n meta: context.options.meta,\n }\n\n addSignalProperty(queryFnContext)\n\n const page = await queryFn(\n queryFnContext as QueryFunctionContext<QueryKey, unknown>,\n )\n\n const { maxPages } = context.options\n const addTo = previous ? addToStart : addToEnd\n\n return {\n pages: addTo(data.pages, page, maxPages),\n pageParams: addTo(data.pageParams, param, maxPages),\n }\n }\n\n // fetch next / previous page?\n if (direction && oldPages.length) {\n const previous = direction === 'backward'\n const pageParamFn = previous ? getPreviousPageParam : getNextPageParam\n const oldData = {\n pages: oldPages,\n pageParams: oldPageParams,\n }\n const param = pageParamFn(options, oldData)\n\n result = await fetchPage(oldData, param, previous)\n } else {\n const remainingPages = pages ?? oldPages.length\n\n // Fetch all pages\n do {\n const param =\n currentPage === 0\n ? (oldPageParams[0] ?? options.initialPageParam)\n : getNextPageParam(options, result)\n if (param == null) {\n break\n }\n result = await fetchPage(result, param)\n currentPage++\n } while (currentPage < remainingPages)\n }\n\n return result\n }\n if (context.options.persister) {\n context.fetchFn = () => {\n return context.options.persister?.(\n fetchFn as any,\n {\n queryKey: context.queryKey,\n meta: context.options.meta,\n signal: context.signal,\n },\n query,\n )\n }\n } else {\n context.fetchFn = fetchFn\n }\n },\n }\n}\n\nfunction getNextPageParam(\n options: InfiniteQueryPageParamsOptions<any>,\n { pages, pageParams }: InfiniteData<unknown>,\n): unknown | undefined {\n const lastIndex = pages.length - 1\n return pages.length > 0\n ? options.getNextPageParam(\n pages[lastIndex],\n pages,\n pageParams[lastIndex],\n pageParams,\n )\n : undefined\n}\n\nfunction getPreviousPageParam(\n options: InfiniteQueryPageParamsOptions<any>,\n { pages, pageParams }: InfiniteData<unknown>,\n): unknown | undefined {\n return pages.length > 0\n ? options.getPreviousPageParam?.(pages[0], pages, pageParams[0], pageParams)\n : undefined\n}\n\n/**\n * Checks if there is a next page.\n */\nexport function hasNextPage(\n options: InfiniteQueryPageParamsOptions<any, any>,\n data?: InfiniteData<unknown>,\n): boolean {\n if (!data) return false\n return getNextPageParam(options, data) != null\n}\n\n/**\n * Checks if there is a previous page.\n */\nexport function hasPreviousPage(\n options: InfiniteQueryPageParamsOptions<any, any>,\n data?: InfiniteData<unknown>,\n): boolean {\n if (!data || !options.getPreviousPageParam) return false\n return getPreviousPageParam(options, data) != null\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -2,7 +2,12 @@ import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest'
|
|
|
2
2
|
import { waitFor } from '@testing-library/react'
|
|
3
3
|
import { CancelledError, InfiniteQueryObserver } from '..'
|
|
4
4
|
import { createQueryClient, queryKey, sleep } from './utils'
|
|
5
|
-
import type {
|
|
5
|
+
import type {
|
|
6
|
+
InfiniteData,
|
|
7
|
+
InfiniteQueryObserverResult,
|
|
8
|
+
QueryCache,
|
|
9
|
+
QueryClient,
|
|
10
|
+
} from '..'
|
|
6
11
|
|
|
7
12
|
describe('InfiniteQueryBehavior', () => {
|
|
8
13
|
let queryClient: QueryClient
|
|
@@ -323,4 +328,72 @@ describe('InfiniteQueryBehavior', () => {
|
|
|
323
328
|
|
|
324
329
|
unsubscribe()
|
|
325
330
|
})
|
|
331
|
+
|
|
332
|
+
test('InfiniteQueryBehavior should not enter an infinite loop when a page errors while retry is on #8046', async () => {
|
|
333
|
+
let errorCount = 0
|
|
334
|
+
const key = queryKey()
|
|
335
|
+
|
|
336
|
+
interface TestResponse {
|
|
337
|
+
data: Array<{ id: string }>
|
|
338
|
+
nextToken?: number
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
const fakeData = [
|
|
342
|
+
{ data: [{ id: 'item-1' }], nextToken: 1 },
|
|
343
|
+
{ data: [{ id: 'item-2' }], nextToken: 2 },
|
|
344
|
+
{ data: [{ id: 'item-3' }], nextToken: 3 },
|
|
345
|
+
{ data: [{ id: 'item-4' }] },
|
|
346
|
+
]
|
|
347
|
+
|
|
348
|
+
const fetchData = async ({ nextToken = 0 }: { nextToken?: number }) =>
|
|
349
|
+
new Promise<TestResponse>((resolve, reject) => {
|
|
350
|
+
setTimeout(() => {
|
|
351
|
+
if (nextToken == 2 && errorCount < 3) {
|
|
352
|
+
errorCount += 1
|
|
353
|
+
reject({ statusCode: 429 })
|
|
354
|
+
return
|
|
355
|
+
}
|
|
356
|
+
resolve(fakeData[nextToken] as TestResponse)
|
|
357
|
+
}, 10)
|
|
358
|
+
})
|
|
359
|
+
|
|
360
|
+
const observer = new InfiniteQueryObserver<
|
|
361
|
+
TestResponse,
|
|
362
|
+
Error,
|
|
363
|
+
InfiniteData<TestResponse>,
|
|
364
|
+
TestResponse,
|
|
365
|
+
typeof key,
|
|
366
|
+
number
|
|
367
|
+
>(queryClient, {
|
|
368
|
+
retry: 5,
|
|
369
|
+
staleTime: 0,
|
|
370
|
+
retryDelay: 10,
|
|
371
|
+
|
|
372
|
+
queryKey: key,
|
|
373
|
+
initialPageParam: 1,
|
|
374
|
+
getNextPageParam: (lastPage) => lastPage.nextToken,
|
|
375
|
+
queryFn: ({ pageParam }) => fetchData({ nextToken: pageParam }),
|
|
376
|
+
})
|
|
377
|
+
|
|
378
|
+
// Fetch Page 1
|
|
379
|
+
const page1Data = await observer.fetchNextPage()
|
|
380
|
+
expect(page1Data.data?.pageParams).toEqual([1])
|
|
381
|
+
|
|
382
|
+
// Fetch Page 2, as per the queryFn, this will reject 2 times then resolves
|
|
383
|
+
const page2Data = await observer.fetchNextPage()
|
|
384
|
+
expect(page2Data.data?.pageParams).toEqual([1, 2])
|
|
385
|
+
|
|
386
|
+
// Fetch Page 3
|
|
387
|
+
const page3Data = await observer.fetchNextPage()
|
|
388
|
+
expect(page3Data.data?.pageParams).toEqual([1, 2, 3])
|
|
389
|
+
|
|
390
|
+
// Now the real deal; re-fetching this query **should not** stamp into an
|
|
391
|
+
// infinite loop where the retryer every time restarts from page 1
|
|
392
|
+
// once it reaches the page where it errors.
|
|
393
|
+
// For this to work, we'd need to reset the error count so we actually retry
|
|
394
|
+
errorCount = 0
|
|
395
|
+
const reFetchedData = await observer.refetch()
|
|
396
|
+
|
|
397
|
+
expect(reFetchedData.data?.pageParams).toEqual([1, 2, 3])
|
|
398
|
+
})
|
|
326
399
|
})
|
|
@@ -13,14 +13,15 @@ export function infiniteQueryBehavior<TQueryFnData, TError, TData, TPageParam>(
|
|
|
13
13
|
): QueryBehavior<TQueryFnData, TError, InfiniteData<TData, TPageParam>> {
|
|
14
14
|
return {
|
|
15
15
|
onFetch: (context, query) => {
|
|
16
|
+
const options = context.options as InfiniteQueryPageParamsOptions<TData>
|
|
17
|
+
const direction = context.fetchOptions?.meta?.fetchMore?.direction
|
|
18
|
+
const oldPages = context.state.data?.pages || []
|
|
19
|
+
const oldPageParams = context.state.data?.pageParams || []
|
|
20
|
+
let result: InfiniteData<unknown> = { pages: [], pageParams: [] }
|
|
21
|
+
let currentPage = 0
|
|
22
|
+
|
|
16
23
|
const fetchFn = async () => {
|
|
17
|
-
const options = context.options as InfiniteQueryPageParamsOptions<TData>
|
|
18
|
-
const direction = context.fetchOptions?.meta?.fetchMore?.direction
|
|
19
|
-
const oldPages = context.state.data?.pages || []
|
|
20
|
-
const oldPageParams = context.state.data?.pageParams || []
|
|
21
|
-
const empty = { pages: [], pageParams: [] }
|
|
22
24
|
let cancelled = false
|
|
23
|
-
|
|
24
25
|
const addSignalProperty = (object: unknown) => {
|
|
25
26
|
Object.defineProperty(object, 'signal', {
|
|
26
27
|
enumerable: true,
|
|
@@ -78,8 +79,6 @@ export function infiniteQueryBehavior<TQueryFnData, TError, TData, TPageParam>(
|
|
|
78
79
|
}
|
|
79
80
|
}
|
|
80
81
|
|
|
81
|
-
let result: InfiniteData<unknown>
|
|
82
|
-
|
|
83
82
|
// fetch next / previous page?
|
|
84
83
|
if (direction && oldPages.length) {
|
|
85
84
|
const previous = direction === 'backward'
|
|
@@ -92,22 +91,20 @@ export function infiniteQueryBehavior<TQueryFnData, TError, TData, TPageParam>(
|
|
|
92
91
|
|
|
93
92
|
result = await fetchPage(oldData, param, previous)
|
|
94
93
|
} else {
|
|
95
|
-
// Fetch first page
|
|
96
|
-
result = await fetchPage(
|
|
97
|
-
empty,
|
|
98
|
-
oldPageParams[0] ?? options.initialPageParam,
|
|
99
|
-
)
|
|
100
|
-
|
|
101
94
|
const remainingPages = pages ?? oldPages.length
|
|
102
95
|
|
|
103
|
-
// Fetch
|
|
104
|
-
|
|
105
|
-
const param =
|
|
96
|
+
// Fetch all pages
|
|
97
|
+
do {
|
|
98
|
+
const param =
|
|
99
|
+
currentPage === 0
|
|
100
|
+
? (oldPageParams[0] ?? options.initialPageParam)
|
|
101
|
+
: getNextPageParam(options, result)
|
|
106
102
|
if (param == null) {
|
|
107
103
|
break
|
|
108
104
|
}
|
|
109
105
|
result = await fetchPage(result, param)
|
|
110
|
-
|
|
106
|
+
currentPage++
|
|
107
|
+
} while (currentPage < remainingPages)
|
|
111
108
|
}
|
|
112
109
|
|
|
113
110
|
return result
|