create-fluxstack 1.0.13 → 1.0.15

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 (214) hide show
  1. package/.env.example +29 -29
  2. package/app/client/README.md +69 -69
  3. package/app/client/index.html +14 -13
  4. package/app/client/src/App.tsx +157 -524
  5. package/app/client/src/components/ErrorBoundary.tsx +107 -0
  6. package/app/client/src/components/ErrorDisplay.css +365 -0
  7. package/app/client/src/components/ErrorDisplay.tsx +258 -0
  8. package/app/client/src/components/FluxStackConfig.tsx +1321 -0
  9. package/app/client/src/components/HybridLiveCounter.tsx +140 -0
  10. package/app/client/src/components/LiveClock.tsx +286 -0
  11. package/app/client/src/components/MainLayout.tsx +390 -0
  12. package/app/client/src/components/SidebarNavigation.tsx +391 -0
  13. package/app/client/src/components/StateDemo.tsx +178 -0
  14. package/app/client/src/components/SystemMonitor.tsx +1038 -0
  15. package/app/client/src/components/Teste.tsx +104 -0
  16. package/app/client/src/components/UserProfile.tsx +809 -0
  17. package/app/client/src/hooks/useAuth.ts +39 -0
  18. package/app/client/src/hooks/useNotifications.ts +56 -0
  19. package/app/client/src/lib/eden-api.ts +189 -53
  20. package/app/client/src/lib/errors.ts +340 -0
  21. package/app/client/src/lib/hooks/useErrorHandler.ts +258 -0
  22. package/app/client/src/lib/index.ts +45 -0
  23. package/app/client/src/main.tsx +3 -2
  24. package/app/client/src/pages/ApiDocs.tsx +182 -0
  25. package/app/client/src/pages/Demo.tsx +174 -0
  26. package/app/client/src/pages/HybridLive.tsx +263 -0
  27. package/app/client/src/pages/Overview.tsx +155 -0
  28. package/app/client/src/store/README.md +43 -0
  29. package/app/client/src/store/index.ts +16 -0
  30. package/app/client/src/store/slices/uiSlice.ts +151 -0
  31. package/app/client/src/store/slices/userSlice.ts +161 -0
  32. package/app/client/src/test/README.md +257 -0
  33. package/app/client/src/test/setup.ts +70 -0
  34. package/app/client/src/test/types.ts +12 -0
  35. package/app/client/src/vite-env.d.ts +1 -1
  36. package/app/client/tsconfig.app.json +44 -43
  37. package/app/client/tsconfig.json +7 -7
  38. package/app/client/tsconfig.node.json +25 -25
  39. package/app/client/zustand-setup.md +65 -0
  40. package/app/server/controllers/users.controller.ts +68 -68
  41. package/app/server/index.ts +9 -1
  42. package/app/server/live/CounterComponent.ts +191 -0
  43. package/app/server/live/FluxStackConfig.ts +529 -0
  44. package/app/server/live/LiveClockComponent.ts +214 -0
  45. package/app/server/live/SidebarNavigation.ts +156 -0
  46. package/app/server/live/SystemMonitor.ts +594 -0
  47. package/app/server/live/SystemMonitorIntegration.ts +151 -0
  48. package/app/server/live/TesteComponent.ts +87 -0
  49. package/app/server/live/UserProfileComponent.ts +135 -0
  50. package/app/server/live/register-components.ts +28 -0
  51. package/app/server/middleware/auth.ts +136 -0
  52. package/app/server/middleware/errorHandling.ts +250 -0
  53. package/app/server/middleware/index.ts +10 -0
  54. package/app/server/middleware/rateLimit.ts +193 -0
  55. package/app/server/middleware/requestLogging.ts +215 -0
  56. package/app/server/middleware/validation.ts +270 -0
  57. package/app/server/routes/index.ts +14 -2
  58. package/app/server/routes/upload.ts +92 -0
  59. package/app/server/routes/users.routes.ts +2 -9
  60. package/app/server/services/NotificationService.ts +302 -0
  61. package/app/server/services/UserService.ts +222 -0
  62. package/app/server/services/index.ts +46 -0
  63. package/core/cli/commands/plugin-deps.ts +263 -0
  64. package/core/cli/generators/README.md +339 -0
  65. package/core/cli/generators/component.ts +770 -0
  66. package/core/cli/generators/controller.ts +299 -0
  67. package/core/cli/generators/index.ts +144 -0
  68. package/core/cli/generators/interactive.ts +228 -0
  69. package/core/cli/generators/prompts.ts +83 -0
  70. package/core/cli/generators/route.ts +513 -0
  71. package/core/cli/generators/service.ts +465 -0
  72. package/core/cli/generators/template-engine.ts +154 -0
  73. package/core/cli/generators/types.ts +71 -0
  74. package/core/cli/generators/utils.ts +192 -0
  75. package/core/cli/index.ts +69 -0
  76. package/core/cli/plugin-discovery.ts +16 -85
  77. package/core/client/fluxstack.ts +17 -0
  78. package/core/client/hooks/index.ts +7 -0
  79. package/core/client/hooks/state-validator.ts +130 -0
  80. package/core/client/hooks/useAuth.ts +49 -0
  81. package/core/client/hooks/useChunkedUpload.ts +258 -0
  82. package/core/client/hooks/useHybridLiveComponent.ts +967 -0
  83. package/core/client/hooks/useWebSocket.ts +373 -0
  84. package/core/client/index.ts +47 -0
  85. package/core/client/state/createStore.ts +193 -0
  86. package/core/client/state/index.ts +15 -0
  87. package/core/config/env-dynamic.ts +1 -1
  88. package/core/config/env.ts +2 -1
  89. package/core/config/runtime-config.ts +3 -3
  90. package/core/config/schema.ts +84 -49
  91. package/core/framework/server.ts +30 -0
  92. package/core/index.ts +25 -0
  93. package/core/live/ComponentRegistry.ts +399 -0
  94. package/core/live/types.ts +164 -0
  95. package/core/plugins/built-in/live-components/commands/create-live-component.ts +1201 -0
  96. package/core/plugins/built-in/live-components/index.ts +27 -0
  97. package/core/plugins/built-in/logger/index.ts +1 -1
  98. package/core/plugins/built-in/monitoring/index.ts +1 -1
  99. package/core/plugins/built-in/static/index.ts +1 -1
  100. package/core/plugins/built-in/swagger/index.ts +1 -1
  101. package/core/plugins/built-in/vite/index.ts +1 -1
  102. package/core/plugins/dependency-manager.ts +384 -0
  103. package/core/plugins/index.ts +5 -1
  104. package/core/plugins/manager.ts +7 -3
  105. package/core/plugins/registry.ts +88 -10
  106. package/core/plugins/types.ts +11 -11
  107. package/core/server/framework.ts +43 -0
  108. package/core/server/index.ts +11 -1
  109. package/core/server/live/ComponentRegistry.ts +1017 -0
  110. package/core/server/live/FileUploadManager.ts +272 -0
  111. package/core/server/live/LiveComponentPerformanceMonitor.ts +930 -0
  112. package/core/server/live/SingleConnectionManager.ts +0 -0
  113. package/core/server/live/StateSignature.ts +644 -0
  114. package/core/server/live/WebSocketConnectionManager.ts +688 -0
  115. package/core/server/live/websocket-plugin.ts +435 -0
  116. package/core/server/middleware/errorHandling.ts +141 -0
  117. package/core/server/middleware/index.ts +16 -0
  118. package/core/server/plugins/static-files-plugin.ts +232 -0
  119. package/core/server/services/BaseService.ts +95 -0
  120. package/core/server/services/ServiceContainer.ts +144 -0
  121. package/core/server/services/index.ts +9 -0
  122. package/core/templates/create-project.ts +196 -33
  123. package/core/testing/index.ts +10 -0
  124. package/core/testing/setup.ts +74 -0
  125. package/core/types/build.ts +38 -14
  126. package/core/types/types.ts +319 -0
  127. package/core/utils/env-runtime.ts +7 -0
  128. package/core/utils/errors/handlers.ts +264 -39
  129. package/core/utils/errors/index.ts +528 -18
  130. package/core/utils/errors/middleware.ts +114 -0
  131. package/core/utils/logger/formatters.ts +222 -0
  132. package/core/utils/logger/index.ts +167 -48
  133. package/core/utils/logger/middleware.ts +253 -0
  134. package/core/utils/logger/performance.ts +384 -0
  135. package/core/utils/logger/transports.ts +365 -0
  136. package/create-fluxstack.ts +296 -296
  137. package/fluxstack.config.ts +17 -1
  138. package/package-template.json +66 -66
  139. package/package.json +31 -6
  140. package/public/README.md +16 -0
  141. package/vite.config.ts +29 -14
  142. package/.claude/settings.local.json +0 -74
  143. package/.github/workflows/ci-build-tests.yml +0 -480
  144. package/.github/workflows/dependency-management.yml +0 -324
  145. package/.github/workflows/release-validation.yml +0 -355
  146. package/.kiro/specs/fluxstack-architecture-optimization/design.md +0 -700
  147. package/.kiro/specs/fluxstack-architecture-optimization/requirements.md +0 -127
  148. package/.kiro/specs/fluxstack-architecture-optimization/tasks.md +0 -330
  149. package/CLAUDE.md +0 -200
  150. package/Dockerfile +0 -58
  151. package/Dockerfile.backend +0 -52
  152. package/Dockerfile.frontend +0 -54
  153. package/README-Docker.md +0 -85
  154. package/ai-context/00-QUICK-START.md +0 -86
  155. package/ai-context/README.md +0 -88
  156. package/ai-context/development/eden-treaty-guide.md +0 -362
  157. package/ai-context/development/patterns.md +0 -382
  158. package/ai-context/development/plugins-guide.md +0 -572
  159. package/ai-context/examples/crud-complete.md +0 -626
  160. package/ai-context/project/architecture.md +0 -399
  161. package/ai-context/project/overview.md +0 -213
  162. package/ai-context/recent-changes/eden-treaty-refactor.md +0 -281
  163. package/ai-context/recent-changes/type-inference-fix.md +0 -223
  164. package/ai-context/reference/environment-vars.md +0 -384
  165. package/ai-context/reference/troubleshooting.md +0 -407
  166. package/app/client/src/components/TestPage.tsx +0 -453
  167. package/bun.lock +0 -1063
  168. package/bunfig.toml +0 -16
  169. package/core/__tests__/integration.test.ts +0 -227
  170. package/core/build/index.ts +0 -186
  171. package/core/config/__tests__/config-loader.test.ts +0 -554
  172. package/core/config/__tests__/config-merger.test.ts +0 -657
  173. package/core/config/__tests__/env-converter.test.ts +0 -372
  174. package/core/config/__tests__/env-processor.test.ts +0 -431
  175. package/core/config/__tests__/env.test.ts +0 -452
  176. package/core/config/__tests__/integration.test.ts +0 -418
  177. package/core/config/__tests__/loader.test.ts +0 -331
  178. package/core/config/__tests__/schema.test.ts +0 -129
  179. package/core/config/__tests__/validator.test.ts +0 -318
  180. package/core/framework/__tests__/server.test.ts +0 -233
  181. package/core/plugins/__tests__/built-in.test.ts.disabled +0 -366
  182. package/core/plugins/__tests__/manager.test.ts +0 -398
  183. package/core/plugins/__tests__/monitoring.test.ts +0 -401
  184. package/core/plugins/__tests__/registry.test.ts +0 -335
  185. package/core/utils/__tests__/errors.test.ts +0 -139
  186. package/core/utils/__tests__/helpers.test.ts +0 -297
  187. package/core/utils/__tests__/logger.test.ts +0 -141
  188. package/create-test-app.ts +0 -156
  189. package/docker-compose.microservices.yml +0 -75
  190. package/docker-compose.simple.yml +0 -57
  191. package/docker-compose.yml +0 -71
  192. package/eslint.config.js +0 -23
  193. package/flux-cli.ts +0 -214
  194. package/nginx-lb.conf +0 -37
  195. package/publish.sh +0 -63
  196. package/run-clean.ts +0 -26
  197. package/run-env-tests.ts +0 -313
  198. package/tailwind.config.js +0 -34
  199. package/tests/__mocks__/api.ts +0 -56
  200. package/tests/fixtures/users.ts +0 -69
  201. package/tests/integration/api/users.routes.test.ts +0 -221
  202. package/tests/setup.ts +0 -29
  203. package/tests/unit/app/client/App-simple.test.tsx +0 -56
  204. package/tests/unit/app/client/App.test.tsx.skip +0 -237
  205. package/tests/unit/app/client/eden-api.test.ts +0 -186
  206. package/tests/unit/app/client/simple.test.tsx +0 -23
  207. package/tests/unit/app/controllers/users.controller.test.ts +0 -150
  208. package/tests/unit/core/create-project.test.ts.skip +0 -95
  209. package/tests/unit/core/framework.test.ts +0 -144
  210. package/tests/unit/core/plugins/logger.test.ts.skip +0 -268
  211. package/tests/unit/core/plugins/vite.test.ts.disabled +0 -188
  212. package/tests/utils/test-helpers.ts +0 -61
  213. package/vitest.config.ts +0 -50
  214. package/workspace.json +0 -6
@@ -0,0 +1,253 @@
1
+ /**
2
+ * FluxStack Logger Middleware Integration
3
+ * Easy integration with Elysia and other frameworks
4
+ */
5
+
6
+ import type { Logger } from './index'
7
+ import { RequestLogger, PerformanceLogger } from './performance'
8
+
9
+ /**
10
+ * Enhanced logger middleware for Elysia
11
+ */
12
+ export function createElysiaLoggerMiddleware(logger: Logger) {
13
+ const requestLogger = new RequestLogger(logger)
14
+ const performanceLogger = new PerformanceLogger(logger)
15
+
16
+ return {
17
+ // Before request handler
18
+ beforeHandle: ({ request, set }: any) => {
19
+ const method = request.method
20
+ const url = new URL(request.url)
21
+ const path = url.pathname
22
+ const userAgent = request.headers.get('user-agent')
23
+ const ip = request.headers.get('x-forwarded-for') ||
24
+ request.headers.get('x-real-ip') ||
25
+ 'unknown'
26
+
27
+ // Start request tracking
28
+ const requestId = requestLogger.startRequest(method, path, {
29
+ userAgent,
30
+ ip,
31
+ query: Object.fromEntries(url.searchParams),
32
+ headers: Object.fromEntries(request.headers.entries())
33
+ })
34
+
35
+ // Add request context to set for access in handlers
36
+ set.requestId = requestId
37
+ set.logger = requestLogger.childLogger(requestId)
38
+ set.performance = performanceLogger
39
+
40
+ // Start overall request timer
41
+ performanceLogger.startTimer(`request:${requestId}`, {
42
+ method,
43
+ path
44
+ })
45
+ },
46
+
47
+ // After request handler
48
+ afterHandle: ({ request, response, set }: any) => {
49
+ if (set.requestId) {
50
+ const status = response?.status || 200
51
+
52
+ // End request tracking
53
+ requestLogger.endRequest(set.requestId, status, {
54
+ responseSize: response?.headers?.get('content-length'),
55
+ contentType: response?.headers?.get('content-type')
56
+ })
57
+
58
+ // End request timer
59
+ performanceLogger.endTimer(`request:${set.requestId}`)
60
+ }
61
+ },
62
+
63
+ // Error handler
64
+ onError: ({ request, error, set }: any) => {
65
+ if (set.requestId) {
66
+ requestLogger.errorRequest(set.requestId, error)
67
+ performanceLogger.endTimer(`request:${set.requestId}`)
68
+ }
69
+
70
+ // Log the error with context
71
+ logger.error('Request error', {
72
+ error: {
73
+ name: error.name,
74
+ message: error.message,
75
+ stack: error.stack
76
+ },
77
+ request: {
78
+ method: request.method,
79
+ url: request.url
80
+ }
81
+ })
82
+ }
83
+ }
84
+ }
85
+
86
+ /**
87
+ * Database query logging middleware
88
+ */
89
+ export function createDatabaseLoggerMiddleware(logger: Logger) {
90
+ const performanceLogger = new PerformanceLogger(logger)
91
+
92
+ return {
93
+ beforeQuery: (query: string, params?: any[]) => {
94
+ const queryId = `query:${Date.now()}:${Math.random().toString(36).substr(2, 9)}`
95
+
96
+ logger.debug('Executing database query', {
97
+ type: 'db_query_start',
98
+ queryId,
99
+ query: query.replace(/\s+/g, ' ').trim(),
100
+ params
101
+ })
102
+
103
+ performanceLogger.startTimer(queryId, {
104
+ query: query.substring(0, 100) + (query.length > 100 ? '...' : ''),
105
+ paramCount: params?.length || 0
106
+ })
107
+
108
+ return queryId
109
+ },
110
+
111
+ afterQuery: (queryId: string, result?: any) => {
112
+ const duration = performanceLogger.endTimer(queryId)
113
+
114
+ logger.debug('Database query completed', {
115
+ type: 'db_query_end',
116
+ queryId,
117
+ duration,
118
+ rowCount: result?.rowCount || result?.length || 0
119
+ })
120
+ },
121
+
122
+ onQueryError: (queryId: string, error: Error) => {
123
+ performanceLogger.endTimer(queryId)
124
+
125
+ logger.error('Database query failed', {
126
+ type: 'db_query_error',
127
+ queryId,
128
+ error: {
129
+ name: error.name,
130
+ message: error.message,
131
+ stack: error.stack
132
+ }
133
+ })
134
+ }
135
+ }
136
+ }
137
+
138
+ /**
139
+ * Plugin execution logging
140
+ */
141
+ export function createPluginLoggerMiddleware(logger: Logger) {
142
+ const performanceLogger = new PerformanceLogger(logger)
143
+
144
+ return {
145
+ beforePluginExecution: (pluginName: string, hook: string, context?: any) => {
146
+ const executionId = `plugin:${pluginName}:${hook}:${Date.now()}`
147
+
148
+ logger.debug(`Executing plugin hook: ${pluginName}.${hook}`, {
149
+ type: 'plugin_execution_start',
150
+ plugin: pluginName,
151
+ hook,
152
+ executionId,
153
+ context
154
+ })
155
+
156
+ performanceLogger.startTimer(executionId, {
157
+ plugin: pluginName,
158
+ hook
159
+ })
160
+
161
+ return executionId
162
+ },
163
+
164
+ afterPluginExecution: (executionId: string, result?: any) => {
165
+ const duration = performanceLogger.endTimer(executionId)
166
+
167
+ logger.debug('Plugin hook execution completed', {
168
+ type: 'plugin_execution_end',
169
+ executionId,
170
+ duration,
171
+ success: true
172
+ })
173
+ },
174
+
175
+ onPluginError: (executionId: string, pluginName: string, hook: string, error: Error) => {
176
+ performanceLogger.endTimer(executionId)
177
+
178
+ logger.error(`Plugin hook execution failed: ${pluginName}.${hook}`, {
179
+ type: 'plugin_execution_error',
180
+ plugin: pluginName,
181
+ hook,
182
+ executionId,
183
+ error: {
184
+ name: error.name,
185
+ message: error.message,
186
+ stack: error.stack
187
+ }
188
+ })
189
+ }
190
+ }
191
+ }
192
+
193
+ /**
194
+ * Build process logging
195
+ */
196
+ export function createBuildLoggerMiddleware(logger: Logger) {
197
+ const performanceLogger = new PerformanceLogger(logger)
198
+
199
+ return {
200
+ beforeBuild: (target: string, config?: any) => {
201
+ const buildId = `build:${target}:${Date.now()}`
202
+
203
+ logger.info(`Starting build process for ${target}`, {
204
+ type: 'build_start',
205
+ target,
206
+ buildId,
207
+ config
208
+ })
209
+
210
+ performanceLogger.startTimer(buildId, { target })
211
+ performanceLogger.logMemoryUsage(`build-start-${target}`)
212
+
213
+ return buildId
214
+ },
215
+
216
+ afterBuild: (buildId: string, result: any) => {
217
+ const duration = performanceLogger.endTimer(buildId)
218
+ performanceLogger.logMemoryUsage(`build-end`)
219
+
220
+ logger.info('Build process completed', {
221
+ type: 'build_end',
222
+ buildId,
223
+ duration,
224
+ success: true,
225
+ result
226
+ })
227
+ },
228
+
229
+ onBuildError: (buildId: string, error: Error) => {
230
+ performanceLogger.endTimer(buildId)
231
+ performanceLogger.logMemoryUsage(`build-error`)
232
+
233
+ logger.error('Build process failed', {
234
+ type: 'build_error',
235
+ buildId,
236
+ error: {
237
+ name: error.name,
238
+ message: error.message,
239
+ stack: error.stack
240
+ }
241
+ })
242
+ },
243
+
244
+ logBuildStep: (buildId: string, step: string, details?: any) => {
245
+ logger.info(`Build step: ${step}`, {
246
+ type: 'build_step',
247
+ buildId,
248
+ step,
249
+ details
250
+ })
251
+ }
252
+ }
253
+ }
@@ -0,0 +1,384 @@
1
+ /**
2
+ * FluxStack Performance and Request Logging
3
+ * Utilities for measuring and logging performance metrics
4
+ */
5
+
6
+ import { randomUUID } from 'crypto'
7
+ import type { Logger } from './index'
8
+
9
+ export interface RequestContext {
10
+ id: string
11
+ method: string
12
+ path: string
13
+ userAgent?: string
14
+ ip?: string
15
+ startTime: number
16
+ endTime?: number
17
+ duration?: number
18
+ status?: number
19
+ error?: Error
20
+ meta?: any
21
+ }
22
+
23
+ export interface PerformanceTimer {
24
+ label: string
25
+ startTime: number
26
+ endTime?: number
27
+ duration?: number
28
+ meta?: any
29
+ }
30
+
31
+ /**
32
+ * Request correlation and contextual logging
33
+ */
34
+ export class RequestLogger {
35
+ private logger: Logger
36
+ private activeRequests: Map<string, RequestContext> = new Map()
37
+
38
+ constructor(logger: Logger) {
39
+ this.logger = logger
40
+ }
41
+
42
+ /**
43
+ * Start tracking a request
44
+ */
45
+ startRequest(method: string, path: string, meta?: any): string {
46
+ const id = randomUUID()
47
+ const context: RequestContext = {
48
+ id,
49
+ method,
50
+ path,
51
+ startTime: Date.now(),
52
+ meta
53
+ }
54
+
55
+ this.activeRequests.set(id, context)
56
+
57
+ // Log request start
58
+ this.logger.child({ requestId: id }).info(`→ ${method} ${path}`, {
59
+ type: 'request_start',
60
+ method,
61
+ path,
62
+ ...meta
63
+ })
64
+
65
+ return id
66
+ }
67
+
68
+ /**
69
+ * End tracking a request
70
+ */
71
+ endRequest(id: string, status: number, meta?: any): void {
72
+ const context = this.activeRequests.get(id)
73
+ if (!context) return
74
+
75
+ const endTime = Date.now()
76
+ const duration = endTime - context.startTime
77
+
78
+ context.endTime = endTime
79
+ context.duration = duration
80
+ context.status = status
81
+
82
+ // Determine log level based on status and duration
83
+ const logLevel = this.getRequestLogLevel(status, duration)
84
+ const statusEmoji = this.getStatusEmoji(status)
85
+
86
+ // Log request completion
87
+ this.logger.child({ requestId: id })[logLevel](
88
+ `← ${context.method} ${context.path} ${statusEmoji} ${status} (${duration}ms)`,
89
+ {
90
+ type: 'request_end',
91
+ method: context.method,
92
+ path: context.path,
93
+ status,
94
+ duration,
95
+ ...context.meta,
96
+ ...meta
97
+ }
98
+ )
99
+
100
+ // Clean up
101
+ this.activeRequests.delete(id)
102
+ }
103
+
104
+ /**
105
+ * Log request error
106
+ */
107
+ errorRequest(id: string, error: Error, status?: number): void {
108
+ const context = this.activeRequests.get(id)
109
+ if (!context) return
110
+
111
+ const endTime = Date.now()
112
+ const duration = endTime - context.startTime
113
+ const finalStatus = status || 500
114
+
115
+ context.endTime = endTime
116
+ context.duration = duration
117
+ context.status = finalStatus
118
+ context.error = error
119
+
120
+ // Log request error
121
+ this.logger.child({ requestId: id }).error(
122
+ `✗ ${context.method} ${context.path} ${finalStatus} (${duration}ms)`,
123
+ {
124
+ type: 'request_error',
125
+ method: context.method,
126
+ path: context.path,
127
+ status: finalStatus,
128
+ duration,
129
+ error: {
130
+ name: error.name,
131
+ message: error.message,
132
+ stack: error.stack
133
+ },
134
+ ...context.meta
135
+ }
136
+ )
137
+
138
+ // Clean up
139
+ this.activeRequests.delete(id)
140
+ }
141
+
142
+ /**
143
+ * Get request context for correlation
144
+ */
145
+ getRequestContext(id: string): RequestContext | undefined {
146
+ return this.activeRequests.get(id)
147
+ }
148
+
149
+ /**
150
+ * Create child logger with request context
151
+ */
152
+ childLogger(id: string, additionalContext?: any): Logger {
153
+ const context = this.activeRequests.get(id)
154
+ if (!context) {
155
+ return this.logger.child({ requestId: id, ...additionalContext })
156
+ }
157
+
158
+ return this.logger.child({
159
+ requestId: id,
160
+ method: context.method,
161
+ path: context.path,
162
+ ...additionalContext
163
+ })
164
+ }
165
+
166
+ private getRequestLogLevel(status: number, duration: number): 'info' | 'warn' | 'error' {
167
+ if (status >= 500) return 'error'
168
+ if (status >= 400) return 'warn'
169
+ if (duration > 5000) return 'warn' // Slow requests
170
+ return 'info'
171
+ }
172
+
173
+ private getStatusEmoji(status: number): string {
174
+ if (status >= 500) return '💥'
175
+ if (status >= 400) return '⚠️'
176
+ if (status >= 300) return '↩️'
177
+ if (status >= 200) return '✅'
178
+ return '❓'
179
+ }
180
+ }
181
+
182
+ /**
183
+ * Performance timing utilities
184
+ */
185
+ export class PerformanceLogger {
186
+ private logger: Logger
187
+ private timers: Map<string, PerformanceTimer> = new Map()
188
+
189
+ constructor(logger: Logger) {
190
+ this.logger = logger
191
+ }
192
+
193
+ /**
194
+ * Start a performance timer
195
+ */
196
+ startTimer(label: string, meta?: any): void {
197
+ const timer: PerformanceTimer = {
198
+ label,
199
+ startTime: performance.now(),
200
+ meta
201
+ }
202
+
203
+ this.timers.set(label, timer)
204
+
205
+ this.logger.debug(`⏱️ Started timer: ${label}`, {
206
+ type: 'timer_start',
207
+ label,
208
+ ...meta
209
+ })
210
+ }
211
+
212
+ /**
213
+ * End a performance timer
214
+ */
215
+ endTimer(label: string, meta?: any): number | undefined {
216
+ const timer = this.timers.get(label)
217
+ if (!timer) {
218
+ this.logger.warn(`Timer not found: ${label}`)
219
+ return undefined
220
+ }
221
+
222
+ const endTime = performance.now()
223
+ const duration = endTime - timer.startTime
224
+
225
+ timer.endTime = endTime
226
+ timer.duration = duration
227
+
228
+ // Determine log level based on duration
229
+ const logLevel = this.getTimerLogLevel(duration)
230
+ const durationEmoji = this.getDurationEmoji(duration)
231
+
232
+ this.logger[logLevel](`${durationEmoji} Timer ${label}: ${duration.toFixed(2)}ms`, {
233
+ type: 'timer_end',
234
+ label,
235
+ duration,
236
+ ...timer.meta,
237
+ ...meta
238
+ })
239
+
240
+ // Clean up
241
+ this.timers.delete(label)
242
+
243
+ return duration
244
+ }
245
+
246
+ /**
247
+ * Measure execution time of a function
248
+ */
249
+ async measure<T>(label: string, fn: () => Promise<T>, meta?: any): Promise<T> {
250
+ this.startTimer(label, meta)
251
+ try {
252
+ const result = await fn()
253
+ this.endTimer(label, { success: true })
254
+ return result
255
+ } catch (error) {
256
+ this.endTimer(label, { success: false, error: error.message })
257
+ throw error
258
+ }
259
+ }
260
+
261
+ /**
262
+ * Measure execution time of a synchronous function
263
+ */
264
+ measureSync<T>(label: string, fn: () => T, meta?: any): T {
265
+ this.startTimer(label, meta)
266
+ try {
267
+ const result = fn()
268
+ this.endTimer(label, { success: true })
269
+ return result
270
+ } catch (error) {
271
+ this.endTimer(label, { success: false, error: error.message })
272
+ throw error
273
+ }
274
+ }
275
+
276
+ /**
277
+ * Log memory usage
278
+ */
279
+ logMemoryUsage(label?: string): void {
280
+ const memUsage = process.memoryUsage()
281
+ const formatBytes = (bytes: number) => (bytes / 1024 / 1024).toFixed(2) + ' MB'
282
+
283
+ this.logger.info(`📊 Memory usage${label ? ` (${label})` : ''}`, {
284
+ type: 'memory_usage',
285
+ label,
286
+ memory: {
287
+ rss: formatBytes(memUsage.rss),
288
+ heapTotal: formatBytes(memUsage.heapTotal),
289
+ heapUsed: formatBytes(memUsage.heapUsed),
290
+ external: formatBytes(memUsage.external)
291
+ },
292
+ raw: memUsage
293
+ })
294
+ }
295
+
296
+ /**
297
+ * Log system performance metrics
298
+ */
299
+ logSystemMetrics(label?: string): void {
300
+ const cpuUsage = process.cpuUsage()
301
+ const uptime = process.uptime()
302
+
303
+ this.logger.info(`⚡ System metrics${label ? ` (${label})` : ''}`, {
304
+ type: 'system_metrics',
305
+ label,
306
+ cpu: {
307
+ user: cpuUsage.user,
308
+ system: cpuUsage.system
309
+ },
310
+ uptime: {
311
+ seconds: uptime,
312
+ formatted: this.formatUptime(uptime)
313
+ }
314
+ })
315
+ }
316
+
317
+ private getTimerLogLevel(duration: number): 'debug' | 'info' | 'warn' {
318
+ if (duration > 1000) return 'warn' // > 1 second
319
+ if (duration > 100) return 'info' // > 100ms
320
+ return 'debug'
321
+ }
322
+
323
+ private getDurationEmoji(duration: number): string {
324
+ if (duration > 5000) return '🐌' // Very slow
325
+ if (duration > 1000) return '⏳' // Slow
326
+ if (duration > 100) return '⏱️' // Medium
327
+ return '⚡' // Fast
328
+ }
329
+
330
+ private formatUptime(seconds: number): string {
331
+ const days = Math.floor(seconds / 86400)
332
+ const hours = Math.floor((seconds % 86400) / 3600)
333
+ const minutes = Math.floor((seconds % 3600) / 60)
334
+ const secs = Math.floor(seconds % 60)
335
+
336
+ if (days > 0) return `${days}d ${hours}h ${minutes}m ${secs}s`
337
+ if (hours > 0) return `${hours}h ${minutes}m ${secs}s`
338
+ if (minutes > 0) return `${minutes}m ${secs}s`
339
+ return `${secs}s`
340
+ }
341
+ }
342
+
343
+ /**
344
+ * Middleware for automatic request logging
345
+ */
346
+ export function createRequestLoggingMiddleware(logger: Logger) {
347
+ const requestLogger = new RequestLogger(logger)
348
+
349
+ return {
350
+ onRequest: (request: any) => {
351
+ const method = request.method
352
+ const path = request.url || request.path
353
+ const userAgent = request.headers?.['user-agent']
354
+ const ip = request.headers?.['x-forwarded-for'] || request.ip
355
+
356
+ const requestId = requestLogger.startRequest(method, path, {
357
+ userAgent,
358
+ ip,
359
+ headers: request.headers
360
+ })
361
+
362
+ // Attach request ID to request for correlation
363
+ request.requestId = requestId
364
+ request.logger = requestLogger.childLogger(requestId)
365
+
366
+ return requestId
367
+ },
368
+
369
+ onResponse: (request: any, response: any) => {
370
+ if (request.requestId) {
371
+ const status = response.status || response.statusCode || 200
372
+ requestLogger.endRequest(request.requestId, status, {
373
+ responseHeaders: response.headers
374
+ })
375
+ }
376
+ },
377
+
378
+ onError: (request: any, error: Error) => {
379
+ if (request.requestId) {
380
+ requestLogger.errorRequest(request.requestId, error)
381
+ }
382
+ }
383
+ }
384
+ }