diff --git a/packages/editor/package.json b/packages/editor/package.json index e46936d5..e344440f 100644 --- a/packages/editor/package.json +++ b/packages/editor/package.json @@ -101,6 +101,7 @@ "@sunmao-ui/core": "^0.4.1", "@sunmao-ui/editor-sdk": "^0.0.0", "@sunmao-ui/runtime": "^0.4.1", + "@sinclair/typebox": "^0.21.2", "formik": "^2.2.9", "immer": "^9.0.6", "lodash-es": "^4.17.21", diff --git a/packages/runtime/src/index.ts b/packages/runtime/src/index.ts index 7078f4bf..fb545469 100644 --- a/packages/runtime/src/index.ts +++ b/packages/runtime/src/index.ts @@ -5,8 +5,14 @@ import { initApiService } from './services/apiService'; import { initGlobalHandlerMap } from './services/handler'; import { UtilMethodManager } from './services/UtilMethodManager'; import { AppHooks, UtilMethod } from './types'; +import { enableES5, setAutoFreeze } from 'immer'; import './style.css'; +// immer would make some errors when read the states, so we do these to avoid it temporarily +// ref: https://github.com/immerjs/immer/issues/916 +enableES5(); +setAutoFreeze(false); + export type SunmaoUIRuntimeProps = { dependencies?: Record; utilMethods?: UtilMethod[]; diff --git a/packages/runtime/src/traits/core/Event.tsx b/packages/runtime/src/traits/core/Event.tsx index c8af847a..e4d60715 100644 --- a/packages/runtime/src/traits/core/Event.tsx +++ b/packages/runtime/src/traits/core/Event.tsx @@ -10,11 +10,12 @@ const PropsSchema = Type.Object({ export const generateCallback = ( handler: Omit, 'type'>, + rawHandler: Static, services: UIServices ) => { const send = () => { // Eval before sending event to assure the handler object is evaled from the latest state. - const evaledHandler = services.stateManager.deepEval(handler); + const evaledHandler = services.stateManager.deepEval(rawHandler); if (evaledHandler.disabled && typeof evaledHandler.disabled === 'boolean') { return; @@ -42,15 +43,18 @@ export const generateCallback = ( }; const EventTraitFactory: TraitImplFactory> = () => { - return ({ handlers, services }) => { + return ({ trait, handlers, services }) => { const callbackQueueMap: Record void>> = {}; + const rawHandlers = trait.properties.handlers as Static[]; // setup current handlers for (const i in handlers) { const handler = handlers[i]; if (!callbackQueueMap[handler.type]) { callbackQueueMap[handler.type] = []; } - callbackQueueMap[handler.type].push(generateCallback(handler, services)); + callbackQueueMap[handler.type].push( + generateCallback(handler, rawHandlers[i], services) + ); } const callbackMap: CallbackMap = {}; diff --git a/packages/runtime/src/traits/core/Fetch.tsx b/packages/runtime/src/traits/core/Fetch.tsx index 56daacab..22f4f4d8 100644 --- a/packages/runtime/src/traits/core/Fetch.tsx +++ b/packages/runtime/src/traits/core/Fetch.tsx @@ -1,7 +1,10 @@ import { createTrait } from '@sunmao-ui/core'; import { Static, Type } from '@sinclair/typebox'; import { TraitImplFactory } from '../../types'; -import { FetchTraitPropertiesSchema } from '../../types/traitPropertiesSchema'; +import { + FetchTraitPropertiesSchema, + EventHandlerSchema, +} from '../../types/traitPropertiesSchema'; import { generateCallback } from './Event'; const FetchTraitFactory: TraitImplFactory> = @@ -15,6 +18,8 @@ const FetchTraitFactory: TraitImplFactory['onComplete']; - rawOnComplete?.forEach(handler => { - generateCallback(handler, services)(); + rawOnComplete?.forEach((rawHandler, index) => { + generateCallback( + onComplete![index], + rawHandler as Static, + services + )(); }); } else { // TODO: Add FetchError class and remove console info @@ -109,8 +118,12 @@ const FetchTraitFactory: TraitImplFactory['onError']; - rawOnError?.forEach(handler => { - generateCallback(handler, services)(); + rawOnError?.forEach((rawHandler, index) => { + generateCallback( + onError![index], + rawHandler as Static, + services + )(); }); } },