@scpxl/nodejs-framework 1.0.30 → 1.0.42

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/README.md +1 -0
  2. package/dist/application/base-application.d.ts +7 -7
  3. package/dist/application/base-application.d.ts.map +1 -1
  4. package/dist/application/base-application.interface.d.ts +1 -1
  5. package/dist/application/base-application.interface.d.ts.map +1 -1
  6. package/dist/application/base-application.js +122 -14
  7. package/dist/application/base-application.js.map +2 -2
  8. package/dist/application/web-application.d.ts.map +1 -1
  9. package/dist/application/web-application.js +2 -4
  10. package/dist/application/web-application.js.map +2 -2
  11. package/dist/cache/manager.d.ts +1 -0
  12. package/dist/cache/manager.d.ts.map +1 -1
  13. package/dist/cache/manager.js +11 -2
  14. package/dist/cache/manager.js.map +2 -2
  15. package/dist/cli/index.js +24 -10
  16. package/dist/cli/index.js.map +2 -2
  17. package/dist/config/schema.d.ts +2 -63
  18. package/dist/config/schema.d.ts.map +1 -1
  19. package/dist/config/schema.js +1 -7
  20. package/dist/config/schema.js.map +2 -2
  21. package/dist/event/manager.js +2 -2
  22. package/dist/event/manager.js.map +2 -2
  23. package/dist/logger/logger.js +0 -1
  24. package/dist/logger/logger.js.map +2 -2
  25. package/dist/queue/manager.d.ts.map +1 -1
  26. package/dist/queue/manager.js +19 -7
  27. package/dist/queue/manager.js.map +2 -2
  28. package/dist/redis/instance.d.ts.map +1 -1
  29. package/dist/redis/instance.js +9 -1
  30. package/dist/redis/instance.js.map +2 -2
  31. package/dist/redis/manager.d.ts.map +1 -1
  32. package/dist/redis/manager.js +26 -16
  33. package/dist/redis/manager.js.map +3 -3
  34. package/dist/webserver/controller/entity.js +1 -1
  35. package/dist/webserver/controller/entity.js.map +2 -2
  36. package/dist/webserver/controller/health.js.map +1 -1
  37. package/dist/webserver/util.d.ts +1 -1
  38. package/dist/webserver/util.d.ts.map +1 -1
  39. package/dist/webserver/util.js +5 -23
  40. package/dist/webserver/util.js.map +2 -2
  41. package/dist/webserver/webserver.d.ts +2 -13
  42. package/dist/webserver/webserver.d.ts.map +1 -1
  43. package/dist/webserver/webserver.interface.d.ts +1 -21
  44. package/dist/webserver/webserver.interface.d.ts.map +1 -1
  45. package/dist/webserver/webserver.interface.js.map +1 -1
  46. package/dist/webserver/webserver.js +34 -36
  47. package/dist/webserver/webserver.js.map +2 -2
  48. package/dist/websocket/utils.d.ts.map +1 -1
  49. package/dist/websocket/utils.js +5 -1
  50. package/dist/websocket/utils.js.map +2 -2
  51. package/dist/websocket/websocket-base.d.ts.map +1 -1
  52. package/dist/websocket/websocket-base.js +9 -1
  53. package/dist/websocket/websocket-base.js.map +2 -2
  54. package/dist/websocket/websocket-server.d.ts.map +1 -1
  55. package/dist/websocket/websocket-server.js.map +2 -2
  56. package/package.json +5 -6
package/README.md CHANGED
@@ -4,6 +4,7 @@
4
4
  [![Node.js Version](https://img.shields.io/node/v/@scpxl/nodejs-framework.svg)](https://nodejs.org)
5
5
  [![License: ISC](https://img.shields.io/badge/License-ISC-blue.svg)](https://opensource.org/licenses/ISC)
6
6
  [![TypeScript](https://img.shields.io/badge/TypeScript-5.8-blue.svg)](https://www.typescriptlang.org/)
7
+ [![Coverage](https://img.shields.io/badge/Coverage-81%25-yellowgreen.svg)](#testing)
7
8
 
8
9
  A comprehensive, production-ready Node.js framework for building modern applications with built-in support for web servers, databases, queues, caching, WebSockets, and more.
9
10
 
@@ -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
- * Set up global error handlers
84
- */
85
- /**
86
- * Initialize performance monitor
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;IAE3D,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;IAmCnC;;OAEG;YACW,aAAa;IAuE3B;;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;IA0D3B,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;;OAEG;IACH;;OAEG;IAIH,OAAO,CAAC,wBAAwB;IAkBhC;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAwB7B;;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"}
1
+ {"version":3,"file":"base-application.d.ts","sourceRoot":"","sources":["../../src/application/base-application.ts"],"names":[],"mappings":"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"}
@@ -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: WebServerRoute[];
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
- this.setupGlobalErrorHandlers();
102
- if (this.config.database && this.config.database.enabled === true) {
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;
@@ -142,6 +144,14 @@ ${formatted}`);
142
144
  async start() {
143
145
  this.startTime = Time.now();
144
146
  this.applicationVersion = await this.getApplicationVersion();
147
+ Logger.info({
148
+ message: "Starting application",
149
+ meta: {
150
+ Name: this.config.name,
151
+ "Instance ID": this.config.instanceId,
152
+ "PXL Framework Version": this.applicationVersion
153
+ }
154
+ });
145
155
  const startInstanceOptions = {
146
156
  onStarted: this.onStarted.bind(this)
147
157
  };
@@ -163,8 +173,27 @@ ${formatted}`);
163
173
  * Before application start
164
174
  */
165
175
  async onBeforeStart() {
176
+ const phaseStartTime = Time.now();
177
+ if (process.env.DEBUG_TESTS) {
178
+ console.log("[BaseApplication] Connecting to Redis...");
179
+ }
166
180
  const redisInstance = await this.redisManager.connect();
167
- const databaseInstance = this.databaseManager ? await this.databaseManager.connect() : null;
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
+ }
168
197
  let eventManager;
169
198
  if (this.config.event?.enabled) {
170
199
  eventManager = new EventManager({
@@ -228,28 +257,68 @@ ${formatted}`);
228
257
  */
229
258
  async startInstance(options) {
230
259
  try {
260
+ if (process.env.DEBUG_TESTS) {
261
+ console.log("[startInstance] Phase 1: Initializing lifecycle...");
262
+ }
263
+ const initStartTime = Time.now();
231
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
+ }
232
269
  if (initResult.errors.length > 0) {
233
270
  Logger.warn({
234
271
  message: "Lifecycle init phase encountered errors",
235
272
  meta: { errors: initResult.errors.map((e) => e instanceof Error ? e.message : String(e)) }
236
273
  });
237
274
  }
275
+ if (process.env.DEBUG_TESTS) {
276
+ console.log("[startInstance] Connecting to services (Redis, Database, Queue, Events)...");
277
+ }
278
+ const beforeStartTime = Time.now();
238
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();
239
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
+ }
240
293
  if (startResult.errors.length > 0) {
241
294
  Logger.warn({
242
295
  message: "Lifecycle start phase encountered errors",
243
296
  meta: { errors: startResult.errors.map((e) => e instanceof Error ? e.message : String(e)) }
244
297
  });
245
298
  }
299
+ if (process.env.DEBUG_TESTS) {
300
+ console.log("[startInstance] Starting application handler...");
301
+ }
302
+ const handlerStartTime = Time.now();
246
303
  await this.startHandler({
247
304
  redisInstance,
248
305
  databaseInstance,
249
306
  queueManager,
250
307
  eventManager
251
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();
252
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
+ }
253
322
  if (readyResult.errors.length > 0) {
254
323
  Logger.warn({
255
324
  message: "Lifecycle ready phase encountered errors",
@@ -270,18 +339,51 @@ ${formatted}`);
270
339
  throw error;
271
340
  }
272
341
  }
273
- /**
274
- * Set up global error handlers
275
- */
276
- /**
277
- * Initialize performance monitor
278
- */
279
- // initializePerformanceMonitor deprecated in favor of PerformanceMonitorPlugin
280
- // (left intentionally absent)
281
- setupGlobalErrorHandlers() {
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
+ }
282
382
  process.on("uncaughtException", (error) => {
283
383
  Logger.error({ error, message: "Uncaught Exception" });
284
- this.initiateGracefulShutdown();
384
+ for (const app of BaseApplication.getActiveInstances()) {
385
+ app.initiateGracefulShutdown();
386
+ }
285
387
  });
286
388
  process.on("unhandledRejection", (reason, promise) => {
287
389
  Logger.error({
@@ -289,13 +391,19 @@ ${formatted}`);
289
391
  message: "Unhandled Rejection",
290
392
  meta: { promise: String(promise) }
291
393
  });
292
- this.initiateGracefulShutdown();
394
+ for (const app of BaseApplication.getActiveInstances()) {
395
+ app.initiateGracefulShutdown();
396
+ }
293
397
  });
398
+ BaseApplication.globalErrorHandlersRegistered = true;
294
399
  }
295
400
  /**
296
401
  * Register shutdown hooks for proper cleanup
297
402
  */
298
403
  registerShutdownHooks() {
404
+ this.lifecycle.onShutdown(() => {
405
+ BaseApplication.unregisterInstance(this);
406
+ });
299
407
  this.lifecycle.onShutdown(async () => {
300
408
  Logger.info({ message: "Executing custom stop callback" });
301
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 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": ";;AAAA,OAAO,aAAa;AACpB,SAAS,YAAY,oBAAoB;AACzC,SAAS,qBAAqB;AAC9B,SAAS,SAAS,MAAM,eAAe;AACvC,SAAgC,uBAAuB;AACvD,OAAO,kBAAkB;AACzB,OAAO,kBAAkB;AAMzB,OAAO,oBAAoB;AAE3B,SAAS,IAAI,YAAY;AACzB,OAAO,kBAAkB;AACzB,OAAO,QAAQ;AACf,OAAO,kBAAkB;AACzB,OAAO,YAAY;AAGnB,SAAS,gCAAgC;AACzC,SAA+B,kBAAkB,0BAA0B;AAC3E,SAAS,uBAAuB,oBAAoB,+BAA+B;AACnF,SAA2B,mBAAmB;AAC9C,SAAS,0BAA0B;AAKnC,MAAO,gBAAuC;AAAA,EA9B9C,OA8B8C;AAAA;AAAA;AAAA;AAAA,EAErC;AAAA;AAAA,EAGG,YAAoB;AAAA;AAAA,EAGpB,kBAAkB;AAAA;AAAA,EAG5B,OAAe;AAAA,EACf,OAAe,gCAAgC;AAAA,EAC/C,OAAwB,YAAY,oBAAI,IAA8B;AAAA;AAAA,EAG5D,WAAW,QAAQ,YAAY,QAAQ,SAAS,QAAQ,OAAO,KAAK;AAAA;AAAA,EAGpE;AAAA;AAAA,EAGA;AAAA;AAAA,EAGH;AAAA;AAAA,EAGA;AAAA;AAAA,EAGA;AAAA;AAAA,EAGA;AAAA;AAAA,EAGA;AAAA;AAAA,EAGA;AAAA;AAAA,EAGA;AAAA;AAAA,EAGA;AAAA,EAEP,IAAW,OAAO;AAChB,WAAO,KAAK,OAAO;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA,EAKA,YAAY,QAA2B;AAErC,QAAI;AACF,YAAM,YAAY,wBAAwB,MAAa;AACvD,eAAS;AAAA,IACX,SAAS,KAAK;AACZ,UAAI,eAAe,uBAAuB;AACxC,cAAM,YAAY,mBAAmB,IAAI,MAAM;AAC/C,cAAM,IAAI,MAAM;AAAA,EAAqC,SAAS,EAAE;AAAA,MAClE;AACA,YAAM;AAAA,IACR;AACA,UAAM,eAAe,GAAG,SAAS;AAEjC,SAAK,mBAAmB,GAAG,OAAO,UAAU,IAAI,YAAY,IAAI,GAAG,oBAAoB,CAAC;AACxF,SAAK,SAAS;AAGd,QAAI,KAAK,OAAO,KAAK,2BAA2B,QAAW;AACzD,aAAO,UAAU,EAAE,wBAAwB,KAAK,OAAO,IAAI,uBAAuB,CAAC;AAAA,IACrF;AAGA,UAAM,kBAA4C;AAAA,MAChD,kBAAkB;AAAA,QAChB,WAAW,KAAK;AAAA,MAClB;AAAA,MACA,WAAW;AAAA,QACT,WAAW;AAAA,QACX,iBAAiB;AAAA,MACnB;AAAA,IACF;AACA,SAAK,YAAY,IAAI,iBAAiB,eAAe;AACrD,SAAK,qBAAqB,IAAI,mBAAmB,KAAK,SAAS;AAG/D,SAAK,sBAAsB;AAG3B,SAAK,eAAe,IAAI,aAAa;AAAA,MACnC,mBAAmB,KAAK;AAAA,MACxB,MAAM,KAAK,OAAO,MAAM;AAAA,MACxB,MAAM,KAAK,OAAO,MAAM;AAAA,MACxB,UAAU,KAAK,OAAO,MAAM;AAAA,IAC9B,CAAC;AAGD,SAAK,eAAe,IAAI,aAAa;AAAA,MACnC,cAAc,KAAK;AAAA,IACrB,CAAC;AAGD,6BAAyB,SAAS,IAAI;AAGtC,oBAAgB,iBAAiB,IAAI;AAErC,QAAI,KAAK,OAAO,UAAU,YAAY,MAAM;AAC1C,YAAM,2BAA2B,KAAK,KAAK,OAAO,eAAe,OAAO,YAAY,UAAU;AAE9F,UAAI,CAAC,KAAK,OAAO,SAAS,mBAAmB;AAC3C,aAAK,OAAO,SAAS,oBAAoB;AAAA,MAC3C;AAEA,UAAI,CAAC,WAAW,KAAK,OAAO,SAAS,iBAAiB,GAAG;AACvD,cAAM,IAAI,MAAM,gDAAgD,KAAK,OAAO,SAAS,iBAAiB,GAAG;AAAA,MAC3G;AAGA,WAAK,kBAAkB,IAAI,gBAAgB;AAAA,QACzC,mBAAmB,KAAK;AAAA,QACxB,MAAM,KAAK,OAAO,SAAS;AAAA,QAC3B,MAAM,KAAK,OAAO,SAAS;AAAA,QAC3B,UAAU,KAAK,OAAO,SAAS;AAAA,QAC/B,UAAU,KAAK,OAAO,SAAS;AAAA,QAC/B,cAAc,KAAK,OAAO,SAAS;AAAA,QACnC,mBAAmB,KAAK,OAAO,SAAS;AAAA,MAC1C,CAAC;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAa,wBAAyC;AAEpD,QAAI,gBAAgB,4BAA4B,QAAW;AACzD,aAAO,gBAAgB;AAAA,IACzB;AAGA,UAAM,aAAa,cAAc,YAAY,GAAG;AAChD,UAAM,YAAY,QAAQ,UAAU;AACpC,UAAM,kBAAkB,QAAQ,WAAW,oBAAoB;AAG/D,UAAM,eAAe,aAAa,iBAAiB,OAAO;AAC1D,UAAM,cAAc,KAAK,MAAM,YAAY;AAE3C,QAAI,CAAC,aAAa,SAAS;AACzB,YAAM,IAAI,MAAM,+BAA+B;AAAA,IACjD;AAGA,oBAAgB,0BAA0B,YAAY;AAEtD,WAAO,YAAY;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAa,QAAuB;AAElC,SAAK,YAAY,KAAK,IAAI;AAG1B,SAAK,qBAAqB,MAAM,KAAK,sBAAsB;AAG3D,WAAO,KAAK;AAAA,MACV,SAAS;AAAA,MACT,MAAM;AAAA,QACJ,MAAM,KAAK,OAAO;AAAA,QAClB,eAAe,KAAK,OAAO;AAAA,QAC3B,yBAAyB,KAAK;AAAA,MAChC;AAAA,IACF,CAAC;AAED,UAAM,uBAAwD;AAAA,MAC5D,WAAW,KAAK,UAAU,KAAK,IAAI;AAAA,IACrC;AAEA,UAAM,sBAAsD;AAAA,MAC1D,WAAW,KAAK,UAAU,KAAK,IAAI;AAAA,IACrC;AAEA,QAAI,KAAK,OAAO,SAAS,SAAS;AAEhC,YAAM,iBAAiB,IAAI,eAAe;AAAA,QACxC,QAAQ,KAAK,OAAO;AAAA,QAEpB,0BAA0B,6BAAM,KAAK,cAAc,oBAAoB,GAA7C;AAAA,QAC1B,yBAAyB,6BAAM,KAAK,KAAK,mBAAmB,GAAnC;AAAA,MAC3B,CAAC;AAGD,qBAAe,MAAM;AAAA,IACvB,OAAO;AAEL,YAAM,KAAK,cAAc,oBAAoB;AAAA,IAI/C;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,gBAKX;AACD,UAAM,iBAAiB,KAAK,IAAI;AAGhC,QAAI,QAAQ,IAAI,aAAa;AAC3B,cAAQ,IAAI,0CAA0C;AAAA,IACxD;AACA,UAAM,gBAAgB,MAAM,KAAK,aAAa,QAAQ;AACtD,QAAI,QAAQ,IAAI,aAAa;AAC3B,YAAM,eAAe,KAAK,uBAAuB,EAAE,WAAW,eAAe,CAAC;AAC9E,cAAQ,IAAI,sCAAsC,YAAY,KAAK;AAAA,IACrE;AAGA,QAAI,mBAA4C;AAChD,QAAI,KAAK,iBAAiB;AACxB,UAAI,QAAQ,IAAI,aAAa;AAC3B,gBAAQ,IAAI,6CAA6C;AAAA,MAC3D;AACA,YAAM,cAAc,KAAK,IAAI;AAC7B,yBAAmB,MAAM,KAAK,gBAAgB,QAAQ;AACtD,UAAI,QAAQ,IAAI,aAAa;AAC3B,cAAM,YAAY,KAAK,uBAAuB,EAAE,WAAW,YAAY,CAAC;AACxE,gBAAQ,IAAI,yCAAyC,SAAS,KAAK;AAAA,MACrE;AAAA,IACF;AAEA,QAAI;AAEJ,QAAI,KAAK,OAAO,OAAO,SAAS;AAC9B,qBAAe,IAAI,aAAa;AAAA,QAC9B,mBAAmB,KAAK;AAAA,QACxB,SAAS,KAAK,OAAO;AAAA,QACrB,QAAQ,KAAK,OAAO,MAAM,UAAU,CAAC;AAAA,QACrC;AAAA,QACA;AAAA;AAAA,MAEF,CAAC;AAED,mBAAa,KAAK;AAAA,IACpB;AAGA,UAAM,eAAe,IAAI,aAAa;AAAA,MACpC,mBAAmB,KAAK;AAAA,MACxB,SAAS;AAAA,QACP,qBAAqB,KAAK,OAAO,MAAM;AAAA,MACzC;AAAA,MACA,QAAQ,KAAK,OAAO,MAAM;AAAA,MAC1B;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAGD,UAAM,aAAa,eAAe;AAAA,MAChC,QAAQ,KAAK,OAAO,MAAM;AAAA,IAC5B,CAAC;AAGD,SAAK,UAAU,kBAAkB,SAAS,YAAY;AACpD,UAAI;AACF,eAAO,MAAM,cAAc,YAAY;AAAA,MACzC,QAAQ;AACN,eAAO;AAAA,MACT;AAAA,IACF,CAAC;AAED,QAAI,kBAAkB;AACpB,WAAK,UAAU,kBAAkB,YAAY,YAAY;AACvD,YAAI;AACF,iBAAO,MAAM,iBAAiB,YAAY;AAAA,QAC5C,QAAQ;AACN,iBAAO;AAAA,QACT;AAAA,MACF,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKU,UAAU,EAAE,aAAa,aAAa,GAAkC;AAAA,EAAC;AAAA;AAAA;AAAA;AAAA,EAKzE,UAAU,EAAE,SAAS,SAAS,GAA8B;AAAA,EAAC;AAAA;AAAA;AAAA;AAAA,EAKvE,MAAc,cAAc,SAAyD;AACnF,QAAI;AAEF,UAAI,QAAQ,IAAI,aAAa;AAC3B,gBAAQ,IAAI,oDAAoD;AAAA,MAClE;AACA,YAAM,gBAAgB,KAAK,IAAI;AAC/B,YAAM,aAAa,MAAM,KAAK,UAAU,WAAW;AACnD,UAAI,QAAQ,IAAI,aAAa;AAC3B,cAAM,cAAc,KAAK,uBAAuB,EAAE,WAAW,cAAc,CAAC;AAC5E,gBAAQ,IAAI,qCAAqC,WAAW,KAAK;AAAA,MACnE;AACA,UAAI,WAAW,OAAO,SAAS,GAAG;AAChC,eAAO,KAAK;AAAA,UACV,SAAS;AAAA,UACT,MAAM,EAAE,QAAQ,WAAW,OAAO,IAAI,OAAM,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,CAAE,EAAE;AAAA,QAC3F,CAAC;AAAA,MACH;AAGA,UAAI,QAAQ,IAAI,aAAa;AAC3B,gBAAQ,IAAI,4EAA4E;AAAA,MAC1F;AACA,YAAM,kBAAkB,KAAK,IAAI;AACjC,YAAM,EAAE,eAAe,kBAAkB,cAAc,aAAa,IAAI,MAAM,KAAK,cAAc;AACjG,UAAI,QAAQ,IAAI,aAAa;AAC3B,cAAM,qBAAqB,KAAK,uBAAuB,EAAE,WAAW,gBAAgB,CAAC;AACrF,gBAAQ,IAAI,uCAAuC,kBAAkB,KAAK;AAAA,MAC5E;AAGA,UAAI,QAAQ,IAAI,aAAa;AAC3B,gBAAQ,IAAI,2DAA2D;AAAA,MACzE;AACA,YAAM,iBAAiB,KAAK,IAAI;AAChC,YAAM,cAAc,MAAM,KAAK,UAAU,MAAM;AAC/C,UAAI,QAAQ,IAAI,aAAa;AAC3B,cAAM,eAAe,KAAK,uBAAuB,EAAE,WAAW,eAAe,CAAC;AAC9E,gBAAQ,IAAI,qCAAqC,YAAY,KAAK;AAAA,MACpE;AACA,UAAI,YAAY,OAAO,SAAS,GAAG;AACjC,eAAO,KAAK;AAAA,UACV,SAAS;AAAA,UACT,MAAM,EAAE,QAAQ,YAAY,OAAO,IAAI,OAAM,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,CAAE,EAAE;AAAA,QAC5F,CAAC;AAAA,MACH;AAGA,UAAI,QAAQ,IAAI,aAAa;AAC3B,gBAAQ,IAAI,iDAAiD;AAAA,MAC/D;AACA,YAAM,mBAAmB,KAAK,IAAI;AAClC,YAAM,KAAK,aAAa;AAAA,QACtB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AACD,UAAI,QAAQ,IAAI,aAAa;AAC3B,cAAM,iBAAiB,KAAK,uBAAuB,EAAE,WAAW,iBAAiB,CAAC;AAClF,gBAAQ,IAAI,gDAAgD,cAAc,KAAK;AAAA,MACjF;AAGA,UAAI,QAAQ,IAAI,aAAa;AAC3B,gBAAQ,IAAI,iEAAiE;AAAA,MAC/E;AACA,YAAM,iBAAiB,KAAK,IAAI;AAChC,YAAM,cAAc,MAAM,KAAK,UAAU,MAAM;AAC/C,UAAI,QAAQ,IAAI,aAAa;AAC3B,cAAM,eAAe,KAAK,uBAAuB,EAAE,WAAW,eAAe,CAAC;AAC9E,gBAAQ,IAAI,qCAAqC,YAAY,KAAK;AAAA,MACpE;AACA,UAAI,YAAY,OAAO,SAAS,GAAG;AACjC,eAAO,KAAK;AAAA,UACV,SAAS;AAAA,UACT,MAAM,EAAE,QAAQ,YAAY,OAAO,IAAI,OAAM,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,CAAE,EAAE;AAAA,QAC5F,CAAC;AAAA,MACH;AAGA,YAAM,cAAc,KAAK,uBAAuB;AAAA,QAC9C,WAAW,KAAK;AAAA,MAClB,CAAC;AAGD,UAAI,QAAQ,WAAW;AACrB,cAAM,QAAQ,UAAU,EAAE,YAAY,CAAC;AAAA,MACzC;AAAA,IACF,SAAS,OAAO;AACd,aAAO,MAAM;AAAA,QACX,OAAO,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,mBAAmB,KAAK,CAAC;AAAA,QAC3E,SAAS;AAAA,MACX,CAAC;AACD,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAgBA,OAAe,iBAAiB,UAAiC;AAC/D,oBAAgB,oBAAoB;AACpC,oBAAgB,UAAU,IAAI,IAAI,QAAQ,QAAQ,CAAC;AACnD,oBAAgB,4BAA4B;AAAA,EAC9C;AAAA,EAEA,OAAe,mBAAmB,UAAiC;AACjE,eAAW,OAAO,MAAM,KAAK,gBAAgB,SAAS,GAAG;AACvD,YAAM,UAAU,IAAI,MAAM;AAC1B,UAAI,CAAC,WAAW,YAAY,UAAU;AACpC,wBAAgB,UAAU,OAAO,GAAG;AAAA,MACtC;AAAA,IACF;AAAA,EACF;AAAA,EAEA,OAAe,sBAA4B;AACzC,eAAW,OAAO,MAAM,KAAK,gBAAgB,SAAS,GAAG;AACvD,UAAI,CAAC,IAAI,MAAM,GAAG;AAChB,wBAAgB,UAAU,OAAO,GAAG;AAAA,MACtC;AAAA,IACF;AAAA,EACF;AAAA,EAEA,OAAe,qBAAwC;AACrD,UAAM,SAA4B,CAAC;AACnC,UAAM,QAAoC,CAAC;AAE3C,eAAW,OAAO,gBAAgB,WAAW;AAC3C,YAAM,WAAW,IAAI,MAAM;AAC3B,UAAI,UAAU;AACZ,eAAO,KAAK,QAAQ;AAAA,MACtB,OAAO;AACL,cAAM,KAAK,GAAG;AAAA,MAChB;AAAA,IACF;AAEA,eAAW,OAAO,OAAO;AACvB,sBAAgB,UAAU,OAAO,GAAG;AAAA,IACtC;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,OAAe,8BAAoC;AACjD,QAAI,gBAAgB,+BAA+B;AACjD;AAAA,IACF;AAEA,YAAQ,GAAG,qBAAqB,WAAS;AACvC,aAAO,MAAM,EAAE,OAAO,SAAS,qBAAqB,CAAC;AACrD,iBAAW,OAAO,gBAAgB,mBAAmB,GAAG;AACtD,YAAI,yBAAyB;AAAA,MAC/B;AAAA,IACF,CAAC;AAED,YAAQ,GAAG,sBAAsB,CAAC,QAAQ,YAAY;AACpD,aAAO,MAAM;AAAA,QACX,OAAO,kBAAkB,QAAQ,SAAS,IAAI,MAAM,OAAO,MAAM,CAAC;AAAA,QAClE,SAAS;AAAA,QACT,MAAM,EAAE,SAAS,OAAO,OAAO,EAAE;AAAA,MACnC,CAAC;AACD,iBAAW,OAAO,gBAAgB,mBAAmB,GAAG;AACtD,YAAI,yBAAyB;AAAA,MAC/B;AAAA,IACF,CAAC;AAED,oBAAgB,gCAAgC;AAAA,EAClD;AAAA;AAAA;AAAA;AAAA,EAKQ,wBAA8B;AAEpC,SAAK,UAAU,WAAW,MAAM;AAC9B,sBAAgB,mBAAmB,IAAI;AAAA,IACzC,CAAC;AAED,SAAK,UAAU,WAAW,YAAY;AACpC,aAAO,KAAK,EAAE,SAAS,iCAAiC,CAAC;AACzD,YAAM,KAAK,aAAa;AAAA,IAC1B,CAAC;AAED,SAAK,UAAU,WAAW,YAAY;AACpC,UAAI,KAAK,cAAc;AACrB,eAAO,KAAK,EAAE,SAAS,2BAA2B,CAAC;AACnD,cAAM,KAAK,aAAa,WAAW;AAAA,MACrC;AAAA,IACF,CAAC;AAED,SAAK,UAAU,WAAW,YAAY;AACpC,UAAI,KAAK,iBAAiB;AACxB,eAAO,KAAK,EAAE,SAAS,8BAA8B,CAAC;AACtD,cAAM,KAAK,gBAAgB,WAAW;AAAA,MACxC;AAAA,IACF,CAAC;AAAA,EAGH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,2BAA0C;AACtD,QAAI,KAAK,mBAAmB,gBAAgB;AAC1C;AAAA,IACF;AAEA,WAAO,KAAK,EAAE,SAAS,4CAA4C,CAAC;AACpE,QAAI;AACF,YAAM,SAAS,MAAM,KAAK,mBAAmB,SAAS,iBAAiB;AACvE,UAAI,OAAO,OAAO,SAAS,GAAG;AAC5B,eAAO,MAAM;AAAA,UACX,SAAS;AAAA,UACT,OAAO,OAAO;AAAA,QAChB,CAAC;AACD,aAAK,aAAa,EAAE,MAAM,GAAG,QAAQ,2BAA2B,OAAO,OAAO,OAAO,CAAC;AAAA,MACxF,WAAW,OAAO,UAAU;AAC1B,eAAO,KAAK,EAAE,SAAS,qBAAqB,CAAC;AAC7C,aAAK,aAAa,EAAE,MAAM,GAAG,QAAQ,mBAAmB,CAAC;AAAA,MAC3D,OAAO;AACL,aAAK,aAAa,EAAE,MAAM,GAAG,QAAQ,0BAA0B,CAAC;AAAA,MAClE;AAAA,IACF,SAAS,OAAO;AACd,aAAO,MAAM;AAAA,QACX,OAAO,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,mBAAmB,KAAK,CAAC;AAAA,QAC3E,SAAS;AAAA,MACX,CAAC;AACD,WAAK,aAAa,EAAE,MAAM,GAAG,QAAQ,2BAA2B,MAAM,CAAC;AAAA,IACzE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAa,KAAK,EAAE,UAAU,IAAoC,CAAC,GAAkB;AACnF,QAAI,KAAK,mBAAmB,gBAAgB;AAC1C;AAAA,IACF;AAGA,QAAI,WAAW;AACb,WAAK,UAAU,WAAW,MAAM;AAC9B,cAAM,UAAU,QAAQ,OAAO,IAAI;AACnC,kBAAU,EAAE,QAAQ,CAAC;AAAA,MACvB,CAAC;AAAA,IACH;AAEA,QAAI;AACF,YAAM,SAAS,MAAM,KAAK,mBAAmB,SAAS,aAAa;AACnE,UAAI,OAAO,OAAO,SAAS,GAAG;AAC5B,eAAO,MAAM;AAAA,UACX,SAAS;AAAA,UACT,OAAO,OAAO;AAAA,QAChB,CAAC;AACD,aAAK,aAAa,EAAE,MAAM,GAAG,QAAQ,kBAAkB,OAAO,OAAO,OAAO,CAAC;AAAA,MAC/E,WAAW,OAAO,UAAU;AAC1B,eAAO,KAAK,EAAE,SAAS,qBAAqB,CAAC;AAC7C,aAAK,aAAa,EAAE,MAAM,GAAG,QAAQ,mBAAmB,CAAC;AAAA,MAC3D,OAAO;AACL,aAAK,aAAa,EAAE,MAAM,GAAG,QAAQ,oBAAoB,CAAC;AAAA,MAC5D;AAAA,IACF,SAAS,OAAO;AACd,aAAO,MAAM;AAAA,QACX,OAAO,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,mBAAmB,KAAK,CAAC;AAAA,QAC3E,SAAS;AAAA,MACX,CAAC;AACD,WAAK,aAAa,EAAE,MAAM,GAAG,QAAQ,kBAAkB,MAAM,CAAC;AAAA,IAChE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,aAAa,SAA4B;AAC/C,UAAM,UAAU,QAAQ,IAAI,YAAY;AACxC,UAAM,YACJ,QAAQ,YAAY,MAAM,UAC1B,YAAY,QAAQ,OACpB,sBAAsB,QAAQ,OAC9B,QAAQ,KAAK,KAAK,OAAK,EAAE,SAAS,QAAQ,CAAC,KAC3C,OAAQ,WAAmB,aAAa;AAE1C,QAAI,WAAW;AACb,aAAO,KAAK,EAAE,SAAS,8CAA8C,QAAQ,MAAM,KAAK,MAAM,QAAQ,KAAK,CAAC;AAC5G;AAAA,IACF;AACA,gBAAY,OAAO;AAAA,EACrB;AACF;",
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;IAoHjB;;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;cA0BlE,SAAS,CAAC,EAAE,OAAO,EAAE,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAqB3E"}
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: this.config.webServer.routes,
52
+ ...Array.isArray(staticRoutes) ? { routes: staticRoutes } : {},
52
53
  redisInstance,
53
54
  databaseInstance,
54
55
  queueManager,
@@ -139,9 +140,6 @@ class WebApplication extends BaseApplication {
139
140
  Logger.info({
140
141
  message: "Application started",
141
142
  meta: {
142
- Name: this.config.name,
143
- "Instance ID": this.config.instanceId,
144
- "PXL Framework Version": this.applicationVersion,
145
143
  "Startup Time": Time.formatTime({
146
144
  time: startupTime,
147
145
  format: "s",
@@ -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: this.config.webServer.routes,\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 Name: this.config.name,\n 'Instance ID': this.config.instanceId,\n 'PXL Framework Version': this.applicationVersion,\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": ";;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;AAElC,WAAK,YAAY,IAAI,UAAU;AAAA,QAC7B,mBAAmB,KAAK;AAAA,QACxB,SAAS;AAAA,UACP,MAAM,KAAK,OAAO,UAAU;AAAA,UAC5B,MAAM,KAAK,OAAO,UAAU;AAAA,UAC5B,sBAAsB,KAAK,OAAO,UAAU;AAAA,UAC5C,iBAAiB,KAAK,OAAO,UAAU;AAAA,UACvC,MAAM,KAAK,OAAO,UAAU;AAAA,UAC5B,UAAU,KAAK,OAAO,UAAU;AAAA,UAChC,KAAK,KAAK,OAAO,UAAU;AAAA,UAC3B,OAAO,KAAK,OAAO,UAAU;AAAA,QAC/B;AAAA,QAEA,QAAQ,KAAK,OAAO,UAAU;AAAA,QAE9B;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,kBAAkB,KAAK;AAAA,MACzB,CAAC;AAGD,UAAI,KAAK,sBAAsB,KAAK,OAAO,uBAAuB,wBAAwB,OAAO;AAC/F,oCAA4B,sBAAsB,KAAK,kBAAkB;AAAA,MAC3E;AAGA,YAAM,KAAK,UAAU,KAAK;AAG1B,YAAM,KAAK,UAAU,MAAM;AAG3B,WAAK,UAAU,kBAAkB,aAAa,YAAY;AACxD,YAAI;AACF,iBAAO,KAAK,WAAW,QAAQ,KAAK;AAAA,QACtC,QAAQ;AACN,iBAAO;AAAA,QACT;AAAA,MACF,CAAC;AAAA,IACH;AAEA,QAAI,KAAK,OAAO,WAAW,SAAS;AAClC,UAAI,CAAC,KAAK,WAAW;AACnB,cAAM,IAAI,MAAM,6CAA6C;AAAA,MAC/D;AAEA,UAAI;AACJ,UAAI;AAEJ,cAAQ,KAAK,OAAO,UAAU,MAAM;AAAA,QAClC,KAAK,UAAU;AAEb,4BAAkB,IAAI,gBAAgB;AAAA,YACpC,kBAAkB,KAAK;AAAA,YACvB,mBAAmB,KAAK;AAAA,YACxB,SAAS,KAAK,OAAO;AAAA,YACrB;AAAA,YACA;AAAA,YACA;AAAA,YACA,QAAQ,KAAK,OAAO,UAAU;AAAA,YAC9B,UAAU,KAAK;AAAA,UACjB,CAAC;AAGD,cAAI,KAAK,sBAAsB,KAAK,OAAO,uBAAuB,+BAA+B,OAAO;AACtG,wCAA4B,sBAAsB,KAAK,kBAAkB;AAAA,UAC3E;AAGA,gBAAM,gBAAgB,KAAK;AAG3B,gBAAM,gBAAgB,MAAM;AAAA,YAC1B,eAAe,KAAK,UAAU;AAAA,UAChC,CAAC;AAED;AAAA,QACF;AAAA,QACA,KAAK,UAAU;AAEb,4BAAkB,IAAI,gBAAgB;AAAA,YACpC,mBAAmB,KAAK;AAAA,YACxB,SAAS,KAAK,OAAO;AAAA,YACrB;AAAA,YACA;AAAA,YACA;AAAA,YACA,QAAQ,KAAK,OAAO,UAAU;AAAA,UAChC,CAAC;AAGD,gBAAM,gBAAgB,KAAK;AAG3B,gBAAM,gBAAgB,gBAAgB;AAEtC;AAAA,QACF;AAAA,QACA,SAAS;AACP,cAAI,CAAC,KAAK,OAAO,UAAU,MAAM;AAC/B,kBAAM,IAAI,MAAM,4BAA4B;AAAA,UAC9C,OAAO;AACL,kBAAM,IAAI,MAAM,0CAA0C,KAAK,OAAO,UAAU,IAAI,GAAG;AAAA,UACzF;AAAA,QACF;AAAA,MACF;AAEA,WAAK,kBAAkB;AACvB,WAAK,kBAAkB;AAAA,IACzB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAgB,eAA8B;AAC5C,QAAI,KAAK,WAAW;AAElB,YAAM,KAAK,UAAU,KAAK;AAAA,IAC5B;AAEA,QAAI,KAAK,iBAAiB;AAExB,YAAM,KAAK,gBAAgB,KAAK;AAAA,IAClC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAgB,UAAU,EAAE,YAAY,GAA2C;AACjF,QAAI,KAAK,OAAO,KAAK,SAAS;AAC5B,aAAO,KAAK;AAAA,QACV,SAAS;AAAA,QACT,MAAM;AAAA,UACJ,MAAM,KAAK,OAAO;AAAA,UAClB,eAAe,KAAK,OAAO;AAAA,UAC3B,yBAAyB,KAAK;AAAA,UAC9B,gBAAgB,KAAK,WAAW;AAAA,YAC9B,MAAM;AAAA,YACN,QAAQ;AAAA,YACR,aAAa;AAAA,YACb,UAAU;AAAA,UACZ,CAAC;AAAA,QACH;AAAA,MACF,CAAC;AAAA,IACH;AAEA,QAAI,KAAK,OAAO,QAAQ,WAAW;AACjC,WAAK,OAAO,OAAO,UAAU;AAAA,QAC3B,KAAK;AAAA,QACL;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,MAAgB,UAAU,EAAE,QAAQ,GAAuC;AACzE,QAAI,KAAK,OAAO,KAAK,UAAU;AAC7B,aAAO,KAAK;AAAA,QACV,SAAS;AAAA,QACT,MAAM;AAAA,UACJ,MAAM,KAAK,OAAO;AAAA,UAClB,eAAe,KAAK,OAAO;AAAA,UAC3B,SAAS,KAAK,WAAW;AAAA,YACvB,MAAM;AAAA,YACN,QAAQ;AAAA,YACR,aAAa;AAAA,YACb,UAAU;AAAA,UACZ,CAAC;AAAA,QACH;AAAA,MACF,CAAC;AAAA,IACH;AAEA,QAAI,KAAK,OAAO,QAAQ,WAAW;AACjC,WAAK,OAAO,OAAO,UAAU,EAAE,KAAK,MAAM,QAAQ,CAAC;AAAA,IACrD;AAAA,EACF;AACF;",
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
  }
@@ -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;gBAE1B,EAAE,YAAY,EAAE,EAAE,iBAAiB;IAI/C;;;OAGG;YACW,gBAAgB;IAa9B;;;;;;;;;;;;;;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"}
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"}
@@ -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.redisInstance = await this.redisManager.connect();
24
- return this.redisInstance;
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.