mirror of
https://github.com/microsoft/vscode.git
synced 2026-07-13 23:44:09 +01:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -43,9 +43,10 @@ export interface IStorageDatabase {
|
||||
|
||||
export interface IStorage extends IDisposable {
|
||||
|
||||
readonly onDidChangeStorage: Event<string>;
|
||||
|
||||
readonly items: Map<string, string>;
|
||||
readonly size: number;
|
||||
readonly onDidChangeStorage: Event<string>;
|
||||
|
||||
init(): Promise<void>;
|
||||
|
||||
@@ -61,6 +62,8 @@ export interface IStorage extends IDisposable {
|
||||
set(key: string, value: string | boolean | number | undefined | null): Promise<void>;
|
||||
delete(key: string): Promise<void>;
|
||||
|
||||
whenFlushed(): Promise<void>;
|
||||
|
||||
close(): Promise<void>;
|
||||
}
|
||||
|
||||
@@ -86,6 +89,8 @@ export class Storage extends Disposable implements IStorage {
|
||||
private pendingDeletes = new Set<string>();
|
||||
private pendingInserts = new Map<string, string>();
|
||||
|
||||
private readonly whenFlushedCallbacks: Function[] = [];
|
||||
|
||||
constructor(
|
||||
protected readonly database: IStorageDatabase,
|
||||
private readonly options: IStorageOptions = Object.create(null)
|
||||
@@ -273,8 +278,12 @@ export class Storage extends Disposable implements IStorage {
|
||||
await this.database.close(() => this.cache);
|
||||
}
|
||||
|
||||
private get hasPending() {
|
||||
return this.pendingInserts.size > 0 || this.pendingDeletes.size > 0;
|
||||
}
|
||||
|
||||
private flushPending(): Promise<void> {
|
||||
if (this.pendingInserts.size === 0 && this.pendingDeletes.size === 0) {
|
||||
if (!this.hasPending) {
|
||||
return Promise.resolve(); // return early if nothing to do
|
||||
}
|
||||
|
||||
@@ -285,8 +294,23 @@ export class Storage extends Disposable implements IStorage {
|
||||
this.pendingDeletes = new Set<string>();
|
||||
this.pendingInserts = new Map<string, string>();
|
||||
|
||||
// Update in storage
|
||||
return this.database.updateItems(updateRequest);
|
||||
// Update in storage and release any
|
||||
// waiters we have once done
|
||||
return this.database.updateItems(updateRequest).finally(() => {
|
||||
if (!this.hasPending) {
|
||||
while (this.whenFlushedCallbacks.length) {
|
||||
this.whenFlushedCallbacks.pop()?.();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
whenFlushed(): Promise<void> {
|
||||
if (!this.hasPending) {
|
||||
return Promise.resolve(); // return early if nothing to do
|
||||
}
|
||||
|
||||
return new Promise(resolve => this.whenFlushedCallbacks.push(resolve));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -45,11 +45,16 @@ suite('Storage Library', function () {
|
||||
changes.add(key);
|
||||
});
|
||||
|
||||
await storage.whenFlushed(); // returns immediately when no pending updates
|
||||
|
||||
// Simple updates
|
||||
const set1Promise = storage.set('bar', 'foo');
|
||||
const set2Promise = storage.set('barNumber', 55);
|
||||
const set3Promise = storage.set('barBoolean', true);
|
||||
|
||||
let flushPromiseResolved = false;
|
||||
storage.whenFlushed().then(() => flushPromiseResolved = true);
|
||||
|
||||
equal(storage.get('bar'), 'foo');
|
||||
equal(storage.getNumber('barNumber'), 55);
|
||||
equal(storage.getBoolean('barBoolean'), true);
|
||||
@@ -62,6 +67,7 @@ suite('Storage Library', function () {
|
||||
let setPromiseResolved = false;
|
||||
await Promise.all([set1Promise, set2Promise, set3Promise]).then(() => setPromiseResolved = true);
|
||||
equal(setPromiseResolved, true);
|
||||
equal(flushPromiseResolved, true);
|
||||
|
||||
changes = new Set<string>();
|
||||
|
||||
@@ -166,6 +172,9 @@ suite('Storage Library', function () {
|
||||
const set1Promise = storage.set('foo', 'bar');
|
||||
const set2Promise = storage.set('bar', 'foo');
|
||||
|
||||
let flushPromiseResolved = false;
|
||||
storage.whenFlushed().then(() => flushPromiseResolved = true);
|
||||
|
||||
equal(storage.get('foo'), 'bar');
|
||||
equal(storage.get('bar'), 'foo');
|
||||
|
||||
@@ -175,6 +184,7 @@ suite('Storage Library', function () {
|
||||
await storage.close();
|
||||
|
||||
equal(setPromiseResolved, true);
|
||||
equal(flushPromiseResolved, true);
|
||||
|
||||
storage = new Storage(new SQLiteStorageDatabase(join(storageDir, 'storage.db')));
|
||||
await storage.init();
|
||||
@@ -226,6 +236,9 @@ suite('Storage Library', function () {
|
||||
const set2Promise = storage.set('foo', 'bar2');
|
||||
const set3Promise = storage.set('foo', 'bar3');
|
||||
|
||||
let flushPromiseResolved = false;
|
||||
storage.whenFlushed().then(() => flushPromiseResolved = true);
|
||||
|
||||
equal(storage.get('foo'), 'bar3');
|
||||
equal(changes.size, 1);
|
||||
ok(changes.has('foo'));
|
||||
@@ -233,6 +246,7 @@ suite('Storage Library', function () {
|
||||
let setPromiseResolved = false;
|
||||
await Promise.all([set1Promise, set2Promise, set3Promise]).then(() => setPromiseResolved = true);
|
||||
ok(setPromiseResolved);
|
||||
ok(flushPromiseResolved);
|
||||
|
||||
changes = new Set<string>();
|
||||
|
||||
|
||||
@@ -26,7 +26,6 @@ import { IStorageService, StorageScope } from 'vs/platform/storage/common/storag
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import { EditorOption } from 'vs/editor/common/config/editorOptions';
|
||||
import { IStorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys';
|
||||
|
||||
const SEARCH_STRING_MAX_LENGTH = 524288;
|
||||
|
||||
@@ -411,7 +410,6 @@ export class FindController extends CommonFindController implements IFindControl
|
||||
@IThemeService private readonly _themeService: IThemeService,
|
||||
@INotificationService private readonly _notificationService: INotificationService,
|
||||
@IStorageService _storageService: IStorageService,
|
||||
@IStorageKeysSyncRegistryService private readonly _storageKeysSyncRegistryService: IStorageKeysSyncRegistryService,
|
||||
@IClipboardService clipboardService: IClipboardService,
|
||||
) {
|
||||
super(editor, _contextKeyService, _storageService, clipboardService);
|
||||
@@ -468,7 +466,7 @@ export class FindController extends CommonFindController implements IFindControl
|
||||
}
|
||||
|
||||
private _createFindWidget() {
|
||||
this._widget = this._register(new FindWidget(this._editor, this, this._state, this._contextViewService, this._keybindingService, this._contextKeyService, this._themeService, this._storageService, this._notificationService, this._storageKeysSyncRegistryService));
|
||||
this._widget = this._register(new FindWidget(this._editor, this, this._state, this._contextViewService, this._keybindingService, this._contextKeyService, this._themeService, this._storageService, this._notificationService));
|
||||
this._findOptionsWidget = this._register(new FindOptionsWidget(this._editor, this._state, this._keybindingService, this._themeService));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,9 +34,8 @@ import { contrastBorder, editorFindMatch, editorFindMatchBorder, editorFindMatch
|
||||
import { IColorTheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService';
|
||||
import { ContextScopedFindInput, ContextScopedReplaceInput } from 'vs/platform/browser/contextScopedHistoryWidget';
|
||||
import { AccessibilitySupport } from 'vs/platform/accessibility/common/accessibility';
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import { IStorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys';
|
||||
import { Codicon, registerIcon } from 'vs/base/common/codicons';
|
||||
|
||||
const findSelectionIcon = registerIcon('find-selection', Codicon.selection);
|
||||
@@ -164,7 +163,6 @@ export class FindWidget extends Widget implements IOverlayWidget, IVerticalSashL
|
||||
themeService: IThemeService,
|
||||
storageService: IStorageService,
|
||||
notificationService: INotificationService,
|
||||
storageKeysSyncRegistryService: IStorageKeysSyncRegistryService
|
||||
) {
|
||||
super();
|
||||
this._codeEditor = codeEditor;
|
||||
@@ -176,7 +174,6 @@ export class FindWidget extends Widget implements IOverlayWidget, IVerticalSashL
|
||||
this._storageService = storageService;
|
||||
this._notificationService = notificationService;
|
||||
|
||||
storageKeysSyncRegistryService.registerStorageKey({ key: ctrlEnterReplaceAllWarningPromptedKey, version: 1 });
|
||||
this._ctrlEnterReplaceAllWarningPrompted = !!storageService.getBoolean(ctrlEnterReplaceAllWarningPromptedKey, StorageScope.GLOBAL);
|
||||
|
||||
this._isVisible = false;
|
||||
@@ -880,7 +877,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IVerticalSashL
|
||||
);
|
||||
|
||||
this._ctrlEnterReplaceAllWarningPrompted = true;
|
||||
this._storageService.store(ctrlEnterReplaceAllWarningPromptedKey, true, StorageScope.GLOBAL);
|
||||
this._storageService.store2(ctrlEnterReplaceAllWarningPromptedKey, true, StorageScope.GLOBAL, StorageTarget.USER);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -61,17 +61,20 @@ suite('Multicursor selection', () => {
|
||||
let serviceCollection = new ServiceCollection();
|
||||
serviceCollection.set(IStorageService, {
|
||||
_serviceBrand: undefined,
|
||||
onDidChangeStorage: Event.None,
|
||||
onDidChangeValue: Event.None,
|
||||
onDidChangeTarget: Event.None,
|
||||
onWillSaveState: Event.None,
|
||||
get: (key: string) => queryState[key],
|
||||
getBoolean: (key: string) => !!queryState[key],
|
||||
getNumber: (key: string) => undefined!,
|
||||
store2: (key: string, value: any) => { queryState[key] = value; return Promise.resolve(); },
|
||||
store: (key: string, value: any) => { queryState[key] = value; return Promise.resolve(); },
|
||||
remove: (key) => undefined,
|
||||
logStorage: () => undefined,
|
||||
migrate: (toWorkspace) => Promise.resolve(undefined),
|
||||
flush: () => undefined,
|
||||
isNew: () => true
|
||||
flush: () => Promise.resolve(undefined),
|
||||
isNew: () => true,
|
||||
keys: () => []
|
||||
} as IStorageService);
|
||||
|
||||
test('issue #8817: Cursor position changes when you cancel multicursor', () => {
|
||||
|
||||
@@ -584,6 +584,10 @@ export class SuggestController implements IEditorContribution {
|
||||
toggleSuggestionFocus(): void {
|
||||
this.widget.value.toggleDetailsFocus();
|
||||
}
|
||||
|
||||
resetWidgetSize(): void {
|
||||
this.widget.value.resetPersistedSize();
|
||||
}
|
||||
}
|
||||
|
||||
export class TriggerSuggestAction extends EditorAction {
|
||||
@@ -875,3 +879,20 @@ registerEditorCommand(new SuggestCommand({
|
||||
primary: KeyMod.Shift | KeyCode.Tab
|
||||
}
|
||||
}));
|
||||
|
||||
|
||||
registerEditorAction(class extends EditorAction {
|
||||
|
||||
constructor() {
|
||||
super({
|
||||
id: 'editor.action.resetSuggestSize',
|
||||
label: nls.localize('suggest.reset.label', "Reset Suggest Widget Size"),
|
||||
alias: 'Reset Suggest Widget Size',
|
||||
precondition: undefined
|
||||
});
|
||||
}
|
||||
|
||||
run(_accessor: ServicesAccessor, editor: ICodeEditor): void {
|
||||
SuggestController.get(editor).resetWidgetSize();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -84,6 +84,10 @@ class PersistedWidgetSize {
|
||||
store(size: dom.Dimension) {
|
||||
this._service.store(this._key, JSON.stringify(size), StorageScope.GLOBAL);
|
||||
}
|
||||
|
||||
reset(): void {
|
||||
this._service.remove(this._key, StorageScope.GLOBAL);
|
||||
}
|
||||
}
|
||||
|
||||
export class SuggestWidget implements IDisposable {
|
||||
@@ -148,11 +152,13 @@ export class SuggestWidget implements IDisposable {
|
||||
this._persistedSize = new PersistedWidgetSize(_storageService, editor);
|
||||
|
||||
let persistedSize: dom.Dimension | undefined;
|
||||
let currentSize: dom.Dimension | undefined;
|
||||
let persistHeight = false;
|
||||
let persistWidth = false;
|
||||
this._disposables.add(this.element.onDidWillResize(() => {
|
||||
this._contentWidget.lockPreference();
|
||||
persistedSize = this._persistedSize.restore();
|
||||
currentSize = this.element.size;
|
||||
}));
|
||||
this._disposables.add(this.element.onDidResize(e => {
|
||||
|
||||
@@ -161,14 +167,15 @@ export class SuggestWidget implements IDisposable {
|
||||
persistHeight = persistHeight || !!e.north || !!e.south;
|
||||
persistWidth = persistWidth || !!e.east || !!e.west;
|
||||
if (e.done) {
|
||||
|
||||
// only store width or height value that have changed
|
||||
// only store width or height value that have changed and also
|
||||
// only store changes that are above a certain threshold
|
||||
const threshold = Math.floor(this.getLayoutInfo().itemHeight / 3);
|
||||
let { width, height } = this.element.size;
|
||||
if (persistedSize) {
|
||||
if (!persistHeight) {
|
||||
if (persistedSize && currentSize) {
|
||||
if (!persistHeight || Math.abs(currentSize.height - height) > threshold) {
|
||||
height = persistedSize.height;
|
||||
}
|
||||
if (!persistWidth) {
|
||||
if (!persistWidth || Math.abs(currentSize.width - width) > threshold) {
|
||||
width = persistedSize.width;
|
||||
}
|
||||
}
|
||||
@@ -177,6 +184,7 @@ export class SuggestWidget implements IDisposable {
|
||||
// reset working state
|
||||
this._contentWidget.unlockPreference();
|
||||
persistedSize = undefined;
|
||||
currentSize = undefined;
|
||||
persistHeight = false;
|
||||
persistWidth = false;
|
||||
}
|
||||
@@ -677,6 +685,10 @@ export class SuggestWidget implements IDisposable {
|
||||
}
|
||||
}
|
||||
|
||||
resetPersistedSize(): void {
|
||||
this._persistedSize.reset();
|
||||
}
|
||||
|
||||
hideWidget(): void {
|
||||
this._loadingTimeout?.dispose();
|
||||
this._setState(State.Hidden);
|
||||
|
||||
@@ -7,7 +7,7 @@ import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { IExtensionIdentifier, IGlobalExtensionEnablementService, DISABLED_EXTENSIONS_STORAGE_PATH } from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
|
||||
import { IStorageService, StorageScope, IStorageChangeEvent } from 'vs/platform/storage/common/storage';
|
||||
import { IStorageService, StorageScope, IStorageValueChangeEvent } from 'vs/platform/storage/common/storage';
|
||||
import { isUndefinedOrNull } from 'vs/base/common/types';
|
||||
|
||||
export class GlobalExtensionEnablementService extends Disposable implements IGlobalExtensionEnablementService {
|
||||
@@ -96,7 +96,7 @@ export class StorageManager extends Disposable {
|
||||
|
||||
constructor(private storageService: IStorageService) {
|
||||
super();
|
||||
this._register(storageService.onDidChangeStorage(e => this.onDidStorageChange(e)));
|
||||
this._register(storageService.onDidChangeValue(e => this.onDidStorageChange(e)));
|
||||
}
|
||||
|
||||
get(key: string, scope: StorageScope): IExtensionIdentifier[] {
|
||||
@@ -127,7 +127,7 @@ export class StorageManager extends Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
private onDidStorageChange(storageChangeEvent: IStorageChangeEvent): void {
|
||||
private onDidStorageChange(storageChangeEvent: IStorageValueChangeEvent): void {
|
||||
if (storageChangeEvent.scope === StorageScope.GLOBAL) {
|
||||
if (!isUndefinedOrNull(this.storage[storageChangeEvent.key])) {
|
||||
const newValue = this._get(storageChangeEvent.key, storageChangeEvent.scope);
|
||||
|
||||
@@ -11,7 +11,7 @@ import { DisposableStore, Disposable, IDisposable } from 'vs/base/common/lifecyc
|
||||
import { or, matchesPrefix, matchesWords, matchesContiguousSubString } from 'vs/base/common/filters';
|
||||
import { withNullAsUndefined } from 'vs/base/common/types';
|
||||
import { LRUCache } from 'vs/base/common/map';
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
@@ -21,7 +21,6 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { isPromiseCanceledError } from 'vs/base/common/errors';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import { toErrorMessage } from 'vs/base/common/errorMessage';
|
||||
import { IStorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys';
|
||||
|
||||
export interface ICommandQuickPick extends IPickerQuickAccessItem {
|
||||
commandId: string;
|
||||
@@ -204,14 +203,9 @@ export class CommandsHistory extends Disposable {
|
||||
constructor(
|
||||
@IStorageService private readonly storageService: IStorageService,
|
||||
@IConfigurationService private readonly configurationService: IConfigurationService,
|
||||
@IStorageKeysSyncRegistryService storageKeysSyncRegistryService: IStorageKeysSyncRegistryService
|
||||
) {
|
||||
super();
|
||||
|
||||
// opt-in to syncing
|
||||
storageKeysSyncRegistryService.registerStorageKey({ key: CommandsHistory.PREF_KEY_CACHE, version: 1 });
|
||||
storageKeysSyncRegistryService.registerStorageKey({ key: CommandsHistory.PREF_KEY_COUNTER, version: 1 });
|
||||
|
||||
this.updateConfiguration();
|
||||
this.load();
|
||||
|
||||
@@ -279,8 +273,8 @@ export class CommandsHistory extends Disposable {
|
||||
const serializedCache: ISerializedCommandHistory = { usesLRU: true, entries: [] };
|
||||
CommandsHistory.cache.forEach((value, key) => serializedCache.entries.push({ key, value }));
|
||||
|
||||
storageService.store(CommandsHistory.PREF_KEY_CACHE, JSON.stringify(serializedCache), StorageScope.GLOBAL);
|
||||
storageService.store(CommandsHistory.PREF_KEY_COUNTER, CommandsHistory.counter, StorageScope.GLOBAL);
|
||||
storageService.store2(CommandsHistory.PREF_KEY_CACHE, JSON.stringify(serializedCache), StorageScope.GLOBAL, StorageTarget.USER);
|
||||
storageService.store2(CommandsHistory.PREF_KEY_COUNTER, CommandsHistory.counter, StorageScope.GLOBAL, StorageTarget.USER);
|
||||
}
|
||||
|
||||
static getConfiguredCommandHistoryLength(configurationService: IConfigurationService): number {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import { Disposable, IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { Emitter } from 'vs/base/common/event';
|
||||
import { IStorageChangeEvent, IStorageService, StorageScope, IWillSaveStateEvent, WillSaveStateReason, logStorage, IS_NEW_KEY } from 'vs/platform/storage/common/storage';
|
||||
import { StorageScope, logStorage, IS_NEW_KEY, AbstractStorageService } from 'vs/platform/storage/common/storage';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { IWorkspaceInitializationPayload } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { IFileService, FileChangeType } from 'vs/platform/files/common/files';
|
||||
@@ -16,15 +16,7 @@ import { runWhenIdle, RunOnceScheduler } from 'vs/base/common/async';
|
||||
import { VSBuffer } from 'vs/base/common/buffer';
|
||||
import { assertIsDefined, assertAllDefined } from 'vs/base/common/types';
|
||||
|
||||
export class BrowserStorageService extends Disposable implements IStorageService {
|
||||
|
||||
declare readonly _serviceBrand: undefined;
|
||||
|
||||
private readonly _onDidChangeStorage = this._register(new Emitter<IStorageChangeEvent>());
|
||||
readonly onDidChangeStorage = this._onDidChangeStorage.event;
|
||||
|
||||
private readonly _onWillSaveState = this._register(new Emitter<IWillSaveStateEvent>());
|
||||
readonly onWillSaveState = this._onWillSaveState.event;
|
||||
export class BrowserStorageService extends AbstractStorageService {
|
||||
|
||||
private globalStorage: IStorage | undefined;
|
||||
private workspaceStorage: IStorage | undefined;
|
||||
@@ -40,6 +32,10 @@ export class BrowserStorageService extends Disposable implements IStorageService
|
||||
private readonly periodicFlushScheduler = this._register(new RunOnceScheduler(() => this.doFlushWhenIdle(), 5000 /* every 5s */));
|
||||
private runWhenIdleDisposable: IDisposable | undefined = undefined;
|
||||
|
||||
get hasPendingUpdate(): boolean {
|
||||
return (!!this.globalStorageDatabase && this.globalStorageDatabase.hasPendingUpdate) || (!!this.workspaceStorageDatabase && this.workspaceStorageDatabase.hasPendingUpdate);
|
||||
}
|
||||
|
||||
constructor(
|
||||
@IEnvironmentService private readonly environmentService: IEnvironmentService,
|
||||
@IFileService private readonly fileService: IFileService
|
||||
@@ -66,13 +62,13 @@ export class BrowserStorageService extends Disposable implements IStorageService
|
||||
|
||||
this.workspaceStorageDatabase = this._register(new FileStorageDatabase(this.workspaceStorageFile, false /* do not watch for external changes */, this.fileService));
|
||||
this.workspaceStorage = this._register(new Storage(this.workspaceStorageDatabase));
|
||||
this._register(this.workspaceStorage.onDidChangeStorage(key => this._onDidChangeStorage.fire({ key, scope: StorageScope.WORKSPACE })));
|
||||
this._register(this.workspaceStorage.onDidChangeStorage(key => this.emitDidChangeValue(StorageScope.WORKSPACE, key)));
|
||||
|
||||
// Global Storage
|
||||
this.globalStorageFile = joinPath(stateRoot, 'global.json');
|
||||
this.globalStorageDatabase = this._register(new FileStorageDatabase(this.globalStorageFile, true /* watch for external changes */, this.fileService));
|
||||
this.globalStorage = this._register(new Storage(this.globalStorageDatabase));
|
||||
this._register(this.globalStorage.onDidChangeStorage(key => this._onDidChangeStorage.fire({ key, scope: StorageScope.GLOBAL })));
|
||||
this._register(this.globalStorage.onDidChangeStorage(key => this.emitDidChangeValue(StorageScope.GLOBAL, key)));
|
||||
|
||||
// Init both
|
||||
await Promise.all([
|
||||
@@ -122,11 +118,11 @@ export class BrowserStorageService extends Disposable implements IStorageService
|
||||
return this.getStorage(scope).getNumber(key, fallbackValue);
|
||||
}
|
||||
|
||||
store(key: string, value: string | boolean | number | undefined | null, scope: StorageScope): void {
|
||||
protected doStore(key: string, value: string | boolean | number | undefined | null, scope: StorageScope): void {
|
||||
this.getStorage(scope).set(key, value);
|
||||
}
|
||||
|
||||
remove(key: string, scope: StorageScope): void {
|
||||
protected doRemove(key: string, scope: StorageScope): void {
|
||||
this.getStorage(scope).delete(key);
|
||||
}
|
||||
|
||||
@@ -149,6 +145,13 @@ export class BrowserStorageService extends Disposable implements IStorageService
|
||||
throw new Error('Migrating storage is currently unsupported in Web');
|
||||
}
|
||||
|
||||
protected async doFlush(): Promise<void> {
|
||||
await Promise.all([
|
||||
this.getStorage(StorageScope.GLOBAL).whenFlushed(),
|
||||
this.getStorage(StorageScope.WORKSPACE).whenFlushed()
|
||||
]);
|
||||
}
|
||||
|
||||
private doFlushWhenIdle(): void {
|
||||
|
||||
// Dispose any previous idle runner
|
||||
@@ -175,14 +178,6 @@ export class BrowserStorageService extends Disposable implements IStorageService
|
||||
});
|
||||
}
|
||||
|
||||
get hasPendingUpdate(): boolean {
|
||||
return (!!this.globalStorageDatabase && this.globalStorageDatabase.hasPendingUpdate) || (!!this.workspaceStorageDatabase && this.workspaceStorageDatabase.hasPendingUpdate);
|
||||
}
|
||||
|
||||
flush(): void {
|
||||
this._onWillSaveState.fire({ reason: WillSaveStateReason.NONE });
|
||||
}
|
||||
|
||||
close(): void {
|
||||
// We explicitly do not close our DBs because writing data onBeforeUnload()
|
||||
// can result in unexpected results. Namely, it seems that - even though this
|
||||
@@ -195,10 +190,6 @@ export class BrowserStorageService extends Disposable implements IStorageService
|
||||
this.dispose();
|
||||
}
|
||||
|
||||
isNew(scope: StorageScope): boolean {
|
||||
return this.getBoolean(IS_NEW_KEY, scope) === true;
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
dispose(this.runWhenIdleDisposable);
|
||||
this.runWhenIdleDisposable = undefined;
|
||||
|
||||
@@ -4,12 +4,13 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { Event, Emitter, PauseableEmitter } from 'vs/base/common/event';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { isUndefinedOrNull } from 'vs/base/common/types';
|
||||
import { IWorkspaceInitializationPayload } from 'vs/platform/workspaces/common/workspaces';
|
||||
|
||||
export const IS_NEW_KEY = '__$__isNewStorageMarker';
|
||||
const TARGET_KEY = '__$__targetStorageMarker';
|
||||
|
||||
export const IStorageService = createDecorator<IStorageService>('storageService');
|
||||
|
||||
@@ -29,7 +30,12 @@ export interface IStorageService {
|
||||
/**
|
||||
* Emitted whenever data is updated or deleted.
|
||||
*/
|
||||
readonly onDidChangeStorage: Event<IStorageChangeEvent>;
|
||||
readonly onDidChangeValue: Event<IStorageValueChangeEvent>;
|
||||
|
||||
/**
|
||||
* Emitted whenever target of a storage entry changes.
|
||||
*/
|
||||
readonly onDidChangeTarget: Event<IStorageTargetChangeEvent>;
|
||||
|
||||
/**
|
||||
* Emitted when the storage is about to persist. This is the right time
|
||||
@@ -48,45 +54,55 @@ export interface IStorageService {
|
||||
|
||||
/**
|
||||
* Retrieve an element stored with the given key from storage. Use
|
||||
* the provided defaultValue if the element is null or undefined.
|
||||
* the provided `defaultValue` if the element is `null` or `undefined`.
|
||||
*
|
||||
* The scope argument allows to define the scope of the storage
|
||||
* operation to either the current workspace only or all workspaces.
|
||||
* @param scope allows to define the scope of the storage operation
|
||||
* to either the current workspace only or all workspaces.
|
||||
*/
|
||||
get(key: string, scope: StorageScope, fallbackValue: string): string;
|
||||
get(key: string, scope: StorageScope, fallbackValue?: string): string | undefined;
|
||||
|
||||
/**
|
||||
* Retrieve an element stored with the given key from storage. Use
|
||||
* the provided defaultValue if the element is null or undefined. The element
|
||||
* will be converted to a boolean.
|
||||
* the provided `defaultValue` if the element is `null` or `undefined`.
|
||||
* The element will be converted to a `boolean`.
|
||||
*
|
||||
* The scope argument allows to define the scope of the storage
|
||||
* operation to either the current workspace only or all workspaces.
|
||||
* @param scope allows to define the scope of the storage operation
|
||||
* to either the current workspace only or all workspaces.
|
||||
*/
|
||||
getBoolean(key: string, scope: StorageScope, fallbackValue: boolean): boolean;
|
||||
getBoolean(key: string, scope: StorageScope, fallbackValue?: boolean): boolean | undefined;
|
||||
|
||||
/**
|
||||
* Retrieve an element stored with the given key from storage. Use
|
||||
* the provided defaultValue if the element is null or undefined. The element
|
||||
* will be converted to a number using parseInt with a base of 10.
|
||||
* the provided `defaultValue` if the element is `null` or `undefined`.
|
||||
* The element will be converted to a `number` using `parseInt` with a
|
||||
* base of `10`.
|
||||
*
|
||||
* The scope argument allows to define the scope of the storage
|
||||
* operation to either the current workspace only or all workspaces.
|
||||
* @param scope allows to define the scope of the storage operation
|
||||
* to either the current workspace only or all workspaces.
|
||||
*/
|
||||
getNumber(key: string, scope: StorageScope, fallbackValue: number): number;
|
||||
getNumber(key: string, scope: StorageScope, fallbackValue?: number): number | undefined;
|
||||
|
||||
/**
|
||||
* Store a value under the given key to storage. The value will be converted to a string.
|
||||
* Storing either undefined or null will remove the entry under the key.
|
||||
*
|
||||
* The scope argument allows to define the scope of the storage
|
||||
* operation to either the current workspace only or all workspaces.
|
||||
* @deprecated use store2 instead
|
||||
*/
|
||||
store(key: string, value: string | boolean | number | undefined | null, scope: StorageScope): void;
|
||||
|
||||
/**
|
||||
* Store a value under the given key to storage. The value will be
|
||||
* converted to a `string`. Storing either `undefined` or `null` will
|
||||
* remove the entry under the key.
|
||||
*
|
||||
* @param scope allows to define the scope of the storage operation
|
||||
* to either the current workspace only or all workspaces.
|
||||
*
|
||||
* @param target allows to define the target of the storage operation
|
||||
* to either the current machine or user.
|
||||
*/
|
||||
store2(key: string, value: string | boolean | number | undefined | null, scope: StorageScope, target: StorageTarget): void;
|
||||
|
||||
/**
|
||||
* Delete an element stored under the provided key from storage.
|
||||
*
|
||||
@@ -95,6 +111,22 @@ export interface IStorageService {
|
||||
*/
|
||||
remove(key: string, scope: StorageScope): void;
|
||||
|
||||
/**
|
||||
* Returns all the keys used in the storage for the provided `scope`
|
||||
* and `target`.
|
||||
*
|
||||
* Note: this will NOT return all keys stored in the storage layer.
|
||||
* Some keys may not have an associated `StorageTarget` and thus
|
||||
* will be excluded from the results.
|
||||
*
|
||||
* @param scope allows to define the scope for the keys
|
||||
* to either the current workspace only or all workspaces.
|
||||
*
|
||||
* @param target allows to define the target for the keys
|
||||
* to either the current machine or user.
|
||||
*/
|
||||
keys(scope: StorageScope, target: StorageTarget): string[];
|
||||
|
||||
/**
|
||||
* Log the contents of the storage to the console.
|
||||
*/
|
||||
@@ -108,16 +140,18 @@ export interface IStorageService {
|
||||
/**
|
||||
* Whether the storage for the given scope was created during this session or
|
||||
* existed before.
|
||||
*
|
||||
*/
|
||||
isNew(scope: StorageScope): boolean;
|
||||
|
||||
/**
|
||||
* Allows to flush state, e.g. in cases where a shutdown is
|
||||
* imminent. This will send out the onWillSaveState to ask
|
||||
* imminent. This will send out the `onWillSaveState` to ask
|
||||
* everyone for latest state.
|
||||
*
|
||||
* @returns a `Promise` that can be awaited on when all updates
|
||||
* to the underlying storage have been flushed.
|
||||
*/
|
||||
flush(): void;
|
||||
flush(): Promise<void>;
|
||||
}
|
||||
|
||||
export const enum StorageScope {
|
||||
@@ -133,21 +167,242 @@ export const enum StorageScope {
|
||||
WORKSPACE
|
||||
}
|
||||
|
||||
export interface IStorageChangeEvent {
|
||||
export const enum StorageTarget {
|
||||
|
||||
/**
|
||||
* The stored data is user specific and applies across machines.
|
||||
*/
|
||||
USER,
|
||||
|
||||
/**
|
||||
* The stored data is machine specific.
|
||||
*/
|
||||
MACHINE
|
||||
}
|
||||
|
||||
export interface IStorageValueChangeEvent {
|
||||
|
||||
/**
|
||||
* The scope for the storage entry that changed
|
||||
* or was removed.
|
||||
*/
|
||||
readonly scope: StorageScope;
|
||||
|
||||
/**
|
||||
* The `key` of the storage entry that was changed
|
||||
* or was removed.
|
||||
*/
|
||||
readonly key: string;
|
||||
|
||||
/**
|
||||
* The `target` can be `undefined` if a key is being
|
||||
* removed.
|
||||
*/
|
||||
readonly target: StorageTarget | undefined;
|
||||
}
|
||||
|
||||
export interface IStorageTargetChangeEvent {
|
||||
readonly scope: StorageScope;
|
||||
}
|
||||
|
||||
export class InMemoryStorageService extends Disposable implements IStorageService {
|
||||
interface IKeyTargets {
|
||||
[key: string]: StorageTarget
|
||||
}
|
||||
|
||||
export abstract class AbstractStorageService extends Disposable implements IStorageService {
|
||||
|
||||
declare readonly _serviceBrand: undefined;
|
||||
|
||||
private readonly _onDidChangeStorage = this._register(new Emitter<IStorageChangeEvent>());
|
||||
readonly onDidChangeStorage = this._onDidChangeStorage.event;
|
||||
private readonly _onDidChangeValue = this._register(new PauseableEmitter<IStorageValueChangeEvent>());
|
||||
readonly onDidChangeValue = this._onDidChangeValue.event;
|
||||
|
||||
protected readonly _onWillSaveState = this._register(new Emitter<IWillSaveStateEvent>());
|
||||
private readonly _onDidChangeTarget = this._register(new PauseableEmitter<IStorageTargetChangeEvent>());
|
||||
readonly onDidChangeTarget = this._onDidChangeTarget.event;
|
||||
|
||||
private readonly _onWillSaveState = this._register(new Emitter<IWillSaveStateEvent>());
|
||||
readonly onWillSaveState = this._onWillSaveState.event;
|
||||
|
||||
protected emitDidChangeValue(scope: StorageScope, key: string): void {
|
||||
|
||||
// Specially handle `TARGET_KEY`
|
||||
if (key === TARGET_KEY) {
|
||||
|
||||
// Clear our cached version which is now out of date
|
||||
if (scope === StorageScope.GLOBAL) {
|
||||
this._globalKeyTargets = undefined;
|
||||
} else if (scope === StorageScope.WORKSPACE) {
|
||||
this._workspaceKeyTargets = undefined;
|
||||
}
|
||||
|
||||
// Emit as `didChangeTarget` event
|
||||
this._onDidChangeTarget.fire({ scope });
|
||||
}
|
||||
|
||||
// Emit any other key to outside
|
||||
else {
|
||||
this._onDidChangeValue.fire({ scope, key, target: this.getKeyTargets(scope)[key] });
|
||||
}
|
||||
}
|
||||
|
||||
protected emitWillSaveState(reason: WillSaveStateReason): void {
|
||||
this._onWillSaveState.fire({ reason });
|
||||
}
|
||||
|
||||
store2(key: string, value: string | boolean | number | undefined | null, scope: StorageScope, target: StorageTarget): void {
|
||||
|
||||
// We remove the key for undefined/null values
|
||||
if (isUndefinedOrNull(value)) {
|
||||
this.remove(key, scope);
|
||||
return;
|
||||
}
|
||||
|
||||
// Update our datastructures but send events only after
|
||||
this.withPausedEmitters(() => {
|
||||
|
||||
// Update key-target map
|
||||
this.updateKeyTarget(key, scope, target);
|
||||
|
||||
// Store actual value
|
||||
this.doStore(key, value, scope);
|
||||
});
|
||||
}
|
||||
|
||||
store(key: string, value: string | boolean | number | undefined | null, scope: StorageScope): void {
|
||||
this.store2(key, value, scope, StorageTarget.MACHINE);
|
||||
}
|
||||
|
||||
remove(key: string, scope: StorageScope): void {
|
||||
|
||||
// Update our datastructures but send events only after
|
||||
this.withPausedEmitters(() => {
|
||||
|
||||
// Update key-target map
|
||||
this.updateKeyTarget(key, scope, undefined);
|
||||
|
||||
// Remove actual key
|
||||
this.doRemove(key, scope);
|
||||
});
|
||||
}
|
||||
|
||||
private withPausedEmitters(fn: Function): void {
|
||||
|
||||
// Pause emitters
|
||||
this._onDidChangeValue.pause();
|
||||
this._onDidChangeTarget.pause();
|
||||
|
||||
try {
|
||||
fn();
|
||||
} finally {
|
||||
|
||||
// Resume emitters
|
||||
this._onDidChangeValue.resume();
|
||||
this._onDidChangeTarget.resume();
|
||||
}
|
||||
}
|
||||
|
||||
keys(scope: StorageScope, target: StorageTarget): string[] {
|
||||
const keys: string[] = [];
|
||||
for (const [key, keyTarget] of Object.entries(this.getKeyTargets(scope))) {
|
||||
if (keyTarget === target) {
|
||||
keys.push(key);
|
||||
}
|
||||
}
|
||||
|
||||
return keys;
|
||||
}
|
||||
|
||||
private updateKeyTarget(key: string, scope: StorageScope, target: StorageTarget | undefined): void {
|
||||
|
||||
// Add
|
||||
const keyTargets = this.getKeyTargets(scope);
|
||||
if (typeof target === 'number') {
|
||||
if (keyTargets[key] !== target) {
|
||||
keyTargets[key] = target;
|
||||
this.doStore(TARGET_KEY, JSON.stringify(keyTargets), scope);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove
|
||||
else {
|
||||
if (typeof keyTargets[key] === 'number') {
|
||||
delete keyTargets[key];
|
||||
this.doStore(TARGET_KEY, JSON.stringify(keyTargets), scope);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private _workspaceKeyTargets: IKeyTargets | undefined = undefined;
|
||||
private get workspaceKeyTargets(): IKeyTargets {
|
||||
if (!this._workspaceKeyTargets) {
|
||||
this._workspaceKeyTargets = this.loadKeyTargets(StorageScope.WORKSPACE);
|
||||
}
|
||||
|
||||
return this._workspaceKeyTargets;
|
||||
}
|
||||
|
||||
private _globalKeyTargets: IKeyTargets | undefined = undefined;
|
||||
private get globalKeyTargets(): IKeyTargets {
|
||||
if (!this._globalKeyTargets) {
|
||||
this._globalKeyTargets = this.loadKeyTargets(StorageScope.GLOBAL);
|
||||
}
|
||||
|
||||
return this._globalKeyTargets;
|
||||
}
|
||||
|
||||
private getKeyTargets(scope: StorageScope): IKeyTargets {
|
||||
return scope === StorageScope.GLOBAL ? this.globalKeyTargets : this.workspaceKeyTargets;
|
||||
}
|
||||
|
||||
private loadKeyTargets(scope: StorageScope): { [key: string]: StorageTarget } {
|
||||
const keysRaw = this.get(TARGET_KEY, scope);
|
||||
if (keysRaw) {
|
||||
try {
|
||||
return JSON.parse(keysRaw);
|
||||
} catch (error) {
|
||||
// Fail gracefully
|
||||
}
|
||||
}
|
||||
|
||||
return Object.create(null);
|
||||
}
|
||||
|
||||
isNew(scope: StorageScope): boolean {
|
||||
return this.getBoolean(IS_NEW_KEY, scope) === true;
|
||||
}
|
||||
|
||||
flush(): Promise<void> {
|
||||
|
||||
// Signal event to collect changes
|
||||
this._onWillSaveState.fire({ reason: WillSaveStateReason.NONE });
|
||||
|
||||
// Await flush
|
||||
return this.doFlush();
|
||||
}
|
||||
|
||||
// --- abstract
|
||||
|
||||
abstract get(key: string, scope: StorageScope, fallbackValue: string): string;
|
||||
abstract get(key: string, scope: StorageScope, fallbackValue?: string): string | undefined;
|
||||
|
||||
abstract getBoolean(key: string, scope: StorageScope, fallbackValue: boolean): boolean;
|
||||
abstract getBoolean(key: string, scope: StorageScope, fallbackValue?: boolean): boolean | undefined;
|
||||
|
||||
abstract getNumber(key: string, scope: StorageScope, fallbackValue: number): number;
|
||||
abstract getNumber(key: string, scope: StorageScope, fallbackValue?: number): number | undefined;
|
||||
|
||||
protected abstract doStore(key: string, value: string | boolean | number, scope: StorageScope): void;
|
||||
|
||||
protected abstract doRemove(key: string, scope: StorageScope): void;
|
||||
|
||||
protected abstract doFlush(): Promise<void>;
|
||||
|
||||
abstract migrate(toWorkspace: IWorkspaceInitializationPayload): Promise<void>;
|
||||
|
||||
abstract logStorage(): void;
|
||||
}
|
||||
|
||||
export class InMemoryStorageService extends AbstractStorageService {
|
||||
|
||||
private readonly globalCache = new Map<string, string>();
|
||||
private readonly workspaceCache = new Map<string, string>();
|
||||
|
||||
@@ -188,12 +443,7 @@ export class InMemoryStorageService extends Disposable implements IStorageServic
|
||||
return parseInt(value, 10);
|
||||
}
|
||||
|
||||
store(key: string, value: string | boolean | number | undefined | null, scope: StorageScope): Promise<void> {
|
||||
|
||||
// We remove the key for undefined/null values
|
||||
if (isUndefinedOrNull(value)) {
|
||||
return this.remove(key, scope);
|
||||
}
|
||||
protected doStore(key: string, value: string | boolean | number, scope: StorageScope): void {
|
||||
|
||||
// Otherwise, convert to String and store
|
||||
const valueStr = String(value);
|
||||
@@ -201,28 +451,24 @@ export class InMemoryStorageService extends Disposable implements IStorageServic
|
||||
// Return early if value already set
|
||||
const currentValue = this.getCache(scope).get(key);
|
||||
if (currentValue === valueStr) {
|
||||
return Promise.resolve();
|
||||
return;
|
||||
}
|
||||
|
||||
// Update in cache
|
||||
this.getCache(scope).set(key, valueStr);
|
||||
|
||||
// Events
|
||||
this._onDidChangeStorage.fire({ scope, key });
|
||||
|
||||
return Promise.resolve();
|
||||
this.emitDidChangeValue(scope, key);
|
||||
}
|
||||
|
||||
remove(key: string, scope: StorageScope): Promise<void> {
|
||||
protected doRemove(key: string, scope: StorageScope): void {
|
||||
const wasDeleted = this.getCache(scope).delete(key);
|
||||
if (!wasDeleted) {
|
||||
return Promise.resolve(); // Return early if value already deleted
|
||||
return; // Return early if value already deleted
|
||||
}
|
||||
|
||||
// Events
|
||||
this._onDidChangeStorage.fire({ scope, key });
|
||||
|
||||
return Promise.resolve();
|
||||
this.emitDidChangeValue(scope, key);
|
||||
}
|
||||
|
||||
logStorage(): void {
|
||||
@@ -233,13 +479,7 @@ export class InMemoryStorageService extends Disposable implements IStorageServic
|
||||
// not supported
|
||||
}
|
||||
|
||||
flush(): void {
|
||||
this._onWillSaveState.fire({ reason: WillSaveStateReason.NONE });
|
||||
}
|
||||
|
||||
isNew(): boolean {
|
||||
return true; // always new when in-memory
|
||||
}
|
||||
async doFlush(): Promise<void> { }
|
||||
|
||||
async close(): Promise<void> { }
|
||||
}
|
||||
|
||||
@@ -3,10 +3,9 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Disposable, IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { Emitter } from 'vs/base/common/event';
|
||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { ILogService, LogLevel } from 'vs/platform/log/common/log';
|
||||
import { IStorageChangeEvent, IStorageService, StorageScope, IWillSaveStateEvent, WillSaveStateReason, logStorage, IS_NEW_KEY } from 'vs/platform/storage/common/storage';
|
||||
import { StorageScope, WillSaveStateReason, logStorage, IS_NEW_KEY, AbstractStorageService } from 'vs/platform/storage/common/storage';
|
||||
import { SQLiteStorageDatabase, ISQLiteStorageDatabaseLoggingOptions } from 'vs/base/parts/storage/node/storage';
|
||||
import { Storage, IStorageDatabase, IStorage, StorageHint } from 'vs/base/parts/storage/common/storage';
|
||||
import { mark } from 'vs/base/common/performance';
|
||||
@@ -17,19 +16,11 @@ import { IWorkspaceInitializationPayload, isWorkspaceIdentifier, isSingleFolderW
|
||||
import { assertIsDefined } from 'vs/base/common/types';
|
||||
import { RunOnceScheduler, runWhenIdle } from 'vs/base/common/async';
|
||||
|
||||
export class NativeStorageService extends Disposable implements IStorageService {
|
||||
|
||||
declare readonly _serviceBrand: undefined;
|
||||
export class NativeStorageService extends AbstractStorageService {
|
||||
|
||||
private static readonly WORKSPACE_STORAGE_NAME = 'state.vscdb';
|
||||
private static readonly WORKSPACE_META_NAME = 'workspace.json';
|
||||
|
||||
private readonly _onDidChangeStorage = this._register(new Emitter<IStorageChangeEvent>());
|
||||
readonly onDidChangeStorage = this._onDidChangeStorage.event;
|
||||
|
||||
private readonly _onWillSaveState = this._register(new Emitter<IWillSaveStateEvent>());
|
||||
readonly onWillSaveState = this._onWillSaveState.event;
|
||||
|
||||
private readonly globalStorage = new Storage(this.globalStorageDatabase);
|
||||
|
||||
private workspaceStoragePath: string | undefined;
|
||||
@@ -54,11 +45,7 @@ export class NativeStorageService extends Disposable implements IStorageService
|
||||
private registerListeners(): void {
|
||||
|
||||
// Global Storage change events
|
||||
this._register(this.globalStorage.onDidChangeStorage(key => this.handleDidChangeStorage(key, StorageScope.GLOBAL)));
|
||||
}
|
||||
|
||||
private handleDidChangeStorage(key: string, scope: StorageScope): void {
|
||||
this._onDidChangeStorage.fire({ key, scope });
|
||||
this._register(this.globalStorage.onDidChangeStorage(key => this.emitDidChangeValue(StorageScope.GLOBAL, key)));
|
||||
}
|
||||
|
||||
initialize(payload?: IWorkspaceInitializationPayload): Promise<void> {
|
||||
@@ -134,7 +121,7 @@ export class NativeStorageService extends Disposable implements IStorageService
|
||||
// Create new
|
||||
this.workspaceStoragePath = workspaceStoragePath;
|
||||
this.workspaceStorage = new Storage(new SQLiteStorageDatabase(workspaceStoragePath, { logging: workspaceLoggingOptions }), { hint });
|
||||
this.workspaceStorageListener = this.workspaceStorage.onDidChangeStorage(key => this.handleDidChangeStorage(key, StorageScope.WORKSPACE));
|
||||
this.workspaceStorageListener = this.workspaceStorage.onDidChangeStorage(key => this.emitDidChangeValue(StorageScope.WORKSPACE, key));
|
||||
|
||||
return this.workspaceStorage;
|
||||
}
|
||||
@@ -201,11 +188,11 @@ export class NativeStorageService extends Disposable implements IStorageService
|
||||
return this.getStorage(scope).getNumber(key, fallbackValue);
|
||||
}
|
||||
|
||||
store(key: string, value: string | boolean | number | undefined | null, scope: StorageScope): void {
|
||||
protected doStore(key: string, value: string | boolean | number | undefined | null, scope: StorageScope): void {
|
||||
this.getStorage(scope).set(key, value);
|
||||
}
|
||||
|
||||
remove(key: string, scope: StorageScope): void {
|
||||
protected doRemove(key: string, scope: StorageScope): void {
|
||||
this.getStorage(scope).delete(key);
|
||||
}
|
||||
|
||||
@@ -213,6 +200,13 @@ export class NativeStorageService extends Disposable implements IStorageService
|
||||
return assertIsDefined(scope === StorageScope.GLOBAL ? this.globalStorage : this.workspaceStorage);
|
||||
}
|
||||
|
||||
protected async doFlush(): Promise<void> {
|
||||
await Promise.all([
|
||||
this.getStorage(StorageScope.GLOBAL).whenFlushed(),
|
||||
this.getStorage(StorageScope.WORKSPACE).whenFlushed()
|
||||
]);
|
||||
}
|
||||
|
||||
private doFlushWhenIdle(): void {
|
||||
|
||||
// Dispose any previous idle runner
|
||||
@@ -229,10 +223,6 @@ export class NativeStorageService extends Disposable implements IStorageService
|
||||
});
|
||||
}
|
||||
|
||||
flush(): void {
|
||||
this._onWillSaveState.fire({ reason: WillSaveStateReason.NONE });
|
||||
}
|
||||
|
||||
async close(): Promise<void> {
|
||||
|
||||
// Stop periodic scheduler and idle runner as we now collect state normally
|
||||
@@ -241,7 +231,7 @@ export class NativeStorageService extends Disposable implements IStorageService
|
||||
this.runWhenIdleDisposable = undefined;
|
||||
|
||||
// Signal as event so that clients can still store data
|
||||
this._onWillSaveState.fire({ reason: WillSaveStateReason.SHUTDOWN });
|
||||
this.emitWillSaveState(WillSaveStateReason.SHUTDOWN);
|
||||
|
||||
// Do it
|
||||
await Promise.all([
|
||||
@@ -277,8 +267,4 @@ export class NativeStorageService extends Disposable implements IStorageService
|
||||
// Recreate and init workspace storage
|
||||
return this.createWorkspaceStorage(newWorkspaceStoragePath).init();
|
||||
}
|
||||
|
||||
isNew(scope: StorageScope): boolean {
|
||||
return this.getBoolean(IS_NEW_KEY, scope) === true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,198 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { strictEqual, ok, equal } from 'assert';
|
||||
import { StorageScope, InMemoryStorageService, StorageTarget, IStorageValueChangeEvent, IStorageTargetChangeEvent } from 'vs/platform/storage/common/storage';
|
||||
|
||||
suite('StorageService', function () {
|
||||
|
||||
test('Get Data, Integer, Boolean (global, in-memory)', () => {
|
||||
storeData(StorageScope.GLOBAL);
|
||||
});
|
||||
|
||||
test('Get Data, Integer, Boolean (workspace, in-memory)', () => {
|
||||
storeData(StorageScope.WORKSPACE);
|
||||
});
|
||||
|
||||
function storeData(scope: StorageScope): void {
|
||||
const storage = new InMemoryStorageService();
|
||||
|
||||
let storageValueChangeEvents: IStorageValueChangeEvent[] = [];
|
||||
storage.onDidChangeValue(e => storageValueChangeEvents.push(e));
|
||||
|
||||
strictEqual(storage.get('test.get', scope, 'foobar'), 'foobar');
|
||||
strictEqual(storage.get('test.get', scope, ''), '');
|
||||
strictEqual(storage.getNumber('test.getNumber', scope, 5), 5);
|
||||
strictEqual(storage.getNumber('test.getNumber', scope, 0), 0);
|
||||
strictEqual(storage.getBoolean('test.getBoolean', scope, true), true);
|
||||
strictEqual(storage.getBoolean('test.getBoolean', scope, false), false);
|
||||
|
||||
storage.store('test.get', 'foobar', scope);
|
||||
strictEqual(storage.get('test.get', scope, (undefined)!), 'foobar');
|
||||
let storageValueChangeEvent = storageValueChangeEvents.find(e => e.key === 'test.get');
|
||||
equal(storageValueChangeEvent?.scope, scope);
|
||||
equal(storageValueChangeEvent?.key, 'test.get');
|
||||
storageValueChangeEvents = [];
|
||||
|
||||
storage.store('test.get', '', scope);
|
||||
strictEqual(storage.get('test.get', scope, (undefined)!), '');
|
||||
storageValueChangeEvent = storageValueChangeEvents.find(e => e.key === 'test.get');
|
||||
equal(storageValueChangeEvent!.scope, scope);
|
||||
equal(storageValueChangeEvent!.key, 'test.get');
|
||||
|
||||
storage.store('test.getNumber', 5, scope);
|
||||
strictEqual(storage.getNumber('test.getNumber', scope, (undefined)!), 5);
|
||||
|
||||
storage.store('test.getNumber', 0, scope);
|
||||
strictEqual(storage.getNumber('test.getNumber', scope, (undefined)!), 0);
|
||||
|
||||
storage.store('test.getBoolean', true, scope);
|
||||
strictEqual(storage.getBoolean('test.getBoolean', scope, (undefined)!), true);
|
||||
|
||||
storage.store('test.getBoolean', false, scope);
|
||||
strictEqual(storage.getBoolean('test.getBoolean', scope, (undefined)!), false);
|
||||
|
||||
strictEqual(storage.get('test.getDefault', scope, 'getDefault'), 'getDefault');
|
||||
strictEqual(storage.getNumber('test.getNumberDefault', scope, 5), 5);
|
||||
strictEqual(storage.getBoolean('test.getBooleanDefault', scope, true), true);
|
||||
}
|
||||
|
||||
test('Remove Data (global, in-memory)', () => {
|
||||
removeData(StorageScope.GLOBAL);
|
||||
});
|
||||
|
||||
test('Remove Data (workspace, in-memory)', () => {
|
||||
removeData(StorageScope.WORKSPACE);
|
||||
});
|
||||
|
||||
function removeData(scope: StorageScope): void {
|
||||
const storage = new InMemoryStorageService();
|
||||
|
||||
let storageValueChangeEvents: IStorageValueChangeEvent[] = [];
|
||||
storage.onDidChangeValue(e => storageValueChangeEvents.push(e));
|
||||
|
||||
storage.store('test.remove', 'foobar', scope);
|
||||
strictEqual('foobar', storage.get('test.remove', scope, (undefined)!));
|
||||
|
||||
storage.remove('test.remove', scope);
|
||||
ok(!storage.get('test.remove', scope, (undefined)!));
|
||||
let storageValueChangeEvent = storageValueChangeEvents.find(e => e.key === 'test.remove');
|
||||
equal(storageValueChangeEvent?.scope, scope);
|
||||
equal(storageValueChangeEvent?.key, 'test.remove');
|
||||
}
|
||||
|
||||
test('Keys (in-memory)', () => {
|
||||
const storage = new InMemoryStorageService();
|
||||
|
||||
let storageTargetEvent: IStorageTargetChangeEvent | undefined = undefined;
|
||||
storage.onDidChangeTarget(e => storageTargetEvent = e);
|
||||
|
||||
let storageValueChangeEvent: IStorageValueChangeEvent | undefined = undefined;
|
||||
storage.onDidChangeValue(e => storageValueChangeEvent = e);
|
||||
|
||||
// Empty
|
||||
for (const scope of [StorageScope.WORKSPACE, StorageScope.GLOBAL]) {
|
||||
for (const target of [StorageTarget.MACHINE, StorageTarget.USER]) {
|
||||
strictEqual(storage.keys(scope, target).length, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Add values
|
||||
for (const scope of [StorageScope.WORKSPACE, StorageScope.GLOBAL]) {
|
||||
for (const target of [StorageTarget.MACHINE, StorageTarget.USER]) {
|
||||
storageTargetEvent = Object.create(null);
|
||||
storageValueChangeEvent = Object.create(null);
|
||||
|
||||
storage.store2('test.target1', 'value1', scope, target);
|
||||
strictEqual(storage.keys(scope, target).length, 1);
|
||||
equal(storageTargetEvent?.scope, scope);
|
||||
equal(storageValueChangeEvent?.key, 'test.target1');
|
||||
equal(storageValueChangeEvent?.scope, scope);
|
||||
equal(storageValueChangeEvent?.target, target);
|
||||
|
||||
storageTargetEvent = undefined;
|
||||
storageValueChangeEvent = Object.create(null);
|
||||
|
||||
storage.store2('test.target1', 'otherValue1', scope, target);
|
||||
strictEqual(storage.keys(scope, target).length, 1);
|
||||
equal(storageTargetEvent, undefined);
|
||||
equal(storageValueChangeEvent?.key, 'test.target1');
|
||||
equal(storageValueChangeEvent?.scope, scope);
|
||||
equal(storageValueChangeEvent?.target, target);
|
||||
|
||||
storage.store2('test.target2', 'value2', scope, target);
|
||||
storage.store2('test.target3', 'value3', scope, target);
|
||||
|
||||
strictEqual(storage.keys(scope, target).length, 3);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove values
|
||||
for (const scope of [StorageScope.WORKSPACE, StorageScope.GLOBAL]) {
|
||||
for (const target of [StorageTarget.MACHINE, StorageTarget.USER]) {
|
||||
const keysLength = storage.keys(scope, target).length;
|
||||
|
||||
storage.store2('test.target4', 'value1', scope, target);
|
||||
strictEqual(storage.keys(scope, target).length, keysLength + 1);
|
||||
|
||||
storageTargetEvent = Object.create(null);
|
||||
storageValueChangeEvent = Object.create(null);
|
||||
|
||||
storage.remove('test.target4', scope);
|
||||
strictEqual(storage.keys(scope, target).length, keysLength);
|
||||
equal(storageTargetEvent?.scope, scope);
|
||||
equal(storageValueChangeEvent?.key, 'test.target4');
|
||||
equal(storageValueChangeEvent?.scope, scope);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove all
|
||||
for (const scope of [StorageScope.WORKSPACE, StorageScope.GLOBAL]) {
|
||||
for (const target of [StorageTarget.MACHINE, StorageTarget.USER]) {
|
||||
const keys = storage.keys(scope, target);
|
||||
|
||||
for (const key of keys) {
|
||||
storage.remove(key, scope);
|
||||
}
|
||||
|
||||
strictEqual(storage.keys(scope, target).length, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Adding undefined or null removes value
|
||||
for (const scope of [StorageScope.WORKSPACE, StorageScope.GLOBAL]) {
|
||||
for (const target of [StorageTarget.MACHINE, StorageTarget.USER]) {
|
||||
storage.store2('test.target1', 'value1', scope, target);
|
||||
strictEqual(storage.keys(scope, target).length, 1);
|
||||
|
||||
storageTargetEvent = Object.create(null);
|
||||
|
||||
storage.store2('test.target1', undefined, scope, target);
|
||||
strictEqual(storage.keys(scope, target).length, 0);
|
||||
equal(storageTargetEvent?.scope, scope);
|
||||
|
||||
storage.store2('test.target1', '', scope, target);
|
||||
strictEqual(storage.keys(scope, target).length, 1);
|
||||
|
||||
storage.store2('test.target1', null, scope, target);
|
||||
strictEqual(storage.keys(scope, target).length, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Target change
|
||||
storageTargetEvent = undefined;
|
||||
storage.store2('test.target5', 'value1', StorageScope.GLOBAL, StorageTarget.MACHINE);
|
||||
ok(storageTargetEvent);
|
||||
storageTargetEvent = undefined;
|
||||
storage.store2('test.target5', 'value1', StorageScope.GLOBAL, StorageTarget.USER);
|
||||
ok(storageTargetEvent);
|
||||
storageTargetEvent = undefined;
|
||||
storage.store2('test.target5', 'value1', StorageScope.GLOBAL, StorageTarget.MACHINE);
|
||||
ok(storageTargetEvent);
|
||||
storageTargetEvent = undefined;
|
||||
storage.store2('test.target5', 'value1', StorageScope.GLOBAL, StorageTarget.MACHINE);
|
||||
ok(!storageTargetEvent); // no change in target
|
||||
});
|
||||
});
|
||||
@@ -3,8 +3,8 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { strictEqual, ok, equal } from 'assert';
|
||||
import { StorageScope, InMemoryStorageService } from 'vs/platform/storage/common/storage';
|
||||
import { equal } from 'assert';
|
||||
import { StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { NativeStorageService } from 'vs/platform/storage/node/storageService';
|
||||
import { generateUuid } from 'vs/base/common/uuid';
|
||||
import { join } from 'vs/base/common/path';
|
||||
@@ -16,66 +16,7 @@ import { parseArgs, OPTIONS } from 'vs/platform/environment/node/argv';
|
||||
import { InMemoryStorageDatabase } from 'vs/base/parts/storage/common/storage';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
|
||||
suite('StorageService', function () {
|
||||
|
||||
test('Remove Data (global, in-memory)', () => {
|
||||
removeData(StorageScope.GLOBAL);
|
||||
});
|
||||
|
||||
test('Remove Data (workspace, in-memory)', () => {
|
||||
removeData(StorageScope.WORKSPACE);
|
||||
});
|
||||
|
||||
function removeData(scope: StorageScope): void {
|
||||
const storage = new InMemoryStorageService();
|
||||
|
||||
storage.store('test.remove', 'foobar', scope);
|
||||
strictEqual('foobar', storage.get('test.remove', scope, (undefined)!));
|
||||
|
||||
storage.remove('test.remove', scope);
|
||||
ok(!storage.get('test.remove', scope, (undefined)!));
|
||||
}
|
||||
|
||||
test('Get Data, Integer, Boolean (global, in-memory)', () => {
|
||||
storeData(StorageScope.GLOBAL);
|
||||
});
|
||||
|
||||
test('Get Data, Integer, Boolean (workspace, in-memory)', () => {
|
||||
storeData(StorageScope.WORKSPACE);
|
||||
});
|
||||
|
||||
function storeData(scope: StorageScope): void {
|
||||
const storage = new InMemoryStorageService();
|
||||
|
||||
strictEqual(storage.get('test.get', scope, 'foobar'), 'foobar');
|
||||
strictEqual(storage.get('test.get', scope, ''), '');
|
||||
strictEqual(storage.getNumber('test.getNumber', scope, 5), 5);
|
||||
strictEqual(storage.getNumber('test.getNumber', scope, 0), 0);
|
||||
strictEqual(storage.getBoolean('test.getBoolean', scope, true), true);
|
||||
strictEqual(storage.getBoolean('test.getBoolean', scope, false), false);
|
||||
|
||||
storage.store('test.get', 'foobar', scope);
|
||||
strictEqual(storage.get('test.get', scope, (undefined)!), 'foobar');
|
||||
|
||||
storage.store('test.get', '', scope);
|
||||
strictEqual(storage.get('test.get', scope, (undefined)!), '');
|
||||
|
||||
storage.store('test.getNumber', 5, scope);
|
||||
strictEqual(storage.getNumber('test.getNumber', scope, (undefined)!), 5);
|
||||
|
||||
storage.store('test.getNumber', 0, scope);
|
||||
strictEqual(storage.getNumber('test.getNumber', scope, (undefined)!), 0);
|
||||
|
||||
storage.store('test.getBoolean', true, scope);
|
||||
strictEqual(storage.getBoolean('test.getBoolean', scope, (undefined)!), true);
|
||||
|
||||
storage.store('test.getBoolean', false, scope);
|
||||
strictEqual(storage.getBoolean('test.getBoolean', scope, (undefined)!), false);
|
||||
|
||||
strictEqual(storage.get('test.getDefault', scope, 'getDefault'), 'getDefault');
|
||||
strictEqual(storage.getNumber('test.getNumberDefault', scope, 5), 5);
|
||||
strictEqual(storage.getBoolean('test.getBooleanDefault', scope, true), true);
|
||||
}
|
||||
suite('NativeStorageService', function () {
|
||||
|
||||
function uniqueStorageDir(): string {
|
||||
const id = generateUuid();
|
||||
@@ -115,6 +56,10 @@ suite('StorageService', function () {
|
||||
storage.store('barNumber', 55, StorageScope.WORKSPACE);
|
||||
storage.store('barBoolean', true, StorageScope.GLOBAL);
|
||||
|
||||
equal(storage.get('bar', StorageScope.WORKSPACE), 'foo');
|
||||
equal(storage.getNumber('barNumber', StorageScope.WORKSPACE), 55);
|
||||
equal(storage.getBoolean('barBoolean', StorageScope.GLOBAL), true);
|
||||
|
||||
await storage.migrate({ id: String(Date.now() + 100) });
|
||||
|
||||
equal(storage.get('bar', StorageScope.WORKSPACE), 'foo');
|
||||
|
||||
@@ -115,7 +115,7 @@ export class ExtensionsSynchroniser extends AbstractSynchroniser implements IUse
|
||||
Event.filter(this.extensionManagementService.onDidUninstallExtension, (e => !e.error)),
|
||||
this.extensionEnablementService.onDidChangeEnablement,
|
||||
this.storageKeysSyncRegistryService.onDidChangeExtensionStorageKeys,
|
||||
Event.filter(this.storageService.onDidChangeStorage, e => e.scope === StorageScope.GLOBAL
|
||||
Event.filter(this.storageService.onDidChangeValue, e => e.scope === StorageScope.GLOBAL
|
||||
&& this.storageKeysSyncRegistryService.extensionsStorageKeys.some(([extensionIdentifier]) => areSameExtensions(extensionIdentifier, { id: e.key })))),
|
||||
() => undefined, 500)(() => this.triggerLocalChange()));
|
||||
}
|
||||
|
||||
@@ -6,24 +6,22 @@
|
||||
import * as objects from 'vs/base/common/objects';
|
||||
import { IStorageValue } from 'vs/platform/userDataSync/common/userDataSync';
|
||||
import { IStringDictionary } from 'vs/base/common/collections';
|
||||
import { IStorageKey } from 'vs/platform/userDataSync/common/storageKeys';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
|
||||
export interface IMergeResult {
|
||||
local: { added: IStringDictionary<IStorageValue>, removed: string[], updated: IStringDictionary<IStorageValue> };
|
||||
remote: IStringDictionary<IStorageValue> | null;
|
||||
skipped: string[];
|
||||
}
|
||||
|
||||
export function merge(localStorage: IStringDictionary<IStorageValue>, remoteStorage: IStringDictionary<IStorageValue> | null, baseStorage: IStringDictionary<IStorageValue> | null, storageKeys: ReadonlyArray<IStorageKey>, previouslySkipped: string[], logService: ILogService): IMergeResult {
|
||||
export function merge(localStorage: IStringDictionary<IStorageValue>, remoteStorage: IStringDictionary<IStorageValue> | null, baseStorage: IStringDictionary<IStorageValue> | null, machineScopedStorageKeys: ReadonlyArray<string>, logService: ILogService): IMergeResult {
|
||||
if (!remoteStorage) {
|
||||
return { remote: Object.keys(localStorage).length > 0 ? localStorage : null, local: { added: {}, removed: [], updated: {} }, skipped: [] };
|
||||
return { remote: Object.keys(localStorage).length > 0 ? localStorage : null, local: { added: {}, removed: [], updated: {} } };
|
||||
}
|
||||
|
||||
const localToRemote = compare(localStorage, remoteStorage);
|
||||
if (localToRemote.added.size === 0 && localToRemote.removed.size === 0 && localToRemote.updated.size === 0) {
|
||||
// No changes found between local and remote.
|
||||
return { remote: null, local: { added: {}, removed: [], updated: {} }, skipped: [] };
|
||||
return { remote: null, local: { added: {}, removed: [], updated: {} } };
|
||||
}
|
||||
|
||||
const baseToRemote = baseStorage ? compare(baseStorage, remoteStorage) : { added: Object.keys(remoteStorage).reduce((r, k) => { r.add(k); return r; }, new Set<string>()), removed: new Set<string>(), updated: new Set<string>() };
|
||||
@@ -31,26 +29,19 @@ export function merge(localStorage: IStringDictionary<IStorageValue>, remoteStor
|
||||
|
||||
const local: { added: IStringDictionary<IStorageValue>, removed: string[], updated: IStringDictionary<IStorageValue> } = { added: {}, removed: [], updated: {} };
|
||||
const remote: IStringDictionary<IStorageValue> = objects.deepClone(remoteStorage);
|
||||
const skipped: string[] = [];
|
||||
|
||||
// Added in remote
|
||||
for (const key of baseToRemote.added.values()) {
|
||||
const remoteValue = remoteStorage[key];
|
||||
const storageKey = storageKeys.filter(storageKey => storageKey.key === key)[0];
|
||||
if (!storageKey) {
|
||||
skipped.push(key);
|
||||
logService.trace(`GlobalState: Skipped adding ${key} in local storage as it is not registered.`);
|
||||
continue;
|
||||
}
|
||||
if (storageKey.version !== remoteValue.version) {
|
||||
logService.info(`GlobalState: Skipped adding ${key} in local storage. Local version '${storageKey.version}' and remote version '${remoteValue.version} are not same.`);
|
||||
if (machineScopedStorageKeys.includes(key)) {
|
||||
logService.info(`GlobalState: Skipped adding ${key} in local storage because it is declared as machine scoped.`);
|
||||
continue;
|
||||
}
|
||||
const localValue = localStorage[key];
|
||||
if (localValue && localValue.value === remoteValue.value) {
|
||||
continue;
|
||||
}
|
||||
if (baseToLocal.added.has(key)) {
|
||||
if (localValue) {
|
||||
local.updated[key] = remoteValue;
|
||||
} else {
|
||||
local.added[key] = remoteValue;
|
||||
@@ -60,28 +51,25 @@ export function merge(localStorage: IStringDictionary<IStorageValue>, remoteStor
|
||||
// Updated in Remote
|
||||
for (const key of baseToRemote.updated.values()) {
|
||||
const remoteValue = remoteStorage[key];
|
||||
const storageKey = storageKeys.filter(storageKey => storageKey.key === key)[0];
|
||||
if (!storageKey) {
|
||||
skipped.push(key);
|
||||
logService.trace(`GlobalState: Skipped updating ${key} in local storage as is not registered.`);
|
||||
continue;
|
||||
}
|
||||
if (storageKey.version !== remoteValue.version) {
|
||||
logService.info(`GlobalState: Skipped updating ${key} in local storage. Local version '${storageKey.version}' and remote version '${remoteValue.version} are not same.`);
|
||||
if (machineScopedStorageKeys.includes(key)) {
|
||||
logService.info(`GlobalState: Skipped updating ${key} in local storage because it is declared as machine scoped.`);
|
||||
continue;
|
||||
}
|
||||
const localValue = localStorage[key];
|
||||
if (localValue && localValue.value === remoteValue.value) {
|
||||
continue;
|
||||
}
|
||||
local.updated[key] = remoteValue;
|
||||
if (localValue) {
|
||||
local.updated[key] = remoteValue;
|
||||
} else {
|
||||
local.added[key] = remoteValue;
|
||||
}
|
||||
}
|
||||
|
||||
// Removed in remote
|
||||
for (const key of baseToRemote.removed.values()) {
|
||||
const storageKey = storageKeys.filter(storageKey => storageKey.key === key)[0];
|
||||
if (!storageKey) {
|
||||
logService.trace(`GlobalState: Skipped removing ${key} in local storage. It is not registered to sync.`);
|
||||
if (machineScopedStorageKeys.includes(key)) {
|
||||
logService.trace(`GlobalState: Skipped removing ${key} in local storage because it is declared as machine scoped.`);
|
||||
continue;
|
||||
}
|
||||
local.removed.push(key);
|
||||
@@ -89,9 +77,10 @@ export function merge(localStorage: IStringDictionary<IStorageValue>, remoteStor
|
||||
|
||||
// Added in local
|
||||
for (const key of baseToLocal.added.values()) {
|
||||
if (!baseToRemote.added.has(key)) {
|
||||
remote[key] = localStorage[key];
|
||||
if (baseToRemote.added.has(key)) {
|
||||
continue;
|
||||
}
|
||||
remote[key] = localStorage[key];
|
||||
}
|
||||
|
||||
// Updated in local
|
||||
@@ -99,13 +88,7 @@ export function merge(localStorage: IStringDictionary<IStorageValue>, remoteStor
|
||||
if (baseToRemote.updated.has(key) || baseToRemote.removed.has(key)) {
|
||||
continue;
|
||||
}
|
||||
const remoteValue = remote[key];
|
||||
const localValue = localStorage[key];
|
||||
if (localValue.version < remoteValue.version) {
|
||||
logService.info(`GlobalState: Skipped updating ${key} in remote storage. Local version '${localValue.version}' and remote version '${remoteValue.version} are not same.`);
|
||||
continue;
|
||||
}
|
||||
remote[key] = localValue;
|
||||
remote[key] = localStorage[key];
|
||||
}
|
||||
|
||||
// Removed in local
|
||||
@@ -114,32 +97,10 @@ export function merge(localStorage: IStringDictionary<IStorageValue>, remoteStor
|
||||
if (baseToRemote.updated.has(key)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const storageKey = storageKeys.filter(storageKey => storageKey.key === key)[0];
|
||||
// do not remove from remote if storage key is not found
|
||||
if (!storageKey) {
|
||||
skipped.push(key);
|
||||
logService.trace(`GlobalState: Skipped removing ${key} in remote storage. It is not registered to sync.`);
|
||||
continue;
|
||||
}
|
||||
|
||||
const remoteValue = remote[key];
|
||||
// do not remove from remote if local data version is old
|
||||
if (storageKey.version < remoteValue.version) {
|
||||
logService.info(`GlobalState: Skipped updating ${key} in remote storage. Local version '${storageKey.version}' and remote version '${remoteValue.version} are not same.`);
|
||||
continue;
|
||||
}
|
||||
|
||||
// add to local if it was skipped before
|
||||
if (previouslySkipped.indexOf(key) !== -1) {
|
||||
local.added[key] = remote[key];
|
||||
continue;
|
||||
}
|
||||
|
||||
delete remote[key];
|
||||
}
|
||||
|
||||
return { local, remote: areSame(remote, remoteStorage) ? null : remote, skipped };
|
||||
return { local, remote: areSame(remote, remoteStorage) ? null : remote };
|
||||
}
|
||||
|
||||
function compare(from: IStringDictionary<any>, to: IStringDictionary<any>): { added: Set<string>, removed: Set<string>, updated: Set<string> } {
|
||||
|
||||
@@ -21,9 +21,7 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { format } from 'vs/base/common/jsonFormatter';
|
||||
import { applyEdits } from 'vs/base/common/jsonEdit';
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { IStorageKeysSyncRegistryService, IStorageKey } from 'vs/platform/userDataSync/common/storageKeys';
|
||||
import { equals } from 'vs/base/common/arrays';
|
||||
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
|
||||
const argvStoragePrefx = 'globalState.argv.';
|
||||
@@ -35,15 +33,19 @@ interface IGlobalStateResourceMergeResult extends IAcceptResult {
|
||||
}
|
||||
|
||||
export interface IGlobalStateResourcePreview extends IResourcePreview {
|
||||
readonly skippedStorageKeys: string[];
|
||||
readonly localUserData: IGlobalState;
|
||||
readonly previewResult: IGlobalStateResourceMergeResult;
|
||||
}
|
||||
|
||||
interface ILastSyncUserData extends IRemoteUserData {
|
||||
skippedStorageKeys: string[] | undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronises global state that includes
|
||||
* - Global storage with user scope
|
||||
* - Locale from argv properties
|
||||
*
|
||||
* Global storage is synced without checking version just like other resources (settings, keybindings).
|
||||
* If there is a change in format of the value of a storage key which requires migration then
|
||||
* Owner of that key should remove that key from user scope and replace that with new user scoped key.
|
||||
*/
|
||||
export class GlobalStateSynchroniser extends AbstractSynchroniser implements IUserDataSynchroniser {
|
||||
|
||||
private static readonly GLOBAL_STATE_DATA_URI = URI.from({ scheme: USER_DATA_SYNC_SCHEME, authority: 'globalState', path: `/globalState.json` });
|
||||
@@ -63,23 +65,22 @@ export class GlobalStateSynchroniser extends AbstractSynchroniser implements IUs
|
||||
@ITelemetryService telemetryService: ITelemetryService,
|
||||
@IConfigurationService configurationService: IConfigurationService,
|
||||
@IStorageService private readonly storageService: IStorageService,
|
||||
@IStorageKeysSyncRegistryService private readonly storageKeysSyncRegistryService: IStorageKeysSyncRegistryService,
|
||||
) {
|
||||
super(SyncResource.GlobalState, fileService, environmentService, storageService, userDataSyncStoreService, userDataSyncBackupStoreService, userDataSyncResourceEnablementService, telemetryService, logService, configurationService);
|
||||
this._register(this.fileService.watch(this.extUri.dirname(this.environmentService.argvResource)));
|
||||
this._register(fileService.watch(this.extUri.dirname(this.environmentService.argvResource)));
|
||||
this._register(
|
||||
Event.any(
|
||||
/* Locale change */
|
||||
Event.filter(this.fileService.onDidFilesChange, e => e.contains(this.environmentService.argvResource)),
|
||||
/* Storage change */
|
||||
Event.filter(this.storageService.onDidChangeStorage, e => storageKeysSyncRegistryService.storageKeys.some(({ key }) => e.key === key)),
|
||||
/* Storage key registered */
|
||||
this.storageKeysSyncRegistryService.onDidChangeStorageKeys
|
||||
Event.filter(fileService.onDidFilesChange, e => e.contains(this.environmentService.argvResource)),
|
||||
/* Global storage with user target has changed */
|
||||
Event.filter(storageService.onDidChangeValue, e => e.scope === StorageScope.GLOBAL && e.target !== undefined ? e.target === StorageTarget.USER : storageService.keys(StorageScope.GLOBAL, StorageTarget.USER).includes(e.key)),
|
||||
/* Storage key target has changed */
|
||||
this.storageService.onDidChangeTarget
|
||||
)((() => this.triggerLocalChange()))
|
||||
);
|
||||
}
|
||||
|
||||
protected async generateSyncPreview(remoteUserData: IRemoteUserData, lastSyncUserData: ILastSyncUserData | null, token: CancellationToken): Promise<IGlobalStateResourcePreview[]> {
|
||||
protected async generateSyncPreview(remoteUserData: IRemoteUserData, lastSyncUserData: IRemoteUserData | null, token: CancellationToken): Promise<IGlobalStateResourcePreview[]> {
|
||||
const remoteGlobalState: IGlobalState = remoteUserData.syncData ? JSON.parse(remoteUserData.syncData.content) : null;
|
||||
const lastSyncGlobalState: IGlobalState | null = lastSyncUserData && lastSyncUserData.syncData ? JSON.parse(lastSyncUserData.syncData.content) : null;
|
||||
|
||||
@@ -91,7 +92,7 @@ export class GlobalStateSynchroniser extends AbstractSynchroniser implements IUs
|
||||
this.logService.trace(`${this.syncResourceLogLabel}: Remote ui state does not exist. Synchronizing ui state for the first time.`);
|
||||
}
|
||||
|
||||
const { local, remote, skipped } = merge(localGloablState.storage, remoteGlobalState ? remoteGlobalState.storage : null, lastSyncGlobalState ? lastSyncGlobalState.storage : null, this.getSyncStorageKeys(), lastSyncUserData?.skippedStorageKeys || [], this.logService);
|
||||
const { local, remote } = merge(localGloablState.storage, remoteGlobalState ? remoteGlobalState.storage : null, lastSyncGlobalState ? lastSyncGlobalState.storage : null, this.getIgnoredSyncStorageKeys(), this.logService);
|
||||
const previewResult: IGlobalStateResourceMergeResult = {
|
||||
content: null,
|
||||
local,
|
||||
@@ -101,7 +102,6 @@ export class GlobalStateSynchroniser extends AbstractSynchroniser implements IUs
|
||||
};
|
||||
|
||||
return [{
|
||||
skippedStorageKeys: skipped,
|
||||
localResource: this.localResource,
|
||||
localContent: this.format(localGloablState),
|
||||
localUserData: localGloablState,
|
||||
@@ -152,7 +152,7 @@ export class GlobalStateSynchroniser extends AbstractSynchroniser implements IUs
|
||||
private async acceptRemote(resourcePreview: IGlobalStateResourcePreview): Promise<IGlobalStateResourceMergeResult> {
|
||||
if (resourcePreview.remoteContent !== null) {
|
||||
const remoteGlobalState: IGlobalState = JSON.parse(resourcePreview.remoteContent);
|
||||
const { local, remote } = merge(resourcePreview.localUserData.storage, remoteGlobalState.storage, null, this.getSyncStorageKeys(), resourcePreview.skippedStorageKeys, this.logService);
|
||||
const { local, remote } = merge(resourcePreview.localUserData.storage, remoteGlobalState.storage, null, this.getIgnoredSyncStorageKeys(), this.logService);
|
||||
return {
|
||||
content: resourcePreview.remoteContent,
|
||||
local,
|
||||
@@ -171,8 +171,8 @@ export class GlobalStateSynchroniser extends AbstractSynchroniser implements IUs
|
||||
}
|
||||
}
|
||||
|
||||
protected async applyResult(remoteUserData: IRemoteUserData, lastSyncUserData: ILastSyncUserData | null, resourcePreviews: [IGlobalStateResourcePreview, IGlobalStateResourceMergeResult][], force: boolean): Promise<void> {
|
||||
let { localUserData, skippedStorageKeys } = resourcePreviews[0][0];
|
||||
protected async applyResult(remoteUserData: IRemoteUserData, lastSyncUserData: IRemoteUserData | null, resourcePreviews: [IGlobalStateResourcePreview, IGlobalStateResourceMergeResult][], force: boolean): Promise<void> {
|
||||
let { localUserData } = resourcePreviews[0][0];
|
||||
let { local, remote, localChange, remoteChange } = resourcePreviews[0][1];
|
||||
|
||||
if (localChange === Change.None && remoteChange === Change.None) {
|
||||
@@ -195,10 +195,10 @@ export class GlobalStateSynchroniser extends AbstractSynchroniser implements IUs
|
||||
this.logService.info(`${this.syncResourceLogLabel}: Updated remote ui state`);
|
||||
}
|
||||
|
||||
if (lastSyncUserData?.ref !== remoteUserData.ref || !equals(lastSyncUserData.skippedStorageKeys, skippedStorageKeys)) {
|
||||
if (lastSyncUserData?.ref !== remoteUserData.ref) {
|
||||
// update last sync
|
||||
this.logService.trace(`${this.syncResourceLogLabel}: Updating last synchronized ui state...`);
|
||||
await this.updateLastSyncUserData(remoteUserData, { skippedStorageKeys });
|
||||
await this.updateLastSyncUserData(remoteUserData);
|
||||
this.logService.info(`${this.syncResourceLogLabel}: Updated last synchronized ui state`);
|
||||
}
|
||||
}
|
||||
@@ -267,10 +267,10 @@ export class GlobalStateSynchroniser extends AbstractSynchroniser implements IUs
|
||||
storage[`${argvStoragePrefx}${argvProperty}`] = { version: 1, value: argvValue[argvProperty] };
|
||||
}
|
||||
}
|
||||
for (const { key, version } of this.storageKeysSyncRegistryService.storageKeys) {
|
||||
for (const key of this.storageService.keys(StorageScope.GLOBAL, StorageTarget.USER)) {
|
||||
const value = this.storageService.get(key, StorageScope.GLOBAL);
|
||||
if (value) {
|
||||
storage[key] = { version, value };
|
||||
storage[key] = { version: 1, value };
|
||||
}
|
||||
}
|
||||
return { storage };
|
||||
@@ -317,7 +317,7 @@ export class GlobalStateSynchroniser extends AbstractSynchroniser implements IUs
|
||||
if (updatedStorageKeys.length) {
|
||||
this.logService.trace(`${this.syncResourceLogLabel}: Updating global state...`);
|
||||
for (const key of Object.keys(updatedStorage)) {
|
||||
this.storageService.store(key, updatedStorage[key], StorageScope.GLOBAL);
|
||||
this.storageService.store2(key, updatedStorage[key], StorageScope.GLOBAL, StorageTarget.USER);
|
||||
}
|
||||
this.logService.info(`${this.syncResourceLogLabel}: Updated global state`, Object.keys(updatedStorage));
|
||||
}
|
||||
@@ -336,8 +336,8 @@ export class GlobalStateSynchroniser extends AbstractSynchroniser implements IUs
|
||||
}
|
||||
}
|
||||
|
||||
private getSyncStorageKeys(): IStorageKey[] {
|
||||
return [...this.storageKeysSyncRegistryService.storageKeys, ...argvProperties.map(argvProprety => (<IStorageKey>{ key: `${argvStoragePrefx}${argvProprety}`, version: 1 }))];
|
||||
private getIgnoredSyncStorageKeys(): string[] {
|
||||
return this.storageService.keys(StorageScope.GLOBAL, StorageTarget.MACHINE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -385,7 +385,7 @@ export class GlobalStateInitializer extends AbstractInitializer {
|
||||
|
||||
if (Object.keys(storage).length) {
|
||||
for (const key of Object.keys(storage)) {
|
||||
this.storageService.store(key, storage[key], StorageScope.GLOBAL);
|
||||
this.storageService.store2(key, storage[key], StorageScope.GLOBAL, StorageTarget.USER);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { Disposable, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { IExtensionIdentifierWithVersion } from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
|
||||
@@ -43,21 +43,6 @@ export interface IStorageKeysSyncRegistryService {
|
||||
|
||||
_serviceBrand: any;
|
||||
|
||||
/**
|
||||
* All registered storage keys
|
||||
*/
|
||||
readonly storageKeys: ReadonlyArray<IStorageKey>;
|
||||
|
||||
/**
|
||||
* Event that is triggered when storage keys are changed
|
||||
*/
|
||||
readonly onDidChangeStorageKeys: Event<ReadonlyArray<IStorageKey>>;
|
||||
|
||||
/**
|
||||
* Register a storage key that has to be synchronized during sync.
|
||||
*/
|
||||
registerStorageKey(key: IStorageKey): void;
|
||||
|
||||
/**
|
||||
* All registered extensions storage keys
|
||||
*/
|
||||
@@ -83,12 +68,6 @@ export abstract class AbstractStorageKeysSyncRegistryService extends Disposable
|
||||
|
||||
declare readonly _serviceBrand: undefined;
|
||||
|
||||
protected readonly _storageKeys = new Map<string, IStorageKey>();
|
||||
get storageKeys(): ReadonlyArray<IStorageKey> { return [...this._storageKeys.values()]; }
|
||||
|
||||
protected readonly _onDidChangeStorageKeys: Emitter<ReadonlyArray<IStorageKey>> = this._register(new Emitter<ReadonlyArray<IStorageKey>>());
|
||||
readonly onDidChangeStorageKeys = this._onDidChangeStorageKeys.event;
|
||||
|
||||
protected readonly _extensionsStorageKeys = new Map<string, string[]>();
|
||||
get extensionsStorageKeys() {
|
||||
const result: [IExtensionIdWithVersion, ReadonlyArray<string>][] = [];
|
||||
@@ -98,11 +77,6 @@ export abstract class AbstractStorageKeysSyncRegistryService extends Disposable
|
||||
protected readonly _onDidChangeExtensionStorageKeys = this._register(new Emitter<[IExtensionIdWithVersion, ReadonlyArray<string>]>());
|
||||
readonly onDidChangeExtensionStorageKeys = this._onDidChangeExtensionStorageKeys.event;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this._register(toDisposable(() => this._storageKeys.clear()));
|
||||
}
|
||||
|
||||
getExtensioStorageKeys(extension: IExtensionIdWithVersion): ReadonlyArray<string> | undefined {
|
||||
return this._extensionsStorageKeys.get(ExtensionIdWithVersion.toKey(extension));
|
||||
}
|
||||
@@ -112,7 +86,6 @@ export abstract class AbstractStorageKeysSyncRegistryService extends Disposable
|
||||
this._onDidChangeExtensionStorageKeys.fire([extension, keys]);
|
||||
}
|
||||
|
||||
abstract registerStorageKey(key: IStorageKey): void;
|
||||
abstract registerExtensionStorageKeys(extension: IExtensionIdWithVersion, keys: string[]): void;
|
||||
}
|
||||
|
||||
@@ -120,13 +93,6 @@ export class StorageKeysSyncRegistryService extends AbstractStorageKeysSyncRegis
|
||||
|
||||
_serviceBrand: any;
|
||||
|
||||
registerStorageKey(storageKey: IStorageKey): void {
|
||||
if (!this._storageKeys.has(storageKey.key)) {
|
||||
this._storageKeys.set(storageKey.key, storageKey);
|
||||
this._onDidChangeStorageKeys.fire(this.storageKeys);
|
||||
}
|
||||
}
|
||||
|
||||
registerExtensionStorageKeys(extension: IExtensionIdWithVersion, keys: string[]): void {
|
||||
this.updateExtensionStorageKeys(extension, keys);
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import { IUserDataSyncAccountService } from 'vs/platform/userDataSync/common/use
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { isPromiseCanceledError } from 'vs/base/common/errors';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { IStorageService, StorageScope, IStorageChangeEvent } from 'vs/platform/storage/common/storage';
|
||||
import { IStorageService, StorageScope, IStorageValueChangeEvent } from 'vs/platform/storage/common/storage';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { IUserDataSyncMachinesService } from 'vs/platform/userDataSync/common/userDataSyncMachines';
|
||||
import { localize } from 'vs/nls';
|
||||
@@ -55,7 +55,7 @@ export class UserDataAutoSyncEnablementService extends Disposable implements _IU
|
||||
@IUserDataSyncStoreManagementService private readonly userDataSyncStoreManagementService: IUserDataSyncStoreManagementService,
|
||||
) {
|
||||
super();
|
||||
this._register(storageService.onDidChangeStorage(e => this.onDidStorageChange(e)));
|
||||
this._register(storageService.onDidChangeValue(e => this.onDidStorageChange(e)));
|
||||
}
|
||||
|
||||
isEnabled(defaultEnablement?: boolean): boolean {
|
||||
@@ -76,7 +76,7 @@ export class UserDataAutoSyncEnablementService extends Disposable implements _IU
|
||||
this.storageService.store(enablementKey, enabled, StorageScope.GLOBAL);
|
||||
}
|
||||
|
||||
private onDidStorageChange(storageChangeEvent: IStorageChangeEvent): void {
|
||||
private onDidStorageChange(storageChangeEvent: IStorageValueChangeEvent): void {
|
||||
if (storageChangeEvent.scope !== StorageScope.GLOBAL) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import { IUserDataSyncService, IUserDataSyncUtilService, IUserDataAutoSyncServic
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IStringDictionary } from 'vs/base/common/collections';
|
||||
import { FormattingOptions } from 'vs/base/common/jsonFormatter';
|
||||
import { IStorageKeysSyncRegistryService, IStorageKey, IExtensionIdWithVersion, AbstractStorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys';
|
||||
import { IStorageKeysSyncRegistryService, IExtensionIdWithVersion, AbstractStorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { IUserDataSyncMachinesService } from 'vs/platform/userDataSync/common/userDataSyncMachines';
|
||||
import { IUserDataSyncAccountService } from 'vs/platform/userDataSync/common/userDataSyncAccount';
|
||||
@@ -175,7 +175,7 @@ export class UserDataSyncUtilServiceClient implements IUserDataSyncUtilService {
|
||||
|
||||
}
|
||||
|
||||
type StorageKeysSyncRegistryServiceInitData = { storageKeys: ReadonlyArray<IStorageKey>, extensionsStorageKeys: ReadonlyArray<[IExtensionIdWithVersion, ReadonlyArray<string>]> };
|
||||
type StorageKeysSyncRegistryServiceInitData = { extensionsStorageKeys: ReadonlyArray<[IExtensionIdWithVersion, ReadonlyArray<string>]> };
|
||||
|
||||
export class StorageKeysSyncRegistryChannel implements IServerChannel {
|
||||
|
||||
@@ -183,7 +183,6 @@ export class StorageKeysSyncRegistryChannel implements IServerChannel {
|
||||
|
||||
listen(_: unknown, event: string): Event<any> {
|
||||
switch (event) {
|
||||
case 'onDidChangeStorageKeys': return this.service.onDidChangeStorageKeys;
|
||||
case 'onDidChangeExtensionStorageKeys': return this.service.onDidChangeExtensionStorageKeys;
|
||||
}
|
||||
throw new Error(`Event not found: ${event}`);
|
||||
@@ -191,8 +190,7 @@ export class StorageKeysSyncRegistryChannel implements IServerChannel {
|
||||
|
||||
call(context: any, command: string, args?: any): Promise<any> {
|
||||
switch (command) {
|
||||
case '_getInitialData': return Promise.resolve<StorageKeysSyncRegistryServiceInitData>({ storageKeys: this.service.storageKeys, extensionsStorageKeys: this.service.extensionsStorageKeys });
|
||||
case 'registerStorageKey': return Promise.resolve(this.service.registerStorageKey(args[0]));
|
||||
case '_getInitialData': return Promise.resolve<StorageKeysSyncRegistryServiceInitData>({ extensionsStorageKeys: this.service.extensionsStorageKeys });
|
||||
case 'registerExtensionStorageKeys': return Promise.resolve(this.service.registerExtensionStorageKeys(args[0], args[1]));
|
||||
}
|
||||
throw new Error('Invalid call');
|
||||
@@ -205,32 +203,18 @@ export class StorageKeysSyncRegistryChannelClient extends AbstractStorageKeysSyn
|
||||
|
||||
constructor(private readonly channel: IChannel) {
|
||||
super();
|
||||
this.channel.call<StorageKeysSyncRegistryServiceInitData>('_getInitialData').then(({ storageKeys, extensionsStorageKeys }) => {
|
||||
this.updateStorageKeys(storageKeys);
|
||||
this.channel.call<StorageKeysSyncRegistryServiceInitData>('_getInitialData').then(({ extensionsStorageKeys }) => {
|
||||
this.updateExtensionsStorageKeys(extensionsStorageKeys);
|
||||
this._register(this.channel.listen<ReadonlyArray<IStorageKey>>('onDidChangeStorageKeys')(storageKeys => this.updateStorageKeys(storageKeys)));
|
||||
this._register(this.channel.listen<[IExtensionIdentifierWithVersion, string[]]>('onDidChangeExtensionStorageKeys')(e => this.updateExtensionStorageKeys(e[0], e[1])));
|
||||
});
|
||||
}
|
||||
|
||||
private async updateStorageKeys(storageKeys: ReadonlyArray<IStorageKey>): Promise<void> {
|
||||
this._storageKeys.clear();
|
||||
for (const storageKey of storageKeys) {
|
||||
this._storageKeys.set(storageKey.key, storageKey);
|
||||
}
|
||||
this._onDidChangeStorageKeys.fire(this.storageKeys);
|
||||
}
|
||||
|
||||
private async updateExtensionsStorageKeys(extensionStorageKeys: ReadonlyArray<[IExtensionIdentifierWithVersion, ReadonlyArray<string>]>): Promise<void> {
|
||||
for (const [extension, keys] of extensionStorageKeys) {
|
||||
this.updateExtensionStorageKeys(extension, [...keys]);
|
||||
}
|
||||
}
|
||||
|
||||
registerStorageKey(storageKey: IStorageKey): void {
|
||||
this.channel.call('registerStorageKey', [storageKey]);
|
||||
}
|
||||
|
||||
registerExtensionStorageKeys(extension: IExtensionIdentifierWithVersion, keys: string[]): void {
|
||||
this.channel.call('registerExtensionStorageKeys', [extension, keys]);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import { IUserDataSyncResourceEnablementService, ALL_SYNC_RESOURCES, SyncResource } from 'vs/platform/userDataSync/common/userDataSync';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { IStorageService, IStorageChangeEvent, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { IStorageService, IStorageValueChangeEvent, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
|
||||
type SyncEnablementClassification = {
|
||||
@@ -28,7 +28,7 @@ export class UserDataSyncResourceEnablementService extends Disposable implements
|
||||
@ITelemetryService private readonly telemetryService: ITelemetryService,
|
||||
) {
|
||||
super();
|
||||
this._register(storageService.onDidChangeStorage(e => this.onDidStorageChange(e)));
|
||||
this._register(storageService.onDidChangeValue(e => this.onDidStorageChange(e)));
|
||||
}
|
||||
|
||||
isResourceEnabled(resource: SyncResource): boolean {
|
||||
@@ -43,7 +43,7 @@ export class UserDataSyncResourceEnablementService extends Disposable implements
|
||||
}
|
||||
}
|
||||
|
||||
private onDidStorageChange(storageChangeEvent: IStorageChangeEvent): void {
|
||||
private onDidStorageChange(storageChangeEvent: IStorageValueChangeEvent): void {
|
||||
if (storageChangeEvent.scope === StorageScope.GLOBAL) {
|
||||
const resourceKey = ALL_SYNC_RESOURCES.filter(resourceKey => getEnablementKey(resourceKey) === storageChangeEvent.key)[0];
|
||||
if (resourceKey) {
|
||||
|
||||
@@ -13,7 +13,7 @@ suite('GlobalStateMerge', () => {
|
||||
const local = { 'a': { version: 1, value: 'a' } };
|
||||
const remote = { 'a': { version: 1, value: 'a' } };
|
||||
|
||||
const actual = merge(local, remote, null, [{ key: 'a', version: 1 }], [], new NullLogService());
|
||||
const actual = merge(local, remote, null, [], new NullLogService());
|
||||
|
||||
assert.deepEqual(actual.local.added, {});
|
||||
assert.deepEqual(actual.local.updated, {});
|
||||
@@ -25,7 +25,7 @@ suite('GlobalStateMerge', () => {
|
||||
const local = { 'a': { version: 1, value: 'a' }, 'b': { version: 1, value: 'b' } };
|
||||
const remote = { 'a': { version: 1, value: 'a' }, 'b': { version: 1, value: 'b' } };
|
||||
|
||||
const actual = merge(local, remote, null, [{ key: 'a', version: 1 }, { key: 'b', version: 1 }], [], new NullLogService());
|
||||
const actual = merge(local, remote, null, [], new NullLogService());
|
||||
|
||||
assert.deepEqual(actual.local.added, {});
|
||||
assert.deepEqual(actual.local.updated, {});
|
||||
@@ -37,7 +37,7 @@ suite('GlobalStateMerge', () => {
|
||||
const local = { 'a': { version: 1, value: 'a' }, 'b': { version: 1, value: 'b' } };
|
||||
const remote = { 'b': { version: 1, value: 'b' }, 'a': { version: 1, value: 'a' } };
|
||||
|
||||
const actual = merge(local, remote, null, [{ key: 'a', version: 1 }, { key: 'b', version: 1 }], [], new NullLogService());
|
||||
const actual = merge(local, remote, null, [], new NullLogService());
|
||||
|
||||
assert.deepEqual(actual.local.added, {});
|
||||
assert.deepEqual(actual.local.updated, {});
|
||||
@@ -50,7 +50,7 @@ suite('GlobalStateMerge', () => {
|
||||
const remote = { 'b': { version: 1, value: 'b' }, 'a': { version: 1, value: 'a' } };
|
||||
const base = { 'b': { version: 1, value: 'a' } };
|
||||
|
||||
const actual = merge(local, remote, base, [{ key: 'a', version: 1 }, { key: 'b', version: 1 }], [], new NullLogService());
|
||||
const actual = merge(local, remote, base, [], new NullLogService());
|
||||
|
||||
assert.deepEqual(actual.local.added, {});
|
||||
assert.deepEqual(actual.local.updated, {});
|
||||
@@ -62,7 +62,7 @@ suite('GlobalStateMerge', () => {
|
||||
const local = { 'a': { version: 1, value: 'a' } };
|
||||
const remote = { 'b': { version: 1, value: 'b' }, 'a': { version: 1, value: 'a' } };
|
||||
|
||||
const actual = merge(local, remote, null, [{ key: 'a', version: 1 }, { key: 'b', version: 1 }], [], new NullLogService());
|
||||
const actual = merge(local, remote, null, [], new NullLogService());
|
||||
|
||||
assert.deepEqual(actual.local.added, { 'b': { version: 1, value: 'b' } });
|
||||
assert.deepEqual(actual.local.updated, {});
|
||||
@@ -74,7 +74,7 @@ suite('GlobalStateMerge', () => {
|
||||
const local = {};
|
||||
const remote = { 'b': { version: 1, value: 'b' }, 'a': { version: 1, value: 'a' } };
|
||||
|
||||
const actual = merge(local, remote, null, [{ key: 'a', version: 1 }, { key: 'b', version: 1 }], [], new NullLogService());
|
||||
const actual = merge(local, remote, null, [], new NullLogService());
|
||||
|
||||
assert.deepEqual(actual.local.added, { 'b': { version: 1, value: 'b' }, 'a': { version: 1, value: 'a' } });
|
||||
assert.deepEqual(actual.local.updated, {});
|
||||
@@ -86,7 +86,7 @@ suite('GlobalStateMerge', () => {
|
||||
const local = { 'a': { version: 1, value: 'a' } };
|
||||
const remote = { 'b': { version: 1, value: 'b' }, 'a': { version: 1, value: 'a' } };
|
||||
|
||||
const actual = merge(local, remote, local, [{ key: 'a', version: 1 }, { key: 'b', version: 1 }], [], new NullLogService());
|
||||
const actual = merge(local, remote, local, [], new NullLogService());
|
||||
|
||||
assert.deepEqual(actual.local.added, { 'b': { version: 1, value: 'b' } });
|
||||
assert.deepEqual(actual.local.updated, {});
|
||||
@@ -98,7 +98,7 @@ suite('GlobalStateMerge', () => {
|
||||
const local = { 'b': { version: 1, value: 'b' }, 'a': { version: 1, value: 'a' } };
|
||||
const remote = { 'a': { version: 1, value: 'a' } };
|
||||
|
||||
const actual = merge(local, remote, local, [{ key: 'a', version: 1 }, { key: 'b', version: 1 }], [], new NullLogService());
|
||||
const actual = merge(local, remote, local, [], new NullLogService());
|
||||
|
||||
assert.deepEqual(actual.local.added, {});
|
||||
assert.deepEqual(actual.local.updated, {});
|
||||
@@ -110,7 +110,7 @@ suite('GlobalStateMerge', () => {
|
||||
const local = { 'b': { version: 1, value: 'b' }, 'a': { version: 1, value: 'a' } };
|
||||
const remote = {};
|
||||
|
||||
const actual = merge(local, remote, local, [{ key: 'a', version: 1 }, { key: 'b', version: 1 }], [], new NullLogService());
|
||||
const actual = merge(local, remote, local, [], new NullLogService());
|
||||
|
||||
assert.deepEqual(actual.local.added, {});
|
||||
assert.deepEqual(actual.local.updated, {});
|
||||
@@ -122,7 +122,7 @@ suite('GlobalStateMerge', () => {
|
||||
const local = { 'a': { version: 1, value: 'a' } };
|
||||
const remote = { 'a': { version: 1, value: 'b' } };
|
||||
|
||||
const actual = merge(local, remote, local, [{ key: 'a', version: 1 }, { key: 'b', version: 1 }], [], new NullLogService());
|
||||
const actual = merge(local, remote, local, [], new NullLogService());
|
||||
|
||||
assert.deepEqual(actual.local.added, {});
|
||||
assert.deepEqual(actual.local.updated, { 'a': { version: 1, value: 'b' } });
|
||||
@@ -134,7 +134,7 @@ suite('GlobalStateMerge', () => {
|
||||
const local = { 'a': { version: 1, value: 'a' }, 'b': { version: 1, value: 'b' } };
|
||||
const remote = { 'a': { version: 1, value: 'd' }, 'c': { version: 1, value: 'c' } };
|
||||
|
||||
const actual = merge(local, remote, local, [{ key: 'a', version: 1 }, { key: 'b', version: 1 }, { key: 'c', version: 1 }], [], new NullLogService());
|
||||
const actual = merge(local, remote, local, [], new NullLogService());
|
||||
|
||||
assert.deepEqual(actual.local.added, { 'c': { version: 1, value: 'c' } });
|
||||
assert.deepEqual(actual.local.updated, { 'a': { version: 1, value: 'd' } });
|
||||
@@ -146,7 +146,7 @@ suite('GlobalStateMerge', () => {
|
||||
const local = { 'a': { version: 1, value: 'a' }, 'b': { version: 1, value: 'b' } };
|
||||
const remote = { 'a': { version: 1, value: 'a' } };
|
||||
|
||||
const actual = merge(local, remote, null, [{ key: 'a', version: 1 }, { key: 'b', version: 1 }, { key: 'c', version: 1 }], [], new NullLogService());
|
||||
const actual = merge(local, remote, null, [], new NullLogService());
|
||||
|
||||
assert.deepEqual(actual.local.added, {});
|
||||
assert.deepEqual(actual.local.updated, {});
|
||||
@@ -158,7 +158,7 @@ suite('GlobalStateMerge', () => {
|
||||
const local = { 'a': { version: 1, value: 'a' }, 'b': { version: 1, value: 'b' }, 'c': { version: 1, value: 'c' } };
|
||||
const remote = { 'a': { version: 1, value: 'a' } };
|
||||
|
||||
const actual = merge(local, remote, remote, [{ key: 'a', version: 1 }, { key: 'b', version: 1 }, { key: 'c', version: 1 }], [], new NullLogService());
|
||||
const actual = merge(local, remote, remote, [], new NullLogService());
|
||||
|
||||
assert.deepEqual(actual.local.added, {});
|
||||
assert.deepEqual(actual.local.updated, {});
|
||||
@@ -170,7 +170,7 @@ suite('GlobalStateMerge', () => {
|
||||
const local = { 'a': { version: 1, value: 'a' } };
|
||||
const remote = { 'a': { version: 1, value: 'a' }, 'b': { version: 1, value: 'b' } };
|
||||
|
||||
const actual = merge(local, remote, remote, [{ key: 'a', version: 1 }, { key: 'b', version: 1 }, { key: 'c', version: 1 }], [], new NullLogService());
|
||||
const actual = merge(local, remote, remote, [], new NullLogService());
|
||||
|
||||
assert.deepEqual(actual.local.added, {});
|
||||
assert.deepEqual(actual.local.updated, {});
|
||||
@@ -182,7 +182,7 @@ suite('GlobalStateMerge', () => {
|
||||
const local = { 'a': { version: 1, value: 'b' } };
|
||||
const remote = { 'a': { version: 1, value: 'a' } };
|
||||
|
||||
const actual = merge(local, remote, remote, [{ key: 'a', version: 1 }, { key: 'b', version: 1 }, { key: 'c', version: 1 }], [], new NullLogService());
|
||||
const actual = merge(local, remote, remote, [], new NullLogService());
|
||||
|
||||
assert.deepEqual(actual.local.added, {});
|
||||
assert.deepEqual(actual.local.updated, {});
|
||||
@@ -194,7 +194,7 @@ suite('GlobalStateMerge', () => {
|
||||
const local = { 'a': { version: 1, value: 'd' }, 'b': { version: 1, value: 'b' } };
|
||||
const remote = { 'a': { version: 1, value: 'a' }, 'c': { version: 1, value: 'c' } };
|
||||
|
||||
const actual = merge(local, remote, remote, [{ key: 'a', version: 1 }, { key: 'b', version: 1 }, { key: 'c', version: 1 }], [], new NullLogService());
|
||||
const actual = merge(local, remote, remote, [], new NullLogService());
|
||||
|
||||
assert.deepEqual(actual.local.added, {});
|
||||
assert.deepEqual(actual.local.updated, {});
|
||||
@@ -206,7 +206,7 @@ suite('GlobalStateMerge', () => {
|
||||
const local = { 'a': { version: 1, value: 'a' } };
|
||||
const remote = { 'a': { version: 1, value: 'b' } };
|
||||
|
||||
const actual = merge(local, remote, null, [{ key: 'a', version: 1 }, { key: 'b', version: 1 }, { key: 'c', version: 1 }], [], new NullLogService());
|
||||
const actual = merge(local, remote, null, [], new NullLogService());
|
||||
|
||||
assert.deepEqual(actual.local.added, {});
|
||||
assert.deepEqual(actual.local.updated, { 'a': { version: 1, value: 'b' } });
|
||||
@@ -219,7 +219,7 @@ suite('GlobalStateMerge', () => {
|
||||
const local = { 'a': { version: 1, value: 'a' }, 'b': { version: 1, value: 'd' } };
|
||||
const remote = { 'a': { version: 1, value: 'a' }, 'c': { version: 1, value: 'c' } };
|
||||
|
||||
const actual = merge(local, remote, base, [{ key: 'a', version: 1 }, { key: 'b', version: 1 }, { key: 'c', version: 1 }], [], new NullLogService());
|
||||
const actual = merge(local, remote, base, [], new NullLogService());
|
||||
|
||||
assert.deepEqual(actual.local.added, { 'c': { version: 1, value: 'c' } });
|
||||
assert.deepEqual(actual.local.updated, {});
|
||||
@@ -232,10 +232,10 @@ suite('GlobalStateMerge', () => {
|
||||
const local = {};
|
||||
const remote = { 'a': { version: 1, value: 'b' } };
|
||||
|
||||
const actual = merge(local, remote, base, [{ key: 'a', version: 1 }, { key: 'b', version: 1 }, { key: 'c', version: 1 }], [], new NullLogService());
|
||||
const actual = merge(local, remote, base, [], new NullLogService());
|
||||
|
||||
assert.deepEqual(actual.local.added, {});
|
||||
assert.deepEqual(actual.local.updated, { 'a': { version: 1, value: 'b' } });
|
||||
assert.deepEqual(actual.local.added, { 'a': { version: 1, value: 'b' } });
|
||||
assert.deepEqual(actual.local.updated, {});
|
||||
assert.deepEqual(actual.local.removed, []);
|
||||
assert.deepEqual(actual.remote, null);
|
||||
});
|
||||
@@ -245,7 +245,7 @@ suite('GlobalStateMerge', () => {
|
||||
const local = { 'a': { version: 1, value: 'd' } };
|
||||
const remote = { 'a': { version: 1, value: 'b' } };
|
||||
|
||||
const actual = merge(local, remote, base, [{ key: 'a', version: 1 }, { key: 'b', version: 1 }, { key: 'c', version: 1 }], [], new NullLogService());
|
||||
const actual = merge(local, remote, base, [], new NullLogService());
|
||||
|
||||
assert.deepEqual(actual.local.added, {});
|
||||
assert.deepEqual(actual.local.updated, { 'a': { version: 1, value: 'b' } });
|
||||
@@ -253,11 +253,11 @@ suite('GlobalStateMerge', () => {
|
||||
assert.deepEqual(actual.remote, null);
|
||||
});
|
||||
|
||||
test('merge when a new entry is added to remote but not a registered key', async () => {
|
||||
test('merge when a new entry is added to remote but scoped to machine locally', async () => {
|
||||
const local = { 'a': { version: 1, value: 'a' } };
|
||||
const remote = { 'b': { version: 1, value: 'b' }, 'a': { version: 1, value: 'a' } };
|
||||
|
||||
const actual = merge(local, remote, null, [{ key: 'a', version: 1 }], [], new NullLogService());
|
||||
const actual = merge(local, remote, null, ['b'], new NullLogService());
|
||||
|
||||
assert.deepEqual(actual.local.added, {});
|
||||
assert.deepEqual(actual.local.updated, {});
|
||||
@@ -265,23 +265,11 @@ suite('GlobalStateMerge', () => {
|
||||
assert.deepEqual(actual.remote, null);
|
||||
});
|
||||
|
||||
test('merge when a new entry is added to remote but different version', async () => {
|
||||
const local = { 'a': { version: 1, value: 'a' } };
|
||||
const remote = { 'b': { version: 2, value: 'b' }, 'a': { version: 1, value: 'a' } };
|
||||
|
||||
const actual = merge(local, remote, null, [{ key: 'a', version: 1 }, { key: 'b', version: 1 }], [], new NullLogService());
|
||||
|
||||
assert.deepEqual(actual.local.added, {});
|
||||
assert.deepEqual(actual.local.updated, {});
|
||||
assert.deepEqual(actual.local.removed, []);
|
||||
assert.deepEqual(actual.remote, null);
|
||||
});
|
||||
|
||||
test('merge when an entry is updated to remote but not a registered key', async () => {
|
||||
test('merge when an entry is updated to remote but scoped to machine locally', async () => {
|
||||
const local = { 'a': { version: 1, value: 'a' } };
|
||||
const remote = { 'a': { version: 1, value: 'b' } };
|
||||
|
||||
const actual = merge(local, remote, local, [], [], new NullLogService());
|
||||
const actual = merge(local, remote, local, ['a'], new NullLogService());
|
||||
|
||||
assert.deepEqual(actual.local.added, {});
|
||||
assert.deepEqual(actual.local.updated, {});
|
||||
@@ -289,11 +277,12 @@ suite('GlobalStateMerge', () => {
|
||||
assert.deepEqual(actual.remote, null);
|
||||
});
|
||||
|
||||
test('merge when a new entry is updated to remote but different version', async () => {
|
||||
const local = { 'a': { version: 1, value: 'a' }, 'b': { version: 1, value: 'b' } };
|
||||
test('merge when a local value is removed and iscoped to machine locally', async () => {
|
||||
const base = { 'a': { version: 1, value: 'a' }, 'b': { version: 1, value: 'b' } };
|
||||
const local = { 'a': { version: 1, value: 'a' } };
|
||||
const remote = { 'b': { version: 2, value: 'b' }, 'a': { version: 1, value: 'a' } };
|
||||
|
||||
const actual = merge(local, remote, local, [{ key: 'a', version: 1 }, { key: 'b', version: 1 }], [], new NullLogService());
|
||||
const actual = merge(local, remote, base, ['b'], new NullLogService());
|
||||
|
||||
assert.deepEqual(actual.local.added, {});
|
||||
assert.deepEqual(actual.local.updated, {});
|
||||
@@ -301,23 +290,12 @@ suite('GlobalStateMerge', () => {
|
||||
assert.deepEqual(actual.remote, null);
|
||||
});
|
||||
|
||||
test('merge when a local value is update with lower version', async () => {
|
||||
const local = { 'a': { version: 1, value: 'a' }, 'b': { version: 1, value: 'c' } };
|
||||
const remote = { 'b': { version: 2, value: 'b' }, 'a': { version: 1, value: 'a' } };
|
||||
test('merge when local moved forwared by changing a key to machine scope', async () => {
|
||||
const base = { 'a': { version: 1, value: 'a' }, 'b': { version: 1, value: 'b' } };
|
||||
const remote = { 'a': { version: 1, value: 'a' }, 'b': { version: 1, value: 'b' } };
|
||||
const local = { 'a': { version: 1, value: 'a' } };
|
||||
|
||||
const actual = merge(local, remote, remote, [{ key: 'a', version: 1 }, { key: 'b', version: 1 }], [], new NullLogService());
|
||||
|
||||
assert.deepEqual(actual.local.added, {});
|
||||
assert.deepEqual(actual.local.updated, {});
|
||||
assert.deepEqual(actual.local.removed, []);
|
||||
assert.deepEqual(actual.remote, null);
|
||||
});
|
||||
|
||||
test('merge when a local value is update with higher version', async () => {
|
||||
const local = { 'a': { version: 1, value: 'a' }, 'b': { version: 2, value: 'c' } };
|
||||
const remote = { 'b': { version: 1, value: 'b' }, 'a': { version: 1, value: 'a' } };
|
||||
|
||||
const actual = merge(local, remote, remote, [{ key: 'a', version: 1 }, { key: 'b', version: 2 }], [], new NullLogService());
|
||||
const actual = merge(local, remote, base, ['b'], new NullLogService());
|
||||
|
||||
assert.deepEqual(actual.local.added, {});
|
||||
assert.deepEqual(actual.local.updated, {});
|
||||
@@ -325,56 +303,4 @@ suite('GlobalStateMerge', () => {
|
||||
assert.deepEqual(actual.remote, local);
|
||||
});
|
||||
|
||||
test('merge when a local value is removed but not registered', async () => {
|
||||
const base = { 'a': { version: 1, value: 'a' }, 'b': { version: 1, value: 'b' } };
|
||||
const local = { 'a': { version: 1, value: 'a' } };
|
||||
const remote = { 'b': { version: 2, value: 'b' }, 'a': { version: 1, value: 'a' } };
|
||||
|
||||
const actual = merge(local, remote, base, [{ key: 'a', version: 1 }], [], new NullLogService());
|
||||
|
||||
assert.deepEqual(actual.local.added, {});
|
||||
assert.deepEqual(actual.local.updated, {});
|
||||
assert.deepEqual(actual.local.removed, []);
|
||||
assert.deepEqual(actual.remote, null);
|
||||
});
|
||||
|
||||
test('merge when a local value is removed with lower version', async () => {
|
||||
const base = { 'a': { version: 1, value: 'a' }, 'b': { version: 1, value: 'b' } };
|
||||
const local = { 'a': { version: 1, value: 'a' } };
|
||||
const remote = { 'b': { version: 2, value: 'b' }, 'a': { version: 1, value: 'a' } };
|
||||
|
||||
const actual = merge(local, remote, base, [{ key: 'a', version: 1 }, { key: 'b', version: 1 }], [], new NullLogService());
|
||||
|
||||
assert.deepEqual(actual.local.added, {});
|
||||
assert.deepEqual(actual.local.updated, {});
|
||||
assert.deepEqual(actual.local.removed, []);
|
||||
assert.deepEqual(actual.remote, null);
|
||||
});
|
||||
|
||||
test('merge when a local value is removed with higher version', async () => {
|
||||
const base = { 'a': { version: 1, value: 'a' }, 'b': { version: 1, value: 'b' } };
|
||||
const local = { 'a': { version: 1, value: 'a' } };
|
||||
const remote = { 'b': { version: 1, value: 'b' }, 'a': { version: 1, value: 'a' } };
|
||||
|
||||
const actual = merge(local, remote, base, [{ key: 'a', version: 1 }, { key: 'b', version: 2 }], [], new NullLogService());
|
||||
|
||||
assert.deepEqual(actual.local.added, {});
|
||||
assert.deepEqual(actual.local.updated, {});
|
||||
assert.deepEqual(actual.local.removed, []);
|
||||
assert.deepEqual(actual.remote, local);
|
||||
});
|
||||
|
||||
test('merge when a local value is not yet registered', async () => {
|
||||
const base = { 'a': { version: 1, value: 'a' }, 'b': { version: 1, value: 'b' } };
|
||||
const local = { 'a': { version: 1, value: 'a' } };
|
||||
const remote = { 'b': { version: 1, value: 'b' }, 'a': { version: 1, value: 'a' } };
|
||||
|
||||
const actual = merge(local, remote, base, [{ key: 'a', version: 1 }], [], new NullLogService());
|
||||
|
||||
assert.deepEqual(actual.local.added, {});
|
||||
assert.deepEqual(actual.local.updated, {});
|
||||
assert.deepEqual(actual.local.removed, []);
|
||||
assert.deepEqual(actual.remote, null);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -10,10 +10,9 @@ import { DisposableStore, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { UserDataSyncService } from 'vs/platform/userDataSync/common/userDataSyncService';
|
||||
import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
|
||||
import { GlobalStateSynchroniser } from 'vs/platform/userDataSync/common/globalStateSync';
|
||||
import { VSBuffer } from 'vs/base/common/buffer';
|
||||
import { IStorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys';
|
||||
|
||||
|
||||
suite('GlobalStateSync', () => {
|
||||
@@ -28,17 +27,11 @@ suite('GlobalStateSync', () => {
|
||||
setup(async () => {
|
||||
testClient = disposableStore.add(new UserDataSyncClient(server));
|
||||
await testClient.setUp(true);
|
||||
let storageKeysSyncRegistryService = testClient.instantiationService.get(IStorageKeysSyncRegistryService);
|
||||
storageKeysSyncRegistryService.registerStorageKey({ key: 'a', version: 1 });
|
||||
storageKeysSyncRegistryService.registerStorageKey({ key: 'b', version: 1 });
|
||||
testObject = (testClient.instantiationService.get(IUserDataSyncService) as UserDataSyncService).getSynchroniser(SyncResource.GlobalState) as GlobalStateSynchroniser;
|
||||
disposableStore.add(toDisposable(() => testClient.instantiationService.get(IUserDataSyncStoreService).clear()));
|
||||
|
||||
client2 = disposableStore.add(new UserDataSyncClient(server));
|
||||
await client2.setUp(true);
|
||||
storageKeysSyncRegistryService = client2.instantiationService.get(IStorageKeysSyncRegistryService);
|
||||
storageKeysSyncRegistryService.registerStorageKey({ key: 'a', version: 1 });
|
||||
storageKeysSyncRegistryService.registerStorageKey({ key: 'b', version: 1 });
|
||||
});
|
||||
|
||||
teardown(() => disposableStore.clear());
|
||||
@@ -72,7 +65,7 @@ suite('GlobalStateSync', () => {
|
||||
|
||||
test('when global state is created after first sync', async () => {
|
||||
await testObject.sync(await testClient.manifest());
|
||||
updateStorage('a', 'value1', testClient);
|
||||
updateUserStorage('a', 'value1', testClient);
|
||||
|
||||
let lastSyncUserData = await testObject.getLastSyncUserData();
|
||||
const manifest = await testClient.manifest();
|
||||
@@ -91,7 +84,8 @@ suite('GlobalStateSync', () => {
|
||||
});
|
||||
|
||||
test('first time sync - outgoing to server (no state)', async () => {
|
||||
updateStorage('a', 'value1', testClient);
|
||||
updateUserStorage('a', 'value1', testClient);
|
||||
updateMachineStorage('b', 'value1', testClient);
|
||||
await updateLocale(testClient);
|
||||
|
||||
await testObject.sync(await testClient.manifest());
|
||||
@@ -105,7 +99,7 @@ suite('GlobalStateSync', () => {
|
||||
});
|
||||
|
||||
test('first time sync - incoming from server (no state)', async () => {
|
||||
updateStorage('a', 'value1', client2);
|
||||
updateUserStorage('a', 'value1', client2);
|
||||
await updateLocale(client2);
|
||||
await client2.sync();
|
||||
|
||||
@@ -118,10 +112,10 @@ suite('GlobalStateSync', () => {
|
||||
});
|
||||
|
||||
test('first time sync when storage exists', async () => {
|
||||
updateStorage('a', 'value1', client2);
|
||||
updateUserStorage('a', 'value1', client2);
|
||||
await client2.sync();
|
||||
|
||||
updateStorage('b', 'value2', testClient);
|
||||
updateUserStorage('b', 'value2', testClient);
|
||||
await testObject.sync(await testClient.manifest());
|
||||
assert.equal(testObject.status, SyncStatus.Idle);
|
||||
assert.deepEqual(testObject.conflicts, []);
|
||||
@@ -136,10 +130,10 @@ suite('GlobalStateSync', () => {
|
||||
});
|
||||
|
||||
test('first time sync when storage exists - has conflicts', async () => {
|
||||
updateStorage('a', 'value1', client2);
|
||||
updateUserStorage('a', 'value1', client2);
|
||||
await client2.sync();
|
||||
|
||||
updateStorage('a', 'value2', client2);
|
||||
updateUserStorage('a', 'value2', client2);
|
||||
await testObject.sync(await testClient.manifest());
|
||||
|
||||
assert.equal(testObject.status, SyncStatus.Idle);
|
||||
@@ -154,10 +148,10 @@ suite('GlobalStateSync', () => {
|
||||
});
|
||||
|
||||
test('sync adding a storage value', async () => {
|
||||
updateStorage('a', 'value1', testClient);
|
||||
updateUserStorage('a', 'value1', testClient);
|
||||
await testObject.sync(await testClient.manifest());
|
||||
|
||||
updateStorage('b', 'value2', testClient);
|
||||
updateUserStorage('b', 'value2', testClient);
|
||||
await testObject.sync(await testClient.manifest());
|
||||
assert.equal(testObject.status, SyncStatus.Idle);
|
||||
assert.deepEqual(testObject.conflicts, []);
|
||||
@@ -172,10 +166,10 @@ suite('GlobalStateSync', () => {
|
||||
});
|
||||
|
||||
test('sync updating a storage value', async () => {
|
||||
updateStorage('a', 'value1', testClient);
|
||||
updateUserStorage('a', 'value1', testClient);
|
||||
await testObject.sync(await testClient.manifest());
|
||||
|
||||
updateStorage('a', 'value2', testClient);
|
||||
updateUserStorage('a', 'value2', testClient);
|
||||
await testObject.sync(await testClient.manifest());
|
||||
assert.equal(testObject.status, SyncStatus.Idle);
|
||||
assert.deepEqual(testObject.conflicts, []);
|
||||
@@ -189,8 +183,8 @@ suite('GlobalStateSync', () => {
|
||||
});
|
||||
|
||||
test('sync removing a storage value', async () => {
|
||||
updateStorage('a', 'value1', testClient);
|
||||
updateStorage('b', 'value2', testClient);
|
||||
updateUserStorage('a', 'value1', testClient);
|
||||
updateUserStorage('b', 'value2', testClient);
|
||||
await testObject.sync(await testClient.manifest());
|
||||
|
||||
removeStorage('b', testClient);
|
||||
@@ -218,9 +212,14 @@ suite('GlobalStateSync', () => {
|
||||
await fileService.writeFile(environmentService.argvResource, VSBuffer.fromString(JSON.stringify({ 'locale': 'en' })));
|
||||
}
|
||||
|
||||
function updateStorage(key: string, value: string, client: UserDataSyncClient): void {
|
||||
function updateUserStorage(key: string, value: string, client: UserDataSyncClient): void {
|
||||
const storageService = client.instantiationService.get(IStorageService);
|
||||
storageService.store(key, value, StorageScope.GLOBAL);
|
||||
storageService.store2(key, value, StorageScope.GLOBAL, StorageTarget.USER);
|
||||
}
|
||||
|
||||
function updateMachineStorage(key: string, value: string, client: UserDataSyncClient): void {
|
||||
const storageService = client.instantiationService.get(IStorageService);
|
||||
storageService.store2(key, value, StorageScope.GLOBAL, StorageTarget.MACHINE);
|
||||
}
|
||||
|
||||
function removeStorage(key: string, client: UserDataSyncClient): void {
|
||||
|
||||
@@ -10,11 +10,10 @@ import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
|
||||
import { IAuthenticationService, AllowedExtension, readAllowedExtensions, getAuthenticationProviderActivationEvent } from 'vs/workbench/services/authentication/browser/authenticationService';
|
||||
import { ExtHostAuthenticationShape, ExtHostContext, IExtHostContext, MainContext, MainThreadAuthenticationShape } from '../common/extHost.protocol';
|
||||
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
|
||||
import Severity from 'vs/base/common/severity';
|
||||
import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import { IStorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys';
|
||||
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
|
||||
import { fromNow } from 'vs/base/common/date';
|
||||
import { ActivationKind, IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
||||
@@ -83,7 +82,6 @@ export class MainThreadAuthenticationProvider extends Disposable {
|
||||
public readonly label: string,
|
||||
public readonly supportsMultipleAccounts: boolean,
|
||||
private readonly notificationService: INotificationService,
|
||||
private readonly storageKeysSyncRegistryService: IStorageKeysSyncRegistryService,
|
||||
private readonly storageService: IStorageService,
|
||||
private readonly quickInputService: IQuickInputService,
|
||||
private readonly dialogService: IDialogService
|
||||
@@ -122,7 +120,7 @@ export class MainThreadAuthenticationProvider extends Disposable {
|
||||
|
||||
quickPick.onDidAccept(() => {
|
||||
const updatedAllowedList = quickPick.selectedItems.map(item => item.extension);
|
||||
this.storageService.store(`${this.id}-${accountName}`, JSON.stringify(updatedAllowedList), StorageScope.GLOBAL);
|
||||
this.storageService.store2(`${this.id}-${accountName}`, JSON.stringify(updatedAllowedList), StorageScope.GLOBAL, StorageTarget.USER);
|
||||
|
||||
quickPick.dispose();
|
||||
});
|
||||
@@ -153,8 +151,6 @@ export class MainThreadAuthenticationProvider extends Disposable {
|
||||
} else {
|
||||
this._accounts.set(session.account.label, [session.id]);
|
||||
}
|
||||
|
||||
this.storageKeysSyncRegistryService.registerStorageKey({ key: `${this.id}-${session.account.label}`, version: 1 });
|
||||
}
|
||||
|
||||
async signOut(accountName: string): Promise<void> {
|
||||
@@ -220,7 +216,6 @@ export class MainThreadAuthentication extends Disposable implements MainThreadAu
|
||||
@IDialogService private readonly dialogService: IDialogService,
|
||||
@IStorageService private readonly storageService: IStorageService,
|
||||
@INotificationService private readonly notificationService: INotificationService,
|
||||
@IStorageKeysSyncRegistryService private readonly storageKeysSyncRegistryService: IStorageKeysSyncRegistryService,
|
||||
@IRemoteAgentService private readonly remoteAgentService: IRemoteAgentService,
|
||||
@IQuickInputService private readonly quickInputService: IQuickInputService,
|
||||
@IExtensionService private readonly extensionService: IExtensionService,
|
||||
@@ -259,7 +254,7 @@ export class MainThreadAuthentication extends Disposable implements MainThreadAu
|
||||
}
|
||||
|
||||
async $registerAuthenticationProvider(id: string, label: string, supportsMultipleAccounts: boolean): Promise<void> {
|
||||
const provider = new MainThreadAuthenticationProvider(this._proxy, id, label, supportsMultipleAccounts, this.notificationService, this.storageKeysSyncRegistryService, this.storageService, this.quickInputService, this.dialogService);
|
||||
const provider = new MainThreadAuthenticationProvider(this._proxy, id, label, supportsMultipleAccounts, this.notificationService, this.storageService, this.quickInputService, this.dialogService);
|
||||
await provider.initialize();
|
||||
this.authenticationService.registerAuthenticationProvider(id, provider);
|
||||
}
|
||||
@@ -383,7 +378,7 @@ export class MainThreadAuthentication extends Disposable implements MainThreadAu
|
||||
const allowList = readAllowedExtensions(this.storageService, providerId, accountName);
|
||||
if (!allowList.find(allowed => allowed.id === extensionId)) {
|
||||
allowList.push({ id: extensionId, name: extensionName });
|
||||
this.storageService.store(`${providerId}-${accountName}`, JSON.stringify(allowList), StorageScope.GLOBAL);
|
||||
this.storageService.store2(`${providerId}-${accountName}`, JSON.stringify(allowList), StorageScope.GLOBAL, StorageTarget.USER);
|
||||
}
|
||||
|
||||
this.storageService.store(`${extensionName}-${providerId}`, session.id, StorageScope.GLOBAL);
|
||||
@@ -435,7 +430,7 @@ export class MainThreadAuthentication extends Disposable implements MainThreadAu
|
||||
if (allow) {
|
||||
addAccountUsage(this.storageService, providerId, accountName, extensionId, extensionName);
|
||||
allowList.push({ id: extensionId, name: extensionName });
|
||||
this.storageService.store(`${providerId}-${accountName}`, JSON.stringify(allowList), StorageScope.GLOBAL);
|
||||
this.storageService.store2(`${providerId}-${accountName}`, JSON.stringify(allowList), StorageScope.GLOBAL, StorageTarget.USER);
|
||||
}
|
||||
|
||||
return allow;
|
||||
@@ -458,7 +453,7 @@ export class MainThreadAuthentication extends Disposable implements MainThreadAu
|
||||
const allowList = readAllowedExtensions(this.storageService, providerId, accountName);
|
||||
if (!allowList.find(allowed => allowed.id === extensionId)) {
|
||||
allowList.push({ id: extensionId, name: extensionName });
|
||||
this.storageService.store(`${providerId}-${accountName}`, JSON.stringify(allowList), StorageScope.GLOBAL);
|
||||
this.storageService.store2(`${providerId}-${accountName}`, JSON.stringify(allowList), StorageScope.GLOBAL, StorageTarget.USER);
|
||||
}
|
||||
|
||||
this.storageService.store(`${extensionName}-${providerId}`, sessionId, StorageScope.GLOBAL);
|
||||
|
||||
@@ -27,7 +27,7 @@ export class MainThreadStorage implements MainThreadStorageShape {
|
||||
this._storageKeysSyncRegistryService = storageKeysSyncRegistryService;
|
||||
this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostStorage);
|
||||
|
||||
this._storageListener = this._storageService.onDidChangeStorage(e => {
|
||||
this._storageListener = this._storageService.onDidChangeValue(e => {
|
||||
const shared = e.scope === StorageScope.GLOBAL;
|
||||
if (shared && this._sharedStorageKeysToWatch.has(e.key)) {
|
||||
try {
|
||||
|
||||
@@ -16,7 +16,7 @@ import { PanelPart } from 'vs/workbench/browser/parts/panel/panelPart';
|
||||
import { PanelRegistry, Extensions as PanelExtensions } from 'vs/workbench/browser/panel';
|
||||
import { Position, Parts, PanelOpensMaximizedOptions, IWorkbenchLayoutService, positionFromString, positionToString, panelOpensMaximizedFromString } from 'vs/workbench/services/layout/browser/layoutService';
|
||||
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
|
||||
import { IStorageService, StorageScope, WillSaveStateReason } from 'vs/platform/storage/common/storage';
|
||||
import { IStorageService, StorageScope, StorageTarget, WillSaveStateReason } from 'vs/platform/storage/common/storage';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
|
||||
import { IPanelService } from 'vs/workbench/services/panel/common/panelService';
|
||||
@@ -673,7 +673,7 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
}
|
||||
|
||||
if (sidebarState.length) {
|
||||
storageService.store(ActivitybarPart.PINNED_VIEW_CONTAINERS, JSON.stringify(sidebarState), StorageScope.GLOBAL);
|
||||
storageService.store2(ActivitybarPart.PINNED_VIEW_CONTAINERS, JSON.stringify(sidebarState), StorageScope.GLOBAL, StorageTarget.USER);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -743,7 +743,7 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
}
|
||||
|
||||
if (panelState.length) {
|
||||
storageService.store(PanelPart.PINNED_PANELS, JSON.stringify(panelState), StorageScope.GLOBAL);
|
||||
storageService.store2(PanelPart.PINNED_PANELS, JSON.stringify(panelState), StorageScope.GLOBAL, StorageTarget.USER);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ import { getCurrentAuthenticationSessionInfo, IAuthenticationService } from 'vs/
|
||||
import { AuthenticationSession } from 'vs/editor/common/modes';
|
||||
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
|
||||
import { ActionViewItem } from 'vs/base/browser/ui/actionbar/actionViewItems';
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IProductService } from 'vs/platform/product/common/productService';
|
||||
import { AnchorAlignment } from 'vs/base/browser/ui/contextview/contextview';
|
||||
@@ -235,7 +235,7 @@ export class AccountsActionViewItem extends ActivityActionViewItem {
|
||||
}
|
||||
|
||||
menus.push(new Action('hide', nls.localize('hide', "Hide"), undefined, true, _ => {
|
||||
this.storageService.store(ACCOUNTS_VISIBILITY_PREFERENCE_KEY, false, StorageScope.GLOBAL);
|
||||
this.storageService.store2(ACCOUNTS_VISIBILITY_PREFERENCE_KEY, false, StorageScope.GLOBAL, StorageTarget.USER);
|
||||
return Promise.resolve();
|
||||
}));
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ import { ACTIVITY_BAR_BACKGROUND, ACTIVITY_BAR_BORDER, ACTIVITY_BAR_FOREGROUND,
|
||||
import { contrastBorder } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { CompositeBar, ICompositeBarItem, CompositeDragAndDrop } from 'vs/workbench/browser/parts/compositeBar';
|
||||
import { Dimension, createCSSRule, asCSSUrl, addDisposableListener, EventType } from 'vs/base/browser/dom';
|
||||
import { IStorageService, StorageScope, IStorageChangeEvent } from 'vs/platform/storage/common/storage';
|
||||
import { IStorageService, StorageScope, IStorageValueChangeEvent, StorageTarget } from 'vs/platform/storage/common/storage';
|
||||
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import { URI, UriComponents } from 'vs/base/common/uri';
|
||||
import { ToggleCompositePinnedAction, ICompositeBarColors, ActivityAction, ICompositeActivity } from 'vs/workbench/browser/parts/compositeBarActions';
|
||||
@@ -34,7 +34,6 @@ import { CustomMenubarControl } from 'vs/workbench/browser/parts/titlebar/menuba
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { getMenuBarVisibility } from 'vs/platform/windows/common/windows';
|
||||
import { isWeb } from 'vs/base/common/platform';
|
||||
import { IStorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys';
|
||||
import { Before2D } from 'vs/workbench/browser/dnd';
|
||||
import { Codicon, iconRegistry } from 'vs/base/common/codicons';
|
||||
import { Action, Separator } from 'vs/base/common/actions';
|
||||
@@ -125,14 +124,9 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
@IContextKeyService private readonly contextKeyService: IContextKeyService,
|
||||
@IConfigurationService private readonly configurationService: IConfigurationService,
|
||||
@IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService,
|
||||
@IStorageKeysSyncRegistryService storageKeysSyncRegistryService: IStorageKeysSyncRegistryService
|
||||
) {
|
||||
super(Parts.ACTIVITYBAR_PART, { hasTitle: false }, themeService, storageService, layoutService);
|
||||
|
||||
storageKeysSyncRegistryService.registerStorageKey({ key: ActivitybarPart.PINNED_VIEW_CONTAINERS, version: 1 });
|
||||
storageKeysSyncRegistryService.registerStorageKey({ key: ActivitybarPart.HOME_BAR_VISIBILITY_PREFERENCE, version: 1 });
|
||||
storageKeysSyncRegistryService.registerStorageKey({ key: ACCOUNTS_VISIBILITY_PREFERENCE_KEY, version: 1 });
|
||||
|
||||
this.migrateFromOldCachedViewContainersValue();
|
||||
|
||||
for (const cachedViewContainer of this.cachedViewContainers) {
|
||||
@@ -253,7 +247,7 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
disposables.clear();
|
||||
this.onDidRegisterExtensions();
|
||||
this.compositeBar.onDidChange(() => this.saveCachedViewContainers(), this, disposables);
|
||||
this.storageService.onDidChangeStorage(e => this.onDidStorageChange(e), this, disposables);
|
||||
this.storageService.onDidChangeValue(e => this.onDidStorageValueChange(e), this, disposables);
|
||||
}));
|
||||
|
||||
// Register for configuration changes
|
||||
@@ -841,7 +835,7 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
return this.viewDescriptorService.getViewContainersByLocation(this.location);
|
||||
}
|
||||
|
||||
private onDidStorageChange(e: IStorageChangeEvent): void {
|
||||
private onDidStorageValueChange(e: IStorageValueChangeEvent): void {
|
||||
if (e.key === ActivitybarPart.PINNED_VIEW_CONTAINERS && e.scope === StorageScope.GLOBAL
|
||||
&& this.pinnedViewContainersValue !== this.getStoredPinnedViewContainersValue() /* This checks if current window changed the value or not */) {
|
||||
this._pinnedViewContainersValue = undefined;
|
||||
@@ -971,7 +965,7 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
}
|
||||
|
||||
private setStoredPinnedViewContainersValue(value: string): void {
|
||||
this.storageService.store(ActivitybarPart.PINNED_VIEW_CONTAINERS, value, StorageScope.GLOBAL);
|
||||
this.storageService.store2(ActivitybarPart.PINNED_VIEW_CONTAINERS, value, StorageScope.GLOBAL, StorageTarget.USER);
|
||||
}
|
||||
|
||||
private getPlaceholderViewContainers(): IPlaceholderViewContainer[] {
|
||||
@@ -1011,7 +1005,7 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
}
|
||||
|
||||
private set homeBarVisibilityPreference(value: boolean) {
|
||||
this.storageService.store(ActivitybarPart.HOME_BAR_VISIBILITY_PREFERENCE, value, StorageScope.GLOBAL);
|
||||
this.storageService.store2(ActivitybarPart.HOME_BAR_VISIBILITY_PREFERENCE, value, StorageScope.GLOBAL, StorageTarget.USER);
|
||||
}
|
||||
|
||||
private get accountsVisibilityPreference(): boolean {
|
||||
@@ -1019,7 +1013,7 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
}
|
||||
|
||||
private set accountsVisibilityPreference(value: boolean) {
|
||||
this.storageService.store(ACCOUNTS_VISIBILITY_PREFERENCE_KEY, value, StorageScope.GLOBAL);
|
||||
this.storageService.store2(ACCOUNTS_VISIBILITY_PREFERENCE_KEY, value, StorageScope.GLOBAL, StorageTarget.USER);
|
||||
}
|
||||
|
||||
private migrateFromOldCachedViewContainersValue(): void {
|
||||
|
||||
@@ -13,7 +13,7 @@ import { CompositePart, ICompositeTitleLabel } from 'vs/workbench/browser/parts/
|
||||
import { Panel, PanelRegistry, Extensions as PanelExtensions, PanelDescriptor } from 'vs/workbench/browser/panel';
|
||||
import { IPanelService, IPanelIdentifier } from 'vs/workbench/services/panel/common/panelService';
|
||||
import { IWorkbenchLayoutService, Parts, Position } from 'vs/workbench/services/layout/browser/layoutService';
|
||||
import { IStorageService, StorageScope, IStorageChangeEvent } from 'vs/platform/storage/common/storage';
|
||||
import { IStorageService, StorageScope, IStorageValueChangeEvent, StorageTarget } from 'vs/platform/storage/common/storage';
|
||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
@@ -37,7 +37,6 @@ import { ViewContainer, IViewDescriptorService, IViewContainerModel, ViewContain
|
||||
import { MenuId } from 'vs/platform/actions/common/actions';
|
||||
import { ViewMenuActions, ViewContainerMenuActions } from 'vs/workbench/browser/parts/views/viewMenuActions';
|
||||
import { IPaneComposite } from 'vs/workbench/common/panecomposite';
|
||||
import { IStorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys';
|
||||
import { Before2D, CompositeDragAndDropObserver, ICompositeDragAndDrop, toggleDropEffect } from 'vs/workbench/browser/dnd';
|
||||
import { IActivity } from 'vs/workbench/common/activity';
|
||||
|
||||
@@ -118,7 +117,6 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||
@IViewDescriptorService private readonly viewDescriptorService: IViewDescriptorService,
|
||||
@IContextKeyService private readonly contextKeyService: IContextKeyService,
|
||||
@IExtensionService private readonly extensionService: IExtensionService,
|
||||
@IStorageKeysSyncRegistryService storageKeysSyncRegistryService: IStorageKeysSyncRegistryService
|
||||
) {
|
||||
super(
|
||||
notificationService,
|
||||
@@ -140,7 +138,6 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||
);
|
||||
|
||||
this.panelRegistry = Registry.as<PanelRegistry>(PanelExtensions.Panels);
|
||||
storageKeysSyncRegistryService.registerStorageKey({ key: PanelPart.PINNED_PANELS, version: 1 });
|
||||
|
||||
this.dndHandler = new CompositeDragAndDrop(this.viewDescriptorService, ViewContainerLocation.Panel,
|
||||
(id: string, focus?: boolean) => (this.openPanel(id, focus) as Promise<IPaneComposite | undefined>).then(panel => panel || null),
|
||||
@@ -338,7 +335,7 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||
disposables.clear();
|
||||
this.onDidRegisterExtensions();
|
||||
this.compositeBar.onDidChange(() => this.saveCachedPanels(), this, disposables);
|
||||
this.storageService.onDidChangeStorage(e => this.onDidStorageChange(e), this, disposables);
|
||||
this.storageService.onDidChangeValue(e => this.onDidStorageValueChange(e), this, disposables);
|
||||
}));
|
||||
|
||||
}
|
||||
@@ -670,7 +667,7 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||
return this.toolBar.getItemsWidth();
|
||||
}
|
||||
|
||||
private onDidStorageChange(e: IStorageChangeEvent): void {
|
||||
private onDidStorageValueChange(e: IStorageValueChangeEvent): void {
|
||||
if (e.key === PanelPart.PINNED_PANELS && e.scope === StorageScope.GLOBAL
|
||||
&& this.cachedPanelsValue !== this.getStoredCachedPanelsValue() /* This checks if current window changed the value or not */) {
|
||||
this._cachedPanelsValue = undefined;
|
||||
@@ -760,7 +757,7 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||
}
|
||||
|
||||
private setStoredCachedViewletsValue(value: string): void {
|
||||
this.storageService.store(PanelPart.PINNED_PANELS, value, StorageScope.GLOBAL);
|
||||
this.storageService.store2(PanelPart.PINNED_PANELS, value, StorageScope.GLOBAL, StorageTarget.USER);
|
||||
}
|
||||
|
||||
private getPlaceholderViewContainers(): IPlaceholderViewContainer[] {
|
||||
|
||||
@@ -23,7 +23,7 @@ import { isThemeColor } from 'vs/editor/common/editorCommon';
|
||||
import { Color } from 'vs/base/common/color';
|
||||
import { EventHelper, createStyleSheet, addDisposableListener, EventType, hide, show, isAncestor, appendChildren } from 'vs/base/browser/dom';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import { IStorageService, StorageScope, IStorageChangeEvent } from 'vs/platform/storage/common/storage';
|
||||
import { IStorageService, StorageScope, IStorageValueChangeEvent, StorageTarget } from 'vs/platform/storage/common/storage';
|
||||
import { Parts, IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';
|
||||
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
|
||||
import { coalesce } from 'vs/base/common/arrays';
|
||||
@@ -32,7 +32,6 @@ import { ToggleStatusbarVisibilityAction } from 'vs/workbench/browser/actions/la
|
||||
import { assertIsDefined } from 'vs/base/common/types';
|
||||
import { Emitter } from 'vs/base/common/event';
|
||||
import { Command } from 'vs/editor/common/modes';
|
||||
import { IStorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys';
|
||||
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
@@ -102,10 +101,10 @@ class StatusbarViewModel extends Disposable {
|
||||
}
|
||||
|
||||
private registerListeners(): void {
|
||||
this._register(this.storageService.onDidChangeStorage(e => this.onDidStorageChange(e)));
|
||||
this._register(this.storageService.onDidChangeValue(e => this.onDidStorageValueChange(e)));
|
||||
}
|
||||
|
||||
private onDidStorageChange(event: IStorageChangeEvent): void {
|
||||
private onDidStorageValueChange(event: IStorageValueChangeEvent): void {
|
||||
if (event.key === StatusbarViewModel.HIDDEN_ENTRIES_KEY && event.scope === StorageScope.GLOBAL) {
|
||||
|
||||
// Keep current hidden entries
|
||||
@@ -275,7 +274,7 @@ class StatusbarViewModel extends Disposable {
|
||||
|
||||
private saveState(): void {
|
||||
if (this.hidden.size > 0) {
|
||||
this.storageService.store(StatusbarViewModel.HIDDEN_ENTRIES_KEY, JSON.stringify(Array.from(this.hidden.values())), StorageScope.GLOBAL);
|
||||
this.storageService.store2(StatusbarViewModel.HIDDEN_ENTRIES_KEY, JSON.stringify(Array.from(this.hidden.values())), StorageScope.GLOBAL, StorageTarget.USER);
|
||||
} else {
|
||||
this.storageService.remove(StatusbarViewModel.HIDDEN_ENTRIES_KEY, StorageScope.GLOBAL);
|
||||
}
|
||||
@@ -405,12 +404,9 @@ export class StatusbarPart extends Part implements IStatusbarService {
|
||||
@IWorkbenchLayoutService layoutService: IWorkbenchLayoutService,
|
||||
@IContextMenuService private contextMenuService: IContextMenuService,
|
||||
@IContextKeyService private readonly contextKeyService: IContextKeyService,
|
||||
@IStorageKeysSyncRegistryService storageKeysSyncRegistryService: IStorageKeysSyncRegistryService,
|
||||
) {
|
||||
super(Parts.STATUSBAR_PART, { hasTitle: false }, themeService, storageService, layoutService);
|
||||
|
||||
storageKeysSyncRegistryService.registerStorageKey({ key: StatusbarViewModel.HIDDEN_ENTRIES_KEY, version: 1 });
|
||||
|
||||
this.registerListeners();
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ import { registerEditorContribution } from 'vs/editor/browser/editorExtensions';
|
||||
import { IEditorContribution } from 'vs/editor/common/editorCommon';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
|
||||
import { IStorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys';
|
||||
|
||||
/**
|
||||
* Shows a message when opening a large file which has been memory optimized (and features disabled).
|
||||
@@ -24,14 +23,9 @@ export class LargeFileOptimizationsWarner extends Disposable implements IEditorC
|
||||
private readonly _editor: ICodeEditor,
|
||||
@INotificationService private readonly _notificationService: INotificationService,
|
||||
@IConfigurationService private readonly _configurationService: IConfigurationService,
|
||||
@IStorageKeysSyncRegistryService storageKeysSyncRegistryService: IStorageKeysSyncRegistryService
|
||||
) {
|
||||
super();
|
||||
|
||||
// opt-in to syncing
|
||||
const neverShowAgainId = 'editor.contrib.largeFileOptimizationsWarner';
|
||||
storageKeysSyncRegistryService.registerStorageKey({ key: neverShowAgainId, version: 1 });
|
||||
|
||||
this._register(this._editor.onDidChangeModel((e) => {
|
||||
const model = this._editor.getModel();
|
||||
if (!model) {
|
||||
@@ -61,7 +55,7 @@ export class LargeFileOptimizationsWarner extends Disposable implements IEditorC
|
||||
});
|
||||
}
|
||||
}
|
||||
], { neverShowAgain: { id: neverShowAgainId } });
|
||||
], { neverShowAgain: { id: 'editor.contrib.largeFileOptimizationsWarner' } });
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
+2
-5
@@ -16,9 +16,8 @@ import { areSameExtensions } from 'vs/platform/extensionManagement/common/extens
|
||||
import { IExtensionRecommendationNotificationService, RecommendationsNotificationResult, RecommendationSource } from 'vs/platform/extensionRecommendations/common/extensionRecommendations';
|
||||
import { IInstantiationService, optional } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { INotificationHandle, INotificationService, IPromptChoice, Severity } from 'vs/platform/notification/common/notification';
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { IStorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys';
|
||||
import { IUserDataAutoSyncEnablementService, IUserDataSyncResourceEnablementService, SyncResource } from 'vs/platform/userDataSync/common/userDataSync';
|
||||
import { SearchExtensionsAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions';
|
||||
import { IExtension, IExtensionsWorkbenchService } from 'vs/workbench/contrib/extensions/common/extensions';
|
||||
@@ -142,12 +141,10 @@ export class ExtensionRecommendationNotificationService implements IExtensionRec
|
||||
@IWorkbenchExtensioManagementService private readonly extensionManagementService: IWorkbenchExtensioManagementService,
|
||||
@IWorkbenchExtensionEnablementService private readonly extensionEnablementService: IWorkbenchExtensionEnablementService,
|
||||
@IExtensionIgnoredRecommendationsService private readonly extensionIgnoredRecommendationsService: IExtensionIgnoredRecommendationsService,
|
||||
@IStorageKeysSyncRegistryService storageKeysSyncRegistryService: IStorageKeysSyncRegistryService,
|
||||
@IUserDataAutoSyncEnablementService private readonly userDataAutoSyncEnablementService: IUserDataAutoSyncEnablementService,
|
||||
@IUserDataSyncResourceEnablementService private readonly userDataSyncResourceEnablementService: IUserDataSyncResourceEnablementService,
|
||||
@optional(ITASExperimentService) tasExperimentService: ITASExperimentService,
|
||||
) {
|
||||
storageKeysSyncRegistryService.registerStorageKey({ key: ignoreImportantExtensionRecommendationStorageKey, version: 1 });
|
||||
this.tasExperimentService = tasExperimentService;
|
||||
}
|
||||
|
||||
@@ -423,7 +420,7 @@ export class ExtensionRecommendationNotificationService implements IExtensionRec
|
||||
const importantRecommendationsIgnoreList = [...this.ignoredRecommendations];
|
||||
if (!importantRecommendationsIgnoreList.includes(id.toLowerCase())) {
|
||||
importantRecommendationsIgnoreList.push(id.toLowerCase());
|
||||
this.storageService.store(ignoreImportantExtensionRecommendationStorageKey, JSON.stringify(importantRecommendationsIgnoreList), StorageScope.GLOBAL);
|
||||
this.storageService.store2(ignoreImportantExtensionRecommendationStorageKey, JSON.stringify(importantRecommendationsIgnoreList), StorageScope.GLOBAL, StorageTarget.USER);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ import { FileEditorInput } from 'vs/workbench/contrib/files/common/editors/fileE
|
||||
import { SAVE_FILE_COMMAND_ID, REVERT_FILE_COMMAND_ID, SAVE_FILE_AS_COMMAND_ID, SAVE_FILE_AS_LABEL } from 'vs/workbench/contrib/files/browser/fileCommands';
|
||||
import { INotificationService, INotificationHandle, INotificationActions, Severity } from 'vs/platform/notification/common/notification';
|
||||
import { IOpenerService } from 'vs/platform/opener/common/opener';
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
|
||||
import { ExecuteCommandAction } from 'vs/platform/actions/common/actions';
|
||||
import { IProductService } from 'vs/platform/product/common/productService';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
@@ -32,7 +32,6 @@ import { isWindows } from 'vs/base/common/platform';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { IPreferencesService } from 'vs/workbench/services/preferences/common/preferences';
|
||||
import { SaveReason } from 'vs/workbench/common/editor';
|
||||
import { IStorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys';
|
||||
|
||||
export const CONFLICT_RESOLUTION_CONTEXT = 'saveConflictResolutionContext';
|
||||
export const CONFLICT_RESOLUTION_SCHEME = 'conflictResolution';
|
||||
@@ -56,13 +55,9 @@ export class TextFileSaveErrorHandler extends Disposable implements ISaveErrorHa
|
||||
@ITextModelService textModelService: ITextModelService,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
@IStorageService private readonly storageService: IStorageService,
|
||||
@IStorageKeysSyncRegistryService storageKeysSyncRegistryService: IStorageKeysSyncRegistryService
|
||||
) {
|
||||
super();
|
||||
|
||||
// opt-in to syncing
|
||||
storageKeysSyncRegistryService.registerStorageKey({ key: LEARN_MORE_DIRTY_WRITE_IGNORE_KEY, version: 1 });
|
||||
|
||||
const provider = this._register(instantiationService.createInstance(TextFileContentProvider));
|
||||
this._register(textModelService.registerTextModelContentProvider(CONFLICT_RESOLUTION_SCHEME, provider));
|
||||
|
||||
@@ -225,7 +220,7 @@ class DoNotShowResolveConflictLearnMoreAction extends Action {
|
||||
}
|
||||
|
||||
async run(notification: IDisposable): Promise<void> {
|
||||
this.storageService.store(LEARN_MORE_DIRTY_WRITE_IGNORE_KEY, true, StorageScope.GLOBAL);
|
||||
this.storageService.store2(LEARN_MORE_DIRTY_WRITE_IGNORE_KEY, true, StorageScope.GLOBAL, StorageTarget.USER);
|
||||
|
||||
// Hide notification
|
||||
notification.dispose();
|
||||
|
||||
@@ -19,13 +19,12 @@ import Severity from 'vs/base/common/severity';
|
||||
import { IJSONEditingService } from 'vs/workbench/services/configuration/common/jsonEditing';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { IHostService } from 'vs/workbench/services/host/browser/host';
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
|
||||
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
|
||||
import { VIEWLET_ID as EXTENSIONS_VIEWLET_ID, IExtensionsViewPaneContainer } from 'vs/workbench/contrib/extensions/common/extensions';
|
||||
import { minimumTranslatedStrings } from 'vs/workbench/contrib/localizations/browser/minimalTranslations';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { IStorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys';
|
||||
|
||||
// Register action to configure locale and related settings
|
||||
const registry = Registry.as<IWorkbenchActionRegistry>(Extensions.WorkbenchActions);
|
||||
@@ -44,12 +43,9 @@ export class LocalizationWorkbenchContribution extends Disposable implements IWo
|
||||
@IExtensionGalleryService private readonly galleryService: IExtensionGalleryService,
|
||||
@IViewletService private readonly viewletService: IViewletService,
|
||||
@ITelemetryService private readonly telemetryService: ITelemetryService,
|
||||
@IStorageKeysSyncRegistryService storageKeysSyncRegistryService: IStorageKeysSyncRegistryService
|
||||
) {
|
||||
super();
|
||||
|
||||
storageKeysSyncRegistryService.registerStorageKey({ key: LANGUAGEPACK_SUGGESTION_IGNORE_STORAGE_KEY, version: 1 });
|
||||
storageKeysSyncRegistryService.registerStorageKey({ key: 'langugage.update.donotask', version: 1 });
|
||||
this.checkAndInstall();
|
||||
this._register(this.extensionManagementService.onDidInstallExtension(e => this.onDidInstallExtension(e)));
|
||||
}
|
||||
@@ -172,10 +168,11 @@ export class LocalizationWorkbenchContribution extends Disposable implements IWo
|
||||
isSecondary: true,
|
||||
run: () => {
|
||||
languagePackSuggestionIgnoreList.push(language);
|
||||
this.storageService.store(
|
||||
this.storageService.store2(
|
||||
LANGUAGEPACK_SUGGESTION_IGNORE_STORAGE_KEY,
|
||||
JSON.stringify(languagePackSuggestionIgnoreList),
|
||||
StorageScope.GLOBAL
|
||||
StorageScope.GLOBAL,
|
||||
StorageTarget.USER
|
||||
);
|
||||
logUserReaction('neverShowAgain');
|
||||
}
|
||||
|
||||
@@ -31,12 +31,11 @@ import { IEditorModel } from 'vs/platform/editor/common/editor';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { badgeBackground, badgeForeground, contrastBorder, editorForeground } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { attachButtonStyler, attachStylerCallback } from 'vs/platform/theme/common/styler';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { IStorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys';
|
||||
import { IUserDataAutoSyncEnablementService, IUserDataSyncService, SyncStatus } from 'vs/platform/userDataSync/common/userDataSync';
|
||||
import { EditorPane } from 'vs/workbench/browser/parts/editor/editorPane';
|
||||
import { IEditorMemento, IEditorOpenContext, IEditorPane } from 'vs/workbench/common/editor';
|
||||
@@ -173,7 +172,6 @@ export class SettingsEditor2 extends EditorPane {
|
||||
@IStorageService private readonly storageService: IStorageService,
|
||||
@INotificationService private readonly notificationService: INotificationService,
|
||||
@IEditorGroupsService protected editorGroupService: IEditorGroupsService,
|
||||
@IStorageKeysSyncRegistryService storageKeysSyncRegistryService: IStorageKeysSyncRegistryService,
|
||||
@IUserDataSyncWorkbenchService private readonly userDataSyncWorkbenchService: IUserDataSyncWorkbenchService,
|
||||
@IUserDataAutoSyncEnablementService private readonly userDataAutoSyncEnablementService: IUserDataAutoSyncEnablementService
|
||||
) {
|
||||
@@ -202,8 +200,6 @@ export class SettingsEditor2 extends EditorPane {
|
||||
this.onConfigUpdate(e.affectedKeys);
|
||||
}
|
||||
}));
|
||||
|
||||
storageKeysSyncRegistryService.registerStorageKey({ key: SETTINGS_AUTOSAVE_NOTIFIED_KEY, version: 1 });
|
||||
}
|
||||
|
||||
get minimumWidth(): number { return 375; }
|
||||
@@ -737,7 +733,7 @@ export class SettingsEditor2 extends EditorPane {
|
||||
|
||||
private notifyNoSaveNeeded() {
|
||||
if (!this.storageService.getBoolean(SETTINGS_AUTOSAVE_NOTIFIED_KEY, StorageScope.GLOBAL, false)) {
|
||||
this.storageService.store(SETTINGS_AUTOSAVE_NOTIFIED_KEY, true, StorageScope.GLOBAL);
|
||||
this.storageService.store2(SETTINGS_AUTOSAVE_NOTIFIED_KEY, true, StorageScope.GLOBAL, StorageTarget.USER);
|
||||
this.notificationService.info(localize('settingsNoSaveNeeded', "Your changes are automatically saved as you edit."));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,9 +26,8 @@ import { languagesExtPoint } from 'vs/workbench/services/mode/common/workbenchMo
|
||||
import { SnippetCompletionProvider } from './snippetCompletionProvider';
|
||||
import { IExtensionResourceLoaderService } from 'vs/workbench/services/extensionResourceLoader/common/extensionResourceLoader';
|
||||
import { ResourceMap } from 'vs/base/common/map';
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
|
||||
import { isStringArray } from 'vs/base/common/types';
|
||||
import { IStorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
|
||||
namespace snippetExt {
|
||||
@@ -136,11 +135,8 @@ class SnippetEnablement {
|
||||
|
||||
constructor(
|
||||
@IStorageService private readonly _storageService: IStorageService,
|
||||
@IStorageKeysSyncRegistryService storageKeysSyncService: IStorageKeysSyncRegistryService,
|
||||
) {
|
||||
|
||||
storageKeysSyncService.registerStorageKey({ key: SnippetEnablement._key, version: 1 });
|
||||
|
||||
const raw = _storageService.get(SnippetEnablement._key, StorageScope.GLOBAL, '');
|
||||
let data: string[] | undefined;
|
||||
try {
|
||||
@@ -164,7 +160,7 @@ class SnippetEnablement {
|
||||
changed = true;
|
||||
}
|
||||
if (changed) {
|
||||
this._storageService.store(SnippetEnablement._key, JSON.stringify(Array.from(this._ignored)), StorageScope.GLOBAL);
|
||||
this._storageService.store2(SnippetEnablement._key, JSON.stringify(Array.from(this._ignored)), StorageScope.GLOBAL, StorageTarget.USER);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,8 +9,7 @@ import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
import { IWorkbenchContributionsRegistry, IWorkbenchContribution, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { IStorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys';
|
||||
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
|
||||
import { ISurveyData, IProductService } from 'vs/platform/product/common/productService';
|
||||
import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle';
|
||||
import { Severity, INotificationService } from 'vs/platform/notification/common/notification';
|
||||
@@ -26,7 +25,6 @@ class LanguageSurvey extends Disposable {
|
||||
constructor(
|
||||
data: ISurveyData,
|
||||
storageService: IStorageService,
|
||||
storageKeysSyncRegistryService: IStorageKeysSyncRegistryService,
|
||||
notificationService: INotificationService,
|
||||
telemetryService: ITelemetryService,
|
||||
modelService: IModelService,
|
||||
@@ -43,14 +41,6 @@ class LanguageSurvey extends Disposable {
|
||||
const EDITED_LANGUAGE_COUNT_KEY = `${data.surveyId}.editedCount`;
|
||||
const EDITED_LANGUAGE_DATE_KEY = `${data.surveyId}.editedDate`;
|
||||
|
||||
// opt-in to syncing
|
||||
storageKeysSyncRegistryService.registerStorageKey({ key: SESSION_COUNT_KEY, version: 1 });
|
||||
storageKeysSyncRegistryService.registerStorageKey({ key: LAST_SESSION_DATE_KEY, version: 1 });
|
||||
storageKeysSyncRegistryService.registerStorageKey({ key: SKIP_VERSION_KEY, version: 1 });
|
||||
storageKeysSyncRegistryService.registerStorageKey({ key: IS_CANDIDATE_KEY, version: 1 });
|
||||
storageKeysSyncRegistryService.registerStorageKey({ key: EDITED_LANGUAGE_COUNT_KEY, version: 1 });
|
||||
storageKeysSyncRegistryService.registerStorageKey({ key: EDITED_LANGUAGE_DATE_KEY, version: 1 });
|
||||
|
||||
const skipVersion = storageService.get(SKIP_VERSION_KEY, StorageScope.GLOBAL, '');
|
||||
if (skipVersion) {
|
||||
return;
|
||||
@@ -65,8 +55,8 @@ class LanguageSurvey extends Disposable {
|
||||
models.forEach(m => {
|
||||
if (m.getMode() === data.languageId && date !== storageService.get(EDITED_LANGUAGE_DATE_KEY, StorageScope.GLOBAL)) {
|
||||
const editedCount = storageService.getNumber(EDITED_LANGUAGE_COUNT_KEY, StorageScope.GLOBAL, 0) + 1;
|
||||
storageService.store(EDITED_LANGUAGE_COUNT_KEY, editedCount, StorageScope.GLOBAL);
|
||||
storageService.store(EDITED_LANGUAGE_DATE_KEY, date, StorageScope.GLOBAL);
|
||||
storageService.store2(EDITED_LANGUAGE_COUNT_KEY, editedCount, StorageScope.GLOBAL, StorageTarget.USER);
|
||||
storageService.store2(EDITED_LANGUAGE_DATE_KEY, date, StorageScope.GLOBAL, StorageTarget.USER);
|
||||
}
|
||||
});
|
||||
}, 250));
|
||||
@@ -80,8 +70,8 @@ class LanguageSurvey extends Disposable {
|
||||
}
|
||||
|
||||
const sessionCount = storageService.getNumber(SESSION_COUNT_KEY, StorageScope.GLOBAL, 0) + 1;
|
||||
storageService.store(LAST_SESSION_DATE_KEY, date, StorageScope.GLOBAL);
|
||||
storageService.store(SESSION_COUNT_KEY, sessionCount, StorageScope.GLOBAL);
|
||||
storageService.store2(LAST_SESSION_DATE_KEY, date, StorageScope.GLOBAL, StorageTarget.USER);
|
||||
storageService.store2(SESSION_COUNT_KEY, sessionCount, StorageScope.GLOBAL, StorageTarget.USER);
|
||||
|
||||
if (sessionCount < 9) {
|
||||
return;
|
||||
@@ -94,10 +84,10 @@ class LanguageSurvey extends Disposable {
|
||||
const isCandidate = storageService.getBoolean(IS_CANDIDATE_KEY, StorageScope.GLOBAL, false)
|
||||
|| Math.random() < data.userProbability;
|
||||
|
||||
storageService.store(IS_CANDIDATE_KEY, isCandidate, StorageScope.GLOBAL);
|
||||
storageService.store2(IS_CANDIDATE_KEY, isCandidate, StorageScope.GLOBAL, StorageTarget.USER);
|
||||
|
||||
if (!isCandidate) {
|
||||
storageService.store(SKIP_VERSION_KEY, productService.version, StorageScope.GLOBAL);
|
||||
storageService.store2(SKIP_VERSION_KEY, productService.version, StorageScope.GLOBAL, StorageTarget.USER);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -113,23 +103,23 @@ class LanguageSurvey extends Disposable {
|
||||
telemetryService.publicLog(`${data.surveyId}.survey/takeShortSurvey`);
|
||||
telemetryService.getTelemetryInfo().then(info => {
|
||||
openerService.open(URI.parse(`${data.surveyUrl}?o=${encodeURIComponent(platform)}&v=${encodeURIComponent(productService.version)}&m=${encodeURIComponent(info.machineId)}`));
|
||||
storageService.store(IS_CANDIDATE_KEY, false, StorageScope.GLOBAL);
|
||||
storageService.store(SKIP_VERSION_KEY, productService.version, StorageScope.GLOBAL);
|
||||
storageService.store2(IS_CANDIDATE_KEY, false, StorageScope.GLOBAL, StorageTarget.USER);
|
||||
storageService.store2(SKIP_VERSION_KEY, productService.version, StorageScope.GLOBAL, StorageTarget.USER);
|
||||
});
|
||||
}
|
||||
}, {
|
||||
label: nls.localize('remindLater', "Remind Me later"),
|
||||
run: () => {
|
||||
telemetryService.publicLog(`${data.surveyId}.survey/remindMeLater`);
|
||||
storageService.store(SESSION_COUNT_KEY, sessionCount - 3, StorageScope.GLOBAL);
|
||||
storageService.store2(SESSION_COUNT_KEY, sessionCount - 3, StorageScope.GLOBAL, StorageTarget.USER);
|
||||
}
|
||||
}, {
|
||||
label: nls.localize('neverAgain', "Don't Show Again"),
|
||||
isSecondary: true,
|
||||
run: () => {
|
||||
telemetryService.publicLog(`${data.surveyId}.survey/dontShowAgain`);
|
||||
storageService.store(IS_CANDIDATE_KEY, false, StorageScope.GLOBAL);
|
||||
storageService.store(SKIP_VERSION_KEY, productService.version, StorageScope.GLOBAL);
|
||||
storageService.store2(IS_CANDIDATE_KEY, false, StorageScope.GLOBAL, StorageTarget.USER);
|
||||
storageService.store2(SKIP_VERSION_KEY, productService.version, StorageScope.GLOBAL, StorageTarget.USER);
|
||||
}
|
||||
}],
|
||||
{ sticky: true }
|
||||
@@ -141,7 +131,6 @@ class LanguageSurveysContribution implements IWorkbenchContribution {
|
||||
|
||||
constructor(
|
||||
@IStorageService storageService: IStorageService,
|
||||
@IStorageKeysSyncRegistryService storageKeysSyncRegistryService: IStorageKeysSyncRegistryService,
|
||||
@INotificationService notificationService: INotificationService,
|
||||
@ITelemetryService telemetryService: ITelemetryService,
|
||||
@IModelService modelService: IModelService,
|
||||
@@ -155,7 +144,7 @@ class LanguageSurveysContribution implements IWorkbenchContribution {
|
||||
|
||||
productService.surveys
|
||||
.filter(surveyData => surveyData.surveyId && surveyData.editCount && surveyData.languageId && surveyData.surveyUrl && surveyData.userProbability)
|
||||
.map(surveyData => new LanguageSurvey(surveyData, storageService, storageKeysSyncRegistryService, notificationService, telemetryService, modelService, textFileService, openerService, productService));
|
||||
.map(surveyData => new LanguageSurvey(surveyData, storageService, notificationService, telemetryService, modelService, textFileService, openerService, productService));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,8 +8,7 @@ import { language } from 'vs/base/common/platform';
|
||||
import { IWorkbenchContributionsRegistry, IWorkbenchContribution, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { IStorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys';
|
||||
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
|
||||
import { IProductService } from 'vs/platform/product/common/productService';
|
||||
import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle';
|
||||
import { Severity, INotificationService } from 'vs/platform/notification/common/notification';
|
||||
@@ -27,7 +26,6 @@ class NPSContribution implements IWorkbenchContribution {
|
||||
|
||||
constructor(
|
||||
@IStorageService storageService: IStorageService,
|
||||
@IStorageKeysSyncRegistryService storageKeysSyncRegistryService: IStorageKeysSyncRegistryService,
|
||||
@INotificationService notificationService: INotificationService,
|
||||
@ITelemetryService telemetryService: ITelemetryService,
|
||||
@IOpenerService openerService: IOpenerService,
|
||||
@@ -37,12 +35,6 @@ class NPSContribution implements IWorkbenchContribution {
|
||||
return;
|
||||
}
|
||||
|
||||
// opt-in to syncing
|
||||
storageKeysSyncRegistryService.registerStorageKey({ key: SESSION_COUNT_KEY, version: 1 });
|
||||
storageKeysSyncRegistryService.registerStorageKey({ key: LAST_SESSION_DATE_KEY, version: 1 });
|
||||
storageKeysSyncRegistryService.registerStorageKey({ key: SKIP_VERSION_KEY, version: 1 });
|
||||
storageKeysSyncRegistryService.registerStorageKey({ key: IS_CANDIDATE_KEY, version: 1 });
|
||||
|
||||
const skipVersion = storageService.get(SKIP_VERSION_KEY, StorageScope.GLOBAL, '');
|
||||
if (skipVersion) {
|
||||
return;
|
||||
@@ -56,8 +48,8 @@ class NPSContribution implements IWorkbenchContribution {
|
||||
}
|
||||
|
||||
const sessionCount = (storageService.getNumber(SESSION_COUNT_KEY, StorageScope.GLOBAL, 0) || 0) + 1;
|
||||
storageService.store(LAST_SESSION_DATE_KEY, date, StorageScope.GLOBAL);
|
||||
storageService.store(SESSION_COUNT_KEY, sessionCount, StorageScope.GLOBAL);
|
||||
storageService.store2(LAST_SESSION_DATE_KEY, date, StorageScope.GLOBAL, StorageTarget.USER);
|
||||
storageService.store2(SESSION_COUNT_KEY, sessionCount, StorageScope.GLOBAL, StorageTarget.USER);
|
||||
|
||||
if (sessionCount < 9) {
|
||||
return;
|
||||
@@ -66,10 +58,10 @@ class NPSContribution implements IWorkbenchContribution {
|
||||
const isCandidate = storageService.getBoolean(IS_CANDIDATE_KEY, StorageScope.GLOBAL, false)
|
||||
|| Math.random() < PROBABILITY;
|
||||
|
||||
storageService.store(IS_CANDIDATE_KEY, isCandidate, StorageScope.GLOBAL);
|
||||
storageService.store2(IS_CANDIDATE_KEY, isCandidate, StorageScope.GLOBAL, StorageTarget.USER);
|
||||
|
||||
if (!isCandidate) {
|
||||
storageService.store(SKIP_VERSION_KEY, productService.version, StorageScope.GLOBAL);
|
||||
storageService.store2(SKIP_VERSION_KEY, productService.version, StorageScope.GLOBAL, StorageTarget.USER);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -81,18 +73,18 @@ class NPSContribution implements IWorkbenchContribution {
|
||||
run: () => {
|
||||
telemetryService.getTelemetryInfo().then(info => {
|
||||
openerService.open(URI.parse(`${productService.npsSurveyUrl}?o=${encodeURIComponent(platform)}&v=${encodeURIComponent(productService.version)}&m=${encodeURIComponent(info.machineId)}`));
|
||||
storageService.store(IS_CANDIDATE_KEY, false, StorageScope.GLOBAL);
|
||||
storageService.store(SKIP_VERSION_KEY, productService.version, StorageScope.GLOBAL);
|
||||
storageService.store2(IS_CANDIDATE_KEY, false, StorageScope.GLOBAL, StorageTarget.USER);
|
||||
storageService.store2(SKIP_VERSION_KEY, productService.version, StorageScope.GLOBAL, StorageTarget.USER);
|
||||
});
|
||||
}
|
||||
}, {
|
||||
label: nls.localize('remindLater', "Remind Me later"),
|
||||
run: () => storageService.store(SESSION_COUNT_KEY, sessionCount - 3, StorageScope.GLOBAL)
|
||||
run: () => storageService.store2(SESSION_COUNT_KEY, sessionCount - 3, StorageScope.GLOBAL, StorageTarget.USER)
|
||||
}, {
|
||||
label: nls.localize('neverAgain', "Don't Show Again"),
|
||||
run: () => {
|
||||
storageService.store(IS_CANDIDATE_KEY, false, StorageScope.GLOBAL);
|
||||
storageService.store(SKIP_VERSION_KEY, productService.version, StorageScope.GLOBAL);
|
||||
storageService.store2(IS_CANDIDATE_KEY, false, StorageScope.GLOBAL, StorageTarget.USER);
|
||||
storageService.store2(SKIP_VERSION_KEY, productService.version, StorageScope.GLOBAL, StorageTarget.USER);
|
||||
}
|
||||
}],
|
||||
{ sticky: true }
|
||||
|
||||
@@ -20,7 +20,6 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
|
||||
import { InstallRecommendedExtensionAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions';
|
||||
import { IProductService } from 'vs/platform/product/common/productService';
|
||||
import { XTermCore } from 'vs/workbench/contrib/terminal/browser/xterm-private';
|
||||
import { IStorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys';
|
||||
|
||||
const MINIMUM_FONT_SIZE = 6;
|
||||
const MAXIMUM_FONT_SIZE = 25;
|
||||
@@ -51,7 +50,6 @@ export class TerminalConfigHelper implements IBrowserTerminalConfigHelper {
|
||||
@ITelemetryService private readonly telemetryService: ITelemetryService,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
@IProductService private readonly productService: IProductService,
|
||||
@IStorageKeysSyncRegistryService storageKeysSyncRegistryService: IStorageKeysSyncRegistryService
|
||||
) {
|
||||
this._updateConfig();
|
||||
this._configurationService.onDidChangeConfiguration(e => {
|
||||
@@ -59,9 +57,6 @@ export class TerminalConfigHelper implements IBrowserTerminalConfigHelper {
|
||||
this._updateConfig();
|
||||
}
|
||||
});
|
||||
|
||||
// opt-in to syncing
|
||||
storageKeysSyncRegistryService.registerStorageKey({ key: 'terminalConfigHelper/launchRecommendationsIgnore', version: 1 });
|
||||
}
|
||||
|
||||
public setLinuxDistro(linuxDistro: LinuxDistro) {
|
||||
|
||||
@@ -8,7 +8,6 @@ import { TerminalConfigHelper } from 'vs/workbench/contrib/terminal/browser/term
|
||||
import { EDITOR_FONT_DEFAULTS } from 'vs/editor/common/config/editorOptions';
|
||||
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
|
||||
import { LinuxDistro } from 'vs/workbench/contrib/terminal/common/terminal';
|
||||
import { StorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys';
|
||||
|
||||
suite('Workbench - TerminalConfigHelper', () => {
|
||||
let fixture: HTMLElement;
|
||||
@@ -30,7 +29,7 @@ suite('Workbench - TerminalConfigHelper', () => {
|
||||
const configurationService = new TestConfigurationService();
|
||||
configurationService.setUserConfiguration('editor', { fontFamily: 'foo' });
|
||||
configurationService.setUserConfiguration('terminal', { integrated: { fontFamily: null } });
|
||||
const configHelper = new TerminalConfigHelper(configurationService, null!, null!, null!, null!, null!, null!, new StorageKeysSyncRegistryService());
|
||||
const configHelper = new TerminalConfigHelper(configurationService, null!, null!, null!, null!, null!, null!);
|
||||
configHelper.setLinuxDistro(LinuxDistro.Fedora);
|
||||
configHelper.panelContainer = fixture;
|
||||
assert.equal(configHelper.getFont().fontFamily, '\'DejaVu Sans Mono\', monospace', 'Fedora should have its font overridden when terminal.integrated.fontFamily not set');
|
||||
@@ -40,7 +39,7 @@ suite('Workbench - TerminalConfigHelper', () => {
|
||||
const configurationService = new TestConfigurationService();
|
||||
configurationService.setUserConfiguration('editor', { fontFamily: 'foo' });
|
||||
configurationService.setUserConfiguration('terminal', { integrated: { fontFamily: null } });
|
||||
const configHelper = new TerminalConfigHelper(configurationService, null!, null!, null!, null!, null!, null!, new StorageKeysSyncRegistryService());
|
||||
const configHelper = new TerminalConfigHelper(configurationService, null!, null!, null!, null!, null!, null!);
|
||||
configHelper.setLinuxDistro(LinuxDistro.Ubuntu);
|
||||
configHelper.panelContainer = fixture;
|
||||
assert.equal(configHelper.getFont().fontFamily, '\'Ubuntu Mono\', monospace', 'Ubuntu should have its font overridden when terminal.integrated.fontFamily not set');
|
||||
@@ -50,7 +49,7 @@ suite('Workbench - TerminalConfigHelper', () => {
|
||||
const configurationService = new TestConfigurationService();
|
||||
configurationService.setUserConfiguration('editor', { fontFamily: 'foo' });
|
||||
configurationService.setUserConfiguration('terminal', { integrated: { fontFamily: null } });
|
||||
const configHelper = new TerminalConfigHelper(configurationService, null!, null!, null!, null!, null!, null!, new StorageKeysSyncRegistryService());
|
||||
const configHelper = new TerminalConfigHelper(configurationService, null!, null!, null!, null!, null!, null!);
|
||||
configHelper.panelContainer = fixture;
|
||||
assert.equal(configHelper.getFont().fontFamily, 'foo', 'editor.fontFamily should be the fallback when terminal.integrated.fontFamily not set');
|
||||
});
|
||||
@@ -68,7 +67,7 @@ suite('Workbench - TerminalConfigHelper', () => {
|
||||
fontSize: 10
|
||||
}
|
||||
});
|
||||
let configHelper = new TerminalConfigHelper(configurationService, null!, null!, null!, null!, null!, null!, new StorageKeysSyncRegistryService());
|
||||
let configHelper = new TerminalConfigHelper(configurationService, null!, null!, null!, null!, null!, null!);
|
||||
configHelper.panelContainer = fixture;
|
||||
assert.equal(configHelper.getFont().fontSize, 10, 'terminal.integrated.fontSize should be selected over editor.fontSize');
|
||||
|
||||
@@ -81,12 +80,12 @@ suite('Workbench - TerminalConfigHelper', () => {
|
||||
fontSize: 0
|
||||
}
|
||||
});
|
||||
configHelper = new TerminalConfigHelper(configurationService, null!, null!, null!, null!, null!, null!, new StorageKeysSyncRegistryService());
|
||||
configHelper = new TerminalConfigHelper(configurationService, null!, null!, null!, null!, null!, null!);
|
||||
configHelper.setLinuxDistro(LinuxDistro.Ubuntu);
|
||||
configHelper.panelContainer = fixture;
|
||||
assert.equal(configHelper.getFont().fontSize, 8, 'The minimum terminal font size (with adjustment) should be used when terminal.integrated.fontSize less than it');
|
||||
|
||||
configHelper = new TerminalConfigHelper(configurationService, null!, null!, null!, null!, null!, null!, new StorageKeysSyncRegistryService());
|
||||
configHelper = new TerminalConfigHelper(configurationService, null!, null!, null!, null!, null!, null!);
|
||||
configHelper.panelContainer = fixture;
|
||||
assert.equal(configHelper.getFont().fontSize, 6, 'The minimum terminal font size should be used when terminal.integrated.fontSize less than it');
|
||||
|
||||
@@ -99,7 +98,7 @@ suite('Workbench - TerminalConfigHelper', () => {
|
||||
fontSize: 1500
|
||||
}
|
||||
});
|
||||
configHelper = new TerminalConfigHelper(configurationService, null!, null!, null!, null!, null!, null!, new StorageKeysSyncRegistryService());
|
||||
configHelper = new TerminalConfigHelper(configurationService, null!, null!, null!, null!, null!, null!);
|
||||
configHelper.panelContainer = fixture;
|
||||
assert.equal(configHelper.getFont().fontSize, 25, 'The maximum terminal font size should be used when terminal.integrated.fontSize more than it');
|
||||
|
||||
@@ -112,12 +111,12 @@ suite('Workbench - TerminalConfigHelper', () => {
|
||||
fontSize: null
|
||||
}
|
||||
});
|
||||
configHelper = new TerminalConfigHelper(configurationService, null!, null!, null!, null!, null!, null!, new StorageKeysSyncRegistryService());
|
||||
configHelper = new TerminalConfigHelper(configurationService, null!, null!, null!, null!, null!, null!);
|
||||
configHelper.setLinuxDistro(LinuxDistro.Ubuntu);
|
||||
configHelper.panelContainer = fixture;
|
||||
assert.equal(configHelper.getFont().fontSize, EDITOR_FONT_DEFAULTS.fontSize + 2, 'The default editor font size (with adjustment) should be used when terminal.integrated.fontSize is not set');
|
||||
|
||||
configHelper = new TerminalConfigHelper(configurationService, null!, null!, null!, null!, null!, null!, new StorageKeysSyncRegistryService());
|
||||
configHelper = new TerminalConfigHelper(configurationService, null!, null!, null!, null!, null!, null!);
|
||||
configHelper.panelContainer = fixture;
|
||||
assert.equal(configHelper.getFont().fontSize, EDITOR_FONT_DEFAULTS.fontSize, 'The default editor font size should be used when terminal.integrated.fontSize is not set');
|
||||
});
|
||||
@@ -135,7 +134,7 @@ suite('Workbench - TerminalConfigHelper', () => {
|
||||
lineHeight: 2
|
||||
}
|
||||
});
|
||||
let configHelper = new TerminalConfigHelper(configurationService, null!, null!, null!, null!, null!, null!, new StorageKeysSyncRegistryService());
|
||||
let configHelper = new TerminalConfigHelper(configurationService, null!, null!, null!, null!, null!, null!);
|
||||
configHelper.panelContainer = fixture;
|
||||
assert.equal(configHelper.getFont().lineHeight, 2, 'terminal.integrated.lineHeight should be selected over editor.lineHeight');
|
||||
|
||||
@@ -149,7 +148,7 @@ suite('Workbench - TerminalConfigHelper', () => {
|
||||
lineHeight: 0
|
||||
}
|
||||
});
|
||||
configHelper = new TerminalConfigHelper(configurationService, null!, null!, null!, null!, null!, null!, new StorageKeysSyncRegistryService());
|
||||
configHelper = new TerminalConfigHelper(configurationService, null!, null!, null!, null!, null!, null!);
|
||||
configHelper.panelContainer = fixture;
|
||||
assert.equal(configHelper.getFont().lineHeight, 1, 'editor.lineHeight should be 1 when terminal.integrated.lineHeight not set');
|
||||
});
|
||||
@@ -162,7 +161,7 @@ suite('Workbench - TerminalConfigHelper', () => {
|
||||
}
|
||||
});
|
||||
|
||||
let configHelper = new TerminalConfigHelper(configurationService, null!, null!, null!, null!, null!, null!, new StorageKeysSyncRegistryService());
|
||||
let configHelper = new TerminalConfigHelper(configurationService, null!, null!, null!, null!, null!, null!);
|
||||
configHelper.panelContainer = fixture;
|
||||
assert.equal(configHelper.configFontIsMonospace(), true, 'monospace is monospaced');
|
||||
});
|
||||
@@ -174,7 +173,7 @@ suite('Workbench - TerminalConfigHelper', () => {
|
||||
fontFamily: 'sans-serif'
|
||||
}
|
||||
});
|
||||
let configHelper = new TerminalConfigHelper(configurationService, null!, null!, null!, null!, null!, null!, new StorageKeysSyncRegistryService());
|
||||
let configHelper = new TerminalConfigHelper(configurationService, null!, null!, null!, null!, null!, null!);
|
||||
configHelper.panelContainer = fixture;
|
||||
assert.equal(configHelper.configFontIsMonospace(), false, 'sans-serif is not monospaced');
|
||||
});
|
||||
@@ -186,7 +185,7 @@ suite('Workbench - TerminalConfigHelper', () => {
|
||||
fontFamily: 'serif'
|
||||
}
|
||||
});
|
||||
let configHelper = new TerminalConfigHelper(configurationService, null!, null!, null!, null!, null!, null!, new StorageKeysSyncRegistryService());
|
||||
let configHelper = new TerminalConfigHelper(configurationService, null!, null!, null!, null!, null!, null!);
|
||||
configHelper.panelContainer = fixture;
|
||||
assert.equal(configHelper.configFontIsMonospace(), false, 'serif is not monospaced');
|
||||
});
|
||||
@@ -202,7 +201,7 @@ suite('Workbench - TerminalConfigHelper', () => {
|
||||
}
|
||||
});
|
||||
|
||||
let configHelper = new TerminalConfigHelper(configurationService, null!, null!, null!, null!, null!, null!, new StorageKeysSyncRegistryService());
|
||||
let configHelper = new TerminalConfigHelper(configurationService, null!, null!, null!, null!, null!, null!);
|
||||
configHelper.panelContainer = fixture;
|
||||
assert.equal(configHelper.configFontIsMonospace(), true, 'monospace is monospaced');
|
||||
});
|
||||
@@ -218,7 +217,7 @@ suite('Workbench - TerminalConfigHelper', () => {
|
||||
}
|
||||
});
|
||||
|
||||
let configHelper = new TerminalConfigHelper(configurationService, null!, null!, null!, null!, null!, null!, new StorageKeysSyncRegistryService());
|
||||
let configHelper = new TerminalConfigHelper(configurationService, null!, null!, null!, null!, null!, null!);
|
||||
configHelper.panelContainer = fixture;
|
||||
assert.equal(configHelper.configFontIsMonospace(), false, 'sans-serif is not monospaced');
|
||||
});
|
||||
@@ -234,7 +233,7 @@ suite('Workbench - TerminalConfigHelper', () => {
|
||||
}
|
||||
});
|
||||
|
||||
let configHelper = new TerminalConfigHelper(configurationService, null!, null!, null!, null!, null!, null!, new StorageKeysSyncRegistryService());
|
||||
let configHelper = new TerminalConfigHelper(configurationService, null!, null!, null!, null!, null!, null!);
|
||||
configHelper.panelContainer = fixture;
|
||||
assert.equal(configHelper.configFontIsMonospace(), false, 'serif is not monospaced');
|
||||
});
|
||||
|
||||
@@ -28,7 +28,6 @@ import { ShowCurrentReleaseNotesActionId, CheckForVSCodeUpdateActionId } from 'v
|
||||
import { IHostService } from 'vs/workbench/services/host/browser/host';
|
||||
import { IProductService } from 'vs/platform/product/common/productService';
|
||||
import product from 'vs/platform/product/common/product';
|
||||
import { IStorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys';
|
||||
|
||||
export const CONTEXT_UPDATE_STATE = new RawContextKey<string>('updateState', StateType.Idle);
|
||||
|
||||
@@ -185,15 +184,11 @@ export class UpdateContribution extends Disposable implements IWorkbenchContribu
|
||||
@IContextKeyService private readonly contextKeyService: IContextKeyService,
|
||||
@IProductService private readonly productService: IProductService,
|
||||
@IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService,
|
||||
@IStorageKeysSyncRegistryService storageKeysSyncRegistryService: IStorageKeysSyncRegistryService
|
||||
) {
|
||||
super();
|
||||
this.state = updateService.state;
|
||||
this.updateStateContextKey = CONTEXT_UPDATE_STATE.bindTo(this.contextKeyService);
|
||||
|
||||
// opt-in to syncing
|
||||
storageKeysSyncRegistryService.registerStorageKey({ key: 'neverShowAgain:update/win32-fast-updates', version: 1 });
|
||||
|
||||
this._register(updateService.onStateChange(this.onUpdateStateChange, this));
|
||||
this.onUpdateStateChange(this.updateService.state);
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import { localize } from 'vs/nls';
|
||||
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IProductService } from 'vs/platform/product/common/productService';
|
||||
import { IQuickInputService, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput';
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { IAuthenticationService } from 'vs/workbench/services/authentication/browser/authenticationService';
|
||||
@@ -127,10 +127,11 @@ export async function configureOpenerTrustedDomainsHandler(
|
||||
const itemToTrust = pickedResult.toTrust;
|
||||
if (trustedDomains.indexOf(itemToTrust) === -1) {
|
||||
storageService.remove(TRUSTED_DOMAINS_CONTENT_STORAGE_KEY, StorageScope.GLOBAL);
|
||||
storageService.store(
|
||||
storageService.store2(
|
||||
TRUSTED_DOMAINS_STORAGE_KEY,
|
||||
JSON.stringify([...trustedDomains, itemToTrust]),
|
||||
StorageScope.GLOBAL
|
||||
StorageScope.GLOBAL,
|
||||
StorageTarget.USER
|
||||
);
|
||||
|
||||
return [...trustedDomains, itemToTrust];
|
||||
|
||||
@@ -8,11 +8,10 @@ import { parse } from 'vs/base/common/json';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { FileDeleteOptions, FileOverwriteOptions, FileSystemProviderCapabilities, FileType, FileWriteOptions, IFileService, IStat, IWatchOptions, IFileSystemProviderWithFileReadWriteCapability } from 'vs/platform/files/common/files';
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
|
||||
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
|
||||
import { VSBuffer } from 'vs/base/common/buffer';
|
||||
import { readTrustedDomains, TRUSTED_DOMAINS_CONTENT_STORAGE_KEY, TRUSTED_DOMAINS_STORAGE_KEY } from 'vs/workbench/contrib/url/browser/trustedDomains';
|
||||
import { IStorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys';
|
||||
import { assertIsDefined } from 'vs/base/common/types';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
|
||||
@@ -97,12 +96,8 @@ export class TrustedDomainsFileSystemProvider implements IFileSystemProviderWith
|
||||
@IFileService private readonly fileService: IFileService,
|
||||
@IStorageService private readonly storageService: IStorageService,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
@IStorageKeysSyncRegistryService private readonly storageKeysSyncRegistryService: IStorageKeysSyncRegistryService,
|
||||
) {
|
||||
this.fileService.registerProvider(TRUSTED_DOMAINS_SCHEMA, this);
|
||||
|
||||
this.storageKeysSyncRegistryService.registerStorageKey({ key: TRUSTED_DOMAINS_STORAGE_KEY, version: 1 });
|
||||
this.storageKeysSyncRegistryService.registerStorageKey({ key: TRUSTED_DOMAINS_CONTENT_STORAGE_KEY, version: 1 });
|
||||
}
|
||||
|
||||
stat(resource: URI): Promise<IStat> {
|
||||
@@ -134,11 +129,12 @@ export class TrustedDomainsFileSystemProvider implements IFileSystemProviderWith
|
||||
const trustedDomainsContent = VSBuffer.wrap(content).toString();
|
||||
const trustedDomains = parse(trustedDomainsContent);
|
||||
|
||||
this.storageService.store(TRUSTED_DOMAINS_CONTENT_STORAGE_KEY, trustedDomainsContent, StorageScope.GLOBAL);
|
||||
this.storageService.store(
|
||||
this.storageService.store2(TRUSTED_DOMAINS_CONTENT_STORAGE_KEY, trustedDomainsContent, StorageScope.GLOBAL, StorageTarget.USER);
|
||||
this.storageService.store2(
|
||||
TRUSTED_DOMAINS_STORAGE_KEY,
|
||||
JSON.stringify(trustedDomains) || '',
|
||||
StorageScope.GLOBAL
|
||||
StorageScope.GLOBAL,
|
||||
StorageTarget.USER
|
||||
);
|
||||
} catch (err) { }
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { IOpenerService } from 'vs/platform/opener/common/opener';
|
||||
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
|
||||
@@ -19,7 +19,6 @@ import { IProductService } from 'vs/platform/product/common/productService';
|
||||
import { IHostService } from 'vs/workbench/services/host/browser/host';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { IJSONEditingService } from 'vs/workbench/services/configuration/common/jsonEditing';
|
||||
import { IStorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys';
|
||||
|
||||
export abstract class AbstractTelemetryOptOut implements IWorkbenchContribution {
|
||||
|
||||
@@ -28,7 +27,6 @@ export abstract class AbstractTelemetryOptOut implements IWorkbenchContribution
|
||||
|
||||
constructor(
|
||||
@IStorageService private readonly storageService: IStorageService,
|
||||
@IStorageKeysSyncRegistryService storageKeysSyncRegistryService: IStorageKeysSyncRegistryService,
|
||||
@IOpenerService private readonly openerService: IOpenerService,
|
||||
@INotificationService private readonly notificationService: INotificationService,
|
||||
@IHostService private readonly hostService: IHostService,
|
||||
@@ -40,7 +38,6 @@ export abstract class AbstractTelemetryOptOut implements IWorkbenchContribution
|
||||
@IEnvironmentService private readonly environmentService: IEnvironmentService,
|
||||
@IJSONEditingService private readonly jsonEditingService: IJSONEditingService
|
||||
) {
|
||||
storageKeysSyncRegistryService.registerStorageKey({ key: AbstractTelemetryOptOut.TELEMETRY_OPT_OUT_SHOWN, version: 1 });
|
||||
}
|
||||
|
||||
protected async handleTelemetryOptOut(): Promise<void> {
|
||||
@@ -53,7 +50,7 @@ export abstract class AbstractTelemetryOptOut implements IWorkbenchContribution
|
||||
return; // return early if meanwhile another window opened (we only show the opt-out once)
|
||||
}
|
||||
|
||||
this.storageService.store(AbstractTelemetryOptOut.TELEMETRY_OPT_OUT_SHOWN, true, StorageScope.GLOBAL);
|
||||
this.storageService.store2(AbstractTelemetryOptOut.TELEMETRY_OPT_OUT_SHOWN, true, StorageScope.GLOBAL, StorageTarget.USER);
|
||||
|
||||
this.privacyUrl = this.productService.privacyStatementUrl || this.productService.telemetryOptOutUrl;
|
||||
|
||||
@@ -165,7 +162,6 @@ export class BrowserTelemetryOptOut extends AbstractTelemetryOptOut {
|
||||
|
||||
constructor(
|
||||
@IStorageService storageService: IStorageService,
|
||||
@IStorageKeysSyncRegistryService storageKeysSyncRegistryService: IStorageKeysSyncRegistryService,
|
||||
@IOpenerService openerService: IOpenerService,
|
||||
@INotificationService notificationService: INotificationService,
|
||||
@IHostService hostService: IHostService,
|
||||
@@ -177,7 +173,7 @@ export class BrowserTelemetryOptOut extends AbstractTelemetryOptOut {
|
||||
@IEnvironmentService environmentService: IEnvironmentService,
|
||||
@IJSONEditingService jsonEditingService: IJSONEditingService
|
||||
) {
|
||||
super(storageService, storageKeysSyncRegistryService, openerService, notificationService, hostService, telemetryService, experimentService, configurationService, galleryService, productService, environmentService, jsonEditingService);
|
||||
super(storageService, openerService, notificationService, hostService, telemetryService, experimentService, configurationService, galleryService, productService, environmentService, jsonEditingService);
|
||||
|
||||
this.handleTelemetryOptOut();
|
||||
}
|
||||
|
||||
+1
-3
@@ -16,13 +16,11 @@ import { AbstractTelemetryOptOut } from 'vs/workbench/contrib/welcome/telemetryO
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { IJSONEditingService } from 'vs/workbench/services/configuration/common/jsonEditing';
|
||||
import { INativeHostService } from 'vs/platform/native/electron-sandbox/native';
|
||||
import { IStorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys';
|
||||
|
||||
export class NativeTelemetryOptOut extends AbstractTelemetryOptOut {
|
||||
|
||||
constructor(
|
||||
@IStorageService storageService: IStorageService,
|
||||
@IStorageKeysSyncRegistryService storageKeysSyncRegistryService: IStorageKeysSyncRegistryService,
|
||||
@IOpenerService openerService: IOpenerService,
|
||||
@INotificationService notificationService: INotificationService,
|
||||
@IHostService hostService: IHostService,
|
||||
@@ -35,7 +33,7 @@ export class NativeTelemetryOptOut extends AbstractTelemetryOptOut {
|
||||
@IJSONEditingService jsonEditingService: IJSONEditingService,
|
||||
@INativeHostService private readonly nativeHostService: INativeHostService
|
||||
) {
|
||||
super(storageService, storageKeysSyncRegistryService, openerService, notificationService, hostService, telemetryService, experimentService, configurationService, galleryService, productService, environmentService, jsonEditingService);
|
||||
super(storageService, openerService, notificationService, hostService, telemetryService, experimentService, configurationService, galleryService, productService, environmentService, jsonEditingService);
|
||||
|
||||
this.handleTelemetryOptOut();
|
||||
}
|
||||
|
||||
@@ -677,10 +677,6 @@ class SimpleStorageKeysSyncRegistryService implements IStorageKeysSyncRegistrySe
|
||||
|
||||
declare readonly _serviceBrand: undefined;
|
||||
|
||||
onDidChangeStorageKeys = Event.None;
|
||||
|
||||
storageKeys = [];
|
||||
|
||||
registerStorageKey(): void { }
|
||||
|
||||
onDidChangeExtensionStorageKeys = Event.None;
|
||||
|
||||
@@ -298,7 +298,7 @@ suite('EditorsObserver', function () {
|
||||
assert.equal(observer.hasEditor(input2.resource), true);
|
||||
assert.equal(observer.hasEditor(input3.resource), true);
|
||||
|
||||
storage._onWillSaveState.fire({ reason: WillSaveStateReason.SHUTDOWN });
|
||||
storage.emitWillSaveState(WillSaveStateReason.SHUTDOWN);
|
||||
|
||||
const restoredObserver = new EditorsObserver(part, storage);
|
||||
await part.whenRestored;
|
||||
@@ -350,7 +350,7 @@ suite('EditorsObserver', function () {
|
||||
assert.equal(observer.hasEditor(input2.resource), true);
|
||||
assert.equal(observer.hasEditor(input3.resource), true);
|
||||
|
||||
storage._onWillSaveState.fire({ reason: WillSaveStateReason.SHUTDOWN });
|
||||
storage.emitWillSaveState(WillSaveStateReason.SHUTDOWN);
|
||||
|
||||
const restoredObserver = new EditorsObserver(part, storage);
|
||||
await part.whenRestored;
|
||||
@@ -390,7 +390,7 @@ suite('EditorsObserver', function () {
|
||||
assert.equal(currentEditorsMRU[0].editor, input1);
|
||||
assert.equal(observer.hasEditor(input1.resource), true);
|
||||
|
||||
storage._onWillSaveState.fire({ reason: WillSaveStateReason.SHUTDOWN });
|
||||
storage.emitWillSaveState(WillSaveStateReason.SHUTDOWN);
|
||||
|
||||
const restoredObserver = new EditorsObserver(part, storage);
|
||||
await part.whenRestored;
|
||||
|
||||
+4
-7
@@ -7,8 +7,7 @@ import { distinct } from 'vs/base/common/arrays';
|
||||
import { Emitter } from 'vs/base/common/event';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
|
||||
import { IStorageService, IStorageChangeEvent, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { IStorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys';
|
||||
import { IStorageService, IStorageValueChangeEvent, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
|
||||
import { IExtensionIgnoredRecommendationsService, IgnoredRecommendationChangeNotification } from 'vs/workbench/services/extensionRecommendations/common/extensionRecommendations';
|
||||
import { IWorkpsaceExtensionsConfigService } from 'vs/workbench/services/extensionRecommendations/common/workspaceExtensionsConfig';
|
||||
|
||||
@@ -35,12 +34,10 @@ export class ExtensionIgnoredRecommendationsService extends Disposable implement
|
||||
constructor(
|
||||
@IWorkpsaceExtensionsConfigService private readonly workpsaceExtensionsConfigService: IWorkpsaceExtensionsConfigService,
|
||||
@IStorageService private readonly storageService: IStorageService,
|
||||
@IStorageKeysSyncRegistryService storageKeysSyncRegistryService: IStorageKeysSyncRegistryService,
|
||||
) {
|
||||
super();
|
||||
storageKeysSyncRegistryService.registerStorageKey({ key: ignoredRecommendationsStorageKey, version: 1 });
|
||||
this._globalIgnoredRecommendations = this.getCachedIgnoredRecommendations();
|
||||
this._register(this.storageService.onDidChangeStorage(e => this.onDidStorageChange(e)));
|
||||
this._register(this.storageService.onDidChangeValue(e => this.onDidStorageChange(e)));
|
||||
|
||||
this.initIgnoredWorkspaceRecommendations();
|
||||
}
|
||||
@@ -72,7 +69,7 @@ export class ExtensionIgnoredRecommendationsService extends Disposable implement
|
||||
return ignoredRecommendations.map(e => e.toLowerCase());
|
||||
}
|
||||
|
||||
private onDidStorageChange(e: IStorageChangeEvent): void {
|
||||
private onDidStorageChange(e: IStorageValueChangeEvent): void {
|
||||
if (e.key === ignoredRecommendationsStorageKey && e.scope === StorageScope.GLOBAL
|
||||
&& this.ignoredRecommendationsValue !== this.getStoredIgnoredRecommendationsValue() /* This checks if current window changed the value or not */) {
|
||||
this._ignoredRecommendationsValue = undefined;
|
||||
@@ -106,7 +103,7 @@ export class ExtensionIgnoredRecommendationsService extends Disposable implement
|
||||
}
|
||||
|
||||
private setStoredIgnoredRecommendationsValue(value: string): void {
|
||||
this.storageService.store(ignoredRecommendationsStorageKey, value, StorageScope.GLOBAL);
|
||||
this.storageService.store2(ignoredRecommendationsStorageKey, value, StorageScope.GLOBAL, StorageTarget.USER);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import { Disposable, DisposableStore, IDisposable } from 'vs/base/common/lifecyc
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
|
||||
import { IAction, Action } from 'vs/base/common/actions';
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
|
||||
|
||||
export class NotificationService extends Disposable implements INotificationService {
|
||||
|
||||
@@ -83,7 +83,7 @@ export class NotificationService extends Disposable implements INotificationServ
|
||||
handle.close();
|
||||
|
||||
// Remember choice
|
||||
this.storageService.store(id, true, scope);
|
||||
this.storageService.store2(id, true, scope, StorageTarget.USER);
|
||||
|
||||
return Promise.resolve();
|
||||
}));
|
||||
@@ -127,7 +127,7 @@ export class NotificationService extends Disposable implements INotificationServ
|
||||
|
||||
const neverShowAgainChoice = {
|
||||
label: nls.localize('neverShowAgain', "Don't Show Again"),
|
||||
run: () => this.storageService.store(id, true, scope),
|
||||
run: () => this.storageService.store2(id, true, scope, StorageTarget.USER),
|
||||
isSecondary: options.neverShowAgain.isSecondary
|
||||
};
|
||||
|
||||
|
||||
@@ -38,7 +38,6 @@ import { ColorScheme } from 'vs/platform/theme/common/theme';
|
||||
import { IHostColorSchemeService } from 'vs/workbench/services/themes/common/hostColorSchemeService';
|
||||
import { CodiconStyles } from 'vs/base/browser/ui/codicons/codiconStyles';
|
||||
import { RunOnceScheduler } from 'vs/base/common/async';
|
||||
import { IStorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys';
|
||||
|
||||
// implementation
|
||||
|
||||
@@ -109,11 +108,7 @@ export class WorkbenchThemeService implements IWorkbenchThemeService {
|
||||
@IWorkbenchLayoutService readonly layoutService: IWorkbenchLayoutService,
|
||||
@ILogService private readonly logService: ILogService,
|
||||
@IHostColorSchemeService private readonly hostColorService: IHostColorSchemeService,
|
||||
@IStorageKeysSyncRegistryService storageKeysSyncRegistryService: IStorageKeysSyncRegistryService
|
||||
) {
|
||||
// roam persisted color theme colors. Don't enable for icons as they contain references to fonts and images.
|
||||
storageKeysSyncRegistryService.registerStorageKey({ key: ColorThemeData.STORAGE_KEY, version: 1 });
|
||||
|
||||
this.container = layoutService.container;
|
||||
this.settings = new ThemeConfiguration(configurationService);
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ import { TokenStyle, SemanticTokenRule, ProbeScope, getTokenClassificationRegist
|
||||
import { MatcherWithPriority, Matcher, createMatchers } from 'vs/workbench/services/themes/common/textMateScopeMatcher';
|
||||
import { IExtensionResourceLoaderService } from 'vs/workbench/services/extensionResourceLoader/common/extensionResourceLoader';
|
||||
import { CharCode } from 'vs/base/common/charCode';
|
||||
import { StorageScope, IStorageService } from 'vs/platform/storage/common/storage';
|
||||
import { StorageScope, IStorageService, StorageTarget } from 'vs/platform/storage/common/storage';
|
||||
import { ThemeConfiguration } from 'vs/workbench/services/themes/common/themeConfiguration';
|
||||
import { ColorScheme } from 'vs/platform/theme/common/theme';
|
||||
|
||||
@@ -523,7 +523,8 @@ export class ColorThemeData implements IWorkbenchColorTheme {
|
||||
watch: this.watch
|
||||
});
|
||||
|
||||
storageService.store(ColorThemeData.STORAGE_KEY, value, StorageScope.GLOBAL);
|
||||
// roam persisted color theme colors. Don't enable for icons as they contain references to fonts and images.
|
||||
storageService.store2(ColorThemeData.STORAGE_KEY, value, StorageScope.GLOBAL, StorageTarget.USER);
|
||||
}
|
||||
|
||||
get baseTheme(): string {
|
||||
|
||||
@@ -14,7 +14,7 @@ import { flatten, equals } from 'vs/base/common/arrays';
|
||||
import { getCurrentAuthenticationSessionInfo, IAuthenticationService } from 'vs/workbench/services/authentication/browser/authenticationService';
|
||||
import { IUserDataSyncAccountService } from 'vs/platform/userDataSync/common/userDataSyncAccount';
|
||||
import { IQuickInputService, IQuickPickSeparator } from 'vs/platform/quickinput/common/quickInput';
|
||||
import { IStorageService, IStorageChangeEvent, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { IStorageService, IStorageValueChangeEvent, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { IProductService } from 'vs/platform/product/common/productService';
|
||||
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
||||
@@ -175,7 +175,7 @@ export class UserDataSyncWorkbenchService extends Disposable implements IUserDat
|
||||
(() => this.update()));
|
||||
|
||||
this._register(Event.filter(this.authenticationService.onDidChangeSessions, e => this.isSupportedAuthenticationProviderId(e.providerId))(({ event }) => this.onDidChangeSessions(event)));
|
||||
this._register(this.storageService.onDidChangeStorage(e => this.onDidChangeStorage(e)));
|
||||
this._register(this.storageService.onDidChangeValue(e => this.onDidChangeStorage(e)));
|
||||
this._register(Event.filter(this.userDataSyncAccountService.onTokenFailed, isSuccessive => isSuccessive)(() => this.onDidSuccessiveAuthFailures()));
|
||||
}
|
||||
|
||||
@@ -584,7 +584,7 @@ export class UserDataSyncWorkbenchService extends Disposable implements IUserDat
|
||||
this.update();
|
||||
}
|
||||
|
||||
private onDidChangeStorage(e: IStorageChangeEvent): void {
|
||||
private onDidChangeStorage(e: IStorageValueChangeEvent): void {
|
||||
if (e.key === UserDataSyncWorkbenchService.CACHED_SESSION_STORAGE_KEY && e.scope === StorageScope.GLOBAL
|
||||
&& this.currentSessionId !== this.getStoredCachedSessionId() /* This checks if current window changed the value or not */) {
|
||||
this._cachedCurrentSessionId = null;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import { ViewContainerLocation, IViewDescriptorService, ViewContainer, IViewsRegistry, IViewContainersRegistry, IViewDescriptor, Extensions as ViewExtensions, ViewVisibilityState } from 'vs/workbench/common/views';
|
||||
import { IContextKey, RawContextKey, IContextKeyService, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { IStorageService, StorageScope, IStorageChangeEvent } from 'vs/platform/storage/common/storage';
|
||||
import { IStorageService, StorageScope, IStorageValueChangeEvent, StorageTarget } from 'vs/platform/storage/common/storage';
|
||||
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { toDisposable, DisposableStore, Disposable, IDisposable } from 'vs/base/common/lifecycle';
|
||||
@@ -13,7 +13,6 @@ import { ViewPaneContainer } from 'vs/workbench/browser/parts/views/viewPaneCont
|
||||
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
|
||||
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { IStorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { generateUuid } from 'vs/base/common/uuid';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
@@ -98,12 +97,9 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor
|
||||
@IStorageService private readonly storageService: IStorageService,
|
||||
@IExtensionService private readonly extensionService: IExtensionService,
|
||||
@ITelemetryService private readonly telemetryService: ITelemetryService,
|
||||
@IStorageKeysSyncRegistryService storageKeysSyncRegistryService: IStorageKeysSyncRegistryService,
|
||||
) {
|
||||
super();
|
||||
|
||||
storageKeysSyncRegistryService.registerStorageKey({ key: ViewDescriptorService.CACHED_VIEW_POSITIONS, version: 1 });
|
||||
storageKeysSyncRegistryService.registerStorageKey({ key: ViewDescriptorService.CACHED_VIEW_CONTAINER_LOCATIONS, version: 1 });
|
||||
this.viewContainerModels = new Map<ViewContainer, { viewContainerModel: ViewContainerModel, disposable: IDisposable; }>();
|
||||
this.activeViewContextKeys = new Map<string, IContextKey<boolean>>();
|
||||
this.movableViewContextKeys = new Map<string, IContextKey<boolean>>();
|
||||
@@ -139,7 +135,7 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor
|
||||
this.viewContainerModels.clear();
|
||||
}));
|
||||
|
||||
this._register(this.storageService.onDidChangeStorage((e) => { this.onDidStorageChange(e); }));
|
||||
this._register(this.storageService.onDidChangeValue((e) => { this.onDidStorageChange(e); }));
|
||||
|
||||
this._register(this.extensionService.onDidRegisterExtensions(() => this.onDidRegisterExtensions()));
|
||||
}
|
||||
@@ -505,7 +501,7 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor
|
||||
return new Map<string, ViewContainerLocation>(JSON.parse(this.cachedViewContainerLocationsValue));
|
||||
}
|
||||
|
||||
private onDidStorageChange(e: IStorageChangeEvent): void {
|
||||
private onDidStorageChange(e: IStorageValueChangeEvent): void {
|
||||
if (e.key === ViewDescriptorService.CACHED_VIEW_POSITIONS && e.scope === StorageScope.GLOBAL
|
||||
&& this.cachedViewPositionsValue !== this.getStoredCachedViewPositionsValue() /* This checks if current window changed the value or not */) {
|
||||
this._cachedViewPositionsValue = this.getStoredCachedViewPositionsValue();
|
||||
@@ -600,7 +596,7 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor
|
||||
}
|
||||
|
||||
private setStoredCachedViewPositionsValue(value: string): void {
|
||||
this.storageService.store(ViewDescriptorService.CACHED_VIEW_POSITIONS, value, StorageScope.GLOBAL);
|
||||
this.storageService.store2(ViewDescriptorService.CACHED_VIEW_POSITIONS, value, StorageScope.GLOBAL, StorageTarget.USER);
|
||||
}
|
||||
|
||||
private getStoredCachedViewContainerLocationsValue(): string {
|
||||
@@ -608,7 +604,7 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor
|
||||
}
|
||||
|
||||
private setStoredCachedViewContainerLocationsValue(value: string): void {
|
||||
this.storageService.store(ViewDescriptorService.CACHED_VIEW_CONTAINER_LOCATIONS, value, StorageScope.GLOBAL);
|
||||
this.storageService.store2(ViewDescriptorService.CACHED_VIEW_CONTAINER_LOCATIONS, value, StorageScope.GLOBAL, StorageTarget.USER);
|
||||
}
|
||||
|
||||
private saveViewPositionsToCache(): void {
|
||||
|
||||
@@ -5,11 +5,10 @@
|
||||
|
||||
import { ViewContainer, IViewsRegistry, IViewDescriptor, Extensions as ViewExtensions, IViewContainerModel, IAddedViewDescriptorRef, IViewDescriptorRef, IAddedViewDescriptorState } from 'vs/workbench/common/views';
|
||||
import { IContextKeyService, IReadableSet } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { IStorageService, StorageScope, IStorageChangeEvent } from 'vs/platform/storage/common/storage';
|
||||
import { IStorageService, StorageScope, IStorageValueChangeEvent, StorageTarget } from 'vs/platform/storage/common/storage';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { IStorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { move } from 'vs/base/common/arrays';
|
||||
@@ -84,14 +83,12 @@ class ViewDescriptorsState extends Disposable {
|
||||
constructor(
|
||||
viewContainerStorageId: string,
|
||||
@IStorageService private readonly storageService: IStorageService,
|
||||
@IStorageKeysSyncRegistryService storageKeysSyncRegistryService: IStorageKeysSyncRegistryService
|
||||
) {
|
||||
super();
|
||||
|
||||
this.globalViewsStateStorageId = getViewsStateStorageId(viewContainerStorageId);
|
||||
this.workspaceViewsStateStorageId = viewContainerStorageId;
|
||||
storageKeysSyncRegistryService.registerStorageKey({ key: this.globalViewsStateStorageId, version: 1 });
|
||||
this._register(this.storageService.onDidChangeStorage(e => this.onDidStorageChange(e)));
|
||||
this._register(this.storageService.onDidChangeValue(e => this.onDidStorageChange(e)));
|
||||
|
||||
this.state = this.initialize();
|
||||
}
|
||||
@@ -143,7 +140,7 @@ class ViewDescriptorsState extends Disposable {
|
||||
this.setStoredGlobalState(storedGlobalState);
|
||||
}
|
||||
|
||||
private onDidStorageChange(e: IStorageChangeEvent): void {
|
||||
private onDidStorageChange(e: IStorageValueChangeEvent): void {
|
||||
if (e.key === this.globalViewsStateStorageId && e.scope === StorageScope.GLOBAL
|
||||
&& this.globalViewsStatesValue !== this.getStoredGlobalViewsStatesValue() /* This checks if current window changed the value or not */) {
|
||||
this._globalViewsStatesValue = undefined;
|
||||
@@ -270,7 +267,7 @@ class ViewDescriptorsState extends Disposable {
|
||||
}
|
||||
|
||||
private setStoredGlobalViewsStatesValue(value: string): void {
|
||||
this.storageService.store(this.globalViewsStateStorageId, value, StorageScope.GLOBAL);
|
||||
this.storageService.store2(this.globalViewsStateStorageId, value, StorageScope.GLOBAL, StorageTarget.USER);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
|
||||
import { IWorkspacesService, IWorkspaceFolderCreationData, IWorkspaceIdentifier, IEnterWorkspaceResult, IRecentlyOpened, restoreRecentlyOpened, IRecent, isRecentFile, isRecentFolder, toStoreData, IStoredWorkspaceFolder, getStoredWorkspaceFolder, WORKSPACE_EXTENSION, IStoredWorkspace } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { Emitter } from 'vs/base/common/event';
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
|
||||
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
@@ -16,7 +16,6 @@ import { IFileService, FileOperationError, FileOperationResult } from 'vs/platfo
|
||||
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
|
||||
import { joinPath } from 'vs/base/common/resources';
|
||||
import { VSBuffer } from 'vs/base/common/buffer';
|
||||
import { IStorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys';
|
||||
|
||||
export class BrowserWorkspacesService extends Disposable implements IWorkspacesService {
|
||||
|
||||
@@ -33,13 +32,9 @@ export class BrowserWorkspacesService extends Disposable implements IWorkspacesS
|
||||
@ILogService private readonly logService: ILogService,
|
||||
@IFileService private readonly fileService: IFileService,
|
||||
@IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService,
|
||||
@IStorageKeysSyncRegistryService storageKeysSyncRegistryService: IStorageKeysSyncRegistryService
|
||||
) {
|
||||
super();
|
||||
|
||||
// opt-in to syncing
|
||||
storageKeysSyncRegistryService.registerStorageKey({ key: BrowserWorkspacesService.RECENTLY_OPENED_KEY, version: 1 });
|
||||
|
||||
// Opening a workspace should push it as most
|
||||
// recently used to the workspaces history
|
||||
this.addWorkspaceToRecentlyOpened();
|
||||
@@ -48,7 +43,7 @@ export class BrowserWorkspacesService extends Disposable implements IWorkspacesS
|
||||
}
|
||||
|
||||
private registerListeners(): void {
|
||||
this._register(this.storageService.onDidChangeStorage(event => {
|
||||
this._register(this.storageService.onDidChangeValue(event => {
|
||||
if (event.key === BrowserWorkspacesService.RECENTLY_OPENED_KEY && event.scope === StorageScope.GLOBAL) {
|
||||
this._onRecentlyOpenedChange.fire();
|
||||
}
|
||||
@@ -116,7 +111,7 @@ export class BrowserWorkspacesService extends Disposable implements IWorkspacesS
|
||||
}
|
||||
|
||||
private async saveRecentlyOpened(data: IRecentlyOpened): Promise<void> {
|
||||
return this.storageService.store(BrowserWorkspacesService.RECENTLY_OPENED_KEY, JSON.stringify(toStoreData(data)), StorageScope.GLOBAL);
|
||||
return this.storageService.store2(BrowserWorkspacesService.RECENTLY_OPENED_KEY, JSON.stringify(toStoreData(data)), StorageScope.GLOBAL, StorageTarget.USER);
|
||||
}
|
||||
|
||||
async clearRecentlyOpened(): Promise<void> {
|
||||
|
||||
@@ -13,7 +13,7 @@ import { TestWorkspace } from 'vs/platform/workspace/test/common/testWorkspace';
|
||||
import { IWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { ITextResourcePropertiesService } from 'vs/editor/common/services/textResourceConfigurationService';
|
||||
import { isLinux, isMacintosh } from 'vs/base/common/platform';
|
||||
import { InMemoryStorageService, IWillSaveStateEvent } from 'vs/platform/storage/common/storage';
|
||||
import { InMemoryStorageService, WillSaveStateReason } from 'vs/platform/storage/common/storage';
|
||||
import { WorkingCopyService, IWorkingCopy, IWorkingCopyBackup, WorkingCopyCapabilities } from 'vs/workbench/services/workingCopy/common/workingCopyService';
|
||||
import { NullExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import { IWorkingCopyFileService, IWorkingCopyFileOperationParticipant, WorkingCopyFileEvent } from 'vs/workbench/services/workingCopy/common/workingCopyFileService';
|
||||
@@ -121,8 +121,10 @@ export class TestContextService implements IWorkspaceContextService {
|
||||
}
|
||||
|
||||
export class TestStorageService extends InMemoryStorageService {
|
||||
readonly _onWillSaveState = this._register(new Emitter<IWillSaveStateEvent>());
|
||||
readonly onWillSaveState = this._onWillSaveState.event;
|
||||
|
||||
emitWillSaveState(reason: WillSaveStateReason): void {
|
||||
super.emitWillSaveState(reason);
|
||||
}
|
||||
}
|
||||
|
||||
export class TestWorkingCopyService extends WorkingCopyService { }
|
||||
|
||||
Reference in New Issue
Block a user