@grafana/faro-react-native 1.3.0 → 1.4.0
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 +176 -30
- package/android/build.gradle +20 -15
- package/android/src/main/java/com/grafana/faro/reactnative/FaroCrashIds.kt +44 -0
- package/android/src/main/java/com/grafana/faro/reactnative/FaroCrashReporter.kt +134 -38
- package/android/src/main/java/com/grafana/faro/reactnative/FaroCrashSessionStore.kt +433 -0
- package/android/src/main/java/com/grafana/faro/reactnative/FaroCrashTraceCache.kt +11 -2
- package/android/src/main/java/com/grafana/faro/reactnative/FaroReactNativeModule.kt +128 -17
- package/android/src/main/java/com/grafana/faro/reactnative/FaroSessionProcess.kt +88 -0
- package/android/src/main/java/com/grafana/faro/reactnative/FrameMonitor.kt +34 -42
- package/android/src/test/java/com/grafana/faro/reactnative/FaroCrashReporterBelowApi30Test.kt +21 -0
- package/android/src/test/java/com/grafana/faro/reactnative/FaroCrashReporterTest.kt +59 -0
- package/android/src/test/java/com/grafana/faro/reactnative/FaroCrashSessionStoreTest.kt +268 -0
- package/android/src/test/java/com/grafana/faro/reactnative/FaroCrashTraceCacheTest.kt +52 -0
- package/android/src/test/java/com/grafana/faro/reactnative/FaroSessionProcessTest.kt +127 -0
- package/dist/cjs/config/getRNInstrumentations.js +6 -8
- package/dist/cjs/config/getRNInstrumentations.js.map +1 -1
- package/dist/cjs/config/sampling.js.map +1 -1
- package/dist/cjs/config/types.js.map +1 -1
- package/dist/cjs/dataCollection/DataCollectionPolicy.js +1 -2
- package/dist/cjs/dataCollection/DataCollectionPolicy.js.map +1 -1
- package/dist/cjs/generated/faroRNPackageMeta.js +1 -1
- package/dist/cjs/generated/faroRNPackageMeta.js.map +1 -1
- package/dist/cjs/index.js +8 -3
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/instrumentations/anr/instrumentation.js +10 -1
- package/dist/cjs/instrumentations/anr/instrumentation.js.map +1 -1
- package/dist/cjs/instrumentations/appState/index.js +8 -2
- package/dist/cjs/instrumentations/appState/index.js.map +1 -1
- package/dist/cjs/instrumentations/crashReporting/BaseCrashReportingInstrumentation.js +19 -6
- package/dist/cjs/instrumentations/crashReporting/BaseCrashReportingInstrumentation.js.map +1 -1
- package/dist/cjs/instrumentations/crashReporting/RecoveredCrashReportingInstrumentation.js +331 -0
- package/dist/cjs/instrumentations/crashReporting/RecoveredCrashReportingInstrumentation.js.map +1 -0
- package/dist/cjs/instrumentations/crashReporting/android/AndroidCrashReportingInstrumentation.js +2 -2
- package/dist/cjs/instrumentations/crashReporting/android/AndroidCrashReportingInstrumentation.js.map +1 -1
- package/dist/cjs/instrumentations/crashReporting/ios/IosCrashReportingInstrumentation.js +2 -2
- package/dist/cjs/instrumentations/crashReporting/ios/IosCrashReportingInstrumentation.js.map +1 -1
- package/dist/cjs/instrumentations/crashReporting/types.js.map +1 -1
- package/dist/cjs/instrumentations/errors/index.js +8 -3
- package/dist/cjs/instrumentations/errors/index.js.map +1 -1
- package/dist/cjs/instrumentations/frameMonitoring/instrumentation.js +20 -31
- package/dist/cjs/instrumentations/frameMonitoring/instrumentation.js.map +1 -1
- package/dist/cjs/instrumentations/frameMonitoring/types.js.map +1 -1
- package/dist/cjs/instrumentations/performance/index.js +2 -6
- package/dist/cjs/instrumentations/performance/index.js.map +1 -1
- package/dist/cjs/instrumentations/session/FaroSessionActivityBoundary.js +48 -0
- package/dist/cjs/instrumentations/session/FaroSessionActivityBoundary.js.map +1 -0
- package/dist/cjs/instrumentations/session/directSessionActivity.js +37 -0
- package/dist/cjs/instrumentations/session/directSessionActivity.js.map +1 -0
- package/dist/cjs/instrumentations/session/index.js +214 -45
- package/dist/cjs/instrumentations/session/index.js.map +1 -1
- package/dist/cjs/instrumentations/session/sessionActivity.js +43 -0
- package/dist/cjs/instrumentations/session/sessionActivity.js.map +1 -0
- package/dist/cjs/instrumentations/session/sessionAttributes.js +8 -8
- package/dist/cjs/instrumentations/session/sessionAttributes.js.map +1 -1
- package/dist/cjs/instrumentations/session/sessionManager/MmkvPersistentSessionsManager.js +199 -24
- package/dist/cjs/instrumentations/session/sessionManager/MmkvPersistentSessionsManager.js.map +1 -1
- package/dist/cjs/instrumentations/session/sessionManager/VolatileSessionManager.js +31 -13
- package/dist/cjs/instrumentations/session/sessionManager/VolatileSessionManager.js.map +1 -1
- package/dist/cjs/instrumentations/session/sessionManager/persistentSessionRecord.js +72 -0
- package/dist/cjs/instrumentations/session/sessionManager/persistentSessionRecord.js.map +1 -0
- package/dist/cjs/instrumentations/session/sessionManager/sessionConstants.js +1 -1
- package/dist/cjs/instrumentations/session/sessionManager/sessionConstants.js.map +1 -1
- package/dist/cjs/instrumentations/session/sessionManager/sessionManagerUtils.js +124 -96
- package/dist/cjs/instrumentations/session/sessionManager/sessionManagerUtils.js.map +1 -1
- package/dist/cjs/instrumentations/session/sessionManager/types.js.map +1 -1
- package/dist/cjs/instrumentations/session/sessionProcess.js +96 -0
- package/dist/cjs/instrumentations/session/sessionProcess.js.map +1 -0
- package/dist/cjs/instrumentations/startup/index.js +2 -6
- package/dist/cjs/instrumentations/startup/index.js.map +1 -1
- package/dist/cjs/navigation/utils.js +3 -1
- package/dist/cjs/navigation/utils.js.map +1 -1
- package/dist/cjs/transports/fetch/index.js.map +1 -1
- package/dist/cjs/transports/fetch/transport.js +56 -25
- package/dist/cjs/transports/fetch/transport.js.map +1 -1
- package/dist/cjs/transports/fetch/types.js.map +1 -1
- package/dist/cjs/transports/offline/ConnectivityService.js +1 -1
- package/dist/cjs/transports/offline/ConnectivityService.js.map +1 -1
- package/dist/cjs/transports/offline/OfflineCache.js +2 -2
- package/dist/cjs/transports/offline/OfflineCache.js.map +1 -1
- package/dist/cjs/transports/offline/transport.js +3 -4
- package/dist/cjs/transports/offline/transport.js.map +1 -1
- package/dist/cjs/userPersistence/UserPersistence.js +1 -2
- package/dist/cjs/userPersistence/UserPersistence.js.map +1 -1
- package/dist/esm/config/getRNInstrumentations.js +6 -8
- package/dist/esm/config/getRNInstrumentations.js.map +1 -1
- package/dist/esm/config/sampling.js.map +1 -1
- package/dist/esm/config/types.js.map +1 -1
- package/dist/esm/dataCollection/DataCollectionPolicy.js +1 -2
- package/dist/esm/dataCollection/DataCollectionPolicy.js.map +1 -1
- package/dist/esm/generated/faroRNPackageMeta.js +1 -1
- package/dist/esm/generated/faroRNPackageMeta.js.map +1 -1
- package/dist/esm/index.js +4 -2
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/instrumentations/anr/instrumentation.js +6 -1
- package/dist/esm/instrumentations/anr/instrumentation.js.map +1 -1
- package/dist/esm/instrumentations/appState/index.js +8 -2
- package/dist/esm/instrumentations/appState/index.js.map +1 -1
- package/dist/esm/instrumentations/crashReporting/BaseCrashReportingInstrumentation.js +15 -4
- package/dist/esm/instrumentations/crashReporting/BaseCrashReportingInstrumentation.js.map +1 -1
- package/dist/esm/instrumentations/crashReporting/RecoveredCrashReportingInstrumentation.js +230 -0
- package/dist/esm/instrumentations/crashReporting/RecoveredCrashReportingInstrumentation.js.map +1 -0
- package/dist/esm/instrumentations/crashReporting/android/AndroidCrashReportingInstrumentation.js +2 -2
- package/dist/esm/instrumentations/crashReporting/android/AndroidCrashReportingInstrumentation.js.map +1 -1
- package/dist/esm/instrumentations/crashReporting/ios/IosCrashReportingInstrumentation.js +2 -2
- package/dist/esm/instrumentations/crashReporting/ios/IosCrashReportingInstrumentation.js.map +1 -1
- package/dist/esm/instrumentations/crashReporting/types.js.map +1 -1
- package/dist/esm/instrumentations/errors/index.js +8 -3
- package/dist/esm/instrumentations/errors/index.js.map +1 -1
- package/dist/esm/instrumentations/frameMonitoring/instrumentation.js +17 -32
- package/dist/esm/instrumentations/frameMonitoring/instrumentation.js.map +1 -1
- package/dist/esm/instrumentations/frameMonitoring/types.js.map +1 -1
- package/dist/esm/instrumentations/performance/index.js +2 -6
- package/dist/esm/instrumentations/performance/index.js.map +1 -1
- package/dist/esm/instrumentations/session/FaroSessionActivityBoundary.js +34 -0
- package/dist/esm/instrumentations/session/FaroSessionActivityBoundary.js.map +1 -0
- package/dist/esm/instrumentations/session/directSessionActivity.js +32 -0
- package/dist/esm/instrumentations/session/directSessionActivity.js.map +1 -0
- package/dist/esm/instrumentations/session/index.js +207 -46
- package/dist/esm/instrumentations/session/index.js.map +1 -1
- package/dist/esm/instrumentations/session/sessionActivity.js +38 -0
- package/dist/esm/instrumentations/session/sessionActivity.js.map +1 -0
- package/dist/esm/instrumentations/session/sessionAttributes.js +7 -7
- package/dist/esm/instrumentations/session/sessionAttributes.js.map +1 -1
- package/dist/esm/instrumentations/session/sessionManager/MmkvPersistentSessionsManager.js +190 -27
- package/dist/esm/instrumentations/session/sessionManager/MmkvPersistentSessionsManager.js.map +1 -1
- package/dist/esm/instrumentations/session/sessionManager/VolatileSessionManager.js +31 -14
- package/dist/esm/instrumentations/session/sessionManager/VolatileSessionManager.js.map +1 -1
- package/dist/esm/instrumentations/session/sessionManager/persistentSessionRecord.js +56 -0
- package/dist/esm/instrumentations/session/sessionManager/persistentSessionRecord.js.map +1 -0
- package/dist/esm/instrumentations/session/sessionManager/sessionConstants.js +1 -1
- package/dist/esm/instrumentations/session/sessionManager/sessionConstants.js.map +1 -1
- package/dist/esm/instrumentations/session/sessionManager/sessionManagerUtils.js +120 -44
- package/dist/esm/instrumentations/session/sessionManager/sessionManagerUtils.js.map +1 -1
- package/dist/esm/instrumentations/session/sessionManager/types.js.map +1 -1
- package/dist/esm/instrumentations/session/sessionProcess.js +89 -0
- package/dist/esm/instrumentations/session/sessionProcess.js.map +1 -0
- package/dist/esm/instrumentations/startup/index.js +2 -6
- package/dist/esm/instrumentations/startup/index.js.map +1 -1
- package/dist/esm/navigation/utils.js +2 -1
- package/dist/esm/navigation/utils.js.map +1 -1
- package/dist/esm/transports/fetch/index.js.map +1 -1
- package/dist/esm/transports/fetch/transport.js +38 -14
- package/dist/esm/transports/fetch/transport.js.map +1 -1
- package/dist/esm/transports/fetch/types.js.map +1 -1
- package/dist/esm/transports/offline/ConnectivityService.js +1 -1
- package/dist/esm/transports/offline/ConnectivityService.js.map +1 -1
- package/dist/esm/transports/offline/OfflineCache.js +2 -2
- package/dist/esm/transports/offline/OfflineCache.js.map +1 -1
- package/dist/esm/transports/offline/transport.js +3 -4
- package/dist/esm/transports/offline/transport.js.map +1 -1
- package/dist/esm/userPersistence/UserPersistence.js +1 -2
- package/dist/esm/userPersistence/UserPersistence.js.map +1 -1
- package/dist/types/config/getRNInstrumentations.d.ts +1 -2
- package/dist/types/config/sampling.d.ts +0 -3
- package/dist/types/config/types.d.ts +5 -3
- package/dist/types/dataCollection/DataCollectionPolicy.d.ts +1 -2
- package/dist/types/generated/faroRNPackageMeta.d.ts +1 -1
- package/dist/types/index.d.ts +4 -1
- package/dist/types/instrumentations/anr/instrumentation.d.ts +1 -1
- package/dist/types/instrumentations/appState/index.d.ts +1 -1
- package/dist/types/instrumentations/console/index.d.ts +1 -1
- package/dist/types/instrumentations/crashReporting/BaseCrashReportingInstrumentation.d.ts +14 -4
- package/dist/types/instrumentations/crashReporting/NoOpCrashReportingInstrumentation.d.ts +1 -1
- package/dist/types/instrumentations/crashReporting/RecoveredCrashReportingInstrumentation.d.ts +27 -0
- package/dist/types/instrumentations/crashReporting/android/AndroidCrashReportingInstrumentation.d.ts +3 -3
- package/dist/types/instrumentations/crashReporting/ios/IosCrashReportingInstrumentation.d.ts +3 -3
- package/dist/types/instrumentations/crashReporting/types.d.ts +6 -0
- package/dist/types/instrumentations/frameMonitoring/instrumentation.d.ts +3 -3
- package/dist/types/instrumentations/frameMonitoring/types.d.ts +4 -6
- package/dist/types/instrumentations/http/index.d.ts +1 -1
- package/dist/types/instrumentations/performance/index.d.ts +1 -3
- package/dist/types/instrumentations/session/FaroSessionActivityBoundary.d.ts +8 -0
- package/dist/types/instrumentations/session/directSessionActivity.d.ts +13 -0
- package/dist/types/instrumentations/session/index.d.ts +21 -2
- package/dist/types/instrumentations/session/sessionActivity.d.ts +9 -0
- package/dist/types/instrumentations/session/sessionAttributes.d.ts +6 -3
- package/dist/types/instrumentations/session/sessionManager/MmkvPersistentSessionsManager.d.ts +16 -3
- package/dist/types/instrumentations/session/sessionManager/VolatileSessionManager.d.ts +9 -3
- package/dist/types/instrumentations/session/sessionManager/persistentSessionRecord.d.ts +4 -0
- package/dist/types/instrumentations/session/sessionManager/sessionManagerUtils.d.ts +19 -7
- package/dist/types/instrumentations/session/sessionManager/types.d.ts +6 -0
- package/dist/types/instrumentations/session/sessionProcess.d.ts +17 -0
- package/dist/types/instrumentations/startup/index.d.ts +3 -7
- package/dist/types/instrumentations/userActions/index.d.ts +1 -1
- package/dist/types/instrumentations/view/index.d.ts +1 -1
- package/dist/types/instrumentations/xhr/index.d.ts +1 -1
- package/dist/types/navigation/utils.d.ts +1 -0
- package/dist/types/testUtils/mockFaroReactNativeTracing.d.ts +1 -1
- package/dist/types/transports/console/transport.d.ts +1 -1
- package/dist/types/transports/fetch/index.d.ts +1 -1
- package/dist/types/transports/fetch/transport.d.ts +9 -2
- package/dist/types/transports/fetch/types.d.ts +5 -0
- package/dist/types/transports/offline/ConnectivityService.d.ts +1 -1
- package/dist/types/transports/offline/OfflineCache.d.ts +2 -2
- package/dist/types/transports/offline/transport.d.ts +4 -5
- package/dist/types/userPersistence/UserPersistence.d.ts +1 -2
- package/ios/FaroCrashReporter.swift +214 -21
- package/ios/FaroReactNative.swift +24 -0
- package/ios/FaroReactNativeModule.h +2 -1
- package/ios/FaroReactNativeModule.mm +121 -6
- package/ios/RefreshRateVitals.swift +34 -38
- package/package.json +8 -6
- package/src/config/getRNInstrumentations.ts +6 -8
- package/src/config/makeRNConfig.test.ts +6 -0
- package/src/config/sampling.ts +0 -3
- package/src/config/types.ts +5 -3
- package/src/dataCollection/DataCollectionPolicy.ts +1 -2
- package/src/generated/faroRNPackageMeta.ts +1 -1
- package/src/index.ts +8 -2
- package/src/instrumentations/anr/instrumentation.ts +8 -1
- package/src/instrumentations/appState/index.ts +10 -2
- package/src/instrumentations/crashReporting/BaseCrashReportingInstrumentation.ts +28 -8
- package/src/instrumentations/crashReporting/RecoveredCrashReportingInstrumentation.ts +277 -0
- package/src/instrumentations/crashReporting/android/AndroidCrashReportingInstrumentation.ts +2 -2
- package/src/instrumentations/crashReporting/instrumentation.test.ts +433 -5
- package/src/instrumentations/crashReporting/ios/IosCrashReportingInstrumentation.ts +2 -2
- package/src/instrumentations/crashReporting/types.ts +7 -0
- package/src/instrumentations/errors/index.ts +12 -4
- package/src/instrumentations/errors/instrumentation.test.ts +35 -0
- package/src/instrumentations/frameMonitoring/instrumentation.test.ts +155 -0
- package/src/instrumentations/frameMonitoring/instrumentation.ts +19 -38
- package/src/instrumentations/frameMonitoring/types.ts +4 -6
- package/src/instrumentations/performance/index.ts +2 -6
- package/src/instrumentations/session/FaroSessionActivityBoundary.test.ts +60 -0
- package/src/instrumentations/session/FaroSessionActivityBoundary.tsx +41 -0
- package/src/instrumentations/session/beforeSendHook.test.ts +246 -0
- package/src/instrumentations/session/directSessionActivity.test.ts +158 -0
- package/src/instrumentations/session/directSessionActivity.ts +36 -0
- package/src/instrumentations/session/index.ts +269 -46
- package/src/instrumentations/session/persistentColdStart.test.ts +196 -0
- package/src/instrumentations/session/sessionActivity.test.ts +68 -0
- package/src/instrumentations/session/sessionActivity.ts +58 -0
- package/src/instrumentations/session/sessionAttributes.test.ts +37 -2
- package/src/instrumentations/session/sessionAttributes.ts +12 -6
- package/src/instrumentations/session/sessionCleanup.test.ts +410 -0
- package/src/instrumentations/session/sessionManager/MmkvPersistentSessionsManager.test.ts +552 -0
- package/src/instrumentations/session/sessionManager/MmkvPersistentSessionsManager.ts +249 -33
- package/src/instrumentations/session/sessionManager/VolatileSessionManager.ts +38 -18
- package/src/instrumentations/session/sessionManager/persistentSessionRecord.test.ts +103 -0
- package/src/instrumentations/session/sessionManager/persistentSessionRecord.ts +78 -0
- package/src/instrumentations/session/sessionManager/sampling.test.ts +1 -1
- package/src/instrumentations/session/sessionManager/sessionConstants.ts +1 -1
- package/src/instrumentations/session/sessionManager/sessionManagerUtils.test.ts +256 -18
- package/src/instrumentations/session/sessionManager/sessionManagerUtils.ts +180 -39
- package/src/instrumentations/session/sessionManager/types.ts +8 -0
- package/src/instrumentations/session/sessionManagerInstance.test.ts +65 -0
- package/src/instrumentations/session/sessionProcess.test.ts +136 -0
- package/src/instrumentations/session/sessionProcess.ts +114 -0
- package/src/instrumentations/session/startNewSession.test.ts +337 -0
- package/src/instrumentations/startup/index.ts +2 -6
- package/src/navigation/utils.ts +3 -1
- package/src/transports/fetch/index.ts +6 -1
- package/src/transports/fetch/transport.test.ts +86 -2
- package/src/transports/fetch/transport.ts +38 -16
- package/src/transports/fetch/types.ts +7 -0
- package/src/transports/offline/ConnectivityService.ts +1 -1
- package/src/transports/offline/OfflineCache.ts +2 -2
- package/src/transports/offline/transport.ts +3 -4
- package/src/userPersistence/UserPersistence.ts +1 -2
- package/dist/cjs/utils/throttle.js +0 -42
- package/dist/cjs/utils/throttle.js.map +0 -1
- package/dist/esm/utils/throttle.js +0 -34
- package/dist/esm/utils/throttle.js.map +0 -1
- package/dist/types/utils/throttle.d.ts +0 -9
- package/src/utils/throttle.test.ts +0 -141
- package/src/utils/throttle.ts +0 -34
|
@@ -7,15 +7,12 @@ import type { StartupInstrumentationOptions } from './types';
|
|
|
7
7
|
* - iOS: sysctl() to query kernel for process start time
|
|
8
8
|
* - Android: Process.getStartElapsedRealtime() from Android OS (API 24+)
|
|
9
9
|
*
|
|
10
|
-
* Implementation aligned with Faro Flutter SDK:
|
|
11
|
-
* https://github.com/grafana/faro-flutter-sdk
|
|
12
|
-
*
|
|
13
10
|
* **Key Features**:
|
|
14
11
|
* - ✅ NO AppDelegate/MainActivity setup required - OS tracks process start automatically!
|
|
15
12
|
* - ✅ Cold start: appStartDuration from native, coldStart: 1
|
|
16
13
|
* - ✅ Warm start: appStartDuration (time to first frame after resume), coldStart: 0
|
|
17
14
|
*
|
|
18
|
-
* **Metrics Captured
|
|
15
|
+
* **Metrics Captured**:
|
|
19
16
|
* - Cold start: `appStartDuration`, `coldStart: 1`
|
|
20
17
|
* - Warm start: `appStartDuration`, `coldStart: 0`
|
|
21
18
|
*
|
|
@@ -37,7 +34,7 @@ import type { StartupInstrumentationOptions } from './types';
|
|
|
37
34
|
export declare class StartupInstrumentation extends BaseInstrumentation {
|
|
38
35
|
private options;
|
|
39
36
|
readonly name = "@grafana/faro-react-native:instrumentation-startup";
|
|
40
|
-
readonly version = "2.
|
|
37
|
+
readonly version = "2.8.2";
|
|
41
38
|
/** 0 = came from background (warm start eligible), null = never backgrounded */
|
|
42
39
|
private warmStartTimestamp;
|
|
43
40
|
private appStateSubscription;
|
|
@@ -45,12 +42,11 @@ export declare class StartupInstrumentation extends BaseInstrumentation {
|
|
|
45
42
|
initialize(): void;
|
|
46
43
|
/**
|
|
47
44
|
* Captures cold start duration from native (process start to Faro init).
|
|
48
|
-
*
|
|
45
|
+
* Sends appStartDuration with coldStart: 1.
|
|
49
46
|
*/
|
|
50
47
|
private captureColdStartMetrics;
|
|
51
48
|
/**
|
|
52
49
|
* Tracks warm start: when app resumes from background, measures time to first frame.
|
|
53
|
-
* Matches Flutter SDK: setWarmStart on resume, getWarmStart after postFrameCallback.
|
|
54
50
|
*/
|
|
55
51
|
private setupWarmStartTracking;
|
|
56
52
|
unpatch(): void;
|
|
@@ -24,7 +24,7 @@ import { BaseInstrumentation } from '@grafana/faro-core';
|
|
|
24
24
|
*/
|
|
25
25
|
export declare class UserActionInstrumentation extends BaseInstrumentation {
|
|
26
26
|
readonly name = "@grafana/faro-react-native:instrumentation-user-action";
|
|
27
|
-
readonly version = "2.
|
|
27
|
+
readonly version = "2.8.2";
|
|
28
28
|
private _userActionSub?;
|
|
29
29
|
initialize(): void;
|
|
30
30
|
/**
|
|
@@ -9,7 +9,7 @@ import { BaseInstrumentation } from '@grafana/faro-core';
|
|
|
9
9
|
*/
|
|
10
10
|
export declare class ViewInstrumentation extends BaseInstrumentation {
|
|
11
11
|
readonly name = "@grafana/faro-react-native:instrumentation-view";
|
|
12
|
-
readonly version = "2.
|
|
12
|
+
readonly version = "2.8.2";
|
|
13
13
|
private notifiedView;
|
|
14
14
|
private metaUnsubscribe;
|
|
15
15
|
private sendViewChangedEvent;
|
|
@@ -7,7 +7,7 @@ import { BaseInstrumentation } from '@grafana/faro-core';
|
|
|
7
7
|
*/
|
|
8
8
|
export declare class XHRInstrumentation extends BaseInstrumentation {
|
|
9
9
|
readonly name = "@grafana/faro-react-native:instrumentation-xhr";
|
|
10
|
-
readonly version = "2.
|
|
10
|
+
readonly version = "2.8.2";
|
|
11
11
|
private originalOpen?;
|
|
12
12
|
private originalSend?;
|
|
13
13
|
private ignoredUrls;
|
|
@@ -5,6 +5,6 @@
|
|
|
5
5
|
import { BaseInstrumentation } from '@grafana/faro-core';
|
|
6
6
|
export declare class TracingInstrumentation extends BaseInstrumentation {
|
|
7
7
|
readonly name = "@grafana/faro-react-native-tracing";
|
|
8
|
-
readonly version = "2.
|
|
8
|
+
readonly version = "2.8.2";
|
|
9
9
|
initialize(): void;
|
|
10
10
|
}
|
|
@@ -4,7 +4,7 @@ import type { ConsoleTransportOptions } from './types';
|
|
|
4
4
|
export declare class ConsoleTransport extends BaseTransport {
|
|
5
5
|
private options;
|
|
6
6
|
readonly name = "@grafana/faro-react-native:transport-console";
|
|
7
|
-
readonly version = "2.
|
|
7
|
+
readonly version = "2.8.2";
|
|
8
8
|
constructor(options?: ConsoleTransportOptions);
|
|
9
9
|
send(item: TransportItem): void;
|
|
10
10
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { FetchTransport } from './transport';
|
|
2
|
-
export type { FetchTransportOptions, FetchTransportRequestOptions } from './types';
|
|
2
|
+
export type { FetchTransportOptions, FetchTransportRequestOptions, FetchTransportSendOutcome, FetchTransportSendResult, } from './types';
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { BaseTransport } from '@grafana/faro-core';
|
|
2
2
|
import type { Patterns, PromiseBuffer, TransportItem } from '@grafana/faro-core';
|
|
3
|
-
import type { FetchTransportOptions } from './types';
|
|
3
|
+
import type { FetchTransportOptions, FetchTransportSendResult } from './types';
|
|
4
4
|
export declare class FetchTransport extends BaseTransport {
|
|
5
5
|
private options;
|
|
6
6
|
readonly name = "@grafana/faro-react-native:transport-fetch";
|
|
7
|
-
readonly version = "2.
|
|
7
|
+
readonly version = "2.8.2";
|
|
8
8
|
promiseBuffer: PromiseBuffer<Response | void>;
|
|
9
9
|
private readonly rateLimitBackoffMs;
|
|
10
10
|
private readonly getNow;
|
|
@@ -28,6 +28,13 @@ export declare class FetchTransport extends BaseTransport {
|
|
|
28
28
|
*/
|
|
29
29
|
private waitForSession;
|
|
30
30
|
send(items: TransportItem[]): Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* Sends a batch and reports whether the collector accepted it.
|
|
33
|
+
* The request header uses the live session for collector accounting. Payload
|
|
34
|
+
* metadata remains independent so delayed signals can retain their original
|
|
35
|
+
* session.
|
|
36
|
+
*/
|
|
37
|
+
sendWithResult(items: TransportItem[]): Promise<FetchTransportSendResult>;
|
|
31
38
|
getIgnoreUrls(): Patterns;
|
|
32
39
|
isBatched(): boolean;
|
|
33
40
|
private getRetryAfterDate;
|
|
@@ -11,3 +11,8 @@ export interface FetchTransportOptions {
|
|
|
11
11
|
requestOptions?: FetchTransportRequestOptions;
|
|
12
12
|
}
|
|
13
13
|
export type ClockFn = () => number;
|
|
14
|
+
export type FetchTransportSendOutcome = 'accepted' | 'rejected' | 'failed' | 'skipped';
|
|
15
|
+
export interface FetchTransportSendResult {
|
|
16
|
+
outcome: FetchTransportSendOutcome;
|
|
17
|
+
status?: number;
|
|
18
|
+
}
|
|
@@ -5,7 +5,7 @@ import type { ConnectivityService } from './types';
|
|
|
5
5
|
* Uses @react-native-community/netinfo when available, otherwise falls back
|
|
6
6
|
* to basic fetch-based connectivity detection.
|
|
7
7
|
*
|
|
8
|
-
*
|
|
8
|
+
* Monitors network connectivity for offline transport flush behavior.
|
|
9
9
|
*/
|
|
10
10
|
export declare class DefaultConnectivityService implements ConnectivityService {
|
|
11
11
|
private _isOnline;
|
|
@@ -3,7 +3,7 @@ import type { CachedPayload, OfflineCache } from './types';
|
|
|
3
3
|
* File-based offline cache implementation using AsyncStorage.
|
|
4
4
|
*
|
|
5
5
|
* Stores cached telemetry payloads as JSONL (one JSON object per line)
|
|
6
|
-
*
|
|
6
|
+
* Persistent offline telemetry cache backed by AsyncStorage.
|
|
7
7
|
*
|
|
8
8
|
* Uses a mutex pattern for thread-safe file access.
|
|
9
9
|
*/
|
|
@@ -22,7 +22,7 @@ export declare class AsyncStorageOfflineCache implements OfflineCache {
|
|
|
22
22
|
getCount(): Promise<number>;
|
|
23
23
|
/**
|
|
24
24
|
* Execute an operation with a mutex lock to ensure thread-safe access.
|
|
25
|
-
*
|
|
25
|
+
* Async lock to serialize cache read/write operations.
|
|
26
26
|
*/
|
|
27
27
|
private withLock;
|
|
28
28
|
private readAllInternal;
|
|
@@ -8,8 +8,7 @@ import type { OfflineTransportOptions } from './types';
|
|
|
8
8
|
* When the device is offline, telemetry is cached to AsyncStorage.
|
|
9
9
|
* When connectivity is restored, cached telemetry is replayed through the wrapped transports.
|
|
10
10
|
*
|
|
11
|
-
*
|
|
12
|
-
* - Uses AsyncStorage for persistent caching (matching Flutter's SharedPreferences)
|
|
11
|
+
* Uses AsyncStorage for persistent offline telemetry caching.
|
|
13
12
|
* - Respects maxCacheDuration to skip expired entries
|
|
14
13
|
* - Uses mutex pattern for thread-safe cache access
|
|
15
14
|
* - Excludes itself when replaying to prevent infinite loops
|
|
@@ -31,7 +30,7 @@ import type { OfflineTransportOptions } from './types';
|
|
|
31
30
|
*/
|
|
32
31
|
export declare class OfflineTransport extends BaseTransport {
|
|
33
32
|
readonly name = "@grafana/faro-react-native:transport-offline";
|
|
34
|
-
readonly version = "2.
|
|
33
|
+
readonly version = "2.8.2";
|
|
35
34
|
private readonly cache;
|
|
36
35
|
private readonly connectivityService;
|
|
37
36
|
private readonly maxCacheDurationMs;
|
|
@@ -72,12 +71,12 @@ export declare class OfflineTransport extends BaseTransport {
|
|
|
72
71
|
dispose(): void;
|
|
73
72
|
/**
|
|
74
73
|
* Replay cached payloads through other transports.
|
|
75
|
-
*
|
|
74
|
+
* Reads cached telemetry from AsyncStorage.
|
|
76
75
|
*/
|
|
77
76
|
private replayCachedPayloads;
|
|
78
77
|
/**
|
|
79
78
|
* Send items to all other registered transports.
|
|
80
|
-
*
|
|
79
|
+
* Sends cached telemetry when connectivity is restored.
|
|
81
80
|
*/
|
|
82
81
|
private sendToOtherTransports;
|
|
83
82
|
}
|
|
@@ -6,8 +6,7 @@ import type { UserPersistence, UserPersistenceOptions } from './types';
|
|
|
6
6
|
* Stores user information persistently so it can be restored on app restart.
|
|
7
7
|
* This ensures early telemetry events include user identification.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
* - Uses AsyncStorage for persistence (matching Flutter's SharedPreferences)
|
|
9
|
+
* Uses AsyncStorage for persistent user data across app sessions.
|
|
11
10
|
* - Stores user as JSON
|
|
12
11
|
* - Handles null/cleared users
|
|
13
12
|
*
|
|
@@ -21,6 +21,17 @@ public class FaroCrashReporter: NSObject {
|
|
|
21
21
|
|
|
22
22
|
private static var crashReporter: PLCrashReporter?
|
|
23
23
|
private static var isEnabled = false
|
|
24
|
+
private static let stateLock = NSLock()
|
|
25
|
+
// activatedAt keeps the persisted context aligned with Android. iOS does not
|
|
26
|
+
// use it to match a pending PLCrashReporter report.
|
|
27
|
+
private static let sessionContextKeys = [
|
|
28
|
+
"sessionId",
|
|
29
|
+
"activatedAt",
|
|
30
|
+
"isSampled",
|
|
31
|
+
"appVersion",
|
|
32
|
+
"appRelease",
|
|
33
|
+
"appBundleId"
|
|
34
|
+
]
|
|
24
35
|
|
|
25
36
|
/// Signal descriptions for human-readable crash messages.
|
|
26
37
|
private static let signalDescriptions: [String: String] = [
|
|
@@ -50,6 +61,12 @@ public class FaroCrashReporter: NSObject {
|
|
|
50
61
|
///
|
|
51
62
|
/// - Returns: true if successfully enabled, false otherwise
|
|
52
63
|
@objc public static func enable() -> Bool {
|
|
64
|
+
stateLock.lock()
|
|
65
|
+
defer { stateLock.unlock() }
|
|
66
|
+
return enableLocked()
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
private static func enableLocked() -> Bool {
|
|
53
70
|
guard !isEnabled else {
|
|
54
71
|
return true
|
|
55
72
|
}
|
|
@@ -90,53 +107,145 @@ public class FaroCrashReporter: NSObject {
|
|
|
90
107
|
}
|
|
91
108
|
}
|
|
92
109
|
|
|
93
|
-
///
|
|
110
|
+
/// Records the active Faro session in PLCrashReporter's crash-safe custom data.
|
|
94
111
|
///
|
|
95
|
-
///
|
|
96
|
-
///
|
|
97
|
-
///
|
|
112
|
+
/// PLCrashReporter copies this data into the report at crash time, allowing a
|
|
113
|
+
/// recovered crash to retain its original session after the app restarts.
|
|
114
|
+
/// Keep this payload minimal because it is embedded in every crash report.
|
|
115
|
+
///
|
|
116
|
+
/// - Parameter sessionContext: Sanitized session and app fields from JavaScript
|
|
117
|
+
/// - Returns: true when the context was stored, false when it was invalid
|
|
118
|
+
@objc public static func recordSessionContext(_ sessionContext: [String: Any]) -> Bool {
|
|
119
|
+
let sanitizedContext = sanitizeSessionContext(sessionContext)
|
|
120
|
+
guard sanitizedContext["sessionId"] != nil,
|
|
121
|
+
JSONSerialization.isValidJSONObject(sanitizedContext) else {
|
|
122
|
+
return false
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
do {
|
|
126
|
+
let data = try JSONSerialization.data(withJSONObject: sanitizedContext)
|
|
127
|
+
stateLock.lock()
|
|
128
|
+
defer { stateLock.unlock() }
|
|
129
|
+
guard enableLocked(), let reporter = crashReporter else {
|
|
130
|
+
return false
|
|
131
|
+
}
|
|
132
|
+
reporter.customData = data
|
|
133
|
+
return true
|
|
134
|
+
} catch {
|
|
135
|
+
print("[FaroCrashReporter] Failed to serialize crash session context: \(error)")
|
|
136
|
+
return false
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/// Gets crash reports from previous sessions without deleting them.
|
|
141
|
+
///
|
|
142
|
+
/// JavaScript acknowledges a report only after successful delivery or an
|
|
143
|
+
/// intentional local discard.
|
|
98
144
|
///
|
|
99
145
|
/// - Returns: Array of crash report JSON strings, or nil if no crashes
|
|
100
|
-
@objc public static func
|
|
101
|
-
|
|
102
|
-
guard enable() else {
|
|
146
|
+
@objc public static func getPendingCrashReports() -> [String]? {
|
|
147
|
+
guard let reporter = enabledReporter(), reporter.hasPendingCrashReport() else {
|
|
103
148
|
return nil
|
|
104
149
|
}
|
|
105
150
|
|
|
106
|
-
|
|
151
|
+
do {
|
|
152
|
+
let data = try reporter.loadPendingCrashReportDataAndReturnError()
|
|
153
|
+
let reportId = reportIdentifier(for: data)
|
|
154
|
+
|
|
155
|
+
do {
|
|
156
|
+
let plcrReport = try PLCrashReport(data: data)
|
|
157
|
+
let crashReport = try FaroCrashReport(from: plcrReport)
|
|
158
|
+
if let json = exportCrashReportAsJSON(crashReport, reportId: reportId) {
|
|
159
|
+
return [json]
|
|
160
|
+
}
|
|
161
|
+
} catch {
|
|
162
|
+
print("[FaroCrashReporter] Failed to parse pending crash report: \(error)")
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Return a stable marker so JavaScript can acknowledge an unreadable
|
|
166
|
+
// report rather than assigning it to the new session or retrying forever.
|
|
167
|
+
return [malformedReportJSON(reportId: reportId)]
|
|
168
|
+
} catch {
|
|
169
|
+
print("[FaroCrashReporter] Failed to load pending crash report: \(error)")
|
|
170
|
+
_ = purgeUnreadablePendingReport(reporter)
|
|
107
171
|
return nil
|
|
108
172
|
}
|
|
173
|
+
}
|
|
109
174
|
|
|
175
|
+
/// Purges the pending report only when its stable ID was acknowledged.
|
|
176
|
+
///
|
|
177
|
+
/// - Parameter reportIds: Stable IDs handled by JavaScript
|
|
178
|
+
/// - Returns: true when no matching report remains or the matching report was purged
|
|
179
|
+
@objc public static func acknowledgeCrashReports(_ reportIds: [String]) -> Bool {
|
|
180
|
+
guard let reporter = enabledReporter() else {
|
|
181
|
+
return false
|
|
182
|
+
}
|
|
110
183
|
guard reporter.hasPendingCrashReport() else {
|
|
111
|
-
return
|
|
184
|
+
return true
|
|
112
185
|
}
|
|
113
186
|
|
|
114
|
-
|
|
187
|
+
let acknowledgedIds = Set(
|
|
188
|
+
reportIds
|
|
189
|
+
.map { $0.trimmingCharacters(in: .whitespacesAndNewlines) }
|
|
190
|
+
.filter { !$0.isEmpty }
|
|
191
|
+
)
|
|
192
|
+
guard !acknowledgedIds.isEmpty else {
|
|
193
|
+
return true
|
|
194
|
+
}
|
|
115
195
|
|
|
116
196
|
do {
|
|
117
197
|
let data = try reporter.loadPendingCrashReportDataAndReturnError()
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
// Convert to JSON matching Android format
|
|
122
|
-
if let jsonString = exportCrashReportAsJSON(crashReport) {
|
|
123
|
-
crashReports.append(jsonString)
|
|
198
|
+
guard acknowledgedIds.contains(reportIdentifier(for: data)) else {
|
|
199
|
+
return true
|
|
124
200
|
}
|
|
201
|
+
return reporter.purgePendingCrashReport()
|
|
125
202
|
} catch {
|
|
126
|
-
print("[FaroCrashReporter] Failed to
|
|
203
|
+
print("[FaroCrashReporter] Failed to acknowledge pending crash report: \(error)")
|
|
204
|
+
return purgeUnreadablePendingReport(reporter)
|
|
127
205
|
}
|
|
206
|
+
}
|
|
128
207
|
|
|
129
|
-
|
|
130
|
-
|
|
208
|
+
/// Gets crash reports from previous sessions as JSON strings.
|
|
209
|
+
///
|
|
210
|
+
/// Returns an array of JSON strings, each representing a crash report.
|
|
211
|
+
/// The JSON format matches the Android implementation for consistency.
|
|
212
|
+
/// This legacy API eagerly purges returned reports for older JavaScript bundles
|
|
213
|
+
/// that cannot acknowledge delivery.
|
|
214
|
+
///
|
|
215
|
+
/// - Returns: Array of crash report JSON strings, or nil if no crashes
|
|
216
|
+
@objc public static func getCrashReports() -> [String]? {
|
|
217
|
+
guard let crashReports = getPendingCrashReports() else {
|
|
218
|
+
return nil
|
|
219
|
+
}
|
|
131
220
|
|
|
132
|
-
|
|
221
|
+
let reportIds = crashReports.compactMap(reportIdentifier(from:))
|
|
222
|
+
_ = acknowledgeCrashReports(reportIds)
|
|
223
|
+
return crashReports
|
|
133
224
|
}
|
|
134
225
|
|
|
135
226
|
// MARK: - Private Helpers
|
|
136
227
|
|
|
228
|
+
private static func enabledReporter() -> PLCrashReporter? {
|
|
229
|
+
stateLock.lock()
|
|
230
|
+
defer { stateLock.unlock() }
|
|
231
|
+
guard enableLocked() else {
|
|
232
|
+
return nil
|
|
233
|
+
}
|
|
234
|
+
return crashReporter
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
private static func purgeUnreadablePendingReport(_ reporter: PLCrashReporter) -> Bool {
|
|
238
|
+
let purged = reporter.purgePendingCrashReport()
|
|
239
|
+
if !purged {
|
|
240
|
+
print("[FaroCrashReporter] Failed to purge unreadable pending crash report")
|
|
241
|
+
}
|
|
242
|
+
return purged
|
|
243
|
+
}
|
|
244
|
+
|
|
137
245
|
/// Converts a FaroCrashReport to JSON string matching the Android format.
|
|
138
|
-
private static func exportCrashReportAsJSON(_ crashReport: FaroCrashReport) -> String? {
|
|
246
|
+
private static func exportCrashReportAsJSON(_ crashReport: FaroCrashReport, reportId: String) -> String? {
|
|
139
247
|
var json: [String: Any] = [:]
|
|
248
|
+
json["reportId"] = reportId
|
|
140
249
|
|
|
141
250
|
// Reason - matches Android's "reason" field
|
|
142
251
|
// For iOS, we use the signal name as the reason
|
|
@@ -176,6 +285,14 @@ public class FaroCrashReporter: NSObject {
|
|
|
176
285
|
json["incidentId"] = incidentId
|
|
177
286
|
}
|
|
178
287
|
|
|
288
|
+
if let sessionContext = decodeSessionContext(crashReport.contextData) {
|
|
289
|
+
for key in sessionContextKeys {
|
|
290
|
+
if let value = sessionContext[key] {
|
|
291
|
+
json[key] = value
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
179
296
|
// Convert to JSON string
|
|
180
297
|
do {
|
|
181
298
|
let jsonData = try JSONSerialization.data(withJSONObject: json, options: [])
|
|
@@ -186,6 +303,82 @@ public class FaroCrashReporter: NSObject {
|
|
|
186
303
|
}
|
|
187
304
|
}
|
|
188
305
|
|
|
306
|
+
private static func sanitizeSessionContext(_ context: [String: Any]) -> [String: Any] {
|
|
307
|
+
var sanitized: [String: Any] = [:]
|
|
308
|
+
|
|
309
|
+
if let sessionId = nonEmptyString(context["sessionId"]) {
|
|
310
|
+
sanitized["sessionId"] = sessionId
|
|
311
|
+
}
|
|
312
|
+
// Android uses activatedAt to map a crash to persisted session history.
|
|
313
|
+
// iOS keeps it in the shared context shape, although PLCrashReporter
|
|
314
|
+
// already snapshots the one active context directly into the report.
|
|
315
|
+
if let activatedAt = context["activatedAt"] as? NSNumber,
|
|
316
|
+
activatedAt.doubleValue.isFinite,
|
|
317
|
+
activatedAt.doubleValue > 0 {
|
|
318
|
+
sanitized["activatedAt"] = activatedAt
|
|
319
|
+
}
|
|
320
|
+
if let isSampled = context["isSampled"] as? NSNumber {
|
|
321
|
+
sanitized["isSampled"] = isSampled.boolValue
|
|
322
|
+
}
|
|
323
|
+
for key in ["appVersion", "appRelease", "appBundleId"] {
|
|
324
|
+
if let value = nonEmptyString(context[key]) {
|
|
325
|
+
sanitized[key] = value
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
return sanitized
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
private static func decodeSessionContext(_ data: Data?) -> [String: Any]? {
|
|
333
|
+
guard let data else {
|
|
334
|
+
return nil
|
|
335
|
+
}
|
|
336
|
+
do {
|
|
337
|
+
guard let context = try JSONSerialization.jsonObject(with: data) as? [String: Any],
|
|
338
|
+
nonEmptyString(context["sessionId"]) != nil else {
|
|
339
|
+
return nil
|
|
340
|
+
}
|
|
341
|
+
return sanitizeSessionContext(context)
|
|
342
|
+
} catch {
|
|
343
|
+
print("[FaroCrashReporter] Failed to decode crash session context: \(error)")
|
|
344
|
+
return nil
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
private static func nonEmptyString(_ value: Any?) -> String? {
|
|
349
|
+
guard let string = value as? String else {
|
|
350
|
+
return nil
|
|
351
|
+
}
|
|
352
|
+
let trimmed = string.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
353
|
+
return trimmed.isEmpty ? nil : trimmed
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
private static func malformedReportJSON(reportId: String) -> String {
|
|
357
|
+
let data = try? JSONSerialization.data(withJSONObject: ["reportId": reportId])
|
|
358
|
+
return data.flatMap { String(data: $0, encoding: .utf8) } ?? "{\"reportId\":\"\(reportId)\"}"
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
private static func reportIdentifier(from crashReportJSON: String) -> String? {
|
|
362
|
+
guard let data = crashReportJSON.data(using: .utf8),
|
|
363
|
+
let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any] else {
|
|
364
|
+
return nil
|
|
365
|
+
}
|
|
366
|
+
return nonEmptyString(json["reportId"])
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
private static func reportIdentifier(for data: Data) -> String {
|
|
370
|
+
// PLCrashReporter stores a single immutable report. A deterministic hash
|
|
371
|
+
// gives both retrieval and acknowledgement the same stable opaque ID,
|
|
372
|
+
// including when the report itself cannot be parsed.
|
|
373
|
+
var hash: UInt64 = 14_695_981_039_346_656_037
|
|
374
|
+
for byte in data {
|
|
375
|
+
hash ^= UInt64(byte)
|
|
376
|
+
hash = hash &* 1_099_511_628_211
|
|
377
|
+
}
|
|
378
|
+
let hex = String(hash, radix: 16)
|
|
379
|
+
return "ios-\(String(repeating: "0", count: max(0, 16 - hex.count)))\(hex)"
|
|
380
|
+
}
|
|
381
|
+
|
|
189
382
|
/// Creates a human-readable description of the crash.
|
|
190
383
|
///
|
|
191
384
|
/// This returns just the descriptive portion. The TypeScript layer formats the
|
|
@@ -20,6 +20,15 @@ import Foundation
|
|
|
20
20
|
/// but include improvements where applicable (e.g., better memory metric).
|
|
21
21
|
@objc(FaroReactNative)
|
|
22
22
|
public class FaroReactNative: NSObject {
|
|
23
|
+
/// Stable bundle identity used to isolate persisted session chains.
|
|
24
|
+
@objc public static func getSessionProcessIdentifier() -> String {
|
|
25
|
+
return Bundle.main.bundleIdentifier ?? ProcessInfo.processInfo.processName
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/// App extensions have an NSExtension dictionary in their main bundle.
|
|
29
|
+
@objc public static func isMainSessionProcess() -> Bool {
|
|
30
|
+
return Bundle.main.object(forInfoDictionaryKey: "NSExtension") == nil
|
|
31
|
+
}
|
|
23
32
|
|
|
24
33
|
// MARK: - App Startup Time
|
|
25
34
|
|
|
@@ -172,4 +181,19 @@ public class FaroReactNative: NSObject {
|
|
|
172
181
|
@objc public static func getCrashReports() -> [String]? {
|
|
173
182
|
return FaroCrashReporter.getCrashReports()
|
|
174
183
|
}
|
|
184
|
+
|
|
185
|
+
/// Records the active Faro session in PLCrashReporter's custom crash data.
|
|
186
|
+
@objc public static func recordCrashSessionContext(_ sessionContext: [String: Any]) -> Bool {
|
|
187
|
+
return FaroCrashReporter.recordSessionContext(sessionContext)
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/// Gets pending crash reports without deleting them.
|
|
191
|
+
@objc public static func getPendingCrashReports() -> [String]? {
|
|
192
|
+
return FaroCrashReporter.getPendingCrashReports()
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/// Purges only the pending report whose stable ID was acknowledged.
|
|
196
|
+
@objc public static func acknowledgeCrashReports(_ reportIds: [String]) -> Bool {
|
|
197
|
+
return FaroCrashReporter.acknowledgeCrashReports(reportIds)
|
|
198
|
+
}
|
|
175
199
|
}
|