Merge branch 'v/0.8.0' of gitlab.alibaba-inc.com:ali-lowcode/ali-lowcode-engine into preset-general/0.9.0

This commit is contained in:
wuyue.xht 2020-05-26 11:38:17 +08:00
commit 55a707bbf5
26 changed files with 421 additions and 300 deletions

View File

@ -1,130 +1,17 @@
// mixin .expression-setter-item-inner {
.lowcode-setter-mixin > * { .next-menu-item-text {
vertical-align: middle; vertical-align: middle;
} display: flex;
.lowcode-setter-mixin { justify-content: space-between;
width: 86%;
}
.lowcode-setter-mixin .next-input {
width: 100%;
}
.lowcode-setter-mixin .next-select-trigger {
width: 100%;
}
// json-setter
// :global {
.nrs-monaco-form {
.next-form-item:last-child {
margin: 0 !important;
}
} }
.monaco-editor-wrap { .next-menu-item {
.luna-monaco-button .next-icon-first { padding: 0 10px;
height: 26px;
}
.monaco_fullscreen_icon {
position: absolute;
line-height: 1;
z-index: 7;
color: #ddd;
&:hover {
color: #fff;
}
}
.btns-eare {
text-align: left;
line-height: initial;
margin-top: 5px;
// button{
// margin-right: 10px;
// }
}
&.monaco-nofullscreen {
position: relative !important;
.monaco_fullscreen_icon {
position: absolute;
top: 5px;
right: 5px;
line-height: 1;
z-index: 7;
i:before {
font-size: 16px;
}
}
}
&.monaco-fullscreen {
position: fixed !important;
height: 100% !important;
width: 100% !important;
border: 0;
margin: 0;
top: 0;
bottom: 0;
left: 0;
right: 0;
z-index: 1001;
overflow: hidden;
.monaco_fullscreen_icon {
top: 10px;
right: 10px;
i:before {
font-size: 24px;
}
}
}
}
.luna-monaco-button button {
width: 100%;
}
.luna-monaco-button-dialog {
.next-dialog-body {
padding: 0;
.next-form-item {
height: 100%;
margin-bottom: 0;
.next-form-item-control,
.next-form-item-control > div {
height: 100% !important;
}
.next-form-item-help {
position: absolute;
}
}
}
}
// }
// color-setter
.lowcode-color-box {
margin-right: -5px;
padding: 3px 0 3px 3px;
width: 26px;
height: 26px;
display: inline-block;
div {
width: 20px;
height: 20px;
border: 1px solid #ddd;
} }
} }
.next-balloon-normal.lowcode-color-content { .code-input-value {
padding: 0; float: left;
background: #ffffff; }
border-radius: 0; .code-input-help {
border: 1px solid #e5e5e5; float: right;
box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.1); color: #6897f2;
&:after { }
display: none;
}
.sketch-picker {
border-radius: 0 !important;
border: none !important;
box-shadow: none !important;
.flexbox-fix {
input {
width: 100% !important;
min-width: 30px;
text-align: center;
}
}
}
}

View File

@ -1,24 +1,26 @@
import React, { PureComponent } from 'react'; import React, { PureComponent } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { Select, Balloon } from '@alife/next'; import { Select, Balloon, Icon } from '@alife/next';
import * as acorn from 'acorn'; import * as acorn from 'acorn';
import { isJSExpression, generateI18n } from './locale/utils'; import { isJSExpression, generateI18n } from './locale/utils';
import zhCN from './locale/zh-CN'; import zhCN from './locale/zh-CN';
import './index.scss';
const { Option, AutoComplete } = Select; const { Option, AutoComplete } = Select;
const { Tooltip } = Balloon; const { Tooltip } = Balloon;
const helpMap = { const helpMap = {
this: '容器上下文对象', this: '容器上下文对象',
'this.state': '容器的state', 'state': '容器的state',
'this.props': '容器的props', 'props': '容器的props',
'this.context': '容器的context', 'context': '容器的context',
'this.page': '页面上下文对象', 'schema': '页面上下文对象',
'this.component': '组件上下文对象', 'component': '组件上下文对象',
'this.constants': '应用常量对象', 'constants': '应用常量对象',
'this.utils': '应用工具对象', 'utils': '应用工具对象',
'this.dataSourceMap': '容器数据源Map', 'dataSourceMap': '容器数据源Map',
'this.field': '表单Field对象' 'field': '表单Field对象'
} }
export default class ExpressionView extends PureComponent { export default class ExpressionView extends PureComponent {
@ -45,7 +47,7 @@ export default class ExpressionView extends PureComponent {
i18n: any; i18n: any;
t: void; t: void;
$input: any; $input: any;
listenerFun: (event: any) => void; listenerFun: ((event: any) => void) | undefined;
static getInitValue(val: { value: any; match: (arg0: RegExp) => any; }) { static getInitValue(val: { value: any; match: (arg0: RegExp) => any; }) {
if (isJSExpression(val)) { if (isJSExpression(val)) {
@ -81,51 +83,12 @@ export default class ExpressionView extends PureComponent {
onChange(value: string, actionType: string) { onChange(value: string, actionType: string) {
let realInputValue = value; let realInputValue = value;
let realDataSource = null; let realDataSource = null;
const cursorIndex = this.getInputCursorPosition();
let nextCursorIndex: number; let nextCursorIndex: number;
//更新值 //更新值
if (actionType === 'itemClick' || actionType === 'enter') { if (actionType === 'itemClick' || actionType === 'enter') {
let curValue = this.state.value; let curValue = this.state.value;
if (curValue) { if (curValue) {
//如果是非.结束,则替换当前这个变量; realInputValue = curValue + realInputValue;
let preStr = curValue.substr(0, cursorIndex);
let nextStr = curValue.substr(cursorIndex);
let preArr = preStr.split('.');
let preArrLen = preArr.length;
let tarPreStr = '';
if (!preArr[preArrLen - 1]) {
//如果是.结束,则增加到.后面
if (preArr[preArrLen - 2] === 'this') {
preArr = preArr.slice(0, preArrLen - 2);
preArr.push(value);
tarPreStr = preArr.join('.');
} else {
tarPreStr = preStr + value;
}
} else {
if (preArr[preArrLen - 2] === 'this') {
preArr = preArr.slice(0, preArrLen - 2);
} else {
preArr = preArr.slice(0, preArrLen - 1);
}
preArr.push(value);
tarPreStr = preArr.join('.');
}
realInputValue = tarPreStr + nextStr;
realDataSource = this.getDataSource(tarPreStr + '.') || [];
nextCursorIndex = tarPreStr.length;
}
} else {
let tarPreStr = value.substr(0, cursorIndex);
if (tarPreStr) {
let lastChar = tarPreStr.charAt(tarPreStr.length - 1);
if (lastChar === '.') {
realDataSource = this.getDataSource(tarPreStr) || [];
} else {
realDataSource = this.getDataSource(tarPreStr + '.');
}
} else {
realDataSource = this.getDataSource('this.');
} }
} }
//更新数据源 //更新数据源
@ -154,21 +117,16 @@ export default class ExpressionView extends PureComponent {
* @return {Array} * @return {Array}
*/ */
getDataSource(tempStr: string): Array<any> { getDataSource(tempStr: string): Array<any> {
if (tempStr === '' || /[^\w\.]$/.test(tempStr)) { if (/[^\w\.]$/.test(tempStr)) {
return this.getDataSource('this.') || []; return [];
} else if (tempStr === null || tempStr === '') {
return this.getContextKeys([]);
} else if (/\w\.$/.test(tempStr)) { } else if (/\w\.$/.test(tempStr)) {
let currentField = this.getCurrentFiled(tempStr); let currentField = this.getCurrentFiled(tempStr);
if (!currentField) return null; if (!currentField) return null;
let tempKeys = this.getObjectKeys(currentField.str); let tempKeys = this.getObjectKeys(currentField.str);
tempKeys = this.getContextKeys(tempKeys); tempKeys = this.getContextKeys(tempKeys);
if (!tempKeys) return null; if (!tempKeys) return null;
//给默认情况增加this
if (tempStr === 'this.') {
tempKeys = tempKeys.map((item: string) => {
return 'this.' + item;
});
tempKeys.unshift('this');
}
return tempKeys; return tempKeys;
} else if (/\.$/.test(tempStr)) { } else if (/\.$/.test(tempStr)) {
return []; return [];
@ -202,34 +160,31 @@ export default class ExpressionView extends PureComponent {
* @param {Array} * @param {Array}
* @return {Array} * @return {Array}
*/ */
getContextKeys(keys: any) { getContextKeys(keys: []) {
// let context = {}; const editor = this.props.field.editor;
// const { appHelper } = this.context; console.log(editor);
// const activeKey = appHelper && appHelper.activeKey; const limitKeys = ['schema', 'utils', 'constants'];
// if (!activeKey) return; if (keys.length === 0) return limitKeys;
// const activeCtx = appHelper.schemaHelper.compCtxMap && appHelper.schemaHelper.compCtxMap[activeKey]; if (!limitKeys.includes(keys[0])) return [];
// if (!activeCtx) return null; let result = [];
// let __self = activeCtx; let keyValue = editor;
// if (keys && keys.length > 1) { let assert = false;
// keys.shift(0); keys.forEach(item => {
// let path = '/' + keys.join('/'); if (!keyValue[item] || typeof keyValue[item] !== 'object') {
// path = path.replace(/[\[\]]/g, '/'); assert = true;
// context = jsonuri.get(__self, path); }
// if (context && typeof context === 'object') { if (keyValue[item]) {
// return this.filterKey(context); keyValue = keyValue[item];
// } }
// } else if (keys && keys[0] === 'this') { })
// return this.filterKey(__self); if (assert) return [];
// } result = Object.keys(keyValue);
// return null; return result;
return [ // return utilsKeys.concat(constantsKeys).concat(schemaKeys);
"page",
"component"
]
} }
/*过滤key */ /*过滤key */
filterKey(obj: any) { filterKey(obj: any, name: string) {
let filterKeys = [ let filterKeys = [
'reloadDataSource', 'reloadDataSource',
'REACT_HOT_LOADER_RENDERED_GENERATION', 'REACT_HOT_LOADER_RENDERED_GENERATION',
@ -244,7 +199,7 @@ export default class ExpressionView extends PureComponent {
let result = []; let result = [];
for (let key in obj) { for (let key in obj) {
if (key.indexOf('_') !== 0 && filterKeys.indexOf(key) === -1) { if (key.indexOf('_') !== 0 && filterKeys.indexOf(key) === -1) {
result.push(key); result.push(`${name}.${key}`);
} }
} }
return result; return result;
@ -259,12 +214,16 @@ export default class ExpressionView extends PureComponent {
filterOption(inputValue: string, item: { value: string | any[]; }) { filterOption(inputValue: string, item: { value: string | any[]; }) {
const cursorIndex = this.getInputCursorPosition(); const cursorIndex = this.getInputCursorPosition();
let preStr = inputValue.substr(0, cursorIndex); let preStr = inputValue.substr(0, cursorIndex);
let lastKey = preStr.split('.').slice(-1); let lastKey: string[] = preStr.split('.').slice(-1);
if (!lastKey) return true; if (!lastKey) return true;
if (item.value.indexOf(lastKey) > -1) return true; if (item.value.indexOf(lastKey) > -1) return true;
return false; return false;
} }
// handleClick = () => {
// this.props.field.editor.emit('variableBindDialog.open');
// }
render() { render() {
const { value, dataSource } = this.state; const { value, dataSource } = this.state;
const { placeholder } = this.props; const { placeholder } = this.props;
@ -293,26 +252,30 @@ export default class ExpressionView extends PureComponent {
isValObject ? ( isValObject ? (
value value
) : ( ) : (
<AutoComplete <div>
{...this.props} <AutoComplete
style={{ width: '100%' }} {...this.props}
dataSource={dataSource} style={{ width: '100%' }}
placeholder={placeholder || this.i18n('jsExpression')} dataSource={dataSource}
value={value} placeholder={placeholder || this.i18n('jsExpression')}
disabled={isValObject} value={value}
innerBefore={<span style={{ color: '#999', marginLeft: 4 }}>{'{{'}</span>} disabled={isValObject}
innerAfter={<span style={{ color: '#999', marginRight: 4 }}>{'}}'}</span>} innerBefore={<span style={{ color: '#999', marginLeft: 4 }}>{'{{'}</span>}
itemRender={({ value }) => { innerAfter={<span style={{ color: '#999', marginRight: 4 }}>{'}}'}</span>}
return ( popupClassName="expression-setter-item-inner"
<Option key={value} text={value} value={value}> itemRender={({ value }) => {
<div className="code-input-value">{value}</div> console.log(value);
<div className="code-input-help">{helpMap[value]}</div> return (
</Option> <Option key={value} text={value} value={value}>
); <div className="code-input-value">{value}</div>
}} <div className="code-input-help">{helpMap[value]}</div>
onChange={this.onChange.bind(this)} </Option>
filter={this.filterOption.bind(this)} );
/> }}
onChange={this.onChange.bind(this)}
filter={this.filterOption.bind(this)}
/>
</div>
) )
} }
> >
@ -363,7 +326,7 @@ export default class ExpressionView extends PureComponent {
* keys * keys
*/ */
getObjectKeys(str: string) { getObjectKeys(str: string) {
let keys = []; let keys: string | any[] = [];
if (str) keys = str.split('.'); if (str) keys = str.split('.');
return keys.slice(0, keys.length - 1); return keys.slice(0, keys.length - 1);
} }

View File

@ -0,0 +1,4 @@
# Change Log
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.

View File

@ -0,0 +1 @@
# 低代码引擎运行时框架

View File

@ -0,0 +1,11 @@
{
"plugins": [
[
"build-plugin-rax-component",
{
"type": "rax",
"targets": ["web"]
}
]
]
}

View File

@ -0,0 +1,30 @@
{
"name": "@ali/lowcode-rax-provider",
"version": "0.8.14-beta.0",
"description": "Rax Provider for Runtime",
"files": [
"es",
"lib"
],
"main": "lib/index.js",
"module": "es/index.js",
"scripts": {
"start": "build-scripts start",
"build": "build-scripts build"
},
"license": "MIT",
"dependencies": {
"@ali/lowcode-runtime": "^0.8.14-beta.0",
"rax": "1.1.2",
"driver-universal": "^3.1.3",
"rax-use-router": "^3.0.0",
"history": "^4.10.1"
},
"devDependencies": {
"@alib/build-scripts": "^0.1.18",
"build-plugin-rax-component": "^0.2.0"
},
"publishConfig": {
"registry": "https://registry.npm.alibaba-inc.com"
}
}

View File

@ -0,0 +1,5 @@
import RaxProvider from './provider';
import getRouter from './router';
export { getRouter };
export default RaxProvider;

View File

@ -0,0 +1,28 @@
import { createElement, useState, useEffect } from 'rax';
import { app } from '@ali/lowcode-runtime';
export default function LazyComponent(props) {
const [schema, setSchema] = useState(null);
useEffect(() => {
(async () => {
const { getPageData } = props || {};
if (getPageData && !schema) {
const data = await getPageData();
setSchema(data);
}
})();
});
const { getPageData, ...restProps } = props || {};
const Renderer = app.getRenderer();
const Loading = app.getLoading();
if (!Renderer || !schema) {
if (!Loading) {
return null;
}
// loading扩展点
return createElement(Loading);
}
return createElement(Renderer, { schema, loading: Loading ? createElement(Loading) : null, ...restProps });
}

View File

@ -0,0 +1,103 @@
import { createElement, render } from 'rax';
import UniversalDriver from 'driver-universal';
import { app, Provider } from '@ali/lowcode-runtime';
import LazyComponent from './lazy-component';
import getRouter from './router';
export default class RaxProvider extends Provider {
// 定制构造根组件的逻辑,如切换路由机制
createApp() {
const RouterView = this.getRouterView();
let App;
const layoutConfig = this.getLayoutConfig();
if (!layoutConfig || !layoutConfig.componentName) {
App = (props) => (RouterView ? createElement(RouterView, { ...props }) : null);
return App;
}
const { componentName: layoutName, props: layoutProps } = layoutConfig;
const { content: Layout, props: extraLayoutProps } = app.getLayout(layoutName) || {};
const sectionalRender = this.isSectionalRender();
if (!sectionalRender && Layout) {
App = (props) =>
createElement(
Layout,
{ ...layoutProps, ...extraLayoutProps },
RouterView ? createElement(RouterView, props) : null,
);
} else {
App = (props) => (RouterView ? createElement(RouterView, props) : null);
}
return App;
}
runApp(App, config) {
render(createElement(App), document.getElementById(config?.containerId || 'App'), { driver: UniversalDriver });
}
// 内置实现 for 动态化渲染
getRouterView() {
const routerConfig = this.getRouterConfig();
if (!routerConfig) {
return null;
}
const routes = [];
let homePageId = this.getHomePage();
Object.keys(routerConfig).forEach((pageId, idx) => {
if (!pageId) {
return;
}
const path = routerConfig[pageId];
routes.push({
path,
component: (props: any) =>
this.getLazyComponent(pageId, {
components: this.getComponents(),
utils: this.getUtils(),
componentsMap: this.getComponentsMapObj(),
...props,
}),
});
if (homePageId) {
return;
}
if (idx === 0 || path === '/') {
homePageId = pageId;
}
});
if (homePageId) {
routes.push({
path: '**',
component: (props) =>
this.getLazyComponent(homePageId, {
components: this.getComponents(),
utils: this.getUtils(),
componentsMap: this.getComponentsMapObj(),
...props,
}),
});
}
const Router = getRouter({
history: this.getHistory(),
routes,
});
const RouterView = (props) => createElement(Router, props);
return RouterView;
}
getLazyComponent(pageId, props) {
if (!pageId) {
return null;
}
if (this.getlazyElement(pageId)) {
return this.getlazyElement(pageId);
}
const lazyElement = createElement(LazyComponent, {
// eslint-disable-next-line no-return-await
getPageData: async () => await this.getPageData(pageId),
key: pageId,
...props,
});
this.setlazyElement(pageId, lazyElement);
return lazyElement;
}
}

View File

@ -0,0 +1,26 @@
import { useRouter } from 'rax-use-router';
import { createHashHistory, createBrowserHistory } from 'history';
const getConfig = (config) => {
let { history } = config;
const { routes } = config;
if (typeof history === 'string') {
if (history === 'hash') {
history = createHashHistory();
} else if (history === 'browser') {
history = createBrowserHistory();
}
}
return () => ({
history,
routes,
});
};
export default function getRouter(config) {
return function Router() {
const configWrapper = getConfig(config);
const { component } = useRouter(configWrapper);
return component;
};
}

View File

@ -0,0 +1,4 @@
# Change Log
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.

View File

@ -0,0 +1 @@
# 低代码引擎运行时框架

View File

@ -0,0 +1,5 @@
{
"plugins": [
"build-plugin-component"
]
}

View File

@ -0,0 +1,43 @@
{
"name": "@ali/lowcode-react-provider",
"version": "0.8.14",
"description": "React Provider for Runtime",
"files": [
"es",
"lib"
],
"main": "lib/index.js",
"module": "es/index.js",
"scripts": {
"build": "build-scripts build --skip-demo",
"test": "ava",
"test:snapshot": "ava --update-snapshots"
},
"ava": {
"compileEnhancements": false,
"snapshotDir": "test/fixtures/__snapshots__",
"extensions": [
"ts"
],
"require": [
"ts-node/register"
]
},
"license": "MIT",
"dependencies": {
"@ali/lowcode-runtime": "^0.8.13",
"react": "^16",
"react-dom": "^16",
"@recore/router": "^1.0.11"
},
"devDependencies": {
"@alib/build-scripts": "^0.1.18",
"build-plugin-component": "^0.2.16",
"@types/node": "^13.7.1",
"@types/react": "^16",
"@types/react-dom": "^16"
},
"publishConfig": {
"registry": "https://registry.npm.alibaba-inc.com"
}
}

View File

@ -0,0 +1,5 @@
import ReactProvider from './provider';
import { Router } from '@recore/router';
export { Router };
export default ReactProvider;

View File

@ -1,5 +1,5 @@
import { Component, createElement } from 'react'; import { Component, createElement } from 'react';
import app from '../../index'; import { app } from '@ali/lowcode-runtime';
interface IProps { interface IProps {
getPageData: () => any; getPageData: () => any;

View File

@ -1,7 +1,7 @@
import { createElement, ReactType, ReactElement } from 'react'; import { createElement, ReactType, ReactElement } from 'react';
import { Router } from '@ali/recore'; import ReactDOM from 'react-dom';
import app from '../../index'; import { Router } from '@recore/router';
import Provider from '..'; import { app, Provider } from '@ali/lowcode-runtime';
import LazyComponent from './lazy-component'; import LazyComponent from './lazy-component';
export default class ReactProvider extends Provider { export default class ReactProvider extends Provider {
@ -30,6 +30,10 @@ export default class ReactProvider extends Provider {
return App; return App;
} }
runApp(App: any, config: any) {
ReactDOM.render(<App />, document.getElementById(config?.containerId || 'App'));
}
// 内置实现 for 动态化渲染 // 内置实现 for 动态化渲染
getRouterView(): ReactType | null { getRouterView(): ReactType | null {
const routerConfig = this.getRouterConfig(); const routerConfig = this.getRouterConfig();

View File

@ -0,0 +1,9 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "lib"
},
"include": [
"./src/"
]
}

View File

@ -1,9 +1,5 @@
{ {
"plugins": [ "plugins": [
"build-plugin-component", "build-plugin-component"
"build-plugin-fusion",
["build-plugin-moment-locales", {
"locales": ["zh-cn"]
}]
] ]
} }

View File

@ -1,8 +1,7 @@
import { ReactType } from 'react';
type HistoryMode = 'browser' | 'hash'; type HistoryMode = 'browser' | 'hash';
interface ComponentsMap { interface ComponentsMap {
[key: string]: ReactType; [key: string]: any;
} }
interface UtilsMap { interface UtilsMap {

View File

@ -1,6 +1,6 @@
{ {
"name": "@ali/lowcode-runtime", "name": "@ali/lowcode-runtime",
"version": "0.8.13", "version": "0.8.14",
"description": "Runtime for Ali lowCode engine", "description": "Runtime for Ali lowCode engine",
"files": [ "files": [
"es", "es",
@ -26,14 +26,12 @@
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@ali/offline-events": "^1.0.0", "@ali/offline-events": "^1.0.0",
"@ali/recore": "^1.6.9" "history": "^4.10.1"
}, },
"devDependencies": { "devDependencies": {
"@alib/build-scripts": "^0.1.18", "@alib/build-scripts": "^0.1.18",
"@types/node": "^13.7.1", "@types/node": "^13.7.1",
"@types/react": "^16", "build-plugin-component": "^0.2.16"
"@types/react-dom": "^16",
"build-plugin-component": "^0.2.11"
}, },
"publishConfig": { "publishConfig": {
"registry": "https://registry.npm.alibaba-inc.com" "registry": "https://registry.npm.alibaba-inc.com"

View File

@ -1,4 +1,3 @@
import { ReactType } from 'react';
import Provider from './provider'; import Provider from './provider';
export interface ILayoutOptions { export interface ILayoutOptions {
@ -7,16 +6,16 @@ export interface ILayoutOptions {
} }
export default class Container { export default class Container {
private renderer: ReactType | null = null; private renderer: any = null;
private layouts: { [key: string]: { content: ReactType; props: any } } = {}; private layouts: { [key: string]: { content: any; props: any } } = {};
private loading: ReactType | null = null; private loading: any = null;
private provider: any; private provider: any;
registerRenderer(renderer: ReactType): any { registerRenderer(renderer: any): any {
this.renderer = renderer; this.renderer = renderer;
} }
registerLayout(Layout: ReactType, options: ILayoutOptions): any { registerLayout(Layout: any, options: ILayoutOptions): any {
if (!options) { if (!options) {
return; return;
} }
@ -27,7 +26,7 @@ export default class Container {
this.layouts[componentName] = { content: Layout, props }; this.layouts[componentName] = { content: Layout, props };
} }
registerLoading(component: ReactType) { registerLoading(component: any) {
if (!component) { if (!component) {
return; return;
} }
@ -50,11 +49,11 @@ export default class Container {
return this.layouts[componentName]; return this.layouts[componentName];
} }
getRenderer(): ReactType | null { getRenderer(): any {
return this.renderer; return this.renderer;
} }
getLoading(): ReactType | null { getLoading(): any {
return this.loading; return this.loading;
} }

View File

@ -1,7 +1,6 @@
import { ReactType } from 'react';
import Container, { ILayoutOptions } from './container'; import Container, { ILayoutOptions } from './container';
import { IProvider } from './provider'; import { IProvider } from './provider';
import run from './run'; import runApp from './runApp';
class App { class App {
private container: Container; private container: Container;
@ -11,18 +10,18 @@ class App {
} }
run() { run() {
run(); runApp();
} }
registerRenderer(renderer: ReactType): any { registerRenderer(renderer: any): any {
this.container.registerRenderer(renderer); this.container.registerRenderer(renderer);
} }
registerLayout(Layout: ReactType, options: ILayoutOptions): any { registerLayout(Layout: any, options: ILayoutOptions): any {
this.container.registerLayout(Layout, options); this.container.registerLayout(Layout, options);
} }
registerLoading(component: ReactType) { registerLoading(component: any) {
this.container.registerLoading(component); this.container.registerLoading(component);
} }
@ -34,11 +33,11 @@ class App {
return this.container.getLayout(componentName); return this.container.getLayout(componentName);
} }
getRenderer(): ReactType | null { getRenderer(): any | null {
return this.container.getRenderer(); return this.container.getRenderer();
} }
getLoading(): ReactType | null { getLoading(): any | null {
return this.container.getLoading(); return this.container.getLoading();
} }

View File

@ -1,4 +1,4 @@
import { IAppConfig, IUtils, IComponents, HistoryMode } from '../run'; import { IAppConfig, IUtils, IComponents, HistoryMode } from './runApp';
import EventEmitter from '@ali/offline-events'; import EventEmitter from '@ali/offline-events';
interface IConstants { interface IConstants {
@ -110,6 +110,7 @@ export interface IProvider {
getPageData(pageId: string): Promise<ComponentModel | undefined>; getPageData(pageId: string): Promise<ComponentModel | undefined>;
getLazyComponent(pageId: string, props: any): any; getLazyComponent(pageId: string, props: any): any;
createApp(): void; createApp(): void;
runApp(App: any, config: IAppConfig): void;
} }
export default class Provider implements IProvider { export default class Provider implements IProvider {
@ -197,6 +198,10 @@ export default class Provider implements IProvider {
throw new Error('Method called "createApp" not implemented.'); throw new Error('Method called "createApp" not implemented.');
} }
runApp(App: any, config: IAppConfig) {
throw new Error('Method called "runApp" not implemented.');
}
registerComponents(components: IComponents | undefined) { registerComponents(components: IComponents | undefined) {
if (!components) { if (!components) {
return; return;

View File

@ -1,6 +1,4 @@
import { ReactType } from 'react'; import { HashHistoryBuildOptions, BrowserHistoryBuildOptions, MemoryHistoryBuildOptions } from 'history';
import { runApp } from '@ali/recore';
import { HashHistoryBuildOptions, BrowserHistoryBuildOptions, MemoryHistoryBuildOptions } from '@recore/history';
import app from './index'; import app from './index';
export type HistoryOptions = { export type HistoryOptions = {
@ -8,7 +6,7 @@ export type HistoryOptions = {
} & (HashHistoryBuildOptions | BrowserHistoryBuildOptions | MemoryHistoryBuildOptions); } & (HashHistoryBuildOptions | BrowserHistoryBuildOptions | MemoryHistoryBuildOptions);
export interface IComponents { export interface IComponents {
[key: string]: ReactType; [key: string]: any;
} }
export interface IUtils { export interface IUtils {
@ -22,34 +20,35 @@ export interface IAppConfig {
components?: IComponents; components?: IComponents;
utils?: IUtils; utils?: IUtils;
containerId?: string; containerId?: string;
[key: string]: any;
} }
export interface IRecoreAppConfig { // export interface IRecoreAppConfig {
history?: HistoryMode; // history?: HistoryMode;
globalComponents?: IComponents; // globalComponents?: IComponents;
globalUtils?: IUtils; // globalUtils?: IUtils;
containerId?: string; // containerId?: string;
} // }
function transformConfig(config: IAppConfig | (() => IAppConfig)): IRecoreAppConfig { // function transformConfig(config: IAppConfig | (() => IAppConfig)): IRecoreAppConfig {
if (!config) { // if (!config) {
return {}; // return {};
} // }
if (typeof config === 'function') { // if (typeof config === 'function') {
config = config(); // config = config();
} // }
return { // return {
history: config.history, // history: config.history,
globalComponents: config.components, // globalComponents: config.components,
globalUtils: config.utils, // globalUtils: config.utils,
containerId: config.containerId, // containerId: config.containerId,
}; // };
} // }
export default function run() { export default function runApp() {
const provider = app.getProvider(); const provider = app.getProvider();
if (!provider) { if (!provider) {
throw new Error(''); throw new Error('Please register class Provider');
} }
provider.onReady(() => { provider.onReady(() => {
const promise = provider.async(); const promise = provider.async();
@ -58,8 +57,7 @@ export default function run() {
return; return;
} }
const App = provider.createApp(); const App = provider.createApp();
config = transformConfig(config); provider.runApp(App, config);
runApp(App, config);
}); });
}); });
} }

View File

@ -1,7 +1,5 @@
import { navigator, Router } from '@ali/recore';
import Provider from './core/provider'; import Provider from './core/provider';
import ReactProvider from './core/provider/react';
import app from './core'; import app from './core';
import * as Utils from './utils'; import * as Utils from './utils';
export { app, Router, Provider, ReactProvider, navigator, Utils }; export { app, Provider, Utils };