woaru
Version:
Universal Project Setup Autopilot - Analyze and automatically configure development tools for ANY programming language
215 lines • 6.88 kB
JavaScript
import { EventEmitter } from 'events';
/**
* 🎣 WOARU Hook Manager
*
* Zentrale Verwaltung für alle Hook-Registrierungen und -Ausführungen.
* Basiert auf Node.js EventEmitter für maximale Kompatibilität.
*/
export class HookManager extends EventEmitter {
static instance;
hookStats = new Map();
debugMode = false;
constructor() {
super();
this.setMaxListeners(50); // Erlaube mehr Listeners für extensible architecture
}
static getInstance() {
if (!HookManager.instance) {
HookManager.instance = new HookManager();
}
return HookManager.instance;
}
/**
* 🔗 Hook registrieren
*
* @param event Hook-Event Name
* @param handler Handler-Funktion
* @param priority Priorität (höhere Zahl = frühere Ausführung)
*/
registerHook(event, handler, priority = 0) {
const wrappedHandler = async (data) => {
try {
if (this.debugMode) {
console.log(`🎣 Executing hook: ${event} (priority: ${priority})`);
}
await handler(data);
this.incrementHookStats(event);
}
catch (error) {
console.error(`❌ Hook execution failed for ${event}:`, error);
// Emit error hook if it's not already an error hook to prevent loops
if (event !== 'onError') {
this.triggerHook('onError', {
error: error,
context: `Hook execution: ${event}`,
timestamp: new Date(),
});
}
}
};
// Store priority for sorting
wrappedHandler.__priority = priority;
this.on(event, wrappedHandler);
if (this.debugMode) {
console.log(`🎣 Registered hook: ${event} (priority: ${priority})`);
}
}
/**
* 🚀 Hook auslösen
*
* Alle registrierten Handler für das Event werden parallel ausgeführt,
* sortiert nach Priorität (höchste zuerst).
*
* @param event Hook-Event Name
* @param data Event-Daten
*/
async triggerHook(event, data) {
if (this.debugMode) {
console.log(`🎣 Triggering hook: ${event}`);
}
const listeners = this.listeners(event);
if (listeners.length === 0) {
if (this.debugMode) {
console.log(`🎣 No handlers registered for: ${event}`);
}
return;
}
// Sort by priority (höchste zuerst)
const sortedListeners = listeners.sort((a, b) => {
const priorityA = a.__priority || 0;
const priorityB = b.__priority || 0;
return priorityB - priorityA;
});
// Execute all handlers in parallel
const promises = sortedListeners.map(listener => listener(data));
try {
await Promise.all(promises);
if (this.debugMode) {
console.log(`🎣 Hook completed: ${event} (${listeners.length} handlers)`);
}
}
catch (error) {
console.error(`❌ Hook execution error for ${event}:`, error);
throw error;
}
}
/**
* 🗑️ Hook entfernen
*/
unregisterHook(event, handler) {
this.removeListener(event, handler);
if (this.debugMode) {
console.log(`🎣 Unregistered hook: ${event}`);
}
}
/**
* 🧹 Alle Hooks eines Events entfernen
*/
clearHooks(event) {
if (event) {
this.removeAllListeners(event);
if (this.debugMode) {
console.log(`🎣 Cleared all hooks for: ${event}`);
}
}
else {
this.removeAllListeners();
this.hookStats.clear();
if (this.debugMode) {
console.log('🎣 Cleared all hooks');
}
}
}
/**
* 📊 Hook-Statistiken
*/
getHookStats() {
const stats = {};
for (const [event, count] of this.hookStats.entries()) {
stats[event] = count;
}
return stats;
}
/**
* 📋 Registrierte Hooks auflisten
*/
listRegisteredHooks() {
const hooks = {};
const events = [
'beforeAnalysis',
'afterAnalysis',
'beforeFileAnalysis',
'afterFileAnalysis',
'beforeToolExecution',
'afterToolExecution',
'onError',
'onConfigLoad',
'onReportGeneration',
];
for (const event of events) {
hooks[event] = this.listenerCount(event);
}
return hooks;
}
/**
* 🐛 Debug-Modus umschalten
*/
setDebugMode(enabled) {
this.debugMode = enabled;
console.log(`🎣 Hook debug mode: ${enabled ? 'enabled' : 'disabled'}`);
}
incrementHookStats(event) {
const current = this.hookStats.get(event) || 0;
this.hookStats.set(event, current + 1);
}
}
/**
* 🎯 Hook Utilities - Hilfs-Funktionen für häufige Hook-Patterns
*/
export class HookUtils {
/**
* Erstelle einen Hook-Handler mit automatischem Error-Handling
*/
static createSafeHandler(handler, context) {
return async (data) => {
try {
await handler(data);
}
catch (error) {
console.error(`❌ Hook handler error in ${context}:`, error);
// Don't re-throw to prevent breaking the entire hook chain
}
};
}
/**
* Erstelle einen konditionalen Hook-Handler
*/
static createConditionalHandler(condition, handler) {
return async (data) => {
if (condition(data)) {
await handler(data);
}
};
}
/**
* Erstelle einen Rate-Limited Hook-Handler
*/
static createRateLimitedHandler(handler, intervalMs) {
let lastExecuted = 0;
return async (data) => {
const now = Date.now();
if (now - lastExecuted >= intervalMs) {
lastExecuted = now;
await handler(data);
}
};
}
}
// Global Hook Manager Instance Export
export const hookManager = HookManager.getInstance();
// Convenience functions for common operations
export const registerHook = (event, handler, priority) => hookManager.registerHook(event, handler, priority);
export const triggerHook = (event, data) => hookManager.triggerHook(event, data);
export const unregisterHook = (event, handler) => hookManager.unregisterHook(event, handler);
export const clearHooks = (event) => hookManager.clearHooks(event);
//# sourceMappingURL=HookSystem.js.map