remote_console.js 2.21 KB

class ARCSRemoteConsole {
    #stack= [];
    #server;
    #idxSource;

    constructor(address) {
        this.#server = new globalThis.WebSocket(address);
        this.#idxSource = (globalThis.navigator.userAgent.match(/firefox|fxios/i))?2:3;
        let self = this;

        this.#server.onopen = function() {
            self.flush();
        }
    }
    
    #currentPlace() {
        let err = new Error();
        let lst = err.stack.split("\n");
        return lst[this.#idxSource];
    }
            
    #send(data) {
        if (server.readyState === WebSocket.OPEN ) {
            server.send(data);
        } else {
            this.#stack.push(data);
        }
    }

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

    #notify(type) {
        let self = this;
        return function() {
            let obj = { type, args: Array.from(arguments), context: self.#currentPlace() };

            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) {
        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');

    static init(address) {
        let _address = address || 'ws://localhost:8088';
        const remoteConsole = new ARCSRemoteConsole(address);

        const console = globalThis.console;
        console.error = remoteConsole.error;
        console.warn  = remoteConsole.warn;
        console.info  = remoteConsole.info; 
        console.log  = remoteConsole.log;
        console.tainted = true;
        const window = globalThis.window;
        window.onerror = remoteConsole.runtimeException;
    }

}