@@ -269,7 +269,7 @@ export class SvelteSnapshot {
269
269
}
270
270
271
271
export class SvelteSnapshotManager {
272
- private snapshots = new Map < string , SvelteSnapshot > ( ) ;
272
+ private snapshots : Map < string , SvelteSnapshot > ;
273
273
274
274
constructor (
275
275
private typescript : typeof ts ,
@@ -280,7 +280,9 @@ export class SvelteSnapshotManager {
280
280
/** undefined if no node_modules with Svelte next to tsconfig.json */
281
281
private svelteCompiler : typeof import ( 'svelte/compiler' ) | undefined
282
282
) {
283
- this . patchProjectServiceReadFile ( ) ;
283
+ this . patchProjectService ( ) ;
284
+ // @ts -expect-error
285
+ this . snapshots = this . projectService [ snapshots ] ;
284
286
}
285
287
286
288
get ( fileName : string ) {
@@ -321,92 +323,78 @@ export class SvelteSnapshotManager {
321
323
return snapshot ;
322
324
}
323
325
324
- private patchProjectServiceReadFile ( ) {
325
- // @ts -ignore The projectService is shared across some instances, make sure we patch readFile only once
326
- if ( ! this . projectService . host [ onReadSvelteFile ] ) {
327
- this . logger . log ( 'patching projectService host readFile' ) ;
326
+ private patchProjectService ( ) {
327
+ // @ts -expect-error The projectService is shared across some instances, make sure we patch only once
328
+ if ( this . projectService [ snapshots ] ) return ;
328
329
329
- // @ts -ignore
330
- this . projectService . host [ onReadSvelteFile ] = [ ] ;
330
+ this . logger . log ( 'patching projectService' ) ;
331
331
332
- const readFile = this . projectService . host . readFile ;
333
- this . projectService . host . readFile = ( path : string , encoding ?: string | undefined ) => {
334
- if ( ! this . configManager . getConfig ( ) . enable ) {
335
- return readFile ( path , encoding ) ;
336
- }
332
+ // @ts -expect-error Snapshots are stored on the projectService, so they are shared across all instances
333
+ this . snapshots = this . projectService [ snapshots ] = new Map ( ) ;
337
334
338
- // The following (very hacky) first two checks make sure that the ambient module definitions
339
- // that tell TS "every import ending with .svelte is a valid module" are removed.
340
- // They exist in svelte2tsx and svelte to make sure that people don't
341
- // get errors in their TS files when importing Svelte files and not using our TS plugin.
342
- // If someone wants to get back the behavior they can add an ambient module definition
343
- // on their own.
344
- const normalizedPath = path . replace ( / \\ / g, '/' ) ;
345
- if ( normalizedPath . endsWith ( 'node_modules/svelte/types/runtime/ambient.d.ts' ) ) {
346
- return '' ;
347
- } else if ( normalizedPath . endsWith ( 'svelte2tsx/svelte-jsx.d.ts' ) ) {
348
- // Remove the dom lib reference to not load these ambient types in case
349
- // the user has a tsconfig.json with different lib settings like in
350
- // https://github.com/sveltejs/language-tools/issues/1733
351
- const originalText = readFile ( path ) || '' ;
352
- const toReplace = '/// <reference lib="dom" />' ;
353
- return originalText . replace ( toReplace , ' ' . repeat ( toReplace . length ) ) ;
354
- } else if ( normalizedPath . endsWith ( 'svelte2tsx/svelte-shims.d.ts' ) ) {
355
- let originalText = readFile ( path ) || '' ;
356
- if ( ! originalText . includes ( '// -- start svelte-ls-remove --' ) ) {
357
- return originalText ; // uses an older version of svelte2tsx or is already patched
358
- }
359
- const startIdx = originalText . indexOf ( '// -- start svelte-ls-remove --' ) ;
360
- const endIdx = originalText . indexOf ( '// -- end svelte-ls-remove --' ) ;
361
- originalText =
362
- originalText . substring ( 0 , startIdx ) +
363
- ' ' . repeat ( endIdx - startIdx ) +
364
- originalText . substring ( endIdx ) ;
365
- return originalText ;
366
- } else if ( isSvelteFilePath ( path ) ) {
367
- this . logger . debug ( 'Read Svelte file:' , path ) ;
368
- const svelteCode = readFile ( path ) || '' ;
369
- const isTsFile = true ; // TODO check file contents? TS might be okay with importing ts into js.
370
- let code : string ;
371
- let mapper : SourceMapper ;
372
-
373
- try {
374
- const result = svelte2tsx ( svelteCode , {
375
- filename : path . split ( '/' ) . pop ( ) ,
376
- isTsFile,
377
- mode : 'ts' ,
378
- typingsNamespace : this . svelteOptions . namespace ,
379
- // Don't search for compiler from current path - could be a different one from which we have loaded the svelte2tsx globals
380
- parse : this . svelteCompiler ?. parse ,
381
- version : this . svelteCompiler ?. VERSION
382
- } ) ;
383
- code = result . code ;
384
- mapper = new SourceMapper ( result . map . mappings ) ;
385
- this . logger . log ( 'Successfully read Svelte file contents of' , path ) ;
386
- } catch ( e ) {
387
- this . logger . log ( 'Error loading Svelte file:' , path , ' Using fallback.' ) ;
388
- this . logger . debug ( 'Error:' , e ) ;
389
- // Return something either way, else "X is not a module" errors will appear
390
- // in the TS files that use this file.
391
- code = 'export default class extends Svelte2TsxComponent<any,any,any> {}' ;
392
- mapper = new SourceMapper ( '' ) ;
393
- }
394
-
395
- // @ts -ignore
396
- this . projectService . host [ onReadSvelteFile ] . forEach ( ( listener ) =>
397
- listener ( path , svelteCode , isTsFile , mapper )
398
- ) ;
335
+ const readFile = this . projectService . host . readFile ;
336
+ this . projectService . host . readFile = ( path : string , encoding ?: string | undefined ) => {
337
+ if ( ! this . configManager . getConfig ( ) . enable ) {
338
+ return readFile ( path , encoding ) ;
339
+ }
399
340
400
- return code ;
401
- } else {
402
- return readFile ( path , encoding ) ;
341
+ // The following (very hacky) first two checks make sure that the ambient module definitions
342
+ // that tell TS "every import ending with .svelte is a valid module" are removed.
343
+ // They exist in svelte2tsx and svelte to make sure that people don't
344
+ // get errors in their TS files when importing Svelte files and not using our TS plugin.
345
+ // If someone wants to get back the behavior they can add an ambient module definition
346
+ // on their own.
347
+ const normalizedPath = path . replace ( / \\ / g, '/' ) ;
348
+ if ( normalizedPath . endsWith ( 'node_modules/svelte/types/runtime/ambient.d.ts' ) ) {
349
+ return '' ;
350
+ } else if ( normalizedPath . endsWith ( 'svelte2tsx/svelte-jsx.d.ts' ) ) {
351
+ // Remove the dom lib reference to not load these ambient types in case
352
+ // the user has a tsconfig.json with different lib settings like in
353
+ // https://github.com/sveltejs/language-tools/issues/1733
354
+ const originalText = readFile ( path ) || '' ;
355
+ const toReplace = '/// <reference lib="dom" />' ;
356
+ return originalText . replace ( toReplace , ' ' . repeat ( toReplace . length ) ) ;
357
+ } else if ( normalizedPath . endsWith ( 'svelte2tsx/svelte-shims.d.ts' ) ) {
358
+ let originalText = readFile ( path ) || '' ;
359
+ if ( ! originalText . includes ( '// -- start svelte-ls-remove --' ) ) {
360
+ return originalText ; // uses an older version of svelte2tsx or is already patched
361
+ }
362
+ const startIdx = originalText . indexOf ( '// -- start svelte-ls-remove --' ) ;
363
+ const endIdx = originalText . indexOf ( '// -- end svelte-ls-remove --' ) ;
364
+ originalText =
365
+ originalText . substring ( 0 , startIdx ) +
366
+ ' ' . repeat ( endIdx - startIdx ) +
367
+ originalText . substring ( endIdx ) ;
368
+ return originalText ;
369
+ } else if ( isSvelteFilePath ( path ) ) {
370
+ this . logger . debug ( 'Read Svelte file:' , path ) ;
371
+ const svelteCode = readFile ( path ) || '' ;
372
+ const isTsFile = true ; // TODO check file contents? TS might be okay with importing ts into js.
373
+ let code : string ;
374
+ let mapper : SourceMapper ;
375
+
376
+ try {
377
+ const result = svelte2tsx ( svelteCode , {
378
+ filename : path . split ( '/' ) . pop ( ) ,
379
+ isTsFile,
380
+ mode : 'ts' ,
381
+ typingsNamespace : this . svelteOptions . namespace ,
382
+ // Don't search for compiler from current path - could be a different one from which we have loaded the svelte2tsx globals
383
+ parse : this . svelteCompiler ?. parse ,
384
+ version : this . svelteCompiler ?. VERSION
385
+ } ) ;
386
+ code = result . code ;
387
+ mapper = new SourceMapper ( result . map . mappings ) ;
388
+ this . logger . log ( 'Successfully read Svelte file contents of' , path ) ;
389
+ } catch ( e ) {
390
+ this . logger . log ( 'Error loading Svelte file:' , path , ' Using fallback.' ) ;
391
+ this . logger . debug ( 'Error:' , e ) ;
392
+ // Return something either way, else "X is not a module" errors will appear
393
+ // in the TS files that use this file.
394
+ code = 'export default class extends Svelte2TsxComponent<any,any,any> {}' ;
395
+ mapper = new SourceMapper ( '' ) ;
403
396
}
404
- } ;
405
- }
406
397
407
- // @ts -ignore
408
- this . projectService . host [ onReadSvelteFile ] . push (
409
- ( path : string , svelteCode : string , isTsFile : boolean , mapper : SourceMapper ) => {
410
398
const canonicalFilePath = this . projectService . toCanonicalFileName ( path ) ;
411
399
const existingSnapshot = this . snapshots . get ( canonicalFilePath ) ;
412
400
if ( existingSnapshot ) {
@@ -424,9 +412,13 @@ export class SvelteSnapshotManager {
424
412
)
425
413
) ;
426
414
}
415
+
416
+ return code ;
417
+ } else {
418
+ return readFile ( path , encoding ) ;
427
419
}
428
- ) ;
420
+ } ;
429
421
}
430
422
}
431
423
432
- const onReadSvelteFile = Symbol ( 'sveltePluginPatchSymbol' ) ;
424
+ const snapshots = Symbol ( 'sveltePluginPatchSymbol' ) ;
0 commit comments