zixflow-reactnative 1.1.3 → 1.1.4

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 (239) hide show
  1. package/README.md +631 -261
  2. package/android/build.gradle +18 -1
  3. package/android/consumer-rules.pro +3 -2
  4. package/android/gradle.properties +1 -1
  5. package/android/src/main/java/com/zixflow/reactnative/sdk/NativeZixflowModule.kt +40 -5
  6. package/android/src/main/java/com/zixflow/reactnative/sdk/ZixflowReactNativePackage.kt +25 -1
  7. package/android/src/main/java/com/zixflow/reactnative/sdk/constant/Keys.kt +19 -0
  8. package/android/src/main/java/com/zixflow/reactnative/sdk/geofence/NativeGeofenceModule.kt +65 -0
  9. package/android/src/main/java/com/zixflow/reactnative/sdk/liveactivities/NativeLiveActivitiesModule.kt +310 -0
  10. package/android/src/main/java/com/zixflow/reactnative/sdk/messaginginapp/NativeMessagingInAppModule.kt +150 -0
  11. package/android/src/main/java/com/zixflow/reactnative/sdk/messaginginapp/ReactInboxEventListener.kt +99 -0
  12. package/android/src/main/java/com/zixflow/reactnative/sdk/messaginginbox/NotificationInboxBellViewManager.kt +38 -0
  13. package/android/src/main/java/com/zixflow/reactnative/sdk/messaginginbox/NotificationInboxViewManager.kt +30 -0
  14. package/android/src/main/java/com/zixflow/reactnative/sdk/messaginginbox/ReactComposeHostView.kt +96 -0
  15. package/android/src/main/java/com/zixflow/reactnative/sdk/messaginginbox/ReactNotificationInboxBellView.kt +48 -0
  16. package/android/src/main/java/com/zixflow/reactnative/sdk/messaginginbox/ReactNotificationInboxView.kt +17 -0
  17. package/android/src/main/java/com/zixflow/reactnative/sdk/messagingpush/NativeMessagingPushModule.kt +11 -1
  18. package/android/src/main/res/values/zixflow_config.xml +1 -1
  19. package/android/zixflow-core.gradle +17 -7
  20. package/docs/cocoapods-deployment-target-normalization.md +139 -0
  21. package/ios/cocoapods_deployment_target.rb +432 -0
  22. package/ios/wrappers/NativeZixflow.mm +37 -0
  23. package/ios/wrappers/NativeZixflow.swift +135 -1
  24. package/ios/wrappers/ZixflowReactNativeDeepLinkRequestStore.swift +123 -0
  25. package/ios/wrappers/ZixflowReactNativeDeepLinkRouter.swift +312 -0
  26. package/ios/wrappers/geofence/NativeGeofence.mm +46 -0
  27. package/ios/wrappers/geofence/NativeGeofence.swift +27 -0
  28. package/ios/wrappers/inapp/NativeMessagingInApp.mm +22 -0
  29. package/ios/wrappers/inapp/NativeMessagingInApp.swift +90 -0
  30. package/ios/wrappers/inbox/InboxHostContainment.swift +40 -0
  31. package/ios/wrappers/inbox/RCTNotificationInboxBellNative.h +12 -0
  32. package/ios/wrappers/inbox/RCTNotificationInboxBellNative.mm +98 -0
  33. package/ios/wrappers/inbox/RCTNotificationInboxViewNative.h +12 -0
  34. package/ios/wrappers/inbox/RCTNotificationInboxViewNative.mm +78 -0
  35. package/ios/wrappers/inbox/ReactInboxEventListener.swift +76 -0
  36. package/ios/wrappers/inbox/ReactNotificationInboxBellView.h +22 -0
  37. package/ios/wrappers/inbox/ReactNotificationInboxBellView.swift +109 -0
  38. package/ios/wrappers/inbox/ReactNotificationInboxView.h +22 -0
  39. package/ios/wrappers/inbox/ReactNotificationInboxView.swift +69 -0
  40. package/ios/wrappers/liveactivities/NativeLiveActivities.mm +83 -0
  41. package/ios/wrappers/liveactivities/NativeLiveActivities.swift +390 -0
  42. package/ios/wrappers/location/NativeLocation.swift +7 -5
  43. package/ios/wrappers/utils/ZixflowConstants.swift +4 -0
  44. package/ios/wrappers/zixflow_reactnative.h +6 -0
  45. package/lib/commonjs/components/NotificationInboxBellView.js +49 -0
  46. package/lib/commonjs/components/NotificationInboxBellView.js.map +1 -0
  47. package/lib/commonjs/components/NotificationInboxView.js +36 -0
  48. package/lib/commonjs/components/NotificationInboxView.js.map +1 -0
  49. package/lib/commonjs/components/index.js +14 -0
  50. package/lib/commonjs/components/index.js.map +1 -1
  51. package/lib/commonjs/index.js +81 -4
  52. package/lib/commonjs/index.js.map +1 -1
  53. package/lib/commonjs/notification-inbox.js +1 -0
  54. package/lib/commonjs/notification-inbox.js.map +1 -1
  55. package/lib/commonjs/specs/components/NotificationInboxBellNativeComponent.ts +24 -0
  56. package/lib/commonjs/specs/components/NotificationInboxViewNativeComponent.ts +22 -0
  57. package/lib/commonjs/specs/modules/NativeZixflow.js.map +1 -1
  58. package/lib/commonjs/specs/modules/NativeZixflowGeofence.js +15 -0
  59. package/lib/commonjs/specs/modules/NativeZixflowGeofence.js.map +1 -0
  60. package/lib/commonjs/specs/modules/NativeZixflowLiveActivities.js +23 -0
  61. package/lib/commonjs/specs/modules/NativeZixflowLiveActivities.js.map +1 -0
  62. package/lib/commonjs/specs/modules/NativeZixflowMessagingInApp.js +3 -1
  63. package/lib/commonjs/specs/modules/NativeZixflowMessagingInApp.js.map +1 -1
  64. package/lib/commonjs/specs/modules/NativeZixflowMessagingPush.js +3 -1
  65. package/lib/commonjs/specs/modules/NativeZixflowMessagingPush.js.map +1 -1
  66. package/lib/commonjs/types/data-pipelines.js +13 -1
  67. package/lib/commonjs/types/data-pipelines.js.map +1 -1
  68. package/lib/commonjs/types/in-app.js +24 -1
  69. package/lib/commonjs/types/in-app.js.map +1 -1
  70. package/lib/commonjs/types/inbox.js +79 -0
  71. package/lib/commonjs/types/inbox.js.map +1 -0
  72. package/lib/commonjs/types/index.js +22 -0
  73. package/lib/commonjs/types/index.js.map +1 -1
  74. package/lib/commonjs/types/live-activities.js +85 -0
  75. package/lib/commonjs/types/live-activities.js.map +1 -0
  76. package/lib/commonjs/utils/param-validation.js +76 -1
  77. package/lib/commonjs/utils/param-validation.js.map +1 -1
  78. package/lib/commonjs/zixflow-cdp.js +99 -1
  79. package/lib/commonjs/zixflow-cdp.js.map +1 -1
  80. package/lib/commonjs/zixflow-geofence.js +55 -0
  81. package/lib/commonjs/zixflow-geofence.js.map +1 -0
  82. package/lib/commonjs/zixflow-inapp.js +120 -0
  83. package/lib/commonjs/zixflow-inapp.js.map +1 -1
  84. package/lib/commonjs/zixflow-liveactivities.js +85 -0
  85. package/lib/commonjs/zixflow-liveactivities.js.map +1 -0
  86. package/lib/module/components/NotificationInboxBellView.js +44 -0
  87. package/lib/module/components/NotificationInboxBellView.js.map +1 -0
  88. package/lib/module/components/NotificationInboxView.js +31 -0
  89. package/lib/module/components/NotificationInboxView.js.map +1 -0
  90. package/lib/module/components/index.js +5 -0
  91. package/lib/module/components/index.js.map +1 -1
  92. package/lib/module/index.js +8 -3
  93. package/lib/module/index.js.map +1 -1
  94. package/lib/module/notification-inbox.js +1 -1
  95. package/lib/module/notification-inbox.js.map +1 -1
  96. package/lib/module/specs/components/NotificationInboxBellNativeComponent.ts +24 -0
  97. package/lib/module/specs/components/NotificationInboxViewNativeComponent.ts +22 -0
  98. package/lib/module/specs/modules/NativeZixflow.js.map +1 -1
  99. package/lib/module/specs/modules/NativeZixflowGeofence.js +13 -0
  100. package/lib/module/specs/modules/NativeZixflowGeofence.js.map +1 -0
  101. package/lib/module/specs/modules/NativeZixflowLiveActivities.js +21 -0
  102. package/lib/module/specs/modules/NativeZixflowLiveActivities.js.map +1 -0
  103. package/lib/module/specs/modules/NativeZixflowMessagingInApp.js +3 -1
  104. package/lib/module/specs/modules/NativeZixflowMessagingInApp.js.map +1 -1
  105. package/lib/module/specs/modules/NativeZixflowMessagingPush.js +3 -1
  106. package/lib/module/specs/modules/NativeZixflowMessagingPush.js.map +1 -1
  107. package/lib/module/types/data-pipelines.js +13 -0
  108. package/lib/module/types/data-pipelines.js.map +1 -1
  109. package/lib/module/types/in-app.js +24 -0
  110. package/lib/module/types/in-app.js.map +1 -1
  111. package/lib/module/types/inbox.js +75 -0
  112. package/lib/module/types/inbox.js.map +1 -0
  113. package/lib/module/types/index.js +2 -0
  114. package/lib/module/types/index.js.map +1 -1
  115. package/lib/module/types/live-activities.js +88 -0
  116. package/lib/module/types/live-activities.js.map +1 -0
  117. package/lib/module/utils/param-validation.js +76 -1
  118. package/lib/module/utils/param-validation.js.map +1 -1
  119. package/lib/module/zixflow-cdp.js +99 -1
  120. package/lib/module/zixflow-cdp.js.map +1 -1
  121. package/lib/module/zixflow-geofence.js +50 -0
  122. package/lib/module/zixflow-geofence.js.map +1 -0
  123. package/lib/module/zixflow-inapp.js +99 -1
  124. package/lib/module/zixflow-inapp.js.map +1 -1
  125. package/lib/module/zixflow-liveactivities.js +80 -0
  126. package/lib/module/zixflow-liveactivities.js.map +1 -0
  127. package/lib/typescript/commonjs/components/NotificationInboxBellView.d.ts +39 -0
  128. package/lib/typescript/commonjs/components/NotificationInboxBellView.d.ts.map +1 -0
  129. package/lib/typescript/commonjs/components/NotificationInboxView.d.ts +25 -0
  130. package/lib/typescript/commonjs/components/NotificationInboxView.d.ts.map +1 -0
  131. package/lib/typescript/commonjs/components/index.d.ts +4 -0
  132. package/lib/typescript/commonjs/components/index.d.ts.map +1 -1
  133. package/lib/typescript/commonjs/index.d.ts +8 -1
  134. package/lib/typescript/commonjs/index.d.ts.map +1 -1
  135. package/lib/typescript/commonjs/notification-inbox.d.ts +5 -0
  136. package/lib/typescript/commonjs/notification-inbox.d.ts.map +1 -1
  137. package/lib/typescript/commonjs/specs/components/NotificationInboxBellNativeComponent.d.ts +13 -0
  138. package/lib/typescript/commonjs/specs/components/NotificationInboxBellNativeComponent.d.ts.map +1 -0
  139. package/lib/typescript/commonjs/specs/components/NotificationInboxViewNativeComponent.d.ts +12 -0
  140. package/lib/typescript/commonjs/specs/components/NotificationInboxViewNativeComponent.d.ts.map +1 -0
  141. package/lib/typescript/commonjs/specs/modules/NativeZixflow.d.ts +6 -1
  142. package/lib/typescript/commonjs/specs/modules/NativeZixflow.d.ts.map +1 -1
  143. package/lib/typescript/commonjs/specs/modules/NativeZixflowGeofence.d.ts +13 -0
  144. package/lib/typescript/commonjs/specs/modules/NativeZixflowGeofence.d.ts.map +1 -0
  145. package/lib/typescript/commonjs/specs/modules/NativeZixflowLiveActivities.d.ts +31 -0
  146. package/lib/typescript/commonjs/specs/modules/NativeZixflowLiveActivities.d.ts.map +1 -0
  147. package/lib/typescript/commonjs/specs/modules/NativeZixflowMessagingInApp.d.ts +5 -1
  148. package/lib/typescript/commonjs/specs/modules/NativeZixflowMessagingInApp.d.ts.map +1 -1
  149. package/lib/typescript/commonjs/specs/modules/NativeZixflowMessagingPush.d.ts +1 -1
  150. package/lib/typescript/commonjs/specs/modules/NativeZixflowMessagingPush.d.ts.map +1 -1
  151. package/lib/typescript/commonjs/types/data-pipelines.d.ts +53 -1
  152. package/lib/typescript/commonjs/types/data-pipelines.d.ts.map +1 -1
  153. package/lib/typescript/commonjs/types/in-app.d.ts +22 -0
  154. package/lib/typescript/commonjs/types/in-app.d.ts.map +1 -1
  155. package/lib/typescript/commonjs/types/inbox.d.ts +97 -0
  156. package/lib/typescript/commonjs/types/inbox.d.ts.map +1 -0
  157. package/lib/typescript/commonjs/types/index.d.ts +2 -0
  158. package/lib/typescript/commonjs/types/index.d.ts.map +1 -1
  159. package/lib/typescript/commonjs/types/live-activities.d.ts +161 -0
  160. package/lib/typescript/commonjs/types/live-activities.d.ts.map +1 -0
  161. package/lib/typescript/commonjs/utils/param-validation.d.ts +7 -0
  162. package/lib/typescript/commonjs/utils/param-validation.d.ts.map +1 -1
  163. package/lib/typescript/commonjs/zixflow-cdp.d.ts +38 -0
  164. package/lib/typescript/commonjs/zixflow-cdp.d.ts.map +1 -1
  165. package/lib/typescript/commonjs/zixflow-geofence.d.ts +36 -0
  166. package/lib/typescript/commonjs/zixflow-geofence.d.ts.map +1 -0
  167. package/lib/typescript/commonjs/zixflow-inapp.d.ts +36 -2
  168. package/lib/typescript/commonjs/zixflow-inapp.d.ts.map +1 -1
  169. package/lib/typescript/commonjs/zixflow-liveactivities.d.ts +66 -0
  170. package/lib/typescript/commonjs/zixflow-liveactivities.d.ts.map +1 -0
  171. package/lib/typescript/module/components/NotificationInboxBellView.d.ts +39 -0
  172. package/lib/typescript/module/components/NotificationInboxBellView.d.ts.map +1 -0
  173. package/lib/typescript/module/components/NotificationInboxView.d.ts +25 -0
  174. package/lib/typescript/module/components/NotificationInboxView.d.ts.map +1 -0
  175. package/lib/typescript/module/components/index.d.ts +4 -0
  176. package/lib/typescript/module/components/index.d.ts.map +1 -1
  177. package/lib/typescript/module/index.d.ts +8 -1
  178. package/lib/typescript/module/index.d.ts.map +1 -1
  179. package/lib/typescript/module/notification-inbox.d.ts +5 -0
  180. package/lib/typescript/module/notification-inbox.d.ts.map +1 -1
  181. package/lib/typescript/module/specs/components/NotificationInboxBellNativeComponent.d.ts +13 -0
  182. package/lib/typescript/module/specs/components/NotificationInboxBellNativeComponent.d.ts.map +1 -0
  183. package/lib/typescript/module/specs/components/NotificationInboxViewNativeComponent.d.ts +12 -0
  184. package/lib/typescript/module/specs/components/NotificationInboxViewNativeComponent.d.ts.map +1 -0
  185. package/lib/typescript/module/specs/modules/NativeZixflow.d.ts +6 -1
  186. package/lib/typescript/module/specs/modules/NativeZixflow.d.ts.map +1 -1
  187. package/lib/typescript/module/specs/modules/NativeZixflowGeofence.d.ts +13 -0
  188. package/lib/typescript/module/specs/modules/NativeZixflowGeofence.d.ts.map +1 -0
  189. package/lib/typescript/module/specs/modules/NativeZixflowLiveActivities.d.ts +31 -0
  190. package/lib/typescript/module/specs/modules/NativeZixflowLiveActivities.d.ts.map +1 -0
  191. package/lib/typescript/module/specs/modules/NativeZixflowMessagingInApp.d.ts +5 -1
  192. package/lib/typescript/module/specs/modules/NativeZixflowMessagingInApp.d.ts.map +1 -1
  193. package/lib/typescript/module/specs/modules/NativeZixflowMessagingPush.d.ts +1 -1
  194. package/lib/typescript/module/specs/modules/NativeZixflowMessagingPush.d.ts.map +1 -1
  195. package/lib/typescript/module/types/data-pipelines.d.ts +53 -1
  196. package/lib/typescript/module/types/data-pipelines.d.ts.map +1 -1
  197. package/lib/typescript/module/types/in-app.d.ts +22 -0
  198. package/lib/typescript/module/types/in-app.d.ts.map +1 -1
  199. package/lib/typescript/module/types/inbox.d.ts +97 -0
  200. package/lib/typescript/module/types/inbox.d.ts.map +1 -0
  201. package/lib/typescript/module/types/index.d.ts +2 -0
  202. package/lib/typescript/module/types/index.d.ts.map +1 -1
  203. package/lib/typescript/module/types/live-activities.d.ts +161 -0
  204. package/lib/typescript/module/types/live-activities.d.ts.map +1 -0
  205. package/lib/typescript/module/utils/param-validation.d.ts +7 -0
  206. package/lib/typescript/module/utils/param-validation.d.ts.map +1 -1
  207. package/lib/typescript/module/zixflow-cdp.d.ts +38 -0
  208. package/lib/typescript/module/zixflow-cdp.d.ts.map +1 -1
  209. package/lib/typescript/module/zixflow-geofence.d.ts +36 -0
  210. package/lib/typescript/module/zixflow-geofence.d.ts.map +1 -0
  211. package/lib/typescript/module/zixflow-inapp.d.ts +36 -2
  212. package/lib/typescript/module/zixflow-inapp.d.ts.map +1 -1
  213. package/lib/typescript/module/zixflow-liveactivities.d.ts +66 -0
  214. package/lib/typescript/module/zixflow-liveactivities.d.ts.map +1 -0
  215. package/package.json +11 -2
  216. package/src/components/NotificationInboxBellView.tsx +55 -0
  217. package/src/components/NotificationInboxView.tsx +30 -0
  218. package/src/components/index.ts +6 -0
  219. package/src/index.ts +8 -3
  220. package/src/notification-inbox.ts +1 -1
  221. package/src/specs/components/NotificationInboxBellNativeComponent.ts +24 -0
  222. package/src/specs/components/NotificationInboxViewNativeComponent.ts +22 -0
  223. package/src/specs/modules/NativeZixflow.ts +9 -1
  224. package/src/specs/modules/NativeZixflowGeofence.ts +14 -0
  225. package/src/specs/modules/NativeZixflowLiveActivities.ts +39 -0
  226. package/src/specs/modules/NativeZixflowMessagingInApp.ts +12 -1
  227. package/src/specs/modules/NativeZixflowMessagingPush.ts +3 -1
  228. package/src/types/data-pipelines.ts +54 -1
  229. package/src/types/in-app.ts +23 -0
  230. package/src/types/inbox.ts +110 -0
  231. package/src/types/index.ts +2 -0
  232. package/src/types/live-activities.ts +170 -0
  233. package/src/utils/param-validation.ts +103 -0
  234. package/src/zixflow-cdp.ts +117 -1
  235. package/src/zixflow-geofence.ts +56 -0
  236. package/src/zixflow-inapp.ts +125 -2
  237. package/src/zixflow-liveactivities.ts +86 -0
  238. package/zixflow-reactnative-richpush.podspec +4 -1
  239. package/zixflow-reactnative.podspec +26 -0
@@ -0,0 +1,110 @@
1
+ import type { InboxMessage } from './in-app';
2
+
3
+ /**
4
+ * Enum representing the type of event triggered by an inbox event callback.
5
+ *
6
+ * Mirrors the native `InboxEventListener` contract on iOS and Android.
7
+ *
8
+ * @public
9
+ */
10
+ export enum InboxEventType {
11
+ /** A non-dismiss action (e.g. a button/link) was taken on an inbox message. */
12
+ messageActionTaken = 'messageActionTaken',
13
+ /** An inbox message was first shown/rendered in the visible inbox view. */
14
+ messageShown = 'messageShown',
15
+ /** An inbox message was marked opened (e.g. when the panel opens). */
16
+ messageOpened = 'messageOpened',
17
+ /** An inbox message was dismissed/removed from the inbox. */
18
+ messageDismissed = 'messageDismissed',
19
+ }
20
+
21
+ /**
22
+ * Event delivered to a registered inbox event listener.
23
+ *
24
+ * `messageActionTaken` carries `actionName`/`actionValue`; the observational
25
+ * events (`messageShown`, `messageOpened`, `messageDismissed`) carry only the
26
+ * message.
27
+ *
28
+ * @public
29
+ */
30
+ export class InboxMessageEvent {
31
+ /** The type of inbox event. */
32
+ eventType: InboxEventType;
33
+ /** The inbox message the event relates to. */
34
+ message: InboxMessage;
35
+ /** The Jist action name (only present for `messageActionTaken`). */
36
+ actionName?: string;
37
+ /** The resolved action value, typically a url (only present for `messageActionTaken`). */
38
+ actionValue?: string;
39
+
40
+ constructor(
41
+ eventType: InboxEventType,
42
+ message: InboxMessage,
43
+ actionName?: string,
44
+ actionValue?: string
45
+ ) {
46
+ this.eventType = eventType;
47
+ this.message = message;
48
+ this.actionName = actionName;
49
+ this.actionValue = actionValue;
50
+ }
51
+ }
52
+
53
+ /**
54
+ * Host-provided accessibility labels for the Visual Notification Inbox UI.
55
+ *
56
+ * The SDK ships no text of its own in the visual inbox — the empty state is an icon and the
57
+ * loading state is a spinner — so accessibility labels are the one place a string is still
58
+ * needed. Because the SDK cannot know your app's language, every label is optional and unset by
59
+ * default, and an omitted label leaves that element unlabeled rather than falling back to
60
+ * English. Pass strings already localized for the user's language.
61
+ *
62
+ * @example
63
+ * ```ts
64
+ * Zixflow.initialize({
65
+ * apiKey: '...',
66
+ * inApp: {
67
+ * siteId: '...',
68
+ * notificationInboxAccessibilityLabels: {
69
+ * bell: t('inbox.bell'),
70
+ * bellWithUnreadCount: t('inbox.unread'), // e.g. "{count} unread notifications"
71
+ * loadingIndicator: t('inbox.loading'),
72
+ * emptyState: t('inbox.empty'),
73
+ * },
74
+ * },
75
+ * });
76
+ * ```
77
+ *
78
+ * @public
79
+ */
80
+ export type NotificationInboxAccessibilityLabels = {
81
+ /**
82
+ * Label for the inbox bell button. Also used when the bell shows an unread badge but
83
+ * `bellWithUnreadCount` is not provided. Unset → the bell is announced as an unnamed button
84
+ * (it stays focusable and tappable; hiding it would leave screen reader users no way in).
85
+ */
86
+ bell?: string;
87
+ /**
88
+ * Label for the bell while it shows an unread badge. Include `{count}` where the number of
89
+ * unread messages should appear; it is substituted at render time. Unset → falls back to `bell`.
90
+ *
91
+ * The badge itself is always hidden from assistive technologies, so the count is announced
92
+ * only through this label, never as bare digits appended to the button.
93
+ *
94
+ * This is a template rather than a function because configuration crosses the native bridge,
95
+ * which carries data but not callbacks. One template cannot express languages whose plural
96
+ * rules need a distinct form per count.
97
+ */
98
+ bellWithUnreadCount?: string;
99
+ /**
100
+ * Label announced for the loading spinner.
101
+ *
102
+ * Unset behaves differently per platform: on Android the spinner keeps its indeterminate
103
+ * progress role, which TalkBack describes in the device's own language, while on iOS it is not
104
+ * an accessibility element at all, so VoiceOver skips it rather than focusing an unnamed
105
+ * control. Set a label if you want the loading state announced on both.
106
+ */
107
+ loadingIndicator?: string;
108
+ /** Label announced for the empty-state icon. Unset → the icon is treated as decorative. */
109
+ emptyState?: string;
110
+ };
@@ -1,3 +1,5 @@
1
1
  export * from './data-pipelines';
2
2
  export * from './in-app';
3
+ export * from './inbox';
4
+ export * from './live-activities';
3
5
  export * from './push';
@@ -0,0 +1,170 @@
1
+ /**
2
+ * Public types for the Live Activities module.
3
+ *
4
+ * Live Activities (iOS) / Live Notifications (Android) render live, updating
5
+ * notifications from built-in templates. Two templates ship today: Segments and
6
+ * Countdown Timer. Field names and identifiers are identical across platforms.
7
+ */
8
+
9
+ /**
10
+ * Built-in activity type identifiers usable from the wrapper.
11
+ *
12
+ * The values are the reverse-DNS identifiers Zixflow uses everywhere — the
13
+ * `notificationType` on the wire, Android's `LiveNotificationType`, and iOS's
14
+ * `CIOSegmentsAttributes.identifier` — so JS, both native SDKs, and the backend
15
+ * share one vocabulary.
16
+ *
17
+ * Use these enum members (not raw strings) for `LiveActivitiesConfig.types` and a
18
+ * payload's `type` to avoid typos.
19
+ *
20
+ * @public
21
+ */
22
+ export enum LiveActivityTemplate {
23
+ Segments = 'com.zixflow.livenotifications.segments',
24
+ CountdownTimer = 'com.zixflow.livenotifications.countdowntimer',
25
+ /**
26
+ * Your own activity type, rendered by SwiftUI you write.
27
+ *
28
+ * Unlike the members above, this value is a marker rather than an identifier — your activity is
29
+ * named by {@link LiveActivitiesConfig.customType}, and the SDK reports it under that name. It
30
+ * belongs in a payload's `type`, never in {@link LiveActivitiesConfig.types}.
31
+ */
32
+ Custom = 'custom',
33
+ }
34
+
35
+ /**
36
+ * Segments template — a progress activity split into N segments.
37
+ * `header` is a static attribute (fixed at start); the rest are content-state.
38
+ *
39
+ * @public
40
+ */
41
+ export interface LiveActivitySegmentsPayload {
42
+ type: LiveActivityTemplate.Segments;
43
+ /** Static header line (set at start, never changes). */
44
+ header: string;
45
+ /** Primary status line. */
46
+ status: string;
47
+ /** Optional secondary status line. */
48
+ substatus?: string;
49
+ /** Total number of segments. */
50
+ segmentsTotal: number;
51
+ /** Number of completed segments (clamped to 0..segmentsTotal). */
52
+ segmentsComplete: number;
53
+ /** Optional trailing text (e.g. an ETA). */
54
+ trailingText?: string;
55
+ }
56
+
57
+ /**
58
+ * Custom template — your own activity type, rendered by SwiftUI you write.
59
+ *
60
+ * Unlike the built-in templates there is no schema: `data` is an untyped map, because a bridge
61
+ * payload carries nothing for the SDK to validate against. Every value is a string, so your widget
62
+ * parses whichever ones it needs.
63
+ *
64
+ * Requires {@link LiveActivitiesConfig.customType} to be set. On iOS you must also render
65
+ * `CIOCustomAttributes` in your Widget Extension; on Android your `createLiveNotification`
66
+ * callback receives the same map.
67
+ *
68
+ * @public
69
+ */
70
+ export interface LiveActivityCustomPayload {
71
+ type: LiveActivityTemplate.Custom;
72
+ /**
73
+ * The full content-state, re-sent in its entirety on every update. Neither platform keeps a
74
+ * static/dynamic split for custom types, so include anything your widget needs each time.
75
+ *
76
+ * Values must be strings. Numbers and booleans are coerced, but nested objects and arrays are
77
+ * not supported and the platforms disagree on them — iOS drops them, Android stringifies them —
78
+ * so flatten anything structured before sending it.
79
+ */
80
+ data: Record<string, string>;
81
+ }
82
+
83
+ /**
84
+ * Countdown Timer template — a live countdown to a target time.
85
+ * `header` is a static attribute (fixed at start); the rest are content-state.
86
+ *
87
+ * @public
88
+ */
89
+ export interface LiveActivityCountdownTimerPayload {
90
+ type: LiveActivityTemplate.CountdownTimer;
91
+ /** Static header line (set at start, never changes). */
92
+ header: string;
93
+ /** Primary title line. */
94
+ title: string;
95
+ /** Optional status message. */
96
+ statusMessage?: string;
97
+ /** Target time as epoch **seconds**. Omit to render the finished state. */
98
+ endTime?: number;
99
+ }
100
+
101
+ /**
102
+ * Payload for {@link ZixflowLiveActivities.start} and
103
+ * {@link ZixflowLiveActivities.update}.
104
+ *
105
+ * Because ActivityKit replaces content-state wholesale on update, `update` takes the
106
+ * same full payload as `start` — pass the complete desired state each time.
107
+ *
108
+ * @public
109
+ */
110
+ export type LiveActivityPayload =
111
+ | LiveActivitySegmentsPayload
112
+ | LiveActivityCountdownTimerPayload
113
+ | LiveActivityCustomPayload;
114
+
115
+ /**
116
+ * Live Activities branding (Android only). On iOS, branding is compiled into the
117
+ * widget extension's SwiftUI, so these values are ignored there.
118
+ *
119
+ * @public
120
+ */
121
+ export interface LiveActivitiesBranding {
122
+ /** Reserved for future use. */
123
+ companyName?: string;
124
+ /** Accent color as "#RRGGBB". */
125
+ accentColorHex?: string;
126
+ /**
127
+ * Bundled Android drawable resource name for the logo, resolved natively.
128
+ * Preferred over {@link LiveActivitiesBranding.logoUrl} when both are set — it
129
+ * needs no network.
130
+ */
131
+ logoResource?: string;
132
+ /** Remote logo URL (downloaded and cached natively). */
133
+ logoUrl?: string;
134
+ /** Android drawable resource name, resolved natively. */
135
+ smallIconResource?: string;
136
+ }
137
+
138
+ /**
139
+ * Live Activities configuration, passed under the `liveNotifications` key of the SDK config.
140
+ *
141
+ * @public
142
+ */
143
+ export interface LiveActivitiesConfig {
144
+ /**
145
+ * Built-in activity types to enable. Enables the matching native type on each
146
+ * platform and registers push-to-start for it. Unrecognized identifiers are
147
+ * ignored, so a newer native template can't break an older wrapper build.
148
+ *
149
+ * `Custom` is excluded on purpose — it is enabled by {@link LiveActivitiesConfig.customType},
150
+ * and both platforms would silently drop it from this list.
151
+ */
152
+ types?: Exclude<LiveActivityTemplate, LiveActivityTemplate.Custom>[];
153
+ /**
154
+ * Your own reverse-DNS identifier for the custom activity type, e.g.
155
+ * `'com.myapp.rideshare'`. Setting it enables the custom template on both platforms.
156
+ *
157
+ * Start one with `{ type: LiveActivityTemplate.Custom, data: { … } }`; the SDK reports it
158
+ * under this identifier, and your campaigns target it by the same name.
159
+ *
160
+ * Singular by design: iOS resolves an activity's type from its Swift attributes type, and
161
+ * every custom activity shares one. A second identifier could not be told apart, so one
162
+ * identifier is the limit rather than a silent mis-attribution.
163
+ *
164
+ * You must also render it yourself — `CIOCustomAttributes` in an iOS Widget Extension, and
165
+ * the `createLiveNotification` callback on Android.
166
+ */
167
+ customType?: string;
168
+ /** Android Live Notification branding (ignored on iOS). */
169
+ branding?: LiveActivitiesBranding;
170
+ }
@@ -1,6 +1,7 @@
1
1
  // Argument validation utilities for SDK internal use
2
2
  // Ensures input safety and throws clear errors when validation fails
3
3
 
4
+ import { ZixflowColorScheme } from '../types';
4
5
  import type { ZixflowConfig, CustomAttributes } from '../types';
5
6
 
6
7
  /**
@@ -32,6 +33,16 @@ function failIf(condition: boolean, message: () => string): void {
32
33
  }
33
34
  }
34
35
 
36
+ /**
37
+ * Logs a warning if the condition is true.
38
+ * Use this for misconfigurations that degrade behavior but must not fail initialization.
39
+ */
40
+ function warnIf(condition: boolean, message: () => string): void {
41
+ if (__DEV__ && condition) {
42
+ console.warn(`[Zixflow] ${message()}`);
43
+ }
44
+ }
45
+
35
46
  /**
36
47
  * Validates that a value is defined (not undefined or null).
37
48
  * Useful for checking required fields.
@@ -137,6 +148,92 @@ function validateAttributes(
137
148
  return attributes as CustomAttributes;
138
149
  }
139
150
 
151
+ /**
152
+ * The placeholder the SDK substitutes with the unread count when rendering
153
+ * `bellWithUnreadCount`.
154
+ */
155
+ const COUNT_PLACEHOLDER = '{count}';
156
+
157
+ /**
158
+ * Warns when `bellWithUnreadCount` is missing its `{count}` placeholder.
159
+ *
160
+ * The label is a template, not a finished string. A misspelled placeholder (`{COUNT}`,
161
+ * `{{count}}`, `%d`) matches nothing, so the template is announced verbatim — braces and all —
162
+ * and the count is never spoken. The check lives here rather than in either native layer
163
+ * because neither can report it usefully: Android logs at `debug`, which the default `ERROR`
164
+ * level discards, and iOS does not check at all. Warning from JavaScript reaches the
165
+ * developer's console on both platforms, whatever the SDK log level.
166
+ */
167
+ function validateInboxAccessibilityLabels(value: unknown): void {
168
+ if (isUndefined(value) || typeof value !== 'object') {
169
+ return;
170
+ }
171
+
172
+ const template = (value as { bellWithUnreadCount?: unknown })
173
+ .bellWithUnreadCount;
174
+ warnIf(
175
+ typeof template === 'string' && !template.includes(COUNT_PLACEHOLDER),
176
+ () =>
177
+ `"inApp.notificationInboxAccessibilityLabels.bellWithUnreadCount" has no ` +
178
+ `"${COUNT_PLACEHOLDER}" placeholder, so the unread count will not be announced.`
179
+ );
180
+ }
181
+
182
+ /**
183
+ * Warns when a value is not one of the `ZixflowColorScheme` values.
184
+ *
185
+ * TypeScript rejects a bad value already, but JavaScript callers reach both entry points
186
+ * untyped, and neither native layer reports the mistake at the default log level. The
187
+ * failure mode is a message rendered in the wrong theme with no error attached, so
188
+ * JavaScript is the only place the developer reliably sees it.
189
+ *
190
+ * `consequence` differs per entry point because the native fallback does: an unrecognized
191
+ * value at initialization resolves to `auto`, while the runtime setter leaves whatever
192
+ * scheme the app already chose in place.
193
+ */
194
+ function warnIfNotColorScheme(
195
+ value: unknown,
196
+ fieldName: string,
197
+ consequence: string
198
+ ): void {
199
+ const allowed: string[] = Object.values(ZixflowColorScheme);
200
+ warnIf(
201
+ !(typeof value === 'string' && allowed.includes(value)),
202
+ () =>
203
+ `"${fieldName}" is not a valid ZixflowColorScheme (expected one of ` +
204
+ `${allowed.join(', ')}), so ${consequence}.`
205
+ );
206
+ }
207
+
208
+ /**
209
+ * Validates `inApp.colorScheme`. An absent value is legitimate here — the native SDKs
210
+ * already default to `auto` — so only a value the host actually set is checked.
211
+ */
212
+ function validateConfigColorScheme(value: unknown): void {
213
+ if (isUndefined(value)) {
214
+ return;
215
+ }
216
+
217
+ warnIfNotColorScheme(
218
+ value,
219
+ 'inApp.colorScheme',
220
+ 'in-app messages will follow the device appearance'
221
+ );
222
+ }
223
+
224
+ /**
225
+ * Validates the argument to `setColorScheme`. Unlike the config field, an absent value is
226
+ * itself the mistake: the caller asked for a scheme change and named none, and there is no
227
+ * default to fall back to, so null and undefined are reported rather than skipped.
228
+ */
229
+ function validateColorSchemeArgument(value: unknown): void {
230
+ warnIfNotColorScheme(
231
+ value,
232
+ 'colorScheme',
233
+ 'the color scheme will be left unchanged'
234
+ );
235
+ }
236
+
140
237
  /**
141
238
  * Validates that the given value is a valid ZixflowConfig object.
142
239
  * Throws if required fields are missing or incorrectly typed.
@@ -155,6 +252,10 @@ function validateConfig(value: unknown): asserts value is ZixflowConfig {
155
252
  allowEmpty: false,
156
253
  usage: usage,
157
254
  });
255
+ validateConfigColorScheme(obj.inApp?.colorScheme);
256
+ validateInboxAccessibilityLabels(
257
+ obj.inApp?.notificationInboxAccessibilityLabels
258
+ );
158
259
  }
159
260
 
160
261
  // For type safety, we define a ConfigValidator type that asserts the value is a ZixflowConfig
@@ -166,11 +267,13 @@ export const assert: {
166
267
  record: typeof validateRecord;
167
268
  attributes: typeof validateAttributes;
168
269
  config: ConfigValidator;
270
+ colorScheme: typeof validateColorSchemeArgument;
169
271
  } = {
170
272
  string: validateString,
171
273
  record: validateRecord,
172
274
  attributes: validateAttributes,
173
275
  config: validateConfig,
276
+ colorScheme: validateColorSchemeArgument,
174
277
  };
175
278
 
176
279
  export const validate = {
@@ -1,4 +1,6 @@
1
+ import { ZixflowGeofence } from './zixflow-geofence';
1
2
  import { ZixflowInAppMessaging } from './zixflow-inapp';
3
+ import { ZixflowLiveActivities } from './zixflow-liveactivities';
2
4
  import { ZixflowLocation } from './zixflow-location';
3
5
  import { ZixflowPushMessaging } from './zixflow-push';
4
6
  import { NativeLoggerListener } from './native-logger-listener';
@@ -17,10 +19,26 @@ import type { NativeSDKArgs } from './types/internal';
17
19
  import { callNativeModule, ensureNativeModule } from './utils/native-bridge';
18
20
  import { assert, validate } from './utils/param-validation';
19
21
 
20
- const packageJson = require('../../package.json');
22
+ const packageJson = require('../package.json');
21
23
 
22
24
  // Track whether Zixflow SDK has been initialized to prevent usage before setup
23
25
  let _initialized = false;
26
+ let deepLinkHandlerSubscription: DeepLinkHandlerSubscription | undefined;
27
+
28
+ /**
29
+ * Handles a Zixflow deep-link destination delivered from iOS.
30
+ * @public
31
+ */
32
+ export type DeepLinkHandler = (url: string) => boolean | Promise<boolean>;
33
+
34
+ /**
35
+ * Removes a Zixflow deep-link handler.
36
+ * @public
37
+ */
38
+ export interface DeepLinkHandlerSubscription {
39
+ /** Stop routing Zixflow deep links through this handler. */
40
+ remove(): void;
41
+ }
24
42
 
25
43
  // Reference to the native Zixflow Data Pipelines module for SDK operations
26
44
  const nativeModule = ensureNativeModule(NativeModule);
@@ -58,6 +76,102 @@ export class Zixflow {
58
76
  });
59
77
  };
60
78
 
79
+ /**
80
+ * Signal that the app's React Native Linking listener is ready to receive Zixflow URLs.
81
+ *
82
+ * This is only needed by UIScene hosts that initialize Zixflow natively, such as Expo
83
+ * config-plugin auto-initialization. Call it after registering the Linking listener.
84
+ */
85
+ static readonly setDeepLinkRoutingReady = () => {
86
+ return withNativeModule<void>((native) => native.setDeepLinkRoutingReady());
87
+ };
88
+
89
+ /**
90
+ * Register an acknowledged deep-link handler for an iOS UIScene host.
91
+ *
92
+ * This API only handles Zixflow destinations delivered through an iOS UIScene lifecycle.
93
+ * In a native React Native scene host, pair this with
94
+ * `NativeZixflow.configureAcknowledgedSceneDeepLinkRouting()` in the SceneDelegate. Register
95
+ * this before `initialize` when possible. Return `true` after routing a URL. Returning `false`,
96
+ * throwing, or rejecting lets the native SDK try the host AppDelegate, then React Native Linking
97
+ * for a host-owned custom scheme or the system for other URLs. Cold URLs are buffered until this
98
+ * handler is registered, subject to the native timeout. After delivery, the handler has ten
99
+ * seconds to settle. Once that timeout runs the native fallback, a late handler cannot cancel it
100
+ * and may cause a second navigation if it also routes the URL.
101
+ */
102
+ static readonly setDeepLinkHandler = (
103
+ handler: DeepLinkHandler
104
+ ): DeepLinkHandlerSubscription => {
105
+ if (typeof handler !== 'function') {
106
+ throw new Error('[Zixflow] "handler" must be a function.');
107
+ }
108
+
109
+ // Native unregister is tokenless and removes the current native handler. Remove the old
110
+ // subscription first so its cleanup cannot unregister the replacement.
111
+ deepLinkHandlerSubscription?.remove();
112
+
113
+ return withNativeModule<DeepLinkHandlerSubscription>((native) => {
114
+ const nativeSubscription = native.onDeepLinkReceived(async (data) => {
115
+ const event = data as { id?: unknown; url?: unknown };
116
+ if (typeof event.id !== 'string' || typeof event.url !== 'string') {
117
+ NativeLoggerListener.warn(
118
+ 'Received an invalid native deep-link event.'
119
+ );
120
+ return;
121
+ }
122
+
123
+ let handled = false;
124
+ try {
125
+ handled = (await handler(event.url)) === true;
126
+ } catch (error) {
127
+ NativeLoggerListener.warn('Deep-link handler failed:', error);
128
+ }
129
+
130
+ try {
131
+ native.acknowledgeDeepLink(event.id, handled);
132
+ } catch (error) {
133
+ NativeLoggerListener.warn(
134
+ 'Failed to acknowledge a deep-link result:',
135
+ error
136
+ );
137
+ }
138
+ });
139
+
140
+ let removed = false;
141
+ const subscription: DeepLinkHandlerSubscription = {
142
+ remove: () => {
143
+ if (removed) {
144
+ return;
145
+ }
146
+ removed = true;
147
+ try {
148
+ native.unregisterDeepLinkHandler();
149
+ } finally {
150
+ nativeSubscription.remove();
151
+ if (deepLinkHandlerSubscription === subscription) {
152
+ deepLinkHandlerSubscription = undefined;
153
+ }
154
+ }
155
+ },
156
+ };
157
+
158
+ try {
159
+ native.registerDeepLinkHandler();
160
+ } catch (error) {
161
+ try {
162
+ native.unregisterDeepLinkHandler();
163
+ } catch {
164
+ // Preserve the registration error; the native timeout still owns pending URLs.
165
+ }
166
+ nativeSubscription.remove();
167
+ throw error;
168
+ }
169
+
170
+ deepLinkHandlerSubscription = subscription;
171
+ return subscription;
172
+ });
173
+ };
174
+
61
175
  /** Identify a user to start tracking their activity. Requires userId, traits, or both. */
62
176
  static readonly identify = async ({
63
177
  userId,
@@ -182,7 +296,9 @@ export class Zixflow {
182
296
  */
183
297
  static readonly isInitialized = () => _initialized;
184
298
 
299
+ static readonly geofence = new ZixflowGeofence();
185
300
  static readonly inAppMessaging = new ZixflowInAppMessaging();
301
+ static readonly liveActivities = new ZixflowLiveActivities();
186
302
  static readonly location = new ZixflowLocation();
187
303
  static readonly pushMessaging = new ZixflowPushMessaging();
188
304
  }
@@ -0,0 +1,56 @@
1
+ import { type TurboModule } from 'react-native';
2
+ import {
3
+ default as NativeModule,
4
+ type Spec as CodegenSpec,
5
+ } from './specs/modules/NativeZixflowGeofence';
6
+
7
+ /**
8
+ * Ensures all methods defined in codegen spec are implemented by the public module
9
+ *
10
+ * @internal
11
+ */
12
+ interface NativeGeofenceSpec extends Omit<CodegenSpec, keyof TurboModule> {}
13
+
14
+ // Geofence is an optional module — NativeModule may be null when geofence is not enabled.
15
+ // Methods silently no-op when the native module is unavailable, with a one-time dev warning.
16
+ let hasWarnedNotEnabled = false;
17
+ const withNativeModule = (fn: (native: CodegenSpec) => void): void => {
18
+ if (NativeModule) {
19
+ fn(NativeModule);
20
+ } else if (__DEV__ && !hasWarnedNotEnabled) {
21
+ hasWarnedNotEnabled = true;
22
+ console.warn(
23
+ 'Zixflow: Geofence module is not enabled. ' +
24
+ 'To use geofence features, set zixflow_geofence_enabled=true in ' +
25
+ 'gradle.properties (Android) or add the geofence subspec to your Podfile (iOS).'
26
+ );
27
+ }
28
+ };
29
+
30
+ /**
31
+ * Public entry point for the optional Geofence module.
32
+ *
33
+ * Geofence runs automatically once enabled. Apps opt in by passing a `geofence` config to
34
+ * `initialize` and enabling the module at build time: set `zixflow_geofence_enabled=true`
35
+ * in `gradle.properties` (Android) or add the `geofence` subspec to your Podfile (iOS).
36
+ * Enabling geofence also enables the Location module, which geofence depends on.
37
+ *
38
+ * @public
39
+ */
40
+ export class ZixflowGeofence implements NativeGeofenceSpec {
41
+ /**
42
+ * Requests a one-shot location fix and refreshes the nearby geofence set from it,
43
+ * without sending a location analytics event (unlike
44
+ * `Zixflow.location.requestLocationUpdate()`) and without caching the fix.
45
+ *
46
+ * Call this after the host app has been granted location permission — the SDK never
47
+ * requests permission itself. It is the primary way to drive geofencing when the module
48
+ * is configured with `MANUAL` location mode; with the default `AUTOMATIC` the SDK acquires
49
+ * location on its own and this only forces an immediate refresh.
50
+ *
51
+ * No-ops if the geofence module is not enabled or a user has not been identified.
52
+ */
53
+ refreshFromCurrentLocation(): void {
54
+ return withNativeModule((native) => native.refreshFromCurrentLocation());
55
+ }
56
+ }