const Message = require('../shared/Message') const WebSocket = require('ws') const Errors = require('../shared/Errors') const config = require('./config') class Connector { initialize() { this.client = new WebSocket(`ws://${config.config.data_server}`) this.messages = [] this.token; this.client.on('message', msg => this.on_message(msg)) } async on_message(msg) { const message = new Message(msg) const response = new Message() message.socket = this if ( message.is_response() ) { // Try to find the message that sent the request const request = this.messages.find(x => x.uuid() === message.response_to()) if ( request ) { await request._response_callback(message) request.has_response = true; } else { this.send( response.response_to(request.uuid()) .error(Errors.InvalidReplyUUID) ) } this.messages = this.messages.filter(x => !x.has_response) } else { let handler; try { handler = require(`./routes/${message.route()}`) } catch (e) {} if ( !handler ) { return this.send(response.error(Errors.InvalidMessageRoute)) } await handler(message, this) } } async open() { await new Promise(res => this.client.once('open', res)) } close() { this.client.close() } send(message) { if ( typeof message === 'string' ) { this.client.send(message); return; } if ( message.needs_response ) { this.messages.push(message); } const serial = message.serialize() this.client.send(serial); } async simple_request(route, data) { return new Promise((res, rej) => { this.send( Message.route(route) .data(data) .expect_response(message => { if ( message.error() ) rej(new Error(message.error())) else res(message.data()) }) ) }) } async authenticate(token_value) { return new Promise((res, rej) => { this.send( Message.route('meta.authenticate') .data({ token_value }) .expect_response(message => { const { is_auth } = message.data() if ( is_auth ) res() else rej(new Error('Unable to authenticate.')) }) ) }) } } module.exports = exports = new Connector;