import { Signal } from '#utils/signal' import type { Bytecode, Value } from 'reefvm' let ws: WebSocket type IncomingMessage = | { type: 'connected' } | { type: 'ping'; data: number } | { type: 'commands'; data: number } | { type: 'apps' data: { name: string type: 'browser' | 'server' }[] } | { type: 'session:start' data: { NOSE_DIR: string cwd: string hostname: string mode: string project: string } } | { type: 'reef-output'; data: Value } | { type: 'error'; data: string } | { type: 'command-defs' data: CommandDef[] } export type CommandDef = { name: string signature: { params: { default: any; name: string; optional: boolean; rest: boolean; type: string }[] returnType: string type: string } } export const noseSignals = new Signal() export const connectToNose = (url: string = 'ws://localhost:3000/ws') => { ws = new WebSocket(url) ws.onopen = () => noseSignals.emit({ type: 'connected' }) ws.onmessage = (event) => { const message = JSON.parse(event.data) noseSignals.emit(message) } ws.onerror = (event) => { console.error(`💥WebSocket error:`, event) } ws.onclose = () => { console.log(`🚪 Connection closed`) } } let id = 0 export const sendToNose = (code: Bytecode) => { if (!ws) { throw new Error('WebSocket is not connected.') } else if (ws.readyState !== WebSocket.OPEN) { throw new Error(`WebSocket is not open, current status is ${ws.readyState}.`) } id += 1 ws.send(JSON.stringify({ type: 'reef-bytecode', data: code, id })) }