From 14ffcdd1cd72304b81a152a92e0258991ab1222b Mon Sep 17 00:00:00 2001
From: Sridhar Ratnakumar <3998+srid@users.noreply.github.com>
Date: Thu, 22 Apr 2021 13:53:22 -0400
Subject: [PATCH] Speed up hot reload using Dom patching (#11)
* Speed DOM replace using patch via morphdom
* Don't send JS shims when sending HTML down websocket
Don't need.
* Fix a bug with recursive route switch
* Iron out some bugs
---
README.md | 10 +++---
src/Ema/Server.hs | 77 ++++++++++++++++++++++++++++++-----------------
2 files changed, 55 insertions(+), 32 deletions(-)
diff --git a/README.md b/README.md
index 55bd7f0..48b06e3 100644
--- a/README.md
+++ b/README.md
@@ -28,22 +28,22 @@ Run `bin/run` (or Ctrl+Shift+B in VSCode). This runs the clock exampl
- [x] client to server reconnect (on ghcid reload, or accidental client disconnect)
- [x] or, investigate https://hackage.haskell.org/package/ghci-websockets
- [x] Multi-websocket-client support
-- [ ] Refactor Server.hs
- [ ] Static site generation mode
- [ ] add common examples,
- [x] filesystem watcher
- [ ] docs site for self (w/ sidebar and possibly even search)
pre-announce,
-- [ ] plan features / messaging, re: hakyll
- - Safer and simpler routes system
- - Template system?
- [ ] CLI UX (opts, logging, etc.)
-- [ ] documentation ([howto](https://documentation.divio.com/))
+- [ ] How to serve non-generated files (css, img, etc.)
- [ ] Publish Data.LVar to Hackage
+- [ ] documentation ([howto](https://documentation.divio.com/))
doc notes,
- use async:race to avoid ghcid ghosts
- at most one ws client supported right now
- tailwind + blaze-html layout (BlazeWind?) for no-frills getting started
- [dealing with errors](https://github.com/srid/memoir/issues/1)
+- messaging re: hakyll
+ - safer/ simpler routes system
+ - bring your own templates / DSL
diff --git a/src/Ema/Server.hs b/src/Ema/Server.hs
index 4cb472e..f15520e 100644
--- a/src/Ema/Server.hs
+++ b/src/Ema/Server.hs
@@ -57,7 +57,7 @@ runServerWithWebSocketHotReload port model render = do
Left newHtml -> do
-- The page the user is currently viewing has changed. Send
-- the new HTML to them.
- WS.sendTextData conn $ routeHtml newHtml watchingRoute
+ WS.sendTextData conn $ renderWithEmaHtmlShims newHtml watchingRoute
log $ "[Watch]: ~~> " <> show watchingRoute
loop
Right nextRoute -> do
@@ -67,7 +67,7 @@ runServerWithWebSocketHotReload port model render = do
-- request immediately following this).
log $ "[Switch]: <~~ " <> show nextRoute
html <- LVar.get model
- WS.sendTextData conn $ routeHtml html nextRoute
+ WS.sendTextData conn $ renderWithEmaHtmlShims html nextRoute
log $ "[Switch]: ~~> " <> show nextRoute
loop
try loop >>= \case
@@ -81,13 +81,14 @@ runServerWithWebSocketHotReload port model render = do
pure (H.status404, "No route")
Just r -> do
val <- LVar.get model
- pure (H.status200, routeHtml val r)
+ pure (H.status200, renderWithEmaShims val r)
f $ Wai.responseLBS status [(H.hContentType, "text/html")] v
+ renderWithEmaShims m r =
+ render m r <> emaStatusHtml <> wsClientShim
+ renderWithEmaHtmlShims m r =
+ render m r <> emaStatusHtml
routeFromPathInfo =
fromSlug . fmap (fromString . toString)
- routeHtml :: model -> route -> LByteString
- routeHtml m r = do
- render m r <> emaStatusHtml <> wsClientShim
-- | Return the equivalent of WAI's @pathInfo@, from the raw path string
-- (`document.location.pathname`) the browser sends us.
@@ -100,14 +101,33 @@ wsClientShim :: LByteString
wsClientShim =
encodeUtf8
[text|
+
+