@vestig/next 0.8.0 → 0.9.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/dist/client/error-boundary.d.ts.map +1 -1
- package/dist/client/transport.d.ts +8 -0
- package/dist/client/transport.d.ts.map +1 -1
- package/dist/client/transport.js +59 -3
- package/dist/client/transport.js.map +1 -1
- package/dist/db/drizzle.d.ts.map +1 -1
- package/dist/db/drizzle.js +1 -1
- package/dist/db/drizzle.js.map +1 -1
- package/dist/db/prisma.d.ts.map +1 -1
- package/dist/db/prisma.js.map +1 -1
- package/dist/db/query-logger.js +1 -1
- package/dist/db/query-logger.js.map +1 -1
- package/dist/dev/filters.d.ts.map +1 -1
- package/dist/dev/filters.js +5 -1
- package/dist/dev/filters.js.map +1 -1
- package/dist/dev/hooks/use-logs.d.ts +3 -1
- package/dist/dev/hooks/use-logs.d.ts.map +1 -1
- package/dist/dev/hooks/use-logs.js +26 -29
- package/dist/dev/hooks/use-logs.js.map +1 -1
- package/dist/dev/log-entry.js.map +1 -1
- package/dist/dev/log-viewer.d.ts.map +1 -1
- package/dist/dev/log-viewer.js.map +1 -1
- package/dist/dev/metrics-card.d.ts.map +1 -1
- package/dist/dev/metrics-card.js +1 -1
- package/dist/dev/metrics-card.js.map +1 -1
- package/dist/dev/metrics-histogram.d.ts.map +1 -1
- package/dist/dev/metrics-histogram.js +1 -1
- package/dist/dev/metrics-histogram.js.map +1 -1
- package/dist/dev/metrics-panel.js +1 -1
- package/dist/dev/metrics-panel.js.map +1 -1
- package/dist/dev/overlay.d.ts +1 -1
- package/dist/dev/overlay.d.ts.map +1 -1
- package/dist/dev/overlay.js +22 -10
- package/dist/dev/overlay.js.map +1 -1
- package/dist/dev/store.d.ts +18 -78
- package/dist/dev/store.d.ts.map +1 -1
- package/dist/dev/store.js +179 -183
- package/dist/dev/store.js.map +1 -1
- package/dist/error/boundary.d.ts.map +1 -1
- package/dist/error/boundary.js +2 -2
- package/dist/error/boundary.js.map +1 -1
- package/dist/error/stack-parser.js +4 -4
- package/dist/error/stack-parser.js.map +1 -1
- package/dist/metrics/hooks/use-route-metrics.d.ts +2 -0
- package/dist/metrics/hooks/use-route-metrics.d.ts.map +1 -1
- package/dist/metrics/hooks/use-route-metrics.js +12 -11
- package/dist/metrics/hooks/use-route-metrics.js.map +1 -1
- package/dist/metrics/hooks/use-web-vitals.d.ts +6 -3
- package/dist/metrics/hooks/use-web-vitals.d.ts.map +1 -1
- package/dist/metrics/hooks/use-web-vitals.js +24 -29
- package/dist/metrics/hooks/use-web-vitals.js.map +1 -1
- package/dist/metrics/store.d.ts +57 -24
- package/dist/metrics/store.d.ts.map +1 -1
- package/dist/metrics/store.js +145 -130
- package/dist/metrics/store.js.map +1 -1
- package/dist/metrics/types.d.ts +5 -1
- package/dist/metrics/types.d.ts.map +1 -1
- package/dist/metrics/web-vitals.d.ts.map +1 -1
- package/dist/metrics/web-vitals.js +1 -1
- package/dist/metrics/web-vitals.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-web-vitals.d.ts","sourceRoot":"","sources":["../../../src/metrics/hooks/use-web-vitals.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;
|
|
1
|
+
{"version":3,"file":"use-web-vitals.d.ts","sourceRoot":"","sources":["../../../src/metrics/hooks/use-web-vitals.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AASH,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAkB,YAAY,EAAE,MAAM,UAAU,CAAA;AAExF;;GAEG;AACH,UAAU,mBAAmB;IAC5B,mCAAmC;IACnC,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,gCAAgC;IAChC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,sBAAsB;IACtB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,6CAA6C;IAC7C,qBAAqB,CAAC,EAAE,OAAO,CAAA;IAC/B,iBAAiB;IACjB,KAAK,CAAC,EAAE,OAAO,CAAA;CACf;AAmBD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,YAAY,CAAC,OAAO,GAAE,mBAAwB,GAAG,IAAI,CAqDpE;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC,CAgB7E;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,IAAI,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC,CAclF"}
|
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
* Web Vitals Hook
|
|
3
3
|
*
|
|
4
4
|
* React hook for capturing Core Web Vitals metrics.
|
|
5
|
-
*
|
|
5
|
+
* Uses simple useState + useEffect pattern (React Compiler handles memoization).
|
|
6
6
|
*
|
|
7
7
|
* @packageDocumentation
|
|
8
8
|
*/
|
|
9
9
|
'use client';
|
|
10
|
-
import {
|
|
10
|
+
import { useEffect, useState } from 'react';
|
|
11
11
|
import { onCLS, onFCP, onINP, onLCP, onTTFB } from 'web-vitals';
|
|
12
|
-
import { metricsStore } from '../store';
|
|
13
12
|
import { MetricsReporter } from '../reporter';
|
|
13
|
+
import { metricsStore } from '../store';
|
|
14
14
|
/**
|
|
15
15
|
* Convert web-vitals Metric to our MetricEntry format
|
|
16
16
|
*/
|
|
@@ -46,20 +46,16 @@ function toMetricEntry(metric) {
|
|
|
46
46
|
export function useWebVitals(options = {}) {
|
|
47
47
|
const { enabled = true, sampleRate = 1.0, reportEndpoint = '/api/vestig/metrics', reportPoorImmediately = true, debug = false, } = options;
|
|
48
48
|
useEffect(() => {
|
|
49
|
-
// Skip if disabled or failed sample
|
|
50
49
|
if (!enabled)
|
|
51
50
|
return;
|
|
52
51
|
if (Math.random() > sampleRate)
|
|
53
52
|
return;
|
|
54
|
-
// Create reporter for this session
|
|
55
53
|
const reporter = new MetricsReporter({
|
|
56
54
|
endpoint: reportEndpoint,
|
|
57
55
|
debug,
|
|
58
56
|
});
|
|
59
|
-
// Handler for all metrics
|
|
60
57
|
const handleMetric = (metric) => {
|
|
61
58
|
const entry = toMetricEntry(metric);
|
|
62
|
-
// Add to store
|
|
63
59
|
metricsStore.addMetric(entry);
|
|
64
60
|
if (debug) {
|
|
65
61
|
console.log(`[vestig-metrics] ${metric.name}:`, {
|
|
@@ -68,13 +64,11 @@ export function useWebVitals(options = {}) {
|
|
|
68
64
|
delta: metric.delta,
|
|
69
65
|
});
|
|
70
66
|
}
|
|
71
|
-
// Create full entry with ID for reporter
|
|
72
67
|
const fullEntry = {
|
|
73
68
|
...entry,
|
|
74
69
|
id: `m_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 7)}`,
|
|
75
70
|
timestamp: new Date().toISOString(),
|
|
76
71
|
};
|
|
77
|
-
// Report immediately if poor, otherwise batch
|
|
78
72
|
if (reportPoorImmediately && metric.rating === 'poor') {
|
|
79
73
|
reporter.reportImmediate(fullEntry);
|
|
80
74
|
}
|
|
@@ -82,8 +76,6 @@ export function useWebVitals(options = {}) {
|
|
|
82
76
|
reporter.report(fullEntry);
|
|
83
77
|
}
|
|
84
78
|
};
|
|
85
|
-
// Subscribe to all Core Web Vitals
|
|
86
|
-
// Note: onFID is deprecated, use onINP instead
|
|
87
79
|
onLCP(handleMetric);
|
|
88
80
|
onCLS(handleMetric);
|
|
89
81
|
onINP(handleMetric);
|
|
@@ -97,6 +89,9 @@ export function useWebVitals(options = {}) {
|
|
|
97
89
|
/**
|
|
98
90
|
* Hook to get the current Web Vitals from the store
|
|
99
91
|
*
|
|
92
|
+
* Simple useState + useEffect pattern - React Compiler handles memoization.
|
|
93
|
+
* No useSyncExternalStore = no hydration headaches.
|
|
94
|
+
*
|
|
100
95
|
* @returns Latest Web Vitals values
|
|
101
96
|
*
|
|
102
97
|
* @example
|
|
@@ -115,16 +110,17 @@ export function useWebVitals(options = {}) {
|
|
|
115
110
|
* ```
|
|
116
111
|
*/
|
|
117
112
|
export function useWebVitalsData() {
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
113
|
+
const [vitals, setVitals] = useState({});
|
|
114
|
+
useEffect(() => {
|
|
115
|
+
// Get initial state
|
|
116
|
+
setVitals(metricsStore.getLatestVitals());
|
|
117
|
+
// Subscribe to updates
|
|
118
|
+
const unsubscribe = metricsStore.subscribe(() => {
|
|
119
|
+
setVitals(metricsStore.getLatestVitals());
|
|
120
|
+
});
|
|
121
|
+
return unsubscribe;
|
|
126
122
|
}, []);
|
|
127
|
-
return
|
|
123
|
+
return vitals;
|
|
128
124
|
}
|
|
129
125
|
/**
|
|
130
126
|
* Hook to get Web Vitals summary statistics
|
|
@@ -132,15 +128,14 @@ export function useWebVitalsData() {
|
|
|
132
128
|
* @returns Summary statistics for all Web Vitals
|
|
133
129
|
*/
|
|
134
130
|
export function useWebVitalsSummary() {
|
|
135
|
-
const
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
return {};
|
|
131
|
+
const [summary, setSummary] = useState({});
|
|
132
|
+
useEffect(() => {
|
|
133
|
+
setSummary(metricsStore.getVitalsSummary());
|
|
134
|
+
const unsubscribe = metricsStore.subscribe(() => {
|
|
135
|
+
setSummary(metricsStore.getVitalsSummary());
|
|
136
|
+
});
|
|
137
|
+
return unsubscribe;
|
|
143
138
|
}, []);
|
|
144
|
-
return
|
|
139
|
+
return summary;
|
|
145
140
|
}
|
|
146
141
|
//# sourceMappingURL=use-web-vitals.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-web-vitals.js","sourceRoot":"","sources":["../../../src/metrics/hooks/use-web-vitals.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,YAAY,CAAA;AAEZ,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"use-web-vitals.js","sourceRoot":"","sources":["../../../src/metrics/hooks/use-web-vitals.ts"],"names":[],"mappings":"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"}
|
package/dist/metrics/store.d.ts
CHANGED
|
@@ -1,34 +1,67 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Metrics Store
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Simple pub/sub store for performance metrics.
|
|
5
|
+
* Designed for reliability over cleverness - no useSyncExternalStore magic.
|
|
6
6
|
*
|
|
7
7
|
* @packageDocumentation
|
|
8
8
|
*/
|
|
9
|
-
import type {
|
|
9
|
+
import type { HistogramBucket, MetricEntry, MetricSummary, MetricsState, WebVitalName } from './types';
|
|
10
|
+
type Listener = () => void;
|
|
11
|
+
/**
|
|
12
|
+
* Simple metrics store - no React magic, just data + subscriptions
|
|
13
|
+
*/
|
|
14
|
+
declare class SimpleMetricsStore {
|
|
15
|
+
private state;
|
|
16
|
+
private listeners;
|
|
17
|
+
/**
|
|
18
|
+
* Subscribe to store changes
|
|
19
|
+
*/
|
|
20
|
+
subscribe(listener: Listener): () => void;
|
|
21
|
+
/**
|
|
22
|
+
* Notify all listeners of a change
|
|
23
|
+
*/
|
|
24
|
+
private notify;
|
|
25
|
+
/**
|
|
26
|
+
* Add a new metric to the store
|
|
27
|
+
*/
|
|
28
|
+
addMetric(entry: Omit<MetricEntry, 'id' | 'timestamp'>): void;
|
|
29
|
+
/**
|
|
30
|
+
* Get latest vitals - returns a new object each time (React will handle memoization)
|
|
31
|
+
*/
|
|
32
|
+
getLatestVitals(): Partial<Record<WebVitalName, MetricEntry>>;
|
|
33
|
+
/**
|
|
34
|
+
* Get vitals summary
|
|
35
|
+
*/
|
|
36
|
+
getVitalsSummary(): Partial<Record<WebVitalName, MetricSummary>>;
|
|
37
|
+
/**
|
|
38
|
+
* Get route metrics
|
|
39
|
+
*/
|
|
40
|
+
getRouteMetrics(): MetricEntry[];
|
|
41
|
+
/**
|
|
42
|
+
* Get histogram for a specific metric
|
|
43
|
+
*/
|
|
44
|
+
getHistogram(name: string, bucketCount?: number): HistogramBucket[];
|
|
45
|
+
/**
|
|
46
|
+
* Get summary statistics for a metric
|
|
47
|
+
*/
|
|
48
|
+
getSummary(name: string): MetricSummary | null;
|
|
49
|
+
/**
|
|
50
|
+
* Get the latest metric for a given name
|
|
51
|
+
*/
|
|
52
|
+
getLatest(name: string): MetricEntry | null;
|
|
53
|
+
/**
|
|
54
|
+
* Get current snapshot (for debugging)
|
|
55
|
+
*/
|
|
56
|
+
getSnapshot(): MetricsState;
|
|
57
|
+
/**
|
|
58
|
+
* Clear all metrics
|
|
59
|
+
*/
|
|
60
|
+
clear(): void;
|
|
61
|
+
}
|
|
10
62
|
/**
|
|
11
63
|
* Global metrics store singleton
|
|
12
|
-
*
|
|
13
|
-
* @example
|
|
14
|
-
* ```ts
|
|
15
|
-
* import { metricsStore } from '@vestig/next/metrics'
|
|
16
|
-
*
|
|
17
|
-
* // Subscribe to changes
|
|
18
|
-
* const unsubscribe = metricsStore.subscribe(() => {
|
|
19
|
-
* const summary = metricsStore.getVitalsSummary()
|
|
20
|
-
* console.log('LCP p75:', summary.LCP?.p75)
|
|
21
|
-
* })
|
|
22
|
-
*
|
|
23
|
-
* // Add a metric
|
|
24
|
-
* metricsStore.addMetric({
|
|
25
|
-
* type: 'web-vital',
|
|
26
|
-
* name: 'LCP',
|
|
27
|
-
* value: 2500,
|
|
28
|
-
* rating: 'needs-improvement',
|
|
29
|
-
* metadata: { pathname: '/dashboard' }
|
|
30
|
-
* })
|
|
31
|
-
* ```
|
|
32
64
|
*/
|
|
33
|
-
export declare const metricsStore:
|
|
65
|
+
export declare const metricsStore: SimpleMetricsStore;
|
|
66
|
+
export {};
|
|
34
67
|
//# sourceMappingURL=store.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/metrics/store.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/metrics/store.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EACX,eAAe,EACf,WAAW,EAEX,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,MAAM,SAAS,CAAA;AAmBhB,KAAK,QAAQ,GAAG,MAAM,IAAI,CAAA;AAE1B;;GAEG;AACH,cAAM,kBAAkB;IACvB,OAAO,CAAC,KAAK,CAIZ;IAED,OAAO,CAAC,SAAS,CAAsB;IAEvC;;OAEG;IACH,SAAS,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,IAAI;IAKzC;;OAEG;IACH,OAAO,CAAC,MAAM;IAUd;;OAEG;IACH,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,GAAG,WAAW,CAAC,GAAG,IAAI;IAsB7D;;OAEG;IACH,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;IAI7D;;OAEG;IACH,gBAAgB,IAAI,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;IAchE;;OAEG;IACH,eAAe,IAAI,WAAW,EAAE;IAIhC;;OAEG;IACH,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,SAAK,GAAG,eAAe,EAAE;IA8B/D;;OAEG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI;IA6B9C;;OAEG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IAS3C;;OAEG;IACH,WAAW,IAAI,YAAY;IAI3B;;OAEG;IACH,KAAK,IAAI,IAAI;CAKb;AAED;;GAEG;AACH,eAAO,MAAM,YAAY,oBAA2B,CAAA"}
|
package/dist/metrics/store.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Metrics Store
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Simple pub/sub store for performance metrics.
|
|
5
|
+
* Designed for reliability over cleverness - no useSyncExternalStore magic.
|
|
6
6
|
*
|
|
7
7
|
* @packageDocumentation
|
|
8
8
|
*/
|
|
9
|
-
import {
|
|
9
|
+
import { THRESHOLDS, getRating } from './thresholds';
|
|
10
10
|
/**
|
|
11
11
|
* Create a unique ID for metrics
|
|
12
12
|
*/
|
|
@@ -24,17 +24,27 @@ function percentile(sorted, p) {
|
|
|
24
24
|
return sorted[clampedIndex] ?? 0;
|
|
25
25
|
}
|
|
26
26
|
/**
|
|
27
|
-
*
|
|
27
|
+
* Simple metrics store - no React magic, just data + subscriptions
|
|
28
28
|
*/
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
class SimpleMetricsStore {
|
|
30
|
+
state = {
|
|
31
31
|
metrics: [],
|
|
32
32
|
maxMetrics: 500,
|
|
33
33
|
latestVitals: {},
|
|
34
34
|
};
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
listeners = new Set();
|
|
36
|
+
/**
|
|
37
|
+
* Subscribe to store changes
|
|
38
|
+
*/
|
|
39
|
+
subscribe(listener) {
|
|
40
|
+
this.listeners.add(listener);
|
|
41
|
+
return () => this.listeners.delete(listener);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Notify all listeners of a change
|
|
45
|
+
*/
|
|
46
|
+
notify() {
|
|
47
|
+
for (const listener of this.listeners) {
|
|
38
48
|
try {
|
|
39
49
|
listener();
|
|
40
50
|
}
|
|
@@ -43,130 +53,135 @@ function createMetricsStore() {
|
|
|
43
53
|
}
|
|
44
54
|
}
|
|
45
55
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
count: 0,
|
|
83
|
-
percentage: 0,
|
|
84
|
-
}));
|
|
85
|
-
for (const value of values) {
|
|
86
|
-
const bucketIndex = Math.min(Math.floor((value - min) / bucketSize), bucketCount - 1);
|
|
87
|
-
const bucket = buckets[bucketIndex];
|
|
88
|
-
if (bucket)
|
|
89
|
-
bucket.count++;
|
|
90
|
-
}
|
|
91
|
-
// Calculate percentages
|
|
92
|
-
for (const bucket of buckets) {
|
|
93
|
-
bucket.percentage = (bucket.count / values.length) * 100;
|
|
94
|
-
}
|
|
95
|
-
return buckets;
|
|
96
|
-
},
|
|
97
|
-
getSummary(name) {
|
|
98
|
-
const values = state.metrics.filter((m) => m.name === name).map((m) => m.value);
|
|
99
|
-
if (values.length === 0)
|
|
100
|
-
return null;
|
|
101
|
-
const sorted = [...values].sort((a, b) => a - b);
|
|
102
|
-
const sum = values.reduce((acc, v) => acc + v, 0);
|
|
103
|
-
const avg = sum / values.length;
|
|
104
|
-
const p75 = percentile(sorted, 75);
|
|
105
|
-
// Determine rating based on p75 for web vitals
|
|
106
|
-
let rating = 'needs-improvement';
|
|
107
|
-
if (name in THRESHOLDS) {
|
|
108
|
-
rating = getRating(name, p75);
|
|
109
|
-
}
|
|
110
|
-
return {
|
|
111
|
-
name,
|
|
112
|
-
count: values.length,
|
|
113
|
-
avg,
|
|
114
|
-
min: sorted[0] ?? 0,
|
|
115
|
-
max: sorted[sorted.length - 1] ?? 0,
|
|
116
|
-
p50: percentile(sorted, 50),
|
|
117
|
-
p75,
|
|
118
|
-
p95: percentile(sorted, 95),
|
|
119
|
-
p99: percentile(sorted, 99),
|
|
120
|
-
rating,
|
|
121
|
-
};
|
|
122
|
-
},
|
|
123
|
-
getVitalsSummary() {
|
|
124
|
-
const result = {};
|
|
125
|
-
const vitals = ['LCP', 'CLS', 'INP', 'TTFB', 'FCP'];
|
|
126
|
-
for (const name of vitals) {
|
|
127
|
-
const summary = this.getSummary(name);
|
|
128
|
-
if (summary) {
|
|
129
|
-
result[name] = summary;
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
return result;
|
|
133
|
-
},
|
|
134
|
-
getLatest(name) {
|
|
135
|
-
if (name in state.latestVitals) {
|
|
136
|
-
return state.latestVitals[name] ?? null;
|
|
56
|
+
/**
|
|
57
|
+
* Add a new metric to the store
|
|
58
|
+
*/
|
|
59
|
+
addMetric(entry) {
|
|
60
|
+
const metric = {
|
|
61
|
+
...entry,
|
|
62
|
+
id: createMetricId(),
|
|
63
|
+
timestamp: new Date().toISOString(),
|
|
64
|
+
};
|
|
65
|
+
this.state.metrics.push(metric);
|
|
66
|
+
// Update latest vitals
|
|
67
|
+
if (entry.type === 'web-vital') {
|
|
68
|
+
this.state.latestVitals[entry.name] = metric;
|
|
69
|
+
}
|
|
70
|
+
// Trim if over limit
|
|
71
|
+
if (this.state.metrics.length > this.state.maxMetrics) {
|
|
72
|
+
this.state.metrics = this.state.metrics.slice(-this.state.maxMetrics);
|
|
73
|
+
}
|
|
74
|
+
this.notify();
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Get latest vitals - returns a new object each time (React will handle memoization)
|
|
78
|
+
*/
|
|
79
|
+
getLatestVitals() {
|
|
80
|
+
return { ...this.state.latestVitals };
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Get vitals summary
|
|
84
|
+
*/
|
|
85
|
+
getVitalsSummary() {
|
|
86
|
+
const result = {};
|
|
87
|
+
const vitals = ['LCP', 'CLS', 'INP', 'TTFB', 'FCP'];
|
|
88
|
+
for (const name of vitals) {
|
|
89
|
+
const summary = this.getSummary(name);
|
|
90
|
+
if (summary) {
|
|
91
|
+
result[name] = summary;
|
|
137
92
|
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
}
|
|
93
|
+
}
|
|
94
|
+
return result;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Get route metrics
|
|
98
|
+
*/
|
|
99
|
+
getRouteMetrics() {
|
|
100
|
+
return this.state.metrics.filter((m) => m.type === 'route');
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Get histogram for a specific metric
|
|
104
|
+
*/
|
|
105
|
+
getHistogram(name, bucketCount = 10) {
|
|
106
|
+
const values = this.state.metrics.filter((m) => m.name === name).map((m) => m.value);
|
|
107
|
+
if (values.length === 0)
|
|
108
|
+
return [];
|
|
109
|
+
const min = Math.min(...values);
|
|
110
|
+
const max = Math.max(...values);
|
|
111
|
+
const range = max - min || 1;
|
|
112
|
+
const bucketSize = range / bucketCount;
|
|
113
|
+
const buckets = Array.from({ length: bucketCount }, (_, i) => ({
|
|
114
|
+
min: min + i * bucketSize,
|
|
115
|
+
max: min + (i + 1) * bucketSize,
|
|
116
|
+
count: 0,
|
|
117
|
+
percentage: 0,
|
|
118
|
+
}));
|
|
119
|
+
for (const value of values) {
|
|
120
|
+
const bucketIndex = Math.min(Math.floor((value - min) / bucketSize), bucketCount - 1);
|
|
121
|
+
const bucket = buckets[bucketIndex];
|
|
122
|
+
if (bucket)
|
|
123
|
+
bucket.count++;
|
|
124
|
+
}
|
|
125
|
+
for (const bucket of buckets) {
|
|
126
|
+
bucket.percentage = (bucket.count / values.length) * 100;
|
|
127
|
+
}
|
|
128
|
+
return buckets;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Get summary statistics for a metric
|
|
132
|
+
*/
|
|
133
|
+
getSummary(name) {
|
|
134
|
+
const values = this.state.metrics.filter((m) => m.name === name).map((m) => m.value);
|
|
135
|
+
if (values.length === 0)
|
|
136
|
+
return null;
|
|
137
|
+
const sorted = [...values].sort((a, b) => a - b);
|
|
138
|
+
const sum = values.reduce((acc, v) => acc + v, 0);
|
|
139
|
+
const avg = sum / values.length;
|
|
140
|
+
const p75 = percentile(sorted, 75);
|
|
141
|
+
let rating = 'needs-improvement';
|
|
142
|
+
if (name in THRESHOLDS) {
|
|
143
|
+
rating = getRating(name, p75);
|
|
144
|
+
}
|
|
145
|
+
return {
|
|
146
|
+
name,
|
|
147
|
+
count: values.length,
|
|
148
|
+
avg,
|
|
149
|
+
min: sorted[0] ?? 0,
|
|
150
|
+
max: sorted[sorted.length - 1] ?? 0,
|
|
151
|
+
p50: percentile(sorted, 50),
|
|
152
|
+
p75,
|
|
153
|
+
p95: percentile(sorted, 95),
|
|
154
|
+
p99: percentile(sorted, 99),
|
|
155
|
+
rating,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Get the latest metric for a given name
|
|
160
|
+
*/
|
|
161
|
+
getLatest(name) {
|
|
162
|
+
if (name in this.state.latestVitals) {
|
|
163
|
+
return this.state.latestVitals[name] ?? null;
|
|
164
|
+
}
|
|
165
|
+
const metrics = this.state.metrics.filter((m) => m.name === name);
|
|
166
|
+
return metrics[metrics.length - 1] ?? null;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Get current snapshot (for debugging)
|
|
170
|
+
*/
|
|
171
|
+
getSnapshot() {
|
|
172
|
+
return this.state;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Clear all metrics
|
|
176
|
+
*/
|
|
177
|
+
clear() {
|
|
178
|
+
this.state.metrics = [];
|
|
179
|
+
this.state.latestVitals = {};
|
|
180
|
+
this.notify();
|
|
181
|
+
}
|
|
147
182
|
}
|
|
148
183
|
/**
|
|
149
184
|
* Global metrics store singleton
|
|
150
|
-
*
|
|
151
|
-
* @example
|
|
152
|
-
* ```ts
|
|
153
|
-
* import { metricsStore } from '@vestig/next/metrics'
|
|
154
|
-
*
|
|
155
|
-
* // Subscribe to changes
|
|
156
|
-
* const unsubscribe = metricsStore.subscribe(() => {
|
|
157
|
-
* const summary = metricsStore.getVitalsSummary()
|
|
158
|
-
* console.log('LCP p75:', summary.LCP?.p75)
|
|
159
|
-
* })
|
|
160
|
-
*
|
|
161
|
-
* // Add a metric
|
|
162
|
-
* metricsStore.addMetric({
|
|
163
|
-
* type: 'web-vital',
|
|
164
|
-
* name: 'LCP',
|
|
165
|
-
* value: 2500,
|
|
166
|
-
* rating: 'needs-improvement',
|
|
167
|
-
* metadata: { pathname: '/dashboard' }
|
|
168
|
-
* })
|
|
169
|
-
* ```
|
|
170
185
|
*/
|
|
171
|
-
export const metricsStore =
|
|
186
|
+
export const metricsStore = new SimpleMetricsStore();
|
|
172
187
|
//# sourceMappingURL=store.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/metrics/store.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/metrics/store.ts"],"names":[],"mappings":"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"}
|
package/dist/metrics/types.d.ts
CHANGED
|
@@ -180,7 +180,7 @@ export interface MetricsState {
|
|
|
180
180
|
export interface MetricsStore {
|
|
181
181
|
/** Subscribe to store changes */
|
|
182
182
|
subscribe: (listener: () => void) => () => void;
|
|
183
|
-
/** Get current snapshot of state */
|
|
183
|
+
/** Get current snapshot of state (for debugging) */
|
|
184
184
|
getSnapshot: () => MetricsState;
|
|
185
185
|
/** Add a new metric */
|
|
186
186
|
addMetric: (entry: Omit<MetricEntry, 'id' | 'timestamp'>) => void;
|
|
@@ -190,6 +190,10 @@ export interface MetricsStore {
|
|
|
190
190
|
getSummary: (name: string) => MetricSummary | null;
|
|
191
191
|
/** Get all summaries for web vitals */
|
|
192
192
|
getVitalsSummary: () => Partial<Record<WebVitalName, MetricSummary>>;
|
|
193
|
+
/** Get latest vitals */
|
|
194
|
+
getLatestVitals: () => Partial<Record<WebVitalName, MetricEntry>>;
|
|
195
|
+
/** Get route metrics */
|
|
196
|
+
getRouteMetrics: () => MetricEntry[];
|
|
193
197
|
/** Get the latest metric for a given name */
|
|
194
198
|
getLatest: (name: string) => MetricEntry | null;
|
|
195
199
|
/** Clear all metrics */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/metrics/types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/metrics/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web-vitals.d.ts","sourceRoot":"","sources":["../../src/metrics/web-vitals.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;
|
|
1
|
+
{"version":3,"file":"web-vitals.d.ts","sourceRoot":"","sources":["../../src/metrics/web-vitals.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAMH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAA;AAElD;;GAEG;AACH,MAAM,WAAW,kBAAmB,SAAQ,mBAAmB;CAAG;AAElE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wBAAgB,aAAa,CAAC,EAC7B,OAAc,EACd,UAAU,EACV,cAAsC,EACtC,qBAA4B,EAC5B,mBAA0B,EAC1B,KAAa,GACb,EAAE,kBAAkB,GAAG,IAAI,CAwB3B"}
|
|
@@ -27,8 +27,8 @@
|
|
|
27
27
|
* @packageDocumentation
|
|
28
28
|
*/
|
|
29
29
|
'use client';
|
|
30
|
-
import { useWebVitals } from './hooks/use-web-vitals';
|
|
31
30
|
import { useRouteMetrics } from './hooks/use-route-metrics';
|
|
31
|
+
import { useWebVitals } from './hooks/use-web-vitals';
|
|
32
32
|
/**
|
|
33
33
|
* VestigMetrics - Core Web Vitals and Route Metrics Component
|
|
34
34
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web-vitals.js","sourceRoot":"","sources":["../../src/metrics/web-vitals.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"web-vitals.js","sourceRoot":"","sources":["../../src/metrics/web-vitals.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,YAAY,CAAA;AAEZ,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAA;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAA;AAQrD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,MAAM,UAAU,aAAa,CAAC,EAC7B,OAAO,GAAG,IAAI,EACd,UAAU,EACV,cAAc,GAAG,qBAAqB,EACtC,qBAAqB,GAAG,IAAI,EAC5B,mBAAmB,GAAG,IAAI,EAC1B,KAAK,GAAG,KAAK,GACO;IACpB,8DAA8D;IAC9D,MAAM,mBAAmB,GACxB,UAAU;QACV,CAAC,OAAO,MAAM,KAAK,WAAW,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;IAErF,0BAA0B;IAC1B,YAAY,CAAC;QACZ,OAAO;QACP,UAAU,EAAE,mBAAmB;QAC/B,cAAc;QACd,qBAAqB;QACrB,KAAK;KACL,CAAC,CAAA;IAEF,wBAAwB;IACxB,eAAe,CAAC;QACf,OAAO,EAAE,OAAO,IAAI,mBAAmB;QACvC,cAAc;QACd,KAAK;KACL,CAAC,CAAA;IAEF,yCAAyC;IACzC,OAAO,IAAI,CAAA;AACZ,CAAC"}
|