Skip to content

Commit cfc6aea

Browse files
committed
refactor: optimize router handling and middleware execution logic
1 parent 9a0ed9f commit cfc6aea

File tree

1 file changed

+91
-61
lines changed

1 file changed

+91
-61
lines changed

index.js

Lines changed: 91 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,82 +1,112 @@
1-
const handlers = {
2-
match: updateParams => (req, res, params) => {
3-
if (updateParams) {
4-
req.params = params
5-
}
1+
// Optimized handlers with minimal allocations
2+
const createMatchHandler = (updateParams) =>
3+
updateParams
4+
? (req, res, params) => {
5+
req.params = params;
6+
return true;
7+
}
8+
: () => true;
9+
10+
const defaultHandler = () => false;
611

7-
return true
8-
},
9-
default: () => false
12+
// Router cache for reusing router instances
13+
const routerCache = new WeakMap();
14+
15+
function normalizeEndpoint(endpoint) {
16+
if (typeof endpoint === "string") {
17+
return { url: endpoint, methods: ["GET"], updateParams: false };
18+
}
19+
return {
20+
methods: endpoint.methods || ["GET"],
21+
url: endpoint.url,
22+
version: endpoint.version,
23+
updateParams: endpoint.updateParams || false,
24+
};
1025
}
1126

12-
module.exports = function (routerOpts = {}, routerFactory = require('find-my-way')) {
13-
routerOpts.defaultRoute = handlers.default
14-
15-
function exec (options, isIff = true) {
16-
const middleware = this
17-
18-
// independent router instance per config
19-
const router = routerFactory(routerOpts)
20-
21-
const opts = typeof options === 'function' ? { custom: options } : (Array.isArray(options) ? { endpoints: options } : options)
22-
if (opts.endpoints && opts.endpoints.length) {
23-
// setup matching router
24-
opts.endpoints
25-
.map(endpoint => typeof endpoint === 'string' ? { url: endpoint } : endpoint)
26-
.forEach(({ methods = ['GET'], url, version, updateParams = false }) => {
27-
if (version) {
28-
router.on(methods, url, { constraints: { version } }, handlers.match(updateParams))
29-
} else {
30-
router.on(methods, url, handlers.match(updateParams))
27+
module.exports = function (routerOpts = {}, routerFactory = require("find-my-way")) {
28+
function exec(options, isIff = true) {
29+
const middleware = this;
30+
let router = null;
31+
let customFn = null;
32+
33+
// Process options efficiently
34+
if (typeof options === "function") {
35+
customFn = options;
36+
} else {
37+
const endpoints = Array.isArray(options) ? options : options?.endpoints;
38+
39+
if (endpoints?.length) {
40+
// Try to get cached router first
41+
let cache = routerCache.get(routerOpts);
42+
if (!cache) {
43+
cache = new Map();
44+
routerCache.set(routerOpts, cache);
45+
}
46+
47+
const cacheKey = JSON.stringify(endpoints);
48+
router = cache.get(cacheKey);
49+
50+
if (!router) {
51+
router = routerFactory({ ...routerOpts, defaultRoute: defaultHandler });
52+
53+
// Normalize and register routes
54+
const normalized = endpoints.map(normalizeEndpoint);
55+
for (const { methods, url, version, updateParams } of normalized) {
56+
const handler = createMatchHandler(updateParams);
57+
58+
if (version) {
59+
router.on(methods, url, { constraints: { version } }, handler);
60+
} else {
61+
router.on(methods, url, handler);
62+
}
3163
}
32-
})
64+
65+
cache.set(cacheKey, router);
66+
}
67+
}
68+
69+
if (options?.custom) {
70+
customFn = options.custom;
71+
}
3372
}
3473

74+
// Optimized execution function
3575
const result = function (req, res, next) {
36-
// supporting custom matching function
37-
if (opts.custom) {
38-
if (opts.custom(req)) {
39-
if (isIff) {
40-
return middleware(req, res, next)
41-
}
42-
} else if (!isIff) {
43-
return middleware(req, res, next)
44-
}
76+
let shouldExecute = false;
4577

46-
// leave here and do not process opts.endpoints
47-
return next()
78+
if (customFn) {
79+
shouldExecute = customFn(req);
80+
} else if (router) {
81+
shouldExecute = router.lookup(req, res);
4882
}
4983

50-
// matching endpoints and moving forward
51-
if (router.lookup(req, res)) {
52-
if (isIff) {
53-
return middleware(req, res, next)
54-
}
55-
} else if (!isIff) {
56-
return middleware(req, res, next)
84+
// Simplified logic: execute middleware if conditions match
85+
if ((isIff && shouldExecute) || (!isIff && !shouldExecute)) {
86+
return middleware(req, res, next);
5787
}
5888

59-
return next()
60-
}
89+
return next();
90+
};
6191

62-
// allowing chaining
63-
result.iff = iff
64-
result.unless = unless
92+
// Allow chaining
93+
result.iff = iff;
94+
result.unless = unless;
6595

66-
return result
96+
return result;
6797
}
6898

69-
function iff (options) {
70-
return exec.call(this, options, true)
99+
function iff(options) {
100+
return exec.call(this, options, true);
71101
}
72-
function unless (options) {
73-
return exec.call(this, options, false)
102+
function unless(options) {
103+
return exec.call(this, options, false);
74104
}
75105

76106
return function (middleware) {
77-
middleware.iff = iff
78-
middleware.unless = unless
107+
middleware.iff = iff;
108+
middleware.unless = unless;
79109

80-
return middleware
81-
}
82-
}
110+
return middleware;
111+
};
112+
};

0 commit comments

Comments
 (0)