react-query
Version:
Hooks for managing, caching and syncing asynchronous and remote data in React
138 lines (115 loc) • 5.98 kB
JavaScript
;
exports.__esModule = true;
exports.getNextPageParam = getNextPageParam;
exports.getPreviousPageParam = getPreviousPageParam;
exports.hasNextPage = hasNextPage;
exports.hasPreviousPage = hasPreviousPage;
exports.infiniteQueryBehavior = infiniteQueryBehavior;
var _utils = require("./utils");
function infiniteQueryBehavior() {
return {
onFetch: context => {
context.fetchFn = () => {
var _context$fetchOptions, _context$fetchOptions2, _context$fetchOptions3, _context$fetchOptions4, _context$state$data, _context$state$data2, _context$signal;
const refetchPage = (_context$fetchOptions = context.fetchOptions) == null ? void 0 : (_context$fetchOptions2 = _context$fetchOptions.meta) == null ? void 0 : _context$fetchOptions2.refetchPage;
const fetchMore = (_context$fetchOptions3 = context.fetchOptions) == null ? void 0 : (_context$fetchOptions4 = _context$fetchOptions3.meta) == null ? void 0 : _context$fetchOptions4.fetchMore;
const pageParam = fetchMore == null ? void 0 : fetchMore.pageParam;
const isFetchingNextPage = (fetchMore == null ? void 0 : fetchMore.direction) === 'forward';
const isFetchingPreviousPage = (fetchMore == null ? void 0 : fetchMore.direction) === 'backward';
const oldPages = ((_context$state$data = context.state.data) == null ? void 0 : _context$state$data.pages) || [];
const oldPageParams = ((_context$state$data2 = context.state.data) == null ? void 0 : _context$state$data2.pageParams) || [];
const abortController = (0, _utils.getAbortController)();
const abortSignal = abortController == null ? void 0 : abortController.signal;
let newPageParams = oldPageParams;
let cancelled = false; // Get query function
const queryFn = context.options.queryFn || (() => Promise.reject('Missing queryFn'));
const buildNewPages = (pages, param, page, previous) => {
newPageParams = previous ? [param, ...newPageParams] : [...newPageParams, param];
return previous ? [page, ...pages] : [...pages, page];
}; // Create function to fetch a page
const fetchPage = (pages, manual, param, previous) => {
if (cancelled) {
return Promise.reject('Cancelled');
}
if (typeof param === 'undefined' && !manual && pages.length) {
return Promise.resolve(pages);
}
const queryFnContext = {
queryKey: context.queryKey,
signal: abortSignal,
pageParam: param,
meta: context.meta
};
const queryFnResult = queryFn(queryFnContext);
const promise = Promise.resolve(queryFnResult).then(page => buildNewPages(pages, param, page, previous));
return promise;
};
let promise; // Fetch first page?
if (!oldPages.length) {
promise = fetchPage([]);
} // Fetch next page?
else if (isFetchingNextPage) {
const manual = typeof pageParam !== 'undefined';
const param = manual ? pageParam : getNextPageParam(context.options, oldPages);
promise = fetchPage(oldPages, manual, param);
} // Fetch previous page?
else if (isFetchingPreviousPage) {
const manual = typeof pageParam !== 'undefined';
const param = manual ? pageParam : getPreviousPageParam(context.options, oldPages);
promise = fetchPage(oldPages, manual, param, true);
} // Refetch pages
else {
newPageParams = [];
const manual = typeof context.options.getNextPageParam === 'undefined';
const shouldFetchFirstPage = refetchPage && oldPages[0] ? refetchPage(oldPages[0], 0, oldPages) : true; // Fetch first page
promise = shouldFetchFirstPage ? fetchPage([], manual, oldPageParams[0]) : Promise.resolve(buildNewPages([], oldPageParams[0], oldPages[0])); // Fetch remaining pages
for (let i = 1; i < oldPages.length; i++) {
promise = promise.then(pages => {
const shouldFetchNextPage = refetchPage && oldPages[i] ? refetchPage(oldPages[i], i, oldPages) : true;
if (shouldFetchNextPage) {
const param = manual ? oldPageParams[i] : getNextPageParam(context.options, pages);
return fetchPage(pages, manual, param);
}
return Promise.resolve(buildNewPages(pages, oldPageParams[i], oldPages[i]));
});
}
}
const finalPromise = promise.then(pages => ({
pages,
pageParams: newPageParams
}));
(_context$signal = context.signal) == null ? void 0 : _context$signal.addEventListener('abort', () => {
cancelled = true;
abortController == null ? void 0 : abortController.abort();
});
return finalPromise;
};
}
};
}
function getNextPageParam(options, pages) {
return options.getNextPageParam == null ? void 0 : options.getNextPageParam(pages[pages.length - 1], pages);
}
function getPreviousPageParam(options, pages) {
return options.getPreviousPageParam == null ? void 0 : options.getPreviousPageParam(pages[0], pages);
}
/**
* Checks if there is a next page.
* Returns `undefined` if it cannot be determined.
*/
function hasNextPage(options, pages) {
if (options.getNextPageParam && Array.isArray(pages)) {
const nextPageParam = getNextPageParam(options, pages);
return typeof nextPageParam !== 'undefined' && nextPageParam !== null && nextPageParam !== false;
}
}
/**
* Checks if there is a previous page.
* Returns `undefined` if it cannot be determined.
*/
function hasPreviousPage(options, pages) {
if (options.getPreviousPageParam && Array.isArray(pages)) {
const previousPageParam = getPreviousPageParam(options, pages);
return typeof previousPageParam !== 'undefined' && previousPageParam !== null && previousPageParam !== false;
}
}