Path: blob/main/extensions/copilot/src/platform/inlineEdits/common/utils/observable.ts
13405 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { IDisposable } from '../../../../util/vs/base/common/lifecycle';6import { autorunHandleChanges, IObservableWithChange } from '../../../../util/vs/base/common/observable';78type ObservableResult<T> = T extends IObservableWithChange<infer U, any> ? U : never;910type ObservableArrayToChangesData<T extends Record<string, IObservableWithChange<any, any>>> = {11[Key in keyof T]: {12value: ObservableResult<T[Key]>;13changes: T[Key]['TChange'][];14/**15* The value of the observable before the changes. `undefined` if16*/17previous: ObservableResult<T[Key]> | undefined;18}19};2021export function autorunWithChanges<T extends Record<string, IObservableWithChange<any, any>>>(owner: object, observables: T, handler: (data: ObservableArrayToChangesData<T>) => void): IDisposable {22const observableToKey = new Map(Object.entries(observables).map(([key, value]) => [value, key] as const));2324const previousValues = new Map(Object.keys(observables).map(key => [key, undefined]));2526return autorunHandleChanges({27owner,28changeTracker: {29createChangeSummary: () => ({}) as ObservableArrayToChangesData<T>,30handleChange: (ctx, changeSummary) => {31const key = observableToKey.get(ctx.changedObservable)!;3233if (changeSummary[key] === undefined) {34(changeSummary as any)[key] = { value: undefined!, changes: [] };35}36changeSummary[key].changes.push(ctx.change);37return true;38}39}40}, (reader, data) => {41for (const [key, value] of Object.entries(observables)) {42const v = value.read(reader);4344if (data[key] === undefined) {45(data as any)[key] = { value: v, changes: [], previous: previousValues.get(key) };46}47data[key].value = v;48data[key].previous = previousValues.get(key) === undefined ? undefined : previousValues.get(key);49previousValues.set(key, v);50}51handler(data);52});53}545556