remoteconsole.js 2.47 KB

class RemoteConsole {
    #stack= [];
    #server;
    #idxSource;
    _log = globalThis.console.log;
    _info = globalThis.console.info;
    _warn = globalThis.console.warn;
    _error = globalThis.console.error;

    constructor(address) {
        let self = this;

        console.error = this.error;
        console.warn  = this.warn;
        console.info  = this.info; 
        console.log  = this.log;
        console.tainted = true;

        if (globalThis.window) {
            globalThis.window.onerror = this.runtimeException;
        }
        
        if (globalThis.WebSocket && globalThis.navigator) {
            this.#server = new globalThis.WebSocket(address);
            this.#idxSource = (globalThis.navigator.userAgent.match(/firefox|fxios/i))?2:3;
            this.#server.onopen = function() {
                self.#flush();
            }
        }
    }
    
    #currentPlace() {
        let err = new Error();
        let lst = err.stack.split("\n");
        return lst[this.#idxSource];
    }
            
    #send(data) {
        if (!this.#server)  return ;

        if (this.#server.readyState === WebSocket.OPEN ) {
            this.#server.send(data);
        } else {
            this.#stack.push(data);
        }
    }

    #flush () {
        if (!this.#server)  return ;

        if (this.#server.readyState !== WebSocket.OPEN) 
            return ;
        this.#stack.forEach(elt => this.#server.send(elt));
        this.#stack = [];
    }

    #notify(type) {
        let self = this;
        return function() {
            let obj = { type, args: Array.from(arguments), context: self.#currentPlace() };
            self[`_${type}`].apply(globalThis.console, obj.args);

            let serializedObject = "";

            try {
                serializedObject = JSON.stringify(obj);
            } catch(e) {
                obj.args= [ 'Argument(s) not serializable' ];
                serializedObject = JSON.stringify(obj);
            }
            self.#send(serializedObject);
        };
    }
            
    #runtimeException (msg, url, line, column,err) {
        if (!this.#server)  return false;

        this.#server.send(
            JSON.stringify(
                {type: "exception", args: [{ message: msg, url: url, line: line, column: column }] }
            )
        );
        return false;
    }

    log = this.#notify('log');
    info = this.#notify('info');
    warn = this.#notify('warn');
    error = this.#notify('error');

};


export default RemoteConsole;