@@ -15,13 +15,13 @@ import { ISCMRepository, ISCMService } from 'vs/workbench/contrib/scm/common/scm
15
15
import { IFileService } from 'vs/platform/files/common/files' ;
16
16
import { IWorkspaceContextService , IWorkspaceFolder , WorkbenchState } from 'vs/platform/workspace/common/workspace' ;
17
17
import { URI } from 'vs/base/common/uri' ;
18
- import { basename , isEqualOrParent , joinPath , relativePath } from 'vs/base/common/resources' ;
18
+ import { basename , joinPath , relativePath } from 'vs/base/common/resources' ;
19
19
import { encodeBase64 } from 'vs/base/common/buffer' ;
20
20
import { IConfigurationService } from 'vs/platform/configuration/common/configuration' ;
21
21
import { IProgress , IProgressService , IProgressStep , ProgressLocation } from 'vs/platform/progress/common/progress' ;
22
22
import { EditSessionsWorkbenchService } from 'vs/workbench/contrib/editSessions/browser/editSessionsStorageService' ;
23
23
import { InstantiationType , registerSingleton } from 'vs/platform/instantiation/common/extensions' ;
24
- import { UserDataSyncErrorCode , UserDataSyncStoreError } from 'vs/platform/userDataSync/common/userDataSync' ;
24
+ import { UserDataSyncErrorCode , UserDataSyncStoreError , IUserDataSynchroniser } from 'vs/platform/userDataSync/common/userDataSync' ;
25
25
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry' ;
26
26
import { INotificationService , Severity } from 'vs/platform/notification/common/notification' ;
27
27
import { getFileNamesMessage , IDialogService , IFileDialogService } from 'vs/platform/dialogs/common/dialogs' ;
@@ -62,7 +62,12 @@ import { CancellationError } from 'vs/base/common/errors';
62
62
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService' ;
63
63
import { IExtensionsViewPaneContainer , VIEWLET_ID } from 'vs/workbench/contrib/extensions/common/extensions' ;
64
64
import { IPaneCompositePartService } from 'vs/workbench/services/panecomposite/browser/panecomposite' ;
65
- import { EditSessionRegistry } from 'vs/platform/workspace/browser/editSessionsStorageService' ;
65
+ import { WorkspaceStateSynchroniser } from 'vs/workbench/contrib/editSessions/common/workspaceStateSync' ;
66
+ import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile' ;
67
+ import { IRequestService } from 'vs/platform/request/common/request' ;
68
+ import { EditSessionsStoreClient } from 'vs/workbench/contrib/editSessions/common/editSessionsStorageClient' ;
69
+ import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity' ;
70
+ import { IWorkspaceIdentityService } from 'vs/workbench/services/workspaces/common/workspaceIdentityService' ;
66
71
67
72
registerSingleton ( IEditSessionsLogService , EditSessionsLogService , InstantiationType . Delayed ) ;
68
73
registerSingleton ( IEditSessionsStorageService , EditSessionsWorkbenchService , InstantiationType . Delayed ) ;
@@ -121,6 +126,9 @@ export class EditSessionsContribution extends Disposable implements IWorkbenchCo
121
126
122
127
private registeredCommands = new Set < string > ( ) ;
123
128
129
+ private workspaceStateSynchronizer : IUserDataSynchroniser | undefined ;
130
+ private editSessionsStorageClient : EditSessionsStoreClient | undefined ;
131
+
124
132
constructor (
125
133
@IEditSessionsStorageService private readonly editSessionsStorageService : IEditSessionsStorageService ,
126
134
@IFileService private readonly fileService : IFileService ,
@@ -147,17 +155,29 @@ export class EditSessionsContribution extends Disposable implements IWorkbenchCo
147
155
@IEditorService private readonly editorService : IEditorService ,
148
156
@IRemoteAgentService private readonly remoteAgentService : IRemoteAgentService ,
149
157
@IExtensionService private readonly extensionService : IExtensionService ,
158
+ @IRequestService private readonly requestService : IRequestService ,
159
+ @IUserDataProfilesService private readonly userDataProfilesService : IUserDataProfilesService ,
160
+ @IUriIdentityService private readonly uriIdentityService : IUriIdentityService ,
161
+ @IWorkspaceIdentityService private readonly workspaceIdentityService : IWorkspaceIdentityService ,
150
162
) {
151
163
super ( ) ;
152
164
165
+ this . shouldShowViewsContext = EDIT_SESSIONS_SHOW_VIEW . bindTo ( this . contextKeyService ) ;
166
+
167
+ if ( ! this . productService [ 'editSessions.store' ] ?. url ) {
168
+ return ;
169
+ }
170
+
171
+ this . editSessionsStorageClient = new EditSessionsStoreClient ( URI . parse ( this . productService [ 'editSessions.store' ] . url ) , this . productService , this . requestService , this . logService , this . environmentService , this . fileService , this . storageService ) ;
172
+ this . editSessionsStorageService . storeClient = this . editSessionsStorageClient ;
173
+ this . workspaceStateSynchronizer = new WorkspaceStateSynchroniser ( this . userDataProfilesService . defaultProfile , undefined , this . editSessionsStorageClient , this . logService , this . fileService , this . environmentService , this . telemetryService , this . configurationService , this . storageService , this . uriIdentityService , this . workspaceIdentityService , this . editSessionsStorageService ) ;
174
+
153
175
this . autoResumeEditSession ( ) ;
154
176
155
177
this . registerActions ( ) ;
156
178
this . registerViews ( ) ;
157
179
this . registerContributedEditSessionOptions ( ) ;
158
180
159
- this . shouldShowViewsContext = EDIT_SESSIONS_SHOW_VIEW . bindTo ( this . contextKeyService ) ;
160
-
161
181
this . _register ( this . fileService . registerProvider ( EditSessionsFileSystemProvider . SCHEMA , new EditSessionsFileSystemProvider ( this . editSessionsStorageService ) ) ) ;
162
182
this . lifecycleService . onWillShutdown ( ( e ) => {
163
183
if ( e . reason !== ShutdownReason . RELOAD && this . editSessionsStorageService . isSignedIn && this . configurationService . getValue ( 'workbench.experimental.cloudChanges.autoStore' ) === 'onShutdown' && ! isWeb ) {
@@ -482,7 +502,7 @@ export class EditSessionsContribution extends Disposable implements IWorkbenchCo
482
502
performance . mark ( 'code/willResumeEditSessionFromIdentifier' ) ;
483
503
484
504
progress ?. report ( { message : localize ( 'checkingForWorkingChanges' , 'Checking for pending cloud changes...' ) } ) ;
485
- const data = serializedData ? { editSession : JSON . parse ( serializedData ) , ref : '' } : await this . editSessionsStorageService . read ( ref ) ;
505
+ const data = serializedData ? { content : serializedData , ref : '' } : await this . editSessionsStorageService . read ( 'editSessions' , ref ) ;
486
506
if ( ! data ) {
487
507
if ( ref === undefined && ! silent ) {
488
508
this . notificationService . info ( localize ( 'no cloud changes' , 'There are no changes to resume from the cloud.' ) ) ;
@@ -494,7 +514,7 @@ export class EditSessionsContribution extends Disposable implements IWorkbenchCo
494
514
}
495
515
496
516
progress ?. report ( { message : resumeProgressOptionsTitle } ) ;
497
- const editSession = data . editSession ;
517
+ const editSession = JSON . parse ( data . content ) ;
498
518
ref = data . ref ;
499
519
500
520
if ( editSession . version > EditSessionSchemaVersion ) {
@@ -504,8 +524,8 @@ export class EditSessionsContribution extends Disposable implements IWorkbenchCo
504
524
}
505
525
506
526
try {
507
- const { changes, conflictingChanges, contributedStateHandlers } = await this . generateChanges ( editSession , ref , forceApplyUnrelatedChange , applyPartialMatch ) ;
508
- if ( changes . length === 0 && contributedStateHandlers . length === 0 ) {
527
+ const { changes, conflictingChanges } = await this . generateChanges ( editSession , ref , forceApplyUnrelatedChange , applyPartialMatch ) ;
528
+ if ( changes . length === 0 ) {
509
529
return ;
510
530
}
511
531
@@ -534,12 +554,10 @@ export class EditSessionsContribution extends Disposable implements IWorkbenchCo
534
554
}
535
555
}
536
556
537
- for ( const handleContributedState of contributedStateHandlers ) {
538
- handleContributedState ( ) ;
539
- }
557
+ await this . workspaceStateSynchronizer ?. apply ( false , { } ) ;
540
558
541
559
this . logService . info ( `Deleting edit session with ref ${ ref } after successfully applying it to current workspace...` ) ;
542
- await this . editSessionsStorageService . delete ( ref ) ;
560
+ await this . editSessionsStorageService . delete ( 'editSessions' , ref ) ;
543
561
this . logService . info ( `Deleted edit session with ref ${ ref } .` ) ;
544
562
545
563
this . telemetryService . publicLog2 < ResumeEvent , ResumeClassification > ( 'editSessions.resume.outcome' , { hashedId : hashedEditSessionId ( ref ) , outcome : 'resumeSucceeded' } ) ;
@@ -553,7 +571,6 @@ export class EditSessionsContribution extends Disposable implements IWorkbenchCo
553
571
554
572
private async generateChanges ( editSession : EditSession , ref : string , forceApplyUnrelatedChange = false , applyPartialMatch = false ) {
555
573
const changes : ( { uri : URI ; type : ChangeType ; contents : string | undefined } ) [ ] = [ ] ;
556
- const contributedStateHandlers : ( ( ) => void ) [ ] = [ ] ;
557
574
const conflictingChanges = [ ] ;
558
575
const workspaceFolders = this . contextService . getWorkspace ( ) . folders ;
559
576
const cancellationTokenSource = new CancellationTokenSource ( ) ;
@@ -623,44 +640,7 @@ export class EditSessionsContribution extends Disposable implements IWorkbenchCo
623
640
}
624
641
}
625
642
626
- const incomingFolderUrisToIdentifiers = new Map < string , [ string , EditSessionIdentityMatch ] > ( ) ;
627
- for ( const folder of editSession . folders ) {
628
- const { canonicalIdentity } = folder ;
629
- for ( const workspaceFolder of workspaceFolders ) {
630
- const identity = await this . editSessionIdentityService . getEditSessionIdentifier ( workspaceFolder , cancellationTokenSource . token ) ;
631
- if ( ! identity || ! canonicalIdentity || ! folder . absoluteUri ) {
632
- continue ;
633
- }
634
- const match = identity === canonicalIdentity
635
- ? EditSessionIdentityMatch . Complete
636
- : await this . editSessionIdentityService . provideEditSessionIdentityMatch ( workspaceFolder , identity , canonicalIdentity , cancellationTokenSource . token ) ;
637
- if ( ! match ) {
638
- continue ;
639
- }
640
- incomingFolderUrisToIdentifiers . set ( folder . absoluteUri . toString ( ) , [ workspaceFolder . uri . toString ( ) , match ] ) ;
641
- }
642
- }
643
-
644
- EditSessionRegistry . getEditSessionContributions ( ) . forEach ( ( [ key , contrib ] ) => {
645
- const state = editSession . state [ key ] ;
646
- if ( state ) {
647
- contributedStateHandlers . push ( ( ) => contrib . resumeState ( state , ( incomingUri : URI ) => {
648
- for ( const absoluteUri of incomingFolderUrisToIdentifiers . keys ( ) ) {
649
- if ( isEqualOrParent ( incomingUri , URI . parse ( absoluteUri ) ) ) {
650
- const [ workspaceFolderUri , match ] = incomingFolderUrisToIdentifiers . get ( absoluteUri ) ! ;
651
- if ( match === EditSessionIdentityMatch . Complete ) {
652
- const relativeFilePath = relativePath ( URI . parse ( absoluteUri ) , incomingUri ) ;
653
- return relativeFilePath ? joinPath ( URI . parse ( workspaceFolderUri ) , relativeFilePath ) : incomingUri ;
654
- }
655
-
656
- }
657
- }
658
- return incomingUri ;
659
- } ) ) ;
660
- }
661
- } ) ;
662
-
663
- return { changes, conflictingChanges, contributedStateHandlers } ;
643
+ return { changes, conflictingChanges } ;
664
644
}
665
645
666
646
private async willChangeLocalContents ( localChanges : Set < string > , uriWithIncomingChanges : URI , incomingChange : Change ) {
@@ -747,11 +727,8 @@ export class EditSessionsContribution extends Disposable implements IWorkbenchCo
747
727
folders . push ( { workingChanges, name : name ?? '' , canonicalIdentity : canonicalIdentity ?? undefined , absoluteUri : workspaceFolder ?. uri . toString ( ) } ) ;
748
728
}
749
729
750
- // Look through all registered contributions to gather additional state
751
- const contributedData : { [ key : string ] : unknown } = { } ;
752
- EditSessionRegistry . getEditSessionContributions ( ) . forEach ( ( [ key , contrib ] ) => {
753
- contributedData [ key ] = contrib . getStateToStore ( ) ;
754
- } ) ;
730
+ // Store contributed workspace state
731
+ await this . workspaceStateSynchronizer ?. sync ( null , { } ) ;
755
732
756
733
if ( ! hasEdits ) {
757
734
this . logService . info ( 'Skipped storing working changes in the cloud as there are no edits to store.' ) ;
@@ -761,11 +738,11 @@ export class EditSessionsContribution extends Disposable implements IWorkbenchCo
761
738
return undefined ;
762
739
}
763
740
764
- const data : EditSession = { folders, version : 2 , state : contributedData } ;
741
+ const data : EditSession = { folders, version : 2 } ;
765
742
766
743
try {
767
744
this . logService . info ( `Storing edit session...` ) ;
768
- const ref = await this . editSessionsStorageService . write ( data ) ;
745
+ const ref = await this . editSessionsStorageService . write ( 'editSessions' , data ) ;
769
746
this . logService . info ( `Stored edit session with ref ${ ref } .` ) ;
770
747
return ref ;
771
748
} catch ( ex ) {
0 commit comments