mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2025-12-14 04:43:14 +00:00
refactor: change render core export api
This commit is contained in:
parent
c1356bfe70
commit
9d0f178a06
11
packages/engine-core/src/common/uri.ts
Normal file
11
packages/engine-core/src/common/uri.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
export interface UriComponents {
|
||||||
|
path: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class URI implements UriComponents {
|
||||||
|
readonly path: string;
|
||||||
|
|
||||||
|
constructor(path: string) {
|
||||||
|
this.path = path;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -100,7 +100,9 @@ export interface IConfigurationPropertySchema extends IJSONSchema {
|
|||||||
* 扩展信息,用来查找对应属性的源扩展
|
* 扩展信息,用来查找对应属性的源扩展
|
||||||
*/
|
*/
|
||||||
export interface IExtensionInfo {
|
export interface IExtensionInfo {
|
||||||
name: string;
|
id: string;
|
||||||
|
displayName?: string;
|
||||||
|
version?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ConfigurationDefaultValueSource = IExtensionInfo | Map<string, IExtensionInfo>;
|
export type ConfigurationDefaultValueSource = IExtensionInfo | Map<string, IExtensionInfo>;
|
||||||
@ -640,7 +642,7 @@ export class ConfigurationRegistry implements IConfigurationRegistry {
|
|||||||
|
|
||||||
function isSameExtension(a?: IExtensionInfo, b?: IExtensionInfo): boolean {
|
function isSameExtension(a?: IExtensionInfo, b?: IExtensionInfo): boolean {
|
||||||
if (!a || !b) return false;
|
if (!a || !b) return false;
|
||||||
return a.name === b.name;
|
return a.id === b.id && a.version === b.version;
|
||||||
}
|
}
|
||||||
|
|
||||||
Registry.add(Extensions.Configuration, new ConfigurationRegistry());
|
Registry.add(Extensions.Configuration, new ConfigurationRegistry());
|
||||||
|
|||||||
@ -7,9 +7,10 @@ export type ExtensionInitializer = <Context = any>(ctx: Context) => IExtensionIn
|
|||||||
* 函数声明插件
|
* 函数声明插件
|
||||||
*/
|
*/
|
||||||
export interface IFunctionExtension extends ExtensionInitializer {
|
export interface IFunctionExtension extends ExtensionInitializer {
|
||||||
name: string;
|
id: string;
|
||||||
|
displayName?: string;
|
||||||
version: string;
|
version: string;
|
||||||
meta?: IExtensionMetadata;
|
metadata?: IExtensionMetadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IExtensionMetadata {
|
export interface IExtensionMetadata {
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import { InstantiationService } from '@alilc/lowcode-shared';
|
|||||||
import { IWorkbenchService } from './workbench';
|
import { IWorkbenchService } from './workbench';
|
||||||
import { IConfigurationService } from './configuration';
|
import { IConfigurationService } from './configuration';
|
||||||
|
|
||||||
export class MainApplication {
|
class MainApplication {
|
||||||
constructor() {
|
constructor() {
|
||||||
console.log('main application');
|
console.log('main application');
|
||||||
}
|
}
|
||||||
|
|||||||
140
packages/engine-core/src/workspace/file/file.ts
Normal file
140
packages/engine-core/src/workspace/file/file.ts
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
import { URI } from '../../common/uri';
|
||||||
|
|
||||||
|
export enum FileType {
|
||||||
|
/**
|
||||||
|
* File is unknown (neither file, directory).
|
||||||
|
*/
|
||||||
|
Unknown = 0,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* File is a normal file.
|
||||||
|
*/
|
||||||
|
File = 1,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* File is a directory.
|
||||||
|
*/
|
||||||
|
Directory = 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IStat {
|
||||||
|
/**
|
||||||
|
* The file type.
|
||||||
|
*/
|
||||||
|
readonly type: FileType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The last modification date represented as millis from unix epoch.
|
||||||
|
*/
|
||||||
|
readonly mtime: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The creation date represented as millis from unix epoch.
|
||||||
|
*/
|
||||||
|
readonly ctime: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IBaseFileStat {
|
||||||
|
/**
|
||||||
|
* The unified resource identifier of this file or folder.
|
||||||
|
*/
|
||||||
|
readonly resource: URI;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name which is the last segment
|
||||||
|
* of the {{path}}.
|
||||||
|
*/
|
||||||
|
readonly name: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The size of the file.
|
||||||
|
*
|
||||||
|
* The value may or may not be resolved as
|
||||||
|
* it is optional.
|
||||||
|
*/
|
||||||
|
readonly size?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The last modification date represented as millis from unix epoch.
|
||||||
|
*
|
||||||
|
* The value may or may not be resolved as
|
||||||
|
* it is optional.
|
||||||
|
*/
|
||||||
|
readonly mtime?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The creation date represented as millis from unix epoch.
|
||||||
|
*
|
||||||
|
* The value may or may not be resolved as
|
||||||
|
* it is optional.
|
||||||
|
*/
|
||||||
|
readonly ctime?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A unique identifier that represents the
|
||||||
|
* current state of the file or directory.
|
||||||
|
*
|
||||||
|
* The value may or may not be resolved as
|
||||||
|
* it is optional.
|
||||||
|
*/
|
||||||
|
readonly etag?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* File is readonly. Components like editors should not
|
||||||
|
* offer to edit the contents.
|
||||||
|
*/
|
||||||
|
readonly readonly?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* File is locked. Components like editors should offer
|
||||||
|
* to edit the contents and ask the user upon saving to
|
||||||
|
* remove the lock.
|
||||||
|
*/
|
||||||
|
readonly locked?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A file resource with meta information and resolved children if any.
|
||||||
|
*/
|
||||||
|
export interface IFileStat extends IBaseFileStat {
|
||||||
|
/**
|
||||||
|
* The resource is a file.
|
||||||
|
*/
|
||||||
|
readonly isFile: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The resource is a directory.
|
||||||
|
*/
|
||||||
|
readonly isDirectory: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The children of the file stat or undefined if none.
|
||||||
|
*/
|
||||||
|
children: IFileStat[] | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IFileStatWithMetadata extends Required<IFileStat> {
|
||||||
|
readonly children: IFileStatWithMetadata[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export const enum FileOperation {
|
||||||
|
CREATE,
|
||||||
|
DELETE,
|
||||||
|
MOVE,
|
||||||
|
COPY,
|
||||||
|
WRITE,
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IFileOperationEvent {
|
||||||
|
readonly resource: URI;
|
||||||
|
readonly operation: FileOperation;
|
||||||
|
|
||||||
|
isOperation(operation: FileOperation.DELETE | FileOperation.WRITE): boolean;
|
||||||
|
isOperation(
|
||||||
|
operation: FileOperation.CREATE | FileOperation.MOVE | FileOperation.COPY,
|
||||||
|
): this is IFileOperationEventWithMetadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IFileOperationEventWithMetadata extends IFileOperationEvent {
|
||||||
|
readonly target: IFileStatWithMetadata;
|
||||||
|
}
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
/**
|
||||||
|
* URI -> file content
|
||||||
|
* URI -> file Stat
|
||||||
|
*/
|
||||||
|
|
||||||
|
export interface IFileManagement {}
|
||||||
1
packages/engine-core/src/workspace/file/fileService.ts
Normal file
1
packages/engine-core/src/workspace/file/fileService.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export interface IFileService {}
|
||||||
26
packages/engine-core/src/workspace/folder.ts
Normal file
26
packages/engine-core/src/workspace/folder.ts
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import { URI } from '../common/uri';
|
||||||
|
|
||||||
|
export interface IWorkspaceFolderData {
|
||||||
|
/**
|
||||||
|
* The associated URI for this workspace folder.
|
||||||
|
*/
|
||||||
|
readonly uri: URI;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of this workspace folder. Defaults to
|
||||||
|
* the basename of its [uri-path](#Uri.path)
|
||||||
|
*/
|
||||||
|
readonly name: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The ordinal number of this workspace folder.
|
||||||
|
*/
|
||||||
|
readonly index: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IWorkspaceFolder extends IWorkspaceFolderData {
|
||||||
|
/**
|
||||||
|
* Given workspace folder relative path, returns the resource with the absolute path.
|
||||||
|
*/
|
||||||
|
toResource: (relativePath: string) => URI;
|
||||||
|
}
|
||||||
82
packages/engine-core/src/workspace/window/window.ts
Normal file
82
packages/engine-core/src/workspace/window/window.ts
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
import { type Event } from '@alilc/lowcode-shared';
|
||||||
|
import { URI } from '../../common/uri';
|
||||||
|
|
||||||
|
export interface IEditWindow {
|
||||||
|
// readonly onWillLoad: Event<ILoadEvent>;
|
||||||
|
readonly onDidSignalReady: Event<void>;
|
||||||
|
readonly onDidDestroy: Event<void>;
|
||||||
|
|
||||||
|
readonly onDidClose: Event<void>;
|
||||||
|
|
||||||
|
readonly id: number;
|
||||||
|
|
||||||
|
readonly config: IWindowConfiguration | undefined;
|
||||||
|
|
||||||
|
readonly isReady: boolean;
|
||||||
|
ready(): Promise<IEditWindow>;
|
||||||
|
|
||||||
|
load(config: IWindowConfiguration, options?: { isReload?: boolean }): void;
|
||||||
|
reload(): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IWindowConfiguration {
|
||||||
|
filesToOpenOrCreate?: IPath[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IPath<T = any> {
|
||||||
|
/**
|
||||||
|
* Optional editor options to apply in the file
|
||||||
|
*/
|
||||||
|
readonly options?: T;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The file path to open within the instance
|
||||||
|
*/
|
||||||
|
fileUri?: URI;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies if the file should be only be opened
|
||||||
|
* if it exists.
|
||||||
|
*/
|
||||||
|
readonly openOnlyIfExists?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const enum WindowMode {
|
||||||
|
Maximized,
|
||||||
|
Normal,
|
||||||
|
Fullscreen,
|
||||||
|
Custom,
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IWindowState {
|
||||||
|
width?: number;
|
||||||
|
height?: number;
|
||||||
|
x?: number;
|
||||||
|
y?: number;
|
||||||
|
mode?: WindowMode;
|
||||||
|
zoomLevel?: number;
|
||||||
|
readonly display?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IOpenConfiguration {
|
||||||
|
readonly urisToOpen?: IWindowOpenable[];
|
||||||
|
readonly preferNewWindow?: boolean;
|
||||||
|
readonly forceNewWindow?: boolean;
|
||||||
|
readonly forceNewTabbedWindow?: boolean;
|
||||||
|
readonly forceReuseWindow?: boolean;
|
||||||
|
readonly forceEmpty?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IBaseWindowOpenable {
|
||||||
|
label?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IFolderToOpen extends IBaseWindowOpenable {
|
||||||
|
readonly folderUri: URI;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IFileToOpen extends IBaseWindowOpenable {
|
||||||
|
readonly fileUri: URI;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type IWindowOpenable = IFolderToOpen | IFileToOpen;
|
||||||
@ -0,0 +1,43 @@
|
|||||||
|
import { type Event } from '@alilc/lowcode-shared';
|
||||||
|
import { IEditWindow, IOpenConfiguration } from './window';
|
||||||
|
|
||||||
|
export interface IWindowService {
|
||||||
|
readonly onDidOpenWindow: Event<IEditWindow>;
|
||||||
|
readonly onDidSignalReadyWindow: Event<IEditWindow>;
|
||||||
|
readonly onDidChangeFullScreen: Event<{ window: IEditWindow; fullscreen: boolean }>;
|
||||||
|
readonly onDidDestroyWindow: Event<IEditWindow>;
|
||||||
|
|
||||||
|
open(openConfig: IOpenConfiguration): Promise<IEditWindow[]>;
|
||||||
|
|
||||||
|
sendToFocused(channel: string, ...args: any[]): void;
|
||||||
|
sendToOpeningWindow(channel: string, ...args: any[]): void;
|
||||||
|
sendToAll(channel: string, payload?: any, windowIdsToIgnore?: number[]): void;
|
||||||
|
|
||||||
|
getWindows(): IEditWindow[];
|
||||||
|
getWindowCount(): number;
|
||||||
|
|
||||||
|
getFocusedWindow(): IEditWindow | undefined;
|
||||||
|
getLastActiveWindow(): IEditWindow | undefined;
|
||||||
|
|
||||||
|
getWindowById(windowId: number): IEditWindow | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class WindowService implements IWindowService {
|
||||||
|
private readonly windows = new Map<number, IEditWindow>();
|
||||||
|
|
||||||
|
getWindows(): IEditWindow[] {
|
||||||
|
return [...this.windows.values()];
|
||||||
|
}
|
||||||
|
|
||||||
|
getWindowCount(): number {
|
||||||
|
return this.windows.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
getFocusedWindow(): IEditWindow | undefined {
|
||||||
|
return this.getWindows().find((w) => w.focused);
|
||||||
|
}
|
||||||
|
|
||||||
|
getLastActiveWindow(): IEditWindow | undefined {
|
||||||
|
return this.getWindows().find((w) => w.lastActive);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,4 +1,31 @@
|
|||||||
|
import { IWorkspaceFolder } from './folder';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 工作空间:一个或多个项目的集合
|
* workspace -> one or more folders -> virtual files
|
||||||
|
* file -> editWindow
|
||||||
|
* editorView -> component tree schema
|
||||||
|
*
|
||||||
|
* project = (one or muti folders -> files) + some configs
|
||||||
*/
|
*/
|
||||||
export interface Workspace {}
|
export interface IWorkspace {
|
||||||
|
readonly id: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Folders in the workspace.
|
||||||
|
*/
|
||||||
|
readonly folders: IWorkspaceFolder[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Workspace implements IWorkspace {
|
||||||
|
private _folders: IWorkspaceFolder[] = [];
|
||||||
|
|
||||||
|
constructor(private _id: string) {}
|
||||||
|
|
||||||
|
get id() {
|
||||||
|
return this._id;
|
||||||
|
}
|
||||||
|
|
||||||
|
get folders() {
|
||||||
|
return this._folders;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -1,12 +1,8 @@
|
|||||||
import { createDecorator, Provide } from '@alilc/lowcode-shared';
|
import { createDecorator, Provide } from '@alilc/lowcode-shared';
|
||||||
|
|
||||||
export interface IWorkspaceService {
|
export interface IWorkspaceService {}
|
||||||
mount(container: HTMLElement): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const IWorkspaceService = createDecorator<IWorkspaceService>('workspaceService');
|
export const IWorkspaceService = createDecorator<IWorkspaceService>('workspaceService');
|
||||||
|
|
||||||
@Provide(IWorkspaceService)
|
@Provide(IWorkspaceService)
|
||||||
export class WorkspaceService implements IWorkspaceService {
|
export class WorkspaceService implements IWorkspaceService {}
|
||||||
mount(container: HTMLElement): void {}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -1,14 +1,14 @@
|
|||||||
import { createRenderer } from '@alilc/lowcode-renderer-core';
|
import { createRenderer } from '@alilc/lowcode-renderer-core';
|
||||||
import { type Root, createRoot } from 'react-dom/client';
|
import { type Root, createRoot } from 'react-dom/client';
|
||||||
import { RendererContext } from './context';
|
import { RendererContext, getRenderInstancesByAccessor } from './context';
|
||||||
import { ApplicationView, boosts } from '../app';
|
import { ApplicationView, boosts } from '../app';
|
||||||
import { type ReactAppOptions } from './types';
|
import { type ReactAppOptions } from './types';
|
||||||
|
|
||||||
export const createApp = async (options: ReactAppOptions) => {
|
export const createApp = async (options: ReactAppOptions) => {
|
||||||
return createRenderer(async (context) => {
|
return createRenderer(async (accessor) => {
|
||||||
const { schema, boostsManager } = context;
|
const instances = getRenderInstancesByAccessor(accessor);
|
||||||
|
|
||||||
boostsManager.extend(boosts.toExpose());
|
instances.boostsManager.extend(boosts.toExpose());
|
||||||
|
|
||||||
let root: Root | undefined;
|
let root: Root | undefined;
|
||||||
|
|
||||||
@ -16,9 +16,9 @@ export const createApp = async (options: ReactAppOptions) => {
|
|||||||
async mount(containerOrId) {
|
async mount(containerOrId) {
|
||||||
if (root) return;
|
if (root) return;
|
||||||
|
|
||||||
const defaultId = schema.get('config')?.targetRootID ?? 'app';
|
const defaultId = instances.schema.get('config')?.targetRootID ?? 'app';
|
||||||
const rootElement = normalizeContainer(containerOrId, defaultId);
|
const rootElement = normalizeContainer(containerOrId, defaultId);
|
||||||
const contextValue = { ...context, options };
|
const contextValue = { ...instances, options };
|
||||||
|
|
||||||
root = createRoot(rootElement);
|
root = createRoot(rootElement);
|
||||||
root.render(
|
root.render(
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import {
|
|||||||
type LowCodeComponentProps,
|
type LowCodeComponentProps,
|
||||||
createComponent as createSchemaComponent,
|
createComponent as createSchemaComponent,
|
||||||
} from '../runtime/createComponent';
|
} from '../runtime/createComponent';
|
||||||
import { RendererContext } from './context';
|
import { RendererContext, getRenderInstancesByAccessor } from './context';
|
||||||
import { type ReactAppOptions } from './types';
|
import { type ReactAppOptions } from './types';
|
||||||
|
|
||||||
interface Render {
|
interface Render {
|
||||||
@ -12,16 +12,16 @@ interface Render {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function createComponent(options: ReactAppOptions) {
|
export async function createComponent(options: ReactAppOptions) {
|
||||||
const creator = createRenderer<Render>((context) => {
|
const creator = createRenderer<Render>((accessor) => {
|
||||||
const { schema } = context;
|
const instances = getRenderInstancesByAccessor(accessor);
|
||||||
const componentsTree = schema.get('componentsTree')[0];
|
const componentsTree = instances.schema.get('componentsTree')[0];
|
||||||
|
|
||||||
const LowCodeComponent = createSchemaComponent(componentsTree, {
|
const LowCodeComponent = createSchemaComponent(componentsTree, {
|
||||||
displayName: componentsTree.componentName,
|
displayName: componentsTree.componentName,
|
||||||
...options.component,
|
...options.component,
|
||||||
});
|
});
|
||||||
|
|
||||||
const contextValue = { ...context, options };
|
const contextValue = { ...instances, options };
|
||||||
|
|
||||||
function Component(props: LowCodeComponentProps) {
|
function Component(props: LowCodeComponentProps) {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -1,10 +1,39 @@
|
|||||||
|
import {
|
||||||
|
IBoostsService,
|
||||||
|
IComponentTreeModelService,
|
||||||
|
ILifeCycleService,
|
||||||
|
IPackageManagementService,
|
||||||
|
ISchemaService,
|
||||||
|
} from '@alilc/lowcode-renderer-core';
|
||||||
|
import { InstanceAccessor } from '@alilc/lowcode-shared';
|
||||||
import { createContext, useContext } from 'react';
|
import { createContext, useContext } from 'react';
|
||||||
import { type RenderContext } from '@alilc/lowcode-renderer-core';
|
|
||||||
import { type ReactAppOptions } from './types';
|
import { type ReactAppOptions } from './types';
|
||||||
|
|
||||||
export const RendererContext = createContext<RenderContext & { options: ReactAppOptions }>(
|
export interface IRendererContext {
|
||||||
undefined!,
|
readonly options: ReactAppOptions;
|
||||||
);
|
|
||||||
|
readonly schema: Omit<ISchemaService, 'initialize'>;
|
||||||
|
|
||||||
|
readonly packageManager: IPackageManagementService;
|
||||||
|
|
||||||
|
readonly boostsManager: IBoostsService;
|
||||||
|
|
||||||
|
readonly componentTreeModel: IComponentTreeModelService;
|
||||||
|
|
||||||
|
readonly lifeCycle: ILifeCycleService;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getRenderInstancesByAccessor = (accessor: InstanceAccessor) => {
|
||||||
|
return {
|
||||||
|
schema: accessor.get(ISchemaService),
|
||||||
|
packageManager: accessor.get(IPackageManagementService),
|
||||||
|
boostsManager: accessor.get(IBoostsService),
|
||||||
|
componentTreeModel: accessor.get(IComponentTreeModelService),
|
||||||
|
lifeCycle: accessor.get(ILifeCycleService),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const RendererContext = createContext<IRendererContext>(undefined!);
|
||||||
|
|
||||||
RendererContext.displayName = 'RendererContext';
|
RendererContext.displayName = 'RendererContext';
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,7 @@ export { defineRendererPlugin } from './app';
|
|||||||
export * from './router';
|
export * from './router';
|
||||||
export { LifecyclePhase } from '@alilc/lowcode-renderer-core';
|
export { LifecyclePhase } from '@alilc/lowcode-renderer-core';
|
||||||
|
|
||||||
export type { Spec, ProCodeComponent, LowCodeComponent } from '@alilc/lowcode-shared';
|
export type { Package, ProCodeComponent, LowCodeComponent } from '@alilc/lowcode-shared';
|
||||||
export type {
|
export type {
|
||||||
PackageLoader,
|
PackageLoader,
|
||||||
CodeScope,
|
CodeScope,
|
||||||
|
|||||||
@ -1,3 +1,10 @@
|
|||||||
export * from './context';
|
export * from './context';
|
||||||
export * from './plugin';
|
export * from './plugin';
|
||||||
export type * from '@alilc/lowcode-renderer-router';
|
export type {
|
||||||
|
RouteLocation,
|
||||||
|
RawLocation,
|
||||||
|
Router,
|
||||||
|
RouterOptions,
|
||||||
|
RouteLocationNormalized,
|
||||||
|
RouterHistory,
|
||||||
|
} from '@alilc/lowcode-renderer-router';
|
||||||
|
|||||||
@ -1,13 +1,12 @@
|
|||||||
import { invariant, specTypes, type ComponentTreeRoot } from '@alilc/lowcode-shared';
|
import { invariant, specTypes, type ComponentTreeRoot } from '@alilc/lowcode-shared';
|
||||||
import { forwardRef, useRef, useEffect } from 'react';
|
import { forwardRef, useRef, useEffect } from 'react';
|
||||||
import { isValidElementType } from 'react-is';
|
import { isValidElementType } from 'react-is';
|
||||||
import { useRendererContext } from '../api/context';
|
import { useRendererContext, IRendererContext } from '../api/context';
|
||||||
import { reactiveStateFactory } from './reactiveState';
|
import { reactiveStateFactory } from './reactiveState';
|
||||||
import { type ReactComponent, type ReactWidget, createElementByWidget } from './elements';
|
import { type ReactComponent, type ReactWidget, createElementByWidget } from './elements';
|
||||||
import { appendExternalStyle } from '../utils/element';
|
import { appendExternalStyle } from '../utils/element';
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
RenderContext,
|
|
||||||
IComponentTreeModel,
|
IComponentTreeModel,
|
||||||
CreateComponentTreeModelOptions,
|
CreateComponentTreeModelOptions,
|
||||||
} from '@alilc/lowcode-renderer-core';
|
} from '@alilc/lowcode-renderer-core';
|
||||||
@ -36,7 +35,7 @@ const lowCodeComponentsCache = new Map<string, ReactComponent>();
|
|||||||
|
|
||||||
export function getComponentByName(
|
export function getComponentByName(
|
||||||
name: string,
|
name: string,
|
||||||
{ packageManager }: RenderContext,
|
{ packageManager }: IRendererContext,
|
||||||
componentOptions: ComponentOptions = {},
|
componentOptions: ComponentOptions = {},
|
||||||
): ReactComponent {
|
): ReactComponent {
|
||||||
const result = lowCodeComponentsCache.get(name) || packageManager.getComponent(name);
|
const result = lowCodeComponentsCache.get(name) || packageManager.getComponent(name);
|
||||||
|
|||||||
@ -1,23 +1,22 @@
|
|||||||
/* --------------- api -------------------- */
|
/* --------------- api -------------------- */
|
||||||
export { createRenderer } from './main';
|
export { createRenderer } from './main';
|
||||||
export { definePackageLoader } from './services/package';
|
export { IBoostsService, IExtensionHostService } from './services/extension';
|
||||||
export { LifecyclePhase } from './services/lifeCycleService';
|
export { definePackageLoader, IPackageManagementService } from './services/package';
|
||||||
export { Widget } from './services/widget';
|
export { LifecyclePhase, ILifeCycleService } from './services/lifeCycleService';
|
||||||
export * from '../../shared/src/utils/node';
|
export { IComponentTreeModelService } from './services/model';
|
||||||
|
export { ICodeRuntimeService } from './services/code-runtime';
|
||||||
|
export { IRuntimeIntlService } from './services/runtimeIntlService';
|
||||||
|
export { IRuntimeUtilService } from './services/runtimeUtilService';
|
||||||
|
export { ISchemaService } from './services/schema';
|
||||||
|
export { Widget } from './widget';
|
||||||
export * from './utils/value';
|
export * from './utils/value';
|
||||||
|
|
||||||
/* --------------- types ---------------- */
|
/* --------------- types ---------------- */
|
||||||
export type * from './types';
|
export type * from './types';
|
||||||
export type {
|
export type * from './services/extension';
|
||||||
Plugin,
|
|
||||||
IRenderObject,
|
|
||||||
PluginContext,
|
|
||||||
RenderAdapter,
|
|
||||||
RenderContext,
|
|
||||||
} from './services/extension';
|
|
||||||
export type * from './services/code-runtime';
|
export type * from './services/code-runtime';
|
||||||
export type * from './services/model';
|
export type * from './services/model';
|
||||||
export type * from './services/package';
|
export type * from './services/package';
|
||||||
export type * from './services/schema';
|
export type * from './services/schema';
|
||||||
export type * from './services/widget';
|
|
||||||
export type * from './services/extension';
|
export type * from './services/extension';
|
||||||
|
export type * from './widget';
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import { invariant, InstantiationService } from '@alilc/lowcode-shared';
|
import { invariant, InstantiationService } from '@alilc/lowcode-shared';
|
||||||
import { ICodeRuntimeService } from './services/code-runtime';
|
import { ICodeRuntimeService } from './services/code-runtime';
|
||||||
import {
|
import {
|
||||||
IBoostsService,
|
|
||||||
IExtensionHostService,
|
IExtensionHostService,
|
||||||
type RenderAdapter,
|
type RenderAdapter,
|
||||||
type IRenderObject,
|
type IRenderObject,
|
||||||
@ -9,80 +8,8 @@ import {
|
|||||||
import { IPackageManagementService } from './services/package';
|
import { IPackageManagementService } from './services/package';
|
||||||
import { ISchemaService } from './services/schema';
|
import { ISchemaService } from './services/schema';
|
||||||
import { ILifeCycleService, LifecyclePhase } from './services/lifeCycleService';
|
import { ILifeCycleService, LifecyclePhase } from './services/lifeCycleService';
|
||||||
import { IComponentTreeModelService } from './services/model';
|
|
||||||
import type { AppOptions, RendererApplication } from './types';
|
import type { AppOptions, RendererApplication } from './types';
|
||||||
|
|
||||||
export class RendererMain<RenderObject> {
|
|
||||||
private mode: 'development' | 'production' = 'production';
|
|
||||||
|
|
||||||
private initOptions: AppOptions;
|
|
||||||
|
|
||||||
private renderObject: RenderObject;
|
|
||||||
|
|
||||||
private adapter: RenderAdapter<RenderObject>;
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
@ICodeRuntimeService private codeRuntimeService: ICodeRuntimeService,
|
|
||||||
@IPackageManagementService private packageManagementService: IPackageManagementService,
|
|
||||||
@ISchemaService private schemaService: ISchemaService,
|
|
||||||
@IExtensionHostService private extensionHostService: IExtensionHostService,
|
|
||||||
@IComponentTreeModelService private componentTreeModelService: IComponentTreeModelService,
|
|
||||||
@IBoostsService private boostsService: IBoostsService,
|
|
||||||
@ILifeCycleService private lifeCycleService: ILifeCycleService,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
async main(options: AppOptions, adapter: RenderAdapter<RenderObject>) {
|
|
||||||
const { schema, mode, plugins = [] } = options;
|
|
||||||
|
|
||||||
if (mode) this.mode = mode;
|
|
||||||
this.initOptions = { ...options };
|
|
||||||
this.adapter = adapter;
|
|
||||||
|
|
||||||
// valid schema
|
|
||||||
this.schemaService.initialize(schema);
|
|
||||||
|
|
||||||
this.codeRuntimeService.initialize(options.codeRuntime ?? {});
|
|
||||||
|
|
||||||
await this.lifeCycleService.setPhase(LifecyclePhase.OptionsResolved);
|
|
||||||
|
|
||||||
const renderContext = {
|
|
||||||
schema: this.schemaService,
|
|
||||||
packageManager: this.packageManagementService,
|
|
||||||
boostsManager: this.boostsService,
|
|
||||||
componentTreeModel: this.componentTreeModelService,
|
|
||||||
lifeCycle: this.lifeCycleService,
|
|
||||||
};
|
|
||||||
|
|
||||||
this.renderObject = await this.adapter(renderContext);
|
|
||||||
|
|
||||||
await this.extensionHostService.registerPlugin(plugins);
|
|
||||||
// 先加载插件提供 package loader
|
|
||||||
await this.packageManagementService.loadPackages(this.initOptions.packages ?? []);
|
|
||||||
|
|
||||||
await this.lifeCycleService.setPhase(LifecyclePhase.Ready);
|
|
||||||
}
|
|
||||||
|
|
||||||
getApp(): RendererApplication<RenderObject> {
|
|
||||||
// construct application
|
|
||||||
return Object.freeze<RendererApplication<RenderObject>>({
|
|
||||||
// develop use
|
|
||||||
__options: this.initOptions,
|
|
||||||
|
|
||||||
mode: this.mode,
|
|
||||||
schema: this.schemaService,
|
|
||||||
packageManager: this.packageManagementService,
|
|
||||||
...this.renderObject,
|
|
||||||
|
|
||||||
use: (plugin) => {
|
|
||||||
return this.extensionHostService.registerPlugin(plugin);
|
|
||||||
},
|
|
||||||
destroy: async () => {
|
|
||||||
return this.lifeCycleService.setPhase(LifecyclePhase.Destroying);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建 createRenderer 的辅助函数
|
* 创建 createRenderer 的辅助函数
|
||||||
* @param schema
|
* @param schema
|
||||||
@ -94,13 +21,51 @@ export function createRenderer<RenderObject = IRenderObject>(
|
|||||||
): (options: AppOptions) => Promise<RendererApplication<RenderObject>> {
|
): (options: AppOptions) => Promise<RendererApplication<RenderObject>> {
|
||||||
invariant(typeof renderAdapter === 'function', 'The first parameter must be a function.');
|
invariant(typeof renderAdapter === 'function', 'The first parameter must be a function.');
|
||||||
|
|
||||||
const instantiationService = new InstantiationService({ defaultScope: 'Singleton' });
|
const accessor = new InstantiationService({ defaultScope: 'Singleton' });
|
||||||
const rendererMain = instantiationService.createInstance(
|
let mode: 'development' | 'production' = 'production';
|
||||||
RendererMain,
|
|
||||||
) as RendererMain<RenderObject>;
|
const schemaService = accessor.get(ISchemaService);
|
||||||
|
const packageManagementService = accessor.get(IPackageManagementService);
|
||||||
|
const codeRuntimeService = accessor.get(ICodeRuntimeService);
|
||||||
|
const lifeCycleService = accessor.get(ILifeCycleService);
|
||||||
|
const extensionHostService = accessor.get(IExtensionHostService);
|
||||||
|
|
||||||
return async (options) => {
|
return async (options) => {
|
||||||
await rendererMain.main(options, renderAdapter);
|
if (options.mode) mode = options.mode;
|
||||||
return rendererMain.getApp();
|
|
||||||
|
// valid schema
|
||||||
|
schemaService.initialize(options.schema);
|
||||||
|
codeRuntimeService.initialize(options.codeRuntime ?? {});
|
||||||
|
await lifeCycleService.setPhase(LifecyclePhase.OptionsResolved);
|
||||||
|
|
||||||
|
const renderObject = await renderAdapter(accessor);
|
||||||
|
|
||||||
|
await extensionHostService.registerPlugin(options.plugins ?? []);
|
||||||
|
// 先加载插件提供 package loader
|
||||||
|
await packageManagementService.loadPackages(options.packages ?? []);
|
||||||
|
|
||||||
|
await lifeCycleService.setPhase(LifecyclePhase.Ready);
|
||||||
|
|
||||||
|
const app: RendererApplication<RenderObject> = {
|
||||||
|
get mode() {
|
||||||
|
return mode;
|
||||||
|
},
|
||||||
|
schema: schemaService,
|
||||||
|
packageManager: packageManagementService,
|
||||||
|
...renderObject,
|
||||||
|
|
||||||
|
use: (plugin) => {
|
||||||
|
return extensionHostService.registerPlugin(plugin);
|
||||||
|
},
|
||||||
|
destroy: async () => {
|
||||||
|
return lifeCycleService.setPhase(LifecyclePhase.Destroying);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
if (mode === 'development') {
|
||||||
|
Object.defineProperty(app, '__options', { get: () => options });
|
||||||
|
}
|
||||||
|
|
||||||
|
return app;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,9 @@
|
|||||||
import { type EventEmitter, type IStore, type StringDictionary } from '@alilc/lowcode-shared';
|
import { type EventEmitter, type StringDictionary } from '@alilc/lowcode-shared';
|
||||||
import { type IBoosts } from './boosts';
|
import { type IBoosts } from './boosts';
|
||||||
import { ILifeCycleService } from '../lifeCycleService';
|
import { ILifeCycleService } from '../lifeCycleService';
|
||||||
import { type ISchemaService } from '../schema';
|
import { type ISchemaService } from '../schema';
|
||||||
import { type IPackageManagementService } from '../package';
|
import { type IPackageManagementService } from '../package';
|
||||||
|
import { type IStore } from '../../utils/store';
|
||||||
|
|
||||||
export interface PluginContext<BoostsExtends = object> {
|
export interface PluginContext<BoostsExtends = object> {
|
||||||
eventEmitter: EventEmitter;
|
eventEmitter: EventEmitter;
|
||||||
|
|||||||
@ -1,26 +1,10 @@
|
|||||||
import { IPackageManagementService } from '../package';
|
import { type InstanceAccessor } from '@alilc/lowcode-shared';
|
||||||
import { IBoostsService } from './boosts';
|
|
||||||
import { ISchemaService } from '../schema';
|
|
||||||
import { IComponentTreeModelService } from '../model';
|
|
||||||
import { ILifeCycleService } from '../lifeCycleService';
|
|
||||||
|
|
||||||
export interface IRenderObject {
|
export interface IRenderObject {
|
||||||
mount: (containerOrId?: string | HTMLElement) => void | Promise<void>;
|
mount: (containerOrId?: string | HTMLElement) => void | Promise<void>;
|
||||||
unmount: () => void | Promise<void>;
|
unmount: () => void | Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RenderContext {
|
|
||||||
readonly schema: Omit<ISchemaService, 'initialize'>;
|
|
||||||
|
|
||||||
readonly packageManager: IPackageManagementService;
|
|
||||||
|
|
||||||
readonly boostsManager: IBoostsService;
|
|
||||||
|
|
||||||
readonly componentTreeModel: IComponentTreeModelService;
|
|
||||||
|
|
||||||
readonly lifeCycle: ILifeCycleService;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface RenderAdapter<Render> {
|
export interface RenderAdapter<Render> {
|
||||||
(context: RenderContext): Render | Promise<Render>;
|
(accessor: InstanceAccessor): Render | Promise<Render>;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,7 +14,7 @@ import {
|
|||||||
uniqueId,
|
uniqueId,
|
||||||
} from '@alilc/lowcode-shared';
|
} from '@alilc/lowcode-shared';
|
||||||
import { type ICodeRuntime } from '../code-runtime';
|
import { type ICodeRuntime } from '../code-runtime';
|
||||||
import { IWidget, Widget } from '../widget';
|
import { IWidget, Widget } from '../../widget';
|
||||||
|
|
||||||
export interface NormalizedComponentNode extends ComponentNode {
|
export interface NormalizedComponentNode extends ComponentNode {
|
||||||
loopArgs: [string, string];
|
loopArgs: [string, string];
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import {
|
|||||||
Provide,
|
Provide,
|
||||||
specTypes,
|
specTypes,
|
||||||
exportByReference,
|
exportByReference,
|
||||||
mapPackageToId,
|
mapPackageToUniqueId,
|
||||||
type Reference,
|
type Reference,
|
||||||
} from '@alilc/lowcode-shared';
|
} from '@alilc/lowcode-shared';
|
||||||
import { get as lodashGet } from 'lodash-es';
|
import { get as lodashGet } from 'lodash-es';
|
||||||
@ -91,7 +91,7 @@ export class PackageManagementService implements IPackageManagementService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getModuleByReference<T = any>(reference: Reference): T | undefined {
|
getModuleByReference<T = any>(reference: Reference): T | undefined {
|
||||||
const id = mapPackageToId(reference);
|
const id = mapPackageToUniqueId(reference);
|
||||||
if (this.packageStore.has(id)) {
|
if (this.packageStore.has(id)) {
|
||||||
const library = this.packageStore.get(id);
|
const library = this.packageStore.get(id);
|
||||||
const result = exportByReference(library, reference);
|
const result = exportByReference(library, reference);
|
||||||
@ -138,7 +138,7 @@ export class PackageManagementService implements IPackageManagementService {
|
|||||||
|
|
||||||
const normalized: NormalizedPackage = {
|
const normalized: NormalizedPackage = {
|
||||||
package: packageInfo.package,
|
package: packageInfo.package,
|
||||||
id: mapPackageToId(packageInfo),
|
id: mapPackageToUniqueId(packageInfo),
|
||||||
library: packageInfo.library,
|
library: packageInfo.library,
|
||||||
raw: packageInfo,
|
raw: packageInfo,
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { type NodeType, uniqueId, type ComponentNode } from '@alilc/lowcode-shared';
|
import { type NodeType, uniqueId, type ComponentNode } from '@alilc/lowcode-shared';
|
||||||
import { IComponentTreeModel } from '../model';
|
import { IComponentTreeModel } from '../services/model';
|
||||||
|
|
||||||
export interface IWidget<Component, ComponentInstance = unknown> {
|
export interface IWidget<Component, ComponentInstance = unknown> {
|
||||||
readonly key: string;
|
readonly key: string;
|
||||||
@ -1,7 +1,10 @@
|
|||||||
|
import * as Platform from './platform';
|
||||||
|
|
||||||
|
export { Platform };
|
||||||
|
|
||||||
export * from './event';
|
export * from './event';
|
||||||
export * from './logger';
|
export * from './logger';
|
||||||
export * from './intl';
|
export * from './intl';
|
||||||
export * from './instantiation';
|
export * from './instantiation';
|
||||||
export * from './signals';
|
export * from './signals';
|
||||||
export * as Platform from './platform';
|
|
||||||
export * from './linkedList';
|
export * from './linkedList';
|
||||||
|
|||||||
@ -1,8 +1,10 @@
|
|||||||
|
import * as Iterable from './iterable';
|
||||||
|
|
||||||
|
export { Iterable };
|
||||||
|
|
||||||
export * from './invariant';
|
export * from './invariant';
|
||||||
export * from './unique-id';
|
export * from './unique-id';
|
||||||
export * from './types';
|
export * from './types';
|
||||||
export * from './async';
|
export * from './async';
|
||||||
export * from './node';
|
export * from './node';
|
||||||
export * from './resource';
|
export * from './resource';
|
||||||
|
|
||||||
export * as Iterable from './iterable';
|
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
export * as specTypes from './spec';
|
import * as specTypes from './spec';
|
||||||
export * as jsonTypes from './json';
|
import * as jsonTypes from './json';
|
||||||
export * as types from './type';
|
import * as types from './type';
|
||||||
|
|
||||||
export * from './constraint';
|
export * from './constraint';
|
||||||
|
|
||||||
|
export { specTypes, jsonTypes, types };
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user