Collapse newly imported collector packages

Project disclosure state through stable link URLs so new or moved import content starts collapsed, duplicate-only imports preserve manual state, and enrichment-driven package ID changes retain the existing disclosure state.
This commit is contained in:
Sucukdeluxe
2026-08-26 16:50:40 +02:00
parent 1fe48d9ff8
commit 5644ba25da
3 changed files with 66 additions and 7 deletions
+14 -7
View File
@@ -70,6 +70,7 @@ import {
mergeCollectorEnrichment,
mergeCollectorPackages,
removeCollectorLinks,
reconcileCollectorCollapsedPackageIds,
selectCollectorPackageLinks,
type CollectorWorkspaceFilter
} from "./views/collector/collector-model";
@@ -3596,13 +3597,19 @@ export function App(): ReactElement {
};
const mergeCollectorResult = (result: CollectorInspectionResult, enrichment = false): void => {
setCollectorPackages((current) => {
const merged = enrichment
? mergeCollectorEnrichment(current, result.packages)
: mergeCollectorPackages(current, result.packages);
collectorPackagesRef.current = merged.packages;
return merged.packages;
});
const current = collectorPackagesRef.current;
const merged = enrichment
? mergeCollectorEnrichment(current, result.packages)
: mergeCollectorPackages(current, result.packages);
collectorPackagesRef.current = merged.packages;
setCollectorPackages(merged.packages);
setCollapsedCollectorPackageIds((collapsed) => reconcileCollectorCollapsedPackageIds(
collapsed,
current,
merged.packages,
result.packages,
!enrichment
));
};
const enrichCollectorResult = (packages: CollectorPackage[]): void => {
@@ -186,6 +186,37 @@ export function mergeCollectorEnrichment(current: CollectorPackage[], incoming:
return mergeCollectorPackages(current, retained);
}
export function reconcileCollectorCollapsedPackageIds(
current: Set<string>,
previousPackages: CollectorPackage[],
packages: CollectorPackage[],
incoming: CollectorPackage[],
collapseImported: boolean
): Set<string> {
const incomingUrls = new Set(incoming.flatMap((pkg) => pkg.links.map((link) => collectorUrlKey(link.url))));
const previousPackageByUrl = new Map<string, string>();
const collapsedUrls = new Set<string>();
for (const pkg of previousPackages) {
for (const link of pkg.links) {
const key = collectorUrlKey(link.url);
previousPackageByUrl.set(key, pkg.id);
if (current.has(pkg.id)) collapsedUrls.add(key);
}
}
const next = new Set<string>();
for (const pkg of packages) {
const keys = pkg.links.map((link) => collectorUrlKey(link.url));
const preservesCollapsedState = current.has(pkg.id) || keys.some((key) => collapsedUrls.has(key));
const receivesImportedContent = collapseImported && keys.some((key) => {
if (!incomingUrls.has(key)) return false;
const previousPackageId = previousPackageByUrl.get(key);
return !previousPackageId || previousPackageId !== pkg.id;
});
if (preservesCollapsedState || receivesImportedContent) next.add(pkg.id);
}
return next;
}
export function selectCollectorPackageLinks(current: Set<string>, pkg: CollectorPackage, selected: boolean): Set<string> {
const next = new Set(current);
for (const link of pkg.links) {