mixpanel-browser 2.77.0 → 2.78.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 +3 -1
- package/CHANGELOG.md +4 -0
- package/dist/async-modules/{mixpanel-recorder-wIWnMDLA.min.js → mixpanel-recorder-BjSlYaNJ.min.js} +2 -2
- package/dist/async-modules/{mixpanel-recorder-wIWnMDLA.min.js.map → mixpanel-recorder-BjSlYaNJ.min.js.map} +1 -1
- package/dist/async-modules/{mixpanel-recorder-DLKbUIEE.js → mixpanel-recorder-zMBXIyeG.js} +1 -1
- package/dist/async-modules/{mixpanel-targeting-CTcftSJC.min.js → mixpanel-targeting-BSHal4N9.min.js} +2 -2
- package/dist/async-modules/{mixpanel-targeting-CTcftSJC.min.js.map → mixpanel-targeting-BSHal4N9.min.js.map} +1 -1
- package/dist/async-modules/{mixpanel-targeting-CmVvUyFM.js → mixpanel-targeting-UHf4eBfC.js} +1 -1
- package/dist/mixpanel-core.cjs.d.ts +1 -0
- package/dist/mixpanel-core.cjs.js +111 -80
- package/dist/mixpanel-recorder.js +1 -1
- package/dist/mixpanel-recorder.min.js +1 -1
- package/dist/mixpanel-recorder.min.js.map +1 -1
- package/dist/mixpanel-targeting.js +1 -1
- package/dist/mixpanel-targeting.min.js +1 -1
- package/dist/mixpanel-targeting.min.js.map +1 -1
- package/dist/mixpanel-with-async-modules.cjs.d.ts +1 -0
- package/dist/mixpanel-with-async-modules.cjs.js +113 -82
- package/dist/mixpanel-with-async-recorder.cjs.d.ts +1 -0
- package/dist/mixpanel-with-async-recorder.cjs.js +113 -82
- package/dist/mixpanel-with-recorder.d.ts +1 -0
- package/dist/mixpanel-with-recorder.js +111 -80
- package/dist/mixpanel-with-recorder.min.d.ts +1 -0
- package/dist/mixpanel-with-recorder.min.js +1 -1
- package/dist/mixpanel.amd.d.ts +1 -0
- package/dist/mixpanel.amd.js +111 -80
- package/dist/mixpanel.cjs.d.ts +1 -0
- package/dist/mixpanel.cjs.js +111 -80
- package/dist/mixpanel.globals.js +113 -82
- package/dist/mixpanel.min.js +180 -179
- package/dist/mixpanel.module.d.ts +1 -0
- package/dist/mixpanel.module.js +111 -80
- package/dist/mixpanel.umd.d.ts +1 -0
- package/dist/mixpanel.umd.js +111 -80
- package/package.json +1 -1
- package/src/config.js +1 -1
- package/src/flags/CLAUDE.md +24 -0
- package/src/flags/index.js +109 -80
- package/src/index.d.ts +1 -0
- package/src/mixpanel-core.js +3 -1
- package/testServer.js +2 -0
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
|
|
29
29
|
var Config = {
|
|
30
30
|
DEBUG: false,
|
|
31
|
-
LIB_VERSION: '2.
|
|
31
|
+
LIB_VERSION: '2.78.0'
|
|
32
32
|
};
|
|
33
33
|
|
|
34
34
|
// Window global names for async modules
|
|
@@ -25663,7 +25663,9 @@
|
|
|
25663
25663
|
}
|
|
25664
25664
|
|
|
25665
25665
|
this.flags = null;
|
|
25666
|
-
this.fetchFlags()
|
|
25666
|
+
this.fetchFlags().catch(function() {
|
|
25667
|
+
logger$1.error('Error fetching flags during init');
|
|
25668
|
+
});
|
|
25667
25669
|
|
|
25668
25670
|
this.trackedFeatures = new Set();
|
|
25669
25671
|
this.pendingFirstTimeEvents = {};
|
|
@@ -25704,8 +25706,12 @@
|
|
|
25704
25706
|
var oldContext = (options && options['replace']) ? {} : this.getConfig(CONFIG_CONTEXT);
|
|
25705
25707
|
ffConfig[CONFIG_CONTEXT] = _.extend({}, oldContext, newContext);
|
|
25706
25708
|
|
|
25707
|
-
|
|
25708
|
-
|
|
25709
|
+
var configUpdate = {};
|
|
25710
|
+
configUpdate[FLAGS_CONFIG_KEY] = ffConfig;
|
|
25711
|
+
this.setMpConfig(configUpdate);
|
|
25712
|
+
return this.fetchFlags().catch(function() {
|
|
25713
|
+
logger$1.error('Error fetching flags during updateContext');
|
|
25714
|
+
});
|
|
25709
25715
|
};
|
|
25710
25716
|
|
|
25711
25717
|
FeatureFlagManager.prototype.areFlagsReady = function() {
|
|
@@ -25742,96 +25748,110 @@
|
|
|
25742
25748
|
}
|
|
25743
25749
|
}).then(function(response) {
|
|
25744
25750
|
this.markFetchComplete();
|
|
25745
|
-
return response.json()
|
|
25746
|
-
|
|
25747
|
-
|
|
25748
|
-
|
|
25749
|
-
|
|
25750
|
-
|
|
25751
|
-
|
|
25752
|
-
|
|
25753
|
-
|
|
25754
|
-
|
|
25755
|
-
|
|
25756
|
-
|
|
25757
|
-
|
|
25758
|
-
|
|
25759
|
-
|
|
25760
|
-
|
|
25761
|
-
|
|
25762
|
-
}
|
|
25751
|
+
return response.json();
|
|
25752
|
+
}.bind(this)).then(function(responseBody) {
|
|
25753
|
+
var responseFlags = responseBody['flags'];
|
|
25754
|
+
if (!responseFlags) {
|
|
25755
|
+
throw new Error('No flags in API response');
|
|
25756
|
+
}
|
|
25757
|
+
var flags = new Map();
|
|
25758
|
+
var pendingFirstTimeEvents = {};
|
|
25759
|
+
|
|
25760
|
+
// Process flags from response
|
|
25761
|
+
_.each(responseFlags, function(data, key) {
|
|
25762
|
+
// Check if this flag has any activated first-time events this session
|
|
25763
|
+
var hasActivatedEvent = false;
|
|
25764
|
+
var prefix = key + ':';
|
|
25765
|
+
_.each(this.activatedFirstTimeEvents, function(activated, eventKey) {
|
|
25766
|
+
if (eventKey.startsWith(prefix)) {
|
|
25767
|
+
hasActivatedEvent = true;
|
|
25768
|
+
}
|
|
25769
|
+
});
|
|
25763
25770
|
|
|
25764
|
-
|
|
25765
|
-
|
|
25766
|
-
|
|
25767
|
-
|
|
25768
|
-
|
|
25769
|
-
}
|
|
25770
|
-
} else {
|
|
25771
|
-
// Use server's current variant
|
|
25772
|
-
flags.set(key, {
|
|
25773
|
-
'key': data['variant_key'],
|
|
25774
|
-
'value': data['variant_value'],
|
|
25775
|
-
'experiment_id': data['experiment_id'],
|
|
25776
|
-
'is_experiment_active': data['is_experiment_active'],
|
|
25777
|
-
'is_qa_tester': data['is_qa_tester']
|
|
25778
|
-
});
|
|
25771
|
+
if (hasActivatedEvent) {
|
|
25772
|
+
// Preserve the activated variant, don't overwrite with server's current variant
|
|
25773
|
+
var currentFlag = this.flags && this.flags.get(key);
|
|
25774
|
+
if (currentFlag) {
|
|
25775
|
+
flags.set(key, currentFlag);
|
|
25779
25776
|
}
|
|
25780
|
-
}
|
|
25777
|
+
} else {
|
|
25778
|
+
// Use server's current variant
|
|
25779
|
+
flags.set(key, {
|
|
25780
|
+
'key': data['variant_key'],
|
|
25781
|
+
'value': data['variant_value'],
|
|
25782
|
+
'experiment_id': data['experiment_id'],
|
|
25783
|
+
'is_experiment_active': data['is_experiment_active'],
|
|
25784
|
+
'is_qa_tester': data['is_qa_tester']
|
|
25785
|
+
});
|
|
25786
|
+
}
|
|
25787
|
+
}, this);
|
|
25781
25788
|
|
|
25782
|
-
|
|
25783
|
-
|
|
25784
|
-
|
|
25785
|
-
|
|
25786
|
-
|
|
25787
|
-
|
|
25789
|
+
// Process top-level pending_first_time_events array
|
|
25790
|
+
var topLevelDefinitions = responseBody['pending_first_time_events'];
|
|
25791
|
+
if (topLevelDefinitions && topLevelDefinitions.length > 0) {
|
|
25792
|
+
_.each(topLevelDefinitions, function(def) {
|
|
25793
|
+
var flagKey = def['flag_key'];
|
|
25794
|
+
var eventKey = getPendingEventKey(flagKey, def['first_time_event_hash']);
|
|
25788
25795
|
|
|
25789
|
-
|
|
25790
|
-
|
|
25791
|
-
|
|
25792
|
-
|
|
25796
|
+
// Skip if this specific event has already been activated this session
|
|
25797
|
+
if (this.activatedFirstTimeEvents[eventKey]) {
|
|
25798
|
+
return;
|
|
25799
|
+
}
|
|
25793
25800
|
|
|
25794
|
-
|
|
25795
|
-
|
|
25796
|
-
|
|
25797
|
-
|
|
25798
|
-
|
|
25799
|
-
|
|
25800
|
-
|
|
25801
|
-
|
|
25802
|
-
|
|
25803
|
-
|
|
25804
|
-
|
|
25805
|
-
|
|
25801
|
+
// Store pending event definition using composite key
|
|
25802
|
+
pendingFirstTimeEvents[eventKey] = {
|
|
25803
|
+
'flag_key': flagKey,
|
|
25804
|
+
'flag_id': def['flag_id'],
|
|
25805
|
+
'project_id': def['project_id'],
|
|
25806
|
+
'first_time_event_hash': def['first_time_event_hash'],
|
|
25807
|
+
'event_name': def['event_name'],
|
|
25808
|
+
'property_filters': def['property_filters'],
|
|
25809
|
+
'pending_variant': def['pending_variant']
|
|
25810
|
+
};
|
|
25811
|
+
}, this);
|
|
25812
|
+
}
|
|
25806
25813
|
|
|
25807
|
-
|
|
25808
|
-
|
|
25809
|
-
|
|
25810
|
-
|
|
25811
|
-
|
|
25812
|
-
|
|
25813
|
-
|
|
25814
|
-
|
|
25815
|
-
|
|
25816
|
-
|
|
25814
|
+
// Preserve any activated orphaned flags (flags that were activated but are no longer in response)
|
|
25815
|
+
if (this.activatedFirstTimeEvents) {
|
|
25816
|
+
_.each(this.activatedFirstTimeEvents, function(activated, eventKey) {
|
|
25817
|
+
var flagKey = getFlagKeyFromPendingEventKey(eventKey);
|
|
25818
|
+
if (activated && !flags.has(flagKey) && this.flags && this.flags.has(flagKey)) {
|
|
25819
|
+
// Keep the activated flag even though it's not in the new response
|
|
25820
|
+
flags.set(flagKey, this.flags.get(flagKey));
|
|
25821
|
+
}
|
|
25822
|
+
}, this);
|
|
25823
|
+
}
|
|
25817
25824
|
|
|
25818
|
-
|
|
25819
|
-
|
|
25820
|
-
|
|
25825
|
+
this.flags = flags;
|
|
25826
|
+
this.pendingFirstTimeEvents = pendingFirstTimeEvents;
|
|
25827
|
+
this._traceparent = traceparent;
|
|
25821
25828
|
|
|
25822
|
-
|
|
25823
|
-
}.bind(this)).catch(function(error) {
|
|
25824
|
-
this.markFetchComplete();
|
|
25825
|
-
logger$1.error(error);
|
|
25826
|
-
}.bind(this));
|
|
25829
|
+
this._loadTargetingIfNeeded();
|
|
25827
25830
|
}.bind(this)).catch(function(error) {
|
|
25828
|
-
this.
|
|
25831
|
+
if (this._fetchInProgressStartTime) {
|
|
25832
|
+
this.markFetchComplete();
|
|
25833
|
+
}
|
|
25829
25834
|
logger$1.error(error);
|
|
25835
|
+
throw error;
|
|
25830
25836
|
}.bind(this));
|
|
25831
25837
|
|
|
25832
25838
|
return this.fetchPromise;
|
|
25833
25839
|
};
|
|
25834
25840
|
|
|
25841
|
+
FeatureFlagManager.prototype.loadFlags = function() {
|
|
25842
|
+
if (!this.isSystemEnabled()) {
|
|
25843
|
+
return Promise.resolve();
|
|
25844
|
+
}
|
|
25845
|
+
if (!this.trackedFeatures) {
|
|
25846
|
+
logger$1.error('loadFlags called before init');
|
|
25847
|
+
return Promise.resolve();
|
|
25848
|
+
}
|
|
25849
|
+
if (this._fetchInProgressStartTime) {
|
|
25850
|
+
return this.fetchPromise;
|
|
25851
|
+
}
|
|
25852
|
+
return this.fetchFlags();
|
|
25853
|
+
};
|
|
25854
|
+
|
|
25835
25855
|
FeatureFlagManager.prototype.markFetchComplete = function() {
|
|
25836
25856
|
if (!this._fetchInProgressStartTime) {
|
|
25837
25857
|
logger$1.error('Fetch in progress started time not set, cannot mark fetch complete');
|
|
@@ -26111,6 +26131,13 @@
|
|
|
26111
26131
|
this.track('$experiment_started', trackingProperties);
|
|
26112
26132
|
};
|
|
26113
26133
|
|
|
26134
|
+
FeatureFlagManager.prototype.whenReady = function() {
|
|
26135
|
+
if (this.fetchPromise) {
|
|
26136
|
+
return this.fetchPromise;
|
|
26137
|
+
}
|
|
26138
|
+
return Promise.resolve();
|
|
26139
|
+
};
|
|
26140
|
+
|
|
26114
26141
|
FeatureFlagManager.prototype.minApisSupported = function() {
|
|
26115
26142
|
return !!this.fetch &&
|
|
26116
26143
|
typeof Promise !== 'undefined' &&
|
|
@@ -26127,7 +26154,9 @@
|
|
|
26127
26154
|
FeatureFlagManager.prototype['get_variant_value_sync'] = FeatureFlagManager.prototype.getVariantValueSync;
|
|
26128
26155
|
FeatureFlagManager.prototype['is_enabled'] = FeatureFlagManager.prototype.isEnabled;
|
|
26129
26156
|
FeatureFlagManager.prototype['is_enabled_sync'] = FeatureFlagManager.prototype.isEnabledSync;
|
|
26157
|
+
FeatureFlagManager.prototype['load_flags'] = FeatureFlagManager.prototype.loadFlags;
|
|
26130
26158
|
FeatureFlagManager.prototype['update_context'] = FeatureFlagManager.prototype.updateContext;
|
|
26159
|
+
FeatureFlagManager.prototype['when_ready'] = FeatureFlagManager.prototype.whenReady;
|
|
26131
26160
|
|
|
26132
26161
|
// Deprecated method
|
|
26133
26162
|
FeatureFlagManager.prototype['get_feature_data'] = FeatureFlagManager.prototype.getFeatureData;
|
|
@@ -29483,7 +29512,9 @@
|
|
|
29483
29512
|
|
|
29484
29513
|
// check feature flags again if distinct id has changed
|
|
29485
29514
|
if (new_distinct_id !== previous_distinct_id) {
|
|
29486
|
-
this.flags.fetchFlags()
|
|
29515
|
+
this.flags.fetchFlags().catch(function() {
|
|
29516
|
+
console$1.error('[flags] Error fetching flags during identify');
|
|
29517
|
+
});
|
|
29487
29518
|
}
|
|
29488
29519
|
};
|
|
29489
29520
|
|