import { createContext, useCallback, useContext } from "react"; import type { AgentView, Batch } from "../../api/types.ts"; import type { ModuleEvent } from "./events.ts"; // состояние модуля, которое ядро держит за него: агент, текущее событие пакета, блокировка кнопки обновления export interface ModuleActivity { agent: AgentView | null; event: ModuleEvent | null; busy: boolean; // запрос постановки в пути или отслеживаемый пакет — пакет действия обновления модуля running: Batch | null; // отслеживаемый пакет (последний ответ опроса) start(): Promise; // «обновить» текущий проект модуля; без проекта у модуля с охватом «проект» — ничего track(batchId: number): void; // опрашивать уже поставленный пакет (после создания проекта) } export interface ActivityValue { agents: AgentView[]; modules: Record; summary: "error" | "busy" | "online" | "offline"; trackBatch(batchId: number): Promise; // пакет без известного модуля: модуль берётся из ответа хаба } export const AGENTS_KEY = ["agents"] as const; export const ActivityContext = createContext(null); function useActivity(): ActivityValue { const v = useContext(ActivityContext); if (!v) throw new Error("активность модулей вызвана вне ActivityProvider: оберните оболочку в "); return v; } export function useModuleActivity(name: string): ModuleActivity { const m = useActivity().modules[name]; if (!m) throw new Error(`у модуля «${name}» нет описания состояния (HubModule.status)`); return m; } // отслеживать пакет, поставленный хабом конкретному модулю (после создания/правки проекта); неизвестный модуль пропускается export function useTrackModuleBatch(): (module: string, batchId: number) => void { const { modules } = useActivity(); return useCallback((module, id) => { modules[module]?.track(id); }, [modules]); } export const useAgents = (): AgentView[] => useActivity().agents; export const useActivitySummary = (): ActivityValue["summary"] => useActivity().summary; export const useTrackBatch = (): ActivityValue["trackBatch"] => useActivity().trackBatch;