1interface ReviewPerformanceLike {
2 readonly now?: () => number;
3 readonly mark?: (name: string) => void;
4 readonly measure?: (name: string, startMark: string, endMark: string) => void;
5 readonly clearMarks?: (name?: string) => void;
6 readonly clearMeasures?: (name?: string) => void;
7}
8
9const REVIEW_PERF_PREFIX = "t3.review";
10let reviewPerfSequence = 0;
11
12function getPerformance(): ReviewPerformanceLike | null {
13 const candidate = (globalThis as { readonly performance?: ReviewPerformanceLike }).performance;
14 return candidate ?? null;
15}
16
17export function isReviewPerfEnabled(): boolean {
18 return typeof __DEV__ !== "undefined" ? __DEV__ : false;
19}
20
21export function measureReviewWork<T>(name: string, callback: () => T): T {
22 if (!isReviewPerfEnabled()) {
23 return callback();
24 }
25
26 const perf = getPerformance();
27 const marker = `${REVIEW_PERF_PREFIX}.${name}.${reviewPerfSequence++}`;
28 const startMark = `${marker}.start`;
29 const endMark = `${marker}.end`;
30 const startedAt = perf?.now?.() ?? Date.now();
31
32 perf?.mark?.(startMark);
33 try {
34 return callback();
35 } finally {
36 const durationMs = (perf?.now?.() ?? Date.now()) - startedAt;
37 perf?.mark?.(endMark);
38 perf?.measure?.(`${REVIEW_PERF_PREFIX}.${name}`, startMark, endMark);
39 perf?.clearMarks?.(startMark);
40 perf?.clearMarks?.(endMark);
41 console.log(`[review-perf] ${name}`, { durationMs: Number(durationMs.toFixed(2)) });
42 }
43}
44
45export function markReviewEvent(name: string, details?: Record<string, unknown>): void {
46 if (!isReviewPerfEnabled()) {
47 return;
48 }
49
50 getPerformance()?.mark?.(`${REVIEW_PERF_PREFIX}.${name}`);
51 if (details) {
52 console.log(`[review-perf] ${name}`, details);
53 return;
54 }
55 console.log(`[review-perf] ${name}`);
56}