@rakeyshgidwani/roger-ui-bank-theme-stan-design 0.1.4 → 0.1.5

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 (164) hide show
  1. package/CHANGELOG.md +1 -1
  2. package/dist/index.d.ts +131 -131
  3. package/dist/index.esm.js +148 -148
  4. package/dist/index.js +148 -148
  5. package/dist/styles.css +1 -1
  6. package/package.json +1 -1
  7. package/src/components/ui/accessibility-demo.tsx +271 -0
  8. package/src/components/ui/advanced-component-architecture-demo.tsx +916 -0
  9. package/src/components/ui/advanced-transition-system-demo.tsx +670 -0
  10. package/src/components/ui/advanced-transition-system.tsx +395 -0
  11. package/src/components/ui/animation/animated-container.tsx +166 -0
  12. package/src/components/ui/animation/index.ts +19 -0
  13. package/src/components/ui/animation/staggered-container.tsx +68 -0
  14. package/src/components/ui/animation-demo.tsx +250 -0
  15. package/src/components/ui/badge.tsx +33 -0
  16. package/src/components/ui/battery-conscious-animation-demo.tsx +568 -0
  17. package/src/components/ui/border-radius-shadow-demo.tsx +187 -0
  18. package/src/components/ui/button.tsx +36 -0
  19. package/src/components/ui/card.tsx +207 -0
  20. package/src/components/ui/checkbox.tsx +30 -0
  21. package/src/components/ui/color-preview.tsx +411 -0
  22. package/src/components/ui/data-display/chart.tsx +653 -0
  23. package/src/components/ui/data-display/data-grid-simple.tsx +76 -0
  24. package/src/components/ui/data-display/data-grid.tsx +680 -0
  25. package/src/components/ui/data-display/list.tsx +456 -0
  26. package/src/components/ui/data-display/table.tsx +482 -0
  27. package/src/components/ui/data-display/timeline.tsx +441 -0
  28. package/src/components/ui/data-display/tree.tsx +602 -0
  29. package/src/components/ui/data-display/types.ts +536 -0
  30. package/src/components/ui/enterprise-mobile-experience-demo.tsx +749 -0
  31. package/src/components/ui/enterprise-mobile-experience.tsx +464 -0
  32. package/src/components/ui/feedback/alert.tsx +157 -0
  33. package/src/components/ui/feedback/progress.tsx +292 -0
  34. package/src/components/ui/feedback/skeleton.tsx +185 -0
  35. package/src/components/ui/feedback/toast.tsx +280 -0
  36. package/src/components/ui/feedback/types.ts +125 -0
  37. package/src/components/ui/font-preview.tsx +288 -0
  38. package/src/components/ui/form-demo.tsx +553 -0
  39. package/src/components/ui/hardware-acceleration-demo.tsx +547 -0
  40. package/src/components/ui/input.tsx +35 -0
  41. package/src/components/ui/label.tsx +16 -0
  42. package/src/components/ui/layout-demo.tsx +367 -0
  43. package/src/components/ui/layouts/adaptive-layout.tsx +139 -0
  44. package/src/components/ui/layouts/desktop-layout.tsx +224 -0
  45. package/src/components/ui/layouts/index.ts +10 -0
  46. package/src/components/ui/layouts/mobile-layout.tsx +162 -0
  47. package/src/components/ui/layouts/tablet-layout.tsx +197 -0
  48. package/src/components/ui/mobile-form-validation.tsx +451 -0
  49. package/src/components/ui/mobile-input-demo.tsx +201 -0
  50. package/src/components/ui/mobile-input.tsx +281 -0
  51. package/src/components/ui/mobile-skeleton-loading-demo.tsx +638 -0
  52. package/src/components/ui/navigation/breadcrumb.tsx +158 -0
  53. package/src/components/ui/navigation/index.ts +36 -0
  54. package/src/components/ui/navigation/menu.tsx +374 -0
  55. package/src/components/ui/navigation/navigation-demo.tsx +324 -0
  56. package/src/components/ui/navigation/pagination.tsx +272 -0
  57. package/src/components/ui/navigation/sidebar.tsx +383 -0
  58. package/src/components/ui/navigation/stepper.tsx +303 -0
  59. package/src/components/ui/navigation/tabs.tsx +205 -0
  60. package/src/components/ui/navigation/types.ts +299 -0
  61. package/src/components/ui/overlay/backdrop.tsx +81 -0
  62. package/src/components/ui/overlay/focus-manager.tsx +143 -0
  63. package/src/components/ui/overlay/index.ts +36 -0
  64. package/src/components/ui/overlay/modal.tsx +270 -0
  65. package/src/components/ui/overlay/overlay-manager.tsx +110 -0
  66. package/src/components/ui/overlay/popover.tsx +462 -0
  67. package/src/components/ui/overlay/portal.tsx +79 -0
  68. package/src/components/ui/overlay/tooltip.tsx +303 -0
  69. package/src/components/ui/overlay/types.ts +196 -0
  70. package/src/components/ui/performance-demo.tsx +596 -0
  71. package/src/components/ui/semantic-input-system-demo.tsx +502 -0
  72. package/src/components/ui/semantic-input-system-demo.tsx.disabled +873 -0
  73. package/src/components/ui/tablet-layout.tsx +192 -0
  74. package/src/components/ui/theme-customizer.tsx +386 -0
  75. package/src/components/ui/theme-preview.tsx +310 -0
  76. package/src/components/ui/theme-switcher.tsx +264 -0
  77. package/src/components/ui/theme-toggle.tsx +38 -0
  78. package/src/components/ui/token-demo.tsx +195 -0
  79. package/src/components/ui/touch-demo.tsx +462 -0
  80. package/src/components/ui/touch-friendly-interface-demo.tsx +519 -0
  81. package/src/components/ui/touch-friendly-interface.tsx +296 -0
  82. package/src/hooks/index.ts +190 -0
  83. package/src/hooks/use-accessibility-support.ts +518 -0
  84. package/src/hooks/use-adaptive-layout.ts +289 -0
  85. package/src/hooks/use-advanced-patterns.ts +294 -0
  86. package/src/hooks/use-advanced-transition-system.ts +393 -0
  87. package/src/hooks/use-animation-profile.ts +288 -0
  88. package/src/hooks/use-battery-animations.ts +384 -0
  89. package/src/hooks/use-battery-conscious-loading.ts +475 -0
  90. package/src/hooks/use-battery-optimization.ts +330 -0
  91. package/src/hooks/use-battery-status.ts +299 -0
  92. package/src/hooks/use-component-performance.ts +344 -0
  93. package/src/hooks/use-device-loading-states.ts +459 -0
  94. package/src/hooks/use-device.tsx +110 -0
  95. package/src/hooks/use-enterprise-mobile-experience.ts +488 -0
  96. package/src/hooks/use-form-feedback.ts +403 -0
  97. package/src/hooks/use-form-performance.ts +513 -0
  98. package/src/hooks/use-frame-rate.ts +251 -0
  99. package/src/hooks/use-gestures.ts +338 -0
  100. package/src/hooks/use-hardware-acceleration.ts +341 -0
  101. package/src/hooks/use-input-accessibility.ts +455 -0
  102. package/src/hooks/use-input-performance.ts +506 -0
  103. package/src/hooks/use-layout-performance.ts +319 -0
  104. package/src/hooks/use-loading-accessibility.ts +535 -0
  105. package/src/hooks/use-loading-performance.ts +473 -0
  106. package/src/hooks/use-memory-usage.ts +287 -0
  107. package/src/hooks/use-mobile-form-layout.ts +464 -0
  108. package/src/hooks/use-mobile-form-validation.ts +518 -0
  109. package/src/hooks/use-mobile-keyboard-optimization.ts +472 -0
  110. package/src/hooks/use-mobile-layout.ts +302 -0
  111. package/src/hooks/use-mobile-optimization.ts +406 -0
  112. package/src/hooks/use-mobile-skeleton.ts +402 -0
  113. package/src/hooks/use-mobile-touch.ts +414 -0
  114. package/src/hooks/use-performance-throttling.ts +348 -0
  115. package/src/hooks/use-performance.ts +316 -0
  116. package/src/hooks/use-reusable-architecture.ts +414 -0
  117. package/src/hooks/use-semantic-input-types.ts +357 -0
  118. package/src/hooks/use-semantic-input.ts +565 -0
  119. package/src/hooks/use-tablet-layout.ts +384 -0
  120. package/src/hooks/use-touch-friendly-input.ts +524 -0
  121. package/src/hooks/use-touch-friendly-interface.ts +331 -0
  122. package/src/hooks/use-touch-optimization.ts +375 -0
  123. package/src/index.ts +279 -279
  124. package/src/lib/utils.ts +6 -0
  125. package/src/themes/README.md +272 -0
  126. package/src/themes/ThemeContext.tsx +31 -0
  127. package/src/themes/ThemeProvider.tsx +232 -0
  128. package/src/themes/accessibility/index.ts +27 -0
  129. package/src/themes/accessibility.ts +259 -0
  130. package/src/themes/aria-patterns.ts +420 -0
  131. package/src/themes/base-themes.ts +55 -0
  132. package/src/themes/colorManager.ts +380 -0
  133. package/src/themes/examples/dark-theme.ts +154 -0
  134. package/src/themes/examples/minimal-theme.ts +108 -0
  135. package/src/themes/focus-management.ts +701 -0
  136. package/src/themes/fontLoader.ts +201 -0
  137. package/src/themes/high-contrast.ts +621 -0
  138. package/src/themes/index.ts +19 -0
  139. package/src/themes/inheritance.ts +227 -0
  140. package/src/themes/keyboard-navigation.ts +550 -0
  141. package/src/themes/motion-reduction.ts +662 -0
  142. package/src/themes/navigation.ts +238 -0
  143. package/src/themes/screen-reader.ts +645 -0
  144. package/src/themes/systemThemeDetector.ts +182 -0
  145. package/src/themes/themeCSSUpdater.ts +262 -0
  146. package/src/themes/themePersistence.ts +238 -0
  147. package/src/themes/themes/default.ts +586 -0
  148. package/src/themes/themes/harvey.ts +554 -0
  149. package/src/themes/themes/stan-design.ts +683 -0
  150. package/src/themes/types.ts +460 -0
  151. package/src/themes/useSystemTheme.ts +48 -0
  152. package/src/themes/useTheme.ts +87 -0
  153. package/src/themes/validation.ts +462 -0
  154. package/src/tokens/index.ts +34 -0
  155. package/src/tokens/tokenExporter.ts +397 -0
  156. package/src/tokens/tokenGenerator.ts +276 -0
  157. package/src/tokens/tokenManager.ts +248 -0
  158. package/src/tokens/tokenValidator.ts +543 -0
  159. package/src/tokens/types.ts +78 -0
  160. package/src/utils/bundle-analyzer.ts +260 -0
  161. package/src/utils/bundle-splitting.ts +483 -0
  162. package/src/utils/lazy-loading.ts +441 -0
  163. package/src/utils/performance-monitor.ts +513 -0
  164. package/src/utils/tree-shaking.ts +274 -0
@@ -0,0 +1,513 @@
1
+ // Performance monitoring utilities for tracking various metrics
2
+ export interface PerformanceMetric {
3
+ name: string;
4
+ value: number;
5
+ unit: string;
6
+ timestamp: number;
7
+ metadata?: Record<string, any>;
8
+ }
9
+
10
+ export interface PerformanceThreshold {
11
+ name: string;
12
+ warning: number;
13
+ critical: number;
14
+ unit: string;
15
+ }
16
+
17
+ export interface PerformanceReport {
18
+ metrics: PerformanceMetric[];
19
+ thresholds: PerformanceThreshold[];
20
+ violations: Array<{
21
+ metric: string;
22
+ value: number;
23
+ threshold: number;
24
+ severity: 'warning' | 'critical';
25
+ }>;
26
+ summary: {
27
+ totalMetrics: number;
28
+ warnings: number;
29
+ criticals: number;
30
+ averagePerformance: number;
31
+ };
32
+ timestamp: number;
33
+ }
34
+
35
+ export interface PerformanceMonitorConfig {
36
+ enabled: boolean;
37
+ autoCollect: boolean;
38
+ collectionInterval: number;
39
+ maxMetrics: number;
40
+ thresholds: PerformanceThreshold[];
41
+ enableWebVitals: boolean;
42
+ enableMemoryMonitoring: boolean;
43
+ enableNetworkMonitoring: boolean;
44
+ }
45
+
46
+ export class PerformanceMonitor {
47
+ private config: PerformanceMonitorConfig;
48
+ private metrics: PerformanceMetric[];
49
+ private thresholds: Map<string, PerformanceThreshold>;
50
+ private observers: Map<string, PerformanceObserver>;
51
+ private collectionTimer: NodeJS.Timeout | null;
52
+ private startTime: number;
53
+
54
+ constructor(config: PerformanceMonitorConfig = {
55
+ enabled: true,
56
+ autoCollect: true,
57
+ collectionInterval: 5000, // 5 seconds
58
+ maxMetrics: 1000,
59
+ thresholds: [],
60
+ enableWebVitals: true,
61
+ enableMemoryMonitoring: true,
62
+ enableNetworkMonitoring: true
63
+ }) {
64
+ this.config = config;
65
+ this.metrics = [];
66
+ this.thresholds = new Map();
67
+ this.observers = new Map();
68
+ this.collectionTimer = null;
69
+ this.startTime = Date.now();
70
+
71
+ // Initialize thresholds
72
+ this.config.thresholds.forEach(threshold => {
73
+ this.thresholds.set(threshold.name, threshold);
74
+ });
75
+
76
+ // Set up default thresholds if none provided
77
+ if (this.config.thresholds.length === 0) {
78
+ this.setupDefaultThresholds();
79
+ }
80
+
81
+ // Start auto-collection if enabled
82
+ if (this.config.autoCollect) {
83
+ this.startAutoCollection();
84
+ }
85
+
86
+ // Set up performance observers
87
+ if (this.config.enableWebVitals) {
88
+ this.setupWebVitalsObserver();
89
+ }
90
+ }
91
+
92
+ // Set up default performance thresholds
93
+ private setupDefaultThresholds(): void {
94
+ const defaultThresholds: PerformanceThreshold[] = [
95
+ { name: 'themeSwitchTime', warning: 100, critical: 300, unit: 'ms' },
96
+ { name: 'componentRenderTime', warning: 50, critical: 150, unit: 'ms' },
97
+ { name: 'bundleLoadTime', warning: 2000, critical: 5000, unit: 'ms' },
98
+ { name: 'memoryUsage', warning: 100, critical: 500, unit: 'MB' },
99
+ { name: 'firstContentfulPaint', warning: 1000, critical: 3000, unit: 'ms' },
100
+ { name: 'largestContentfulPaint', warning: 2500, critical: 4000, unit: 'ms' }
101
+ ];
102
+
103
+ defaultThresholds.forEach(threshold => {
104
+ this.thresholds.set(threshold.name, threshold);
105
+ });
106
+ }
107
+
108
+ // Set up Web Vitals observer
109
+ private setupWebVitalsObserver(): void {
110
+ if (!('PerformanceObserver' in window)) return;
111
+
112
+ try {
113
+ // First Contentful Paint
114
+ const fcpObserver = new PerformanceObserver((list) => {
115
+ const entries = list.getEntries();
116
+ entries.forEach(entry => {
117
+ this.recordMetric('firstContentfulPaint', entry.startTime, 'ms', {
118
+ entryType: entry.entryType,
119
+ name: entry.name
120
+ });
121
+ });
122
+ });
123
+ fcpObserver.observe({ entryTypes: ['paint'] });
124
+
125
+ // Largest Contentful Paint
126
+ const lcpObserver = new PerformanceObserver((list) => {
127
+ const entries = list.getEntries();
128
+ entries.forEach(entry => {
129
+ this.recordMetric('largestContentfulPaint', entry.startTime, 'ms', {
130
+ entryType: entry.entryType,
131
+ name: entry.name
132
+ });
133
+ });
134
+ });
135
+ lcpObserver.observe({ entryTypes: ['largest-contentful-paint'] });
136
+
137
+ // First Input Delay
138
+ const fidObserver = new PerformanceObserver((list) => {
139
+ const entries = list.getEntries();
140
+ entries.forEach(entry => {
141
+ if ('processingStart' in entry) {
142
+ const fidEntry = entry as any;
143
+ this.recordMetric('firstInputDelay', fidEntry.processingStart - fidEntry.startTime, 'ms', {
144
+ entryType: entry.entryType,
145
+ name: entry.name
146
+ });
147
+ }
148
+ });
149
+ });
150
+ fidObserver.observe({ entryTypes: ['first-input'] });
151
+
152
+ // Cumulative Layout Shift
153
+ const clsObserver = new PerformanceObserver((list) => {
154
+ const entries = list.getEntries();
155
+ entries.forEach(entry => {
156
+ if ('value' in entry) {
157
+ const clsEntry = entry as any;
158
+ this.recordMetric('cumulativeLayoutShift', clsEntry.value, 'score', {
159
+ entryType: entry.entryType,
160
+ name: entry.name
161
+ });
162
+ }
163
+ });
164
+ });
165
+ clsObserver.observe({ entryTypes: ['layout-shift'] });
166
+
167
+ this.observers.set('webVitals', fcpObserver);
168
+ } catch (error) {
169
+ console.warn('Failed to set up Web Vitals observer:', error);
170
+ }
171
+ }
172
+
173
+ // Record a performance metric
174
+ recordMetric(name: string, value: number, unit: string, metadata?: Record<string, any>): void {
175
+ if (!this.config.enabled) return;
176
+
177
+ const metric: PerformanceMetric = {
178
+ name,
179
+ value,
180
+ unit,
181
+ timestamp: Date.now(),
182
+ metadata
183
+ };
184
+
185
+ this.metrics.push(metric);
186
+
187
+ // Enforce max metrics limit
188
+ if (this.metrics.length > this.config.maxMetrics) {
189
+ this.metrics = this.metrics.slice(-this.config.maxMetrics);
190
+ }
191
+
192
+ // Check thresholds and emit warnings
193
+ this.checkThresholds(metric);
194
+ }
195
+
196
+ // Check if a metric violates any thresholds
197
+ private checkThresholds(metric: PerformanceMetric): void {
198
+ const threshold = this.thresholds.get(metric.name);
199
+ if (!threshold) return;
200
+
201
+ if (metric.value >= threshold.critical) {
202
+ this.emitThresholdViolation(metric, threshold, 'critical');
203
+ } else if (metric.value >= threshold.warning) {
204
+ this.emitThresholdViolation(metric, threshold, 'warning');
205
+ }
206
+ }
207
+
208
+ // Emit threshold violation event
209
+ private emitThresholdViolation(metric: PerformanceMetric, threshold: PerformanceThreshold, severity: 'warning' | 'critical'): void {
210
+ const event = new CustomEvent('performanceThresholdViolation', {
211
+ detail: {
212
+ metric: metric.name,
213
+ value: metric.value,
214
+ threshold: threshold[severity],
215
+ severity,
216
+ unit: threshold.unit,
217
+ timestamp: metric.timestamp
218
+ }
219
+ });
220
+
221
+ window.dispatchEvent(event);
222
+
223
+ // Log to console
224
+ const logMethod = severity === 'critical' ? 'error' : 'warn';
225
+ console[logMethod](`Performance ${severity}: ${metric.name} = ${metric.value}${metric.unit} (threshold: ${threshold[severity]}${threshold.unit})`);
226
+ }
227
+
228
+ // Measure theme switch performance
229
+ measureThemeSwitch(callback: () => void): number {
230
+ const startTime = performance.now();
231
+ callback();
232
+ const endTime = performance.now();
233
+ const duration = endTime - startTime;
234
+
235
+ this.recordMetric('themeSwitchTime', duration, 'ms');
236
+ return duration;
237
+ }
238
+
239
+ // Measure component render performance
240
+ measureComponentRender(callback: () => void): number {
241
+ const startTime = performance.now();
242
+ callback();
243
+ const endTime = performance.now();
244
+ const duration = endTime - startTime;
245
+
246
+ this.recordMetric('componentRenderTime', duration, 'ms');
247
+ return duration;
248
+ }
249
+
250
+ // Measure bundle load performance
251
+ measureBundleLoad(callback: () => Promise<any>): Promise<number> {
252
+ const startTime = performance.now();
253
+ return callback().then(() => {
254
+ const endTime = performance.now();
255
+ const duration = endTime - startTime;
256
+ this.recordMetric('bundleLoadTime', duration, 'ms');
257
+ return duration;
258
+ });
259
+ }
260
+
261
+ // Measure memory usage
262
+ measureMemoryUsage(): number | null {
263
+ if (!this.config.enableMemoryMonitoring || !('memory' in performance)) {
264
+ return null;
265
+ }
266
+
267
+ const memory = (performance as any).memory;
268
+ const usedMB = memory.usedJSHeapSize / 1024 / 1024;
269
+
270
+ this.recordMetric('memoryUsage', usedMB, 'MB', {
271
+ totalJSHeapSize: memory.totalJSHeapSize / 1024 / 1024,
272
+ jsHeapSizeLimit: memory.jsHeapSizeLimit / 1024 / 1024
273
+ });
274
+
275
+ return usedMB;
276
+ }
277
+
278
+ // Measure network performance
279
+ measureNetworkPerformance(): void {
280
+ if (!this.config.enableNetworkMonitoring || !('getEntriesByType' in performance)) return;
281
+
282
+ try {
283
+ const navigationEntries = performance.getEntriesByType('navigation');
284
+ if (navigationEntries.length > 0) {
285
+ const nav = navigationEntries[0] as PerformanceNavigationTiming;
286
+
287
+ this.recordMetric('domContentLoaded', nav.domContentLoadedEventEnd - nav.domContentLoadedEventStart, 'ms');
288
+ this.recordMetric('loadComplete', nav.loadEventEnd - nav.loadEventStart, 'ms');
289
+ this.recordMetric('domInteractive', nav.domInteractive - nav.fetchStart, 'ms');
290
+ this.recordMetric('firstByte', nav.responseStart - nav.fetchStart, 'ms');
291
+ }
292
+ } catch (error) {
293
+ console.warn('Failed to measure network performance:', error);
294
+ }
295
+ }
296
+
297
+ // Start automatic metric collection
298
+ startAutoCollection(): void {
299
+ if (this.collectionTimer) return;
300
+
301
+ this.collectionTimer = setInterval(() => {
302
+ // Collect memory usage
303
+ this.measureMemoryUsage();
304
+
305
+ // Collect network performance
306
+ this.measureNetworkPerformance();
307
+
308
+ // Collect custom metrics
309
+ this.collectCustomMetrics();
310
+ }, this.config.collectionInterval);
311
+ }
312
+
313
+ // Stop automatic metric collection
314
+ stopAutoCollection(): void {
315
+ if (this.collectionTimer) {
316
+ clearInterval(this.collectionTimer);
317
+ this.collectionTimer = null;
318
+ }
319
+ }
320
+
321
+ // Collect custom metrics
322
+ private collectCustomMetrics(): void {
323
+ // Record uptime
324
+ const uptime = Date.now() - this.startTime;
325
+ this.recordMetric('uptime', uptime, 'ms');
326
+
327
+ // Record metric count
328
+ this.recordMetric('metricCount', this.metrics.length, 'count');
329
+ }
330
+
331
+ // Get metrics by name
332
+ getMetricsByName(name: string): PerformanceMetric[] {
333
+ return this.metrics.filter(metric => metric.name === name);
334
+ }
335
+
336
+ // Get latest metric by name
337
+ getLatestMetric(name: string): PerformanceMetric | null {
338
+ const metrics = this.getMetricsByName(name);
339
+ return metrics.length > 0 ? metrics[metrics.length - 1] : null;
340
+ }
341
+
342
+ // Get metrics within time range
343
+ getMetricsInRange(startTime: number, endTime: number): PerformanceMetric[] {
344
+ return this.metrics.filter(metric =>
345
+ metric.timestamp >= startTime && metric.timestamp <= endTime
346
+ );
347
+ }
348
+
349
+ // Calculate average for a metric
350
+ getAverageMetric(name: string, timeRange?: { start: number; end: number }): number {
351
+ let metrics = this.getMetricsByName(name);
352
+
353
+ if (timeRange) {
354
+ metrics = this.getMetricsInRange(timeRange.start, timeRange.end);
355
+ }
356
+
357
+ if (metrics.length === 0) return 0;
358
+
359
+ const sum = metrics.reduce((total, metric) => total + metric.value, 0);
360
+ return sum / metrics.length;
361
+ }
362
+
363
+ // Get performance report
364
+ getPerformanceReport(): PerformanceReport {
365
+ const violations: Array<{
366
+ metric: string;
367
+ value: number;
368
+ threshold: number;
369
+ severity: 'warning' | 'critical';
370
+ }> = [];
371
+
372
+ // Check all metrics against thresholds
373
+ this.metrics.forEach(metric => {
374
+ const threshold = this.thresholds.get(metric.name);
375
+ if (threshold) {
376
+ if (metric.value >= threshold.critical) {
377
+ violations.push({
378
+ metric: metric.name,
379
+ value: metric.value,
380
+ threshold: threshold.critical,
381
+ severity: 'critical'
382
+ });
383
+ } else if (metric.value >= threshold.warning) {
384
+ violations.push({
385
+ metric: metric.name,
386
+ value: metric.value,
387
+ threshold: threshold.warning,
388
+ severity: 'warning'
389
+ });
390
+ }
391
+ }
392
+ });
393
+
394
+ const warnings = violations.filter(v => v.severity === 'warning').length;
395
+ const criticals = violations.filter(v => v.severity === 'critical').length;
396
+
397
+ // Calculate average performance (lower is better for time-based metrics)
398
+ const timeMetrics = this.metrics.filter(m => m.unit === 'ms');
399
+ const averagePerformance = timeMetrics.length > 0
400
+ ? timeMetrics.reduce((sum, m) => sum + m.value, 0) / timeMetrics.length
401
+ : 0;
402
+
403
+ return {
404
+ metrics: [...this.metrics],
405
+ thresholds: Array.from(this.thresholds.values()),
406
+ violations,
407
+ summary: {
408
+ totalMetrics: this.metrics.length,
409
+ warnings,
410
+ criticals,
411
+ averagePerformance
412
+ },
413
+ timestamp: Date.now()
414
+ };
415
+ }
416
+
417
+ // Add custom threshold
418
+ addThreshold(threshold: PerformanceThreshold): void {
419
+ this.thresholds.set(threshold.name, threshold);
420
+ }
421
+
422
+ // Remove threshold
423
+ removeThreshold(name: string): void {
424
+ this.thresholds.delete(name);
425
+ }
426
+
427
+ // Clear all metrics
428
+ clearMetrics(): void {
429
+ this.metrics = [];
430
+ }
431
+
432
+ // Export metrics to JSON
433
+ exportMetrics(): string {
434
+ return JSON.stringify({
435
+ config: this.config,
436
+ metrics: this.metrics,
437
+ thresholds: Array.from(this.thresholds.values()),
438
+ report: this.getPerformanceReport(),
439
+ timestamp: new Date().toISOString()
440
+ }, null, 2);
441
+ }
442
+
443
+ // Get configuration
444
+ getConfig(): PerformanceMonitorConfig {
445
+ return { ...this.config };
446
+ }
447
+
448
+ // Update configuration
449
+ updateConfig(newConfig: Partial<PerformanceMonitorConfig>): void {
450
+ this.config = { ...this.config, ...newConfig };
451
+
452
+ // Restart auto-collection if interval changed
453
+ if (newConfig.collectionInterval && this.collectionTimer) {
454
+ this.stopAutoCollection();
455
+ this.startAutoCollection();
456
+ }
457
+ }
458
+
459
+ // Cleanup resources
460
+ destroy(): void {
461
+ this.stopAutoCollection();
462
+
463
+ // Disconnect observers
464
+ this.observers.forEach(observer => {
465
+ observer.disconnect();
466
+ });
467
+ this.observers.clear();
468
+
469
+ // Clear metrics
470
+ this.clearMetrics();
471
+ }
472
+ }
473
+
474
+ // Create and export default instance
475
+ export const performanceMonitor = new PerformanceMonitor();
476
+
477
+ // Utility function for measuring async operations
478
+ export async function measureAsync<T>(
479
+ name: string,
480
+ operation: () => Promise<T>,
481
+ monitor: PerformanceMonitor = performanceMonitor
482
+ ): Promise<T> {
483
+ const startTime = performance.now();
484
+ try {
485
+ const result = await operation();
486
+ const duration = performance.now() - startTime;
487
+ monitor.recordMetric(name, duration, 'ms');
488
+ return result;
489
+ } catch (error) {
490
+ const duration = performance.now() - startTime;
491
+ monitor.recordMetric(name, duration, 'ms');
492
+ throw error;
493
+ }
494
+ }
495
+
496
+ // Utility function for measuring sync operations
497
+ export function measureSync<T>(
498
+ name: string,
499
+ operation: () => T,
500
+ monitor: PerformanceMonitor = performanceMonitor
501
+ ): T {
502
+ const startTime = performance.now();
503
+ try {
504
+ const result = operation();
505
+ const duration = performance.now() - startTime;
506
+ monitor.recordMetric(name, duration, 'ms');
507
+ return result;
508
+ } catch (error) {
509
+ const duration = performance.now() - startTime;
510
+ monitor.recordMetric(name, duration, 'ms');
511
+ throw error;
512
+ }
513
+ }