|  | import { atom, map } from 'nanostores'; | 
					
						
						|  | import Cookies from 'js-cookie'; | 
					
						
						|  | import { createScopedLogger } from '~/utils/logger'; | 
					
						
						|  |  | 
					
						
						|  | const logger = createScopedLogger('LogStore'); | 
					
						
						|  |  | 
					
						
						|  | export interface LogEntry { | 
					
						
						|  | id: string; | 
					
						
						|  | timestamp: string; | 
					
						
						|  | level: 'info' | 'warning' | 'error' | 'debug'; | 
					
						
						|  | message: string; | 
					
						
						|  | details?: Record<string, any>; | 
					
						
						|  | category: 'system' | 'provider' | 'user' | 'error'; | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | const MAX_LOGS = 1000; | 
					
						
						|  |  | 
					
						
						|  | class LogStore { | 
					
						
						|  | private _logs = map<Record<string, LogEntry>>({}); | 
					
						
						|  | showLogs = atom(true); | 
					
						
						|  |  | 
					
						
						|  | constructor() { | 
					
						
						|  |  | 
					
						
						|  | this._loadLogs(); | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | private _loadLogs() { | 
					
						
						|  | const savedLogs = Cookies.get('eventLogs'); | 
					
						
						|  |  | 
					
						
						|  | if (savedLogs) { | 
					
						
						|  | try { | 
					
						
						|  | const parsedLogs = JSON.parse(savedLogs); | 
					
						
						|  | this._logs.set(parsedLogs); | 
					
						
						|  | } catch (error) { | 
					
						
						|  | logger.error('Failed to parse logs from cookies:', error); | 
					
						
						|  | } | 
					
						
						|  | } | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | private _saveLogs() { | 
					
						
						|  | const currentLogs = this._logs.get(); | 
					
						
						|  | Cookies.set('eventLogs', JSON.stringify(currentLogs)); | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | private _generateId(): string { | 
					
						
						|  | return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | private _trimLogs() { | 
					
						
						|  | const currentLogs = Object.entries(this._logs.get()); | 
					
						
						|  |  | 
					
						
						|  | if (currentLogs.length > MAX_LOGS) { | 
					
						
						|  | const sortedLogs = currentLogs.sort( | 
					
						
						|  | ([, a], [, b]) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime(), | 
					
						
						|  | ); | 
					
						
						|  | const newLogs = Object.fromEntries(sortedLogs.slice(0, MAX_LOGS)); | 
					
						
						|  | this._logs.set(newLogs); | 
					
						
						|  | } | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | addLog( | 
					
						
						|  | message: string, | 
					
						
						|  | level: LogEntry['level'] = 'info', | 
					
						
						|  | category: LogEntry['category'] = 'system', | 
					
						
						|  | details?: Record<string, any>, | 
					
						
						|  | ) { | 
					
						
						|  | const id = this._generateId(); | 
					
						
						|  | const entry: LogEntry = { | 
					
						
						|  | id, | 
					
						
						|  | timestamp: new Date().toISOString(), | 
					
						
						|  | level, | 
					
						
						|  | message, | 
					
						
						|  | details, | 
					
						
						|  | category, | 
					
						
						|  | }; | 
					
						
						|  |  | 
					
						
						|  | this._logs.setKey(id, entry); | 
					
						
						|  | this._trimLogs(); | 
					
						
						|  | this._saveLogs(); | 
					
						
						|  |  | 
					
						
						|  | return id; | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | logSystem(message: string, details?: Record<string, any>) { | 
					
						
						|  | return this.addLog(message, 'info', 'system', details); | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | logProvider(message: string, details?: Record<string, any>) { | 
					
						
						|  | return this.addLog(message, 'info', 'provider', details); | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | logUserAction(message: string, details?: Record<string, any>) { | 
					
						
						|  | return this.addLog(message, 'info', 'user', details); | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | logError(message: string, error?: Error | unknown, details?: Record<string, any>) { | 
					
						
						|  | const errorDetails = { | 
					
						
						|  | ...(details || {}), | 
					
						
						|  | error: | 
					
						
						|  | error instanceof Error | 
					
						
						|  | ? { | 
					
						
						|  | message: error.message, | 
					
						
						|  | stack: error.stack, | 
					
						
						|  | } | 
					
						
						|  | : error, | 
					
						
						|  | }; | 
					
						
						|  | return this.addLog(message, 'error', 'error', errorDetails); | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | logWarning(message: string, details?: Record<string, any>) { | 
					
						
						|  | return this.addLog(message, 'warning', 'system', details); | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | logDebug(message: string, details?: Record<string, any>) { | 
					
						
						|  | return this.addLog(message, 'debug', 'system', details); | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | clearLogs() { | 
					
						
						|  | this._logs.set({}); | 
					
						
						|  | this._saveLogs(); | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | getLogs() { | 
					
						
						|  | return Object.values(this._logs.get()).sort( | 
					
						
						|  | (a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime(), | 
					
						
						|  | ); | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | getFilteredLogs(level?: LogEntry['level'], category?: LogEntry['category'], searchQuery?: string) { | 
					
						
						|  | return this.getLogs().filter((log) => { | 
					
						
						|  | const matchesLevel = !level || level === 'debug' || log.level === level; | 
					
						
						|  | const matchesCategory = !category || log.category === category; | 
					
						
						|  | const matchesSearch = | 
					
						
						|  | !searchQuery || | 
					
						
						|  | log.message.toLowerCase().includes(searchQuery.toLowerCase()) || | 
					
						
						|  | JSON.stringify(log.details).toLowerCase().includes(searchQuery.toLowerCase()); | 
					
						
						|  |  | 
					
						
						|  | return matchesLevel && matchesCategory && matchesSearch; | 
					
						
						|  | }); | 
					
						
						|  | } | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | export const logStore = new LogStore(); | 
					
						
						|  |  |