mixpanel-react-native 3.1.2 → 3.2.0-beta.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/.claude/settings.local.json +12 -1
- package/.github/dependabot.yml +7 -0
- package/.github/workflows/node.js.yml +24 -1
- package/.vscode/settings.json +2 -1
- package/MixpanelReactNative.podspec +1 -1
- package/Samples/MixpanelExample/ios/MixpanelExample.xcworkspace/contents.xcworkspacedata +10 -0
- package/Samples/MixpanelExample/ios/Podfile.lock +1996 -0
- package/Samples/MixpanelStarter/.bundle/config +2 -0
- package/Samples/MixpanelStarter/.env.example +4 -0
- package/Samples/MixpanelStarter/.eslintrc.js +4 -0
- package/Samples/MixpanelStarter/.prettierrc.js +5 -0
- package/Samples/MixpanelStarter/.watchmanconfig +1 -0
- package/Samples/MixpanelStarter/App.tsx +10 -0
- package/Samples/MixpanelStarter/CLAUDE.md +538 -0
- package/Samples/MixpanelStarter/Gemfile +16 -0
- package/Samples/MixpanelStarter/INTEGRATION_GUIDE.md +606 -0
- package/Samples/MixpanelStarter/README.md +406 -0
- package/Samples/MixpanelStarter/__tests__/MixpanelContext.test.tsx +63 -0
- package/Samples/MixpanelStarter/android/app/build.gradle +119 -0
- package/Samples/MixpanelStarter/android/app/debug.keystore +0 -0
- package/Samples/MixpanelStarter/android/app/proguard-rules.pro +10 -0
- package/Samples/MixpanelStarter/android/app/src/main/AndroidManifest.xml +27 -0
- package/Samples/MixpanelStarter/android/app/src/main/java/com/mixpanelstarter/MainActivity.kt +22 -0
- package/Samples/MixpanelStarter/android/app/src/main/java/com/mixpanelstarter/MainApplication.kt +27 -0
- package/Samples/MixpanelStarter/android/app/src/main/res/drawable/rn_edit_text_material.xml +37 -0
- package/Samples/MixpanelStarter/android/app/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
- package/Samples/MixpanelStarter/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png +0 -0
- package/Samples/MixpanelStarter/android/app/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
- package/Samples/MixpanelStarter/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png +0 -0
- package/Samples/MixpanelStarter/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
- package/Samples/MixpanelStarter/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png +0 -0
- package/Samples/MixpanelStarter/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
- package/Samples/MixpanelStarter/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png +0 -0
- package/Samples/MixpanelStarter/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
- package/Samples/MixpanelStarter/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png +0 -0
- package/Samples/MixpanelStarter/android/app/src/main/res/values/strings.xml +3 -0
- package/Samples/MixpanelStarter/android/app/src/main/res/values/styles.xml +9 -0
- package/Samples/MixpanelStarter/android/build.gradle +21 -0
- package/Samples/MixpanelStarter/android/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/Samples/MixpanelStarter/android/gradle/wrapper/gradle-wrapper.properties +7 -0
- package/Samples/MixpanelStarter/android/gradle.properties +44 -0
- package/Samples/MixpanelStarter/android/gradlew +251 -0
- package/Samples/MixpanelStarter/android/gradlew.bat +99 -0
- package/Samples/MixpanelStarter/android/settings.gradle +6 -0
- package/Samples/MixpanelStarter/app.json +4 -0
- package/Samples/MixpanelStarter/babel.config.js +14 -0
- package/Samples/MixpanelStarter/index.js +9 -0
- package/Samples/MixpanelStarter/ios/.xcode.env +11 -0
- package/Samples/MixpanelStarter/ios/MixpanelStarter/AppDelegate.swift +48 -0
- package/Samples/MixpanelStarter/ios/MixpanelStarter/Images.xcassets/AppIcon.appiconset/Contents.json +53 -0
- package/Samples/MixpanelStarter/ios/MixpanelStarter/Images.xcassets/Contents.json +6 -0
- package/Samples/MixpanelStarter/ios/MixpanelStarter/Info.plist +55 -0
- package/Samples/MixpanelStarter/ios/MixpanelStarter/LaunchScreen.storyboard +47 -0
- package/Samples/MixpanelStarter/ios/MixpanelStarter/PrivacyInfo.xcprivacy +38 -0
- package/Samples/MixpanelStarter/ios/MixpanelStarter.xcodeproj/project.pbxproj +482 -0
- package/Samples/MixpanelStarter/ios/MixpanelStarter.xcodeproj/xcshareddata/xcschemes/MixpanelStarter.xcscheme +88 -0
- package/Samples/MixpanelStarter/ios/MixpanelStarter.xcworkspace/contents.xcworkspacedata +10 -0
- package/Samples/MixpanelStarter/ios/Podfile +34 -0
- package/Samples/MixpanelStarter/ios/Podfile.lock +2839 -0
- package/Samples/MixpanelStarter/jest.config.js +3 -0
- package/Samples/MixpanelStarter/metro.config.js +42 -0
- package/Samples/MixpanelStarter/package-lock.json +12141 -0
- package/Samples/MixpanelStarter/package.json +51 -0
- package/Samples/MixpanelStarter/src/@types/env.d.ts +3 -0
- package/Samples/MixpanelStarter/src/App.tsx +83 -0
- package/Samples/MixpanelStarter/src/components/ActionButton.tsx +92 -0
- package/Samples/MixpanelStarter/src/components/ErrorBoundary.tsx +81 -0
- package/Samples/MixpanelStarter/src/components/EventTrackingLog.tsx +163 -0
- package/Samples/MixpanelStarter/src/components/FlagCard.tsx +199 -0
- package/Samples/MixpanelStarter/src/components/InfoCard.tsx +77 -0
- package/Samples/MixpanelStarter/src/components/TestResultDisplay.tsx +181 -0
- package/Samples/MixpanelStarter/src/constants/tracking.ts +77 -0
- package/Samples/MixpanelStarter/src/contexts/MixpanelContext.tsx +159 -0
- package/Samples/MixpanelStarter/src/screens/FeatureFlagsScreen.tsx +1011 -0
- package/Samples/MixpanelStarter/src/screens/HomeScreen.tsx +307 -0
- package/Samples/MixpanelStarter/src/screens/OnboardingScreen.tsx +253 -0
- package/Samples/MixpanelStarter/src/screens/SettingsScreen.tsx +316 -0
- package/Samples/MixpanelStarter/src/types/flags.types.ts +42 -0
- package/Samples/MixpanelStarter/src/types/mixpanel.types.ts +26 -0
- package/Samples/MixpanelStarter/tsconfig.json +13 -0
- package/__tests__/flags.test.js +730 -0
- package/__tests__/index.test.js +7 -3
- package/__tests__/jest_setup.js +18 -0
- package/android/build.gradle +1 -1
- package/android/src/main/java/com/mixpanel/reactnative/MixpanelReactNativeModule.java +272 -2
- package/index.d.ts +64 -1
- package/index.js +42 -3
- package/ios/MixpanelReactNative.m +19 -1
- package/ios/MixpanelReactNative.swift +183 -5
- package/javascript/mixpanel-flags-js.js +463 -0
- package/javascript/mixpanel-flags.js +290 -0
- package/javascript/mixpanel-main.js +13 -1
- package/package.json +2 -2
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
import React, {useState, useEffect} from 'react';
|
|
2
|
+
import {View, Text, StyleSheet, ScrollView, Switch, Alert} from 'react-native';
|
|
3
|
+
import {useMixpanel} from '../contexts/MixpanelContext';
|
|
4
|
+
import {ActionButton} from '../components/ActionButton';
|
|
5
|
+
import {InfoCard} from '../components/InfoCard';
|
|
6
|
+
import {Events} from '../constants/tracking';
|
|
7
|
+
|
|
8
|
+
export const SettingsScreen: React.FC = () => {
|
|
9
|
+
const {mixpanel, isInitialized, track, reset, flush} = useMixpanel();
|
|
10
|
+
const [trackingEnabled, setTrackingEnabled] = useState(true);
|
|
11
|
+
const [distinctId, setDistinctId] = useState<string>('');
|
|
12
|
+
const [loading, setLoading] = useState(false);
|
|
13
|
+
const [sdkVersion, setSdkVersion] = useState<string>('');
|
|
14
|
+
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
// Track screen view
|
|
17
|
+
if (isInitialized) {
|
|
18
|
+
track(Events.SCREEN_VIEWED, {
|
|
19
|
+
screen_name: 'Settings',
|
|
20
|
+
timestamp: new Date().toISOString(),
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
}, [isInitialized, track]);
|
|
24
|
+
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
// Get current settings
|
|
27
|
+
const fetchSettings = async () => {
|
|
28
|
+
if (mixpanel && isInitialized) {
|
|
29
|
+
try {
|
|
30
|
+
// Get distinct ID
|
|
31
|
+
const id = await mixpanel.getDistinctId();
|
|
32
|
+
setDistinctId(id);
|
|
33
|
+
|
|
34
|
+
// Check opt-out status
|
|
35
|
+
const hasOptedOut = await mixpanel.hasOptedOutTracking();
|
|
36
|
+
setTrackingEnabled(!hasOptedOut);
|
|
37
|
+
} catch (error) {
|
|
38
|
+
console.error('Failed to fetch settings:', error);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
fetchSettings();
|
|
43
|
+
}, [mixpanel, isInitialized]);
|
|
44
|
+
|
|
45
|
+
const handleToggleTracking = async (value: boolean) => {
|
|
46
|
+
setLoading(true);
|
|
47
|
+
try {
|
|
48
|
+
if (value) {
|
|
49
|
+
// Opt in to tracking
|
|
50
|
+
await mixpanel?.optInTracking();
|
|
51
|
+
track(Events.TRACKING_OPTED_IN, {
|
|
52
|
+
timestamp: new Date().toISOString(),
|
|
53
|
+
});
|
|
54
|
+
Alert.alert(
|
|
55
|
+
'Tracking Enabled',
|
|
56
|
+
'Analytics tracking has been enabled. Your events will now be sent to Mixpanel.',
|
|
57
|
+
);
|
|
58
|
+
} else {
|
|
59
|
+
// Track opt-out event before opting out
|
|
60
|
+
track(Events.TRACKING_OPTED_OUT, {
|
|
61
|
+
timestamp: new Date().toISOString(),
|
|
62
|
+
});
|
|
63
|
+
// Flush events before opting out
|
|
64
|
+
await mixpanel?.flush();
|
|
65
|
+
// Opt out of tracking
|
|
66
|
+
await mixpanel?.optOutTracking();
|
|
67
|
+
Alert.alert(
|
|
68
|
+
'Tracking Disabled',
|
|
69
|
+
'Analytics tracking has been disabled. No events will be sent until you opt back in.',
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
setTrackingEnabled(value);
|
|
73
|
+
} catch (error) {
|
|
74
|
+
console.error('Failed to toggle tracking:', error);
|
|
75
|
+
Alert.alert('Error', 'Failed to update tracking preference');
|
|
76
|
+
} finally {
|
|
77
|
+
setLoading(false);
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const handleResetData = () => {
|
|
82
|
+
Alert.alert(
|
|
83
|
+
'Reset All Data',
|
|
84
|
+
'This will clear your distinct ID, user profile, and all local data. Are you sure?',
|
|
85
|
+
[
|
|
86
|
+
{text: 'Cancel', style: 'cancel'},
|
|
87
|
+
{
|
|
88
|
+
text: 'Reset',
|
|
89
|
+
style: 'destructive',
|
|
90
|
+
onPress: async () => {
|
|
91
|
+
setLoading(true);
|
|
92
|
+
try {
|
|
93
|
+
// Track reset event before resetting
|
|
94
|
+
track(Events.DATA_RESET, {
|
|
95
|
+
timestamp: new Date().toISOString(),
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
// Flush events to ensure reset event is sent
|
|
99
|
+
await flush();
|
|
100
|
+
|
|
101
|
+
// Reset all data
|
|
102
|
+
reset();
|
|
103
|
+
|
|
104
|
+
Alert.alert(
|
|
105
|
+
'Data Reset',
|
|
106
|
+
'All your data has been cleared. You now have a new anonymous ID.',
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
// Fetch new distinct ID
|
|
110
|
+
const newId = await mixpanel?.getDistinctId();
|
|
111
|
+
if (newId) {
|
|
112
|
+
setDistinctId(newId);
|
|
113
|
+
}
|
|
114
|
+
} catch (error) {
|
|
115
|
+
console.error('Failed to reset data:', error);
|
|
116
|
+
Alert.alert('Error', 'Failed to reset data');
|
|
117
|
+
} finally {
|
|
118
|
+
setLoading(false);
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
],
|
|
123
|
+
);
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
const handleFlushEvents = async () => {
|
|
127
|
+
setLoading(true);
|
|
128
|
+
try {
|
|
129
|
+
// Track flush event
|
|
130
|
+
track(Events.EVENTS_FLUSHED, {
|
|
131
|
+
timestamp: new Date().toISOString(),
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
// Flush all queued events
|
|
135
|
+
await flush();
|
|
136
|
+
|
|
137
|
+
Alert.alert(
|
|
138
|
+
'Events Flushed',
|
|
139
|
+
'All queued events have been sent to Mixpanel immediately.',
|
|
140
|
+
);
|
|
141
|
+
} catch (error) {
|
|
142
|
+
console.error('Failed to flush events:', error);
|
|
143
|
+
Alert.alert('Error', 'Failed to flush events');
|
|
144
|
+
} finally {
|
|
145
|
+
setLoading(false);
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
const handleViewDistinctId = () => {
|
|
150
|
+
Alert.alert('Your Distinct ID', distinctId || 'Loading...');
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
return (
|
|
154
|
+
<ScrollView style={styles.container} contentContainerStyle={styles.content}>
|
|
155
|
+
<View style={styles.header}>
|
|
156
|
+
<Text style={styles.title}>Settings</Text>
|
|
157
|
+
<Text style={styles.subtitle}>Privacy controls and data management</Text>
|
|
158
|
+
</View>
|
|
159
|
+
|
|
160
|
+
<InfoCard title="Your Distinct ID" content={distinctId || 'Loading...'} />
|
|
161
|
+
|
|
162
|
+
<View style={styles.section}>
|
|
163
|
+
<Text style={styles.sectionTitle}>Privacy Controls</Text>
|
|
164
|
+
|
|
165
|
+
<View style={styles.preferenceRow}>
|
|
166
|
+
<View style={styles.preferenceLabel}>
|
|
167
|
+
<Text style={styles.preferenceTitle}>Analytics Tracking</Text>
|
|
168
|
+
<Text style={styles.preferenceSubtitle}>
|
|
169
|
+
{trackingEnabled
|
|
170
|
+
? 'Events are being sent to Mixpanel'
|
|
171
|
+
: 'Tracking is disabled (GDPR compliant)'}
|
|
172
|
+
</Text>
|
|
173
|
+
</View>
|
|
174
|
+
<Switch
|
|
175
|
+
value={trackingEnabled}
|
|
176
|
+
onValueChange={handleToggleTracking}
|
|
177
|
+
disabled={!isInitialized || loading}
|
|
178
|
+
/>
|
|
179
|
+
</View>
|
|
180
|
+
|
|
181
|
+
<ActionButton
|
|
182
|
+
title="Reset All Data"
|
|
183
|
+
onPress={handleResetData}
|
|
184
|
+
variant="danger"
|
|
185
|
+
disabled={!isInitialized || loading}
|
|
186
|
+
loading={loading}
|
|
187
|
+
style={styles.actionButton}
|
|
188
|
+
/>
|
|
189
|
+
</View>
|
|
190
|
+
|
|
191
|
+
<View style={styles.section}>
|
|
192
|
+
<Text style={styles.sectionTitle}>Developer Tools</Text>
|
|
193
|
+
|
|
194
|
+
<ActionButton
|
|
195
|
+
title="Flush Events Now"
|
|
196
|
+
onPress={handleFlushEvents}
|
|
197
|
+
variant="secondary"
|
|
198
|
+
disabled={!isInitialized || loading}
|
|
199
|
+
loading={loading}
|
|
200
|
+
style={styles.actionButton}
|
|
201
|
+
/>
|
|
202
|
+
|
|
203
|
+
<ActionButton
|
|
204
|
+
title="View Distinct ID"
|
|
205
|
+
onPress={handleViewDistinctId}
|
|
206
|
+
variant="secondary"
|
|
207
|
+
disabled={!isInitialized}
|
|
208
|
+
style={styles.actionButton}
|
|
209
|
+
/>
|
|
210
|
+
</View>
|
|
211
|
+
|
|
212
|
+
<View style={styles.section}>
|
|
213
|
+
<Text style={styles.sectionTitle}>About</Text>
|
|
214
|
+
|
|
215
|
+
<InfoCard
|
|
216
|
+
title="SDK Information"
|
|
217
|
+
content={{
|
|
218
|
+
'SDK Version': '3.1.2',
|
|
219
|
+
'Implementation Mode': 'Native (iOS: Swift, Android: Java)',
|
|
220
|
+
'Tracking Status': trackingEnabled ? 'Enabled' : 'Disabled',
|
|
221
|
+
}}
|
|
222
|
+
/>
|
|
223
|
+
</View>
|
|
224
|
+
|
|
225
|
+
<InfoCard
|
|
226
|
+
title="What's Happening?"
|
|
227
|
+
content={`Privacy Controls:
|
|
228
|
+
• optInTracking() / optOutTracking() controls data collection
|
|
229
|
+
• Complies with GDPR and privacy regulations
|
|
230
|
+
• hasOptedOutTracking() checks current status
|
|
231
|
+
• When opted out, no events are sent to Mixpanel
|
|
232
|
+
|
|
233
|
+
Data Reset:
|
|
234
|
+
• reset() clears all local data and user identity
|
|
235
|
+
• Generates a new anonymous distinct ID
|
|
236
|
+
• Use this for logout or "forget me" functionality
|
|
237
|
+
• Previous events remain in Mixpanel (not deleted)
|
|
238
|
+
|
|
239
|
+
Manual Flush:
|
|
240
|
+
• flush() immediately sends all queued events
|
|
241
|
+
• Useful before app termination or user logout
|
|
242
|
+
• Events are normally flushed automatically every 60s
|
|
243
|
+
• Ensures data is sent even if app is force-closed
|
|
244
|
+
|
|
245
|
+
Distinct ID:
|
|
246
|
+
• Every user has a unique distinct ID
|
|
247
|
+
• Anonymous users get an auto-generated UUID
|
|
248
|
+
• Identified users get their custom ID (email, etc.)
|
|
249
|
+
• Used to associate events with individual users`}
|
|
250
|
+
style={styles.infoCard}
|
|
251
|
+
/>
|
|
252
|
+
</ScrollView>
|
|
253
|
+
);
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
const styles = StyleSheet.create({
|
|
257
|
+
container: {
|
|
258
|
+
flex: 1,
|
|
259
|
+
backgroundColor: '#fff',
|
|
260
|
+
},
|
|
261
|
+
content: {
|
|
262
|
+
padding: 20,
|
|
263
|
+
},
|
|
264
|
+
header: {
|
|
265
|
+
marginBottom: 20,
|
|
266
|
+
},
|
|
267
|
+
title: {
|
|
268
|
+
fontSize: 24,
|
|
269
|
+
fontWeight: 'bold',
|
|
270
|
+
color: '#333',
|
|
271
|
+
marginBottom: 8,
|
|
272
|
+
},
|
|
273
|
+
subtitle: {
|
|
274
|
+
fontSize: 16,
|
|
275
|
+
color: '#666',
|
|
276
|
+
},
|
|
277
|
+
section: {
|
|
278
|
+
marginTop: 20,
|
|
279
|
+
marginBottom: 10,
|
|
280
|
+
},
|
|
281
|
+
sectionTitle: {
|
|
282
|
+
fontSize: 18,
|
|
283
|
+
fontWeight: '600',
|
|
284
|
+
color: '#333',
|
|
285
|
+
marginBottom: 16,
|
|
286
|
+
},
|
|
287
|
+
preferenceRow: {
|
|
288
|
+
flexDirection: 'row',
|
|
289
|
+
justifyContent: 'space-between',
|
|
290
|
+
alignItems: 'center',
|
|
291
|
+
paddingVertical: 12,
|
|
292
|
+
paddingHorizontal: 15,
|
|
293
|
+
backgroundColor: '#f9f9f9',
|
|
294
|
+
borderRadius: 8,
|
|
295
|
+
marginBottom: 16,
|
|
296
|
+
},
|
|
297
|
+
preferenceLabel: {
|
|
298
|
+
flex: 1,
|
|
299
|
+
},
|
|
300
|
+
preferenceTitle: {
|
|
301
|
+
fontSize: 16,
|
|
302
|
+
fontWeight: '500',
|
|
303
|
+
color: '#333',
|
|
304
|
+
marginBottom: 4,
|
|
305
|
+
},
|
|
306
|
+
preferenceSubtitle: {
|
|
307
|
+
fontSize: 13,
|
|
308
|
+
color: '#666',
|
|
309
|
+
},
|
|
310
|
+
actionButton: {
|
|
311
|
+
marginBottom: 12,
|
|
312
|
+
},
|
|
313
|
+
infoCard: {
|
|
314
|
+
marginTop: 10,
|
|
315
|
+
},
|
|
316
|
+
});
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export interface MixpanelFlagVariant {
|
|
2
|
+
key: string;
|
|
3
|
+
value: any;
|
|
4
|
+
experimentID?: string;
|
|
5
|
+
isExperimentActive?: boolean;
|
|
6
|
+
isQATester?: boolean;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface TestResult {
|
|
10
|
+
id: string;
|
|
11
|
+
timestamp: Date;
|
|
12
|
+
method: string;
|
|
13
|
+
flagName: string;
|
|
14
|
+
fallback: any;
|
|
15
|
+
result: any;
|
|
16
|
+
resultType: string;
|
|
17
|
+
executionTime: number;
|
|
18
|
+
usedFallback: boolean;
|
|
19
|
+
error?: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface TrackedEvent {
|
|
23
|
+
id: string;
|
|
24
|
+
timestamp: Date;
|
|
25
|
+
eventName: string;
|
|
26
|
+
properties: Record<string, any>;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export type TestMode = 'sync' | 'async' | 'edge' | 'coercion';
|
|
30
|
+
|
|
31
|
+
export type ValueType = 'string' | 'number' | 'boolean' | 'object' | 'array' | 'null' | 'undefined';
|
|
32
|
+
|
|
33
|
+
export interface FlagInfo {
|
|
34
|
+
key: string;
|
|
35
|
+
value: any;
|
|
36
|
+
valueType: ValueType;
|
|
37
|
+
variantKey: string;
|
|
38
|
+
experimentID?: string;
|
|
39
|
+
isExperimentActive?: boolean;
|
|
40
|
+
isQATester?: boolean;
|
|
41
|
+
lastAccessed?: Date;
|
|
42
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import {Mixpanel} from 'mixpanel-react-native';
|
|
2
|
+
|
|
3
|
+
export interface MixpanelContextValue {
|
|
4
|
+
mixpanel: Mixpanel | null;
|
|
5
|
+
isInitialized: boolean;
|
|
6
|
+
isLoading: boolean;
|
|
7
|
+
error: Error | null;
|
|
8
|
+
|
|
9
|
+
// Convenience methods
|
|
10
|
+
track: (eventName: string, properties?: Record<string, any>) => void;
|
|
11
|
+
identify: (distinctId: string) => void;
|
|
12
|
+
alias: (alias: string, distinctId?: string) => Promise<void>;
|
|
13
|
+
reset: () => void;
|
|
14
|
+
flush: () => Promise<void>;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface UserProfile {
|
|
18
|
+
$email?: string;
|
|
19
|
+
$name?: string;
|
|
20
|
+
signup_date?: string;
|
|
21
|
+
[key: string]: any;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface EventProperties {
|
|
25
|
+
[key: string]: any;
|
|
26
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "@react-native/typescript-config",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"strict": true,
|
|
5
|
+
"baseUrl": ".",
|
|
6
|
+
"paths": {
|
|
7
|
+
"@env": ["src/@types/env.d.ts"]
|
|
8
|
+
},
|
|
9
|
+
"typeRoots": ["./node_modules/@types", "./src/@types"]
|
|
10
|
+
},
|
|
11
|
+
"include": ["**/*.ts", "**/*.tsx"],
|
|
12
|
+
"exclude": ["**/node_modules", "**/Pods"]
|
|
13
|
+
}
|