File size: 2,901 Bytes
3c3f089
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
import { createSlice } from "@reduxjs/toolkit";
import { RootState } from "../store";
import * as esbuild from "esbuild-wasm";
import { unpkgFetchPlugin, unpkgPathPlugin } from "../../esbuild/plugins";
import { CompilerOutput, CompilerStatus } from "../../_types/compilerTypes";

type InitialStateType = {
  isInitializing: boolean;
  esbuildStatus: CompilerStatus;
  isCompiling: boolean;
  output: CompilerOutput;
};

const initialState = {
  isInitializing: false,
  esbuildStatus: { isReady: false, error: "" },
  isCompiling: false,
  output: { code: "", error: "" },
};

export const compilerSlice = createSlice({
  name: "compiler",
  initialState: initialState,
  reducers: {
    init_esbuild: (state: InitialStateType) => {
      state.isInitializing = true;
    },
    init_esbuild_success: (state: InitialStateType) => {
      state.esbuildStatus.isReady = true;
      state.esbuildStatus.error = "";
      state.isInitializing = false;
    },
    init_esbuild_failure: (state: InitialStateType, { payload }) => {
      state.esbuildStatus.isReady = false;
      state.esbuildStatus.error = payload;
      state.isInitializing = false;
    },
    compiled: (state: InitialStateType) => {
      state.isCompiling = true;
    },
    compiled_success: (state: InitialStateType, { payload }) => {
      state.output.code = payload;
      state.output.error = "";
      state.isCompiling = false;
    },
    compiled_failure: (state: InitialStateType, { payload }) => {
      state.output.code = "";
      state.output.error = payload;
      state.isCompiling = false;
    },
  },
});

export const {
  compiled,
  compiled_success,
  compiled_failure,
  init_esbuild,
  init_esbuild_success,
  init_esbuild_failure,
} = compilerSlice.actions;

export const compiler_state = (state: RootState) => state.compiler;

export default compilerSlice.reducer;

// Asynchronous thunk action

export function initEsbuild() {
  return async (dispatch: any) => {
    dispatch(init_esbuild());

    await esbuild
      .initialize({
        worker: true,
        wasmURL: "https://unpkg.com/[email protected]/esbuild.wasm",
      })
      .then(() => {
        dispatch(init_esbuild_success());
      })
      .catch((error) => dispatch(init_esbuild_failure(error.message)));
  };
}

export function getCompileCode(rawCode: string, entryPoint: string) {
  return async (dispatch: any) => {
    dispatch(compiled());

    try {
      const result = await esbuild.build({
        entryPoints: [`${entryPoint}`],
        bundle: true,
        write: false,
        minify: true,
        outdir: "/",
        plugins: [unpkgPathPlugin(), unpkgFetchPlugin(rawCode, entryPoint)],
        metafile: true,
        allowOverwrite: true,
      });

      dispatch(compiled_success(result.outputFiles[0].text));
    } catch (error) {
      // @ts-ignore
      dispatch(compiled_failure(error.message));
    }
  };
}