UNPKG

sussudio

Version:

An unofficial VS Code Internal API

143 lines (142 loc) 5.39 kB
/*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __param = (this && this.__param) || function (paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } }; import { ThrottledDelayer } from "../../../base/common/async.mjs"; import { VSBuffer } from "../../../base/common/buffer.mjs"; import { isUndefined, isUndefinedOrNull } from "../../../base/common/types.mjs"; import { IEnvironmentService } from "../../environment/common/environment.mjs"; import { IFileService } from "../../files/common/files.mjs"; import { ILogService } from "../../log/common/log.mjs"; export class FileStorage { storagePath; logService; fileService; storage = Object.create(null); lastSavedStorageContents = ''; flushDelayer = new ThrottledDelayer(100 /* buffer saves over a short time */); initializing = undefined; closing = undefined; constructor(storagePath, logService, fileService) { this.storagePath = storagePath; this.logService = logService; this.fileService = fileService; } init() { if (!this.initializing) { this.initializing = this.doInit(); } return this.initializing; } async doInit() { try { this.lastSavedStorageContents = (await this.fileService.readFile(this.storagePath)).value.toString(); this.storage = JSON.parse(this.lastSavedStorageContents); } catch (error) { if (error.fileOperationResult !== 1 /* FileOperationResult.FILE_NOT_FOUND */) { this.logService.error(error); } } } getItem(key, defaultValue) { const res = this.storage[key]; if (isUndefinedOrNull(res)) { return defaultValue; } return res; } setItem(key, data) { this.setItems([{ key, data }]); } setItems(items) { let save = false; for (const { key, data } of items) { // Shortcut for data that did not change if (this.storage[key] === data) { continue; } // Remove items when they are undefined or null if (isUndefinedOrNull(data)) { if (!isUndefined(this.storage[key])) { this.storage[key] = undefined; save = true; } } // Otherwise add an item else { this.storage[key] = data; save = true; } } if (save) { this.save(); } } removeItem(key) { // Only update if the key is actually present (not undefined) if (!isUndefined(this.storage[key])) { this.storage[key] = undefined; this.save(); } } async save() { if (this.closing) { return; // already about to close } return this.flushDelayer.trigger(() => this.doSave()); } async doSave() { if (!this.initializing) { return; // if we never initialized, we should not save our state } // Make sure to wait for init to finish first await this.initializing; // Return early if the database has not changed const serializedDatabase = JSON.stringify(this.storage, null, 4); if (serializedDatabase === this.lastSavedStorageContents) { return; } // Write to disk try { await this.fileService.writeFile(this.storagePath, VSBuffer.fromString(serializedDatabase)); this.lastSavedStorageContents = serializedDatabase; } catch (error) { this.logService.error(error); } } async close() { if (!this.closing) { this.closing = this.flushDelayer.trigger(() => this.doSave(), 0 /* as soon as possible */); } return this.closing; } } let StateService = class StateService { fileStorage; constructor(environmentService, logService, fileService) { this.fileStorage = new FileStorage(environmentService.stateResource, logService, fileService); } async init() { await this.fileStorage.init(); } getItem(key, defaultValue) { return this.fileStorage.getItem(key, defaultValue); } }; StateService = __decorate([ __param(0, IEnvironmentService), __param(1, ILogService), __param(2, IFileService) ], StateService); export { StateService };