export const getStreamInfiniteData = async (args: { url: string; pageParam: number; queryKey: QueryKey; signal: AbortSignal; }): Promise => { type InfiniteQueryData = InfiniteData | undefined; const { pageParam, url, queryKey, signal } = args; const response = await fetch(url, { headers: { accept: "application/x-ndjson", Authorization: "Bearer " + scopedStorageManager.getItem("kcToken"), }, signal, }); if (!response.body) { throw new Error("No response body"); } const ndjson = ndjsonStream(response.body); const reader = ndjson.getReader(); const previousData: InfiniteQueryData = queryClient.getQueryData(queryKey); // if the next page already has data, then it means invalidation is happening const isInvalidating = previousData?.pages[pageParam + 1] !== undefined; const newPage = [] as TData[]; try { while (true) { const { done, value } = await reader.read(); // if the data is being invalidated then fill the new page with the new data if (isInvalidating) { if (value) { newPage.push(value); } if (!done) continue; } queryClient.setQueryData(queryKey, (oldData: InfiniteQueryData) => { // if there is no data, then initialize it with a page with single value if (!oldData) { return { pages: [value ? [value] : []], pageParams: [0], }; } // if data is being invalidated then replace the current page with the new page if (isInvalidating) { return { ...oldData, pages: oldData.pages.map((page, index) => { if (index === pageParam) { return newPage; } return page; }), }; } // if the last page is filled, then add a new page and push the value from the stream to it if (oldData.pages[oldData.pages.length - 1].length === DEFAULT_PAGINATION_SIZE) { return { ...oldData, pages: [...oldData.pages, value ? [value] : []], pageParams: [...oldData.pageParams, oldData.pages.length], }; } else { // add the value to the last page return { ...oldData, pages: oldData.pages.map((page, index) => { if (index === oldData.pages.length - 1) { return value ? [...page, value] : page; } return page; }), }; } }); if (done) break; } } catch (e) { console.error("Errored reading stream:\n", e); } finally { reader.releaseLock(); } const newData: InfiniteQueryData = queryClient.getQueryData(queryKey); return newData ? newData.pages[pageParam] : []; };