@@ -6,6 +6,8 @@ import { Plugin } from '@remixproject/engine'
6
6
import * as packageJson from '../../../../../package.json'
7
7
import { PluginViewWrapper } from '@remix-ui/helper'
8
8
9
+ import { fetchAndLoadTypes } from './type-fetcher'
10
+
9
11
const EventManager = require ( '../../lib/events' )
10
12
11
13
const profile = {
@@ -71,12 +73,19 @@ export default class Editor extends Plugin {
71
73
this . api = { }
72
74
this . dispatch = null
73
75
this . ref = null
76
+
77
+ this . monaco = null
78
+ this . typeLoaderDebounce = null
74
79
}
75
80
76
81
setDispatch ( dispatch ) {
77
82
this . dispatch = dispatch
78
83
}
79
84
85
+ setMonaco ( monaco ) {
86
+ this . monaco = monaco
87
+ }
88
+
80
89
updateComponent ( state ) {
81
90
return < EditorUI
82
91
editorAPI = { state . api }
@@ -86,6 +95,7 @@ export default class Editor extends Plugin {
86
95
events = { state . events }
87
96
plugin = { state . plugin }
88
97
isDiff = { state . isDiff }
98
+ setMonaco = { ( monaco ) => this . setMonaco ( monaco ) }
89
99
/>
90
100
}
91
101
@@ -128,6 +138,17 @@ export default class Editor extends Plugin {
128
138
129
139
async onActivation ( ) {
130
140
this . activated = true
141
+ this . on ( 'editor' , 'editorMounted' , ( ) => {
142
+ if ( ! this . monaco ) return
143
+ const tsDefaults = this . monaco . languages . typescript . typescriptDefaults
144
+
145
+ tsDefaults . setCompilerOptions ( {
146
+ moduleResolution : this . monaco . languages . typescript . ModuleResolutionKind . NodeJs ,
147
+ typeRoots : [ "file:///node_modules/@types" , "file:///node_modules" ] ,
148
+ target : this . monaco . languages . typescript . ScriptTarget . ES2020 ,
149
+ allowNonTsExtensions : true ,
150
+ } )
151
+ } )
131
152
this . on ( 'sidePanel' , 'focusChanged' , ( name ) => {
132
153
this . keepDecorationsFor ( name , 'sourceAnnotationsPerFile' )
133
154
this . keepDecorationsFor ( name , 'markerPerFile' )
@@ -158,6 +179,30 @@ export default class Editor extends Plugin {
158
179
159
180
async _onChange ( file ) {
160
181
this . triggerEvent ( 'didChangeFile' , [ file ] )
182
+
183
+ if ( this . monaco && ( file . endsWith ( '.ts' ) || file . endsWith ( '.js' ) ) ) {
184
+ clearTimeout ( this . typeLoaderDebounce )
185
+ this . typeLoaderDebounce = setTimeout ( async ( ) => {
186
+ if ( ! this . monaco ) return
187
+ const model = this . monaco . editor . getModel ( this . monaco . Uri . parse ( file ) )
188
+ if ( ! model ) return
189
+ const code = model . getValue ( )
190
+
191
+ try {
192
+ const npmImports = [ ...code . matchAll ( / f r o m \s + [ ' " ] ( (? ! [ . / ] ) .+ ) [ ' " ] / g) ] . map ( match => match [ 1 ] )
193
+ const uniquePackages = [ ...new Set ( npmImports ) ]
194
+
195
+ if ( uniquePackages . length > 0 ) {
196
+ await Promise . all ( uniquePackages . map ( pkg => fetchAndLoadTypes ( pkg , this . monaco ) ) )
197
+ const tsDefaults = this . monaco . languages . typescript . typescriptDefaults
198
+ tsDefaults . setCompilerOptions ( tsDefaults . getCompilerOptions ( ) )
199
+ }
200
+ } catch ( error ) {
201
+ console . error ( '[Type Loader] Error during type loading process:' , error )
202
+ }
203
+ } , 1500 )
204
+ }
205
+
161
206
const currentFile = await this . call ( 'fileManager' , 'file' )
162
207
if ( ! currentFile ) {
163
208
return
@@ -232,7 +277,7 @@ export default class Editor extends Plugin {
232
277
this . emit ( 'addModel' , contentDep , 'typescript' , pathDep , this . readOnlySessions [ path ] )
233
278
}
234
279
} else {
235
- console . log ( "The file " , pathDep , " can't be found." )
280
+ // console.log("The file ", pathDep, " can't be found.")
236
281
}
237
282
} catch ( e ) {
238
283
console . log ( e )
0 commit comments