MIRROR: javascript for ๐Ÿœ's, a tiny runtime with big ambitions
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

move radix3 into examples

+34 -265
+33 -4
examples/server/radix3.js
··· 24 24 return minLen; 25 25 } 26 26 27 - insert(path, handler) { 28 - this.insertPath(this.root, path, handler, 0); 27 + insert(path, handler, method = 'GET') { 28 + this.insertPath(this.root, `${method}#${path}`, handler, 0); 29 + } 30 + 31 + get(path, handler) { 32 + this.insert(path, handler, 'GET'); 33 + } 34 + 35 + post(path, handler) { 36 + this.insert(path, handler, 'POST'); 37 + } 38 + 39 + put(path, handler) { 40 + this.insert(path, handler, 'PUT'); 41 + } 42 + 43 + delete(path, handler) { 44 + this.insert(path, handler, 'DELETE'); 45 + } 46 + 47 + patch(path, handler) { 48 + this.insert(path, handler, 'PATCH'); 49 + } 50 + 51 + head(path, handler) { 52 + this.insert(path, handler, 'HEAD'); 53 + } 54 + 55 + options(path, handler) { 56 + this.insert(path, handler, 'OPTIONS'); 29 57 } 30 58 31 59 insertPath(node, path, handler, start) { ··· 114 142 this.insertPath(newChild, path, handler, end); 115 143 } 116 144 117 - lookup(path) { 145 + lookup(path, method = 'GET') { 118 146 const params = {}; 119 - const handler = this.matchPath(this.root, path, 0, params); 147 + const fullPath = `${method}#${path}`; 148 + const handler = this.matchPath(this.root, fullPath, 0, params); 120 149 121 150 if (!handler) return undefined; 122 151 return { handler, params };
+1 -1
meson.build
··· 67 67 build_date = run_command('date', '+%Y-%m-%d', check: true).stdout().strip() 68 68 69 69 version_conf = configuration_data() 70 - version_conf.set('ANT_VERSION', '0.0.6.36') 70 + version_conf.set('ANT_VERSION', '0.0.6.37') 71 71 version_conf.set('ANT_GIT_HASH', git_hash) 72 72 version_conf.set('ANT_BUILD_DATE', build_date) 73 73
-260
radix3.js
··· 1 - class Radix3Node { 2 - constructor() { 3 - this.prefix = ''; 4 - this.handler = undefined; 5 - this.children = []; 6 - this.paramChild = undefined; 7 - this.wildcardChild = undefined; 8 - this.paramName = undefined; 9 - } 10 - } 11 - 12 - export class Radix3 { 13 - constructor() { 14 - this.root = new Radix3Node(); 15 - } 16 - 17 - longestCommonPrefix(a, b) { 18 - const minLen = a.length < b.length ? a.length : b.length; 19 - for (let i = 0; i < minLen; i = i + 1) { 20 - if (a[i] !== b[i]) { 21 - return i; 22 - } 23 - } 24 - return minLen; 25 - } 26 - 27 - insert(path, handler, method = 'GET') { 28 - this.insertPath(this.root, `${method}#${path}`, handler, 0); 29 - } 30 - 31 - get(path, handler) { 32 - this.insert(path, handler, 'GET'); 33 - } 34 - 35 - post(path, handler) { 36 - this.insert(path, handler, 'POST'); 37 - } 38 - 39 - put(path, handler) { 40 - this.insert(path, handler, 'PUT'); 41 - } 42 - 43 - delete(path, handler) { 44 - this.insert(path, handler, 'DELETE'); 45 - } 46 - 47 - patch(path, handler) { 48 - this.insert(path, handler, 'PATCH'); 49 - } 50 - 51 - head(path, handler) { 52 - this.insert(path, handler, 'HEAD'); 53 - } 54 - 55 - options(path, handler) { 56 - this.insert(path, handler, 'OPTIONS'); 57 - } 58 - 59 - insertPath(node, path, handler, start) { 60 - if (start >= path.length) { 61 - node.handler = handler; 62 - return; 63 - } 64 - 65 - const char = path[start]; 66 - 67 - if (char === ':') { 68 - let end = start + 1; 69 - for (let i = end; i < path.length; i = i + 1) { 70 - if (path[i] === '/') { 71 - break; 72 - } 73 - end = i + 1; 74 - } 75 - 76 - const paramName = path.substring(start + 1, end); 77 - 78 - if (node.paramChild === undefined) { 79 - node.paramChild = new Radix3Node(); 80 - node.paramChild.paramName = paramName; 81 - } 82 - 83 - this.insertPath(node.paramChild, path, handler, end); 84 - return; 85 - } 86 - 87 - if (char === '*') { 88 - const paramName = path.substring(start + 1, path.length); 89 - 90 - if (node.wildcardChild === undefined) { 91 - node.wildcardChild = new Radix3Node(); 92 - node.wildcardChild.paramName = paramName; 93 - } 94 - 95 - node.wildcardChild.handler = handler; 96 - return; 97 - } 98 - 99 - let end = start; 100 - for (let i = start; i < path.length; i = i + 1) { 101 - if (path[i] === ':' || path[i] === '*') { 102 - break; 103 - } 104 - end = i + 1; 105 - } 106 - 107 - const segment = path.substring(start, end); 108 - 109 - for (let i = 0; i < node.children.length; i = i + 1) { 110 - const child = node.children[i]; 111 - const commonLen = this.longestCommonPrefix(child.prefix, segment); 112 - 113 - if (commonLen > 0) { 114 - if (commonLen < child.prefix.length) { 115 - const splitNode = new Radix3Node(); 116 - splitNode.prefix = child.prefix.substring(commonLen, child.prefix.length); 117 - splitNode.handler = child.handler; 118 - splitNode.children = child.children; 119 - splitNode.paramChild = child.paramChild; 120 - splitNode.wildcardChild = child.wildcardChild; 121 - 122 - child.prefix = child.prefix.substring(0, commonLen); 123 - child.handler = undefined; 124 - child.children = [splitNode]; 125 - child.paramChild = undefined; 126 - child.wildcardChild = undefined; 127 - } 128 - 129 - if (commonLen < segment.length) { 130 - this.insertPath(child, path, handler, start + commonLen); 131 - } else { 132 - this.insertPath(child, path, handler, end); 133 - } 134 - 135 - return; 136 - } 137 - } 138 - 139 - const newChild = new Radix3Node(); 140 - newChild.prefix = segment; 141 - node.children.push(newChild); 142 - this.insertPath(newChild, path, handler, end); 143 - } 144 - 145 - lookup(path, method = 'GET') { 146 - const params = {}; 147 - const fullPath = `${method}#${path}`; 148 - const handler = this.matchPath(this.root, fullPath, 0, params); 149 - 150 - if (!handler) return undefined; 151 - return { handler, params }; 152 - } 153 - 154 - matchPath(node, path, depth, params) { 155 - if (depth >= path.length) { 156 - return node.handler; 157 - } 158 - 159 - const remaining = path.substring(depth, path.length); 160 - for (let i = 0; i < node.children.length; i = i + 1) { 161 - const child = node.children[i]; 162 - 163 - if (remaining.length >= child.prefix.length) { 164 - let matches = true; 165 - for (let j = 0; j < child.prefix.length; j = j + 1) { 166 - if (remaining[j] !== child.prefix[j]) { 167 - matches = false; 168 - break; 169 - } 170 - } 171 - 172 - if (matches) { 173 - const result = this.matchPath(child, path, depth + child.prefix.length, params); 174 - if (result !== undefined) { 175 - return result; 176 - } 177 - } 178 - } 179 - } 180 - 181 - if (node.paramChild !== undefined) { 182 - let paramValue = ''; 183 - let offset = depth; 184 - 185 - for (let i = depth; i < path.length; i = i + 1) { 186 - if (path[i] === '/') { 187 - break; 188 - } 189 - paramValue = paramValue + path[i]; 190 - offset = i + 1; 191 - } 192 - 193 - if (paramValue !== '') { 194 - params[node.paramChild.paramName] = paramValue; 195 - const result = this.matchPath(node.paramChild, path, offset, params); 196 - if (result !== undefined) { 197 - return result; 198 - } 199 - delete params[node.paramChild.paramName]; 200 - } 201 - } 202 - 203 - if (node.wildcardChild !== undefined) { 204 - const wildcardValue = path.substring(depth, path.length); 205 - params[node.wildcardChild.paramName] = wildcardValue; 206 - return node.wildcardChild.handler; 207 - } 208 - 209 - return undefined; 210 - } 211 - 212 - printTree() { 213 - this.printNode(this.root, '', true); 214 - } 215 - 216 - printNode(node, prefix, isLast) { 217 - const marker = isLast ? 'โ””โ”€ ' : 'โ”œโ”€ '; 218 - let line = `${prefix}${marker}`; 219 - 220 - if (node.prefix !== '') { 221 - line = `${line}"${node.prefix}"`; 222 - } else { 223 - line = `${line}(root)`; 224 - } 225 - 226 - if (node.handler !== undefined) { 227 - line = `${line} [HANDLER]`; 228 - } 229 - 230 - if (node.paramName !== undefined) { 231 - line = `${line} :${node.paramName}`; 232 - } 233 - 234 - console.log(line); 235 - 236 - const childPrefix = `${prefix}${isLast ? ' ' : 'โ”‚ '}`; 237 - 238 - for (let i = 0; i < node.children.length; i = i + 1) { 239 - const isLastChild = i === node.children.length - 1 && node.paramChild === undefined && node.wildcardChild === undefined; 240 - this.printNode(node.children[i], childPrefix, isLastChild); 241 - } 242 - 243 - if (node.paramChild !== undefined) { 244 - const isLastChild = node.wildcardChild === undefined; 245 - console.log(`${childPrefix}${isLastChild ? 'โ””โ”€ ' : 'โ”œโ”€ '}:${node.paramChild.paramName}`); 246 - this.printNode(node.paramChild, `${childPrefix}${isLastChild ? ' ' : 'โ”‚ '}`, true); 247 - } 248 - 249 - if (node.wildcardChild !== undefined) { 250 - console.log(`${childPrefix}โ””โ”€ *${node.wildcardChild.paramName}`); 251 - this.printNode(node.wildcardChild, `${childPrefix} `, true); 252 - } 253 - } 254 - } 255 - 256 - const router = new Radix3(); 257 - 258 - router.get('/hello', () => console.log('hello world')); 259 - const result = router.lookup('/hello', 'GET'); 260 - result.handler();