UNPKG

@datadog/mobile-react-native

Version:

A client-side React Native module to interact with Datadog

133 lines (129 loc) 5.83 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DdRumUserInteractionTracking = void 0; var _react = _interopRequireDefault(require("react")); var _InternalLog = require("../../../InternalLog"); var _SdkVerbosity = require("../../../SdkVerbosity"); var _DdSdk = require("../../../sdk/DdSdk"); var _errorUtils = require("../../../utils/errorUtils"); var _constants = require("../../constants"); var _DdBabelInteractionTracking = require("./DdBabelInteractionTracking"); var _DdEventsInterceptor = require("./DdEventsInterceptor"); var _NoOpEventsInterceptor = require("./NoOpEventsInterceptor"); var _ShallowObjectEqualityChecker = require("./ShallowObjectEqualityChecker"); var _getJsxRuntime = require("./getJsxRuntime"); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } /* * Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0. * This product includes software developed at Datadog (https://www.datadoghq.com/). * Copyright 2016-Present Datadog, Inc. */ /** * Provides RUM auto-instrumentation feature to track user interaction as RUM events. * For now we are only covering the "onPress" events. */ class DdRumUserInteractionTracking { static isTracking = false; static eventsInterceptor = new _NoOpEventsInterceptor.NoOpEventsInterceptor(); static originalCreateElement = _react.default.createElement; static originalMemo = _react.default.memo; static originalJsx = null; static originalDevJsx = null; static patchCreateElementFunction = (originalFunction, [element, props, ...rest]) => { if (props && typeof props.onPress === 'function') { const originalOnPress = props // eslint-disable-next-line @typescript-eslint/ban-types .onPress; props.onPress = (...args) => { DdRumUserInteractionTracking.eventsInterceptor.interceptOnPress(...args); return originalOnPress(...args); }; // we store the original onPress prop so we can keep memoization working props.__DATADOG_INTERNAL_ORIGINAL_ON_PRESS__ = originalOnPress; } return originalFunction(element, props, ...rest); }; /** * Starts tracking user interactions and sends a RUM Action event every time a new interaction was detected. * Please note that we are only considering as valid - for - tracking only the user interactions that have * a visible output (either an UI state change or a Resource request) */ static startTracking(options) { // extra safety to avoid wrapping more than 1 time this function if (DdRumUserInteractionTracking.isTracking) { _InternalLog.InternalLog.log('Datadog SDK is already tracking interactions', _SdkVerbosity.SdkVerbosity.WARN); return; } _DdSdk.DdSdk?.sendTelemetryLog(_constants.BABEL_PLUGIN_TELEMETRY, _DdBabelInteractionTracking.DdBabelInteractionTracking.getTelemetryConfig(), { onlyOnce: true }); DdRumUserInteractionTracking.eventsInterceptor = new _DdEventsInterceptor.DdEventsInterceptor(options); const original = _react.default.createElement; _react.default.createElement = (...args) => { return this.patchCreateElementFunction(original, args); }; try { const [jsxRuntime, jsxDevRuntime] = (0, _getJsxRuntime.getJsxRuntimes)(); const originalJsx = jsxRuntime?.jsx; const originalDevJsx = jsxDevRuntime?.jsxDEV; this.originalJsx = originalJsx; this.originalDevJsx = originalDevJsx; if (originalJsx) { jsxRuntime.jsx = (...args) => { return this.patchCreateElementFunction(originalJsx, args); }; } if (originalDevJsx) { jsxRuntime.jsxDEV = (...args) => { return this.patchCreateElementFunction(originalDevJsx, args); }; } } catch (e) { _DdSdk.DdSdk.telemetryDebug((0, _errorUtils.getErrorMessage)(e)); } const originalMemo = _react.default.memo; _react.default.memo = (component, propsAreEqual) => { return originalMemo(component, (prev, next) => { if (!next.onPress || !prev.onPress) { return propsAreEqual ? propsAreEqual(prev, next) : (0, _ShallowObjectEqualityChecker.areObjectShallowEqual)(prev, next); } // we replace "our" onPress from the props by the original for comparison const { onPress: _prevOnPress, ...partialPrevProps } = prev; const prevProps = { ...partialPrevProps, onPress: prev.__DATADOG_INTERNAL_ORIGINAL_ON_PRESS__ }; const { onPress: _nextOnPress, ...partialNextProps } = next; const nextProps = { ...partialNextProps, onPress: next.__DATADOG_INTERNAL_ORIGINAL_ON_PRESS__ }; // if no comparison function is provided we do shallow comparison return propsAreEqual ? propsAreEqual(prevProps, nextProps) : (0, _ShallowObjectEqualityChecker.areObjectShallowEqual)(nextProps, prevProps); }); }; DdRumUserInteractionTracking.isTracking = true; _InternalLog.InternalLog.log('Datadog SDK is tracking interactions', _SdkVerbosity.SdkVerbosity.INFO); } static stopTracking() { _react.default.createElement = this.originalCreateElement; _react.default.memo = this.originalMemo; DdRumUserInteractionTracking.isTracking = false; if (this.originalJsx || this.originalDevJsx) { const [jsxRuntime, jsxDevRuntime] = (0, _getJsxRuntime.getJsxRuntimes)(); jsxRuntime.jsx = this.originalJsx; jsxDevRuntime.jsxDEV = this.originalDevJsx; this.originalJsx = null; this.originalDevJsx = null; } } } exports.DdRumUserInteractionTracking = DdRumUserInteractionTracking; //# sourceMappingURL=DdRumUserInteractionTracking.js.map