userDataProfilesManifestSync.ts ×14

Frontier kind: Code frontier

unlabeled · c_25677bf27574

23 tests · 26073 LOC · 133 files · introduces 0 tests · 57 LOC · 3 files

Introduces — evidence that enters the hierarchy at this concept

Code
19 ranges57 lines · 3 files
Tests
0 tests

Contains — complete concept membership

All code (extent)
4236 ranges26073 lines · 133 files · Browse complete extent
All tests (intent)
23 testsBrowse complete intent

Neighbourhood graph

The orange circle is the focus. Violet and green circles are every ancestor and descendant, broader and narrower, at any distance; blue squares and pink diamonds are the introduced files and exact introduced tests of every visible concept, not only the focus's. Arrows point from broader to narrower concepts and bridge only concepts omitted from this view. Undirected links show source or test introduction. Concept and file size follows LOC; exact test nodes use test-count units.

Introduced files, introduced tests, and structurally relevant concept specialization

In the embedded map, ordinary wheel input scrolls the page; use the visible controls to zoom and drag to pan. Open the full-screen map for canvas navigation: wheel pans, Ctrl/Command plus wheel zooms, and arrow keys pan when this region is focused. On touch screens, open the full-screen map to pan or pinch. If JavaScript or WebGL is unavailable, use the native relationship evidence on this page.

Graph controls are ready.

Interactive rendering requires JavaScript and WebGL. Use the native relationship evidence on this page while the interactive map is unavailable.

Native relationship evidence

Every exact file and test below is linked only from the concept that introduces it.

Introduced tests

Every collected test enters the hierarchy at exactly one concept.

No tests are introduced at this concept. Its intent tests are introduced by other concepts.

Introduced code

Every collected source range enters the hierarchy at exactly one concept.

3 files ranked by introduced lines: 57 introduced LOC across 19 ranges. Expand a file to inspect source; the > gutter marks introduced lines.

src/vs/platform/userDataSync/common/userDataProfilesManifestSync.ts 40 introduced LOC · 14 ranges

Open complete file

105
106 protected async getMergeResult(resourcePreview: IUserDataProfilesManifestResourcePreview, token: CancellationToken): Promise<IMergeResult> {
107 > return { ...resourcePreview.previewResult, hasConflicts: false }; userDataProfilesManifestSync.ts
108 > }
109
110 protected async getAcceptResult(resourcePreview: IUserDataProfilesManifestResourcePreview, resource: URI, content: string | null | undefined, token: CancellationToken): Promise<IAcceptResult> {
111 > /* Accept local resource */ userDataProfilesManifestSync.ts
112 > if (this.extUri.isEqual(resource, this.localResource)) {
113 return this.acceptLocal(resourcePreview);
114 }
116 > /* Accept remote resource */
117 > if (this.extUri.isEqual(resource, this.remoteResource)) {
118 return this.acceptRemote(resourcePreview);
119 }
121 > /* Accept preview resource */
122 > if (this.extUri.isEqual(resource, this.previewResource)) {
123 > return resourcePreview.previewResult;
124 > }
125
126 throw new Error(`Invalid Resource: ${resource.toString()}`);
128
129 private async acceptLocal(resourcePreview: IUserDataProfilesManifestResourcePreview): Promise<IUserDataProfileManifestResourceMergeResult> {
208
209 if (remoteChange !== Change.None) {
210 > this.logService.trace(`${this.syncResourceLogLabel}: Updating remote profiles...`); userDataProfilesManifestSync.ts
211 > const addedCollections: string[] = [];
212 > const canAddRemoteProfiles = remoteProfiles.length + (remote?.added.length ?? 0) <= 20;
213 > if (canAddRemoteProfiles) {
214 > for (const profile of remote?.added || []) {
215 > const collection = await this.userDataSyncStoreService.createCollection(this.syncHeaders);
216 > this.logService.trace(`${this.syncResourceLogLabel}: Created collection "${collection}" for "${profile.name}".`);
217 > addedCollections.push(collection);
218 > remoteProfiles.push({ id: profile.id, name: profile.name, collection, icon: profile.icon, useDefaultFlags: profile.useDefaultFlags });
219 > }
220 > } else {
221 this.logService.info(`${this.syncResourceLogLabel}: Could not create remote profiles as there are too many profiles.`);
222 }
223 > for (const profile of remote?.removed || []) { userDataProfilesManifestSync.ts
224 remoteProfiles.splice(remoteProfiles.findIndex(({ id }) => profile.id === id), 1);
225 }
226 > for (const profile of remote?.updated || []) { userDataProfilesManifestSync.ts
227 const profileToBeUpdated = remoteProfiles.find(({ id }) => profile.id === id);
228 if (profileToBeUpdated) {
230 }
231 }
233 > try {
234 > remoteUserData = await this.updateRemoteProfiles(remoteProfiles, force ? null : remoteUserData.ref);
235 > this.logService.info(`${this.syncResourceLogLabel}: Updated remote profiles.${canAddRemoteProfiles && remote?.added.length ? ` Added: ${JSON.stringify(remote.added.map(e => e.name))}.` : ''}${remote?.updated.length ? ` Updated: ${JSON.stringify(remote.updated.map(e => e.name))}.` : ''}${remote?.removed.length ? ` Removed: ${JSON.stringify(remote.removed.map(e => e.name))}.` : ''}`);
236 > } catch (error) {
237 if (addedCollections.length) {
238 this.logService.info(`${this.syncResourceLogLabel}: Failed to update remote profiles. Cleaning up added collections...`);
243 throw error;
244 }
246 > for (const profile of remote?.removed || []) {
247 await this.userDataSyncStoreService.deleteCollection(profile.collection, this.syncHeaders);
248 }
250
251 if (lastSyncUserData?.ref !== remoteUserData.ref) {
258
259 async updateRemoteProfiles(profiles: ISyncUserDataProfile[], ref: string | null): Promise<IRemoteUserData> {
260 > return this.updateRemoteUserData(this.stringifyRemoteProfiles(profiles), ref); userDataProfilesManifestSync.ts
261 > }
262
263 async hasLocalData(): Promise<boolean> {
282
283 private stringifyRemoteProfiles(profiles: ISyncUserDataProfile[]): string {
284 > return JSON.stringify([...profiles].sort((a, b) => a.name.localeCompare(b.name))); userDataProfilesManifestSync.ts
285 > }
286
287 }
293
294 export function parseUserDataProfilesManifest(syncData: ISyncData): ISyncUserDataProfile[] {
295 > return JSON.parse(syncData.content); userDataProfilesManifestSync.ts
296 > }
297
298
src/vs/platform/userDataSync/common/userDataSyncStoreService.ts 11 introduced LOC · 3 ranges

Open complete file

265
266 async createCollection(headers: IHeaders = {}): Promise<string> {
267 > if (!this.userDataSyncStoreUrl) { userDataSyncStoreService.ts
268 throw new Error('No settings sync store url configured.');
269 }
271 > const url = joinPath(this.userDataSyncStoreUrl, 'collection').toString();
272 > headers = { ...headers };
273 > headers['Content-Type'] = Mimes.text;
274 >
275 > const context = await this.request(url, { type: 'POST', headers, callSite: 'userDataSync.createCollection' }, [], CancellationToken.None);
276 > const collectionId = await asTextOrError(context);
277 > if (!collectionId) {
278 throw new UserDataSyncStoreError('Server did not return the collection id', url, UserDataSyncErrorCode.NoCollection, context.res.statusCode, context.res.headers[HEADER_OPERATION_ID]);
279 }
280 > return collectionId; userDataSyncStoreService.ts
281 > }
282
283 async deleteCollection(collection?: string, headers: IHeaders = {}): Promise<void> {
src/vs/platform/userDataSync/test/common/userDataSyncClient.ts 6 introduced LOC · 2 ranges

Open complete file

259 }
260 if (options.type === 'POST' && segments.length === 1 && segments[0] === 'collection') {
261 > return this.createCollection(); userDataSyncClient.ts
262 > }
263 return this.toResponse(501);
264 }
346
347 private async createCollection(): Promise<IRequestContext> {
348 > const collectionId = `${++this.collectionCounter}`; userDataSyncClient.ts
349 > this.collections.set(collectionId, new Map());
350 > return this.toResponse(200, {}, collectionId);
351 > }
352
353 async clear(headers?: IHeaders): Promise<IRequestContext> {