@http-client-toolkit/store-sqlite 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +15 -0
- package/README.md +93 -0
- package/lib/index.cjs +1311 -0
- package/lib/index.cjs.map +1 -0
- package/lib/index.d.cts +537 -0
- package/lib/index.d.ts +537 -0
- package/lib/index.js +1299 -0
- package/lib/index.js.map +1 -0
- package/package.json +79 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/schema.ts","../src/sqlite-cache-store.ts","../src/sqlite-dedupe-store.ts","../src/sqlite-rate-limit-store.ts","../src/sqlite-adaptive-rate-limit-store.ts"],"names":["sqliteTable","text","blob","integer","Database","drizzle","eq","count","and","gt","lt","sql","randomUUID","DEFAULT_RATE_LIMIT","gte","AdaptiveCapacityCalculator"],"mappings":"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","file":"index.cjs","sourcesContent":["import { sqliteTable, text, integer, blob } from 'drizzle-orm/sqlite-core';\n\n// Cache table for storing cached API responses\nexport const cacheTable = sqliteTable('cache', {\n hash: text('hash').primaryKey(),\n value: blob('value', { mode: 'json' }).notNull(),\n expiresAt: integer('expires_at').notNull(),\n createdAt: integer('created_at').notNull(),\n});\n\n// Dedupe table for tracking in-progress requests\nexport const dedupeTable = sqliteTable('dedupe_jobs', {\n hash: text('hash').primaryKey(),\n jobId: text('job_id').notNull(),\n status: text('status').notNull(), // 'pending', 'completed', 'failed'\n result: blob('result', { mode: 'json' }),\n error: text('error'),\n createdAt: integer('created_at').notNull(),\n updatedAt: integer('updated_at').notNull(),\n});\n\n// Rate limit table for tracking API request limits\nexport const rateLimitTable = sqliteTable('rate_limits', {\n resource: text('resource').notNull(),\n timestamp: integer('timestamp').notNull(),\n id: integer('id').primaryKey({ autoIncrement: true }),\n});\n\nexport type CacheRow = typeof cacheTable.$inferSelect;\nexport type DedupeRow = typeof dedupeTable.$inferSelect;\nexport type RateLimitRow = typeof rateLimitTable.$inferSelect;\n","import type { CacheStore } from '@http-client-toolkit/core';\nimport Database from 'better-sqlite3';\nimport { and, eq, gt, lt, count, sql } from 'drizzle-orm';\nimport { drizzle, BetterSQLite3Database } from 'drizzle-orm/better-sqlite3';\nimport { cacheTable } from './schema.js';\n\nexport interface SQLiteCacheStoreOptions {\n /** File path or existing `better-sqlite3` connection. Defaults to `':memory:'`. */\n database?: string | InstanceType<typeof Database>;\n cleanupIntervalMs?: number;\n maxEntrySizeBytes?: number;\n}\n\nexport class SQLiteCacheStore<T = unknown> implements CacheStore<T> {\n private db: BetterSQLite3Database;\n private sqlite: InstanceType<typeof Database>;\n /** Indicates whether this store is responsible for managing (and therefore closing) the SQLite connection */\n private readonly isConnectionManaged: boolean = false;\n private cleanupInterval?: NodeJS.Timeout;\n private readonly cleanupIntervalMs: number;\n /**\n * Maximum allowed size (in bytes) for a single cache entry. If the serialized\n * value exceeds this limit the entry will be **silently skipped** to avoid\n * breaching SQLite's max length limits which could otherwise throw at write\n * time. Defaults to `5 MiB`, which is well under SQLiteʼs compiled\n * `SQLITE_MAX_LENGTH` (usually 1 GiB) yet large enough for typical Comic Vine\n * responses.\n */\n private readonly maxEntrySizeBytes: number;\n private isDestroyed = false;\n\n constructor({\n /** File path or existing `better-sqlite3` connection. Defaults to `':memory:'`. */\n database = ':memory:',\n /** Cleanup interval in milliseconds. Defaults to 1 minute. */\n cleanupIntervalMs = 60_000,\n /** Maximum allowed size (in bytes) for a single cache entry. Defaults to 5 MiB. */\n maxEntrySizeBytes = 5 * 1024 * 1024,\n }: SQLiteCacheStoreOptions = {}) {\n // Support passing an existing `better-sqlite3` Database instance so that\n // multiple stores can share the *same* file and connection. If a string\n // path is provided we create the connection ourselves and therefore take\n // ownership of it for later cleanup.\n let sqliteInstance: InstanceType<typeof Database>;\n let isConnectionManaged = false;\n\n if (typeof database === 'string') {\n sqliteInstance = new Database(database);\n isConnectionManaged = true;\n } else {\n sqliteInstance = database;\n }\n\n this.sqlite = sqliteInstance;\n this.isConnectionManaged = isConnectionManaged;\n this.db = drizzle(sqliteInstance);\n this.cleanupIntervalMs = cleanupIntervalMs;\n this.maxEntrySizeBytes = maxEntrySizeBytes;\n\n this.initializeDatabase();\n this.startCleanupInterval();\n }\n\n async get(hash: string): Promise<T | undefined> {\n if (this.isDestroyed) {\n throw new Error('Cache store has been destroyed');\n }\n\n const result = await this.db\n .select()\n .from(cacheTable)\n .where(eq(cacheTable.hash, hash))\n .limit(1);\n\n if (result.length === 0) {\n return undefined;\n }\n\n const item = result[0];\n if (!item) {\n return undefined;\n }\n\n const now = Date.now();\n\n if (item.expiresAt > 0 && now >= item.expiresAt) {\n await this.db.delete(cacheTable).where(eq(cacheTable.hash, hash));\n return undefined;\n }\n\n try {\n if (item.value === '__UNDEFINED__') {\n return undefined;\n }\n return JSON.parse(item.value as string);\n } catch {\n // If deserialization fails, remove the corrupted item\n await this.db.delete(cacheTable).where(eq(cacheTable.hash, hash));\n return undefined;\n }\n }\n\n async set(hash: string, value: T, ttlSeconds: number): Promise<void> {\n if (this.isDestroyed) {\n throw new Error('Cache store has been destroyed');\n }\n\n const now = Date.now();\n const expiresAt =\n ttlSeconds < 0 ? now : ttlSeconds === 0 ? 0 : now + ttlSeconds * 1000;\n\n let serializedValue: string;\n try {\n if (value === undefined) {\n serializedValue = '__UNDEFINED__';\n } else {\n serializedValue = JSON.stringify(value);\n }\n } catch (error) {\n throw new Error(\n `Failed to serialize value: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n\n // SIZE GUARD: Skip caching if the value is too large to avoid hitting\n // SQLite length limits. We **silently** skip because callers shouldn't be\n // penalised for large responses — they will simply be fetched again next\n // time.\n if (Buffer.byteLength(serializedValue, 'utf8') > this.maxEntrySizeBytes) {\n return;\n }\n\n await this.db\n .insert(cacheTable)\n .values({\n hash,\n value: serializedValue,\n expiresAt,\n createdAt: now,\n })\n .onConflictDoUpdate({\n target: cacheTable.hash,\n set: {\n value: serializedValue,\n expiresAt,\n createdAt: now,\n },\n });\n }\n\n async delete(hash: string): Promise<void> {\n if (this.isDestroyed) {\n throw new Error('Cache store has been destroyed');\n }\n await this.db.delete(cacheTable).where(eq(cacheTable.hash, hash));\n }\n\n async clear(): Promise<void> {\n if (this.isDestroyed) {\n throw new Error('Cache store has been destroyed');\n }\n await this.db.delete(cacheTable);\n }\n\n /**\n * Get cache statistics\n */\n async getStats(): Promise<{\n totalItems: number;\n expiredItems: number;\n databaseSizeKB: number;\n }> {\n const now = Date.now();\n\n const totalResult = await this.db\n .select({ count: count() })\n .from(cacheTable);\n\n const expiredResult = await this.db\n .select({ count: count() })\n .from(cacheTable)\n .where(and(gt(cacheTable.expiresAt, 0), lt(cacheTable.expiresAt, now)));\n\n // Get database size (approximate)\n const pageCount = Number(\n this.sqlite.pragma('page_count', { simple: true }),\n );\n const pageSize = Number(this.sqlite.pragma('page_size', { simple: true }));\n\n // Fallback to 0 if parsing failed (NaN)\n const safePageCount = Number.isFinite(pageCount) ? pageCount : 0;\n const safePageSize = Number.isFinite(pageSize) ? pageSize : 0;\n const databaseSizeKB = Math.round((safePageCount * safePageSize) / 1024);\n\n return {\n databaseSizeKB,\n expiredItems: expiredResult[0]?.count ?? 0,\n totalItems: totalResult[0]?.count ?? 0,\n };\n }\n\n /**\n * Manually trigger cleanup of expired items\n */\n async cleanup(): Promise<void> {\n const now = Date.now();\n await this.db\n .delete(cacheTable)\n .where(and(gt(cacheTable.expiresAt, 0), lt(cacheTable.expiresAt, now)));\n }\n\n /**\n * Close the database connection\n */\n async close(): Promise<void> {\n if (this.cleanupInterval) {\n clearInterval(this.cleanupInterval);\n this.cleanupInterval = undefined;\n }\n\n this.isDestroyed = true;\n\n // Only close the underlying DB if **this** store manages it.\n if (this.isConnectionManaged && typeof this.sqlite.close === 'function') {\n this.sqlite.close();\n }\n }\n\n /**\n * Alias for close() to match test expectations\n */\n destroy(): void {\n this.close();\n }\n\n private initializeDatabase(): void {\n // Create table if it doesn't exist\n this.db.run(sql`\n CREATE TABLE IF NOT EXISTS cache (\n hash TEXT PRIMARY KEY,\n value BLOB NOT NULL,\n expires_at INTEGER NOT NULL,\n created_at INTEGER NOT NULL\n )\n `);\n\n // Create index on expires_at for efficient cleanup\n this.db.run(sql`\n CREATE INDEX IF NOT EXISTS idx_cache_expires_at ON cache(expires_at)\n `);\n }\n\n private startCleanupInterval(): void {\n if (this.cleanupIntervalMs <= 0) {\n return;\n }\n\n this.cleanupInterval = setInterval(async () => {\n await this.cleanup();\n }, this.cleanupIntervalMs);\n if (typeof this.cleanupInterval.unref === 'function') {\n this.cleanupInterval.unref();\n }\n }\n\n private async cleanupExpiredItems(): Promise<void> {\n const now = Date.now();\n await this.db.delete(cacheTable).where(lt(cacheTable.expiresAt, now));\n }\n}\n","import { randomUUID } from 'crypto';\nimport type { DedupeStore } from '@http-client-toolkit/core';\nimport Database from 'better-sqlite3';\nimport { eq, lt, count, sql, and } from 'drizzle-orm';\nimport { drizzle, BetterSQLite3Database } from 'drizzle-orm/better-sqlite3';\nimport { dedupeTable } from './schema.js';\n\nexport interface SQLiteDedupeStoreOptions {\n database?: string | InstanceType<typeof Database>;\n jobTimeoutMs?: number;\n timeoutMs?: number;\n cleanupIntervalMs?: number;\n pollIntervalMs?: number;\n}\n\nexport class SQLiteDedupeStore<T = unknown> implements DedupeStore<T> {\n private db: BetterSQLite3Database;\n private sqlite: InstanceType<typeof Database>;\n /** Indicates whether this store manages (and should close) the SQLite connection */\n private readonly isConnectionManaged: boolean = false;\n private jobPromises = new Map<string, Promise<T | undefined>>();\n private jobSettlers = new Map<string, (value: T | undefined) => void>();\n private readonly jobTimeoutMs: number;\n private readonly pollIntervalMs: number;\n private cleanupInterval?: NodeJS.Timeout;\n private readonly cleanupIntervalMs: number;\n private isDestroyed = false;\n\n constructor({\n /** File path or existing `better-sqlite3` Database instance. Defaults to `':memory:'`. */\n database = ':memory:',\n /** Job timeout in milliseconds. Preferred over timeoutMs. */\n jobTimeoutMs,\n /** Legacy alias for jobTimeoutMs. */\n timeoutMs,\n /** Cleanup interval in milliseconds. Defaults to 1 minute. */\n cleanupIntervalMs = 60_000,\n /** Poll interval for checking pending jobs in milliseconds. Defaults to 100ms. */\n pollIntervalMs = 100,\n }: SQLiteDedupeStoreOptions = {}) {\n // Support passing an existing `better-sqlite3` Database instance so that\n // multiple stores can share the *same* file and connection. If a string\n // path is provided we create the connection ourselves and therefore take\n // ownership of it for later cleanup.\n let sqliteInstance: InstanceType<typeof Database>;\n let isConnectionManaged = false;\n\n if (typeof database === 'string') {\n sqliteInstance = new Database(database);\n isConnectionManaged = true;\n } else {\n sqliteInstance = database;\n }\n\n this.sqlite = sqliteInstance;\n this.isConnectionManaged = isConnectionManaged;\n this.db = drizzle(sqliteInstance);\n this.jobTimeoutMs = timeoutMs ?? jobTimeoutMs ?? 300000;\n this.cleanupIntervalMs = cleanupIntervalMs;\n this.pollIntervalMs = pollIntervalMs;\n\n this.initializeDatabase();\n this.startCleanupInterval();\n }\n\n private startCleanupInterval(): void {\n if (this.cleanupIntervalMs > 0) {\n this.cleanupInterval = setInterval(() => {\n this.cleanupExpiredJobs().catch(() => {\n // Ignore cleanup errors\n });\n }, this.cleanupIntervalMs);\n if (typeof this.cleanupInterval.unref === 'function') {\n this.cleanupInterval.unref();\n }\n }\n }\n\n private async cleanupExpiredJobs(): Promise<void> {\n const noTimeoutConfigured = this.jobTimeoutMs <= 0;\n if (noTimeoutConfigured) {\n return;\n }\n\n const now = Date.now();\n const expiredThreshold = now - this.jobTimeoutMs;\n\n // Delete expired pending jobs\n await this.db\n .delete(dedupeTable)\n .where(\n and(\n eq(dedupeTable.status, 'pending'),\n lt(dedupeTable.createdAt, expiredThreshold),\n ),\n );\n }\n\n async waitFor(hash: string): Promise<T | undefined> {\n if (this.isDestroyed) {\n throw new Error('Dedupe store has been destroyed');\n }\n\n const existingPromise = this.jobPromises.get(hash);\n if (existingPromise) {\n return existingPromise;\n }\n\n let result: Array<typeof dedupeTable.$inferSelect>;\n try {\n result = await this.db\n .select()\n .from(dedupeTable)\n .where(eq(dedupeTable.hash, hash))\n .limit(1);\n } catch {\n return undefined;\n }\n\n if (result.length === 0) {\n return undefined;\n }\n\n const job = result[0];\n if (!job) {\n return undefined;\n }\n\n // If job is already completed, return result immediately\n if (job.status === 'completed') {\n return this.deserializeResult(job.result);\n }\n\n if (job.status === 'failed') {\n return undefined;\n }\n\n // Job is pending - create a promise that polls DB state so other processes\n // can observe completion/failure without in-memory resolver sharing.\n const promise = new Promise<T | undefined>((resolve) => {\n let settled = false;\n let timeoutHandle: NodeJS.Timeout | undefined;\n\n const settle = (value: T | undefined) => {\n if (settled) {\n return;\n }\n settled = true;\n\n if (timeoutHandle) {\n clearTimeout(timeoutHandle);\n }\n clearInterval(pollHandle);\n\n this.jobSettlers.delete(hash);\n this.jobPromises.delete(hash);\n resolve(value);\n };\n\n this.jobSettlers.set(hash, settle);\n\n const poll = async () => {\n if (this.isDestroyed) {\n settle(undefined);\n return;\n }\n\n try {\n const latest = await this.db\n .select()\n .from(dedupeTable)\n .where(eq(dedupeTable.hash, hash))\n .limit(1);\n\n const latestJob = latest[0];\n if (!latestJob) {\n settle(undefined);\n return;\n }\n\n const isExpired =\n this.jobTimeoutMs > 0 &&\n Date.now() - latestJob.createdAt >= this.jobTimeoutMs;\n\n if (isExpired) {\n await this.db\n .update(dedupeTable)\n .set({\n status: 'failed',\n error: 'Job timed out',\n updatedAt: Date.now(),\n })\n .where(eq(dedupeTable.hash, hash));\n settle(undefined);\n return;\n }\n\n if (latestJob.status === 'completed') {\n settle(this.deserializeResult(latestJob.result));\n return;\n }\n\n if (latestJob.status === 'failed') {\n settle(undefined);\n }\n } catch {\n settle(undefined);\n }\n };\n\n const pollHandle = setInterval(() => {\n void poll();\n }, this.pollIntervalMs);\n\n if (typeof pollHandle.unref === 'function') {\n pollHandle.unref();\n }\n\n void poll();\n\n if (this.jobTimeoutMs > 0) {\n timeoutHandle = setTimeout(() => {\n if (this.isDestroyed) {\n settle(undefined);\n return;\n }\n\n void (async () => {\n try {\n await this.db\n .update(dedupeTable)\n .set({\n status: 'failed',\n error: 'Job timed out',\n updatedAt: Date.now(),\n })\n .where(eq(dedupeTable.hash, hash));\n } catch {\n // Ignore DB errors on timeout settlement.\n } finally {\n settle(undefined);\n }\n })();\n }, this.jobTimeoutMs);\n\n if (typeof timeoutHandle.unref === 'function') {\n timeoutHandle.unref();\n }\n }\n });\n\n this.jobPromises.set(hash, promise);\n return promise;\n }\n\n async register(hash: string): Promise<string> {\n const registration = await this.registerOrJoin(hash);\n return registration.jobId;\n }\n\n async registerOrJoin(hash: string): Promise<{\n jobId: string;\n isOwner: boolean;\n }> {\n if (this.isDestroyed) {\n throw new Error('Dedupe store has been destroyed');\n }\n\n const now = Date.now();\n const candidateJobId = randomUUID();\n\n const registerTransaction = this.sqlite.transaction(\n (requestHash: string, createdAt: number, jobId: string) => {\n const existing = this.sqlite\n .prepare(\n 'SELECT job_id as jobId, status FROM dedupe_jobs WHERE hash = ? LIMIT 1',\n )\n .get(requestHash) as\n | {\n jobId: string;\n status: string;\n }\n | undefined;\n\n if (existing && existing.status === 'pending') {\n return {\n jobId: existing.jobId,\n isOwner: false,\n };\n }\n\n this.sqlite\n .prepare(\n `\n INSERT INTO dedupe_jobs (hash, job_id, status, result, error, created_at, updated_at)\n VALUES (?, ?, 'pending', NULL, NULL, ?, ?)\n ON CONFLICT(hash) DO UPDATE SET\n job_id = excluded.job_id,\n status = excluded.status,\n result = NULL,\n error = NULL,\n created_at = excluded.created_at,\n updated_at = excluded.updated_at\n `,\n )\n .run(requestHash, jobId, createdAt, createdAt);\n\n return {\n jobId,\n isOwner: true,\n };\n },\n );\n\n return registerTransaction(hash, now, candidateJobId);\n }\n\n async complete(hash: string, value: T | undefined): Promise<void> {\n if (this.isDestroyed) {\n throw new Error('Dedupe store has been destroyed');\n }\n\n // Handle different value types with proper serialization\n let serializedResult: string;\n if (value === undefined) {\n serializedResult = '__UNDEFINED__';\n } else if (value === null) {\n serializedResult = '__NULL__';\n } else {\n try {\n serializedResult = JSON.stringify(value);\n } catch (error) {\n throw new Error(\n `Failed to serialize result: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n\n const now = Date.now();\n\n // Check if job already completed (prevent double completion)\n const existingJob = await this.db\n .select()\n .from(dedupeTable)\n .where(eq(dedupeTable.hash, hash))\n .limit(1);\n\n if (existingJob.length > 0 && existingJob[0]?.status === 'completed') {\n // Job already completed, don't update again\n return;\n }\n\n await this.db\n .update(dedupeTable)\n .set({\n status: 'completed',\n result: serializedResult,\n updatedAt: now,\n })\n .where(eq(dedupeTable.hash, hash));\n\n // Resolve any waiting promises in this process immediately.\n const settle = this.jobSettlers.get(hash);\n if (settle) {\n settle(value);\n }\n }\n\n async fail(hash: string, error: Error): Promise<void> {\n if (this.isDestroyed) {\n throw new Error('Dedupe store has been destroyed');\n }\n\n const now = Date.now();\n\n await this.db\n .update(dedupeTable)\n .set({\n status: 'failed',\n error: error.message,\n updatedAt: now,\n })\n .where(eq(dedupeTable.hash, hash));\n\n // Resolve waiters to undefined on failure.\n const settle = this.jobSettlers.get(hash);\n if (settle) {\n settle(undefined);\n }\n }\n\n async isInProgress(hash: string): Promise<boolean> {\n if (this.isDestroyed) {\n throw new Error('Dedupe store has been destroyed');\n }\n\n const result = await this.db\n .select()\n .from(dedupeTable)\n .where(eq(dedupeTable.hash, hash))\n .limit(1);\n\n if (result.length === 0) {\n return false;\n }\n\n const job = result[0];\n if (!job) {\n return false;\n }\n\n const jobExpired =\n this.jobTimeoutMs > 0 && Date.now() - job.createdAt >= this.jobTimeoutMs;\n if (jobExpired) {\n await this.db.delete(dedupeTable).where(eq(dedupeTable.hash, hash));\n return false;\n }\n\n return job.status === 'pending';\n }\n\n async getResult(hash: string): Promise<T | undefined> {\n const result = await this.db\n .select()\n .from(dedupeTable)\n .where(eq(dedupeTable.hash, hash))\n .limit(1);\n\n if (result.length === 0) {\n return undefined;\n }\n\n const job = result[0];\n if (!job) {\n return undefined;\n }\n\n const now = Date.now();\n\n const isExpired = now - job.createdAt > this.jobTimeoutMs;\n if (isExpired) {\n await this.db.delete(dedupeTable).where(eq(dedupeTable.hash, hash));\n return undefined;\n }\n\n if (job.status === 'completed') {\n try {\n if (job.result === '__UNDEFINED__') {\n return undefined;\n } else if (job.result === '__NULL__') {\n return null as unknown as T;\n } else if (job.result) {\n return JSON.parse(job.result as string);\n }\n return undefined;\n } catch {\n return undefined;\n }\n }\n\n return undefined;\n }\n\n /**\n * Get statistics about dedupe jobs\n */\n async getStats(): Promise<{\n totalJobs: number;\n pendingJobs: number;\n completedJobs: number;\n failedJobs: number;\n expiredJobs: number;\n }> {\n const now = Date.now();\n const expiredTime = now - this.jobTimeoutMs;\n\n const totalResult = await this.db\n .select({ count: count() })\n .from(dedupeTable);\n\n const pendingResult = await this.db\n .select({ count: count() })\n .from(dedupeTable)\n .where(eq(dedupeTable.status, 'pending'));\n\n const completedResult = await this.db\n .select({ count: count() })\n .from(dedupeTable)\n .where(eq(dedupeTable.status, 'completed'));\n\n const failedResult = await this.db\n .select({ count: count() })\n .from(dedupeTable)\n .where(eq(dedupeTable.status, 'failed'));\n\n const expiredResult = await this.db\n .select({ count: count() })\n .from(dedupeTable)\n .where(lt(dedupeTable.createdAt, expiredTime));\n\n return {\n totalJobs: totalResult[0]?.count || 0,\n pendingJobs: pendingResult[0]?.count || 0,\n completedJobs: completedResult[0]?.count || 0,\n failedJobs: failedResult[0]?.count || 0,\n expiredJobs: expiredResult[0]?.count || 0,\n };\n }\n\n /**\n * Clean up expired jobs\n */\n async cleanup(): Promise<void> {\n const now = Date.now();\n const expiredTime = now - this.jobTimeoutMs;\n\n await this.db\n .delete(dedupeTable)\n .where(lt(dedupeTable.createdAt, expiredTime));\n }\n\n /**\n * Clear all jobs\n */\n async clear(): Promise<void> {\n await this.db.delete(dedupeTable);\n\n for (const settle of this.jobSettlers.values()) {\n settle(undefined);\n }\n\n this.jobPromises.clear();\n this.jobSettlers.clear();\n }\n\n /**\n * Close the database connection\n */\n async close(): Promise<void> {\n if (this.cleanupInterval) {\n clearInterval(this.cleanupInterval);\n this.cleanupInterval = undefined;\n }\n\n this.isDestroyed = true;\n\n for (const settle of this.jobSettlers.values()) {\n settle(undefined);\n }\n\n this.jobPromises.clear();\n this.jobSettlers.clear();\n\n // Only close the underlying DB if **this** store created it.\n if (this.isConnectionManaged && typeof this.sqlite.close === 'function') {\n this.sqlite.close();\n }\n }\n\n /**\n * Alias for close() to match test expectations\n */\n destroy(): void {\n this.close();\n }\n\n private deserializeResult(serializedResult: unknown): T | undefined {\n try {\n if (serializedResult === '__UNDEFINED__') {\n return undefined;\n }\n\n // Preserve explicit null payloads; callers may rely on null as a valid\n // response distinct from \"no result\" (undefined).\n if (serializedResult === '__NULL__') {\n return null as unknown as T;\n }\n\n if (serializedResult) {\n return JSON.parse(serializedResult as string);\n }\n\n return undefined;\n } catch {\n return undefined;\n }\n }\n\n private initializeDatabase(): void {\n // Create tables if they don't exist\n this.db.run(sql`\n CREATE TABLE IF NOT EXISTS dedupe_jobs (\n hash TEXT PRIMARY KEY,\n job_id TEXT NOT NULL,\n status TEXT NOT NULL,\n result BLOB,\n error TEXT,\n created_at INTEGER NOT NULL,\n updated_at INTEGER NOT NULL\n )\n `);\n\n // Create index on status for efficient queries\n this.db.run(sql`\n CREATE INDEX IF NOT EXISTS idx_dedupe_status ON dedupe_jobs(status)\n `);\n }\n}\n","import {\n type RateLimitConfig,\n type RateLimitStore,\n DEFAULT_RATE_LIMIT,\n} from '@http-client-toolkit/core';\nimport Database from 'better-sqlite3';\nimport { and, eq, gte, count, sql, lt } from 'drizzle-orm';\nimport { drizzle, BetterSQLite3Database } from 'drizzle-orm/better-sqlite3';\nimport { rateLimitTable } from './schema.js';\n\nexport interface SQLiteRateLimitStoreOptions {\n /** File path or existing `better-sqlite3` Database instance. Defaults to `':memory:'`. */\n database?: string | InstanceType<typeof Database>;\n /** Global/default rate-limit config applied when a resource-specific override is not provided. */\n defaultConfig?: RateLimitConfig;\n /** Optional per-resource overrides. */\n resourceConfigs?: Map<string, RateLimitConfig>;\n}\n\nexport class SQLiteRateLimitStore implements RateLimitStore {\n private db: BetterSQLite3Database;\n private sqlite: InstanceType<typeof Database>;\n /** Indicates whether this store manages (and should close) the SQLite connection */\n private readonly isConnectionManaged: boolean = false;\n private defaultConfig: RateLimitConfig;\n private resourceConfigs = new Map<string, RateLimitConfig>();\n private isDestroyed = false;\n\n constructor({\n /** File path or existing `better-sqlite3` Database instance. Defaults to `':memory:'`. */\n database = ':memory:',\n /** Global/default rate-limit config applied when a resource-specific override is not provided. */\n defaultConfig = DEFAULT_RATE_LIMIT,\n /** Optional per-resource overrides. */\n resourceConfigs = new Map<string, RateLimitConfig>(),\n }: SQLiteRateLimitStoreOptions = {}) {\n // Allow callers to pass a pre-existing connection so that all stores can\n // operate on the same underlying DB file.\n let sqliteInstance: InstanceType<typeof Database>;\n let isConnectionManaged = false;\n\n if (typeof database === 'string') {\n sqliteInstance = new Database(database);\n isConnectionManaged = true;\n } else {\n sqliteInstance = database;\n }\n\n this.sqlite = sqliteInstance;\n this.isConnectionManaged = isConnectionManaged;\n this.db = drizzle(sqliteInstance);\n this.defaultConfig = defaultConfig;\n this.resourceConfigs = resourceConfigs;\n\n this.initializeDatabase();\n }\n\n async canProceed(resource: string): Promise<boolean> {\n if (this.isDestroyed) {\n throw new Error('Rate limit store has been destroyed');\n }\n\n const config = this.resourceConfigs.get(resource) || this.defaultConfig;\n const now = Date.now();\n const windowStart = now - config.windowMs;\n\n await this.cleanupExpiredRequests(resource, windowStart);\n\n // Count current requests in window\n const result = await this.db\n .select({ count: count() })\n .from(rateLimitTable)\n .where(\n and(\n eq(rateLimitTable.resource, resource),\n gte(rateLimitTable.timestamp, windowStart),\n ),\n );\n\n const currentCount = (result[0] as { count?: number })?.count || 0;\n return currentCount < config.limit;\n }\n\n async record(resource: string): Promise<void> {\n if (this.isDestroyed) {\n throw new Error('Rate limit store has been destroyed');\n }\n\n const now = Date.now();\n await this.db.insert(rateLimitTable).values({\n resource,\n timestamp: now,\n });\n }\n\n async getStatus(resource: string): Promise<{\n remaining: number;\n resetTime: Date;\n limit: number;\n }> {\n if (this.isDestroyed) {\n throw new Error('Rate limit store has been destroyed');\n }\n\n const config = this.resourceConfigs.get(resource) || this.defaultConfig;\n const now = Date.now();\n const windowStart = now - config.windowMs;\n\n await this.cleanupExpiredRequests(resource, windowStart);\n\n // Count current requests in the window\n const result = await this.db\n .select({ count: count() })\n .from(rateLimitTable)\n .where(\n and(\n eq(rateLimitTable.resource, resource),\n gte(rateLimitTable.timestamp, windowStart),\n ),\n );\n\n const currentRequests = (result[0]?.count as number) || 0;\n const remaining = Math.max(0, config.limit - currentRequests);\n\n const resetTime = new Date(now + config.windowMs);\n\n return {\n remaining,\n resetTime,\n limit: config.limit,\n };\n }\n\n async reset(resource: string): Promise<void> {\n if (this.isDestroyed) {\n throw new Error('Rate limit store has been destroyed');\n }\n await this.db\n .delete(rateLimitTable)\n .where(eq(rateLimitTable.resource, resource));\n }\n\n async getWaitTime(resource: string): Promise<number> {\n if (this.isDestroyed) {\n throw new Error('Rate limit store has been destroyed');\n }\n\n const config = this.resourceConfigs.get(resource) || this.defaultConfig;\n\n if (config.limit === 0) {\n return config.windowMs;\n }\n\n const now = Date.now();\n const windowStart = now - config.windowMs;\n\n await this.cleanupExpiredRequests(resource, windowStart);\n\n // Count current requests in the window\n const countResult = await this.db\n .select({ count: count() })\n .from(rateLimitTable)\n .where(\n and(\n eq(rateLimitTable.resource, resource),\n gte(rateLimitTable.timestamp, windowStart),\n ),\n );\n\n const currentRequests = (countResult[0]?.count as number) || 0;\n\n if (currentRequests < config.limit) {\n return 0;\n }\n\n const oldestResult = await this.db\n .select({ timestamp: rateLimitTable.timestamp })\n .from(rateLimitTable)\n .where(\n and(\n eq(rateLimitTable.resource, resource),\n gte(rateLimitTable.timestamp, windowStart),\n ),\n )\n .orderBy(rateLimitTable.timestamp)\n .limit(1);\n\n if (oldestResult.length === 0) {\n return 0;\n }\n\n const oldestTimestamp = oldestResult[0]?.timestamp;\n if (oldestTimestamp === undefined) {\n return 0;\n }\n\n const timeUntilOldestExpires = oldestTimestamp + config.windowMs - now;\n\n return Math.max(0, timeUntilOldestExpires);\n }\n\n /**\n * Set rate limit configuration for a specific resource\n */\n setResourceConfig(resource: string, config: RateLimitConfig): void {\n this.resourceConfigs.set(resource, config);\n }\n\n /**\n * Get rate limit configuration for a resource\n */\n getResourceConfig(resource: string): RateLimitConfig {\n return this.resourceConfigs.get(resource) || this.defaultConfig;\n }\n\n /**\n * Get statistics for all resources\n */\n async getStats(): Promise<{\n totalRequests: number;\n uniqueResources: number;\n rateLimitedResources: Array<string>;\n }> {\n if (this.isDestroyed) {\n throw new Error('Rate limit store has been destroyed');\n }\n\n const totalResult = await this.db\n .select({ count: count() })\n .from(rateLimitTable);\n\n const resourcesResult = await this.db\n .select({ resource: rateLimitTable.resource })\n .from(rateLimitTable)\n .groupBy(rateLimitTable.resource);\n\n const uniqueResources = resourcesResult.length;\n const rateLimitedResources: Array<string> = [];\n\n for (const { resource } of resourcesResult) {\n const canProceed = await this.canProceed(resource);\n if (!canProceed) {\n rateLimitedResources.push(resource);\n }\n }\n\n return {\n totalRequests: (totalResult[0]?.count as number) || 0,\n uniqueResources,\n rateLimitedResources,\n };\n }\n\n /**\n * Clean up all rate limit data\n */\n async clear(): Promise<void> {\n if (this.isDestroyed) {\n throw new Error('Rate limit store has been destroyed');\n }\n await this.db.delete(rateLimitTable);\n }\n\n /**\n * Clean up expired requests for all resources\n */\n async cleanup(): Promise<void> {\n const now = Date.now();\n\n // Find all unique resources\n const resources = await this.db\n .select({ resource: rateLimitTable.resource })\n .from(rateLimitTable)\n .groupBy(rateLimitTable.resource);\n\n for (const { resource } of resources) {\n const config = this.resourceConfigs.get(resource) || this.defaultConfig;\n const windowStart = now - config.windowMs;\n await this.cleanupExpiredRequests(resource, windowStart);\n }\n }\n\n /**\n * Close the database connection\n */\n async close(): Promise<void> {\n this.isDestroyed = true;\n\n // Close only if this instance established the connection.\n if (this.isConnectionManaged && typeof this.sqlite.close === 'function') {\n this.sqlite.close();\n }\n }\n\n /**\n * Alias for close() to match test expectations\n */\n destroy(): void {\n this.close();\n }\n\n private async cleanupExpiredRequests(\n resource: string,\n windowStart: number,\n ): Promise<void> {\n await this.db\n .delete(rateLimitTable)\n .where(\n and(\n eq(rateLimitTable.resource, resource),\n lt(rateLimitTable.timestamp, windowStart),\n ),\n );\n }\n\n private initializeDatabase(): void {\n // Create tables if they don't exist\n this.db.run(sql`\n CREATE TABLE IF NOT EXISTS rate_limits (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n resource TEXT NOT NULL,\n timestamp INTEGER NOT NULL\n )\n `);\n\n // Create index on resource for efficient lookups\n this.db.run(sql`\n CREATE INDEX IF NOT EXISTS idx_rate_limit_resource ON rate_limits(resource)\n `);\n\n // Create index on timestamp for efficient cleanup\n this.db.run(sql`\n CREATE INDEX IF NOT EXISTS idx_rate_limit_timestamp ON rate_limits(timestamp)\n `);\n }\n}\n","import {\n AdaptiveCapacityCalculator,\n type AdaptiveRateLimitStore as IAdaptiveRateLimitStore,\n type RequestPriority,\n type AdaptiveConfigSchema,\n type RateLimitConfig,\n type ActivityMetrics,\n type DynamicCapacityResult,\n} from '@http-client-toolkit/core';\nimport Database from 'better-sqlite3';\nimport { and, eq, count, sql, lt } from 'drizzle-orm';\nimport { drizzle, BetterSQLite3Database } from 'drizzle-orm/better-sqlite3';\nimport { z } from 'zod';\nimport { rateLimitTable } from './schema.js';\n\nconst DEFAULT_RATE_LIMIT: RateLimitConfig = {\n limit: 200,\n windowMs: 3600000, // 1 hour\n};\n\nexport interface SqliteAdaptiveRateLimitStoreOptions {\n /** File path or existing `better-sqlite3` Database instance. Defaults to `':memory:'`. */\n database?: string | InstanceType<typeof Database>;\n /** Global/default rate-limit config applied when a resource-specific override is not provided. */\n defaultConfig?: RateLimitConfig;\n /** Optional per-resource overrides. */\n resourceConfigs?: Map<string, RateLimitConfig>;\n /** Adaptive configuration for priority-based rate limiting */\n adaptiveConfig?: Partial<z.input<typeof AdaptiveConfigSchema>>;\n}\n\nexport class SqliteAdaptiveRateLimitStore implements IAdaptiveRateLimitStore {\n private db: BetterSQLite3Database;\n private sqlite: InstanceType<typeof Database>;\n /** Indicates whether this store manages (and should close) the SQLite connection */\n private readonly isConnectionManaged: boolean = false;\n private defaultConfig: RateLimitConfig;\n private resourceConfigs = new Map<string, RateLimitConfig>();\n private isDestroyed = false;\n\n // Adaptive rate limiting components\n private capacityCalculator: AdaptiveCapacityCalculator;\n private activityMetrics = new Map<string, ActivityMetrics>();\n private lastCapacityUpdate = new Map<string, number>();\n private cachedCapacity = new Map<string, DynamicCapacityResult>();\n\n constructor({\n database = ':memory:',\n defaultConfig = DEFAULT_RATE_LIMIT,\n resourceConfigs = new Map<string, RateLimitConfig>(),\n adaptiveConfig = {},\n }: SqliteAdaptiveRateLimitStoreOptions = {}) {\n // Allow callers to pass a pre-existing connection so that all stores can\n // operate on the same underlying DB file.\n let sqliteInstance: InstanceType<typeof Database>;\n let isConnectionManaged = false;\n\n if (typeof database === 'string') {\n sqliteInstance = new Database(database);\n isConnectionManaged = true;\n } else {\n sqliteInstance = database;\n }\n\n this.sqlite = sqliteInstance;\n this.isConnectionManaged = isConnectionManaged;\n this.db = drizzle(sqliteInstance);\n this.defaultConfig = defaultConfig;\n this.resourceConfigs = resourceConfigs;\n\n // Initialize adaptive components\n this.capacityCalculator = new AdaptiveCapacityCalculator(adaptiveConfig);\n\n this.initializeDatabase();\n }\n\n async canProceed(\n resource: string,\n priority: RequestPriority = 'background',\n ): Promise<boolean> {\n if (this.isDestroyed) {\n throw new Error('Rate limit store has been destroyed');\n }\n\n // Load activity metrics if needed\n await this.ensureActivityMetrics(resource);\n const metrics = this.getOrCreateActivityMetrics(resource);\n const capacity = this.calculateCurrentCapacity(resource, metrics);\n\n // Check if background requests should be paused\n if (priority === 'background' && capacity.backgroundPaused) {\n return false; // Hard pause for background requests\n }\n\n // Get current usage for each priority\n const currentUserRequests = await this.getCurrentUsage(resource, 'user');\n const currentBackgroundRequests = await this.getCurrentUsage(\n resource,\n 'background',\n );\n\n if (priority === 'user') {\n return currentUserRequests < capacity.userReserved;\n } else {\n return currentBackgroundRequests < capacity.backgroundMax;\n }\n }\n\n async record(\n resource: string,\n priority: RequestPriority = 'background',\n ): Promise<void> {\n if (this.isDestroyed) {\n throw new Error('Rate limit store has been destroyed');\n }\n\n const now = Date.now();\n\n // Insert into database with priority using raw SQL to handle the additional column\n this.db.run(sql`\n INSERT INTO rate_limits (resource, timestamp, priority)\n VALUES (${resource}, ${now}, ${priority})\n `);\n\n // Update in-memory activity metrics\n const metrics = this.getOrCreateActivityMetrics(resource);\n\n if (priority === 'user') {\n metrics.recentUserRequests.push(now);\n this.cleanupOldRequests(metrics.recentUserRequests);\n } else {\n metrics.recentBackgroundRequests.push(now);\n this.cleanupOldRequests(metrics.recentBackgroundRequests);\n }\n\n // Update activity trend\n metrics.userActivityTrend = this.capacityCalculator.calculateActivityTrend(\n metrics.recentUserRequests,\n );\n }\n\n async getStatus(resource: string): Promise<{\n remaining: number;\n resetTime: Date;\n limit: number;\n adaptive?: {\n userReserved: number;\n backgroundMax: number;\n backgroundPaused: boolean;\n recentUserActivity: number;\n reason: string;\n };\n }> {\n if (this.isDestroyed) {\n throw new Error('Rate limit store has been destroyed');\n }\n\n await this.ensureActivityMetrics(resource);\n const metrics = this.getOrCreateActivityMetrics(resource);\n const capacity = this.calculateCurrentCapacity(resource, metrics);\n\n const currentUserUsage = await this.getCurrentUsage(resource, 'user');\n const currentBackgroundUsage = await this.getCurrentUsage(\n resource,\n 'background',\n );\n\n const config = this.resourceConfigs.get(resource) || this.defaultConfig;\n\n return {\n remaining:\n capacity.userReserved -\n currentUserUsage +\n (capacity.backgroundMax - currentBackgroundUsage),\n resetTime: new Date(Date.now() + config.windowMs),\n limit: this.getResourceLimit(resource),\n adaptive: {\n userReserved: capacity.userReserved,\n backgroundMax: capacity.backgroundMax,\n backgroundPaused: capacity.backgroundPaused,\n recentUserActivity: this.capacityCalculator.getRecentActivity(\n metrics.recentUserRequests,\n ),\n reason: capacity.reason,\n },\n };\n }\n\n async reset(resource: string): Promise<void> {\n if (this.isDestroyed) {\n throw new Error('Rate limit store has been destroyed');\n }\n\n // Clear database records\n await this.db\n .delete(rateLimitTable)\n .where(eq(rateLimitTable.resource, resource));\n\n // Clear in-memory metrics\n this.activityMetrics.delete(resource);\n this.cachedCapacity.delete(resource);\n this.lastCapacityUpdate.delete(resource);\n }\n\n async getWaitTime(\n resource: string,\n priority: RequestPriority = 'background',\n ): Promise<number> {\n if (this.isDestroyed) {\n throw new Error('Rate limit store has been destroyed');\n }\n\n const config = this.resourceConfigs.get(resource) || this.defaultConfig;\n\n if (config.limit === 0) {\n return config.windowMs;\n }\n\n const canProceed = await this.canProceed(resource, priority);\n if (canProceed) {\n return 0;\n }\n\n // For background requests that are paused, check back in 30 seconds\n await this.ensureActivityMetrics(resource);\n const metrics = this.getOrCreateActivityMetrics(resource);\n const capacity = this.calculateCurrentCapacity(resource, metrics);\n\n if (priority === 'background' && capacity.backgroundPaused) {\n return this.capacityCalculator.config.recalculationIntervalMs;\n }\n\n // Find the oldest request in the current window for this priority\n const now = Date.now();\n const windowStart = now - config.windowMs;\n\n const oldestResult = this.sqlite\n .prepare(\n `\n SELECT timestamp\n FROM rate_limits\n WHERE resource = ? AND COALESCE(priority, 'background') = ? AND timestamp >= ?\n ORDER BY timestamp\n LIMIT 1\n `,\n )\n .get(resource, priority, windowStart) as\n | { timestamp: number }\n | undefined;\n\n if (!oldestResult) {\n return 0;\n }\n\n const oldestTimestamp = oldestResult.timestamp;\n if (!oldestTimestamp) {\n return 0;\n }\n\n const timeUntilOldestExpires = oldestTimestamp + config.windowMs - now;\n return Math.max(0, timeUntilOldestExpires);\n }\n\n /**\n * Set rate limit configuration for a specific resource\n */\n setResourceConfig(resource: string, config: RateLimitConfig): void {\n this.resourceConfigs.set(resource, config);\n }\n\n /**\n * Get rate limit configuration for a resource\n */\n getResourceConfig(resource: string): RateLimitConfig {\n return this.resourceConfigs.get(resource) || this.defaultConfig;\n }\n\n /**\n * Get statistics for all resources\n */\n async getStats(): Promise<{\n totalRequests: number;\n uniqueResources: number;\n rateLimitedResources: Array<string>;\n }> {\n if (this.isDestroyed) {\n throw new Error('Rate limit store has been destroyed');\n }\n\n const totalResult = await this.db\n .select({ count: count() })\n .from(rateLimitTable);\n\n const resourcesResult = await this.db\n .select({ resource: rateLimitTable.resource })\n .from(rateLimitTable)\n .groupBy(rateLimitTable.resource);\n\n const uniqueResources = resourcesResult.length;\n const rateLimitedResources: Array<string> = [];\n\n for (const { resource } of resourcesResult) {\n const canProceed = await this.canProceed(resource);\n if (!canProceed) {\n rateLimitedResources.push(resource);\n }\n }\n\n return {\n totalRequests: (totalResult[0]?.count as number) || 0,\n uniqueResources,\n rateLimitedResources,\n };\n }\n\n /**\n * Clean up all rate limit data\n */\n async clear(): Promise<void> {\n if (this.isDestroyed) {\n throw new Error('Rate limit store has been destroyed');\n }\n await this.db.delete(rateLimitTable);\n this.activityMetrics.clear();\n this.cachedCapacity.clear();\n this.lastCapacityUpdate.clear();\n }\n\n /**\n * Clean up expired requests for all resources\n */\n async cleanup(): Promise<void> {\n const now = Date.now();\n\n // Find all unique resources\n const resources = await this.db\n .select({ resource: rateLimitTable.resource })\n .from(rateLimitTable)\n .groupBy(rateLimitTable.resource);\n\n for (const { resource } of resources) {\n const config = this.resourceConfigs.get(resource) || this.defaultConfig;\n const windowStart = now - config.windowMs;\n await this.cleanupExpiredRequests(resource, windowStart);\n }\n }\n\n /**\n * Close the database connection\n */\n async close(): Promise<void> {\n this.isDestroyed = true;\n\n // Close only if this instance established the connection.\n if (this.isConnectionManaged && typeof this.sqlite.close === 'function') {\n this.sqlite.close();\n }\n }\n\n /**\n * Alias for close() to match test expectations\n */\n destroy(): void {\n this.close();\n }\n\n // Private helper methods for adaptive functionality\n\n private calculateCurrentCapacity(\n resource: string,\n metrics: ActivityMetrics,\n ): DynamicCapacityResult {\n // Only recalculate based on configured interval to avoid thrashing\n const lastUpdate = this.lastCapacityUpdate.get(resource) || 0;\n const recalcInterval =\n this.capacityCalculator.config.recalculationIntervalMs;\n\n if (Date.now() - lastUpdate < recalcInterval) {\n return (\n this.cachedCapacity.get(resource) || this.getDefaultCapacity(resource)\n );\n }\n\n const totalLimit = this.getResourceLimit(resource);\n const capacity = this.capacityCalculator.calculateDynamicCapacity(\n resource,\n totalLimit,\n metrics,\n );\n\n this.cachedCapacity.set(resource, capacity);\n this.lastCapacityUpdate.set(resource, Date.now());\n\n return capacity;\n }\n\n private getOrCreateActivityMetrics(resource: string): ActivityMetrics {\n if (!this.activityMetrics.has(resource)) {\n this.activityMetrics.set(resource, {\n recentUserRequests: [],\n recentBackgroundRequests: [],\n userActivityTrend: 'none',\n });\n }\n return this.activityMetrics.get(resource)!;\n }\n\n private async ensureActivityMetrics(resource: string): Promise<void> {\n if (this.activityMetrics.has(resource)) {\n return; // Already loaded\n }\n\n // Load recent activity from database to populate in-memory metrics\n const now = Date.now();\n const windowStart = now - this.capacityCalculator.config.monitoringWindowMs;\n\n const recentRequests = this.sqlite\n .prepare(\n `\n SELECT timestamp, COALESCE(priority, 'background') as priority\n FROM rate_limits\n WHERE resource = ? AND timestamp >= ?\n ORDER BY timestamp\n `,\n )\n .all(resource, windowStart) as Array<{\n timestamp: number;\n priority: string;\n }>;\n\n const metrics: ActivityMetrics = {\n recentUserRequests: [],\n recentBackgroundRequests: [],\n userActivityTrend: 'none',\n };\n\n for (const request of recentRequests) {\n if (request.priority === 'user') {\n metrics.recentUserRequests.push(request.timestamp);\n } else {\n metrics.recentBackgroundRequests.push(request.timestamp);\n }\n }\n\n // Calculate trend based on loaded data\n metrics.userActivityTrend = this.capacityCalculator.calculateActivityTrend(\n metrics.recentUserRequests,\n );\n\n this.activityMetrics.set(resource, metrics);\n }\n\n private async getCurrentUsage(\n resource: string,\n priority: RequestPriority,\n ): Promise<number> {\n const config = this.resourceConfigs.get(resource) || this.defaultConfig;\n const now = Date.now();\n const windowStart = now - config.windowMs;\n\n await this.cleanupExpiredRequests(resource, windowStart);\n\n // Count current requests in window for this priority using raw SQL\n const result = this.sqlite\n .prepare(\n `\n SELECT COUNT(*) as count\n FROM rate_limits\n WHERE resource = ? AND priority = ? AND timestamp >= ?\n `,\n )\n .get(resource, priority, windowStart) as { count: number };\n\n return result.count || 0;\n }\n\n private cleanupOldRequests(requests: Array<number>): void {\n const cutoff =\n Date.now() - this.capacityCalculator.config.monitoringWindowMs;\n while (requests.length > 0 && requests[0]! < cutoff) {\n requests.shift();\n }\n }\n\n private getResourceLimit(resource: string): number {\n const config = this.resourceConfigs.get(resource) || this.defaultConfig;\n return config.limit;\n }\n\n private getDefaultCapacity(resource: string): DynamicCapacityResult {\n const limit = this.getResourceLimit(resource);\n return {\n userReserved: Math.floor(limit * 0.3),\n backgroundMax: Math.floor(limit * 0.7),\n backgroundPaused: false,\n reason: 'Default capacity allocation',\n };\n }\n\n private async cleanupExpiredRequests(\n resource: string,\n windowStart: number,\n ): Promise<void> {\n await this.db\n .delete(rateLimitTable)\n .where(\n and(\n eq(rateLimitTable.resource, resource),\n lt(rateLimitTable.timestamp, windowStart),\n ),\n );\n }\n\n private initializeDatabase(): void {\n // Create tables if they don't exist\n this.db.run(sql`\n CREATE TABLE IF NOT EXISTS rate_limits (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n resource TEXT NOT NULL,\n timestamp INTEGER NOT NULL,\n priority TEXT NOT NULL DEFAULT 'background'\n )\n `);\n\n // Check if priority column exists, add it if not (for migration from older schema)\n try {\n this.db.run(sql`\n ALTER TABLE rate_limits ADD COLUMN priority TEXT DEFAULT 'background'\n `);\n } catch {\n // Column already exists, ignore error\n }\n\n // Create index on resource for efficient lookups\n this.db.run(sql`\n CREATE INDEX IF NOT EXISTS idx_rate_limit_resource ON rate_limits(resource)\n `);\n\n // Create index on timestamp for efficient cleanup\n this.db.run(sql`\n CREATE INDEX IF NOT EXISTS idx_rate_limit_timestamp ON rate_limits(timestamp)\n `);\n\n // Create composite index for priority-based queries\n this.db.run(sql`\n CREATE INDEX IF NOT EXISTS idx_rate_limit_resource_priority_timestamp\n ON rate_limits(resource, priority, timestamp)\n `);\n }\n}\n"]}
|