pdf-oxide 0.3.24 → 0.3.28

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 (271) hide show
  1. package/lib/builders/annotation-builder.d.ts +199 -0
  2. package/lib/builders/annotation-builder.d.ts.map +1 -0
  3. package/lib/builders/annotation-builder.js +318 -0
  4. package/lib/builders/annotation-builder.js.map +1 -0
  5. package/lib/builders/conversion-options-builder.d.ts +107 -0
  6. package/lib/builders/conversion-options-builder.d.ts.map +1 -0
  7. package/lib/builders/conversion-options-builder.js +215 -0
  8. package/lib/builders/conversion-options-builder.js.map +1 -0
  9. package/{src/builders/index.ts → lib/builders/index.d.ts} +1 -1
  10. package/lib/builders/index.d.ts.map +1 -0
  11. package/lib/builders/index.js +12 -0
  12. package/lib/builders/index.js.map +1 -0
  13. package/lib/builders/metadata-builder.d.ts +202 -0
  14. package/lib/builders/metadata-builder.d.ts.map +1 -0
  15. package/lib/builders/metadata-builder.js +286 -0
  16. package/lib/builders/metadata-builder.js.map +1 -0
  17. package/lib/builders/pdf-builder.d.ts +215 -0
  18. package/lib/builders/pdf-builder.d.ts.map +1 -0
  19. package/lib/builders/pdf-builder.js +339 -0
  20. package/lib/builders/pdf-builder.js.map +1 -0
  21. package/lib/builders/search-options-builder.d.ts +74 -0
  22. package/lib/builders/search-options-builder.d.ts.map +1 -0
  23. package/lib/builders/search-options-builder.js +130 -0
  24. package/lib/builders/search-options-builder.js.map +1 -0
  25. package/lib/document-editor-manager.d.ts +140 -0
  26. package/lib/document-editor-manager.d.ts.map +1 -0
  27. package/lib/document-editor-manager.js +257 -0
  28. package/lib/document-editor-manager.js.map +1 -0
  29. package/lib/errors.d.ts +383 -0
  30. package/lib/errors.d.ts.map +1 -0
  31. package/lib/errors.js +1117 -0
  32. package/lib/errors.js.map +1 -0
  33. package/lib/form-field-manager.d.ts +300 -0
  34. package/lib/form-field-manager.d.ts.map +1 -0
  35. package/lib/form-field-manager.js +567 -0
  36. package/lib/form-field-manager.js.map +1 -0
  37. package/lib/hybrid-ml-manager.d.ts +143 -0
  38. package/lib/hybrid-ml-manager.d.ts.map +1 -0
  39. package/lib/hybrid-ml-manager.js +209 -0
  40. package/lib/hybrid-ml-manager.js.map +1 -0
  41. package/lib/index.d.ts +23 -0
  42. package/lib/index.d.ts.map +1 -0
  43. package/lib/index.js +280 -0
  44. package/lib/index.js.map +1 -0
  45. package/lib/managers/accessibility-manager.d.ts +149 -0
  46. package/lib/managers/accessibility-manager.d.ts.map +1 -0
  47. package/lib/managers/accessibility-manager.js +224 -0
  48. package/lib/managers/accessibility-manager.js.map +1 -0
  49. package/lib/managers/annotation-manager.d.ts +220 -0
  50. package/lib/managers/annotation-manager.d.ts.map +1 -0
  51. package/lib/managers/annotation-manager.js +360 -0
  52. package/lib/managers/annotation-manager.js.map +1 -0
  53. package/lib/managers/barcode-manager.d.ts +80 -0
  54. package/lib/managers/barcode-manager.d.ts.map +1 -0
  55. package/lib/managers/barcode-manager.js +226 -0
  56. package/lib/managers/barcode-manager.js.map +1 -0
  57. package/lib/managers/batch-manager.d.ts +186 -0
  58. package/lib/managers/batch-manager.d.ts.map +1 -0
  59. package/lib/managers/batch-manager.js +389 -0
  60. package/lib/managers/batch-manager.js.map +1 -0
  61. package/lib/managers/cache-manager.d.ts +182 -0
  62. package/lib/managers/cache-manager.d.ts.map +1 -0
  63. package/lib/managers/cache-manager.js +387 -0
  64. package/lib/managers/cache-manager.js.map +1 -0
  65. package/lib/managers/compliance-manager.d.ts +104 -0
  66. package/lib/managers/compliance-manager.d.ts.map +1 -0
  67. package/lib/managers/compliance-manager.js +415 -0
  68. package/lib/managers/compliance-manager.js.map +1 -0
  69. package/lib/managers/content-manager.d.ts +121 -0
  70. package/lib/managers/content-manager.d.ts.map +1 -0
  71. package/lib/managers/content-manager.js +295 -0
  72. package/lib/managers/content-manager.js.map +1 -0
  73. package/lib/managers/document-utility-manager.d.ts +370 -0
  74. package/lib/managers/document-utility-manager.d.ts.map +1 -0
  75. package/lib/managers/document-utility-manager.js +731 -0
  76. package/lib/managers/document-utility-manager.js.map +1 -0
  77. package/lib/managers/dom-pdf-creator.d.ts +105 -0
  78. package/lib/managers/dom-pdf-creator.d.ts.map +1 -0
  79. package/lib/managers/dom-pdf-creator.js +300 -0
  80. package/lib/managers/dom-pdf-creator.js.map +1 -0
  81. package/lib/managers/editing-manager.d.ts +249 -0
  82. package/lib/managers/editing-manager.d.ts.map +1 -0
  83. package/lib/managers/editing-manager.js +388 -0
  84. package/lib/managers/editing-manager.js.map +1 -0
  85. package/lib/managers/enterprise-manager.d.ts +193 -0
  86. package/lib/managers/enterprise-manager.d.ts.map +1 -0
  87. package/lib/managers/enterprise-manager.js +305 -0
  88. package/lib/managers/enterprise-manager.js.map +1 -0
  89. package/lib/managers/extended-managers.d.ts +123 -0
  90. package/lib/managers/extended-managers.d.ts.map +1 -0
  91. package/lib/managers/extended-managers.js +658 -0
  92. package/lib/managers/extended-managers.js.map +1 -0
  93. package/lib/managers/extraction-manager.d.ts +247 -0
  94. package/lib/managers/extraction-manager.d.ts.map +1 -0
  95. package/lib/managers/extraction-manager.js +478 -0
  96. package/lib/managers/extraction-manager.js.map +1 -0
  97. package/lib/managers/final-utilities.d.ts +128 -0
  98. package/lib/managers/final-utilities.d.ts.map +1 -0
  99. package/lib/managers/final-utilities.js +653 -0
  100. package/lib/managers/final-utilities.js.map +1 -0
  101. package/lib/managers/hybrid-ml-advanced.d.ts +137 -0
  102. package/lib/managers/hybrid-ml-advanced.d.ts.map +1 -0
  103. package/lib/managers/hybrid-ml-advanced.js +707 -0
  104. package/lib/managers/hybrid-ml-advanced.js.map +1 -0
  105. package/lib/managers/index.d.ts +65 -0
  106. package/lib/managers/index.d.ts.map +1 -0
  107. package/lib/managers/index.js +70 -0
  108. package/lib/managers/index.js.map +1 -0
  109. package/lib/managers/layer-manager.d.ts +204 -0
  110. package/lib/managers/layer-manager.d.ts.map +1 -0
  111. package/lib/managers/layer-manager.js +403 -0
  112. package/lib/managers/layer-manager.js.map +1 -0
  113. package/lib/managers/metadata-manager.d.ts +149 -0
  114. package/lib/managers/metadata-manager.d.ts.map +1 -0
  115. package/lib/managers/metadata-manager.js +281 -0
  116. package/lib/managers/metadata-manager.js.map +1 -0
  117. package/lib/managers/ocr-manager.d.ts +195 -0
  118. package/lib/managers/ocr-manager.d.ts.map +1 -0
  119. package/lib/managers/ocr-manager.js +583 -0
  120. package/lib/managers/ocr-manager.js.map +1 -0
  121. package/lib/managers/optimization-manager.d.ts +103 -0
  122. package/lib/managers/optimization-manager.d.ts.map +1 -0
  123. package/lib/managers/optimization-manager.js +194 -0
  124. package/lib/managers/optimization-manager.js.map +1 -0
  125. package/lib/managers/outline-manager.d.ts +102 -0
  126. package/lib/managers/outline-manager.d.ts.map +1 -0
  127. package/lib/managers/outline-manager.js +170 -0
  128. package/lib/managers/outline-manager.js.map +1 -0
  129. package/lib/managers/page-manager.d.ts +143 -0
  130. package/lib/managers/page-manager.d.ts.map +1 -0
  131. package/lib/managers/page-manager.js +237 -0
  132. package/lib/managers/page-manager.js.map +1 -0
  133. package/lib/managers/pattern-detection.d.ts +170 -0
  134. package/lib/managers/pattern-detection.d.ts.map +1 -0
  135. package/lib/managers/pattern-detection.js +325 -0
  136. package/lib/managers/pattern-detection.js.map +1 -0
  137. package/lib/managers/rendering-manager.d.ts +354 -0
  138. package/lib/managers/rendering-manager.d.ts.map +1 -0
  139. package/lib/managers/rendering-manager.js +680 -0
  140. package/lib/managers/rendering-manager.js.map +1 -0
  141. package/lib/managers/search-manager.d.ts +236 -0
  142. package/lib/managers/search-manager.d.ts.map +1 -0
  143. package/lib/managers/search-manager.js +330 -0
  144. package/lib/managers/search-manager.js.map +1 -0
  145. package/lib/managers/security-manager.d.ts +162 -0
  146. package/lib/managers/security-manager.d.ts.map +1 -0
  147. package/lib/managers/security-manager.js +293 -0
  148. package/lib/managers/security-manager.js.map +1 -0
  149. package/lib/managers/signature-manager.d.ts +725 -0
  150. package/lib/managers/signature-manager.d.ts.map +1 -0
  151. package/lib/managers/signature-manager.js +1365 -0
  152. package/lib/managers/signature-manager.js.map +1 -0
  153. package/lib/managers/streams.d.ts +263 -0
  154. package/lib/managers/streams.d.ts.map +1 -0
  155. package/lib/managers/streams.js +472 -0
  156. package/lib/managers/streams.js.map +1 -0
  157. package/lib/managers/xfa-manager.d.ts +228 -0
  158. package/lib/managers/xfa-manager.d.ts.map +1 -0
  159. package/lib/managers/xfa-manager.js +490 -0
  160. package/lib/managers/xfa-manager.js.map +1 -0
  161. package/lib/pdf-creator-manager.d.ts +201 -0
  162. package/lib/pdf-creator-manager.d.ts.map +1 -0
  163. package/lib/pdf-creator-manager.js +379 -0
  164. package/lib/pdf-creator-manager.js.map +1 -0
  165. package/lib/properties.d.ts +80 -0
  166. package/lib/properties.d.ts.map +1 -0
  167. package/lib/properties.js +455 -0
  168. package/lib/properties.js.map +1 -0
  169. package/lib/result-accessors-manager.d.ts +347 -0
  170. package/lib/result-accessors-manager.d.ts.map +1 -0
  171. package/lib/result-accessors-manager.js +705 -0
  172. package/lib/result-accessors-manager.js.map +1 -0
  173. package/lib/thumbnail-manager.d.ts +122 -0
  174. package/lib/thumbnail-manager.d.ts.map +1 -0
  175. package/lib/thumbnail-manager.js +206 -0
  176. package/lib/thumbnail-manager.js.map +1 -0
  177. package/lib/types/common.d.ts +93 -0
  178. package/lib/types/common.d.ts.map +1 -0
  179. package/lib/types/common.js +5 -0
  180. package/lib/types/common.js.map +1 -0
  181. package/lib/types/document-types.d.ts +353 -0
  182. package/lib/types/document-types.d.ts.map +1 -0
  183. package/lib/types/document-types.js +83 -0
  184. package/lib/types/document-types.js.map +1 -0
  185. package/{src/types/index.ts → lib/types/index.d.ts} +1 -1
  186. package/lib/types/index.d.ts.map +1 -0
  187. package/lib/types/index.js +6 -0
  188. package/lib/types/index.js.map +1 -0
  189. package/lib/types/manager-types.d.ts +180 -0
  190. package/lib/types/manager-types.d.ts.map +1 -0
  191. package/lib/types/manager-types.js +99 -0
  192. package/lib/types/manager-types.js.map +1 -0
  193. package/lib/types/native-bindings.d.ts +440 -0
  194. package/lib/types/native-bindings.d.ts.map +1 -0
  195. package/lib/types/native-bindings.js +8 -0
  196. package/lib/types/native-bindings.js.map +1 -0
  197. package/{src/workers/index.ts → lib/workers/index.d.ts} +1 -1
  198. package/lib/workers/index.d.ts.map +1 -0
  199. package/lib/workers/index.js +6 -0
  200. package/lib/workers/index.js.map +1 -0
  201. package/lib/workers/pool.d.ts +65 -0
  202. package/lib/workers/pool.d.ts.map +1 -0
  203. package/lib/workers/pool.js +195 -0
  204. package/lib/workers/pool.js.map +1 -0
  205. package/lib/workers/worker.d.ts +6 -0
  206. package/lib/workers/worker.d.ts.map +1 -0
  207. package/lib/workers/worker.js +100 -0
  208. package/lib/workers/worker.js.map +1 -0
  209. package/package.json +12 -22
  210. package/prebuilds/darwin-arm64/pdf_oxide.node +0 -0
  211. package/prebuilds/darwin-x64/pdf_oxide.node +0 -0
  212. package/prebuilds/linux-arm64/pdf_oxide.node +0 -0
  213. package/prebuilds/linux-x64/pdf_oxide.node +0 -0
  214. package/prebuilds/win32-x64/pdf_oxide.node +0 -0
  215. package/binding.gyp +0 -35
  216. package/src/builders/annotation-builder.ts +0 -367
  217. package/src/builders/conversion-options-builder.ts +0 -257
  218. package/src/builders/metadata-builder.ts +0 -317
  219. package/src/builders/pdf-builder.ts +0 -386
  220. package/src/builders/search-options-builder.ts +0 -151
  221. package/src/document-editor-manager.ts +0 -318
  222. package/src/errors.ts +0 -1629
  223. package/src/form-field-manager.ts +0 -666
  224. package/src/hybrid-ml-manager.ts +0 -283
  225. package/src/index.ts +0 -453
  226. package/src/managers/accessibility-manager.ts +0 -338
  227. package/src/managers/annotation-manager.ts +0 -439
  228. package/src/managers/barcode-manager.ts +0 -235
  229. package/src/managers/batch-manager.ts +0 -533
  230. package/src/managers/cache-manager.ts +0 -486
  231. package/src/managers/compliance-manager.ts +0 -375
  232. package/src/managers/content-manager.ts +0 -339
  233. package/src/managers/document-utility-manager.ts +0 -922
  234. package/src/managers/dom-pdf-creator.ts +0 -365
  235. package/src/managers/editing-manager.ts +0 -514
  236. package/src/managers/enterprise-manager.ts +0 -478
  237. package/src/managers/extended-managers.ts +0 -437
  238. package/src/managers/extraction-manager.ts +0 -583
  239. package/src/managers/final-utilities.ts +0 -429
  240. package/src/managers/hybrid-ml-advanced.ts +0 -479
  241. package/src/managers/index.ts +0 -239
  242. package/src/managers/layer-manager.ts +0 -500
  243. package/src/managers/metadata-manager.ts +0 -303
  244. package/src/managers/ocr-manager.ts +0 -756
  245. package/src/managers/optimization-manager.ts +0 -262
  246. package/src/managers/outline-manager.ts +0 -196
  247. package/src/managers/page-manager.ts +0 -289
  248. package/src/managers/pattern-detection.ts +0 -440
  249. package/src/managers/rendering-manager.ts +0 -863
  250. package/src/managers/search-manager.ts +0 -385
  251. package/src/managers/security-manager.ts +0 -345
  252. package/src/managers/signature-manager.ts +0 -1664
  253. package/src/managers/streams.ts +0 -618
  254. package/src/managers/xfa-manager.ts +0 -500
  255. package/src/pdf-creator-manager.ts +0 -494
  256. package/src/properties.ts +0 -522
  257. package/src/result-accessors-manager.ts +0 -867
  258. package/src/tests/advanced-features.test.ts +0 -414
  259. package/src/tests/advanced.test.ts +0 -266
  260. package/src/tests/extended-managers.test.ts +0 -316
  261. package/src/tests/final-utilities.test.ts +0 -455
  262. package/src/tests/foundation.test.ts +0 -315
  263. package/src/tests/high-demand.test.ts +0 -257
  264. package/src/tests/specialized.test.ts +0 -97
  265. package/src/thumbnail-manager.ts +0 -272
  266. package/src/types/common.ts +0 -142
  267. package/src/types/document-types.ts +0 -457
  268. package/src/types/manager-types.ts +0 -284
  269. package/src/types/native-bindings.ts +0 -517
  270. package/src/workers/pool.ts +0 -274
  271. package/src/workers/worker.ts +0 -131
@@ -1,486 +0,0 @@
1
- /**
2
- * Cache Manager - TypeScript/Node.js Implementation
3
- *
4
- * Provides caching functionality for PDF operations:
5
- * - Document-level caching
6
- * - Page-level caching
7
- * - Result caching with TTL
8
- * - LRU eviction
9
- * - Cache statistics
10
- *
11
- * This completes the cache coverage for 100% FFI parity.
12
- */
13
-
14
- import { EventEmitter } from 'events';
15
-
16
- // ============================================================================
17
- // Type Definitions
18
- // ============================================================================
19
-
20
- /**
21
- * Cache entry with metadata
22
- */
23
- export interface CacheEntry<T = unknown> {
24
- readonly key: string;
25
- readonly value: T;
26
- readonly timestamp: number;
27
- readonly ttl?: number;
28
- readonly size?: number;
29
- readonly hits: number;
30
- }
31
-
32
- /**
33
- * Cache options
34
- */
35
- export interface CacheOptions {
36
- readonly maxSize?: number;
37
- readonly maxEntries?: number;
38
- readonly defaultTtl?: number;
39
- readonly enableStatistics?: boolean;
40
- readonly evictionPolicy?: 'lru' | 'lfu' | 'fifo';
41
- }
42
-
43
- /**
44
- * Cache statistics
45
- */
46
- export interface CacheStatistics {
47
- readonly totalEntries: number;
48
- readonly totalSize: number;
49
- readonly hitCount: number;
50
- readonly missCount: number;
51
- readonly hitRate: number;
52
- readonly evictionCount: number;
53
- readonly oldestEntry?: number;
54
- readonly newestEntry?: number;
55
- }
56
-
57
- /**
58
- * Cache scope enumeration
59
- */
60
- export enum CacheScope {
61
- /** Cache per document */
62
- DOCUMENT = 'document',
63
- /** Cache per page */
64
- PAGE = 'page',
65
- /** Global cache */
66
- GLOBAL = 'global',
67
- /** Session-level cache */
68
- SESSION = 'session',
69
- }
70
-
71
- /**
72
- * Cache event data
73
- */
74
- export interface CacheEventData {
75
- readonly key: string;
76
- readonly scope?: CacheScope;
77
- readonly operation: 'set' | 'get' | 'delete' | 'evict' | 'clear';
78
- readonly hit?: boolean;
79
- }
80
-
81
- // ============================================================================
82
- // Cache Manager Implementation
83
- // ============================================================================
84
-
85
- /**
86
- * Cache Manager - Complete caching capabilities
87
- *
88
- * Provides 10 functions for cache management:
89
- * 1. set - Store a value
90
- * 2. get - Retrieve a value
91
- * 3. has - Check if key exists
92
- * 4. delete - Remove a key
93
- * 5. clear - Clear all entries
94
- * 6. clearScope - Clear entries by scope
95
- * 7. getStatistics - Get cache statistics
96
- * 8. setTtl - Set TTL for an entry
97
- * 9. getKeys - Get all keys
98
- * 10. prune - Remove expired entries
99
- *
100
- * @example
101
- * ```typescript
102
- * const cache = new CacheManager({
103
- * maxEntries: 1000,
104
- * defaultTtl: 60000, // 1 minute
105
- * evictionPolicy: 'lru',
106
- * });
107
- *
108
- * // Store a value
109
- * cache.set('page:0:text', extractedText, CacheScope.PAGE);
110
- *
111
- * // Retrieve a value
112
- * const text = cache.get<string>('page:0:text');
113
- *
114
- * // Check statistics
115
- * const stats = cache.getStatistics();
116
- * console.log(`Hit rate: ${stats.hitRate * 100}%`);
117
- * ```
118
- */
119
- export class CacheManager extends EventEmitter {
120
- private readonly cache: Map<string, CacheEntry> = new Map();
121
- private readonly scopeIndex: Map<CacheScope, Set<string>> = new Map();
122
- private readonly options: Required<CacheOptions>;
123
-
124
- // Statistics
125
- private hitCount = 0;
126
- private missCount = 0;
127
- private evictionCount = 0;
128
-
129
- constructor(options: CacheOptions = {}) {
130
- super();
131
- this.options = {
132
- maxSize: options.maxSize ?? 100 * 1024 * 1024, // 100MB default
133
- maxEntries: options.maxEntries ?? 10000,
134
- defaultTtl: options.defaultTtl ?? 0, // 0 = no expiry
135
- enableStatistics: options.enableStatistics ?? true,
136
- evictionPolicy: options.evictionPolicy ?? 'lru',
137
- };
138
-
139
- // Initialize scope index
140
- for (const scope of Object.values(CacheScope)) {
141
- this.scopeIndex.set(scope, new Set());
142
- }
143
- }
144
-
145
- // ==========================================================================
146
- // Core Cache Operations (6 functions)
147
- // ==========================================================================
148
-
149
- /**
150
- * Store a value in the cache
151
- */
152
- set<T>(key: string, value: T, scope: CacheScope = CacheScope.GLOBAL, ttl?: number): void {
153
- // Check if we need to evict
154
- this.ensureCapacity();
155
-
156
- const entry: CacheEntry<T> = {
157
- key,
158
- value,
159
- timestamp: Date.now(),
160
- ttl: ttl ?? this.options.defaultTtl,
161
- size: this.estimateSize(value),
162
- hits: 0,
163
- };
164
-
165
- // Remove from old scope if exists
166
- if (this.cache.has(key)) {
167
- this.removeFromScopeIndex(key);
168
- }
169
-
170
- this.cache.set(key, entry as CacheEntry);
171
- this.scopeIndex.get(scope)?.add(key);
172
-
173
- this.emit('cache-set', {
174
- key,
175
- scope,
176
- operation: 'set',
177
- } as CacheEventData);
178
- }
179
-
180
- /**
181
- * Retrieve a value from the cache
182
- */
183
- get<T>(key: string): T | undefined {
184
- const entry = this.cache.get(key) as CacheEntry<T> | undefined;
185
-
186
- if (!entry) {
187
- if (this.options.enableStatistics) {
188
- this.missCount++;
189
- }
190
- this.emit('cache-miss', { key, operation: 'get', hit: false } as CacheEventData);
191
- return undefined;
192
- }
193
-
194
- // Check TTL
195
- if (entry.ttl && entry.ttl > 0 && Date.now() - entry.timestamp > entry.ttl) {
196
- this.delete(key);
197
- if (this.options.enableStatistics) {
198
- this.missCount++;
199
- }
200
- this.emit('cache-expired', { key, operation: 'get', hit: false } as CacheEventData);
201
- return undefined;
202
- }
203
-
204
- // Update hit count for LFU
205
- const updatedEntry: CacheEntry<T> = {
206
- ...entry,
207
- hits: entry.hits + 1,
208
- timestamp: this.options.evictionPolicy === 'lru' ? Date.now() : entry.timestamp,
209
- };
210
- this.cache.set(key, updatedEntry as CacheEntry);
211
-
212
- if (this.options.enableStatistics) {
213
- this.hitCount++;
214
- }
215
-
216
- this.emit('cache-hit', { key, operation: 'get', hit: true } as CacheEventData);
217
- return entry.value;
218
- }
219
-
220
- /**
221
- * Check if a key exists in the cache
222
- */
223
- has(key: string): boolean {
224
- const entry = this.cache.get(key);
225
- if (!entry) return false;
226
-
227
- // Check TTL
228
- if (entry.ttl && entry.ttl > 0 && Date.now() - entry.timestamp > entry.ttl) {
229
- this.delete(key);
230
- return false;
231
- }
232
-
233
- return true;
234
- }
235
-
236
- /**
237
- * Remove a key from the cache
238
- */
239
- delete(key: string): boolean {
240
- const exists = this.cache.has(key);
241
- if (exists) {
242
- this.removeFromScopeIndex(key);
243
- this.cache.delete(key);
244
- this.emit('cache-delete', { key, operation: 'delete' } as CacheEventData);
245
- }
246
- return exists;
247
- }
248
-
249
- /**
250
- * Clear all entries from the cache
251
- */
252
- clear(): void {
253
- const count = this.cache.size;
254
- this.cache.clear();
255
- for (const scope of this.scopeIndex.values()) {
256
- scope.clear();
257
- }
258
- this.hitCount = 0;
259
- this.missCount = 0;
260
- this.evictionCount = 0;
261
- this.emit('cache-clear', { key: '*', operation: 'clear' } as CacheEventData);
262
- }
263
-
264
- /**
265
- * Clear entries by scope
266
- */
267
- clearScope(scope: CacheScope): number {
268
- const keys = this.scopeIndex.get(scope);
269
- if (!keys) return 0;
270
-
271
- const count = keys.size;
272
- for (const key of keys) {
273
- this.cache.delete(key);
274
- }
275
- keys.clear();
276
-
277
- this.emit('cache-scope-clear', { key: scope, scope, operation: 'clear' } as CacheEventData);
278
- return count;
279
- }
280
-
281
- // ==========================================================================
282
- // Statistics and Maintenance (4 functions)
283
- // ==========================================================================
284
-
285
- /**
286
- * Get cache statistics
287
- */
288
- getStatistics(): CacheStatistics {
289
- const entries = Array.from(this.cache.values());
290
- const totalSize = entries.reduce((sum, e) => sum + (e.size ?? 0), 0);
291
- const timestamps = entries.map((e) => e.timestamp);
292
-
293
- return {
294
- totalEntries: this.cache.size,
295
- totalSize,
296
- hitCount: this.hitCount,
297
- missCount: this.missCount,
298
- hitRate: this.hitCount + this.missCount > 0
299
- ? this.hitCount / (this.hitCount + this.missCount)
300
- : 0,
301
- evictionCount: this.evictionCount,
302
- oldestEntry: timestamps.length > 0 ? Math.min(...timestamps) : undefined,
303
- newestEntry: timestamps.length > 0 ? Math.max(...timestamps) : undefined,
304
- };
305
- }
306
-
307
- /**
308
- * Set TTL for an existing entry
309
- */
310
- setTtl(key: string, ttl: number): boolean {
311
- const entry = this.cache.get(key);
312
- if (!entry) return false;
313
-
314
- const updatedEntry: CacheEntry = {
315
- ...entry,
316
- ttl,
317
- };
318
- this.cache.set(key, updatedEntry);
319
- return true;
320
- }
321
-
322
- /**
323
- * Get all cache keys
324
- */
325
- getKeys(scope?: CacheScope): string[] {
326
- if (scope) {
327
- return Array.from(this.scopeIndex.get(scope) ?? []);
328
- }
329
- return Array.from(this.cache.keys());
330
- }
331
-
332
- /**
333
- * Remove expired entries
334
- */
335
- prune(): number {
336
- const now = Date.now();
337
- let pruned = 0;
338
-
339
- for (const [key, entry] of this.cache.entries()) {
340
- if (entry.ttl && entry.ttl > 0 && now - entry.timestamp > entry.ttl) {
341
- this.delete(key);
342
- pruned++;
343
- }
344
- }
345
-
346
- if (pruned > 0) {
347
- this.emit('cache-prune', { key: '*', operation: 'delete' } as CacheEventData);
348
- }
349
-
350
- return pruned;
351
- }
352
-
353
- // ==========================================================================
354
- // Helper Methods
355
- // ==========================================================================
356
-
357
- /**
358
- * Ensure cache has capacity, evicting if needed
359
- */
360
- private ensureCapacity(): void {
361
- // Check entry count
362
- while (this.cache.size >= this.options.maxEntries) {
363
- this.evictOne();
364
- }
365
-
366
- // Check total size
367
- let totalSize = 0;
368
- for (const entry of this.cache.values()) {
369
- totalSize += entry.size ?? 0;
370
- }
371
-
372
- while (totalSize > this.options.maxSize && this.cache.size > 0) {
373
- const evicted = this.evictOne();
374
- totalSize -= evicted?.size ?? 0;
375
- }
376
- }
377
-
378
- /**
379
- * Evict one entry based on eviction policy
380
- */
381
- private evictOne(): CacheEntry | undefined {
382
- if (this.cache.size === 0) return undefined;
383
-
384
- let keyToEvict: string | undefined;
385
-
386
- switch (this.options.evictionPolicy) {
387
- case 'lru':
388
- // Find oldest timestamp
389
- keyToEvict = this.findOldestKey();
390
- break;
391
-
392
- case 'lfu':
393
- // Find least frequently used
394
- keyToEvict = this.findLeastUsedKey();
395
- break;
396
-
397
- case 'fifo':
398
- default:
399
- // First key
400
- keyToEvict = this.cache.keys().next().value;
401
- break;
402
- }
403
-
404
- if (keyToEvict) {
405
- const entry = this.cache.get(keyToEvict);
406
- this.removeFromScopeIndex(keyToEvict);
407
- this.cache.delete(keyToEvict);
408
- this.evictionCount++;
409
- this.emit('cache-evict', { key: keyToEvict, operation: 'evict' } as CacheEventData);
410
- return entry;
411
- }
412
-
413
- return undefined;
414
- }
415
-
416
- /**
417
- * Find key with oldest timestamp (LRU)
418
- */
419
- private findOldestKey(): string | undefined {
420
- let oldestKey: string | undefined;
421
- let oldestTime = Infinity;
422
-
423
- for (const [key, entry] of this.cache.entries()) {
424
- if (entry.timestamp < oldestTime) {
425
- oldestTime = entry.timestamp;
426
- oldestKey = key;
427
- }
428
- }
429
-
430
- return oldestKey;
431
- }
432
-
433
- /**
434
- * Find key with least hits (LFU)
435
- */
436
- private findLeastUsedKey(): string | undefined {
437
- let leastUsedKey: string | undefined;
438
- let leastHits = Infinity;
439
-
440
- for (const [key, entry] of this.cache.entries()) {
441
- if (entry.hits < leastHits) {
442
- leastHits = entry.hits;
443
- leastUsedKey = key;
444
- }
445
- }
446
-
447
- return leastUsedKey;
448
- }
449
-
450
- /**
451
- * Remove key from scope index
452
- */
453
- private removeFromScopeIndex(key: string): void {
454
- for (const keys of this.scopeIndex.values()) {
455
- keys.delete(key);
456
- }
457
- }
458
-
459
- /**
460
- * Estimate size of a value in bytes
461
- */
462
- private estimateSize(value: unknown): number {
463
- if (value === null || value === undefined) return 0;
464
- if (typeof value === 'string') return value.length * 2;
465
- if (typeof value === 'number') return 8;
466
- if (typeof value === 'boolean') return 4;
467
- if (Buffer.isBuffer(value)) return value.length;
468
- if (Array.isArray(value)) {
469
- return value.reduce((sum, v) => sum + this.estimateSize(v), 0);
470
- }
471
- if (typeof value === 'object') {
472
- return JSON.stringify(value).length * 2;
473
- }
474
- return 0;
475
- }
476
-
477
- /**
478
- * Cleanup resources
479
- */
480
- destroy(): void {
481
- this.clear();
482
- this.removeAllListeners();
483
- }
484
- }
485
-
486
- export default CacheManager;