{ "name": "rate-limit-meter", "type": "registry:ui", "title": "Rate Limit Meter", "description": "A quota with its reset time given equal weight. \"9,800 of 10,000\" is alarming; \"resets in 40 seconds\" makes it fine — showing the first without the second sends people to build a cache they do not need.", "category": "Runtime", "dependencies": [], "registryDependencies": [ "fmt", "lib-motion", "lib-styles", "lib-utils" ], "files": [ { "path": "components/ui/rate-limit-meter.tsx", "type": "registry:ui", "content": "import type { ComponentProps, ReactNode } from 'react'\nimport { Fmt } from '@/components/ui/fmt'\nimport { enterFade, growIn } from '@/lib/motion'\nimport { radius, surface } from '@/lib/styles'\nimport { cn } from '@/lib/utils'\n\n/**\n * A quota and the window it resets in.\n *\n * The reset time is as prominent as the count. \"9,800 of 10,000\" is alarming\n * and \"resets in 40 seconds\" makes it fine; showing the first without the\n * second sends people to write a caching layer they do not need.\n *\n * Burn rate is derived from what has been consumed against how much of the\n * window has elapsed, and the projection says whether the quota runs out before\n * the reset. That is the question — not the current number.\n *\n * Remaining is shown, not used. Both are on screen, but the headline is the one\n * a caller acts on, and inverting it costs a subtraction every glance.\n */\nfunction RateLimitMeter({\n limit,\n remaining,\n resetAt,\n windowSeconds,\n now,\n label = 'Rate limit',\n remainingLabel = 'remaining',\n resetsLabel = 'resets',\n exhaustedLabel = 'Quota exhausted',\n projectionLabel = 'On the current rate this window runs out before it resets.',\n className,\n ...props\n}: Omit, 'children'> & {\n limit: number\n remaining: number\n resetAt?: Date\n /** Length of the window. Enables the burn-rate projection. */\n windowSeconds?: number\n now?: Date\n label?: ReactNode\n remainingLabel?: ReactNode\n resetsLabel?: ReactNode\n exhaustedLabel?: ReactNode\n /** Warning when the projection says the quota will not last. */\n projectionLabel?: ReactNode\n}) {\n const reference = now ?? new Date()\n const used = Math.max(0, limit - remaining)\n const share = limit > 0 ? remaining / limit : 0\n const exhausted = remaining <= 0\n\n // Elapsed share of the window, from the reset time and the window length.\n const secondsLeft = resetAt ? (resetAt.getTime() - reference.getTime()) / 1000 : undefined\n const elapsedShare =\n windowSeconds && secondsLeft !== undefined\n ? Math.min(1, Math.max(0.0001, (windowSeconds - secondsLeft) / windowSeconds))\n : undefined\n\n // Will the quota outlast the window at the current rate?\n const willExhaust =\n elapsedShare !== undefined && !exhausted && used / elapsedShare > limit\n\n const tone = exhausted\n ? 'var(--destructive)'\n : share < 0.15 || willExhaust\n ? 'var(--amber)'\n : 'var(--green)'\n\n return (\n \n
\n {label}\n {/* Reset is as prominent as the count — it is what makes a scary\n number harmless. */}\n {resetAt && (\n \n {resetsLabel} \n \n )}\n
\n\n

\n \n \n \n \n / {remainingLabel}\n \n

\n\n \n \n {/* Where the window itself has got to, for comparison against spend. */}\n {elapsedShare !== undefined && (\n \n )}\n \n\n {exhausted ? (\n

{exhaustedLabel}

\n ) : willExhaust ? (\n

{projectionLabel}

\n ) : null}\n \n )\n}\n\nexport { RateLimitMeter }\n" } ] }