1.0.1 • Published 6 years ago

pathricia v1.0.1

Weekly downloads
2
License
MIT
Repository
github
Last release
6 years ago

Pathricia

This is a very simple implementation of a router, that is nevertheless fully functional. I have personally used it in various client projects and it has been a pleasure! Now it is named and published.

This package exports the Pathricia Router, which can be used with the history API or without. If you don't give it an instance of a history, it will just use the location.hash and work splendidly.

Install

For your copy-pasting pleasure:

yarn add pathricia

Use

Import the named export { Router } from the Pathricia package.

Refer to the usage example below, and have a peek into the example folder for an... uh, example.

import { Router } from 'pathricia'
const router = Router('indexroute')

If you want to use HTML5 history, you can give it a history object:

import { Router } from 'pathricia'
import createHistory from 'history/createBrowserHistory'

const router = Router('indexroute', createHistory())

Hash example

This is an example of a tab UI that uses the hash for routing AND is connected to your favorite state manager:

import { Router } from 'pathricia'

const state = { currentTab: 'lions' }
 
function activateTab(tabName) {
  // Dispatch state change
  state.currentTab = tabName
}

// Instantiate a router and set the index route
// which is what get() will return when the hash is empty.
const router = Router('lions')

// Listen to changes in the url
router.listen(activateTab)

<TabBar
  tabs={[
    { name: 'lions', label: 'Lions' },
    { name: 'tigers', label: 'Tigers' }
  ]}
  onSelect={ tab => router.go(tab.name) }
  selectedTab={ state.currentTab } />

History example

This is an example of the same tab UI that uses a Browser History instance for routing AND is connected to your favorite state manager. It's on you to install and instantiate a history object, which the router factory accepts its second argument.

yarn add history

import { Router } from 'pathricia'
import createHistory from 'history/createBrowserHistory'

const state = { currentTab: 'lions' }
 
function activateTab(tabName) {
  // Dispatch state change
  state.currentTab = tabName
}

const browserHistory = createHistory()

// Instantiate a router and set the index route
// which is what get() will return when the hash is empty.
const router = Router('lions', browserHistory)

// Listen to changes in the url
router.listen(activateTab)

<TabBar
  tabs={[
    { name: 'lions', label: 'Lions' },
    { name: 'tigers', label: 'Tigers' }
  ]}
  onSelect={ tab => router.go(tab.name) }
  selectedTab={ state.currentTab } />

API

The Pathricia Router is a factory function that returns an object with six methods: go, get, isActive, back, forward and listen. The factory accepts two arguments, the first of which is the index an the second being the history instance you wish to use. If you don't provide an instance of a history, the router will work just fine with location.hash.

In fact, this router was designed to be used with only location.hash, so don't feel like you're missing out if you don't provide a history! The only real difference is that the back and forward methods will not work in hash-only mode. This might change in the future, but I need to keep track of the history manually, so I'll save it for a future release.

Register a route change listener by calling the listen method with a function. The callback will be called with the new route each time the route changes. You can easily hook this up into your state manager, as shown above. If you call the function thar is returned, you'll de-register your listener callback.

The central methods you'll use the most is the go and the get methods. The go(toRoute) method sets the location to be what you passed as toRoute, and then call all listeners. If you are using history, you can also pass a second replace parameter to go(), in which case the route will replace the current route.

The get() method just returns what the current route is. If there is no current route, get() will return what you passed the router factory as the indexRoute argument. Easy peasy.

Examples and usage ideas

React app example

Check the example folder for a quick React-based example with tabs.

Use in conditionals

If all you want is to check what the current route is, you can do this:

/* will return false if you are NOT where you are checking. */
const router = Router(false)

if(router.get() === 'route') {
  console.log(`at route example.com/#route`)
}

// Or alternatively

if(router.isActive('route')) {
  console.log(`at route example.com/#route`)
}

Note that the router won't do anything unless you call a method, so just calling the factory will not cause any overhead more than a simple function call. The route change listener is dynamically enabled and disabled when you add or remove listeners. If you have a need for many different "index routes", you can just conjure up as many routers as you want.

Use in node (or other windowless basements)

Since the Pathricia router uses window.location.hash, you obviously need access to the window object to use it in hash-only mode. If you need to use this in node, just pass a MemoryHistory (or something) from the history package as the second argument for the factory function. Then Pathricia will not try to access the window at any point.

File an issue if the fact that Pathricia reads from the window object in becomes an issue at some point.

Bonus router

Because what would a package be without a BONUS?

The precursor to the Pathricia router is an even simpler hash-only router. I included it too because I really like it. it has no possibility to use a history instance, and no possibility to de-register listeners.

Just the essence of routing.

Use it by importing it from Pathricia:

import { SimpleRouter } from 'pathricia'