@dotcms/analytics 1.2.0 → 1.2.1-next.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/README.md +314 -9
  2. package/lib/core/dot-analytics.content.js +84 -0
  3. package/lib/core/plugin/click/dot-analytics.click-tracker.d.ts +108 -0
  4. package/lib/core/plugin/click/dot-analytics.click-tracker.js +144 -0
  5. package/lib/core/plugin/click/dot-analytics.click.plugin.d.ts +36 -0
  6. package/lib/core/plugin/click/dot-analytics.click.plugin.js +27 -0
  7. package/lib/core/plugin/click/dot-analytics.click.utils.d.ts +12 -0
  8. package/lib/core/plugin/click/dot-analytics.click.utils.js +55 -0
  9. package/lib/core/plugin/enricher/dot-analytics.enricher.plugin.d.ts +14 -10
  10. package/lib/core/plugin/enricher/dot-analytics.enricher.plugin.js +26 -38
  11. package/lib/core/{shared/dot-content-analytics.activity-tracker.d.ts → plugin/identity/dot-analytics.identity.activity-tracker.d.ts} +2 -17
  12. package/lib/core/{shared/dot-content-analytics.activity-tracker.js → plugin/identity/dot-analytics.identity.activity-tracker.js} +17 -38
  13. package/lib/core/plugin/identity/dot-analytics.identity.plugin.d.ts +2 -20
  14. package/lib/core/plugin/identity/dot-analytics.identity.plugin.js +7 -7
  15. package/lib/core/plugin/identity/dot-analytics.identity.utils.d.ts +0 -16
  16. package/lib/core/plugin/impression/dot-analytics.impression-tracker.d.ts +62 -0
  17. package/lib/core/plugin/impression/dot-analytics.impression-tracker.js +202 -0
  18. package/lib/core/plugin/impression/dot-analytics.impression.plugin.d.ts +40 -0
  19. package/lib/core/plugin/impression/dot-analytics.impression.plugin.js +27 -0
  20. package/lib/core/plugin/impression/dot-analytics.impression.utils.d.ts +26 -0
  21. package/lib/core/plugin/impression/dot-analytics.impression.utils.js +27 -0
  22. package/lib/core/plugin/impression/index.d.ts +2 -0
  23. package/lib/core/plugin/main/dot-analytics.plugin.d.ts +46 -0
  24. package/lib/core/plugin/main/dot-analytics.plugin.js +129 -0
  25. package/lib/core/shared/constants/{dot-content-analytics.constants.d.ts → dot-analytics.constants.d.ts} +62 -0
  26. package/lib/core/shared/constants/dot-analytics.constants.js +53 -0
  27. package/lib/core/shared/constants/index.d.ts +1 -1
  28. package/lib/core/shared/dot-analytics.logger.d.ts +85 -0
  29. package/lib/core/shared/dot-analytics.logger.js +90 -0
  30. package/lib/core/shared/http/dot-analytics.http.d.ts +9 -0
  31. package/lib/core/shared/http/dot-analytics.http.js +34 -0
  32. package/lib/core/shared/models/data.model.d.ts +39 -1
  33. package/lib/core/shared/models/event.model.d.ts +108 -3
  34. package/lib/core/shared/models/library.model.d.ts +89 -28
  35. package/lib/core/shared/models/request.model.d.ts +17 -9
  36. package/lib/core/shared/queue/dot-analytics.queue.utils.js +47 -40
  37. package/lib/core/shared/{dot-content-analytics.utils.d.ts → utils/dot-analytics.utils.d.ts} +91 -3
  38. package/lib/core/shared/utils/dot-analytics.utils.js +200 -0
  39. package/lib/react/hook/useContentAnalytics.js +17 -11
  40. package/lib/react/hook/useRouterTracker.js +12 -12
  41. package/lib/react/internal/utils.js +1 -1
  42. package/package.json +7 -6
  43. package/uve/src/internal/events.js +30 -31
  44. package/uve/src/lib/dom/dom.utils.js +46 -52
  45. package/lib/core/dot-content-analytics.js +0 -46
  46. package/lib/core/plugin/dot-analytics.plugin.d.ts +0 -33
  47. package/lib/core/plugin/dot-analytics.plugin.js +0 -42
  48. package/lib/core/shared/constants/dot-content-analytics.constants.js +0 -34
  49. package/lib/core/shared/dot-content-analytics.http.d.ts +0 -17
  50. package/lib/core/shared/dot-content-analytics.http.js +0 -41
  51. package/lib/core/shared/dot-content-analytics.utils.js +0 -147
  52. /package/lib/core/{dot-content-analytics.d.ts → dot-analytics.content.d.ts} +0 -0
@@ -1,40 +1,51 @@
1
- import p from "@analytics/queue-utils";
2
- import { DEFAULT_QUEUE_CONFIG as c } from "../constants/dot-content-analytics.constants.js";
3
- import { sendAnalyticsEvent as y } from "../dot-content-analytics.http.js";
4
- const z = (n) => {
5
- let e = null, i = null, o = "fetch";
6
- const l = {
7
- ...c,
8
- ...typeof n.queue == "object" ? n.queue : {}
9
- }, f = (t) => {
10
- if (!i) return;
11
- n.debug && console.log(`DotCMS Analytics Queue: Sending batch of ${t.length} event(s)`, {
12
- events: t,
13
- transport: o
14
- }), y({ context: i, events: t }, n, o);
15
- }, u = () => {
16
- !e || e.size() === 0 || !i || (n.debug && console.warn(
17
- `DotCMS Analytics: Flushing ${e.size()} events (page hidden/unload)`
18
- ), o = "beacon", e.flush(!0));
19
- }, d = () => {
20
- document.visibilityState === "hidden" && u();
1
+ import m from "@analytics/queue-utils";
2
+ import v from "@analytics/router-utils";
3
+ import { DEFAULT_QUEUE_CONFIG as y } from "../constants/dot-analytics.constants.js";
4
+ import { sendAnalyticsEvent as b } from "../http/dot-analytics.http.js";
5
+ import { createPluginLogger as w } from "../utils/dot-analytics.utils.js";
6
+ const L = (u) => {
7
+ const i = w("Queue", u);
8
+ let t = null, n = null, o = !1, d = !1, f = typeof window < "u" ? window.location.pathname : "";
9
+ const a = {
10
+ ...y,
11
+ ...typeof u.queue == "object" ? u.queue : {}
12
+ }, g = (e, s) => {
13
+ if (!n) return;
14
+ i.debug(`Sending batch of ${e.length} event(s)`, {
15
+ events: e,
16
+ keepalive: o
17
+ }), b({ context: n, events: e }, u, o);
18
+ }, l = () => {
19
+ !t || t.size() === 0 || !n || (i.info(`Flushing ${t.size()} events (page hidden/unload)`), o = !0, t.flush(!0));
20
+ }, c = () => {
21
+ if (i.debug("handleVisibilityChange", document.visibilityState), document.visibilityState === "hidden") {
22
+ if (d) {
23
+ i.debug("Skipping flush (SPA navigation detected)");
24
+ return;
25
+ }
26
+ l();
27
+ } else document.visibilityState === "visible" && (d = !1);
21
28
  };
22
29
  return {
23
30
  /**
24
31
  * Initialize the queue with smart batching
25
32
  */
26
33
  initialize: () => {
27
- e = p(
28
- (t) => {
29
- f(t);
34
+ t = m(
35
+ (e, s) => {
36
+ g(e);
30
37
  },
31
38
  {
32
- max: l.eventBatchSize,
33
- interval: l.flushInterval,
39
+ max: a.eventBatchSize,
40
+ interval: a.flushInterval,
34
41
  throttle: !1
35
42
  // Always false - enables both batch size and interval triggers
36
43
  }
37
- ), typeof window < "u" && typeof document < "u" && (document.addEventListener("visibilitychange", d), window.addEventListener("pagehide", u));
44
+ ), typeof window < "u" && typeof document < "u" && (document.addEventListener("visibilitychange", c), window.addEventListener("pagehide", l), v((e) => {
45
+ d = !0, f = e, i.debug(`SPA navigation detected (${f})`), setTimeout(() => {
46
+ d = !1;
47
+ }, 100);
48
+ }));
38
49
  },
39
50
  /**
40
51
  * Add event to queue
@@ -42,32 +53,28 @@ const z = (n) => {
42
53
  * - Sends immediately when eventBatchSize reached (with throttle: false)
43
54
  * - Sends pending events every flushInterval
44
55
  */
45
- enqueue: (t, s) => {
46
- if (i = s, !!e) {
47
- if (n.debug) {
48
- const a = e.size() + 1, r = l.eventBatchSize ?? c.eventBatchSize, h = a >= r;
49
- console.log(
50
- `DotCMS Analytics Queue: Event added. Queue size: ${a}/${r}${h ? " (full, sending...)" : ""}`,
51
- { eventType: t.event_type, event: t }
52
- );
53
- }
54
- e.push(t);
55
- }
56
+ enqueue: (e, s) => {
57
+ if (n = s, !t) return;
58
+ const r = t.size() + 1, p = a.eventBatchSize, h = r >= p;
59
+ i.debug(
60
+ `Event added. Queue size: ${r}/${p}${h ? " (full, sending...)" : ""}`,
61
+ { eventType: e.event_type, event: e }
62
+ ), t.push(e);
56
63
  },
57
64
  /**
58
65
  * Get queue size for debugging
59
66
  * Returns the number of events in smartQueue
60
67
  */
61
- size: () => (e == null ? void 0 : e.size()) ?? 0,
68
+ size: () => t?.size() ?? 0,
62
69
  /**
63
70
  * Clean up queue resources
64
71
  * Flushes remaining events and cleans up listeners
65
72
  */
66
73
  cleanup: () => {
67
- u(), typeof window < "u" && typeof document < "u" && (document.removeEventListener("visibilitychange", d), window.removeEventListener("pagehide", u)), e = null, i = null, o = "fetch";
74
+ l(), typeof window < "u" && typeof document < "u" && (document.removeEventListener("visibilitychange", c), window.removeEventListener("pagehide", l)), t = null, n = null, o = !1;
68
75
  }
69
76
  };
70
77
  };
71
78
  export {
72
- z as createAnalyticsQueue
79
+ L as createAnalyticsQueue
73
80
  };
@@ -1,6 +1,27 @@
1
- import { PageData } from 'analytics';
2
- import { AnalyticsBasePayloadWithContext, DotCMSAnalyticsConfig, DotCMSAnalyticsEventContext, DotCMSBrowserData, DotCMSEventDeviceData, DotCMSEventUtmData, EnrichedAnalyticsPayload } from './models';
3
- export { cleanupActivityTracking, getLastActivity, getSessionInfo, initializeActivityTracking, isUserInactive, updateSessionActivity } from './dot-content-analytics.activity-tracker';
1
+ import { AnalyticsPlugin, PageData } from 'analytics';
2
+ import { DotCMSPredefinedEventType } from '../constants';
3
+ import { DotLogger, LogLevel } from '../dot-analytics.logger';
4
+ import { AnalyticsBasePayloadWithContext, ContentletData, DotCMSAnalyticsConfig, DotCMSAnalyticsEventContext, DotCMSBrowserData, DotCMSEventDeviceData, DotCMSEventUtmData, EnrichedAnalyticsPayload } from '../models';
5
+ export { cleanupActivityTracking, initializeActivityTracking, updateSessionActivity } from '../../plugin/identity/dot-analytics.identity.activity-tracker';
6
+ /**
7
+ * Type guard to check if an event is a predefined event type.
8
+ * Enables TypeScript type narrowing for better type safety.
9
+ *
10
+ * @param event - Event name to check
11
+ * @returns True if event is a predefined type, false for custom events
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * if (isPredefinedEventType(eventName)) {
16
+ * // TypeScript knows eventName is DotCMSPredefinedEventType here
17
+ * console.log('Predefined event:', eventName);
18
+ * } else {
19
+ * // TypeScript knows eventName is string (custom) here
20
+ * console.log('Custom event:', eventName);
21
+ * }
22
+ * ```
23
+ */
24
+ export declare function isPredefinedEventType(event: string): event is DotCMSPredefinedEventType;
4
25
  /**
5
26
  * Validates required configuration fields for Analytics initialization.
6
27
  *
@@ -170,3 +191,70 @@ export declare const enrichPagePayload: (payload: {
170
191
  properties: Record<string, unknown>;
171
192
  };
172
193
  };
194
+ /**
195
+ * Creates a throttled version of a callback function
196
+ * Ensures the callback is executed at most once every `limitMs` milliseconds
197
+ * @param callback - The function to throttle
198
+ * @param limitMs - The time limit in milliseconds
199
+ * @returns A throttled function
200
+ */
201
+ export declare function createThrottle<T extends (...args: unknown[]) => void>(callback: T, limitMs: number): (...args: Parameters<T>) => void;
202
+ /**
203
+ * Extracts the contentlet identifier from a DOM element
204
+ * @param element - The HTML element containing data attributes
205
+ * @returns The contentlet identifier or null if not found
206
+ */
207
+ export declare function extractContentletIdentifier(element: HTMLElement): string | null;
208
+ /**
209
+ * Extracts all contentlet data from a DOM element's data attributes
210
+ * @param element - The HTML element containing data attributes
211
+ * @returns Complete contentlet data object
212
+ */
213
+ export declare function extractContentletData(element: HTMLElement): ContentletData;
214
+ /**
215
+ * Initial scan delay for DOM readiness
216
+ * Allows React/Next.js to finish rendering before scanning for contentlets
217
+ */
218
+ export declare const INITIAL_SCAN_DELAY_MS = 100;
219
+ /**
220
+ * Checks if code is running in a browser environment
221
+ * @returns true if window and document are available
222
+ */
223
+ export declare const isBrowser: () => boolean;
224
+ /**
225
+ * Finds all contentlet elements in the DOM
226
+ * @returns Array of contentlet HTMLElements
227
+ */
228
+ export declare const findContentlets: () => HTMLElement[];
229
+ /**
230
+ * Creates a MutationObserver that watches for contentlet changes in the DOM
231
+ * @param callback - Function to call when mutations are detected
232
+ * @param debounceMs - Debounce time in milliseconds (default: 250ms)
233
+ * @returns Configured and active MutationObserver
234
+ */
235
+ export declare const createContentletObserver: (callback: () => void, debounceMs?: number) => MutationObserver;
236
+ /**
237
+ * Sets up cleanup handlers for page unload events
238
+ * Registers cleanup function to both 'beforeunload' and 'pagehide' for maximum compatibility
239
+ * @param cleanup - Function to call on page unload
240
+ */
241
+ export declare const setupPluginCleanup: (cleanup: () => void) => void;
242
+ /**
243
+ * Creates a logger with plugin-specific prefix and configurable log level
244
+ * @param pluginName - Name of the plugin (e.g., 'Click', 'Impression')
245
+ * @param config - Analytics configuration with debug flag and optional logLevel
246
+ * @returns DotLogger instance with configured log level
247
+ */
248
+ export declare const createPluginLogger: (pluginName: string, config: {
249
+ debug: boolean;
250
+ logLevel?: LogLevel;
251
+ }) => DotLogger;
252
+ /**
253
+ * Gets enhanced tracking plugins based on configuration
254
+ * Returns content impression and click tracking plugins if enabled
255
+ * @param config - Analytics configuration
256
+ * @param impressionPlugin - Impression tracking plugin factory
257
+ * @param clickPlugin - Click tracking plugin factory
258
+ * @returns Array of enabled tracking plugins
259
+ */
260
+ export declare const getEnhancedTrackingPlugins: (config: DotCMSAnalyticsConfig, impressionPlugin: (config: DotCMSAnalyticsConfig) => AnalyticsPlugin, clickPlugin: (config: DotCMSAnalyticsConfig) => AnalyticsPlugin) => AnalyticsPlugin[];
@@ -0,0 +1,200 @@
1
+ import { ANALYTICS_JS_DEFAULT_PROPERTIES as _, SESSION_STORAGE_KEY as g, DEFAULT_SESSION_TIMEOUT_MINUTES as p, USER_ID_KEY as m, DEFAULT_IMPRESSION_MUTATION_OBSERVER_DEBOUNCE_MS as T, EXPECTED_UTM_KEYS as y, ANALYTICS_CONTENTLET_CLASS as h } from "../constants/dot-analytics.constants.js";
2
+ import { DotLogger as I } from "../dot-analytics.logger.js";
3
+ import "../../../../uve/src/internal/constants.js";
4
+ function P(t) {
5
+ const e = [];
6
+ return t.siteAuth?.trim() || e.push('"siteAuth"'), t.server?.trim() || e.push('"server"'), e.length > 0 ? e : null;
7
+ }
8
+ let d = null, u = null;
9
+ const l = (t) => {
10
+ const e = Date.now(), n = Math.random().toString(36).substr(2, 9), s = Math.random().toString(36).substr(2, 9);
11
+ return `${t}_${e}_${n}${s}`;
12
+ }, f = {
13
+ getItem: (t) => {
14
+ try {
15
+ return localStorage.getItem(t);
16
+ } catch {
17
+ return null;
18
+ }
19
+ },
20
+ setItem: (t, e) => {
21
+ try {
22
+ localStorage.setItem(t, e);
23
+ } catch {
24
+ console.warn(`DotCMS Analytics [Core]: Could not save ${t} to localStorage`);
25
+ }
26
+ }
27
+ }, D = () => {
28
+ let t = f.getItem(m);
29
+ return t || (t = l("user"), f.setItem(m, t)), t;
30
+ }, E = (t) => {
31
+ const e = new Date(t), n = /* @__PURE__ */ new Date(), s = new Date(
32
+ e.getUTCFullYear(),
33
+ e.getUTCMonth(),
34
+ e.getUTCDate()
35
+ ), r = new Date(n.getUTCFullYear(), n.getUTCMonth(), n.getUTCDate());
36
+ return s.getTime() !== r.getTime();
37
+ }, A = () => {
38
+ const t = Date.now();
39
+ if (typeof window > "u")
40
+ return l("session_fallback");
41
+ try {
42
+ const e = sessionStorage.getItem(g);
43
+ if (e) {
44
+ const { sessionId: r, startTime: o, lastActivity: a } = JSON.parse(e), i = !E(o), c = t - a < p * 60 * 1e3;
45
+ if (i && c)
46
+ return sessionStorage.setItem(
47
+ g,
48
+ JSON.stringify({
49
+ sessionId: r,
50
+ startTime: o,
51
+ lastActivity: t
52
+ })
53
+ ), r;
54
+ }
55
+ const n = l("session"), s = {
56
+ sessionId: n,
57
+ startTime: t,
58
+ lastActivity: t
59
+ };
60
+ return sessionStorage.setItem(g, JSON.stringify(s)), n;
61
+ } catch {
62
+ return l("session_fallback");
63
+ }
64
+ }, R = (t) => {
65
+ const e = A(), n = D(), s = C();
66
+ return {
67
+ site_auth: t.siteAuth,
68
+ session_id: e,
69
+ user_id: n,
70
+ device: s
71
+ };
72
+ }, w = () => d || (d = {
73
+ user_language: navigator.language,
74
+ doc_encoding: document.characterSet || document.charset,
75
+ screen_resolution: typeof screen < "u" && screen.width && screen.height ? `${screen.width}x${screen.height}` : ""
76
+ }, d), C = () => {
77
+ const t = w(), e = window.innerWidth || document.documentElement.clientWidth || 0, n = window.innerHeight || document.documentElement.clientHeight || 0;
78
+ return {
79
+ screen_resolution: t.screen_resolution ?? "",
80
+ language: t.user_language ?? "",
81
+ viewport_width: String(e),
82
+ viewport_height: String(n)
83
+ };
84
+ }, v = (t) => {
85
+ const e = t.search;
86
+ if (u && u.search === e)
87
+ return u.params;
88
+ const n = new URLSearchParams(e), s = {};
89
+ return y.forEach((r) => {
90
+ const o = n.get(r);
91
+ if (o) {
92
+ const a = r.replace("utm_", "");
93
+ s[a] = o;
94
+ }
95
+ }), u = { search: e, params: s }, s;
96
+ }, O = () => {
97
+ try {
98
+ const t = (/* @__PURE__ */ new Date()).getTimezoneOffset(), e = t > 0 ? "-" : "+", n = Math.abs(t), s = Math.floor(n / 60), r = n % 60;
99
+ return `${e}${s.toString().padStart(2, "0")}:${r.toString().padStart(2, "0")}`;
100
+ } catch {
101
+ return "+00:00";
102
+ }
103
+ }, N = () => {
104
+ try {
105
+ const t = /* @__PURE__ */ new Date(), e = O(), n = t.getFullYear(), s = (t.getMonth() + 1).toString().padStart(2, "0"), r = t.getDate().toString().padStart(2, "0"), o = t.getHours().toString().padStart(2, "0"), a = t.getMinutes().toString().padStart(2, "0"), i = t.getSeconds().toString().padStart(2, "0");
106
+ return `${n}-${s}-${r}T${o}:${a}:${i}${e}`;
107
+ } catch {
108
+ return (/* @__PURE__ */ new Date()).toISOString();
109
+ }
110
+ }, Y = (t, e = typeof window < "u" ? window.location : {}) => {
111
+ const n = N(), s = w(), { properties: r } = t, o = {};
112
+ Object.keys(r).forEach((c) => {
113
+ _.includes(c) || (o[c] = r[c]);
114
+ });
115
+ const a = {
116
+ url: e.href,
117
+ doc_encoding: s.doc_encoding,
118
+ doc_hash: e.hash,
119
+ doc_protocol: e.protocol,
120
+ doc_search: e.search,
121
+ doc_host: e.hostname,
122
+ doc_path: e.pathname,
123
+ title: r.title ?? document?.title
124
+ }, i = v(e);
125
+ return {
126
+ ...t,
127
+ page: a,
128
+ ...Object.keys(i).length > 0 && { utm: i },
129
+ // Only include custom if there are user-provided properties
130
+ ...Object.keys(o).length > 0 && { custom: o },
131
+ local_time: n
132
+ };
133
+ };
134
+ function b(t, e) {
135
+ let n = 0;
136
+ return (...s) => {
137
+ const r = Date.now();
138
+ r - n >= e && (t(...s), n = r);
139
+ };
140
+ }
141
+ function x(t) {
142
+ return t.dataset.dotAnalyticsIdentifier || null;
143
+ }
144
+ function B(t) {
145
+ return {
146
+ identifier: t.dataset.dotAnalyticsIdentifier || "",
147
+ inode: t.dataset.dotAnalyticsInode || "",
148
+ contentType: t.dataset.dotAnalyticsContenttype || "",
149
+ title: t.dataset.dotAnalyticsTitle || "",
150
+ baseType: t.dataset.dotAnalyticsBasetype || ""
151
+ };
152
+ }
153
+ const F = 100, M = () => typeof window < "u" && typeof document < "u", k = () => Array.from(document.querySelectorAll(`.${h}`)), z = (t, e = T) => {
154
+ const n = b(t, e), s = new MutationObserver((r) => {
155
+ r.some((a) => a.addedNodes.length === 0 && a.removedNodes.length === 0 ? !1 : [
156
+ ...Array.from(a.addedNodes),
157
+ ...Array.from(a.removedNodes)
158
+ ].some((c) => {
159
+ if (c.nodeType !== Node.ELEMENT_NODE)
160
+ return !1;
161
+ const S = c;
162
+ return S.classList?.contains(h) ? !0 : S.querySelector?.(`.${h}`) !== null;
163
+ })) && n();
164
+ });
165
+ return s.observe(document.body, {
166
+ childList: !0,
167
+ subtree: !0,
168
+ attributes: !1,
169
+ characterData: !1
170
+ }), s;
171
+ }, H = (t) => {
172
+ M() && (window.addEventListener("beforeunload", t), window.addEventListener("pagehide", t));
173
+ }, J = (t, e) => {
174
+ const n = e.logLevel ?? (e.debug ? "debug" : "warn");
175
+ return new I("Analytics", t, n);
176
+ }, K = (t, e, n) => [
177
+ t.impressions && e(t),
178
+ t.clicks && n(t)
179
+ ].filter(Boolean);
180
+ export {
181
+ F as INITIAL_SCAN_DELAY_MS,
182
+ z as createContentletObserver,
183
+ J as createPluginLogger,
184
+ b as createThrottle,
185
+ Y as enrichPagePayloadOptimized,
186
+ B as extractContentletData,
187
+ x as extractContentletIdentifier,
188
+ v as extractUTMParameters,
189
+ k as findContentlets,
190
+ l as generateSecureId,
191
+ R as getAnalyticsContext,
192
+ C as getDeviceDataForContext,
193
+ K as getEnhancedTrackingPlugins,
194
+ N as getLocalTime,
195
+ A as getSessionId,
196
+ D as getUserId,
197
+ M as isBrowser,
198
+ H as setupPluginCleanup,
199
+ P as validateAnalyticsConfig
200
+ };
@@ -1,27 +1,33 @@
1
- import { useMemo as n, useCallback as o } from "react";
2
- import { getUVEState as u } from "../../../uve/src/lib/core/core.utils.js";
1
+ import { useMemo as s, useCallback as o } from "react";
2
+ import { getUVEState as l } from "../../../uve/src/lib/core/core.utils.js";
3
3
  import "../../../uve/src/internal/constants.js";
4
- import { initializeAnalytics as l } from "../internal/utils.js";
5
- const h = (r) => {
6
- const t = n(() => l(r), [r.server, r.siteAuth]), e = n(() => !!u(), []);
4
+ import { initializeAnalytics as m } from "../internal/utils.js";
5
+ const h = (i) => {
6
+ const t = s(() => m(i), [i.server, i.siteAuth]), e = s(() => !!l(), []);
7
7
  if (!t)
8
8
  throw new Error(
9
9
  "DotCMS Analytics: Failed to initialize. Please verify the required configuration (server and siteAuth)."
10
10
  );
11
11
  const a = o(
12
- (i, c = {}) => {
13
- e || t.track(i, c);
12
+ (r, n = {}) => {
13
+ e || t.track(r, n);
14
14
  },
15
15
  [t, e]
16
- ), s = o(
17
- (i = {}) => {
18
- e || t.pageView(i);
16
+ ), c = o(
17
+ (r = {}) => {
18
+ e || t.pageView(r);
19
+ },
20
+ [t, e]
21
+ ), u = o(
22
+ (r, n = {}) => {
23
+ e || t.conversion(r, n);
19
24
  },
20
25
  [t, e]
21
26
  );
22
27
  return {
23
28
  track: a,
24
- pageView: s
29
+ pageView: c,
30
+ conversion: u
25
31
  };
26
32
  };
27
33
  export {
@@ -1,18 +1,18 @@
1
- import { usePathname as u, useSearchParams as p } from "next/navigation";
2
- import { useRef as c, useEffect as m } from "react";
3
- import { getUVEState as s } from "../../../uve/src/lib/core/core.utils.js";
1
+ import { usePathname as s, useSearchParams as u } from "next/navigation";
2
+ import { useRef as c, useEffect as a } from "react";
3
+ import { getUVEState as m } from "../../../uve/src/lib/core/core.utils.js";
4
4
  import "../../../uve/src/internal/constants.js";
5
- const g = (e, t) => `${e}${t != null && t.toString() ? "?" + t.toString() : ""}`;
6
- function A(e, t = !1) {
7
- const o = c(null), n = u(), r = p();
8
- m(() => {
9
- if (!e) return;
5
+ const p = (t, e) => `${t}${e?.toString() ? "?" + e.toString() : ""}`;
6
+ function l(t, e = !1) {
7
+ const r = c(null), o = s(), n = u();
8
+ a(() => {
9
+ if (!t) return;
10
10
  const i = (f) => {
11
- s() || f !== o.current && (o.current = f, e.pageView());
11
+ m() || f !== r.current && (r.current = f, t.pageView());
12
12
  };
13
- t && console.info("DotContentAnalytics: using Next.js App Router tracking"), i(g(n, r));
14
- }, [e, n, r, t]);
13
+ e && console.info("DotCMS Analytics [React]: using Next.js App Router tracking"), i(p(o, n));
14
+ }, [t, o, n, e]);
15
15
  }
16
16
  export {
17
- A as useRouterTracker
17
+ l as useRouterTracker
18
18
  };
@@ -1,4 +1,4 @@
1
- import { initializeContentAnalytics as r } from "../../core/dot-content-analytics.js";
1
+ import { initializeContentAnalytics as r } from "../../core/dot-analytics.content.js";
2
2
  let t, i;
3
3
  const s = (e) => (i && (i.server !== e.server || i.siteAuth !== e.siteAuth) && (t = void 0), t !== void 0 || (i = e, t = r(e)), t);
4
4
  export {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dotcms/analytics",
3
- "version": "1.2.0",
3
+ "version": "1.2.1-next.2",
4
4
  "description": "Official JavaScript library for Content Analytics with DotCMS.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -20,20 +20,21 @@
20
20
  },
21
21
  "homepage": "https://github.com/dotCMS/core/tree/main/core-web/libs/sdk/analytics/README.md",
22
22
  "dependencies": {
23
- "analytics": "^0.8.0",
24
23
  "@analytics/core": "^0.13.0",
25
- "@analytics/storage-utils": "^0.4.0",
26
24
  "@analytics/queue-utils": "^0.1.3",
27
- "@dotcms/uve": "latest"
25
+ "@analytics/router-utils": "^0.1.1",
26
+ "@analytics/storage-utils": "^0.4.0",
27
+ "@dotcms/uve": "latest",
28
+ "analytics": "^0.8.0"
28
29
  },
29
30
  "peerDependencies": {
30
31
  "react": "^18 || ^19"
31
32
  },
32
33
  "devDependencies": {
34
+ "@dotcms/types": "latest",
33
35
  "@testing-library/jest-dom": "^6.1.6",
34
36
  "@testing-library/react": "^14.0.0",
35
- "vite": "~5.0.0",
36
- "@dotcms/types": "latest"
37
+ "vite": "~5.0.0"
37
38
  },
38
39
  "main": "./index.js",
39
40
  "module": "./index.js",
@@ -1,7 +1,7 @@
1
1
  import { UVEEventType as a } from "../../../types/src/lib/editor/public.js";
2
2
  import { __DOTCMS_UVE_EVENT__ as s } from "../../../types/src/lib/events/internal.js";
3
- import { findDotCMSElement as M, findDotCMSVTLData as p, getClosestDotCMSContainerData as w, getDotCMSPageBounds as S } from "../lib/dom/dom.utils.js";
4
- function U(o) {
3
+ import { findDotCMSElement as u, findDotCMSVTLData as C, getClosestDotCMSContainerData as g, getDotCMSPageBounds as v } from "../lib/dom/dom.utils.js";
4
+ function O(o) {
5
5
  const t = (n) => {
6
6
  n.data.name === s.UVE_SET_PAGE_DATA && o(n.data.payload);
7
7
  };
@@ -12,7 +12,7 @@ function U(o) {
12
12
  event: a.CONTENT_CHANGES
13
13
  };
14
14
  }
15
- function V(o) {
15
+ function b(o) {
16
16
  const t = (n) => {
17
17
  n.data.name === s.UVE_RELOAD_PAGE && o();
18
18
  };
@@ -23,12 +23,12 @@ function V(o) {
23
23
  event: a.PAGE_RELOAD
24
24
  };
25
25
  }
26
- function I(o) {
26
+ function M(o) {
27
27
  const t = (n) => {
28
28
  if (n.data.name === s.UVE_REQUEST_BOUNDS) {
29
29
  const e = Array.from(
30
30
  document.querySelectorAll('[data-dot-object="container"]')
31
- ), i = S(e);
31
+ ), i = v(e);
32
32
  o(i);
33
33
  }
34
34
  };
@@ -39,7 +39,7 @@ function I(o) {
39
39
  event: a.REQUEST_BOUNDS
40
40
  };
41
41
  }
42
- function Y(o) {
42
+ function p(o) {
43
43
  const t = (n) => {
44
44
  if (n.data.name === s.UVE_SCROLL_INSIDE_IFRAME) {
45
45
  const e = n.data.direction;
@@ -53,12 +53,11 @@ function Y(o) {
53
53
  event: a.IFRAME_SCROLL
54
54
  };
55
55
  }
56
- function B(o) {
56
+ function w(o) {
57
57
  const t = (n) => {
58
- var d, r, E, c, T, l, m, _, u, C;
59
- const e = M(n.target);
58
+ const e = u(n.target);
60
59
  if (!e) return;
61
- const { x: i, y: g, width: v, height: N } = e.getBoundingClientRect(), f = ((d = e.dataset) == null ? void 0 : d.dotObject) === "container", L = {
60
+ const { x: i, y: d, width: r, height: E } = e.getBoundingClientRect(), c = e.dataset?.dotObject === "container", T = {
62
61
  identifier: "TEMP_EMPTY_CONTENTLET",
63
62
  title: "TEMP_EMPTY_CONTENTLET",
64
63
  contentType: "TEMP_EMPTY_CONTENTLET_TYPE",
@@ -66,29 +65,29 @@ function B(o) {
66
65
  widgetTitle: "TEMP_EMPTY_CONTENTLET",
67
66
  baseType: "TEMP_EMPTY_CONTENTLET",
68
67
  onNumberOfPages: 1
69
- }, P = {
70
- identifier: (r = e.dataset) == null ? void 0 : r.dotIdentifier,
71
- title: (E = e.dataset) == null ? void 0 : E.dotTitle,
72
- inode: (c = e.dataset) == null ? void 0 : c.dotInode,
73
- contentType: (T = e.dataset) == null ? void 0 : T.dotType,
74
- baseType: (l = e.dataset) == null ? void 0 : l.dotBasetype,
75
- widgetTitle: (m = e.dataset) == null ? void 0 : m.dotWidgetTitle,
76
- onNumberOfPages: (_ = e.dataset) == null ? void 0 : _.dotOnNumberOfPages
77
- }, O = p(e), b = {
68
+ }, l = {
69
+ identifier: e.dataset?.dotIdentifier,
70
+ title: e.dataset?.dotTitle,
71
+ inode: e.dataset?.dotInode,
72
+ contentType: e.dataset?.dotType,
73
+ baseType: e.dataset?.dotBasetype,
74
+ widgetTitle: e.dataset?.dotWidgetTitle,
75
+ onNumberOfPages: e.dataset?.dotOnNumberOfPages
76
+ }, m = C(e), _ = {
78
77
  container: (
79
78
  // Here extract dot-container from contentlet if it is Headless
80
79
  // or search in parent container if it is VTL
81
- (u = e.dataset) != null && u.dotContainer ? JSON.parse((C = e.dataset) == null ? void 0 : C.dotContainer) : w(e)
80
+ e.dataset?.dotContainer ? JSON.parse(e.dataset?.dotContainer) : g(e)
82
81
  ),
83
- contentlet: f ? L : P,
84
- vtlFiles: O
82
+ contentlet: c ? T : l,
83
+ vtlFiles: m
85
84
  };
86
85
  o({
87
86
  x: i,
88
- y: g,
89
- width: v,
90
- height: N,
91
- payload: b
87
+ y: d,
88
+ width: r,
89
+ height: E,
90
+ payload: _
92
91
  });
93
92
  };
94
93
  return document.addEventListener("pointermove", t), {
@@ -99,9 +98,9 @@ function B(o) {
99
98
  };
100
99
  }
101
100
  export {
102
- U as onContentChanges,
103
- B as onContentletHovered,
104
- Y as onIframeScroll,
105
- V as onPageReload,
106
- I as onRequestBounds
101
+ O as onContentChanges,
102
+ w as onContentletHovered,
103
+ p as onIframeScroll,
104
+ b as onPageReload,
105
+ M as onRequestBounds
107
106
  };