const lean_files = { } ; import { lean_server , Lean } from "./lean" ; import { init_global_packages } from "./global-packages" ; import { isEqual } from "underscore" ; let the_lean_server = undefined ; function init_lean_server ( client , logger ) { the_lean_server = lean_server ( client ) ; the_lean_server . on ( "tasks" , function ( path , tasks ) { logger . debug ( "lean_server:websocket:tasks -- " , path , tasks ) ; const lean_file = lean_files [ `lean:${ path }` ] ; if ( lean_file !== undefined && ! isEqual ( lean_file . tasks , tasks ) ) { lean_file . tasks = tasks ; lean_file . channel . write ( { tasks } ) ; } } ) ; the_lean_server . on ( "sync" , function ( path , hash ) { logger . debug ( "lean_server:websocket:sync -- " , path , hash ) ; const lean_file = lean_files [ `lean:${ path }` ] ; if ( lean_file !== undefined && ! isEqual ( lean_file . sync , hash ) ) { const sync = { hash : hash , time : new Date ( ) . valueOf ( ) } ; lean_file . sync = sync ; lean_file . channel . write ( { sync } ) ; } } ) ; the_lean_server . on ( "messages" , function ( path , messages ) { logger . debug ( "lean_server:websocket:messages -- " , path , messages ) ; const lean_file = lean_files [ `lean:${ path }` ] ; if ( lean_file !== undefined && ! isEqual ( lean_file . messages , messages ) ) { lean_file . messages = messages ; lean_file . channel . write ( { messages } ) ; } } ) ; } export async function lean_channel ( client , primus , logger , path ) { if ( the_lean_server === undefined ) { await init_global_packages ( ) ; init_lean_server ( client , logger ) ; if ( the_lean_server === undefined ) { throw Error ( "lean server not defined" ) ; } } the_lean_server . register ( path ) ; const name = `lean:${ path }` ; if ( lean_files [ name ] !== undefined ) { return name ; } const channel = primus . channel ( name ) ; lean_files [ name ] = { channel , messages : [ ] , } ; channel . on ( "connection" , function ( spark ) : void { if ( the_lean_server === undefined ) { throw Error ( "lean server not defined" ) ; } the_lean_server . register ( path ) ; const lean_file = lean_files [ name ] ; if ( lean_file === undefined ) { return ; } logger . debug ( "lean channel" , `new connection from ${ spark . address . ip } -- ${ spark . id }` ) ; spark . write ( { messages : lean_file . messages , sync : lean_file . sync , tasks : lean_file . tasks , } ) ; spark . on ( "end" , function ( ) { } ) ; } ) ; return name ; } function assert_type ( name , x , type ) { if ( typeof x != type ) { throw Error ( `${ name } must have type ${ type }` ) ; } } export async function lean ( client , _ , logger , opts ) { if ( the_lean_server === undefined ) { init_lean_server ( client , logger ) ; if ( the_lean_server === undefined ) { throw Error ( "lean server not defined" ) ; } } if ( opts == null || typeof opts . cmd != "string" ) { throw Error ( "opts must be an object with cmd field a string" ) ; } logger . debug ( "lean command" , JSON . stringify ( opts ) ) ; switch ( opts . cmd ) { case "info" : assert_type ( "path" , opts . path , "string" ) ; assert_type ( "line" , opts . line , "number" ) ; assert_type ( "column" , opts . column , "number" ) ; const r = ( await the_lean_server . info ( opts . path , opts . line , opts . column ) ) . record ; return r ? r : { } ; case "version" : return await the_lean_server . version ( ) ; case "kill" : return the_lean_server . kill ( ) ; case "restart" : return await the_lean_server . restart ( ) ; case "complete" : assert_type ( "path" , opts . path , "string" ) ; assert_type ( "line" , opts . line , "number" ) ; assert_type ( "column" , opts . column , "number" ) ; const complete = await the_lean_server . complete ( opts . path , opts . line , opts . column , opts . skipCompletions ) ; if ( complete == null || complete . completions == null ) { return [ ] ; } for ( const c of complete . completions ) { delete ( c as any ) . source ; } return complete . completions ; default : throw Error ( `unknown cmd ${ opts . cmd }` ) ; } }