Persist collector state and stabilize download controls

Persist collector packages and disclosure state through validated atomic AppData storage with backup recovery and shutdown synchronization. Align download sidebar metrics with the hidden-extracted presentation scope and keep Start available through temporary Real-Debrid cooldowns while preserving hard account blocks.
This commit is contained in:
Sucukdeluxe
2026-08-26 17:24:07 +02:00
parent 5644ba25da
commit bdcf9e3754
20 changed files with 933 additions and 48 deletions
+19 -1
View File
@@ -76,7 +76,9 @@ import { getRenameLogPath, initRenameLog, shutdownRenameLog } from "./rename-log
import { getDesktopRenameLogPath, initDesktopRenameLogAt, shutdownDesktopRenameLog } from "./desktop-rename-log";
import { buildAccountSummary, buildNotificationSupportPayload, diffAccountSummary, type NotificationSupportPayload } from "./support-data";
import { buildSupportBundle, getSupportBundleDefaultFileName } from "./support-bundle";
import { getTraceConfig, getTraceLogPath, initTraceLog, logTraceEvent, setTraceEnabled, shutdownTraceLog } from "./trace-log";
import { getTraceConfig, getTraceLogPath, initTraceLog, logTraceEvent, setTraceEnabled, shutdownTraceLog } from "./trace-log";
import { CollectorStore } from "./collector-store";
import type { CollectorPersistenceState } from "../shared/collector";
import type { DebugSetupCheckResult, SupportTraceConfig } from "../shared/types";
import { createOnlineBackup, downloadOnlineBackup, uploadOnlineBackup } from "./online-backup";
import { overlayLiveUsageCounters } from "./settings-live-overlay";
@@ -126,6 +128,8 @@ export class AppController {
private storagePaths = createStoragePaths(path.join(app.getPath("userData"), "runtime"));
private collectorStore = new CollectorStore(this.storagePaths.collectorFile);
private notificationOutbox: NotificationOutbox;
private downloadHealthMonitor: DownloadHealthMonitor;
@@ -997,6 +1001,15 @@ export class AppController {
return prepareCollectorText(request);
}
public getCollectorState(): CollectorPersistenceState {
return this.collectorStore.getState();
}
public saveCollectorState(state: CollectorPersistenceState): CollectorPersistenceState {
this.collectorStore.update(state);
return this.collectorStore.getState();
}
public prepareCollectorContainers(filePaths: string[], addedAt: number): Promise<CollectorInspectionResult> {
return prepareCollectorContainers(filePaths, addedAt);
}
@@ -1388,6 +1401,11 @@ export class AppController {
}
stopDebugServer();
abortActiveUpdateDownload();
try {
this.collectorStore?.flushSync();
} catch (error) {
logger.warn(`Linksammler konnte beim Beenden nicht gespeichert werden: ${String(error)}`);
}
cancelPendingAsyncSaves();
this.manager.prepareForShutdown();
if (this.downloadHealthEvaluation) {