Thin WebSocket FFI for MoonBit — Node.js server + browser client with typed JSON messaging
let send = @thin_ws.run_json_server(
5022, // port — nothing hardcoded
"/ws", // path
fn(sid) { log("connect \{sid}") },
fn(sid, op : MyClientOp) { handle(sid, op) },
fn(sid) { log("disconnect \{sid}") },
)
// send a typed message to a client
send(sid, my_server_event)let url = @thin_ws.make_ws_url("5173,5174", 5022, "/ws")
let (socket, send) = @thin_ws.connect_json(
url,
fn() { log("opened") },
fn(payload : MyServerEvent) { apply_delta(payload) },
fn() { log("closed") },
)
// send a typed op to the server (no-op until the connection opens)
send(my_client_op)import {
"tiye/thin_ws" @thin_ws,
}#external
pub type BrowserWebSocket#external
pub type NodeWsRuntimefn[In : FromJson, Out : ToJson] connect_json(url : String, on_open : () -> Unit, on_message : (In) -> Unit, on_close : () -> Unit) -> (BrowserWebSocket, (Out) -> Unit)let url = make_ws_url("5173,5174", 5022, "/ws")
let (socket, send) = connect_json(
url,
fn() { store.update(Connected) },
fn(msg : ServerEvent) { store.update(Received(msg)) },
fn() { store.update(Disconnected) },
)
// later: send(ClientOp::Login(...))fn make_ws_url(dev_ports : String, backend_port : Int, ws_path : String) -> Stringlet send = run_json_server(
5022,
"/ws",
fn(sid) { log("connect \{sid}") },
fn(sid, op : MyClientOp) { handle(sid, op) },
fn(sid) { log("disconnect \{sid}") },
)
// later: send(sid, my_server_event)fn server_log(text : String) -> UnitInstall
Download zipThin WebSocket FFI for MoonBit — Node.js server + browser client with typed JSON messaging