datastar-hs 0.1.0.1 → 0.1.0.2
raw patch · 6 files changed
+118/−7 lines, 6 filesdep +lucid2dep ~aesondep ~basedep ~bytestringnew-component:exe:e2e-serverPVP ok
version bump matches the API change (PVP)
Dependencies added: lucid2
Dependency ranges changed: aeson, base, bytestring, http-types, text, wai, warp
API changes (from Hackage documentation)
Files
- CHANGELOG.md +5/−0
- datastar-hs.cabal +25/−1
- e2e-server/Main.hs +83/−0
- src/Hypermedia/Datastar.hs +2/−2
- src/Hypermedia/Datastar/WAI.hs +2/−3
- test/Hypermedia/Datastar/SSESpec.hs +1/−1
CHANGELOG.md view
@@ -1,5 +1,10 @@ # Changelog +## 0.1.0.2++* Bump to Datastar RC.8+* Add end-to-end testing with Playwright+ ## 0.1.0.1 * Add example apps: hello-world (warp/servant/channel), activity-feed, heap-view
datastar-hs.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.0 name: datastar-hs-version: 0.1.0.1+version: 0.1.0.2 synopsis: Haskell bindings for Datastar description: Server-side SDK for building real-time hypermedia applications with@@ -43,6 +43,30 @@ , http-types >= 0.12 && < 1 , text >= 1.2 && < 3 , wai >= 3.2 && < 4++executable e2e-server+ hs-source-dirs: e2e-server+ main-is: Main.hs+ build-depends:+ , base+ , aeson+ , bytestring+ , datastar-hs+ , http-types+ , lucid2+ , text+ , warp+ , wai+ default-language: Haskell2010+ default-extensions:+ DeriveGeneric+ DeriveAnyClass+ DerivingStrategies+ ImportQualifiedPost+ OverloadedStrings+ ScopedTypeVariables+ ghc-options: -threaded+ test-suite datastar-hs-test type: exitcode-stdio-1.0
+ e2e-server/Main.hs view
@@ -0,0 +1,83 @@+module Main where++import Data.Aeson (FromJSON)+import Data.ByteString.Lazy qualified as LBS+import Data.Text qualified as T+import GHC.Generics (Generic)+import Hypermedia.Datastar+import Lucid+import Lucid.Base (makeAttributes)+import Network.HTTP.Types (status200, status404)+import Network.Wai qualified as WAI+import Network.Wai.Handler.Warp qualified as Warp++newtype Greeting = Greeting {greeting :: T.Text}+ deriving (Generic)+ deriving anyclass (FromJSON)++app :: WAI.Request -> (WAI.Response -> IO b) -> IO b+app req respond = case (WAI.requestMethod req, WAI.pathInfo req) of+ ("GET", []) ->+ respond $ WAI.responseLBS status200 [("Content-Type", "text/html")] testPage+ ("GET", ["sse", "patch-elements"]) ->+ respond $ sseResponse nullLogger $ \gen ->+ sendPatchElements gen (patchElements "<div id=\"pe-result\">Patched Content</div>")+ ("GET", ["sse", "patch-signals"]) ->+ respond $ sseResponse nullLogger $ \gen ->+ sendPatchSignals gen (patchSignals "{\"message\":\"Signal Updated\"}")+ ("GET", ["sse", "execute-script"]) ->+ respond $ sseResponse nullLogger $ \gen ->+ sendExecuteScript gen (executeScript "document.getElementById('es-result').textContent = 'Script Executed'")+ ("GET", ["sse", "read-signals"]) ->+ respond $ sseResponse nullLogger $ \gen -> do+ result <- readSignals req+ case result of+ Right (signals :: Greeting) ->+ sendPatchElements gen (patchElements ("<div id=\"rs-result\">" <> greeting signals <> "</div>"))+ Left err ->+ sendPatchElements gen (patchElements ("<div id=\"rs-result\">Error: " <> T.pack err <> "</div>"))+ ("GET", ["sse", "multiple-events"]) ->+ respond $ sseResponse nullLogger $ \gen -> do+ sendPatchElements gen (patchElements "<div id=\"me-result\">Event 1</div>")+ sendPatchElements gen (patchElements "<div id=\"me-result\">Event 2</div>")+ sendPatchElements gen (patchElements "<div id=\"me-result\">Event 3</div>")+ _ ->+ respond $ WAI.responseLBS status404 [] "Not found"++testPage :: LBS.ByteString+testPage = renderBS $ doctypehtml_ $ do+ head_ $ do+ title_ "datastar-hs e2e tests"+ script_ [type_ "module", src_ "https://cdn.jsdelivr.net/gh/starfederation/datastar@1.0.0-RC.8/bundles/datastar.js"] ("" :: T.Text)+ body_ [makeAttributes "data-signals" "{}"] $ do+ h1_ "datastar-hs E2E Test Page"++ section_ [id_ "patch-elements-test"] $ do+ h2_ "Patch Elements"+ button_ [id_ "pe-trigger", makeAttributes "data-on:click" "@get('/sse/patch-elements')"] "Trigger"+ div_ [id_ "pe-result"] "Waiting..."++ section_ [id_ "patch-signals-test", makeAttributes "data-signals:message" "'Waiting...'"] $ do+ h2_ "Patch Signals"+ button_ [id_ "ps-trigger", makeAttributes "data-on:click" "@get('/sse/patch-signals')"] "Trigger"+ div_ [id_ "ps-result", makeAttributes "data-text" "$message"] "Waiting..."++ section_ [id_ "execute-script-test"] $ do+ h2_ "Execute Script"+ button_ [id_ "es-trigger", makeAttributes "data-on:click" "@get('/sse/execute-script')"] "Trigger"+ div_ [id_ "es-result"] "Waiting..."++ section_ [id_ "read-signals-test", makeAttributes "data-signals:greeting" "'Hello from Browser'"] $ do+ h2_ "Read Signals"+ button_ [id_ "rs-trigger", makeAttributes "data-on:click" "@get('/sse/read-signals')"] "Trigger"+ div_ [id_ "rs-result"] "Waiting..."++ section_ [id_ "multiple-events-test"] $ do+ h2_ "Multiple Events"+ button_ [id_ "me-trigger", makeAttributes "data-on:click" "@get('/sse/multiple-events')"] "Trigger"+ div_ [id_ "me-result"] "Waiting..."++main :: IO ()+main = do+ putStrLn "e2e-server running on http://localhost:3113"+ Warp.run 3113 app
src/Hypermedia/Datastar.hs view
@@ -76,13 +76,14 @@ , isDatastarRequest -- * Logger- , DatastarLogger(..)+ , DatastarLogger (..) , nullLogger , stderrLogger ) where import Hypermedia.Datastar.ExecuteScript (ExecuteScript (..), executeScript)+import Hypermedia.Datastar.Logger (DatastarLogger, nullLogger, stderrLogger) import Hypermedia.Datastar.PatchElements (PatchElements (..), patchElements, removeElements) import Hypermedia.Datastar.PatchSignals (PatchSignals (..), patchSignals) import Hypermedia.Datastar.Types (ElementNamespace (..), ElementPatchMode (..), EventType (..))@@ -95,4 +96,3 @@ , sendPatchSignals , sseResponse )-import Hypermedia.Datastar.Logger (DatastarLogger, nullLogger, stderrLogger)
src/Hypermedia/Datastar/WAI.hs view
@@ -55,10 +55,9 @@ import Hypermedia.Datastar.Types import Hypermedia.Datastar.ExecuteScript qualified as ES+import Hypermedia.Datastar.Logger qualified as Logger import Hypermedia.Datastar.PatchElements qualified as PE import Hypermedia.Datastar.PatchSignals qualified as PS-import Hypermedia.Datastar.Logger qualified as Logger-import qualified Hypermedia.Datastar.Logger as Logger {- | An opaque handle for sending SSE events to the browser. @@ -71,7 +70,7 @@ { sseWrite :: BSB.Builder -> IO () , sseFlush :: IO () , sseLock :: MVar ()- , sseLogger :: Logger.DatastarLogger + , sseLogger :: Logger.DatastarLogger } {- | Create a WAI 'WAI.Response' that streams SSE events.
test/Hypermedia/Datastar/SSESpec.hs view
@@ -9,11 +9,11 @@ import Data.List (isInfixOf) import Hypermedia.Datastar+import Hypermedia.Datastar.Logger (nullLogger) import Hypermedia.Datastar.PatchElements import Hypermedia.Datastar.PatchSignals import Hypermedia.Datastar.Types import Hypermedia.Datastar.WAI (renderEvent)-import Hypermedia.Datastar.Logger (nullLogger) import Network.Wai.Internal (Response (..)) render :: DatastarEvent -> String