@stacksjs/bun-router 0.0.12 → 0.0.14
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/CHANGELOG.md +770 -0
- package/README.md +584 -261
- package/package.json +43 -48
- package/bin/cli.ts +0 -9
- package/dist/auth.d.ts +0 -134
- package/dist/cache/lru-cache.d.ts +0 -139
- package/dist/cache/middleware-memoization.d.ts +0 -151
- package/dist/cache/route-cache-warmer.d.ts +0 -161
- package/dist/cache/sqlite-cache.d.ts +0 -209
- package/dist/cache/streaming-cache.d.ts +0 -132
- package/dist/chunk-1mvtv6jw.js +0 -13012
- package/dist/cli/colors.d.ts +0 -15
- package/dist/cli/index.d.ts +0 -10
- package/dist/cli/middleware.d.ts +0 -31
- package/dist/cli/openapi.d.ts +0 -17
- package/dist/cli/router.d.ts +0 -15
- package/dist/cli/routes.d.ts +0 -29
- package/dist/cli/utils.d.ts +0 -74
- package/dist/cli.d.ts +0 -1
- package/dist/cli.js +0 -3195
- package/dist/config.d.ts +0 -7
- package/dist/container/container.d.ts +0 -273
- package/dist/container/contextual-binding.d.ts +0 -240
- package/dist/container/decorators.d.ts +0 -141
- package/dist/container/service-provider.d.ts +0 -285
- package/dist/development/hot-reload.d.ts +0 -187
- package/dist/development/index.d.ts +0 -167
- package/dist/development/performance-profiler.d.ts +0 -217
- package/dist/development/route-debugger.d.ts +0 -154
- package/dist/development/route-inspector.d.ts +0 -211
- package/dist/development/typescript-utilities.d.ts +0 -209
- package/dist/docs.d.ts +0 -11
- package/dist/errors/circuit-breaker.d.ts +0 -195
- package/dist/errors/error-handler.d.ts +0 -88
- package/dist/errors/error-reporting.d.ts +0 -144
- package/dist/errors/exceptions.d.ts +0 -184
- package/dist/errors/graceful-degradation.d.ts +0 -154
- package/dist/errors/index.d.ts +0 -9
- package/dist/errors/router-errors.d.ts +0 -110
- package/dist/file-serving/static-files.d.ts +0 -143
- package/dist/index.d.ts +0 -14
- package/dist/index.js +0 -13933
- package/dist/middleware/auth.d.ts +0 -63
- package/dist/middleware/content_security_policy.d.ts +0 -53
- package/dist/middleware/cors.d.ts +0 -5
- package/dist/middleware/csrf.d.ts +0 -7
- package/dist/middleware/ddos_protection.d.ts +0 -39
- package/dist/middleware/file_security.d.ts +0 -26
- package/dist/middleware/file_upload.d.ts +0 -38
- package/dist/middleware/helmet.d.ts +0 -54
- package/dist/middleware/index.d.ts +0 -44
- package/dist/middleware/input_validation.d.ts +0 -45
- package/dist/middleware/json_body.d.ts +0 -4
- package/dist/middleware/performance_alerting.d.ts +0 -87
- package/dist/middleware/performance_dashboard.d.ts +0 -87
- package/dist/middleware/performance_monitor.d.ts +0 -209
- package/dist/middleware/pipeline.d.ts +0 -131
- package/dist/middleware/rate_limit.d.ts +0 -36
- package/dist/middleware/request_id.d.ts +0 -4
- package/dist/middleware/request_signing.d.ts +0 -153
- package/dist/middleware/request_tracer.d.ts +0 -72
- package/dist/middleware/response_cache.d.ts +0 -97
- package/dist/middleware/security.d.ts +0 -69
- package/dist/middleware/security_suite.d.ts +0 -46
- package/dist/middleware/session.d.ts +0 -23
- package/dist/model-binding/index.d.ts +0 -2
- package/dist/model-binding/model-middleware.d.ts +0 -118
- package/dist/model-binding/model-registry.d.ts +0 -164
- package/dist/model-binding.d.ts +0 -185
- package/dist/model-resolver-factory.d.ts +0 -31
- package/dist/observability/correlation.d.ts +0 -187
- package/dist/observability/health-checks.d.ts +0 -186
- package/dist/observability/index.d.ts +0 -60
- package/dist/observability/integration.d.ts +0 -147
- package/dist/observability/metrics.d.ts +0 -184
- package/dist/observability/tracing.d.ts +0 -187
- package/dist/optimization/bun-utilities.d.ts +0 -224
- package/dist/query-builder-integration.d.ts +0 -36
- package/dist/request/context.d.ts +0 -34
- package/dist/request/enhanced-request.d.ts +0 -213
- package/dist/request/macros.d.ts +0 -300
- package/dist/response/macros.d.ts +0 -245
- package/dist/response/response-factory.d.ts +0 -133
- package/dist/router/api-routes.d.ts +0 -5
- package/dist/router/file-based-routing.d.ts +0 -118
- package/dist/router/file-streaming.d.ts +0 -5
- package/dist/router/fluent-router.d.ts +0 -315
- package/dist/router/fluent-routing.d.ts +0 -271
- package/dist/router/group-organization.d.ts +0 -5
- package/dist/router/handler-resolver.d.ts +0 -24
- package/dist/router/http-methods.d.ts +0 -10
- package/dist/router/index.d.ts +0 -114
- package/dist/router/middleware-groups.d.ts +0 -94
- package/dist/router/middleware-integration.d.ts +0 -112
- package/dist/router/middleware.d.ts +0 -5
- package/dist/router/model-binding.d.ts +0 -5
- package/dist/router/optimized-route-matching.d.ts +0 -6
- package/dist/router/route-building.d.ts +0 -5
- package/dist/router/route-compiler.d.ts +0 -153
- package/dist/router/route-matching.d.ts +0 -5
- package/dist/router/route-trie.d.ts +0 -114
- package/dist/router/router.d.ts +0 -294
- package/dist/router/server.d.ts +0 -5
- package/dist/router/validation-integration.d.ts +0 -170
- package/dist/router/view-rendering.d.ts +0 -5
- package/dist/router/websocket.d.ts +0 -5
- package/dist/routing/route-caching.d.ts +0 -129
- package/dist/routing/route-throttling.d.ts +0 -150
- package/dist/routing/subdomain-routing.d.ts +0 -206
- package/dist/session/database-store.d.ts +0 -51
- package/dist/session/file-store.d.ts +0 -22
- package/dist/session/index.d.ts +0 -106
- package/dist/session/memory-store.d.ts +0 -21
- package/dist/session/redis-store.d.ts +0 -31
- package/dist/streaming/index.d.ts +0 -3
- package/dist/streaming/sse-handler.d.ts +0 -138
- package/dist/streaming/stream-handler.d.ts +0 -114
- package/dist/testing/auth-testing.d.ts +0 -156
- package/dist/testing/file-upload-testing.d.ts +0 -190
- package/dist/testing/index.d.ts +0 -10
- package/dist/testing/middleware-testing.d.ts +0 -138
- package/dist/testing/model-binding-testing.d.ts +0 -186
- package/dist/testing/performance-testing.d.ts +0 -235
- package/dist/testing/test-client.d.ts +0 -117
- package/dist/testing/test-request.d.ts +0 -85
- package/dist/testing/test-response.d.ts +0 -90
- package/dist/testing/types.d.ts +0 -207
- package/dist/testing/websocket-testing.d.ts +0 -227
- package/dist/types/controller-types.d.ts +0 -208
- package/dist/types/core.d.ts +0 -543
- package/dist/types/middleware-types.d.ts +0 -227
- package/dist/types/request-response-augmentation.d.ts +0 -261
- package/dist/types/route-inference.d.ts +0 -168
- package/dist/types.d.ts +0 -1782
- package/dist/url.d.ts +0 -56
- package/dist/utils/index.d.ts +0 -1
- package/dist/utils/query-preservation.d.ts +0 -48
- package/dist/utils.d.ts +0 -69
- package/dist/validation/validator.d.ts +0 -140
- package/dist/websocket/clustering.d.ts +0 -185
- package/src/auth.ts +0 -469
- package/src/cache/lru-cache.ts +0 -457
- package/src/cache/middleware-memoization.ts +0 -531
- package/src/cache/route-cache-warmer.ts +0 -486
- package/src/cache/sqlite-cache.ts +0 -783
- package/src/cache/streaming-cache.ts +0 -572
- package/src/cli/colors.ts +0 -29
- package/src/cli/index.ts +0 -287
- package/src/cli/middleware.ts +0 -291
- package/src/cli/openapi.ts +0 -407
- package/src/cli/router.ts +0 -188
- package/src/cli/routes.ts +0 -265
- package/src/cli/utils.ts +0 -531
- package/src/cli.ts +0 -5
- package/src/config.ts +0 -322
- package/src/container/container.ts +0 -740
- package/src/container/contextual-binding.ts +0 -603
- package/src/container/decorators.ts +0 -359
- package/src/container/service-provider.ts +0 -596
- package/src/development/hot-reload.ts +0 -673
- package/src/development/index.ts +0 -499
- package/src/development/performance-profiler.ts +0 -717
- package/src/development/route-debugger.ts +0 -527
- package/src/development/route-inspector.ts +0 -749
- package/src/development/typescript-utilities.ts +0 -682
- package/src/docs.ts +0 -397
- package/src/errors/circuit-breaker.ts +0 -732
- package/src/errors/error-handler.ts +0 -569
- package/src/errors/error-reporting.ts +0 -672
- package/src/errors/exceptions.ts +0 -536
- package/src/errors/graceful-degradation.ts +0 -621
- package/src/errors/index.ts +0 -21
- package/src/errors/router-errors.ts +0 -632
- package/src/file-serving/static-files.ts +0 -581
- package/src/index.ts +0 -14
- package/src/middleware/auth.ts +0 -219
- package/src/middleware/content_security_policy.ts +0 -215
- package/src/middleware/cors.ts +0 -74
- package/src/middleware/csrf.ts +0 -108
- package/src/middleware/ddos_protection.ts +0 -255
- package/src/middleware/file_security.ts +0 -191
- package/src/middleware/file_upload.ts +0 -264
- package/src/middleware/helmet.ts +0 -268
- package/src/middleware/index.ts +0 -117
- package/src/middleware/input_validation.ts +0 -449
- package/src/middleware/json_body.ts +0 -37
- package/src/middleware/performance_alerting.ts +0 -538
- package/src/middleware/performance_dashboard.ts +0 -661
- package/src/middleware/performance_monitor.ts +0 -943
- package/src/middleware/pipeline.ts +0 -489
- package/src/middleware/rate_limit.ts +0 -245
- package/src/middleware/request_id.ts +0 -36
- package/src/middleware/request_signing.ts +0 -636
- package/src/middleware/request_tracer.ts +0 -636
- package/src/middleware/response_cache.ts +0 -743
- package/src/middleware/security.ts +0 -482
- package/src/middleware/security_suite.ts +0 -257
- package/src/middleware/session.ts +0 -91
- package/src/model-binding/index.ts +0 -18
- package/src/model-binding/model-middleware.ts +0 -425
- package/src/model-binding/model-registry.ts +0 -550
- package/src/model-binding.ts +0 -370
- package/src/model-resolver-factory.ts +0 -106
- package/src/observability/correlation.ts +0 -691
- package/src/observability/health-checks.ts +0 -729
- package/src/observability/index.ts +0 -184
- package/src/observability/integration.ts +0 -548
- package/src/observability/metrics.ts +0 -753
- package/src/observability/tracing.ts +0 -638
- package/src/optimization/bun-utilities.ts +0 -778
- package/src/query-builder-integration.ts +0 -137
- package/src/request/context.ts +0 -62
- package/src/request/enhanced-request.ts +0 -857
- package/src/request/macros.ts +0 -688
- package/src/response/macros.ts +0 -612
- package/src/response/response-factory.ts +0 -596
- package/src/router/api-routes.ts +0 -243
- package/src/router/file-based-routing.ts +0 -670
- package/src/router/file-streaming.ts +0 -372
- package/src/router/fluent-router.ts +0 -927
- package/src/router/fluent-routing.ts +0 -797
- package/src/router/group-organization.ts +0 -213
- package/src/router/handler-resolver.ts +0 -291
- package/src/router/http-methods.ts +0 -377
- package/src/router/index.ts +0 -187
- package/src/router/middleware-groups.ts +0 -222
- package/src/router/middleware-integration.ts +0 -399
- package/src/router/middleware.ts +0 -231
- package/src/router/model-binding.ts +0 -215
- package/src/router/optimized-route-matching.ts +0 -253
- package/src/router/route-building.ts +0 -212
- package/src/router/route-compiler.ts +0 -702
- package/src/router/route-matching.ts +0 -349
- package/src/router/route-trie.ts +0 -464
- package/src/router/router.ts +0 -1581
- package/src/router/server.ts +0 -462
- package/src/router/validation-integration.ts +0 -443
- package/src/router/view-rendering.ts +0 -233
- package/src/router/websocket.ts +0 -100
- package/src/routing/route-caching.ts +0 -402
- package/src/routing/route-throttling.ts +0 -469
- package/src/routing/subdomain-routing.ts +0 -492
- package/src/session/database-store.ts +0 -109
- package/src/session/file-store.ts +0 -148
- package/src/session/index.ts +0 -244
- package/src/session/memory-store.ts +0 -88
- package/src/session/redis-store.ts +0 -93
- package/src/streaming/index.ts +0 -17
- package/src/streaming/sse-handler.ts +0 -482
- package/src/streaming/stream-handler.ts +0 -552
- package/src/testing/auth-testing.ts +0 -446
- package/src/testing/file-upload-testing.ts +0 -543
- package/src/testing/index.ts +0 -10
- package/src/testing/middleware-testing.ts +0 -322
- package/src/testing/model-binding-testing.ts +0 -645
- package/src/testing/performance-testing.ts +0 -738
- package/src/testing/test-client.ts +0 -310
- package/src/testing/test-request.ts +0 -315
- package/src/testing/test-response.ts +0 -332
- package/src/testing/types.ts +0 -224
- package/src/testing/websocket-testing.ts +0 -590
- package/src/types/controller-types.ts +0 -385
- package/src/types/core.ts +0 -683
- package/src/types/middleware-types.ts +0 -419
- package/src/types/request-response-augmentation.ts +0 -489
- package/src/types/route-inference.ts +0 -357
- package/src/types.ts +0 -2055
- package/src/url.ts +0 -126
- package/src/utils/index.ts +0 -1
- package/src/utils/query-preservation.ts +0 -201
- package/src/utils.ts +0 -327
- package/src/validation/validator.ts +0 -685
- package/src/websocket/clustering.ts +0 -762
package/src/cache/lru-cache.ts
DELETED
|
@@ -1,457 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* High-performance LRU (Least Recently Used) cache implementation
|
|
3
|
-
* Optimized for Bun runtime with configurable size limits and TTL support
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
export interface LRUCacheOptions {
|
|
7
|
-
maxSize: number
|
|
8
|
-
ttl?: number // Time to live in milliseconds
|
|
9
|
-
onEvict?: (key: string, value: any) => void
|
|
10
|
-
allowStale?: boolean // Allow returning stale items
|
|
11
|
-
updateAgeOnGet?: boolean // Update age when item is accessed
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export interface CacheEntry<T = any> {
|
|
15
|
-
value: T
|
|
16
|
-
timestamp: number
|
|
17
|
-
accessCount: number
|
|
18
|
-
lastAccessed: number
|
|
19
|
-
ttl?: number
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export interface CacheStats {
|
|
23
|
-
size: number
|
|
24
|
-
maxSize: number
|
|
25
|
-
hits: number
|
|
26
|
-
misses: number
|
|
27
|
-
evictions: number
|
|
28
|
-
hitRate: number
|
|
29
|
-
memoryUsage: number
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Node in the doubly linked list for LRU tracking
|
|
34
|
-
*/
|
|
35
|
-
class LRUNode<T = any> {
|
|
36
|
-
constructor(
|
|
37
|
-
public key: string,
|
|
38
|
-
public entry: CacheEntry<T>,
|
|
39
|
-
public prev: LRUNode<T> | null = null,
|
|
40
|
-
public next: LRUNode<T> | null = null,
|
|
41
|
-
) {}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* High-performance LRU cache with TTL support and detailed statistics
|
|
46
|
-
*/
|
|
47
|
-
export class LRUCache<T = any> {
|
|
48
|
-
private cache = new Map<string, LRUNode<T>>()
|
|
49
|
-
private head: LRUNode<T> | null = null
|
|
50
|
-
private tail: LRUNode<T> | null = null
|
|
51
|
-
private stats = {
|
|
52
|
-
hits: 0,
|
|
53
|
-
misses: 0,
|
|
54
|
-
evictions: 0,
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
constructor(private options: LRUCacheOptions) {
|
|
58
|
-
if (options.maxSize <= 0) {
|
|
59
|
-
throw new Error('maxSize must be greater than 0')
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Get value from cache
|
|
65
|
-
*/
|
|
66
|
-
get(key: string): T | undefined {
|
|
67
|
-
const node = this.cache.get(key)
|
|
68
|
-
|
|
69
|
-
if (!node) {
|
|
70
|
-
this.stats.misses++
|
|
71
|
-
return undefined
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
const now = Date.now()
|
|
75
|
-
const entry = node.entry
|
|
76
|
-
|
|
77
|
-
// Check TTL expiration
|
|
78
|
-
if (this.isExpired(entry, now)) {
|
|
79
|
-
if (!this.options.allowStale) {
|
|
80
|
-
this.delete(key)
|
|
81
|
-
this.stats.misses++
|
|
82
|
-
return undefined
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
// Update access statistics
|
|
87
|
-
entry.lastAccessed = now
|
|
88
|
-
entry.accessCount++
|
|
89
|
-
this.stats.hits++
|
|
90
|
-
|
|
91
|
-
// Move to front (most recently used) if updateAgeOnGet is enabled
|
|
92
|
-
if (this.options.updateAgeOnGet !== false) {
|
|
93
|
-
this.moveToFront(node)
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
return entry.value
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Set value in cache
|
|
101
|
-
*/
|
|
102
|
-
set(key: string, value: T, ttl?: number): void {
|
|
103
|
-
const now = Date.now()
|
|
104
|
-
const existingNode = this.cache.get(key)
|
|
105
|
-
|
|
106
|
-
if (existingNode) {
|
|
107
|
-
// Update existing entry
|
|
108
|
-
existingNode.entry.value = value
|
|
109
|
-
existingNode.entry.timestamp = now
|
|
110
|
-
existingNode.entry.lastAccessed = now
|
|
111
|
-
existingNode.entry.ttl = ttl ?? this.options.ttl
|
|
112
|
-
this.moveToFront(existingNode)
|
|
113
|
-
return
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
// Create new entry
|
|
117
|
-
const entry: CacheEntry<T> = {
|
|
118
|
-
value,
|
|
119
|
-
timestamp: now,
|
|
120
|
-
accessCount: 0,
|
|
121
|
-
lastAccessed: now,
|
|
122
|
-
ttl: ttl ?? this.options.ttl,
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
const newNode = new LRUNode(key, entry)
|
|
126
|
-
|
|
127
|
-
// Add to cache
|
|
128
|
-
this.cache.set(key, newNode)
|
|
129
|
-
this.addToFront(newNode)
|
|
130
|
-
|
|
131
|
-
// Check size limit and evict if necessary
|
|
132
|
-
if (this.cache.size > this.options.maxSize) {
|
|
133
|
-
this.evictLRU()
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* Delete key from cache
|
|
139
|
-
*/
|
|
140
|
-
delete(key: string): boolean {
|
|
141
|
-
const node = this.cache.get(key)
|
|
142
|
-
if (!node)
|
|
143
|
-
return false
|
|
144
|
-
|
|
145
|
-
this.cache.delete(key)
|
|
146
|
-
this.removeNode(node)
|
|
147
|
-
|
|
148
|
-
if (this.options.onEvict) {
|
|
149
|
-
this.options.onEvict(key, node.entry.value)
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
return true
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
/**
|
|
156
|
-
* Check if key exists in cache (without updating access time)
|
|
157
|
-
*/
|
|
158
|
-
has(key: string): boolean {
|
|
159
|
-
const node = this.cache.get(key)
|
|
160
|
-
if (!node)
|
|
161
|
-
return false
|
|
162
|
-
|
|
163
|
-
const now = Date.now()
|
|
164
|
-
if (this.isExpired(node.entry, now)) {
|
|
165
|
-
if (!this.options.allowStale) {
|
|
166
|
-
this.delete(key)
|
|
167
|
-
return false
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
return true
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
/**
|
|
175
|
-
* Clear all entries from cache
|
|
176
|
-
*/
|
|
177
|
-
clear(): void {
|
|
178
|
-
if (this.options.onEvict) {
|
|
179
|
-
for (const [key, node] of this.cache) {
|
|
180
|
-
this.options.onEvict(key, node.entry.value)
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
this.cache.clear()
|
|
185
|
-
this.head = null
|
|
186
|
-
this.tail = null
|
|
187
|
-
this.stats.evictions += this.cache.size
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
/**
|
|
191
|
-
* Get all keys in cache (ordered by recency)
|
|
192
|
-
*/
|
|
193
|
-
keys(): string[] {
|
|
194
|
-
const keys: string[] = []
|
|
195
|
-
let current = this.head
|
|
196
|
-
|
|
197
|
-
while (current) {
|
|
198
|
-
keys.push(current.key)
|
|
199
|
-
current = current.next
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
return keys
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
/**
|
|
206
|
-
* Get all values in cache (ordered by recency)
|
|
207
|
-
*/
|
|
208
|
-
values(): T[] {
|
|
209
|
-
const values: T[] = []
|
|
210
|
-
let current = this.head
|
|
211
|
-
|
|
212
|
-
while (current) {
|
|
213
|
-
values.push(current.entry.value)
|
|
214
|
-
current = current.next
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
return values
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
/**
|
|
221
|
-
* Get cache statistics
|
|
222
|
-
*/
|
|
223
|
-
getStats(): CacheStats {
|
|
224
|
-
const memoryUsage = this.estimateMemoryUsage()
|
|
225
|
-
const totalRequests = this.stats.hits + this.stats.misses
|
|
226
|
-
|
|
227
|
-
return {
|
|
228
|
-
size: this.cache.size,
|
|
229
|
-
maxSize: this.options.maxSize,
|
|
230
|
-
hits: this.stats.hits,
|
|
231
|
-
misses: this.stats.misses,
|
|
232
|
-
evictions: this.stats.evictions,
|
|
233
|
-
hitRate: totalRequests > 0 ? this.stats.hits / totalRequests : 0,
|
|
234
|
-
memoryUsage,
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
/**
|
|
239
|
-
* Reset statistics
|
|
240
|
-
*/
|
|
241
|
-
resetStats(): void {
|
|
242
|
-
this.stats = {
|
|
243
|
-
hits: 0,
|
|
244
|
-
misses: 0,
|
|
245
|
-
evictions: 0,
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
/**
|
|
250
|
-
* Prune expired entries
|
|
251
|
-
*/
|
|
252
|
-
prune(): number {
|
|
253
|
-
const now = Date.now()
|
|
254
|
-
const keysToDelete: string[] = []
|
|
255
|
-
|
|
256
|
-
for (const [key, node] of this.cache) {
|
|
257
|
-
if (this.isExpired(node.entry, now)) {
|
|
258
|
-
keysToDelete.push(key)
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
for (const key of keysToDelete) {
|
|
263
|
-
this.delete(key)
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
return keysToDelete.length
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
/**
|
|
270
|
-
* Get entries sorted by access frequency
|
|
271
|
-
*/
|
|
272
|
-
getFrequentlyUsed(limit: number = 10): Array<{ key: string, value: T, accessCount: number }> {
|
|
273
|
-
const entries: Array<{ key: string, value: T, accessCount: number }> = []
|
|
274
|
-
|
|
275
|
-
for (const [key, node] of this.cache) {
|
|
276
|
-
entries.push({
|
|
277
|
-
key,
|
|
278
|
-
value: node.entry.value,
|
|
279
|
-
accessCount: node.entry.accessCount,
|
|
280
|
-
})
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
return entries
|
|
284
|
-
.sort((a, b) => b.accessCount - a.accessCount)
|
|
285
|
-
.slice(0, limit)
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
/**
|
|
289
|
-
* Resize cache (may trigger evictions)
|
|
290
|
-
*/
|
|
291
|
-
resize(newMaxSize: number): void {
|
|
292
|
-
if (newMaxSize <= 0) {
|
|
293
|
-
throw new Error('maxSize must be greater than 0')
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
this.options.maxSize = newMaxSize
|
|
297
|
-
|
|
298
|
-
// Evict excess entries if new size is smaller
|
|
299
|
-
while (this.cache.size > newMaxSize) {
|
|
300
|
-
this.evictLRU()
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
/**
|
|
305
|
-
* Check if entry is expired
|
|
306
|
-
*/
|
|
307
|
-
private isExpired(entry: CacheEntry<T>, now: number): boolean {
|
|
308
|
-
if (!entry.ttl)
|
|
309
|
-
return false
|
|
310
|
-
return now - entry.timestamp > entry.ttl
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
/**
|
|
314
|
-
* Move node to front of list (most recently used)
|
|
315
|
-
*/
|
|
316
|
-
private moveToFront(node: LRUNode<T>): void {
|
|
317
|
-
if (node === this.head)
|
|
318
|
-
return
|
|
319
|
-
|
|
320
|
-
this.removeNode(node)
|
|
321
|
-
this.addToFront(node)
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
/**
|
|
325
|
-
* Add node to front of list
|
|
326
|
-
*/
|
|
327
|
-
private addToFront(node: LRUNode<T>): void {
|
|
328
|
-
node.prev = null
|
|
329
|
-
node.next = this.head
|
|
330
|
-
|
|
331
|
-
if (this.head) {
|
|
332
|
-
this.head.prev = node
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
this.head = node
|
|
336
|
-
|
|
337
|
-
if (!this.tail) {
|
|
338
|
-
this.tail = node
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
/**
|
|
343
|
-
* Remove node from list
|
|
344
|
-
*/
|
|
345
|
-
private removeNode(node: LRUNode<T>): void {
|
|
346
|
-
if (node.prev) {
|
|
347
|
-
node.prev.next = node.next
|
|
348
|
-
}
|
|
349
|
-
else {
|
|
350
|
-
this.head = node.next
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
if (node.next) {
|
|
354
|
-
node.next.prev = node.prev
|
|
355
|
-
}
|
|
356
|
-
else {
|
|
357
|
-
this.tail = node.prev
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
/**
|
|
362
|
-
* Evict least recently used entry
|
|
363
|
-
*/
|
|
364
|
-
private evictLRU(): void {
|
|
365
|
-
if (!this.tail)
|
|
366
|
-
return
|
|
367
|
-
|
|
368
|
-
const key = this.tail.key
|
|
369
|
-
const value = this.tail.entry.value
|
|
370
|
-
|
|
371
|
-
this.cache.delete(key)
|
|
372
|
-
this.removeNode(this.tail)
|
|
373
|
-
this.stats.evictions++
|
|
374
|
-
|
|
375
|
-
if (this.options.onEvict) {
|
|
376
|
-
this.options.onEvict(key, value)
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
/**
|
|
381
|
-
* Estimate memory usage in bytes
|
|
382
|
-
*/
|
|
383
|
-
private estimateMemoryUsage(): number {
|
|
384
|
-
let totalSize = 0
|
|
385
|
-
|
|
386
|
-
for (const [key, node] of this.cache) {
|
|
387
|
-
// Estimate key size (2 bytes per character for UTF-16)
|
|
388
|
-
totalSize += key.length * 2
|
|
389
|
-
|
|
390
|
-
// Estimate value size (rough approximation)
|
|
391
|
-
totalSize += this.estimateValueSize(node.entry.value)
|
|
392
|
-
|
|
393
|
-
// Add overhead for entry metadata
|
|
394
|
-
totalSize += 64 // timestamp, accessCount, lastAccessed, ttl
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
// Add overhead for Map and linked list structure
|
|
398
|
-
totalSize += this.cache.size * 48 // rough estimate for Map entry + node overhead
|
|
399
|
-
|
|
400
|
-
return totalSize
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
/**
|
|
404
|
-
* Estimate size of a value in bytes
|
|
405
|
-
*/
|
|
406
|
-
private estimateValueSize(value: any): number {
|
|
407
|
-
if (value === null || value === undefined)
|
|
408
|
-
return 0
|
|
409
|
-
if (typeof value === 'string')
|
|
410
|
-
return value.length * 2
|
|
411
|
-
if (typeof value === 'number')
|
|
412
|
-
return 8
|
|
413
|
-
if (typeof value === 'boolean')
|
|
414
|
-
return 1
|
|
415
|
-
if (value instanceof ArrayBuffer)
|
|
416
|
-
return value.byteLength
|
|
417
|
-
if (value instanceof Uint8Array)
|
|
418
|
-
return value.length
|
|
419
|
-
|
|
420
|
-
// For objects, rough JSON size estimation
|
|
421
|
-
try {
|
|
422
|
-
return JSON.stringify(value).length * 2
|
|
423
|
-
}
|
|
424
|
-
catch {
|
|
425
|
-
return 100 // fallback estimate
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
/**
|
|
431
|
-
* Factory function to create LRU cache with common configurations
|
|
432
|
-
*/
|
|
433
|
-
export const createLRUCache = {
|
|
434
|
-
/**
|
|
435
|
-
* Create a small cache for frequently accessed items
|
|
436
|
-
*/
|
|
437
|
-
small: <T = any>(ttl?: number): LRUCache<T> =>
|
|
438
|
-
new LRUCache<T>({ maxSize: 100, ttl, updateAgeOnGet: true }),
|
|
439
|
-
|
|
440
|
-
/**
|
|
441
|
-
* Create a medium cache for general purpose use
|
|
442
|
-
*/
|
|
443
|
-
medium: <T = any>(ttl?: number): LRUCache<T> =>
|
|
444
|
-
new LRUCache<T>({ maxSize: 1000, ttl, updateAgeOnGet: true }),
|
|
445
|
-
|
|
446
|
-
/**
|
|
447
|
-
* Create a large cache for heavy caching scenarios
|
|
448
|
-
*/
|
|
449
|
-
large: <T = any>(ttl?: number): LRUCache<T> =>
|
|
450
|
-
new LRUCache<T>({ maxSize: 10000, ttl, updateAgeOnGet: true }),
|
|
451
|
-
|
|
452
|
-
/**
|
|
453
|
-
* Create a custom configured cache
|
|
454
|
-
*/
|
|
455
|
-
custom: <T = any>(options: LRUCacheOptions): LRUCache<T> =>
|
|
456
|
-
new LRUCache<T>(options),
|
|
457
|
-
}
|