Merge current main into PR 1039

This commit is contained in:
vorotamoroz
2026-08-09 08:45:16 +00:00
1036 changed files with 87150 additions and 45505 deletions
@@ -1,6 +1,6 @@
import type { FilePath, UXFileInfoStub, UXInternalFileInfoStub } from "@lib/common/types";
import type { FileEventItem } from "@lib/common/types";
import type { IStorageEventManagerAdapter } from "@lib/managers/adapters";
import type { FilePath, UXFileInfoStub, UXInternalFileInfoStub } from "@vrtmrz/livesync-commonlib/compat/common/types";
import type { FileEventItem } from "@vrtmrz/livesync-commonlib/compat/common/types";
import type { IStorageEventManagerAdapter } from "@vrtmrz/livesync-commonlib/compat/managers/adapters";
import type {
IStorageEventTypeGuardAdapter,
IStorageEventPersistenceAdapter,
@@ -8,12 +8,13 @@ import type {
IStorageEventStatusAdapter,
IStorageEventConverterAdapter,
IStorageEventWatchHandlers,
} from "@lib/managers/adapters";
import type { FileEventItemSentinel } from "@lib/managers/StorageEventManager";
} from "@vrtmrz/livesync-commonlib/compat/managers/adapters";
import type { FileEventItemSentinel } from "@vrtmrz/livesync-commonlib/compat/managers/StorageEventManager";
import type { NodeFile, NodeFolder } from "@/apps/cli/adapters/NodeTypes";
import { watch as chokidarWatch, type FSWatcher } from "chokidar";
import type { IgnoreRules } from "@/apps/cli/serviceModules/IgnoreRules";
import { fsPromises as fs, path, type Stats } from "@/apps/cli/node-compat";
import { fsPromises as fs, path, type Stats } from "@vrtmrz/livesync-commonlib/node";
import type { CliDiagnosticReporter } from "@/apps/cli/cliOutput";
/**
* CLI-specific type guard adapter
@@ -45,7 +46,10 @@ class CLITypeGuardAdapter implements IStorageEventTypeGuardAdapter<NodeFile, Nod
class CLIPersistenceAdapter implements IStorageEventPersistenceAdapter {
private snapshotPath: string;
constructor(basePath: string) {
constructor(
basePath: string,
private reportDiagnostic: CliDiagnosticReporter = () => undefined
) {
this.snapshotPath = path.join(basePath, ".livesync-snapshot.json");
}
@@ -53,14 +57,14 @@ class CLIPersistenceAdapter implements IStorageEventPersistenceAdapter {
try {
await fs.writeFile(this.snapshotPath, JSON.stringify(snapshot, null, 2), "utf-8");
} catch (error) {
console.error("Failed to save snapshot:", error);
this.reportDiagnostic("Failed to save snapshot:", error);
}
}
async loadSnapshot(): Promise<(FileEventItem | FileEventItemSentinel)[] | null> {
try {
const content = await fs.readFile(this.snapshotPath, "utf-8");
return JSON.parse(content);
return JSON.parse(content) as (FileEventItem | FileEventItemSentinel)[];
} catch {
return null;
}
@@ -109,7 +113,8 @@ class CLIWatchAdapter implements IStorageEventWatchAdapter {
constructor(
private basePath: string,
private ignoreRules?: IgnoreRules,
private watchEnabled: boolean = false
private watchEnabled: boolean = false,
private reportDiagnostic: CliDiagnosticReporter = () => undefined
) {}
private _toNodeFile(filePath: string, stats: Stats | undefined): NodeFile {
@@ -182,8 +187,8 @@ class CLIWatchAdapter implements IStorageEventWatchAdapter {
});
watcher.on("error", (err) => {
console.error("[CLIWatchAdapter] Fatal watcher error — file watching stopped:", err);
console.error("[CLIWatchAdapter] Exiting for systemd restart.");
this.reportDiagnostic("[CLIWatchAdapter] Fatal watcher error — file watching stopped:", err);
this.reportDiagnostic("[CLIWatchAdapter] Exiting for systemd restart.");
void watcher.close();
this._watcher = undefined;
// Use exit(1) rather than SIGTERM so systemd Restart=on-failure engages.
@@ -212,10 +217,15 @@ export class CLIStorageEventManagerAdapter implements IStorageEventManagerAdapte
readonly status: CLIStatusAdapter;
readonly converter: CLIConverterAdapter;
constructor(basePath: string, ignoreRules?: IgnoreRules, watchEnabled: boolean = false) {
constructor(
basePath: string,
ignoreRules?: IgnoreRules,
watchEnabled: boolean = false,
reportDiagnostic: CliDiagnosticReporter = () => undefined
) {
this.typeGuard = new CLITypeGuardAdapter();
this.persistence = new CLIPersistenceAdapter(basePath);
this.watch = new CLIWatchAdapter(basePath, ignoreRules, watchEnabled);
this.persistence = new CLIPersistenceAdapter(basePath, reportDiagnostic);
this.watch = new CLIWatchAdapter(basePath, ignoreRules, watchEnabled, reportDiagnostic);
this.status = new CLIStatusAdapter();
this.converter = new CLIConverterAdapter();
}