@ninetailed/experience.js-react 3.0.1-beta.3 → 3.0.1-beta.4

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,7 +1,8 @@
1
- import React, { createContext, useMemo, useContext, useState, useEffect, useCallback } from 'react';
1
+ import React, { createContext, useMemo, useContext, useState, useRef, useEffect, useCallback } from 'react';
2
2
  import { Ninetailed, selectVariant, selectDistribution, selectHasExperienceVariants, selectActiveExperiments, selectExperience, selectExperienceVariant } from '@ninetailed/experience.js';
3
+ import isEqual from 'lodash/isEqual';
4
+ import { logger, isBrowser } from '@ninetailed/experience.js-shared';
3
5
  import { useInView } from 'react-intersection-observer';
4
- import { isBrowser } from '@ninetailed/experience.js-shared';
5
6
  import get$1 from 'lodash/get';
6
7
  import has$1 from 'lodash/has';
7
8
 
@@ -1612,11 +1613,37 @@ $$2({ target: 'Object', stat: true, forced: Object.assign !== assign }, {
1612
1613
  const useProfile = () => {
1613
1614
  const ninetailed = useNinetailed();
1614
1615
  const [profileState, setProfileState] = useState(ninetailed.profileState);
1616
+ const profileStateRef = useRef({});
1617
+ /**
1618
+ * This effect compares the old and new profile state before updating it.
1619
+ * We use a ref to avoid an infinite loop which can happen when an empty profile state was updated with no changes.
1620
+ * This behaviour occurred as the validation handling on the error property was not set properly in the "CreateProfile" and "UpdateProfile" endpoint types.
1621
+ * Furthermore, it was also observed, that it "only" occurred when the preview plugin was used in parallel.
1622
+ */
1623
+
1615
1624
  useEffect(() => {
1616
- return ninetailed.onProfileChange(profileState => {
1617
- setProfileState(profileState);
1625
+ ninetailed.onProfileChange(profileState => {
1626
+ if (isEqual(profileState, profileStateRef.current)) {
1627
+ logger.debug("Profile State Did Not Change", profileState);
1628
+ return;
1629
+ } else {
1630
+ setProfileState(profileState);
1631
+ profileStateRef.current = profileState;
1632
+ logger.debug("Profile State Changed", profileState);
1633
+ }
1618
1634
  });
1619
1635
  }, []);
1636
+ /**
1637
+ * Old implementation without profile state deep comparison
1638
+ */
1639
+
1640
+ /*useEffect(() => {
1641
+ return ninetailed.onProfileChange((profileState) => {
1642
+ console.log('profileState', profileState);
1643
+ setProfileState(profileState);
1644
+ });
1645
+ }, []);*/
1646
+
1620
1647
  return Object.assign(Object.assign({}, profileState), {
1621
1648
  loading: profileState.status === 'loading'
1622
1649
  });
@@ -2487,16 +2514,19 @@ const useExperience = ({
2487
2514
  });
2488
2515
 
2489
2516
  if (status === 'loading') {
2517
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
2490
2518
  // @ts-ignore
2491
2519
  return emptyReturn;
2492
2520
  }
2493
2521
 
2494
2522
  if (status === 'error') {
2523
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
2495
2524
  // @ts-ignore
2496
2525
  return emptyReturn;
2497
2526
  }
2498
2527
 
2499
2528
  if (!profile) {
2529
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
2500
2530
  // @ts-ignore
2501
2531
  return emptyReturn;
2502
2532
  }
@@ -2509,6 +2539,7 @@ const useExperience = ({
2509
2539
  });
2510
2540
 
2511
2541
  if (!experience) {
2542
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
2512
2543
  // @ts-ignore
2513
2544
  return emptyReturn;
2514
2545
  }
package/index.umd.js CHANGED
@@ -1,12 +1,13 @@
1
1
  (function (global, factory) {
2
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react'), require('@ninetailed/experience.js'), require('react-intersection-observer'), require('@ninetailed/experience.js-shared'), require('lodash/get'), require('lodash/has')) :
3
- typeof define === 'function' && define.amd ? define(['exports', 'react', '@ninetailed/experience.js', 'react-intersection-observer', '@ninetailed/experience.js-shared', 'lodash/get', 'lodash/has'], factory) :
4
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.React = {}, global.React, global.experience_js, global.reactIntersectionObserver, global.experience_jsShared, global.get$1, global.has$1));
5
- })(this, (function (exports, React, experience_js, reactIntersectionObserver, experience_jsShared, get$1, has$1) { 'use strict';
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react'), require('@ninetailed/experience.js'), require('lodash/isEqual'), require('@ninetailed/experience.js-shared'), require('react-intersection-observer'), require('lodash/get'), require('lodash/has')) :
3
+ typeof define === 'function' && define.amd ? define(['exports', 'react', '@ninetailed/experience.js', 'lodash/isEqual', '@ninetailed/experience.js-shared', 'react-intersection-observer', 'lodash/get', 'lodash/has'], factory) :
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.React = {}, global.React, global.experience_js, global.isEqual, global.experience_jsShared, global.reactIntersectionObserver, global.get$1, global.has$1));
5
+ })(this, (function (exports, React, experience_js, isEqual, experience_jsShared, reactIntersectionObserver, get$1, has$1) { 'use strict';
6
6
 
7
7
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
8
8
 
9
9
  var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
10
+ var isEqual__default = /*#__PURE__*/_interopDefaultLegacy(isEqual);
10
11
  var get__default = /*#__PURE__*/_interopDefaultLegacy(get$1);
11
12
  var has__default = /*#__PURE__*/_interopDefaultLegacy(has$1);
12
13
 
@@ -116,11 +117,37 @@
116
117
  profileState = _a[0],
117
118
  setProfileState = _a[1];
118
119
 
120
+ var profileStateRef = React.useRef({});
121
+ /**
122
+ * This effect compares the old and new profile state before updating it.
123
+ * We use a ref to avoid an infinite loop which can happen when an empty profile state was updated with no changes.
124
+ * This behaviour occurred as the validation handling on the error property was not set properly in the "CreateProfile" and "UpdateProfile" endpoint types.
125
+ * Furthermore, it was also observed, that it "only" occurred when the preview plugin was used in parallel.
126
+ */
127
+
119
128
  React.useEffect(function () {
120
- return ninetailed.onProfileChange(function (profileState) {
121
- setProfileState(profileState);
129
+ ninetailed.onProfileChange(function (profileState) {
130
+ if (isEqual__default["default"](profileState, profileStateRef.current)) {
131
+ experience_jsShared.logger.debug("Profile State Did Not Change", profileState);
132
+ return;
133
+ } else {
134
+ setProfileState(profileState);
135
+ profileStateRef.current = profileState;
136
+ experience_jsShared.logger.debug("Profile State Changed", profileState);
137
+ }
122
138
  });
123
139
  }, []);
140
+ /**
141
+ * Old implementation without profile state deep comparison
142
+ */
143
+
144
+ /*useEffect(() => {
145
+ return ninetailed.onProfileChange((profileState) => {
146
+ console.log('profileState', profileState);
147
+ setProfileState(profileState);
148
+ });
149
+ }, []);*/
150
+
124
151
  return __assign(__assign({}, profileState), {
125
152
  loading: profileState.status === 'loading'
126
153
  });
@@ -2038,16 +2065,19 @@
2038
2065
  });
2039
2066
 
2040
2067
  if (status === 'loading') {
2068
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
2041
2069
  // @ts-ignore
2042
2070
  return emptyReturn;
2043
2071
  }
2044
2072
 
2045
2073
  if (status === 'error') {
2074
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
2046
2075
  // @ts-ignore
2047
2076
  return emptyReturn;
2048
2077
  }
2049
2078
 
2050
2079
  if (!profile) {
2080
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
2051
2081
  // @ts-ignore
2052
2082
  return emptyReturn;
2053
2083
  }
@@ -2060,6 +2090,7 @@
2060
2090
  });
2061
2091
 
2062
2092
  if (!experience) {
2093
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
2063
2094
  // @ts-ignore
2064
2095
  return emptyReturn;
2065
2096
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ninetailed/experience.js-react",
3
- "version": "3.0.1-beta.3",
3
+ "version": "3.0.1-beta.4",
4
4
  "peerDependencies": {
5
5
  "react": ">=16.8.0"
6
6
  },
@@ -8,8 +8,8 @@
8
8
  "@analytics/google-analytics": "0.5.3",
9
9
  "react-visibility-sensor": "5.1.1",
10
10
  "lodash": "^4.17.21",
11
- "@ninetailed/experience.js": "3.0.1-beta.3",
12
- "@ninetailed/experience.js-shared": "3.0.1-beta.3",
11
+ "@ninetailed/experience.js": "3.0.1-beta.4",
12
+ "@ninetailed/experience.js-shared": "3.0.1-beta.4",
13
13
  "ts-toolbelt": "^9.6.0",
14
14
  "diary": "^0.3.1",
15
15
  "zod": "^3.18.0",