@@ -473,7 +473,7 @@ async function getReadyServerConnection(
473473 { type : "isready" , content : { } } ,
474474 transportOptions . key ,
475475 executeOptions ,
476- ) as Promise < boolean > ;
476+ ) ;
477477 const timeoutMilliseconds = 10000 ;
478478 const timeout = new Promise ( ( accept , _ ) =>
479479 setTimeout ( ( ) => {
@@ -590,7 +590,7 @@ async function executeJulia(
590590 { type : "isopen" , content : { file } } ,
591591 transportOptions . key ,
592592 options ,
593- ) as boolean ;
593+ ) ;
594594 if ( isopen ) {
595595 await writeJuliaCommand (
596596 conn ,
@@ -629,11 +629,7 @@ async function executeJulia(
629629 ) ;
630630 }
631631
632- if ( response . error !== undefined ) {
633- throw new Error ( "Running notebook failed:\n" + response . juliaError ) ;
634- }
635-
636- return response . notebook as JupyterNotebook ;
632+ return response . notebook ;
637633}
638634
639635interface ProgressUpdate {
@@ -654,13 +650,38 @@ type ServerCommand =
654650 | { type : "isready" ; content : empty }
655651 | { type : "status" ; content : empty } ;
656652
657- async function writeJuliaCommand (
653+ type ServerCommandResponseMap = {
654+ run : { notebook : JupyterNotebook } ;
655+ close : { status : true } ;
656+ stop : { message : "Server stopped." } ;
657+ isopen : boolean ;
658+ isready : true ;
659+ status : string ;
660+ } ;
661+
662+ type ServerCommandError = {
663+ error : string ;
664+ juliaError ?: string ;
665+ } ;
666+
667+ type ServerCommandResponse < T extends ServerCommand [ "type" ] > =
668+ ServerCommandResponseMap [ T ] ;
669+
670+ function isProgressUpdate ( data : any ) : data is ProgressUpdate {
671+ return data && data . type === "progress_update" ;
672+ }
673+
674+ function isServerCommandError ( data : any ) : data is ServerCommandError {
675+ return data && typeof ( data . error ) === "string" ;
676+ }
677+
678+ async function writeJuliaCommand < T extends ServerCommand [ "type" ] > (
658679 conn : Deno . Conn ,
659- command : ServerCommand ,
680+ command : Extract < ServerCommand , { type : T } > ,
660681 secret : string ,
661682 options : JuliaExecuteOptions ,
662683 onProgressUpdate ?: ( update : ProgressUpdate ) => void ,
663- ) {
684+ ) : Promise < ServerCommandResponse < T > > {
664685 const payload = JSON . stringify ( command ) ;
665686 const key = await crypto . subtle . importKey (
666687 "raw" ,
@@ -752,30 +773,41 @@ async function writeJuliaCommand(
752773 // one command should be sent, ended by a newline, currently just throwing away anything else because we don't
753774 // expect multiple commmands at once
754775 const json = response . split ( "\n" ) [ 0 ] ;
755- const data = JSON . parse ( json ) ;
776+ const responseData = JSON . parse ( json ) ;
756777
757- if ( data . type === "progress_update" ) {
758- trace (
759- options ,
760- "received progress update response, listening for further responses" ,
761- ) ;
762- if ( onProgressUpdate !== undefined ) {
763- onProgressUpdate ( data as ProgressUpdate ) ;
764- }
765- continue ; // wait for the next message
766- }
767-
768- const err = data . error ;
769- if ( err !== undefined ) {
770- const juliaError = data . juliaError ?? "No julia error message available." ;
778+ if ( isServerCommandError ( responseData ) ) {
779+ const data = responseData ;
771780 error (
772781 `Julia server returned error after receiving "${ command . type } " command:\n` +
773- err ,
782+ data . error ,
774783 ) ;
775- error ( juliaError ) ;
784+ if ( data . juliaError ) {
785+ error ( data . juliaError ) ;
786+ }
776787 throw new Error ( "Internal julia server error" ) ;
777788 }
778789
790+ let data : ServerCommandResponse < T > ;
791+ if ( command . type === "run" ) {
792+ const data_or_update : ServerCommandResponse < T > | ProgressUpdate =
793+ responseData ;
794+ if ( isProgressUpdate ( data_or_update ) ) {
795+ const update = data_or_update ;
796+ trace (
797+ options ,
798+ "received progress update response, listening for further responses" ,
799+ ) ;
800+ if ( onProgressUpdate !== undefined ) {
801+ onProgressUpdate ( update ) ;
802+ }
803+ continue ; // wait for the next message
804+ } else {
805+ data = data_or_update ;
806+ }
807+ } else {
808+ data = responseData ;
809+ }
810+
779811 return data ;
780812 }
781813}
0 commit comments