mixpanel-browser 2.66.0 → 2.67.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/.github/dependabot.yml +7 -0
- package/CHANGELOG.md +7 -0
- package/dist/mixpanel-core.cjs.js +48 -39
- package/dist/mixpanel-recorder.js +36 -12
- package/dist/mixpanel-recorder.min.js +1 -1
- package/dist/mixpanel-recorder.min.js.map +1 -1
- package/dist/mixpanel-with-async-recorder.cjs.js +48 -39
- package/dist/mixpanel-with-recorder.js +83 -50
- package/dist/mixpanel-with-recorder.min.js +1 -1
- package/dist/mixpanel.amd.js +83 -50
- package/dist/mixpanel.cjs.js +83 -50
- package/dist/mixpanel.globals.js +48 -39
- package/dist/mixpanel.min.js +139 -139
- package/dist/mixpanel.module.js +83 -50
- package/dist/mixpanel.umd.js +83 -50
- package/package.json +1 -1
- package/src/config.js +1 -1
- package/src/flags/index.js +29 -7
- package/src/mixpanel-core.js +18 -31
- package/src/recorder/session-recording.js +35 -11
package/dist/mixpanel.amd.js
CHANGED
|
@@ -13944,7 +13944,7 @@ define((function () { 'use strict';
|
|
|
13944
13944
|
|
|
13945
13945
|
var Config = {
|
|
13946
13946
|
DEBUG: false,
|
|
13947
|
-
LIB_VERSION: '2.
|
|
13947
|
+
LIB_VERSION: '2.67.0'
|
|
13948
13948
|
};
|
|
13949
13949
|
|
|
13950
13950
|
/* eslint camelcase: "off", eqeqeq: "off" */
|
|
@@ -17062,6 +17062,13 @@ define((function () { 'use strict';
|
|
|
17062
17062
|
* @property {string} replayStartUrl
|
|
17063
17063
|
*/
|
|
17064
17064
|
|
|
17065
|
+
/**
|
|
17066
|
+
* @typedef {Object} UserIdInfo
|
|
17067
|
+
* @property {string} distinct_id
|
|
17068
|
+
* @property {string} user_id
|
|
17069
|
+
* @property {string} device_id
|
|
17070
|
+
*/
|
|
17071
|
+
|
|
17065
17072
|
|
|
17066
17073
|
/**
|
|
17067
17074
|
* This class encapsulates a single session recording and its lifecycle.
|
|
@@ -17117,6 +17124,30 @@ define((function () { 'use strict';
|
|
|
17117
17124
|
});
|
|
17118
17125
|
};
|
|
17119
17126
|
|
|
17127
|
+
/**
|
|
17128
|
+
* @returns {UserIdInfo}
|
|
17129
|
+
*/
|
|
17130
|
+
SessionRecording.prototype.getUserIdInfo = function () {
|
|
17131
|
+
if (this.finalFlushUserIdInfo) {
|
|
17132
|
+
return this.finalFlushUserIdInfo;
|
|
17133
|
+
}
|
|
17134
|
+
|
|
17135
|
+
var userIdInfo = {
|
|
17136
|
+
'distinct_id': String(this._mixpanel.get_distinct_id()),
|
|
17137
|
+
};
|
|
17138
|
+
|
|
17139
|
+
// send ID management props if they exist
|
|
17140
|
+
var deviceId = this._mixpanel.get_property('$device_id');
|
|
17141
|
+
if (deviceId) {
|
|
17142
|
+
userIdInfo['$device_id'] = deviceId;
|
|
17143
|
+
}
|
|
17144
|
+
var userId = this._mixpanel.get_property('$user_id');
|
|
17145
|
+
if (userId) {
|
|
17146
|
+
userIdInfo['$user_id'] = userId;
|
|
17147
|
+
}
|
|
17148
|
+
return userIdInfo;
|
|
17149
|
+
};
|
|
17150
|
+
|
|
17120
17151
|
SessionRecording.prototype.unloadPersistedData = function () {
|
|
17121
17152
|
this.batcher.stop();
|
|
17122
17153
|
return this.batcher.flush()
|
|
@@ -17241,6 +17272,9 @@ define((function () { 'use strict';
|
|
|
17241
17272
|
};
|
|
17242
17273
|
|
|
17243
17274
|
SessionRecording.prototype.stopRecording = function (skipFlush) {
|
|
17275
|
+
// store the user ID info in case this is getting called in mixpanel.reset()
|
|
17276
|
+
this.finalFlushUserIdInfo = this.getUserIdInfo();
|
|
17277
|
+
|
|
17244
17278
|
if (!this.isRrwebStopped()) {
|
|
17245
17279
|
try {
|
|
17246
17280
|
this._stopRecording();
|
|
@@ -17406,7 +17440,6 @@ define((function () { 'use strict';
|
|
|
17406
17440
|
'$current_url': this.batchStartUrl,
|
|
17407
17441
|
'$lib_version': Config.LIB_VERSION,
|
|
17408
17442
|
'batch_start_time': batchStartTime / 1000,
|
|
17409
|
-
'distinct_id': String(this._mixpanel.get_distinct_id()),
|
|
17410
17443
|
'mp_lib': 'web',
|
|
17411
17444
|
'replay_id': replayId,
|
|
17412
17445
|
'replay_length_ms': replayLengthMs,
|
|
@@ -17415,16 +17448,7 @@ define((function () { 'use strict';
|
|
|
17415
17448
|
'seq': this.seqNo
|
|
17416
17449
|
};
|
|
17417
17450
|
var eventsJson = JSON.stringify(data);
|
|
17418
|
-
|
|
17419
|
-
// send ID management props if they exist
|
|
17420
|
-
var deviceId = this._mixpanel.get_property('$device_id');
|
|
17421
|
-
if (deviceId) {
|
|
17422
|
-
reqParams['$device_id'] = deviceId;
|
|
17423
|
-
}
|
|
17424
|
-
var userId = this._mixpanel.get_property('$user_id');
|
|
17425
|
-
if (userId) {
|
|
17426
|
-
reqParams['$user_id'] = userId;
|
|
17427
|
-
}
|
|
17451
|
+
Object.assign(reqParams, this.getUserIdInfo());
|
|
17428
17452
|
|
|
17429
17453
|
if (CompressionStream) {
|
|
17430
17454
|
var jsonStream = new Blob([eventsJson], {type: 'application/json'}).stream();
|
|
@@ -18553,8 +18577,9 @@ define((function () { 'use strict';
|
|
|
18553
18577
|
* @constructor
|
|
18554
18578
|
*/
|
|
18555
18579
|
var FeatureFlagManager = function(initOptions) {
|
|
18580
|
+
this.getFullApiRoute = initOptions.getFullApiRoute;
|
|
18556
18581
|
this.getMpConfig = initOptions.getConfigFunc;
|
|
18557
|
-
this.
|
|
18582
|
+
this.getMpProperty = initOptions.getPropertyFunc;
|
|
18558
18583
|
this.track = initOptions.trackingFunc;
|
|
18559
18584
|
};
|
|
18560
18585
|
|
|
@@ -18603,12 +18628,14 @@ define((function () { 'use strict';
|
|
|
18603
18628
|
return;
|
|
18604
18629
|
}
|
|
18605
18630
|
|
|
18606
|
-
var distinctId = this.
|
|
18631
|
+
var distinctId = this.getMpProperty('distinct_id');
|
|
18632
|
+
var deviceId = this.getMpProperty('$device_id');
|
|
18607
18633
|
logger.log('Fetching flags for distinct ID: ' + distinctId);
|
|
18608
18634
|
var reqParams = {
|
|
18609
|
-
'context': _.extend({'distinct_id': distinctId}, this.getConfig(CONFIG_CONTEXT))
|
|
18635
|
+
'context': _.extend({'distinct_id': distinctId, 'device_id': deviceId}, this.getConfig(CONFIG_CONTEXT))
|
|
18610
18636
|
};
|
|
18611
|
-
this.
|
|
18637
|
+
this._fetchInProgressStartTime = Date.now();
|
|
18638
|
+
this.fetchPromise = win['fetch'](this.getFullApiRoute(), {
|
|
18612
18639
|
'method': 'POST',
|
|
18613
18640
|
'headers': {
|
|
18614
18641
|
'Authorization': 'Basic ' + btoa(this.getMpConfig('token') + ':'),
|
|
@@ -18616,6 +18643,7 @@ define((function () { 'use strict';
|
|
|
18616
18643
|
},
|
|
18617
18644
|
'body': JSON.stringify(reqParams)
|
|
18618
18645
|
}).then(function(response) {
|
|
18646
|
+
this.markFetchComplete();
|
|
18619
18647
|
return response.json().then(function(responseBody) {
|
|
18620
18648
|
var responseFlags = responseBody['flags'];
|
|
18621
18649
|
if (!responseFlags) {
|
|
@@ -18630,9 +18658,24 @@ define((function () { 'use strict';
|
|
|
18630
18658
|
});
|
|
18631
18659
|
this.flags = flags;
|
|
18632
18660
|
}.bind(this)).catch(function(error) {
|
|
18661
|
+
this.markFetchComplete();
|
|
18633
18662
|
logger.error(error);
|
|
18634
|
-
});
|
|
18635
|
-
}.bind(this)).catch(function() {
|
|
18663
|
+
}.bind(this));
|
|
18664
|
+
}.bind(this)).catch(function(error) {
|
|
18665
|
+
this.markFetchComplete();
|
|
18666
|
+
logger.error(error);
|
|
18667
|
+
}.bind(this));
|
|
18668
|
+
};
|
|
18669
|
+
|
|
18670
|
+
FeatureFlagManager.prototype.markFetchComplete = function() {
|
|
18671
|
+
if (!this._fetchInProgressStartTime) {
|
|
18672
|
+
logger.error('Fetch in progress started time not set, cannot mark fetch complete');
|
|
18673
|
+
return;
|
|
18674
|
+
}
|
|
18675
|
+
this._fetchStartTime = this._fetchInProgressStartTime;
|
|
18676
|
+
this._fetchCompleteTime = Date.now();
|
|
18677
|
+
this._fetchLatency = this._fetchCompleteTime - this._fetchStartTime;
|
|
18678
|
+
this._fetchInProgressStartTime = null;
|
|
18636
18679
|
};
|
|
18637
18680
|
|
|
18638
18681
|
FeatureFlagManager.prototype.getVariant = function(featureName, fallback) {
|
|
@@ -18711,7 +18754,10 @@ define((function () { 'use strict';
|
|
|
18711
18754
|
this.track('$experiment_started', {
|
|
18712
18755
|
'Experiment name': featureName,
|
|
18713
18756
|
'Variant name': feature['key'],
|
|
18714
|
-
'$experiment_type': 'feature_flag'
|
|
18757
|
+
'$experiment_type': 'feature_flag',
|
|
18758
|
+
'Variant fetch start time': new Date(this._fetchStartTime).toISOString(),
|
|
18759
|
+
'Variant fetch complete time': new Date(this._fetchCompleteTime).toISOString(),
|
|
18760
|
+
'Variant fetch latency (ms)': this._fetchLatency
|
|
18715
18761
|
});
|
|
18716
18762
|
};
|
|
18717
18763
|
|
|
@@ -20411,8 +20457,11 @@ define((function () { 'use strict';
|
|
|
20411
20457
|
}
|
|
20412
20458
|
|
|
20413
20459
|
this.flags = new FeatureFlagManager({
|
|
20460
|
+
getFullApiRoute: _.bind(function() {
|
|
20461
|
+
return this.get_api_host('flags') + '/' + this.get_config('api_routes')['flags'];
|
|
20462
|
+
}, this),
|
|
20414
20463
|
getConfigFunc: _.bind(this.get_config, this),
|
|
20415
|
-
|
|
20464
|
+
getPropertyFunc: _.bind(this.get_property, this),
|
|
20416
20465
|
trackingFunc: _.bind(this.track, this)
|
|
20417
20466
|
});
|
|
20418
20467
|
this.flags.init();
|
|
@@ -20898,11 +20947,10 @@ define((function () { 'use strict';
|
|
|
20898
20947
|
|
|
20899
20948
|
MixpanelLib.prototype.get_batcher_configs = function() {
|
|
20900
20949
|
var queue_prefix = '__mpq_' + this.get_config('token');
|
|
20901
|
-
var api_routes = this.get_config('api_routes');
|
|
20902
20950
|
this._batcher_configs = this._batcher_configs || {
|
|
20903
|
-
events: {type: 'events',
|
|
20904
|
-
people: {type: 'people',
|
|
20905
|
-
groups: {type: 'groups',
|
|
20951
|
+
events: {type: 'events', api_name: 'track', queue_key: queue_prefix + '_ev'},
|
|
20952
|
+
people: {type: 'people', api_name: 'engage', queue_key: queue_prefix + '_pp'},
|
|
20953
|
+
groups: {type: 'groups', api_name: 'groups', queue_key: queue_prefix + '_gr'}
|
|
20906
20954
|
};
|
|
20907
20955
|
return this._batcher_configs;
|
|
20908
20956
|
};
|
|
@@ -20916,8 +20964,9 @@ define((function () { 'use strict';
|
|
|
20916
20964
|
libConfig: this['config'],
|
|
20917
20965
|
errorReporter: this.get_config('error_reporter'),
|
|
20918
20966
|
sendRequestFunc: _.bind(function(data, options, cb) {
|
|
20967
|
+
var api_routes = this.get_config('api_routes');
|
|
20919
20968
|
this._send_request(
|
|
20920
|
-
this.
|
|
20969
|
+
this.get_api_host(attrs.api_name) + '/' + api_routes[attrs.api_name],
|
|
20921
20970
|
this._encode_data_for_request(data),
|
|
20922
20971
|
options,
|
|
20923
20972
|
this._prepare_callback(cb, data)
|
|
@@ -21645,31 +21694,15 @@ define((function () { 'use strict';
|
|
|
21645
21694
|
* Useful for clearing data when a user logs out.
|
|
21646
21695
|
*/
|
|
21647
21696
|
MixpanelLib.prototype.reset = function() {
|
|
21648
|
-
|
|
21649
|
-
|
|
21650
|
-
|
|
21651
|
-
|
|
21652
|
-
|
|
21653
|
-
|
|
21654
|
-
|
|
21655
|
-
|
|
21656
|
-
|
|
21657
|
-
}, '');
|
|
21658
|
-
};
|
|
21659
|
-
|
|
21660
|
-
if (self._recorder) {
|
|
21661
|
-
self.stop_session_recording()
|
|
21662
|
-
.then(function () {
|
|
21663
|
-
reset();
|
|
21664
|
-
self._check_and_start_session_recording();
|
|
21665
|
-
})
|
|
21666
|
-
.catch(_.bind(function (err) {
|
|
21667
|
-
reset();
|
|
21668
|
-
this.report_error('Error restarting recording session', err);
|
|
21669
|
-
}, this));
|
|
21670
|
-
} else {
|
|
21671
|
-
reset();
|
|
21672
|
-
}
|
|
21697
|
+
this.stop_session_recording();
|
|
21698
|
+
this['persistence'].clear();
|
|
21699
|
+
this._flags.identify_called = false;
|
|
21700
|
+
var uuid = _.UUID();
|
|
21701
|
+
this.register_once({
|
|
21702
|
+
'distinct_id': DEVICE_ID_PREFIX + uuid,
|
|
21703
|
+
'$device_id': uuid
|
|
21704
|
+
}, '');
|
|
21705
|
+
this._check_and_start_session_recording();
|
|
21673
21706
|
};
|
|
21674
21707
|
|
|
21675
21708
|
/**
|
package/dist/mixpanel.cjs.js
CHANGED
|
@@ -13944,7 +13944,7 @@ if (typeof Promise !== 'undefined' && Promise.toString().indexOf('[native code]'
|
|
|
13944
13944
|
|
|
13945
13945
|
var Config = {
|
|
13946
13946
|
DEBUG: false,
|
|
13947
|
-
LIB_VERSION: '2.
|
|
13947
|
+
LIB_VERSION: '2.67.0'
|
|
13948
13948
|
};
|
|
13949
13949
|
|
|
13950
13950
|
/* eslint camelcase: "off", eqeqeq: "off" */
|
|
@@ -17062,6 +17062,13 @@ function isUserEvent(ev) {
|
|
|
17062
17062
|
* @property {string} replayStartUrl
|
|
17063
17063
|
*/
|
|
17064
17064
|
|
|
17065
|
+
/**
|
|
17066
|
+
* @typedef {Object} UserIdInfo
|
|
17067
|
+
* @property {string} distinct_id
|
|
17068
|
+
* @property {string} user_id
|
|
17069
|
+
* @property {string} device_id
|
|
17070
|
+
*/
|
|
17071
|
+
|
|
17065
17072
|
|
|
17066
17073
|
/**
|
|
17067
17074
|
* This class encapsulates a single session recording and its lifecycle.
|
|
@@ -17117,6 +17124,30 @@ var SessionRecording = function(options) {
|
|
|
17117
17124
|
});
|
|
17118
17125
|
};
|
|
17119
17126
|
|
|
17127
|
+
/**
|
|
17128
|
+
* @returns {UserIdInfo}
|
|
17129
|
+
*/
|
|
17130
|
+
SessionRecording.prototype.getUserIdInfo = function () {
|
|
17131
|
+
if (this.finalFlushUserIdInfo) {
|
|
17132
|
+
return this.finalFlushUserIdInfo;
|
|
17133
|
+
}
|
|
17134
|
+
|
|
17135
|
+
var userIdInfo = {
|
|
17136
|
+
'distinct_id': String(this._mixpanel.get_distinct_id()),
|
|
17137
|
+
};
|
|
17138
|
+
|
|
17139
|
+
// send ID management props if they exist
|
|
17140
|
+
var deviceId = this._mixpanel.get_property('$device_id');
|
|
17141
|
+
if (deviceId) {
|
|
17142
|
+
userIdInfo['$device_id'] = deviceId;
|
|
17143
|
+
}
|
|
17144
|
+
var userId = this._mixpanel.get_property('$user_id');
|
|
17145
|
+
if (userId) {
|
|
17146
|
+
userIdInfo['$user_id'] = userId;
|
|
17147
|
+
}
|
|
17148
|
+
return userIdInfo;
|
|
17149
|
+
};
|
|
17150
|
+
|
|
17120
17151
|
SessionRecording.prototype.unloadPersistedData = function () {
|
|
17121
17152
|
this.batcher.stop();
|
|
17122
17153
|
return this.batcher.flush()
|
|
@@ -17241,6 +17272,9 @@ SessionRecording.prototype.startRecording = function (shouldStopBatcher) {
|
|
|
17241
17272
|
};
|
|
17242
17273
|
|
|
17243
17274
|
SessionRecording.prototype.stopRecording = function (skipFlush) {
|
|
17275
|
+
// store the user ID info in case this is getting called in mixpanel.reset()
|
|
17276
|
+
this.finalFlushUserIdInfo = this.getUserIdInfo();
|
|
17277
|
+
|
|
17244
17278
|
if (!this.isRrwebStopped()) {
|
|
17245
17279
|
try {
|
|
17246
17280
|
this._stopRecording();
|
|
@@ -17406,7 +17440,6 @@ SessionRecording.prototype._flushEvents = addOptOutCheckMixpanelLib(function (da
|
|
|
17406
17440
|
'$current_url': this.batchStartUrl,
|
|
17407
17441
|
'$lib_version': Config.LIB_VERSION,
|
|
17408
17442
|
'batch_start_time': batchStartTime / 1000,
|
|
17409
|
-
'distinct_id': String(this._mixpanel.get_distinct_id()),
|
|
17410
17443
|
'mp_lib': 'web',
|
|
17411
17444
|
'replay_id': replayId,
|
|
17412
17445
|
'replay_length_ms': replayLengthMs,
|
|
@@ -17415,16 +17448,7 @@ SessionRecording.prototype._flushEvents = addOptOutCheckMixpanelLib(function (da
|
|
|
17415
17448
|
'seq': this.seqNo
|
|
17416
17449
|
};
|
|
17417
17450
|
var eventsJson = JSON.stringify(data);
|
|
17418
|
-
|
|
17419
|
-
// send ID management props if they exist
|
|
17420
|
-
var deviceId = this._mixpanel.get_property('$device_id');
|
|
17421
|
-
if (deviceId) {
|
|
17422
|
-
reqParams['$device_id'] = deviceId;
|
|
17423
|
-
}
|
|
17424
|
-
var userId = this._mixpanel.get_property('$user_id');
|
|
17425
|
-
if (userId) {
|
|
17426
|
-
reqParams['$user_id'] = userId;
|
|
17427
|
-
}
|
|
17451
|
+
Object.assign(reqParams, this.getUserIdInfo());
|
|
17428
17452
|
|
|
17429
17453
|
if (CompressionStream) {
|
|
17430
17454
|
var jsonStream = new Blob([eventsJson], {type: 'application/json'}).stream();
|
|
@@ -18553,8 +18577,9 @@ CONFIG_DEFAULTS[CONFIG_CONTEXT] = {};
|
|
|
18553
18577
|
* @constructor
|
|
18554
18578
|
*/
|
|
18555
18579
|
var FeatureFlagManager = function(initOptions) {
|
|
18580
|
+
this.getFullApiRoute = initOptions.getFullApiRoute;
|
|
18556
18581
|
this.getMpConfig = initOptions.getConfigFunc;
|
|
18557
|
-
this.
|
|
18582
|
+
this.getMpProperty = initOptions.getPropertyFunc;
|
|
18558
18583
|
this.track = initOptions.trackingFunc;
|
|
18559
18584
|
};
|
|
18560
18585
|
|
|
@@ -18603,12 +18628,14 @@ FeatureFlagManager.prototype.fetchFlags = function() {
|
|
|
18603
18628
|
return;
|
|
18604
18629
|
}
|
|
18605
18630
|
|
|
18606
|
-
var distinctId = this.
|
|
18631
|
+
var distinctId = this.getMpProperty('distinct_id');
|
|
18632
|
+
var deviceId = this.getMpProperty('$device_id');
|
|
18607
18633
|
logger.log('Fetching flags for distinct ID: ' + distinctId);
|
|
18608
18634
|
var reqParams = {
|
|
18609
|
-
'context': _.extend({'distinct_id': distinctId}, this.getConfig(CONFIG_CONTEXT))
|
|
18635
|
+
'context': _.extend({'distinct_id': distinctId, 'device_id': deviceId}, this.getConfig(CONFIG_CONTEXT))
|
|
18610
18636
|
};
|
|
18611
|
-
this.
|
|
18637
|
+
this._fetchInProgressStartTime = Date.now();
|
|
18638
|
+
this.fetchPromise = win['fetch'](this.getFullApiRoute(), {
|
|
18612
18639
|
'method': 'POST',
|
|
18613
18640
|
'headers': {
|
|
18614
18641
|
'Authorization': 'Basic ' + btoa(this.getMpConfig('token') + ':'),
|
|
@@ -18616,6 +18643,7 @@ FeatureFlagManager.prototype.fetchFlags = function() {
|
|
|
18616
18643
|
},
|
|
18617
18644
|
'body': JSON.stringify(reqParams)
|
|
18618
18645
|
}).then(function(response) {
|
|
18646
|
+
this.markFetchComplete();
|
|
18619
18647
|
return response.json().then(function(responseBody) {
|
|
18620
18648
|
var responseFlags = responseBody['flags'];
|
|
18621
18649
|
if (!responseFlags) {
|
|
@@ -18630,9 +18658,24 @@ FeatureFlagManager.prototype.fetchFlags = function() {
|
|
|
18630
18658
|
});
|
|
18631
18659
|
this.flags = flags;
|
|
18632
18660
|
}.bind(this)).catch(function(error) {
|
|
18661
|
+
this.markFetchComplete();
|
|
18633
18662
|
logger.error(error);
|
|
18634
|
-
});
|
|
18635
|
-
}.bind(this)).catch(function() {
|
|
18663
|
+
}.bind(this));
|
|
18664
|
+
}.bind(this)).catch(function(error) {
|
|
18665
|
+
this.markFetchComplete();
|
|
18666
|
+
logger.error(error);
|
|
18667
|
+
}.bind(this));
|
|
18668
|
+
};
|
|
18669
|
+
|
|
18670
|
+
FeatureFlagManager.prototype.markFetchComplete = function() {
|
|
18671
|
+
if (!this._fetchInProgressStartTime) {
|
|
18672
|
+
logger.error('Fetch in progress started time not set, cannot mark fetch complete');
|
|
18673
|
+
return;
|
|
18674
|
+
}
|
|
18675
|
+
this._fetchStartTime = this._fetchInProgressStartTime;
|
|
18676
|
+
this._fetchCompleteTime = Date.now();
|
|
18677
|
+
this._fetchLatency = this._fetchCompleteTime - this._fetchStartTime;
|
|
18678
|
+
this._fetchInProgressStartTime = null;
|
|
18636
18679
|
};
|
|
18637
18680
|
|
|
18638
18681
|
FeatureFlagManager.prototype.getVariant = function(featureName, fallback) {
|
|
@@ -18711,7 +18754,10 @@ FeatureFlagManager.prototype.trackFeatureCheck = function(featureName, feature)
|
|
|
18711
18754
|
this.track('$experiment_started', {
|
|
18712
18755
|
'Experiment name': featureName,
|
|
18713
18756
|
'Variant name': feature['key'],
|
|
18714
|
-
'$experiment_type': 'feature_flag'
|
|
18757
|
+
'$experiment_type': 'feature_flag',
|
|
18758
|
+
'Variant fetch start time': new Date(this._fetchStartTime).toISOString(),
|
|
18759
|
+
'Variant fetch complete time': new Date(this._fetchCompleteTime).toISOString(),
|
|
18760
|
+
'Variant fetch latency (ms)': this._fetchLatency
|
|
18715
18761
|
});
|
|
18716
18762
|
};
|
|
18717
18763
|
|
|
@@ -20411,8 +20457,11 @@ MixpanelLib.prototype._init = function(token, config, name) {
|
|
|
20411
20457
|
}
|
|
20412
20458
|
|
|
20413
20459
|
this.flags = new FeatureFlagManager({
|
|
20460
|
+
getFullApiRoute: _.bind(function() {
|
|
20461
|
+
return this.get_api_host('flags') + '/' + this.get_config('api_routes')['flags'];
|
|
20462
|
+
}, this),
|
|
20414
20463
|
getConfigFunc: _.bind(this.get_config, this),
|
|
20415
|
-
|
|
20464
|
+
getPropertyFunc: _.bind(this.get_property, this),
|
|
20416
20465
|
trackingFunc: _.bind(this.track, this)
|
|
20417
20466
|
});
|
|
20418
20467
|
this.flags.init();
|
|
@@ -20898,11 +20947,10 @@ MixpanelLib.prototype.are_batchers_initialized = function() {
|
|
|
20898
20947
|
|
|
20899
20948
|
MixpanelLib.prototype.get_batcher_configs = function() {
|
|
20900
20949
|
var queue_prefix = '__mpq_' + this.get_config('token');
|
|
20901
|
-
var api_routes = this.get_config('api_routes');
|
|
20902
20950
|
this._batcher_configs = this._batcher_configs || {
|
|
20903
|
-
events: {type: 'events',
|
|
20904
|
-
people: {type: 'people',
|
|
20905
|
-
groups: {type: 'groups',
|
|
20951
|
+
events: {type: 'events', api_name: 'track', queue_key: queue_prefix + '_ev'},
|
|
20952
|
+
people: {type: 'people', api_name: 'engage', queue_key: queue_prefix + '_pp'},
|
|
20953
|
+
groups: {type: 'groups', api_name: 'groups', queue_key: queue_prefix + '_gr'}
|
|
20906
20954
|
};
|
|
20907
20955
|
return this._batcher_configs;
|
|
20908
20956
|
};
|
|
@@ -20916,8 +20964,9 @@ MixpanelLib.prototype.init_batchers = function() {
|
|
|
20916
20964
|
libConfig: this['config'],
|
|
20917
20965
|
errorReporter: this.get_config('error_reporter'),
|
|
20918
20966
|
sendRequestFunc: _.bind(function(data, options, cb) {
|
|
20967
|
+
var api_routes = this.get_config('api_routes');
|
|
20919
20968
|
this._send_request(
|
|
20920
|
-
this.
|
|
20969
|
+
this.get_api_host(attrs.api_name) + '/' + api_routes[attrs.api_name],
|
|
20921
20970
|
this._encode_data_for_request(data),
|
|
20922
20971
|
options,
|
|
20923
20972
|
this._prepare_callback(cb, data)
|
|
@@ -21645,31 +21694,15 @@ MixpanelLib.prototype.identify = function(
|
|
|
21645
21694
|
* Useful for clearing data when a user logs out.
|
|
21646
21695
|
*/
|
|
21647
21696
|
MixpanelLib.prototype.reset = function() {
|
|
21648
|
-
|
|
21649
|
-
|
|
21650
|
-
|
|
21651
|
-
|
|
21652
|
-
|
|
21653
|
-
|
|
21654
|
-
|
|
21655
|
-
|
|
21656
|
-
|
|
21657
|
-
}, '');
|
|
21658
|
-
};
|
|
21659
|
-
|
|
21660
|
-
if (self._recorder) {
|
|
21661
|
-
self.stop_session_recording()
|
|
21662
|
-
.then(function () {
|
|
21663
|
-
reset();
|
|
21664
|
-
self._check_and_start_session_recording();
|
|
21665
|
-
})
|
|
21666
|
-
.catch(_.bind(function (err) {
|
|
21667
|
-
reset();
|
|
21668
|
-
this.report_error('Error restarting recording session', err);
|
|
21669
|
-
}, this));
|
|
21670
|
-
} else {
|
|
21671
|
-
reset();
|
|
21672
|
-
}
|
|
21697
|
+
this.stop_session_recording();
|
|
21698
|
+
this['persistence'].clear();
|
|
21699
|
+
this._flags.identify_called = false;
|
|
21700
|
+
var uuid = _.UUID();
|
|
21701
|
+
this.register_once({
|
|
21702
|
+
'distinct_id': DEVICE_ID_PREFIX + uuid,
|
|
21703
|
+
'$device_id': uuid
|
|
21704
|
+
}, '');
|
|
21705
|
+
this._check_and_start_session_recording();
|
|
21673
21706
|
};
|
|
21674
21707
|
|
|
21675
21708
|
/**
|
package/dist/mixpanel.globals.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
var Config = {
|
|
5
5
|
DEBUG: false,
|
|
6
|
-
LIB_VERSION: '2.
|
|
6
|
+
LIB_VERSION: '2.67.0'
|
|
7
7
|
};
|
|
8
8
|
|
|
9
9
|
// since es6 imports are static and we run unit tests from the console, window won't be defined when importing this file
|
|
@@ -3003,8 +3003,9 @@
|
|
|
3003
3003
|
* @constructor
|
|
3004
3004
|
*/
|
|
3005
3005
|
var FeatureFlagManager = function(initOptions) {
|
|
3006
|
+
this.getFullApiRoute = initOptions.getFullApiRoute;
|
|
3006
3007
|
this.getMpConfig = initOptions.getConfigFunc;
|
|
3007
|
-
this.
|
|
3008
|
+
this.getMpProperty = initOptions.getPropertyFunc;
|
|
3008
3009
|
this.track = initOptions.trackingFunc;
|
|
3009
3010
|
};
|
|
3010
3011
|
|
|
@@ -3053,12 +3054,14 @@
|
|
|
3053
3054
|
return;
|
|
3054
3055
|
}
|
|
3055
3056
|
|
|
3056
|
-
var distinctId = this.
|
|
3057
|
+
var distinctId = this.getMpProperty('distinct_id');
|
|
3058
|
+
var deviceId = this.getMpProperty('$device_id');
|
|
3057
3059
|
logger$3.log('Fetching flags for distinct ID: ' + distinctId);
|
|
3058
3060
|
var reqParams = {
|
|
3059
|
-
'context': _.extend({'distinct_id': distinctId}, this.getConfig(CONFIG_CONTEXT))
|
|
3061
|
+
'context': _.extend({'distinct_id': distinctId, 'device_id': deviceId}, this.getConfig(CONFIG_CONTEXT))
|
|
3060
3062
|
};
|
|
3061
|
-
this.
|
|
3063
|
+
this._fetchInProgressStartTime = Date.now();
|
|
3064
|
+
this.fetchPromise = win['fetch'](this.getFullApiRoute(), {
|
|
3062
3065
|
'method': 'POST',
|
|
3063
3066
|
'headers': {
|
|
3064
3067
|
'Authorization': 'Basic ' + btoa(this.getMpConfig('token') + ':'),
|
|
@@ -3066,6 +3069,7 @@
|
|
|
3066
3069
|
},
|
|
3067
3070
|
'body': JSON.stringify(reqParams)
|
|
3068
3071
|
}).then(function(response) {
|
|
3072
|
+
this.markFetchComplete();
|
|
3069
3073
|
return response.json().then(function(responseBody) {
|
|
3070
3074
|
var responseFlags = responseBody['flags'];
|
|
3071
3075
|
if (!responseFlags) {
|
|
@@ -3080,9 +3084,24 @@
|
|
|
3080
3084
|
});
|
|
3081
3085
|
this.flags = flags;
|
|
3082
3086
|
}.bind(this)).catch(function(error) {
|
|
3087
|
+
this.markFetchComplete();
|
|
3083
3088
|
logger$3.error(error);
|
|
3084
|
-
});
|
|
3085
|
-
}.bind(this)).catch(function() {
|
|
3089
|
+
}.bind(this));
|
|
3090
|
+
}.bind(this)).catch(function(error) {
|
|
3091
|
+
this.markFetchComplete();
|
|
3092
|
+
logger$3.error(error);
|
|
3093
|
+
}.bind(this));
|
|
3094
|
+
};
|
|
3095
|
+
|
|
3096
|
+
FeatureFlagManager.prototype.markFetchComplete = function() {
|
|
3097
|
+
if (!this._fetchInProgressStartTime) {
|
|
3098
|
+
logger$3.error('Fetch in progress started time not set, cannot mark fetch complete');
|
|
3099
|
+
return;
|
|
3100
|
+
}
|
|
3101
|
+
this._fetchStartTime = this._fetchInProgressStartTime;
|
|
3102
|
+
this._fetchCompleteTime = Date.now();
|
|
3103
|
+
this._fetchLatency = this._fetchCompleteTime - this._fetchStartTime;
|
|
3104
|
+
this._fetchInProgressStartTime = null;
|
|
3086
3105
|
};
|
|
3087
3106
|
|
|
3088
3107
|
FeatureFlagManager.prototype.getVariant = function(featureName, fallback) {
|
|
@@ -3161,7 +3180,10 @@
|
|
|
3161
3180
|
this.track('$experiment_started', {
|
|
3162
3181
|
'Experiment name': featureName,
|
|
3163
3182
|
'Variant name': feature['key'],
|
|
3164
|
-
'$experiment_type': 'feature_flag'
|
|
3183
|
+
'$experiment_type': 'feature_flag',
|
|
3184
|
+
'Variant fetch start time': new Date(this._fetchStartTime).toISOString(),
|
|
3185
|
+
'Variant fetch complete time': new Date(this._fetchCompleteTime).toISOString(),
|
|
3186
|
+
'Variant fetch latency (ms)': this._fetchLatency
|
|
3165
3187
|
});
|
|
3166
3188
|
};
|
|
3167
3189
|
|
|
@@ -6172,8 +6194,11 @@
|
|
|
6172
6194
|
}
|
|
6173
6195
|
|
|
6174
6196
|
this.flags = new FeatureFlagManager({
|
|
6197
|
+
getFullApiRoute: _.bind(function() {
|
|
6198
|
+
return this.get_api_host('flags') + '/' + this.get_config('api_routes')['flags'];
|
|
6199
|
+
}, this),
|
|
6175
6200
|
getConfigFunc: _.bind(this.get_config, this),
|
|
6176
|
-
|
|
6201
|
+
getPropertyFunc: _.bind(this.get_property, this),
|
|
6177
6202
|
trackingFunc: _.bind(this.track, this)
|
|
6178
6203
|
});
|
|
6179
6204
|
this.flags.init();
|
|
@@ -6659,11 +6684,10 @@
|
|
|
6659
6684
|
|
|
6660
6685
|
MixpanelLib.prototype.get_batcher_configs = function() {
|
|
6661
6686
|
var queue_prefix = '__mpq_' + this.get_config('token');
|
|
6662
|
-
var api_routes = this.get_config('api_routes');
|
|
6663
6687
|
this._batcher_configs = this._batcher_configs || {
|
|
6664
|
-
events: {type: 'events',
|
|
6665
|
-
people: {type: 'people',
|
|
6666
|
-
groups: {type: 'groups',
|
|
6688
|
+
events: {type: 'events', api_name: 'track', queue_key: queue_prefix + '_ev'},
|
|
6689
|
+
people: {type: 'people', api_name: 'engage', queue_key: queue_prefix + '_pp'},
|
|
6690
|
+
groups: {type: 'groups', api_name: 'groups', queue_key: queue_prefix + '_gr'}
|
|
6667
6691
|
};
|
|
6668
6692
|
return this._batcher_configs;
|
|
6669
6693
|
};
|
|
@@ -6677,8 +6701,9 @@
|
|
|
6677
6701
|
libConfig: this['config'],
|
|
6678
6702
|
errorReporter: this.get_config('error_reporter'),
|
|
6679
6703
|
sendRequestFunc: _.bind(function(data, options, cb) {
|
|
6704
|
+
var api_routes = this.get_config('api_routes');
|
|
6680
6705
|
this._send_request(
|
|
6681
|
-
this.
|
|
6706
|
+
this.get_api_host(attrs.api_name) + '/' + api_routes[attrs.api_name],
|
|
6682
6707
|
this._encode_data_for_request(data),
|
|
6683
6708
|
options,
|
|
6684
6709
|
this._prepare_callback(cb, data)
|
|
@@ -7406,31 +7431,15 @@
|
|
|
7406
7431
|
* Useful for clearing data when a user logs out.
|
|
7407
7432
|
*/
|
|
7408
7433
|
MixpanelLib.prototype.reset = function() {
|
|
7409
|
-
|
|
7410
|
-
|
|
7411
|
-
|
|
7412
|
-
|
|
7413
|
-
|
|
7414
|
-
|
|
7415
|
-
|
|
7416
|
-
|
|
7417
|
-
|
|
7418
|
-
}, '');
|
|
7419
|
-
};
|
|
7420
|
-
|
|
7421
|
-
if (self._recorder) {
|
|
7422
|
-
self.stop_session_recording()
|
|
7423
|
-
.then(function () {
|
|
7424
|
-
reset();
|
|
7425
|
-
self._check_and_start_session_recording();
|
|
7426
|
-
})
|
|
7427
|
-
.catch(_.bind(function (err) {
|
|
7428
|
-
reset();
|
|
7429
|
-
this.report_error('Error restarting recording session', err);
|
|
7430
|
-
}, this));
|
|
7431
|
-
} else {
|
|
7432
|
-
reset();
|
|
7433
|
-
}
|
|
7434
|
+
this.stop_session_recording();
|
|
7435
|
+
this['persistence'].clear();
|
|
7436
|
+
this._flags.identify_called = false;
|
|
7437
|
+
var uuid = _.UUID();
|
|
7438
|
+
this.register_once({
|
|
7439
|
+
'distinct_id': DEVICE_ID_PREFIX + uuid,
|
|
7440
|
+
'$device_id': uuid
|
|
7441
|
+
}, '');
|
|
7442
|
+
this._check_and_start_session_recording();
|
|
7434
7443
|
};
|
|
7435
7444
|
|
|
7436
7445
|
/**
|