@truewatchtech/react-native-mobile 0.4.0-alpha.4 → 0.4.2

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 (155) hide show
  1. package/FTMobileReactNativeSDK.podspec +31 -2
  2. package/android/build.gradle +7 -19
  3. package/android/src/main/java/com/ft/sdk/reactnative/FTMobileImpl.java +472 -5
  4. package/android/src/main/java/com/ft/sdk/reactnative/FTRUMImpl.java +12 -0
  5. package/android/src/newarch/java/com/ft/sdk/reactnative/FTLogModule.java +7 -14
  6. package/android/src/newarch/java/com/ft/sdk/reactnative/FTMobileModule.java +46 -12
  7. package/android/src/newarch/java/com/ft/sdk/reactnative/FTRUMModule.java +12 -13
  8. package/android/src/newarch/java/com/ft/sdk/reactnative/FTTraceModule.java +6 -8
  9. package/android/src/oldarch/java/com/ft/sdk/reactnative/FTMobileModule.java +34 -2
  10. package/android/src/oldarch/java/com/ft/sdk/reactnative/FTRUMModule.java +5 -0
  11. package/android/src/rnpost74/java/com/ft/sdk/reactnative/FTMobilePackage.java +14 -3
  12. package/android/src/rnpre74/java/com/ft/sdk/reactnative/FTMobilePackage.java +0 -3
  13. package/ios/FTMobileReactNative.h +9 -5
  14. package/ios/FTMobileReactNative.mm +625 -0
  15. package/ios/FTReactNativeLog.h +8 -3
  16. package/ios/FTReactNativeLog.mm +79 -0
  17. package/ios/FTReactNativeRUM.h +8 -3
  18. package/ios/{FTReactNativeRUM.m → FTReactNativeRUM.mm} +143 -84
  19. package/ios/FTReactNativeTrace.h +8 -2
  20. package/ios/FTReactNativeTrace.mm +74 -0
  21. package/ios/FtMobileAgent.xcodeproj/project.pbxproj +17 -1
  22. package/lib/commonjs/ft_logger.js +14 -13
  23. package/lib/commonjs/ft_logger.js.map +1 -1
  24. package/lib/commonjs/ft_mobile_agent.js +155 -6
  25. package/lib/commonjs/ft_mobile_agent.js.map +1 -1
  26. package/lib/commonjs/ft_rum.js +55 -21
  27. package/lib/commonjs/ft_rum.js.map +1 -1
  28. package/lib/commonjs/ft_tracing.js +29 -10
  29. package/lib/commonjs/ft_tracing.js.map +1 -1
  30. package/lib/commonjs/index.js +24 -13
  31. package/lib/commonjs/index.js.map +1 -1
  32. package/lib/commonjs/rum/FTRumActionTracking.js +10 -4
  33. package/lib/commonjs/rum/FTRumActionTracking.js.map +1 -1
  34. package/lib/commonjs/rum/FTRumErrorTracking.js +4 -4
  35. package/lib/commonjs/rum/FTRumErrorTracking.js.map +1 -1
  36. package/lib/commonjs/specs/NativeFTMobileReactNative.js +10 -0
  37. package/lib/commonjs/specs/NativeFTMobileReactNative.js.map +1 -0
  38. package/lib/commonjs/specs/NativeFTReactNativeLog.js +10 -0
  39. package/lib/commonjs/specs/NativeFTReactNativeLog.js.map +1 -0
  40. package/lib/commonjs/specs/NativeFTReactNativeRUM.js +10 -0
  41. package/lib/commonjs/specs/NativeFTReactNativeRUM.js.map +1 -0
  42. package/lib/commonjs/specs/NativeFTReactNativeTrace.js +10 -0
  43. package/lib/commonjs/specs/NativeFTReactNativeTrace.js.map +1 -0
  44. package/lib/commonjs/version.js +1 -1
  45. package/lib/commonjs/version.js.map +1 -1
  46. package/lib/module/ft_logger.js +14 -12
  47. package/lib/module/ft_logger.js.map +1 -1
  48. package/lib/module/ft_mobile_agent.js +161 -5
  49. package/lib/module/ft_mobile_agent.js.map +1 -1
  50. package/lib/module/ft_rum.js +54 -16
  51. package/lib/module/ft_rum.js.map +1 -1
  52. package/lib/module/ft_tracing.js +29 -9
  53. package/lib/module/ft_tracing.js.map +1 -1
  54. package/lib/module/index.js +3 -4
  55. package/lib/module/index.js.map +1 -1
  56. package/lib/module/rum/FTRumActionTracking.js +10 -4
  57. package/lib/module/rum/FTRumActionTracking.js.map +1 -1
  58. package/lib/module/rum/FTRumErrorTracking.js +4 -4
  59. package/lib/module/rum/FTRumErrorTracking.js.map +1 -1
  60. package/lib/module/specs/NativeFTMobileReactNative.js +5 -0
  61. package/lib/module/specs/NativeFTMobileReactNative.js.map +1 -0
  62. package/lib/module/specs/NativeFTReactNativeLog.js +5 -0
  63. package/lib/module/specs/NativeFTReactNativeLog.js.map +1 -0
  64. package/lib/module/specs/NativeFTReactNativeRUM.js +5 -0
  65. package/lib/module/specs/NativeFTReactNativeRUM.js.map +1 -0
  66. package/lib/module/specs/NativeFTReactNativeTrace.js +5 -0
  67. package/lib/module/specs/NativeFTReactNativeTrace.js.map +1 -0
  68. package/lib/module/version.js +1 -1
  69. package/lib/module/version.js.map +1 -1
  70. package/lib/typescript/ft_logger.d.ts +6 -6
  71. package/lib/typescript/ft_mobile_agent.d.ts +169 -14
  72. package/lib/typescript/ft_rum.d.ts +32 -8
  73. package/lib/typescript/ft_tracing.d.ts +6 -6
  74. package/lib/typescript/index.d.ts +3 -4
  75. package/lib/typescript/specs/NativeFTMobileReactNative.d.ts +75 -0
  76. package/lib/typescript/specs/NativeFTReactNativeLog.d.ts +23 -0
  77. package/lib/typescript/specs/NativeFTReactNativeRUM.d.ts +89 -0
  78. package/lib/typescript/specs/NativeFTReactNativeTrace.d.ts +24 -0
  79. package/lib/typescript/version.d.ts +1 -1
  80. package/package.json +26 -93
  81. package/scripts/replace-react-require.js +37 -38
  82. package/src/ft_logger.tsx +72 -40
  83. package/src/ft_mobile_agent.tsx +378 -91
  84. package/src/ft_rum.tsx +227 -121
  85. package/src/ft_tracing.tsx +58 -37
  86. package/src/index.tsx +58 -18
  87. package/src/rum/FTRumActionTracking.tsx +212 -204
  88. package/src/rum/FTRumErrorTracking.tsx +70 -71
  89. package/src/specs/NativeFTMobileReactNative.ts +83 -0
  90. package/src/specs/NativeFTReactNativeLog.ts +29 -0
  91. package/src/specs/NativeFTReactNativeRUM.ts +104 -0
  92. package/src/specs/NativeFTReactNativeTrace.ts +26 -0
  93. package/src/version.ts +1 -1
  94. package/LICENSE +0 -201
  95. package/android/.project +0 -17
  96. package/android/.settings/org.eclipse.buildship.core.prefs +0 -13
  97. package/android/gradlew +0 -185
  98. package/android/local.properties +0 -8
  99. package/android/src/main/java/com/ft/sdk/InnerClassProxy.java +0 -8
  100. package/android/src/main/java/com/ft/sdk/reactnative/FTSessionReplayImpl.java +0 -60
  101. package/android/src/main/java/com/ft/sdk/reactnative/extensions/ReactDrawablesExt.java +0 -155
  102. package/android/src/main/java/com/ft/sdk/reactnative/sessionreplay/NoopTextPropertiesResolver.java +0 -23
  103. package/android/src/main/java/com/ft/sdk/reactnative/sessionreplay/ReactNativeSessionReplayExtensionSupport.java +0 -57
  104. package/android/src/main/java/com/ft/sdk/reactnative/sessionreplay/ShadowNodeWrapper.java +0 -84
  105. package/android/src/main/java/com/ft/sdk/reactnative/sessionreplay/TextPropertiesResolver.java +0 -20
  106. package/android/src/main/java/com/ft/sdk/reactnative/sessionreplay/mappers/DefaultMapper.java +0 -78
  107. package/android/src/main/java/com/ft/sdk/reactnative/sessionreplay/mappers/Pair.java +0 -11
  108. package/android/src/main/java/com/ft/sdk/reactnative/sessionreplay/mappers/ReactEditTextMapper.java +0 -136
  109. package/android/src/main/java/com/ft/sdk/reactnative/sessionreplay/mappers/ReactNativeImageViewMapper.java +0 -117
  110. package/android/src/main/java/com/ft/sdk/reactnative/sessionreplay/mappers/ReactTextMapper.java +0 -57
  111. package/android/src/main/java/com/ft/sdk/reactnative/sessionreplay/mappers/ReactViewGroupMapper.java +0 -22
  112. package/android/src/main/java/com/ft/sdk/reactnative/sessionreplay/mappers/ReactViewModalMapper.java +0 -21
  113. package/android/src/main/java/com/ft/sdk/reactnative/sessionreplay/resources/ReactDrawableCopier.java +0 -35
  114. package/android/src/main/java/com/ft/sdk/reactnative/sessionreplay/utils/DrawableUtils.java +0 -34
  115. package/android/src/main/java/com/ft/sdk/reactnative/sessionreplay/utils/ReflectionUtils.java +0 -43
  116. package/android/src/main/java/com/ft/sdk/reactnative/sessionreplay/utils/text/FabricTextViewUtils.java +0 -69
  117. package/android/src/main/java/com/ft/sdk/reactnative/sessionreplay/utils/text/LegacyTextViewUtils.java +0 -97
  118. package/android/src/main/java/com/ft/sdk/reactnative/sessionreplay/utils/text/TextViewUtils.java +0 -184
  119. package/android/src/main/java/com/ft/sdk/reactnative/utils/ColorUtils.java +0 -24
  120. package/android/src/newarch/java/com/ft/sdk/reactnative/FTSessionReplayModule.java +0 -30
  121. package/android/src/oldarch/java/com/ft/sdk/reactnative/FTSessionReplayModule.java +0 -25
  122. package/android/src/rn69/java/com/ft/sdk/reactnative/sessionreplay/utils/ReactViewBackgroundDrawableUtils.java +0 -100
  123. package/android/src/rn75/java/com/ft/sdk/reactnative/sessionreplay/extensions/LengthPercentageExt.java +0 -27
  124. package/android/src/rn75/java/com/ft/sdk/reactnative/sessionreplay/utils/ReactViewBackgroundDrawableUtils.java +0 -116
  125. package/android/src/rn76/java/com/ft/sdk/reactnative/sessionreplay/extensions/LengthPercentageExt.java +0 -38
  126. package/android/src/rn76/java/com/ft/sdk/reactnative/sessionreplay/utils/ReactViewBackgroundDrawableUtils.java +0 -117
  127. package/android/src/rn79/java/com/ft/sdk/reactnative/sessionreplay/extensions/LengthPercentageExt.java +0 -38
  128. package/android/src/rn79/java/com/ft/sdk/reactnative/sessionreplay/utils/ReactViewBackgroundDrawableUtils.java +0 -132
  129. package/android/src/rn80/java/com/ft/sdk/reactnative/sessionreplay/extensions/ComputedBorderRadiusExt.java +0 -58
  130. package/android/src/rn80/java/com/ft/sdk/reactnative/sessionreplay/utils/ReactViewBackgroundDrawableUtils.java +0 -190
  131. package/android/src/rnlegacy/java/com/ft/sdk/reactnative/sessionreplay/utils/ReactViewBackgroundDrawableUtils.java +0 -120
  132. package/ios/.idea/.name +0 -1
  133. package/ios/.idea/ios.iml +0 -2
  134. package/ios/.idea/modules.xml +0 -8
  135. package/ios/.idea/vcs.xml +0 -6
  136. package/ios/.idea/xcode.xml +0 -4
  137. package/ios/FTMobileReactNative.m +0 -184
  138. package/ios/FTRCTTextViewRecorder.h +0 -33
  139. package/ios/FTRCTTextViewRecorder.m +0 -120
  140. package/ios/FTReactNativeLog.m +0 -60
  141. package/ios/FTReactNativeSessionReplay.h +0 -6
  142. package/ios/FTReactNativeSessionReplay.mm +0 -44
  143. package/ios/FTReactNativeTrace.m +0 -56
  144. package/ios/FtMobileAgent.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -4
  145. package/ios/FtMobileAgent.xcodeproj/project.xcworkspace/xcuserdata/Brandon.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  146. package/ios/FtMobileAgent.xcodeproj/project.xcworkspace/xcuserdata/Brandon.xcuserdatad/xcschemes/xcschememanagement.plist +0 -5
  147. package/ios/FtMobileAgent.xcodeproj/xcuserdata/Brandon.xcuserdatad/xcschemes/FtMobileAgent.xcscheme +0 -56
  148. package/ios/FtMobileAgent.xcodeproj/xcuserdata/Brandon.xcuserdatad/xcschemes/xcschememanagement.plist +0 -14
  149. package/ios/RCTVersion.h +0 -8
  150. package/lib/commonjs/ft_session_replay.js +0 -34
  151. package/lib/commonjs/ft_session_replay.js.map +0 -1
  152. package/lib/module/ft_session_replay.js +0 -29
  153. package/lib/module/ft_session_replay.js.map +0 -1
  154. package/lib/typescript/ft_session_replay.d.ts +0 -27
  155. package/src/ft_session_replay.tsx +0 -34
@@ -1,6 +1,7 @@
1
1
  require "json"
2
2
 
3
3
  package = JSON.parse(File.read(File.join(__dir__, "package.json")))
4
+ folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32'
4
5
 
5
6
  Pod::Spec.new do |s|
6
7
  s.name = "FTMobileReactNativeSDK"
@@ -18,6 +19,34 @@ Pod::Spec.new do |s|
18
19
 
19
20
 
20
21
  s.dependency "React-Core"
21
- s.dependency 'FTMobileSDK', '1.6.2-alpha.3'
22
- s.dependency 'FTMobileSDK/FTSessionReplay', '1.6.2-alpha.3'
22
+ s.dependency 'FTMobileSDK', '1.6.5'
23
+
24
+ xcconfig = {
25
+ "HEADER_SEARCH_PATHS" => "$(inherited) " +
26
+ "$(PODS_ROOT)/React-RCTFabric/** " +
27
+ "$(PODS_ROOT)/React-FabricComponents/** " +
28
+ "${PODS_CONFIGURATION_BUILD_DIR}/React-Fabric/React_RCTFabric.framework/Headers/** " +
29
+ "$(PODS_CONFIGURATION_BUILD_DIR)/React-FabricComponents/React_FabricComponents.framework/Headers/**",
30
+ "USER_HEADER_SEARCH_PATHS" => "$(inherited) " +
31
+ "$(PODS_ROOT)/React-RCTFabric/** " +
32
+ "$(PODS_ROOT)/React-FabricComponents/** " +
33
+ "${PODS_CONFIGURATION_BUILD_DIR}/React-Fabric/React_RCTFabric.framework/Headers/** " +
34
+ "$(PODS_CONFIGURATION_BUILD_DIR)/React-FabricComponents/React_FabricComponents.framework/Headers/**"
35
+ }
36
+
37
+ if ENV['RCT_NEW_ARCH_ENABLED'] == '1' then
38
+ s.compiler_flags = folly_compiler_flags + " -DRCT_NEW_ARCH_ENABLED=1"
39
+
40
+ xcconfig.merge!({
41
+ "DEFINES_MODULE" => "YES",
42
+ "CLANG_CXX_LANGUAGE_STANDARD" => "c++17"
43
+ })
44
+ end
45
+
46
+ s.pod_target_xcconfig = xcconfig
47
+
48
+ if respond_to?(:install_modules_dependencies, true)
49
+ install_modules_dependencies(s)
50
+ end
51
+
23
52
  end
@@ -29,8 +29,10 @@ def reactNativeVersion = new groovy.json.JsonSlurper()
29
29
  def (reactNativeMajorVersion, reactNativeMinorVersion) = reactNativeVersion.split("\\.").collect { it.isInteger() ? it.toInteger() : it }
30
30
 
31
31
  def isNewArchitectureEnabled() {
32
- //return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true"
33
- return false //TODO code not ready, hide this part
32
+ return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true"
33
+ }
34
+ if (isNewArchitectureEnabled()) {
35
+ apply plugin: 'com.facebook.react'
34
36
  }
35
37
 
36
38
  android {
@@ -92,20 +94,6 @@ android {
92
94
  }
93
95
 
94
96
  if (reactNativeMajorVersion == 0) {
95
- if (reactNativeMinorVersion >= 80) {
96
- java.srcDirs += ['src/rn80/java']
97
- } else if (reactNativeMinorVersion >= 79) {
98
- java.srcDirs += ['src/rn79/java']
99
- } else if (reactNativeMinorVersion >= 76) {
100
- java.srcDirs += ['src/rn76/java']
101
- } else if (reactNativeMinorVersion >= 75) {
102
- java.srcDirs += ['src/rn75/java']
103
- }else if (reactNativeMinorVersion >= 69) {
104
- java.srcDirs += ['src/rn69/java']
105
- } else {
106
- java.srcDirs += ['src/rnlegacy/java']
107
- }
108
-
109
97
  if (reactNativeMinorVersion >= 74) {
110
98
  java.srcDirs += ['src/rnpost74/java']
111
99
  } else {
@@ -191,9 +179,9 @@ repositories {
191
179
  dependencies {
192
180
  // noinspection GradleDynamicVersion
193
181
  implementation 'com.facebook.react:react-native:+'
194
- implementation 'com.truewatch.ft.mobile.sdk.tracker.agent:ft-sdk:1.7.0-alpha20'
195
- implementation 'com.truewatch.ft.mobile.sdk.tracker.agent:ft-native:1.1.1'
196
- implementation 'com.truewatch.ft.mobile.sdk.tracker.agent:ft-session-replay:0.1.2-alpha02'
182
+ implementation 'com.truewatch.ft.mobile.sdk.tracker.agent:ft-sdk:1.7.2'
183
+ implementation 'com.truewatch.ft.mobile.sdk.tracker.agent:ft-native:1.1.2'
184
+
197
185
  // implementation files('../example/android/app/libs/ft-sdk-debug.aar')
198
186
  // implementation files('../example/android/app/libs/ft-session-replay-debug.aar')
199
187
 
@@ -2,23 +2,370 @@ package com.ft.sdk.reactnative;
2
2
 
3
3
  import static com.ft.sdk.garble.utils.Constants.FT_LOG_DEFAULT_MEASUREMENT;
4
4
 
5
+ import androidx.annotation.Nullable;
6
+
7
+ import com.facebook.react.bridge.Arguments;
5
8
  import com.facebook.react.bridge.Promise;
9
+ import com.facebook.react.bridge.ReactApplicationContext;
10
+ import com.facebook.react.bridge.ReadableArray;
6
11
  import com.facebook.react.bridge.ReadableMap;
12
+ import com.facebook.react.bridge.ReadableType;
13
+ import com.facebook.react.bridge.WritableArray;
14
+ import com.facebook.react.bridge.WritableMap;
15
+ import com.facebook.react.modules.core.DeviceEventManagerModule;
7
16
  import com.ft.sdk.DBCacheDiscard;
8
17
  import com.ft.sdk.EnvType;
18
+ import com.ft.sdk.FTRemoteConfigManager;
9
19
  import com.ft.sdk.FTSDKConfig;
10
20
  import com.ft.sdk.FTSdk;
11
- import com.ft.sdk.InnerClassProxy;
12
21
  import com.ft.sdk.LineDataModifier;
22
+ import com.ft.sdk.garble.bean.RemoteConfigBean;
13
23
  import com.ft.sdk.garble.bean.UserData;
14
24
  import com.ft.sdk.DataModifier;
15
25
  import com.ft.sdk.reactnative.utils.ReactNativeUtils;
16
26
 
17
27
  import java.util.HashMap;
28
+ import java.util.ArrayList;
29
+ import java.util.List;
18
30
  import java.util.Map;
31
+ import org.json.JSONArray;
32
+ import org.json.JSONException;
33
+ import org.json.JSONObject;
19
34
 
20
35
  public class FTMobileImpl {
21
36
  public static final String NAME = "FTMobileReactNative";
37
+ private static final String REMOTE_CONFIG_EVENT = "ft_remote_config_callback";
38
+ private final ReactApplicationContext reactContext;
39
+ private boolean remoteConfigurationEnabled = false;
40
+ private int remoteConfigMiniUpdateInterval = 12 * 60 * 60;
41
+ @Nullable
42
+ private ReadableArray remoteConfigOverrideRules;
43
+
44
+ public FTMobileImpl(ReactApplicationContext reactContext) {
45
+ this.reactContext = reactContext;
46
+ }
47
+
48
+ private static class RemoteConfigOverrideResult {
49
+ final RemoteConfigBean configBean;
50
+ final List<String> appliedRuleIds;
51
+
52
+ RemoteConfigOverrideResult(RemoteConfigBean configBean, List<String> appliedRuleIds) {
53
+ this.configBean = configBean;
54
+ this.appliedRuleIds = appliedRuleIds;
55
+ }
56
+ }
57
+
58
+ private WritableMap createRemoteConfigPayload(String triggerType,
59
+ boolean success,
60
+ @Nullable String rawJson,
61
+ @Nullable List<String> appliedRuleIds,
62
+ @Nullable String errorCode,
63
+ @Nullable String errorMessage) {
64
+ WritableMap payload = Arguments.createMap();
65
+ payload.putString("triggerType", triggerType);
66
+ payload.putBoolean("success", success);
67
+ payload.putString("platform", "android");
68
+ payload.putDouble("timestamp", System.currentTimeMillis());
69
+ if (rawJson != null) {
70
+ payload.putString("rawJson", rawJson);
71
+ }
72
+ if (appliedRuleIds != null && !appliedRuleIds.isEmpty()) {
73
+ WritableArray ids = Arguments.createArray();
74
+ for (String ruleId : appliedRuleIds) {
75
+ ids.pushString(ruleId);
76
+ }
77
+ payload.putArray("appliedOverrideRuleIds", ids);
78
+ }
79
+ if (errorCode != null) {
80
+ payload.putString("errorCode", errorCode);
81
+ }
82
+ if (errorMessage != null) {
83
+ payload.putString("errorMessage", errorMessage);
84
+ }
85
+ return payload;
86
+ }
87
+
88
+ private void emitRemoteConfigEvent(boolean success, @Nullable String rawJson,
89
+ @Nullable List<String> appliedRuleIds,
90
+ @Nullable String errorCode, @Nullable String errorMessage) {
91
+ if (!reactContext.hasActiveCatalystInstance()) {
92
+ return;
93
+ }
94
+ reactContext
95
+ .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
96
+ .emit(REMOTE_CONFIG_EVENT, createRemoteConfigPayload("auto", success, rawJson, appliedRuleIds, errorCode, errorMessage));
97
+ }
98
+
99
+ private RemoteConfigOverrideResult applyRemoteConfigOverrideRules(RemoteConfigBean configBean,
100
+ @Nullable String jsonConfig) {
101
+ return applyRemoteConfigOverrideRules(configBean, jsonConfig, this.remoteConfigOverrideRules);
102
+ }
103
+
104
+ private RemoteConfigOverrideResult applyRemoteConfigOverrideRules(RemoteConfigBean configBean,
105
+ @Nullable String jsonConfig,
106
+ @Nullable ReadableArray rules) {
107
+ if (configBean == null || jsonConfig == null || rules == null || rules.size() == 0) {
108
+ return new RemoteConfigOverrideResult(configBean, new ArrayList<>());
109
+ }
110
+ List<String> appliedRuleIds = new ArrayList<>();
111
+ try {
112
+ JSONObject jsonObject = new JSONObject(jsonConfig);
113
+ for (int i = 0; i < rules.size(); i++) {
114
+ if (rules.getType(i) != ReadableType.Map) {
115
+ continue;
116
+ }
117
+ ReadableMap rule = rules.getMap(i);
118
+ boolean enabled = !rule.hasKey("enabled") || rule.isNull("enabled") || rule.getBoolean("enabled");
119
+ if (!enabled) {
120
+ continue;
121
+ }
122
+ ReadableMap match = rule.hasKey("match") && !rule.isNull("match") ? rule.getMap("match") : null;
123
+ ReadableMap customKeys = match != null && match.hasKey("customKeys") && !match.isNull("customKeys")
124
+ ? match.getMap("customKeys") : null;
125
+ if (customKeys == null) {
126
+ continue;
127
+ }
128
+ HashMap<String, Object> keyMap = customKeys.toHashMap();
129
+ if (keyMap.isEmpty()) {
130
+ continue;
131
+ }
132
+ boolean matches = true;
133
+ for (Map.Entry<String, Object> entry : keyMap.entrySet()) {
134
+ Object expectedValue = entry.getValue();
135
+ Object actualValue = getJsonValue(jsonObject, entry.getKey());
136
+
137
+ if (!matchesCustomKey(actualValue, expectedValue)) {
138
+ matches = false;
139
+ break;
140
+ }
141
+ }
142
+ if (!matches) {
143
+ continue;
144
+ }
145
+ ReadableMap override = rule.hasKey("override") && !rule.isNull("override") ? rule.getMap("override") : null;
146
+ if (override == null) {
147
+ continue;
148
+ }
149
+
150
+ // Basic configuration properties
151
+ if (override.hasKey("env") && !override.isNull("env")) {
152
+ configBean.setEnv(override.getString("env"));
153
+ }
154
+ if (override.hasKey("serviceName") && !override.isNull("serviceName")) {
155
+ configBean.setServiceName(override.getString("serviceName"));
156
+ }
157
+ if (override.hasKey("autoSync") && !override.isNull("autoSync")) {
158
+ configBean.setAutoSync(override.getBoolean("autoSync"));
159
+ }
160
+ if (override.hasKey("compressIntakeRequests") && !override.isNull("compressIntakeRequests")) {
161
+ configBean.setCompressIntakeRequests(override.getBoolean("compressIntakeRequests"));
162
+ }
163
+ if (override.hasKey("syncPageSize") && !override.isNull("syncPageSize")) {
164
+ configBean.setSyncPageSize(override.getInt("syncPageSize"));
165
+ }
166
+ if (override.hasKey("syncSleepTime") && !override.isNull("syncSleepTime")) {
167
+ configBean.setSyncSleepTime(override.getInt("syncSleepTime"));
168
+ }
169
+
170
+ // Log configuration properties
171
+ if (override.hasKey("logSampleRate") && !override.isNull("logSampleRate")) {
172
+ configBean.setLogSampleRate((float) override.getDouble("logSampleRate"));
173
+ }
174
+ if (override.hasKey("logLevelFilters") && !override.isNull("logLevelFilters")) {
175
+ ReadableArray filtersArray = override.getArray("logLevelFilters");
176
+ String[] filters = new String[filtersArray.size()];
177
+ for (int j = 0; j < filtersArray.size(); j++) {
178
+ filters[j] = filtersArray.getString(j);
179
+ }
180
+ configBean.setLogLevelFilters(filters);
181
+ }
182
+ if (override.hasKey("logEnableCustomLog") && !override.isNull("logEnableCustomLog")) {
183
+ configBean.setLogEnableCustomLog(override.getBoolean("logEnableCustomLog"));
184
+ }
185
+ if (override.hasKey("logEnableConsoleLog") && !override.isNull("logEnableConsoleLog")) {
186
+ configBean.setLogEnableConsoleLog(override.getBoolean("logEnableConsoleLog"));
187
+ }
188
+
189
+ // RUM configuration properties
190
+ if (override.hasKey("rumSampleRate") && !override.isNull("rumSampleRate")) {
191
+ configBean.setRumSampleRate((float) override.getDouble("rumSampleRate"));
192
+ }
193
+ if (override.hasKey("rumSessionOnErrorSampleRate") && !override.isNull("rumSessionOnErrorSampleRate")) {
194
+ configBean.setRumSessionOnErrorSampleRate((float) override.getDouble("rumSessionOnErrorSampleRate"));
195
+ }
196
+ if (override.hasKey("rumEnableTraceUserAction") && !override.isNull("rumEnableTraceUserAction")) {
197
+ configBean.setRumEnableTraceUserAction(override.getBoolean("rumEnableTraceUserAction"));
198
+ }
199
+ if (override.hasKey("rumEnableTraceUserView") && !override.isNull("rumEnableTraceUserView")) {
200
+ configBean.setRumEnableTraceUserView(override.getBoolean("rumEnableTraceUserView"));
201
+ }
202
+ if (override.hasKey("rumEnableTraceUserResource") && !override.isNull("rumEnableTraceUserResource")) {
203
+ configBean.setRumEnableTraceUserResource(override.getBoolean("rumEnableTraceUserResource"));
204
+ }
205
+ if (override.hasKey("rumEnableResourceHostIP") && !override.isNull("rumEnableResourceHostIP")) {
206
+ configBean.setRumEnableResourceHostIP(override.getBoolean("rumEnableResourceHostIP"));
207
+ }
208
+ if (override.hasKey("rumEnableTrackAppUIBlock") && !override.isNull("rumEnableTrackAppUIBlock")) {
209
+ configBean.setRumEnableTrackAppUIBlock(override.getBoolean("rumEnableTrackAppUIBlock"));
210
+ }
211
+ if (override.hasKey("rumBlockDurationMs") && !override.isNull("rumBlockDurationMs")) {
212
+ configBean.setRumBlockDurationMs((long) override.getInt("rumBlockDurationMs"));
213
+ }
214
+ if (override.hasKey("rumEnableTrackAppCrash") && !override.isNull("rumEnableTrackAppCrash")) {
215
+ configBean.setRumEnableTrackAppCrash(override.getBoolean("rumEnableTrackAppCrash"));
216
+ }
217
+ if (override.hasKey("rumEnableTrackAppANR") && !override.isNull("rumEnableTrackAppANR")) {
218
+ configBean.setRumEnableTrackAppANR(override.getBoolean("rumEnableTrackAppANR"));
219
+ }
220
+ if (override.hasKey("rumEnableTraceWebView") && !override.isNull("rumEnableTraceWebView")) {
221
+ configBean.setRumEnableTraceWebView(override.getBoolean("rumEnableTraceWebView"));
222
+ }
223
+ if (override.hasKey("rumAllowWebViewHost") && !override.isNull("rumAllowWebViewHost")) {
224
+ ReadableArray hostsArray = override.getArray("rumAllowWebViewHost");
225
+ String[] hosts = new String[hostsArray.size()];
226
+ for (int j = 0; j < hostsArray.size(); j++) {
227
+ hosts[j] = hostsArray.getString(j);
228
+ }
229
+ configBean.setRumAllowWebViewHost(hosts);
230
+ }
231
+
232
+ // Trace configuration properties
233
+ if (override.hasKey("traceSampleRate") && !override.isNull("traceSampleRate")) {
234
+ configBean.setTraceSampleRate((float) override.getDouble("traceSampleRate"));
235
+ }
236
+ if (override.hasKey("traceEnableAutoTrace") && !override.isNull("traceEnableAutoTrace")) {
237
+ configBean.setTraceEnableAutoTrace(override.getBoolean("traceEnableAutoTrace"));
238
+ }
239
+ if (override.hasKey("traceType") && !override.isNull("traceType")) {
240
+ configBean.setTraceType(override.getString("traceType"));
241
+ }
242
+
243
+ String ruleId = rule.hasKey("id") && !rule.isNull("id") ? rule.getString("id") : null;
244
+ appliedRuleIds.add(ruleId != null ? ruleId : "rule_" + i);
245
+ }
246
+ } catch (JSONException ignored) {
247
+ }
248
+ return new RemoteConfigOverrideResult(configBean, appliedRuleIds);
249
+ }
250
+
251
+ private Object getJsonValue(JSONObject jsonObject, String key) {
252
+ if (!jsonObject.has(key)) {
253
+ return null;
254
+ }
255
+ try {
256
+ Object value = jsonObject.get(key);
257
+ if (value == JSONObject.NULL) {
258
+ return null;
259
+ }
260
+ return value;
261
+ } catch (JSONException e) {
262
+ return null;
263
+ }
264
+ }
265
+
266
+ private boolean isEqualValue(Object actual, Object expected) {
267
+ if (actual == null && expected == null) {
268
+ return true;
269
+ }
270
+ if (actual == null || expected == null) {
271
+ return false;
272
+ }
273
+
274
+ if (actual instanceof String) {
275
+ String actualString = (String) actual;
276
+ Object normalizedActual = parseJsonStringIfNeeded(actualString);
277
+ if (normalizedActual != actual) {
278
+ return isEqualValue(normalizedActual, expected);
279
+ }
280
+ }
281
+
282
+ // Handle number comparison
283
+ if (actual instanceof Number && expected instanceof Number) {
284
+ return ((Number) actual).doubleValue() == ((Number) expected).doubleValue();
285
+ }
286
+
287
+ // Handle string comparison
288
+ if (actual instanceof String && expected instanceof String) {
289
+ return actual.equals(expected);
290
+ }
291
+
292
+ // Handle boolean comparison (JSON booleans are represented as Boolean in Java)
293
+ if (actual instanceof Boolean && expected instanceof Boolean) {
294
+ return actual.equals(expected);
295
+ }
296
+
297
+ // Fallback to string comparison
298
+ return actual.toString().equals(expected.toString());
299
+ }
300
+
301
+ private boolean matchesCustomKey(Object actual, Object expected) {
302
+ if (expected instanceof Map) {
303
+ Map<?, ?> expectedMap = (Map<?, ?>) expected;
304
+ if (expectedMap.containsKey("contains")) {
305
+ return containsValue(actual, expectedMap.get("contains"));
306
+ }
307
+ }
308
+ return isEqualValue(actual, expected);
309
+ }
310
+
311
+ private boolean containsValue(Object actual, Object expectedValue) {
312
+ Object normalizedActual = actual;
313
+ if (actual instanceof String) {
314
+ normalizedActual = parseJsonStringIfNeeded((String) actual);
315
+ }
316
+
317
+ if (normalizedActual instanceof JSONArray) {
318
+ JSONArray actualArray = (JSONArray) normalizedActual;
319
+ try {
320
+ for (int i = 0; i < actualArray.length(); i++) {
321
+ if (isEqualValue(actualArray.get(i), expectedValue)) {
322
+ return true;
323
+ }
324
+ }
325
+ } catch (JSONException ignored) {
326
+ return false;
327
+ }
328
+ }
329
+ return isEqualValue(normalizedActual, expectedValue);
330
+ }
331
+
332
+ private Object parseJsonStringIfNeeded(String value) {
333
+ String trimmedValue = value.trim();
334
+ if (trimmedValue.length() < 2) {
335
+ return value;
336
+ }
337
+ try {
338
+ if (trimmedValue.startsWith("[") && trimmedValue.endsWith("]")) {
339
+ return new JSONArray(trimmedValue);
340
+ }
341
+ } catch (JSONException ignored) {
342
+ return value;
343
+ }
344
+ return value;
345
+ }
346
+
347
+ @Nullable
348
+ private HashMap<String, String[]> convertDataFilters(@Nullable Map<String, Object> filters) {
349
+ if (filters == null) {
350
+ return null;
351
+ }
352
+ HashMap<String, String[]> convertedFilters = new HashMap<>();
353
+ for (Map.Entry<String, Object> entry : filters.entrySet()) {
354
+ Object value = entry.getValue();
355
+ if (!(value instanceof List<?>)) {
356
+ continue;
357
+ }
358
+ List<?> filterList = (List<?>) value;
359
+ List<String> filterValues = new ArrayList<>();
360
+ for (Object filter : filterList) {
361
+ if (filter != null) {
362
+ filterValues.add(filter.toString());
363
+ }
364
+ }
365
+ convertedFilters.put(entry.getKey(), filterValues.toArray(new String[0]));
366
+ }
367
+ return convertedFilters;
368
+ }
22
369
 
23
370
  public void sdkConfig(ReadableMap context, Promise promise) {
24
371
  Map<String, Object> map = context.toHashMap();
@@ -31,15 +378,20 @@ public class FTMobileImpl {
31
378
  Integer syncSleepTime = ReactNativeUtils.convertToNativeInt(map.get("syncSleepTime"));
32
379
  Boolean enableDataIntegerCompatible = (Boolean) map.get("enableDataIntegerCompatible");
33
380
  Boolean compressIntakeRequests = (Boolean) map.get("compressIntakeRequests");
381
+ Boolean enableDataFilter = (Boolean) map.get("enableDataFilter");
382
+ Map<String, Object> dataFilters = (Map<String, Object>) map.get("dataFilters");
34
383
  Integer env = ReactNativeUtils.convertToNativeInt(map.get("envType"));
35
384
  String serviceName = (String) map.get("service");
36
385
  Map<String, Object> globalContext = (Map<String, Object>) map.get("globalContext");
37
386
  Boolean enableLimitWithDbSize = (Boolean) map.get("enableLimitWithDbSize");
38
387
  Long dbCacheLimit = ReactNativeUtils.convertToNativeLong(map.get("dbCacheLimit"));
39
388
  Integer dbDiscardStrategy = ReactNativeUtils.convertToNativeInt(map.get("dbDiscardStrategy"));
40
- String sdkPkgInfo = (String)map.get("pkgInfo");
41
389
  Map<String, Object> dataModifier = (Map<String, Object>) map.get("dataModifier");
42
390
  Map<String, Map<String,Object>> lineDataModifier = (Map<String, Map<String,Object>>) map.get("lineDataModifier");
391
+ Boolean remoteConfiguration = (Boolean) map.get("remoteConfiguration");
392
+ Integer remoteConfigMiniUpdateInterval = ReactNativeUtils.convertToNativeInt(map.get("remoteConfigMiniUpdateInterval"));
393
+ this.remoteConfigOverrideRules = context.hasKey("remoteConfigOverrideRules")
394
+ ? context.getArray("remoteConfigOverrideRules") : null;
43
395
 
44
396
  FTSDKConfig sdkConfig = (datakitUrl != null)
45
397
  ? FTSDKConfig.builder(datakitUrl)
@@ -83,6 +435,13 @@ public class FTMobileImpl {
83
435
  if (compressIntakeRequests != null && compressIntakeRequests) {
84
436
  sdkConfig.setCompressIntakeRequests(compressIntakeRequests);
85
437
  }
438
+ if (enableDataFilter != null) {
439
+ sdkConfig.setEnableDataFilter(enableDataFilter);
440
+ }
441
+ HashMap<String, String[]> convertedDataFilters = convertDataFilters(dataFilters);
442
+ if (convertedDataFilters != null) {
443
+ sdkConfig.setDataFilters(convertedDataFilters);
444
+ }
86
445
  if (globalContext != null) {
87
446
  for (Map.Entry<String, Object> entry : globalContext.entrySet()) {
88
447
  sdkConfig.addGlobalContext(entry.getKey(), entry.getValue().toString());
@@ -103,9 +462,6 @@ public class FTMobileImpl {
103
462
  sdkConfig.setDbCacheDiscard(dbCacheDiscard);
104
463
  }
105
464
 
106
- if(sdkPkgInfo!=null){
107
- InnerClassProxy.addPkgInfo(sdkConfig,"reactnative",sdkPkgInfo);
108
- }
109
465
  if (dataModifier != null) {
110
466
  sdkConfig.setDataModifier(new DataModifier() {
111
467
  @Override
@@ -127,6 +483,40 @@ public class FTMobileImpl {
127
483
  }
128
484
  }
129
485
  );
486
+ }
487
+ if (remoteConfiguration != null) {
488
+ sdkConfig.setRemoteConfiguration(remoteConfiguration);
489
+ }
490
+ remoteConfigurationEnabled = sdkConfig.isRemoteConfiguration();
491
+ if (remoteConfigMiniUpdateInterval != null) {
492
+ sdkConfig.setRemoteConfigMiniUpdateInterval(remoteConfigMiniUpdateInterval);
493
+ this.remoteConfigMiniUpdateInterval = remoteConfigMiniUpdateInterval;
494
+ } else {
495
+ this.remoteConfigMiniUpdateInterval = sdkConfig.getRemoteConfigMiniUpdateInterval();
496
+ }
497
+ if (remoteConfigurationEnabled) {
498
+ sdkConfig.setRemoteConfigurationCallBack(new FTRemoteConfigManager.FetchResult() {
499
+ private String rawJson;
500
+ private List<String> appliedRuleIds = new ArrayList<>();
501
+
502
+ @Override
503
+ public RemoteConfigBean onConfigSuccessFetched(RemoteConfigBean configBean, String jsonConfig) {
504
+ rawJson = jsonConfig;
505
+ RemoteConfigOverrideResult result = applyRemoteConfigOverrideRules(configBean, jsonConfig);
506
+ appliedRuleIds = result.appliedRuleIds;
507
+ emitRemoteConfigEvent(true, configBean.toJsonString(), appliedRuleIds, null, null);
508
+ return result.configBean;
509
+ }
510
+
511
+ @Override
512
+ public void onResult(boolean success) {
513
+ if (!success) {
514
+ emitRemoteConfigEvent(false, rawJson, appliedRuleIds, "FETCH_FAILED", "Remote config update failed");
515
+ }
516
+ rawJson = null;
517
+ appliedRuleIds = new ArrayList<>();
518
+ }
519
+ });
130
520
  }
131
521
  FTSdk.install(sdkConfig);
132
522
  // LogUtils.d("configCheck","sdkConfig:"+new Gson().toJson(sdkConfig));
@@ -160,6 +550,16 @@ public class FTMobileImpl {
160
550
  promise.resolve(null);
161
551
  }
162
552
 
553
+ public void setDatakitURL(String datakitUrl, Promise promise) {
554
+ FTSdk.setDatakitUrl(datakitUrl);
555
+ promise.resolve(null);
556
+ }
557
+
558
+ public void setDatawayURL(String datawayUrl, String clientToken, Promise promise) {
559
+ FTSdk.setDatawayUrl(datawayUrl, clientToken);
560
+ promise.resolve(null);
561
+ }
562
+
163
563
  public void flushSyncData(Promise promise) {
164
564
  FTSdk.flushSyncData();
165
565
  promise.resolve(null);
@@ -195,4 +595,71 @@ public class FTMobileImpl {
195
595
  FTSdk.clearAllData();
196
596
  promise.resolve(null);
197
597
  }
598
+
599
+ public void updateRemoteConfig(Promise promise) {
600
+ if (!remoteConfigurationEnabled) {
601
+ promise.reject("E_REMOTE_CONFIG_DISABLED", "Remote configuration is not enabled.");
602
+ return;
603
+ }
604
+ FTSdk.updateRemoteConfig(remoteConfigMiniUpdateInterval, new FTRemoteConfigManager.FetchResult() {
605
+ private String rawJson;
606
+ private List<String> appliedRuleIds = new ArrayList<>();
607
+
608
+ @Override
609
+ public RemoteConfigBean onConfigSuccessFetched(RemoteConfigBean configBean, String jsonConfig) {
610
+ rawJson = jsonConfig;
611
+ RemoteConfigOverrideResult result = applyRemoteConfigOverrideRules(configBean, jsonConfig);
612
+ appliedRuleIds = result.appliedRuleIds;
613
+ promise.resolve(createRemoteConfigPayload("manual", true, configBean.toJsonString(), appliedRuleIds, null, null));
614
+ return result.configBean;
615
+ }
616
+
617
+ @Override
618
+ public void onResult(boolean success) {
619
+ if (!success) {
620
+ promise.reject("E_REMOTE_CONFIG_UPDATE_FAILED", "Remote config update failed");
621
+ } else if (rawJson == null) {
622
+ promise.resolve(createRemoteConfigPayload("manual", true, null, appliedRuleIds, null, null));
623
+ }
624
+ }
625
+ });
626
+ }
627
+
628
+ public void updateRemoteConfigWithMiniUpdateInterval(int interval, @Nullable ReadableArray rules, Promise promise) {
629
+ if (!remoteConfigurationEnabled) {
630
+ promise.reject("E_REMOTE_CONFIG_DISABLED", "Remote configuration is not enabled.");
631
+ return;
632
+ }
633
+ FTSdk.updateRemoteConfig(interval, new FTRemoteConfigManager.FetchResult() {
634
+ private String rawJson;
635
+ private List<String> appliedRuleIds = new ArrayList<>();
636
+
637
+ @Override
638
+ public RemoteConfigBean onConfigSuccessFetched(RemoteConfigBean configBean, String jsonConfig) {
639
+ rawJson = jsonConfig;
640
+ ReadableArray rulesToApply = rules != null && rules.size() > 0 ? rules : remoteConfigOverrideRules;
641
+ RemoteConfigOverrideResult result = applyRemoteConfigOverrideRules(configBean, jsonConfig, rulesToApply);
642
+ appliedRuleIds = result.appliedRuleIds;
643
+ promise.resolve(createRemoteConfigPayload("manual", true, configBean.toJsonString(), appliedRuleIds, null, null));
644
+ return result.configBean;
645
+ }
646
+
647
+ @Override
648
+ public void onResult(boolean success) {
649
+ if (!success) {
650
+ promise.reject("E_REMOTE_CONFIG_UPDATE_FAILED", "Remote config update failed");
651
+ } else if (rawJson == null) {
652
+ promise.resolve(createRemoteConfigPayload("manual", true, null, appliedRuleIds, null, null));
653
+ }
654
+ }
655
+ });
656
+ }
657
+
658
+ public void addListener(String eventName) {
659
+ // Required for NativeEventEmitter. No-op because native does not need listener bookkeeping.
660
+ }
661
+
662
+ public void removeListeners(double count) {
663
+ // Required for NativeEventEmitter. No-op because native does not need listener bookkeeping.
664
+ }
198
665
  }
@@ -15,6 +15,7 @@ import com.ft.sdk.garble.bean.NetStatusBean;
15
15
  import com.ft.sdk.garble.bean.ResourceParams;
16
16
  import com.ft.sdk.reactnative.utils.ReactNativeUtils;
17
17
 
18
+ import java.util.ArrayList;
18
19
  import java.util.HashMap;
19
20
  import java.util.Map;
20
21
 
@@ -44,6 +45,8 @@ public class FTRUMImpl {
44
45
  Map<String, Object> globalContext = (Map<String, Object>) map.get("globalContext");
45
46
  Integer rumCacheLimitCount = ReactNativeUtils.convertToNativeInt(map.get("rumCacheLimitCount"));
46
47
  Integer rumDiscardStrategy = ReactNativeUtils.convertToNativeInt(map.get("rumDiscardStrategy"));
48
+ Boolean enableTraceWebView = (Boolean) map.get("enableTraceWebView");
49
+ ArrayList<String> allowWebViewHost = (ArrayList<String>) map.get("allowWebViewHost");
47
50
 
48
51
  FTRUMConfig rumConfig = new FTRUMConfig().setRumAppId(rumAppId);
49
52
  if (sampleRate != null) {
@@ -122,6 +125,15 @@ public class FTRUMImpl {
122
125
  }
123
126
  rumConfig.setRumCacheDiscardStrategy(rumCacheDiscard);
124
127
  }
128
+ if (enableTraceWebView != null) {
129
+ rumConfig.setEnableTraceWebView(enableTraceWebView);
130
+ }
131
+ if (allowWebViewHost != null) {
132
+ String[] allowWebViewHostArr = new String[allowWebViewHost.size()];
133
+ allowWebViewHost.toArray(allowWebViewHostArr);
134
+ rumConfig.setAllowWebViewHost(allowWebViewHostArr);
135
+ }
136
+
125
137
  FTSdk.initRUMWithConfig(rumConfig);
126
138
  //LogUtils.d("configCheck","rumConfig:"+new Gson().toJson(rumConfig));
127
139
  promise.resolve(null);