Skip to content

Evaluate code in playground #415

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 13 commits into from
Closed
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ const config = {
test: /\.m?js$/,
// v-- currently using an experimental setting with esbuild-loader
//use: options.defaultLoaders.babel,
use: [{loader: 'esbuild-loader', options: { loader: 'jsx'}}],
use: [{loader: 'esbuild-loader', options: { loader: 'jsx', target: 'es2020' }}],
exclude: /node_modules/,
type: "javascript/auto",
resolve: {
Expand Down
30 changes: 30 additions & 0 deletions src/Playground.mjs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Generated by ReScript, PLEASE EDIT WITH CARE

import * as Eval from "./common/Eval.mjs";
import * as Icon from "./components/Icon.mjs";
import * as Meta from "./components/Meta.mjs";
import * as Next from "./bindings/Next.mjs";
Expand Down Expand Up @@ -1500,6 +1501,8 @@ function Playground$ControlPanel(Props) {
var dispatch = Props.dispatch;
var editorCode = Props.editorCode;
var router = Next.Router.useRouter(undefined);
var match = Eval.useEval(undefined);
var dispatchEval = match[1];
var children;
var exit = 0;
if (typeof state === "number") {
Expand Down Expand Up @@ -1529,6 +1532,28 @@ function Playground$ControlPanel(Props) {
[Symbol.for("name")]: "Format"
});
};
var onRunClick = function (evt) {
evt.preventDefault();
var getSuccessCompilationResult = function (result) {
if (result.TAG === /* Success */1) {
return result._0;
}

};
var x = ready.result;
if (typeof x === "number") {
console.log("nothing");
return ;
}
if (x.TAG === /* Conv */0) {
console.log("conv");
return ;
}
Belt_Option.map(getSuccessCompilationResult(x._0), (function (r) {
return Curry._1(dispatchEval, r.js_code);
}));

};
var createShareLink = function (param) {
var lang = ready.targetLang;
var params = lang >= 2 ? [] : [[
Expand All @@ -1551,6 +1576,11 @@ function Playground$ControlPanel(Props) {
}, React.createElement(Playground$ControlPanel$Button, {
children: "Format",
onClick: onFormatClick
})), React.createElement("div", {
className: "mr-2"
}, React.createElement(Playground$ControlPanel$Button, {
children: "Run",
onClick: onRunClick
})), React.createElement(Playground$ControlPanel$ShareButton, {
createShareLink: createShareLink,
actionIndicatorKey: actionIndicatorKey
Expand Down
19 changes: 19 additions & 0 deletions src/Playground.res
Original file line number Diff line number Diff line change
Expand Up @@ -1184,6 +1184,7 @@ module ControlPanel = {
~editorCode: React.ref<string>,
) => {
let router = Next.Router.useRouter()
let (evalState, dispatchEval) = Eval.useEval()
let children = switch state {
| Init => React.string("Initializing...")
| SwitchingCompiler(_, _, _) => React.string("Switching Compiler...")
Expand All @@ -1194,6 +1195,23 @@ module ControlPanel = {
dispatch(Format(editorCode.current))
}

let onRunClick = evt => {
ReactEvent.Mouse.preventDefault(evt)

let getSuccessCompilationResult = result =>
switch result {
| RescriptCompilerApi.CompilationResult.Success(r) => Some(r)
| _ => None
}

switch ready.result {
| FinalResult.Nothing => Js.log("nothing")
| FinalResult.Comp(x) =>
getSuccessCompilationResult(x)->Belt.Option.map(r => dispatchEval(r.js_code))->ignore
| FinalResult.Conv(_) => Js.log("conv")
}
}

let createShareLink = () => {
let params = switch ready.targetLang {
| Res => []
Expand All @@ -1216,6 +1234,7 @@ module ControlPanel = {
<div className="mr-2">
<Button onClick=onFormatClick> {React.string("Format")} </Button>
</div>
<div className="mr-2"> <Button onClick=onRunClick> {React.string("Run")} </Button> </div>
<ShareButton actionIndicatorKey createShareLink />
</>
| _ => React.null
Expand Down
3 changes: 3 additions & 0 deletions src/bindings/Webapi.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,13 @@ var ClassList = {};

var $$Element = {};

var Url = {};

export {
$$Document ,
ClassList ,
$$Element ,
Url ,

}
/* No side effect */
11 changes: 9 additions & 2 deletions src/bindings/Webapi.res
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ module Document = {
}

module ClassList = {
type t;
type t
@send external toggle: (t, string) => unit = "toggle"
}

Expand All @@ -15,11 +15,18 @@ module Element = {
@get external classList: Dom.element => ClassList.t = "classList"
}


type animationFrameId

@scope("window") @val
external requestAnimationFrame: (unit => unit) => animationFrameId = "requestAnimationFrame"

@scope("window") @val
external cancelAnimationFrame: animationFrameId => unit = "cancelAnimationFrame"

module Url = {
type t
@new external make: string => t = "URL"
@new external makeWithBase: (string, string) => t = "URL"

@send external toString: t => string = "toString"
}
8 changes: 4 additions & 4 deletions src/bindings/Worker.resi
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,16 @@ module Make: (Config: Config) =>
include Config

module App: {
let postMessage: (worker, fromApp) => unit
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without these changes I was getting type errors. I posted about it on the forum: https://forum.rescript-lang.org/t/regarding-src-bindings-worker-res-in-the-rescript-lang-org-repo/2004/2

let onMessage: (worker, {"data": fromWorker} => unit) => unit
let postMessage: (worker, Config.fromApp) => unit
let onMessage: (worker, {"data": Config.fromWorker} => unit) => unit
let onError: (worker, 'a => unit) => unit
let terminate: worker => unit
}

module Worker: {
type self
let postMessage: fromWorker => unit
let onMessage: (self, {"data": fromApp} => unit) => unit
let postMessage: Config.fromWorker => unit
let onMessage: (self, {"data": Config.fromApp} => unit) => unit
let self: self
let importScripts: string => unit
}
Expand Down
166 changes: 166 additions & 0 deletions src/common/Eval.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
// Generated by ReScript, PLEASE EDIT WITH CARE

import * as Curry from "rescript/lib/es6/curry.js";
import * as React from "react";
import * as $$Worker from "../bindings/Worker.mjs";
import * as Belt_Option from "rescript/lib/es6/belt_Option.js";
import * as Caml_option from "rescript/lib/es6/caml_option.js";

var source = "EvalSource";

function make(param) {
return $$Worker.make(new URL("./EvalWorker.mjs", import.meta.url).toString());
}

var Config = {
make: make
};

var EvalWorker = $$Worker.Make(Config);

function workerMessageToAction(message) {
var message$1 = message.result;
var forCode = message.forCode;
if (message$1.TAG === /* Ok */0) {
return {
TAG: 1,
forCode: forCode,
message: message$1._0,
[Symbol.for("name")]: "Success"
};
} else {
return {
TAG: 2,
forCode: forCode,
message: message$1._0,
[Symbol.for("name")]: "Fail"
};
}
}

function reducer(state, action) {
if (typeof state === "number") {
switch (action.TAG | 0) {
case /* Evaluate */0 :
return {
TAG: 0,
_0: action._0,
[Symbol.for("name")]: "Evaluating"
};
case /* Success */1 :
case /* Fail */2 :
return state;

}
} else {
switch (state.TAG | 0) {
case /* Evaluating */0 :
var code = state._0;
switch (action.TAG | 0) {
case /* Evaluate */0 :
return state;
case /* Success */1 :
if (action.forCode === code) {
return {
TAG: 1,
_0: action.message,
[Symbol.for("name")]: "Evaluated"
};
} else {
return state;
}
case /* Fail */2 :
if (action.forCode === code) {
return {
TAG: 2,
_0: action.message,
[Symbol.for("name")]: "Error"
};
} else {
return state;
}

}
case /* Evaluated */1 :
switch (action.TAG | 0) {
case /* Evaluate */0 :
return {
TAG: 0,
_0: action._0,
[Symbol.for("name")]: "Evaluating"
};
case /* Success */1 :
case /* Fail */2 :
return state;

}
case /* Error */2 :
switch (action.TAG | 0) {
case /* Evaluate */0 :
return {
TAG: 0,
_0: action._0,
[Symbol.for("name")]: "Evaluating"
};
case /* Success */1 :
case /* Fail */2 :
return state;

}

}
}
}

function useEval(param) {
var match = React.useReducer(reducer, /* Idle */0);
var dispatch = match[1];
var state = match[0];
var workerRef = React.useRef(undefined);
React.useEffect((function () {
workerRef.current = Caml_option.some(Curry._1(EvalWorker.make, undefined));
return (function (param) {
Belt_Option.map(workerRef.current, (function (worker) {
return Curry._1(EvalWorker.App.terminate, worker);
}));

});
}), []);
React.useEffect((function () {
var maybeWorker = workerRef.current;
if (typeof state !== "number" && state.TAG === /* Evaluating */0) {
var code = state._0;
Belt_Option.map(maybeWorker, (function (worker) {
return Curry._2(EvalWorker.App.postMessage, worker, {
source: source,
payload: {
_0: code,
[Symbol.for("name")]: "EvalMessage"
}
});
}));
}

}), [state]);
return [
state,
(function (code) {
return Curry._1(dispatch, {
TAG: 0,
_0: code,
[Symbol.for("name")]: "Evaluate"
});
})
];
}

export {
source ,
Config ,
EvalWorker ,
workerMessageToAction ,
reducer ,
useEval ,

}
/* EvalWorker Not a pure module */
Loading