(workspaceId: string)
| 125 | * `useQueries`. One slow server cannot block the others. |
| 126 | */ |
| 127 | export function useMcpToolsQuery(workspaceId: string) { |
| 128 | const { data: servers, isLoading: serversLoading } = useMcpServers(workspaceId) |
| 129 | |
| 130 | // Skip disabled rows (would 404 → negative-cache) and rows from a previous |
| 131 | // workspace (keepPreviousData on useMcpServers). |
| 132 | const serverIds = useMemo( |
| 133 | () => |
| 134 | servers |
| 135 | ? servers |
| 136 | .filter((s) => s.enabled && s.workspaceId === workspaceId) |
| 137 | .map((s) => s.id) |
| 138 | .sort() |
| 139 | : [], |
| 140 | [servers, workspaceId] |
| 141 | ) |
| 142 | |
| 143 | const results = useQueries({ |
| 144 | queries: serverIds.map((serverId) => ({ |
| 145 | queryKey: mcpKeys.serverToolsList(workspaceId, serverId), |
| 146 | queryFn: ({ signal }: { signal?: AbortSignal }) => |
| 147 | fetchMcpTools(workspaceId, false, signal, serverId), |
| 148 | enabled: !!workspaceId, |
| 149 | retry: false, |
| 150 | staleTime: 30 * 1000, |
| 151 | refetchOnWindowFocus: false, |
| 152 | })), |
| 153 | }) |
| 154 | |
| 155 | return useMemo(() => { |
| 156 | const tools: McpTool[] = [] |
| 157 | let hasData = false |
| 158 | let anyServerLoading = false |
| 159 | let firstError: Error | null = null |
| 160 | for (const result of results) { |
| 161 | // Drop stale data from servers whose latest refetch errored. |
| 162 | if (result.data && !result.isError) { |
| 163 | tools.push(...result.data) |
| 164 | hasData = true |
| 165 | } |
| 166 | if (result.isLoading) anyServerLoading = true |
| 167 | if (!firstError && result.error instanceof Error) firstError = result.error |
| 168 | } |
| 169 | return { |
| 170 | data: tools, |
| 171 | isLoading: (serversLoading || anyServerLoading) && !hasData, |
| 172 | isFetching: serversLoading || results.some((r) => r.isFetching), |
| 173 | // Suppress when any healthy server rendered; per-server errors live in `perServer`. |
| 174 | error: hasData ? null : firstError, |
| 175 | perServer: results, |
| 176 | } |
| 177 | }, [results, serversLoading]) |
| 178 | } |
| 179 | |
| 180 | export function useForceRefreshMcpTools() { |
| 181 | const queryClient = useQueryClient() |
no test coverage detected