Restructure chat service, web routes, and add test suite
Split monolithic chat service into modular structure with Matrix client support, extract web server into per-resource route modules, introduce bootstrap/main-loop separation, and add comprehensive vitest coverage across services, repositories, and utilities. Adds project docs and CLAUDE.md agent instructions.
This commit is contained in:
1 parent
dfa0580859
commit
633bb0ec04
84 files changed
+19278
-3888
No files matched your search
@@ -2,17 +2,22 @@ import PQueue from 'p-queue';
|
||||
import type { Config } from '../config/index.js';
|
||||
import type { Logger } from './logger.js';
|
||||
|
||||
const DEFAULT_HOUR_WINDOW_MS = 3600000;
|
||||
|
||||
export class RateLimiter {
|
||||
private queue: PQueue;
|
||||
private lastMessageTime: number = 0;
|
||||
private messagesThisHour: number = 0;
|
||||
private hourStartTime: number = Date.now();
|
||||
private readonly hourWindowMs: number;
|
||||
|
||||
constructor(
|
||||
private config: Config,
|
||||
private logger: Logger
|
||||
private logger: Logger,
|
||||
hourWindowMs: number = DEFAULT_HOUR_WINDOW_MS,
|
||||
) {
|
||||
this.queue = new PQueue({ concurrency: 1 });
|
||||
this.hourWindowMs = hourWindowMs;
|
||||
}
|
||||
|
||||
async throttle<T>(fn: () => Promise<T>, shouldCount: (result: T) => boolean = () => true): Promise<T> {
|
||||
@@ -20,7 +25,7 @@ export class RateLimiter {
|
||||
const now = Date.now();
|
||||
|
||||
// Reset hourly counter if needed
|
||||
if (now - this.hourStartTime > 3600000) {
|
||||
if (now - this.hourStartTime > this.hourWindowMs) {
|
||||
this.messagesThisHour = 0;
|
||||
this.hourStartTime = now;
|
||||
this.logger.debug('Hourly rate limit counter reset');
|
||||
@@ -28,7 +33,7 @@ export class RateLimiter {
|
||||
|
||||
// Check hourly limit
|
||||
if (this.messagesThisHour >= this.config.rateLimit.maxMessagesPerHour) {
|
||||
const waitTime = 3600000 - (now - this.hourStartTime);
|
||||
const waitTime = this.hourWindowMs - (now - this.hourStartTime);
|
||||
this.logger.info(`Hourly limit reached, waiting ${Math.round(waitTime / 60000)} minutes`);
|
||||
await this.sleep(waitTime);
|
||||
this.messagesThisHour = 0;
|
||||
@@ -94,7 +99,7 @@ export class RateLimiter {
|
||||
}
|
||||
|
||||
// Calculate when the hourly counter resets
|
||||
const hourlyResetAt = this.hourStartTime + 3600000;
|
||||
const hourlyResetAt = this.hourStartTime + this.hourWindowMs;
|
||||
|
||||
// Check if hourly limit is reached
|
||||
const isHourlyLimitReached = this.messagesThisHour >= maxMessages;
|
||||
|
||||
Reference in new issue
Block a user