mixpanel-react-native 3.2.0-beta.2 → 3.2.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,19 @@
1
1
  #
2
2
 
3
+ ## [v3.1.3](https://github.com/mixpanel/mixpanel-react-native/tree/v3.1.3) (2025-12-15)
4
+
5
+ ### Fixes
6
+
7
+ - Fix getUseIpAddressForGeolocation always returning true [\#316](https://github.com/mixpanel/mixpanel-react-native/pull/316)
8
+
9
+ ## [v3.2.0-beta.2](https://github.com/mixpanel/mixpanel-react-native/tree/v3.2.0-beta.2) (2025-11-07)
10
+
11
+ ## [v3.2.0-beta.1](https://github.com/mixpanel/mixpanel-react-native/tree/v3.2.0-beta.1) (2025-11-07)
12
+
13
+ ## [v3.2.0-beta.0](https://github.com/mixpanel/mixpanel-react-native/tree/v3.2.0-beta.0) (2025-11-07)
14
+
15
+ #
16
+
3
17
  ## [v3.1.2](https://github.com/mixpanel/mixpanel-react-native/tree/v3.1.2) (2025-06-05)
4
18
 
5
19
  ### Fixes
@@ -529,6 +543,8 @@ This major release removes all remaining calls to Mixpanel's `/decide` API endpo
529
543
 
530
544
 
531
545
 
546
+
547
+
532
548
 
533
549
 
534
550
 
@@ -10,7 +10,7 @@ Pod::Spec.new do |s|
10
10
  s.license = package['license']
11
11
  s.author = { 'Mixpanel, Inc' => 'support@mixpanel.com' }
12
12
  s.homepage = package['homepage']
13
- s.platform = :ios, "11.0"
13
+ s.platform = :ios, "12.0"
14
14
  s.swift_version = '5.0'
15
15
  s.source = { :git => "https://github.com/mixpanel/mixpanel-react-native.git", :tag => s.version }
16
16
  s.source_files = "ios/*.{swift,h,m}"
package/README.md CHANGED
@@ -47,7 +47,15 @@ Mixpanel's React Native SDK is a wrapper around Mixpanel’s native iOS and Andr
47
47
  npm install mixpanel-react-native
48
48
  ```
49
49
 
50
- 2. Under your application's ios folder, run
50
+ 2. Install AsyncStorage (required for data persistence):
51
+
52
+ ```
53
+ npm install @react-native-async-storage/async-storage
54
+ ```
55
+
56
+ > **Note:** Starting from v3.2.0, `@react-native-async-storage/async-storage` is a peer dependency. This allows your project to use either v1.x or v2.x, avoiding conflicts with frameworks like Expo 52+.
57
+
58
+ 3. Under your application's ios folder, run
51
59
 
52
60
  ```
53
61
  pod install
@@ -55,7 +63,7 @@ pod install
55
63
 
56
64
  Please note: You do not need to update your Podfile to add Mixpanel.
57
65
 
58
- 3. Since Xcode 12.5, there is a known swift compile issue, please refer to this **[workaround](https://github.com/mixpanel/mixpanel-react-native/issues/43#issuecomment-829599732)**. However the compile issue has been resolved in Xcode 13.2.1+, there is no extra step required as long as you upgrade to Xcode 13.2.1+.
66
+ 4. Since Xcode 12.5, there is a known swift compile issue, please refer to this **[workaround](https://github.com/mixpanel/mixpanel-react-native/issues/43#issuecomment-829599732)**. However the compile issue has been resolved in Xcode 13.2.1+, there is no extra step required as long as you upgrade to Xcode 13.2.1+.
59
67
 
60
68
  ### 2. Initialize Mixpanel
61
69
 
@@ -115,35 +123,6 @@ const SampleApp = () => {
115
123
  export default SampleApp;
116
124
  ```
117
125
 
118
- ### Feature Flags (Beta - 3.2.0-beta.1+)
119
-
120
- Control features dynamically and run A/B tests with Mixpanel Feature Flags. **Native mode only** (iOS/Android) in beta.
121
-
122
- #### Quick Start
123
-
124
- ```js
125
- // Enable during initialization
126
- await mixpanel.init(false, {}, 'https://api.mixpanel.com', true, {
127
- enabled: true,
128
- context: { platform: 'mobile' } // Optional targeting context
129
- });
130
-
131
- // Check if feature is enabled
132
- if (mixpanel.flags.areFlagsReady()) {
133
- const showNewUI = mixpanel.flags.isEnabledSync('new-feature', false);
134
- const buttonColor = mixpanel.flags.getVariantValueSync('button-color', 'blue');
135
- }
136
- ```
137
-
138
- #### Key Methods
139
-
140
- - `areFlagsReady()` - Check if flags are loaded
141
- - `isEnabledSync(name, fallback)` - Check if feature is enabled
142
- - `getVariantValueSync(name, fallback)` - Get variant value
143
- - `getVariantSync(name, fallback)` - Get full variant object with metadata
144
-
145
- All methods support async versions and snake_case aliases. See **[Feature Flags Quick Start Guide](FEATURE_FLAGS_QUICKSTART.md)** for complete documentation.
146
-
147
126
  ### Expo and React Native for Web support (3.0.2 and above)
148
127
 
149
128
  Starting from version 3.0.2, we have introduced support for Expo, React Native for Web, and other platforms utilizing React Native that do not support iOS and Android directly.
@@ -1,9 +1,6 @@
1
1
  package com.mixpanel.reactnative;
2
2
 
3
3
  import com.mixpanel.android.mpmetrics.MixpanelAPI;
4
- import com.mixpanel.android.mpmetrics.MixpanelOptions;
5
- import com.mixpanel.android.mpmetrics.MixpanelFlagVariant;
6
- import com.mixpanel.android.mpmetrics.FlagCompletionCallback;
7
4
 
8
5
  import com.facebook.react.bridge.Promise;
9
6
  import com.facebook.react.bridge.ReactApplicationContext;
@@ -12,10 +9,6 @@ import com.facebook.react.bridge.ReactMethod;
12
9
  import com.facebook.react.bridge.ReadableArray;
13
10
  import com.facebook.react.bridge.ReadableMap;
14
11
  import com.facebook.react.bridge.Dynamic;
15
- import com.facebook.react.bridge.WritableMap;
16
- import com.facebook.react.bridge.WritableNativeMap;
17
- import com.facebook.react.bridge.WritableArray;
18
- import com.facebook.react.bridge.Callback;
19
12
 
20
13
  import org.json.JSONArray;
21
14
  import org.json.JSONException;
@@ -40,35 +33,10 @@ public class MixpanelReactNativeModule extends ReactContextBaseJavaModule {
40
33
 
41
34
 
42
35
  @ReactMethod
43
- public void initialize(String token, boolean trackAutomaticEvents, boolean optOutTrackingDefault, ReadableMap metadata, String serverURL, boolean useGzipCompression, ReadableMap featureFlagsOptions, Promise promise) throws JSONException {
36
+ public void initialize(String token, boolean trackAutomaticEvents, boolean optOutTrackingDefault, ReadableMap metadata, String serverURL, boolean useGzipCompression, Promise promise) throws JSONException {
44
37
  JSONObject mixpanelProperties = ReactNativeHelper.reactToJSON(metadata);
45
38
  AutomaticProperties.setAutomaticProperties(mixpanelProperties);
46
-
47
- // Handle feature flags options
48
- boolean featureFlagsEnabled = false;
49
- JSONObject featureFlagsContext = null;
50
-
51
- if (featureFlagsOptions != null && featureFlagsOptions.hasKey("enabled")) {
52
- featureFlagsEnabled = featureFlagsOptions.getBoolean("enabled");
53
-
54
- if (featureFlagsOptions.hasKey("context")) {
55
- featureFlagsContext = ReactNativeHelper.reactToJSON(featureFlagsOptions.getMap("context"));
56
- }
57
- }
58
-
59
- // Create Mixpanel instance with feature flags configuration
60
- MixpanelOptions.Builder optionsBuilder = new MixpanelOptions.Builder()
61
- .optOutTrackingDefault(optOutTrackingDefault)
62
- .superProperties(mixpanelProperties)
63
- .featureFlagsEnabled(featureFlagsEnabled);
64
-
65
- if (featureFlagsContext != null) {
66
- optionsBuilder.featureFlagsContext(featureFlagsContext);
67
- }
68
-
69
- MixpanelOptions options = optionsBuilder.build();
70
-
71
- MixpanelAPI instance = MixpanelAPI.getInstance(this.mReactContext, token, trackAutomaticEvents, options);
39
+ MixpanelAPI instance = MixpanelAPI.getInstance(this.mReactContext, token, optOutTrackingDefault, mixpanelProperties, null, trackAutomaticEvents);
72
40
  instance.setServerURL(serverURL);
73
41
  if (useGzipCompression) {
74
42
  instance.setShouldGzipRequestPayload(true);
@@ -634,242 +602,4 @@ public class MixpanelReactNativeModule extends ReactContextBaseJavaModule {
634
602
  promise.resolve(null);
635
603
  }
636
604
  }
637
-
638
- // Feature Flags Methods
639
-
640
- @ReactMethod
641
- public void loadFlags(final String token, Promise promise) {
642
- MixpanelAPI instance = MixpanelAPI.getInstance(this.mReactContext, token, true);
643
- if (instance == null) {
644
- promise.reject("Instance Error", "Failed to get Mixpanel instance");
645
- return;
646
- }
647
- synchronized (instance) {
648
- instance.getFlags().loadFlags();
649
- promise.resolve(null);
650
- }
651
- }
652
-
653
- @ReactMethod(isBlockingSynchronousMethod = true)
654
- public boolean areFlagsReadySync(final String token) {
655
- MixpanelAPI instance = MixpanelAPI.getInstance(this.mReactContext, token, true);
656
- if (instance == null) {
657
- return false;
658
- }
659
- synchronized (instance) {
660
- return instance.getFlags().areFlagsReady();
661
- }
662
- }
663
-
664
- @ReactMethod(isBlockingSynchronousMethod = true)
665
- public WritableMap getVariantSync(final String token, String featureName, ReadableMap fallback) {
666
- MixpanelAPI instance = MixpanelAPI.getInstance(this.mReactContext, token, true);
667
- if (instance == null) {
668
- return convertVariantToMap(fallback);
669
- }
670
-
671
- synchronized (instance) {
672
- MixpanelFlagVariant fallbackVariant = convertMapToVariant(fallback);
673
- MixpanelFlagVariant variant = instance.getFlags().getVariantSync(featureName, fallbackVariant);
674
- return convertVariantToWritableMap(variant);
675
- }
676
- }
677
-
678
- // Note: For getVariantValueSync, we'll return the full variant and extract value in JS
679
- // React Native doesn't support returning Dynamic types from synchronous methods
680
- @ReactMethod(isBlockingSynchronousMethod = true)
681
- public WritableMap getVariantValueSync(final String token, String featureName, Dynamic fallbackValue) {
682
- MixpanelAPI instance = MixpanelAPI.getInstance(this.mReactContext, token, true);
683
-
684
- WritableMap result = new WritableNativeMap();
685
- if (instance == null) {
686
- result.putString("type", "fallback");
687
- // We'll handle the conversion in JavaScript
688
- return result;
689
- }
690
-
691
- synchronized (instance) {
692
- Object value = instance.getFlags().getVariantValueSync(featureName, ReactNativeHelper.dynamicToObject(fallbackValue));
693
- result.putString("type", "value");
694
-
695
- // Convert value to appropriate type
696
- if (value == null) {
697
- result.putNull("value");
698
- } else if (value instanceof String) {
699
- result.putString("value", (String) value);
700
- } else if (value instanceof Boolean) {
701
- result.putBoolean("value", (Boolean) value);
702
- } else if (value instanceof Integer) {
703
- result.putInt("value", (Integer) value);
704
- } else if (value instanceof Double) {
705
- result.putDouble("value", (Double) value);
706
- } else if (value instanceof Float) {
707
- result.putDouble("value", ((Float) value).doubleValue());
708
- } else if (value instanceof Long) {
709
- result.putDouble("value", ((Long) value).doubleValue());
710
- } else {
711
- result.putString("value", value.toString());
712
- }
713
-
714
- return result;
715
- }
716
- }
717
-
718
- @ReactMethod(isBlockingSynchronousMethod = true)
719
- public boolean isEnabledSync(final String token, String featureName, boolean fallbackValue) {
720
- MixpanelAPI instance = MixpanelAPI.getInstance(this.mReactContext, token, true);
721
- if (instance == null) {
722
- return fallbackValue;
723
- }
724
-
725
- synchronized (instance) {
726
- return instance.getFlags().isEnabledSync(featureName, fallbackValue);
727
- }
728
- }
729
-
730
- @ReactMethod
731
- public void getVariant(final String token, String featureName, ReadableMap fallback, final Promise promise) {
732
- MixpanelAPI instance = MixpanelAPI.getInstance(this.mReactContext, token, true);
733
- if (instance == null) {
734
- promise.resolve(convertVariantToMap(fallback));
735
- return;
736
- }
737
-
738
- synchronized (instance) {
739
- MixpanelFlagVariant fallbackVariant = convertMapToVariant(fallback);
740
- instance.getFlags().getVariant(featureName, fallbackVariant, new FlagCompletionCallback<MixpanelFlagVariant>() {
741
- @Override
742
- public void onComplete(MixpanelFlagVariant variant) {
743
- promise.resolve(convertVariantToWritableMap(variant));
744
- }
745
- });
746
- }
747
- }
748
-
749
- @ReactMethod
750
- public void getVariantValue(final String token, String featureName, Dynamic fallbackValue, final Promise promise) {
751
- MixpanelAPI instance = MixpanelAPI.getInstance(this.mReactContext, token, true);
752
- if (instance == null) {
753
- promise.resolve(fallbackValue);
754
- return;
755
- }
756
-
757
- synchronized (instance) {
758
- Object fallbackObj = ReactNativeHelper.dynamicToObject(fallbackValue);
759
- instance.getFlags().getVariantValue(featureName, fallbackObj, new FlagCompletionCallback<Object>() {
760
- @Override
761
- public void onComplete(Object value) {
762
- // Convert the value back to a format React Native can handle
763
- if (value == null) {
764
- promise.resolve(null);
765
- } else if (value instanceof String) {
766
- promise.resolve((String) value);
767
- } else if (value instanceof Boolean) {
768
- promise.resolve((Boolean) value);
769
- } else if (value instanceof Number) {
770
- promise.resolve(((Number) value).doubleValue());
771
- } else if (value instanceof JSONObject) {
772
- try {
773
- WritableMap map = ReactNativeHelper.convertJsonToMap((JSONObject) value);
774
- promise.resolve(map);
775
- } catch (Exception e) {
776
- promise.resolve(value.toString());
777
- }
778
- } else if (value instanceof JSONArray) {
779
- try {
780
- WritableArray array = ReactNativeHelper.convertJsonToArray((JSONArray) value);
781
- promise.resolve(array);
782
- } catch (Exception e) {
783
- promise.resolve(value.toString());
784
- }
785
- } else {
786
- promise.resolve(value.toString());
787
- }
788
- }
789
- });
790
- }
791
- }
792
-
793
- @ReactMethod
794
- public void isEnabled(final String token, String featureName, boolean fallbackValue, final Promise promise) {
795
- MixpanelAPI instance = MixpanelAPI.getInstance(this.mReactContext, token, true);
796
- if (instance == null) {
797
- promise.resolve(fallbackValue);
798
- return;
799
- }
800
-
801
- synchronized (instance) {
802
- instance.getFlags().isEnabled(featureName, fallbackValue, new FlagCompletionCallback<Boolean>() {
803
- @Override
804
- public void onComplete(Boolean isEnabled) {
805
- promise.resolve(isEnabled);
806
- }
807
- });
808
- }
809
- }
810
-
811
- // Helper methods for variant conversion
812
- private MixpanelFlagVariant convertMapToVariant(ReadableMap map) {
813
- if (map == null) {
814
- return new MixpanelFlagVariant("", null);
815
- }
816
-
817
- String key = map.hasKey("key") ? map.getString("key") : "";
818
- Object value = map.hasKey("value") ? ReactNativeHelper.dynamicToObject(map.getDynamic("value")) : null;
819
- String experimentID = map.hasKey("experimentID") ? map.getString("experimentID") : null;
820
- Boolean isExperimentActive = map.hasKey("isExperimentActive") ? map.getBoolean("isExperimentActive") : null;
821
- Boolean isQATester = map.hasKey("isQATester") ? map.getBoolean("isQATester") : null;
822
-
823
- // Create variant with all properties using the full constructor
824
- return new MixpanelFlagVariant(key, value, experimentID, isExperimentActive, isQATester);
825
- }
826
-
827
- private WritableMap convertVariantToMap(ReadableMap source) {
828
- WritableMap map = new WritableNativeMap();
829
- if (source != null) {
830
- map.merge(source);
831
- }
832
- return map;
833
- }
834
-
835
- private WritableMap convertVariantToWritableMap(MixpanelFlagVariant variant) {
836
- WritableMap map = new WritableNativeMap();
837
-
838
- if (variant != null) {
839
- map.putString("key", variant.key);
840
-
841
- Object value = variant.value;
842
- if (value == null) {
843
- map.putNull("value");
844
- } else if (value instanceof String) {
845
- map.putString("value", (String) value);
846
- } else if (value instanceof Boolean) {
847
- map.putBoolean("value", (Boolean) value);
848
- } else if (value instanceof Integer) {
849
- map.putInt("value", (Integer) value);
850
- } else if (value instanceof Double) {
851
- map.putDouble("value", (Double) value);
852
- } else if (value instanceof Float) {
853
- map.putDouble("value", ((Float) value).doubleValue());
854
- } else if (value instanceof Long) {
855
- map.putDouble("value", ((Long) value).doubleValue());
856
- } else {
857
- // For complex objects, convert to string
858
- map.putString("value", value.toString());
859
- }
860
-
861
- // Add optional fields if they exist
862
- if (variant.experimentID != null) {
863
- map.putString("experimentID", variant.experimentID);
864
- }
865
- if (variant.isExperimentActive != null) {
866
- map.putBoolean("isExperimentActive", variant.isExperimentActive);
867
- }
868
- if (variant.isQATester != null) {
869
- map.putBoolean("isQATester", variant.isQATester);
870
- }
871
- }
872
-
873
- return map;
874
- }
875
605
  }
package/index.d.ts CHANGED
@@ -7,69 +7,7 @@ export type MixpanelAsyncStorage = {
7
7
  removeItem(key: string): Promise<void>;
8
8
  };
9
9
 
10
- export interface MixpanelFlagVariant {
11
- key: string;
12
- value: any;
13
- experiment_id?: string | number; // Updated to match mixpanel-js format
14
- is_experiment_active?: boolean; // Updated to match mixpanel-js format
15
- is_qa_tester?: boolean; // Updated to match mixpanel-js format
16
- }
17
-
18
- export interface FeatureFlagsOptions {
19
- enabled?: boolean;
20
- context?: {
21
- [key: string]: any;
22
- custom_properties?: {
23
- [key: string]: any;
24
- };
25
- };
26
- }
27
-
28
- export interface UpdateContextOptions {
29
- replace?: boolean;
30
- }
31
-
32
- export interface Flags {
33
- // Synchronous methods
34
- loadFlags(): Promise<void>;
35
- areFlagsReady(): boolean;
36
- getVariantSync(featureName: string, fallback: MixpanelFlagVariant): MixpanelFlagVariant;
37
- getVariantValueSync(featureName: string, fallbackValue: any): any;
38
- isEnabledSync(featureName: string, fallbackValue?: boolean): boolean;
39
-
40
- // Asynchronous methods with overloads for callback and Promise patterns
41
- getVariant(featureName: string, fallback: MixpanelFlagVariant): Promise<MixpanelFlagVariant>;
42
- getVariant(featureName: string, fallback: MixpanelFlagVariant, callback: (result: MixpanelFlagVariant) => void): void;
43
-
44
- getVariantValue(featureName: string, fallbackValue: any): Promise<any>;
45
- getVariantValue(featureName: string, fallbackValue: any, callback: (value: any) => void): void;
46
-
47
- isEnabled(featureName: string, fallbackValue?: boolean): Promise<boolean>;
48
- isEnabled(featureName: string, fallbackValue: boolean, callback: (isEnabled: boolean) => void): void;
49
-
50
- // Context management (NEW - aligned with mixpanel-js)
51
- // NOTE: Only available in JavaScript mode (Expo/React Native Web)
52
- // In native mode, throws an error - context must be set during initialization
53
- updateContext(newContext: MixpanelProperties, options?: UpdateContextOptions): Promise<void>;
54
-
55
- // snake_case aliases (NEW - aligned with mixpanel-js)
56
- are_flags_ready(): boolean;
57
- get_variant(featureName: string, fallback: MixpanelFlagVariant): Promise<MixpanelFlagVariant>;
58
- get_variant(featureName: string, fallback: MixpanelFlagVariant, callback: (result: MixpanelFlagVariant) => void): void;
59
- get_variant_sync(featureName: string, fallback: MixpanelFlagVariant): MixpanelFlagVariant;
60
- get_variant_value(featureName: string, fallbackValue: any): Promise<any>;
61
- get_variant_value(featureName: string, fallbackValue: any, callback: (value: any) => void): void;
62
- get_variant_value_sync(featureName: string, fallbackValue: any): any;
63
- is_enabled(featureName: string, fallbackValue?: boolean): Promise<boolean>;
64
- is_enabled(featureName: string, fallbackValue: boolean, callback: (isEnabled: boolean) => void): void;
65
- is_enabled_sync(featureName: string, fallbackValue?: boolean): boolean;
66
- // NOTE: Only available in JavaScript mode (Expo/React Native Web)
67
- update_context(newContext: MixpanelProperties, options?: UpdateContextOptions): Promise<void>;
68
- }
69
-
70
10
  export class Mixpanel {
71
- readonly flags: Flags;
72
-
73
11
  constructor(token: string, trackAutoMaticEvents: boolean);
74
12
  constructor(token: string, trackAutoMaticEvents: boolean, useNative: true);
75
13
  constructor(
@@ -87,8 +25,7 @@ export class Mixpanel {
87
25
  optOutTrackingDefault?: boolean,
88
26
  superProperties?: MixpanelProperties,
89
27
  serverURL?: string,
90
- useGzipCompression?: boolean,
91
- featureFlagsOptions?: FeatureFlagsOptions
28
+ useGzipCompression?: boolean
92
29
  ): Promise<void>;
93
30
  setServerURL(serverURL: string): void;
94
31
  setLoggingEnabled(loggingEnabled: boolean): void;
package/index.js CHANGED
@@ -46,8 +46,6 @@ export class Mixpanel {
46
46
  }
47
47
  this.token = token;
48
48
  this.trackAutomaticEvents = trackAutomaticEvents;
49
- this._flags = null; // Lazy-loaded flags instance
50
- this.storage = storage; // Store for JavaScript mode
51
49
 
52
50
  if (useNative && MixpanelReactNative) {
53
51
  this.mixpanelImpl = MixpanelReactNative;
@@ -62,116 +60,27 @@ export class Mixpanel {
62
60
  }
63
61
 
64
62
  /**
65
- * Returns the Flags instance for feature flags operations.
63
+ * Initializes Mixpanel
66
64
  *
67
- * <p>Feature Flags enable dynamic feature control and A/B testing capabilities.
68
- * This property is lazy-loaded to avoid unnecessary initialization until first access.
69
- *
70
- * <p><b>Native Mode Only:</b> Feature flags are currently only available when using native mode
71
- * (iOS/Android). JavaScript mode (Expo/React Native Web) support is planned for a future release.
72
- *
73
- * @return {Flags} an instance of Flags that provides access to feature flag operations
74
- * @throws {Error} if accessed in JavaScript mode (when native modules are not available)
75
- *
76
- * @example
77
- * // Check if flags are ready
78
- * if (mixpanel.flags.areFlagsReady()) {
79
- * const isEnabled = mixpanel.flags.isEnabledSync('new-checkout', false);
80
- * }
81
- *
82
- * @example
83
- * // Get a feature variant value
84
- * const buttonColor = mixpanel.flags.getVariantValueSync('button-color', 'blue');
85
- *
86
- * @see Flags
87
- */
88
- get flags() {
89
- // Short circuit for JavaScript mode - flags not ready for public use
90
- if (this.mixpanelImpl !== MixpanelReactNative) {
91
- throw new Error(
92
- "Feature flags are only available in native mode. " +
93
- "JavaScript mode support is coming in a future release."
94
- );
95
- }
96
-
97
- if (!this._flags) {
98
- // Lazy load the Flags instance with proper dependencies
99
- const Flags = require("./javascript/mixpanel-flags").Flags;
100
- this._flags = new Flags(this.token, this.mixpanelImpl, this.storage);
101
- }
102
- return this._flags;
103
- }
104
-
105
- /**
106
- * Initializes Mixpanel with optional configuration for tracking, super properties, and feature flags.
107
- *
108
- * <p>This method must be called before using any other Mixpanel functionality. It sets up
109
- * the tracking environment, registers super properties, and optionally initializes feature flags.
110
- *
111
- * @param {boolean} [optOutTrackingDefault=false] Whether or not Mixpanel can start tracking by default.
112
- * If true, no data will be tracked until optInTracking() is called. See optOutTracking()
113
- * @param {object} [superProperties={}] A Map containing the key value pairs of the super properties to register.
114
- * These properties will be sent with every event. Pass {} if no super properties needed.
115
- * @param {string} [serverURL="https://api.mixpanel.com"] The base URL used for Mixpanel API requests.
116
- * Use "https://api-eu.mixpanel.com" for EU data residency. See setServerURL()
117
- * @param {boolean} [useGzipCompression=false] Whether to use gzip compression for network requests.
118
- * Enabling this reduces bandwidth usage but adds slight CPU overhead.
119
- * @param {object} [featureFlagsOptions={}] Feature flags configuration object with the following properties:
120
- * @param {boolean} [featureFlagsOptions.enabled=false] Whether to enable feature flags functionality
121
- * @param {object} [featureFlagsOptions.context={}] Context properties used for feature flag targeting.
122
- * Can include user properties, device properties, or any custom properties for flag evaluation.
123
- * Note: In native mode, context must be set during initialization and cannot be updated later.
124
- * @returns {Promise<void>} A promise that resolves when initialization is complete
125
- *
126
- * @example
127
- * // Basic initialization
128
- * const mixpanel = new Mixpanel('YOUR_TOKEN', true);
129
- * await mixpanel.init();
130
- *
131
- * @example
132
- * // Initialize with feature flags enabled
133
- * const mixpanel = new Mixpanel('YOUR_TOKEN', true);
134
- * await mixpanel.init(false, {}, 'https://api.mixpanel.com', false, {
135
- * enabled: true,
136
- * context: {
137
- * platform: 'mobile',
138
- * app_version: '2.1.0'
139
- * }
140
- * });
141
- *
142
- * @example
143
- * // Initialize with EU data residency and super properties
144
- * await mixpanel.init(
145
- * false,
146
- * { plan: 'premium', region: 'eu' },
147
- * 'https://api-eu.mixpanel.com',
148
- * true
149
- * );
65
+ * @param {boolean} optOutTrackingDefault Optional Whether or not Mixpanel can start tracking by default. See optOutTracking()
66
+ * @param {object} superProperties Optional A Map containing the key value pairs of the super properties to register
67
+ * @param {string} serverURL Optional Set the base URL used for Mixpanel API requests. See setServerURL()
68
+ * @param {boolean} useGzipCompression Optional Set whether to use gzip compression for network requests. Defaults to false.
150
69
  */
151
70
  async init(
152
71
  optOutTrackingDefault = DEFAULT_OPT_OUT,
153
72
  superProperties = {},
154
73
  serverURL = "https://api.mixpanel.com",
155
- useGzipCompression = false,
156
- featureFlagsOptions = {}
74
+ useGzipCompression = false
157
75
  ) {
158
- // Store feature flags options for later use
159
- this.featureFlagsOptions = featureFlagsOptions;
160
-
161
76
  await this.mixpanelImpl.initialize(
162
77
  this.token,
163
78
  this.trackAutomaticEvents,
164
79
  optOutTrackingDefault,
165
80
  {...Helper.getMetaData(), ...superProperties},
166
81
  serverURL,
167
- useGzipCompression,
168
- featureFlagsOptions
82
+ useGzipCompression
169
83
  );
170
-
171
- // If flags are enabled AND we're in native mode, initialize them
172
- if (featureFlagsOptions.enabled && this.mixpanelImpl === MixpanelReactNative) {
173
- await this.flags.loadFlags();
174
- }
175
84
  }
176
85
 
177
86
  /**
@@ -200,9 +109,7 @@ export class Mixpanel {
200
109
  trackAutomaticEvents,
201
110
  optOutTrackingDefault,
202
111
  Helper.getMetaData(),
203
- "https://api.mixpanel.com",
204
- false,
205
- {}
112
+ "https://api.mixpanel.com"
206
113
  );
207
114
  return new Mixpanel(token, trackAutomaticEvents);
208
115
  }
@@ -5,7 +5,7 @@
5
5
 
6
6
  // MARK: - Mixpanel Instance
7
7
 
8
- RCT_EXTERN_METHOD(initialize:(NSString *)token trackAutomaticEvents:(BOOL)trackAutomaticEvents optOutTrackingByDefault:(BOOL)optOutTrackingByDefault properties:(NSDictionary *)properties serverURL:(NSString *)serverURL useGzipCompression:(BOOL)useGzipCompression featureFlagsOptions:(NSDictionary *)featureFlagsOptions resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
8
+ RCT_EXTERN_METHOD(initialize:(NSString *)token trackAutomaticEvents:(BOOL)trackAutomaticEvents optOutTrackingByDefault:(BOOL)optOutTrackingByDefault properties:(NSDictionary *)properties serverURL:(NSString *)serverURL useGzipCompression:(BOOL)useGzipCompression resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
9
9
 
10
10
  // Mark: - Settings
11
11
  RCT_EXTERN_METHOD(setServerURL:(NSString *)token serverURL:(NSString *)serverURL resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
@@ -105,22 +105,4 @@ RCT_EXTERN_METHOD(groupRemovePropertyValue:(NSString *)token groupKey:(NSString
105
105
 
106
106
  RCT_EXTERN_METHOD(groupUnionProperty:(NSString *)token groupKey:(NSString *)groupKey groupID:(id)groupID name:(NSString *)name values:(NSArray *)values resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
107
107
 
108
- // MARK: - Feature Flags
109
-
110
- RCT_EXTERN_METHOD(loadFlags:(NSString *)token resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
111
-
112
- RCT_EXTERN__BLOCKING_SYNCHRONOUS_METHOD(areFlagsReadySync:(NSString *)token)
113
-
114
- RCT_EXTERN__BLOCKING_SYNCHRONOUS_METHOD(getVariantSync:(NSString *)token featureName:(NSString *)featureName fallback:(NSDictionary *)fallback)
115
-
116
- RCT_EXTERN__BLOCKING_SYNCHRONOUS_METHOD(getVariantValueSync:(NSString *)token featureName:(NSString *)featureName fallbackValue:(id)fallbackValue)
117
-
118
- RCT_EXTERN__BLOCKING_SYNCHRONOUS_METHOD(isEnabledSync:(NSString *)token featureName:(NSString *)featureName fallbackValue:(BOOL)fallbackValue)
119
-
120
- RCT_EXTERN_METHOD(getVariant:(NSString *)token featureName:(NSString *)featureName fallback:(NSDictionary *)fallback resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
121
-
122
- RCT_EXTERN_METHOD(getVariantValue:(NSString *)token featureName:(NSString *)featureName fallbackValue:(id)fallbackValue resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
123
-
124
- RCT_EXTERN_METHOD(isEnabled:(NSString *)token featureName:(NSString *)featureName fallbackValue:(BOOL)fallbackValue resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
125
-
126
108
  @end