0.7.3 • Published 7 months ago

isomorphic-app-router v0.7.3

Weekly downloads
-
License
MIT
Repository
github
Last release
7 months ago

Getting Started

This package is intended to work seamlessly with history and URLPattern – although URLPattern requires a polyfill at the moment.

npm i -D isomorphic-app-router urlpattern-polyfill

Installation

// <repo>/library/router.ts
import { RouterBuilderFactory, URLPatternResolver } from 'isomorphic-app-router'
import { createBrowserHistory } from 'history'
import "urlpattern-polyfill"

export const history = createBrowserHistory()

export const RouterBuilder = RouterBuilderFactory({
  history,
  resolver: URLPatternResolver,
})
import { …, PathToRegexpResolver } from 'isomorphic-app-router'
import { match } from 'path-to-regexp'

export const RouterBuilder = RouterBuilderFactory({
  …
  resolver: PathToRegexpResolver(match),
})

Your first route

import { RouterBuilder } from '<repo>/library/router'

type Route =
  | { name: 'Home' }
  | { name: 'Product', productId: number }
  | { name: 'NotFound' }

const router = RouterBuilder<Route>()
  // define `Home` route
  .set('home', '/', () => ({ name: 'Home' }))

  // define `Product` route
  .set('product', '/product/:id', ({ params }) => {
    const productId = Number(params.id) // params: { id: string }

    return Number.isNaN(productId)
      ? { name: 'NotFound' }
      : { name: 'Product', productId }
  })

  // finish building the router
  .or(() => ({ name: 'NotFound' })) // required _at the end_

router.makeLinkTo('home') // parameter-less path, no arg required
router.makeLinkTo('product', { id: '2' }) // TS forcefully asks for the route parameters

Path Syntax

I based the library on web standards, namely URLPattern. Which itself based its syntax on path-to-regexp. Therefore, their syntax prevails.

The MDN website is an excellent place to start. Here are a few tips though:

  • /post/* will match /post/, /post/1 & /post/1/2 ; but not /post :warning: To match /post => post{/*}?
  • /post{/:id}? matches /post & /post/1, not /post/1/2
  • Regex groups like /books/(\\d+) can be used but break intellisense of path parameters
  • For nested routers, type the home as {/}? 😉

Recipes / Advanced Usage

Why yet-another X ?

Because I never encountered one that made sense to me:

!Important Routing and history are separate concerns.

A history can be unique or cascaded across the client-side app, it should not impact routing.

My opinion: use one history per app.

You want routing? Fine: provide the history to watch changes, you'll get the active route in return.

You want some nested routing? Perfect, provide the history and a base path, you'll get the active route in return.

You want to mix browser, hash and/or memory routing? Fine: provide a different history per-router.

All in pure JS, testable with no framework, adaptable to every framework. Testable: No jsdom needed, no {your framework}-library, no nothing. Aim at that 3ms test 😉.

Fully type-safe and type-driven for mad-typers. It comes with a double-function cost, but still worth it! Now you have the treat of typed path parameters 😛

Contributing

Any contribution is welcome, fork and PR 😁

# clone the repo, then
npm ci
npm run test
0.7.3

7 months ago

0.7.2

7 months ago

0.7.1

7 months ago

0.7.0

8 months ago

0.6.0

8 months ago

0.5.1

8 months ago

0.5.0

8 months ago

0.4.0

8 months ago

0.3.0

8 months ago

0.2.0

8 months ago

0.1.0

8 months ago