mixpanel-browser 2.67.0 → 2.69.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/CHANGELOG.md +5 -0
- package/dist/mixpanel-core.cjs.js +132 -6
- package/dist/mixpanel-recorder.js +186 -47
- 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 +132 -6
- package/dist/mixpanel-with-recorder.js +308 -51
- package/dist/mixpanel-with-recorder.min.js +1 -1
- package/dist/mixpanel.amd.js +308 -51
- package/dist/mixpanel.cjs.js +308 -51
- package/dist/mixpanel.globals.js +132 -6
- package/dist/mixpanel.min.js +148 -146
- package/dist/mixpanel.module.js +308 -51
- package/dist/mixpanel.umd.js +308 -51
- package/dist/rrweb-compiled.js +190 -59
- package/package.json +14 -2
- package/rollup.config.mjs +2 -2
- package/src/autocapture/index.js +59 -1
- package/src/autocapture/rageclick.js +38 -0
- package/src/config.js +1 -1
- package/src/flags/index.js +22 -1
- package/src/index.d.ts +19 -0
- package/src/mixpanel-core.js +10 -2
- package/src/recorder/recorder.js +1 -1
- package/src/recorder/recording-registry.js +37 -2
- package/src/recorder/session-recording.js +2 -3
- package/src/request-queue.js +1 -1
- package/src/storage/indexed-db.js +4 -0
- package/src/storage/local-storage.js +4 -0
- package/src/storage/wrapper.js +1 -0
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.69.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
|
|
@@ -2655,6 +2655,38 @@
|
|
|
2655
2655
|
return true;
|
|
2656
2656
|
}
|
|
2657
2657
|
|
|
2658
|
+
/** @const */ var DEFAULT_RAGE_CLICK_THRESHOLD_PX = 30;
|
|
2659
|
+
/** @const */ var DEFAULT_RAGE_CLICK_TIMEOUT_MS = 1000;
|
|
2660
|
+
/** @const */ var DEFAULT_RAGE_CLICK_CLICK_COUNT = 4;
|
|
2661
|
+
|
|
2662
|
+
function RageClickTracker() {
|
|
2663
|
+
this.clicks = [];
|
|
2664
|
+
}
|
|
2665
|
+
|
|
2666
|
+
RageClickTracker.prototype.isRageClick = function(x, y, options) {
|
|
2667
|
+
options = options || {};
|
|
2668
|
+
var thresholdPx = options['threshold_px'] || DEFAULT_RAGE_CLICK_THRESHOLD_PX;
|
|
2669
|
+
var timeoutMs = options['timeout_ms'] || DEFAULT_RAGE_CLICK_TIMEOUT_MS;
|
|
2670
|
+
var clickCount = options['click_count'] || DEFAULT_RAGE_CLICK_CLICK_COUNT;
|
|
2671
|
+
var timestamp = Date.now();
|
|
2672
|
+
|
|
2673
|
+
var lastClick = this.clicks[this.clicks.length - 1];
|
|
2674
|
+
if (
|
|
2675
|
+
lastClick &&
|
|
2676
|
+
timestamp - lastClick.timestamp < timeoutMs &&
|
|
2677
|
+
Math.sqrt(Math.pow(x - lastClick.x, 2) + Math.pow(y - lastClick.y, 2)) < thresholdPx
|
|
2678
|
+
) {
|
|
2679
|
+
this.clicks.push({ x: x, y: y, timestamp: timestamp });
|
|
2680
|
+
if (this.clicks.length >= clickCount) {
|
|
2681
|
+
this.clicks = [];
|
|
2682
|
+
return true;
|
|
2683
|
+
}
|
|
2684
|
+
} else {
|
|
2685
|
+
this.clicks = [{ x: x, y: y, timestamp: timestamp }];
|
|
2686
|
+
}
|
|
2687
|
+
return false;
|
|
2688
|
+
};
|
|
2689
|
+
|
|
2658
2690
|
var AUTOCAPTURE_CONFIG_KEY = 'autocapture';
|
|
2659
2691
|
var LEGACY_PAGEVIEW_CONFIG_KEY = 'track_pageview';
|
|
2660
2692
|
|
|
@@ -2676,6 +2708,7 @@
|
|
|
2676
2708
|
var CONFIG_TRACK_CLICK = 'click';
|
|
2677
2709
|
var CONFIG_TRACK_INPUT = 'input';
|
|
2678
2710
|
var CONFIG_TRACK_PAGEVIEW = 'pageview';
|
|
2711
|
+
var CONFIG_TRACK_RAGE_CLICK = 'rage_click';
|
|
2679
2712
|
var CONFIG_TRACK_SCROLL = 'scroll';
|
|
2680
2713
|
var CONFIG_TRACK_SUBMIT = 'submit';
|
|
2681
2714
|
|
|
@@ -2693,6 +2726,7 @@
|
|
|
2693
2726
|
CONFIG_DEFAULTS$1[CONFIG_TRACK_CLICK] = true;
|
|
2694
2727
|
CONFIG_DEFAULTS$1[CONFIG_TRACK_INPUT] = true;
|
|
2695
2728
|
CONFIG_DEFAULTS$1[CONFIG_TRACK_PAGEVIEW] = PAGEVIEW_OPTION_FULL_URL;
|
|
2729
|
+
CONFIG_DEFAULTS$1[CONFIG_TRACK_RAGE_CLICK] = true;
|
|
2696
2730
|
CONFIG_DEFAULTS$1[CONFIG_TRACK_SCROLL] = true;
|
|
2697
2731
|
CONFIG_DEFAULTS$1[CONFIG_TRACK_SUBMIT] = true;
|
|
2698
2732
|
|
|
@@ -2702,6 +2736,7 @@
|
|
|
2702
2736
|
|
|
2703
2737
|
var MP_EV_CLICK = '$mp_click';
|
|
2704
2738
|
var MP_EV_INPUT = '$mp_input_change';
|
|
2739
|
+
var MP_EV_RAGE_CLICK = '$mp_rage_click';
|
|
2705
2740
|
var MP_EV_SCROLL = '$mp_scroll';
|
|
2706
2741
|
var MP_EV_SUBMIT = '$mp_submit';
|
|
2707
2742
|
|
|
@@ -2724,6 +2759,7 @@
|
|
|
2724
2759
|
this.initInputTracking();
|
|
2725
2760
|
this.initScrollTracking();
|
|
2726
2761
|
this.initSubmitTracking();
|
|
2762
|
+
this.initRageClickTracking();
|
|
2727
2763
|
};
|
|
2728
2764
|
|
|
2729
2765
|
Autocapture.prototype.getFullConfig = function() {
|
|
@@ -2802,6 +2838,11 @@
|
|
|
2802
2838
|
return;
|
|
2803
2839
|
}
|
|
2804
2840
|
|
|
2841
|
+
var isCapturedForHeatMap = this.mp.is_recording_heatmap_data() && (
|
|
2842
|
+
(mpEventName === MP_EV_CLICK && !this.getConfig(CONFIG_TRACK_CLICK)) ||
|
|
2843
|
+
(mpEventName === MP_EV_RAGE_CLICK && !this._getRageClickConfig())
|
|
2844
|
+
);
|
|
2845
|
+
|
|
2805
2846
|
var props = getPropsForDOMEvent(ev, {
|
|
2806
2847
|
allowElementCallback: this.getConfig(CONFIG_ALLOW_ELEMENT_CALLBACK),
|
|
2807
2848
|
allowSelectors: this.getConfig(CONFIG_ALLOW_SELECTORS),
|
|
@@ -2810,7 +2851,7 @@
|
|
|
2810
2851
|
blockSelectors: this.getConfig(CONFIG_BLOCK_SELECTORS),
|
|
2811
2852
|
captureExtraAttrs: this.getConfig(CONFIG_CAPTURE_EXTRA_ATTRS),
|
|
2812
2853
|
captureTextContent: this.getConfig(CONFIG_CAPTURE_TEXT_CONTENT),
|
|
2813
|
-
capturedForHeatMap:
|
|
2854
|
+
capturedForHeatMap: isCapturedForHeatMap,
|
|
2814
2855
|
});
|
|
2815
2856
|
if (props) {
|
|
2816
2857
|
_.extend(props, DEFAULT_PROPS);
|
|
@@ -2818,6 +2859,24 @@
|
|
|
2818
2859
|
}
|
|
2819
2860
|
};
|
|
2820
2861
|
|
|
2862
|
+
Autocapture.prototype._getRageClickConfig = function() {
|
|
2863
|
+
var config = this.getConfig(CONFIG_TRACK_RAGE_CLICK);
|
|
2864
|
+
|
|
2865
|
+
if (!config) {
|
|
2866
|
+
return null; // rage click tracking disabled
|
|
2867
|
+
}
|
|
2868
|
+
|
|
2869
|
+
if (config === true) {
|
|
2870
|
+
return {}; // use defaults
|
|
2871
|
+
}
|
|
2872
|
+
|
|
2873
|
+
if (typeof config === 'object') {
|
|
2874
|
+
return config; // use custom configuration
|
|
2875
|
+
}
|
|
2876
|
+
|
|
2877
|
+
return {}; // fallback to defaults for any other truthy value
|
|
2878
|
+
};
|
|
2879
|
+
|
|
2821
2880
|
Autocapture.prototype.initClickTracking = function() {
|
|
2822
2881
|
win.removeEventListener(EV_CLICK, this.listenerClick);
|
|
2823
2882
|
|
|
@@ -2919,6 +2978,36 @@
|
|
|
2919
2978
|
}.bind(this)));
|
|
2920
2979
|
};
|
|
2921
2980
|
|
|
2981
|
+
Autocapture.prototype.initRageClickTracking = function() {
|
|
2982
|
+
win.removeEventListener(EV_CLICK, this.listenerRageClick);
|
|
2983
|
+
|
|
2984
|
+
var rageClickConfig = this._getRageClickConfig();
|
|
2985
|
+
if (!rageClickConfig && !this.mp.get_config('record_heatmap_data')) {
|
|
2986
|
+
return;
|
|
2987
|
+
}
|
|
2988
|
+
|
|
2989
|
+
logger$4.log('Initializing rage click tracking');
|
|
2990
|
+
if (!this._rageClickTracker) {
|
|
2991
|
+
this._rageClickTracker = new RageClickTracker();
|
|
2992
|
+
}
|
|
2993
|
+
|
|
2994
|
+
this.listenerRageClick = function(ev) {
|
|
2995
|
+
var currentRageClickConfig = this._getRageClickConfig();
|
|
2996
|
+
if (!currentRageClickConfig && !this.mp.is_recording_heatmap_data()) {
|
|
2997
|
+
return;
|
|
2998
|
+
}
|
|
2999
|
+
|
|
3000
|
+
if (this.currentUrlBlocked()) {
|
|
3001
|
+
return;
|
|
3002
|
+
}
|
|
3003
|
+
|
|
3004
|
+
if (this._rageClickTracker.isRageClick(ev['pageX'], ev['pageY'], currentRageClickConfig)) {
|
|
3005
|
+
this.trackDomEvent(ev, MP_EV_RAGE_CLICK);
|
|
3006
|
+
}
|
|
3007
|
+
}.bind(this);
|
|
3008
|
+
win.addEventListener(EV_CLICK, this.listenerRageClick);
|
|
3009
|
+
};
|
|
3010
|
+
|
|
2922
3011
|
Autocapture.prototype.initScrollTracking = function() {
|
|
2923
3012
|
win.removeEventListener(EV_SCROLLEND, this.listenerScroll);
|
|
2924
3013
|
|
|
@@ -3005,6 +3094,7 @@
|
|
|
3005
3094
|
var FeatureFlagManager = function(initOptions) {
|
|
3006
3095
|
this.getFullApiRoute = initOptions.getFullApiRoute;
|
|
3007
3096
|
this.getMpConfig = initOptions.getConfigFunc;
|
|
3097
|
+
this.setMpConfig = initOptions.setConfigFunc;
|
|
3008
3098
|
this.getMpProperty = initOptions.getPropertyFunc;
|
|
3009
3099
|
this.track = initOptions.trackingFunc;
|
|
3010
3100
|
};
|
|
@@ -3042,6 +3132,23 @@
|
|
|
3042
3132
|
return !!this.getMpConfig(FLAGS_CONFIG_KEY);
|
|
3043
3133
|
};
|
|
3044
3134
|
|
|
3135
|
+
FeatureFlagManager.prototype.updateContext = function(newContext, options) {
|
|
3136
|
+
if (!this.isSystemEnabled()) {
|
|
3137
|
+
logger$3.critical('Feature Flags not enabled, cannot update context');
|
|
3138
|
+
return Promise.resolve();
|
|
3139
|
+
}
|
|
3140
|
+
|
|
3141
|
+
var ffConfig = this.getMpConfig(FLAGS_CONFIG_KEY);
|
|
3142
|
+
if (!_.isObject(ffConfig)) {
|
|
3143
|
+
ffConfig = {};
|
|
3144
|
+
}
|
|
3145
|
+
var oldContext = (options && options['replace']) ? {} : this.getConfig(CONFIG_CONTEXT);
|
|
3146
|
+
ffConfig[CONFIG_CONTEXT] = _.extend({}, oldContext, newContext);
|
|
3147
|
+
|
|
3148
|
+
this.setMpConfig(FLAGS_CONFIG_KEY, ffConfig);
|
|
3149
|
+
return this.fetchFlags();
|
|
3150
|
+
};
|
|
3151
|
+
|
|
3045
3152
|
FeatureFlagManager.prototype.areFlagsReady = function() {
|
|
3046
3153
|
if (!this.isSystemEnabled()) {
|
|
3047
3154
|
logger$3.error('Feature Flags not enabled');
|
|
@@ -3051,7 +3158,7 @@
|
|
|
3051
3158
|
|
|
3052
3159
|
FeatureFlagManager.prototype.fetchFlags = function() {
|
|
3053
3160
|
if (!this.isSystemEnabled()) {
|
|
3054
|
-
return;
|
|
3161
|
+
return Promise.resolve();
|
|
3055
3162
|
}
|
|
3056
3163
|
|
|
3057
3164
|
var distinctId = this.getMpProperty('distinct_id');
|
|
@@ -3091,6 +3198,8 @@
|
|
|
3091
3198
|
this.markFetchComplete();
|
|
3092
3199
|
logger$3.error(error);
|
|
3093
3200
|
}.bind(this));
|
|
3201
|
+
|
|
3202
|
+
return this.fetchPromise;
|
|
3094
3203
|
};
|
|
3095
3204
|
|
|
3096
3205
|
FeatureFlagManager.prototype.markFetchComplete = function() {
|
|
@@ -3203,6 +3312,7 @@
|
|
|
3203
3312
|
FeatureFlagManager.prototype['get_variant_value_sync'] = FeatureFlagManager.prototype.getVariantValueSync;
|
|
3204
3313
|
FeatureFlagManager.prototype['is_enabled'] = FeatureFlagManager.prototype.isEnabled;
|
|
3205
3314
|
FeatureFlagManager.prototype['is_enabled_sync'] = FeatureFlagManager.prototype.isEnabledSync;
|
|
3315
|
+
FeatureFlagManager.prototype['update_context'] = FeatureFlagManager.prototype.updateContext;
|
|
3206
3316
|
|
|
3207
3317
|
// Deprecated method
|
|
3208
3318
|
FeatureFlagManager.prototype['get_feature_data'] = FeatureFlagManager.prototype.getFeatureData;
|
|
@@ -3520,6 +3630,10 @@
|
|
|
3520
3630
|
return PromisePolyfill.resolve();
|
|
3521
3631
|
};
|
|
3522
3632
|
|
|
3633
|
+
LocalStorageWrapper.prototype.isInitialized = function () {
|
|
3634
|
+
return true;
|
|
3635
|
+
};
|
|
3636
|
+
|
|
3523
3637
|
LocalStorageWrapper.prototype.setItem = function (key, value) {
|
|
3524
3638
|
return new PromisePolyfill(_.bind(function (resolve, reject) {
|
|
3525
3639
|
try {
|
|
@@ -3600,7 +3714,7 @@
|
|
|
3600
3714
|
};
|
|
3601
3715
|
|
|
3602
3716
|
RequestQueue.prototype.ensureInit = function () {
|
|
3603
|
-
if (this.initialized) {
|
|
3717
|
+
if (this.initialized || !this.usePersistence) {
|
|
3604
3718
|
return PromisePolyfill.resolve();
|
|
3605
3719
|
}
|
|
3606
3720
|
|
|
@@ -5784,6 +5898,10 @@
|
|
|
5784
5898
|
});
|
|
5785
5899
|
};
|
|
5786
5900
|
|
|
5901
|
+
IDBStorageWrapper.prototype.isInitialized = function () {
|
|
5902
|
+
return !!this.dbPromise;
|
|
5903
|
+
};
|
|
5904
|
+
|
|
5787
5905
|
/**
|
|
5788
5906
|
* @param {IDBTransactionMode} mode
|
|
5789
5907
|
* @param {function(IDBObjectStore): void} storeCb
|
|
@@ -5974,7 +6092,7 @@
|
|
|
5974
6092
|
'batch_autostart': true,
|
|
5975
6093
|
'hooks': {},
|
|
5976
6094
|
'record_block_class': new RegExp('^(mp-block|fs-exclude|amp-block|rr-block|ph-no-capture)$'),
|
|
5977
|
-
'record_block_selector': 'img, video',
|
|
6095
|
+
'record_block_selector': 'img, video, audio',
|
|
5978
6096
|
'record_canvas': false,
|
|
5979
6097
|
'record_collect_fonts': false,
|
|
5980
6098
|
'record_heatmap_data': false,
|
|
@@ -6198,6 +6316,7 @@
|
|
|
6198
6316
|
return this.get_api_host('flags') + '/' + this.get_config('api_routes')['flags'];
|
|
6199
6317
|
}, this),
|
|
6200
6318
|
getConfigFunc: _.bind(this.get_config, this),
|
|
6319
|
+
setConfigFunc: _.bind(this.set_config, this),
|
|
6201
6320
|
getPropertyFunc: _.bind(this.get_property, this),
|
|
6202
6321
|
trackingFunc: _.bind(this.track, this)
|
|
6203
6322
|
});
|
|
@@ -6216,7 +6335,9 @@
|
|
|
6216
6335
|
* This is primarily used for session recording, where data must be isolated to the current tab.
|
|
6217
6336
|
*/
|
|
6218
6337
|
MixpanelLib.prototype._init_tab_id = function() {
|
|
6219
|
-
if (
|
|
6338
|
+
if (this.get_config('disable_persistence')) {
|
|
6339
|
+
console.log('Tab ID initialization skipped due to disable_persistence config');
|
|
6340
|
+
} else if (_.sessionStorage.is_supported()) {
|
|
6220
6341
|
try {
|
|
6221
6342
|
var key_suffix = this.get_config('name') + '_' + this.get_config('token');
|
|
6222
6343
|
var tab_id_key = 'mp_tab_id_' + key_suffix;
|
|
@@ -6250,6 +6371,11 @@
|
|
|
6250
6371
|
};
|
|
6251
6372
|
|
|
6252
6373
|
MixpanelLib.prototype._should_load_recorder = function () {
|
|
6374
|
+
if (this.get_config('disable_persistence')) {
|
|
6375
|
+
console.log('Load recorder check skipped due to disable_persistence config');
|
|
6376
|
+
return Promise.resolve(false);
|
|
6377
|
+
}
|
|
6378
|
+
|
|
6253
6379
|
var recording_registry_idb = new IDBStorageWrapper(RECORDING_REGISTRY_STORE_NAME);
|
|
6254
6380
|
var tab_id = this.get_tab_id();
|
|
6255
6381
|
return recording_registry_idb.init()
|