@ninetailed/experience.js-react 4.2.0-beta.0 → 4.2.0-beta.10

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.cjs CHANGED
@@ -7,20 +7,11 @@ var React = require('react');
7
7
  var experience_js = require('@ninetailed/experience.js');
8
8
  var reactIntersectionObserver = require('react-intersection-observer');
9
9
  var experience_jsShared = require('@ninetailed/experience.js-shared');
10
- var isEqual = require('lodash/isEqual');
11
- var has$1 = require('lodash/has');
12
- var _debounce = require('lodash/debounce');
13
- var values$1 = require('lodash/values');
14
- var get$1 = require('lodash/get');
10
+ var radash = require('radash');
15
11
 
16
12
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
17
13
 
18
14
  var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
19
- var isEqual__default = /*#__PURE__*/_interopDefaultLegacy(isEqual);
20
- var has__default = /*#__PURE__*/_interopDefaultLegacy(has$1);
21
- var _debounce__default = /*#__PURE__*/_interopDefaultLegacy(_debounce);
22
- var values__default = /*#__PURE__*/_interopDefaultLegacy(values$1);
23
- var get__default = /*#__PURE__*/_interopDefaultLegacy(get$1);
24
15
 
25
16
  var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
26
17
 
@@ -1914,7 +1905,7 @@ const useProfile = () => {
1914
1905
  */
1915
1906
  React.useEffect(() => {
1916
1907
  ninetailed.onProfileChange(profileState => {
1917
- if (isEqual__default["default"](profileState, profileStateRef.current)) {
1908
+ if (radash.isEqual(profileState, profileStateRef.current)) {
1918
1909
  experience_jsShared.logger.debug('Profile State Did Not Change', profileState);
1919
1910
  return;
1920
1911
  } else {
@@ -1955,6 +1946,35 @@ const useExperiments = () => {
1955
1946
  };
1956
1947
  };
1957
1948
 
1949
+ const useExperienceSelectionMiddleware = ({
1950
+ experiences,
1951
+ baseline,
1952
+ profile
1953
+ }) => {
1954
+ const {
1955
+ plugins
1956
+ } = useNinetailed();
1957
+ const [_, setCurrentTime] = React.useState(Date.now());
1958
+ const {
1959
+ addListeners,
1960
+ removeListeners,
1961
+ middleware
1962
+ } = React.useMemo(() => experience_js.makeExperienceSelectMiddleware({
1963
+ plugins,
1964
+ experiences,
1965
+ baseline,
1966
+ profile,
1967
+ onChange: () => setCurrentTime(Date.now())
1968
+ }), [plugins, experiences, baseline, profile]);
1969
+ React.useEffect(() => {
1970
+ addListeners();
1971
+ return () => {
1972
+ removeListeners();
1973
+ };
1974
+ }, [addListeners, removeListeners]);
1975
+ return middleware;
1976
+ };
1977
+
1958
1978
  const useExperience = ({
1959
1979
  baseline,
1960
1980
  experiences
@@ -1968,6 +1988,31 @@ const useExperience = ({
1968
1988
  status,
1969
1989
  profile
1970
1990
  } = profileState;
1991
+ const experienceSelectionMiddleware = useExperienceSelectionMiddleware({
1992
+ experiences,
1993
+ baseline,
1994
+ profile
1995
+ });
1996
+ const overrideResult = _a => {
1997
+ var {
1998
+ experience: originalExperience,
1999
+ variant: originalVariant
2000
+ } = _a,
2001
+ other = __rest(_a, ["experience", "variant"]);
2002
+ const {
2003
+ experience,
2004
+ variant
2005
+ } = experienceSelectionMiddleware({
2006
+ experience: originalExperience,
2007
+ variant: originalVariant
2008
+ });
2009
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
2010
+ // @ts-ignore
2011
+ return Object.assign(Object.assign({}, other), {
2012
+ experience,
2013
+ variant
2014
+ });
2015
+ };
1971
2016
  const baseReturn = Object.assign(Object.assign({}, profileState), {
1972
2017
  hasVariants,
1973
2018
  baseline
@@ -1982,17 +2027,17 @@ const useExperience = ({
1982
2027
  if (status === 'loading') {
1983
2028
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1984
2029
  // @ts-ignore
1985
- return emptyReturn;
2030
+ return overrideResult(emptyReturn);
1986
2031
  }
1987
2032
  if (status === 'error') {
1988
2033
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1989
2034
  // @ts-ignore
1990
- return emptyReturn;
2035
+ return overrideResult(emptyReturn);
1991
2036
  }
1992
2037
  if (!profile) {
1993
2038
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1994
2039
  // @ts-ignore
1995
- return emptyReturn;
2040
+ return overrideResult(emptyReturn);
1996
2041
  }
1997
2042
  const activeExperiments = experience_js.selectActiveExperiments(experiments, profile);
1998
2043
  const experience = experience_js.selectExperience({
@@ -2003,9 +2048,9 @@ const useExperience = ({
2003
2048
  if (!experience) {
2004
2049
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
2005
2050
  // @ts-ignore
2006
- return Object.assign(Object.assign({}, emptyReturn), {
2051
+ return overrideResult(Object.assign(Object.assign({}, emptyReturn), {
2007
2052
  profile
2008
- });
2053
+ }));
2009
2054
  }
2010
2055
  const audience = experience.audience;
2011
2056
  const variant = experience_js.selectExperienceVariant({
@@ -2014,7 +2059,7 @@ const useExperience = ({
2014
2059
  profile
2015
2060
  });
2016
2061
  if (!variant) {
2017
- return Object.assign(Object.assign({}, baseReturn), {
2062
+ return overrideResult(Object.assign(Object.assign({}, baseReturn), {
2018
2063
  status: 'success',
2019
2064
  loading: false,
2020
2065
  error: null,
@@ -2023,9 +2068,9 @@ const useExperience = ({
2023
2068
  audience: audience ? audience : null,
2024
2069
  profile,
2025
2070
  isPersonalized: false
2026
- });
2071
+ }));
2027
2072
  }
2028
- return Object.assign(Object.assign({}, baseReturn), {
2073
+ return overrideResult(Object.assign(Object.assign({}, baseReturn), {
2029
2074
  status: 'success',
2030
2075
  loading: false,
2031
2076
  error: null,
@@ -2034,7 +2079,7 @@ const useExperience = ({
2034
2079
  audience: audience ? audience : null,
2035
2080
  profile,
2036
2081
  isPersonalized: true
2037
- });
2082
+ }));
2038
2083
  };
2039
2084
 
2040
2085
  const useJoinExperiment = () => {
@@ -2042,58 +2087,6 @@ const useJoinExperiment = () => {
2042
2087
  return context.joinExperiment;
2043
2088
  };
2044
2089
 
2045
- /**
2046
- * This component is used to conditionally render Experiences which may include empty variants.
2047
- * It is essential to intercept the props within the ComponentWrapper to be able to get the current variant.
2048
- * Note: the passed props can be altered by the render plugins.
2049
- */
2050
- const ConditionalRenderComponent = _a => {
2051
- var {
2052
- children
2053
- } = _a,
2054
- props = __rest(_a, ["children"]);
2055
- if ('hidden' in props && props.hidden) {
2056
- return null;
2057
- }
2058
- return jsxRuntime.jsx(jsxRuntime.Fragment, {
2059
- children: React__default["default"].Children.map(children, child => {
2060
- if ( /*#__PURE__*/React__default["default"].isValidElement(child)) {
2061
- return /*#__PURE__*/React__default["default"].cloneElement(child, props);
2062
- }
2063
- return null;
2064
- })
2065
- });
2066
- };
2067
-
2068
- const useExperienceSelectionMiddleware = ({
2069
- experiences,
2070
- baseline,
2071
- profile
2072
- }) => {
2073
- const {
2074
- plugins
2075
- } = useNinetailed();
2076
- const [_, setCurrentTime] = React.useState(Date.now());
2077
- const {
2078
- addListeners,
2079
- removeListeners,
2080
- middleware
2081
- } = React.useMemo(() => experience_js.makeExperienceSelectMiddleware({
2082
- plugins,
2083
- experiences,
2084
- baseline,
2085
- profile,
2086
- onChange: () => setCurrentTime(Date.now())
2087
- }), [plugins, experiences, baseline, profile]);
2088
- React.useEffect(() => {
2089
- addListeners();
2090
- return () => {
2091
- removeListeners();
2092
- };
2093
- }, [addListeners, removeListeners]);
2094
- return middleware;
2095
- };
2096
-
2097
2090
  const DefaultExperienceLoadingComponent = _a => {
2098
2091
  var {
2099
2092
  component: Component,
@@ -2151,8 +2144,8 @@ const Experience = _a => {
2151
2144
  const {
2152
2145
  status,
2153
2146
  hasVariants,
2154
- experience: originalExperience,
2155
- variant: originalVariant,
2147
+ experience,
2148
+ variant,
2156
2149
  audience,
2157
2150
  isPersonalized,
2158
2151
  profile
@@ -2160,18 +2153,6 @@ const Experience = _a => {
2160
2153
  baseline,
2161
2154
  experiences
2162
2155
  });
2163
- const experienceSelectionMiddleware = useExperienceSelectionMiddleware({
2164
- experiences,
2165
- baseline,
2166
- profile
2167
- });
2168
- const {
2169
- experience,
2170
- variant
2171
- } = experienceSelectionMiddleware({
2172
- experience: originalExperience,
2173
- variant: originalVariant
2174
- });
2175
2156
  const joinExperiment = useJoinExperiment();
2176
2157
  React.useEffect(() => {
2177
2158
  if (status === 'success' && experience && profile) {
@@ -2222,23 +2203,22 @@ const Experience = _a => {
2222
2203
  }))
2223
2204
  }), baseline.id);
2224
2205
  }
2206
+ const isVariantHidden = 'hidden' in variant && variant.hidden;
2225
2207
  return jsxRuntime.jsx(TrackExperience, Object.assign({
2226
2208
  experience: experience,
2227
2209
  variant: variant,
2228
2210
  // the profile is definitely defined, otherwise there wouldn't be an experience selected
2229
2211
  profile: profile
2230
2212
  }, {
2231
- children: jsxRuntime.jsx(ConditionalRenderComponent, {
2232
- children: /*#__PURE__*/React.createElement(Component, Object.assign({}, Object.assign(Object.assign({}, passthroughProps), variant), {
2233
- key: `${experience.id}-${variant.id}`,
2234
- ninetailed: {
2235
- isPersonalized,
2236
- audience: {
2237
- id: (audience === null || audience === void 0 ? void 0 : audience.id) || 'all visitors'
2238
- }
2213
+ children: !isVariantHidden ? /*#__PURE__*/React.createElement(Component, Object.assign({}, Object.assign(Object.assign({}, passthroughProps), variant), {
2214
+ key: `${experience.id}-${variant.id}`,
2215
+ ninetailed: {
2216
+ isPersonalized,
2217
+ audience: {
2218
+ id: (audience === null || audience === void 0 ? void 0 : audience.id) || 'all visitors'
2239
2219
  }
2240
- }))
2241
- })
2220
+ }
2221
+ })) : null
2242
2222
  }));
2243
2223
  };
2244
2224
 
@@ -2274,7 +2254,7 @@ const ESRLoadingComponent = _a => {
2274
2254
  const {
2275
2255
  experienceVariantsMap
2276
2256
  } = useESR();
2277
- const experience = experiences.find(experience => has__default["default"](experienceVariantsMap, experience.id));
2257
+ const experience = experiences.find(experience => Object.prototype.hasOwnProperty.call(experienceVariantsMap, experience.id));
2278
2258
  if (!experience) {
2279
2259
  return jsxRuntime.jsx(Component, Object.assign({}, passthroughProps, baseline, {
2280
2260
  ninetailed: {
@@ -2329,14 +2309,16 @@ const ESRLoadingComponent = _a => {
2329
2309
 
2330
2310
  const EXPERIENCE_TRAIT_PREFIX = 'nt_experiment_';
2331
2311
 
2332
- const debounce = (fn, wait, options) => {
2312
+ const debounce = (fn, wait) => {
2333
2313
  let debouncedArgs = [];
2334
- const debouncedFn = _debounce__default["default"](() => {
2314
+ const debouncedFn = radash.debounce({
2315
+ delay: wait !== null && wait !== void 0 ? wait : 0
2316
+ }, () => {
2335
2317
  fn.call(undefined, debouncedArgs);
2336
2318
  debouncedArgs = [];
2337
- }, wait, options);
2319
+ });
2338
2320
  return (...args) => {
2339
- debouncedArgs.push(values__default["default"](args));
2321
+ debouncedArgs.push(args);
2340
2322
  debouncedFn();
2341
2323
  };
2342
2324
  };
@@ -2398,39 +2380,47 @@ const ExperimentsProvider = ({
2398
2380
  }));
2399
2381
  };
2400
2382
 
2401
- const NinetailedProvider = ({
2402
- children,
2403
- clientId,
2404
- experiments: _experiments = [],
2405
- maximumActiveExperiments,
2406
- environment,
2407
- preview,
2408
- url,
2409
- profile,
2410
- locale,
2411
- requestTimeout,
2412
- plugins: _plugins = [],
2413
- onLog,
2414
- onError
2415
- }) => {
2416
- const ninetailed = React.useMemo(() => new experience_js.Ninetailed({
2417
- clientId,
2418
- environment,
2419
- preview
2420
- }, {
2421
- url,
2422
- plugins: _plugins,
2423
- profile,
2424
- locale,
2425
- requestTimeout,
2426
- onLog,
2427
- onError
2428
- }), []);
2383
+ const NinetailedProvider = props => {
2384
+ const ninetailed = React.useMemo(() => {
2385
+ if ('ninetailed' in props) {
2386
+ return props.ninetailed;
2387
+ }
2388
+ const {
2389
+ clientId,
2390
+ environment,
2391
+ preview,
2392
+ url,
2393
+ profile,
2394
+ locale,
2395
+ requestTimeout,
2396
+ plugins = [],
2397
+ onLog,
2398
+ onError
2399
+ } = props;
2400
+ return new experience_js.Ninetailed({
2401
+ clientId,
2402
+ environment,
2403
+ preview
2404
+ }, {
2405
+ url,
2406
+ plugins,
2407
+ profile,
2408
+ locale,
2409
+ requestTimeout,
2410
+ onLog,
2411
+ onError
2412
+ });
2413
+ }, []);
2414
+ const {
2415
+ experiments = [],
2416
+ maximumActiveExperiments,
2417
+ children
2418
+ } = props;
2429
2419
  return jsxRuntime.jsx(NinetailedContext.Provider, Object.assign({
2430
2420
  value: ninetailed
2431
2421
  }, {
2432
2422
  children: jsxRuntime.jsx(ExperimentsProvider, Object.assign({
2433
- experiments: _experiments,
2423
+ experiments: experiments,
2434
2424
  maximumActiveExperiments: maximumActiveExperiments
2435
2425
  }, {
2436
2426
  children: children
@@ -2540,11 +2530,11 @@ const generateSelectors = id => {
2540
2530
  };
2541
2531
  const selectValueFromProfile = (profile, id) => {
2542
2532
  const selectors = generateSelectors(id);
2543
- const matchingSelector = selectors.find(selector => get__default["default"](profile, selector));
2533
+ const matchingSelector = selectors.find(selector => radash.get(profile, selector));
2544
2534
  if (!matchingSelector) {
2545
2535
  return null;
2546
2536
  }
2547
- return get__default["default"](profile, matchingSelector);
2537
+ return radash.get(profile, matchingSelector);
2548
2538
  };
2549
2539
  const MergeTag = ({
2550
2540
  id
package/index.js CHANGED
@@ -1,13 +1,9 @@
1
1
  import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
2
2
  import React, { createContext, useContext, useEffect, useState, useRef, useMemo, createElement as createElement$1, useCallback } from 'react';
3
- import { selectDistribution, selectHasExperienceVariants, selectActiveExperiments, selectExperience, selectExperienceVariant, makeExperienceSelectMiddleware, Ninetailed, selectVariant } from '@ninetailed/experience.js';
3
+ import { selectDistribution, makeExperienceSelectMiddleware, selectHasExperienceVariants, selectActiveExperiments, selectExperience, selectExperienceVariant, Ninetailed, selectVariant } from '@ninetailed/experience.js';
4
4
  import { useInView } from 'react-intersection-observer';
5
5
  import { isBrowser, logger } from '@ninetailed/experience.js-shared';
6
- import isEqual from 'lodash/isEqual';
7
- import has$1 from 'lodash/has';
8
- import _debounce from 'lodash/debounce';
9
- import values$1 from 'lodash/values';
10
- import get$1 from 'lodash/get';
6
+ import { isEqual, debounce as debounce$1, get as get$1 } from 'radash';
11
7
 
12
8
  var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
13
9
 
@@ -1942,6 +1938,35 @@ const useExperiments = () => {
1942
1938
  };
1943
1939
  };
1944
1940
 
1941
+ const useExperienceSelectionMiddleware = ({
1942
+ experiences,
1943
+ baseline,
1944
+ profile
1945
+ }) => {
1946
+ const {
1947
+ plugins
1948
+ } = useNinetailed();
1949
+ const [_, setCurrentTime] = useState(Date.now());
1950
+ const {
1951
+ addListeners,
1952
+ removeListeners,
1953
+ middleware
1954
+ } = useMemo(() => makeExperienceSelectMiddleware({
1955
+ plugins,
1956
+ experiences,
1957
+ baseline,
1958
+ profile,
1959
+ onChange: () => setCurrentTime(Date.now())
1960
+ }), [plugins, experiences, baseline, profile]);
1961
+ useEffect(() => {
1962
+ addListeners();
1963
+ return () => {
1964
+ removeListeners();
1965
+ };
1966
+ }, [addListeners, removeListeners]);
1967
+ return middleware;
1968
+ };
1969
+
1945
1970
  const useExperience = ({
1946
1971
  baseline,
1947
1972
  experiences
@@ -1955,6 +1980,31 @@ const useExperience = ({
1955
1980
  status,
1956
1981
  profile
1957
1982
  } = profileState;
1983
+ const experienceSelectionMiddleware = useExperienceSelectionMiddleware({
1984
+ experiences,
1985
+ baseline,
1986
+ profile
1987
+ });
1988
+ const overrideResult = _a => {
1989
+ var {
1990
+ experience: originalExperience,
1991
+ variant: originalVariant
1992
+ } = _a,
1993
+ other = __rest(_a, ["experience", "variant"]);
1994
+ const {
1995
+ experience,
1996
+ variant
1997
+ } = experienceSelectionMiddleware({
1998
+ experience: originalExperience,
1999
+ variant: originalVariant
2000
+ });
2001
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
2002
+ // @ts-ignore
2003
+ return Object.assign(Object.assign({}, other), {
2004
+ experience,
2005
+ variant
2006
+ });
2007
+ };
1958
2008
  const baseReturn = Object.assign(Object.assign({}, profileState), {
1959
2009
  hasVariants,
1960
2010
  baseline
@@ -1969,17 +2019,17 @@ const useExperience = ({
1969
2019
  if (status === 'loading') {
1970
2020
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1971
2021
  // @ts-ignore
1972
- return emptyReturn;
2022
+ return overrideResult(emptyReturn);
1973
2023
  }
1974
2024
  if (status === 'error') {
1975
2025
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1976
2026
  // @ts-ignore
1977
- return emptyReturn;
2027
+ return overrideResult(emptyReturn);
1978
2028
  }
1979
2029
  if (!profile) {
1980
2030
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1981
2031
  // @ts-ignore
1982
- return emptyReturn;
2032
+ return overrideResult(emptyReturn);
1983
2033
  }
1984
2034
  const activeExperiments = selectActiveExperiments(experiments, profile);
1985
2035
  const experience = selectExperience({
@@ -1990,9 +2040,9 @@ const useExperience = ({
1990
2040
  if (!experience) {
1991
2041
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1992
2042
  // @ts-ignore
1993
- return Object.assign(Object.assign({}, emptyReturn), {
2043
+ return overrideResult(Object.assign(Object.assign({}, emptyReturn), {
1994
2044
  profile
1995
- });
2045
+ }));
1996
2046
  }
1997
2047
  const audience = experience.audience;
1998
2048
  const variant = selectExperienceVariant({
@@ -2001,7 +2051,7 @@ const useExperience = ({
2001
2051
  profile
2002
2052
  });
2003
2053
  if (!variant) {
2004
- return Object.assign(Object.assign({}, baseReturn), {
2054
+ return overrideResult(Object.assign(Object.assign({}, baseReturn), {
2005
2055
  status: 'success',
2006
2056
  loading: false,
2007
2057
  error: null,
@@ -2010,9 +2060,9 @@ const useExperience = ({
2010
2060
  audience: audience ? audience : null,
2011
2061
  profile,
2012
2062
  isPersonalized: false
2013
- });
2063
+ }));
2014
2064
  }
2015
- return Object.assign(Object.assign({}, baseReturn), {
2065
+ return overrideResult(Object.assign(Object.assign({}, baseReturn), {
2016
2066
  status: 'success',
2017
2067
  loading: false,
2018
2068
  error: null,
@@ -2021,7 +2071,7 @@ const useExperience = ({
2021
2071
  audience: audience ? audience : null,
2022
2072
  profile,
2023
2073
  isPersonalized: true
2024
- });
2074
+ }));
2025
2075
  };
2026
2076
 
2027
2077
  const useJoinExperiment = () => {
@@ -2029,58 +2079,6 @@ const useJoinExperiment = () => {
2029
2079
  return context.joinExperiment;
2030
2080
  };
2031
2081
 
2032
- /**
2033
- * This component is used to conditionally render Experiences which may include empty variants.
2034
- * It is essential to intercept the props within the ComponentWrapper to be able to get the current variant.
2035
- * Note: the passed props can be altered by the render plugins.
2036
- */
2037
- const ConditionalRenderComponent = _a => {
2038
- var {
2039
- children
2040
- } = _a,
2041
- props = __rest(_a, ["children"]);
2042
- if ('hidden' in props && props.hidden) {
2043
- return null;
2044
- }
2045
- return jsx(Fragment, {
2046
- children: React.Children.map(children, child => {
2047
- if ( /*#__PURE__*/React.isValidElement(child)) {
2048
- return /*#__PURE__*/React.cloneElement(child, props);
2049
- }
2050
- return null;
2051
- })
2052
- });
2053
- };
2054
-
2055
- const useExperienceSelectionMiddleware = ({
2056
- experiences,
2057
- baseline,
2058
- profile
2059
- }) => {
2060
- const {
2061
- plugins
2062
- } = useNinetailed();
2063
- const [_, setCurrentTime] = useState(Date.now());
2064
- const {
2065
- addListeners,
2066
- removeListeners,
2067
- middleware
2068
- } = useMemo(() => makeExperienceSelectMiddleware({
2069
- plugins,
2070
- experiences,
2071
- baseline,
2072
- profile,
2073
- onChange: () => setCurrentTime(Date.now())
2074
- }), [plugins, experiences, baseline, profile]);
2075
- useEffect(() => {
2076
- addListeners();
2077
- return () => {
2078
- removeListeners();
2079
- };
2080
- }, [addListeners, removeListeners]);
2081
- return middleware;
2082
- };
2083
-
2084
2082
  const DefaultExperienceLoadingComponent = _a => {
2085
2083
  var {
2086
2084
  component: Component,
@@ -2138,8 +2136,8 @@ const Experience = _a => {
2138
2136
  const {
2139
2137
  status,
2140
2138
  hasVariants,
2141
- experience: originalExperience,
2142
- variant: originalVariant,
2139
+ experience,
2140
+ variant,
2143
2141
  audience,
2144
2142
  isPersonalized,
2145
2143
  profile
@@ -2147,18 +2145,6 @@ const Experience = _a => {
2147
2145
  baseline,
2148
2146
  experiences
2149
2147
  });
2150
- const experienceSelectionMiddleware = useExperienceSelectionMiddleware({
2151
- experiences,
2152
- baseline,
2153
- profile
2154
- });
2155
- const {
2156
- experience,
2157
- variant
2158
- } = experienceSelectionMiddleware({
2159
- experience: originalExperience,
2160
- variant: originalVariant
2161
- });
2162
2148
  const joinExperiment = useJoinExperiment();
2163
2149
  useEffect(() => {
2164
2150
  if (status === 'success' && experience && profile) {
@@ -2209,23 +2195,22 @@ const Experience = _a => {
2209
2195
  }))
2210
2196
  }), baseline.id);
2211
2197
  }
2198
+ const isVariantHidden = 'hidden' in variant && variant.hidden;
2212
2199
  return jsx(TrackExperience, Object.assign({
2213
2200
  experience: experience,
2214
2201
  variant: variant,
2215
2202
  // the profile is definitely defined, otherwise there wouldn't be an experience selected
2216
2203
  profile: profile
2217
2204
  }, {
2218
- children: jsx(ConditionalRenderComponent, {
2219
- children: /*#__PURE__*/createElement$1(Component, Object.assign({}, Object.assign(Object.assign({}, passthroughProps), variant), {
2220
- key: `${experience.id}-${variant.id}`,
2221
- ninetailed: {
2222
- isPersonalized,
2223
- audience: {
2224
- id: (audience === null || audience === void 0 ? void 0 : audience.id) || 'all visitors'
2225
- }
2205
+ children: !isVariantHidden ? /*#__PURE__*/createElement$1(Component, Object.assign({}, Object.assign(Object.assign({}, passthroughProps), variant), {
2206
+ key: `${experience.id}-${variant.id}`,
2207
+ ninetailed: {
2208
+ isPersonalized,
2209
+ audience: {
2210
+ id: (audience === null || audience === void 0 ? void 0 : audience.id) || 'all visitors'
2226
2211
  }
2227
- }))
2228
- })
2212
+ }
2213
+ })) : null
2229
2214
  }));
2230
2215
  };
2231
2216
 
@@ -2261,7 +2246,7 @@ const ESRLoadingComponent = _a => {
2261
2246
  const {
2262
2247
  experienceVariantsMap
2263
2248
  } = useESR();
2264
- const experience = experiences.find(experience => has$1(experienceVariantsMap, experience.id));
2249
+ const experience = experiences.find(experience => Object.prototype.hasOwnProperty.call(experienceVariantsMap, experience.id));
2265
2250
  if (!experience) {
2266
2251
  return jsx(Component, Object.assign({}, passthroughProps, baseline, {
2267
2252
  ninetailed: {
@@ -2316,14 +2301,16 @@ const ESRLoadingComponent = _a => {
2316
2301
 
2317
2302
  const EXPERIENCE_TRAIT_PREFIX = 'nt_experiment_';
2318
2303
 
2319
- const debounce = (fn, wait, options) => {
2304
+ const debounce = (fn, wait) => {
2320
2305
  let debouncedArgs = [];
2321
- const debouncedFn = _debounce(() => {
2306
+ const debouncedFn = debounce$1({
2307
+ delay: wait !== null && wait !== void 0 ? wait : 0
2308
+ }, () => {
2322
2309
  fn.call(undefined, debouncedArgs);
2323
2310
  debouncedArgs = [];
2324
- }, wait, options);
2311
+ });
2325
2312
  return (...args) => {
2326
- debouncedArgs.push(values$1(args));
2313
+ debouncedArgs.push(args);
2327
2314
  debouncedFn();
2328
2315
  };
2329
2316
  };
@@ -2385,39 +2372,47 @@ const ExperimentsProvider = ({
2385
2372
  }));
2386
2373
  };
2387
2374
 
2388
- const NinetailedProvider = ({
2389
- children,
2390
- clientId,
2391
- experiments: _experiments = [],
2392
- maximumActiveExperiments,
2393
- environment,
2394
- preview,
2395
- url,
2396
- profile,
2397
- locale,
2398
- requestTimeout,
2399
- plugins: _plugins = [],
2400
- onLog,
2401
- onError
2402
- }) => {
2403
- const ninetailed = useMemo(() => new Ninetailed({
2404
- clientId,
2405
- environment,
2406
- preview
2407
- }, {
2408
- url,
2409
- plugins: _plugins,
2410
- profile,
2411
- locale,
2412
- requestTimeout,
2413
- onLog,
2414
- onError
2415
- }), []);
2375
+ const NinetailedProvider = props => {
2376
+ const ninetailed = useMemo(() => {
2377
+ if ('ninetailed' in props) {
2378
+ return props.ninetailed;
2379
+ }
2380
+ const {
2381
+ clientId,
2382
+ environment,
2383
+ preview,
2384
+ url,
2385
+ profile,
2386
+ locale,
2387
+ requestTimeout,
2388
+ plugins = [],
2389
+ onLog,
2390
+ onError
2391
+ } = props;
2392
+ return new Ninetailed({
2393
+ clientId,
2394
+ environment,
2395
+ preview
2396
+ }, {
2397
+ url,
2398
+ plugins,
2399
+ profile,
2400
+ locale,
2401
+ requestTimeout,
2402
+ onLog,
2403
+ onError
2404
+ });
2405
+ }, []);
2406
+ const {
2407
+ experiments = [],
2408
+ maximumActiveExperiments,
2409
+ children
2410
+ } = props;
2416
2411
  return jsx(NinetailedContext.Provider, Object.assign({
2417
2412
  value: ninetailed
2418
2413
  }, {
2419
2414
  children: jsx(ExperimentsProvider, Object.assign({
2420
- experiments: _experiments,
2415
+ experiments: experiments,
2421
2416
  maximumActiveExperiments: maximumActiveExperiments
2422
2417
  }, {
2423
2418
  children: children
@@ -1,11 +1,11 @@
1
1
  import { ExperienceConfiguration, Profile, Reference } from '@ninetailed/experience.js-shared';
2
- type UseExperienceSelectionMiddlewareArg = {
3
- experiences: ExperienceConfiguration<Reference>[];
2
+ type UseExperienceSelectionMiddlewareArg<Variant extends Reference> = {
3
+ experiences: ExperienceConfiguration<Variant>[];
4
4
  baseline: Reference;
5
5
  profile: Profile | null;
6
6
  };
7
- export declare const useExperienceSelectionMiddleware: ({ experiences, baseline, profile, }: UseExperienceSelectionMiddlewareArg) => ({ experience, variant, }: import("@ninetailed/experience.js").ExperienceSelectionMiddlewareReturnArg<Reference>) => {
8
- experience: ExperienceConfiguration<Reference> | null;
9
- variant: Reference | null;
7
+ export declare const useExperienceSelectionMiddleware: <Variant extends Reference>({ experiences, baseline, profile, }: UseExperienceSelectionMiddlewareArg<Variant>) => ({ experience, variant, }: import("@ninetailed/experience.js").ExperienceSelectionMiddlewareReturnArg<Variant | import("@ninetailed/experience.js-shared").VariantRef>) => {
8
+ experience: ExperienceConfiguration<Variant | import("@ninetailed/experience.js-shared").VariantRef> | null;
9
+ variant: Variant | import("@ninetailed/experience.js-shared").VariantRef | null;
10
10
  };
11
11
  export {};
package/lib/MergeTag.d.ts CHANGED
@@ -4,6 +4,6 @@ type MergeTagProps = {
4
4
  id: string;
5
5
  };
6
6
  export declare const generateSelectors: (id: string) => string[];
7
- export declare const selectValueFromProfile: (profile: Profile, id: string) => any;
7
+ export declare const selectValueFromProfile: (profile: Profile, id: string) => unknown;
8
8
  export declare const MergeTag: React.FC<React.PropsWithChildren<MergeTagProps>>;
9
9
  export {};
@@ -1,11 +1,13 @@
1
1
  import React from 'react';
2
- import { NinetailedPlugin, ExperienceConfiguration } from '@ninetailed/experience.js';
2
+ import { Ninetailed, NinetailedPlugin, ExperienceConfiguration } from '@ninetailed/experience.js';
3
3
  import { Profile, Locale, OnErrorHandler, OnLogHandler } from '@ninetailed/experience.js-shared';
4
- export type NinetailedProviderProps = {
5
- clientId: string;
6
- environment?: string;
4
+ type ExperimentProviderProps = {
7
5
  experiments?: ExperienceConfiguration<any>[];
8
6
  maximumActiveExperiments?: number;
7
+ };
8
+ export type NinetailedProviderInstantiationProps = {
9
+ clientId: string;
10
+ environment?: string;
9
11
  preview?: boolean;
10
12
  url?: string;
11
13
  plugins?: (NinetailedPlugin | NinetailedPlugin[])[];
@@ -14,5 +16,9 @@ export type NinetailedProviderProps = {
14
16
  requestTimeout?: number;
15
17
  onLog?: OnLogHandler;
16
18
  onError?: OnErrorHandler;
17
- };
18
- export declare const NinetailedProvider: ({ children, clientId, experiments, maximumActiveExperiments, environment, preview, url, profile, locale, requestTimeout, plugins, onLog, onError, }: React.PropsWithChildren<NinetailedProviderProps>) => JSX.Element;
19
+ } & ExperimentProviderProps;
20
+ export type NinetailedProviderProps = NinetailedProviderInstantiationProps | ({
21
+ ninetailed: Ninetailed;
22
+ } & ExperimentProviderProps);
23
+ export declare const NinetailedProvider: (props: React.PropsWithChildren<NinetailedProviderProps>) => JSX.Element;
24
+ export {};
package/lib/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  export type { Profile, Variant } from '@ninetailed/experience.js-shared';
2
2
  export type { ExperienceConfiguration, ExperienceType, EXPERIENCE_TRAIT_PREFIX, } from '@ninetailed/experience.js';
3
3
  export { NinetailedProvider } from './NinetailedProvider';
4
- export type { NinetailedProviderProps } from './NinetailedProvider';
4
+ export type { NinetailedProviderProps, NinetailedProviderInstantiationProps, } from './NinetailedProvider';
5
5
  export { useNinetailed } from './useNinetailed';
6
6
  export { useProfile } from './useProfile';
7
7
  export { usePersonalize } from './usePersonalize';
@@ -41,12 +41,7 @@ export declare const useProfile: () => {
41
41
  averageSessionLength: number;
42
42
  };
43
43
  };
44
- error: null; /**
45
- * This effect compares the old and new profile state before updating it.
46
- * We use a ref to avoid an infinite loop which can happen when an empty profile state was updated with no changes.
47
- * This behaviour occurred as the validation handling on the error property was not set properly in the "CreateProfile" and "UpdateProfile" endpoint types.
48
- * Furthermore, it was also observed, that it "only" occurred when the preview plugin was used in parallel.
49
- */
44
+ error: null;
50
45
  } | {
51
46
  loading: boolean;
52
47
  from: "api" | "hydrated";
package/package.json CHANGED
@@ -1,16 +1,16 @@
1
1
  {
2
2
  "name": "@ninetailed/experience.js-react",
3
- "version": "4.2.0-beta.0",
3
+ "version": "4.2.0-beta.10",
4
4
  "peerDependencies": {
5
5
  "react": ">=16.8.0"
6
6
  },
7
7
  "dependencies": {
8
8
  "@analytics/google-analytics": "0.5.3",
9
9
  "react-visibility-sensor": "5.1.1",
10
- "lodash": "4.17.21",
11
- "@ninetailed/experience.js": "4.2.0-beta.0",
10
+ "@ninetailed/experience.js": "4.2.0-beta.10",
12
11
  "react-intersection-observer": "8.34.0",
13
- "@ninetailed/experience.js-shared": "4.2.0-beta.0",
12
+ "@ninetailed/experience.js-shared": "4.2.0-beta.10",
13
+ "radash": "10.9.0",
14
14
  "analytics": "0.8.1"
15
15
  },
16
16
  "module": "./index.js",
@@ -1,7 +0,0 @@
1
- import React from 'react';
2
- /**
3
- * This component is used to conditionally render Experiences which may include empty variants.
4
- * It is essential to intercept the props within the ComponentWrapper to be able to get the current variant.
5
- * Note: the passed props can be altered by the render plugins.
6
- */
7
- export declare const ConditionalRenderComponent: React.FC<React.PropsWithChildren>;