@c9up/ream 0.1.7 → 0.1.9

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.
Files changed (162) hide show
  1. package/dist/Application.d.ts +9 -1
  2. package/dist/Application.d.ts.map +1 -1
  3. package/dist/Application.js +35 -5
  4. package/dist/Application.js.map +1 -1
  5. package/dist/GracefulShutdown.d.ts.map +1 -1
  6. package/dist/GracefulShutdown.js +13 -7
  7. package/dist/GracefulShutdown.js.map +1 -1
  8. package/dist/HttpKernel.d.ts.map +1 -1
  9. package/dist/HttpKernel.js +43 -14
  10. package/dist/HttpKernel.js.map +1 -1
  11. package/dist/Ignitor.d.ts +10 -10
  12. package/dist/Ignitor.d.ts.map +1 -1
  13. package/dist/Ignitor.js +104 -32
  14. package/dist/Ignitor.js.map +1 -1
  15. package/dist/bodyparser/BodyParserMiddleware.d.ts +3 -0
  16. package/dist/bodyparser/BodyParserMiddleware.d.ts.map +1 -1
  17. package/dist/bodyparser/BodyParserMiddleware.js +32 -16
  18. package/dist/bodyparser/BodyParserMiddleware.js.map +1 -1
  19. package/dist/bodyparser/parseSize.d.ts +2 -1
  20. package/dist/bodyparser/parseSize.d.ts.map +1 -1
  21. package/dist/bodyparser/parseSize.js +2 -1
  22. package/dist/bodyparser/parseSize.js.map +1 -1
  23. package/dist/container/Container.d.ts.map +1 -1
  24. package/dist/container/Container.js +39 -9
  25. package/dist/container/Container.js.map +1 -1
  26. package/dist/decorators/Service.d.ts +4 -6
  27. package/dist/decorators/Service.d.ts.map +1 -1
  28. package/dist/decorators/Service.js +0 -1
  29. package/dist/decorators/Service.js.map +1 -1
  30. package/dist/events/Emitter.d.ts +16 -6
  31. package/dist/events/Emitter.d.ts.map +1 -1
  32. package/dist/events/Emitter.js +32 -25
  33. package/dist/events/Emitter.js.map +1 -1
  34. package/dist/events/EventsProvider.d.ts +1 -0
  35. package/dist/events/EventsProvider.d.ts.map +1 -1
  36. package/dist/events/EventsProvider.js +6 -4
  37. package/dist/events/EventsProvider.js.map +1 -1
  38. package/dist/graphql/GraphQLEngine.d.ts +16 -0
  39. package/dist/graphql/GraphQLEngine.d.ts.map +1 -1
  40. package/dist/graphql/GraphQLEngine.js +122 -4
  41. package/dist/graphql/GraphQLEngine.js.map +1 -1
  42. package/dist/graphql/GraphQLProvider.d.ts.map +1 -1
  43. package/dist/graphql/GraphQLProvider.js +13 -2
  44. package/dist/graphql/GraphQLProvider.js.map +1 -1
  45. package/dist/http/HttpContext.d.ts +27 -1
  46. package/dist/http/HttpContext.d.ts.map +1 -1
  47. package/dist/http/HttpContext.js +20 -1
  48. package/dist/http/HttpContext.js.map +1 -1
  49. package/dist/http/RedirectBuilder.d.ts +5 -1
  50. package/dist/http/RedirectBuilder.d.ts.map +1 -1
  51. package/dist/http/RedirectBuilder.js +26 -3
  52. package/dist/http/RedirectBuilder.js.map +1 -1
  53. package/dist/http/Request.d.ts +13 -0
  54. package/dist/http/Request.d.ts.map +1 -1
  55. package/dist/http/Request.js +18 -0
  56. package/dist/http/Request.js.map +1 -1
  57. package/dist/index.d.ts +1 -1
  58. package/dist/index.d.ts.map +1 -1
  59. package/dist/middleware/Pipeline.d.ts +13 -0
  60. package/dist/middleware/Pipeline.d.ts.map +1 -1
  61. package/dist/middleware/Pipeline.js +43 -7
  62. package/dist/middleware/Pipeline.js.map +1 -1
  63. package/dist/router/Router.d.ts +21 -2
  64. package/dist/router/Router.d.ts.map +1 -1
  65. package/dist/router/Router.js +53 -8
  66. package/dist/router/Router.js.map +1 -1
  67. package/dist/rpc/RpcProvider.d.ts.map +1 -1
  68. package/dist/rpc/RpcProvider.js +11 -2
  69. package/dist/rpc/RpcProvider.js.map +1 -1
  70. package/dist/rpc/RpcRouter.d.ts +11 -3
  71. package/dist/rpc/RpcRouter.d.ts.map +1 -1
  72. package/dist/rpc/RpcRouter.js +92 -8
  73. package/dist/rpc/RpcRouter.js.map +1 -1
  74. package/dist/scheduler/ScheduleProvider.d.ts.map +1 -1
  75. package/dist/scheduler/ScheduleProvider.js +10 -0
  76. package/dist/scheduler/ScheduleProvider.js.map +1 -1
  77. package/dist/scheduler/locks/MemoryLockBackend.d.ts +0 -1
  78. package/dist/scheduler/locks/MemoryLockBackend.d.ts.map +1 -1
  79. package/dist/scheduler/locks/MemoryLockBackend.js +0 -1
  80. package/dist/scheduler/locks/MemoryLockBackend.js.map +1 -1
  81. package/dist/services/app.d.ts +6 -0
  82. package/dist/services/app.d.ts.map +1 -1
  83. package/dist/services/app.js +9 -0
  84. package/dist/services/app.js.map +1 -1
  85. package/dist/services/router.d.ts +5 -0
  86. package/dist/services/router.d.ts.map +1 -1
  87. package/dist/services/router.js +8 -0
  88. package/dist/services/router.js.map +1 -1
  89. package/dist/services/server.d.ts +5 -0
  90. package/dist/services/server.d.ts.map +1 -1
  91. package/dist/services/server.js +8 -0
  92. package/dist/services/server.js.map +1 -1
  93. package/dist/session/SessionMiddleware.d.ts.map +1 -1
  94. package/dist/session/SessionMiddleware.js +4 -0
  95. package/dist/session/SessionMiddleware.js.map +1 -1
  96. package/dist/session/drivers/MemoryDriver.d.ts +1 -1
  97. package/dist/session/drivers/MemoryDriver.d.ts.map +1 -1
  98. package/dist/session/drivers/MemoryDriver.js +14 -6
  99. package/dist/session/drivers/MemoryDriver.js.map +1 -1
  100. package/dist/testing/TestClient.d.ts +11 -5
  101. package/dist/testing/TestClient.d.ts.map +1 -1
  102. package/dist/testing/TestClient.js +9 -4
  103. package/dist/testing/TestClient.js.map +1 -1
  104. package/events.darwin-arm64.node +0 -0
  105. package/events.darwin-x64.node +0 -0
  106. package/events.linux-arm64-gnu.node +0 -0
  107. package/events.linux-x64-gnu.node +0 -0
  108. package/events.win32-x64-msvc.node +0 -0
  109. package/index.darwin-arm64.node +0 -0
  110. package/index.darwin-x64.node +0 -0
  111. package/index.linux-arm64-gnu.node +0 -0
  112. package/index.linux-x64-gnu.node +0 -0
  113. package/index.win32-x64-msvc.node +0 -0
  114. package/package.json +1 -1
  115. package/scheduler.darwin-arm64.node +0 -0
  116. package/scheduler.darwin-x64.node +0 -0
  117. package/scheduler.linux-arm64-gnu.node +0 -0
  118. package/scheduler.linux-x64-gnu.node +0 -0
  119. package/scheduler.win32-x64-msvc.node +0 -0
  120. package/src/Application.ts +36 -5
  121. package/src/GracefulShutdown.ts +15 -7
  122. package/src/HttpKernel.ts +52 -17
  123. package/src/Ignitor.ts +106 -34
  124. package/src/bodyparser/BodyParserMiddleware.ts +43 -16
  125. package/src/bodyparser/parseSize.ts +2 -1
  126. package/src/container/Container.ts +42 -12
  127. package/src/decorators/Service.ts +4 -6
  128. package/src/events/Emitter.ts +36 -28
  129. package/src/events/EventsProvider.ts +6 -4
  130. package/src/graphql/GraphQLEngine.ts +139 -3
  131. package/src/graphql/GraphQLProvider.ts +17 -2
  132. package/src/http/HttpContext.ts +38 -1
  133. package/src/http/RedirectBuilder.ts +23 -3
  134. package/src/http/Request.ts +20 -0
  135. package/src/index.ts +1 -1
  136. package/src/middleware/Pipeline.ts +61 -8
  137. package/src/router/Router.ts +53 -8
  138. package/src/rpc/RpcProvider.ts +14 -2
  139. package/src/rpc/RpcRouter.ts +115 -11
  140. package/src/scheduler/ScheduleProvider.ts +10 -0
  141. package/src/scheduler/locks/MemoryLockBackend.ts +0 -2
  142. package/src/services/app.ts +9 -0
  143. package/src/services/router.ts +8 -0
  144. package/src/services/server.ts +8 -0
  145. package/src/session/SessionMiddleware.ts +6 -0
  146. package/src/session/drivers/MemoryDriver.ts +14 -6
  147. package/src/testing/TestClient.ts +18 -7
  148. package/dist/server/HyperServer.d.ts +0 -64
  149. package/dist/server/HyperServer.d.ts.map +0 -1
  150. package/dist/server/HyperServer.js +0 -54
  151. package/dist/server/HyperServer.js.map +0 -1
  152. package/dist/storage/S3Driver.d.ts +0 -27
  153. package/dist/storage/S3Driver.d.ts.map +0 -1
  154. package/dist/storage/S3Driver.js +0 -135
  155. package/dist/storage/S3Driver.js.map +0 -1
  156. package/dist/storage/StorageManager.d.ts +0 -31
  157. package/dist/storage/StorageManager.d.ts.map +0 -1
  158. package/dist/storage/StorageManager.js +0 -120
  159. package/dist/storage/StorageManager.js.map +0 -1
  160. package/src/server/HyperServer.ts +0 -121
  161. package/src/storage/S3Driver.ts +0 -171
  162. package/src/storage/StorageManager.ts +0 -142
@@ -1 +1 @@
1
- {"version":3,"file":"TestClient.d.ts","sourceRoot":"","sources":["../../src/testing/TestClient.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TestClient.d.ts","sourceRoot":"","sources":["../../src/testing/TestClient.ts"],"names":[],"mappings":"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"}
@@ -53,9 +53,9 @@ export class TestClient {
53
53
  this.#headers[name.toLowerCase()] = value;
54
54
  return this;
55
55
  }
56
- /** GET request. */
56
+ /** GET request. Returns a chainable, awaitable builder (await sends it). */
57
57
  get(path) {
58
- return this.request('GET', path).send();
58
+ return this.request('GET', path);
59
59
  }
60
60
  /** POST request. */
61
61
  post(path) {
@@ -69,9 +69,9 @@ export class TestClient {
69
69
  patch(path) {
70
70
  return this.request('PATCH', path);
71
71
  }
72
- /** DELETE request. */
72
+ /** DELETE request. Returns a chainable, awaitable builder (await sends it). */
73
73
  delete(path) {
74
- return this.request('DELETE', path).send();
74
+ return this.request('DELETE', path);
75
75
  }
76
76
  /**
77
77
  * Build a request with the rich fluent surface: chained assertions
@@ -114,6 +114,11 @@ export class TestClient {
114
114
  }
115
115
  return sendRequest(this.#port, method, path, headers, bodyContent);
116
116
  },
117
+ // Thenable: `await client.get('/x')` (or any builder) sends the request,
118
+ // matching AdonisJS/japa's api-client ergonomics. The `then` IS the public
119
+ // contract here — awaiting the builder is the documented way to send.
120
+ // biome-ignore lint/suspicious/noThenProperty: thenable request builder is the intended API (AdonisJS/japa parity) — `await client.get(path)` sends
121
+ then: (onfulfilled, onrejected) => builder.send().then(onfulfilled, onrejected),
117
122
  };
118
123
  return builder;
119
124
  }
@@ -1 +1 @@
1
- {"version":3,"file":"TestClient.js","sourceRoot":"","sources":["../../src/testing/TestClient.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TestClient.js","sourceRoot":"","sources":["../../src/testing/TestClient.ts"],"names":[],"mappings":"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"}
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@c9up/ream",
3
- "version": "0.1.7",
3
+ "version": "0.1.9",
4
4
  "description": "Ream — Rust-powered Node.js application framework",
5
5
  "license": "MIT",
6
6
  "type": "module",
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -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
- process.on(signal, callback)
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
- /** Shutdown all providers in reverse order. */
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
- // Run shutdown hooks
165
+ const errors: unknown[] = []
166
+
155
167
  for (const hook of this._shutdownHooks) {
156
- await hook()
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
- await callProviderPhase(provider, 'shutdown')
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. */
@@ -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 onSigterm = () => {
59
- shutdown().catch((err) => {
60
- logger.error(`Fatal: ${err}`)
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 { MiddlewareFunction, MiddlewareRegistry } from './middleware/Pipeline.js'
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 route key (PERF-7)
77
- // Cleared when router.clear() is called (hot-reload).
78
- const pipelineCache = new Map<string, { chain: MiddlewareFunction }>()
79
-
80
- // Hook into router clear for cache invalidation
81
- const origClear = config.router.clear.bind(config.router)
82
- config.router.clear = () => {
83
- origClear()
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
- // Cache key: method + path pattern (static per route definition)
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(cacheKey, cached)
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
- await this.phaseRegister()
270
- await this.phaseBoot()
271
- await this.phaseStart()
272
- await this.phaseReady()
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
- const availablePort = await findAvailablePort(desiredPort)
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
- // Hot-reload in dev mode
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: async () => {
476
- const { clearServiceRegistry } = await import('./decorators/Service.js')
477
- clearServiceRegistry()
478
- this.router.clear()
479
- if (this.inlineRoutes) this.inlineRoutes(this.router)
480
- if (this.reamrc?.preloads) {
481
- for (const preloadEntry of this.reamrc.preloads) {
482
- const preloadImport =
483
- typeof preloadEntry === 'function' ? preloadEntry : preloadEntry.file
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
- /** Graceful shutdown. */
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
- if (this.hotReloadCleanup) this.hotReloadCleanup()
572
- if (this._httpServer) await this._httpServer.close()
573
- this.errorBoundary.uninstall()
574
- await this.app.shutdown()
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
- /** Get the kernel callback (for serverless / testing). */
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
- return createHttpKernel({
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
- await runner.handle(argv)
680
- await this.ignitor.stop()
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