@umituz/web-dashboard 6.1.0 → 6.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +47 -73
- package/package.json +5 -9
- package/src/config/DashboardConfig.ts +19 -68
- package/src/domains/analytics/components/index.ts +0 -6
- package/src/domains/analytics/hooks/index.ts +0 -6
- package/src/domains/analytics/hooks/useAnalytics.ts +2 -20
- package/src/domains/analytics/index.ts +0 -10
- package/src/domains/analytics/services/AnalyticsEngineService.ts +7 -74
- package/src/domains/analytics/services/PerformanceService.ts +27 -138
- package/src/domains/analytics/services/index.ts +0 -4
- package/src/domains/analytics/types/analytics.ts +100 -270
- package/src/domains/analytics/types/index.ts +0 -6
- package/src/domains/analytics/utils/analytics.test.ts +2 -9
- package/src/domains/analytics/utils/analytics.ts +1 -22
- package/src/domains/analytics/utils/index.ts +0 -6
- package/src/domains/calendar/config.ts +0 -7
- package/src/domains/calendar/hooks/index.ts +0 -4
- package/src/domains/calendar/hooks/useCalendar.ts +7 -27
- package/src/domains/calendar/index.ts +0 -4
- package/src/domains/calendar/services/CalendarService.ts +0 -21
- package/src/domains/calendar/services/index.ts +0 -4
- package/src/domains/calendar/types/calendar.types.ts +9 -53
- package/src/domains/calendar/utils/contentItemMapper.test.ts +0 -4
- package/src/domains/calendar/utils/contentItemMapper.ts +0 -31
- package/src/domains/calendar/utils/index.ts +0 -26
- package/src/domains/layouts/components/index.ts +0 -4
- package/src/domains/layouts/hooks/dashboard.ts +0 -21
- package/src/domains/layouts/hooks/index.ts +0 -4
- package/src/domains/layouts/index.ts +0 -6
- package/src/domains/layouts/theme/default.ts +0 -12
- package/src/domains/layouts/theme/index.ts +0 -4
- package/src/domains/layouts/theme/presets.ts +0 -9
- package/src/domains/layouts/theme/utils.ts +0 -15
- package/src/domains/layouts/types/index.ts +0 -4
- package/src/domains/layouts/types/layout.ts +18 -56
- package/src/domains/layouts/types/notification.ts +4 -17
- package/src/domains/layouts/types/sidebar.ts +8 -28
- package/src/domains/layouts/types/theme.ts +23 -59
- package/src/domains/layouts/types/user.ts +9 -30
- package/src/domains/layouts/utils/dashboard.ts +4 -48
- package/src/domains/layouts/utils/index.ts +0 -4
- package/src/domains/modules/build.tsx +2 -16
- package/src/domains/modules/types.ts +8 -23
- package/src/domains/onboarding/calc/calc.test.ts +1 -9
- package/src/domains/onboarding/calc/card-stack-motion-curve.ts +0 -6
- package/src/domains/onboarding/calc/count-with-locale.ts +0 -8
- package/src/domains/onboarding/calc/duration-equal-split.ts +0 -12
- package/src/domains/onboarding/calc/elapsed-millis.ts +0 -6
- package/src/domains/onboarding/calc/progress-percentage.ts +1 -11
- package/src/domains/onboarding/calc/slider-value-bounds.ts +1 -11
- package/src/domains/onboarding/calc/step-index-clamp.ts +0 -9
- package/src/domains/onboarding/calc/swipe-gesture-curve.ts +0 -13
- package/src/domains/onboarding/components/{shared/AnimationWrapper.tsx → AnimationWrapper.tsx} +0 -4
- package/src/domains/onboarding/components/{shared/OnboardingErrorBoundary.tsx → OnboardingErrorBoundary.tsx} +7 -27
- package/src/domains/onboarding/components/OnboardingFlow.test.tsx +8 -30
- package/src/domains/onboarding/components/OnboardingFlow.tsx +13 -61
- package/src/domains/onboarding/components/OnboardingIntl.tsx +1 -11
- package/src/domains/onboarding/components/PrimaryButton.tsx +40 -0
- package/src/domains/onboarding/components/ProgressBar.tsx +32 -0
- package/src/domains/onboarding/components/QuestionWrapper.tsx +28 -0
- package/src/domains/onboarding/components/ScreenContainer.tsx +19 -0
- package/src/domains/onboarding/components/{shared/SwipeCard.test.tsx → SwipeCard.test.tsx} +1 -3
- package/src/domains/onboarding/components/{shared/SwipeCard.tsx → SwipeCard.tsx} +10 -28
- package/src/domains/onboarding/components/renderBundledIcon.tsx +7 -0
- package/src/domains/onboarding/components/screens/AccountGateScreen.tsx +7 -17
- package/src/domains/onboarding/components/screens/AppDemoScreen.tsx +4 -10
- package/src/domains/onboarding/components/screens/ComparisonScreen.tsx +12 -22
- package/src/domains/onboarding/components/screens/GoalQuestionScreen.tsx +9 -6
- package/src/domains/onboarding/components/screens/PainPointsScreen.tsx +10 -10
- package/src/domains/onboarding/components/screens/PaywallScreen.tsx +22 -38
- package/src/domains/onboarding/components/screens/PermissionPrimingScreen.tsx +14 -29
- package/src/domains/onboarding/components/screens/PersonalizedSolutionScreen.tsx +10 -23
- package/src/domains/onboarding/components/screens/PreferencesScreen.tsx +13 -27
- package/src/domains/onboarding/components/screens/ProcessingScreen.tsx +11 -27
- package/src/domains/onboarding/components/screens/SocialProofScreen.tsx +22 -51
- package/src/domains/onboarding/components/screens/TinderCardsScreen.tsx +13 -30
- package/src/domains/onboarding/components/screens/ValueDeliveryScreen.tsx +13 -29
- package/src/domains/onboarding/components/screens/WelcomeScreen.tsx +12 -32
- package/src/domains/onboarding/{components/hooks → hooks}/useOnboardingAnalytics.test.tsx +1 -1
- package/src/domains/onboarding/{components/hooks → hooks}/useOnboardingAnalytics.ts +3 -16
- package/src/domains/onboarding/{components/hooks → hooks}/useOnboardingProgress.test.tsx +2 -2
- package/src/domains/onboarding/{components/hooks → hooks}/useOnboardingProgress.ts +10 -21
- package/src/domains/onboarding/{components/hooks → hooks}/usePermissionPriming.ts +3 -10
- package/src/domains/onboarding/{components/hooks → hooks}/useReducedMotion.ts +0 -5
- package/src/domains/onboarding/index.ts +16 -45
- package/src/domains/onboarding/predicates/has-handler.ts +0 -4
- package/src/domains/onboarding/predicates/icon-name-resolves.ts +1 -17
- package/src/domains/onboarding/predicates/permission-granted.ts +0 -5
- package/src/domains/onboarding/predicates/permission-supports.ts +1 -11
- package/src/domains/onboarding/predicates/predicates.test.ts +6 -20
- package/src/domains/onboarding/predicates/screen-emits-data.ts +0 -4
- package/src/domains/onboarding/predicates/storage-available.ts +0 -8
- package/src/domains/onboarding/templates/TemplateDemoFallback.tsx +19 -39
- package/src/domains/onboarding/templates/art-onboarding.ts +1 -11
- package/src/domains/onboarding/templates/health-onboarding.ts +0 -5
- package/src/domains/onboarding/templates/platform-onboarding.ts +0 -9
- package/src/domains/onboarding/templates/video-onboarding.ts +0 -5
- package/src/domains/onboarding/test/setup.ts +1 -8
- package/src/domains/onboarding/types/config.ts +7 -18
- package/src/domains/onboarding/types/labels.ts +25 -59
- package/src/domains/onboarding/types/screens.ts +3 -11
- package/src/domains/onboarding/utils/analytics-dispatch.ts +2 -21
- package/src/domains/onboarding/utils/default-storage-key.ts +0 -1
- package/src/domains/onboarding/utils/index.ts +0 -1
- package/src/domains/onboarding/utils/local-storage-bridge.ts +1 -21
- package/src/domains/onboarding/utils/permission-bridge.ts +0 -8
- package/src/domains/onboarding/validation/flow-structure-check.ts +0 -6
- package/src/domains/onboarding/validation/permission-status-check.ts +0 -5
- package/src/domains/onboarding/validation/screen-config-check.ts +0 -5
- package/src/domains/onboarding/validation/stored-progress-check.ts +1 -10
- package/src/domains/onboarding/validation/validation.test.ts +1 -6
- package/src/domains/permissions/hasPermission.ts +0 -8
- package/src/domains/permissions/types.ts +0 -20
- package/src/domains/settings/components/index.ts +0 -4
- package/src/domains/settings/hooks/index.ts +0 -4
- package/src/domains/settings/hooks/useSettings.ts +1 -26
- package/src/domains/settings/index.ts +0 -6
- package/src/domains/settings/types/index.ts +0 -4
- package/src/domains/settings/types/settings.ts +23 -67
- package/src/domains/settings/utils/index.ts +0 -4
- package/src/domains/settings/utils/settings.ts +0 -45
- package/src/styles/dashboard.css +818 -1
- package/src/domains/onboarding/components/shared/OptionCard.tsx +0 -73
- package/src/domains/onboarding/components/shared/PrimaryButton.tsx +0 -58
- package/src/domains/onboarding/components/shared/ProgressBar.tsx +0 -51
- package/src/domains/onboarding/components/shared/QuestionWrapper.tsx +0 -36
- package/src/domains/onboarding/components/shared/ScreenContainer.tsx +0 -29
- package/src/domains/onboarding/components/shared/index.ts +0 -16
- package/src/domains/onboarding/components/shared/renderBundledIcon.tsx +0 -20
- package/src/domains/onboarding/onboarding.css +0 -1
- package/src/domains/onboarding/theme/cn.ts +0 -10
- package/src/domains/onboarding/theme/index.css +0 -131
- package/src/domains/onboarding/theme/index.ts +0 -12
- package/src/domains/onboarding/theme/tokens.ts +0 -122
- /package/src/domains/onboarding/{components/hooks → hooks}/index.ts +0 -0
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Performance Service
|
|
3
|
-
*
|
|
4
|
-
* Real-time metrics and dashboard performance monitoring
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
1
|
export interface PerformanceMetric {
|
|
8
2
|
name: string;
|
|
9
3
|
value: number;
|
|
@@ -37,17 +31,10 @@ export interface RealtimeMetrics {
|
|
|
37
31
|
revenue: number;
|
|
38
32
|
}
|
|
39
33
|
|
|
40
|
-
/**
|
|
41
|
-
* Chrome-specific `performance.memory` shape (not in standard lib types).
|
|
42
|
-
*/
|
|
43
34
|
interface PerformanceMemoryLike {
|
|
44
35
|
usedJSHeapSize: number;
|
|
45
36
|
}
|
|
46
37
|
|
|
47
|
-
/**
|
|
48
|
-
* Layout-shift and first-input entry shapes (not in standard lib types
|
|
49
|
-
* for all TS versions). Structurally typed — no `any`.
|
|
50
|
-
*/
|
|
51
38
|
interface LayoutShiftEntry extends PerformanceEntry {
|
|
52
39
|
value: number;
|
|
53
40
|
}
|
|
@@ -62,27 +49,15 @@ const isLayoutShiftEntry = (entry: PerformanceEntry): entry is LayoutShiftEntry
|
|
|
62
49
|
const isFirstInputEntry = (entry: PerformanceEntry): entry is FirstInputEntry =>
|
|
63
50
|
typeof (entry as FirstInputEntry).processingStart === 'number';
|
|
64
51
|
|
|
65
|
-
/**
|
|
66
|
-
* Performance Service
|
|
67
|
-
*
|
|
68
|
-
* Monitors dashboard performance and provides real-time metrics.
|
|
69
|
-
* Web-vitals observation is opt-in via `startMonitoring()` so that
|
|
70
|
-
* importing the module never registers browser observers as a side effect.
|
|
71
|
-
*/
|
|
72
52
|
export class PerformanceService {
|
|
73
53
|
private metrics: Map<string, PerformanceMetric[]> = new Map();
|
|
74
54
|
private observers: PerformanceObserver[] = [];
|
|
75
55
|
|
|
76
|
-
|
|
77
|
-
* Register web-vitals observers (CLS / LCP / FID).
|
|
78
|
-
* Idempotent — calling it twice will not duplicate observers.
|
|
79
|
-
*/
|
|
80
|
-
public startMonitoring(): void {
|
|
56
|
+
public startMonitoring(): void {
|
|
81
57
|
if (typeof window === 'undefined' || !('PerformanceObserver' in window)) return;
|
|
82
58
|
if (this.observers.length > 0) return;
|
|
83
59
|
|
|
84
|
-
|
|
85
|
-
try {
|
|
60
|
+
try {
|
|
86
61
|
const observer = new PerformanceObserver((list) => {
|
|
87
62
|
for (const entry of list.getEntries()) {
|
|
88
63
|
if (entry.entryType === 'layout-shift' && isLayoutShiftEntry(entry)) {
|
|
@@ -93,11 +68,9 @@ export class PerformanceService {
|
|
|
93
68
|
observer.observe({ entryTypes: ['layout-shift'] });
|
|
94
69
|
this.observers.push(observer);
|
|
95
70
|
} catch {
|
|
96
|
-
|
|
97
|
-
}
|
|
71
|
+
}
|
|
98
72
|
|
|
99
|
-
|
|
100
|
-
try {
|
|
73
|
+
try {
|
|
101
74
|
const observer = new PerformanceObserver((list) => {
|
|
102
75
|
for (const entry of list.getEntries()) {
|
|
103
76
|
if (entry.entryType === 'largest-contentful-paint') {
|
|
@@ -108,11 +81,9 @@ export class PerformanceService {
|
|
|
108
81
|
observer.observe({ entryTypes: ['largest-contentful-paint'] });
|
|
109
82
|
this.observers.push(observer);
|
|
110
83
|
} catch {
|
|
111
|
-
|
|
112
|
-
}
|
|
84
|
+
}
|
|
113
85
|
|
|
114
|
-
|
|
115
|
-
try {
|
|
86
|
+
try {
|
|
116
87
|
const observer = new PerformanceObserver((list) => {
|
|
117
88
|
for (const entry of list.getEntries()) {
|
|
118
89
|
if (entry.entryType === 'first-input' && isFirstInputEntry(entry)) {
|
|
@@ -123,19 +94,10 @@ export class PerformanceService {
|
|
|
123
94
|
observer.observe({ entryTypes: ['first-input'] });
|
|
124
95
|
this.observers.push(observer);
|
|
125
96
|
} catch {
|
|
126
|
-
|
|
127
|
-
}
|
|
97
|
+
}
|
|
128
98
|
}
|
|
129
99
|
|
|
130
|
-
|
|
131
|
-
* Record a performance metric
|
|
132
|
-
*
|
|
133
|
-
* @param name - Metric name
|
|
134
|
-
* @param value - Metric value
|
|
135
|
-
* @param unit - Unit of measurement
|
|
136
|
-
* @param threshold - Warning threshold
|
|
137
|
-
*/
|
|
138
|
-
public recordMetric(name: string, value: number, unit: string, threshold?: number): void {
|
|
100
|
+
public recordMetric(name: string, value: number, unit: string, threshold?: number): void {
|
|
139
101
|
const status = threshold
|
|
140
102
|
? value > threshold * 2
|
|
141
103
|
? 'critical'
|
|
@@ -160,55 +122,29 @@ export class PerformanceService {
|
|
|
160
122
|
const metrics = this.metrics.get(name)!;
|
|
161
123
|
metrics.push(metric);
|
|
162
124
|
|
|
163
|
-
|
|
164
|
-
if (metrics.length > 100) {
|
|
125
|
+
if (metrics.length > 100) {
|
|
165
126
|
metrics.shift();
|
|
166
127
|
}
|
|
167
128
|
}
|
|
168
129
|
|
|
169
|
-
|
|
170
|
-
* Get metrics by name
|
|
171
|
-
*
|
|
172
|
-
* @param name - Metric name
|
|
173
|
-
* @returns Array of metrics
|
|
174
|
-
*/
|
|
175
|
-
public getMetrics(name: string): PerformanceMetric[] {
|
|
130
|
+
public getMetrics(name: string): PerformanceMetric[] {
|
|
176
131
|
return this.metrics.get(name) || [];
|
|
177
132
|
}
|
|
178
133
|
|
|
179
|
-
|
|
180
|
-
* Get latest metric value
|
|
181
|
-
*
|
|
182
|
-
* @param name - Metric name
|
|
183
|
-
* @returns Latest metric or undefined
|
|
184
|
-
*/
|
|
185
|
-
public getLatestMetric(name: string): PerformanceMetric | undefined {
|
|
134
|
+
public getLatestMetric(name: string): PerformanceMetric | undefined {
|
|
186
135
|
const metrics = this.getMetrics(name);
|
|
187
136
|
return metrics[metrics.length - 1];
|
|
188
137
|
}
|
|
189
138
|
|
|
190
|
-
|
|
191
|
-
* Get all metrics
|
|
192
|
-
*
|
|
193
|
-
* @returns Map of all metrics
|
|
194
|
-
*/
|
|
195
|
-
public getAllMetrics(): Map<string, PerformanceMetric[]> {
|
|
139
|
+
public getAllMetrics(): Map<string, PerformanceMetric[]> {
|
|
196
140
|
return new Map(this.metrics);
|
|
197
141
|
}
|
|
198
142
|
|
|
199
|
-
|
|
200
|
-
* Clear all metrics
|
|
201
|
-
*/
|
|
202
|
-
public clearMetrics(): void {
|
|
143
|
+
public clearMetrics(): void {
|
|
203
144
|
this.metrics.clear();
|
|
204
145
|
}
|
|
205
146
|
|
|
206
|
-
|
|
207
|
-
* Calculate dashboard performance metrics
|
|
208
|
-
*
|
|
209
|
-
* @returns Dashboard performance data
|
|
210
|
-
*/
|
|
211
|
-
public getDashboardMetrics(): DashboardMetrics {
|
|
147
|
+
public getDashboardMetrics(): DashboardMetrics {
|
|
212
148
|
const loadTime =
|
|
213
149
|
this.getNavigationLoadTime() ?? this.getLatestMetric('loadTime')?.value ?? 0;
|
|
214
150
|
|
|
@@ -224,60 +160,36 @@ export class PerformanceService {
|
|
|
224
160
|
apiResponseTime,
|
|
225
161
|
memoryUsage,
|
|
226
162
|
errorRate,
|
|
227
|
-
activeUsers: 0,
|
|
228
|
-
};
|
|
163
|
+
activeUsers: 0, };
|
|
229
164
|
}
|
|
230
165
|
|
|
231
|
-
|
|
232
|
-
* Page load time from the modern Navigation Timing API.
|
|
233
|
-
* Returns null when the API or the entry is unavailable.
|
|
234
|
-
*/
|
|
235
|
-
private getNavigationLoadTime(): number | null {
|
|
166
|
+
private getNavigationLoadTime(): number | null {
|
|
236
167
|
if (typeof performance === 'undefined' || typeof performance.getEntriesByType !== 'function') {
|
|
237
168
|
return null;
|
|
238
169
|
}
|
|
239
170
|
|
|
240
|
-
|
|
241
|
-
// are the only ones with loadEventEnd, hence the narrowing cast.
|
|
242
|
-
const [navigation] = performance.getEntriesByType('navigation') as PerformanceNavigationTiming[];
|
|
171
|
+
const [navigation] = performance.getEntriesByType('navigation') as PerformanceNavigationTiming[];
|
|
243
172
|
if (!navigation || navigation.loadEventEnd <= 0) return null;
|
|
244
173
|
return navigation.loadEventEnd - navigation.startTime;
|
|
245
174
|
}
|
|
246
175
|
|
|
247
|
-
|
|
248
|
-
* JS heap usage in MB via the Chrome-only `performance.memory`.
|
|
249
|
-
* Returns 0 where unavailable (all other browsers, Node).
|
|
250
|
-
*/
|
|
251
|
-
private getMemoryUsageMb(): number {
|
|
176
|
+
private getMemoryUsageMb(): number {
|
|
252
177
|
const memory = (performance as Performance & { memory?: PerformanceMemoryLike }).memory;
|
|
253
178
|
return typeof memory !== 'undefined' ? memory.usedJSHeapSize / 1048576 : 0;
|
|
254
179
|
}
|
|
255
180
|
|
|
256
|
-
|
|
257
|
-
* Calculate error rate from metrics
|
|
258
|
-
*
|
|
259
|
-
* @returns Error rate percentage
|
|
260
|
-
*/
|
|
261
|
-
private calculateErrorRate(): number {
|
|
181
|
+
private calculateErrorRate(): number {
|
|
262
182
|
const errors = this.getMetrics('error');
|
|
263
183
|
if (errors.length === 0) return 0;
|
|
264
184
|
|
|
265
|
-
const recentErrors = errors.filter((e) => e.timestamp > Date.now() - 60000);
|
|
266
|
-
return recentErrors.length;
|
|
185
|
+
const recentErrors = errors.filter((e) => e.timestamp > Date.now() - 60000); return recentErrors.length;
|
|
267
186
|
}
|
|
268
187
|
|
|
269
|
-
|
|
270
|
-
* Simulate real-time metrics
|
|
271
|
-
*
|
|
272
|
-
* @param previous - Previous metrics
|
|
273
|
-
* @returns Simulated real-time metrics
|
|
274
|
-
*/
|
|
275
|
-
public simulateRealtimeMetrics(previous?: RealtimeMetrics): RealtimeMetrics {
|
|
188
|
+
public simulateRealtimeMetrics(previous?: RealtimeMetrics): RealtimeMetrics {
|
|
276
189
|
const now = Date.now();
|
|
277
190
|
|
|
278
191
|
if (previous) {
|
|
279
|
-
|
|
280
|
-
const userChange = Math.floor(Math.random() * 20) - 10;
|
|
192
|
+
const userChange = Math.floor(Math.random() * 20) - 10;
|
|
281
193
|
const sessionChange = Math.floor(Math.random() * 30) - 15;
|
|
282
194
|
const pageViewChange = Math.floor(Math.random() * 50) - 20;
|
|
283
195
|
const conversionCount = Math.random() > 0.8 ? Math.floor(Math.random() * 3) : 0;
|
|
@@ -293,8 +205,7 @@ export class PerformanceService {
|
|
|
293
205
|
};
|
|
294
206
|
}
|
|
295
207
|
|
|
296
|
-
|
|
297
|
-
return {
|
|
208
|
+
return {
|
|
298
209
|
timestamp: now,
|
|
299
210
|
users: Math.floor(Math.random() * 1000) + 500,
|
|
300
211
|
sessions: Math.floor(Math.random() * 1500) + 800,
|
|
@@ -304,14 +215,7 @@ export class PerformanceService {
|
|
|
304
215
|
};
|
|
305
216
|
}
|
|
306
217
|
|
|
307
|
-
|
|
308
|
-
* Calculate growth KPI
|
|
309
|
-
*
|
|
310
|
-
* @param current - Current value
|
|
311
|
-
* @param previous - Previous value
|
|
312
|
-
* @returns KPI data
|
|
313
|
-
*/
|
|
314
|
-
public calculateKPI(current: number, previous: number): KPIData {
|
|
218
|
+
public calculateKPI(current: number, previous: number): KPIData {
|
|
315
219
|
const growth = previous > 0 ? ((current - previous) / previous) * 100 : 0;
|
|
316
220
|
return {
|
|
317
221
|
current,
|
|
@@ -320,11 +224,7 @@ export class PerformanceService {
|
|
|
320
224
|
};
|
|
321
225
|
}
|
|
322
226
|
|
|
323
|
-
|
|
324
|
-
* Measure page load time.
|
|
325
|
-
* Records immediately if the page already loaded; otherwise listens once.
|
|
326
|
-
*/
|
|
327
|
-
public measurePageLoad(): void {
|
|
227
|
+
public measurePageLoad(): void {
|
|
328
228
|
if (typeof window === 'undefined' || typeof window.performance === 'undefined') return;
|
|
329
229
|
|
|
330
230
|
const record = () => {
|
|
@@ -344,26 +244,15 @@ export class PerformanceService {
|
|
|
344
244
|
}, { once: true });
|
|
345
245
|
}
|
|
346
246
|
|
|
347
|
-
|
|
348
|
-
* Measure API response time
|
|
349
|
-
*
|
|
350
|
-
* @param startTime - Request start time
|
|
351
|
-
*/
|
|
352
|
-
public measureAPIResponse(startTime: number): void {
|
|
247
|
+
public measureAPIResponse(startTime: number): void {
|
|
353
248
|
const duration = Date.now() - startTime;
|
|
354
249
|
this.recordMetric('apiResponseTime', duration, 'ms', 1000);
|
|
355
250
|
}
|
|
356
251
|
|
|
357
|
-
|
|
358
|
-
* Disconnect all observers
|
|
359
|
-
*/
|
|
360
|
-
public disconnect(): void {
|
|
252
|
+
public disconnect(): void {
|
|
361
253
|
this.observers.forEach((observer) => observer.disconnect());
|
|
362
254
|
this.observers = [];
|
|
363
255
|
}
|
|
364
256
|
}
|
|
365
257
|
|
|
366
|
-
/**
|
|
367
|
-
* Create singleton instance
|
|
368
|
-
*/
|
|
369
258
|
export const performanceService = new PerformanceService();
|