0http-bun 1.1.2 → 1.1.3
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 +266 -71
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,89 +1,284 @@
|
|
|
1
|
-
#
|
|
2
|
-
Experimental, bun-based HTTP framework inspired by [0http](https://0http.21no.de/#/)
|
|
1
|
+
# 0http-bun
|
|
3
2
|
|
|
4
|
-
|
|
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
|
-
##
|
|
8
|
-
```js
|
|
9
|
-
const http = require('0http-bun')
|
|
5
|
+
## Key Benefits
|
|
10
6
|
|
|
11
|
-
|
|
12
|
-
|
|
7
|
+
- **🚀 Bun-Native Performance**: Optimized for Bun's runtime with minimal overhead
|
|
8
|
+
- **⚡ Zero Dependencies**: Core framework uses only essential, lightweight dependencies
|
|
9
|
+
- **🔧 TypeScript First**: Full TypeScript support with comprehensive type definitions
|
|
10
|
+
- **🎯 Minimalist API**: Clean, intuitive API that's easy to learn and use
|
|
11
|
+
- **🔄 Middleware Support**: Flexible middleware system with async/await support
|
|
12
|
+
- **📦 Tiny Footprint**: Lightweight framework focused on performance
|
|
13
|
+
- **🛡️ Web Standards**: Built on standard Web APIs (Request/Response)
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
bun add 0http-bun
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Quick Start
|
|
22
|
+
|
|
23
|
+
### Basic Server
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
import http from '0http-bun'
|
|
27
|
+
|
|
28
|
+
const {router} = http()
|
|
29
|
+
|
|
30
|
+
router.get('/', () => {
|
|
31
|
+
return new Response('Hello World!')
|
|
13
32
|
})
|
|
14
|
-
router.use((req, next) => {
|
|
15
|
-
req.ctx = {
|
|
16
|
-
engine: 'bun'
|
|
17
|
-
}
|
|
18
33
|
|
|
19
|
-
|
|
34
|
+
router.get('/:id', (req) => {
|
|
35
|
+
return Response.json({id: req.params.id})
|
|
20
36
|
})
|
|
21
|
-
|
|
22
|
-
|
|
37
|
+
|
|
38
|
+
// Start the server
|
|
39
|
+
Bun.serve({
|
|
40
|
+
port: 3000,
|
|
41
|
+
fetch: router.fetch,
|
|
23
42
|
})
|
|
24
|
-
|
|
25
|
-
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### With TypeScript Types
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
import http, {ZeroRequest, StepFunction} from '0http-bun'
|
|
49
|
+
|
|
50
|
+
const {router} = http({
|
|
51
|
+
port: 3000,
|
|
52
|
+
errorHandler: (err: Error) => {
|
|
53
|
+
console.error('Server error:', err)
|
|
54
|
+
return new Response('Internal Server Error', {status: 500})
|
|
55
|
+
},
|
|
26
56
|
})
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
57
|
+
|
|
58
|
+
// Typed middleware
|
|
59
|
+
router.use((req: ZeroRequest, next: StepFunction) => {
|
|
60
|
+
req.ctx = {
|
|
61
|
+
startTime: Date.now(),
|
|
62
|
+
engine: 'bun',
|
|
63
|
+
}
|
|
64
|
+
return next()
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
// Typed route handlers
|
|
68
|
+
router.get('/:id', async (req: ZeroRequest) => {
|
|
69
|
+
return Response.json({
|
|
70
|
+
id: req.params.id,
|
|
71
|
+
context: req.ctx,
|
|
30
72
|
})
|
|
31
73
|
})
|
|
32
74
|
|
|
33
|
-
|
|
75
|
+
router.post('/users', async (req: ZeroRequest) => {
|
|
76
|
+
const body = await req.json()
|
|
77
|
+
return Response.json({created: true, data: body}, {status: 201})
|
|
78
|
+
})
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## API Reference
|
|
82
|
+
|
|
83
|
+
### Router Configuration
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
interface IRouterConfig {
|
|
87
|
+
defaultRoute?: RequestHandler // Custom 404 handler
|
|
88
|
+
errorHandler?: (err: Error) => Response | Promise<Response> // Error handler
|
|
89
|
+
port?: number // Port number (for reference)
|
|
90
|
+
}
|
|
34
91
|
```
|
|
35
|
-
|
|
36
|
-
|
|
92
|
+
|
|
93
|
+
### Request Object
|
|
94
|
+
|
|
95
|
+
The `ZeroRequest` extends the standard `Request` with additional properties:
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
type ZeroRequest = Request & {
|
|
99
|
+
params: Record<string, string> // URL parameters
|
|
100
|
+
query: Record<string, string> // Query string parameters
|
|
101
|
+
ctx?: Record<string, any> // Custom context (set by middleware)
|
|
102
|
+
}
|
|
37
103
|
```
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
104
|
+
|
|
105
|
+
### Route Methods
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
// HTTP Methods
|
|
109
|
+
router.get(pattern, ...handlers)
|
|
110
|
+
router.post(pattern, ...handlers)
|
|
111
|
+
router.put(pattern, ...handlers)
|
|
112
|
+
router.patch(pattern, ...handlers)
|
|
113
|
+
router.delete(pattern, ...handlers)
|
|
114
|
+
router.head(pattern, ...handlers)
|
|
115
|
+
router.options(pattern, ...handlers)
|
|
116
|
+
router.connect(pattern, ...handlers)
|
|
117
|
+
router.trace(pattern, ...handlers)
|
|
118
|
+
|
|
119
|
+
// Generic method
|
|
120
|
+
router.on(method, pattern, ...handlers)
|
|
121
|
+
|
|
122
|
+
// All methods
|
|
123
|
+
router.all(pattern, ...handlers)
|
|
52
124
|
```
|
|
53
|
-
|
|
125
|
+
|
|
126
|
+
### Middleware
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
// Global middleware
|
|
130
|
+
router.use((req, next) => {
|
|
131
|
+
// Middleware logic
|
|
132
|
+
return next()
|
|
133
|
+
})
|
|
134
|
+
|
|
135
|
+
// Path-specific middleware
|
|
136
|
+
router.use('/api/*', (req, next) => {
|
|
137
|
+
// API-specific middleware
|
|
138
|
+
return next()
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
// Multiple middlewares
|
|
142
|
+
router.use(authMiddleware, loggingMiddleware, (req, next) => next())
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## Examples
|
|
146
|
+
|
|
147
|
+
### Complete REST API
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
import http, {ZeroRequest, StepFunction} from '0http-bun'
|
|
151
|
+
|
|
152
|
+
const {router} = http({
|
|
153
|
+
errorHandler: (err: Error) => {
|
|
154
|
+
return Response.json({error: err.message}, {status: 500})
|
|
155
|
+
},
|
|
156
|
+
})
|
|
157
|
+
|
|
158
|
+
// Logging middleware
|
|
159
|
+
router.use((req: ZeroRequest, next: StepFunction) => {
|
|
160
|
+
console.log(`${req.method} ${req.url}`)
|
|
161
|
+
return next()
|
|
162
|
+
})
|
|
163
|
+
|
|
164
|
+
// JSON body parser middleware for POST/PUT
|
|
165
|
+
router.use('/api/*', async (req: ZeroRequest, next: StepFunction) => {
|
|
166
|
+
if (req.method === 'POST' || req.method === 'PUT') {
|
|
167
|
+
try {
|
|
168
|
+
req.ctx = {...req.ctx, body: await req.json()}
|
|
169
|
+
} catch (err) {
|
|
170
|
+
return Response.json({error: 'Invalid JSON'}, {status: 400})
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return next()
|
|
174
|
+
})
|
|
175
|
+
|
|
176
|
+
// Routes
|
|
177
|
+
router.get('/api/users', () => {
|
|
178
|
+
return Response.json([
|
|
179
|
+
{id: 1, name: 'John'},
|
|
180
|
+
{id: 2, name: 'Jane'},
|
|
181
|
+
])
|
|
182
|
+
})
|
|
183
|
+
|
|
184
|
+
router.get('/api/users/:id', (req: ZeroRequest) => {
|
|
185
|
+
const {id} = req.params
|
|
186
|
+
return Response.json({id: Number(id), name: 'User'})
|
|
187
|
+
})
|
|
188
|
+
|
|
189
|
+
router.post('/api/users', (req: ZeroRequest) => {
|
|
190
|
+
const userData = req.ctx?.body
|
|
191
|
+
return Response.json({id: Date.now(), ...userData}, {status: 201})
|
|
192
|
+
})
|
|
193
|
+
|
|
194
|
+
router.delete('/api/users/:id', (req: ZeroRequest) => {
|
|
195
|
+
const {id} = req.params
|
|
196
|
+
return Response.json({deleted: id})
|
|
197
|
+
})
|
|
198
|
+
|
|
199
|
+
// Start server
|
|
200
|
+
Bun.serve({
|
|
201
|
+
port: 3000,
|
|
202
|
+
fetch: router.fetch,
|
|
203
|
+
})
|
|
54
204
|
```
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
205
|
+
|
|
206
|
+
### Error Handling
|
|
207
|
+
|
|
208
|
+
```typescript
|
|
209
|
+
import http, {ZeroRequest} from '0http-bun'
|
|
210
|
+
|
|
211
|
+
const {router} = http({
|
|
212
|
+
errorHandler: (err: Error) => {
|
|
213
|
+
console.error('Application error:', err)
|
|
214
|
+
|
|
215
|
+
// Custom error responses based on error type
|
|
216
|
+
if (err.name === 'ValidationError') {
|
|
217
|
+
return Response.json(
|
|
218
|
+
{error: 'Validation failed', details: err.message},
|
|
219
|
+
{status: 400},
|
|
220
|
+
)
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
return Response.json({error: 'Internal server error'}, {status: 500})
|
|
224
|
+
},
|
|
225
|
+
defaultRoute: () => {
|
|
226
|
+
return Response.json({error: 'Route not found'}, {status: 404})
|
|
227
|
+
},
|
|
228
|
+
})
|
|
229
|
+
|
|
230
|
+
// Route that might throw an error
|
|
231
|
+
router.get('/api/risky', (req: ZeroRequest) => {
|
|
232
|
+
if (Math.random() > 0.5) {
|
|
233
|
+
const error = new Error('Random failure')
|
|
234
|
+
error.name = 'ValidationError'
|
|
235
|
+
throw error
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
return Response.json({success: true})
|
|
239
|
+
})
|
|
69
240
|
```
|
|
70
|
-
|
|
241
|
+
|
|
242
|
+
## Performance
|
|
243
|
+
|
|
244
|
+
0http-bun is designed for high performance with Bun's native capabilities:
|
|
245
|
+
|
|
246
|
+
- **Minimal overhead**: Direct use of Web APIs
|
|
247
|
+
- **Efficient routing**: Based on the proven `trouter` library
|
|
248
|
+
- **Fast parameter parsing**: Optimized URL parameter extraction
|
|
249
|
+
- **Query string parsing**: Uses `fast-querystring` for performance
|
|
250
|
+
|
|
251
|
+
### Benchmark Results
|
|
252
|
+
|
|
253
|
+
Run benchmarks with:
|
|
254
|
+
|
|
255
|
+
```bash
|
|
256
|
+
bun run bench
|
|
71
257
|
```
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
Transfer/sec: 2.19MB
|
|
258
|
+
|
|
259
|
+
## TypeScript Support
|
|
260
|
+
|
|
261
|
+
Full TypeScript support is included with comprehensive type definitions:
|
|
262
|
+
|
|
263
|
+
```typescript
|
|
264
|
+
import {
|
|
265
|
+
ZeroRequest,
|
|
266
|
+
StepFunction,
|
|
267
|
+
RequestHandler,
|
|
268
|
+
IRouter,
|
|
269
|
+
IRouterConfig,
|
|
270
|
+
} from '0http-bun'
|
|
86
271
|
```
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
272
|
+
|
|
273
|
+
## License
|
|
274
|
+
|
|
275
|
+
MIT
|
|
276
|
+
|
|
277
|
+
## Contributing
|
|
278
|
+
|
|
279
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
280
|
+
|
|
281
|
+
## Related Projects
|
|
282
|
+
|
|
283
|
+
- [0http](https://0http.21no.de/#/) - The original inspiration
|
|
284
|
+
- [Bun](https://bun.sh/) - The JavaScript runtime this framework is built for
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "0http-bun",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.3",
|
|
4
4
|
"description": "0http for Bun",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
"lib/"
|
|
27
27
|
],
|
|
28
28
|
"devDependencies": {
|
|
29
|
-
"0http-bun": "^1.1.
|
|
30
|
-
"bun-types": "^1.2.
|
|
29
|
+
"0http-bun": "^1.1.2",
|
|
30
|
+
"bun-types": "^1.2.15",
|
|
31
31
|
"mitata": "^1.0.34",
|
|
32
32
|
"prettier": "^3.5.3"
|
|
33
33
|
},
|