0http-bun 1.1.2 → 1.2.0

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/README.md CHANGED
@@ -1,89 +1,353 @@
1
- # Introduction
2
- Experimental, bun-based HTTP framework inspired by [0http](https://0http.21no.de/#/)
1
+ # 0http-bun
3
2
 
4
- ![Performance Benchmarks](0http-benchmarks.png)
5
- > MacBook Pro (13-inch, 2020)
3
+ A high-performance, minimalist HTTP framework for [Bun](https://bun.sh/), inspired by [0http](https://0http.21no.de/#/). Built specifically to leverage Bun's native performance capabilities with a developer-friendly API.
6
4
 
7
- ## Usage
8
- ```js
9
- const http = require('0http-bun')
5
+ ## Key Benefits
10
6
 
11
- const { router } = http({
12
- port: 3000
7
+ - **🚀 Bun-Native Performance**: Optimized for Bun's runtime with minimal overhead
8
+ - **🔧 TypeScript First**: Full TypeScript support with comprehensive type definitions
9
+ - **🎯 Minimalist API**: Clean, intuitive API that's easy to learn and use
10
+ - **🔄 Middleware Support**: Flexible middleware system with async/await support
11
+ - **📦 Tiny Footprint**: Lightweight framework focused on performance
12
+ - **🛡️ Web Standards**: Built on standard Web APIs (Request/Response)
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ bun add 0http-bun
18
+ ```
19
+
20
+ ## Quick Start
21
+
22
+ ### Basic Server
23
+
24
+ ```typescript
25
+ import http from '0http-bun'
26
+
27
+ const {router} = http()
28
+
29
+ router.get('/', () => {
30
+ return new Response('Hello World!')
13
31
  })
14
- router.use((req, next) => {
15
- req.ctx = {
16
- engine: 'bun'
17
- }
18
32
 
19
- return next()
33
+ router.get('/:id', (req) => {
34
+ return Response.json({id: req.params.id})
20
35
  })
21
- router.get('/:id', async (req) => {
22
- return Response.json(req.params)
36
+
37
+ // Start the server
38
+ Bun.serve({
39
+ port: 3000,
40
+ fetch: router.fetch,
23
41
  })
24
- router.post('/', async (req) => {
25
- return new Response('POST')
42
+ ```
43
+
44
+ ### With TypeScript Types
45
+
46
+ ```typescript
47
+ import http, {ZeroRequest, StepFunction} from '0http-bun'
48
+
49
+ const {router} = http({
50
+ port: 3000,
51
+ errorHandler: (err: Error) => {
52
+ console.error('Server error:', err)
53
+ return new Response('Internal Server Error', {status: 500})
54
+ },
26
55
  })
27
- router.delete('/:id', async (req) => {
28
- return Response.json(req.params, {
29
- status: 200
56
+
57
+ // Typed middleware
58
+ router.use((req: ZeroRequest, next: StepFunction) => {
59
+ req.ctx = {
60
+ startTime: Date.now(),
61
+ engine: 'bun',
62
+ }
63
+ return next()
64
+ })
65
+
66
+ // Typed route handlers
67
+ router.get('/:id', async (req: ZeroRequest) => {
68
+ return Response.json({
69
+ id: req.params.id,
70
+ context: req.ctx,
30
71
  })
31
72
  })
32
73
 
33
- export default router
74
+ router.post('/users', async (req: ZeroRequest) => {
75
+ const body = await req.json()
76
+ return Response.json({created: true, data: body}, {status: 201})
77
+ })
78
+ ```
79
+
80
+ ## API Reference
81
+
82
+ ### Router Configuration
83
+
84
+ ```typescript
85
+ interface IRouterConfig {
86
+ defaultRoute?: RequestHandler // Custom 404 handler
87
+ errorHandler?: (err: Error) => Response | Promise<Response> // Error handler
88
+ port?: number // Port number (for reference)
89
+ }
34
90
  ```
35
- # Benchmarks
36
- ## 0http-bun (bun v0.2.2)
91
+
92
+ ### Request Object
93
+
94
+ The `ZeroRequest` extends the standard `Request` with additional properties:
95
+
96
+ ```typescript
97
+ type ZeroRequest = Request & {
98
+ params: Record<string, string> // URL parameters
99
+ query: Record<string, string> // Query string parameters
100
+ ctx?: Record<string, any> // Custom context (set by middleware)
101
+ }
102
+ ```
103
+
104
+ ### Route Methods
105
+
106
+ ```typescript
107
+ // HTTP Methods
108
+ router.get(pattern, ...handlers)
109
+ router.post(pattern, ...handlers)
110
+ router.put(pattern, ...handlers)
111
+ router.patch(pattern, ...handlers)
112
+ router.delete(pattern, ...handlers)
113
+ router.head(pattern, ...handlers)
114
+ router.options(pattern, ...handlers)
115
+ router.connect(pattern, ...handlers)
116
+ router.trace(pattern, ...handlers)
117
+
118
+ // Generic method
119
+ router.on(method, pattern, ...handlers)
120
+
121
+ // All methods
122
+ router.all(pattern, ...handlers)
37
123
  ```
38
- % wrk -t4 -c50 -d10s --latency http://127.0.0.1:3000/hi
39
- Running 10s test @ http://127.0.0.1:3000/hi
40
- 4 threads and 50 connections
41
- Thread Stats Avg Stdev Max +/- Stdev
42
- Latency 463.26us 99.23us 4.28ms 96.62%
43
- Req/Sec 25.98k 1.10k 27.48k 76.73%
44
- Latency Distribution
45
- 50% 442.00us
46
- 75% 466.00us
47
- 90% 485.00us
48
- 99% 0.91ms
49
- 1044377 requests in 10.10s, 127.49MB read
50
- Requests/sec: 103397.66
51
- Transfer/sec: 12.62MB
124
+
125
+ ### Middleware
126
+
127
+ ```typescript
128
+ // Global middleware
129
+ router.use((req, next) => {
130
+ // Middleware logic
131
+ return next()
132
+ })
133
+
134
+ // Path-specific middleware
135
+ router.use('/api/*', (req, next) => {
136
+ // API-specific middleware
137
+ return next()
138
+ })
139
+
140
+ // Multiple middlewares
141
+ router.use(authMiddleware, loggingMiddleware, (req, next) => next())
142
+ ```
143
+
144
+ ## Examples
145
+
146
+ ### Complete REST API
147
+
148
+ ```typescript
149
+ import http, {ZeroRequest, StepFunction} from '0http-bun'
150
+
151
+ const {router} = http({
152
+ errorHandler: (err: Error) => {
153
+ return Response.json({error: err.message}, {status: 500})
154
+ },
155
+ })
156
+
157
+ // Logging middleware
158
+ router.use((req: ZeroRequest, next: StepFunction) => {
159
+ console.log(`${req.method} ${req.url}`)
160
+ return next()
161
+ })
162
+
163
+ // JSON body parser middleware for POST/PUT
164
+ router.use('/api/*', async (req: ZeroRequest, next: StepFunction) => {
165
+ if (req.method === 'POST' || req.method === 'PUT') {
166
+ try {
167
+ req.ctx = {...req.ctx, body: await req.json()}
168
+ } catch (err) {
169
+ return Response.json({error: 'Invalid JSON'}, {status: 400})
170
+ }
171
+ }
172
+ return next()
173
+ })
174
+
175
+ // Routes
176
+ router.get('/api/users', () => {
177
+ return Response.json([
178
+ {id: 1, name: 'John'},
179
+ {id: 2, name: 'Jane'},
180
+ ])
181
+ })
182
+
183
+ router.get('/api/users/:id', (req: ZeroRequest) => {
184
+ const {id} = req.params
185
+ return Response.json({id: Number(id), name: 'User'})
186
+ })
187
+
188
+ router.post('/api/users', (req: ZeroRequest) => {
189
+ const userData = req.ctx?.body
190
+ return Response.json({id: Date.now(), ...userData}, {status: 201})
191
+ })
192
+
193
+ router.delete('/api/users/:id', (req: ZeroRequest) => {
194
+ const {id} = req.params
195
+ return Response.json({deleted: id})
196
+ })
197
+
198
+ // Start server
199
+ Bun.serve({
200
+ port: 3000,
201
+ fetch: router.fetch,
202
+ })
52
203
  ```
53
- ## 0http (node v18.2.0)
204
+
205
+ ## Middleware Support
206
+
207
+ 0http-bun includes a comprehensive middleware system with built-in middlewares for common use cases:
208
+
209
+ - **[Body Parser](./lib/middleware/README.md#body-parser)** - Automatic request body parsing (JSON, form data, text)
210
+ - **[CORS](./lib/middleware/README.md#cors)** - Cross-Origin Resource Sharing with flexible configuration
211
+ - **[JWT Authentication](./lib/middleware/README.md#jwt-authentication)** - JSON Web Token authentication and authorization
212
+ - **[Logger](./lib/middleware/README.md#logger)** - Request logging with multiple output formats
213
+ - **[Rate Limiting](./lib/middleware/README.md#rate-limiting)** - Flexible rate limiting with sliding window support
214
+
215
+ ### Quick Example
216
+
217
+ ```javascript
218
+ // Import middleware functions from the middleware module
219
+ const {
220
+ createCORS,
221
+ createLogger,
222
+ createBodyParser,
223
+ createJWTAuth,
224
+ createRateLimit,
225
+ } = require('0http-bun/lib/middleware')
226
+
227
+ const {router} = http()
228
+
229
+ // Apply middleware stack
230
+ router.use(createCORS()) // Enable CORS
231
+ router.use(createLogger()) // Request logging
232
+ router.use(createBodyParser()) // Parse request bodies
233
+ router.use(createRateLimit({max: 100})) // Rate limiting
234
+
235
+ // Protected routes
236
+ router.use('/api/*', createJWTAuth({secret: process.env.JWT_SECRET}))
54
237
  ```
55
- % wrk -t4 -c50 -d10s --latency http://127.0.0.1:3000/hi
56
- Running 10s test @ http://127.0.0.1:3000/hi
57
- 4 threads and 50 connections
58
- Thread Stats Avg Stdev Max +/- Stdev
59
- Latency 0.98ms 251.77us 13.04ms 95.09%
60
- Req/Sec 12.31k 771.37 16.96k 95.29%
61
- Latency Distribution
62
- 50% 0.95ms
63
- 75% 0.96ms
64
- 90% 0.98ms
65
- 99% 1.88ms
66
- 493899 requests in 10.10s, 63.59MB read
67
- Requests/sec: 48893.32
68
- Transfer/sec: 6.29MB
238
+
239
+ 📖 **[Complete Middleware Documentation](./lib/middleware/README.md)**
240
+
241
+ ### Error Handling
242
+
243
+ ```typescript
244
+ import http, {ZeroRequest} from '0http-bun'
245
+
246
+ const {router} = http({
247
+ errorHandler: (err: Error) => {
248
+ console.error('Application error:', err)
249
+
250
+ // Custom error responses based on error type
251
+ if (err.name === 'ValidationError') {
252
+ return Response.json(
253
+ {error: 'Validation failed', details: err.message},
254
+ {status: 400},
255
+ )
256
+ }
257
+
258
+ return Response.json({error: 'Internal server error'}, {status: 500})
259
+ },
260
+ defaultRoute: () => {
261
+ return Response.json({error: 'Route not found'}, {status: 404})
262
+ },
263
+ })
264
+
265
+ // Route that might throw an error
266
+ router.get('/api/risky', (req: ZeroRequest) => {
267
+ if (Math.random() > 0.5) {
268
+ const error = new Error('Random failure')
269
+ error.name = 'ValidationError'
270
+ throw error
271
+ }
272
+
273
+ return Response.json({success: true})
274
+ })
69
275
  ```
70
- ## express (node v18.2.0)
276
+
277
+ ## Performance
278
+
279
+ 0http-bun is designed for high performance with Bun's native capabilities:
280
+
281
+ - **Minimal overhead**: Direct use of Web APIs
282
+ - **Efficient routing**: Based on the proven `trouter` library
283
+ - **Fast parameter parsing**: Optimized URL parameter extraction with caching
284
+ - **Query string parsing**: Uses `fast-querystring` for optimal performance
285
+ - **Memory efficient**: Route caching and object reuse to minimize allocations
286
+
287
+ ### Benchmark Results
288
+
289
+ Run benchmarks with:
290
+
291
+ ```bash
292
+ bun run bench
71
293
  ```
72
- % wrk -t4 -c50 -d10s --latency http://127.0.0.1:3000/hi
73
- Running 10s test @ http://127.0.0.1:3000/hi
74
- 4 threads and 50 connections
75
- Thread Stats Avg Stdev Max +/- Stdev
76
- Latency 4.99ms 0.90ms 20.31ms 89.52%
77
- Req/Sec 2.42k 154.52 2.66k 82.25%
78
- Latency Distribution
79
- 50% 4.67ms
80
- 75% 4.83ms
81
- 90% 6.03ms
82
- 99% 8.43ms
83
- 96296 requests in 10.01s, 21.95MB read
84
- Requests/sec: 9622.74
85
- Transfer/sec: 2.19MB
294
+
295
+ _Performance characteristics will vary based on your specific use case and middleware stack._
296
+
297
+ ## TypeScript Support
298
+
299
+ Full TypeScript support is included with comprehensive type definitions:
300
+
301
+ ```typescript
302
+ // Main framework types
303
+ import {
304
+ ZeroRequest,
305
+ StepFunction,
306
+ RequestHandler,
307
+ IRouter,
308
+ IRouterConfig,
309
+ } from '0http-bun'
310
+
311
+ // Middleware-specific types
312
+ import {
313
+ LoggerOptions,
314
+ JWTAuthOptions,
315
+ APIKeyAuthOptions,
316
+ RateLimitOptions,
317
+ CORSOptions,
318
+ BodyParserOptions,
319
+ MemoryStore,
320
+ } from '0http-bun/lib/middleware'
321
+
322
+ // Example typed middleware
323
+ const customMiddleware: RequestHandler = (
324
+ req: ZeroRequest,
325
+ next: StepFunction,
326
+ ) => {
327
+ req.ctx = req.ctx || {}
328
+ req.ctx.timestamp = Date.now()
329
+ return next()
330
+ }
331
+
332
+ // Example typed route handler
333
+ const typedHandler = (req: ZeroRequest): Response => {
334
+ return Response.json({
335
+ params: req.params,
336
+ query: req.query,
337
+ context: req.ctx,
338
+ })
339
+ }
86
340
  ```
87
- # Support / Donate 💚
88
- You can support the maintenance of this project:
89
- - PayPal: https://www.paypal.me/kyberneees
341
+
342
+ ## License
343
+
344
+ MIT
345
+
346
+ ## Contributing
347
+
348
+ Contributions are welcome! Please feel free to submit a Pull Request.
349
+
350
+ ## Related Projects
351
+
352
+ - [0http](https://0http.21no.de/#/) - The original inspiration
353
+ - [Bun](https://bun.sh/) - The JavaScript runtime this framework is built for
package/common.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import {Pattern, Methods} from 'trouter'
2
+ import {Logger} from 'pino'
2
3
 
3
4
  export interface IRouterConfig {
4
5
  defaultRoute?: RequestHandler
@@ -8,10 +9,44 @@ export interface IRouterConfig {
8
9
 
9
10
  export type StepFunction = (error?: unknown) => Response | Promise<Response>
10
11
 
11
- type ZeroRequest = Request & {
12
+ export interface ParsedFile {
13
+ name: string
14
+ size: number
15
+ type: string
16
+ data: File
17
+ }
18
+
19
+ export type ZeroRequest = Request & {
12
20
  params: Record<string, string>
13
21
  query: Record<string, string>
14
- ctx?: Record<string, any>
22
+ // Legacy compatibility properties (mirrored from ctx)
23
+ user?: any
24
+ jwt?: {
25
+ payload: any
26
+ header: any
27
+ token: string
28
+ }
29
+ apiKey?: string
30
+ // Context object for middleware data
31
+ ctx?: {
32
+ log?: Logger
33
+ user?: any
34
+ jwt?: {
35
+ payload: any
36
+ header: any
37
+ token: string
38
+ }
39
+ apiKey?: string
40
+ rateLimit?: {
41
+ limit: number
42
+ used: number
43
+ remaining: number
44
+ resetTime: Date
45
+ }
46
+ body?: any
47
+ files?: Record<string, ParsedFile | ParsedFile[]>
48
+ [key: string]: any
49
+ }
15
50
  }
16
51
 
17
52
  export type RequestHandler = (