mithril-stream-router

An external router for mithril using streams.

Usage no npm install needed!

<script type="module">
  import mithrilStreamRouter from 'https://cdn.skypack.dev/mithril-stream-router';
</script>

README

mithril-stream-router

This is a very early draft at an opinionated router. Use with caution.

Low Level Example

High Level Example

Quick Start

const Albums = 
  ({ getState, link, Route }) => {
    return m('.albums'
      ,m('h1', 'Albums')
      ,m('ul'
        ,['One', 'Two', 'Three']
        .map(
          k => m('a', link( Route.of.Album({ album_key: k }) ), k )
        )
        .map( x => m('li', x) )
      )
    )
  }

const Album = 
  ({ album_key, link, Route }) => {
   
    const base = '/albums/'+album_key+'/photo/'
    return m('.album'
      ,m('h1', 'Album '+album_key )
      ,m('h2', 'Files')
      ,m('ul'
        ,['A', 'B', 'C']
        .map( k => 
            m('a', 
             link( Route.of.AlbumFile({ album_key, file_id: k }))
              , k 
            ) 
        )
        .map( x => m('li', x) )
      )
    )
  }

const AlbumFile = 
  ({ album_key, file_id }) => {
    return m('.file'
      ,m('h1', 'File ' + file_id +' from ' + album_key )
    )
  }

const render = 
  attrs => m('.app'
    ,m('pre', attrs.Route.toURL(attrs.getState().route))
    ,m('button', { onclick: () => window.history.back() }, 'Back' )
    ,attrs.Route.fold({
      Albums: () => Albums(attrs),
      Album: route => Album({ ...attrs, ...route }),
      AlbumFile: route => AlbumFile({ ...attrs, ...route }),
    }) (attrs.getState().route)           
  )

m.mount(document.body, () => {
  const Route =
    superouter.type('Route', {
      'Albums': '/',
      'Album': '/albums/:album_key',
      'AlbumFile': '/albums/:album_key/photo/:file_id',
    })
    
  return {
    view: () => 
      m(m.stream.router.component, {
        m,
        stream: m.stream,
        fromURL: url => Route.matchOr( () => Route.of.Albums(), url ),
        toURL: x => Route.toURL(x),
        location: () => window.location,
        initial(){
          return {
            route: Route.of.Albums()
          }
        },
        services(){},
        render: attrs => render({ ...attrs, Route })
      })
  }
})