Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/extensions/copilot/test/simulation/workbench/utils/utils.ts
13399 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import * as fs from 'fs';
7
import * as mobx from 'mobx';
8
import { InterceptedRequest } from '../../shared/sharedTypes';
9
10
export const REPO_ROOT: string = (globalThis as any).projectRoot;
11
12
export const monacoModule: {
13
value: typeof import('monaco-editor');
14
} = {
15
value: null! // @ulugbekna: this is initialized on workbench startup and must be non-null by the time it's used
16
};
17
18
export function genericEquals(one: any, other: any): boolean {
19
if (one === other) {
20
return true;
21
}
22
if (one === null || one === undefined || other === null || other === undefined) {
23
return false;
24
}
25
if (typeof one !== typeof other) {
26
return false;
27
}
28
if (typeof one !== 'object') {
29
return false;
30
}
31
if ((Array.isArray(one)) !== (Array.isArray(other))) {
32
return false;
33
}
34
35
let i: number;
36
let key: string;
37
38
if (Array.isArray(one)) {
39
if (one.length !== other.length) {
40
return false;
41
}
42
for (i = 0; i < one.length; i++) {
43
if (!genericEquals(one[i], other[i])) {
44
return false;
45
}
46
}
47
} else {
48
const oneKeys: string[] = [];
49
50
for (key in one) {
51
oneKeys.push(key);
52
}
53
oneKeys.sort();
54
const otherKeys: string[] = [];
55
for (key in other) {
56
otherKeys.push(key);
57
}
58
otherKeys.sort();
59
if (!genericEquals(oneKeys, otherKeys)) {
60
return false;
61
}
62
for (i = 0; i < oneKeys.length; i++) {
63
if (!genericEquals(one[oneKeys[i]], other[oneKeys[i]])) {
64
return false;
65
}
66
}
67
}
68
return true;
69
}
70
71
let pendingRunInAction: (() => void)[] = [];
72
73
/**
74
* Schedules a function to be run inside a MobX action.
75
* This will batch multiple callers in a single runInAction MobX call.
76
*
77
* @param fn - The function to be scheduled.
78
*/
79
export function scheduleRunInAction(fn: () => void) {
80
pendingRunInAction.push(fn);
81
if (pendingRunInAction.length === 1) {
82
process.nextTick(() => {
83
const updates = pendingRunInAction;
84
pendingRunInAction = [];
85
runInAction(updates);
86
});
87
}
88
}
89
90
function runInAction(fns: (() => void)[]) {
91
mobx.runInAction(() => {
92
for (const fn of fns) {
93
try {
94
fn();
95
} catch (err) {
96
console.error(err);
97
}
98
}
99
});
100
}
101
102
export class ObservablePromise<T> {
103
104
public static resolve<T>(value: T): ObservablePromise<T> {
105
return new ObservablePromise(Promise.resolve(value), value);
106
}
107
108
public readonly promise: Promise<T>;
109
110
@mobx.observable.ref
111
public error: unknown;
112
113
@mobx.observable.ref
114
public value: T;
115
116
@mobx.observable.ref
117
public resolved: boolean;
118
119
constructor(promise: Promise<T>, defaultValue: T) {
120
this.promise = promise;
121
this.error = null;
122
this.value = defaultValue;
123
this.resolved = false;
124
125
mobx.makeObservable(this);
126
127
this.promise.then(
128
(value: T) => {
129
scheduleRunInAction(() => {
130
this.value = value;
131
this.resolved = true;
132
});
133
},
134
(error: unknown) => {
135
scheduleRunInAction(() => {
136
console.error(error);
137
this.error = error;
138
this.resolved = true;
139
});
140
}
141
);
142
}
143
}
144
145
export async function fileExists(filePath: string): Promise<boolean> {
146
try {
147
await fs.promises.access(filePath);
148
return true;
149
} catch (_) {
150
return false;
151
}
152
}
153
154
export function isToolCall(request: InterceptedRequest) {
155
return Boolean(request.response.copilotFunctionCalls?.length);
156
}
157
158