An open API service indexing awesome lists of open source software.

https://github.com/doasync/trace-router

The next generation router for your app
https://github.com/doasync/trace-router

Last synced: 8 months ago
JSON representation

The next generation router for your app

Awesome Lists containing this project

README

          

[![NPM Version][npm-image]][npm-url] ![NPM Downloads][downloads-image] [![GitHub issues][issues-image]][issues-url]

[npm-image]: https://img.shields.io/npm/v/trace-router.svg
[npm-url]: https://www.npmjs.com/package/trace-router
[downloads-image]: https://img.shields.io/npm/dw/trace-router.svg
[deps-image]: https://david-dm.org/doasync/trace-router.svg
[issues-image]: https://img.shields.io/github/issues/doasync/trace-router.svg
[issues-url]: https://github.com/doasync/trace-router/issues

# Trace Router

The next generation router for your app

### Installation

```
yarn add effector trace-router
```

### Examples

Create a router:

```js
import history from 'history/browser';
import { createRouter, history } from 'trace-router';

export const router = createRouter({ history });
```

Create routes:

```ts
// This route is used only for redirection below
export const exactRoot = router.add({ path: '/' });

// User section
export const user = router.add('/user(/.*)?'); // parent route
export const userProfile = router.add('/user');
export const userTickets = router.add('/user/tickets');
export const userTicket = router.add<{ id: number }>('/user/tickets/:id');

// Info section
export const joinUs = router.add('/join-us');
export const about = router.add('/about');
export const privacy = router.add('/privacy');

// Merge routes to create a parent route
// When you can't create common path
export const info = router.merge([joinUs, about, privacy]);

// Redirect from "/" to "/user"
exactRoot.visible.watch(visible => {
if (visible) {
user.redirect();
}
});
```

Use routes in React (`trace-router-react` package):

```jsx
export const Root = () => (
<>
{useRoute(user) && }
{useRoute(info) && }
{useStore(router.noMatches) && }
>
);

export const UserPage = () => (


{useRoute(userProfile) && }
{useRoute(userTickets) && }
{useRoute(userTicket) && }


);

export const InfoPage = () => (


{useRoute(joinUs) && }
{useRoute(about) && }
{useRoute(privacy) && }


);
```

You can also use `Route` component instead of a hook:

```tsx

```

Use links to navigate routes directly:

```jsx
About
```

Use can add params to the route (if it has ones):

```jsx

Month

```

The above link compiles to something like:

```jsx

Join Us

```

Here is how you compile route to a `string`:

```jsx
const href = route.compile({
params: { id: 100 },
query: {
lang: 'ru',
},
hash: '#description',
});
```

Manual route navigation:

```jsx
product.navigate({ id: '100' })} />
```

or `redirect` + `compile` as an example:

```jsx

product.router.redirect({
to: product.compile({ params: { id: '100' } }),
state: { back },
})
}
/>
```

You can use another history for a router:

```jsx
import hashHistory from 'history/hash';
import { router } from '~/core/router';

router.use(hashHistory);
```

You can bind one router to another:

```ts
export const product = router
.add<{ tab: string }>('/product:tab(.*)?')
.bind('tab', { router: tabRouter });
```

`.bind` method binds child router path to a parent router parameter

You can have an url `/product/info` where:
`/product` - the path of the main router (without a parameter)
`/info` - tabRouter path

### Types

Router

```ts
export type Router = {
history: History;
historyUpdated: Event>;
historyUpdate: Store>;
navigate: Event>;
redirect: Event>;
shift: Event;
back: Event;
forward: Event;
location: Store>;
action: Store;
pathname: Store;
search: Store;
hash: Store;
state: Store;
key: Store;
href: Store;
query: Store;
hasMatches: Store;
noMatches: Store;
add:

(
pathConfig: Pattern | RouteConfig
) => Route

>;
merge: (routes: T) => MergedRoute;
none: (routes: T) => MergedRoute;
use: (
givenHistory: BrowserHistory | HashHistory | MemoryHistory
) => void;
};
```

Route

```ts
export type Route

= {
visible: Store;
params: Store;
config: RouteConfig;
compile: (compileConfig?: CompileConfig

) => string;
router: R extends Router ? Router : never;
navigate: Event

;
redirect: Event

;
bindings: Partial<{ [K in keyof P]: BindConfig }>;
bind: (
param: keyof P,
bindConfig: {
router: Router;
parse?: (rawParam?: string) => string | undefined;
format?: (path?: string) => string | undefined;
}
) => Route

;
};
```

Other typings

```ts
export type ToLocation =
| string
| { to?: To; state?: S };
export type Delta = number;
export type Href = string;
export type Pattern = string;
export interface Query extends ObjectString {}
export interface Params extends ObjectUnknown {}

export type RouterConfig = {
history?: BrowserHistory | HashHistory | MemoryHistory;
root?: InitialEntry;
};

export type RouteConfig = {
path: Pattern;
matchOptions?: ParseOptions & TokensToRegexpOptions & RegexpToFunctionOptions;
};

export type CompileConfig

= {
params?: P;
query?: string[][] | Record | string | URLSearchParams;
hash?: string;
options?: ParseOptions & TokensToFunctionOptions;
};

export type BindConfig = {
router: Router;
parse?: (rawParam?: string) => string | undefined;
format?: (path?: string) => string | undefined;
};

export type MergedRoute = {
visible: Store;
routes: Route[];
configs: RouteConfig[];
};
```

### Repo

Give `trace-router` a star!

GitHub ★: https://github.com/doasync/trace-router