@ninetailed/experience.js-react 2.0.0-beta.9 → 2.0.2
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 +166 -52
- package/index.umd.js +181 -62
- package/lib/Experience/ESRLoadingComponent.d.ts +15 -0
- package/lib/Experience/Experience.d.ts +12 -3
- package/lib/Experience/TrackExperience.d.ts +12 -0
- package/lib/Experience/index.d.ts +3 -1
- package/lib/Experience/useJoinExperiment.d.ts +1 -1
- package/lib/index.d.ts +3 -2
- package/package.json +5 -4
package/index.esm.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import React, { createContext, useMemo, useContext, useState, useEffect, useCallback } from 'react';
|
|
2
|
-
import { Ninetailed, selectVariant, selectHasExperienceVariants, selectActiveExperiments, selectExperience, selectExperienceVariant } from '@ninetailed/experience.js';
|
|
2
|
+
import { Ninetailed, selectVariant, selectDistribution, selectHasExperienceVariants, selectActiveExperiments, selectExperience, selectExperienceVariant } from '@ninetailed/experience.js';
|
|
3
3
|
import { useInView } from 'react-intersection-observer';
|
|
4
4
|
import { isBrowser } from '@ninetailed/experience.js-shared';
|
|
5
5
|
import get$1 from 'lodash/get';
|
|
6
|
+
import has$1 from 'lodash/has';
|
|
6
7
|
|
|
7
8
|
const NinetailedContext = /*#__PURE__*/createContext(undefined);
|
|
8
9
|
|
|
@@ -2333,6 +2334,37 @@ const MergeTag = ({
|
|
|
2333
2334
|
return /*#__PURE__*/React.createElement(React.Fragment, null, value);
|
|
2334
2335
|
};
|
|
2335
2336
|
|
|
2337
|
+
const TrackExperience = ({
|
|
2338
|
+
children,
|
|
2339
|
+
experience,
|
|
2340
|
+
variant,
|
|
2341
|
+
profile
|
|
2342
|
+
}) => {
|
|
2343
|
+
const ninetailed = useNinetailed();
|
|
2344
|
+
const {
|
|
2345
|
+
ref,
|
|
2346
|
+
inView
|
|
2347
|
+
} = useInView({
|
|
2348
|
+
triggerOnce: true
|
|
2349
|
+
});
|
|
2350
|
+
useEffect(() => {
|
|
2351
|
+
if (isBrowser() && inView) {
|
|
2352
|
+
const distribution = selectDistribution({
|
|
2353
|
+
experience,
|
|
2354
|
+
profile
|
|
2355
|
+
});
|
|
2356
|
+
ninetailed.trackExperience({
|
|
2357
|
+
experience,
|
|
2358
|
+
component: variant,
|
|
2359
|
+
variant: distribution.index
|
|
2360
|
+
});
|
|
2361
|
+
}
|
|
2362
|
+
}, [inView]);
|
|
2363
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
|
|
2364
|
+
ref: ref
|
|
2365
|
+
}), children);
|
|
2366
|
+
};
|
|
2367
|
+
|
|
2336
2368
|
var global$2 = global$w;
|
|
2337
2369
|
var aCallable = aCallable$2;
|
|
2338
2370
|
var toObject = toObject$5;
|
|
@@ -2515,7 +2547,8 @@ const useJoinExperiment = ({
|
|
|
2515
2547
|
}) => {
|
|
2516
2548
|
const {
|
|
2517
2549
|
identify
|
|
2518
|
-
} = useNinetailed();
|
|
2550
|
+
} = useNinetailed(); // TODO this gets called twice
|
|
2551
|
+
|
|
2519
2552
|
return useCallback(({
|
|
2520
2553
|
experiment,
|
|
2521
2554
|
profile
|
|
@@ -2523,18 +2556,61 @@ const useJoinExperiment = ({
|
|
|
2523
2556
|
const activeExperiments = selectActiveExperiments(experiences, profile);
|
|
2524
2557
|
|
|
2525
2558
|
if (!activeExperiments.length && experiment.type === 'nt_experiment') {
|
|
2526
|
-
identify(
|
|
2559
|
+
identify(profile.id, {
|
|
2527
2560
|
[`${EXPERIENCE_TRAIT_PREFIX}${experiment.id}`]: true
|
|
2528
2561
|
});
|
|
2529
2562
|
}
|
|
2530
2563
|
}, [experiences]);
|
|
2531
2564
|
};
|
|
2532
2565
|
|
|
2566
|
+
const DefaultExperienceLoadingComponent = _a => {
|
|
2567
|
+
var {
|
|
2568
|
+
component: Component,
|
|
2569
|
+
experiences,
|
|
2570
|
+
unhideAfterMs = 5000
|
|
2571
|
+
} = _a,
|
|
2572
|
+
baseline = __rest(_a, ["component", "experiences", "unhideAfterMs"]);
|
|
2573
|
+
|
|
2574
|
+
const [hidden, setHidden] = useState(true);
|
|
2575
|
+
useEffect(() => {
|
|
2576
|
+
const timer = setTimeout(() => {
|
|
2577
|
+
setHidden(false);
|
|
2578
|
+
}, unhideAfterMs);
|
|
2579
|
+
return () => {
|
|
2580
|
+
clearTimeout(timer);
|
|
2581
|
+
};
|
|
2582
|
+
}, []);
|
|
2583
|
+
|
|
2584
|
+
if (hidden) {
|
|
2585
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
2586
|
+
key: "hide",
|
|
2587
|
+
style: {
|
|
2588
|
+
opacity: 0
|
|
2589
|
+
}
|
|
2590
|
+
}, /*#__PURE__*/React.createElement(Component, Object.assign({}, baseline, {
|
|
2591
|
+
ninetailed: {
|
|
2592
|
+
isPersonalized: false,
|
|
2593
|
+
audience: {
|
|
2594
|
+
id: 'baseline'
|
|
2595
|
+
}
|
|
2596
|
+
}
|
|
2597
|
+
})));
|
|
2598
|
+
}
|
|
2599
|
+
|
|
2600
|
+
return /*#__PURE__*/React.createElement(Component, Object.assign({}, baseline, {
|
|
2601
|
+
ninetailed: {
|
|
2602
|
+
isPersonalized: false,
|
|
2603
|
+
audience: {
|
|
2604
|
+
id: 'baseline'
|
|
2605
|
+
}
|
|
2606
|
+
}
|
|
2607
|
+
}));
|
|
2608
|
+
};
|
|
2533
2609
|
const Experience = _a => {
|
|
2534
2610
|
var {
|
|
2535
2611
|
experiences,
|
|
2536
2612
|
component: Component,
|
|
2537
|
-
loadingComponent: LoadingComponent
|
|
2613
|
+
loadingComponent: LoadingComponent = DefaultExperienceLoadingComponent
|
|
2538
2614
|
} = _a,
|
|
2539
2615
|
baseline = __rest(_a, ["experiences", "component", "loadingComponent"]);
|
|
2540
2616
|
|
|
@@ -2567,74 +2643,112 @@ const Experience = _a => {
|
|
|
2567
2643
|
}
|
|
2568
2644
|
|
|
2569
2645
|
if (status === 'loading') {
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2646
|
+
return /*#__PURE__*/React.createElement(LoadingComponent, Object.assign({}, baseline, {
|
|
2647
|
+
experiences: experiences,
|
|
2648
|
+
component: Component
|
|
2649
|
+
}));
|
|
2650
|
+
}
|
|
2573
2651
|
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
opacity: 0
|
|
2578
|
-
}
|
|
2579
|
-
}, /*#__PURE__*/React.createElement(Component, Object.assign({}, baseline, {
|
|
2652
|
+
if (!experience) {
|
|
2653
|
+
return /*#__PURE__*/React.createElement(Component, Object.assign({}, baseline, {
|
|
2654
|
+
key: baseline.id,
|
|
2580
2655
|
ninetailed: {
|
|
2581
2656
|
isPersonalized: false,
|
|
2582
2657
|
audience: {
|
|
2583
2658
|
id: 'baseline'
|
|
2584
2659
|
}
|
|
2585
2660
|
}
|
|
2586
|
-
}))
|
|
2661
|
+
}));
|
|
2587
2662
|
}
|
|
2588
2663
|
|
|
2589
|
-
if (!
|
|
2590
|
-
return /*#__PURE__*/React.createElement(
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
},
|
|
2596
|
-
hidden: false
|
|
2597
|
-
},
|
|
2598
|
-
audience: {
|
|
2599
|
-
id: 'baseline'
|
|
2600
|
-
},
|
|
2601
|
-
isPersonalized: false
|
|
2664
|
+
if (!variant) {
|
|
2665
|
+
return /*#__PURE__*/React.createElement(TrackExperience, {
|
|
2666
|
+
experience: experience,
|
|
2667
|
+
variant: baseline,
|
|
2668
|
+
// the profile is definitely defined, otherwise there wouldn't be an experience selected
|
|
2669
|
+
profile: profile
|
|
2602
2670
|
}, /*#__PURE__*/React.createElement(Component, Object.assign({}, baseline, {
|
|
2603
2671
|
key: baseline.id,
|
|
2604
2672
|
ninetailed: {
|
|
2605
2673
|
isPersonalized: false,
|
|
2606
2674
|
audience: {
|
|
2607
|
-
id: '
|
|
2675
|
+
id: (audience === null || audience === void 0 ? void 0 : audience.id) || 'all visitors'
|
|
2608
2676
|
}
|
|
2609
2677
|
}
|
|
2610
2678
|
})));
|
|
2611
2679
|
}
|
|
2612
2680
|
|
|
2613
|
-
return (
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
hidden: variant.hidden || false
|
|
2623
|
-
},
|
|
2681
|
+
return /*#__PURE__*/React.createElement(TrackExperience, {
|
|
2682
|
+
experience: experience,
|
|
2683
|
+
variant: variant,
|
|
2684
|
+
// the profile is definitely defined, otherwise there wouldn't be an experience selected
|
|
2685
|
+
profile: profile
|
|
2686
|
+
}, (variant === null || variant === void 0 ? void 0 : variant.hidden) ? null : /*#__PURE__*/React.createElement(Component, Object.assign({}, variant, {
|
|
2687
|
+
key: `${experience.id}-${variant.id}`,
|
|
2688
|
+
ninetailed: {
|
|
2689
|
+
isPersonalized,
|
|
2624
2690
|
audience: {
|
|
2625
|
-
id: (audience === null || audience === void 0 ? void 0 : audience.id) || '
|
|
2626
|
-
},
|
|
2627
|
-
isPersonalized: isPersonalized
|
|
2628
|
-
}, (variant === null || variant === void 0 ? void 0 : variant.hidden) ? null : /*#__PURE__*/React.createElement(Component, Object.assign({}, variant, {
|
|
2629
|
-
key: `${experience.id}-${variant.id}`,
|
|
2630
|
-
ninetailed: {
|
|
2631
|
-
isPersonalized,
|
|
2632
|
-
audience: {
|
|
2633
|
-
id: (audience === null || audience === void 0 ? void 0 : audience.id) || 'baseline'
|
|
2634
|
-
}
|
|
2691
|
+
id: (audience === null || audience === void 0 ? void 0 : audience.id) || 'all visitors'
|
|
2635
2692
|
}
|
|
2636
|
-
}
|
|
2637
|
-
);
|
|
2693
|
+
}
|
|
2694
|
+
})));
|
|
2695
|
+
};
|
|
2696
|
+
|
|
2697
|
+
const ESRContext = /*#__PURE__*/React.createContext(undefined);
|
|
2698
|
+
const ESRProvider = ({
|
|
2699
|
+
experienceVariantsMap,
|
|
2700
|
+
children
|
|
2701
|
+
}) => {
|
|
2702
|
+
return /*#__PURE__*/React.createElement(ESRContext.Provider, {
|
|
2703
|
+
value: {
|
|
2704
|
+
experienceVariantsMap
|
|
2705
|
+
}
|
|
2706
|
+
}, children);
|
|
2707
|
+
};
|
|
2708
|
+
const useESR = () => {
|
|
2709
|
+
const context = React.useContext(ESRContext);
|
|
2710
|
+
|
|
2711
|
+
if (context === undefined) {
|
|
2712
|
+
throw new Error('The component using the the context must be a descendant of the ESRProvider');
|
|
2713
|
+
}
|
|
2714
|
+
|
|
2715
|
+
return {
|
|
2716
|
+
experienceVariantsMap: context.experienceVariantsMap
|
|
2717
|
+
};
|
|
2718
|
+
};
|
|
2719
|
+
const ESRLoadingComponent = _a => {
|
|
2720
|
+
var {
|
|
2721
|
+
experiences,
|
|
2722
|
+
component: Component
|
|
2723
|
+
} = _a,
|
|
2724
|
+
baseline = __rest(_a, ["experiences", "component"]);
|
|
2725
|
+
|
|
2726
|
+
const {
|
|
2727
|
+
experienceVariantsMap
|
|
2728
|
+
} = useESR();
|
|
2729
|
+
const experience = experiences.find(experience => has$1(experienceVariantsMap, experience.id));
|
|
2730
|
+
|
|
2731
|
+
if (!experience) {
|
|
2732
|
+
return /*#__PURE__*/React.createElement(Component, Object.assign({}, baseline));
|
|
2733
|
+
}
|
|
2734
|
+
|
|
2735
|
+
const component = experience.components.find(component => component.baseline.id === baseline.id);
|
|
2736
|
+
|
|
2737
|
+
if (!component) {
|
|
2738
|
+
return /*#__PURE__*/React.createElement(Component, Object.assign({}, baseline));
|
|
2739
|
+
}
|
|
2740
|
+
|
|
2741
|
+
if (experienceVariantsMap[experience.id] === 0) {
|
|
2742
|
+
return /*#__PURE__*/React.createElement(Component, Object.assign({}, baseline));
|
|
2743
|
+
}
|
|
2744
|
+
|
|
2745
|
+
const variant = component.variants[experienceVariantsMap[experience.id] - 1];
|
|
2746
|
+
|
|
2747
|
+
if (!variant) {
|
|
2748
|
+
return /*#__PURE__*/React.createElement(Component, Object.assign({}, baseline));
|
|
2749
|
+
}
|
|
2750
|
+
|
|
2751
|
+
return /*#__PURE__*/React.createElement(Component, Object.assign({}, variant));
|
|
2638
2752
|
};
|
|
2639
2753
|
|
|
2640
|
-
export { Experience, MergeTag, NinetailedProvider, Personalize, TrackHasSeenComponent, useNinetailed, usePersonalize, useProfile };
|
|
2754
|
+
export { DefaultExperienceLoadingComponent, ESRLoadingComponent, ESRProvider, Experience, MergeTag, NinetailedProvider, Personalize, TrackHasSeenComponent, useNinetailed, usePersonalize, useProfile };
|
package/index.umd.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
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')) :
|
|
3
|
-
typeof define === 'function' && define.amd ? define(['exports', 'react', '@ninetailed/experience.js', 'react-intersection-observer', '@ninetailed/experience.js-shared', 'lodash/get'], 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));
|
|
5
|
-
})(this, (function (exports, React, experience_js, reactIntersectionObserver, experience_jsShared, get$1) { 'use strict';
|
|
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';
|
|
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
10
|
var get__default = /*#__PURE__*/_interopDefaultLegacy(get$1);
|
|
11
|
+
var has__default = /*#__PURE__*/_interopDefaultLegacy(has$1);
|
|
11
12
|
|
|
12
13
|
var NinetailedContext = /*#__PURE__*/React.createContext(undefined);
|
|
13
14
|
|
|
@@ -1883,6 +1884,37 @@
|
|
|
1883
1884
|
return /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, value);
|
|
1884
1885
|
};
|
|
1885
1886
|
|
|
1887
|
+
var TrackExperience = function TrackExperience(_a) {
|
|
1888
|
+
var children = _a.children,
|
|
1889
|
+
experience = _a.experience,
|
|
1890
|
+
variant = _a.variant,
|
|
1891
|
+
profile = _a.profile;
|
|
1892
|
+
var ninetailed = useNinetailed();
|
|
1893
|
+
|
|
1894
|
+
var _b = reactIntersectionObserver.useInView({
|
|
1895
|
+
triggerOnce: true
|
|
1896
|
+
}),
|
|
1897
|
+
ref = _b.ref,
|
|
1898
|
+
inView = _b.inView;
|
|
1899
|
+
|
|
1900
|
+
React.useEffect(function () {
|
|
1901
|
+
if (experience_jsShared.isBrowser() && inView) {
|
|
1902
|
+
var distribution = experience_js.selectDistribution({
|
|
1903
|
+
experience: experience,
|
|
1904
|
+
profile: profile
|
|
1905
|
+
});
|
|
1906
|
+
ninetailed.trackExperience({
|
|
1907
|
+
experience: experience,
|
|
1908
|
+
component: variant,
|
|
1909
|
+
variant: distribution.index
|
|
1910
|
+
});
|
|
1911
|
+
}
|
|
1912
|
+
}, [inView]);
|
|
1913
|
+
return /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, /*#__PURE__*/React__default["default"].createElement("div", {
|
|
1914
|
+
ref: ref
|
|
1915
|
+
}), children);
|
|
1916
|
+
};
|
|
1917
|
+
|
|
1886
1918
|
var global$2 = global$t;
|
|
1887
1919
|
var aCallable = aCallable$2;
|
|
1888
1920
|
var toObject = toObject$3;
|
|
@@ -2063,7 +2095,8 @@
|
|
|
2063
2095
|
|
|
2064
2096
|
var useJoinExperiment = function useJoinExperiment(_a) {
|
|
2065
2097
|
var experiences = _a.experiences;
|
|
2066
|
-
var identify = useNinetailed().identify;
|
|
2098
|
+
var identify = useNinetailed().identify; // TODO this gets called twice
|
|
2099
|
+
|
|
2067
2100
|
return React.useCallback(function (_a) {
|
|
2068
2101
|
var _b;
|
|
2069
2102
|
|
|
@@ -2072,28 +2105,74 @@
|
|
|
2072
2105
|
var activeExperiments = experience_js.selectActiveExperiments(experiences, profile);
|
|
2073
2106
|
|
|
2074
2107
|
if (!activeExperiments.length && experiment.type === 'nt_experiment') {
|
|
2075
|
-
identify(
|
|
2108
|
+
identify(profile.id, (_b = {}, _b["".concat(EXPERIENCE_TRAIT_PREFIX).concat(experiment.id)] = true, _b));
|
|
2076
2109
|
}
|
|
2077
2110
|
}, [experiences]);
|
|
2078
2111
|
};
|
|
2079
2112
|
|
|
2113
|
+
var DefaultExperienceLoadingComponent = function DefaultExperienceLoadingComponent(_a) {
|
|
2114
|
+
var Component = _a.component;
|
|
2115
|
+
_a.experiences;
|
|
2116
|
+
var _b = _a.unhideAfterMs,
|
|
2117
|
+
unhideAfterMs = _b === void 0 ? 5000 : _b,
|
|
2118
|
+
baseline = __rest(_a, ["component", "experiences", "unhideAfterMs"]);
|
|
2119
|
+
|
|
2120
|
+
var _c = React.useState(true),
|
|
2121
|
+
hidden = _c[0],
|
|
2122
|
+
setHidden = _c[1];
|
|
2123
|
+
|
|
2124
|
+
React.useEffect(function () {
|
|
2125
|
+
var timer = setTimeout(function () {
|
|
2126
|
+
setHidden(false);
|
|
2127
|
+
}, unhideAfterMs);
|
|
2128
|
+
return function () {
|
|
2129
|
+
clearTimeout(timer);
|
|
2130
|
+
};
|
|
2131
|
+
}, []);
|
|
2132
|
+
|
|
2133
|
+
if (hidden) {
|
|
2134
|
+
return /*#__PURE__*/React__default["default"].createElement("div", {
|
|
2135
|
+
key: "hide",
|
|
2136
|
+
style: {
|
|
2137
|
+
opacity: 0
|
|
2138
|
+
}
|
|
2139
|
+
}, /*#__PURE__*/React__default["default"].createElement(Component, __assign({}, baseline, {
|
|
2140
|
+
ninetailed: {
|
|
2141
|
+
isPersonalized: false,
|
|
2142
|
+
audience: {
|
|
2143
|
+
id: 'baseline'
|
|
2144
|
+
}
|
|
2145
|
+
}
|
|
2146
|
+
})));
|
|
2147
|
+
}
|
|
2148
|
+
|
|
2149
|
+
return /*#__PURE__*/React__default["default"].createElement(Component, __assign({}, baseline, {
|
|
2150
|
+
ninetailed: {
|
|
2151
|
+
isPersonalized: false,
|
|
2152
|
+
audience: {
|
|
2153
|
+
id: 'baseline'
|
|
2154
|
+
}
|
|
2155
|
+
}
|
|
2156
|
+
}));
|
|
2157
|
+
};
|
|
2080
2158
|
var Experience = function Experience(_a) {
|
|
2081
2159
|
var experiences = _a.experiences,
|
|
2082
2160
|
Component = _a.component,
|
|
2083
|
-
|
|
2161
|
+
_b = _a.loadingComponent,
|
|
2162
|
+
LoadingComponent = _b === void 0 ? DefaultExperienceLoadingComponent : _b,
|
|
2084
2163
|
baseline = __rest(_a, ["experiences", "component", "loadingComponent"]);
|
|
2085
2164
|
|
|
2086
|
-
var
|
|
2165
|
+
var _c = useExperience({
|
|
2087
2166
|
baseline: baseline,
|
|
2088
2167
|
experiences: experiences
|
|
2089
2168
|
}),
|
|
2090
|
-
status =
|
|
2091
|
-
hasVariants =
|
|
2092
|
-
experience =
|
|
2093
|
-
variant =
|
|
2094
|
-
audience =
|
|
2095
|
-
isPersonalized =
|
|
2096
|
-
profile =
|
|
2169
|
+
status = _c.status,
|
|
2170
|
+
hasVariants = _c.hasVariants,
|
|
2171
|
+
experience = _c.experience,
|
|
2172
|
+
variant = _c.variant,
|
|
2173
|
+
audience = _c.audience,
|
|
2174
|
+
isPersonalized = _c.isPersonalized,
|
|
2175
|
+
profile = _c.profile;
|
|
2097
2176
|
|
|
2098
2177
|
var joinExperiment = useJoinExperiment({
|
|
2099
2178
|
experiences: experiences
|
|
@@ -2112,76 +2191,116 @@
|
|
|
2112
2191
|
}
|
|
2113
2192
|
|
|
2114
2193
|
if (status === 'loading') {
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2194
|
+
return /*#__PURE__*/React__default["default"].createElement(LoadingComponent, __assign({}, baseline, {
|
|
2195
|
+
experiences: experiences,
|
|
2196
|
+
component: Component
|
|
2197
|
+
}));
|
|
2198
|
+
}
|
|
2118
2199
|
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
opacity: 0
|
|
2123
|
-
}
|
|
2124
|
-
}, /*#__PURE__*/React__default["default"].createElement(Component, __assign({}, baseline, {
|
|
2200
|
+
if (!experience) {
|
|
2201
|
+
return /*#__PURE__*/React__default["default"].createElement(Component, __assign({}, baseline, {
|
|
2202
|
+
key: baseline.id,
|
|
2125
2203
|
ninetailed: {
|
|
2126
2204
|
isPersonalized: false,
|
|
2127
2205
|
audience: {
|
|
2128
2206
|
id: 'baseline'
|
|
2129
2207
|
}
|
|
2130
2208
|
}
|
|
2131
|
-
}))
|
|
2209
|
+
}));
|
|
2132
2210
|
}
|
|
2133
2211
|
|
|
2134
|
-
if (!
|
|
2135
|
-
return /*#__PURE__*/React__default["default"].createElement(
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
},
|
|
2141
|
-
hidden: false
|
|
2142
|
-
},
|
|
2143
|
-
audience: {
|
|
2144
|
-
id: 'baseline'
|
|
2145
|
-
},
|
|
2146
|
-
isPersonalized: false
|
|
2212
|
+
if (!variant) {
|
|
2213
|
+
return /*#__PURE__*/React__default["default"].createElement(TrackExperience, {
|
|
2214
|
+
experience: experience,
|
|
2215
|
+
variant: baseline,
|
|
2216
|
+
// the profile is definitely defined, otherwise there wouldn't be an experience selected
|
|
2217
|
+
profile: profile
|
|
2147
2218
|
}, /*#__PURE__*/React__default["default"].createElement(Component, __assign({}, baseline, {
|
|
2148
2219
|
key: baseline.id,
|
|
2149
2220
|
ninetailed: {
|
|
2150
2221
|
isPersonalized: false,
|
|
2151
2222
|
audience: {
|
|
2152
|
-
id: '
|
|
2223
|
+
id: (audience === null || audience === void 0 ? void 0 : audience.id) || 'all visitors'
|
|
2153
2224
|
}
|
|
2154
2225
|
}
|
|
2155
2226
|
})));
|
|
2156
2227
|
}
|
|
2157
2228
|
|
|
2158
|
-
return (
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
hidden: variant.hidden || false
|
|
2168
|
-
},
|
|
2229
|
+
return /*#__PURE__*/React__default["default"].createElement(TrackExperience, {
|
|
2230
|
+
experience: experience,
|
|
2231
|
+
variant: variant,
|
|
2232
|
+
// the profile is definitely defined, otherwise there wouldn't be an experience selected
|
|
2233
|
+
profile: profile
|
|
2234
|
+
}, (variant === null || variant === void 0 ? void 0 : variant.hidden) ? null : /*#__PURE__*/React__default["default"].createElement(Component, __assign({}, variant, {
|
|
2235
|
+
key: "".concat(experience.id, "-").concat(variant.id),
|
|
2236
|
+
ninetailed: {
|
|
2237
|
+
isPersonalized: isPersonalized,
|
|
2169
2238
|
audience: {
|
|
2170
|
-
id: (audience === null || audience === void 0 ? void 0 : audience.id) || '
|
|
2171
|
-
},
|
|
2172
|
-
isPersonalized: isPersonalized
|
|
2173
|
-
}, (variant === null || variant === void 0 ? void 0 : variant.hidden) ? null : /*#__PURE__*/React__default["default"].createElement(Component, __assign({}, variant, {
|
|
2174
|
-
key: "".concat(experience.id, "-").concat(variant.id),
|
|
2175
|
-
ninetailed: {
|
|
2176
|
-
isPersonalized: isPersonalized,
|
|
2177
|
-
audience: {
|
|
2178
|
-
id: (audience === null || audience === void 0 ? void 0 : audience.id) || 'baseline'
|
|
2179
|
-
}
|
|
2239
|
+
id: (audience === null || audience === void 0 ? void 0 : audience.id) || 'all visitors'
|
|
2180
2240
|
}
|
|
2181
|
-
}
|
|
2182
|
-
);
|
|
2241
|
+
}
|
|
2242
|
+
})));
|
|
2243
|
+
};
|
|
2244
|
+
|
|
2245
|
+
var ESRContext = /*#__PURE__*/React__default["default"].createContext(undefined);
|
|
2246
|
+
var ESRProvider = function ESRProvider(_a) {
|
|
2247
|
+
var experienceVariantsMap = _a.experienceVariantsMap,
|
|
2248
|
+
children = _a.children;
|
|
2249
|
+
return /*#__PURE__*/React__default["default"].createElement(ESRContext.Provider, {
|
|
2250
|
+
value: {
|
|
2251
|
+
experienceVariantsMap: experienceVariantsMap
|
|
2252
|
+
}
|
|
2253
|
+
}, children);
|
|
2254
|
+
};
|
|
2255
|
+
var useESR = function useESR() {
|
|
2256
|
+
var context = React__default["default"].useContext(ESRContext);
|
|
2257
|
+
|
|
2258
|
+
if (context === undefined) {
|
|
2259
|
+
throw new Error('The component using the the context must be a descendant of the ESRProvider');
|
|
2260
|
+
}
|
|
2261
|
+
|
|
2262
|
+
return {
|
|
2263
|
+
experienceVariantsMap: context.experienceVariantsMap
|
|
2264
|
+
};
|
|
2265
|
+
};
|
|
2266
|
+
var ESRLoadingComponent = function ESRLoadingComponent(_a) {
|
|
2267
|
+
var experiences = _a.experiences,
|
|
2268
|
+
Component = _a.component,
|
|
2269
|
+
baseline = __rest(_a, ["experiences", "component"]);
|
|
2270
|
+
|
|
2271
|
+
var experienceVariantsMap = useESR().experienceVariantsMap;
|
|
2272
|
+
var experience = experiences.find(function (experience) {
|
|
2273
|
+
return has__default["default"](experienceVariantsMap, experience.id);
|
|
2274
|
+
});
|
|
2275
|
+
|
|
2276
|
+
if (!experience) {
|
|
2277
|
+
return /*#__PURE__*/React__default["default"].createElement(Component, __assign({}, baseline));
|
|
2278
|
+
}
|
|
2279
|
+
|
|
2280
|
+
var component = experience.components.find(function (component) {
|
|
2281
|
+
return component.baseline.id === baseline.id;
|
|
2282
|
+
});
|
|
2283
|
+
|
|
2284
|
+
if (!component) {
|
|
2285
|
+
return /*#__PURE__*/React__default["default"].createElement(Component, __assign({}, baseline));
|
|
2286
|
+
}
|
|
2287
|
+
|
|
2288
|
+
if (experienceVariantsMap[experience.id] === 0) {
|
|
2289
|
+
return /*#__PURE__*/React__default["default"].createElement(Component, __assign({}, baseline));
|
|
2290
|
+
}
|
|
2291
|
+
|
|
2292
|
+
var variant = component.variants[experienceVariantsMap[experience.id] - 1];
|
|
2293
|
+
|
|
2294
|
+
if (!variant) {
|
|
2295
|
+
return /*#__PURE__*/React__default["default"].createElement(Component, __assign({}, baseline));
|
|
2296
|
+
}
|
|
2297
|
+
|
|
2298
|
+
return /*#__PURE__*/React__default["default"].createElement(Component, __assign({}, variant));
|
|
2183
2299
|
};
|
|
2184
2300
|
|
|
2301
|
+
exports.DefaultExperienceLoadingComponent = DefaultExperienceLoadingComponent;
|
|
2302
|
+
exports.ESRLoadingComponent = ESRLoadingComponent;
|
|
2303
|
+
exports.ESRProvider = ESRProvider;
|
|
2185
2304
|
exports.Experience = Experience;
|
|
2186
2305
|
exports.MergeTag = MergeTag;
|
|
2187
2306
|
exports.NinetailedProvider = NinetailedProvider;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ExperienceLoadingComponent } from './Experience';
|
|
3
|
+
declare type ESRContextValue = {
|
|
4
|
+
experienceVariantsMap: Record<string, number>;
|
|
5
|
+
};
|
|
6
|
+
export declare const ESRContext: React.Context<ESRContextValue | undefined>;
|
|
7
|
+
declare type ESRProviderProps = {
|
|
8
|
+
experienceVariantsMap: Record<string, number>;
|
|
9
|
+
};
|
|
10
|
+
export declare const ESRProvider: React.FC<ESRProviderProps>;
|
|
11
|
+
export declare const useESR: () => {
|
|
12
|
+
experienceVariantsMap: Record<string, number>;
|
|
13
|
+
};
|
|
14
|
+
export declare const ESRLoadingComponent: ExperienceLoadingComponent;
|
|
15
|
+
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Baseline, ExperienceConfiguration } from '@ninetailed/experience.js';
|
|
3
|
-
declare type ExperienceComponent<P extends Baseline> = React.ComponentType<Omit<P, 'id'> & {
|
|
3
|
+
export declare type ExperienceComponent<P extends Baseline> = React.ComponentType<Omit<P, 'id'> & {
|
|
4
4
|
ninetailed?: {
|
|
5
5
|
isPersonalized: boolean;
|
|
6
6
|
audience: {
|
|
@@ -8,11 +8,20 @@ declare type ExperienceComponent<P extends Baseline> = React.ComponentType<Omit<
|
|
|
8
8
|
};
|
|
9
9
|
};
|
|
10
10
|
}>;
|
|
11
|
-
declare type
|
|
11
|
+
export declare type ExperienceBaseProps<P extends Baseline = Baseline> = P & {
|
|
12
12
|
experiences: ExperienceConfiguration[];
|
|
13
13
|
component: ExperienceComponent<P> | React.ComponentType<P>;
|
|
14
|
-
loadingComponent?: React.ComponentType;
|
|
15
14
|
};
|
|
15
|
+
export declare type ExperienceLoadingComponent<P extends Baseline = Baseline> = React.ComponentType<ExperienceBaseProps<P>>;
|
|
16
|
+
export declare type ExperienceProps<P extends Baseline> = ExperienceBaseProps<P> & {
|
|
17
|
+
experiences: ExperienceConfiguration[];
|
|
18
|
+
component: ExperienceComponent<P> | React.ComponentType<P>;
|
|
19
|
+
loadingComponent?: ExperienceLoadingComponent<P>;
|
|
20
|
+
};
|
|
21
|
+
declare type DefaultExperienceLoadingComponentProps = ExperienceBaseProps & {
|
|
22
|
+
unhideAfterMs?: number;
|
|
23
|
+
};
|
|
24
|
+
export declare const DefaultExperienceLoadingComponent: React.FC<DefaultExperienceLoadingComponentProps>;
|
|
16
25
|
export declare const Experience: <P extends {
|
|
17
26
|
id: string;
|
|
18
27
|
}>({ experiences, component: Component, loadingComponent: LoadingComponent, ...baseline }: ExperienceProps<P>) => JSX.Element;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Profile } from '@ninetailed/experience.js-shared';
|
|
3
|
+
import { ExperienceConfiguration } from '@ninetailed/experience.js';
|
|
4
|
+
declare type TrackExperienceProps = {
|
|
5
|
+
experience: ExperienceConfiguration;
|
|
6
|
+
variant: {
|
|
7
|
+
id: string;
|
|
8
|
+
};
|
|
9
|
+
profile: Profile;
|
|
10
|
+
};
|
|
11
|
+
export declare const TrackExperience: React.FC<React.PropsWithChildren<TrackExperienceProps>>;
|
|
12
|
+
export {};
|
|
@@ -1 +1,3 @@
|
|
|
1
|
-
export { Experience } from './Experience';
|
|
1
|
+
export { Experience, DefaultExperienceLoadingComponent } from './Experience';
|
|
2
|
+
export type { ExperienceProps, ExperienceBaseProps, ExperienceComponent, ExperienceLoadingComponent } from './Experience';
|
|
3
|
+
export { ESRProvider, ESRLoadingComponent } from './ESRLoadingComponent';
|
package/lib/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export type { Profile, Variant } from '@ninetailed/experience.js-shared';
|
|
2
|
-
export type { ExperienceConfiguration, ExperienceType, } from '@ninetailed/experience.js';
|
|
2
|
+
export type { ExperienceConfiguration, ExperienceType, EXPERIENCE_TRAIT_PREFIX, } from '@ninetailed/experience.js';
|
|
3
3
|
export { NinetailedProvider } from './NinetailedProvider';
|
|
4
4
|
export type { NinetailedProviderProps } from './NinetailedProvider';
|
|
5
5
|
export { useNinetailed } from './useNinetailed';
|
|
@@ -9,4 +9,5 @@ export { Personalize } from './Personalize';
|
|
|
9
9
|
export type { PersonalizedComponent } from './Personalize';
|
|
10
10
|
export { MergeTag } from './MergeTag';
|
|
11
11
|
export { TrackHasSeenComponent } from './TrackHasSeenComponent';
|
|
12
|
-
export { Experience } from './Experience';
|
|
12
|
+
export { Experience, ESRProvider, ESRLoadingComponent, DefaultExperienceLoadingComponent } from './Experience';
|
|
13
|
+
export type { ExperienceProps, ExperienceBaseProps, ExperienceComponent, ExperienceLoadingComponent, } from './Experience';
|
package/package.json
CHANGED
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ninetailed/experience.js-react",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.2",
|
|
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
|
-
"
|
|
10
|
+
"lodash": "^4.17.21",
|
|
11
|
+
"@ninetailed/experience.js": "2.0.2",
|
|
11
12
|
"analytics": "^0.8.0",
|
|
12
|
-
"@ninetailed/experience.js-shared": "2.0.
|
|
13
|
+
"@ninetailed/experience.js-shared": "2.0.2",
|
|
13
14
|
"uuid": "^8.3.2",
|
|
14
15
|
"ts-toolbelt": "^9.6.0",
|
|
15
16
|
"locale-enum": "^1.1.1",
|
|
16
17
|
"i18n-iso-countries": "^7.3.0",
|
|
17
|
-
"
|
|
18
|
+
"loglevel": "^1.8.0",
|
|
18
19
|
"murmurhash-js": "^1.0.0",
|
|
19
20
|
"react-intersection-observer": "^8.33.1"
|
|
20
21
|
},
|