git.iko.soy/purestack-dev/todomvc
on master help sign in
Got backend interaction working
commit99438958ec44038678c13d6f95be5cd808cd49c0 authoriko <mail@iko.soy> dateSat 5 Jul 2025, 12:56 (1 year ago) parenta4c41d9
3 files changed+29−16
unifiedsplit
flake.nix+1−1 src/Frontend.purs+15−13 src/Plum.purs+13−2
flake.nix+1−1
@@ -39,7 +39,7 @@
3939 project-m36-rest.packages.${system}.default
4040 }/bin/project-m36-rest";
4141 proxy.command =
42− "${pkgs.reproxy}/bin/reproxy -l=localhost:3001 --static.enabled --static.rule='*,^/api/(.*),http://localhost:3000/$1' --assets.location=. --assets.spa";
42+ "${pkgs.reproxy}/bin/reproxy -l=localhost:3001 --static.enabled --static.rule='*,^/api/(.*),http://localhost:3000/$$1' --assets.location=. --assets.spa --logger.stdout";
4343 };
4444 });
4545 in {
src/Frontend.purs+15−13
@@ -7,30 +7,36 @@ import Prim
77
88import Data.Array ((:))
99import Data.Foldable (for_)
10−import Data.Maybe (Maybe(..))
1110import Data.URL as URL
1211import Effect (Effect)
1312import Plum as Plum
1413import PureStack.Client (client)
15−import Unsafe.Coerce (unsafeCoerce)
1614
17−type Model = { newTodo :: String, todos :: Array String }
15+type Model = { newTodo :: String, todos :: Array TodoItem }
1816
1917data Msg
2018 = UpdateNewTodo String
19+ | SetTodos (Array TodoItem)
2120 | AddNewTodo
2221 | TodoAdded
2322
2423main :: Effect Unit
2524main = do
25+ origin <- Plum.currentOrigin
26+ let api = getApi (origin `URL.addSegment` "api")
2627 Plum.run @Model @Msg "plum"
27− { init: \_runMsg -> pure { newTodo: "", todos: [] }
28+ { init: \runMsg -> do
29+ runMsg $ SetTodos <$> api.getTodos
30+ pure { newTodo: "", todos: [] }
2831 , update: \runMsg msg model -> case msg of
2932 UpdateNewTodo newTodo -> pure model { newTodo = newTodo }
3033 AddNewTodo -> do
3134 runMsg $ api.createTodo (TodoItem { text: model.newTodo, done: false }) $> TodoAdded
32− pure model { newTodo = "", todos = model.newTodo : model.todos }
33− TodoAdded -> pure model
35+ pure model
36+ TodoAdded -> do
37+ runMsg $ SetTodos <$> api.getTodos
38+ pure model
39+ SetTodos todos -> pure model { todos = todos }
3440 , view: \model -> column do
3541 font "sans-serif"
3642
@@ -46,13 +52,9 @@ main = do
4652
4753 onKey "Enter" AddNewTodo
4854
49− for_ model.todos $ \todo -> do
50− text todo mempty
55+ for_ model.todos $ \(TodoItem todo) -> do
56+ text todo.text mempty
5157 }
5258
53−url = case URL.fromString "http://localhost" of
54− Just x -> x
55− Nothing -> unsafeCoerce unit
56−
57−api = client @API url
59+getApi = client @API
5860
src/Plum.purs+13−2
@@ -1,13 +1,16 @@
1−module Plum (Plum, run) where
1+module Plum (Plum, run, currentOrigin) where
22
33import Prelude
44
55import Data.Array as Array
66import Data.Maybe (Maybe(..))
7+import Data.URL (URL)
8+import Data.URL as URL
79import Effect (Effect)
810import Effect.Aff (Aff, launchAff_)
911import Effect.Class (liftEffect)
1012import Effect.Console (log)
13+import Effect.Exception (throw)
1114import Effect.Ref as Ref
1215import Foreign.Object as Object
1316import Literals.Undefined (undefined)
@@ -17,8 +20,10 @@ import Unsafe.Coerce (unsafeCoerce)
1720import Untagged.Union (asOneOf)
1821import Web.DOM.NonElementParentNode (getElementById) as Web
1922import Web.HTML (window) as Web
23+import Web.HTML.Event.EventTypes (invalid)
2024import Web.HTML.HTMLDocument (toNonElementParentNode) as Web
21−import Web.HTML.Window (document) as Web
25+import Web.HTML.Location as Location
26+import Web.HTML.Window (document, location) as Web
2227
2328type Plum msg model =
2429 { init :: (Aff msg -> Effect Unit) -> Effect model
@@ -108,3 +113,9 @@ run id plum = do
108113outerStyle :: String
109114outerStyle = "html,body{height:100%;padding:0;margin:0;}"
110115
116+currentOrigin :: Effect URL
117+currentOrigin = do
118+ s <- Web.window >>= Web.location >>= Location.origin
119+ case URL.fromString s of
120+ Nothing -> throw "window.location.origin returned an invalid url"
121+ Just url -> pure url