export function useEvalCode()

in docs-sdk/docs-provider/src2/DemoContainer/useEvalCode.tsx [15:87]


export function useEvalCode({ code, deps: demoDeps, enable }: IOpts) {
  const [transformedCode, setTransformedCode] = useState("");
  const [evaluated, setEvaluated] = useState<any>({});

  useEffect(() => {
    if (!enable) return;
    setTransformedCode("");
    setEvaluated({});
    Promise.all([
      import("@babel/standalone"),
    ]).then(
      ([
        babel,
      ]) => {
        const res = babel
          .transform(code, {
            presets: [
              [
                'typescript',
                {
                  isTSX: true,
                  allExtensions: true,
                },
              ],
            ],

            plugins: ['transform-modules-amd', 'transform-react-jsx'],
          })
          
          if (typeof res?.code === "string") {
            setTransformedCode(res.code);
          }
      }
    );
  }, [code, enable]);

  useLayoutEffect(() => {
    if (!enable) return;

    const exports: any = {};

    try {
      const fn = new Function("define", transformedCode);
      fn(define);
      setEvaluated(exports);
    } catch (error) {
      console.error("error when eval code:");
      console.error(error);
    }

    function define(depsArr, factory) {
      const deps = { ...externaledDeps, ...demoDeps };
      const depsValue = depsArr.map((depName) => {
        if (depName === "exports") {
          return exports;
        }
        if (deps && deps.hasOwnProperty(depName)) {
          return deps[depName];
        }
        throw new Error(`can not find dependency "${depName}"`);
      });
      factory(...depsValue);
    }
  }, [transformedCode, demoDeps, enable]);

  const renderEvalCode = evaluated.default ? (
    <WrapEvaledComponent retryKey={evaluated.default}>
      <evaluated.default />
    </WrapEvaledComponent>
  ) : null;

  return { value: evaluated, transformedCode, renderEvalCode };
}