@datadog/mobile-react-native
Version:
A client-side React Native module to interact with Datadog
133 lines (129 loc) • 5.83 kB
JavaScript
;
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