(:~ : jsonrpc : @author andy bunce :) module namespace rpc = 'rpc'; import module namespace lsp-text = 'lsp-text' at "lsp-text.xqm"; (: map methods to functions :) declare variable $rpc:methods:=map:merge(( map{ "initialize" : rpc:method-initialize#1, "initialized" : rpc:method-initialized#1, "workspace/didChangeConfiguration" :rpc:method-unknown#1 }, $lsp-text:methods )); (:~ return map if $msg is jsonrpc else empty :) declare function rpc:parse($msg as xs:string) as map(*)? { try { let $json:=parse-json($msg) return if($json?jsonrpc="2.0" and exists($json?method)) then $json else () } catch *{ () } }; (:~ send replay to $json :) declare function rpc:reply($json as map(*)) as empty-sequence() { let $method := $json?method let $f :=$rpc:methods?($method) let $response := $f!.($json) return if(exists($response)) then ws:send($response=>trace("REPLY: "),ws:id()) }; (:~ canned initialize response :) declare function rpc:method-initialize($json as map(*)) as map(*) { { "jsonrpc": "2.0", "id": $json?id, "result": json:doc("etc/capabilities.json",{"format":"w3"}) } }; (:~ initialized response :) declare function rpc:method-initialized($json as map(*)) as empty-sequence() { ws:set(ws:id(),"initialized", true()) }; (:~ unknown method response :) declare function rpc:method-unknown($json as map(*)) as map(*)? { let $_:=trace($json?method,"unknown") return () }; (:~ rpc log message :) declare function rpc:log($msg as xs:string) as map(*) { {"jsonrpc": "2.0", "method":"window/logMessage", "params":{"type":1, "message": $msg} } };