@dynatrace/react-native-plugin 2.343.1 → 2.345.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/README.md +638 -660
  2. package/android/build.gradle +6 -2
  3. package/files/plugin-runtime.gradle +17 -33
  4. package/files/plugin.gradle +1 -1
  5. package/instrumentation/BabelPluginDynatrace.js +1 -1
  6. package/instrumentation/libs/UserInteraction.js +20 -6
  7. package/instrumentation/libs/react-navigation/ReactNavigation.js +14 -58
  8. package/instrumentation/libs/withOnPressMonitoring.js +3 -54
  9. package/internal.d.ts +1 -0
  10. package/internal.js +3 -1
  11. package/ios/DynatraceRNBridge.mm +9 -0
  12. package/lib/core/configuration/ConfigurationHandler.js +0 -21
  13. package/lib/dynatrace-reporter.js +1 -30
  14. package/lib/dynatrace-transformer.js +6 -34
  15. package/lib/next/configuration/INativeRuntimeConfiguration.js +0 -1
  16. package/lib/next/configuration/RuntimeConfigurationObserver.js +1 -6
  17. package/lib/next/navigation/NavigationTracker.js +93 -0
  18. package/lib/next/navigation/useNavigationTracking.js +54 -0
  19. package/package.json +9 -21
  20. package/public.js +3 -1
  21. package/react-native-dynatrace.podspec +1 -1
  22. package/scripts/Android.js +1 -20
  23. package/scripts/Config.js +0 -4
  24. package/scripts/Deprecations.js +18 -0
  25. package/scripts/Install.js +13 -0
  26. package/scripts/PathsConstants.js +0 -4
  27. package/scripts/Uninstall.js +0 -15
  28. package/scripts/core/InstrumentCall.js +2 -3
  29. package/scripts/util/DeprecationReport.js +24 -0
  30. package/types.d.ts +212 -10
  31. package/instrumentation/DynatraceInstrumentation.js +0 -1
  32. package/instrumentation/libs/community/Picker.InstrInfo.js +0 -20
  33. package/instrumentation/libs/community/gesture-handler/Touchables.InstrInfo.js +0 -25
  34. package/instrumentation/libs/react-native/RefreshControl.InstrInfo.js +0 -12
  35. package/instrumentation/libs/react-native/Switch.InstrInfo.js +0 -12
  36. package/instrumentation/libs/react-native/Touchables.InstrInfo.js +0 -25
  37. package/instrumentation/model/Reference.js +0 -2
  38. package/instrumentation/parser/Babel.js +0 -60
  39. package/instrumentation/parser/ParserUtil.js +0 -11
  40. package/lib/features/ui-interaction/Config.js +0 -42
  41. package/lib/features/ui-interaction/IUserInteractionEvent.js +0 -16
  42. package/lib/features/ui-interaction/Plugin.Fragment.Test.js +0 -170
  43. package/lib/features/ui-interaction/Plugin.js +0 -289
  44. package/lib/features/ui-interaction/RootDetection.js +0 -51
  45. package/lib/features/ui-interaction/RootWrapper.js +0 -236
  46. package/lib/features/ui-interaction/Run.js +0 -38
  47. package/lib/features/ui-interaction/Runtime.js +0 -843
  48. package/lib/features/ui-interaction/TouchMetaResolver.js +0 -493
  49. package/lib/features/ui-interaction/Types.js +0 -14
  50. package/lib/metro/getSourceMapInfo.js +0 -26
  51. package/scripts/LineOffsetAnalyze.js +0 -25
  52. package/scripts/core/LineOffsetAnalyzeCall.js +0 -165
  53. package/scripts/util/SourceMapUtil.js +0 -68
@@ -29,7 +29,9 @@ buildscript {
29
29
  }
30
30
 
31
31
  apply plugin: 'com.android.library'
32
- apply plugin: 'org.jetbrains.kotlin.android'
32
+ if (!project.extensions.findByName('kotlin')) {
33
+ apply plugin: 'org.jetbrains.kotlin.android'
34
+ }
33
35
 
34
36
  if (isNewArchitectureEnabled()) {
35
37
  apply plugin: 'com.facebook.react'
@@ -68,8 +70,10 @@ android {
68
70
  main {
69
71
  if (isNewArchitectureEnabled()) {
70
72
  java.srcDirs += ['src/new']
73
+ kotlin.srcDirs += ['src/new']
71
74
  } else {
72
75
  java.srcDirs += ['src/old']
76
+ kotlin.srcDirs += ['src/old']
73
77
  }
74
78
  }
75
79
  }
@@ -81,7 +85,7 @@ repositories {
81
85
  }
82
86
 
83
87
  dependencies {
84
- implementation 'com.dynatrace.agent:agent-android:8.343.1.1038'
88
+ implementation 'com.dynatrace.agent:agent-android:8.345.1.1003'
85
89
  implementation "com.facebook.react:react-native:${safeExtGet('reactNative', '+')}"
86
90
  }
87
91
 
@@ -1,33 +1,17 @@
1
- import org.gradle.process.ExecOperations
2
- import javax.inject.Inject
3
-
4
- abstract class RunLineOffsetTask extends DefaultTask {
5
- @Internal
6
- abstract DirectoryProperty getWorkingDirectory()
7
-
8
- @Inject
9
- abstract ExecOperations getExecOperations()
10
-
11
- @TaskAction
12
- void run() {
13
- execOperations.exec {
14
- workingDir workingDirectory.get().asFile
15
- if (System.getProperty('os.name').toLowerCase().contains('windows')) {
16
- commandLine 'cmd', '/c', 'npx', 'lineOffsetDynatrace'
17
- } else {
18
- commandLine 'npx', 'lineOffsetDynatrace'
19
- }
20
- }
21
- }
22
- }
23
-
24
- android.applicationVariants.all { variant ->
25
- if (variant.buildType.name == "release") {
26
- def lineOffsetTask = tasks.register("runLineOffset${variant.name.capitalize()}", RunLineOffsetTask) {
27
- workingDirectory = layout.projectDirectory
28
- }
29
- variant.mergeAssetsProvider.configure { task ->
30
- task.dependsOn(lineOffsetTask)
31
- }
32
- }
33
- }
1
+ // Intentionally left empty. DO NOT DELETE THIS FILE.
2
+ //
3
+ // Apps instrumented with an older version of this plugin have the following
4
+ // line hard-coded in their android/app/build.gradle:
5
+ //
6
+ // apply from: "../../node_modules/@dynatrace/react-native-plugin/files/plugin-runtime.gradle"
7
+ //
8
+ // That line lives in the customer's own build.gradle, so we cannot reliably
9
+ // remove it on upgrade. If this file were missing, the `apply from:` above
10
+ // would fail the Gradle build for every app that still has that line.
11
+ //
12
+ // Previously this script registered a release-build Gradle task that ran
13
+ // `npx lineOffsetDynatrace` for line-offset analysis. That is no longer needed:
14
+ // auto-instrumentation moved to a Babel plugin and capturing moved to native,
15
+ // so the script is now a no-op kept purely for backward compatibility.
16
+ //
17
+ // New installs no longer add the `apply from:` line at all.
@@ -1,4 +1,4 @@
1
1
  // TEMPLATE: plugin-gradle.template
2
2
  dependencies {
3
- classpath 'com.dynatrace.tools.android:gradle-plugin:8.343.1.1038'
3
+ classpath 'com.dynatrace.tools.android:gradle-plugin:8.345.1.1003'
4
4
  }
@@ -1 +1 @@
1
- var _templateObject,_templateObject2,_templateObject3,_templateObject4,_templateObject5,_templateObject6,_interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault"),_taggedTemplateLiteral2=_interopRequireDefault(require("@babel/runtime/helpers/taggedTemplateLiteral"));function _createForOfIteratorHelper(e,t){var n,r,a,i,o="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(o)return a=!(r=!0),{s:function(){o=o.call(e)},n:function(){var e=o.next();return r=e.done,e},e:function(e){a=!0,n=e},f:function(){try{r||null==o.return||o.return()}finally{if(a)throw n}}};if(Array.isArray(e)||(o=_unsupportedIterableToArray(e))||t&&e&&"number"==typeof e.length)return o&&(e=o),i=0,{s:t=function(){},n:function(){return i>=e.length?{done:!0}:{done:!1,value:e[i++]}},e:function(e){throw e},f:t};throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _unsupportedIterableToArray(e,t){var n;if(e)return"string"==typeof e?_arrayLikeToArray(e,t):"Map"===(n="Object"===(n={}.toString.call(e).slice(8,-1))&&e.constructor?e.constructor.name:n)||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?_arrayLikeToArray(e,t):void 0}function _arrayLikeToArray(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n<t;n++)r[n]=e[n];return r}Object.defineProperty(exports,"__esModule",{value:!0});var reactOptions,fspath=require("path"),fs=require("fs"),core_1=require("@babel/core"),generator_1=require("@babel/generator"),PathsConstants_1=require("../scripts/PathsConstants"),Config_1=require("../scripts/Config"),GetValuesFromPackage_1=require("../lib/core/util/GetValuesFromPackage"),Types_1=require("./model/Types"),INSTRUMENTATION_LIBS="@dynatrace/react-native-plugin/instrumentation/libs",COMPONENTS_EXCLUDED_FROM_UIA=new Set(["Fragment","React.Fragment"]),hasJSX=function(e){var t=!1;return e.traverse({"JSXElement|JSXFragment":function(){t=!0}}),t},instrumentUserInteraction=function(e){e.traverse({"FunctionDeclaration|ObjectMethod":function(e){var e=e.node,t=core_1.types.isFunctionDeclaration(e)?e.id:e.key;core_1.types.isIdentifier(t,{name:"registerComponent"})&&(t="".concat(INSTRUMENTATION_LIBS,"/UserInteraction"),e.body.body.unshift(core_1.template.statement('componentProvider = require("'.concat(t,'").wrapProvider(componentProvider);'))()))}})},instrumentAppRegistry=function(e){e.traverse({"FunctionDeclaration|ObjectMethod":function(e){var e=e.node,t=core_1.types.isFunctionDeclaration(e)?e.id:e.key;core_1.types.isIdentifier(t,{name:"runApplication"})&&e.body.body.unshift(core_1.template.statement(_templateObject=_templateObject||(0,_taggedTemplateLiteral2.default)(['require("@dynatrace/react-native-plugin").ApplicationHandler.startup();']))())}})},instrumentExceptionsManager=function(e){var t,n=null!=(t=null==(t=null==reactOptions?void 0:reactOptions.errorHandler)?void 0:t.reportFatalErrorAsCrash)&&t,r=(null==reactOptions?void 0:reactOptions.autoStart)&&(null==(t=null==reactOptions?void 0:reactOptions.errorHandler)?void 0:t.enabled);e.traverse({FunctionDeclaration:function(e){var t;core_1.types.isIdentifier(e.node.id,{name:"handleException"})&&(t=core_1.template.statement(_templateObject2=_templateObject2||(0,_taggedTemplateLiteral2.default)(['\n setTimeout(() => BODY, require("@dynatrace/react-native-plugin/lib/core/ErrorHandler")\n .reportErrorToDynatrace(e, isFatal, CRASH, AUTO));\n ']))({BODY:core_1.types.cloneNode(e.node.body),CRASH:core_1.types.booleanLiteral(n),AUTO:core_1.types.booleanLiteral(!!r)}),e.node.body.body=[t])}})},instrumentCssInterop=function(e){e.traverse({CallExpression:function(e){core_1.types.isIdentifier(e.node.callee,{name:"require"})&&(e=e.node.arguments[0],core_1.types.isStringLiteral(e))&&("react/jsx-runtime"===e.value?e.value="@dynatrace/react-native-plugin/jsx-runtime":"react/jsx-dev-runtime"===e.value&&(e.value="@dynatrace/react-native-plugin/jsx-dev-runtime"))}})},instrumentNavigation=function(e){e.traverse({VariableDeclarator:function(e){var t;core_1.types.isIdentifier(e.node.id,{name:"getRootState"})&&(t=core_1.template.statement(_templateObject3=_templateObject3||(0,_taggedTemplateLiteral2.default)(["\n require(PATH).monitorNavigation(getRootState);\n "]))({PATH:core_1.types.stringLiteral("".concat(INSTRUMENTATION_LIBS,"/react-navigation/ReactNavigation"))}),e.parentPath.insertAfter(t))}})},instrumentReactCreateElement=function(e){var t=core_1.template.statement(_templateObject4=_templateObject4||(0,_taggedTemplateLiteral2.default)(["\n require(PATH).instrumentCreateElement(module.exports);\n "]))({PATH:core_1.types.stringLiteral("@dynatrace/react-native-plugin/instrumentation/jsx/ElementHelper")});e.pushContainer("body",t)},instrumentComponents=function(e,n){e.traverse({FunctionDeclaration:function(e){var t;hasJSX(e)&&(t=e.node,core_1.types.isIdentifier(t.id))&&null!=(e=e.getStatementParent())&&e.insertAfter(n(t.id.name,Types_1.Types.FunctionalComponent))},ClassDeclaration:function(e){var t;hasJSX(e)&&(t=e.node,core_1.types.isIdentifier(t.id))&&null!=(e=e.getStatementParent())&&e.insertAfter(n(t.id.name,Types_1.Types.ClassComponent))},"FunctionExpression|ArrowFunctionExpression":function(e){var t;hasJSX(e)&&(t=e.parent,void 0!==(t=core_1.types.isVariableDeclarator(t)&&core_1.types.isIdentifier(t.id)?t.id.name:core_1.types.isAssignmentExpression(t)&&core_1.types.isIdentifier(t.left)?t.left.name:void 0))&&null!=(e=e.getStatementParent())&&e.insertAfter(n(t,Types_1.Types.FunctionalComponent))}})},instrumentLifecycle=function(e){instrumentComponents(e,function(e,t){return core_1.template.statement(_templateObject5=_templateObject5||(0,_taggedTemplateLiteral2.default)(["NAME._dtInfo = { type: TYPE, name: 'NAME_STR' }"]))({NAME:core_1.types.identifier(e),TYPE:core_1.types.numericLiteral(t),NAME_STR:core_1.types.stringLiteral(e)})})},instrumentComponentNames=function(e){instrumentComponents(e,function(e){return core_1.template.statement(_templateObject6=_templateObject6||(0,_taggedTemplateLiteral2.default)(["NAME.dtName = 'NAME_STR'"]))({NAME:core_1.types.identifier(e),NAME_STR:core_1.types.stringLiteral(e)})})},instrumentInput=function(e){var u=new Map([["react-native",{proxy:"".concat(INSTRUMENTATION_LIBS,"/react-native/"),components:new Set(["TouchableHighlight","TouchableNativeFeedback","TouchableOpacity","TouchableWithoutFeedback","Button","RefreshControl","Text","Pressable","Switch"])}],["react-native-gesture-handler",{proxy:"".concat(INSTRUMENTATION_LIBS,"/community/gesture-handler/"),components:new Set(["TouchableHighlight","TouchableNativeFeedback","TouchableOpacity","TouchableWithoutFeedback","RectButton","BorderlessButton","BaseButton"])}],["@react-native-picker/picker",{proxy:"".concat(INSTRUMENTATION_LIBS,"/community/Picker"),components:new Set(["Picker","PickerIOS"])}]]);e.traverse({ImportDeclaration:function(e){if(void 0===e.node.processed){var t=e.node.source;if(u.has(t.value)){var r=u.get(t.value),n=e.node.specifiers,a=[],i=[];if(n.forEach(function(e,t){var n;core_1.types.isImportSpecifier(e)&&(n=core_1.types.isIdentifier(e.imported)?e.imported.name:e.imported.value,r.components.has(n)||(a.push(e),i.push(t)))}),a.length!==n.length){var o,s=_createForOfIteratorHelper([].concat(i).reverse());try{for(s.s();!(o=s.n()).done;){var c=o.value;n.splice(c,1)}}catch(e){s.e(e)}finally{s.f()}0<a.length&&((t=core_1.types.importDeclaration(a,core_1.types.stringLiteral(t.value))).processed=!0,e.insertBefore(t)),e.node.source=core_1.types.stringLiteral(r.proxy),e.scope.crawl()}}}},CallExpression:function(e){core_1.types.isIdentifier(e.node.callee,{name:"require"})&&(e=e.node.arguments[0],core_1.types.isStringLiteral(e))&&u.has(e.value)&&(e.value=u.get(e.value).proxy)}})},instrumentJsxNames=function(e){e.traverse({JSXOpeningElement:function(e){var t=e.node.name,t=core_1.types.isJSXIdentifier(t)?t.name:core_1.types.isJSXMemberExpression(t)?(0,generator_1.default)(t).code:void 0;t&&!COMPONENTS_EXCLUDED_FROM_UIA.has(t)&&e.node.attributes.unshift(core_1.types.jsxAttribute(core_1.types.jsxIdentifier("dtName"),core_1.types.stringLiteral(t)))}})},instrumentConfigurationPreset=function(e){var t,n=(0,GetValuesFromPackage_1.getHostAppBundleInfo)(PathsConstants_1.default.getPackageJsonFile()),r={getLifecycleUpdate:reactOptions.lifecycle.includeUpdate,getLogLevel:reactOptions.debug?0:1,getBundleName:null!=(t=reactOptions.bundleName)?t:null==n?void 0:n.name,getBundleVersion:null!=(t=reactOptions.bundleVersion)?t:null==n?void 0:n.version,getActionNamePrivacy:reactOptions.input.actionNamePrivacy,getActionNamePreference:reactOptions.input.actionNamePreference,getActionNameAlgorithm:reactOptions.input.actionNameAlgorithm,isErrorHandlerEnabled:reactOptions.errorHandler.enabled,isReportFatalErrorAsCrash:reactOptions.errorHandler.reportFatalErrorAsCrash,isAutoStartupEnabled:reactOptions.autoStart};e.traverse({ClassMethod:function(e){var t;core_1.types.isIdentifier(e.node.key)&&void 0!==(t=r[e.node.key.name])&&(e=e.node.body.body[0],core_1.types.isReturnStatement(e))&&(e.argument=core_1.types.valueToNode(t))}})},createFilenameMatcher=function(r){return{isModule:function(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];return t.some(function(e){return r.includes(fspath.join("node_modules",e)+fspath.sep)})},isFile:function(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];return t.some(function(e){return r.endsWith(e)})}}},captureOriginalCode=function(e){return!0!==reactOptions.debugBabelPlugin?"":(0,generator_1.default)(e.node).code},isConfigurationPresetTarget=function(e){return e.isModule("@dynatrace")&&e.isFile("ConfigurationPreset.js")},isAppRegistryTarget=function(e){return e.isModule("react-native")&&e.isFile("AppRegistry.js","AppRegistryImpl.js")},isExceptionsManagerTarget=function(e){return e.isModule("react-native")&&e.isFile("ExceptionsManager.js")},isCssInteropTarget=function(e){return e.isModule("react-native-css-interop")&&e.isFile("jsx-runtime.js","jsx-dev-runtime.js")},isNavigationTarget=function(e){return reactOptions.navigation.enabled&&e.isModule("@react-navigation")&&e.isFile("BaseNavigationContainer.js","BaseNavigationContainer.tsx")},isReactIndexTarget=function(e){return e.isModule("react")&&e.isFile("index.js")},shouldInstrumentLifecycleForFile=function(e,t,n){var r,a,n=n.isModule("react-native")&&n.isFile("renderApplication.js");return(null==(a=null==(r=reactOptions.lifecycle)?void 0:r.instrument)?void 0:a.call(r,t))&&(!t.includes("node_modules")||n)&&hasJSX(e)},shouldInstrumentInputForFile=function(e,t){var n,r,t=t.isModule("@react-navigation","react-native-drawer-layout");return(null==(r=null==(n=reactOptions.input)?void 0:n.instrument)?void 0:r.call(n,e))&&(!e.includes("node_modules")||t)},shouldInstrumentUserInteractionNames=function(e){return reactOptions.userInteraction&&!e.includes("node_modules")},instrumentByModuleAndFile=function(e,t,n){isConfigurationPresetTarget(n)&&instrumentConfigurationPreset(e),isAppRegistryTarget(n)&&(reactOptions.autoStart&&instrumentAppRegistry(e),reactOptions.userInteraction)&&instrumentUserInteraction(e),isExceptionsManagerTarget(n)&&instrumentExceptionsManager(e),isCssInteropTarget(n)&&instrumentCssInterop(e),isNavigationTarget(n)&&instrumentNavigation(e),isReactIndexTarget(n)&&instrumentReactCreateElement(e),shouldInstrumentLifecycleForFile(e,t,n)&&instrumentLifecycle(e),shouldInstrumentInputForFile(t,n)&&instrumentInput(e),shouldInstrumentUserInteractionNames(t)&&(instrumentJsxNames(e),instrumentComponentNames(e))},writeDebugOutputIfChanged=function(e,t,n,r){!0===reactOptions.debugBabelPlugin&&(e=(0,generator_1.default)(e.node).code)!==r&&(r=fspath.join(PathsConstants_1.default.getBuildPath(),fspath.relative(PathsConstants_1.default.getApplicationPath(),n)+".dtx"),fs.mkdirSync(fspath.dirname(r),{recursive:!0}),fs.writeFileSync(r,e),t.set("fileDidChange",!0))};exports.default=function(){return{visitor:{Program:function(e,t){reactOptions=(0,Config_1.readConfigDefault)().react;var n,r,a=t.filename;void 0!==a&&(n=createFilenameMatcher(a),r=captureOriginalCode(e),instrumentByModuleAndFile(e,a,n),writeDebugOutputIfChanged(e,t,a,r))}},post:function(e){var t;!0===reactOptions.debugBabelPlugin&&!0===this.get("fileDidChange")&&(t=(0,generator_1.default)(e.ast).code,e=fspath.join(PathsConstants_1.default.getBuildPath(),fspath.relative(PathsConstants_1.default.getApplicationPath(),e.opts.filename)+".dtx.downstream"),fs.mkdirSync(fspath.dirname(e),{recursive:!0}),fs.writeFileSync(e,t))}}};
1
+ var _templateObject,_templateObject2,_templateObject3,_templateObject4,_templateObject5,_templateObject6,_interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault"),_taggedTemplateLiteral2=_interopRequireDefault(require("@babel/runtime/helpers/taggedTemplateLiteral"));function _createForOfIteratorHelper(e,t){var n,r,a,i,o="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(o)return a=!(r=!0),{s:function(){o=o.call(e)},n:function(){var e=o.next();return r=e.done,e},e:function(e){a=!0,n=e},f:function(){try{r||null==o.return||o.return()}finally{if(a)throw n}}};if(Array.isArray(e)||(o=_unsupportedIterableToArray(e))||t&&e&&"number"==typeof e.length)return o&&(e=o),i=0,{s:t=function(){},n:function(){return i>=e.length?{done:!0}:{done:!1,value:e[i++]}},e:function(e){throw e},f:t};throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _unsupportedIterableToArray(e,t){var n;if(e)return"string"==typeof e?_arrayLikeToArray(e,t):"Map"===(n="Object"===(n={}.toString.call(e).slice(8,-1))&&e.constructor?e.constructor.name:n)||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?_arrayLikeToArray(e,t):void 0}function _arrayLikeToArray(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n<t;n++)r[n]=e[n];return r}Object.defineProperty(exports,"__esModule",{value:!0});var reactOptions,fspath=require("path"),fs=require("fs"),core_1=require("@babel/core"),generator_1=require("@babel/generator"),PathsConstants_1=require("../scripts/PathsConstants"),Config_1=require("../scripts/Config"),GetValuesFromPackage_1=require("../lib/core/util/GetValuesFromPackage"),Types_1=require("./model/Types"),INSTRUMENTATION_LIBS="@dynatrace/react-native-plugin/instrumentation/libs",COMPONENTS_EXCLUDED_FROM_UIA=new Set(["Fragment","React.Fragment"]),hasJSX=function(e){var t=!1;return e.traverse({"JSXElement|JSXFragment":function(){t=!0}}),t},instrumentUserInteraction=function(e){e.traverse({"FunctionDeclaration|ObjectMethod":function(e){var e=e.node,t=core_1.types.isFunctionDeclaration(e)?e.id:e.key;core_1.types.isIdentifier(t,{name:"registerComponent"})&&(t="".concat(INSTRUMENTATION_LIBS,"/UserInteraction"),e.body.body.unshift(core_1.template.statement('componentProvider = require("'.concat(t,'").wrapProvider(componentProvider);'))()))}})},instrumentAppRegistry=function(e){e.traverse({"FunctionDeclaration|ObjectMethod":function(e){var e=e.node,t=core_1.types.isFunctionDeclaration(e)?e.id:e.key;core_1.types.isIdentifier(t,{name:"runApplication"})&&e.body.body.unshift(core_1.template.statement(_templateObject=_templateObject||(0,_taggedTemplateLiteral2.default)(['require("@dynatrace/react-native-plugin").ApplicationHandler.startup();']))())}})},instrumentExceptionsManager=function(e){var t,n=null!=(t=null==(t=null==reactOptions?void 0:reactOptions.errorHandler)?void 0:t.reportFatalErrorAsCrash)&&t,r=(null==reactOptions?void 0:reactOptions.autoStart)&&(null==(t=null==reactOptions?void 0:reactOptions.errorHandler)?void 0:t.enabled);e.traverse({FunctionDeclaration:function(e){var t;core_1.types.isIdentifier(e.node.id,{name:"handleException"})&&(t=core_1.template.statement(_templateObject2=_templateObject2||(0,_taggedTemplateLiteral2.default)(['\n setTimeout(() => BODY, require("@dynatrace/react-native-plugin/lib/core/ErrorHandler")\n .reportErrorToDynatrace(e, isFatal, CRASH, AUTO));\n ']))({BODY:core_1.types.cloneNode(e.node.body),CRASH:core_1.types.booleanLiteral(n),AUTO:core_1.types.booleanLiteral(!!r)}),e.node.body.body=[t])}})},instrumentCssInterop=function(e){e.traverse({CallExpression:function(e){core_1.types.isIdentifier(e.node.callee,{name:"require"})&&(e=e.node.arguments[0],core_1.types.isStringLiteral(e))&&("react/jsx-runtime"===e.value?e.value="@dynatrace/react-native-plugin/jsx-runtime":"react/jsx-dev-runtime"===e.value&&(e.value="@dynatrace/react-native-plugin/jsx-dev-runtime"))}})},instrumentNavigation=function(e){e.traverse({VariableDeclarator:function(e){var t;core_1.types.isIdentifier(e.node.id,{name:"getRootState"})&&(t=core_1.template.statement(_templateObject3=_templateObject3||(0,_taggedTemplateLiteral2.default)(["\n require(PATH).useNavigationMonitor(getRootState);\n "]))({PATH:core_1.types.stringLiteral("".concat(INSTRUMENTATION_LIBS,"/react-navigation/ReactNavigation"))}),e.parentPath.insertAfter(t))}})},instrumentReactCreateElement=function(e){var t=core_1.template.statement(_templateObject4=_templateObject4||(0,_taggedTemplateLiteral2.default)(["\n require(PATH).instrumentCreateElement(module.exports);\n "]))({PATH:core_1.types.stringLiteral("@dynatrace/react-native-plugin/instrumentation/jsx/ElementHelper")});e.pushContainer("body",t)},instrumentComponents=function(e,n){e.traverse({FunctionDeclaration:function(e){var t;hasJSX(e)&&(t=e.node,core_1.types.isIdentifier(t.id))&&null!=(e=e.getStatementParent())&&e.insertAfter(n(t.id.name,Types_1.Types.FunctionalComponent))},ClassDeclaration:function(e){var t;hasJSX(e)&&(t=e.node,core_1.types.isIdentifier(t.id))&&null!=(e=e.getStatementParent())&&e.insertAfter(n(t.id.name,Types_1.Types.ClassComponent))},"FunctionExpression|ArrowFunctionExpression":function(e){var t;hasJSX(e)&&(t=e.parent,void 0!==(t=core_1.types.isVariableDeclarator(t)&&core_1.types.isIdentifier(t.id)?t.id.name:core_1.types.isAssignmentExpression(t)&&core_1.types.isIdentifier(t.left)?t.left.name:void 0))&&null!=(e=e.getStatementParent())&&e.insertAfter(n(t,Types_1.Types.FunctionalComponent))}})},instrumentLifecycle=function(e){instrumentComponents(e,function(e,t){return core_1.template.statement(_templateObject5=_templateObject5||(0,_taggedTemplateLiteral2.default)(["NAME._dtInfo = { type: TYPE, name: 'NAME_STR' }"]))({NAME:core_1.types.identifier(e),TYPE:core_1.types.numericLiteral(t),NAME_STR:core_1.types.stringLiteral(e)})})},instrumentComponentNames=function(e){instrumentComponents(e,function(e){return core_1.template.statement(_templateObject6=_templateObject6||(0,_taggedTemplateLiteral2.default)(["NAME.dtName = 'NAME_STR'"]))({NAME:core_1.types.identifier(e),NAME_STR:core_1.types.stringLiteral(e)})})},instrumentInput=function(e){var u=new Map([["react-native",{proxy:"".concat(INSTRUMENTATION_LIBS,"/react-native/"),components:new Set(["TouchableHighlight","TouchableNativeFeedback","TouchableOpacity","TouchableWithoutFeedback","Button","RefreshControl","Text","Pressable","Switch"])}],["react-native-gesture-handler",{proxy:"".concat(INSTRUMENTATION_LIBS,"/community/gesture-handler/"),components:new Set(["TouchableHighlight","TouchableNativeFeedback","TouchableOpacity","TouchableWithoutFeedback","RectButton","BorderlessButton","BaseButton"])}],["@react-native-picker/picker",{proxy:"".concat(INSTRUMENTATION_LIBS,"/community/Picker"),components:new Set(["Picker","PickerIOS"])}]]);e.traverse({ImportDeclaration:function(e){if(void 0===e.node.processed){var t=e.node.source;if(u.has(t.value)){var r=u.get(t.value),n=e.node.specifiers,a=[],i=[];if(n.forEach(function(e,t){var n;core_1.types.isImportSpecifier(e)&&(n=core_1.types.isIdentifier(e.imported)?e.imported.name:e.imported.value,r.components.has(n)||(a.push(e),i.push(t)))}),a.length!==n.length){var o,s=_createForOfIteratorHelper([].concat(i).reverse());try{for(s.s();!(o=s.n()).done;){var c=o.value;n.splice(c,1)}}catch(e){s.e(e)}finally{s.f()}0<a.length&&((t=core_1.types.importDeclaration(a,core_1.types.stringLiteral(t.value))).processed=!0,e.insertBefore(t)),e.node.source=core_1.types.stringLiteral(r.proxy),e.scope.crawl()}}}},CallExpression:function(e){core_1.types.isIdentifier(e.node.callee,{name:"require"})&&(e=e.node.arguments[0],core_1.types.isStringLiteral(e))&&u.has(e.value)&&(e.value=u.get(e.value).proxy)}})},instrumentJsxNames=function(e){e.traverse({JSXOpeningElement:function(e){var t=e.node.name,t=core_1.types.isJSXIdentifier(t)?t.name:core_1.types.isJSXMemberExpression(t)?(0,generator_1.default)(t).code:void 0;t&&!COMPONENTS_EXCLUDED_FROM_UIA.has(t)&&e.node.attributes.unshift(core_1.types.jsxAttribute(core_1.types.jsxIdentifier("dtName"),core_1.types.stringLiteral(t)))}})},instrumentConfigurationPreset=function(e){var t,n=(0,GetValuesFromPackage_1.getHostAppBundleInfo)(PathsConstants_1.default.getPackageJsonFile()),r={getLifecycleUpdate:reactOptions.lifecycle.includeUpdate,getLogLevel:reactOptions.debug?0:1,getBundleName:null!=(t=reactOptions.bundleName)?t:null==n?void 0:n.name,getBundleVersion:null!=(t=reactOptions.bundleVersion)?t:null==n?void 0:n.version,getActionNamePrivacy:reactOptions.input.actionNamePrivacy,getActionNamePreference:reactOptions.input.actionNamePreference,getActionNameAlgorithm:reactOptions.input.actionNameAlgorithm,isErrorHandlerEnabled:reactOptions.errorHandler.enabled,isReportFatalErrorAsCrash:reactOptions.errorHandler.reportFatalErrorAsCrash,isAutoStartupEnabled:reactOptions.autoStart};e.traverse({ClassMethod:function(e){var t;core_1.types.isIdentifier(e.node.key)&&void 0!==(t=r[e.node.key.name])&&(e=e.node.body.body[0],core_1.types.isReturnStatement(e))&&(e.argument=core_1.types.valueToNode(t))}})},createFilenameMatcher=function(r){return{isModule:function(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];return t.some(function(e){return r.includes(fspath.join("node_modules",e)+fspath.sep)})},isFile:function(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];return t.some(function(e){return r.endsWith(e)})}}},captureOriginalCode=function(e){return!0!==reactOptions.debugBabelPlugin?"":(0,generator_1.default)(e.node).code},isConfigurationPresetTarget=function(e){return e.isModule("@dynatrace")&&e.isFile("ConfigurationPreset.js")},isAppRegistryTarget=function(e){return e.isModule("react-native")&&e.isFile("AppRegistry.js","AppRegistryImpl.js")},isExceptionsManagerTarget=function(e){return e.isModule("react-native")&&e.isFile("ExceptionsManager.js")},isCssInteropTarget=function(e){return e.isModule("react-native-css-interop")&&e.isFile("jsx-runtime.js","jsx-dev-runtime.js")},isNavigationTarget=function(e){return reactOptions.navigation.enabled&&e.isModule("@react-navigation")&&e.isFile("BaseNavigationContainer.js","BaseNavigationContainer.tsx")},isReactIndexTarget=function(e){return e.isModule("react")&&e.isFile("index.js")},shouldInstrumentLifecycleForFile=function(e,t,n){var r,a,n=n.isModule("react-native")&&n.isFile("renderApplication.js");return(null==(a=null==(r=reactOptions.lifecycle)?void 0:r.instrument)?void 0:a.call(r,t))&&(!t.includes("node_modules")||n)&&hasJSX(e)},shouldInstrumentInputForFile=function(e,t){var n,r,t=t.isModule("@react-navigation","react-native-drawer-layout");return(null==(r=null==(n=reactOptions.input)?void 0:n.instrument)?void 0:r.call(n,e))&&(!e.includes("node_modules")||t)},shouldInstrumentUserInteractionNames=function(e){return reactOptions.userInteraction&&!e.includes("node_modules")},instrumentByModuleAndFile=function(e,t,n){isConfigurationPresetTarget(n)&&instrumentConfigurationPreset(e),isAppRegistryTarget(n)&&(reactOptions.autoStart&&instrumentAppRegistry(e),reactOptions.userInteraction)&&instrumentUserInteraction(e),isExceptionsManagerTarget(n)&&instrumentExceptionsManager(e),isCssInteropTarget(n)&&instrumentCssInterop(e),isNavigationTarget(n)&&instrumentNavigation(e),isReactIndexTarget(n)&&instrumentReactCreateElement(e),shouldInstrumentLifecycleForFile(e,t,n)&&instrumentLifecycle(e),shouldInstrumentInputForFile(t,n)&&instrumentInput(e),shouldInstrumentUserInteractionNames(t)&&(instrumentJsxNames(e),instrumentComponentNames(e))},writeDebugOutputIfChanged=function(e,t,n,r){!0===reactOptions.debugBabelPlugin&&(e=(0,generator_1.default)(e.node).code)!==r&&(r=fspath.join(PathsConstants_1.default.getBuildPath(),fspath.relative(PathsConstants_1.default.getApplicationPath(),n)+".dtx"),fs.mkdirSync(fspath.dirname(r),{recursive:!0}),fs.writeFileSync(r,e),t.set("fileDidChange",!0))};exports.default=function(){return{visitor:{Program:function(e,t){reactOptions=(0,Config_1.readConfigDefault)().react;var n,r,a=t.filename;void 0!==a&&(n=createFilenameMatcher(a),r=captureOriginalCode(e),instrumentByModuleAndFile(e,a,n),writeDebugOutputIfChanged(e,t,a,r))}},post:function(e){var t;!0===reactOptions.debugBabelPlugin&&!0===this.get("fileDidChange")&&(t=(0,generator_1.default)(e.ast).code,e=fspath.join(PathsConstants_1.default.getBuildPath(),fspath.relative(PathsConstants_1.default.getApplicationPath(),e.opts.filename)+".dtx.downstream"),fs.mkdirSync(fspath.dirname(e),{recursive:!0}),fs.writeFileSync(e,t))}}};
@@ -1,12 +1,25 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.RootWrapper = exports.wrapProvider = exports.notifyPress = void 0;
3
+ exports.RootWrapper = exports.wrapProvider = exports.notifyPress = exports.UserInteractionEventKey = void 0;
4
4
  const React = require("react");
5
5
  const react_native_1 = require("react-native");
6
- const ConfigurationHandler_1 = require("../../lib/core/configuration/ConfigurationHandler");
7
6
  const EventPipeline_1 = require("../../lib/next/events/EventPipeline");
8
7
  const EventTimestamp_1 = require("../../lib/next/events/EventTimestamp");
9
8
  const TimestampProvider_1 = require("../../lib/next/provider/TimestampProvider");
9
+ const ConfigurationHandler_1 = require("../../lib/core/configuration/ConfigurationHandler");
10
+ var UserInteractionEventKey;
11
+ (function (UserInteractionEventKey) {
12
+ UserInteractionEventKey["EventHasUserInteraction"] = "characteristics.has_user_interaction";
13
+ UserInteractionEventKey["UiElementDetectedName"] = "ui_element.detected_name";
14
+ UserInteractionEventKey["UiElementComponents"] = "ui_element.components";
15
+ UserInteractionEventKey["UiElementId"] = "ui_element.id";
16
+ UserInteractionEventKey["UiElementNameOrigin"] = "ui_element.name_origin";
17
+ UserInteractionEventKey["InteractionType"] = "interaction.type";
18
+ UserInteractionEventKey["UiElementResponderDetectedName"] = "ui_element.responder.detected_name";
19
+ UserInteractionEventKey["UiElementResponderComponents"] = "ui_element.responder.components";
20
+ UserInteractionEventKey["UiElementResponderOriginName"] = "ui_element.responder.name_origin";
21
+ UserInteractionEventKey["UiElementResponderId"] = "ui_element.responder.id";
22
+ })(UserInteractionEventKey = exports.UserInteractionEventKey || (exports.UserInteractionEventKey = {}));
10
23
  const TOUCH_FLUSH_DELAY = 250;
11
24
  let pendingTouch = null;
12
25
  const getFiberPath = (fiber) => {
@@ -43,7 +56,7 @@ function findRCTTextChild(fiber) {
43
56
  return null;
44
57
  }
45
58
  const getHostComponentInfo = (event) => {
46
- var _a, _b;
59
+ var _a, _b, _c, _d, _e;
47
60
  let fiber = event._targetInst;
48
61
  if (!fiber) {
49
62
  console.warn('Assumption violated: _targetInst not found');
@@ -64,7 +77,7 @@ const getHostComponentInfo = (event) => {
64
77
  let detectedName;
65
78
  if (fiber.type !== 'RCTText') {
66
79
  nameOrigin = 'component';
67
- detectedName = (_b = fiber.memoizedProps.accessibilityLabel) !== null && _b !== void 0 ? _b : leaf;
80
+ detectedName = (_c = (_b = fiber.memoizedProps) === null || _b === void 0 ? void 0 : _b.accessibilityLabel) !== null && _c !== void 0 ? _c : leaf;
68
81
  }
69
82
  else if (anyParentMasked) {
70
83
  nameOrigin = 'masked';
@@ -72,7 +85,7 @@ const getHostComponentInfo = (event) => {
72
85
  }
73
86
  else {
74
87
  nameOrigin = 'text';
75
- detectedName = flatten(fiber.memoizedProps.children);
88
+ detectedName = flatten((_e = (_d = fiber.memoizedProps) === null || _d === void 0 ? void 0 : _d.children) !== null && _e !== void 0 ? _e : '');
76
89
  }
77
90
  return { id, components, detectedName, nameOrigin };
78
91
  };
@@ -92,8 +105,9 @@ const flushTouch = (responderComponentInfo) => {
92
105
  EventPipeline_1.EventPipeline.insertEvent(event);
93
106
  };
94
107
  const onTouch = (e) => {
95
- if (!ConfigurationHandler_1.ConfigurationHandler.isUserInteractionEnabled())
108
+ if (!ConfigurationHandler_1.ConfigurationHandler.getThirdGenDataReportingDecision().allowed) {
96
109
  return;
110
+ }
97
111
  flushTouch();
98
112
  const touchedComponentInfo = getHostComponentInfo(e);
99
113
  if (!touchedComponentInfo)
@@ -1,74 +1,30 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.monitorNavigation = void 0;
3
+ exports.useNavigationMonitor = void 0;
4
4
  const react_1 = require("react");
5
5
  const react_native_1 = require("react-native");
6
- const ConsoleLogger_1 = require("../../../lib/core/logging/ConsoleLogger");
7
- const LogMessages_1 = require("../../../lib/core/logging/LogMessages");
8
- const DynatraceBridge_1 = require("../../../lib/core/DynatraceBridge");
9
- const BaseDataEventModifier_1 = require("../../../lib/next/events/modifier/BaseDataEventModifier");
10
- const ConfigurationHandler_1 = require("../../../lib/core/configuration/ConfigurationHandler");
11
- const logger = new ConsoleLogger_1.ConsoleLogger('ReactNavigation');
12
- let activePath = '';
13
- let appState = react_native_1.AppState.currentState;
14
- const monitorNavigation = (getRootState) => {
6
+ const NavigationTracker_1 = require("../../../lib/next/navigation/NavigationTracker");
7
+ const useNavigationMonitor = (getRootState) => {
15
8
  (0, react_1.useEffect)(() => {
16
- var _a, _b;
17
- let currentState = getRootState();
18
- let newPath = '';
19
- while (currentState === null || currentState === void 0 ? void 0 : currentState.routes[(_a = currentState.index) !== null && _a !== void 0 ? _a : 0]) {
20
- const currentRoute = currentState === null || currentState === void 0 ? void 0 : currentState.routes[(_b = currentState.index) !== null && _b !== void 0 ? _b : 0];
21
- newPath += `/${currentRoute.name}`;
22
- currentState = currentRoute.state;
23
- }
24
- if (newPath !== activePath) {
25
- if (activePath !== '') {
26
- stopView();
27
- }
28
- startView(newPath);
29
- activePath = newPath;
30
- }
9
+ const newPath = (0, NavigationTracker_1.buildPathFromState)(getRootState());
10
+ (0, NavigationTracker_1.reportScreenChange)(newPath);
31
11
  });
12
+ const appStateRef = (0, react_1.useRef)(react_native_1.AppState.currentState);
32
13
  (0, react_1.useEffect)(() => {
33
14
  const subscription = react_native_1.AppState.addEventListener('change', (nextAppState) => {
34
- if (nextAppState !== 'active' && appState === 'active') {
35
- stopView();
15
+ const prevAppState = appStateRef.current;
16
+ appStateRef.current = nextAppState;
17
+ if (nextAppState !== 'active' && prevAppState === 'active') {
18
+ (0, NavigationTracker_1.reportScreenBackground)();
36
19
  }
37
- else if (nextAppState === 'active' && appState !== 'active') {
38
- startView(activePath);
20
+ else if (nextAppState === 'active' &&
21
+ prevAppState !== 'active') {
22
+ (0, NavigationTracker_1.reportScreenResume)();
39
23
  }
40
- appState = nextAppState;
41
24
  });
42
25
  return () => {
43
26
  subscription.remove();
44
27
  };
45
28
  }, []);
46
29
  };
47
- exports.monitorNavigation = monitorNavigation;
48
- const startView = (newPath) => {
49
- if (!ConfigurationHandler_1.ConfigurationHandler.isConfigurationAvailable()) {
50
- logger.info(LogMessages_1.LogMessage.NAVIGATION_NOT_STARTED);
51
- return;
52
- }
53
- const startViewInternalEvent = new BaseDataEventModifier_1.BaseDataEventModifier().modifyEvent(Object.assign({ 'view.detected_name': newPath }, (activePath && {
54
- 'view.source.detected_name': activePath,
55
- })));
56
- const fn = DynatraceBridge_1.DynatraceNative === null || DynatraceBridge_1.DynatraceNative === void 0 ? void 0 : DynatraceBridge_1.DynatraceNative.startViewInternal;
57
- if (typeof fn === 'function') {
58
- fn(startViewInternalEvent);
59
- }
60
- logger.debug(LogMessages_1.LogMessage.START_VIEW_INTERNAL, {
61
- event: JSON.stringify(startViewInternalEvent),
62
- });
63
- };
64
- const stopView = () => {
65
- if (!ConfigurationHandler_1.ConfigurationHandler.isConfigurationAvailable()) {
66
- logger.info(LogMessages_1.LogMessage.NAVIGATION_NOT_STARTED);
67
- return;
68
- }
69
- const fn = DynatraceBridge_1.DynatraceNative === null || DynatraceBridge_1.DynatraceNative === void 0 ? void 0 : DynatraceBridge_1.DynatraceNative.stopViewInternal;
70
- if (typeof fn === 'function') {
71
- fn();
72
- }
73
- logger.debug(LogMessages_1.LogMessage.STOP_VIEW_INTERNAL);
74
- };
30
+ exports.useNavigationMonitor = useNavigationMonitor;
@@ -15,68 +15,18 @@ function withOnPressMonitoring(Component, fallbackName) {
15
15
  const { onPress, onLongPress } = props;
16
16
  const touchableName = (0, exports.chooseTouchableName)(props, fallbackName);
17
17
  const dynatraceIgnored = (0, ComponentUtil_1.isDynatraceIgnored)(props);
18
- const isRNButton = 'title' in props && typeof props.title === 'string';
19
- const isRectButton = fallbackName === 'Button';
20
- const isButtonLike = isRNButton || isRectButton;
21
- const buttonLabel = isRNButton ? String(props.title) : null;
22
18
  const propsWithoutRef = Object.assign(Object.assign(Object.assign({}, props), (!dynatraceIgnored &&
23
19
  onPress && {
24
- onPress: (0, exports.wrapOnPress)(onPress, touchableName, isButtonLike, buttonLabel),
20
+ onPress: (0, exports.wrapOnPress)(onPress, touchableName),
25
21
  })), (!dynatraceIgnored &&
26
22
  onLongPress && {
27
- onLongPress: (0, exports.wrapOnPress)(onLongPress, touchableName, isButtonLike, buttonLabel),
23
+ onLongPress: (0, exports.wrapOnPress)(onLongPress, touchableName),
28
24
  }));
29
25
  const propsWithRef = Object.assign(Object.assign({}, propsWithoutRef), { ref });
30
26
  return React.createElement(Component, Object.assign({}, propsWithRef));
31
27
  });
32
28
  }
33
29
  exports.withOnPressMonitoring = withOnPressMonitoring;
34
- const dtGetUiBridge = () => {
35
- var _a;
36
- const g = globalThis;
37
- return (_a = g === null || g === void 0 ? void 0 : g.__DT_UII_BRIDGE) !== null && _a !== void 0 ? _a : null;
38
- };
39
- const dtBuildPressPath = (startPath, touchableName) => {
40
- var _a;
41
- const base = (_a = startPath === null || startPath === void 0 ? void 0 : startPath.toString()) !== null && _a !== void 0 ? _a : '';
42
- if (!base)
43
- return `Touchable(${touchableName})`;
44
- const cut1 = base.lastIndexOf('/Text');
45
- const cut2 = base.lastIndexOf('/Text(');
46
- const cut = Math.max(cut1, cut2);
47
- const parent = cut > 0 ? base.slice(0, cut) : base;
48
- return parent + `/Touchable(${touchableName})`;
49
- };
50
- const registerPressOnBridge = (args, touchableName, isButtonLike, buttonLabel) => {
51
- const bridge = dtGetUiBridge();
52
- if (!bridge || typeof bridge.registerPress !== 'function') {
53
- return;
54
- }
55
- try {
56
- const e = args === null || args === void 0 ? void 0 : args[0];
57
- const ne = e === null || e === void 0 ? void 0 : e.nativeEvent;
58
- const x = Number(ne === null || ne === void 0 ? void 0 : ne.pageX);
59
- const y = Number(ne === null || ne === void 0 ? void 0 : ne.pageY);
60
- const pos = Number.isFinite(x) && Number.isFinite(y) ? { x, y } : undefined;
61
- const startPath = typeof bridge.getStartPath === 'function'
62
- ? bridge.getStartPath()
63
- : null;
64
- const nameForBridge = isButtonLike
65
- ? buttonLabel || touchableName
66
- : touchableName;
67
- bridge.registerPress({
68
- path: dtBuildPressPath(startPath, nameForBridge),
69
- elementName: nameForBridge,
70
- pos,
71
- });
72
- }
73
- catch (e) {
74
- const errorMsg = e instanceof Error ? e.stack || e.message : String(e);
75
- Logger.debug(LogMessages_1.LogMessage.REGISTER_PRESS_HOOK_FAILED, {
76
- errorMsg,
77
- });
78
- }
79
- };
80
30
  const notifyPressFromEvent = (args) => {
81
31
  if (args[0] && typeof args[0] === 'object' && 'nativeEvent' in args[0]) {
82
32
  (0, UserInteraction_1.notifyPress)(args[0]);
@@ -104,9 +54,8 @@ const invokeOnPressWithAction = (onPress, args, touchableName) => {
104
54
  }
105
55
  }
106
56
  };
107
- const wrapOnPress = (onPress, touchableName, isButtonLike, buttonLabel) => {
57
+ const wrapOnPress = (onPress, touchableName) => {
108
58
  return (...args) => {
109
- registerPressOnBridge(args, touchableName, isButtonLike, buttonLabel);
110
59
  notifyPressFromEvent(args);
111
60
  if (!ConfigurationHandler_1.ConfigurationHandler.isConfigurationAvailable()) {
112
61
  invokeOnPressWithoutConfiguration(onPress, args);
package/internal.d.ts ADDED
@@ -0,0 +1 @@
1
+ export declare function registerEventTrigger(fn: ((name: string, timestamp: number) => void) | null): void;
package/internal.js CHANGED
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createElement = exports.ApplicationHandler = void 0;
3
+ exports.registerEventTrigger = exports.createElement = exports.ApplicationHandler = void 0;
4
4
  var Application_1 = require("./lib/core/Application");
5
5
  Object.defineProperty(exports, "ApplicationHandler", { enumerable: true, get: function () { return Application_1.ApplicationHandler; } });
6
6
  var CreateElement_1 = require("./instrumentation/jsx/CreateElement");
7
7
  Object.defineProperty(exports, "createElement", { enumerable: true, get: function () { return CreateElement_1.createElement; } });
8
+ var NavigationTracker_1 = require("./lib/next/navigation/NavigationTracker");
9
+ Object.defineProperty(exports, "registerEventTrigger", { enumerable: true, get: function () { return NavigationTracker_1.registerEventTrigger; } });
@@ -225,11 +225,13 @@ template<typename T = void> std::enable_if_t<(facebook::react::ReactNativeVersio
225
225
  /**
226
226
  * When bridge is starting we will add an observer for content did appear so we can emit our app start measurements
227
227
  */
228
+ #if !RCT_NEW_ARCH_ENABLED
228
229
  - (void)setBridge:(RCTBridge *)bridge
229
230
  {
230
231
  [super setBridge:bridge];
231
232
  [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(contentAppeared) name:RCTContentDidAppearNotification object:nil];
232
233
  }
234
+ #endif
233
235
 
234
236
  - (BOOL)isReady
235
237
  {
@@ -289,6 +291,13 @@ template<typename T = void> std::enable_if_t<(facebook::react::ReactNativeVersio
289
291
  - (void)startObserving
290
292
  {
291
293
  hasListeners = YES;
294
+ #if RCT_NEW_ARCH_ENABLED
295
+ // On new arch setBridge: is not called, so RCTContentDidAppearNotification is never observed.
296
+ // JS adding a listener is the earliest signal we have that content is visible.
297
+ if (contentAppeared == -1) {
298
+ contentAppeared = GetTimestampUnix();
299
+ }
300
+ #endif
292
301
  [self emitMeasurements];
293
302
 
294
303
  [self setupRuntimeConfigurationListenerIfNeeded];
@@ -4,7 +4,6 @@ exports.ConfigurationHandler = void 0;
4
4
  const RuntimeConfigurationObserver_1 = require("../../next/configuration/RuntimeConfigurationObserver");
5
5
  const LogLevel_1 = require("../logging/LogLevel");
6
6
  let _configuration;
7
- let _uiiEnabledLastKnownGood = undefined;
8
7
  const getRuntimeConfiguration = () => RuntimeConfigurationObserver_1.RuntimeConfigurationObserver.getCurrentRuntimeConfiguration();
9
8
  const getBaseThirdGenDecision = () => {
10
9
  if (!RuntimeConfigurationObserver_1.RuntimeConfigurationObserver.isInitiated()) {
@@ -46,9 +45,6 @@ exports.ConfigurationHandler = {
46
45
  setConfiguration(configuration) {
47
46
  _configuration = configuration;
48
47
  },
49
- setUserInteractionEnabledLastKnownGood(value) {
50
- _uiiEnabledLastKnownGood = value;
51
- },
52
48
  isConfigurationAvailable: () => _configuration !== undefined,
53
49
  isErrorHandlerEnabled: () => _configuration.errorHandler,
54
50
  isReportFatalErrorAsCrash: () => _configuration.reportFatalErrorAsCrash,
@@ -84,23 +80,6 @@ exports.ConfigurationHandler = {
84
80
  getApplicationId: () => RuntimeConfigurationObserver_1.RuntimeConfigurationObserver.getCurrentRuntimeConfiguration()['application_id'],
85
81
  getTracestateKeyPrefix: () => RuntimeConfigurationObserver_1.RuntimeConfigurationObserver.getCurrentRuntimeConfiguration()['tracestate_key_prefix'],
86
82
  getTraceContextEnabled: () => RuntimeConfigurationObserver_1.RuntimeConfigurationObserver.getCurrentRuntimeConfiguration()['trace_context_enabled'],
87
- isUserInteractionEnabled: () => {
88
- const isRuntimeConfigInitiated = RuntimeConfigurationObserver_1.RuntimeConfigurationObserver.isInitiated();
89
- if (isRuntimeConfigInitiated) {
90
- const realTimeconfiguration = RuntimeConfigurationObserver_1.RuntimeConfigurationObserver.getCurrentRuntimeConfiguration();
91
- const remoteUIConfiguration = realTimeconfiguration
92
- ? realTimeconfiguration.touch_interaction_enabled
93
- : undefined;
94
- if (typeof remoteUIConfiguration === 'boolean') {
95
- _uiiEnabledLastKnownGood = remoteUIConfiguration;
96
- return remoteUIConfiguration;
97
- }
98
- }
99
- if (typeof _uiiEnabledLastKnownGood === 'boolean') {
100
- return _uiiEnabledLastKnownGood;
101
- }
102
- return false;
103
- },
104
83
  isRuntimeConfigurationInitiated: () => RuntimeConfigurationObserver_1.RuntimeConfigurationObserver.isInitiated(),
105
84
  getBundleName: () => _configuration.bundleName,
106
85
  getBundleVersion: () => _configuration.bundleVersion,
@@ -1,14 +1,4 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
2
  const TerminalReporter = (() => {
13
3
  try {
14
4
  return require('metro/src/lib/TerminalReporter');
@@ -18,23 +8,4 @@ const TerminalReporter = (() => {
18
8
  }
19
9
  })();
20
10
  const { Terminal } = require('metro-core');
21
- const files = require('../scripts/FileOperationHelper');
22
- const paths = require('../scripts/PathsConstants');
23
- const reporter = new TerminalReporter(new Terminal(process.stdout));
24
- const updateOrig = TerminalReporter.prototype.update;
25
- TerminalReporter.prototype.update = function update(event) {
26
- return updateOrig === null || updateOrig === void 0 ? void 0 : updateOrig.apply(this, arguments);
27
- };
28
- const update = (event) => __awaiter(void 0, void 0, void 0, function* () {
29
- if (event != null) {
30
- if (event.type === 'transform_cache_reset') {
31
- try {
32
- yield files.default.deleteDirectory(paths.default.getBuildPath());
33
- }
34
- catch (e) {
35
- }
36
- }
37
- }
38
- reporter.update(event);
39
- });
40
- module.exports.update = update;
11
+ module.exports = new TerminalReporter(new Terminal(process.stdout));
@@ -1,40 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getUpstreamTransformer = exports.transform = void 0;
4
- const config = require("../scripts/Config");
5
- const Logger_1 = require("../scripts/Logger");
6
4
  const BabelPluginDynatrace_1 = require("../instrumentation/BabelPluginDynatrace");
7
- const instrumentor = require("../instrumentation/DynatraceInstrumentation");
8
5
  const Config_1 = require("../scripts/Config");
9
6
  const transform = (args) => {
10
7
  var _a;
11
- let src = args.src;
12
- const { filename, options } = args;
13
- let reactOptions;
14
- try {
15
- reactOptions = (0, Config_1.readConfigDefault)();
16
- if (!reactOptions.react.useLegacyJscodeshift) {
17
- args.plugins = [BabelPluginDynatrace_1.default, ...((_a = args.plugins) !== null && _a !== void 0 ? _a : [])];
18
- return (0, exports.getUpstreamTransformer)(reactOptions === null || reactOptions === void 0 ? void 0 : reactOptions.react).transform(args);
19
- }
20
- src = instrumentor.instrument(src, filename, reactOptions.react);
21
- }
22
- catch (e) {
23
- if (e instanceof Error) {
24
- if (e.message === config.ERROR_CONFIG_NOT_AVAILABLE) {
25
- console.log('dynatrace.config.js not found!');
26
- }
27
- else {
28
- console.log("Couldn't instrument file: " + filename);
29
- Logger_1.default.logErrorSync(e.message);
30
- }
31
- }
32
- }
33
- return (0, exports.getUpstreamTransformer)(reactOptions === null || reactOptions === void 0 ? void 0 : reactOptions.react).transform({
34
- src,
35
- filename,
36
- options,
37
- });
8
+ args.plugins = [BabelPluginDynatrace_1.default, ...((_a = args.plugins) !== null && _a !== void 0 ? _a : [])];
9
+ return (0, exports.getUpstreamTransformer)((0, Config_1.readConfigDefault)().react).transform(args);
38
10
  };
39
11
  exports.transform = transform;
40
12
  const safeRequire = (modulePath) => {
@@ -45,10 +17,10 @@ const safeRequire = (modulePath) => {
45
17
  return null;
46
18
  }
47
19
  };
48
- const getUpstreamTransformer = (reactOptions) => {
49
- if (reactOptions !== undefined &&
50
- reactOptions.upstreamTransformer !== undefined) {
51
- return require(reactOptions.upstreamTransformer);
20
+ const getUpstreamTransformer = (transformerReactConfig) => {
21
+ const upstreamTransformer = transformerReactConfig === null || transformerReactConfig === void 0 ? void 0 : transformerReactConfig.upstreamTransformer;
22
+ if (upstreamTransformer !== undefined) {
23
+ return require(upstreamTransformer);
52
24
  }
53
25
  else {
54
26
  const transformer = safeRequire('@expo/metro-config/babel-transformer') ||
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.generateDefaultConfiguration = void 0;
4
4
  const generateDefaultConfiguration = () => ({
5
5
  '3rd_gen_enabled': true,
6
- touch_interaction_enabled: false,
7
6
  instance_id: '',
8
7
  session_id: '',
9
8
  application_id: '',
@@ -28,9 +28,6 @@ class RuntimeConfigurationObserverImpl {
28
28
  const thirdGenEnabled = typeof payload['3rd_gen_enabled'] === 'boolean'
29
29
  ? payload['3rd_gen_enabled']
30
30
  : undefined;
31
- const touchInteractionEnabled = typeof payload.touch_interaction_enabled === 'boolean'
32
- ? payload.touch_interaction_enabled
33
- : undefined;
34
31
  const traceContextEnabled = typeof payload.trace_context_enabled === 'boolean'
35
32
  ? payload.trace_context_enabled
36
33
  : undefined;
@@ -60,10 +57,8 @@ class RuntimeConfigurationObserverImpl {
60
57
  const tracestateKeyPrefix = typeof payload.tracestate_key_prefix === 'string'
61
58
  ? payload.tracestate_key_prefix
62
59
  : undefined;
63
- const normalized = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, (typeof thirdGenEnabled === 'boolean'
60
+ const normalized = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, (typeof thirdGenEnabled === 'boolean'
64
61
  ? { '3rd_gen_enabled': thirdGenEnabled }
65
- : {})), (typeof touchInteractionEnabled === 'boolean'
66
- ? { touch_interaction_enabled: touchInteractionEnabled }
67
62
  : {})), (typeof traceContextEnabled === 'boolean'
68
63
  ? { trace_context_enabled: traceContextEnabled }
69
64
  : {})), (typeof dataCollectionLevel === 'number'