@@ -46,3 +46,79 @@ export interface Infrastructure {
4646 */
4747 openConnection ( id : LanguageClientId ) : Promise < MessageConnection >
4848}
49+
50+ function openWebsocketConnection ( url : URL | string ) : Promise < MessageConnection > {
51+ return new Promise < MessageConnection > ( ( resolve , reject ) => {
52+ const webSocket = new WebSocket ( url )
53+
54+ webSocket . onopen = ( ) => {
55+ const socket = toSocket ( webSocket )
56+ const webSocketConnection = createWebSocketConnection ( socket , new ConsoleLogger ( ) )
57+ webSocketConnection . onDispose ( ( ) => {
58+ webSocket . close ( )
59+ } )
60+
61+ resolve ( webSocketConnection )
62+ }
63+
64+ webSocket . onerror = ( ) => {
65+ reject ( new Error ( 'Unable to connect to server' ) )
66+ }
67+ } )
68+ }
69+
70+ export abstract class CodinGameInfrastructure implements Infrastructure {
71+ constructor (
72+ /**
73+ * The domain of the server
74+ */
75+ public serverAddress : string ,
76+ public useMutualizedProxy : boolean ,
77+ /**
78+ * An optional sessionId when connecting to the session-mutualized server
79+ */
80+ private sessionId ?: string ,
81+ /**
82+ * A list of urls which link to zip files containing libraries/resources
83+ */
84+ private libraryUrls ?: string [ ]
85+ ) {
86+ }
87+
88+ public readonly automaticTextDocumentUpdate = false
89+ public readonly rootUri = 'file:///tmp/project'
90+ public readonly workspaceFolders : typeof vscode . workspace . workspaceFolders = [ {
91+ uri : monaco . Uri . file ( '/tmp/project' ) ,
92+ index : 0 ,
93+ name : 'main'
94+ } ]
95+
96+ public async saveFileContent ( document : TextDocument , reason : TextDocumentSaveReason , languageClient : LanguageClientManager ) : Promise < void > {
97+ if ( languageClient . isReady ( ) ) {
98+ await updateFile ( document . uri . toString ( ) , document . getText ( ) , languageClient )
99+ }
100+ }
101+
102+ public async getFileContent ( resource : monaco . Uri , languageClient : LanguageClientManager ) : Promise < string | null > {
103+ try {
104+ return ( await getFile ( resource . toString ( true ) , languageClient ) ) . text
105+ } catch ( error ) {
106+ console . error ( 'File not found' , resource . toString ( ) )
107+ return null
108+ }
109+ }
110+
111+ /**
112+ * A function which returns a valid JWT token to use to connect to the server
113+ */
114+ protected abstract getSecurityToken ( ) : Promise < string >
115+
116+ public async openConnection ( id : LanguageClientId ) : Promise < MessageConnection > {
117+ const url = new URL ( this . sessionId != null ? `run/${ this . sessionId } /${ id } ` : `run/${ id } ` , this . serverAddress )
118+ this . libraryUrls ?. forEach ( libraryUrl => url . searchParams . append ( 'libraryUrl' , libraryUrl ) )
119+ url . searchParams . append ( 'token' , await this . getSecurityToken ( ) )
120+
121+ const connection = await openWebsocketConnection ( url )
122+ return connection
123+ }
124+ }
0 commit comments