/** * MyBricks Opensource * https://mybricks.world * This source code is licensed under the MIT license. * * CheMingjun @2019 * mybricks@126.com */ import React, { useMemo, useCallback, useLayoutEffect, useEffect, useState } from "react"; import RenderSlot from "./RenderSlot"; import { observable as defaultObservable, hijackReactcreateElement } from "./observable"; // import coreLib from '@mybricks/comlib-core' import executor from './executor' import { compareVersion } from "./utils"; import ErrorBoundary from "./ErrorBoundary"; import { setLoggerSilent } from "./logger"; const regAry = (comAray, comDefs) => { comAray.forEach(comDef => { if (comDef.comAray) { regAry(comDef.comAray, comDefs); } else { comDefs[`${comDef.namespace}-${comDef.version}`] = comDef; } }) } export default function Main({ json, opts }: { json, opts: { env, events, libSourceCode, comDefs, comModules, observable, ref } }) { const comModules = useMemo(() => { console.log("opts.comModules", opts.comModules); return opts.comModules }, []); //所有组件定义 const comDefs = useMemo(() => { // if (!opts.observable) { // // 未传入observable,使用内置observable配合对React.createElement的劫持 // hijackReactcreateElement(); // } if (opts.comDefs) { // regAry(coreLib.comAray, opts.comDefs); return opts.comDefs } // let comLibs = window["__comlibs_rt_"];//运行组件库,在preivew.html中引入 // if (!comLibs) { // comLibs = window["__comlibs_edit_"]//设计状态 // } // if (!comLibs || !Array.isArray(comLibs)) { // throw new Error(`组件库为空,请检查是否通过加载了组件库运行时.`) // } // const comDefs = {} // comLibs.push(coreLib) // comLibs.forEach(lib => { // const comAray = lib.comAray; // if (comAray && Array.isArray(comAray)) { // regAry(comAray, comDefs); // } // }) // return comDefs; }, []) const getComDef = useCallback((def) => { const rtn = comDefs[def.namespace + '-' + def.version] if (!rtn) { const ary = [] for (let ns in comDefs) { if (ns.startsWith(def.namespace + '-')) { ary.push(comDefs[ns]) } } if (ary && ary.length > 0) { ary.sort((a, b) => { return compareVersion(a.version, b.version) }) const rtn0 = ary[0] console.warn(`【Mybricks】组件${def.namespace + '@' + def.version}未找到,使用${rtn0.namespace}@${rtn0.version}代替.`) return rtn0 } else { console.log(comDefs) throw new Error(`组件${def.namespace + '@' + def.version}未找到,请确定是否存在该组件以及对应的版本号.`) } } return rtn }, []) //环境变量,此处可以定义连接器、多语言等实现 const env = useMemo(() => { if (!!opts?.env?.silent) { setLoggerSilent(); } return Object.assign({ runtime: {}, i18n(text: any) { return text }, // canvasElement: document.body }, opts.env) }, []) const { slot } = json; // onError const onError = useMemo(() => { return (e) => { console.error(e); }; }, []); // logger const logger = useMemo(() => { return { ...console, error: (e) => { console.error(e); }, }; }, []); //根据script生成context对象 const [context, refs] = useMemo(() => { try { let refs const context = executor({ comModules, json, getComDef, events: opts.events, env, ref(_refs) { refs = _refs if (opts.ref) { opts.ref(_refs) } }, onError, logger }, {//////TODO goon observable: opts.observable || defaultObservable }) return [context, refs] } catch (ex: any) { console.error(ex); throw new Error(`导出的JSON.script执行异常.`) } }, []) useLayoutEffect(() => { refs.run() }, []) return ( ) }