diff --git a/src/ConsolePanel.res b/src/ConsolePanel.res index 04f11d9b8..03861c714 100644 --- a/src/ConsolePanel.res +++ b/src/ConsolePanel.res @@ -3,34 +3,35 @@ type logLevel = [ | #warn | #error ] +type log = {level: logLevel, content: array} @react.component -let make = (~logs, ~setLogs) => { +let make = (~logs, ~appendLog) => { React.useEffect(() => { let cb = e => { let data = e["data"] switch data["type"] { | #...logLevel as logLevel => let args: array = data["args"] - setLogs(previous => previous->Array.concat([(logLevel, args)])) + appendLog(logLevel, args) | _ => () } } Webapi.Window.addEventListener("message", cb) Some(() => Webapi.Window.removeEventListener("message", cb)) - }, []) + }, [appendLog])

{React.string("Console")}

{switch logs { | [] => React.string( - "Add some 'Console.log' to your code and enable 'Auto-run' to see your logs here.", + "Add some 'Console.log' to your code and click 'Run' or enable 'Auto-run' to see your logs here.", ) | logs => let content = logs - ->Array.mapWithIndex(((logLevel, log), i) => { + ->Array.mapWithIndex(({level: logLevel, content: log}, i) => { let log = Array.join(log, " ")
 {
+let make = (~compilerState, ~appendLog) => {
+  let validReact = switch compilerState {
+  | CompilerManagerHook.Executing({state: {validReactCode: true}})
+  | Compiling({state: {validReactCode: true}})
+  | Ready({validReactCode: true}) => true
+  | _ => false
+  }
+
+  let logs = switch compilerState {
+  | CompilerManagerHook.Executing({state: {logs}})
+  | Compiling({state: {logs}})
+  | Ready({logs}) => logs
+  | _ => []
+  }
   
- setLogs(_ => [])} /> +
- +
} diff --git a/src/Playground.res b/src/Playground.res index 5749a1bbc..c506e6c1c 100644 --- a/src/Playground.res +++ b/src/Playground.res @@ -1038,20 +1038,6 @@ module Settings = { } module ControlPanel = { - let codeFromResult = (result: FinalResult.t): string => { - open Api - switch result { - | FinalResult.Comp(comp) => - switch comp { - | CompilationResult.Success({js_code}) => js_code - | UnexpectedError(_) - | Unknown(_, _) - | Fail(_) => "/* No JS code generated */" - } - | Nothing - | Conv(_) => "/* No JS code generated */" - } - } module Button = { @react.component let make = (~children, ~onClick=?) => @@ -1130,23 +1116,73 @@ module ControlPanel = { ~state: CompilerManagerHook.state, ~dispatch: CompilerManagerHook.action => unit, ~editorCode: React.ref, - ~runOutput, - ~toggleRunOutput, + ~setCurrentTab: (tab => tab) => unit, ) => { let children = switch state { | Init => React.string("Initializing...") | SwitchingCompiler(_ready, _version) => React.string("Switching Compiler...") - | Compiling(_, _) + | Compiling(_) + | Executing(_) | Ready(_) => let onFormatClick = evt => { ReactEvent.Mouse.preventDefault(evt) dispatch(Format(editorCode.current)) } + let autoRun = switch state { + | CompilerManagerHook.Executing({state: {autoRun: true}}) + | Compiling({state: {autoRun: true}}) + | Ready({autoRun: true}) => true + | _ => false + } + + let runCode = () => { + setCurrentTab(_ => Output) + dispatch(RunCode) + } + + let onKeyDown = event => { + switch ( + event->ReactEvent.Keyboard.metaKey || event->ReactEvent.Keyboard.ctrlKey, + event->ReactEvent.Keyboard.key, + ) { + | (true, "e") => + event->ReactEvent.Keyboard.preventDefault + runCode() + | _ => () + } + } + + React.useEffect(() => { + Webapi.Window.addEventListener("keydown", onKeyDown) + Some(() => Webapi.Window.removeEventListener("keydown", onKeyDown)) + }, []) + + let runButtonText = { + let userAgent = Webapi.Window.Navigator.userAgent + let run = "Run" + if userAgent->String.includes("iPhone") || userAgent->String.includes("Android") { + run + } else if userAgent->String.includes("Mac") { + `${run} (⌘ + E)` + } else { + `${run} (Ctrl + E)` + } + } +
- toggleRunOutput()}> + { + switch state { + | Ready({autoRun: false}) => setCurrentTab(_ => Output) + | _ => () + } + dispatch(ToggleAutoRun) + }}> {React.string("Auto-run")} +
@@ -1176,78 +1212,27 @@ module OutputPanel = { ~compilerState: CompilerManagerHook.state, ~editorCode: React.ref, ~currentTab: tab, - ~runOutput, ) => { - /* - We need the prevState to understand different - state transitions, and to be able to keep displaying - old results until those transitions are done. - - Goal was to reduce the UI flickering during different - state transitions - */ - let prevState = React.useRef(None) - - let cmCode = switch prevState.current { - | Some(prev) => - switch (prev, compilerState) { - | (_, Ready({result: Nothing})) => None - | (Ready(prevReady), Ready(ready)) => - switch (prevReady.result, ready.result) { - | (_, Comp(Success(_))) => ControlPanel.codeFromResult(ready.result)->Some - | _ => None - } - | (_, Ready({result: Comp(Success(_)) as result})) => - ControlPanel.codeFromResult(result)->Some - | (Ready({result: Comp(Success(_)) as result}), Compiling(_, _)) => - ControlPanel.codeFromResult(result)->Some - | _ => None - } - | None => - switch compilerState { - | Ready(ready) => ControlPanel.codeFromResult(ready.result)->Some - | _ => None - } - } - - prevState.current = Some(compilerState) - - let resultPane = switch compilerState { - | Compiling(ready, _) - | Ready(ready) => - switch ready.result { - | Comp(Success(_)) - | Conv(Success(_)) => React.null - | _ => - - } - - | _ => React.null - } - - let (code, showCm) = switch cmCode { - | None => ("", false) - | Some(code) => (code, true) - } - - let codeElement = -
-        {HighlightJs.renderHLJS(~code, ~darkmode=true, ~lang="js", ())}
-      
- let output =
- resultPane - codeElement + {switch compilerState { + | Compiling({previousJsCode: Some(jsCode)}) + | Executing({jsCode}) + | Ready({result: Comp(Success({jsCode}))}) => +
+            {HighlightJs.renderHLJS(~code=jsCode, ~darkmode=true, ~lang="js", ())}
+          
+ | Ready({result: Conv(Success(_))}) => React.null + | Ready({result, targetLang, selected}) => + + | _ => React.null + }}
let errorPane = switch compilerState { - | Compiling(ready, _) + | Compiling({state: ready}) | Ready(ready) + | Executing({state: ready}) | SwitchingCompiler(ready, _) => let config = ready.selected.config let setConfig = config => compilerDispatch(UpdateConfig(config)) @@ -1273,7 +1259,9 @@ module OutputPanel = { let prevSelected = React.useRef(0) let selected = switch compilerState { - | Compiling(_, _) => prevSelected.current + | Executing(_) + | Compiling(_) => + prevSelected.current | Ready(ready) => switch ready.result { | Comp(Success(_)) @@ -1285,10 +1273,10 @@ module OutputPanel = { prevSelected.current = selected - let (logs, setLogs) = React.useState(_ => []) + let appendLog = (level, content) => compilerDispatch(AppendLog({level, content})) let tabs = [ - (Output, ), + (Output, ), (JavaScript, output), (Problems, errorPane), (Settings, settingsPane), @@ -1483,7 +1471,7 @@ let make = (~versions: array) => { } None - }, [compilerState]) + }, (compilerState, compilerDispatch)) let (layout, setLayout) = React.useState(_ => Webapi.Window.innerWidth < breakingPoint ? Column : Row @@ -1632,8 +1620,8 @@ let make = (~versions: array) => { } let cmHoverHints = switch compilerState { - | Ready({result: FinalResult.Comp(Success({type_hints}))}) => - Array.map(type_hints, hint => { + | Ready({result: FinalResult.Comp(Success({typeHints}))}) => + Array.map(typeHints, hint => { switch hint { | TypeDeclaration({start, end, hint}) | Binding({start, end, hint}) @@ -1693,17 +1681,13 @@ let make = (~versions: array) => { }) - let (runOutput, setRunOutput) = React.useState(() => false) - let toggleRunOutput = () => setRunOutput(prev => !prev) -
) => { {React.array(headers)}
- +
diff --git a/src/RenderPanel.res b/src/RenderPanel.res index 8cb391e2e..961430cf0 100644 --- a/src/RenderPanel.res +++ b/src/RenderPanel.res @@ -1,74 +1,11 @@ -let wrapReactApp = code => - `(function () { - ${code} - window.reactRoot.render(React.createElement(App.make, {})); -})();` - -let capitalizeFirstLetter = string => { - let firstLetter = string->String.charAt(0)->String.toUpperCase - `${firstLetter}${string->String.sliceToEnd(~start=1)}` -} - @react.component -let make = (~compilerState: CompilerManagerHook.state, ~clearLogs, ~runOutput) => { - let (validReact, setValidReact) = React.useState(() => false) - React.useEffect(() => { - if runOutput { - switch compilerState { - | CompilerManagerHook.Ready({selected, result: Comp(Success({js_code}))}) => - clearLogs() - open Babel - - let ast = Parser.parse(js_code, {sourceType: "module"}) - let {entryPointExists, code, imports} = PlaygroundValidator.validate(ast) - let imports = imports->Dict.mapValues(path => { - let filename = path->String.sliceToEnd(~start=9) // the part after "./stdlib/" - let filename = switch selected.id { - | {major: 12, minor: 0, patch: 0, preRelease: Some(Alpha(alpha))} if alpha < 8 => - let filename = if filename->String.startsWith("core__") { - filename->String.sliceToEnd(~start=6) - } else { - filename - } - capitalizeFirstLetter(filename) - | {major} if major < 12 && filename->String.startsWith("core__") => - capitalizeFirstLetter(filename) - | _ => filename - } - let compilerVersion = switch selected.id { - | {major: 12, minor: 0, patch: 0, preRelease: Some(Alpha(alpha))} if alpha < 8 => { - Semver.major: 12, - minor: 0, - patch: 0, - preRelease: Some(Alpha(8)), - } - | {major, minor} if (major === 11 && minor < 2) || major < 11 => { - major: 11, - minor: 2, - patch: 0, - preRelease: Some(Beta(1)), - } - | version => version - } - CompilerManagerHook.CdnMeta.getStdlibRuntimeUrl(compilerVersion, filename) - }) - - entryPointExists - ? code->wrapReactApp->EvalIFrame.sendOutput(imports) - : EvalIFrame.sendOutput(code, imports) - setValidReact(_ => entryPointExists) - | _ => () - } - } - None - }, (compilerState, runOutput)) - +let make = (~validReact) => {

{React.string("React")}

{validReact ? React.null : React.string( - "Create a React component called 'App' if you want to render it here, then enable 'Auto-run'.", + "Create a React component called 'App' if you want to render it here, then click 'Run' or enable 'Auto-run'.", )}
diff --git a/src/RenderPanel.resi b/src/RenderPanel.resi index 7a5e6d8bb..cf39cd0ee 100644 --- a/src/RenderPanel.resi +++ b/src/RenderPanel.resi @@ -1,6 +1,2 @@ @react.component -let make: ( - ~compilerState: CompilerManagerHook.state, - ~clearLogs: unit => unit, - ~runOutput: bool, -) => Jsx.element +let make: (~validReact: bool) => Jsx.element diff --git a/src/bindings/RescriptCompilerApi.res b/src/bindings/RescriptCompilerApi.res index 027da6a3e..5d953825f 100644 --- a/src/bindings/RescriptCompilerApi.res +++ b/src/bindings/RescriptCompilerApi.res @@ -237,18 +237,20 @@ module TypeHint = { module CompileSuccess = { type t = { - js_code: string, + @as("js_code") + jsCode: string, warnings: array, - type_hints: array, + @as("type_hints") + typeHints: array, time: float, // total compilation time } let decode = (~time: float, json): t => { open Json.Decode { - js_code: field("js_code", string, json), + jsCode: field("js_code", string, json), warnings: field("warnings", array(Warning.decode, ...), json), - type_hints: withDefault([], field("type_hints", array(TypeHint.decode, ...), ...), json), + typeHints: withDefault([], field("type_hints", array(TypeHint.decode, ...), ...), json), time, } } diff --git a/src/bindings/RescriptCompilerApi.resi b/src/bindings/RescriptCompilerApi.resi index 4852d197b..de8c069d4 100644 --- a/src/bindings/RescriptCompilerApi.resi +++ b/src/bindings/RescriptCompilerApi.resi @@ -104,9 +104,11 @@ module TypeHint: { module CompileSuccess: { type t = { - js_code: string, + @as("js_code") + jsCode: string, warnings: array, - type_hints: array, // Not supported in older versions <= 9.0.1 (will always be []) + @as("type_hints") + typeHints: array, // Not supported in older versions <= 9.0.1 (will always be []) time: float, // total compilation time } diff --git a/src/bindings/Webapi.res b/src/bindings/Webapi.res index 55d5eecc8..0cbc09f93 100644 --- a/src/bindings/Webapi.res +++ b/src/bindings/Webapi.res @@ -62,6 +62,10 @@ module Window = { module Location = { @scope(("window", "location")) @val external href: string = "href" } + + module Navigator = { + @scope(("window", "navigator")) @val external userAgent: string = "userAgent" + } } module Fetch = { diff --git a/src/common/CompilerManagerHook.res b/src/common/CompilerManagerHook.res index 4236657ef..3114d434b 100644 --- a/src/common/CompilerManagerHook.res +++ b/src/common/CompilerManagerHook.res @@ -136,6 +136,17 @@ let attachCompilerAndLibraries = async (~version, ~libraries: array, ()) } } +let wrapReactApp = code => + `(function () { + ${code} + window.reactRoot.render(React.createElement(App.make, {})); +})();` + +let capitalizeFirstLetter = string => { + let firstLetter = string->String.charAt(0)->String.toUpperCase + `${firstLetter}${string->String.sliceToEnd(~start=1)}` +} + type error = | SetupError(string) | CompilerLoadingError(string) @@ -157,6 +168,9 @@ type ready = { targetLang: Lang.t, errors: array, // For major errors like bundle loading result: FinalResult.t, + autoRun: bool, + validReactCode: bool, + logs: array, } type state = @@ -164,7 +178,8 @@ type state = | SetupFailed(string) | SwitchingCompiler(ready, Semver.t) // (ready, targetId, libraries) | Ready(ready) - | Compiling(ready, (Lang.t, string)) + | Compiling({state: ready, previousJsCode: option}) + | Executing({state: ready, jsCode: string}) type action = | SwitchToCompiler(Semver.t) // id @@ -172,6 +187,9 @@ type action = | Format(string) | CompileCode(Lang.t, string) | UpdateConfig(Config.t) + | AppendLog(ConsolePanel.log) + | ToggleAutoRun + | RunCode let createUrl = (pathName, ready) => { let params = switch ready.targetLang { @@ -213,119 +231,151 @@ let useCompilerManager = ( // Dispatch method for the public interface let dispatch = (action: action): unit => { Option.forEach(onAction, cb => cb(action)) - switch action { - | SwitchToCompiler(id) => - switch state { - | Ready(ready) => - // TODO: Check if libraries have changed as well - if ready.selected.id !== id { - setState(_ => SwitchingCompiler(ready, id)) - } else { - () + setState(state => + switch action { + | SwitchToCompiler(id) => + switch state { + | Ready(ready) if ready.selected.id !== id => + // TODO: Check if libraries have changed as well + SwitchingCompiler(ready, id) + | _ => state } - | _ => () - } - | UpdateConfig(config) => - switch state { - | Ready(ready) => - ready.selected.instance->Compiler.setConfig(config) - setState(_ => { + | UpdateConfig(config) => + switch state { + | Ready(ready) => + ready.selected.instance->Compiler.setConfig(config) let selected = {...ready.selected, config} - Compiling({...ready, selected}, (ready.targetLang, ready.code)) - }) - | _ => () - } - | CompileCode(lang, code) => - switch state { - | Ready(ready) => setState(_ => Compiling({...ready, code}, (lang, code))) - | _ => () - } - | SwitchLanguage({lang, code}) => - switch state { - | Ready(ready) => - let instance = ready.selected.instance - let availableTargetLangs = Version.availableLanguages(ready.selected.apiVersion) - - let currentLang = ready.targetLang - - Array.find(availableTargetLangs, l => l === lang)->Option.forEach(lang => { - // Try to automatically transform code - let (result, targetLang) = switch ready.selected.apiVersion { - | V1 => - let convResult = switch (currentLang, lang) { - | (Reason, Res) => - instance->Compiler.convertSyntax(~fromLang=Reason, ~toLang=Res, ~code)->Some - | (Res, Reason) => - instance->Compiler.convertSyntax(~fromLang=Res, ~toLang=Reason, ~code)->Some + Compiling({state: {...ready, selected}, previousJsCode: None}) + | _ => state + } + | CompileCode(lang, code) => + switch state { + | Ready(ready) => + Compiling({ + state: {...ready, code, targetLang: lang}, + previousJsCode: switch ready.result { + | Comp(Success({jsCode})) => Some(jsCode) | _ => None - } + }, + }) + | _ => state + } + | SwitchLanguage({lang, code}) => + switch state { + | Ready(ready) => + let instance = ready.selected.instance + let availableTargetLangs = Version.availableLanguages(ready.selected.apiVersion) + + let currentLang = ready.targetLang + + Array.find(availableTargetLangs, l => l === lang) + ->Option.map(lang => { + // Try to automatically transform code + let (result, targetLang) = switch ready.selected.apiVersion { + | V1 => + let convResult = switch (currentLang, lang) { + | (Reason, Res) => + instance->Compiler.convertSyntax(~fromLang=Reason, ~toLang=Res, ~code)->Some + | (Res, Reason) => + instance->Compiler.convertSyntax(~fromLang=Res, ~toLang=Reason, ~code)->Some + | _ => None + } - /* + /* Syntax convertion works the following way: If currentLang -> otherLang is not valid, try to pretty print the code with the otherLang, in case we e.g. want to copy paste or otherLang code in the editor and quickly switch to it */ - switch convResult { - | Some(result) => - switch result { - | ConversionResult.Fail(_) - | Unknown(_, _) - | UnexpectedError(_) => - let secondTry = - instance->Compiler.convertSyntax(~fromLang=lang, ~toLang=lang, ~code) - switch secondTry { + switch convResult { + | Some(result) => + switch result { | ConversionResult.Fail(_) | Unknown(_, _) - | UnexpectedError(_) => (FinalResult.Conv(secondTry), lang) - | Success(_) => (Conv(secondTry), lang) + | UnexpectedError(_) => + let secondTry = + instance->Compiler.convertSyntax(~fromLang=lang, ~toLang=lang, ~code) + switch secondTry { + | ConversionResult.Fail(_) + | Unknown(_, _) + | UnexpectedError(_) => (FinalResult.Conv(secondTry), lang) + | Success(_) => (Conv(secondTry), lang) + } + | ConversionResult.Success(_) => (Conv(result), lang) } - | ConversionResult.Success(_) => (Conv(result), lang) + | None => (Nothing, lang) } - | None => (Nothing, lang) + | _ => (Nothing, lang) } - | _ => (Nothing, lang) - } - setState(_ => Ready({...ready, result, errors: [], targetLang})) - }) - | _ => () - } - | Format(code) => - switch state { - | Ready(ready) => - let instance = ready.selected.instance - let convResult = switch ready.targetLang { - | Res => instance->Compiler.resFormat(code)->Some - | Reason => instance->Compiler.reasonFormat(code)->Some - | _ => None + Ready({...ready, result, errors: [], targetLang}) + }) + ->Option.getOr(state) + | _ => state } + | Format(code) => + switch state { + | Ready(ready) => + let instance = ready.selected.instance + let convResult = switch ready.targetLang { + | Res => instance->Compiler.resFormat(code)->Some + | Reason => instance->Compiler.reasonFormat(code)->Some + | _ => None + } - let result = switch convResult { - | Some(result) => - switch result { - | ConversionResult.Success(success) => - // We will only change the result to a ConversionResult - // in case the reformatting has actually changed code - // otherwise we'd loose previous compilationResults, although - // the result should be the same anyways - if code !== success.code { + let result = switch convResult { + | Some(result) => + switch result { + | ConversionResult.Success(success) => + // We will only change the result to a ConversionResult + // in case the reformatting has actually changed code + // otherwise we'd loose previous compilationResults, although + // the result should be the same anyways + if code !== success.code { + FinalResult.Conv(result) + } else { + ready.result + } + | ConversionResult.Fail(_) + | Unknown(_, _) + | UnexpectedError(_) => FinalResult.Conv(result) - } else { - ready.result } - | ConversionResult.Fail(_) - | Unknown(_, _) - | UnexpectedError(_) => - FinalResult.Conv(result) + | None => ready.result } - | None => ready.result - } - setState(_ => Ready({...ready, result, errors: []})) - | _ => () + Ready({...ready, result, errors: []}) + | _ => state + } + | AppendLog(log) => + switch state { + | Ready(ready) => Ready({...ready, logs: Array.concat(ready.logs, [log])}) + | _ => state + } + | ToggleAutoRun => + switch state { + | Ready({autoRun: true} as ready) => Ready({...ready, autoRun: false}) + | Ready({autoRun: false} as ready) => + Compiling({ + state: { + ...ready, + autoRun: true, + }, + previousJsCode: switch ready.result { + | Comp(Success({jsCode})) => Some(jsCode) + | _ => None + }, + }) + | _ => state + } + | RunCode => + switch state { + | Ready({result: Comp(Success({jsCode}))} as ready) => + Executing({state: {...ready, autoRun: false}, jsCode}) + | _ => state + } } - } + ) } let dispatchError = (err: error) => @@ -392,6 +442,9 @@ let useCompilerManager = ( versions, errors: [], result: FinalResult.Nothing, + logs: [], + autoRun: false, + validReactCode: false, })) | Error(errs) => let msg = Array.join(errs, "; ") @@ -442,13 +495,16 @@ let useCompilerManager = ( versions: ready.versions, errors: [], result: FinalResult.Nothing, + autoRun: ready.autoRun, + validReactCode: ready.validReactCode, + logs: [], })) | Error(errs) => let msg = Array.join(errs, "; ") dispatchError(CompilerLoadingError(msg)) } - | Compiling(ready, (lang, code)) => + | Compiling({state: {targetLang: lang, code, autoRun} as ready}) => let apiVersion = ready.selected.apiVersion let instance = ready.selected.instance @@ -478,8 +534,54 @@ let useCompilerManager = ( `Can't handle result of compiler API version "${version}"`, ) } + let ready = {...ready, result: FinalResult.Comp(compResult)} + setState(_ => + switch (ready.result, autoRun) { + | (FinalResult.Comp(Success({jsCode})), true) => Executing({state: ready, jsCode}) + | _ => Ready(ready) + } + ) + | Executing({state, jsCode}) => + open Babel + + let ast = Parser.parse(jsCode, {sourceType: "module"}) + let {entryPointExists, code, imports} = PlaygroundValidator.validate(ast) + let imports = imports->Dict.mapValues(path => { + let filename = path->String.sliceToEnd(~start=9) // the part after "./stdlib/" + let filename = switch state.selected.id { + | {major: 12, minor: 0, patch: 0, preRelease: Some(Alpha(alpha))} if alpha < 8 => + let filename = if filename->String.startsWith("core__") { + filename->String.sliceToEnd(~start=6) + } else { + filename + } + capitalizeFirstLetter(filename) + | {major} if major < 12 && filename->String.startsWith("core__") => + capitalizeFirstLetter(filename) + | _ => filename + } + let compilerVersion = switch state.selected.id { + | {major: 12, minor: 0, patch: 0, preRelease: Some(Alpha(alpha))} if alpha < 8 => { + Semver.major: 12, + minor: 0, + patch: 0, + preRelease: Some(Alpha(8)), + } + | {major, minor} if (major === 11 && minor < 2) || major < 11 => { + major: 11, + minor: 2, + patch: 0, + preRelease: Some(Beta(1)), + } + | version => version + } + CdnMeta.getStdlibRuntimeUrl(compilerVersion, filename) + }) - setState(_ => Ready({...ready, result: FinalResult.Comp(compResult)})) + entryPointExists + ? code->wrapReactApp->EvalIFrame.sendOutput(imports) + : EvalIFrame.sendOutput(code, imports) + setState(_ => Ready({...state, logs: [], validReactCode: entryPointExists})) | SetupFailed(_) => () | Ready(ready) => let url = createUrl(router.route, ready) @@ -487,9 +589,17 @@ let useCompilerManager = ( } } - updateState()->ignore + updateState()->Promise.done None - }, [state]) + }, ( + state, + dispatchError, + initialVersion, + initialModuleSystem, + initialLang, + versions, + router.route, + )) (state, dispatch) } diff --git a/src/common/CompilerManagerHook.resi b/src/common/CompilerManagerHook.resi index 5e9f8a826..113a5c7b7 100644 --- a/src/common/CompilerManagerHook.resi +++ b/src/common/CompilerManagerHook.resi @@ -25,6 +25,9 @@ type ready = { targetLang: Lang.t, errors: array, // For major errors like bundle loading result: FinalResult.t, + autoRun: bool, + validReactCode: bool, + logs: array, } module CdnMeta: { @@ -36,7 +39,8 @@ type state = | SetupFailed(string) | SwitchingCompiler(ready, Semver.t) // (ready, targetId, libraries) | Ready(ready) - | Compiling(ready, (Lang.t, string)) + | Compiling({state: ready, previousJsCode: option}) + | Executing({state: ready, jsCode: string}) type action = | SwitchToCompiler(Semver.t) // id @@ -44,6 +48,9 @@ type action = | Format(string) | CompileCode(Lang.t, string) | UpdateConfig(Config.t) + | AppendLog(ConsolePanel.log) + | ToggleAutoRun + | RunCode let useCompilerManager: ( ~initialVersion: Semver.t=?,