'use client'; import React, { createContext, useContext, ReactNode, useMemo, useRef, useEffect } from 'react'; import { useLogger, LogEntry, LogLevel } from './use-logger'; const LOG_LEVELS: LogLevel[] = ['info', 'warn', 'error']; interface LoggerContextType { logs: LogEntry[]; isVisible: boolean; toggleVisibility: () => void; clearLogs: () => void; info: (message: string, payload?: any) => string; warn: (message: string, payload?: any) => string; error: (message: string, payload?: any) => string; isDevelopment: boolean; hasError: boolean; hasWarning: boolean; } const LoggerContext = createContext(undefined); let globalAddLogFunction: | ((level: string, message: string, payload?: any) => string) | null = null; // temporary queue for logs generated before the logger is initialized const pendingLogs: Array<{ level: string; message: string; payload?: any }> = []; const createLogFunction = (level: LogLevel) => (message: string, payload?: any) => { if ( typeof window !== 'undefined' && process.env.NODE_ENV === 'development' ) { try { if (globalAddLogFunction) { globalAddLogFunction(level, message, payload); } else { pendingLogs.push({ level, message, payload }); } } catch (err) { // prevent errors } } return ''; }; const stableLogger = LOG_LEVELS.reduce((logger, level) => { logger[level] = createLogFunction(level); return logger; }, {} as Record string>); export const LoggerProvider = ({ children }: { children: ReactNode }) => { const loggerHook = useLogger(); const addLogRef = useRef< (level: string, message: string, payload?: any) => string >((level, message, payload) => { if (LOG_LEVELS.includes(level as LogLevel)) { return loggerHook[level as LogLevel](message, payload); } return ''; }); useEffect(() => { globalAddLogFunction = addLogRef.current; if (pendingLogs.length > 0) { pendingLogs.forEach((log) => { if (globalAddLogFunction) { globalAddLogFunction(log.level, log.message, log.payload); } }); pendingLogs.length = 0; } return () => { globalAddLogFunction = null; }; }, []); const contextValue = useMemo( () => loggerHook, [loggerHook.logs, loggerHook.isVisible, loggerHook.isDevelopment] // eslint-disable-line react-hooks/exhaustive-deps ); return ( {children} ); }; export const useLoggerContext = () => { const context = useContext(LoggerContext); if (context === undefined) { throw new Error('useLoggerContext must be used within a LoggerProvider'); } return context; }; export const devLogger = stableLogger;