Buckets:
| // src/router/trie-router/node.ts | |
| import { METHOD_NAME_ALL } from "../../router.js"; | |
| import { getPattern, splitPath, splitRoutingPath } from "../../utils/url.js"; | |
| var emptyParams = /* @__PURE__ */ Object.create(null); | |
| var Node = class _Node { | |
| #methods; | |
| #children; | |
| #patterns; | |
| #order = 0; | |
| #params = emptyParams; | |
| constructor(method, handler, children) { | |
| this.#children = children || /* @__PURE__ */ Object.create(null); | |
| this.#methods = []; | |
| if (method && handler) { | |
| const m = /* @__PURE__ */ Object.create(null); | |
| m[method] = { handler, possibleKeys: [], score: 0 }; | |
| this.#methods = [m]; | |
| } | |
| this.#patterns = []; | |
| } | |
| insert(method, path, handler) { | |
| this.#order = ++this.#order; | |
| let curNode = this; | |
| const parts = splitRoutingPath(path); | |
| const possibleKeys = []; | |
| for (let i = 0, len = parts.length; i < len; i++) { | |
| const p = parts[i]; | |
| const nextP = parts[i + 1]; | |
| const pattern = getPattern(p, nextP); | |
| const key = Array.isArray(pattern) ? pattern[0] : p; | |
| if (key in curNode.#children) { | |
| curNode = curNode.#children[key]; | |
| if (pattern) { | |
| possibleKeys.push(pattern[1]); | |
| } | |
| continue; | |
| } | |
| curNode.#children[key] = new _Node(); | |
| if (pattern) { | |
| curNode.#patterns.push(pattern); | |
| possibleKeys.push(pattern[1]); | |
| } | |
| curNode = curNode.#children[key]; | |
| } | |
| curNode.#methods.push({ | |
| [method]: { | |
| handler, | |
| possibleKeys: possibleKeys.filter((v, i, a) => a.indexOf(v) === i), | |
| score: this.#order | |
| } | |
| }); | |
| return curNode; | |
| } | |
| #getHandlerSets(node, method, nodeParams, params) { | |
| const handlerSets = []; | |
| for (let i = 0, len = node.#methods.length; i < len; i++) { | |
| const m = node.#methods[i]; | |
| const handlerSet = m[method] || m[METHOD_NAME_ALL]; | |
| const processedSet = {}; | |
| if (handlerSet !== void 0) { | |
| handlerSet.params = /* @__PURE__ */ Object.create(null); | |
| handlerSets.push(handlerSet); | |
| if (nodeParams !== emptyParams || params && params !== emptyParams) { | |
| for (let i2 = 0, len2 = handlerSet.possibleKeys.length; i2 < len2; i2++) { | |
| const key = handlerSet.possibleKeys[i2]; | |
| const processed = processedSet[handlerSet.score]; | |
| handlerSet.params[key] = params?.[key] && !processed ? params[key] : nodeParams[key] ?? params?.[key]; | |
| processedSet[handlerSet.score] = true; | |
| } | |
| } | |
| } | |
| } | |
| return handlerSets; | |
| } | |
| search(method, path) { | |
| const handlerSets = []; | |
| this.#params = emptyParams; | |
| const curNode = this; | |
| let curNodes = [curNode]; | |
| const parts = splitPath(path); | |
| const curNodesQueue = []; | |
| for (let i = 0, len = parts.length; i < len; i++) { | |
| const part = parts[i]; | |
| const isLast = i === len - 1; | |
| const tempNodes = []; | |
| for (let j = 0, len2 = curNodes.length; j < len2; j++) { | |
| const node = curNodes[j]; | |
| const nextNode = node.#children[part]; | |
| if (nextNode) { | |
| nextNode.#params = node.#params; | |
| if (isLast) { | |
| if (nextNode.#children["*"]) { | |
| handlerSets.push( | |
| ...this.#getHandlerSets(nextNode.#children["*"], method, node.#params) | |
| ); | |
| } | |
| handlerSets.push(...this.#getHandlerSets(nextNode, method, node.#params)); | |
| } else { | |
| tempNodes.push(nextNode); | |
| } | |
| } | |
| for (let k = 0, len3 = node.#patterns.length; k < len3; k++) { | |
| const pattern = node.#patterns[k]; | |
| const params = node.#params === emptyParams ? {} : { ...node.#params }; | |
| if (pattern === "*") { | |
| const astNode = node.#children["*"]; | |
| if (astNode) { | |
| handlerSets.push(...this.#getHandlerSets(astNode, method, node.#params)); | |
| astNode.#params = params; | |
| tempNodes.push(astNode); | |
| } | |
| continue; | |
| } | |
| const [key, name, matcher] = pattern; | |
| if (!part && !(matcher instanceof RegExp)) { | |
| continue; | |
| } | |
| const child = node.#children[key]; | |
| const restPathString = parts.slice(i).join("/"); | |
| if (matcher instanceof RegExp) { | |
| const m = matcher.exec(restPathString); | |
| if (m) { | |
| params[name] = m[0]; | |
| handlerSets.push(...this.#getHandlerSets(child, method, node.#params, params)); | |
| if (Object.keys(child.#children).length) { | |
| child.#params = params; | |
| const componentCount = m[0].match(/\//)?.length ?? 0; | |
| const targetCurNodes = curNodesQueue[componentCount] ||= []; | |
| targetCurNodes.push(child); | |
| } | |
| continue; | |
| } | |
| } | |
| if (matcher === true || matcher.test(part)) { | |
| params[name] = part; | |
| if (isLast) { | |
| handlerSets.push(...this.#getHandlerSets(child, method, params, node.#params)); | |
| if (child.#children["*"]) { | |
| handlerSets.push( | |
| ...this.#getHandlerSets(child.#children["*"], method, params, node.#params) | |
| ); | |
| } | |
| } else { | |
| child.#params = params; | |
| tempNodes.push(child); | |
| } | |
| } | |
| } | |
| } | |
| curNodes = tempNodes.concat(curNodesQueue.shift() ?? []); | |
| } | |
| if (handlerSets.length > 1) { | |
| handlerSets.sort((a, b) => { | |
| return a.score - b.score; | |
| }); | |
| } | |
| return [handlerSets.map(({ handler, params }) => [handler, params])]; | |
| } | |
| }; | |
| export { | |
| Node | |
| }; | |
Xet Storage Details
- Size:
- 5.7 kB
- Xet hash:
- 6f8c5230d1eb750cb5a0c050454148c72259a630b70faaf13acf1eeacb5ef13b
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.