(: Store for XQuery document data , type, text,uri on save parse is created and stored data is stored in webSocket attributes @author Andy Bunce :) module namespace docs="lsp/docs"; import module namespace p="xq4" at "xq4.xqm"; import module namespace pos="lsp/position" at "position.xqm"; (: save $textDocument data as session $socket properties @return uri :) declare function docs:open( $socket as xs:string, $params as map(*) ) as xs:string { let $text as xs:string:=$params?textDocument?text let $uri:=$params?textDocument?uri let $files:=ws:get($socket,"files",{}) let $files:=if(map:contains($files,$uri)) then $files else let $uuid:=random:uuid() return map:put($files,$uri,{ "textDocument": "file-" || $uuid, "parse": "parse-" || $uuid }) let $keys:=$files($uri) return ( ws:set($socket,"files",$files), ws:set($socket,$keys?textDocument,$params?textDocument), $uri ) }; (: change $textDocument data as session $socket properties @return uri :) declare function docs:change( $socket as xs:string, $params as map(*) ) as xs:string { let $uri:=$params?textDocument?uri let $key:=docs:key($socket,$uri,"textDocument") let $file:=if(exists($key)) then ws:get($socket,$key) else error("no file") let $ver:=$params?textDocument?version let $text:=if($ver eq 1+ $file?version) then pos:apply-changes($file?text,$params?contentChanges) else error("bad ver") let $file:=$file=>map:put("version",$ver)=>map:put("text",$text) return (ws:set($socket,$key,$file), `{$uri} V{ $ver} text: { $text}` ) }; (:~ close a file :) declare function docs:close($socket as xs:string,$uri as xs:string) as map(*){ let $files:=ws:get($socket,"files",{}) return if(map:contains($files,$uri)) then let $props:=$files($uri) return ( map:items($props)!ws:delete($socket,.), ws:set($socket,"files",map:remove($files,$uri)) ) else () }; (:~ list of all files :) declare function docs:list($socket as xs:string) as xs:string*{ ws:get($socket,"files",{})=>map:keys() }; (: document info :) declare type docs:property as enum( "textDocument", "parse" ); (: get $property key for $file from session $socket :) declare function docs:key( $socket as xs:string, $file as xs:string, $property as docs:property ) as xs:string? { ws:get($socket,"files")($file)($property) };