()
| 634 | */ |
| 635 | const REFRESH_THROTTLE_MS = 5_000 |
| 636 | export function startBackgroundCacheRefresh(): void { |
| 637 | if (fileListRefreshPromise) return |
| 638 | |
| 639 | // Throttle only when a cache exists — cold start must always populate. |
| 640 | // Refresh immediately when .git/index mtime changed (tracked files). |
| 641 | // Otherwise refresh at most once per 5s — this floor picks up new UNTRACKED |
| 642 | // files, which don't bump .git/index. The signature checks downstream skip |
| 643 | // the rebuild when the 5s refresh finds nothing actually changed. |
| 644 | const indexMtime = getGitIndexMtime() |
| 645 | if (fileIndex) { |
| 646 | const gitStateChanged = |
| 647 | indexMtime !== null && indexMtime !== lastGitIndexMtime |
| 648 | if (!gitStateChanged && Date.now() - lastRefreshMs < REFRESH_THROTTLE_MS) { |
| 649 | return |
| 650 | } |
| 651 | } |
| 652 | |
| 653 | const generation = cacheGeneration |
| 654 | const refreshStart = Date.now() |
| 655 | // Ensure the FileIndex singleton exists — it's progressively queryable |
| 656 | // via readyCount while the build runs. Callers searching early get partial |
| 657 | // results; indexBuildComplete fires after .done so they can re-search. |
| 658 | getFileIndex() |
| 659 | fileListRefreshPromise = getPathsForSuggestions() |
| 660 | .then(result => { |
| 661 | if (generation !== cacheGeneration) { |
| 662 | return result // Cache was cleared; don't overwrite with stale data |
| 663 | } |
| 664 | fileListRefreshPromise = null |
| 665 | indexBuildComplete.emit() |
| 666 | // Commit the start-time mtime observation on success. If git state |
| 667 | // changed mid-refresh, the next call will see the newer mtime and |
| 668 | // correctly refresh again. |
| 669 | lastGitIndexMtime = indexMtime |
| 670 | lastRefreshMs = Date.now() |
| 671 | logForDebugging( |
| 672 | `[FileIndex] cache refresh completed in ${Date.now() - refreshStart}ms`, |
| 673 | ) |
| 674 | return result |
| 675 | }) |
| 676 | .catch(error => { |
| 677 | logForDebugging( |
| 678 | `[FileIndex] Cache refresh failed: ${errorMessage(error)}`, |
| 679 | ) |
| 680 | logError(error) |
| 681 | if (generation === cacheGeneration) { |
| 682 | fileListRefreshPromise = null // Allow retry on next call |
| 683 | } |
| 684 | return getFileIndex() |
| 685 | }) |
| 686 | } |
| 687 | |
| 688 | /** |
| 689 | * Gets the top-level files and directories in the current working directory |
no test coverage detected