h,qc      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~                                                                                           0.4.3None "%1> None "%1=>  hyperbole:Data.Default doesn't have a Text instance. This class does hyperbole&Generic encoding of records to a Query hyperbole(Generic decoding of records from a Query hyperboleDecode data from a query, session, or form parameter value data Todo = Todo { id :: TodoId , task :: Text , completed :: Bool } deriving (Show, Read, , ) "data Tags = Tags [Text] instance  Tags where parseParam (ParamValue t) = pure $ Tags $ Text.splitOn "," t  hyperbolesessions, forms, and querys all encode data as query strings. ToParam and FromParam control how a datatype is encoded to a parameter. By default it simply url-encodes the show instance. data Todo = Todo { id :: TodoId , task :: Text , completed :: Bool } deriving (Show, Read, , ) "data Tags = Tags [Text] instance  Tags where toParam (Tags ts) = ParamValue $ Text.intercalate "," ts  hyperbole&A page can store state in the browser query string. ToQuery and 9 control how a datatype is encoded to a full query string data Filters = Filters { active :: Bool , term :: Text } deriving (Generic, , ) %render $ toQuery $ Filter True "asdf""active=true&search=asdf"'If the value of a field is the same as *, it will be omitted from the query string!render $ toQuery $ Filter True "" "active=true""render $ toQuery $ Filter False """" hyperboleDecode a type from a . Missing fields are set to  data Filters = Filters { active :: Bool , term :: Text } deriving (Generic, , ) ,parseQuery $ parse "active=true&search=asdf"Right (Filters True "asdf") parseQuery $ parse "search=asdf"Right (Filters False "asdf") hyperbole-Key-value store for query params and sessions hyperboleEncode a Show as a query param hyperboleDecode a Read as a query param hyperbole$Parse a Traversable (list) of params',None "%1=> hyperbolegeneric datatype name hyperbole(Configure a data type to persist in the session data Preferences = Preferences { color :: AppColor } deriving (Generic, Show, Read, ,  FromParam,  ) instance  DefaultParam6 Preferences where defaultParam = Preferences White  hyperbole8Unique key for the Session. Defaults to the datatypeName hyperboleBy default Sessions are persisted only to the current page. Set this to `Just []` to make an application-wide SessionNone "%1=> hyperboleAutomatically derive  hyperboleDerive this class to use a sum type as a route. Constructors and Selectors map intuitively to url patterns data AppRoute = Main | Messages | User UserId deriving (Eq, Generic) instance ( AppRoute where baseRoute = Just Main  routeUrl Main/routeUrl (User 9)/user/9 hyperbole9The route to use if attempting to match on empty segments hyperbole Try to match segments to a route hyperboleMap a route to segments hyperboleTry to match a route, use defRoute if it's empty hyperbole Convert a  to a brouteUrl (User 100) /user/100 ! hbhb None "%1> hyperbole$An action, with its corresponding id hyperboleSerialized ViewId hyperboleValid responses for a  Hyperbole effect. Use notFound, etc instead. hyperboleLow level effect mapping request/response to either HTTP or WebSockets22 None "%1>_ hyperboleThe  ) allows you to access information in the  , manually  respondEarly, and manipulate the Client  and . hyperboleRun the  effect to    None "%1> hyperbole!Return all information about the  hyperboleReturn the request pathreqPath["users", "100"] hyperbole4Return the request body as a Web.FormUrlEncoded.FormPrefer using Type-Safe s when possible None "%1>$  hyperbolePersist datatypes in browser cookies. If the session doesn't exist, the  is used data Preferences = Preferences { color :: AppColor } deriving (Generic, Show, Read, , ,  ) instance  Preferences where defaultParam = Preferences White page :: ( :> es) =>  es (Page '[Content]) page = do prefs <- session @Preferences pure $ el& (bg prefs.color) "Custom Background"  hyperboleReturn a session if it exists hyperbole$Persist datatypes in browser cookies data Preferences = Preferences { color :: AppColor } deriving (Generic, Show, Read, , ,  ) instance  Preferences where defaultParam = Preferences White instance  HyperView Content es where data Action; Content = SetColor AppColor deriving (Show, Read,  ViewAction) update (SetColor clr) = do let prefs = Preferences clr saveSession prefs pure $ el& (bg prefs.color) "Custom Background"  hyperboleRemove a single  from the browser cookies hyperbole7save a single datatype to a specific key in the session hyperboleModify the client cookies hyperboleReturn all the cookies, both those sent in the request and others added by the page hyperbole*Return the session from the Client cookies hyperboleReturn the session from the  cookies   None "%1>* hyperboleParse querystring from the  into a datatype. See  data Filters = Filters { active :: Bool , term :: Text } deriving (Generic, ,  ) page :: ( :> es) =>  es (Page '[Todos]) page = do filters <- query @Filters todos <- loadTodos filters pure $ do hyper Todos $ todosView todos  hyperbole es) =>  es (Page '[Message]) page' = do msg <- param "message" pure $ do hyper Message $ messageView msg  hyperbole;Parse a single parameter from the query string if available hyperbole?Modify the client's querystring to set a single parameter. See   instance  HyperView Message es where data Action9 Message = SetMessage Text deriving (Show, Read,  ViewAction) update (SetMessage msg) = do * "message" msg pure $ messageView msg  hyperbole/Delete a single parameter from the query string hyperboleReturn the query from  as a None "%1>+ None "%1=>2 hyperbole Access the  in a n or  8data LazyData = LazyData TaskId deriving (Show, Read, .) instance (Debug :> es, GenRandom :> es) =>  LazyData es where data 2 LazyData = Details deriving (Show, Read, ) % Details = do LazyData taskId <-  task <- pretendLoadTask taskId pure $ viewTaskDetails task  hyperbole!The top-level view returned by a Page(. It carries a type-level list of every  used in our Page so the compiler can check our work and wire everything together. hyperbole,HyperViews are interactive subsections of a PageCreate an instance with a unique view id type and a sum type describing the actions the HyperView supports. The View Id can contain context (a database id, for example) /data Message = Message deriving (Show, Read,  ) instance  Message es where data 9 Message = SetMessage Text deriving (Show, Read, ) / (SetMessage msg) = pure $ messageView msg  hyperbole8Outline all actions that are permitted in this HyperView data Action Message = SetMessage Text | ClearMessage deriving (Show, Read, ViewAction) hyperboleInclude any child hyperviews here. The compiler will make sure that the page knows how to handle them type Require = '[ChildView] hyperbole6Specify how the view should be updated for each Action update (SetMessage msg) = pure $ messageView msg update ClearMessage = pure $ messageView "" hyperboleEmbed a  into another n page ::  es (Page '[Message]) page = do pure $ do col (pad 10 . gap 10) $ do x0 (bold . fontSize 24) "Unchanging Header" % Message $ messageView "Hello World" "#$%None "%1>5 hyperbole/Respond with the given view, and stop execution hyperbole&Respond immediately with 404 Not Found  findUser :: ( :> es, Users :> es) => Int ->  es User findUser uid = do mu <- send (LoadUser uid) maybe notFound pure mu userPage :: ( :> es, Users :> es) =>  es (Page '[]) userPage = do user <- findUser 100 -- skipped if user not found pure $ userView user  hyperbole&Respond immediately with a parse error hyperboleRedirect immediately to the b hyperboleManually set the response to the given view. Normally you would return a n from runPage insteadNone "%1>6D hyperbole,Lower-level lookup straight from the requestNone "%1>6~None "%1>9 hyperbole:Conceptually, an application is dividied up into multiple  #g:pagesPages9. Each page module should have a function that returns a . The  itself is a n with a type-level list of  HyperViews used on the page. page ::  es (? [Message, Count]) page = do pure $ do row id $ do hyper% Message $ messageView "Hello" hyper Count $ countView 0  hyperboleRun a  and return a  main :: IO () main = do run 3000 $ do liveApp ( basicDocument "Example") ( page) page ::  es (8 '[]) page = do pure $ do col (pad 10) $ do el bold "Hello World" None "%1>9  None "%1>@^ hyperboleTurn one or more Pages into a Wai Application. Respond using both HTTP and WebSockets main :: IO () main = do run 3000 $ do liveApp (basicDocument "Example") (runPage page) hyperbolewrap HTML fragments in a simple document with a custom title and include required embeds  (basicDocument "App Title") ( router) You may want to specify a custom document function to import custom javascript, css, or add other information to the import Data.String.Interpolate (i) import Web.Hyperbole (scriptEmbed, cssResetEmbed) customDocument :: ByteString -> ByteString customDocument content = [i| My Website #{content} |] hyperbole%Route URL patterns to different pages import Example.Docs.Page4.Messages qualified as Messages import Example.Docs.Page.Users qualified as Users type UserId = Int data AppRoute = Main | Messages | User UserId deriving (Eq, Generic) instance 4 AppRoute where baseRoute = Just Main router :: ( :> es) => AppRoute ->  es  router Messages = runPage# Messages.page router (User cid) = runPage3 $ Users.page cid router Main = do view $ do el+_ "click a link below to visit a page" route Messages id "Messages" route (User 1) id "User 1" route (User 2) id "User 2"   None "%1>E hyperboleSend the action after N milliseconds. Can be used to implement lazy loading or polling. See &https://docs.hyperbole.live/concurrentExample.Page.Concurrent viewTaskLoad :: n LazyData () viewTaskLoad = do -- 100ms after rendering, get the details el (onLoad Details 100 . bg GrayLight . textAlign AlignCenter) $ do text "..."  hyperbole*Run an action when the user types into an input or textarea.WARNING: a short delay can result in poor performance. It is not recommended to set the value of the input input (onInput OnSearch) 250 id hyperbole.Serialize a constructor that expects a single &, like `data MyAction = GoSearch Text` hyperbole2Apply a Mod only when a request is in flight. See &https://docs.hyperbole.live/contacts/1Example.Page.Contact contactEditView :: User -> n% Contact () contactEditView u = do el- (hide . onRequest flexCol) contactLoading el (onRequest hide) $ contactEdit n Save u  hyperboleInternal hyperbole4Allow inputs to trigger actions for a different viewNone "%1>I hyperboleThe view context for an  hyperbole5