driftdetect-core 0.1.0

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.
Files changed (221) hide show
  1. package/dist/analyzers/ast-analyzer.d.ts +251 -0
  2. package/dist/analyzers/ast-analyzer.d.ts.map +1 -0
  3. package/dist/analyzers/ast-analyzer.js +548 -0
  4. package/dist/analyzers/ast-analyzer.js.map +1 -0
  5. package/dist/analyzers/flow-analyzer.d.ts +241 -0
  6. package/dist/analyzers/flow-analyzer.d.ts.map +1 -0
  7. package/dist/analyzers/flow-analyzer.js +1219 -0
  8. package/dist/analyzers/flow-analyzer.js.map +1 -0
  9. package/dist/analyzers/index.d.ts +18 -0
  10. package/dist/analyzers/index.d.ts.map +1 -0
  11. package/dist/analyzers/index.js +19 -0
  12. package/dist/analyzers/index.js.map +1 -0
  13. package/dist/analyzers/semantic-analyzer.d.ts +252 -0
  14. package/dist/analyzers/semantic-analyzer.d.ts.map +1 -0
  15. package/dist/analyzers/semantic-analyzer.js +1182 -0
  16. package/dist/analyzers/semantic-analyzer.js.map +1 -0
  17. package/dist/analyzers/type-analyzer.d.ts +289 -0
  18. package/dist/analyzers/type-analyzer.d.ts.map +1 -0
  19. package/dist/analyzers/type-analyzer.js +1269 -0
  20. package/dist/analyzers/type-analyzer.js.map +1 -0
  21. package/dist/analyzers/types.d.ts +537 -0
  22. package/dist/analyzers/types.d.ts.map +1 -0
  23. package/dist/analyzers/types.js +11 -0
  24. package/dist/analyzers/types.js.map +1 -0
  25. package/dist/config/config-loader.d.ts +166 -0
  26. package/dist/config/config-loader.d.ts.map +1 -0
  27. package/dist/config/config-loader.js +429 -0
  28. package/dist/config/config-loader.js.map +1 -0
  29. package/dist/config/config-validator.d.ts +204 -0
  30. package/dist/config/config-validator.d.ts.map +1 -0
  31. package/dist/config/config-validator.js +632 -0
  32. package/dist/config/config-validator.js.map +1 -0
  33. package/dist/config/defaults.d.ts +8 -0
  34. package/dist/config/defaults.d.ts.map +1 -0
  35. package/dist/config/defaults.js +26 -0
  36. package/dist/config/defaults.js.map +1 -0
  37. package/dist/config/index.d.ts +10 -0
  38. package/dist/config/index.d.ts.map +1 -0
  39. package/dist/config/index.js +10 -0
  40. package/dist/config/index.js.map +1 -0
  41. package/dist/config/types.d.ts +47 -0
  42. package/dist/config/types.d.ts.map +1 -0
  43. package/dist/config/types.js +7 -0
  44. package/dist/config/types.js.map +1 -0
  45. package/dist/index.d.ts +37 -0
  46. package/dist/index.d.ts.map +1 -0
  47. package/dist/index.js +39 -0
  48. package/dist/index.js.map +1 -0
  49. package/dist/manifest/exporter.d.ts +21 -0
  50. package/dist/manifest/exporter.d.ts.map +1 -0
  51. package/dist/manifest/exporter.js +339 -0
  52. package/dist/manifest/exporter.js.map +1 -0
  53. package/dist/manifest/index.d.ts +14 -0
  54. package/dist/manifest/index.d.ts.map +1 -0
  55. package/dist/manifest/index.js +15 -0
  56. package/dist/manifest/index.js.map +1 -0
  57. package/dist/manifest/manifest-store.d.ts +111 -0
  58. package/dist/manifest/manifest-store.d.ts.map +1 -0
  59. package/dist/manifest/manifest-store.js +418 -0
  60. package/dist/manifest/manifest-store.js.map +1 -0
  61. package/dist/manifest/types.d.ts +238 -0
  62. package/dist/manifest/types.d.ts.map +1 -0
  63. package/dist/manifest/types.js +11 -0
  64. package/dist/manifest/types.js.map +1 -0
  65. package/dist/matcher/confidence-scorer.d.ts +188 -0
  66. package/dist/matcher/confidence-scorer.d.ts.map +1 -0
  67. package/dist/matcher/confidence-scorer.js +302 -0
  68. package/dist/matcher/confidence-scorer.js.map +1 -0
  69. package/dist/matcher/index.d.ts +24 -0
  70. package/dist/matcher/index.d.ts.map +1 -0
  71. package/dist/matcher/index.js +26 -0
  72. package/dist/matcher/index.js.map +1 -0
  73. package/dist/matcher/outlier-detector.d.ts +252 -0
  74. package/dist/matcher/outlier-detector.d.ts.map +1 -0
  75. package/dist/matcher/outlier-detector.js +544 -0
  76. package/dist/matcher/outlier-detector.js.map +1 -0
  77. package/dist/matcher/pattern-matcher.d.ts +169 -0
  78. package/dist/matcher/pattern-matcher.d.ts.map +1 -0
  79. package/dist/matcher/pattern-matcher.js +692 -0
  80. package/dist/matcher/pattern-matcher.js.map +1 -0
  81. package/dist/matcher/types.d.ts +476 -0
  82. package/dist/matcher/types.d.ts.map +1 -0
  83. package/dist/matcher/types.js +36 -0
  84. package/dist/matcher/types.js.map +1 -0
  85. package/dist/parsers/base-parser.d.ts +282 -0
  86. package/dist/parsers/base-parser.d.ts.map +1 -0
  87. package/dist/parsers/base-parser.js +421 -0
  88. package/dist/parsers/base-parser.js.map +1 -0
  89. package/dist/parsers/css-parser.d.ts +225 -0
  90. package/dist/parsers/css-parser.d.ts.map +1 -0
  91. package/dist/parsers/css-parser.js +477 -0
  92. package/dist/parsers/css-parser.js.map +1 -0
  93. package/dist/parsers/index.d.ts +15 -0
  94. package/dist/parsers/index.d.ts.map +1 -0
  95. package/dist/parsers/index.js +15 -0
  96. package/dist/parsers/index.js.map +1 -0
  97. package/dist/parsers/json-parser.d.ts +219 -0
  98. package/dist/parsers/json-parser.d.ts.map +1 -0
  99. package/dist/parsers/json-parser.js +602 -0
  100. package/dist/parsers/json-parser.js.map +1 -0
  101. package/dist/parsers/markdown-parser.d.ts +276 -0
  102. package/dist/parsers/markdown-parser.d.ts.map +1 -0
  103. package/dist/parsers/markdown-parser.js +731 -0
  104. package/dist/parsers/markdown-parser.js.map +1 -0
  105. package/dist/parsers/parser-manager.d.ts +294 -0
  106. package/dist/parsers/parser-manager.d.ts.map +1 -0
  107. package/dist/parsers/parser-manager.js +738 -0
  108. package/dist/parsers/parser-manager.js.map +1 -0
  109. package/dist/parsers/python-parser.d.ts +204 -0
  110. package/dist/parsers/python-parser.d.ts.map +1 -0
  111. package/dist/parsers/python-parser.js +517 -0
  112. package/dist/parsers/python-parser.js.map +1 -0
  113. package/dist/parsers/types.d.ts +43 -0
  114. package/dist/parsers/types.d.ts.map +1 -0
  115. package/dist/parsers/types.js +7 -0
  116. package/dist/parsers/types.js.map +1 -0
  117. package/dist/parsers/typescript-parser.d.ts +264 -0
  118. package/dist/parsers/typescript-parser.d.ts.map +1 -0
  119. package/dist/parsers/typescript-parser.js +658 -0
  120. package/dist/parsers/typescript-parser.js.map +1 -0
  121. package/dist/rules/evaluator.d.ts +305 -0
  122. package/dist/rules/evaluator.d.ts.map +1 -0
  123. package/dist/rules/evaluator.js +579 -0
  124. package/dist/rules/evaluator.js.map +1 -0
  125. package/dist/rules/index.d.ts +13 -0
  126. package/dist/rules/index.d.ts.map +1 -0
  127. package/dist/rules/index.js +13 -0
  128. package/dist/rules/index.js.map +1 -0
  129. package/dist/rules/quick-fix-generator.d.ts +334 -0
  130. package/dist/rules/quick-fix-generator.d.ts.map +1 -0
  131. package/dist/rules/quick-fix-generator.js +1075 -0
  132. package/dist/rules/quick-fix-generator.js.map +1 -0
  133. package/dist/rules/rule-engine.d.ts +241 -0
  134. package/dist/rules/rule-engine.d.ts.map +1 -0
  135. package/dist/rules/rule-engine.js +585 -0
  136. package/dist/rules/rule-engine.js.map +1 -0
  137. package/dist/rules/severity-manager.d.ts +394 -0
  138. package/dist/rules/severity-manager.d.ts.map +1 -0
  139. package/dist/rules/severity-manager.js +619 -0
  140. package/dist/rules/severity-manager.js.map +1 -0
  141. package/dist/rules/types.d.ts +370 -0
  142. package/dist/rules/types.d.ts.map +1 -0
  143. package/dist/rules/types.js +133 -0
  144. package/dist/rules/types.js.map +1 -0
  145. package/dist/rules/variant-manager.d.ts +388 -0
  146. package/dist/rules/variant-manager.d.ts.map +1 -0
  147. package/dist/rules/variant-manager.js +777 -0
  148. package/dist/rules/variant-manager.js.map +1 -0
  149. package/dist/scanner/change-detector.d.ts +164 -0
  150. package/dist/scanner/change-detector.d.ts.map +1 -0
  151. package/dist/scanner/change-detector.js +263 -0
  152. package/dist/scanner/change-detector.js.map +1 -0
  153. package/dist/scanner/dependency-graph.d.ts +270 -0
  154. package/dist/scanner/dependency-graph.d.ts.map +1 -0
  155. package/dist/scanner/dependency-graph.js +436 -0
  156. package/dist/scanner/dependency-graph.js.map +1 -0
  157. package/dist/scanner/file-walker.d.ts +127 -0
  158. package/dist/scanner/file-walker.d.ts.map +1 -0
  159. package/dist/scanner/file-walker.js +526 -0
  160. package/dist/scanner/file-walker.js.map +1 -0
  161. package/dist/scanner/index.d.ts +12 -0
  162. package/dist/scanner/index.d.ts.map +1 -0
  163. package/dist/scanner/index.js +12 -0
  164. package/dist/scanner/index.js.map +1 -0
  165. package/dist/scanner/types.d.ts +218 -0
  166. package/dist/scanner/types.d.ts.map +1 -0
  167. package/dist/scanner/types.js +10 -0
  168. package/dist/scanner/types.js.map +1 -0
  169. package/dist/scanner/worker-pool.d.ts +317 -0
  170. package/dist/scanner/worker-pool.d.ts.map +1 -0
  171. package/dist/scanner/worker-pool.js +571 -0
  172. package/dist/scanner/worker-pool.js.map +1 -0
  173. package/dist/store/cache-manager.d.ts +179 -0
  174. package/dist/store/cache-manager.d.ts.map +1 -0
  175. package/dist/store/cache-manager.js +391 -0
  176. package/dist/store/cache-manager.js.map +1 -0
  177. package/dist/store/history-store.d.ts +314 -0
  178. package/dist/store/history-store.d.ts.map +1 -0
  179. package/dist/store/history-store.js +707 -0
  180. package/dist/store/history-store.js.map +1 -0
  181. package/dist/store/index.d.ts +20 -0
  182. package/dist/store/index.d.ts.map +1 -0
  183. package/dist/store/index.js +26 -0
  184. package/dist/store/index.js.map +1 -0
  185. package/dist/store/lock-file-manager.d.ts +202 -0
  186. package/dist/store/lock-file-manager.d.ts.map +1 -0
  187. package/dist/store/lock-file-manager.js +475 -0
  188. package/dist/store/lock-file-manager.js.map +1 -0
  189. package/dist/store/pattern-store.d.ts +289 -0
  190. package/dist/store/pattern-store.d.ts.map +1 -0
  191. package/dist/store/pattern-store.js +936 -0
  192. package/dist/store/pattern-store.js.map +1 -0
  193. package/dist/store/schema-validator.d.ts +159 -0
  194. package/dist/store/schema-validator.d.ts.map +1 -0
  195. package/dist/store/schema-validator.js +1096 -0
  196. package/dist/store/schema-validator.js.map +1 -0
  197. package/dist/store/types.d.ts +585 -0
  198. package/dist/store/types.d.ts.map +1 -0
  199. package/dist/store/types.js +82 -0
  200. package/dist/store/types.js.map +1 -0
  201. package/dist/types/analysis.d.ts +19 -0
  202. package/dist/types/analysis.d.ts.map +1 -0
  203. package/dist/types/analysis.js +5 -0
  204. package/dist/types/analysis.js.map +1 -0
  205. package/dist/types/common.d.ts +7 -0
  206. package/dist/types/common.d.ts.map +1 -0
  207. package/dist/types/common.js +5 -0
  208. package/dist/types/common.js.map +1 -0
  209. package/dist/types/index.d.ts +12 -0
  210. package/dist/types/index.d.ts.map +1 -0
  211. package/dist/types/index.js +10 -0
  212. package/dist/types/index.js.map +1 -0
  213. package/dist/types/patterns.d.ts +40 -0
  214. package/dist/types/patterns.d.ts.map +1 -0
  215. package/dist/types/patterns.js +7 -0
  216. package/dist/types/patterns.js.map +1 -0
  217. package/dist/types/violations.d.ts +7 -0
  218. package/dist/types/violations.d.ts.map +1 -0
  219. package/dist/types/violations.js +7 -0
  220. package/dist/types/violations.js.map +1 -0
  221. package/package.json +46 -0
@@ -0,0 +1,179 @@
1
+ /**
2
+ * Cache Manager - Analysis result caching
3
+ *
4
+ * LRU cache for analysis results with file hash-based keys.
5
+ * Handles cache invalidation on file changes.
6
+ *
7
+ * @requirements 2.5 - THE Scanner SHALL cache analysis results using file content hashes
8
+ */
9
+ /**
10
+ * Configuration options for the CacheManager
11
+ */
12
+ export interface CacheManagerOptions {
13
+ /** Maximum number of entries in the cache (default: 1000) */
14
+ maxSize: number;
15
+ /** Time-to-live in milliseconds (default: 1 hour, 0 = no expiry) */
16
+ ttl: number;
17
+ /** Path to persist cache to disk (optional) */
18
+ persistPath?: string;
19
+ /** Whether to enable statistics tracking (default: true) */
20
+ enableStats: boolean;
21
+ }
22
+ /**
23
+ * A single cache entry with metadata
24
+ */
25
+ export interface CacheEntry<T> {
26
+ /** The cached value */
27
+ value: T;
28
+ /** File content hash used as key */
29
+ hash: string;
30
+ /** Timestamp when entry was created */
31
+ timestamp: number;
32
+ /** Number of times this entry has been accessed */
33
+ hits: number;
34
+ /** Size estimate in bytes (for memory tracking) */
35
+ size: number;
36
+ }
37
+ /**
38
+ * Cache statistics for monitoring
39
+ */
40
+ export interface CacheStats {
41
+ /** Total number of cache hits */
42
+ hits: number;
43
+ /** Total number of cache misses */
44
+ misses: number;
45
+ /** Total number of evictions due to size limit */
46
+ evictions: number;
47
+ /** Total number of expirations due to TTL */
48
+ expirations: number;
49
+ /** Current number of entries in cache */
50
+ size: number;
51
+ /** Maximum size of cache */
52
+ maxSize: number;
53
+ /** Cache hit ratio (hits / (hits + misses)) */
54
+ hitRatio: number;
55
+ }
56
+ /**
57
+ * LRU Cache Manager for analysis results
58
+ *
59
+ * Implements a Least Recently Used (LRU) eviction strategy with:
60
+ * - File hash-based cache keys
61
+ * - Configurable maximum size
62
+ * - Optional TTL-based expiration
63
+ * - Statistics tracking (hits, misses, evictions)
64
+ * - Optional persistence to disk
65
+ */
66
+ export declare class CacheManager<T = unknown> {
67
+ private readonly options;
68
+ private readonly cache;
69
+ private head;
70
+ private tail;
71
+ private stats;
72
+ constructor(options?: Partial<CacheManagerOptions>);
73
+ /**
74
+ * Get a value from the cache by its hash key
75
+ *
76
+ * @param hash - The file content hash to look up
77
+ * @returns The cached value or undefined if not found/expired
78
+ */
79
+ get(hash: string): T | undefined;
80
+ /**
81
+ * Store a value in the cache with the given hash key
82
+ *
83
+ * @param hash - The file content hash to use as key
84
+ * @param value - The value to cache
85
+ * @param size - Optional size estimate in bytes
86
+ */
87
+ set(hash: string, value: T, size?: number): void;
88
+ /**
89
+ * Check if a hash key exists in the cache (without updating LRU order)
90
+ *
91
+ * @param hash - The file content hash to check
92
+ * @returns True if the key exists and is not expired
93
+ */
94
+ has(hash: string): boolean;
95
+ /**
96
+ * Delete an entry from the cache
97
+ *
98
+ * @param hash - The file content hash to delete
99
+ * @returns True if the entry was deleted, false if not found
100
+ */
101
+ delete(hash: string): boolean;
102
+ /**
103
+ * Clear all entries from the cache
104
+ */
105
+ clear(): void;
106
+ /**
107
+ * Get the current cache statistics
108
+ *
109
+ * @returns Current cache statistics
110
+ */
111
+ getStats(): CacheStats;
112
+ /**
113
+ * Reset cache statistics
114
+ */
115
+ resetStats(): void;
116
+ /**
117
+ * Get all cache entries (for debugging/persistence)
118
+ *
119
+ * @returns Array of all cache entries
120
+ */
121
+ entries(): Array<{
122
+ key: string;
123
+ entry: CacheEntry<T>;
124
+ }>;
125
+ /**
126
+ * Get the current size of the cache
127
+ *
128
+ * @returns Number of entries in the cache
129
+ */
130
+ get size(): number;
131
+ /**
132
+ * Compute a SHA-256 hash of file content
133
+ *
134
+ * @param content - The file content to hash
135
+ * @returns The hex-encoded SHA-256 hash
136
+ */
137
+ static computeHash(content: string | Buffer): string;
138
+ /**
139
+ * Compute a SHA-256 hash of a file on disk
140
+ *
141
+ * @param filePath - Path to the file
142
+ * @returns The hex-encoded SHA-256 hash
143
+ */
144
+ static computeFileHash(filePath: string): Promise<string>;
145
+ /**
146
+ * Persist the cache to disk
147
+ *
148
+ * @param filePath - Path to save the cache (uses options.persistPath if not provided)
149
+ */
150
+ persist(filePath?: string): Promise<void>;
151
+ /**
152
+ * Load the cache from disk
153
+ *
154
+ * @param filePath - Path to load the cache from (uses options.persistPath if not provided)
155
+ */
156
+ load(filePath?: string): Promise<void>;
157
+ /**
158
+ * Invalidate cache entries for a specific file and its dependents
159
+ *
160
+ * @param hash - The hash of the file that changed
161
+ * @param dependentHashes - Hashes of files that depend on the changed file
162
+ * @returns Number of entries invalidated
163
+ */
164
+ invalidate(hash: string, dependentHashes?: string[]): number;
165
+ /**
166
+ * Prune expired entries from the cache
167
+ *
168
+ * @returns Number of entries pruned
169
+ */
170
+ prune(): number;
171
+ private isExpired;
172
+ private isExpiredAt;
173
+ private addToFront;
174
+ private removeFromList;
175
+ private moveToFront;
176
+ private evictLRU;
177
+ private updateHitRatio;
178
+ }
179
+ //# sourceMappingURL=cache-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache-manager.d.ts","sourceRoot":"","sources":["../../src/store/cache-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,391 @@
1
+ /**
2
+ * Cache Manager - Analysis result caching
3
+ *
4
+ * LRU cache for analysis results with file hash-based keys.
5
+ * Handles cache invalidation on file changes.
6
+ *
7
+ * @requirements 2.5 - THE Scanner SHALL cache analysis results using file content hashes
8
+ */
9
+ import * as fs from 'node:fs/promises';
10
+ import * as path from 'node:path';
11
+ import * as crypto from 'node:crypto';
12
+ const DEFAULT_OPTIONS = {
13
+ maxSize: 1000,
14
+ ttl: 3600000, // 1 hour
15
+ enableStats: true,
16
+ };
17
+ /**
18
+ * LRU Cache Manager for analysis results
19
+ *
20
+ * Implements a Least Recently Used (LRU) eviction strategy with:
21
+ * - File hash-based cache keys
22
+ * - Configurable maximum size
23
+ * - Optional TTL-based expiration
24
+ * - Statistics tracking (hits, misses, evictions)
25
+ * - Optional persistence to disk
26
+ */
27
+ export class CacheManager {
28
+ options;
29
+ cache;
30
+ head = null;
31
+ tail = null;
32
+ stats;
33
+ constructor(options = {}) {
34
+ this.options = { ...DEFAULT_OPTIONS, ...options };
35
+ this.cache = new Map();
36
+ this.stats = {
37
+ hits: 0,
38
+ misses: 0,
39
+ evictions: 0,
40
+ expirations: 0,
41
+ size: 0,
42
+ maxSize: this.options.maxSize,
43
+ hitRatio: 0,
44
+ };
45
+ }
46
+ /**
47
+ * Get a value from the cache by its hash key
48
+ *
49
+ * @param hash - The file content hash to look up
50
+ * @returns The cached value or undefined if not found/expired
51
+ */
52
+ get(hash) {
53
+ const node = this.cache.get(hash);
54
+ if (!node) {
55
+ if (this.options.enableStats) {
56
+ this.stats.misses++;
57
+ this.updateHitRatio();
58
+ }
59
+ return undefined;
60
+ }
61
+ // Check TTL expiration
62
+ if (this.isExpired(node.entry)) {
63
+ this.delete(hash);
64
+ if (this.options.enableStats) {
65
+ this.stats.misses++;
66
+ this.stats.expirations++;
67
+ this.updateHitRatio();
68
+ }
69
+ return undefined;
70
+ }
71
+ // Move to front (most recently used)
72
+ this.moveToFront(node);
73
+ // Update stats
74
+ if (this.options.enableStats) {
75
+ node.entry.hits++;
76
+ this.stats.hits++;
77
+ this.updateHitRatio();
78
+ }
79
+ return node.entry.value;
80
+ }
81
+ /**
82
+ * Store a value in the cache with the given hash key
83
+ *
84
+ * @param hash - The file content hash to use as key
85
+ * @param value - The value to cache
86
+ * @param size - Optional size estimate in bytes
87
+ */
88
+ set(hash, value, size = 0) {
89
+ // Check if key already exists
90
+ const existingNode = this.cache.get(hash);
91
+ if (existingNode) {
92
+ // Update existing entry
93
+ existingNode.entry.value = value;
94
+ existingNode.entry.timestamp = Date.now();
95
+ existingNode.entry.size = size;
96
+ this.moveToFront(existingNode);
97
+ return;
98
+ }
99
+ // Evict if at capacity
100
+ while (this.cache.size >= this.options.maxSize) {
101
+ this.evictLRU();
102
+ }
103
+ // Create new entry
104
+ const entry = {
105
+ value,
106
+ hash,
107
+ timestamp: Date.now(),
108
+ hits: 0,
109
+ size,
110
+ };
111
+ const node = {
112
+ key: hash,
113
+ entry,
114
+ prev: null,
115
+ next: null,
116
+ };
117
+ // Add to cache and front of list
118
+ this.cache.set(hash, node);
119
+ this.addToFront(node);
120
+ this.stats.size = this.cache.size;
121
+ }
122
+ /**
123
+ * Check if a hash key exists in the cache (without updating LRU order)
124
+ *
125
+ * @param hash - The file content hash to check
126
+ * @returns True if the key exists and is not expired
127
+ */
128
+ has(hash) {
129
+ const node = this.cache.get(hash);
130
+ if (!node) {
131
+ return false;
132
+ }
133
+ // Check TTL expiration
134
+ if (this.isExpired(node.entry)) {
135
+ this.delete(hash);
136
+ if (this.options.enableStats) {
137
+ this.stats.expirations++;
138
+ }
139
+ return false;
140
+ }
141
+ return true;
142
+ }
143
+ /**
144
+ * Delete an entry from the cache
145
+ *
146
+ * @param hash - The file content hash to delete
147
+ * @returns True if the entry was deleted, false if not found
148
+ */
149
+ delete(hash) {
150
+ const node = this.cache.get(hash);
151
+ if (!node) {
152
+ return false;
153
+ }
154
+ this.removeFromList(node);
155
+ this.cache.delete(hash);
156
+ this.stats.size = this.cache.size;
157
+ return true;
158
+ }
159
+ /**
160
+ * Clear all entries from the cache
161
+ */
162
+ clear() {
163
+ this.cache.clear();
164
+ this.head = null;
165
+ this.tail = null;
166
+ this.stats.size = 0;
167
+ }
168
+ /**
169
+ * Get the current cache statistics
170
+ *
171
+ * @returns Current cache statistics
172
+ */
173
+ getStats() {
174
+ return { ...this.stats };
175
+ }
176
+ /**
177
+ * Reset cache statistics
178
+ */
179
+ resetStats() {
180
+ this.stats = {
181
+ hits: 0,
182
+ misses: 0,
183
+ evictions: 0,
184
+ expirations: 0,
185
+ size: this.cache.size,
186
+ maxSize: this.options.maxSize,
187
+ hitRatio: 0,
188
+ };
189
+ }
190
+ /**
191
+ * Get all cache entries (for debugging/persistence)
192
+ *
193
+ * @returns Array of all cache entries
194
+ */
195
+ entries() {
196
+ const result = [];
197
+ for (const [key, node] of this.cache) {
198
+ if (!this.isExpired(node.entry)) {
199
+ result.push({ key, entry: node.entry });
200
+ }
201
+ }
202
+ return result;
203
+ }
204
+ /**
205
+ * Get the current size of the cache
206
+ *
207
+ * @returns Number of entries in the cache
208
+ */
209
+ get size() {
210
+ return this.cache.size;
211
+ }
212
+ /**
213
+ * Compute a SHA-256 hash of file content
214
+ *
215
+ * @param content - The file content to hash
216
+ * @returns The hex-encoded SHA-256 hash
217
+ */
218
+ static computeHash(content) {
219
+ return crypto.createHash('sha256').update(content).digest('hex');
220
+ }
221
+ /**
222
+ * Compute a SHA-256 hash of a file on disk
223
+ *
224
+ * @param filePath - Path to the file
225
+ * @returns The hex-encoded SHA-256 hash
226
+ */
227
+ static async computeFileHash(filePath) {
228
+ const content = await fs.readFile(filePath);
229
+ return CacheManager.computeHash(content);
230
+ }
231
+ /**
232
+ * Persist the cache to disk
233
+ *
234
+ * @param filePath - Path to save the cache (uses options.persistPath if not provided)
235
+ */
236
+ async persist(filePath) {
237
+ const targetPath = filePath ?? this.options.persistPath;
238
+ if (!targetPath) {
239
+ throw new Error('No persist path specified');
240
+ }
241
+ const persistedCache = {
242
+ version: '1.0.0',
243
+ createdAt: new Date().toISOString(),
244
+ entries: this.entries(),
245
+ };
246
+ // Ensure directory exists
247
+ await fs.mkdir(path.dirname(targetPath), { recursive: true });
248
+ await fs.writeFile(targetPath, JSON.stringify(persistedCache, null, 2));
249
+ }
250
+ /**
251
+ * Load the cache from disk
252
+ *
253
+ * @param filePath - Path to load the cache from (uses options.persistPath if not provided)
254
+ */
255
+ async load(filePath) {
256
+ const targetPath = filePath ?? this.options.persistPath;
257
+ if (!targetPath) {
258
+ throw new Error('No persist path specified');
259
+ }
260
+ try {
261
+ const content = await fs.readFile(targetPath, 'utf-8');
262
+ const persistedCache = JSON.parse(content);
263
+ if (!persistedCache.version) {
264
+ throw new Error('Invalid cache file: missing version');
265
+ }
266
+ if (persistedCache.version !== '1.0.0') {
267
+ throw new Error(`Unsupported cache version: ${persistedCache.version}`);
268
+ }
269
+ // Clear current cache and load entries
270
+ this.clear();
271
+ for (const { key, entry } of persistedCache.entries) {
272
+ // Skip expired entries
273
+ if (!this.isExpired(entry)) {
274
+ this.set(key, entry.value, entry.size);
275
+ // Restore original timestamp and hits
276
+ const node = this.cache.get(key);
277
+ if (node) {
278
+ node.entry.timestamp = entry.timestamp;
279
+ node.entry.hits = entry.hits;
280
+ }
281
+ }
282
+ }
283
+ }
284
+ catch (error) {
285
+ if (error.code === 'ENOENT') {
286
+ // File doesn't exist, start with empty cache
287
+ return;
288
+ }
289
+ throw error;
290
+ }
291
+ }
292
+ /**
293
+ * Invalidate cache entries for a specific file and its dependents
294
+ *
295
+ * @param hash - The hash of the file that changed
296
+ * @param dependentHashes - Hashes of files that depend on the changed file
297
+ * @returns Number of entries invalidated
298
+ */
299
+ invalidate(hash, dependentHashes = []) {
300
+ let count = 0;
301
+ if (this.delete(hash)) {
302
+ count++;
303
+ }
304
+ for (const depHash of dependentHashes) {
305
+ if (this.delete(depHash)) {
306
+ count++;
307
+ }
308
+ }
309
+ return count;
310
+ }
311
+ /**
312
+ * Prune expired entries from the cache
313
+ *
314
+ * @returns Number of entries pruned
315
+ */
316
+ prune() {
317
+ let count = 0;
318
+ const now = Date.now();
319
+ for (const [key, node] of this.cache) {
320
+ if (this.isExpiredAt(node.entry, now)) {
321
+ this.delete(key);
322
+ count++;
323
+ if (this.options.enableStats) {
324
+ this.stats.expirations++;
325
+ }
326
+ }
327
+ }
328
+ return count;
329
+ }
330
+ // Private helper methods
331
+ isExpired(entry) {
332
+ return this.isExpiredAt(entry, Date.now());
333
+ }
334
+ isExpiredAt(entry, now) {
335
+ if (this.options.ttl === 0) {
336
+ return false; // No expiration
337
+ }
338
+ return now - entry.timestamp > this.options.ttl;
339
+ }
340
+ addToFront(node) {
341
+ node.prev = null;
342
+ node.next = this.head;
343
+ if (this.head) {
344
+ this.head.prev = node;
345
+ }
346
+ this.head = node;
347
+ if (!this.tail) {
348
+ this.tail = node;
349
+ }
350
+ }
351
+ removeFromList(node) {
352
+ if (node.prev) {
353
+ node.prev.next = node.next;
354
+ }
355
+ else {
356
+ this.head = node.next;
357
+ }
358
+ if (node.next) {
359
+ node.next.prev = node.prev;
360
+ }
361
+ else {
362
+ this.tail = node.prev;
363
+ }
364
+ node.prev = null;
365
+ node.next = null;
366
+ }
367
+ moveToFront(node) {
368
+ if (node === this.head) {
369
+ return; // Already at front
370
+ }
371
+ this.removeFromList(node);
372
+ this.addToFront(node);
373
+ }
374
+ evictLRU() {
375
+ if (!this.tail) {
376
+ return;
377
+ }
378
+ const key = this.tail.key;
379
+ this.removeFromList(this.tail);
380
+ this.cache.delete(key);
381
+ if (this.options.enableStats) {
382
+ this.stats.evictions++;
383
+ }
384
+ this.stats.size = this.cache.size;
385
+ }
386
+ updateHitRatio() {
387
+ const total = this.stats.hits + this.stats.misses;
388
+ this.stats.hitRatio = total > 0 ? this.stats.hits / total : 0;
389
+ }
390
+ }
391
+ //# sourceMappingURL=cache-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache-manager.js","sourceRoot":"","sources":["../../src/store/cache-manager.ts"],"names":[],"mappings":"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"}