Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: create instanceService #733

Merged
merged 14 commits into from
Jun 7, 2022
Merged
Next Next commit
feat: create instanceService
  • Loading branch information
mortalYoung committed May 10, 2022
commit 0da9e618e7f973cf64631f833496afdcffd68d45
10 changes: 5 additions & 5 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import * as molecule from './molecule.api';
import * as moleculeAPI from './molecule.api';

export { MoleculeProvider } from 'mo/provider';
export type { IMoleculeProps } from 'mo/provider';
import { molecule } from './provider/create';

export { Workbench } from 'mo/workbench/workbench';
export { molecule };
export { create } from 'mo/provider';

export default molecule;
// TODO: put API into moleucle temporarily, should consider it
export default Object.assign(molecule, moleculeAPI);
95 changes: 0 additions & 95 deletions src/molecule.api.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
import 'reflect-metadata';
import { container } from 'tsyringe';

export * as event from 'mo/common/event';
export * as react from 'mo/react';
export * as component from 'mo/components';
Expand All @@ -11,95 +8,3 @@ export * from 'mo/workbench';
export * from 'mo/services';

export * as model from 'mo/model';

import {
ILayoutService,
LayoutService,
ActivityBarService,
IActivityBarService,
ExplorerService,
IExplorerService,
FolderTreeService,
IFolderTreeService,
SearchService,
ISearchService,
ISidebarService,
SidebarService,
IMenuBarService,
MenuBarService,
IStatusBarService,
StatusBarService,
EditorService,
IEditorService,
IPanelService,
PanelService,
INotificationService,
NotificationService,
IColorThemeService,
ColorThemeService,
ISettingsService,
SettingsService,
IProblemsService,
ProblemsService,
IEditorTreeService,
EditorTreeService,
BuiltinService,
ExtensionService,
IExtensionService,
} from 'mo/services';

import { ILocaleService, LocaleService } from 'mo/i18n';

/**
* The locale service
*/
export const i18n = container.resolve<ILocaleService>(LocaleService);

/**
* The layout service
*/
export const layout = container.resolve<ILayoutService>(LayoutService);

/**
* The activityBar service
*/
export const activityBar: IActivityBarService =
container.resolve<IActivityBarService>(ActivityBarService);

export const explorer: IExplorerService =
container.resolve<IExplorerService>(ExplorerService);

export const folderTree: IFolderTreeService =
container.resolve<IFolderTreeService>(FolderTreeService);

export const editorTree =
container.resolve<IEditorTreeService>(EditorTreeService);

export const search = container.resolve<ISearchService>(SearchService);
export const sidebar = container.resolve<ISidebarService>(SidebarService);
export const menuBar = container.resolve<IMenuBarService>(MenuBarService);
export const editor = container.resolve<IEditorService>(EditorService);
export const statusBar = container.resolve<IStatusBarService>(StatusBarService);
export const panel = container.resolve<IPanelService>(PanelService);
export const notification =
container.resolve<INotificationService>(NotificationService);

export const problems = container.resolve<IProblemsService>(ProblemsService);

/**
* The ColorTheme service
*/
export const colorTheme =
container.resolve<IColorThemeService>(ColorThemeService);

/**
* The Settings service
*/
export const settings = container.resolve<ISettingsService>(SettingsService);

export const builtin = container.resolve(BuiltinService);

/**
* The Extension service
*/
export const extension = container.resolve<IExtensionService>(ExtensionService);
167 changes: 167 additions & 0 deletions src/provider/create.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
import { ILocaleService, LocaleService } from 'mo/i18n';
import { IExtension } from 'mo/model';
import { IMonacoService, MonacoService } from 'mo/monaco/monacoService';
import {
ActivityBarService,
BuiltinService,
ColorThemeService,
EditorService,
EditorTreeService,
ExplorerService,
ExtensionService,
FolderTreeService,
IActivityBarService,
IBuiltinService,
IColorThemeService,
IEditorService,
IEditorTreeService,
IExplorerService,
IExtensionService,
IFolderTreeService,
ILayoutService,
IMenuBarService,
INotificationService,
IPanelService,
IProblemsService,
ISearchService,
ISettingsService,
ISidebarService,
IStatusBarService,
LayoutService,
MenuBarService,
NotificationService,
PanelService,
ProblemsService,
SearchService,
SettingsService,
SidebarService,
StatusBarService,
} from 'mo/services';
import InstanceService from 'mo/services/instanceService';
import { container, InjectionToken } from 'tsyringe';

export interface IConfigProps {
/**
* Molecule Extension instances, after the MoleculeProvider
* did mount, then handle it.
*/
extensions?: IExtension[];
/**
* Specify a default locale Id, the Molecule built-in `zh-CN`, `en` two languages, and
* default locale Id is `en`.
*/
defaultLocale?: string;
}

enum ServiceUuidKind {
monacoService = 'monacoService',
layout = 'layout',
i18n = 'i18n',
activityBar = 'activityBar',
explorer = 'explorer',
folderTree = 'folderTree',
editorTree = 'editorTree',
search = 'search',
sidebar = 'sidebar',
menuBar = 'menuBar',
editor = 'editor',
statusBar = 'statusBar',
panel = 'panel',
notification = 'notification',
problems = 'problems',
colorTheme = 'colorTheme',
settings = 'settings',
builtin = 'builtin',
extension = 'extension',
}

export type IServiceCollection = {
[ServiceUuidKind.monacoService]: IMonacoService;
[ServiceUuidKind.layout]: ILayoutService;
[ServiceUuidKind.i18n]: ILocaleService;
[ServiceUuidKind.activityBar]: IActivityBarService;
[ServiceUuidKind.explorer]: IExplorerService;
[ServiceUuidKind.folderTree]: IFolderTreeService;
[ServiceUuidKind.editorTree]: IEditorTreeService;
[ServiceUuidKind.search]: ISearchService;
[ServiceUuidKind.sidebar]: ISidebarService;
[ServiceUuidKind.menuBar]: IMenuBarService;
[ServiceUuidKind.editor]: IEditorService;
[ServiceUuidKind.statusBar]: IStatusBarService;
[ServiceUuidKind.panel]: IPanelService;
[ServiceUuidKind.notification]: INotificationService;
[ServiceUuidKind.problems]: IProblemsService;
[ServiceUuidKind.colorTheme]: IColorThemeService;
[ServiceUuidKind.settings]: ISettingsService;
[ServiceUuidKind.builtin]: IBuiltinService;
[ServiceUuidKind.extension]: IExtensionService;
};

namespace stanalone {
let instance: InstanceService | null = null;

// used for internal
const _services = <any>{};
// used for user
export const molecule: Partial<IServiceCollection> = {};

function registerService<T extends IServiceCollection[ServiceUuidKind]>(
Service: InjectionToken<T>,
uuid: ServiceUuidKind
) {
const service = container.resolve<T>(Service);
_services[uuid] = service;

molecule[uuid] = new Proxy(<any>{}, {
get: function (_, prop) {
if (!instance) {
console.warn(
new Error(
"Don't call service's methods before initialize the instance"
)
);
return () => {};
}

return service[prop];
},
});
}

registerService(MonacoService, ServiceUuidKind.monacoService);
registerService(LayoutService, ServiceUuidKind.layout);
registerService(LocaleService, ServiceUuidKind.i18n);
registerService(ActivityBarService, ServiceUuidKind.activityBar);
registerService(ExplorerService, ServiceUuidKind.explorer);
registerService(FolderTreeService, ServiceUuidKind.folderTree);
registerService(EditorTreeService, ServiceUuidKind.editorTree);
registerService(SearchService, ServiceUuidKind.search);
registerService(SidebarService, ServiceUuidKind.sidebar);
registerService(MenuBarService, ServiceUuidKind.menuBar);
registerService(EditorService, ServiceUuidKind.editor);
registerService(StatusBarService, ServiceUuidKind.statusBar);
registerService(PanelService, ServiceUuidKind.panel);
registerService(NotificationService, ServiceUuidKind.notification);
registerService(ProblemsService, ServiceUuidKind.problems);
registerService(ColorThemeService, ServiceUuidKind.colorTheme);
registerService(SettingsService, ServiceUuidKind.settings);
registerService(BuiltinService, ServiceUuidKind.builtin);
registerService(ExtensionService, ServiceUuidKind.extension);

/**
* Create an instance
*/
export function create(config: IConfigProps) {
if (instance) {
return instance;
}
instance = new InstanceService(config, _services);
return instance;
}
}

export default function create(config: IConfigProps) {
return stanalone.create(config);
}

export const molecule = <IServiceCollection>stanalone.molecule;
2 changes: 2 additions & 0 deletions src/provider/index.tsx
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
export * from 'mo/provider/molecule';

export { default as create } from './create';
66 changes: 66 additions & 0 deletions src/services/instanceService.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { ILocaleService } from 'mo/i18n';
import { container } from 'tsyringe';
import * as controllers from 'mo/controller';
import type { Controller } from 'mo/react';
import { defaultExtensions } from 'mo/extensions';
import { GlobalEvent } from 'mo/common/event';
import { IConfigProps, IServiceCollection } from 'mo/provider/create';
import { ReactNode } from 'react';

interface IInstanceServiceProps {
render: (dom: any) => void;
onBeforeInit: (callback: () => void) => void;
}

enum InstanceHookKind {
beforeInit = 'before.init',
}

export default class InstanceService
extends GlobalEvent
implements IInstanceServiceProps
{
private _services: IServiceCollection;
private _config = {
extensions: defaultExtensions,
defaultLocale: 'en',
};

constructor(config: IConfigProps, services: IServiceCollection) {
super();
this._services = services;

if (config.defaultLocale) {
const localeService: ILocaleService = this._services.i18n;
localeService.setCurrentLocale(config.defaultLocale);

this._config.defaultLocale = config.defaultLocale;
}

if (Array.isArray(config.extensions)) {
this._config.extensions.push(...config.extensions);
}
}

public render = (workbench: ReactNode) => {
this.emit(InstanceHookKind.beforeInit);

Object.keys(controllers).forEach((key) => {
const module = controllers[key];
const controller = container.resolve<Controller>(module);
controller.initView?.();
});

this._services.extension.load(this._config.extensions);

this._services.monacoService.initWorkspace(
this._services.layout.container!
);

return workbench;
};

public onBeforeInit = (callback: () => void) => {
this.subscribe(InstanceHookKind.beforeInit, callback);
};
}
16 changes: 10 additions & 6 deletions stories/workbench/0-Workbench.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import React from 'react';
import { MoleculeProvider, Workbench } from 'mo';
import molecule, { create, Workbench } from 'mo';
import 'mo/style/mo.scss';
import { customExtensions } from '../extensions';
import '../demo.scss';

export const IDEDemo = () => (
<MoleculeProvider extensions={customExtensions} defaultLocale="en">
<Workbench />
</MoleculeProvider>
);
// this line will console.warn a tip
console.log('molecule:', molecule.editor.isOpened(1));

const moInstance = create({
extensions: customExtensions,
defaultLocale: 'en',
});

export const IDEDemo = () => moInstance.render(<Workbench />);

IDEDemo.story = {
name: 'Workbench',
Expand Down