main
js 90 lines 2.52 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 type {LoggerEvent} from 'react-devtools-shared/src/Logger';
11
12 import {registerEventLogger} from 'react-devtools-shared/src/Logger';
13 import {enableLogger} from 'react-devtools-feature-flags';
14
15 let currentLoggingIFrame = null;
16 let currentSessionId = null;
17 let missedEvents: Array<LoggerEvent> = [];
18 let hasRegisteredEventLogger = false;
19
20 type LoggerContext = {
21 page_url: ?string,
22 };
23
24 export function registerDevToolsEventLogger(
25 surface: string,
26 fetchAdditionalContext?:
27 | (() => LoggerContext)
28 | (() => Promise<LoggerContext>),
29 ): void {
30 async function logEvent(event: LoggerEvent) {
31 if (enableLogger) {
32 if (currentLoggingIFrame != null && currentSessionId != null) {
33 const {metadata, ...eventWithoutMetadata} = event;
34 const additionalContext: LoggerContext | {} =
35 fetchAdditionalContext != null ? await fetchAdditionalContext() : {};
36
37 currentLoggingIFrame?.contentWindow?.postMessage(
38 {
39 source: 'react-devtools-logging',
40 event: eventWithoutMetadata,
41 context: {
42 ...additionalContext,
43 metadata: metadata != null ? JSON.stringify(metadata) : '',
44 session_id: currentSessionId,
45 surface,
46 version: process.env.DEVTOOLS_VERSION,
47 },
48 },
49 '*',
50 );
51 } else {
52 missedEvents.push(event);
53 }
54 }
55 }
56
57 function handleLoggingIFrameLoaded(iframe: HTMLIFrameElement) {
58 currentLoggingIFrame = iframe;
59
60 if (missedEvents.length > 0) {
61 missedEvents.forEach(event => logEvent(event));
62 missedEvents = [];
63 }
64 }
65
66 // If logger is enabled, register a logger that captures logged events
67 // and render iframe where the logged events will be reported to
68 if (enableLogger) {
69 const loggingUrl = process.env.LOGGING_URL;
70 const body = document.body;
71
72 if (
73 typeof loggingUrl === 'string' &&
74 loggingUrl.length > 0 &&
75 body != null &&
76 !hasRegisteredEventLogger
77 ) {
78 hasRegisteredEventLogger = true;
79 registerEventLogger(logEvent);
80 currentSessionId = window.crypto.randomUUID();
81
82 const iframe = document.createElement('iframe');
83
84 iframe.onload = () => handleLoggingIFrameLoaded(iframe);
85 iframe.src = loggingUrl;
86
87 body.appendChild(iframe);
88 }
89 }
90 }