git.iko.soy/rowtype-yoga/psfp
on master help sign in
Huh
commitcf0f24c5c7c6580f0bbeb68a935ec8f57e023e35 authorMark Eibes <mark.eibes@gmail.com> dateThu 21 Jan 2021, 21:09 (6 years ago) parent491e24e
4 files changed+184
client/src/Main.js+22 client/src/Main.purs+46 client/src/Monaco/Editor/Component.purs+77 server/src/Playground/Handler.purs+39
client/src/Main.jsnew file+22
@@ -0,0 +1,22 @@
1+'use strict';
2+
3+var ReactDOMServer = require('react-dom/server');
4+var ReactDOM = require('react-dom');
5+
6+exports.isServerSide = typeof document === 'undefined';
7+
8+exports.renderToString = ReactDOMServer.renderToString;
9+
10+exports.createRoot = function(elem) {
11+ return function() {
12+ return ReactDOM.createRoot(elem);
13+ }
14+}
15+
16+exports.renderRoot = function(component) {
17+ return function(root) {
18+ return function() {
19+ root.render(component)
20+ }
21+ }
22+}
client/src/Main.pursnew file+46
@@ -0,0 +1,46 @@
1+module Example (main) where
2+
3+import Prelude
4+import Container.Component (mkContainer)
5+import Data.Maybe (fromJust)
6+import Effect (Effect)
7+import Effect.Console (log)
8+import Partial.Unsafe (unsafePartial)
9+import React.Basic (JSX, element)
10+import Theme (fromTheme)
11+import Theme.Default (darkTheme)
12+import Web.DOM (Element)
13+import Web.DOM.NonElementParentNode (getElementById) as DOM
14+import Web.HTML (window) as DOM
15+import Web.HTML.HTMLDocument (toNonElementParentNode) as DOM
16+import Web.HTML.Window (document) as DOM
17+
18+main ∷ Effect Unit
19+main = do
20+ container <- mkContainer
21+ let
22+ appEl = element container { theme: fromTheme darkTheme, children: [] }
23+ if isServerSide then
24+ void (log (renderToString appEl))
25+ else
26+ void do
27+ window <- DOM.window
28+ document <- DOM.document window
29+ let
30+ node = DOM.toNonElementParentNode document
31+ elem <- DOM.getElementById "app" node
32+ let
33+ element' = unsafePartial (fromJust elem)
34+ root <- createRoot element'
35+ renderRoot appEl root
36+
37+-- ReactDOM.render appEl element'
38+foreign import isServerSide ∷ Boolean
39+
40+foreign import renderToString ∷ JSX -> String
41+
42+foreign import data ReactRoot ∷ Type
43+
44+foreign import createRoot ∷ Element -> Effect ReactRoot
45+
46+foreign import renderRoot ∷ JSX -> ReactRoot -> Effect Unit
client/src/Monaco/Editor/Component.pursnew file+77
@@ -0,0 +1,77 @@
1+module Editor.Component where
2+
3+import Prelude
4+import CSS.Safer (cssSafer)
5+import Data.Nullable (Nullable, notNull)
6+import Editor (defineThemeImpl, editor, initMonaco, nightOwlTheme, purescriptSyntax, registerLanguageImpl, setMonarchTokensProviderImpl, vsCodeTheme)
7+import Effect (Effect)
8+import Effect.Aff (Aff)
9+import Effect.Class (liftEffect)
10+import Effect.Uncurried (mkEffectFn2)
11+import Foreign (unsafeToForeign)
12+import React.Basic (ReactComponent, element, fragment)
13+import React.Basic.Hooks (Ref, component, writeRef)
14+import React.Basic.Hooks as React
15+import React.Basic.Hooks.Aff (useAff)
16+import React.Helpers (wrapperDiv)
17+import Theme.Styles (makeStyles, useTheme)
18+import Theme.Types (CSSTheme)
19+
20+darkThemeName ∷ String
21+darkThemeName = "NightOwl"
22+
23+lightThemeName ∷ String
24+lightThemeName = "VSCode"
25+
26+initEditor ∷ Aff Unit
27+initEditor = do
28+ monaco <- initMonaco
29+ defineThemeImpl monaco darkThemeName nightOwlTheme # liftEffect
30+ defineThemeImpl monaco lightThemeName vsCodeTheme # liftEffect
31+ registerLanguageImpl monaco "purescript" # liftEffect
32+ setMonarchTokensProviderImpl monaco "purescript" purescriptSyntax # liftEffect
33+
34+mkEditor ∷ Effect (ReactComponent { editorRef ∷ Ref (Nullable _) })
35+mkEditor = do
36+ useStyles <-
37+ makeStyles \(theme ∷ CSSTheme) ->
38+ { wrapper:
39+ cssSafer
40+ { margin: "0"
41+ , boxSizing: "border-box"
42+ , padding: "35px 40px"
43+ , width: "100%"
44+ , height: "100%"
45+ , borderRadius: "32px"
46+ , backgroundColor: theme.backgroundColour
47+ }
48+ }
49+ component "Editor" \{ editorRef } -> React.do
50+ classes <- useStyles
51+ useAff unit initEditor
52+ theme <- useTheme
53+ let
54+ themeName = if theme.isLight then lightThemeName else darkThemeName
55+ pure
56+ $ fragment
57+ [ wrapperDiv { className: classes.wrapper }
58+ $ element editor
59+ { theme: themeName
60+ , options:
61+ unsafeToForeign
62+ { fontFamily: "PragmataPro"
63+ , fontLigatures: true
64+ , fontSize: "16pt"
65+ , lineNumbers: "off"
66+ , glyphMargin: false
67+ , folding: false
68+ , lineDecorationsWidth: 0
69+ , lineNumbersMinChars: 0
70+ , minimap: { enabled: false }
71+ }
72+ , language: "purescript"
73+ -- https://microsoft.github.io/monaco-editor/playground.html#extending-language-services-custom-languages
74+ , editorDidMount:
75+ mkEffectFn2 \_ -> notNull >>> writeRef editorRef
76+ }
77+ ]
server/src/Playground/Handler.pursnew file+39
@@ -0,0 +1,39 @@
1+module Playground.Handler where
2+
3+import Prelude
4+
5+import Data.Maybe (Maybe)
6+import Effect.Aff.Class (liftAff)
7+import Effect.Class (class MonadEffect, liftEffect)
8+import Node.Buffer (Buffer)
9+import Node.Buffer as Buffer
10+import Node.Encoding (Encoding(..))
11+import Node.Express.Handler (HandlerM)
12+import Node.Express.Request (getBody')
13+import Node.Express.Response as Response
14+import Playground.Playground (asErrorWithCode, compileCode, runCode)
15+import Shared.Json (readAff)
16+import Shared.Models.Body (RunResult)
17+import Shared.Models.Body as Body
18+import Simple.JSON (write)
19+
20+toBody ∷ ∀ r m. MonadEffect m => { stdout ∷ Buffer, stderr ∷ Buffer | r } -> m RunResult
21+toBody result = liftEffect $ ado
22+ stdout <- Buffer.toString UTF8 result.stdout
23+ stderr <- Buffer.toString UTF8 result.stderr
24+ let (code ∷ Maybe Int) = asErrorWithCode result >>= _.code
25+ in { code, stdout, stderr } ∷ RunResult
26+
27+compileHandler ∷ HandlerM Unit
28+compileHandler = do
29+ body <- getBody'
30+ json <- readAff body # liftAff
31+ result <- compileCode (json ∷ Body.CompileRequest).code # liftAff
32+ Response.send $ write ({ result } ∷ Body.CompileResult)
33+
34+runHandler ∷ HandlerM Unit
35+runHandler = do
36+ result <- liftAff do
37+ result <- runCode
38+ toBody result
39+ Response.send $ write (result ∷ Body.RunResult)