mixpanel-browser 2.65.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 +12 -0
- package/README.md +1 -1
- package/dist/mixpanel-core.cjs.js +61 -21
- package/dist/mixpanel-recorder.js +53 -21
- 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 +61 -21
- package/dist/mixpanel-with-recorder.js +113 -41
- package/dist/mixpanel-with-recorder.min.js +1 -1
- package/dist/mixpanel.amd.js +113 -41
- package/dist/mixpanel.cjs.js +113 -41
- package/dist/mixpanel.globals.js +61 -21
- package/dist/mixpanel.min.js +140 -139
- package/dist/mixpanel.module.js +113 -41
- package/dist/mixpanel.umd.js +113 -41
- package/package.json +2 -1
- package/src/config.js +1 -1
- package/src/flags/index.js +29 -7
- package/src/index.d.ts +408 -0
- package/src/mixpanel-core.js +29 -11
- package/src/mixpanel-group.js +1 -1
- package/src/mixpanel-people.js +1 -1
- package/src/recorder/recorder.js +15 -7
- package/src/recorder/session-recording.js +37 -13
- package/tunnel.log +0 -0
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();
|
|
@@ -17351,8 +17385,8 @@ SessionRecording.prototype._sendRequest = function(currentReplayId, reqParams, r
|
|
|
17351
17385
|
retryAfter: response.headers.get('Retry-After')
|
|
17352
17386
|
});
|
|
17353
17387
|
}.bind(this);
|
|
17354
|
-
|
|
17355
|
-
win['fetch'](
|
|
17388
|
+
var apiHost = (this._mixpanel.get_api_host && this._mixpanel.get_api_host('record')) || this.getConfig('api_host');
|
|
17389
|
+
win['fetch'](apiHost + '/' + this.getConfig('api_routes')['record'] + '?' + new URLSearchParams(reqParams), {
|
|
17356
17390
|
'method': 'POST',
|
|
17357
17391
|
'headers': {
|
|
17358
17392
|
'Authorization': 'Basic ' + btoa(this.getConfig('token') + ':'),
|
|
@@ -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();
|
|
@@ -17569,6 +17593,7 @@ var MixpanelRecorder = function(mixpanelInstance, rrwebRecord, sharedLockStorage
|
|
|
17569
17593
|
this._flushInactivePromise = this.recordingRegistry.flushInactiveRecordings();
|
|
17570
17594
|
|
|
17571
17595
|
this.activeRecording = null;
|
|
17596
|
+
this.stopRecordingInProgress = false;
|
|
17572
17597
|
};
|
|
17573
17598
|
|
|
17574
17599
|
MixpanelRecorder.prototype.startRecording = function(options) {
|
|
@@ -17617,19 +17642,26 @@ MixpanelRecorder.prototype.startRecording = function(options) {
|
|
|
17617
17642
|
};
|
|
17618
17643
|
|
|
17619
17644
|
MixpanelRecorder.prototype.stopRecording = function() {
|
|
17620
|
-
|
|
17621
|
-
this.
|
|
17622
|
-
this.
|
|
17623
|
-
|
|
17645
|
+
// Prevents activeSerializedRecording from being reused when stopping the recording.
|
|
17646
|
+
this.stopRecordingInProgress = true;
|
|
17647
|
+
return this._stopCurrentRecording(false, true).then(function() {
|
|
17648
|
+
return this.recordingRegistry.clearActiveRecording();
|
|
17649
|
+
}.bind(this)).then(function() {
|
|
17650
|
+
this.stopRecordingInProgress = false;
|
|
17651
|
+
}.bind(this));
|
|
17624
17652
|
};
|
|
17625
17653
|
|
|
17626
17654
|
MixpanelRecorder.prototype.pauseRecording = function() {
|
|
17627
17655
|
return this._stopCurrentRecording(false);
|
|
17628
17656
|
};
|
|
17629
17657
|
|
|
17630
|
-
MixpanelRecorder.prototype._stopCurrentRecording = function(skipFlush) {
|
|
17658
|
+
MixpanelRecorder.prototype._stopCurrentRecording = function(skipFlush, disableActiveRecording) {
|
|
17631
17659
|
if (this.activeRecording) {
|
|
17632
|
-
|
|
17660
|
+
var stopRecordingPromise = this.activeRecording.stopRecording(skipFlush);
|
|
17661
|
+
if (disableActiveRecording) {
|
|
17662
|
+
this.activeRecording = null;
|
|
17663
|
+
}
|
|
17664
|
+
return stopRecordingPromise;
|
|
17633
17665
|
}
|
|
17634
17666
|
return PromisePolyfill.resolve();
|
|
17635
17667
|
};
|
|
@@ -17642,7 +17674,7 @@ MixpanelRecorder.prototype.resumeRecording = function (startNewIfInactive) {
|
|
|
17642
17674
|
|
|
17643
17675
|
return this.recordingRegistry.getActiveRecording()
|
|
17644
17676
|
.then(function (activeSerializedRecording) {
|
|
17645
|
-
if (activeSerializedRecording) {
|
|
17677
|
+
if (activeSerializedRecording && !this.stopRecordingInProgress) {
|
|
17646
17678
|
return this.startRecording({activeSerializedRecording: activeSerializedRecording});
|
|
17647
17679
|
} else if (startNewIfInactive) {
|
|
17648
17680
|
return this.startRecording({shouldStopBatcher: false});
|
|
@@ -18545,8 +18577,9 @@ CONFIG_DEFAULTS[CONFIG_CONTEXT] = {};
|
|
|
18545
18577
|
* @constructor
|
|
18546
18578
|
*/
|
|
18547
18579
|
var FeatureFlagManager = function(initOptions) {
|
|
18580
|
+
this.getFullApiRoute = initOptions.getFullApiRoute;
|
|
18548
18581
|
this.getMpConfig = initOptions.getConfigFunc;
|
|
18549
|
-
this.
|
|
18582
|
+
this.getMpProperty = initOptions.getPropertyFunc;
|
|
18550
18583
|
this.track = initOptions.trackingFunc;
|
|
18551
18584
|
};
|
|
18552
18585
|
|
|
@@ -18595,12 +18628,14 @@ FeatureFlagManager.prototype.fetchFlags = function() {
|
|
|
18595
18628
|
return;
|
|
18596
18629
|
}
|
|
18597
18630
|
|
|
18598
|
-
var distinctId = this.
|
|
18631
|
+
var distinctId = this.getMpProperty('distinct_id');
|
|
18632
|
+
var deviceId = this.getMpProperty('$device_id');
|
|
18599
18633
|
logger.log('Fetching flags for distinct ID: ' + distinctId);
|
|
18600
18634
|
var reqParams = {
|
|
18601
|
-
'context': _.extend({'distinct_id': distinctId}, this.getConfig(CONFIG_CONTEXT))
|
|
18635
|
+
'context': _.extend({'distinct_id': distinctId, 'device_id': deviceId}, this.getConfig(CONFIG_CONTEXT))
|
|
18602
18636
|
};
|
|
18603
|
-
this.
|
|
18637
|
+
this._fetchInProgressStartTime = Date.now();
|
|
18638
|
+
this.fetchPromise = win['fetch'](this.getFullApiRoute(), {
|
|
18604
18639
|
'method': 'POST',
|
|
18605
18640
|
'headers': {
|
|
18606
18641
|
'Authorization': 'Basic ' + btoa(this.getMpConfig('token') + ':'),
|
|
@@ -18608,6 +18643,7 @@ FeatureFlagManager.prototype.fetchFlags = function() {
|
|
|
18608
18643
|
},
|
|
18609
18644
|
'body': JSON.stringify(reqParams)
|
|
18610
18645
|
}).then(function(response) {
|
|
18646
|
+
this.markFetchComplete();
|
|
18611
18647
|
return response.json().then(function(responseBody) {
|
|
18612
18648
|
var responseFlags = responseBody['flags'];
|
|
18613
18649
|
if (!responseFlags) {
|
|
@@ -18622,9 +18658,24 @@ FeatureFlagManager.prototype.fetchFlags = function() {
|
|
|
18622
18658
|
});
|
|
18623
18659
|
this.flags = flags;
|
|
18624
18660
|
}.bind(this)).catch(function(error) {
|
|
18661
|
+
this.markFetchComplete();
|
|
18625
18662
|
logger.error(error);
|
|
18626
|
-
});
|
|
18627
|
-
}.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;
|
|
18628
18679
|
};
|
|
18629
18680
|
|
|
18630
18681
|
FeatureFlagManager.prototype.getVariant = function(featureName, fallback) {
|
|
@@ -18703,7 +18754,10 @@ FeatureFlagManager.prototype.trackFeatureCheck = function(featureName, feature)
|
|
|
18703
18754
|
this.track('$experiment_started', {
|
|
18704
18755
|
'Experiment name': featureName,
|
|
18705
18756
|
'Variant name': feature['key'],
|
|
18706
|
-
'$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
|
|
18707
18761
|
});
|
|
18708
18762
|
};
|
|
18709
18763
|
|
|
@@ -19144,7 +19198,7 @@ MixpanelGroup.prototype._send_request = function(data, callback) {
|
|
|
19144
19198
|
return this._mixpanel._track_or_batch({
|
|
19145
19199
|
type: 'groups',
|
|
19146
19200
|
data: date_encoded_data,
|
|
19147
|
-
endpoint: this.
|
|
19201
|
+
endpoint: this._mixpanel.get_api_host('groups') + '/' + this._get_config('api_routes')['groups'],
|
|
19148
19202
|
batcher: this._mixpanel.request_batchers.groups
|
|
19149
19203
|
}, callback);
|
|
19150
19204
|
};
|
|
@@ -19496,7 +19550,7 @@ MixpanelPeople.prototype._send_request = function(data, callback) {
|
|
|
19496
19550
|
return this._mixpanel._track_or_batch({
|
|
19497
19551
|
type: 'people',
|
|
19498
19552
|
data: date_encoded_data,
|
|
19499
|
-
endpoint: this.
|
|
19553
|
+
endpoint: this._mixpanel.get_api_host('people') + '/' + this._get_config('api_routes')['engage'],
|
|
19500
19554
|
batcher: this._mixpanel.request_batchers.people
|
|
19501
19555
|
}, callback);
|
|
19502
19556
|
};
|
|
@@ -20133,6 +20187,7 @@ var DEFAULT_API_ROUTES = {
|
|
|
20133
20187
|
*/
|
|
20134
20188
|
var DEFAULT_CONFIG = {
|
|
20135
20189
|
'api_host': 'https://api-js.mixpanel.com',
|
|
20190
|
+
'api_hosts': {},
|
|
20136
20191
|
'api_routes': DEFAULT_API_ROUTES,
|
|
20137
20192
|
'api_extra_query_params': {},
|
|
20138
20193
|
'api_method': 'POST',
|
|
@@ -20402,8 +20457,11 @@ MixpanelLib.prototype._init = function(token, config, name) {
|
|
|
20402
20457
|
}
|
|
20403
20458
|
|
|
20404
20459
|
this.flags = new FeatureFlagManager({
|
|
20460
|
+
getFullApiRoute: _.bind(function() {
|
|
20461
|
+
return this.get_api_host('flags') + '/' + this.get_config('api_routes')['flags'];
|
|
20462
|
+
}, this),
|
|
20405
20463
|
getConfigFunc: _.bind(this.get_config, this),
|
|
20406
|
-
|
|
20464
|
+
getPropertyFunc: _.bind(this.get_property, this),
|
|
20407
20465
|
trackingFunc: _.bind(this.track, this)
|
|
20408
20466
|
});
|
|
20409
20467
|
this.flags.init();
|
|
@@ -20518,20 +20576,23 @@ MixpanelLib.prototype.start_session_recording = function () {
|
|
|
20518
20576
|
|
|
20519
20577
|
MixpanelLib.prototype.stop_session_recording = function () {
|
|
20520
20578
|
if (this._recorder) {
|
|
20521
|
-
this._recorder['stopRecording']();
|
|
20579
|
+
return this._recorder['stopRecording']();
|
|
20522
20580
|
}
|
|
20581
|
+
return Promise.resolve();
|
|
20523
20582
|
};
|
|
20524
20583
|
|
|
20525
20584
|
MixpanelLib.prototype.pause_session_recording = function () {
|
|
20526
20585
|
if (this._recorder) {
|
|
20527
|
-
this._recorder['pauseRecording']();
|
|
20586
|
+
return this._recorder['pauseRecording']();
|
|
20528
20587
|
}
|
|
20588
|
+
return Promise.resolve();
|
|
20529
20589
|
};
|
|
20530
20590
|
|
|
20531
20591
|
MixpanelLib.prototype.resume_session_recording = function () {
|
|
20532
20592
|
if (this._recorder) {
|
|
20533
|
-
this._recorder['resumeRecording']();
|
|
20593
|
+
return this._recorder['resumeRecording']();
|
|
20534
20594
|
}
|
|
20595
|
+
return Promise.resolve();
|
|
20535
20596
|
};
|
|
20536
20597
|
|
|
20537
20598
|
MixpanelLib.prototype.is_recording_heatmap_data = function () {
|
|
@@ -20886,11 +20947,10 @@ MixpanelLib.prototype.are_batchers_initialized = function() {
|
|
|
20886
20947
|
|
|
20887
20948
|
MixpanelLib.prototype.get_batcher_configs = function() {
|
|
20888
20949
|
var queue_prefix = '__mpq_' + this.get_config('token');
|
|
20889
|
-
var api_routes = this.get_config('api_routes');
|
|
20890
20950
|
this._batcher_configs = this._batcher_configs || {
|
|
20891
|
-
events: {type: 'events',
|
|
20892
|
-
people: {type: 'people',
|
|
20893
|
-
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'}
|
|
20894
20954
|
};
|
|
20895
20955
|
return this._batcher_configs;
|
|
20896
20956
|
};
|
|
@@ -20904,8 +20964,9 @@ MixpanelLib.prototype.init_batchers = function() {
|
|
|
20904
20964
|
libConfig: this['config'],
|
|
20905
20965
|
errorReporter: this.get_config('error_reporter'),
|
|
20906
20966
|
sendRequestFunc: _.bind(function(data, options, cb) {
|
|
20967
|
+
var api_routes = this.get_config('api_routes');
|
|
20907
20968
|
this._send_request(
|
|
20908
|
-
this.
|
|
20969
|
+
this.get_api_host(attrs.api_name) + '/' + api_routes[attrs.api_name],
|
|
20909
20970
|
this._encode_data_for_request(data),
|
|
20910
20971
|
options,
|
|
20911
20972
|
this._prepare_callback(cb, data)
|
|
@@ -21131,7 +21192,7 @@ MixpanelLib.prototype.track = addOptOutCheckMixpanelLib(function(event_name, pro
|
|
|
21131
21192
|
var ret = this._track_or_batch({
|
|
21132
21193
|
type: 'events',
|
|
21133
21194
|
data: data,
|
|
21134
|
-
endpoint: this.
|
|
21195
|
+
endpoint: this.get_api_host('events') + '/' + this.get_config('api_routes')['track'],
|
|
21135
21196
|
batcher: this.request_batchers.events,
|
|
21136
21197
|
should_send_immediately: should_send_immediately,
|
|
21137
21198
|
send_request_options: options
|
|
@@ -21633,6 +21694,7 @@ MixpanelLib.prototype.identify = function(
|
|
|
21633
21694
|
* Useful for clearing data when a user logs out.
|
|
21634
21695
|
*/
|
|
21635
21696
|
MixpanelLib.prototype.reset = function() {
|
|
21697
|
+
this.stop_session_recording();
|
|
21636
21698
|
this['persistence'].clear();
|
|
21637
21699
|
this._flags.identify_called = false;
|
|
21638
21700
|
var uuid = _.UUID();
|
|
@@ -21640,7 +21702,6 @@ MixpanelLib.prototype.reset = function() {
|
|
|
21640
21702
|
'distinct_id': DEVICE_ID_PREFIX + uuid,
|
|
21641
21703
|
'$device_id': uuid
|
|
21642
21704
|
}, '');
|
|
21643
|
-
this.stop_session_recording();
|
|
21644
21705
|
this._check_and_start_session_recording();
|
|
21645
21706
|
};
|
|
21646
21707
|
|
|
@@ -21952,6 +22013,16 @@ MixpanelLib.prototype.get_property = function(property_name) {
|
|
|
21952
22013
|
return this['persistence'].load_prop([property_name]);
|
|
21953
22014
|
};
|
|
21954
22015
|
|
|
22016
|
+
/**
|
|
22017
|
+
* Get the API host for a specific endpoint type, falling back to the default api_host if not specified
|
|
22018
|
+
*
|
|
22019
|
+
* @param {String} endpoint_type The type of endpoint (e.g., "events", "people", "groups")
|
|
22020
|
+
* @returns {String} The API host to use for this endpoint
|
|
22021
|
+
*/
|
|
22022
|
+
MixpanelLib.prototype.get_api_host = function(endpoint_type) {
|
|
22023
|
+
return this.get_config('api_hosts')[endpoint_type] || this.get_config('api_host');
|
|
22024
|
+
};
|
|
22025
|
+
|
|
21955
22026
|
MixpanelLib.prototype.toString = function() {
|
|
21956
22027
|
var name = this.get_config('name');
|
|
21957
22028
|
if (name !== PRIMARY_INSTANCE_NAME) {
|
|
@@ -22247,6 +22318,7 @@ MixpanelLib.prototype['alias'] = MixpanelLib.protot
|
|
|
22247
22318
|
MixpanelLib.prototype['name_tag'] = MixpanelLib.prototype.name_tag;
|
|
22248
22319
|
MixpanelLib.prototype['set_config'] = MixpanelLib.prototype.set_config;
|
|
22249
22320
|
MixpanelLib.prototype['get_config'] = MixpanelLib.prototype.get_config;
|
|
22321
|
+
MixpanelLib.prototype['get_api_host'] = MixpanelLib.prototype.get_api_host;
|
|
22250
22322
|
MixpanelLib.prototype['get_property'] = MixpanelLib.prototype.get_property;
|
|
22251
22323
|
MixpanelLib.prototype['get_distinct_id'] = MixpanelLib.prototype.get_distinct_id;
|
|
22252
22324
|
MixpanelLib.prototype['toString'] = MixpanelLib.prototype.toString;
|
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
|
|
|
@@ -4790,7 +4812,7 @@
|
|
|
4790
4812
|
return this._mixpanel._track_or_batch({
|
|
4791
4813
|
type: 'groups',
|
|
4792
4814
|
data: date_encoded_data,
|
|
4793
|
-
endpoint: this.
|
|
4815
|
+
endpoint: this._mixpanel.get_api_host('groups') + '/' + this._get_config('api_routes')['groups'],
|
|
4794
4816
|
batcher: this._mixpanel.request_batchers.groups
|
|
4795
4817
|
}, callback);
|
|
4796
4818
|
};
|
|
@@ -5142,7 +5164,7 @@
|
|
|
5142
5164
|
return this._mixpanel._track_or_batch({
|
|
5143
5165
|
type: 'people',
|
|
5144
5166
|
data: date_encoded_data,
|
|
5145
|
-
endpoint: this.
|
|
5167
|
+
endpoint: this._mixpanel.get_api_host('people') + '/' + this._get_config('api_routes')['engage'],
|
|
5146
5168
|
batcher: this._mixpanel.request_batchers.people
|
|
5147
5169
|
}, callback);
|
|
5148
5170
|
};
|
|
@@ -5902,6 +5924,7 @@
|
|
|
5902
5924
|
*/
|
|
5903
5925
|
var DEFAULT_CONFIG = {
|
|
5904
5926
|
'api_host': 'https://api-js.mixpanel.com',
|
|
5927
|
+
'api_hosts': {},
|
|
5905
5928
|
'api_routes': DEFAULT_API_ROUTES,
|
|
5906
5929
|
'api_extra_query_params': {},
|
|
5907
5930
|
'api_method': 'POST',
|
|
@@ -6171,8 +6194,11 @@
|
|
|
6171
6194
|
}
|
|
6172
6195
|
|
|
6173
6196
|
this.flags = new FeatureFlagManager({
|
|
6197
|
+
getFullApiRoute: _.bind(function() {
|
|
6198
|
+
return this.get_api_host('flags') + '/' + this.get_config('api_routes')['flags'];
|
|
6199
|
+
}, this),
|
|
6174
6200
|
getConfigFunc: _.bind(this.get_config, this),
|
|
6175
|
-
|
|
6201
|
+
getPropertyFunc: _.bind(this.get_property, this),
|
|
6176
6202
|
trackingFunc: _.bind(this.track, this)
|
|
6177
6203
|
});
|
|
6178
6204
|
this.flags.init();
|
|
@@ -6287,20 +6313,23 @@
|
|
|
6287
6313
|
|
|
6288
6314
|
MixpanelLib.prototype.stop_session_recording = function () {
|
|
6289
6315
|
if (this._recorder) {
|
|
6290
|
-
this._recorder['stopRecording']();
|
|
6316
|
+
return this._recorder['stopRecording']();
|
|
6291
6317
|
}
|
|
6318
|
+
return Promise.resolve();
|
|
6292
6319
|
};
|
|
6293
6320
|
|
|
6294
6321
|
MixpanelLib.prototype.pause_session_recording = function () {
|
|
6295
6322
|
if (this._recorder) {
|
|
6296
|
-
this._recorder['pauseRecording']();
|
|
6323
|
+
return this._recorder['pauseRecording']();
|
|
6297
6324
|
}
|
|
6325
|
+
return Promise.resolve();
|
|
6298
6326
|
};
|
|
6299
6327
|
|
|
6300
6328
|
MixpanelLib.prototype.resume_session_recording = function () {
|
|
6301
6329
|
if (this._recorder) {
|
|
6302
|
-
this._recorder['resumeRecording']();
|
|
6330
|
+
return this._recorder['resumeRecording']();
|
|
6303
6331
|
}
|
|
6332
|
+
return Promise.resolve();
|
|
6304
6333
|
};
|
|
6305
6334
|
|
|
6306
6335
|
MixpanelLib.prototype.is_recording_heatmap_data = function () {
|
|
@@ -6655,11 +6684,10 @@
|
|
|
6655
6684
|
|
|
6656
6685
|
MixpanelLib.prototype.get_batcher_configs = function() {
|
|
6657
6686
|
var queue_prefix = '__mpq_' + this.get_config('token');
|
|
6658
|
-
var api_routes = this.get_config('api_routes');
|
|
6659
6687
|
this._batcher_configs = this._batcher_configs || {
|
|
6660
|
-
events: {type: 'events',
|
|
6661
|
-
people: {type: 'people',
|
|
6662
|
-
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'}
|
|
6663
6691
|
};
|
|
6664
6692
|
return this._batcher_configs;
|
|
6665
6693
|
};
|
|
@@ -6673,8 +6701,9 @@
|
|
|
6673
6701
|
libConfig: this['config'],
|
|
6674
6702
|
errorReporter: this.get_config('error_reporter'),
|
|
6675
6703
|
sendRequestFunc: _.bind(function(data, options, cb) {
|
|
6704
|
+
var api_routes = this.get_config('api_routes');
|
|
6676
6705
|
this._send_request(
|
|
6677
|
-
this.
|
|
6706
|
+
this.get_api_host(attrs.api_name) + '/' + api_routes[attrs.api_name],
|
|
6678
6707
|
this._encode_data_for_request(data),
|
|
6679
6708
|
options,
|
|
6680
6709
|
this._prepare_callback(cb, data)
|
|
@@ -6900,7 +6929,7 @@
|
|
|
6900
6929
|
var ret = this._track_or_batch({
|
|
6901
6930
|
type: 'events',
|
|
6902
6931
|
data: data,
|
|
6903
|
-
endpoint: this.
|
|
6932
|
+
endpoint: this.get_api_host('events') + '/' + this.get_config('api_routes')['track'],
|
|
6904
6933
|
batcher: this.request_batchers.events,
|
|
6905
6934
|
should_send_immediately: should_send_immediately,
|
|
6906
6935
|
send_request_options: options
|
|
@@ -7402,6 +7431,7 @@
|
|
|
7402
7431
|
* Useful for clearing data when a user logs out.
|
|
7403
7432
|
*/
|
|
7404
7433
|
MixpanelLib.prototype.reset = function() {
|
|
7434
|
+
this.stop_session_recording();
|
|
7405
7435
|
this['persistence'].clear();
|
|
7406
7436
|
this._flags.identify_called = false;
|
|
7407
7437
|
var uuid = _.UUID();
|
|
@@ -7409,7 +7439,6 @@
|
|
|
7409
7439
|
'distinct_id': DEVICE_ID_PREFIX + uuid,
|
|
7410
7440
|
'$device_id': uuid
|
|
7411
7441
|
}, '');
|
|
7412
|
-
this.stop_session_recording();
|
|
7413
7442
|
this._check_and_start_session_recording();
|
|
7414
7443
|
};
|
|
7415
7444
|
|
|
@@ -7721,6 +7750,16 @@
|
|
|
7721
7750
|
return this['persistence'].load_prop([property_name]);
|
|
7722
7751
|
};
|
|
7723
7752
|
|
|
7753
|
+
/**
|
|
7754
|
+
* Get the API host for a specific endpoint type, falling back to the default api_host if not specified
|
|
7755
|
+
*
|
|
7756
|
+
* @param {String} endpoint_type The type of endpoint (e.g., "events", "people", "groups")
|
|
7757
|
+
* @returns {String} The API host to use for this endpoint
|
|
7758
|
+
*/
|
|
7759
|
+
MixpanelLib.prototype.get_api_host = function(endpoint_type) {
|
|
7760
|
+
return this.get_config('api_hosts')[endpoint_type] || this.get_config('api_host');
|
|
7761
|
+
};
|
|
7762
|
+
|
|
7724
7763
|
MixpanelLib.prototype.toString = function() {
|
|
7725
7764
|
var name = this.get_config('name');
|
|
7726
7765
|
if (name !== PRIMARY_INSTANCE_NAME) {
|
|
@@ -8016,6 +8055,7 @@
|
|
|
8016
8055
|
MixpanelLib.prototype['name_tag'] = MixpanelLib.prototype.name_tag;
|
|
8017
8056
|
MixpanelLib.prototype['set_config'] = MixpanelLib.prototype.set_config;
|
|
8018
8057
|
MixpanelLib.prototype['get_config'] = MixpanelLib.prototype.get_config;
|
|
8058
|
+
MixpanelLib.prototype['get_api_host'] = MixpanelLib.prototype.get_api_host;
|
|
8019
8059
|
MixpanelLib.prototype['get_property'] = MixpanelLib.prototype.get_property;
|
|
8020
8060
|
MixpanelLib.prototype['get_distinct_id'] = MixpanelLib.prototype.get_distinct_id;
|
|
8021
8061
|
MixpanelLib.prototype['toString'] = MixpanelLib.prototype.toString;
|