- name
- deslop-cache
- description
- Clean up hand-rolled caches and request state generated by AI in packages/review/app. Use after adding or changing caching, prefetching or request code in the canvas, before review.
Review every canvas file the branch changed (`git diff origin/main --stat -- packages/review/app`). Look for `Map`, `WeakMap`, module-level `let`, refs that hold fetched data, and hand-written fetch effects. Assume each one duplicates the query client, and prove otherwise before you keep it.
## The cache
- Fetched data lives in TanStack Query. The client comes from `createCanvasQueryClient` in `src/canvas-query.tsx`. Desktop's canvas shares one client across the boards it shows (`SharedCanvasQueryClient`).
- Keys come from `canvasQueryKeys`. A key for one board's data names the board first, so boards that share the client do not share entries.
- Shared UI state lives in the existing Zustand stores. Do not put UI state in the query cache, and do not put fetched data in Zustand. Do not add a cache library.
## Checklist
- **Side tables.** Replace each of these with the query client:
- a `WeakMap<QueryClient, …>` or a `Map` that holds a value per board: `queryClient.getQueryData` / `setQueryData` under a `canvasQueryKeys` key
- a map of promises that runs a read once: `queryClient.fetchQuery` with `staleTime: Infinity` for data that never changes
- an entry marked stale and then filtered on read: `queryClient.removeQueries`
- a "previous value while the next one loads" ref: `placeholderData`
- a timer or flag that reads again: `staleTime`, `invalidateQueries` or `refetch`
- **What may stay a map.** Keep a `Map` or `WeakMap` only for these, and say why in one short comment:
- the result of a pure function of one object (a `WeakMap` keyed by that object)
- something that must be cleaned up with its owner, such as object URLs revoked on unmount
- a lookup that lives and dies inside one effect
- server code with no React, such as a short time-limited cache in `packages/review/src`
- **Freshness.** Data drawn from the cache must stay current, or it must be dropped:
- A cached copy of a board that no stream follows can be stale. Remove it when the stream stops. Do not draw it.
- Read the stream line's version (and links revision) before you read a board's resources again. Activity alone sends a board again.
- Key a read per board when the server checks it against its board. A cache shared across boards skips that check.
- Keep a version in a key when other code relies on a new version reading again, such as the page bar's place.
- **Focus.** `refetchOnWindowFocus` listens only to `visibilitychange`. In Desktop, switching to another app leaves the window visible. A read that must follow window focus keeps its own `focus` listener.
- **Data paths.** Do not schedule data updates with `requestAnimationFrame`. It pauses in hidden windows and does not run reliably under jsdom. React already batches updates from one task.
- **Tests.** Test a cache through what the canvas shows. Hold every request, switch boards, and check what draws. Then remove the cache in the code and check that the test fails. Do not count calls to internal functions.
Ver no GitHub