@@ -1088,28 +1088,63 @@ interface RunGroupVariables {
10881088 runMode ?: 'all' | 'incomplete'
10891089}
10901090
1091- type RowsCacheSnapshots = Array < [ ReadonlyArray < unknown > , TableRowsResponse ] >
1091+ type InfiniteRowsCache = { pages : TableRowsResponse [ ] ; pageParams : number [ ] }
1092+ /**
1093+ * Cache shapes that hold table-row data. Single-page (`useTableRows`) and
1094+ * infinite (`useInfiniteTableRows`) live under the same `rowsRoot(tableId)`
1095+ * prefix, so optimistic mutations have to walk both shapes.
1096+ */
1097+ type RowsCacheEntry = TableRowsResponse | InfiniteRowsCache
1098+ type RowsCacheSnapshots = Array < [ ReadonlyArray < unknown > , RowsCacheEntry ] >
1099+
1100+ function isInfiniteRowsCache ( value : unknown ) : value is InfiniteRowsCache {
1101+ return (
1102+ ! ! value &&
1103+ typeof value === 'object' &&
1104+ Array . isArray ( ( value as { pages ?: unknown } ) . pages ) &&
1105+ Array . isArray ( ( value as { pageParams ?: unknown } ) . pageParams )
1106+ )
1107+ }
10921108
10931109/**
10941110 * Walks every cached row-list under `tableId`, applies `transform` to each row,
1095- * and snapshots the originals for rollback. Returns `null` if no row was touched
1096- * — callers can use that to skip a useless invalidation cycle.
1111+ * and snapshots the originals for rollback.
10971112 *
1098- * `transform(row)` returns the next row to write, or `null` to leave it. The
1099- * common pattern is "matching cells flip state, others are skipped".
1113+ * Handles both cache shapes: the single-page `TableRowsResponse` and the
1114+ * infinite-query `{ pages, pageParams }`. `transform(row)` returns the next
1115+ * row to write, or `null` to leave it. The common pattern is "matching cells
1116+ * flip state, others are skipped".
11001117 */
11011118export async function snapshotAndMutateRows (
11021119 queryClient : ReturnType < typeof useQueryClient > ,
11031120 tableId : string ,
11041121 transform : ( row : TableRow ) => TableRow | null
11051122) : Promise < RowsCacheSnapshots > {
11061123 await queryClient . cancelQueries ( { queryKey : tableKeys . rowsRoot ( tableId ) } )
1107- const matching = queryClient . getQueriesData < TableRowsResponse > ( {
1124+ const matching = queryClient . getQueriesData < RowsCacheEntry > ( {
11081125 queryKey : tableKeys . rowsRoot ( tableId ) ,
11091126 } )
11101127 const snapshots : RowsCacheSnapshots = [ ]
11111128 for ( const [ key , data ] of matching ) {
11121129 if ( ! data ) continue
1130+ if ( isInfiniteRowsCache ( data ) ) {
1131+ let touched = false
1132+ const nextPages = data . pages . map ( ( page ) => {
1133+ let pageTouched = false
1134+ const nextRows = page . rows . map ( ( r ) => {
1135+ const next = transform ( r )
1136+ if ( ! next ) return r
1137+ pageTouched = true
1138+ touched = true
1139+ return next
1140+ } )
1141+ return pageTouched ? { ...page , rows : nextRows } : page
1142+ } )
1143+ if ( ! touched ) continue
1144+ snapshots . push ( [ key , data ] )
1145+ queryClient . setQueryData < InfiniteRowsCache > ( key , { ...data , pages : nextPages } )
1146+ continue
1147+ }
11131148 let touched = false
11141149 const nextRows = data . rows . map ( ( r ) => {
11151150 const next = transform ( r )
0 commit comments