@http-client-toolkit/store-memory 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 +103 -0
- package/lib/index.cjs +761 -0
- package/lib/index.cjs.map +1 -0
- package/lib/index.d.cts +223 -0
- package/lib/index.d.ts +223 -0
- package/lib/index.js +752 -0
- package/lib/index.js.map +1 -0
- package/package.json +78 -0
package/lib/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/in-memory-cache-store.ts","../src/in-memory-dedupe-store.ts","../src/in-memory-rate-limit-store.ts","../src/adaptive-rate-limit-store.ts"],"names":["DEFAULT_RATE_LIMIT"],"mappings":"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","file":"index.js","sourcesContent":["import type { CacheStore } from '@http-client-toolkit/core';\n// We use fast-safe-stringify instead of JSON.stringify so that\n// 1) objects containing circular references don’t throw, and\n// 2) we get a deterministic string length for accurate memory-usage\n// calculations. A normal JSON.stringify would either error or\n// force us to fallback to a rough 1 KB estimate, under-reporting\n// large cyclic payloads.\nimport safeStringify from 'fast-safe-stringify';\n\ninterface CacheItem<T> {\n value: T;\n expiresAt: number;\n lastAccessed: number;\n size: number; // bytes occupied by this entry\n}\n\nexport interface InMemoryCacheStoreOptions {\n /** Cleanup interval in milliseconds. Set to 0 to disable automatic cleanup. Default: 60000 (1 minute) */\n cleanupIntervalMs?: number;\n /** Maximum number of items to store. When exceeded, least recently used items are evicted. Default: 1000 */\n maxItems?: number;\n /** Maximum memory usage in bytes (rough estimate). When exceeded, least recently used items are evicted. Default: 50MB */\n maxMemoryBytes?: number;\n /** When evicting items, remove this percentage of LRU items. Default: 0.1 (10%) */\n evictionRatio?: number;\n}\n\nexport class InMemoryCacheStore<T = unknown> implements CacheStore<T> {\n private cache = new Map<string, CacheItem<T>>();\n private cleanupInterval?: NodeJS.Timeout;\n private readonly maxItems: number;\n private readonly maxMemoryBytes: number;\n private readonly evictionRatio: number;\n private totalSize = 0; // running total of memory usage in bytes\n\n constructor(options: InMemoryCacheStoreOptions = {}) {\n const cleanupIntervalMs = options.cleanupIntervalMs ?? 60000; // 1 minute default\n this.maxItems = options.maxItems ?? 1000;\n this.maxMemoryBytes = options.maxMemoryBytes ?? 50 * 1024 * 1024; // 50MB default\n this.evictionRatio = options.evictionRatio ?? 0.1;\n\n if (cleanupIntervalMs > 0) {\n this.cleanupInterval = setInterval(() => {\n this.cleanup();\n }, cleanupIntervalMs);\n // Allow the Node.js process to exit naturally if this timer is the only event loop item\n if (typeof this.cleanupInterval.unref === 'function') {\n this.cleanupInterval.unref();\n }\n }\n }\n\n async get(hash: string): Promise<T | undefined> {\n const item = this.cache.get(hash);\n\n if (!item) {\n return undefined;\n }\n\n if (item.expiresAt > 0 && Date.now() > item.expiresAt) {\n this.totalSize -= item.size;\n this.cache.delete(hash);\n return undefined;\n }\n\n // Update last accessed time for LRU\n item.lastAccessed = Date.now();\n // Re-set the item to trigger map ordering update\n this.cache.set(hash, item);\n return item.value;\n }\n\n async set(hash: string, value: T, ttlSeconds: number): Promise<void> {\n const now = Date.now();\n const expiresAt = ttlSeconds === 0 ? 0 : now + ttlSeconds * 1000;\n\n // If replacing an existing entry, subtract its size first\n const existing = this.cache.get(hash);\n if (existing) {\n this.totalSize -= existing.size;\n }\n\n const entrySize = this.estimateEntrySize(hash, value);\n this.totalSize += entrySize;\n\n this.cache.set(hash, {\n value,\n expiresAt,\n lastAccessed: now,\n size: entrySize,\n });\n\n // Check if we need to evict items\n this.enforceMemoryLimits();\n }\n\n async delete(hash: string): Promise<void> {\n const existing = this.cache.get(hash);\n if (existing) {\n this.totalSize -= existing.size;\n }\n this.cache.delete(hash);\n }\n\n async clear(): Promise<void> {\n this.cache.clear();\n this.totalSize = 0;\n }\n\n /**\n * Get statistics about cache usage\n */\n getStats(): {\n totalItems: number;\n expired: number;\n memoryUsageBytes: number;\n maxItems: number;\n maxMemoryBytes: number;\n memoryUtilization: number;\n itemUtilization: number;\n } {\n const now = Date.now();\n let expired = 0;\n\n for (const [_hash, item] of this.cache) {\n if (item.expiresAt > 0 && now > item.expiresAt) {\n expired++;\n }\n }\n\n // Rough estimate of memory usage\n const memoryUsageBytes = this.calculateMemoryUsage();\n\n return {\n totalItems: this.cache.size,\n expired,\n memoryUsageBytes,\n maxItems: this.maxItems,\n maxMemoryBytes: this.maxMemoryBytes,\n memoryUtilization: memoryUsageBytes / this.maxMemoryBytes,\n itemUtilization: this.cache.size / this.maxItems,\n };\n }\n\n /**\n * Clean up expired cache entries\n */\n cleanup(): void {\n const now = Date.now();\n const toDelete: Array<string> = [];\n\n for (const [hash, item] of this.cache) {\n if (item.expiresAt > 0 && now > item.expiresAt) {\n toDelete.push(hash);\n }\n }\n\n for (const hash of toDelete) {\n const item = this.cache.get(hash);\n if (item) {\n this.totalSize -= item.size;\n }\n this.cache.delete(hash);\n }\n }\n\n /**\n * Enforce memory and item count limits using LRU eviction\n */\n private enforceMemoryLimits(): void {\n // Check item count limit\n if (this.cache.size > this.maxItems) {\n this.evictLRUItems(this.cache.size - this.maxItems);\n return;\n }\n\n // Check memory usage limit\n const memoryUsage = this.totalSize;\n if (memoryUsage > this.maxMemoryBytes) {\n const itemsToEvict = Math.max(\n 1,\n Math.floor(this.cache.size * this.evictionRatio),\n );\n this.evictLRUItems(itemsToEvict);\n }\n }\n\n /**\n * Evict the least recently used items\n */\n private evictLRUItems(count: number): void {\n // Sort entries by last accessed time (oldest first)\n const entries = Array.from(this.cache.entries()).sort(\n ([, a], [, b]) => a.lastAccessed - b.lastAccessed,\n );\n\n // Remove the oldest entries\n for (let i = 0; i < count && i < entries.length; i++) {\n const entry = entries[i];\n if (entry) {\n const [key, item] = entry;\n this.totalSize -= item.size;\n this.cache.delete(key);\n }\n }\n }\n\n /**\n * Calculate rough memory usage\n */\n private calculateMemoryUsage(): number {\n // O(1) – maintained incrementally\n return this.totalSize;\n }\n\n /**\n * Get items sorted by last accessed time (for debugging/monitoring)\n */\n getLRUItems(\n limit: number = 10,\n ): Array<{ hash: string; lastAccessed: Date; size: number }> {\n const entries = Array.from(this.cache.entries())\n .sort(([, a], [, b]) => a.lastAccessed - b.lastAccessed)\n .slice(0, limit);\n\n return entries.map(([hash, item]) => ({\n hash,\n lastAccessed: new Date(item.lastAccessed),\n size: item.size,\n }));\n }\n\n /**\n * Destroy the cache and cleanup resources\n */\n destroy(): void {\n if (this.cleanupInterval) {\n clearInterval(this.cleanupInterval);\n this.cleanupInterval = undefined;\n }\n this.cache.clear();\n this.totalSize = 0;\n }\n\n /**\n * Estimate the size in bytes of a cache entry (key + value + metadata)\n */\n private estimateEntrySize(hash: string, value: unknown): number {\n let size = 0;\n\n // Hash key size (UTF-16 => 2 bytes per char)\n size += hash.length * 2;\n\n // Metadata size (expiresAt & lastAccessed)\n size += 16;\n\n // Value size via safe-stringify\n try {\n const json = safeStringify(value) ?? '';\n size += json.length * 2;\n } catch {\n size += 1024; // fallback estimate\n }\n\n return size;\n }\n}\n","import { randomUUID } from 'crypto';\nimport type { DedupeStore } from '@http-client-toolkit/core';\n\n// Simple deferred promise helper to avoid non-null assertions\nfunction deferred<T>() {\n let resolve!: (value: T | PromiseLike<T>) => void;\n let reject!: (reason?: unknown) => void;\n const promise = new Promise<T>((res, rej) => {\n resolve = res;\n reject = rej;\n });\n return { promise, resolve, reject } as const;\n}\n\ninterface DedupeJob<T> {\n jobId: string;\n promise: Promise<T | undefined>;\n resolve: (value: T | undefined) => void;\n reject: (reason: unknown) => void;\n createdAt: number;\n completed: boolean;\n result?: T;\n error?: Error;\n}\n\nexport interface InMemoryDedupeStoreOptions {\n jobTimeoutMs?: number;\n cleanupIntervalMs?: number;\n}\n\nexport class InMemoryDedupeStore<T = unknown> implements DedupeStore<T> {\n private jobs = new Map<string, DedupeJob<T>>();\n private readonly jobTimeoutMs: number;\n private cleanupInterval?: NodeJS.Timeout;\n private totalJobsProcessed: number = 0;\n private destroyed: boolean = false;\n\n constructor({\n /** Job timeout in milliseconds. Defaults to 5 minutes. */\n jobTimeoutMs = 300_000,\n /** Cleanup interval in milliseconds. Defaults to 1 minute. */\n cleanupIntervalMs = 60_000,\n }: InMemoryDedupeStoreOptions = {}) {\n this.jobTimeoutMs = jobTimeoutMs;\n\n if (cleanupIntervalMs > 0) {\n this.cleanupInterval = setInterval(() => {\n this.cleanup();\n }, cleanupIntervalMs);\n\n // Do not keep the process alive solely for periodic maintenance.\n if (typeof this.cleanupInterval.unref === 'function') {\n this.cleanupInterval.unref();\n }\n }\n }\n\n async waitFor(hash: string): Promise<T | undefined> {\n if (this.destroyed) {\n return undefined;\n }\n\n const job = this.jobs.get(hash);\n if (!job) {\n return undefined;\n }\n\n const jobTimedOut =\n this.jobTimeoutMs > 0 && Date.now() - job.createdAt > this.jobTimeoutMs;\n if (jobTimedOut) {\n this.cleanup();\n return undefined;\n }\n\n // If job is already completed, return the result or throw the error\n if (job.completed) {\n if (job.error) {\n return undefined; // Return undefined for failed jobs instead of throwing\n }\n return job.result ?? undefined;\n }\n\n try {\n return await job.promise;\n } catch {\n // The job promise was rejected, return undefined for failed jobs\n return undefined;\n }\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 // Check if there's already a job for this hash\n const existingJob = this.jobs.get(hash);\n if (existingJob) {\n return {\n jobId: existingJob.jobId,\n isOwner: false,\n };\n }\n\n // Create a new job\n const jobId = randomUUID();\n const { promise, resolve, reject } = deferred<T | undefined>();\n\n const job: DedupeJob<T> = {\n jobId,\n promise,\n resolve,\n reject,\n createdAt: Date.now(),\n completed: false,\n };\n\n this.jobs.set(hash, job);\n this.totalJobsProcessed++;\n return {\n jobId,\n isOwner: true,\n };\n }\n\n async complete(hash: string, value: T): Promise<void> {\n const job = this.jobs.get(hash);\n if (job && !job.completed) {\n job.completed = true;\n job.result = value;\n job.resolve(value);\n }\n }\n\n async fail(hash: string, error: Error): Promise<void> {\n const job = this.jobs.get(hash);\n if (job && !job.completed) {\n job.completed = true;\n job.error = error;\n job.reject(error);\n }\n }\n\n async isInProgress(hash: string): Promise<boolean> {\n const job = this.jobs.get(hash);\n if (!job) {\n return false;\n }\n\n const isJobExpired =\n this.jobTimeoutMs > 0 && Date.now() - job.createdAt > this.jobTimeoutMs;\n if (isJobExpired) {\n this.cleanup();\n return false;\n }\n\n return !job.completed;\n }\n\n /**\n * Get statistics about current dedupe jobs\n */\n getStats(): {\n activeJobs: number;\n totalJobsProcessed: number;\n expiredJobs: number;\n oldestJobAgeMs: number;\n } {\n const now = Date.now();\n let expiredJobs = 0;\n let oldestJobAgeMs = 0;\n let activeJobs = 0;\n\n for (const [_hash, job] of this.jobs) {\n const ageMs = now - job.createdAt;\n if (this.jobTimeoutMs > 0 && ageMs > this.jobTimeoutMs) {\n expiredJobs++;\n }\n if (ageMs > oldestJobAgeMs) {\n oldestJobAgeMs = ageMs;\n }\n // Only count jobs that are not completed as active\n if (!job.completed) {\n activeJobs++;\n }\n }\n\n return {\n activeJobs,\n totalJobsProcessed: this.totalJobsProcessed,\n expiredJobs,\n oldestJobAgeMs,\n };\n }\n\n /**\n * Clean up expired jobs\n */\n cleanup(): void {\n // Skip cleanup if timeout is disabled\n if (this.jobTimeoutMs <= 0) {\n return;\n }\n\n const now = Date.now();\n const toDelete: Array<string> = [];\n\n for (const [hash, job] of this.jobs) {\n if (now - job.createdAt > this.jobTimeoutMs) {\n if (!job.completed) {\n // Reject the expired job\n job.completed = true;\n job.error = new Error(\n 'Job timeout: Request took too long to complete',\n );\n job.reject(job.error);\n }\n toDelete.push(hash);\n }\n }\n\n for (const hash of toDelete) {\n this.jobs.delete(hash);\n }\n }\n\n /**\n * Clear all jobs\n */\n clear(): void {\n // Reject all pending jobs\n for (const [_hash, job] of this.jobs) {\n if (!job.completed) {\n job.completed = true;\n job.error = new Error('DedupeStore cleared');\n job.reject(job.error);\n }\n }\n this.jobs.clear();\n }\n\n /**\n * Destroy the store and clean up resources\n */\n destroy(): void {\n if (this.cleanupInterval) {\n clearInterval(this.cleanupInterval);\n this.cleanupInterval = undefined;\n }\n this.clear();\n this.destroyed = true;\n }\n}\n","import {\n type RateLimitConfig,\n type RateLimitStore,\n DEFAULT_RATE_LIMIT,\n} from '@http-client-toolkit/core';\n\ninterface RateLimitInfo {\n requests: Array<number>;\n limit: number;\n windowMs: number;\n resetTime: number;\n}\n\nexport interface InMemoryRateLimitStoreOptions {\n defaultConfig?: RateLimitConfig;\n resourceConfigs?: Map<string, RateLimitConfig>;\n cleanupIntervalMs?: number;\n}\n\nexport class InMemoryRateLimitStore implements RateLimitStore {\n private limits = new Map<string, RateLimitInfo>();\n private defaultConfig: RateLimitConfig;\n private resourceConfigs = new Map<string, RateLimitConfig>();\n private cleanupInterval?: NodeJS.Timeout;\n private totalRequests: number = 0;\n\n constructor({\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(),\n /** Cleanup interval in milliseconds. Defaults to 1 minute. */\n cleanupIntervalMs = 60_000,\n }: InMemoryRateLimitStoreOptions = {}) {\n this.defaultConfig = defaultConfig;\n this.resourceConfigs = resourceConfigs;\n\n if (cleanupIntervalMs > 0) {\n this.cleanupInterval = setInterval(() => {\n this.cleanup();\n }, cleanupIntervalMs);\n\n // Do not pin Node's event loop for background cleanup only.\n if (typeof this.cleanupInterval.unref === 'function') {\n this.cleanupInterval.unref();\n }\n }\n }\n\n async canProceed(resource: string): Promise<boolean> {\n const config = this.resourceConfigs.get(resource) || this.defaultConfig;\n const info = this.getOrCreateRateLimitInfo(resource, config);\n\n this.cleanupExpiredRequests(info);\n\n return info.requests.length < info.limit;\n }\n\n async record(resource: string): Promise<void> {\n const config = this.resourceConfigs.get(resource) || this.defaultConfig;\n const info = this.getOrCreateRateLimitInfo(resource, config);\n\n this.cleanupExpiredRequests(info);\n\n const now = Date.now();\n info.requests.push(now);\n this.totalRequests++;\n\n // Update reset time to be one window from now\n info.resetTime = now + config.windowMs;\n }\n\n async getStatus(resource: string): Promise<{\n remaining: number;\n resetTime: Date;\n limit: number;\n }> {\n const config = this.resourceConfigs.get(resource) || this.defaultConfig;\n const info = this.getOrCreateRateLimitInfo(resource, config);\n\n this.cleanupExpiredRequests(info);\n\n return {\n remaining: Math.max(0, info.limit - info.requests.length),\n resetTime: new Date(info.resetTime),\n limit: info.limit,\n };\n }\n\n async reset(resource: string): Promise<void> {\n const info = this.limits.get(resource);\n if (info) {\n // Subtract the requests for this resource from total count\n this.totalRequests = Math.max(\n 0,\n this.totalRequests - info.requests.length,\n );\n }\n this.limits.delete(resource);\n }\n\n async getWaitTime(resource: string): Promise<number> {\n const config = this.resourceConfigs.get(resource) || this.defaultConfig;\n const info = this.getOrCreateRateLimitInfo(resource, config);\n\n this.cleanupExpiredRequests(info);\n\n // Special case: if limit is 0, always return the time until window resets\n if (info.limit === 0) {\n return Math.max(0, info.resetTime - Date.now());\n }\n\n if (info.requests.length < info.limit) {\n return 0;\n }\n\n // Find the oldest request that's still within the window\n const oldestRequest = info.requests[0];\n if (oldestRequest === undefined) {\n return 0;\n }\n const timeUntilOldestExpires = oldestRequest + config.windowMs - Date.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 // Reset existing limits for this resource to apply new config\n this.limits.delete(resource);\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 getStats(): {\n totalResources: number;\n activeResources: number;\n rateLimitedResources: number;\n totalRequests: number;\n } {\n let activeResources = 0;\n let rateLimitedResources = 0;\n\n for (const [_resource, info] of this.limits) {\n this.cleanupExpiredRequests(info);\n\n if (info.requests.length > 0) {\n activeResources++;\n if (info.requests.length >= info.limit) {\n rateLimitedResources++;\n }\n }\n }\n\n return {\n totalResources: this.limits.size,\n activeResources,\n rateLimitedResources,\n totalRequests: this.totalRequests,\n };\n }\n\n /**\n * Clear all rate limit data\n */\n clear(): void {\n this.limits.clear();\n this.totalRequests = 0;\n }\n\n /**\n * Clean up expired requests for all resources\n */\n cleanup(): void {\n for (const [_resource, info] of this.limits) {\n this.cleanupExpiredRequests(info);\n }\n }\n\n /**\n * Destroy the store and clean up resources\n */\n destroy(): void {\n if (this.cleanupInterval) {\n clearInterval(this.cleanupInterval);\n this.cleanupInterval = undefined;\n }\n this.clear();\n }\n\n private getOrCreateRateLimitInfo(\n resource: string,\n config: RateLimitConfig,\n ): RateLimitInfo {\n let info = this.limits.get(resource);\n if (!info) {\n info = {\n requests: [],\n limit: config.limit,\n windowMs: config.windowMs,\n resetTime: Date.now() + config.windowMs,\n };\n this.limits.set(resource, info);\n }\n return info;\n }\n\n private cleanupExpiredRequests(info: RateLimitInfo): void {\n const now = Date.now();\n const cutoff = now - info.windowMs;\n const initialLength = info.requests.length;\n\n // Remove requests older than the window\n while (info.requests.length > 0 && info.requests[0]! < cutoff) {\n info.requests.shift();\n }\n\n // Update total request count to reflect removed expired requests\n const expiredCount = initialLength - info.requests.length;\n this.totalRequests = Math.max(0, this.totalRequests - expiredCount);\n\n // Update reset time if no requests remain\n if (info.requests.length === 0) {\n info.resetTime = now + info.windowMs;\n }\n }\n}\n","import {\n AdaptiveConfigSchema,\n type AdaptiveRateLimitStore as IAdaptiveRateLimitStore,\n type RequestPriority,\n type RateLimitConfig,\n DEFAULT_RATE_LIMIT,\n AdaptiveCapacityCalculator,\n type ActivityMetrics,\n type DynamicCapacityResult,\n} from '@http-client-toolkit/core';\nimport { z } from 'zod';\n\nexport interface AdaptiveRateLimitStoreOptions {\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\n/**\n * In-memory rate limiting store with adaptive priority-based capacity allocation\n */\nexport class AdaptiveRateLimitStore implements IAdaptiveRateLimitStore {\n private defaultConfig: RateLimitConfig;\n private resourceConfigs: Map<string, RateLimitConfig>;\n private activityMetrics = new Map<string, ActivityMetrics>();\n private capacityCalculator: AdaptiveCapacityCalculator;\n private lastCapacityUpdate = new Map<string, number>();\n private cachedCapacity = new Map<string, DynamicCapacityResult>();\n\n constructor(options: AdaptiveRateLimitStoreOptions = {}) {\n this.defaultConfig = options.defaultConfig ?? DEFAULT_RATE_LIMIT;\n this.resourceConfigs = options.resourceConfigs ?? new Map();\n this.capacityCalculator = new AdaptiveCapacityCalculator(\n options.adaptiveConfig,\n );\n }\n\n async canProceed(\n resource: string,\n priority: RequestPriority = 'background',\n ): Promise<boolean> {\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\n const currentUserRequests = this.getCurrentUsage(\n resource,\n metrics.recentUserRequests,\n );\n const currentBackgroundRequests = this.getCurrentUsage(\n resource,\n metrics.recentBackgroundRequests,\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 const metrics = this.getOrCreateActivityMetrics(resource);\n const now = Date.now();\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 const metrics = this.getOrCreateActivityMetrics(resource);\n const capacity = this.calculateCurrentCapacity(resource, metrics);\n const currentUserUsage = this.getCurrentUsage(\n resource,\n metrics.recentUserRequests,\n );\n const currentBackgroundUsage = this.getCurrentUsage(\n resource,\n metrics.recentBackgroundRequests,\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 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 const canProceed = await this.canProceed(resource, priority);\n if (canProceed) {\n return 0;\n }\n\n const metrics = this.getOrCreateActivityMetrics(resource);\n const capacity = this.calculateCurrentCapacity(resource, metrics);\n\n // If background is paused, wait until next recalculation\n if (priority === 'background' && capacity.backgroundPaused) {\n const lastUpdate = this.lastCapacityUpdate.get(resource) || 0;\n const nextUpdate =\n lastUpdate + this.capacityCalculator.config.recalculationIntervalMs;\n return Math.max(0, nextUpdate - Date.now());\n }\n\n // Otherwise, wait until requests age out of the monitoring window\n const monitoringWindow = this.capacityCalculator.config.monitoringWindowMs;\n const requests =\n priority === 'user'\n ? metrics.recentUserRequests\n : metrics.recentBackgroundRequests;\n\n if (requests.length === 0) {\n return 0;\n }\n\n // Wait until the oldest request falls out of the monitoring window\n const oldestRequest = Math.min(...requests);\n const waitTime = oldestRequest + monitoringWindow - Date.now();\n return Math.max(0, waitTime);\n }\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 getCurrentUsage(resource: string, requests: Array<number>): number {\n const config = this.resourceConfigs.get(resource) ?? this.defaultConfig;\n const windowStart = Date.now() - config.windowMs;\n return requests.filter((timestamp) => timestamp > windowStart).length;\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 totalLimit = this.getResourceLimit(resource);\n return {\n userReserved: Math.floor(totalLimit * 0.3),\n backgroundMax: Math.floor(totalLimit * 0.7),\n backgroundPaused: false,\n reason: 'Default capacity allocation',\n };\n }\n}\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@http-client-toolkit/store-memory",
|
|
3
|
+
"description": "In-memory store implementations for HTTP client toolkit caching, deduplication, and rate limiting",
|
|
4
|
+
"repository": {
|
|
5
|
+
"type": "git",
|
|
6
|
+
"url": "git+https://github.com/AllyMurray/http-client-toolkit.git"
|
|
7
|
+
},
|
|
8
|
+
"author": {
|
|
9
|
+
"name": "Ally Murray",
|
|
10
|
+
"email": "allymurray88@gmail.com",
|
|
11
|
+
"organization": false
|
|
12
|
+
},
|
|
13
|
+
"devDependencies": {
|
|
14
|
+
"@types/node": "20",
|
|
15
|
+
"eslint": "^9.39.0",
|
|
16
|
+
"rimraf": "6.0.1",
|
|
17
|
+
"tsup": "8.5.0",
|
|
18
|
+
"tsx": "4.20.3",
|
|
19
|
+
"typescript": "5.8.3",
|
|
20
|
+
"vitest": "3.2.4",
|
|
21
|
+
"@repo/eslint-config": "0.0.1",
|
|
22
|
+
"@repo/tsup-config": "0.0.1",
|
|
23
|
+
"@repo/vitest-config": "0.0.1"
|
|
24
|
+
},
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"fast-safe-stringify": "^2.1.1",
|
|
27
|
+
"zod": "^3.24.1",
|
|
28
|
+
"@http-client-toolkit/core": "0.0.1"
|
|
29
|
+
},
|
|
30
|
+
"keywords": [
|
|
31
|
+
"http-client",
|
|
32
|
+
"in-memory-store",
|
|
33
|
+
"caching",
|
|
34
|
+
"deduplication",
|
|
35
|
+
"rate-limiting"
|
|
36
|
+
],
|
|
37
|
+
"engines": {
|
|
38
|
+
"node": ">= 20.0.0"
|
|
39
|
+
},
|
|
40
|
+
"main": "./lib/index.cjs",
|
|
41
|
+
"license": "ISC",
|
|
42
|
+
"sideEffects": false,
|
|
43
|
+
"files": [
|
|
44
|
+
"lib/**"
|
|
45
|
+
],
|
|
46
|
+
"homepage": "https://github.com/AllyMurray/http-client-toolkit#readme",
|
|
47
|
+
"version": "0.0.1",
|
|
48
|
+
"bugs": {
|
|
49
|
+
"url": "https://github.com/AllyMurray/http-client-toolkit/issues"
|
|
50
|
+
},
|
|
51
|
+
"types": "./lib/index.d.ts",
|
|
52
|
+
"type": "module",
|
|
53
|
+
"module": "./lib/index.js",
|
|
54
|
+
"exports": {
|
|
55
|
+
".": {
|
|
56
|
+
"import": {
|
|
57
|
+
"types": "./lib/index.d.ts",
|
|
58
|
+
"default": "./lib/index.js"
|
|
59
|
+
},
|
|
60
|
+
"require": {
|
|
61
|
+
"types": "./lib/index.d.cts",
|
|
62
|
+
"default": "./lib/index.cjs"
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
"publishConfig": {
|
|
67
|
+
"access": "public"
|
|
68
|
+
},
|
|
69
|
+
"scripts": {
|
|
70
|
+
"build": "tsup && npm run test",
|
|
71
|
+
"lint": "eslint --fix src && prettier --write .",
|
|
72
|
+
"test": "vitest run --dir=src",
|
|
73
|
+
"test:coverage": "vitest run --dir=src --coverage",
|
|
74
|
+
"test:watch": "vitest --dir=src",
|
|
75
|
+
"dev": "tsup --watch",
|
|
76
|
+
"clean": "rimraf lib dist node_modules .turbo"
|
|
77
|
+
}
|
|
78
|
+
}
|