feat(FN-4854): complete Step 2 — hydrate agents cache
Fusion-Task-Id: FN-4854 Fusion-Task-Lineage: 969ec04a-efe3-4dee-b183-2d4f2de6b388
This commit is contained in:
committed by
gsxdsm
parent
228daa8f35
commit
0f9c08ace7
@@ -45,6 +45,7 @@ describe("useAgents", () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
MockEventSource.instances = [];
|
MockEventSource.instances = [];
|
||||||
window.sessionStorage.clear();
|
window.sessionStorage.clear();
|
||||||
|
window.localStorage.clear();
|
||||||
mockFetchAgents.mockReset().mockResolvedValue([]);
|
mockFetchAgents.mockReset().mockResolvedValue([]);
|
||||||
mockFetchAgentStats.mockReset().mockResolvedValue(defaultStats);
|
mockFetchAgentStats.mockReset().mockResolvedValue(defaultStats);
|
||||||
vi.spyOn(console, "error").mockImplementation(() => {});
|
vi.spyOn(console, "error").mockImplementation(() => {});
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import { useState, useEffect, useCallback } from "react";
|
import { useState, useEffect, useCallback, useRef } from "react";
|
||||||
import type { Agent, AgentState, AgentCapability, AgentStats } from "../api";
|
import type { Agent, AgentState, AgentCapability, AgentStats } from "../api";
|
||||||
import { fetchAgents, fetchAgentStats } from "../api";
|
import { fetchAgents, fetchAgentStats } from "../api";
|
||||||
import { isEphemeralAgent } from "@fusion/core";
|
import { isEphemeralAgent } from "@fusion/core";
|
||||||
import { subscribeSse } from "../sse-bus";
|
import { subscribeSse } from "../sse-bus";
|
||||||
|
import { readCache, SWR_CACHE_KEYS, writeCache } from "../utils/swrCache";
|
||||||
|
|
||||||
interface UseAgentsOptions {
|
interface UseAgentsOptions {
|
||||||
filterState?: AgentState | "all";
|
filterState?: AgentState | "all";
|
||||||
@@ -16,12 +17,21 @@ interface AgentFilter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function useAgents(projectId?: string, options?: UseAgentsOptions) {
|
export function useAgents(projectId?: string, options?: UseAgentsOptions) {
|
||||||
const [agents, setAgents] = useState<Agent[]>([]);
|
const [agents, setAgents] = useState<Agent[]>(() => {
|
||||||
const [stats, setStats] = useState<AgentStats | null>(null);
|
const cached = readCache<Agent[]>(SWR_CACHE_KEYS.AGENTS);
|
||||||
|
return Array.isArray(cached) ? cached : [];
|
||||||
|
});
|
||||||
|
const [stats, setStats] = useState<AgentStats | null>(() => {
|
||||||
|
const cached = readCache<AgentStats>(SWR_CACHE_KEYS.AGENT_STATS);
|
||||||
|
return cached ?? null;
|
||||||
|
});
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
const hasCachedHydrationRef = useRef(agents.length > 0 || stats !== null);
|
||||||
|
|
||||||
const loadAgents = useCallback(async (filter?: AgentFilter) => {
|
const loadAgents = useCallback(async (filter?: AgentFilter) => {
|
||||||
setIsLoading(true);
|
if (!hasCachedHydrationRef.current) {
|
||||||
|
setIsLoading(true);
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
const filterState = options?.filterState;
|
const filterState = options?.filterState;
|
||||||
const baseFilter = filterState && filterState !== "all" ? { state: filterState } : undefined;
|
const baseFilter = filterState && filterState !== "all" ? { state: filterState } : undefined;
|
||||||
@@ -40,6 +50,8 @@ export function useAgents(projectId?: string, options?: UseAgentsOptions) {
|
|||||||
// with duplicate-key warnings until the dashboard runs out of heap.
|
// with duplicate-key warnings until the dashboard runs out of heap.
|
||||||
const unique = Array.from(new Map(data.map((a) => [a.id, a])).values());
|
const unique = Array.from(new Map(data.map((a) => [a.id, a])).values());
|
||||||
setAgents(unique);
|
setAgents(unique);
|
||||||
|
writeCache(SWR_CACHE_KEYS.AGENTS, unique, { maxBytes: 500_000 });
|
||||||
|
hasCachedHydrationRef.current = hasCachedHydrationRef.current || unique.length > 0;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error("Failed to load agents:", err);
|
console.error("Failed to load agents:", err);
|
||||||
} finally {
|
} finally {
|
||||||
@@ -51,6 +63,8 @@ export function useAgents(projectId?: string, options?: UseAgentsOptions) {
|
|||||||
try {
|
try {
|
||||||
const data = await fetchAgentStats(projectId);
|
const data = await fetchAgentStats(projectId);
|
||||||
setStats(data);
|
setStats(data);
|
||||||
|
writeCache(SWR_CACHE_KEYS.AGENT_STATS, data, { maxBytes: 500_000 });
|
||||||
|
hasCachedHydrationRef.current = true;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error("Failed to load agent stats:", err);
|
console.error("Failed to load agent stats:", err);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user