Stop exposing Syncer from SyncClient

This commit is contained in:
Andras Schmelczer 2025-03-22 13:48:01 +00:00
commit 2722f7c7fc
No known key found for this signature in database
GPG key ID: FC8F2C3D3D1A718C
11 changed files with 84 additions and 55 deletions

View file

@ -9,7 +9,7 @@ export class ObsidianFileEventHandler {
if (file instanceof TFile) { if (file instanceof TFile) {
this.client.logger.info(`File created: ${file.path}`); this.client.logger.info(`File created: ${file.path}`);
await this.client.syncer.syncLocallyCreatedFile(file.path); await this.client.syncLocallyCreatedFile(file.path);
} else { } else {
this.client.logger.debug(`Folder created: ${file.path}, ignored`); this.client.logger.debug(`Folder created: ${file.path}, ignored`);
} }
@ -19,7 +19,7 @@ export class ObsidianFileEventHandler {
if (file instanceof TFile) { if (file instanceof TFile) {
this.client.logger.info(`File deleted: ${file.path}`); this.client.logger.info(`File deleted: ${file.path}`);
await this.client.syncer.syncLocallyDeletedFile(file.path); await this.client.syncLocallyDeletedFile(file.path);
} else { } else {
this.client.logger.debug(`Folder deleted: ${file.path}, ignored`); this.client.logger.debug(`Folder deleted: ${file.path}, ignored`);
} }
@ -29,7 +29,7 @@ export class ObsidianFileEventHandler {
if (file instanceof TFile) { if (file instanceof TFile) {
this.client.logger.info(`File renamed: ${oldPath} -> ${file.path}`); this.client.logger.info(`File renamed: ${oldPath} -> ${file.path}`);
await this.client.syncer.syncLocallyUpdatedFile({ await this.client.syncLocallyUpdatedFile({
oldPath, oldPath,
relativePath: file.path relativePath: file.path
}); });
@ -48,7 +48,7 @@ export class ObsidianFileEventHandler {
this.client.logger.info(`File modified: ${file.path}`); this.client.logger.info(`File modified: ${file.path}`);
await this.client.syncer.syncLocallyUpdatedFile({ await this.client.syncLocallyUpdatedFile({
relativePath: file.path relativePath: file.path
}); });
} else { } else {

View file

@ -33,7 +33,7 @@ export class SyncSettingsTab extends PluginSettingTab {
this.statusDescription = statusDescription; this.statusDescription = statusDescription;
this.editedVaultName = this.syncClient.getSettings().vaultName; this.editedVaultName = this.syncClient.getSettings().vaultName;
this.syncClient.addOnSettingsChangeHandlers( this.syncClient.addOnSettingsChangeListener(
(newSettings, oldSettings) => { (newSettings, oldSettings) => {
if (newSettings.vaultName !== oldSettings.vaultName) { if (newSettings.vaultName !== oldSettings.vaultName) {
this.editedVaultName = newSettings.vaultName; this.editedVaultName = newSettings.vaultName;

View file

@ -17,14 +17,14 @@ export class StatusBar {
this.updateStatus(); this.updateStatus();
}); });
this.syncClient.syncer.addRemainingOperationsListener( this.syncClient.addRemainingSyncOperationsListener(
(remainingOperations) => { (remainingOperations) => {
this.lastRemaining = remainingOperations; this.lastRemaining = remainingOperations;
this.updateStatus(); this.updateStatus();
} }
); );
this.syncClient.addOnSettingsChangeHandlers(() => { this.syncClient.addOnSettingsChangeListener(() => {
this.updateStatus(); this.updateStatus();
}); });
} }

View file

@ -19,14 +19,14 @@ export class StatusDescription {
this.updateDescription(); this.updateDescription();
}); });
this.syncClient.syncer.addRemainingOperationsListener( this.syncClient.addRemainingSyncOperationsListener(
(remainingOperations) => { (remainingOperations) => {
this.lastRemaining = remainingOperations; this.lastRemaining = remainingOperations;
this.updateDescription(); this.updateDescription();
} }
); );
this.syncClient.addOnSettingsChangeHandlers(() => { this.syncClient.addOnSettingsChangeListener(() => {
void this.updateConnectionState(); void this.updateConnectionState();
}); });
} }

View file

@ -1,19 +1,15 @@
export { export {
SyncHistory,
SyncType, SyncType,
SyncSource, SyncSource,
SyncStatus, SyncStatus,
type HistoryStats, type HistoryStats,
type HistoryEntry type HistoryEntry
} from "./tracing/sync-history"; } from "./tracing/sync-history";
export { Logger, LogLevel, LogLine } from "./tracing/logger"; 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 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 { RelativePath } from "./persistence/database";
export type { FileSystemOperations } from "./file-operations/filesystem-operations"; export type { FileSystemOperations } from "./file-operations/filesystem-operations";
export type { PersistenceProvider } from "./persistence/persistence"; export type { PersistenceProvider } from "./persistence/persistence";
export { SyncClient } from "./sync-client";

View file

@ -48,7 +48,7 @@ export class Settings {
return this.settings; return this.settings;
} }
public addOnSettingsChangeHandlers( public addOnSettingsChangeListener(
handler: (settings: SyncSettings, oldSettings: SyncSettings) => void handler: (settings: SyncSettings, oldSettings: SyncSettings) => void
): void { ): void {
this.onSettingsChangeHandlers.push(handler); this.onSettingsChangeHandlers.push(handler);

View file

@ -17,7 +17,7 @@ export class ConnectionStatus {
[this.until, this.resolveUntil, this.rejectUntil] = [this.until, this.resolveUntil, this.rejectUntil] =
createPromise<symbol>(); createPromise<symbol>();
settings.addOnSettingsChangeHandlers((newSettings, oldSettings) => { settings.addOnSettingsChangeListener((newSettings, oldSettings) => {
if (oldSettings.isSyncEnabled != newSettings.isSyncEnabled) { if (oldSettings.isSyncEnabled != newSettings.isSyncEnabled) {
this.canFetch = newSettings.isSyncEnabled; this.canFetch = newSettings.isSyncEnabled;
this.resolveUntil(ConnectionStatus.UNTIL_RESOLUTION); this.resolveUntil(ConnectionStatus.UNTIL_RESOLUTION);

View file

@ -27,7 +27,7 @@ export class SyncService {
) { ) {
this.createClient(this.settings.getSettings().remoteUri); this.createClient(this.settings.getSettings().remoteUri);
settings.addOnSettingsChangeHandlers((newSettings, oldSettings) => { settings.addOnSettingsChangeListener((newSettings, oldSettings) => {
if (newSettings.remoteUri === oldSettings.remoteUri) { if (newSettings.remoteUri === oldSettings.remoteUri) {
return; return;
} }

View file

@ -4,7 +4,7 @@ import type { PersistenceProvider } from "./persistence/persistence";
import type { HistoryEntry, HistoryStats } from "./tracing/sync-history"; import type { HistoryEntry, HistoryStats } from "./tracing/sync-history";
import { SyncHistory } from "./tracing/sync-history"; import { SyncHistory } from "./tracing/sync-history";
import { Logger } from "./tracing/logger"; import { Logger } from "./tracing/logger";
import type { StoredDatabase } from "./persistence/database"; import type { RelativePath, StoredDatabase } from "./persistence/database";
import { Database } from "./persistence/database"; import { Database } from "./persistence/database";
import type { SyncSettings } from "./persistence/settings"; import type { SyncSettings } from "./persistence/settings";
import { Settings } from "./persistence/settings"; import { Settings } from "./persistence/settings";
@ -29,10 +29,6 @@ export class SyncClient {
private readonly _connectionStatus: ConnectionStatus private readonly _connectionStatus: ConnectionStatus
) {} ) {}
public get syncer(): Syncer {
return this._syncer;
}
public get logger(): Logger { public get logger(): Logger {
return this._logger; return this._logger;
} }
@ -58,7 +54,7 @@ export class SyncClient {
nativeLineEndings?: string; nativeLineEndings?: string;
}): Promise<SyncClient> { }): Promise<SyncClient> {
const logger = new Logger(); const logger = new Logger();
logger.info("Starting SyncClient"); logger.info("Initialising SyncClient");
const history = new SyncHistory(logger); const history = new SyncHistory(logger);
@ -112,25 +108,6 @@ export class SyncClient {
connectionStatus 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"); logger.info("SyncClient initialised");
return client; return client;
@ -151,6 +128,27 @@ export class SyncClient {
} }
public async start(): Promise<void> { public async start(): Promise<void> {
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(); await this._syncer.scheduleSyncForOfflineChanges();
this.setRemoteEventListener( this.setRemoteEventListener(
@ -163,6 +161,12 @@ export class SyncClient {
this.unsetRemoteEventListener(); this.unsetRemoteEventListener();
} }
public async waitAndStop(): Promise<void> {
await this._syncer.waitForSyncQueue();
await this._syncer.applyRemoteChangesLocally();
this.stop();
}
/// Wait for the in-flight operations to finish, reset all tracking, /// Wait for the in-flight operations to finish, reset all tracking,
/// and the local database but retain the settings. /// and the local database but retain the settings.
/// The SyncClient can be used again after calling this method. /// The SyncClient can be used again after calling this method.
@ -187,10 +191,41 @@ export class SyncClient {
await this._settings.setSetting(key, value); await this._settings.setSetting(key, value);
} }
public addOnSettingsChangeHandlers( public addOnSettingsChangeListener(
handler: (settings: SyncSettings, oldSettings: SyncSettings) => void handler: (settings: SyncSettings, oldSettings: SyncSettings) => void
): 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<void> {
return this._syncer.syncLocallyCreatedFile(relativePath);
}
public async syncLocallyDeletedFile(
relativePath: RelativePath
): Promise<void> {
return this._syncer.syncLocallyDeletedFile(relativePath);
}
public async syncLocallyUpdatedFile({
oldPath,
relativePath
}: {
oldPath?: RelativePath;
relativePath: RelativePath;
}): Promise<void> {
return this._syncer.syncLocallyUpdatedFile({
oldPath,
relativePath
});
} }
private setRemoteEventListener(intervalMs: number): void { private setRemoteEventListener(intervalMs: number): void {

View file

@ -134,9 +134,7 @@ export class MockAgent extends MockClient {
public async finish(): Promise<void> { public async finish(): Promise<void> {
await this.client.setSetting("isSyncEnabled", true); await this.client.setSetting("isSyncEnabled", true);
await Promise.all(this.pendingActions); await Promise.all(this.pendingActions);
this.client.stop(); await this.client.waitAndStop();
await this.client.syncer.waitForSyncQueue();
await this.client.syncer.applyRemoteChangesLocally();
} }
public assertFileSystemsAreConsistent(otherAgent: MockAgent): void { public assertFileSystemsAreConsistent(otherAgent: MockAgent): void {

View file

@ -72,7 +72,7 @@ export class MockClient implements FileSystemOperations {
this.localFiles.set(path, newContent); this.localFiles.set(path, newContent);
this.runCallback(() => { this.runCallback(() => {
void this.client.syncer.syncLocallyCreatedFile(path); void this.client.syncLocallyCreatedFile(path);
}); });
} }
@ -114,7 +114,7 @@ export class MockClient implements FileSystemOperations {
); );
this.runCallback(() => { this.runCallback(() => {
void this.client.syncer.syncLocallyUpdatedFile({ void this.client.syncLocallyUpdatedFile({
relativePath: path relativePath: path
}); });
}); });
@ -132,11 +132,11 @@ export class MockClient implements FileSystemOperations {
this.runCallback(() => { this.runCallback(() => {
if (hasExisted) { if (hasExisted) {
void this.client.syncer.syncLocallyUpdatedFile({ void this.client.syncLocallyUpdatedFile({
relativePath: path relativePath: path
}); });
} else { } 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.localFiles.delete(path);
this.runCallback(() => { this.runCallback(() => {
void this.client.syncer.syncLocallyDeletedFile(path); void this.client.syncLocallyDeletedFile(path);
}); });
} }
@ -170,7 +170,7 @@ export class MockClient implements FileSystemOperations {
); );
this.runCallback(() => { this.runCallback(() => {
void this.client.syncer.syncLocallyUpdatedFile({ void this.client.syncLocallyUpdatedFile({
oldPath, oldPath,
relativePath: newPath relativePath: newPath
}); });