initial commit
This commit is contained in:
21
node_modules/radix3/LICENSE
generated
vendored
Normal file
21
node_modules/radix3/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) Pooya Parsa <pooya@pi0.io>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
157
node_modules/radix3/README.md
generated
vendored
Normal file
157
node_modules/radix3/README.md
generated
vendored
Normal file
@@ -0,0 +1,157 @@
|
||||
# 🌳 radix3
|
||||
|
||||
[![npm version][npm-version-src]][npm-version-href]
|
||||
[![npm downloads][npm-downloads-src]][npm-downloads-href]
|
||||
[![Github Actions][github-actions-src]][github-actions-href]
|
||||
[![Codecov][codecov-src]][codecov-href]
|
||||
[![bundle][bundle-src]][bundle-href]
|
||||
|
||||
Lightweight and fast router for JavaScript based on [Radix Tree](https://en.wikipedia.org/wiki/Radix_tree).
|
||||
|
||||
## Usage
|
||||
|
||||
**Install package:**
|
||||
|
||||
```sh
|
||||
# npm
|
||||
npm i radix3
|
||||
|
||||
# yarn
|
||||
yarn add radix3
|
||||
|
||||
# pnpm
|
||||
pnpm i radix3
|
||||
```
|
||||
|
||||
**Import:**
|
||||
|
||||
```js
|
||||
// ESM
|
||||
import { createRouter } from 'radix3'
|
||||
|
||||
// CJS
|
||||
const { createRouter } = require('radix3')
|
||||
```
|
||||
|
||||
**Create a router instance and insert routes:**
|
||||
|
||||
```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' })
|
||||
```
|
||||
|
||||
***Match route to access matched data:**
|
||||
|
||||
```js
|
||||
// { payload: 'this path' }
|
||||
router.lookup('/path')
|
||||
|
||||
// { payload: 'named route', params: { name: 'fooval' } }
|
||||
router.lookup('/path/fooval')
|
||||
|
||||
// { payload: 'wildcard route' }
|
||||
router.lookup('/path/foo/bar/baz')
|
||||
|
||||
// null (no route matched for/)
|
||||
router.lookup('/')
|
||||
```
|
||||
|
||||
## Methods
|
||||
|
||||
### `router.insert(path, data)`
|
||||
|
||||
`path` can be static or using `:placeholder`s and `**` for wildcard paths.
|
||||
|
||||
The `data` object will be returned on matching params. It should be an object like `{ handler }` and not containing reserved keyword `params`.
|
||||
|
||||
### `router.lookup(path)`
|
||||
|
||||
Returns matched data for `path` with optional `params` key if mached route using placeholders.
|
||||
|
||||
### `router.remove(path)`
|
||||
|
||||
Remove route matching `path`.
|
||||
|
||||
## Options
|
||||
|
||||
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
|
||||
|
||||
**Experimental feature:** Behavior might change in a semver-minor release.
|
||||
|
||||
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",
|
||||
// },
|
||||
// ]
|
||||
```
|
||||
|
||||
## Performance
|
||||
|
||||
See [benchmark](./benchmark).
|
||||
|
||||
## License
|
||||
|
||||
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-square
|
||||
[npm-version-href]: https://npmjs.com/package/radix3
|
||||
|
||||
[npm-downloads-src]: https://img.shields.io/npm/dm/radix3?style=flat-square
|
||||
[npm-downloads-href]: https://npmjs.com/package/radix3
|
||||
|
||||
[github-actions-src]: https://img.shields.io/github/workflow/status/unjs/radix3/ci/main?style=flat-square
|
||||
[github-actions-href]: https://github.com/unjs/radix3/actions?query=workflow%3Aci
|
||||
|
||||
[codecov-src]: https://img.shields.io/codecov/c/gh/unjs/radix3/main?style=flat-square
|
||||
[codecov-href]: https://codecov.io/gh/unjs/radix3
|
||||
|
||||
[bundle-src]: https://img.shields.io/bundlephobia/minzip/radix3?style=flat-square
|
||||
[bundle-href]: https://bundlephobia.com/result?p=radix3
|
||||
214
node_modules/radix3/dist/index.cjs
generated
vendored
Normal file
214
node_modules/radix3/dist/index.cjs
generated
vendored
Normal file
@@ -0,0 +1,214 @@
|
||||
'use strict';
|
||||
|
||||
const NODE_TYPES = {
|
||||
NORMAL: 0,
|
||||
WILDCARD: 1,
|
||||
PLACEHOLDER: 2
|
||||
};
|
||||
|
||||
function createRouter(options = {}) {
|
||||
const ctx = {
|
||||
options,
|
||||
rootNode: createRadixNode(),
|
||||
staticRoutesMap: {}
|
||||
};
|
||||
const normalizeTrailingSlash = (p) => options.strictTrailingSlash ? p : p.replace(/\/$/, "") || "/";
|
||||
if (options.routes) {
|
||||
for (const path in options.routes) {
|
||||
insert(ctx, normalizeTrailingSlash(path), options.routes[path]);
|
||||
}
|
||||
}
|
||||
return {
|
||||
ctx,
|
||||
lookup: (path) => lookup(ctx, normalizeTrailingSlash(path)),
|
||||
insert: (path, data) => insert(ctx, normalizeTrailingSlash(path), data),
|
||||
remove: (path) => remove(ctx, normalizeTrailingSlash(path))
|
||||
};
|
||||
}
|
||||
function lookup(ctx, path) {
|
||||
const staticPathNode = ctx.staticRoutesMap[path];
|
||||
if (staticPathNode) {
|
||||
return staticPathNode.data;
|
||||
}
|
||||
const sections = path.split("/");
|
||||
const params = {};
|
||||
let paramsFound = false;
|
||||
let wildcardNode = null;
|
||||
let node = ctx.rootNode;
|
||||
let wildCardParam = null;
|
||||
for (let i = 0; i < sections.length; i++) {
|
||||
const section = sections[i];
|
||||
if (node.wildcardChildNode !== null) {
|
||||
wildcardNode = node.wildcardChildNode;
|
||||
wildCardParam = sections.slice(i).join("/");
|
||||
}
|
||||
const nextNode = node.children.get(section);
|
||||
if (nextNode !== void 0) {
|
||||
node = nextNode;
|
||||
} else {
|
||||
node = node.placeholderChildNode;
|
||||
if (node !== null) {
|
||||
params[node.paramName] = section;
|
||||
paramsFound = true;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((node === null || node.data === null) && wildcardNode !== null) {
|
||||
node = wildcardNode;
|
||||
params[node.paramName || "_"] = wildCardParam;
|
||||
paramsFound = true;
|
||||
}
|
||||
if (!node) {
|
||||
return null;
|
||||
}
|
||||
if (paramsFound) {
|
||||
return {
|
||||
...node.data,
|
||||
params: paramsFound ? params : void 0
|
||||
};
|
||||
}
|
||||
return node.data;
|
||||
}
|
||||
function insert(ctx, path, data) {
|
||||
let isStaticRoute = true;
|
||||
const sections = path.split("/");
|
||||
let node = ctx.rootNode;
|
||||
let _unnamedPlaceholderCtr = 0;
|
||||
for (let i = 0; i < sections.length; i++) {
|
||||
const section = sections[i];
|
||||
let childNode;
|
||||
if (childNode = node.children.get(section)) {
|
||||
node = childNode;
|
||||
} else {
|
||||
const type = getNodeType(section);
|
||||
childNode = createRadixNode({ type, parent: node });
|
||||
node.children.set(section, childNode);
|
||||
if (type === NODE_TYPES.PLACEHOLDER) {
|
||||
childNode.paramName = section === "*" ? `_${_unnamedPlaceholderCtr++}` : section.slice(1);
|
||||
node.placeholderChildNode = childNode;
|
||||
isStaticRoute = false;
|
||||
} else if (type === NODE_TYPES.WILDCARD) {
|
||||
node.wildcardChildNode = childNode;
|
||||
childNode.paramName = section.substring(3) || "_";
|
||||
isStaticRoute = false;
|
||||
}
|
||||
node = childNode;
|
||||
}
|
||||
}
|
||||
node.data = data;
|
||||
if (isStaticRoute === true) {
|
||||
ctx.staticRoutesMap[path] = node;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
function remove(ctx, path) {
|
||||
let success = false;
|
||||
const sections = path.split("/");
|
||||
let node = ctx.rootNode;
|
||||
for (let i = 0; i < sections.length; i++) {
|
||||
const section = sections[i];
|
||||
node = node.children.get(section);
|
||||
if (!node) {
|
||||
return success;
|
||||
}
|
||||
}
|
||||
if (node.data) {
|
||||
const lastSection = sections[sections.length - 1];
|
||||
node.data = null;
|
||||
if (Object.keys(node.children).length === 0) {
|
||||
const parentNode = node.parent;
|
||||
delete parentNode[lastSection];
|
||||
parentNode.wildcardChildNode = null;
|
||||
parentNode.placeholderChildNode = null;
|
||||
}
|
||||
success = true;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
function createRadixNode(options = {}) {
|
||||
return {
|
||||
type: options.type || NODE_TYPES.NORMAL,
|
||||
parent: options.parent || null,
|
||||
children: /* @__PURE__ */ new Map(),
|
||||
data: options.data || null,
|
||||
paramName: options.paramName || null,
|
||||
wildcardChildNode: null,
|
||||
placeholderChildNode: null
|
||||
};
|
||||
}
|
||||
function getNodeType(str) {
|
||||
if (str.startsWith("**")) {
|
||||
return NODE_TYPES.WILDCARD;
|
||||
}
|
||||
if (str[0] === ":" || str === "*") {
|
||||
return NODE_TYPES.PLACEHOLDER;
|
||||
}
|
||||
return NODE_TYPES.NORMAL;
|
||||
}
|
||||
|
||||
function toRouteMatcher(router) {
|
||||
const table = _routerNodeToTable("", router.ctx.rootNode);
|
||||
return _createMatcher(table);
|
||||
}
|
||||
function _createMatcher(table) {
|
||||
return {
|
||||
ctx: { table },
|
||||
matchAll: (path) => _matchRoutes(path, table)
|
||||
};
|
||||
}
|
||||
function _createRouteTable() {
|
||||
return {
|
||||
static: /* @__PURE__ */ new Map(),
|
||||
wildcard: /* @__PURE__ */ new Map(),
|
||||
dynamic: /* @__PURE__ */ new Map()
|
||||
};
|
||||
}
|
||||
function _matchRoutes(path, table) {
|
||||
const matches = [];
|
||||
for (const [key, value] of table.wildcard) {
|
||||
if (path.startsWith(key)) {
|
||||
matches.push(value);
|
||||
}
|
||||
}
|
||||
for (const [key, value] of table.dynamic) {
|
||||
if (path.startsWith(key + "/")) {
|
||||
const subPath = "/" + path.substring(key.length).split("/").splice(2).join("/");
|
||||
matches.push(..._matchRoutes(subPath, value));
|
||||
}
|
||||
}
|
||||
const staticMatch = table.static.get(path);
|
||||
if (staticMatch) {
|
||||
matches.push(staticMatch);
|
||||
}
|
||||
return matches.filter(Boolean);
|
||||
}
|
||||
function _routerNodeToTable(initialPath, initialNode) {
|
||||
const table = _createRouteTable();
|
||||
function _addNode(path, node) {
|
||||
if (path) {
|
||||
if (node.type === NODE_TYPES.NORMAL && !(path.includes("*") || path.includes(":"))) {
|
||||
table.static.set(path, node.data);
|
||||
} else if (node.type === NODE_TYPES.WILDCARD) {
|
||||
table.wildcard.set(path.replace("/**", ""), node.data);
|
||||
} else if (node.type === NODE_TYPES.PLACEHOLDER) {
|
||||
const subTable = _routerNodeToTable("", node);
|
||||
if (node.data) {
|
||||
subTable.static.set("/", node.data);
|
||||
}
|
||||
table.dynamic.set(path.replace(/\/\*|\/:\w+/, ""), subTable);
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (const [childPath, child] of node.children.entries()) {
|
||||
_addNode(`${path}/${childPath}`.replace("//", "/"), child);
|
||||
}
|
||||
}
|
||||
_addNode(initialPath, initialNode);
|
||||
return table;
|
||||
}
|
||||
|
||||
exports.NODE_TYPES = NODE_TYPES;
|
||||
exports.createRouter = createRouter;
|
||||
exports.toRouteMatcher = toRouteMatcher;
|
||||
74
node_modules/radix3/dist/index.d.ts
generated
vendored
Normal file
74
node_modules/radix3/dist/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
declare const NODE_TYPES: {
|
||||
NORMAL: 0;
|
||||
WILDCARD: 1;
|
||||
PLACEHOLDER: 2;
|
||||
};
|
||||
declare type _NODE_TYPES = typeof NODE_TYPES;
|
||||
declare type NODE_TYPE = _NODE_TYPES[keyof _NODE_TYPES];
|
||||
declare type _RadixNodeDataObject = {
|
||||
params?: never;
|
||||
[key: string]: any;
|
||||
};
|
||||
declare type RadixNodeData<T extends _RadixNodeDataObject = _RadixNodeDataObject> = T;
|
||||
declare type MatchedRoute<T extends RadixNodeData = RadixNodeData> = Omit<T, 'params'> & {
|
||||
params?: Record<string, any>;
|
||||
};
|
||||
interface RadixNode<T extends RadixNodeData = RadixNodeData> {
|
||||
type: NODE_TYPE;
|
||||
parent: RadixNode<T> | null;
|
||||
children: Map<string, RadixNode<T>>;
|
||||
data: RadixNodeData | null;
|
||||
paramName: string | null;
|
||||
wildcardChildNode: RadixNode<T> | null;
|
||||
placeholderChildNode: RadixNode<T> | null;
|
||||
}
|
||||
interface RadixRouterOptions {
|
||||
strictTrailingSlash?: boolean;
|
||||
routes?: Record<string, any>;
|
||||
}
|
||||
interface RadixRouterContext<T extends RadixNodeData = RadixNodeData> {
|
||||
options: RadixRouterOptions;
|
||||
rootNode: RadixNode<T>;
|
||||
staticRoutesMap: Record<string, RadixNode>;
|
||||
}
|
||||
interface RadixRouter<T extends RadixNodeData = RadixNodeData> {
|
||||
ctx: RadixRouterContext<T>;
|
||||
/**
|
||||
* Perform lookup of given path in radix tree
|
||||
* @param path - the path to search for
|
||||
*
|
||||
* @returns The data that was originally inserted into the tree
|
||||
*/
|
||||
lookup(path: string): MatchedRoute<T> | null;
|
||||
/**
|
||||
* Perform an insert into the radix tree
|
||||
* @param path - the prefix to match
|
||||
* @param data - the associated data to path
|
||||
*
|
||||
*/
|
||||
insert(path: string, data: T): void;
|
||||
/**
|
||||
* Perform a remove on the tree
|
||||
* @param { string } data.path - the route to match
|
||||
*
|
||||
* @returns A boolean signifying if the remove was successful or not
|
||||
*/
|
||||
remove(path: string): boolean;
|
||||
}
|
||||
|
||||
declare function createRouter<T extends RadixNodeData = RadixNodeData>(options?: RadixRouterOptions): RadixRouter<T>;
|
||||
|
||||
interface RouteTable {
|
||||
static: Map<string, RadixNodeData>;
|
||||
wildcard: Map<string, RadixNodeData>;
|
||||
dynamic: Map<string, RouteTable>;
|
||||
}
|
||||
interface RouteMatcher {
|
||||
ctx: {
|
||||
table: RouteTable;
|
||||
};
|
||||
matchAll: (path: string) => RadixNodeData[];
|
||||
}
|
||||
declare function toRouteMatcher(router: RadixRouter): RouteMatcher;
|
||||
|
||||
export { MatchedRoute, NODE_TYPE, NODE_TYPES, RadixNode, RadixNodeData, RadixRouter, RadixRouterContext, RadixRouterOptions, RouteMatcher, RouteTable, createRouter, toRouteMatcher };
|
||||
210
node_modules/radix3/dist/index.mjs
generated
vendored
Normal file
210
node_modules/radix3/dist/index.mjs
generated
vendored
Normal file
@@ -0,0 +1,210 @@
|
||||
const NODE_TYPES = {
|
||||
NORMAL: 0,
|
||||
WILDCARD: 1,
|
||||
PLACEHOLDER: 2
|
||||
};
|
||||
|
||||
function createRouter(options = {}) {
|
||||
const ctx = {
|
||||
options,
|
||||
rootNode: createRadixNode(),
|
||||
staticRoutesMap: {}
|
||||
};
|
||||
const normalizeTrailingSlash = (p) => options.strictTrailingSlash ? p : p.replace(/\/$/, "") || "/";
|
||||
if (options.routes) {
|
||||
for (const path in options.routes) {
|
||||
insert(ctx, normalizeTrailingSlash(path), options.routes[path]);
|
||||
}
|
||||
}
|
||||
return {
|
||||
ctx,
|
||||
lookup: (path) => lookup(ctx, normalizeTrailingSlash(path)),
|
||||
insert: (path, data) => insert(ctx, normalizeTrailingSlash(path), data),
|
||||
remove: (path) => remove(ctx, normalizeTrailingSlash(path))
|
||||
};
|
||||
}
|
||||
function lookup(ctx, path) {
|
||||
const staticPathNode = ctx.staticRoutesMap[path];
|
||||
if (staticPathNode) {
|
||||
return staticPathNode.data;
|
||||
}
|
||||
const sections = path.split("/");
|
||||
const params = {};
|
||||
let paramsFound = false;
|
||||
let wildcardNode = null;
|
||||
let node = ctx.rootNode;
|
||||
let wildCardParam = null;
|
||||
for (let i = 0; i < sections.length; i++) {
|
||||
const section = sections[i];
|
||||
if (node.wildcardChildNode !== null) {
|
||||
wildcardNode = node.wildcardChildNode;
|
||||
wildCardParam = sections.slice(i).join("/");
|
||||
}
|
||||
const nextNode = node.children.get(section);
|
||||
if (nextNode !== void 0) {
|
||||
node = nextNode;
|
||||
} else {
|
||||
node = node.placeholderChildNode;
|
||||
if (node !== null) {
|
||||
params[node.paramName] = section;
|
||||
paramsFound = true;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((node === null || node.data === null) && wildcardNode !== null) {
|
||||
node = wildcardNode;
|
||||
params[node.paramName || "_"] = wildCardParam;
|
||||
paramsFound = true;
|
||||
}
|
||||
if (!node) {
|
||||
return null;
|
||||
}
|
||||
if (paramsFound) {
|
||||
return {
|
||||
...node.data,
|
||||
params: paramsFound ? params : void 0
|
||||
};
|
||||
}
|
||||
return node.data;
|
||||
}
|
||||
function insert(ctx, path, data) {
|
||||
let isStaticRoute = true;
|
||||
const sections = path.split("/");
|
||||
let node = ctx.rootNode;
|
||||
let _unnamedPlaceholderCtr = 0;
|
||||
for (let i = 0; i < sections.length; i++) {
|
||||
const section = sections[i];
|
||||
let childNode;
|
||||
if (childNode = node.children.get(section)) {
|
||||
node = childNode;
|
||||
} else {
|
||||
const type = getNodeType(section);
|
||||
childNode = createRadixNode({ type, parent: node });
|
||||
node.children.set(section, childNode);
|
||||
if (type === NODE_TYPES.PLACEHOLDER) {
|
||||
childNode.paramName = section === "*" ? `_${_unnamedPlaceholderCtr++}` : section.slice(1);
|
||||
node.placeholderChildNode = childNode;
|
||||
isStaticRoute = false;
|
||||
} else if (type === NODE_TYPES.WILDCARD) {
|
||||
node.wildcardChildNode = childNode;
|
||||
childNode.paramName = section.substring(3) || "_";
|
||||
isStaticRoute = false;
|
||||
}
|
||||
node = childNode;
|
||||
}
|
||||
}
|
||||
node.data = data;
|
||||
if (isStaticRoute === true) {
|
||||
ctx.staticRoutesMap[path] = node;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
function remove(ctx, path) {
|
||||
let success = false;
|
||||
const sections = path.split("/");
|
||||
let node = ctx.rootNode;
|
||||
for (let i = 0; i < sections.length; i++) {
|
||||
const section = sections[i];
|
||||
node = node.children.get(section);
|
||||
if (!node) {
|
||||
return success;
|
||||
}
|
||||
}
|
||||
if (node.data) {
|
||||
const lastSection = sections[sections.length - 1];
|
||||
node.data = null;
|
||||
if (Object.keys(node.children).length === 0) {
|
||||
const parentNode = node.parent;
|
||||
delete parentNode[lastSection];
|
||||
parentNode.wildcardChildNode = null;
|
||||
parentNode.placeholderChildNode = null;
|
||||
}
|
||||
success = true;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
function createRadixNode(options = {}) {
|
||||
return {
|
||||
type: options.type || NODE_TYPES.NORMAL,
|
||||
parent: options.parent || null,
|
||||
children: /* @__PURE__ */ new Map(),
|
||||
data: options.data || null,
|
||||
paramName: options.paramName || null,
|
||||
wildcardChildNode: null,
|
||||
placeholderChildNode: null
|
||||
};
|
||||
}
|
||||
function getNodeType(str) {
|
||||
if (str.startsWith("**")) {
|
||||
return NODE_TYPES.WILDCARD;
|
||||
}
|
||||
if (str[0] === ":" || str === "*") {
|
||||
return NODE_TYPES.PLACEHOLDER;
|
||||
}
|
||||
return NODE_TYPES.NORMAL;
|
||||
}
|
||||
|
||||
function toRouteMatcher(router) {
|
||||
const table = _routerNodeToTable("", router.ctx.rootNode);
|
||||
return _createMatcher(table);
|
||||
}
|
||||
function _createMatcher(table) {
|
||||
return {
|
||||
ctx: { table },
|
||||
matchAll: (path) => _matchRoutes(path, table)
|
||||
};
|
||||
}
|
||||
function _createRouteTable() {
|
||||
return {
|
||||
static: /* @__PURE__ */ new Map(),
|
||||
wildcard: /* @__PURE__ */ new Map(),
|
||||
dynamic: /* @__PURE__ */ new Map()
|
||||
};
|
||||
}
|
||||
function _matchRoutes(path, table) {
|
||||
const matches = [];
|
||||
for (const [key, value] of table.wildcard) {
|
||||
if (path.startsWith(key)) {
|
||||
matches.push(value);
|
||||
}
|
||||
}
|
||||
for (const [key, value] of table.dynamic) {
|
||||
if (path.startsWith(key + "/")) {
|
||||
const subPath = "/" + path.substring(key.length).split("/").splice(2).join("/");
|
||||
matches.push(..._matchRoutes(subPath, value));
|
||||
}
|
||||
}
|
||||
const staticMatch = table.static.get(path);
|
||||
if (staticMatch) {
|
||||
matches.push(staticMatch);
|
||||
}
|
||||
return matches.filter(Boolean);
|
||||
}
|
||||
function _routerNodeToTable(initialPath, initialNode) {
|
||||
const table = _createRouteTable();
|
||||
function _addNode(path, node) {
|
||||
if (path) {
|
||||
if (node.type === NODE_TYPES.NORMAL && !(path.includes("*") || path.includes(":"))) {
|
||||
table.static.set(path, node.data);
|
||||
} else if (node.type === NODE_TYPES.WILDCARD) {
|
||||
table.wildcard.set(path.replace("/**", ""), node.data);
|
||||
} else if (node.type === NODE_TYPES.PLACEHOLDER) {
|
||||
const subTable = _routerNodeToTable("", node);
|
||||
if (node.data) {
|
||||
subTable.static.set("/", node.data);
|
||||
}
|
||||
table.dynamic.set(path.replace(/\/\*|\/:\w+/, ""), subTable);
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (const [childPath, child] of node.children.entries()) {
|
||||
_addNode(`${path}/${childPath}`.replace("//", "/"), child);
|
||||
}
|
||||
}
|
||||
_addNode(initialPath, initialNode);
|
||||
return table;
|
||||
}
|
||||
|
||||
export { NODE_TYPES, createRouter, toRouteMatcher };
|
||||
50
node_modules/radix3/package.json
generated
vendored
Normal file
50
node_modules/radix3/package.json
generated
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"name": "radix3",
|
||||
"version": "1.0.0",
|
||||
"description": "Lightweight and fast router for JavaScript based on Radix Tree",
|
||||
"repository": "unjs/radix3",
|
||||
"license": "MIT",
|
||||
"sideEffects": false,
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"require": "./dist/index.cjs",
|
||||
"import": "./dist/index.mjs"
|
||||
}
|
||||
},
|
||||
"main": "./dist/index.cjs",
|
||||
"module": "./dist/index.mjs",
|
||||
"types": "./dist/index.d.ts",
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"bench": "node ./benchmark/direct.mjs",
|
||||
"bench:http": "node ./benchmark/http.mjs",
|
||||
"bench:profile": "0x -o -D benchmark/.profile -- node ./benchmark/direct.mjs",
|
||||
"build": "unbuild",
|
||||
"dev": "vitest",
|
||||
"lint": "eslint --ext .ts,.mjs .",
|
||||
"playground": "pnpm jiti ./playground.ts",
|
||||
"release": "pnpm test && pnpm build && changelogen --release && git push --follow-tags && pnpm publish",
|
||||
"test": "pnpm lint && vitest run"
|
||||
},
|
||||
"devDependencies": {
|
||||
"0x": "^5.4.1",
|
||||
"@vitest/coverage-c8": "^0.25.2",
|
||||
"autocannon": "^7.10.0",
|
||||
"benchmark": "^2.1.4",
|
||||
"changelogen": "^0.4.0",
|
||||
"eslint": "^8.27.0",
|
||||
"eslint-config-unjs": "^0.0.2",
|
||||
"jiti": "^1.16.0",
|
||||
"listhen": "^1.0.0",
|
||||
"ohmyfetch": "^0.4.21",
|
||||
"standard-version": "^9.5.0",
|
||||
"typescript": "^4.8.4",
|
||||
"unbuild": "^0.9.4",
|
||||
"vitest": "^0.25.2"
|
||||
},
|
||||
"packageManager": "pnpm@7.16.0"
|
||||
}
|
||||
Reference in New Issue
Block a user