UNPKG

@grace-js/grace

Version:

An opinionated API framework

78 lines 2.5 kB
export class TrieNode { constructor() { this.children = new Map(); this.dynamicChild = null; this.dynamicParamName = null; this.regexChild = null; this.regex = null; this.isEndOfPath = false; this.routes = new Map(); } } export class TrieRouter { constructor() { this.root = new TrieNode(); } addRoute(route) { let node = this.root; const parts = route.path.split('/').filter(Boolean); for (const part of parts) { if (part.startsWith(':')) { if (!node.dynamicChild) { node.dynamicChild = new TrieNode(); node.dynamicParamName = part.slice(1); } node = node.dynamicChild; } else if (part.startsWith('(') && part.endsWith(')')) { const regex = new RegExp(part.slice(1, -1)); if (!node.regexChild || node.regex.toString() !== regex.toString()) { node.regexChild = new TrieNode(); node.regex = regex; } node = node.regexChild; } else { if (!node.children.has(part)) { node.children.set(part, new TrieNode()); } node = node.children.get(part); } } node.isEndOfPath = true; if (!node.routes.has(route.method)) { node.routes.set(route.method, route); } else { throw new Error(`Route with method ${route.method} already exists`); } } match(path, method) { let node = this.root; const parts = path.split('/').filter(Boolean); const params = {}; for (const part of parts) { if (node.children.has(part)) { node = node.children.get(part); } else if (node.dynamicChild) { params[node.dynamicParamName] = part; node = node.dynamicChild; } else if (node.regexChild && node.regex.test(part)) { node = node.regexChild; } else { return null; } } if (node.isEndOfPath && node.routes.has(method)) { return { route: node.routes.get(method), params }; } return null; } } //# sourceMappingURL=trie.js.map