hyperbole-0.3.6: Interactive HTML apps using type-safe serverside Haskell
Safe HaskellSafe-Inferred
LanguageGHC2021

Web.Hyperbole.Effect

Synopsis

Documentation

newtype Host Source #

Constructors

Host 

Fields

Instances

Instances details
Show Host Source # 
Instance details

Defined in Web.Hyperbole.Effect

Methods

showsPrec :: Int -> Host -> ShowS #

show :: Host -> String #

showList :: [Host] -> ShowS #

data Request Source #

Constructors

Request 

Instances

Instances details
Show Request Source # 
Instance details

Defined in Web.Hyperbole.Effect

data Response Source #

Valid responses for a Hyperbole effect. Use notFound, etc instead. Reminds you to use load in your Page

myPage :: (Hyperbole :> es) => Page es Response
myPage = do
  -- compiler error: () does not equal Response
  pure ()

newtype Page es a Source #

Hyperbole applications are divided into Pages. Each Page must load the whole page , and handle each type of HyperView

myPage :: (Hyperbole :> es) => Page es Response
myPage = do
  handle messages
  load pageView

pageView = do
  el_ "My Page"
  hyper (Message 1) $ messageView "Starting Message"

Constructors

Page (Eff es a) 

Instances

Instances details
Applicative (Page es) Source # 
Instance details

Defined in Web.Hyperbole.Effect

Methods

pure :: a -> Page es a #

(<*>) :: Page es (a -> b) -> Page es a -> Page es b #

liftA2 :: (a -> b -> c) -> Page es a -> Page es b -> Page es c #

(*>) :: Page es a -> Page es b -> Page es b #

(<*) :: Page es a -> Page es b -> Page es a #

Functor (Page es) Source # 
Instance details

Defined in Web.Hyperbole.Effect

Methods

fmap :: (a -> b) -> Page es a -> Page es b #

(<$) :: a -> Page es b -> Page es a #

Monad (Page es) Source # 
Instance details

Defined in Web.Hyperbole.Effect

Methods

(>>=) :: Page es a -> (a -> Page es b) -> Page es b #

(>>) :: Page es a -> Page es b -> Page es b #

return :: a -> Page es a #

data Event id act Source #

An action, with its corresponding id

Constructors

Event 

Fields

Instances

Instances details
(Show act, Show id) => Show (Event id act) Source # 
Instance details

Defined in Web.Hyperbole.Effect

Methods

showsPrec :: Int -> Event id act -> ShowS #

show :: Event id act -> String #

showList :: [Event id act] -> ShowS #

data Server :: Effect where Source #

Low level effect mapping request/response to either HTTP or WebSockets

Constructors

LoadRequest :: Server m Request 
SendResponse :: Session -> Response -> Server m () 

Instances

Instances details
type DispatchOf Server Source # 
Instance details

Defined in Web.Hyperbole.Effect

data Hyperbole :: Effect where Source #

In any load or handle, you can use this Effect to get extra request information or control the response manually.

For most Pages, you won't need to use this effect directly. Use custom Routes for request info, and return Views to respond

Instances

Instances details
type DispatchOf Hyperbole Source # 
Instance details

Defined in Web.Hyperbole.Effect

data HyperState Source #

Constructors

HyperState 

runHyperbole :: Server :> es => Eff (Hyperbole : es) Response -> Eff es Response Source #

Run the Hyperbole effect to Server

request :: Hyperbole :> es => Eff es Request Source #

Return all information about the Request

reqPath :: Hyperbole :> es => Eff es [Segment] Source #

Return the request path

>>> reqPath
["users", "100"]

formData :: Hyperbole :> es => Eff es Form Source #

Return the request body as a Web.FormUrlEncoded.Form

Prefer using Type-Safe Forms when possible

getEvent :: (HyperView id, Hyperbole :> es) => Eff es (Maybe (Event id (Action id))) Source #

session :: (Hyperbole :> es, FromHttpApiData a) => Text -> Eff es (Maybe a) Source #

Lookup a session variable by keyword

load $ do
  tok <- session "token"
  ...

setSession :: (Hyperbole :> es, ToHttpApiData a) => Text -> a -> Eff es () Source #

Set a session variable by keyword

load $ do
  t <- reqParam "token"
  setSession "token" t
  ...

clearSession :: Hyperbole :> es => Text -> Eff es () Source #

Clear the user's session

reqParams :: Hyperbole :> es => Eff es Query Source #

Return the entire Query

myPage :: Page es Response
myPage = do
  load $ do
    q <- reqParams
    case lookupParam "token" q of
      Nothing -> pure $ errorView "Missing Token in Query String"
      Just t -> do
        sideEffectUsingToken token
        pure myPageView

lookupParam :: ByteString -> Query -> Maybe Text Source #

Lookup the query param in the Query

reqParam :: (Hyperbole :> es, FromHttpApiData a) => Text -> Eff es a Source #

Require a given parameter from the Query arguments

myPage :: Page es Response
myPage = do
  load $ do
    token <- reqParam "token"
    sideEffectUsingToken token
    pure myPageView

notFound :: Hyperbole :> es => Eff es a Source #

Respond immediately with 404 Not Found

userLoad :: (Hyperbole :> es, Users :> es) => UserId -> Eff es User
userLoad uid = do
  mu <- send (LoadUser uid)
  maybe notFound pure mu

myPage :: (Hyperbole :> es, Users :> es) => Eff es View
myPage = do
  load $ do
    u <- userLoad 100
    -- skipped if user = Nothing
    pure $ userView u

parseError :: Hyperbole :> es => Text -> Eff es a Source #

Respond immediately with a parse error

redirect :: Hyperbole :> es => Url -> Eff es a Source #

Redirect immediately to the Url

respondEarly :: (Hyperbole :> es, HyperView id) => id -> View id () -> Eff es () Source #

Respond with the given view, and stop execution

view :: Hyperbole :> es => View () () -> Eff es Response Source #

Manually set the response to the given view. Normally you return a View from load or handle instead of using this

load :: Hyperbole :> es => Eff es (View () ()) -> Page es Response Source #

The load handler is run when the page is first loaded. Run any side effects needed, then return a view of the full page

myPage :: (Hyperbole :> es) => UserId -> Page es Response
myPage userId = do
  load $ do
    user <- loadUserFromDatabase userId
    pure $ userPageView user

handle :: forall id es. (Hyperbole :> es, HyperView id) => (id -> Action id -> Eff es (View id ())) -> Page es () Source #

A handler is run when an action for that HyperView is triggered. Run any side effects needed, then return a view of the corresponding type

myPage :: (Hyperbole :> es) => Page es Response
myPage = do
  handle messages
  load pageView

messages :: (Hyperbole :> es, MessageDatabase) => Message -> MessageAction -> Eff es (View Message ())
messages (Message mid) ClearMessage = do
  deleteMessageSideEffect mid
  pure $ messageView ""

messages (Message mid) (Louder m) = do
  let new = m <> "!"
  saveMessageSideEffect mid new
  pure $ messageView new