@scpxl/nodejs-framework 1.0.32 → 1.0.43
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/base-application.d.ts +7 -7
- package/dist/application/base-application.d.ts.map +1 -1
- package/dist/application/base-application.interface.d.ts +1 -1
- package/dist/application/base-application.interface.d.ts.map +1 -1
- package/dist/application/base-application.js +114 -14
- package/dist/application/base-application.js.map +2 -2
- package/dist/application/web-application.d.ts.map +1 -1
- package/dist/application/web-application.js +2 -1
- package/dist/application/web-application.js.map +2 -2
- package/dist/cache/manager.d.ts +1 -0
- package/dist/cache/manager.d.ts.map +1 -1
- package/dist/cache/manager.js +11 -2
- package/dist/cache/manager.js.map +2 -2
- package/dist/cli/index.js +28 -12
- package/dist/cli/index.js.map +2 -2
- package/dist/config/schema.d.ts +2 -63
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js +1 -7
- package/dist/config/schema.js.map +2 -2
- package/dist/event/manager.js +2 -2
- package/dist/event/manager.js.map +2 -2
- package/dist/logger/logger.js +0 -1
- package/dist/logger/logger.js.map +2 -2
- package/dist/queue/manager.d.ts.map +1 -1
- package/dist/queue/manager.js +19 -7
- package/dist/queue/manager.js.map +2 -2
- package/dist/redis/instance.d.ts.map +1 -1
- package/dist/redis/instance.js +9 -1
- package/dist/redis/instance.js.map +2 -2
- package/dist/redis/manager.d.ts.map +1 -1
- package/dist/redis/manager.js +26 -16
- package/dist/redis/manager.js.map +3 -3
- package/dist/webserver/controller/entity.js +1 -1
- package/dist/webserver/controller/entity.js.map +2 -2
- package/dist/webserver/controller/health.js.map +1 -1
- package/dist/webserver/util.d.ts +1 -1
- package/dist/webserver/util.d.ts.map +1 -1
- package/dist/webserver/util.js +5 -23
- package/dist/webserver/util.js.map +2 -2
- package/dist/webserver/webserver.d.ts +2 -13
- package/dist/webserver/webserver.d.ts.map +1 -1
- package/dist/webserver/webserver.interface.d.ts +1 -21
- package/dist/webserver/webserver.interface.d.ts.map +1 -1
- package/dist/webserver/webserver.interface.js.map +1 -1
- package/dist/webserver/webserver.js +34 -36
- package/dist/webserver/webserver.js.map +2 -2
- package/dist/websocket/define-subscriber.d.ts +8 -1
- package/dist/websocket/define-subscriber.d.ts.map +1 -1
- package/dist/websocket/define-subscriber.js +2 -1
- package/dist/websocket/define-subscriber.js.map +2 -2
- package/dist/websocket/index.d.ts +4 -0
- package/dist/websocket/index.d.ts.map +1 -1
- package/dist/websocket/index.js +43 -1
- package/dist/websocket/index.js.map +2 -2
- package/dist/websocket/subscriber-middleware.d.ts +52 -0
- package/dist/websocket/subscriber-middleware.d.ts.map +1 -0
- package/dist/websocket/subscriber-middleware.js +200 -0
- package/dist/websocket/subscriber-middleware.js.map +7 -0
- package/dist/websocket/subscriber-utils.d.ts +88 -0
- package/dist/websocket/subscriber-utils.d.ts.map +1 -0
- package/dist/websocket/subscriber-utils.js +227 -0
- package/dist/websocket/subscriber-utils.js.map +7 -0
- package/dist/websocket/utils.d.ts.map +1 -1
- package/dist/websocket/utils.js +5 -1
- package/dist/websocket/utils.js.map +2 -2
- package/dist/websocket/websocket-base.d.ts.map +1 -1
- package/dist/websocket/websocket-base.js +9 -1
- package/dist/websocket/websocket-base.js.map +2 -2
- package/dist/websocket/websocket-server.d.ts +41 -1
- package/dist/websocket/websocket-server.d.ts.map +1 -1
- package/dist/websocket/websocket-server.js +90 -7
- package/dist/websocket/websocket-server.js.map +2 -2
- package/dist/websocket/websocket.interface.d.ts +7 -0
- package/dist/websocket/websocket.interface.d.ts.map +1 -1
- package/dist/websocket/websocket.interface.js.map +2 -2
- package/package.json +5 -6
|
@@ -17,6 +17,8 @@ export default abstract class BaseApplication {
|
|
|
17
17
|
protected shutdownTimeout: number;
|
|
18
18
|
/** Cache for application version to avoid repeated imports */
|
|
19
19
|
private static applicationVersionCache;
|
|
20
|
+
private static globalErrorHandlersRegistered;
|
|
21
|
+
private static readonly instances;
|
|
20
22
|
/** Cluster worker ID */
|
|
21
23
|
protected workerId: number | null;
|
|
22
24
|
/** Application config */
|
|
@@ -79,13 +81,11 @@ export default abstract class BaseApplication {
|
|
|
79
81
|
eventManager?: EventManager | null;
|
|
80
82
|
}): Promise<void>;
|
|
81
83
|
protected abstract stopCallback(): void;
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
*/
|
|
88
|
-
private setupGlobalErrorHandlers;
|
|
84
|
+
private static registerInstance;
|
|
85
|
+
private static unregisterInstance;
|
|
86
|
+
private static pruneStaleInstances;
|
|
87
|
+
private static getActiveInstances;
|
|
88
|
+
private static registerGlobalErrorHandlers;
|
|
89
89
|
/**
|
|
90
90
|
* Register shutdown hooks for proper cleanup
|
|
91
91
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base-application.d.ts","sourceRoot":"","sources":["../../src/application/base-application.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,gBAAgB,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC9E,OAAO,YAAY,MAAM,qBAAqB,CAAC;AAC/C,OAAO,YAAY,MAAM,qBAAqB,CAAC;AAC/C,OAAO,KAAK,EACV,iBAAiB,EAEjB,8BAA8B,EAC/B,MAAM,iCAAiC,CAAC;AAEzC,OAAO,KAAK,aAAa,MAAM,sBAAsB,CAAC;AAEtD,OAAO,YAAY,MAAM,qBAAqB,CAAC;AAE/C,OAAO,YAAY,MAAM,qBAAqB,CAAC;AAE/C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAGhF,OAAO,EAAwB,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAMnG,YAAY,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAEzE,MAAM,CAAC,OAAO,CAAC,QAAQ,OAAO,eAAe;IAC3C,yBAAyB;IAClB,gBAAgB,EAAE,MAAM,CAAC;IAEhC,6BAA6B;IAC7B,SAAS,CAAC,SAAS,EAAE,MAAM,CAAK;IAEhC,oCAAoC;IACpC,SAAS,CAAC,eAAe,SAAS;IAElC,8DAA8D;IAC9D,OAAO,CAAC,MAAM,CAAC,uBAAuB,CAAqB;
|
|
1
|
+
{"version":3,"file":"base-application.d.ts","sourceRoot":"","sources":["../../src/application/base-application.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,gBAAgB,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC9E,OAAO,YAAY,MAAM,qBAAqB,CAAC;AAC/C,OAAO,YAAY,MAAM,qBAAqB,CAAC;AAC/C,OAAO,KAAK,EACV,iBAAiB,EAEjB,8BAA8B,EAC/B,MAAM,iCAAiC,CAAC;AAEzC,OAAO,KAAK,aAAa,MAAM,sBAAsB,CAAC;AAEtD,OAAO,YAAY,MAAM,qBAAqB,CAAC;AAE/C,OAAO,YAAY,MAAM,qBAAqB,CAAC;AAE/C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAGhF,OAAO,EAAwB,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAMnG,YAAY,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAEzE,MAAM,CAAC,OAAO,CAAC,QAAQ,OAAO,eAAe;IAC3C,yBAAyB;IAClB,gBAAgB,EAAE,MAAM,CAAC;IAEhC,6BAA6B;IAC7B,SAAS,CAAC,SAAS,EAAE,MAAM,CAAK;IAEhC,oCAAoC;IACpC,SAAS,CAAC,eAAe,SAAS;IAElC,8DAA8D;IAC9D,OAAO,CAAC,MAAM,CAAC,uBAAuB,CAAqB;IAC3D,OAAO,CAAC,MAAM,CAAC,6BAA6B,CAAS;IACrD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAuC;IAExE,wBAAwB;IACxB,SAAS,CAAC,QAAQ,gBAAiE;IAEnF,yBAAyB;IACzB,SAAS,CAAC,MAAM,EAAE,iBAAiB,CAAC;IAEpC,0BAA0B;IAC1B,SAAS,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAEtC,oBAAoB;IACb,YAAY,EAAE,YAAY,CAAC;IAElC,oBAAoB;IACb,YAAY,EAAE,YAAY,CAAC;IAElC,uBAAuB;IAChB,eAAe,CAAC,EAAE,eAAe,CAAC;IAEzC,oBAAoB;IACb,YAAY,CAAC,EAAE,YAAY,CAAC;IAEnC,oBAAoB;IACb,YAAY,CAAC,EAAE,YAAY,CAAC;IAEnC,0BAA0B;IACnB,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IAE/C,wBAAwB;IACjB,SAAS,EAAE,gBAAgB,CAAC;IAEnC,0BAA0B;IACnB,kBAAkB,EAAE,kBAAkB,CAAC;IAE9C,IAAW,IAAI,WAEd;IAED;;OAEG;gBACS,MAAM,EAAE,iBAAiB;IAiFrC;;OAEG;IACU,qBAAqB,IAAI,OAAO,CAAC,MAAM,CAAC;IAyBrD;;OAEG;IACU,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA6CnC;;OAEG;YACW,aAAa;IA2F3B;;OAEG;IACH,SAAS,CAAC,SAAS,CAAC,EAAE,WAAW,EAAE,YAAY,EAAE,EAAE;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAEjF;;OAEG;IACH,SAAS,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAErE;;OAEG;YACW,aAAa;IAkG3B,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC,EAC9B,aAAa,EACb,gBAAgB,EAChB,YAAY,EACZ,YAAY,GACb,EAAE;QACD,aAAa,EAAE,aAAa,CAAC;QAC7B,gBAAgB,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAC;QAC3C,YAAY,EAAE,YAAY,CAAC;QAC3B,YAAY,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;KACpC,GAAG,OAAO,CAAC,IAAI,CAAC;IAEjB,SAAS,CAAC,QAAQ,CAAC,YAAY,IAAI,IAAI;IAEvC,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAM/B,OAAO,CAAC,MAAM,CAAC,kBAAkB;IASjC,OAAO,CAAC,MAAM,CAAC,mBAAmB;IAQlC,OAAO,CAAC,MAAM,CAAC,kBAAkB;IAoBjC,OAAO,CAAC,MAAM,CAAC,2BAA2B;IA0B1C;;OAEG;IACH,OAAO,CAAC,qBAAqB;IA4B7B;;OAEG;YACW,wBAAwB;IA6BtC;;OAEG;IACU,IAAI,CAAC,EAAE,SAAS,EAAE,GAAE,8BAAmC,GAAG,OAAO,CAAC,IAAI,CAAC;IAoCpF;;OAEG;IACH,OAAO,CAAC,YAAY;CAerB"}
|
|
@@ -90,7 +90,7 @@ export interface ApplicationWebServerConfig extends WebServerOptions {
|
|
|
90
90
|
/** Whether to enable web server */
|
|
91
91
|
enabled: boolean;
|
|
92
92
|
/** Web server routes */
|
|
93
|
-
routes
|
|
93
|
+
routes?: WebServerRoute[];
|
|
94
94
|
log?: WebServerLogConfig;
|
|
95
95
|
debug: WebServerDebugOptions;
|
|
96
96
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base-application.interface.d.ts","sourceRoot":"","sources":["../../src/application/base-application.interface.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"base-application.interface.d.ts","sourceRoot":"","sources":["../../src/application/base-application.interface.ts"],"names":[],"mappings":"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"}
|
|
@@ -30,6 +30,8 @@ class BaseApplication {
|
|
|
30
30
|
shutdownTimeout = 3e4;
|
|
31
31
|
/** Cache for application version to avoid repeated imports */
|
|
32
32
|
static applicationVersionCache;
|
|
33
|
+
static globalErrorHandlersRegistered = false;
|
|
34
|
+
static instances = /* @__PURE__ */ new Set();
|
|
33
35
|
/** Cluster worker ID */
|
|
34
36
|
workerId = cluster.isWorker && cluster.worker ? cluster.worker.id : null;
|
|
35
37
|
/** Application config */
|
|
@@ -98,8 +100,8 @@ ${formatted}`);
|
|
|
98
100
|
redisManager: this.redisManager
|
|
99
101
|
});
|
|
100
102
|
PerformanceMonitorPlugin.register(this);
|
|
101
|
-
|
|
102
|
-
if (this.config.database
|
|
103
|
+
BaseApplication.registerInstance(this);
|
|
104
|
+
if (this.config.database?.enabled === true) {
|
|
103
105
|
const defaultEntitiesDirectory = join(this.config.rootDirectory, "src", "database", "entities");
|
|
104
106
|
if (!this.config.database.entitiesDirectory) {
|
|
105
107
|
this.config.database.entitiesDirectory = defaultEntitiesDirectory;
|
|
@@ -171,8 +173,27 @@ ${formatted}`);
|
|
|
171
173
|
* Before application start
|
|
172
174
|
*/
|
|
173
175
|
async onBeforeStart() {
|
|
176
|
+
const phaseStartTime = Time.now();
|
|
177
|
+
if (process.env.DEBUG_TESTS) {
|
|
178
|
+
console.log("[BaseApplication] Connecting to Redis...");
|
|
179
|
+
}
|
|
174
180
|
const redisInstance = await this.redisManager.connect();
|
|
175
|
-
|
|
181
|
+
if (process.env.DEBUG_TESTS) {
|
|
182
|
+
const redisElapsed = Time.calculateElapsedTimeMs({ startTime: phaseStartTime });
|
|
183
|
+
console.log(`[BaseApplication] Redis connected (${redisElapsed}ms)`);
|
|
184
|
+
}
|
|
185
|
+
let databaseInstance = null;
|
|
186
|
+
if (this.databaseManager) {
|
|
187
|
+
if (process.env.DEBUG_TESTS) {
|
|
188
|
+
console.log("[BaseApplication] Connecting to database...");
|
|
189
|
+
}
|
|
190
|
+
const dbStartTime = Time.now();
|
|
191
|
+
databaseInstance = await this.databaseManager.connect();
|
|
192
|
+
if (process.env.DEBUG_TESTS) {
|
|
193
|
+
const dbElapsed = Time.calculateElapsedTimeMs({ startTime: dbStartTime });
|
|
194
|
+
console.log(`[BaseApplication] Database connected (${dbElapsed}ms)`);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
176
197
|
let eventManager;
|
|
177
198
|
if (this.config.event?.enabled) {
|
|
178
199
|
eventManager = new EventManager({
|
|
@@ -236,28 +257,68 @@ ${formatted}`);
|
|
|
236
257
|
*/
|
|
237
258
|
async startInstance(options) {
|
|
238
259
|
try {
|
|
260
|
+
if (process.env.DEBUG_TESTS) {
|
|
261
|
+
console.log("[startInstance] Phase 1: Initializing lifecycle...");
|
|
262
|
+
}
|
|
263
|
+
const initStartTime = Time.now();
|
|
239
264
|
const initResult = await this.lifecycle.initialize();
|
|
265
|
+
if (process.env.DEBUG_TESTS) {
|
|
266
|
+
const initElapsed = Time.calculateElapsedTimeMs({ startTime: initStartTime });
|
|
267
|
+
console.log(`[startInstance] Phase 1 complete (${initElapsed}ms)`);
|
|
268
|
+
}
|
|
240
269
|
if (initResult.errors.length > 0) {
|
|
241
270
|
Logger.warn({
|
|
242
271
|
message: "Lifecycle init phase encountered errors",
|
|
243
272
|
meta: { errors: initResult.errors.map((e) => e instanceof Error ? e.message : String(e)) }
|
|
244
273
|
});
|
|
245
274
|
}
|
|
275
|
+
if (process.env.DEBUG_TESTS) {
|
|
276
|
+
console.log("[startInstance] Connecting to services (Redis, Database, Queue, Events)...");
|
|
277
|
+
}
|
|
278
|
+
const beforeStartTime = Time.now();
|
|
246
279
|
const { redisInstance, databaseInstance, queueManager, eventManager } = await this.onBeforeStart();
|
|
280
|
+
if (process.env.DEBUG_TESTS) {
|
|
281
|
+
const beforeStartElapsed = Time.calculateElapsedTimeMs({ startTime: beforeStartTime });
|
|
282
|
+
console.log(`[startInstance] Services connected (${beforeStartElapsed}ms)`);
|
|
283
|
+
}
|
|
284
|
+
if (process.env.DEBUG_TESTS) {
|
|
285
|
+
console.log("[startInstance] Phase 2: Starting lifecycle components...");
|
|
286
|
+
}
|
|
287
|
+
const startStartTime = Time.now();
|
|
247
288
|
const startResult = await this.lifecycle.start();
|
|
289
|
+
if (process.env.DEBUG_TESTS) {
|
|
290
|
+
const startElapsed = Time.calculateElapsedTimeMs({ startTime: startStartTime });
|
|
291
|
+
console.log(`[startInstance] Phase 2 complete (${startElapsed}ms)`);
|
|
292
|
+
}
|
|
248
293
|
if (startResult.errors.length > 0) {
|
|
249
294
|
Logger.warn({
|
|
250
295
|
message: "Lifecycle start phase encountered errors",
|
|
251
296
|
meta: { errors: startResult.errors.map((e) => e instanceof Error ? e.message : String(e)) }
|
|
252
297
|
});
|
|
253
298
|
}
|
|
299
|
+
if (process.env.DEBUG_TESTS) {
|
|
300
|
+
console.log("[startInstance] Starting application handler...");
|
|
301
|
+
}
|
|
302
|
+
const handlerStartTime = Time.now();
|
|
254
303
|
await this.startHandler({
|
|
255
304
|
redisInstance,
|
|
256
305
|
databaseInstance,
|
|
257
306
|
queueManager,
|
|
258
307
|
eventManager
|
|
259
308
|
});
|
|
309
|
+
if (process.env.DEBUG_TESTS) {
|
|
310
|
+
const handlerElapsed = Time.calculateElapsedTimeMs({ startTime: handlerStartTime });
|
|
311
|
+
console.log(`[startInstance] Application handler started (${handlerElapsed}ms)`);
|
|
312
|
+
}
|
|
313
|
+
if (process.env.DEBUG_TESTS) {
|
|
314
|
+
console.log("[startInstance] Phase 3: Waiting for application to be ready...");
|
|
315
|
+
}
|
|
316
|
+
const readyStartTime = Time.now();
|
|
260
317
|
const readyResult = await this.lifecycle.ready();
|
|
318
|
+
if (process.env.DEBUG_TESTS) {
|
|
319
|
+
const readyElapsed = Time.calculateElapsedTimeMs({ startTime: readyStartTime });
|
|
320
|
+
console.log(`[startInstance] Phase 3 complete (${readyElapsed}ms)`);
|
|
321
|
+
}
|
|
261
322
|
if (readyResult.errors.length > 0) {
|
|
262
323
|
Logger.warn({
|
|
263
324
|
message: "Lifecycle ready phase encountered errors",
|
|
@@ -278,18 +339,51 @@ ${formatted}`);
|
|
|
278
339
|
throw error;
|
|
279
340
|
}
|
|
280
341
|
}
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
342
|
+
static registerInstance(instance) {
|
|
343
|
+
BaseApplication.pruneStaleInstances();
|
|
344
|
+
BaseApplication.instances.add(new WeakRef(instance));
|
|
345
|
+
BaseApplication.registerGlobalErrorHandlers();
|
|
346
|
+
}
|
|
347
|
+
static unregisterInstance(instance) {
|
|
348
|
+
for (const ref of Array.from(BaseApplication.instances)) {
|
|
349
|
+
const current = ref.deref();
|
|
350
|
+
if (!current || current === instance) {
|
|
351
|
+
BaseApplication.instances.delete(ref);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
static pruneStaleInstances() {
|
|
356
|
+
for (const ref of Array.from(BaseApplication.instances)) {
|
|
357
|
+
if (!ref.deref()) {
|
|
358
|
+
BaseApplication.instances.delete(ref);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
static getActiveInstances() {
|
|
363
|
+
const active = [];
|
|
364
|
+
const stale = [];
|
|
365
|
+
for (const ref of BaseApplication.instances) {
|
|
366
|
+
const instance = ref.deref();
|
|
367
|
+
if (instance) {
|
|
368
|
+
active.push(instance);
|
|
369
|
+
} else {
|
|
370
|
+
stale.push(ref);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
for (const ref of stale) {
|
|
374
|
+
BaseApplication.instances.delete(ref);
|
|
375
|
+
}
|
|
376
|
+
return active;
|
|
377
|
+
}
|
|
378
|
+
static registerGlobalErrorHandlers() {
|
|
379
|
+
if (BaseApplication.globalErrorHandlersRegistered) {
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
290
382
|
process.on("uncaughtException", (error) => {
|
|
291
383
|
Logger.error({ error, message: "Uncaught Exception" });
|
|
292
|
-
|
|
384
|
+
for (const app of BaseApplication.getActiveInstances()) {
|
|
385
|
+
app.initiateGracefulShutdown();
|
|
386
|
+
}
|
|
293
387
|
});
|
|
294
388
|
process.on("unhandledRejection", (reason, promise) => {
|
|
295
389
|
Logger.error({
|
|
@@ -297,13 +391,19 @@ ${formatted}`);
|
|
|
297
391
|
message: "Unhandled Rejection",
|
|
298
392
|
meta: { promise: String(promise) }
|
|
299
393
|
});
|
|
300
|
-
|
|
394
|
+
for (const app of BaseApplication.getActiveInstances()) {
|
|
395
|
+
app.initiateGracefulShutdown();
|
|
396
|
+
}
|
|
301
397
|
});
|
|
398
|
+
BaseApplication.globalErrorHandlersRegistered = true;
|
|
302
399
|
}
|
|
303
400
|
/**
|
|
304
401
|
* Register shutdown hooks for proper cleanup
|
|
305
402
|
*/
|
|
306
403
|
registerShutdownHooks() {
|
|
404
|
+
this.lifecycle.onShutdown(() => {
|
|
405
|
+
BaseApplication.unregisterInstance(this);
|
|
406
|
+
});
|
|
307
407
|
this.lifecycle.onShutdown(async () => {
|
|
308
408
|
Logger.info({ message: "Executing custom stop callback" });
|
|
309
409
|
await this.stopCallback();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/application/base-application.ts"],
|
|
4
|
-
"sourcesContent": ["import cluster from 'cluster';\nimport { existsSync, readFileSync } from 'fs';\nimport { fileURLToPath } from 'url';\nimport { dirname, join, resolve } from 'path';\nimport { type DatabaseInstance, DatabaseManager } from '../database/index.js';\nimport QueueManager from '../queue/manager.js';\nimport RedisManager from '../redis/manager.js';\nimport type {\n ApplicationConfig,\n ApplicationStartInstanceOptions,\n ApplicationStopInstanceOptions,\n} from './base-application.interface.js';\nimport ClusterManager from '../cluster/cluster-manager.js';\nimport type RedisInstance from '../redis/instance.js';\nimport { OS, Time } from '../util/index.js';\nimport CacheManager from '../cache/manager.js';\nimport os from 'os';\nimport EventManager from '../event/manager.js';\nimport Logger from '../logger/logger.js';\nimport type { PerformanceMonitor } from '../performance/performance-monitor.js';\n// Performance monitoring now pluginized\nimport { PerformanceMonitorPlugin } from '../performance/performance-monitor.plugin.js';\nimport { type LifecycleConfig, LifecycleManager, ShutdownController } from '../lifecycle/index.js';\nimport { ConfigValidationError, formatConfigIssues, validateFrameworkConfig } from '../config/schema.js';\nimport { type ExitOutcome, requestExit } from '../lifecycle/exit.js';\nimport { safeSerializeError } from '../error/error-reporter.js';\n\n// Re-export types for external use\nexport type { ApplicationConfig } from './base-application.interface.js';\n\nexport default abstract class BaseApplication {\n /** Unique instance ID */\n public uniqueInstanceId: string;\n\n /** Application start time */\n protected startTime: number = 0;\n\n /** Shutdown timeout (30 seconds) */\n protected shutdownTimeout = 30000;\n\n /** Cache for application version to avoid repeated imports */\n private static applicationVersionCache: string | undefined;\n\n /** Cluster worker ID */\n protected workerId = cluster.isWorker && cluster.worker ? cluster.worker.id : null;\n\n /** Application config */\n protected config: ApplicationConfig;\n\n /** Application version */\n protected applicationVersion?: string;\n\n /** Redis manager */\n public redisManager: RedisManager;\n\n /** Cache manager */\n public cacheManager: CacheManager;\n\n /** Database manager */\n public databaseManager?: DatabaseManager;\n\n /** Queue manager */\n public queueManager?: QueueManager;\n\n /** Event manager */\n public eventManager?: EventManager;\n\n /** Performance monitor */\n public performanceMonitor?: PerformanceMonitor;\n\n /** Lifecycle manager */\n public lifecycle: LifecycleManager;\n\n /** Shutdown controller */\n public shutdownController: ShutdownController;\n\n public get Name() {\n return this.config.name;\n }\n\n /**\n * Application constructor\n */\n constructor(config: ApplicationConfig) {\n // Validate configuration early (fail-fast before side effects)\n try {\n const validated = validateFrameworkConfig(config as any);\n config = validated as unknown as ApplicationConfig;\n } catch (err) {\n if (err instanceof ConfigValidationError) {\n const formatted = formatConfigIssues(err.issues);\n throw new Error(`Configuration validation failed:\\n${formatted}`);\n }\n throw err;\n }\n const computerName = os.hostname();\n\n this.uniqueInstanceId = `${config.instanceId}-${computerName}-${OS.getUniqueComputerId()}`;\n this.config = config;\n\n // Configure logger with application settings\n if (this.config.log?.showRequestIdInConsole !== undefined) {\n Logger.configure({ showRequestIdInConsole: this.config.log.showRequestIdInConsole });\n }\n\n // Initialize lifecycle management\n const lifecycleConfig: Partial<LifecycleConfig> = {\n gracefulShutdown: {\n timeoutMs: this.shutdownTimeout,\n },\n readiness: {\n timeoutMs: 30000,\n checkIntervalMs: 100,\n },\n };\n this.lifecycle = new LifecycleManager(lifecycleConfig);\n this.shutdownController = new ShutdownController(this.lifecycle);\n\n // Register shutdown hooks for cleanup\n this.registerShutdownHooks();\n\n // Initialize Redis manager\n this.redisManager = new RedisManager({\n applicationConfig: this.config,\n host: this.config.redis.host,\n port: this.config.redis.port,\n password: this.config.redis.password,\n });\n\n // Initialize cache manager\n this.cacheManager = new CacheManager({\n redisManager: this.redisManager,\n });\n\n // Register performance monitor plugin (idempotent & opt-in)\n PerformanceMonitorPlugin.register(this);\n\n // Set up global error handlers\n this.setupGlobalErrorHandlers();\n\n if (this.config.database && this.config.database.enabled === true) {\n const defaultEntitiesDirectory = join(this.config.rootDirectory, 'src', 'database', 'entities');\n\n if (!this.config.database.entitiesDirectory) {\n this.config.database.entitiesDirectory = defaultEntitiesDirectory;\n }\n\n if (!existsSync(this.config.database.entitiesDirectory)) {\n throw new Error(`Database entities directory not found (Path: ${this.config.database.entitiesDirectory})`);\n }\n\n // Initialize Database manager\n this.databaseManager = new DatabaseManager({\n applicationConfig: this.config,\n host: this.config.database.host,\n port: this.config.database.port,\n username: this.config.database.username,\n password: this.config.database.password,\n databaseName: this.config.database.databaseName,\n entitiesDirectory: this.config.database.entitiesDirectory,\n });\n }\n }\n\n /**\n * Get application version\n */\n public async getApplicationVersion(): Promise<string> {\n // Return cached version if available\n if (BaseApplication.applicationVersionCache !== undefined) {\n return BaseApplication.applicationVersionCache;\n }\n\n // Resolve the path to package.json\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = dirname(__filename);\n const packageJsonPath = resolve(__dirname, '../../package.json');\n\n // Read and parse the file\n const fileContents = readFileSync(packageJsonPath, 'utf-8');\n const packageJson = JSON.parse(fileContents);\n\n if (!packageJson?.version) {\n throw new Error('Application version not found');\n }\n\n // Cache and return the version\n BaseApplication.applicationVersionCache = packageJson.version;\n\n return packageJson.version;\n }\n\n /**\n * Start application\n */\n public async start(): Promise<void> {\n // Start application timer\n this.startTime = Time.now();\n\n // Get application version`\n this.applicationVersion = await this.getApplicationVersion();\n\n // Log initial startup message with version\n Logger.info({\n message: 'Starting application',\n meta: {\n Name: this.config.name,\n 'Instance ID': this.config.instanceId,\n 'PXL Framework Version': this.applicationVersion,\n },\n });\n\n const startInstanceOptions: ApplicationStartInstanceOptions = {\n onStarted: this.onStarted.bind(this),\n };\n\n const stopInstanceOptions: ApplicationStopInstanceOptions = {\n onStopped: this.onStopped.bind(this),\n };\n\n if (this.config.cluster?.enabled) {\n // Initialize clustered application\n const clusterManager = new ClusterManager({\n config: this.config.cluster,\n\n startApplicationCallback: () => this.startInstance(startInstanceOptions),\n stopApplicationCallback: () => this.stop(stopInstanceOptions),\n });\n\n // Start cluster\n clusterManager.start();\n } else {\n // Start standalone application\n await this.startInstance(startInstanceOptions);\n\n // Note: Signal handling should be implemented at the application launcher level\n // The lifecycle manager provides the stop() method for programmatic shutdown\n }\n }\n\n /**\n * Before application start\n */\n private async onBeforeStart(): Promise<{\n redisInstance: RedisInstance;\n databaseInstance: DatabaseInstance | null;\n queueManager: QueueManager;\n eventManager?: EventManager;\n }> {\n // Connect to Redis\n const redisInstance = await this.redisManager.connect();\n\n // Connect to database\n const databaseInstance = this.databaseManager ? await this.databaseManager.connect() : null;\n\n let eventManager: EventManager | undefined;\n\n if (this.config.event?.enabled) {\n eventManager = new EventManager({\n applicationConfig: this.config,\n options: this.config.event,\n events: this.config.event.events || [],\n redisInstance,\n databaseInstance,\n // queueManager,\n });\n\n eventManager.load();\n }\n\n // Initialize queue\n const queueManager = new QueueManager({\n applicationConfig: this.config,\n options: {\n processorsDirectory: this.config.queue.processorsDirectory,\n },\n queues: this.config.queue.queues,\n redisInstance,\n databaseInstance,\n eventManager,\n });\n\n // Register queues\n await queueManager.registerQueues({\n queues: this.config.queue.queues,\n });\n\n // Register readiness checks for key services\n this.lifecycle.addReadinessCheck('redis', async () => {\n try {\n return await redisInstance.isConnected();\n } catch {\n return false;\n }\n });\n\n if (databaseInstance) {\n this.lifecycle.addReadinessCheck('database', async () => {\n try {\n return await databaseInstance.isConnected();\n } catch {\n return false;\n }\n });\n }\n\n return {\n redisInstance,\n databaseInstance,\n queueManager,\n eventManager,\n };\n }\n\n /**\n * Application started event\n */\n protected onStarted({ startupTime: _startupTime }: { startupTime: number }): void {}\n\n /**\n * Application stopped event\n */\n protected onStopped({ runtime: _runtime }: { runtime: number }): void {}\n\n /**\n * Start application instance\n */\n private async startInstance(options: ApplicationStartInstanceOptions): Promise<void> {\n try {\n // Phase 1: Initialize (resource setup)\n const initResult = await this.lifecycle.initialize();\n if (initResult.errors.length > 0) {\n Logger.warn({\n message: 'Lifecycle init phase encountered errors',\n meta: { errors: initResult.errors.map(e => (e instanceof Error ? e.message : String(e))) },\n });\n }\n\n // Before application start\n const { redisInstance, databaseInstance, queueManager, eventManager } = await this.onBeforeStart();\n\n // Phase 2: Start (component startup)\n const startResult = await this.lifecycle.start();\n if (startResult.errors.length > 0) {\n Logger.warn({\n message: 'Lifecycle start phase encountered errors',\n meta: { errors: startResult.errors.map(e => (e instanceof Error ? e.message : String(e))) },\n });\n }\n\n // Start application\n await this.startHandler({\n redisInstance,\n databaseInstance,\n queueManager,\n eventManager,\n });\n\n // Phase 3: Ready (application accepting traffic)\n const readyResult = await this.lifecycle.ready();\n if (readyResult.errors.length > 0) {\n Logger.warn({\n message: 'Lifecycle ready phase encountered errors',\n meta: { errors: readyResult.errors.map(e => (e instanceof Error ? e.message : String(e))) },\n });\n }\n\n // Calculate application startup time\n const startupTime = Time.calculateElapsedTimeMs({\n startTime: this.startTime,\n });\n\n // On application started\n if (options.onStarted) {\n await options.onStarted({ startupTime });\n }\n } catch (error) {\n Logger.error({\n error: error instanceof Error ? error : new Error(safeSerializeError(error)),\n message: 'startInstance failure',\n });\n throw error;\n }\n }\n\n protected abstract startHandler({\n redisInstance,\n databaseInstance,\n queueManager,\n eventManager,\n }: {\n redisInstance: RedisInstance;\n databaseInstance?: DatabaseInstance | null;\n queueManager: QueueManager;\n eventManager?: EventManager | null;\n }): Promise<void>;\n\n protected abstract stopCallback(): void;\n\n /**\n * Set up global error handlers\n */\n /**\n * Initialize performance monitor\n */\n // initializePerformanceMonitor deprecated in favor of PerformanceMonitorPlugin\n // (left intentionally absent)\n\n private setupGlobalErrorHandlers(): void {\n // Handle uncaught exceptions\n process.on('uncaughtException', error => {\n Logger.error({ error, message: 'Uncaught Exception' });\n this.initiateGracefulShutdown();\n });\n\n // Handle unhandled promise rejections\n process.on('unhandledRejection', (reason, promise) => {\n Logger.error({\n error: reason instanceof Error ? reason : new Error(String(reason)),\n message: 'Unhandled Rejection',\n meta: { promise: String(promise) },\n });\n this.initiateGracefulShutdown();\n });\n }\n\n /**\n * Register shutdown hooks for proper cleanup\n */\n private registerShutdownHooks(): void {\n // Register shutdown hooks in reverse dependency order\n this.lifecycle.onShutdown(async () => {\n Logger.info({ message: 'Executing custom stop callback' });\n await this.stopCallback();\n });\n\n this.lifecycle.onShutdown(async () => {\n if (this.redisManager) {\n Logger.info({ message: 'Disconnecting from Redis' });\n await this.redisManager.disconnect();\n }\n });\n\n this.lifecycle.onShutdown(async () => {\n if (this.databaseManager) {\n Logger.info({ message: 'Disconnecting from database' });\n await this.databaseManager.disconnect();\n }\n });\n\n // Performance monitor is handled via trackInterval, so it will be cleaned up automatically\n }\n\n /**\n * Initiate graceful shutdown\n */\n private async initiateGracefulShutdown(): Promise<void> {\n if (this.shutdownController.isShuttingDown) {\n return;\n }\n\n Logger.info({ message: 'Initiating graceful shutdown due to error' });\n try {\n const result = await this.shutdownController.initiate('error-triggered');\n if (result.errors.length > 0) {\n Logger.error({\n message: 'Errors during shutdown',\n error: result.errors,\n });\n this.finalizeExit({ code: 1, reason: 'graceful-shutdown-error', error: result.errors });\n } else if (result.timedOut) {\n Logger.warn({ message: 'Shutdown timed out' });\n this.finalizeExit({ code: 1, reason: 'shutdown-timeout' });\n } else {\n this.finalizeExit({ code: 0, reason: 'error-shutdown-complete' });\n }\n } catch (error) {\n Logger.error({\n error: error instanceof Error ? error : new Error(safeSerializeError(error)),\n message: 'Error during graceful shutdown',\n });\n this.finalizeExit({ code: 1, reason: 'graceful-shutdown-error', error });\n }\n }\n\n /**\n * Stop application using lifecycle manager\n */\n public async stop({ onStopped }: ApplicationStopInstanceOptions = {}): Promise<void> {\n if (this.shutdownController.isShuttingDown) {\n return;\n }\n\n // Register the onStopped callback if provided\n if (onStopped) {\n this.lifecycle.onShutdown(() => {\n const runtime = process.uptime() * 1000;\n onStopped({ runtime });\n });\n }\n\n try {\n const result = await this.shutdownController.initiate('manual-stop');\n if (result.errors.length > 0) {\n Logger.error({\n message: 'Errors during shutdown',\n error: result.errors,\n });\n this.finalizeExit({ code: 1, reason: 'shutdown-error', error: result.errors });\n } else if (result.timedOut) {\n Logger.warn({ message: 'Shutdown timed out' });\n this.finalizeExit({ code: 1, reason: 'shutdown-timeout' });\n } else {\n this.finalizeExit({ code: 0, reason: 'shutdown-complete' });\n }\n } catch (error) {\n Logger.error({\n error: error instanceof Error ? error : new Error(safeSerializeError(error)),\n message: 'Error during shutdown',\n });\n this.finalizeExit({ code: 1, reason: 'shutdown-error', error });\n }\n }\n\n /**\n * Finalize exit: during tests, suppress actual process exit to avoid failing vitest runs.\n */\n private finalizeExit(outcome: ExitOutcome): void {\n const nodeEnv = process.env.NODE_ENV ?? '';\n const isTestEnv =\n nodeEnv.toLowerCase() === 'test' ||\n 'VITEST' in process.env ||\n 'VITEST_WORKER_ID' in process.env ||\n process.argv.some(a => a.includes('vitest')) ||\n typeof (globalThis as any).afterAll === 'function';\n\n if (isTestEnv) {\n Logger.info({ message: `Skipping process exit in test environment (${outcome.reason})`, code: outcome.code });\n return;\n }\n requestExit(outcome);\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import cluster from 'cluster';\nimport { existsSync, readFileSync } from 'fs';\nimport { fileURLToPath } from 'url';\nimport { dirname, join, resolve } from 'path';\nimport { type DatabaseInstance, DatabaseManager } from '../database/index.js';\nimport QueueManager from '../queue/manager.js';\nimport RedisManager from '../redis/manager.js';\nimport type {\n ApplicationConfig,\n ApplicationStartInstanceOptions,\n ApplicationStopInstanceOptions,\n} from './base-application.interface.js';\nimport ClusterManager from '../cluster/cluster-manager.js';\nimport type RedisInstance from '../redis/instance.js';\nimport { OS, Time } from '../util/index.js';\nimport CacheManager from '../cache/manager.js';\nimport os from 'os';\nimport EventManager from '../event/manager.js';\nimport Logger from '../logger/logger.js';\nimport type { PerformanceMonitor } from '../performance/performance-monitor.js';\n// Performance monitoring now pluginized\nimport { PerformanceMonitorPlugin } from '../performance/performance-monitor.plugin.js';\nimport { type LifecycleConfig, LifecycleManager, ShutdownController } from '../lifecycle/index.js';\nimport { ConfigValidationError, formatConfigIssues, validateFrameworkConfig } from '../config/schema.js';\nimport { type ExitOutcome, requestExit } from '../lifecycle/exit.js';\nimport { safeSerializeError } from '../error/error-reporter.js';\n\n// Re-export types for external use\nexport type { ApplicationConfig } from './base-application.interface.js';\n\nexport default abstract class BaseApplication {\n /** Unique instance ID */\n public uniqueInstanceId: string;\n\n /** Application start time */\n protected startTime: number = 0;\n\n /** Shutdown timeout (30 seconds) */\n protected shutdownTimeout = 30000;\n\n /** Cache for application version to avoid repeated imports */\n private static applicationVersionCache: string | undefined;\n private static globalErrorHandlersRegistered = false;\n private static readonly instances = new Set<WeakRef<BaseApplication>>();\n\n /** Cluster worker ID */\n protected workerId = cluster.isWorker && cluster.worker ? cluster.worker.id : null;\n\n /** Application config */\n protected config: ApplicationConfig;\n\n /** Application version */\n protected applicationVersion?: string;\n\n /** Redis manager */\n public redisManager: RedisManager;\n\n /** Cache manager */\n public cacheManager: CacheManager;\n\n /** Database manager */\n public databaseManager?: DatabaseManager;\n\n /** Queue manager */\n public queueManager?: QueueManager;\n\n /** Event manager */\n public eventManager?: EventManager;\n\n /** Performance monitor */\n public performanceMonitor?: PerformanceMonitor;\n\n /** Lifecycle manager */\n public lifecycle: LifecycleManager;\n\n /** Shutdown controller */\n public shutdownController: ShutdownController;\n\n public get Name() {\n return this.config.name;\n }\n\n /**\n * Application constructor\n */\n constructor(config: ApplicationConfig) {\n // Validate configuration early (fail-fast before side effects)\n try {\n const validated = validateFrameworkConfig(config as any);\n config = validated as unknown as ApplicationConfig;\n } catch (err) {\n if (err instanceof ConfigValidationError) {\n const formatted = formatConfigIssues(err.issues);\n throw new Error(`Configuration validation failed:\\n${formatted}`);\n }\n throw err;\n }\n const computerName = os.hostname();\n\n this.uniqueInstanceId = `${config.instanceId}-${computerName}-${OS.getUniqueComputerId()}`;\n this.config = config;\n\n // Configure logger with application settings\n if (this.config.log?.showRequestIdInConsole !== undefined) {\n Logger.configure({ showRequestIdInConsole: this.config.log.showRequestIdInConsole });\n }\n\n // Initialize lifecycle management\n const lifecycleConfig: Partial<LifecycleConfig> = {\n gracefulShutdown: {\n timeoutMs: this.shutdownTimeout,\n },\n readiness: {\n timeoutMs: 30000,\n checkIntervalMs: 100,\n },\n };\n this.lifecycle = new LifecycleManager(lifecycleConfig);\n this.shutdownController = new ShutdownController(this.lifecycle);\n\n // Register shutdown hooks for cleanup\n this.registerShutdownHooks();\n\n // Initialize Redis manager\n this.redisManager = new RedisManager({\n applicationConfig: this.config,\n host: this.config.redis.host,\n port: this.config.redis.port,\n password: this.config.redis.password,\n });\n\n // Initialize cache manager\n this.cacheManager = new CacheManager({\n redisManager: this.redisManager,\n });\n\n // Register performance monitor plugin (idempotent & opt-in)\n PerformanceMonitorPlugin.register(this);\n\n // Track instance and ensure global error handlers are registered once\n BaseApplication.registerInstance(this);\n\n if (this.config.database?.enabled === true) {\n const defaultEntitiesDirectory = join(this.config.rootDirectory, 'src', 'database', 'entities');\n\n if (!this.config.database.entitiesDirectory) {\n this.config.database.entitiesDirectory = defaultEntitiesDirectory;\n }\n\n if (!existsSync(this.config.database.entitiesDirectory)) {\n throw new Error(`Database entities directory not found (Path: ${this.config.database.entitiesDirectory})`);\n }\n\n // Initialize Database manager\n this.databaseManager = new DatabaseManager({\n applicationConfig: this.config,\n host: this.config.database.host,\n port: this.config.database.port,\n username: this.config.database.username,\n password: this.config.database.password,\n databaseName: this.config.database.databaseName,\n entitiesDirectory: this.config.database.entitiesDirectory,\n });\n }\n }\n\n /**\n * Get application version\n */\n public async getApplicationVersion(): Promise<string> {\n // Return cached version if available\n if (BaseApplication.applicationVersionCache !== undefined) {\n return BaseApplication.applicationVersionCache;\n }\n\n // Resolve the path to package.json\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = dirname(__filename);\n const packageJsonPath = resolve(__dirname, '../../package.json');\n\n // Read and parse the file\n const fileContents = readFileSync(packageJsonPath, 'utf-8');\n const packageJson = JSON.parse(fileContents);\n\n if (!packageJson?.version) {\n throw new Error('Application version not found');\n }\n\n // Cache and return the version\n BaseApplication.applicationVersionCache = packageJson.version;\n\n return packageJson.version;\n }\n\n /**\n * Start application\n */\n public async start(): Promise<void> {\n // Start application timer\n this.startTime = Time.now();\n\n // Get application version`\n this.applicationVersion = await this.getApplicationVersion();\n\n // Log initial startup message with version\n Logger.info({\n message: 'Starting application',\n meta: {\n Name: this.config.name,\n 'Instance ID': this.config.instanceId,\n 'PXL Framework Version': this.applicationVersion,\n },\n });\n\n const startInstanceOptions: ApplicationStartInstanceOptions = {\n onStarted: this.onStarted.bind(this),\n };\n\n const stopInstanceOptions: ApplicationStopInstanceOptions = {\n onStopped: this.onStopped.bind(this),\n };\n\n if (this.config.cluster?.enabled) {\n // Initialize clustered application\n const clusterManager = new ClusterManager({\n config: this.config.cluster,\n\n startApplicationCallback: () => this.startInstance(startInstanceOptions),\n stopApplicationCallback: () => this.stop(stopInstanceOptions),\n });\n\n // Start cluster\n clusterManager.start();\n } else {\n // Start standalone application\n await this.startInstance(startInstanceOptions);\n\n // Note: Signal handling should be implemented at the application launcher level\n // The lifecycle manager provides the stop() method for programmatic shutdown\n }\n }\n\n /**\n * Before application start\n */\n private async onBeforeStart(): Promise<{\n redisInstance: RedisInstance;\n databaseInstance: DatabaseInstance | null;\n queueManager: QueueManager;\n eventManager?: EventManager;\n }> {\n const phaseStartTime = Time.now();\n\n // Connect to Redis\n if (process.env.DEBUG_TESTS) {\n console.log('[BaseApplication] Connecting to Redis...');\n }\n const redisInstance = await this.redisManager.connect();\n if (process.env.DEBUG_TESTS) {\n const redisElapsed = Time.calculateElapsedTimeMs({ startTime: phaseStartTime });\n console.log(`[BaseApplication] Redis connected (${redisElapsed}ms)`);\n }\n\n // Connect to database\n let databaseInstance: DatabaseInstance | null = null;\n if (this.databaseManager) {\n if (process.env.DEBUG_TESTS) {\n console.log('[BaseApplication] Connecting to database...');\n }\n const dbStartTime = Time.now();\n databaseInstance = await this.databaseManager.connect();\n if (process.env.DEBUG_TESTS) {\n const dbElapsed = Time.calculateElapsedTimeMs({ startTime: dbStartTime });\n console.log(`[BaseApplication] Database connected (${dbElapsed}ms)`);\n }\n }\n\n let eventManager: EventManager | undefined;\n\n if (this.config.event?.enabled) {\n eventManager = new EventManager({\n applicationConfig: this.config,\n options: this.config.event,\n events: this.config.event.events || [],\n redisInstance,\n databaseInstance,\n // queueManager,\n });\n\n eventManager.load();\n }\n\n // Initialize queue\n const queueManager = new QueueManager({\n applicationConfig: this.config,\n options: {\n processorsDirectory: this.config.queue.processorsDirectory,\n },\n queues: this.config.queue.queues,\n redisInstance,\n databaseInstance,\n eventManager,\n });\n\n // Register queues\n await queueManager.registerQueues({\n queues: this.config.queue.queues,\n });\n\n // Register readiness checks for key services\n this.lifecycle.addReadinessCheck('redis', async () => {\n try {\n return await redisInstance.isConnected();\n } catch {\n return false;\n }\n });\n\n if (databaseInstance) {\n this.lifecycle.addReadinessCheck('database', async () => {\n try {\n return await databaseInstance.isConnected();\n } catch {\n return false;\n }\n });\n }\n\n return {\n redisInstance,\n databaseInstance,\n queueManager,\n eventManager,\n };\n }\n\n /**\n * Application started event\n */\n protected onStarted({ startupTime: _startupTime }: { startupTime: number }): void {}\n\n /**\n * Application stopped event\n */\n protected onStopped({ runtime: _runtime }: { runtime: number }): void {}\n\n /**\n * Start application instance\n */\n private async startInstance(options: ApplicationStartInstanceOptions): Promise<void> {\n try {\n // Phase 1: Initialize (resource setup)\n if (process.env.DEBUG_TESTS) {\n console.log('[startInstance] Phase 1: Initializing lifecycle...');\n }\n const initStartTime = Time.now();\n const initResult = await this.lifecycle.initialize();\n if (process.env.DEBUG_TESTS) {\n const initElapsed = Time.calculateElapsedTimeMs({ startTime: initStartTime });\n console.log(`[startInstance] Phase 1 complete (${initElapsed}ms)`);\n }\n if (initResult.errors.length > 0) {\n Logger.warn({\n message: 'Lifecycle init phase encountered errors',\n meta: { errors: initResult.errors.map(e => (e instanceof Error ? e.message : String(e))) },\n });\n }\n\n // Before application start\n if (process.env.DEBUG_TESTS) {\n console.log('[startInstance] Connecting to services (Redis, Database, Queue, Events)...');\n }\n const beforeStartTime = Time.now();\n const { redisInstance, databaseInstance, queueManager, eventManager } = await this.onBeforeStart();\n if (process.env.DEBUG_TESTS) {\n const beforeStartElapsed = Time.calculateElapsedTimeMs({ startTime: beforeStartTime });\n console.log(`[startInstance] Services connected (${beforeStartElapsed}ms)`);\n }\n\n // Phase 2: Start (component startup)\n if (process.env.DEBUG_TESTS) {\n console.log('[startInstance] Phase 2: Starting lifecycle components...');\n }\n const startStartTime = Time.now();\n const startResult = await this.lifecycle.start();\n if (process.env.DEBUG_TESTS) {\n const startElapsed = Time.calculateElapsedTimeMs({ startTime: startStartTime });\n console.log(`[startInstance] Phase 2 complete (${startElapsed}ms)`);\n }\n if (startResult.errors.length > 0) {\n Logger.warn({\n message: 'Lifecycle start phase encountered errors',\n meta: { errors: startResult.errors.map(e => (e instanceof Error ? e.message : String(e))) },\n });\n }\n\n // Start application\n if (process.env.DEBUG_TESTS) {\n console.log('[startInstance] Starting application handler...');\n }\n const handlerStartTime = Time.now();\n await this.startHandler({\n redisInstance,\n databaseInstance,\n queueManager,\n eventManager,\n });\n if (process.env.DEBUG_TESTS) {\n const handlerElapsed = Time.calculateElapsedTimeMs({ startTime: handlerStartTime });\n console.log(`[startInstance] Application handler started (${handlerElapsed}ms)`);\n }\n\n // Phase 3: Ready (application accepting traffic)\n if (process.env.DEBUG_TESTS) {\n console.log('[startInstance] Phase 3: Waiting for application to be ready...');\n }\n const readyStartTime = Time.now();\n const readyResult = await this.lifecycle.ready();\n if (process.env.DEBUG_TESTS) {\n const readyElapsed = Time.calculateElapsedTimeMs({ startTime: readyStartTime });\n console.log(`[startInstance] Phase 3 complete (${readyElapsed}ms)`);\n }\n if (readyResult.errors.length > 0) {\n Logger.warn({\n message: 'Lifecycle ready phase encountered errors',\n meta: { errors: readyResult.errors.map(e => (e instanceof Error ? e.message : String(e))) },\n });\n }\n\n // Calculate application startup time\n const startupTime = Time.calculateElapsedTimeMs({\n startTime: this.startTime,\n });\n\n // On application started\n if (options.onStarted) {\n await options.onStarted({ startupTime });\n }\n } catch (error) {\n Logger.error({\n error: error instanceof Error ? error : new Error(safeSerializeError(error)),\n message: 'startInstance failure',\n });\n throw error;\n }\n }\n\n protected abstract startHandler({\n redisInstance,\n databaseInstance,\n queueManager,\n eventManager,\n }: {\n redisInstance: RedisInstance;\n databaseInstance?: DatabaseInstance | null;\n queueManager: QueueManager;\n eventManager?: EventManager | null;\n }): Promise<void>;\n\n protected abstract stopCallback(): void;\n\n private static registerInstance(instance: BaseApplication): void {\n BaseApplication.pruneStaleInstances();\n BaseApplication.instances.add(new WeakRef(instance));\n BaseApplication.registerGlobalErrorHandlers();\n }\n\n private static unregisterInstance(instance: BaseApplication): void {\n for (const ref of Array.from(BaseApplication.instances)) {\n const current = ref.deref();\n if (!current || current === instance) {\n BaseApplication.instances.delete(ref);\n }\n }\n }\n\n private static pruneStaleInstances(): void {\n for (const ref of Array.from(BaseApplication.instances)) {\n if (!ref.deref()) {\n BaseApplication.instances.delete(ref);\n }\n }\n }\n\n private static getActiveInstances(): BaseApplication[] {\n const active: BaseApplication[] = [];\n const stale: WeakRef<BaseApplication>[] = [];\n\n for (const ref of BaseApplication.instances) {\n const instance = ref.deref();\n if (instance) {\n active.push(instance);\n } else {\n stale.push(ref);\n }\n }\n\n for (const ref of stale) {\n BaseApplication.instances.delete(ref);\n }\n\n return active;\n }\n\n private static registerGlobalErrorHandlers(): void {\n if (BaseApplication.globalErrorHandlersRegistered) {\n return;\n }\n\n process.on('uncaughtException', error => {\n Logger.error({ error, message: 'Uncaught Exception' });\n for (const app of BaseApplication.getActiveInstances()) {\n app.initiateGracefulShutdown();\n }\n });\n\n process.on('unhandledRejection', (reason, promise) => {\n Logger.error({\n error: reason instanceof Error ? reason : new Error(String(reason)),\n message: 'Unhandled Rejection',\n meta: { promise: String(promise) },\n });\n for (const app of BaseApplication.getActiveInstances()) {\n app.initiateGracefulShutdown();\n }\n });\n\n BaseApplication.globalErrorHandlersRegistered = true;\n }\n\n /**\n * Register shutdown hooks for proper cleanup\n */\n private registerShutdownHooks(): void {\n // Register shutdown hooks in reverse dependency order\n this.lifecycle.onShutdown(() => {\n BaseApplication.unregisterInstance(this);\n });\n\n this.lifecycle.onShutdown(async () => {\n Logger.info({ message: 'Executing custom stop callback' });\n await this.stopCallback();\n });\n\n this.lifecycle.onShutdown(async () => {\n if (this.redisManager) {\n Logger.info({ message: 'Disconnecting from Redis' });\n await this.redisManager.disconnect();\n }\n });\n\n this.lifecycle.onShutdown(async () => {\n if (this.databaseManager) {\n Logger.info({ message: 'Disconnecting from database' });\n await this.databaseManager.disconnect();\n }\n });\n\n // Performance monitor is handled via trackInterval, so it will be cleaned up automatically\n }\n\n /**\n * Initiate graceful shutdown\n */\n private async initiateGracefulShutdown(): Promise<void> {\n if (this.shutdownController.isShuttingDown) {\n return;\n }\n\n Logger.info({ message: 'Initiating graceful shutdown due to error' });\n try {\n const result = await this.shutdownController.initiate('error-triggered');\n if (result.errors.length > 0) {\n Logger.error({\n message: 'Errors during shutdown',\n error: result.errors,\n });\n this.finalizeExit({ code: 1, reason: 'graceful-shutdown-error', error: result.errors });\n } else if (result.timedOut) {\n Logger.warn({ message: 'Shutdown timed out' });\n this.finalizeExit({ code: 1, reason: 'shutdown-timeout' });\n } else {\n this.finalizeExit({ code: 0, reason: 'error-shutdown-complete' });\n }\n } catch (error) {\n Logger.error({\n error: error instanceof Error ? error : new Error(safeSerializeError(error)),\n message: 'Error during graceful shutdown',\n });\n this.finalizeExit({ code: 1, reason: 'graceful-shutdown-error', error });\n }\n }\n\n /**\n * Stop application using lifecycle manager\n */\n public async stop({ onStopped }: ApplicationStopInstanceOptions = {}): Promise<void> {\n if (this.shutdownController.isShuttingDown) {\n return;\n }\n\n // Register the onStopped callback if provided\n if (onStopped) {\n this.lifecycle.onShutdown(() => {\n const runtime = process.uptime() * 1000;\n onStopped({ runtime });\n });\n }\n\n try {\n const result = await this.shutdownController.initiate('manual-stop');\n if (result.errors.length > 0) {\n Logger.error({\n message: 'Errors during shutdown',\n error: result.errors,\n });\n this.finalizeExit({ code: 1, reason: 'shutdown-error', error: result.errors });\n } else if (result.timedOut) {\n Logger.warn({ message: 'Shutdown timed out' });\n this.finalizeExit({ code: 1, reason: 'shutdown-timeout' });\n } else {\n this.finalizeExit({ code: 0, reason: 'shutdown-complete' });\n }\n } catch (error) {\n Logger.error({\n error: error instanceof Error ? error : new Error(safeSerializeError(error)),\n message: 'Error during shutdown',\n });\n this.finalizeExit({ code: 1, reason: 'shutdown-error', error });\n }\n }\n\n /**\n * Finalize exit: during tests, suppress actual process exit to avoid failing vitest runs.\n */\n private finalizeExit(outcome: ExitOutcome): void {\n const nodeEnv = process.env.NODE_ENV ?? '';\n const isTestEnv =\n nodeEnv.toLowerCase() === 'test' ||\n 'VITEST' in process.env ||\n 'VITEST_WORKER_ID' in process.env ||\n process.argv.some(a => a.includes('vitest')) ||\n typeof (globalThis as any).afterAll === 'function';\n\n if (isTestEnv) {\n Logger.info({ message: `Skipping process exit in test environment (${outcome.reason})`, code: outcome.code });\n return;\n }\n requestExit(outcome);\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web-application.d.ts","sourceRoot":"","sources":["../../src/application/web-application.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,aAAa,MAAM,sBAAsB,CAAC;AACtD,OAAO,KAAK,gBAAgB,MAAM,yBAAyB,CAAC;AAC5D,OAAO,SAAS,MAAM,2BAA2B,CAAC;AAClD,OAAO,KAAK,YAAY,MAAM,qBAAqB,CAAC;AACpD,OAAO,eAAe,MAAM,uBAAuB,CAAC;AACpD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AAG3E,OAAO,eAAe,MAAM,kCAAkC,CAAC;AAC/D,OAAO,eAAe,MAAM,kCAAkC,CAAC;AAC/D,OAAO,KAAK,YAAY,MAAM,qBAAqB,CAAC;AAGpD;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,cAAe,SAAQ,eAAe;IACzD,6BAA6B;IAC7B,SAAS,CAAC,MAAM,EAAE,oBAAoB,CAAC;IAEvC,iBAAiB;IACV,SAAS,CAAC,EAAE,SAAS,CAAC;IAE7B,uBAAuB;IAChB,eAAe,CAAC,EAAE,eAAe,CAAC;IAEzC,uBAAuB;IAChB,eAAe,CAAC,EAAE,eAAe,CAAC;gBAE7B,MAAM,EAAE,oBAAoB;cAcxB,YAAY,CAAC,EAC3B,aAAa,EACb,gBAAgB,EAChB,YAAY,EACZ,YAAY,GACb,EAAE;QACD,aAAa,EAAE,aAAa,CAAC;QAC7B,gBAAgB,EAAE,gBAAgB,CAAC;QACnC,YAAY,EAAE,YAAY,CAAC;QAC3B,YAAY,EAAE,YAAY,CAAC;KAC5B,GAAG,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"web-application.d.ts","sourceRoot":"","sources":["../../src/application/web-application.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,aAAa,MAAM,sBAAsB,CAAC;AACtD,OAAO,KAAK,gBAAgB,MAAM,yBAAyB,CAAC;AAC5D,OAAO,SAAS,MAAM,2BAA2B,CAAC;AAClD,OAAO,KAAK,YAAY,MAAM,qBAAqB,CAAC;AACpD,OAAO,eAAe,MAAM,uBAAuB,CAAC;AACpD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AAG3E,OAAO,eAAe,MAAM,kCAAkC,CAAC;AAC/D,OAAO,eAAe,MAAM,kCAAkC,CAAC;AAC/D,OAAO,KAAK,YAAY,MAAM,qBAAqB,CAAC;AAGpD;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,cAAe,SAAQ,eAAe;IACzD,6BAA6B;IAC7B,SAAS,CAAC,MAAM,EAAE,oBAAoB,CAAC;IAEvC,iBAAiB;IACV,SAAS,CAAC,EAAE,SAAS,CAAC;IAE7B,uBAAuB;IAChB,eAAe,CAAC,EAAE,eAAe,CAAC;IAEzC,uBAAuB;IAChB,eAAe,CAAC,EAAE,eAAe,CAAC;gBAE7B,MAAM,EAAE,oBAAoB;cAcxB,YAAY,CAAC,EAC3B,aAAa,EACb,gBAAgB,EAChB,YAAY,EACZ,YAAY,GACb,EAAE;QACD,aAAa,EAAE,aAAa,CAAC;QAC7B,gBAAgB,EAAE,gBAAgB,CAAC;QACnC,YAAY,EAAE,YAAY,CAAC;QAC3B,YAAY,EAAE,YAAY,CAAC;KAC5B,GAAG,OAAO,CAAC,IAAI,CAAC;IAsHjB;;OAEG;cACa,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAY7C;;OAEG;cACa,SAAS,CAAC,EAAE,WAAW,EAAE,EAAE;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;cAuBlE,SAAS,CAAC,EAAE,OAAO,EAAE,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAqB3E"}
|
|
@@ -36,6 +36,7 @@ class WebApplication extends BaseApplication {
|
|
|
36
36
|
eventManager
|
|
37
37
|
}) {
|
|
38
38
|
if (this.config.webServer?.enabled) {
|
|
39
|
+
const staticRoutes = this.config.webServer.routes;
|
|
39
40
|
this.webServer = new WebServer({
|
|
40
41
|
applicationConfig: this.config,
|
|
41
42
|
options: {
|
|
@@ -48,7 +49,7 @@ class WebApplication extends BaseApplication {
|
|
|
48
49
|
log: this.config.webServer.log,
|
|
49
50
|
debug: this.config.webServer.debug
|
|
50
51
|
},
|
|
51
|
-
routes:
|
|
52
|
+
...Array.isArray(staticRoutes) ? { routes: staticRoutes } : {},
|
|
52
53
|
redisInstance,
|
|
53
54
|
databaseInstance,
|
|
54
55
|
queueManager,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/application/web-application.ts"],
|
|
4
|
-
"sourcesContent": ["import type RedisInstance from '../redis/instance.js';\nimport type DatabaseInstance from '../database/instance.js';\nimport WebServer from '../webserver/webserver.js';\nimport type QueueManager from '../queue/manager.js';\nimport BaseApplication from './base-application.js';\nimport type { WebApplicationConfig } from './web-application.interface.js';\nimport { Helper, Time } from '../util/index.js';\nimport { Logger } from '../logger/index.js';\nimport WebSocketServer from '../websocket/websocket-server.js';\nimport WebSocketClient from '../websocket/websocket-client.js';\nimport type EventManager from '../event/manager.js';\nimport { WebServerPerformanceWrapper, WebSocketPerformanceWrapper } from '../performance/index.js';\n\n/**\n * Application\n */\nexport default class WebApplication extends BaseApplication {\n /** Web application config */\n protected config: WebApplicationConfig;\n\n /** Web server */\n public webServer?: WebServer;\n\n /** WebSocket server */\n public webSocketServer?: WebSocketServer;\n\n /** WebSocket client */\n public webSocketClient?: WebSocketClient;\n\n constructor(config: WebApplicationConfig) {\n super(config);\n\n const defaultConfig: Partial<WebApplicationConfig> = {\n log: {\n startUp: true,\n },\n };\n\n const mergedConfig = Helper.defaultsDeep(config, defaultConfig);\n\n this.config = mergedConfig;\n }\n\n protected async startHandler({\n redisInstance,\n databaseInstance,\n queueManager,\n eventManager,\n }: {\n redisInstance: RedisInstance;\n databaseInstance: DatabaseInstance;\n queueManager: QueueManager;\n eventManager: EventManager;\n }): Promise<void> {\n if (this.config.webServer?.enabled) {\n // Initialize web server\n this.webServer = new WebServer({\n applicationConfig: this.config,\n options: {\n host: this.config.webServer.host,\n port: this.config.webServer.port,\n controllersDirectory: this.config.webServer.controllersDirectory,\n routesDirectory: this.config.webServer.routesDirectory,\n cors: this.config.webServer.cors,\n security: this.config.webServer.security,\n log: this.config.webServer.log,\n debug: this.config.webServer.debug,\n },\n\n routes:
|
|
5
|
-
"mappings": ";;AAEA,OAAO,eAAe;AAEtB,OAAO,qBAAqB;AAE5B,SAAS,QAAQ,YAAY;AAC7B,SAAS,cAAc;AACvB,OAAO,qBAAqB;AAC5B,OAAO,qBAAqB;AAE5B,SAAS,6BAA6B,mCAAmC;AAKzE,MAAO,uBAAqC,gBAAgB;AAAA,EAhB5D,OAgB4D;AAAA;AAAA;AAAA;AAAA,EAEhD;AAAA;AAAA,EAGH;AAAA;AAAA,EAGA;AAAA;AAAA,EAGA;AAAA,EAEP,YAAY,QAA8B;AACxC,UAAM,MAAM;AAEZ,UAAM,gBAA+C;AAAA,MACnD,KAAK;AAAA,QACH,SAAS;AAAA,MACX;AAAA,IACF;AAEA,UAAM,eAAe,OAAO,aAAa,QAAQ,aAAa;AAE9D,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,MAAgB,aAAa;AAAA,IAC3B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAKkB;AAChB,QAAI,KAAK,OAAO,WAAW,SAAS;
|
|
4
|
+
"sourcesContent": ["import type RedisInstance from '../redis/instance.js';\nimport type DatabaseInstance from '../database/instance.js';\nimport WebServer from '../webserver/webserver.js';\nimport type QueueManager from '../queue/manager.js';\nimport BaseApplication from './base-application.js';\nimport type { WebApplicationConfig } from './web-application.interface.js';\nimport { Helper, Time } from '../util/index.js';\nimport { Logger } from '../logger/index.js';\nimport WebSocketServer from '../websocket/websocket-server.js';\nimport WebSocketClient from '../websocket/websocket-client.js';\nimport type EventManager from '../event/manager.js';\nimport { WebServerPerformanceWrapper, WebSocketPerformanceWrapper } from '../performance/index.js';\n\n/**\n * Application\n */\nexport default class WebApplication extends BaseApplication {\n /** Web application config */\n protected config: WebApplicationConfig;\n\n /** Web server */\n public webServer?: WebServer;\n\n /** WebSocket server */\n public webSocketServer?: WebSocketServer;\n\n /** WebSocket client */\n public webSocketClient?: WebSocketClient;\n\n constructor(config: WebApplicationConfig) {\n super(config);\n\n const defaultConfig: Partial<WebApplicationConfig> = {\n log: {\n startUp: true,\n },\n };\n\n const mergedConfig = Helper.defaultsDeep(config, defaultConfig);\n\n this.config = mergedConfig;\n }\n\n protected async startHandler({\n redisInstance,\n databaseInstance,\n queueManager,\n eventManager,\n }: {\n redisInstance: RedisInstance;\n databaseInstance: DatabaseInstance;\n queueManager: QueueManager;\n eventManager: EventManager;\n }): Promise<void> {\n if (this.config.webServer?.enabled) {\n const staticRoutes = this.config.webServer.routes;\n\n // Initialize web server\n this.webServer = new WebServer({\n applicationConfig: this.config,\n options: {\n host: this.config.webServer.host,\n port: this.config.webServer.port,\n controllersDirectory: this.config.webServer.controllersDirectory,\n routesDirectory: this.config.webServer.routesDirectory,\n cors: this.config.webServer.cors,\n security: this.config.webServer.security,\n log: this.config.webServer.log,\n debug: this.config.webServer.debug,\n },\n\n ...(Array.isArray(staticRoutes) ? { routes: staticRoutes } : {}),\n\n redisInstance,\n databaseInstance,\n queueManager,\n eventManager,\n lifecycleManager: this.lifecycle,\n });\n\n // Set up performance monitoring for web server\n if (this.performanceMonitor && this.config.performanceMonitoring?.monitorHttpRequests !== false) {\n WebServerPerformanceWrapper.setPerformanceMonitor(this.performanceMonitor);\n }\n\n // Load web server\n await this.webServer.load();\n\n // Start web server\n await this.webServer.start();\n\n // Register readiness check for web server\n this.lifecycle.addReadinessCheck('webserver', async () => {\n try {\n return this.webServer?.isReady() ?? false;\n } catch {\n return false;\n }\n });\n }\n\n if (this.config.webSocket?.enabled) {\n if (!this.webServer) {\n throw new Error('WebSocket requires web server to be enabled');\n }\n\n let webSocketServer: WebSocketServer | undefined;\n let webSocketClient: WebSocketClient | undefined;\n\n switch (this.config.webSocket.type) {\n case 'server': {\n // Initialize WebSocket server\n webSocketServer = new WebSocketServer({\n uniqueInstanceId: this.uniqueInstanceId,\n applicationConfig: this.config,\n options: this.config.webSocket,\n redisInstance,\n databaseInstance,\n queueManager,\n routes: this.config.webSocket.routes,\n workerId: this.workerId,\n });\n\n // Set up performance monitoring for WebSocket\n if (this.performanceMonitor && this.config.performanceMonitoring?.monitorWebSocketOperations !== false) {\n WebSocketPerformanceWrapper.setPerformanceMonitor(this.performanceMonitor);\n }\n\n // Load WebSocket client\n await webSocketServer.load();\n\n // Start WebSocket server\n await webSocketServer.start({\n fastifyServer: this.webServer.fastifyServer,\n });\n\n break;\n }\n case 'client': {\n // Initialize WebSocket client\n webSocketClient = new WebSocketClient({\n applicationConfig: this.config,\n options: this.config.webSocket,\n redisInstance,\n databaseInstance,\n queueManager,\n routes: this.config.webSocket.routes,\n });\n\n // Load WebSocket client\n await webSocketClient.load();\n\n // Connect to WebSocket server\n await webSocketClient.connectToServer();\n\n break;\n }\n default: {\n if (!this.config.webSocket.type) {\n throw new Error('WebSocket type is required');\n } else {\n throw new Error(`WebSocket type is not supported (Type: ${this.config.webSocket.type})`);\n }\n }\n }\n\n this.webSocketServer = webSocketServer;\n this.webSocketClient = webSocketClient;\n }\n }\n\n /**\n * Stop application callback\n */\n protected async stopCallback(): Promise<void> {\n if (this.webServer) {\n // Stop web server\n await this.webServer.stop();\n }\n\n if (this.webSocketServer) {\n // Stop WebSocket server\n await this.webSocketServer.stop();\n }\n }\n\n /**\n * Application started event\n */\n protected async onStarted({ startupTime }: { startupTime: number }): Promise<void> {\n if (this.config.log?.startUp) {\n Logger.info({\n message: 'Application started',\n meta: {\n 'Startup Time': Time.formatTime({\n time: startupTime,\n format: 's',\n numDecimals: 2,\n showUnit: true,\n }),\n },\n });\n }\n\n if (this.config.events?.onStarted) {\n this.config.events.onStarted({\n app: this,\n startupTime,\n });\n }\n }\n\n protected async onStopped({ runtime }: { runtime: number }): Promise<void> {\n if (this.config.log?.shutdown) {\n Logger.info({\n message: 'Application stopped',\n meta: {\n Name: this.config.name,\n 'Instance ID': this.config.instanceId,\n Runtime: Time.formatTime({\n time: runtime,\n format: 's',\n numDecimals: 2,\n showUnit: true,\n }),\n },\n });\n }\n\n if (this.config.events?.onStopped) {\n this.config.events.onStopped({ app: this, runtime });\n }\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/cache/manager.d.ts
CHANGED
|
@@ -37,6 +37,7 @@ export interface CacheManagerProps {
|
|
|
37
37
|
export default class CacheManager {
|
|
38
38
|
private redisManager;
|
|
39
39
|
private redisInstance?;
|
|
40
|
+
private redisInstancePromise?;
|
|
40
41
|
constructor({ redisManager }: CacheManagerProps);
|
|
41
42
|
/**
|
|
42
43
|
* Ensure we have a connected RedisInstance. Reuses the first existing
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/cache/manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,YAAY,MAAM,qBAAqB,CAAC;AAIpD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,MAAM,WAAW,iBAAiB;IAChC,oDAAoD;IACpD,YAAY,EAAE,YAAY,CAAC;CAC5B;AAED,MAAM,CAAC,OAAO,OAAO,YAAY;IAC/B,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,aAAa,CAAC,CAAgB;
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/cache/manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,YAAY,MAAM,qBAAqB,CAAC;AAIpD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,MAAM,WAAW,iBAAiB;IAChC,oDAAoD;IACpD,YAAY,EAAE,YAAY,CAAC;CAC5B;AAED,MAAM,CAAC,OAAO,OAAO,YAAY;IAC/B,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,aAAa,CAAC,CAAgB;IACtC,OAAO,CAAC,oBAAoB,CAAC,CAAyB;gBAE1C,EAAE,YAAY,EAAE,EAAE,iBAAiB;IAI/C;;;OAGG;YACW,gBAAgB;IAyB9B;;;;;;;;;;;;;;OAcG;IACU,OAAO,CAAC,CAAC,EAAE,EAAE,GAAG,EAAE,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IAkBpE;;;;;;;;;;;;;;;;;;;OAmBG;IACU,OAAO,CAAC,CAAC,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,CAAC,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAK9G;;;;;;;;;OASG;IACU,SAAS,CAAC,EAAE,GAAG,EAAE,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAK/D;;OAEG;IACU,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAGpC"}
|
package/dist/cache/manager.js
CHANGED
|
@@ -7,6 +7,7 @@ class CacheManager {
|
|
|
7
7
|
}
|
|
8
8
|
redisManager;
|
|
9
9
|
redisInstance;
|
|
10
|
+
redisInstancePromise;
|
|
10
11
|
constructor({ redisManager }) {
|
|
11
12
|
this.redisManager = redisManager;
|
|
12
13
|
}
|
|
@@ -16,12 +17,20 @@ class CacheManager {
|
|
|
16
17
|
*/
|
|
17
18
|
async getRedisInstance() {
|
|
18
19
|
if (this.redisInstance) return this.redisInstance;
|
|
20
|
+
if (this.redisInstancePromise) return this.redisInstancePromise;
|
|
19
21
|
if (this.redisManager.instances.length > 0) {
|
|
20
22
|
this.redisInstance = this.redisManager.instances[0];
|
|
21
23
|
return this.redisInstance;
|
|
22
24
|
}
|
|
23
|
-
this.
|
|
24
|
-
|
|
25
|
+
this.redisInstancePromise = this.redisManager.connect().then((instance) => {
|
|
26
|
+
this.redisInstance = instance;
|
|
27
|
+
this.redisInstancePromise = void 0;
|
|
28
|
+
return instance;
|
|
29
|
+
}).catch((error) => {
|
|
30
|
+
this.redisInstancePromise = void 0;
|
|
31
|
+
throw error;
|
|
32
|
+
});
|
|
33
|
+
return this.redisInstancePromise;
|
|
25
34
|
}
|
|
26
35
|
/**
|
|
27
36
|
* Get a cached JSON value (deserialized) or null if not present.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/cache/manager.ts"],
|
|
4
|
-
"sourcesContent": ["import type RedisManager from '../redis/manager.js';\nimport type RedisInstance from '../redis/instance.js';\nimport { safeSerializeError } from '../error/error-reporter.js';\n\n/**\n * CacheManager\n *\n * Thin abstraction over Redis for basic JSON value caching. Unifies all Redis\n * access through the framework RedisManager / RedisInstance (ioredis) so we\n * avoid maintaining a second client implementation (node-redis).\n *\n * Lazy acquisition: the first call to any cache method will either reuse an\n * existing connected RedisInstance (if already established by application\n * startup) or trigger a connection via RedisManager.\n *\n * **Important:** All values are stored as JSON strings. Only JSON-serializable\n * values are supported. Complex types like Date, Map, Set, RegExp, etc. will\n * lose their type information during serialization:\n * - `Date` objects \u2192 ISO strings\n * - `Map` / `Set` \u2192 empty objects `{}`\n * - `undefined` \u2192 omitted from objects, `null` in arrays\n * - Functions \u2192 omitted\n *\n * @example\n * ```typescript\n * // Supported types\n * await cache.setItem({ key: 'user', value: { id: 1, name: 'John' } }); // \u2713\n * await cache.setItem({ key: 'count', value: 42 }); // \u2713\n * await cache.setItem({ key: 'tags', value: ['a', 'b', 'c'] }); // \u2713\n *\n * // Unsupported types (will lose type information)\n * await cache.setItem({ key: 'date', value: new Date() }); // \u2192 ISO string\n * await cache.setItem({ key: 'map', value: new Map() }); // \u2192 {}\n * ```\n */\n\nexport interface CacheManagerProps {\n /** Redis manager (shared across the application) */\n redisManager: RedisManager;\n}\n\nexport default class CacheManager {\n private redisManager: RedisManager;\n private redisInstance?: RedisInstance;\n\n constructor({ redisManager }: CacheManagerProps) {\n this.redisManager = redisManager;\n }\n\n /**\n * Ensure we have a connected RedisInstance. Reuses the first existing\n * instance if already connected by the application bootstrap.\n */\n private async getRedisInstance(): Promise<RedisInstance> {\n if (this.redisInstance) return this.redisInstance;\n\n if (this.redisManager.instances.length > 0) {\n this.redisInstance = this.redisManager.instances[0];\n return this.redisInstance;\n }\n\n // Lazily connect if no instances yet (e.g., used before app onBeforeStart)\n this.
|
|
5
|
-
"mappings": ";;AAEA,SAAS,0BAA0B;AAuCnC,MAAO,aAA2B;AAAA,EAzClC,OAyCkC;AAAA;AAAA;AAAA,EACxB;AAAA,EACA;AAAA,EAER,YAAY,EAAE,aAAa,GAAsB;AAC/C,SAAK,eAAe;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,mBAA2C;AACvD,QAAI,KAAK,cAAe,QAAO,KAAK;
|
|
4
|
+
"sourcesContent": ["import type RedisManager from '../redis/manager.js';\nimport type RedisInstance from '../redis/instance.js';\nimport { safeSerializeError } from '../error/error-reporter.js';\n\n/**\n * CacheManager\n *\n * Thin abstraction over Redis for basic JSON value caching. Unifies all Redis\n * access through the framework RedisManager / RedisInstance (ioredis) so we\n * avoid maintaining a second client implementation (node-redis).\n *\n * Lazy acquisition: the first call to any cache method will either reuse an\n * existing connected RedisInstance (if already established by application\n * startup) or trigger a connection via RedisManager.\n *\n * **Important:** All values are stored as JSON strings. Only JSON-serializable\n * values are supported. Complex types like Date, Map, Set, RegExp, etc. will\n * lose their type information during serialization:\n * - `Date` objects \u2192 ISO strings\n * - `Map` / `Set` \u2192 empty objects `{}`\n * - `undefined` \u2192 omitted from objects, `null` in arrays\n * - Functions \u2192 omitted\n *\n * @example\n * ```typescript\n * // Supported types\n * await cache.setItem({ key: 'user', value: { id: 1, name: 'John' } }); // \u2713\n * await cache.setItem({ key: 'count', value: 42 }); // \u2713\n * await cache.setItem({ key: 'tags', value: ['a', 'b', 'c'] }); // \u2713\n *\n * // Unsupported types (will lose type information)\n * await cache.setItem({ key: 'date', value: new Date() }); // \u2192 ISO string\n * await cache.setItem({ key: 'map', value: new Map() }); // \u2192 {}\n * ```\n */\n\nexport interface CacheManagerProps {\n /** Redis manager (shared across the application) */\n redisManager: RedisManager;\n}\n\nexport default class CacheManager {\n private redisManager: RedisManager;\n private redisInstance?: RedisInstance;\n private redisInstancePromise?: Promise<RedisInstance>;\n\n constructor({ redisManager }: CacheManagerProps) {\n this.redisManager = redisManager;\n }\n\n /**\n * Ensure we have a connected RedisInstance. Reuses the first existing\n * instance if already connected by the application bootstrap.\n */\n private async getRedisInstance(): Promise<RedisInstance> {\n if (this.redisInstance) return this.redisInstance;\n if (this.redisInstancePromise) return this.redisInstancePromise;\n\n if (this.redisManager.instances.length > 0) {\n this.redisInstance = this.redisManager.instances[0];\n return this.redisInstance;\n }\n\n // Lazily connect if no instances yet (e.g., used before app onBeforeStart)\n this.redisInstancePromise = this.redisManager\n .connect()\n .then(instance => {\n this.redisInstance = instance;\n this.redisInstancePromise = undefined;\n return instance;\n })\n .catch(error => {\n this.redisInstancePromise = undefined;\n throw error;\n });\n\n return this.redisInstancePromise;\n }\n\n /**\n * Get a cached JSON value (deserialized) or null if not present.\n *\n * @param key - Cache key\n * @returns Deserialized value or null if not found\n * @throws {Error} If the cached value is not valid JSON\n *\n * @example\n * ```typescript\n * const user = await cache.getItem<{ id: number; name: string }>({ key: 'user:123' });\n * if (user) {\n * console.log(user.name);\n * }\n * ```\n */\n public async getItem<T>({ key }: { key: string }): Promise<T | null> {\n const instance = await this.getRedisInstance();\n const raw = await instance.getCache({ key });\n if (raw === null) return null;\n\n // Validate that we received a string (Redis should always return string or null)\n if (typeof raw !== 'string') {\n throw new Error(`Cache value for key \"${key}\" must be a string, got ${typeof raw}`);\n }\n\n try {\n return JSON.parse(raw) as T;\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : safeSerializeError(error);\n throw new Error(`Failed to parse cached value for key \"${key}\": ${errorMessage}`);\n }\n }\n\n /**\n * Set a JSON-serializable value. Optionally specify lifetime (seconds).\n *\n * @param key - Cache key\n * @param value - Value to cache (must be JSON-serializable)\n * @param lifetime - Optional expiration in seconds\n *\n * @example\n * ```typescript\n * // Cache with no expiration\n * await cache.setItem({ key: 'config', value: { theme: 'dark' } });\n *\n * // Cache with 1 hour expiration\n * await cache.setItem({\n * key: 'session:abc',\n * value: { userId: 123 },\n * lifetime: 3600\n * });\n * ```\n */\n public async setItem<T>({ key, value, lifetime }: { key: string; value: T; lifetime?: number }): Promise<void> {\n const instance = await this.getRedisInstance();\n await instance.setCache({ key, value, expiration: lifetime });\n }\n\n /**\n * Delete a cached value.\n *\n * @param key - Cache key to delete\n *\n * @example\n * ```typescript\n * await cache.clearItem({ key: 'session:abc' });\n * ```\n */\n public async clearItem({ key }: { key: string }): Promise<void> {\n const instance = await this.getRedisInstance();\n await instance.deleteCache({ key });\n }\n\n /**\n * No-op: lifecycle handles Redis disconnection globally.\n */\n public async close(): Promise<void> {\n // Intentionally empty; RedisManager handles disconnect.\n }\n}\n"],
|
|
5
|
+
"mappings": ";;AAEA,SAAS,0BAA0B;AAuCnC,MAAO,aAA2B;AAAA,EAzClC,OAyCkC;AAAA;AAAA;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EAER,YAAY,EAAE,aAAa,GAAsB;AAC/C,SAAK,eAAe;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,mBAA2C;AACvD,QAAI,KAAK,cAAe,QAAO,KAAK;AACpC,QAAI,KAAK,qBAAsB,QAAO,KAAK;AAE3C,QAAI,KAAK,aAAa,UAAU,SAAS,GAAG;AAC1C,WAAK,gBAAgB,KAAK,aAAa,UAAU,CAAC;AAClD,aAAO,KAAK;AAAA,IACd;AAGA,SAAK,uBAAuB,KAAK,aAC9B,QAAQ,EACR,KAAK,cAAY;AAChB,WAAK,gBAAgB;AACrB,WAAK,uBAAuB;AAC5B,aAAO;AAAA,IACT,CAAC,EACA,MAAM,WAAS;AACd,WAAK,uBAAuB;AAC5B,YAAM;AAAA,IACR,CAAC;AAEH,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBA,MAAa,QAAW,EAAE,IAAI,GAAuC;AACnE,UAAM,WAAW,MAAM,KAAK,iBAAiB;AAC7C,UAAM,MAAM,MAAM,SAAS,SAAS,EAAE,IAAI,CAAC;AAC3C,QAAI,QAAQ,KAAM,QAAO;AAGzB,QAAI,OAAO,QAAQ,UAAU;AAC3B,YAAM,IAAI,MAAM,wBAAwB,GAAG,2BAA2B,OAAO,GAAG,EAAE;AAAA,IACpF;AAEA,QAAI;AACF,aAAO,KAAK,MAAM,GAAG;AAAA,IACvB,SAAS,OAAO;AACd,YAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,mBAAmB,KAAK;AACtF,YAAM,IAAI,MAAM,yCAAyC,GAAG,MAAM,YAAY,EAAE;AAAA,IAClF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAsBA,MAAa,QAAW,EAAE,KAAK,OAAO,SAAS,GAAgE;AAC7G,UAAM,WAAW,MAAM,KAAK,iBAAiB;AAC7C,UAAM,SAAS,SAAS,EAAE,KAAK,OAAO,YAAY,SAAS,CAAC;AAAA,EAC9D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAa,UAAU,EAAE,IAAI,GAAmC;AAC9D,UAAM,WAAW,MAAM,KAAK,iBAAiB;AAC7C,UAAM,SAAS,YAAY,EAAE,IAAI,CAAC;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA,EAKA,MAAa,QAAuB;AAAA,EAEpC;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|