import { EventEmitter } from '../core/EventEmitter'; /** * Cached job */ export interface CachedJob { /** Unique job identifier */ id: string; /** Print data */ data: Uint8Array; /** Creation timestamp */ createdAt: number; /** Expiry timestamp */ expiresAt: number; /** Retry count */ retryCount: number; /** Last error message */ lastError?: string; /** Additional metadata */ metadata?: Record; } /** * Cache configuration */ export interface CacheConfig { /** Maximum number of cached jobs (default: 50) */ maxJobs: number; /** Job expiry time in ms (default: 24 hours) */ expiryTime: number; /** Storage key prefix (default: 'bt_print_cache_') */ storagePrefix: string; /** Auto sync when connected (default: true) */ autoSync: boolean; } /** * Cache statistics */ export interface CacheStats { /** Total cached jobs */ total: number; /** Expired jobs */ expired: number; /** Pending jobs */ pending: number; } /** * Offline cache events */ export interface OfflineCacheEvents { 'job-saved': CachedJob; 'job-removed': string; 'job-synced': CachedJob; 'sync-started': void; 'sync-completed': { success: number; failed: number; }; 'cleanup-completed': number; error: Error; } /** * Offline cache interface */ export interface IOfflineCache { save(job: CachedJob): void; getAll(): CachedJob[]; remove(jobId: string): void; cleanup(): number; sync(): Promise; getStats(): CacheStats; } /** * Sync executor function type */ export type SyncExecutor = (job: CachedJob) => Promise; /** * Offline Cache class * Manages offline storage for print jobs */ export declare class OfflineCache extends EventEmitter implements IOfflineCache { protected readonly logger: { debug: (message: string, ...args: unknown[]) => void; info: (message: string, ...args: unknown[]) => void; warn: (message: string, ...args: unknown[]) => void; error: (message: string, ...args: unknown[]) => void; }; private readonly config; private readonly JOBS_KEY; private syncExecutor; private isSyncing; /** In-memory cache – null means "not yet loaded from storage" */ private jobCache; /** LRU tracking: job IDs in access order (most recently used at end) */ private lruOrder; /** Maximum cache entries for LRU eviction (default: 100) */ private readonly maxCacheEntries; /** * Creates a new OfflineCache instance */ constructor(config?: Partial); /** * Set the sync executor function */ setSyncExecutor(executor: SyncExecutor): void; /** * Save a job to cache. * Operates on the in-memory cache and persists to storage once. * Includes LRU eviction if cache exceeds max entries. */ save(job: CachedJob): void; /** * Get all cached jobs * Updates LRU order for each job accessed. */ getAll(): CachedJob[]; /** * Remove a job from cache. * Operates on the in-memory cache and persists to storage once. */ remove(jobId: string): void; /** * Cleanup expired jobs. * Operates on the in-memory cache and persists to storage once. */ cleanup(): number; /** * Sync cached jobs (execute them). * * **Optimized**: All processing happens on the in-memory array; a single * persist happens at the end. Previous implementation called remove() * per job → O(n) storage reads/writes → O(n²) total. Now O(n). */ sync(): Promise; /** * Get cache statistics */ getStats(): CacheStats; /** * Check if syncing */ get syncing(): boolean; /** * Create a cached job from print data */ createJob(id: string, data: Uint8Array, metadata?: Record): CachedJob; /** * Clear all cached jobs. * Invalidates the in-memory cache and removes from storage. */ clear(): void; /** * Load jobs – returns in-memory cache when available, otherwise reads * from storage (once) and caches the result. */ private loadJobs; /** * Save jobs to storage. * Also updates the in-memory cache so subsequent reads skip storage. */ private saveJobs; /** * Serialize job for storage. * Uses Base64 encoding for Uint8Array data instead of Array.from() * which would expand each byte to a 64-bit float (8× memory). * Base64 is ~1.33× the original size – a net win. */ private serializeJob; /** * Deserialize job from storage. * Supports both legacy number[] format and new Base64 string format * for backward compatibility. */ private deserializeJob; /** * Evict least recently used jobs if cache exceeds max entries. * Called before adding a new job to prevent unbounded memory growth. */ private evictIfNecessary; /** * Update LRU order for a job ID (move to end = most recently used). */ private updateLRU; } export declare const offlineCache: OfflineCache;