import { InfiniteData, replaceEqualDeep } from '@tanstack/react-query' import { ApiCollection, ResourceObject } from '../types' type Pages = InfiniteData> /** replaceEqualById * TanStack's default structural sharing compares arrays by index, so an insert or * delete gives every shifted record a new identity. Match by id instead. */ export function replaceEqualById(oldData: unknown, newData: unknown): unknown { const prev = oldData as Pages | undefined const next = newData as Pages if (!prev?.pages || !next?.pages) return replaceEqualDeep(prev, next) const prevById = new Map() prev.pages.forEach(page => page.data.forEach(record => prevById.set(record.id, record))) let changed = prev.pages.length !== next.pages.length const pages = next.pages.map((page, index) => { const prevPage = prev.pages[index] const data = page.data.map(record => { const previous = prevById.get(record.id) return previous ? replaceEqualDeep(previous, record) : record }) const links = replaceEqualDeep(prevPage?.links, page.links) const meta = replaceEqualDeep(prevPage?.meta, page.meta) const sameRecords = !!prevPage && data.length === prevPage.data.length && data.every((record, i) => record === prevPage.data[i]) if (prevPage && sameRecords && links === prevPage.links && meta === prevPage.meta) { return prevPage } changed = true return { ...page, data, links, meta } }) const pageParams = replaceEqualDeep(prev.pageParams, next.pageParams) if (!changed && pageParams === prev.pageParams) return prev return { ...next, pages, pageParams } }