@ansight/react-native 1.0.2-preview.1 → 1.0.2-preview.3
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.
|
|
29
|
-
- Maven: `ai.ansight:ansight-android:1.0.2-preview.
|
|
28
|
+
- CocoaPods: `Ansight`, `AnsightObjC` version `1.0.2-preview.3`
|
|
29
|
+
- Maven: `ai.ansight:ansight-android:1.0.2-preview.3`
|
|
30
30
|
|
|
31
31
|
## Quickstart
|
|
32
32
|
|
|
@@ -38,6 +38,13 @@ const isDevelopmentOnly = __DEV__;
|
|
|
38
38
|
await Ansight.initializeAndActivate({
|
|
39
39
|
useNativeAllInOneDefaults: isDevelopmentOnly,
|
|
40
40
|
clientName: "My React Native App",
|
|
41
|
+
hostAutoProbe: {
|
|
42
|
+
enabled: isDevelopmentOnly,
|
|
43
|
+
initialDelayMilliseconds: 1000,
|
|
44
|
+
probeIntervalMilliseconds: 5000,
|
|
45
|
+
reconnectDelayMilliseconds: 10000,
|
|
46
|
+
clientName: "My React Native App",
|
|
47
|
+
},
|
|
41
48
|
hostConnection: isDevelopmentOnly ? {
|
|
42
49
|
bundledDeveloperConfigJson: process.env.EXPO_PUBLIC_ANSIGHT_PAIRING_CONFIG_JSON,
|
|
43
50
|
} : undefined,
|
|
@@ -59,6 +66,19 @@ does not infer whether the app is a debug build. Gate it with the app's own
|
|
|
59
66
|
condition, such as React Native's `__DEV__`, and configure `toolGuard`, capture
|
|
60
67
|
options, host auto-probe, and host connection separately.
|
|
61
68
|
|
|
69
|
+
Host auto-probe uses the native iOS/Android remembered-host retry behavior.
|
|
70
|
+
When enabled and the runtime is active, it retries previous host connections so
|
|
71
|
+
the app can reconnect after the host disappears and later reappears. Probing
|
|
72
|
+
pauses while a live session is connected and resumes after
|
|
73
|
+
`reconnectDelayMilliseconds` when that session is lost. Use
|
|
74
|
+
`withoutHostAutoProbe()` or set `hostAutoProbe.enabled` to `false` for flows
|
|
75
|
+
where reconnects should only happen after an explicit app action.
|
|
76
|
+
|
|
77
|
+
> **Important:** Screen capture will result in an FPS drop while native frames
|
|
78
|
+
> are rendered, encoded, and sent. Use conservative interval, quality, and
|
|
79
|
+
> max-width settings, and disable `sessionJpegCapture` for performance-focused
|
|
80
|
+
> runs unless visual evidence is required.
|
|
81
|
+
|
|
62
82
|
## Options
|
|
63
83
|
|
|
64
84
|
The TypeScript `AnsightOptions` surface mirrors Android `AnsightOptions`, iOS
|
|
@@ -66,7 +86,7 @@ The TypeScript `AnsightOptions` surface mirrors Android `AnsightOptions`, iOS
|
|
|
66
86
|
|
|
67
87
|
| Option | Purpose |
|
|
68
88
|
| --- | --- |
|
|
69
|
-
| `useNativeAllInOneDefaults` | Applies native iOS/Android all-in-one defaults when true. Defaults to false. This
|
|
89
|
+
| `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
90
|
| `pairingConfigJson` | Legacy top-level pairing JSON. Prefer `hostConnection.*`. |
|
|
71
91
|
| `clientName` | Default client name for host auto-probe and connections. |
|
|
72
92
|
| `sampleFrequencyMilliseconds` | Built-in telemetry sampling interval. |
|
|
@@ -76,12 +96,12 @@ The TypeScript `AnsightOptions` surface mirrors Android `AnsightOptions`, iOS
|
|
|
76
96
|
| `defaultMemoryChannels` | Selects built-in memory channels. Prefer `managedHeap`, `nativeHeap`, `residentSetSize`, and `physicalFootprint`; `javaHeap` and `rss` are accepted as Android/RN compatibility aliases. |
|
|
77
97
|
| `reactNativeMemory` | Controls native React Native runtime memory channels. Enabled by default; set to `false` to disable, or use `{ jsHeapUsed, jsHeapTotal }`. |
|
|
78
98
|
| `additionalChannels` | Registers custom metric channels. |
|
|
79
|
-
| `sessionJpegCapture` | Object to enable/configure capture, or `false` to disable. |
|
|
99
|
+
| `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
100
|
| `touchCapture` | Object to enable/configure capture, or `false` to disable. |
|
|
81
101
|
| `lifecycleCapture` | Native lifecycle and screen-view capture options. |
|
|
82
102
|
| `toolGuard` | `"disabled"`, `"readOnly"`, `"readWrite"`, or `"fullAccess"`. |
|
|
83
103
|
| `customProperties` | Grouped string properties sent with `session.open`. |
|
|
84
|
-
| `hostAutoProbe` |
|
|
104
|
+
| `hostAutoProbe` | Remembered-host retry settings for reconnecting after the host disappears and later reappears. |
|
|
85
105
|
| `hostConnection` | Saved, bundled, and developer pairing settings. |
|
|
86
106
|
| `secureStorage` | Compatibility alias for native secure-storage allow-list settings. |
|
|
87
107
|
| `remoteTools` | Native visual tree, file, database, preferences, reflection, and secure-storage tool options. |
|
|
@@ -97,6 +117,7 @@ await Ansight.initializeAndActivate({
|
|
|
97
117
|
intervalMilliseconds: 2000,
|
|
98
118
|
quality: 60,
|
|
99
119
|
maxWidth: 480,
|
|
120
|
+
captureGpuBackedSurfaces: true,
|
|
100
121
|
},
|
|
101
122
|
touchCapture: {
|
|
102
123
|
captureMoveEvents: true,
|
|
@@ -106,14 +127,21 @@ await Ansight.initializeAndActivate({
|
|
|
106
127
|
},
|
|
107
128
|
hostAutoProbe: {
|
|
108
129
|
enabled: true,
|
|
130
|
+
initialDelayMilliseconds: 1000,
|
|
131
|
+
probeIntervalMilliseconds: 5000,
|
|
132
|
+
reconnectDelayMilliseconds: 10000,
|
|
109
133
|
clientName: "My React Native App",
|
|
110
134
|
},
|
|
111
135
|
});
|
|
112
136
|
```
|
|
113
137
|
|
|
138
|
+
On iOS, `captureGpuBackedSurfaces` defaults to `true` so Metal, SceneKit, and
|
|
139
|
+
similar GPU-backed views are included. Set it to `false` to use a lower-overhead
|
|
140
|
+
capture path when those surfaces are not needed.
|
|
141
|
+
|
|
114
142
|
## Native Tool Options
|
|
115
143
|
|
|
116
|
-
`remoteTools` configures the native tool suites registered by the bridge.
|
|
144
|
+
`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
145
|
|
|
118
146
|
```ts
|
|
119
147
|
await Ansight.initializeAndActivate(
|
|
@@ -147,6 +175,12 @@ await Ansight.initializeAndActivate(
|
|
|
147
175
|
);
|
|
148
176
|
```
|
|
149
177
|
|
|
178
|
+
`reflect.list_roots` reports a `hostRuntime` descriptor on each root. Current
|
|
179
|
+
React Native reflection roots are hosted by the native iOS or Android runtime;
|
|
180
|
+
future JavaScript reflection roots should report `kind: "javascript"` and
|
|
181
|
+
`bridge: "react-native"` so callers can route reflection requests to the
|
|
182
|
+
correct runtime boundary.
|
|
183
|
+
|
|
150
184
|
`secureStorage.preferencesName` is Android-specific. `secureStorage.appleService`
|
|
151
185
|
is iOS-specific. The top-level `secureStorage` option is still accepted as a
|
|
152
186
|
compatibility alias for `remoteTools.secureStorage`.
|
|
@@ -165,7 +199,7 @@ await Ansight.connect(null, {
|
|
|
165
199
|
Automatic connection tries:
|
|
166
200
|
|
|
167
201
|
1. `hostConnection.bundledDeveloperConfigJson`
|
|
168
|
-
2. native
|
|
202
|
+
2. native remembered host profiles, newest first
|
|
169
203
|
3. saved pairing config
|
|
170
204
|
4. `hostConnection.bundledConfigJson`
|
|
171
205
|
|
|
@@ -406,7 +440,11 @@ const snapshot = await Ansight.snapshot();
|
|
|
406
440
|
const options = await Ansight.currentOptions();
|
|
407
441
|
|
|
408
442
|
await Ansight.captureBuiltInTelemetrySample();
|
|
409
|
-
await Ansight.captureScreenFrame({
|
|
443
|
+
await Ansight.captureScreenFrame({
|
|
444
|
+
quality: 60,
|
|
445
|
+
maxWidth: 480,
|
|
446
|
+
captureGpuBackedSurfaces: true,
|
|
447
|
+
});
|
|
410
448
|
await Ansight.enableTouchCapture();
|
|
411
449
|
await Ansight.disableTouchCapture();
|
|
412
450
|
```
|
package/android/build.gradle
CHANGED
|
@@ -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(
|
|
769
|
+
return options.withNativeToolOptions(
|
|
770
|
+
map,
|
|
771
|
+
enableVisualTreeToolsByDefault = useNativeAllInOneDefaults,
|
|
772
|
+
)
|
|
766
773
|
}
|
|
767
774
|
|
|
768
|
-
private fun AnsightOptions.withNativeToolOptions(
|
|
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
|
|
1211
|
-
if (!map.hasKey(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(
|
|
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(
|
|
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
|
|
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
|
|
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()
|