@growth-rail/react-native 1.0.0 → 2.0.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @growth-rail/react-native
2
2
 
3
+ ## 2.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - Fixed issues and modified usage
8
+
3
9
  ## 1.0.0
4
10
 
5
11
  ### Major Changes
package/README.md CHANGED
@@ -32,7 +32,7 @@ import { GrowthRailProvider } from '@growth-rail/react-native';
32
32
  const App = () => {
33
33
  return (
34
34
  <GrowthRailProvider
35
- apiKey="YOUR_API_KEY"
35
+ projectSecretKey="YOUR_PROJECT_SECRET_KEY"
36
36
  userId="USER_UNIQUE_ID" // optional at start
37
37
  >
38
38
  <YourAppContent />
@@ -69,16 +69,15 @@ Add an intent filter for your deep link scheme:
69
69
  </intent-filter>
70
70
  ```
71
71
 
72
- ## Usage
73
-
74
72
  ### User Initialization
75
73
  If you didn't provide a `userId` to the provider, or if the user logs in later:
76
74
 
77
75
  ```tsx
78
- import { GrowthRail } from '@growth-rail/react-native';
76
+ import { useGrowthRail } from '@growth-rail/react-native';
79
77
 
80
78
  const handleLogin = async (user) => {
81
- await GrowthRail.initAppUser(user.id);
79
+ const { initAppUser } = useGrowthRail();
80
+ await initAppUser(user.id);
82
81
  };
83
82
  ```
84
83
 
@@ -86,10 +85,11 @@ const handleLogin = async (user) => {
86
85
  Attribute successful actions (like purchases or sign-ups) to the referrer:
87
86
 
88
87
  ```tsx
89
- import { GrowthRail } from '@growth-rail/react-native';
88
+ import { useGrowthRail } from '@growth-rail/react-native';
90
89
 
91
90
  const onPurchaseComplete = async () => {
92
- await GrowthRail.trackRewardEvent('purchase_completed');
91
+ const { trackRewardEvent } = useGrowthRail();
92
+ await trackRewardEvent('purchase_completed');
93
93
  };
94
94
  ```
95
95
 
@@ -101,15 +101,16 @@ import { useGrowthRail } from '@growth-rail/react-native';
101
101
 
102
102
  const MyComponent = () => {
103
103
  const {
104
- initUser,
105
- trackReward,
104
+ initAppUser,
105
+ trackRewardEvent,
106
106
  showReferralDashboard,
107
107
  isLoading,
108
+ isUserReady,
108
109
  error
109
110
  } = useGrowthRail();
110
111
 
111
112
  const handleAction = async () => {
112
- await trackReward('custom_action');
113
+ await trackRewardEvent('custom_action');
113
114
  };
114
115
 
115
116
  return (
@@ -125,13 +126,13 @@ const MyComponent = () => {
125
126
  Display a beautiful, pre-built dashboard for users to manage their referrals.
126
127
 
127
128
  ```tsx
128
- import { useGrowthRailContext } from '@growth-rail/react-native';
129
+ import { useGrowthRail } from '@growth-rail/react-native';
129
130
 
130
131
  const MyProfile = () => {
131
- const { showDashboard } = useGrowthRailContext();
132
+ const { showReferralDashboard } = useGrowthRail();
132
133
 
133
134
  return (
134
- <Button title="Refer & Earn" onPress={() => showDashboard()} />
135
+ <Button title="Refer & Earn" onPress={() => showReferralDashboard()} />
135
136
  );
136
137
  };
137
138
  ```
@@ -140,10 +141,11 @@ const MyProfile = () => {
140
141
  If you need to build a custom UI, you can generate the referral link directly:
141
142
 
142
143
  ```tsx
143
- import { GrowthRail } from '@growth-rail/react-native';
144
+ import { useGrowthRail } from '@growth-rail/react-native';
144
145
 
145
146
  const getLink = async () => {
146
- const { referralLink } = await GrowthRail.createReferralLink();
147
+ const { getReferralLink } = useGrowthRail();
148
+ const referralLink = await getReferralLink();
147
149
  console.log('Share this link:', referralLink);
148
150
  };
149
151
  ```
@@ -153,16 +155,22 @@ const getLink = async () => {
153
155
  ### `GrowthRailProvider` Props
154
156
  | Prop | Type | Description |
155
157
  | :--- | :--- | :--- |
156
- | `apiKey` | `string` | Your GrowthRail API Key. |
158
+ | `projectSecretKey` | `string` | Your GrowthRail Project Secret Key. |
157
159
  | `userId` | `string` | (Optional) The current user's unique ID. |
158
160
  | `apiUrl` | `string` | (Optional) Custom API endpoint. |
159
161
 
160
- ### `useGrowthRailContext()`
161
- Provides access to SDK methods:
162
- - `showDashboard()`: Opens the referral dashboard.
163
- - `hideDashboard()`: Closes the referral dashboard.
164
- - `showFloatingButton()`: Shows/hides the floating trigger.
162
+ ### `useGrowthRail()`
163
+ Provides access to SDK methods and state:
164
+ - `initAppUser(userId)`: Initializes a user in the GrowthRail system.
165
+ - `trackRewardEvent(eventName)`: Tracks a reward-eligible event.
166
+ - `showReferralDashboard(options)`: Opens the referral dashboard modal.
167
+ - `hideReferralDashboard()`: Closes the referral dashboard modal.
168
+ - `getReferralLink()`: Returns the user's referral link.
169
+ - `getReferralTrackingId()`: Returns the current tracking ID.
165
170
  - `isInitialized`: Boolean indicating if the SDK is ready.
171
+ - `isUserReady`: Boolean indicating if the user is initialized.
172
+ - `isLoading`: Boolean indicating if an operation is in progress.
173
+ - `error`: The last error that occurred.
166
174
 
167
175
  ## License
168
176
  MIT
package/dist/index.d.mts CHANGED
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
 
3
3
  type GrowthRailOptions = {
4
- apiKey: string;
4
+ projectSecretKey: string;
5
5
  cookieDomain?: string;
6
6
  autoPageTrack?: boolean;
7
7
  };
@@ -14,19 +14,10 @@ type AppUserType = {
14
14
  referralLink: string;
15
15
  referrerExperience: ReferrerExperience;
16
16
  };
17
- type AppUserTypeWithId = AppUserType & {
18
- id: string;
19
- };
20
17
  type ReferralLink = {
21
18
  referralCode: string;
22
19
  referralLink: string;
23
20
  };
24
- type EventPayload = {
25
- event: string;
26
- userId?: string;
27
- properties?: Record<string, any>;
28
- timestamp: string;
29
- };
30
21
  type TrackReferralResponse = {
31
22
  referralTrackingId: string;
32
23
  promotionalText: string;
@@ -60,112 +51,113 @@ interface NewUserExperience {
60
51
  themeColor: string;
61
52
  };
62
53
  }
63
- interface DeviceFingerprint {
64
- os: string;
65
- osVersion: string;
66
- deviceModel?: string;
67
- deviceBrand?: string;
68
- screenWidth?: number;
69
- screenHeight?: number;
70
- timezoneOffsetInMinutes: string;
71
- locale?: string;
72
- language?: string;
73
- platform?: string;
74
- pixelRatio?: number;
75
- }
76
-
77
- declare class GrowthRail {
78
- private static api;
79
- private static options;
80
- private static currentUser;
81
- private static referralObject;
82
- private static initialized;
83
- private static userReadyPromise;
84
- private static userReadyResolver;
85
- private constructor();
86
- static init(options: GrowthRailOptions): Promise<void>;
87
- private static handleInitialUrl;
88
- private static setupLinkListeners;
89
- private static checkDeferredReferral;
90
- private static checkInstallReferrer;
91
- static getDeviceFingerprint(): DeviceFingerprint;
92
- private static checkDeferredDeepLinkFingerprint;
93
- private static handleDeepLink;
94
- private static ensureInitialized;
95
- static initAppUser(clientProvidedId: string): Promise<AppUserType>;
96
- static trackReferral(referralCode: string, rewardEventName?: string): Promise<TrackReferralResponse>;
97
- static trackRewardEvent(eventName?: string): Promise<void>;
98
- static createReferralLink(rewardEventName?: string): Promise<ReferralLink>;
99
- static isInitialized(): boolean;
100
- static getReferralLink(): string;
101
- static getReferralCode(): string | undefined;
102
- static getUserId(): string | undefined;
103
- static isUserReady(): boolean;
104
- static getReferrerExperience(): ReferrerExperience | undefined;
105
- static ensureUserReady(): Promise<AppUserTypeWithId>;
106
- static getNewUserExperience(): Promise<NewUserExperience>;
107
- }
108
-
109
- declare class StorageManager {
110
- static setTrackedReferral(id: string): Promise<void>;
111
- static getTrackedReferral(): Promise<string | null>;
112
- static isFirstLaunch(): Promise<boolean>;
113
- }
114
54
 
115
- declare class APIClient {
116
- private baseUrl;
117
- private apiKey;
118
- constructor(options: GrowthRailOptions);
119
- private request;
120
- getNewUserExperience(): Promise<NewUserExperience>;
121
- initAppUser(clientProvidedId: string): Promise<AppUserType>;
122
- createReferralLink(referrerId: string, rewardEventName?: string): Promise<{
123
- referralCode: string;
124
- referralLink: string;
125
- }>;
126
- trackReferral(referralCode: string, rewardEventName?: string): Promise<TrackReferralResponse>;
127
- trackRewardEvent(refereeId: string, referralTrackingId: string, eventName?: string): Promise<any>;
128
- checkDeferredDeepLink(fingerprint: DeviceFingerprint): Promise<TrackReferralResponse>;
129
- }
130
-
131
- interface GrowthRailContextType {
132
- isInitialized: boolean;
133
- isUserReady: boolean;
134
- showDashboard: (options?: Partial<ReferrerModalOptions>) => void;
135
- hideDashboard: () => void;
136
- showFloatingButton: (options?: Partial<ReferrerTriggerButton>) => void;
137
- hideFloatingButton: () => void;
138
- }
55
+ /**
56
+ * Props for the GrowthRailProvider component in React Native.
57
+ */
139
58
  interface GrowthRailProviderProps extends GrowthRailOptions {
59
+ /** The unique ID for the current application user. */
140
60
  userId?: string;
61
+ /** Your application components. */
141
62
  children: React.ReactNode;
142
63
  }
64
+ /**
65
+ * Root provider component for GrowthRail in React Native applications.
66
+ * This component initializes the SDK, handles deep links, and manages user state.
67
+ *
68
+ * Wrap your root app component with this provider.
69
+ *
70
+ * @example
71
+ * <GrowthRailProvider projectSecretKey="your-api-key" userId="user-123">
72
+ * <App />
73
+ * </GrowthRailProvider>
74
+ */
143
75
  declare const GrowthRailProvider: React.FC<GrowthRailProviderProps>;
144
- declare const useGrowthRailContext: () => GrowthRailContextType;
145
76
 
77
+ /**
78
+ * The return type of the useGrowthRail hook in React Native.
79
+ */
80
+ interface UseGrowthRailReturn {
81
+ /**
82
+ * Initializes a user in the GrowthRail system.
83
+ * @param userId - Unique identifier for the user.
84
+ */
85
+ initAppUser: (userId: string) => Promise<AppUserType>;
86
+ /**
87
+ * Tracks a reward-eligible event for the current user.
88
+ * @param eventName - Optional name of the event.
89
+ */
90
+ trackRewardEvent: (eventName?: string) => Promise<void>;
91
+ /**
92
+ * Manually triggers the referral dashboard modal.
93
+ * @param options - Customization options for the modal.
94
+ */
95
+ showReferralDashboard: (options?: Partial<ReferrerModalOptions>) => void;
96
+ /** Hides the referral dashboard. */
97
+ hideReferralDashboard: () => void;
98
+ /** Gets the current referral tracking ID if one is stored. */
99
+ getReferralTrackingId: () => Promise<string | null>;
100
+ /** Gets the user's referral link. */
101
+ getReferralLink: () => Promise<string | undefined>;
102
+ /** Whether an asynchronous operation (like init or track) is in progress. */
103
+ isLoading: boolean;
104
+ /** Whether the SDK is initialized. */
105
+ isInitialized: boolean;
106
+ /** Whether the user is fully initialized and ready. */
107
+ isUserReady: boolean;
108
+ /** The last error that occurred during an operation. */
109
+ error: Error | null;
110
+ }
111
+ /**
112
+ * A hook that provides access to GrowthRail SDK methods and state in React Native.
113
+ *
114
+ * @returns An object containing methods to manage referrals and track state.
115
+ *
116
+ * @example
117
+ * const { showReferralDashboard, trackRewardEvent } = useGrowthRail();
118
+ */
119
+ declare const useGrowthRail: () => UseGrowthRailReturn;
120
+
121
+ /**
122
+ * Props for the ReferralDashboard component in React Native.
123
+ */
146
124
  interface ReferralDashboardProps {
125
+ /** Whether the dashboard modal is currently visible. */
147
126
  visible: boolean;
127
+ /** Customization options for the dashboard's appearance. */
148
128
  options?: Partial<ReferrerModalOptions>;
129
+ /** Callback fired when the dashboard is closed. */
149
130
  onClose: () => void;
150
131
  }
132
+ /**
133
+ * A modal-based referral dashboard for React Native.
134
+ * Usually managed by the `GrowthRailProvider`, but can be used standalone.
135
+ *
136
+ * @example
137
+ * <ReferralDashboard
138
+ * visible={showDashboard}
139
+ * onClose={() => setShowDashboard(false)}
140
+ * />
141
+ */
151
142
  declare const ReferralDashboard: React.FC<ReferralDashboardProps>;
152
143
 
144
+ /**
145
+ * Props for the TriggerButton component in React Native.
146
+ */
153
147
  interface TriggerButtonProps {
148
+ /** Callback fired when the button is pressed. */
154
149
  onPress: () => void;
150
+ /** Customization options for the button's appearance and behavior. */
155
151
  options?: Partial<ReferrerExperience>;
156
152
  }
153
+ /**
154
+ * A floating or edge-attached trigger button for the referral dashboard.
155
+ *
156
+ * @example
157
+ * <TriggerButton
158
+ * onPress={() => setShowDashboard(true)}
159
+ * />
160
+ */
157
161
  declare const TriggerButton: React.FC<TriggerButtonProps>;
158
162
 
159
- interface UseGrowthRailReturn {
160
- initUser: (userId: string) => Promise<AppUserType>;
161
- trackReward: (eventName?: string) => Promise<void>;
162
- showReferralDashboard: (options?: Partial<ReferrerModalOptions>) => void;
163
- showFloatingButton: (options: Partial<ReferrerTriggerButton>) => void;
164
- hideFloatingButton: () => void;
165
- isLoading: boolean;
166
- isInitialized: boolean;
167
- error: Error | null;
168
- }
169
- declare const useGrowthRail: () => UseGrowthRailReturn;
170
-
171
- export { APIClient, type AppUserType, type AppUserTypeWithId, type DeviceFingerprint, type EventPayload, GrowthRail, type GrowthRailOptions, GrowthRailProvider, type NewUserExperience, ReferralDashboard, type ReferralLink, type ReferrerExperience, type ReferrerModalOptions, type ReferrerTriggerButton, StorageManager, type TrackReferralResponse, TriggerButton, type TriggerButtonPosition, type UseGrowthRailReturn, useGrowthRail, useGrowthRailContext };
163
+ export { type AppUserType, type GrowthRailOptions, GrowthRailProvider, type NewUserExperience, ReferralDashboard, type ReferralLink, type ReferrerExperience, type ReferrerModalOptions, type ReferrerTriggerButton, type TrackReferralResponse, TriggerButton, type TriggerButtonPosition, type UseGrowthRailReturn, useGrowthRail };
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
 
3
3
  type GrowthRailOptions = {
4
- apiKey: string;
4
+ projectSecretKey: string;
5
5
  cookieDomain?: string;
6
6
  autoPageTrack?: boolean;
7
7
  };
@@ -14,19 +14,10 @@ type AppUserType = {
14
14
  referralLink: string;
15
15
  referrerExperience: ReferrerExperience;
16
16
  };
17
- type AppUserTypeWithId = AppUserType & {
18
- id: string;
19
- };
20
17
  type ReferralLink = {
21
18
  referralCode: string;
22
19
  referralLink: string;
23
20
  };
24
- type EventPayload = {
25
- event: string;
26
- userId?: string;
27
- properties?: Record<string, any>;
28
- timestamp: string;
29
- };
30
21
  type TrackReferralResponse = {
31
22
  referralTrackingId: string;
32
23
  promotionalText: string;
@@ -60,112 +51,113 @@ interface NewUserExperience {
60
51
  themeColor: string;
61
52
  };
62
53
  }
63
- interface DeviceFingerprint {
64
- os: string;
65
- osVersion: string;
66
- deviceModel?: string;
67
- deviceBrand?: string;
68
- screenWidth?: number;
69
- screenHeight?: number;
70
- timezoneOffsetInMinutes: string;
71
- locale?: string;
72
- language?: string;
73
- platform?: string;
74
- pixelRatio?: number;
75
- }
76
-
77
- declare class GrowthRail {
78
- private static api;
79
- private static options;
80
- private static currentUser;
81
- private static referralObject;
82
- private static initialized;
83
- private static userReadyPromise;
84
- private static userReadyResolver;
85
- private constructor();
86
- static init(options: GrowthRailOptions): Promise<void>;
87
- private static handleInitialUrl;
88
- private static setupLinkListeners;
89
- private static checkDeferredReferral;
90
- private static checkInstallReferrer;
91
- static getDeviceFingerprint(): DeviceFingerprint;
92
- private static checkDeferredDeepLinkFingerprint;
93
- private static handleDeepLink;
94
- private static ensureInitialized;
95
- static initAppUser(clientProvidedId: string): Promise<AppUserType>;
96
- static trackReferral(referralCode: string, rewardEventName?: string): Promise<TrackReferralResponse>;
97
- static trackRewardEvent(eventName?: string): Promise<void>;
98
- static createReferralLink(rewardEventName?: string): Promise<ReferralLink>;
99
- static isInitialized(): boolean;
100
- static getReferralLink(): string;
101
- static getReferralCode(): string | undefined;
102
- static getUserId(): string | undefined;
103
- static isUserReady(): boolean;
104
- static getReferrerExperience(): ReferrerExperience | undefined;
105
- static ensureUserReady(): Promise<AppUserTypeWithId>;
106
- static getNewUserExperience(): Promise<NewUserExperience>;
107
- }
108
-
109
- declare class StorageManager {
110
- static setTrackedReferral(id: string): Promise<void>;
111
- static getTrackedReferral(): Promise<string | null>;
112
- static isFirstLaunch(): Promise<boolean>;
113
- }
114
54
 
115
- declare class APIClient {
116
- private baseUrl;
117
- private apiKey;
118
- constructor(options: GrowthRailOptions);
119
- private request;
120
- getNewUserExperience(): Promise<NewUserExperience>;
121
- initAppUser(clientProvidedId: string): Promise<AppUserType>;
122
- createReferralLink(referrerId: string, rewardEventName?: string): Promise<{
123
- referralCode: string;
124
- referralLink: string;
125
- }>;
126
- trackReferral(referralCode: string, rewardEventName?: string): Promise<TrackReferralResponse>;
127
- trackRewardEvent(refereeId: string, referralTrackingId: string, eventName?: string): Promise<any>;
128
- checkDeferredDeepLink(fingerprint: DeviceFingerprint): Promise<TrackReferralResponse>;
129
- }
130
-
131
- interface GrowthRailContextType {
132
- isInitialized: boolean;
133
- isUserReady: boolean;
134
- showDashboard: (options?: Partial<ReferrerModalOptions>) => void;
135
- hideDashboard: () => void;
136
- showFloatingButton: (options?: Partial<ReferrerTriggerButton>) => void;
137
- hideFloatingButton: () => void;
138
- }
55
+ /**
56
+ * Props for the GrowthRailProvider component in React Native.
57
+ */
139
58
  interface GrowthRailProviderProps extends GrowthRailOptions {
59
+ /** The unique ID for the current application user. */
140
60
  userId?: string;
61
+ /** Your application components. */
141
62
  children: React.ReactNode;
142
63
  }
64
+ /**
65
+ * Root provider component for GrowthRail in React Native applications.
66
+ * This component initializes the SDK, handles deep links, and manages user state.
67
+ *
68
+ * Wrap your root app component with this provider.
69
+ *
70
+ * @example
71
+ * <GrowthRailProvider projectSecretKey="your-api-key" userId="user-123">
72
+ * <App />
73
+ * </GrowthRailProvider>
74
+ */
143
75
  declare const GrowthRailProvider: React.FC<GrowthRailProviderProps>;
144
- declare const useGrowthRailContext: () => GrowthRailContextType;
145
76
 
77
+ /**
78
+ * The return type of the useGrowthRail hook in React Native.
79
+ */
80
+ interface UseGrowthRailReturn {
81
+ /**
82
+ * Initializes a user in the GrowthRail system.
83
+ * @param userId - Unique identifier for the user.
84
+ */
85
+ initAppUser: (userId: string) => Promise<AppUserType>;
86
+ /**
87
+ * Tracks a reward-eligible event for the current user.
88
+ * @param eventName - Optional name of the event.
89
+ */
90
+ trackRewardEvent: (eventName?: string) => Promise<void>;
91
+ /**
92
+ * Manually triggers the referral dashboard modal.
93
+ * @param options - Customization options for the modal.
94
+ */
95
+ showReferralDashboard: (options?: Partial<ReferrerModalOptions>) => void;
96
+ /** Hides the referral dashboard. */
97
+ hideReferralDashboard: () => void;
98
+ /** Gets the current referral tracking ID if one is stored. */
99
+ getReferralTrackingId: () => Promise<string | null>;
100
+ /** Gets the user's referral link. */
101
+ getReferralLink: () => Promise<string | undefined>;
102
+ /** Whether an asynchronous operation (like init or track) is in progress. */
103
+ isLoading: boolean;
104
+ /** Whether the SDK is initialized. */
105
+ isInitialized: boolean;
106
+ /** Whether the user is fully initialized and ready. */
107
+ isUserReady: boolean;
108
+ /** The last error that occurred during an operation. */
109
+ error: Error | null;
110
+ }
111
+ /**
112
+ * A hook that provides access to GrowthRail SDK methods and state in React Native.
113
+ *
114
+ * @returns An object containing methods to manage referrals and track state.
115
+ *
116
+ * @example
117
+ * const { showReferralDashboard, trackRewardEvent } = useGrowthRail();
118
+ */
119
+ declare const useGrowthRail: () => UseGrowthRailReturn;
120
+
121
+ /**
122
+ * Props for the ReferralDashboard component in React Native.
123
+ */
146
124
  interface ReferralDashboardProps {
125
+ /** Whether the dashboard modal is currently visible. */
147
126
  visible: boolean;
127
+ /** Customization options for the dashboard's appearance. */
148
128
  options?: Partial<ReferrerModalOptions>;
129
+ /** Callback fired when the dashboard is closed. */
149
130
  onClose: () => void;
150
131
  }
132
+ /**
133
+ * A modal-based referral dashboard for React Native.
134
+ * Usually managed by the `GrowthRailProvider`, but can be used standalone.
135
+ *
136
+ * @example
137
+ * <ReferralDashboard
138
+ * visible={showDashboard}
139
+ * onClose={() => setShowDashboard(false)}
140
+ * />
141
+ */
151
142
  declare const ReferralDashboard: React.FC<ReferralDashboardProps>;
152
143
 
144
+ /**
145
+ * Props for the TriggerButton component in React Native.
146
+ */
153
147
  interface TriggerButtonProps {
148
+ /** Callback fired when the button is pressed. */
154
149
  onPress: () => void;
150
+ /** Customization options for the button's appearance and behavior. */
155
151
  options?: Partial<ReferrerExperience>;
156
152
  }
153
+ /**
154
+ * A floating or edge-attached trigger button for the referral dashboard.
155
+ *
156
+ * @example
157
+ * <TriggerButton
158
+ * onPress={() => setShowDashboard(true)}
159
+ * />
160
+ */
157
161
  declare const TriggerButton: React.FC<TriggerButtonProps>;
158
162
 
159
- interface UseGrowthRailReturn {
160
- initUser: (userId: string) => Promise<AppUserType>;
161
- trackReward: (eventName?: string) => Promise<void>;
162
- showReferralDashboard: (options?: Partial<ReferrerModalOptions>) => void;
163
- showFloatingButton: (options: Partial<ReferrerTriggerButton>) => void;
164
- hideFloatingButton: () => void;
165
- isLoading: boolean;
166
- isInitialized: boolean;
167
- error: Error | null;
168
- }
169
- declare const useGrowthRail: () => UseGrowthRailReturn;
170
-
171
- export { APIClient, type AppUserType, type AppUserTypeWithId, type DeviceFingerprint, type EventPayload, GrowthRail, type GrowthRailOptions, GrowthRailProvider, type NewUserExperience, ReferralDashboard, type ReferralLink, type ReferrerExperience, type ReferrerModalOptions, type ReferrerTriggerButton, StorageManager, type TrackReferralResponse, TriggerButton, type TriggerButtonPosition, type UseGrowthRailReturn, useGrowthRail, useGrowthRailContext };
163
+ export { type AppUserType, type GrowthRailOptions, GrowthRailProvider, type NewUserExperience, ReferralDashboard, type ReferralLink, type ReferrerExperience, type ReferrerModalOptions, type ReferrerTriggerButton, type TrackReferralResponse, TriggerButton, type TriggerButtonPosition, type UseGrowthRailReturn, useGrowthRail };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";var pe=Object.create;var $=Object.defineProperty;var ue=Object.getOwnPropertyDescriptor;var ge=Object.getOwnPropertyNames;var he=Object.getPrototypeOf,me=Object.prototype.hasOwnProperty;var we=(a,e,r)=>e in a?$(a,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):a[e]=r;var ye=(a,e)=>{for(var r in e)$(a,r,{get:e[r],enumerable:!0})},ne=(a,e,r,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let l of ge(e))!me.call(a,l)&&l!==r&&$(a,l,{get:()=>e[l],enumerable:!(o=ue(e,l))||o.enumerable});return a};var N=(a,e,r)=>(r=a!=null?pe(he(a)):{},ne(e||!a||!a.__esModule?$(r,"default",{value:a,enumerable:!0}):r,a)),be=a=>ne($({},"__esModule",{value:!0}),a);var P=(a,e,r)=>we(a,typeof e!="symbol"?e+"":e,r);var xe={};ye(xe,{APIClient:()=>j,GrowthRail:()=>g,GrowthRailProvider:()=>ke,ReferralDashboard:()=>re,StorageManager:()=>B,TriggerButton:()=>ie,useGrowthRail:()=>ve,useGrowthRailContext:()=>oe});module.exports=be(xe);var b=require("react-native"),ae=N(require("react-native-play-install-referrer"));var j=class{constructor(e){P(this,"baseUrl");P(this,"apiKey");let r=typeof process<"u"&&process.env?.ENV_BASE_URL;this.baseUrl=r||"https://api.growthrail.dev",this.apiKey=e.apiKey}async request(e,r,o){let l={"Content-Type":"application/json","X-GrowthRail-ProjectSecret":this.apiKey,Origin:this.baseUrl};try{let c=await fetch(`${this.baseUrl}${e}`,{method:r,headers:l,body:o?JSON.stringify(o):void 0});if(!c.ok){let p="";try{p=await c.text()}catch{}throw new Error(`GrowthRail API Error ${c.status} (${this.baseUrl}${e}): ${c.statusText} - ${p}`)}return c.json()}catch(c){throw console.error("GrowthRail SDK Error:",c),c}}async getNewUserExperience(){return this.request("/api/v1/sdk/new-user-experience","POST")}async initAppUser(e){return this.request("/api/v1/sdk/init-app-user","POST",{clientProvidedId:e})}async createReferralLink(e,r){return this.request("/api/v1/sdk/create-referral-link","POST",{referrerId:e,rewardEventName:r})}async trackReferral(e,r){return this.request("/api/v1/sdk/track-referral","POST",{referralCode:e,rewardEventName:r})}async trackRewardEvent(e,r,o){return this.request("/api/v1/sdk/track-reward-event","POST",{refereeId:e,referralTrackingId:r,eventName:o})}async checkDeferredDeepLink(e){return this.request("/api/v1/sdk/match-link","POST",{fingerprint:e})}};var H=N(require("@react-native-async-storage/async-storage")),Y={TRACKED_REFERRAL:"growth-rail-tracked-referral",IS_FIRST_LAUNCH:"growth-rail-is-first-launch"},B=class{static async setTrackedReferral(e){await H.default.setItem(Y.TRACKED_REFERRAL,e)}static async getTrackedReferral(){return await H.default.getItem(Y.TRACKED_REFERRAL)}static async isFirstLaunch(){return await H.default.getItem(Y.IS_FIRST_LAUNCH)===null?(await H.default.setItem(Y.IS_FIRST_LAUNCH,"false"),!0):!1}};var i=class i{constructor(){}static async init(e){i.initialized||(i.options=e,i.api=new j(e),i.initialized=!0,await i.handleInitialUrl(),await i.setupLinkListeners(),await i.checkDeferredReferral())}static async handleInitialUrl(){try{let e=await b.Linking.getInitialURL();e&&await i.handleDeepLink(e)}catch(e){console.error("GrowthRail: Error getting initial URL",e)}}static setupLinkListeners(){b.Linking.addEventListener("url",({url:e})=>{i.handleDeepLink(e)})}static async checkDeferredReferral(){await B.isFirstLaunch()&&(b.Platform.OS==="android"?await i.checkInstallReferrer():await i.checkDeferredDeepLinkFingerprint())}static checkInstallReferrer(){return new Promise(e=>{ae.default.getInstallReferrerInfo(async(r,o)=>{if(!o&&r&&r.installReferrer)try{let c=decodeURIComponent(r.installReferrer).match(/[?&]referralCode=([^&]+)/);if(c){let{referralTrackingId:p}=await i.trackReferral(c[1]);await B.setTrackedReferral(p),console.log("GrowthRail: Tracked referral via Install Referrer")}}catch(l){console.warn("GrowthRail: Failed to process install referrer",l)}else await i.checkDeferredDeepLinkFingerprint();e()})})}static getDeviceFingerprint(){let{width:e,height:r}=b.Dimensions.get("window"),o=Intl.DateTimeFormat().resolvedOptions().locale,l=b.PixelRatio.get(),c,p;if(b.Platform.OS==="android"){let m=b.Platform.constants;c=m.Model,p=m.Brand||m.Manufacturer}return{os:b.Platform.OS,platform:b.Platform.OS,osVersion:String(b.Platform.Version),screenWidth:e,screenHeight:r,timezoneOffsetInMinutes:String(new Date().getTimezoneOffset()),locale:o,language:o,deviceModel:c,deviceBrand:p,pixelRatio:l}}static async checkDeferredDeepLinkFingerprint(){try{let e=i.getDeviceFingerprint();console.log("GrowthRail executing deferred fingerprint check to API...");let{referralTrackingId:r}=await i.api.checkDeferredDeepLink(e);r&&(console.log("GrowthRail: Found deferred referral via fingerprinting",r),await B.setTrackedReferral(r))}catch(e){console.warn("GrowthRail: Fingerprint check failed",e)}}static async handleDeepLink(e){try{let r=new URL(e),o=r.searchParams.get("referralCode"),l=r.searchParams.get("rewardEventName");o&&(console.log("GrowthRail: Tracking referral from deep link",o),await i.trackReferral(o,l||void 0))}catch{let o=e.match(/[?&]referralCode=([^&]+)/);o&&await i.trackReferral(o[1])}}static ensureInitialized(){if(!i.initialized)throw new Error("GrowthRail.init() must be called before using the SDK")}static async initAppUser(e){i.ensureInitialized();let r=await i.api.initAppUser(e);return i.currentUser={...r,id:e},i.userReadyResolver&&i.userReadyResolver(i.currentUser),r}static async trackReferral(e,r){i.ensureInitialized();let o=await i.api.trackReferral(e,r);return await B.setTrackedReferral(o.referralTrackingId),o}static async trackRewardEvent(e){i.ensureInitialized();let r=i.currentUser?.id;if(!r)throw new Error("GrowthRail: User must be initialized before tracking a reward event.");let o=await B.getTrackedReferral();if(!o){console.warn("GrowthRail: No referral tracking ID found. Reward event not attributed.");return}return i.api.trackRewardEvent(r,o,e)}static async createReferralLink(e){i.ensureInitialized();let r=i.currentUser?.id;if(!r)throw new Error("GrowthRail: User must be initialized before creating a referral link.");if(i.referralObject)return i.referralObject;let o=await i.api.createReferralLink(r,e);return i.referralObject=o,o}static isInitialized(){return i.initialized}static getReferralLink(){if(!i.referralObject?.referralLink)throw new Error("GrowthRail: Referral Link not loaded or user not initialized");return i.referralObject.referralLink}static getReferralCode(){return i.referralObject?.referralCode||i.currentUser?.referralCode}static getUserId(){return i.currentUser?.id}static isUserReady(){return i.currentUser!==null}static getReferrerExperience(){return i.currentUser?.referrerExperience}static ensureUserReady(){return i.currentUser?Promise.resolve(i.currentUser):(i.userReadyPromise||(i.userReadyPromise=new Promise(e=>{i.userReadyResolver=e})),i.userReadyPromise)}static async getNewUserExperience(){return i.ensureInitialized(),i.api.getNewUserExperience()}};P(i,"api"),P(i,"options"),P(i,"currentUser",null),P(i,"referralObject",null),P(i,"initialized",!1),P(i,"userReadyPromise",null),P(i,"userReadyResolver",null);var g=i;var f=N(require("react"));var n=N(require("react")),t=require("react-native");var{width:se,height:te}=t.Dimensions.get("window"),re=({visible:a,options:e,onClose:r})=>{let[o,l]=(0,n.useState)(null),[c,p]=(0,n.useState)(!1),[m,T]=(0,n.useState)(!1),u=(0,n.useRef)(new t.Animated.Value(0)).current,d=(0,n.useRef)(new t.Animated.Value(0)).current,y=e?.title||"Invite Friends & Earn",R=e?.theme?.primaryColor||"#2563eb",G=e?.theme?.backgroundColor||"#ffffff",D=e?.theme?.tintColor||"#000000",X=e?.theme?.tintAlpha??.5,C=(e?.componentType||"modal")==="drawer",S=e?.position||"bottom-right",Q="#111827",M="#6b7280";(0,n.useEffect)(()=>{a?(o||Z(),t.Animated.parallel([t.Animated.timing(d,{toValue:1,duration:300,useNativeDriver:!0}),t.Animated.spring(u,{toValue:1,useNativeDriver:!0,tension:50,friction:8})]).start()):(u.setValue(0),d.setValue(0))},[a]);let L=()=>{t.Animated.parallel([t.Animated.timing(d,{toValue:0,duration:250,useNativeDriver:!0}),t.Animated.timing(u,{toValue:0,duration:250,useNativeDriver:!0})]).start(()=>{r()})},Z=async()=>{p(!0);try{if(g.isUserReady()){let A=await g.createReferralLink();l(A.referralLink)}}catch(A){console.error("GrowthRail: Failed to load referral link",A)}finally{p(!1)}},_=()=>{o&&(t.Clipboard.setString(o),T(!0),setTimeout(()=>T(!1),2e3))},I=A=>{if(!o)return;let O="",F=encodeURIComponent(o),ee=encodeURIComponent("Check this out!");switch(A){case"twitter":O=`https://twitter.com/intent/tweet?url=${F}&text=${ee}`;break;case"facebook":O=`https://www.facebook.com/sharer/sharer.php?u=${F}`;break;case"linkedin":O=`https://www.linkedin.com/sharing/share-offsite/?url=${F}`;break;case"whatsapp":O=`whatsapp://send?text=${ee}%20${F}`;break;case"email":O=`mailto:?subject=Check this out&body=${ee}%20${F}`;break}O&&t.Linking.openURL(O).catch(()=>{})},k=()=>{if(D.startsWith("#")){let A=parseInt(D.slice(1,3),16),O=parseInt(D.slice(3,5),16),F=parseInt(D.slice(5,7),16);return`rgba(${A}, ${O}, ${F}, ${X})`}return`rgba(0, 0, 0, ${X})`},W=[];C?S.includes("right")?W=[{translateX:u.interpolate({inputRange:[0,1],outputRange:[se,0]})}]:S.includes("left")?W=[{translateX:u.interpolate({inputRange:[0,1],outputRange:[-se,0]})}]:W=[{translateY:u.interpolate({inputRange:[0,1],outputRange:[te,0]})}]:W=[{scale:u.interpolate({inputRange:[0,1],outputRange:[.9,1]})},{translateY:u.interpolate({inputRange:[0,1],outputRange:[20,0]})}];let de=S.includes("top"),V=S.includes("right"),z=S.includes("left"),fe=C?{position:"absolute",...de?{top:100}:{bottom:100},...V?{right:0}:z?{left:0}:{left:0,right:0},width:V||z?"85%":"100%",maxHeight:V||z?te-200:"80%"}:{};return n.default.createElement(t.Modal,{visible:a,transparent:!0,animationType:"none",onRequestClose:L},n.default.createElement(t.View,{style:s.fullScreen},n.default.createElement(t.Animated.View,{style:[s.overlay,{backgroundColor:k(),opacity:d}]},n.default.createElement(t.TouchableOpacity,{style:s.fullScreen,activeOpacity:1,onPress:L})),n.default.createElement(t.Animated.View,{style:[C?fe:s.centeredModalContainer,{backgroundColor:G,transform:W},C&&V&&{borderTopLeftRadius:24,borderBottomLeftRadius:24},C&&z&&{borderTopRightRadius:24,borderBottomRightRadius:24},C&&!V&&!z&&S.includes("bottom")&&{borderTopLeftRadius:24,borderTopRightRadius:24},C&&!V&&!z&&S.includes("top")&&{borderBottomLeftRadius:24,borderBottomRightRadius:24},!C&&{borderRadius:24,opacity:u}]},n.default.createElement(t.View,{style:s.contentWrapper},C&&!V&&!z&&S.includes("bottom")&&n.default.createElement(t.View,{style:s.drawerHandle}),n.default.createElement(t.TouchableOpacity,{style:s.closeBtn,onPress:L},n.default.createElement(t.Text,{style:s.closeIcon},"\u2715")),n.default.createElement(t.ScrollView,{contentContainerStyle:s.scrollContent,showsVerticalScrollIndicator:!1},n.default.createElement(t.View,{style:s.header},n.default.createElement(t.Text,{style:s.iconLg},"\u{1F381}"),n.default.createElement(t.Text,{style:[s.title,{color:Q}]},y),n.default.createElement(t.Text,{style:[s.subtitle,{color:M}]},e?.description||"Share your unique link and earn rewards for every friend who signs up.")),g.isUserReady()?c?n.default.createElement(t.ActivityIndicator,{size:"large",color:R,style:s.loader}):n.default.createElement(t.View,{style:s.mainContent},n.default.createElement(t.Text,{style:s.label},"YOUR UNIQUE LINK"),n.default.createElement(t.View,{style:s.inputGroup},n.default.createElement(t.Text,{numberOfLines:1,style:s.input},o||"Initializing..."),n.default.createElement(t.TouchableOpacity,{style:[s.copyBtn,{backgroundColor:m?"#10b981":R}],onPress:_},n.default.createElement(t.Text,{style:s.copyBtnText},m?"Copied!":"Copy"))),n.default.createElement(t.View,{style:s.shareLabelContainer},n.default.createElement(t.View,{style:s.divider}),n.default.createElement(t.Text,{style:s.shareLabel},"Share via"),n.default.createElement(t.View,{style:s.divider})),n.default.createElement(t.View,{style:s.socialContainer},n.default.createElement(K,{platform:"twitter",color:"#000000",onPress:()=>I("twitter"),icon:"\u{1D54F}"}),n.default.createElement(K,{platform:"facebook",color:"#1877F2",onPress:()=>I("facebook"),icon:"f"}),n.default.createElement(K,{platform:"linkedin",color:"#0A66C2",onPress:()=>I("linkedin"),icon:"in"}),n.default.createElement(K,{platform:"whatsapp",color:"#25D366",onPress:()=>I("whatsapp"),icon:"W"}),n.default.createElement(K,{platform:"email",color:"#888888",onPress:()=>I("email"),icon:"\u2709"}))):n.default.createElement(t.View,{style:s.loadingBox},n.default.createElement(t.Text,{style:{color:M,textAlign:"center"}},"Please log in to view your referral dashboard.")),n.default.createElement(t.View,{style:s.footer},n.default.createElement(t.Text,{style:s.poweredBy},"Powered by ",n.default.createElement(t.Text,{style:s.brand,onPress:()=>t.Linking.openURL("https://growthrail.com")},"Growth Rail"))))))))},K=({color:a,onPress:e,icon:r})=>n.default.createElement(t.TouchableOpacity,{style:[s.socialBtn,{borderColor:"#e5e7eb"}],onPress:e},n.default.createElement(t.Text,{style:[s.socialIcon,{color:a}]},r)),s=t.StyleSheet.create({fullScreen:{flex:1},overlay:{...t.StyleSheet.absoluteFillObject},centeredModalContainer:{width:"90%",maxWidth:400,alignSelf:"center",marginTop:te*.15,overflow:"hidden",shadowColor:"#000",shadowOffset:{width:0,height:20},shadowOpacity:.25,shadowRadius:30,elevation:20},contentWrapper:{paddingTop:t.Platform.OS==="ios"?20:0},drawerHandle:{width:40,height:4,backgroundColor:"#e5e7eb",borderRadius:2,alignSelf:"center",marginTop:12},scrollContent:{padding:32,alignItems:"center"},closeBtn:{position:"absolute",top:20,right:20,zIndex:10,width:32,height:32,borderRadius:16,backgroundColor:"#f3f4f6",justifyContent:"center",alignItems:"center"},closeIcon:{fontSize:14,color:"#9ca3af"},header:{alignItems:"center",marginBottom:28},iconLg:{fontSize:32,marginBottom:12},title:{fontSize:22,fontWeight:"700",letterSpacing:-.5,marginBottom:8,textAlign:"center"},subtitle:{fontSize:14,lineHeight:20,textAlign:"center",paddingHorizontal:10},loadingBox:{padding:16,backgroundColor:"#f9fafb",borderRadius:12,width:"100%",alignItems:"center"},loader:{marginVertical:20},mainContent:{width:"100%"},label:{fontSize:12,fontWeight:"600",color:"#6b7280",marginBottom:8,letterSpacing:.5},inputGroup:{flexDirection:"row",alignItems:"center",backgroundColor:"#f9fafb",borderWidth:1,borderColor:"#e5e7eb",borderRadius:12,padding:6,marginBottom:24},input:{flex:1,paddingHorizontal:12,fontSize:14,color:"#111827",fontFamily:t.Platform.OS==="ios"?"Menlo":"monospace"},copyBtn:{paddingVertical:8,paddingHorizontal:16,borderRadius:8},copyBtnText:{color:"#fff",fontSize:13,fontWeight:"600"},shareLabelContainer:{flexDirection:"row",alignItems:"center",marginBottom:16},divider:{flex:1,height:1,backgroundColor:"#e5e7eb"},shareLabel:{marginHorizontal:12,fontSize:13,fontWeight:"500",color:"#6b7280"},socialContainer:{flexDirection:"row",justifyContent:"center",gap:12},socialBtn:{width:44,height:44,borderRadius:22,backgroundColor:"#fff",borderWidth:1,justifyContent:"center",alignItems:"center"},socialIcon:{fontSize:18,fontWeight:"bold"},footer:{marginTop:32,alignItems:"center"},poweredBy:{fontSize:11,color:"#9ca3af"},brand:{fontWeight:"600",textDecorationLine:"underline"}});var v=N(require("react")),w=require("react-native"),ie=({onPress:a,options:e})=>{let r=e?.modal?.theme?.primaryColor||"#2563eb",o=e?.trigger?.position||"bottom-right",c=(e?.trigger?.displayMode||"floating")==="edge",p=o.includes("right"),m=o.includes("top"),T=(0,v.useRef)(new w.Animated.Value(-1)).current;(0,v.useEffect)(()=>{let R=()=>{T.setValue(-1),w.Animated.timing(T,{toValue:2,duration:3e3,easing:w.Easing.linear,useNativeDriver:!0}).start(()=>{setTimeout(R,1e3)})};R()},[]);let u=T.interpolate({inputRange:[-1,2],outputRange:c?[-50,100]:[-60,120]}),d={"bottom-right":{bottom:100,right:0},"bottom-left":{bottom:100,left:0},"top-right":{top:100,right:0},"top-left":{top:100,left:0}};c||(d["bottom-right"]={bottom:30,right:20},d["bottom-left"]={bottom:30,left:20},d["top-right"]={top:60,right:20},d["top-left"]={top:60,left:20});let y=()=>v.default.createElement(w.View,{style:U.iconContainer},v.default.createElement(w.View,{style:U.giftBody},v.default.createElement(w.View,{style:U.giftLid}),v.default.createElement(w.View,{style:U.giftRibbonV}),v.default.createElement(w.View,{style:U.giftRibbonH})));return v.default.createElement(w.TouchableOpacity,{style:[c?U.edgeButton:U.floatingButton,{backgroundColor:r},d[o],c&&(p?U.edgeRight:U.edgeLeft)],onPress:a,activeOpacity:.9},v.default.createElement(w.View,{style:U.content},y()),v.default.createElement(w.Animated.View,{style:[U.shimmer,{transform:[{translateX:u},{skewX:"-15deg"}]}]}))},U=w.StyleSheet.create({floatingButton:{position:"absolute",width:60,height:60,borderRadius:30,justifyContent:"center",alignItems:"center",overflow:"hidden",shadowColor:"#000",shadowOffset:{width:0,height:8},shadowOpacity:.2,shadowRadius:12,elevation:8,zIndex:2147483646},edgeButton:{position:"absolute",width:50,height:50,justifyContent:"center",alignItems:"center",overflow:"hidden",shadowColor:"#000",shadowOffset:{width:0,height:4},shadowOpacity:.1,shadowRadius:8,elevation:4,zIndex:2147483646},edgeRight:{borderTopLeftRadius:8,borderBottomLeftRadius:8,paddingLeft:4},edgeLeft:{borderTopRightRadius:8,borderBottomRightRadius:8,paddingRight:4},content:{justifyContent:"center",alignItems:"center"},iconContainer:{width:24,height:24,justifyContent:"center",alignItems:"center"},giftBody:{width:16,height:14,backgroundColor:"rgba(255, 255, 255, 0.9)",borderRadius:1.5,marginTop:3,position:"relative"},giftLid:{position:"absolute",top:-3,left:-1.5,width:19,height:3,backgroundColor:"#fff",borderRadius:.5},giftRibbonV:{position:"absolute",top:-3,left:7,width:2.5,height:17,backgroundColor:"rgba(0, 0, 0, 0.1)"},giftRibbonH:{position:"absolute",top:5,left:0,width:16,height:2,backgroundColor:"rgba(0, 0, 0, 0.05)"},shimmer:{position:"absolute",top:0,left:0,width:50,height:"100%",backgroundColor:"rgba(255, 255, 255, 0.25)"}});var x=N(require("react")),h=require("react-native"),{width:Re}=h.Dimensions.get("window"),le=({visible:a,options:e,onClose:r})=>{let o=(0,x.useRef)(new h.Animated.Value(0)).current,[l,c]=(0,x.useState)(a),p=e.position.includes("bottom")?"bottom":"top",m=e.position.includes("left")?"left":e.position.includes("right")?"right":"center";if((0,x.useEffect)(()=>{a?(c(!0),h.Animated.spring(o,{toValue:1,useNativeDriver:!0,tension:50,friction:8}).start()):h.Animated.timing(o,{toValue:0,duration:250,useNativeDriver:!0}).start(()=>{c(!1)})},[a]),!l)return null;let T=o.interpolate({inputRange:[0,1],outputRange:[p==="top"?-100:100,0]}),u=o.interpolate({inputRange:[0,1],outputRange:[0,1]}),d={position:"absolute",[p]:h.Platform.OS==="ios"?60:40,zIndex:9999};return m==="center"?(d.left=20,d.right=20,d.alignItems="center"):d[m]=20,x.default.createElement(h.Animated.View,{style:[d,{transform:[{translateY:T}],opacity:u}]},x.default.createElement(h.View,{style:[q.banner,{backgroundColor:e.themeColor||"#2563eb"}]},x.default.createElement(h.Text,{style:q.icon},"\u{1F381}"),x.default.createElement(h.Text,{style:q.text},e.text),x.default.createElement(h.TouchableOpacity,{onPress:r,style:q.closeBtn},x.default.createElement(h.Text,{style:q.closeIcon},"\u2715"))))},q=h.StyleSheet.create({banner:{flexDirection:"row",alignItems:"center",padding:12,paddingHorizontal:16,borderRadius:12,shadowColor:"#000",shadowOffset:{width:0,height:4},shadowOpacity:.15,shadowRadius:10,elevation:5,maxWidth:Re-40},icon:{fontSize:18,marginRight:10},text:{color:"#fff",fontSize:14,fontWeight:"600",flex:1},closeBtn:{marginLeft:10,padding:4},closeIcon:{color:"rgba(255, 255, 255, 0.8)",fontSize:14,fontWeight:"bold"}});var ce=(0,f.createContext)(void 0),ke=({children:a,userId:e,...r})=>{let[o,l]=(0,f.useState)(g.isInitialized()),[c,p]=(0,f.useState)(g.isUserReady()),m=(0,f.useRef)(!1),[T,u]=(0,f.useState)(!1),[d,y]=(0,f.useState)(),[R,G]=(0,f.useState)(!1),[D,X]=(0,f.useState)(),[J,C]=(0,f.useState)(!1),[S,Q]=(0,f.useState)();(0,f.useEffect)(()=>{if(m.current)return;m.current=!0,(async()=>{if(await g.init(r),e)try{let k=await g.initAppUser(e);p(!0),k.referrerExperience?.trigger?.show&&G(!0)}catch(k){console.error("GrowthRail: User init failed",k)}try{let k=await g.getNewUserExperience();k.banner?.show&&(Q(k.banner),C(!0))}catch{}l(!0)})()},[]),(0,f.useEffect)(()=>{(async()=>{if(m.current&&e&&g.getUserId()!==e)try{let k=await g.initAppUser(e);p(!0),k.referrerExperience?.trigger?.show&&G(!0)}catch(k){console.error("GrowthRail: User init failed",k)}})()},[e]);let M={isInitialized:o,isUserReady:c,showDashboard:I=>{y(I),u(!0)},hideDashboard:()=>u(!1),showFloatingButton:I=>{X({trigger:I}),G(!0)},hideFloatingButton:()=>G(!1)};if(!o)return null;let L=g.getReferrerExperience(),Z={...L?.modal,...d,position:L?.trigger?.position||d?.position||"bottom-right",theme:{...L?.modal?.theme||{},...d?.theme||{}}},_={...L,...D,trigger:{...L?.trigger||{},...D?.trigger||{}}};return f.default.createElement(ce.Provider,{value:M},a,f.default.createElement(re,{visible:T,options:Z,onClose:()=>u(!1)}),R&&f.default.createElement(ie,{options:_,onPress:()=>M.showDashboard()}),J&&f.default.createElement(le,{visible:J,options:S,onClose:()=>C(!1)}))},oe=()=>{let a=(0,f.useContext)(ce);if(!a)throw new Error("useGrowthRail must be used within a GrowthRailProvider");return a};var E=require("react");var ve=()=>{let[a,e]=(0,E.useState)(!1),[r,o]=(0,E.useState)(null),l=oe(),c=(0,E.useCallback)(async d=>{e(!0),o(null);try{return await g.initAppUser(d)}catch(y){let R=y instanceof Error?y:new Error(String(y));throw o(R),R}finally{e(!1)}},[]),p=(0,E.useCallback)(async d=>{e(!0),o(null);try{await g.trackRewardEvent(d)}catch(y){let R=y instanceof Error?y:new Error(String(y));throw o(R),R}finally{e(!1)}},[]),m=(0,E.useCallback)(d=>{l.showDashboard(d)},[l]),T=(0,E.useCallback)(d=>{l.showFloatingButton(d)},[l]),u=(0,E.useCallback)(()=>{l.hideFloatingButton()},[l]);return{initUser:c,trackReward:p,showReferralDashboard:m,showFloatingButton:T,hideFloatingButton:u,isLoading:a,isInitialized:l.isInitialized,error:r}};0&&(module.exports={APIClient,GrowthRail,GrowthRailProvider,ReferralDashboard,StorageManager,TriggerButton,useGrowthRail,useGrowthRailContext});
1
+ "use strict";var Ce=Object.create;var _=Object.defineProperty;var ke=Object.getOwnPropertyDescriptor;var Te=Object.getOwnPropertyNames;var xe=Object.getPrototypeOf,ve=Object.prototype.hasOwnProperty;var Le=(o,e,a)=>e in o?_(o,e,{enumerable:!0,configurable:!0,writable:!0,value:a}):o[e]=a;var Ie=(o,e)=>{for(var a in e)_(o,a,{get:e[a],enumerable:!0})},ue=(o,e,a,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let l of Te(e))!ve.call(o,l)&&l!==a&&_(o,l,{get:()=>e[l],enumerable:!(s=ke(e,l))||s.enumerable});return o};var W=(o,e,a)=>(a=o!=null?Ce(xe(o)):{},ue(e||!o||!o.__esModule?_(a,"default",{value:o,enumerable:!0}):a,o)),Se=o=>ue(_({},"__esModule",{value:!0}),o);var de=(o,e,a)=>Le(o,typeof e!="symbol"?e+"":e,a);var Be={};Ie(Be,{GrowthRailProvider:()=>be,ReferralDashboard:()=>te,TriggerButton:()=>oe,useGrowthRail:()=>ye});module.exports=Se(Be);var n=W(require("react")),C=require("react-native"),we=W(require("react-native-play-install-referrer"));var Z=class{constructor(e){de(this,"baseUrl");de(this,"projectSecretKey");let a=typeof process<"u"&&process.env?.ENV_BASE_URL;this.baseUrl=a||"https://api.growthrail.dev",this.projectSecretKey=e.projectSecretKey}async request(e,a,s){let l={"Content-Type":"application/json","X-GrowthRail-ProjectSecret":this.projectSecretKey,Origin:this.baseUrl};try{let f=await fetch(`${this.baseUrl}${e}`,{method:a,headers:l,body:s?JSON.stringify(s):void 0});if(!f.ok){let k="";try{k=await f.text()}catch{}throw new Error(`GrowthRail API Error ${f.status} (${this.baseUrl}${e}): ${f.statusText} - ${k}`)}return f.json()}catch(f){throw console.error("GrowthRail SDK Error:",f),f}}async getNewUserExperience(){return this.request("/api/v1/sdk/new-user-experience","POST")}async initAppUser(e){return this.request("/api/v1/sdk/init-app-user","POST",{clientProvidedId:e})}async trackReferral(e,a){return this.request("/api/v1/sdk/track-referral","POST",{referralCode:e,rewardEventName:a})}async trackRewardEvent(e,a,s){return this.request("/api/v1/sdk/track-reward-event","POST",{refereeId:e,referralTrackingId:a,eventName:s})}async checkDeferredDeepLink(e){return this.request("/api/v1/sdk/match-link","POST",{fingerprint:e})}};var K=W(require("@react-native-async-storage/async-storage")),ee={TRACKED_REFERRAL:"growth-rail-tracked-referral",IS_FIRST_LAUNCH:"growth-rail-is-first-launch"},D=class{static async setTrackedReferral(e){await K.default.setItem(ee.TRACKED_REFERRAL,e)}static async getTrackedReferral(){return await K.default.getItem(ee.TRACKED_REFERRAL)}static async isFirstLaunch(){return await K.default.getItem(ee.IS_FIRST_LAUNCH)===null?(await K.default.setItem(ee.IS_FIRST_LAUNCH,"false"),!0):!1}};var r=W(require("react")),t=require("react-native");var{width:pe,height:fe}=t.Dimensions.get("window"),te=({visible:o,options:e,onClose:a})=>{let s=re(),[l,f]=(0,r.useState)(null),[k,d]=(0,r.useState)(!1),[p,m]=(0,r.useState)(!1),g=(0,r.useRef)(new t.Animated.Value(0)).current,T=(0,r.useRef)(new t.Animated.Value(0)).current,z=e?.title||"Invite Friends & Earn",B=e?.theme?.primaryColor||"#2563eb",M=e?.theme?.backgroundColor||"#ffffff",ie=e?.theme?.tintColor||"#000000",ne=e?.theme?.tintAlpha??.5,v=(e?.componentType||"modal")==="drawer",E=e?.position||"bottom-right",Y="#111827",j="#6b7280";(0,r.useEffect)(()=>{o?(l||ae(),t.Animated.parallel([t.Animated.timing(T,{toValue:1,duration:300,useNativeDriver:!0}),t.Animated.spring(g,{toValue:1,useNativeDriver:!0,tension:50,friction:8})]).start()):(g.setValue(0),T.setValue(0))},[o]);let $=()=>{t.Animated.parallel([t.Animated.timing(T,{toValue:0,duration:250,useNativeDriver:!0}),t.Animated.timing(g,{toValue:0,duration:250,useNativeDriver:!0})]).start(()=>{a()})},ae=async()=>{d(!0);try{if(s.isUserReady){let G=await s.getReferralLink();f(G||null)}}catch(G){console.error("GrowthRail: Failed to load referral link",G)}finally{d(!1)}},J=()=>{l&&(t.Clipboard.setString(l),m(!0),setTimeout(()=>m(!1),2e3))},V=G=>{if(!l)return;let O="",I=encodeURIComponent(l),H=encodeURIComponent("Check this out!");switch(G){case"twitter":O=`https://twitter.com/intent/tweet?url=${I}&text=${H}`;break;case"facebook":O=`https://www.facebook.com/sharer/sharer.php?u=${I}`;break;case"linkedin":O=`https://www.linkedin.com/sharing/share-offsite/?url=${I}`;break;case"whatsapp":O=`whatsapp://send?text=${H}%20${I}`;break;case"email":O=`mailto:?subject=Check this out&body=${H}%20${I}`;break}O&&t.Linking.openURL(O).catch(()=>{})},Q=()=>ie||"#000000",U=[];v?E.includes("right")?U=[{translateX:g.interpolate({inputRange:[0,1],outputRange:[pe,0]})}]:E.includes("left")?U=[{translateX:g.interpolate({inputRange:[0,1],outputRange:[-pe,0]})}]:U=[{translateY:g.interpolate({inputRange:[0,1],outputRange:[fe,0]})}]:U=[{scale:g.interpolate({inputRange:[0,1],outputRange:[.9,1]})},{translateY:g.interpolate({inputRange:[0,1],outputRange:[20,0]})}];let se=E.includes("top"),L=E.includes("right"),A=E.includes("left"),le=v?{position:"absolute",...se?{top:100}:{bottom:100},...L?{right:0}:A?{left:0}:{left:0,right:0},width:L||A?"85%":"100%",maxHeight:L||A?fe-200:"80%"}:{};return r.default.createElement(t.Modal,{visible:o,transparent:!0,animationType:"none",onRequestClose:$},r.default.createElement(t.View,{style:i.fullScreen},r.default.createElement(t.Animated.View,{style:[i.overlay,{backgroundColor:Q(),opacity:T.interpolate({inputRange:[0,1],outputRange:[0,ne]})}]},r.default.createElement(t.TouchableOpacity,{style:i.fullScreen,activeOpacity:1,onPress:$})),r.default.createElement(t.Animated.View,{style:[v?le:i.centeredModalContainer,{backgroundColor:M,transform:U},v&&L&&{borderTopLeftRadius:24,borderBottomLeftRadius:24},v&&A&&{borderTopRightRadius:24,borderBottomRightRadius:24},v&&!L&&!A&&E.includes("bottom")&&{borderTopLeftRadius:24,borderTopRightRadius:24},v&&!L&&!A&&E.includes("top")&&{borderBottomLeftRadius:24,borderBottomRightRadius:24},!v&&{borderRadius:24,opacity:g}]},r.default.createElement(t.View,{style:i.contentWrapper},v&&!L&&!A&&E.includes("bottom")&&r.default.createElement(t.View,{style:i.drawerHandle}),r.default.createElement(t.TouchableOpacity,{style:i.closeBtn,onPress:$},r.default.createElement(t.Text,{style:i.closeIcon},"\u2715")),r.default.createElement(t.ScrollView,{contentContainerStyle:i.scrollContent,showsVerticalScrollIndicator:!1},r.default.createElement(t.View,{style:i.header},r.default.createElement(t.View,{style:i.iconLgContainer},r.default.createElement(t.View,{style:i.bowContainerLg},r.default.createElement(t.View,{style:[i.bowLoopLg,i.bowLeftLg,{borderColor:B}]}),r.default.createElement(t.View,{style:[i.bowLoopLg,i.bowRightLg,{borderColor:B}]})),r.default.createElement(t.View,{style:[i.giftLidLg,{backgroundColor:B}]}),r.default.createElement(t.View,{style:[i.giftBodyLg,{borderColor:B}]},r.default.createElement(t.View,{style:[i.ribbonVerticalLg,{backgroundColor:"#fff",opacity:.3}]}))),r.default.createElement(t.Text,{style:[i.title,{color:Y}]},z),r.default.createElement(t.Text,{style:[i.subtitle,{color:j}]},e?.description||"Share your unique link and earn rewards for every friend who signs up.")),s.isUserReady?k?r.default.createElement(t.ActivityIndicator,{size:"large",color:B,style:i.loader}):r.default.createElement(t.View,{style:i.mainContent},r.default.createElement(t.Text,{style:i.label},"YOUR UNIQUE LINK"),r.default.createElement(t.View,{style:i.inputGroup},r.default.createElement(t.Text,{numberOfLines:1,style:i.input},l||"Initializing..."),r.default.createElement(t.TouchableOpacity,{style:[i.copyBtn,{backgroundColor:p?"#10b981":B}],onPress:J},r.default.createElement(t.Text,{style:i.copyBtnText},p?"Copied!":"Copy"))),r.default.createElement(t.View,{style:i.shareLabelContainer},r.default.createElement(t.View,{style:i.divider}),r.default.createElement(t.Text,{style:i.shareLabel},"Share via"),r.default.createElement(t.View,{style:i.divider})),r.default.createElement(t.View,{style:i.socialContainer},r.default.createElement(q,{platform:"twitter",color:"#000000",onPress:()=>V("twitter"),icon:"\u{1D54F}"}),r.default.createElement(q,{platform:"facebook",color:"#1877F2",onPress:()=>V("facebook"),icon:"f"}),r.default.createElement(q,{platform:"linkedin",color:"#0A66C2",onPress:()=>V("linkedin"),icon:"in"}),r.default.createElement(q,{platform:"whatsapp",color:"#25D366",onPress:()=>V("whatsapp"),icon:"W"}),r.default.createElement(q,{platform:"email",color:"#888888",onPress:()=>V("email"),icon:"\u2709"}))):r.default.createElement(t.View,{style:i.loadingBox},r.default.createElement(t.Text,{style:{color:j,textAlign:"center"}},"Please log in to view your referral dashboard.")),r.default.createElement(t.View,{style:i.footer},r.default.createElement(t.Text,{style:i.poweredBy},"Powered by ",r.default.createElement(t.Text,{style:i.brand,onPress:()=>t.Linking.openURL("https://growthrail.com")},"Growth Rail"))))))))},q=({color:o,onPress:e,icon:a})=>r.default.createElement(t.TouchableOpacity,{style:[i.socialBtn,{borderColor:"#e5e7eb"}],onPress:e},r.default.createElement(t.Text,{style:[i.socialIcon,{color:o}]},a)),i=t.StyleSheet.create({fullScreen:{flex:1},overlay:{...t.StyleSheet.absoluteFillObject},centeredModalContainer:{width:"90%",maxWidth:400,alignSelf:"center",marginTop:fe*.15,overflow:"hidden",shadowColor:"#000",shadowOffset:{width:0,height:20},shadowOpacity:.25,shadowRadius:30,elevation:20},contentWrapper:{paddingTop:t.Platform.OS==="ios"?20:0},drawerHandle:{width:40,height:4,backgroundColor:"#e5e7eb",borderRadius:2,alignSelf:"center",marginTop:12},scrollContent:{padding:32,alignItems:"center"},closeBtn:{position:"absolute",top:20,right:20,zIndex:10,width:32,height:32,borderRadius:16,backgroundColor:"#f3f4f6",justifyContent:"center",alignItems:"center"},closeIcon:{fontSize:14,color:"#9ca3af"},header:{alignItems:"center",marginBottom:28,width:"100%"},socialIcon:{fontSize:18,fontWeight:"bold"},title:{fontSize:22,fontWeight:"700",letterSpacing:-.5,marginBottom:8,textAlign:"center"},subtitle:{fontSize:14,lineHeight:20,textAlign:"center",paddingHorizontal:10},loadingBox:{padding:16,backgroundColor:"#f9fafb",borderRadius:12,width:"100%",alignItems:"center",borderWidth:1,borderColor:"#e5e7eb",marginTop:20},loader:{marginVertical:20},mainContent:{width:"100%"},label:{fontSize:12,fontWeight:"600",color:"#6b7280",marginBottom:8,letterSpacing:.5},inputGroup:{flexDirection:"row",alignItems:"center",backgroundColor:"#f9fafb",borderWidth:1,borderColor:"#e5e7eb",borderRadius:12,padding:6,marginBottom:24},input:{flex:1,paddingHorizontal:12,fontSize:14,color:"#111827",fontFamily:t.Platform.OS==="ios"?"Menlo":"monospace"},copyBtn:{paddingVertical:8,paddingHorizontal:16,borderRadius:8,justifyContent:"center",alignItems:"center"},copyBtnText:{color:"#fff",fontSize:13,fontWeight:"600"},shareLabelContainer:{flexDirection:"row",alignItems:"center",marginBottom:16,marginTop:8},divider:{flex:1,height:1,backgroundColor:"#e5e7eb"},shareLabel:{marginHorizontal:12,fontSize:13,fontWeight:"500",color:"#6b7280"},socialContainer:{flexDirection:"row",justifyContent:"center",gap:12},socialBtn:{width:44,height:44,borderRadius:22,backgroundColor:"#fff",borderWidth:1,justifyContent:"center",alignItems:"center"},iconLgContainer:{width:60,height:60,justifyContent:"center",alignItems:"center",marginBottom:16},bowContainerLg:{flexDirection:"row",position:"absolute",top:2,zIndex:2},bowLoopLg:{width:20,height:16,borderWidth:3,borderColor:"#e5e7eb",borderRadius:10},bowLeftLg:{marginRight:-2,transform:[{rotate:"-15deg"}]},bowRightLg:{marginLeft:-2,transform:[{rotate:"15deg"}]},giftLidLg:{width:44,height:10,backgroundColor:"#f3f4f6",borderRadius:2,marginTop:12,zIndex:3},giftBodyLg:{width:36,height:24,borderWidth:3,borderTopWidth:0,borderBottomLeftRadius:4,borderBottomRightRadius:4,justifyContent:"center",alignItems:"center",marginTop:-2},ribbonVerticalLg:{width:4,height:"100%",opacity:.1},footer:{marginTop:32,alignItems:"center"},poweredBy:{fontSize:11,color:"#9ca3af"},brand:{fontWeight:"600",textDecorationLine:"underline"}});var R=W(require("react")),h=require("react-native"),oe=({onPress:o,options:e})=>{let a=e?.modal?.theme?.primaryColor||"#2563eb",s=e?.trigger?.position||"bottom-right",f=(e?.trigger?.displayMode||"floating")==="edge",k=s.includes("right"),d=s.includes("top"),p=(0,R.useRef)(new h.Animated.Value(-1)).current;(0,R.useEffect)(()=>{let z=()=>{p.setValue(-1),h.Animated.timing(p,{toValue:2,duration:3e3,easing:h.Easing.linear,useNativeDriver:!0}).start(()=>{setTimeout(z,1e3)})};z()},[]);let m=p.interpolate({inputRange:[-1,2],outputRange:f?[-50,100]:[-60,120]}),g={"bottom-right":{bottom:100,right:0},"bottom-left":{bottom:100,left:0},"top-right":{top:100,right:0},"top-left":{top:100,left:0}};f||(g["bottom-right"]={bottom:30,right:20},g["bottom-left"]={bottom:30,left:20},g["top-right"]={top:60,right:20},g["top-left"]={top:60,left:20});let T=()=>R.default.createElement(h.View,{style:y.iconContainer},R.default.createElement(h.View,{style:y.bowContainer},R.default.createElement(h.View,{style:[y.bowLoop,y.bowLeft]}),R.default.createElement(h.View,{style:[y.bowLoop,y.bowRight]})),R.default.createElement(h.View,{style:y.giftLid}),R.default.createElement(h.View,{style:y.giftBody},R.default.createElement(h.View,{style:y.ribbonVertical})));return R.default.createElement(h.TouchableOpacity,{style:[f?y.edgeButton:y.floatingButton,{backgroundColor:a},g[s],f&&(k?y.edgeRight:y.edgeLeft)],onPress:o,activeOpacity:.9},R.default.createElement(h.View,{style:y.content},T()),R.default.createElement(h.Animated.View,{style:[y.shimmer,{transform:[{translateX:m},{skewX:"-15deg"}]}]}))},y=h.StyleSheet.create({floatingButton:{position:"absolute",width:60,height:60,borderRadius:30,justifyContent:"center",alignItems:"center",overflow:"hidden",shadowColor:"#000",shadowOffset:{width:0,height:8},shadowOpacity:.2,shadowRadius:12,elevation:8,zIndex:2147483646},edgeButton:{position:"absolute",width:50,height:50,justifyContent:"center",alignItems:"center",overflow:"hidden",shadowColor:"#000",shadowOffset:{width:0,height:4},shadowOpacity:.1,shadowRadius:8,elevation:4,zIndex:2147483646},edgeRight:{borderTopLeftRadius:8,borderBottomLeftRadius:8,paddingLeft:4},edgeLeft:{borderTopRightRadius:8,borderBottomRightRadius:8,paddingRight:4},content:{justifyContent:"center",alignItems:"center"},iconContainer:{width:28,height:28,justifyContent:"center",alignItems:"center"},bowContainer:{flexDirection:"row",position:"absolute",top:0,zIndex:2},bowLoop:{width:10,height:8,borderWidth:2,borderColor:"#fff",borderRadius:5},bowLeft:{marginRight:-1,transform:[{rotate:"-15deg"}]},bowRight:{marginLeft:-1,transform:[{rotate:"15deg"}]},giftLid:{width:22,height:5,backgroundColor:"#fff",borderRadius:1,marginTop:6,zIndex:3},giftBody:{width:18,height:12,borderWidth:2,borderColor:"#fff",borderTopWidth:0,borderBottomLeftRadius:2,borderBottomRightRadius:2,justifyContent:"center",alignItems:"center",marginTop:-1},ribbonVertical:{width:2,height:"100%",backgroundColor:"#fff",opacity:.8},shimmer:{position:"absolute",top:0,left:0,width:50,height:"100%",backgroundColor:"rgba(255, 255, 255, 0.25)"}});var x=W(require("react")),w=require("react-native"),{width:Pe}=w.Dimensions.get("window"),he=({visible:o,options:e,onClose:a})=>{let s=(0,x.useRef)(new w.Animated.Value(0)).current,[l,f]=(0,x.useState)(o),k=e.position.includes("bottom")?"bottom":"top",d=e.position.includes("left")?"left":e.position.includes("right")?"right":"center";if((0,x.useEffect)(()=>{o?(f(!0),w.Animated.spring(s,{toValue:1,useNativeDriver:!0,tension:50,friction:8}).start()):w.Animated.timing(s,{toValue:0,duration:250,useNativeDriver:!0}).start(()=>{f(!1)})},[o]),!l)return null;let p=s.interpolate({inputRange:[0,1],outputRange:[k==="top"?-100:100,0]}),m=s.interpolate({inputRange:[0,1],outputRange:[0,1]}),g={position:"absolute",[k]:w.Platform.OS==="ios"?60:40,zIndex:9999};return d==="center"?(g.left=20,g.right=20,g.alignItems="center"):g[d]=20,x.default.createElement(w.Animated.View,{style:[g,{transform:[{translateY:p}],opacity:m}]},x.default.createElement(w.View,{style:[X.banner,{backgroundColor:e.themeColor||"#2563eb"}]},x.default.createElement(w.Text,{style:X.icon},"\u{1F381}"),x.default.createElement(w.Text,{style:X.text},e.text),x.default.createElement(w.TouchableOpacity,{onPress:a,style:X.closeBtn},x.default.createElement(w.Text,{style:X.closeIcon},"\u2715"))))},X=w.StyleSheet.create({banner:{flexDirection:"row",alignItems:"center",padding:12,paddingHorizontal:16,borderRadius:12,shadowColor:"#000",shadowOffset:{width:0,height:4},shadowOpacity:.15,shadowRadius:10,elevation:5,maxWidth:Pe-40},icon:{fontSize:18,marginRight:10},text:{color:"#fff",fontSize:14,fontWeight:"600",flex:1},closeBtn:{marginLeft:10,padding:4},closeIcon:{color:"rgba(255, 255, 255, 0.8)",fontSize:14,fontWeight:"bold"}});var me=(0,n.createContext)(void 0),be=({children:o,userId:e,...a})=>{let[s,l]=(0,n.useState)(!1),[f,k]=(0,n.useState)(!1),[d,p]=(0,n.useState)(null),m=(0,n.useRef)(new Z(a)),g=(0,n.useRef)(!1),T=(0,n.useRef)(null),[z,B]=(0,n.useState)(!1),[M,ie]=(0,n.useState)(),[ne,ge]=(0,n.useState)(!1),[v,E]=(0,n.useState)(),[Y,j]=(0,n.useState)(!1),[$,ae]=(0,n.useState)(),J=(0,n.useCallback)(()=>{let{width:u,height:c}=C.Dimensions.get("window"),b=Intl.DateTimeFormat().resolvedOptions().locale,S=C.PixelRatio.get(),P,F;if(C.Platform.OS==="android"){let ce=C.Platform.constants;P=ce.Model,F=ce.Brand||ce.Manufacturer}return{os:C.Platform.OS,platform:C.Platform.OS,osVersion:String(C.Platform.Version),screenWidth:u,screenHeight:c,timezoneOffsetInMinutes:String(new Date().getTimezoneOffset()),locale:b,language:b,deviceModel:P,deviceBrand:F,pixelRatio:S}},[]),V=(0,n.useCallback)(async(u,c)=>{let b=await m.current.trackReferral(u,c);return await D.setTrackedReferral(b.referralTrackingId),b},[]),Q=(0,n.useCallback)(async u=>{try{let c=u.match(/[?&]referralCode=([^&]+)/);c&&(console.log("GrowthRail: Tracking referral from deep link",c[1]),await V(c[1]))}catch(c){console.warn("GrowthRail: Error handling deep link",c)}},[V]),U=(0,n.useCallback)(async()=>{try{let u=J(),{referralTrackingId:c}=await m.current.checkDeferredDeepLink(u);c&&(console.log("GrowthRail: Found deferred referral via fingerprinting",c),await D.setTrackedReferral(c))}catch(u){console.warn("GrowthRail: Fingerprint check failed",u)}},[J]),se=(0,n.useCallback)(()=>new Promise(u=>{we.default.getInstallReferrerInfo(async(c,b)=>{if(!b&&c&&c.installReferrer)try{let P=decodeURIComponent(c.installReferrer).match(/[?&]referralCode=([^&]+)/);if(P){let{referralTrackingId:F}=await V(P[1]);await D.setTrackedReferral(F),console.log("GrowthRail: Tracked referral via Install Referrer")}}catch(S){console.warn("GrowthRail: Failed to process install referrer",S)}else await U();u()})}),[V,U]),L=(0,n.useCallback)(async u=>{if(d?.id===u&&f)return d;let c=(async()=>{try{let b=await m.current.initAppUser(u),S={...b,id:u};return p(S),k(!0),b.referrerExperience?.trigger?.show&&ge(!0),S}catch(b){throw T.current=null,b}})();return T.current=c,c},[d,f]),A=(0,n.useCallback)(async u=>{let c=d;!c&&T.current&&(c=await T.current);let b=c?.id||e;if(!b)throw new Error("GrowthRail: User must be initialized before tracking a reward event.");let S=await D.getTrackedReferral();if(!S){console.warn("GrowthRail: No referral tracking ID found. Reward event not attributed.");return}return m.current.trackRewardEvent(b,S,u)},[d,e]),le=(0,n.useCallback)(async()=>await D.getTrackedReferral(),[]),G=(0,n.useCallback)(async()=>{if(d)return d.referralLink;if(T.current)return(await T.current).referralLink},[d]);(0,n.useEffect)(()=>{if(g.current)return;g.current=!0,(async()=>{let c=await C.Linking.getInitialURL();c&&await Q(c);let b=C.Linking.addEventListener("url",({url:P})=>Q(P));await D.isFirstLaunch()&&(C.Platform.OS==="android"?await se():await U()),e&&await L(e);try{let P=await m.current.getNewUserExperience(),F=await D.getTrackedReferral();P.banner?.show&&F&&(ae(P.banner),j(!0))}catch{}return l(!0),()=>b.remove()})()},[]),(0,n.useEffect)(()=>{s&&e&&d?.id!==e&&L(e)},[e,s]);let O={isInitialized:s,isUserReady:f,currentUser:d,referralCode:d?.referralCode,referralLink:d?.referralLink,showDashboard:u=>{ie(u),B(!0)},hideDashboard:()=>B(!1),initUser:L,trackReward:A,getReferralTrackingId:le,getReferralLink:G};if(!s)return null;let I=d?.referrerExperience,H={...I?.modal,...M,position:I?.trigger?.position||M?.position||"bottom-right",theme:{...I?.modal?.theme||{},...M?.theme||{}}},Re={...I,...v,trigger:{...I?.trigger||{},...v?.trigger||{}}};return n.default.createElement(me.Provider,{value:O},o,n.default.createElement(te,{visible:z,options:H,onClose:()=>B(!1)}),ne&&n.default.createElement(oe,{options:Re,onPress:()=>O.showDashboard()}),Y&&n.default.createElement(he,{visible:Y,options:$,onClose:()=>j(!1)}))},re=()=>{let o=(0,n.useContext)(me);if(!o)throw new Error("useGrowthRail must be used within a GrowthRailProvider");return o};var N=require("react");var ye=()=>{let[o,e]=(0,N.useState)(!1),[a,s]=(0,N.useState)(null),l=re(),f=(0,N.useCallback)(async d=>{e(!0),s(null);try{return await l.initUser(d)}catch(p){let m=p instanceof Error?p:new Error(String(p));throw s(m),m}finally{e(!1)}},[l]),k=(0,N.useCallback)(async d=>{e(!0),s(null);try{await l.trackReward(d)}catch(p){let m=p instanceof Error?p:new Error(String(p));throw s(m),m}finally{e(!1)}},[l]);return{initAppUser:f,trackRewardEvent:k,showReferralDashboard:l.showDashboard,hideReferralDashboard:l.hideDashboard,getReferralTrackingId:l.getReferralTrackingId,getReferralLink:l.getReferralLink,isLoading:o,isInitialized:l.isInitialized,isUserReady:l.isUserReady,error:a}};0&&(module.exports={GrowthRailProvider,ReferralDashboard,TriggerButton,useGrowthRail});
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- var ve=Object.defineProperty;var xe=(l,e,r)=>e in l?ve(l,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):l[e]=r;var v=(l,e,r)=>xe(l,typeof e!="symbol"?e+"":e,r);import{Linking as se,Platform as A,Dimensions as Te,PixelRatio as Ce}from"react-native";import Ie from"react-native-play-install-referrer";var K=class{constructor(e){v(this,"baseUrl");v(this,"apiKey");let r=typeof process<"u"&&process.env?.ENV_BASE_URL;this.baseUrl=r||"https://api.growthrail.dev",this.apiKey=e.apiKey}async request(e,r,i){let c={"Content-Type":"application/json","X-GrowthRail-ProjectSecret":this.apiKey,Origin:this.baseUrl};try{let a=await fetch(`${this.baseUrl}${e}`,{method:r,headers:c,body:i?JSON.stringify(i):void 0});if(!a.ok){let d="";try{d=await a.text()}catch{}throw new Error(`GrowthRail API Error ${a.status} (${this.baseUrl}${e}): ${a.statusText} - ${d}`)}return a.json()}catch(a){throw console.error("GrowthRail SDK Error:",a),a}}async getNewUserExperience(){return this.request("/api/v1/sdk/new-user-experience","POST")}async initAppUser(e){return this.request("/api/v1/sdk/init-app-user","POST",{clientProvidedId:e})}async createReferralLink(e,r){return this.request("/api/v1/sdk/create-referral-link","POST",{referrerId:e,rewardEventName:r})}async trackReferral(e,r){return this.request("/api/v1/sdk/track-referral","POST",{referralCode:e,rewardEventName:r})}async trackRewardEvent(e,r,i){return this.request("/api/v1/sdk/track-reward-event","POST",{refereeId:e,referralTrackingId:r,eventName:i})}async checkDeferredDeepLink(e){return this.request("/api/v1/sdk/match-link","POST",{fingerprint:e})}};import q from"@react-native-async-storage/async-storage";var X={TRACKED_REFERRAL:"growth-rail-tracked-referral",IS_FIRST_LAUNCH:"growth-rail-is-first-launch"},U=class{static async setTrackedReferral(e){await q.setItem(X.TRACKED_REFERRAL,e)}static async getTrackedReferral(){return await q.getItem(X.TRACKED_REFERRAL)}static async isFirstLaunch(){return await q.getItem(X.IS_FIRST_LAUNCH)===null?(await q.setItem(X.IS_FIRST_LAUNCH,"false"),!0):!1}};var t=class t{constructor(){}static async init(e){t.initialized||(t.options=e,t.api=new K(e),t.initialized=!0,await t.handleInitialUrl(),await t.setupLinkListeners(),await t.checkDeferredReferral())}static async handleInitialUrl(){try{let e=await se.getInitialURL();e&&await t.handleDeepLink(e)}catch(e){console.error("GrowthRail: Error getting initial URL",e)}}static setupLinkListeners(){se.addEventListener("url",({url:e})=>{t.handleDeepLink(e)})}static async checkDeferredReferral(){await U.isFirstLaunch()&&(A.OS==="android"?await t.checkInstallReferrer():await t.checkDeferredDeepLinkFingerprint())}static checkInstallReferrer(){return new Promise(e=>{Ie.getInstallReferrerInfo(async(r,i)=>{if(!i&&r&&r.installReferrer)try{let a=decodeURIComponent(r.installReferrer).match(/[?&]referralCode=([^&]+)/);if(a){let{referralTrackingId:d}=await t.trackReferral(a[1]);await U.setTrackedReferral(d),console.log("GrowthRail: Tracked referral via Install Referrer")}}catch(c){console.warn("GrowthRail: Failed to process install referrer",c)}else await t.checkDeferredDeepLinkFingerprint();e()})})}static getDeviceFingerprint(){let{width:e,height:r}=Te.get("window"),i=Intl.DateTimeFormat().resolvedOptions().locale,c=Ce.get(),a,d;if(A.OS==="android"){let u=A.constants;a=u.Model,d=u.Brand||u.Manufacturer}return{os:A.OS,platform:A.OS,osVersion:String(A.Version),screenWidth:e,screenHeight:r,timezoneOffsetInMinutes:String(new Date().getTimezoneOffset()),locale:i,language:i,deviceModel:a,deviceBrand:d,pixelRatio:c}}static async checkDeferredDeepLinkFingerprint(){try{let e=t.getDeviceFingerprint();console.log("GrowthRail executing deferred fingerprint check to API...");let{referralTrackingId:r}=await t.api.checkDeferredDeepLink(e);r&&(console.log("GrowthRail: Found deferred referral via fingerprinting",r),await U.setTrackedReferral(r))}catch(e){console.warn("GrowthRail: Fingerprint check failed",e)}}static async handleDeepLink(e){try{let r=new URL(e),i=r.searchParams.get("referralCode"),c=r.searchParams.get("rewardEventName");i&&(console.log("GrowthRail: Tracking referral from deep link",i),await t.trackReferral(i,c||void 0))}catch{let i=e.match(/[?&]referralCode=([^&]+)/);i&&await t.trackReferral(i[1])}}static ensureInitialized(){if(!t.initialized)throw new Error("GrowthRail.init() must be called before using the SDK")}static async initAppUser(e){t.ensureInitialized();let r=await t.api.initAppUser(e);return t.currentUser={...r,id:e},t.userReadyResolver&&t.userReadyResolver(t.currentUser),r}static async trackReferral(e,r){t.ensureInitialized();let i=await t.api.trackReferral(e,r);return await U.setTrackedReferral(i.referralTrackingId),i}static async trackRewardEvent(e){t.ensureInitialized();let r=t.currentUser?.id;if(!r)throw new Error("GrowthRail: User must be initialized before tracking a reward event.");let i=await U.getTrackedReferral();if(!i){console.warn("GrowthRail: No referral tracking ID found. Reward event not attributed.");return}return t.api.trackRewardEvent(r,i,e)}static async createReferralLink(e){t.ensureInitialized();let r=t.currentUser?.id;if(!r)throw new Error("GrowthRail: User must be initialized before creating a referral link.");if(t.referralObject)return t.referralObject;let i=await t.api.createReferralLink(r,e);return t.referralObject=i,i}static isInitialized(){return t.initialized}static getReferralLink(){if(!t.referralObject?.referralLink)throw new Error("GrowthRail: Referral Link not loaded or user not initialized");return t.referralObject.referralLink}static getReferralCode(){return t.referralObject?.referralCode||t.currentUser?.referralCode}static getUserId(){return t.currentUser?.id}static isUserReady(){return t.currentUser!==null}static getReferrerExperience(){return t.currentUser?.referrerExperience}static ensureUserReady(){return t.currentUser?Promise.resolve(t.currentUser):(t.userReadyPromise||(t.userReadyPromise=new Promise(e=>{t.userReadyResolver=e})),t.userReadyPromise)}static async getNewUserExperience(){return t.ensureInitialized(),t.api.getNewUserExperience()}};v(t,"api"),v(t,"options"),v(t,"currentUser",null),v(t,"referralObject",null),v(t,"initialized",!1),v(t,"userReadyPromise",null),v(t,"userReadyResolver",null);var p=t;import Q,{createContext as qe,useContext as Xe,useEffect as me,useState as L,useRef as Ye}from"react";import o,{useEffect as Pe,useState as ie,useRef as le}from"react";import{Modal as Ue,View as b,Text as R,StyleSheet as ce,TouchableOpacity as Y,Clipboard as Se,ActivityIndicator as Le,Linking as de,ScrollView as Oe,Platform as fe,Animated as C,Dimensions as Be}from"react-native";var{width:pe,height:oe}=Be.get("window"),ue=({visible:l,options:e,onClose:r})=>{let[i,c]=ie(null),[a,d]=ie(!1),[u,w]=ie(!1),f=le(new C.Value(0)).current,s=le(new C.Value(0)).current,g=e?.title||"Invite Friends & Earn",h=e?.theme?.primaryColor||"#2563eb",z=e?.theme?.backgroundColor||"#ffffff",O=e?.theme?.tintColor||"#000000",H=e?.theme?.tintAlpha??.5,y=(e?.componentType||"modal")==="drawer",T=e?.position||"bottom-right",_="#111827",N="#6b7280";Pe(()=>{l?(i||ee(),C.parallel([C.timing(s,{toValue:1,duration:300,useNativeDriver:!0}),C.spring(f,{toValue:1,useNativeDriver:!0,tension:50,friction:8})]).start()):(f.setValue(0),s.setValue(0))},[l]);let I=()=>{C.parallel([C.timing(s,{toValue:0,duration:250,useNativeDriver:!0}),C.timing(f,{toValue:0,duration:250,useNativeDriver:!0})]).start(()=>{r()})},ee=async()=>{d(!0);try{if(p.isUserReady()){let D=await p.createReferralLink();c(D.referralLink)}}catch(D){console.error("GrowthRail: Failed to load referral link",D)}finally{d(!1)}},te=()=>{i&&(Se.setString(i),w(!0),setTimeout(()=>w(!1),2e3))},k=D=>{if(!i)return;let P="",V=encodeURIComponent(i),re=encodeURIComponent("Check this out!");switch(D){case"twitter":P=`https://twitter.com/intent/tweet?url=${V}&text=${re}`;break;case"facebook":P=`https://www.facebook.com/sharer/sharer.php?u=${V}`;break;case"linkedin":P=`https://www.linkedin.com/sharing/share-offsite/?url=${V}`;break;case"whatsapp":P=`whatsapp://send?text=${re}%20${V}`;break;case"email":P=`mailto:?subject=Check this out&body=${re}%20${V}`;break}P&&de.openURL(P).catch(()=>{})},m=()=>{if(O.startsWith("#")){let D=parseInt(O.slice(1,3),16),P=parseInt(O.slice(3,5),16),V=parseInt(O.slice(5,7),16);return`rgba(${D}, ${P}, ${V}, ${H})`}return`rgba(0, 0, 0, ${H})`},M=[];y?T.includes("right")?M=[{translateX:f.interpolate({inputRange:[0,1],outputRange:[pe,0]})}]:T.includes("left")?M=[{translateX:f.interpolate({inputRange:[0,1],outputRange:[-pe,0]})}]:M=[{translateY:f.interpolate({inputRange:[0,1],outputRange:[oe,0]})}]:M=[{scale:f.interpolate({inputRange:[0,1],outputRange:[.9,1]})},{translateY:f.interpolate({inputRange:[0,1],outputRange:[20,0]})}];let Re=T.includes("top"),B=T.includes("right"),E=T.includes("left"),ke=y?{position:"absolute",...Re?{top:100}:{bottom:100},...B?{right:0}:E?{left:0}:{left:0,right:0},width:B||E?"85%":"100%",maxHeight:B||E?oe-200:"80%"}:{};return o.createElement(Ue,{visible:l,transparent:!0,animationType:"none",onRequestClose:I},o.createElement(b,{style:n.fullScreen},o.createElement(C.View,{style:[n.overlay,{backgroundColor:m(),opacity:s}]},o.createElement(Y,{style:n.fullScreen,activeOpacity:1,onPress:I})),o.createElement(C.View,{style:[y?ke:n.centeredModalContainer,{backgroundColor:z,transform:M},y&&B&&{borderTopLeftRadius:24,borderBottomLeftRadius:24},y&&E&&{borderTopRightRadius:24,borderBottomRightRadius:24},y&&!B&&!E&&T.includes("bottom")&&{borderTopLeftRadius:24,borderTopRightRadius:24},y&&!B&&!E&&T.includes("top")&&{borderBottomLeftRadius:24,borderBottomRightRadius:24},!y&&{borderRadius:24,opacity:f}]},o.createElement(b,{style:n.contentWrapper},y&&!B&&!E&&T.includes("bottom")&&o.createElement(b,{style:n.drawerHandle}),o.createElement(Y,{style:n.closeBtn,onPress:I},o.createElement(R,{style:n.closeIcon},"\u2715")),o.createElement(Oe,{contentContainerStyle:n.scrollContent,showsVerticalScrollIndicator:!1},o.createElement(b,{style:n.header},o.createElement(R,{style:n.iconLg},"\u{1F381}"),o.createElement(R,{style:[n.title,{color:_}]},g),o.createElement(R,{style:[n.subtitle,{color:N}]},e?.description||"Share your unique link and earn rewards for every friend who signs up.")),p.isUserReady()?a?o.createElement(Le,{size:"large",color:h,style:n.loader}):o.createElement(b,{style:n.mainContent},o.createElement(R,{style:n.label},"YOUR UNIQUE LINK"),o.createElement(b,{style:n.inputGroup},o.createElement(R,{numberOfLines:1,style:n.input},i||"Initializing..."),o.createElement(Y,{style:[n.copyBtn,{backgroundColor:u?"#10b981":h}],onPress:te},o.createElement(R,{style:n.copyBtnText},u?"Copied!":"Copy"))),o.createElement(b,{style:n.shareLabelContainer},o.createElement(b,{style:n.divider}),o.createElement(R,{style:n.shareLabel},"Share via"),o.createElement(b,{style:n.divider})),o.createElement(b,{style:n.socialContainer},o.createElement(W,{platform:"twitter",color:"#000000",onPress:()=>k("twitter"),icon:"\u{1D54F}"}),o.createElement(W,{platform:"facebook",color:"#1877F2",onPress:()=>k("facebook"),icon:"f"}),o.createElement(W,{platform:"linkedin",color:"#0A66C2",onPress:()=>k("linkedin"),icon:"in"}),o.createElement(W,{platform:"whatsapp",color:"#25D366",onPress:()=>k("whatsapp"),icon:"W"}),o.createElement(W,{platform:"email",color:"#888888",onPress:()=>k("email"),icon:"\u2709"}))):o.createElement(b,{style:n.loadingBox},o.createElement(R,{style:{color:N,textAlign:"center"}},"Please log in to view your referral dashboard.")),o.createElement(b,{style:n.footer},o.createElement(R,{style:n.poweredBy},"Powered by ",o.createElement(R,{style:n.brand,onPress:()=>de.openURL("https://growthrail.com")},"Growth Rail"))))))))},W=({color:l,onPress:e,icon:r})=>o.createElement(Y,{style:[n.socialBtn,{borderColor:"#e5e7eb"}],onPress:e},o.createElement(R,{style:[n.socialIcon,{color:l}]},r)),n=ce.create({fullScreen:{flex:1},overlay:{...ce.absoluteFillObject},centeredModalContainer:{width:"90%",maxWidth:400,alignSelf:"center",marginTop:oe*.15,overflow:"hidden",shadowColor:"#000",shadowOffset:{width:0,height:20},shadowOpacity:.25,shadowRadius:30,elevation:20},contentWrapper:{paddingTop:fe.OS==="ios"?20:0},drawerHandle:{width:40,height:4,backgroundColor:"#e5e7eb",borderRadius:2,alignSelf:"center",marginTop:12},scrollContent:{padding:32,alignItems:"center"},closeBtn:{position:"absolute",top:20,right:20,zIndex:10,width:32,height:32,borderRadius:16,backgroundColor:"#f3f4f6",justifyContent:"center",alignItems:"center"},closeIcon:{fontSize:14,color:"#9ca3af"},header:{alignItems:"center",marginBottom:28},iconLg:{fontSize:32,marginBottom:12},title:{fontSize:22,fontWeight:"700",letterSpacing:-.5,marginBottom:8,textAlign:"center"},subtitle:{fontSize:14,lineHeight:20,textAlign:"center",paddingHorizontal:10},loadingBox:{padding:16,backgroundColor:"#f9fafb",borderRadius:12,width:"100%",alignItems:"center"},loader:{marginVertical:20},mainContent:{width:"100%"},label:{fontSize:12,fontWeight:"600",color:"#6b7280",marginBottom:8,letterSpacing:.5},inputGroup:{flexDirection:"row",alignItems:"center",backgroundColor:"#f9fafb",borderWidth:1,borderColor:"#e5e7eb",borderRadius:12,padding:6,marginBottom:24},input:{flex:1,paddingHorizontal:12,fontSize:14,color:"#111827",fontFamily:fe.OS==="ios"?"Menlo":"monospace"},copyBtn:{paddingVertical:8,paddingHorizontal:16,borderRadius:8},copyBtnText:{color:"#fff",fontSize:13,fontWeight:"600"},shareLabelContainer:{flexDirection:"row",alignItems:"center",marginBottom:16},divider:{flex:1,height:1,backgroundColor:"#e5e7eb"},shareLabel:{marginHorizontal:12,fontSize:13,fontWeight:"500",color:"#6b7280"},socialContainer:{flexDirection:"row",justifyContent:"center",gap:12},socialBtn:{width:44,height:44,borderRadius:22,backgroundColor:"#fff",borderWidth:1,justifyContent:"center",alignItems:"center"},socialIcon:{fontSize:18,fontWeight:"bold"},footer:{marginTop:32,alignItems:"center"},poweredBy:{fontSize:11,color:"#9ca3af"},brand:{fontWeight:"600",textDecorationLine:"underline"}});import S,{useEffect as Ee,useRef as De}from"react";import{TouchableOpacity as Ve,View as F,StyleSheet as ze,Animated as ne,Easing as Ae}from"react-native";var ge=({onPress:l,options:e})=>{let r=e?.modal?.theme?.primaryColor||"#2563eb",i=e?.trigger?.position||"bottom-right",a=(e?.trigger?.displayMode||"floating")==="edge",d=i.includes("right"),u=i.includes("top"),w=De(new ne.Value(-1)).current;Ee(()=>{let h=()=>{w.setValue(-1),ne.timing(w,{toValue:2,duration:3e3,easing:Ae.linear,useNativeDriver:!0}).start(()=>{setTimeout(h,1e3)})};h()},[]);let f=w.interpolate({inputRange:[-1,2],outputRange:a?[-50,100]:[-60,120]}),s={"bottom-right":{bottom:100,right:0},"bottom-left":{bottom:100,left:0},"top-right":{top:100,right:0},"top-left":{top:100,left:0}};a||(s["bottom-right"]={bottom:30,right:20},s["bottom-left"]={bottom:30,left:20},s["top-right"]={top:60,right:20},s["top-left"]={top:60,left:20});let g=()=>S.createElement(F,{style:x.iconContainer},S.createElement(F,{style:x.giftBody},S.createElement(F,{style:x.giftLid}),S.createElement(F,{style:x.giftRibbonV}),S.createElement(F,{style:x.giftRibbonH})));return S.createElement(Ve,{style:[a?x.edgeButton:x.floatingButton,{backgroundColor:r},s[i],a&&(d?x.edgeRight:x.edgeLeft)],onPress:l,activeOpacity:.9},S.createElement(F,{style:x.content},g()),S.createElement(ne.View,{style:[x.shimmer,{transform:[{translateX:f},{skewX:"-15deg"}]}]}))},x=ze.create({floatingButton:{position:"absolute",width:60,height:60,borderRadius:30,justifyContent:"center",alignItems:"center",overflow:"hidden",shadowColor:"#000",shadowOffset:{width:0,height:8},shadowOpacity:.2,shadowRadius:12,elevation:8,zIndex:2147483646},edgeButton:{position:"absolute",width:50,height:50,justifyContent:"center",alignItems:"center",overflow:"hidden",shadowColor:"#000",shadowOffset:{width:0,height:4},shadowOpacity:.1,shadowRadius:8,elevation:4,zIndex:2147483646},edgeRight:{borderTopLeftRadius:8,borderBottomLeftRadius:8,paddingLeft:4},edgeLeft:{borderTopRightRadius:8,borderBottomRightRadius:8,paddingRight:4},content:{justifyContent:"center",alignItems:"center"},iconContainer:{width:24,height:24,justifyContent:"center",alignItems:"center"},giftBody:{width:16,height:14,backgroundColor:"rgba(255, 255, 255, 0.9)",borderRadius:1.5,marginTop:3,position:"relative"},giftLid:{position:"absolute",top:-3,left:-1.5,width:19,height:3,backgroundColor:"#fff",borderRadius:.5},giftRibbonV:{position:"absolute",top:-3,left:7,width:2.5,height:17,backgroundColor:"rgba(0, 0, 0, 0.1)"},giftRibbonH:{position:"absolute",top:5,left:0,width:16,height:2,backgroundColor:"rgba(0, 0, 0, 0.05)"},shimmer:{position:"absolute",top:0,left:0,width:50,height:"100%",backgroundColor:"rgba(255, 255, 255, 0.25)"}});import G,{useEffect as Fe,useRef as Ge,useState as Ne}from"react";import{View as Me,Text as ae,StyleSheet as We,Animated as J,Dimensions as $e,TouchableOpacity as je,Platform as He}from"react-native";var{width:Ke}=$e.get("window"),he=({visible:l,options:e,onClose:r})=>{let i=Ge(new J.Value(0)).current,[c,a]=Ne(l),d=e.position.includes("bottom")?"bottom":"top",u=e.position.includes("left")?"left":e.position.includes("right")?"right":"center";if(Fe(()=>{l?(a(!0),J.spring(i,{toValue:1,useNativeDriver:!0,tension:50,friction:8}).start()):J.timing(i,{toValue:0,duration:250,useNativeDriver:!0}).start(()=>{a(!1)})},[l]),!c)return null;let w=i.interpolate({inputRange:[0,1],outputRange:[d==="top"?-100:100,0]}),f=i.interpolate({inputRange:[0,1],outputRange:[0,1]}),s={position:"absolute",[d]:He.OS==="ios"?60:40,zIndex:9999};return u==="center"?(s.left=20,s.right=20,s.alignItems="center"):s[u]=20,G.createElement(J.View,{style:[s,{transform:[{translateY:w}],opacity:f}]},G.createElement(Me,{style:[$.banner,{backgroundColor:e.themeColor||"#2563eb"}]},G.createElement(ae,{style:$.icon},"\u{1F381}"),G.createElement(ae,{style:$.text},e.text),G.createElement(je,{onPress:r,style:$.closeBtn},G.createElement(ae,{style:$.closeIcon},"\u2715"))))},$=We.create({banner:{flexDirection:"row",alignItems:"center",padding:12,paddingHorizontal:16,borderRadius:12,shadowColor:"#000",shadowOffset:{width:0,height:4},shadowOpacity:.15,shadowRadius:10,elevation:5,maxWidth:Ke-40},icon:{fontSize:18,marginRight:10},text:{color:"#fff",fontSize:14,fontWeight:"600",flex:1},closeBtn:{marginLeft:10,padding:4},closeIcon:{color:"rgba(255, 255, 255, 0.8)",fontSize:14,fontWeight:"bold"}});var we=qe(void 0),Tt=({children:l,userId:e,...r})=>{let[i,c]=L(p.isInitialized()),[a,d]=L(p.isUserReady()),u=Ye(!1),[w,f]=L(!1),[s,g]=L(),[h,z]=L(!1),[O,H]=L(),[Z,y]=L(!1),[T,_]=L();me(()=>{if(u.current)return;u.current=!0,(async()=>{if(await p.init(r),e)try{let m=await p.initAppUser(e);d(!0),m.referrerExperience?.trigger?.show&&z(!0)}catch(m){console.error("GrowthRail: User init failed",m)}try{let m=await p.getNewUserExperience();m.banner?.show&&(_(m.banner),y(!0))}catch{}c(!0)})()},[]),me(()=>{(async()=>{if(u.current&&e&&p.getUserId()!==e)try{let m=await p.initAppUser(e);d(!0),m.referrerExperience?.trigger?.show&&z(!0)}catch(m){console.error("GrowthRail: User init failed",m)}})()},[e]);let N={isInitialized:i,isUserReady:a,showDashboard:k=>{g(k),f(!0)},hideDashboard:()=>f(!1),showFloatingButton:k=>{H({trigger:k}),z(!0)},hideFloatingButton:()=>z(!1)};if(!i)return null;let I=p.getReferrerExperience(),ee={...I?.modal,...s,position:I?.trigger?.position||s?.position||"bottom-right",theme:{...I?.modal?.theme||{},...s?.theme||{}}},te={...I,...O,trigger:{...I?.trigger||{},...O?.trigger||{}}};return Q.createElement(we.Provider,{value:N},l,Q.createElement(ue,{visible:w,options:ee,onClose:()=>f(!1)}),h&&Q.createElement(ge,{options:te,onPress:()=>N.showDashboard()}),Z&&Q.createElement(he,{visible:Z,options:T,onClose:()=>y(!1)}))},ye=()=>{let l=Xe(we);if(!l)throw new Error("useGrowthRail must be used within a GrowthRailProvider");return l};import{useState as be,useCallback as j}from"react";var St=()=>{let[l,e]=be(!1),[r,i]=be(null),c=ye(),a=j(async s=>{e(!0),i(null);try{return await p.initAppUser(s)}catch(g){let h=g instanceof Error?g:new Error(String(g));throw i(h),h}finally{e(!1)}},[]),d=j(async s=>{e(!0),i(null);try{await p.trackRewardEvent(s)}catch(g){let h=g instanceof Error?g:new Error(String(g));throw i(h),h}finally{e(!1)}},[]),u=j(s=>{c.showDashboard(s)},[c]),w=j(s=>{c.showFloatingButton(s)},[c]),f=j(()=>{c.hideFloatingButton()},[c]);return{initUser:a,trackReward:d,showReferralDashboard:u,showFloatingButton:w,hideFloatingButton:f,isLoading:l,isInitialized:c.isInitialized,error:r}};export{K as APIClient,p as GrowthRail,Tt as GrowthRailProvider,ue as ReferralDashboard,U as StorageManager,ge as TriggerButton,St as useGrowthRail,ye as useGrowthRailContext};
1
+ var Ve=Object.defineProperty;var Oe=(n,e,s)=>e in n?Ve(n,e,{enumerable:!0,configurable:!0,writable:!0,value:s}):n[e]=s;var de=(n,e,s)=>Oe(n,typeof e!="symbol"?e+"":e,s);import oe,{createContext as Ze,useContext as et,useEffect as ve,useState as E,useRef as me,useCallback as U}from"react";import{Linking as Le,Platform as N,Dimensions as tt,PixelRatio as rt}from"react-native";import ot from"react-native-play-install-referrer";var J=class{constructor(e){de(this,"baseUrl");de(this,"projectSecretKey");let s=typeof process<"u"&&process.env?.ENV_BASE_URL;this.baseUrl=s||"https://api.growthrail.dev",this.projectSecretKey=e.projectSecretKey}async request(e,s,o){let l={"Content-Type":"application/json","X-GrowthRail-ProjectSecret":this.projectSecretKey,Origin:this.baseUrl};try{let c=await fetch(`${this.baseUrl}${e}`,{method:s,headers:l,body:o?JSON.stringify(o):void 0});if(!c.ok){let m="";try{m=await c.text()}catch{}throw new Error(`GrowthRail API Error ${c.status} (${this.baseUrl}${e}): ${c.statusText} - ${m}`)}return c.json()}catch(c){throw console.error("GrowthRail SDK Error:",c),c}}async getNewUserExperience(){return this.request("/api/v1/sdk/new-user-experience","POST")}async initAppUser(e){return this.request("/api/v1/sdk/init-app-user","POST",{clientProvidedId:e})}async trackReferral(e,s){return this.request("/api/v1/sdk/track-referral","POST",{referralCode:e,rewardEventName:s})}async trackRewardEvent(e,s,o){return this.request("/api/v1/sdk/track-reward-event","POST",{refereeId:e,referralTrackingId:s,eventName:o})}async checkDeferredDeepLink(e){return this.request("/api/v1/sdk/match-link","POST",{fingerprint:e})}};import Q from"@react-native-async-storage/async-storage";var Z={TRACKED_REFERRAL:"growth-rail-tracked-referral",IS_FIRST_LAUNCH:"growth-rail-is-first-launch"},S=class{static async setTrackedReferral(e){await Q.setItem(Z.TRACKED_REFERRAL,e)}static async getTrackedReferral(){return await Q.getItem(Z.TRACKED_REFERRAL)}static async isFirstLaunch(){return await Q.getItem(Z.IS_FIRST_LAUNCH)===null?(await Q.setItem(Z.IS_FIRST_LAUNCH,"false"),!0):!1}};import t,{useEffect as De,useState as fe,useRef as ye}from"react";import{Modal as Ee,View as u,Text as x,StyleSheet as Re,TouchableOpacity as ee,Clipboard as Ue,ActivityIndicator as Ae,Linking as Ce,ScrollView as Ge,Platform as ke,Animated as P,Dimensions as ze}from"react-native";var{width:Te,height:ge}=ze.get("window"),ue=({visible:n,options:e,onClose:s})=>{let o=te(),[l,c]=fe(null),[m,a]=fe(!1),[g,p]=fe(!1),d=ye(new P.Value(0)).current,b=ye(new P.Value(0)).current,z=e?.title||"Invite Friends & Earn",v=e?.theme?.primaryColor||"#2563eb",M=e?.theme?.backgroundColor||"#ffffff",ie=e?.theme?.tintColor||"#000000",ne=e?.theme?.tintAlpha??.5,y=(e?.componentType||"modal")==="drawer",V=e?.position||"bottom-right",q="#111827",j="#6b7280";De(()=>{n?(l||ae(),P.parallel([P.timing(b,{toValue:1,duration:300,useNativeDriver:!0}),P.spring(d,{toValue:1,useNativeDriver:!0,tension:50,friction:8})]).start()):(d.setValue(0),b.setValue(0))},[n]);let $=()=>{P.parallel([P.timing(b,{toValue:0,duration:250,useNativeDriver:!0}),P.timing(d,{toValue:0,duration:250,useNativeDriver:!0})]).start(()=>{s()})},ae=async()=>{a(!0);try{if(o.isUserReady){let G=await o.getReferralLink();c(G||null)}}catch(G){console.error("GrowthRail: Failed to load referral link",G)}finally{a(!1)}},X=()=>{l&&(Ue.setString(l),p(!0),setTimeout(()=>p(!1),2e3))},L=G=>{if(!l)return;let I="",C=encodeURIComponent(l),H=encodeURIComponent("Check this out!");switch(G){case"twitter":I=`https://twitter.com/intent/tweet?url=${C}&text=${H}`;break;case"facebook":I=`https://www.facebook.com/sharer/sharer.php?u=${C}`;break;case"linkedin":I=`https://www.linkedin.com/sharing/share-offsite/?url=${C}`;break;case"whatsapp":I=`whatsapp://send?text=${H}%20${C}`;break;case"email":I=`mailto:?subject=Check this out&body=${H}%20${C}`;break}I&&Ce.openURL(I).catch(()=>{})},Y=()=>ie||"#000000",O=[];y?V.includes("right")?O=[{translateX:d.interpolate({inputRange:[0,1],outputRange:[Te,0]})}]:V.includes("left")?O=[{translateX:d.interpolate({inputRange:[0,1],outputRange:[-Te,0]})}]:O=[{translateY:d.interpolate({inputRange:[0,1],outputRange:[ge,0]})}]:O=[{scale:d.interpolate({inputRange:[0,1],outputRange:[.9,1]})},{translateY:d.interpolate({inputRange:[0,1],outputRange:[20,0]})}];let se=V.includes("top"),R=V.includes("right"),D=V.includes("left"),le=y?{position:"absolute",...se?{top:100}:{bottom:100},...R?{right:0}:D?{left:0}:{left:0,right:0},width:R||D?"85%":"100%",maxHeight:R||D?ge-200:"80%"}:{};return t.createElement(Ee,{visible:n,transparent:!0,animationType:"none",onRequestClose:$},t.createElement(u,{style:r.fullScreen},t.createElement(P.View,{style:[r.overlay,{backgroundColor:Y(),opacity:b.interpolate({inputRange:[0,1],outputRange:[0,ne]})}]},t.createElement(ee,{style:r.fullScreen,activeOpacity:1,onPress:$})),t.createElement(P.View,{style:[y?le:r.centeredModalContainer,{backgroundColor:M,transform:O},y&&R&&{borderTopLeftRadius:24,borderBottomLeftRadius:24},y&&D&&{borderTopRightRadius:24,borderBottomRightRadius:24},y&&!R&&!D&&V.includes("bottom")&&{borderTopLeftRadius:24,borderTopRightRadius:24},y&&!R&&!D&&V.includes("top")&&{borderBottomLeftRadius:24,borderBottomRightRadius:24},!y&&{borderRadius:24,opacity:d}]},t.createElement(u,{style:r.contentWrapper},y&&!R&&!D&&V.includes("bottom")&&t.createElement(u,{style:r.drawerHandle}),t.createElement(ee,{style:r.closeBtn,onPress:$},t.createElement(x,{style:r.closeIcon},"\u2715")),t.createElement(Ge,{contentContainerStyle:r.scrollContent,showsVerticalScrollIndicator:!1},t.createElement(u,{style:r.header},t.createElement(u,{style:r.iconLgContainer},t.createElement(u,{style:r.bowContainerLg},t.createElement(u,{style:[r.bowLoopLg,r.bowLeftLg,{borderColor:v}]}),t.createElement(u,{style:[r.bowLoopLg,r.bowRightLg,{borderColor:v}]})),t.createElement(u,{style:[r.giftLidLg,{backgroundColor:v}]}),t.createElement(u,{style:[r.giftBodyLg,{borderColor:v}]},t.createElement(u,{style:[r.ribbonVerticalLg,{backgroundColor:"#fff",opacity:.3}]}))),t.createElement(x,{style:[r.title,{color:q}]},z),t.createElement(x,{style:[r.subtitle,{color:j}]},e?.description||"Share your unique link and earn rewards for every friend who signs up.")),o.isUserReady?m?t.createElement(Ae,{size:"large",color:v,style:r.loader}):t.createElement(u,{style:r.mainContent},t.createElement(x,{style:r.label},"YOUR UNIQUE LINK"),t.createElement(u,{style:r.inputGroup},t.createElement(x,{numberOfLines:1,style:r.input},l||"Initializing..."),t.createElement(ee,{style:[r.copyBtn,{backgroundColor:g?"#10b981":v}],onPress:X},t.createElement(x,{style:r.copyBtnText},g?"Copied!":"Copy"))),t.createElement(u,{style:r.shareLabelContainer},t.createElement(u,{style:r.divider}),t.createElement(x,{style:r.shareLabel},"Share via"),t.createElement(u,{style:r.divider})),t.createElement(u,{style:r.socialContainer},t.createElement(_,{platform:"twitter",color:"#000000",onPress:()=>L("twitter"),icon:"\u{1D54F}"}),t.createElement(_,{platform:"facebook",color:"#1877F2",onPress:()=>L("facebook"),icon:"f"}),t.createElement(_,{platform:"linkedin",color:"#0A66C2",onPress:()=>L("linkedin"),icon:"in"}),t.createElement(_,{platform:"whatsapp",color:"#25D366",onPress:()=>L("whatsapp"),icon:"W"}),t.createElement(_,{platform:"email",color:"#888888",onPress:()=>L("email"),icon:"\u2709"}))):t.createElement(u,{style:r.loadingBox},t.createElement(x,{style:{color:j,textAlign:"center"}},"Please log in to view your referral dashboard.")),t.createElement(u,{style:r.footer},t.createElement(x,{style:r.poweredBy},"Powered by ",t.createElement(x,{style:r.brand,onPress:()=>Ce.openURL("https://growthrail.com")},"Growth Rail"))))))))},_=({color:n,onPress:e,icon:s})=>t.createElement(ee,{style:[r.socialBtn,{borderColor:"#e5e7eb"}],onPress:e},t.createElement(x,{style:[r.socialIcon,{color:n}]},s)),r=Re.create({fullScreen:{flex:1},overlay:{...Re.absoluteFillObject},centeredModalContainer:{width:"90%",maxWidth:400,alignSelf:"center",marginTop:ge*.15,overflow:"hidden",shadowColor:"#000",shadowOffset:{width:0,height:20},shadowOpacity:.25,shadowRadius:30,elevation:20},contentWrapper:{paddingTop:ke.OS==="ios"?20:0},drawerHandle:{width:40,height:4,backgroundColor:"#e5e7eb",borderRadius:2,alignSelf:"center",marginTop:12},scrollContent:{padding:32,alignItems:"center"},closeBtn:{position:"absolute",top:20,right:20,zIndex:10,width:32,height:32,borderRadius:16,backgroundColor:"#f3f4f6",justifyContent:"center",alignItems:"center"},closeIcon:{fontSize:14,color:"#9ca3af"},header:{alignItems:"center",marginBottom:28,width:"100%"},socialIcon:{fontSize:18,fontWeight:"bold"},title:{fontSize:22,fontWeight:"700",letterSpacing:-.5,marginBottom:8,textAlign:"center"},subtitle:{fontSize:14,lineHeight:20,textAlign:"center",paddingHorizontal:10},loadingBox:{padding:16,backgroundColor:"#f9fafb",borderRadius:12,width:"100%",alignItems:"center",borderWidth:1,borderColor:"#e5e7eb",marginTop:20},loader:{marginVertical:20},mainContent:{width:"100%"},label:{fontSize:12,fontWeight:"600",color:"#6b7280",marginBottom:8,letterSpacing:.5},inputGroup:{flexDirection:"row",alignItems:"center",backgroundColor:"#f9fafb",borderWidth:1,borderColor:"#e5e7eb",borderRadius:12,padding:6,marginBottom:24},input:{flex:1,paddingHorizontal:12,fontSize:14,color:"#111827",fontFamily:ke.OS==="ios"?"Menlo":"monospace"},copyBtn:{paddingVertical:8,paddingHorizontal:16,borderRadius:8,justifyContent:"center",alignItems:"center"},copyBtnText:{color:"#fff",fontSize:13,fontWeight:"600"},shareLabelContainer:{flexDirection:"row",alignItems:"center",marginBottom:16,marginTop:8},divider:{flex:1,height:1,backgroundColor:"#e5e7eb"},shareLabel:{marginHorizontal:12,fontSize:13,fontWeight:"500",color:"#6b7280"},socialContainer:{flexDirection:"row",justifyContent:"center",gap:12},socialBtn:{width:44,height:44,borderRadius:22,backgroundColor:"#fff",borderWidth:1,justifyContent:"center",alignItems:"center"},iconLgContainer:{width:60,height:60,justifyContent:"center",alignItems:"center",marginBottom:16},bowContainerLg:{flexDirection:"row",position:"absolute",top:2,zIndex:2},bowLoopLg:{width:20,height:16,borderWidth:3,borderColor:"#e5e7eb",borderRadius:10},bowLeftLg:{marginRight:-2,transform:[{rotate:"-15deg"}]},bowRightLg:{marginLeft:-2,transform:[{rotate:"15deg"}]},giftLidLg:{width:44,height:10,backgroundColor:"#f3f4f6",borderRadius:2,marginTop:12,zIndex:3},giftBodyLg:{width:36,height:24,borderWidth:3,borderTopWidth:0,borderBottomLeftRadius:4,borderBottomRightRadius:4,justifyContent:"center",alignItems:"center",marginTop:-2},ribbonVerticalLg:{width:4,height:"100%",opacity:.1},footer:{marginTop:32,alignItems:"center"},poweredBy:{fontSize:11,color:"#9ca3af"},brand:{fontWeight:"600",textDecorationLine:"underline"}});import B,{useEffect as Fe,useRef as We}from"react";import{TouchableOpacity as Ne,View as A,StyleSheet as Me,Animated as pe,Easing as je}from"react-native";var he=({onPress:n,options:e})=>{let s=e?.modal?.theme?.primaryColor||"#2563eb",o=e?.trigger?.position||"bottom-right",c=(e?.trigger?.displayMode||"floating")==="edge",m=o.includes("right"),a=o.includes("top"),g=We(new pe.Value(-1)).current;Fe(()=>{let z=()=>{g.setValue(-1),pe.timing(g,{toValue:2,duration:3e3,easing:je.linear,useNativeDriver:!0}).start(()=>{setTimeout(z,1e3)})};z()},[]);let p=g.interpolate({inputRange:[-1,2],outputRange:c?[-50,100]:[-60,120]}),d={"bottom-right":{bottom:100,right:0},"bottom-left":{bottom:100,left:0},"top-right":{top:100,right:0},"top-left":{top:100,left:0}};c||(d["bottom-right"]={bottom:30,right:20},d["bottom-left"]={bottom:30,left:20},d["top-right"]={top:60,right:20},d["top-left"]={top:60,left:20});let b=()=>B.createElement(A,{style:w.iconContainer},B.createElement(A,{style:w.bowContainer},B.createElement(A,{style:[w.bowLoop,w.bowLeft]}),B.createElement(A,{style:[w.bowLoop,w.bowRight]})),B.createElement(A,{style:w.giftLid}),B.createElement(A,{style:w.giftBody},B.createElement(A,{style:w.ribbonVertical})));return B.createElement(Ne,{style:[c?w.edgeButton:w.floatingButton,{backgroundColor:s},d[o],c&&(m?w.edgeRight:w.edgeLeft)],onPress:n,activeOpacity:.9},B.createElement(A,{style:w.content},b()),B.createElement(pe.View,{style:[w.shimmer,{transform:[{translateX:p},{skewX:"-15deg"}]}]}))},w=Me.create({floatingButton:{position:"absolute",width:60,height:60,borderRadius:30,justifyContent:"center",alignItems:"center",overflow:"hidden",shadowColor:"#000",shadowOffset:{width:0,height:8},shadowOpacity:.2,shadowRadius:12,elevation:8,zIndex:2147483646},edgeButton:{position:"absolute",width:50,height:50,justifyContent:"center",alignItems:"center",overflow:"hidden",shadowColor:"#000",shadowOffset:{width:0,height:4},shadowOpacity:.1,shadowRadius:8,elevation:4,zIndex:2147483646},edgeRight:{borderTopLeftRadius:8,borderBottomLeftRadius:8,paddingLeft:4},edgeLeft:{borderTopRightRadius:8,borderBottomRightRadius:8,paddingRight:4},content:{justifyContent:"center",alignItems:"center"},iconContainer:{width:28,height:28,justifyContent:"center",alignItems:"center"},bowContainer:{flexDirection:"row",position:"absolute",top:0,zIndex:2},bowLoop:{width:10,height:8,borderWidth:2,borderColor:"#fff",borderRadius:5},bowLeft:{marginRight:-1,transform:[{rotate:"-15deg"}]},bowRight:{marginLeft:-1,transform:[{rotate:"15deg"}]},giftLid:{width:22,height:5,backgroundColor:"#fff",borderRadius:1,marginTop:6,zIndex:3},giftBody:{width:18,height:12,borderWidth:2,borderColor:"#fff",borderTopWidth:0,borderBottomLeftRadius:2,borderBottomRightRadius:2,justifyContent:"center",alignItems:"center",marginTop:-1},ribbonVertical:{width:2,height:"100%",backgroundColor:"#fff",opacity:.8},shimmer:{position:"absolute",top:0,left:0,width:50,height:"100%",backgroundColor:"rgba(255, 255, 255, 0.25)"}});import W,{useEffect as $e,useRef as He,useState as _e}from"react";import{View as Ke,Text as we,StyleSheet as qe,Animated as re,Dimensions as Xe,TouchableOpacity as Ye,Platform as Je}from"react-native";var{width:Qe}=Xe.get("window"),xe=({visible:n,options:e,onClose:s})=>{let o=He(new re.Value(0)).current,[l,c]=_e(n),m=e.position.includes("bottom")?"bottom":"top",a=e.position.includes("left")?"left":e.position.includes("right")?"right":"center";if($e(()=>{n?(c(!0),re.spring(o,{toValue:1,useNativeDriver:!0,tension:50,friction:8}).start()):re.timing(o,{toValue:0,duration:250,useNativeDriver:!0}).start(()=>{c(!1)})},[n]),!l)return null;let g=o.interpolate({inputRange:[0,1],outputRange:[m==="top"?-100:100,0]}),p=o.interpolate({inputRange:[0,1],outputRange:[0,1]}),d={position:"absolute",[m]:Je.OS==="ios"?60:40,zIndex:9999};return a==="center"?(d.left=20,d.right=20,d.alignItems="center"):d[a]=20,W.createElement(re.View,{style:[d,{transform:[{translateY:g}],opacity:p}]},W.createElement(Ke,{style:[K.banner,{backgroundColor:e.themeColor||"#2563eb"}]},W.createElement(we,{style:K.icon},"\u{1F381}"),W.createElement(we,{style:K.text},e.text),W.createElement(Ye,{onPress:s,style:K.closeBtn},W.createElement(we,{style:K.closeIcon},"\u2715"))))},K=qe.create({banner:{flexDirection:"row",alignItems:"center",padding:12,paddingHorizontal:16,borderRadius:12,shadowColor:"#000",shadowOffset:{width:0,height:4},shadowOpacity:.15,shadowRadius:10,elevation:5,maxWidth:Qe-40},icon:{fontSize:18,marginRight:10},text:{color:"#fff",fontSize:14,fontWeight:"600",flex:1},closeBtn:{marginLeft:10,padding:4},closeIcon:{color:"rgba(255, 255, 255, 0.8)",fontSize:14,fontWeight:"bold"}});var Ie=Ze(void 0),it=({children:n,userId:e,...s})=>{let[o,l]=E(!1),[c,m]=E(!1),[a,g]=E(null),p=me(new J(s)),d=me(!1),b=me(null),[z,v]=E(!1),[M,ie]=E(),[ne,be]=E(!1),[y,V]=E(),[q,j]=E(!1),[$,ae]=E(),X=U(()=>{let{width:f,height:i}=tt.get("window"),h=Intl.DateTimeFormat().resolvedOptions().locale,k=rt.get(),T,F;if(N.OS==="android"){let ce=N.constants;T=ce.Model,F=ce.Brand||ce.Manufacturer}return{os:N.OS,platform:N.OS,osVersion:String(N.Version),screenWidth:f,screenHeight:i,timezoneOffsetInMinutes:String(new Date().getTimezoneOffset()),locale:h,language:h,deviceModel:T,deviceBrand:F,pixelRatio:k}},[]),L=U(async(f,i)=>{let h=await p.current.trackReferral(f,i);return await S.setTrackedReferral(h.referralTrackingId),h},[]),Y=U(async f=>{try{let i=f.match(/[?&]referralCode=([^&]+)/);i&&(console.log("GrowthRail: Tracking referral from deep link",i[1]),await L(i[1]))}catch(i){console.warn("GrowthRail: Error handling deep link",i)}},[L]),O=U(async()=>{try{let f=X(),{referralTrackingId:i}=await p.current.checkDeferredDeepLink(f);i&&(console.log("GrowthRail: Found deferred referral via fingerprinting",i),await S.setTrackedReferral(i))}catch(f){console.warn("GrowthRail: Fingerprint check failed",f)}},[X]),se=U(()=>new Promise(f=>{ot.getInstallReferrerInfo(async(i,h)=>{if(!h&&i&&i.installReferrer)try{let T=decodeURIComponent(i.installReferrer).match(/[?&]referralCode=([^&]+)/);if(T){let{referralTrackingId:F}=await L(T[1]);await S.setTrackedReferral(F),console.log("GrowthRail: Tracked referral via Install Referrer")}}catch(k){console.warn("GrowthRail: Failed to process install referrer",k)}else await O();f()})}),[L,O]),R=U(async f=>{if(a?.id===f&&c)return a;let i=(async()=>{try{let h=await p.current.initAppUser(f),k={...h,id:f};return g(k),m(!0),h.referrerExperience?.trigger?.show&&be(!0),k}catch(h){throw b.current=null,h}})();return b.current=i,i},[a,c]),D=U(async f=>{let i=a;!i&&b.current&&(i=await b.current);let h=i?.id||e;if(!h)throw new Error("GrowthRail: User must be initialized before tracking a reward event.");let k=await S.getTrackedReferral();if(!k){console.warn("GrowthRail: No referral tracking ID found. Reward event not attributed.");return}return p.current.trackRewardEvent(h,k,f)},[a,e]),le=U(async()=>await S.getTrackedReferral(),[]),G=U(async()=>{if(a)return a.referralLink;if(b.current)return(await b.current).referralLink},[a]);ve(()=>{if(d.current)return;d.current=!0,(async()=>{let i=await Le.getInitialURL();i&&await Y(i);let h=Le.addEventListener("url",({url:T})=>Y(T));await S.isFirstLaunch()&&(N.OS==="android"?await se():await O()),e&&await R(e);try{let T=await p.current.getNewUserExperience(),F=await S.getTrackedReferral();T.banner?.show&&F&&(ae(T.banner),j(!0))}catch{}return l(!0),()=>h.remove()})()},[]),ve(()=>{o&&e&&a?.id!==e&&R(e)},[e,o]);let I={isInitialized:o,isUserReady:c,currentUser:a,referralCode:a?.referralCode,referralLink:a?.referralLink,showDashboard:f=>{ie(f),v(!0)},hideDashboard:()=>v(!1),initUser:R,trackReward:D,getReferralTrackingId:le,getReferralLink:G};if(!o)return null;let C=a?.referrerExperience,H={...C?.modal,...M,position:C?.trigger?.position||M?.position||"bottom-right",theme:{...C?.modal?.theme||{},...M?.theme||{}}},Be={...C,...y,trigger:{...C?.trigger||{},...y?.trigger||{}}};return oe.createElement(Ie.Provider,{value:I},n,oe.createElement(ue,{visible:z,options:H,onClose:()=>v(!1)}),ne&&oe.createElement(he,{options:Be,onPress:()=>I.showDashboard()}),q&&oe.createElement(xe,{visible:q,options:$,onClose:()=>j(!1)}))},te=()=>{let n=et(Ie);if(!n)throw new Error("useGrowthRail must be used within a GrowthRailProvider");return n};import{useState as Se,useCallback as Pe}from"react";var nt=()=>{let[n,e]=Se(!1),[s,o]=Se(null),l=te(),c=Pe(async a=>{e(!0),o(null);try{return await l.initUser(a)}catch(g){let p=g instanceof Error?g:new Error(String(g));throw o(p),p}finally{e(!1)}},[l]),m=Pe(async a=>{e(!0),o(null);try{await l.trackReward(a)}catch(g){let p=g instanceof Error?g:new Error(String(g));throw o(p),p}finally{e(!1)}},[l]);return{initAppUser:c,trackRewardEvent:m,showReferralDashboard:l.showDashboard,hideReferralDashboard:l.hideDashboard,getReferralTrackingId:l.getReferralTrackingId,getReferralLink:l.getReferralLink,isLoading:n,isInitialized:l.isInitialized,isUserReady:l.isUserReady,error:s}};export{it as GrowthRailProvider,ue as ReferralDashboard,he as TriggerButton,nt as useGrowthRail};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@growth-rail/react-native",
3
- "version": "1.0.0",
3
+ "version": "2.0.0",
4
4
  "description": "Growth Rail SDK for React Native",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",