pdf-oxide-fips 0.3.47
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE-APACHE +176 -0
- package/LICENSE-MIT +25 -0
- package/README.md +218 -0
- package/lib/builders/annotation-builder.d.ts +198 -0
- package/lib/builders/annotation-builder.js +317 -0
- package/lib/builders/conversion-options-builder.d.ts +106 -0
- package/lib/builders/conversion-options-builder.js +214 -0
- package/lib/builders/document-builder.d.ts +381 -0
- package/lib/builders/document-builder.js +770 -0
- package/lib/builders/index.d.ts +13 -0
- package/lib/builders/index.js +13 -0
- package/lib/builders/metadata-builder.d.ts +201 -0
- package/lib/builders/metadata-builder.js +285 -0
- package/lib/builders/pdf-builder.d.ts +216 -0
- package/lib/builders/pdf-builder.js +350 -0
- package/lib/builders/search-options-builder.d.ts +73 -0
- package/lib/builders/search-options-builder.js +129 -0
- package/lib/builders/streaming-table.d.ts +64 -0
- package/lib/builders/streaming-table.js +140 -0
- package/lib/document-editor-manager.d.ts +139 -0
- package/lib/document-editor-manager.js +256 -0
- package/lib/document-editor.d.ts +124 -0
- package/lib/document-editor.js +318 -0
- package/lib/errors.d.ts +382 -0
- package/lib/errors.js +1115 -0
- package/lib/form-field-manager.d.ts +299 -0
- package/lib/form-field-manager.js +568 -0
- package/lib/hybrid-ml-manager.d.ts +142 -0
- package/lib/hybrid-ml-manager.js +208 -0
- package/lib/index.d.ts +205 -0
- package/lib/index.js +693 -0
- package/lib/managers/accessibility-manager.d.ts +148 -0
- package/lib/managers/accessibility-manager.js +234 -0
- package/lib/managers/annotation-manager.d.ts +219 -0
- package/lib/managers/annotation-manager.js +359 -0
- package/lib/managers/barcode-manager.d.ts +82 -0
- package/lib/managers/barcode-manager.js +263 -0
- package/lib/managers/batch-manager.d.ts +185 -0
- package/lib/managers/batch-manager.js +385 -0
- package/lib/managers/cache-manager.d.ts +181 -0
- package/lib/managers/cache-manager.js +384 -0
- package/lib/managers/compliance-manager.d.ts +103 -0
- package/lib/managers/compliance-manager.js +453 -0
- package/lib/managers/content-manager.d.ts +120 -0
- package/lib/managers/content-manager.js +294 -0
- package/lib/managers/document-utility-manager.d.ts +369 -0
- package/lib/managers/document-utility-manager.js +730 -0
- package/lib/managers/dom-pdf-creator.d.ts +104 -0
- package/lib/managers/dom-pdf-creator.js +299 -0
- package/lib/managers/editing-manager.d.ts +248 -0
- package/lib/managers/editing-manager.js +387 -0
- package/lib/managers/enterprise-manager.d.ts +192 -0
- package/lib/managers/enterprise-manager.js +307 -0
- package/lib/managers/extended-managers.d.ts +122 -0
- package/lib/managers/extended-managers.js +664 -0
- package/lib/managers/extraction-manager.d.ts +246 -0
- package/lib/managers/extraction-manager.js +482 -0
- package/lib/managers/final-utilities.d.ts +127 -0
- package/lib/managers/final-utilities.js +657 -0
- package/lib/managers/hybrid-ml-advanced.d.ts +136 -0
- package/lib/managers/hybrid-ml-advanced.js +722 -0
- package/lib/managers/index.d.ts +64 -0
- package/lib/managers/index.js +69 -0
- package/lib/managers/layer-manager.d.ts +203 -0
- package/lib/managers/layer-manager.js +401 -0
- package/lib/managers/metadata-manager.d.ts +148 -0
- package/lib/managers/metadata-manager.js +280 -0
- package/lib/managers/ocr-manager.d.ts +194 -0
- package/lib/managers/ocr-manager.js +582 -0
- package/lib/managers/optimization-manager.d.ts +102 -0
- package/lib/managers/optimization-manager.js +213 -0
- package/lib/managers/outline-manager.d.ts +101 -0
- package/lib/managers/outline-manager.js +169 -0
- package/lib/managers/page-manager.d.ts +142 -0
- package/lib/managers/page-manager.js +235 -0
- package/lib/managers/pattern-detection.d.ts +169 -0
- package/lib/managers/pattern-detection.js +322 -0
- package/lib/managers/rendering-manager.d.ts +353 -0
- package/lib/managers/rendering-manager.js +679 -0
- package/lib/managers/search-manager.d.ts +235 -0
- package/lib/managers/search-manager.js +329 -0
- package/lib/managers/security-manager.d.ts +161 -0
- package/lib/managers/security-manager.js +292 -0
- package/lib/managers/signature-manager.d.ts +738 -0
- package/lib/managers/signature-manager.js +1509 -0
- package/lib/managers/streams.d.ts +262 -0
- package/lib/managers/streams.js +477 -0
- package/lib/managers/xfa-manager.d.ts +227 -0
- package/lib/managers/xfa-manager.js +539 -0
- package/lib/native-loader.d.ts +7 -0
- package/lib/native-loader.js +62 -0
- package/lib/native.d.ts +16 -0
- package/lib/native.js +69 -0
- package/lib/pdf-creator-manager.d.ts +200 -0
- package/lib/pdf-creator-manager.js +381 -0
- package/lib/properties.d.ts +79 -0
- package/lib/properties.js +454 -0
- package/lib/result-accessors-manager.d.ts +346 -0
- package/lib/result-accessors-manager.js +706 -0
- package/lib/thumbnail-manager.d.ts +121 -0
- package/lib/thumbnail-manager.js +205 -0
- package/lib/timestamp.d.ts +54 -0
- package/lib/timestamp.js +115 -0
- package/lib/tsa-client.d.ts +44 -0
- package/lib/tsa-client.js +67 -0
- package/lib/types/common.d.ts +189 -0
- package/lib/types/common.js +17 -0
- package/lib/types/document-types.d.ts +352 -0
- package/lib/types/document-types.js +82 -0
- package/lib/types/index.d.ts +5 -0
- package/lib/types/index.js +5 -0
- package/lib/types/manager-types.d.ts +179 -0
- package/lib/types/manager-types.js +100 -0
- package/lib/types/native-bindings.d.ts +439 -0
- package/lib/types/native-bindings.js +7 -0
- package/lib/workers/index.d.ts +6 -0
- package/lib/workers/index.js +5 -0
- package/lib/workers/pool.d.ts +64 -0
- package/lib/workers/pool.js +192 -0
- package/lib/workers/worker.d.ts +5 -0
- package/lib/workers/worker.js +99 -0
- package/package.json +79 -0
- package/prebuilds/darwin-arm64/pdf_oxide.node +0 -0
- package/prebuilds/darwin-x64/pdf_oxide.node +0 -0
- package/prebuilds/linux-arm64/pdf_oxide.node +0 -0
- package/prebuilds/linux-x64/pdf_oxide.node +0 -0
- package/prebuilds/win32-x64/pdf_oxide.node +0 -0
|
@@ -0,0 +1,181 @@
|
|
|
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
|
+
import { EventEmitter } from 'events';
|
|
14
|
+
/**
|
|
15
|
+
* Cache entry with metadata
|
|
16
|
+
*/
|
|
17
|
+
export interface CacheEntry<T = unknown> {
|
|
18
|
+
readonly key: string;
|
|
19
|
+
readonly value: T;
|
|
20
|
+
readonly timestamp: number;
|
|
21
|
+
readonly ttl?: number;
|
|
22
|
+
readonly size?: number;
|
|
23
|
+
readonly hits: number;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Cache options
|
|
27
|
+
*/
|
|
28
|
+
export interface CacheOptions {
|
|
29
|
+
readonly maxSize?: number;
|
|
30
|
+
readonly maxEntries?: number;
|
|
31
|
+
readonly defaultTtl?: number;
|
|
32
|
+
readonly enableStatistics?: boolean;
|
|
33
|
+
readonly evictionPolicy?: 'lru' | 'lfu' | 'fifo';
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Cache statistics
|
|
37
|
+
*/
|
|
38
|
+
export interface CacheStatistics {
|
|
39
|
+
readonly totalEntries: number;
|
|
40
|
+
readonly totalSize: number;
|
|
41
|
+
readonly hitCount: number;
|
|
42
|
+
readonly missCount: number;
|
|
43
|
+
readonly hitRate: number;
|
|
44
|
+
readonly evictionCount: number;
|
|
45
|
+
readonly oldestEntry?: number;
|
|
46
|
+
readonly newestEntry?: number;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Cache scope enumeration
|
|
50
|
+
*/
|
|
51
|
+
export declare enum CacheScope {
|
|
52
|
+
/** Cache per document */
|
|
53
|
+
DOCUMENT = "document",
|
|
54
|
+
/** Cache per page */
|
|
55
|
+
PAGE = "page",
|
|
56
|
+
/** Global cache */
|
|
57
|
+
GLOBAL = "global",
|
|
58
|
+
/** Session-level cache */
|
|
59
|
+
SESSION = "session"
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Cache event data
|
|
63
|
+
*/
|
|
64
|
+
export interface CacheEventData {
|
|
65
|
+
readonly key: string;
|
|
66
|
+
readonly scope?: CacheScope;
|
|
67
|
+
readonly operation: 'set' | 'get' | 'delete' | 'evict' | 'clear';
|
|
68
|
+
readonly hit?: boolean;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Cache Manager - Complete caching capabilities
|
|
72
|
+
*
|
|
73
|
+
* Provides 10 functions for cache management:
|
|
74
|
+
* 1. set - Store a value
|
|
75
|
+
* 2. get - Retrieve a value
|
|
76
|
+
* 3. has - Check if key exists
|
|
77
|
+
* 4. delete - Remove a key
|
|
78
|
+
* 5. clear - Clear all entries
|
|
79
|
+
* 6. clearScope - Clear entries by scope
|
|
80
|
+
* 7. getStatistics - Get cache statistics
|
|
81
|
+
* 8. setTtl - Set TTL for an entry
|
|
82
|
+
* 9. getKeys - Get all keys
|
|
83
|
+
* 10. prune - Remove expired entries
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* ```typescript
|
|
87
|
+
* const cache = new CacheManager({
|
|
88
|
+
* maxEntries: 1000,
|
|
89
|
+
* defaultTtl: 60000, // 1 minute
|
|
90
|
+
* evictionPolicy: 'lru',
|
|
91
|
+
* });
|
|
92
|
+
*
|
|
93
|
+
* // Store a value
|
|
94
|
+
* cache.set('page:0:text', extractedText, CacheScope.PAGE);
|
|
95
|
+
*
|
|
96
|
+
* // Retrieve a value
|
|
97
|
+
* const text = cache.get<string>('page:0:text');
|
|
98
|
+
*
|
|
99
|
+
* // Check statistics
|
|
100
|
+
* const stats = cache.getStatistics();
|
|
101
|
+
* console.log(`Hit rate: ${stats.hitRate * 100}%`);
|
|
102
|
+
* ```
|
|
103
|
+
*/
|
|
104
|
+
export declare class CacheManager extends EventEmitter {
|
|
105
|
+
private readonly cache;
|
|
106
|
+
private readonly scopeIndex;
|
|
107
|
+
private readonly options;
|
|
108
|
+
private hitCount;
|
|
109
|
+
private missCount;
|
|
110
|
+
private evictionCount;
|
|
111
|
+
constructor(options?: CacheOptions);
|
|
112
|
+
/**
|
|
113
|
+
* Store a value in the cache
|
|
114
|
+
*/
|
|
115
|
+
set<T>(key: string, value: T, scope?: CacheScope, ttl?: number): void;
|
|
116
|
+
/**
|
|
117
|
+
* Retrieve a value from the cache
|
|
118
|
+
*/
|
|
119
|
+
get<T>(key: string): T | undefined;
|
|
120
|
+
/**
|
|
121
|
+
* Check if a key exists in the cache
|
|
122
|
+
*/
|
|
123
|
+
has(key: string): boolean;
|
|
124
|
+
/**
|
|
125
|
+
* Remove a key from the cache
|
|
126
|
+
*/
|
|
127
|
+
delete(key: string): boolean;
|
|
128
|
+
/**
|
|
129
|
+
* Clear all entries from the cache
|
|
130
|
+
*/
|
|
131
|
+
clear(): void;
|
|
132
|
+
/**
|
|
133
|
+
* Clear entries by scope
|
|
134
|
+
*/
|
|
135
|
+
clearScope(scope: CacheScope): number;
|
|
136
|
+
/**
|
|
137
|
+
* Get cache statistics
|
|
138
|
+
*/
|
|
139
|
+
getStatistics(): CacheStatistics;
|
|
140
|
+
/**
|
|
141
|
+
* Set TTL for an existing entry
|
|
142
|
+
*/
|
|
143
|
+
setTtl(key: string, ttl: number): boolean;
|
|
144
|
+
/**
|
|
145
|
+
* Get all cache keys
|
|
146
|
+
*/
|
|
147
|
+
getKeys(scope?: CacheScope): string[];
|
|
148
|
+
/**
|
|
149
|
+
* Remove expired entries
|
|
150
|
+
*/
|
|
151
|
+
prune(): number;
|
|
152
|
+
/**
|
|
153
|
+
* Ensure cache has capacity, evicting if needed
|
|
154
|
+
*/
|
|
155
|
+
private ensureCapacity;
|
|
156
|
+
/**
|
|
157
|
+
* Evict one entry based on eviction policy
|
|
158
|
+
*/
|
|
159
|
+
private evictOne;
|
|
160
|
+
/**
|
|
161
|
+
* Find key with oldest timestamp (LRU)
|
|
162
|
+
*/
|
|
163
|
+
private findOldestKey;
|
|
164
|
+
/**
|
|
165
|
+
* Find key with least hits (LFU)
|
|
166
|
+
*/
|
|
167
|
+
private findLeastUsedKey;
|
|
168
|
+
/**
|
|
169
|
+
* Remove key from scope index
|
|
170
|
+
*/
|
|
171
|
+
private removeFromScopeIndex;
|
|
172
|
+
/**
|
|
173
|
+
* Estimate size of a value in bytes
|
|
174
|
+
*/
|
|
175
|
+
private estimateSize;
|
|
176
|
+
/**
|
|
177
|
+
* Cleanup resources
|
|
178
|
+
*/
|
|
179
|
+
destroy(): void;
|
|
180
|
+
}
|
|
181
|
+
export default CacheManager;
|
|
@@ -0,0 +1,384 @@
|
|
|
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
|
+
import { EventEmitter } from 'events';
|
|
14
|
+
/**
|
|
15
|
+
* Cache scope enumeration
|
|
16
|
+
*/
|
|
17
|
+
export var CacheScope;
|
|
18
|
+
(function (CacheScope) {
|
|
19
|
+
/** Cache per document */
|
|
20
|
+
CacheScope["DOCUMENT"] = "document";
|
|
21
|
+
/** Cache per page */
|
|
22
|
+
CacheScope["PAGE"] = "page";
|
|
23
|
+
/** Global cache */
|
|
24
|
+
CacheScope["GLOBAL"] = "global";
|
|
25
|
+
/** Session-level cache */
|
|
26
|
+
CacheScope["SESSION"] = "session";
|
|
27
|
+
})(CacheScope || (CacheScope = {}));
|
|
28
|
+
// ============================================================================
|
|
29
|
+
// Cache Manager Implementation
|
|
30
|
+
// ============================================================================
|
|
31
|
+
/**
|
|
32
|
+
* Cache Manager - Complete caching capabilities
|
|
33
|
+
*
|
|
34
|
+
* Provides 10 functions for cache management:
|
|
35
|
+
* 1. set - Store a value
|
|
36
|
+
* 2. get - Retrieve a value
|
|
37
|
+
* 3. has - Check if key exists
|
|
38
|
+
* 4. delete - Remove a key
|
|
39
|
+
* 5. clear - Clear all entries
|
|
40
|
+
* 6. clearScope - Clear entries by scope
|
|
41
|
+
* 7. getStatistics - Get cache statistics
|
|
42
|
+
* 8. setTtl - Set TTL for an entry
|
|
43
|
+
* 9. getKeys - Get all keys
|
|
44
|
+
* 10. prune - Remove expired entries
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```typescript
|
|
48
|
+
* const cache = new CacheManager({
|
|
49
|
+
* maxEntries: 1000,
|
|
50
|
+
* defaultTtl: 60000, // 1 minute
|
|
51
|
+
* evictionPolicy: 'lru',
|
|
52
|
+
* });
|
|
53
|
+
*
|
|
54
|
+
* // Store a value
|
|
55
|
+
* cache.set('page:0:text', extractedText, CacheScope.PAGE);
|
|
56
|
+
*
|
|
57
|
+
* // Retrieve a value
|
|
58
|
+
* const text = cache.get<string>('page:0:text');
|
|
59
|
+
*
|
|
60
|
+
* // Check statistics
|
|
61
|
+
* const stats = cache.getStatistics();
|
|
62
|
+
* console.log(`Hit rate: ${stats.hitRate * 100}%`);
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
export class CacheManager extends EventEmitter {
|
|
66
|
+
constructor(options = {}) {
|
|
67
|
+
super();
|
|
68
|
+
this.cache = new Map();
|
|
69
|
+
this.scopeIndex = new Map();
|
|
70
|
+
// Statistics
|
|
71
|
+
this.hitCount = 0;
|
|
72
|
+
this.missCount = 0;
|
|
73
|
+
this.evictionCount = 0;
|
|
74
|
+
this.options = {
|
|
75
|
+
maxSize: options.maxSize ?? 100 * 1024 * 1024, // 100MB default
|
|
76
|
+
maxEntries: options.maxEntries ?? 10000,
|
|
77
|
+
defaultTtl: options.defaultTtl ?? 0, // 0 = no expiry
|
|
78
|
+
enableStatistics: options.enableStatistics ?? true,
|
|
79
|
+
evictionPolicy: options.evictionPolicy ?? 'lru',
|
|
80
|
+
};
|
|
81
|
+
// Initialize scope index
|
|
82
|
+
for (const scope of Object.values(CacheScope)) {
|
|
83
|
+
this.scopeIndex.set(scope, new Set());
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
// ==========================================================================
|
|
87
|
+
// Core Cache Operations (6 functions)
|
|
88
|
+
// ==========================================================================
|
|
89
|
+
/**
|
|
90
|
+
* Store a value in the cache
|
|
91
|
+
*/
|
|
92
|
+
set(key, value, scope = CacheScope.GLOBAL, ttl) {
|
|
93
|
+
// Check if we need to evict
|
|
94
|
+
this.ensureCapacity();
|
|
95
|
+
const entry = {
|
|
96
|
+
key,
|
|
97
|
+
value,
|
|
98
|
+
timestamp: Date.now(),
|
|
99
|
+
ttl: ttl ?? this.options.defaultTtl,
|
|
100
|
+
size: this.estimateSize(value),
|
|
101
|
+
hits: 0,
|
|
102
|
+
};
|
|
103
|
+
// Remove from old scope if exists
|
|
104
|
+
if (this.cache.has(key)) {
|
|
105
|
+
this.removeFromScopeIndex(key);
|
|
106
|
+
}
|
|
107
|
+
this.cache.set(key, entry);
|
|
108
|
+
this.scopeIndex.get(scope)?.add(key);
|
|
109
|
+
this.emit('cache-set', {
|
|
110
|
+
key,
|
|
111
|
+
scope,
|
|
112
|
+
operation: 'set',
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Retrieve a value from the cache
|
|
117
|
+
*/
|
|
118
|
+
get(key) {
|
|
119
|
+
const entry = this.cache.get(key);
|
|
120
|
+
if (!entry) {
|
|
121
|
+
if (this.options.enableStatistics) {
|
|
122
|
+
this.missCount++;
|
|
123
|
+
}
|
|
124
|
+
this.emit('cache-miss', { key, operation: 'get', hit: false });
|
|
125
|
+
return undefined;
|
|
126
|
+
}
|
|
127
|
+
// Check TTL
|
|
128
|
+
if (entry.ttl && entry.ttl > 0 && Date.now() - entry.timestamp > entry.ttl) {
|
|
129
|
+
this.delete(key);
|
|
130
|
+
if (this.options.enableStatistics) {
|
|
131
|
+
this.missCount++;
|
|
132
|
+
}
|
|
133
|
+
this.emit('cache-expired', { key, operation: 'get', hit: false });
|
|
134
|
+
return undefined;
|
|
135
|
+
}
|
|
136
|
+
// Update hit count for LFU
|
|
137
|
+
const updatedEntry = {
|
|
138
|
+
...entry,
|
|
139
|
+
hits: entry.hits + 1,
|
|
140
|
+
timestamp: this.options.evictionPolicy === 'lru' ? Date.now() : entry.timestamp,
|
|
141
|
+
};
|
|
142
|
+
this.cache.set(key, updatedEntry);
|
|
143
|
+
if (this.options.enableStatistics) {
|
|
144
|
+
this.hitCount++;
|
|
145
|
+
}
|
|
146
|
+
this.emit('cache-hit', { key, operation: 'get', hit: true });
|
|
147
|
+
return entry.value;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Check if a key exists in the cache
|
|
151
|
+
*/
|
|
152
|
+
has(key) {
|
|
153
|
+
const entry = this.cache.get(key);
|
|
154
|
+
if (!entry)
|
|
155
|
+
return false;
|
|
156
|
+
// Check TTL
|
|
157
|
+
if (entry.ttl && entry.ttl > 0 && Date.now() - entry.timestamp > entry.ttl) {
|
|
158
|
+
this.delete(key);
|
|
159
|
+
return false;
|
|
160
|
+
}
|
|
161
|
+
return true;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Remove a key from the cache
|
|
165
|
+
*/
|
|
166
|
+
delete(key) {
|
|
167
|
+
const exists = this.cache.has(key);
|
|
168
|
+
if (exists) {
|
|
169
|
+
this.removeFromScopeIndex(key);
|
|
170
|
+
this.cache.delete(key);
|
|
171
|
+
this.emit('cache-delete', { key, operation: 'delete' });
|
|
172
|
+
}
|
|
173
|
+
return exists;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Clear all entries from the cache
|
|
177
|
+
*/
|
|
178
|
+
clear() {
|
|
179
|
+
const count = this.cache.size;
|
|
180
|
+
this.cache.clear();
|
|
181
|
+
for (const scope of this.scopeIndex.values()) {
|
|
182
|
+
scope.clear();
|
|
183
|
+
}
|
|
184
|
+
this.hitCount = 0;
|
|
185
|
+
this.missCount = 0;
|
|
186
|
+
this.evictionCount = 0;
|
|
187
|
+
this.emit('cache-clear', { key: '*', operation: 'clear' });
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Clear entries by scope
|
|
191
|
+
*/
|
|
192
|
+
clearScope(scope) {
|
|
193
|
+
const keys = this.scopeIndex.get(scope);
|
|
194
|
+
if (!keys)
|
|
195
|
+
return 0;
|
|
196
|
+
const count = keys.size;
|
|
197
|
+
for (const key of keys) {
|
|
198
|
+
this.cache.delete(key);
|
|
199
|
+
}
|
|
200
|
+
keys.clear();
|
|
201
|
+
this.emit('cache-scope-clear', { key: scope, scope, operation: 'clear' });
|
|
202
|
+
return count;
|
|
203
|
+
}
|
|
204
|
+
// ==========================================================================
|
|
205
|
+
// Statistics and Maintenance (4 functions)
|
|
206
|
+
// ==========================================================================
|
|
207
|
+
/**
|
|
208
|
+
* Get cache statistics
|
|
209
|
+
*/
|
|
210
|
+
getStatistics() {
|
|
211
|
+
const entries = Array.from(this.cache.values());
|
|
212
|
+
const totalSize = entries.reduce((sum, e) => sum + (e.size ?? 0), 0);
|
|
213
|
+
const timestamps = entries.map((e) => e.timestamp);
|
|
214
|
+
return {
|
|
215
|
+
totalEntries: this.cache.size,
|
|
216
|
+
totalSize,
|
|
217
|
+
hitCount: this.hitCount,
|
|
218
|
+
missCount: this.missCount,
|
|
219
|
+
hitRate: this.hitCount + this.missCount > 0 ? this.hitCount / (this.hitCount + this.missCount) : 0,
|
|
220
|
+
evictionCount: this.evictionCount,
|
|
221
|
+
oldestEntry: timestamps.length > 0 ? Math.min(...timestamps) : undefined,
|
|
222
|
+
newestEntry: timestamps.length > 0 ? Math.max(...timestamps) : undefined,
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Set TTL for an existing entry
|
|
227
|
+
*/
|
|
228
|
+
setTtl(key, ttl) {
|
|
229
|
+
const entry = this.cache.get(key);
|
|
230
|
+
if (!entry)
|
|
231
|
+
return false;
|
|
232
|
+
const updatedEntry = {
|
|
233
|
+
...entry,
|
|
234
|
+
ttl,
|
|
235
|
+
};
|
|
236
|
+
this.cache.set(key, updatedEntry);
|
|
237
|
+
return true;
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Get all cache keys
|
|
241
|
+
*/
|
|
242
|
+
getKeys(scope) {
|
|
243
|
+
if (scope) {
|
|
244
|
+
return Array.from(this.scopeIndex.get(scope) ?? []);
|
|
245
|
+
}
|
|
246
|
+
return Array.from(this.cache.keys());
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Remove expired entries
|
|
250
|
+
*/
|
|
251
|
+
prune() {
|
|
252
|
+
const now = Date.now();
|
|
253
|
+
let pruned = 0;
|
|
254
|
+
for (const [key, entry] of this.cache.entries()) {
|
|
255
|
+
if (entry.ttl && entry.ttl > 0 && now - entry.timestamp > entry.ttl) {
|
|
256
|
+
this.delete(key);
|
|
257
|
+
pruned++;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
if (pruned > 0) {
|
|
261
|
+
this.emit('cache-prune', { key: '*', operation: 'delete' });
|
|
262
|
+
}
|
|
263
|
+
return pruned;
|
|
264
|
+
}
|
|
265
|
+
// ==========================================================================
|
|
266
|
+
// Helper Methods
|
|
267
|
+
// ==========================================================================
|
|
268
|
+
/**
|
|
269
|
+
* Ensure cache has capacity, evicting if needed
|
|
270
|
+
*/
|
|
271
|
+
ensureCapacity() {
|
|
272
|
+
// Check entry count
|
|
273
|
+
while (this.cache.size >= this.options.maxEntries) {
|
|
274
|
+
this.evictOne();
|
|
275
|
+
}
|
|
276
|
+
// Check total size
|
|
277
|
+
let totalSize = 0;
|
|
278
|
+
for (const entry of this.cache.values()) {
|
|
279
|
+
totalSize += entry.size ?? 0;
|
|
280
|
+
}
|
|
281
|
+
while (totalSize > this.options.maxSize && this.cache.size > 0) {
|
|
282
|
+
const evicted = this.evictOne();
|
|
283
|
+
totalSize -= evicted?.size ?? 0;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Evict one entry based on eviction policy
|
|
288
|
+
*/
|
|
289
|
+
evictOne() {
|
|
290
|
+
if (this.cache.size === 0)
|
|
291
|
+
return undefined;
|
|
292
|
+
let keyToEvict;
|
|
293
|
+
switch (this.options.evictionPolicy) {
|
|
294
|
+
case 'lru':
|
|
295
|
+
// Find oldest timestamp
|
|
296
|
+
keyToEvict = this.findOldestKey();
|
|
297
|
+
break;
|
|
298
|
+
case 'lfu':
|
|
299
|
+
// Find least frequently used
|
|
300
|
+
keyToEvict = this.findLeastUsedKey();
|
|
301
|
+
break;
|
|
302
|
+
case 'fifo':
|
|
303
|
+
default:
|
|
304
|
+
// First key
|
|
305
|
+
keyToEvict = this.cache.keys().next().value;
|
|
306
|
+
break;
|
|
307
|
+
}
|
|
308
|
+
if (keyToEvict) {
|
|
309
|
+
const entry = this.cache.get(keyToEvict);
|
|
310
|
+
this.removeFromScopeIndex(keyToEvict);
|
|
311
|
+
this.cache.delete(keyToEvict);
|
|
312
|
+
this.evictionCount++;
|
|
313
|
+
this.emit('cache-evict', { key: keyToEvict, operation: 'evict' });
|
|
314
|
+
return entry;
|
|
315
|
+
}
|
|
316
|
+
return undefined;
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Find key with oldest timestamp (LRU)
|
|
320
|
+
*/
|
|
321
|
+
findOldestKey() {
|
|
322
|
+
let oldestKey;
|
|
323
|
+
let oldestTime = Infinity;
|
|
324
|
+
for (const [key, entry] of this.cache.entries()) {
|
|
325
|
+
if (entry.timestamp < oldestTime) {
|
|
326
|
+
oldestTime = entry.timestamp;
|
|
327
|
+
oldestKey = key;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
return oldestKey;
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Find key with least hits (LFU)
|
|
334
|
+
*/
|
|
335
|
+
findLeastUsedKey() {
|
|
336
|
+
let leastUsedKey;
|
|
337
|
+
let leastHits = Infinity;
|
|
338
|
+
for (const [key, entry] of this.cache.entries()) {
|
|
339
|
+
if (entry.hits < leastHits) {
|
|
340
|
+
leastHits = entry.hits;
|
|
341
|
+
leastUsedKey = key;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
return leastUsedKey;
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Remove key from scope index
|
|
348
|
+
*/
|
|
349
|
+
removeFromScopeIndex(key) {
|
|
350
|
+
for (const keys of this.scopeIndex.values()) {
|
|
351
|
+
keys.delete(key);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Estimate size of a value in bytes
|
|
356
|
+
*/
|
|
357
|
+
estimateSize(value) {
|
|
358
|
+
if (value === null || value === undefined)
|
|
359
|
+
return 0;
|
|
360
|
+
if (typeof value === 'string')
|
|
361
|
+
return value.length * 2;
|
|
362
|
+
if (typeof value === 'number')
|
|
363
|
+
return 8;
|
|
364
|
+
if (typeof value === 'boolean')
|
|
365
|
+
return 4;
|
|
366
|
+
if (Buffer.isBuffer(value))
|
|
367
|
+
return value.length;
|
|
368
|
+
if (Array.isArray(value)) {
|
|
369
|
+
return value.reduce((sum, v) => sum + this.estimateSize(v), 0);
|
|
370
|
+
}
|
|
371
|
+
if (typeof value === 'object') {
|
|
372
|
+
return JSON.stringify(value).length * 2;
|
|
373
|
+
}
|
|
374
|
+
return 0;
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* Cleanup resources
|
|
378
|
+
*/
|
|
379
|
+
destroy() {
|
|
380
|
+
this.clear();
|
|
381
|
+
this.removeAllListeners();
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
export default CacheManager;
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ComplianceManager - Canonical Compliance Manager (merged from 2 implementations)
|
|
3
|
+
*
|
|
4
|
+
* Consolidates:
|
|
5
|
+
* - src/compliance-manager.ts ComplianceManager (validation + issue analysis + native FFI)
|
|
6
|
+
* - src/managers/ocr-compliance-cache.ts ComplianceManager (validation + conversion + fixing)
|
|
7
|
+
*
|
|
8
|
+
* Provides complete PDF/A, PDF/X, PDF/UA compliance operations.
|
|
9
|
+
*/
|
|
10
|
+
import { EventEmitter } from 'events';
|
|
11
|
+
export declare enum PdfALevel {
|
|
12
|
+
A1a = "PDF/A-1a",
|
|
13
|
+
A1b = "PDF/A-1b",
|
|
14
|
+
A2a = "PDF/A-2a",
|
|
15
|
+
A2b = "PDF/A-2b",
|
|
16
|
+
A3a = "PDF/A-3a",
|
|
17
|
+
A3b = "PDF/A-3b"
|
|
18
|
+
}
|
|
19
|
+
export declare enum PdfXLevel {
|
|
20
|
+
X1a = "PDF/X-1a",
|
|
21
|
+
X1a2001 = "PDF/X-1a:2001",
|
|
22
|
+
X1a2003 = "PDF/X-1a:2003",
|
|
23
|
+
X3 = "PDF/X-3",
|
|
24
|
+
X3_2002 = "PDF/X-3:2002",
|
|
25
|
+
X3_2003 = "PDF/X-3:2003",
|
|
26
|
+
X4 = "PDF/X-4"
|
|
27
|
+
}
|
|
28
|
+
export declare enum PdfUALevel {
|
|
29
|
+
UA1 = "PDF/UA-1",
|
|
30
|
+
UA2 = "PDF/UA-2"
|
|
31
|
+
}
|
|
32
|
+
export declare enum ComplianceIssueType {
|
|
33
|
+
FontNotEmbedded = "font_not_embedded",
|
|
34
|
+
InvalidColorSpace = "invalid_color_space",
|
|
35
|
+
MissingAltText = "missing_alt_text",
|
|
36
|
+
MissingLanguage = "missing_language",
|
|
37
|
+
MissingTitle = "missing_title",
|
|
38
|
+
InvalidAnnotation = "invalid_annotation",
|
|
39
|
+
MissingStructure = "missing_structure",
|
|
40
|
+
InvalidLink = "invalid_link",
|
|
41
|
+
Other = "other"
|
|
42
|
+
}
|
|
43
|
+
export declare enum IssueSeverity {
|
|
44
|
+
Error = "error",
|
|
45
|
+
Warning = "warning",
|
|
46
|
+
Info = "info"
|
|
47
|
+
}
|
|
48
|
+
export interface ComplianceIssue {
|
|
49
|
+
type: ComplianceIssueType;
|
|
50
|
+
severity: IssueSeverity;
|
|
51
|
+
message: string;
|
|
52
|
+
pageIndex?: number;
|
|
53
|
+
}
|
|
54
|
+
export interface ComplianceValidationResult {
|
|
55
|
+
isCompliant: boolean;
|
|
56
|
+
level: string;
|
|
57
|
+
issues: ComplianceIssue[];
|
|
58
|
+
validationTime: number;
|
|
59
|
+
}
|
|
60
|
+
export interface ComplianceResult {
|
|
61
|
+
type: string;
|
|
62
|
+
valid: boolean;
|
|
63
|
+
issues: string[];
|
|
64
|
+
severity: string;
|
|
65
|
+
}
|
|
66
|
+
export declare class ComplianceManager extends EventEmitter {
|
|
67
|
+
private document;
|
|
68
|
+
private resultCache;
|
|
69
|
+
private maxCacheSize;
|
|
70
|
+
private native;
|
|
71
|
+
constructor(document: any);
|
|
72
|
+
validatePdfA(level?: PdfALevel | string): Promise<ComplianceValidationResult>;
|
|
73
|
+
validatePdfX(level?: PdfXLevel | string): Promise<ComplianceValidationResult>;
|
|
74
|
+
validatePdfUA(level?: PdfUALevel | string): Promise<ComplianceValidationResult>;
|
|
75
|
+
getAllIssues(): Promise<ComplianceIssue[]>;
|
|
76
|
+
getIssuesOfType(type: ComplianceIssueType): Promise<ComplianceIssue[]>;
|
|
77
|
+
getIssueCount(): Promise<number>;
|
|
78
|
+
getErrorCount(): Promise<number>;
|
|
79
|
+
getWarningCount(): Promise<number>;
|
|
80
|
+
convertToPdfA(level?: string): Promise<boolean>;
|
|
81
|
+
convertToPdfUA(): Promise<boolean>;
|
|
82
|
+
getComplianceReport(complianceType?: string): Promise<string>;
|
|
83
|
+
checkFontEmbedding(): Promise<boolean>;
|
|
84
|
+
/** @deprecated Use checkFontEmbedding() instead */
|
|
85
|
+
hasFontsEmbedded(): Promise<boolean>;
|
|
86
|
+
checkColorSpace(): Promise<boolean>;
|
|
87
|
+
/** @deprecated Use checkColorSpace() instead */
|
|
88
|
+
hasValidColorSpace(): Promise<boolean>;
|
|
89
|
+
checkTaggedContent(): Promise<boolean>;
|
|
90
|
+
addMissingTags(): Promise<boolean>;
|
|
91
|
+
fixFontIssues(): Promise<number>;
|
|
92
|
+
fixColorIssues(): Promise<number>;
|
|
93
|
+
removeUnsupportedFeatures(): Promise<number>;
|
|
94
|
+
getComplianceIssues(): Promise<string[]>;
|
|
95
|
+
getIssueSeverity(issue: string): string;
|
|
96
|
+
createComplianceReportFile(filePath: string): Promise<boolean>;
|
|
97
|
+
getComplianceSummary(): Promise<object>;
|
|
98
|
+
clearCache(): void;
|
|
99
|
+
getCacheStats(): Record<string, any>;
|
|
100
|
+
destroy(): void;
|
|
101
|
+
private setCached;
|
|
102
|
+
}
|
|
103
|
+
export default ComplianceManager;
|