diff --git a/packages/arco-lib/package.json b/packages/arco-lib/package.json index 57cc18a1..1f416cfd 100644 --- a/packages/arco-lib/package.json +++ b/packages/arco-lib/package.json @@ -1,6 +1,6 @@ { "name": "@sunmao-ui/arco-lib", - "version": "0.1.7", + "version": "0.1.8", "homepage": "https://github.com/webzard-io/sunmao-ui-arco-lib", "license": "MIT", "publishConfig": { @@ -31,8 +31,8 @@ "@arco-design/web-react": "^2.29.0", "@emotion/css": "^11.7.1", "@sinclair/typebox": "^0.21.2", - "@sunmao-ui/core": "^0.5.4", - "@sunmao-ui/runtime": "^0.5.6", + "@sunmao-ui/core": "^0.5.5", + "@sunmao-ui/runtime": "^0.5.7", "eslint-plugin-react-hooks": "^4.3.0", "lodash-es": "^4.17.21", "react": "^17.0.2", @@ -42,9 +42,9 @@ "devDependencies": { "@types/lodash": "^4.14.170", "@types/lodash-es": "^4.17.5", - "@types/react-resizable": "^1.7.4", "@types/react": "^17.0.0", "@types/react-dom": "^17.0.0", + "@types/react-resizable": "^1.7.4", "@typescript-eslint/eslint-plugin": "^4.31.1", "@typescript-eslint/parser": "^4.31.1", "@vitejs/plugin-react": "^1.0.0", diff --git a/packages/chakra-ui-lib/package.json b/packages/chakra-ui-lib/package.json index 7d855a11..696034ea 100644 --- a/packages/chakra-ui-lib/package.json +++ b/packages/chakra-ui-lib/package.json @@ -1,6 +1,6 @@ { "name": "@sunmao-ui/chakra-ui-lib", - "version": "0.3.7", + "version": "0.3.8", "description": "sunmao-ui chakra-ui library", "author": "sunmao-ui developers", "homepage": "https://github.com/webzard-io/sunmao-ui#readme", @@ -33,9 +33,9 @@ "@chakra-ui/react": "^1.7.1", "@emotion/styled": "^11.6.0", "@sinclair/typebox": "^0.21.2", - "@sunmao-ui/core": "^0.5.4", - "@sunmao-ui/editor-sdk": "^0.1.8", - "@sunmao-ui/runtime": "^0.5.6", + "@sunmao-ui/core": "^0.5.5", + "@sunmao-ui/editor-sdk": "^0.1.9", + "@sunmao-ui/runtime": "^0.5.7", "chakra-react-select": "^1.3.2", "framer-motion": "^4", "lodash-es": "^4.17.21", diff --git a/packages/core/package.json b/packages/core/package.json index fabb5b99..f488b6ed 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@sunmao-ui/core", - "version": "0.5.4", + "version": "0.5.5", "description": "sunmao-ui core", "author": "sunmao-ui developers", "homepage": "https://github.com/webzard-io/sunmao-ui#readme", diff --git a/packages/editor-sdk/package.json b/packages/editor-sdk/package.json index c4fa6ad7..a1ab7dad 100644 --- a/packages/editor-sdk/package.json +++ b/packages/editor-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@sunmao-ui/editor-sdk", - "version": "0.1.8", + "version": "0.1.9", "description": "The SDK for SunMao Editor", "author": "sunmao-ui developers", "homepage": "https://github.com/webzard-io/sunmao-ui#readme", @@ -29,8 +29,8 @@ "@emotion/css": "^11.7.1", "@emotion/react": "^11.1.1", "@sinclair/typebox": "^0.21.2", - "@sunmao-ui/core": "^0.5.4", - "@sunmao-ui/runtime": "^0.5.6", + "@sunmao-ui/core": "^0.5.5", + "@sunmao-ui/runtime": "^0.5.7", "codemirror": "^5.63.3", "formik": "^2.2.9", "immer": "^9.0.6", diff --git a/packages/editor/package.json b/packages/editor/package.json index a0c6d1e3..e6149e0c 100644 --- a/packages/editor/package.json +++ b/packages/editor/package.json @@ -1,6 +1,6 @@ { "name": "@sunmao-ui/editor", - "version": "0.5.8", + "version": "0.5.9", "description": "sunmao-ui editor", "author": "sunmao-ui developers", "homepage": "https://github.com/webzard-io/sunmao-ui#readme", @@ -36,11 +36,11 @@ "@emotion/css": "^11.7.1", "@emotion/react": "^11.1.1", "@sinclair/typebox": "^0.21.2", - "@sunmao-ui/arco-lib": "^0.1.7", - "@sunmao-ui/chakra-ui-lib": "^0.3.7", - "@sunmao-ui/core": "^0.5.4", - "@sunmao-ui/editor-sdk": "^0.1.8", - "@sunmao-ui/runtime": "^0.5.6", + "@sunmao-ui/arco-lib": "^0.1.8", + "@sunmao-ui/chakra-ui-lib": "^0.3.8", + "@sunmao-ui/core": "^0.5.5", + "@sunmao-ui/editor-sdk": "^0.1.9", + "@sunmao-ui/runtime": "^0.5.7", "acorn": "^8.7.0", "acorn-loose": "^8.3.0", "acorn-walk": "^8.2.0", diff --git a/packages/editor/src/components/Editor.tsx b/packages/editor/src/components/Editor.tsx index d5af531d..c7483320 100644 --- a/packages/editor/src/components/Editor.tsx +++ b/packages/editor/src/components/Editor.tsx @@ -1,4 +1,4 @@ -import React, { useMemo, useState, useEffect } from 'react'; +import React, { useMemo, useState, useCallback, useEffect } from 'react'; import { Application } from '@sunmao-ui/core'; import { GridCallbacks, @@ -38,7 +38,8 @@ type Props = { stateStore: ReturnOfInit['stateManager']['store']; services: EditorServices; libs: SunmaoLib[]; - uiProps: UIPros + onRefresh: () => void; + uiProps: UIPros; }; const ApiFormStyle = css` @@ -51,7 +52,7 @@ const ApiFormStyle = css` `; export const Editor: React.FC = observer( - ({ App, registry, stateStore, services, libs, uiProps }) => { + ({ App, registry, stateStore, services, libs, uiProps, onRefresh: onRefreshApp }) => { const { eventBus, editorStore } = services; const { components, @@ -69,12 +70,7 @@ export const Editor: React.FC = observer( const [preview, setPreview] = useState(false); const [codeMode, setCodeMode] = useState(false); const [code, setCode] = useState(''); - const [recoverKey, setRecoverKey] = useState(0); - const [isError, setIsError] = useState(false); - - const onError = (err: Error | null) => { - setIsError(err !== null); - }; + const [isDisplayApp, setIsDisplayApp] = useState(true); const gridCallbacks: GridCallbacks = useMemo(() => { return { @@ -118,8 +114,8 @@ export const Editor: React.FC = observer( }, [components]); const appComponent = useMemo(() => { - return ( - + return isDisplayApp ? ( + = observer( gridCallbacks={gridCallbacks} /> - ); - }, [App, app, gridCallbacks, recoverKey]); + ) : null; + }, [App, app, gridCallbacks, isDisplayApp]); const dataSourceForm = useMemo(() => { let component: React.ReactNode = ; @@ -148,16 +144,29 @@ export const Editor: React.FC = observer( return component; }, [activeDataSource, services, activeDataSourceType]); - useEffect(() => { - // when errors happened, `ErrorBoundary` wouldn't update until rerender - // so after the errors are fixed, would trigger this effect before `setError(false)` - // the process to handle the error is: - // app change -> error happen -> setError(true) -> setRecoverKey(recoverKey + 1) -> app change -> setRecoverKey(recoverKey + 1) -> setError(false) - if (isError) { - setRecoverKey(recoverKey + 1); + const onRefresh = useCallback(()=> { + services.stateManager.clear(); + setIsDisplayApp(false); + onRefreshApp(); + }, [services.stateManager, onRefreshApp]); + useEffect(()=> { + // Wait until the app is completely unmounted before remounting it + if (isDisplayApp === false) { + setIsDisplayApp(true); } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [app, isError]); // it only should depend on the app schema and `isError` to update + }, [isDisplayApp]); + const onCodeMode = useCallback(v => { + setCodeMode(v); + if (!v && code) { + eventBus.send( + 'operation', + genOperation(registry, 'replaceApp', { + app: new AppModel(JSON.parse(code).spec.components, registry), + }) + ); + } + }, [code, eventBus, registry]); + const onPreview = useCallback(() => setPreview(true), []); const renderMain = () => { const appBox = ( @@ -324,19 +333,10 @@ export const Editor: React.FC = observer( setPreview(true)} + onPreview={onPreview} codeMode={codeMode} - onCodeMode={v => { - setCodeMode(v); - if (!v && code) { - eventBus.send( - 'operation', - genOperation(registry, 'replaceApp', { - app: new AppModel(JSON.parse(code).spec.components, registry), - }) - ); - } - }} + onRefresh={onRefresh} + onCodeMode={onCodeMode} /> {renderMain()} diff --git a/packages/editor/src/components/EditorHeader/EditorHeader.tsx b/packages/editor/src/components/EditorHeader/EditorHeader.tsx index 9ff447f9..dd43790a 100644 --- a/packages/editor/src/components/EditorHeader/EditorHeader.tsx +++ b/packages/editor/src/components/EditorHeader/EditorHeader.tsx @@ -7,7 +7,8 @@ export const EditorHeader: React.FC<{ onPreview: () => void; codeMode: boolean; onCodeMode: (v: boolean) => void; -}> = ({ scale, setScale, onPreview, onCodeMode, codeMode }) => { + onRefresh: () => void; +}> = ({ scale, setScale, onPreview, onCodeMode, onRefresh, codeMode }) => { return ( @@ -31,6 +32,9 @@ export const EditorHeader: React.FC<{ + diff --git a/packages/editor/src/components/ErrorBoundary.tsx b/packages/editor/src/components/ErrorBoundary.tsx index bcc6b9a6..af880bed 100644 --- a/packages/editor/src/components/ErrorBoundary.tsx +++ b/packages/editor/src/components/ErrorBoundary.tsx @@ -2,18 +2,15 @@ import React from 'react'; type Props = { onError?: (error: Error | null) => void; -} +}; -class ErrorBoundary extends React.Component< - Props, - { error: unknown } -> { +class ErrorBoundary extends React.Component { constructor(props: Props) { super(props); this.state = { error: null }; } - static getDerivedStateFromError(error: unknown) { + static getDerivedStateFromError(error: Error) { return { error }; } @@ -27,7 +24,7 @@ class ErrorBoundary extends React.Component< render() { if (this.state.error) { - return String(this.state.error); + return
{this.state.error.stack}
; } return this.props.children; diff --git a/packages/editor/src/constants/enum.ts b/packages/editor/src/constants/enum.ts index 00f5d2c0..f696f9d9 100644 --- a/packages/editor/src/constants/enum.ts +++ b/packages/editor/src/constants/enum.ts @@ -1,8 +1,8 @@ enum ExplorerMenuTabs { - // EXPLORER = 0, - UI_TREE = 0, - DATA = 1, - STATE = 2 + EXPLORER = 0, + UI_TREE = 1, + DATA = 2, + STATE = 3 } enum ToolMenuTabs { diff --git a/packages/editor/src/init.tsx b/packages/editor/src/init.tsx index f7ddac47..a9b77418 100644 --- a/packages/editor/src/init.tsx +++ b/packages/editor/src/init.tsx @@ -1,7 +1,7 @@ import { Editor as _Editor } from './components/Editor'; import { initSunmaoUI, SunmaoLib, SunmaoUIRuntimeProps } from '@sunmao-ui/runtime'; import { AppModelManager } from './operations/AppModelManager'; -import React from 'react'; +import React, { useState, useCallback } from 'react'; import { widgets as internalWidgets, WidgetManager, @@ -96,15 +96,21 @@ export function initSunmaoUIEditor(props: SunmaoUIEditorProps = {}) { }; const Editor: React.FC = () => { + const [store, setStore] = useState(stateManager.store); + const onRefresh = useCallback(()=> { + setStore(stateManager.store); + }, []); + return ( <_Editor App={App} eleMap={ui.eleMap} registry={registry} - stateStore={stateManager.store} + stateStore={store} services={services} libs={props.libs || []} + onRefresh={onRefresh} uiProps={props.uiProps||{}} /> diff --git a/packages/runtime/package.json b/packages/runtime/package.json index da30f937..228f9709 100644 --- a/packages/runtime/package.json +++ b/packages/runtime/package.json @@ -1,6 +1,6 @@ { "name": "@sunmao-ui/runtime", - "version": "0.5.6", + "version": "0.5.7", "description": "sunmao-ui runtime", "author": "sunmao-ui developers", "homepage": "https://github.com/webzard-io/sunmao-ui#readme", @@ -31,7 +31,7 @@ "dependencies": { "@emotion/css": "^11.7.1", "@sinclair/typebox": "^0.21.2", - "@sunmao-ui/core": "^0.5.4", + "@sunmao-ui/core": "^0.5.5", "@vue/reactivity": "^3.1.5", "@vue/shared": "^3.2.20", "copy-to-clipboard": "^3.3.1", diff --git a/packages/runtime/src/components/core/Dummy.tsx b/packages/runtime/src/components/core/Dummy.tsx index 65f7e543..d29dccc9 100644 --- a/packages/runtime/src/components/core/Dummy.tsx +++ b/packages/runtime/src/components/core/Dummy.tsx @@ -1,5 +1,4 @@ import { implementRuntimeComponent } from '../../utils/buildKit'; -// import { useEffect } from 'react'; import { Type } from '@sinclair/typebox'; export default implementRuntimeComponent({ @@ -25,21 +24,5 @@ export default implementRuntimeComponent({ events: [], }, })(() => { - // console.info('####Component Render', component.id); - // useEffect(() => { - // console.info('####Component DidMount', component.id); - // componentDidMount?.forEach(e => e()); - // }, [component.id, componentDidMount]); - // useEffect(() => { - // console.info('####Component Update', component.id); - // componentDidUpdate?.forEach(e => e()); - // }, [component.id, componentDidMount, componentDidUpdate]); - // useEffect(() => { - // return () => { - // console.info('Component DidUnmount', component.id, unmountHooks); - // unmountHooks?.forEach(e => e()); - // }; - // }, [component.id, unmountHooks]); - return null; }); diff --git a/packages/runtime/src/traits/core/State.tsx b/packages/runtime/src/traits/core/State.tsx index dc7d68a2..ff645cca 100644 --- a/packages/runtime/src/traits/core/State.tsx +++ b/packages/runtime/src/traits/core/State.tsx @@ -32,6 +32,11 @@ const StateTraitFactory: TraitImplFactory> = () => { mergeState({ [key]: initialValue }); }, ], + unmountHooks: [ + () => { + HasInitializedMap.delete(hashId); + }, + ], }, }; };