UNPKG

@sussudio/platform

Version:

Internal APIs for VS Code's service injection the base services.

111 lines (110 loc) 4.23 kB
/*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { Emitter, Event } from '@sussudio/base/common/event.mjs'; import { Disposable, DisposableStore, MutableDisposable } from '@sussudio/base/common/lifecycle.mjs'; import { loadKeyTargets, TARGET_KEY } from '../../storage/common/storage.mjs'; export class ProfileStorageChangesListenerChannel extends Disposable { storageMainService; userDataProfilesService; logService; _onDidChange; constructor(storageMainService, userDataProfilesService, logService) { super(); this.storageMainService = storageMainService; this.userDataProfilesService = userDataProfilesService; this.logService = logService; const disposable = this._register(new MutableDisposable()); this._onDidChange = this._register( new Emitter({ // Start listening to profile storage changes only when someone is listening onWillAddFirstListener: () => (disposable.value = this.registerStorageChangeListeners()), // Stop listening to profile storage changes when no one is listening onDidRemoveLastListener: () => (disposable.value = undefined), }), ); } registerStorageChangeListeners() { this.logService.debug('ProfileStorageChangesListenerChannel#registerStorageChangeListeners'); const disposables = new DisposableStore(); disposables.add( Event.debounce( this.storageMainService.applicationStorage.onDidChangeStorage, (keys, e) => { if (keys) { keys.push(e.key); } else { keys = [e.key]; } return keys; }, 100, )((keys) => this.onDidChangeApplicationStorage(keys)), ); disposables.add( Event.debounce( this.storageMainService.onDidChangeProfileStorage, (changes, e) => { if (!changes) { changes = new Map(); } let profileChanges = changes.get(e.profile.id); if (!profileChanges) { changes.set(e.profile.id, (profileChanges = { profile: e.profile, keys: [], storage: e.storage })); } profileChanges.keys.push(e.key); return changes; }, 100, )((keys) => this.onDidChangeProfileStorage(keys)), ); return disposables; } onDidChangeApplicationStorage(keys) { const targetChangedProfiles = keys.includes(TARGET_KEY) ? [this.userDataProfilesService.defaultProfile] : []; const profileStorageValueChanges = []; keys = keys.filter((key) => key !== TARGET_KEY); if (keys.length) { const keyTargets = loadKeyTargets(this.storageMainService.applicationStorage.storage); profileStorageValueChanges.push({ profile: this.userDataProfilesService.defaultProfile, changes: keys.map((key) => ({ key, scope: 0 /* StorageScope.PROFILE */, target: keyTargets[key] })), }); } this.triggerEvents(targetChangedProfiles, profileStorageValueChanges); } onDidChangeProfileStorage(changes) { const targetChangedProfiles = []; const profileStorageValueChanges = new Map(); for (const [profileId, profileChanges] of changes.entries()) { if (profileChanges.keys.includes(TARGET_KEY)) { targetChangedProfiles.push(profileChanges.profile); } const keys = profileChanges.keys.filter((key) => key !== TARGET_KEY); if (keys.length) { const keyTargets = loadKeyTargets(profileChanges.storage.storage); profileStorageValueChanges.set(profileId, { profile: profileChanges.profile, changes: keys.map((key) => ({ key, scope: 0 /* StorageScope.PROFILE */, target: keyTargets[key] })), }); } } this.triggerEvents(targetChangedProfiles, [...profileStorageValueChanges.values()]); } triggerEvents(targetChanges, valueChanges) { if (targetChanges.length || valueChanges.length) { this._onDidChange.fire({ valueChanges, targetChanges }); } } listen(_, event, arg) { switch (event) { case 'onDidChange': return this._onDidChange.event; } throw new Error(`Event not found: ${event}`); } async call(_, command) { throw new Error(`Call not found: ${command}`); } }