JSON-RPC 2.0 for MoonBit.
A method table for one request and one answer. A peer for streams where either side may call the other. Framing for lines and Content-Length. The protocol you build on top stays yours.
moon add moonbitstack/moonjrpcWhat you get
One body in, one body out
Register methods, hand Methods::body the text of a request, send back what it returns. Parse errors, unknown methods, bad parameters and batches are handled.
Both sides can call
Peer matches each reply to its call, whichever side asked and in whatever order the answers come. A handler can call back in the middle of its own call.
An order you can rely on
Updates sent before an answer are handled before the caller sees that answer, and a change sent before a call is in place when the call starts.
Any transport
A transport is two functions, read and write. Lines and Content-Length come with the library; a WebSocket or an HTTP stream takes a few lines of your own.
Two shapes
One request, one answer
let methods = @moonjrpc.Methods::new()
methods.typed("sum", (numbers : Array[Int32]) => {
numbers.fold(init=0, (a, b) => a + b)
})
let answer = methods.body(request)
A stream that stays open
let editor = @peer.Peer::new(
@peer.lines(editor_reads, editor_writes),
methods=editor_methods,
)
group.spawn_bg(no_wait=true, () => editor.run())
let answer = editor.call("prompt")
Agent protocols, language servers and anything else built on JSON-RPC can sit on these two pieces. The guide walks through both.