@ninetailed/experience.js 5.0.0-beta.3 → 6.0.1-beta.0

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.js CHANGED
@@ -1,10 +1,11 @@
1
1
  import { FEATURES, logger, ConsoleLogSink, buildPageEvent, buildTrackEvent, buildIdentifyEvent, unionBy, NinetailedApiClient, OnLogLogSink, OnErrorLogSink, PageviewProperties, Properties, Traits, pipe } from '@ninetailed/experience.js-shared';
2
- export { EXPERIENCE_TRAIT_PREFIX, isExperienceMatch, selectActiveExperiments, selectDistribution, selectEligibleExperiences, selectExperience, selectBaselineWithVariants as selectExperienceBaselineWithVariants, selectVariantClientSide as selectExperienceVariantClientSide, selectVariants as selectExperienceVariants, selectHasVariants as selectHasExperienceVariants } from '@ninetailed/experience.js-shared';
2
+ export { EXPERIENCE_TRAIT_PREFIX, isExperienceMatch, selectActiveExperiments, selectDistribution, selectEligibleExperiences, selectExperience, selectBaselineWithVariants as selectExperienceBaselineWithVariants, selectVariant as selectExperienceVariant, selectVariants as selectExperienceVariants, selectHasVariants as selectHasExperienceVariants } from '@ninetailed/experience.js-shared';
3
3
  import Analytics from 'analytics';
4
4
  import { z } from 'zod';
5
5
 
6
- const HAS_SEEN_EXPERIENCE = 'has_seen_experience';
7
6
  const HAS_SEEN_COMPONENT = 'has_seen_component';
7
+ const HAS_SEEN_ELEMENT = 'has_seen_element';
8
+ const PAGE_HIDDEN = 'page_hidden';
8
9
 
9
10
  var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
10
11
 
@@ -602,9 +603,9 @@ var inspectSource$3 = store$1.inspectSource;
602
603
  var global$d = global$k;
603
604
  var isCallable$d = isCallable$k;
604
605
 
605
- var WeakMap$1 = global$d.WeakMap;
606
+ var WeakMap$2 = global$d.WeakMap;
606
607
 
607
- var weakMapBasicDetection = isCallable$d(WeakMap$1) && /native code/.test(String(WeakMap$1));
608
+ var weakMapBasicDetection = isCallable$d(WeakMap$2) && /native code/.test(String(WeakMap$2));
608
609
 
609
610
  var shared$1 = shared$3.exports;
610
611
  var uid = uid$2;
@@ -628,7 +629,7 @@ var hiddenKeys$3 = hiddenKeys$4;
628
629
 
629
630
  var OBJECT_ALREADY_INITIALIZED = 'Object already initialized';
630
631
  var TypeError$2 = global$c.TypeError;
631
- var WeakMap = global$c.WeakMap;
632
+ var WeakMap$1 = global$c.WeakMap;
632
633
  var set$1, get, has;
633
634
 
634
635
  var enforce = function (it) {
@@ -645,7 +646,7 @@ var getterFor = function (TYPE) {
645
646
  };
646
647
 
647
648
  if (NATIVE_WEAK_MAP || shared.state) {
648
- var store = shared.state || (shared.state = new WeakMap());
649
+ var store = shared.state || (shared.state = new WeakMap$1());
649
650
  /* eslint-disable no-self-assign -- prototype methods protection */
650
651
  store.get = store.get;
651
652
  store.has = store.has;
@@ -2517,6 +2518,18 @@ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
2517
2518
  PERFORMANCE OF THIS SOFTWARE.
2518
2519
  ***************************************************************************** */
2519
2520
 
2521
+ function __rest(s, e) {
2522
+ var t = {};
2523
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
2524
+ t[p] = s[p];
2525
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
2526
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
2527
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
2528
+ t[p[i]] = s[p[i]];
2529
+ }
2530
+ return t;
2531
+ }
2532
+
2520
2533
  function __awaiter(thisArg, _arguments, P, generator) {
2521
2534
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
2522
2535
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -2572,7 +2585,6 @@ const LEGACY_ANONYMOUS_ID = '__anon_id';
2572
2585
  const ANONYMOUS_ID = '__nt_anonymous_id__';
2573
2586
  const DEBUG_FLAG = '__nt_debug__';
2574
2587
  const PROFILE_FALLBACK_CACHE = '__nt_profile__';
2575
- const EXPERIENCES_FALLBACK_CACHE = '__nt_experiences__';
2576
2588
  const PROFILE_CHANGE = 'profile-change';
2577
2589
  const PROFILE_RESET = 'profile-reset';
2578
2590
  const CONSENT = '__nt-consent__';
@@ -2601,10 +2613,7 @@ const ninetailedPlugin = ({
2601
2613
  }
2602
2614
  try {
2603
2615
  const anonymousId = _instance.storage.getItem(ANONYMOUS_ID);
2604
- const {
2605
- profile,
2606
- experiences
2607
- } = yield apiClient.upsertProfile({
2616
+ const profile = yield apiClient.upsertProfile({
2608
2617
  profileId: anonymousId,
2609
2618
  events
2610
2619
  }, {
@@ -2613,13 +2622,10 @@ const ninetailedPlugin = ({
2613
2622
  });
2614
2623
  _instance.storage.setItem(ANONYMOUS_ID, profile.id);
2615
2624
  _instance.storage.setItem(PROFILE_FALLBACK_CACHE, profile);
2616
- _instance.storage.setItem(EXPERIENCES_FALLBACK_CACHE, experiences);
2617
2625
  logger.debug('Profile from api: ', profile);
2618
- logger.debug('Experiences from api: ', experiences);
2619
2626
  _instance.dispatch({
2620
2627
  type: PROFILE_CHANGE,
2621
- profile,
2622
- experiences
2628
+ profile
2623
2629
  });
2624
2630
  yield delay(20);
2625
2631
  return {
@@ -2628,27 +2634,27 @@ const ninetailedPlugin = ({
2628
2634
  } catch (error) {
2629
2635
  logger.debug('An error occurred during flushing the events: ', error);
2630
2636
  const fallbackProfile = _instance.storage.getItem(PROFILE_FALLBACK_CACHE);
2631
- const fallbackExperiences = _instance.storage.getItem(EXPERIENCES_FALLBACK_CACHE) || [];
2632
2637
  if (fallbackProfile) {
2633
2638
  logger.debug('Found a fallback profile - will use this.');
2634
2639
  _instance.dispatch({
2635
2640
  type: PROFILE_CHANGE,
2636
- profile: fallbackProfile,
2637
- experiences: fallbackExperiences
2641
+ profile: fallbackProfile
2638
2642
  });
2643
+ return {
2644
+ success: false
2645
+ };
2639
2646
  } else {
2640
2647
  logger.debug('No fallback profile found - setting profile to null.');
2641
2648
  _instance.dispatch({
2642
2649
  type: PROFILE_CHANGE,
2643
2650
  // TODO is it a good idea to set the profile to null?
2644
2651
  profile: null,
2645
- experiences: fallbackExperiences,
2646
2652
  error
2647
2653
  });
2654
+ return {
2655
+ success: false
2656
+ };
2648
2657
  }
2649
- return {
2650
- success: false
2651
- };
2652
2658
  }
2653
2659
  });
2654
2660
  const enqueueEvent = event => __awaiter(void 0, void 0, void 0, function* () {
@@ -2747,7 +2753,7 @@ const ninetailedPlugin = ({
2747
2753
  abort,
2748
2754
  payload
2749
2755
  }) => {
2750
- if (![ANONYMOUS_ID, DEBUG_FLAG, PROFILE_FALLBACK_CACHE, EXPERIENCES_FALLBACK_CACHE, CONSENT].includes(payload.key)) {
2756
+ if (![ANONYMOUS_ID, DEBUG_FLAG, PROFILE_FALLBACK_CACHE, CONSENT].includes(payload.key)) {
2751
2757
  return abort();
2752
2758
  }
2753
2759
  return payload;
@@ -2762,7 +2768,6 @@ const ninetailedPlugin = ({
2762
2768
  });
2763
2769
  instance.storage.removeItem(ANONYMOUS_ID);
2764
2770
  instance.storage.removeItem(PROFILE_FALLBACK_CACHE);
2765
- instance.storage.removeItem(EXPERIENCES_FALLBACK_CACHE);
2766
2771
  logger.debug('Removed old profile data from localstorage.');
2767
2772
  yield ninetailed.track('nt_reset');
2768
2773
  logger.info('Profile reset successful.');
@@ -2843,6 +2848,115 @@ if (NOT_GENERIC || INCORRECT_NAME) {
2843
2848
  }, { unsafe: true });
2844
2849
  }
2845
2850
 
2851
+ var classof = classofRaw$2;
2852
+
2853
+ // `IsArray` abstract operation
2854
+ // https://tc39.es/ecma262/#sec-isarray
2855
+ // eslint-disable-next-line es/no-array-isarray -- safe
2856
+ var isArray$2 = Array.isArray || function isArray(argument) {
2857
+ return classof(argument) == 'Array';
2858
+ };
2859
+
2860
+ var $TypeError$1 = TypeError;
2861
+ var MAX_SAFE_INTEGER = 0x1FFFFFFFFFFFFF; // 2 ** 53 - 1 == 9007199254740991
2862
+
2863
+ var doesNotExceedSafeInteger$1 = function (it) {
2864
+ if (it > MAX_SAFE_INTEGER) throw $TypeError$1('Maximum allowed index exceeded');
2865
+ return it;
2866
+ };
2867
+
2868
+ var isArray$1 = isArray$2;
2869
+ var lengthOfArrayLike$2 = lengthOfArrayLike$5;
2870
+ var doesNotExceedSafeInteger = doesNotExceedSafeInteger$1;
2871
+ var bind = functionBindContext;
2872
+
2873
+ // `FlattenIntoArray` abstract operation
2874
+ // https://tc39.github.io/proposal-flatMap/#sec-FlattenIntoArray
2875
+ var flattenIntoArray$1 = function (target, original, source, sourceLen, start, depth, mapper, thisArg) {
2876
+ var targetIndex = start;
2877
+ var sourceIndex = 0;
2878
+ var mapFn = mapper ? bind(mapper, thisArg) : false;
2879
+ var element, elementLen;
2880
+
2881
+ while (sourceIndex < sourceLen) {
2882
+ if (sourceIndex in source) {
2883
+ element = mapFn ? mapFn(source[sourceIndex], sourceIndex, original) : source[sourceIndex];
2884
+
2885
+ if (depth > 0 && isArray$1(element)) {
2886
+ elementLen = lengthOfArrayLike$2(element);
2887
+ targetIndex = flattenIntoArray$1(target, original, element, elementLen, targetIndex, depth - 1) - 1;
2888
+ } else {
2889
+ doesNotExceedSafeInteger(targetIndex + 1);
2890
+ target[targetIndex] = element;
2891
+ }
2892
+
2893
+ targetIndex++;
2894
+ }
2895
+ sourceIndex++;
2896
+ }
2897
+ return targetIndex;
2898
+ };
2899
+
2900
+ var flattenIntoArray_1 = flattenIntoArray$1;
2901
+
2902
+ var isArray = isArray$2;
2903
+ var isConstructor = isConstructor$2;
2904
+ var isObject$1 = isObject$a;
2905
+ var wellKnownSymbol$3 = wellKnownSymbol$h;
2906
+
2907
+ var SPECIES = wellKnownSymbol$3('species');
2908
+ var $Array = Array;
2909
+
2910
+ // a part of `ArraySpeciesCreate` abstract operation
2911
+ // https://tc39.es/ecma262/#sec-arrayspeciescreate
2912
+ var arraySpeciesConstructor$1 = function (originalArray) {
2913
+ var C;
2914
+ if (isArray(originalArray)) {
2915
+ C = originalArray.constructor;
2916
+ // cross-realm fallback
2917
+ if (isConstructor(C) && (C === $Array || isArray(C.prototype))) C = undefined;
2918
+ else if (isObject$1(C)) {
2919
+ C = C[SPECIES];
2920
+ if (C === null) C = undefined;
2921
+ }
2922
+ } return C === undefined ? $Array : C;
2923
+ };
2924
+
2925
+ var arraySpeciesConstructor = arraySpeciesConstructor$1;
2926
+
2927
+ // `ArraySpeciesCreate` abstract operation
2928
+ // https://tc39.es/ecma262/#sec-arrayspeciescreate
2929
+ var arraySpeciesCreate$1 = function (originalArray, length) {
2930
+ return new (arraySpeciesConstructor(originalArray))(length === 0 ? 0 : length);
2931
+ };
2932
+
2933
+ var $$3 = _export;
2934
+ var flattenIntoArray = flattenIntoArray_1;
2935
+ var toObject$2 = toObject$5;
2936
+ var lengthOfArrayLike$1 = lengthOfArrayLike$5;
2937
+ var toIntegerOrInfinity = toIntegerOrInfinity$3;
2938
+ var arraySpeciesCreate = arraySpeciesCreate$1;
2939
+
2940
+ // `Array.prototype.flat` method
2941
+ // https://tc39.es/ecma262/#sec-array.prototype.flat
2942
+ $$3({ target: 'Array', proto: true }, {
2943
+ flat: function flat(/* depthArg = 1 */) {
2944
+ var depthArg = arguments.length ? arguments[0] : undefined;
2945
+ var O = toObject$2(this);
2946
+ var sourceLen = lengthOfArrayLike$1(O);
2947
+ var A = arraySpeciesCreate(O, 0);
2948
+ A.length = flattenIntoArray(A, O, O, sourceLen, 0, depthArg === undefined ? 1 : toIntegerOrInfinity(depthArg));
2949
+ return A;
2950
+ }
2951
+ });
2952
+
2953
+ // this method was added to unscopables after implementation
2954
+ // in popular engines, so it's moved to a separate module
2955
+ var addToUnscopables$1 = addToUnscopables$3;
2956
+
2957
+ // https://tc39.es/ecma262/#sec-array.prototype-@@unscopables
2958
+ addToUnscopables$1('flat');
2959
+
2846
2960
  var fails$3 = fails$h;
2847
2961
 
2848
2962
  var correctPrototypeGetter = !fails$3(function () {
@@ -2854,7 +2968,7 @@ var correctPrototypeGetter = !fails$3(function () {
2854
2968
 
2855
2969
  var hasOwn = hasOwnProperty_1;
2856
2970
  var isCallable$2 = isCallable$k;
2857
- var toObject$2 = toObject$5;
2971
+ var toObject$1 = toObject$5;
2858
2972
  var sharedKey = sharedKey$3;
2859
2973
  var CORRECT_PROTOTYPE_GETTER = correctPrototypeGetter;
2860
2974
 
@@ -2866,7 +2980,7 @@ var ObjectPrototype = $Object.prototype;
2866
2980
  // https://tc39.es/ecma262/#sec-object.getprototypeof
2867
2981
  // eslint-disable-next-line es/no-object-getprototypeof -- safe
2868
2982
  var objectGetPrototypeOf = CORRECT_PROTOTYPE_GETTER ? $Object.getPrototypeOf : function (O) {
2869
- var object = toObject$2(O);
2983
+ var object = toObject$1(O);
2870
2984
  if (hasOwn(object, IE_PROTO)) return object[IE_PROTO];
2871
2985
  var constructor = object.constructor;
2872
2986
  if (isCallable$2(constructor) && object instanceof constructor) {
@@ -2876,12 +2990,12 @@ var objectGetPrototypeOf = CORRECT_PROTOTYPE_GETTER ? $Object.getPrototypeOf : f
2876
2990
 
2877
2991
  var fails$2 = fails$h;
2878
2992
  var isCallable$1 = isCallable$k;
2879
- var isObject$1 = isObject$a;
2993
+ var isObject = isObject$a;
2880
2994
  var getPrototypeOf$1 = objectGetPrototypeOf;
2881
2995
  var defineBuiltIn$1 = defineBuiltIn$6;
2882
- var wellKnownSymbol$3 = wellKnownSymbol$h;
2996
+ var wellKnownSymbol$2 = wellKnownSymbol$h;
2883
2997
 
2884
- var ITERATOR$3 = wellKnownSymbol$3('iterator');
2998
+ var ITERATOR$3 = wellKnownSymbol$2('iterator');
2885
2999
  var BUGGY_SAFARI_ITERATORS$1 = false;
2886
3000
 
2887
3001
  // `%IteratorPrototype%` object
@@ -2899,7 +3013,7 @@ if ([].keys) {
2899
3013
  }
2900
3014
  }
2901
3015
 
2902
- var NEW_ITERATOR_PROTOTYPE = !isObject$1(IteratorPrototype$2) || fails$2(function () {
3016
+ var NEW_ITERATOR_PROTOTYPE = !isObject(IteratorPrototype$2) || fails$2(function () {
2903
3017
  var test = {};
2904
3018
  // FF44- legacy iterators case
2905
3019
  return IteratorPrototype$2[ITERATOR$3].call(test) !== test;
@@ -2936,7 +3050,7 @@ var iteratorCreateConstructor = function (IteratorConstructor, NAME, next, ENUME
2936
3050
  return IteratorConstructor;
2937
3051
  };
2938
3052
 
2939
- var $$3 = _export;
3053
+ var $$2 = _export;
2940
3054
  var call = functionCall;
2941
3055
  var FunctionName = functionName;
2942
3056
  var isCallable = isCallable$k;
@@ -2946,7 +3060,7 @@ var setPrototypeOf = objectSetPrototypeOf;
2946
3060
  var setToStringTag = setToStringTag$3;
2947
3061
  var createNonEnumerableProperty$1 = createNonEnumerableProperty$4;
2948
3062
  var defineBuiltIn = defineBuiltIn$6;
2949
- var wellKnownSymbol$2 = wellKnownSymbol$h;
3063
+ var wellKnownSymbol$1 = wellKnownSymbol$h;
2950
3064
  var Iterators$1 = iterators;
2951
3065
  var IteratorsCore = iteratorsCore;
2952
3066
 
@@ -2954,7 +3068,7 @@ var PROPER_FUNCTION_NAME = FunctionName.PROPER;
2954
3068
  var CONFIGURABLE_FUNCTION_NAME = FunctionName.CONFIGURABLE;
2955
3069
  var IteratorPrototype = IteratorsCore.IteratorPrototype;
2956
3070
  var BUGGY_SAFARI_ITERATORS = IteratorsCore.BUGGY_SAFARI_ITERATORS;
2957
- var ITERATOR$2 = wellKnownSymbol$2('iterator');
3071
+ var ITERATOR$2 = wellKnownSymbol$1('iterator');
2958
3072
  var KEYS = 'keys';
2959
3073
  var VALUES = 'values';
2960
3074
  var ENTRIES = 'entries';
@@ -3021,7 +3135,7 @@ var iteratorDefine = function (Iterable, NAME, IteratorConstructor, next, DEFAUL
3021
3135
  if (BUGGY_SAFARI_ITERATORS || INCORRECT_VALUES_NAME || !(KEY in IterablePrototype)) {
3022
3136
  defineBuiltIn(IterablePrototype, KEY, methods[KEY]);
3023
3137
  }
3024
- } else $$3({ target: NAME, proto: true, forced: BUGGY_SAFARI_ITERATORS || INCORRECT_VALUES_NAME }, methods);
3138
+ } else $$2({ target: NAME, proto: true, forced: BUGGY_SAFARI_ITERATORS || INCORRECT_VALUES_NAME }, methods);
3025
3139
  }
3026
3140
 
3027
3141
  // define iterator
@@ -3040,7 +3154,7 @@ var createIterResultObject$1 = function (value, done) {
3040
3154
  };
3041
3155
 
3042
3156
  var toIndexedObject = toIndexedObject$5;
3043
- var addToUnscopables$1 = addToUnscopables$3;
3157
+ var addToUnscopables = addToUnscopables$3;
3044
3158
  var Iterators = iterators;
3045
3159
  var InternalStateModule = internalState;
3046
3160
  var defineProperty = objectDefineProperty.f;
@@ -3091,9 +3205,9 @@ var es_array_iterator = defineIterator(Array, 'Array', function (iterated, kind)
3091
3205
  var values = Iterators.Arguments = Iterators.Array;
3092
3206
 
3093
3207
  // https://tc39.es/ecma262/#sec-array.prototype-@@unscopables
3094
- addToUnscopables$1('keys');
3095
- addToUnscopables$1('values');
3096
- addToUnscopables$1('entries');
3208
+ addToUnscopables('keys');
3209
+ addToUnscopables('values');
3210
+ addToUnscopables('entries');
3097
3211
 
3098
3212
  // V8 ~ Chrome 45- bug
3099
3213
  if (DESCRIPTORS && values.name !== 'values') try {
@@ -3149,10 +3263,10 @@ var DOMIterables = domIterables;
3149
3263
  var DOMTokenListPrototype = domTokenListPrototype;
3150
3264
  var ArrayIteratorMethods = es_array_iterator;
3151
3265
  var createNonEnumerableProperty = createNonEnumerableProperty$4;
3152
- var wellKnownSymbol$1 = wellKnownSymbol$h;
3266
+ var wellKnownSymbol = wellKnownSymbol$h;
3153
3267
 
3154
- var ITERATOR$1 = wellKnownSymbol$1('iterator');
3155
- var TO_STRING_TAG = wellKnownSymbol$1('toStringTag');
3268
+ var ITERATOR$1 = wellKnownSymbol('iterator');
3269
+ var TO_STRING_TAG = wellKnownSymbol('toStringTag');
3156
3270
  var ArrayValues = ArrayIteratorMethods.values;
3157
3271
 
3158
3272
  var handlePrototype = function (CollectionPrototype, COLLECTION_NAME) {
@@ -3183,123 +3297,64 @@ for (var COLLECTION_NAME in DOMIterables) {
3183
3297
 
3184
3298
  handlePrototype(DOMTokenListPrototype, 'DOMTokenList');
3185
3299
 
3186
- var classof = classofRaw$2;
3187
-
3188
- // `IsArray` abstract operation
3189
- // https://tc39.es/ecma262/#sec-isarray
3190
- // eslint-disable-next-line es/no-array-isarray -- safe
3191
- var isArray$2 = Array.isArray || function isArray(argument) {
3192
- return classof(argument) == 'Array';
3193
- };
3194
-
3195
- var $TypeError$1 = TypeError;
3196
- var MAX_SAFE_INTEGER = 0x1FFFFFFFFFFFFF; // 2 ** 53 - 1 == 9007199254740991
3197
-
3198
- var doesNotExceedSafeInteger$1 = function (it) {
3199
- if (it > MAX_SAFE_INTEGER) throw $TypeError$1('Maximum allowed index exceeded');
3200
- return it;
3201
- };
3202
-
3203
- var isArray$1 = isArray$2;
3204
- var lengthOfArrayLike$2 = lengthOfArrayLike$5;
3205
- var doesNotExceedSafeInteger = doesNotExceedSafeInteger$1;
3206
- var bind = functionBindContext;
3207
-
3208
- // `FlattenIntoArray` abstract operation
3209
- // https://tc39.github.io/proposal-flatMap/#sec-FlattenIntoArray
3210
- var flattenIntoArray$1 = function (target, original, source, sourceLen, start, depth, mapper, thisArg) {
3211
- var targetIndex = start;
3212
- var sourceIndex = 0;
3213
- var mapFn = mapper ? bind(mapper, thisArg) : false;
3214
- var element, elementLen;
3215
-
3216
- while (sourceIndex < sourceLen) {
3217
- if (sourceIndex in source) {
3218
- element = mapFn ? mapFn(source[sourceIndex], sourceIndex, original) : source[sourceIndex];
3219
-
3220
- if (depth > 0 && isArray$1(element)) {
3221
- elementLen = lengthOfArrayLike$2(element);
3222
- targetIndex = flattenIntoArray$1(target, original, element, elementLen, targetIndex, depth - 1) - 1;
3300
+ class ElementSeenObserver {
3301
+ constructor(_options) {
3302
+ this._options = _options;
3303
+ this._elementDelays = new WeakMap();
3304
+ this._intersectionTimers = new WeakMap();
3305
+ if (typeof IntersectionObserver !== 'undefined') {
3306
+ this._intersectionObserver = new IntersectionObserver(this.onIntersection.bind(this));
3307
+ }
3308
+ }
3309
+ onIntersection(entries) {
3310
+ entries.forEach(entry => {
3311
+ const {
3312
+ isIntersecting,
3313
+ target
3314
+ } = entry;
3315
+ if (isIntersecting) {
3316
+ const delay = this._elementDelays.get(target);
3317
+ const timeOut = window.setTimeout(() => {
3318
+ this._options.onElementSeen(target);
3319
+ }, delay);
3320
+ this._intersectionTimers.set(target, timeOut);
3223
3321
  } else {
3224
- doesNotExceedSafeInteger(targetIndex + 1);
3225
- target[targetIndex] = element;
3322
+ const timeOut = this._intersectionTimers.get(target);
3323
+ if (typeof timeOut !== 'undefined') {
3324
+ window.clearTimeout(timeOut);
3325
+ }
3226
3326
  }
3227
-
3228
- targetIndex++;
3229
- }
3230
- sourceIndex++;
3327
+ });
3231
3328
  }
3232
- return targetIndex;
3233
- };
3234
-
3235
- var flattenIntoArray_1 = flattenIntoArray$1;
3236
-
3237
- var isArray = isArray$2;
3238
- var isConstructor = isConstructor$2;
3239
- var isObject = isObject$a;
3240
- var wellKnownSymbol = wellKnownSymbol$h;
3241
-
3242
- var SPECIES = wellKnownSymbol('species');
3243
- var $Array = Array;
3329
+ observe(element, options) {
3330
+ var _a, _b;
3331
+ this._elementDelays.set(element, (_a = options === null || options === void 0 ? void 0 : options.delay) !== null && _a !== void 0 ? _a : 2000);
3332
+ (_b = this._intersectionObserver) === null || _b === void 0 ? void 0 : _b.observe(element);
3333
+ }
3334
+ unobserve(element) {
3335
+ var _a;
3336
+ (_a = this._intersectionObserver) === null || _a === void 0 ? void 0 : _a.unobserve(element);
3337
+ }
3338
+ }
3244
3339
 
3245
- // a part of `ArraySpeciesCreate` abstract operation
3246
- // https://tc39.es/ecma262/#sec-arrayspeciescreate
3247
- var arraySpeciesConstructor$1 = function (originalArray) {
3248
- var C;
3249
- if (isArray(originalArray)) {
3250
- C = originalArray.constructor;
3251
- // cross-realm fallback
3252
- if (isConstructor(C) && (C === $Array || isArray(C.prototype))) C = undefined;
3253
- else if (isObject(C)) {
3254
- C = C[SPECIES];
3255
- if (C === null) C = undefined;
3256
- }
3257
- } return C === undefined ? $Array : C;
3340
+ const acceptsCredentials = plugin => {
3341
+ return typeof plugin === 'object' && plugin !== null && 'setCredentials' in plugin && typeof plugin.setCredentials === 'function';
3258
3342
  };
3259
3343
 
3260
- var arraySpeciesConstructor = arraySpeciesConstructor$1;
3261
-
3262
- // `ArraySpeciesCreate` abstract operation
3263
- // https://tc39.es/ecma262/#sec-arrayspeciescreate
3264
- var arraySpeciesCreate$1 = function (originalArray, length) {
3265
- return new (arraySpeciesConstructor(originalArray))(length === 0 ? 0 : length);
3344
+ const isInterestedInHiddenPage = arg => {
3345
+ return typeof arg === 'object' && arg !== null && PAGE_HIDDEN in arg && typeof arg[PAGE_HIDDEN] === 'function';
3266
3346
  };
3267
3347
 
3268
- var $$2 = _export;
3269
- var flattenIntoArray = flattenIntoArray_1;
3270
- var toObject$1 = toObject$5;
3271
- var lengthOfArrayLike$1 = lengthOfArrayLike$5;
3272
- var toIntegerOrInfinity = toIntegerOrInfinity$3;
3273
- var arraySpeciesCreate = arraySpeciesCreate$1;
3274
-
3275
- // `Array.prototype.flat` method
3276
- // https://tc39.es/ecma262/#sec-array.prototype.flat
3277
- $$2({ target: 'Array', proto: true }, {
3278
- flat: function flat(/* depthArg = 1 */) {
3279
- var depthArg = arguments.length ? arguments[0] : undefined;
3280
- var O = toObject$1(this);
3281
- var sourceLen = lengthOfArrayLike$1(O);
3282
- var A = arraySpeciesCreate(O, 0);
3283
- A.length = flattenIntoArray(A, O, O, sourceLen, 0, depthArg === undefined ? 1 : toIntegerOrInfinity(depthArg));
3284
- return A;
3285
- }
3286
- });
3287
-
3288
- // this method was added to unscopables after implementation
3289
- // in popular engines, so it's moved to a separate module
3290
- var addToUnscopables = addToUnscopables$3;
3291
-
3292
- // https://tc39.es/ecma262/#sec-array.prototype-@@unscopables
3293
- addToUnscopables('flat');
3294
-
3295
3348
  class Ninetailed {
3296
3349
  constructor(ninetailedApiClientInstanceOrOptions, {
3297
3350
  plugins,
3298
3351
  url,
3352
+ profile,
3299
3353
  locale,
3300
3354
  requestTimeout,
3301
3355
  onLog,
3302
- onError
3356
+ onError,
3357
+ componentViewTrackingThreshold = 2000
3303
3358
  } = {}) {
3304
3359
  this.isInitialized = false;
3305
3360
  this.page = (data, options) => __awaiter(this, void 0, void 0, function* () {
@@ -3336,16 +3391,48 @@ class Ninetailed {
3336
3391
  throw error;
3337
3392
  }
3338
3393
  });
3394
+ /**
3395
+ * @deprecated The legacy datamodel is not recommended anymore
3396
+ * Will be removed in version 5 of the SDK
3397
+ */
3339
3398
  this.trackHasSeenComponent = properties => __awaiter(this, void 0, void 0, function* () {
3340
3399
  return this.instance.dispatch(Object.assign(Object.assign({}, properties), {
3341
3400
  type: HAS_SEEN_COMPONENT
3342
3401
  }));
3343
3402
  });
3403
+ /**
3404
+ * @deprecated Use the Ninetailed provided observers instead
3405
+ * Will be removed in version 5 of the SDK
3406
+ */
3344
3407
  this.trackHasSeenExperience = properties => {
3345
3408
  return this.instance.dispatch(Object.assign(Object.assign({}, properties), {
3346
- type: HAS_SEEN_EXPERIENCE
3409
+ type: HAS_SEEN_ELEMENT
3347
3410
  }));
3348
3411
  };
3412
+ this.observeElement = (payload, options) => {
3413
+ const {
3414
+ element
3415
+ } = payload,
3416
+ remaingPayload = __rest(payload, ["element"]);
3417
+ this.observedElements.set(element, remaingPayload);
3418
+ this.elementSeenObserver.observe(element, Object.assign({
3419
+ delay: this.componentViewTrackingThreshold
3420
+ }, options));
3421
+ };
3422
+ this.unobserveElement = element => {
3423
+ this.observedElements.delete(element);
3424
+ this.elementSeenObserver.unobserve(element);
3425
+ };
3426
+ this.onElementSeen = element => {
3427
+ const payload = this.observedElements.get(element);
3428
+ if (typeof payload !== 'undefined') {
3429
+ this.instance.dispatch(Object.assign(Object.assign({
3430
+ element
3431
+ }, payload), {
3432
+ type: HAS_SEEN_ELEMENT
3433
+ }));
3434
+ }
3435
+ };
3349
3436
  this.identify = (uid, traits, options) => __awaiter(this, void 0, void 0, function* () {
3350
3437
  try {
3351
3438
  const result = Traits.default({}).safeParse(traits);
@@ -3384,14 +3471,12 @@ class Ninetailed {
3384
3471
  cb(Object.assign(Object.assign({}, this._profileState), {
3385
3472
  status: 'error',
3386
3473
  profile: payload.profile,
3387
- experiences: payload.experiences,
3388
3474
  error: payload.error
3389
3475
  }));
3390
3476
  } else {
3391
3477
  cb(Object.assign(Object.assign({}, this._profileState), {
3392
3478
  status: 'success',
3393
3479
  profile: payload.profile,
3394
- experiences: payload.experiences,
3395
3480
  error: null
3396
3481
  }));
3397
3482
  }
@@ -3415,6 +3500,18 @@ class Ninetailed {
3415
3500
  this.onIsInitialized(resolve);
3416
3501
  });
3417
3502
  };
3503
+ this.onVisibilityChange = () => {
3504
+ if (typeof document === 'undefined') {
3505
+ return;
3506
+ }
3507
+ document.addEventListener('visibilitychange', () => {
3508
+ if (document.visibilityState === 'hidden') {
3509
+ this.instance.dispatch({
3510
+ type: PAGE_HIDDEN
3511
+ });
3512
+ }
3513
+ });
3514
+ };
3418
3515
  if (ninetailedApiClientInstanceOrOptions instanceof NinetailedApiClient) {
3419
3516
  this.apiClient = ninetailedApiClientInstanceOrOptions;
3420
3517
  } else {
@@ -3432,22 +3529,30 @@ class Ninetailed {
3432
3529
  preview
3433
3530
  });
3434
3531
  }
3435
- this.plugins = [...(plugins || []).map(plugin => {
3436
- if ('setCredentials' in plugin && typeof plugin['setCredentials'] === 'function') {
3437
- plugin['setCredentials']({
3532
+ this.plugins = (plugins !== null && plugins !== void 0 ? plugins : []).flat();
3533
+ this.plugins.forEach(plugin => {
3534
+ if (acceptsCredentials(plugin) && this.clientId && this.environment) {
3535
+ plugin.setCredentials({
3438
3536
  clientId: this.clientId,
3439
3537
  environment: this.environment
3440
3538
  });
3441
3539
  }
3442
- return plugin;
3443
- }).flat()];
3444
- this._profileState = {
3445
- status: 'loading',
3446
- profile: null,
3447
- experiences: null,
3448
- error: null,
3449
- from: 'api'
3450
- };
3540
+ });
3541
+ if (profile) {
3542
+ this._profileState = {
3543
+ status: 'success',
3544
+ profile,
3545
+ error: null,
3546
+ from: 'hydrated'
3547
+ };
3548
+ } else {
3549
+ this._profileState = {
3550
+ status: 'loading',
3551
+ profile: null,
3552
+ error: null,
3553
+ from: 'api'
3554
+ };
3555
+ }
3451
3556
  if (typeof onLog === 'function') {
3452
3557
  logger.addSink(new OnLogLogSink(onLog));
3453
3558
  }
@@ -3457,6 +3562,7 @@ class Ninetailed {
3457
3562
  this.logger = logger;
3458
3563
  this.eventQueue = ninetailedPlugin({
3459
3564
  apiClient: this.apiClient,
3565
+ profile,
3460
3566
  locale,
3461
3567
  requestTimeout,
3462
3568
  ninetailed: this
@@ -3475,11 +3581,19 @@ class Ninetailed {
3475
3581
  this._profileState = profileState;
3476
3582
  if (typeof window !== 'undefined') {
3477
3583
  window.ninetailed = Object.assign({}, window.ninetailed, {
3478
- profile: this.profileState.profile,
3479
- experiences: this.profileState.experiences
3584
+ profile: this.profileState.profile
3480
3585
  });
3481
3586
  }
3482
3587
  });
3588
+ this.observedElements = new WeakMap();
3589
+ this.elementSeenObserver = new ElementSeenObserver({
3590
+ onElementSeen: this.onElementSeen.bind(this)
3591
+ });
3592
+ this.componentViewTrackingThreshold = componentViewTrackingThreshold;
3593
+ const hasPluginsInterestedInHiddenPage = this.plugins.some(isInterestedInHiddenPage);
3594
+ if (hasPluginsInterestedInHiddenPage) {
3595
+ this.onVisibilityChange();
3596
+ }
3483
3597
  this.registerWindowHandlers();
3484
3598
  }
3485
3599
  get profileState() {
@@ -3592,39 +3706,44 @@ const selectVariant = (baseline, variants, {
3592
3706
  };
3593
3707
  };
3594
3708
 
3595
- const TrackExperienceProperties = z.object({
3709
+ const TrackComponentProperties = z.object({
3710
+ variant: z.object({
3711
+ id: z.string()
3712
+ }),
3713
+ audience: z.object({
3714
+ id: z.string()
3715
+ }),
3716
+ isPersonalized: z.boolean()
3717
+ });
3718
+
3719
+ /**
3720
+ * @deprecated Use `NinetailedPlugin` from the sdks/javascript package instead.
3721
+ */
3722
+ class NinetailedPlugin {}
3723
+
3724
+ const ElementSeenPayloadSchema = z.object({
3725
+ element: z.any(),
3596
3726
  experience: z.object({
3597
3727
  id: z.string(),
3598
3728
  type: z.union([z.literal('nt_experiment'), z.literal('nt_personalization')]),
3599
- name: z.string(),
3729
+ name: z.string().optional(),
3600
3730
  description: z.string().optional()
3601
- }),
3731
+ }).optional().nullable(),
3602
3732
  audience: z.object({
3603
3733
  id: z.string(),
3604
3734
  name: z.string().optional(),
3605
3735
  description: z.string().optional()
3606
- }).optional().default({
3736
+ }).optional().nullable().default({
3607
3737
  id: 'ALL_VISITORS',
3608
3738
  name: 'All Visitors',
3609
3739
  description: 'This is the default all visitors audience as no audience was set.'
3610
3740
  }),
3611
- selectedVariant: z.object({
3612
- id: z.string()
3613
- }).catchall(z.unknown()),
3614
- selectedVariantIndex: z.number()
3615
- });
3616
- const TrackComponentProperties = z.object({
3617
3741
  variant: z.object({
3618
3742
  id: z.string()
3619
- }),
3620
- audience: z.object({
3621
- id: z.string()
3622
- }),
3623
- isPersonalized: z.boolean()
3743
+ }).catchall(z.unknown()),
3744
+ variantIndex: z.number()
3624
3745
  });
3625
3746
 
3626
- class NinetailedPlugin {}
3627
-
3628
3747
  var aCallable = aCallable$8;
3629
3748
  var toObject = toObject$5;
3630
3749
  var IndexedObject = indexedObject;
@@ -3831,11 +3950,13 @@ const selectPluginsHavingExperienceSelectionMiddleware = plugins => {
3831
3950
  const createPassThroughMiddleware = () => {
3832
3951
  return ({
3833
3952
  experience,
3834
- variant
3953
+ variant,
3954
+ variantIndex
3835
3955
  }) => {
3836
3956
  return {
3837
3957
  experience,
3838
- variant
3958
+ variant,
3959
+ variantIndex
3839
3960
  };
3840
3961
  };
3841
3962
  };
@@ -3878,4 +3999,4 @@ const makeExperienceSelectMiddleware = ({
3878
3999
  };
3879
4000
  };
3880
4001
 
3881
- export { ANONYMOUS_ID, CONSENT, DEBUG_FLAG, EMPTY_MERGE_ID, EXPERIENCES_FALLBACK_CACHE, HAS_SEEN_COMPONENT, HAS_SEEN_EXPERIENCE, LEGACY_ANONYMOUS_ID, Ninetailed, NinetailedPlugin, OnChangeEmitter, PLUGIN_NAME, PROFILE_CHANGE, PROFILE_FALLBACK_CACHE, PROFILE_RESET, SET_ENABLED_FEATURES, TrackComponentProperties, TrackExperienceProperties, decodeExperienceVariantsMap, makeExperienceSelectMiddleware, ninetailedPlugin, selectPluginsHavingExperienceSelectionMiddleware, selectPluginsHavingOnChangeEmitter, selectVariant };
4002
+ export { ANONYMOUS_ID, CONSENT, DEBUG_FLAG, EMPTY_MERGE_ID, ElementSeenPayloadSchema, HAS_SEEN_COMPONENT, HAS_SEEN_ELEMENT, LEGACY_ANONYMOUS_ID, Ninetailed, NinetailedPlugin, OnChangeEmitter, PAGE_HIDDEN, PLUGIN_NAME, PROFILE_CHANGE, PROFILE_FALLBACK_CACHE, PROFILE_RESET, SET_ENABLED_FEATURES, TrackComponentProperties, buildClientNinetailedRequestContext, decodeExperienceVariantsMap, makeExperienceSelectMiddleware, ninetailedPlugin, selectPluginsHavingExperienceSelectionMiddleware, selectPluginsHavingOnChangeEmitter, selectVariant };