diff --git a/package.json b/package.json index d680967..d7bdc87 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@filen/sync", - "version": "0.1.86", + "version": "0.1.87", "description": "Filen Sync", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/src/lib/sync.ts b/src/lib/sync.ts index 80349a1..9682830 100644 --- a/src/lib/sync.ts +++ b/src/lib/sync.ts @@ -420,6 +420,7 @@ export class Sync { const confirmLocalDeletion = this.previousLocalTree.size > 0 && currentLocalTree.result.size === 0 const confirmRemoteDeletion = this.previousRemoteTree.size > 0 && currentRemoteTree.result.size === 0 + let skipSyncDueToConfirmDeletionRestart = false // If the previous tree has nodes and the current one is empty, we should prompt the user to confirm deletion if ( @@ -429,190 +430,194 @@ export class Sync { ) { this.deletionConfirmationResult = "waiting" - const result = await new Promise<"delete" | "restart">(resolve => { + const sendConfirmationMessage = () => { + postMessageToMain({ + type: "confirmDeletion", + syncPair: this.syncPair, + data: { + where: + confirmLocalDeletion && confirmRemoteDeletion ? "both" : confirmLocalDeletion ? "local" : "remote", + previous: + confirmLocalDeletion && confirmRemoteDeletion + ? this.previousLocalTree.size + this.previousRemoteTree.size + : confirmLocalDeletion + ? this.previousLocalTree.size + : this.previousRemoteTree.size, + current: + confirmLocalDeletion && confirmRemoteDeletion + ? currentLocalTree.result.size + currentRemoteTree.result.size + : confirmLocalDeletion + ? currentLocalTree.result.size + : currentRemoteTree.result.size + } + }) + } + + sendConfirmationMessage() + + await new Promise(resolve => { const interval = setInterval(() => { if (this.deletionConfirmationResult !== "waiting") { clearInterval(interval) - resolve(this.deletionConfirmationResult) + resolve() } else { - postMessageToMain({ - type: "confirmDeletion", - syncPair: this.syncPair, - data: { - where: - confirmLocalDeletion && confirmRemoteDeletion - ? "both" - : confirmLocalDeletion - ? "local" - : "remote", - previous: - confirmLocalDeletion && confirmRemoteDeletion - ? this.previousLocalTree.size + this.previousRemoteTree.size - : confirmLocalDeletion - ? this.previousLocalTree.size - : this.previousRemoteTree.size, - current: - confirmLocalDeletion && confirmRemoteDeletion - ? currentLocalTree.result.size + currentRemoteTree.result.size - : confirmLocalDeletion - ? currentLocalTree.result.size - : currentRemoteTree.result.size - } - }) + sendConfirmationMessage() } }, 1000) }) - if (result === "restart") { - return + if (this.deletionConfirmationResult === "waiting" || this.deletionConfirmationResult === "restart") { + skipSyncDueToConfirmDeletionRestart = true } } - postMessageToMain({ - type: "cycleProcessingDeltasStarted", - syncPair: this.syncPair - }) - - const deltas = await this.deltas.process({ - currentLocalTree: currentLocalTree.result, - currentRemoteTree: currentRemoteTree.result, - previousLocalTree: this.previousLocalTree, - previousRemoteTree: this.previousRemoteTree, - currentLocalTreeErrors: currentLocalTree.errors - }) - - postMessageToMain({ - type: "deltasCount", - syncPair: this.syncPair, - data: { - count: deltas.length - } - }) + if (!skipSyncDueToConfirmDeletionRestart) { + postMessageToMain({ + type: "cycleProcessingDeltasStarted", + syncPair: this.syncPair + }) - postMessageToMain({ - type: "deltasSize", - syncPair: this.syncPair, - data: { - size: deltas.reduce( - (prev, delta) => prev + (delta.type === "uploadFile" || delta.type === "downloadFile" ? delta.size : 0), - 0 - ) - } - }) + const deltas = await this.deltas.process({ + currentLocalTree: currentLocalTree.result, + currentRemoteTree: currentRemoteTree.result, + previousLocalTree: this.previousLocalTree, + previousRemoteTree: this.previousRemoteTree, + currentLocalTreeErrors: currentLocalTree.errors + }) - postMessageToMain({ - type: "cycleProcessingDeltasDone", - syncPair: this.syncPair - }) + postMessageToMain({ + type: "deltasCount", + syncPair: this.syncPair, + data: { + count: deltas.length + } + }) - postMessageToMain({ - type: "cycleProcessingTasksStarted", - syncPair: this.syncPair - }) + postMessageToMain({ + type: "deltasSize", + syncPair: this.syncPair, + data: { + size: deltas.reduce( + (prev, delta) => prev + (delta.type === "uploadFile" || delta.type === "downloadFile" ? delta.size : 0), + 0 + ) + } + }) - const { doneTasks, errors } = await this.tasks.process({ deltasSorted: deltas }) + postMessageToMain({ + type: "cycleProcessingDeltasDone", + syncPair: this.syncPair + }) - postMessageToMain({ - type: "cycleProcessingTasksDone", - syncPair: this.syncPair - }) + postMessageToMain({ + type: "cycleProcessingTasksStarted", + syncPair: this.syncPair + }) - postMessageToMain({ - type: "taskErrors", - syncPair: this.syncPair, - data: { - errors: errors.map(e => ({ - ...e, - error: serializeError(e.error) - })) - } - }) + const { doneTasks, errors } = await this.tasks.process({ deltasSorted: deltas }) - this.taskErrors = errors + postMessageToMain({ + type: "cycleProcessingTasksDone", + syncPair: this.syncPair + }) - if (this.taskErrors.length === 0) { - if (doneTasks.length > 0) { - postMessageToMain({ - type: "cycleApplyingStateStarted", - syncPair: this.syncPair - }) + postMessageToMain({ + type: "taskErrors", + syncPair: this.syncPair, + data: { + errors: errors.map(e => ({ + ...e, + error: serializeError(e.error) + })) + } + }) - const didLocalChanges = doneTasks.some( - task => - task.type === "createLocalDirectory" || - task.type === "deleteLocalDirectory" || - task.type === "deleteLocalFile" || - task.type === "renameLocalDirectory" || - task.type === "renameLocalFile" - ) - const didRemoteChanges = doneTasks.some( - task => - task.type === "renameRemoteDirectory" || - task.type === "renameRemoteFile" || - task.type === "createRemoteDirectory" || - task.type === "deleteRemoteDirectory" || - task.type === "deleteRemoteFile" - ) - - // Here we reset the internal local/remote tree changed times so we rescan after we did changes for consistency - if (didLocalChanges) { - this.localFileSystem.lastDirectoryChangeTimestamp = Date.now() - SYNC_INTERVAL * 2 - this.localFileSystem.getDirectoryTreeCache = { - timestamp: 0, - tree: {}, - inodes: {}, - ignored: [], - errors: [], - size: 0 + this.taskErrors = errors + + if (this.taskErrors.length === 0) { + if (doneTasks.length > 0) { + postMessageToMain({ + type: "cycleApplyingStateStarted", + syncPair: this.syncPair + }) + + const didLocalChanges = doneTasks.some( + task => + task.type === "createLocalDirectory" || + task.type === "deleteLocalDirectory" || + task.type === "deleteLocalFile" || + task.type === "renameLocalDirectory" || + task.type === "renameLocalFile" + ) + const didRemoteChanges = doneTasks.some( + task => + task.type === "renameRemoteDirectory" || + task.type === "renameRemoteFile" || + task.type === "createRemoteDirectory" || + task.type === "deleteRemoteDirectory" || + task.type === "deleteRemoteFile" + ) + + // Here we reset the internal local/remote tree changed times so we rescan after we did changes for consistency + if (didLocalChanges) { + this.localFileSystem.lastDirectoryChangeTimestamp = Date.now() - SYNC_INTERVAL * 2 + this.localFileSystem.getDirectoryTreeCache = { + timestamp: 0, + tree: {}, + inodes: {}, + ignored: [], + errors: [], + size: 0 + } } - } - if (didRemoteChanges) { - this.remoteFileSystem.getDirectoryTreeCache = { - timestamp: 0, - tree: {}, - uuids: {}, - ignored: [], - size: 0 + if (didRemoteChanges) { + this.remoteFileSystem.getDirectoryTreeCache = { + timestamp: 0, + tree: {}, + uuids: {}, + ignored: [], + size: 0 + } } - } - const applied = this.state.applyDoneTasksToState({ - doneTasks, - currentLocalTree: currentLocalTree.result, - currentRemoteTree: currentRemoteTree.result - }) + const applied = this.state.applyDoneTasksToState({ + doneTasks, + currentLocalTree: currentLocalTree.result, + currentRemoteTree: currentRemoteTree.result + }) + + currentLocalTree.result = applied.currentLocalTree + currentRemoteTree.result = applied.currentRemoteTree - currentLocalTree.result = applied.currentLocalTree - currentRemoteTree.result = applied.currentRemoteTree + postMessageToMain({ + type: "cycleApplyingStateDone", + syncPair: this.syncPair + }) + } postMessageToMain({ - type: "cycleApplyingStateDone", + type: "cycleSavingStateStarted", syncPair: this.syncPair }) - } - postMessageToMain({ - type: "cycleSavingStateStarted", - syncPair: this.syncPair - }) + this.previousLocalTree = currentLocalTree.result + this.previousRemoteTree = currentRemoteTree.result - this.previousLocalTree = currentLocalTree.result - this.previousRemoteTree = currentRemoteTree.result + await this.state.save() - await this.state.save() + postMessageToMain({ + type: "cycleSavingStateDone", + syncPair: this.syncPair + }) + } postMessageToMain({ - type: "cycleSavingStateDone", + type: "cycleSuccess", syncPair: this.syncPair }) } - - postMessageToMain({ - type: "cycleSuccess", - syncPair: this.syncPair - }) } } finally { postMessageToMain({