git.iko.soy/rowtype-yoga/psfp
on master help sign in
Use Compiler
50f5e9dMark Eibes
blog/src/components/PSLayout.purs+17−9
@@ -1,7 +1,6 @@
1module PSLayout where
1module PSLayout where
2
2
3import Prelude
3import Prelude
4−
5import Data.Array as A
4import Data.Array as A
6import Data.Array as Array
5import Data.Array as Array
7import Data.Array.NonEmpty as NEA
6import Data.Array.NonEmpty as NEA
@@ -26,6 +25,7 @@ import Yoga.Box.Component as Box
26import Yoga.CompileEditor.Component (mkCompileEditor)
25import Yoga.CompileEditor.Component (mkCompileEditor)
27import Yoga.Compiler.Api (apiCompiler)
26import Yoga.Compiler.Api (apiCompiler)
28import Yoga.FillInTheGaps.Component as FillInTheGaps
27import Yoga.FillInTheGaps.Component as FillInTheGaps
28+import Yoga.FillInTheGaps.Logic (parseSegments)
29import Yoga.Header.Component (mkHeader)
29import Yoga.Header.Component (mkHeader)
30import Yoga.Helpers ((?||))
30import Yoga.Helpers ((?||))
31import Yoga.InlineCode.Component as InlineCode
31import Yoga.InlineCode.Component as InlineCode
@@ -83,7 +83,7 @@ mkLayout fetchImpl = do
83 ]
83 ]
84 }
84 }
85
85
86−mkSecret :: Effect ( ReactComponent { kids ∷ Array JSX , visible ∷ Boolean, register :: Effect Unit })
86+mkSecret ∷ Effect (ReactComponent { kids ∷ Array JSX, visible ∷ Boolean, register ∷ Effect Unit })
87mkSecret = do
87mkSecret = do
88 component "Secret" \{ kids, visible, register } -> React.do
88 component "Secret" \{ kids, visible, register } -> React.do
89 useEffect visible do
89 useEffect visible do
@@ -106,7 +106,7 @@ mkMdxProviderComponent ∷
106mkMdxProviderComponent fetchImpl = do
106mkMdxProviderComponent fetchImpl = do
107 cssBaseline <- mkCssBaseline
107 cssBaseline <- mkCssBaseline
108 editor <- mkCompileEditor fetchImpl
108 editor <- mkCompileEditor fetchImpl
109− fillInTheGaps <- FillInTheGaps.makeComponent (apiCompiler fetchImpl)
109+ fillInTheGaps <- FillInTheGaps.makeComponent
110 box <- Box.makeComponent
110 box <- Box.makeComponent
111 sidebar <- mkSidebar
111 sidebar <- mkSidebar
112 header <- mkHeader
112 header <- mkHeader
@@ -135,10 +135,14 @@ mkMdxProviderComponent fetchImpl = do
135 visibleThroughKey /\ updateVisible <- useState ""
135 visibleThroughKey /\ updateVisible <- useState ""
136 let
136 let
137 baseline child = element cssBaseline { kids: child }
137 baseline child = element cssBaseline { kids: child }
138+
138 kids = reactChildrenToArray children
139 kids = reactChildrenToArray children
140+
141+ visibleKids =
142+ spy "visibleKids"
139− visibleKids = spy "visibleKids" $ fromMaybe kids do
143+ $ fromMaybe kids do
140− i <- kids # A.findIndex (\x -> (unsafeCoerce x).key == visibleThroughKey)
144+ i <- kids # A.findIndex (\x -> (unsafeCoerce x).key == visibleThroughKey)
141− pure $ A.take (i+1) kids
145+ pure $ A.take (i + 1) kids
142
146
143 siteInfoJSX =
147 siteInfoJSX =
144 R.div
148 R.div
@@ -197,7 +201,11 @@ mkMdxProviderComponent fetchImpl = do
197
201
198 language = fromMaybe "" (classNameQ >>= String.stripPrefix (String.Pattern "language-"))
202 language = fromMaybe "" (classNameQ >>= String.stripPrefix (String.Pattern "language-"))
199 case isCode, language of
203 case isCode, language of
204+ true, "puregaps" ->
200− true, "puregaps" -> element fillInTheGaps { code: fromMaybe "" codeQ }
205+ element fillInTheGaps
206+ { initialSegments: parseSegments (codeQ ?|| "")
207+ , update: \segs -> pure unit
208+ }
201 true, _ ->
209 true, _ ->
202 element editor
210 element editor
203 { initialCode: fromMaybe "" codeQ
211 { initialCode: fromMaybe "" codeQ
@@ -206,10 +214,10 @@ mkMdxProviderComponent fetchImpl = do
206 }
214 }
207 false, _ -> element (unsafeCreateDOMComponent "pre") props
215 false, _ -> element (unsafeCreateDOMComponent "pre") props
208 }
216 }
209−
210 useEffect (A.length kids) do
217 useEffect (A.length kids) do
211− let
218+ let
212 firstGaps = kids # A.find (\x -> (unsafeCoerce x).props.mdxType == "pre" && ((unsafeCoerce x).props.children.props.className == "language-puregaps")) <#> (\x -> (unsafeCoerce x).key)
219 firstGaps = kids # A.find (\x -> (unsafeCoerce x).props.mdxType == "pre" && ((unsafeCoerce x).props.children.props.className == "language-puregaps")) <#> (\x -> (unsafeCoerce x).key)
220+
213 lastKey = kids # A.last # unsafeCoerce # _.key
221 lastKey = kids # A.last # unsafeCoerce # _.key
214 updateVisible (const (firstGaps ?|| lastKey))
222 updateVisible (const (firstGaps ?|| lastKey))
215 pure mempty
223 pure mempty
components/src/Yoga/CompileEditor/Component.purs+5−46
@@ -9,23 +9,19 @@ import Data.Interpolate (i)
9import Data.Maybe (Maybe(..))
9import Data.Maybe (Maybe(..))
10import Data.Tuple.Nested ((/\))
10import Data.Tuple.Nested ((/\))
11import Effect (Effect)
11import Effect (Effect)
12−import Effect.Aff (Aff, attempt, error, launchAff_, message, throwError)
12+import Effect.Aff (launchAff_)
13import Effect.Class (liftEffect)
13import Effect.Class (liftEffect)
14import JSS (jssClasses)
14import JSS (jssClasses)
15−import Milkis as M
16−import Milkis.Impl (FetchImpl)
17import React.Basic (ReactComponent)
15import React.Basic (ReactComponent)
18import React.Basic.DOM as R
16import React.Basic.DOM as R
19import React.Basic.Events (handler_)
17import React.Basic.Events (handler_)
20import React.Basic.Helpers (jsx)
18import React.Basic.Helpers (jsx)
21import React.Basic.Hooks (component, element, useState)
19import React.Basic.Hooks (component, element, useState)
22import React.Basic.Hooks as React
20import React.Basic.Hooks as React
23−import Shared.Json (readAff)
24−import Shared.Models.Body as Body
25−import Simple.JSON (writeJSON)
26import Yoga.Button.Component (ButtonType(..), mkButton)
21import Yoga.Button.Component (ButtonType(..), mkButton)
27import Yoga.Card.Component (mkCard)
22import Yoga.Card.Component (mkCard)
28import Yoga.Cluster.Component as Cluster
23import Yoga.Cluster.Component as Cluster
24+import Yoga.Compiler.Types (Compiler)
29import Yoga.Editor (getValue, mkEditor, setValue)
25import Yoga.Editor (getValue, mkEditor, setValue)
30import Yoga.Stack.Component as Stack
26import Yoga.Stack.Component as Stack
31import Yoga.Theme.Styles (makeStylesJSS)
27import Yoga.Theme.Styles (makeStylesJSS)
@@ -34,8 +30,8 @@ import Yoga.Theme.Types (CSSTheme)
34type Props
30type Props
35 = { initialCode ∷ String, height ∷ String, language ∷ String }
31 = { initialCode ∷ String, height ∷ String, language ∷ String }
36
32
37−mkCompileEditor ∷ FetchImpl -> Effect (ReactComponent Props)
33+mkCompileEditor ∷ ∀ r. { | Compiler r } -> Effect (ReactComponent Props)
38−mkCompileEditor fetch = do
34+mkCompileEditor { compileAndRun } = do
39 editor <- mkEditor
35 editor <- mkEditor
40 card <- mkCard
36 card <- mkCard
41 cluster <- Cluster.makeComponent
37 cluster <- Cluster.makeComponent
@@ -93,7 +89,7 @@ mkCompileEditor fetch = do
93 setCompileResult Nothing
89 setCompileResult Nothing
94 code <- getValue ed
90 code <- getValue ed
95 launchAff_ do
91 launchAff_ do
96− res <- compileAndRun (M.fetch fetch) { code }
92+ res <- compileAndRun { code }
97 setCompileResult (Just res) # liftEffect
93 setCompileResult (Just res) # liftEffect
98 pure
94 pure
99 $ jsx stack { space: "--s1" }
95 $ jsx stack { space: "--s1" }
@@ -118,40 +114,3 @@ mkCompileEditor fetch = do
118 }
114 }
119 [ R.text (compileResultToString compileResult) ]
115 [ R.text (compileResultToString compileResult) ]
120 ]
116 ]
121−
122−compileAndRun ∷ M.Fetch -> Body.CompileRequest -> Aff (Either Body.CompileResult Body.RunResult)
123−compileAndRun fetch body = do
124− response <-
125− attempt
126− $ fetch (M.URL "/api/compileAndRun")
127− { method: M.postMethod
128− , body: writeJSON body
129− , headers: M.makeHeaders { "Content-Type": "application/json" }
130− }
131− case response of
132− Left l ->
133− pure
134− ( Left
135− { resultType: ""
136− , result:
137− [ { allSpans: []
138− , errorCode: ""
139− , errorLink: ""
140− , filename: ""
141− , message: message l
142− , moduleName: Nothing
143− , position:
144− { endColumn: 0
145− , endLine: 0
146− , startColumn: 0
147− , startLine: 0
148− }
149− , suggestion: Nothing
150− }
151− ]
152− }
153− )
154− Right r -> case M.statusCode r of
155− 200 -> M.json r >>= readAff <#> Right
156− 422 -> M.json r >>= readAff <#> Left
157− code -> throwError (error $ "Unexpected response code " <> show code)
components/src/Yoga/CompileEditor/Stories.purs+10−4
@@ -1,17 +1,23 @@
1module Yoga.CompileEditor.Stories where
1module Yoga.CompileEditor.Stories where
2
2
3import Prelude hiding (add)
3import Prelude hiding (add)
4−import Yoga.CompileEditor.Component (mkCompileEditor)
4+import Data.Maybe (Maybe(..))
5−import Storybook.Decorator.FullScreen (fullScreenDecorator)
6import Effect (Effect)
5import Effect (Effect)
7−import Milkis.Impl.Window (windowFetch)
6+import Storybook.Decorator.FullScreen (fullScreenDecorator)
8import Storybook.React (Storybook, add, addDecorator, storiesOf)
7import Storybook.React (Storybook, add, addDecorator, storiesOf)
8+import Yoga.CompileEditor.Component (mkCompileEditor)
9+import Yoga.Compiler.Types (Compiler)
10+
11+compiler ∷ { | Compiler () }
12+compiler = { compileAndRun }
13+ where
14+ compileAndRun { code } = pure (pure { code: Nothing, stderr: "", stdout: "" })
9
15
10stories ∷ Effect Storybook
16stories ∷ Effect Storybook
11stories = do
17stories = do
12 storiesOf "Editor" do
18 storiesOf "Editor" do
13 addDecorator fullScreenDecorator
19 addDecorator fullScreenDecorator
14− add "The Editor" (mkCompileEditor windowFetch)
20+ add "The Editor" (mkCompileEditor compiler)
15 [ { initialCode
21 [ { initialCode
16 , height: "30vh"
22 , height: "30vh"
17 , language: "purescript"
23 , language: "purescript"
components/src/Yoga/InlineCode/Stories.purs+2−3
@@ -11,7 +11,6 @@ import Effect (Effect)
11import Effect.Aff (Aff)
11import Effect.Aff (Aff)
12import Effect.Console (log)
12import Effect.Console (log)
13import Justifill (justifill)
13import Justifill (justifill)
14−import Milkis as M
15import Milkis.Impl.Window (windowFetch)
14import Milkis.Impl.Window (windowFetch)
16import React.Basic (JSX, fragment)
15import React.Basic (JSX, fragment)
17import React.Basic.DOM as R
16import React.Basic.DOM as R
@@ -21,7 +20,7 @@ import React.Basic.Hooks (ReactComponent, component, element)
21import React.Basic.Hooks as React
20import React.Basic.Hooks as React
22import Storybook.Decorator.FullScreen (fullScreenDecorator)
21import Storybook.Decorator.FullScreen (fullScreenDecorator)
23import Storybook.React (Storybook, add, addDecorator, storiesOf)
22import Storybook.React (Storybook, add, addDecorator, storiesOf)
24−import Yoga.CompileEditor.Component (compileAndRun)
23+import Yoga.Compiler.Api (apiCompiler)
25import Yoga.InlineCode.Component as InlineCode
24import Yoga.InlineCode.Component as InlineCode
26import Yoga.Modal.Component as Modal
25import Yoga.Modal.Component as Modal
27
26
@@ -110,7 +109,7 @@ realReducer ∷ State -> RealAction -> Aff State
110realReducer state = case _ of
109realReducer state = case _ of
111 CloseModal -> pure Nothing
110 CloseModal -> pure Nothing
112 InlineCodeSubmitted code -> do
111 InlineCodeSubmitted code -> do
113− res <- compileAndRun (M.fetch windowFetch) { code: codePrefix <> code <> codeSuffix }
112+ res <- (apiCompiler windowFetch).compileAndRun { code: codePrefix <> code <> codeSuffix }
114 (pure <<< pure) case res of
113 (pure <<< pure) case res of
115 Right { stdout }
114 Right { stdout }
116 | String.dropRight 1 stdout == "Magick" -> true
115 | String.dropRight 1 stdout == "Magick" -> true