From 2722f7c7fcb15398b5a57943491826fc34dd93f5 Mon Sep 17 00:00:00 2001 From: Andras Schmelczer Date: Sat, 22 Mar 2025 13:48:01 +0000 Subject: [PATCH] Stop exposing Syncer from SyncClient --- .../src/obisidan-event-handler.ts | 8 +- .../obsidian-plugin/src/views/settings-tab.ts | 2 +- .../obsidian-plugin/src/views/status-bar.ts | 4 +- .../src/views/status-description.ts | 4 +- frontend/sync-client/src/index.ts | 10 +-- .../sync-client/src/persistence/settings.ts | 2 +- .../src/services/connection-status.ts | 2 +- .../sync-client/src/services/sync-service.ts | 2 +- frontend/sync-client/src/sync-client.ts | 89 +++++++++++++------ frontend/test-client/src/agent/mock-agent.ts | 4 +- frontend/test-client/src/agent/mock-client.ts | 12 +-- 11 files changed, 84 insertions(+), 55 deletions(-) diff --git a/frontend/obsidian-plugin/src/obisidan-event-handler.ts b/frontend/obsidian-plugin/src/obisidan-event-handler.ts index 9fb5dba..df0d826 100644 --- a/frontend/obsidian-plugin/src/obisidan-event-handler.ts +++ b/frontend/obsidian-plugin/src/obisidan-event-handler.ts @@ -9,7 +9,7 @@ export class ObsidianFileEventHandler { if (file instanceof TFile) { this.client.logger.info(`File created: ${file.path}`); - await this.client.syncer.syncLocallyCreatedFile(file.path); + await this.client.syncLocallyCreatedFile(file.path); } else { this.client.logger.debug(`Folder created: ${file.path}, ignored`); } @@ -19,7 +19,7 @@ export class ObsidianFileEventHandler { if (file instanceof TFile) { this.client.logger.info(`File deleted: ${file.path}`); - await this.client.syncer.syncLocallyDeletedFile(file.path); + await this.client.syncLocallyDeletedFile(file.path); } else { this.client.logger.debug(`Folder deleted: ${file.path}, ignored`); } @@ -29,7 +29,7 @@ export class ObsidianFileEventHandler { if (file instanceof TFile) { this.client.logger.info(`File renamed: ${oldPath} -> ${file.path}`); - await this.client.syncer.syncLocallyUpdatedFile({ + await this.client.syncLocallyUpdatedFile({ oldPath, relativePath: file.path }); @@ -48,7 +48,7 @@ export class ObsidianFileEventHandler { this.client.logger.info(`File modified: ${file.path}`); - await this.client.syncer.syncLocallyUpdatedFile({ + await this.client.syncLocallyUpdatedFile({ relativePath: file.path }); } else { diff --git a/frontend/obsidian-plugin/src/views/settings-tab.ts b/frontend/obsidian-plugin/src/views/settings-tab.ts index 79f3baf..29e0b82 100644 --- a/frontend/obsidian-plugin/src/views/settings-tab.ts +++ b/frontend/obsidian-plugin/src/views/settings-tab.ts @@ -33,7 +33,7 @@ export class SyncSettingsTab extends PluginSettingTab { this.statusDescription = statusDescription; this.editedVaultName = this.syncClient.getSettings().vaultName; - this.syncClient.addOnSettingsChangeHandlers( + this.syncClient.addOnSettingsChangeListener( (newSettings, oldSettings) => { if (newSettings.vaultName !== oldSettings.vaultName) { this.editedVaultName = newSettings.vaultName; diff --git a/frontend/obsidian-plugin/src/views/status-bar.ts b/frontend/obsidian-plugin/src/views/status-bar.ts index 6a55f3d..84e7586 100644 --- a/frontend/obsidian-plugin/src/views/status-bar.ts +++ b/frontend/obsidian-plugin/src/views/status-bar.ts @@ -17,14 +17,14 @@ export class StatusBar { this.updateStatus(); }); - this.syncClient.syncer.addRemainingOperationsListener( + this.syncClient.addRemainingSyncOperationsListener( (remainingOperations) => { this.lastRemaining = remainingOperations; this.updateStatus(); } ); - this.syncClient.addOnSettingsChangeHandlers(() => { + this.syncClient.addOnSettingsChangeListener(() => { this.updateStatus(); }); } diff --git a/frontend/obsidian-plugin/src/views/status-description.ts b/frontend/obsidian-plugin/src/views/status-description.ts index e992326..c696c53 100644 --- a/frontend/obsidian-plugin/src/views/status-description.ts +++ b/frontend/obsidian-plugin/src/views/status-description.ts @@ -19,14 +19,14 @@ export class StatusDescription { this.updateDescription(); }); - this.syncClient.syncer.addRemainingOperationsListener( + this.syncClient.addRemainingSyncOperationsListener( (remainingOperations) => { this.lastRemaining = remainingOperations; this.updateDescription(); } ); - this.syncClient.addOnSettingsChangeHandlers(() => { + this.syncClient.addOnSettingsChangeListener(() => { void this.updateConnectionState(); }); } diff --git a/frontend/sync-client/src/index.ts b/frontend/sync-client/src/index.ts index 82b6bd8..9308c06 100644 --- a/frontend/sync-client/src/index.ts +++ b/frontend/sync-client/src/index.ts @@ -1,19 +1,15 @@ export { - SyncHistory, SyncType, SyncSource, SyncStatus, type HistoryStats, type HistoryEntry } from "./tracing/sync-history"; - export { Logger, LogLevel, LogLine } from "./tracing/logger"; - -export { SyncClient } from "./sync-client"; -export { Syncer } from "./sync-operations/syncer"; export type { CheckConnectionResult } from "./services/sync-service"; -export { Settings, type SyncSettings } from "./persistence/settings"; - +export { type SyncSettings } from "./persistence/settings"; export type { RelativePath } from "./persistence/database"; export type { FileSystemOperations } from "./file-operations/filesystem-operations"; export type { PersistenceProvider } from "./persistence/persistence"; + +export { SyncClient } from "./sync-client"; diff --git a/frontend/sync-client/src/persistence/settings.ts b/frontend/sync-client/src/persistence/settings.ts index 1848cb6..8233ddf 100644 --- a/frontend/sync-client/src/persistence/settings.ts +++ b/frontend/sync-client/src/persistence/settings.ts @@ -48,7 +48,7 @@ export class Settings { return this.settings; } - public addOnSettingsChangeHandlers( + public addOnSettingsChangeListener( handler: (settings: SyncSettings, oldSettings: SyncSettings) => void ): void { this.onSettingsChangeHandlers.push(handler); diff --git a/frontend/sync-client/src/services/connection-status.ts b/frontend/sync-client/src/services/connection-status.ts index 753af36..0ee0d5a 100644 --- a/frontend/sync-client/src/services/connection-status.ts +++ b/frontend/sync-client/src/services/connection-status.ts @@ -17,7 +17,7 @@ export class ConnectionStatus { [this.until, this.resolveUntil, this.rejectUntil] = createPromise(); - settings.addOnSettingsChangeHandlers((newSettings, oldSettings) => { + settings.addOnSettingsChangeListener((newSettings, oldSettings) => { if (oldSettings.isSyncEnabled != newSettings.isSyncEnabled) { this.canFetch = newSettings.isSyncEnabled; this.resolveUntil(ConnectionStatus.UNTIL_RESOLUTION); diff --git a/frontend/sync-client/src/services/sync-service.ts b/frontend/sync-client/src/services/sync-service.ts index 1b52751..53cb4d5 100644 --- a/frontend/sync-client/src/services/sync-service.ts +++ b/frontend/sync-client/src/services/sync-service.ts @@ -27,7 +27,7 @@ export class SyncService { ) { this.createClient(this.settings.getSettings().remoteUri); - settings.addOnSettingsChangeHandlers((newSettings, oldSettings) => { + settings.addOnSettingsChangeListener((newSettings, oldSettings) => { if (newSettings.remoteUri === oldSettings.remoteUri) { return; } diff --git a/frontend/sync-client/src/sync-client.ts b/frontend/sync-client/src/sync-client.ts index 8e139f7..39970e4 100644 --- a/frontend/sync-client/src/sync-client.ts +++ b/frontend/sync-client/src/sync-client.ts @@ -4,7 +4,7 @@ import type { PersistenceProvider } from "./persistence/persistence"; import type { HistoryEntry, HistoryStats } from "./tracing/sync-history"; import { SyncHistory } from "./tracing/sync-history"; import { Logger } from "./tracing/logger"; -import type { StoredDatabase } from "./persistence/database"; +import type { RelativePath, StoredDatabase } from "./persistence/database"; import { Database } from "./persistence/database"; import type { SyncSettings } from "./persistence/settings"; import { Settings } from "./persistence/settings"; @@ -29,10 +29,6 @@ export class SyncClient { private readonly _connectionStatus: ConnectionStatus ) {} - public get syncer(): Syncer { - return this._syncer; - } - public get logger(): Logger { return this._logger; } @@ -58,7 +54,7 @@ export class SyncClient { nativeLineEndings?: string; }): Promise { const logger = new Logger(); - logger.info("Starting SyncClient"); + logger.info("Initialising SyncClient"); const history = new SyncHistory(logger); @@ -112,25 +108,6 @@ export class SyncClient { connectionStatus ); - settings.addOnSettingsChangeHandlers((newSettings, oldSettings) => { - if ( - newSettings.fetchChangesUpdateIntervalMs !== - oldSettings.fetchChangesUpdateIntervalMs - ) { - client.setRemoteEventListener( - newSettings.fetchChangesUpdateIntervalMs - ); - } - - if ( - newSettings.vaultName !== oldSettings.vaultName || - newSettings.token !== oldSettings.token || - newSettings.remoteUri !== oldSettings.remoteUri - ) { - void client.reset(); - } - }); - logger.info("SyncClient initialised"); return client; @@ -151,6 +128,27 @@ export class SyncClient { } public async start(): Promise { + this._settings.addOnSettingsChangeListener( + (newSettings, oldSettings) => { + if ( + newSettings.fetchChangesUpdateIntervalMs !== + oldSettings.fetchChangesUpdateIntervalMs + ) { + this.setRemoteEventListener( + newSettings.fetchChangesUpdateIntervalMs + ); + } + + if ( + newSettings.vaultName !== oldSettings.vaultName || + newSettings.token !== oldSettings.token || + newSettings.remoteUri !== oldSettings.remoteUri + ) { + void this.reset(); + } + } + ); + await this._syncer.scheduleSyncForOfflineChanges(); this.setRemoteEventListener( @@ -163,6 +161,12 @@ export class SyncClient { this.unsetRemoteEventListener(); } + public async waitAndStop(): Promise { + await this._syncer.waitForSyncQueue(); + await this._syncer.applyRemoteChangesLocally(); + this.stop(); + } + /// Wait for the in-flight operations to finish, reset all tracking, /// and the local database but retain the settings. /// The SyncClient can be used again after calling this method. @@ -187,10 +191,41 @@ export class SyncClient { await this._settings.setSetting(key, value); } - public addOnSettingsChangeHandlers( + public addOnSettingsChangeListener( handler: (settings: SyncSettings, oldSettings: SyncSettings) => void ): void { - this._settings.addOnSettingsChangeHandlers(handler); + this._settings.addOnSettingsChangeListener(handler); + } + + public addRemainingSyncOperationsListener( + listener: (remainingOperations: number) => void + ): void { + this._syncer.addRemainingOperationsListener(listener); + } + + public async syncLocallyCreatedFile( + relativePath: RelativePath + ): Promise { + return this._syncer.syncLocallyCreatedFile(relativePath); + } + + public async syncLocallyDeletedFile( + relativePath: RelativePath + ): Promise { + return this._syncer.syncLocallyDeletedFile(relativePath); + } + + public async syncLocallyUpdatedFile({ + oldPath, + relativePath + }: { + oldPath?: RelativePath; + relativePath: RelativePath; + }): Promise { + return this._syncer.syncLocallyUpdatedFile({ + oldPath, + relativePath + }); } private setRemoteEventListener(intervalMs: number): void { diff --git a/frontend/test-client/src/agent/mock-agent.ts b/frontend/test-client/src/agent/mock-agent.ts index 23fcd09..3f7b16d 100644 --- a/frontend/test-client/src/agent/mock-agent.ts +++ b/frontend/test-client/src/agent/mock-agent.ts @@ -134,9 +134,7 @@ export class MockAgent extends MockClient { public async finish(): Promise { await this.client.setSetting("isSyncEnabled", true); await Promise.all(this.pendingActions); - this.client.stop(); - await this.client.syncer.waitForSyncQueue(); - await this.client.syncer.applyRemoteChangesLocally(); + await this.client.waitAndStop(); } public assertFileSystemsAreConsistent(otherAgent: MockAgent): void { diff --git a/frontend/test-client/src/agent/mock-client.ts b/frontend/test-client/src/agent/mock-client.ts index 9f3483c..793c377 100644 --- a/frontend/test-client/src/agent/mock-client.ts +++ b/frontend/test-client/src/agent/mock-client.ts @@ -72,7 +72,7 @@ export class MockClient implements FileSystemOperations { this.localFiles.set(path, newContent); this.runCallback(() => { - void this.client.syncer.syncLocallyCreatedFile(path); + void this.client.syncLocallyCreatedFile(path); }); } @@ -114,7 +114,7 @@ export class MockClient implements FileSystemOperations { ); this.runCallback(() => { - void this.client.syncer.syncLocallyUpdatedFile({ + void this.client.syncLocallyUpdatedFile({ relativePath: path }); }); @@ -132,11 +132,11 @@ export class MockClient implements FileSystemOperations { this.runCallback(() => { if (hasExisted) { - void this.client.syncer.syncLocallyUpdatedFile({ + void this.client.syncLocallyUpdatedFile({ relativePath: path }); } else { - void this.client.syncer.syncLocallyCreatedFile(path); + void this.client.syncLocallyCreatedFile(path); } }); } @@ -148,7 +148,7 @@ export class MockClient implements FileSystemOperations { this.localFiles.delete(path); this.runCallback(() => { - void this.client.syncer.syncLocallyDeletedFile(path); + void this.client.syncLocallyDeletedFile(path); }); } @@ -170,7 +170,7 @@ export class MockClient implements FileSystemOperations { ); this.runCallback(() => { - void this.client.syncer.syncLocallyUpdatedFile({ + void this.client.syncLocallyUpdatedFile({ oldPath, relativePath: newPath });