@scpxl/nodejs-framework 1.0.17 → 1.0.19

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 (192) hide show
  1. package/README.md +29 -0
  2. package/dist/api-requester/api-requester.d.ts +27 -6
  3. package/dist/api-requester/api-requester.d.ts.map +1 -1
  4. package/dist/api-requester/api-requester.js +188 -26
  5. package/dist/api-requester/api-requester.js.map +2 -2
  6. package/dist/api-requester/index.d.ts +1 -0
  7. package/dist/api-requester/index.d.ts.map +1 -1
  8. package/dist/api-requester/index.js.map +1 -1
  9. package/dist/application/base-application.d.ts +15 -22
  10. package/dist/application/base-application.d.ts.map +1 -1
  11. package/dist/application/base-application.js +145 -111
  12. package/dist/application/base-application.js.map +2 -2
  13. package/dist/application/command-application.d.ts.map +1 -1
  14. package/dist/application/command-application.js +3 -4
  15. package/dist/application/command-application.js.map +2 -2
  16. package/dist/application/web-application.d.ts.map +1 -1
  17. package/dist/application/web-application.js +9 -2
  18. package/dist/application/web-application.js.map +2 -2
  19. package/dist/cache/manager.d.ts +87 -6
  20. package/dist/cache/manager.d.ts.map +1 -1
  21. package/dist/cache/manager.js +77 -30
  22. package/dist/cache/manager.js.map +2 -2
  23. package/dist/cluster/cluster-manager.d.ts.map +1 -1
  24. package/dist/cluster/cluster-manager.js +5 -8
  25. package/dist/cluster/cluster-manager.js.map +2 -2
  26. package/dist/config/env.d.ts +11 -0
  27. package/dist/config/env.d.ts.map +1 -0
  28. package/dist/config/env.js +103 -0
  29. package/dist/config/env.js.map +7 -0
  30. package/dist/config/index.d.ts +3 -0
  31. package/dist/config/index.d.ts.map +1 -0
  32. package/dist/config/index.js +3 -0
  33. package/dist/config/index.js.map +7 -0
  34. package/dist/config/schema.d.ts +408 -0
  35. package/dist/config/schema.d.ts.map +1 -0
  36. package/dist/config/schema.js +218 -0
  37. package/dist/config/schema.js.map +7 -0
  38. package/dist/database/dynamic-entity.d.ts.map +1 -1
  39. package/dist/database/dynamic-entity.js +6 -2
  40. package/dist/database/dynamic-entity.js.map +2 -2
  41. package/dist/database/instance.d.ts.map +1 -1
  42. package/dist/database/instance.js +0 -8
  43. package/dist/database/instance.js.map +2 -2
  44. package/dist/database/manager.d.ts.map +1 -1
  45. package/dist/database/manager.js +71 -9
  46. package/dist/database/manager.js.map +2 -2
  47. package/dist/error/error-reporter.d.ts +96 -0
  48. package/dist/error/error-reporter.d.ts.map +1 -0
  49. package/dist/error/error-reporter.js +228 -0
  50. package/dist/error/error-reporter.js.map +7 -0
  51. package/dist/error/error.interface.d.ts +126 -0
  52. package/dist/error/error.interface.d.ts.map +1 -0
  53. package/dist/error/error.interface.js +45 -0
  54. package/dist/error/error.interface.js.map +7 -0
  55. package/dist/error/framework-errors.d.ts +113 -0
  56. package/dist/error/framework-errors.d.ts.map +1 -0
  57. package/dist/error/framework-errors.js +176 -0
  58. package/dist/error/framework-errors.js.map +7 -0
  59. package/dist/error/index.d.ts +6 -0
  60. package/dist/error/index.d.ts.map +1 -0
  61. package/dist/error/index.js +34 -0
  62. package/dist/error/index.js.map +7 -0
  63. package/dist/event/manager.d.ts.map +1 -1
  64. package/dist/event/manager.js +2 -9
  65. package/dist/event/manager.js.map +2 -2
  66. package/dist/index.d.ts +5 -1
  67. package/dist/index.d.ts.map +1 -1
  68. package/dist/index.js +5 -1
  69. package/dist/index.js.map +2 -2
  70. package/dist/lifecycle/exit.d.ts +2 -1
  71. package/dist/lifecycle/exit.d.ts.map +1 -1
  72. package/dist/lifecycle/exit.js +6 -0
  73. package/dist/lifecycle/exit.js.map +2 -2
  74. package/dist/lifecycle/index.d.ts +7 -0
  75. package/dist/lifecycle/index.d.ts.map +1 -0
  76. package/dist/lifecycle/index.js +12 -0
  77. package/dist/lifecycle/index.js.map +7 -0
  78. package/dist/lifecycle/lifecycle-manager.d.ts +55 -2
  79. package/dist/lifecycle/lifecycle-manager.d.ts.map +1 -1
  80. package/dist/lifecycle/lifecycle-manager.js +233 -7
  81. package/dist/lifecycle/lifecycle-manager.js.map +3 -3
  82. package/dist/lifecycle/shutdown-controller.d.ts +15 -0
  83. package/dist/lifecycle/shutdown-controller.d.ts.map +1 -0
  84. package/dist/lifecycle/shutdown-controller.js +38 -0
  85. package/dist/lifecycle/shutdown-controller.js.map +7 -0
  86. package/dist/lifecycle/types.d.ts +28 -0
  87. package/dist/lifecycle/types.d.ts.map +1 -0
  88. package/dist/lifecycle/types.js +13 -0
  89. package/dist/lifecycle/types.js.map +7 -0
  90. package/dist/logger/logger.d.ts +2 -1
  91. package/dist/logger/logger.d.ts.map +1 -1
  92. package/dist/logger/logger.js +35 -11
  93. package/dist/logger/logger.js.map +2 -2
  94. package/dist/performance/cache-performance.d.ts +6 -0
  95. package/dist/performance/cache-performance.d.ts.map +1 -1
  96. package/dist/performance/cache-performance.js +16 -0
  97. package/dist/performance/cache-performance.js.map +2 -2
  98. package/dist/performance/index.d.ts +1 -0
  99. package/dist/performance/index.d.ts.map +1 -1
  100. package/dist/performance/index.js +1 -0
  101. package/dist/performance/index.js.map +2 -2
  102. package/dist/performance/performance-monitor.d.ts.map +1 -1
  103. package/dist/performance/performance-monitor.js +47 -18
  104. package/dist/performance/performance-monitor.js.map +2 -2
  105. package/dist/performance/performance-monitor.plugin.d.ts +24 -0
  106. package/dist/performance/performance-monitor.plugin.d.ts.map +1 -0
  107. package/dist/performance/performance-monitor.plugin.js +89 -0
  108. package/dist/performance/performance-monitor.plugin.js.map +7 -0
  109. package/dist/performance/webserver-performance.js +1 -1
  110. package/dist/performance/webserver-performance.js.map +2 -2
  111. package/dist/queue/manager.d.ts.map +1 -1
  112. package/dist/queue/manager.js +3 -10
  113. package/dist/queue/manager.js.map +2 -2
  114. package/dist/queue/worker.d.ts.map +1 -1
  115. package/dist/queue/worker.js +2 -2
  116. package/dist/queue/worker.js.map +2 -2
  117. package/dist/redis/manager.d.ts.map +1 -1
  118. package/dist/redis/manager.js +228 -33
  119. package/dist/redis/manager.js.map +2 -2
  120. package/dist/request-context/index.d.ts +3 -0
  121. package/dist/request-context/index.d.ts.map +1 -0
  122. package/dist/request-context/index.js +25 -0
  123. package/dist/request-context/index.js.map +7 -0
  124. package/dist/request-context/request-context.d.ts +108 -0
  125. package/dist/request-context/request-context.d.ts.map +1 -0
  126. package/dist/request-context/request-context.interface.d.ts +46 -0
  127. package/dist/request-context/request-context.interface.d.ts.map +1 -0
  128. package/dist/request-context/request-context.interface.js +1 -0
  129. package/dist/request-context/request-context.interface.js.map +7 -0
  130. package/dist/request-context/request-context.js +79 -0
  131. package/dist/request-context/request-context.js.map +7 -0
  132. package/dist/services/aws/s3.js +4 -6
  133. package/dist/services/aws/s3.js.map +2 -2
  134. package/dist/util/file.d.ts +13 -0
  135. package/dist/util/file.d.ts.map +1 -1
  136. package/dist/util/file.js +46 -9
  137. package/dist/util/file.js.map +2 -2
  138. package/dist/util/helper.d.ts +16 -1
  139. package/dist/util/helper.d.ts.map +1 -1
  140. package/dist/util/helper.js +19 -43
  141. package/dist/util/helper.js.map +2 -2
  142. package/dist/util/index.d.ts +1 -0
  143. package/dist/util/index.d.ts.map +1 -1
  144. package/dist/util/index.js +18 -16
  145. package/dist/util/index.js.map +2 -2
  146. package/dist/util/loader.d.ts.map +1 -1
  147. package/dist/util/loader.js +13 -2
  148. package/dist/util/loader.js.map +2 -2
  149. package/dist/util/os.d.ts.map +1 -1
  150. package/dist/util/os.js +8 -14
  151. package/dist/util/os.js.map +2 -2
  152. package/dist/util/time.d.ts +8 -2
  153. package/dist/util/time.d.ts.map +1 -1
  154. package/dist/util/time.js +12 -7
  155. package/dist/util/time.js.map +2 -2
  156. package/dist/util/timing.d.ts +36 -0
  157. package/dist/util/timing.d.ts.map +1 -0
  158. package/dist/util/timing.interface.d.ts +47 -0
  159. package/dist/util/timing.interface.d.ts.map +1 -0
  160. package/dist/util/timing.interface.js +1 -0
  161. package/dist/util/timing.interface.js.map +7 -0
  162. package/dist/util/timing.js +98 -0
  163. package/dist/util/timing.js.map +7 -0
  164. package/dist/util/url.js +1 -1
  165. package/dist/util/url.js.map +2 -2
  166. package/dist/webserver/controller/base.d.ts +3 -1
  167. package/dist/webserver/controller/base.d.ts.map +1 -1
  168. package/dist/webserver/controller/base.interface.d.ts +2 -0
  169. package/dist/webserver/controller/base.interface.d.ts.map +1 -1
  170. package/dist/webserver/controller/base.js +4 -1
  171. package/dist/webserver/controller/base.js.map +2 -2
  172. package/dist/webserver/controller/health.d.ts +8 -1
  173. package/dist/webserver/controller/health.d.ts.map +1 -1
  174. package/dist/webserver/controller/health.js +36 -22
  175. package/dist/webserver/controller/health.js.map +2 -2
  176. package/dist/webserver/webserver.d.ts +16 -2
  177. package/dist/webserver/webserver.d.ts.map +1 -1
  178. package/dist/webserver/webserver.interface.d.ts +37 -0
  179. package/dist/webserver/webserver.interface.d.ts.map +1 -1
  180. package/dist/webserver/webserver.interface.js.map +2 -2
  181. package/dist/webserver/webserver.js +117 -20
  182. package/dist/webserver/webserver.js.map +2 -2
  183. package/dist/websocket/controllers/server/system.d.ts.map +1 -1
  184. package/dist/websocket/controllers/server/system.js.map +2 -2
  185. package/dist/websocket/websocket-base.d.ts.map +1 -1
  186. package/dist/websocket/websocket-base.js +2 -3
  187. package/dist/websocket/websocket-base.js.map +2 -2
  188. package/dist/websocket/websocket-server.d.ts +1 -1
  189. package/dist/websocket/websocket-server.d.ts.map +1 -1
  190. package/dist/websocket/websocket-server.js +7 -31
  191. package/dist/websocket/websocket-server.js.map +2 -2
  192. package/package.json +51 -10
@@ -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\n // config: this.config.webServer,\n options: {\n host: this.config.webServer.host,\n port: this.config.webServer.port,\n controllersDirectory: this.config.webServer.controllersDirectory,\n cors: this.config.webServer.cors,\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 });\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({ webSocketServer: this.webSocketServer?.server });\n await this.webServer.start();\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": "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",
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 cors: this.config.webServer.cors,\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,MAAM,KAAK,OAAO,UAAU;AAAA,UAC5B,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;",
6
6
  "names": []
7
7
  }
@@ -1,26 +1,107 @@
1
- import type { ApplicationConfig } from '../application/base-application.interface.js';
2
1
  import type RedisManager from '../redis/manager.js';
2
+ /**
3
+ * CacheManager
4
+ *
5
+ * Thin abstraction over Redis for basic JSON value caching. Unifies all Redis
6
+ * access through the framework RedisManager / RedisInstance (ioredis) so we
7
+ * avoid maintaining a second client implementation (node-redis).
8
+ *
9
+ * Lazy acquisition: the first call to any cache method will either reuse an
10
+ * existing connected RedisInstance (if already established by application
11
+ * startup) or trigger a connection via RedisManager.
12
+ *
13
+ * **Important:** All values are stored as JSON strings. Only JSON-serializable
14
+ * values are supported. Complex types like Date, Map, Set, RegExp, etc. will
15
+ * lose their type information during serialization:
16
+ * - `Date` objects → ISO strings
17
+ * - `Map` / `Set` → empty objects `{}`
18
+ * - `undefined` → omitted from objects, `null` in arrays
19
+ * - Functions → omitted
20
+ *
21
+ * @example
22
+ * ```typescript
23
+ * // Supported types
24
+ * await cache.setItem({ key: 'user', value: { id: 1, name: 'John' } }); // ✓
25
+ * await cache.setItem({ key: 'count', value: 42 }); // ✓
26
+ * await cache.setItem({ key: 'tags', value: ['a', 'b', 'c'] }); // ✓
27
+ *
28
+ * // Unsupported types (will lose type information)
29
+ * await cache.setItem({ key: 'date', value: new Date() }); // → ISO string
30
+ * await cache.setItem({ key: 'map', value: new Map() }); // → {}
31
+ * ```
32
+ */
3
33
  export interface CacheManagerProps {
4
- applicationConfig: ApplicationConfig;
34
+ /** Redis manager (shared across the application) */
5
35
  redisManager: RedisManager;
6
36
  }
7
37
  export default class CacheManager {
8
- private client?;
9
- private applicationConfig;
10
38
  private redisManager;
11
- constructor({ applicationConfig, redisManager }: CacheManagerProps);
12
- private getClient;
39
+ private redisInstance?;
40
+ constructor({ redisManager }: CacheManagerProps);
41
+ /**
42
+ * Ensure we have a connected RedisInstance. Reuses the first existing
43
+ * instance if already connected by the application bootstrap.
44
+ */
45
+ private getRedisInstance;
46
+ /**
47
+ * Get a cached JSON value (deserialized) or null if not present.
48
+ *
49
+ * @param key - Cache key
50
+ * @returns Deserialized value or null if not found
51
+ * @throws {Error} If the cached value is not valid JSON
52
+ *
53
+ * @example
54
+ * ```typescript
55
+ * const user = await cache.getItem<{ id: number; name: string }>({ key: 'user:123' });
56
+ * if (user) {
57
+ * console.log(user.name);
58
+ * }
59
+ * ```
60
+ */
13
61
  getItem<T>({ key }: {
14
62
  key: string;
15
63
  }): Promise<T | null>;
64
+ /**
65
+ * Set a JSON-serializable value. Optionally specify lifetime (seconds).
66
+ *
67
+ * @param key - Cache key
68
+ * @param value - Value to cache (must be JSON-serializable)
69
+ * @param lifetime - Optional expiration in seconds
70
+ *
71
+ * @example
72
+ * ```typescript
73
+ * // Cache with no expiration
74
+ * await cache.setItem({ key: 'config', value: { theme: 'dark' } });
75
+ *
76
+ * // Cache with 1 hour expiration
77
+ * await cache.setItem({
78
+ * key: 'session:abc',
79
+ * value: { userId: 123 },
80
+ * lifetime: 3600
81
+ * });
82
+ * ```
83
+ */
16
84
  setItem<T>({ key, value, lifetime }: {
17
85
  key: string;
18
86
  value: T;
19
87
  lifetime?: number;
20
88
  }): Promise<void>;
89
+ /**
90
+ * Delete a cached value.
91
+ *
92
+ * @param key - Cache key to delete
93
+ *
94
+ * @example
95
+ * ```typescript
96
+ * await cache.clearItem({ key: 'session:abc' });
97
+ * ```
98
+ */
21
99
  clearItem({ key }: {
22
100
  key: string;
23
101
  }): Promise<void>;
102
+ /**
103
+ * No-op: lifecycle handles Redis disconnection globally.
104
+ */
24
105
  close(): Promise<void>;
25
106
  }
26
107
  //# sourceMappingURL=manager.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/cache/manager.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,8CAA8C,CAAC;AACtF,OAAO,KAAK,YAAY,MAAM,qBAAqB,CAAC;AAEpD,MAAM,WAAW,iBAAiB;IAChC,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,YAAY,EAAE,YAAY,CAAC;CAC5B;AAED,MAAM,CAAC,OAAO,OAAO,YAAY;IAC/B,OAAO,CAAC,MAAM,CAAC,CAAkB;IAEjC,OAAO,CAAC,iBAAiB,CAAoB;IAC7C,OAAO,CAAC,YAAY,CAAe;gBAEvB,EAAE,iBAAiB,EAAE,YAAY,EAAE,EAAE,iBAAiB;YAKpD,SAAS;IAcV,OAAO,CAAC,CAAC,EAAE,EAAE,GAAG,EAAE,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IAOvD,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;IAWjG,SAAS,CAAC,EAAE,GAAG,EAAE,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAKlD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAKpC"}
1
+ {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/cache/manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,YAAY,MAAM,qBAAqB,CAAC;AAGpD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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,51 +1,98 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
- import { createClient } from "redis";
4
3
  class CacheManager {
5
4
  static {
6
5
  __name(this, "CacheManager");
7
6
  }
8
- client;
9
- applicationConfig;
10
7
  redisManager;
11
- constructor({ applicationConfig, redisManager }) {
12
- this.applicationConfig = applicationConfig;
8
+ redisInstance;
9
+ constructor({ redisManager }) {
13
10
  this.redisManager = redisManager;
14
11
  }
15
- async getClient() {
16
- if (!this.client) {
17
- this.client = createClient({
18
- socket: {
19
- host: this.applicationConfig.redis.host,
20
- port: this.applicationConfig.redis.port
21
- }
22
- });
23
- await this.client.connect();
12
+ /**
13
+ * Ensure we have a connected RedisInstance. Reuses the first existing
14
+ * instance if already connected by the application bootstrap.
15
+ */
16
+ async getRedisInstance() {
17
+ if (this.redisInstance) return this.redisInstance;
18
+ if (this.redisManager.instances.length > 0) {
19
+ this.redisInstance = this.redisManager.instances[0];
20
+ return this.redisInstance;
24
21
  }
25
- return this.client;
22
+ this.redisInstance = await this.redisManager.connect();
23
+ return this.redisInstance;
26
24
  }
25
+ /**
26
+ * Get a cached JSON value (deserialized) or null if not present.
27
+ *
28
+ * @param key - Cache key
29
+ * @returns Deserialized value or null if not found
30
+ * @throws {Error} If the cached value is not valid JSON
31
+ *
32
+ * @example
33
+ * ```typescript
34
+ * const user = await cache.getItem<{ id: number; name: string }>({ key: 'user:123' });
35
+ * if (user) {
36
+ * console.log(user.name);
37
+ * }
38
+ * ```
39
+ */
27
40
  async getItem({ key }) {
28
- const client = await this.getClient();
29
- const value = await client.get(key);
30
- return value ? JSON.parse(value) : null;
41
+ const instance = await this.getRedisInstance();
42
+ const raw = await instance.getCache({ key });
43
+ if (raw === null) return null;
44
+ if (typeof raw !== "string") {
45
+ throw new Error(`Cache value for key "${key}" must be a string, got ${typeof raw}`);
46
+ }
47
+ try {
48
+ return JSON.parse(raw);
49
+ } catch (error) {
50
+ const errorMessage = error instanceof Error ? error.message : String(error);
51
+ throw new Error(`Failed to parse cached value for key "${key}": ${errorMessage}`);
52
+ }
31
53
  }
54
+ /**
55
+ * Set a JSON-serializable value. Optionally specify lifetime (seconds).
56
+ *
57
+ * @param key - Cache key
58
+ * @param value - Value to cache (must be JSON-serializable)
59
+ * @param lifetime - Optional expiration in seconds
60
+ *
61
+ * @example
62
+ * ```typescript
63
+ * // Cache with no expiration
64
+ * await cache.setItem({ key: 'config', value: { theme: 'dark' } });
65
+ *
66
+ * // Cache with 1 hour expiration
67
+ * await cache.setItem({
68
+ * key: 'session:abc',
69
+ * value: { userId: 123 },
70
+ * lifetime: 3600
71
+ * });
72
+ * ```
73
+ */
32
74
  async setItem({ key, value, lifetime }) {
33
- const client = await this.getClient();
34
- const stringValue = JSON.stringify(value);
35
- if (lifetime) {
36
- await client.setEx(key, lifetime, stringValue);
37
- } else {
38
- await client.set(key, stringValue);
39
- }
75
+ const instance = await this.getRedisInstance();
76
+ await instance.setCache({ key, value, expiration: lifetime });
40
77
  }
78
+ /**
79
+ * Delete a cached value.
80
+ *
81
+ * @param key - Cache key to delete
82
+ *
83
+ * @example
84
+ * ```typescript
85
+ * await cache.clearItem({ key: 'session:abc' });
86
+ * ```
87
+ */
41
88
  async clearItem({ key }) {
42
- const client = await this.getClient();
43
- await client.del(key);
89
+ const instance = await this.getRedisInstance();
90
+ await instance.deleteCache({ key });
44
91
  }
92
+ /**
93
+ * No-op: lifecycle handles Redis disconnection globally.
94
+ */
45
95
  async close() {
46
- if (this.client) {
47
- await this.client.quit();
48
- }
49
96
  }
50
97
  }
51
98
  export {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/cache/manager.ts"],
4
- "sourcesContent": ["import { type RedisClientType, createClient } from 'redis';\nimport type { ApplicationConfig } from '../application/base-application.interface.js';\nimport type RedisManager from '../redis/manager.js';\n\nexport interface CacheManagerProps {\n applicationConfig: ApplicationConfig;\n redisManager: RedisManager;\n}\n\nexport default class CacheManager {\n private client?: RedisClientType;\n\n private applicationConfig: ApplicationConfig;\n private redisManager: RedisManager;\n\n constructor({ applicationConfig, redisManager }: CacheManagerProps) {\n this.applicationConfig = applicationConfig;\n this.redisManager = redisManager;\n }\n\n private async getClient(): Promise<RedisClientType> {\n if (!this.client) {\n this.client = createClient({\n socket: {\n host: this.applicationConfig.redis.host,\n port: this.applicationConfig.redis.port,\n },\n });\n\n await this.client.connect();\n }\n return this.client;\n }\n\n public async getItem<T>({ key }: { key: string }): Promise<T | null> {\n const client = await this.getClient();\n const value = await client.get(key);\n\n return value ? JSON.parse(value) : null;\n }\n\n public async setItem<T>({ key, value, lifetime }: { key: string; value: T; lifetime?: number }): Promise<void> {\n const client = await this.getClient();\n const stringValue = JSON.stringify(value);\n\n if (lifetime) {\n await client.setEx(key, lifetime, stringValue);\n } else {\n await client.set(key, stringValue);\n }\n }\n\n public async clearItem({ key }: { key: string }): Promise<void> {\n const client = await this.getClient();\n await client.del(key);\n }\n\n public async close(): Promise<void> {\n if (this.client) {\n await this.client.quit();\n }\n }\n}\n"],
5
- "mappings": ";;AAAA,SAA+B,oBAAoB;AASnD,MAAO,aAA2B;AAAA,EATlC,OASkC;AAAA;AAAA;AAAA,EACxB;AAAA,EAEA;AAAA,EACA;AAAA,EAER,YAAY,EAAE,mBAAmB,aAAa,GAAsB;AAClE,SAAK,oBAAoB;AACzB,SAAK,eAAe;AAAA,EACtB;AAAA,EAEA,MAAc,YAAsC;AAClD,QAAI,CAAC,KAAK,QAAQ;AAChB,WAAK,SAAS,aAAa;AAAA,QACzB,QAAQ;AAAA,UACN,MAAM,KAAK,kBAAkB,MAAM;AAAA,UACnC,MAAM,KAAK,kBAAkB,MAAM;AAAA,QACrC;AAAA,MACF,CAAC;AAED,YAAM,KAAK,OAAO,QAAQ;AAAA,IAC5B;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAa,QAAW,EAAE,IAAI,GAAuC;AACnE,UAAM,SAAS,MAAM,KAAK,UAAU;AACpC,UAAM,QAAQ,MAAM,OAAO,IAAI,GAAG;AAElC,WAAO,QAAQ,KAAK,MAAM,KAAK,IAAI;AAAA,EACrC;AAAA,EAEA,MAAa,QAAW,EAAE,KAAK,OAAO,SAAS,GAAgE;AAC7G,UAAM,SAAS,MAAM,KAAK,UAAU;AACpC,UAAM,cAAc,KAAK,UAAU,KAAK;AAExC,QAAI,UAAU;AACZ,YAAM,OAAO,MAAM,KAAK,UAAU,WAAW;AAAA,IAC/C,OAAO;AACL,YAAM,OAAO,IAAI,KAAK,WAAW;AAAA,IACnC;AAAA,EACF;AAAA,EAEA,MAAa,UAAU,EAAE,IAAI,GAAmC;AAC9D,UAAM,SAAS,MAAM,KAAK,UAAU;AACpC,UAAM,OAAO,IAAI,GAAG;AAAA,EACtB;AAAA,EAEA,MAAa,QAAuB;AAClC,QAAI,KAAK,QAAQ;AACf,YAAM,KAAK,OAAO,KAAK;AAAA,IACzB;AAAA,EACF;AACF;",
4
+ "sourcesContent": ["import type RedisManager from '../redis/manager.js';\nimport type RedisInstance from '../redis/instance.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.redisInstance = await this.redisManager.connect();\n return this.redisInstance;\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 : String(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": ";;AAwCA,MAAO,aAA2B;AAAA,EAxClC,OAwCkC;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;AAEpC,QAAI,KAAK,aAAa,UAAU,SAAS,GAAG;AAC1C,WAAK,gBAAgB,KAAK,aAAa,UAAU,CAAC;AAClD,aAAO,KAAK;AAAA,IACd;AAGA,SAAK,gBAAgB,MAAM,KAAK,aAAa,QAAQ;AACrD,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,OAAO,KAAK;AAC1E,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
  }
@@ -1 +1 @@
1
- {"version":3,"file":"cluster-manager.d.ts","sourceRoot":"","sources":["../../src/cluster/cluster-manager.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAEV,mBAAmB,EAEpB,MAAM,gCAAgC,CAAC;AAIxC,MAAM,CAAC,OAAO,OAAO,cAAc;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuB;IAE9C,OAAO,CAAC,wBAAwB,CAAsB;IACtD,OAAO,CAAC,uBAAuB,CAAsB;IAErD,OAAO,CAAC,eAAe,CAA2C;IAClE,OAAO,CAAC,cAAc,CAAS;gBAEnB,EAAE,MAAM,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,EAAE,mBAAmB;IAOvF,KAAK,IAAI,IAAI;IAUpB,OAAO,CAAC,YAAY;YAqCN,WAAW;IAkBzB,OAAO,CAAC,cAAc;YAMR,gBAAgB;CAkC/B"}
1
+ {"version":3,"file":"cluster-manager.d.ts","sourceRoot":"","sources":["../../src/cluster/cluster-manager.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAEV,mBAAmB,EAEpB,MAAM,gCAAgC,CAAC;AAIxC,MAAM,CAAC,OAAO,OAAO,cAAc;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuB;IAE9C,OAAO,CAAC,wBAAwB,CAAsB;IACtD,OAAO,CAAC,uBAAuB,CAAsB;IAErD,OAAO,CAAC,eAAe,CAA2C;IAClE,OAAO,CAAC,cAAc,CAAS;gBAEnB,EAAE,MAAM,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,EAAE,mBAAmB;IAOvF,KAAK,IAAI,IAAI;IAUpB,OAAO,CAAC,YAAY;YAqCN,WAAW;IAkBzB,OAAO,CAAC,cAAc;YAMR,gBAAgB;CA6B/B"}
@@ -80,18 +80,15 @@ class ClusterManager {
80
80
  }
81
81
  this.isShuttingDown = true;
82
82
  if (cluster.isPrimary) {
83
- for (const id in cluster.workers) {
84
- const worker = cluster.workers[id];
85
- if (!worker) {
86
- continue;
83
+ Object.values(cluster.workers ?? {}).forEach((worker) => {
84
+ if (worker) {
85
+ worker.send("shutdown");
87
86
  }
88
- worker.send("shutdown");
89
- }
87
+ });
90
88
  let exitedWorkers = 0;
91
89
  cluster.on("exit", () => {
92
90
  exitedWorkers++;
93
- const clusterWorkers = cluster.workers ?? {};
94
- const numClusterWorkers = Object.keys(clusterWorkers).length;
91
+ const numClusterWorkers = Object.values(cluster.workers ?? {}).filter(Boolean).length;
95
92
  if (exitedWorkers === numClusterWorkers) {
96
93
  requestExit({ code: 0, reason: "cluster-workers-exited" });
97
94
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/cluster/cluster-manager.ts"],
4
- "sourcesContent": ["import cluster from 'node:cluster';\nimport { cpus } from 'node:os';\nimport type {\n ClusterManagerConfig,\n ClusterManagerProps,\n ClusterManagerWorkerModeManualConfig,\n} from './cluster-manager.interface.js';\nimport { Logger } from '../logger/index.js';\nimport { requestExit } from '../lifecycle/exit.js';\n\nexport default class ClusterManager {\n private readonly config: ClusterManagerConfig;\n\n private startApplicationCallback: () => Promise<void>;\n private stopApplicationCallback: () => Promise<void>;\n\n private shutdownSignals: NodeJS.Signals[] = ['SIGTERM', 'SIGINT'];\n private isShuttingDown = false;\n\n constructor({ config, startApplicationCallback, stopApplicationCallback }: ClusterManagerProps) {\n this.config = config;\n\n this.startApplicationCallback = startApplicationCallback;\n this.stopApplicationCallback = stopApplicationCallback;\n }\n\n public start(): void {\n if (cluster.isPrimary) {\n this.setupPrimary();\n } else {\n this.setupWorker();\n }\n\n this.handleShutdown();\n }\n\n private setupPrimary(): void {\n const numCPUs: number = cpus().length;\n\n const numClusterWorkers =\n this.config.workerMode === 'auto' ? numCPUs : (this.config as ClusterManagerWorkerModeManualConfig).workerCount;\n\n for (let workerIndex = 0; workerIndex < numClusterWorkers; workerIndex++) {\n cluster.fork();\n }\n\n cluster.on('online', worker => {\n Logger.debug({\n message: 'Started cluster worker',\n meta: {\n ID: worker.id,\n PID: worker.process.pid,\n },\n });\n });\n\n cluster.on('exit', () => {\n if (!this.isShuttingDown) {\n // Restart worker on unexpected exit\n cluster.fork();\n }\n });\n\n Logger.debug({\n message: 'Started cluster master',\n meta: {\n Mode: this.config.workerMode,\n 'Worker Count': numClusterWorkers,\n CPUs: numCPUs,\n },\n });\n }\n\n private async setupWorker(): Promise<void> {\n await this.startApplicationCallback();\n\n process.on('message', async message => {\n if (message === 'shutdown') {\n Logger.debug({\n message: 'Worker received shutdown message, stopping...',\n meta: {\n PID: process.pid,\n },\n });\n\n // Stop application\n await this.stopApplicationCallback();\n }\n });\n }\n\n private handleShutdown(): void {\n this.shutdownSignals.forEach(signal => {\n process.on(signal, async () => await this.initiateShutdown());\n });\n }\n\n private async initiateShutdown(): Promise<void> {\n if (this.isShuttingDown) {\n return;\n }\n\n this.isShuttingDown = true;\n\n if (cluster.isPrimary) {\n for (const id in cluster.workers) {\n const worker = cluster.workers[id];\n\n if (!worker) {\n continue;\n }\n\n worker.send('shutdown');\n }\n\n let exitedWorkers = 0;\n\n cluster.on('exit', () => {\n exitedWorkers++;\n\n const clusterWorkers = cluster.workers ?? {};\n const numClusterWorkers = Object.keys(clusterWorkers).length;\n\n if (exitedWorkers === numClusterWorkers) {\n requestExit({ code: 0, reason: 'cluster-workers-exited' });\n }\n });\n } else {\n await this.stopApplicationCallback();\n }\n }\n}\n"],
5
- "mappings": ";;AAAA,OAAO,aAAa;AACpB,SAAS,YAAY;AAMrB,SAAS,cAAc;AACvB,SAAS,mBAAmB;AAE5B,MAAO,eAA6B;AAAA,EAVpC,OAUoC;AAAA;AAAA;AAAA,EACjB;AAAA,EAET;AAAA,EACA;AAAA,EAEA,kBAAoC,CAAC,WAAW,QAAQ;AAAA,EACxD,iBAAiB;AAAA,EAEzB,YAAY,EAAE,QAAQ,0BAA0B,wBAAwB,GAAwB;AAC9F,SAAK,SAAS;AAEd,SAAK,2BAA2B;AAChC,SAAK,0BAA0B;AAAA,EACjC;AAAA,EAEO,QAAc;AACnB,QAAI,QAAQ,WAAW;AACrB,WAAK,aAAa;AAAA,IACpB,OAAO;AACL,WAAK,YAAY;AAAA,IACnB;AAEA,SAAK,eAAe;AAAA,EACtB;AAAA,EAEQ,eAAqB;AAC3B,UAAM,UAAkB,KAAK,EAAE;AAE/B,UAAM,oBACJ,KAAK,OAAO,eAAe,SAAS,UAAW,KAAK,OAAgD;AAEtG,aAAS,cAAc,GAAG,cAAc,mBAAmB,eAAe;AACxE,cAAQ,KAAK;AAAA,IACf;AAEA,YAAQ,GAAG,UAAU,YAAU;AAC7B,aAAO,MAAM;AAAA,QACX,SAAS;AAAA,QACT,MAAM;AAAA,UACJ,IAAI,OAAO;AAAA,UACX,KAAK,OAAO,QAAQ;AAAA,QACtB;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAED,YAAQ,GAAG,QAAQ,MAAM;AACvB,UAAI,CAAC,KAAK,gBAAgB;AAExB,gBAAQ,KAAK;AAAA,MACf;AAAA,IACF,CAAC;AAED,WAAO,MAAM;AAAA,MACX,SAAS;AAAA,MACT,MAAM;AAAA,QACJ,MAAM,KAAK,OAAO;AAAA,QAClB,gBAAgB;AAAA,QAChB,MAAM;AAAA,MACR;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,cAA6B;AACzC,UAAM,KAAK,yBAAyB;AAEpC,YAAQ,GAAG,WAAW,OAAM,YAAW;AACrC,UAAI,YAAY,YAAY;AAC1B,eAAO,MAAM;AAAA,UACX,SAAS;AAAA,UACT,MAAM;AAAA,YACJ,KAAK,QAAQ;AAAA,UACf;AAAA,QACF,CAAC;AAGD,cAAM,KAAK,wBAAwB;AAAA,MACrC;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEQ,iBAAuB;AAC7B,SAAK,gBAAgB,QAAQ,YAAU;AACrC,cAAQ,GAAG,QAAQ,YAAY,MAAM,KAAK,iBAAiB,CAAC;AAAA,IAC9D,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,mBAAkC;AAC9C,QAAI,KAAK,gBAAgB;AACvB;AAAA,IACF;AAEA,SAAK,iBAAiB;AAEtB,QAAI,QAAQ,WAAW;AACrB,iBAAW,MAAM,QAAQ,SAAS;AAChC,cAAM,SAAS,QAAQ,QAAQ,EAAE;AAEjC,YAAI,CAAC,QAAQ;AACX;AAAA,QACF;AAEA,eAAO,KAAK,UAAU;AAAA,MACxB;AAEA,UAAI,gBAAgB;AAEpB,cAAQ,GAAG,QAAQ,MAAM;AACvB;AAEA,cAAM,iBAAiB,QAAQ,WAAW,CAAC;AAC3C,cAAM,oBAAoB,OAAO,KAAK,cAAc,EAAE;AAEtD,YAAI,kBAAkB,mBAAmB;AACvC,sBAAY,EAAE,MAAM,GAAG,QAAQ,yBAAyB,CAAC;AAAA,QAC3D;AAAA,MACF,CAAC;AAAA,IACH,OAAO;AACL,YAAM,KAAK,wBAAwB;AAAA,IACrC;AAAA,EACF;AACF;",
4
+ "sourcesContent": ["import cluster from 'node:cluster';\nimport { cpus } from 'node:os';\nimport type {\n ClusterManagerConfig,\n ClusterManagerProps,\n ClusterManagerWorkerModeManualConfig,\n} from './cluster-manager.interface.js';\nimport { Logger } from '../logger/index.js';\nimport { requestExit } from '../lifecycle/exit.js';\n\nexport default class ClusterManager {\n private readonly config: ClusterManagerConfig;\n\n private startApplicationCallback: () => Promise<void>;\n private stopApplicationCallback: () => Promise<void>;\n\n private shutdownSignals: NodeJS.Signals[] = ['SIGTERM', 'SIGINT'];\n private isShuttingDown = false;\n\n constructor({ config, startApplicationCallback, stopApplicationCallback }: ClusterManagerProps) {\n this.config = config;\n\n this.startApplicationCallback = startApplicationCallback;\n this.stopApplicationCallback = stopApplicationCallback;\n }\n\n public start(): void {\n if (cluster.isPrimary) {\n this.setupPrimary();\n } else {\n this.setupWorker();\n }\n\n this.handleShutdown();\n }\n\n private setupPrimary(): void {\n const numCPUs: number = cpus().length;\n\n const numClusterWorkers =\n this.config.workerMode === 'auto' ? numCPUs : (this.config as ClusterManagerWorkerModeManualConfig).workerCount;\n\n for (let workerIndex = 0; workerIndex < numClusterWorkers; workerIndex++) {\n cluster.fork();\n }\n\n cluster.on('online', worker => {\n Logger.debug({\n message: 'Started cluster worker',\n meta: {\n ID: worker.id,\n PID: worker.process.pid,\n },\n });\n });\n\n cluster.on('exit', () => {\n if (!this.isShuttingDown) {\n // Restart worker on unexpected exit\n cluster.fork();\n }\n });\n\n Logger.debug({\n message: 'Started cluster master',\n meta: {\n Mode: this.config.workerMode,\n 'Worker Count': numClusterWorkers,\n CPUs: numCPUs,\n },\n });\n }\n\n private async setupWorker(): Promise<void> {\n await this.startApplicationCallback();\n\n process.on('message', async message => {\n if (message === 'shutdown') {\n Logger.debug({\n message: 'Worker received shutdown message, stopping...',\n meta: {\n PID: process.pid,\n },\n });\n\n // Stop application\n await this.stopApplicationCallback();\n }\n });\n }\n\n private handleShutdown(): void {\n this.shutdownSignals.forEach(signal => {\n process.on(signal, async () => await this.initiateShutdown());\n });\n }\n\n private async initiateShutdown(): Promise<void> {\n if (this.isShuttingDown) {\n return;\n }\n\n this.isShuttingDown = true;\n\n if (cluster.isPrimary) {\n Object.values(cluster.workers ?? {}).forEach(worker => {\n if (worker) {\n worker.send('shutdown');\n }\n });\n\n let exitedWorkers = 0;\n\n cluster.on('exit', () => {\n exitedWorkers++;\n\n const numClusterWorkers = Object.values(cluster.workers ?? {}).filter(Boolean).length;\n\n if (exitedWorkers === numClusterWorkers) {\n requestExit({ code: 0, reason: 'cluster-workers-exited' });\n }\n });\n } else {\n await this.stopApplicationCallback();\n }\n }\n}\n"],
5
+ "mappings": ";;AAAA,OAAO,aAAa;AACpB,SAAS,YAAY;AAMrB,SAAS,cAAc;AACvB,SAAS,mBAAmB;AAE5B,MAAO,eAA6B;AAAA,EAVpC,OAUoC;AAAA;AAAA;AAAA,EACjB;AAAA,EAET;AAAA,EACA;AAAA,EAEA,kBAAoC,CAAC,WAAW,QAAQ;AAAA,EACxD,iBAAiB;AAAA,EAEzB,YAAY,EAAE,QAAQ,0BAA0B,wBAAwB,GAAwB;AAC9F,SAAK,SAAS;AAEd,SAAK,2BAA2B;AAChC,SAAK,0BAA0B;AAAA,EACjC;AAAA,EAEO,QAAc;AACnB,QAAI,QAAQ,WAAW;AACrB,WAAK,aAAa;AAAA,IACpB,OAAO;AACL,WAAK,YAAY;AAAA,IACnB;AAEA,SAAK,eAAe;AAAA,EACtB;AAAA,EAEQ,eAAqB;AAC3B,UAAM,UAAkB,KAAK,EAAE;AAE/B,UAAM,oBACJ,KAAK,OAAO,eAAe,SAAS,UAAW,KAAK,OAAgD;AAEtG,aAAS,cAAc,GAAG,cAAc,mBAAmB,eAAe;AACxE,cAAQ,KAAK;AAAA,IACf;AAEA,YAAQ,GAAG,UAAU,YAAU;AAC7B,aAAO,MAAM;AAAA,QACX,SAAS;AAAA,QACT,MAAM;AAAA,UACJ,IAAI,OAAO;AAAA,UACX,KAAK,OAAO,QAAQ;AAAA,QACtB;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAED,YAAQ,GAAG,QAAQ,MAAM;AACvB,UAAI,CAAC,KAAK,gBAAgB;AAExB,gBAAQ,KAAK;AAAA,MACf;AAAA,IACF,CAAC;AAED,WAAO,MAAM;AAAA,MACX,SAAS;AAAA,MACT,MAAM;AAAA,QACJ,MAAM,KAAK,OAAO;AAAA,QAClB,gBAAgB;AAAA,QAChB,MAAM;AAAA,MACR;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,cAA6B;AACzC,UAAM,KAAK,yBAAyB;AAEpC,YAAQ,GAAG,WAAW,OAAM,YAAW;AACrC,UAAI,YAAY,YAAY;AAC1B,eAAO,MAAM;AAAA,UACX,SAAS;AAAA,UACT,MAAM;AAAA,YACJ,KAAK,QAAQ;AAAA,UACf;AAAA,QACF,CAAC;AAGD,cAAM,KAAK,wBAAwB;AAAA,MACrC;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEQ,iBAAuB;AAC7B,SAAK,gBAAgB,QAAQ,YAAU;AACrC,cAAQ,GAAG,QAAQ,YAAY,MAAM,KAAK,iBAAiB,CAAC;AAAA,IAC9D,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,mBAAkC;AAC9C,QAAI,KAAK,gBAAgB;AACvB;AAAA,IACF;AAEA,SAAK,iBAAiB;AAEtB,QAAI,QAAQ,WAAW;AACrB,aAAO,OAAO,QAAQ,WAAW,CAAC,CAAC,EAAE,QAAQ,YAAU;AACrD,YAAI,QAAQ;AACV,iBAAO,KAAK,UAAU;AAAA,QACxB;AAAA,MACF,CAAC;AAED,UAAI,gBAAgB;AAEpB,cAAQ,GAAG,QAAQ,MAAM;AACvB;AAEA,cAAM,oBAAoB,OAAO,OAAO,QAAQ,WAAW,CAAC,CAAC,EAAE,OAAO,OAAO,EAAE;AAE/E,YAAI,kBAAkB,mBAAmB;AACvC,sBAAY,EAAE,MAAM,GAAG,QAAQ,yBAAyB,CAAC;AAAA,QAC3D;AAAA,MACF,CAAC;AAAA,IACH,OAAO;AACL,YAAM,KAAK,wBAAwB;AAAA,IACrC;AAAA,EACF;AACF;",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,11 @@
1
+ import { type InferFrameworkConfig } from './schema.js';
2
+ /**
3
+ * Load a partial framework configuration from environment variables. This is intentionally
4
+ * conservative: only widely useful primitives are supported. Complex structures (e.g. routes)
5
+ * should be defined in code and merged before validation.
6
+ *
7
+ * Naming convention: PXL_<SECTION>_<FIELD>
8
+ */
9
+ export declare function loadFrameworkConfigFromEnv(): Partial<InferFrameworkConfig>;
10
+ /** Deep merge helper (shallow for primitives & plain objects) */
11
+ //# sourceMappingURL=env.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../src/config/env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAsBxD;;;;;;GAMG;AACH,wBAAgB,0BAA0B,IAAI,OAAO,CAAC,oBAAoB,CAAC,CA6F1E;AAED,iEAAiE"}
@@ -0,0 +1,103 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
+ function parseBool(v) {
4
+ if (v == null) return void 0;
5
+ return /^(true|1|yes|on)$/i.test(v);
6
+ }
7
+ __name(parseBool, "parseBool");
8
+ function parseIntEnv(v) {
9
+ if (v == null) return void 0;
10
+ const n = Number(v);
11
+ return Number.isFinite(n) ? n : void 0;
12
+ }
13
+ __name(parseIntEnv, "parseIntEnv");
14
+ function splitCsv(v) {
15
+ if (!v) return void 0;
16
+ return v.split(",").map((s) => s.trim()).filter(Boolean);
17
+ }
18
+ __name(splitCsv, "splitCsv");
19
+ function loadFrameworkConfigFromEnv() {
20
+ const env = process.env;
21
+ const redis = {
22
+ host: env.PXL_REDIS_HOST,
23
+ port: parseIntEnv(env.PXL_REDIS_PORT),
24
+ password: env.PXL_REDIS_PASSWORD
25
+ };
26
+ if (!redis.host) delete redis.host;
27
+ if (!redis.port) delete redis.port;
28
+ if (!redis.password) delete redis.password;
29
+ const databaseEnabled = parseBool(env.PXL_DB_ENABLED);
30
+ const database = {
31
+ enabled: databaseEnabled,
32
+ host: env.PXL_DB_HOST,
33
+ port: parseIntEnv(env.PXL_DB_PORT),
34
+ username: env.PXL_DB_USERNAME,
35
+ password: env.PXL_DB_PASSWORD,
36
+ databaseName: env.PXL_DB_NAME,
37
+ entitiesDirectory: env.PXL_DB_ENTITIES_DIR
38
+ };
39
+ const databaseFinal = {
40
+ ...database.enabled !== void 0 ? { enabled: database.enabled } : {},
41
+ ...database.host ? { host: database.host } : {},
42
+ ...database.port !== void 0 ? { port: database.port } : {},
43
+ ...database.username ? { username: database.username } : {},
44
+ ...database.password ? { password: database.password } : {},
45
+ ...database.databaseName ? { databaseName: database.databaseName } : {},
46
+ ...database.entitiesDirectory ? { entitiesDirectory: database.entitiesDirectory } : {}
47
+ };
48
+ const hasDatabaseConfig = Object.keys(databaseFinal).length > 0;
49
+ const queueProcessorsDirectory = env.PXL_QUEUE_PROCESSORS_DIR;
50
+ const queueQueues = splitCsv(env.PXL_QUEUE_QUEUES)?.map((name2) => ({ name: name2, jobs: [] }));
51
+ const queue = {};
52
+ if (queueProcessorsDirectory) queue.processorsDirectory = queueProcessorsDirectory;
53
+ if (queueQueues) queue.queues = queueQueues;
54
+ const webEnabled = parseBool(env.PXL_WEB_ENABLED);
55
+ const webCorsEnabled = parseBool(env.PXL_WEB_CORS_ENABLED);
56
+ const webCorsUrls = splitCsv(env.PXL_WEB_CORS_URLS);
57
+ const webBodyLimit = parseIntEnv(env.PXL_WEB_BODY_LIMIT);
58
+ const webPort = parseIntEnv(env.PXL_WEB_PORT);
59
+ const web = {};
60
+ if (webEnabled !== void 0) web.enabled = webEnabled;
61
+ if (env.PXL_WEB_HOST) web.host = env.PXL_WEB_HOST;
62
+ if (webPort !== void 0) web.port = webPort;
63
+ if (webBodyLimit !== void 0) web.bodyLimit = webBodyLimit;
64
+ if (webCorsEnabled || webCorsUrls && webCorsUrls.length > 0) {
65
+ web.cors = { enabled: webCorsEnabled ?? true, urls: webCorsUrls ?? [] };
66
+ }
67
+ const auth = {};
68
+ if (env.PXL_AUTH_JWT_SECRET_KEY) auth.jwtSecretKey = env.PXL_AUTH_JWT_SECRET_KEY;
69
+ const cluster = {};
70
+ const clusterEnabled = parseBool(env.PXL_CLUSTER_ENABLED);
71
+ if (clusterEnabled !== void 0) cluster.enabled = clusterEnabled;
72
+ const clusterWorkers = parseIntEnv(env.PXL_CLUSTER_WORKERS);
73
+ if (clusterWorkers !== void 0) cluster.workers = clusterWorkers;
74
+ if (Object.keys(cluster).length === 0) {
75
+ }
76
+ const performanceMonitoring = {};
77
+ const perfEnabled = parseBool(env.PXL_PERF_ENABLED);
78
+ if (perfEnabled !== void 0) performanceMonitoring.enabled = perfEnabled;
79
+ const perfInterval = parseIntEnv(env.PXL_PERF_REPORT_INTERVAL_MS);
80
+ if (perfInterval !== void 0) performanceMonitoring.reportInterval = perfInterval;
81
+ if (Object.keys(performanceMonitoring).length === 0) {
82
+ }
83
+ const name = env.PXL_NAME;
84
+ const instanceId = env.PXL_INSTANCE_ID;
85
+ const rootDirectory = env.PXL_ROOT_DIR;
86
+ const partial = {};
87
+ if (name) partial.name = name;
88
+ if (instanceId) partial.instanceId = instanceId;
89
+ if (rootDirectory) partial.rootDirectory = rootDirectory;
90
+ if (redis.host || redis.port || redis.password) partial.redis = redis;
91
+ if (hasDatabaseConfig) partial.database = databaseFinal;
92
+ if (Object.keys(queue).length > 0) partial.queue = queue;
93
+ if (Object.keys(web).length > 0) partial.web = web;
94
+ if (Object.keys(auth).length > 0) partial.auth = auth;
95
+ if (Object.keys(cluster).length > 0) partial.cluster = cluster;
96
+ if (Object.keys(performanceMonitoring).length > 0) partial.performanceMonitoring = performanceMonitoring;
97
+ return partial;
98
+ }
99
+ __name(loadFrameworkConfigFromEnv, "loadFrameworkConfigFromEnv");
100
+ export {
101
+ loadFrameworkConfigFromEnv
102
+ };
103
+ //# sourceMappingURL=env.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/config/env.ts"],
4
+ "sourcesContent": ["import { type InferFrameworkConfig } from './schema.js';\n\n// Helper to parse booleans like 'true', '1', 'yes'\nfunction parseBool(v: string | undefined): boolean | undefined {\n if (v == null) return undefined;\n return /^(true|1|yes|on)$/i.test(v);\n}\n\nfunction parseIntEnv(v: string | undefined): number | undefined {\n if (v == null) return undefined;\n const n = Number(v);\n return Number.isFinite(n) ? n : undefined;\n}\n\nfunction splitCsv(v: string | undefined): string[] | undefined {\n if (!v) return undefined;\n return v\n .split(',')\n .map(s => s.trim())\n .filter(Boolean);\n}\n\n/**\n * Load a partial framework configuration from environment variables. This is intentionally\n * conservative: only widely useful primitives are supported. Complex structures (e.g. routes)\n * should be defined in code and merged before validation.\n *\n * Naming convention: PXL_<SECTION>_<FIELD>\n */\nexport function loadFrameworkConfigFromEnv(): Partial<InferFrameworkConfig> {\n const env = process.env;\n\n const redis = {\n host: env.PXL_REDIS_HOST,\n port: parseIntEnv(env.PXL_REDIS_PORT),\n password: env.PXL_REDIS_PASSWORD,\n };\n if (!redis.host) delete (redis as any).host; // allow omission\n if (!redis.port) delete (redis as any).port;\n if (!redis.password) delete (redis as any).password;\n\n const databaseEnabled = parseBool(env.PXL_DB_ENABLED);\n const database = {\n enabled: databaseEnabled,\n host: env.PXL_DB_HOST,\n port: parseIntEnv(env.PXL_DB_PORT),\n username: env.PXL_DB_USERNAME,\n password: env.PXL_DB_PASSWORD,\n databaseName: env.PXL_DB_NAME,\n entitiesDirectory: env.PXL_DB_ENTITIES_DIR,\n };\n // prune undefined fields so Zod defaults/optionals apply\n const databaseFinal = {\n ...(database.enabled !== undefined ? { enabled: database.enabled } : {}),\n ...(database.host ? { host: database.host } : {}),\n ...(database.port !== undefined ? { port: database.port } : {}),\n ...(database.username ? { username: database.username } : {}),\n ...(database.password ? { password: database.password } : {}),\n ...(database.databaseName ? { databaseName: database.databaseName } : {}),\n ...(database.entitiesDirectory ? { entitiesDirectory: database.entitiesDirectory } : {}),\n } as any;\n const hasDatabaseConfig = Object.keys(databaseFinal).length > 0;\n\n const queueProcessorsDirectory = env.PXL_QUEUE_PROCESSORS_DIR;\n const queueQueues = splitCsv(env.PXL_QUEUE_QUEUES)?.map(name => ({ name, jobs: [] }));\n const queue: any = {};\n if (queueProcessorsDirectory) queue.processorsDirectory = queueProcessorsDirectory;\n if (queueQueues) queue.queues = queueQueues;\n\n const webEnabled = parseBool(env.PXL_WEB_ENABLED);\n const webCorsEnabled = parseBool(env.PXL_WEB_CORS_ENABLED);\n const webCorsUrls = splitCsv(env.PXL_WEB_CORS_URLS);\n const webBodyLimit = parseIntEnv(env.PXL_WEB_BODY_LIMIT);\n const webPort = parseIntEnv(env.PXL_WEB_PORT);\n const web: any = {};\n if (webEnabled !== undefined) web.enabled = webEnabled;\n if (env.PXL_WEB_HOST) web.host = env.PXL_WEB_HOST;\n if (webPort !== undefined) web.port = webPort;\n if (webBodyLimit !== undefined) web.bodyLimit = webBodyLimit;\n if (webCorsEnabled || (webCorsUrls && webCorsUrls.length > 0)) {\n web.cors = { enabled: webCorsEnabled ?? true, urls: webCorsUrls ?? [] };\n }\n\n const auth: any = {};\n if (env.PXL_AUTH_JWT_SECRET_KEY) auth.jwtSecretKey = env.PXL_AUTH_JWT_SECRET_KEY;\n\n const cluster: any = {};\n const clusterEnabled = parseBool(env.PXL_CLUSTER_ENABLED);\n if (clusterEnabled !== undefined) cluster.enabled = clusterEnabled;\n const clusterWorkers = parseIntEnv(env.PXL_CLUSTER_WORKERS);\n if (clusterWorkers !== undefined) cluster.workers = clusterWorkers;\n if (Object.keys(cluster).length === 0) {\n // leave cluster undefined later\n }\n\n const performanceMonitoring: any = {};\n const perfEnabled = parseBool(env.PXL_PERF_ENABLED);\n if (perfEnabled !== undefined) performanceMonitoring.enabled = perfEnabled;\n const perfInterval = parseIntEnv(env.PXL_PERF_REPORT_INTERVAL_MS);\n if (perfInterval !== undefined) performanceMonitoring.reportInterval = perfInterval;\n if (Object.keys(performanceMonitoring).length === 0) {\n // leave undefined later\n }\n\n const name = env.PXL_NAME;\n const instanceId = env.PXL_INSTANCE_ID;\n const rootDirectory = env.PXL_ROOT_DIR;\n\n // assemble partial, removing empty objects\n const partial: Partial<InferFrameworkConfig> = {};\n if (name) partial.name = name;\n if (instanceId) partial.instanceId = instanceId;\n if (rootDirectory) partial.rootDirectory = rootDirectory;\n if (redis.host || redis.port || redis.password) partial.redis = redis as any;\n if (hasDatabaseConfig) partial.database = databaseFinal;\n if (Object.keys(queue).length > 0) partial.queue = queue;\n if (Object.keys(web).length > 0) partial.web = web;\n if (Object.keys(auth).length > 0) partial.auth = auth;\n if (Object.keys(cluster).length > 0) partial.cluster = cluster;\n if (Object.keys(performanceMonitoring).length > 0) partial.performanceMonitoring = performanceMonitoring;\n\n return partial;\n}\n\n/** Deep merge helper (shallow for primitives & plain objects) */\n// mergeConfig intentionally removed (security lint). If needed later, implement with explicit key lists.\n"],
5
+ "mappings": ";;AAGA,SAAS,UAAU,GAA4C;AAC7D,MAAI,KAAK,KAAM,QAAO;AACtB,SAAO,qBAAqB,KAAK,CAAC;AACpC;AAHS;AAKT,SAAS,YAAY,GAA2C;AAC9D,MAAI,KAAK,KAAM,QAAO;AACtB,QAAM,IAAI,OAAO,CAAC;AAClB,SAAO,OAAO,SAAS,CAAC,IAAI,IAAI;AAClC;AAJS;AAMT,SAAS,SAAS,GAA6C;AAC7D,MAAI,CAAC,EAAG,QAAO;AACf,SAAO,EACJ,MAAM,GAAG,EACT,IAAI,OAAK,EAAE,KAAK,CAAC,EACjB,OAAO,OAAO;AACnB;AANS;AAeF,SAAS,6BAA4D;AAC1E,QAAM,MAAM,QAAQ;AAEpB,QAAM,QAAQ;AAAA,IACZ,MAAM,IAAI;AAAA,IACV,MAAM,YAAY,IAAI,cAAc;AAAA,IACpC,UAAU,IAAI;AAAA,EAChB;AACA,MAAI,CAAC,MAAM,KAAM,QAAQ,MAAc;AACvC,MAAI,CAAC,MAAM,KAAM,QAAQ,MAAc;AACvC,MAAI,CAAC,MAAM,SAAU,QAAQ,MAAc;AAE3C,QAAM,kBAAkB,UAAU,IAAI,cAAc;AACpD,QAAM,WAAW;AAAA,IACf,SAAS;AAAA,IACT,MAAM,IAAI;AAAA,IACV,MAAM,YAAY,IAAI,WAAW;AAAA,IACjC,UAAU,IAAI;AAAA,IACd,UAAU,IAAI;AAAA,IACd,cAAc,IAAI;AAAA,IAClB,mBAAmB,IAAI;AAAA,EACzB;AAEA,QAAM,gBAAgB;AAAA,IACpB,GAAI,SAAS,YAAY,SAAY,EAAE,SAAS,SAAS,QAAQ,IAAI,CAAC;AAAA,IACtE,GAAI,SAAS,OAAO,EAAE,MAAM,SAAS,KAAK,IAAI,CAAC;AAAA,IAC/C,GAAI,SAAS,SAAS,SAAY,EAAE,MAAM,SAAS,KAAK,IAAI,CAAC;AAAA,IAC7D,GAAI,SAAS,WAAW,EAAE,UAAU,SAAS,SAAS,IAAI,CAAC;AAAA,IAC3D,GAAI,SAAS,WAAW,EAAE,UAAU,SAAS,SAAS,IAAI,CAAC;AAAA,IAC3D,GAAI,SAAS,eAAe,EAAE,cAAc,SAAS,aAAa,IAAI,CAAC;AAAA,IACvE,GAAI,SAAS,oBAAoB,EAAE,mBAAmB,SAAS,kBAAkB,IAAI,CAAC;AAAA,EACxF;AACA,QAAM,oBAAoB,OAAO,KAAK,aAAa,EAAE,SAAS;AAE9D,QAAM,2BAA2B,IAAI;AACrC,QAAM,cAAc,SAAS,IAAI,gBAAgB,GAAG,IAAI,CAAAA,WAAS,EAAE,MAAAA,OAAM,MAAM,CAAC,EAAE,EAAE;AACpF,QAAM,QAAa,CAAC;AACpB,MAAI,yBAA0B,OAAM,sBAAsB;AAC1D,MAAI,YAAa,OAAM,SAAS;AAEhC,QAAM,aAAa,UAAU,IAAI,eAAe;AAChD,QAAM,iBAAiB,UAAU,IAAI,oBAAoB;AACzD,QAAM,cAAc,SAAS,IAAI,iBAAiB;AAClD,QAAM,eAAe,YAAY,IAAI,kBAAkB;AACvD,QAAM,UAAU,YAAY,IAAI,YAAY;AAC5C,QAAM,MAAW,CAAC;AAClB,MAAI,eAAe,OAAW,KAAI,UAAU;AAC5C,MAAI,IAAI,aAAc,KAAI,OAAO,IAAI;AACrC,MAAI,YAAY,OAAW,KAAI,OAAO;AACtC,MAAI,iBAAiB,OAAW,KAAI,YAAY;AAChD,MAAI,kBAAmB,eAAe,YAAY,SAAS,GAAI;AAC7D,QAAI,OAAO,EAAE,SAAS,kBAAkB,MAAM,MAAM,eAAe,CAAC,EAAE;AAAA,EACxE;AAEA,QAAM,OAAY,CAAC;AACnB,MAAI,IAAI,wBAAyB,MAAK,eAAe,IAAI;AAEzD,QAAM,UAAe,CAAC;AACtB,QAAM,iBAAiB,UAAU,IAAI,mBAAmB;AACxD,MAAI,mBAAmB,OAAW,SAAQ,UAAU;AACpD,QAAM,iBAAiB,YAAY,IAAI,mBAAmB;AAC1D,MAAI,mBAAmB,OAAW,SAAQ,UAAU;AACpD,MAAI,OAAO,KAAK,OAAO,EAAE,WAAW,GAAG;AAAA,EAEvC;AAEA,QAAM,wBAA6B,CAAC;AACpC,QAAM,cAAc,UAAU,IAAI,gBAAgB;AAClD,MAAI,gBAAgB,OAAW,uBAAsB,UAAU;AAC/D,QAAM,eAAe,YAAY,IAAI,2BAA2B;AAChE,MAAI,iBAAiB,OAAW,uBAAsB,iBAAiB;AACvE,MAAI,OAAO,KAAK,qBAAqB,EAAE,WAAW,GAAG;AAAA,EAErD;AAEA,QAAM,OAAO,IAAI;AACjB,QAAM,aAAa,IAAI;AACvB,QAAM,gBAAgB,IAAI;AAG1B,QAAM,UAAyC,CAAC;AAChD,MAAI,KAAM,SAAQ,OAAO;AACzB,MAAI,WAAY,SAAQ,aAAa;AACrC,MAAI,cAAe,SAAQ,gBAAgB;AAC3C,MAAI,MAAM,QAAQ,MAAM,QAAQ,MAAM,SAAU,SAAQ,QAAQ;AAChE,MAAI,kBAAmB,SAAQ,WAAW;AAC1C,MAAI,OAAO,KAAK,KAAK,EAAE,SAAS,EAAG,SAAQ,QAAQ;AACnD,MAAI,OAAO,KAAK,GAAG,EAAE,SAAS,EAAG,SAAQ,MAAM;AAC/C,MAAI,OAAO,KAAK,IAAI,EAAE,SAAS,EAAG,SAAQ,OAAO;AACjD,MAAI,OAAO,KAAK,OAAO,EAAE,SAAS,EAAG,SAAQ,UAAU;AACvD,MAAI,OAAO,KAAK,qBAAqB,EAAE,SAAS,EAAG,SAAQ,wBAAwB;AAEnF,SAAO;AACT;AA7FgB;",
6
+ "names": ["name"]
7
+ }
@@ -0,0 +1,3 @@
1
+ export * from './schema.js';
2
+ export * from './env.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from "./schema.js";
2
+ export * from "./env.js";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/config/index.ts"],
4
+ "sourcesContent": ["export * from './schema.js';\nexport * from './env.js';\n"],
5
+ "mappings": "AAAA,cAAc;AACd,cAAc;",
6
+ "names": []
7
+ }