miso 0.1.4.0 → 0.1.5.0
raw patch · 6 files changed
+133/−15 lines, 6 filesnew-component:exe:routerPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
Files
- README.md +4/−1
- examples/router/Main.hs +80/−0
- ghcjs-src/Miso.hs +3/−1
- ghcjs-src/Miso/Router.hs +1/−1
- ghcjs-src/Miso/Subscription/History.hs +27/−11
- miso.cabal +18/−1
README.md view
@@ -30,7 +30,7 @@ </a> </p> -**Miso** is a small "[isomorphic](http://nerds.airbnb.com/isomorphic-javascript-future-web-apps/)" [Haskell](https://www.haskell.org/) front-end framework featuring a virtual-dom, diffing / patching algorithm, event delegation, event batching, SVG, Server-sent events, Websockets, and an extensible Subscription-based subsystem. Inspired by [Elm](http://elm-lang.org/), [Redux](http://redux.js.org/) and [Bobril](http://github.com/bobris/bobril). `IO` and other effects (like `XHR`) can be introduced into the system via the `Effect` data type. Miso makes heavy use of the [GHCJS](https://github.com/ghcjs/ghcjs) FFI and therefore has minimal dependencies.+**Miso** is a small "[isomorphic](http://nerds.airbnb.com/isomorphic-javascript-future-web-apps/)" [Haskell](https://www.haskell.org/) front-end framework featuring a virtual-dom, diffing / patching algorithm, event delegation, event batching, SVG, Server-sent events, Websockets, type-safe [servant](https://haskell-servant.github.io/)-style routing and an extensible Subscription-based subsystem. Inspired by [Elm](http://elm-lang.org/), [Redux](http://redux.js.org/) and [Bobril](http://github.com/bobris/bobril). `IO` and other effects (like `XHR`) can be introduced into the system via the `Effect` data type. Miso makes heavy use of the [GHCJS](https://github.com/ghcjs/ghcjs) FFI and therefore has minimal dependencies. ## Examples - TodoMVC@@ -42,6 +42,9 @@ - Websocket - [Link](https://websocket.haskell-miso.org/) - [Source](https://github.com/dmjio/miso/blob/master/examples/websocket/Main.hs)+ - Router+ - [Link](https://router.haskell-miso.org/)+ - [Source](https://github.com/dmjio/miso/blob/master/examples/router/Main.hs) - SVG - [Link](https://svg.haskell-miso.org/) - Simple
+ examples/router/Main.hs view
@@ -0,0 +1,80 @@+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE TypeFamilies #-}+module Main where++import Data.Proxy+import Servant.API++import Miso++-- | Model+data Model+ = Model+ { uri :: URI+ -- ^ current URI of application+ } deriving (Eq, Show)++-- | Action+data Action+ = HandleURI URI+ | ChangeURI URI+ | NoOp+ deriving (Show, Eq)++-- | Main entry point+main :: IO ()+main = do+ currentRoute <- getURI+ startApp App { model = Model currentRoute, ..}+ where+ update = updateModel+ events = defaultEvents+ subs = [ uriSub HandleURI ]+ view = viewModel++-- | Update your model+updateModel :: Action -> Model -> Effect Model Action+updateModel (HandleURI u) m = m { uri = u } <# do+ pure NoOp+updateModel (ChangeURI u) m = m <# do+ pushURI u+ pure NoOp+updateModel _ m = noEff m++-- | View function, with routing+viewModel :: Model -> View Action+viewModel Model {..} =+ case runRoute uri (Proxy :: Proxy API) handlers of+ Left _ -> the404+ Right v -> v+ where+ handlers = about :<|> home+ home = div_ [] [+ div_ [] [ text "home" ]+ , button_ [ onClick goAbout ] [ text "go about" ]+ ]+ about = div_ [] [+ div_ [] [ text "about" ]+ , button_ [ onClick goHome ] [ text "go home" ]+ ]+ the404 = div_ [] [+ text "the 404 :("+ , button_ [ onClick goHome ] [ text "go home" ]+ ]++-- | Type-level routes+type API = About :<|> Home+type Home = View Action+type About = "about" :> View Action++-- | Type-safe links used in `onClick` event handlers to route the application+goAbout, goHome :: Action+(goHome, goAbout) = (goto api home, goto api about)+ where+ goto a b = ChangeURI (safeLink a b)+ home = Proxy :: Proxy Home+ about = Proxy :: Proxy About+ api = Proxy :: Proxy API+
ghcjs-src/Miso.hs view
@@ -19,6 +19,7 @@ , module Miso.Html , module Miso.Subscription , module Miso.Types+ , module Miso.Router ) where import Control.Concurrent@@ -30,13 +31,14 @@ import JavaScript.Web.AnimationFrame import Miso.Concurrent+import Miso.Delegate import Miso.Diff import Miso.Effect import Miso.Event import Miso.Html+import Miso.Router import Miso.Subscription import Miso.Types-import Miso.Delegate -- | Runs a miso application startApp :: Eq model => App model action -> IO ()
ghcjs-src/Miso/Router.hs view
@@ -18,7 +18,7 @@ -- Stability : experimental -- Portability : non-portable -----------------------------------------------------------------------------module Miso.Router where+module Miso.Router ( runRoute, RoutingError(..) ) where import qualified Data.ByteString.Char8 as BS import Data.Proxy
ghcjs-src/Miso/Subscription/History.hs view
@@ -20,12 +20,17 @@ , forward , go , uriSub+ , URI (..) ) where -import Miso.String+import Control.Concurrent+import Control.Monad import GHCJS.Foreign.Callback-import Network.URI hiding (path)-import Miso.Html.Internal ( Sub )+import Miso.Concurrent+import Miso.Html.Internal ( Sub )+import Miso.String+import Network.URI hiding (path)+import System.IO.Unsafe -- | Retrieves current URI of page getURI :: IO URI@@ -40,7 +45,7 @@ -- | Pushes a new URI onto the History stack pushURI :: URI -> IO () {-# INLINE pushURI #-}-pushURI uri = pushStateNoModel uri { uriPath = path }+pushURI uri = pushStateNoModel uri { uriPath = path } >> notify chan where path | uriPath uri == mempty = "/" | otherwise = uriPath uri@@ -48,7 +53,7 @@ -- | Replaces current URI on stack replaceURI :: URI -> IO () {-# INLINE replaceURI #-}-replaceURI uri = replaceTo' uri { uriPath = path }+replaceURI uri = replaceTo' uri { uriPath = path } >> notify chan where path | uriPath uri == mempty = "/" | otherwise = uriPath uri@@ -66,14 +71,21 @@ -- | Jumps to a specific position in history go :: Int -> IO () {-# INLINE go #-}-go = go'+go n = go' n +chan :: Notify+{-# NOINLINE chan #-}+chan = unsafePerformIO newNotify+ -- | Subscription for `popState` events, from the History API uriSub :: (URI -> action) -> Sub action model-uriSub = \f _ sink ->+uriSub = \f _ sink -> do+ void.forkIO.forever $ do+ wait chan >> do+ sink =<< f <$> getURI onPopState =<< do- ps <- f <$> getURI- asyncCallback $ sink ps+ asyncCallback $ do+ sink =<< f <$> getURI foreign import javascript unsafe "window.history.go($1);" go' :: Int -> IO ()@@ -101,8 +113,12 @@ pushStateNoModel :: URI -> IO () {-# INLINE pushStateNoModel #-}-pushStateNoModel = pushStateNoModel' . pack . show+pushStateNoModel u = do+ pushStateNoModel' . pack . show $ u+ notify chan replaceTo' :: URI -> IO () {-# INLINE replaceTo' #-}-replaceTo' = replaceState' . pack . show+replaceTo' u = do+ replaceState' . pack . show $ u+ notify chan
miso.cabal view
@@ -1,5 +1,5 @@ name: miso-version: 0.1.4.0+version: 0.1.5.0 category: Web, Miso, Data Structures license: BSD3 license-file: LICENSE@@ -50,6 +50,23 @@ base < 5, containers, miso+ default-language:+ Haskell2010++executable router+ main-is:+ Main.hs+ if !impl(ghcjs) || !flag(examples)+ buildable: False+ else+ hs-source-dirs:+ examples/router+ build-depends:+ aeson,+ base < 5,+ containers,+ miso,+ servant default-language: Haskell2010