UNPKG

@adonis-agora/agent

Version:

Governed, durable-backed AI agent (chat + tool-calling + governance) for AdonisJS — part of the Agora ecosystem.

39 lines • 1.75 kB
import { useEffect, useRef, useState } from 'react'; /** What {@link useApprovalCountdown} reads for `expiresAt` at `now`, without the ticking. */ export function approvalCountdown(expiresAt, now = Date.now()) { const deadline = expiresAt == null ? Number.NaN : Date.parse(expiresAt); if (!Number.isFinite(deadline)) { return { remainingMs: null, isExpired: false }; } const remainingMs = Math.max(0, deadline - now); return { remainingMs, isExpired: remainingMs === 0 }; } /** * Time left on an approval request (`call.approval.expiresAt`), ticking until it lapses and then * holding at zero. Headless: pair `remainingMs` with `formatElapsed` or any label of your own, and * use `isExpired` to stop offering buttons the server would refuse (`410 Gone`). The server stays * the authority — a lapse is final only once the call settles `expired`. */ export function useApprovalCountdown(expiresAt, options = {}) { const { intervalMs = 1000 } = options; const nowRef = useRef(options.now ?? Date.now); nowRef.current = options.now ?? Date.now; const [state, setState] = useState(() => approvalCountdown(expiresAt, nowRef.current())); useEffect(() => { const read = () => approvalCountdown(expiresAt, nowRef.current()); const first = read(); setState(first); if (first.remainingMs === null || first.isExpired) { return; } const timer = setInterval(() => { const next = read(); setState(next); if (next.isExpired) clearInterval(timer); }, intervalMs); return () => clearInterval(timer); }, [expiresAt, intervalMs]); return state; } //# sourceMappingURL=countdown.js.map