Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
gitpod-io
GitHub Repository: gitpod-io/gitpod
Path: blob/main/components/supervisor/frontend/src/ide/ide-frontend-service-impl.ts
2501 views
1
/**
2
* Copyright (c) 2020 Gitpod GmbH. All rights reserved.
3
* Licensed under the GNU Affero General Public License (AGPL).
4
* See License.AGPL.txt in the project root for license information.
5
*/
6
7
import { IDEFrontendService, IDEFrontendState } from "@gitpod/gitpod-protocol/lib/ide-frontend-service";
8
import { Disposable, DisposableCollection } from "@gitpod/gitpod-protocol/lib/util/disposable";
9
import { Emitter } from "@gitpod/gitpod-protocol/lib/util/event";
10
11
interface IDEFrontendCapabilities {
12
/**
13
* Controls whether IDE window can provide the IDE frontend service.
14
*/
15
readonly service?: boolean;
16
}
17
18
let state: IDEFrontendState = "init";
19
window.addEventListener(
20
"beforeunload",
21
(e) => {
22
if (state === "terminated") {
23
// workspace is stopping or stopped avoid to prompt a user with confirmation dialogs
24
e.stopImmediatePropagation();
25
}
26
},
27
{ capture: true },
28
);
29
30
export function create(): IDEFrontendService {
31
let failureCause: Error | undefined;
32
let capabilities: IDEFrontendCapabilities = { service: false };
33
const onDidChangeEmitter = new Emitter<void>();
34
let _delegate: IDEFrontendService | undefined;
35
const toStop = new DisposableCollection();
36
toStop.push(onDidChangeEmitter);
37
const doStart = () => {
38
if (!_delegate || state !== "ready") {
39
return;
40
}
41
try {
42
toStop.push(_delegate.start());
43
} catch (e) {
44
console.error("supervisor frontend: IDE frontend start failed:", e);
45
failureCause = e;
46
state = "terminated";
47
onDidChangeEmitter.fire();
48
}
49
};
50
const service: IDEFrontendService = {
51
get state() {
52
if (state === "terminated") {
53
return "terminated";
54
}
55
if (capabilities.service) {
56
return _delegate?.state || "init";
57
}
58
return state;
59
},
60
get failureCause() {
61
return _delegate?.failureCause || failureCause;
62
},
63
onDidChange: onDidChangeEmitter.event,
64
start: () => {
65
if (state === "terminated") {
66
throw new Error("IDE frontend has been stopped");
67
}
68
state = "ready";
69
toStop.push(
70
Disposable.create(() => {
71
state = "terminated";
72
onDidChangeEmitter.fire();
73
}),
74
);
75
doStart();
76
return toStop;
77
},
78
};
79
const capabilitiesElementAttribute = document
80
.getElementById("gitpod-ide-capabilities")
81
?.getAttribute("data-settings");
82
capabilities = (capabilitiesElementAttribute && JSON.parse(capabilitiesElementAttribute)) || capabilities;
83
Object.defineProperty(window.gitpod, "ideService", {
84
get() {
85
return _delegate;
86
},
87
set(delegate: IDEFrontendService) {
88
if (_delegate) {
89
console.error(new Error("ideService is already set"));
90
return;
91
}
92
_delegate = delegate;
93
doStart();
94
onDidChangeEmitter.fire();
95
delegate.onDidChange(() => onDidChangeEmitter.fire());
96
},
97
});
98
return service;
99
}
100
101