@ansight/react-native 1.0.2-preview.1 → 1.0.2-preview.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.
package/README.md CHANGED
@@ -25,8 +25,8 @@ npx react-native run-android
25
25
 
26
26
  This package version expects matching native SDK packages:
27
27
 
28
- - CocoaPods: `Ansight`, `AnsightObjC` version `1.0.2-preview.1`
29
- - Maven: `ai.ansight:ansight-android:1.0.2-preview.1`
28
+ - CocoaPods: `Ansight`, `AnsightObjC` version `1.0.2-preview.2`
29
+ - Maven: `ai.ansight:ansight-android:1.0.2-preview.2`
30
30
 
31
31
  ## Quickstart
32
32
 
@@ -59,6 +59,11 @@ does not infer whether the app is a debug build. Gate it with the app's own
59
59
  condition, such as React Native's `__DEV__`, and configure `toolGuard`, capture
60
60
  options, host auto-probe, and host connection separately.
61
61
 
62
+ > **Important:** Screen capture will result in an FPS drop while native frames
63
+ > are rendered, encoded, and sent. Use conservative interval, quality, and
64
+ > max-width settings, and disable `sessionJpegCapture` for performance-focused
65
+ > runs unless visual evidence is required.
66
+
62
67
  ## Options
63
68
 
64
69
  The TypeScript `AnsightOptions` surface mirrors Android `AnsightOptions`, iOS
@@ -66,7 +71,7 @@ The TypeScript `AnsightOptions` surface mirrors Android `AnsightOptions`, iOS
66
71
 
67
72
  | Option | Purpose |
68
73
  | --- | --- |
69
- | `useNativeAllInOneDefaults` | Applies native iOS/Android all-in-one defaults when true. Defaults to false. This is not a master enable switch; configure `toolGuard`, capture options, and `hostConnection` separately. |
74
+ | `useNativeAllInOneDefaults` | Applies native iOS/Android all-in-one defaults when true. Defaults to false. This enables the native visual-tree/screenshot tools required by Studio visual tree inspection unless `remoteTools.visualTree` is explicitly false. Configure `toolGuard`, capture options, and `hostConnection` separately. |
70
75
  | `pairingConfigJson` | Legacy top-level pairing JSON. Prefer `hostConnection.*`. |
71
76
  | `clientName` | Default client name for host auto-probe and connections. |
72
77
  | `sampleFrequencyMilliseconds` | Built-in telemetry sampling interval. |
@@ -76,7 +81,7 @@ The TypeScript `AnsightOptions` surface mirrors Android `AnsightOptions`, iOS
76
81
  | `defaultMemoryChannels` | Selects built-in memory channels. Prefer `managedHeap`, `nativeHeap`, `residentSetSize`, and `physicalFootprint`; `javaHeap` and `rss` are accepted as Android/RN compatibility aliases. |
77
82
  | `reactNativeMemory` | Controls native React Native runtime memory channels. Enabled by default; set to `false` to disable, or use `{ jsHeapUsed, jsHeapTotal }`. |
78
83
  | `additionalChannels` | Registers custom metric channels. |
79
- | `sessionJpegCapture` | Object to enable/configure capture, or `false` to disable. |
84
+ | `sessionJpegCapture` | Object to enable/configure capture, or `false` to disable. Supports `captureGpuBackedSurfaces`; on iOS it defaults to `true` so Metal, SceneKit, and similar GPU-backed views are included. |
80
85
  | `touchCapture` | Object to enable/configure capture, or `false` to disable. |
81
86
  | `lifecycleCapture` | Native lifecycle and screen-view capture options. |
82
87
  | `toolGuard` | `"disabled"`, `"readOnly"`, `"readWrite"`, or `"fullAccess"`. |
@@ -97,6 +102,7 @@ await Ansight.initializeAndActivate({
97
102
  intervalMilliseconds: 2000,
98
103
  quality: 60,
99
104
  maxWidth: 480,
105
+ captureGpuBackedSurfaces: true,
100
106
  },
101
107
  touchCapture: {
102
108
  captureMoveEvents: true,
@@ -111,9 +117,13 @@ await Ansight.initializeAndActivate({
111
117
  });
112
118
  ```
113
119
 
120
+ On iOS, `captureGpuBackedSurfaces` defaults to `true` so Metal, SceneKit, and
121
+ similar GPU-backed views are included. Set it to `false` to use a lower-overhead
122
+ capture path when those surfaces are not needed.
123
+
114
124
  ## Native Tool Options
115
125
 
116
- `remoteTools` configures the native tool suites registered by the bridge. Visual tree tools are opt-in:
126
+ `remoteTools` configures the native tool suites registered by the bridge. `useNativeAllInOneDefaults: true` enables visual tree tools by default so Studio can pair `ui.get_visual_tree` data with `ui.get_screenshot` frames. Apps that do not use all-in-one defaults can opt in explicitly:
117
127
 
118
128
  ```ts
119
129
  await Ansight.initializeAndActivate(
@@ -406,7 +416,11 @@ const snapshot = await Ansight.snapshot();
406
416
  const options = await Ansight.currentOptions();
407
417
 
408
418
  await Ansight.captureBuiltInTelemetrySample();
409
- await Ansight.captureScreenFrame({ quality: 60, maxWidth: 480 });
419
+ await Ansight.captureScreenFrame({
420
+ quality: 60,
421
+ maxWidth: 480,
422
+ captureGpuBackedSurfaces: true,
423
+ });
410
424
  await Ansight.enableTouchCapture();
411
425
  await Ansight.disableTouchCapture();
412
426
  ```
@@ -66,5 +66,5 @@ repositories {
66
66
 
67
67
  dependencies {
68
68
  implementation("com.facebook.react:react-android")
69
- implementation("ai.ansight:ansight-android:1.0.2-preview.1")
69
+ implementation("ai.ansight:ansight-android:1.0.2-preview.2")
70
70
  }
@@ -702,6 +702,10 @@ class AnsightReactNativeModule(
702
702
  ),
703
703
  quality = jpeg.intValue("quality", AnsightSessionJpegCaptureOptions.DefaultQuality),
704
704
  maxWidth = jpeg.optionalInt("maxWidth") ?: AnsightSessionJpegCaptureOptions.DefaultMaxWidth,
705
+ captureGpuBackedSurfaces = jpeg.booleanValue(
706
+ "captureGpuBackedSurfaces",
707
+ AnsightSessionJpegCaptureOptions.DefaultCaptureGpuBackedSurfaces,
708
+ ),
705
709
  )
706
710
  },
707
711
  )
@@ -762,13 +766,19 @@ class AnsightReactNativeModule(
762
766
  ),
763
767
  )
764
768
  }
765
- return options.withNativeToolOptions(map)
769
+ return options.withNativeToolOptions(
770
+ map,
771
+ enableVisualTreeToolsByDefault = useNativeAllInOneDefaults,
772
+ )
766
773
  }
767
774
 
768
- private fun AnsightOptions.withNativeToolOptions(map: ReadableMap?): AnsightOptions {
775
+ private fun AnsightOptions.withNativeToolOptions(
776
+ map: ReadableMap?,
777
+ enableVisualTreeToolsByDefault: Boolean,
778
+ ): AnsightOptions {
769
779
  val remoteTools = map.getMapOrNull("remoteTools")
770
780
  val builder = AnsightOptions.createBuilder(this)
771
- if (remoteTools.toolSuiteEnabled("visualTree")) {
781
+ if (remoteTools.toolSuiteEnabled("visualTree", enableVisualTreeToolsByDefault)) {
772
782
  builder.withVisualTreeTools()
773
783
  }
774
784
  builder.withDatabaseTools(databaseToolsOptions(remoteTools.getMapOrNull("database")))
@@ -868,6 +878,10 @@ class AnsightReactNativeModule(
868
878
  ),
869
879
  quality = map.intValue("quality", AnsightSessionJpegCaptureOptions.DefaultQuality),
870
880
  maxWidth = map.optionalInt("maxWidth") ?: AnsightSessionJpegCaptureOptions.DefaultMaxWidth,
881
+ captureGpuBackedSurfaces = map.booleanValue(
882
+ "captureGpuBackedSurfaces",
883
+ AnsightSessionJpegCaptureOptions.DefaultCaptureGpuBackedSurfaces,
884
+ ),
871
885
  )
872
886
  }
873
887
 
@@ -1058,6 +1072,7 @@ class AnsightReactNativeModule(
1058
1072
  "intervalMilliseconds" to capture.intervalMilliseconds,
1059
1073
  "quality" to capture.quality,
1060
1074
  "maxWidth" to capture.maxWidth,
1075
+ "captureGpuBackedSurfaces" to capture.captureGpuBackedSurfaces,
1061
1076
  ).toWritableMap())
1062
1077
  } ?: putNull("sessionJpegCapture")
1063
1078
  options.touchCapture?.let { touch ->
@@ -1206,9 +1221,12 @@ private fun ReadableMap?.hasBoolean(name: String): Boolean = this?.hasKey(name)
1206
1221
  private fun ReadableMap?.hasMap(name: String): Boolean = this?.hasKey(name) == true && this.getType(name) == ReadableType.Map
1207
1222
  private fun ReadableMap?.hasArray(name: String): Boolean = this?.hasKey(name) == true && this.getType(name) == ReadableType.Array
1208
1223
  private fun ReadableMap?.isFalse(name: String): Boolean = this?.hasBoolean(name) == true && !this.getBoolean(name)
1209
- private fun ReadableMap?.toolSuiteEnabled(name: String): Boolean {
1210
- val map = this ?: return false
1211
- if (!map.hasKey(name) || map.isNull(name)) {
1224
+ private fun ReadableMap?.toolSuiteEnabled(name: String, defaultValue: Boolean = false): Boolean {
1225
+ val map = this ?: return defaultValue
1226
+ if (!map.hasKey(name)) {
1227
+ return defaultValue
1228
+ }
1229
+ if (map.isNull(name)) {
1212
1230
  return false
1213
1231
  }
1214
1232
  return when (map.getType(name)) {
package/index.d.ts CHANGED
@@ -36,6 +36,7 @@ export interface AnsightSessionJpegCaptureOptions {
36
36
  intervalMilliseconds?: number;
37
37
  quality?: number;
38
38
  maxWidth?: number;
39
+ captureGpuBackedSurfaces?: boolean;
39
40
  }
40
41
 
41
42
  export interface AnsightTouchCaptureOptions {
@@ -261,7 +262,12 @@ export class AnsightOptionsBuilder {
261
262
  withReactNativeMemoryProfiling(options?: AnsightReactNativeMemoryOptions): this;
262
263
  withoutReactNativeMemoryProfiling(): this;
263
264
  withSessionJpegCapture(options?: AnsightSessionJpegCaptureOptions): this;
264
- withSessionJpegCapture(intervalMilliseconds: number, quality?: number, maxWidth?: number | null): this;
265
+ withSessionJpegCapture(
266
+ intervalMilliseconds: number,
267
+ quality?: number,
268
+ maxWidth?: number | null,
269
+ captureGpuBackedSurfaces?: boolean
270
+ ): this;
265
271
  withoutSessionJpegCapture(): this;
266
272
  withTouchCapture(touchCapture?: AnsightTouchCaptureOptions): this;
267
273
  withoutTouchCapture(): this;
package/index.js CHANGED
@@ -267,6 +267,7 @@ class AnsightOptionsBuilder {
267
267
  intervalMilliseconds: optionsOrIntervalMilliseconds,
268
268
  quality: arguments.length > 1 ? arguments[1] : 60,
269
269
  maxWidth: arguments.length > 2 ? arguments[2] : 480,
270
+ captureGpuBackedSurfaces: arguments.length > 3 ? arguments[3] : true,
270
271
  };
271
272
  return this;
272
273
  }
@@ -925,7 +925,12 @@ final class AnsightReactNative: RCTEventEmitter {
925
925
  defaultValue: AnsightSessionJpegCaptureOptions.defaultIntervalMilliseconds
926
926
  ),
927
927
  quality: intValue(jpeg, "quality", defaultValue: AnsightSessionJpegCaptureOptions.defaultQuality),
928
- maxWidth: optionalInt(jpeg, "maxWidth") ?? AnsightSessionJpegCaptureOptions.defaultMaxWidth
928
+ maxWidth: optionalInt(jpeg, "maxWidth") ?? AnsightSessionJpegCaptureOptions.defaultMaxWidth,
929
+ captureGpuBackedSurfaces: boolValue(
930
+ jpeg,
931
+ "captureGpuBackedSurfaces",
932
+ defaultValue: AnsightSessionJpegCaptureOptions.defaultCaptureGpuBackedSurfaces
933
+ )
929
934
  )
930
935
  }
931
936
  }
@@ -982,8 +987,12 @@ final class AnsightReactNative: RCTEventEmitter {
982
987
 
983
988
  private func remoteToolOptions(_ dictionary: NSDictionary?) -> AnsightRemoteToolOptions {
984
989
  let remoteTools = dictionary?["remoteTools"] as? NSDictionary
990
+ let useNativeAllInOneDefaults = boolValue(dictionary, "useNativeAllInOneDefaults", defaultValue: false)
985
991
  return AnsightRemoteToolOptions(
986
- visualTree: toolSuiteEnabled(remoteTools?["visualTree"]),
992
+ visualTree: toolSuiteEnabled(
993
+ remoteTools?["visualTree"],
994
+ defaultValue: useNativeAllInOneDefaults
995
+ ),
987
996
  database: databaseToolsOptions(remoteTools?["database"] as? NSDictionary),
988
997
  fileSystem: fileSystemToolsOptions(remoteTools?["fileSystem"] as? NSDictionary),
989
998
  preferences: preferencesToolsOptions(remoteTools?["preferences"] as? NSDictionary),
@@ -994,14 +1003,14 @@ final class AnsightReactNative: RCTEventEmitter {
994
1003
  )
995
1004
  }
996
1005
 
997
- private func toolSuiteEnabled(_ value: Any?) -> Bool {
1006
+ private func toolSuiteEnabled(_ value: Any?, defaultValue: Bool = false) -> Bool {
998
1007
  if let enabled = value as? Bool {
999
1008
  return enabled
1000
1009
  }
1001
1010
  if let dictionary = value as? NSDictionary {
1002
1011
  return boolValue(dictionary, "enabled", defaultValue: true)
1003
1012
  }
1004
- return false
1013
+ return defaultValue
1005
1014
  }
1006
1015
 
1007
1016
  private func fileSystemToolsOptions(_ dictionary: NSDictionary?) -> AnsightFileSystemToolsOptions {
@@ -1241,7 +1250,12 @@ final class AnsightReactNative: RCTEventEmitter {
1241
1250
  defaultValue: AnsightSessionJpegCaptureOptions.defaultIntervalMilliseconds
1242
1251
  ),
1243
1252
  quality: intValue(dictionary, "quality", defaultValue: AnsightSessionJpegCaptureOptions.defaultQuality),
1244
- maxWidth: optionalInt(dictionary, "maxWidth") ?? AnsightSessionJpegCaptureOptions.defaultMaxWidth
1253
+ maxWidth: optionalInt(dictionary, "maxWidth") ?? AnsightSessionJpegCaptureOptions.defaultMaxWidth,
1254
+ captureGpuBackedSurfaces: boolValue(
1255
+ dictionary,
1256
+ "captureGpuBackedSurfaces",
1257
+ defaultValue: AnsightSessionJpegCaptureOptions.defaultCaptureGpuBackedSurfaces
1258
+ )
1245
1259
  )
1246
1260
  }
1247
1261
 
@@ -1289,6 +1303,7 @@ final class AnsightReactNative: RCTEventEmitter {
1289
1303
  "intervalMilliseconds": capture.intervalMilliseconds,
1290
1304
  "quality": capture.quality,
1291
1305
  "maxWidth": capture.maxWidth as Any,
1306
+ "captureGpuBackedSurfaces": capture.captureGpuBackedSurfaces,
1292
1307
  ]
1293
1308
  } else {
1294
1309
  dictionary["sessionJpegCapture"] = NSNull()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ansight/react-native",
3
- "version": "1.0.2-preview.1",
3
+ "version": "1.0.2-preview.2",
4
4
  "description": "React Native bridge for the Ansight mobile SDK.",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",