@spfn/core 0.2.0-beta.4 → 0.2.0-beta.42
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/cache/index.js +32 -29
- package/dist/cache/index.js.map +1 -1
- package/dist/codegen/index.d.ts +55 -8
- package/dist/codegen/index.js +179 -5
- package/dist/codegen/index.js.map +1 -1
- package/dist/config/index.d.ts +168 -6
- package/dist/config/index.js +29 -5
- package/dist/config/index.js.map +1 -1
- package/dist/db/index.d.ts +128 -4
- package/dist/db/index.js +177 -50
- package/dist/db/index.js.map +1 -1
- package/dist/env/index.d.ts +55 -1
- package/dist/env/index.js +71 -3
- package/dist/env/index.js.map +1 -1
- package/dist/env/loader.d.ts +27 -19
- package/dist/env/loader.js +33 -25
- package/dist/env/loader.js.map +1 -1
- package/dist/event/index.d.ts +27 -1
- package/dist/event/index.js +6 -1
- package/dist/event/index.js.map +1 -1
- package/dist/event/sse/client.d.ts +77 -2
- package/dist/event/sse/client.js +87 -24
- package/dist/event/sse/client.js.map +1 -1
- package/dist/event/sse/index.d.ts +10 -4
- package/dist/event/sse/index.js +158 -12
- package/dist/event/sse/index.js.map +1 -1
- package/dist/job/index.d.ts +23 -8
- package/dist/job/index.js +96 -20
- package/dist/job/index.js.map +1 -1
- package/dist/logger/index.d.ts +5 -0
- package/dist/logger/index.js +14 -0
- package/dist/logger/index.js.map +1 -1
- package/dist/middleware/index.d.ts +23 -1
- package/dist/middleware/index.js +58 -5
- package/dist/middleware/index.js.map +1 -1
- package/dist/nextjs/index.d.ts +2 -2
- package/dist/nextjs/index.js +77 -31
- package/dist/nextjs/index.js.map +1 -1
- package/dist/nextjs/server.d.ts +44 -23
- package/dist/nextjs/server.js +83 -65
- package/dist/nextjs/server.js.map +1 -1
- package/dist/route/index.d.ts +158 -4
- package/dist/route/index.js +253 -17
- package/dist/route/index.js.map +1 -1
- package/dist/server/index.d.ts +251 -16
- package/dist/server/index.js +774 -228
- package/dist/server/index.js.map +1 -1
- package/dist/{types-D_N_U-Py.d.ts → types-7Mhoxnnt.d.ts} +21 -1
- package/dist/types-DKQ90YL7.d.ts +372 -0
- package/docs/cache.md +133 -0
- package/docs/codegen.md +74 -0
- package/docs/database.md +370 -0
- package/docs/entity.md +539 -0
- package/docs/env.md +499 -0
- package/docs/errors.md +319 -0
- package/docs/event.md +443 -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 +247 -0
- package/docs/repository.md +496 -0
- package/docs/route.md +497 -0
- package/docs/server.md +429 -0
- package/package.json +3 -2
- package/dist/types-B-e_f2dQ.d.ts +0 -121
package/docs/server.md
ADDED
|
@@ -0,0 +1,429 @@
|
|
|
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 with drain behavior (AWS drain style):
|
|
195
|
+
|
|
196
|
+
```
|
|
197
|
+
SIGTERM
|
|
198
|
+
│
|
|
199
|
+
├─ Phase 1: server.close() ← 새 연결 거부, 진행 중 요청 대기
|
|
200
|
+
├─ Phase 2: stopBoss() ← pg-boss 작업 정리
|
|
201
|
+
├─ Phase 3: ShutdownManager.execute()
|
|
202
|
+
│ ├─ drain: tracked operations 완료 대기
|
|
203
|
+
│ └─ hooks: 등록된 훅 순서대로 실행
|
|
204
|
+
├─ Phase 4: beforeShutdown lifecycle ← 기존 lifecycle 호환
|
|
205
|
+
├─ Phase 5: closeDatabase / closeCache
|
|
206
|
+
└─ process.exit(0)
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
**Signals handled:** `SIGTERM`, `SIGINT`
|
|
210
|
+
|
|
211
|
+
### ShutdownManager
|
|
212
|
+
|
|
213
|
+
모듈별 독립적인 shutdown 훅 등록과 장기 작업 추적:
|
|
214
|
+
|
|
215
|
+
```typescript
|
|
216
|
+
import { getShutdownManager } from '@spfn/core/server';
|
|
217
|
+
|
|
218
|
+
const shutdown = getShutdownManager();
|
|
219
|
+
|
|
220
|
+
// 1. Shutdown 훅 등록 — 모듈별 독립 cleanup
|
|
221
|
+
shutdown.onShutdown('ai-client', async () =>
|
|
222
|
+
{
|
|
223
|
+
await openaiClient.close();
|
|
224
|
+
}, { timeout: 5000, order: 10 });
|
|
225
|
+
|
|
226
|
+
shutdown.onShutdown('search-index', async () =>
|
|
227
|
+
{
|
|
228
|
+
await elasticClient.close();
|
|
229
|
+
}, { order: 20 });
|
|
230
|
+
|
|
231
|
+
// 2. 장기 작업 추적 — shutdown 시 완료까지 대기
|
|
232
|
+
const result = await shutdown.trackOperation(
|
|
233
|
+
'ai-generate',
|
|
234
|
+
aiService.generate(prompt)
|
|
235
|
+
);
|
|
236
|
+
// shutdown 중이면 자동으로 throw → 503
|
|
237
|
+
|
|
238
|
+
// 3. Shutdown 상태 확인
|
|
239
|
+
if (shutdown.isShuttingDown())
|
|
240
|
+
{
|
|
241
|
+
return c.json({ error: 'Server is shutting down' }, 503);
|
|
242
|
+
}
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### Timeout Configuration
|
|
246
|
+
|
|
247
|
+
```typescript
|
|
248
|
+
defineServerConfig()
|
|
249
|
+
.timeout({
|
|
250
|
+
request: 120000, // SERVER_TIMEOUT (default: 120s)
|
|
251
|
+
keepAlive: 65000, // SERVER_KEEPALIVE_TIMEOUT (default: 65s)
|
|
252
|
+
headers: 60000, // SERVER_HEADERS_TIMEOUT (default: 60s)
|
|
253
|
+
})
|
|
254
|
+
.fetchTimeout({
|
|
255
|
+
connect: 10000, // FETCH_CONNECT_TIMEOUT (default: 10s)
|
|
256
|
+
headers: 300000, // FETCH_HEADERS_TIMEOUT (default: 300s)
|
|
257
|
+
body: 300000, // FETCH_BODY_TIMEOUT (default: 300s)
|
|
258
|
+
})
|
|
259
|
+
.shutdown({
|
|
260
|
+
timeout: 280000, // SHUTDOWN_TIMEOUT (default: 280s)
|
|
261
|
+
})
|
|
262
|
+
.build();
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
For long-running AI workloads, increase fetch timeouts:
|
|
266
|
+
|
|
267
|
+
```bash
|
|
268
|
+
FETCH_HEADERS_TIMEOUT=600000 # 10 minutes
|
|
269
|
+
FETCH_BODY_TIMEOUT=600000 # 10 minutes
|
|
270
|
+
RPC_PROXY_TIMEOUT=580000 # Must be < FETCH_HEADERS_TIMEOUT
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
AI 파이프라인 등 장기 작업이 있는 앱은 Helm chart과 함께 조정:
|
|
274
|
+
|
|
275
|
+
```yaml
|
|
276
|
+
# apps/values.yaml
|
|
277
|
+
gracefulShutdown:
|
|
278
|
+
terminationGracePeriodSeconds: 660 # 11분
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
```bash
|
|
282
|
+
SHUTDOWN_TIMEOUT=640000 # 660 - 5 - 15 = 640s
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
---
|
|
286
|
+
|
|
287
|
+
## Health Check
|
|
288
|
+
|
|
289
|
+
Built-in health endpoint at `/health`:
|
|
290
|
+
|
|
291
|
+
```bash
|
|
292
|
+
# Normal
|
|
293
|
+
curl http://localhost:8790/health
|
|
294
|
+
# { "status": "ok", "timestamp": "2024-..." }
|
|
295
|
+
|
|
296
|
+
# During shutdown → 503
|
|
297
|
+
# { "status": "shutting_down", "timestamp": "2024-..." }
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
---
|
|
301
|
+
|
|
302
|
+
## Environment Variables
|
|
303
|
+
|
|
304
|
+
```bash
|
|
305
|
+
# Server
|
|
306
|
+
PORT=8790
|
|
307
|
+
HOST=localhost
|
|
308
|
+
NODE_ENV=development
|
|
309
|
+
|
|
310
|
+
# Database
|
|
311
|
+
DATABASE_URL=postgresql://localhost:5432/mydb
|
|
312
|
+
DATABASE_WRITE_URL=postgresql://primary:5432/mydb
|
|
313
|
+
DATABASE_READ_URL=postgresql://replica:5432/mydb
|
|
314
|
+
|
|
315
|
+
# Redis
|
|
316
|
+
REDIS_URL=redis://localhost:6379
|
|
317
|
+
|
|
318
|
+
# Server Timeout (inbound HTTP server)
|
|
319
|
+
SERVER_TIMEOUT=120000 # Request timeout (default: 120s)
|
|
320
|
+
SERVER_KEEPALIVE_TIMEOUT=65000 # Keep-alive timeout (default: 65s)
|
|
321
|
+
SERVER_HEADERS_TIMEOUT=60000 # Headers timeout, Slowloris defense (default: 60s)
|
|
322
|
+
|
|
323
|
+
# Fetch Timeout (outbound HTTP via undici global dispatcher)
|
|
324
|
+
FETCH_CONNECT_TIMEOUT=10000 # TCP connection timeout (default: 10s)
|
|
325
|
+
FETCH_HEADERS_TIMEOUT=300000 # Response headers timeout (default: 300s)
|
|
326
|
+
FETCH_BODY_TIMEOUT=300000 # Body chunk interval timeout (default: 300s)
|
|
327
|
+
|
|
328
|
+
# RPC Proxy Timeout (Next.js → Backend)
|
|
329
|
+
RPC_PROXY_TIMEOUT=120000 # AbortController timeout (default: 120s)
|
|
330
|
+
|
|
331
|
+
# Shutdown
|
|
332
|
+
SHUTDOWN_TIMEOUT=280000 # Graceful shutdown timeout (default: 280s)
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
### Timeout Architecture
|
|
336
|
+
|
|
337
|
+
```
|
|
338
|
+
Request flow:
|
|
339
|
+
Client → Next.js API Route → fetch() → SPFN Backend
|
|
340
|
+
|
|
341
|
+
Timeout layers:
|
|
342
|
+
┌──────────────────────────────────────────────────────┐
|
|
343
|
+
│ RPC_PROXY_TIMEOUT (AbortController) default 120s │ ← shortest, returns 504
|
|
344
|
+
│ FETCH_HEADERS_TIMEOUT (undici) default 300s │ ← fetch socket level
|
|
345
|
+
│ FETCH_BODY_TIMEOUT (undici) default 300s │ ← body chunk interval
|
|
346
|
+
│ FETCH_CONNECT_TIMEOUT (undici) default 10s │ ← TCP connection
|
|
347
|
+
├──────────────────────────────────────────────────────┤
|
|
348
|
+
│ SERVER_TIMEOUT (backend server.timeout) default 120s │ ← backend HTTP server
|
|
349
|
+
│ SERVER_HEADERS_TIMEOUT default 60s │ ← Slowloris defense
|
|
350
|
+
│ SERVER_KEEPALIVE_TIMEOUT default 65s │ ← idle connection
|
|
351
|
+
└──────────────────────────────────────────────────────┘
|
|
352
|
+
|
|
353
|
+
Rule: RPC_PROXY_TIMEOUT < FETCH_HEADERS_TIMEOUT
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
---
|
|
357
|
+
|
|
358
|
+
## File Structure
|
|
359
|
+
|
|
360
|
+
```
|
|
361
|
+
src/server/
|
|
362
|
+
├── server.config.ts # Configuration (Level 2)
|
|
363
|
+
├── app.ts # Custom Hono app (Level 3, optional)
|
|
364
|
+
├── index.ts # Entry point
|
|
365
|
+
├── entities/ # Database schema
|
|
366
|
+
├── repositories/ # Data access
|
|
367
|
+
├── routes/ # API routes
|
|
368
|
+
└── middlewares/ # Custom middleware
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
---
|
|
372
|
+
|
|
373
|
+
## Startup Banner
|
|
374
|
+
|
|
375
|
+
On startup, server displays:
|
|
376
|
+
|
|
377
|
+
```
|
|
378
|
+
╭──────────────────────────────────────╮
|
|
379
|
+
│ │
|
|
380
|
+
│ SPFN Server v1.0.0 │
|
|
381
|
+
│ │
|
|
382
|
+
│ http://localhost:8790 │
|
|
383
|
+
│ │
|
|
384
|
+
│ Press Ctrl+C to stop │
|
|
385
|
+
│ │
|
|
386
|
+
╰──────────────────────────────────────╯
|
|
387
|
+
|
|
388
|
+
✓ Database connected
|
|
389
|
+
✓ Redis connected
|
|
390
|
+
✓ 12 routes registered
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
---
|
|
394
|
+
|
|
395
|
+
## Best Practices
|
|
396
|
+
|
|
397
|
+
### Do
|
|
398
|
+
|
|
399
|
+
```typescript
|
|
400
|
+
// 1. Export router type for client usage
|
|
401
|
+
export type AppRouter = typeof appRouter;
|
|
402
|
+
|
|
403
|
+
// 2. Use lifecycle hooks for initialization
|
|
404
|
+
.beforeStart(async () => {
|
|
405
|
+
await warmupCache();
|
|
406
|
+
})
|
|
407
|
+
|
|
408
|
+
// 3. Register global middlewares
|
|
409
|
+
.middlewares([authMiddleware, rateLimiter])
|
|
410
|
+
|
|
411
|
+
// 4. Use Level 2 for most projects
|
|
412
|
+
defineServerConfig()
|
|
413
|
+
.port(8790)
|
|
414
|
+
.routes(appRouter)
|
|
415
|
+
.build();
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
### Don't
|
|
419
|
+
|
|
420
|
+
```typescript
|
|
421
|
+
// 1. Don't hardcode port in production
|
|
422
|
+
.port(8790) // Use process.env.PORT instead
|
|
423
|
+
|
|
424
|
+
// 2. Don't skip database auto-init unless needed
|
|
425
|
+
.database(false) // Usually let it auto-detect
|
|
426
|
+
|
|
427
|
+
// 3. Don't use Level 3 unless necessary
|
|
428
|
+
// Level 2 covers most use cases
|
|
429
|
+
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spfn/core",
|
|
3
|
-
"version": "0.2.0-beta.
|
|
3
|
+
"version": "0.2.0-beta.42",
|
|
4
4
|
"description": "SPFN Framework Core - File-based routing, transactions, repository pattern",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -146,12 +146,13 @@
|
|
|
146
146
|
"dotenv": "^17.2.3",
|
|
147
147
|
"drizzle-orm": "^0.45.0",
|
|
148
148
|
"drizzle-typebox": "^0.1.0",
|
|
149
|
-
"hono": "^4.
|
|
149
|
+
"hono": "^4.12.4",
|
|
150
150
|
"jiti": "^2.6.1",
|
|
151
151
|
"micromatch": "^4.0.8",
|
|
152
152
|
"pg-boss": "^11.1.2",
|
|
153
153
|
"postgres": "^3.4.0",
|
|
154
154
|
"typescript": "^5.3.3",
|
|
155
|
+
"undici": "^7.24.0",
|
|
155
156
|
"zod": "^4.1.11"
|
|
156
157
|
},
|
|
157
158
|
"optionalDependencies": {
|
package/dist/types-B-e_f2dQ.d.ts
DELETED
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
import { E as EventRouterDef, I as InferEventNames, b as InferEventPayload } from './router-Di7ENoah.js';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* SSE Types
|
|
5
|
-
*
|
|
6
|
-
* Type definitions for Server-Sent Events
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* SSE message sent from server
|
|
11
|
-
*/
|
|
12
|
-
interface SSEMessage<TEvent extends string = string, TPayload = unknown> {
|
|
13
|
-
/** Event name */
|
|
14
|
-
event: TEvent;
|
|
15
|
-
/** Event payload */
|
|
16
|
-
data: TPayload;
|
|
17
|
-
/** Optional message ID for reconnection */
|
|
18
|
-
id?: string;
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* SSE Handler configuration
|
|
22
|
-
*/
|
|
23
|
-
interface SSEHandlerConfig {
|
|
24
|
-
/**
|
|
25
|
-
* Keep-alive ping interval in milliseconds
|
|
26
|
-
* @default 30000
|
|
27
|
-
*/
|
|
28
|
-
pingInterval?: number;
|
|
29
|
-
/**
|
|
30
|
-
* Custom headers for SSE response
|
|
31
|
-
*/
|
|
32
|
-
headers?: Record<string, string>;
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* SSE Client configuration
|
|
36
|
-
*/
|
|
37
|
-
interface SSEClientConfig {
|
|
38
|
-
/**
|
|
39
|
-
* Backend API host URL
|
|
40
|
-
* @default NEXT_PUBLIC_SPFN_API_URL || 'http://localhost:8790'
|
|
41
|
-
* @example 'http://localhost:8790'
|
|
42
|
-
* @example 'https://api.example.com'
|
|
43
|
-
*/
|
|
44
|
-
host?: string;
|
|
45
|
-
/**
|
|
46
|
-
* SSE endpoint pathname
|
|
47
|
-
* @default '/events/stream'
|
|
48
|
-
*/
|
|
49
|
-
pathname?: string;
|
|
50
|
-
/**
|
|
51
|
-
* Full URL (overrides host + pathname)
|
|
52
|
-
* @deprecated Use host and pathname instead
|
|
53
|
-
* @example 'http://localhost:8790/events/stream'
|
|
54
|
-
*/
|
|
55
|
-
url?: string;
|
|
56
|
-
/**
|
|
57
|
-
* Auto reconnect on disconnect
|
|
58
|
-
* @default true
|
|
59
|
-
*/
|
|
60
|
-
reconnect?: boolean;
|
|
61
|
-
/**
|
|
62
|
-
* Reconnect delay in milliseconds
|
|
63
|
-
* @default 3000
|
|
64
|
-
*/
|
|
65
|
-
reconnectDelay?: number;
|
|
66
|
-
/**
|
|
67
|
-
* Maximum reconnect attempts (0 = infinite)
|
|
68
|
-
* @default 0
|
|
69
|
-
*/
|
|
70
|
-
maxReconnectAttempts?: number;
|
|
71
|
-
/**
|
|
72
|
-
* Include credentials (cookies) in request
|
|
73
|
-
* @default false
|
|
74
|
-
*/
|
|
75
|
-
withCredentials?: boolean;
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* Event handler function
|
|
79
|
-
*/
|
|
80
|
-
type SSEEventHandler<TPayload> = (payload: TPayload) => void;
|
|
81
|
-
/**
|
|
82
|
-
* Event handlers map for EventRouter
|
|
83
|
-
*/
|
|
84
|
-
type SSEEventHandlers<TRouter extends EventRouterDef<any>> = {
|
|
85
|
-
[K in InferEventNames<TRouter>]?: SSEEventHandler<InferEventPayload<TRouter, K>>;
|
|
86
|
-
};
|
|
87
|
-
/**
|
|
88
|
-
* Subscription options
|
|
89
|
-
*/
|
|
90
|
-
interface SSESubscribeOptions<TRouter extends EventRouterDef<any>> {
|
|
91
|
-
/**
|
|
92
|
-
* Events to subscribe
|
|
93
|
-
*/
|
|
94
|
-
events: InferEventNames<TRouter>[];
|
|
95
|
-
/**
|
|
96
|
-
* Event handlers
|
|
97
|
-
*/
|
|
98
|
-
handlers: SSEEventHandlers<TRouter>;
|
|
99
|
-
/**
|
|
100
|
-
* Called when connection opens
|
|
101
|
-
*/
|
|
102
|
-
onOpen?: () => void;
|
|
103
|
-
/**
|
|
104
|
-
* Called on connection error
|
|
105
|
-
*/
|
|
106
|
-
onError?: (error: Event) => void;
|
|
107
|
-
/**
|
|
108
|
-
* Called when reconnecting
|
|
109
|
-
*/
|
|
110
|
-
onReconnect?: (attempt: number) => void;
|
|
111
|
-
}
|
|
112
|
-
/**
|
|
113
|
-
* SSE connection state
|
|
114
|
-
*/
|
|
115
|
-
type SSEConnectionState = 'connecting' | 'open' | 'closed' | 'error';
|
|
116
|
-
/**
|
|
117
|
-
* Unsubscribe function
|
|
118
|
-
*/
|
|
119
|
-
type SSEUnsubscribe = () => void;
|
|
120
|
-
|
|
121
|
-
export type { SSEHandlerConfig as S, SSEMessage as a, SSEClientConfig as b, SSEEventHandler as c, SSEEventHandlers as d, SSESubscribeOptions as e, SSEConnectionState as f, SSEUnsubscribe as g };
|