1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
/*
* SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/>
*
* SPDX-License-Identifier: EPL-2.0
*/
import { Diagnostic } from '@codemirror/lint';
import { type IReactionDisposer, makeAutoObservable, reaction } from 'mobx';
import type EditorStore from './EditorStore';
const HYSTERESIS_TIME_MS = 250;
export interface State {
analyzing: boolean;
errorCount: number;
warningCount: number;
infoCount: number;
semanticsError: string | undefined;
}
export default class EditorErrors implements State {
private readonly disposer: IReactionDisposer;
private timer: number | undefined;
analyzing = false;
errorCount = 0;
warningCount = 0;
infoCount = 0;
semanticsError: string | undefined;
constructor(private readonly store: EditorStore) {
this.updateImmediately(this.getNextState());
makeAutoObservable<EditorErrors, 'disposer' | 'timer'>(this, {
disposer: false,
timer: false,
});
this.disposer = reaction(
() => this.getNextState(),
(nextState) => {
if (this.timer !== undefined) {
clearTimeout(this.timer);
this.timer = undefined;
}
if (nextState.analyzing) {
this.timer = setTimeout(
() => this.updateImmediately(nextState),
HYSTERESIS_TIME_MS,
);
} else {
this.updateImmediately(nextState);
}
},
{ fireImmediately: true },
);
}
get highestDiagnosticLevel(): Diagnostic['severity'] | undefined {
if (this.errorCount > 0) {
return 'error';
}
if (this.warningCount > 0) {
return 'warning';
}
if (this.infoCount > 0) {
return 'info';
}
return undefined;
}
private getNextState(): State {
return {
analyzing: this.store.analyzing,
errorCount: this.store.errorCount,
warningCount: this.store.warningCount,
infoCount: this.store.infoCount,
semanticsError: this.store.semanticsError,
};
}
private updateImmediately(nextState: State) {
Object.assign(this, nextState);
}
dispose() {
this.disposer();
}
}
|