Shpadoinkle-backend-snabbdom 0.1.0.1 → 0.2.0.0
raw patch · 4 files changed
+47/−33 lines, 4 filesdep +ghcjs-domdep +unliftioPVP ok
version bump matches the API change (PVP)
Dependencies added: ghcjs-dom, unliftio
API changes (from Hackage documentation)
- Shpadoinkle.Backend.Snabbdom: instance (Language.Javascript.JSaddle.Types.MonadJSM m, GHC.Classes.Eq a) => Shpadoinkle.Backend (Shpadoinkle.Backend.Snabbdom.SnabbdomT a) m a
+ Shpadoinkle.Backend.Snabbdom: instance (Language.Javascript.JSaddle.Types.MonadJSM m, GHC.Classes.Eq a) => Shpadoinkle.Core.Backend (Shpadoinkle.Backend.Snabbdom.SnabbdomT a) m a
Files
- LICENSE +21/−20
- README.md +2/−2
- Shpadoinkle-backend-snabbdom.cabal +5/−3
- Shpadoinkle/Backend/Snabbdom.hs +19/−8
LICENSE view
@@ -1,26 +1,27 @@-Shpadoinkle Snabbdom, I think I know exactly what it means-Copyright © 2020 Isaac Shpaira+Shpadoinkle Snabbdom aka S11 Snabbdom+Copyright © 2020 Isaac Shapira All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:-1. Redistributions of source code must retain the above copyright-notice, this list of conditions and the following disclaimer.-2. Redistributions in binary form must reproduce the above copyright-notice, this list of conditions and the following disclaimer in the-documentation and/or other materials provided with the distribution.-3. Neither the name of the <`3:organization`> nor the-names of its contributors may be used to endorse or promote products-derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY <|2|> ''AS IS'' AND ANY-EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE-DISCLAIMED. IN NO EVENT SHALL <|2|> BE LIABLE FOR ANY-DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND-ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.+ * Redistributions of source code must retain the above copyright notice,+ this list of conditions and the following disclaimer.+ * Redistributions in binary form must reproduce the above copyright+ notice, this list of conditions and the following disclaimer in the+ documentation and/or other materials provided with the distribution.+ * Neither the name of Shpadoinkle nor the names of its contributors may be+ used to endorse or promote products derived from this software without+ specific prior written permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE+POSSIBILITY OF SUCH DAMAGE.
README.md view
@@ -1,6 +1,7 @@ # Shpadoinkle Backend Snabbdom [](https://gitlab.com/fresheyeball/Shpadoinkle)+[](https://shpadoinkle.org/backend-snabbdom) [](https://opensource.org/licenses/BSD-3-Clause) [](https://builtwithnix.org) [](https://hackage.haskell.org/package/Shpadoinkle-backend-snabbdom)@@ -11,8 +12,7 @@ > Snabbdom consists of an extremely simple, performant, and extensible core that is only ≈ 200 SLOC. It offers a modular architecture with rich functionality for extensions through custom modules. To keep the core simple, all non-essential functionality is delegated to modules. -These design decisions made Snabbdom a good fit for Shpadoinkle's first high-performance pure JavaScript backend. Right now Snabbdom is being provided via [CloudFlare](https://cdnjs.com/) content delivery network (CDN) and is not included in this repo. This is great for getting started fast and having a transparent developer experience where you can simply switch to the backend of your choosing. However, this is not a stable long term approach as the CDN artifact could be removed at any time. If you wish to use Snabbdom in production, I recommend either:+These design decisions made Snabbdom a good fit for Shpadoinkle's first high-performance pure JavaScript backend. Right now Snabbdom is being provided using [CloudFlare](https://cdnjs.com/) content delivery network (CDN) and is not included in this repo. This is great for getting started fast and having a transparent developer experience where you can simply switch to the backend of your choosing. However, this is not a stable long term approach as the CDN artifact could be removed at any time. If you wish to use Snabbdom in production, I recommend either: - Proactively monitoring the CDN endpoints - Wrap `SnabbdomT` in your own `newtype` and overriding the `setup` method in the `Backend` instance with a mechanism where you provide Snabbdom's JavaScript artifacts yourself.-
Shpadoinkle-backend-snabbdom.cabal view
@@ -4,12 +4,12 @@ -- -- see: https://github.com/sol/hpack ----- hash: 8d640457d8dcfbf7edf0ce733ba9d6c10d9beb6d8c62b7bbd10c0a294a0f2cb7+-- hash: 6ac6720a8444015edf2b03ef30437c3c9ec703c559e4c205e6e1145bca8bdf91 name: Shpadoinkle-backend-snabbdom-version: 0.1.0.1+version: 0.2.0.0 synopsis: Use the high-performance Snabbdom virtual dom library written in JavaScript.-description: Snabbdom is a battle-tested virtual dom library for JavaScript. It's extremely fast, lean, and modular. Snabbdom's design made it a natural choice for a Shpadoinkle rendering backend, as it has a similar core philosophy of "just don't do much" and is friendly to purely functional binding.+description: Snabbdom is a battle-tested virtual DOM library for JavaScript. It's extremely fast, lean, and modular. Snabbdom's design makes Snabbdom a natural choice for a Shpadoinkle rendering backend, as it has a similar core philosophy of "just don't do much" and is friendly to purely functional binding. category: Web author: Isaac Shapira maintainer: fresheyeball@protonmail.com@@ -37,7 +37,9 @@ Shpadoinkle , base >=4.12.0 && <4.16 , file-embed >=0.0.11 && <0.1+ , ghcjs-dom >=0.9.4 && <0.20 , jsaddle >=0.9.7 && <0.20 , mtl >=2.2.2 && <2.3 , text >=1.2.3 && <1.3+ , unliftio >=0.2.12 && <0.3 default-language: Haskell2010
Shpadoinkle/Backend/Snabbdom.hs view
@@ -9,26 +9,34 @@ {-# LANGUAGE RankNTypes #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TupleSections #-} {-# LANGUAGE TypeApplications #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-} {-# OPTIONS_GHC -fno-warn-type-defaults #-} +{-|+ This module provides the 'Backend' binding for the JavaScript virtual DOM implementation <https://github.com/snabbdom/snabbdom Snabbdom>.+-}++ module Shpadoinkle.Backend.Snabbdom ( SnabbdomT (..) , runSnabbdom , stage ) where + import Control.Category import Control.Monad.Reader import Data.FileEmbed import Data.Text import Data.Traversable-import GHC.Conc-import Language.Javascript.JSaddle hiding (( # ))-import Prelude hiding ((.))+import GHCJS.DOM.Types (JSM, MonadJSM, liftJSM)+import Language.Javascript.JSaddle hiding (( # ), JSM, MonadJSM, liftJSM)+import Prelude hiding (id, (.))+import UnliftIO.STM (TVar) import Shpadoinkle hiding (children, name, props) @@ -50,11 +58,12 @@ #endif +-- | 'SnabbdomT' is a @newtype@ of 'ReaderT', this is the 'runReaderT' equivalent. runSnabbdom :: TVar model -> SnabbdomT model m a -> m a runSnabbdom t (Snabbdom r) = runReaderT r t -props :: (m ~> JSM) -> TVar a -> [(Text, Prop (SnabbdomT a m) a)] -> JSM Object+props :: Monad m => (m ~> JSM) -> TVar a -> [(Text, Prop (SnabbdomT a m) a)] -> JSM Object props toJSM i xs = do o <- create a <- create@@ -65,14 +74,15 @@ t' <- toJSVal t true <- toJSVal True case k of- "className" | t /= "" -> unsafeSetProp (toJSString t) true c+ "className" | t /= "" -> forM_ (split (== ' ') t) $ \u -> unsafeSetProp (toJSString u) true c _ -> unsafeSetProp (toJSString k) t' a PListener f -> do f' <- toJSVal . fun $ \_ _ -> \case [] -> return () ev:_ -> do rn <- unsafeGetProp "target" =<< valToObject ev- liftIO . atomically . writeTVar i =<< (toJSM . runSnabbdom i) (f (RawNode rn) (RawEvent ev))+ x <- f (RawNode rn) (RawEvent ev)+ writeUpdate i $ hoist (toJSM . runSnabbdom i) x unsafeSetProp (toJSString k) f' e PFlag b -> do f <- toJSVal b@@ -124,12 +134,13 @@ where f' = maybe r unVNode f - setup :: JSM () -> SnabbdomT a m ()- setup cb = liftJSM $ do+ setup :: JSM () -> JSM ()+ setup cb = do void $ eval @Text $(embedStringFile "Shpadoinkle/Backend/Snabbdom/Setup.js") void . jsg1 "startApp" . fun $ \_ _ _ -> cb +-- | Get the @window.container@ DOM node produced by 'setup' (@Setup.js@). stage :: MonadJSM m => SnabbdomT a m RawNode stage = liftJSM $ fromJSValUnchecked =<< jsg "container"