1import WebSocket from 'ws'; 2 3import RelapseError from './RelapseError'; 4import { RelapseCode } from './protocol'; 5 6const defaultOptions = { 7 port: 8085, 8}; 9 10let state; 11 12export async function startAsync(startOptions = {}) { 13 if (state) { 14 throw new RelapseError(`server`, 'Server is already started'); 15 } 16 const options = { ...defaultOptions, ...startOptions }; 17 18 const wss = new WebSocket.Server({ port: options.port }); 19 20 state = { 21 ws: null, 22 server: wss, 23 }; 24 25 wss.on('connection', ws => { 26 ws.on('message', message => { 27 const body = JSON.parse(message); 28 if (body.code === RelapseCode.SerializationError) { 29 console.error(`Client failed to serialize the arguments for a call to ${body.call}`); 30 } else if (body.code === RelapseCode.ProxyCall) { 31 if (!Array.isArray(body.arguments)) { 32 console.error( 33 `Proxied invocation of ${body.call} from the client did not send an array of arguments:`, 34 body.arguments 35 ); 36 } else { 37 options.onEvent && options.onEvent(body.call, body.arguments); 38 } 39 } 40 }); 41 state.ws = ws; 42 startOptions.onConnect && startOptions.onConnect(ws); 43 }); 44 45 return async () => { 46 if (state.ws) state.ws.close(); 47 return new Promise((resolve, reject) => 48 wss.close(error => { 49 if (error) reject(error); 50 else resolve(); 51 }) 52 ); 53 }; 54} 55 56export function send(message) { 57 if (!state || !state.ws) { 58 throw new RelapseError(`server`, 'Server cannot send data'); 59 } 60 state.ws.send(JSON.stringify(message)); 61} 62