@@ -24,6 +24,10 @@ extension WorkspaceDocument.SearchState {
2424 isLoading: true
2525 )
2626 }
27+
28+ let ( progressStream, continuation) = AsyncStream< Double> . makeStream( )
29+ // Dispatch this now, we want to continue after starting to monitor
30+ Task { await self . monitorProgressStream ( progressStream, activityId: activity. id) }
2731
2832 Task . detached {
2933 let filePaths = self . getFileURLs ( at: url)
@@ -33,16 +37,6 @@ extension WorkspaceDocument.SearchState {
3337 // Batch our progress updates
3438 var pendingProgress : Double ?
3539
36- func updateProgress( _ progress: Double ) async {
37- await MainActor . run {
38- self . indexStatus = . indexing( progress: progress)
39- self . workspace. activityManager. update (
40- id: activity. id,
41- percentage: progress
42- )
43- }
44- }
45-
4640 for await (file, index) in AsyncFileIterator ( fileURLs: filePaths) {
4741 _ = await asyncController. addText ( files: [ file] , flushWhenComplete: false )
4842 let progress = Double ( index) / Double( filePaths. count)
@@ -54,7 +48,7 @@ extension WorkspaceDocument.SearchState {
5448
5549 // Only update UI every 100ms
5650 if index == filePaths. count - 1 || pendingProgress != nil {
57- await updateProgress ( progress)
51+ continuation . yield ( progress)
5852 pendingProgress = nil
5953 }
6054 }
@@ -77,6 +71,25 @@ extension WorkspaceDocument.SearchState {
7771 }
7872 }
7973
74+ /// Monitors a progress stream from ``addProjectToIndex()`` and updates ``indexStatus`` and the workspace's activity
75+ /// manager accordingly.
76+ ///
77+ /// Without this, updates can come too fast for `Combine` to handle and can cause crashes.
78+ ///
79+ /// - Parameters:
80+ /// - stream: The stream to monitor for progress updates, in %.
81+ /// - activityId: The activity ID that's being monitored
82+ @MainActor
83+ private func monitorProgressStream( _ stream: AsyncStream < Double > , activityId: String ) async {
84+ for await progressUpdate in stream. debounce ( for: . milliseconds( 10 ) ) {
85+ self . indexStatus = . indexing( progress: progressUpdate)
86+ self . workspace. activityManager. update (
87+ id: activityId,
88+ percentage: progressUpdate
89+ )
90+ }
91+ }
92+
8093 /// Retrieves an array of file URLs within the specified directory URL.
8194 ///
8295 /// - Parameter url: The URL of the directory to search for files.
0 commit comments