Repository navigation
Keep extracted auto-import packages across cancelled builds - #65412
Open
Andrea Cappuccio (hood) wants to merge 1 commit into
Open
Andrea Cappuccio (hood) wants to merge 1 commit into
Andrea Cappuccio (hood) wants to merge 1 commit into
Conversation
The auto-import warm-up is cancelled on every keystroke and used to drop every package it had already extracted, so while typing it re-read and re-parsed node_modules over and over without ever finishing. Started extractions now run to completion and are shared with later builds until node_modules, a kept package's directory or the build inputs change.
Jake Bailey (jakebailey)
requested a review
from Andrew Branch (andrewbranch)
November 9, 2026 20:46
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
Active cache invalidation gaps can reuse stale exports after workspace edits, while cancelled warm-ups can repeatedly restart extraction because compatible cache replacements are not retained.
3 open issues
What changed in this PR
Addresses #65410 by retaining package extraction work across cancelled auto-import builds, reducing repeated parsing while typing in the language server.
Changes:
- Shares completed and in-flight package extractions across registry clones.
- Adds cache invalidation for file and build-input changes, plus cleanup after successful builds.
- Adds regression tests for reuse after cancellation and invalidation after
node_moduleschanges.
| File | Description |
|---|---|
tsc/internal/ls/autoimport/registry.go |
Adds shared extraction caching, single-flight coordination, and invalidation. |
tsc/internal/ls/autoimport/registry_test.go |
Tests cancelled-build reuse and re-extraction after package changes. |
Review effort: Balanced
Comment on lines
+386
to
+388
| p.results.Range(func(key extractionKey, _ *pendingExtraction) bool { | ||
| affected = caseSensitivity.ContainsPath(key.realpath, tspath.RootedPath(fileName)) | ||
| return !affected |
Comment on lines
+386
to
+388
| p.results.Range(func(key extractionKey, _ *pendingExtraction) bool { | ||
| affected = caseSensitivity.ContainsPath(key.realpath, tspath.RootedPath(fileName)) | ||
| return !affected |
Comment on lines
+985
to
+988
| if !partial.usableFor(buildPreferences, projectReferenceOutputs) { | ||
| partial = &partialExtractions{} | ||
| partial.usableFor(buildPreferences, projectReferenceOutputs) | ||
| b.partialExtractions = partial |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Fixes #65410
While typing, the auto-import warm-up gets cancelled on every keystroke and used to throw away every package it had already extracted, so it kept re-reading and re-parsing
node_modulesfrom scratch and never finished if you type faster than one full build. This keeps per-package extraction results on the registry, shared from one clone to the next, so a cancelled build leaves its finished packages for the next one:node_modulesor under a kept package's own directory changes (workspace packages), when bucket build preferences or project-reference outputs change, and once a build completes, so memory goes back to what it was once the index is ready.src/cartesian/Line.tsx, 120 keystrokes at 150 ms, diagnostics + semantic tokens per keymain(7 runs)textDocument/diagnosticmedianMeasured with this harness: https://gist.github.com/hood/506e87027c83bbec1b44c1f687273349
Tests:
TestCancelledBuildKeepsExtractedPackages: a build cancelled mid-extraction doesn't extract that package again on the next build (fails onmain), and anode_moduleschange still re-extracts it.mainon the same session across 13 prefixes: 21,610 items, 6,335 of them auto-imports.go test ./...,npx hereby lintandnpx hereby check:formatpass.AI disclosure: I polished my solution, my breakdown of it and -most importantly- did most of the measurements with help from an AI agent. I've gone 2x through everything and I'll handle any follow-up myself ofc.