@ninetailed/experience.js 7.6.0-beta.5 → 7.6.0-beta.6

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.js CHANGED
@@ -120,6 +120,9 @@ class NinetailedCorePlugin extends experience_jsPluginAnalytics.NinetailedAnalyt
120
120
  this.queue = [];
121
121
  this.enabledFeatures = Object.values(experience_jsShared.FEATURES);
122
122
  this.buildContext = buildClientNinetailedRequestContext;
123
+ this.getComponentViewTrackingThreshold = () => {
124
+ return 0;
125
+ };
123
126
  this[_a] = ({
124
127
  payload
125
128
  }) => __awaiter(this, void 0, void 0, function* () {
@@ -267,9 +270,6 @@ class NinetailedCorePlugin extends experience_jsPluginAnalytics.NinetailedAnalyt
267
270
  }));
268
271
  });
269
272
  }
270
- getComponentViewTrackingThreshold() {
271
- return 0;
272
- }
273
273
  onTrackExperience(properties) {
274
274
  return __awaiter(this, void 0, void 0, function* () {
275
275
  if (properties.experience.sticky) {
@@ -595,10 +595,6 @@ class EventBuilder {
595
595
  }
596
596
  }
597
597
 
598
- const hasComponentViewTrackingThreshold = arg => {
599
- return typeof arg === 'object' && arg !== null && 'getComponentViewTrackingThreshold' in arg && typeof arg['getComponentViewTrackingThreshold'] === 'function';
600
- };
601
-
602
598
  const buildOverrideMiddleware = experienceSelectionMiddleware => _a => {
603
599
  var {
604
600
  experience: originalExperience,
@@ -754,7 +750,9 @@ class Ninetailed {
754
750
  });
755
751
  this.trackComponentView = properties => {
756
752
  return this.instance.dispatch(Object.assign(Object.assign({}, properties), {
757
- type: experience_jsPluginAnalytics.HAS_SEEN_ELEMENT
753
+ type: experience_jsPluginAnalytics.HAS_SEEN_ELEMENT,
754
+ // TODO this is a temporary solution - to not make the user specify a delay
755
+ seenFor: this.componentViewTrackingThreshold
758
756
  }));
759
757
  };
760
758
  this.observeElement = (payload, options) => {
@@ -768,9 +766,20 @@ class Ninetailed {
768
766
  const isConstructorNameNotObject = constructorName && constructorName !== 'Object';
769
767
  experience_jsShared.logger.warn(`ElementSeenObserver.observeElement was called with an invalid element. Expected an Element but got ${typeof element}${isConstructorNameNotObject ? ` of type ${constructorName}` : ''}. This call will be ignored.`);
770
768
  } else {
771
- this.observedElements.set(element, remaingPayload);
769
+ const existingPayloads = this.observedElements.get(element);
772
770
  const delays = this.pluginsWithCustomComponentViewThreshold.map(plugin => plugin.getComponentViewTrackingThreshold());
773
- const uniqueDelays = Array.from(new Set([...delays, (options === null || options === void 0 ? void 0 : options.delay) || this.componentViewTrackingThreshold]));
771
+ const uniqueDelays = Array.from(new Set([...delays, options === null || options === void 0 ? void 0 : options.delay]));
772
+ if (!existingPayloads) {
773
+ this.observedElements.set(element, [remaingPayload]);
774
+ } else {
775
+ const isPayloadAlreadyObserved = existingPayloads.some(payload => {
776
+ return JSON.stringify(payload) === JSON.stringify(remaingPayload);
777
+ });
778
+ if (isPayloadAlreadyObserved) {
779
+ return;
780
+ }
781
+ this.observedElements.set(element, [...existingPayloads, remaingPayload]);
782
+ }
774
783
  uniqueDelays.forEach(delay => {
775
784
  this.elementSeenObserver.observe(element, {
776
785
  delay
@@ -783,21 +792,15 @@ class Ninetailed {
783
792
  this.elementSeenObserver.unobserve(element);
784
793
  };
785
794
  this.onElementSeen = (element, delay) => {
786
- const payload = this.observedElements.get(element);
787
- if (typeof payload !== 'undefined') {
788
- const pluginNamesInterestedInSeenElementMessage = [...this.pluginsWithCustomComponentViewThreshold.filter(plugin => plugin.getComponentViewTrackingThreshold() === delay), ...this.plugins.filter(plugin => !hasComponentViewTrackingThreshold(plugin))].map(plugin => plugin.name);
789
- if (pluginNamesInterestedInSeenElementMessage.length === 0) {
790
- return;
795
+ const payloads = this.observedElements.get(element);
796
+ if (Array.isArray(payloads) && payloads.length > 0) {
797
+ for (const payload of payloads) {
798
+ this.instance.dispatch(Object.assign(Object.assign({}, payload), {
799
+ element,
800
+ type: experience_jsPluginAnalytics.HAS_SEEN_ELEMENT,
801
+ seenFor: delay
802
+ }));
791
803
  }
792
- this.instance.dispatch(Object.assign(Object.assign({}, payload), {
793
- element,
794
- type: experience_jsPluginAnalytics.HAS_SEEN_ELEMENT,
795
- plugins: Object.assign({
796
- all: false
797
- }, pluginNamesInterestedInSeenElementMessage.reduce((acc, curr) => Object.assign(Object.assign({}, acc), {
798
- [curr]: true
799
- }), {}))
800
- }));
801
804
  }
802
805
  };
803
806
  this.reset = () => __awaiter(this, void 0, void 0, function* () {
@@ -1049,6 +1052,9 @@ class Ninetailed {
1049
1052
  environment: this.environment
1050
1053
  });
1051
1054
  }
1055
+ if (experience_jsPluginAnalytics.hasComponentViewTrackingThreshold(plugin)) {
1056
+ plugin.setComponentViewTrackingThreshold(componentViewTrackingThreshold);
1057
+ }
1052
1058
  });
1053
1059
  this._profileState = {
1054
1060
  status: 'loading',
@@ -1106,7 +1112,7 @@ class Ninetailed {
1106
1112
  this.registerWindowHandlers();
1107
1113
  }
1108
1114
  get pluginsWithCustomComponentViewThreshold() {
1109
- return [this.ninetailedCorePlugin, ...this.plugins].filter(plugin => hasComponentViewTrackingThreshold(plugin));
1115
+ return [this.ninetailedCorePlugin, ...this.plugins].filter(plugin => experience_jsPluginAnalytics.hasComponentViewTrackingThreshold(plugin));
1110
1116
  }
1111
1117
  get profileState() {
1112
1118
  return this._profileState;
package/index.esm.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { FEATURES, buildComponentViewEvent, logger, ConsoleLogSink, buildPageEvent, buildTrackEvent, buildIdentifyEvent, unionBy, pipe, PageviewProperties, Properties, Traits, isPageViewEvent, isTrackEvent, isIdentifyEvent, isComponentViewEvent, selectHasVariants, selectExperience, selectVariant as selectVariant$1, selectBaselineWithVariants, NinetailedApiClient, OnLogLogSink, OnErrorLogSink } from '@ninetailed/experience.js-shared';
2
2
  export { EXPERIENCE_TRAIT_PREFIX, isExperienceMatch, selectActiveExperiments, selectDistribution, selectExperience, selectBaselineWithVariants as selectExperienceBaselineWithVariants, selectVariant as selectExperienceVariant, selectVariants as selectExperienceVariants, selectHasVariants as selectHasExperienceVariants } from '@ninetailed/experience.js-shared';
3
- import { NinetailedAnalyticsPlugin, HAS_SEEN_COMPONENT, HAS_SEEN_ELEMENT } from '@ninetailed/experience.js-plugin-analytics';
3
+ import { NinetailedAnalyticsPlugin, HAS_SEEN_COMPONENT, HAS_SEEN_ELEMENT, hasComponentViewTrackingThreshold } from '@ninetailed/experience.js-plugin-analytics';
4
4
  import Analytics from 'analytics';
5
5
  import { v4 } from 'uuid';
6
6
 
@@ -82,6 +82,9 @@ class NinetailedCorePlugin extends NinetailedAnalyticsPlugin {
82
82
  this.apiClient = void 0;
83
83
  this.locale = void 0;
84
84
  this.ninetailed = void 0;
85
+ this.getComponentViewTrackingThreshold = () => {
86
+ return 0;
87
+ };
85
88
  this[HAS_SEEN_STICKY_COMPONENT] = async function ({
86
89
  payload
87
90
  }) {
@@ -222,9 +225,6 @@ class NinetailedCorePlugin extends NinetailedAnalyticsPlugin {
222
225
  ctx
223
226
  }));
224
227
  }
225
- getComponentViewTrackingThreshold() {
226
- return 0;
227
- }
228
228
  async onTrackExperience(properties) {
229
229
  if (properties.experience.sticky) {
230
230
  await this.instance.dispatch({
@@ -560,10 +560,6 @@ class EventBuilder {
560
560
  }
561
561
  }
562
562
 
563
- const hasComponentViewTrackingThreshold = arg => {
564
- return typeof arg === 'object' && arg !== null && 'getComponentViewTrackingThreshold' in arg && typeof arg['getComponentViewTrackingThreshold'] === 'function';
565
- };
566
-
567
563
  const _excluded = ["experience", "variant", "variantIndex"],
568
564
  _excluded2 = ["element"];
569
565
  const buildOverrideMiddleware = experienceSelectionMiddleware => _ref => {
@@ -735,7 +731,9 @@ class Ninetailed {
735
731
  };
736
732
  this.trackComponentView = properties => {
737
733
  return this.instance.dispatch(Object.assign({}, properties, {
738
- type: HAS_SEEN_ELEMENT
734
+ type: HAS_SEEN_ELEMENT,
735
+ // TODO this is a temporary solution - to not make the user specify a delay
736
+ seenFor: this.componentViewTrackingThreshold
739
737
  }));
740
738
  };
741
739
  this.observeElement = (payload, options) => {
@@ -749,9 +747,20 @@ class Ninetailed {
749
747
  const isConstructorNameNotObject = constructorName && constructorName !== 'Object';
750
748
  logger.warn(`ElementSeenObserver.observeElement was called with an invalid element. Expected an Element but got ${typeof element}${isConstructorNameNotObject ? ` of type ${constructorName}` : ''}. This call will be ignored.`);
751
749
  } else {
752
- this.observedElements.set(element, remaingPayload);
750
+ const existingPayloads = this.observedElements.get(element);
753
751
  const delays = this.pluginsWithCustomComponentViewThreshold.map(plugin => plugin.getComponentViewTrackingThreshold());
754
- const uniqueDelays = Array.from(new Set([...delays, (options == null ? void 0 : options.delay) || this.componentViewTrackingThreshold]));
752
+ const uniqueDelays = Array.from(new Set([...delays, options == null ? void 0 : options.delay]));
753
+ if (!existingPayloads) {
754
+ this.observedElements.set(element, [remaingPayload]);
755
+ } else {
756
+ const isPayloadAlreadyObserved = existingPayloads.some(payload => {
757
+ return JSON.stringify(payload) === JSON.stringify(remaingPayload);
758
+ });
759
+ if (isPayloadAlreadyObserved) {
760
+ return;
761
+ }
762
+ this.observedElements.set(element, [...existingPayloads, remaingPayload]);
763
+ }
755
764
  uniqueDelays.forEach(delay => {
756
765
  this.elementSeenObserver.observe(element, {
757
766
  delay
@@ -764,21 +773,15 @@ class Ninetailed {
764
773
  this.elementSeenObserver.unobserve(element);
765
774
  };
766
775
  this.onElementSeen = (element, delay) => {
767
- const payload = this.observedElements.get(element);
768
- if (typeof payload !== 'undefined') {
769
- const pluginNamesInterestedInSeenElementMessage = [...this.pluginsWithCustomComponentViewThreshold.filter(plugin => plugin.getComponentViewTrackingThreshold() === delay), ...this.plugins.filter(plugin => !hasComponentViewTrackingThreshold(plugin))].map(plugin => plugin.name);
770
- if (pluginNamesInterestedInSeenElementMessage.length === 0) {
771
- return;
776
+ const payloads = this.observedElements.get(element);
777
+ if (Array.isArray(payloads) && payloads.length > 0) {
778
+ for (const payload of payloads) {
779
+ this.instance.dispatch(Object.assign({}, payload, {
780
+ element,
781
+ type: HAS_SEEN_ELEMENT,
782
+ seenFor: delay
783
+ }));
772
784
  }
773
- this.instance.dispatch(Object.assign({}, payload, {
774
- element,
775
- type: HAS_SEEN_ELEMENT,
776
- plugins: Object.assign({
777
- all: false
778
- }, pluginNamesInterestedInSeenElementMessage.reduce((acc, curr) => Object.assign({}, acc, {
779
- [curr]: true
780
- }), {}))
781
- }));
782
785
  }
783
786
  };
784
787
  this.reset = async function () {
@@ -1031,6 +1034,9 @@ class Ninetailed {
1031
1034
  environment: this.environment
1032
1035
  });
1033
1036
  }
1037
+ if (hasComponentViewTrackingThreshold(plugin)) {
1038
+ plugin.setComponentViewTrackingThreshold(componentViewTrackingThreshold);
1039
+ }
1034
1040
  });
1035
1041
  this._profileState = {
1036
1042
  status: 'loading',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ninetailed/experience.js",
3
- "version": "7.6.0-beta.5",
3
+ "version": "7.6.0-beta.6",
4
4
  "description": "Ninetailed SDK for javascript",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -9,11 +9,14 @@
9
9
  "directory": "packages/sdks/javascript"
10
10
  },
11
11
  "dependencies": {
12
+ "@ninetailed/experience.js-plugin-analytics": "7.6.0-beta.6",
13
+ "@ninetailed/experience.js-shared": "7.6.0-beta.6",
12
14
  "analytics": "0.8.1",
13
- "@ninetailed/experience.js-plugin-analytics": "7.6.0-beta.5",
14
- "@ninetailed/experience.js-shared": "7.6.0-beta.5",
15
15
  "uuid": "9.0.0"
16
16
  },
17
+ "devDependencies": {
18
+ "@jest/globals": "29.7.0"
19
+ },
17
20
  "module": "./index.esm.js",
18
21
  "main": "./index.cjs.js"
19
22
  }
@@ -1,9 +1,8 @@
1
1
  import { AnalyticsInstance } from 'analytics';
2
2
  import { Locale, NinetailedApiClient, NinetailedRequestContext } from '@ninetailed/experience.js-shared';
3
- import { NinetailedAnalyticsPlugin, NinetailedPlugin, SanitizedElementSeenPayload } from '@ninetailed/experience.js-plugin-analytics';
3
+ import { NinetailedAnalyticsPlugin, SanitizedElementSeenPayload } from '@ninetailed/experience.js-plugin-analytics';
4
4
  import { NinetailedInstance, FlushResult } from '../types';
5
5
  import { HAS_SEEN_STICKY_COMPONENT } from '../constants';
6
- import { HasComponentViewTrackingThreshold } from '../types/interfaces/HasComponentViewTrackingThreshold';
7
6
  export type OnInitProfileId = (profileId?: string) => Promise<string | undefined> | string | undefined;
8
7
  type AnalyticsPluginNinetailedConfig = {
9
8
  apiClient: NinetailedApiClient;
@@ -25,10 +24,10 @@ type AbortableFnParams = {
25
24
  type InternalAnalyticsInstance = AnalyticsInstance & {
26
25
  dispatch: (action: any) => void;
27
26
  };
28
- export interface NinetailedCorePlugin extends NinetailedPlugin {
27
+ export interface NinetailedCorePlugin extends NinetailedAnalyticsPlugin {
29
28
  flush: (args: void) => Promise<FlushResult>;
30
29
  }
31
- export declare class NinetailedCorePlugin extends NinetailedAnalyticsPlugin implements NinetailedCorePlugin, HasComponentViewTrackingThreshold {
30
+ export declare class NinetailedCorePlugin extends NinetailedAnalyticsPlugin implements NinetailedCorePlugin {
32
31
  name: string;
33
32
  private _instance?;
34
33
  private queue;
@@ -48,7 +47,7 @@ export declare class NinetailedCorePlugin extends NinetailedAnalyticsPlugin impl
48
47
  track({ payload }: EventFn): Promise<void>;
49
48
  identifyStart(params: AbortableFnParams): unknown;
50
49
  identify({ payload }: EventFn): Promise<void>;
51
- getComponentViewTrackingThreshold(): number;
50
+ getComponentViewTrackingThreshold: () => number;
52
51
  protected onTrackExperience(properties: SanitizedElementSeenPayload): Promise<void>;
53
52
  protected onTrackComponent(): Promise<void>;
54
53
  [HAS_SEEN_STICKY_COMPONENT]: ({ payload }: EventFn) => Promise<void>;
@@ -0,0 +1,2 @@
1
+ export declare function intersect(element: Element, isIntersecting: boolean): void;
2
+ export declare function getObserverOf(element: Element): IntersectionObserver;
@@ -40,7 +40,7 @@ export type OnProfileChangeCallback = (profile: ProfileState) => void;
40
40
  export type Page = (data?: Partial<PageviewProperties>, options?: EventFunctionOptions) => Promise<FlushResult>;
41
41
  export type Track = (event: string, properties?: Properties, options?: EventFunctionOptions) => Promise<FlushResult>;
42
42
  export type TrackHasSeenComponent = (properties: TrackComponentProperties) => Promise<void>;
43
- export type TrackComponentView = (properties: ElementSeenPayload) => Promise<void>;
43
+ export type TrackComponentView = (properties: Omit<ElementSeenPayload, 'seenFor'>) => Promise<void>;
44
44
  export type Identify = (uid: string, traits?: Traits, options?: EventFunctionOptions) => Promise<FlushResult>;
45
45
  export type Batch = (events: Event[]) => Promise<FlushResult>;
46
46
  export type Reset = () => void;
@@ -1,3 +0,0 @@
1
- import { NinetailedPlugin } from '@ninetailed/experience.js-plugin-analytics';
2
- import type { HasComponentViewTrackingThreshold } from '../types/interfaces/HasComponentViewTrackingThreshold';
3
- export declare const hasComponentViewTrackingThreshold: (arg: NinetailedPlugin) => arg is NinetailedPlugin & HasComponentViewTrackingThreshold;
@@ -1,3 +0,0 @@
1
- export interface HasComponentViewTrackingThreshold {
2
- getComponentViewTrackingThreshold: () => number;
3
- }