@@ -4,35 +4,43 @@ const { parse } = require('regexparam')
44const { LRUCache : Cache } = require ( 'lru-cache' )
55const queryparams = require ( '../utils/queryparams' )
66
7+ // Default handlers as constants to avoid creating functions on each router instance
8+ const DEFAULT_ROUTE = ( req , res ) => {
9+ res . statusCode = 404
10+ res . end ( )
11+ }
12+
13+ const DEFAULT_ERROR_HANDLER = ( err , req , res ) => {
14+ res . statusCode = 500
15+ res . end ( err . message )
16+ }
17+
18+ // Simple ID generator
19+ const generateId = ( ) => Math . random ( ) . toString ( 36 ) . substring ( 2 , 10 ) . toUpperCase ( )
20+
721module . exports = ( config = { } ) => {
8- if ( config . defaultRoute === undefined ) {
9- config . defaultRoute = ( req , res ) => {
10- res . statusCode = 404
11- res . end ( )
12- }
13- }
14- if ( config . errorHandler === undefined ) {
15- config . errorHandler = ( err , req , res ) => {
16- res . statusCode = 500
17- res . end ( err . message )
18- }
19- }
20- if ( config . cacheSize === undefined ) {
21- config . cacheSize = - 1
22- }
23- if ( config . id === undefined ) {
24- config . id = ( Date . now ( ) . toString ( 36 ) + Math . random ( ) . toString ( 36 ) . substr ( 2 , 5 ) ) . toUpperCase ( )
25- }
22+ // Use object destructuring with defaults for cleaner config initialization
23+ const {
24+ defaultRoute = DEFAULT_ROUTE ,
25+ errorHandler = DEFAULT_ERROR_HANDLER ,
26+ cacheSize = - 1 ,
27+ id = generateId ( )
28+ } = config
2629
2730 const routers = { }
31+
32+ // Initialize cache only once
2833 let cache = null
29- if ( config . cacheSize > 0 ) {
30- cache = new Cache ( { max : config . cacheSize } )
31- } else if ( config . cacheSize < 0 ) {
32- cache = new Map ( )
34+ if ( cacheSize > 0 ) {
35+ cache = new Cache ( { max : cacheSize } )
36+ } else if ( cacheSize < 0 ) {
37+ // For unlimited cache, still use LRUCache but with a very high max
38+ // This provides better memory management than an unbounded Map
39+ cache = new Cache ( { max : 100000 } )
3340 }
41+
3442 const router = new Trouter ( )
35- router . id = config . id
43+ router . id = id
3644
3745 const _use = router . use
3846
@@ -43,60 +51,73 @@ module.exports = (config = {}) => {
4351 }
4452 _use . call ( router , prefix , middlewares )
4553
46- if ( middlewares [ 0 ] . id ) {
54+ if ( middlewares [ 0 ] ? .id ) {
4755 // caching router -> pattern relation for urls pattern replacement
4856 const { pattern } = parse ( prefix , true )
4957 routers [ middlewares [ 0 ] . id ] = pattern
5058 }
5159
52- return this
60+ return router // Fix: return router instead of this
61+ }
62+
63+ // Create the cleanup middleware once
64+ const createCleanupMiddleware = ( step ) => ( req , res , next ) => {
65+ req . url = req . preRouterUrl
66+ req . path = req . preRouterPath
67+
68+ req . preRouterUrl = undefined
69+ req . preRouterPath = undefined
70+
71+ return step ( )
5372 }
5473
5574 router . lookup = ( req , res , step ) => {
56- if ( ! req . url ) {
57- req . url = '/'
58- }
59- if ( ! req . originalUrl ) {
60- req . originalUrl = req . url
61- }
75+ // Initialize URL and originalUrl if needed
76+ req . url = req . url || '/'
77+ req . originalUrl = req . originalUrl || req . url
6278
79+ // Parse query parameters
6380 queryparams ( req , req . url )
6481
65- let match
66- if ( cache ) {
67- const reqCacheKey = req . method + req . path
68- match = cache . get ( reqCacheKey )
69- if ( ! match ) {
70- match = router . find ( req . method , req . path )
82+ // Fast path for cache lookup
83+ const reqCacheKey = cache && ( req . method + req . path )
84+ let match = cache && cache . get ( reqCacheKey )
85+
86+ if ( ! match ) {
87+ match = router . find ( req . method , req . path )
88+ if ( cache && reqCacheKey ) {
7189 cache . set ( reqCacheKey , match )
7290 }
73- } else {
74- match = router . find ( req . method , req . path )
7591 }
7692
77- if ( match . handlers . length > 0 ) {
78- const middlewares = [ ...match . handlers ]
79- if ( step !== undefined ) {
80- // router is being used as a nested router
81- middlewares . push ( ( req , res , next ) => {
82- req . url = req . preRouterUrl
83- req . path = req . preRouterPath
93+ const { handlers, params } = match
8494
85- req . preRouterUrl = undefined
86- req . preRouterPath = undefined
95+ if ( handlers . length > 0 ) {
96+ // Avoid creating a new array with spread operator
97+ // Use the handlers array directly
98+ let middlewares
8799
88- return step ( )
89- } )
100+ if ( step !== undefined ) {
101+ // Only create a new array if we need to add the cleanup middleware
102+ middlewares = handlers . slice ( )
103+ middlewares . push ( createCleanupMiddleware ( step ) )
104+ } else {
105+ middlewares = handlers
90106 }
91107
108+ // Initialize params object if needed
92109 if ( ! req . params ) {
93- req . params = { }
110+ req . params = params
111+ } else if ( params ) {
112+ // Faster than Object.assign for small objects
113+ for ( const key in params ) {
114+ req . params [ key ] = params [ key ]
115+ }
94116 }
95- Object . assign ( req . params , match . params )
96117
97- return next ( middlewares , req , res , 0 , routers , config . defaultRoute , config . errorHandler )
118+ return next ( middlewares , req , res , 0 , routers , defaultRoute , errorHandler )
98119 } else {
99- config . defaultRoute ( req , res )
120+ defaultRoute ( req , res )
100121 }
101122 }
102123
0 commit comments