Fixes & refactor
This commit is contained in:
parent
e6eedab87d
commit
f73b5ecb71
4 changed files with 54 additions and 43 deletions
|
|
@ -120,7 +120,7 @@ export class FileOperations {
|
||||||
}
|
}
|
||||||
|
|
||||||
public async remove(path: RelativePath): Promise<void> {
|
public async remove(path: RelativePath): Promise<void> {
|
||||||
this.logger.debug(`Removing file: ${path}`);
|
this.logger.debug(`Deleting file: ${path}`);
|
||||||
return this.fs.delete(path);
|
return this.fs.delete(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -135,6 +135,7 @@ export class SyncClient {
|
||||||
public async reset(): Promise<void> {
|
public async reset(): Promise<void> {
|
||||||
await this._syncer.reset();
|
await this._syncer.reset();
|
||||||
this._history.reset();
|
this._history.reset();
|
||||||
|
await this._database.resetSyncState();
|
||||||
this.logger.reset();
|
this.logger.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ import type { components } from "src/services/types";
|
||||||
import { deserialize } from "src/utils/deserialize";
|
import { deserialize } from "src/utils/deserialize";
|
||||||
import type { Settings } from "src/persistence/settings";
|
import type { Settings } from "src/persistence/settings";
|
||||||
import { FileOperations } from "src/file-operations/file-operations";
|
import { FileOperations } from "src/file-operations/file-operations";
|
||||||
|
import { findMatchingFileBasedOnHash } from "src/utils/find-matching-file-based-on-hash";
|
||||||
|
|
||||||
export class Syncer {
|
export class Syncer {
|
||||||
private readonly remainingOperationsListeners: ((
|
private readonly remainingOperationsListeners: ((
|
||||||
|
|
@ -74,6 +75,10 @@ export class Syncer {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public waitForSyncQueue(): Promise<void> {
|
||||||
|
return this.syncQueue.onEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
public async syncLocallyDeletedFile(
|
public async syncLocallyDeletedFile(
|
||||||
relativePath: RelativePath
|
relativePath: RelativePath
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
|
|
@ -136,11 +141,10 @@ export class Syncer {
|
||||||
await this.operations.read(relativePath);
|
await this.operations.read(relativePath);
|
||||||
const contentHash = hash(contentBytes);
|
const contentHash = hash(contentBytes);
|
||||||
|
|
||||||
const originalFile =
|
const originalFile = findMatchingFileBasedOnHash(
|
||||||
await this.findMatchingFileBasedOnHash(
|
contentHash,
|
||||||
contentHash,
|
locallyDeletedFiles
|
||||||
locallyDeletedFiles
|
);
|
||||||
);
|
|
||||||
if (originalFile !== undefined) {
|
if (originalFile !== undefined) {
|
||||||
// `originalFile` hasn't been deleted but it got moved instead
|
// `originalFile` hasn't been deleted but it got moved instead
|
||||||
locallyDeletedFiles = locallyDeletedFiles.filter(
|
locallyDeletedFiles = locallyDeletedFiles.filter(
|
||||||
|
|
@ -202,7 +206,8 @@ export class Syncer {
|
||||||
return Promise.resolve();
|
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<void> {
|
public async reset(): Promise<void> {
|
||||||
this.syncQueue.clear();
|
this.syncQueue.clear();
|
||||||
await this.syncQueue.onEmpty();
|
await this.syncQueue.onEmpty();
|
||||||
await this.database.resetSyncState();
|
|
||||||
this.history.reset();
|
|
||||||
this.remainingOperationsListeners.forEach((listener) => {
|
this.remainingOperationsListeners.forEach((listener) => {
|
||||||
listener(0);
|
listener(0);
|
||||||
});
|
});
|
||||||
|
|
@ -388,22 +391,9 @@ export class Syncer {
|
||||||
SyncType.UPDATE,
|
SyncType.UPDATE,
|
||||||
SyncSource.PUSH,
|
SyncSource.PUSH,
|
||||||
async () => {
|
async () => {
|
||||||
if (
|
this.logger.debug(
|
||||||
(await this.operations.getFileSize(relativePath)) /
|
`Renaming? oldPath ${oldPath} relativePath ${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 localMetadata = this.database.getDocument(
|
const localMetadata = this.database.getDocument(
|
||||||
oldPath ?? relativePath
|
oldPath ?? relativePath
|
||||||
|
|
@ -420,9 +410,27 @@ export class Syncer {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new Error(
|
this.logger.debug(
|
||||||
`Document metadata not found for ${relativePath}. This implies a corrupt local database. Consider resetting the plugin's sync history.`
|
`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 =
|
const contentBytes =
|
||||||
|
|
@ -487,7 +495,7 @@ export class Syncer {
|
||||||
try {
|
try {
|
||||||
if (response.relativePath != relativePath) {
|
if (response.relativePath != relativePath) {
|
||||||
await this.operations.move(
|
await this.operations.move(
|
||||||
oldPath ?? relativePath,
|
relativePath,
|
||||||
response.relativePath
|
response.relativePath
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -616,7 +624,7 @@ export class Syncer {
|
||||||
status: SyncStatus.SUCCESS,
|
status: SyncStatus.SUCCESS,
|
||||||
source: SyncSource.PULL,
|
source: SyncSource.PULL,
|
||||||
relativePath: remoteVersion.relativePath,
|
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
|
type: SyncType.CREATE
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
|
|
@ -720,7 +728,9 @@ export class Syncer {
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.logger.debug(`Syncing ${relativePath}`);
|
this.logger.debug(
|
||||||
|
`Syncing ${relativePath} (${syncSource} - ${syncType})`
|
||||||
|
);
|
||||||
|
|
||||||
await waitForDocumentLock(relativePath);
|
await waitForDocumentLock(relativePath);
|
||||||
try {
|
try {
|
||||||
|
|
@ -752,17 +762,4 @@ export class Syncer {
|
||||||
await this.database.setLastSeenUpdateId(responseVaultUpdateId);
|
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
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue