{"version":3,"file":"LoggingUtils.mjs","sources":["../src/LoggingUtils.ts"],"sourcesContent":["/**\n * @module LoggingUtils\n * @description A comprehensive collection of utility functions for logging, performance monitoring, and debugging.\n * Provides methods for logging messages with different severity levels (debug, info, warn, error),\n * managing log entries with storage, filtering, and export/import capabilities,\n * measuring performance and memory usage, and formatting console output with grouping.\n * @example\n * ```typescript\n * import { LoggingUtils } from 'houser-js-utils';\n *\n * // Basic logging with different levels\n * LoggingUtils.debug(\"Processing started\", { prefix: \"DataService\" });\n * LoggingUtils.info(\"User logged in\", { data: { userId: \"123\" } });\n * LoggingUtils.warn(\"High memory usage\", { data: { usage: \"85%\" } });\n * LoggingUtils.error(\"API call failed\", { data: error, stackTrace: true });\n *\n * // Performance measurement\n * const endMeasurement = LoggingUtils.measurePerformance(\"Data processing\");\n * // ... do some work ...\n * endMeasurement();\n *\n * // Memory usage tracking\n * LoggingUtils.measureMemory(\"After data load\");\n * ```\n */\n\ntype LogLevel = \"debug\" | \"info\" | \"warn\" | \"error\";\n\ninterface LogOptions {\n  level?: LogLevel;\n  timestamp?: boolean;\n  prefix?: string;\n  group?: boolean;\n  groupCollapsed?: boolean;\n  stackTrace?: boolean;\n  data?: unknown;\n}\n\ninterface LogEntry {\n  timestamp: string;\n  level: LogLevel;\n  message: string;\n  data?: unknown;\n  stack?: string;\n}\n\ninterface PerformanceMemory {\n  totalJSHeapSize: number;\n  usedJSHeapSize: number;\n  jsHeapSizeLimit: number;\n}\n\ndeclare global {\n  interface Performance {\n    memory?: PerformanceMemory;\n  }\n}\n\nexport const LoggingUtils = {\n  /**\n   * Default configuration options for logging.\n   * @default\n   * ```typescript\n   * {\n   *   level: \"info\",\n   *   timestamp: true,\n   *   prefix: \"\",\n   *   group: false,\n   *   groupCollapsed: false,\n   *   stackTrace: false\n   * }\n   * ```\n   */\n  defaultOptions: {\n    level: \"info\" as LogLevel,\n    timestamp: true,\n    prefix: \"\",\n    group: false,\n    groupCollapsed: false,\n    stackTrace: false,\n  },\n\n  /**\n   * Internal storage for all log entries.\n   * @default []\n   */\n  logEntries: [] as LogEntry[],\n\n  /**\n   * Maximum number of log entries to store before removing oldest entries.\n   * @default 1000\n   */\n  maxLogEntries: 1000,\n\n  /**\n   * Clears all stored log entries from memory.\n   * @example\n   * ```typescript\n   * // Clear all stored logs\n   * LoggingUtils.clearLogEntries();\n   * console.log(\"Logs cleared\");\n   *\n   * // Clear logs after exporting\n   * const logs = LoggingUtils.exportLogEntries();\n   * LoggingUtils.clearLogEntries();\n   * ```\n   */\n  clearLogEntries(): void {\n    this.logEntries = [];\n  },\n\n  /**\n   * Logs a debug message with optional metadata.\n   * @param message - The debug message to log\n   * @param options - Optional configuration for the log entry\n   * @example\n   * ```typescript\n   * // Simple debug message\n   * LoggingUtils.debug(\"Processing started\");\n   *\n   * // Debug with data and prefix\n   * LoggingUtils.debug(\"Data processed\", {\n   *   prefix: \"DataService\",\n   *   data: { count: 100, status: \"success\" }\n   * });\n   *\n   * // Debug with grouping\n   * LoggingUtils.debug(\"Complex operation\", {\n   *   group: true,\n   *   groupCollapsed: true,\n   *   data: { steps: [\"step1\", \"step2\"] }\n   * });\n   * ```\n   */\n  debug(message: string, options: Omit<LogOptions, \"level\"> = {}): void {\n    this.log(message, { ...options, level: \"debug\" });\n  },\n\n  /**\n   * Logs an error message with optional stack trace and metadata.\n   * @param message - The error message to log\n   * @param options - Optional configuration for the log entry\n   * @example\n   * ```typescript\n   * try {\n   *   // ... some code that might throw\n   * } catch (error) {\n   *   LoggingUtils.error(\"Failed to process data\", {\n   *     data: error,\n   *     prefix: \"DataService\",\n   *     stackTrace: true\n   *   });\n   * }\n   *\n   * // Error with custom data\n   * LoggingUtils.error(\"API request failed\", {\n   *   data: {\n   *     status: 500,\n   *     endpoint: \"/api/data\",\n   *     response: \"Internal Server Error\"\n   *   }\n   * });\n   * ```\n   */\n  error(message: string, options: Omit<LogOptions, \"level\"> = {}): void {\n    this.log(message, { ...options, level: \"error\", stackTrace: true });\n  },\n\n  /**\n   * Exports all stored log entries as a formatted JSON string.\n   * @returns A JSON string containing all log entries\n   * @example\n   * ```typescript\n   * // Export logs to file\n   * const logs = LoggingUtils.exportLogEntries();\n   * const blob = new Blob([logs], { type: 'application/json' });\n   * const url = URL.createObjectURL(blob);\n   *\n   * // Export logs to server\n   * const logs = LoggingUtils.exportLogEntries();\n   * await fetch('/api/logs', {\n   *   method: 'POST',\n   *   body: logs,\n   *   headers: { 'Content-Type': 'application/json' }\n   * });\n   * ```\n   */\n  exportLogEntries(): string {\n    return JSON.stringify(this.logEntries, null, 2);\n  },\n\n  /**\n   * Formats a number of bytes into a human-readable string with appropriate unit.\n   * @param bytes - The number of bytes to format\n   * @returns A formatted string with appropriate unit (B, KB, MB, GB, TB)\n   * @example\n   * ```typescript\n   * const size = LoggingUtils.formatBytes(1024 * 1024);\n   * console.log(size); // \"1.00 MB\"\n   *\n   * const smallSize = LoggingUtils.formatBytes(500);\n   * console.log(smallSize); // \"500.00 B\"\n   *\n   * const largeSize = LoggingUtils.formatBytes(1024 * 1024 * 1024 * 2);\n   * console.log(largeSize); // \"2.00 GB\"\n   * ```\n   */\n  formatBytes(bytes: number): string {\n    const units = [\"B\", \"KB\", \"MB\", \"GB\", \"TB\"];\n    let size = bytes;\n    let unitIndex = 0;\n\n    while (size >= 1024 && unitIndex < units.length - 1) {\n      size /= 1024;\n      unitIndex++;\n    }\n\n    return `${size.toFixed(2)} ${units[unitIndex]}`;\n  },\n\n  /**\n   * Gets a copy of all stored log entries.\n   * @returns An array of log entries\n   * @example\n   * ```typescript\n   * // Get all logs\n   * const allLogs = LoggingUtils.getLogEntries();\n   * console.log(`Total logs: ${allLogs.length}`);\n   *\n   * // Filter logs in memory\n   * const errorLogs = LoggingUtils.getLogEntries()\n   *   .filter(log => log.level === 'error');\n   * ```\n   */\n  getLogEntries(): LogEntry[] {\n    return [...this.logEntries];\n  },\n\n  /**\n   * Gets log entries filtered by a specific log level.\n   * @param level - The log level to filter by\n   * @returns An array of filtered log entries\n   * @example\n   * ```typescript\n   * // Get all error logs\n   * const errorLogs = LoggingUtils.getLogEntriesByLevel(\"error\");\n   * console.log(`Error count: ${errorLogs.length}`);\n   *\n   * // Get all debug logs\n   * const debugLogs = LoggingUtils.getLogEntriesByLevel(\"debug\");\n   * console.log(`Debug count: ${debugLogs.length}`);\n   * ```\n   */\n  getLogEntriesByLevel(level: LogLevel): LogEntry[] {\n    return this.logEntries.filter((entry) => entry.level === level);\n  },\n\n  /**\n   * Gets log entries within a specific time range.\n   * @param startTime - The start time of the range\n   * @param endTime - The end time of the range\n   * @returns An array of filtered log entries\n   * @example\n   * ```typescript\n   * // Get logs from today\n   * const today = new Date();\n   * const yesterday = new Date(today);\n   * yesterday.setDate(yesterday.getDate() - 1);\n   *\n   * const todayLogs = LoggingUtils.getLogEntriesByTimeRange(yesterday, today);\n   * console.log(`Logs in last 24 hours: ${todayLogs.length}`);\n   *\n   * // Get logs from specific time period\n   * const startDate = new Date(\"2024-01-01\");\n   * const endDate = new Date(\"2024-01-02\");\n   * const periodLogs = LoggingUtils.getLogEntriesByTimeRange(startDate, endDate);\n   * ```\n   */\n  getLogEntriesByTimeRange(startTime: Date, endTime: Date): LogEntry[] {\n    return this.logEntries.filter(\n      (entry) =>\n        new Date(entry.timestamp) >= startTime &&\n        new Date(entry.timestamp) <= endTime\n    );\n  },\n\n  /**\n   * Logs an informational message with optional metadata.\n   * @param message - The info message to log\n   * @param options - Optional configuration for the log entry\n   * @example\n   * ```typescript\n   * // Simple info message\n   * LoggingUtils.info(\"Application started\");\n   *\n   * // Info with data and prefix\n   * LoggingUtils.info(\"User logged in\", {\n   *   prefix: \"Auth\",\n   *   data: { userId: \"123\", role: \"admin\" }\n   * });\n   *\n   * // Info with grouping\n   * LoggingUtils.info(\"Configuration loaded\", {\n   *   group: true,\n   *   data: { settings: { theme: \"dark\", language: \"en\" } }\n   * });\n   * ```\n   */\n  info(message: string, options: Omit<LogOptions, \"level\"> = {}): void {\n    this.log(message, { ...options, level: \"info\" });\n  },\n\n  /**\n   * Imports log entries from a JSON string.\n   * @param json - The JSON string containing log entries\n   * @throws {Error} If the JSON string is invalid or cannot be parsed\n   * @example\n   * ```typescript\n   * // Import logs from file\n   * const json = await fetch('/logs.json').then(r => r.text());\n   * LoggingUtils.importLogEntries(json);\n   *\n   * // Import logs from server\n   * const response = await fetch('/api/logs');\n   * const json = await response.text();\n   * LoggingUtils.importLogEntries(json);\n   * ```\n   */\n  importLogEntries(json: string): void {\n    try {\n      const entries = JSON.parse(json) as LogEntry[];\n      this.logEntries = entries.slice(-this.maxLogEntries);\n    } catch (error) {\n      this.error(\"Failed to import log entries\", { data: error });\n    }\n  },\n\n  /**\n   * Logs a message with the specified options.\n   * @param message - The message to log\n   * @param options - Configuration options for the log entry\n   * @example\n   * ```typescript\n   * // Custom log with all options\n   * LoggingUtils.log(\"Custom message\", {\n   *   level: \"info\",\n   *   prefix: \"Custom\",\n   *   group: true,\n   *   groupCollapsed: true,\n   *   stackTrace: true,\n   *   data: { custom: \"data\" }\n   * });\n   *\n   * // Simple log with default options\n   * LoggingUtils.log(\"Simple message\");\n   * ```\n   */\n  log(message: string, options: LogOptions = {}): void {\n    const opts = { ...this.defaultOptions, ...options };\n    const timestamp = new Date().toISOString();\n    const prefix = opts.prefix ? `[${opts.prefix}] ` : \"\";\n    const fullMessage = `${prefix}${message}`;\n\n    // Create log entry\n    const entry: LogEntry = {\n      timestamp,\n      level: opts.level || \"info\",\n      message: fullMessage,\n      data: opts.data,\n    };\n\n    // Add stack trace if requested\n    if (opts.stackTrace) {\n      entry.stack = new Error().stack;\n    }\n\n    // Store log entry\n    this.logEntries.push(entry);\n    if (this.logEntries.length > this.maxLogEntries) {\n      this.logEntries.shift();\n    }\n\n    // Group logs if requested\n    if (opts.group) {\n      if (opts.groupCollapsed) {\n        console.groupCollapsed(fullMessage);\n      } else {\n        console.group(fullMessage);\n      }\n    }\n\n    // Log with appropriate console method\n    switch (opts.level) {\n      case \"debug\":\n        console.debug(fullMessage, opts.data || \"\");\n        break;\n      case \"info\":\n        console.info(fullMessage, opts.data || \"\");\n        break;\n      case \"warn\":\n        console.warn(fullMessage, opts.data || \"\");\n        break;\n      case \"error\":\n        console.error(fullMessage, opts.data || \"\");\n        if (entry.stack) {\n          console.error(entry.stack);\n        }\n        break;\n    }\n\n    // End group if started\n    if (opts.group) {\n      console.groupEnd();\n    }\n  },\n\n  /**\n   * Logs memory usage information if available in the browser.\n   * @param label - The label for the memory measurement\n   * @example\n   * ```typescript\n   * // Log memory usage\n   * LoggingUtils.measureMemory(\"After data load\");\n   * // Output: Memory: After data load { used: \"50.2 MB\", total: \"100.0 MB\", limit: \"500.0 MB\" }\n   *\n   * // Track memory usage over time\n   * setInterval(() => {\n   *   LoggingUtils.measureMemory(\"Periodic check\");\n   * }, 60000);\n   * ```\n   */\n  measureMemory(label: string): void {\n    if (performance.memory) {\n      const { usedJSHeapSize, totalJSHeapSize, jsHeapSizeLimit } =\n        performance.memory;\n      this.debug(`Memory: ${label}`, {\n        data: {\n          used: this.formatBytes(usedJSHeapSize),\n          total: this.formatBytes(totalJSHeapSize),\n          limit: this.formatBytes(jsHeapSizeLimit),\n        },\n      });\n    }\n  },\n\n  /**\n   * Creates a performance measurement for synchronous operations.\n   * @param label - The label for the performance measurement\n   * @returns A function to end the measurement and log the duration\n   * @example\n   * ```typescript\n   * // Measure a synchronous operation\n   * const endMeasurement = LoggingUtils.measurePerformance(\"Data processing\");\n   * // ... do some work ...\n   * endMeasurement();\n   * // Output: Performance: Data processing { duration: \"123.45ms\" }\n   *\n   * // Measure multiple operations\n   * const endTotal = LoggingUtils.measurePerformance(\"Total processing\");\n   *\n   * const endStep1 = LoggingUtils.measurePerformance(\"Step 1\");\n   * // ... do step 1 ...\n   * endStep1();\n   *\n   * const endStep2 = LoggingUtils.measurePerformance(\"Step 2\");\n   * // ... do step 2 ...\n   * endStep2();\n   *\n   * endTotal();\n   * ```\n   */\n  measurePerformance(label: string): () => void {\n    const startTime = performance.now();\n    return () => {\n      const endTime = performance.now();\n      const duration = endTime - startTime;\n      this.debug(`Performance: ${label}`, {\n        data: { duration: `${duration.toFixed(2)}ms` },\n      });\n    };\n  },\n\n  /**\n   * Measures the performance of an asynchronous function.\n   * @param label - The label for the performance measurement\n   * @param fn - The async function to measure\n   * @returns A Promise with the function result\n   * @example\n   * ```typescript\n   * // Measure an API call\n   * const result = await LoggingUtils.measureAsyncPerformance(\n   *   \"API call\",\n   *   async () => await fetchData()\n   * );\n   *\n   * // Measure multiple async operations\n   * const results = await Promise.all([\n   *   LoggingUtils.measureAsyncPerformance(\"API 1\", () => fetchData1()),\n   *   LoggingUtils.measureAsyncPerformance(\"API 2\", () => fetchData2())\n   * ]);\n   * ```\n   */\n  async measureAsyncPerformance<T>(\n    label: string,\n    fn: () => Promise<T>\n  ): Promise<T> {\n    const startTime = performance.now();\n    try {\n      const result = await fn();\n      const endTime = performance.now();\n      const duration = endTime - startTime;\n      this.debug(`Performance: ${label}`, {\n        data: { duration: `${duration.toFixed(2)}ms` },\n      });\n      return result;\n    } catch (error) {\n      const endTime = performance.now();\n      const duration = endTime - startTime;\n      this.error(`Performance: ${label}`, {\n        data: { duration: `${duration.toFixed(2)}ms`, error },\n      });\n      throw error;\n    }\n  },\n\n  /**\n   * Logs a warning message with optional metadata.\n   * @param message - The warning message to log\n   * @param options - Optional configuration for the log entry\n   * @example\n   * ```typescript\n   * // Simple warning\n   * LoggingUtils.warn(\"Resource usage high\");\n   *\n   * // Warning with data and prefix\n   * LoggingUtils.warn(\"High memory usage\", {\n   *   prefix: \"System\",\n   *   data: { cpu: \"80%\", memory: \"75%\" }\n   * });\n   *\n   * // Warning with grouping\n   * LoggingUtils.warn(\"Multiple issues detected\", {\n   *   group: true,\n   *   data: { issues: [\"CPU\", \"Memory\", \"Disk\"] }\n   * });\n   * ```\n   */\n  warn(message: string, options: Omit<LogOptions, \"level\"> = {}): void {\n    this.log(message, { ...options, level: \"warn\" });\n  },\n};\n"],"names":[],"mappings":"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"}