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.
@@ -1,670 +0,0 @@
1
- import { MixpanelFlagsJS } from './mixpanel-flags-js';
2
-
3
- /**
4
- * Core class for using Mixpanel Feature Flags.
5
- *
6
- * <p>The Flags class provides access to Mixpanel's Feature Flags functionality, enabling
7
- * dynamic feature control, A/B testing, and personalized user experiences. Feature flags
8
- * allow you to remotely configure your app's features without deploying new code.
9
- *
10
- * <p>This class is accessed through the {@link Mixpanel#flags} property and is lazy-loaded
11
- * to minimize performance impact until feature flags are actually used.
12
- *
13
- * <p><b>Platform Support:</b>
14
- * <ul>
15
- * <li><b>Native Mode (iOS/Android):</b> Fully supported with automatic experiment tracking</li>
16
- * <li><b>JavaScript Mode (Expo/React Native Web):</b> Planned for future release</li>
17
- * </ul>
18
- *
19
- * <p><b>Key Concepts:</b>
20
- * <ul>
21
- * <li><b>Feature Name:</b> The unique identifier for your feature flag (e.g., "new-checkout")</li>
22
- * <li><b>Variant:</b> An object containing both a key and value representing the feature configuration</li>
23
- * <li><b>Variant Key:</b> The identifier for the specific variation (e.g., "control", "treatment")</li>
24
- * <li><b>Variant Value:</b> The actual configuration value (can be any JSON-serializable type)</li>
25
- * <li><b>Fallback:</b> Default value returned when a flag is not available or not loaded</li>
26
- * </ul>
27
- *
28
- * <p><b>Automatic Experiment Tracking:</b> When a feature flag is evaluated for the first time,
29
- * Mixpanel automatically tracks a "$experiment_started" event with relevant metadata.
30
- *
31
- * @example
32
- * // Initialize with feature flags enabled
33
- * const mixpanel = new Mixpanel('YOUR_TOKEN', true);
34
- * await mixpanel.init(false, {}, 'https://api.mixpanel.com', false, {
35
- * enabled: true,
36
- * context: { platform: 'mobile' }
37
- * });
38
- *
39
- * @example
40
- * // Synchronous access (when flags are ready)
41
- * if (mixpanel.flags.areFlagsReady()) {
42
- * const isEnabled = mixpanel.flags.isEnabledSync('new-feature', false);
43
- * const color = mixpanel.flags.getVariantValueSync('button-color', 'blue');
44
- * const variant = mixpanel.flags.getVariantSync('checkout-flow', {
45
- * key: 'control',
46
- * value: 'standard'
47
- * });
48
- * }
49
- *
50
- * @example
51
- * // Asynchronous access with Promise pattern
52
- * const variant = await mixpanel.flags.getVariant('pricing-test', {
53
- * key: 'control',
54
- * value: { price: 9.99, currency: 'USD' }
55
- * });
56
- *
57
- * @example
58
- * // Asynchronous access with callback pattern
59
- * mixpanel.flags.isEnabled('beta-features', false, (isEnabled) => {
60
- * if (isEnabled) {
61
- * // Enable beta features
62
- * }
63
- * });
64
- *
65
- * @see Mixpanel#flags
66
- */
67
- export class Flags {
68
- constructor(token, mixpanelImpl, storage) {
69
- this.token = token;
70
- this.mixpanelImpl = mixpanelImpl;
71
- this.storage = storage;
72
- this.isNativeMode = typeof mixpanelImpl.loadFlags === 'function';
73
-
74
- // For JavaScript mode, create the JS implementation
75
- if (!this.isNativeMode && storage) {
76
- this.jsFlags = new MixpanelFlagsJS(token, mixpanelImpl, storage);
77
- }
78
- }
79
-
80
- /**
81
- * Manually fetch feature flags from the Mixpanel servers.
82
- *
83
- * <p>Feature flags are automatically loaded during initialization when feature flags are enabled.
84
- * This method allows you to manually trigger a refresh of the flags, which is useful when:
85
- * <ul>
86
- * <li>You want to reload flags after a user property change</li>
87
- * <li>You need to ensure you have the latest flag configuration</li>
88
- * <li>Initial automatic load failed and you want to retry</li>
89
- * </ul>
90
- *
91
- * <p>After successfully loading flags, {@link areFlagsReady} will return true and synchronous
92
- * methods can be used to access flag values.
93
- *
94
- * @returns {Promise<void>} A promise that resolves when flags have been fetched and loaded
95
- * @throws {Error} if feature flags are not initialized
96
- *
97
- * @example
98
- * // Manually reload flags after user identification
99
- * await mixpanel.identify('user123');
100
- * await mixpanel.flags.loadFlags();
101
- */
102
- async loadFlags() {
103
- if (this.isNativeMode) {
104
- return await this.mixpanelImpl.loadFlags(this.token);
105
- } else if (this.jsFlags) {
106
- return await this.jsFlags.loadFlags();
107
- }
108
- throw new Error("Feature flags are not initialized");
109
- }
110
-
111
- /**
112
- * Check if feature flags have been fetched from the server and are ready to use.
113
- *
114
- * <p>This method returns true after feature flags have been successfully loaded via {@link loadFlags}
115
- * or during initialization. When flags are ready, you can safely use the synchronous methods
116
- * ({@link getVariantSync}, {@link getVariantValueSync}, {@link isEnabledSync}) without waiting.
117
- *
118
- * <p>It's recommended to check this before using synchronous methods to ensure you're not
119
- * getting fallback values due to flags not being loaded yet.
120
- *
121
- * @returns {boolean} true if flags have been loaded and are ready to use, false otherwise
122
- *
123
- * @example
124
- * // Check before using synchronous methods
125
- * if (mixpanel.flags.areFlagsReady()) {
126
- * const isEnabled = mixpanel.flags.isEnabledSync('new-feature', false);
127
- * } else {
128
- * console.log('Flags not ready yet, using fallback');
129
- * }
130
- *
131
- * @example
132
- * // Wait for flags to be ready
133
- * await mixpanel.flags.loadFlags();
134
- * if (mixpanel.flags.areFlagsReady()) {
135
- * // Now safe to use sync methods
136
- * }
137
- */
138
- areFlagsReady() {
139
- if (this.isNativeMode) {
140
- return this.mixpanelImpl.areFlagsReadySync(this.token);
141
- } else if (this.jsFlags) {
142
- return this.jsFlags.areFlagsReady();
143
- }
144
- return false;
145
- }
146
-
147
- /**
148
- * Get a feature flag variant synchronously.
149
- *
150
- * <p>Returns the complete variant object for a feature flag, including both the variant key
151
- * (e.g., "control", "treatment") and the variant value (the actual configuration data).
152
- *
153
- * <p><b>Important:</b> This is a synchronous method that only works when flags are ready.
154
- * Always check {@link areFlagsReady} first, or use the asynchronous {@link getVariant} method instead.
155
- *
156
- * <p>When a flag is evaluated for the first time, Mixpanel automatically tracks a
157
- * "$experiment_started" event with relevant experiment metadata.
158
- *
159
- * @param {string} featureName The unique identifier for the feature flag
160
- * @param {object} fallback The fallback variant object to return if the flag is not available.
161
- * Must include both 'key' and 'value' properties.
162
- * @returns {object} The flag variant object with the following structure:
163
- * - key: {string} The variant key (e.g., "control", "treatment")
164
- * - value: {any} The variant value (can be any JSON-serializable type)
165
- * - experiment_id: {string|number} (optional) The experiment ID if this is an experiment
166
- * - is_experiment_active: {boolean} (optional) Whether the experiment is currently active
167
- *
168
- * @example
169
- * // Get a checkout flow variant
170
- * if (mixpanel.flags.areFlagsReady()) {
171
- * const variant = mixpanel.flags.getVariantSync('checkout-flow', {
172
- * key: 'control',
173
- * value: 'standard'
174
- * });
175
- * console.log(`Using variant: ${variant.key}`);
176
- * console.log(`Configuration: ${JSON.stringify(variant.value)}`);
177
- * }
178
- *
179
- * @example
180
- * // Get a complex configuration variant
181
- * const defaultConfig = {
182
- * key: 'default',
183
- * value: {
184
- * theme: 'light',
185
- * layout: 'grid',
186
- * itemsPerPage: 20
187
- * }
188
- * };
189
- * const config = mixpanel.flags.getVariantSync('ui-config', defaultConfig);
190
- *
191
- * @see getVariant for asynchronous access
192
- * @see getVariantValueSync to get only the value (not the full variant object)
193
- */
194
- getVariantSync(featureName, fallback) {
195
- if (!this.areFlagsReady()) {
196
- return fallback;
197
- }
198
-
199
- if (this.isNativeMode) {
200
- return this.mixpanelImpl.getVariantSync(this.token, featureName, fallback);
201
- } else if (this.jsFlags) {
202
- return this.jsFlags.getVariantSync(featureName, fallback);
203
- }
204
- return fallback;
205
- }
206
-
207
- /**
208
- * Get a feature flag variant value synchronously.
209
- *
210
- * <p>Returns only the value portion of a feature flag variant, without the variant key or metadata.
211
- * This is useful when you only care about the configuration data, not which variant was selected.
212
- *
213
- * <p><b>Important:</b> This is a synchronous method that only works when flags are ready.
214
- * Always check {@link areFlagsReady} first, or use the asynchronous {@link getVariantValue} method instead.
215
- *
216
- * <p>When a flag is evaluated for the first time, Mixpanel automatically tracks a
217
- * "$experiment_started" event with relevant experiment metadata.
218
- *
219
- * @param {string} featureName The unique identifier for the feature flag
220
- * @param {any} fallbackValue The fallback value to return if the flag is not available.
221
- * Can be any JSON-serializable type (string, number, boolean, object, array, etc.)
222
- * @returns {any} The flag's value, or the fallback if the flag is not available.
223
- * The return type matches the type of value configured in your Mixpanel project.
224
- *
225
- * @example
226
- * // Get a simple string value
227
- * if (mixpanel.flags.areFlagsReady()) {
228
- * const buttonColor = mixpanel.flags.getVariantValueSync('button-color', 'blue');
229
- * applyButtonColor(buttonColor);
230
- * }
231
- *
232
- * @example
233
- * // Get a complex object value
234
- * const defaultPricing = { price: 9.99, currency: 'USD', trial_days: 7 };
235
- * const pricing = mixpanel.flags.getVariantValueSync('pricing-config', defaultPricing);
236
- * console.log(`Price: ${pricing.price} ${pricing.currency}`);
237
- *
238
- * @example
239
- * // Get a boolean value
240
- * const showPromo = mixpanel.flags.getVariantValueSync('show-promo', false);
241
- * if (showPromo) {
242
- * displayPromotionalBanner();
243
- * }
244
- *
245
- * @see getVariantValue for asynchronous access
246
- * @see getVariantSync to get the full variant object including key and metadata
247
- */
248
- getVariantValueSync(featureName, fallbackValue) {
249
- if (!this.areFlagsReady()) {
250
- return fallbackValue;
251
- }
252
-
253
- if (this.isNativeMode) {
254
- // Android returns a wrapped object due to React Native limitations
255
- const result = this.mixpanelImpl.getVariantValueSync(this.token, featureName, fallbackValue);
256
- if (result && typeof result === 'object' && 'type' in result) {
257
- // Android wraps the response
258
- return result.type === 'fallback' ? fallbackValue : result.value;
259
- }
260
- // iOS returns the value directly
261
- return result;
262
- } else if (this.jsFlags) {
263
- return this.jsFlags.getVariantValueSync(featureName, fallbackValue);
264
- }
265
- return fallbackValue;
266
- }
267
-
268
- /**
269
- * Check if a feature flag is enabled synchronously.
270
- *
271
- * <p>This is a convenience method for boolean feature flags. It checks if a feature is enabled
272
- * by evaluating the variant value as a boolean. A feature is considered "enabled" when its
273
- * variant value evaluates to true.
274
- *
275
- * <p><b>Important:</b> This is a synchronous method that only works when flags are ready.
276
- * Always check {@link areFlagsReady} first, or use the asynchronous {@link isEnabled} method instead.
277
- *
278
- * <p>When a flag is evaluated for the first time, Mixpanel automatically tracks a
279
- * "$experiment_started" event with relevant experiment metadata.
280
- *
281
- * @param {string} featureName The unique identifier for the feature flag
282
- * @param {boolean} [fallbackValue=false] The fallback value to return if the flag is not available.
283
- * Defaults to false if not provided.
284
- * @returns {boolean} true if the feature is enabled, false otherwise
285
- *
286
- * @example
287
- * // Simple feature toggle
288
- * if (mixpanel.flags.areFlagsReady()) {
289
- * if (mixpanel.flags.isEnabledSync('new-checkout', false)) {
290
- * showNewCheckout();
291
- * } else {
292
- * showLegacyCheckout();
293
- * }
294
- * }
295
- *
296
- * @example
297
- * // With explicit fallback
298
- * const enableBetaFeatures = mixpanel.flags.isEnabledSync('beta-features', true);
299
- *
300
- * @see isEnabled for asynchronous access
301
- * @see getVariantValueSync for non-boolean flag values
302
- */
303
- isEnabledSync(featureName, fallbackValue = false) {
304
- if (!this.areFlagsReady()) {
305
- return fallbackValue;
306
- }
307
-
308
- if (this.isNativeMode) {
309
- return this.mixpanelImpl.isEnabledSync(this.token, featureName, fallbackValue);
310
- } else if (this.jsFlags) {
311
- return this.jsFlags.isEnabledSync(featureName, fallbackValue);
312
- }
313
- return fallbackValue;
314
- }
315
-
316
- /**
317
- * Get a feature flag variant asynchronously.
318
- *
319
- * <p>Returns the complete variant object for a feature flag, including both the variant key
320
- * and the variant value. This method works regardless of whether flags are ready, making it
321
- * safe to use at any time.
322
- *
323
- * <p>Supports both Promise and callback patterns for maximum flexibility.
324
- *
325
- * <p>When a flag is evaluated for the first time, Mixpanel automatically tracks a
326
- * "$experiment_started" event with relevant experiment metadata.
327
- *
328
- * @param {string} featureName The unique identifier for the feature flag
329
- * @param {object} fallback The fallback variant object to return if the flag is not available.
330
- * Must include both 'key' and 'value' properties.
331
- * @param {function} [callback] Optional callback function that receives the variant object.
332
- * If provided, the method returns void. If omitted, the method returns a Promise.
333
- * @returns {Promise<object>|void} Promise that resolves to the variant object if no callback provided,
334
- * void if callback is provided. The variant object has the following structure:
335
- * - key: {string} The variant key (e.g., "control", "treatment")
336
- * - value: {any} The variant value (can be any JSON-serializable type)
337
- * - experiment_id: {string|number} (optional) The experiment ID if this is an experiment
338
- * - is_experiment_active: {boolean} (optional) Whether the experiment is currently active
339
- *
340
- * @example
341
- * // Promise pattern (recommended)
342
- * const variant = await mixpanel.flags.getVariant('checkout-flow', {
343
- * key: 'control',
344
- * value: 'standard'
345
- * });
346
- * console.log(`Using ${variant.key}: ${variant.value}`);
347
- *
348
- * @example
349
- * // Callback pattern
350
- * mixpanel.flags.getVariant('pricing-test', {
351
- * key: 'default',
352
- * value: { price: 9.99 }
353
- * }, (variant) => {
354
- * console.log(`Price: ${variant.value.price}`);
355
- * });
356
- *
357
- * @see getVariantSync for synchronous access when flags are ready
358
- * @see getVariantValue to get only the value without the variant key
359
- */
360
- getVariant(featureName, fallback, callback) {
361
- // If callback provided, use callback pattern
362
- if (typeof callback === 'function') {
363
- if (this.isNativeMode) {
364
- this.mixpanelImpl.getVariant(this.token, featureName, fallback)
365
- .then(result => callback(result))
366
- .catch(() => callback(fallback));
367
- } else if (this.jsFlags) {
368
- this.jsFlags.getVariant(featureName, fallback)
369
- .then(result => callback(result))
370
- .catch(() => callback(fallback));
371
- } else {
372
- callback(fallback);
373
- }
374
- return;
375
- }
376
-
377
- // Promise pattern
378
- return new Promise((resolve) => {
379
- if (this.isNativeMode) {
380
- this.mixpanelImpl.getVariant(this.token, featureName, fallback)
381
- .then(resolve)
382
- .catch(() => resolve(fallback));
383
- } else if (this.jsFlags) {
384
- this.jsFlags.getVariant(featureName, fallback)
385
- .then(resolve)
386
- .catch(() => resolve(fallback));
387
- } else {
388
- resolve(fallback);
389
- }
390
- });
391
- }
392
-
393
- /**
394
- * Get a feature flag variant value asynchronously.
395
- *
396
- * <p>Returns only the value portion of a feature flag variant. This method works regardless
397
- * of whether flags are ready, making it safe to use at any time.
398
- *
399
- * <p>Supports both Promise and callback patterns for maximum flexibility.
400
- *
401
- * <p>When a flag is evaluated for the first time, Mixpanel automatically tracks a
402
- * "$experiment_started" event with relevant experiment metadata.
403
- *
404
- * @param {string} featureName The unique identifier for the feature flag
405
- * @param {any} fallbackValue The fallback value to return if the flag is not available.
406
- * Can be any JSON-serializable type (string, number, boolean, object, array, etc.)
407
- * @param {function} [callback] Optional callback function that receives the flag value.
408
- * If provided, the method returns void. If omitted, the method returns a Promise.
409
- * @returns {Promise<any>|void} Promise that resolves to the flag value if no callback provided,
410
- * void if callback is provided. The return type matches the type of value configured in
411
- * your Mixpanel project.
412
- *
413
- * @example
414
- * // Promise pattern (recommended)
415
- * const buttonColor = await mixpanel.flags.getVariantValue('button-color', 'blue');
416
- * applyButtonColor(buttonColor);
417
- *
418
- * @example
419
- * // Promise pattern with object value
420
- * const pricing = await mixpanel.flags.getVariantValue('pricing-config', {
421
- * price: 9.99,
422
- * currency: 'USD'
423
- * });
424
- * displayPrice(pricing.price, pricing.currency);
425
- *
426
- * @example
427
- * // Callback pattern
428
- * mixpanel.flags.getVariantValue('theme', 'light', (theme) => {
429
- * applyTheme(theme);
430
- * });
431
- *
432
- * @see getVariantValueSync for synchronous access when flags are ready
433
- * @see getVariant to get the full variant object including key and metadata
434
- */
435
- getVariantValue(featureName, fallbackValue, callback) {
436
- // If callback provided, use callback pattern
437
- if (typeof callback === 'function') {
438
- if (this.isNativeMode) {
439
- this.mixpanelImpl.getVariantValue(this.token, featureName, fallbackValue)
440
- .then(result => callback(result))
441
- .catch(() => callback(fallbackValue));
442
- } else if (this.jsFlags) {
443
- this.jsFlags.getVariantValue(featureName, fallbackValue)
444
- .then(result => callback(result))
445
- .catch(() => callback(fallbackValue));
446
- } else {
447
- callback(fallbackValue);
448
- }
449
- return;
450
- }
451
-
452
- // Promise pattern
453
- return new Promise((resolve) => {
454
- if (this.isNativeMode) {
455
- this.mixpanelImpl.getVariantValue(this.token, featureName, fallbackValue)
456
- .then(resolve)
457
- .catch(() => resolve(fallbackValue));
458
- } else if (this.jsFlags) {
459
- this.jsFlags.getVariantValue(featureName, fallbackValue)
460
- .then(resolve)
461
- .catch(() => resolve(fallbackValue));
462
- } else {
463
- resolve(fallbackValue);
464
- }
465
- });
466
- }
467
-
468
- /**
469
- * Check if a feature flag is enabled asynchronously.
470
- *
471
- * <p>This is a convenience method for boolean feature flags. It checks if a feature is enabled
472
- * by evaluating the variant value as a boolean. This method works regardless of whether flags
473
- * are ready, making it safe to use at any time.
474
- *
475
- * <p>Supports both Promise and callback patterns for maximum flexibility.
476
- *
477
- * <p>When a flag is evaluated for the first time, Mixpanel automatically tracks a
478
- * "$experiment_started" event with relevant experiment metadata.
479
- *
480
- * @param {string} featureName The unique identifier for the feature flag
481
- * @param {boolean} [fallbackValue=false] The fallback value to return if the flag is not available.
482
- * Defaults to false if not provided.
483
- * @param {function} [callback] Optional callback function that receives the boolean result.
484
- * If provided, the method returns void. If omitted, the method returns a Promise.
485
- * @returns {Promise<boolean>|void} Promise that resolves to true if enabled, false otherwise
486
- * (when no callback provided). Returns void if callback is provided.
487
- *
488
- * @example
489
- * // Promise pattern (recommended)
490
- * const isEnabled = await mixpanel.flags.isEnabled('new-checkout', false);
491
- * if (isEnabled) {
492
- * showNewCheckout();
493
- * } else {
494
- * showLegacyCheckout();
495
- * }
496
- *
497
- * @example
498
- * // Callback pattern
499
- * mixpanel.flags.isEnabled('beta-features', false, (isEnabled) => {
500
- * if (isEnabled) {
501
- * enableBetaFeatures();
502
- * }
503
- * });
504
- *
505
- * @example
506
- * // Default fallback (false)
507
- * const showPromo = await mixpanel.flags.isEnabled('show-promo');
508
- *
509
- * @see isEnabledSync for synchronous access when flags are ready
510
- * @see getVariantValue for non-boolean flag values
511
- */
512
- isEnabled(featureName, fallbackValue = false, callback) {
513
- // If callback provided, use callback pattern
514
- if (typeof callback === 'function') {
515
- if (this.isNativeMode) {
516
- this.mixpanelImpl.isEnabled(this.token, featureName, fallbackValue)
517
- .then(result => callback(result))
518
- .catch(() => callback(fallbackValue));
519
- } else if (this.jsFlags) {
520
- this.jsFlags.isEnabled(featureName, fallbackValue)
521
- .then(result => callback(result))
522
- .catch(() => callback(fallbackValue));
523
- } else {
524
- callback(fallbackValue);
525
- }
526
- return;
527
- }
528
-
529
- // Promise pattern
530
- return new Promise((resolve) => {
531
- if (this.isNativeMode) {
532
- this.mixpanelImpl.isEnabled(this.token, featureName, fallbackValue)
533
- .then(resolve)
534
- .catch(() => resolve(fallbackValue));
535
- } else if (this.jsFlags) {
536
- this.jsFlags.isEnabled(featureName, fallbackValue)
537
- .then(resolve)
538
- .catch(() => resolve(fallbackValue));
539
- } else {
540
- resolve(fallbackValue);
541
- }
542
- });
543
- }
544
-
545
- /**
546
- * Update the context used for feature flag evaluation.
547
- *
548
- * <p>Context properties are used to determine which feature flag variants a user should receive
549
- * based on targeting rules configured in your Mixpanel project. This allows for personalized
550
- * feature experiences based on user attributes, device properties, or custom criteria.
551
- *
552
- * <p><b>IMPORTANT LIMITATION:</b> This method is <b>only available in JavaScript mode</b>
553
- * (Expo/React Native Web). In native mode (iOS/Android), context must be set during initialization
554
- * via {@link Mixpanel#init} and cannot be updated at runtime.
555
- *
556
- * <p>By default, the new context properties are merged with existing context. Set
557
- * <code>options.replace = true</code> to completely replace the context instead.
558
- *
559
- * @param {object} newContext New context properties to add or update. Can include any
560
- * JSON-serializable properties that are used in your feature flag targeting rules.
561
- * Common examples include user tier, region, platform version, etc.
562
- * @param {object} [options={replace: false}] Configuration options for the update
563
- * @param {boolean} [options.replace=false] If true, replaces the entire context instead of merging.
564
- * If false (default), merges new properties with existing context.
565
- * @returns {Promise<void>} A promise that resolves when the context has been updated and
566
- * flags have been re-evaluated with the new context
567
- * @throws {Error} if called in native mode (iOS/Android)
568
- *
569
- * @example
570
- * // Merge new properties into existing context (JavaScript mode only)
571
- * await mixpanel.flags.updateContext({
572
- * user_tier: 'premium',
573
- * region: 'us-west'
574
- * });
575
- *
576
- * @example
577
- * // Replace entire context (JavaScript mode only)
578
- * await mixpanel.flags.updateContext({
579
- * device_type: 'tablet',
580
- * os_version: '14.0'
581
- * }, { replace: true });
582
- *
583
- * @example
584
- * // This will throw an error in native mode
585
- * try {
586
- * await mixpanel.flags.updateContext({ tier: 'premium' });
587
- * } catch (error) {
588
- * console.error('Context updates not supported in native mode');
589
- * }
590
- */
591
- async updateContext(newContext, options = { replace: false }) {
592
- if (this.isNativeMode) {
593
- throw new Error(
594
- "updateContext() is not supported in native mode. " +
595
- "Context must be set during initialization via FeatureFlagsOptions. " +
596
- "This feature is only available in JavaScript mode (Expo/React Native Web)."
597
- );
598
- } else if (this.jsFlags) {
599
- return await this.jsFlags.updateContext(newContext, options);
600
- }
601
- throw new Error("Feature flags are not initialized");
602
- }
603
-
604
- // snake_case aliases for API consistency with mixpanel-js
605
-
606
- /**
607
- * Alias for {@link areFlagsReady}. Provided for API consistency with mixpanel-js.
608
- * @see areFlagsReady
609
- */
610
- are_flags_ready() {
611
- return this.areFlagsReady();
612
- }
613
-
614
- /**
615
- * Alias for {@link getVariant}. Provided for API consistency with mixpanel-js.
616
- * @see getVariant
617
- */
618
- get_variant(featureName, fallback, callback) {
619
- return this.getVariant(featureName, fallback, callback);
620
- }
621
-
622
- /**
623
- * Alias for {@link getVariantSync}. Provided for API consistency with mixpanel-js.
624
- * @see getVariantSync
625
- */
626
- get_variant_sync(featureName, fallback) {
627
- return this.getVariantSync(featureName, fallback);
628
- }
629
-
630
- /**
631
- * Alias for {@link getVariantValue}. Provided for API consistency with mixpanel-js.
632
- * @see getVariantValue
633
- */
634
- get_variant_value(featureName, fallbackValue, callback) {
635
- return this.getVariantValue(featureName, fallbackValue, callback);
636
- }
637
-
638
- /**
639
- * Alias for {@link getVariantValueSync}. Provided for API consistency with mixpanel-js.
640
- * @see getVariantValueSync
641
- */
642
- get_variant_value_sync(featureName, fallbackValue) {
643
- return this.getVariantValueSync(featureName, fallbackValue);
644
- }
645
-
646
- /**
647
- * Alias for {@link isEnabled}. Provided for API consistency with mixpanel-js.
648
- * @see isEnabled
649
- */
650
- is_enabled(featureName, fallbackValue, callback) {
651
- return this.isEnabled(featureName, fallbackValue, callback);
652
- }
653
-
654
- /**
655
- * Alias for {@link isEnabledSync}. Provided for API consistency with mixpanel-js.
656
- * @see isEnabledSync
657
- */
658
- is_enabled_sync(featureName, fallbackValue) {
659
- return this.isEnabledSync(featureName, fallbackValue);
660
- }
661
-
662
- /**
663
- * Alias for {@link updateContext}. Provided for API consistency with mixpanel-js.
664
- * JavaScript mode only.
665
- * @see updateContext
666
- */
667
- update_context(newContext, options) {
668
- return this.updateContext(newContext, options);
669
- }
670
- }