- Consolidated duplicate UndoManagers to single instance - Fixed connection promise to only resolve on 'connected' status - Fixed WebSocketProvider import (WebsocketProvider) - Added proper doc.destroy() cleanup - Renamed isPresenceInitialized property to avoid conflict Co-Authored-By: Paperclip <noreply@paperclip.ing>
117 lines
2.8 KiB
Plaintext
117 lines
2.8 KiB
Plaintext
/**
|
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*
|
|
* @flow
|
|
* @format
|
|
* @oncall react_native
|
|
*/
|
|
|
|
import type {BundleOptions} from 'metro/private/shared/types';
|
|
|
|
import EventEmitter from 'events';
|
|
import os from 'os';
|
|
|
|
// eslint-disable-next-line import/no-commonjs
|
|
const VERSION = require('../package.json').version;
|
|
|
|
export type ActionLogEntryData = {
|
|
action_name: string,
|
|
log_entry_label?: string,
|
|
...
|
|
};
|
|
|
|
export type ActionStartLogEntry = {
|
|
action_name?: string,
|
|
action_phase?: string,
|
|
log_entry_label: string,
|
|
log_session?: string,
|
|
start_timestamp?: [number, number],
|
|
...
|
|
};
|
|
|
|
export type LogEntry = {
|
|
action_name?: string,
|
|
action_phase?: string,
|
|
action_result?: string,
|
|
duration_ms?: number,
|
|
entry_point?: string,
|
|
file_name?: string,
|
|
log_entry_label: string,
|
|
log_session?: string,
|
|
start_timestamp?: [number, number],
|
|
outdated_modules?: number,
|
|
bundle_size?: number,
|
|
bundle_options?: BundleOptions,
|
|
bundle_hash?: string,
|
|
build_id?: string,
|
|
error_message?: string,
|
|
error_stack?: string,
|
|
...
|
|
};
|
|
|
|
const log_session = `${os.hostname()}-${Date.now()}`;
|
|
const eventEmitter = new EventEmitter();
|
|
|
|
function on(event: string, handler: (logEntry: LogEntry) => void): void {
|
|
eventEmitter.on(event, handler);
|
|
}
|
|
|
|
function createEntry(data: LogEntry | string): LogEntry {
|
|
const logEntry: LogEntry =
|
|
typeof data === 'string' ? {log_entry_label: data} : data;
|
|
|
|
return {
|
|
...logEntry,
|
|
log_session,
|
|
metro_bundler_version: VERSION,
|
|
};
|
|
}
|
|
|
|
function createActionStartEntry(data: ActionLogEntryData | string): LogEntry {
|
|
const logEntry = typeof data === 'string' ? {action_name: data} : data;
|
|
const {action_name} = logEntry;
|
|
|
|
return createEntry({
|
|
log_entry_label: action_name,
|
|
...logEntry,
|
|
action_name,
|
|
action_phase: 'start',
|
|
start_timestamp: process.hrtime(),
|
|
});
|
|
}
|
|
|
|
function createActionEndEntry(
|
|
logEntry: ActionStartLogEntry,
|
|
error?: ?Error,
|
|
): LogEntry {
|
|
const {action_name, action_phase, start_timestamp} = logEntry;
|
|
|
|
if (action_phase !== 'start' || !Array.isArray(start_timestamp)) {
|
|
throw new Error('Action has not started or has already ended');
|
|
}
|
|
|
|
const timeDelta = process.hrtime(start_timestamp);
|
|
const duration_ms = Math.round((timeDelta[0] * 1e9 + timeDelta[1]) / 1e6);
|
|
|
|
return createEntry({
|
|
log_entry_label: action_name as ?string,
|
|
...logEntry,
|
|
action_name,
|
|
action_phase: 'end',
|
|
duration_ms,
|
|
...(error != null
|
|
? {error_message: error.message, error_stack: error.stack}
|
|
: null),
|
|
});
|
|
}
|
|
|
|
function log(logEntry: LogEntry): LogEntry {
|
|
eventEmitter.emit('log', logEntry);
|
|
return logEntry;
|
|
}
|
|
|
|
export {on, createEntry, createActionStartEntry, createActionEndEntry, log};
|