Skip to content

Commit 39be950

Browse files
committed
refactor: renderer
1 parent ddc2473 commit 39be950

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+829
-885
lines changed

packages/designer/src/models/document/document-model.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import { signal, uniqueId, ComponentTreeRoot } from '@alilc/lowcode-shared';
1+
import { Signals, uniqueId, ComponentTree } from '@alilc/lowcode-shared';
22
import { type Project } from '../project';
33
import { History } from './history';
44

5-
export interface DocumentSchema extends ComponentTreeRoot {
5+
export interface DocumentSchema extends ComponentTree {
66
id: string;
77
}
88

@@ -26,7 +26,7 @@ export interface DocumentModel {
2626

2727
export function createDocumentModel(project: Project) {
2828
const uid = uniqueId('doc');
29-
const currentDocumentSchema = signal<DocumentSchema>({});
29+
const currentDocumentSchema = Signals.signal<DocumentSchema>({});
3030

3131
const documentHistory = new History(currentDocumentSchema, () => {});
3232

packages/engine-core/src/index.ts

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,3 @@ export * from './configuration';
22
export * from './extension/extension';
33
export * from './resource';
44
export * from './command';
5-
6-
// test
7-
export * from './extension/registry';
8-
export * from './main';
9-
export * from './keybinding/keybindingRegistry';
10-
export * from './keybinding/keybindingParser';
11-
export * from './keybinding/keybindingResolver';
12-
export * from './keybinding/keybindings';
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import { createDecorator, Barrier } from '@alilc/lowcode-shared';
2+
3+
/**
4+
* 生命周期阶段
5+
*/
6+
export const enum LifecyclePhase {
7+
/**
8+
* 开始
9+
*/
10+
Starting = 1,
11+
/**
12+
* 已就绪
13+
*/
14+
Ready = 2,
15+
/**
16+
* 销毁中
17+
*/
18+
Destroying = 3,
19+
}
20+
21+
export interface ILifeCycleService {
22+
/**
23+
* A flag indicating in what phase of the lifecycle we currently are.
24+
*/
25+
phase: LifecyclePhase;
26+
27+
setPhase(phase: LifecyclePhase): void;
28+
29+
/**
30+
* Returns a promise that resolves when a certain lifecycle phase
31+
* has started.
32+
*/
33+
when(phase: LifecyclePhase): Promise<void>;
34+
35+
onWillDestory(): void;
36+
}
37+
38+
export const ILifeCycleService = createDecorator<ILifeCycleService>('lifeCycleService');
39+
40+
export class LifeCycleService implements ILifeCycleService {
41+
private readonly phaseWhen = new Map<LifecyclePhase, Barrier>();
42+
43+
private _phase = LifecyclePhase.Starting;
44+
45+
get phase(): LifecyclePhase {
46+
return this._phase;
47+
}
48+
49+
setPhase(value: LifecyclePhase) {
50+
if (value < this._phase) {
51+
throw new Error('Lifecycle cannot go backwards');
52+
}
53+
54+
if (this._phase === value) {
55+
return;
56+
}
57+
58+
this._phase = value;
59+
60+
const barrier = this.phaseWhen.get(this._phase);
61+
if (barrier) {
62+
barrier.open();
63+
this.phaseWhen.delete(this._phase);
64+
}
65+
}
66+
67+
async when(phase: LifecyclePhase): Promise<void> {
68+
if (phase <= this._phase) {
69+
return;
70+
}
71+
72+
let barrier = this.phaseWhen.get(phase);
73+
if (!barrier) {
74+
barrier = new Barrier();
75+
this.phaseWhen.set(phase, barrier);
76+
}
77+
78+
await barrier.wait();
79+
}
80+
81+
onWillDestory(): void {}
82+
}

packages/engine-core/src/main.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,31 @@
11
import { InstantiationService } from '@alilc/lowcode-shared';
22
import { IWorkbenchService } from './workbench';
3-
import { IConfigurationService } from './configuration';
3+
import { ConfigurationService, IConfigurationService } from './configuration';
44

5-
class MainApplication {
5+
class TestMainApplication {
66
constructor() {
77
console.log('main application');
88
}
99

1010
async main() {
11-
const instantiationService = new InstantiationService();
12-
const configurationService = instantiationService.get(IConfigurationService);
1311
const workbench = instantiationService.get(IWorkbenchService);
1412

1513
await configurationService.initialize();
1614
workbench.initialize();
1715
}
16+
17+
createServices() {
18+
const instantiationService = new InstantiationService();
19+
20+
const configurationService = new ConfigurationService();
21+
instantiationService.container.set(IConfigurationService, configurationService);
22+
}
23+
24+
initServices() {}
1825
}
1926

20-
export async function createLowCodeEngineApp(): Promise<MainApplication> {
21-
const app = new MainApplication();
27+
export async function createLowCodeEngineApp() {
28+
const app = new TestMainApplication();
2229

2330
await app.main();
2431

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export interface ITheme {
2+
type: string;
3+
4+
value: string;
5+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { Disposable, Events, type IDisposable, createDecorator } from '@alilc/lowcode-shared';
2+
import { type ITheme } from './theme';
3+
4+
export interface IThemeService extends IDisposable {
5+
getTheme(): ITheme;
6+
7+
onDidColorThemeChange: Events.Event<ITheme>;
8+
}
9+
10+
export const IThemeService = createDecorator<IThemeService>('themeService');
11+
12+
export class ThemeService extends Disposable implements IThemeService {
13+
private _activeTheme: ITheme;
14+
15+
private _onDidColorThemeChange = this._addDispose(new Events.Emitter<ITheme>());
16+
onDidColorThemeChange = this._onDidColorThemeChange.event;
17+
18+
getTheme(): ITheme {
19+
return this._activeTheme;
20+
}
21+
}

packages/engine/src/main.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { InstantiationService } from '@alilc/lowcode-shared';
2-
import { IConfigurationService, IWorkspaceService } from '@alilc/lowcode-engine-core';
2+
import { IConfigurationService } from '@alilc/lowcode-engine-core';
33

44
export class MainEngineApplication {
55
instantiationService = new InstantiationService();

packages/engine/src/themeService.ts

Lines changed: 0 additions & 27 deletions
This file was deleted.
Lines changed: 5 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,9 @@
1-
import { createRenderer } from '@alilc/lowcode-renderer-core';
2-
import { type Root, createRoot } from 'react-dom/client';
3-
import { type IRendererContext, RendererContext, getRenderInstancesByAccessor } from './context';
4-
import { ApplicationView, boosts } from '../app';
5-
import { type ReactAppOptions } from './types';
1+
import { App, type AppOptions } from '../app';
62

7-
export const createApp = async (options: ReactAppOptions) => {
8-
return createRenderer(async (service) => {
9-
const contextValue: IRendererContext = service.invokeFunction((accessor) => {
10-
return {
11-
options,
12-
...getRenderInstancesByAccessor(accessor),
13-
};
14-
});
3+
export const createApp = async (options: AppOptions) => {
4+
const app = new App(options);
155

16-
contextValue.boostsManager.extend(boosts.toExpose());
6+
await app.startup();
177

18-
let root: Root | undefined;
19-
20-
return {
21-
async mount(containerOrId) {
22-
if (root) return;
23-
24-
const defaultId = contextValue.schema.get<string>('config.targetRootID', 'app');
25-
const rootElement = normalizeContainer(containerOrId, defaultId);
26-
27-
root = createRoot(rootElement);
28-
root.render(
29-
<RendererContext.Provider value={contextValue}>
30-
<ApplicationView />
31-
</RendererContext.Provider>,
32-
);
33-
},
34-
unmount() {
35-
if (root) {
36-
root.unmount();
37-
root = undefined;
38-
}
39-
},
40-
};
41-
})(options);
8+
return app;
429
};
43-
44-
function normalizeContainer(container: Element | string | undefined, defaultId: string): Element {
45-
let result: Element | undefined = undefined;
46-
47-
if (typeof container === 'string') {
48-
const el = document.getElementById(container);
49-
if (el) result = el;
50-
} else if (container instanceof window.Element) {
51-
result = container;
52-
}
53-
54-
if (!result) {
55-
result = document.createElement('div');
56-
result.id = defaultId;
57-
}
58-
59-
return result;
60-
}
Lines changed: 30 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,38 @@
1-
import { createRenderer } from '@alilc/lowcode-renderer-core';
2-
import { type ComponentTreeRoot } from '@alilc/lowcode-shared';
3-
import { type FunctionComponent } from 'react';
1+
import { type StringDictionary, type ComponentTree } from '@alilc/lowcode-shared';
2+
import { CodeRuntime } from '@alilc/lowcode-renderer-core';
3+
import { FunctionComponent, ComponentType } from 'react';
44
import {
55
type LowCodeComponentProps,
66
createComponent as createSchemaComponent,
7-
} from '../runtime/createComponent';
8-
import { type IRendererContext, RendererContext, getRenderInstancesByAccessor } from './context';
9-
import { type ReactAppOptions } from './types';
10-
11-
interface Render {
12-
toComponent(): FunctionComponent<LowCodeComponentProps>;
7+
type ComponentOptions as SchemaComponentOptions,
8+
reactiveStateFactory,
9+
} from '../runtime';
10+
import { type ComponentsAccessor } from '../app';
11+
12+
export interface ComponentOptions extends SchemaComponentOptions {
13+
schema: ComponentTree;
14+
componentsRecord: Record<string, ComponentType>;
15+
codeScope?: StringDictionary;
1316
}
1417

15-
export async function createComponent(options: ReactAppOptions) {
16-
const creator = createRenderer<Render>((service) => {
17-
const contextValue: IRendererContext = service.invokeFunction((accessor) => {
18-
return {
19-
options,
20-
...getRenderInstancesByAccessor(accessor),
21-
};
22-
});
23-
24-
const componentsTree = contextValue.schema.get<ComponentTreeRoot>('componentsTree.0');
25-
26-
if (!componentsTree) {
27-
throw new Error('componentsTree is required');
28-
}
29-
30-
const LowCodeComponent = createSchemaComponent(componentsTree, {
31-
displayName: componentsTree.componentName,
32-
...options.component,
33-
});
34-
35-
function Component(props: LowCodeComponentProps) {
36-
return (
37-
<RendererContext.Provider value={contextValue}>
38-
<LowCodeComponent {...props} />
39-
</RendererContext.Provider>
40-
);
41-
}
42-
43-
return {
44-
toComponent() {
45-
return Component;
46-
},
47-
};
18+
export function createComponent(
19+
options: ComponentOptions,
20+
): FunctionComponent<LowCodeComponentProps> {
21+
const { schema, componentsRecord, modelOptions, codeScope, ...componentOptions } = options;
22+
const codeRuntime = new CodeRuntime(codeScope);
23+
const components: ComponentsAccessor = {
24+
getComponent(componentName) {
25+
return componentsRecord[componentName] as any;
26+
},
27+
};
28+
29+
const LowCodeComponent = createSchemaComponent(schema, codeRuntime, components, {
30+
...componentOptions,
31+
modelOptions: {
32+
...modelOptions,
33+
stateCreator: modelOptions.stateCreator ?? reactiveStateFactory,
34+
},
4835
});
4936

50-
const render = await creator(options);
51-
52-
return render.toComponent();
37+
return LowCodeComponent;
5338
}

0 commit comments

Comments
 (0)