gitx.do 0.0.2 → 0.0.3
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/dist/cli/commands/blame.d.ts +259 -0
- package/dist/cli/commands/blame.d.ts.map +1 -0
- package/dist/cli/commands/blame.js +609 -0
- package/dist/cli/commands/blame.js.map +1 -0
- package/dist/cli/commands/branch.d.ts +249 -0
- package/dist/cli/commands/branch.d.ts.map +1 -0
- package/dist/cli/commands/branch.js +693 -0
- package/dist/cli/commands/branch.js.map +1 -0
- package/dist/cli/commands/commit.d.ts +182 -0
- package/dist/cli/commands/commit.d.ts.map +1 -0
- package/dist/cli/commands/commit.js +437 -0
- package/dist/cli/commands/commit.js.map +1 -0
- package/dist/cli/commands/diff.d.ts +464 -0
- package/dist/cli/commands/diff.d.ts.map +1 -0
- package/dist/cli/commands/diff.js +958 -0
- package/dist/cli/commands/diff.js.map +1 -0
- package/dist/cli/commands/log.d.ts +239 -0
- package/dist/cli/commands/log.d.ts.map +1 -0
- package/dist/cli/commands/log.js +535 -0
- package/dist/cli/commands/log.js.map +1 -0
- package/dist/cli/commands/review.d.ts +457 -0
- package/dist/cli/commands/review.d.ts.map +1 -0
- package/dist/cli/commands/review.js +533 -0
- package/dist/cli/commands/review.js.map +1 -0
- package/dist/cli/commands/status.d.ts +269 -0
- package/dist/cli/commands/status.d.ts.map +1 -0
- package/dist/cli/commands/status.js +493 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/commands/web.d.ts +199 -0
- package/dist/cli/commands/web.d.ts.map +1 -0
- package/dist/cli/commands/web.js +696 -0
- package/dist/cli/commands/web.js.map +1 -0
- package/dist/cli/fs-adapter.d.ts +656 -0
- package/dist/cli/fs-adapter.d.ts.map +1 -0
- package/dist/cli/fs-adapter.js +1179 -0
- package/dist/cli/fs-adapter.js.map +1 -0
- package/dist/cli/index.d.ts +387 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +523 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/ui/components/DiffView.d.ts +7 -0
- package/dist/cli/ui/components/DiffView.d.ts.map +1 -0
- package/dist/cli/ui/components/DiffView.js +11 -0
- package/dist/cli/ui/components/DiffView.js.map +1 -0
- package/dist/cli/ui/components/ErrorDisplay.d.ts +6 -0
- package/dist/cli/ui/components/ErrorDisplay.d.ts.map +1 -0
- package/dist/cli/ui/components/ErrorDisplay.js +11 -0
- package/dist/cli/ui/components/ErrorDisplay.js.map +1 -0
- package/dist/cli/ui/components/FuzzySearch.d.ts +9 -0
- package/dist/cli/ui/components/FuzzySearch.d.ts.map +1 -0
- package/dist/cli/ui/components/FuzzySearch.js +12 -0
- package/dist/cli/ui/components/FuzzySearch.js.map +1 -0
- package/dist/cli/ui/components/LoadingSpinner.d.ts +6 -0
- package/dist/cli/ui/components/LoadingSpinner.d.ts.map +1 -0
- package/dist/cli/ui/components/LoadingSpinner.js +10 -0
- package/dist/cli/ui/components/LoadingSpinner.js.map +1 -0
- package/dist/cli/ui/components/NavigationList.d.ts +9 -0
- package/dist/cli/ui/components/NavigationList.d.ts.map +1 -0
- package/dist/cli/ui/components/NavigationList.js +11 -0
- package/dist/cli/ui/components/NavigationList.js.map +1 -0
- package/dist/cli/ui/components/ScrollableContent.d.ts +8 -0
- package/dist/cli/ui/components/ScrollableContent.d.ts.map +1 -0
- package/dist/cli/ui/components/ScrollableContent.js +11 -0
- package/dist/cli/ui/components/ScrollableContent.js.map +1 -0
- package/dist/cli/ui/components/index.d.ts +7 -0
- package/dist/cli/ui/components/index.d.ts.map +1 -0
- package/dist/cli/ui/components/index.js +9 -0
- package/dist/cli/ui/components/index.js.map +1 -0
- package/dist/cli/ui/terminal-ui.d.ts +52 -0
- package/dist/cli/ui/terminal-ui.d.ts.map +1 -0
- package/dist/cli/ui/terminal-ui.js +121 -0
- package/dist/cli/ui/terminal-ui.js.map +1 -0
- package/dist/durable-object/object-store.d.ts +401 -23
- package/dist/durable-object/object-store.d.ts.map +1 -1
- package/dist/durable-object/object-store.js +414 -25
- package/dist/durable-object/object-store.js.map +1 -1
- package/dist/durable-object/schema.d.ts +188 -0
- package/dist/durable-object/schema.d.ts.map +1 -1
- package/dist/durable-object/schema.js +160 -0
- package/dist/durable-object/schema.js.map +1 -1
- package/dist/durable-object/wal.d.ts +336 -31
- package/dist/durable-object/wal.d.ts.map +1 -1
- package/dist/durable-object/wal.js +272 -27
- package/dist/durable-object/wal.js.map +1 -1
- package/dist/index.d.ts +379 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +379 -7
- package/dist/index.js.map +1 -1
- package/dist/mcp/adapter.d.ts +579 -38
- package/dist/mcp/adapter.d.ts.map +1 -1
- package/dist/mcp/adapter.js +426 -33
- package/dist/mcp/adapter.js.map +1 -1
- package/dist/mcp/sandbox.d.ts +532 -29
- package/dist/mcp/sandbox.d.ts.map +1 -1
- package/dist/mcp/sandbox.js +389 -22
- package/dist/mcp/sandbox.js.map +1 -1
- package/dist/mcp/sdk-adapter.d.ts +478 -56
- package/dist/mcp/sdk-adapter.d.ts.map +1 -1
- package/dist/mcp/sdk-adapter.js +346 -44
- package/dist/mcp/sdk-adapter.js.map +1 -1
- package/dist/mcp/tools.d.ts +445 -30
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +363 -33
- package/dist/mcp/tools.js.map +1 -1
- package/dist/ops/blame.d.ts +424 -21
- package/dist/ops/blame.d.ts.map +1 -1
- package/dist/ops/blame.js +303 -20
- package/dist/ops/blame.js.map +1 -1
- package/dist/ops/branch.d.ts +583 -32
- package/dist/ops/branch.d.ts.map +1 -1
- package/dist/ops/branch.js +365 -23
- package/dist/ops/branch.js.map +1 -1
- package/dist/ops/commit-traversal.d.ts +164 -24
- package/dist/ops/commit-traversal.d.ts.map +1 -1
- package/dist/ops/commit-traversal.js +68 -2
- package/dist/ops/commit-traversal.js.map +1 -1
- package/dist/ops/commit.d.ts +387 -53
- package/dist/ops/commit.d.ts.map +1 -1
- package/dist/ops/commit.js +249 -29
- package/dist/ops/commit.js.map +1 -1
- package/dist/ops/merge-base.d.ts +195 -21
- package/dist/ops/merge-base.d.ts.map +1 -1
- package/dist/ops/merge-base.js +122 -12
- package/dist/ops/merge-base.js.map +1 -1
- package/dist/ops/merge.d.ts +600 -130
- package/dist/ops/merge.d.ts.map +1 -1
- package/dist/ops/merge.js +408 -60
- package/dist/ops/merge.js.map +1 -1
- package/dist/ops/tag.d.ts +67 -2
- package/dist/ops/tag.d.ts.map +1 -1
- package/dist/ops/tag.js +42 -1
- package/dist/ops/tag.js.map +1 -1
- package/dist/ops/tree-builder.d.ts +102 -6
- package/dist/ops/tree-builder.d.ts.map +1 -1
- package/dist/ops/tree-builder.js +30 -5
- package/dist/ops/tree-builder.js.map +1 -1
- package/dist/ops/tree-diff.d.ts +50 -2
- package/dist/ops/tree-diff.d.ts.map +1 -1
- package/dist/ops/tree-diff.js +50 -2
- package/dist/ops/tree-diff.js.map +1 -1
- package/dist/pack/delta.d.ts +211 -39
- package/dist/pack/delta.d.ts.map +1 -1
- package/dist/pack/delta.js +232 -46
- package/dist/pack/delta.js.map +1 -1
- package/dist/pack/format.d.ts +390 -28
- package/dist/pack/format.d.ts.map +1 -1
- package/dist/pack/format.js +344 -33
- package/dist/pack/format.js.map +1 -1
- package/dist/pack/full-generation.d.ts +313 -28
- package/dist/pack/full-generation.d.ts.map +1 -1
- package/dist/pack/full-generation.js +238 -19
- package/dist/pack/full-generation.js.map +1 -1
- package/dist/pack/generation.d.ts +346 -23
- package/dist/pack/generation.d.ts.map +1 -1
- package/dist/pack/generation.js +269 -21
- package/dist/pack/generation.js.map +1 -1
- package/dist/pack/index.d.ts +407 -86
- package/dist/pack/index.d.ts.map +1 -1
- package/dist/pack/index.js +351 -70
- package/dist/pack/index.js.map +1 -1
- package/dist/refs/branch.d.ts +517 -71
- package/dist/refs/branch.d.ts.map +1 -1
- package/dist/refs/branch.js +410 -26
- package/dist/refs/branch.js.map +1 -1
- package/dist/refs/storage.d.ts +610 -57
- package/dist/refs/storage.d.ts.map +1 -1
- package/dist/refs/storage.js +481 -29
- package/dist/refs/storage.js.map +1 -1
- package/dist/refs/tag.d.ts +677 -67
- package/dist/refs/tag.d.ts.map +1 -1
- package/dist/refs/tag.js +497 -30
- package/dist/refs/tag.js.map +1 -1
- package/dist/storage/lru-cache.d.ts +556 -53
- package/dist/storage/lru-cache.d.ts.map +1 -1
- package/dist/storage/lru-cache.js +439 -36
- package/dist/storage/lru-cache.js.map +1 -1
- package/dist/storage/object-index.d.ts +483 -38
- package/dist/storage/object-index.d.ts.map +1 -1
- package/dist/storage/object-index.js +388 -22
- package/dist/storage/object-index.js.map +1 -1
- package/dist/storage/r2-pack.d.ts +957 -94
- package/dist/storage/r2-pack.d.ts.map +1 -1
- package/dist/storage/r2-pack.js +756 -48
- package/dist/storage/r2-pack.js.map +1 -1
- package/dist/tiered/cdc-pipeline.d.ts +1610 -38
- package/dist/tiered/cdc-pipeline.d.ts.map +1 -1
- package/dist/tiered/cdc-pipeline.js +1131 -22
- package/dist/tiered/cdc-pipeline.js.map +1 -1
- package/dist/tiered/migration.d.ts +903 -41
- package/dist/tiered/migration.d.ts.map +1 -1
- package/dist/tiered/migration.js +646 -24
- package/dist/tiered/migration.js.map +1 -1
- package/dist/tiered/parquet-writer.d.ts +944 -47
- package/dist/tiered/parquet-writer.d.ts.map +1 -1
- package/dist/tiered/parquet-writer.js +667 -39
- package/dist/tiered/parquet-writer.js.map +1 -1
- package/dist/tiered/read-path.d.ts +728 -34
- package/dist/tiered/read-path.d.ts.map +1 -1
- package/dist/tiered/read-path.js +310 -27
- package/dist/tiered/read-path.js.map +1 -1
- package/dist/types/objects.d.ts +457 -0
- package/dist/types/objects.d.ts.map +1 -1
- package/dist/types/objects.js +305 -4
- package/dist/types/objects.js.map +1 -1
- package/dist/types/storage.d.ts +407 -35
- package/dist/types/storage.d.ts.map +1 -1
- package/dist/types/storage.js +27 -3
- package/dist/types/storage.js.map +1 -1
- package/dist/utils/hash.d.ts +133 -12
- package/dist/utils/hash.d.ts.map +1 -1
- package/dist/utils/hash.js +133 -12
- package/dist/utils/hash.js.map +1 -1
- package/dist/utils/sha1.d.ts +102 -9
- package/dist/utils/sha1.d.ts.map +1 -1
- package/dist/utils/sha1.js +114 -11
- package/dist/utils/sha1.js.map +1 -1
- package/dist/wire/capabilities.d.ts +896 -88
- package/dist/wire/capabilities.d.ts.map +1 -1
- package/dist/wire/capabilities.js +566 -62
- package/dist/wire/capabilities.js.map +1 -1
- package/dist/wire/pkt-line.d.ts +293 -15
- package/dist/wire/pkt-line.d.ts.map +1 -1
- package/dist/wire/pkt-line.js +251 -15
- package/dist/wire/pkt-line.js.map +1 -1
- package/dist/wire/receive-pack.d.ts +814 -64
- package/dist/wire/receive-pack.d.ts.map +1 -1
- package/dist/wire/receive-pack.js +542 -41
- package/dist/wire/receive-pack.js.map +1 -1
- package/dist/wire/smart-http.d.ts +575 -97
- package/dist/wire/smart-http.d.ts.map +1 -1
- package/dist/wire/smart-http.js +337 -46
- package/dist/wire/smart-http.js.map +1 -1
- package/dist/wire/upload-pack.d.ts +492 -98
- package/dist/wire/upload-pack.d.ts.map +1 -1
- package/dist/wire/upload-pack.js +347 -59
- package/dist/wire/upload-pack.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lru-cache.d.ts","sourceRoot":"","sources":["../../src/storage/lru-cache.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"lru-cache.d.ts","sourceRoot":"","sources":["../../src/storage/lru-cache.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,106 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* LRU Cache
|
|
3
|
-
*
|
|
2
|
+
* @fileoverview LRU Cache Implementation for Hot Objects
|
|
3
|
+
*
|
|
4
|
+
* This module provides a high-performance Least Recently Used (LRU) cache
|
|
5
|
+
* implementation optimized for storing frequently accessed Git objects.
|
|
6
|
+
*
|
|
7
|
+
* ## Features
|
|
8
|
+
*
|
|
9
|
+
* - **Dual Limits**: Supports both count-based and byte-size-based limits
|
|
10
|
+
* - **TTL Support**: Optional time-to-live for automatic entry expiration
|
|
11
|
+
* - **Eviction Callbacks**: Hook into eviction events for cleanup or analytics
|
|
12
|
+
* - **Statistics Tracking**: Built-in hit/miss tracking and hit rate calculation
|
|
13
|
+
* - **O(1) Operations**: All get/set/delete operations are O(1) using a doubly linked list
|
|
14
|
+
*
|
|
15
|
+
* ## Implementation Details
|
|
16
|
+
*
|
|
17
|
+
* The cache uses a combination of:
|
|
18
|
+
* - A Map for O(1) key lookup
|
|
19
|
+
* - A doubly linked list for O(1) LRU ordering
|
|
20
|
+
*
|
|
21
|
+
* When the cache exceeds its limits, the least recently used items are evicted.
|
|
22
|
+
* Items can also be evicted due to TTL expiration.
|
|
23
|
+
*
|
|
24
|
+
* @module storage/lru-cache
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```typescript
|
|
28
|
+
* // Create a cache with 100 items max and 10MB size limit
|
|
29
|
+
* const cache = new LRUCache<string, Uint8Array>({
|
|
30
|
+
* maxCount: 100,
|
|
31
|
+
* maxBytes: 10 * 1024 * 1024,
|
|
32
|
+
* defaultTTL: 3600000, // 1 hour
|
|
33
|
+
* onEvict: (key, value, reason) => {
|
|
34
|
+
* console.log(`Evicted ${key}: ${reason}`);
|
|
35
|
+
* }
|
|
36
|
+
* });
|
|
37
|
+
*
|
|
38
|
+
* // Store and retrieve values
|
|
39
|
+
* cache.set('object-sha', objectData);
|
|
40
|
+
* const data = cache.get('object-sha');
|
|
41
|
+
*
|
|
42
|
+
* // Check statistics
|
|
43
|
+
* const stats = cache.getStats();
|
|
44
|
+
* console.log(`Hit rate: ${stats.hitRate}%`);
|
|
45
|
+
* ```
|
|
4
46
|
*/
|
|
5
47
|
/**
|
|
6
|
-
* LRU Cache class for storing hot objects with size and count limits
|
|
48
|
+
* LRU Cache class for storing hot objects with size and count limits.
|
|
49
|
+
*
|
|
50
|
+
* @description
|
|
51
|
+
* A high-performance Least Recently Used cache with the following features:
|
|
52
|
+
*
|
|
53
|
+
* - **O(1) Operations**: Get, set, and delete are all constant time
|
|
54
|
+
* - **Dual Limits**: Supports both count and byte-size limits
|
|
55
|
+
* - **TTL Support**: Optional per-entry or default time-to-live
|
|
56
|
+
* - **Eviction Events**: Callbacks when items are removed
|
|
57
|
+
* - **Statistics**: Track hits, misses, and evictions
|
|
58
|
+
*
|
|
59
|
+
* The cache maintains items in order of recent use. When the cache is full,
|
|
60
|
+
* the least recently used items are evicted first.
|
|
61
|
+
*
|
|
62
|
+
* ## Type Parameters
|
|
63
|
+
*
|
|
64
|
+
* - `K`: The type of cache keys (default: string)
|
|
65
|
+
* - `V`: The type of cached values (default: unknown)
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```typescript
|
|
69
|
+
* // Basic usage with string keys and Uint8Array values
|
|
70
|
+
* const objectCache = new LRUCache<string, Uint8Array>({
|
|
71
|
+
* maxCount: 1000,
|
|
72
|
+
* maxBytes: 100 * 1024 * 1024 // 100MB
|
|
73
|
+
* });
|
|
74
|
+
*
|
|
75
|
+
* // Store a value
|
|
76
|
+
* objectCache.set(sha, objectData);
|
|
77
|
+
*
|
|
78
|
+
* // Retrieve a value (returns undefined if not found or expired)
|
|
79
|
+
* const data = objectCache.get(sha);
|
|
80
|
+
*
|
|
81
|
+
* // Check without affecting LRU order
|
|
82
|
+
* if (objectCache.has(sha)) {
|
|
83
|
+
* const peeked = objectCache.peek(sha);
|
|
84
|
+
* }
|
|
85
|
+
*
|
|
86
|
+
* // Remove expired entries
|
|
87
|
+
* const pruned = objectCache.prune();
|
|
88
|
+
* console.log(`Removed ${pruned} expired entries`);
|
|
89
|
+
* ```
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* ```typescript
|
|
93
|
+
* // With eviction callback for cleanup
|
|
94
|
+
* const cache = new LRUCache<string, Resource>({
|
|
95
|
+
* maxCount: 100,
|
|
96
|
+
* onEvict: (key, value, reason) => {
|
|
97
|
+
* if (reason !== 'clear') {
|
|
98
|
+
* value.dispose(); // Clean up resources
|
|
99
|
+
* }
|
|
100
|
+
* console.log(`Evicted ${key}: ${reason}`);
|
|
101
|
+
* }
|
|
102
|
+
* });
|
|
103
|
+
* ```
|
|
7
104
|
*/
|
|
8
105
|
export class LRUCache {
|
|
9
106
|
cache = new Map();
|
|
@@ -19,8 +116,31 @@ export class LRUCache {
|
|
|
19
116
|
sizeCalculator;
|
|
20
117
|
onEvict;
|
|
21
118
|
/**
|
|
22
|
-
*
|
|
23
|
-
*
|
|
119
|
+
* Creates a new LRU cache instance.
|
|
120
|
+
*
|
|
121
|
+
* @description
|
|
122
|
+
* Initializes the cache with the specified options. All options have
|
|
123
|
+
* sensible defaults for unlimited caching.
|
|
124
|
+
*
|
|
125
|
+
* @param options - Configuration options for the cache
|
|
126
|
+
*
|
|
127
|
+
* @example
|
|
128
|
+
* ```typescript
|
|
129
|
+
* // Simple cache with count limit
|
|
130
|
+
* const cache = new LRUCache({ maxCount: 100 });
|
|
131
|
+
*
|
|
132
|
+
* // Cache with size limit and TTL
|
|
133
|
+
* const cache = new LRUCache({
|
|
134
|
+
* maxBytes: 50 * 1024 * 1024, // 50MB
|
|
135
|
+
* defaultTTL: 3600000 // 1 hour
|
|
136
|
+
* });
|
|
137
|
+
*
|
|
138
|
+
* // Cache with custom size calculator for Uint8Array
|
|
139
|
+
* const binaryCache = new LRUCache<string, Uint8Array>({
|
|
140
|
+
* maxBytes: 100 * 1024 * 1024,
|
|
141
|
+
* sizeCalculator: (arr) => arr.byteLength
|
|
142
|
+
* });
|
|
143
|
+
* ```
|
|
24
144
|
*/
|
|
25
145
|
constructor(options) {
|
|
26
146
|
this.maxCount = options?.maxCount ?? Infinity;
|
|
@@ -30,7 +150,12 @@ export class LRUCache {
|
|
|
30
150
|
this.onEvict = options?.onEvict;
|
|
31
151
|
}
|
|
32
152
|
/**
|
|
33
|
-
*
|
|
153
|
+
* Checks if an entry is expired.
|
|
154
|
+
*
|
|
155
|
+
* @param entry - The cache entry to check
|
|
156
|
+
* @returns true if the entry has expired
|
|
157
|
+
*
|
|
158
|
+
* @internal
|
|
34
159
|
*/
|
|
35
160
|
isExpired(entry) {
|
|
36
161
|
if (entry.expiresAt === null)
|
|
@@ -38,7 +163,11 @@ export class LRUCache {
|
|
|
38
163
|
return Date.now() > entry.expiresAt;
|
|
39
164
|
}
|
|
40
165
|
/**
|
|
41
|
-
*
|
|
166
|
+
* Moves a node to the head (most recently used position).
|
|
167
|
+
*
|
|
168
|
+
* @param node - The node to move
|
|
169
|
+
*
|
|
170
|
+
* @internal
|
|
42
171
|
*/
|
|
43
172
|
moveToHead(node) {
|
|
44
173
|
if (node === this.head)
|
|
@@ -57,7 +186,11 @@ export class LRUCache {
|
|
|
57
186
|
}
|
|
58
187
|
}
|
|
59
188
|
/**
|
|
60
|
-
*
|
|
189
|
+
* Removes a node from the linked list.
|
|
190
|
+
*
|
|
191
|
+
* @param node - The node to remove
|
|
192
|
+
*
|
|
193
|
+
* @internal
|
|
61
194
|
*/
|
|
62
195
|
removeNode(node) {
|
|
63
196
|
if (node.prev) {
|
|
@@ -74,7 +207,11 @@ export class LRUCache {
|
|
|
74
207
|
}
|
|
75
208
|
}
|
|
76
209
|
/**
|
|
77
|
-
*
|
|
210
|
+
* Adds a node to the head of the list.
|
|
211
|
+
*
|
|
212
|
+
* @param node - The node to add
|
|
213
|
+
*
|
|
214
|
+
* @internal
|
|
78
215
|
*/
|
|
79
216
|
addToHead(node) {
|
|
80
217
|
node.prev = null;
|
|
@@ -88,7 +225,11 @@ export class LRUCache {
|
|
|
88
225
|
}
|
|
89
226
|
}
|
|
90
227
|
/**
|
|
91
|
-
*
|
|
228
|
+
* Evicts items until the cache can accommodate a new item.
|
|
229
|
+
*
|
|
230
|
+
* @param requiredSize - Size in bytes needed for the new item
|
|
231
|
+
*
|
|
232
|
+
* @internal
|
|
92
233
|
*/
|
|
93
234
|
evictToFit(requiredSize) {
|
|
94
235
|
// Evict until we have room for the new item
|
|
@@ -105,9 +246,25 @@ export class LRUCache {
|
|
|
105
246
|
}
|
|
106
247
|
}
|
|
107
248
|
/**
|
|
108
|
-
*
|
|
109
|
-
*
|
|
249
|
+
* Gets a value from the cache.
|
|
250
|
+
*
|
|
251
|
+
* @description
|
|
252
|
+
* Retrieves a value by key. If the key exists and hasn't expired,
|
|
253
|
+
* returns the value and moves the entry to the most recently used position.
|
|
254
|
+
* If the key doesn't exist or has expired, returns undefined.
|
|
255
|
+
*
|
|
256
|
+
* @param key - The cache key to look up
|
|
257
|
+
*
|
|
110
258
|
* @returns The cached value or undefined if not found/expired
|
|
259
|
+
*
|
|
260
|
+
* @example
|
|
261
|
+
* ```typescript
|
|
262
|
+
* const cache = new LRUCache<string, string>();
|
|
263
|
+
* cache.set('greeting', 'hello');
|
|
264
|
+
*
|
|
265
|
+
* const value = cache.get('greeting'); // 'hello'
|
|
266
|
+
* const missing = cache.get('nonexistent'); // undefined
|
|
267
|
+
* ```
|
|
111
268
|
*/
|
|
112
269
|
get(key) {
|
|
113
270
|
const node = this.cache.get(key);
|
|
@@ -133,11 +290,40 @@ export class LRUCache {
|
|
|
133
290
|
return node.entry.value;
|
|
134
291
|
}
|
|
135
292
|
/**
|
|
136
|
-
*
|
|
137
|
-
*
|
|
138
|
-
* @
|
|
139
|
-
*
|
|
140
|
-
*
|
|
293
|
+
* Sets a value in the cache.
|
|
294
|
+
*
|
|
295
|
+
* @description
|
|
296
|
+
* Stores a value with the given key. If the key already exists,
|
|
297
|
+
* updates the value. If storing the value would exceed limits,
|
|
298
|
+
* evicts least recently used items first.
|
|
299
|
+
*
|
|
300
|
+
* Returns false if the value is larger than maxBytes (cannot fit).
|
|
301
|
+
*
|
|
302
|
+
* @param key - The cache key
|
|
303
|
+
* @param value - The value to cache
|
|
304
|
+
* @param options - Optional per-entry settings (TTL, size)
|
|
305
|
+
*
|
|
306
|
+
* @returns true if successfully stored, false if value too large
|
|
307
|
+
*
|
|
308
|
+
* @example
|
|
309
|
+
* ```typescript
|
|
310
|
+
* const cache = new LRUCache<string, Uint8Array>({
|
|
311
|
+
* maxBytes: 1024
|
|
312
|
+
* });
|
|
313
|
+
*
|
|
314
|
+
* // Basic set
|
|
315
|
+
* cache.set('key1', new Uint8Array([1, 2, 3]));
|
|
316
|
+
*
|
|
317
|
+
* // Set with custom TTL
|
|
318
|
+
* cache.set('key2', data, { ttl: 60000 }); // 1 minute
|
|
319
|
+
*
|
|
320
|
+
* // Set with explicit size
|
|
321
|
+
* cache.set('key3', complexObject, { size: 1000 });
|
|
322
|
+
*
|
|
323
|
+
* // Returns false if value too large
|
|
324
|
+
* const hugeData = new Uint8Array(10000);
|
|
325
|
+
* cache.set('huge', hugeData); // returns false
|
|
326
|
+
* ```
|
|
141
327
|
*/
|
|
142
328
|
set(key, value, options) {
|
|
143
329
|
const size = options?.size ?? this.sizeCalculator(value);
|
|
@@ -186,9 +372,23 @@ export class LRUCache {
|
|
|
186
372
|
return true;
|
|
187
373
|
}
|
|
188
374
|
/**
|
|
189
|
-
*
|
|
190
|
-
*
|
|
375
|
+
* Checks if a key exists in the cache.
|
|
376
|
+
*
|
|
377
|
+
* @description
|
|
378
|
+
* Returns true if the key exists and hasn't expired.
|
|
379
|
+
* Does NOT update LRU order (use peek() for that too).
|
|
380
|
+
*
|
|
381
|
+
* @param key - The cache key to check
|
|
382
|
+
*
|
|
191
383
|
* @returns true if the key exists and is not expired
|
|
384
|
+
*
|
|
385
|
+
* @example
|
|
386
|
+
* ```typescript
|
|
387
|
+
* if (cache.has('important-key')) {
|
|
388
|
+
* // Key exists and is valid
|
|
389
|
+
* const value = cache.get('important-key');
|
|
390
|
+
* }
|
|
391
|
+
* ```
|
|
192
392
|
*/
|
|
193
393
|
has(key) {
|
|
194
394
|
const node = this.cache.get(key);
|
|
@@ -199,9 +399,22 @@ export class LRUCache {
|
|
|
199
399
|
return true;
|
|
200
400
|
}
|
|
201
401
|
/**
|
|
202
|
-
*
|
|
203
|
-
*
|
|
402
|
+
* Deletes a key from the cache.
|
|
403
|
+
*
|
|
404
|
+
* @description
|
|
405
|
+
* Removes an entry from the cache. Triggers the onEvict callback
|
|
406
|
+
* with reason 'manual'.
|
|
407
|
+
*
|
|
408
|
+
* @param key - The cache key to delete
|
|
409
|
+
*
|
|
204
410
|
* @returns true if the key was deleted, false if it didn't exist
|
|
411
|
+
*
|
|
412
|
+
* @example
|
|
413
|
+
* ```typescript
|
|
414
|
+
* cache.set('key', 'value');
|
|
415
|
+
* cache.delete('key'); // returns true
|
|
416
|
+
* cache.delete('key'); // returns false (already deleted)
|
|
417
|
+
* ```
|
|
205
418
|
*/
|
|
206
419
|
delete(key) {
|
|
207
420
|
const node = this.cache.get(key);
|
|
@@ -216,7 +429,21 @@ export class LRUCache {
|
|
|
216
429
|
return true;
|
|
217
430
|
}
|
|
218
431
|
/**
|
|
219
|
-
*
|
|
432
|
+
* Clears all entries from the cache.
|
|
433
|
+
*
|
|
434
|
+
* @description
|
|
435
|
+
* Removes all entries and resets the byte counter. If an onEvict
|
|
436
|
+
* callback is configured, it's called for each entry with reason 'clear'.
|
|
437
|
+
*
|
|
438
|
+
* Does NOT reset statistics (use resetStats() for that).
|
|
439
|
+
*
|
|
440
|
+
* @example
|
|
441
|
+
* ```typescript
|
|
442
|
+
* cache.set('a', 1);
|
|
443
|
+
* cache.set('b', 2);
|
|
444
|
+
* cache.clear();
|
|
445
|
+
* console.log(cache.size); // 0
|
|
446
|
+
* ```
|
|
220
447
|
*/
|
|
221
448
|
clear() {
|
|
222
449
|
if (this.onEvict) {
|
|
@@ -231,8 +458,21 @@ export class LRUCache {
|
|
|
231
458
|
this._bytes = 0;
|
|
232
459
|
}
|
|
233
460
|
/**
|
|
234
|
-
*
|
|
461
|
+
* Gets cache statistics.
|
|
462
|
+
*
|
|
463
|
+
* @description
|
|
464
|
+
* Returns current statistics about cache performance including
|
|
465
|
+
* hits, misses, item count, byte usage, evictions, and hit rate.
|
|
466
|
+
*
|
|
235
467
|
* @returns Current cache statistics
|
|
468
|
+
*
|
|
469
|
+
* @example
|
|
470
|
+
* ```typescript
|
|
471
|
+
* const stats = cache.getStats();
|
|
472
|
+
* console.log(`Hit rate: ${stats.hitRate}%`);
|
|
473
|
+
* console.log(`Cache size: ${stats.count} items, ${stats.bytes} bytes`);
|
|
474
|
+
* console.log(`Evictions: ${stats.evictions}`);
|
|
475
|
+
* ```
|
|
236
476
|
*/
|
|
237
477
|
getStats() {
|
|
238
478
|
const total = this._hits + this._misses;
|
|
@@ -247,7 +487,18 @@ export class LRUCache {
|
|
|
247
487
|
};
|
|
248
488
|
}
|
|
249
489
|
/**
|
|
250
|
-
*
|
|
490
|
+
* Resets cache statistics.
|
|
491
|
+
*
|
|
492
|
+
* @description
|
|
493
|
+
* Resets hit, miss, and eviction counters to zero.
|
|
494
|
+
* Does NOT clear cached data.
|
|
495
|
+
*
|
|
496
|
+
* @example
|
|
497
|
+
* ```typescript
|
|
498
|
+
* // After warmup period, reset stats
|
|
499
|
+
* cache.resetStats();
|
|
500
|
+
* // Now stats reflect production traffic
|
|
501
|
+
* ```
|
|
251
502
|
*/
|
|
252
503
|
resetStats() {
|
|
253
504
|
this._hits = 0;
|
|
@@ -255,19 +506,47 @@ export class LRUCache {
|
|
|
255
506
|
this._evictions = 0;
|
|
256
507
|
}
|
|
257
508
|
/**
|
|
258
|
-
*
|
|
509
|
+
* Gets the number of items currently in the cache.
|
|
510
|
+
*
|
|
511
|
+
* @returns Current item count
|
|
512
|
+
*
|
|
513
|
+
* @example
|
|
514
|
+
* ```typescript
|
|
515
|
+
* console.log(`Cache has ${cache.size} items`);
|
|
516
|
+
* ```
|
|
259
517
|
*/
|
|
260
518
|
get size() {
|
|
261
519
|
return this.cache.size;
|
|
262
520
|
}
|
|
263
521
|
/**
|
|
264
|
-
*
|
|
522
|
+
* Gets the current byte size of the cache.
|
|
523
|
+
*
|
|
524
|
+
* @returns Current size in bytes
|
|
525
|
+
*
|
|
526
|
+
* @example
|
|
527
|
+
* ```typescript
|
|
528
|
+
* console.log(`Cache using ${cache.bytes} bytes`);
|
|
529
|
+
* ```
|
|
265
530
|
*/
|
|
266
531
|
get bytes() {
|
|
267
532
|
return this._bytes;
|
|
268
533
|
}
|
|
269
534
|
/**
|
|
270
|
-
*
|
|
535
|
+
* Gets all keys in the cache in LRU order.
|
|
536
|
+
*
|
|
537
|
+
* @description
|
|
538
|
+
* Returns keys from most recently used to least recently used.
|
|
539
|
+
* Does NOT affect LRU ordering.
|
|
540
|
+
*
|
|
541
|
+
* @returns Array of keys in LRU order (most recent first)
|
|
542
|
+
*
|
|
543
|
+
* @example
|
|
544
|
+
* ```typescript
|
|
545
|
+
* cache.set('a', 1);
|
|
546
|
+
* cache.set('b', 2);
|
|
547
|
+
* cache.get('a');
|
|
548
|
+
* console.log(cache.keys()); // ['a', 'b']
|
|
549
|
+
* ```
|
|
271
550
|
*/
|
|
272
551
|
keys() {
|
|
273
552
|
const keys = [];
|
|
@@ -279,7 +558,18 @@ export class LRUCache {
|
|
|
279
558
|
return keys;
|
|
280
559
|
}
|
|
281
560
|
/**
|
|
282
|
-
*
|
|
561
|
+
* Gets all values in the cache in LRU order.
|
|
562
|
+
*
|
|
563
|
+
* @description
|
|
564
|
+
* Returns values from most recently used to least recently used.
|
|
565
|
+
* Does NOT affect LRU ordering.
|
|
566
|
+
*
|
|
567
|
+
* @returns Array of values in LRU order (most recent first)
|
|
568
|
+
*
|
|
569
|
+
* @example
|
|
570
|
+
* ```typescript
|
|
571
|
+
* const recentValues = cache.values();
|
|
572
|
+
* ```
|
|
283
573
|
*/
|
|
284
574
|
values() {
|
|
285
575
|
const values = [];
|
|
@@ -291,7 +581,20 @@ export class LRUCache {
|
|
|
291
581
|
return values;
|
|
292
582
|
}
|
|
293
583
|
/**
|
|
294
|
-
*
|
|
584
|
+
* Gets all entries in the cache in LRU order.
|
|
585
|
+
*
|
|
586
|
+
* @description
|
|
587
|
+
* Returns [key, value] pairs from most recently used to least recently used.
|
|
588
|
+
* Does NOT affect LRU ordering.
|
|
589
|
+
*
|
|
590
|
+
* @returns Array of [key, value] pairs in LRU order
|
|
591
|
+
*
|
|
592
|
+
* @example
|
|
593
|
+
* ```typescript
|
|
594
|
+
* for (const [key, value] of cache.entries()) {
|
|
595
|
+
* console.log(`${key}: ${value}`);
|
|
596
|
+
* }
|
|
597
|
+
* ```
|
|
295
598
|
*/
|
|
296
599
|
entries() {
|
|
297
600
|
const entries = [];
|
|
@@ -303,9 +606,22 @@ export class LRUCache {
|
|
|
303
606
|
return entries;
|
|
304
607
|
}
|
|
305
608
|
/**
|
|
306
|
-
*
|
|
307
|
-
*
|
|
609
|
+
* Peeks at a value without updating LRU order.
|
|
610
|
+
*
|
|
611
|
+
* @description
|
|
612
|
+
* Retrieves a value without marking it as recently used.
|
|
613
|
+
* Useful for inspection or when you don't want to affect eviction order.
|
|
614
|
+
*
|
|
615
|
+
* @param key - The cache key to peek at
|
|
616
|
+
*
|
|
308
617
|
* @returns The cached value or undefined if not found/expired
|
|
618
|
+
*
|
|
619
|
+
* @example
|
|
620
|
+
* ```typescript
|
|
621
|
+
* // Check value without affecting LRU order
|
|
622
|
+
* const value = cache.peek('key');
|
|
623
|
+
* // This won't prevent 'key' from being evicted next
|
|
624
|
+
* ```
|
|
309
625
|
*/
|
|
310
626
|
peek(key) {
|
|
311
627
|
const node = this.cache.get(key);
|
|
@@ -316,8 +632,27 @@ export class LRUCache {
|
|
|
316
632
|
return node.entry.value;
|
|
317
633
|
}
|
|
318
634
|
/**
|
|
319
|
-
*
|
|
635
|
+
* Evicts expired entries from the cache.
|
|
636
|
+
*
|
|
637
|
+
* @description
|
|
638
|
+
* Scans all entries and removes those that have expired.
|
|
639
|
+
* Triggers onEvict callback with reason 'ttl' for each removed entry.
|
|
640
|
+
*
|
|
641
|
+
* Call this periodically if you need proactive cleanup of expired entries.
|
|
642
|
+
* Note: Expired entries are also cleaned up lazily on get().
|
|
643
|
+
*
|
|
320
644
|
* @returns Number of entries evicted
|
|
645
|
+
*
|
|
646
|
+
* @example
|
|
647
|
+
* ```typescript
|
|
648
|
+
* // Run periodic cleanup
|
|
649
|
+
* setInterval(() => {
|
|
650
|
+
* const pruned = cache.prune();
|
|
651
|
+
* if (pruned > 0) {
|
|
652
|
+
* console.log(`Pruned ${pruned} expired entries`);
|
|
653
|
+
* }
|
|
654
|
+
* }, 60000); // Every minute
|
|
655
|
+
* ```
|
|
321
656
|
*/
|
|
322
657
|
prune() {
|
|
323
658
|
let pruned = 0;
|
|
@@ -336,8 +671,22 @@ export class LRUCache {
|
|
|
336
671
|
return pruned;
|
|
337
672
|
}
|
|
338
673
|
/**
|
|
339
|
-
*
|
|
340
|
-
*
|
|
674
|
+
* Resizes the cache to new limits.
|
|
675
|
+
*
|
|
676
|
+
* @description
|
|
677
|
+
* Updates the maxCount and/or maxBytes limits. If the current cache
|
|
678
|
+
* exceeds the new limits, evicts LRU items until within limits.
|
|
679
|
+
*
|
|
680
|
+
* @param options - New size limits (maxCount and/or maxBytes)
|
|
681
|
+
*
|
|
682
|
+
* @example
|
|
683
|
+
* ```typescript
|
|
684
|
+
* // Reduce cache size under memory pressure
|
|
685
|
+
* cache.resize({ maxBytes: 10 * 1024 * 1024 }); // Reduce to 10MB
|
|
686
|
+
*
|
|
687
|
+
* // Increase limit when more memory is available
|
|
688
|
+
* cache.resize({ maxCount: 1000, maxBytes: 100 * 1024 * 1024 });
|
|
689
|
+
* ```
|
|
341
690
|
*/
|
|
342
691
|
resize(options) {
|
|
343
692
|
if (options.maxCount !== undefined) {
|
|
@@ -361,13 +710,67 @@ export class LRUCache {
|
|
|
361
710
|
}
|
|
362
711
|
}
|
|
363
712
|
/**
|
|
364
|
-
*
|
|
713
|
+
* Creates a key serializer for complex key types.
|
|
714
|
+
*
|
|
715
|
+
* @description
|
|
716
|
+
* Helper function for creating serializers when using complex key types
|
|
717
|
+
* that need to be converted to/from strings.
|
|
718
|
+
*
|
|
719
|
+
* @param serialize - Function to convert key to string
|
|
720
|
+
* @param deserialize - Function to convert string back to key
|
|
721
|
+
*
|
|
722
|
+
* @returns Object with serialize and deserialize functions
|
|
723
|
+
*
|
|
724
|
+
* @example
|
|
725
|
+
* ```typescript
|
|
726
|
+
* interface ObjectKey {
|
|
727
|
+
* repo: string;
|
|
728
|
+
* sha: string;
|
|
729
|
+
* }
|
|
730
|
+
*
|
|
731
|
+
* const keySerializer = createKeySerializer<ObjectKey>(
|
|
732
|
+
* (key) => `${key.repo}:${key.sha}`,
|
|
733
|
+
* (str) => {
|
|
734
|
+
* const [repo, sha] = str.split(':');
|
|
735
|
+
* return { repo, sha };
|
|
736
|
+
* }
|
|
737
|
+
* );
|
|
738
|
+
*
|
|
739
|
+
* // Use with cache
|
|
740
|
+
* const serializedKey = keySerializer.serialize({ repo: 'foo', sha: 'abc' });
|
|
741
|
+
* cache.set(serializedKey, value);
|
|
742
|
+
* ```
|
|
365
743
|
*/
|
|
366
744
|
export function createKeySerializer(serialize, deserialize) {
|
|
367
745
|
return { serialize, deserialize };
|
|
368
746
|
}
|
|
369
747
|
/**
|
|
370
|
-
* Default size calculator for common value types
|
|
748
|
+
* Default size calculator for common value types.
|
|
749
|
+
*
|
|
750
|
+
* @description
|
|
751
|
+
* Estimates the byte size of common JavaScript value types:
|
|
752
|
+
* - `null/undefined`: 0 bytes
|
|
753
|
+
* - `string`: 2 bytes per character (UTF-16)
|
|
754
|
+
* - `number`: 8 bytes
|
|
755
|
+
* - `boolean`: 4 bytes
|
|
756
|
+
* - `Uint8Array/ArrayBuffer`: actual byteLength
|
|
757
|
+
* - `object`: JSON-serialized length * 2
|
|
758
|
+
* - `unknown`: 8 bytes (default)
|
|
759
|
+
*
|
|
760
|
+
* For more accurate size calculation with specific types,
|
|
761
|
+
* provide a custom sizeCalculator in CacheOptions.
|
|
762
|
+
*
|
|
763
|
+
* @param value - The value to calculate size for
|
|
764
|
+
*
|
|
765
|
+
* @returns Estimated size in bytes
|
|
766
|
+
*
|
|
767
|
+
* @example
|
|
768
|
+
* ```typescript
|
|
769
|
+
* defaultSizeCalculator('hello'); // 10 (5 chars * 2)
|
|
770
|
+
* defaultSizeCalculator(42); // 8
|
|
771
|
+
* defaultSizeCalculator(new Uint8Array(100)); // 100
|
|
772
|
+
* defaultSizeCalculator({ key: 'value' }); // ~30
|
|
773
|
+
* ```
|
|
371
774
|
*/
|
|
372
775
|
export function defaultSizeCalculator(value) {
|
|
373
776
|
if (value === null || value === undefined) {
|