@dotcms/analytics 1.2.0-next.1 → 1.2.0-next.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +197 -7
- package/lib/core/dot-analytics.content.js +63 -0
- package/lib/core/plugin/click/dot-analytics.click-tracker.d.ts +108 -0
- package/lib/core/plugin/click/dot-analytics.click-tracker.js +144 -0
- package/lib/core/plugin/click/dot-analytics.click.plugin.d.ts +36 -0
- package/lib/core/plugin/click/dot-analytics.click.plugin.js +27 -0
- package/lib/core/plugin/click/dot-analytics.click.utils.d.ts +12 -0
- package/lib/core/plugin/click/dot-analytics.click.utils.js +55 -0
- package/lib/core/plugin/enricher/dot-analytics.enricher.plugin.d.ts +14 -10
- package/lib/core/plugin/enricher/dot-analytics.enricher.plugin.js +26 -38
- package/lib/core/{shared/dot-content-analytics.activity-tracker.d.ts → plugin/identity/dot-analytics.identity.activity-tracker.d.ts} +2 -17
- package/lib/core/{shared/dot-content-analytics.activity-tracker.js → plugin/identity/dot-analytics.identity.activity-tracker.js} +17 -37
- package/lib/core/plugin/identity/dot-analytics.identity.plugin.d.ts +2 -20
- package/lib/core/plugin/identity/dot-analytics.identity.plugin.js +7 -7
- package/lib/core/plugin/identity/dot-analytics.identity.utils.d.ts +0 -16
- package/lib/core/plugin/impression/dot-analytics.impression-tracker.d.ts +62 -0
- package/lib/core/plugin/impression/dot-analytics.impression-tracker.js +200 -0
- package/lib/core/plugin/impression/dot-analytics.impression.plugin.d.ts +40 -0
- package/lib/core/plugin/impression/dot-analytics.impression.plugin.js +27 -0
- package/lib/core/plugin/impression/dot-analytics.impression.utils.d.ts +26 -0
- package/lib/core/plugin/impression/dot-analytics.impression.utils.js +27 -0
- package/lib/core/plugin/impression/index.d.ts +2 -0
- package/lib/core/plugin/main/dot-analytics.plugin.d.ts +46 -0
- package/lib/core/plugin/main/dot-analytics.plugin.js +114 -0
- package/lib/core/shared/constants/{dot-content-analytics.constants.d.ts → dot-analytics.constants.d.ts} +61 -0
- package/lib/core/shared/constants/dot-analytics.constants.js +52 -0
- package/lib/core/shared/constants/index.d.ts +1 -1
- package/lib/core/shared/dot-analytics.logger.d.ts +85 -0
- package/lib/core/shared/dot-analytics.logger.js +90 -0
- package/lib/core/shared/http/dot-analytics.http.d.ts +9 -0
- package/lib/core/shared/http/dot-analytics.http.js +34 -0
- package/lib/core/shared/models/data.model.d.ts +39 -1
- package/lib/core/shared/models/event.model.d.ts +74 -3
- package/lib/core/shared/models/library.model.d.ts +77 -25
- package/lib/core/shared/models/request.model.d.ts +17 -9
- package/lib/core/shared/queue/dot-analytics.queue.utils.js +44 -37
- package/lib/core/shared/{dot-content-analytics.utils.d.ts → utils/dot-analytics.utils.d.ts} +91 -3
- package/lib/core/shared/utils/dot-analytics.utils.js +202 -0
- package/lib/react/hook/useRouterTracker.js +4 -4
- package/lib/react/internal/utils.js +1 -1
- package/package.json +7 -6
- package/lib/core/dot-content-analytics.js +0 -46
- package/lib/core/plugin/dot-analytics.plugin.d.ts +0 -33
- package/lib/core/plugin/dot-analytics.plugin.js +0 -42
- package/lib/core/shared/constants/dot-content-analytics.constants.js +0 -34
- package/lib/core/shared/dot-content-analytics.http.d.ts +0 -17
- package/lib/core/shared/dot-content-analytics.http.js +0 -41
- package/lib/core/shared/dot-content-analytics.utils.js +0 -147
- /package/lib/core/{dot-content-analytics.d.ts → dot-analytics.content.d.ts} +0 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { DotCMSImpressionTracker as t } from "./dot-analytics.impression-tracker.js";
|
|
2
|
+
import { createPluginLogger as a, isBrowser as p, setupPluginCleanup as u } from "../../shared/utils/dot-analytics.utils.js";
|
|
3
|
+
const g = (n) => {
|
|
4
|
+
let i = null, e = null;
|
|
5
|
+
const r = a("Impression", n);
|
|
6
|
+
return {
|
|
7
|
+
name: "dot-analytics-impression",
|
|
8
|
+
/**
|
|
9
|
+
* Initialize impression tracking
|
|
10
|
+
* Called when Analytics.js initializes the plugin with instance context
|
|
11
|
+
* @param instance - Analytics.js instance with track method
|
|
12
|
+
*/
|
|
13
|
+
initialize: ({ instance: s }) => n.impressions ? (i = new t(n), i.initialize(), e = i.onImpression((o, l) => {
|
|
14
|
+
s.track(o, l);
|
|
15
|
+
}), r.info("Impression tracking plugin initialized"), Promise.resolve()) : (r.info("Impression tracking disabled (config.impressions not set)"), Promise.resolve()),
|
|
16
|
+
/**
|
|
17
|
+
* Setup cleanup handlers when plugin is loaded
|
|
18
|
+
* Called after Analytics.js completes plugin loading
|
|
19
|
+
*/
|
|
20
|
+
loaded: () => (p() && i && u(() => {
|
|
21
|
+
e && (e.unsubscribe(), e = null), i && (i.cleanup(), i = null, r.info("Impression tracking cleaned up on page unload"));
|
|
22
|
+
}), !0)
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
export {
|
|
26
|
+
g as dotAnalyticsImpressionPlugin
|
|
27
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { ViewportMetrics } from '../../shared/models';
|
|
2
|
+
/**
|
|
3
|
+
* Calculates the visibility ratio of an element in the viewport
|
|
4
|
+
* @param element - The HTML element to check
|
|
5
|
+
* @returns A number between 0 and 1 representing the visible percentage
|
|
6
|
+
*/
|
|
7
|
+
export declare function calculateElementVisibilityRatio(element: HTMLElement): number;
|
|
8
|
+
/**
|
|
9
|
+
* Calculates the offset percentage of an element from the top of the viewport
|
|
10
|
+
* @param element - The HTML element to check
|
|
11
|
+
* @returns Percentage value (can be negative if above viewport)
|
|
12
|
+
*/
|
|
13
|
+
export declare function calculateViewportOffset(element: HTMLElement): number;
|
|
14
|
+
/**
|
|
15
|
+
* Checks if an element meets a specific visibility threshold
|
|
16
|
+
* @param element - The HTML element to check
|
|
17
|
+
* @param threshold - The required visibility ratio (0.0 to 1.0)
|
|
18
|
+
* @returns True if the element meets or exceeds the threshold
|
|
19
|
+
*/
|
|
20
|
+
export declare function isElementMeetingVisibilityThreshold(element: HTMLElement, threshold: number): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Gets comprehensive viewport metrics for an element
|
|
23
|
+
* @param element - The HTML element to analyze
|
|
24
|
+
* @returns Object containing offset percentage and visibility ratio
|
|
25
|
+
*/
|
|
26
|
+
export declare function getViewportMetrics(element: HTMLElement): ViewportMetrics;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
function s(e) {
|
|
2
|
+
const t = e.getBoundingClientRect(), i = window.innerHeight || document.documentElement.clientHeight, n = window.innerWidth || document.documentElement.clientWidth, o = Math.min(t.bottom, i) - Math.max(t.top, 0), c = Math.min(t.right, n) - Math.max(t.left, 0);
|
|
3
|
+
if (o <= 0 || c <= 0)
|
|
4
|
+
return 0;
|
|
5
|
+
const l = o * c, r = t.height * t.width;
|
|
6
|
+
return r > 0 ? l / r : 0;
|
|
7
|
+
}
|
|
8
|
+
function h(e) {
|
|
9
|
+
const t = e.getBoundingClientRect(), i = window.innerHeight || document.documentElement.clientHeight, n = t.top / i * 100;
|
|
10
|
+
return Math.round(n * 100) / 100;
|
|
11
|
+
}
|
|
12
|
+
function a(e, t) {
|
|
13
|
+
return s(e) >= t;
|
|
14
|
+
}
|
|
15
|
+
function u(e) {
|
|
16
|
+
const t = s(e);
|
|
17
|
+
return {
|
|
18
|
+
offsetPercentage: h(e),
|
|
19
|
+
visibilityRatio: t
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export {
|
|
23
|
+
s as calculateElementVisibilityRatio,
|
|
24
|
+
h as calculateViewportOffset,
|
|
25
|
+
u as getViewportMetrics,
|
|
26
|
+
a as isElementMeetingVisibilityThreshold
|
|
27
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { DotCMSAnalyticsConfig, EnrichedAnalyticsPayload, EnrichedTrackPayload } from '../../shared/models';
|
|
2
|
+
/**
|
|
3
|
+
* Analytics plugin for tracking page views and custom events in DotCMS applications.
|
|
4
|
+
* This plugin handles:
|
|
5
|
+
* 1. Event structuring (deciding between predefined and custom events)
|
|
6
|
+
* 2. Building complete request bodies
|
|
7
|
+
* 3. Sending analytics data to the DotCMS server
|
|
8
|
+
* 4. Managing initialization and queue management
|
|
9
|
+
*
|
|
10
|
+
* The enricher plugin runs BEFORE this plugin and adds page/utm/custom data.
|
|
11
|
+
* This plugin receives enriched payloads and structures them into proper events.
|
|
12
|
+
*
|
|
13
|
+
* @param {DotCMSAnalyticsConfig} config - Configuration object containing API key, server URL,
|
|
14
|
+
* debug mode, auto page view settings, and queue config
|
|
15
|
+
* @returns {Object} Plugin object with methods for initialization and event tracking
|
|
16
|
+
*/
|
|
17
|
+
export declare const dotAnalytics: (config: DotCMSAnalyticsConfig) => {
|
|
18
|
+
name: string;
|
|
19
|
+
config: DotCMSAnalyticsConfig;
|
|
20
|
+
/**
|
|
21
|
+
* Initialize the plugin with optional queue management
|
|
22
|
+
*/
|
|
23
|
+
initialize: () => Promise<void>;
|
|
24
|
+
/**
|
|
25
|
+
* Track a page view event
|
|
26
|
+
* Receives enriched payload from the enricher plugin and structures it into a pageview event
|
|
27
|
+
*/
|
|
28
|
+
page: ({ payload }: {
|
|
29
|
+
payload: EnrichedAnalyticsPayload;
|
|
30
|
+
}) => void;
|
|
31
|
+
/**
|
|
32
|
+
* Track a custom or predefined event
|
|
33
|
+
* Receives enriched payload from enricher plugin and structures it into proper event format.
|
|
34
|
+
*
|
|
35
|
+
* - content_impression → extracts from properties, combines with enriched page data
|
|
36
|
+
* - content_click → extracts from properties, combines with enriched page data
|
|
37
|
+
* - custom events → wraps properties in custom object
|
|
38
|
+
*/
|
|
39
|
+
track: ({ payload }: {
|
|
40
|
+
payload: EnrichedTrackPayload;
|
|
41
|
+
}) => void;
|
|
42
|
+
/**
|
|
43
|
+
* Check if the plugin is loaded
|
|
44
|
+
*/
|
|
45
|
+
loaded: () => boolean;
|
|
46
|
+
};
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { DotCMSPredefinedEventType as c } from "../../shared/constants/dot-analytics.constants.js";
|
|
2
|
+
import { sendAnalyticsEvent as f } from "../../shared/http/dot-analytics.http.js";
|
|
3
|
+
import { createAnalyticsQueue as w } from "../../shared/queue/dot-analytics.queue.utils.js";
|
|
4
|
+
const _ = (l) => {
|
|
5
|
+
let u = !1;
|
|
6
|
+
const m = l.queue !== !1;
|
|
7
|
+
let d = null;
|
|
8
|
+
const y = (e) => {
|
|
9
|
+
const n = e.events[0], t = e.context;
|
|
10
|
+
m && d ? d.enqueue(n, t) : f(e, l);
|
|
11
|
+
};
|
|
12
|
+
return {
|
|
13
|
+
name: "dot-analytics",
|
|
14
|
+
config: l,
|
|
15
|
+
/**
|
|
16
|
+
* Initialize the plugin with optional queue management
|
|
17
|
+
*/
|
|
18
|
+
initialize: () => (u = !0, m && (d = w(l), d.initialize()), Promise.resolve()),
|
|
19
|
+
/**
|
|
20
|
+
* Track a page view event
|
|
21
|
+
* Receives enriched payload from the enricher plugin and structures it into a pageview event
|
|
22
|
+
*/
|
|
23
|
+
page: ({ payload: e }) => {
|
|
24
|
+
if (!u)
|
|
25
|
+
throw new Error("DotCMS Analytics: Plugin not initialized");
|
|
26
|
+
const { context: n, page: t, utm: p, custom: i, local_time: o } = e;
|
|
27
|
+
if (!t)
|
|
28
|
+
throw new Error("DotCMS Analytics: Missing required page data");
|
|
29
|
+
const v = {
|
|
30
|
+
context: n,
|
|
31
|
+
events: [
|
|
32
|
+
{
|
|
33
|
+
event_type: c.PAGEVIEW,
|
|
34
|
+
local_time: o,
|
|
35
|
+
data: {
|
|
36
|
+
page: t,
|
|
37
|
+
...p && { utm: p },
|
|
38
|
+
...i && { custom: i }
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
]
|
|
42
|
+
};
|
|
43
|
+
y(v);
|
|
44
|
+
},
|
|
45
|
+
/**
|
|
46
|
+
* Track a custom or predefined event
|
|
47
|
+
* Receives enriched payload from enricher plugin and structures it into proper event format.
|
|
48
|
+
*
|
|
49
|
+
* - content_impression → extracts from properties, combines with enriched page data
|
|
50
|
+
* - content_click → extracts from properties, combines with enriched page data
|
|
51
|
+
* - custom events → wraps properties in custom object
|
|
52
|
+
*/
|
|
53
|
+
track: ({ payload: e }) => {
|
|
54
|
+
if (!u)
|
|
55
|
+
throw new Error("DotCMS Analytics: Plugin not initialized");
|
|
56
|
+
const { event: n, properties: t, context: p, local_time: i } = e;
|
|
57
|
+
let o;
|
|
58
|
+
switch (n) {
|
|
59
|
+
case c.CONTENT_IMPRESSION: {
|
|
60
|
+
const E = t, { content: s, position: a } = E, { page: r } = e;
|
|
61
|
+
if (!s || !a || !r)
|
|
62
|
+
throw new Error("DotCMS Analytics: Missing required impression data");
|
|
63
|
+
o = {
|
|
64
|
+
event_type: c.CONTENT_IMPRESSION,
|
|
65
|
+
local_time: i,
|
|
66
|
+
data: {
|
|
67
|
+
content: s,
|
|
68
|
+
position: a,
|
|
69
|
+
page: r
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
break;
|
|
73
|
+
}
|
|
74
|
+
case c.CONTENT_CLICK: {
|
|
75
|
+
const E = t, { content: s, position: a, element: r } = E, { page: C } = e;
|
|
76
|
+
if (!s || !a || !r || !C)
|
|
77
|
+
throw new Error("DotCMS Analytics: Missing required click data");
|
|
78
|
+
o = {
|
|
79
|
+
event_type: c.CONTENT_CLICK,
|
|
80
|
+
local_time: i,
|
|
81
|
+
data: {
|
|
82
|
+
content: s,
|
|
83
|
+
position: a,
|
|
84
|
+
element: r,
|
|
85
|
+
page: C
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
break;
|
|
89
|
+
}
|
|
90
|
+
default: {
|
|
91
|
+
o = {
|
|
92
|
+
event_type: n,
|
|
93
|
+
local_time: i,
|
|
94
|
+
data: {
|
|
95
|
+
custom: t
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
y({
|
|
102
|
+
context: p,
|
|
103
|
+
events: [o]
|
|
104
|
+
});
|
|
105
|
+
},
|
|
106
|
+
/**
|
|
107
|
+
* Check if the plugin is loaded
|
|
108
|
+
*/
|
|
109
|
+
loaded: () => u
|
|
110
|
+
};
|
|
111
|
+
};
|
|
112
|
+
export {
|
|
113
|
+
_ as dotAnalytics
|
|
114
|
+
};
|
|
@@ -7,6 +7,8 @@ export declare const ANALYTICS_ENDPOINT = "/api/v1/analytics/content/event";
|
|
|
7
7
|
*/
|
|
8
8
|
export declare const DotCMSPredefinedEventType: {
|
|
9
9
|
readonly PAGEVIEW: "pageview";
|
|
10
|
+
readonly CONTENT_IMPRESSION: "content_impression";
|
|
11
|
+
readonly CONTENT_CLICK: "content_click";
|
|
10
12
|
};
|
|
11
13
|
/**
|
|
12
14
|
* Type for structured events
|
|
@@ -68,3 +70,62 @@ export declare const ANALYTICS_MINIFIED_SCRIPT_NAME = "ca.min.js";
|
|
|
68
70
|
* These should be filtered out to only keep user-provided properties
|
|
69
71
|
*/
|
|
70
72
|
export declare const ANALYTICS_JS_DEFAULT_PROPERTIES: readonly ["title", "url", "path", "hash", "search", "width", "height", "referrer"];
|
|
73
|
+
/**
|
|
74
|
+
* Impression tracking configuration constants
|
|
75
|
+
*/
|
|
76
|
+
/**
|
|
77
|
+
* Default minimum percentage of element that must be visible (0.0 to 1.0)
|
|
78
|
+
*/
|
|
79
|
+
export declare const DEFAULT_IMPRESSION_VISIBILITY_THRESHOLD = 0.5;
|
|
80
|
+
/**
|
|
81
|
+
* Default minimum time in milliseconds element must be visible
|
|
82
|
+
*/
|
|
83
|
+
export declare const DEFAULT_IMPRESSION_DWELL_MS = 750;
|
|
84
|
+
/**
|
|
85
|
+
* Default maximum number of elements to track (performance limit)
|
|
86
|
+
*/
|
|
87
|
+
export declare const DEFAULT_IMPRESSION_MAX_NODES = 100;
|
|
88
|
+
/**
|
|
89
|
+
* Default throttle time in milliseconds for intersection callbacks
|
|
90
|
+
*/
|
|
91
|
+
export declare const DEFAULT_IMPRESSION_THROTTLE_MS = 100;
|
|
92
|
+
/**
|
|
93
|
+
* Default debounce time in milliseconds for MutationObserver
|
|
94
|
+
*/
|
|
95
|
+
export declare const DEFAULT_IMPRESSION_MUTATION_OBSERVER_DEBOUNCE_MS = 250;
|
|
96
|
+
/**
|
|
97
|
+
* Default impression tracking configuration
|
|
98
|
+
*/
|
|
99
|
+
export declare const DEFAULT_IMPRESSION_CONFIG: {
|
|
100
|
+
readonly visibilityThreshold: 0.5;
|
|
101
|
+
readonly dwellMs: 750;
|
|
102
|
+
readonly maxNodes: 100;
|
|
103
|
+
readonly throttleMs: 100;
|
|
104
|
+
};
|
|
105
|
+
/**
|
|
106
|
+
* Event type for content impressions
|
|
107
|
+
* Must match DotCMSPredefinedEventType.CONTENT_IMPRESSION
|
|
108
|
+
*/
|
|
109
|
+
export declare const IMPRESSION_EVENT_TYPE = "content_impression";
|
|
110
|
+
/**
|
|
111
|
+
* Event type for content clicks
|
|
112
|
+
* Must match DotCMSPredefinedEventType.CONTENT_CLICK
|
|
113
|
+
*/
|
|
114
|
+
export declare const CLICK_EVENT_TYPE = "content_click";
|
|
115
|
+
/**
|
|
116
|
+
* Default debounce time in milliseconds for clicks
|
|
117
|
+
*/
|
|
118
|
+
export declare const DEFAULT_CLICK_THROTTLE_MS = 300;
|
|
119
|
+
/**
|
|
120
|
+
* CSS selector for clickable elements to track
|
|
121
|
+
* Only clicks on <a> and <button> elements are tracked
|
|
122
|
+
*/
|
|
123
|
+
export declare const CLICKABLE_ELEMENTS_SELECTOR = "a, button";
|
|
124
|
+
/**
|
|
125
|
+
* Session storage key for tracked impressions (deduplication)
|
|
126
|
+
*/
|
|
127
|
+
export declare const IMPRESSION_SESSION_KEY = "dot_analytics_impressions";
|
|
128
|
+
/**
|
|
129
|
+
* CSS class selector for trackable contentlets
|
|
130
|
+
*/
|
|
131
|
+
export declare const ANALYTICS_CONTENTLET_CLASS = "dotcms-analytics-contentlet";
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
const I = "/api/v1/analytics/content/event", c = {
|
|
2
|
+
PAGEVIEW: "pageview",
|
|
3
|
+
CONTENT_IMPRESSION: "content_impression",
|
|
4
|
+
CONTENT_CLICK: "content_click"
|
|
5
|
+
}, s = [
|
|
6
|
+
"utm_source",
|
|
7
|
+
"utm_medium",
|
|
8
|
+
"utm_campaign",
|
|
9
|
+
"utm_term",
|
|
10
|
+
"utm_content"
|
|
11
|
+
], o = 30, e = "dot_analytics_session_id", N = "dot_analytics_user_id", E = 15, _ = 5e3, L = ["click"], O = {
|
|
12
|
+
eventBatchSize: E,
|
|
13
|
+
// Max events per batch - auto-sends when reached
|
|
14
|
+
flushInterval: _
|
|
15
|
+
// Time between flushes - sends whatever is queued
|
|
16
|
+
}, i = [
|
|
17
|
+
"title",
|
|
18
|
+
"url",
|
|
19
|
+
"path",
|
|
20
|
+
"hash",
|
|
21
|
+
"search",
|
|
22
|
+
"width",
|
|
23
|
+
"height",
|
|
24
|
+
"referrer"
|
|
25
|
+
], t = 0.5, T = 750, n = 100, S = 100, A = 250, C = {
|
|
26
|
+
visibilityThreshold: t,
|
|
27
|
+
dwellMs: T,
|
|
28
|
+
maxNodes: n,
|
|
29
|
+
throttleMs: S
|
|
30
|
+
}, U = "content_impression", M = "content_click", D = 300, a = "a, button", R = "dotcms-analytics-contentlet";
|
|
31
|
+
export {
|
|
32
|
+
L as ACTIVITY_EVENTS,
|
|
33
|
+
R as ANALYTICS_CONTENTLET_CLASS,
|
|
34
|
+
I as ANALYTICS_ENDPOINT,
|
|
35
|
+
i as ANALYTICS_JS_DEFAULT_PROPERTIES,
|
|
36
|
+
a as CLICKABLE_ELEMENTS_SELECTOR,
|
|
37
|
+
M as CLICK_EVENT_TYPE,
|
|
38
|
+
D as DEFAULT_CLICK_THROTTLE_MS,
|
|
39
|
+
C as DEFAULT_IMPRESSION_CONFIG,
|
|
40
|
+
T as DEFAULT_IMPRESSION_DWELL_MS,
|
|
41
|
+
n as DEFAULT_IMPRESSION_MAX_NODES,
|
|
42
|
+
A as DEFAULT_IMPRESSION_MUTATION_OBSERVER_DEBOUNCE_MS,
|
|
43
|
+
S as DEFAULT_IMPRESSION_THROTTLE_MS,
|
|
44
|
+
t as DEFAULT_IMPRESSION_VISIBILITY_THRESHOLD,
|
|
45
|
+
O as DEFAULT_QUEUE_CONFIG,
|
|
46
|
+
o as DEFAULT_SESSION_TIMEOUT_MINUTES,
|
|
47
|
+
c as DotCMSPredefinedEventType,
|
|
48
|
+
s as EXPECTED_UTM_KEYS,
|
|
49
|
+
U as IMPRESSION_EVENT_TYPE,
|
|
50
|
+
e as SESSION_STORAGE_KEY,
|
|
51
|
+
N as USER_ID_KEY
|
|
52
|
+
};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Log level type for the DotLogger
|
|
3
|
+
*/
|
|
4
|
+
export type LogLevel = 'debug' | 'info' | 'warn' | 'error';
|
|
5
|
+
/**
|
|
6
|
+
* Log level constants for convenient usage
|
|
7
|
+
*/
|
|
8
|
+
export declare const LOG_LEVELS: {
|
|
9
|
+
readonly DEBUG: "debug";
|
|
10
|
+
readonly INFO: "info";
|
|
11
|
+
readonly WARN: "warn";
|
|
12
|
+
readonly ERROR: "error";
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Custom logger for DotCMS SDK
|
|
16
|
+
* Provides structured logging with context identification and configurable log level filtering
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```typescript
|
|
20
|
+
* const logger = new DotLogger('Analytics', 'Impression', 'info');
|
|
21
|
+
* logger.debug('This will not show'); // Below threshold
|
|
22
|
+
* logger.info('Tracker initialized'); // Shows
|
|
23
|
+
* logger.error('Failed to track'); // Shows
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export declare class DotLogger {
|
|
27
|
+
private readonly packageName;
|
|
28
|
+
private readonly context;
|
|
29
|
+
private readonly minLevel;
|
|
30
|
+
constructor(packageName: string, context: string, minLevel?: LogLevel);
|
|
31
|
+
/**
|
|
32
|
+
* Creates the formatted prefix for log messages
|
|
33
|
+
* Format: [DotCMS PackageName | Context] [LEVEL]
|
|
34
|
+
*/
|
|
35
|
+
private getPrefix;
|
|
36
|
+
/**
|
|
37
|
+
* Checks if a log level should be displayed based on the minimum threshold
|
|
38
|
+
*/
|
|
39
|
+
private shouldLog;
|
|
40
|
+
/**
|
|
41
|
+
* Log a DEBUG level message
|
|
42
|
+
* Used for detailed debugging information
|
|
43
|
+
*/
|
|
44
|
+
debug(...args: unknown[]): void;
|
|
45
|
+
/**
|
|
46
|
+
* Log an INFO level message
|
|
47
|
+
* Used for general informational messages
|
|
48
|
+
*/
|
|
49
|
+
info(...args: unknown[]): void;
|
|
50
|
+
/**
|
|
51
|
+
* Log a WARN level message
|
|
52
|
+
* Used for warning messages that don't prevent operation
|
|
53
|
+
*/
|
|
54
|
+
warn(...args: unknown[]): void;
|
|
55
|
+
/**
|
|
56
|
+
* Log an ERROR level message
|
|
57
|
+
* Always logs regardless of threshold for critical errors
|
|
58
|
+
*/
|
|
59
|
+
error(...args: unknown[]): void;
|
|
60
|
+
/**
|
|
61
|
+
* Create a console group for organizing related log messages
|
|
62
|
+
* Respects the minimum log level threshold
|
|
63
|
+
*/
|
|
64
|
+
group(label: string): void;
|
|
65
|
+
/**
|
|
66
|
+
* End the current console group
|
|
67
|
+
* Respects the minimum log level threshold
|
|
68
|
+
*/
|
|
69
|
+
groupEnd(): void;
|
|
70
|
+
/**
|
|
71
|
+
* Start a timer with the given label
|
|
72
|
+
* Useful for performance measurements
|
|
73
|
+
*/
|
|
74
|
+
time(label: string): void;
|
|
75
|
+
/**
|
|
76
|
+
* End a timer and log the elapsed time
|
|
77
|
+
* Useful for performance measurements
|
|
78
|
+
*/
|
|
79
|
+
timeEnd(label: string): void;
|
|
80
|
+
/**
|
|
81
|
+
* Log a message (alias for info)
|
|
82
|
+
* Provided for backward compatibility
|
|
83
|
+
*/
|
|
84
|
+
log(...args: unknown[]): void;
|
|
85
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
const o = {
|
|
2
|
+
debug: 0,
|
|
3
|
+
info: 1,
|
|
4
|
+
warn: 2,
|
|
5
|
+
error: 3
|
|
6
|
+
};
|
|
7
|
+
class r {
|
|
8
|
+
constructor(e, i, t = "warn") {
|
|
9
|
+
this.packageName = e, this.context = i, this.minLevel = t;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Creates the formatted prefix for log messages
|
|
13
|
+
* Format: [DotCMS PackageName | Context] [LEVEL]
|
|
14
|
+
*/
|
|
15
|
+
getPrefix(e) {
|
|
16
|
+
return `[DotCMS ${this.packageName} | ${this.context}] [${e.toUpperCase()}]`;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Checks if a log level should be displayed based on the minimum threshold
|
|
20
|
+
*/
|
|
21
|
+
shouldLog(e) {
|
|
22
|
+
return o[e] >= o[this.minLevel];
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Log a DEBUG level message
|
|
26
|
+
* Used for detailed debugging information
|
|
27
|
+
*/
|
|
28
|
+
debug(...e) {
|
|
29
|
+
this.shouldLog("debug") && console.log(this.getPrefix("debug"), ...e);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Log an INFO level message
|
|
33
|
+
* Used for general informational messages
|
|
34
|
+
*/
|
|
35
|
+
info(...e) {
|
|
36
|
+
this.shouldLog("info") && console.info(this.getPrefix("info"), ...e);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Log a WARN level message
|
|
40
|
+
* Used for warning messages that don't prevent operation
|
|
41
|
+
*/
|
|
42
|
+
warn(...e) {
|
|
43
|
+
this.shouldLog("warn") && console.warn(this.getPrefix("warn"), ...e);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Log an ERROR level message
|
|
47
|
+
* Always logs regardless of threshold for critical errors
|
|
48
|
+
*/
|
|
49
|
+
error(...e) {
|
|
50
|
+
console.error(this.getPrefix("error"), ...e);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Create a console group for organizing related log messages
|
|
54
|
+
* Respects the minimum log level threshold
|
|
55
|
+
*/
|
|
56
|
+
group(e) {
|
|
57
|
+
this.shouldLog("debug") && console.group(`${this.getPrefix("debug")} ${e}`);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* End the current console group
|
|
61
|
+
* Respects the minimum log level threshold
|
|
62
|
+
*/
|
|
63
|
+
groupEnd() {
|
|
64
|
+
this.shouldLog("debug") && console.groupEnd();
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Start a timer with the given label
|
|
68
|
+
* Useful for performance measurements
|
|
69
|
+
*/
|
|
70
|
+
time(e) {
|
|
71
|
+
this.shouldLog("debug") && console.time(`${this.getPrefix("debug")} ${e}`);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* End a timer and log the elapsed time
|
|
75
|
+
* Useful for performance measurements
|
|
76
|
+
*/
|
|
77
|
+
timeEnd(e) {
|
|
78
|
+
this.shouldLog("debug") && console.timeEnd(`${this.getPrefix("debug")} ${e}`);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Log a message (alias for info)
|
|
82
|
+
* Provided for backward compatibility
|
|
83
|
+
*/
|
|
84
|
+
log(...e) {
|
|
85
|
+
this.info(...e);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
export {
|
|
89
|
+
r as DotLogger
|
|
90
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { DotCMSAnalyticsConfig, DotCMSAnalyticsRequestBody } from '../models';
|
|
2
|
+
/**
|
|
3
|
+
* Send analytics events to the server using fetch API
|
|
4
|
+
* @param payload - The event payload data
|
|
5
|
+
* @param config - The analytics configuration
|
|
6
|
+
* @param keepalive - Use keepalive mode for page unload scenarios (default: false)
|
|
7
|
+
* @returns A promise that resolves when the request is complete
|
|
8
|
+
*/
|
|
9
|
+
export declare const sendAnalyticsEvent: (payload: DotCMSAnalyticsRequestBody, config: DotCMSAnalyticsConfig, keepalive?: boolean) => Promise<void>;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { ANALYTICS_ENDPOINT as f } from "../constants/dot-analytics.constants.js";
|
|
2
|
+
import { createPluginLogger as T } from "../utils/dot-analytics.utils.js";
|
|
3
|
+
const h = async (n, a, i = !1) => {
|
|
4
|
+
const r = T("HTTP", a), c = `${a.server}${f}`, g = JSON.stringify(n);
|
|
5
|
+
r.info(`Sending ${n.events.length} event(s)${i ? " (keepalive)" : ""}`, {
|
|
6
|
+
payload: n
|
|
7
|
+
});
|
|
8
|
+
try {
|
|
9
|
+
const e = {
|
|
10
|
+
method: "POST",
|
|
11
|
+
headers: { "Content-Type": "application/json" },
|
|
12
|
+
body: g
|
|
13
|
+
};
|
|
14
|
+
if (i) {
|
|
15
|
+
e.keepalive = !0, e.credentials = "omit", fetch(c, e);
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const t = await fetch(c, e);
|
|
19
|
+
if (!t.ok) {
|
|
20
|
+
const p = t.statusText || "Unknown Error", o = `HTTP ${t.status}: ${p}`;
|
|
21
|
+
try {
|
|
22
|
+
const s = await t.json();
|
|
23
|
+
s.message ? r.warn(`${s.message} (${o})`) : r.warn(`${o} - No error message in response`);
|
|
24
|
+
} catch (s) {
|
|
25
|
+
r.warn(`${o} - Failed to parse error response:`, s);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
} catch (e) {
|
|
29
|
+
r.error("Error sending event:", e);
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
export {
|
|
33
|
+
h as sendAnalyticsEvent
|
|
34
|
+
};
|
|
@@ -89,7 +89,7 @@ export interface DotCMSEventUtmData {
|
|
|
89
89
|
id?: string;
|
|
90
90
|
}
|
|
91
91
|
/**
|
|
92
|
-
* Page data structure for DotCMS analytics.
|
|
92
|
+
* Page data structure for DotCMS analytics (used in pageview events).
|
|
93
93
|
* Contains comprehensive information about the current page and its context
|
|
94
94
|
* within the DotCMS environment.
|
|
95
95
|
*/
|
|
@@ -101,3 +101,41 @@ export type DotCMSEventPageData = Pick<DotCMSBrowserData, 'url' | 'doc_path' | '
|
|
|
101
101
|
/** Persona identifier */
|
|
102
102
|
persona?: string;
|
|
103
103
|
};
|
|
104
|
+
/**
|
|
105
|
+
* Minimal page data for content impression events.
|
|
106
|
+
* Contains only essential page information (title and url) to keep payload lightweight.
|
|
107
|
+
*/
|
|
108
|
+
export type DotCMSContentImpressionPageData = Pick<DotCMSEventPageData, 'title' | 'url'>;
|
|
109
|
+
/**
|
|
110
|
+
* Data structure for content impression events.
|
|
111
|
+
* Tracks when a contentlet becomes visible in the viewport.
|
|
112
|
+
*/
|
|
113
|
+
export interface DotCMSImpressionEventData {
|
|
114
|
+
/** Contentlet identification data extracted from data-dot-analytics-* attributes */
|
|
115
|
+
contentlet: {
|
|
116
|
+
/** Unique identifier of the contentlet */
|
|
117
|
+
identifier: string;
|
|
118
|
+
/** Inode of the contentlet */
|
|
119
|
+
inode: string;
|
|
120
|
+
/** Content type name */
|
|
121
|
+
contentType: string;
|
|
122
|
+
/** Title of the contentlet */
|
|
123
|
+
title: string;
|
|
124
|
+
/** Base type of the contentlet (e.g., CONTENT, WIDGET) */
|
|
125
|
+
baseType: string;
|
|
126
|
+
};
|
|
127
|
+
/** Viewport position and visibility metrics */
|
|
128
|
+
viewport: {
|
|
129
|
+
/** Percentage offset from top of viewport (0-100) */
|
|
130
|
+
offsetPercentage: number;
|
|
131
|
+
/** Percentage of element visible in viewport (0-1) */
|
|
132
|
+
visibilityRatio: number;
|
|
133
|
+
};
|
|
134
|
+
/** Timing information about the impression */
|
|
135
|
+
timing: {
|
|
136
|
+
/** Time in milliseconds the element was continuously visible */
|
|
137
|
+
dwellTime: number;
|
|
138
|
+
/** ISO 8601 timestamp when the impression was fired */
|
|
139
|
+
timestamp: string;
|
|
140
|
+
};
|
|
141
|
+
}
|