UNPKG

@casoon/auditmysite

Version:

Professional website analysis suite with robust accessibility testing, Core Web Vitals performance monitoring, SEO analysis, and content optimization insights. Features isolated browser contexts, retry mechanisms, and comprehensive API endpoints for profe

286 lines 9.29 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.PriorityQueue = void 0; class PriorityQueue { constructor(options = {}) { this.queue = []; this.processing = new Set(); this.completed = []; this.failed = []; this.itemIdCounter = 0; this.options = { maxSize: 1000, defaultPriority: 5, maxAttempts: 3, retryDelay: 1000, enablePriorityBoost: true, priorityBoostThreshold: 30, // 30 Sekunden priorityBoostAmount: 2, ...options }; } enqueue(data, priority, id) { if (this.queue.length >= this.options.maxSize) { throw new Error(`Queue is full (max size: ${this.options.maxSize})`); } const itemId = id || `item_${++this.itemIdCounter}`; const item = { id: itemId, data, priority: priority ?? this.options.defaultPriority, timestamp: new Date(), attempts: 0, maxAttempts: this.options.maxAttempts, status: 'pending' }; this.queue.push(item); this.sortQueue(); return itemId; } dequeue() { if (this.queue.length === 0) { return null; } // Priority Boost für alte Items if (this.options.enablePriorityBoost) { this.applyPriorityBoost(); } const item = this.queue.shift(); item.status = 'processing'; item.startedAt = new Date(); this.processing.add(item.id); return item; } peek() { if (this.queue.length === 0) { return null; } return this.queue[0]; } complete(id, result) { const item = this.findItem(id); if (!item || item.status !== 'processing') { return false; } item.status = 'completed'; item.result = result; item.completedAt = new Date(); item.duration = item.completedAt.getTime() - item.startedAt.getTime(); this.processing.delete(id); this.completed.push(item); return true; } fail(id, error) { const item = this.findItem(id); if (!item || item.status !== 'processing') { return false; } item.attempts++; item.error = error; if (item.attempts >= item.maxAttempts) { item.status = 'failed'; item.completedAt = new Date(); item.duration = item.completedAt.getTime() - item.startedAt.getTime(); this.processing.delete(id); this.failed.push(item); } else { item.status = 'retrying'; item.priority += this.options.priorityBoostAmount; // Boost für Retry // Zurück in die Queue für Retry this.queue.push(item); this.sortQueue(); } this.processing.delete(id); return true; } retry(id) { const item = this.findItem(id); if (!item || item.status !== 'retrying') { return false; } item.status = 'pending'; item.startedAt = undefined; item.completedAt = undefined; item.duration = undefined; this.sortQueue(); return true; } remove(id) { const index = this.queue.findIndex(item => item.id === id); if (index === -1) { return false; } this.queue.splice(index, 1); this.processing.delete(id); return true; } clear() { this.queue = []; this.processing.clear(); this.completed = []; this.failed = []; } getById(id) { return this.findItem(id); } updatePriority(id, newPriority) { const item = this.findItem(id); if (!item) { return false; } item.priority = newPriority; this.sortQueue(); return true; } getStats() { const now = new Date(); const total = this.queue.length + this.processing.size + this.completed.length + this.failed.length; const pending = this.queue.filter(item => item.status === 'pending').length; const processing = this.processing.size; const completed = this.completed.length; const failed = this.failed.length; const retrying = this.queue.filter(item => item.status === 'retrying').length; const allItems = [...this.queue, ...this.completed, ...this.failed]; const averagePriority = allItems.length > 0 ? allItems.reduce((sum, item) => sum + item.priority, 0) / allItems.length : 0; const averageWaitTime = this.completed.length > 0 ? this.completed.reduce((sum, item) => sum + (item.startedAt.getTime() - item.timestamp.getTime()), 0) / this.completed.length : 0; const averageProcessingTime = this.completed.length > 0 ? this.completed.reduce((sum, item) => sum + (item.duration || 0), 0) / this.completed.length : 0; const oldestItem = this.queue.length > 0 ? this.queue[this.queue.length - 1] : undefined; const newestItem = this.queue.length > 0 ? this.queue[0] : undefined; return { total, pending, processing, completed, failed, retrying, averagePriority: Math.round(averagePriority * 100) / 100, averageWaitTime: Math.round(averageWaitTime), averageProcessingTime: Math.round(averageProcessingTime), oldestItem, newestItem }; } getPendingItems() { return this.queue.filter(item => item.status === 'pending'); } getProcessingItems() { return Array.from(this.processing).map(id => this.findItem(id)).filter(Boolean); } getCompletedItems() { return [...this.completed]; } getFailedItems() { return [...this.failed]; } getRetryingItems() { return this.queue.filter(item => item.status === 'retrying'); } isEmpty() { return this.queue.length === 0 && this.processing.size === 0; } isFull() { return this.queue.length >= this.options.maxSize; } size() { return this.queue.length; } processingSize() { return this.processing.size; } // Private Methods findItem(id) { // In Queue suchen const queueItem = this.queue.find(item => item.id === id); if (queueItem) return queueItem; // In Processing suchen if (this.processing.has(id)) { // Item ist in Processing, aber nicht mehr in Queue // Das sollte nicht passieren, aber zur Sicherheit return null; } // In Completed suchen const completedItem = this.completed.find(item => item.id === id); if (completedItem) return completedItem; // In Failed suchen const failedItem = this.failed.find(item => item.id === id); if (failedItem) return failedItem; return null; } sortQueue() { this.queue.sort((a, b) => { // Höchste Priorität zuerst if (a.priority !== b.priority) { return b.priority - a.priority; } // Bei gleicher Priorität: Ältestes zuerst (FIFO) return a.timestamp.getTime() - b.timestamp.getTime(); }); } applyPriorityBoost() { const now = new Date(); const threshold = this.options.priorityBoostThreshold * 1000; // zu Millisekunden this.queue.forEach(item => { const waitTime = now.getTime() - item.timestamp.getTime(); if (waitTime > threshold && item.status === 'pending') { item.priority += this.options.priorityBoostAmount; } }); // Neu sortieren nach Boost this.sortQueue(); } // Utility Methods getMaxSize() { return this.options.maxSize; } setMaxSize(maxSize) { this.options.maxSize = maxSize; } getDefaultPriority() { return this.options.defaultPriority; } setDefaultPriority(priority) { this.options.defaultPriority = priority; } getMaxAttempts() { return this.options.maxAttempts; } setMaxAttempts(maxAttempts) { this.options.maxAttempts = maxAttempts; } // Batch Operations enqueueBatch(items) { const ids = []; for (const item of items) { try { const id = this.enqueue(item.data, item.priority, item.id); ids.push(id); } catch (error) { console.warn(`Failed to enqueue item: ${error}`); } } return ids; } dequeueBatch(count) { const items = []; for (let i = 0; i < count && this.queue.length > 0; i++) { const item = this.dequeue(); if (item) { items.push(item); } } return items; } } exports.PriorityQueue = PriorityQueue; //# sourceMappingURL=priority-queue.js.map