@ansight/react-native 1.3.0-preview.1 → 1.3.0-preview.11
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 +65 -3
- package/android/build.gradle +2 -2
- package/android/src/main/kotlin/ai/ansight/reactnative/AnsightReactNativeModule.kt +97 -8
- package/index.d.ts +127 -2
- package/index.js +375 -34
- package/ios/AnsightReactNative.swift +104 -7
- package/ios/AnsightReactNativeModule.m +8 -0
- package/network.js +764 -0
- package/package.json +5 -2
- package/session-properties.js +151 -0
|
@@ -139,6 +139,7 @@ final class AnsightReactNative: RCTEventEmitter {
|
|
|
139
139
|
|
|
140
140
|
private let lock = NSLock()
|
|
141
141
|
private var hasListeners = false
|
|
142
|
+
private var hostConnectionStatusSubscription: HostConnectionStatusSubscription?
|
|
142
143
|
private var activeCustomToolIds: Set<String> = []
|
|
143
144
|
private var pendingToolCalls: [String: PendingToolCall] = [:]
|
|
144
145
|
private var reactNativeMemorySampler: ReactNativeMemorySamplerBox?
|
|
@@ -150,10 +151,14 @@ final class AnsightReactNative: RCTEventEmitter {
|
|
|
150
151
|
override init() {
|
|
151
152
|
super.init()
|
|
152
153
|
AnsightLogger.registerCallback(logCallback)
|
|
154
|
+
hostConnectionStatusSubscription = AnsightRuntime.shared.addHostConnectionStatusListener { [weak self] status, _ in
|
|
155
|
+
self?.emitHostConnectionStatusEvent(status)
|
|
156
|
+
}
|
|
153
157
|
}
|
|
154
158
|
|
|
155
159
|
deinit {
|
|
156
160
|
AnsightLogger.removeCallback(logCallback)
|
|
161
|
+
hostConnectionStatusSubscription?.remove()
|
|
157
162
|
}
|
|
158
163
|
|
|
159
164
|
override static func requiresMainQueueSetup() -> Bool {
|
|
@@ -161,7 +166,7 @@ final class AnsightReactNative: RCTEventEmitter {
|
|
|
161
166
|
}
|
|
162
167
|
|
|
163
168
|
override func supportedEvents() -> [String]! {
|
|
164
|
-
["AnsightToolCall", "AnsightLog"]
|
|
169
|
+
["AnsightToolCall", "AnsightLog", "AnsightHostConnectionStatus"]
|
|
165
170
|
}
|
|
166
171
|
|
|
167
172
|
override func startObserving() {
|
|
@@ -292,6 +297,52 @@ final class AnsightReactNative: RCTEventEmitter {
|
|
|
292
297
|
}
|
|
293
298
|
}
|
|
294
299
|
|
|
300
|
+
@objc(recordNetworkRequest:resolver:rejecter:)
|
|
301
|
+
func recordNetworkRequest(
|
|
302
|
+
_ input: NSDictionary,
|
|
303
|
+
resolver resolve: @escaping RCTPromiseResolveBlock,
|
|
304
|
+
rejecter reject: RCTPromiseRejectBlock
|
|
305
|
+
) {
|
|
306
|
+
guard JSONSerialization.isValidJSONObject(input),
|
|
307
|
+
let data = try? JSONSerialization.data(withJSONObject: input),
|
|
308
|
+
let request = try? JSONDecoder().decode(AnsightNetworkRequest.self, from: data),
|
|
309
|
+
request.schema == AnsightNetworkRequest.schemaName
|
|
310
|
+
else {
|
|
311
|
+
resolve(operationResultDictionary(
|
|
312
|
+
.failure("Network request must use the ansight.network-request.v1 schema.")
|
|
313
|
+
))
|
|
314
|
+
return
|
|
315
|
+
}
|
|
316
|
+
Task {
|
|
317
|
+
resolve(operationResultDictionary(await AnsightRuntime.shared.recordNetworkRequest(request)))
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
@objc(recordCrashCandidate:resolver:rejecter:)
|
|
322
|
+
func recordCrashCandidate(
|
|
323
|
+
_ input: NSDictionary,
|
|
324
|
+
resolver resolve: RCTPromiseResolveBlock,
|
|
325
|
+
rejecter reject: RCTPromiseRejectBlock
|
|
326
|
+
) {
|
|
327
|
+
let metadata: [String: String]
|
|
328
|
+
if let metadataJson = stringValue(input, "metadata"),
|
|
329
|
+
let data = metadataJson.data(using: .utf8),
|
|
330
|
+
let decoded = try? JSONDecoder().decode([String: String].self, from: data) {
|
|
331
|
+
metadata = decoded
|
|
332
|
+
} else {
|
|
333
|
+
metadata = [:]
|
|
334
|
+
}
|
|
335
|
+
let candidateId = AnsightRuntime.shared.recordCrashCandidate(
|
|
336
|
+
runtime: stringValue(input, "runtime") ?? "react-native-javascript",
|
|
337
|
+
kind: stringValue(input, "kind") ?? "unhandled_javascript_error",
|
|
338
|
+
message: stringValue(input, "message"),
|
|
339
|
+
stack: stringValue(input, "stack"),
|
|
340
|
+
fatal: boolValue(input, "fatal", defaultValue: false),
|
|
341
|
+
metadata: metadata
|
|
342
|
+
)
|
|
343
|
+
resolve(candidateId.map { ["candidateId": $0] } ?? [:])
|
|
344
|
+
}
|
|
345
|
+
|
|
295
346
|
@objc(screenViewed:details:resolver:rejecter:)
|
|
296
347
|
func screenViewed(
|
|
297
348
|
_ name: NSString,
|
|
@@ -834,6 +885,17 @@ final class AnsightReactNative: RCTEventEmitter {
|
|
|
834
885
|
}
|
|
835
886
|
}
|
|
836
887
|
|
|
888
|
+
private func emitHostConnectionStatusEvent(_ status: HostConnectionStatus) {
|
|
889
|
+
let shouldEmit = lock.withLock { hasListeners }
|
|
890
|
+
guard shouldEmit else { return }
|
|
891
|
+
DispatchQueue.main.async {
|
|
892
|
+
self.sendEvent(
|
|
893
|
+
withName: "AnsightHostConnectionStatus",
|
|
894
|
+
body: self.hostConnectionStatusDictionary(status)
|
|
895
|
+
)
|
|
896
|
+
}
|
|
897
|
+
}
|
|
898
|
+
|
|
837
899
|
private func configureReactNativeMemoryProfiling(_ dictionary: NSDictionary?) throws {
|
|
838
900
|
let options = ReactNativeMemoryProfilingOptions(dictionary: dictionary)
|
|
839
901
|
currentReactNativeMemoryOptions = options
|
|
@@ -895,6 +957,13 @@ final class AnsightReactNative: RCTEventEmitter {
|
|
|
895
957
|
if hasBool(dictionary, "enableBatteryLevel") {
|
|
896
958
|
options.enableBatteryLevel = boolValue(dictionary, "enableBatteryLevel", defaultValue: options.enableBatteryLevel)
|
|
897
959
|
}
|
|
960
|
+
if hasBool(dictionary, "enableOpenFileHandleTracking") {
|
|
961
|
+
options.enableOpenFileHandleTracking = boolValue(
|
|
962
|
+
dictionary,
|
|
963
|
+
"enableOpenFileHandleTracking",
|
|
964
|
+
defaultValue: options.enableOpenFileHandleTracking
|
|
965
|
+
)
|
|
966
|
+
}
|
|
898
967
|
if let memory = dictionary?["defaultMemoryChannels"] as? NSDictionary {
|
|
899
968
|
var channels: DefaultMemoryChannels = []
|
|
900
969
|
if boolValue(memory, "managedHeap", defaultValue: boolValue(memory, "javaHeap", defaultValue: false)) {
|
|
@@ -942,9 +1011,14 @@ final class AnsightReactNative: RCTEventEmitter {
|
|
|
942
1011
|
"captureGpuBackedSurfaces",
|
|
943
1012
|
defaultValue: AnsightSessionJpegCaptureOptions.defaultCaptureGpuBackedSurfaces
|
|
944
1013
|
),
|
|
945
|
-
mode:
|
|
946
|
-
|
|
947
|
-
|
|
1014
|
+
mode: AnsightSessionJpegCaptureMode(
|
|
1015
|
+
rawValue: stringValue(jpeg, "mode") ?? ""
|
|
1016
|
+
) ?? .screenshotOnly,
|
|
1017
|
+
captureKeyboardPresence: boolValue(
|
|
1018
|
+
jpeg,
|
|
1019
|
+
"captureKeyboardPresence",
|
|
1020
|
+
defaultValue: AnsightSessionJpegCaptureOptions.defaultCaptureKeyboardPresence
|
|
1021
|
+
)
|
|
948
1022
|
)
|
|
949
1023
|
}
|
|
950
1024
|
}
|
|
@@ -960,6 +1034,21 @@ final class AnsightReactNative: RCTEventEmitter {
|
|
|
960
1034
|
)
|
|
961
1035
|
}
|
|
962
1036
|
}
|
|
1037
|
+
if let raw = dictionary?["crashCapture"] {
|
|
1038
|
+
if (raw as? Bool) == false {
|
|
1039
|
+
options.crashCapture.enabled = false
|
|
1040
|
+
} else if let crash = raw as? NSDictionary {
|
|
1041
|
+
options.crashCapture = AnsightCrashCaptureOptions(
|
|
1042
|
+
enabled: boolValue(crash, "enabled", defaultValue: true),
|
|
1043
|
+
studioHandoffEnabled: boolValue(crash, "studioHandoffEnabled", defaultValue: true),
|
|
1044
|
+
offlineCaptureAttachmentEnabled: boolValue(crash, "offlineCaptureAttachmentEnabled", defaultValue: true),
|
|
1045
|
+
maximumPendingReports: intValue(crash, "maximumPendingReports", defaultValue: 8),
|
|
1046
|
+
retentionDays: intValue(crash, "retentionDays", defaultValue: 7),
|
|
1047
|
+
maximumBreadcrumbs: intValue(crash, "maximumBreadcrumbs", defaultValue: 64),
|
|
1048
|
+
maximumTraceBytes: intValue(crash, "maximumTraceBytes", defaultValue: 1_048_576)
|
|
1049
|
+
)
|
|
1050
|
+
}
|
|
1051
|
+
}
|
|
963
1052
|
if let lifecycle = dictionary?["lifecycleCapture"] as? NSDictionary {
|
|
964
1053
|
options.lifecycleCapture = AnsightLifecycleCaptureOptions(
|
|
965
1054
|
enabled: boolValue(lifecycle, "enabled", defaultValue: options.lifecycleCapture.enabled),
|
|
@@ -1271,9 +1360,14 @@ final class AnsightReactNative: RCTEventEmitter {
|
|
|
1271
1360
|
"captureGpuBackedSurfaces",
|
|
1272
1361
|
defaultValue: AnsightSessionJpegCaptureOptions.defaultCaptureGpuBackedSurfaces
|
|
1273
1362
|
),
|
|
1274
|
-
mode:
|
|
1275
|
-
|
|
1276
|
-
|
|
1363
|
+
mode: AnsightSessionJpegCaptureMode(
|
|
1364
|
+
rawValue: stringValue(dictionary, "mode") ?? ""
|
|
1365
|
+
) ?? .screenshotOnly,
|
|
1366
|
+
captureKeyboardPresence: boolValue(
|
|
1367
|
+
dictionary,
|
|
1368
|
+
"captureKeyboardPresence",
|
|
1369
|
+
defaultValue: AnsightSessionJpegCaptureOptions.defaultCaptureKeyboardPresence
|
|
1370
|
+
)
|
|
1277
1371
|
)
|
|
1278
1372
|
}
|
|
1279
1373
|
|
|
@@ -1283,6 +1377,8 @@ final class AnsightReactNative: RCTEventEmitter {
|
|
|
1283
1377
|
"retentionPeriodSeconds": options.retentionPeriodSeconds,
|
|
1284
1378
|
"enableFramesPerSecond": options.enableFramesPerSecond,
|
|
1285
1379
|
"enableBatteryLevel": options.enableBatteryLevel,
|
|
1380
|
+
"enableOpenFileHandleTracking": options.enableOpenFileHandleTracking,
|
|
1381
|
+
"enableJniReferenceCountTracking": false,
|
|
1286
1382
|
"defaultMemoryChannels": [
|
|
1287
1383
|
"managedHeap": options.defaultMemoryChannels.contains(.managedHeap),
|
|
1288
1384
|
"javaHeap": options.defaultMemoryChannels.contains(.managedHeap),
|
|
@@ -1322,6 +1418,7 @@ final class AnsightReactNative: RCTEventEmitter {
|
|
|
1322
1418
|
"quality": capture.quality,
|
|
1323
1419
|
"maxWidth": capture.maxWidth as Any,
|
|
1324
1420
|
"captureGpuBackedSurfaces": capture.captureGpuBackedSurfaces,
|
|
1421
|
+
"captureKeyboardPresence": capture.captureKeyboardPresence,
|
|
1325
1422
|
"mode": capture.mode.rawValue,
|
|
1326
1423
|
]
|
|
1327
1424
|
} else {
|
|
@@ -33,6 +33,14 @@ RCT_EXTERN_METHOD(recordEvent:(NSDictionary *)input
|
|
|
33
33
|
resolver:(RCTPromiseResolveBlock)resolve
|
|
34
34
|
rejecter:(RCTPromiseRejectBlock)reject)
|
|
35
35
|
|
|
36
|
+
RCT_EXTERN_METHOD(recordNetworkRequest:(NSDictionary *)input
|
|
37
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
38
|
+
rejecter:(RCTPromiseRejectBlock)reject)
|
|
39
|
+
|
|
40
|
+
RCT_EXTERN_METHOD(recordCrashCandidate:(NSDictionary *)input
|
|
41
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
42
|
+
rejecter:(RCTPromiseRejectBlock)reject)
|
|
43
|
+
|
|
36
44
|
RCT_EXTERN_METHOD(screenViewed:(NSString *)name
|
|
37
45
|
details:(NSDictionary *)details
|
|
38
46
|
resolver:(RCTPromiseResolveBlock)resolve
|