mixpanel-browser 2.64.0 → 2.66.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.
@@ -13945,7 +13945,7 @@
13945
13945
 
13946
13946
  var Config = {
13947
13947
  DEBUG: false,
13948
- LIB_VERSION: '2.64.0'
13948
+ LIB_VERSION: '2.66.0'
13949
13949
  };
13950
13950
 
13951
13951
  /* eslint camelcase: "off", eqeqeq: "off" */
@@ -15430,6 +15430,9 @@
15430
15430
  return 'Microsoft Edge';
15431
15431
  } else if (_.includes(user_agent, 'FBIOS')) {
15432
15432
  return 'Facebook Mobile';
15433
+ } else if (_.includes(user_agent, 'Whale/')) {
15434
+ // https://user-agents.net/browsers/whale-browser
15435
+ return 'Whale Browser';
15433
15436
  } else if (_.includes(user_agent, 'Chrome')) {
15434
15437
  return 'Chrome';
15435
15438
  } else if (_.includes(user_agent, 'CriOS')) {
@@ -15481,7 +15484,8 @@
15481
15484
  'Android Mobile': /android\s(\d+(\.\d+)?)/,
15482
15485
  'Samsung Internet': /SamsungBrowser\/(\d+(\.\d+)?)/,
15483
15486
  'Internet Explorer': /(rv:|MSIE )(\d+(\.\d+)?)/,
15484
- 'Mozilla': /rv:(\d+(\.\d+)?)/
15487
+ 'Mozilla': /rv:(\d+(\.\d+)?)/,
15488
+ 'Whale Browser': /Whale\/(\d+(\.\d+)?)/
15485
15489
  };
15486
15490
  var regex = versionRegexs[browser];
15487
15491
  if (regex === undefined) {
@@ -17348,8 +17352,8 @@
17348
17352
  retryAfter: response.headers.get('Retry-After')
17349
17353
  });
17350
17354
  }.bind(this);
17351
-
17352
- win['fetch'](this.getConfig('api_host') + '/' + this.getConfig('api_routes')['record'] + '?' + new URLSearchParams(reqParams), {
17355
+ var apiHost = (this._mixpanel.get_api_host && this._mixpanel.get_api_host('record')) || this.getConfig('api_host');
17356
+ win['fetch'](apiHost + '/' + this.getConfig('api_routes')['record'] + '?' + new URLSearchParams(reqParams), {
17353
17357
  'method': 'POST',
17354
17358
  'headers': {
17355
17359
  'Authorization': 'Basic ' + btoa(this.getConfig('token') + ':'),
@@ -17566,6 +17570,7 @@
17566
17570
  this._flushInactivePromise = this.recordingRegistry.flushInactiveRecordings();
17567
17571
 
17568
17572
  this.activeRecording = null;
17573
+ this.stopRecordingInProgress = false;
17569
17574
  };
17570
17575
 
17571
17576
  MixpanelRecorder.prototype.startRecording = function(options) {
@@ -17614,19 +17619,26 @@
17614
17619
  };
17615
17620
 
17616
17621
  MixpanelRecorder.prototype.stopRecording = function() {
17617
- var stopPromise = this._stopCurrentRecording(false);
17618
- this.recordingRegistry.clearActiveRecording();
17619
- this.activeRecording = null;
17620
- return stopPromise;
17622
+ // Prevents activeSerializedRecording from being reused when stopping the recording.
17623
+ this.stopRecordingInProgress = true;
17624
+ return this._stopCurrentRecording(false, true).then(function() {
17625
+ return this.recordingRegistry.clearActiveRecording();
17626
+ }.bind(this)).then(function() {
17627
+ this.stopRecordingInProgress = false;
17628
+ }.bind(this));
17621
17629
  };
17622
17630
 
17623
17631
  MixpanelRecorder.prototype.pauseRecording = function() {
17624
17632
  return this._stopCurrentRecording(false);
17625
17633
  };
17626
17634
 
17627
- MixpanelRecorder.prototype._stopCurrentRecording = function(skipFlush) {
17635
+ MixpanelRecorder.prototype._stopCurrentRecording = function(skipFlush, disableActiveRecording) {
17628
17636
  if (this.activeRecording) {
17629
- return this.activeRecording.stopRecording(skipFlush);
17637
+ var stopRecordingPromise = this.activeRecording.stopRecording(skipFlush);
17638
+ if (disableActiveRecording) {
17639
+ this.activeRecording = null;
17640
+ }
17641
+ return stopRecordingPromise;
17630
17642
  }
17631
17643
  return PromisePolyfill.resolve();
17632
17644
  };
@@ -17639,7 +17651,7 @@
17639
17651
 
17640
17652
  return this.recordingRegistry.getActiveRecording()
17641
17653
  .then(function (activeSerializedRecording) {
17642
- if (activeSerializedRecording) {
17654
+ if (activeSerializedRecording && !this.stopRecordingInProgress) {
17643
17655
  return this.startRecording({activeSerializedRecording: activeSerializedRecording});
17644
17656
  } else if (startNewIfInactive) {
17645
17657
  return this.startRecording({shouldStopBatcher: false});
@@ -17843,7 +17855,9 @@
17843
17855
  '$elements': elementsJson,
17844
17856
  '$el_attr__href': href,
17845
17857
  '$viewportHeight': Math.max(docElement['clientHeight'], win['innerHeight'] || 0),
17846
- '$viewportWidth': Math.max(docElement['clientWidth'], win['innerWidth'] || 0)
17858
+ '$viewportWidth': Math.max(docElement['clientWidth'], win['innerWidth'] || 0),
17859
+ '$pageHeight': document$1['body']['offsetHeight'] || 0,
17860
+ '$pageWidth': document$1['body']['offsetWidth'] || 0,
17847
17861
  };
17848
17862
  _.each(captureExtraAttrs, function(attr) {
17849
17863
  if (!blockAttrsSet[attr] && target.hasAttribute(attr)) {
@@ -18574,19 +18588,19 @@
18574
18588
  return this.getFullConfig()[key];
18575
18589
  };
18576
18590
 
18577
- FeatureFlagManager.prototype.isEnabled = function() {
18591
+ FeatureFlagManager.prototype.isSystemEnabled = function() {
18578
18592
  return !!this.getMpConfig(FLAGS_CONFIG_KEY);
18579
18593
  };
18580
18594
 
18581
- FeatureFlagManager.prototype.areFeaturesReady = function() {
18582
- if (!this.isEnabled()) {
18595
+ FeatureFlagManager.prototype.areFlagsReady = function() {
18596
+ if (!this.isSystemEnabled()) {
18583
18597
  logger.error('Feature Flags not enabled');
18584
18598
  }
18585
18599
  return !!this.flags;
18586
18600
  };
18587
18601
 
18588
18602
  FeatureFlagManager.prototype.fetchFlags = function() {
18589
- if (!this.isEnabled()) {
18603
+ if (!this.isSystemEnabled()) {
18590
18604
  return;
18591
18605
  }
18592
18606
 
@@ -18612,7 +18626,7 @@
18612
18626
  _.each(responseFlags, function(data, key) {
18613
18627
  flags.set(key, {
18614
18628
  'key': data['variant_key'],
18615
- 'data': data['variant_value']
18629
+ 'value': data['variant_value']
18616
18630
  });
18617
18631
  });
18618
18632
  this.flags = flags;
@@ -18622,7 +18636,7 @@
18622
18636
  }.bind(this)).catch(function() {});
18623
18637
  };
18624
18638
 
18625
- FeatureFlagManager.prototype.getFeature = function(featureName, fallback) {
18639
+ FeatureFlagManager.prototype.getVariant = function(featureName, fallback) {
18626
18640
  if (!this.fetchPromise) {
18627
18641
  return new Promise(function(resolve) {
18628
18642
  logger.critical('Feature Flags not initialized');
@@ -18631,15 +18645,15 @@
18631
18645
  }
18632
18646
 
18633
18647
  return this.fetchPromise.then(function() {
18634
- return this.getFeatureSync(featureName, fallback);
18648
+ return this.getVariantSync(featureName, fallback);
18635
18649
  }.bind(this)).catch(function(error) {
18636
18650
  logger.error(error);
18637
18651
  return fallback;
18638
18652
  });
18639
18653
  };
18640
18654
 
18641
- FeatureFlagManager.prototype.getFeatureSync = function(featureName, fallback) {
18642
- if (!this.areFeaturesReady()) {
18655
+ FeatureFlagManager.prototype.getVariantSync = function(featureName, fallback) {
18656
+ if (!this.areFlagsReady()) {
18643
18657
  logger.log('Flags not loaded yet');
18644
18658
  return fallback;
18645
18659
  }
@@ -18652,31 +18666,37 @@
18652
18666
  return feature;
18653
18667
  };
18654
18668
 
18655
- FeatureFlagManager.prototype.getFeatureData = function(featureName, fallbackValue) {
18656
- return this.getFeature(featureName, {'data': fallbackValue}).then(function(feature) {
18657
- return feature['data'];
18669
+ FeatureFlagManager.prototype.getVariantValue = function(featureName, fallbackValue) {
18670
+ return this.getVariant(featureName, {'value': fallbackValue}).then(function(feature) {
18671
+ return feature['value'];
18658
18672
  }).catch(function(error) {
18659
18673
  logger.error(error);
18660
18674
  return fallbackValue;
18661
18675
  });
18662
18676
  };
18663
18677
 
18664
- FeatureFlagManager.prototype.getFeatureDataSync = function(featureName, fallbackValue) {
18665
- return this.getFeatureSync(featureName, {'data': fallbackValue})['data'];
18678
+ // TODO remove deprecated method
18679
+ FeatureFlagManager.prototype.getFeatureData = function(featureName, fallbackValue) {
18680
+ logger.critical('mixpanel.flags.get_feature_data() is deprecated and will be removed in a future release. Use mixpanel.flags.get_variant_value() instead.');
18681
+ return this.getVariantValue(featureName, fallbackValue);
18682
+ };
18683
+
18684
+ FeatureFlagManager.prototype.getVariantValueSync = function(featureName, fallbackValue) {
18685
+ return this.getVariantSync(featureName, {'value': fallbackValue})['value'];
18666
18686
  };
18667
18687
 
18668
- FeatureFlagManager.prototype.isFeatureEnabled = function(featureName, fallbackValue) {
18669
- return this.getFeatureData(featureName).then(function() {
18670
- return this.isFeatureEnabledSync(featureName, fallbackValue);
18688
+ FeatureFlagManager.prototype.isEnabled = function(featureName, fallbackValue) {
18689
+ return this.getVariantValue(featureName).then(function() {
18690
+ return this.isEnabledSync(featureName, fallbackValue);
18671
18691
  }.bind(this)).catch(function(error) {
18672
18692
  logger.error(error);
18673
18693
  return fallbackValue;
18674
18694
  });
18675
18695
  };
18676
18696
 
18677
- FeatureFlagManager.prototype.isFeatureEnabledSync = function(featureName, fallbackValue) {
18697
+ FeatureFlagManager.prototype.isEnabledSync = function(featureName, fallbackValue) {
18678
18698
  fallbackValue = fallbackValue || false;
18679
- var val = this.getFeatureDataSync(featureName, fallbackValue);
18699
+ var val = this.getVariantValueSync(featureName, fallbackValue);
18680
18700
  if (val !== true && val !== false) {
18681
18701
  logger.error('Feature flag "' + featureName + '" value: ' + val + ' is not a boolean; returning fallback value: ' + fallbackValue);
18682
18702
  val = fallbackValue;
@@ -18705,13 +18725,16 @@
18705
18725
 
18706
18726
  safewrapClass(FeatureFlagManager);
18707
18727
 
18708
- FeatureFlagManager.prototype['are_features_ready'] = FeatureFlagManager.prototype.areFeaturesReady;
18709
- FeatureFlagManager.prototype['get_feature'] = FeatureFlagManager.prototype.getFeature;
18728
+ FeatureFlagManager.prototype['are_flags_ready'] = FeatureFlagManager.prototype.areFlagsReady;
18729
+ FeatureFlagManager.prototype['get_variant'] = FeatureFlagManager.prototype.getVariant;
18730
+ FeatureFlagManager.prototype['get_variant_sync'] = FeatureFlagManager.prototype.getVariantSync;
18731
+ FeatureFlagManager.prototype['get_variant_value'] = FeatureFlagManager.prototype.getVariantValue;
18732
+ FeatureFlagManager.prototype['get_variant_value_sync'] = FeatureFlagManager.prototype.getVariantValueSync;
18733
+ FeatureFlagManager.prototype['is_enabled'] = FeatureFlagManager.prototype.isEnabled;
18734
+ FeatureFlagManager.prototype['is_enabled_sync'] = FeatureFlagManager.prototype.isEnabledSync;
18735
+
18736
+ // Deprecated method
18710
18737
  FeatureFlagManager.prototype['get_feature_data'] = FeatureFlagManager.prototype.getFeatureData;
18711
- FeatureFlagManager.prototype['get_feature_data_sync'] = FeatureFlagManager.prototype.getFeatureDataSync;
18712
- FeatureFlagManager.prototype['get_feature_sync'] = FeatureFlagManager.prototype.getFeatureSync;
18713
- FeatureFlagManager.prototype['is_feature_enabled'] = FeatureFlagManager.prototype.isFeatureEnabled;
18714
- FeatureFlagManager.prototype['is_feature_enabled_sync'] = FeatureFlagManager.prototype.isFeatureEnabledSync;
18715
18738
 
18716
18739
  /* eslint camelcase: "off" */
18717
18740
 
@@ -19130,7 +19153,7 @@
19130
19153
  return this._mixpanel._track_or_batch({
19131
19154
  type: 'groups',
19132
19155
  data: date_encoded_data,
19133
- endpoint: this._get_config('api_host') + '/' + this._get_config('api_routes')['groups'],
19156
+ endpoint: this._mixpanel.get_api_host('groups') + '/' + this._get_config('api_routes')['groups'],
19134
19157
  batcher: this._mixpanel.request_batchers.groups
19135
19158
  }, callback);
19136
19159
  };
@@ -19407,18 +19430,8 @@
19407
19430
  * @param {Function} [callback] If provided, the callback will be called when the server responds
19408
19431
  * @deprecated
19409
19432
  */
19410
- MixpanelPeople.prototype.track_charge = addOptOutCheckMixpanelPeople(function(amount, properties, callback) {
19411
- if (!_.isNumber(amount)) {
19412
- amount = parseFloat(amount);
19413
- if (isNaN(amount)) {
19414
- console$1.error('Invalid value passed to mixpanel.people.track_charge - must be a number');
19415
- return;
19416
- }
19417
- }
19418
-
19419
- return this.append('$transactions', _.extend({
19420
- '$amount': amount
19421
- }, properties), callback);
19433
+ MixpanelPeople.prototype.track_charge = addOptOutCheckMixpanelPeople(function() {
19434
+ console$1.error('mixpanel.people.track_charge() is deprecated and no longer has any effect.');
19422
19435
  });
19423
19436
 
19424
19437
  /*
@@ -19492,7 +19505,7 @@
19492
19505
  return this._mixpanel._track_or_batch({
19493
19506
  type: 'people',
19494
19507
  data: date_encoded_data,
19495
- endpoint: this._get_config('api_host') + '/' + this._get_config('api_routes')['engage'],
19508
+ endpoint: this._mixpanel.get_api_host('people') + '/' + this._get_config('api_routes')['engage'],
19496
19509
  batcher: this._mixpanel.request_batchers.people
19497
19510
  }, callback);
19498
19511
  };
@@ -20129,7 +20142,9 @@
20129
20142
  */
20130
20143
  var DEFAULT_CONFIG = {
20131
20144
  'api_host': 'https://api-js.mixpanel.com',
20145
+ 'api_hosts': {},
20132
20146
  'api_routes': DEFAULT_API_ROUTES,
20147
+ 'api_extra_query_params': {},
20133
20148
  'api_method': 'POST',
20134
20149
  'api_transport': 'XHR',
20135
20150
  'api_payload_format': PAYLOAD_TYPE_BASE64,
@@ -20513,20 +20528,23 @@
20513
20528
 
20514
20529
  MixpanelLib.prototype.stop_session_recording = function () {
20515
20530
  if (this._recorder) {
20516
- this._recorder['stopRecording']();
20531
+ return this._recorder['stopRecording']();
20517
20532
  }
20533
+ return Promise.resolve();
20518
20534
  };
20519
20535
 
20520
20536
  MixpanelLib.prototype.pause_session_recording = function () {
20521
20537
  if (this._recorder) {
20522
- this._recorder['pauseRecording']();
20538
+ return this._recorder['pauseRecording']();
20523
20539
  }
20540
+ return Promise.resolve();
20524
20541
  };
20525
20542
 
20526
20543
  MixpanelLib.prototype.resume_session_recording = function () {
20527
20544
  if (this._recorder) {
20528
- this._recorder['resumeRecording']();
20545
+ return this._recorder['resumeRecording']();
20529
20546
  }
20547
+ return Promise.resolve();
20530
20548
  };
20531
20549
 
20532
20550
  MixpanelLib.prototype.is_recording_heatmap_data = function () {
@@ -20717,6 +20735,8 @@
20717
20735
  delete data['data'];
20718
20736
  }
20719
20737
 
20738
+ _.extend(data, this.get_config('api_extra_query_params'));
20739
+
20720
20740
  url += '?' + _.HTTPBuildQuery(data);
20721
20741
 
20722
20742
  var lib = this;
@@ -21124,7 +21144,7 @@
21124
21144
  var ret = this._track_or_batch({
21125
21145
  type: 'events',
21126
21146
  data: data,
21127
- endpoint: this.get_config('api_host') + '/' + this.get_config('api_routes')['track'],
21147
+ endpoint: this.get_api_host('events') + '/' + this.get_config('api_routes')['track'],
21128
21148
  batcher: this.request_batchers.events,
21129
21149
  should_send_immediately: should_send_immediately,
21130
21150
  send_request_options: options
@@ -21626,13 +21646,31 @@
21626
21646
  * Useful for clearing data when a user logs out.
21627
21647
  */
21628
21648
  MixpanelLib.prototype.reset = function() {
21629
- this['persistence'].clear();
21630
- this._flags.identify_called = false;
21631
- var uuid = _.UUID();
21632
- this.register_once({
21633
- 'distinct_id': DEVICE_ID_PREFIX + uuid,
21634
- '$device_id': uuid
21635
- }, '');
21649
+ var self = this;
21650
+
21651
+ var reset = function () {
21652
+ self['persistence'].clear();
21653
+ self._flags.identify_called = false;
21654
+ var uuid = _.UUID();
21655
+ self.register_once({
21656
+ 'distinct_id': DEVICE_ID_PREFIX + uuid,
21657
+ '$device_id': uuid
21658
+ }, '');
21659
+ };
21660
+
21661
+ if (self._recorder) {
21662
+ self.stop_session_recording()
21663
+ .then(function () {
21664
+ reset();
21665
+ self._check_and_start_session_recording();
21666
+ })
21667
+ .catch(_.bind(function (err) {
21668
+ reset();
21669
+ this.report_error('Error restarting recording session', err);
21670
+ }, this));
21671
+ } else {
21672
+ reset();
21673
+ }
21636
21674
  };
21637
21675
 
21638
21676
  /**
@@ -21943,6 +21981,16 @@
21943
21981
  return this['persistence'].load_prop([property_name]);
21944
21982
  };
21945
21983
 
21984
+ /**
21985
+ * Get the API host for a specific endpoint type, falling back to the default api_host if not specified
21986
+ *
21987
+ * @param {String} endpoint_type The type of endpoint (e.g., "events", "people", "groups")
21988
+ * @returns {String} The API host to use for this endpoint
21989
+ */
21990
+ MixpanelLib.prototype.get_api_host = function(endpoint_type) {
21991
+ return this.get_config('api_hosts')[endpoint_type] || this.get_config('api_host');
21992
+ };
21993
+
21946
21994
  MixpanelLib.prototype.toString = function() {
21947
21995
  var name = this.get_config('name');
21948
21996
  if (name !== PRIMARY_INSTANCE_NAME) {
@@ -22238,6 +22286,7 @@
22238
22286
  MixpanelLib.prototype['name_tag'] = MixpanelLib.prototype.name_tag;
22239
22287
  MixpanelLib.prototype['set_config'] = MixpanelLib.prototype.set_config;
22240
22288
  MixpanelLib.prototype['get_config'] = MixpanelLib.prototype.get_config;
22289
+ MixpanelLib.prototype['get_api_host'] = MixpanelLib.prototype.get_api_host;
22241
22290
  MixpanelLib.prototype['get_property'] = MixpanelLib.prototype.get_property;
22242
22291
  MixpanelLib.prototype['get_distinct_id'] = MixpanelLib.prototype.get_distinct_id;
22243
22292
  MixpanelLib.prototype['toString'] = MixpanelLib.prototype.toString;