Skip to content

Commit

Permalink
Integrate preload into the messaging system
Browse files Browse the repository at this point in the history
  • Loading branch information
msujew committed Jul 3, 2023
1 parent c5150c0 commit 692ffa9
Show file tree
Hide file tree
Showing 14 changed files with 108 additions and 67 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -140,14 +140,14 @@ async function start(port, host, argv = process.argv) {
container.bind(BackendApplicationServer).toConstantValue({ configure: defaultServeStatic });
}
await container.get(CliManager).initializeCli(argv);
await container.get(BackendApplication).start(port, host);
return container.get(BackendApplication).start(port, host);
}
module.exports = async (port, host, argv) => {
try {
${Array.from(backendModules.values(), jsModulePath => `\
await load(require('${jsModulePath}'));`).join('\n')}
await start(port, host, argv);
return await start(port, host, argv);
} catch (error) {
console.error('Failed to start the backend application:');
console.error(error);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,9 @@ function load(container, jsModule) {
.then(containerModule => container.load(containerModule.default));
}
async function preload() {
async function preload(parent) {
const container = new Container();
container.parent = parent;
try {
${Array.from(frontendPreloadModules.values(), jsModulePath => `\
await load(container, import('${jsModulePath}'));`).join('\n')}
Expand All @@ -107,18 +108,18 @@ ${Array.from(frontendPreloadModules.values(), jsModulePath => `\
}
}
module.exports = async () => {
await preload();
const { FrontendApplication } = require('@theia/core/lib/browser');
const { frontendApplicationModule } = require('@theia/core/lib/browser/frontend-application-module');
module.exports = (async () => {
const { messagingFrontendModule } = require('@theia/core/lib/${this.pck.isBrowser()
? 'browser/messaging/messaging-frontend-module'
: 'electron-browser/messaging/electron-messaging-frontend-module'}');
? 'browser/messaging/messaging-frontend-module'
: 'electron-browser/messaging/electron-messaging-frontend-module'}');
const container = new Container();
container.load(messagingFrontendModule);
await preload(container);
const { FrontendApplication } = require('@theia/core/lib/browser');
const { frontendApplicationModule } = require('@theia/core/lib/browser/frontend-application-module');
const { loggerFrontendModule } = require('@theia/core/lib/browser/logger-frontend-module');
const container = new Container();
container.load(frontendApplicationModule);
container.load(messagingFrontendModule);
container.load(loggerFrontendModule);
try {
Expand All @@ -136,7 +137,7 @@ ${Array.from(frontendModules.values(), jsModulePath => `\
(window['theia'] = window['theia'] || {}).container = container;
return container.get(FrontendApplication).start();
}
};
})();
`;
}

Expand Down
14 changes: 8 additions & 6 deletions packages/core/src/browser/preload/i18n-preload-contribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,17 @@
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
// *****************************************************************************

import { AbstractPreloadContribution } from './preloader';
import { PreloadContribution } from './preloader';
import { FrontendApplicationConfigProvider } from '../frontend-application-config-provider';
import { nls } from '../../common/nls';
import { Localization } from '../../common/i18n/localization';
import { injectable } from 'inversify';
import { inject, injectable } from 'inversify';
import { LocalizationServer } from '../../common/i18n/localization-server';

@injectable()
export class I18nPreloadContribution extends AbstractPreloadContribution {
export class I18nPreloadContribution implements PreloadContribution {

@inject(LocalizationServer)
protected readonly localizationServer: LocalizationServer;

async initialize(): Promise<void> {
const defaultLocale = FrontendApplicationConfigProvider.get().defaultLocale;
Expand All @@ -31,8 +34,7 @@ export class I18nPreloadContribution extends AbstractPreloadContribution {
});
}
if (nls.locale) {
const response = await this.fetch(`/i18n/${nls.locale}`);
const localization = await response.json() as Localization;
const localization = await this.localizationServer.loadLocalization(nls.locale);
if (localization.languagePack) {
nls.localization = localization;
} else {
Expand Down
15 changes: 9 additions & 6 deletions packages/core/src/browser/preload/os-preload-contribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,24 @@
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
// *****************************************************************************

import { injectable } from 'inversify';
import { OS } from '../../common';
import { AbstractPreloadContribution } from './preloader';
import { inject, injectable } from 'inversify';
import { OS, OSBackendProvider } from '../../common';
import { PreloadContribution } from './preloader';

@injectable()
export class OSPreloadContribution extends AbstractPreloadContribution {
export class OSPreloadContribution implements PreloadContribution {

@inject(OSBackendProvider)
protected readonly osBackendProvider: OSBackendProvider;

async initialize(): Promise<void> {
const response = await this.fetch('/os');
const osType = await response.text() as OS.Type;
const osType = await this.osBackendProvider.getBackendOS();
const isWindows = osType === 'Windows';
const isOSX = osType === 'OSX';
OS.backend.isOSX = isOSX;
OS.backend.isWindows = isWindows;
OS.backend.type = () => osType;
OS.backend.EOL = isWindows ? '\r\n' : '\n';
}

}
11 changes: 11 additions & 0 deletions packages/core/src/browser/preload/preload-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,22 @@ import { bindContributionProvider } from '../../common/contribution-provider';
import { I18nPreloadContribution } from './i18n-preload-contribution';
import { OSPreloadContribution } from './os-preload-contribution';
import { ThemePreloadContribution } from './theme-preload-contribution';
import { LocalizationServer, LocalizationServerPath } from '../../common/i18n/localization-server';
import { WebSocketConnectionProvider } from '../messaging/ws-connection-provider';
import { OSBackendProvider, OSBackendProviderPath } from '../../common/os';

export default new ContainerModule(bind => {
bind(Preloader).toSelf().inSingletonScope();
bindContributionProvider(bind, PreloadContribution);

bind(LocalizationServer).toDynamicValue(ctx =>
WebSocketConnectionProvider.createProxy<LocalizationServer>(ctx.container, LocalizationServerPath)
).inSingletonScope();

bind(OSBackendProvider).toDynamicValue(ctx =>
WebSocketConnectionProvider.createProxy<OSBackendProvider>(ctx.container, OSBackendProviderPath)
).inSingletonScope();

bind(I18nPreloadContribution).toSelf().inSingletonScope();
bind(PreloadContribution).toService(I18nPreloadContribution);
bind(OSPreloadContribution).toSelf().inSingletonScope();
Expand Down
11 changes: 0 additions & 11 deletions packages/core/src/browser/preload/preloader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
// *****************************************************************************

import { Endpoint } from '../endpoint';
import { MaybePromise } from '../../common/types';
import { inject, injectable, interfaces, named } from 'inversify';
import { ContributionProvider } from '../../common/contribution-provider';
Expand All @@ -25,16 +24,6 @@ export interface PreloadContribution {
initialize(): MaybePromise<void>;
}

@injectable()
export abstract class AbstractPreloadContribution {

protected fetch(path: string): Promise<Response> {
const endpoint = new Endpoint({ path }).getRestUrl().toString();
return fetch(endpoint);
}

}

@injectable()
export class Preloader {

Expand Down
25 changes: 25 additions & 0 deletions packages/core/src/common/i18n/localization-server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// *****************************************************************************
// Copyright (C) 2023 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
// *****************************************************************************

import { Localization } from './localization';

export const LocalizationServerPath = '/localization-server';

export const LocalizationServer = Symbol('LocalizationServer');

export interface LocalizationServer {
loadLocalization(languageId: string): Promise<Localization>;
}
8 changes: 8 additions & 0 deletions packages/core/src/common/os.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,11 @@ export namespace OS {
};

}

export const OSBackendProviderPath = '/os';

export const OSBackendProvider = Symbol('OSBackendProvider');

export interface OSBackendProvider {
getBackendOS(): Promise<OS.Type>;
}
11 changes: 7 additions & 4 deletions packages/core/src/node/backend-application-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { ApplicationPackage } from '@theia/application-package';
import { REQUEST_SERVICE_PATH } from '@theia/request';
import {
bindContributionProvider, MessageService, MessageClient, ConnectionHandler, RpcConnectionHandler,
CommandService, commandServicePath, messageServicePath
CommandService, commandServicePath, messageServicePath, OSBackendProvider, OSBackendProviderPath
} from '../common';
import { BackendApplication, BackendApplicationContribution, BackendApplicationCliContribution, BackendApplicationServer } from './backend-application';
import { CliManager, CliContribution } from './cli';
Expand All @@ -38,7 +38,7 @@ import { EnvironmentUtils } from './environment-utils';
import { ProcessUtils } from './process-utils';
import { ProxyCliContribution } from './request/proxy-cli-contribution';
import { bindNodeStopwatch, bindBackendStopwatchServer } from './performance';
import { OSBackendApplicationContribution } from './os-backend-application-contribution';
import { OSBackendProviderImpl } from './os-backend-provider';
import { BackendRequestFacade } from './request/backend-request-facade';
import { FileSystemLocking, FileSystemLockingImpl } from './filesystem-locking';

Expand Down Expand Up @@ -116,8 +116,11 @@ export const backendApplicationModule = new ContainerModule(bind => {
bind(EnvironmentUtils).toSelf().inSingletonScope();
bind(ProcessUtils).toSelf().inSingletonScope();

bind(OSBackendApplicationContribution).toSelf().inSingletonScope();
bind(BackendApplicationContribution).toService(OSBackendApplicationContribution);
bind(OSBackendProviderImpl).toSelf().inSingletonScope();
bind(OSBackendProvider).toService(OSBackendProviderImpl);
bind(ConnectionHandler).toDynamicValue(
ctx => new RpcConnectionHandler(OSBackendProviderPath, () => ctx.container.get(OSBackendProvider))
).inSingletonScope();

bind(ProxyCliContribution).toSelf().inSingletonScope();
bind(CliContribution).toService(ProxyCliContribution);
Expand Down
13 changes: 9 additions & 4 deletions packages/core/src/node/i18n/i18n-backend-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@ import { localizationPath } from '../../common/i18n/localization';
import { LocalizationProvider } from './localization-provider';
import { ConnectionHandler, RpcConnectionHandler, bindContributionProvider } from '../../common';
import { LocalizationRegistry, LocalizationContribution } from './localization-contribution';
import { LocalizationBackendContribution } from './localization-backend-contribution';
import { BackendApplicationContribution } from '../backend-application';
import { LocalizationServerImpl } from './localization-server';
import { TheiaLocalizationContribution } from './theia-localization-contribution';
import { LocalizationServer, LocalizationServerPath } from '../../common/i18n/localization-server';
import { BackendApplicationContribution } from '../backend-application';

export default new ContainerModule(bind => {
bind(LocalizationProvider).toSelf().inSingletonScope();
Expand All @@ -30,8 +31,12 @@ export default new ContainerModule(bind => {
).inSingletonScope();
bind(LocalizationRegistry).toSelf().inSingletonScope();
bindContributionProvider(bind, LocalizationContribution);
bind(LocalizationBackendContribution).toSelf().inSingletonScope();
bind(BackendApplicationContribution).toService(LocalizationBackendContribution);
bind(LocalizationServerImpl).toSelf().inSingletonScope();
bind(LocalizationServer).toService(LocalizationServerImpl);
bind(BackendApplicationContribution).toService(LocalizationServerImpl);
bind(ConnectionHandler).toDynamicValue(ctx =>
new RpcConnectionHandler(LocalizationServerPath, () => ctx.container.get(LocalizationServer))
).inSingletonScope();
bind(TheiaLocalizationContribution).toSelf().inSingletonScope();
bind(LocalizationContribution).toService(TheiaLocalizationContribution);
});
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,18 @@
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
// *****************************************************************************

import * as express from 'express';
import { inject, injectable } from 'inversify';
import { Localization } from 'src/common/i18n/localization';
import { LocalizationServer } from '../../common/i18n/localization-server';
import { nls } from '../../common/nls';
import { Deferred } from '../../common/promise-util';
import { BackendApplicationContribution } from '../backend-application';
import { LocalizationRegistry } from './localization-contribution';
import { LocalizationProvider } from './localization-provider';

@injectable()
export class LocalizationBackendContribution implements BackendApplicationContribution {
export class LocalizationServerImpl implements LocalizationServer, BackendApplicationContribution {

protected readonly initialized = new Deferred<void>();

@inject(LocalizationRegistry)
Expand All @@ -41,13 +43,10 @@ export class LocalizationBackendContribution implements BackendApplicationContri
return this.initialized.promise;
}

configure(app: express.Application): void {
app.get('/i18n/:locale', async (req, res) => {
await this.waitForInitialization();
let locale = req.params.locale;
locale = this.localizationProvider.getAvailableLanguages().some(e => e.languageId === locale) ? locale : nls.defaultLocale;
this.localizationProvider.setCurrentLanguage(locale);
res.send(this.localizationProvider.loadLocalization(locale));
});
async loadLocalization(languageId: string): Promise<Localization> {
await this.waitForInitialization();
languageId = this.localizationProvider.getAvailableLanguages().some(e => e.languageId === languageId) ? languageId : nls.defaultLocale;
this.localizationProvider.setCurrentLanguage(languageId);
return this.localizationProvider.loadLocalization(languageId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,12 @@
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
// *****************************************************************************

import * as express from 'express';
import { injectable } from 'inversify';
import { BackendApplicationContribution } from './backend-application';
import { OS } from '../common/os';
import { OS, OSBackendProvider } from '../common/os';

@injectable()
export class OSBackendApplicationContribution implements BackendApplicationContribution {

configure(app: express.Application): void {
app.get('/os', (_, res) => {
res.send(OS.type());
});
export class OSBackendProviderImpl implements OSBackendProvider {
getBackendOS(): Promise<OS.Type> {
return Promise.resolve(OS.type());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ import { PluginTheiaEnvironment } from '../common/plugin-theia-environment';
import { PluginTheiaDeployerParticipant } from './plugin-theia-deployer-participant';
import { WebviewBackendSecurityWarnings } from './webview-backend-security-warnings';
import { PluginUninstallationManager } from './plugin-uninstallation-manager';
import { LocalizationBackendContribution } from '@theia/core/lib/node/i18n/localization-backend-contribution';
import { PluginLocalizationBackendContribution } from './plugin-localization-backend-contribution';
import { LocalizationServerImpl } from '@theia/core/lib/node/i18n/localization-server';
import { PluginLocalizationServer } from './plugin-localization-server';

export function bindMainBackend(bind: interfaces.Bind, unbind: interfaces.Unbind, isBound: interfaces.IsBound, rebind: interfaces.Rebind): void {
bind(PluginApiContribution).toSelf().inSingletonScope();
Expand Down Expand Up @@ -88,6 +88,6 @@ export function bindMainBackend(bind: interfaces.Bind, unbind: interfaces.Unbind
bind(WebviewBackendSecurityWarnings).toSelf().inSingletonScope();
bind(BackendApplicationContribution).toService(WebviewBackendSecurityWarnings);

rebind(LocalizationBackendContribution).to(PluginLocalizationBackendContribution).inSingletonScope();
rebind(LocalizationServerImpl).to(PluginLocalizationServer).inSingletonScope();

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@
// *****************************************************************************

import { inject, injectable } from '@theia/core/shared/inversify';
import { LocalizationBackendContribution } from '@theia/core/lib/node/i18n/localization-backend-contribution';
import { PluginDeployer } from '../../common/plugin-protocol';
import { PluginDeployerImpl } from './plugin-deployer-impl';
import { Deferred } from '@theia/core/lib/common/promise-util';
import { LocalizationServerImpl } from '@theia/core/lib/node/i18n/localization-server';

@injectable()
export class PluginLocalizationBackendContribution extends LocalizationBackendContribution {
export class PluginLocalizationServer extends LocalizationServerImpl {
@inject(PluginDeployer)
protected readonly pluginDeployer: PluginDeployerImpl;
protected readonly pluginsDeployed = new Deferred();
Expand Down

0 comments on commit 692ffa9

Please sign in to comment.