mixpanel-browser 2.41.0 → 2.45.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/doc/build-docs.js CHANGED
@@ -97,6 +97,22 @@ function doxToMD(items) {
97
97
  });
98
98
  }
99
99
 
100
+ // Captures prototype bracket notation property assignment, e.g.:
101
+ // `MixpanelGroup.prototype['delete'] = addOptOutCheckMixpanelGroup(function(callback) {`
102
+ // Based on https://github.com/tj/dox/blob/9fe92e17dfcd31c9b6512f6e5bf0b52c2b6b84d4/lib/dox.js#L592
103
+ dox.contextPatternMatchers.push(function (str) {
104
+ if (/^\s*([\w$.]+)\s*\.\s*prototype\s*\['\s*([\w$]+)'\]\s*=\s*([^\n;]+)/.exec(str)) {
105
+ return {
106
+ type: 'property'
107
+ , constructor: RegExp.$1
108
+ , cons: RegExp.$1
109
+ , name: RegExp.$2
110
+ , value: RegExp.$3.trim()
111
+ , string: RegExp.$1 + '.prototype.' + RegExp.$2
112
+ };
113
+ }
114
+ });
115
+
100
116
  const rawCode = fs.readFileSync(SOURCE_FILE).toString().trim();
101
117
  const parsed = dox.parseComments(rawCode);
102
118
 
@@ -990,6 +990,24 @@ mixpanel.people.unset(['gender', 'Company']);
990
990
  # mixpanel.group
991
991
 
992
992
 
993
+ ___
994
+ ## mixpanel.group.delete
995
+ Permanently delete a group.
996
+
997
+
998
+ ### Usage:
999
+
1000
+ ```javascript
1001
+ mixpanel.get_group('company', 'mixpanel').delete();
1002
+ ```
1003
+
1004
+
1005
+
1006
+ | Argument | Type | Description |
1007
+ | ------------- | ------------- | ----- |
1008
+ | **callback** | <span class="mp-arg-type">Function</span></br></span><span class="mp-arg-optional">optional</span> | If provided, the callback will be called after the tracking event |
1009
+
1010
+
993
1011
  ___
994
1012
  ## mixpanel.group.remove
995
1013
  Remove a property from a group. The value will be ignored if doesn't exist.
@@ -68,8 +68,8 @@ var MIXPANEL_LIB_URL = '//cdn.mxpnl.com/libs/mixpanel-2-latest.min.js';
68
68
 
69
69
  function _set_and_defer_chained(fn_name) {
70
70
  mock_group[fn_name] = function() {
71
- call2_args = arguments;
72
- call2 = [fn_name].concat(Array.prototype.slice.call(call2_args, 0));
71
+ var call2_args = arguments;
72
+ var call2 = [fn_name].concat(Array.prototype.slice.call(call2_args, 0));
73
73
  target.push([call1, call2]);
74
74
  };
75
75
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mixpanel-browser",
3
- "version": "2.41.0",
3
+ "version": "2.45.0",
4
4
  "description": "The official Mixpanel JavaScript browser client library",
5
5
  "main": "dist/mixpanel.cjs.js",
6
6
  "directories": {
@@ -46,10 +46,10 @@
46
46
  "jsdom": "11.12.0",
47
47
  "jsdom-global": "3.0.2",
48
48
  "localStorage": "1.0.4",
49
- "lodash": "4.17.19",
49
+ "lodash": "4.17.21",
50
50
  "mocha": "7.1.1",
51
51
  "morgan": "1.9.1",
52
- "rdme": "3.0.0",
52
+ "rdme": "4.0.0",
53
53
  "request": "2.88.0",
54
54
  "rollup": "0.25.8",
55
55
  "rollup-plugin-npm": "1.4.0",
package/src/config.js CHANGED
@@ -1,6 +1,6 @@
1
1
  var Config = {
2
2
  DEBUG: false,
3
- LIB_VERSION: '2.41.0'
3
+ LIB_VERSION: '2.45.0'
4
4
  };
5
5
 
6
6
  export default Config;
@@ -1,10 +1,9 @@
1
1
  /* eslint camelcase: "off" */
2
2
  import Config from './config';
3
- import { _, console, userAgent, window, document, navigator, determine_eligibility, slice } from './utils';
3
+ import { _, console, userAgent, window, document, navigator, slice } from './utils';
4
4
  import { FormTracker, LinkTracker } from './dom-trackers';
5
5
  import { RequestBatcher } from './request-batcher';
6
6
  import { MixpanelGroup } from './mixpanel-group';
7
- import { MixpanelNotification } from './mixpanel-notification';
8
7
  import { MixpanelPeople } from './mixpanel-people';
9
8
  import {
10
9
  MixpanelPersistence,
@@ -56,6 +55,8 @@ var IDENTITY_FUNC = function(x) {return x;};
56
55
  var NOOP_FUNC = function() {};
57
56
 
58
57
  /** @const */ var PRIMARY_INSTANCE_NAME = 'mixpanel';
58
+ /** @const */ var PAYLOAD_TYPE_BASE64 = 'base64';
59
+ /** @const */ var PAYLOAD_TYPE_JSON = 'json';
59
60
 
60
61
 
61
62
  /*
@@ -86,10 +87,12 @@ var DEFAULT_CONFIG = {
86
87
  'api_host': 'https://api-js.mixpanel.com',
87
88
  'api_method': 'POST',
88
89
  'api_transport': 'XHR',
90
+ 'api_payload_format': PAYLOAD_TYPE_BASE64,
89
91
  'app_host': 'https://mixpanel.com',
90
92
  'cdn': 'https://cdn.mxpnl.com',
91
93
  'cross_site_cookie': false,
92
94
  'cross_subdomain_cookie': true,
95
+ 'error_reporter': NOOP_FUNC,
93
96
  'persistence': 'cookie',
94
97
  'persistence_name': '',
95
98
  'cookie_domain': '',
@@ -114,10 +117,8 @@ var DEFAULT_CONFIG = {
114
117
  'opt_out_tracking_cookie_prefix': null,
115
118
  'property_blacklist': [],
116
119
  'xhr_headers': {}, // { header: value, header2: value }
117
- 'inapp_protocol': '//',
118
- 'inapp_link_new_window': false,
119
120
  'ignore_dnt': false,
120
- 'batch_requests': false, // for now
121
+ 'batch_requests': true,
121
122
  'batch_size': 50,
122
123
  'batch_flush_interval_ms': 5000,
123
124
  'batch_request_timeout_ms': 90000,
@@ -157,8 +158,6 @@ var create_mplib = function(token, config, name) {
157
158
  }
158
159
 
159
160
  instance._cached_groups = {}; // cache groups in a pool
160
- instance._user_decide_check_complete = false;
161
- instance._events_tracked_before_user_decide_check_complete = [];
162
161
 
163
162
  instance._init(token, config, name);
164
163
 
@@ -181,12 +180,6 @@ var create_mplib = function(token, config, name) {
181
180
  return instance;
182
181
  };
183
182
 
184
- var encode_data_for_request = function(data) {
185
- var json_data = _.JSONEncode(data);
186
- var encoded_data = _.base64Encode(json_data);
187
- return {'data': encoded_data};
188
- };
189
-
190
183
  // Initialization methods
191
184
 
192
185
  /**
@@ -207,11 +200,11 @@ var encode_data_for_request = function(data) {
207
200
  */
208
201
  MixpanelLib.prototype.init = function (token, config, name) {
209
202
  if (_.isUndefined(name)) {
210
- console.error('You must name your new library: init(token, config, name)');
203
+ this.report_error('You must name your new library: init(token, config, name)');
211
204
  return;
212
205
  }
213
206
  if (name === PRIMARY_INSTANCE_NAME) {
214
- console.error('You must initialize the main mixpanel object right after you include the Mixpanel js snippet');
207
+ this.report_error('You must initialize the main mixpanel object right after you include the Mixpanel js snippet');
215
208
  return;
216
209
  }
217
210
 
@@ -234,16 +227,15 @@ MixpanelLib.prototype._init = function(token, config, name) {
234
227
 
235
228
  this['__loaded'] = true;
236
229
  this['config'] = {};
237
- this['_triggered_notifs'] = [];
238
230
 
239
- // rollout: enable batch_requests by default for 60% of projects
240
- // (only if they have not specified a value in their init config
241
- // and they aren't using a custom API host)
242
231
  var variable_features = {};
243
- var api_host = config['api_host'];
244
- var is_custom_api = !!api_host && !api_host.match(/\.mixpanel\.com$/);
245
- if (!('batch_requests' in config) && !is_custom_api && determine_eligibility(token, 'batch', 60)) {
246
- variable_features['batch_requests'] = true;
232
+
233
+ // default to JSON payload for standard mixpanel.com API hosts
234
+ if (!('api_payload_format' in config)) {
235
+ var api_host = config['api_host'] || DEFAULT_CONFIG['api_host'];
236
+ if (api_host.match(/\.mixpanel\.com$/)) {
237
+ variable_features['api_payload_format'] = PAYLOAD_TYPE_JSON;
238
+ }
247
239
  }
248
240
 
249
241
  this.set_config(_.extend({}, DEFAULT_CONFIG, variable_features, config, {
@@ -272,15 +264,32 @@ MixpanelLib.prototype._init = function(token, config, name) {
272
264
  } else {
273
265
  this.init_batchers();
274
266
  if (sendBeacon && window.addEventListener) {
275
- window.addEventListener('unload', _.bind(function() {
276
- // Before page closes, attempt to flush any events queued up via navigator.sendBeacon.
277
- // Since sendBeacon doesn't report success/failure, events will not be removed from
278
- // the persistent store; if the site is loaded again, the events will be flushed again
279
- // on startup and deduplicated on the Mixpanel server side.
267
+ // Before page closes or hides (user tabs away etc), attempt to flush any events
268
+ // queued up via navigator.sendBeacon. Since sendBeacon doesn't report success/failure,
269
+ // events will not be removed from the persistent store; if the site is loaded again,
270
+ // the events will be flushed again on startup and deduplicated on the Mixpanel server
271
+ // side.
272
+ // There is no reliable way to capture only page close events, so we lean on the
273
+ // visibilitychange and pagehide events as recommended at
274
+ // https://developer.mozilla.org/en-US/docs/Web/API/Window/unload_event#usage_notes.
275
+ // These events fire when the user clicks away from the current page/tab, so will occur
276
+ // more frequently than page unload, but are the only mechanism currently for capturing
277
+ // this scenario somewhat reliably.
278
+ var flush_on_unload = _.bind(function() {
280
279
  if (!this.request_batchers.events.stopped) {
281
280
  this.request_batchers.events.flush({unloading: true});
282
281
  }
283
- }, this));
282
+ }, this);
283
+ window.addEventListener('pagehide', function(ev) {
284
+ if (ev['persisted']) {
285
+ flush_on_unload();
286
+ }
287
+ });
288
+ window.addEventListener('visibilitychange', function() {
289
+ if (document['visibilityState'] === 'hidden') {
290
+ flush_on_unload();
291
+ }
292
+ });
284
293
  }
285
294
  }
286
295
  }
@@ -336,7 +345,7 @@ MixpanelLib.prototype._dom_loaded = function() {
336
345
 
337
346
  MixpanelLib.prototype._track_dom = function(DomClass, args) {
338
347
  if (this.get_config('img')) {
339
- console.error('You can\'t use DOM tracking functions with img = true.');
348
+ this.report_error('You can\'t use DOM tracking functions with img = true.');
340
349
  return false;
341
350
  }
342
351
 
@@ -438,6 +447,7 @@ MixpanelLib.prototype._send_request = function(url, data, options, callback) {
438
447
 
439
448
  url += '?' + _.HTTPBuildQuery(data);
440
449
 
450
+ var lib = this;
441
451
  if ('img' in data) {
442
452
  var img = document.createElement('img');
443
453
  img.src = url;
@@ -446,7 +456,7 @@ MixpanelLib.prototype._send_request = function(url, data, options, callback) {
446
456
  try {
447
457
  succeeded = sendBeacon(url, body_data);
448
458
  } catch (e) {
449
- console.error(e);
459
+ lib.report_error(e);
450
460
  succeeded = false;
451
461
  }
452
462
  try {
@@ -454,7 +464,7 @@ MixpanelLib.prototype._send_request = function(url, data, options, callback) {
454
464
  callback(succeeded ? 1 : 0);
455
465
  }
456
466
  } catch (e) {
457
- console.error(e);
467
+ lib.report_error(e);
458
468
  }
459
469
  } else if (USE_XHR) {
460
470
  try {
@@ -486,7 +496,7 @@ MixpanelLib.prototype._send_request = function(url, data, options, callback) {
486
496
  try {
487
497
  response = _.JSONDecode(req.responseText);
488
498
  } catch (e) {
489
- console.error(e);
499
+ lib.report_error(e);
490
500
  if (options.ignore_json_errors) {
491
501
  response = req.responseText;
492
502
  } else {
@@ -509,7 +519,7 @@ MixpanelLib.prototype._send_request = function(url, data, options, callback) {
509
519
  } else {
510
520
  error = 'Bad HTTP status: ' + req.status + ' ' + req.statusText;
511
521
  }
512
- console.error(error);
522
+ lib.report_error(error);
513
523
  if (callback) {
514
524
  if (verbose_mode) {
515
525
  callback({status: 0, error: error, xhr_req: req});
@@ -522,7 +532,7 @@ MixpanelLib.prototype._send_request = function(url, data, options, callback) {
522
532
  };
523
533
  req.send(body_data);
524
534
  } catch (e) {
525
- console.error(e);
535
+ lib.report_error(e);
526
536
  succeeded = false;
527
537
  }
528
538
  } else {
@@ -605,14 +615,16 @@ MixpanelLib.prototype.init_batchers = function() {
605
615
  sendRequestFunc: _.bind(function(data, options, cb) {
606
616
  this._send_request(
607
617
  this.get_config('api_host') + attrs.endpoint,
608
- encode_data_for_request(data),
618
+ this._encode_data_for_request(data),
609
619
  options,
610
620
  this._prepare_callback(cb, data)
611
621
  );
612
622
  }, this),
613
623
  beforeSendHook: _.bind(function(item) {
614
624
  return this._run_hook('before_send_' + attrs.type, item);
615
- }, this)
625
+ }, this),
626
+ errorReporter: this.get_config('error_reporter'),
627
+ stopAllBatchingFunc: _.bind(this.stop_batch_senders, this)
616
628
  }
617
629
  );
618
630
  }, this);
@@ -679,6 +691,14 @@ MixpanelLib.prototype.disable = function(events) {
679
691
  }
680
692
  };
681
693
 
694
+ MixpanelLib.prototype._encode_data_for_request = function(data) {
695
+ var encoded_data = _.JSONEncode(data);
696
+ if (this.get_config('api_payload_format') === PAYLOAD_TYPE_BASE64) {
697
+ encoded_data = _.base64Encode(encoded_data);
698
+ }
699
+ return {'data': encoded_data};
700
+ };
701
+
682
702
  // internal method for handling track vs batch-enqueue logic
683
703
  MixpanelLib.prototype._track_or_batch = function(options, callback) {
684
704
  var truncated_data = _.truncate(options.data, 255);
@@ -698,7 +718,7 @@ MixpanelLib.prototype._track_or_batch = function(options, callback) {
698
718
  console.log(truncated_data);
699
719
  return this._send_request(
700
720
  endpoint,
701
- encode_data_for_request(truncated_data),
721
+ this._encode_data_for_request(truncated_data),
702
722
  send_request_options,
703
723
  this._prepare_callback(callback, truncated_data)
704
724
  );
@@ -761,7 +781,7 @@ MixpanelLib.prototype.track = addOptOutCheckMixpanelLib(function(event_name, pro
761
781
  }
762
782
 
763
783
  if (_.isUndefined(event_name)) {
764
- console.error('No event name provided to mixpanel.track');
784
+ this.report_error('No event name provided to mixpanel.track');
765
785
  return;
766
786
  }
767
787
 
@@ -802,7 +822,7 @@ MixpanelLib.prototype.track = addOptOutCheckMixpanelLib(function(event_name, pro
802
822
  delete properties[blacklisted_prop];
803
823
  });
804
824
  } else {
805
- console.error('Invalid value for property_blacklist config: ' + property_blacklist);
825
+ this.report_error('Invalid value for property_blacklist config: ' + property_blacklist);
806
826
  }
807
827
 
808
828
  var data = {
@@ -818,8 +838,6 @@ MixpanelLib.prototype.track = addOptOutCheckMixpanelLib(function(event_name, pro
818
838
  send_request_options: options
819
839
  }, callback);
820
840
 
821
- this._check_and_handle_triggered_notifications(data);
822
-
823
841
  return ret;
824
842
  });
825
843
 
@@ -1047,7 +1065,7 @@ MixpanelLib.prototype.track_forms = function() {
1047
1065
  */
1048
1066
  MixpanelLib.prototype.time_event = function(event_name) {
1049
1067
  if (_.isUndefined(event_name)) {
1050
- console.error('No event name provided to mixpanel.time_event');
1068
+ this.report_error('No event name provided to mixpanel.time_event');
1051
1069
  return;
1052
1070
  }
1053
1071
 
@@ -1230,7 +1248,6 @@ MixpanelLib.prototype.identify = function(
1230
1248
  this.unregister(ALIAS_ID_KEY);
1231
1249
  this.register({'distinct_id': new_distinct_id});
1232
1250
  }
1233
- this._check_and_handle_notifications(this.get_distinct_id());
1234
1251
  this._flags.identify_called = true;
1235
1252
  // Flush any queued up people requests
1236
1253
  this['people']._flush(_set_callback, _add_callback, _append_callback, _set_once_callback, _union_callback, _unset_callback, _remove_callback);
@@ -1320,7 +1337,7 @@ MixpanelLib.prototype.alias = function(alias, original) {
1320
1337
  // mixpanel.people.identify() call made for this user. It is VERY BAD to make an alias with
1321
1338
  // this ID, as it will duplicate users.
1322
1339
  if (alias === this.get_property(PEOPLE_DISTINCT_ID_KEY)) {
1323
- console.critical('Attempting to create alias for existing People user - aborting.');
1340
+ this.report_error('Attempting to create alias for existing People user - aborting.');
1324
1341
  return -2;
1325
1342
  }
1326
1343
 
@@ -1340,7 +1357,7 @@ MixpanelLib.prototype.alias = function(alias, original) {
1340
1357
  _this.identify(alias);
1341
1358
  });
1342
1359
  } else {
1343
- console.error('alias matches current distinct_id - skipping api call.');
1360
+ this.report_error('alias matches current distinct_id - skipping api call.');
1344
1361
  this.identify(alias);
1345
1362
  return -1;
1346
1363
  }
@@ -1467,14 +1484,6 @@ MixpanelLib.prototype.name_tag = function(name_tag) {
1467
1484
  * // the format {'Header-Name': value}
1468
1485
  * xhr_headers: {}
1469
1486
  *
1470
- * // protocol for fetching in-app message resources, e.g.
1471
- * // 'https://' or 'http://'; defaults to '//' (which defers to the
1472
- * // current page's protocol)
1473
- * inapp_protocol: '//'
1474
- *
1475
- * // whether to open in-app message link in new tab/window
1476
- * inapp_link_new_window: false
1477
- *
1478
1487
  * // whether to ignore or respect the web browser's Do Not Track setting
1479
1488
  * ignore_dnt: false
1480
1489
  * }
@@ -1523,7 +1532,7 @@ MixpanelLib.prototype.get_config = function(prop_name) {
1523
1532
  MixpanelLib.prototype._run_hook = function(hook_name) {
1524
1533
  var ret = (this['config']['hooks'][hook_name] || IDENTITY_FUNC).apply(this, slice.call(arguments, 1));
1525
1534
  if (typeof ret === 'undefined') {
1526
- console.error(hook_name + ' hook did not return a value');
1535
+ this.report_error(hook_name + ' hook did not return a value');
1527
1536
  ret = null;
1528
1537
  }
1529
1538
  return ret;
@@ -1565,75 +1574,6 @@ MixpanelLib.prototype._event_is_disabled = function(event_name) {
1565
1574
  _.include(this.__disabled_events, event_name);
1566
1575
  };
1567
1576
 
1568
- MixpanelLib.prototype._check_and_handle_triggered_notifications = addOptOutCheckMixpanelLib(function(event_data) {
1569
- if (!this._user_decide_check_complete) {
1570
- this._events_tracked_before_user_decide_check_complete.push(event_data);
1571
- } else {
1572
- var arr = this['_triggered_notifs'];
1573
- for (var i = 0; i < arr.length; i++) {
1574
- var notif = new MixpanelNotification(arr[i], this);
1575
- if (notif._matches_event_data(event_data)) {
1576
- this._show_notification(arr[i]);
1577
- return;
1578
- }
1579
- }
1580
- }
1581
- });
1582
-
1583
- MixpanelLib.prototype._check_and_handle_notifications = addOptOutCheckMixpanelLib(function(distinct_id) {
1584
- if (
1585
- !distinct_id ||
1586
- this._flags.identify_called ||
1587
- this.get_config('disable_notifications')
1588
- ) {
1589
- return;
1590
- }
1591
-
1592
- console.log('MIXPANEL NOTIFICATION CHECK');
1593
-
1594
- var data = {
1595
- 'verbose': true,
1596
- 'version': '3',
1597
- 'lib': 'web',
1598
- 'token': this.get_config('token'),
1599
- 'distinct_id': distinct_id
1600
- };
1601
- this._send_request(
1602
- this.get_config('api_host') + '/decide/',
1603
- data,
1604
- {method: 'GET', transport: 'XHR'},
1605
- this._prepare_callback(_.bind(function(result) {
1606
- if (result['notifications'] && result['notifications'].length > 0) {
1607
- this['_triggered_notifs'] = [];
1608
- var notifications = [];
1609
- _.each(result['notifications'], function(notif) {
1610
- (notif['display_triggers'] && notif['display_triggers'].length > 0 ? this['_triggered_notifs'] : notifications).push(notif);
1611
- }, this);
1612
- if (notifications.length > 0) {
1613
- this._show_notification.call(this, notifications[0]);
1614
- }
1615
- }
1616
- this._handle_user_decide_check_complete();
1617
- }, this))
1618
- );
1619
- });
1620
-
1621
- MixpanelLib.prototype._handle_user_decide_check_complete = function() {
1622
- this._user_decide_check_complete = true;
1623
-
1624
- // check notifications against events that were tracked before decide call completed
1625
- var events = this._events_tracked_before_user_decide_check_complete;
1626
- while (events.length > 0) {
1627
- var data = events.shift(); // replay in the same order they came in
1628
- this._check_and_handle_triggered_notifications(data);
1629
- }
1630
- };
1631
-
1632
- MixpanelLib.prototype._show_notification = function(notif_data) {
1633
- var notification = new MixpanelNotification(notif_data, this);
1634
- notification.show();
1635
- };
1636
-
1637
1577
  // perform some housekeeping around GDPR opt-in/out state
1638
1578
  MixpanelLib.prototype._gdpr_init = function() {
1639
1579
  var is_localStorage_requested = this.get_config('opt_out_tracking_persistence_type') === 'localStorage';
@@ -1879,6 +1819,18 @@ MixpanelLib.prototype.clear_opt_in_out_tracking = function(options) {
1879
1819
  this._gdpr_update_persistence(options);
1880
1820
  };
1881
1821
 
1822
+ MixpanelLib.prototype.report_error = function(msg, err) {
1823
+ console.error.apply(console.error, arguments);
1824
+ try {
1825
+ if (!err && !(msg instanceof Error)) {
1826
+ msg = new Error(msg);
1827
+ }
1828
+ this.get_config('error_reporter')(msg, err);
1829
+ } catch(err) {
1830
+ console.error(err);
1831
+ }
1832
+ };
1833
+
1882
1834
  // EXPORTS (for closure compiler)
1883
1835
 
1884
1836
  // MixpanelLib Exports
@@ -1901,9 +1853,6 @@ MixpanelLib.prototype['get_config'] = MixpanelLib.protot
1901
1853
  MixpanelLib.prototype['get_property'] = MixpanelLib.prototype.get_property;
1902
1854
  MixpanelLib.prototype['get_distinct_id'] = MixpanelLib.prototype.get_distinct_id;
1903
1855
  MixpanelLib.prototype['toString'] = MixpanelLib.prototype.toString;
1904
- MixpanelLib.prototype['_check_and_handle_notifications'] = MixpanelLib.prototype._check_and_handle_notifications;
1905
- MixpanelLib.prototype['_handle_user_decide_check_complete'] = MixpanelLib.prototype._handle_user_decide_check_complete;
1906
- MixpanelLib.prototype['_show_notification'] = MixpanelLib.prototype._show_notification;
1907
1856
  MixpanelLib.prototype['opt_out_tracking'] = MixpanelLib.prototype.opt_out_tracking;
1908
1857
  MixpanelLib.prototype['opt_in_tracking'] = MixpanelLib.prototype.opt_in_tracking;
1909
1858
  MixpanelLib.prototype['has_opted_out_tracking'] = MixpanelLib.prototype.has_opted_out_tracking;
@@ -1924,8 +1873,6 @@ MixpanelPersistence.prototype['update_referrer_info'] = MixpanelPersistence.pro
1924
1873
  MixpanelPersistence.prototype['get_cross_subdomain'] = MixpanelPersistence.prototype.get_cross_subdomain;
1925
1874
  MixpanelPersistence.prototype['clear'] = MixpanelPersistence.prototype.clear;
1926
1875
 
1927
- _.safewrap_class(MixpanelLib, ['identify', '_check_and_handle_notifications', '_show_notification']);
1928
-
1929
1876
 
1930
1877
  var instances = {};
1931
1878
  var extend_mp = function() {
@@ -110,9 +110,13 @@ MixpanelGroup.prototype.union = addOptOutCheckMixpanelGroup(function(list_name,
110
110
  * Permanently delete a group.
111
111
  *
112
112
  * ### Usage:
113
+ *
113
114
  * mixpanel.get_group('company', 'mixpanel').delete();
115
+ *
116
+ * @param {Function} [callback] If provided, the callback will be called after the tracking event
114
117
  */
115
118
  MixpanelGroup.prototype['delete'] = addOptOutCheckMixpanelGroup(function(callback) {
119
+ // bracket notation above prevents a minification error related to reserved words
116
120
  var data = this.delete_action();
117
121
  return this._send_request(data, callback);
118
122
  });
@@ -9,7 +9,6 @@ import {
9
9
  REMOVE_ACTION,
10
10
  UNION_ACTION
11
11
  } from './api-actions';
12
- import Config from './config';
13
12
  import { _, console } from './utils';
14
13
 
15
14
  /*
@@ -25,7 +24,6 @@ import { _, console } from './utils';
25
24
  // This key is deprecated, but we want to check for it to see whether aliasing is allowed.
26
25
  /** @const */ var PEOPLE_DISTINCT_ID_KEY = '$people_distinct_id';
27
26
  /** @const */ var ALIAS_ID_KEY = '__alias';
28
- /** @const */ var CAMPAIGN_IDS_KEY = '__cmpns';
29
27
  /** @const */ var EVENT_TIMERS_KEY = '__timers';
30
28
  /** @const */ var RESERVED_PROPERTIES = [
31
29
  SET_QUEUE_KEY,
@@ -37,7 +35,6 @@ import { _, console } from './utils';
37
35
  UNION_QUEUE_KEY,
38
36
  PEOPLE_DISTINCT_ID_KEY,
39
37
  ALIAS_ID_KEY,
40
- CAMPAIGN_IDS_KEY,
41
38
  EVENT_TIMERS_KEY
42
39
  ];
43
40
 
@@ -151,7 +148,6 @@ MixpanelPersistence.prototype.upgrade = function(config) {
151
148
 
152
149
  MixpanelPersistence.prototype.save = function() {
153
150
  if (this.disabled) { return; }
154
- this._expire_notification_campaigns();
155
151
  this.storage.set(
156
152
  this.name,
157
153
  _.JSONEncode(this['props']),
@@ -223,22 +219,6 @@ MixpanelPersistence.prototype.unregister = function(prop) {
223
219
  }
224
220
  };
225
221
 
226
- MixpanelPersistence.prototype._expire_notification_campaigns = _.safewrap(function() {
227
- var campaigns_shown = this['props'][CAMPAIGN_IDS_KEY],
228
- EXPIRY_TIME = Config.DEBUG ? 60 * 1000 : 60 * 60 * 1000; // 1 minute (Config.DEBUG) / 1 hour (PDXN)
229
- if (!campaigns_shown) {
230
- return;
231
- }
232
- for (var campaign_id in campaigns_shown) {
233
- if (1 * new Date() - campaigns_shown[campaign_id] > EXPIRY_TIME) {
234
- delete campaigns_shown[campaign_id];
235
- }
236
- }
237
- if (_.isEmptyObject(campaigns_shown)) {
238
- delete this['props'][CAMPAIGN_IDS_KEY];
239
- }
240
- });
241
-
242
222
  MixpanelPersistence.prototype.update_campaign_params = function() {
243
223
  if (!this.campaign_params_saved) {
244
224
  this.register_once(_.info.campaignParams());
@@ -501,6 +481,5 @@ export {
501
481
  UNION_QUEUE_KEY,
502
482
  PEOPLE_DISTINCT_ID_KEY,
503
483
  ALIAS_ID_KEY,
504
- CAMPAIGN_IDS_KEY,
505
484
  EVENT_TIMERS_KEY
506
485
  };