@codingame/monaco-vscode-working-copy-service-override 18.1.2 → 18.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +11 -13
- package/package.json +5 -5
- package/vscode/src/vs/workbench/services/workingCopy/browser/workingCopyBackupService.d.ts +8 -0
- package/vscode/src/vs/workbench/services/workingCopy/browser/workingCopyBackupService.js +27 -0
- package/vscode/src/vs/workbench/services/workingCopy/browser/workingCopyBackupTracker.d.ts +16 -0
- package/vscode/src/vs/workbench/services/workingCopy/browser/workingCopyBackupTracker.js +46 -0
- package/vscode/src/vs/workbench/services/workingCopy/common/workingCopyBackupTracker.d.ts +54 -0
- package/vscode/src/vs/workbench/services/workingCopy/common/workingCopyBackupTracker.js +259 -0
package/index.js
CHANGED
|
@@ -12,29 +12,27 @@ import { IWorkspaceContextService } from '@codingame/monaco-vscode-api/vscode/vs
|
|
|
12
12
|
import { IWorkbenchEnvironmentService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/environment/common/environmentService.service';
|
|
13
13
|
import { IFileService } from '@codingame/monaco-vscode-api/vscode/vs/platform/files/common/files.service';
|
|
14
14
|
import { ILogService } from '@codingame/monaco-vscode-api/vscode/vs/platform/log/common/log.service';
|
|
15
|
-
import { joinPath } from '@codingame/monaco-vscode-api/vscode/vs/base/common/resources';
|
|
16
15
|
import { WorkingCopyBackupService } from './vscode/src/vs/workbench/services/workingCopy/common/workingCopyBackupService.js';
|
|
16
|
+
import { BrowserWorkingCopyBackupService } from './vscode/src/vs/workbench/services/workingCopy/browser/workingCopyBackupService.js';
|
|
17
17
|
import getServiceOverride$1 from '@codingame/monaco-vscode-files-service-override';
|
|
18
18
|
|
|
19
|
-
let
|
|
20
|
-
constructor(
|
|
21
|
-
super(
|
|
22
|
-
? undefined
|
|
23
|
-
: joinPath(environmentService.userRoamingDataHome, 'Backups', contextService.getWorkspace().id), fileService, logService);
|
|
19
|
+
let MemoryWorkingCopyBackupService = class MemoryWorkingCopyBackupService extends WorkingCopyBackupService {
|
|
20
|
+
constructor(contextService, environmentService, fileService, logService) {
|
|
21
|
+
super(undefined, fileService, logService);
|
|
24
22
|
}
|
|
25
23
|
};
|
|
26
|
-
|
|
27
|
-
__param(
|
|
28
|
-
__param(
|
|
29
|
-
__param(
|
|
30
|
-
__param(
|
|
31
|
-
],
|
|
24
|
+
MemoryWorkingCopyBackupService = __decorate([
|
|
25
|
+
__param(0, IWorkspaceContextService),
|
|
26
|
+
__param(1, IWorkbenchEnvironmentService),
|
|
27
|
+
__param(2, IFileService),
|
|
28
|
+
__param(3, ILogService)
|
|
29
|
+
], MemoryWorkingCopyBackupService);
|
|
32
30
|
function getServiceOverride({ storage = 'userData' } = {}) {
|
|
33
31
|
return {
|
|
34
32
|
...getServiceOverride$1(),
|
|
35
33
|
...(storage != null
|
|
36
34
|
? {
|
|
37
|
-
[IWorkingCopyBackupService.toString()]: new SyncDescriptor(
|
|
35
|
+
[IWorkingCopyBackupService.toString()]: new SyncDescriptor(storage === 'memory' ? MemoryWorkingCopyBackupService : BrowserWorkingCopyBackupService)
|
|
38
36
|
}
|
|
39
37
|
: {}),
|
|
40
38
|
[IWorkingCopyService.toString()]: new SyncDescriptor(WorkingCopyService, [], false),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@codingame/monaco-vscode-working-copy-service-override",
|
|
3
|
-
"version": "18.1.
|
|
3
|
+
"version": "18.1.3",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "VSCode public API plugged on the monaco editor - working-copy service-override",
|
|
6
6
|
"keywords": [],
|
|
@@ -15,10 +15,10 @@
|
|
|
15
15
|
},
|
|
16
16
|
"type": "module",
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@codingame/monaco-vscode-a4683c2b-a0d2-5112-96ba-eedc605346d2-common": "18.1.
|
|
19
|
-
"@codingame/monaco-vscode-api": "18.1.
|
|
20
|
-
"@codingame/monaco-vscode-bba55be6-41a2-50cd-a3cc-8bafa35bfa89-common": "18.1.
|
|
21
|
-
"@codingame/monaco-vscode-files-service-override": "18.1.
|
|
18
|
+
"@codingame/monaco-vscode-a4683c2b-a0d2-5112-96ba-eedc605346d2-common": "18.1.3",
|
|
19
|
+
"@codingame/monaco-vscode-api": "18.1.3",
|
|
20
|
+
"@codingame/monaco-vscode-bba55be6-41a2-50cd-a3cc-8bafa35bfa89-common": "18.1.3",
|
|
21
|
+
"@codingame/monaco-vscode-files-service-override": "18.1.3"
|
|
22
22
|
},
|
|
23
23
|
"main": "index.js",
|
|
24
24
|
"module": "index.js",
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { IFileService } from "@codingame/monaco-vscode-api/vscode/vs/platform/files/common/files.service";
|
|
2
|
+
import { IWorkbenchEnvironmentService } from "@codingame/monaco-vscode-api/vscode/vs/workbench/services/environment/common/environmentService.service";
|
|
3
|
+
import { ILogService } from "@codingame/monaco-vscode-api/vscode/vs/platform/log/common/log.service";
|
|
4
|
+
import { WorkingCopyBackupService } from "../common/workingCopyBackupService.js";
|
|
5
|
+
import { IWorkspaceContextService } from "@codingame/monaco-vscode-api/vscode/vs/platform/workspace/common/workspace.service";
|
|
6
|
+
export declare class BrowserWorkingCopyBackupService extends WorkingCopyBackupService {
|
|
7
|
+
constructor(contextService: IWorkspaceContextService, environmentService: IWorkbenchEnvironmentService, fileService: IFileService, logService: ILogService);
|
|
8
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
|
|
2
|
+
import { __decorate, __param } from '@codingame/monaco-vscode-api/external/tslib/tslib.es6';
|
|
3
|
+
import { IFileService } from '@codingame/monaco-vscode-api/vscode/vs/platform/files/common/files.service';
|
|
4
|
+
import { IWorkbenchEnvironmentService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/environment/common/environmentService.service';
|
|
5
|
+
import { ILogService } from '@codingame/monaco-vscode-api/vscode/vs/platform/log/common/log.service';
|
|
6
|
+
import { WorkingCopyBackupService } from '../common/workingCopyBackupService.js';
|
|
7
|
+
import '@codingame/monaco-vscode-api/vscode/vs/platform/instantiation/common/extensions';
|
|
8
|
+
import '@codingame/monaco-vscode-api/vscode/vs/platform/instantiation/common/instantiation';
|
|
9
|
+
import { joinPath } from '@codingame/monaco-vscode-api/vscode/vs/base/common/resources';
|
|
10
|
+
import { IWorkspaceContextService } from '@codingame/monaco-vscode-api/vscode/vs/platform/workspace/common/workspace.service';
|
|
11
|
+
import { registerWorkbenchContribution2, WorkbenchPhase } from '@codingame/monaco-vscode-api/vscode/vs/workbench/common/contributions';
|
|
12
|
+
import { BrowserWorkingCopyBackupTracker } from './workingCopyBackupTracker.js';
|
|
13
|
+
|
|
14
|
+
let BrowserWorkingCopyBackupService = class BrowserWorkingCopyBackupService extends WorkingCopyBackupService {
|
|
15
|
+
constructor(contextService, environmentService, fileService, logService) {
|
|
16
|
+
super(joinPath(environmentService.userRoamingDataHome, 'Backups', contextService.getWorkspace().id), fileService, logService);
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
BrowserWorkingCopyBackupService = ( __decorate([
|
|
20
|
+
( __param(0, IWorkspaceContextService)),
|
|
21
|
+
( __param(1, IWorkbenchEnvironmentService)),
|
|
22
|
+
( __param(2, IFileService)),
|
|
23
|
+
( __param(3, ILogService))
|
|
24
|
+
], BrowserWorkingCopyBackupService));
|
|
25
|
+
registerWorkbenchContribution2(BrowserWorkingCopyBackupTracker.ID, BrowserWorkingCopyBackupTracker, WorkbenchPhase.BlockStartup);
|
|
26
|
+
|
|
27
|
+
export { BrowserWorkingCopyBackupService };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { IWorkingCopyBackupService } from "@codingame/monaco-vscode-api/vscode/vs/workbench/services/workingCopy/common/workingCopyBackup.service";
|
|
2
|
+
import { IWorkbenchContribution } from "@codingame/monaco-vscode-api/vscode/vs/workbench/common/contributions";
|
|
3
|
+
import { IFilesConfigurationService } from "@codingame/monaco-vscode-api/vscode/vs/workbench/services/filesConfiguration/common/filesConfigurationService.service";
|
|
4
|
+
import { IWorkingCopyService } from "@codingame/monaco-vscode-api/vscode/vs/workbench/services/workingCopy/common/workingCopyService.service";
|
|
5
|
+
import { ShutdownReason } from "@codingame/monaco-vscode-api/vscode/vs/workbench/services/lifecycle/common/lifecycle";
|
|
6
|
+
import { ILifecycleService } from "@codingame/monaco-vscode-api/vscode/vs/workbench/services/lifecycle/common/lifecycle.service";
|
|
7
|
+
import { ILogService } from "@codingame/monaco-vscode-api/vscode/vs/platform/log/common/log.service";
|
|
8
|
+
import { WorkingCopyBackupTracker } from "../common/workingCopyBackupTracker.js";
|
|
9
|
+
import { IWorkingCopyEditorService } from "@codingame/monaco-vscode-api/vscode/vs/workbench/services/workingCopy/common/workingCopyEditorService.service";
|
|
10
|
+
import { IEditorService } from "@codingame/monaco-vscode-api/vscode/vs/workbench/services/editor/common/editorService.service";
|
|
11
|
+
import { IEditorGroupsService } from "@codingame/monaco-vscode-api/vscode/vs/workbench/services/editor/common/editorGroupsService.service";
|
|
12
|
+
export declare class BrowserWorkingCopyBackupTracker extends WorkingCopyBackupTracker implements IWorkbenchContribution {
|
|
13
|
+
static readonly ID = "workbench.contrib.browserWorkingCopyBackupTracker";
|
|
14
|
+
constructor(workingCopyBackupService: IWorkingCopyBackupService, filesConfigurationService: IFilesConfigurationService, workingCopyService: IWorkingCopyService, lifecycleService: ILifecycleService, logService: ILogService, workingCopyEditorService: IWorkingCopyEditorService, editorService: IEditorService, editorGroupService: IEditorGroupsService);
|
|
15
|
+
protected onFinalBeforeShutdown(reason: ShutdownReason): boolean;
|
|
16
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
|
|
2
|
+
import { __decorate, __param } from '@codingame/monaco-vscode-api/external/tslib/tslib.es6';
|
|
3
|
+
import { IWorkingCopyBackupService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/workingCopy/common/workingCopyBackup.service';
|
|
4
|
+
import { IFilesConfigurationService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/filesConfiguration/common/filesConfigurationService.service';
|
|
5
|
+
import { IWorkingCopyService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/workingCopy/common/workingCopyService.service';
|
|
6
|
+
import { ILifecycleService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/lifecycle/common/lifecycle.service';
|
|
7
|
+
import { ILogService } from '@codingame/monaco-vscode-api/vscode/vs/platform/log/common/log.service';
|
|
8
|
+
import { WorkingCopyBackupTracker } from '../common/workingCopyBackupTracker.js';
|
|
9
|
+
import { IWorkingCopyEditorService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/workingCopy/common/workingCopyEditorService.service';
|
|
10
|
+
import { IEditorService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/editor/common/editorService.service';
|
|
11
|
+
import { IEditorGroupsService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/editor/common/editorGroupsService.service';
|
|
12
|
+
|
|
13
|
+
let BrowserWorkingCopyBackupTracker = class BrowserWorkingCopyBackupTracker extends WorkingCopyBackupTracker {
|
|
14
|
+
static { this.ID = 'workbench.contrib.browserWorkingCopyBackupTracker'; }
|
|
15
|
+
constructor(workingCopyBackupService, filesConfigurationService, workingCopyService, lifecycleService, logService, workingCopyEditorService, editorService, editorGroupService) {
|
|
16
|
+
super(workingCopyBackupService, workingCopyService, logService, lifecycleService, filesConfigurationService, workingCopyEditorService, editorService, editorGroupService);
|
|
17
|
+
}
|
|
18
|
+
onFinalBeforeShutdown(reason) {
|
|
19
|
+
const modifiedWorkingCopies = this.workingCopyService.modifiedWorkingCopies;
|
|
20
|
+
if (!modifiedWorkingCopies.length) {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
if (!this.filesConfigurationService.isHotExitEnabled) {
|
|
24
|
+
return true;
|
|
25
|
+
}
|
|
26
|
+
for (const modifiedWorkingCopy of modifiedWorkingCopies) {
|
|
27
|
+
if (!this.workingCopyBackupService.hasBackupSync(modifiedWorkingCopy, this.getContentVersion(modifiedWorkingCopy))) {
|
|
28
|
+
this.logService.warn('Unload veto: pending backups');
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
BrowserWorkingCopyBackupTracker = ( __decorate([
|
|
36
|
+
( __param(0, IWorkingCopyBackupService)),
|
|
37
|
+
( __param(1, IFilesConfigurationService)),
|
|
38
|
+
( __param(2, IWorkingCopyService)),
|
|
39
|
+
( __param(3, ILifecycleService)),
|
|
40
|
+
( __param(4, ILogService)),
|
|
41
|
+
( __param(5, IWorkingCopyEditorService)),
|
|
42
|
+
( __param(6, IEditorService)),
|
|
43
|
+
( __param(7, IEditorGroupsService))
|
|
44
|
+
], BrowserWorkingCopyBackupTracker));
|
|
45
|
+
|
|
46
|
+
export { BrowserWorkingCopyBackupTracker };
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { IWorkingCopyBackupService } from "@codingame/monaco-vscode-api/vscode/vs/workbench/services/workingCopy/common/workingCopyBackup.service";
|
|
2
|
+
import { Disposable, IDisposable } from "@codingame/monaco-vscode-api/vscode/vs/base/common/lifecycle";
|
|
3
|
+
import { IWorkingCopyService } from "@codingame/monaco-vscode-api/vscode/vs/workbench/services/workingCopy/common/workingCopyService.service";
|
|
4
|
+
import { IWorkingCopy, IWorkingCopyIdentifier } from "@codingame/monaco-vscode-a4683c2b-a0d2-5112-96ba-eedc605346d2-common/vscode/vs/workbench/services/workingCopy/common/workingCopy";
|
|
5
|
+
import { ILogService } from "@codingame/monaco-vscode-api/vscode/vs/platform/log/common/log.service";
|
|
6
|
+
import { ShutdownReason } from "@codingame/monaco-vscode-api/vscode/vs/workbench/services/lifecycle/common/lifecycle";
|
|
7
|
+
import { ILifecycleService } from "@codingame/monaco-vscode-api/vscode/vs/workbench/services/lifecycle/common/lifecycle.service";
|
|
8
|
+
import { IFilesConfigurationService } from "@codingame/monaco-vscode-api/vscode/vs/workbench/services/filesConfiguration/common/filesConfigurationService.service";
|
|
9
|
+
import { IWorkingCopyEditorHandler } from "./workingCopyEditorService.js";
|
|
10
|
+
import { IWorkingCopyEditorService } from "@codingame/monaco-vscode-api/vscode/vs/workbench/services/workingCopy/common/workingCopyEditorService.service";
|
|
11
|
+
import { IEditorService } from "@codingame/monaco-vscode-api/vscode/vs/workbench/services/editor/common/editorService.service";
|
|
12
|
+
import { IEditorGroupsService } from "@codingame/monaco-vscode-api/vscode/vs/workbench/services/editor/common/editorGroupsService.service";
|
|
13
|
+
export declare abstract class WorkingCopyBackupTracker extends Disposable {
|
|
14
|
+
protected readonly workingCopyBackupService: IWorkingCopyBackupService;
|
|
15
|
+
protected readonly workingCopyService: IWorkingCopyService;
|
|
16
|
+
protected readonly logService: ILogService;
|
|
17
|
+
private readonly lifecycleService;
|
|
18
|
+
protected readonly filesConfigurationService: IFilesConfigurationService;
|
|
19
|
+
private readonly workingCopyEditorService;
|
|
20
|
+
protected readonly editorService: IEditorService;
|
|
21
|
+
private readonly editorGroupService;
|
|
22
|
+
constructor(workingCopyBackupService: IWorkingCopyBackupService, workingCopyService: IWorkingCopyService, logService: ILogService, lifecycleService: ILifecycleService, filesConfigurationService: IFilesConfigurationService, workingCopyEditorService: IWorkingCopyEditorService, editorService: IEditorService, editorGroupService: IEditorGroupsService);
|
|
23
|
+
private registerListeners;
|
|
24
|
+
protected abstract onFinalBeforeShutdown(reason: ShutdownReason): boolean | Promise<boolean>;
|
|
25
|
+
private onWillShutdown;
|
|
26
|
+
private static readonly DEFAULT_BACKUP_SCHEDULE_DELAYS;
|
|
27
|
+
private readonly mapWorkingCopyToContentVersion;
|
|
28
|
+
protected readonly pendingBackupOperations: Map<IWorkingCopyIdentifier, {
|
|
29
|
+
disposable: IDisposable;
|
|
30
|
+
cancel: () => void;
|
|
31
|
+
}>;
|
|
32
|
+
private suspended;
|
|
33
|
+
private onDidRegister;
|
|
34
|
+
private onDidUnregister;
|
|
35
|
+
private onDidChangeDirty;
|
|
36
|
+
private onDidChangeContent;
|
|
37
|
+
private scheduleBackup;
|
|
38
|
+
protected getBackupScheduleDelay(workingCopy: IWorkingCopy): number;
|
|
39
|
+
protected getContentVersion(workingCopy: IWorkingCopy): number;
|
|
40
|
+
private discardBackup;
|
|
41
|
+
private doDiscardBackup;
|
|
42
|
+
private cancelBackupOperation;
|
|
43
|
+
private doClearPendingBackupOperation;
|
|
44
|
+
protected cancelBackupOperations(): void;
|
|
45
|
+
protected suspendBackupOperations(): {
|
|
46
|
+
resume: () => void;
|
|
47
|
+
};
|
|
48
|
+
protected readonly unrestoredBackups: Set<IWorkingCopyIdentifier>;
|
|
49
|
+
protected readonly whenReady: Promise<void>;
|
|
50
|
+
private _isReady;
|
|
51
|
+
protected get isReady(): boolean;
|
|
52
|
+
private resolveBackupsToRestore;
|
|
53
|
+
protected restoreBackups(handler: IWorkingCopyEditorHandler): Promise<void>;
|
|
54
|
+
}
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
|
|
2
|
+
import { Disposable, toDisposable } from '@codingame/monaco-vscode-api/vscode/vs/base/common/lifecycle';
|
|
3
|
+
import { WorkingCopyCapabilities } from '@codingame/monaco-vscode-a4683c2b-a0d2-5112-96ba-eedc605346d2-common/vscode/vs/workbench/services/workingCopy/common/workingCopy';
|
|
4
|
+
import { LifecyclePhase } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/lifecycle/common/lifecycle';
|
|
5
|
+
import { CancellationTokenSource } from '@codingame/monaco-vscode-api/vscode/vs/base/common/cancellation';
|
|
6
|
+
import { Promises } from '@codingame/monaco-vscode-api/vscode/vs/base/common/async';
|
|
7
|
+
import { EditorsOrder } from '@codingame/monaco-vscode-api/vscode/vs/workbench/common/editor';
|
|
8
|
+
|
|
9
|
+
class WorkingCopyBackupTracker extends Disposable {
|
|
10
|
+
constructor(workingCopyBackupService, workingCopyService, logService, lifecycleService, filesConfigurationService, workingCopyEditorService, editorService, editorGroupService) {
|
|
11
|
+
super();
|
|
12
|
+
this.workingCopyBackupService = workingCopyBackupService;
|
|
13
|
+
this.workingCopyService = workingCopyService;
|
|
14
|
+
this.logService = logService;
|
|
15
|
+
this.lifecycleService = lifecycleService;
|
|
16
|
+
this.filesConfigurationService = filesConfigurationService;
|
|
17
|
+
this.workingCopyEditorService = workingCopyEditorService;
|
|
18
|
+
this.editorService = editorService;
|
|
19
|
+
this.editorGroupService = editorGroupService;
|
|
20
|
+
this.mapWorkingCopyToContentVersion = ( new Map());
|
|
21
|
+
this.pendingBackupOperations = ( new Map());
|
|
22
|
+
this.suspended = false;
|
|
23
|
+
this.unrestoredBackups = ( new Set());
|
|
24
|
+
this._isReady = false;
|
|
25
|
+
this.whenReady = this.resolveBackupsToRestore();
|
|
26
|
+
for (const workingCopy of this.workingCopyService.modifiedWorkingCopies) {
|
|
27
|
+
this.onDidRegister(workingCopy);
|
|
28
|
+
}
|
|
29
|
+
this.registerListeners();
|
|
30
|
+
}
|
|
31
|
+
registerListeners() {
|
|
32
|
+
this._register(this.workingCopyService.onDidRegister(workingCopy => this.onDidRegister(workingCopy)));
|
|
33
|
+
this._register(this.workingCopyService.onDidUnregister(workingCopy => this.onDidUnregister(workingCopy)));
|
|
34
|
+
this._register(this.workingCopyService.onDidChangeDirty(workingCopy => this.onDidChangeDirty(workingCopy)));
|
|
35
|
+
this._register(this.workingCopyService.onDidChangeContent(workingCopy => this.onDidChangeContent(workingCopy)));
|
|
36
|
+
this._register(this.lifecycleService.onBeforeShutdown(event => event.finalVeto(() => this.onFinalBeforeShutdown(event.reason), 'veto.backups')));
|
|
37
|
+
this._register(this.lifecycleService.onWillShutdown(() => this.onWillShutdown()));
|
|
38
|
+
this._register(this.workingCopyEditorService.onDidRegisterHandler(handler => this.restoreBackups(handler)));
|
|
39
|
+
}
|
|
40
|
+
onWillShutdown() {
|
|
41
|
+
this.cancelBackupOperations();
|
|
42
|
+
this.suspendBackupOperations();
|
|
43
|
+
}
|
|
44
|
+
static { this.DEFAULT_BACKUP_SCHEDULE_DELAYS = {
|
|
45
|
+
['default']: 1000,
|
|
46
|
+
['delayed']: 2000
|
|
47
|
+
}; }
|
|
48
|
+
onDidRegister(workingCopy) {
|
|
49
|
+
if (this.suspended) {
|
|
50
|
+
this.logService.warn(`[backup tracker] suspended, ignoring register event`, ( workingCopy.resource.toString()), workingCopy.typeId);
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
if (workingCopy.isModified()) {
|
|
54
|
+
this.scheduleBackup(workingCopy);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
onDidUnregister(workingCopy) {
|
|
58
|
+
this.mapWorkingCopyToContentVersion.delete(workingCopy);
|
|
59
|
+
if (this.suspended) {
|
|
60
|
+
this.logService.warn(`[backup tracker] suspended, ignoring unregister event`, ( workingCopy.resource.toString()), workingCopy.typeId);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
this.discardBackup(workingCopy);
|
|
64
|
+
}
|
|
65
|
+
onDidChangeDirty(workingCopy) {
|
|
66
|
+
if (this.suspended) {
|
|
67
|
+
this.logService.warn(`[backup tracker] suspended, ignoring dirty change event`, ( workingCopy.resource.toString()), workingCopy.typeId);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
if (workingCopy.isDirty()) {
|
|
71
|
+
this.scheduleBackup(workingCopy);
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
this.discardBackup(workingCopy);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
onDidChangeContent(workingCopy) {
|
|
78
|
+
const contentVersionId = this.getContentVersion(workingCopy);
|
|
79
|
+
this.mapWorkingCopyToContentVersion.set(workingCopy, contentVersionId + 1);
|
|
80
|
+
if (this.suspended) {
|
|
81
|
+
this.logService.warn(`[backup tracker] suspended, ignoring content change event`, ( workingCopy.resource.toString()), workingCopy.typeId);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
if (workingCopy.isModified()) {
|
|
85
|
+
this.scheduleBackup(workingCopy);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
scheduleBackup(workingCopy) {
|
|
89
|
+
this.cancelBackupOperation(workingCopy);
|
|
90
|
+
this.logService.trace(`[backup tracker] scheduling backup`, ( workingCopy.resource.toString()), workingCopy.typeId);
|
|
91
|
+
const workingCopyIdentifier = { resource: workingCopy.resource, typeId: workingCopy.typeId };
|
|
92
|
+
const cts = ( new CancellationTokenSource());
|
|
93
|
+
const handle = setTimeout(async () => {
|
|
94
|
+
if (cts.token.isCancellationRequested) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
if (workingCopy.isModified()) {
|
|
98
|
+
this.logService.trace(`[backup tracker] creating backup`, ( workingCopy.resource.toString()), workingCopy.typeId);
|
|
99
|
+
try {
|
|
100
|
+
const backup = await workingCopy.backup(cts.token);
|
|
101
|
+
if (cts.token.isCancellationRequested) {
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
if (workingCopy.isModified()) {
|
|
105
|
+
this.logService.trace(`[backup tracker] storing backup`, ( workingCopy.resource.toString()), workingCopy.typeId);
|
|
106
|
+
await this.workingCopyBackupService.backup(workingCopy, backup.content, this.getContentVersion(workingCopy), backup.meta, cts.token);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
this.logService.error(error);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
if (!cts.token.isCancellationRequested) {
|
|
114
|
+
this.doClearPendingBackupOperation(workingCopyIdentifier);
|
|
115
|
+
}
|
|
116
|
+
}, this.getBackupScheduleDelay(workingCopy));
|
|
117
|
+
this.pendingBackupOperations.set(workingCopyIdentifier, {
|
|
118
|
+
cancel: () => {
|
|
119
|
+
this.logService.trace(`[backup tracker] clearing pending backup creation`, ( workingCopy.resource.toString()), workingCopy.typeId);
|
|
120
|
+
cts.cancel();
|
|
121
|
+
},
|
|
122
|
+
disposable: toDisposable(() => {
|
|
123
|
+
cts.dispose();
|
|
124
|
+
clearTimeout(handle);
|
|
125
|
+
})
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
getBackupScheduleDelay(workingCopy) {
|
|
129
|
+
if (typeof workingCopy.backupDelay === 'number') {
|
|
130
|
+
return workingCopy.backupDelay;
|
|
131
|
+
}
|
|
132
|
+
let backupScheduleDelay;
|
|
133
|
+
if (workingCopy.capabilities & WorkingCopyCapabilities.Untitled) {
|
|
134
|
+
backupScheduleDelay = 'default';
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
backupScheduleDelay = this.filesConfigurationService.hasShortAutoSaveDelay(workingCopy.resource) ? 'delayed' : 'default';
|
|
138
|
+
}
|
|
139
|
+
return WorkingCopyBackupTracker.DEFAULT_BACKUP_SCHEDULE_DELAYS[backupScheduleDelay];
|
|
140
|
+
}
|
|
141
|
+
getContentVersion(workingCopy) {
|
|
142
|
+
return this.mapWorkingCopyToContentVersion.get(workingCopy) || 0;
|
|
143
|
+
}
|
|
144
|
+
discardBackup(workingCopy) {
|
|
145
|
+
this.cancelBackupOperation(workingCopy);
|
|
146
|
+
const workingCopyIdentifier = { resource: workingCopy.resource, typeId: workingCopy.typeId };
|
|
147
|
+
const cts = ( new CancellationTokenSource());
|
|
148
|
+
this.doDiscardBackup(workingCopyIdentifier, cts);
|
|
149
|
+
this.pendingBackupOperations.set(workingCopyIdentifier, {
|
|
150
|
+
cancel: () => {
|
|
151
|
+
this.logService.trace(`[backup tracker] clearing pending backup discard`, ( workingCopy.resource.toString()), workingCopy.typeId);
|
|
152
|
+
cts.cancel();
|
|
153
|
+
},
|
|
154
|
+
disposable: cts
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
async doDiscardBackup(workingCopyIdentifier, cts) {
|
|
158
|
+
this.logService.trace(`[backup tracker] discarding backup`, ( workingCopyIdentifier.resource.toString()), workingCopyIdentifier.typeId);
|
|
159
|
+
try {
|
|
160
|
+
await this.workingCopyBackupService.discardBackup(workingCopyIdentifier, cts.token);
|
|
161
|
+
}
|
|
162
|
+
catch (error) {
|
|
163
|
+
this.logService.error(error);
|
|
164
|
+
}
|
|
165
|
+
if (!cts.token.isCancellationRequested) {
|
|
166
|
+
this.doClearPendingBackupOperation(workingCopyIdentifier);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
cancelBackupOperation(workingCopy) {
|
|
170
|
+
let workingCopyIdentifier = undefined;
|
|
171
|
+
for (const [identifier] of this.pendingBackupOperations) {
|
|
172
|
+
if (( identifier.resource.toString()) === ( workingCopy.resource.toString()) && identifier.typeId === workingCopy.typeId) {
|
|
173
|
+
workingCopyIdentifier = identifier;
|
|
174
|
+
break;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
if (workingCopyIdentifier) {
|
|
178
|
+
this.doClearPendingBackupOperation(workingCopyIdentifier, { cancel: true });
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
doClearPendingBackupOperation(workingCopyIdentifier, options) {
|
|
182
|
+
const pendingBackupOperation = this.pendingBackupOperations.get(workingCopyIdentifier);
|
|
183
|
+
if (!pendingBackupOperation) {
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
if (options?.cancel) {
|
|
187
|
+
pendingBackupOperation.cancel();
|
|
188
|
+
}
|
|
189
|
+
pendingBackupOperation.disposable.dispose();
|
|
190
|
+
this.pendingBackupOperations.delete(workingCopyIdentifier);
|
|
191
|
+
}
|
|
192
|
+
cancelBackupOperations() {
|
|
193
|
+
for (const [, operation] of this.pendingBackupOperations) {
|
|
194
|
+
operation.cancel();
|
|
195
|
+
operation.disposable.dispose();
|
|
196
|
+
}
|
|
197
|
+
this.pendingBackupOperations.clear();
|
|
198
|
+
}
|
|
199
|
+
suspendBackupOperations() {
|
|
200
|
+
this.suspended = true;
|
|
201
|
+
return { resume: () => this.suspended = false };
|
|
202
|
+
}
|
|
203
|
+
get isReady() { return this._isReady; }
|
|
204
|
+
async resolveBackupsToRestore() {
|
|
205
|
+
await this.lifecycleService.when(LifecyclePhase.Restored);
|
|
206
|
+
for (const backup of await this.workingCopyBackupService.getBackups()) {
|
|
207
|
+
this.unrestoredBackups.add(backup);
|
|
208
|
+
}
|
|
209
|
+
this._isReady = true;
|
|
210
|
+
}
|
|
211
|
+
async restoreBackups(handler) {
|
|
212
|
+
await this.whenReady;
|
|
213
|
+
const openedEditorsForBackups = ( new Set());
|
|
214
|
+
const nonOpenedEditorsForBackups = ( new Set());
|
|
215
|
+
const restoredBackups = ( new Set());
|
|
216
|
+
for (const unrestoredBackup of this.unrestoredBackups) {
|
|
217
|
+
const canHandleUnrestoredBackup = await handler.handles(unrestoredBackup);
|
|
218
|
+
if (!canHandleUnrestoredBackup) {
|
|
219
|
+
continue;
|
|
220
|
+
}
|
|
221
|
+
let hasOpenedEditorForBackup = false;
|
|
222
|
+
for (const { editor } of this.editorService.getEditors(EditorsOrder.MOST_RECENTLY_ACTIVE)) {
|
|
223
|
+
const isUnrestoredBackupOpened = handler.isOpen(unrestoredBackup, editor);
|
|
224
|
+
if (isUnrestoredBackupOpened) {
|
|
225
|
+
openedEditorsForBackups.add(editor);
|
|
226
|
+
hasOpenedEditorForBackup = true;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
if (!hasOpenedEditorForBackup) {
|
|
230
|
+
nonOpenedEditorsForBackups.add(await handler.createEditor(unrestoredBackup));
|
|
231
|
+
}
|
|
232
|
+
restoredBackups.add(unrestoredBackup);
|
|
233
|
+
}
|
|
234
|
+
if (nonOpenedEditorsForBackups.size > 0) {
|
|
235
|
+
await this.editorGroupService.activeGroup.openEditors(( [...nonOpenedEditorsForBackups].map(nonOpenedEditorForBackup => ({
|
|
236
|
+
editor: nonOpenedEditorForBackup,
|
|
237
|
+
options: {
|
|
238
|
+
pinned: true,
|
|
239
|
+
preserveFocus: true,
|
|
240
|
+
inactive: true
|
|
241
|
+
}
|
|
242
|
+
}))));
|
|
243
|
+
for (const nonOpenedEditorForBackup of nonOpenedEditorsForBackups) {
|
|
244
|
+
openedEditorsForBackups.add(nonOpenedEditorForBackup);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
await Promises.settled(( [...openedEditorsForBackups].map(async (openedEditorForBackup) => {
|
|
248
|
+
if (this.editorService.isVisible(openedEditorForBackup)) {
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
return openedEditorForBackup.resolve();
|
|
252
|
+
})));
|
|
253
|
+
for (const restoredBackup of restoredBackups) {
|
|
254
|
+
this.unrestoredBackups.delete(restoredBackup);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
export { WorkingCopyBackupTracker };
|