@dotcms/experiments 0.0.1-alpha.26 → 0.0.1-alpha.27

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 CHANGED
@@ -1,5 +1,5 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
- import { createContext, useContext, useState, useEffect } from 'react';
2
+ import { createContext, useContext, useState, useEffect, useRef, useCallback } from 'react';
3
3
  import { isInsideEditor } from '@dotcms/client';
4
4
  import { jitsuClient } from '@jitsu/sdk-js';
5
5
 
@@ -6650,6 +6650,45 @@ const DotExperimentsProvider = ({
6650
6650
  });
6651
6651
  };
6652
6652
 
6653
+ /**
6654
+ * Compares two objects and returns true if they are equal, false otherwise.
6655
+ * @param objA The first object to compare.
6656
+ * @param objB The second object to compare.
6657
+ * @returns
6658
+ */
6659
+ function shallowEqual(objA, objB) {
6660
+ if (Object.is(objA, objB)) {
6661
+ return true;
6662
+ }
6663
+ if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
6664
+ return false;
6665
+ }
6666
+ const keysA = Object.keys(objA);
6667
+ const keysB = Object.keys(objB);
6668
+ if (keysA.length !== keysB.length) {
6669
+ return false;
6670
+ }
6671
+ for (const key of keysA) {
6672
+ if (!Object.prototype.hasOwnProperty.call(objB, key) || !Object.is(objA[key], objB[key])) {
6673
+ return false;
6674
+ }
6675
+ }
6676
+ return true;
6677
+ }
6678
+ /**
6679
+ * Memoizes an object and returns the memoized object.
6680
+ * Mantaing the same reference if the object is the same independently if is called inside any component.
6681
+ * @param object
6682
+ * @returns
6683
+ */
6684
+ function useMemoizedObject(object) {
6685
+ const ref = useRef(object);
6686
+ if (!shallowEqual(ref.current, object)) {
6687
+ ref.current = object;
6688
+ }
6689
+ return ref.current;
6690
+ }
6691
+
6653
6692
  /**
6654
6693
  * Wraps a given component with experiment handling capabilities using the 'useExperimentVariant' hook.
6655
6694
  * This HOC checks if the entity's assigned experiment variant differs from the currently displayed variant.
@@ -6663,14 +6702,18 @@ const DotExperimentsProvider = ({
6663
6702
  * adding experiment handling based on the specified configuration.
6664
6703
  */
6665
6704
  const withExperiments = (WrappedComponent, config) => {
6666
- return props => {
6705
+ // We need to use a custom memoization hook
6706
+ // because the useMemo or React.memo lose the reference of the object
6707
+ // in each render, causing the experiment handling to be reinitialized.
6708
+ const memoizedConfig = useMemoizedObject(config);
6709
+ return useCallback(props => {
6667
6710
  return jsx(DotExperimentsProvider, {
6668
- config: Object.assign({}, config),
6711
+ config: memoizedConfig,
6669
6712
  children: jsx(DotExperimentHandlingComponent, Object.assign({}, props, {
6670
6713
  WrappedComponent: WrappedComponent
6671
6714
  }))
6672
6715
  });
6673
- };
6716
+ }, [WrappedComponent, memoizedConfig]);
6674
6717
  };
6675
6718
 
6676
6719
  export { withExperiments };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dotcms/experiments",
3
- "version": "0.0.1-alpha.26",
3
+ "version": "0.0.1-alpha.27",
4
4
  "description": "Official JavaScript library to use Experiments with DotCMS.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -25,7 +25,7 @@
25
25
  "peerDependencies": {
26
26
  "react": ">=18",
27
27
  "react-dom": ">=18",
28
- "@dotcms/client": "0.0.1-alpha.26"
28
+ "@dotcms/client": "0.0.1-alpha.27"
29
29
  },
30
30
  "module": "./index.esm.js",
31
31
  "type": "module",
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Memoizes an object and returns the memoized object.
3
+ * Mantaing the same reference if the object is the same independently if is called inside any component.
4
+ * @param object
5
+ * @returns
6
+ */
7
+ export declare function useMemoizedObject<T extends object>(object: T): T;