@amplitude/plugin-engagement-react-native 0.1.1-alpha.9 → 0.2.0-alpha.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/PluginEngagementReactNative.podspec +3 -3
- package/README.md +19 -19
- package/android/build.gradle +1 -1
- package/android/src/main/java/com/amplitude/pluginengagementreactnative/PluginEngagementReactNativeModule.kt +18 -3
- package/android/src/main/java/com/amplitude/pluginengagementreactnative/Util.kt +51 -0
- package/ios/AmplitudeEngagementAdapter.swift +78 -47
- package/ios/PluginEngagementReactNative.h +1 -1
- package/ios/PluginEngagementReactNative.mm +5 -1
- package/lib/module/AmplitudeEngagement.js.map +1 -1
- package/lib/module/AmplitudeEngagementPlugin.js +26 -5
- package/lib/module/AmplitudeEngagementPlugin.js.map +1 -1
- package/lib/module/NativePluginEngagementReactNative.js.map +1 -1
- package/lib/module/index.js +5 -1
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/src/AmplitudeEngagement.d.ts +2 -2
- package/lib/typescript/src/AmplitudeEngagement.d.ts.map +1 -1
- package/lib/typescript/src/AmplitudeEngagementPlugin.d.ts +10 -2
- package/lib/typescript/src/AmplitudeEngagementPlugin.d.ts.map +1 -1
- package/lib/typescript/src/NativePluginEngagementReactNative.d.ts +7 -1
- package/lib/typescript/src/NativePluginEngagementReactNative.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +4 -3
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +13 -0
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/AmplitudeEngagement.ts +2 -2
- package/src/AmplitudeEngagementPlugin.ts +43 -6
- package/src/NativePluginEngagementReactNative.ts +8 -1
- package/src/index.tsx +12 -4
- package/src/types.ts +14 -0
|
@@ -15,8 +15,8 @@ Pod::Spec.new do |s|
|
|
|
15
15
|
|
|
16
16
|
s.source_files = "ios/**/*.{h,m,mm,cpp,swift}"
|
|
17
17
|
s.private_header_files = "ios/**/*.h"
|
|
18
|
-
|
|
19
|
-
s.dependency "AmplitudeEngagementSwift"
|
|
20
|
-
|
|
18
|
+
|
|
19
|
+
s.dependency "AmplitudeEngagementSwift", ">=1.0.6"
|
|
20
|
+
|
|
21
21
|
install_modules_dependencies(s)
|
|
22
22
|
end
|
package/README.md
CHANGED
|
@@ -5,29 +5,19 @@ Amplitude Engagement plugin for React Native
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
7
|
To install:
|
|
8
|
+
|
|
8
9
|
- Add `@amplitude/analytics-react-native` and `@amplitude/plugin-engagement-react-native`
|
|
9
10
|
- Also, add `@react-native-async-storage/async-storage`
|
|
10
11
|
- Why? This is used by the `engagement` native module, but the CLI only auto links native modules which you directly depend on in your app’s `package.json`
|
|
11
12
|
|
|
12
|
-
|
|
13
13
|
```sh
|
|
14
14
|
npm install @amplitude/analytics-react-native
|
|
15
|
-
npm install @amplitude/plugin-engagement-react-native
|
|
16
15
|
npm install @react-native-async-storage/async-storage
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
Add the source for the `AmplitudeEngagementSwift` pod to your Podfile:
|
|
20
|
-
```rb
|
|
21
|
-
target '<your appname>' do
|
|
22
|
-
...
|
|
23
|
-
|
|
24
|
-
pod "AmplitudeEngagementSwift", :git => "https://github.com/amplitude/Amplitude-Engagement-Swift"
|
|
25
|
-
|
|
26
|
-
...
|
|
27
|
-
end
|
|
16
|
+
npm install @amplitude/plugin-engagement-react-native
|
|
28
17
|
```
|
|
29
18
|
|
|
30
19
|
Re-run `pod install` in the `ios` directory:
|
|
20
|
+
|
|
31
21
|
```sh
|
|
32
22
|
$ cd ios
|
|
33
23
|
$ bundle exec pod install
|
|
@@ -68,6 +58,7 @@ Linking.addEventListener('url', async ({ url }) => {
|
|
|
68
58
|
```
|
|
69
59
|
|
|
70
60
|
### Linking setup
|
|
61
|
+
|
|
71
62
|
If you don't already have it set up, please follow this guide to enable deep-linking support in your React Native app in addition to adding the above Linking code:
|
|
72
63
|
https://reactnative.dev/docs/linking#enabling-deep-links
|
|
73
64
|
|
|
@@ -75,21 +66,30 @@ Then, following the Alpha Onboarding guide to setup the "scheme" for the deep li
|
|
|
75
66
|
|
|
76
67
|
### Boot
|
|
77
68
|
|
|
78
|
-
Finally, “boot” with the user’s ID:
|
|
69
|
+
Finally, “boot” the plugin with the user’s ID; "booting" the SDK enables Guides and Surveys to be shown:
|
|
79
70
|
|
|
80
71
|
```
|
|
81
72
|
import {
|
|
82
|
-
|
|
83
|
-
|
|
73
|
+
track,
|
|
74
|
+
setDeviceId,
|
|
75
|
+
setUserId,
|
|
76
|
+
} from '@amplitude/analytics-react-native';
|
|
77
|
+
import { useEffect } from 'react';
|
|
84
78
|
|
|
85
79
|
export default function App() {
|
|
86
80
|
useEffect(() => {
|
|
87
|
-
|
|
81
|
+
//
|
|
82
|
+
// NOTE: setting the User ID in @amplitude/analytics-react-native
|
|
83
|
+
// --and-- passing it to boot() is necessary for now, but in a
|
|
84
|
+
// future version will not be necessary
|
|
85
|
+
//
|
|
86
|
+
setUserId('rn-test-user-1');
|
|
87
|
+
setDeviceId('test-device-1');
|
|
88
|
+
getPlugin().boot('rn-test-user-1', 'test-device-1');
|
|
88
89
|
}, []);
|
|
89
90
|
|
|
90
91
|
```
|
|
91
92
|
|
|
92
|
-
|
|
93
93
|
## License
|
|
94
94
|
|
|
95
|
-
MIT
|
|
95
|
+
MIT
|
package/android/build.gradle
CHANGED
|
@@ -76,7 +76,7 @@ dependencies {
|
|
|
76
76
|
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
|
77
77
|
|
|
78
78
|
// Amplitude Engagement SDK
|
|
79
|
-
implementation "com.amplitude:amplitude-engagement-android:1.0.
|
|
79
|
+
implementation "com.amplitude:amplitude-engagement-android:1.0.15"
|
|
80
80
|
|
|
81
81
|
// Amplitude Analytics SDK (required dependency)
|
|
82
82
|
implementation "com.amplitude:analytics-android:1.+"
|
|
@@ -6,7 +6,9 @@ import android.content.Intent
|
|
|
6
6
|
import android.os.Bundle
|
|
7
7
|
import android.util.Log
|
|
8
8
|
import androidx.core.net.toUri
|
|
9
|
+
import com.amplitude.android.engagement.AmplitudeBootOptions
|
|
9
10
|
import com.amplitude.android.engagement.AmplitudeEngagement
|
|
11
|
+
import com.amplitude.android.engagement.__ReactNative__AESDK
|
|
10
12
|
import com.amplitude.android.engagement.AmplitudeInitOptions
|
|
11
13
|
import com.amplitude.android.engagement.ui.theme.ThemeMode
|
|
12
14
|
import com.amplitude.core.events.BaseEvent
|
|
@@ -74,12 +76,25 @@ class PluginEngagementReactNativeModule(val reactContext: ReactApplicationContex
|
|
|
74
76
|
}
|
|
75
77
|
}
|
|
76
78
|
|
|
77
|
-
override fun boot(id: Double, userId: String
|
|
79
|
+
override fun boot(id: Double, userId: String?, deviceId: String?) {
|
|
78
80
|
val instance = instances[id]?.instance ?: return
|
|
79
|
-
|
|
81
|
+
val self = this
|
|
80
82
|
runBlocking(Dispatchers.Main) {
|
|
81
83
|
Log.d("PluginEngagementReactNativeModule", "boot: $userId, $deviceId")
|
|
82
|
-
|
|
84
|
+
val options = AmplitudeBootOptions(userId=userId ?: "", deviceId=deviceId, integrations = arrayOf(
|
|
85
|
+
{ event: BaseEvent ->
|
|
86
|
+
try {
|
|
87
|
+
val serializedEvent = mapOf(
|
|
88
|
+
"event_type" to event.eventType,
|
|
89
|
+
"event_properties" to event.eventProperties
|
|
90
|
+
).toWritableMap()
|
|
91
|
+
self.emitOnTrackEvent(serializedEvent)
|
|
92
|
+
} catch (e: Exception) {
|
|
93
|
+
Log.e("PluginEngagementReactNativeModule", "Error tracking Event", e)
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
))
|
|
97
|
+
instance.boot(options)
|
|
83
98
|
}
|
|
84
99
|
}
|
|
85
100
|
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
package com.amplitude.pluginengagementreactnative
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.Arguments
|
|
4
|
+
import com.facebook.react.bridge.WritableArray
|
|
5
|
+
import com.facebook.react.bridge.WritableMap
|
|
6
|
+
|
|
7
|
+
fun Iterable<*>.toWritableArray(): WritableArray {
|
|
8
|
+
val iter = this.iterator()
|
|
9
|
+
|
|
10
|
+
val writableArray: WritableArray = Arguments.createArray()
|
|
11
|
+
|
|
12
|
+
while (iter.hasNext()) {
|
|
13
|
+
val value = iter.next()
|
|
14
|
+
|
|
15
|
+
when (value) {
|
|
16
|
+
null -> writableArray.pushNull()
|
|
17
|
+
is Boolean -> writableArray.pushBoolean(value)
|
|
18
|
+
is Double -> writableArray.pushDouble(value)
|
|
19
|
+
is Int -> writableArray.pushInt(value)
|
|
20
|
+
is String -> writableArray.pushString(value)
|
|
21
|
+
is Map<*, *> -> writableArray.pushMap((value as Map<String, Any?>).toWritableMap())
|
|
22
|
+
else -> throw IllegalArgumentException("Cannot convert value of type ${value.javaClass.simpleName}")
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return writableArray
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
fun Map<String, *>.toWritableMap(): WritableMap {
|
|
31
|
+
val writableMap: WritableMap = Arguments.createMap()
|
|
32
|
+
val iterator = entries.iterator()
|
|
33
|
+
|
|
34
|
+
while (iterator.hasNext()) {
|
|
35
|
+
val pair = iterator.next()
|
|
36
|
+
val value = pair.value
|
|
37
|
+
|
|
38
|
+
when {
|
|
39
|
+
value == null -> writableMap.putNull(pair.key)
|
|
40
|
+
value is Boolean -> writableMap.putBoolean(pair.key, value)
|
|
41
|
+
value is Double -> writableMap.putDouble(pair.key, value)
|
|
42
|
+
value is Int -> writableMap.putInt(pair.key, value)
|
|
43
|
+
value is String -> writableMap.putString(pair.key, value)
|
|
44
|
+
value is Map<*, *> -> writableMap.putMap(pair.key, (value as Map<String, *>).toWritableMap())
|
|
45
|
+
value is Iterable<*> -> writableMap.putArray(pair.key, value.toWritableArray())
|
|
46
|
+
else -> throw IllegalArgumentException("Cannot convert value of type ${value.javaClass.simpleName}")
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return writableMap
|
|
51
|
+
}
|
|
@@ -5,117 +5,148 @@
|
|
|
5
5
|
// Created by Jared Luxenberg on 5/19/25.
|
|
6
6
|
//
|
|
7
7
|
|
|
8
|
-
import Foundation
|
|
9
8
|
import AmplitudeEngagementSwift
|
|
10
|
-
|
|
9
|
+
import Foundation
|
|
11
10
|
|
|
12
11
|
extension Encodable {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
12
|
+
/// Converting object to postable dictionary
|
|
13
|
+
func toDictionary(_ encoder: JSONEncoder = JSONEncoder()) throws -> [String: Any] {
|
|
14
|
+
let data = try encoder.encode(self)
|
|
15
|
+
let object = try JSONSerialization.jsonObject(with: data)
|
|
16
|
+
if let json = object as? [String: Any] { return json }
|
|
17
|
+
|
|
18
|
+
let context = DecodingError.Context(
|
|
19
|
+
codingPath: [], debugDescription: "Deserialized object is not a dictionary")
|
|
20
|
+
throw DecodingError.typeMismatch(type(of: object), context)
|
|
21
|
+
}
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
// id -> (api_key, amplitude engagement instance)
|
|
25
25
|
var instances: [Int: (String, AmplitudeEngagement)] = [:]
|
|
26
26
|
var _id = 0
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
/// `@objc` attribute exposes Swift methods to the Objective-C runtime*
|
|
29
29
|
@objc public class AmplitudeEngagementAdapter: NSObject {
|
|
30
30
|
@objc public func newInstance(_ apiKey: String) -> Int {
|
|
31
31
|
if let existingId = instances.first(where: { $0.value.0 == apiKey })?.key {
|
|
32
|
-
|
|
32
|
+
return existingId
|
|
33
33
|
}
|
|
34
|
-
|
|
34
|
+
|
|
35
35
|
return DispatchQueue.main.sync {
|
|
36
|
-
_id += 1
|
|
37
|
-
let id = _id + 1
|
|
38
|
-
instances[id] = (
|
|
36
|
+
_id += 1
|
|
37
|
+
let id = _id + 1
|
|
38
|
+
instances[id] = (
|
|
39
|
+
apiKey,
|
|
40
|
+
__ReactNative__AESDK(apiKey, AmplitudeInitOptions(logLevel: AmplitudeLogLevel.verbose))
|
|
41
|
+
)
|
|
39
42
|
return id
|
|
40
43
|
}
|
|
41
44
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
+
|
|
46
|
+
@objc public func boot(
|
|
47
|
+
_ instanceId: Int, _ user_id: String, device_id: String? = nil,
|
|
48
|
+
integration: @escaping (_ event_type: String, _ event: [String: Any]) -> Void
|
|
49
|
+
) {
|
|
45
50
|
DispatchQueue.main.sync {
|
|
46
51
|
guard let (_, instance) = instances[instanceId] else { return }
|
|
47
|
-
|
|
48
|
-
|
|
52
|
+
let options = AmplitudeBootOptions(
|
|
53
|
+
user_id: user_id, device_id: device_id,
|
|
54
|
+
integrations: [
|
|
55
|
+
{ event, props in
|
|
56
|
+
integration(event, props)
|
|
57
|
+
}
|
|
58
|
+
])
|
|
59
|
+
return instance.boot(options: options)
|
|
49
60
|
}
|
|
50
61
|
}
|
|
51
|
-
|
|
62
|
+
|
|
52
63
|
@objc public func setThemeMode(_ instanceId: Int, themeMode: String) {
|
|
53
64
|
DispatchQueue.main.sync {
|
|
54
|
-
guard let (_, instance) = instances[instanceId] else {
|
|
65
|
+
guard let (_, instance) = instances[instanceId] else {
|
|
66
|
+
fatalError("🚨 Runtime exception: no instance found for id “\(instanceId)”")
|
|
67
|
+
}
|
|
55
68
|
guard let themeModeParsed = ThemeMode(rawValue: themeMode) else { return }
|
|
56
|
-
|
|
69
|
+
|
|
57
70
|
return instance.setThemeMode(themeMode: themeModeParsed)
|
|
58
71
|
}
|
|
59
72
|
}
|
|
60
|
-
|
|
73
|
+
|
|
61
74
|
@objc public func reset(_ instanceId: Int, key: String, stepIndex: Int = 0) {
|
|
62
75
|
DispatchQueue.main.sync {
|
|
63
|
-
guard let (_, instance) = instances[instanceId] else {
|
|
64
|
-
|
|
76
|
+
guard let (_, instance) = instances[instanceId] else {
|
|
77
|
+
fatalError("🚨 Runtime exception: no instance found for id “\(instanceId)”")
|
|
78
|
+
}
|
|
79
|
+
|
|
65
80
|
return instance.reset(key: key, stepIndex: stepIndex)
|
|
66
81
|
}
|
|
67
82
|
}
|
|
68
|
-
|
|
83
|
+
|
|
69
84
|
@objc public func list(_ instanceId: Int) -> [[String: Any]] {
|
|
70
85
|
DispatchQueue.main.sync {
|
|
71
|
-
guard let (_, instance) = instances[instanceId] else {
|
|
72
|
-
|
|
86
|
+
guard let (_, instance) = instances[instanceId] else {
|
|
87
|
+
fatalError("🚨 Runtime exception: no instance found for id “\(instanceId)”")
|
|
88
|
+
}
|
|
89
|
+
|
|
73
90
|
return instance.list().compactMap { x in try? x.toDictionary() }
|
|
74
91
|
}
|
|
75
92
|
}
|
|
76
|
-
|
|
93
|
+
|
|
77
94
|
@objc public func handleUrl(_ instanceId: Int, _ url: String) -> Bool {
|
|
78
95
|
DispatchQueue.main.sync {
|
|
79
|
-
guard let (_, instance) = instances[instanceId] else {
|
|
80
|
-
|
|
81
|
-
|
|
96
|
+
guard let (_, instance) = instances[instanceId] else {
|
|
97
|
+
fatalError("🚨 Runtime exception: no instance found for id “\(instanceId)”")
|
|
98
|
+
}
|
|
99
|
+
guard let url = URL(string: url) else { return false }
|
|
100
|
+
|
|
82
101
|
return instance.handleUrl(url)
|
|
83
102
|
}
|
|
84
103
|
}
|
|
85
|
-
|
|
104
|
+
|
|
86
105
|
@objc public func show(_ instanceId: Int, key: String, stepIndex: Int = 0) {
|
|
87
106
|
DispatchQueue.main.sync {
|
|
88
|
-
guard let (_, instance) = instances[instanceId] else {
|
|
107
|
+
guard let (_, instance) = instances[instanceId] else {
|
|
108
|
+
fatalError("🚨 Runtime exception: no instance found for id “\(instanceId)”")
|
|
109
|
+
}
|
|
89
110
|
return instance.show(key: key, stepIndex: stepIndex)
|
|
90
111
|
}
|
|
91
112
|
}
|
|
92
|
-
|
|
113
|
+
|
|
93
114
|
@objc public func screen(_ instanceId: Int, _ screenName: String) {
|
|
94
115
|
DispatchQueue.main.sync {
|
|
95
|
-
guard let (_, instance) = instances[instanceId] else {
|
|
116
|
+
guard let (_, instance) = instances[instanceId] else {
|
|
117
|
+
fatalError("🚨 Runtime exception: no instance found for id “\(instanceId)”")
|
|
118
|
+
}
|
|
96
119
|
return instance.screen(screenName)
|
|
97
120
|
}
|
|
98
121
|
}
|
|
99
|
-
|
|
122
|
+
|
|
100
123
|
@objc public func closeAll(_ instanceId: Int) {
|
|
101
124
|
DispatchQueue.main.sync {
|
|
102
|
-
guard let (_, instance) = instances[instanceId] else {
|
|
125
|
+
guard let (_, instance) = instances[instanceId] else {
|
|
126
|
+
fatalError("🚨 Runtime exception: no instance found for id “\(instanceId)”")
|
|
127
|
+
}
|
|
103
128
|
return instance.closeAll()
|
|
104
129
|
}
|
|
105
130
|
}
|
|
106
|
-
|
|
131
|
+
|
|
107
132
|
@objc public func forwardEvent(_ instanceId: Int, _ event: [String: Any]) {
|
|
108
133
|
DispatchQueue.main.sync {
|
|
109
|
-
guard let (_, instance) = instances[instanceId] else {
|
|
134
|
+
guard let (_, instance) = instances[instanceId] else {
|
|
135
|
+
fatalError("🚨 Runtime exception: no instance found for id “\(instanceId)”")
|
|
136
|
+
}
|
|
110
137
|
return instance.forwardEvent(event)
|
|
111
138
|
}
|
|
112
139
|
}
|
|
113
|
-
|
|
114
|
-
@objc(addCallback:::) public func addCallback(
|
|
140
|
+
|
|
141
|
+
@objc(addCallback:::) public func addCallback(
|
|
142
|
+
_ instanceId: Int, _ key: String, _ function: @escaping () -> Void
|
|
143
|
+
) {
|
|
115
144
|
DispatchQueue.main.sync {
|
|
116
|
-
guard let (_, instance) = instances[instanceId] else {
|
|
145
|
+
guard let (_, instance) = instances[instanceId] else {
|
|
146
|
+
fatalError("🚨 Runtime exception: no instance found for id “\(instanceId)”")
|
|
147
|
+
}
|
|
117
148
|
return instance.addCallback(key, function)
|
|
118
149
|
}
|
|
119
150
|
}
|
|
120
|
-
|
|
151
|
+
|
|
121
152
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#import <PluginEngagementReactNativeSpec/PluginEngagementReactNativeSpec.h>
|
|
2
2
|
|
|
3
|
-
@interface PluginEngagementReactNative :
|
|
3
|
+
@interface PluginEngagementReactNative : NativePluginEngagementReactNativeSpecBase <NativePluginEngagementReactNativeSpec>
|
|
4
4
|
|
|
5
5
|
@end
|
|
@@ -29,7 +29,11 @@
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
- (void)boot:(double)id user_id:(nonnull NSString *)user_id device_id:(nonnull NSString *)device_id {
|
|
32
|
-
|
|
32
|
+
void (^callback)(NSString *, NSDictionary *) = ^(NSString *event_type, NSDictionary *event) {
|
|
33
|
+
[self emitOnTrackEvent:@{@"event_type": event_type, @"event_properties": event}];
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
[adapter boot:id :user_id device_id:device_id integration:callback];
|
|
33
37
|
}
|
|
34
38
|
|
|
35
39
|
- (nonnull NSArray<NSDictionary *> *)list:(double)id {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["NativeModules","isTurboModuleEnabled","global","__turboModuleProxy","PluginEngagementReactNative","require","default","AmplitudeEngagement","constructor","apiKey","id","newInstance","boot","user_id","device_id","setThemeMode","themeMode","reset","key","stepIndex","list","show","screen","screenName","closeAll","forwardEvent","event","addCallback","func","handleURL","url"],"sourceRoot":"../../src","sources":["AmplitudeEngagement.ts"],"mappings":";;AACA,SAASA,aAAa,QAAQ,cAAc;AAM5C,MAAMC,oBAAoB,GAAIC,MAAM,CAASC,kBAAkB,IAAI,IAAI;AAEvE,MAAMC,2BAA4D,GAChEH,oBAAoB,GAChBI,OAAO,CAAC,qCAAqC,CAAC,CAACC,OAAO,GACtDN,aAAa,CAACI,2BAA2B;AAE/C,OAAO,MAAMG,mBAAmB,CAAC;EAG/BC,WAAWA,CAACC,MAAc,EAAE;IAC1B;IACA,IAAI,CAACC,EAAE,GAAGN,2BAA2B,CAACO,WAAW,CAACF,MAAM,CAAC;EAC3D;EAEAG,IAAIA,CAACC,
|
|
1
|
+
{"version":3,"names":["NativeModules","isTurboModuleEnabled","global","__turboModuleProxy","PluginEngagementReactNative","require","default","AmplitudeEngagement","constructor","apiKey","id","newInstance","boot","user_id","device_id","setThemeMode","themeMode","reset","key","stepIndex","list","show","screen","screenName","closeAll","forwardEvent","event","addCallback","func","handleURL","url"],"sourceRoot":"../../src","sources":["AmplitudeEngagement.ts"],"mappings":";;AACA,SAASA,aAAa,QAAQ,cAAc;AAM5C,MAAMC,oBAAoB,GAAIC,MAAM,CAASC,kBAAkB,IAAI,IAAI;AAEvE,MAAMC,2BAA4D,GAChEH,oBAAoB,GAChBI,OAAO,CAAC,qCAAqC,CAAC,CAACC,OAAO,GACtDN,aAAa,CAACI,2BAA2B;AAE/C,OAAO,MAAMG,mBAAmB,CAAC;EAG/BC,WAAWA,CAACC,MAAc,EAAE;IAC1B;IACA,IAAI,CAACC,EAAE,GAAGN,2BAA2B,CAACO,WAAW,CAACF,MAAM,CAAC;EAC3D;EAEAG,IAAIA,CAACC,OAAgB,EAAEC,SAAkB,EAAQ;IAC/CV,2BAA2B,CAACQ,IAAI,CAAC,IAAI,CAACF,EAAE,EAAEG,OAAO,EAAEC,SAAS,CAAC;EAC/D;EAEAC,YAAYA,CAACC,SAAoB,EAAQ;IACvC,OAAOZ,2BAA2B,CAACW,YAAY,CAAC,IAAI,CAACL,EAAE,EAAEM,SAAS,CAAC;EACrE;EAEAC,KAAKA,CAACC,GAAW,EAAEC,SAAiB,EAAQ;IAC1C,OAAOf,2BAA2B,CAACa,KAAK,CAAC,IAAI,CAACP,EAAE,EAAEQ,GAAG,EAAEC,SAAS,CAAC;EACnE;EAEAC,IAAIA,CAAA,EAAoB;IACtB,OAAOhB,2BAA2B,CAACgB,IAAI,CAAC,IAAI,CAACV,EAAE,CAAC;EAClD;EAEAW,IAAIA,CAACH,GAAW,EAAEC,SAAiB,EAAQ;IACzC,OAAOf,2BAA2B,CAACiB,IAAI,CAAC,IAAI,CAACX,EAAE,EAAEQ,GAAG,EAAEC,SAAS,CAAC;EAClE;EAEAG,MAAMA,CAACC,UAAkB,EAAQ;IAC/B,OAAOnB,2BAA2B,CAACkB,MAAM,CAAC,IAAI,CAACZ,EAAE,EAAEa,UAAU,CAAC;EAChE;EAEAC,QAAQA,CAAA,EAAS;IACf,OAAOpB,2BAA2B,CAACoB,QAAQ,CAAC,IAAI,CAACd,EAAE,CAAC;EACtD;EAEAe,YAAYA,CAACC,KAAgB,EAAQ;IACnC,OAAOtB,2BAA2B,CAACqB,YAAY,CAAC,IAAI,CAACf,EAAE,EAAEgB,KAAK,CAAC;EACjE;EAEAC,WAAWA,CAACT,GAAW,EAAEU,IAAgB,EAAQ;IAC/C,OAAOxB,2BAA2B,CAACuB,WAAW,CAAC,IAAI,CAACjB,EAAE,EAAEQ,GAAG,EAAEU,IAAI,CAAC;EACpE;EAEAC,SAASA,CAACC,GAAW,EAAW;IAC9B,OAAO1B,2BAA2B,CAACyB,SAAS,CAAC,IAAI,CAACnB,EAAE,EAAEoB,GAAG,CAAC;EAC5D;AACF","ignoreList":[]}
|
|
@@ -1,23 +1,44 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
import { forwardEvent, init, screen } from "./index.js";
|
|
3
|
+
import { forwardEvent, init, screen, boot } from "./index.js";
|
|
4
|
+
import NativePluginEngagementReactNative from "./NativePluginEngagementReactNative.js";
|
|
4
5
|
import { Logger } from "./logger.js";
|
|
5
6
|
export class AmplitudeEngagementPlugin {
|
|
6
7
|
name = 'AmplitudeEngagementPlugin';
|
|
7
8
|
type = 'enrichment';
|
|
8
9
|
logger = new Logger('AmplitudeEngagementPlugin');
|
|
9
|
-
|
|
10
|
+
trackEventSubscription = null;
|
|
11
|
+
async setup(config, client) {
|
|
10
12
|
try {
|
|
11
|
-
|
|
13
|
+
this.logger.log('initializing with apiKey', config.apiKey);
|
|
12
14
|
init(config.apiKey);
|
|
15
|
+
this.client = client;
|
|
16
|
+
// TODO: grab identity from client when available -- need to wait until it's added.
|
|
17
|
+
// Need to wait until https://amplitude.atlassian.net/browse/AMP-133461 is resolved
|
|
18
|
+
// then; follow the same pattern as in the `AmplitudeEngagementPlugin` in the Swift/iOS code
|
|
13
19
|
} catch (error) {
|
|
14
20
|
this.logger.error('AmplitudeEngagementPlugin#setup failed to initialize', error);
|
|
15
21
|
}
|
|
22
|
+
}
|
|
16
23
|
|
|
17
|
-
|
|
24
|
+
// TODO: for now, you must call `boot()` manually
|
|
25
|
+
// but once we have access to the identity from the client,
|
|
26
|
+
// we can call `boot()` automatically in `setup` and `onIdentityChanged`
|
|
27
|
+
boot(user_id, device_id) {
|
|
28
|
+
boot(user_id, device_id);
|
|
29
|
+
if (this.trackEventSubscription) {
|
|
30
|
+
this.trackEventSubscription.remove();
|
|
31
|
+
}
|
|
32
|
+
this.trackEventSubscription = NativePluginEngagementReactNative.onTrackEvent(event => {
|
|
33
|
+
if (!this.client) {
|
|
34
|
+
this.logger.error('AmplitudeEngagementPlugin#onIdentityChanged client is not initialized');
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
this.client?.track(event.event_type, event.event_properties);
|
|
38
|
+
});
|
|
18
39
|
}
|
|
19
40
|
async execute(context) {
|
|
20
|
-
|
|
41
|
+
this.logger.log(`AmplitudeEngagement#execute event=${JSON.stringify(context)}`);
|
|
21
42
|
if (context.event_type === '[Amplitude] Screen Viewed' && typeof context.event_properties?.['[Amplitude] Screen Name'] === 'string') {
|
|
22
43
|
const screenName = context.event_properties['[Amplitude] Screen Name'];
|
|
23
44
|
screen(screenName);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["forwardEvent","init","screen","Logger","AmplitudeEngagementPlugin","name","type","logger","
|
|
1
|
+
{"version":3,"names":["forwardEvent","init","screen","boot","NativePluginEngagementReactNative","Logger","AmplitudeEngagementPlugin","name","type","logger","trackEventSubscription","setup","config","client","log","apiKey","error","user_id","device_id","remove","onTrackEvent","event","track","event_type","event_properties","execute","context","JSON","stringify","screenName"],"sourceRoot":"../../src","sources":["AmplitudeEngagementPlugin.ts"],"mappings":";;AAMA,SAASA,YAAY,EAAEC,IAAI,EAAEC,MAAM,EAAEC,IAAI,QAAQ,YAAG;AACpD,OAAOC,iCAAiC,MAAM,wCAAqC;AAEnF,SAASC,MAAM,QAA8B,aAAU;AAGvD,OAAO,MAAMC,yBAAyB,CAA6B;EACjEC,IAAI,GAAG,2BAA2B;EAClCC,IAAI,GAAG,YAAY;EASnBC,MAAM,GAAoB,IAAIJ,MAAM,CAAC,2BAA2B,CAAC;EAEjEK,sBAAsB,GAA6B,IAAI;EAEvD,MAAMC,KAAKA,CAACC,MAAc,EAAEC,MAAkB,EAAiB;IAC7D,IAAI;MACF,IAAI,CAACJ,MAAM,CAACK,GAAG,CAAC,0BAA0B,EAAEF,MAAM,CAACG,MAAM,CAAC;MAC1Dd,IAAI,CAACW,MAAM,CAACG,MAAM,CAAC;MACnB,IAAI,CAACF,MAAM,GAAGA,MAAM;MACpB;MACA;MACA;IACF,CAAC,CAAC,OAAOG,KAAK,EAAE;MACd,IAAI,CAACP,MAAM,CAACO,KAAK,CACf,sDAAsD,EACtDA,KACF,CAAC;IACH;EACF;;EAEA;EACA;EACA;EACAb,IAAIA,CAACc,OAAgB,EAAEC,SAAkB,EAAQ;IAC/Cf,IAAI,CAACc,OAAO,EAAEC,SAAS,CAAC;IACxB,IAAI,IAAI,CAACR,sBAAsB,EAAE;MAC/B,IAAI,CAACA,sBAAsB,CAACS,MAAM,CAAC,CAAC;IACtC;IAEA,IAAI,CAACT,sBAAsB,GACzBN,iCAAiC,CAACgB,YAAY,CAAEC,KAAK,IAAK;MACxD,IAAI,CAAC,IAAI,CAACR,MAAM,EAAE;QAChB,IAAI,CAACJ,MAAM,CAACO,KAAK,CACf,uEACF,CAAC;QACD;MACF;MACA,IAAI,CAACH,MAAM,EAAES,KAAK,CAACD,KAAK,CAACE,UAAU,EAAEF,KAAK,CAACG,gBAAgB,CAAC;IAC9D,CAAC,CAAC;EACN;EAEA,MAAMC,OAAOA,CAACC,OAAc,EAAyB;IACnD,IAAI,CAACjB,MAAM,CAACK,GAAG,CACb,qCAAqCa,IAAI,CAACC,SAAS,CAACF,OAAO,CAAC,EAC9D,CAAC;IAED,IACEA,OAAO,CAACH,UAAU,KAAK,2BAA2B,IAClD,OAAOG,OAAO,CAACF,gBAAgB,GAAG,yBAAyB,CAAC,KAAK,QAAQ,EACzE;MACA,MAAMK,UAAU,GAAGH,OAAO,CAACF,gBAAgB,CACzC,yBAAyB,CAChB;MACXtB,MAAM,CAAC2B,UAAU,CAAC;IACpB;IAEA7B,YAAY,CAAC0B,OAAO,CAAC;IAErB,OAAOA,OAAO;EAChB;AACF","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["TurboModuleRegistry","getEnforcing"],"sourceRoot":"../../src","sources":["NativePluginEngagementReactNative.ts"],"mappings":";;AACA,SAASA,mBAAmB,QAAQ,cAAc;
|
|
1
|
+
{"version":3,"names":["TurboModuleRegistry","getEnforcing"],"sourceRoot":"../../src","sources":["NativePluginEngagementReactNative.ts"],"mappings":";;AACA,SAASA,mBAAmB,QAAQ,cAAc;AA+BlD,eAAeA,mBAAmB,CAACC,YAAY,CAC7C,6BACF,CAAC","ignoreList":[]}
|
package/lib/module/index.js
CHANGED
|
@@ -58,7 +58,11 @@ export async function handleURL(url) {
|
|
|
58
58
|
const e = await getGlobalEngagement();
|
|
59
59
|
return e.handleURL(url);
|
|
60
60
|
}
|
|
61
|
+
let plugin = null;
|
|
61
62
|
export function getPlugin() {
|
|
62
|
-
|
|
63
|
+
if (!plugin) {
|
|
64
|
+
plugin = new AmplitudeEngagementPlugin();
|
|
65
|
+
}
|
|
66
|
+
return plugin;
|
|
63
67
|
}
|
|
64
68
|
//# sourceMappingURL=index.js.map
|
package/lib/module/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["AmplitudeEngagement","AmplitudeEngagementPlugin","globalEngagement","toNotify","getGlobalEngagement","Promise","resolve","_reject","push","engagement","init","apiKey","Error","forEach","callback","boot","user_id","device_id","e","list","show","key","stepIndex","screen","screenName","closeAll","forwardEvent","event","addCallback","func","handleURL","url","getPlugin"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,SAASA,mBAAmB,QAAQ,0BAAuB;AAC3D,SAASC,yBAAyB,QAAQ,gCAA6B;AAIvE,IAAIC,gBAAqC,GAAG,IAAW;AACvD,IAAIC,QAAuD,GAAG,EAAE;AAEhE,eAAeC,mBAAmBA,CAAA,EAAiC;EACjE,IAAIF,gBAAgB,EAAE;IACpB,OAAOA,gBAAgB;EACzB,CAAC,MAAM;IACL,OAAO,MAAM,IAAIG,OAAO,CAAC,CAACC,OAAO,EAAEC,OAAO,KAAK;MAC7CJ,QAAQ,CAACK,IAAI,CAAEC,UAAU,IAAK;QAC5BH,OAAO,CAACG,UAAU,CAAC;MACrB,CAAC,CAAC;IACJ,CAAC,CAAC;EACJ;AACF;AAEA,OAAO,SAASC,IAAIA,CAACC,MAAc,EAAQ;EACzC;EACA,IAAIT,gBAAgB,EAAE;IACpB,MAAM,IAAIU,KAAK,CAAC,yCAAyC,CAAC;EAC5D;EACAV,gBAAgB,GAAG,IAAIF,mBAAmB,CAACW,MAAM,CAAC;EAClDR,QAAQ,CAACU,OAAO,CAAEC,QAAQ,IAAK;IAC7BA,QAAQ,CAACZ,gBAAgB,CAAC;EAC5B,CAAC,CAAC;EACFC,QAAQ,GAAG,EAAE;AACf;AAEA,OAAO,eAAeY,IAAIA,
|
|
1
|
+
{"version":3,"names":["AmplitudeEngagement","AmplitudeEngagementPlugin","globalEngagement","toNotify","getGlobalEngagement","Promise","resolve","_reject","push","engagement","init","apiKey","Error","forEach","callback","boot","user_id","device_id","e","list","show","key","stepIndex","screen","screenName","closeAll","forwardEvent","event","addCallback","func","handleURL","url","plugin","getPlugin"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,SAASA,mBAAmB,QAAQ,0BAAuB;AAC3D,SAASC,yBAAyB,QAAQ,gCAA6B;AAIvE,IAAIC,gBAAqC,GAAG,IAAW;AACvD,IAAIC,QAAuD,GAAG,EAAE;AAEhE,eAAeC,mBAAmBA,CAAA,EAAiC;EACjE,IAAIF,gBAAgB,EAAE;IACpB,OAAOA,gBAAgB;EACzB,CAAC,MAAM;IACL,OAAO,MAAM,IAAIG,OAAO,CAAC,CAACC,OAAO,EAAEC,OAAO,KAAK;MAC7CJ,QAAQ,CAACK,IAAI,CAAEC,UAAU,IAAK;QAC5BH,OAAO,CAACG,UAAU,CAAC;MACrB,CAAC,CAAC;IACJ,CAAC,CAAC;EACJ;AACF;AAEA,OAAO,SAASC,IAAIA,CAACC,MAAc,EAAQ;EACzC;EACA,IAAIT,gBAAgB,EAAE;IACpB,MAAM,IAAIU,KAAK,CAAC,yCAAyC,CAAC;EAC5D;EACAV,gBAAgB,GAAG,IAAIF,mBAAmB,CAACW,MAAM,CAAC;EAClDR,QAAQ,CAACU,OAAO,CAAEC,QAAQ,IAAK;IAC7BA,QAAQ,CAACZ,gBAAgB,CAAC;EAC5B,CAAC,CAAC;EACFC,QAAQ,GAAG,EAAE;AACf;AAEA,OAAO,eAAeY,IAAIA,CACxBC,OAAgB,EAChBC,SAAkB,EACH;EACf,MAAMC,CAAC,GAAG,MAAMd,mBAAmB,CAAC,CAAC;EACrC,OAAOc,CAAC,CAACH,IAAI,CAACC,OAAO,EAAEC,SAAS,CAAC;AACnC;AAEA,OAAO,eAAeE,IAAIA,CAAA,EAA6B;EACrD,MAAMD,CAAC,GAAG,MAAMd,mBAAmB,CAAC,CAAC;EACrC,OAAOc,CAAC,CAACC,IAAI,CAAC,CAAC;AACjB;AAEA,OAAO,eAAeC,IAAIA,CAACC,GAAW,EAAEC,SAAiB,EAAiB;EACxE,MAAMJ,CAAC,GAAG,MAAMd,mBAAmB,CAAC,CAAC;EACrC,OAAOc,CAAC,CAACE,IAAI,CAACC,GAAG,EAAEC,SAAS,CAAC;AAC/B;AAEA,OAAO,eAAeC,MAAMA,CAACC,UAAkB,EAAiB;EAC9D,MAAMN,CAAC,GAAG,MAAMd,mBAAmB,CAAC,CAAC;EACrC,OAAOc,CAAC,CAACK,MAAM,CAACC,UAAU,CAAC;AAC7B;AAEA,OAAO,eAAeC,QAAQA,CAAA,EAAkB;EAC9C,MAAMP,CAAC,GAAG,MAAMd,mBAAmB,CAAC,CAAC;EACrC,OAAOc,CAAC,CAACO,QAAQ,CAAC,CAAC;AACrB;AAEA,OAAO,eAAeC,YAAYA,CAACC,KAAgB,EAAiB;EAClE,MAAMT,CAAC,GAAG,MAAMd,mBAAmB,CAAC,CAAC;EACrC,OAAOc,CAAC,CAACQ,YAAY,CAACC,KAAK,CAAC;AAC9B;AAEA,OAAO,eAAeC,WAAWA,CAC/BP,GAAW,EACXQ,IAAgB,EACD;EACf,MAAMX,CAAC,GAAG,MAAMd,mBAAmB,CAAC,CAAC;EACrC,OAAOc,CAAC,CAACU,WAAW,CAACP,GAAG,EAAEQ,IAAI,CAAC;AACjC;AAEA,OAAO,eAAeC,SAASA,CAACC,GAAW,EAAoB;EAC7D,MAAMb,CAAC,GAAG,MAAMd,mBAAmB,CAAC,CAAC;EACrC,OAAOc,CAAC,CAACY,SAAS,CAACC,GAAG,CAAC;AACzB;AAEA,IAAIC,MAAwC,GAAG,IAAI;AACnD,OAAO,SAASC,SAASA,CAAA,EAA8B;EACrD,IAAI,CAACD,MAAM,EAAE;IACXA,MAAM,GAAG,IAAI/B,yBAAyB,CAAC,CAAC;EAC1C;EAEA,OAAO+B,MAAM;AACf","ignoreList":[]}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { GuideOrSurvey, ThemeMode } from './types';
|
|
2
|
-
import type { BaseEvent } from '@amplitude/analytics-
|
|
2
|
+
import type { BaseEvent } from '@amplitude/analytics-core';
|
|
3
3
|
export declare class AmplitudeEngagement {
|
|
4
4
|
id: number;
|
|
5
5
|
constructor(apiKey: string);
|
|
6
|
-
boot(user_id
|
|
6
|
+
boot(user_id?: string, device_id?: string): void;
|
|
7
7
|
setThemeMode(themeMode: ThemeMode): void;
|
|
8
8
|
reset(key: string, stepIndex: number): void;
|
|
9
9
|
list(): GuideOrSurvey[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AmplitudeEngagement.d.ts","sourceRoot":"","sources":["../../../src/AmplitudeEngagement.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACxD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"AmplitudeEngagement.d.ts","sourceRoot":"","sources":["../../../src/AmplitudeEngagement.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACxD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAW3D,qBAAa,mBAAmB;IAC9B,EAAE,EAAE,MAAM,CAAC;gBAEC,MAAM,EAAE,MAAM;IAK1B,IAAI,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI;IAIhD,YAAY,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI;IAIxC,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAI3C,IAAI,IAAI,aAAa,EAAE;IAIvB,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAI1C,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAIhC,QAAQ,IAAI,IAAI;IAIhB,YAAY,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI;IAIpC,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,IAAI,GAAG,IAAI;IAIhD,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;CAGhC"}
|
|
@@ -1,10 +1,18 @@
|
|
|
1
|
-
import type { Config, CoreClient, EnrichmentPlugin, Event } from '@amplitude/analytics-
|
|
1
|
+
import type { Config, CoreClient, EnrichmentPlugin, Event } from '@amplitude/analytics-core';
|
|
2
2
|
import { type AmplitudeLogger } from './logger';
|
|
3
|
+
import type { EventSubscription } from 'react-native';
|
|
3
4
|
export declare class AmplitudeEngagementPlugin implements EnrichmentPlugin {
|
|
4
5
|
name: string;
|
|
5
6
|
type: "enrichment";
|
|
7
|
+
client?: CoreClient;
|
|
8
|
+
userId?: string;
|
|
9
|
+
deviceId?: string;
|
|
10
|
+
sessionId?: number;
|
|
11
|
+
userProperties?: Record<string, any>;
|
|
6
12
|
logger: AmplitudeLogger;
|
|
7
|
-
|
|
13
|
+
trackEventSubscription: EventSubscription | null;
|
|
14
|
+
setup(config: Config, client: CoreClient): Promise<void>;
|
|
15
|
+
boot(user_id?: string, device_id?: string): void;
|
|
8
16
|
execute(context: Event): Promise<Event | null>;
|
|
9
17
|
}
|
|
10
18
|
//# sourceMappingURL=AmplitudeEngagementPlugin.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AmplitudeEngagementPlugin.d.ts","sourceRoot":"","sources":["../../../src/AmplitudeEngagementPlugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,MAAM,EACN,UAAU,EACV,gBAAgB,EAChB,KAAK,EACN,MAAM,
|
|
1
|
+
{"version":3,"file":"AmplitudeEngagementPlugin.d.ts","sourceRoot":"","sources":["../../../src/AmplitudeEngagementPlugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,MAAM,EACN,UAAU,EACV,gBAAgB,EAChB,KAAK,EACN,MAAM,2BAA2B,CAAC;AAInC,OAAO,EAAU,KAAK,eAAe,EAAE,MAAM,UAAU,CAAC;AACxD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEtD,qBAAa,yBAA0B,YAAW,gBAAgB;IAChE,IAAI,SAA+B;IACnC,IAAI,EAAG,YAAY,CAAU;IAE7B,MAAM,CAAC,EAAE,UAAU,CAAC;IAEpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAErC,MAAM,EAAE,eAAe,CAA2C;IAElE,sBAAsB,EAAE,iBAAiB,GAAG,IAAI,CAAQ;IAElD,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAmB9D,IAAI,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI;IAkB1C,OAAO,CAAC,OAAO,EAAE,KAAK,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC;CAmBrD"}
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import type { TurboModule } from 'react-native';
|
|
2
2
|
import type { GuideOrSurvey } from './types';
|
|
3
|
+
import type { EventEmitter } from 'react-native/Libraries/Types/CodegenTypes';
|
|
4
|
+
export type AnalyticsEvent = {
|
|
5
|
+
event_type: string;
|
|
6
|
+
event_properties: Object;
|
|
7
|
+
};
|
|
3
8
|
export interface Spec extends TurboModule {
|
|
4
9
|
newInstance(apiKey: string): number;
|
|
5
|
-
boot(id: number, user_id
|
|
10
|
+
boot(id: number, user_id?: string, device_id?: string): void;
|
|
6
11
|
setThemeMode(id: number, themeMode: 'auto' | 'dark_mode' | 'light_mode'): void;
|
|
7
12
|
reset(id: number, key: string, stepIndex: number): void;
|
|
8
13
|
list(id: number): GuideOrSurvey[];
|
|
@@ -12,6 +17,7 @@ export interface Spec extends TurboModule {
|
|
|
12
17
|
forwardEvent(id: number, event: Object): void;
|
|
13
18
|
addCallback(id: number, key: string, func: () => void): void;
|
|
14
19
|
handleURL(id: number, url: string): boolean;
|
|
20
|
+
readonly onTrackEvent: EventEmitter<AnalyticsEvent>;
|
|
15
21
|
}
|
|
16
22
|
declare const _default: Spec;
|
|
17
23
|
export default _default;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NativePluginEngagementReactNative.d.ts","sourceRoot":"","sources":["../../../src/NativePluginEngagementReactNative.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"NativePluginEngagementReactNative.d.ts","sourceRoot":"","sources":["../../../src/NativePluginEngagementReactNative.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2CAA2C,CAAC;AAE9E,MAAM,MAAM,cAAc,GAAG;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;CAC1B,CAAC;AACF,MAAM,WAAW,IAAK,SAAQ,WAAW;IACvC,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IAEpC,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7D,YAAY,CACV,EAAE,EAAE,MAAM,EACV,SAAS,EAAE,MAAM,GAAG,WAAW,GAAG,YAAY,GAC7C,IAAI,CAAC;IACR,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAExD,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,aAAa,EAAE,CAAC;IAElC,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACvD,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7C,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAmB,IAAI,CAAC;IAC9D,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IAE7D,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IAE5C,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC,cAAc,CAAC,CAAC;CACrD;;AAED,wBAEE"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import { AmplitudeEngagementPlugin } from './AmplitudeEngagementPlugin';
|
|
1
2
|
import type { GuideOrSurvey } from './types';
|
|
2
|
-
import type { BaseEvent
|
|
3
|
+
import type { BaseEvent } from '@amplitude/analytics-core';
|
|
3
4
|
export declare function init(apiKey: string): void;
|
|
4
|
-
export declare function boot(user_id
|
|
5
|
+
export declare function boot(user_id?: string, device_id?: string): Promise<void>;
|
|
5
6
|
export declare function list(): Promise<GuideOrSurvey[]>;
|
|
6
7
|
export declare function show(key: string, stepIndex: number): Promise<void>;
|
|
7
8
|
export declare function screen(screenName: string): Promise<void>;
|
|
@@ -9,5 +10,5 @@ export declare function closeAll(): Promise<void>;
|
|
|
9
10
|
export declare function forwardEvent(event: BaseEvent): Promise<void>;
|
|
10
11
|
export declare function addCallback(key: string, func: () => void): Promise<void>;
|
|
11
12
|
export declare function handleURL(url: string): Promise<boolean>;
|
|
12
|
-
export declare function getPlugin():
|
|
13
|
+
export declare function getPlugin(): AmplitudeEngagementPlugin;
|
|
13
14
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAiB3D,wBAAgB,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAUzC;AAED,wBAAsB,IAAI,CACxB,OAAO,CAAC,EAAE,MAAM,EAChB,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC,CAGf;AAED,wBAAsB,IAAI,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC,CAGrD;AAED,wBAAsB,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAGxE;AAED,wBAAsB,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAG9D;AAED,wBAAsB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAG9C;AAED,wBAAsB,YAAY,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAGlE;AAED,wBAAsB,WAAW,CAC/B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,IAAI,GACf,OAAO,CAAC,IAAI,CAAC,CAGf;AAED,wBAAsB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAG7D;AAGD,wBAAgB,SAAS,IAAI,yBAAyB,CAMrD"}
|
|
@@ -4,4 +4,17 @@ export type GuideOrSurvey = {
|
|
|
4
4
|
title: string;
|
|
5
5
|
};
|
|
6
6
|
export type ThemeMode = 'auto' | 'dark_mode' | 'light_mode';
|
|
7
|
+
export type AmplitudeEndUser = {
|
|
8
|
+
user_id?: string;
|
|
9
|
+
device_id?: string;
|
|
10
|
+
user_properties: {
|
|
11
|
+
[key: string]: any;
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
export type AmplitudeBootOptions = {
|
|
15
|
+
user: AmplitudeEndUser;
|
|
16
|
+
integrations: ((eventType: string, eventProperties: {
|
|
17
|
+
[key: string]: any;
|
|
18
|
+
}) => void)[];
|
|
19
|
+
};
|
|
7
20
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GAAG;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,WAAW,GAAG,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GAAG;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,WAAW,GAAG,YAAY,CAAC;AAE5D,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,CAAC;CACzC,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,IAAI,EAAE,gBAAgB,CAAC;IACvB,YAAY,EAAE,CAAC,CACb,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,KACpC,IAAI,CAAC,EAAE,CAAC;CACd,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@amplitude/plugin-engagement-react-native",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0-alpha.1",
|
|
4
4
|
"description": "Amplitude Engagement plugin for React Native",
|
|
5
5
|
"main": "./lib/module/index.js",
|
|
6
6
|
"types": "./lib/typescript/src/index.d.ts",
|
|
@@ -163,6 +163,6 @@
|
|
|
163
163
|
"version": "0.50.3"
|
|
164
164
|
},
|
|
165
165
|
"dependencies": {
|
|
166
|
-
"@amplitude/analytics-
|
|
166
|
+
"@amplitude/analytics-core": "^2.12.3"
|
|
167
167
|
}
|
|
168
168
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Spec } from './NativePluginEngagementReactNative';
|
|
2
2
|
import { NativeModules } from 'react-native';
|
|
3
3
|
import type { GuideOrSurvey, ThemeMode } from './types';
|
|
4
|
-
import type { BaseEvent } from '@amplitude/analytics-
|
|
4
|
+
import type { BaseEvent } from '@amplitude/analytics-core';
|
|
5
5
|
|
|
6
6
|
type PluginEngagementReactNativeType = Exclude<Spec, 'getConstants'>;
|
|
7
7
|
|
|
@@ -20,7 +20,7 @@ export class AmplitudeEngagement {
|
|
|
20
20
|
this.id = PluginEngagementReactNative.newInstance(apiKey);
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
boot(user_id
|
|
23
|
+
boot(user_id?: string, device_id?: string): void {
|
|
24
24
|
PluginEngagementReactNative.boot(this.id, user_id, device_id);
|
|
25
25
|
}
|
|
26
26
|
|
|
@@ -3,32 +3,69 @@ import type {
|
|
|
3
3
|
CoreClient,
|
|
4
4
|
EnrichmentPlugin,
|
|
5
5
|
Event,
|
|
6
|
-
} from '@amplitude/analytics-
|
|
7
|
-
import { forwardEvent, init, screen } from '.';
|
|
6
|
+
} from '@amplitude/analytics-core';
|
|
7
|
+
import { forwardEvent, init, screen, boot } from '.';
|
|
8
|
+
import NativePluginEngagementReactNative from './NativePluginEngagementReactNative';
|
|
9
|
+
|
|
8
10
|
import { Logger, type AmplitudeLogger } from './logger';
|
|
11
|
+
import type { EventSubscription } from 'react-native';
|
|
9
12
|
|
|
10
13
|
export class AmplitudeEngagementPlugin implements EnrichmentPlugin {
|
|
11
14
|
name = 'AmplitudeEngagementPlugin';
|
|
12
15
|
type = 'enrichment' as const;
|
|
13
16
|
|
|
17
|
+
client?: CoreClient;
|
|
18
|
+
|
|
19
|
+
userId?: string;
|
|
20
|
+
deviceId?: string;
|
|
21
|
+
sessionId?: number;
|
|
22
|
+
userProperties?: Record<string, any>;
|
|
23
|
+
|
|
14
24
|
logger: AmplitudeLogger = new Logger('AmplitudeEngagementPlugin');
|
|
15
25
|
|
|
16
|
-
|
|
26
|
+
trackEventSubscription: EventSubscription | null = null;
|
|
27
|
+
|
|
28
|
+
async setup(config: Config, client: CoreClient): Promise<void> {
|
|
17
29
|
try {
|
|
18
|
-
|
|
30
|
+
this.logger.log('initializing with apiKey', config.apiKey);
|
|
19
31
|
init(config.apiKey);
|
|
32
|
+
this.client = client;
|
|
33
|
+
// TODO: grab identity from client when available -- need to wait until it's added.
|
|
34
|
+
// Need to wait until https://amplitude.atlassian.net/browse/AMP-133461 is resolved
|
|
35
|
+
// then; follow the same pattern as in the `AmplitudeEngagementPlugin` in the Swift/iOS code
|
|
20
36
|
} catch (error) {
|
|
21
37
|
this.logger.error(
|
|
22
38
|
'AmplitudeEngagementPlugin#setup failed to initialize',
|
|
23
39
|
error
|
|
24
40
|
);
|
|
25
41
|
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// TODO: for now, you must call `boot()` manually
|
|
45
|
+
// but once we have access to the identity from the client,
|
|
46
|
+
// we can call `boot()` automatically in `setup` and `onIdentityChanged`
|
|
47
|
+
boot(user_id?: string, device_id?: string): void {
|
|
48
|
+
boot(user_id, device_id);
|
|
49
|
+
if (this.trackEventSubscription) {
|
|
50
|
+
this.trackEventSubscription.remove();
|
|
51
|
+
}
|
|
26
52
|
|
|
27
|
-
|
|
53
|
+
this.trackEventSubscription =
|
|
54
|
+
NativePluginEngagementReactNative.onTrackEvent((event) => {
|
|
55
|
+
if (!this.client) {
|
|
56
|
+
this.logger.error(
|
|
57
|
+
'AmplitudeEngagementPlugin#onIdentityChanged client is not initialized'
|
|
58
|
+
);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
this.client?.track(event.event_type, event.event_properties);
|
|
62
|
+
});
|
|
28
63
|
}
|
|
29
64
|
|
|
30
65
|
async execute(context: Event): Promise<Event | null> {
|
|
31
|
-
|
|
66
|
+
this.logger.log(
|
|
67
|
+
`AmplitudeEngagement#execute event=${JSON.stringify(context)}`
|
|
68
|
+
);
|
|
32
69
|
|
|
33
70
|
if (
|
|
34
71
|
context.event_type === '[Amplitude] Screen Viewed' &&
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import type { TurboModule } from 'react-native';
|
|
2
2
|
import { TurboModuleRegistry } from 'react-native';
|
|
3
3
|
import type { GuideOrSurvey } from './types';
|
|
4
|
+
import type { EventEmitter } from 'react-native/Libraries/Types/CodegenTypes';
|
|
4
5
|
|
|
6
|
+
export type AnalyticsEvent = {
|
|
7
|
+
event_type: string;
|
|
8
|
+
event_properties: Object;
|
|
9
|
+
};
|
|
5
10
|
export interface Spec extends TurboModule {
|
|
6
11
|
newInstance(apiKey: string): number;
|
|
7
12
|
|
|
8
|
-
boot(id: number, user_id
|
|
13
|
+
boot(id: number, user_id?: string, device_id?: string): void;
|
|
9
14
|
setThemeMode(
|
|
10
15
|
id: number,
|
|
11
16
|
themeMode: 'auto' | 'dark_mode' | 'light_mode' /* ThemeMode */
|
|
@@ -21,6 +26,8 @@ export interface Spec extends TurboModule {
|
|
|
21
26
|
addCallback(id: number, key: string, func: () => void): void;
|
|
22
27
|
|
|
23
28
|
handleURL(id: number, url: string): boolean;
|
|
29
|
+
|
|
30
|
+
readonly onTrackEvent: EventEmitter<AnalyticsEvent>;
|
|
24
31
|
}
|
|
25
32
|
|
|
26
33
|
export default TurboModuleRegistry.getEnforcing<Spec>(
|
package/src/index.tsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { AmplitudeEngagement } from './AmplitudeEngagement';
|
|
2
2
|
import { AmplitudeEngagementPlugin } from './AmplitudeEngagementPlugin';
|
|
3
3
|
import type { GuideOrSurvey } from './types';
|
|
4
|
-
import type { BaseEvent
|
|
4
|
+
import type { BaseEvent } from '@amplitude/analytics-core';
|
|
5
5
|
|
|
6
6
|
let globalEngagement: AmplitudeEngagement = null as any;
|
|
7
7
|
let toNotify: ((engagement: AmplitudeEngagement) => void)[] = [];
|
|
@@ -30,7 +30,10 @@ export function init(apiKey: string): void {
|
|
|
30
30
|
toNotify = [];
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
export async function boot(
|
|
33
|
+
export async function boot(
|
|
34
|
+
user_id?: string,
|
|
35
|
+
device_id?: string
|
|
36
|
+
): Promise<void> {
|
|
34
37
|
const e = await getGlobalEngagement();
|
|
35
38
|
return e.boot(user_id, device_id);
|
|
36
39
|
}
|
|
@@ -73,6 +76,11 @@ export async function handleURL(url: string): Promise<boolean> {
|
|
|
73
76
|
return e.handleURL(url);
|
|
74
77
|
}
|
|
75
78
|
|
|
76
|
-
|
|
77
|
-
|
|
79
|
+
let plugin: AmplitudeEngagementPlugin | null = null;
|
|
80
|
+
export function getPlugin(): AmplitudeEngagementPlugin {
|
|
81
|
+
if (!plugin) {
|
|
82
|
+
plugin = new AmplitudeEngagementPlugin();
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return plugin;
|
|
78
86
|
}
|
package/src/types.ts
CHANGED
|
@@ -5,3 +5,17 @@ export type GuideOrSurvey = {
|
|
|
5
5
|
};
|
|
6
6
|
|
|
7
7
|
export type ThemeMode = 'auto' | 'dark_mode' | 'light_mode';
|
|
8
|
+
|
|
9
|
+
export type AmplitudeEndUser = {
|
|
10
|
+
user_id?: string;
|
|
11
|
+
device_id?: string;
|
|
12
|
+
user_properties: { [key: string]: any };
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export type AmplitudeBootOptions = {
|
|
16
|
+
user: AmplitudeEndUser;
|
|
17
|
+
integrations: ((
|
|
18
|
+
eventType: string,
|
|
19
|
+
eventProperties: { [key: string]: any }
|
|
20
|
+
) => void)[];
|
|
21
|
+
};
|