@ninetailed/experience.js 4.2.3-beta.0 → 4.3.0-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
@@ -5,6 +5,8 @@ import { z } from 'zod';
5
5
 
6
6
  const HAS_SEEN_EXPERIENCE = 'has_seen_experience';
7
7
  const HAS_SEEN_COMPONENT = 'has_seen_component';
8
+ const HAS_SEEN_ELEMENT = 'has_seen_element';
9
+ const PAGE_HIDDEN = 'page_hidden';
8
10
 
9
11
  var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
10
12
 
@@ -602,9 +604,9 @@ var inspectSource$3 = store$1.inspectSource;
602
604
  var global$d = global$k;
603
605
  var isCallable$d = isCallable$k;
604
606
 
605
- var WeakMap$1 = global$d.WeakMap;
607
+ var WeakMap$2 = global$d.WeakMap;
606
608
 
607
- var weakMapBasicDetection = isCallable$d(WeakMap$1) && /native code/.test(String(WeakMap$1));
609
+ var weakMapBasicDetection = isCallable$d(WeakMap$2) && /native code/.test(String(WeakMap$2));
608
610
 
609
611
  var shared$1 = shared$3.exports;
610
612
  var uid = uid$2;
@@ -628,7 +630,7 @@ var hiddenKeys$3 = hiddenKeys$4;
628
630
 
629
631
  var OBJECT_ALREADY_INITIALIZED = 'Object already initialized';
630
632
  var TypeError$2 = global$c.TypeError;
631
- var WeakMap = global$c.WeakMap;
633
+ var WeakMap$1 = global$c.WeakMap;
632
634
  var set$1, get, has;
633
635
 
634
636
  var enforce = function (it) {
@@ -645,7 +647,7 @@ var getterFor = function (TYPE) {
645
647
  };
646
648
 
647
649
  if (NATIVE_WEAK_MAP || shared.state) {
648
- var store = shared.state || (shared.state = new WeakMap());
650
+ var store = shared.state || (shared.state = new WeakMap$1());
649
651
  /* eslint-disable no-self-assign -- prototype methods protection */
650
652
  store.get = store.get;
651
653
  store.has = store.has;
@@ -2517,6 +2519,18 @@ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
2517
2519
  PERFORMANCE OF THIS SOFTWARE.
2518
2520
  ***************************************************************************** */
2519
2521
 
2522
+ function __rest(s, e) {
2523
+ var t = {};
2524
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
2525
+ t[p] = s[p];
2526
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
2527
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
2528
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
2529
+ t[p[i]] = s[p[i]];
2530
+ }
2531
+ return t;
2532
+ }
2533
+
2520
2534
  function __awaiter(thisArg, _arguments, P, generator) {
2521
2535
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
2522
2536
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -2835,6 +2849,115 @@ if (NOT_GENERIC || INCORRECT_NAME) {
2835
2849
  }, { unsafe: true });
2836
2850
  }
2837
2851
 
2852
+ var classof = classofRaw$2;
2853
+
2854
+ // `IsArray` abstract operation
2855
+ // https://tc39.es/ecma262/#sec-isarray
2856
+ // eslint-disable-next-line es/no-array-isarray -- safe
2857
+ var isArray$2 = Array.isArray || function isArray(argument) {
2858
+ return classof(argument) == 'Array';
2859
+ };
2860
+
2861
+ var $TypeError$1 = TypeError;
2862
+ var MAX_SAFE_INTEGER = 0x1FFFFFFFFFFFFF; // 2 ** 53 - 1 == 9007199254740991
2863
+
2864
+ var doesNotExceedSafeInteger$1 = function (it) {
2865
+ if (it > MAX_SAFE_INTEGER) throw $TypeError$1('Maximum allowed index exceeded');
2866
+ return it;
2867
+ };
2868
+
2869
+ var isArray$1 = isArray$2;
2870
+ var lengthOfArrayLike$2 = lengthOfArrayLike$5;
2871
+ var doesNotExceedSafeInteger = doesNotExceedSafeInteger$1;
2872
+ var bind = functionBindContext;
2873
+
2874
+ // `FlattenIntoArray` abstract operation
2875
+ // https://tc39.github.io/proposal-flatMap/#sec-FlattenIntoArray
2876
+ var flattenIntoArray$1 = function (target, original, source, sourceLen, start, depth, mapper, thisArg) {
2877
+ var targetIndex = start;
2878
+ var sourceIndex = 0;
2879
+ var mapFn = mapper ? bind(mapper, thisArg) : false;
2880
+ var element, elementLen;
2881
+
2882
+ while (sourceIndex < sourceLen) {
2883
+ if (sourceIndex in source) {
2884
+ element = mapFn ? mapFn(source[sourceIndex], sourceIndex, original) : source[sourceIndex];
2885
+
2886
+ if (depth > 0 && isArray$1(element)) {
2887
+ elementLen = lengthOfArrayLike$2(element);
2888
+ targetIndex = flattenIntoArray$1(target, original, element, elementLen, targetIndex, depth - 1) - 1;
2889
+ } else {
2890
+ doesNotExceedSafeInteger(targetIndex + 1);
2891
+ target[targetIndex] = element;
2892
+ }
2893
+
2894
+ targetIndex++;
2895
+ }
2896
+ sourceIndex++;
2897
+ }
2898
+ return targetIndex;
2899
+ };
2900
+
2901
+ var flattenIntoArray_1 = flattenIntoArray$1;
2902
+
2903
+ var isArray = isArray$2;
2904
+ var isConstructor = isConstructor$2;
2905
+ var isObject$1 = isObject$a;
2906
+ var wellKnownSymbol$3 = wellKnownSymbol$h;
2907
+
2908
+ var SPECIES = wellKnownSymbol$3('species');
2909
+ var $Array = Array;
2910
+
2911
+ // a part of `ArraySpeciesCreate` abstract operation
2912
+ // https://tc39.es/ecma262/#sec-arrayspeciescreate
2913
+ var arraySpeciesConstructor$1 = function (originalArray) {
2914
+ var C;
2915
+ if (isArray(originalArray)) {
2916
+ C = originalArray.constructor;
2917
+ // cross-realm fallback
2918
+ if (isConstructor(C) && (C === $Array || isArray(C.prototype))) C = undefined;
2919
+ else if (isObject$1(C)) {
2920
+ C = C[SPECIES];
2921
+ if (C === null) C = undefined;
2922
+ }
2923
+ } return C === undefined ? $Array : C;
2924
+ };
2925
+
2926
+ var arraySpeciesConstructor = arraySpeciesConstructor$1;
2927
+
2928
+ // `ArraySpeciesCreate` abstract operation
2929
+ // https://tc39.es/ecma262/#sec-arrayspeciescreate
2930
+ var arraySpeciesCreate$1 = function (originalArray, length) {
2931
+ return new (arraySpeciesConstructor(originalArray))(length === 0 ? 0 : length);
2932
+ };
2933
+
2934
+ var $$3 = _export;
2935
+ var flattenIntoArray = flattenIntoArray_1;
2936
+ var toObject$2 = toObject$5;
2937
+ var lengthOfArrayLike$1 = lengthOfArrayLike$5;
2938
+ var toIntegerOrInfinity = toIntegerOrInfinity$3;
2939
+ var arraySpeciesCreate = arraySpeciesCreate$1;
2940
+
2941
+ // `Array.prototype.flat` method
2942
+ // https://tc39.es/ecma262/#sec-array.prototype.flat
2943
+ $$3({ target: 'Array', proto: true }, {
2944
+ flat: function flat(/* depthArg = 1 */) {
2945
+ var depthArg = arguments.length ? arguments[0] : undefined;
2946
+ var O = toObject$2(this);
2947
+ var sourceLen = lengthOfArrayLike$1(O);
2948
+ var A = arraySpeciesCreate(O, 0);
2949
+ A.length = flattenIntoArray(A, O, O, sourceLen, 0, depthArg === undefined ? 1 : toIntegerOrInfinity(depthArg));
2950
+ return A;
2951
+ }
2952
+ });
2953
+
2954
+ // this method was added to unscopables after implementation
2955
+ // in popular engines, so it's moved to a separate module
2956
+ var addToUnscopables$1 = addToUnscopables$3;
2957
+
2958
+ // https://tc39.es/ecma262/#sec-array.prototype-@@unscopables
2959
+ addToUnscopables$1('flat');
2960
+
2838
2961
  var fails$3 = fails$h;
2839
2962
 
2840
2963
  var correctPrototypeGetter = !fails$3(function () {
@@ -2846,7 +2969,7 @@ var correctPrototypeGetter = !fails$3(function () {
2846
2969
 
2847
2970
  var hasOwn = hasOwnProperty_1;
2848
2971
  var isCallable$2 = isCallable$k;
2849
- var toObject$2 = toObject$5;
2972
+ var toObject$1 = toObject$5;
2850
2973
  var sharedKey = sharedKey$3;
2851
2974
  var CORRECT_PROTOTYPE_GETTER = correctPrototypeGetter;
2852
2975
 
@@ -2858,7 +2981,7 @@ var ObjectPrototype = $Object.prototype;
2858
2981
  // https://tc39.es/ecma262/#sec-object.getprototypeof
2859
2982
  // eslint-disable-next-line es/no-object-getprototypeof -- safe
2860
2983
  var objectGetPrototypeOf = CORRECT_PROTOTYPE_GETTER ? $Object.getPrototypeOf : function (O) {
2861
- var object = toObject$2(O);
2984
+ var object = toObject$1(O);
2862
2985
  if (hasOwn(object, IE_PROTO)) return object[IE_PROTO];
2863
2986
  var constructor = object.constructor;
2864
2987
  if (isCallable$2(constructor) && object instanceof constructor) {
@@ -2868,12 +2991,12 @@ var objectGetPrototypeOf = CORRECT_PROTOTYPE_GETTER ? $Object.getPrototypeOf : f
2868
2991
 
2869
2992
  var fails$2 = fails$h;
2870
2993
  var isCallable$1 = isCallable$k;
2871
- var isObject$1 = isObject$a;
2994
+ var isObject = isObject$a;
2872
2995
  var getPrototypeOf$1 = objectGetPrototypeOf;
2873
2996
  var defineBuiltIn$1 = defineBuiltIn$6;
2874
- var wellKnownSymbol$3 = wellKnownSymbol$h;
2997
+ var wellKnownSymbol$2 = wellKnownSymbol$h;
2875
2998
 
2876
- var ITERATOR$3 = wellKnownSymbol$3('iterator');
2999
+ var ITERATOR$3 = wellKnownSymbol$2('iterator');
2877
3000
  var BUGGY_SAFARI_ITERATORS$1 = false;
2878
3001
 
2879
3002
  // `%IteratorPrototype%` object
@@ -2891,7 +3014,7 @@ if ([].keys) {
2891
3014
  }
2892
3015
  }
2893
3016
 
2894
- var NEW_ITERATOR_PROTOTYPE = !isObject$1(IteratorPrototype$2) || fails$2(function () {
3017
+ var NEW_ITERATOR_PROTOTYPE = !isObject(IteratorPrototype$2) || fails$2(function () {
2895
3018
  var test = {};
2896
3019
  // FF44- legacy iterators case
2897
3020
  return IteratorPrototype$2[ITERATOR$3].call(test) !== test;
@@ -2928,7 +3051,7 @@ var iteratorCreateConstructor = function (IteratorConstructor, NAME, next, ENUME
2928
3051
  return IteratorConstructor;
2929
3052
  };
2930
3053
 
2931
- var $$3 = _export;
3054
+ var $$2 = _export;
2932
3055
  var call = functionCall;
2933
3056
  var FunctionName = functionName;
2934
3057
  var isCallable = isCallable$k;
@@ -2938,7 +3061,7 @@ var setPrototypeOf = objectSetPrototypeOf;
2938
3061
  var setToStringTag = setToStringTag$3;
2939
3062
  var createNonEnumerableProperty$1 = createNonEnumerableProperty$4;
2940
3063
  var defineBuiltIn = defineBuiltIn$6;
2941
- var wellKnownSymbol$2 = wellKnownSymbol$h;
3064
+ var wellKnownSymbol$1 = wellKnownSymbol$h;
2942
3065
  var Iterators$1 = iterators;
2943
3066
  var IteratorsCore = iteratorsCore;
2944
3067
 
@@ -2946,7 +3069,7 @@ var PROPER_FUNCTION_NAME = FunctionName.PROPER;
2946
3069
  var CONFIGURABLE_FUNCTION_NAME = FunctionName.CONFIGURABLE;
2947
3070
  var IteratorPrototype = IteratorsCore.IteratorPrototype;
2948
3071
  var BUGGY_SAFARI_ITERATORS = IteratorsCore.BUGGY_SAFARI_ITERATORS;
2949
- var ITERATOR$2 = wellKnownSymbol$2('iterator');
3072
+ var ITERATOR$2 = wellKnownSymbol$1('iterator');
2950
3073
  var KEYS = 'keys';
2951
3074
  var VALUES = 'values';
2952
3075
  var ENTRIES = 'entries';
@@ -3013,7 +3136,7 @@ var iteratorDefine = function (Iterable, NAME, IteratorConstructor, next, DEFAUL
3013
3136
  if (BUGGY_SAFARI_ITERATORS || INCORRECT_VALUES_NAME || !(KEY in IterablePrototype)) {
3014
3137
  defineBuiltIn(IterablePrototype, KEY, methods[KEY]);
3015
3138
  }
3016
- } else $$3({ target: NAME, proto: true, forced: BUGGY_SAFARI_ITERATORS || INCORRECT_VALUES_NAME }, methods);
3139
+ } else $$2({ target: NAME, proto: true, forced: BUGGY_SAFARI_ITERATORS || INCORRECT_VALUES_NAME }, methods);
3017
3140
  }
3018
3141
 
3019
3142
  // define iterator
@@ -3032,7 +3155,7 @@ var createIterResultObject$1 = function (value, done) {
3032
3155
  };
3033
3156
 
3034
3157
  var toIndexedObject = toIndexedObject$5;
3035
- var addToUnscopables$1 = addToUnscopables$3;
3158
+ var addToUnscopables = addToUnscopables$3;
3036
3159
  var Iterators = iterators;
3037
3160
  var InternalStateModule = internalState;
3038
3161
  var defineProperty = objectDefineProperty.f;
@@ -3083,9 +3206,9 @@ var es_array_iterator = defineIterator(Array, 'Array', function (iterated, kind)
3083
3206
  var values = Iterators.Arguments = Iterators.Array;
3084
3207
 
3085
3208
  // https://tc39.es/ecma262/#sec-array.prototype-@@unscopables
3086
- addToUnscopables$1('keys');
3087
- addToUnscopables$1('values');
3088
- addToUnscopables$1('entries');
3209
+ addToUnscopables('keys');
3210
+ addToUnscopables('values');
3211
+ addToUnscopables('entries');
3089
3212
 
3090
3213
  // V8 ~ Chrome 45- bug
3091
3214
  if (DESCRIPTORS && values.name !== 'values') try {
@@ -3141,10 +3264,10 @@ var DOMIterables = domIterables;
3141
3264
  var DOMTokenListPrototype = domTokenListPrototype;
3142
3265
  var ArrayIteratorMethods = es_array_iterator;
3143
3266
  var createNonEnumerableProperty = createNonEnumerableProperty$4;
3144
- var wellKnownSymbol$1 = wellKnownSymbol$h;
3267
+ var wellKnownSymbol = wellKnownSymbol$h;
3145
3268
 
3146
- var ITERATOR$1 = wellKnownSymbol$1('iterator');
3147
- var TO_STRING_TAG = wellKnownSymbol$1('toStringTag');
3269
+ var ITERATOR$1 = wellKnownSymbol('iterator');
3270
+ var TO_STRING_TAG = wellKnownSymbol('toStringTag');
3148
3271
  var ArrayValues = ArrayIteratorMethods.values;
3149
3272
 
3150
3273
  var handlePrototype = function (CollectionPrototype, COLLECTION_NAME) {
@@ -3175,115 +3298,54 @@ for (var COLLECTION_NAME in DOMIterables) {
3175
3298
 
3176
3299
  handlePrototype(DOMTokenListPrototype, 'DOMTokenList');
3177
3300
 
3178
- var classof = classofRaw$2;
3179
-
3180
- // `IsArray` abstract operation
3181
- // https://tc39.es/ecma262/#sec-isarray
3182
- // eslint-disable-next-line es/no-array-isarray -- safe
3183
- var isArray$2 = Array.isArray || function isArray(argument) {
3184
- return classof(argument) == 'Array';
3185
- };
3186
-
3187
- var $TypeError$1 = TypeError;
3188
- var MAX_SAFE_INTEGER = 0x1FFFFFFFFFFFFF; // 2 ** 53 - 1 == 9007199254740991
3189
-
3190
- var doesNotExceedSafeInteger$1 = function (it) {
3191
- if (it > MAX_SAFE_INTEGER) throw $TypeError$1('Maximum allowed index exceeded');
3192
- return it;
3193
- };
3194
-
3195
- var isArray$1 = isArray$2;
3196
- var lengthOfArrayLike$2 = lengthOfArrayLike$5;
3197
- var doesNotExceedSafeInteger = doesNotExceedSafeInteger$1;
3198
- var bind = functionBindContext;
3199
-
3200
- // `FlattenIntoArray` abstract operation
3201
- // https://tc39.github.io/proposal-flatMap/#sec-FlattenIntoArray
3202
- var flattenIntoArray$1 = function (target, original, source, sourceLen, start, depth, mapper, thisArg) {
3203
- var targetIndex = start;
3204
- var sourceIndex = 0;
3205
- var mapFn = mapper ? bind(mapper, thisArg) : false;
3206
- var element, elementLen;
3207
-
3208
- while (sourceIndex < sourceLen) {
3209
- if (sourceIndex in source) {
3210
- element = mapFn ? mapFn(source[sourceIndex], sourceIndex, original) : source[sourceIndex];
3211
-
3212
- if (depth > 0 && isArray$1(element)) {
3213
- elementLen = lengthOfArrayLike$2(element);
3214
- targetIndex = flattenIntoArray$1(target, original, element, elementLen, targetIndex, depth - 1) - 1;
3301
+ class ElementSeenObserver {
3302
+ constructor(_options) {
3303
+ this._options = _options;
3304
+ this._elementDelays = new WeakMap();
3305
+ this._intersectionTimers = new WeakMap();
3306
+ if (typeof IntersectionObserver !== 'undefined') {
3307
+ this._intersectionObserver = new IntersectionObserver(this.onIntersection.bind(this));
3308
+ }
3309
+ }
3310
+ onIntersection(entries) {
3311
+ entries.forEach(entry => {
3312
+ const {
3313
+ isIntersecting,
3314
+ target
3315
+ } = entry;
3316
+ if (isIntersecting) {
3317
+ const delay = this._elementDelays.get(target);
3318
+ const timeOut = window.setTimeout(() => {
3319
+ this._options.onElementSeen(target);
3320
+ }, delay);
3321
+ this._intersectionTimers.set(target, timeOut);
3215
3322
  } else {
3216
- doesNotExceedSafeInteger(targetIndex + 1);
3217
- target[targetIndex] = element;
3323
+ const timeOut = this._intersectionTimers.get(target);
3324
+ if (typeof timeOut !== 'undefined') {
3325
+ window.clearTimeout(timeOut);
3326
+ }
3218
3327
  }
3219
-
3220
- targetIndex++;
3221
- }
3222
- sourceIndex++;
3328
+ });
3223
3329
  }
3224
- return targetIndex;
3225
- };
3226
-
3227
- var flattenIntoArray_1 = flattenIntoArray$1;
3228
-
3229
- var isArray = isArray$2;
3230
- var isConstructor = isConstructor$2;
3231
- var isObject = isObject$a;
3232
- var wellKnownSymbol = wellKnownSymbol$h;
3233
-
3234
- var SPECIES = wellKnownSymbol('species');
3235
- var $Array = Array;
3330
+ observe(element, options) {
3331
+ var _a, _b;
3332
+ this._elementDelays.set(element, (_a = options === null || options === void 0 ? void 0 : options.delay) !== null && _a !== void 0 ? _a : 2000);
3333
+ (_b = this._intersectionObserver) === null || _b === void 0 ? void 0 : _b.observe(element);
3334
+ }
3335
+ unobserve(element) {
3336
+ var _a;
3337
+ (_a = this._intersectionObserver) === null || _a === void 0 ? void 0 : _a.unobserve(element);
3338
+ }
3339
+ }
3236
3340
 
3237
- // a part of `ArraySpeciesCreate` abstract operation
3238
- // https://tc39.es/ecma262/#sec-arrayspeciescreate
3239
- var arraySpeciesConstructor$1 = function (originalArray) {
3240
- var C;
3241
- if (isArray(originalArray)) {
3242
- C = originalArray.constructor;
3243
- // cross-realm fallback
3244
- if (isConstructor(C) && (C === $Array || isArray(C.prototype))) C = undefined;
3245
- else if (isObject(C)) {
3246
- C = C[SPECIES];
3247
- if (C === null) C = undefined;
3248
- }
3249
- } return C === undefined ? $Array : C;
3341
+ const acceptsCredentials = plugin => {
3342
+ return typeof plugin === 'object' && plugin !== null && 'setCredentials' in plugin && typeof plugin.setCredentials === 'function';
3250
3343
  };
3251
3344
 
3252
- var arraySpeciesConstructor = arraySpeciesConstructor$1;
3253
-
3254
- // `ArraySpeciesCreate` abstract operation
3255
- // https://tc39.es/ecma262/#sec-arrayspeciescreate
3256
- var arraySpeciesCreate$1 = function (originalArray, length) {
3257
- return new (arraySpeciesConstructor(originalArray))(length === 0 ? 0 : length);
3345
+ const isInterestedInHiddenPage = arg => {
3346
+ return typeof arg === 'object' && arg !== null && PAGE_HIDDEN in arg && typeof arg[PAGE_HIDDEN] === 'function';
3258
3347
  };
3259
3348
 
3260
- var $$2 = _export;
3261
- var flattenIntoArray = flattenIntoArray_1;
3262
- var toObject$1 = toObject$5;
3263
- var lengthOfArrayLike$1 = lengthOfArrayLike$5;
3264
- var toIntegerOrInfinity = toIntegerOrInfinity$3;
3265
- var arraySpeciesCreate = arraySpeciesCreate$1;
3266
-
3267
- // `Array.prototype.flat` method
3268
- // https://tc39.es/ecma262/#sec-array.prototype.flat
3269
- $$2({ target: 'Array', proto: true }, {
3270
- flat: function flat(/* depthArg = 1 */) {
3271
- var depthArg = arguments.length ? arguments[0] : undefined;
3272
- var O = toObject$1(this);
3273
- var sourceLen = lengthOfArrayLike$1(O);
3274
- var A = arraySpeciesCreate(O, 0);
3275
- A.length = flattenIntoArray(A, O, O, sourceLen, 0, depthArg === undefined ? 1 : toIntegerOrInfinity(depthArg));
3276
- return A;
3277
- }
3278
- });
3279
-
3280
- // this method was added to unscopables after implementation
3281
- // in popular engines, so it's moved to a separate module
3282
- var addToUnscopables = addToUnscopables$3;
3283
-
3284
- // https://tc39.es/ecma262/#sec-array.prototype-@@unscopables
3285
- addToUnscopables('flat');
3286
-
3287
3349
  class Ninetailed {
3288
3350
  constructor(ninetailedApiClientInstanceOrOptions, {
3289
3351
  plugins,
@@ -3339,6 +3401,28 @@ class Ninetailed {
3339
3401
  type: HAS_SEEN_EXPERIENCE
3340
3402
  }));
3341
3403
  };
3404
+ this.observeElement = (payload, options) => {
3405
+ const {
3406
+ element
3407
+ } = payload,
3408
+ remaingPayload = __rest(payload, ["element"]);
3409
+ this.observedElements.set(element, remaingPayload);
3410
+ this.elementSeenObserver.observe(element, options);
3411
+ };
3412
+ this.unobserveElement = element => {
3413
+ this.observedElements.delete(element);
3414
+ this.elementSeenObserver.unobserve(element);
3415
+ };
3416
+ this.onElementSeen = element => {
3417
+ const payload = this.observedElements.get(element);
3418
+ if (typeof payload !== 'undefined') {
3419
+ this.instance.dispatch(Object.assign(Object.assign({
3420
+ element
3421
+ }, payload), {
3422
+ type: HAS_SEEN_ELEMENT
3423
+ }));
3424
+ }
3425
+ };
3342
3426
  this.identify = (uid, traits, options) => __awaiter(this, void 0, void 0, function* () {
3343
3427
  try {
3344
3428
  const result = Traits.default({}).safeParse(traits);
@@ -3406,6 +3490,18 @@ class Ninetailed {
3406
3490
  this.onIsInitialized(resolve);
3407
3491
  });
3408
3492
  };
3493
+ this.onVisibilityChange = () => {
3494
+ if (typeof document === 'undefined') {
3495
+ return;
3496
+ }
3497
+ document.addEventListener('visibilitychange', () => {
3498
+ if (document.visibilityState === 'hidden') {
3499
+ this.instance.dispatch({
3500
+ type: PAGE_HIDDEN
3501
+ });
3502
+ }
3503
+ });
3504
+ };
3409
3505
  if (ninetailedApiClientInstanceOrOptions instanceof NinetailedApiClient) {
3410
3506
  this.apiClient = ninetailedApiClientInstanceOrOptions;
3411
3507
  } else {
@@ -3423,15 +3519,15 @@ class Ninetailed {
3423
3519
  preview
3424
3520
  });
3425
3521
  }
3426
- this.plugins = [...(plugins || []).map(plugin => {
3427
- if ('setCredentials' in plugin && typeof plugin['setCredentials'] === 'function') {
3428
- plugin['setCredentials']({
3522
+ this.plugins = (plugins !== null && plugins !== void 0 ? plugins : []).flat();
3523
+ this.plugins.forEach(plugin => {
3524
+ if (acceptsCredentials(plugin) && this.clientId && this.environment) {
3525
+ plugin.setCredentials({
3429
3526
  clientId: this.clientId,
3430
3527
  environment: this.environment
3431
3528
  });
3432
3529
  }
3433
- return plugin;
3434
- }).flat()];
3530
+ });
3435
3531
  if (profile) {
3436
3532
  this._profileState = {
3437
3533
  status: 'success',
@@ -3479,6 +3575,14 @@ class Ninetailed {
3479
3575
  });
3480
3576
  }
3481
3577
  });
3578
+ this.observedElements = new WeakMap();
3579
+ this.elementSeenObserver = new ElementSeenObserver({
3580
+ onElementSeen: this.onElementSeen.bind(this)
3581
+ });
3582
+ const hasPluginsInterestedInHiddenPage = this.plugins.some(isInterestedInHiddenPage);
3583
+ if (hasPluginsInterestedInHiddenPage) {
3584
+ this.onVisibilityChange();
3585
+ }
3482
3586
  this.registerWindowHandlers();
3483
3587
  }
3484
3588
  get profileState() {
@@ -3877,4 +3981,4 @@ const makeExperienceSelectMiddleware = ({
3877
3981
  };
3878
3982
  };
3879
3983
 
3880
- export { ANONYMOUS_ID, CONSENT, DEBUG_FLAG, EMPTY_MERGE_ID, 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 };
3984
+ export { ANONYMOUS_ID, CONSENT, DEBUG_FLAG, EMPTY_MERGE_ID, HAS_SEEN_COMPONENT, HAS_SEEN_ELEMENT, HAS_SEEN_EXPERIENCE, LEGACY_ANONYMOUS_ID, Ninetailed, NinetailedPlugin, OnChangeEmitter, PAGE_HIDDEN, PLUGIN_NAME, PROFILE_CHANGE, PROFILE_FALLBACK_CACHE, PROFILE_RESET, SET_ENABLED_FEATURES, TrackComponentProperties, TrackExperienceProperties, buildClientNinetailedRequestContext, decodeExperienceVariantsMap, makeExperienceSelectMiddleware, ninetailedPlugin, selectPluginsHavingExperienceSelectionMiddleware, selectPluginsHavingOnChangeEmitter, selectVariant };
@@ -0,0 +1,16 @@
1
+ export type ElementSeenObserverOptions = {
2
+ onElementSeen: (element: Element) => void;
3
+ };
4
+ export type ObserveOptions = {
5
+ delay?: number;
6
+ };
7
+ export declare class ElementSeenObserver {
8
+ private _options;
9
+ private _intersectionObserver?;
10
+ private _elementDelays;
11
+ private _intersectionTimers;
12
+ constructor(_options: ElementSeenObserverOptions);
13
+ private onIntersection;
14
+ observe(element: Element, options?: ObserveOptions): void;
15
+ unobserve(element: Element): void;
16
+ }
@@ -1,6 +1,7 @@
1
1
  /// <reference types="analytics" />
2
2
  import { Locale, Traits, Profile, OnLogHandler, OnErrorHandler, Logger, PageviewProperties, Properties, NinetailedApiClient, NinetailedApiClientOptions } from '@ninetailed/experience.js-shared';
3
- import { EventFunctionOptions, NinetailedInstance, NinetailedPlugin, OnIsInitializedCallback, OnProfileChangeCallback, ProfileState, TrackHasSeenComponent, TrackHasSeenExperience } from './types';
3
+ import { EventFunctionOptions, NinetailedInstance, NinetailedPlugin, OnIsInitializedCallback, OnProfileChangeCallback, ProfileState, TrackHasSeenComponent, TrackHasSeenExperience, ElementSeenPayload } from './types';
4
+ import { ObserveOptions } from './ElementSeenObserver';
4
5
  declare global {
5
6
  interface Window {
6
7
  ninetailed?: {
@@ -27,6 +28,8 @@ export declare class Ninetailed implements NinetailedInstance {
27
28
  private isInitialized;
28
29
  private readonly apiClient;
29
30
  private readonly eventQueue;
31
+ private readonly elementSeenObserver;
32
+ private readonly observedElements;
30
33
  private readonly clientId;
31
34
  private readonly environment;
32
35
  readonly plugins: NinetailedPlugin[];
@@ -36,6 +39,9 @@ export declare class Ninetailed implements NinetailedInstance {
36
39
  track: (event: string, properties?: Properties, options?: EventFunctionOptions) => Promise<import("./types").FlushResult>;
37
40
  trackHasSeenComponent: TrackHasSeenComponent;
38
41
  trackHasSeenExperience: TrackHasSeenExperience;
42
+ observeElement: (payload: ElementSeenPayload, options?: ObserveOptions) => void;
43
+ unobserveElement: (element: Element) => void;
44
+ private onElementSeen;
39
45
  identify: (uid: string, traits?: Traits, options?: EventFunctionOptions) => Promise<import("./types").FlushResult>;
40
46
  reset: () => Promise<void>;
41
47
  debug: (enabled: boolean) => Promise<void>;
@@ -45,5 +51,6 @@ export declare class Ninetailed implements NinetailedInstance {
45
51
  get profileState(): ProfileState;
46
52
  private buildOptions;
47
53
  private registerWindowHandlers;
54
+ private onVisibilityChange;
48
55
  }
49
56
  export {};
@@ -1,2 +1,3 @@
1
1
  export * from './get-analytics-plugin';
2
2
  export * from './constants';
3
+ export * from './Events';
@@ -1,2 +1,4 @@
1
1
  export declare const HAS_SEEN_EXPERIENCE = "has_seen_experience";
2
2
  export declare const HAS_SEEN_COMPONENT = "has_seen_component";
3
+ export declare const HAS_SEEN_ELEMENT = "has_seen_element";
4
+ export declare const PAGE_HIDDEN = "page_hidden";
@@ -0,0 +1,2 @@
1
+ import { AcceptsCredentials } from '../types/interfaces/AcceptsCredentials';
2
+ export declare const acceptsCredentials: (plugin: unknown) => plugin is AcceptsCredentials;
@@ -0,0 +1,2 @@
1
+ import { InterestedInHiddenPage } from '../types/interfaces/InterestedInHiddenPage';
2
+ export declare const isInterestedInHiddenPage: (arg: unknown) => arg is InterestedInHiddenPage;
@@ -0,0 +1,2 @@
1
+ import { InterestedInSeenElements } from '../types/interfaces/InterestedInSeenElements';
2
+ export declare const isInterestedInSeenElements: (arg: unknown) => arg is InterestedInSeenElements;
@@ -0,0 +1,4 @@
1
+ export type Credentials = {
2
+ clientId: string;
3
+ environment: string;
4
+ };
@@ -0,0 +1,7 @@
1
+ export type ElementSeenPayload = {
2
+ element: Element;
3
+ experienceId?: string;
4
+ baselineId?: string;
5
+ variantId?: string;
6
+ audienceId?: string;
7
+ };
@@ -0,0 +1,4 @@
1
+ import { type Profile } from '@ninetailed/experience.js-shared';
2
+ export type ProfileChangedPayload = {
3
+ profile: Profile;
4
+ };