| import { EventEmitter } from "events"; |
| import { CONSOLE_LOG_CONFIG } from "@/shared/constants/config.js"; |
|
|
| const consoleLevels = ["log", "info", "warn", "error", "debug"]; |
|
|
| if (!global._consoleLogBufferState) { |
| global._consoleLogBufferState = { |
| logs: [], |
| patched: false, |
| originals: {}, |
| emitter: new EventEmitter(), |
| }; |
| global._consoleLogBufferState.emitter.setMaxListeners(50); |
| } |
|
|
| const state = global._consoleLogBufferState; |
|
|
| |
| if (!state.emitter) { |
| state.emitter = new EventEmitter(); |
| state.emitter.setMaxListeners(50); |
| } |
|
|
| function toLogLine(level, args) { |
| return args.map(formatArg).join(" "); |
| } |
|
|
| |
| const ANSI_RE = /\x1b\[[0-9;]*m/g; |
|
|
| function stripAnsi(str) { |
| return str.replace(ANSI_RE, ""); |
| } |
|
|
| function formatArg(arg) { |
| if (typeof arg === "string") return stripAnsi(arg); |
| if (arg instanceof Error) return stripAnsi(arg.stack || arg.message || String(arg)); |
| try { |
| return stripAnsi(JSON.stringify(arg)); |
| } catch { |
| return stripAnsi(String(arg)); |
| } |
| } |
|
|
| function appendLine(line) { |
| state.logs.push(line); |
| const maxLines = CONSOLE_LOG_CONFIG.maxLines; |
| if (state.logs.length > maxLines) { |
| state.logs = state.logs.slice(-maxLines); |
| } |
| state.emitter.emit("line", line); |
| } |
|
|
| export function initConsoleLogCapture() { |
| if (state.patched) return; |
|
|
| for (const level of consoleLevels) { |
| state.originals[level] = console[level]; |
| console[level] = (...args) => { |
| appendLine(toLogLine(level, args)); |
| state.originals[level](...args); |
| }; |
| } |
|
|
| state.patched = true; |
| } |
|
|
| export function getConsoleLogs() { |
| return state.logs; |
| } |
|
|
| export function clearConsoleLogs() { |
| state.logs = []; |
| state.emitter.emit("clear"); |
| } |
|
|
| export function getConsoleEmitter() { |
| return state.emitter; |
| } |
|
|