canvas-query-cache.ts1.9 KBView on GitHub import { getBrowserQueryClient } from '@/lib/browser-query-client';
import type { CanvasViewConfig } from '@/modules/canvas/types/canvas-types';
/**
* tRPC's tanstack query key for `canvas.getCanvases`, without an input — TanStack matches by
* prefix, so this covers every variant (homeViewOnly / includeShared combinations).
*/
const CANVAS_LIST_QUERY_KEY = [['canvas', 'getCanvases']];
/** The raw row shape `canvas.getCanvases` returns (snake_case — it is a `SELECT c.*`). */
type CachedCanvasRow = {
id: string;
view_config: CanvasViewConfig;
updated_at: string | Date;
};
/**
* Writes a just-saved viewConfig into the cached `canvas.getCanvases` response.
*
* `canvasSlice` is hydrated from that query on every mount of a consumer (client-providers,
* PipelineView, ReportsView) and the response is persisted to IndexedDB, so it also survives a
* reload. Saving only to the server leaves the pre-save row in the cache: the next mount inside
* the staleTime window rehydrates the store from it and the user's filter/sort/layout change
* silently reverts — and the next save then writes that stale config back to the server, losing
* the change for good. The change is already persisted; this stops the client from serving the
* version from before it.
*/
export function syncSavedViewConfigToQueryCache(
canvasId: string,
viewConfig: CanvasViewConfig,
updatedAt: string,
): void {
const queryClient = getBrowserQueryClient();
if (!queryClient) return;
queryClient.setQueriesData({ queryKey=[redacted] }, (data: unknown) => {
if (!Array.isArray(data)) return data;
let matched = false;
const next = data.map((row) => {
const canvasRow = row as CachedCanvasRow;
if (canvasRow?.id !== canvasId) return row;
matched = true;
return { ...canvasRow, view_config: viewConfig, updated_at: updatedAt };
});
return matched ? next : data;
});
}