@theia/core
Version:
Theia is a cloud & desktop IDE framework implemented in TypeScript.
210 lines • 9.26 kB
JavaScript
// *****************************************************************************
// Copyright (C) 2018 TypeFox and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0.
//
// This Source Code may also be made available under the following Secondary
// Licenses when the conditions for such availability set forth in the Eclipse
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
// with the GNU Classpath Exception which is available at
// https://www.gnu.org/software/classpath/license.html.
//
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
// *****************************************************************************
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ApplicationConnectionStatusContribution = exports.FrontendConnectionStatusService = exports.AbstractConnectionStatusService = exports.PingService = exports.ConnectionStatusOptions = exports.ConnectionStatus = exports.ConnectionStatusService = void 0;
const inversify_1 = require("inversify");
const logger_1 = require("../common/logger");
const event_1 = require("../common/event");
const frontend_application_contribution_1 = require("./frontend-application-contribution");
const status_bar_1 = require("./status-bar/status-bar");
const ws_connection_provider_1 = require("./messaging/ws-connection-provider");
const common_1 = require("../common");
/**
* Service for listening on backend connection changes.
*/
exports.ConnectionStatusService = Symbol('ConnectionStatusService');
/**
* The connection status.
*/
var ConnectionStatus;
(function (ConnectionStatus) {
/**
* Connected to the backend.
*/
ConnectionStatus[ConnectionStatus["ONLINE"] = 0] = "ONLINE";
/**
* The connection is lost between frontend and backend.
*/
ConnectionStatus[ConnectionStatus["OFFLINE"] = 1] = "OFFLINE";
})(ConnectionStatus = exports.ConnectionStatus || (exports.ConnectionStatus = {}));
let ConnectionStatusOptions = class ConnectionStatusOptions {
};
ConnectionStatusOptions.DEFAULT = {
offlineTimeout: 5000,
};
ConnectionStatusOptions = __decorate([
(0, inversify_1.injectable)()
], ConnectionStatusOptions);
exports.ConnectionStatusOptions = ConnectionStatusOptions;
exports.PingService = Symbol('PingService');
let AbstractConnectionStatusService = class AbstractConnectionStatusService {
constructor(options = ConnectionStatusOptions.DEFAULT) {
this.options = options;
this.statusChangeEmitter = new event_1.Emitter();
this.connectionStatus = ConnectionStatus.ONLINE;
}
get onStatusChange() {
return this.statusChangeEmitter.event;
}
get currentStatus() {
return this.connectionStatus;
}
dispose() {
this.statusChangeEmitter.dispose();
}
updateStatus(success) {
const previousStatus = this.connectionStatus;
const newStatus = success ? ConnectionStatus.ONLINE : ConnectionStatus.OFFLINE;
if (previousStatus !== newStatus) {
this.connectionStatus = newStatus;
this.fireStatusChange(newStatus);
}
}
fireStatusChange(status) {
this.statusChangeEmitter.fire(status);
}
};
__decorate([
(0, inversify_1.inject)(logger_1.ILogger),
__metadata("design:type", Object)
], AbstractConnectionStatusService.prototype, "logger", void 0);
AbstractConnectionStatusService = __decorate([
(0, inversify_1.injectable)(),
__param(0, (0, inversify_1.inject)(ConnectionStatusOptions)),
__param(0, (0, inversify_1.optional)()),
__metadata("design:paramtypes", [ConnectionStatusOptions])
], AbstractConnectionStatusService);
exports.AbstractConnectionStatusService = AbstractConnectionStatusService;
let FrontendConnectionStatusService = class FrontendConnectionStatusService extends AbstractConnectionStatusService {
init() {
this.wsConnectionProvider.onSocketDidOpen(() => {
this.updateStatus(true);
this.schedulePing();
});
this.wsConnectionProvider.onSocketDidClose(() => {
this.clearTimeout(this.scheduledPing);
this.updateStatus(false);
});
this.wsConnectionProvider.onIncomingMessageActivity(() => {
// natural activity
this.updateStatus(true);
this.schedulePing();
});
}
schedulePing() {
this.clearTimeout(this.scheduledPing);
this.scheduledPing = this.setTimeout(async () => {
await this.performPingRequest();
this.schedulePing();
}, this.options.offlineTimeout);
}
async performPingRequest() {
try {
await this.pingService.ping();
this.updateStatus(true);
}
catch (e) {
this.updateStatus(false);
await this.logger.error(e);
}
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
setTimeout(handler, timeout) {
return window.setTimeout(handler, timeout);
}
clearTimeout(handle) {
if (handle !== undefined) {
window.clearTimeout(handle);
}
}
};
__decorate([
(0, inversify_1.inject)(ws_connection_provider_1.WebSocketConnectionProvider),
__metadata("design:type", ws_connection_provider_1.WebSocketConnectionProvider)
], FrontendConnectionStatusService.prototype, "wsConnectionProvider", void 0);
__decorate([
(0, inversify_1.inject)(exports.PingService),
__metadata("design:type", Object)
], FrontendConnectionStatusService.prototype, "pingService", void 0);
__decorate([
(0, inversify_1.postConstruct)(),
__metadata("design:type", Function),
__metadata("design:paramtypes", []),
__metadata("design:returntype", void 0)
], FrontendConnectionStatusService.prototype, "init", null);
FrontendConnectionStatusService = __decorate([
(0, inversify_1.injectable)()
], FrontendConnectionStatusService);
exports.FrontendConnectionStatusService = FrontendConnectionStatusService;
let ApplicationConnectionStatusContribution = class ApplicationConnectionStatusContribution extends frontend_application_contribution_1.DefaultFrontendApplicationContribution {
constructor(connectionStatusService, statusBar, logger) {
super();
this.connectionStatusService = connectionStatusService;
this.statusBar = statusBar;
this.logger = logger;
this.toDisposeOnOnline = new common_1.DisposableCollection();
this.statusbarId = 'connection-status';
this.connectionStatusService.onStatusChange(state => this.onStateChange(state));
}
onStateChange(state) {
switch (state) {
case ConnectionStatus.OFFLINE: {
this.handleOffline();
break;
}
case ConnectionStatus.ONLINE: {
this.handleOnline();
break;
}
}
}
handleOnline() {
this.toDisposeOnOnline.dispose();
}
handleOffline() {
this.statusBar.setElement(this.statusbarId, {
alignment: status_bar_1.StatusBarAlignment.LEFT,
text: common_1.nls.localize('theia/core/offline', 'Offline'),
tooltip: common_1.nls.localize('theia/localize/offlineTooltip', 'Cannot connect to backend.'),
priority: 5000
});
this.toDisposeOnOnline.push(common_1.Disposable.create(() => this.statusBar.removeElement(this.statusbarId)));
document.body.classList.add('theia-mod-offline');
this.toDisposeOnOnline.push(common_1.Disposable.create(() => document.body.classList.remove('theia-mod-offline')));
}
};
ApplicationConnectionStatusContribution = __decorate([
(0, inversify_1.injectable)(),
__param(0, (0, inversify_1.inject)(exports.ConnectionStatusService)),
__param(1, (0, inversify_1.inject)(status_bar_1.StatusBar)),
__param(2, (0, inversify_1.inject)(logger_1.ILogger)),
__metadata("design:paramtypes", [Object, Object, Object])
], ApplicationConnectionStatusContribution);
exports.ApplicationConnectionStatusContribution = ApplicationConnectionStatusContribution;
//# sourceMappingURL=connection-status-service.js.map
;