33* Licensed under the MIT License. See LICENSE in the package root for license information.
44* ------------------------------------------------------------------------------------------ */
55
6+ import { Deferred } from 'monaco-languageclient/common' ;
67import { EditorApp , type EditorAppConfig , type TextContents } from 'monaco-languageclient/editorApp' ;
78import { type LanguageClientConfig , LanguageClientManager } from 'monaco-languageclient/lcwrapper' ;
89import { getEnhancedMonacoEnvironment , type MonacoVscodeApiConfig , MonacoVscodeApiWrapper } from 'monaco-languageclient/vscodeApiWrapper' ;
@@ -36,8 +37,46 @@ const haveEditorService = () => {
3637} ;
3738
3839const runQueue : Array < { id : string , func : ( ) => Promise < void > } > = [ ] ;
39- let queueAwait : Promise < void > | undefined = undefined ;
40- let queueResolve : ( ( value : void | PromiseLike < void > ) => void ) | undefined = undefined ;
40+ let queueAwait : Deferred | undefined = new Deferred ( ) ;
41+
42+ const addQueue = ( id : string , func : ( ) => Promise < void > ) => {
43+ debugLogging ( '=======================' ) ;
44+ debugLogging ( `Adding to queue: ${ id } ` ) ;
45+ debugLogging ( `QUEUE SIZE before: ${ runQueue . length } ` ) ;
46+ runQueue . push ( { id, func} ) ;
47+
48+ executeQueue ( ) ;
49+ } ;
50+
51+ const executeQueue = async ( ) => {
52+ if ( queueAwait !== undefined ) {
53+ await queueAwait . promise ;
54+ }
55+ if ( runQueue . length > 0 ) {
56+ queueAwait = new Deferred ( ) ;
57+ const queueObj = runQueue . shift ( ) ;
58+ if ( queueObj !== undefined ) {
59+ debugLogging ( `QUEUE ${ queueObj . id } SIZE before: ${ runQueue . length } ` ) ;
60+ debugLogging ( `QUEUE ${ queueObj . id } start` , true ) ;
61+ await queueObj . func ( ) ;
62+ debugLogging ( `QUEUE ${ queueObj . id } SIZE after: ${ runQueue . length } ` ) ;
63+ debugLogging ( `QUEUE ${ queueObj . id } end` ) ;
64+ }
65+
66+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
67+ queueAwait ?. resolve ( ) ;
68+ queueAwait = undefined ;
69+ executeQueue ( ) ;
70+ }
71+ } ;
72+
73+ const debugLogging = ( id : string , useTime ?: boolean ) => {
74+ if ( useTime === true ) {
75+ apiWrapper ?. getLogger ( ) . debug ( `${ id } : ${ Date . now ( ) } ` ) ;
76+ } else {
77+ apiWrapper ?. getLogger ( ) . debug ( id ) ;
78+ }
79+ } ;
4180
4281export const MonacoEditorReactComp : React . FC < MonacoEditorProps > = ( props ) => {
4382 const {
@@ -65,47 +104,6 @@ export const MonacoEditorReactComp: React.FC<MonacoEditorProps> = (props) => {
65104 const modifiedCode = useRef < string > ( modifiedTextValue ) ;
66105 const originalCode = useRef < string > ( originalTextValue ) ;
67106
68- const addQueue = ( id : string , func : ( ) => Promise < void > ) => {
69- debugLogging ( `Adding to queue: ${ id } ` ) ;
70- debugLogging ( `QUEUE SIZE before: ${ runQueue . length } ` ) ;
71- runQueue . push ( { id, func} ) ;
72- } ;
73-
74- const triggerQueue = ( ) => {
75- setInterval ( ( ) => {
76- if ( queueAwait === undefined ) {
77- queueAwait = new Promise < void > ( ( resolve ) => {
78- queueResolve = resolve ;
79- } ) ;
80- executeQueue ( ) ;
81- }
82- } , 50 ) ;
83- } ;
84-
85- const executeQueue = async ( ) => {
86- while ( runQueue . length > 0 ) {
87- const queueObj = runQueue . shift ( ) ;
88- if ( queueObj !== undefined ) {
89- debugLogging ( `QUEUE ${ queueObj . id } SIZE before: ${ runQueue . length } ` ) ;
90- debugLogging ( `QUEUE ${ queueObj . id } start` , true ) ;
91- await queueObj . func ( ) ;
92- debugLogging ( `QUEUE ${ queueObj . id } SIZE after: ${ runQueue . length } ` ) ;
93- debugLogging ( `QUEUE ${ queueObj . id } end` ) ;
94- }
95- }
96- queueResolve ?.( ) ;
97- queueAwait = undefined ;
98- queueResolve = undefined ;
99- } ;
100-
101- const debugLogging = ( id : string , useTime ?: boolean ) => {
102- if ( useTime === true ) {
103- apiWrapper ?. getLogger ( ) . debug ( `${ id } : ${ Date . now ( ) } ` ) ;
104- } else {
105- apiWrapper ?. getLogger ( ) . debug ( id ) ;
106- }
107- } ;
108-
109107 const performErrorHandling = ( error : Error ) => {
110108 if ( onError ) {
111109 onError ( error ) ;
@@ -156,15 +154,14 @@ export const MonacoEditorReactComp: React.FC<MonacoEditorProps> = (props) => {
156154 lcsManager . setLogger ( apiWrapper . getLogger ( ) ) ;
157155
158156 onVscodeApiInitDone ?.( apiWrapper ) ;
159- triggerQueue ( ) ;
160157 debugLogging ( 'GLOBAL INIT DONE' , true ) ;
158+
159+ queueAwait ?. resolve ( ) ;
161160 } catch ( error ) {
162161 performErrorHandling ( error as Error ) ;
163162 }
164163 } ;
165164 globalInitFunc ( ) ;
166- } else if ( envEnhanced . vscodeApiInitialised === true ) {
167- triggerQueue ( ) ;
168165 }
169166 } ;
170167
@@ -178,47 +175,49 @@ export const MonacoEditorReactComp: React.FC<MonacoEditorProps> = (props) => {
178175 // re-create editor if config changed
179176 const recreateEditor = editorAppRef . current === undefined || currentEditorConfig . current === undefined ||
180177 JSON . stringify ( editorAppConfig ) !== JSON . stringify ( currentEditorConfig . current ) ;
181- const editorInitFunc = async ( ) => {
182- try {
183- debugLogging ( 'INIT' , true ) ;
178+ if ( recreateEditor ) {
179+ const editorInitFunc = async ( ) => {
180+ try {
181+ debugLogging ( 'INIT' , true ) ;
184182
185- // it is possible to run without an editorApp, for example when using the ViewsService
186- if ( recreateEditor && haveEditorService ( ) ) {
187- debugLogging ( 'INIT: Creating editor' , true ) ;
183+ // it is possible to run without an editorApp, for example when using the ViewsService
184+ if ( haveEditorService ( ) ) {
185+ debugLogging ( 'INIT: Creating editor' , true ) ;
188186
189- await handleEditorDispose ( ) ;
187+ await handleEditorDispose ( ) ;
190188
191- currentEditorConfig . current = editorAppConfig ;
192- editorAppRef . current = new EditorApp ( editorAppConfig ) ;
193- if ( editorAppRef . current . isStarting ( ) === true || editorAppRef . current . isDisposing ( ) === true ) {
194- await Promise . all ( [
195- editorAppRef . current . getStartingAwait ( ) ,
196- editorAppRef . current . getDisposingAwait ( )
197- ] ) ;
198- }
199-
200- editorAppRef . current . registerOnTextChangedCallback ( ( textChanges ) => {
201- if ( textChanges . modified !== undefined ) {
202- modifiedCode . current = textChanges . modified ;
203- }
204- if ( textChanges . original !== undefined ) {
205- originalCode . current = textChanges . original ;
206- }
207- if ( onTextChangedRef . current !== undefined ) {
208- onTextChangedRef . current ( textChanges ) ;
189+ currentEditorConfig . current = editorAppConfig ;
190+ editorAppRef . current = new EditorApp ( editorAppConfig ) ;
191+ if ( editorAppRef . current . isStarting ( ) === true || editorAppRef . current . isDisposing ( ) === true ) {
192+ await Promise . all ( [
193+ editorAppRef . current . getStartingAwait ( ) ,
194+ editorAppRef . current . getDisposingAwait ( )
195+ ] ) ;
209196 }
210- } ) ;
211- await editorAppRef . current . start ( containerRef . current ! ) ;
212197
213- onEditorStartDone ?.( editorAppRef . current ) ;
214- }
198+ editorAppRef . current . registerOnTextChangedCallback ( ( textChanges ) => {
199+ if ( textChanges . modified !== undefined ) {
200+ modifiedCode . current = textChanges . modified ;
201+ }
202+ if ( textChanges . original !== undefined ) {
203+ originalCode . current = textChanges . original ;
204+ }
205+ if ( onTextChangedRef . current !== undefined ) {
206+ onTextChangedRef . current ( textChanges ) ;
207+ }
208+ } ) ;
209+ await editorAppRef . current . start ( containerRef . current ! ) ;
215210
216- debugLogging ( 'INIT DONE' , true ) ;
217- } catch ( error ) {
218- performErrorHandling ( error as Error ) ;
219- }
220- } ;
221- addQueue ( 'editorInit' , editorInitFunc ) ;
211+ onEditorStartDone ?.( editorAppRef . current ) ;
212+ }
213+
214+ debugLogging ( 'INIT DONE' , true ) ;
215+ } catch ( error ) {
216+ performErrorHandling ( error as Error ) ;
217+ }
218+ } ;
219+ addQueue ( 'editorInit' , editorInitFunc ) ;
220+ }
222221 } , [ editorAppConfig ] ) ;
223222
224223 const handleEditorDispose = async ( ) => {
@@ -238,7 +237,7 @@ export const MonacoEditorReactComp: React.FC<MonacoEditorProps> = (props) => {
238237
239238 const lcInitFunc = async ( ) => {
240239 try {
241- debugLogging ( 'INIT LC2 ' , true ) ;
240+ debugLogging ( 'INIT LC ' , true ) ;
242241
243242 await lcsManager . setConfig ( languageClientConfig ) ;
244243 await lcsManager . start ( ) ;
0 commit comments