mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-26 03:29:00 +01:00
Allow globalState to be synchronized across multiple windows (#61024)
* Allow globalState to be synchronized across multiple windows (fixes #55834) * address some feedback
This commit is contained in:
@@ -62,6 +62,7 @@ import { ExtHostSearch } from './extHostSearch';
|
||||
import { ExtHostUrls } from './extHostUrls';
|
||||
import { localize } from 'vs/nls';
|
||||
import { ExtHostClipboard } from 'vs/workbench/api/node/extHostClipboard';
|
||||
import { ExtHostStorage } from 'vs/workbench/api/node/extHostStorage';
|
||||
|
||||
export interface IExtensionApiFactory {
|
||||
(extension: IExtensionDescription): typeof vscode;
|
||||
@@ -94,7 +95,8 @@ export function createApiFactory(
|
||||
extHostWorkspace: ExtHostWorkspace,
|
||||
extHostConfiguration: ExtHostConfiguration,
|
||||
extensionService: ExtHostExtensionService,
|
||||
extHostLogService: ExtHostLogService
|
||||
extHostLogService: ExtHostLogService,
|
||||
extHostStorage: ExtHostStorage
|
||||
): IExtensionApiFactory {
|
||||
|
||||
let schemeTransformer: ISchemeTransformer | null = null;
|
||||
@@ -129,6 +131,7 @@ export function createApiFactory(
|
||||
const extHostProgress = rpcProtocol.set(ExtHostContext.ExtHostProgress, new ExtHostProgress(rpcProtocol.getProxy(MainContext.MainThreadProgress)));
|
||||
const exthostCommentProviders = rpcProtocol.set(ExtHostContext.ExtHostComments, new ExtHostComments(rpcProtocol, extHostCommands.converter, extHostDocuments));
|
||||
const extHostOutputService = rpcProtocol.set(ExtHostContext.ExtHostOutputService, new ExtHostOutputService(initData.logsLocation, rpcProtocol));
|
||||
rpcProtocol.set(ExtHostContext.ExtHostStorage, extHostStorage);
|
||||
|
||||
// Check that no named customers are missing
|
||||
const expected: ProxyIdentifier<any>[] = Object.keys(ExtHostContext).map((key) => (<any>ExtHostContext)[key]);
|
||||
|
||||
@@ -430,7 +430,7 @@ export interface MainThreadStatusBarShape extends IDisposable {
|
||||
|
||||
export interface MainThreadStorageShape extends IDisposable {
|
||||
$getValue<T>(shared: boolean, key: string): Thenable<T>;
|
||||
$setValue(shared: boolean, key: string, value: any): Thenable<void>;
|
||||
$setValue(shared: boolean, key: string, value: object): Thenable<void>;
|
||||
}
|
||||
|
||||
export interface MainThreadTelemetryShape extends IDisposable {
|
||||
@@ -1016,6 +1016,10 @@ export interface ExtHostCommentsShape {
|
||||
$provideWorkspaceComments(handle: number): Thenable<modes.CommentThread[]>;
|
||||
}
|
||||
|
||||
export interface ExtHostStorageShape {
|
||||
$acceptValue(shared: boolean, key: string, value: object): void;
|
||||
}
|
||||
|
||||
// --- proxy identifiers
|
||||
|
||||
export const MainContext = {
|
||||
@@ -1081,6 +1085,7 @@ export const ExtHostContext = {
|
||||
ExtHostWebviews: createExtId<ExtHostWebviewsShape>('ExtHostWebviews'),
|
||||
ExtHostProgress: createMainId<ExtHostProgressShape>('ExtHostProgress'),
|
||||
ExtHostComments: createMainId<ExtHostCommentsShape>('ExtHostComments'),
|
||||
ExtHostStorage: createMainId<ExtHostStorageShape>('ExtHostStorage'),
|
||||
ExtHostUrls: createExtId<ExtHostUrlsShape>('ExtHostUrls'),
|
||||
ExtHostOutputService: createMainId<ExtHostOutputServiceShape>('ExtHostOutputService'),
|
||||
};
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { dispose } from 'vs/base/common/lifecycle';
|
||||
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { join } from 'path';
|
||||
import { mkdirp, dirExists, realpath, writeFile } from 'vs/base/node/pfs';
|
||||
import Severity from 'vs/base/common/severity';
|
||||
@@ -30,6 +30,7 @@ class ExtensionMemento implements IExtensionMemento {
|
||||
|
||||
private readonly _init: Thenable<ExtensionMemento>;
|
||||
private _value: { [n: string]: any; };
|
||||
private readonly _storageListener: IDisposable;
|
||||
|
||||
constructor(id: string, global: boolean, storage: ExtHostStorage) {
|
||||
this._id = id;
|
||||
@@ -40,6 +41,12 @@ class ExtensionMemento implements IExtensionMemento {
|
||||
this._value = value;
|
||||
return this;
|
||||
});
|
||||
|
||||
this._storageListener = this._storage.onDidChangeStorage(e => {
|
||||
if (e.shared === this._shared && e.key === this._id) {
|
||||
this._value = e.value;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
get whenReady(): Thenable<ExtensionMemento> {
|
||||
@@ -60,6 +67,10 @@ class ExtensionMemento implements IExtensionMemento {
|
||||
.setValue(this._shared, this._id, this._value)
|
||||
.then(() => true);
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this._storageListener.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
class ExtensionStoragePath {
|
||||
@@ -150,7 +161,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
|
||||
this._activator = null;
|
||||
|
||||
// initialize API first (i.e. do not release barrier until the API is initialized)
|
||||
const apiFactory = createApiFactory(initData, extHostContext, extHostWorkspace, extHostConfiguration, this, this._extHostLogService);
|
||||
const apiFactory = createApiFactory(initData, extHostContext, extHostWorkspace, extHostConfiguration, this, this._extHostLogService, this._storage);
|
||||
|
||||
initializeExtensionApi(this, apiFactory).then(() => {
|
||||
|
||||
|
||||
@@ -3,12 +3,22 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { MainContext, MainThreadStorageShape, IMainContext } from './extHost.protocol';
|
||||
import { MainContext, MainThreadStorageShape, IMainContext, ExtHostStorageShape } from './extHost.protocol';
|
||||
import { Emitter } from 'vs/base/common/event';
|
||||
|
||||
export class ExtHostStorage {
|
||||
export interface IStorageChangeEvent {
|
||||
shared: boolean;
|
||||
key: string;
|
||||
value: object;
|
||||
}
|
||||
|
||||
export class ExtHostStorage implements ExtHostStorageShape {
|
||||
|
||||
private _proxy: MainThreadStorageShape;
|
||||
|
||||
private _onDidChangeStorage = new Emitter<IStorageChangeEvent>();
|
||||
readonly onDidChangeStorage = this._onDidChangeStorage.event;
|
||||
|
||||
constructor(mainContext: IMainContext) {
|
||||
this._proxy = mainContext.getProxy(MainContext.MainThreadStorage);
|
||||
}
|
||||
@@ -17,7 +27,11 @@ export class ExtHostStorage {
|
||||
return this._proxy.$getValue<T>(shared, key).then(value => value || defaultValue);
|
||||
}
|
||||
|
||||
setValue(shared: boolean, key: string, value: any): Thenable<void> {
|
||||
setValue(shared: boolean, key: string, value: object): Thenable<void> {
|
||||
return this._proxy.$setValue(shared, key, value);
|
||||
}
|
||||
|
||||
$acceptValue(shared: boolean, key: string, value: object): void {
|
||||
this._onDidChangeStorage.fire({ shared, key, value });
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user