MeteorClient class that connects to a Meteor server

Continuing the discussion from [SOLVED] Calling a Meteor.method manually over websocket?:

I created a small MeteorClient class that can be used to connect to a Meteor server and interact with it (the purpose is essentially the same as what Asteroid is for).

Example:

import MeteorClient from './path/to/MeteorClient'

async function main() {
    const client = new MeteorClient
    const sessionId = await client.connect('some-meteor-app.com')

    console.log('session ID:', sessionId)

    // Call one of the server's methods
    // (the ones defined with `Meteor.methods`)
    const result = await client.call('foo', 1, 2, 3)

    console.log(' --- result:', result)
}

main()

MeteorClient:

import WebSocket from 'ws'

export default
class MeteorClient {

    constructor() {
        this.ws = undefined
        this.methodId = 1
    }

    connect(host) {
        var resolve, reject
        const promise = new Promise((res, rej) => {resolve = res; reject = rej})

        this.ws = new WebSocket(`ws://${host}/websocket`)

        this.ws.addEventListener('open', () => {
            this.ws.send(JSON.stringify({
                msg: 'connect',
                version: '1',
                support: [ '1', 'pre2', 'pre1' ]
            }))
        })

        const onconnect = msg => {
            msg = JSON.parse(msg.data)

            if (msg.msg && msg.msg == 'failed') reject(new Error('connection failed.'))
            if (msg.msg && msg.msg == 'error') reject(new Error(msg.reason))

            if (msg.msg && msg.msg == 'connected') {
                this.ws.removeEventListener('message', onconnect)
                resolve(msg.session)
            }
        }

        const onping = msg => {
            msg = JSON.parse(msg.data)

            if (msg.msg && msg.msg == 'ping') {
                this.ws.send(JSON.stringify({
                    msg: 'pong'
                }))

                setTimeout(function() {
                    this.ws.send(JSON.stringify({
                        msg: 'ping'
                    }))
                }, 25000)
            }
        }

        this.ws.addEventListener('message', onconnect)
        this.ws.addEventListener('message', onping)

        return promise
    }

    call(methodName, ...args) {
        var resolve, reject
        const promise = new Promise((res, rej) => {resolve = res; reject = rej})

        const currentMethodId = (this.methodId++).toString()

        const onmethod = msg => {
            msg = JSON.parse(msg.data)

            if (msg.msg && msg.msg == 'failed') reject(new Error('Method call failed.'))
            if (msg.msg && msg.msg == 'error') reject(new Error(msg.reason))

            if (msg.msg && msg.msg == 'result' && msg.id == currentMethodId) {
                this.ws.removeEventListener('message', onmethod)
                resolve(msg.result)
            }
        }

        this.ws.addEventListener('message', onmethod)

        this.ws.send(JSON.stringify({
            msg: 'method',
            method: methodName,
            params: [...args],
            id: currentMethodId,
        }))

        return promise
    }
}