main
js 123 lines 2.93 KB
Raw
1 /**
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 *
7 * @flow strict-local
8 */
9
10 import {enableLogger} from 'react-devtools-feature-flags';
11
12 export type LoggerEvent =
13 | {
14 +event_name: 'loaded-dev-tools',
15 }
16 | {
17 +event_name: 'error',
18 +error_message: string | null,
19 +error_stack: string | null,
20 +error_component_stack: string | null,
21 }
22 | {
23 +event_name: 'selected-components-tab',
24 }
25 | {
26 +event_name: 'selected-profiler-tab',
27 }
28 | {
29 +event_name: 'selected-suspense-tab',
30 }
31 | {
32 +event_name: 'load-hook-names',
33 +event_status: 'success' | 'error' | 'timeout' | 'unknown',
34 +duration_ms: number,
35 +inspected_element_display_name: string | null,
36 +inspected_element_number_of_hooks: number | null,
37 }
38 | {
39 +event_name: 'select-element',
40 +metadata: {
41 +source: string,
42 },
43 }
44 | {
45 +event_name: 'inspect-element-button-clicked',
46 }
47 | {
48 +event_name: 'profiling-start',
49 +metadata: {
50 +current_tab: string,
51 },
52 }
53 | {
54 +event_name: 'profiler-tab-changed',
55 +metadata: {
56 +tabId: string,
57 },
58 }
59 | {
60 +event_name: 'settings-changed',
61 +metadata: {
62 +key: string,
63 +value: any,
64 ...
65 },
66 }
67 | {
68 +event_name: 'selected-editor-pane',
69 }
70 | {+event_name: 'selected-inspected-element-pane'};
71
72 export type LogFunction = LoggerEvent => void | Promise<void>;
73
74 let logFunctions: Array<LogFunction> = [];
75 export const logEvent: LogFunction =
76 enableLogger === true
77 ? function logEvent(event: LoggerEvent): void {
78 logFunctions.forEach(log => {
79 log(event);
80 });
81 }
82 : function logEvent() {};
83
84 export function logErrorEvent(
85 error: mixed,
86 componentStack: string | null,
87 ): void {
88 const errorMessage =
89 typeof error === 'object' &&
90 error !== null &&
91 typeof error.message === 'string'
92 ? error.message
93 : null;
94 const errorStack =
95 typeof error === 'object' &&
96 error !== null &&
97 typeof error.stack === 'string'
98 ? error.stack
99 : null;
100
101 logEvent({
102 event_name: 'error',
103 error_message: errorMessage,
104 error_stack: errorStack,
105 error_component_stack: componentStack,
106 });
107 }
108
109 export const registerEventLogger: (logFunction: LogFunction) => () => void =
110 enableLogger === true
111 ? function registerEventLogger(logFunction: LogFunction): () => void {
112 // $FlowFixMe[constant-condition]
113 if (enableLogger) {
114 logFunctions.push(logFunction);
115 return function unregisterEventLogger() {
116 logFunctions = logFunctions.filter(log => log !== logFunction);
117 };
118 }
119 return () => {};
120 }
121 : function registerEventLogger(logFunction: LogFunction) {
122 return () => {};
123 };