@attentive-mobile/attentive-react-native-sdk 1.0.3-beta.1 → 2.0.0-beta.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.
Files changed (34) hide show
  1. package/README.md +150 -0
  2. package/android/build.gradle +4 -0
  3. package/android/src/main/kotlin/com/attentivereactnativesdk/AttentiveReactNativeSdkModule.kt +384 -0
  4. package/android/src/main/kotlin/com/attentivereactnativesdk/AttentiveReactNativeSdkPackage.kt +36 -0
  5. package/android/src/main/kotlin/com/attentivereactnativesdk/debug/AttentiveDebugHelper.kt +438 -0
  6. package/android/src/main/kotlin/com/attentivereactnativesdk/debug/DebugEvent.kt +76 -0
  7. package/attentive-react-native-sdk.podspec +4 -5
  8. package/ios/AttentiveReactNativeSdk.h +6 -6
  9. package/ios/AttentiveReactNativeSdk.mm +325 -35
  10. package/ios/AttentiveReactNativeSdk.xcodeproj/project.pbxproj +2 -2
  11. package/ios/Bridging/ATTNNativeSDK.swift +1118 -3
  12. package/ios/Bridging/AttentiveReactNativeSdk-Bridging-Header.h +3 -0
  13. package/ios/Bridging/AttentiveSDKManager.swift +83 -0
  14. package/ios/Podfile +4 -17
  15. package/lib/commonjs/NativeAttentiveReactNativeSdk.js +14 -0
  16. package/lib/commonjs/NativeAttentiveReactNativeSdk.js.map +1 -0
  17. package/lib/commonjs/index.js +363 -39
  18. package/lib/commonjs/index.js.map +1 -1
  19. package/lib/module/NativeAttentiveReactNativeSdk.js +7 -0
  20. package/lib/module/NativeAttentiveReactNativeSdk.js.map +1 -0
  21. package/lib/module/index.js +346 -38
  22. package/lib/module/index.js.map +1 -1
  23. package/lib/typescript/NativeAttentiveReactNativeSdk.d.ts +103 -0
  24. package/lib/typescript/NativeAttentiveReactNativeSdk.d.ts.map +1 -0
  25. package/lib/typescript/eventTypes.d.ts +44 -17
  26. package/lib/typescript/eventTypes.d.ts.map +1 -1
  27. package/lib/typescript/index.d.ts +276 -33
  28. package/lib/typescript/index.d.ts.map +1 -1
  29. package/package.json +22 -8
  30. package/src/NativeAttentiveReactNativeSdk.ts +152 -0
  31. package/src/eventTypes.tsx +57 -20
  32. package/src/index.tsx +472 -82
  33. package/android/src/main/java/com/attentivereactnativesdk/AttentiveReactNativeSdkModule.java +0 -247
  34. package/android/src/main/java/com/attentivereactnativesdk/AttentiveReactNativeSdkPackage.java +0 -28
@@ -1,34 +1,277 @@
1
- import type { AddToCartEvent, ProductViewEvent, PurchaseEvent, CustomEvent } from './eventTypes';
2
- export declare enum Mode {
3
- Production = "production",
4
- Debug = "debug"
5
- }
6
- export type AttentiveConfiguration = {
7
- attentiveDomain: string;
8
- mode: Mode;
9
- skipFatigueOnCreatives?: boolean;
10
- };
11
- export type UserIdentifiers = {
12
- phone?: string;
13
- email?: string;
14
- klaviyoId?: string;
15
- shopifyId?: string;
16
- clientUserId?: string;
17
- customIdentifiers?: {
18
- [key: string]: string;
19
- };
20
- };
21
- export declare class Attentive {
22
- static initialize(configuration: AttentiveConfiguration): void;
23
- static identify(userIdentifiers: UserIdentifiers): void;
24
- static clearUser(): void;
25
- static triggerCreative(creativeId?: string | null): void;
26
- static destroyCreative(): void;
27
- static updateDomain(domain: string): void;
28
- static recordProductViewEvent(productViewEvent: ProductViewEvent): void;
29
- static recordAddToCartEvent(addToCartEvent: AddToCartEvent): void;
30
- static recordPurchaseEvent(purchaseEvent: PurchaseEvent): void;
31
- static recordCustomEvent(customEvent: CustomEvent): void;
32
- }
33
- export type { AddToCartEvent, ProductViewEvent, PurchaseEvent, CustomEvent };
1
+ import type { UserIdentifiers, AttentiveSdkConfiguration, ProductView, Purchase, AddToCart, CustomEvent, Item, PushAuthorizationStatus, ApplicationState, PushNotificationUserInfo, PushRegistrationResult } from './eventTypes';
2
+ /**
3
+ * Initialize the Attentive SDK with the provided configuration
4
+ * @param configuration - Configuration object for the Attentive SDK
5
+ */
6
+ declare function initialize(configuration: AttentiveSdkConfiguration): void;
7
+ /**
8
+ * Trigger a creative with an optional creative ID
9
+ * @param creativeId - Optional creative ID to trigger
10
+ */
11
+ declare function triggerCreative(creativeId?: string): void;
12
+ /**
13
+ * Destroy the current creative
14
+ */
15
+ declare function destroyCreative(): void;
16
+ /**
17
+ * Update the Attentive domain
18
+ * @param domain - New domain to use
19
+ */
20
+ declare function updateDomain(domain: string): void;
21
+ /**
22
+ * Identify a user with the provided identifiers
23
+ * @param identifiers - User identifier object containing phone, email, etc.
24
+ */
25
+ declare function identify(identifiers: UserIdentifiers): void;
26
+ /**
27
+ * Clear the current user identification
28
+ */
29
+ declare function clearUser(): void;
30
+ /**
31
+ * Record an add to cart event
32
+ * @param attrs - Event attributes containing items and optional deeplink
33
+ */
34
+ declare function recordAddToCartEvent(attrs: AddToCart): void;
35
+ /**
36
+ * Record a product view event
37
+ * @param attrs - Event attributes containing items and optional deeplink
38
+ */
39
+ declare function recordProductViewEvent(attrs: ProductView): void;
40
+ /**
41
+ * Record a purchase event
42
+ * @param attrs - Event attributes containing items, order ID, and optional cart details
43
+ */
44
+ declare function recordPurchaseEvent(attrs: Purchase): void;
45
+ /**
46
+ * Record a custom event
47
+ * @param attrs - Custom event attributes containing type and properties
48
+ */
49
+ declare function recordCustomEvent(attrs: CustomEvent): void;
50
+ /**
51
+ * Invoke the Attentive debug helper
52
+ */
53
+ declare function invokeAttentiveDebugHelper(): void;
54
+ /**
55
+ * Export debug logs
56
+ * @returns Promise that resolves to a string containing the debug logs
57
+ */
58
+ declare function exportDebugLogs(): Promise<string>;
59
+ /**
60
+ * Request push notification permission from the user.
61
+ * On iOS, this will trigger the system permission dialog.
62
+ * On Android, this is currently a no-op (TODO: implement FCM integration).
63
+ *
64
+ * @example
65
+ * ```typescript
66
+ * import { registerForPushNotifications } from 'attentive-react-native-sdk';
67
+ *
68
+ * // Request permission (typically called after user onboarding)
69
+ * registerForPushNotifications();
70
+ * ```
71
+ */
72
+ declare function registerForPushNotifications(): void;
73
+ /**
74
+ * Register the device token received from APNs/FCM with the Attentive backend.
75
+ * Call this from your AppDelegate's didRegisterForRemoteNotificationsWithDeviceToken.
76
+ *
77
+ * On iOS, the token should be the hex-encoded string representation of the device token Data.
78
+ * On Android, this is currently a no-op (TODO: implement FCM integration).
79
+ *
80
+ * @param token - The device token as a hex-encoded string
81
+ * @param authorizationStatus - Current push authorization status
82
+ *
83
+ * @example
84
+ * ```typescript
85
+ * import { registerDeviceToken } from 'attentive-react-native-sdk';
86
+ *
87
+ * // In your native module or push notification handler:
88
+ * registerDeviceToken('abc123...', 'authorized');
89
+ * ```
90
+ */
91
+ declare function registerDeviceToken(token: string, authorizationStatus: PushAuthorizationStatus): void;
92
+ /**
93
+ * Register the device token received from APNs with a callback.
94
+ * This is the callback-based version that allows you to handle the response from the Attentive API.
95
+ *
96
+ * On iOS, this will register the device token with the Attentive SDK and invoke the callback
97
+ * after the registration completes (success or failure).
98
+ * On Android, this is currently a no-op (TODO: implement FCM integration).
99
+ *
100
+ * @param token - The hex-encoded device token string from APNs
101
+ * @param authorizationStatus - Current push authorization status
102
+ * @param callback - Callback function invoked after registration completes
103
+ *
104
+ * @example
105
+ * ```typescript
106
+ * import { registerDeviceTokenWithCallback, handleRegularOpen } from 'attentive-react-native-sdk';
107
+ *
108
+ * // In your AppDelegate equivalent (TypeScript):
109
+ * registerDeviceTokenWithCallback(
110
+ * deviceToken,
111
+ * 'authorized',
112
+ * (data, url, response, error) => {
113
+ * console.log('Registration complete:', { data, url, response, error });
114
+ * // After registration, trigger regular open event
115
+ * handleRegularOpen('authorized');
116
+ * }
117
+ * );
118
+ * ```
119
+ */
120
+ declare function registerDeviceTokenWithCallback(token: string, authorizationStatus: PushAuthorizationStatus, callback: (data?: Object, url?: string, response?: Object, error?: Object) => void): void;
121
+ /**
122
+ * Handle regular/direct app open (not from a push notification).
123
+ * This should be called after device token registration to track app opens.
124
+ *
125
+ * This is the TypeScript equivalent of the native iOS AppDelegate method:
126
+ * ```swift
127
+ * func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
128
+ * UNUserNotificationCenter.current().getNotificationSettings { [weak self] settings in
129
+ * guard let self = self else { return }
130
+ * let authStatus = settings.authorizationStatus
131
+ * attentiveSdk?.registerDeviceToken(deviceToken, authorizationStatus: authStatus, callback: { data, url, response, error in
132
+ * DispatchQueue.main.async {
133
+ * self.attentiveSdk?.handleRegularOpen(authorizationStatus: authStatus)
134
+ * }
135
+ * })
136
+ * }
137
+ * }
138
+ * ```
139
+ *
140
+ * On iOS, this will notify the Attentive SDK that the app was opened directly
141
+ * (not from a push notification tap).
142
+ * On Android, this is currently a no-op (TODO: implement FCM integration).
143
+ *
144
+ * @param authorizationStatus - Current push authorization status
145
+ *
146
+ * @example
147
+ * ```typescript
148
+ * import { registerDeviceTokenWithCallback, handleRegularOpen } from 'attentive-react-native-sdk';
149
+ * import PushNotificationIOS from '@react-native-community/push-notification-ios';
150
+ *
151
+ * // In your device token registration handler:
152
+ * PushNotificationIOS.addEventListener('register', (deviceToken: string) => {
153
+ * PushNotificationIOS.checkPermissions((permissions) => {
154
+ * let authStatus: PushAuthorizationStatus = 'notDetermined'
155
+ * if (permissions.alert || permissions.badge || permissions.sound) {
156
+ * authStatus = 'authorized'
157
+ * }
158
+ *
159
+ * // Register device token with callback
160
+ * registerDeviceTokenWithCallback(deviceToken, authStatus, (data, url, response, error) => {
161
+ * if (error) {
162
+ * console.error('Registration error:', error)
163
+ * }
164
+ * // After registration completes, trigger regular open event
165
+ * handleRegularOpen(authStatus)
166
+ * })
167
+ * })
168
+ * })
169
+ * ```
170
+ */
171
+ declare function handleRegularOpen(authorizationStatus: PushAuthorizationStatus): void;
172
+ /**
173
+ * Handle when a push notification is opened by the user.
174
+ * Call this from your notification handler when the user taps a notification.
175
+ *
176
+ * On iOS, this will track the push open event and handle the notification appropriately
177
+ * based on whether the app was in the foreground, background, or not running.
178
+ * On Android, this is currently a no-op (TODO: implement FCM integration).
179
+ *
180
+ * @param userInfo - The notification payload from the push notification
181
+ * @param applicationState - The app state when the notification was opened ('active', 'inactive', 'background')
182
+ * @param authorizationStatus - Current push authorization status
183
+ *
184
+ * @example
185
+ * ```typescript
186
+ * import { handlePushOpened } from 'attentive-react-native-sdk';
187
+ *
188
+ * // In your notification handler:
189
+ * handlePushOpened(
190
+ * notification.data,
191
+ * 'background',
192
+ * 'authorized'
193
+ * );
194
+ * ```
195
+ */
196
+ declare function handlePushOpened(userInfo: PushNotificationUserInfo, applicationState: ApplicationState, authorizationStatus: PushAuthorizationStatus): void;
197
+ /**
198
+ * Handle when a push notification arrives while the app is in the foreground.
199
+ * Call this from your notification handler when a notification is received while the app is active.
200
+ *
201
+ * On iOS, this allows the Attentive SDK to track the notification event.
202
+ * On Android, this is currently a no-op (TODO: implement FCM integration).
203
+ *
204
+ * @param userInfo - The notification payload from the push notification
205
+ *
206
+ * @example
207
+ * ```typescript
208
+ * import { handleForegroundNotification } from 'attentive-react-native-sdk';
209
+ *
210
+ * // In your notification handler when app is in foreground:
211
+ * handleForegroundNotification(notification.data);
212
+ * ```
213
+ */
214
+ declare function handleForegroundNotification(userInfo: PushNotificationUserInfo): void;
215
+ /**
216
+ * Handle a push notification when the app is in the foreground (active state).
217
+ * This is the React Native equivalent of the native iOS handleForegroundPush method.
218
+ *
219
+ * Call this when you receive a notification response and the app state is 'active'.
220
+ * This is part of implementing the native iOS pattern:
221
+ * ```swift
222
+ * case .active:
223
+ * self.attentiveSdk?.handleForegroundPush(response: response, authorizationStatus: authStatus)
224
+ * ```
225
+ *
226
+ * On iOS, this properly tracks foreground push notifications.
227
+ * On Android, this is currently a no-op (TODO: implement FCM integration).
228
+ *
229
+ * @param userInfo - The notification payload from the push notification
230
+ * @param authorizationStatus - Current push authorization status
231
+ *
232
+ * @example
233
+ * ```typescript
234
+ * import { handleForegroundPush } from 'attentive-react-native-sdk';
235
+ * import { AppState } from 'react-native';
236
+ *
237
+ * // In your notification handler:
238
+ * const appState = AppState.currentState;
239
+ * if (appState === 'active') {
240
+ * handleForegroundPush(notification.data, 'authorized');
241
+ * }
242
+ * ```
243
+ */
244
+ declare function handleForegroundPush(userInfo: PushNotificationUserInfo, authorizationStatus: PushAuthorizationStatus): void;
245
+ /**
246
+ * Handle when a push notification is opened by the user (app in background/inactive state).
247
+ * This is the React Native equivalent of the native iOS handlePushOpen method.
248
+ *
249
+ * Call this when you receive a notification response and the app state is 'background' or 'inactive'.
250
+ * This is part of implementing the native iOS pattern:
251
+ * ```swift
252
+ * case .background, .inactive:
253
+ * self.attentiveSdk?.handlePushOpen(response: response, authorizationStatus: authStatus)
254
+ * ```
255
+ *
256
+ * On iOS, this properly tracks push notification opens.
257
+ * On Android, this is currently a no-op (TODO: implement FCM integration).
258
+ *
259
+ * @param userInfo - The notification payload from the push notification
260
+ * @param authorizationStatus - Current push authorization status
261
+ *
262
+ * @example
263
+ * ```typescript
264
+ * import { handlePushOpen } from 'attentive-react-native-sdk';
265
+ * import { AppState } from 'react-native';
266
+ *
267
+ * // In your notification handler:
268
+ * const appState = AppState.currentState;
269
+ * if (appState === 'background' || appState === 'inactive') {
270
+ * handlePushOpen(notification.data, 'authorized');
271
+ * }
272
+ * ```
273
+ */
274
+ declare function handlePushOpen(userInfo: PushNotificationUserInfo, authorizationStatus: PushAuthorizationStatus): void;
275
+ export { initialize, triggerCreative, destroyCreative, updateDomain, identify, clearUser, recordAddToCartEvent, recordProductViewEvent, recordPurchaseEvent, recordCustomEvent, invokeAttentiveDebugHelper, exportDebugLogs, registerForPushNotifications, registerDeviceToken, registerDeviceTokenWithCallback, handleRegularOpen, handlePushOpened, handleForegroundNotification, handleForegroundPush, handlePushOpen, };
276
+ export type { UserIdentifiers, AttentiveSdkConfiguration, ProductView, Purchase, AddToCart, CustomEvent, Item, PushAuthorizationStatus, ApplicationState, PushNotificationUserInfo, PushRegistrationResult, };
34
277
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,WAAW,EACZ,MAAM,cAAc,CAAC;AAmBtB,oBAAY,IAAI;IACd,UAAU,eAAe;IACzB,KAAK,UAAU;CAChB;AAED,MAAM,MAAM,sBAAsB,GAAG;IACnC,eAAe,EAAE,MAAM,CAAC;IACxB,IAAI,EAAE,IAAI,CAAC;IACX,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAClC,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iBAAiB,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;CAC/C,CAAC;AAEF,qBAAa,SAAS;IACpB,MAAM,CAAC,UAAU,CAAC,aAAa,EAAE,sBAAsB,GAAG,IAAI;IAI9D,MAAM,CAAC,QAAQ,CAAC,eAAe,EAAE,eAAe,GAAG,IAAI;IAIvD,MAAM,CAAC,SAAS,IAAI,IAAI;IAIxB,MAAM,CAAC,eAAe,CAAC,UAAU,GAAE,MAAM,GAAG,IAAW,GAAG,IAAI;IAI9D,MAAM,CAAC,eAAe,IAAI,IAAI;IAI9B,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAIzC,MAAM,CAAC,sBAAsB,CAAC,gBAAgB,EAAE,gBAAgB,GAAG,IAAI;IAIvE,MAAM,CAAC,oBAAoB,CAAC,cAAc,EAAE,cAAc,GAAG,IAAI;IAIjE,MAAM,CAAC,mBAAmB,CAAC,aAAa,EAAE,aAAa,GAAG,IAAI;IAI9D,MAAM,CAAC,iBAAiB,CAAC,WAAW,EAAE,WAAW,GAAG,IAAI;CAGzD;AAED,YAAY,EAAE,cAAc,EAAE,gBAAgB,EAAE,aAAa,EAAE,WAAW,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.tsx"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@attentive-mobile/attentive-react-native-sdk",
3
- "version": "1.0.3-beta.1",
3
+ "version": "2.0.0-beta.1",
4
4
  "description": "React Native Module for the Attentive SDK",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",
@@ -31,11 +31,16 @@
31
31
  "test": "jest",
32
32
  "typecheck": "tsc --noEmit",
33
33
  "lint": "eslint \"**/*.{js,ts,tsx}\"",
34
+ "build": "bob build",
34
35
  "prepack": "bob build",
35
36
  "release": "release-it",
36
- "example": "yarn --cwd example",
37
- "bootstrap": "yarn example && yarn install && yarn example pods",
38
- "clean": "del-cli android/build example/android/build example/android/app/build example/ios/build"
37
+ "example": "npm --prefix example",
38
+ "bootstrap": "npm install && npm --prefix example install && npm --prefix example run pods",
39
+ "clean": "del-cli android/build example/android/build example/android/app/build example/ios/build",
40
+ "dev:start": "npm run build && cd example && ./reset.sh && cd .. && npm run dev",
41
+ "dev": "npm --prefix example run start",
42
+ "dev:ios": "npm --prefix example run ios",
43
+ "dev:android": "npm --prefix example run android"
39
44
  },
40
45
  "keywords": [
41
46
  "attentive",
@@ -63,7 +68,6 @@
63
68
  "@release-it/conventional-changelog": "^5.0.0",
64
69
  "@types/jest": "^28.1.2",
65
70
  "@types/react": "~17.0.21",
66
- "@types/react-native": "0.70.0",
67
71
  "commitlint": "^17.0.2",
68
72
  "del-cli": "^5.0.0",
69
73
  "eslint": "^8.4.1",
@@ -73,7 +77,7 @@
73
77
  "pod-install": "^0.1.0",
74
78
  "prettier": "^2.0.5",
75
79
  "react": "18.2.0",
76
- "react-native": "0.71.19",
80
+ "react-native": "0.75.5",
77
81
  "react-native-builder-bob": "^0.20.4",
78
82
  "release-it": "^15.0.0",
79
83
  "typescript": "^4.5.2"
@@ -131,7 +135,8 @@
131
135
  "singleQuote": true,
132
136
  "tabWidth": 2,
133
137
  "trailingComma": "es5",
134
- "useTabs": false
138
+ "useTabs": false,
139
+ "semi": false
135
140
  }
136
141
  ]
137
142
  }
@@ -145,7 +150,8 @@
145
150
  "singleQuote": true,
146
151
  "tabWidth": 2,
147
152
  "trailingComma": "es5",
148
- "useTabs": false
153
+ "useTabs": false,
154
+ "semi": false
149
155
  },
150
156
  "react-native-builder-bob": {
151
157
  "source": "src",
@@ -161,6 +167,14 @@
161
167
  ]
162
168
  ]
163
169
  },
170
+ "codegenConfig": {
171
+ "name": "AttentiveReactNativeSdkSpec",
172
+ "type": "modules",
173
+ "jsSrcsDir": "src",
174
+ "android": {
175
+ "javaPackageName": "com.attentivereactnativesdk"
176
+ }
177
+ },
164
178
  "dependencies": {
165
179
  "@babel/runtime": "^7.27.0"
166
180
  }
@@ -0,0 +1,152 @@
1
+ import type { TurboModule } from "react-native/Libraries/TurboModule/RCTExport";
2
+ import { TurboModuleRegistry, NativeModules } from "react-native";
3
+
4
+ export interface Spec extends TurboModule {
5
+ initialize: (
6
+ attentiveDomain: string,
7
+ mode: string,
8
+ skipFatigueOnCreatives: boolean,
9
+ enableDebugger: boolean
10
+ ) => void;
11
+ triggerCreative: (creativeId?: string) => void;
12
+ destroyCreative: () => void;
13
+ updateDomain: (domain: string) => void;
14
+ identify: (
15
+ phone?: string,
16
+ email?: string,
17
+ klaviyoId?: string,
18
+ shopifyId?: string,
19
+ clientUserId?: string,
20
+ customIdentifiers?: Object
21
+ ) => void;
22
+ clearUser: () => void;
23
+ recordAddToCartEvent: (
24
+ items: Array<{
25
+ productId: string;
26
+ productVariantId: string;
27
+ price: string;
28
+ currency: string;
29
+ productImage?: string;
30
+ name?: string;
31
+ quantity?: number;
32
+ category?: string;
33
+ }>,
34
+ deeplink?: string
35
+ ) => void;
36
+ recordProductViewEvent: (
37
+ items: Array<{
38
+ productId: string;
39
+ productVariantId: string;
40
+ price: string;
41
+ currency: string;
42
+ productImage?: string;
43
+ name?: string;
44
+ quantity?: number;
45
+ category?: string;
46
+ }>,
47
+ deeplink?: string
48
+ ) => void;
49
+ recordPurchaseEvent: (
50
+ items: Array<{
51
+ productId: string;
52
+ productVariantId: string;
53
+ price: string;
54
+ currency: string;
55
+ productImage?: string;
56
+ name?: string;
57
+ quantity?: number;
58
+ category?: string;
59
+ }>,
60
+ orderId: string,
61
+ cartId?: string,
62
+ cartCoupon?: string
63
+ ) => void;
64
+ recordCustomEvent: (type: string, properties: Object) => void;
65
+ invokeAttentiveDebugHelper: () => void;
66
+ exportDebugLogs: () => Promise<string>;
67
+
68
+ // Push Notification Methods (iOS only)
69
+ /**
70
+ * Request push notification permission from the user.
71
+ * iOS only - Android is a no-op.
72
+ */
73
+ registerForPushNotifications: () => void;
74
+
75
+ /**
76
+ * Register the device token received from APNs (simple version without callback).
77
+ * iOS only - Android is a no-op.
78
+ * @param token - The hex-encoded device token string
79
+ * @param authorizationStatus - Current push authorization status
80
+ */
81
+ registerDeviceToken: (token: string, authorizationStatus: string) => void;
82
+
83
+ /**
84
+ * Register the device token received from APNs with a callback.
85
+ * iOS only - Android is a no-op.
86
+ * The callback receives the response from the Attentive API after registration.
87
+ * @param token - The hex-encoded device token string
88
+ * @param authorizationStatus - Current push authorization status
89
+ * @param callback - Callback invoked after registration completes
90
+ */
91
+ registerDeviceTokenWithCallback: (
92
+ token: string,
93
+ authorizationStatus: string,
94
+ callback: (data?: Object, url?: string, response?: Object, error?: Object) => void
95
+ ) => void;
96
+
97
+ /**
98
+ * Handle regular/direct app open (not from a push notification).
99
+ * iOS only - Android is a no-op.
100
+ * This should be called after device token registration to track app opens.
101
+ * @param authorizationStatus - Current push authorization status
102
+ */
103
+ handleRegularOpen: (authorizationStatus: string) => void;
104
+
105
+ /**
106
+ * Handle when a push notification is opened by the user.
107
+ * iOS only - Android is a no-op.
108
+ * @param userInfo - The notification payload
109
+ * @param applicationState - The app state when notification was opened ('active', 'inactive', 'background')
110
+ * @param authorizationStatus - Current push authorization status
111
+ */
112
+ handlePushOpened: (
113
+ userInfo: Object,
114
+ applicationState: string,
115
+ authorizationStatus: string
116
+ ) => void;
117
+
118
+ /**
119
+ * Handle when a push notification arrives while the app is in foreground.
120
+ * iOS only - Android is a no-op.
121
+ * @param userInfo - The notification payload
122
+ */
123
+ handleForegroundNotification: (userInfo: Object) => void;
124
+
125
+ /**
126
+ * Handle a push notification when the app is in the foreground (active state).
127
+ * This is the React Native equivalent of calling handleForegroundPush in native iOS.
128
+ * iOS only - Android is a no-op.
129
+ * @param userInfo - The notification payload
130
+ * @param authorizationStatus - Current push authorization status
131
+ */
132
+ handleForegroundPush: (userInfo: Object, authorizationStatus: string) => void;
133
+
134
+ /**
135
+ * Handle when a push notification is opened by the user (app in background/inactive state).
136
+ * This is the React Native equivalent of calling handlePushOpen in native iOS.
137
+ * iOS only - Android is a no-op.
138
+ * @param userInfo - The notification payload
139
+ * @param authorizationStatus - Current push authorization status
140
+ */
141
+ handlePushOpen: (userInfo: Object, authorizationStatus: string) => void;
142
+ }
143
+
144
+ // Try to load via TurboModule first (new architecture)
145
+ // Fall back to NativeModules for old architecture
146
+ const isTurboModuleEnabled = (global as any).__turboModuleProxy != null;
147
+
148
+ const AttentiveReactNativeSdkModule = isTurboModuleEnabled
149
+ ? TurboModuleRegistry.get<Spec>("AttentiveReactNativeSdk")
150
+ : NativeModules.AttentiveReactNativeSdk;
151
+
152
+ export default AttentiveReactNativeSdkModule as Spec | null;
@@ -1,44 +1,81 @@
1
+ export type UserIdentifiers = {
2
+ phone?: string;
3
+ email?: string;
4
+ klaviyoId?: string;
5
+ shopifyId?: string;
6
+ clientUserId?: string;
7
+ customIdentifiers?: Record<string, string>;
8
+ };
9
+
10
+ export type AttentiveSdkConfiguration = {
11
+ attentiveDomain: string;
12
+ mode: string; // "production" or "debug"
13
+ skipFatigueOnCreatives?: boolean;
14
+ enableDebugger?: boolean;
15
+ };
16
+
17
+ // Codegen does not support nested objects inside of arrays. We must flatten the Item type.
1
18
  export type Item = {
2
19
  productId: string;
3
20
  productVariantId: string;
4
- price: Price;
21
+ price: string;
22
+ currency: string;
5
23
  productImage?: string;
6
24
  name?: string;
7
25
  quantity?: number;
8
26
  category?: string;
9
27
  };
10
28
 
11
- export type Price = {
12
- price: string;
13
- currency: string;
29
+ export type ProductView = {
30
+ items: Item[];
31
+ deeplink?: string;
14
32
  };
15
33
 
16
- export type Order = {
34
+ // Codegen does not support nested objects. We must flatten the Purchase type.
35
+ export type Purchase = {
36
+ items: Item[];
17
37
  orderId: string;
18
- };
19
-
20
- export type Cart = {
21
38
  cartId?: string;
22
39
  cartCoupon?: string;
23
40
  };
24
41
 
25
- export type ProductViewEvent = {
42
+ export type AddToCart = {
26
43
  items: Item[];
27
44
  deeplink?: string;
28
45
  };
29
46
 
30
- export type AddToCartEvent = {
31
- items: Item[];
32
- deeplink?: string;
33
- };
34
-
35
- export type PurchaseEvent = {
36
- items: Item[];
37
- order: Order;
38
- cart?: Cart;
39
- };
40
-
41
47
  export type CustomEvent = {
42
48
  type: string;
43
49
  properties: Record<string, string>;
44
50
  };
51
+
52
+ /**
53
+ * Push notification authorization status
54
+ * Maps to UNAuthorizationStatus on iOS
55
+ */
56
+ export type PushAuthorizationStatus =
57
+ | 'authorized'
58
+ | 'denied'
59
+ | 'notDetermined'
60
+ | 'provisional'
61
+ | 'ephemeral';
62
+
63
+ /**
64
+ * Application state when handling push notifications
65
+ */
66
+ export type ApplicationState = 'active' | 'inactive' | 'background';
67
+
68
+ /**
69
+ * Push notification user info payload
70
+ * Contains data from the remote notification
71
+ */
72
+ export type PushNotificationUserInfo = Record<string, unknown>;
73
+
74
+ /**
75
+ * Result of registering for push notifications
76
+ */
77
+ export type PushRegistrationResult = {
78
+ success: boolean;
79
+ token?: string;
80
+ error?: string;
81
+ };