src/common/state/extension_state_service.ts (29 lines of code) (raw):
import * as vscode from 'vscode';
export type StateKey<T> = string & { __brand: 'StateKey'; __type: T };
export interface ExtensionStateProvider<T> {
state: T;
onChange: vscode.Event<T>;
}
export interface ExtensionStateService {
onChange: vscode.Event<void>;
addStateProvider<T>(key: StateKey<T>, provider: ExtensionStateProvider<T>): void;
get<T>(key: StateKey<T>): ExtensionStateProvider<T>;
}
export class DefaultExtensionStateService implements ExtensionStateService {
#subscriptions: vscode.Disposable[] = [];
#eventEmitter = new vscode.EventEmitter<void>();
onChange = this.#eventEmitter.event;
#providers: Record<StateKey<unknown>, ExtensionStateProvider<unknown>> = {};
addStateProvider<T>(key: StateKey<T>, provider: ExtensionStateProvider<T>) {
this.#providers[key] = provider;
this.#subscriptions.push(provider.onChange(() => this.#eventEmitter.fire()));
this.#eventEmitter.fire();
}
get<T>(key: StateKey<T>): ExtensionStateProvider<T> {
const provider = this.#providers[key];
if (!provider) {
throw new Error(`No state provider registered for key: ${key}`);
}
return provider as ExtensionStateProvider<T>;
}
}