Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/extensions/copilot/src/util/vs/base/common/observableInternal/changeTracker.ts
13406 views
1
//!!! DO NOT modify, this file was COPIED from 'microsoft/vscode'
2
3
/*---------------------------------------------------------------------------------------------
4
* Copyright (c) Microsoft Corporation. All rights reserved.
5
* Licensed under the MIT License. See License.txt in the project root for license information.
6
*--------------------------------------------------------------------------------------------*/
7
8
import { BugIndicatingError } from './commonFacade/deps';
9
import { IObservableWithChange, IReader } from './base';
10
11
export interface IChangeTracker<TChangeSummary> {
12
createChangeSummary(previousChangeSummary: TChangeSummary | undefined): TChangeSummary;
13
handleChange(ctx: IChangeContext, change: TChangeSummary): boolean;
14
beforeUpdate?(reader: IReader, change: TChangeSummary): void;
15
}
16
17
export interface IChangeContext {
18
readonly changedObservable: IObservableWithChange<any, any>;
19
readonly change: unknown;
20
21
/**
22
* Returns if the given observable caused the change.
23
*/
24
didChange<T, TChange>(observable: IObservableWithChange<T, TChange>): this is { change: TChange };
25
}
26
27
/**
28
* Subscribes to and records changes and the last value of the given observables.
29
* Don't use the key "changes", as it is reserved for the changes array!
30
*/
31
export function recordChanges<TObs extends Record<any, IObservableWithChange<any, any>>>(obs: TObs):
32
IChangeTracker<{ [TKey in keyof TObs]: ReturnType<TObs[TKey]['get']> }
33
& { changes: readonly ({ [TKey in keyof TObs]: { key: TKey; change: TObs[TKey]['TChange'] } }[keyof TObs])[] }> {
34
return {
35
createChangeSummary: (_previousChangeSummary) => {
36
// eslint-disable-next-line local/code-no-any-casts
37
return {
38
changes: [],
39
} as any;
40
},
41
handleChange(ctx, changeSummary) {
42
for (const key in obs) {
43
if (ctx.didChange(obs[key])) {
44
// eslint-disable-next-line local/code-no-any-casts
45
(changeSummary.changes as any).push({ key, change: ctx.change });
46
}
47
}
48
return true;
49
},
50
beforeUpdate(reader, changeSummary) {
51
for (const key in obs) {
52
if (key === 'changes') {
53
throw new BugIndicatingError('property name "changes" is reserved for change tracking');
54
}
55
changeSummary[key] = obs[key].read(reader);
56
}
57
}
58
};
59
}
60
61
/**
62
* Subscribes to and records changes and the last value of the given observables.
63
* Don't use the key "changes", as it is reserved for the changes array!
64
*/
65
export function recordChangesLazy<TObs extends Record<any, IObservableWithChange<any, any>>>(getObs: () => TObs):
66
IChangeTracker<{ [TKey in keyof TObs]: ReturnType<TObs[TKey]['get']> }
67
& { changes: readonly ({ [TKey in keyof TObs]: { key: TKey; change: TObs[TKey]['TChange'] } }[keyof TObs])[] }> {
68
let obs: TObs | undefined = undefined;
69
return {
70
createChangeSummary: (_previousChangeSummary) => {
71
// eslint-disable-next-line local/code-no-any-casts
72
return {
73
changes: [],
74
} as any;
75
},
76
handleChange(ctx, changeSummary) {
77
if (!obs) {
78
obs = getObs();
79
}
80
for (const key in obs) {
81
if (ctx.didChange(obs[key])) {
82
// eslint-disable-next-line local/code-no-any-casts
83
(changeSummary.changes as any).push({ key, change: ctx.change });
84
}
85
}
86
return true;
87
},
88
beforeUpdate(reader, changeSummary) {
89
if (!obs) {
90
obs = getObs();
91
}
92
for (const key in obs) {
93
if (key === 'changes') {
94
throw new BugIndicatingError('property name "changes" is reserved for change tracking');
95
}
96
changeSummary[key] = obs[key].read(reader);
97
}
98
}
99
};
100
}
101
102