mixpanel-browser 2.78.0 → 2.79.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/.claude/settings.local.json +6 -11
- package/.eslintrc.json +12 -0
- package/.github/workflows/openfeature-provider-tests.yml +31 -0
- package/CHANGELOG.md +8 -1
- package/build.sh +2 -2
- package/dist/async-modules/{mixpanel-recorder-BjSlYaNJ.min.js → mixpanel-recorder-D5HJyV2E.min.js} +2 -2
- package/dist/async-modules/mixpanel-recorder-D5HJyV2E.min.js.map +1 -0
- package/dist/async-modules/{mixpanel-recorder-zMBXIyeG.js → mixpanel-recorder-P6SEnnPV.js} +57 -33
- package/dist/async-modules/mixpanel-targeting-1L9FyetZ.min.js +2 -0
- package/dist/async-modules/mixpanel-targeting-1L9FyetZ.min.js.map +1 -0
- package/dist/async-modules/{mixpanel-targeting-UHf4eBfC.js → mixpanel-targeting-BBMVbgJF.js} +24 -13
- package/dist/mixpanel-core.cjs.d.ts +45 -1
- package/dist/mixpanel-core.cjs.js +565 -197
- package/dist/mixpanel-recorder.js +57 -33
- package/dist/mixpanel-recorder.min.js +1 -1
- package/dist/mixpanel-recorder.min.js.map +1 -1
- package/dist/mixpanel-targeting.js +24 -13
- package/dist/mixpanel-targeting.min.js +1 -1
- package/dist/mixpanel-targeting.min.js.map +1 -1
- package/dist/mixpanel-with-async-modules.cjs.d.ts +45 -1
- package/dist/mixpanel-with-async-modules.cjs.js +567 -199
- package/dist/mixpanel-with-async-recorder.cjs.d.ts +45 -1
- package/dist/mixpanel-with-async-recorder.cjs.js +567 -199
- package/dist/mixpanel-with-recorder.d.ts +45 -1
- package/dist/mixpanel-with-recorder.js +490 -122
- package/dist/mixpanel-with-recorder.min.d.ts +45 -1
- package/dist/mixpanel-with-recorder.min.js +1 -1
- package/dist/mixpanel.amd.d.ts +45 -1
- package/dist/mixpanel.amd.js +490 -122
- package/dist/mixpanel.cjs.d.ts +45 -1
- package/dist/mixpanel.cjs.js +490 -122
- package/dist/mixpanel.globals.js +567 -199
- package/dist/mixpanel.min.js +199 -189
- package/dist/mixpanel.module.d.ts +45 -1
- package/dist/mixpanel.module.js +490 -122
- package/dist/mixpanel.umd.d.ts +45 -1
- package/dist/mixpanel.umd.js +490 -122
- package/package.json +1 -1
- package/packages/openfeature-web-provider/README.md +357 -0
- package/packages/openfeature-web-provider/package-lock.json +1636 -0
- package/packages/openfeature-web-provider/package.json +51 -0
- package/packages/openfeature-web-provider/rollup.config.browser.mjs +26 -0
- package/packages/openfeature-web-provider/src/MixpanelProvider.ts +302 -0
- package/packages/openfeature-web-provider/src/index.ts +1 -0
- package/packages/openfeature-web-provider/src/types.ts +72 -0
- package/packages/openfeature-web-provider/test/MixpanelProvider.spec.ts +484 -0
- package/packages/openfeature-web-provider/tsconfig.json +15 -0
- package/src/autocapture/index.js +7 -2
- package/src/config.js +1 -1
- package/src/flags/flags-persistence.js +176 -0
- package/src/flags/index.js +174 -23
- package/src/index.d.ts +45 -1
- package/src/mixpanel-core.js +24 -7
- package/src/recorder/idb-config.js +16 -0
- package/src/recorder/recording-registry.js +7 -2
- package/src/recorder/session-recording.js +9 -4
- package/src/recorder-manager.js +7 -2
- package/src/request-queue.js +1 -2
- package/src/shared-lock.js +2 -3
- package/src/storage/indexed-db.js +16 -15
- package/src/storage/local-storage.js +5 -3
- package/src/utils.js +25 -12
- package/tsconfig.base.json +9 -0
- package/dist/async-modules/mixpanel-recorder-BjSlYaNJ.min.js.map +0 -1
- package/dist/async-modules/mixpanel-targeting-BSHal4N9.min.js +0 -2
- package/dist/async-modules/mixpanel-targeting-BSHal4N9.min.js.map +0 -1
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
|
|
29
29
|
var Config = {
|
|
30
30
|
DEBUG: false,
|
|
31
|
-
LIB_VERSION: '2.
|
|
31
|
+
LIB_VERSION: '2.79.0'
|
|
32
32
|
};
|
|
33
33
|
|
|
34
34
|
// Window global names for async modules
|
|
@@ -19126,6 +19126,7 @@
|
|
|
19126
19126
|
var console_with_prefix = function(prefix) {
|
|
19127
19127
|
return {
|
|
19128
19128
|
log: log_func_with_prefix(console$1.log, prefix),
|
|
19129
|
+
warn: log_func_with_prefix(console$1.warn, prefix),
|
|
19129
19130
|
error: log_func_with_prefix(console$1.error, prefix),
|
|
19130
19131
|
critical: log_func_with_prefix(console$1.critical, prefix)
|
|
19131
19132
|
};
|
|
@@ -20072,7 +20073,8 @@
|
|
|
20072
20073
|
if (_localStorageSupported !== null && !forceCheck) {
|
|
20073
20074
|
return _localStorageSupported;
|
|
20074
20075
|
}
|
|
20075
|
-
|
|
20076
|
+
|
|
20077
|
+
return _localStorageSupported = _testStorageSupported(storage);
|
|
20076
20078
|
};
|
|
20077
20079
|
|
|
20078
20080
|
var _sessionStorageSupported = null;
|
|
@@ -20080,7 +20082,8 @@
|
|
|
20080
20082
|
if (_sessionStorageSupported !== null && !forceCheck) {
|
|
20081
20083
|
return _sessionStorageSupported;
|
|
20082
20084
|
}
|
|
20083
|
-
|
|
20085
|
+
|
|
20086
|
+
return _sessionStorageSupported = _testStorageSupported(storage);
|
|
20084
20087
|
};
|
|
20085
20088
|
|
|
20086
20089
|
function _storageWrapper(storage, name, is_supported_fn) {
|
|
@@ -20130,17 +20133,26 @@
|
|
|
20130
20133
|
};
|
|
20131
20134
|
}
|
|
20132
20135
|
|
|
20133
|
-
// Safari
|
|
20134
|
-
//
|
|
20135
|
-
var
|
|
20136
|
-
|
|
20137
|
-
|
|
20138
|
-
|
|
20139
|
-
|
|
20140
|
-
|
|
20136
|
+
// Safari and other browsers may error out accessing localStorage/sessionStorage
|
|
20137
|
+
// when cookies are disabled, so wrap access in a try-catch.
|
|
20138
|
+
var getLocalStorage = function() {
|
|
20139
|
+
try {
|
|
20140
|
+
return win.localStorage; // eslint-disable-line no-restricted-properties
|
|
20141
|
+
} catch (_err) {
|
|
20142
|
+
return null;
|
|
20143
|
+
}
|
|
20144
|
+
};
|
|
20145
|
+
|
|
20146
|
+
var getSessionStorage = function() {
|
|
20147
|
+
try {
|
|
20148
|
+
return win.sessionStorage; // eslint-disable-line no-restricted-properties
|
|
20149
|
+
} catch (_err) {
|
|
20150
|
+
return null;
|
|
20151
|
+
}
|
|
20152
|
+
};
|
|
20141
20153
|
|
|
20142
|
-
_.localStorage = _storageWrapper(
|
|
20143
|
-
_.sessionStorage = _storageWrapper(
|
|
20154
|
+
_.localStorage = _storageWrapper(getLocalStorage(), 'localStorage', localStorageSupported);
|
|
20155
|
+
_.sessionStorage = _storageWrapper(getSessionStorage(), 'sessionStorage', sessionStorageSupported);
|
|
20144
20156
|
|
|
20145
20157
|
_.register_event = (function() {
|
|
20146
20158
|
// written by Dean Edwards, 2005
|
|
@@ -20809,29 +20821,26 @@
|
|
|
20809
20821
|
_['toArray'] = _.toArray;
|
|
20810
20822
|
_['NPO'] = NpoPromise;
|
|
20811
20823
|
|
|
20812
|
-
var MIXPANEL_DB_NAME = 'mixpanelBrowserDb';
|
|
20813
|
-
|
|
20814
|
-
var RECORDING_EVENTS_STORE_NAME = 'mixpanelRecordingEvents';
|
|
20815
|
-
var RECORDING_REGISTRY_STORE_NAME = 'mixpanelRecordingRegistry';
|
|
20816
|
-
|
|
20817
|
-
// note: increment the version number when adding new object stores
|
|
20818
|
-
var DB_VERSION = 1;
|
|
20819
|
-
var OBJECT_STORES = [RECORDING_EVENTS_STORE_NAME, RECORDING_REGISTRY_STORE_NAME];
|
|
20820
|
-
|
|
20821
20824
|
/**
|
|
20822
20825
|
* @type {import('./wrapper').StorageWrapper}
|
|
20823
20826
|
*/
|
|
20824
|
-
var IDBStorageWrapper = function (storeName) {
|
|
20827
|
+
var IDBStorageWrapper = function (dbName, storeName, versionData) {
|
|
20828
|
+
this.dbName = dbName;
|
|
20829
|
+
this.storeName = storeName;
|
|
20830
|
+
this.version = versionData.version;
|
|
20831
|
+
this.storeNamesInDb = versionData.storeNames;
|
|
20825
20832
|
/**
|
|
20826
20833
|
* @type {Promise<IDBDatabase>|null}
|
|
20827
20834
|
*/
|
|
20828
20835
|
this.dbPromise = null;
|
|
20829
|
-
this.storeName = storeName;
|
|
20830
20836
|
};
|
|
20831
20837
|
|
|
20832
20838
|
IDBStorageWrapper.prototype._openDb = function () {
|
|
20839
|
+
var dbName = this.dbName;
|
|
20840
|
+
var version = this.version;
|
|
20841
|
+
var storeNamesInDb = this.storeNamesInDb;
|
|
20833
20842
|
return new PromisePolyfill(function (resolve, reject) {
|
|
20834
|
-
var openRequest = win.indexedDB.open(
|
|
20843
|
+
var openRequest = win.indexedDB.open(dbName, version);
|
|
20835
20844
|
openRequest['onerror'] = function () {
|
|
20836
20845
|
reject(openRequest.error);
|
|
20837
20846
|
};
|
|
@@ -20843,8 +20852,10 @@
|
|
|
20843
20852
|
openRequest['onupgradeneeded'] = function (ev) {
|
|
20844
20853
|
var db = ev.target.result;
|
|
20845
20854
|
|
|
20846
|
-
|
|
20847
|
-
db.
|
|
20855
|
+
storeNamesInDb.forEach(function (storeName) {
|
|
20856
|
+
if (!db.objectStoreNames.contains(storeName)) {
|
|
20857
|
+
db.createObjectStore(storeName);
|
|
20858
|
+
}
|
|
20848
20859
|
});
|
|
20849
20860
|
};
|
|
20850
20861
|
});
|
|
@@ -20936,6 +20947,16 @@
|
|
|
20936
20947
|
});
|
|
20937
20948
|
};
|
|
20938
20949
|
|
|
20950
|
+
var MIXPANEL_BROWSER_DB_NAME = 'mixpanelBrowserDb';
|
|
20951
|
+
var RECORDING_EVENTS_STORE_NAME = 'mixpanelRecordingEvents';
|
|
20952
|
+
var RECORDING_REGISTRY_STORE_NAME = 'mixpanelRecordingRegistry';
|
|
20953
|
+
|
|
20954
|
+
// Keeping these two properties closeby, as adding additional stores to a DB in IndexedDB requires a version increment
|
|
20955
|
+
var RECORDER_VERSION_DATA = {
|
|
20956
|
+
version: 1,
|
|
20957
|
+
storeNames: [RECORDING_EVENTS_STORE_NAME, RECORDING_REGISTRY_STORE_NAME]
|
|
20958
|
+
};
|
|
20959
|
+
|
|
20939
20960
|
/**
|
|
20940
20961
|
* GDPR utils
|
|
20941
20962
|
*
|
|
@@ -21236,7 +21257,7 @@
|
|
|
21236
21257
|
};
|
|
21237
21258
|
}
|
|
21238
21259
|
|
|
21239
|
-
var logger$
|
|
21260
|
+
var logger$9 = console_with_prefix('lock');
|
|
21240
21261
|
|
|
21241
21262
|
/**
|
|
21242
21263
|
* SharedLock: a mutex built on HTML5 localStorage, to ensure that only one browser
|
|
@@ -21262,7 +21283,7 @@
|
|
|
21262
21283
|
options = options || {};
|
|
21263
21284
|
|
|
21264
21285
|
this.storageKey = key;
|
|
21265
|
-
this.storage = options.storage ||
|
|
21286
|
+
this.storage = options.storage || getLocalStorage();
|
|
21266
21287
|
this.pollIntervalMS = options.pollIntervalMS || 100;
|
|
21267
21288
|
this.timeoutMS = options.timeoutMS || 2000;
|
|
21268
21289
|
|
|
@@ -21288,7 +21309,7 @@
|
|
|
21288
21309
|
|
|
21289
21310
|
var delay = function(cb) {
|
|
21290
21311
|
if (new Date().getTime() - startTime > timeoutMS) {
|
|
21291
|
-
logger$
|
|
21312
|
+
logger$9.error('Timeout waiting for mutex on ' + key + '; clearing lock. [' + i + ']');
|
|
21292
21313
|
storage.removeItem(keyZ);
|
|
21293
21314
|
storage.removeItem(keyY);
|
|
21294
21315
|
loop();
|
|
@@ -21390,10 +21411,13 @@
|
|
|
21390
21411
|
* @type {import('./wrapper').StorageWrapper}
|
|
21391
21412
|
*/
|
|
21392
21413
|
var LocalStorageWrapper = function (storageOverride) {
|
|
21393
|
-
this.storage = storageOverride ||
|
|
21414
|
+
this.storage = storageOverride || getLocalStorage();
|
|
21394
21415
|
};
|
|
21395
21416
|
|
|
21396
21417
|
LocalStorageWrapper.prototype.init = function () {
|
|
21418
|
+
if (!this.storage) {
|
|
21419
|
+
return PromisePolyfill.reject(new Error('localStorage is not available'));
|
|
21420
|
+
}
|
|
21397
21421
|
return PromisePolyfill.resolve();
|
|
21398
21422
|
};
|
|
21399
21423
|
|
|
@@ -21435,7 +21459,7 @@
|
|
|
21435
21459
|
}, this));
|
|
21436
21460
|
};
|
|
21437
21461
|
|
|
21438
|
-
var logger$
|
|
21462
|
+
var logger$8 = console_with_prefix('batch');
|
|
21439
21463
|
|
|
21440
21464
|
/**
|
|
21441
21465
|
* RequestQueue: queue for batching API requests with localStorage backup for retries.
|
|
@@ -21460,11 +21484,11 @@
|
|
|
21460
21484
|
if (this.usePersistence) {
|
|
21461
21485
|
this.queueStorage = options.queueStorage || new LocalStorageWrapper();
|
|
21462
21486
|
this.lock = new SharedLock(storageKey, {
|
|
21463
|
-
storage: options.sharedLockStorage
|
|
21487
|
+
storage: options.sharedLockStorage,
|
|
21464
21488
|
timeoutMS: options.sharedLockTimeoutMS,
|
|
21465
21489
|
});
|
|
21466
21490
|
}
|
|
21467
|
-
this.reportError = options.errorReporter || _.bind(logger$
|
|
21491
|
+
this.reportError = options.errorReporter || _.bind(logger$8.error, logger$8);
|
|
21468
21492
|
|
|
21469
21493
|
this.pid = options.pid || null; // pass pid to test out storage lock contention scenarios
|
|
21470
21494
|
|
|
@@ -21797,7 +21821,7 @@
|
|
|
21797
21821
|
// maximum interval between request retries after exponential backoff
|
|
21798
21822
|
var MAX_RETRY_INTERVAL_MS = 10 * 60 * 1000; // 10 minutes
|
|
21799
21823
|
|
|
21800
|
-
var logger$
|
|
21824
|
+
var logger$7 = console_with_prefix('batch');
|
|
21801
21825
|
|
|
21802
21826
|
/**
|
|
21803
21827
|
* RequestBatcher: manages the queueing, flushing, retry etc of requests of one
|
|
@@ -21925,7 +21949,7 @@
|
|
|
21925
21949
|
*/
|
|
21926
21950
|
RequestBatcher.prototype.flush = function(options) {
|
|
21927
21951
|
if (this.requestInProgress) {
|
|
21928
|
-
logger$
|
|
21952
|
+
logger$7.log('Flush: Request already in progress');
|
|
21929
21953
|
return PromisePolyfill.resolve();
|
|
21930
21954
|
}
|
|
21931
21955
|
|
|
@@ -22102,7 +22126,7 @@
|
|
|
22102
22126
|
if (options.unloading) {
|
|
22103
22127
|
requestOptions.transport = 'sendBeacon';
|
|
22104
22128
|
}
|
|
22105
|
-
logger$
|
|
22129
|
+
logger$7.log('MIXPANEL REQUEST:', dataForRequest);
|
|
22106
22130
|
return this.sendRequestPromise(dataForRequest, requestOptions).then(batchSendCallback);
|
|
22107
22131
|
}, this))
|
|
22108
22132
|
.catch(_.bind(function(err) {
|
|
@@ -22115,7 +22139,7 @@
|
|
|
22115
22139
|
* Log error to global logger and optional user-defined logger.
|
|
22116
22140
|
*/
|
|
22117
22141
|
RequestBatcher.prototype.reportError = function(msg, err) {
|
|
22118
|
-
logger$
|
|
22142
|
+
logger$7.error.apply(logger$7.error, arguments);
|
|
22119
22143
|
if (this.errorReporter) {
|
|
22120
22144
|
try {
|
|
22121
22145
|
if (!(err instanceof Error)) {
|
|
@@ -22123,7 +22147,7 @@
|
|
|
22123
22147
|
}
|
|
22124
22148
|
this.errorReporter(msg, err);
|
|
22125
22149
|
} catch(err) {
|
|
22126
|
-
logger$
|
|
22150
|
+
logger$7.error(err);
|
|
22127
22151
|
}
|
|
22128
22152
|
}
|
|
22129
22153
|
};
|
|
@@ -22268,7 +22292,7 @@
|
|
|
22268
22292
|
|
|
22269
22293
|
var MAX_DEPTH = 5;
|
|
22270
22294
|
|
|
22271
|
-
var logger$
|
|
22295
|
+
var logger$6 = console_with_prefix('autocapture');
|
|
22272
22296
|
|
|
22273
22297
|
|
|
22274
22298
|
function getClasses(el) {
|
|
@@ -22532,7 +22556,7 @@
|
|
|
22532
22556
|
return false;
|
|
22533
22557
|
}
|
|
22534
22558
|
} catch (err) {
|
|
22535
|
-
logger$
|
|
22559
|
+
logger$6.critical('Error while checking element in allowElementCallback', err);
|
|
22536
22560
|
return false;
|
|
22537
22561
|
}
|
|
22538
22562
|
}
|
|
@@ -22549,7 +22573,7 @@
|
|
|
22549
22573
|
return true;
|
|
22550
22574
|
}
|
|
22551
22575
|
} catch (err) {
|
|
22552
|
-
logger$
|
|
22576
|
+
logger$6.critical('Error while checking selector: ' + sel, err);
|
|
22553
22577
|
}
|
|
22554
22578
|
}
|
|
22555
22579
|
return false;
|
|
@@ -22564,7 +22588,7 @@
|
|
|
22564
22588
|
return true;
|
|
22565
22589
|
}
|
|
22566
22590
|
} catch (err) {
|
|
22567
|
-
logger$
|
|
22591
|
+
logger$6.critical('Error while checking element in blockElementCallback', err);
|
|
22568
22592
|
return true;
|
|
22569
22593
|
}
|
|
22570
22594
|
}
|
|
@@ -22578,7 +22602,7 @@
|
|
|
22578
22602
|
return true;
|
|
22579
22603
|
}
|
|
22580
22604
|
} catch (err) {
|
|
22581
|
-
logger$
|
|
22605
|
+
logger$6.critical('Error while checking selector: ' + sel, err);
|
|
22582
22606
|
}
|
|
22583
22607
|
}
|
|
22584
22608
|
}
|
|
@@ -23134,7 +23158,7 @@
|
|
|
23134
23158
|
*
|
|
23135
23159
|
*/
|
|
23136
23160
|
|
|
23137
|
-
var logger$
|
|
23161
|
+
var logger$5 = console_with_prefix('network-plugin');
|
|
23138
23162
|
|
|
23139
23163
|
/**
|
|
23140
23164
|
* Get the time origin for converting performance timestamps to absolute timestamps.
|
|
@@ -23286,7 +23310,7 @@
|
|
|
23286
23310
|
return str;
|
|
23287
23311
|
}
|
|
23288
23312
|
if (str.length > MAX_BODY_SIZE) {
|
|
23289
|
-
logger$
|
|
23313
|
+
logger$5.error('Body truncated from ' + str.length + ' to ' + MAX_BODY_SIZE + ' characters');
|
|
23290
23314
|
return str.substring(0, MAX_BODY_SIZE) + '... [truncated]';
|
|
23291
23315
|
}
|
|
23292
23316
|
return str;
|
|
@@ -23300,7 +23324,7 @@
|
|
|
23300
23324
|
*/
|
|
23301
23325
|
function initPerformanceObserver(cb, win, options) {
|
|
23302
23326
|
if (!win.PerformanceObserver) {
|
|
23303
|
-
logger$
|
|
23327
|
+
logger$5.error('PerformanceObserver not supported');
|
|
23304
23328
|
return function() {
|
|
23305
23329
|
//
|
|
23306
23330
|
};
|
|
@@ -23453,7 +23477,7 @@
|
|
|
23453
23477
|
attempt = 0;
|
|
23454
23478
|
}
|
|
23455
23479
|
if (attempt > 10) {
|
|
23456
|
-
logger$
|
|
23480
|
+
logger$5.error('Cannot find performance entry');
|
|
23457
23481
|
return Promise.resolve(null);
|
|
23458
23482
|
}
|
|
23459
23483
|
var urlPerformanceEntries = /** @type {PerformanceResourceTiming[]} */ (
|
|
@@ -23574,7 +23598,7 @@
|
|
|
23574
23598
|
)
|
|
23575
23599
|
.then(function(entry) {
|
|
23576
23600
|
if (!entry) {
|
|
23577
|
-
logger$
|
|
23601
|
+
logger$5.error('Failed to get performance entry for XHR request to ' + req.url);
|
|
23578
23602
|
return;
|
|
23579
23603
|
}
|
|
23580
23604
|
/** @type {NetworkRequest} */
|
|
@@ -23594,7 +23618,7 @@
|
|
|
23594
23618
|
cb({ requests: [request] });
|
|
23595
23619
|
})
|
|
23596
23620
|
.catch(function(e) {
|
|
23597
|
-
logger$
|
|
23621
|
+
logger$5.error('Error recording XHR request to ' + req.url + ': ' + String(e));
|
|
23598
23622
|
});
|
|
23599
23623
|
});
|
|
23600
23624
|
|
|
@@ -23686,7 +23710,7 @@
|
|
|
23686
23710
|
})
|
|
23687
23711
|
.then(function(entry) {
|
|
23688
23712
|
if (!entry) {
|
|
23689
|
-
logger$
|
|
23713
|
+
logger$5.error('Failed to get performance entry for fetch request to ' + req.url);
|
|
23690
23714
|
return;
|
|
23691
23715
|
}
|
|
23692
23716
|
/** @type {NetworkRequest} */
|
|
@@ -23706,7 +23730,7 @@
|
|
|
23706
23730
|
cb({ requests: [request] });
|
|
23707
23731
|
})
|
|
23708
23732
|
.catch(function (e) {
|
|
23709
|
-
logger$
|
|
23733
|
+
logger$5.error('Error recording fetch request to ' + req.url + ': ' + String(e));
|
|
23710
23734
|
});
|
|
23711
23735
|
|
|
23712
23736
|
return originalFetchPromise;
|
|
@@ -23779,7 +23803,7 @@
|
|
|
23779
23803
|
*/
|
|
23780
23804
|
|
|
23781
23805
|
|
|
23782
|
-
var logger$
|
|
23806
|
+
var logger$4 = console_with_prefix('recorder');
|
|
23783
23807
|
var CompressionStream = win['CompressionStream'];
|
|
23784
23808
|
|
|
23785
23809
|
var RECORDER_BATCHER_LIB_CONFIG = {
|
|
@@ -23876,11 +23900,11 @@
|
|
|
23876
23900
|
|
|
23877
23901
|
// disable persistence if localStorage is not supported
|
|
23878
23902
|
// request-queue will automatically disable persistence if indexedDB fails to initialize
|
|
23879
|
-
var usePersistence = localStorageSupported(options.sharedLockStorage, true) && !this.getConfig('disable_persistence');
|
|
23903
|
+
var usePersistence = localStorageSupported(options.sharedLockStorage || getLocalStorage(), true) && !this.getConfig('disable_persistence');
|
|
23880
23904
|
|
|
23881
23905
|
// each replay has its own batcher key to avoid conflicts between rrweb events of different recordings
|
|
23882
23906
|
this.batcherKey = '__mprec_' + this.getConfig('name') + '_' + this.getConfig('token') + '_' + this.replayId;
|
|
23883
|
-
this.queueStorage = new IDBStorageWrapper(RECORDING_EVENTS_STORE_NAME);
|
|
23907
|
+
this.queueStorage = new IDBStorageWrapper(MIXPANEL_BROWSER_DB_NAME, RECORDING_EVENTS_STORE_NAME, RECORDER_VERSION_DATA);
|
|
23884
23908
|
this.batcher = new RequestBatcher(this.batcherKey, {
|
|
23885
23909
|
errorReporter: this.reportError.bind(this),
|
|
23886
23910
|
flushOnlyOnInterval: true,
|
|
@@ -23959,14 +23983,14 @@
|
|
|
23959
23983
|
}
|
|
23960
23984
|
|
|
23961
23985
|
if (this._stopRecording !== null) {
|
|
23962
|
-
logger$
|
|
23986
|
+
logger$4.log('Recording already in progress, skipping startRecording.');
|
|
23963
23987
|
return;
|
|
23964
23988
|
}
|
|
23965
23989
|
|
|
23966
23990
|
this.recordMaxMs = this.getConfig('record_max_ms');
|
|
23967
23991
|
if (this.recordMaxMs > MAX_RECORDING_MS) {
|
|
23968
23992
|
this.recordMaxMs = MAX_RECORDING_MS;
|
|
23969
|
-
logger$
|
|
23993
|
+
logger$4.critical('record_max_ms cannot be greater than ' + MAX_RECORDING_MS + 'ms. Capping value.');
|
|
23970
23994
|
}
|
|
23971
23995
|
|
|
23972
23996
|
if (!this.maxExpires) {
|
|
@@ -24030,7 +24054,7 @@
|
|
|
24030
24054
|
);
|
|
24031
24055
|
}
|
|
24032
24056
|
|
|
24033
|
-
var validatedOrigins = validateAllowedOrigins(this.getConfig('record_allowed_iframe_origins'), logger$
|
|
24057
|
+
var validatedOrigins = validateAllowedOrigins(this.getConfig('record_allowed_iframe_origins'), logger$4);
|
|
24034
24058
|
|
|
24035
24059
|
try {
|
|
24036
24060
|
this._stopRecording = this._rrwebRecord({
|
|
@@ -24292,14 +24316,14 @@
|
|
|
24292
24316
|
|
|
24293
24317
|
|
|
24294
24318
|
SessionRecording.prototype.reportError = function(msg, err) {
|
|
24295
|
-
logger$
|
|
24319
|
+
logger$4.error.apply(logger$4.error, arguments);
|
|
24296
24320
|
try {
|
|
24297
24321
|
if (!err && !(msg instanceof Error)) {
|
|
24298
24322
|
msg = new Error(msg);
|
|
24299
24323
|
}
|
|
24300
24324
|
this.getConfig('error_reporter')(msg, err);
|
|
24301
24325
|
} catch(err) {
|
|
24302
|
-
logger$
|
|
24326
|
+
logger$4.error(err);
|
|
24303
24327
|
}
|
|
24304
24328
|
};
|
|
24305
24329
|
|
|
@@ -24328,7 +24352,7 @@
|
|
|
24328
24352
|
var configValue = this.getConfig('record_min_ms');
|
|
24329
24353
|
|
|
24330
24354
|
if (configValue > MAX_VALUE_FOR_MIN_RECORDING_MS) {
|
|
24331
|
-
logger$
|
|
24355
|
+
logger$4.critical('record_min_ms cannot be greater than ' + MAX_VALUE_FOR_MIN_RECORDING_MS + 'ms. Capping value.');
|
|
24332
24356
|
return MAX_VALUE_FOR_MIN_RECORDING_MS;
|
|
24333
24357
|
}
|
|
24334
24358
|
|
|
@@ -24370,7 +24394,7 @@
|
|
|
24370
24394
|
*/
|
|
24371
24395
|
var RecordingRegistry = function (options) {
|
|
24372
24396
|
/** @type {IDBStorageWrapper} */
|
|
24373
|
-
this.idb = new IDBStorageWrapper(RECORDING_REGISTRY_STORE_NAME);
|
|
24397
|
+
this.idb = new IDBStorageWrapper(MIXPANEL_BROWSER_DB_NAME, RECORDING_REGISTRY_STORE_NAME, RECORDER_VERSION_DATA);
|
|
24374
24398
|
this.errorReporter = options.errorReporter;
|
|
24375
24399
|
this.mixpanelInstance = options.mixpanelInstance;
|
|
24376
24400
|
this.sharedLockStorage = options.sharedLockStorage;
|
|
@@ -24491,7 +24515,7 @@
|
|
|
24491
24515
|
.catch(this.handleError.bind(this));
|
|
24492
24516
|
};
|
|
24493
24517
|
|
|
24494
|
-
var logger$
|
|
24518
|
+
var logger$3 = console_with_prefix('recorder');
|
|
24495
24519
|
|
|
24496
24520
|
/**
|
|
24497
24521
|
* Recorder API: bundles rrweb and and exposes methods to start and stop recordings.
|
|
@@ -24507,7 +24531,7 @@
|
|
|
24507
24531
|
*/
|
|
24508
24532
|
this.recordingRegistry = new RecordingRegistry({
|
|
24509
24533
|
mixpanelInstance: this.mixpanelInstance,
|
|
24510
|
-
errorReporter: logger$
|
|
24534
|
+
errorReporter: logger$3.error,
|
|
24511
24535
|
sharedLockStorage: sharedLockStorage
|
|
24512
24536
|
});
|
|
24513
24537
|
this._flushInactivePromise = this.recordingRegistry.flushInactiveRecordings();
|
|
@@ -24519,17 +24543,17 @@
|
|
|
24519
24543
|
MixpanelRecorder.prototype.startRecording = function(options) {
|
|
24520
24544
|
options = options || {};
|
|
24521
24545
|
if (this.activeRecording && !this.activeRecording.isRrwebStopped()) {
|
|
24522
|
-
logger$
|
|
24546
|
+
logger$3.log('Recording already in progress, skipping startRecording.');
|
|
24523
24547
|
return;
|
|
24524
24548
|
}
|
|
24525
24549
|
|
|
24526
24550
|
var onIdleTimeout = function () {
|
|
24527
|
-
logger$
|
|
24551
|
+
logger$3.log('Idle timeout reached, restarting recording.');
|
|
24528
24552
|
this.resetRecording();
|
|
24529
24553
|
}.bind(this);
|
|
24530
24554
|
|
|
24531
24555
|
var onMaxLengthReached = function () {
|
|
24532
|
-
logger$
|
|
24556
|
+
logger$3.log('Max recording length reached, stopping recording.');
|
|
24533
24557
|
this.resetRecording();
|
|
24534
24558
|
}.bind(this);
|
|
24535
24559
|
|
|
@@ -24599,7 +24623,7 @@
|
|
|
24599
24623
|
} else if (startNewIfInactive) {
|
|
24600
24624
|
return this.startRecording({shouldStopBatcher: false});
|
|
24601
24625
|
} else {
|
|
24602
|
-
logger$
|
|
24626
|
+
logger$3.log('No resumable recording found.');
|
|
24603
24627
|
return null;
|
|
24604
24628
|
}
|
|
24605
24629
|
}.bind(this));
|
|
@@ -24733,7 +24757,7 @@
|
|
|
24733
24757
|
observer.observe(shadowRoot, this.observerConfig);
|
|
24734
24758
|
this.shadowObservers.push(observer);
|
|
24735
24759
|
} catch (e) {
|
|
24736
|
-
logger$
|
|
24760
|
+
logger$6.critical('Error while observing shadow root', e);
|
|
24737
24761
|
}
|
|
24738
24762
|
};
|
|
24739
24763
|
|
|
@@ -24744,7 +24768,7 @@
|
|
|
24744
24768
|
}
|
|
24745
24769
|
|
|
24746
24770
|
if (!weakSetSupported()) {
|
|
24747
|
-
logger$
|
|
24771
|
+
logger$6.critical('Shadow DOM observation unavailable: WeakSet not supported');
|
|
24748
24772
|
return;
|
|
24749
24773
|
}
|
|
24750
24774
|
|
|
@@ -24760,7 +24784,7 @@
|
|
|
24760
24784
|
try {
|
|
24761
24785
|
this.shadowObservers[i].disconnect();
|
|
24762
24786
|
} catch (e) {
|
|
24763
|
-
logger$
|
|
24787
|
+
logger$6.critical('Error while disconnecting shadow DOM observer', e);
|
|
24764
24788
|
}
|
|
24765
24789
|
}
|
|
24766
24790
|
this.shadowObservers = [];
|
|
@@ -24948,7 +24972,7 @@
|
|
|
24948
24972
|
|
|
24949
24973
|
this.mutationObserver.observe(document.body || document.documentElement, MUTATION_OBSERVER_CONFIG);
|
|
24950
24974
|
} catch (e) {
|
|
24951
|
-
logger$
|
|
24975
|
+
logger$6.critical('Error while setting up mutation observer', e);
|
|
24952
24976
|
}
|
|
24953
24977
|
}
|
|
24954
24978
|
|
|
@@ -24963,7 +24987,7 @@
|
|
|
24963
24987
|
);
|
|
24964
24988
|
this.shadowDOMObserver.start();
|
|
24965
24989
|
} catch (e) {
|
|
24966
|
-
logger$
|
|
24990
|
+
logger$6.critical('Error while setting up shadow DOM observer', e);
|
|
24967
24991
|
this.shadowDOMObserver = null;
|
|
24968
24992
|
}
|
|
24969
24993
|
}
|
|
@@ -24990,7 +25014,7 @@
|
|
|
24990
25014
|
try {
|
|
24991
25015
|
listener.target.removeEventListener(listener.event, listener.handler, listener.options);
|
|
24992
25016
|
} catch (e) {
|
|
24993
|
-
logger$
|
|
25017
|
+
logger$6.critical('Error while removing event listener', e);
|
|
24994
25018
|
}
|
|
24995
25019
|
}
|
|
24996
25020
|
this.eventListeners = [];
|
|
@@ -24999,7 +25023,7 @@
|
|
|
24999
25023
|
try {
|
|
25000
25024
|
this.mutationObserver.disconnect();
|
|
25001
25025
|
} catch (e) {
|
|
25002
|
-
logger$
|
|
25026
|
+
logger$6.critical('Error while disconnecting mutation observer', e);
|
|
25003
25027
|
}
|
|
25004
25028
|
this.mutationObserver = null;
|
|
25005
25029
|
}
|
|
@@ -25008,7 +25032,7 @@
|
|
|
25008
25032
|
try {
|
|
25009
25033
|
this.shadowDOMObserver.stop();
|
|
25010
25034
|
} catch (e) {
|
|
25011
|
-
logger$
|
|
25035
|
+
logger$6.critical('Error while stopping shadow DOM observer', e);
|
|
25012
25036
|
}
|
|
25013
25037
|
this.shadowDOMObserver = null;
|
|
25014
25038
|
}
|
|
@@ -25086,7 +25110,7 @@
|
|
|
25086
25110
|
|
|
25087
25111
|
Autocapture.prototype.init = function() {
|
|
25088
25112
|
if (!minDOMApisSupported()) {
|
|
25089
|
-
logger$
|
|
25113
|
+
logger$6.critical('Autocapture unavailable: missing required DOM APIs');
|
|
25090
25114
|
return;
|
|
25091
25115
|
}
|
|
25092
25116
|
this.initPageListeners();
|
|
@@ -25126,7 +25150,7 @@
|
|
|
25126
25150
|
try {
|
|
25127
25151
|
return !urlMatchesRegexList(currentUrl, allowUrlRegexes);
|
|
25128
25152
|
} catch (err) {
|
|
25129
|
-
logger$
|
|
25153
|
+
logger$6.critical('Error while checking block URL regexes: ', err);
|
|
25130
25154
|
return true;
|
|
25131
25155
|
}
|
|
25132
25156
|
}
|
|
@@ -25139,7 +25163,7 @@
|
|
|
25139
25163
|
try {
|
|
25140
25164
|
return urlMatchesRegexList(currentUrl, blockUrlRegexes);
|
|
25141
25165
|
} catch (err) {
|
|
25142
|
-
logger$
|
|
25166
|
+
logger$6.critical('Error while checking block URL regexes: ', err);
|
|
25143
25167
|
return true;
|
|
25144
25168
|
}
|
|
25145
25169
|
};
|
|
@@ -25277,7 +25301,7 @@
|
|
|
25277
25301
|
return;
|
|
25278
25302
|
}
|
|
25279
25303
|
|
|
25280
|
-
logger$
|
|
25304
|
+
logger$6.log('Initializing scroll depth tracking');
|
|
25281
25305
|
|
|
25282
25306
|
this.maxScrollViewDepth = Math.max(document$1.documentElement.clientHeight, win.innerHeight || 0);
|
|
25283
25307
|
|
|
@@ -25303,7 +25327,7 @@
|
|
|
25303
25327
|
if (!this.getConfig(CONFIG_TRACK_CLICK) && !this.mp.get_config('record_heatmap_data')) {
|
|
25304
25328
|
return;
|
|
25305
25329
|
}
|
|
25306
|
-
logger$
|
|
25330
|
+
logger$6.log('Initializing click tracking');
|
|
25307
25331
|
|
|
25308
25332
|
this.listenerClick = function(ev) {
|
|
25309
25333
|
if (!this.getConfig(CONFIG_TRACK_CLICK) && !this.mp.is_recording_heatmap_data()) {
|
|
@@ -25322,7 +25346,7 @@
|
|
|
25322
25346
|
return;
|
|
25323
25347
|
}
|
|
25324
25348
|
|
|
25325
|
-
logger$
|
|
25349
|
+
logger$6.log('Initializing dead click tracking');
|
|
25326
25350
|
if (!this._deadClickTracker) {
|
|
25327
25351
|
this._deadClickTracker = new DeadClickTracker(function(deadClickEvent) {
|
|
25328
25352
|
this.trackDomEvent(deadClickEvent, MP_EV_DEAD_CLICK);
|
|
@@ -25356,7 +25380,7 @@
|
|
|
25356
25380
|
if (!this.getConfig(CONFIG_TRACK_INPUT)) {
|
|
25357
25381
|
return;
|
|
25358
25382
|
}
|
|
25359
|
-
logger$
|
|
25383
|
+
logger$6.log('Initializing input tracking');
|
|
25360
25384
|
|
|
25361
25385
|
this.listenerChange = function(ev) {
|
|
25362
25386
|
if (!this.getConfig(CONFIG_TRACK_INPUT)) {
|
|
@@ -25370,14 +25394,15 @@
|
|
|
25370
25394
|
Autocapture.prototype.initPageviewTracking = function() {
|
|
25371
25395
|
win.removeEventListener(EV_MP_LOCATION_CHANGE, this.listenerLocationchange);
|
|
25372
25396
|
|
|
25373
|
-
if (!this.pageviewTrackingConfig()) {
|
|
25397
|
+
if (!this.pageviewTrackingConfig() && !this.mp.get_config('record_heatmap_data')) {
|
|
25374
25398
|
return;
|
|
25375
25399
|
}
|
|
25376
|
-
logger$
|
|
25400
|
+
logger$6.log('Initializing pageview tracking');
|
|
25377
25401
|
|
|
25378
25402
|
var previousTrackedUrl = '';
|
|
25379
25403
|
var tracked = false;
|
|
25380
|
-
if
|
|
25404
|
+
// Track initial pageview if pageview tracking enabled OR heatmap recording is active
|
|
25405
|
+
if ((this.pageviewTrackingConfig() || this.mp.is_recording_heatmap_data()) && !this.currentUrlBlocked()) {
|
|
25381
25406
|
tracked = this.mp.track_pageview(DEFAULT_PROPS);
|
|
25382
25407
|
}
|
|
25383
25408
|
if (tracked) {
|
|
@@ -25393,6 +25418,10 @@
|
|
|
25393
25418
|
var shouldTrack = false;
|
|
25394
25419
|
var didPathChange = currentUrl.split('#')[0].split('?')[0] !== previousTrackedUrl.split('#')[0].split('?')[0];
|
|
25395
25420
|
var trackPageviewOption = this.pageviewTrackingConfig();
|
|
25421
|
+
if (!trackPageviewOption && this.mp.is_recording_heatmap_data()) {
|
|
25422
|
+
trackPageviewOption = PAGEVIEW_OPTION_FULL_URL;
|
|
25423
|
+
}
|
|
25424
|
+
|
|
25396
25425
|
if (trackPageviewOption === PAGEVIEW_OPTION_FULL_URL) {
|
|
25397
25426
|
shouldTrack = currentUrl !== previousTrackedUrl;
|
|
25398
25427
|
} else if (trackPageviewOption === PAGEVIEW_OPTION_URL_WITH_PATH_AND_QUERY_STRING) {
|
|
@@ -25408,7 +25437,7 @@
|
|
|
25408
25437
|
}
|
|
25409
25438
|
if (didPathChange) {
|
|
25410
25439
|
this.lastScrollCheckpoint = 0;
|
|
25411
|
-
logger$
|
|
25440
|
+
logger$6.log('Path change: re-initializing scroll depth checkpoints');
|
|
25412
25441
|
}
|
|
25413
25442
|
}
|
|
25414
25443
|
}.bind(this));
|
|
@@ -25423,7 +25452,7 @@
|
|
|
25423
25452
|
return;
|
|
25424
25453
|
}
|
|
25425
25454
|
|
|
25426
|
-
logger$
|
|
25455
|
+
logger$6.log('Initializing rage click tracking');
|
|
25427
25456
|
if (!this._rageClickTracker) {
|
|
25428
25457
|
this._rageClickTracker = new RageClickTracker();
|
|
25429
25458
|
}
|
|
@@ -25453,7 +25482,7 @@
|
|
|
25453
25482
|
if (!this.getConfig(CONFIG_TRACK_SCROLL)) {
|
|
25454
25483
|
return;
|
|
25455
25484
|
}
|
|
25456
|
-
logger$
|
|
25485
|
+
logger$6.log('Initializing scroll tracking');
|
|
25457
25486
|
this.lastScrollCheckpoint = 0;
|
|
25458
25487
|
|
|
25459
25488
|
var scrollTrackFunction = function() {
|
|
@@ -25490,7 +25519,7 @@
|
|
|
25490
25519
|
}
|
|
25491
25520
|
}
|
|
25492
25521
|
} catch (err) {
|
|
25493
|
-
logger$
|
|
25522
|
+
logger$6.critical('Error while calculating scroll percentage', err);
|
|
25494
25523
|
}
|
|
25495
25524
|
if (shouldTrack) {
|
|
25496
25525
|
this.mp.track(MP_EV_SCROLL, props);
|
|
@@ -25508,7 +25537,7 @@
|
|
|
25508
25537
|
if (!this.getConfig(CONFIG_TRACK_SUBMIT)) {
|
|
25509
25538
|
return;
|
|
25510
25539
|
}
|
|
25511
|
-
logger$
|
|
25540
|
+
logger$6.log('Initializing submit tracking');
|
|
25512
25541
|
|
|
25513
25542
|
this.listenerSubmit = function(ev) {
|
|
25514
25543
|
if (!this.getConfig(CONFIG_TRACK_SUBMIT)) {
|
|
@@ -25530,7 +25559,7 @@
|
|
|
25530
25559
|
return;
|
|
25531
25560
|
}
|
|
25532
25561
|
|
|
25533
|
-
logger$
|
|
25562
|
+
logger$6.log('Initializing page visibility tracking.');
|
|
25534
25563
|
this._initScrollDepthTracking();
|
|
25535
25564
|
var previousTrackedUrl = _.info.currentUrl();
|
|
25536
25565
|
|
|
@@ -25615,10 +25644,183 @@
|
|
|
25615
25644
|
return win[TARGETING_GLOBAL_NAME];
|
|
25616
25645
|
};
|
|
25617
25646
|
|
|
25647
|
+
var logger$2 = console_with_prefix('flags');
|
|
25648
|
+
|
|
25649
|
+
var MIXPANEL_FLAGS_DB_NAME = 'mixpanelFlagsDb';
|
|
25650
|
+
var FLAGS_STORE_NAME = 'mixpanelFlags';
|
|
25651
|
+
|
|
25652
|
+
// Keeping these two properties closeby, as adding additional stores to a DB in IndexedDB requires a version increment
|
|
25653
|
+
var FLAGS_VERSION_DATA = { version: 1, storeNames: [FLAGS_STORE_NAME] };
|
|
25654
|
+
|
|
25655
|
+
var PERSISTED_VARIANTS_KEY_PREFIX = 'persisted_variants_for_';
|
|
25656
|
+
var DEFAULT_TTL_MS = 24 * 60 * 60 * 1000;
|
|
25657
|
+
|
|
25658
|
+
var VariantLookupPolicy = Object.freeze({
|
|
25659
|
+
NETWORK_ONLY: 'networkOnly',
|
|
25660
|
+
NETWORK_FIRST: 'networkFirst',
|
|
25661
|
+
PERSISTENCE_UNTIL_NETWORK_SUCCESS: 'persistenceUntilNetworkSuccess'
|
|
25662
|
+
});
|
|
25663
|
+
|
|
25664
|
+
var VALID_POLICIES = [
|
|
25665
|
+
VariantLookupPolicy.NETWORK_ONLY,
|
|
25666
|
+
VariantLookupPolicy.NETWORK_FIRST,
|
|
25667
|
+
VariantLookupPolicy.PERSISTENCE_UNTIL_NETWORK_SUCCESS
|
|
25668
|
+
];
|
|
25669
|
+
|
|
25670
|
+
/**
|
|
25671
|
+
* Module for handling the storage and retrieval of persisted feature flag variants.
|
|
25672
|
+
*/
|
|
25673
|
+
var FeatureFlagPersistence = function(persistenceConfig, token, isGloballyDisabled) {
|
|
25674
|
+
this.idb = new IDBStorageWrapper(MIXPANEL_FLAGS_DB_NAME, FLAGS_STORE_NAME, FLAGS_VERSION_DATA);
|
|
25675
|
+
this.persistenceConfig = persistenceConfig;
|
|
25676
|
+
this.persistedVariantsKey = PERSISTED_VARIANTS_KEY_PREFIX + token;
|
|
25677
|
+
this.isGloballyDisabled = isGloballyDisabled || function() { return false; };
|
|
25678
|
+
};
|
|
25679
|
+
|
|
25680
|
+
FeatureFlagPersistence.prototype.getPolicy = function() {
|
|
25681
|
+
if (this.isGloballyDisabled() || !this._isConfigValid()) {
|
|
25682
|
+
return VariantLookupPolicy.NETWORK_ONLY;
|
|
25683
|
+
}
|
|
25684
|
+
return this.persistenceConfig['variantLookupPolicy'];
|
|
25685
|
+
};
|
|
25686
|
+
|
|
25687
|
+
FeatureFlagPersistence.prototype.getTtlMs = function() {
|
|
25688
|
+
if (!this._isConfigValid()) {
|
|
25689
|
+
return DEFAULT_TTL_MS;
|
|
25690
|
+
}
|
|
25691
|
+
var configuredTtl = this.persistenceConfig['persistenceTtlMs'];
|
|
25692
|
+
return (configuredTtl === undefined || configuredTtl === null) ? DEFAULT_TTL_MS : configuredTtl;
|
|
25693
|
+
};
|
|
25694
|
+
|
|
25695
|
+
FeatureFlagPersistence.prototype._isConfigValid = function() {
|
|
25696
|
+
var config = this.persistenceConfig;
|
|
25697
|
+
if (!config) {
|
|
25698
|
+
return false;
|
|
25699
|
+
}
|
|
25700
|
+
|
|
25701
|
+
if (VALID_POLICIES.indexOf(config['variantLookupPolicy']) === -1) {
|
|
25702
|
+
logger$2.error('Invalid variantLookupPolicy:', config['variantLookupPolicy']);
|
|
25703
|
+
return false;
|
|
25704
|
+
}
|
|
25705
|
+
|
|
25706
|
+
if (config['persistenceTtlMs'] !== undefined &&
|
|
25707
|
+
config['persistenceTtlMs'] !== null &&
|
|
25708
|
+
config['persistenceTtlMs'] <= 0) {
|
|
25709
|
+
logger$2.error('If provided, persistenceTtlMs must be a positive number. Provided value:', config['persistenceTtlMs']);
|
|
25710
|
+
return false;
|
|
25711
|
+
}
|
|
25712
|
+
|
|
25713
|
+
return true;
|
|
25714
|
+
};
|
|
25715
|
+
|
|
25716
|
+
FeatureFlagPersistence.prototype.loadFlagsFromStorage = function(context) {
|
|
25717
|
+
var clearAndReturnNull = _.bind(function() {
|
|
25718
|
+
return this.clear().then(function() { return null; }).catch(function() { return null; });
|
|
25719
|
+
}, this);
|
|
25720
|
+
|
|
25721
|
+
if (this.getPolicy() === VariantLookupPolicy.NETWORK_ONLY) {
|
|
25722
|
+
return clearAndReturnNull();
|
|
25723
|
+
}
|
|
25724
|
+
|
|
25725
|
+
var ttlMs = this.getTtlMs();
|
|
25726
|
+
|
|
25727
|
+
return this.idb.init().then(_.bind(function() {
|
|
25728
|
+
return this.idb.getItem(this.persistedVariantsKey);
|
|
25729
|
+
}, this)).then(_.bind(function(data) {
|
|
25730
|
+
if (!data) {
|
|
25731
|
+
logger$2.log('No persisted variants found in IndexedDB');
|
|
25732
|
+
return null;
|
|
25733
|
+
}
|
|
25734
|
+
|
|
25735
|
+
if (ttlMs && Date.now() - data['persistedAt'] >= ttlMs) {
|
|
25736
|
+
logger$2.log('Persisted variants are expiring');
|
|
25737
|
+
return null;
|
|
25738
|
+
}
|
|
25739
|
+
|
|
25740
|
+
if (!context || data['distinctId'] !== context['distinct_id']) {
|
|
25741
|
+
logger$2.log('Persisted variants found, but for a different distinct_id so clearing.');
|
|
25742
|
+
return clearAndReturnNull();
|
|
25743
|
+
}
|
|
25744
|
+
|
|
25745
|
+
var persistedFlags = new Map();
|
|
25746
|
+
_.each(data['flagVariants'], function(variantData, key) {
|
|
25747
|
+
persistedFlags.set(key, {
|
|
25748
|
+
'key': variantData['variant_key'],
|
|
25749
|
+
'value': variantData['variant_value'],
|
|
25750
|
+
'experiment_id': variantData['experiment_id'],
|
|
25751
|
+
'is_experiment_active': variantData['is_experiment_active'],
|
|
25752
|
+
'is_qa_tester': variantData['is_qa_tester'],
|
|
25753
|
+
'variant_source': 'persistence',
|
|
25754
|
+
'persisted_at_in_ms': data['persistedAt'],
|
|
25755
|
+
'ttl_in_ms': ttlMs
|
|
25756
|
+
});
|
|
25757
|
+
});
|
|
25758
|
+
|
|
25759
|
+
logger$2.log('Loaded', persistedFlags.size, 'variants from IndexedDB for distinct_id', data['distinctId']);
|
|
25760
|
+
|
|
25761
|
+
return {
|
|
25762
|
+
flags: persistedFlags,
|
|
25763
|
+
pendingFirstTimeEvents: data['pendingFirstTimeEvents'] || {},
|
|
25764
|
+
persistedAtMs: data['persistedAt'],
|
|
25765
|
+
ttlMs: ttlMs
|
|
25766
|
+
};
|
|
25767
|
+
}, this)).catch(_.bind(function(error) {
|
|
25768
|
+
logger$2.error('Failed to load persisted variants from IndexedDB, so clearing', error);
|
|
25769
|
+
return clearAndReturnNull();
|
|
25770
|
+
}, this));
|
|
25771
|
+
};
|
|
25772
|
+
|
|
25773
|
+
FeatureFlagPersistence.prototype.save = function(context, flagsMap, pendingFirstTimeEvents) {
|
|
25774
|
+
if (this.getPolicy() === VariantLookupPolicy.NETWORK_ONLY) {
|
|
25775
|
+
return Promise.resolve();
|
|
25776
|
+
}
|
|
25777
|
+
|
|
25778
|
+
var flagVariants = {};
|
|
25779
|
+
flagsMap.forEach(function(variant, key) {
|
|
25780
|
+
flagVariants[key] = {
|
|
25781
|
+
'variant_key': variant['key'],
|
|
25782
|
+
'variant_value': variant['value'],
|
|
25783
|
+
'experiment_id': variant['experiment_id'],
|
|
25784
|
+
'is_experiment_active': variant['is_experiment_active'],
|
|
25785
|
+
'is_qa_tester': variant['is_qa_tester']
|
|
25786
|
+
};
|
|
25787
|
+
});
|
|
25788
|
+
|
|
25789
|
+
var data = {
|
|
25790
|
+
'persistedAt': Date.now(),
|
|
25791
|
+
'distinctId': context && context['distinct_id'],
|
|
25792
|
+
'context': context,
|
|
25793
|
+
'flagVariants': flagVariants,
|
|
25794
|
+
'pendingFirstTimeEvents': pendingFirstTimeEvents || {}
|
|
25795
|
+
};
|
|
25796
|
+
|
|
25797
|
+
return this.idb.init().then(_.bind(function() {
|
|
25798
|
+
return this.idb.setItem(this.persistedVariantsKey, data);
|
|
25799
|
+
}, this)).then(function() {
|
|
25800
|
+
logger$2.log('Saved', flagsMap.size, 'variants to IndexedDB for distinct_id', data['distinctId']);
|
|
25801
|
+
}).catch(function(error) {
|
|
25802
|
+
logger$2.error('Failed to persist variants to IndexedDB:', error);
|
|
25803
|
+
});
|
|
25804
|
+
};
|
|
25805
|
+
|
|
25806
|
+
FeatureFlagPersistence.prototype.clear = function() {
|
|
25807
|
+
if (this.isGloballyDisabled()) {
|
|
25808
|
+
return Promise.resolve();
|
|
25809
|
+
}
|
|
25810
|
+
return this.idb.init().then(_.bind(function() {
|
|
25811
|
+
return this.idb.removeItem(this.persistedVariantsKey);
|
|
25812
|
+
}, this)).then(function() {
|
|
25813
|
+
logger$2.log('Cleared persisted variants from IndexedDB');
|
|
25814
|
+
}).catch(function(error) {
|
|
25815
|
+
logger$2.error('Failed to clear persisted variants from IndexedDB:', error);
|
|
25816
|
+
});
|
|
25817
|
+
};
|
|
25818
|
+
|
|
25618
25819
|
var logger$1 = console_with_prefix('flags');
|
|
25619
25820
|
var FLAGS_CONFIG_KEY = 'flags';
|
|
25620
25821
|
|
|
25621
25822
|
var CONFIG_CONTEXT = 'context';
|
|
25823
|
+
var CONFIG_PERSISTENCE = 'persistence';
|
|
25622
25824
|
var CONFIG_DEFAULTS = {};
|
|
25623
25825
|
CONFIG_DEFAULTS[CONFIG_CONTEXT] = {};
|
|
25624
25826
|
|
|
@@ -25641,6 +25843,13 @@
|
|
|
25641
25843
|
return eventKey.split(':')[0];
|
|
25642
25844
|
};
|
|
25643
25845
|
|
|
25846
|
+
var withFallbackSource = function(fallback) {
|
|
25847
|
+
if (_.isObject(fallback)) {
|
|
25848
|
+
return _.extend({}, fallback, {'variant_source': 'fallback'});
|
|
25849
|
+
}
|
|
25850
|
+
return {'value': fallback, 'variant_source': 'fallback'};
|
|
25851
|
+
};
|
|
25852
|
+
|
|
25644
25853
|
/**
|
|
25645
25854
|
* FeatureFlagManager: support for Mixpanel's feature flagging product
|
|
25646
25855
|
* @constructor
|
|
@@ -25663,13 +25872,63 @@
|
|
|
25663
25872
|
}
|
|
25664
25873
|
|
|
25665
25874
|
this.flags = null;
|
|
25666
|
-
this.fetchFlags().catch(function() {
|
|
25667
|
-
logger$1.error('Error fetching flags during init');
|
|
25668
|
-
});
|
|
25669
|
-
|
|
25670
25875
|
this.trackedFeatures = new Set();
|
|
25671
25876
|
this.pendingFirstTimeEvents = {};
|
|
25672
25877
|
this.activatedFirstTimeEvents = {};
|
|
25878
|
+
this._loadedPersistedAtMs = null;
|
|
25879
|
+
this._loadedTtlMs = null;
|
|
25880
|
+
|
|
25881
|
+
this.persistence = new FeatureFlagPersistence(
|
|
25882
|
+
this.getConfig(CONFIG_PERSISTENCE),
|
|
25883
|
+
this.getMpConfig('token'),
|
|
25884
|
+
_.bind(function() { return this.getMpConfig('disable_persistence'); }, this)
|
|
25885
|
+
);
|
|
25886
|
+
|
|
25887
|
+
this.persistenceLoadedPromise = this.persistence.loadFlagsFromStorage(this._buildContext())
|
|
25888
|
+
.then(_.bind(function(loaded) {
|
|
25889
|
+
if (loaded) {
|
|
25890
|
+
this.flags = loaded.flags;
|
|
25891
|
+
this.pendingFirstTimeEvents = loaded.pendingFirstTimeEvents;
|
|
25892
|
+
this._loadedPersistedAtMs = loaded.persistedAtMs;
|
|
25893
|
+
this._loadedTtlMs = loaded.ttlMs;
|
|
25894
|
+
}
|
|
25895
|
+
}, this));
|
|
25896
|
+
|
|
25897
|
+
return this.persistenceLoadedPromise
|
|
25898
|
+
.then(_.bind(function() {
|
|
25899
|
+
return this.fetchFlags();
|
|
25900
|
+
}, this))
|
|
25901
|
+
.catch(function() {
|
|
25902
|
+
logger$1.error('Error initializing feature flags');
|
|
25903
|
+
});
|
|
25904
|
+
};
|
|
25905
|
+
|
|
25906
|
+
FeatureFlagManager.prototype._buildContext = function() {
|
|
25907
|
+
return _.extend(
|
|
25908
|
+
{'distinct_id': this.getMpProperty('distinct_id'), 'device_id': this.getMpProperty('$device_id')},
|
|
25909
|
+
this.getConfig(CONFIG_CONTEXT)
|
|
25910
|
+
);
|
|
25911
|
+
};
|
|
25912
|
+
|
|
25913
|
+
FeatureFlagManager.prototype.reset = function() {
|
|
25914
|
+
if (!this.persistence) {
|
|
25915
|
+
return Promise.resolve();
|
|
25916
|
+
}
|
|
25917
|
+
|
|
25918
|
+
this.flags = null;
|
|
25919
|
+
this.pendingFirstTimeEvents = {};
|
|
25920
|
+
this.activatedFirstTimeEvents = {};
|
|
25921
|
+
this.trackedFeatures = new Set();
|
|
25922
|
+
this.fetchPromise = null;
|
|
25923
|
+
this._fetchInProgressStartTime = null;
|
|
25924
|
+
this._loadedPersistedAtMs = null;
|
|
25925
|
+
this._loadedTtlMs = null;
|
|
25926
|
+
|
|
25927
|
+
return this.persistence.clear().then(_.bind(function() {
|
|
25928
|
+
return this.fetchFlags();
|
|
25929
|
+
}, this)).catch(function() {
|
|
25930
|
+
logger$1.error('Error during flags reset');
|
|
25931
|
+
});
|
|
25673
25932
|
};
|
|
25674
25933
|
|
|
25675
25934
|
FeatureFlagManager.prototype.getFullConfig = function() {
|
|
@@ -25726,12 +25985,11 @@
|
|
|
25726
25985
|
return Promise.resolve();
|
|
25727
25986
|
}
|
|
25728
25987
|
|
|
25729
|
-
var
|
|
25730
|
-
var
|
|
25988
|
+
var context = this._buildContext();
|
|
25989
|
+
var distinctId = context['distinct_id'];
|
|
25731
25990
|
var traceparent = generateTraceparent();
|
|
25732
25991
|
logger$1.log('Fetching flags for distinct ID: ' + distinctId);
|
|
25733
25992
|
|
|
25734
|
-
var context = _.extend({'distinct_id': distinctId, 'device_id': deviceId}, this.getConfig(CONFIG_CONTEXT));
|
|
25735
25993
|
var searchParams = new URLSearchParams();
|
|
25736
25994
|
searchParams.set('context', JSON.stringify(context));
|
|
25737
25995
|
searchParams.set('token', this.getMpConfig('token'));
|
|
@@ -25781,7 +26039,8 @@
|
|
|
25781
26039
|
'value': data['variant_value'],
|
|
25782
26040
|
'experiment_id': data['experiment_id'],
|
|
25783
26041
|
'is_experiment_active': data['is_experiment_active'],
|
|
25784
|
-
'is_qa_tester': data['is_qa_tester']
|
|
26042
|
+
'is_qa_tester': data['is_qa_tester'],
|
|
26043
|
+
'variant_source': 'network'
|
|
25785
26044
|
});
|
|
25786
26045
|
}
|
|
25787
26046
|
}, this);
|
|
@@ -25823,10 +26082,15 @@
|
|
|
25823
26082
|
}
|
|
25824
26083
|
|
|
25825
26084
|
this.flags = flags;
|
|
26085
|
+
this.trackedFeatures = new Set();
|
|
25826
26086
|
this.pendingFirstTimeEvents = pendingFirstTimeEvents;
|
|
26087
|
+
this._loadedPersistedAtMs = null;
|
|
26088
|
+
this._loadedTtlMs = null;
|
|
25827
26089
|
this._traceparent = traceparent;
|
|
25828
26090
|
|
|
25829
26091
|
this._loadTargetingIfNeeded();
|
|
26092
|
+
|
|
26093
|
+
this.persistence.save(context, this.flags, this.pendingFirstTimeEvents);
|
|
25830
26094
|
}.bind(this)).catch(function(error) {
|
|
25831
26095
|
if (this._fetchInProgressStartTime) {
|
|
25832
26096
|
this.markFetchComplete();
|
|
@@ -25986,6 +26250,7 @@
|
|
|
25986
26250
|
};
|
|
25987
26251
|
|
|
25988
26252
|
this.flags.set(flagKey, newVariant);
|
|
26253
|
+
this.trackedFeatures.delete(flagKey);
|
|
25989
26254
|
this.activatedFirstTimeEvents[eventKey] = true;
|
|
25990
26255
|
|
|
25991
26256
|
this.recordFirstTimeEvent(
|
|
@@ -26035,35 +26300,106 @@
|
|
|
26035
26300
|
};
|
|
26036
26301
|
|
|
26037
26302
|
FeatureFlagManager.prototype.getVariant = function(featureName, fallback) {
|
|
26038
|
-
if (!this.
|
|
26303
|
+
if (!this.persistenceLoadedPromise) {
|
|
26039
26304
|
return new Promise(function(resolve) {
|
|
26040
26305
|
logger$1.critical('Feature Flags not initialized');
|
|
26041
|
-
resolve(fallback);
|
|
26306
|
+
resolve(withFallbackSource(fallback));
|
|
26042
26307
|
});
|
|
26043
26308
|
}
|
|
26044
26309
|
|
|
26045
|
-
|
|
26046
|
-
|
|
26047
|
-
|
|
26048
|
-
|
|
26049
|
-
|
|
26050
|
-
|
|
26310
|
+
var policy = this.persistence.getPolicy();
|
|
26311
|
+
|
|
26312
|
+
return this.persistenceLoadedPromise.then(_.bind(function() {
|
|
26313
|
+
// Serve from persistence until the network completes a successful fetch. If a non-expired cached value is available, return it without waiting on the in-flight fetch.
|
|
26314
|
+
if (policy === VariantLookupPolicy.PERSISTENCE_UNTIL_NETWORK_SUCCESS) {
|
|
26315
|
+
if (this.areFlagsReady() && !this._loadedPersistenceIsStale()) {
|
|
26316
|
+
return this.getVariantSync(featureName, fallback);
|
|
26317
|
+
}
|
|
26318
|
+
if (!this.fetchPromise) {
|
|
26319
|
+
return withFallbackSource(fallback);
|
|
26320
|
+
}
|
|
26321
|
+
return this.fetchPromise.then(_.bind(function() {
|
|
26322
|
+
return this.getVariantSync(featureName, fallback);
|
|
26323
|
+
}, this)).catch(function(error) {
|
|
26324
|
+
logger$1.error(error);
|
|
26325
|
+
return withFallbackSource(fallback);
|
|
26326
|
+
});
|
|
26327
|
+
}
|
|
26328
|
+
|
|
26329
|
+
var serve = _.bind(function() { return this.getVariantSync(featureName, fallback); }, this);
|
|
26330
|
+
if (!this.fetchPromise) {
|
|
26331
|
+
return withFallbackSource(fallback);
|
|
26332
|
+
}
|
|
26333
|
+
return this.fetchPromise.then(serve).catch(serve);
|
|
26334
|
+
}, this));
|
|
26335
|
+
};
|
|
26336
|
+
|
|
26337
|
+
FeatureFlagManager.prototype._loadedPersistenceIsStale = function() {
|
|
26338
|
+
if (!this._loadedPersistedAtMs || !this._loadedTtlMs) {
|
|
26339
|
+
return false;
|
|
26340
|
+
}
|
|
26341
|
+
return Date.now() - this._loadedPersistedAtMs >= this._loadedTtlMs;
|
|
26051
26342
|
};
|
|
26052
26343
|
|
|
26053
26344
|
FeatureFlagManager.prototype.getVariantSync = function(featureName, fallback) {
|
|
26345
|
+
if (this._loadedPersistenceIsStale()) {
|
|
26346
|
+
logger$1.log('Loaded persisted variants are past TTL so returning fallback for "' + featureName + '"');
|
|
26347
|
+
return withFallbackSource(fallback);
|
|
26348
|
+
}
|
|
26054
26349
|
if (!this.areFlagsReady()) {
|
|
26055
26350
|
logger$1.log('Flags not loaded yet');
|
|
26056
|
-
return fallback;
|
|
26351
|
+
return withFallbackSource(fallback);
|
|
26057
26352
|
}
|
|
26058
26353
|
var feature = this.flags.get(featureName);
|
|
26059
26354
|
if (!feature) {
|
|
26060
26355
|
logger$1.log('No flag found: "' + featureName + '"');
|
|
26061
|
-
return fallback;
|
|
26356
|
+
return withFallbackSource(fallback);
|
|
26062
26357
|
}
|
|
26063
26358
|
this.trackFeatureCheck(featureName, feature);
|
|
26064
26359
|
return feature;
|
|
26065
26360
|
};
|
|
26066
26361
|
|
|
26362
|
+
FeatureFlagManager.prototype.getAllVariants = function() {
|
|
26363
|
+
if (!this.persistenceLoadedPromise) {
|
|
26364
|
+
logger$1.critical('Feature Flags not initialized');
|
|
26365
|
+
return Promise.resolve(new Map());
|
|
26366
|
+
}
|
|
26367
|
+
|
|
26368
|
+
var policy = this.persistence.getPolicy();
|
|
26369
|
+
|
|
26370
|
+
return this.persistenceLoadedPromise.then(_.bind(function() {
|
|
26371
|
+
// Serve from persistence until the network completes a successful fetch. If a non-expired cached value is available, return it without waiting on the in-flight fetch.
|
|
26372
|
+
if (policy === VariantLookupPolicy.PERSISTENCE_UNTIL_NETWORK_SUCCESS) {
|
|
26373
|
+
if (this.areFlagsReady() && !this._loadedPersistenceIsStale()) {
|
|
26374
|
+
return this.getAllVariantsSync();
|
|
26375
|
+
}
|
|
26376
|
+
if (!this.fetchPromise) {
|
|
26377
|
+
return new Map();
|
|
26378
|
+
}
|
|
26379
|
+
return this.fetchPromise.then(_.bind(function() {
|
|
26380
|
+
return this.getAllVariantsSync();
|
|
26381
|
+
}, this)).catch(function(error) {
|
|
26382
|
+
logger$1.error(error);
|
|
26383
|
+
return new Map();
|
|
26384
|
+
});
|
|
26385
|
+
}
|
|
26386
|
+
|
|
26387
|
+
var serve = _.bind(this.getAllVariantsSync, this);
|
|
26388
|
+
if (!this.fetchPromise) {
|
|
26389
|
+
return new Map();
|
|
26390
|
+
}
|
|
26391
|
+
return this.fetchPromise.then(serve).catch(serve);
|
|
26392
|
+
}, this));
|
|
26393
|
+
};
|
|
26394
|
+
|
|
26395
|
+
FeatureFlagManager.prototype.getAllVariantsSync = function() {
|
|
26396
|
+
if (this._loadedPersistenceIsStale()) {
|
|
26397
|
+
logger$1.log('Loaded persisted variants are past TTL so returning empty Map');
|
|
26398
|
+
return new Map();
|
|
26399
|
+
}
|
|
26400
|
+
return this.flags || new Map();
|
|
26401
|
+
};
|
|
26402
|
+
|
|
26067
26403
|
FeatureFlagManager.prototype.getVariantValue = function(featureName, fallbackValue) {
|
|
26068
26404
|
return this.getVariant(featureName, {'value': fallbackValue}).then(function(feature) {
|
|
26069
26405
|
return feature['value'];
|
|
@@ -26102,6 +26438,10 @@
|
|
|
26102
26438
|
return val;
|
|
26103
26439
|
};
|
|
26104
26440
|
|
|
26441
|
+
function isPresent(v) {
|
|
26442
|
+
return v !== undefined && v !== null;
|
|
26443
|
+
}
|
|
26444
|
+
|
|
26105
26445
|
FeatureFlagManager.prototype.trackFeatureCheck = function(featureName, feature) {
|
|
26106
26446
|
if (this.trackedFeatures.has(featureName)) {
|
|
26107
26447
|
return;
|
|
@@ -26112,21 +26452,30 @@
|
|
|
26112
26452
|
'Experiment name': featureName,
|
|
26113
26453
|
'Variant name': feature['key'],
|
|
26114
26454
|
'$experiment_type': 'feature_flag',
|
|
26115
|
-
'Variant fetch start time': new Date(this._fetchStartTime).toISOString(),
|
|
26116
|
-
'Variant fetch complete time': new Date(this._fetchCompleteTime).toISOString(),
|
|
26455
|
+
'Variant fetch start time': isPresent(this._fetchStartTime) ? new Date(this._fetchStartTime).toISOString() : null,
|
|
26456
|
+
'Variant fetch complete time': isPresent(this._fetchCompleteTime) ? new Date(this._fetchCompleteTime).toISOString() : null,
|
|
26117
26457
|
'Variant fetch latency (ms)': this._fetchLatency,
|
|
26118
26458
|
'Variant fetch traceparent': this._traceparent,
|
|
26119
26459
|
};
|
|
26120
26460
|
|
|
26121
|
-
if (feature['experiment_id']
|
|
26461
|
+
if (isPresent(feature['experiment_id'])) {
|
|
26122
26462
|
trackingProperties['$experiment_id'] = feature['experiment_id'];
|
|
26123
26463
|
}
|
|
26124
|
-
if (feature['is_experiment_active']
|
|
26464
|
+
if (isPresent(feature['is_experiment_active'])) {
|
|
26125
26465
|
trackingProperties['$is_experiment_active'] = feature['is_experiment_active'];
|
|
26126
26466
|
}
|
|
26127
|
-
if (feature['is_qa_tester']
|
|
26467
|
+
if (isPresent(feature['is_qa_tester'])) {
|
|
26128
26468
|
trackingProperties['$is_qa_tester'] = feature['is_qa_tester'];
|
|
26129
26469
|
}
|
|
26470
|
+
if (isPresent(feature['variant_source'])) {
|
|
26471
|
+
trackingProperties['$variant_source'] = feature['variant_source'];
|
|
26472
|
+
}
|
|
26473
|
+
if (isPresent(feature['persisted_at_in_ms'])) {
|
|
26474
|
+
trackingProperties['$persisted_at_in_ms'] = feature['persisted_at_in_ms'];
|
|
26475
|
+
}
|
|
26476
|
+
if (isPresent(feature['ttl_in_ms'])) {
|
|
26477
|
+
trackingProperties['$ttl_in_ms'] = feature['ttl_in_ms'];
|
|
26478
|
+
}
|
|
26130
26479
|
|
|
26131
26480
|
this.track('$experiment_started', trackingProperties);
|
|
26132
26481
|
};
|
|
@@ -26150,6 +26499,8 @@
|
|
|
26150
26499
|
FeatureFlagManager.prototype['are_flags_ready'] = FeatureFlagManager.prototype.areFlagsReady;
|
|
26151
26500
|
FeatureFlagManager.prototype['get_variant'] = FeatureFlagManager.prototype.getVariant;
|
|
26152
26501
|
FeatureFlagManager.prototype['get_variant_sync'] = FeatureFlagManager.prototype.getVariantSync;
|
|
26502
|
+
FeatureFlagManager.prototype['get_all_variants'] = FeatureFlagManager.prototype.getAllVariants;
|
|
26503
|
+
FeatureFlagManager.prototype['get_all_variants_sync'] = FeatureFlagManager.prototype.getAllVariantsSync;
|
|
26153
26504
|
FeatureFlagManager.prototype['get_variant_value'] = FeatureFlagManager.prototype.getVariantValue;
|
|
26154
26505
|
FeatureFlagManager.prototype['get_variant_value_sync'] = FeatureFlagManager.prototype.getVariantValueSync;
|
|
26155
26506
|
FeatureFlagManager.prototype['is_enabled'] = FeatureFlagManager.prototype.isEnabled;
|
|
@@ -26202,7 +26553,7 @@
|
|
|
26202
26553
|
return PromisePolyfill.resolve(false);
|
|
26203
26554
|
}
|
|
26204
26555
|
|
|
26205
|
-
var recording_registry_idb = new IDBStorageWrapper(RECORDING_REGISTRY_STORE_NAME);
|
|
26556
|
+
var recording_registry_idb = new IDBStorageWrapper(MIXPANEL_BROWSER_DB_NAME, RECORDING_REGISTRY_STORE_NAME, RECORDER_VERSION_DATA);
|
|
26206
26557
|
var tab_id = this.getTabId();
|
|
26207
26558
|
return recording_registry_idb.init()
|
|
26208
26559
|
.then(function () {
|
|
@@ -28129,6 +28480,7 @@
|
|
|
28129
28480
|
'disable_all_events': false,
|
|
28130
28481
|
'identify_called': false
|
|
28131
28482
|
};
|
|
28483
|
+
this._remote_settings_strict_disabled = false;
|
|
28132
28484
|
|
|
28133
28485
|
// set up request queueing/batching
|
|
28134
28486
|
this.request_batchers = {};
|
|
@@ -28203,9 +28555,6 @@
|
|
|
28203
28555
|
this.flags.init();
|
|
28204
28556
|
this['flags'] = this.flags;
|
|
28205
28557
|
|
|
28206
|
-
this.autocapture = new Autocapture(this);
|
|
28207
|
-
this.autocapture.init();
|
|
28208
|
-
|
|
28209
28558
|
this._init_tab_id();
|
|
28210
28559
|
|
|
28211
28560
|
// Based on remote_settings_mode, fetch remote settings and then start session recording if applicable
|
|
@@ -28217,6 +28566,9 @@
|
|
|
28217
28566
|
} else {
|
|
28218
28567
|
this.__session_recording_init_promise = this._check_and_start_session_recording();
|
|
28219
28568
|
}
|
|
28569
|
+
|
|
28570
|
+
this.autocapture = new Autocapture(this);
|
|
28571
|
+
this.autocapture.init();
|
|
28220
28572
|
};
|
|
28221
28573
|
|
|
28222
28574
|
/**
|
|
@@ -28263,9 +28615,19 @@
|
|
|
28263
28615
|
return this.recorderManager.checkAndStartSessionRecording(force_start);
|
|
28264
28616
|
});
|
|
28265
28617
|
|
|
28266
|
-
MixpanelLib.prototype._start_recording_on_event = function(event_name, properties) {
|
|
28267
|
-
|
|
28268
|
-
|
|
28618
|
+
MixpanelLib.prototype._start_recording_on_event = safewrap(function(event_name, properties) {
|
|
28619
|
+
// Wait for recording init to complete before evaluating event triggers.
|
|
28620
|
+
// This ensures recording_event_triggers config is fully loaded when remote settings are used.
|
|
28621
|
+
if (this.__session_recording_init_promise) {
|
|
28622
|
+
this.__session_recording_init_promise.then(_.bind(function() {
|
|
28623
|
+
// In strict mode, skip recording if remote settings failed
|
|
28624
|
+
if (this._remote_settings_strict_disabled) {
|
|
28625
|
+
return;
|
|
28626
|
+
}
|
|
28627
|
+
return this.recorderManager.startRecordingOnEvent(event_name, properties);
|
|
28628
|
+
}, this));
|
|
28629
|
+
}
|
|
28630
|
+
});
|
|
28269
28631
|
|
|
28270
28632
|
MixpanelLib.prototype.start_session_recording = function () {
|
|
28271
28633
|
return this._check_and_start_session_recording(true);
|
|
@@ -28564,6 +28926,7 @@
|
|
|
28564
28926
|
var disableRecordingIfStrict = function() {
|
|
28565
28927
|
if (mode === 'strict') {
|
|
28566
28928
|
self.set_config({'record_sessions_percent': 0});
|
|
28929
|
+
self._remote_settings_strict_disabled = true;
|
|
28567
28930
|
}
|
|
28568
28931
|
};
|
|
28569
28932
|
|
|
@@ -29189,6 +29552,10 @@
|
|
|
29189
29552
|
properties
|
|
29190
29553
|
);
|
|
29191
29554
|
|
|
29555
|
+
if (this.is_recording_heatmap_data()) {
|
|
29556
|
+
event_properties['$captured_for_heatmap'] = true;
|
|
29557
|
+
}
|
|
29558
|
+
|
|
29192
29559
|
return this.track(event_name, event_properties);
|
|
29193
29560
|
});
|
|
29194
29561
|
|
|
@@ -29532,6 +29899,7 @@
|
|
|
29532
29899
|
'$device_id': uuid
|
|
29533
29900
|
}, '');
|
|
29534
29901
|
this._check_and_start_session_recording();
|
|
29902
|
+
this.flags.reset();
|
|
29535
29903
|
};
|
|
29536
29904
|
|
|
29537
29905
|
/**
|