Coder Social home page Coder Social logo

robertdp / purescript-web-router Goto Github PK

View Code? Open in Web Editor NEW
15.0 4.0 3.0 243 KB

A simple pushstate router, with support for async routing logic. Bring your preferred parser, printer and state management.

Dhall 7.34% PureScript 92.66%
pushstate pushstate-routing router

purescript-web-router's Introduction

purescript-web-router

A router for browsers that supports asynchronous routing logic. Bring your own printing and parsing (check out routing-duplex).

For a basic React example see here.

How to use

1. Install with Spago

$ spago install web-router

2. Define your routes

data Route
  = Page Page
  | NotFound

data Page
  = Home
  | ProductList
  | ProductView ProductId
  | About
  | ContactUs

type ProductId = Int

3. Implement parsing and printing

This example uses routing-duplex.

Imports
import Prelude hiding ((/))
import Data.Either (Either)
import Data.Generic.Rep (class Generic)
import Routing.Duplex (RouteDuplex', default, end, int, parse, print, root, segment)
import Routing.Duplex.Generic (noArgs, sum)
import Routing.Duplex.Generic.Syntax ((/))
import Routing.Duplex.Parser (RouteError)
derive instance Generic Route _
derive instance Generic Page _

productId :: RouteDuplex' ProductId
productId = int segment

routes :: RouteDuplex' Route
routes =
  default NotFound $
    sum
      { "Page": pages
      , "NotFound": "404" / noArgs
      }

pages :: RouteDuplex' Page
pages =
  root $ end $
    sum
      { "Home": noArgs
      , "ProductList": "products" / noArgs
      , "ProductView": "products" / productId
      , "About": "about" / noArgs
      , "ContactUs": "about" / noArgs
      }

-- | This is the route parser we need to pass to the driver.
-- | It can produce any route which allows the parser to return a value of `NotFound` instead of failing.
parseRoute :: forall  String -> Either RouteError Route
parseRoute = parse routes

-- | This is the route printer we need to pass to the driver.
-- | It can only print paths to valid pages, which means a path can't be produced for the `NotFound` route.
-- | With this approach routes can be seperated based on whether they should be a navigation target and have a URL.
-- | Note: assymetry is not required, and a symmetrical printer works as well.
printRoute :: Page -> String
printRoute = print pages

4. Define how your application reacts to navigation and routing events

Imports
import Web.Router as Router
onNavigation :: Maybe Route -> Route -> Router.RouterM Route Page Router.Routing Router.Resolved Unit
onNavigation previousRoute requestedRoute =
  case requestedRoute of
    NotFound ->
      case previousRoute of
        Just (Page page) -> Router.do
          liftEffect showBrokenNavigationMessage
          Router.redirect page -- redirect back to the previous page and show a message
        _ ->
          Router.continue -- no previous page, so just show the "not found" page
    _ -> Router.do
      access <- liftAff fetchUserAccess
      if userHasAccess requestedRoute access then
        Router.continue -- they have access, so resolve with the requested page
      else
        Router.override NotFound -- no access, so pretend the page doesn't exist


onEvent :: Router.RoutingEvent Route -> Effect Unit
onEvent newEvent =
  case newEvent of
    Router.Routing previousRoute requestedRoute ->
      showNavigationSpinner
    Router.Resolved previousRoute newRoute ->
      hideNavigationSpinner
      setCurrentRoute newRoute

5. Connect up the driver and router

Imports
import Web.Router as Router
import Web.Router.PushState as PushState
mkRouter :: Effect (Router.Router Route Page)
mkRouter = do
  driver <- PushState.mkInterface parseRoute printRoute
  router <- Router.mkInterface onNavigation onEvent driver
  pure router

Both pushstate and hash drivers are included, or a custom driver can be implemented. An example of a custom driver could be one that synchronises some navigation state over sockets, for an experience where one user's behaviour could be broadcast to multiple users to follow along.

purescript-web-router's People

Contributors

jonasbuntinx avatar robertdp avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

purescript-web-router's Issues

You also support hash-based routing

Yet the README specifically mentions push-state. I barely passed on this library but now I'm intrigued.

Am I looking at this wrong (maybe I need to read the README until the end?)

Add to package-sets

I know it's a bit tedious but I'd love to have a clean packages.dhall if possible.

If you need help, let me know, I've done it with a few packages now!

Please, describe the project status

Hi @robertdp!

I've just found this repo and it seems very interesting (as usual :-)). Would you be so kind and write a few words about the library status? Is it WIP? Is it usable?

Thanks in advance!

Example doesn't compile

Hi Robert,

it seems that there is missing import in the example. Should I provide example.dhall alongside the fix in the PR?

Regards

Drop `react-basic` dependency

It seems that the only part which ties this lib to react-basic is a small piece of the router constructor. I think that we can abstract this away and instead of providing component :: JSX (which internally handles subscribing / unsubscribing of the router) return subscribe :: Effect (Effect Unit) (or only unsubscribe :: Effect Unit - I'm not sure) as a part of the makeRouter result.

Then we are going to have wire-react-router without wire and without react which sounds more like a web-router or something :-P

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.