@dotcms/experiments 1.5.5-next.2293 → 1.5.5-next.2303
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/index.esm.js +14 -105
- package/package.json +1 -1
- package/src/index.d.ts +1 -0
- package/src/lib/components/DotExperimentHandlingComponent.d.ts +20 -0
- package/src/lib/components/DotExperimentsProvider.d.ts +17 -0
- package/src/lib/components/withExperiments.d.ts +20 -0
- package/src/lib/contexts/DotExperimentsContext.d.ts +12 -0
- package/src/lib/dot-experiments.d.ts +289 -0
- package/src/lib/hooks/useExperimentVariant.d.ts +17 -0
- package/src/lib/hooks/useExperiments.d.ts +14 -0
- package/src/lib/shared/constants.d.ts +95 -0
- package/src/lib/shared/mocks/mock.d.ts +43 -0
- package/src/lib/shared/models.d.ts +209 -0
- package/src/lib/shared/parser/parser.d.ts +54 -0
- package/src/lib/shared/persistence/index-db-database-handler.d.ts +87 -0
- package/src/lib/shared/utils/DotLogger.d.ts +15 -0
- package/src/lib/shared/utils/memoize.d.ts +7 -0
- package/src/lib/shared/utils/utils.d.ts +73 -0
- package/src/lib/standalone.d.ts +7 -0
package/index.esm.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
1
2
|
import { createContext, useContext, useState, useEffect, useRef, useCallback } from 'react';
|
|
2
3
|
import { UVE_MODE } from '@dotcms/types';
|
|
3
4
|
import { getUVEState } from '@dotcms/uve';
|
|
4
|
-
import { jsx } from 'react/jsx-runtime';
|
|
5
5
|
import { jitsuClient } from '@jitsu/sdk-js';
|
|
6
6
|
|
|
7
7
|
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
|
|
@@ -562,6 +562,7 @@ var PROPER = EXISTS && (function something() { /* empty */ }).name === 'somethin
|
|
|
562
562
|
var CONFIGURABLE = EXISTS && (!DESCRIPTORS$f || (DESCRIPTORS$f && getDescriptor(FunctionPrototype$1, 'name').configurable));
|
|
563
563
|
|
|
564
564
|
var functionName = {
|
|
565
|
+
EXISTS: EXISTS,
|
|
565
566
|
PROPER: PROPER,
|
|
566
567
|
CONFIGURABLE: CONFIGURABLE
|
|
567
568
|
};
|
|
@@ -1664,7 +1665,6 @@ const useExperimentVariant = data => {
|
|
|
1664
1665
|
viewAs
|
|
1665
1666
|
} = data;
|
|
1666
1667
|
const variantId = viewAs == null ? void 0 : viewAs.variantId;
|
|
1667
|
-
|
|
1668
1668
|
// By default, wait for the variant
|
|
1669
1669
|
const [shouldWaitForVariant, setShouldWaitForVariant] = useState(true);
|
|
1670
1670
|
useEffect(() => {
|
|
@@ -1674,10 +1674,8 @@ const useExperimentVariant = data => {
|
|
|
1674
1674
|
setShouldWaitForVariant(false);
|
|
1675
1675
|
return;
|
|
1676
1676
|
}
|
|
1677
|
-
|
|
1678
1677
|
// If variantId is not provided, show content and warn
|
|
1679
1678
|
if (!variantId) {
|
|
1680
|
-
// eslint-disable-next-line no-console
|
|
1681
1679
|
console.warn('[DotExperiments] variantId is required but missing. ' + 'Please ensure the page data includes variantId in viewAs. ' + 'Showing content to prevent blank screen.');
|
|
1682
1680
|
setShouldWaitForVariant(false);
|
|
1683
1681
|
return;
|
|
@@ -1721,14 +1719,14 @@ const DotExperimentHandlingComponent = _ref => {
|
|
|
1721
1719
|
shouldWaitForVariant
|
|
1722
1720
|
} = useExperimentVariant(props.page);
|
|
1723
1721
|
if (shouldWaitForVariant) {
|
|
1724
|
-
return
|
|
1722
|
+
return jsx("div", {
|
|
1725
1723
|
style: {
|
|
1726
1724
|
visibility: 'hidden'
|
|
1727
1725
|
},
|
|
1728
|
-
children:
|
|
1726
|
+
children: jsx(WrappedComponent, Object.assign({}, props))
|
|
1729
1727
|
});
|
|
1730
1728
|
}
|
|
1731
|
-
return
|
|
1729
|
+
return jsx(WrappedComponent, Object.assign({}, props));
|
|
1732
1730
|
};
|
|
1733
1731
|
|
|
1734
1732
|
var NATIVE_BIND$1 = functionBindNative;
|
|
@@ -2383,7 +2381,9 @@ if (!set || !clear) {
|
|
|
2383
2381
|
}
|
|
2384
2382
|
|
|
2385
2383
|
var task$1 = {
|
|
2386
|
-
set: set
|
|
2384
|
+
set: set,
|
|
2385
|
+
clear: clear
|
|
2386
|
+
};
|
|
2387
2387
|
|
|
2388
2388
|
var global$c = global$q;
|
|
2389
2389
|
var DESCRIPTORS$8 = descriptors;
|
|
@@ -4281,7 +4281,6 @@ if (DESCRIPTORS$3 && !('size' in URLSearchParamsPrototype)) {
|
|
|
4281
4281
|
*
|
|
4282
4282
|
* @constant {string}
|
|
4283
4283
|
*/
|
|
4284
|
-
|
|
4285
4284
|
/**
|
|
4286
4285
|
* The default variant name for an experiment.
|
|
4287
4286
|
*
|
|
@@ -4289,14 +4288,12 @@ if (DESCRIPTORS$3 && !('size' in URLSearchParamsPrototype)) {
|
|
|
4289
4288
|
* @constant
|
|
4290
4289
|
*/
|
|
4291
4290
|
const EXPERIMENT_DEFAULT_VARIANT_NAME = 'DEFAULT';
|
|
4292
|
-
|
|
4293
4291
|
/**
|
|
4294
4292
|
* The key used to store or retrieve the information in the SessionStore
|
|
4295
4293
|
*
|
|
4296
4294
|
* @constant {string}
|
|
4297
4295
|
*/
|
|
4298
4296
|
const EXPERIMENT_QUERY_PARAM_KEY = 'variantName';
|
|
4299
|
-
|
|
4300
4297
|
/**
|
|
4301
4298
|
* The key used to store or retrieve the information in the SessionStore
|
|
4302
4299
|
* indicating whether an experiment has already been checked.
|
|
@@ -4304,7 +4301,6 @@ const EXPERIMENT_QUERY_PARAM_KEY = 'variantName';
|
|
|
4304
4301
|
* @constant {string}
|
|
4305
4302
|
*/
|
|
4306
4303
|
const EXPERIMENT_ALREADY_CHECKED_KEY = 'experimentAlreadyCheck';
|
|
4307
|
-
|
|
4308
4304
|
/**
|
|
4309
4305
|
* EXPERIMENT_FETCH_EXPIRE_TIME is a constant that represents the name of the variable used to store
|
|
4310
4306
|
* the expire time for experiment fetching. It is a string value 'experimentFetchExpireTime'.
|
|
@@ -4312,7 +4308,6 @@ const EXPERIMENT_ALREADY_CHECKED_KEY = 'experimentAlreadyCheck';
|
|
|
4312
4308
|
* @constant {string}
|
|
4313
4309
|
*/
|
|
4314
4310
|
const EXPERIMENT_FETCH_EXPIRE_TIME_KEY = 'experimentFetchExpireTime';
|
|
4315
|
-
|
|
4316
4311
|
/**
|
|
4317
4312
|
* The duration in milliseconds for which data should be stored in the local storage.
|
|
4318
4313
|
*
|
|
@@ -4322,7 +4317,6 @@ const EXPERIMENT_FETCH_EXPIRE_TIME_KEY = 'experimentFetchExpireTime';
|
|
|
4322
4317
|
*
|
|
4323
4318
|
*/
|
|
4324
4319
|
const LOCAL_STORAGE_TIME_DURATION_MILLISECONDS = 86400 * 1000;
|
|
4325
|
-
|
|
4326
4320
|
/**
|
|
4327
4321
|
* API_EXPERIMENTS_URL
|
|
4328
4322
|
*
|
|
@@ -4332,7 +4326,6 @@ const LOCAL_STORAGE_TIME_DURATION_MILLISECONDS = 86400 * 1000;
|
|
|
4332
4326
|
* @constant
|
|
4333
4327
|
*/
|
|
4334
4328
|
const API_EXPERIMENTS_URL = 'api/v1/experiments/isUserIncluded';
|
|
4335
|
-
|
|
4336
4329
|
/**
|
|
4337
4330
|
* The name of the experiment database store in indexDB.
|
|
4338
4331
|
*
|
|
@@ -4340,26 +4333,24 @@ const API_EXPERIMENTS_URL = 'api/v1/experiments/isUserIncluded';
|
|
|
4340
4333
|
* @constant
|
|
4341
4334
|
*/
|
|
4342
4335
|
const EXPERIMENT_DB_STORE_NAME = 'dotExperimentStore';
|
|
4343
|
-
|
|
4344
4336
|
/**
|
|
4345
4337
|
* The path to the key in the database IndexDB representing the running experiment data.
|
|
4346
4338
|
* @type {string}
|
|
4347
4339
|
*/
|
|
4348
4340
|
const EXPERIMENT_DB_KEY_PATH = 'running_experiment';
|
|
4349
|
-
|
|
4350
4341
|
/**
|
|
4351
4342
|
* Enumeration of debug levels.
|
|
4352
4343
|
*
|
|
4353
4344
|
* @enum {string}
|
|
4354
4345
|
* @readonly
|
|
4355
4346
|
*/
|
|
4356
|
-
|
|
4347
|
+
var DEBUG_LEVELS;
|
|
4348
|
+
(function (DEBUG_LEVELS) {
|
|
4357
4349
|
DEBUG_LEVELS["NONE"] = "NONE";
|
|
4358
4350
|
DEBUG_LEVELS["DEBUG"] = "DEBUG";
|
|
4359
4351
|
DEBUG_LEVELS["WARN"] = "WARN";
|
|
4360
4352
|
DEBUG_LEVELS["ERROR"] = "ERROR";
|
|
4361
|
-
|
|
4362
|
-
}({});
|
|
4353
|
+
})(DEBUG_LEVELS || (DEBUG_LEVELS = {}));
|
|
4363
4354
|
const PAGE_VIEW_EVENT_NAME = 'pageview';
|
|
4364
4355
|
|
|
4365
4356
|
var $$6 = _export;
|
|
@@ -6280,7 +6271,6 @@ const parseDataForAnalytics = (experiments, location) => {
|
|
|
6280
6271
|
}))
|
|
6281
6272
|
};
|
|
6282
6273
|
};
|
|
6283
|
-
|
|
6284
6274
|
/**
|
|
6285
6275
|
* This utility function performs regular expression (regex) matching on a supplied URL.
|
|
6286
6276
|
*
|
|
@@ -6302,7 +6292,6 @@ const verifyRegex = (regexToCheck, href) => {
|
|
|
6302
6292
|
return false;
|
|
6303
6293
|
}
|
|
6304
6294
|
};
|
|
6305
|
-
|
|
6306
6295
|
/**
|
|
6307
6296
|
* This function merges newly fetched data with the data stored from IndexedDB, preparing it for re-storage in IndexedDB.
|
|
6308
6297
|
*
|
|
@@ -6342,7 +6331,6 @@ const parseData = (fetchExperiments, storedExperiments) => {
|
|
|
6342
6331
|
}
|
|
6343
6332
|
return dataToStorage;
|
|
6344
6333
|
};
|
|
6345
|
-
|
|
6346
6334
|
/**
|
|
6347
6335
|
* Retrieves the array of experiment IDs from the given AssignedExperiments..
|
|
6348
6336
|
*
|
|
@@ -6350,7 +6338,6 @@ const parseData = (fetchExperiments, storedExperiments) => {
|
|
|
6350
6338
|
* @param experiments
|
|
6351
6339
|
*/
|
|
6352
6340
|
const getExperimentsIds = experiments => experiments.map(experiment => experiment.id) || [];
|
|
6353
|
-
|
|
6354
6341
|
/**
|
|
6355
6342
|
* Sets the expire time for new experiments based on the current time.
|
|
6356
6343
|
* The expire time is calculated by adding the expireMillis value of each experiment's lookBackWindow to the current time (Date.now()).
|
|
@@ -6366,7 +6353,6 @@ const addExpireTimeToExperiments = experiments => {
|
|
|
6366
6353
|
})
|
|
6367
6354
|
}));
|
|
6368
6355
|
};
|
|
6369
|
-
|
|
6370
6356
|
/**
|
|
6371
6357
|
* Returns an array of experiments that have not expired yet.
|
|
6372
6358
|
*
|
|
@@ -6383,11 +6369,6 @@ const getUnexpiredExperiments = (experiments, excludedExperimentIdsEnded) => {
|
|
|
6383
6369
|
});
|
|
6384
6370
|
};
|
|
6385
6371
|
|
|
6386
|
-
/**
|
|
6387
|
-
* Represents the configuration for a database connection.
|
|
6388
|
-
* @interface
|
|
6389
|
-
*/
|
|
6390
|
-
|
|
6391
6372
|
/**
|
|
6392
6373
|
* The default version of the database.
|
|
6393
6374
|
*
|
|
@@ -6395,7 +6376,6 @@ const getUnexpiredExperiments = (experiments, excludedExperimentIdsEnded) => {
|
|
|
6395
6376
|
* @constant
|
|
6396
6377
|
*/
|
|
6397
6378
|
const DB_DEFAULT_VERSION = 1;
|
|
6398
|
-
|
|
6399
6379
|
/**
|
|
6400
6380
|
* The `DatabaseHandler` class offers specific methods to store and get data
|
|
6401
6381
|
* from IndexedDB.
|
|
@@ -6413,7 +6393,6 @@ const DB_DEFAULT_VERSION = 1;
|
|
|
6413
6393
|
* await DatabaseHandler.persistData(anAssignedExperiment);
|
|
6414
6394
|
*
|
|
6415
6395
|
*/
|
|
6416
|
-
|
|
6417
6396
|
class IndexDBDatabaseHandler {
|
|
6418
6397
|
constructor(config) {
|
|
6419
6398
|
this.config = config;
|
|
@@ -6435,7 +6414,6 @@ class IndexDBDatabaseHandler {
|
|
|
6435
6414
|
throw new Error("'db_key_path' is required in config");
|
|
6436
6415
|
}
|
|
6437
6416
|
}
|
|
6438
|
-
|
|
6439
6417
|
/**
|
|
6440
6418
|
* Saves the provided data to indexDB.
|
|
6441
6419
|
*
|
|
@@ -6457,7 +6435,6 @@ class IndexDBDatabaseHandler {
|
|
|
6457
6435
|
};
|
|
6458
6436
|
});
|
|
6459
6437
|
}
|
|
6460
|
-
|
|
6461
6438
|
/**
|
|
6462
6439
|
* Retrieves data from the database using a specific key.
|
|
6463
6440
|
*
|
|
@@ -6474,7 +6451,6 @@ class IndexDBDatabaseHandler {
|
|
|
6474
6451
|
request.onerror = () => reject(request.error);
|
|
6475
6452
|
});
|
|
6476
6453
|
}
|
|
6477
|
-
|
|
6478
6454
|
/**
|
|
6479
6455
|
* Deletes all the data from the IndexedDB store.
|
|
6480
6456
|
*
|
|
@@ -6491,7 +6467,6 @@ class IndexDBDatabaseHandler {
|
|
|
6491
6467
|
request.onerror = () => reject(request.error);
|
|
6492
6468
|
});
|
|
6493
6469
|
}
|
|
6494
|
-
|
|
6495
6470
|
/**
|
|
6496
6471
|
* Sets the flag indicating that the experiment has already been checked.
|
|
6497
6472
|
*
|
|
@@ -6501,7 +6476,6 @@ class IndexDBDatabaseHandler {
|
|
|
6501
6476
|
setFlagExperimentAlreadyChecked() {
|
|
6502
6477
|
sessionStorage.setItem(EXPERIMENT_ALREADY_CHECKED_KEY, 'true');
|
|
6503
6478
|
}
|
|
6504
|
-
|
|
6505
6479
|
/**
|
|
6506
6480
|
* Sets the fetch expired time in the local storage.
|
|
6507
6481
|
*
|
|
@@ -6511,7 +6485,6 @@ class IndexDBDatabaseHandler {
|
|
|
6511
6485
|
const expireTime = Date.now() + LOCAL_STORAGE_TIME_DURATION_MILLISECONDS;
|
|
6512
6486
|
localStorage.setItem(EXPERIMENT_FETCH_EXPIRE_TIME_KEY, expireTime.toString());
|
|
6513
6487
|
}
|
|
6514
|
-
|
|
6515
6488
|
/**
|
|
6516
6489
|
* Builds an error message based on the provided error object.
|
|
6517
6490
|
* @param {DOMException | null} error - The error object to build the message from.
|
|
@@ -6526,7 +6499,6 @@ class IndexDBDatabaseHandler {
|
|
|
6526
6499
|
}
|
|
6527
6500
|
return errorMessage;
|
|
6528
6501
|
}
|
|
6529
|
-
|
|
6530
6502
|
/**
|
|
6531
6503
|
* Creates or opens a IndexedDB database with the specified version.
|
|
6532
6504
|
*
|
|
@@ -6553,7 +6525,6 @@ class IndexDBDatabaseHandler {
|
|
|
6553
6525
|
};
|
|
6554
6526
|
});
|
|
6555
6527
|
}
|
|
6556
|
-
|
|
6557
6528
|
/**
|
|
6558
6529
|
* Retrieves the result of a database request from an Event object.
|
|
6559
6530
|
*
|
|
@@ -6570,8 +6541,6 @@ class IndexDBDatabaseHandler {
|
|
|
6570
6541
|
*/
|
|
6571
6542
|
class DotLogger {
|
|
6572
6543
|
constructor(isDebug, packageName) {
|
|
6573
|
-
this.isDebug = void 0;
|
|
6574
|
-
this.packageName = void 0;
|
|
6575
6544
|
this.isDebug = isDebug;
|
|
6576
6545
|
this.packageName = packageName;
|
|
6577
6546
|
}
|
|
@@ -6625,7 +6594,6 @@ const checkFlagExperimentAlreadyChecked = () => {
|
|
|
6625
6594
|
const flag = sessionStorage.getItem(EXPERIMENT_ALREADY_CHECKED_KEY);
|
|
6626
6595
|
return flag === 'true';
|
|
6627
6596
|
};
|
|
6628
|
-
|
|
6629
6597
|
/**
|
|
6630
6598
|
* Checks if the data needs to be invalidated based on the creation date.
|
|
6631
6599
|
*
|
|
@@ -6643,7 +6611,6 @@ const isDataCreateValid = () => {
|
|
|
6643
6611
|
return false;
|
|
6644
6612
|
}
|
|
6645
6613
|
};
|
|
6646
|
-
|
|
6647
6614
|
/**
|
|
6648
6615
|
* Ad to an absolute path the baseUrl depending on the location.
|
|
6649
6616
|
*
|
|
@@ -6665,7 +6632,6 @@ const isFullUrl = url => {
|
|
|
6665
6632
|
const pattern = /^https?:\/\//i;
|
|
6666
6633
|
return pattern.test(url);
|
|
6667
6634
|
};
|
|
6668
|
-
|
|
6669
6635
|
/**
|
|
6670
6636
|
* Updates the URL with the queryParam with the experiment variant name.
|
|
6671
6637
|
*
|
|
@@ -6683,7 +6649,6 @@ const updateUrlWithExperimentVariant = (location, variant) => {
|
|
|
6683
6649
|
}
|
|
6684
6650
|
return url.toString();
|
|
6685
6651
|
};
|
|
6686
|
-
|
|
6687
6652
|
/**
|
|
6688
6653
|
* Check if two arrays of Experiment objects are equal.
|
|
6689
6654
|
*
|
|
@@ -6697,7 +6662,6 @@ const objectsAreEqual = (obj1, obj2) => {
|
|
|
6697
6662
|
}
|
|
6698
6663
|
return JSON.stringify(obj1) === JSON.stringify(obj2);
|
|
6699
6664
|
};
|
|
6700
|
-
|
|
6701
6665
|
/**
|
|
6702
6666
|
* A function to redirect the user to a new URL.
|
|
6703
6667
|
*
|
|
@@ -6734,27 +6698,11 @@ class DotExperiments {
|
|
|
6734
6698
|
* @private
|
|
6735
6699
|
*/
|
|
6736
6700
|
this.initializationPromise = null;
|
|
6737
|
-
/**
|
|
6738
|
-
* Represents the analytics client for Analytics.
|
|
6739
|
-
* @private
|
|
6740
|
-
*/
|
|
6741
|
-
this.analytics = void 0;
|
|
6742
|
-
/**
|
|
6743
|
-
* Class representing a database handler for IndexDB.
|
|
6744
|
-
* @class
|
|
6745
|
-
*/
|
|
6746
|
-
this.persistenceHandler = void 0;
|
|
6747
6701
|
/**
|
|
6748
6702
|
* Represents the stored data in the IndexedDB.
|
|
6749
6703
|
* @private
|
|
6750
6704
|
*/
|
|
6751
6705
|
this.experimentsAssigned = [];
|
|
6752
|
-
/**
|
|
6753
|
-
* A logger utility for logging messages.
|
|
6754
|
-
*
|
|
6755
|
-
* @class
|
|
6756
|
-
*/
|
|
6757
|
-
this.logger = void 0;
|
|
6758
6706
|
/**
|
|
6759
6707
|
* Represents the current location.
|
|
6760
6708
|
* @private
|
|
@@ -6777,7 +6725,6 @@ class DotExperiments {
|
|
|
6777
6725
|
}
|
|
6778
6726
|
this.logger = new DotLogger(this.config.debug, 'DotExperiment');
|
|
6779
6727
|
}
|
|
6780
|
-
|
|
6781
6728
|
/**
|
|
6782
6729
|
* Retrieves the array of experiments assigned to an instance of the class.
|
|
6783
6730
|
*
|
|
@@ -6786,7 +6733,6 @@ class DotExperiments {
|
|
|
6786
6733
|
get experiments() {
|
|
6787
6734
|
return this.experimentsAssigned;
|
|
6788
6735
|
}
|
|
6789
|
-
|
|
6790
6736
|
/**
|
|
6791
6737
|
* Returns a custom redirect function. If a custom redirect function is not configured,
|
|
6792
6738
|
* the default redirect function will be used.
|
|
@@ -6798,7 +6744,6 @@ class DotExperiments {
|
|
|
6798
6744
|
var _this$config$redirect;
|
|
6799
6745
|
return (_this$config$redirect = this.config.redirectFn) != null ? _this$config$redirect : defaultRedirectFn;
|
|
6800
6746
|
}
|
|
6801
|
-
|
|
6802
6747
|
/**
|
|
6803
6748
|
* Retrieves the current location.
|
|
6804
6749
|
*
|
|
@@ -6807,7 +6752,6 @@ class DotExperiments {
|
|
|
6807
6752
|
get location() {
|
|
6808
6753
|
return this.currentLocation;
|
|
6809
6754
|
}
|
|
6810
|
-
|
|
6811
6755
|
/**
|
|
6812
6756
|
* Retrieves instance of DotExperiments class if it doesn't exist create a new one.
|
|
6813
6757
|
* If the instance does not exist, it creates a new instance with the provided configuration and calls the `getExperimentData` method.
|
|
@@ -6828,7 +6772,6 @@ class DotExperiments {
|
|
|
6828
6772
|
}
|
|
6829
6773
|
return DotExperiments.instance;
|
|
6830
6774
|
}
|
|
6831
|
-
|
|
6832
6775
|
/**
|
|
6833
6776
|
* Waits for the initialization process to be completed.
|
|
6834
6777
|
*
|
|
@@ -6838,7 +6781,6 @@ class DotExperiments {
|
|
|
6838
6781
|
var _this$initializationP;
|
|
6839
6782
|
return (_this$initializationP = this.initializationPromise) != null ? _this$initializationP : Promise.resolve();
|
|
6840
6783
|
}
|
|
6841
|
-
|
|
6842
6784
|
/**
|
|
6843
6785
|
* This method appends variant parameters to navigation links based on the provided navClass.
|
|
6844
6786
|
*
|
|
@@ -6882,7 +6824,6 @@ class DotExperiments {
|
|
|
6882
6824
|
});
|
|
6883
6825
|
}
|
|
6884
6826
|
}
|
|
6885
|
-
|
|
6886
6827
|
/**
|
|
6887
6828
|
* Retrieves the current debug status.
|
|
6888
6829
|
*
|
|
@@ -6892,7 +6833,6 @@ class DotExperiments {
|
|
|
6892
6833
|
getIsDebugActive() {
|
|
6893
6834
|
return this.config.debug;
|
|
6894
6835
|
}
|
|
6895
|
-
|
|
6896
6836
|
/**
|
|
6897
6837
|
* Updates the current location and checks if a variant should be applied.
|
|
6898
6838
|
* Redirects to the variant URL if necessary.
|
|
@@ -6929,7 +6869,6 @@ class DotExperiments {
|
|
|
6929
6869
|
this.logger.timeEnd('Total location changed');
|
|
6930
6870
|
this.logger.groupEnd();
|
|
6931
6871
|
}
|
|
6932
|
-
|
|
6933
6872
|
/**
|
|
6934
6873
|
* Tracks a page view event in the analytics system.
|
|
6935
6874
|
*
|
|
@@ -6939,7 +6878,6 @@ class DotExperiments {
|
|
|
6939
6878
|
this.track(PAGE_VIEW_EVENT_NAME);
|
|
6940
6879
|
this.prevLocation = this.currentLocation.href;
|
|
6941
6880
|
}
|
|
6942
|
-
|
|
6943
6881
|
/**
|
|
6944
6882
|
* This method is used to retrieve the variant associated with a given URL.
|
|
6945
6883
|
*
|
|
@@ -6958,7 +6896,6 @@ class DotExperiments {
|
|
|
6958
6896
|
});
|
|
6959
6897
|
return (experiment == null ? void 0 : experiment.variant) || null;
|
|
6960
6898
|
}
|
|
6961
|
-
|
|
6962
6899
|
/**
|
|
6963
6900
|
* Returns the experiment variant name as a URL search parameter.
|
|
6964
6901
|
*
|
|
@@ -6981,7 +6918,6 @@ class DotExperiments {
|
|
|
6981
6918
|
}
|
|
6982
6919
|
return new URLSearchParams(params);
|
|
6983
6920
|
}
|
|
6984
|
-
|
|
6985
6921
|
/**
|
|
6986
6922
|
* Determines whether a page view should be tracked.
|
|
6987
6923
|
*
|
|
@@ -6997,7 +6933,6 @@ class DotExperiments {
|
|
|
6997
6933
|
this.logger.log(`No send pageView. No experiments to track.`);
|
|
6998
6934
|
return false;
|
|
6999
6935
|
}
|
|
7000
|
-
|
|
7001
6936
|
// If the previous location is the same as the current location, we don't need to track the page view
|
|
7002
6937
|
if (this.prevLocation === this.currentLocation.href) {
|
|
7003
6938
|
this.logger.log(`No send pageView. Same location.`);
|
|
@@ -7005,7 +6940,6 @@ class DotExperiments {
|
|
|
7005
6940
|
}
|
|
7006
6941
|
return true;
|
|
7007
6942
|
}
|
|
7008
|
-
|
|
7009
6943
|
/**
|
|
7010
6944
|
* Tracks an event using the analytics service.
|
|
7011
6945
|
*
|
|
@@ -7018,7 +6952,6 @@ class DotExperiments {
|
|
|
7018
6952
|
this.logger.log(`${typeName} event sent`);
|
|
7019
6953
|
});
|
|
7020
6954
|
}
|
|
7021
|
-
|
|
7022
6955
|
/**
|
|
7023
6956
|
* Initializes the application using lazy initialization. This method performs
|
|
7024
6957
|
* necessary setup steps and should be invoked to ensure proper execution of the application.
|
|
@@ -7051,7 +6984,6 @@ class DotExperiments {
|
|
|
7051
6984
|
}();
|
|
7052
6985
|
}
|
|
7053
6986
|
}
|
|
7054
|
-
|
|
7055
6987
|
/**
|
|
7056
6988
|
* Fetches experiments from the server.
|
|
7057
6989
|
*
|
|
@@ -7097,7 +7029,6 @@ class DotExperiments {
|
|
|
7097
7029
|
this.logger.groupEnd();
|
|
7098
7030
|
}
|
|
7099
7031
|
}
|
|
7100
|
-
|
|
7101
7032
|
/**
|
|
7102
7033
|
* This method is responsible for retrieving and persisting experiment data from the server to the local indexDB database.
|
|
7103
7034
|
*
|
|
@@ -7120,13 +7051,11 @@ class DotExperiments {
|
|
|
7120
7051
|
experiments: []
|
|
7121
7052
|
};
|
|
7122
7053
|
const storedExperiments = this.experimentsAssigned ? this.experimentsAssigned : [];
|
|
7123
|
-
|
|
7124
7054
|
// Checks whether fetching experiment data from the server is necessary.
|
|
7125
7055
|
if (this.shouldFetchNewData()) {
|
|
7126
7056
|
fetchedExperiments = await this.getExperimentsFromServer();
|
|
7127
7057
|
}
|
|
7128
7058
|
const dataToPersist = parseData(fetchedExperiments, storedExperiments);
|
|
7129
|
-
|
|
7130
7059
|
// If my stored data is equal to my parsed data, I don't need to persist again
|
|
7131
7060
|
if (!objectsAreEqual(dataToPersist, storedExperiments)) {
|
|
7132
7061
|
this.experimentsAssigned = await this.persistExperiments(dataToPersist);
|
|
@@ -7136,7 +7065,6 @@ class DotExperiments {
|
|
|
7136
7065
|
throw Error(`Error persisting experiments to indexDB, ${e}`);
|
|
7137
7066
|
}
|
|
7138
7067
|
}
|
|
7139
|
-
|
|
7140
7068
|
/**
|
|
7141
7069
|
* Persists the parsed experiment data into the indexDB database.
|
|
7142
7070
|
*
|
|
@@ -7175,7 +7103,6 @@ class DotExperiments {
|
|
|
7175
7103
|
this.logger.groupEnd();
|
|
7176
7104
|
}
|
|
7177
7105
|
}
|
|
7178
|
-
|
|
7179
7106
|
/**
|
|
7180
7107
|
* Initializes the database handler.
|
|
7181
7108
|
*
|
|
@@ -7191,7 +7118,6 @@ class DotExperiments {
|
|
|
7191
7118
|
db_key_path: EXPERIMENT_DB_KEY_PATH
|
|
7192
7119
|
});
|
|
7193
7120
|
}
|
|
7194
|
-
|
|
7195
7121
|
/**
|
|
7196
7122
|
* Initializes the Jitsu analytics client.
|
|
7197
7123
|
*
|
|
@@ -7215,7 +7141,6 @@ class DotExperiments {
|
|
|
7215
7141
|
this.logger.log(`Error creating/updating analytics client: ${error}`);
|
|
7216
7142
|
}
|
|
7217
7143
|
}
|
|
7218
|
-
|
|
7219
7144
|
/**
|
|
7220
7145
|
* Updates the analytics client's data using the experiments data
|
|
7221
7146
|
* currently available in the IndexDB database, based on the current location.
|
|
@@ -7244,14 +7169,12 @@ class DotExperiments {
|
|
|
7244
7169
|
});
|
|
7245
7170
|
this.logger.log('No experiments data available to update analytics client.');
|
|
7246
7171
|
}
|
|
7247
|
-
|
|
7248
7172
|
// trigger the page view event
|
|
7249
7173
|
if (this.shouldTrackPageView()) {
|
|
7250
7174
|
this.trackPageView();
|
|
7251
7175
|
return;
|
|
7252
7176
|
}
|
|
7253
7177
|
}
|
|
7254
|
-
|
|
7255
7178
|
/**
|
|
7256
7179
|
* Determines whether analytics should be checked.
|
|
7257
7180
|
*
|
|
@@ -7275,7 +7198,6 @@ class DotExperiments {
|
|
|
7275
7198
|
this.logger.log(`Not should Check Analytics by now...`);
|
|
7276
7199
|
return false;
|
|
7277
7200
|
}
|
|
7278
|
-
|
|
7279
7201
|
/**
|
|
7280
7202
|
* Retrieves persisted data from the database.
|
|
7281
7203
|
*
|
|
@@ -7302,11 +7224,6 @@ class DotExperiments {
|
|
|
7302
7224
|
return storedData;
|
|
7303
7225
|
}
|
|
7304
7226
|
}
|
|
7305
|
-
/**
|
|
7306
|
-
* The instance of the DotExperiments class.
|
|
7307
|
-
* @private
|
|
7308
|
-
*/
|
|
7309
|
-
DotExperiments.instance = void 0;
|
|
7310
7227
|
/**
|
|
7311
7228
|
* Represents the default configuration for the DotExperiment library.
|
|
7312
7229
|
* @property {boolean} trackPageView - Specifies whether to track page view or not. Default value is true.
|
|
@@ -7349,7 +7266,6 @@ const useExperiments = instance => {
|
|
|
7349
7266
|
}
|
|
7350
7267
|
}
|
|
7351
7268
|
}, [instance]);
|
|
7352
|
-
|
|
7353
7269
|
/**
|
|
7354
7270
|
* This effect sets a click handler on the document.
|
|
7355
7271
|
* It captures click events and redirects to a new URL if the clicked anchor has a variant assigned,
|
|
@@ -7367,23 +7283,19 @@ const useExperiments = instance => {
|
|
|
7367
7283
|
const clickedHref = target.getAttribute('href');
|
|
7368
7284
|
if (clickedHref) {
|
|
7369
7285
|
const modifiedUrl = new URL(clickedHref, instance.location.href);
|
|
7370
|
-
|
|
7371
7286
|
// Remove the experiment query param from the URL
|
|
7372
7287
|
modifiedUrl.searchParams.delete(EXPERIMENT_QUERY_PARAM_KEY);
|
|
7373
7288
|
event.preventDefault();
|
|
7374
|
-
|
|
7375
7289
|
// Get the variant from the href of the clicked anchor
|
|
7376
7290
|
const variant = instance.getVariantFromHref(clickedHref);
|
|
7377
7291
|
if (variant && variant.name !== EXPERIMENT_DEFAULT_VARIANT_NAME) {
|
|
7378
7292
|
// Set the experiment query param in the URL if the variant is not the default one
|
|
7379
7293
|
modifiedUrl.searchParams.set(EXPERIMENT_QUERY_PARAM_KEY, variant.name);
|
|
7380
7294
|
}
|
|
7381
|
-
|
|
7382
7295
|
// Redirect to the new URL using the custom redirect function
|
|
7383
7296
|
instance.customRedirectFn(modifiedUrl.toString());
|
|
7384
7297
|
}
|
|
7385
7298
|
};
|
|
7386
|
-
|
|
7387
7299
|
// Register the click handler to all elements in the document
|
|
7388
7300
|
document.addEventListener('click', customClickHandler);
|
|
7389
7301
|
return () => {
|
|
@@ -7407,10 +7319,8 @@ const DotExperimentsProvider = ({
|
|
|
7407
7319
|
config
|
|
7408
7320
|
}) => {
|
|
7409
7321
|
const [instance, setInstance] = useState(null);
|
|
7410
|
-
|
|
7411
7322
|
// Run Experiments detection
|
|
7412
7323
|
useExperiments(instance);
|
|
7413
|
-
|
|
7414
7324
|
// Initialize the DotExperiments instance
|
|
7415
7325
|
useEffect(() => {
|
|
7416
7326
|
var _getUVEState;
|
|
@@ -7426,7 +7336,7 @@ const DotExperimentsProvider = ({
|
|
|
7426
7336
|
}
|
|
7427
7337
|
}
|
|
7428
7338
|
}, [config]);
|
|
7429
|
-
return
|
|
7339
|
+
return jsx(DotExperimentsContext.Provider, {
|
|
7430
7340
|
value: instance,
|
|
7431
7341
|
children: children
|
|
7432
7342
|
});
|
|
@@ -7457,7 +7367,6 @@ function shallowEqual(objA, objB) {
|
|
|
7457
7367
|
}
|
|
7458
7368
|
return true;
|
|
7459
7369
|
}
|
|
7460
|
-
|
|
7461
7370
|
/**
|
|
7462
7371
|
* Memoizes an object and returns the memoized object.
|
|
7463
7372
|
* Mantaing the same reference if the object is the same independently if is called inside any component.
|
|
@@ -7490,9 +7399,9 @@ const withExperiments = (WrappedComponent, config) => {
|
|
|
7490
7399
|
// in each render, causing the experiment handling to be reinitialized.
|
|
7491
7400
|
const memoizedConfig = useMemoizedObject(config);
|
|
7492
7401
|
return useCallback(props => {
|
|
7493
|
-
return
|
|
7402
|
+
return jsx(DotExperimentsProvider, {
|
|
7494
7403
|
config: memoizedConfig,
|
|
7495
|
-
children:
|
|
7404
|
+
children: jsx(DotExperimentHandlingComponent, Object.assign({}, props, {
|
|
7496
7405
|
WrappedComponent: WrappedComponent
|
|
7497
7406
|
}))
|
|
7498
7407
|
});
|
package/package.json
CHANGED
package/src/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './lib/components/withExperiments';
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { DotCMSLayoutBodyProps } from '@dotcms/react';
|
|
2
|
+
interface ExperimentHandlingProps extends DotCMSLayoutBodyProps {
|
|
3
|
+
WrappedComponent: React.ComponentType<DotCMSLayoutBodyProps>;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* A React functional component that conditionally renders a WrappedComponent based on the
|
|
7
|
+
* experiment variant state. It uses the `useExperimentVariant` hook to determine if there's a
|
|
8
|
+
* variant mismatch. If the current variant does not match the assigned variant, it temporarily
|
|
9
|
+
* hides the WrappedComponent by rendering it with `visibility: hidden`. Once the correct variant
|
|
10
|
+
* is confirmed, it renders the WrappedComponent normally.
|
|
11
|
+
*
|
|
12
|
+
* @param {React.ComponentType<DotcmsPageProps>} WrappedComponent - The React component that will be
|
|
13
|
+
* conditionally rendered based on the experiment variant.
|
|
14
|
+
* @param {DotcmsPageProps} props - Props expected by the WrappedComponent, along with any additional
|
|
15
|
+
* props that extend from DotcmsPageProps.
|
|
16
|
+
* @returns {React.ReactElement} A React element that either renders the WrappedComponent hidden or visible
|
|
17
|
+
* based on the experiment variant.
|
|
18
|
+
*/
|
|
19
|
+
export declare const DotExperimentHandlingComponent: React.FC<ExperimentHandlingProps>;
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ReactElement, ReactNode } from 'react';
|
|
2
|
+
import { DotExperimentConfig } from '../shared/models';
|
|
3
|
+
interface DotExperimentsProviderProps {
|
|
4
|
+
children?: ReactNode;
|
|
5
|
+
config: DotExperimentConfig;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Internal React context provider used by `withExperiments`.
|
|
9
|
+
*
|
|
10
|
+
* @internal Do not import or use directly — use `withExperiments` from the package entry point.
|
|
11
|
+
*
|
|
12
|
+
* @param props.children - Descendants that need access to the `DotExperiments` instance.
|
|
13
|
+
* @param props.config - Configuration object for `DotExperiments`.
|
|
14
|
+
* @returns The provider component.
|
|
15
|
+
*/
|
|
16
|
+
export declare const DotExperimentsProvider: ({ children, config }: DotExperimentsProviderProps) => ReactElement;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React, { ReactNode } from 'react';
|
|
2
|
+
import { DotCMSLayoutBodyProps } from '@dotcms/react';
|
|
3
|
+
import { DotExperimentConfig } from '../shared/models';
|
|
4
|
+
export interface PageProviderProps {
|
|
5
|
+
readonly entity: any;
|
|
6
|
+
readonly children: ReactNode;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Wraps a given component with experiment handling capabilities using the 'useExperimentVariant' hook.
|
|
10
|
+
* This HOC checks if the entity's assigned experiment variant differs from the currently displayed variant.
|
|
11
|
+
* If they differ, the content is hidden until the correct variant is displayed. Once the assigned variant
|
|
12
|
+
* matches the displayed variant, the content of the WrappedComponent is shown.
|
|
13
|
+
*
|
|
14
|
+
* @param {React.ComponentType<DotcmsPageProps>} WrappedComponent - The component to be enhanced.
|
|
15
|
+
* @param {DotExperimentConfig} config - Configuration for experiment handling, including any necessary
|
|
16
|
+
* redirection functions or other settings.
|
|
17
|
+
* @returns {React.FunctionComponent<DotcmsPageProps>} A component that wraps the original component,
|
|
18
|
+
* adding experiment handling based on the specified configuration.
|
|
19
|
+
*/
|
|
20
|
+
export declare const withExperiments: (WrappedComponent: React.ComponentType<DotCMSLayoutBodyProps>, config: DotExperimentConfig) => (props: DotCMSLayoutBodyProps) => import("react/jsx-runtime").JSX.Element;
|