@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
package/dist/Application.d.ts
CHANGED
|
@@ -16,6 +16,7 @@ import { ConfigStore } from './ConfigLoader.js';
|
|
|
16
16
|
import { Container } from './container/Container.js';
|
|
17
17
|
import type { AppContext, ProviderContract } from './Provider.js';
|
|
18
18
|
export declare class Application implements AppContext {
|
|
19
|
+
#private;
|
|
19
20
|
readonly container: Container;
|
|
20
21
|
readonly config: ConfigStore;
|
|
21
22
|
private providers;
|
|
@@ -45,6 +46,9 @@ export declare class Application implements AppContext {
|
|
|
45
46
|
/**
|
|
46
47
|
* Listen for a process signal.
|
|
47
48
|
* Like AdonisJS app.listen('SIGTERM', () => app.terminate()).
|
|
49
|
+
* Tracked and removed on shutdown() — otherwise every boot/stop cycle leaks
|
|
50
|
+
* a process listener, and a real signal would fire the handlers of every
|
|
51
|
+
* previously stopped app instance.
|
|
48
52
|
*/
|
|
49
53
|
listen(signal: NodeJS.Signals, callback: () => void): void;
|
|
50
54
|
/**
|
|
@@ -61,7 +65,11 @@ export declare class Application implements AppContext {
|
|
|
61
65
|
register(provider: ProviderContract): void;
|
|
62
66
|
/** Boot all registered providers. Runs booting/booted hooks. */
|
|
63
67
|
boot(): Promise<void>;
|
|
64
|
-
/**
|
|
68
|
+
/**
|
|
69
|
+
* Shutdown all providers in reverse order. Each hook/provider shutdown is
|
|
70
|
+
* isolated: one throwing provider must not prevent the remaining providers
|
|
71
|
+
* from closing their resources (DB pools, queues). Errors are aggregated.
|
|
72
|
+
*/
|
|
65
73
|
shutdown(): Promise<void>;
|
|
66
74
|
/** Register a shutdown hook. */
|
|
67
75
|
onShutdown(callback: () => Promise<void> | void): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Application.d.ts","sourceRoot":"","sources":["../src/Application.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAGjE,qBAAa,WAAY,YAAW,UAAU
|
|
1
|
+
{"version":3,"file":"Application.d.ts","sourceRoot":"","sources":["../src/Application.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAGjE,qBAAa,WAAY,YAAW,UAAU;;IAC5C,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAA;IAC7B,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAA;IAC5B,OAAO,CAAC,SAAS,CAAyB;IAC1C,OAAO,CAAC,OAAO,CAAQ;IACvB,OAAO,CAAC,aAAa,CAAwC;IAC7D,OAAO,CAAC,YAAY,CAAwC;IAC5D,OAAO,CAAC,cAAc,CAAwC;;IAS9D,sCAAsC;IACtC,IAAI,YAAY,IAAI,OAAO,CAE1B;IAED,uCAAuC;IACvC,IAAI,KAAK,IAAI,OAAO,CAGnB;IAED,qCAAqC;IACrC,IAAI,MAAM,IAAI,OAAO,CAEpB;IAED,+BAA+B;IAC/B,IAAI,YAAY,IAAI,OAAO,CAE1B;IAID;;;OAGG;IACH,OAAO,CAAC,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI;IAInD;;;OAGG;IACH,MAAM,CAAC,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI;IAsBlD;;;;;;OAMG;IACH,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI;IAK1D;;;OAGG;IACH,QAAQ,CAAC,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI;IAMhF;;;OAGG;IACG,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAOhC,oCAAoC;IACpC,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,GAAG,IAAI;IAO1C,gEAAgE;IAC1D,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAuB3B;;;;OAIG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAgC/B,gCAAgC;IAChC,UAAU,CAAC,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI;IAItD,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAED,IAAI,aAAa,IAAI,MAAM,CAE1B;CACF"}
|
package/dist/Application.js
CHANGED
|
@@ -74,11 +74,17 @@ export class Application {
|
|
|
74
74
|
this._bootedHooks.push(callback);
|
|
75
75
|
}
|
|
76
76
|
// ─── Signal handling ──────────────────────────────────────
|
|
77
|
+
/** Signal handlers installed via listen()/listenIf(), removed on shutdown. */
|
|
78
|
+
#signalHandlers = [];
|
|
77
79
|
/**
|
|
78
80
|
* Listen for a process signal.
|
|
79
81
|
* Like AdonisJS app.listen('SIGTERM', () => app.terminate()).
|
|
82
|
+
* Tracked and removed on shutdown() — otherwise every boot/stop cycle leaks
|
|
83
|
+
* a process listener, and a real signal would fire the handlers of every
|
|
84
|
+
* previously stopped app instance.
|
|
80
85
|
*/
|
|
81
86
|
listen(signal, callback) {
|
|
87
|
+
this.#signalHandlers.push([signal, callback]);
|
|
82
88
|
process.on(signal, callback);
|
|
83
89
|
}
|
|
84
90
|
/**
|
|
@@ -87,7 +93,7 @@ export class Application {
|
|
|
87
93
|
*/
|
|
88
94
|
listenIf(condition, signal, callback) {
|
|
89
95
|
if (condition) {
|
|
90
|
-
|
|
96
|
+
this.listen(signal, callback);
|
|
91
97
|
}
|
|
92
98
|
}
|
|
93
99
|
/**
|
|
@@ -126,16 +132,40 @@ export class Application {
|
|
|
126
132
|
await hook();
|
|
127
133
|
}
|
|
128
134
|
}
|
|
129
|
-
/**
|
|
135
|
+
/**
|
|
136
|
+
* Shutdown all providers in reverse order. Each hook/provider shutdown is
|
|
137
|
+
* isolated: one throwing provider must not prevent the remaining providers
|
|
138
|
+
* from closing their resources (DB pools, queues). Errors are aggregated.
|
|
139
|
+
*/
|
|
130
140
|
async shutdown() {
|
|
131
|
-
|
|
141
|
+
const errors = [];
|
|
132
142
|
for (const hook of this._shutdownHooks) {
|
|
133
|
-
|
|
143
|
+
try {
|
|
144
|
+
await hook();
|
|
145
|
+
}
|
|
146
|
+
catch (err) {
|
|
147
|
+
errors.push(err);
|
|
148
|
+
}
|
|
134
149
|
}
|
|
135
150
|
for (const provider of [...this.providers].reverse()) {
|
|
136
|
-
|
|
151
|
+
try {
|
|
152
|
+
await callProviderPhase(provider, 'shutdown');
|
|
153
|
+
}
|
|
154
|
+
catch (err) {
|
|
155
|
+
errors.push(err);
|
|
156
|
+
}
|
|
137
157
|
}
|
|
158
|
+
// Remove the process signal handlers this app installed.
|
|
159
|
+
for (const [signal, callback] of this.#signalHandlers) {
|
|
160
|
+
process.off(signal, callback);
|
|
161
|
+
}
|
|
162
|
+
this.#signalHandlers = [];
|
|
138
163
|
this._booted = false;
|
|
164
|
+
if (errors.length === 1)
|
|
165
|
+
throw errors[0];
|
|
166
|
+
if (errors.length > 1) {
|
|
167
|
+
throw new AggregateError(errors, 'Application.shutdown() completed with errors');
|
|
168
|
+
}
|
|
139
169
|
}
|
|
140
170
|
/** Register a shutdown hook. */
|
|
141
171
|
onShutdown(callback) {
|
package/dist/Application.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Application.js","sourceRoot":"","sources":["../src/Application.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AAEpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AAEjD,MAAM,OAAO,WAAW;IACb,SAAS,CAAW;IACpB,MAAM,CAAa;IACpB,SAAS,GAAuB,EAAE,CAAA;IAClC,OAAO,GAAG,KAAK,CAAA;IACf,aAAa,GAAsC,EAAE,CAAA;IACrD,YAAY,GAAsC,EAAE,CAAA;IACpD,cAAc,GAAsC,EAAE,CAAA;IAE9D;QACE,IAAI,CAAC,SAAS,GAAG,IAAI,SAAS,EAAE,CAAA;QAChC,IAAI,CAAC,MAAM,GAAG,IAAI,WAAW,EAAE,CAAA;IACjC,CAAC;IAED,6DAA6D;IAE7D,sCAAsC;IACtC,IAAI,YAAY;QACd,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,CAAA;IAC9C,CAAC;IAED,uCAAuC;IACvC,IAAI,KAAK;QACP,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAA;QAChC,OAAO,GAAG,KAAK,YAAY,IAAI,GAAG,KAAK,MAAM,CAAA;IAC/C,CAAC;IAED,qCAAqC;IACrC,IAAI,MAAM;QACR,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,MAAM,CAAA;IACxC,CAAC;IAED,+BAA+B;IAC/B,IAAI,YAAY;QACd,OAAO,UAAU,IAAI,OAAO,CAAC,GAAG,IAAI,OAAO,IAAI,OAAO,CAAC,GAAG,CAAA;IAC5D,CAAC;IAED,6DAA6D;IAE7D;;;OAGG;IACH,OAAO,CAAC,QAAoC;QAC1C,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;IACnC,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,QAAoC;QACzC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,iEAAiE;YACjE,6DAA6D;YAC7D,4DAA4D;YAC5D,iEAAiE;YACjE,+BAA+B;YAC/B,OAAO,CAAC,OAAO,EAAE;iBACd,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC;iBACtB,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;gBACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,mCAAmC,GAAG,IAAI,CAAC,CAAA;YAClE,CAAC,CAAC,CAAA;YACJ,OAAM;QACR,CAAC;QACD,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;IAClC,CAAC;IAED,6DAA6D;IAE7D
|
|
1
|
+
{"version":3,"file":"Application.js","sourceRoot":"","sources":["../src/Application.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GracefulShutdown.d.ts","sourceRoot":"","sources":["../src/GracefulShutdown.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,WAAW,eAAe;IAC9B,6DAA6D;IAC7D,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,2CAA2C;IAC3C,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAC/B,uBAAuB;IACvB,MAAM,CAAC,EAAE;QAAE,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;QAAC,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;KAAE,CAAA;CACvE;AAED,MAAM,WAAW,cAAc;IAC7B,+CAA+C;IAC/C,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAC5B,qDAAqD;IACrD,OAAO,EAAE,MAAM,IAAI,CAAA;CACpB;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,eAAe,GAAG,cAAc,
|
|
1
|
+
{"version":3,"file":"GracefulShutdown.d.ts","sourceRoot":"","sources":["../src/GracefulShutdown.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,WAAW,eAAe;IAC9B,6DAA6D;IAC7D,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,2CAA2C;IAC3C,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAC/B,uBAAuB;IACvB,MAAM,CAAC,EAAE;QAAE,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;QAAC,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;KAAE,CAAA;CACvE;AAED,MAAM,WAAW,cAAc;IAC7B,+CAA+C;IAC/C,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAC5B,qDAAqD;IACrD,OAAO,EAAE,MAAM,IAAI,CAAA;CACpB;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,eAAe,GAAG,cAAc,CA6DhF"}
|
package/dist/GracefulShutdown.js
CHANGED
|
@@ -11,17 +11,21 @@ export function installGracefulShutdown(options) {
|
|
|
11
11
|
const drainTimeout = options.drainTimeout ?? 30_000;
|
|
12
12
|
const logger = options.logger ?? { info: () => { }, error: () => { } };
|
|
13
13
|
let shutdownInProgress = false;
|
|
14
|
+
let hadError = false;
|
|
14
15
|
const shutdown = async () => {
|
|
15
16
|
if (shutdownInProgress)
|
|
16
17
|
return;
|
|
17
18
|
shutdownInProgress = true;
|
|
18
19
|
logger.info('Graceful shutdown initiated...');
|
|
20
|
+
let timedOut = false;
|
|
19
21
|
let timeoutHandle;
|
|
20
22
|
const drainPromise = options.onShutdown().catch((err) => {
|
|
23
|
+
hadError = true;
|
|
21
24
|
logger.error(`Shutdown error: ${err instanceof Error ? err.message : String(err)}`);
|
|
22
25
|
});
|
|
23
26
|
const timeoutPromise = new Promise((resolve) => {
|
|
24
27
|
timeoutHandle = setTimeout(() => {
|
|
28
|
+
timedOut = true;
|
|
25
29
|
logger.error(`Drain timeout exceeded (${drainTimeout}ms) — forcing shutdown`);
|
|
26
30
|
resolve();
|
|
27
31
|
}, drainTimeout);
|
|
@@ -30,20 +34,22 @@ export function installGracefulShutdown(options) {
|
|
|
30
34
|
if (timeoutHandle)
|
|
31
35
|
clearTimeout(timeoutHandle);
|
|
32
36
|
logger.info('Shutdown complete');
|
|
33
|
-
process.exit(0);
|
|
37
|
+
process.exit(hadError || timedOut ? 1 : 0);
|
|
34
38
|
};
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
39
|
+
const handleSignal = () => {
|
|
40
|
+
if (shutdownInProgress) {
|
|
41
|
+
// Second signal while draining — escalate immediately.
|
|
42
|
+
logger.error('Forced exit: second signal received during shutdown');
|
|
38
43
|
process.exit(1);
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
const onSigint = () => {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
42
46
|
shutdown().catch((err) => {
|
|
43
47
|
logger.error(`Fatal: ${err}`);
|
|
44
48
|
process.exit(1);
|
|
45
49
|
});
|
|
46
50
|
};
|
|
51
|
+
const onSigterm = handleSignal;
|
|
52
|
+
const onSigint = handleSignal;
|
|
47
53
|
process.on('SIGTERM', onSigterm);
|
|
48
54
|
process.on('SIGINT', onSigint);
|
|
49
55
|
const cleanup = () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GracefulShutdown.js","sourceRoot":"","sources":["../src/GracefulShutdown.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAkBH;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CAAC,OAAwB;IAC9D,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,MAAM,CAAA;IACnD,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,GAAE,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,GAAE,CAAC,EAAE,CAAA;IACpE,IAAI,kBAAkB,GAAG,KAAK,CAAA;IAE9B,MAAM,QAAQ,GAAG,KAAK,IAAI,EAAE;QAC1B,IAAI,kBAAkB;YAAE,OAAM;QAC9B,kBAAkB,GAAG,IAAI,CAAA;QAEzB,MAAM,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAA;QAE7C,IAAI,aAAwD,CAAA;QAE5D,MAAM,YAAY,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;YACtD,MAAM,CAAC,KAAK,CAAC,mBAAmB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QACrF,CAAC,CAAC,CAAA;QAEF,MAAM,cAAc,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;YACnD,aAAa,GAAG,UAAU,CAAC,GAAG,EAAE;gBAC9B,MAAM,CAAC,KAAK,CAAC,2BAA2B,YAAY,wBAAwB,CAAC,CAAA;gBAC7E,OAAO,EAAE,CAAA;YACX,CAAC,EAAE,YAAY,CAAC,CAAA;QAClB,CAAC,CAAC,CAAA;QAEF,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC,CAAA;QAClD,IAAI,aAAa;YAAE,YAAY,CAAC,aAAa,CAAC,CAAA;QAE9C,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAA;QAChC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"GracefulShutdown.js","sourceRoot":"","sources":["../src/GracefulShutdown.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAkBH;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CAAC,OAAwB;IAC9D,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,MAAM,CAAA;IACnD,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,GAAE,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,GAAE,CAAC,EAAE,CAAA;IACpE,IAAI,kBAAkB,GAAG,KAAK,CAAA;IAE9B,IAAI,QAAQ,GAAG,KAAK,CAAA;IAEpB,MAAM,QAAQ,GAAG,KAAK,IAAI,EAAE;QAC1B,IAAI,kBAAkB;YAAE,OAAM;QAC9B,kBAAkB,GAAG,IAAI,CAAA;QAEzB,MAAM,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAA;QAE7C,IAAI,QAAQ,GAAG,KAAK,CAAA;QACpB,IAAI,aAAwD,CAAA;QAE5D,MAAM,YAAY,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;YACtD,QAAQ,GAAG,IAAI,CAAA;YACf,MAAM,CAAC,KAAK,CAAC,mBAAmB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QACrF,CAAC,CAAC,CAAA;QAEF,MAAM,cAAc,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;YACnD,aAAa,GAAG,UAAU,CAAC,GAAG,EAAE;gBAC9B,QAAQ,GAAG,IAAI,CAAA;gBACf,MAAM,CAAC,KAAK,CAAC,2BAA2B,YAAY,wBAAwB,CAAC,CAAA;gBAC7E,OAAO,EAAE,CAAA;YACX,CAAC,EAAE,YAAY,CAAC,CAAA;QAClB,CAAC,CAAC,CAAA;QAEF,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC,CAAA;QAClD,IAAI,aAAa;YAAE,YAAY,CAAC,aAAa,CAAC,CAAA;QAE9C,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAA;QAChC,OAAO,CAAC,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IAC5C,CAAC,CAAA;IAED,MAAM,YAAY,GAAG,GAAG,EAAE;QACxB,IAAI,kBAAkB,EAAE,CAAC;YACvB,uDAAuD;YACvD,MAAM,CAAC,KAAK,CAAC,qDAAqD,CAAC,CAAA;YACnE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YACf,OAAM;QACR,CAAC;QACD,QAAQ,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;YACvB,MAAM,CAAC,KAAK,CAAC,UAAU,GAAG,EAAE,CAAC,CAAA;YAC7B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACjB,CAAC,CAAC,CAAA;IACJ,CAAC,CAAA;IAED,MAAM,SAAS,GAAG,YAAY,CAAA;IAC9B,MAAM,QAAQ,GAAG,YAAY,CAAA;IAE7B,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC,CAAA;IAChC,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAA;IAE9B,MAAM,OAAO,GAAG,GAAG,EAAE;QACnB,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,SAAS,CAAC,CAAA;QACjC,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAA;IACjC,CAAC,CAAA;IAED,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAA;AACvC,CAAC"}
|
package/dist/HttpKernel.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HttpKernel.d.ts","sourceRoot":"","sources":["../src/HttpKernel.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AAEzD,OAAO,EAAqB,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AACzE,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AACnD,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"HttpKernel.d.ts","sourceRoot":"","sources":["../src/HttpKernel.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AAEzD,OAAO,EAAqB,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AACzE,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AACnD,OAAO,KAAK,EACV,kBAAkB,EAClB,kBAAkB,EAEnB,MAAM,0BAA0B,CAAA;AAEjC,OAAO,KAAK,EAAmB,MAAM,EAAE,MAAM,oBAAoB,CAAA;AACjE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAA;AAE9C,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,EAAE,kBAAkB,CAAA;IAC9B,SAAS,CAAC,EAAE,SAAS,CAAA;IACrB,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;IACnC,gBAAgB,CAAC,EAAE,kBAAkB,EAAE,CAAA;IACvC,gBAAgB,CAAC,EAAE,kBAAkB,EAAE,CAAA;IACvC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,WAAW,KAAK,IAAI,CAAA;IACpD,KAAK,CAAC,EAAE,OAAO,CAAA;IACf;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,OAAO,qBAAqB,EAAE,aAAa,GAAG,SAAS,CAAA;CAC9E;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,IAAI,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,IAAI,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,YAAY,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAA;IAChC,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,gBAAgB,GACvB,CAAC,OAAO,EAAE,iBAAiB,KAAK,OAAO,CAAC,kBAAkB,CAAC,CAwN7D"}
|
package/dist/HttpKernel.js
CHANGED
|
@@ -17,15 +17,14 @@ export function createHttpKernel(config) {
|
|
|
17
17
|
const handler = config.exceptionHandler ?? new ExceptionHandler(config.debug === true);
|
|
18
18
|
const serverMw = config.serverMiddleware ?? [];
|
|
19
19
|
const routerMw = config.routerMiddleware ?? [];
|
|
20
|
-
// Pipeline cache: compiled middleware chain per
|
|
21
|
-
//
|
|
22
|
-
|
|
23
|
-
//
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
};
|
|
20
|
+
// Pipeline cache: compiled middleware chain per ROUTE OBJECT (PERF-7).
|
|
21
|
+
// Keyed by route identity, not `method:path` — two routes sharing a path but
|
|
22
|
+
// differing by `domain` would otherwise collide and serve the first-warmed
|
|
23
|
+
// handler for both. WeakMap also makes hot-reload invalidation automatic:
|
|
24
|
+
// router.clear() drops the route objects, their chains become unreachable
|
|
25
|
+
// and are GC'd — no need to monkey-patch router.clear (which leaked a
|
|
26
|
+
// wrapper chain when createHttpKernel ran more than once on one router).
|
|
27
|
+
const pipelineCache = new WeakMap();
|
|
29
28
|
// Resolve the events emitter once, only when the app registered
|
|
30
29
|
// `EventsProvider`. Lazy + cached: the binding may not exist yet at kernel
|
|
31
30
|
// creation, and `has()` avoids loading the native bus for apps without events.
|
|
@@ -73,6 +72,14 @@ export function createHttpKernel(config) {
|
|
|
73
72
|
const ctx = new HttpContext(correlationId, reqData, match?.params ?? {}, routeInfo);
|
|
74
73
|
ctx.setRouteUrlResolver((name, params) => config.router.makeUrl(name, params));
|
|
75
74
|
ctx.events = resolveEvents();
|
|
75
|
+
// Core lifecycle event: a request entered the kernel. Fire-and-forget through
|
|
76
|
+
// the bus when events are wired (`?.` → zero cost when no provider). The
|
|
77
|
+
// `http:response` counterpart fires before every exit below.
|
|
78
|
+
ctx.events?.emit('http:request', {
|
|
79
|
+
id: correlationId,
|
|
80
|
+
method: reqData.method,
|
|
81
|
+
path: reqData.path,
|
|
82
|
+
});
|
|
76
83
|
// Wire the streaming backend so `ctx.response.sse()` can talk to
|
|
77
84
|
// the HyperServer NAPI. Falls back silently when no backend is
|
|
78
85
|
// available (mock server, websocket-only host) — the SSE helper
|
|
@@ -88,9 +95,7 @@ export function createHttpKernel(config) {
|
|
|
88
95
|
if (!match) {
|
|
89
96
|
throw new E_ROUTE_NOT_FOUND(reqData.method, reqData.path);
|
|
90
97
|
}
|
|
91
|
-
|
|
92
|
-
const cacheKey = `${match.route.method}:${match.route.path}`;
|
|
93
|
-
let cached = pipelineCache.get(cacheKey);
|
|
98
|
+
let cached = pipelineCache.get(match.route);
|
|
94
99
|
if (!cached) {
|
|
95
100
|
// Resolve handler (once per route)
|
|
96
101
|
let routeHandler;
|
|
@@ -113,12 +118,24 @@ export function createHttpKernel(config) {
|
|
|
113
118
|
roles = [...roles, ...meta.roles];
|
|
114
119
|
permissions = [...permissions, ...meta.permissions];
|
|
115
120
|
}
|
|
121
|
+
// Resolve route validators by name (container token `validator:<name>`).
|
|
122
|
+
// A declared validator that isn't registered is a HARD error — never
|
|
123
|
+
// silently skip validation, that's a security footgun (a typo'd
|
|
124
|
+
// `.validate('craeteUser')` must fail loudly, not pass unvalidated).
|
|
125
|
+
const validators = match.route.validators.map((name) => {
|
|
126
|
+
const token = `validator:${name}`;
|
|
127
|
+
if (!config.container?.has(token)) {
|
|
128
|
+
throw new Error(`[E_VALIDATOR_NOT_FOUND] Route validator '${name}' is not registered. ` +
|
|
129
|
+
`Bind it with container.singleton('${token}', () => schema({ ... })).`);
|
|
130
|
+
}
|
|
131
|
+
return config.container.resolve(token);
|
|
132
|
+
});
|
|
116
133
|
// Compile pipeline once
|
|
117
134
|
const chain = config.middleware.buildChain(match.route.middleware, [...routerMw, ...match.route.inlineMiddleware], async (c) => {
|
|
118
135
|
await routeHandler(c);
|
|
119
|
-
}, { guards, roles, permissions });
|
|
136
|
+
}, { guards, roles, permissions, validators });
|
|
120
137
|
cached = { chain };
|
|
121
|
-
pipelineCache.set(
|
|
138
|
+
pipelineCache.set(match.route, cached);
|
|
122
139
|
}
|
|
123
140
|
// API versioning headers (per-request, cheap)
|
|
124
141
|
if (match.route.version) {
|
|
@@ -136,6 +153,12 @@ export function createHttpKernel(config) {
|
|
|
136
153
|
// Compose: server middleware wraps everything (onion)
|
|
137
154
|
const fullPipeline = compose([...serverMw, coreHandler]);
|
|
138
155
|
await fullPipeline(ctx, async () => { });
|
|
156
|
+
ctx.events?.emit('http:response', {
|
|
157
|
+
id: correlationId,
|
|
158
|
+
method: reqData.method,
|
|
159
|
+
path: reqData.path,
|
|
160
|
+
status: ctx.response.getStatus(),
|
|
161
|
+
});
|
|
139
162
|
return serializeResponse(ctx);
|
|
140
163
|
}
|
|
141
164
|
catch (error) {
|
|
@@ -167,6 +190,12 @@ export function createHttpKernel(config) {
|
|
|
167
190
|
path: reqData.path,
|
|
168
191
|
error: error instanceof Error ? error.message : String(error),
|
|
169
192
|
});
|
|
193
|
+
ctx.events?.emit('http:response', {
|
|
194
|
+
id: correlationId,
|
|
195
|
+
method: reqData.method,
|
|
196
|
+
path: reqData.path,
|
|
197
|
+
status: ctx.response.getStatus(),
|
|
198
|
+
});
|
|
170
199
|
return serializeResponse(ctx);
|
|
171
200
|
}
|
|
172
201
|
};
|
package/dist/HttpKernel.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HttpKernel.js","sourceRoot":"","sources":["../src/HttpKernel.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AACzE,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;
|
|
1
|
+
{"version":3,"file":"HttpKernel.js","sourceRoot":"","sources":["../src/HttpKernel.ts"],"names":[],"mappings":"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"}
|
package/dist/Ignitor.d.ts
CHANGED
|
@@ -44,14 +44,6 @@ export interface ReamrcConfig {
|
|
|
44
44
|
/** Auto-loaded files in each module directory. Default: ['routes'] */
|
|
45
45
|
autoload?: string[];
|
|
46
46
|
};
|
|
47
|
-
tests?: {
|
|
48
|
-
suites?: Array<{
|
|
49
|
-
name: string;
|
|
50
|
-
files: string[];
|
|
51
|
-
timeout?: number;
|
|
52
|
-
}>;
|
|
53
|
-
forceExit?: boolean;
|
|
54
|
-
};
|
|
55
47
|
}
|
|
56
48
|
/** defineConfig helper — like AdonisJS defineConfig(). */
|
|
57
49
|
export declare function defineConfig(config: ReamrcConfig): ReamrcConfig;
|
|
@@ -168,13 +160,21 @@ export declare class Ignitor {
|
|
|
168
160
|
* Scans modules.path for subdirectories and imports matching files.
|
|
169
161
|
*/
|
|
170
162
|
private autoloadModules;
|
|
171
|
-
/**
|
|
163
|
+
/**
|
|
164
|
+
* Graceful shutdown. Every step runs even when an earlier one throws — a
|
|
165
|
+
* failing `httpServer.close()` must not leave the error boundary installed,
|
|
166
|
+
* providers un-shutdown (open DB pools), or the locators bound. Errors are
|
|
167
|
+
* aggregated and rethrown at the end.
|
|
168
|
+
*/
|
|
172
169
|
stop(): Promise<void>;
|
|
173
170
|
port(): Promise<number>;
|
|
174
171
|
getApp(): Application;
|
|
175
172
|
getRouter(): Router;
|
|
176
173
|
getServer(): Server;
|
|
177
|
-
/**
|
|
174
|
+
/**
|
|
175
|
+
* Get the kernel callback (for serverless / testing). Memoized — building a
|
|
176
|
+
* kernel per call would discard its compiled-pipeline cache every time.
|
|
177
|
+
*/
|
|
178
178
|
getKernel(): (request: HttpKernelRequest) => Promise<HttpKernelResponse>;
|
|
179
179
|
isDevMode(): boolean;
|
|
180
180
|
getPhase(): string;
|
package/dist/Ignitor.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Ignitor.d.ts","sourceRoot":"","sources":["../src/Ignitor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAKH,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAKpD,OAAO,KAAK,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AAG5E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAA;AAElE,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAEjE,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAC3C,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAK3C,+BAA+B;AAC/B,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAAA;AAEnE;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,SAAS,CAAC,EAAE,KAAK,CACb,CAAC,MAAM,OAAO,CAAC;QAAE,OAAO,EAAE,KAAK,GAAG,EAAE,UAAU,KAAK,gBAAgB,CAAA;KAAE,CAAC,CAAC,GACvE;QACE,IAAI,EAAE,MAAM,OAAO,CAAC;YAAE,OAAO,EAAE,KAAK,GAAG,EAAE,UAAU,KAAK,gBAAgB,CAAA;SAAE,CAAC,CAAA;QAC3E,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;KACvB,CACJ,CAAA;IACD,QAAQ,CAAC,EAAE,KAAK,CACZ,CAAC,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC,GACxB;QACE,IAAI,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAA;QAC5B,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;KACvB,CACJ,CAAA;IACD,QAAQ,CAAC,EAAE,KAAK,CAAC,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC,CAAA;IACxC,OAAO,CAAC,EAAE;QACR,qFAAqF;QACrF,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,sEAAsE;QACtE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;KACpB,CAAA;
|
|
1
|
+
{"version":3,"file":"Ignitor.d.ts","sourceRoot":"","sources":["../src/Ignitor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAKH,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAKpD,OAAO,KAAK,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AAG5E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAA;AAElE,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAEjE,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAC3C,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAK3C,+BAA+B;AAC/B,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAAA;AAEnE;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,SAAS,CAAC,EAAE,KAAK,CACb,CAAC,MAAM,OAAO,CAAC;QAAE,OAAO,EAAE,KAAK,GAAG,EAAE,UAAU,KAAK,gBAAgB,CAAA;KAAE,CAAC,CAAC,GACvE;QACE,IAAI,EAAE,MAAM,OAAO,CAAC;YAAE,OAAO,EAAE,KAAK,GAAG,EAAE,UAAU,KAAK,gBAAgB,CAAA;SAAE,CAAC,CAAA;QAC3E,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;KACvB,CACJ,CAAA;IACD,QAAQ,CAAC,EAAE,KAAK,CACZ,CAAC,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC,GACxB;QACE,IAAI,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAA;QAC5B,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;KACvB,CACJ,CAAA;IACD,QAAQ,CAAC,EAAE,KAAK,CAAC,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC,CAAA;IACxC,OAAO,CAAC,EAAE;QACR,qFAAqF;QACrF,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,sEAAsE;QACtE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;KACpB,CAAA;CACF;AAED,0DAA0D;AAC1D,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,YAAY,CAE/D;AAED,4DAA4D;AAC5D,MAAM,WAAW,eAAe;IAC9B,SAAS,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,iBAAiB,KAAK,OAAO,CAAC,kBAAkB,CAAC,GAAG,IAAI,CAAA;IACtF;;;OAGG;IACH,eAAe,CAAC,CAAC,MAAM,EAAE;QAAE,aAAa,EAAE,OAAO,CAAC;QAAC,cAAc,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAA;IACnF,sDAAsD;IACtD,uBAAuB,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAAA;IAC/C,sDAAsD;IACtD,kBAAkB,CAAC,CAAC,MAAM,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,GAAG,IAAI,CAAA;IAC7E,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACvB,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,CAAA;IACvB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IAItB,cAAc,CAAC,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IACnD,WAAW,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IAC/D,WAAW,CAAC,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IAChD,kBAAkB,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI,CAAA;CAClE;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,eAAe,CAAA;IACjD,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;IACjD,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;CACrB;AAED;;;;GAIG;AACH,qBAAa,OAAO;;IAClB,OAAO,CAAC,GAAG,CAAa;IACxB,OAAO,CAAC,MAAM,CAAQ;IACtB,OAAO,CAAC,MAAM,CAAQ;IACtB,OAAO,CAAC,UAAU,CAAoB;IACtC,OAAO,CAAC,aAAa,CAAe;IACpC,OAAO,CAAC,WAAW,CAAC,CAAiB;IACrC,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,OAAO,CAAC,CAAK;IACrB,OAAO,CAAC,WAAW,CAA4B;IAC/C,OAAO,CAAC,MAAM,CAAC,CAAc;IAC7B,OAAO,CAAC,SAAS,CAAyB;IAC1C,OAAO,CAAC,cAAc,CAAyC;IAC/D,OAAO,CAAC,KAAK,CAAoF;IACjG,OAAO,CAAC,gBAAgB,CAAC,CAAY;IAGrC,OAAO,CAAC,YAAY,CAAC,CAA0B;IAC/C,OAAO,CAAC,gBAAgB,CAA2B;IACnD,OAAO,CAAC,qBAAqB,CAA0C;IACvE,OAAO,CAAC,uBAAuB,CAAoD;IAEnF;;;;;;;;OAQG;gBACS,eAAe,CAAC,EAAE,GAAG,GAAG,aAAa,EAAE,MAAM,CAAC,EAAE,aAAa;IAoCzE;;;OAGG;IACH,GAAG,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,WAAW,KAAK,IAAI,GAAG,IAAI;IAK/C,uCAAuC;IACvC,cAAc,CAAC,GAAG,EAAE,cAAc,GAAG,IAAI;IAKzC,cAAc,IAAI,cAAc;IAIhC;;OAEG;IACH,SAAS,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI;IAOrC,0CAA0C;IAC1C,MAAM,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAKhD,oCAAoC;IACpC,GAAG,CAAC,EAAE,EAAE,kBAAkB,GAAG,IAAI;IAKjC,0CAA0C;IAC1C,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,kBAAkB,GAAG,IAAI;IAKjD,+DAA+D;IAC/D,QAAQ,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,WAAW,KAAK,gBAAgB,GAAG,IAAI;IAK/D,+BAA+B;IAC/B,OAAO,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,GAAG,IAAI;IAKpD,0BAA0B;IAC1B,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI;IAO5C,sCAAsC;IACtC,UAAU,IAAI,IAAI;IAKlB,wFAAwF;IACxF,OAAO,IAAI,aAAa;IAKxB,+BAA+B;IAC/B,QAAQ,IAAI,IAAI;IAOV,KAAK,IAAI,OAAO,CAAC,OAAO,CAAC;YAkEjB,aAAa;YAgCb,SAAS;YAKT,UAAU;YAqCV,UAAU;IAoIxB;;;;OAIG;YACW,cAAc;IAsB5B;;;OAGG;YACW,eAAe;IAkC7B;;;;;OAKG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAmCrB,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC;IAI7B,MAAM,IAAI,WAAW;IAIrB,SAAS,IAAI,MAAM;IAInB,SAAS,IAAI,MAAM;IAInB;;;OAGG;IACH,SAAS,IAAI,CAAC,OAAO,EAAE,iBAAiB,KAAK,OAAO,CAAC,kBAAkB,CAAC;IAexE,SAAS,IAAI,OAAO;IAIpB,QAAQ,IAAI,MAAM;IAIlB,OAAO,CAAC,WAAW;CASpB;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CASrD;AAED;;;GAGG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,EAAE,OAAO;IAItB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAkC5C"}
|
package/dist/Ignitor.js
CHANGED
|
@@ -25,9 +25,9 @@ import { MiddlewareRegistry } from './middleware/Pipeline.js';
|
|
|
25
25
|
import { callProviderPhase } from './Provider.js';
|
|
26
26
|
import { Router } from './router/Router.js';
|
|
27
27
|
import { Server } from './server/Server.js';
|
|
28
|
-
import { setApp } from './services/app.js';
|
|
29
|
-
import { setRouter } from './services/router.js';
|
|
30
|
-
import { setServer } from './services/server.js';
|
|
28
|
+
import { clearApp, setApp } from './services/app.js';
|
|
29
|
+
import { clearRouter, setRouter } from './services/router.js';
|
|
30
|
+
import { clearServer, setServer } from './services/server.js';
|
|
31
31
|
/** defineConfig helper — like AdonisJS defineConfig(). */
|
|
32
32
|
export function defineConfig(config) {
|
|
33
33
|
return config;
|
|
@@ -170,11 +170,31 @@ export class Ignitor {
|
|
|
170
170
|
}
|
|
171
171
|
// ─── Lifecycle ────────────────────────────────────────────
|
|
172
172
|
async start() {
|
|
173
|
+
// Double-start guard: a second start() would re-run phaseRegister and
|
|
174
|
+
// instantiate + register every reamrc provider a second time.
|
|
175
|
+
if (this.phase !== 'created') {
|
|
176
|
+
throw new ReamError('IGNITOR_ALREADY_STARTED', `start() called while in phase '${this.phase}' — an Ignitor boots once`, { hint: 'Create a new Ignitor instance instead of restarting this one.' });
|
|
177
|
+
}
|
|
173
178
|
this.#loadEnvironmentFiles();
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
179
|
+
try {
|
|
180
|
+
await this.phaseRegister();
|
|
181
|
+
await this.phaseBoot();
|
|
182
|
+
await this.phaseStart();
|
|
183
|
+
await this.phaseReady();
|
|
184
|
+
}
|
|
185
|
+
catch (err) {
|
|
186
|
+
// A throw mid-boot (e.g. a provider ready() failing AFTER the HTTP port
|
|
187
|
+
// is bound) must release everything the partial boot opened — port,
|
|
188
|
+
// scheduler tickers, watchers — or the process hangs with leaked
|
|
189
|
+
// resources. Best-effort: the original boot error stays the one thrown.
|
|
190
|
+
try {
|
|
191
|
+
await this.stop();
|
|
192
|
+
}
|
|
193
|
+
catch {
|
|
194
|
+
/* surface the boot error, not the rollback error */
|
|
195
|
+
}
|
|
196
|
+
throw err;
|
|
197
|
+
}
|
|
178
198
|
return this;
|
|
179
199
|
}
|
|
180
200
|
/**
|
|
@@ -314,7 +334,13 @@ export class Ignitor {
|
|
|
314
334
|
},
|
|
315
335
|
});
|
|
316
336
|
const desiredPort = this.config.port ?? 3000;
|
|
317
|
-
|
|
337
|
+
// Port-scan fallback (+1..+19) is a DEV convenience only. In production
|
|
338
|
+
// a silent drift to :3001 while the LB targets :3000 is an outage —
|
|
339
|
+
// bind the configured port and let EADDRINUSE fail loudly. The probe
|
|
340
|
+
// also has an inherent TOCTOU; acceptable in dev, not in prod.
|
|
341
|
+
const availablePort = this.app.inProduction
|
|
342
|
+
? desiredPort
|
|
343
|
+
: await findAvailablePort(desiredPort);
|
|
318
344
|
this._httpServer = this.config.serverFactory(availablePort);
|
|
319
345
|
this._httpServer.onRequest(kernel);
|
|
320
346
|
// Pre-resolve client IPs in Rust from the trusted-proxy CIDRs before
|
|
@@ -344,23 +370,29 @@ export class Ignitor {
|
|
|
344
370
|
.resolve('events')
|
|
345
371
|
.emit('app:ready', { environment: this.environment });
|
|
346
372
|
}
|
|
347
|
-
//
|
|
373
|
+
// Dev-mode change watcher. IMPORTANT: this does NOT attempt an in-process
|
|
374
|
+
// reload. The previous implementation cleared the router + service registry
|
|
375
|
+
// and re-invoked the reamrc preload thunks — but a dynamic import() of an
|
|
376
|
+
// already-loaded ESM module returns the CACHED module without re-executing
|
|
377
|
+
// its body (the thunk's specifier is opaque, so it cannot be cache-busted).
|
|
378
|
+
// The "reload" therefore destroyed every preload-registered route on the
|
|
379
|
+
// first file save and never restored them. Process-level restart is the
|
|
380
|
+
// reload mechanism (`ream dev` runs `tsx watch`, which restarts on change);
|
|
381
|
+
// this watcher only surfaces an informational event for hosts that embed
|
|
382
|
+
// the Ignitor without a supervisor. A future true HMR needs a loader-hook
|
|
383
|
+
// (hot-hook style) that can invalidate the ESM cache — plug it in here.
|
|
348
384
|
if (this.isDevMode()) {
|
|
349
385
|
const watchDirs = this.config.watchDirs ?? ['app', 'start'];
|
|
350
386
|
this.hotReloadCleanup = startHotReload({
|
|
351
387
|
watchDirs,
|
|
352
|
-
onReload:
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
const preloadImport = typeof preloadEntry === 'function' ? preloadEntry : preloadEntry.file;
|
|
361
|
-
await preloadImport();
|
|
362
|
-
}
|
|
363
|
-
}
|
|
388
|
+
onReload: () => {
|
|
389
|
+
this.handleError({
|
|
390
|
+
type: 'system.info',
|
|
391
|
+
source: 'HotReload',
|
|
392
|
+
message: 'File change detected — a process restart is required to apply it (`ream dev` restarts automatically).',
|
|
393
|
+
severity: 'info',
|
|
394
|
+
timestamp: new Date().toISOString(),
|
|
395
|
+
});
|
|
364
396
|
},
|
|
365
397
|
logger: {
|
|
366
398
|
info: (msg) => this.handleError({
|
|
@@ -432,15 +464,44 @@ export class Ignitor {
|
|
|
432
464
|
}
|
|
433
465
|
}
|
|
434
466
|
}
|
|
435
|
-
/**
|
|
467
|
+
/**
|
|
468
|
+
* Graceful shutdown. Every step runs even when an earlier one throws — a
|
|
469
|
+
* failing `httpServer.close()` must not leave the error boundary installed,
|
|
470
|
+
* providers un-shutdown (open DB pools), or the locators bound. Errors are
|
|
471
|
+
* aggregated and rethrown at the end.
|
|
472
|
+
*/
|
|
436
473
|
async stop() {
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
474
|
+
const errors = [];
|
|
475
|
+
const attempt = async (step) => {
|
|
476
|
+
try {
|
|
477
|
+
await step();
|
|
478
|
+
}
|
|
479
|
+
catch (err) {
|
|
480
|
+
errors.push(err);
|
|
481
|
+
}
|
|
482
|
+
};
|
|
483
|
+
await attempt(() => {
|
|
484
|
+
if (this.hotReloadCleanup)
|
|
485
|
+
this.hotReloadCleanup();
|
|
486
|
+
});
|
|
487
|
+
await attempt(async () => {
|
|
488
|
+
if (this._httpServer)
|
|
489
|
+
await this._httpServer.close();
|
|
490
|
+
});
|
|
491
|
+
await attempt(() => this.errorBoundary.uninstall());
|
|
492
|
+
await attempt(() => this.app.shutdown());
|
|
493
|
+
// Release the process-wide service locators (ownership-guarded): a stopped
|
|
494
|
+
// app must not keep its container/router reachable through the module
|
|
495
|
+
// singletons, and must not clobber a newer Ignitor's bindings.
|
|
496
|
+
clearApp(this.app);
|
|
497
|
+
clearRouter(this.router);
|
|
498
|
+
clearServer(this.server);
|
|
443
499
|
this.phase = 'shutdown';
|
|
500
|
+
if (errors.length === 1)
|
|
501
|
+
throw errors[0];
|
|
502
|
+
if (errors.length > 1) {
|
|
503
|
+
throw new AggregateError(errors, 'Ignitor.stop() completed with errors');
|
|
504
|
+
}
|
|
444
505
|
}
|
|
445
506
|
// ─── Accessors ────────────────────────────────────────────
|
|
446
507
|
async port() {
|
|
@@ -455,9 +516,12 @@ export class Ignitor {
|
|
|
455
516
|
getServer() {
|
|
456
517
|
return this.server;
|
|
457
518
|
}
|
|
458
|
-
/**
|
|
519
|
+
/**
|
|
520
|
+
* Get the kernel callback (for serverless / testing). Memoized — building a
|
|
521
|
+
* kernel per call would discard its compiled-pipeline cache every time.
|
|
522
|
+
*/
|
|
459
523
|
getKernel() {
|
|
460
|
-
|
|
524
|
+
this.#kernel ??= createHttpKernel({
|
|
461
525
|
router: this.router,
|
|
462
526
|
middleware: this.middleware,
|
|
463
527
|
container: this.app.container,
|
|
@@ -465,7 +529,9 @@ export class Ignitor {
|
|
|
465
529
|
serverMiddleware: this.server.getServerMiddleware(),
|
|
466
530
|
routerMiddleware: this.router.getRouterMiddleware(),
|
|
467
531
|
});
|
|
532
|
+
return this.#kernel;
|
|
468
533
|
}
|
|
534
|
+
#kernel;
|
|
469
535
|
isDevMode() {
|
|
470
536
|
return this.app.inDev;
|
|
471
537
|
}
|
|
@@ -524,8 +590,14 @@ export class ConsoleKernel {
|
|
|
524
590
|
}
|
|
525
591
|
}
|
|
526
592
|
this.ignitor.getApp().container.singleton('console', () => runner);
|
|
527
|
-
|
|
528
|
-
|
|
593
|
+
try {
|
|
594
|
+
await runner.handle(argv);
|
|
595
|
+
}
|
|
596
|
+
finally {
|
|
597
|
+
// A throwing command must still release the Ignitor's resources
|
|
598
|
+
// (scheduler tickers, watchers) — otherwise the CLI process hangs.
|
|
599
|
+
await this.ignitor.stop();
|
|
600
|
+
}
|
|
529
601
|
}
|
|
530
602
|
}
|
|
531
603
|
async function findAvailablePort(desired) {
|