Drop expired buckets so the Map doesn't grow unbounded on a long-lived instance.
(now: number)
| 86 | |
| 87 | /** Drop expired buckets so the Map doesn't grow unbounded on a long-lived instance. */ |
| 88 | function sweepRateLimit(now: number): void { |
| 89 | if (rateLimitHits.size < 10_000) return |
| 90 | for (const [ip, entry] of rateLimitHits) { |
| 91 | if (now >= entry.resetAt) rateLimitHits.delete(ip) |
| 92 | } |
| 93 | } |
| 94 | |
| 95 | /** A structurally valid UI message: has a role and a parts array. */ |
| 96 | function isValidMessage(message: unknown): message is UIMessage { |