@amplitude/plugin-engagement-react-native 0.1.1-alpha.9 → 0.2.0-alpha.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.
Files changed (28) hide show
  1. package/README.md +19 -7
  2. package/android/src/main/java/com/amplitude/pluginengagementreactnative/PluginEngagementReactNativeModule.kt +18 -3
  3. package/android/src/main/java/com/amplitude/pluginengagementreactnative/Util.kt +51 -0
  4. package/ios/AmplitudeEngagementAdapter.swift +78 -47
  5. package/ios/PluginEngagementReactNative.h +1 -1
  6. package/ios/PluginEngagementReactNative.mm +5 -1
  7. package/lib/module/AmplitudeEngagement.js.map +1 -1
  8. package/lib/module/AmplitudeEngagementPlugin.js +26 -5
  9. package/lib/module/AmplitudeEngagementPlugin.js.map +1 -1
  10. package/lib/module/NativePluginEngagementReactNative.js.map +1 -1
  11. package/lib/module/index.js +5 -1
  12. package/lib/module/index.js.map +1 -1
  13. package/lib/typescript/src/AmplitudeEngagement.d.ts +2 -2
  14. package/lib/typescript/src/AmplitudeEngagement.d.ts.map +1 -1
  15. package/lib/typescript/src/AmplitudeEngagementPlugin.d.ts +10 -2
  16. package/lib/typescript/src/AmplitudeEngagementPlugin.d.ts.map +1 -1
  17. package/lib/typescript/src/NativePluginEngagementReactNative.d.ts +7 -1
  18. package/lib/typescript/src/NativePluginEngagementReactNative.d.ts.map +1 -1
  19. package/lib/typescript/src/index.d.ts +4 -3
  20. package/lib/typescript/src/index.d.ts.map +1 -1
  21. package/lib/typescript/src/types.d.ts +13 -0
  22. package/lib/typescript/src/types.d.ts.map +1 -1
  23. package/package.json +2 -2
  24. package/src/AmplitudeEngagement.ts +2 -2
  25. package/src/AmplitudeEngagementPlugin.ts +43 -6
  26. package/src/NativePluginEngagementReactNative.ts +8 -1
  27. package/src/index.tsx +12 -4
  28. package/src/types.ts +14 -0
package/README.md CHANGED
@@ -5,11 +5,11 @@ 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
15
  npm install @amplitude/plugin-engagement-react-native
@@ -17,6 +17,7 @@ npm install @react-native-async-storage/async-storage
17
17
  ```
18
18
 
19
19
  Add the source for the `AmplitudeEngagementSwift` pod to your Podfile:
20
+
20
21
  ```rb
21
22
  target '<your appname>' do
22
23
  ...
@@ -28,6 +29,7 @@ end
28
29
  ```
29
30
 
30
31
  Re-run `pod install` in the `ios` directory:
32
+
31
33
  ```sh
32
34
  $ cd ios
33
35
  $ bundle exec pod install
@@ -68,6 +70,7 @@ Linking.addEventListener('url', async ({ url }) => {
68
70
  ```
69
71
 
70
72
  ### Linking setup
73
+
71
74
  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
75
  https://reactnative.dev/docs/linking#enabling-deep-links
73
76
 
@@ -75,21 +78,30 @@ Then, following the Alpha Onboarding guide to setup the "scheme" for the deep li
75
78
 
76
79
  ### Boot
77
80
 
78
- Finally, “boot” with the user’s ID:
81
+ Finally, “boot” the plugin with the user’s ID; "booting" the SDK enables Guides and Surveys to be shown:
79
82
 
80
83
  ```
81
84
  import {
82
- boot
83
- } from '@amplitude/plugin-engagement-react-native';
85
+ track,
86
+ setDeviceId,
87
+ setUserId,
88
+ } from '@amplitude/analytics-react-native';
89
+ import { useEffect } from 'react';
84
90
 
85
91
  export default function App() {
86
92
  useEffect(() => {
87
- boot('rn-test-user-1', 'test-device-1');
93
+ //
94
+ // NOTE: setting the User ID in @amplitude/analytics-react-native
95
+ // --and-- passing it to boot() is necessary for now, but in a
96
+ // future version will not be necessary
97
+ //
98
+ setUserId('rn-test-user-1');
99
+ setDeviceId('test-device-1');
100
+ getPlugin().boot('rn-test-user-1', 'test-device-1');
88
101
  }, []);
89
102
 
90
103
  ```
91
104
 
92
-
93
105
  ## License
94
106
 
95
- MIT
107
+ MIT
@@ -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, deviceId: 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
- instance.boot(userId, deviceId)
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
- /// Converting object to postable dictionary
14
- func toDictionary(_ encoder: JSONEncoder = JSONEncoder()) throws -> [String: Any] {
15
- let data = try encoder.encode(self)
16
- let object = try JSONSerialization.jsonObject(with: data)
17
- if let json = object as? [String: Any] { return json }
18
-
19
- let context = DecodingError.Context(codingPath: [], debugDescription: "Deserialized object is not a dictionary")
20
- throw DecodingError.typeMismatch(type(of: object), context)
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
- /** `@objc` attribute exposes Swift methods to the Objective-C runtime**/
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
- return existingId
32
+ return existingId
33
33
  }
34
-
34
+
35
35
  return DispatchQueue.main.sync {
36
- _id += 1;
37
- let id = _id + 1;
38
- instances[id] = (apiKey, __ReactNative__AESDK(apiKey, AmplitudeInitOptions(logLevel: AmplitudeLogLevel.verbose)))
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
- @objc public func boot(_ instanceId: Int, _ user_id: String, device_id: String? = nil) {
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
- return instance.boot(user_id, device_id: device_id)
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 { fatalError("🚨 Runtime exception: no instance found for id “\(instanceId)”") }
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 { fatalError("🚨 Runtime exception: no instance found for id “\(instanceId)”") }
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 { fatalError("🚨 Runtime exception: no instance found for id “\(instanceId)”") }
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 { fatalError("🚨 Runtime exception: no instance found for id “\(instanceId)”") }
80
- guard let url = URL(string: url) else { return false; }
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 { fatalError("🚨 Runtime exception: no instance found for id “\(instanceId)”") }
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 { fatalError("🚨 Runtime exception: no instance found for id “\(instanceId)”") }
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 { fatalError("🚨 Runtime exception: no instance found for id “\(instanceId)”") }
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 { fatalError("🚨 Runtime exception: no instance found for id “\(instanceId)”") }
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(_ instanceId: Int, _ key: String, _ function: @escaping () -> Void) {
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 { fatalError("🚨 Runtime exception: no instance found for id “\(instanceId)”") }
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 : NSObject <NativePluginEngagementReactNativeSpec>
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
- [adapter boot:id :user_id device_id:device_id];
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,OAAe,EAAEC,SAAiB,EAAQ;IAC7CV,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
+ {"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
- async setup(config, _client) {
10
+ trackEventSubscription = null;
11
+ async setup(config, client) {
10
12
  try {
11
- console.log('initializing with apiKey', config.apiKey);
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
- // TODO: call "boot" here -- but we don't have the user_id and device_id yet so we cannot
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
- console.log(`AmplitudeEngagement#execute event=${JSON.stringify(context)}`);
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","setup","config","_client","console","log","apiKey","error","execute","context","JSON","stringify","event_type","event_properties","screenName"],"sourceRoot":"../../src","sources":["AmplitudeEngagementPlugin.ts"],"mappings":";;AAMA,SAASA,YAAY,EAAEC,IAAI,EAAEC,MAAM,QAAQ,YAAG;AAC9C,SAASC,MAAM,QAA8B,aAAU;AAEvD,OAAO,MAAMC,yBAAyB,CAA6B;EACjEC,IAAI,GAAG,2BAA2B;EAClCC,IAAI,GAAG,YAAY;EAEnBC,MAAM,GAAoB,IAAIJ,MAAM,CAAC,2BAA2B,CAAC;EAEjE,MAAMK,KAAKA,CAACC,MAAc,EAAEC,OAAmB,EAAiB;IAC9D,IAAI;MACFC,OAAO,CAACC,GAAG,CAAC,0BAA0B,EAAEH,MAAM,CAACI,MAAM,CAAC;MACtDZ,IAAI,CAACQ,MAAM,CAACI,MAAM,CAAC;IACrB,CAAC,CAAC,OAAOC,KAAK,EAAE;MACd,IAAI,CAACP,MAAM,CAACO,KAAK,CACf,sDAAsD,EACtDA,KACF,CAAC;IACH;;IAEA;EACF;EAEA,MAAMC,OAAOA,CAACC,OAAc,EAAyB;IACnDL,OAAO,CAACC,GAAG,CAAC,qCAAqCK,IAAI,CAACC,SAAS,CAACF,OAAO,CAAC,EAAE,CAAC;IAE3E,IACEA,OAAO,CAACG,UAAU,KAAK,2BAA2B,IAClD,OAAOH,OAAO,CAACI,gBAAgB,GAAG,yBAAyB,CAAC,KAAK,QAAQ,EACzE;MACA,MAAMC,UAAU,GAAGL,OAAO,CAACI,gBAAgB,CACzC,yBAAyB,CAChB;MACXlB,MAAM,CAACmB,UAAU,CAAC;IACpB;IAEArB,YAAY,CAACgB,OAAO,CAAC;IAErB,OAAOA,OAAO;EAChB;AACF","ignoreList":[]}
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;AAwBlD,eAAeA,mBAAmB,CAACC,YAAY,CAC7C,6BACF,CAAC","ignoreList":[]}
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":[]}
@@ -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
- return new AmplitudeEngagementPlugin();
63
+ if (!plugin) {
64
+ plugin = new AmplitudeEngagementPlugin();
65
+ }
66
+ return plugin;
63
67
  }
64
68
  //# sourceMappingURL=index.js.map
@@ -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,CAACC,OAAe,EAAEC,SAAiB,EAAiB;EAC5E,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,OAAO,SAASC,SAASA,CAAA,EAAW;EAClC,OAAO,IAAI/B,yBAAyB,CAAC,CAAC;AACxC","ignoreList":[]}
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-types';
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: string, device_id: string): void;
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,4BAA4B,CAAC;AAW5D,qBAAa,mBAAmB;IAC9B,EAAE,EAAE,MAAM,CAAC;gBAEC,MAAM,EAAE,MAAM;IAK1B,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAI9C,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
+ {"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-types';
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
- setup(config: Config, _client: CoreClient): Promise<void>;
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,4BAA4B,CAAC;AAEpC,OAAO,EAAU,KAAK,eAAe,EAAE,MAAM,UAAU,CAAC;AAExD,qBAAa,yBAA0B,YAAW,gBAAgB;IAChE,IAAI,SAA+B;IACnC,IAAI,EAAG,YAAY,CAAU;IAE7B,MAAM,EAAE,eAAe,CAA2C;IAE5D,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAczD,OAAO,CAAC,OAAO,EAAE,KAAK,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC;CAiBrD"}
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: string, device_id: string): void;
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;AAE7C,MAAM,WAAW,IAAK,SAAQ,WAAW;IACvC,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IAEpC,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3D,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;CAC7C;;AAED,wBAEE"}
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, Plugin } from '@amplitude/analytics-types';
3
+ import type { BaseEvent } from '@amplitude/analytics-core';
3
4
  export declare function init(apiKey: string): void;
4
- export declare function boot(user_id: string, device_id: string): Promise<void>;
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(): Plugin;
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":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAiBpE,wBAAgB,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAUzC;AAED,wBAAsB,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAG5E;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;AAED,wBAAgB,SAAS,IAAI,MAAM,CAElC"}
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.1.1-alpha.9",
3
+ "version": "0.2.0-alpha.0",
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-types": "^1.3.5"
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-types';
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: string, device_id: string): void {
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-types';
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
- async setup(config: Config, _client: CoreClient): Promise<void> {
26
+ trackEventSubscription: EventSubscription | null = null;
27
+
28
+ async setup(config: Config, client: CoreClient): Promise<void> {
17
29
  try {
18
- console.log('initializing with apiKey', config.apiKey);
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
- // TODO: call "boot" here -- but we don't have the user_id and device_id yet so we cannot
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
- console.log(`AmplitudeEngagement#execute event=${JSON.stringify(context)}`);
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: string, device_id: string): void;
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, Plugin } from '@amplitude/analytics-types';
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(user_id: string, device_id: string): Promise<void> {
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
- export function getPlugin(): Plugin {
77
- return new AmplitudeEngagementPlugin();
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
+ };