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.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();
|
|
@@ -17351,8 +17385,8 @@ define((function () { 'use strict';
|
|
|
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 @@ 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();
|
|
@@ -17569,6 +17593,7 @@ define((function () { 'use strict';
|
|
|
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 @@ define((function () { 'use strict';
|
|
|
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 @@ define((function () { 'use strict';
|
|
|
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 @@ define((function () { 'use strict';
|
|
|
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 @@ define((function () { 'use strict';
|
|
|
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 @@ define((function () { 'use strict';
|
|
|
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 @@ define((function () { 'use strict';
|
|
|
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 @@ define((function () { 'use strict';
|
|
|
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 @@ define((function () { 'use strict';
|
|
|
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 @@ define((function () { 'use strict';
|
|
|
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 @@ define((function () { 'use strict';
|
|
|
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 @@ define((function () { 'use strict';
|
|
|
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 @@ define((function () { 'use strict';
|
|
|
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 @@ define((function () { 'use strict';
|
|
|
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 @@ define((function () { 'use strict';
|
|
|
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 @@ define((function () { 'use strict';
|
|
|
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 @@ define((function () { 'use strict';
|
|
|
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 @@ define((function () { 'use strict';
|
|
|
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 @@ define((function () { 'use strict';
|
|
|
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 @@ define((function () { 'use strict';
|
|
|
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;
|