UNPKG

@assistant-ui/react

Version:

Open-source TypeScript/React library for building production-grade AI chat experiences

96 lines (95 loc) • 2.54 kB
"use client"; import { AssistantFrameHost } from "@assistant-ui/core"; import { useEffect } from "@assistant-ui/tap/react-shim"; // src/model-context/frame/useAssistantFrameHost.ts /** * React hook that manages the lifecycle of an AssistantFrameHost and its binding to the current AssistantRuntime. * * Usage example: * ```typescript * function MyComponent() { * const iframeRef = useRef<HTMLIFrameElement>(null); * * useAssistantFrameHost({ * iframeRef, * targetOrigin: "https://trusted-domain.com", * }); * * return <iframe ref={iframeRef} src="..." />; * } * ``` */ const useAssistantFrameHost = ({ iframeRef, targetOrigin, register }) => { useEffect(() => { let active; const syncFrame = () => { const iframe = iframeRef.current; const iframeWindow = iframe?.isConnected === false ? null : iframe?.contentWindow; if (active && active.iframe === iframe && active.window === iframeWindow) return; const previous = active; active = void 0; let disposalFailed = false; let disposalError; try { previous?.dispose(); } catch (error) { disposalFailed = true; disposalError = error; } if (iframe && iframeWindow) { const frameHost = new AssistantFrameHost(iframeWindow, targetOrigin); let unsubscribe; try { unsubscribe = register(frameHost); } catch (error_0) { frameHost.dispose(); throw error_0; } const onLoad = () => frameHost.frameLoaded(); iframe.addEventListener("load", onLoad); active = { iframe, window: iframeWindow, dispose: () => { iframe.removeEventListener("load", onLoad); let cleanupFailed = false; let cleanupError; try { frameHost.dispose(); } catch (error_1) { cleanupFailed = true; cleanupError = error_1; } try { unsubscribe(); } catch (error_2) { if (cleanupFailed) console.error("[assistant-ui] AssistantFrameHost unregistration failed.", error_2); else { cleanupFailed = true; cleanupError = error_2; } } if (cleanupFailed) throw cleanupError; } }; } if (disposalFailed) throw disposalError; }; syncFrame(); const observer = new MutationObserver(syncFrame); observer.observe(document, { childList: true, subtree: true }); return () => { observer.disconnect(); active?.dispose(); }; }, [ iframeRef, targetOrigin, register ]); }; export { useAssistantFrameHost }; //# sourceMappingURL=useAssistantFrameHost.js.map