import { buildFindings, createFileRecord } from "./finding-engine.js"; import { extractReferencesFromValue } from "./reference-extractor.js"; import { createFileLocator } from "./path-utils.js"; export async function analyzeStorage({ listFiles, listSources, onProgress, i18n }={}) { const files = []; let fileCount = 0; let sourceCount = 0; let referenceCount = 0; onProgress?.({ phase: "files", label: format(i18n, "KSA.Progress.ScanFiles"), files: 0, sources: 0, references: 0 }); for await (const entry of listFiles()) { files.push(createFileRecord(createFileLocator(entry.storage, entry.path), entry.size ?? null)); fileCount += 1; if ((fileCount % 100) === 0) { onProgress?.({ phase: "files", label: format(i18n, "KSA.Progress.ScanFiles"), files: fileCount, sources: sourceCount, references: referenceCount }); await yieldToUI(); } } const references = []; onProgress?.({ phase: "sources", label: format(i18n, "KSA.Progress.ReadReferences"), files: fileCount, sources: 0, references: 0 }); for await (const source of listSources()) { sourceCount += 1; const extracted = extractReferencesFromValue(source.value, { sourceType: source.sourceType, sourceScope: source.sourceScope, sourceLabel: source.sourceLabel, sourceName: source.sourceName, sourceUuid: source.sourceUuid, resolveSourceTrail: source.resolveSourceTrail }); references.push(...extracted); referenceCount += extracted.length; if ((sourceCount % 50) === 0) { onProgress?.({ phase: "sources", label: format(i18n, "KSA.Progress.ReadReferences"), files: fileCount, sources: sourceCount, references: referenceCount, currentSource: source.sourceLabel }); await yieldToUI(); } } onProgress?.({ phase: "findings", label: format(i18n, "KSA.Progress.ClassifyFindings"), files: fileCount, sources: sourceCount, references: referenceCount }); const findings = buildFindings({ files, references, i18n }); onProgress?.({ phase: "done", label: format(i18n, "KSA.Progress.Completed"), files: fileCount, sources: sourceCount, references: referenceCount, findings: findings.length }); return { files, references, findings }; } async function yieldToUI() { await new Promise(resolve => setTimeout(resolve, 0)); } function format(i18n, key, data = {}) { return i18n?.format?.(key, data) ?? key; }