@casoon/auditmysite
Version:
A comprehensive command-line tool for automated accessibility, security, performance, and SEO testing using Playwright and pa11y, based on sitemap URLs
286 lines • 9.29 kB
JavaScript
"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