diff --git a/frontend/src/lib/ata/index.ts b/frontend/src/lib/ata/index.ts index 4f5c585900..004fe7f6df 100644 --- a/frontend/src/lib/ata/index.ts +++ b/frontend/src/lib/ata/index.ts @@ -136,7 +136,7 @@ export const setupTypeAcquisition = (config: ATABootstrapConfig) => { : '/' + config.scriptPath + (f.raw.startsWith('../') ? '/../' : '/.') + f.raw let url = config.root + path let localPath = f.raw - if (f.raw.startsWith('.') && !f.raw.endsWith('.ts')) { + if ((f.raw.startsWith('.') || f.raw.startsWith('/')) && !f.raw.endsWith('.ts')) { url += '.ts' localPath += '.ts' } diff --git a/frontend/src/lib/components/Editor.svelte b/frontend/src/lib/components/Editor.svelte index 352e963080..ebbf492147 100644 --- a/frontend/src/lib/components/Editor.svelte +++ b/frontend/src/lib/components/Editor.svelte @@ -204,6 +204,7 @@ let lastWsAttempt: Date = new Date() let nbWsAttempt = 0 let disposeMethod: (() => void) | undefined + const absolutePathExtraLibs = new Map void }>() const dispatch = createEventDispatcher() // let graphqlService: MonacoGraphQLAPI | undefined = undefined @@ -1644,6 +1645,8 @@ (scriptLang == 'bun' || scriptLang == 'tsx' || scriptLang == 'bunnative') && ata == undefined ) { + absolutePathExtraLibs.forEach((d) => d.dispose()) + absolutePathExtraLibs.clear() const hostname = getHostname() const addLibraryToRuntime = async (code: string, _path: string) => { @@ -1659,12 +1662,17 @@ } const addLocalFile = async (code: string, _path: string) => { + if (destroyed) return let p = new URL(_path, uri).href - // if (_path?.startsWith('/')) { - // p = 'file://' + p - // } let nuri = mUri.parse(p) console.log('adding local file', _path, nuri.toString()) + // Monaco's TS service resolves relative imports against the importer's URI (finding the + // model), but absolute paths like "/u/admin/foo" are looked up as raw paths and miss the + // `file://` model. Register them as extra libs so TS can resolve them. + if (_path.startsWith('/')) { + absolutePathExtraLibs.get(_path)?.dispose() + absolutePathExtraLibs.set(_path, typescriptDefaults.addExtraLib(code, _path)) + } if (editor) { let localModel = meditor.getModel(nuri) if (localModel) { @@ -1783,6 +1791,8 @@ timeoutModel && clearTimeout(timeoutModel) loadTimeout && clearTimeout(loadTimeout) aiChatEditorHandler?.clear() + absolutePathExtraLibs.forEach((d) => d.dispose()) + absolutePathExtraLibs.clear() }) async function genRoot(hostname: string) {