import type {LoggerEvent} from 'react-devtools-shared/src/Logger';
import {registerEventLogger} from 'react-devtools-shared/src/Logger';
import {enableLogger} from 'react-devtools-feature-flags';
let currentLoggingIFrame = null;
let currentSessionId = null;
let missedEvents: Array<LoggerEvent> = [];
type LoggerContext = {
page_url: ?string,
};
export function registerDevToolsEventLogger(
surface: string,
fetchAdditionalContext?:
| (() => LoggerContext)
| (() => Promise<LoggerContext>),
): void {
async function logEvent(event: LoggerEvent) {
if (enableLogger) {
if (currentLoggingIFrame != null && currentSessionId != null) {
const {metadata, ...eventWithoutMetadata} = event;
const additionalContext: LoggerContext | {} =
fetchAdditionalContext != null ? await fetchAdditionalContext() : {};
currentLoggingIFrame?.contentWindow?.postMessage(
{
source: 'react-devtools-logging',
event: eventWithoutMetadata,
context: {
...additionalContext,
metadata: metadata != null ? JSON.stringify(metadata) : '',
session_id: currentSessionId,
surface,
version: process.env.DEVTOOLS_VERSION,
},
},
'*',
);
} else {
missedEvents.push(event);
}
}
}
function handleLoggingIFrameLoaded(iframe: HTMLIFrameElement) {
currentLoggingIFrame = iframe;
if (missedEvents.length > 0) {
missedEvents.forEach(event => logEvent(event));
missedEvents = [];
}
}
if (enableLogger) {
const loggingUrl = process.env.LOGGING_URL;
const body = document.body;
if (
typeof loggingUrl === 'string' &&
loggingUrl.length > 0 &&
body != null &&
currentLoggingIFrame == null
) {
registerEventLogger(logEvent);
currentSessionId = window.crypto.randomUUID();
const iframe = document.createElement('iframe');
iframe.onload = () => handleLoggingIFrameLoaded(iframe);
iframe.src = loggingUrl;
body.appendChild(iframe);
}
}
}