feat: Update PDF components to improve rendering performance and manage document lifecycle without caching

This commit is contained in:
2025-09-20 21:28:43 +00:00
parent 7b5ba74d8b
commit d9703d3ce3
6 changed files with 583 additions and 206 deletions

View File

@@ -1,15 +1,6 @@
import { domtools } from '@design.estate/dees-element';
interface CachedDocument {
url: string;
document: any;
lastAccessed: number;
refCount: number;
}
export class PdfManager {
private static cache = new Map<string, CachedDocument>();
private static maxCacheSize = 10;
private static pdfjsLib: any;
private static initialized = false;
@@ -26,83 +17,20 @@ export class PdfManager {
public static async loadDocument(url: string): Promise<any> {
await this.initialize();
// Check cache first
const cached = this.cache.get(url);
if (cached) {
cached.lastAccessed = Date.now();
cached.refCount++;
return cached.document;
}
// Load new document
// IMPORTANT: Disabled caching to ensure component isolation
// Each viewer instance gets its own document to prevent state sharing
// This fixes issues where multiple viewers interfere with each other
const loadingTask = this.pdfjsLib.getDocument(url);
const document = await loadingTask.promise;
// Add to cache with LRU eviction if needed
if (this.cache.size >= this.maxCacheSize) {
this.evictLeastRecentlyUsed();
}
this.cache.set(url, {
url,
document,
lastAccessed: Date.now(),
refCount: 1,
});
return document;
}
public static releaseDocument(url: string) {
const cached = this.cache.get(url);
if (cached) {
cached.refCount--;
if (cached.refCount <= 0) {
// Don't immediately remove, keep for potential reuse
cached.refCount = 0;
}
}
public static releaseDocument(_url: string) {
// No-op since we're not caching documents anymore
// Each viewer manages its own document lifecycle
}
private static evictLeastRecentlyUsed() {
let oldestTime = Infinity;
let oldestKey: string | null = null;
for (const [key, value] of this.cache.entries()) {
// Only evict if not currently in use
if (value.refCount === 0 && value.lastAccessed < oldestTime) {
oldestTime = value.lastAccessed;
oldestKey = key;
}
}
if (oldestKey) {
const cached = this.cache.get(oldestKey);
if (cached?.document) {
cached.document.destroy?.();
}
this.cache.delete(oldestKey);
}
}
public static clearCache() {
for (const cached of this.cache.values()) {
if (cached.document) {
cached.document.destroy?.();
}
}
this.cache.clear();
}
public static getCacheStats() {
return {
size: this.cache.size,
maxSize: this.maxCacheSize,
entries: Array.from(this.cache.entries()).map(([url, data]) => ({
url,
refCount: data.refCount,
lastAccessed: new Date(data.lastAccessed).toISOString(),
})),
};
}
}
// Cache methods removed to ensure component isolation
// Each viewer now manages its own document lifecycle
}