import { Platform } from 'react-native'; import parseErrorStackLib, { ExtendedError, StackFrame, } from 'react-native/Libraries/Core/Devtools/parseErrorStack'; import Logger from '../core/logging/logger'; /** * Ensures that a function can only be executed once * @param func - The original function that we want to ensure is called only once. * @param context - The context in which the original function should be executed. * @returns The result of the original function if it's called for the first time, or the previously stored result if called again. */ export function once( func: (this: This, ...args: any[]) => T, context?: This ): (...args: any[]) => T { let result: T; let called = false; return function onceInner(...args: any[]): T { if (!called) { called = true; // @ts-ignore 'this' implicitly has type 'any' because it does not have a type annotation. result = func.apply(context ?? this, args); func = null as any; // clearing the reference to the original function } return result; }; } export const getStackTrace = (e: ExtendedError): StackFrame[] => { // Feature and version check combined, defaulting to a simpler approach if not detailed. const isRNNewerOrEqual64 = Platform.constants?.reactNativeVersion?.minor >= 64; // Use logical OR to handle both cases with a single line. const stackInput = isRNNewerOrEqual64 ? e.stack : e; // @ts-ignore return parseErrorStackLib(stackInput); }; /** * Checks if a given value is an instance of the Error class. * @param value - The value to be checked for being an Error instance. * @returns True if the value is an Error instance, false otherwise. */ export function isError(value: any): value is Error { return Object.prototype.toString.call(value) === '[object Error]'; } // Define the relative path to the contentsquare-sourcemap-info.json file const CONFIG_FILE_PATH = '../../../../../contentsquare-sourcemap-info.json'; interface SourcemapInfo { ios: { id: string }; android: { id: string }; } let sourcemapInfo: SourcemapInfo | null = null; try { // Dynamically import the contentsquare-sourcemap-info.json if it exists sourcemapInfo = require(CONFIG_FILE_PATH); } catch (error) { Logger.warn( 'contentsquare-sourcemap-info.json not found, continuing without sourcemap ID', true ); } /** * Get the sourcemap ID for the current platform. * @returns {string | undefined} - The sourcemap ID if found. */ export const getSourcemapId = (): string | undefined => { if (!sourcemapInfo) { return; } const platform = Platform.OS; try { if (platform === 'ios' || platform === 'android') { return sourcemapInfo[platform]?.id; } return; } catch (error) { Logger.error(`Failed to get sourcemap ID for ${platform}: ${error}`); return; } };