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/.github/workflows/tests.yml +25 -0
- package/CHANGELOG.md +18 -0
- package/README.md +4 -2
- package/dist/mixpanel-jslib-snippet.min.js +3 -3
- package/dist/mixpanel-jslib-snippet.min.test.js +3 -3
- package/dist/mixpanel.amd.js +975 -2843
- package/dist/mixpanel.cjs.js +975 -2843
- package/dist/mixpanel.globals.js +975 -2843
- package/dist/mixpanel.min.js +100 -149
- package/dist/mixpanel.umd.js +975 -2843
- package/doc/build-docs.js +16 -0
- package/doc/readme.io/javascript-full-api-reference.md +18 -0
- package/mixpanel-jslib-snippet.js +2 -2
- package/package.json +3 -3
- package/src/config.js +1 -1
- package/src/mixpanel-core.js +76 -129
- package/src/mixpanel-group.js +4 -0
- package/src/mixpanel-persistence.js +0 -21
- package/src/request-batcher.js +47 -10
- package/src/request-queue.js +55 -18
- package/src/utils.js +2 -71
- package/tunnel.log +0 -0
- package/.travis.yml +0 -6
- package/src/mixpanel-notification.js +0 -1309
- package/src/property-filters.js +0 -508
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.
|
|
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.
|
|
49
|
+
"lodash": "4.17.21",
|
|
50
50
|
"mocha": "7.1.1",
|
|
51
51
|
"morgan": "1.9.1",
|
|
52
|
-
"rdme": "
|
|
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
package/src/mixpanel-core.js
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
/* eslint camelcase: "off" */
|
|
2
2
|
import Config from './config';
|
|
3
|
-
import { _, console, userAgent, window, document, navigator,
|
|
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':
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
244
|
-
|
|
245
|
-
if (!('
|
|
246
|
-
|
|
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
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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() {
|
package/src/mixpanel-group.js
CHANGED
|
@@ -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
|
};
|