1
1
mirror of https://github.com/srid/ema.git synced 2024-12-02 09:15:10 +03:00

Combine staticRoutes and staticAssets

This commit is contained in:
Sridhar Ratnakumar 2021-05-22 00:02:04 -04:00
parent 3216e818c9
commit c345c7bd80
5 changed files with 27 additions and 21 deletions

View File

@ -37,7 +37,7 @@ runEmaPure ::
(CLI.Action -> LByteString) -> (CLI.Action -> LByteString) ->
IO () IO ()
runEmaPure render = do runEmaPure render = do
runEma (const []) (const $ one ()) (\act () () -> render act) $ \model -> do runEma (const $ one $ Right ()) (\act () () -> render act) $ \model -> do
LVar.set model () LVar.set model ()
liftIO $ threadDelay maxBound liftIO $ threadDelay maxBound
@ -49,17 +49,16 @@ runEmaPure render = do
runEma :: runEma ::
forall model route. forall model route.
(FileRoute route, Show route) => (FileRoute route, Show route) =>
(model -> [FilePath]) -> (model -> [Either FilePath route]) ->
(model -> [route]) ->
-- | How to render a route, given the model -- | How to render a route, given the model
(CLI.Action -> model -> route -> LByteString) -> (CLI.Action -> model -> route -> LByteString) ->
-- | A long-running IO action that will update the @model@ @LVar@ over time. -- | A long-running IO action that will update the @model@ @LVar@ over time.
-- This IO action must set the initial model value in the very beginning. -- This IO action must set the initial model value in the very beginning.
(forall m. (MonadIO m, MonadUnliftIO m, MonadLoggerIO m) => LVar model -> m ()) -> (forall m. (MonadIO m, MonadUnliftIO m, MonadLoggerIO m) => LVar model -> m ()) ->
IO () IO ()
runEma staticAssets staticRoutes render runModel = do runEma allRoutes render runModel = do
cli <- CLI.cliAction cli <- CLI.cliAction
runEmaWithCli cli staticAssets staticRoutes render runModel runEmaWithCli cli allRoutes render runModel
-- | Like @runEma@ but takes the CLI action -- | Like @runEma@ but takes the CLI action
-- --
@ -68,15 +67,14 @@ runEmaWithCli ::
forall model route. forall model route.
(FileRoute route, Show route) => (FileRoute route, Show route) =>
Cli -> Cli ->
(model -> [FilePath]) -> (model -> [Either FilePath route]) ->
(model -> [route]) ->
-- | How to render a route, given the model -- | How to render a route, given the model
(CLI.Action -> model -> route -> LByteString) -> (CLI.Action -> model -> route -> LByteString) ->
-- | A long-running IO action that will update the @model@ @LVar@ over time. -- | A long-running IO action that will update the @model@ @LVar@ over time.
-- This IO action must set the initial model value in the very beginning. -- This IO action must set the initial model value in the very beginning.
(forall m. (MonadIO m, MonadUnliftIO m, MonadLoggerIO m) => LVar model -> m ()) -> (forall m. (MonadIO m, MonadUnliftIO m, MonadLoggerIO m) => LVar model -> m ()) ->
IO () IO ()
runEmaWithCli cli staticAssets staticRoutes render runModel = do runEmaWithCli cli allRoutes render runModel = do
model <- LVar.empty model <- LVar.empty
-- TODO: Allow library users to control logging levels -- TODO: Allow library users to control logging levels
let logger = colorize logToStdout let logger = colorize logToStdout
@ -88,7 +86,7 @@ runEmaWithCli cli staticAssets staticRoutes render runModel = do
logInfoN " stuck here? set a model value using `LVar.set`" logInfoN " stuck here? set a model value using `LVar.set`"
race_ race_
(flip runLoggerLoggingT logger $ runModel model) (flip runLoggerLoggingT logger $ runModel model)
(flip runLoggerLoggingT logger $ runEmaWithCliInCwd (CLI.action cli) model staticAssets staticRoutes render) (flip runLoggerLoggingT logger $ runEmaWithCliInCwd (CLI.action cli) model allRoutes render)
-- | Run Ema live dev server -- | Run Ema live dev server
runEmaWithCliInCwd :: runEmaWithCliInCwd ::
@ -103,18 +101,17 @@ runEmaWithCliInCwd ::
-- or @Data.LVar.modify@ to modify it. Ema will automatically hot-reload your -- or @Data.LVar.modify@ to modify it. Ema will automatically hot-reload your
-- site as this model data changes. -- site as this model data changes.
LVar model -> LVar model ->
(model -> [FilePath]) -> (model -> [Either FilePath route]) ->
(model -> [route]) ->
-- | Your site render function. Takes the current @model@ value, and the page -- | Your site render function. Takes the current @model@ value, and the page
-- @route@ type as arguments. It must return the raw HTML to render to browser -- @route@ type as arguments. It must return the raw HTML to render to browser
-- or generate on disk. -- or generate on disk.
(Action -> model -> route -> LByteString) -> (Action -> model -> route -> LByteString) ->
m () m ()
runEmaWithCliInCwd cliAction model staticAssets staticRoutes render = do runEmaWithCliInCwd cliAction model allRoutes render = do
case cliAction of case cliAction of
Generate dest -> do Generate dest -> do
val <- LVar.get model val <- LVar.get model
Generate.generate dest val (staticAssets val) (staticRoutes val) (render cliAction) Generate.generate dest val (allRoutes val) (render cliAction)
Run -> do Run -> do
void $ LVar.get model void $ LVar.get model
port <- liftIO $ fromMaybe 8000 . (readMaybe @Int =<<) <$> lookupEnv "PORT" port <- liftIO $ fromMaybe 8000 . (readMaybe @Int =<<) <$> lookupEnv "PORT"

View File

@ -38,7 +38,7 @@ instance FileRoute Route where
main :: IO () main :: IO ()
main = do main = do
let routes = [minBound .. maxBound] let routes = [minBound .. maxBound]
Ema.runEma mempty (const routes) render $ \model -> do Ema.runEma (const $ Right <$> routes) render $ \model -> do
LVar.set model $ Model "Hello World. " LVar.set model $ Model "Hello World. "
liftIO $ threadDelay maxBound liftIO $ threadDelay maxBound

View File

@ -38,7 +38,7 @@ instance FileRoute Route where
main :: IO () main :: IO ()
main = do main = do
let routes = [minBound .. maxBound] let routes = [minBound .. maxBound]
Ema.runEma mempty (const routes) render $ \model -> Ema.runEma (const $ Right <$> routes) render $ \model ->
forever $ do forever $ do
LVar.set model =<< liftIO getCurrentTime LVar.set model =<< liftIO getCurrentTime
liftIO $ threadDelay $ 1 * 1000000 liftIO $ threadDelay $ 1 * 1000000

View File

@ -24,22 +24,21 @@ generate ::
) => ) =>
FilePath -> FilePath ->
model -> model ->
[FilePath] -> [Either FilePath route] ->
[route] ->
(model -> route -> LByteString) -> (model -> route -> LByteString) ->
m () m ()
generate dest model staticAssets routes render = do generate dest model allRoutes render = do
unlessM (liftIO $ doesDirectoryExist dest) $ do unlessM (liftIO $ doesDirectoryExist dest) $ do
error $ "Destination does not exist: " <> toText dest error $ "Destination does not exist: " <> toText dest
log LevelInfo $ "Writing " <> show (length routes) <> " routes" log LevelInfo $ "Writing " <> show (length allRoutes) <> " routes"
forM_ routes $ \r -> do forM_ (rights allRoutes) $ \r -> do
let fp = dest </> encodeFileRoute r let fp = dest </> encodeFileRoute r
log LevelInfo $ toText $ "W " <> fp log LevelInfo $ toText $ "W " <> fp
let !s = render model r let !s = render model r
liftIO $ do liftIO $ do
createDirectoryIfMissing True (takeDirectory fp) createDirectoryIfMissing True (takeDirectory fp)
writeFileLBS fp s writeFileLBS fp s
forM_ staticAssets $ \staticPath -> do forM_ (lefts allRoutes) $ \staticPath -> do
liftIO (doesPathExist staticPath) >>= \case liftIO (doesPathExist staticPath) >>= \case
True -> True ->
-- TODO: In current branch, we don't expect this to be a directory. -- TODO: In current branch, we don't expect this to be a directory.

View File

@ -28,6 +28,16 @@ instance FileRoute () where
encodeFileRoute () = "index.html" encodeFileRoute () = "index.html"
decodeFileRoute = guard . (== "index.html") decodeFileRoute = guard . (== "index.html")
-- | For file route type extendeded to let raw filepaths pass through.
--
-- Useful in combining with static path routes that are not to be generated.
instance FileRoute r => FileRoute (Either FilePath r) where
encodeFileRoute =
either id encodeFileRoute
decodeFileRoute s =
fmap Right (decodeFileRoute s)
<|> fmap Left (Just s)
-- | Return the relative URL of the given route -- | Return the relative URL of the given route
-- --
-- As the returned URL is relative, you will have to either make it absolute (by -- As the returned URL is relative, you will have to either make it absolute (by