import ts from 'typescript' ; import { getLastPartOfPath } from '../../utils' ; import { DocumentSnapshot } from './DocumentSnapshot' ; import { createSvelteSys } from './svelte-sys' ; import { ensureRealSvelteFilePath , getExtensionFromScriptKind , isVirtualSvelteFilePath } from './utils' ; /**
 * Caches resolved modules.
 */ class ModuleResolutionCache { private cache = new Map < string , ts . ResolvedModule | undefined > ( ) ; /**
     * Tries to get a cached module.
     * Careful: `undefined` can mean either there's no match found, or that the result resolved to `undefined`.
     */ get ( moduleName , containingFile ) { return this . cache . get ( this . getKey ( moduleName , containingFile ) ) ; } /**
     * Checks if has cached module.
     */ has ( moduleName , containingFile ) { return this . cache . has ( this . getKey ( moduleName , containingFile ) ) ; } /**
     * Caches resolved module (or undefined).
     */ set ( moduleName , containingFile , resolvedModule ) { this . cache . set ( this . getKey ( moduleName , containingFile ) , resolvedModule ) ; } param resolvedModuleName delete ( resolvedModuleName ) { this . cache . forEach ( ( val , key ) => { if ( val ?. resolvedFileName === resolvedModuleName ) { this . cache . delete ( key ) ; } } ) ; } /**
     * Deletes everything from cache that resolved to `undefined`
     * and which might match the path.
     */ deleteUnresolvedResolutionsFromCache ( path ) { const fileNameWithoutEnding = getLastPartOfPath ( path ) . split ( '.' ) . shift ( ) || '' ; this . cache . forEach ( ( val , key ) => { const moduleName = key . split ( ':::' ) . pop ( ) || '' ; if ( ! val && moduleName . includes ( fileNameWithoutEnding ) ) { this . cache . delete ( key ) ; } } ) ; } private getKey ( moduleName , containingFile ) { return containingFile + ':::' + ensureRealSvelteFilePath ( moduleName ) ; } } param getSnapshot param compilerOptions export function createSvelteModuleLoader ( getSnapshot , compilerOptions ) { const svelteSys = createSvelteSys ( getSnapshot ) ; const moduleCache = new ModuleResolutionCache ( ) ; return { fileExists : svelteSys . fileExists , readFile : svelteSys . readFile , readDirectory : svelteSys . readDirectory , deleteFromModuleCache : ( path ) => { svelteSys . deleteFromCache ( path ) ; moduleCache . delete ( path ) ; } , deleteUnresolvedResolutionsFromCache : ( path ) => { svelteSys . deleteFromCache ( path ) ; moduleCache . deleteUnresolvedResolutionsFromCache ( path ) ; } , resolveModuleNames } ; function resolveModuleNames ( moduleNames , containingFile ) { return moduleNames . map ( ( moduleName ) => { if ( moduleCache . has ( moduleName , containingFile ) ) { return moduleCache . get ( moduleName , containingFile ) ; } const resolvedModule = resolveModuleName ( moduleName , containingFile ) ; moduleCache . set ( moduleName , containingFile , resolvedModule ) ; return resolvedModule ; } ) ; } function resolveModuleName ( name , containingFile ) { const tsResolvedModule = ts . resolveModuleName ( name , containingFile , compilerOptions , ts . sys ) . resolvedModule ; if ( tsResolvedModule && ! isVirtualSvelteFilePath ( tsResolvedModule . resolvedFileName ) ) { return tsResolvedModule ; } const svelteResolvedModule = ts . resolveModuleName ( name , containingFile , compilerOptions , svelteSys ) . resolvedModule ; if ( ! svelteResolvedModule || ! isVirtualSvelteFilePath ( svelteResolvedModule . resolvedFileName ) ) { return svelteResolvedModule ; } const resolvedFileName = ensureRealSvelteFilePath ( svelteResolvedModule . resolvedFileName ) ; const snapshot = getSnapshot ( resolvedFileName ) ; const resolvedSvelteModule = { extension : getExtensionFromScriptKind ( snapshot && snapshot . scriptKind ) , resolvedFileName , isExternalLibraryImport : svelteResolvedModule . isExternalLibraryImport } ; return resolvedSvelteModule ; } }