73 lines
1.6 KiB
TypeScript
73 lines
1.6 KiB
TypeScript
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<IncomingMessage>()
|
|
|
|
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 }))
|
|
}
|