mixpanel-browser 2.55.0 → 2.56.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/.eslintrc.json +31 -1
- package/CHANGELOG.md +14 -0
- package/README.md +1 -1
- package/dist/mixpanel-core.cjs.js +52 -15
- package/dist/mixpanel-recorder.js +211 -87
- package/dist/mixpanel-recorder.min.js +10 -9
- package/dist/mixpanel-recorder.min.js.map +1 -0
- package/dist/mixpanel-with-async-recorder.cjs.js +52 -15
- package/dist/mixpanel.amd.js +238 -93
- package/dist/mixpanel.cjs.js +238 -93
- package/dist/mixpanel.globals.js +52 -15
- package/dist/mixpanel.min.js +109 -107
- package/dist/mixpanel.min.js.map +8 -0
- package/dist/mixpanel.module.js +238 -93
- package/dist/mixpanel.umd.js +238 -93
- package/package.json +1 -1
- package/src/config.js +1 -1
- package/src/mixpanel-core.js +27 -6
- package/src/recorder/index.js +39 -232
- package/src/recorder/rollup.config.js +2 -1
- package/src/recorder/session-recording.js +305 -0
- package/src/request-batcher.js +7 -2
- package/src/request-queue.js +5 -3
- package/src/utils.js +26 -13
package/.eslintrc.json
CHANGED
|
@@ -27,5 +27,35 @@
|
|
|
27
27
|
"error",
|
|
28
28
|
"always"
|
|
29
29
|
]
|
|
30
|
-
}
|
|
30
|
+
},
|
|
31
|
+
"overrides": [{
|
|
32
|
+
"files": ["tests/unit/**/*.js"],
|
|
33
|
+
"parserOptions": {
|
|
34
|
+
"ecmaVersion": 8,
|
|
35
|
+
"sourceType": "module"
|
|
36
|
+
},
|
|
37
|
+
"env": {
|
|
38
|
+
"mocha": true
|
|
39
|
+
},
|
|
40
|
+
"rules": {
|
|
41
|
+
"camelcase": "error",
|
|
42
|
+
"eol-last": "error",
|
|
43
|
+
"eqeqeq": "error",
|
|
44
|
+
"indent": ["error", 2],
|
|
45
|
+
"linebreak-style": [
|
|
46
|
+
"error",
|
|
47
|
+
"unix"
|
|
48
|
+
],
|
|
49
|
+
"no-console": "off",
|
|
50
|
+
"no-trailing-spaces": "error",
|
|
51
|
+
"quotes": [
|
|
52
|
+
"error",
|
|
53
|
+
"backtick"
|
|
54
|
+
],
|
|
55
|
+
"semi": [
|
|
56
|
+
"error",
|
|
57
|
+
"always"
|
|
58
|
+
]
|
|
59
|
+
}
|
|
60
|
+
}]
|
|
31
61
|
}
|
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
**2.56.0** (4 Nov 2024)
|
|
2
|
+
- Recording payloads now include additional metadata: the current URL, library type, and library version.
|
|
3
|
+
- Sourcemaps are now generated for the recorder module.
|
|
4
|
+
- Added debugging method `mixpanel.get_session_replay_url()` which will return a Mixpanel UI link to the session replay if there is an active recording taking place.
|
|
5
|
+
- Refactored session recording module to encapsulate each active recording and its metadata. Added a unit test suite for the new `session-recording.js`.
|
|
6
|
+
- Added some additional error handling for when `stopRecording` fails or rrweb silently fails to start recording.
|
|
7
|
+
- Removed `record_inline_images` option due to buggy behavior in rrweb.
|
|
8
|
+
|
|
9
|
+
**2.55.1** (27 Aug 2024)
|
|
10
|
+
- Adds a minimum recording length option for session recording
|
|
11
|
+
- Fixes and improvements for session recording batcher to support offline queueing and retry
|
|
12
|
+
- Fix for query param parsing/escaping
|
|
13
|
+
- Support for more UTM tags / click IDs (thanks @aliyalcinkaya)
|
|
14
|
+
|
|
1
15
|
**2.55.0** (2 Aug 2024)
|
|
2
16
|
- Added new build to support native JavaScript modules
|
|
3
17
|
|
package/README.md
CHANGED
|
@@ -78,4 +78,4 @@ Mixpanel production releases are tested against a large matrix of browsers and o
|
|
|
78
78
|
- Publish to readme.io via the [rdme](https://www.npmjs.com/package/rdme) util: `RDME_API_KEY=<API_KEY> RDME_DOC_VERSION=<version> npm run dox-publish`
|
|
79
79
|
|
|
80
80
|
## Thanks
|
|
81
|
-
For patches and support: @bohanyang, @dehau, @drubin, @D1plo1d, @feychenie, @mogstad, @pfhayes, @sandorfr, @stefansedich, @gfx, @pkaminski, @austince, @danielbaker, @mkdai, @wolever, @dpraul, @chriszamierowski, @JoaoGomesTW
|
|
81
|
+
For patches and support: @bohanyang, @dehau, @drubin, @D1plo1d, @feychenie, @mogstad, @pfhayes, @sandorfr, @stefansedich, @gfx, @pkaminski, @austince, @danielbaker, @mkdai, @wolever, @dpraul, @chriszamierowski, @JoaoGomesTW, @@aliyalcinkaya
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var Config = {
|
|
4
4
|
DEBUG: false,
|
|
5
|
-
LIB_VERSION: '2.
|
|
5
|
+
LIB_VERSION: '2.56.0'
|
|
6
6
|
};
|
|
7
7
|
|
|
8
8
|
/* eslint camelcase: "off", eqeqeq: "off" */
|
|
@@ -14,7 +14,7 @@ if (typeof(window) === 'undefined') {
|
|
|
14
14
|
hostname: ''
|
|
15
15
|
};
|
|
16
16
|
win = {
|
|
17
|
-
navigator: { userAgent: '' },
|
|
17
|
+
navigator: { userAgent: '', onLine: true },
|
|
18
18
|
document: {
|
|
19
19
|
location: loc,
|
|
20
20
|
referrer: ''
|
|
@@ -968,7 +968,7 @@ _.HTTPBuildQuery = function(formdata, arg_separator) {
|
|
|
968
968
|
_.getQueryParam = function(url, param) {
|
|
969
969
|
// Expects a raw URL
|
|
970
970
|
|
|
971
|
-
param = param.replace(/[[]
|
|
971
|
+
param = param.replace(/[[]/g, '\\[').replace(/[\]]/g, '\\]');
|
|
972
972
|
var regexS = '[\\?&]' + param + '=([^&#]*)',
|
|
973
973
|
regex = new RegExp(regexS),
|
|
974
974
|
results = regex.exec(url);
|
|
@@ -1425,8 +1425,8 @@ _.dom_query = (function() {
|
|
|
1425
1425
|
};
|
|
1426
1426
|
})();
|
|
1427
1427
|
|
|
1428
|
-
var CAMPAIGN_KEYWORDS = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_content', 'utm_term'];
|
|
1429
|
-
var CLICK_IDS = ['dclid', 'fbclid', 'gclid', 'ko_click_id', 'li_fat_id', 'msclkid', 'ttclid', 'twclid', 'wbraid'];
|
|
1428
|
+
var CAMPAIGN_KEYWORDS = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_content', 'utm_term', 'utm_id', 'utm_source_platform','utm_campaign_id', 'utm_creative_format', 'utm_marketing_tactic'];
|
|
1429
|
+
var CLICK_IDS = ['dclid', 'fbclid', 'gclid', 'ko_click_id', 'li_fat_id', 'msclkid', 'sccid', 'ttclid', 'twclid', 'wbraid'];
|
|
1430
1430
|
|
|
1431
1431
|
_.info = {
|
|
1432
1432
|
campaignParams: function(default_value) {
|
|
@@ -1708,6 +1708,15 @@ var extract_domain = function(hostname) {
|
|
|
1708
1708
|
return matches ? matches[0] : '';
|
|
1709
1709
|
};
|
|
1710
1710
|
|
|
1711
|
+
/**
|
|
1712
|
+
* Check whether we have network connection. default to true for browsers that don't support navigator.onLine (IE)
|
|
1713
|
+
* @returns {boolean}
|
|
1714
|
+
*/
|
|
1715
|
+
var isOnline = function() {
|
|
1716
|
+
var onLine = win.navigator['onLine'];
|
|
1717
|
+
return _.isUndefined(onLine) || onLine;
|
|
1718
|
+
};
|
|
1719
|
+
|
|
1711
1720
|
var JSONStringify = null, JSONParse = null;
|
|
1712
1721
|
if (typeof JSON !== 'undefined') {
|
|
1713
1722
|
JSONStringify = JSON.stringify;
|
|
@@ -2047,11 +2056,13 @@ var logger$1 = console_with_prefix('batch');
|
|
|
2047
2056
|
var RequestQueue = function(storageKey, options) {
|
|
2048
2057
|
options = options || {};
|
|
2049
2058
|
this.storageKey = storageKey;
|
|
2050
|
-
this.
|
|
2059
|
+
this.usePersistence = options.usePersistence;
|
|
2060
|
+
if (this.usePersistence) {
|
|
2061
|
+
this.storage = options.storage || window.localStorage;
|
|
2062
|
+
this.lock = new SharedLock(storageKey, {storage: this.storage});
|
|
2063
|
+
}
|
|
2051
2064
|
this.reportError = options.errorReporter || _.bind(logger$1.error, logger$1);
|
|
2052
|
-
this.lock = new SharedLock(storageKey, {storage: this.storage});
|
|
2053
2065
|
|
|
2054
|
-
this.usePersistence = options.usePersistence;
|
|
2055
2066
|
this.pid = options.pid || null; // pass pid to test out storage lock contention scenarios
|
|
2056
2067
|
|
|
2057
2068
|
this.memQueue = [];
|
|
@@ -2523,7 +2534,12 @@ RequestBatcher.prototype.flush = function(options) {
|
|
|
2523
2534
|
this.flush();
|
|
2524
2535
|
} else if (
|
|
2525
2536
|
_.isObject(res) &&
|
|
2526
|
-
(
|
|
2537
|
+
(
|
|
2538
|
+
res.httpStatusCode >= 500
|
|
2539
|
+
|| res.httpStatusCode === 429
|
|
2540
|
+
|| (res.httpStatusCode <= 0 && !isOnline())
|
|
2541
|
+
|| res.error === 'timeout'
|
|
2542
|
+
)
|
|
2527
2543
|
) {
|
|
2528
2544
|
// network or API error, or 429 Too Many Requests, retry
|
|
2529
2545
|
var retryMS = this.flushInterval * 2;
|
|
@@ -4243,10 +4259,10 @@ var DEFAULT_CONFIG = {
|
|
|
4243
4259
|
'record_block_selector': 'img, video',
|
|
4244
4260
|
'record_collect_fonts': false,
|
|
4245
4261
|
'record_idle_timeout_ms': 30 * 60 * 1000, // 30 minutes
|
|
4246
|
-
'record_inline_images': false,
|
|
4247
4262
|
'record_mask_text_class': new RegExp('^(mp-mask|fs-mask|amp-mask|rr-mask|ph-mask)$'),
|
|
4248
4263
|
'record_mask_text_selector': '*',
|
|
4249
4264
|
'record_max_ms': MAX_RECORDING_MS,
|
|
4265
|
+
'record_min_ms': 0,
|
|
4250
4266
|
'record_sessions_percent': 0,
|
|
4251
4267
|
'recorder_src': 'https://cdn.mxpnl.com/libs/mixpanel-recorder.min.js'
|
|
4252
4268
|
};
|
|
@@ -4495,15 +4511,35 @@ MixpanelLib.prototype.stop_session_recording = function () {
|
|
|
4495
4511
|
|
|
4496
4512
|
MixpanelLib.prototype.get_session_recording_properties = function () {
|
|
4497
4513
|
var props = {};
|
|
4498
|
-
|
|
4499
|
-
|
|
4500
|
-
|
|
4501
|
-
props['$mp_replay_id'] = replay_id;
|
|
4502
|
-
}
|
|
4514
|
+
var replay_id = this._get_session_replay_id();
|
|
4515
|
+
if (replay_id) {
|
|
4516
|
+
props['$mp_replay_id'] = replay_id;
|
|
4503
4517
|
}
|
|
4504
4518
|
return props;
|
|
4505
4519
|
};
|
|
4506
4520
|
|
|
4521
|
+
MixpanelLib.prototype.get_session_replay_url = function () {
|
|
4522
|
+
var replay_url = null;
|
|
4523
|
+
var replay_id = this._get_session_replay_id();
|
|
4524
|
+
if (replay_id) {
|
|
4525
|
+
var query_params = _.HTTPBuildQuery({
|
|
4526
|
+
'replay_id': replay_id,
|
|
4527
|
+
'distinct_id': this.get_distinct_id(),
|
|
4528
|
+
'token': this.get_config('token')
|
|
4529
|
+
});
|
|
4530
|
+
replay_url = 'https://mixpanel.com/projects/replay-redirect?' + query_params;
|
|
4531
|
+
}
|
|
4532
|
+
return replay_url;
|
|
4533
|
+
};
|
|
4534
|
+
|
|
4535
|
+
MixpanelLib.prototype._get_session_replay_id = function () {
|
|
4536
|
+
var replay_id = null;
|
|
4537
|
+
if (this._recorder) {
|
|
4538
|
+
replay_id = this._recorder['replayId'];
|
|
4539
|
+
}
|
|
4540
|
+
return replay_id || null;
|
|
4541
|
+
};
|
|
4542
|
+
|
|
4507
4543
|
// Private methods
|
|
4508
4544
|
|
|
4509
4545
|
MixpanelLib.prototype._loaded = function() {
|
|
@@ -6230,6 +6266,7 @@ MixpanelLib.prototype['stop_batch_senders'] = MixpanelLib.protot
|
|
|
6230
6266
|
MixpanelLib.prototype['start_session_recording'] = MixpanelLib.prototype.start_session_recording;
|
|
6231
6267
|
MixpanelLib.prototype['stop_session_recording'] = MixpanelLib.prototype.stop_session_recording;
|
|
6232
6268
|
MixpanelLib.prototype['get_session_recording_properties'] = MixpanelLib.prototype.get_session_recording_properties;
|
|
6269
|
+
MixpanelLib.prototype['get_session_replay_url'] = MixpanelLib.prototype.get_session_replay_url;
|
|
6233
6270
|
MixpanelLib.prototype['DEFAULT_API_ROUTES'] = DEFAULT_API_ROUTES;
|
|
6234
6271
|
|
|
6235
6272
|
// MixpanelPersistence Exports
|