1
1
import { ReactElement , useEffect , useRef , useState } from 'react'
2
- import { createLanguageClientManager , LanguageClientId , StatusChangeEvent , LanguageClientManager , WillShutdownParams } from '@codingame/monaco-languageclient-wrapper'
2
+ import { createLanguageClientManager , LanguageClientId , StatusChangeEvent as WrapperStatusChangeEvent , LanguageClientManager , WillShutdownParams } from '@codingame/monaco-languageclient-wrapper'
3
3
import useIsUserActive from './hooks/useIsUserActive'
4
4
import useShouldShutdownLanguageClient from './hooks/useShouldShutdownLanguageClient'
5
+ import { useLastVersion } from './hooks/useLastVersion'
6
+
7
+ export interface StatusChangeEvent {
8
+ status : WrapperStatusChangeEvent [ 'status' ] | 'inactivityShutdown'
9
+ }
5
10
6
11
export interface LanguageClientProps {
7
12
id : LanguageClientId
@@ -22,29 +27,33 @@ export interface LanguageClientProps {
22
27
23
28
const defaultLibraryUrls : string [ ] = [ ]
24
29
30
+ const noop = ( ) => null
31
+
25
32
function LanguageClient ( {
26
33
id,
27
34
sessionId,
28
35
languageServerUrl,
29
36
useMutualizedProxy,
30
- getSecurityToken,
37
+ getSecurityToken : _getSecurityToken ,
31
38
libraryUrls = defaultLibraryUrls ,
32
- onError,
33
- onDidChangeStatus,
34
- onWillShutdown,
39
+ onError : _onError ,
40
+ onDidChangeStatus : _onDidChangeStatus ,
41
+ onWillShutdown : _onWillShutdown ,
35
42
userInactivityDelay = 30 * 1000 ,
36
43
userInactivityShutdownDelay = 60 * 1000
37
44
} : LanguageClientProps ) : ReactElement | null {
38
- const onErrorRef = useRef < ( error : Error ) => void > ( )
39
- const onDidChangeStatusRef = useRef < ( status : StatusChangeEvent ) => void > ( )
40
- const onWillShutdownRef = useRef < ( params : WillShutdownParams ) => void > ( )
45
+ const getSecurityToken = useLastVersion ( _getSecurityToken )
46
+ const onError = useLastVersion ( _onError ?? noop )
47
+ const onDidChangeStatus = useLastVersion ( _onDidChangeStatus ?? noop )
48
+ const onWillShutdown = useLastVersion ( _onWillShutdown ?? noop )
49
+
41
50
const languageClientRef = useRef < LanguageClientManager > ( )
42
51
43
52
const [ willShutdown , setWillShutdown ] = useState ( false )
44
53
const [ counter , setCounter ] = useState ( 1 )
45
54
46
55
const isUserInactive = useIsUserActive ( userInactivityDelay )
47
- const shouldShutdownLanguageClient = useShouldShutdownLanguageClient ( isUserInactive , userInactivityShutdownDelay )
56
+ const shouldShutdownLanguageClientForInactivity = useShouldShutdownLanguageClient ( isUserInactive , userInactivityShutdownDelay )
48
57
const restartAllowed = ! isUserInactive
49
58
50
59
useEffect ( ( ) => {
@@ -58,29 +67,22 @@ function LanguageClient ({
58
67
useEffect ( ( ) => {
59
68
setWillShutdown ( false )
60
69
61
- if ( shouldShutdownLanguageClient ) {
70
+ if ( shouldShutdownLanguageClientForInactivity ) {
71
+ onDidChangeStatus ( {
72
+ status : 'inactivityShutdown'
73
+ } )
62
74
return
63
75
}
64
76
65
77
console . info ( `Starting language server for language ${ id } ` )
66
78
const languageClient = createLanguageClientManager ( id , sessionId , languageServerUrl , getSecurityToken , libraryUrls , useMutualizedProxy )
67
79
languageClientRef . current = languageClient
68
- const errorDisposable = languageClient . onError ( ( error : Error ) => {
69
- if ( onErrorRef . current != null ) {
70
- onErrorRef . current ( error )
71
- }
72
- } )
73
- const statusChangeDisposable = languageClient . onDidChangeStatus ( ( status : StatusChangeEvent ) => {
74
- if ( onDidChangeStatusRef . current != null ) {
75
- onDidChangeStatusRef . current ( status )
76
- }
77
- } )
80
+ const errorDisposable = languageClient . onError ( onError )
81
+ const statusChangeDisposable = languageClient . onDidChangeStatus ( onDidChangeStatus )
78
82
const startTimeout = setTimeout ( ( ) => languageClient . start ( ) )
79
83
80
84
languageClient . onWillShutdown ( ( params : WillShutdownParams ) => {
81
- if ( onWillShutdownRef . current != null ) {
82
- onWillShutdownRef . current ( params )
83
- }
85
+ onWillShutdown ( params )
84
86
setWillShutdown ( true )
85
87
} )
86
88
@@ -95,19 +97,7 @@ function LanguageClient ({
95
97
console . error ( 'Unable to dispose language client' , err )
96
98
} )
97
99
}
98
- } , [ getSecurityToken , id , languageServerUrl , libraryUrls , sessionId , counter , useMutualizedProxy , shouldShutdownLanguageClient ] )
99
-
100
- useEffect ( ( ) => {
101
- onErrorRef . current = onError
102
- } , [ onError ] )
103
-
104
- useEffect ( ( ) => {
105
- onDidChangeStatusRef . current = onDidChangeStatus
106
- } , [ onDidChangeStatus ] )
107
-
108
- useEffect ( ( ) => {
109
- onWillShutdownRef . current = onWillShutdown
110
- } , [ onWillShutdown ] )
100
+ } , [ getSecurityToken , id , languageServerUrl , libraryUrls , sessionId , counter , useMutualizedProxy , shouldShutdownLanguageClientForInactivity , onError , onDidChangeStatus , onWillShutdown ] )
111
101
112
102
return null
113
103
}
0 commit comments