@spfn/core 0.2.0-beta.5 → 0.2.0-beta.8
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 +260 -1175
- package/dist/{boss-BO8ty33K.d.ts → boss-DI1r4kTS.d.ts} +24 -7
- package/dist/codegen/index.d.ts +47 -2
- package/dist/codegen/index.js +143 -5
- package/dist/codegen/index.js.map +1 -1
- package/dist/db/index.d.ts +13 -0
- package/dist/db/index.js +40 -6
- package/dist/db/index.js.map +1 -1
- package/dist/job/index.d.ts +23 -8
- package/dist/job/index.js +43 -3
- package/dist/job/index.js.map +1 -1
- package/dist/nextjs/index.d.ts +2 -2
- package/dist/nextjs/index.js +35 -3
- package/dist/nextjs/index.js.map +1 -1
- package/dist/nextjs/server.d.ts +61 -14
- package/dist/nextjs/server.js +98 -32
- package/dist/nextjs/server.js.map +1 -1
- package/dist/route/index.d.ts +136 -2
- package/dist/route/index.js +209 -11
- package/dist/route/index.js.map +1 -1
- package/dist/server/index.d.ts +72 -1
- package/dist/server/index.js +41 -0
- package/dist/server/index.js.map +1 -1
- package/dist/{types-D_N_U-Py.d.ts → types-BOPTApC2.d.ts} +15 -0
- package/docs/cache.md +133 -0
- package/docs/codegen.md +74 -0
- package/docs/database.md +346 -0
- package/docs/entity.md +539 -0
- package/docs/env.md +477 -0
- package/docs/errors.md +319 -0
- package/docs/event.md +116 -0
- package/docs/file-upload.md +717 -0
- package/docs/job.md +131 -0
- package/docs/logger.md +108 -0
- package/docs/middleware.md +337 -0
- package/docs/nextjs.md +241 -0
- package/docs/repository.md +496 -0
- package/docs/route.md +497 -0
- package/docs/server.md +307 -0
- package/package.json +1 -1
package/docs/server.md
ADDED
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
# Server
|
|
2
|
+
|
|
3
|
+
HTTP server configuration with three-level progressive customization.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
// src/server/index.ts
|
|
9
|
+
import { startServer } from '@spfn/core/server';
|
|
10
|
+
|
|
11
|
+
await startServer();
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Configuration Levels
|
|
17
|
+
|
|
18
|
+
### Level 1: Zero Config
|
|
19
|
+
|
|
20
|
+
No configuration needed. Uses sensible defaults:
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
import { startServer } from '@spfn/core/server';
|
|
24
|
+
|
|
25
|
+
await startServer();
|
|
26
|
+
// Port: 4000 (or process.env.PORT)
|
|
27
|
+
// Host: localhost (or process.env.HOST)
|
|
28
|
+
// Middleware: Logger + CORS + ErrorHandler
|
|
29
|
+
// Infrastructure: Auto-init from env vars
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Level 2: Partial Customization
|
|
33
|
+
|
|
34
|
+
Create `src/server/server.config.ts`:
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
import { defineServerConfig, defineRouter } from '@spfn/core/server';
|
|
38
|
+
import * as userRoutes from './routes/users';
|
|
39
|
+
import * as postRoutes from './routes/posts';
|
|
40
|
+
import { authMiddleware, rateLimiter } from './middlewares';
|
|
41
|
+
|
|
42
|
+
const appRouter = defineRouter({
|
|
43
|
+
...userRoutes,
|
|
44
|
+
...postRoutes
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
export default defineServerConfig()
|
|
48
|
+
.port(8790)
|
|
49
|
+
.host('0.0.0.0')
|
|
50
|
+
.routes(appRouter)
|
|
51
|
+
.middlewares([authMiddleware, rateLimiter])
|
|
52
|
+
.build();
|
|
53
|
+
|
|
54
|
+
export type AppRouter = typeof appRouter;
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Level 3: Full Control
|
|
58
|
+
|
|
59
|
+
Create `src/server/app.ts` for custom Hono setup:
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
import { Hono } from 'hono';
|
|
63
|
+
import { timing } from 'hono/timing';
|
|
64
|
+
import { compress } from 'hono/compress';
|
|
65
|
+
import type { AppFactory } from '@spfn/core/server';
|
|
66
|
+
|
|
67
|
+
export default (async () => {
|
|
68
|
+
const app = new Hono();
|
|
69
|
+
|
|
70
|
+
// Custom middleware
|
|
71
|
+
app.use('*', timing());
|
|
72
|
+
app.use('*', compress());
|
|
73
|
+
|
|
74
|
+
// Custom routes
|
|
75
|
+
app.get('/custom', (c) => c.json({ custom: true }));
|
|
76
|
+
|
|
77
|
+
return app;
|
|
78
|
+
}) satisfies AppFactory;
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Then in `server.config.ts`:
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
export default defineServerConfig()
|
|
85
|
+
.routes(appRouter) // Routes registered to your custom app
|
|
86
|
+
.build();
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Configuration Builder
|
|
92
|
+
|
|
93
|
+
### Basic Options
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
defineServerConfig()
|
|
97
|
+
.port(8790) // Server port
|
|
98
|
+
.host('0.0.0.0') // Server host
|
|
99
|
+
.routes(appRouter) // Router
|
|
100
|
+
.middlewares([...]) // Global middlewares
|
|
101
|
+
.build();
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Infrastructure Options
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
defineServerConfig()
|
|
108
|
+
.database(true) // Enable database (default: auto from env)
|
|
109
|
+
.redis(true) // Enable Redis (default: auto from env)
|
|
110
|
+
.build();
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### CORS Options
|
|
114
|
+
|
|
115
|
+
```typescript
|
|
116
|
+
defineServerConfig()
|
|
117
|
+
.cors({
|
|
118
|
+
origin: ['https://example.com'],
|
|
119
|
+
methods: ['GET', 'POST', 'PUT', 'DELETE'],
|
|
120
|
+
credentials: true
|
|
121
|
+
})
|
|
122
|
+
.build();
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Lifecycle Hooks
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
defineServerConfig()
|
|
129
|
+
.beforeStart(async () => {
|
|
130
|
+
// Before server starts
|
|
131
|
+
console.log('Initializing...');
|
|
132
|
+
})
|
|
133
|
+
.afterStart(async (server) => {
|
|
134
|
+
// After server is running
|
|
135
|
+
console.log(`Server running on port ${server.port}`);
|
|
136
|
+
})
|
|
137
|
+
.beforeShutdown(async () => {
|
|
138
|
+
// Before graceful shutdown
|
|
139
|
+
console.log('Shutting down...');
|
|
140
|
+
})
|
|
141
|
+
.build();
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## Router
|
|
147
|
+
|
|
148
|
+
### Define Router
|
|
149
|
+
|
|
150
|
+
```typescript
|
|
151
|
+
import { defineRouter } from '@spfn/core/route';
|
|
152
|
+
|
|
153
|
+
export const appRouter = defineRouter({
|
|
154
|
+
getUser,
|
|
155
|
+
createUser,
|
|
156
|
+
updateUser,
|
|
157
|
+
deleteUser
|
|
158
|
+
});
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Nested Routers
|
|
162
|
+
|
|
163
|
+
```typescript
|
|
164
|
+
export const appRouter = defineRouter({
|
|
165
|
+
users: defineRouter({
|
|
166
|
+
get: getUser,
|
|
167
|
+
create: createUser,
|
|
168
|
+
list: getUsers
|
|
169
|
+
}),
|
|
170
|
+
posts: defineRouter({
|
|
171
|
+
get: getPost,
|
|
172
|
+
create: createPost
|
|
173
|
+
})
|
|
174
|
+
});
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Type Export
|
|
178
|
+
|
|
179
|
+
```typescript
|
|
180
|
+
// server.config.ts
|
|
181
|
+
export type AppRouter = typeof appRouter;
|
|
182
|
+
|
|
183
|
+
// Use in Next.js client
|
|
184
|
+
import type { AppRouter } from '@/server/server.config';
|
|
185
|
+
import { createApi } from '@spfn/core/nextjs';
|
|
186
|
+
|
|
187
|
+
const api = createApi<AppRouter>();
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
## Graceful Shutdown
|
|
193
|
+
|
|
194
|
+
Automatic graceful shutdown handling:
|
|
195
|
+
|
|
196
|
+
1. Stop accepting new connections
|
|
197
|
+
2. Wait for in-flight requests
|
|
198
|
+
3. Close database connections
|
|
199
|
+
4. Close Redis connections
|
|
200
|
+
5. Exit process
|
|
201
|
+
|
|
202
|
+
**Signals handled:** `SIGTERM`, `SIGINT`
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## Health Check
|
|
207
|
+
|
|
208
|
+
Built-in health endpoint at `/health`:
|
|
209
|
+
|
|
210
|
+
```bash
|
|
211
|
+
curl http://localhost:8790/health
|
|
212
|
+
# { "status": "ok", "timestamp": "2024-..." }
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
---
|
|
216
|
+
|
|
217
|
+
## Environment Variables
|
|
218
|
+
|
|
219
|
+
```bash
|
|
220
|
+
# Server
|
|
221
|
+
PORT=8790
|
|
222
|
+
HOST=localhost
|
|
223
|
+
NODE_ENV=development
|
|
224
|
+
|
|
225
|
+
# Database
|
|
226
|
+
DATABASE_URL=postgresql://localhost:5432/mydb
|
|
227
|
+
DATABASE_WRITE_URL=postgresql://primary:5432/mydb
|
|
228
|
+
DATABASE_READ_URL=postgresql://replica:5432/mydb
|
|
229
|
+
|
|
230
|
+
# Redis
|
|
231
|
+
REDIS_URL=redis://localhost:6379
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
|
|
236
|
+
## File Structure
|
|
237
|
+
|
|
238
|
+
```
|
|
239
|
+
src/server/
|
|
240
|
+
├── server.config.ts # Configuration (Level 2)
|
|
241
|
+
├── app.ts # Custom Hono app (Level 3, optional)
|
|
242
|
+
├── index.ts # Entry point
|
|
243
|
+
├── entities/ # Database schema
|
|
244
|
+
├── repositories/ # Data access
|
|
245
|
+
├── routes/ # API routes
|
|
246
|
+
└── middlewares/ # Custom middleware
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
## Startup Banner
|
|
252
|
+
|
|
253
|
+
On startup, server displays:
|
|
254
|
+
|
|
255
|
+
```
|
|
256
|
+
╭──────────────────────────────────────╮
|
|
257
|
+
│ │
|
|
258
|
+
│ SPFN Server v1.0.0 │
|
|
259
|
+
│ │
|
|
260
|
+
│ http://localhost:8790 │
|
|
261
|
+
│ │
|
|
262
|
+
│ Press Ctrl+C to stop │
|
|
263
|
+
│ │
|
|
264
|
+
╰──────────────────────────────────────╯
|
|
265
|
+
|
|
266
|
+
✓ Database connected
|
|
267
|
+
✓ Redis connected
|
|
268
|
+
✓ 12 routes registered
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
---
|
|
272
|
+
|
|
273
|
+
## Best Practices
|
|
274
|
+
|
|
275
|
+
### Do
|
|
276
|
+
|
|
277
|
+
```typescript
|
|
278
|
+
// 1. Export router type for client usage
|
|
279
|
+
export type AppRouter = typeof appRouter;
|
|
280
|
+
|
|
281
|
+
// 2. Use lifecycle hooks for initialization
|
|
282
|
+
.beforeStart(async () => {
|
|
283
|
+
await warmupCache();
|
|
284
|
+
})
|
|
285
|
+
|
|
286
|
+
// 3. Register global middlewares
|
|
287
|
+
.middlewares([authMiddleware, rateLimiter])
|
|
288
|
+
|
|
289
|
+
// 4. Use Level 2 for most projects
|
|
290
|
+
defineServerConfig()
|
|
291
|
+
.port(8790)
|
|
292
|
+
.routes(appRouter)
|
|
293
|
+
.build();
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
### Don't
|
|
297
|
+
|
|
298
|
+
```typescript
|
|
299
|
+
// 1. Don't hardcode port in production
|
|
300
|
+
.port(8790) // Use process.env.PORT instead
|
|
301
|
+
|
|
302
|
+
// 2. Don't skip database auto-init unless needed
|
|
303
|
+
.database(false) // Usually let it auto-detect
|
|
304
|
+
|
|
305
|
+
// 3. Don't use Level 3 unless necessary
|
|
306
|
+
// Level 2 covers most use cases
|
|
307
|
+
```
|