import { createContext, useCallback, useContext, useMemo, type ReactNode } from "react"; import type { ZodType, input as ZodInput, output as ZodOutput } from "zod"; import { callPluginRpc, type PluginRpcContract } from "./rpc.js"; interface PluginRpcContextValue { invoke(method: string, input: unknown): Promise; } const PluginRpcContext = createContext(null); export function PluginRpcProvider({ children, invoke, }: { children: ReactNode; invoke(method: string, input: unknown): Promise; }) { const value = useMemo(() => ({ invoke }), [invoke]); return {children}; } export function useRpc( contract: PluginRpcContract, ): (input: ZodInput) => Promise> { const context = useContext(PluginRpcContext); if (!context) throw new Error("useRpc must run inside a contributed plugin surface"); return useCallback( (input: ZodInput) => callPluginRpc(contract, context.invoke, input), [context, contract], ); }