@@ -15,15 +15,37 @@ const MAX_LOGS = 20;
1515const CONSOLE_METHODS : string [ ] = [ 'log' , 'warn' , 'error' , 'info' , 'debug' ] ;
1616
1717/**
18- * Creates a console interceptor that captures and formats console output
18+ * Console catcher class for intercepting and capturing console logs
1919 */
20- function createConsoleCatcher ( ) : {
21- initConsoleCatcher : ( ) => void ;
22- addErrorEvent : ( event : ErrorEvent | PromiseRejectionEvent ) => void ;
23- getConsoleLogStack : ( ) => ConsoleLogEvent [ ] ;
24- } {
25- const consoleOutput : ConsoleLogEvent [ ] = [ ] ;
26- let isInitialized = false ;
20+ export class ConsoleCatcher {
21+ /**
22+ * Singleton instance
23+ */
24+ private static instance : ConsoleCatcher | null = null ;
25+
26+ /**
27+ * Console output buffer
28+ */
29+ private readonly consoleOutput : ConsoleLogEvent [ ] = [ ] ;
30+
31+ /**
32+ * Initialization flag
33+ */
34+ private isInitialized = false ;
35+
36+ /**
37+ * Private constructor to enforce singleton pattern
38+ */
39+ private constructor ( ) { }
40+
41+ /**
42+ * Get singleton instance
43+ */
44+ public static getInstance ( ) : ConsoleCatcher {
45+ ConsoleCatcher . instance ??= new ConsoleCatcher ( ) ;
46+
47+ return ConsoleCatcher . instance ;
48+ }
2749
2850 /**
2951 * Converts any argument to its string representation
@@ -32,7 +54,7 @@ function createConsoleCatcher(): {
3254 * @throws Error if the argument can not be stringified, for example by such reason:
3355 * SecurityError: Failed to read a named property 'toJSON' from 'Window': Blocked a frame with origin "https://codex.so" from accessing a cross-origin frame.
3456 */
35- function stringifyArg ( arg : unknown ) : string {
57+ private stringifyArg ( arg : unknown ) : string {
3658 if ( typeof arg === 'string' ) {
3759 return arg ;
3860 }
@@ -54,7 +76,7 @@ function createConsoleCatcher(): {
5476 *
5577 * @param args - Console arguments that may include style directives
5678 */
57- function formatConsoleArgs ( args : unknown [ ] ) : {
79+ private formatConsoleArgs ( args : unknown [ ] ) : {
5880 message : string ;
5981 styles : string [ ] ;
6082 } {
@@ -71,7 +93,7 @@ function createConsoleCatcher(): {
7193 return {
7294 message : args . map ( arg => {
7395 try {
74- return stringifyArg ( arg ) ;
96+ return this . stringifyArg ( arg ) ;
7597 } catch ( error ) {
7698 return '[Error stringifying argument: ' + ( error instanceof Error ? error . message : String ( error ) ) + ']' ;
7799 }
@@ -101,7 +123,7 @@ function createConsoleCatcher(): {
101123 . slice ( styles . length + 1 )
102124 . map ( arg => {
103125 try {
104- return stringifyArg ( arg ) ;
126+ return this . stringifyArg ( arg ) ;
105127 } catch ( error ) {
106128 return '[Error stringifying argument: ' + ( error instanceof Error ? error . message : String ( error ) ) + ']' ;
107129 }
@@ -119,21 +141,19 @@ function createConsoleCatcher(): {
119141 *
120142 * @param logEvent - The console log event to be added to the output buffer
121143 */
122- function addToConsoleOutput ( logEvent : ConsoleLogEvent ) : void {
123- if ( consoleOutput . length >= MAX_LOGS ) {
124- consoleOutput . shift ( ) ;
144+ private addToConsoleOutput ( logEvent : ConsoleLogEvent ) : void {
145+ if ( this . consoleOutput . length >= MAX_LOGS ) {
146+ this . consoleOutput . shift ( ) ;
125147 }
126- consoleOutput . push ( logEvent ) ;
148+ this . consoleOutput . push ( logEvent ) ;
127149 }
128150
129151 /**
130152 * Creates a console log event from an error or promise rejection
131153 *
132154 * @param event - The error event or promise rejection event to convert
133155 */
134- function createConsoleEventFromError (
135- event : ErrorEvent | PromiseRejectionEvent
136- ) : ConsoleLogEvent {
156+ private createConsoleEventFromError ( event : ErrorEvent | PromiseRejectionEvent ) : ConsoleLogEvent {
137157 if ( event instanceof ErrorEvent ) {
138158 return {
139159 method : 'error' ,
@@ -160,24 +180,23 @@ function createConsoleCatcher(): {
160180 /**
161181 * Initializes the console interceptor by overriding default console methods
162182 */
163- function initConsoleCatcher ( ) : void {
164- if ( isInitialized ) {
183+ public init ( ) : void {
184+ if ( this . isInitialized ) {
165185 return ;
166186 }
167187
168- isInitialized = true ;
188+ this . isInitialized = true ;
169189
170- CONSOLE_METHODS . forEach ( function overrideConsoleMethod ( method ) {
171- if ( typeof window . console [ method ] !== 'function' ) {
190+ CONSOLE_METHODS . forEach ( ( method ) => {
191+ if ( typeof globalThis . console [ method ] !== 'function' ) {
172192 return ;
173193 }
174194
175195 const oldFunction = window . console [ method ] . bind ( window . console ) ;
176196
177- window . console [ method ] = function ( ...args : unknown [ ] ) : void {
178- const stack = new Error ( ) . stack ?. split ( '\n' ) . slice ( 2 )
179- . join ( '\n' ) || '' ;
180- const { message, styles } = formatConsoleArgs ( args ) ;
197+ window . console [ method ] = ( ...args : unknown [ ] ) : void => {
198+ const stack = new Error ( ) . stack ?. split ( '\n' ) . slice ( 2 ) . join ( '\n' ) || '' ;
199+ const { message, styles } = this . formatConsoleArgs ( args ) ;
181200
182201 const logEvent : ConsoleLogEvent = {
183202 method,
@@ -189,7 +208,7 @@ function createConsoleCatcher(): {
189208 styles,
190209 } ;
191210
192- addToConsoleOutput ( logEvent ) ;
211+ this . addToConsoleOutput ( logEvent ) ;
193212 oldFunction ( ...args ) ;
194213 } ;
195214 } ) ;
@@ -200,28 +219,16 @@ function createConsoleCatcher(): {
200219 *
201220 * @param event - The error or promise rejection event to handle
202221 */
203- function addErrorEvent ( event : ErrorEvent | PromiseRejectionEvent ) : void {
204- const logEvent = createConsoleEventFromError ( event ) ;
222+ public addErrorEvent ( event : ErrorEvent | PromiseRejectionEvent ) : void {
223+ const logEvent = this . createConsoleEventFromError ( event ) ;
205224
206- addToConsoleOutput ( logEvent ) ;
225+ this . addToConsoleOutput ( logEvent ) ;
207226 }
208227
209228 /**
210229 * Returns the current console output buffer
211230 */
212- function getConsoleLogStack ( ) : ConsoleLogEvent [ ] {
213- return [ ...consoleOutput ] ;
231+ public getConsoleLogStack ( ) : ConsoleLogEvent [ ] {
232+ return [ ...this . consoleOutput ] ;
214233 }
215-
216- return {
217- initConsoleCatcher,
218- addErrorEvent,
219- getConsoleLogStack,
220- } ;
221234}
222-
223- const consoleCatcher = createConsoleCatcher ( ) ;
224-
225- export const { initConsoleCatcher, getConsoleLogStack, addErrorEvent } =
226- consoleCatcher ;
227-
0 commit comments