Files
orca/src/main/ipc/workspace-cleanup-progress-emitter.ts
T
mirror 34fa2cd5ca
Skill update round trip / roundtrip (false, macos-latest, copy, 1.5.17) (push) Canceled after 0s
Skill update round trip / roundtrip (false, macos-latest, symlink, 1.5.17) (push) Canceled after 0s
Skill update round trip / roundtrip (false, ubuntu-latest, copy, 1.5.17) (push) Canceled after 0s
Skill update round trip / roundtrip (false, ubuntu-latest, symlink, 1.5.17) (push) Canceled after 0s
Skill update round trip / roundtrip (false, ubuntu-latest, symlink, latest) (push) Canceled after 0s
Skill update round trip / roundtrip (false, windows-latest, copy, 1.5.17) (push) Canceled after 0s
Skill update round trip / roundtrip (false, windows-latest, symlink, 1.5.17) (push) Canceled after 0s
Skill update round trip / roundtrip (true, macos-latest, copy, 1.5.17) (push) Canceled after 0s
Skill update round trip / roundtrip (true, macos-latest, symlink, 1.5.17) (push) Canceled after 0s
Skill update round trip / roundtrip (true, ubuntu-latest, copy, 1.5.17) (push) Canceled after 0s
Skill update round trip / roundtrip (true, ubuntu-latest, symlink, 1.5.17) (push) Canceled after 0s
Skill update round trip / roundtrip (true, windows-latest, copy, 1.5.17) (push) Canceled after 0s
Skill update round trip / roundtrip (true, windows-latest, symlink, 1.5.17) (push) Canceled after 0s
source snapshot 2026-09-02
2026-09-02 02:03:16 +08:00

84 lines
2.2 KiB
TypeScript

import type {
WorkspaceCleanupCandidate,
WorkspaceCleanupScanError,
WorkspaceCleanupScanProgress
} from '../../shared/workspace-cleanup'
import { appendWorkspaceCleanupItems } from './workspace-cleanup-scan-primitives'
const WORKSPACE_CLEANUP_PROGRESS_EMIT_INTERVAL_MS = 100
export type WorkspaceCleanupScanOptions = {
onProgress?: (progress: WorkspaceCleanupScanProgress) => void
signal?: AbortSignal
}
export type WorkspaceCleanupProgressEmitter = {
addDiscovered: (count: number) => void
addCandidate: (candidate: WorkspaceCleanupCandidate) => void
addErrors: (errors: WorkspaceCleanupScanError[]) => void
flush: () => void
}
/** Caps renderer projection churn while preserving an immediate final progress state. */
export function createWorkspaceCleanupProgressEmitter(
scanId: string | undefined,
scannedAt: number,
options: WorkspaceCleanupScanOptions
): WorkspaceCleanupProgressEmitter {
const errors: WorkspaceCleanupScanError[] = []
let pendingCandidates: WorkspaceCleanupCandidate[] = []
let totalWorktreeCount = 0
let scannedWorktreeCount = 0
let dirty = false
let emittedInitialDiscovery = false
let timer: NodeJS.Timeout | null = null
const flush = (): void => {
if (!scanId || !dirty) {
return
}
if (timer) {
clearTimeout(timer)
timer = null
}
dirty = false
const candidates = pendingCandidates
pendingCandidates = []
options.onProgress?.({
scanId,
scannedAt,
totalWorktreeCount,
scannedWorktreeCount,
candidates,
errors: [...errors],
candidateMode: 'append'
})
}
const schedule = (): void => {
if (!scanId) {
return
}
dirty = true
timer ??= setTimeout(flush, WORKSPACE_CLEANUP_PROGRESS_EMIT_INTERVAL_MS)
}
return {
addDiscovered: (count) => {
totalWorktreeCount += count
schedule()
if (!emittedInitialDiscovery) {
emittedInitialDiscovery = true
flush()
}
},
addCandidate: (candidate) => {
pendingCandidates.push(candidate)
scannedWorktreeCount += 1
schedule()
},
addErrors: (newErrors) => {
appendWorkspaceCleanupItems(errors, newErrors)
schedule()
},
flush
}
}