From f73b5ecb7162cfb29a007400cd8101674e156fdc Mon Sep 17 00:00:00 2001 From: Andras Schmelczer Date: Sat, 22 Feb 2025 17:17:07 +0000 Subject: [PATCH] Fixes & refactor --- .../src/file-operations/file-operations.ts | 2 +- frontend/sync-client/src/sync-client.ts | 1 + .../sync-client/src/sync-operations/syncer.ts | 81 +++++++++---------- .../utils/find-matching-file-based-on-hash.ts | 13 +++ 4 files changed, 54 insertions(+), 43 deletions(-) create mode 100644 frontend/sync-client/src/utils/find-matching-file-based-on-hash.ts diff --git a/frontend/sync-client/src/file-operations/file-operations.ts b/frontend/sync-client/src/file-operations/file-operations.ts index fb62c72..ec9ef1a 100644 --- a/frontend/sync-client/src/file-operations/file-operations.ts +++ b/frontend/sync-client/src/file-operations/file-operations.ts @@ -120,7 +120,7 @@ export class FileOperations { } public async remove(path: RelativePath): Promise { - this.logger.debug(`Removing file: ${path}`); + this.logger.debug(`Deleting file: ${path}`); return this.fs.delete(path); } diff --git a/frontend/sync-client/src/sync-client.ts b/frontend/sync-client/src/sync-client.ts index 1d3b33f..5e7d8f2 100644 --- a/frontend/sync-client/src/sync-client.ts +++ b/frontend/sync-client/src/sync-client.ts @@ -135,6 +135,7 @@ export class SyncClient { public async reset(): Promise { await this._syncer.reset(); this._history.reset(); + await this._database.resetSyncState(); this.logger.reset(); } diff --git a/frontend/sync-client/src/sync-operations/syncer.ts b/frontend/sync-client/src/sync-operations/syncer.ts index d73e737..d99eb06 100644 --- a/frontend/sync-client/src/sync-operations/syncer.ts +++ b/frontend/sync-client/src/sync-operations/syncer.ts @@ -15,6 +15,7 @@ import type { components } from "src/services/types"; import { deserialize } from "src/utils/deserialize"; import type { Settings } from "src/persistence/settings"; import { FileOperations } from "src/file-operations/file-operations"; +import { findMatchingFileBasedOnHash } from "src/utils/find-matching-file-based-on-hash"; export class Syncer { private readonly remainingOperationsListeners: (( @@ -74,6 +75,10 @@ export class Syncer { ); } + public waitForSyncQueue(): Promise { + return this.syncQueue.onEmpty(); + } + public async syncLocallyDeletedFile( relativePath: RelativePath ): Promise { @@ -136,11 +141,10 @@ export class Syncer { await this.operations.read(relativePath); const contentHash = hash(contentBytes); - const originalFile = - await this.findMatchingFileBasedOnHash( - contentHash, - locallyDeletedFiles - ); + const originalFile = findMatchingFileBasedOnHash( + contentHash, + locallyDeletedFiles + ); if (originalFile !== undefined) { // `originalFile` hasn't been deleted but it got moved instead locallyDeletedFiles = locallyDeletedFiles.filter( @@ -202,7 +206,8 @@ export class Syncer { return Promise.resolve(); } - return this.internalSyncLocallyDeletedFile(relativePath); + // We're outside of the pqueue, so we need to call the public wrapper + return this.syncLocallyDeletedFile(relativePath); }) ); } @@ -265,8 +270,6 @@ export class Syncer { public async reset(): Promise { this.syncQueue.clear(); await this.syncQueue.onEmpty(); - await this.database.resetSyncState(); - this.history.reset(); this.remainingOperationsListeners.forEach((listener) => { listener(0); }); @@ -388,22 +391,9 @@ export class Syncer { SyncType.UPDATE, SyncSource.PUSH, async () => { - if ( - (await this.operations.getFileSize(relativePath)) / - 1024 / - 1024 > - this.settings.getSettings().maxFileSizeMB - ) { - this.history.addHistoryEntry({ - status: SyncStatus.ERROR, - relativePath, - message: `File size exceeds the maximum file size limit of ${ - this.settings.getSettings().maxFileSizeMB - }MB`, - type: SyncType.CREATE - }); - return; - } + this.logger.debug( + `Renaming? oldPath ${oldPath} relativePath ${relativePath}` + ); const localMetadata = this.database.getDocument( oldPath ?? relativePath @@ -420,9 +410,27 @@ export class Syncer { return; } - throw new Error( - `Document metadata not found for ${relativePath}. This implies a corrupt local database. Consider resetting the plugin's sync history.` + this.logger.debug( + `Document metadata doesn't exist for ${relativePath}, it must have been already deleted` ); + return; + } + + if ( + (await this.operations.getFileSize(relativePath)) / + 1024 / + 1024 > + this.settings.getSettings().maxFileSizeMB + ) { + this.history.addHistoryEntry({ + status: SyncStatus.ERROR, + relativePath, + message: `File size exceeds the maximum file size limit of ${ + this.settings.getSettings().maxFileSizeMB + }MB`, + type: SyncType.CREATE + }); + return; } const contentBytes = @@ -487,7 +495,7 @@ export class Syncer { try { if (response.relativePath != relativePath) { await this.operations.move( - oldPath ?? relativePath, + relativePath, response.relativePath ); } @@ -616,7 +624,7 @@ export class Syncer { status: SyncStatus.SUCCESS, source: SyncSource.PULL, relativePath: remoteVersion.relativePath, - message: `Successfully downloaded remote file which hasn't existed locally`, + message: `Successfully downloaded remote file which hadn't existed locally`, type: SyncType.CREATE }); return; @@ -720,7 +728,9 @@ export class Syncer { ); return; } - this.logger.debug(`Syncing ${relativePath}`); + this.logger.debug( + `Syncing ${relativePath} (${syncSource} - ${syncType})` + ); await waitForDocumentLock(relativePath); try { @@ -752,17 +762,4 @@ export class Syncer { await this.database.setLastSeenUpdateId(responseVaultUpdateId); } } - - private async findMatchingFileBasedOnHash( - contentHash: string, - candidates: [RelativePath, DocumentMetadata][] - ): Promise<[RelativePath, DocumentMetadata] | undefined> { - if (contentHash != EMPTY_HASH) { - return undefined; - } - - return candidates.find( - ([_, document]) => document.hash === contentHash - ); - } } diff --git a/frontend/sync-client/src/utils/find-matching-file-based-on-hash.ts b/frontend/sync-client/src/utils/find-matching-file-based-on-hash.ts new file mode 100644 index 0000000..ecd54c8 --- /dev/null +++ b/frontend/sync-client/src/utils/find-matching-file-based-on-hash.ts @@ -0,0 +1,13 @@ +import { DocumentMetadata, RelativePath } from "src/persistence/database"; +import { EMPTY_HASH } from "./hash"; + +export function findMatchingFileBasedOnHash( + contentHash: string, + candidates: [RelativePath, DocumentMetadata][] +): [RelativePath, DocumentMetadata] | undefined { + if (contentHash != EMPTY_HASH) { + return undefined; + } + + return candidates.find(([_, document]) => document.hash === contentHash); +}