UNPKG

@assistant-ui/react

Version:

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

66 lines (65 loc) • 2.19 kB
"use client"; import { useIsomorphicLayoutEffect } from "../utils/useIsomorphicLayoutEffect.js"; import { c } from "@assistant-ui/tap/react-shim/compiler-runtime"; import { useState } from "@assistant-ui/tap/react-shim"; import { useAuiState } from "@assistant-ui/store"; // src/hooks/useToolCallElapsed.ts /** * Hook that returns the elapsed wall-clock time of the current tool call in * milliseconds, ticking once per second while the call runs. * * Reads `part.timing`. Returns `undefined` when the part is not a tool call, * carries no timing, ended without a recorded completion (the duration is * unknown), or when no message part scope is available (so kit components * stay renderable standalone, e.g. in docs previews). A running call also * returns `undefined` until the component mounts, so a server render never * reads the clock. * * @example * ```tsx * function ToolDuration() { * const elapsedMs = useToolCallElapsed(); * if (elapsedMs === undefined) return null; * return <span>{(elapsedMs / 1000).toFixed(1)}s</span>; * } * ``` */ const useToolCallElapsed = () => { const $ = c(3); const timing = useAuiState(_temp); const partRunning = useAuiState(_temp2); const running = timing !== void 0 && timing.completedAt === void 0 && partRunning; const [now, setNow] = useState(void 0); let t0; let t1; if ($[0] !== running) { t0 = () => { if (!running) return; setNow(Date.now()); const id = setInterval(() => setNow(Date.now()), 1e3); return () => clearInterval(id); }; t1 = [running]; $[0] = running; $[1] = t0; $[2] = t1; } else { t0 = $[1]; t1 = $[2]; } useIsomorphicLayoutEffect(t0, t1); if (timing === void 0) return; if (timing.completedAt !== void 0) return Math.max(0, timing.completedAt - timing.startedAt); if (!running || now === void 0) return; return Math.max(0, now - timing.startedAt); }; function _temp(s) { const part = s.optional.part; return part?.type === "tool-call" ? part.timing : void 0; } function _temp2(s_0) { const part_0 = s_0.optional.part; return part_0?.type === "tool-call" && part_0.status.type === "running"; } export { useToolCallElapsed }; //# sourceMappingURL=useToolCallElapsed.js.map