Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use new reload behaviour in live #29

Open
wants to merge 18 commits into
base: lamdera-next
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions elm.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ Executable lamdera

Lamdera.CLI
Lamdera.CLI.Live
Lamdera.CLI.Live.Output
Lamdera.CLI.Login
Lamdera.CLI.Check
Lamdera.CLI.Deploy
Expand Down
21 changes: 16 additions & 5 deletions ext-sentry/Ext/Sentry.hs
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,36 @@ import Ext.Common
data Cache =
Cache
{ jsOutput :: MVar BS.ByteString
, htmlWrapper :: MVar (BS.ByteString, BS.ByteString)
}


init :: IO Cache
init = do
mJsOutput <- newMVar "cacheInit!"
pure $ Cache mJsOutput
mHtmlWrapper <- newMVar ("cacheInit!", "cacheInit!")
pure $ Cache mJsOutput mHtmlWrapper


getJsOutput :: Cache -> IO BS.ByteString
getJsOutput cache =
readMVar $ jsOutput cache


asyncUpdateJsOutput :: Cache -> IO BS.ByteString -> IO ()
asyncUpdateJsOutput (Cache mJsOutput) recompile = do
getHtmlOutput :: Cache -> IO BS.ByteString
getHtmlOutput cache = do
(htmlPre, htmlPost) <- readMVar $ htmlWrapper cache
js <- getJsOutput cache
pure $ htmlPre <> js <> htmlPost


asyncUpdateJsOutput :: Cache -> IO (BS.ByteString, BS.ByteString, BS.ByteString) -> IO ()
asyncUpdateJsOutput (Cache mJsOutput mHtmlWrapper) recompile = do
trackedForkIO "Ext.Sentry.asyncUpdateJsOutput" $ do
takeMVar mJsOutput
!bs <- track "recompile" $ recompile
putMVar mJsOutput bs
takeMVar mHtmlWrapper
(!pre, !js, !post) <- track "recompile" $ recompile
putMVar mJsOutput js
putMVar mHtmlWrapper (pre, post)
System.Mem.performMajorGC
pure ()
5 changes: 4 additions & 1 deletion extra/Lamdera/CLI/Live.hs
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,10 @@ lamderaLocalDev =


refreshClients (mClients, mLeader, mChan, beState) =
SocketServer.broadcastImpl mClients "{\"t\":\"r\"}" -- r is refresh, see live.js
SocketServer.broadcastImpl mClients "{\"t\":\"r\"}" -- r is refresh, see live.ts

reloadClientsJS (mClients, mLeader, mChan, beState) =
SocketServer.broadcastImpl mClients "{\"t\":\"j\"}" -- j is refresh, see live.ts


serveWebsocket root (mClients, mLeader, mChan, beState) =
Expand Down
88 changes: 88 additions & 0 deletions extra/Lamdera/CLI/Live/Output.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
module Lamdera.CLI.Live.Output where

import qualified Data.ByteString.Builder as B
import Data.Monoid ((<>))
import qualified Data.Name as Name
import Text.RawString.QQ (r)

import qualified Lamdera
import qualified Lamdera.Live
import qualified Lamdera.UiSourceMap


-- For when we already have the combined JS from cache and just need to wrap the HTML around it
parts :: FilePath -> Name.Name -> B.Builder -> (B.Builder, B.Builder, B.Builder)
parts root moduleName javascript =
let
name = Name.toBuilder moduleName

(hasCustom, customHead) = Lamdera.unsafe $ Lamdera.Live.lamderaLiveHead root
htmlHead =
if hasCustom
then
customHead
else
"<title>" <> name <> "</title>"

combinedjs = js root moduleName javascript

pre = [r|<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0, minimum-scale=1.0">
<meta name="apple-mobile-web-app-capable" content="yes" />
<style>body { padding: 0; margin: 0; } body.boot-unhandled-js-error { padding: 10px } @media (prefers-color-scheme: dark) { body.boot-unhandled-js-error { background-color: #000; color: #fff; } } </style>
|] <> htmlHead <> [r|
</head>

<body>

<pre id="elm"></pre>

<script>
|]

post = [r|
</script>

</body>
</html>|]

in
(pre, combinedjs, post)


-- The Elm app, `lamdera live` JS harness (live.ts) and UI sourcemaps combined into a single JS snippet
js :: FilePath -> Name.Name -> B.Builder -> B.Builder
js root moduleName javascript =
let
name = Name.toBuilder moduleName
in
[r|
try {
|] <> javascript <> [r|
|] <> Lamdera.Live.lamderaLiveSrc <> Lamdera.UiSourceMap.src <> [r|
setupApp("|] <> name <> [r|", "elm")
}
catch (e)
{
// document.body.classList.add("boot-unhandled-js-error");
// // display initialization errors (e.g. bad flags, infinite recursion)
// var header = document.createElement("h1");
// header.style.fontFamily = "monospace";
// header.innerText = "Initialization Error";
// var pre = document.createElement("pre");
// document.body.insertBefore(header, pre);
// pre.innerText = e;
throw e;
}
|]


-- For when we need to generate the HTML and combined JS from scratch
-- html :: FilePath -> Name.Name -> B.Builder -> B.Builder
-- html root moduleName javascript =
-- wrapjs root moduleName (js root moduleName javascript)
Loading