1
1
mirror of https://github.com/srid/ema.git synced 2024-11-29 09:25:14 +03:00

make publish private

This commit is contained in:
Sridhar Ratnakumar 2021-04-19 20:18:50 -04:00
parent acccb74bb4
commit 487a1c0aae
2 changed files with 21 additions and 26 deletions

View File

@ -3,10 +3,10 @@
module Ema.Changing where
-- A mutable variable with change notification
-- TODO: Rename to something more accurate?
import qualified Data.Map.Strict as Map
-- A mutable variable with change notification
-- TODO: Rename to something more accurate?
data Changing a = Changing
{ -- | A value that changes over time
changingCurrent :: TMVar a,
@ -26,42 +26,39 @@ get :: MonadIO m => Changing a -> m a
get v =
atomically $ readTMVar $ changingCurrent v
-- | Sets a new value; listeners from @subscribe@ are automatically notifed.
set :: MonadIO m => Changing a -> a -> m ()
set v val = do
n <- atomically $ do
void $ swapTMVar (changingCurrent v) val
publish v
when (n > 0) $
putStrLn $ "pub: sent to " <> show n <> " subscribers"
putStrLn $ "pub: published; " <> show n <> " subscribers listening"
where
publish :: Changing a -> STM Int
publish v' = do
subs <- readTMVar $ changingSubscribers v'
forM_ (Map.elems subs) $ \subVar -> do
tryPutTMVar subVar ()
pure $ Map.size subs
publish :: Changing a -> STM Int
publish v = do
subs <- readTMVar $ changingSubscribers v
forM_ (Map.elems subs) $ \subVar -> do
tryPutTMVar subVar ()
pure $ Map.size subs
-- | Subscribes to new values as they are set.
-- | Subscribes to new values as they are set by @set@.
subscribe :: MonadIO m => Changing a -> (Int -> a -> IO b) -> m (Int, IO ())
subscribe v f = do
putStrLn "sub"
(idx, notify) <- atomically $ do
subs <- readTMVar $ changingSubscribers v
let nextIdx = maybe 0 (succ . fst) $ Map.lookupMax subs
let nextIdx = maybe 1 (succ . fst) $ Map.lookupMax subs
notify <- newEmptyTMVar
void $ swapTMVar (changingSubscribers v) $ Map.insert nextIdx notify subs
pure (nextIdx, notify)
putStrLn $ "sub[" <> show idx <> "]: created notify"
pure
( idx,
void $
let runSubscription =
forever $ do
val :: a <- atomically $ do
takeTMVar notify
readTMVar (changingCurrent v)
putStrLn $ "sub[" <> show idx <> "]: calling f"
liftIO $ f idx val
)
putStrLn $ "sub[" <> show idx <> "]: sending"
liftIO $ void $ f idx val
pure (idx, runSubscription)
unsubscribe :: MonadIO m => Changing a -> Int -> m ()
unsubscribe v subId = do

View File

@ -36,7 +36,7 @@ runServerWithWebSocketHotReload model render = do
pathInfo <- pathInfoFromWsMsg <$> WS.receiveData @Text conn
let r :: route = fromMaybe (error "invalid route from ws") $ routeFromPathInfo pathInfo
log $ "Browser at route: " <> show r
(subId, send) <- Changing.subscribe @IO model $ \subId (val :: model) -> do
(subId, send) <- Changing.subscribe model $ \subId (val :: model) -> do
try (WS.sendTextData conn $ routeHtml val r) >>= \case
Right () -> pure ()
Left (err :: ConnectionException) -> do
@ -63,7 +63,8 @@ runServerWithWebSocketHotReload model render = do
routeHtml m r = do
render m r <> wsClientShim
-- | Return equivalent of WAI's @pathInfo@, from the raw path string the browser strings us.
-- | Return the equivalent of WAI's @pathInfo@, from the raw path string
-- (`document.location.pathname`) the browser sends us.
pathInfoFromWsMsg :: Text -> [Text]
pathInfoFromWsMsg =
filter (/= "") . T.splitOn "/" . T.drop 1
@ -116,16 +117,13 @@ wsClientShim =
ws.send(document.location.pathname);
};
ws.onclose = () => {
// TODO: Display a message box on page during disconnected state.
console.log("ema: closed; reloading..");
refreshPage();
};
ws.onmessage = evt => {
// console.log(evt.data);
console.log("ema: Resetting HTML body")
setInnerHtml(document.documentElement, evt.data);
// document.documentElement.innerHTML = evt.data;
// ws.close();
// history.go(0);
};
window.onbeforeunload = evt => { ws.close(); };
window.onpagehide = evt => { ws.close(); };