UNPKG

visilog

Version:

Stream browser console logs to files for LLM debugging. Zero-config setup with simple imports. No MCP required - just tell your LLM to read the log files.

2 lines â€ĸ 45.8 kB
(()=>{"use strict";var e={3:e=>{e.exports=require("path")},86:e=>{e.exports=require("ws")},176:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.createVitePlugin=o,t.createClientInitCode=function(e={}){return`\nimport { WebSocketLogger } from '@websocket-logger/client/websocket-logger';\n\nconst logger = new WebSocketLogger(${JSON.stringify(e)});\nlogger.enableConsoleOverride();\n\n// Make available globally for debugging\nif (typeof window !== 'undefined') {\n window.__websocketLogger = logger;\n}\n\nexport default logger;\n`},t.checkLoggerServer=async function(e=3001){try{const t=new WebSocket(`ws://localhost:${e}`);return new Promise((e=>{const n=setTimeout((()=>{t.close(),e(!1)}),1e3);t.onopen=()=>{clearTimeout(n),t.close(),e(!0)},t.onerror=()=>{clearTimeout(n),e(!1)}}))}catch{return!1}};const s=n(211);function o(e={}){let t=null,n=!0;const{startServer:o=!0,injectClient:r=!0,development:i=!0,server:a={},client:l={}}=e,c={port:3001,host:"0.0.0.0",logsDir:"logs",...a},g={enableWebSocket:!0,enableConsole:!0,minLevel:0,websocketUrl:`ws://localhost:${c.port}`,maxRetries:5,retryInterval:2e3,autoConnect:!0,...l};return{name:"websocket-logger",configResolved(e){n="serve"===e.command&&i},async configureServer(e){if(n&&o)try{t=new s.WebSocketLoggerServer(c),await t.start(),t.setupGracefulShutdown(),console.log(`🔌 Vite WebSocket Logger Plugin: Server started on port ${c.port}`),e.httpServer?.on("close",(async()=>{t&&(await t.stop(),t=null)}))}catch(e){console.error("❌ Failed to start WebSocket logger server:",e)}},transformIndexHtml:{enforce:"pre",transform(e,t){if(!n||!r)return e;const s=`\n<script type="module">\n import { WebSocketLogger } from '/@websocket-logger/client';\n \n // Initialize logger with configuration\n const logger = new WebSocketLogger(${JSON.stringify(g)});\n \n // Enable console override to capture all console.log calls\n logger.enableConsoleOverride();\n \n // Make logger available globally for debugging\n window.__websocketLogger = logger;\n \n // Log that the logger is ready\n console.log('🔌 WebSocket Logger initialized and ready');\n<\/script>`;return e.replace("</head>",`${s}\n</head>`)}},resolveId:e=>"/@websocket-logger/client"===e?e:null,load:e=>"/@websocket-logger/client"===e?"\nimport { WebSocketLogger } from '@websocket-logger/client/websocket-logger';\nexport { WebSocketLogger };\nexport default WebSocketLogger;\n":null,handleHotUpdate(e){if(e.file.includes("websocket-logger"))return[]},buildStart(){n&&o&&!t&&console.log("🔌 Vite WebSocket Logger Plugin: Preparing to start logging server...")},buildEnd(){t&&console.log("🔌 Vite WebSocket Logger Plugin: Build completed with logging active")},closeBundle:{sequential:!0,async handler(){t&&(console.log("🔌 Vite WebSocket Logger Plugin: Shutting down logger server..."),await t.stop(),t=null)}}}}t.default=o},211:function(e,t,n){var s,o=this&&this.__createBinding||(Object.create?function(e,t,n,s){void 0===s&&(s=n);var o=Object.getOwnPropertyDescriptor(t,n);o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,s,o)}:function(e,t,n,s){void 0===s&&(s=n),e[s]=t[n]}),r=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),i=this&&this.__importStar||(s=function(e){return s=Object.getOwnPropertyNames||function(e){var t=[];for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[t.length]=n);return t},s(e)},function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n=s(e),i=0;i<n.length;i++)"default"!==n[i]&&o(t,e,n[i]);return r(t,e),t});Object.defineProperty(t,"__esModule",{value:!0}),t.WebSocketLoggerServer=void 0;const a=i(n(383)),l=i(n(3)),c=n(86);t.WebSocketLoggerServer=class{constructor(e={}){this.wss=null,this.sessions=new Map,this.cleanupTimer=null,this.sessionHandlers=[],this.logHandlers=[],this.errorHandlers=[],this.config={port:3001,host:"0.0.0.0",maxSessions:50,cleanupThreshold:75,cleanupAmount:25,logsDir:l.join(process.cwd(),"logs"),enableIndex:!0,enableSessionLogs:!0,cleanupInterval:18e5},this.config={...this.config,...e},this.indexFile=l.join(this.config.logsDir,"index.json")}async start(){if(this.wss)throw new Error("Server is already running");try{this.ensureDirectories(),this.wss=new c.WebSocketServer({port:this.config.port,host:this.config.host}),this.setupWebSocketHandlers(),this.startCleanupTimer(),console.log(`🔌 WebSocket logging server started on ${this.config.host}:${this.config.port}`),console.log(`📁 Logs directory: ${this.config.logsDir}`),this.config.enableIndex&&this.initializeIndex()}catch(e){throw this.handleError(e,"Failed to start server"),e}}async stop(){if(this.wss)return console.log("🛑 Shutting down logging server..."),this.cleanupTimer&&(clearInterval(this.cleanupTimer),this.cleanupTimer=null),this.sessions.forEach(((e,t)=>{this.handleSessionClose(t)})),new Promise(((e,t)=>{this.wss.close((n=>{n?(this.handleError(n,"Error stopping server"),t(n)):(this.wss=null,console.log("✅ Logging server stopped"),e())}))}))}ensureDirectories(){if(a.existsSync(this.config.logsDir)||a.mkdirSync(this.config.logsDir,{recursive:!0}),this.config.enableSessionLogs){const e=l.join(this.config.logsDir,"sessions");a.existsSync(e)||a.mkdirSync(e,{recursive:!0})}}setupWebSocketHandlers(){this.wss&&(this.wss.on("connection",((e,t)=>{const n=this.generateSessionId(),s=this.config.enableSessionLogs?l.join(this.config.logsDir,"sessions",`session-${n}.log`):"",o={id:n,startTime:new Date,lastActivity:new Date,messageCount:0},r={...o,ws:e,logFile:s};this.sessions.set(n,r);const i=t.headers["user-agent"]||"unknown",a=t.socket.remoteAddress||"unknown",c=`[SESSION-START] ${n} - ${a} - ${i}`;this.config.enableIndex&&this.updateIndex(),this.config.enableSessionLogs&&s&&this.logToFile(s,c),console.log(`📱 New session: ${n} (${this.sessions.size} active)`),this.sessionHandlers.forEach((e=>{try{e(o)}catch(e){this.handleError(e,"Session handler error")}})),this.sendMessage(e,{type:"session-init",sessionId:n}),e.on("message",(e=>{try{const t=JSON.parse(e.toString());this.handleClientMessage(n,t)}catch(e){this.handleError(e,"Failed to parse client message")}})),e.on("close",(()=>{this.handleSessionClose(n)})),e.on("error",(e=>{this.handleError(e,`WebSocket error for session ${n}`),this.handleSessionClose(n)})),this.checkAndCleanupOldSessions()})),this.wss.on("error",(e=>{this.handleError(e,"WebSocket server error")})))}handleClientMessage(e,t){const n=this.sessions.get(e);if(n)switch(t.type){case"log":t.log&&this.handleLogMessage(e,t.log);break;case"ping":this.sendMessage(n.ws,{type:"pong"});break;case"pong":n.lastActivity=new Date}}sendMessage(e,t){if(e.readyState===c.WebSocket.OPEN)try{e.send(JSON.stringify(t))}catch(e){this.handleError(e,"Failed to send message to client")}}generateSessionId(){return Math.random().toString(36).substring(2,10)}handleLogMessage(e,t){const n=this.sessions.get(e);if(!n)return;n.lastActivity=new Date,n.messageCount++;const s=(new Date).toISOString(),o=this.formatLogMessage(t,s);this.config.enableSessionLogs&&n.logFile&&this.logToFile(n.logFile,o),this.config.enableIndex&&this.updateIndex();const r=`[${e.slice(-6)}] ${t.namespace?`[${t.namespace}] `:""}${t.level.toUpperCase()}: ${t.message}`;switch(t.level){case"error":console.error(`🔴 ${r}`);break;case"warn":console.warn(`🟡 ${r}`);break;case"info":console.info(`â„šī¸ ${r}`);break;case"debug":console.debug(`🔍 ${r}`);break;default:console.log(`📝 ${r}`)}this.logHandlers.forEach((e=>{try{e(t)}catch(e){this.handleError(e,"Log handler error")}}))}formatLogMessage(e,t){const n={timestamp:t,level:e.level,message:e.message,sessionId:e.sessionId,url:e.url,...e.namespace&&{namespace:e.namespace},...e.data&&{data:e.data}};try{return JSON.stringify(n)}catch(n){const s={timestamp:t,level:e.level,message:e.message,sessionId:e.sessionId,url:e.url,error:"Failed to serialize log data",originalError:n instanceof Error?n.message:String(n)};return JSON.stringify(s)}}logToFile(e,t){try{const n=`${t}\n`;a.appendFileSync(e,n)}catch(t){this.handleError(t,`Failed to write to log file: ${e}`)}}initializeIndex(){if(!this.config.enableIndex)return;const e={lastUpdated:(new Date).toISOString(),totalSessions:0,activeSessions:0,sessions:[]};this.writeIndex(e)}writeIndex(e){try{a.writeFileSync(this.indexFile,JSON.stringify(e,null,2))}catch(e){this.handleError(e,`Failed to write index file: ${this.indexFile}`)}}readIndex(){try{if(a.existsSync(this.indexFile)){const e=a.readFileSync(this.indexFile,"utf8");return JSON.parse(e)}}catch(e){this.handleError(e,`Failed to read index file: ${this.indexFile}`)}return{lastUpdated:(new Date).toISOString(),totalSessions:0,activeSessions:0,sessions:[]}}updateIndex(){if(!this.config.enableIndex)return;const e=this.readIndex(),t=Array.from(this.sessions.values());e.activeSessions=t.length,e.lastUpdated=(new Date).toISOString(),t.forEach((t=>{const n=e.sessions.find((e=>e.id===t.id));if(n)n.messageCount=t.messageCount,n.status="active";else{const n={id:t.id,startTime:t.startTime.toISOString(),messageCount:t.messageCount,namespace:t.namespace,logFile:l.relative(this.config.logsDir,t.logFile),status:"active"};e.sessions.push(n),e.totalSessions=Math.max(e.totalSessions,e.sessions.length)}})),this.writeIndex(e)}updateSessionInIndex(e,t,n,s){if(!this.config.enableIndex)return;const o=this.readIndex(),r=o.sessions.find((t=>t.id===e));r&&(r.status=t,n&&(r.endTime=n.toISOString()),s&&(r.duration=s),o.activeSessions=Array.from(this.sessions.values()).length,o.lastUpdated=(new Date).toISOString(),this.writeIndex(o))}handleSessionClose(e){const t=this.sessions.get(e);if(!t)return;const n=Date.now()-t.startTime.getTime(),s=`[SESSION-END] ${e} - Duration: ${Math.round(n/1e3)}s - Messages: ${t.messageCount}`;this.config.enableIndex&&this.updateSessionInIndex(e,"completed",new Date,Math.round(n/1e3)),this.config.enableSessionLogs&&t.logFile&&this.logToFile(t.logFile,s),console.log(`👋 Session ended: ${e} (${t.messageCount} messages, ${Math.round(n/1e3)}s)`),this.sessions.delete(e)}checkAndCleanupOldSessions(){if(!this.config.enableSessionLogs)return;const e=l.join(this.config.logsDir,"sessions");try{const t=a.readdirSync(e).filter((e=>e.startsWith("session-")&&e.endsWith(".log")));t.length>=this.config.cleanupThreshold&&(console.log(`🧹 Session cleanup triggered: ${t.length} files found (threshold: ${this.config.cleanupThreshold})`),this.cleanupOldSessionFiles(t))}catch(e){this.handleError(e,"Failed to check session files")}}cleanupOldSessionFiles(e){const t=l.join(this.config.logsDir,"sessions");try{const n=e.map((e=>{const n=l.join(t,e);return{file:e,path:n,mtime:a.statSync(n).mtime}})).sort(((e,t)=>e.mtime.getTime()-t.mtime.getTime())),s=n.slice(0,this.config.cleanupAmount),o=n.length-s.length;s.forEach((e=>{try{a.unlinkSync(e.path),console.log(`đŸ—‘ī¸ Deleted old session log: ${e.file}`)}catch(t){this.handleError(t,`Failed to delete ${e.file}`)}})),console.log(`✅ Cleanup complete: ${s.length} files deleted, ${o} remaining`)}catch(e){this.handleError(e,"Cleanup process failed")}}startCleanupTimer(){this.cleanupTimer=setInterval((()=>{console.log(`🔍 Periodic cleanup check: ${this.sessions.size} active sessions`),this.checkAndCleanupOldSessions()}),this.config.cleanupInterval)}handleError(e,t){console.error(`❌ WebSocketLoggerServer Error${t?` (${t})`:""}:`,e),this.errorHandlers.forEach((n=>{try{const s=t?{operation:t,component:"WebSocketLoggerServer",timestamp:(new Date).toISOString()}:void 0;n(e,s)}catch(e){console.error("❌ Error handler failed:",e)}}))}onSession(e){return this.sessionHandlers.push(e),()=>{const t=this.sessionHandlers.indexOf(e);t>-1&&this.sessionHandlers.splice(t,1)}}onLog(e){return this.logHandlers.push(e),()=>{const t=this.logHandlers.indexOf(e);t>-1&&this.logHandlers.splice(t,1)}}onError(e){return this.errorHandlers.push(e),()=>{const t=this.errorHandlers.indexOf(e);t>-1&&this.errorHandlers.splice(t,1)}}getStats(){return{activeSessions:this.sessions.size,logsDirectory:this.config.logsDir,indexFile:this.indexFile,maxSessions:this.config.maxSessions,cleanupThreshold:this.config.cleanupThreshold,config:this.config,isRunning:null!==this.wss}}getSessions(){return Array.from(this.sessions.values()).map((e=>({id:e.id,startTime:e.startTime,lastActivity:e.lastActivity,messageCount:e.messageCount,namespace:e.namespace})))}getSession(e){const t=this.sessions.get(e);return t?{id:t.id,startTime:t.startTime,lastActivity:t.lastActivity,messageCount:t.messageCount,namespace:t.namespace}:null}updateConfig(e){this.config={...this.config,...e},this.indexFile=l.join(this.config.logsDir,"index.json"),void 0!==e.cleanupInterval&&(this.cleanupTimer&&clearInterval(this.cleanupTimer),this.startCleanupTimer())}isRunning(){return null!==this.wss}setupGracefulShutdown(){const e=async()=>{console.log("\n🛑 Received shutdown signal...");try{await this.stop(),process.exit(0)}catch(e){console.error("❌ Error during shutdown:",e),process.exit(1)}};process.on("SIGINT",e),process.on("SIGTERM",e)}}},246:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.registry=t.waitForLogger=t.getGlobalLogger=t.createLogger=t.LoggerFactory=void 0;const s=n(668),o=n(491),r=n(335);class i{static createLogger(e={}){this.environmentInfo||(this.environmentInfo=o.EnvironmentDetector.detect());const t={...this.getEnvironmentDefaults(this.environmentInfo),...e},{config:n,validation:r}=s.ConfigValidator.validateAndFix(t);r.warnings.length>0&&console.warn("Visilog configuration warnings:",r.warnings);const i=new a(n,e);return e.name&&this.registry.set(e.name,i),this.defaultLogger||(this.defaultLogger=i),i}static getEnvironmentDefaults(e){const t={enableWebSocket:e.isDevelopment,enableConsole:!0,autoConnect:e.isDevelopment,fallbackMode:"console",enableStructuredLogging:!0,enablePerformanceTracking:e.isDevelopment,maxQueueSize:e.isDevelopment?1e3:500,flushInterval:e.isDevelopment?1e3:5e3,enableOfflineQueue:e.isDevelopment,minLevel:e.isDevelopment?0:2};return e.isBrowser&&e.isDevelopment&&(t.websocketUrl=`ws://${window.location.hostname}:3001`),t}static getRegistry(){return{get:e=>e?this.registry.get(e)||null:this.defaultLogger,create:e=>this.createLogger(e),register:(e,t)=>{this.registry.set(e,t)},unregister:e=>{const t=this.registry.get(e);t&&(t.destroy(),this.registry.delete(e))},list:()=>Array.from(this.registry.keys()),clear:()=>{this.registry.forEach((e=>e.destroy())),this.registry.clear(),this.defaultLogger=null}}}static async waitForLogger(e,t=5e3){const n=this.getRegistry().get(e);return n?new Promise((e=>{if(n.isConnected())return void e(n);const s=setTimeout((()=>{e(n)}),t),o=n.onConnection((t=>{"connected"===t&&(clearTimeout(s),o(),e(n))}))})):null}static getGlobalLogger(){return this.defaultLogger||(this.defaultLogger=this.createLogger({name:"default"})),this.defaultLogger}}t.LoggerFactory=i,i.registry=new Map,i.defaultLogger=null,i.environmentInfo=null;class a{constructor(e,t){this.activeTimers=new Map,this.baseLogger=new r.WebSocketLogger(e),this.factoryConfig=t,!1!==t.autoStart&&this.baseLogger.init(),t.enableAutoRecovery&&this.setupAutoRecovery()}log(e,t){this.logWithEnhancements("log",e,t)}info(e,t){this.logWithEnhancements("info",e,t)}warn(e,t){this.logWithEnhancements("warn",e,t)}error(e,t){this.logWithEnhancements("error",e,t)}debug(e,t){this.logWithEnhancements("debug",e,t)}category(e){const t=Object.create(this);return t.currentCategory=e,t}withContext(e){const t=Object.create(this);return t.currentContext={...this.currentContext,...e},t}startTimer(e){const t=`${e}_${Date.now()}_${Math.random()}`,n=performance.now();return this.activeTimers.set(t,{startTime:n,operation:e}),{end:e=>{const n=this.activeTimers.get(t);if(n){const s=performance.now()-n.startTime;this.activeTimers.delete(t),this.logWithEnhancements("info",`âąī¸ ${n.operation} completed`,{...e,performance:{duration:s,operation:n.operation,timestamp:Date.now()}})}},lap:(e,n)=>{const s=this.activeTimers.get(t);if(s){const t=performance.now()-s.startTime;this.logWithEnhancements("debug",`âąī¸ ${s.operation} - ${e}`,{...n,performance:{duration:t,operation:s.operation,lap:e,timestamp:Date.now()}})}},cancel:()=>{this.activeTimers.delete(t)}}}async connect(){return new Promise(((e,t)=>{if(this.baseLogger.isConnected())return void e();const n=this.factoryConfig.connectionTimeout||5e3,s=setTimeout((()=>{t(new Error(`Connection timeout after ${n}ms`))}),n),o=this.onConnection((n=>{"connected"===n?(clearTimeout(s),o(),e()):"failed"===n&&(clearTimeout(s),o(),t(new Error("Connection failed")))}));this.baseLogger.connect()}))}disconnect(){this.baseLogger.disconnect()}isConnected(){return this.baseLogger.isConnected()}getStatus(){return this.baseLogger.getConnectionStatus()}onLog(e){return this.baseLogger.onLog(e)}onError(e){return this.baseLogger.onError(e)}onConnection(e){return this.baseLogger.onError(((t,n)=>{e("failed",{lastError:t.message})}))}updateConfig(e){this.baseLogger.updateConfig(e)}validateConfig(){return s.ConfigValidator.validate(this.baseLogger.getConfig())}destroy(){this.activeTimers.clear(),this.baseLogger.destroy()}logWithEnhancements(e,t,n){const s={...n,...this.currentContext&&{context:this.currentContext},...this.currentCategory&&{category:this.currentCategory}};switch(e){case"log":this.baseLogger.log(t,s);break;case"info":this.baseLogger.info(t,s);break;case"warn":this.baseLogger.warn(t,s);break;case"error":this.baseLogger.error(t,s);break;case"debug":this.baseLogger.debug(t,s)}if(!this.baseLogger.isConnected()&&this.factoryConfig.customFallback){const n={level:e,message:t,timestamp:(new Date).toISOString(),sessionId:this.baseLogger.getSessionId()||"unknown",data:s,context:this.currentContext,category:this.currentCategory};this.factoryConfig.customFallback(n)}}setupAutoRecovery(){this.onError(((e,t)=>{"WebSocket error"!==t?.operation||this.baseLogger.isConnected()||setTimeout((()=>{this.baseLogger.connect()}),5e3)}))}}t.createLogger=i.createLogger.bind(i),t.getGlobalLogger=i.getGlobalLogger.bind(i),t.waitForLogger=i.waitForLogger.bind(i),t.registry=i.getRegistry()},335:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.WebSocketLogger=void 0,t.WebSocketLogger=class{constructor(e={}){this.ws=null,this.sessionId=null,this.messageQueue=[],this.reconnectAttempts=0,this.reconnectTimer=null,this.isConnecting=!1,this.heartbeatInterval=null,this.logHandlers=[],this.errorHandlers=[],this.config={enableWebSocket:!0,enableConsole:!0,minLevel:0,websocketUrl:"ws://localhost:3001",maxRetries:5,retryInterval:2e3,autoConnect:!0,namespace:void 0},this.levels=[{name:"debug",priority:0,color:"#888888"},{name:"log",priority:1,color:"#000000"},{name:"info",priority:2,color:"#0066cc"},{name:"warn",priority:3,color:"#ff9900"},{name:"error",priority:4,color:"#cc0000"}],this.originalConsole={log:console.log.bind(console),info:console.info.bind(console),warn:console.warn.bind(console),error:console.error.bind(console),debug:console.debug.bind(console)},this.consoleOverridden=!1,this.config={...this.config,...e},this.config.autoConnect&&this.init()}init(){this.config.enableWebSocket&&this.connectWebSocket(),this.log("🔌 WebSocketLogger initialized",{config:this.sanitizeConfig(this.config),url:this.getUrl(),userAgent:this.getUserAgent()})}enableConsoleOverride(){this.consoleOverridden||(console.log=(...e)=>{this.handleLog("log",e)},console.info=(...e)=>{this.handleLog("info",e)},console.warn=(...e)=>{this.handleLog("warn",e)},console.error=(...e)=>{this.handleLog("error",e)},console.debug=(...e)=>{this.handleLog("debug",e)},this.consoleOverridden=!0)}disableConsoleOverride(){this.consoleOverridden&&(console.log=this.originalConsole.log,console.info=this.originalConsole.info,console.warn=this.originalConsole.warn,console.error=this.originalConsole.error,console.debug=this.originalConsole.debug,this.consoleOverridden=!1)}connectWebSocket(){if(!(this.isConnecting||this.ws&&this.ws.readyState===WebSocket.OPEN)){this.isConnecting=!0;try{this.ws=new WebSocket(this.config.websocketUrl),this.ws.onopen=()=>{this.isConnecting=!1,this.reconnectAttempts=0,this.originalConsole.log("🔌 Connected to logging server"),this.startHeartbeat(),this.processMessageQueue()},this.ws.onmessage=e=>{try{const t=JSON.parse(e.data);this.handleServerMessage(t)}catch(e){this.handleError(e,"Failed to parse server message")}},this.ws.onclose=()=>{this.isConnecting=!1,this.stopHeartbeat(),this.originalConsole.warn("🔌 Disconnected from logging server"),this.scheduleReconnect()},this.ws.onerror=e=>{this.isConnecting=!1,this.stopHeartbeat(),this.handleError(new Error("WebSocket connection error"),"WebSocket error"),this.scheduleReconnect()}}catch(e){this.isConnecting=!1,this.handleError(e,"Failed to connect to logging server"),this.scheduleReconnect()}}}handleServerMessage(e){switch(e.type){case"session-init":this.sessionId=e.sessionId||null,this.originalConsole.log(`📱 Session initialized: ${this.sessionId}`);break;case"ping":this.sendMessage({type:"pong"});break;case"error":this.handleError(new Error(e.message||"Server error"),"Server error")}}scheduleReconnect(){if(this.reconnectAttempts>=this.config.maxRetries)return this.originalConsole.warn(`🔌 Max reconnection attempts (${this.config.maxRetries}) reached. Switching to console-only mode.`),void(this.config.enableWebSocket=!1);this.reconnectTimer&&clearTimeout(this.reconnectTimer);const e=this.config.retryInterval*Math.pow(2,this.reconnectAttempts);this.reconnectTimer=setTimeout((()=>{this.reconnectAttempts++,this.originalConsole.log(`🔌 Reconnection attempt ${this.reconnectAttempts}/${this.config.maxRetries}`),this.connectWebSocket()}),e)}startHeartbeat(){this.heartbeatInterval=setInterval((()=>{this.ws&&this.ws.readyState===WebSocket.OPEN&&this.sendMessage({type:"ping"})}),3e4)}stopHeartbeat(){this.heartbeatInterval&&(clearInterval(this.heartbeatInterval),this.heartbeatInterval=null)}processMessageQueue(){for(;this.messageQueue.length>0;){const e=this.messageQueue.shift();e&&this.sendLogMessage(e)}}sendMessage(e){if(this.ws&&this.ws.readyState===WebSocket.OPEN)try{this.ws.send(JSON.stringify(e))}catch(e){this.handleError(e,"Failed to send message")}}sendLogMessage(e){if(this.config.enableWebSocket)if(this.ws&&this.ws.readyState===WebSocket.OPEN)try{this.sendMessage({type:"log",log:e})}catch(t){this.handleError(t,"Failed to send log message"),this.messageQueue.push(e)}else this.messageQueue.push(e),this.messageQueue.length>1e3&&this.messageQueue.shift()}createLogMessage(e,t,n){const s={level:e,message:t,timestamp:(new Date).toISOString(),sessionId:this.sessionId||"unknown",url:this.getUrl(),userAgent:this.getUserAgent(),data:n};return this.config.namespace&&(s.namespace=this.config.namespace),s}handleLog(e,t){const n=this.levels.find((t=>t.name===e));if(!n)return;if(n.priority<this.config.minLevel)return;const s=t.map((e=>{if("object"==typeof e)try{return JSON.stringify(e,null,2)}catch{return String(e)}return String(e)})).join(" "),o=t.filter((e=>"object"==typeof e&&null!==e)),r=o.length>0?o:void 0;this.config.enableConsole&&this.originalConsole[e](...t);const i=this.createLogMessage(e,s,r);this.logHandlers.forEach((e=>{try{e(i)}catch(e){this.handleError(e,"Log handler error")}})),this.sendLogMessage(i)}handleError(e,t){this.originalConsole.error(`❌ WebSocketLogger Error${t?` (${t})`:""}:`,e),this.errorHandlers.forEach((n=>{try{const s=t?{operation:t,component:"WebSocketLogger",timestamp:(new Date).toISOString()}:void 0;n(e,s)}catch(e){this.originalConsole.error("❌ Error handler failed:",e)}}))}getUrl(){return"undefined"!=typeof window&&window.location?window.location.href:"unknown"}getUserAgent(){return"undefined"!=typeof navigator&&navigator.userAgent?navigator.userAgent:"unknown"}sanitizeConfig(e){const{websocketUrl:t,...n}=e;return{...n,websocketUrl:"***"}}log(e,t){this.handleLog("log",[e,t].filter(Boolean))}info(e,t){this.handleLog("info",[e,t].filter(Boolean))}warn(e,t){this.handleLog("warn",[e,t].filter(Boolean))}error(e,t){this.handleLog("error",[e,t].filter(Boolean))}debug(e,t){this.handleLog("debug",[e,t].filter(Boolean))}setMinLevel(e){const t=this.levels.find((t=>t.name===e));t&&(this.config.minLevel=t.priority,this.log(`🔧 Log level set to: ${e}`))}enableWebSocketLogging(e){this.config.enableWebSocket=e,e&&!this.ws?this.connectWebSocket():!e&&this.ws&&this.disconnect(),this.log("🔧 WebSocket logging "+(e?"enabled":"disabled"))}enableConsoleLogging(e){this.config.enableConsole=e,this.log("🔧 Console logging "+(e?"enabled":"disabled"))}updateConfig(e){const t=this.config.websocketUrl;this.config={...this.config,...e},e.websocketUrl&&e.websocketUrl!==t&&this.ws&&(this.disconnect(),this.connectWebSocket())}onLog(e){return this.logHandlers.push(e),()=>{const t=this.logHandlers.indexOf(e);t>-1&&this.logHandlers.splice(t,1)}}onError(e){return this.errorHandlers.push(e),()=>{const t=this.errorHandlers.indexOf(e);t>-1&&this.errorHandlers.splice(t,1)}}getSessionId(){return this.sessionId}getQueueSize(){return this.messageQueue.length}getConnectionStatus(){if(!this.config.enableWebSocket)return"disabled";if(!this.ws)return"disconnected";switch(this.ws.readyState){case WebSocket.CONNECTING:return"connecting";case WebSocket.OPEN:return"connected";case WebSocket.CLOSING:return"closing";case WebSocket.CLOSED:return"closed";default:return"unknown"}}isConnected(){return this.ws?.readyState===WebSocket.OPEN}getConfig(){return{...this.config}}connect(){this.config.enableWebSocket||(this.config.enableWebSocket=!0),this.connectWebSocket()}disconnect(){this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null),this.stopHeartbeat(),this.ws&&(this.ws.close(),this.ws=null),this.sessionId=null,this.reconnectAttempts=0}destroy(){this.disconnect(),this.disableConsoleOverride(),this.logHandlers=[],this.errorHandlers=[],this.messageQueue=[]}}},383:e=>{e.exports=require("fs")},421:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.WebSocketLoggerWebpackPlugin=void 0,t.createWebpackPlugin=function(e={}){return new o(e)};const s=n(211);class o{constructor(e={}){this.loggerServer=null,this.isDevelopment=!0,this.config={startServer:!0,injectClient:!0,development:!0,server:{port:3001,host:"0.0.0.0",logsDir:"logs",...e.server},client:{enableWebSocket:!0,enableConsole:!0,minLevel:0,websocketUrl:`ws://localhost:${e.server?.port||3001}`,maxRetries:5,retryInterval:2e3,autoConnect:!0,...e.client},...e}}apply(e){const t="WebSocketLoggerWebpackPlugin";e.hooks.environment.tap(t,(()=>{this.isDevelopment=this.config.development??"development"===e.options.mode})),e.hooks.beforeCompile.tapAsync(t,(async(e,t)=>{if(this.isDevelopment&&this.config.startServer&&!this.loggerServer)try{this.loggerServer=new s.WebSocketLoggerServer(this.config.server),await this.loggerServer.start(),console.log(`🔌 Webpack WebSocket Logger Plugin: Server started on port ${this.config.server.port}`)}catch(e){console.error("❌ Failed to start WebSocket logger server:",e)}t()})),this.config.injectClient&&(e.hooks.compilation.tap(t,(e=>{if(!this.isDevelopment)return;const n=this.getHtmlWebpackPlugin();if(n)try{const s=n.getHooks?n.getHooks(e):e.hooks.htmlWebpackPluginBeforeHtmlProcessing;s&&s.beforeEmit?s.beforeEmit.tapAsync(t,((e,t)=>{e.html=this.injectClientScript(e.html),t(null,e)})):e.hooks.processAssets?.tap({name:t,stage:e.constructor.PROCESS_ASSETS_STAGE_OPTIMIZE_INLINE},(e=>{Object.keys(e).forEach((t=>{if(t.endsWith(".html")){const n=e[t].source(),s=this.injectClientScript(n);e[t]={source:()=>s,size:()=>s.length}}}))}))}catch(e){console.warn("Failed to hook into HTML webpack plugin:",e)}})),e.hooks.normalModuleFactory.tap(t,(e=>{e.hooks.beforeResolve.tapAsync(t,((e,t)=>{"@websocket-logger/client"===e?.request&&(e.request=this.getClientModulePath()),t()}))}))),e.options.devServer&&e.hooks.afterEnvironment.tap(t,(()=>{const t=e.options.devServer;t.setupMiddlewares||(t.setupMiddlewares=[]),Array.isArray(t.setupMiddlewares)&&t.setupMiddlewares.push(((e,t)=>(t.app?.get("/__websocket-logger-client.js",((e,t)=>{t.setHeader("Content-Type","application/javascript"),t.send(this.generateClientScript())})),e)))})),e.hooks.done.tapAsync(t,(async(e,t)=>{this.loggerServer&&!this.isDevelopment&&(console.log("🔌 Webpack WebSocket Logger Plugin: Shutting down logger server..."),await this.loggerServer.stop(),this.loggerServer=null),t()})),e.hooks.shutdown.tapAsync(t,(async e=>{this.loggerServer&&(await this.loggerServer.stop(),this.loggerServer=null),e()}))}injectClientScript(e){const t=`\n<script>\n ${this.generateClientScript()}\n<\/script>`;return e.includes("</head>")?e.replace("</head>",`${t}\n</head>`):e.includes("<body>")?e.replace("<body>",`<body>\n${t}`):t+e}generateClientScript(){return`\n(function() {\n // Check if WebSocket is available\n if (typeof WebSocket === 'undefined') {\n console.warn('WebSocket not available, skipping logger initialization');\n return;\n }\n\n // Simple WebSocket logger implementation\n class SimpleWebSocketLogger {\n constructor(config) {\n this.config = Object.assign({\n enableWebSocket: true,\n enableConsole: true,\n minLevel: 0,\n websocketUrl: 'ws://localhost:3001',\n maxRetries: 5,\n retryInterval: 2000\n }, config);\n \n this.ws = null;\n this.sessionId = null;\n this.messageQueue = [];\n this.reconnectAttempts = 0;\n this.originalConsole = {\n log: console.log.bind(console),\n info: console.info.bind(console),\n warn: console.warn.bind(console),\n error: console.error.bind(console),\n debug: console.debug.bind(console)\n };\n \n this.init();\n }\n \n init() {\n if (this.config.enableWebSocket) {\n this.connect();\n }\n this.overrideConsole();\n }\n \n connect() {\n try {\n this.ws = new WebSocket(this.config.websocketUrl);\n \n this.ws.onopen = () => {\n this.reconnectAttempts = 0;\n this.processQueue();\n };\n \n this.ws.onmessage = (event) => {\n try {\n const data = JSON.parse(event.data);\n if (data.type === 'session-init') {\n this.sessionId = data.sessionId;\n }\n } catch {\n console.error('Failed to parse server message:', 'Parse error');\n }\n };\n \n this.ws.onclose = () => {\n this.scheduleReconnect();\n };\n \n this.ws.onerror = () => {\n this.scheduleReconnect();\n };\n } catch (connectError) {\n console.error('Failed to connect to logging server:', connectError);\n }\n }\n \n scheduleReconnect() {\n if (this.reconnectAttempts >= this.config.maxRetries) {\n this.config.enableWebSocket = false;\n return;\n }\n \n const delay = this.config.retryInterval * Math.pow(2, this.reconnectAttempts);\n setTimeout(() => {\n this.reconnectAttempts++;\n this.connect();\n }, delay);\n }\n \n processQueue() {\n while (this.messageQueue.length > 0) {\n const message = this.messageQueue.shift();\n this.sendMessage(message);\n }\n }\n \n sendMessage(logMessage) {\n if (!this.config.enableWebSocket) return;\n \n if (this.ws && this.ws.readyState === WebSocket.OPEN) {\n try {\n this.ws.send(JSON.stringify({ type: 'log', log: logMessage }));\n } catch (error) {\n this.messageQueue.push(logMessage);\n }\n } else {\n this.messageQueue.push(logMessage);\n if (this.messageQueue.length > 1000) {\n this.messageQueue.shift();\n }\n }\n }\n \n overrideConsole() {\n const levels = ['log', 'info', 'warn', 'error', 'debug'];\n \n levels.forEach(level => {\n console[level] = (...args) => {\n if (this.config.enableConsole) {\n this.originalConsole[level](...args);\n }\n \n const message = args.map(arg => \n typeof arg === 'object' ? JSON.stringify(arg, null, 2) : String(arg)\n ).join(' ');\n \n const logMessage = {\n level: level,\n message: message,\n timestamp: new Date().toISOString(),\n sessionId: this.sessionId || 'unknown',\n url: window.location.href,\n userAgent: navigator.userAgent,\n data: args.filter(arg => typeof arg === 'object' && arg !== null)\n };\n \n this.sendMessage(logMessage);\n };\n });\n }\n }\n \n // Initialize logger\n const logger = new SimpleWebSocketLogger(${JSON.stringify(this.config.client)});\n \n // Make available globally\n window.__websocketLogger = logger;\n \n console.log('🔌 WebSocket Logger initialized and ready');\n})();\n`}getClientModulePath(){return 335}getHtmlWebpackPlugin(){try{return n(549)}catch{return null}}}t.WebSocketLoggerWebpackPlugin=o,t.default=o},491:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.EnvironmentDetector=void 0;class n{static detect(){if(this.cachedInfo)return this.cachedInfo;const e={isDevelopment:this.isDevelopment(),isProduction:this.isProduction(),isTest:this.isTest(),isBrowser:this.isBrowser(),isNode:this.isNode(),buildTool:this.detectBuildTool(),framework:this.detectFramework()};return this.cachedInfo=e,e}static isDevelopment(){return("undefined"==typeof process||!process.env)&&"undefined"!=typeof window&&("localhost"===window.location.hostname||"127.0.0.1"===window.location.hostname||window.location.hostname.includes("dev")||""!==window.location.port)}static isProduction(){return!("undefined"==typeof process||!process.env)||"undefined"!=typeof window&&!this.isDevelopment()}static isTest(){return"undefined"!=typeof process&&process.env?!!process.env.JEST_WORKER_ID||!!process.env.VITEST||!!process.env.CYPRESS:"undefined"!=typeof window&&!!(window.__karma__||window.jasmine||window.mocha||window.QUnit)}static isBrowser(){return"undefined"!=typeof window&&"undefined"!=typeof document&&"undefined"!=typeof navigator}static isNode(){return"undefined"!=typeof process&&null!=process.versions&&null!=process.versions.node}static detectBuildTool(){if("undefined"!=typeof window&&window.__vite_plugin_react_preamble_installed__)return"vite";if("undefined"!=typeof process&&process.env.VITE)return"vite";if(void 0!==globalThis.__webpack_require__)return"webpack";if("undefined"!=typeof process&&process.env.WEBPACK)return"webpack";if("undefined"!=typeof process&&process.env.ROLLUP)return"rollup";if("undefined"!=typeof process&&process.env.ESBUILD)return"esbuild";if("undefined"!=typeof window){const e=window;if(e.__webpack_public_path__)return"webpack";if(e.__vite__)return"vite"}return"unknown"}static detectFramework(){if("undefined"==typeof window)return"unknown";const e=window;return e.React||e.__REACT_DEVTOOLS_GLOBAL_HOOK__||document.querySelector("[data-reactroot]")||document.querySelector("[data-react-checksum]")?"react":e.Vue||e.__VUE__||document.querySelector("[data-v-]")||document.querySelector(".vue-component")?"vue":e.ng||e.angular||e.getAllAngularRootElements||document.querySelector("[ng-app]")||document.querySelector("[ng-controller]")||document.querySelector("app-root")?"angular":e.__svelte||document.querySelector("[data-svelte]")||document.querySelector(".svelte-component")?"svelte":"unknown"}static clearCache(){this.cachedInfo=null}static getDescription(e){const t=e||this.detect(),n=[];return t.isDevelopment?n.push("Development"):t.isProduction?n.push("Production"):t.isTest&&n.push("Test"),t.isBrowser&&n.push("Browser"),t.isNode&&n.push("Node.js"),t.buildTool&&"unknown"!==t.buildTool&&n.push(t.buildTool.charAt(0).toUpperCase()+t.buildTool.slice(1)),t.framework&&"unknown"!==t.framework&&n.push(t.framework.charAt(0).toUpperCase()+t.framework.slice(1)),n.join(" + ")||"Unknown Environment"}}t.EnvironmentDetector=n,n.cachedInfo=null},549:e=>{e.exports=require("html-webpack-plugin")},668:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.ConfigValidator=void 0;class n{static validate(e){const t=[],n=[],s={...e};for(const o of this.VALIDATION_RULES){const r=e[o.field],i=this.validateField(o,r);i.error&&t.push(i.error),i.warning&&n.push(i.warning),void 0!==i.fixedValue&&(s[o.field]=i.fixedValue)}const o=this.validateCrossFields(e);return t.push(...o.errors),n.push(...o.warnings),this.applyIntelligentFixes(s,t,n),{isValid:0===t.length,errors:t,warnings:n,fixedConfig:t.length>0?s:void 0}}static validateField(e,t){const n={};if(e.required&&null==t)return n.error={field:e.field,message:`Required field '${e.field}' is missing`,value:t,suggestion:`Add '${e.field}: ${this.getDefaultValue(e.field)}' to your configuration`},n.fixedValue=this.getDefaultValue(e.field),n;if(!e.required&&null==t)return n;const s=this.validateType(e,t);return s.error?(n.error=s.error,n.fixedValue=s.fixedValue,n):void 0!==e.min&&"number"==typeof t&&t<e.min?(n.error={field:e.field,message:`Value ${t} is below minimum ${e.min}`,value:t,suggestion:`Use a value >= ${e.min}. Recommended: ${e.min}`},n.fixedValue=e.min,n):(void 0!==e.max&&"number"==typeof t&&t>e.max&&(n.warning={field:e.field,message:`Value ${t} is above recommended maximum ${e.max}`,value:t,suggestion:`Consider using a value <= ${e.max} for better performance`}),e.allowedValues&&!e.allowedValues.includes(t)?(n.error={field:e.field,message:`Invalid value '${t}'. Must be one of: ${e.allowedValues.join(", ")}`,value:t,suggestion:`Use one of: ${e.allowedValues.join(", ")}`},n.fixedValue=e.allowedValues[0],n):e.pattern&&"string"==typeof t&&!e.pattern.test(t)?(n.error={field:e.field,message:`Value '${t}' does not match required pattern`,value:t,suggestion:this.getPatternSuggestion(e.field,e.pattern)},n.fixedValue=this.getPatternDefault(e.field),n):n)}static validateType(e,t){const n=typeof t;switch(e.type){case"boolean":if("boolean"!==n)return"true"===t||1===t||"1"===t?{fixedValue:!0}:"false"===t||0===t||"0"===t?{fixedValue:!1}:{error:{field:e.field,message:`Expected boolean, got ${n}`,value:t,suggestion:`Use true or false instead of '${t}'`},fixedValue:Boolean(t)};break;case"number":case"positive-number":if("number"!==n){const s=Number(t);return isNaN(s)?{error:{field:e.field,message:`Expected number, got ${n}`,value:t,suggestion:`Use a numeric value like ${this.getDefaultValue(e.field)}`},fixedValue:this.getDefaultValue(e.field)}:{fixedValue:s}}if("positive-number"===e.type&&t<0)return{error:{field:e.field,message:`Expected positive number, got ${t}`,value:t,suggestion:`Use a positive number like ${Math.abs(t)}`},fixedValue:Math.abs(t)};break;case"string":if("string"!==n)return{error:{field:e.field,message:`Expected string, got ${n}`,value:t,suggestion:`Use a string value like "${String(t)}"`},fixedValue:String(t)};break;case"url":if("string"!==n)return{error:{field:e.field,message:`Expected URL string, got ${n}`,value:t,suggestion:'Use a valid WebSocket URL like "ws://localhost:3001"'},fixedValue:"ws://localhost:3001"};try{new URL(t)}catch{return{error:{field:e.field,message:`Invalid URL format: ${t}`,value:t,suggestion:'Use a valid WebSocket URL like "ws://localhost:3001"'},fixedValue:"ws://localhost:3001"}}}return{}}static validateCrossFields(e){const t=[],n=[];return!1===e.enableWebSocket&&!1===e.enableConsole&&t.push({field:"enableWebSocket",message:"Both WebSocket and console logging are disabled",value:e.enableWebSocket,suggestion:"Enable at least one logging method: enableWebSocket: true or enableConsole: true"}),e.maxQueueSize&&e.maxQueueSize>5e3&&n.push({field:"maxQueueSize",message:"Large queue size may impact memory usage",value:e.maxQueueSize,suggestion:"Consider using a smaller queue size (< 5000) for better performance"}),e.maxRetries&&e.retryInterval&&e.maxRetries*e.retryInterval>6e4&&n.push({field:"maxRetries",message:"Total retry time exceeds 1 minute",value:e.maxRetries,suggestion:"Consider reducing maxRetries or retryInterval for faster failure detection"}),{errors:t,warnings:n}}static applyIntelligentFixes(e,t,n){e.websocketUrl&&(e.websocketUrl.startsWith("http://")?e.websocketUrl=e.websocketUrl.replace("http://","ws://"):e.websocketUrl.startsWith("https://")&&(e.websocketUrl=e.websocketUrl.replace("https://","wss://"))),e.namespace&&"string"==typeof e.namespace&&(e.namespace=e.namespace.trim().toLowerCase().replace(/\s+/g,"-")),e.enablePerformanceTracking&&!e.flushInterval&&(e.flushInterval=1e3)}static getDefaultValue(e){return this.DEFAULT_CONFIG[e]}static getPatternSuggestion(e,t){return"websocketUrl"===e?'Use a WebSocket URL format like "ws://localhost:3001" or "wss://example.com/ws"':`Value must match pattern: ${t.source}`}static getPatternDefault(e){return"websocketUrl"===e?"ws://localhost:3001":this.getDefaultValue(e)}static withDefaults(e={}){return{...this.DEFAULT_CONFIG,...e}}static validateAndFix(e){const t=this.validate(e);return{config:this.withDefaults(t.fixedConfig||e),validation:t}}}t.ConfigValidator=n,n.VALIDATION_RULES=[{field:"enableWebSocket",type:"boolean",required:!0},{field:"enableConsole",type:"boolean",required:!0},{field:"minLevel",type:"number",required:!0,min:0,max:4,allowedValues:[0,1,2,3,4]},{field:"websocketUrl",type:"url",required:!0,pattern:/^wss?:\/\/.+/},{field:"maxRetries",type:"positive-number",required:!0,min:0,max:100},{field:"retryInterval",type:"positive-number",required:!0,min:100,max:6e4},{field:"autoConnect",type:"boolean",required:!0},{field:"namespace",type:"string",required:!1},{field:"fallbackMode",type:"string",required:!1,allowedValues:["console","silent","custom"]},{field:"maxQueueSize",type:"positive-number",required:!1,min:1,max:1e4},{field:"flushInterval",type:"positive-number",required:!1,min:100,max:3e4}],n.DEFAULT_CONFIG={enableWebSocket:!0,enableConsole:!0,minLevel:0,websocketUrl:"ws://localhost:3001",maxRetries:5,retryInterval:2e3,autoConnect:!0,namespace:void 0,fallbackMode:"console",enableStructuredLogging:!0,enablePerformanceTracking:!1,maxQueueSize:1e3,flushInterval:5e3,enableOfflineQueue:!0,enableCompression:!1}},749:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.fastify=t.koa=t.express=void 0,t.createDevMiddleware=o;const s=n(211);function o(e={}){const{port:t=3001,host:n="0.0.0.0",injectScript:o=!0,logsDir:r="logs",enabled:i=!1}=e;let a=null;return i&&(a=new s.WebSocketLoggerServer({port:t,host:n,logsDir:r}),a.start().then((()=>{console.log(`🔌 VisiLog middleware: WebSocket server started on ${n}:${t}`)})).catch((e=>{console.error("❌ VisiLog middleware: Failed to start server:",e)})),process.on("SIGTERM",(()=>a?.stop())),process.on("SIGINT",(()=>a?.stop()))),(e,n,s)=>{if(!i||!o)return s();const r=n.send;n.send=function(e){if("string"==typeof e&&e.includes("<html")){const n=`\n<script>\n // VisiLog auto-injected client\n (function() {\n if (typeof window === 'undefined') return;\n \n const script = document.createElement('script');\n script.src = 'https://unpkg.com/visilog/dist/browser.js';\n script.onload = function() {\n if (window.VisiLog && window.VisiLog.isDevEnvironment()) {\n window.VisiLog.connect('ws://' + window.location.hostname + ':${t}');\n }\n };\n document.head.appendChild(script);\n })();\n<\/script>`;e.includes("</head>")?e=e.replace("</head>",n+"\n</head>"):e.includes("<head>")&&(e=e.replace("<head>","<head>\n"+n))}return r.call(this,e)},s()}}t.express=o,t.koa=(e={})=>{const t=o(e);return(e,n)=>new Promise(((s,o)=>{t(e.request,e.response,(e=>{e?o(e):s(n())}))}))},t.fastify=(e={})=>{const t=o(e);return(e,n,s)=>{t(e,n,s)}}}},t={};function n(s){var o=t[s];if(void 0!==o)return o.exports;var r=t[s]={exports:{}};return e[s].call(r.exports,r,r.exports,n),r.exports}var s={};(()=>{var e=s;Object.defineProperty(e,"__esModule",{value:!0}),e.EnvironmentDetector=e.ConfigValidator=e.registry=e.waitForLogger=e.getGlobalLogger=e.createLogger=e.LoggerFactory=e.fastify=e.koa=e.express=e.createDevMiddleware=e.createWebpackPlugin=e.createVitePlugin=e.WebSocketLoggerServer=e.WebSocketLogger=void 0;var t=n(335);Object.defineProperty(e,"WebSocketLogger",{enumerable:!0,get:function(){return t.WebSocketLogger}});var o=n(211);Object.defineProperty(e,"WebSocketLoggerServer",{enumerable:!0,get:function(){return o.WebSocketLoggerServer}});var r=n(176);Object.defineProperty(e,"createVitePlugin",{enumerable:!0,get:function(){return r.createVitePlugin}});var i=n(421);Object.defineProperty(e,"createWebpackPlugin",{enumerable:!0,get:function(){return i.createWebpackPlugin}});var a=n(749);Object.defineProperty(e,"createDevMiddleware",{enumerable:!0,get:function(){return a.createDevMiddleware}}),Object.defineProperty(e,"express",{enumerable:!0,get:function(){return a.express}}),Object.defineProperty(e,"koa",{enumerable:!0,get:function(){return a.koa}}),Object.defineProperty(e,"fastify",{enumerable:!0,get:function(){return a.fastify}});var l=n(246);Object.defineProperty(e,"LoggerFactory",{enumerable:!0,get:function(){return l.LoggerFactory}}),Object.defineProperty(e,"createLogger",{enumerable:!0,get:function(){return l.createLogger}}),Object.defineProperty(e,"getGlobalLogger",{enumerable:!0,get:function(){return l.getGlobalLogger}}),Object.defineProperty(e,"waitForLogger",{enumerable:!0,get:function(){return l.waitForLogger}}),Object.defineProperty(e,"registry",{enumerable:!0,get:function(){return l.registry}});var c=n(668);Object.defineProperty(e,"ConfigValidator",{enumerable:!0,get:function(){return c.ConfigValidator}});var g=n(491);Object.defineProperty(e,"EnvironmentDetector",{enumerable:!0,get:function(){return g.EnvironmentDetector}})})(),module.exports.visilog=s})(); //# sourceMappingURL=index.js.map