Download src/lib/hooks/useRateLimit.ts from asnannp/DocDoeAI: direct link, hf CLI and curl.
- Browser
- Download file 2.1 kB
-
https://huggingface.co/spaces/asnannp/DocDoeAI/resolve/main/src/lib/hooks/useRateLimit.ts
- Command line
-
hf download hf://spaces/asnannp/DocDoeAI/src/lib/hooks/useRateLimit.ts
-
curl -L -o useRateLimit.ts https://huggingface.co/spaces/asnannp/DocDoeAI/resolve/main/src/lib/hooks/useRateLimit.ts
2.1 kB
| import { useState, useCallback } from "react"; | |
| import { classifyError } from "@/lib/api/errorTypes"; | |
| import { isApiError, type RateLimitScope } from "@/lib/api/client"; | |
| type RateLimitState = { | |
| isRateLimited: boolean; | |
| remainingSeconds: number; | |
| canRetry: boolean; | |
| scope: RateLimitScope | null; | |
| }; | |
| export function useRateLimit() { | |
| const [rateLimitState, setRateLimitState] = useState<RateLimitState>({ | |
| isRateLimited: false, | |
| remainingSeconds: 0, | |
| canRetry: true, | |
| scope: null, | |
| }); | |
| const checkRateLimit = useCallback((error: unknown): boolean => { | |
| const errorInfo = classifyError(error); | |
| if (errorInfo.type === "RATE_LIMITED") { | |
| const scope = isApiError(error) ? error.rateLimitScope : null; | |
| const retryAfter = isApiError(error) && typeof error.retryAfter === "number" ? error.retryAfter : 30; | |
| setRateLimitState({ | |
| isRateLimited: true, | |
| remainingSeconds: retryAfter, | |
| canRetry: false, | |
| scope, | |
| }); | |
| // Start countdown | |
| let secondsLeft = retryAfter; | |
| const countdownInterval = setInterval(() => { | |
| secondsLeft -= 1; | |
| if (secondsLeft <= 0) { | |
| clearInterval(countdownInterval); | |
| setRateLimitState({ | |
| isRateLimited: false, | |
| remainingSeconds: 0, | |
| canRetry: true, | |
| scope: null, | |
| }); | |
| } else { | |
| setRateLimitState(prev => ({ | |
| ...prev, | |
| remainingSeconds: secondsLeft, | |
| })); | |
| } | |
| }, 1000); | |
| return true; | |
| } | |
| return false; | |
| }, []); | |
| const resetRateLimit = useCallback(() => { | |
| setRateLimitState({ | |
| isRateLimited: false, | |
| remainingSeconds: 0, | |
| canRetry: true, | |
| scope: null, | |
| }); | |
| }, []); | |
| const getRateLimitMessage = useCallback(() => { | |
| if (rateLimitState.isRateLimited) { | |
| return `You're moving fast. I'll be ready in ${rateLimitState.remainingSeconds} seconds.`; | |
| } | |
| return ""; | |
| }, [rateLimitState]); | |
| return { | |
| rateLimitState, | |
| checkRateLimit, | |
| resetRateLimit, | |
| getRateLimitMessage, | |
| }; | |
| } |