mixpanel-browser 2.72.0 → 2.73.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.
@@ -2,7 +2,7 @@ export type Persistence = "cookie" | "localStorage";
2
2
 
3
3
  export type ApiPayloadFormat = "base64" | "json";
4
4
 
5
- export type PushItem = Array<string | Dict>;
5
+ export type PushItem = Array<string | Dict | ((this: Mixpanel) => void)>;
6
6
 
7
7
  export type Query = string | Element | Element[];
8
8
 
@@ -155,6 +155,11 @@ export interface FlagsConfig {
155
155
  context: Dict;
156
156
  }
157
157
 
158
+ export interface BeforeSendHookPayload {
159
+ event: string;
160
+ properties: Record<string, any>;
161
+ }
162
+
158
163
  export interface Config {
159
164
  api_host: string;
160
165
  api_routes: {
@@ -167,10 +172,13 @@ export interface Config {
167
172
  app_host: string;
168
173
  api_payload_format: ApiPayloadFormat;
169
174
  autotrack: boolean;
175
+ batch_autostart: boolean;
176
+ batch_requests: boolean;
170
177
  cdn: string;
171
178
  cookie_domain: string;
172
179
  cross_site_cookie: boolean;
173
180
  cross_subdomain_cookie: boolean;
181
+ error_reporter: (msg: string, err?: Error) => void;
174
182
  flags: boolean | FlagsConfig;
175
183
  persistence: Persistence;
176
184
  persistence_name: string;
@@ -207,10 +215,10 @@ export interface Config {
207
215
  inapp_protocol: string;
208
216
  inapp_link_new_window: boolean;
209
217
  ignore_dnt: boolean;
210
- batch_requests: boolean;
211
218
  batch_size: number;
212
219
  batch_flush_interval_ms: number;
213
220
  batch_request_timeout_ms: number;
221
+ recorder_src: string;
214
222
  record_block_class: string | RegExp;
215
223
  record_block_selector: string;
216
224
  record_collect_fonts: boolean;
@@ -223,6 +231,29 @@ export interface Config {
223
231
  record_sessions_percent: number;
224
232
  record_canvas: boolean;
225
233
  record_heatmap_data: boolean;
234
+ hooks: {
235
+ before_identify?: (new_distinct_id: string) => string | null;
236
+ before_register?: (
237
+ props: Dict,
238
+ days_or_options?: number | Partial<RegisterOptions>
239
+ ) => Dict | Array<Dict | number | Partial<RegisterOptions>> | null;
240
+ before_register_once?: (
241
+ props: Dict,
242
+ default_value?: any,
243
+ days_or_options?: number | Partial<RegisterOptions>
244
+ ) => Dict | Array<any | Dict | number | Partial<RegisterOptions>> | null;
245
+ before_send_events?: (
246
+ event: BeforeSendHookPayload
247
+ ) => BeforeSendHookPayload | null;
248
+ before_track?: (
249
+ event_name: string,
250
+ properties: Dict
251
+ ) => string | Array<string | Dict> | null;
252
+ before_unregister?: (
253
+ property: string,
254
+ options?: Partial<RegisterOptions>
255
+ ) => string | Partial<RegisterOptions> | null;
256
+ };
226
257
  }
227
258
 
228
259
  export type VerboseResponse =
@@ -323,10 +354,11 @@ export interface Mixpanel {
323
354
  get_distinct_id(): any;
324
355
  get_group(group_key: string, group_id: string): Group;
325
356
  get_property(property_name: string): any;
357
+ get_session_replay_url(): string;
326
358
  has_opted_in_tracking(options?: Partial<HasOptedInOutOptions>): boolean;
327
359
  has_opted_out_tracking(options?: Partial<HasOptedInOutOptions>): boolean;
328
360
  identify(unique_id?: string): any;
329
- init(token: string, config: Partial<Config>, name: string): Mixpanel;
361
+ init(token: string, config: Partial<Config>, name?: string): Mixpanel;
330
362
  opt_in_tracking(options?: Partial<InTrackingOptions>): void;
331
363
  opt_out_tracking(options?: Partial<OutTrackingOptions>): void;
332
364
  push(item: PushItem): void;
@@ -351,6 +383,7 @@ export interface Mixpanel {
351
383
  group_ids: string | string[] | number | number[],
352
384
  callback?: Callback
353
385
  ): void;
386
+ start_batch_senders(): void;
354
387
  time_event(event_name: string): void;
355
388
  track(
356
389
  event_name: string,
@@ -380,6 +413,7 @@ export interface Mixpanel {
380
413
  ): void;
381
414
  unregister(property: string, options?: Partial<RegisterOptions>): void;
382
415
  people: People;
416
+ start_batch_senders(): void;
383
417
  start_session_recording(): void;
384
418
  stop_session_recording(): void;
385
419
  get_session_recording_properties(): { $mp_replay_id?: string } | {};
@@ -2,7 +2,7 @@
2
2
 
3
3
  var Config = {
4
4
  DEBUG: false,
5
- LIB_VERSION: '2.72.0'
5
+ LIB_VERSION: '2.73.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
@@ -22,7 +22,9 @@ if (typeof(window) === 'undefined') {
22
22
  screen: { width: 0, height: 0 },
23
23
  location: loc,
24
24
  addEventListener: function() {},
25
- removeEventListener: function() {}
25
+ removeEventListener: function() {},
26
+ dispatchEvent: function() {},
27
+ CustomEvent: function () {}
26
28
  };
27
29
  } else {
28
30
  win = window;
@@ -6835,8 +6837,6 @@ var mixpanel_master; // main mixpanel instance / object
6835
6837
  var INIT_MODULE = 0;
6836
6838
  var INIT_SNIPPET = 1;
6837
6839
 
6838
- var IDENTITY_FUNC = function(x) {return x;};
6839
-
6840
6840
  /** @const */ var PRIMARY_INSTANCE_NAME = 'mixpanel';
6841
6841
  /** @const */ var PAYLOAD_TYPE_BASE64 = 'base64';
6842
6842
  /** @const */ var PAYLOAD_TYPE_JSON = 'json';
@@ -7002,6 +7002,17 @@ var create_mplib = function(token, config, name) {
7002
7002
  // global debug to be true
7003
7003
  Config.DEBUG = Config.DEBUG || instance.get_config('debug');
7004
7004
 
7005
+ var source = init_type === INIT_MODULE ? 'module' : 'snippet';
7006
+ win.dispatchEvent(new win.CustomEvent('$mp_sdk_to_extension_event', {
7007
+ 'detail': {
7008
+ 'instance': instance,
7009
+ 'source': source,
7010
+ 'token': token,
7011
+ 'name': name,
7012
+ 'info': _.info
7013
+ }
7014
+ }));
7015
+
7005
7016
  // if target is not defined, we called init after the lib already
7006
7017
  // loaded, so there won't be an array of things to execute
7007
7018
  if (!_.isUndefined(target) && _.isArray(target)) {
@@ -7072,6 +7083,8 @@ MixpanelLib.prototype._init = function(token, config, name) {
7072
7083
  }
7073
7084
  }
7074
7085
 
7086
+ this.hooks = {};
7087
+
7075
7088
  this.set_config(_.extend({}, DEFAULT_CONFIG, variable_features, config, {
7076
7089
  'name': name,
7077
7090
  'token': token,
@@ -7672,7 +7685,12 @@ MixpanelLib.prototype.init_batchers = function() {
7672
7685
  );
7673
7686
  }, this),
7674
7687
  beforeSendHook: _.bind(function(item) {
7675
- return this._run_hook('before_send_' + attrs.type, item);
7688
+ var ret = this._run_hook('before_send_' + attrs.type, item);
7689
+ if (ret) {
7690
+ return ret[0];
7691
+ } else {
7692
+ return null;
7693
+ }
7676
7694
  }, this),
7677
7695
  stopAllBatchingFunc: _.bind(this.stop_batch_senders, this),
7678
7696
  usePersistence: true,
@@ -7765,6 +7783,9 @@ MixpanelLib.prototype._track_or_batch = function(options, callback) {
7765
7783
  var send_request_immediately = _.bind(function() {
7766
7784
  if (!send_request_options.skip_hooks) {
7767
7785
  truncated_data = this._run_hook('before_send_' + options.type, truncated_data);
7786
+ if (truncated_data) {
7787
+ truncated_data = truncated_data[0];
7788
+ }
7768
7789
  }
7769
7790
  if (truncated_data) {
7770
7791
  console.log('MIXPANEL REQUEST:');
@@ -7819,6 +7840,17 @@ MixpanelLib.prototype._track_or_batch = function(options, callback) {
7819
7840
  * with the tracking payload sent to the API server is returned; otherwise false.
7820
7841
  */
7821
7842
  MixpanelLib.prototype.track = addOptOutCheckMixpanelLib(function(event_name, properties, options, callback) {
7843
+ var ret;
7844
+ if (!(options && options.skip_hooks)) {
7845
+ ret = this._run_hook('before_track', event_name, properties);
7846
+ if (ret === null) {
7847
+ return;
7848
+ } else {
7849
+ event_name = ret[0];
7850
+ properties = ret[1];
7851
+ }
7852
+ }
7853
+
7822
7854
  if (!callback && typeof options === 'function') {
7823
7855
  callback = options;
7824
7856
  options = null;
@@ -7888,7 +7920,7 @@ MixpanelLib.prototype.track = addOptOutCheckMixpanelLib(function(event_name, pro
7888
7920
  'event': event_name,
7889
7921
  'properties': properties
7890
7922
  };
7891
- var ret = this._track_or_batch({
7923
+ ret = this._track_or_batch({
7892
7924
  type: 'events',
7893
7925
  data: data,
7894
7926
  endpoint: this.get_api_host('events') + '/' + this.get_config('api_routes')['track'],
@@ -8234,6 +8266,14 @@ var options_for_register = function(days_or_options) {
8234
8266
  * @param {boolean} [days_or_options.persistent=true] - whether to put in persistent storage (cookie/localStorage)
8235
8267
  */
8236
8268
  MixpanelLib.prototype.register = function(props, days_or_options) {
8269
+ var ret = this._run_hook('before_register', props, days_or_options);
8270
+ if (ret === null) {
8271
+ return;
8272
+ } else {
8273
+ props = ret[0];
8274
+ days_or_options = ret[1];
8275
+ }
8276
+
8237
8277
  var options = options_for_register(days_or_options);
8238
8278
  if (options['persistent']) {
8239
8279
  this['persistence'].register(props, options['days']);
@@ -8270,6 +8310,15 @@ MixpanelLib.prototype.register = function(props, days_or_options) {
8270
8310
  * @param {boolean} [days_or_options.persistent=true] - whether to put in persistent storage (cookie/localStorage)
8271
8311
  */
8272
8312
  MixpanelLib.prototype.register_once = function(props, default_value, days_or_options) {
8313
+ var ret = this._run_hook('before_register_once', props, default_value, days_or_options);
8314
+ if (ret === null) {
8315
+ return;
8316
+ } else {
8317
+ props = ret[0];
8318
+ default_value = ret[1];
8319
+ days_or_options = ret[2];
8320
+ }
8321
+
8273
8322
  var options = options_for_register(days_or_options);
8274
8323
  if (options['persistent']) {
8275
8324
  this['persistence'].register_once(props, default_value, options['days']);
@@ -8293,6 +8342,14 @@ MixpanelLib.prototype.register_once = function(props, default_value, days_or_opt
8293
8342
  * @param {boolean} [options.persistent=true] - whether to look in persistent storage (cookie/localStorage)
8294
8343
  */
8295
8344
  MixpanelLib.prototype.unregister = function(property, options) {
8345
+ var ret = this._run_hook('before_unregister', property, options);
8346
+ if (ret === null) {
8347
+ return;
8348
+ } else {
8349
+ property = ret[0];
8350
+ options = ret[1];
8351
+ }
8352
+
8296
8353
  options = options_for_register(options);
8297
8354
  if (options['persistent']) {
8298
8355
  this['persistence'].unregister(property);
@@ -8341,6 +8398,13 @@ MixpanelLib.prototype.identify = function(
8341
8398
  // _set_once_callback:function A callback to be run if and when the People set_once queue is flushed
8342
8399
  // _union_callback:function A callback to be run if and when the People union queue is flushed
8343
8400
  // _unset_callback:function A callback to be run if and when the People unset queue is flushed
8401
+ var ret = this._run_hook('before_identify', new_distinct_id);
8402
+
8403
+ if (ret === null) {
8404
+ return -1;
8405
+ } else {
8406
+ new_distinct_id = ret[0];
8407
+ }
8344
8408
 
8345
8409
  var previous_distinct_id = this.get_distinct_id();
8346
8410
  if (new_distinct_id && previous_distinct_id !== new_distinct_id) {
@@ -8665,6 +8729,25 @@ MixpanelLib.prototype.set_config = function(config) {
8665
8729
  if (('autocapture' in config || 'record_heatmap_data' in config) && this.autocapture) {
8666
8730
  this.autocapture.init();
8667
8731
  }
8732
+
8733
+ if (_.isObject(config['hooks'])) {
8734
+ this.hooks = {};
8735
+ _.each(config['hooks'], function(hook_value, hook_name) {
8736
+ if (_.isFunction(hook_value)) {
8737
+ this.hooks[hook_name] = [hook_value];
8738
+ } else if (_.isArray(hook_value)) {
8739
+ this.hooks[hook_name] = [];
8740
+ for (var i = 0; i < hook_value.length; i++) {
8741
+ if (!_.isFunction(hook_value[i])) {
8742
+ console.critical('Invalid hook added. Hook is not a function');
8743
+ }
8744
+ this.hooks[hook_name].push(hook_value[i]);
8745
+ }
8746
+ } else {
8747
+ console.critical('Invalid hooks added. Ensure that the hook values passed into config.hooks are functions or arrays of functions.');
8748
+ }
8749
+ }, this);
8750
+ }
8668
8751
  }
8669
8752
  };
8670
8753
 
@@ -8682,12 +8765,26 @@ MixpanelLib.prototype.get_config = function(prop_name) {
8682
8765
  * @returns {any|null} return value of user-provided hook, or null if nothing was returned
8683
8766
  */
8684
8767
  MixpanelLib.prototype._run_hook = function(hook_name) {
8685
- var ret = (this['config']['hooks'][hook_name] || IDENTITY_FUNC).apply(this, slice.call(arguments, 1));
8686
- if (typeof ret === 'undefined') {
8687
- this.report_error(hook_name + ' hook did not return a value');
8688
- ret = null;
8689
- }
8690
- return ret;
8768
+ var hook_data = slice.call(arguments, 1);
8769
+ _.each(this.hooks[hook_name], function(hook) {
8770
+ if (hook_data === null) {
8771
+ return null;
8772
+ }
8773
+
8774
+ var ret = hook.apply(this, hook_data);
8775
+
8776
+ if (typeof ret === 'undefined') {
8777
+ this.report_error(hook_name + ' hook did not return a valid value');
8778
+ hook_data = null;
8779
+ } else {
8780
+ if (!_.isArray(ret)) {
8781
+ ret = [ret];
8782
+ }
8783
+ hook_data.splice.apply(hook_data, [0, ret.length].concat(ret));
8784
+ }
8785
+ }, this);
8786
+
8787
+ return hook_data;
8691
8788
  };
8692
8789
 
8693
8790
  /**
@@ -8998,6 +9095,25 @@ MixpanelLib.prototype.report_error = function(msg, err) {
8998
9095
  }
8999
9096
  };
9000
9097
 
9098
+ MixpanelLib.prototype.add_hook = function(hook_name, hook_fn) {
9099
+ if (!this.hooks[hook_name]) {
9100
+ this.hooks[hook_name] = [];
9101
+ }
9102
+ this.hooks[hook_name].push(hook_fn);
9103
+ };
9104
+
9105
+ MixpanelLib.prototype.remove_hook = function(hook_name, hook_fn) {
9106
+ var fn_index;
9107
+ if (this.hooks[hook_name]) {
9108
+ fn_index = this.hooks[hook_name].indexOf(hook_fn);
9109
+ if (fn_index !== -1) {
9110
+ this.hooks[hook_name].splice(fn_index, 1);
9111
+ } else {
9112
+ console.log('remove_hook failed. Matching hook was not found');
9113
+ }
9114
+ }
9115
+ };
9116
+
9001
9117
  // EXPORTS (for closure compiler)
9002
9118
 
9003
9119
  // MixpanelLib Exports
@@ -9030,6 +9146,8 @@ MixpanelLib.prototype['get_group'] = MixpanelLib.protot
9030
9146
  MixpanelLib.prototype['set_group'] = MixpanelLib.prototype.set_group;
9031
9147
  MixpanelLib.prototype['add_group'] = MixpanelLib.prototype.add_group;
9032
9148
  MixpanelLib.prototype['remove_group'] = MixpanelLib.prototype.remove_group;
9149
+ MixpanelLib.prototype['add_hook'] = MixpanelLib.prototype.add_hook;
9150
+ MixpanelLib.prototype['remove_hook'] = MixpanelLib.prototype.remove_hook;
9033
9151
  MixpanelLib.prototype['track_with_groups'] = MixpanelLib.prototype.track_with_groups;
9034
9152
  MixpanelLib.prototype['start_batch_senders'] = MixpanelLib.prototype.start_batch_senders;
9035
9153
  MixpanelLib.prototype['stop_batch_senders'] = MixpanelLib.prototype.stop_batch_senders;
@@ -2,7 +2,7 @@ export type Persistence = "cookie" | "localStorage";
2
2
 
3
3
  export type ApiPayloadFormat = "base64" | "json";
4
4
 
5
- export type PushItem = Array<string | Dict>;
5
+ export type PushItem = Array<string | Dict | ((this: Mixpanel) => void)>;
6
6
 
7
7
  export type Query = string | Element | Element[];
8
8
 
@@ -155,6 +155,11 @@ export interface FlagsConfig {
155
155
  context: Dict;
156
156
  }
157
157
 
158
+ export interface BeforeSendHookPayload {
159
+ event: string;
160
+ properties: Record<string, any>;
161
+ }
162
+
158
163
  export interface Config {
159
164
  api_host: string;
160
165
  api_routes: {
@@ -167,10 +172,13 @@ export interface Config {
167
172
  app_host: string;
168
173
  api_payload_format: ApiPayloadFormat;
169
174
  autotrack: boolean;
175
+ batch_autostart: boolean;
176
+ batch_requests: boolean;
170
177
  cdn: string;
171
178
  cookie_domain: string;
172
179
  cross_site_cookie: boolean;
173
180
  cross_subdomain_cookie: boolean;
181
+ error_reporter: (msg: string, err?: Error) => void;
174
182
  flags: boolean | FlagsConfig;
175
183
  persistence: Persistence;
176
184
  persistence_name: string;
@@ -207,10 +215,10 @@ export interface Config {
207
215
  inapp_protocol: string;
208
216
  inapp_link_new_window: boolean;
209
217
  ignore_dnt: boolean;
210
- batch_requests: boolean;
211
218
  batch_size: number;
212
219
  batch_flush_interval_ms: number;
213
220
  batch_request_timeout_ms: number;
221
+ recorder_src: string;
214
222
  record_block_class: string | RegExp;
215
223
  record_block_selector: string;
216
224
  record_collect_fonts: boolean;
@@ -223,6 +231,29 @@ export interface Config {
223
231
  record_sessions_percent: number;
224
232
  record_canvas: boolean;
225
233
  record_heatmap_data: boolean;
234
+ hooks: {
235
+ before_identify?: (new_distinct_id: string) => string | null;
236
+ before_register?: (
237
+ props: Dict,
238
+ days_or_options?: number | Partial<RegisterOptions>
239
+ ) => Dict | Array<Dict | number | Partial<RegisterOptions>> | null;
240
+ before_register_once?: (
241
+ props: Dict,
242
+ default_value?: any,
243
+ days_or_options?: number | Partial<RegisterOptions>
244
+ ) => Dict | Array<any | Dict | number | Partial<RegisterOptions>> | null;
245
+ before_send_events?: (
246
+ event: BeforeSendHookPayload
247
+ ) => BeforeSendHookPayload | null;
248
+ before_track?: (
249
+ event_name: string,
250
+ properties: Dict
251
+ ) => string | Array<string | Dict> | null;
252
+ before_unregister?: (
253
+ property: string,
254
+ options?: Partial<RegisterOptions>
255
+ ) => string | Partial<RegisterOptions> | null;
256
+ };
226
257
  }
227
258
 
228
259
  export type VerboseResponse =
@@ -323,10 +354,11 @@ export interface Mixpanel {
323
354
  get_distinct_id(): any;
324
355
  get_group(group_key: string, group_id: string): Group;
325
356
  get_property(property_name: string): any;
357
+ get_session_replay_url(): string;
326
358
  has_opted_in_tracking(options?: Partial<HasOptedInOutOptions>): boolean;
327
359
  has_opted_out_tracking(options?: Partial<HasOptedInOutOptions>): boolean;
328
360
  identify(unique_id?: string): any;
329
- init(token: string, config: Partial<Config>, name: string): Mixpanel;
361
+ init(token: string, config: Partial<Config>, name?: string): Mixpanel;
330
362
  opt_in_tracking(options?: Partial<InTrackingOptions>): void;
331
363
  opt_out_tracking(options?: Partial<OutTrackingOptions>): void;
332
364
  push(item: PushItem): void;
@@ -351,6 +383,7 @@ export interface Mixpanel {
351
383
  group_ids: string | string[] | number | number[],
352
384
  callback?: Callback
353
385
  ): void;
386
+ start_batch_senders(): void;
354
387
  time_event(event_name: string): void;
355
388
  track(
356
389
  event_name: string,
@@ -380,6 +413,7 @@ export interface Mixpanel {
380
413
  ): void;
381
414
  unregister(property: string, options?: Partial<RegisterOptions>): void;
382
415
  people: People;
416
+ start_batch_senders(): void;
383
417
  start_session_recording(): void;
384
418
  stop_session_recording(): void;
385
419
  get_session_recording_properties(): { $mp_replay_id?: string } | {};