Skip to content

Commit

Permalink
refactor!: rewrite library (#107)
Browse files Browse the repository at this point in the history
  • Loading branch information
pi0 authored Jul 4, 2024
1 parent 1747ff7 commit a1e42a0
Show file tree
Hide file tree
Showing 28 changed files with 1,691 additions and 1,258 deletions.
205 changes: 92 additions & 113 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,81 +1,116 @@
# 🌳 radix3
# 🌳 rou3

[![npm version][npm-version-src]][npm-version-href]
[![npm downloads][npm-downloads-src]][npm-downloads-href]
[![bundle][bundle-src]][bundle-href]
[![Codecov][codecov-src]][codecov-href]
[![License][license-src]][license-href]
[![JSDocs][jsdocs-src]][jsdocs-href]
<!-- automd:badges -->

Lightweight and fast router for JavaScript based on [Radix Tree](https://en.wikipedia.org/wiki/Radix_tree).
[![npm version](https://img.shields.io/npm/v/rou3)](https://npmjs.com/package/rou3)
[![npm downloads](https://img.shields.io/npm/dm/rou3)](https://npmjs.com/package/rou3)

<!-- /automd -->

Lightweight and fast router for JavaScript.

> [!NOTE]
> Radix3 migrated to Rou3! See [#108](https://github.com/unjs/radix3/issues/108) for notes and [radix3 branch](https://github.com/unjs/rou3/tree/radix3) for legacy codebase.
## Usage

**Install package:**
**Install:**

<!-- automd:pm-install -->

```sh
# ✨ Auto-detect
npx nypm install rou3

# npm
npm i radix3
npm install rou3

# yarn
yarn add radix3
yarn add rou3

# pnpm
pnpm i radix3
pnpm install rou3

# bun
bun install rou3
```

<!-- /automd -->

**Import:**

```js
// ESM
import { createRouter } from "radix3";
<!-- automd:jsimport cdn cjs src="./src/index.ts"-->

**ESM** (Node.js, Bun)

// CJS
const { createRouter } = require("radix3");
```js
import {
createRouter,
addRoute,
findRoute,
removeRoute,
matchAllRoutes,
} from "rou3";
```

**Create a router instance and insert routes:**
**CommonJS** (Legacy Node.js)

```js
const router = createRouter(/* options */);

router.insert("/path", { payload: "this path" });
router.insert("/path/:name", { payload: "named route" });
router.insert("/path/foo/**", { payload: "wildcard route" });
router.insert("/path/foo/**:name", { payload: "named wildcard route" });
const {
createRouter,
addRoute,
findRoute,
removeRoute,
matchAllRoutes,
} = require("rou3");
```

**Match route to access matched data:**
**CDN** (Deno, Bun and Browsers)

```js
router.lookup("/path");
// { payload: 'this path' }
import {
createRouter,
addRoute,
findRoute,
removeRoute,
matchAllRoutes,
} from "https://esm.sh/rou3";
```

router.lookup("/path/fooval");
// { payload: 'named route', params: { name: 'fooval' } }
<!-- /automd -->

router.lookup("/path/foo/bar/baz");
// { payload: 'wildcard route' }
**Create a router instance and insert routes:**

router.lookup("/");
// null (no route matched for/)
```
```js
import { createRouter, addRoute } from "rou3";

## Methods
const router = createRouter(/* options */);

### `router.insert(path, data)`
addRoute(router, "/path", "GET", { payload: "this path" });
addRoute(router, "/path/:name", "GET", { payload: "named route" });
addRoute(router, "/path/foo/**", "GET", { payload: "wildcard route" });
addRoute(router, "/path/foo/**:name", "GET", {
payload: "named wildcard route",
});
```

`path` can be static or using `:placeholder` or `**` for wildcard paths.
**Match route to access matched data:**

The `data` object will be returned on matching params. It should be an object like `{ handler }` and not containing reserved keyword `params`.
```js
// Returns { payload: 'this path' }
findRoute(router, "/path", "GET");

### `router.lookup(path)`
// Returns { payload: 'named route', params: { name: 'fooval' } }
findRoute(router, "/path/fooval", "GET");

Returns matched data for `path` with optional `params` key if mached route using placeholders.
// Returns { payload: 'wildcard route' }
findRoute(router, "/path/foo/bar/baz", "GET");

### `router.remove(path)`
// Returns undefined (no route matched for/)
findRoute(router, "/", "GET");
```

Remove route matching `path`.
## Methods

## Options

Expand All @@ -84,88 +119,32 @@ You can initialize router instance with options:
```ts
const router = createRouter({
strictTrailingSlash: true,
routes: {
"/foo": {},
},
});
```

- `routes`: An object specifying initial routes to add
- `strictTrailingSlash`: By default router ignored trailing slash for matching and adding routes. When set to `true`, matching with trailing slash is different.

### Route Matcher

Creates a multi matcher from router tree that can match **all routes** matching path:

```ts
import { createRouter, toRouteMatcher } from "radix3";

const router = createRouter({
routes: {
"/foo": { m: "foo" }, // Matches /foo only
"/foo/**": { m: "foo/**" }, // Matches /foo/<any>
"/foo/bar": { m: "foo/bar" }, // Matches /foo/bar only
"/foo/bar/baz": { m: "foo/bar/baz" }, // Matches /foo/bar/baz only
"/foo/*/baz": { m: "foo/*/baz" }, // Matches /foo/<any>/baz
},
});

const matcher = toRouteMatcher(router);

const matches = matcher.matchAll("/foo/bar/baz");

// [
// {
// "m": "foo/**",
// },
// {
// "m": "foo/*/baz",
// },
// {
// "m": "foo/bar/baz",
// },
// ]
```

### Route Matcher Export
## Performance

It is also possible to export and then rehydrate a matcher from pre-compiled rules.
See [benchmark](./benchmark).

```ts
import { exportMatcher, createMatcherFromExport } from "radix3";
## License

// Assuming you already have a matcher
// you can export this to a JSON-type object
const json = exportMatcher(matcher);
<!-- automd:contributors license=MIT author="pi0" -->

// and then rehydrate this later
const newMatcher = createMatcherFromExport(json);
Published under the [MIT](https://github.com/unjs/h3/blob/main/LICENSE) license.
Made by [@pi0](https://github.com/pi0) and [community](https://github.com/unjs/h3/graphs/contributors) 💛
<br><br>
<a href="https://github.com/unjs/h3/graphs/contributors">
<img src="https://contrib.rocks/image?repo=unjs/h3" />
</a>

const matches = newMatcher.matchAll("/foo/bar/baz");
```
<!-- /automd -->

## Performance
<!-- automd:with-automd -->

See [benchmark](./benchmark).
---

## License
_🤖 auto updated with [automd](https://automd.unjs.io)_

Based on original work of [`charlieduong94/radix-router`](https://github.com/charlieduong94/radix-router)
by [Charlie Duong](https://github.com/charlieduong94) (MIT)

[MIT](./LICENSE) - Made with ❤️

<!-- Badges -->

[npm-version-src]: https://img.shields.io/npm/v/radix3?style=flat&colorA=18181B&colorB=F0DB4F
[npm-version-href]: https://npmjs.com/package/radix3
[npm-downloads-src]: https://img.shields.io/npm/dm/radix3?style=flat&colorA=18181B&colorB=F0DB4F
[npm-downloads-href]: https://npmjs.com/package/radix3
[codecov-src]: https://img.shields.io/codecov/c/gh/unjs/radix3/main?style=flat&colorA=18181B&colorB=F0DB4F
[codecov-href]: https://codecov.io/gh/unjs/radix3
[bundle-src]: https://img.shields.io/bundlephobia/minzip/radix3?style=flat&colorA=18181B&colorB=F0DB4F
[bundle-href]: https://bundlephobia.com/result?p=radix3
[license-src]: https://img.shields.io/github/license/unjs/radix3.svg?style=flat&colorA=18181B&colorB=F0DB4F
[license-href]: https://github.com/unjs/radix3/blob/main/LICENSE
[jsdocs-src]: https://img.shields.io/badge/jsDocs.io-reference-18181B?style=flat&colorA=18181B&colorB=F0DB4F
[jsdocs-href]: https://www.jsdocs.io/package/radix3
<!-- /automd -->
104 changes: 0 additions & 104 deletions benchmark/README.md

This file was deleted.

21 changes: 21 additions & 0 deletions benchmark/bench.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { bench, group, run } from 'mitata'
import "./test.mjs"
import { routers } from './routers.mjs'
import { requests, routes } from './input.mjs'

const withParams = !process.argv.includes('--no-params')

// Benchmark all routers
group(`All requests (match params: ${withParams})`, () => {
for (const name in routers) {
const router = new routers[name](routes, withParams)
router.init()
bench(name, () => {
for (const request of requests) {
router.match(request)
}
})
}
})

run({})
Loading

0 comments on commit a1e42a0

Please sign in to comment.