@mapl/router 0.9.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/method/compiler.d.ts +2 -1
- package/method/compiler.js +1 -1
- package/method/index.d.ts +2 -2
- package/method/index.js +1 -1
- package/package.json +1 -1
- package/tree/compiler.js +1 -1
- package/tree/match.d.ts +4 -0
- package/tree/match.js +1 -0
- package/tree/node.d.ts +38 -3
- package/tree/node.js +1 -1
- package/path/compiler.d.ts +0 -7
- package/path/compiler.js +0 -1
- package/path/index.d.ts +0 -9
- package/path/index.js +0 -1
package/method/compiler.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import type { Router } from "./index.js";
|
|
2
|
-
declare
|
|
2
|
+
declare let;
|
|
3
|
+
declare const _default: (router: Router<string>, methodInput: string, start: 0 | 1) => string;
|
|
3
4
|
export default _default;
|
package/method/compiler.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
1
|
+
import{isEmptyNode}from"../tree/node.js";import{compile}from"../tree/compiler.js";let STR,START_IDX;let each=(value,path)=>{STR+=`case"${START_IDX===1?path:path.slice(1)}":{${value}}`};let compileSubrouter=(mp,node)=>{if(mp.size>0){STR+=`switch(p){`;mp.forEach(each);STR+=`}`}isEmptyNode(node)||(STR+=`{let l=p.length;${compile(node,0,START_IDX,``)}}`)};export default (router,methodInput,start)=>{STR=``;START_IDX=start;let methods=router[0];if(methods.length>0){let nodes=router[1];let maps=router[2];STR+=`switch(${methodInput}){`;for(let i=0;i<methods.length;i++){STR+=`case"${methods[i]}":`;compileSubrouter(maps[i],nodes[i])}STR+=`}`}router.length===3||compileSubrouter(router[4],router[3]);return STR};
|
package/method/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
export type Router<T = unknown> = [string[],
|
|
1
|
+
import { type Node } from "../tree/node.js";
|
|
2
|
+
export type Router<T = unknown> = [string[], Node<T>[], Map<string, T>[]] | [string[], Node<T>[], Map<string, T>[], Node<T>, Map<string, T>];
|
|
3
3
|
export declare const createRouter: <T>() => Router<T>;
|
|
4
4
|
export declare const insertItem: <T>(router: Router<T>, method: string, path: string, item: T) => void;
|
package/method/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{createRoot,insert}from"../tree/node.js";export let createRouter=()=>[[],[],[]];export let insertItem=(router,method,path,item)=>{if(method!==``){let idx=router[0].indexOf(method);if(idx>-1)path.includes(`*`)?insert(router[1][idx],1,path,1,item):router[2][idx].set(path,item);else{router[0].push(method);let node=createRoot();router[1].push(node);let mp=new Map;router[2].push(mp);path.includes(`*`)?insert(node,1,path,1,item):mp.set(path,item)}}else{router.length===3&&router.push(createRoot(),new Map);path.includes(`*`)?insert(router[3],1,path,1,item):router[4].set(path,item)}};
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"@mapl/router","version":"0.
|
|
1
|
+
{"name":"@mapl/router","version":"0.10.0","description":"The fastest possible JS router","repository":{"type":"git","url":"git+https://github.com/mapljs/router.git"},"license":"MIT","type":"module","exports":{"./method":"./method/index.js","./utils":"./utils.js","./method/compiler":"./method/compiler.js","./tree/match":"./tree/match.js","./constants":"./constants.js","./tree/compiler":"./tree/compiler.js","./tree/node":"./tree/node.js"}}
|
package/tree/compiler.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export let shouldBoundCheck=node=>node[1]==null&&(node[2].length!==1||node[4]!==null||node[5]!==null);export let compile=(node,paramCount,idx,idxPrefix)=>{let builder=``;let currentIdx=idxPrefix+idx;node[1]==null||(builder+=`if(l
|
|
1
|
+
export let shouldBoundCheck=node=>node[1]==null&&(node[2].length!==1||node[3][0][0].length===1||node[4]!==null||node[5]!==null);export let compile=(node,paramCount,idx,idxPrefix)=>{let builder=``;let currentIdx=idxPrefix+idx;node[1]==null||(builder+=`if(l===${currentIdx}){${node[1]}}`);if(node[2].length>0){let childrenFirstChar=node[2];let children=node[3];if(children.length>1){builder+=`switch(p.charCodeAt(${currentIdx})){`;for(let i=0;i<children.length;i++){let childNode=children[i];let nodePath=childNode[0];let nextIdx=idx+nodePath.length;builder+=`case `+childrenFirstChar[i]+(shouldBoundCheck(childNode)?`:if(l>${idxPrefix+nextIdx})`:`:`)+(nodePath.length>1?`if(p.`+(nodePath.length>2?`startsWith("${nodePath.slice(1)}",${idxPrefix+(idx+1)})){`:`charCodeAt(${idxPrefix+(idx+1)})===${nodePath.charCodeAt(1)}){`):`{`)+compile(childNode,paramCount,nextIdx,idxPrefix)+`}`}builder+=`}`}else{let childNode=children[0];let nodePath=childNode[0];builder+=(shouldBoundCheck(childNode)?`if(l>${idxPrefix+(idx+nodePath.length)})if(p.`:`if(p.`)+(nodePath.length>1?`startsWith("${nodePath}",${currentIdx})){`:`charCodeAt(${currentIdx})===${childrenFirstChar[0]}){`)+compile(childNode,paramCount,idx+nodePath.length,idxPrefix)+`}`}}if(node[4]!=null){let params=node[4];let hasChild=params[0]!=null;if(hasChild){let childNode=params[0];if(paramCount>0){builder+=`let i=${currentIdx};j=p.indexOf("/",`;currentIdx=`i`}else builder+=`let j=p.indexOf("/",`;let needBoundCheck=shouldBoundCheck(childNode);builder+=currentIdx+`);if(j>`+currentIdx+(needBoundCheck?`){if(l>j+1){let q`:`){let q`)+paramCount+`=p.slice(${currentIdx},j);`+compile(childNode,paramCount+1,1,`j+`)+(needBoundCheck?`}}`:`}`)}params[1]!=null&&(builder+=(hasChild?`else if(j===-1){let q`:`if(!p.includes("/",${currentIdx})){let q`)+paramCount+(currentIdx===`0`?`=p;`:`=p.slice(${currentIdx});`)+params[1]+`}`)}node[5]==null||(builder+=`let q`+paramCount+(currentIdx===`0`?`=p;`:`=p.slice(${currentIdx});`)+node[5]);return builder};
|
package/tree/match.d.ts
ADDED
package/tree/match.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export let PARAMS;let PATH;let PATH_LEN;export let init=path=>{PATH=path;PATH_LEN=path.length;PARAMS=[]};export let match=(node,start)=>{if(start===PATH_LEN)return node[1];if(node[2].length>0){let childId=node[2].indexOf(PATH.charCodeAt(start));if(childId>-1){let child=node[3][childId];let part=child[0];if(part.length===1||PATH.startsWith(part,start)){let matched=match(child,start+part.length);if(matched!==null)return matched}}}if(node[4]!==null){let paramNode=node[4];if(paramNode[0]===null){if(!PATH.includes(`/`,start)){PARAMS.push(PATH.slice(start));return paramNode[1]}}else{let endIdx=PATH.indexOf(`/`,start);if(endIdx===-1){if(paramNode[1]!==null){PARAMS.push(PATH.slice(start));return paramNode[1]}}else if(endIdx>start){PARAMS.push(PATH.slice(start,endIdx));let matched=match(paramNode[0],endIdx+1);if(matched!==null)return matched;PARAMS.pop()}}}if(node[5]!==null){PARAMS.push(PATH.slice(start));return node[5]}return null};
|
package/tree/node.d.ts
CHANGED
|
@@ -1,5 +1,40 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
1
|
+
export interface Node<T = unknown> {
|
|
2
|
+
/**
|
|
3
|
+
* Part
|
|
4
|
+
*/
|
|
5
|
+
0: string;
|
|
6
|
+
/**
|
|
7
|
+
* Store
|
|
8
|
+
*/
|
|
9
|
+
1: T | null;
|
|
10
|
+
/**
|
|
11
|
+
* Children first chars
|
|
12
|
+
*/
|
|
13
|
+
2: number[];
|
|
14
|
+
/**
|
|
15
|
+
* Children nodes
|
|
16
|
+
*/
|
|
17
|
+
3: Node<T>[];
|
|
18
|
+
/**
|
|
19
|
+
* Parameter node
|
|
20
|
+
*/
|
|
21
|
+
4: ParamNode<T> | null;
|
|
22
|
+
/**
|
|
23
|
+
* Wildcard store
|
|
24
|
+
*/
|
|
25
|
+
5: T | null;
|
|
26
|
+
}
|
|
27
|
+
export interface ParamNode<T = unknown> {
|
|
28
|
+
/**
|
|
29
|
+
* Child node
|
|
30
|
+
*/
|
|
31
|
+
0: Node<T> | null;
|
|
32
|
+
/**
|
|
33
|
+
* Store
|
|
34
|
+
*/
|
|
35
|
+
1: T | null;
|
|
36
|
+
}
|
|
3
37
|
export declare const isEmptyNode: (node: Node<any>) => boolean;
|
|
4
|
-
export declare const
|
|
38
|
+
export declare const createRoot: <T>() => Node<T>;
|
|
39
|
+
export declare const insertNewBranch: <T>(root: Node<T>, path: string, startIdx: number, nextParamIdx: number, value: T) => void;
|
|
5
40
|
export declare const insert: <T>(root: Node<T>, nodePartIdx: number, path: string, pathIdx: number, value: T) => void;
|
package/tree/node.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export let isEmptyNode=node=>node[1]
|
|
1
|
+
export let isEmptyNode=node=>node[1]==null&&node[2].length===0&&node[4]==null&&node[5]==null;export let createRoot=()=>[`/`,null,[],[],null,null];export let insertNewBranch=(root,path,startIdx,nextParamIdx,value)=>{while(nextParamIdx>-1){if(startIdx<nextParamIdx){let nextNode=[path.slice(startIdx,nextParamIdx),null,[],[],null,null];root[2].push(path.charCodeAt(startIdx));root[3].push(nextNode);root=nextNode}if(nextParamIdx+2===path.length)root[5]=value;else if(nextParamIdx+1===path.length)root[4]=[null,value];else{let nextNode=createRoot();root[4]=[nextNode,null];root=nextNode;startIdx=nextParamIdx+2;nextParamIdx=path.indexOf(`*`,startIdx);continue}return}root[2].push(path.charCodeAt(startIdx));root[3].push([path.slice(startIdx),value,[],[],null,null])};export let insert=(root,nodePartIdx,path,pathIdx,value)=>{let nodePart=root[0];while(pathIdx<path.length)if(nodePartIdx===nodePart.length)if(path.charCodeAt(pathIdx)===42){if(pathIdx+2===path.length)root[5]=value;else if(root[4]===null)insertNewBranch(root,path,pathIdx,pathIdx,value);else if(pathIdx+1===path.length)root[4][1]=value;else{root=root[4][0]??=createRoot();nodePartIdx=1;nodePart=`/`;pathIdx+=2;continue}return}else{let nextNodeId=root[2].indexOf(path.charCodeAt(pathIdx));if(nextNodeId===-1){insertNewBranch(root,path,pathIdx,path.indexOf(`*`,pathIdx+1),value);return}root=root[3][nextNodeId];nodePartIdx=1;nodePart=root[0];pathIdx++}else if(path.charCodeAt(pathIdx)!==nodePart.charCodeAt(nodePartIdx)){root[3]=[[nodePart.slice(nodePartIdx),root[1],root[2],root[3],root[4],root[5]]];root[2]=[nodePart.charCodeAt(nodePartIdx)];root[0]=nodePart.slice(0,nodePartIdx);root[1]=root[4]=root[5]=null;insertNewBranch(root,path,pathIdx,path.indexOf(`*`,pathIdx),value);return}else{nodePartIdx++;pathIdx++}if(nodePartIdx<nodePart.length){root[3]=[[nodePart.slice(nodePartIdx),root[1],root[2],root[3],root[4],root[5]]];root[2]=[nodePart.charCodeAt(nodePartIdx)];root[0]=nodePart.slice(0,nodePartIdx);root[4]=root[5]=null}root[1]=value};
|
package/path/compiler.d.ts
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { Router } from "./index.js";
|
|
2
|
-
declare const _default: (router: Router<string>, startIndex: 0 | 1) => string;
|
|
3
|
-
/**
|
|
4
|
-
* If `startIndex === 1`, input path should start with `/`.
|
|
5
|
-
* If `startIndex === 0`, input path should have sliced first `/`.
|
|
6
|
-
*/
|
|
7
|
-
export default _default;
|
package/path/compiler.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{compile}from"../tree/compiler.js";import{isEmptyNode}from"../tree/node.js";export default (router,startIndex)=>{let str=``;if(router.length>1){str=`if(p==="`+(startIndex===1?router[1]:router[1].slice(1))+`"){`+router[2]+`}`;for(let i=3;i<router.length;i+=2)str+=`else if(p==="`+(startIndex===1?router[i]:router[i].slice(1))+`"){`+router[i+1]+`}`}return isEmptyNode(router[0])?str:str+`let l=p.length;`+compile(router[0],0,startIndex,``)};
|
package/path/index.d.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { type Node } from "../tree/node.js";
|
|
2
|
-
/**
|
|
3
|
-
* @example
|
|
4
|
-
* [createNode('/'), '/', 'return new Response("Hi");', '/param/*', 'return new Response(p0)'];
|
|
5
|
-
*/
|
|
6
|
-
export type Router<T = unknown> = [root: Node<T>, ...staticMap: any[]];
|
|
7
|
-
export declare const createRouter: <T>() => Router<T>;
|
|
8
|
-
export declare const insertItem: <T>(router: Router<T>, path: string, item: T) => void;
|
|
9
|
-
export declare const createStaticMap: <T>(router: Router<T>) => Map<string, T>;
|
package/path/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{insert}from"../tree/node.js";export let createRouter=()=>[[`/`,null,[],[],null,null]];export let insertItem=(router,path,item)=>{path.includes(`*`)?insert(router[0],1,path,1,item):router.push(path,item)};export let createStaticMap=router=>{let mp=new Map;for(let i=1;i<router.length;i+=2)mp.set(router[i],router[i+1]);return mp};
|