@c9up/ream 0.1.6 → 0.1.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/dist/Application.d.ts +9 -1
- package/dist/Application.d.ts.map +1 -1
- package/dist/Application.js +35 -5
- package/dist/Application.js.map +1 -1
- package/dist/GracefulShutdown.d.ts.map +1 -1
- package/dist/GracefulShutdown.js +13 -7
- package/dist/GracefulShutdown.js.map +1 -1
- package/dist/HttpKernel.d.ts.map +1 -1
- package/dist/HttpKernel.js +43 -14
- package/dist/HttpKernel.js.map +1 -1
- package/dist/Ignitor.d.ts +10 -10
- package/dist/Ignitor.d.ts.map +1 -1
- package/dist/Ignitor.js +104 -32
- package/dist/Ignitor.js.map +1 -1
- package/dist/bodyparser/BodyParserMiddleware.d.ts +3 -0
- package/dist/bodyparser/BodyParserMiddleware.d.ts.map +1 -1
- package/dist/bodyparser/BodyParserMiddleware.js +32 -16
- package/dist/bodyparser/BodyParserMiddleware.js.map +1 -1
- package/dist/bodyparser/parseSize.d.ts +2 -1
- package/dist/bodyparser/parseSize.d.ts.map +1 -1
- package/dist/bodyparser/parseSize.js +2 -1
- package/dist/bodyparser/parseSize.js.map +1 -1
- package/dist/container/Container.d.ts.map +1 -1
- package/dist/container/Container.js +6 -7
- package/dist/container/Container.js.map +1 -1
- package/dist/decorators/Service.d.ts +4 -6
- package/dist/decorators/Service.d.ts.map +1 -1
- package/dist/decorators/Service.js +0 -1
- package/dist/decorators/Service.js.map +1 -1
- package/dist/events/Emitter.d.ts +16 -6
- package/dist/events/Emitter.d.ts.map +1 -1
- package/dist/events/Emitter.js +32 -25
- package/dist/events/Emitter.js.map +1 -1
- package/dist/events/EventsProvider.d.ts +1 -0
- package/dist/events/EventsProvider.d.ts.map +1 -1
- package/dist/events/EventsProvider.js +6 -4
- package/dist/events/EventsProvider.js.map +1 -1
- package/dist/graphql/GraphQLEngine.d.ts +16 -0
- package/dist/graphql/GraphQLEngine.d.ts.map +1 -1
- package/dist/graphql/GraphQLEngine.js +122 -4
- package/dist/graphql/GraphQLEngine.js.map +1 -1
- package/dist/graphql/GraphQLProvider.d.ts.map +1 -1
- package/dist/graphql/GraphQLProvider.js +13 -2
- package/dist/graphql/GraphQLProvider.js.map +1 -1
- package/dist/http/HttpContext.d.ts +27 -1
- package/dist/http/HttpContext.d.ts.map +1 -1
- package/dist/http/HttpContext.js +20 -1
- package/dist/http/HttpContext.js.map +1 -1
- package/dist/http/RedirectBuilder.d.ts +5 -1
- package/dist/http/RedirectBuilder.d.ts.map +1 -1
- package/dist/http/RedirectBuilder.js +26 -3
- package/dist/http/RedirectBuilder.js.map +1 -1
- package/dist/http/Request.d.ts +13 -0
- package/dist/http/Request.d.ts.map +1 -1
- package/dist/http/Request.js +18 -0
- package/dist/http/Request.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/middleware/Pipeline.d.ts +13 -0
- package/dist/middleware/Pipeline.d.ts.map +1 -1
- package/dist/middleware/Pipeline.js +43 -7
- package/dist/middleware/Pipeline.js.map +1 -1
- package/dist/router/Router.d.ts +21 -2
- package/dist/router/Router.d.ts.map +1 -1
- package/dist/router/Router.js +53 -8
- package/dist/router/Router.js.map +1 -1
- package/dist/rpc/RpcProvider.d.ts.map +1 -1
- package/dist/rpc/RpcProvider.js +11 -2
- package/dist/rpc/RpcProvider.js.map +1 -1
- package/dist/rpc/RpcRouter.d.ts +11 -3
- package/dist/rpc/RpcRouter.d.ts.map +1 -1
- package/dist/rpc/RpcRouter.js +92 -8
- package/dist/rpc/RpcRouter.js.map +1 -1
- package/dist/scheduler/ScheduleProvider.d.ts.map +1 -1
- package/dist/scheduler/ScheduleProvider.js +10 -0
- package/dist/scheduler/ScheduleProvider.js.map +1 -1
- package/dist/scheduler/locks/MemoryLockBackend.d.ts +0 -1
- package/dist/scheduler/locks/MemoryLockBackend.d.ts.map +1 -1
- package/dist/scheduler/locks/MemoryLockBackend.js +0 -1
- package/dist/scheduler/locks/MemoryLockBackend.js.map +1 -1
- package/dist/services/app.d.ts +6 -0
- package/dist/services/app.d.ts.map +1 -1
- package/dist/services/app.js +9 -0
- package/dist/services/app.js.map +1 -1
- package/dist/services/router.d.ts +5 -0
- package/dist/services/router.d.ts.map +1 -1
- package/dist/services/router.js +8 -0
- package/dist/services/router.js.map +1 -1
- package/dist/services/server.d.ts +5 -0
- package/dist/services/server.d.ts.map +1 -1
- package/dist/services/server.js +8 -0
- package/dist/services/server.js.map +1 -1
- package/dist/session/SessionMiddleware.d.ts.map +1 -1
- package/dist/session/SessionMiddleware.js +4 -0
- package/dist/session/SessionMiddleware.js.map +1 -1
- package/dist/session/drivers/MemoryDriver.d.ts +1 -1
- package/dist/session/drivers/MemoryDriver.d.ts.map +1 -1
- package/dist/session/drivers/MemoryDriver.js +14 -6
- package/dist/session/drivers/MemoryDriver.js.map +1 -1
- package/dist/testing/TestClient.d.ts +11 -5
- package/dist/testing/TestClient.d.ts.map +1 -1
- package/dist/testing/TestClient.js +9 -4
- package/dist/testing/TestClient.js.map +1 -1
- package/events.darwin-arm64.node +0 -0
- package/events.darwin-x64.node +0 -0
- package/events.linux-arm64-gnu.node +0 -0
- package/events.linux-x64-gnu.node +0 -0
- package/events.win32-x64-msvc.node +0 -0
- package/index.darwin-arm64.node +0 -0
- package/index.darwin-x64.node +0 -0
- package/index.linux-arm64-gnu.node +0 -0
- package/index.linux-x64-gnu.node +0 -0
- package/index.win32-x64-msvc.node +0 -0
- package/package.json +29 -1
- package/scheduler.darwin-arm64.node +0 -0
- package/scheduler.darwin-x64.node +0 -0
- package/scheduler.linux-arm64-gnu.node +0 -0
- package/scheduler.linux-x64-gnu.node +0 -0
- package/scheduler.win32-x64-msvc.node +0 -0
- package/src/Application.ts +36 -5
- package/src/GracefulShutdown.ts +15 -7
- package/src/HttpKernel.ts +52 -17
- package/src/Ignitor.ts +106 -34
- package/src/bodyparser/BodyParserMiddleware.ts +43 -16
- package/src/bodyparser/parseSize.ts +2 -1
- package/src/container/Container.ts +6 -9
- package/src/decorators/Service.ts +4 -6
- package/src/events/Emitter.ts +36 -28
- package/src/events/EventsProvider.ts +6 -4
- package/src/graphql/GraphQLEngine.ts +139 -3
- package/src/graphql/GraphQLProvider.ts +17 -2
- package/src/http/HttpContext.ts +38 -1
- package/src/http/RedirectBuilder.ts +23 -3
- package/src/http/Request.ts +20 -0
- package/src/index.ts +2 -2
- package/src/middleware/Pipeline.ts +61 -8
- package/src/router/Router.ts +53 -8
- package/src/rpc/RpcProvider.ts +14 -2
- package/src/rpc/RpcRouter.ts +115 -11
- package/src/scheduler/ScheduleProvider.ts +10 -0
- package/src/scheduler/locks/MemoryLockBackend.ts +0 -2
- package/src/services/app.ts +9 -0
- package/src/services/router.ts +8 -0
- package/src/services/server.ts +8 -0
- package/src/session/SessionMiddleware.ts +6 -0
- package/src/session/drivers/MemoryDriver.ts +14 -6
- package/src/testing/TestClient.ts +18 -7
- package/dist/server/HyperServer.d.ts +0 -64
- package/dist/server/HyperServer.d.ts.map +0 -1
- package/dist/server/HyperServer.js +0 -54
- package/dist/server/HyperServer.js.map +0 -1
- package/dist/storage/S3Driver.d.ts +0 -27
- package/dist/storage/S3Driver.d.ts.map +0 -1
- package/dist/storage/S3Driver.js +0 -135
- package/dist/storage/S3Driver.js.map +0 -1
- package/dist/storage/StorageManager.d.ts +0 -31
- package/dist/storage/StorageManager.d.ts.map +0 -1
- package/dist/storage/StorageManager.js +0 -120
- package/dist/storage/StorageManager.js.map +0 -1
- package/src/server/HyperServer.ts +0 -121
- package/src/storage/S3Driver.ts +0 -171
- package/src/storage/StorageManager.ts +0 -142
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TestClient.js","sourceRoot":"","sources":["../../src/testing/TestClient.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,EAIL,cAAc,GACf,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"TestClient.js","sourceRoot":"","sources":["../../src/testing/TestClient.ts"],"names":[],"mappings":"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"}
|
package/events.darwin-arm64.node
CHANGED
|
Binary file
|
package/events.darwin-x64.node
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/index.darwin-arm64.node
CHANGED
|
Binary file
|
package/index.darwin-x64.node
CHANGED
|
Binary file
|
|
Binary file
|
package/index.linux-x64-gnu.node
CHANGED
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@c9up/ream",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8",
|
|
4
4
|
"description": "Ream — Rust-powered Node.js application framework",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -31,6 +31,34 @@
|
|
|
31
31
|
"types": "./dist/session/SessionMiddleware.d.ts",
|
|
32
32
|
"import": "./dist/session/SessionMiddleware.js"
|
|
33
33
|
},
|
|
34
|
+
"./events": {
|
|
35
|
+
"types": "./dist/events/index.d.ts",
|
|
36
|
+
"import": "./dist/events/index.js"
|
|
37
|
+
},
|
|
38
|
+
"./events/provider": {
|
|
39
|
+
"types": "./dist/events/EventsProvider.d.ts",
|
|
40
|
+
"import": "./dist/events/EventsProvider.js"
|
|
41
|
+
},
|
|
42
|
+
"./events/config": {
|
|
43
|
+
"types": "./dist/events/config.d.ts",
|
|
44
|
+
"import": "./dist/events/config.js"
|
|
45
|
+
},
|
|
46
|
+
"./events/services/main": {
|
|
47
|
+
"types": "./dist/events/services/main.d.ts",
|
|
48
|
+
"import": "./dist/events/services/main.js"
|
|
49
|
+
},
|
|
50
|
+
"./events/testing": {
|
|
51
|
+
"types": "./dist/events/testing/FakeBus.d.ts",
|
|
52
|
+
"import": "./dist/events/testing/FakeBus.js"
|
|
53
|
+
},
|
|
54
|
+
"./events/helix": {
|
|
55
|
+
"types": "./dist/events/helix/helpers.d.ts",
|
|
56
|
+
"import": "./dist/events/helix/helpers.js"
|
|
57
|
+
},
|
|
58
|
+
"./events/configure": {
|
|
59
|
+
"types": "./dist/events/configure.d.ts",
|
|
60
|
+
"import": "./dist/events/configure.js"
|
|
61
|
+
},
|
|
34
62
|
"./helpers": {
|
|
35
63
|
"types": "./dist/helpers/index.d.ts",
|
|
36
64
|
"import": "./dist/helpers/index.js"
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/src/Application.ts
CHANGED
|
@@ -88,11 +88,18 @@ export class Application implements AppContext {
|
|
|
88
88
|
|
|
89
89
|
// ─── Signal handling ──────────────────────────────────────
|
|
90
90
|
|
|
91
|
+
/** Signal handlers installed via listen()/listenIf(), removed on shutdown. */
|
|
92
|
+
#signalHandlers: Array<[NodeJS.Signals, () => void]> = []
|
|
93
|
+
|
|
91
94
|
/**
|
|
92
95
|
* Listen for a process signal.
|
|
93
96
|
* Like AdonisJS app.listen('SIGTERM', () => app.terminate()).
|
|
97
|
+
* Tracked and removed on shutdown() — otherwise every boot/stop cycle leaks
|
|
98
|
+
* a process listener, and a real signal would fire the handlers of every
|
|
99
|
+
* previously stopped app instance.
|
|
94
100
|
*/
|
|
95
101
|
listen(signal: NodeJS.Signals, callback: () => void): void {
|
|
102
|
+
this.#signalHandlers.push([signal, callback])
|
|
96
103
|
process.on(signal, callback)
|
|
97
104
|
}
|
|
98
105
|
|
|
@@ -102,7 +109,7 @@ export class Application implements AppContext {
|
|
|
102
109
|
*/
|
|
103
110
|
listenIf(condition: boolean, signal: NodeJS.Signals, callback: () => void): void {
|
|
104
111
|
if (condition) {
|
|
105
|
-
|
|
112
|
+
this.listen(signal, callback)
|
|
106
113
|
}
|
|
107
114
|
}
|
|
108
115
|
|
|
@@ -149,17 +156,41 @@ export class Application implements AppContext {
|
|
|
149
156
|
}
|
|
150
157
|
}
|
|
151
158
|
|
|
152
|
-
/**
|
|
159
|
+
/**
|
|
160
|
+
* Shutdown all providers in reverse order. Each hook/provider shutdown is
|
|
161
|
+
* isolated: one throwing provider must not prevent the remaining providers
|
|
162
|
+
* from closing their resources (DB pools, queues). Errors are aggregated.
|
|
163
|
+
*/
|
|
153
164
|
async shutdown(): Promise<void> {
|
|
154
|
-
|
|
165
|
+
const errors: unknown[] = []
|
|
166
|
+
|
|
155
167
|
for (const hook of this._shutdownHooks) {
|
|
156
|
-
|
|
168
|
+
try {
|
|
169
|
+
await hook()
|
|
170
|
+
} catch (err) {
|
|
171
|
+
errors.push(err)
|
|
172
|
+
}
|
|
157
173
|
}
|
|
158
174
|
|
|
159
175
|
for (const provider of [...this.providers].reverse()) {
|
|
160
|
-
|
|
176
|
+
try {
|
|
177
|
+
await callProviderPhase(provider, 'shutdown')
|
|
178
|
+
} catch (err) {
|
|
179
|
+
errors.push(err)
|
|
180
|
+
}
|
|
161
181
|
}
|
|
182
|
+
|
|
183
|
+
// Remove the process signal handlers this app installed.
|
|
184
|
+
for (const [signal, callback] of this.#signalHandlers) {
|
|
185
|
+
process.off(signal, callback)
|
|
186
|
+
}
|
|
187
|
+
this.#signalHandlers = []
|
|
188
|
+
|
|
162
189
|
this._booted = false
|
|
190
|
+
if (errors.length === 1) throw errors[0]
|
|
191
|
+
if (errors.length > 1) {
|
|
192
|
+
throw new AggregateError(errors, 'Application.shutdown() completed with errors')
|
|
193
|
+
}
|
|
163
194
|
}
|
|
164
195
|
|
|
165
196
|
/** Register a shutdown hook. */
|
package/src/GracefulShutdown.ts
CHANGED
|
@@ -29,20 +29,25 @@ export function installGracefulShutdown(options: ShutdownOptions): ShutdownHandl
|
|
|
29
29
|
const logger = options.logger ?? { info: () => {}, error: () => {} }
|
|
30
30
|
let shutdownInProgress = false
|
|
31
31
|
|
|
32
|
+
let hadError = false
|
|
33
|
+
|
|
32
34
|
const shutdown = async () => {
|
|
33
35
|
if (shutdownInProgress) return
|
|
34
36
|
shutdownInProgress = true
|
|
35
37
|
|
|
36
38
|
logger.info('Graceful shutdown initiated...')
|
|
37
39
|
|
|
40
|
+
let timedOut = false
|
|
38
41
|
let timeoutHandle: ReturnType<typeof setTimeout> | undefined
|
|
39
42
|
|
|
40
43
|
const drainPromise = options.onShutdown().catch((err) => {
|
|
44
|
+
hadError = true
|
|
41
45
|
logger.error(`Shutdown error: ${err instanceof Error ? err.message : String(err)}`)
|
|
42
46
|
})
|
|
43
47
|
|
|
44
48
|
const timeoutPromise = new Promise<void>((resolve) => {
|
|
45
49
|
timeoutHandle = setTimeout(() => {
|
|
50
|
+
timedOut = true
|
|
46
51
|
logger.error(`Drain timeout exceeded (${drainTimeout}ms) — forcing shutdown`)
|
|
47
52
|
resolve()
|
|
48
53
|
}, drainTimeout)
|
|
@@ -52,22 +57,25 @@ export function installGracefulShutdown(options: ShutdownOptions): ShutdownHandl
|
|
|
52
57
|
if (timeoutHandle) clearTimeout(timeoutHandle)
|
|
53
58
|
|
|
54
59
|
logger.info('Shutdown complete')
|
|
55
|
-
process.exit(0)
|
|
60
|
+
process.exit(hadError || timedOut ? 1 : 0)
|
|
56
61
|
}
|
|
57
62
|
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
63
|
+
const handleSignal = () => {
|
|
64
|
+
if (shutdownInProgress) {
|
|
65
|
+
// Second signal while draining — escalate immediately.
|
|
66
|
+
logger.error('Forced exit: second signal received during shutdown')
|
|
61
67
|
process.exit(1)
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
const onSigint = () => {
|
|
68
|
+
return
|
|
69
|
+
}
|
|
65
70
|
shutdown().catch((err) => {
|
|
66
71
|
logger.error(`Fatal: ${err}`)
|
|
67
72
|
process.exit(1)
|
|
68
73
|
})
|
|
69
74
|
}
|
|
70
75
|
|
|
76
|
+
const onSigterm = handleSignal
|
|
77
|
+
const onSigint = handleSignal
|
|
78
|
+
|
|
71
79
|
process.on('SIGTERM', onSigterm)
|
|
72
80
|
process.on('SIGINT', onSigint)
|
|
73
81
|
|
package/src/HttpKernel.ts
CHANGED
|
@@ -14,9 +14,13 @@ import type { Container } from './container/Container.js'
|
|
|
14
14
|
import type { Emitter } from './events/Emitter.js'
|
|
15
15
|
import { E_ROUTE_NOT_FOUND, ExceptionHandler } from './http/Exception.js'
|
|
16
16
|
import { HttpContext } from './http/HttpContext.js'
|
|
17
|
-
import type {
|
|
17
|
+
import type {
|
|
18
|
+
MiddlewareFunction,
|
|
19
|
+
MiddlewareRegistry,
|
|
20
|
+
RuntimeValidator,
|
|
21
|
+
} from './middleware/Pipeline.js'
|
|
18
22
|
import { compose } from './middleware/Pipeline.js'
|
|
19
|
-
import type { Router } from './router/Router.js'
|
|
23
|
+
import type { RouteDefinition, Router } from './router/Router.js'
|
|
20
24
|
import type { Dict } from './types/helpers.js'
|
|
21
25
|
|
|
22
26
|
export interface HttpKernelConfig {
|
|
@@ -73,16 +77,14 @@ export function createHttpKernel(
|
|
|
73
77
|
const serverMw = config.serverMiddleware ?? []
|
|
74
78
|
const routerMw = config.routerMiddleware ?? []
|
|
75
79
|
|
|
76
|
-
// Pipeline cache: compiled middleware chain per
|
|
77
|
-
//
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
//
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
pipelineCache.clear()
|
|
85
|
-
}
|
|
80
|
+
// Pipeline cache: compiled middleware chain per ROUTE OBJECT (PERF-7).
|
|
81
|
+
// Keyed by route identity, not `method:path` — two routes sharing a path but
|
|
82
|
+
// differing by `domain` would otherwise collide and serve the first-warmed
|
|
83
|
+
// handler for both. WeakMap also makes hot-reload invalidation automatic:
|
|
84
|
+
// router.clear() drops the route objects, their chains become unreachable
|
|
85
|
+
// and are GC'd — no need to monkey-patch router.clear (which leaked a
|
|
86
|
+
// wrapper chain when createHttpKernel ran more than once on one router).
|
|
87
|
+
const pipelineCache = new WeakMap<RouteDefinition, { chain: MiddlewareFunction }>()
|
|
86
88
|
|
|
87
89
|
// Resolve the events emitter once, only when the app registered
|
|
88
90
|
// `EventsProvider`. Lazy + cached: the binding may not exist yet at kernel
|
|
@@ -135,6 +137,14 @@ export function createHttpKernel(
|
|
|
135
137
|
const ctx = new HttpContext(correlationId, reqData, match?.params ?? {}, routeInfo)
|
|
136
138
|
ctx.setRouteUrlResolver((name, params) => config.router.makeUrl(name, params))
|
|
137
139
|
ctx.events = resolveEvents()
|
|
140
|
+
// Core lifecycle event: a request entered the kernel. Fire-and-forget through
|
|
141
|
+
// the bus when events are wired (`?.` → zero cost when no provider). The
|
|
142
|
+
// `http:response` counterpart fires before every exit below.
|
|
143
|
+
ctx.events?.emit('http:request', {
|
|
144
|
+
id: correlationId,
|
|
145
|
+
method: reqData.method,
|
|
146
|
+
path: reqData.path,
|
|
147
|
+
})
|
|
138
148
|
// Wire the streaming backend so `ctx.response.sse()` can talk to
|
|
139
149
|
// the HyperServer NAPI. Falls back silently when no backend is
|
|
140
150
|
// available (mock server, websocket-only host) — the SSE helper
|
|
@@ -152,9 +162,7 @@ export function createHttpKernel(
|
|
|
152
162
|
throw new E_ROUTE_NOT_FOUND(reqData.method, reqData.path)
|
|
153
163
|
}
|
|
154
164
|
|
|
155
|
-
|
|
156
|
-
const cacheKey = `${match.route.method}:${match.route.path}`
|
|
157
|
-
let cached = pipelineCache.get(cacheKey)
|
|
165
|
+
let cached = pipelineCache.get(match.route)
|
|
158
166
|
|
|
159
167
|
if (!cached) {
|
|
160
168
|
// Resolve handler (once per route)
|
|
@@ -184,6 +192,21 @@ export function createHttpKernel(
|
|
|
184
192
|
permissions = [...permissions, ...meta.permissions]
|
|
185
193
|
}
|
|
186
194
|
|
|
195
|
+
// Resolve route validators by name (container token `validator:<name>`).
|
|
196
|
+
// A declared validator that isn't registered is a HARD error — never
|
|
197
|
+
// silently skip validation, that's a security footgun (a typo'd
|
|
198
|
+
// `.validate('craeteUser')` must fail loudly, not pass unvalidated).
|
|
199
|
+
const validators: RuntimeValidator[] = match.route.validators.map((name) => {
|
|
200
|
+
const token = `validator:${name}`
|
|
201
|
+
if (!config.container?.has(token)) {
|
|
202
|
+
throw new Error(
|
|
203
|
+
`[E_VALIDATOR_NOT_FOUND] Route validator '${name}' is not registered. ` +
|
|
204
|
+
`Bind it with container.singleton('${token}', () => schema({ ... })).`,
|
|
205
|
+
)
|
|
206
|
+
}
|
|
207
|
+
return config.container.resolve<RuntimeValidator>(token)
|
|
208
|
+
})
|
|
209
|
+
|
|
187
210
|
// Compile pipeline once
|
|
188
211
|
const chain = config.middleware.buildChain(
|
|
189
212
|
match.route.middleware,
|
|
@@ -191,11 +214,11 @@ export function createHttpKernel(
|
|
|
191
214
|
async (c) => {
|
|
192
215
|
await routeHandler(c)
|
|
193
216
|
},
|
|
194
|
-
{ guards, roles, permissions },
|
|
217
|
+
{ guards, roles, permissions, validators },
|
|
195
218
|
)
|
|
196
219
|
|
|
197
220
|
cached = { chain }
|
|
198
|
-
pipelineCache.set(
|
|
221
|
+
pipelineCache.set(match.route, cached)
|
|
199
222
|
}
|
|
200
223
|
|
|
201
224
|
// API versioning headers (per-request, cheap)
|
|
@@ -217,6 +240,12 @@ export function createHttpKernel(
|
|
|
217
240
|
const fullPipeline = compose([...serverMw, coreHandler])
|
|
218
241
|
await fullPipeline(ctx, async () => {})
|
|
219
242
|
|
|
243
|
+
ctx.events?.emit('http:response', {
|
|
244
|
+
id: correlationId,
|
|
245
|
+
method: reqData.method,
|
|
246
|
+
path: reqData.path,
|
|
247
|
+
status: ctx.response.getStatus(),
|
|
248
|
+
})
|
|
220
249
|
return serializeResponse(ctx)
|
|
221
250
|
} catch (error) {
|
|
222
251
|
// If the handler opened an SSE stream via `response.sse()` and
|
|
@@ -249,6 +278,12 @@ export function createHttpKernel(
|
|
|
249
278
|
error: error instanceof Error ? error.message : String(error),
|
|
250
279
|
})
|
|
251
280
|
|
|
281
|
+
ctx.events?.emit('http:response', {
|
|
282
|
+
id: correlationId,
|
|
283
|
+
method: reqData.method,
|
|
284
|
+
path: reqData.path,
|
|
285
|
+
status: ctx.response.getStatus(),
|
|
286
|
+
})
|
|
252
287
|
return serializeResponse(ctx)
|
|
253
288
|
}
|
|
254
289
|
}
|
package/src/Ignitor.ts
CHANGED
|
@@ -31,9 +31,9 @@ import type { AppContext, ProviderContract } from './Provider.js'
|
|
|
31
31
|
import { callProviderPhase } from './Provider.js'
|
|
32
32
|
import { Router } from './router/Router.js'
|
|
33
33
|
import { Server } from './server/Server.js'
|
|
34
|
-
import { setApp } from './services/app.js'
|
|
35
|
-
import { setRouter } from './services/router.js'
|
|
36
|
-
import { setServer } from './services/server.js'
|
|
34
|
+
import { clearApp, setApp } from './services/app.js'
|
|
35
|
+
import { clearRouter, setRouter } from './services/router.js'
|
|
36
|
+
import { clearServer, setServer } from './services/server.js'
|
|
37
37
|
|
|
38
38
|
/** Application environment. */
|
|
39
39
|
export type AppEnvironment = 'web' | 'console' | 'test' | 'unknown'
|
|
@@ -63,10 +63,6 @@ export interface ReamrcConfig {
|
|
|
63
63
|
/** Auto-loaded files in each module directory. Default: ['routes'] */
|
|
64
64
|
autoload?: string[]
|
|
65
65
|
}
|
|
66
|
-
tests?: {
|
|
67
|
-
suites?: Array<{ name: string; files: string[]; timeout?: number }>
|
|
68
|
-
forceExit?: boolean
|
|
69
|
-
}
|
|
70
66
|
}
|
|
71
67
|
|
|
72
68
|
/** defineConfig helper — like AdonisJS defineConfig(). */
|
|
@@ -265,11 +261,33 @@ export class Ignitor {
|
|
|
265
261
|
// ─── Lifecycle ────────────────────────────────────────────
|
|
266
262
|
|
|
267
263
|
async start(): Promise<Ignitor> {
|
|
264
|
+
// Double-start guard: a second start() would re-run phaseRegister and
|
|
265
|
+
// instantiate + register every reamrc provider a second time.
|
|
266
|
+
if (this.phase !== 'created') {
|
|
267
|
+
throw new ReamError(
|
|
268
|
+
'IGNITOR_ALREADY_STARTED',
|
|
269
|
+
`start() called while in phase '${this.phase}' — an Ignitor boots once`,
|
|
270
|
+
{ hint: 'Create a new Ignitor instance instead of restarting this one.' },
|
|
271
|
+
)
|
|
272
|
+
}
|
|
268
273
|
this.#loadEnvironmentFiles()
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
274
|
+
try {
|
|
275
|
+
await this.phaseRegister()
|
|
276
|
+
await this.phaseBoot()
|
|
277
|
+
await this.phaseStart()
|
|
278
|
+
await this.phaseReady()
|
|
279
|
+
} catch (err) {
|
|
280
|
+
// A throw mid-boot (e.g. a provider ready() failing AFTER the HTTP port
|
|
281
|
+
// is bound) must release everything the partial boot opened — port,
|
|
282
|
+
// scheduler tickers, watchers — or the process hangs with leaked
|
|
283
|
+
// resources. Best-effort: the original boot error stays the one thrown.
|
|
284
|
+
try {
|
|
285
|
+
await this.stop()
|
|
286
|
+
} catch {
|
|
287
|
+
/* surface the boot error, not the rollback error */
|
|
288
|
+
}
|
|
289
|
+
throw err
|
|
290
|
+
}
|
|
273
291
|
return this
|
|
274
292
|
}
|
|
275
293
|
|
|
@@ -428,7 +446,13 @@ export class Ignitor {
|
|
|
428
446
|
})
|
|
429
447
|
|
|
430
448
|
const desiredPort = this.config.port ?? 3000
|
|
431
|
-
|
|
449
|
+
// Port-scan fallback (+1..+19) is a DEV convenience only. In production
|
|
450
|
+
// a silent drift to :3001 while the LB targets :3000 is an outage —
|
|
451
|
+
// bind the configured port and let EADDRINUSE fail loudly. The probe
|
|
452
|
+
// also has an inherent TOCTOU; acceptable in dev, not in prod.
|
|
453
|
+
const availablePort = this.app.inProduction
|
|
454
|
+
? desiredPort
|
|
455
|
+
: await findAvailablePort(desiredPort)
|
|
432
456
|
this._httpServer = this.config.serverFactory(availablePort)
|
|
433
457
|
this._httpServer.onRequest(kernel)
|
|
434
458
|
// Pre-resolve client IPs in Rust from the trusted-proxy CIDRs before
|
|
@@ -467,23 +491,30 @@ export class Ignitor {
|
|
|
467
491
|
.emit('app:ready', { environment: this.environment })
|
|
468
492
|
}
|
|
469
493
|
|
|
470
|
-
//
|
|
494
|
+
// Dev-mode change watcher. IMPORTANT: this does NOT attempt an in-process
|
|
495
|
+
// reload. The previous implementation cleared the router + service registry
|
|
496
|
+
// and re-invoked the reamrc preload thunks — but a dynamic import() of an
|
|
497
|
+
// already-loaded ESM module returns the CACHED module without re-executing
|
|
498
|
+
// its body (the thunk's specifier is opaque, so it cannot be cache-busted).
|
|
499
|
+
// The "reload" therefore destroyed every preload-registered route on the
|
|
500
|
+
// first file save and never restored them. Process-level restart is the
|
|
501
|
+
// reload mechanism (`ream dev` runs `tsx watch`, which restarts on change);
|
|
502
|
+
// this watcher only surfaces an informational event for hosts that embed
|
|
503
|
+
// the Ignitor without a supervisor. A future true HMR needs a loader-hook
|
|
504
|
+
// (hot-hook style) that can invalidate the ESM cache — plug it in here.
|
|
471
505
|
if (this.isDevMode()) {
|
|
472
506
|
const watchDirs = this.config.watchDirs ?? ['app', 'start']
|
|
473
507
|
this.hotReloadCleanup = startHotReload({
|
|
474
508
|
watchDirs,
|
|
475
|
-
onReload:
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
await preloadImport()
|
|
485
|
-
}
|
|
486
|
-
}
|
|
509
|
+
onReload: () => {
|
|
510
|
+
this.handleError({
|
|
511
|
+
type: 'system.info',
|
|
512
|
+
source: 'HotReload',
|
|
513
|
+
message:
|
|
514
|
+
'File change detected — a process restart is required to apply it (`ream dev` restarts automatically).',
|
|
515
|
+
severity: 'info',
|
|
516
|
+
timestamp: new Date().toISOString(),
|
|
517
|
+
} as ErrorEvent)
|
|
487
518
|
},
|
|
488
519
|
logger: {
|
|
489
520
|
info: (msg) =>
|
|
@@ -566,13 +597,43 @@ export class Ignitor {
|
|
|
566
597
|
}
|
|
567
598
|
}
|
|
568
599
|
|
|
569
|
-
/**
|
|
600
|
+
/**
|
|
601
|
+
* Graceful shutdown. Every step runs even when an earlier one throws — a
|
|
602
|
+
* failing `httpServer.close()` must not leave the error boundary installed,
|
|
603
|
+
* providers un-shutdown (open DB pools), or the locators bound. Errors are
|
|
604
|
+
* aggregated and rethrown at the end.
|
|
605
|
+
*/
|
|
570
606
|
async stop(): Promise<void> {
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
607
|
+
const errors: unknown[] = []
|
|
608
|
+
const attempt = async (step: () => void | Promise<void>): Promise<void> => {
|
|
609
|
+
try {
|
|
610
|
+
await step()
|
|
611
|
+
} catch (err) {
|
|
612
|
+
errors.push(err)
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
await attempt(() => {
|
|
617
|
+
if (this.hotReloadCleanup) this.hotReloadCleanup()
|
|
618
|
+
})
|
|
619
|
+
await attempt(async () => {
|
|
620
|
+
if (this._httpServer) await this._httpServer.close()
|
|
621
|
+
})
|
|
622
|
+
await attempt(() => this.errorBoundary.uninstall())
|
|
623
|
+
await attempt(() => this.app.shutdown())
|
|
624
|
+
|
|
625
|
+
// Release the process-wide service locators (ownership-guarded): a stopped
|
|
626
|
+
// app must not keep its container/router reachable through the module
|
|
627
|
+
// singletons, and must not clobber a newer Ignitor's bindings.
|
|
628
|
+
clearApp(this.app)
|
|
629
|
+
clearRouter(this.router)
|
|
630
|
+
clearServer(this.server)
|
|
631
|
+
|
|
575
632
|
this.phase = 'shutdown'
|
|
633
|
+
if (errors.length === 1) throw errors[0]
|
|
634
|
+
if (errors.length > 1) {
|
|
635
|
+
throw new AggregateError(errors, 'Ignitor.stop() completed with errors')
|
|
636
|
+
}
|
|
576
637
|
}
|
|
577
638
|
|
|
578
639
|
// ─── Accessors ────────────────────────────────────────────
|
|
@@ -593,9 +654,12 @@ export class Ignitor {
|
|
|
593
654
|
return this.server
|
|
594
655
|
}
|
|
595
656
|
|
|
596
|
-
/**
|
|
657
|
+
/**
|
|
658
|
+
* Get the kernel callback (for serverless / testing). Memoized — building a
|
|
659
|
+
* kernel per call would discard its compiled-pipeline cache every time.
|
|
660
|
+
*/
|
|
597
661
|
getKernel(): (request: HttpKernelRequest) => Promise<HttpKernelResponse> {
|
|
598
|
-
|
|
662
|
+
this.#kernel ??= createHttpKernel({
|
|
599
663
|
router: this.router,
|
|
600
664
|
middleware: this.middleware,
|
|
601
665
|
container: this.app.container,
|
|
@@ -604,8 +668,11 @@ export class Ignitor {
|
|
|
604
668
|
serverMiddleware: this.server.getServerMiddleware(),
|
|
605
669
|
routerMiddleware: this.router.getRouterMiddleware(),
|
|
606
670
|
})
|
|
671
|
+
return this.#kernel
|
|
607
672
|
}
|
|
608
673
|
|
|
674
|
+
#kernel?: (request: HttpKernelRequest) => Promise<HttpKernelResponse>
|
|
675
|
+
|
|
609
676
|
isDevMode(): boolean {
|
|
610
677
|
return this.app.inDev
|
|
611
678
|
}
|
|
@@ -676,8 +743,13 @@ export class ConsoleKernel {
|
|
|
676
743
|
}
|
|
677
744
|
|
|
678
745
|
this.ignitor.getApp().container.singleton('console', () => runner)
|
|
679
|
-
|
|
680
|
-
|
|
746
|
+
try {
|
|
747
|
+
await runner.handle(argv)
|
|
748
|
+
} finally {
|
|
749
|
+
// A throwing command must still release the Ignitor's resources
|
|
750
|
+
// (scheduler tickers, watchers) — otherwise the CLI process hangs.
|
|
751
|
+
await this.ignitor.stop()
|
|
752
|
+
}
|
|
681
753
|
}
|
|
682
754
|
}
|
|
683
755
|
|