Extract usePacketDetail and share it across the analyzer and overlay

This commit is contained in:
MrAlders0n committed 2026-07-27 18:08:21 -04:00
1 parent 161f481576
commit 1dbbce1ad8
3 files changed
+49 -17

No files matched your search

+4 -17
View File
@@ -1,6 +1,6 @@
import React, { useState, useEffect, useCallback, useRef, lazy, Suspense } from "react";
import { BrowserRouter, useSearchParams } from "react-router-dom";
import { QueryClient, QueryClientProvider, useQuery } from "@tanstack/react-query";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { RegionProvider, useRegion, useRegionSelection } from "./hooks/useRegion";
import {
ALL_REGIONS,
@@ -27,7 +27,7 @@ import { RouteTable } from "./features/routes/RouteTable";
import { TraceList } from "./features/traces/TraceList";
import { ChannelList } from "./features/channels/ChannelList";
import { EmptyState } from "./components/EmptyState";
import { getPacketDetail } from "./api/client";
import { usePacketDetail } from "./features/packets/usePacketDetail";
import { WsManager } from "./api/ws-manager";
import { WS_URL, ENABLED_TABS } from "./lib/constants";
import type { PacketDetail } from "./types/api";
@@ -145,21 +145,8 @@ function AppInner() {
const [pathMapInitialKey, setPathMapInitialKey] = useState<string | null>(null);
const pathLinkHandledRef = useRef(false);
// short staleTime: observations keep accruing, so reopening the analyzer should show them
// instead of a snapshot frozen at first open
const { data: analyzerDetail, isLoading: analyzerLoading } = useQuery({
queryKey: ["packet-detail", analyzerHash],
queryFn: () => getPacketDetail(analyzerHash!),
enabled: !!analyzerHash,
staleTime: 30_000,
});
const { data: overlayPacketDetail, isLoading: overlayPacketLoading } = useQuery({
queryKey: ["packet-detail", overlayPacketHash],
queryFn: () => getPacketDetail(overlayPacketHash!),
enabled: !!overlayPacketHash,
staleTime: 30_000,
});
const { data: analyzerDetail, isLoading: analyzerLoading } = usePacketDetail(analyzerHash);
const { data: overlayPacketDetail, isLoading: overlayPacketLoading } = usePacketDetail(overlayPacketHash);
// deep link: ?hash opens the analyzer drawer; ?path then opens the path popup once, pre-selected
useEffect(() => {
+14
View File
@@ -0,0 +1,14 @@
import { useQuery } from "@tanstack/react-query";
import { getPacketDetail } from "../../api/client";
import type { PacketDetail } from "../../types/api";
// One query per hash shared by the expanded row, the analyzer drawer and the overlay — TanStack
// dedupes, so a row expanded under an open drawer costs a single request.
export function usePacketDetail(hash: string | null) {
return useQuery<PacketDetail>({
queryKey: ["packet-detail", hash],
queryFn: () => getPacketDetail(hash!),
enabled: !!hash,
staleTime: 30_000,
});
}
@@ -0,0 +1,31 @@
import { describe, it, expect, vi, beforeEach } from "vitest";
import { renderHook, waitFor } from "@testing-library/react";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { usePacketDetail } from "../../../src/features/packets/usePacketDetail";
const getPacketDetail = vi.fn();
vi.mock("../../../src/api/client", () => ({
getPacketDetail: (hash: string) => getPacketDetail(hash),
}));
const wrapper = ({ children }: { children: React.ReactNode }) => (
<QueryClientProvider client={new QueryClient({ defaultOptions: { queries: { retry: false } } })}>
{children}
</QueryClientProvider>
);
beforeEach(() => getPacketDetail.mockReset());
describe("usePacketDetail", () => {
it("does not fetch when hash is null", () => {
renderHook(() => usePacketDetail(null), { wrapper });
expect(getPacketDetail).not.toHaveBeenCalled();
});
it("fetches the detail for a hash", async () => {
getPacketDetail.mockResolvedValue({ packetHash: "AA11", observations: [] });
const { result } = renderHook(() => usePacketDetail("AA11"), { wrapper });
await waitFor(() => expect(result.current.data?.packetHash).toBe("AA11"));
expect(getPacketDetail).toHaveBeenCalledWith("AA11");
});
});