| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- import { Emitter, PauseableEmitter } from '../../../base/common/event.js';
- import { Disposable } from '../../../base/common/lifecycle.js';
- import { isUndefinedOrNull } from '../../../base/common/types.js';
- import { InMemoryStorageDatabase, Storage } from '../../../base/parts/storage/common/storage.js';
- import { createDecorator } from '../../instantiation/common/instantiation.js';
- const TARGET_KEY = '__$__targetStorageMarker';
- export const IStorageService = createDecorator('storageService');
- export var WillSaveStateReason;
- (function (WillSaveStateReason) {
- /**
- * No specific reason to save state.
- */
- WillSaveStateReason[WillSaveStateReason["NONE"] = 0] = "NONE";
- /**
- * A hint that the workbench is about to shutdown.
- */
- WillSaveStateReason[WillSaveStateReason["SHUTDOWN"] = 1] = "SHUTDOWN";
- })(WillSaveStateReason || (WillSaveStateReason = {}));
- export class AbstractStorageService extends Disposable {
- constructor(options = { flushInterval: AbstractStorageService.DEFAULT_FLUSH_INTERVAL }) {
- super();
- this.options = options;
- this._onDidChangeValue = this._register(new PauseableEmitter());
- this.onDidChangeValue = this._onDidChangeValue.event;
- this._onDidChangeTarget = this._register(new PauseableEmitter());
- this._onWillSaveState = this._register(new Emitter());
- this.onWillSaveState = this._onWillSaveState.event;
- this._workspaceKeyTargets = undefined;
- this._profileKeyTargets = undefined;
- this._applicationKeyTargets = undefined;
- }
- emitDidChangeValue(scope, key) {
- // Specially handle `TARGET_KEY`
- if (key === TARGET_KEY) {
- // Clear our cached version which is now out of date
- switch (scope) {
- case -1 /* StorageScope.APPLICATION */:
- this._applicationKeyTargets = undefined;
- break;
- case 0 /* StorageScope.PROFILE */:
- this._profileKeyTargets = undefined;
- break;
- case 1 /* StorageScope.WORKSPACE */:
- this._workspaceKeyTargets = undefined;
- break;
- }
- // 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] });
- }
- }
- get(key, scope, fallbackValue) {
- var _a;
- return (_a = this.getStorage(scope)) === null || _a === void 0 ? void 0 : _a.get(key, fallbackValue);
- }
- getBoolean(key, scope, fallbackValue) {
- var _a;
- return (_a = this.getStorage(scope)) === null || _a === void 0 ? void 0 : _a.getBoolean(key, fallbackValue);
- }
- getNumber(key, scope, fallbackValue) {
- var _a;
- return (_a = this.getStorage(scope)) === null || _a === void 0 ? void 0 : _a.getNumber(key, fallbackValue);
- }
- store(key, value, scope, target) {
- // 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(() => {
- var _a;
- // Update key-target map
- this.updateKeyTarget(key, scope, target);
- // Store actual value
- (_a = this.getStorage(scope)) === null || _a === void 0 ? void 0 : _a.set(key, value);
- });
- }
- remove(key, scope) {
- // Update our datastructures but send events only after
- this.withPausedEmitters(() => {
- var _a;
- // Update key-target map
- this.updateKeyTarget(key, scope, undefined);
- // Remove actual key
- (_a = this.getStorage(scope)) === null || _a === void 0 ? void 0 : _a.delete(key);
- });
- }
- withPausedEmitters(fn) {
- // Pause emitters
- this._onDidChangeValue.pause();
- this._onDidChangeTarget.pause();
- try {
- fn();
- }
- finally {
- // Resume emitters
- this._onDidChangeValue.resume();
- this._onDidChangeTarget.resume();
- }
- }
- updateKeyTarget(key, scope, target) {
- var _a, _b;
- // Add
- const keyTargets = this.getKeyTargets(scope);
- if (typeof target === 'number') {
- if (keyTargets[key] !== target) {
- keyTargets[key] = target;
- (_a = this.getStorage(scope)) === null || _a === void 0 ? void 0 : _a.set(TARGET_KEY, JSON.stringify(keyTargets));
- }
- }
- // Remove
- else {
- if (typeof keyTargets[key] === 'number') {
- delete keyTargets[key];
- (_b = this.getStorage(scope)) === null || _b === void 0 ? void 0 : _b.set(TARGET_KEY, JSON.stringify(keyTargets));
- }
- }
- }
- get workspaceKeyTargets() {
- if (!this._workspaceKeyTargets) {
- this._workspaceKeyTargets = this.loadKeyTargets(1 /* StorageScope.WORKSPACE */);
- }
- return this._workspaceKeyTargets;
- }
- get profileKeyTargets() {
- if (!this._profileKeyTargets) {
- this._profileKeyTargets = this.loadKeyTargets(0 /* StorageScope.PROFILE */);
- }
- return this._profileKeyTargets;
- }
- get applicationKeyTargets() {
- if (!this._applicationKeyTargets) {
- this._applicationKeyTargets = this.loadKeyTargets(-1 /* StorageScope.APPLICATION */);
- }
- return this._applicationKeyTargets;
- }
- getKeyTargets(scope) {
- switch (scope) {
- case -1 /* StorageScope.APPLICATION */:
- return this.applicationKeyTargets;
- case 0 /* StorageScope.PROFILE */:
- return this.profileKeyTargets;
- default:
- return this.workspaceKeyTargets;
- }
- }
- loadKeyTargets(scope) {
- const keysRaw = this.get(TARGET_KEY, scope);
- if (keysRaw) {
- try {
- return JSON.parse(keysRaw);
- }
- catch (error) {
- // Fail gracefully
- }
- }
- return Object.create(null);
- }
- }
- AbstractStorageService.DEFAULT_FLUSH_INTERVAL = 60 * 1000; // every minute
- export class InMemoryStorageService extends AbstractStorageService {
- constructor() {
- super();
- this.applicationStorage = this._register(new Storage(new InMemoryStorageDatabase()));
- this.profileStorage = this._register(new Storage(new InMemoryStorageDatabase()));
- this.workspaceStorage = this._register(new Storage(new InMemoryStorageDatabase()));
- this._register(this.workspaceStorage.onDidChangeStorage(key => this.emitDidChangeValue(1 /* StorageScope.WORKSPACE */, key)));
- this._register(this.profileStorage.onDidChangeStorage(key => this.emitDidChangeValue(0 /* StorageScope.PROFILE */, key)));
- this._register(this.applicationStorage.onDidChangeStorage(key => this.emitDidChangeValue(-1 /* StorageScope.APPLICATION */, key)));
- }
- getStorage(scope) {
- switch (scope) {
- case -1 /* StorageScope.APPLICATION */:
- return this.applicationStorage;
- case 0 /* StorageScope.PROFILE */:
- return this.profileStorage;
- default:
- return this.workspaceStorage;
- }
- }
- }
|