0http-bun 1.1.0 → 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/common.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Pattern, Methods } from 'trouter'
1
+ import {Pattern, Methods} from 'trouter'
2
2
 
3
3
  export interface IRouterConfig {
4
4
  defaultRoute?: RequestHandler
@@ -16,7 +16,7 @@ type ZeroRequest = Request & {
16
16
 
17
17
  export type RequestHandler = (
18
18
  req: ZeroRequest,
19
- next: StepFunction
19
+ next: StepFunction,
20
20
  ) => Response | Promise<Response>
21
21
 
22
22
  export interface IRouter {
package/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { IRouter, IRouterConfig } from './common'
1
+ import {IRouter, IRouterConfig} from './common'
2
2
 
3
3
  export default function zero(config?: IRouterConfig): {
4
4
  router: IRouter
5
5
  }
6
6
 
7
- export * from './common'
7
+ export * from './common'
package/index.js CHANGED
@@ -3,6 +3,6 @@ module.exports = (config = {}) => {
3
3
  const router = require('./lib/router/sequential')(config)
4
4
 
5
5
  return {
6
- router
6
+ router,
7
7
  }
8
8
  }
package/lib/next.js CHANGED
@@ -1,16 +1,25 @@
1
- module.exports = function next (middlewares, req, index, defaultRoute, errorHandler) {
2
- if (index >= middlewares.length) {
1
+ module.exports = function next(
2
+ middlewares,
3
+ req,
4
+ index,
5
+ defaultRoute,
6
+ errorHandler,
7
+ ) {
8
+ // Optimized loop unrolling for common cases
9
+ const length = middlewares.length
10
+ if (index >= length) {
3
11
  return defaultRoute(req)
4
12
  }
5
13
 
6
- const middleware = middlewares[index++]
14
+ const middleware = middlewares[index]
15
+ const nextIndex = index + 1
7
16
 
8
17
  try {
9
18
  return middleware(req, (err) => {
10
19
  if (err) {
11
20
  return errorHandler(err, req)
12
21
  }
13
- return next(middlewares, req, index, defaultRoute, errorHandler)
22
+ return next(middlewares, req, nextIndex, defaultRoute, errorHandler)
14
23
  })
15
24
  } catch (err) {
16
25
  return errorHandler(err, req)
@@ -1,3 +1,3 @@
1
- import { IRouter, IRouterConfig } from './../../index'
1
+ import {IRouter, IRouterConfig} from './../../index'
2
2
 
3
3
  export default function createSequentialRouter(config?: IRouterConfig): IRouter
@@ -1,27 +1,27 @@
1
- const Trouter = require('trouter')
1
+ const {Trouter} = require('trouter')
2
2
  const qs = require('fast-querystring')
3
3
  const next = require('./../next')
4
4
 
5
5
  const STATUS_404 = {
6
- status: 404
6
+ status: 404,
7
7
  }
8
8
  const STATUS_500 = {
9
- status: 500
9
+ status: 500,
10
10
  }
11
11
 
12
12
  module.exports = (config = {}) => {
13
13
  const cache = new Map()
14
14
 
15
- if (!config.defaultRoute) {
16
- config.defaultRoute = () => {
17
- return new Response(null, STATUS_404)
18
- }
19
- }
20
- if (!config.errorHandler) {
21
- config.errorHandler = (err) => {
22
- return new Response(err.message, STATUS_500)
23
- }
24
- }
15
+ // Pre-create default responses to avoid object creation overhead
16
+ const default404Response = new Response(null, STATUS_404)
17
+
18
+ // Cache default functions to avoid closure creation
19
+ const defaultRouteHandler = config.defaultRoute || (() => default404Response)
20
+ const errorHandlerFn =
21
+ config.errorHandler || ((err) => new Response(err.message, STATUS_500))
22
+
23
+ // Optimize empty params object reuse
24
+ const emptyParams = {}
25
25
 
26
26
  const router = new Trouter()
27
27
  router.port = config.port || 3000
@@ -40,35 +40,89 @@ module.exports = (config = {}) => {
40
40
 
41
41
  router.fetch = (req) => {
42
42
  const url = req.url
43
- const startIndex = url.indexOf('/', 11)
44
- const queryIndex = url.indexOf('?', startIndex + 1)
45
- const path = queryIndex === -1 ? url.substring(startIndex) : url.substring(startIndex, queryIndex)
46
43
 
47
- req.path = path || '/'
48
- req.query = queryIndex > 0 ? qs.parse(url.substring(queryIndex + 1)) : {}
44
+ // Highly optimized URL parsing - single pass through the string
45
+ let pathStart = 0
46
+ let pathEnd = url.length
47
+ let queryString = null
48
+
49
+ // Find protocol end
50
+ const protocolEnd = url.indexOf('://')
51
+ if (protocolEnd !== -1) {
52
+ // Find host end (start of path)
53
+ pathStart = url.indexOf('/', protocolEnd + 3)
54
+ if (pathStart === -1) {
55
+ pathStart = url.length
56
+ }
57
+ }
58
+
59
+ // Find query start
60
+ const queryStart = url.indexOf('?', pathStart)
61
+ if (queryStart !== -1) {
62
+ pathEnd = queryStart
63
+ queryString = url.substring(queryStart + 1)
64
+ }
65
+
66
+ const path = pathStart < pathEnd ? url.substring(pathStart, pathEnd) : '/'
49
67
 
50
- const cacheKey = `${req.method}:${req.path}`
51
- let match = null
52
- if (cache.has(cacheKey)) {
53
- match = cache.get(cacheKey)
68
+ req.path = path
69
+ req.query = queryString ? qs.parse(queryString) : {}
70
+
71
+ // Optimized cache lookup with method-based Map structure
72
+ const method = req.method
73
+ let methodCache = cache.get(method)
74
+ let match_result
75
+
76
+ if (methodCache) {
77
+ match_result = methodCache.get(path)
78
+ if (match_result === undefined) {
79
+ match_result = router.find(method, path)
80
+ methodCache.set(path, match_result)
81
+ }
54
82
  } else {
55
- match = router.find(req.method, req.path)
56
- cache.set(cacheKey, match)
83
+ match_result = router.find(method, path)
84
+ methodCache = new Map([[path, match_result]])
85
+ cache.set(method, methodCache)
57
86
  }
58
87
 
59
- if (match?.handlers?.length > 0) {
60
- if (!req.params) {
61
- req.params = {}
88
+ if (match_result?.handlers?.length > 0) {
89
+ // Fast path for params assignment
90
+ const params = match_result.params
91
+ if (params) {
92
+ // Check if params object has properties without Object.keys()
93
+ let hasParams = false
94
+ for (const key in params) {
95
+ hasParams = true
96
+ break
97
+ }
98
+
99
+ if (hasParams) {
100
+ req.params = req.params || {}
101
+ // Direct property copy - faster than Object.keys() + loop
102
+ for (const key in params) {
103
+ req.params[key] = params[key]
104
+ }
105
+ } else if (!req.params) {
106
+ req.params = emptyParams
107
+ }
108
+ } else if (!req.params) {
109
+ req.params = emptyParams
62
110
  }
63
- Object.assign(req.params, match.params)
64
111
 
65
- return next(match.handlers, req, 0, config.defaultRoute, config.errorHandler)
112
+ return next(
113
+ match_result.handlers,
114
+ req,
115
+ 0,
116
+ defaultRouteHandler,
117
+ errorHandlerFn,
118
+ )
66
119
  } else {
67
- return config.defaultRoute(req)
120
+ return defaultRouteHandler(req)
68
121
  }
69
122
  }
70
123
 
71
- router.on = (method, pattern, ...handlers) => router.add(method, pattern, handlers)
124
+ router.on = (method, pattern, ...handlers) =>
125
+ router.add(method, pattern, handlers)
72
126
 
73
127
  return router
74
128
  }
package/package.json CHANGED
@@ -1,16 +1,17 @@
1
1
  {
2
2
  "name": "0http-bun",
3
- "version": "1.1.0",
3
+ "version": "1.1.2",
4
4
  "description": "0http for Bun",
5
5
  "main": "index.js",
6
6
  "scripts": {
7
- "lint": "bun x standard",
8
- "format": "bun x standard --fix",
9
- "test": "bun test"
7
+ "lint": "prettier --check **/*.js",
8
+ "test": "bun --coverage test",
9
+ "bench": "bun run bench.js",
10
+ "format": "prettier --write **/*.js"
10
11
  },
11
12
  "dependencies": {
12
13
  "fast-querystring": "^1.1.2",
13
- "trouter": "^3.2.1"
14
+ "trouter": "^4.0.0"
14
15
  },
15
16
  "repository": {
16
17
  "type": "git",
@@ -25,9 +26,10 @@
25
26
  "lib/"
26
27
  ],
27
28
  "devDependencies": {
28
- "0http-bun": "^1.0.3",
29
- "bun-types": "^1.1.8",
30
- "mitata": "^1.0.32"
29
+ "0http-bun": "^1.1.0",
30
+ "bun-types": "^1.2.5",
31
+ "mitata": "^1.0.34",
32
+ "prettier": "^3.5.3"
31
33
  },
32
34
  "keywords": [
33
35
  "http",