const { toast } = require('bulma-toast'); const cbor = require('borc'); const actions = require('./actions'); function errorToast(err) { console.error(err); return toast({ message: err, type: 'is-warning', duration: 5000, }); } // Create WebSocket connection. // requires the redux store in order to push updates // to components function createSocket(store) { const ws = new WebSocket('ws://localhost:40000'); ws.binaryType = 'arraybuffer'; // handle account auth within the socket itself // https://www.christian-schneider.net/CrossSiteWebSocketHijacking.html let account = null; function send(msg) { msg.token = account && account.token; ws.send(cbor.encode(msg)); } function accountLogin(res) { const [struct, login] = res; account = login; store.dispatch(actions.setAccount(login)); console.log(account); return send({ method: 'cryp_spawn', params: { name: 'drake' }}); } function crypSpawn(cryp) { console.log('got a new cryp', cryp); } const handlers = { cryp_spawn: crypSpawn, account_login: accountLogin, account_create: accountLogin, }; function onMessage(event) { // decode binary msg from server const blob = new Uint8Array(event.data); const res = cbor.decode(blob); console.log(res); // check for error and split into response type and data if (res.err) return errorToast(res.err); const { method, params } = res; return handlers[method](params); } // Connection opened ws.addEventListener('open', function wsOpen(event) { // send({ method: 'account_create', params: { name: 'ntr', password: 'grepgrepgrep' }}); send({ method: 'account_login', params: { name: 'ntr', password: 'grepgrepgrep' } }); }); // Listen for messages ws.addEventListener('message', onMessage); ws.addEventListener('error', function wsError(event) { console.error('WebSocket error', event); account = null; }); ws.addEventListener('close', function wsClose(event) { console.error('WebSocket closed', event); account = null; }); } module.exports = createSocket;