mixpanel-browser 2.41.0 → 2.42.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/workflows/tests.yml +25 -0
- package/CHANGELOG.md +6 -0
- package/README.md +4 -2
- package/dist/mixpanel.amd.js +32 -43
- package/dist/mixpanel.cjs.js +32 -43
- package/dist/mixpanel.globals.js +32 -43
- package/dist/mixpanel.min.js +139 -139
- package/dist/mixpanel.umd.js +32 -43
- package/doc/build-docs.js +16 -0
- package/doc/readme.io/javascript-full-api-reference.md +18 -0
- package/package.json +3 -3
- package/src/config.js +1 -1
- package/src/mixpanel-core.js +26 -19
- package/src/mixpanel-group.js +4 -0
- package/src/request-batcher.js +2 -2
- package/src/utils.js +0 -23
- package/tunnel.log +0 -0
- package/.travis.yml +0 -6
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
name: Tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ master ]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [ master ]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
build:
|
|
11
|
+
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
|
|
14
|
+
strategy:
|
|
15
|
+
matrix:
|
|
16
|
+
node-version: [12.x, 14.x]
|
|
17
|
+
|
|
18
|
+
steps:
|
|
19
|
+
- uses: actions/checkout@v2
|
|
20
|
+
- name: Use Node.js ${{ matrix.node-version }}
|
|
21
|
+
uses: actions/setup-node@v1
|
|
22
|
+
with:
|
|
23
|
+
node-version: ${{ matrix.node-version }}
|
|
24
|
+
- run: npm ci
|
|
25
|
+
- run: npm test
|
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
**2.42.0** (9 Nov 2021)
|
|
2
|
+
- Make `batch_requests` default-on for all remaining projects
|
|
3
|
+
- Replace `unload` event listener with modern alternatives (thanks @JoaoGomesTW)
|
|
4
|
+
- Don't retry requests blocked by client (adblockers)
|
|
5
|
+
- Retry with backoff after 429
|
|
6
|
+
|
|
1
7
|
**2.41.0** (28 Jan 2021)
|
|
2
8
|
- Remove all code related to Autotrack feature
|
|
3
9
|
|
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
|
|
1
2
|
# Mixpanel JavaScript Library
|
|
2
|
-
|
|
3
|
+

|
|
4
|
+
[](https://unpkg.com/mixpanel-browser/dist/mixpanel.min.js)
|
|
3
5
|
|
|
4
6
|
The Mixpanel JavaScript Library is a set of methods attached to a global `mixpanel` object
|
|
5
7
|
intended to be used by websites wishing to send data to Mixpanel projects. A full reference
|
|
@@ -73,4 +75,4 @@ Mixpanel production releases are tested against a large matrix of browsers and o
|
|
|
73
75
|
- Publish to readme.io via the [rdme](https://www.npmjs.com/package/rdme) util: `RDME_API_KEY=<API_KEY> npm run dox-publish`
|
|
74
76
|
|
|
75
77
|
## Thanks
|
|
76
|
-
For patches and support: @bohanyang, @dehau, @drubin, @D1plo1d, @feychenie, @mogstad, @pfhayes, @sandorfr, @stefansedich, @gfx, @pkaminski, @austince, @danielbaker, @mkdai, @wolever, @dpraul, @chriszamierowski
|
|
78
|
+
For patches and support: @bohanyang, @dehau, @drubin, @D1plo1d, @feychenie, @mogstad, @pfhayes, @sandorfr, @stefansedich, @gfx, @pkaminski, @austince, @danielbaker, @mkdai, @wolever, @dpraul, @chriszamierowski, @JoaoGomesTW
|
package/dist/mixpanel.amd.js
CHANGED
|
@@ -2,7 +2,7 @@ define(function () { 'use strict';
|
|
|
2
2
|
|
|
3
3
|
var Config = {
|
|
4
4
|
DEBUG: false,
|
|
5
|
-
LIB_VERSION: '2.
|
|
5
|
+
LIB_VERSION: '2.42.0'
|
|
6
6
|
};
|
|
7
7
|
|
|
8
8
|
// since es6 imports are static and we run unit tests from the console, window won't be defined when importing this file
|
|
@@ -1684,28 +1684,6 @@ define(function () { 'use strict';
|
|
|
1684
1684
|
return maxlen ? guid.substring(0, maxlen) : guid;
|
|
1685
1685
|
};
|
|
1686
1686
|
|
|
1687
|
-
/**
|
|
1688
|
-
* Check deterministically whether to include or exclude from a feature rollout/test based on the
|
|
1689
|
-
* given string and the desired percentage to include.
|
|
1690
|
-
* @param {String} str - string to run the check against (for instance a project's token)
|
|
1691
|
-
* @param {String} feature - name of feature (for inclusion in hash, to ensure different results
|
|
1692
|
-
* for different features)
|
|
1693
|
-
* @param {Number} percent_allowed - percentage chance that a given string will be included
|
|
1694
|
-
* @returns {Boolean} whether the given string should be included
|
|
1695
|
-
*/
|
|
1696
|
-
var determine_eligibility = _.safewrap(function(str, feature, percent_allowed) {
|
|
1697
|
-
str = str + feature;
|
|
1698
|
-
|
|
1699
|
-
// Bernstein's hash: http://www.cse.yorku.ca/~oz/hash.html#djb2
|
|
1700
|
-
var hash = 5381;
|
|
1701
|
-
for (var i = 0; i < str.length; i++) {
|
|
1702
|
-
hash = ((hash << 5) + hash) + str.charCodeAt(i);
|
|
1703
|
-
hash = hash & hash;
|
|
1704
|
-
}
|
|
1705
|
-
var dart = (hash >>> 0) % 100;
|
|
1706
|
-
return dart < percent_allowed;
|
|
1707
|
-
});
|
|
1708
|
-
|
|
1709
1687
|
// naive way to extract domain name (example.com) from full hostname (my.sub.example.com)
|
|
1710
1688
|
var SIMPLE_DOMAIN_MATCH_REGEX = /[a-z0-9][a-z0-9-]*\.[a-z]+$/i;
|
|
1711
1689
|
// this next one attempts to account for some ccSLDs, e.g. extracting oxford.ac.uk from www.oxford.ac.uk
|
|
@@ -2444,9 +2422,9 @@ define(function () { 'use strict';
|
|
|
2444
2422
|
} else if (
|
|
2445
2423
|
_.isObject(res) &&
|
|
2446
2424
|
res.xhr_req &&
|
|
2447
|
-
(res.xhr_req['status'] >= 500 || res.xhr_req['status']
|
|
2425
|
+
(res.xhr_req['status'] >= 500 || res.xhr_req['status'] === 429 || res.error === 'timeout')
|
|
2448
2426
|
) {
|
|
2449
|
-
// network or API error, retry
|
|
2427
|
+
// network or API error, or 429 Too Many Requests, retry
|
|
2450
2428
|
var retryMS = this.flushInterval * 2;
|
|
2451
2429
|
var headers = res.xhr_req['responseHeaders'];
|
|
2452
2430
|
if (headers) {
|
|
@@ -3016,9 +2994,13 @@ define(function () { 'use strict';
|
|
|
3016
2994
|
* Permanently delete a group.
|
|
3017
2995
|
*
|
|
3018
2996
|
* ### Usage:
|
|
2997
|
+
*
|
|
3019
2998
|
* mixpanel.get_group('company', 'mixpanel').delete();
|
|
2999
|
+
*
|
|
3000
|
+
* @param {Function} [callback] If provided, the callback will be called after the tracking event
|
|
3020
3001
|
*/
|
|
3021
3002
|
MixpanelGroup.prototype['delete'] = addOptOutCheckMixpanelGroup(function(callback) {
|
|
3003
|
+
// bracket notation above prevents a minification error related to reserved words
|
|
3022
3004
|
var data = this.delete_action();
|
|
3023
3005
|
return this._send_request(data, callback);
|
|
3024
3006
|
});
|
|
@@ -5920,7 +5902,7 @@ define(function () { 'use strict';
|
|
|
5920
5902
|
'inapp_protocol': '//',
|
|
5921
5903
|
'inapp_link_new_window': false,
|
|
5922
5904
|
'ignore_dnt': false,
|
|
5923
|
-
'batch_requests':
|
|
5905
|
+
'batch_requests': true,
|
|
5924
5906
|
'batch_size': 50,
|
|
5925
5907
|
'batch_flush_interval_ms': 5000,
|
|
5926
5908
|
'batch_request_timeout_ms': 90000,
|
|
@@ -6039,17 +6021,7 @@ define(function () { 'use strict';
|
|
|
6039
6021
|
this['config'] = {};
|
|
6040
6022
|
this['_triggered_notifs'] = [];
|
|
6041
6023
|
|
|
6042
|
-
|
|
6043
|
-
// (only if they have not specified a value in their init config
|
|
6044
|
-
// and they aren't using a custom API host)
|
|
6045
|
-
var variable_features = {};
|
|
6046
|
-
var api_host = config['api_host'];
|
|
6047
|
-
var is_custom_api = !!api_host && !api_host.match(/\.mixpanel\.com$/);
|
|
6048
|
-
if (!('batch_requests' in config) && !is_custom_api && determine_eligibility(token, 'batch', 60)) {
|
|
6049
|
-
variable_features['batch_requests'] = true;
|
|
6050
|
-
}
|
|
6051
|
-
|
|
6052
|
-
this.set_config(_.extend({}, DEFAULT_CONFIG, variable_features, config, {
|
|
6024
|
+
this.set_config(_.extend({}, DEFAULT_CONFIG, config, {
|
|
6053
6025
|
'name': name,
|
|
6054
6026
|
'token': token,
|
|
6055
6027
|
'callback_fn': ((name === PRIMARY_INSTANCE_NAME) ? name : PRIMARY_INSTANCE_NAME + '.' + name) + '._jsc'
|
|
@@ -6075,15 +6047,32 @@ define(function () { 'use strict';
|
|
|
6075
6047
|
} else {
|
|
6076
6048
|
this.init_batchers();
|
|
6077
6049
|
if (sendBeacon && window$1.addEventListener) {
|
|
6078
|
-
|
|
6079
|
-
|
|
6080
|
-
|
|
6081
|
-
|
|
6082
|
-
|
|
6050
|
+
// Before page closes or hides (user tabs away etc), attempt to flush any events
|
|
6051
|
+
// queued up via navigator.sendBeacon. Since sendBeacon doesn't report success/failure,
|
|
6052
|
+
// events will not be removed from the persistent store; if the site is loaded again,
|
|
6053
|
+
// the events will be flushed again on startup and deduplicated on the Mixpanel server
|
|
6054
|
+
// side.
|
|
6055
|
+
// There is no reliable way to capture only page close events, so we lean on the
|
|
6056
|
+
// visibilitychange and pagehide events as recommended at
|
|
6057
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/Window/unload_event#usage_notes.
|
|
6058
|
+
// These events fire when the user clicks away from the current page/tab, so will occur
|
|
6059
|
+
// more frequently than page unload, but are the only mechanism currently for capturing
|
|
6060
|
+
// this scenario somewhat reliably.
|
|
6061
|
+
var flush_on_unload = _.bind(function() {
|
|
6083
6062
|
if (!this.request_batchers.events.stopped) {
|
|
6084
6063
|
this.request_batchers.events.flush({unloading: true});
|
|
6085
6064
|
}
|
|
6086
|
-
}, this)
|
|
6065
|
+
}, this);
|
|
6066
|
+
window$1.addEventListener('pagehide', function(ev) {
|
|
6067
|
+
if (ev['persisted']) {
|
|
6068
|
+
flush_on_unload();
|
|
6069
|
+
}
|
|
6070
|
+
});
|
|
6071
|
+
window$1.addEventListener('visibilitychange', function() {
|
|
6072
|
+
if (document$1['visibilityState'] === 'hidden') {
|
|
6073
|
+
flush_on_unload();
|
|
6074
|
+
}
|
|
6075
|
+
});
|
|
6087
6076
|
}
|
|
6088
6077
|
}
|
|
6089
6078
|
}
|
package/dist/mixpanel.cjs.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var Config = {
|
|
4
4
|
DEBUG: false,
|
|
5
|
-
LIB_VERSION: '2.
|
|
5
|
+
LIB_VERSION: '2.42.0'
|
|
6
6
|
};
|
|
7
7
|
|
|
8
8
|
// since es6 imports are static and we run unit tests from the console, window won't be defined when importing this file
|
|
@@ -1684,28 +1684,6 @@ var cheap_guid = function(maxlen) {
|
|
|
1684
1684
|
return maxlen ? guid.substring(0, maxlen) : guid;
|
|
1685
1685
|
};
|
|
1686
1686
|
|
|
1687
|
-
/**
|
|
1688
|
-
* Check deterministically whether to include or exclude from a feature rollout/test based on the
|
|
1689
|
-
* given string and the desired percentage to include.
|
|
1690
|
-
* @param {String} str - string to run the check against (for instance a project's token)
|
|
1691
|
-
* @param {String} feature - name of feature (for inclusion in hash, to ensure different results
|
|
1692
|
-
* for different features)
|
|
1693
|
-
* @param {Number} percent_allowed - percentage chance that a given string will be included
|
|
1694
|
-
* @returns {Boolean} whether the given string should be included
|
|
1695
|
-
*/
|
|
1696
|
-
var determine_eligibility = _.safewrap(function(str, feature, percent_allowed) {
|
|
1697
|
-
str = str + feature;
|
|
1698
|
-
|
|
1699
|
-
// Bernstein's hash: http://www.cse.yorku.ca/~oz/hash.html#djb2
|
|
1700
|
-
var hash = 5381;
|
|
1701
|
-
for (var i = 0; i < str.length; i++) {
|
|
1702
|
-
hash = ((hash << 5) + hash) + str.charCodeAt(i);
|
|
1703
|
-
hash = hash & hash;
|
|
1704
|
-
}
|
|
1705
|
-
var dart = (hash >>> 0) % 100;
|
|
1706
|
-
return dart < percent_allowed;
|
|
1707
|
-
});
|
|
1708
|
-
|
|
1709
1687
|
// naive way to extract domain name (example.com) from full hostname (my.sub.example.com)
|
|
1710
1688
|
var SIMPLE_DOMAIN_MATCH_REGEX = /[a-z0-9][a-z0-9-]*\.[a-z]+$/i;
|
|
1711
1689
|
// this next one attempts to account for some ccSLDs, e.g. extracting oxford.ac.uk from www.oxford.ac.uk
|
|
@@ -2444,9 +2422,9 @@ RequestBatcher.prototype.flush = function(options) {
|
|
|
2444
2422
|
} else if (
|
|
2445
2423
|
_.isObject(res) &&
|
|
2446
2424
|
res.xhr_req &&
|
|
2447
|
-
(res.xhr_req['status'] >= 500 || res.xhr_req['status']
|
|
2425
|
+
(res.xhr_req['status'] >= 500 || res.xhr_req['status'] === 429 || res.error === 'timeout')
|
|
2448
2426
|
) {
|
|
2449
|
-
// network or API error, retry
|
|
2427
|
+
// network or API error, or 429 Too Many Requests, retry
|
|
2450
2428
|
var retryMS = this.flushInterval * 2;
|
|
2451
2429
|
var headers = res.xhr_req['responseHeaders'];
|
|
2452
2430
|
if (headers) {
|
|
@@ -3016,9 +2994,13 @@ MixpanelGroup.prototype.union = addOptOutCheckMixpanelGroup(function(list_name,
|
|
|
3016
2994
|
* Permanently delete a group.
|
|
3017
2995
|
*
|
|
3018
2996
|
* ### Usage:
|
|
2997
|
+
*
|
|
3019
2998
|
* mixpanel.get_group('company', 'mixpanel').delete();
|
|
2999
|
+
*
|
|
3000
|
+
* @param {Function} [callback] If provided, the callback will be called after the tracking event
|
|
3020
3001
|
*/
|
|
3021
3002
|
MixpanelGroup.prototype['delete'] = addOptOutCheckMixpanelGroup(function(callback) {
|
|
3003
|
+
// bracket notation above prevents a minification error related to reserved words
|
|
3022
3004
|
var data = this.delete_action();
|
|
3023
3005
|
return this._send_request(data, callback);
|
|
3024
3006
|
});
|
|
@@ -5920,7 +5902,7 @@ var DEFAULT_CONFIG = {
|
|
|
5920
5902
|
'inapp_protocol': '//',
|
|
5921
5903
|
'inapp_link_new_window': false,
|
|
5922
5904
|
'ignore_dnt': false,
|
|
5923
|
-
'batch_requests':
|
|
5905
|
+
'batch_requests': true,
|
|
5924
5906
|
'batch_size': 50,
|
|
5925
5907
|
'batch_flush_interval_ms': 5000,
|
|
5926
5908
|
'batch_request_timeout_ms': 90000,
|
|
@@ -6039,17 +6021,7 @@ MixpanelLib.prototype._init = function(token, config, name) {
|
|
|
6039
6021
|
this['config'] = {};
|
|
6040
6022
|
this['_triggered_notifs'] = [];
|
|
6041
6023
|
|
|
6042
|
-
|
|
6043
|
-
// (only if they have not specified a value in their init config
|
|
6044
|
-
// and they aren't using a custom API host)
|
|
6045
|
-
var variable_features = {};
|
|
6046
|
-
var api_host = config['api_host'];
|
|
6047
|
-
var is_custom_api = !!api_host && !api_host.match(/\.mixpanel\.com$/);
|
|
6048
|
-
if (!('batch_requests' in config) && !is_custom_api && determine_eligibility(token, 'batch', 60)) {
|
|
6049
|
-
variable_features['batch_requests'] = true;
|
|
6050
|
-
}
|
|
6051
|
-
|
|
6052
|
-
this.set_config(_.extend({}, DEFAULT_CONFIG, variable_features, config, {
|
|
6024
|
+
this.set_config(_.extend({}, DEFAULT_CONFIG, config, {
|
|
6053
6025
|
'name': name,
|
|
6054
6026
|
'token': token,
|
|
6055
6027
|
'callback_fn': ((name === PRIMARY_INSTANCE_NAME) ? name : PRIMARY_INSTANCE_NAME + '.' + name) + '._jsc'
|
|
@@ -6075,15 +6047,32 @@ MixpanelLib.prototype._init = function(token, config, name) {
|
|
|
6075
6047
|
} else {
|
|
6076
6048
|
this.init_batchers();
|
|
6077
6049
|
if (sendBeacon && window$1.addEventListener) {
|
|
6078
|
-
|
|
6079
|
-
|
|
6080
|
-
|
|
6081
|
-
|
|
6082
|
-
|
|
6050
|
+
// Before page closes or hides (user tabs away etc), attempt to flush any events
|
|
6051
|
+
// queued up via navigator.sendBeacon. Since sendBeacon doesn't report success/failure,
|
|
6052
|
+
// events will not be removed from the persistent store; if the site is loaded again,
|
|
6053
|
+
// the events will be flushed again on startup and deduplicated on the Mixpanel server
|
|
6054
|
+
// side.
|
|
6055
|
+
// There is no reliable way to capture only page close events, so we lean on the
|
|
6056
|
+
// visibilitychange and pagehide events as recommended at
|
|
6057
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/Window/unload_event#usage_notes.
|
|
6058
|
+
// These events fire when the user clicks away from the current page/tab, so will occur
|
|
6059
|
+
// more frequently than page unload, but are the only mechanism currently for capturing
|
|
6060
|
+
// this scenario somewhat reliably.
|
|
6061
|
+
var flush_on_unload = _.bind(function() {
|
|
6083
6062
|
if (!this.request_batchers.events.stopped) {
|
|
6084
6063
|
this.request_batchers.events.flush({unloading: true});
|
|
6085
6064
|
}
|
|
6086
|
-
}, this)
|
|
6065
|
+
}, this);
|
|
6066
|
+
window$1.addEventListener('pagehide', function(ev) {
|
|
6067
|
+
if (ev['persisted']) {
|
|
6068
|
+
flush_on_unload();
|
|
6069
|
+
}
|
|
6070
|
+
});
|
|
6071
|
+
window$1.addEventListener('visibilitychange', function() {
|
|
6072
|
+
if (document$1['visibilityState'] === 'hidden') {
|
|
6073
|
+
flush_on_unload();
|
|
6074
|
+
}
|
|
6075
|
+
});
|
|
6087
6076
|
}
|
|
6088
6077
|
}
|
|
6089
6078
|
}
|
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.42.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
|
|
@@ -1685,28 +1685,6 @@
|
|
|
1685
1685
|
return maxlen ? guid.substring(0, maxlen) : guid;
|
|
1686
1686
|
};
|
|
1687
1687
|
|
|
1688
|
-
/**
|
|
1689
|
-
* Check deterministically whether to include or exclude from a feature rollout/test based on the
|
|
1690
|
-
* given string and the desired percentage to include.
|
|
1691
|
-
* @param {String} str - string to run the check against (for instance a project's token)
|
|
1692
|
-
* @param {String} feature - name of feature (for inclusion in hash, to ensure different results
|
|
1693
|
-
* for different features)
|
|
1694
|
-
* @param {Number} percent_allowed - percentage chance that a given string will be included
|
|
1695
|
-
* @returns {Boolean} whether the given string should be included
|
|
1696
|
-
*/
|
|
1697
|
-
var determine_eligibility = _.safewrap(function(str, feature, percent_allowed) {
|
|
1698
|
-
str = str + feature;
|
|
1699
|
-
|
|
1700
|
-
// Bernstein's hash: http://www.cse.yorku.ca/~oz/hash.html#djb2
|
|
1701
|
-
var hash = 5381;
|
|
1702
|
-
for (var i = 0; i < str.length; i++) {
|
|
1703
|
-
hash = ((hash << 5) + hash) + str.charCodeAt(i);
|
|
1704
|
-
hash = hash & hash;
|
|
1705
|
-
}
|
|
1706
|
-
var dart = (hash >>> 0) % 100;
|
|
1707
|
-
return dart < percent_allowed;
|
|
1708
|
-
});
|
|
1709
|
-
|
|
1710
1688
|
// naive way to extract domain name (example.com) from full hostname (my.sub.example.com)
|
|
1711
1689
|
var SIMPLE_DOMAIN_MATCH_REGEX = /[a-z0-9][a-z0-9-]*\.[a-z]+$/i;
|
|
1712
1690
|
// this next one attempts to account for some ccSLDs, e.g. extracting oxford.ac.uk from www.oxford.ac.uk
|
|
@@ -2445,9 +2423,9 @@
|
|
|
2445
2423
|
} else if (
|
|
2446
2424
|
_.isObject(res) &&
|
|
2447
2425
|
res.xhr_req &&
|
|
2448
|
-
(res.xhr_req['status'] >= 500 || res.xhr_req['status']
|
|
2426
|
+
(res.xhr_req['status'] >= 500 || res.xhr_req['status'] === 429 || res.error === 'timeout')
|
|
2449
2427
|
) {
|
|
2450
|
-
// network or API error, retry
|
|
2428
|
+
// network or API error, or 429 Too Many Requests, retry
|
|
2451
2429
|
var retryMS = this.flushInterval * 2;
|
|
2452
2430
|
var headers = res.xhr_req['responseHeaders'];
|
|
2453
2431
|
if (headers) {
|
|
@@ -3017,9 +2995,13 @@
|
|
|
3017
2995
|
* Permanently delete a group.
|
|
3018
2996
|
*
|
|
3019
2997
|
* ### Usage:
|
|
2998
|
+
*
|
|
3020
2999
|
* mixpanel.get_group('company', 'mixpanel').delete();
|
|
3000
|
+
*
|
|
3001
|
+
* @param {Function} [callback] If provided, the callback will be called after the tracking event
|
|
3021
3002
|
*/
|
|
3022
3003
|
MixpanelGroup.prototype['delete'] = addOptOutCheckMixpanelGroup(function(callback) {
|
|
3004
|
+
// bracket notation above prevents a minification error related to reserved words
|
|
3023
3005
|
var data = this.delete_action();
|
|
3024
3006
|
return this._send_request(data, callback);
|
|
3025
3007
|
});
|
|
@@ -5921,7 +5903,7 @@
|
|
|
5921
5903
|
'inapp_protocol': '//',
|
|
5922
5904
|
'inapp_link_new_window': false,
|
|
5923
5905
|
'ignore_dnt': false,
|
|
5924
|
-
'batch_requests':
|
|
5906
|
+
'batch_requests': true,
|
|
5925
5907
|
'batch_size': 50,
|
|
5926
5908
|
'batch_flush_interval_ms': 5000,
|
|
5927
5909
|
'batch_request_timeout_ms': 90000,
|
|
@@ -6040,17 +6022,7 @@
|
|
|
6040
6022
|
this['config'] = {};
|
|
6041
6023
|
this['_triggered_notifs'] = [];
|
|
6042
6024
|
|
|
6043
|
-
|
|
6044
|
-
// (only if they have not specified a value in their init config
|
|
6045
|
-
// and they aren't using a custom API host)
|
|
6046
|
-
var variable_features = {};
|
|
6047
|
-
var api_host = config['api_host'];
|
|
6048
|
-
var is_custom_api = !!api_host && !api_host.match(/\.mixpanel\.com$/);
|
|
6049
|
-
if (!('batch_requests' in config) && !is_custom_api && determine_eligibility(token, 'batch', 60)) {
|
|
6050
|
-
variable_features['batch_requests'] = true;
|
|
6051
|
-
}
|
|
6052
|
-
|
|
6053
|
-
this.set_config(_.extend({}, DEFAULT_CONFIG, variable_features, config, {
|
|
6025
|
+
this.set_config(_.extend({}, DEFAULT_CONFIG, config, {
|
|
6054
6026
|
'name': name,
|
|
6055
6027
|
'token': token,
|
|
6056
6028
|
'callback_fn': ((name === PRIMARY_INSTANCE_NAME) ? name : PRIMARY_INSTANCE_NAME + '.' + name) + '._jsc'
|
|
@@ -6076,15 +6048,32 @@
|
|
|
6076
6048
|
} else {
|
|
6077
6049
|
this.init_batchers();
|
|
6078
6050
|
if (sendBeacon && window$1.addEventListener) {
|
|
6079
|
-
|
|
6080
|
-
|
|
6081
|
-
|
|
6082
|
-
|
|
6083
|
-
|
|
6051
|
+
// Before page closes or hides (user tabs away etc), attempt to flush any events
|
|
6052
|
+
// queued up via navigator.sendBeacon. Since sendBeacon doesn't report success/failure,
|
|
6053
|
+
// events will not be removed from the persistent store; if the site is loaded again,
|
|
6054
|
+
// the events will be flushed again on startup and deduplicated on the Mixpanel server
|
|
6055
|
+
// side.
|
|
6056
|
+
// There is no reliable way to capture only page close events, so we lean on the
|
|
6057
|
+
// visibilitychange and pagehide events as recommended at
|
|
6058
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/Window/unload_event#usage_notes.
|
|
6059
|
+
// These events fire when the user clicks away from the current page/tab, so will occur
|
|
6060
|
+
// more frequently than page unload, but are the only mechanism currently for capturing
|
|
6061
|
+
// this scenario somewhat reliably.
|
|
6062
|
+
var flush_on_unload = _.bind(function() {
|
|
6084
6063
|
if (!this.request_batchers.events.stopped) {
|
|
6085
6064
|
this.request_batchers.events.flush({unloading: true});
|
|
6086
6065
|
}
|
|
6087
|
-
}, this)
|
|
6066
|
+
}, this);
|
|
6067
|
+
window$1.addEventListener('pagehide', function(ev) {
|
|
6068
|
+
if (ev['persisted']) {
|
|
6069
|
+
flush_on_unload();
|
|
6070
|
+
}
|
|
6071
|
+
});
|
|
6072
|
+
window$1.addEventListener('visibilitychange', function() {
|
|
6073
|
+
if (document$1['visibilityState'] === 'hidden') {
|
|
6074
|
+
flush_on_unload();
|
|
6075
|
+
}
|
|
6076
|
+
});
|
|
6088
6077
|
}
|
|
6089
6078
|
}
|
|
6090
6079
|
}
|