import { useState, useEffect, useCallback } from "react"; import type { InspectorClientProtocol } from "../mcp/inspectorClientProtocol.js"; import type { PagedPromptsState, PagedPromptsStateEventMap, LoadPageResult, } from "../mcp/state/pagedPromptsState.js"; import type { Prompt } from "@modelcontextprotocol/sdk/types.js"; import type { TypedEventGeneric } from "../mcp/typedEventTarget.js"; export interface UsePagedPromptsResult { prompts: Prompt[]; loadPage: ( cursor?: string, metadata?: Record, ) => Promise; clear: () => void; } /** * React hook that subscribes to PagedPromptsState and returns prompts + loadPage. */ export function usePagedPrompts( client: InspectorClientProtocol | null, pagedPromptsState: PagedPromptsState | null, ): UsePagedPromptsResult { const [prompts, setPrompts] = useState( pagedPromptsState?.getPrompts() ?? [], ); useEffect(() => { if (!pagedPromptsState) { setPrompts([]); return; } setPrompts(pagedPromptsState.getPrompts()); const onPromptsChange = ( event: TypedEventGeneric, ) => { setPrompts(event.detail); }; pagedPromptsState.addEventListener("promptsChange", onPromptsChange); return () => { pagedPromptsState.removeEventListener("promptsChange", onPromptsChange); }; }, [pagedPromptsState]); const loadPage = useCallback( async ( cursor?: string, metadata?: Record, ): Promise => { if (!pagedPromptsState || !client) { return { prompts: [], nextCursor: undefined }; } const result = await pagedPromptsState.loadPage(cursor, metadata); setPrompts(pagedPromptsState.getPrompts()); return result; }, [client, pagedPromptsState], ); const clear = useCallback(() => { pagedPromptsState?.clear(); }, [pagedPromptsState]); return { prompts, loadPage, clear }; }