git.iko.soy/rowtype-yoga/psfp
on master help sign in
Server called from backend
6f9bfc9Mark Eibes
.gitignore+2
@@ -30,3 +30,5 @@ playground/.psc*
30playground/.purs*
30playground/.purs*
31playground/.psa*
31playground/.psa*
32playground/.spago
32playground/.spago
33+
34+playground/src/Main.purs
client/.storybook/middleware.jsnew file+11
@@ -0,0 +1,11 @@
1+const express = require('express')
2+const request = require('request');
3+
4+const expressMiddleWare = router => {
5+ router.use('/api', (req, res) => {
6+ var url = "http://localhost:14188" + req.url;
7+ req.pipe(request({ qs:req.query, uri: url, json: true })).pipe(res);
8+ })
9+}
10+
11+module.exports = expressMiddleWare
client/spago.dhall+1
@@ -10,6 +10,7 @@ You can edit this file as you like.
10 , "debug"
10 , "debug"
11 , "effect"
11 , "effect"
12 , "matryoshka"
12 , "matryoshka"
13+ , "milkis"
13 , "psci-support"
14 , "psci-support"
14 , "pseudo-random"
15 , "pseudo-random"
15 , "react-basic"
16 , "react-basic"
client/src/Monaco/Editor.purs+6−21
@@ -5,19 +5,15 @@ import Prelude
5import CSS.Safer (cssSafer)
5import CSS.Safer (cssSafer)
6import Control.Promise (Promise)
6import Control.Promise (Promise)
7import Control.Promise as Promise
7import Control.Promise as Promise
8−import Data.Maybe (Maybe(..))
9−import Data.Nullable (notNull, null)
8+import Data.Nullable (Nullable, notNull)
10import Effect (Effect)
9import Effect (Effect)
11import Effect.Aff (Aff)
10import Effect.Aff (Aff)
12import Effect.Class (liftEffect)
11import Effect.Class (liftEffect)
13−import Effect.Class.Console (warn)
14import Effect.Uncurried (EffectFn2, mkEffectFn2)
12import Effect.Uncurried (EffectFn2, mkEffectFn2)
15import Foreign (Foreign, unsafeToForeign)
13import Foreign (Foreign, unsafeToForeign)
16import Prim.Row (class Union)
14import Prim.Row (class Union)
17import React.Basic (JSX, ReactComponent, element, fragment)
15import React.Basic (JSX, ReactComponent, element, fragment)
18−import React.Basic.DOM as R
16+import React.Basic.Hooks (Ref, component, writeRef)
19−import React.Basic.Events (handler_)
20−import React.Basic.Hooks (component, readRefMaybe, useRef, writeRef)
21import React.Basic.Hooks as React
17import React.Basic.Hooks as React
22import React.Basic.Hooks.Aff (useAff)
18import React.Basic.Hooks.Aff (useAff)
23import React.Helpers (wrapperDiv)
19import React.Helpers (wrapperDiv)
@@ -85,7 +81,7 @@ initEditor = do
85 registerLanguageImpl monaco "purescript" # liftEffect
81 registerLanguageImpl monaco "purescript" # liftEffect
86 setMonarchTokensProviderImpl monaco "purescript" purescriptSyntax # liftEffect
82 setMonarchTokensProviderImpl monaco "purescript" purescriptSyntax # liftEffect
87
83
88−mkEditor ∷ Effect (ReactComponent {})
84+mkEditor ∷ Effect (ReactComponent { editorRef ∷ Ref (Nullable _) })
89mkEditor = do
85mkEditor = do
90 useStyles <-
86 useStyles <-
91 makeStyles \(theme ∷ CSSTheme) ->
87 makeStyles \(theme ∷ CSSTheme) ->
@@ -100,25 +96,14 @@ mkEditor = do
100 , backgroundColor: theme.backgroundColour
96 , backgroundColor: theme.backgroundColour
101 }
97 }
102 }
98 }
103− component "Editor" \{} -> React.do
99+ component "Editor" \{ editorRef } -> React.do
104 classes <- useStyles
100 classes <- useStyles
105− ref <- useRef null
106 useAff unit initEditor
101 useAff unit initEditor
107 theme <- useTheme
102 theme <- useTheme
108 let themeName = if theme.isLight then lightThemeName else darkThemeName
103 let themeName = if theme.isLight then lightThemeName else darkThemeName
109 pure
104 pure
110 $ fragment
105 $ fragment
111− [ R.button
112− { onClick:
113− handler_ do
114− maybeEditor <- readRefMaybe ref
115− case maybeEditor of
116− Nothing -> pure unit
117− Just ed -> do
118− v <- getValue ed
119− warn $ "Value: " <> v
120− }
121− , wrapperDiv { className: classes.wrapper }
106+ [ wrapperDiv { className: classes.wrapper }
122 $ element editor
107 $ element editor
123 { theme: themeName
108 { theme: themeName
124 , options:
109 , options:
@@ -136,6 +121,6 @@ mkEditor = do
136 , language: "purescript"
121 , language: "purescript"
137 -- https://microsoft.github.io/monaco-editor/playground.html#extending-language-services-custom-languages
122 -- https://microsoft.github.io/monaco-editor/playground.html#extending-language-services-custom-languages
138 , editorDidMount:
123 , editorDidMount:
139− mkEffectFn2 \_ -> notNull >>> writeRef ref
124+ mkEffectFn2 \_ -> notNull >>> writeRef editorRef
140 }
125 }
141 ]
126 ]
client/stories/EditorStories.purs+69−2
@@ -2,15 +2,82 @@ module EditorStories where
2
2
3import Prelude hiding (add)
3import Prelude hiding (add)
4
4
5+import Data.Foldable (for_)
6+import Data.Nullable (null)
7+import Data.Tuple.Nested ((/\))
8+import Debug.Trace (spy)
5import Decorator.FullScreen (fullScreenDecorator)
9import Decorator.FullScreen (fullScreenDecorator)
6−import Editor (mkEditor)
10+import Editor (getValue, mkEditor)
7import Effect (Effect)
11import Effect (Effect)
12+import Effect.Aff (Aff, launchAff_)
13+import Effect.Class (liftEffect)
14+import Milkis as M
15+import Milkis.Impl.Window (windowFetch)
16+import React.Basic (ReactComponent)
17+import React.Basic.DOM as R
18+import React.Basic.Events (handler_)
19+import React.Basic.Hooks (component, element, fragment, readRefMaybe, useRef, useState)
20+import React.Basic.Hooks as React
21+import Shared.Json (readAff)
22+import Shared.Models.Body as Body
23+import Simple.JSON (writeJSON)
8import Storybook.React (Storybook, add, addDecorator, storiesOf)
24import Storybook.React (Storybook, add, addDecorator, storiesOf)
9
25
10stories ∷ Effect Storybook
26stories ∷ Effect Storybook
11stories = do
27stories = do
12 storiesOf "Editor" do
28 storiesOf "Editor" do
13 addDecorator fullScreenDecorator
29 addDecorator fullScreenDecorator
14− add "The Editor" mkEditor
30+ add "The Editor" mkCompileEditor
15 [ {}
31 [ {}
16 ]
32 ]
33+
34+mkCompileEditor ∷ Effect (ReactComponent {})
35+mkCompileEditor = do
36+ editor <- mkEditor
37+ component "StorybookEditor" \{} -> React.do
38+ editorRef <- useRef null
39+ compileResult /\ modifyCompileResult <- useState ""
40+ let
41+ setCompileResult = modifyCompileResult <<< const
42+ pure
43+ $ fragment
44+ [ R.button
45+ { children: pure $ R.text "Compile"
46+ , onClick:
47+ handler_ do
48+ maybeEditor <- (readRefMaybe editorRef)
49+ for_ maybeEditor \ed -> do
50+ code <- getValue ed
51+ launchAff_ do
52+ res <- compile { code }
53+ res2 <- run
54+ setCompileResult res2.stdout # liftEffect
55+
56+
57+ }
58+ , R.textarea
59+ { value: compileResult
60+ , disabled: true
61+ }
62+ , element editor { editorRef }
63+ ]
64+
65+fetch ∷ M.Fetch
66+fetch = M.fetch windowFetch
67+
68+compile ∷ Body.CompileRequest -> Aff Body.CompileResult
69+compile body = do
70+ fetch (M.URL "/api/compile")
71+ { method: M.postMethod
72+ , body: spy "Body" $ writeJSON body
73+ , headers: M.makeHeaders { "Content-Type": "application/json" }
74+ }
75+ >>= M.json
76+ >>= readAff
77+
78+run ∷ Aff Body.RunResult
79+run = do
80+ fetch (M.URL "/api/run")
81+ { method: M.postMethod }
82+ >>= M.json
83+ >>= readAff
playground/src/Main.purs+6−2
@@ -1,4 +1,8 @@
1module Main where
1module Main where
2+
2import Prelude
3import Prelude
3−import Effect.Console (log)
4+import Effect.Console
5+
4−main = log "Freddy"
6+main = log message
7+
8+message = "Du bist " <> show 7 <> " Jahre alt."