@posthog/react-native-plugin 2.1.2 → 2.2.1
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/LICENSE
CHANGED
|
@@ -327,12 +327,12 @@ SOFTWARE.
|
|
|
327
327
|
|
|
328
328
|
---
|
|
329
329
|
|
|
330
|
-
Some files in this codebase contain code from MCPCat/mcpcat-typescript-sdk.
|
|
330
|
+
Some files in this codebase contain code from agentcathq/agentcat-typescript-sdk (formerly MCPCat/mcpcat-typescript-sdk).
|
|
331
331
|
In such cases it is explicitly stated in the file header. This license only applies to the relevant code in such cases.
|
|
332
332
|
|
|
333
333
|
MIT License
|
|
334
334
|
|
|
335
|
-
Copyright (c) 2025 MCPcat
|
|
335
|
+
Copyright (c) 2025 AgentCat, Inc. (formerly MCPcat)
|
|
336
336
|
|
|
337
337
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
338
338
|
of this software and associated documentation files (the "Software"), to deal
|
package/android/build.gradle
CHANGED
|
@@ -85,6 +85,6 @@ dependencies {
|
|
|
85
85
|
//noinspection GradleDynamicVersion
|
|
86
86
|
implementation "com.facebook.react:react-native:+"
|
|
87
87
|
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
|
88
|
-
implementation "com.posthog:posthog-android:3.
|
|
88
|
+
implementation "com.posthog:posthog-android:3.53.6"
|
|
89
89
|
}
|
|
90
90
|
|
package/android/src/main/java/com/posthogreactnativeplugin/PosthogReactNativePluginModule.kt
CHANGED
|
@@ -7,9 +7,9 @@ import com.facebook.react.bridge.ReactContextBaseJavaModule
|
|
|
7
7
|
import com.facebook.react.bridge.ReactMethod
|
|
8
8
|
import com.facebook.react.bridge.ReadableMap
|
|
9
9
|
import com.facebook.react.bridge.UiThreadUtil
|
|
10
|
+
import com.facebook.react.common.JavascriptException
|
|
10
11
|
import com.posthog.PostHog
|
|
11
12
|
import com.posthog.PostHogConfig
|
|
12
|
-
import com.posthog.PostHogEvent
|
|
13
13
|
import com.posthog.android.PostHogAndroid
|
|
14
14
|
import com.posthog.android.PostHogAndroidConfig
|
|
15
15
|
import com.posthog.internal.PostHogPreferences
|
|
@@ -117,7 +117,7 @@ class PosthogReactNativePluginModule(
|
|
|
117
117
|
|
|
118
118
|
// React Native rethrows fatal JS errors natively as JavascriptException.
|
|
119
119
|
// The JS layer already captured them, so drop the native duplicate.
|
|
120
|
-
|
|
120
|
+
errorTrackingConfig.ignoredExceptionTypes.add(JavascriptException::class.java)
|
|
121
121
|
|
|
122
122
|
// Always apply the session replay configuration so that recording started later
|
|
123
123
|
// (e.g. startRecording or a linked feature flag) uses the right mode and masking;
|
|
@@ -320,16 +320,6 @@ class PosthogReactNativePluginModule(
|
|
|
320
320
|
key: String,
|
|
321
321
|
): Double? = runCatching { if (hasKey(map, key)) map?.getDouble(key) else null }.getOrNull()
|
|
322
322
|
|
|
323
|
-
private fun isReactNativeFatalJsError(event: PostHogEvent): Boolean {
|
|
324
|
-
if (event.event != "\$exception") return false
|
|
325
|
-
val exceptionList = event.properties?.get("\$exception_list") as? List<*> ?: return false
|
|
326
|
-
return exceptionList.any { item ->
|
|
327
|
-
val exception = item as? Map<*, *> ?: return@any false
|
|
328
|
-
exception["type"] == "JavascriptException" &&
|
|
329
|
-
(exception["module"] as? String)?.startsWith("com.facebook.react") == true
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
|
|
333
323
|
private fun logError(
|
|
334
324
|
method: String,
|
|
335
325
|
error: Throwable,
|
|
@@ -5,7 +5,18 @@ private func hedgeLog(_ message: String) {
|
|
|
5
5
|
print("[PostHog] \(message)")
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
#if !os(iOS)
|
|
9
|
+
// Session replay is part of posthog-ios's iOS-only surface, so recording is a no-op on macOS.
|
|
10
|
+
// Log once so a caller isn't left wondering why recording "started" but nothing arrives.
|
|
11
|
+
private var didLogSessionReplayUnsupported = false
|
|
12
|
+
private func logSessionReplayUnsupportedOnMacOS() {
|
|
13
|
+
guard !didLogSessionReplayUnsupported else { return }
|
|
14
|
+
didLogSessionReplayUnsupported = true
|
|
15
|
+
hedgeLog("Session replay is not supported on macOS")
|
|
16
|
+
}
|
|
17
|
+
#endif
|
|
18
|
+
|
|
19
|
+
// Deduplication works on Android (both architectures), iOS (old architecture only), and macOS.
|
|
9
20
|
// On the iOS new architecture, fatal JS exception events surface as a generic SIGABRT
|
|
10
21
|
// crash event with no JS-error text in any field, so they currently cannot be filtered.
|
|
11
22
|
private let fatalJsErrorMarkers = ["Unhandled JS Exception", "ExceptionsManager.reportException", "facebook::jsi::JSError"]
|
|
@@ -126,49 +137,53 @@ class PosthogReactNativePlugin: NSObject {
|
|
|
126
137
|
isReactNativeFatalJsError(event) ? nil : event
|
|
127
138
|
}
|
|
128
139
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
140
|
+
// Surveys and session replay are iOS-only in posthog-ios, so the APIs below
|
|
141
|
+
// don't exist on macOS. macOS gets error tracking only.
|
|
142
|
+
#if os(iOS)
|
|
143
|
+
if #available(iOS 15.0, *) {
|
|
144
|
+
config.surveys = false
|
|
145
|
+
}
|
|
132
146
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
147
|
+
// Always apply the session replay configuration so that recording started later
|
|
148
|
+
// (e.g. startRecording or a linked feature flag) uses the right mode and masking;
|
|
149
|
+
// sessionReplayEnabled only controls whether recording starts at setup.
|
|
150
|
+
config.sessionReplay = sessionReplayEnabled
|
|
151
|
+
config.sessionReplayConfig.screenshotMode = true
|
|
138
152
|
|
|
139
|
-
|
|
140
|
-
|
|
153
|
+
let maskAllTextInputs = sdkReplayConfig["maskAllTextInputs"] as? Bool ?? true
|
|
154
|
+
config.sessionReplayConfig.maskAllTextInputs = maskAllTextInputs
|
|
141
155
|
|
|
142
|
-
|
|
143
|
-
|
|
156
|
+
let maskAllImages = sdkReplayConfig["maskAllImages"] as? Bool ?? true
|
|
157
|
+
config.sessionReplayConfig.maskAllImages = maskAllImages
|
|
144
158
|
|
|
145
|
-
|
|
146
|
-
|
|
159
|
+
let maskAllSandboxedViews = sdkReplayConfig["maskAllSandboxedViews"] as? Bool ?? true
|
|
160
|
+
config.sessionReplayConfig.maskAllSandboxedViews = maskAllSandboxedViews
|
|
147
161
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
162
|
+
// read throttleDelayMs and use iOSdebouncerDelayMs as a fallback for back compatibility
|
|
163
|
+
let throttleDelayMs =
|
|
164
|
+
(sdkReplayConfig["throttleDelayMs"] as? Int)
|
|
165
|
+
?? (sdkReplayConfig["iOSdebouncerDelayMs"] as? Int)
|
|
166
|
+
?? 1000
|
|
153
167
|
|
|
154
|
-
|
|
155
|
-
|
|
168
|
+
let timeInterval: TimeInterval = Double(throttleDelayMs) / 1000.0
|
|
169
|
+
config.sessionReplayConfig.throttleDelay = timeInterval
|
|
156
170
|
|
|
157
|
-
|
|
158
|
-
|
|
171
|
+
let captureNetworkTelemetry = sdkReplayConfig["captureNetworkTelemetry"] as? Bool ?? true
|
|
172
|
+
config.sessionReplayConfig.captureNetworkTelemetry = captureNetworkTelemetry
|
|
159
173
|
|
|
160
|
-
|
|
161
|
-
|
|
174
|
+
let captureLog = sdkReplayConfig["captureLog"] as? Bool ?? true
|
|
175
|
+
config.sessionReplayConfig.captureLogs = captureLog
|
|
162
176
|
|
|
163
|
-
|
|
177
|
+
config.sessionReplayConfig.sampleRate = sdkReplayConfig["sampleRate"] as? NSNumber
|
|
164
178
|
|
|
165
|
-
|
|
166
|
-
|
|
179
|
+
let screenshotModeBackgroundCapture = sdkReplayConfig["screenshotModeBackgroundCapture"] as? Bool ?? false
|
|
180
|
+
config.sessionReplayConfig.screenshotModeBackgroundCapture = screenshotModeBackgroundCapture
|
|
167
181
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
182
|
+
let endpoint = decideReplayConfig["endpoint"] as? String ?? ""
|
|
183
|
+
if !endpoint.isEmpty {
|
|
184
|
+
config.snapshotEndpoint = endpoint
|
|
185
|
+
}
|
|
186
|
+
#endif
|
|
172
187
|
|
|
173
188
|
let distinctId = sdkOptions["distinctId"] as? String ?? ""
|
|
174
189
|
let anonymousId = sdkOptions["anonymousId"] as? String ?? ""
|
|
@@ -221,8 +236,12 @@ class PosthogReactNativePlugin: NSObject {
|
|
|
221
236
|
|
|
222
237
|
@objc(isEnabled:withRejecter:)
|
|
223
238
|
func isEnabled(resolve: RCTPromiseResolveBlock, reject _: RCTPromiseRejectBlock) {
|
|
224
|
-
|
|
225
|
-
|
|
239
|
+
#if os(iOS)
|
|
240
|
+
resolve(PostHogSDK.shared.isSessionReplayActive())
|
|
241
|
+
#else
|
|
242
|
+
// Session replay is unsupported on macOS.
|
|
243
|
+
resolve(false)
|
|
244
|
+
#endif
|
|
226
245
|
}
|
|
227
246
|
|
|
228
247
|
@objc(endSession:withRejecter:)
|
|
@@ -261,13 +280,21 @@ class PosthogReactNativePlugin: NSObject {
|
|
|
261
280
|
func startRecording(
|
|
262
281
|
resumeCurrent: Bool, resolve: RCTPromiseResolveBlock, reject _: RCTPromiseRejectBlock
|
|
263
282
|
) {
|
|
264
|
-
|
|
283
|
+
#if os(iOS)
|
|
284
|
+
PostHogSDK.shared.startSessionRecording(resumeCurrent: resumeCurrent)
|
|
285
|
+
#else
|
|
286
|
+
logSessionReplayUnsupportedOnMacOS()
|
|
287
|
+
#endif
|
|
265
288
|
resolve(nil)
|
|
266
289
|
}
|
|
267
290
|
|
|
268
291
|
@objc(stopRecording:withRejecter:)
|
|
269
292
|
func stopRecording(resolve: RCTPromiseResolveBlock, reject _: RCTPromiseRejectBlock) {
|
|
270
|
-
|
|
293
|
+
#if os(iOS)
|
|
294
|
+
PostHogSDK.shared.stopSessionRecording()
|
|
295
|
+
#else
|
|
296
|
+
logSessionReplayUnsupportedOnMacOS()
|
|
297
|
+
#endif
|
|
271
298
|
resolve(nil)
|
|
272
299
|
}
|
|
273
300
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@posthog/react-native-plugin",
|
|
3
|
-
"version": "2.1
|
|
3
|
+
"version": "2.2.1",
|
|
4
4
|
"description": "PostHog React Native plugin for iOS and Android integrations",
|
|
5
5
|
"source": "./src/index.tsx",
|
|
6
6
|
"main": "./lib/commonjs/index.js",
|
|
@@ -39,7 +39,8 @@
|
|
|
39
39
|
"keywords": [
|
|
40
40
|
"react-native",
|
|
41
41
|
"ios",
|
|
42
|
-
"android"
|
|
42
|
+
"android",
|
|
43
|
+
"macos"
|
|
43
44
|
],
|
|
44
45
|
"repository": {
|
|
45
46
|
"type": "git",
|
|
@@ -16,7 +16,7 @@ Pod::Spec.new do |s|
|
|
|
16
16
|
s.license = package["license"]
|
|
17
17
|
s.authors = package["author"]
|
|
18
18
|
|
|
19
|
-
s.platforms = { :ios => min_ios_version_supported }
|
|
19
|
+
s.platforms = { :ios => min_ios_version_supported, :osx => '10.15' }
|
|
20
20
|
s.source = { :git => "https://github.com/PostHog/posthog-js.git", :tag => "@posthog/react-native-plugin@#{s.version}" }
|
|
21
21
|
|
|
22
22
|
s.source_files = "ios/**/*.{swift,h,hpp,m,mm,c,cpp}"
|
|
@@ -40,6 +40,7 @@ Pod::Spec.new do |s|
|
|
|
40
40
|
s.dependency 'PostHog', "~> #{posthog_ios_version}"
|
|
41
41
|
end
|
|
42
42
|
s.ios.deployment_target = '13.0'
|
|
43
|
+
s.osx.deployment_target = '10.15'
|
|
43
44
|
s.swift_versions = "5.3"
|
|
44
45
|
|
|
45
46
|
|