Path: blob/main/extensions/copilot/src/util/vs/base/common/observableInternal/base.ts
13406 views
//!!! DO NOT modify, this file was COPIED from 'microsoft/vscode'12/*---------------------------------------------------------------------------------------------3* Copyright (c) Microsoft Corporation. All rights reserved.4* Licensed under the MIT License. See License.txt in the project root for license information.5*--------------------------------------------------------------------------------------------*/67import { DisposableStore, onUnexpectedError } from './commonFacade/deps';89/**10* Represents an observable value.11*12* @template T The type of the values the observable can hold.13*/14// This interface exists so that, for example for string observables,15// typescript renders the type as `IObservable<string>` instead of `IObservable<string, unknown>`.16export interface IObservable<T> extends IObservableWithChange<T, unknown> { }1718/**19* Represents an observable value.20*21* @template T The type of the values the observable can hold.22* @template TChange The type used to describe value changes23* (usually `void` and only used in advanced scenarios).24* While observers can miss temporary values of an observable,25* they will receive all change values (as long as they are subscribed)!26*/27export interface IObservableWithChange<T, TChange = unknown> {28/**29* Returns the current value.30*31* Calls {@link IObserver.handleChange} if the observable notices that the value changed.32* Must not be called from {@link IObserver.handleChange}!33*/34get(): T;3536/**37* Forces the observable to check for changes and report them.38*39* Has the same effect as calling {@link IObservable.get}, but does not force the observable40* to actually construct the value, e.g. if change deltas are used.41* Calls {@link IObserver.handleChange} if the observable notices that the value changed.42* Must not be called from {@link IObserver.handleChange}!43*/44reportChanges(): void;4546/**47* Adds the observer to the set of subscribed observers.48* This method is idempotent.49*/50addObserver(observer: IObserver): void;5152/**53* Removes the observer from the set of subscribed observers.54* This method is idempotent.55*/56removeObserver(observer: IObserver): void;5758// #region These members have a standard implementation and are only part of the interface for convenience.5960/**61* Reads the current value and subscribes the reader to this observable.62*63* Calls {@link IReader.readObservable} if a reader is given, otherwise {@link IObservable.get}64* (see {@link ConvenientObservable.read} for the implementation).65*/66read(reader: IReader | undefined): T;6768/**69* Makes sure this value is computed eagerly.70*/71recomputeInitiallyAndOnChange(store: DisposableStore, handleValue?: (value: T) => void): IObservable<T>;7273/**74* Makes sure this value is cached.75*/76keepObserved(store: DisposableStore): IObservable<T>;7778/**79* Creates a derived observable that depends on this observable.80* Use the reader to read other observables81* (see {@link ConvenientObservable.map} for the implementation).82*/83map<TNew>(fn: (value: T, reader: IReader) => TNew): IObservable<TNew>;84map<TNew>(owner: object, fn: (value: T, reader: IReader) => TNew): IObservable<TNew>;8586flatten<TNew>(this: IObservable<IObservable<TNew>>): IObservable<TNew>;8788/**89* ONLY FOR DEBUGGING!90* Logs computations of this derived.91*/92log(): IObservableWithChange<T, TChange>;9394/**95* A human-readable name for debugging purposes.96*/97readonly debugName: string;9899/**100* This property captures the type of the change object. Do not use it at runtime!101*/102readonly TChange: TChange;103104// #endregion105}106107/**108* Represents an observer that can be subscribed to an observable.109*110* If an observer is subscribed to an observable and that observable didn't signal111* a change through one of the observer methods, the observer can assume that the112* observable didn't change.113* If an observable reported a possible change, {@link IObservable.reportChanges} forces114* the observable to report an actual change if there was one.115*/116export interface IObserver {117/**118* Signals that the given observable might have changed and a transaction potentially modifying that observable started.119* Before the given observable can call this method again, is must call {@link IObserver.endUpdate}.120*121* Implementations must not get/read the value of other observables, as they might not have received this event yet!122* The method {@link IObservable.reportChanges} can be used to force the observable to report the changes.123*/124beginUpdate<T>(observable: IObservable<T>): void;125126/**127* Signals that the transaction that potentially modified the given observable ended.128* This is a good place to react to (potential) changes.129*/130endUpdate<T>(observable: IObservable<T>): void;131132/**133* Signals that the given observable might have changed.134* The method {@link IObservable.reportChanges} can be used to force the observable to report the changes.135*136* Implementations must not get/read the value of other observables, as they might not have received this event yet!137* The change should be processed lazily or in {@link IObserver.endUpdate}.138*/139handlePossibleChange<T>(observable: IObservable<T>): void;140141/**142* Signals that the given {@link observable} changed.143*144* Implementations must not get/read the value of other observables, as they might not have received this event yet!145* The change should be processed lazily or in {@link IObserver.endUpdate}.146*147* @param change Indicates how or why the value changed.148*/149handleChange<T, TChange>(observable: IObservableWithChange<T, TChange>, change: TChange): void;150}151152/**153* A reader allows code to track what it depends on, so the caller knows when the computed value or produced side-effect is no longer valid.154* Use `derived(reader => ...)` to turn code that needs a reader into an observable value.155*/156export interface IReader {157/**158* Reads the value of an observable and subscribes to it.159*/160readObservable<T>(observable: IObservableWithChange<T, any>): T;161}162163export interface ISettable<T, TChange = void> {164/**165* Sets the value of the observable.166* Use a transaction to batch multiple changes (with a transaction, observers only react at the end of the transaction).167*168* @param transaction When given, value changes are handled on demand or when the transaction ends.169* @param change Describes how or why the value changed.170*/171set(value: T, transaction: ITransaction | undefined, change: TChange): void;172}173174export interface ITransaction {175/**176* Calls {@link Observer.beginUpdate} immediately177* and {@link Observer.endUpdate} when the transaction ends.178*/179updateObserver(observer: IObserver, observable: IObservableWithChange<any, any>): void;180}181182/**183* This function is used to indicate that the caller recovered from an error that indicates a bug.184*/185export function handleBugIndicatingErrorRecovery(message: string) {186const err = new Error('BugIndicatingErrorRecovery: ' + message);187onUnexpectedError(err);188console.error('recovered from an error that indicates a bug', err);189}190191/**192* A settable observable.193*/194export interface ISettableObservable<T, TChange = void> extends IObservableWithChange<T, TChange>, ISettable<T, TChange> {195}196197export interface IReaderWithStore extends IReader {198/**199* Items in this store get disposed just before the observable recomputes/reruns or when it becomes unobserved.200*/201get store(): DisposableStore;202203/**204* Items in this store get disposed just after the observable recomputes/reruns or when it becomes unobserved.205* This is important if the current run needs the undisposed result from the last run.206*207* Warning: Items in this store might still get disposed before dependents (that read the now disposed value in the past) are recomputed with the new (undisposed) value!208* A clean solution for this is ref counting.209*/210get delayedStore(): DisposableStore;211}212213214