@dotcms/analytics 0.0.1-beta.9 → 1.0.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/README.md +167 -100
- package/lib/dotAnalytics/dot-content-analytics.d.ts +5 -5
- package/lib/dotAnalytics/dot-content-analytics.js +28 -9
- package/lib/dotAnalytics/plugin/dot-analytics.plugin.d.ts +9 -7
- package/lib/dotAnalytics/plugin/dot-analytics.plugin.js +55 -31
- package/lib/dotAnalytics/plugin/enricher/dot-analytics.enricher.plugin.d.ts +45 -0
- package/lib/dotAnalytics/plugin/enricher/dot-analytics.enricher.plugin.js +34 -0
- package/lib/dotAnalytics/plugin/identity/dot-analytics.identity.plugin.d.ts +80 -0
- package/lib/dotAnalytics/plugin/identity/dot-analytics.identity.plugin.js +40 -0
- package/lib/dotAnalytics/plugin/identity/dot-analytics.identity.utils.d.ts +24 -0
- package/lib/dotAnalytics/shared/dot-content-analytics.activity-tracker.d.ts +29 -0
- package/lib/dotAnalytics/shared/dot-content-analytics.activity-tracker.js +86 -0
- package/lib/dotAnalytics/shared/dot-content-analytics.constants.d.ts +28 -8
- package/lib/dotAnalytics/shared/dot-content-analytics.constants.js +12 -8
- package/lib/dotAnalytics/shared/dot-content-analytics.http.d.ts +5 -5
- package/lib/dotAnalytics/shared/dot-content-analytics.http.js +19 -12
- package/lib/dotAnalytics/shared/dot-content-analytics.model.d.ts +303 -88
- package/lib/dotAnalytics/shared/dot-content-analytics.utils.d.ts +86 -29
- package/lib/dotAnalytics/shared/dot-content-analytics.utils.js +118 -41
- package/lib/react/components/DotContentAnalyticsProvider.d.ts +4 -4
- package/lib/react/components/DotContentAnalyticsProvider.js +5 -2
- package/lib/react/contexts/DotContentAnalyticsContext.d.ts +3 -3
- package/lib/react/hook/useContentAnalytics.d.ts +36 -6
- package/lib/react/hook/useContentAnalytics.js +22 -24
- package/lib/react/hook/useRouterTracker.d.ts +3 -3
- package/lib/react/hook/useRouterTracker.js +8 -7
- package/lib/standalone.d.ts +2 -2
- package/package.json +5 -4
- package/types/src/lib/editor/public.js +5 -0
- package/types/src/lib/events/internal.js +4 -0
- package/uve/src/internal/constants.js +3 -0
- package/uve/src/internal/events.js +108 -0
- package/uve/src/lib/core/core.utils.js +21 -0
- package/uve/src/lib/dom/dom.utils.js +81 -0
- package/lib/dotAnalytics/plugin/dot-analytics.enricher.plugin.d.ts +0 -31
- package/lib/dotAnalytics/plugin/dot-analytics.enricher.plugin.js +0 -28
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { DotCMSAnalyticsConfig, DotCMSAnalyticsHookParams } from '../../shared/dot-content-analytics.model';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Identity Plugin for DotAnalytics
|
|
5
|
+
* Handles user ID generation, session management, and activity tracking.
|
|
6
|
+
* This plugin provides consistent identity context across all analytics events.
|
|
7
|
+
*
|
|
8
|
+
* Plugin execution order:
|
|
9
|
+
* 1. Identity Plugin (this) - Injects context
|
|
10
|
+
* 2. Enricher Plugin - Adds page/device/utm data
|
|
11
|
+
* 3. Main Plugin - Sends to server
|
|
12
|
+
*
|
|
13
|
+
* @param {DotCMSAnalyticsConfig} config - Configuration object containing server URL, site key, and debug settings
|
|
14
|
+
* @returns {Object} Plugin object with methods for initialization and event processing
|
|
15
|
+
*/
|
|
16
|
+
export declare const dotAnalyticsIdentityPlugin: (config: DotCMSAnalyticsConfig) => {
|
|
17
|
+
name: string;
|
|
18
|
+
/**
|
|
19
|
+
* Initialize the identity plugin
|
|
20
|
+
* Sets up activity tracking for session management
|
|
21
|
+
*/
|
|
22
|
+
initialize: () => Promise<void>;
|
|
23
|
+
/**
|
|
24
|
+
* Inject identity context into page events
|
|
25
|
+
* This runs BEFORE the enricher plugin
|
|
26
|
+
*/
|
|
27
|
+
pageStart: ({ payload }: DotCMSAnalyticsHookParams) => {
|
|
28
|
+
context: import('../../shared/dot-content-analytics.model').DotCMSAnalyticsContext;
|
|
29
|
+
type: string;
|
|
30
|
+
properties: {
|
|
31
|
+
title: string;
|
|
32
|
+
url: string;
|
|
33
|
+
path: string;
|
|
34
|
+
hash: string;
|
|
35
|
+
search: string;
|
|
36
|
+
width: number;
|
|
37
|
+
height: number;
|
|
38
|
+
referrer?: string | undefined;
|
|
39
|
+
};
|
|
40
|
+
options: Record<string, unknown>;
|
|
41
|
+
userId: string | null;
|
|
42
|
+
anonymousId: string;
|
|
43
|
+
meta: {
|
|
44
|
+
rid: string;
|
|
45
|
+
ts: number;
|
|
46
|
+
hasCallback: boolean;
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Inject identity context into track events
|
|
51
|
+
* This runs BEFORE the enricher plugin
|
|
52
|
+
*/
|
|
53
|
+
trackStart: ({ payload }: DotCMSAnalyticsHookParams) => {
|
|
54
|
+
context: import('../../shared/dot-content-analytics.model').DotCMSAnalyticsContext;
|
|
55
|
+
type: string;
|
|
56
|
+
properties: {
|
|
57
|
+
title: string;
|
|
58
|
+
url: string;
|
|
59
|
+
path: string;
|
|
60
|
+
hash: string;
|
|
61
|
+
search: string;
|
|
62
|
+
width: number;
|
|
63
|
+
height: number;
|
|
64
|
+
referrer?: string | undefined;
|
|
65
|
+
};
|
|
66
|
+
options: Record<string, unknown>;
|
|
67
|
+
userId: string | null;
|
|
68
|
+
anonymousId: string;
|
|
69
|
+
meta: {
|
|
70
|
+
rid: string;
|
|
71
|
+
ts: number;
|
|
72
|
+
hasCallback: boolean;
|
|
73
|
+
};
|
|
74
|
+
};
|
|
75
|
+
/**
|
|
76
|
+
* Clean up on plugin unload
|
|
77
|
+
* Sets up cleanup handlers for activity tracking
|
|
78
|
+
*/
|
|
79
|
+
loaded: () => boolean;
|
|
80
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { getAnalyticsContext as i } from "../../shared/dot-content-analytics.utils.js";
|
|
2
|
+
import { cleanupActivityTracking as r, initializeActivityTracking as o } from "../../shared/dot-content-analytics.activity-tracker.js";
|
|
3
|
+
const c = (t) => ({
|
|
4
|
+
name: "dot-analytics-identity",
|
|
5
|
+
/**
|
|
6
|
+
* Initialize the identity plugin
|
|
7
|
+
* Sets up activity tracking for session management
|
|
8
|
+
*/
|
|
9
|
+
initialize: () => (o(t), Promise.resolve()),
|
|
10
|
+
/**
|
|
11
|
+
* Inject identity context into page events
|
|
12
|
+
* This runs BEFORE the enricher plugin
|
|
13
|
+
*/
|
|
14
|
+
pageStart: ({ payload: e }) => {
|
|
15
|
+
const n = i(t);
|
|
16
|
+
return {
|
|
17
|
+
...e,
|
|
18
|
+
context: n
|
|
19
|
+
};
|
|
20
|
+
},
|
|
21
|
+
/**
|
|
22
|
+
* Inject identity context into track events
|
|
23
|
+
* This runs BEFORE the enricher plugin
|
|
24
|
+
*/
|
|
25
|
+
trackStart: ({ payload: e }) => {
|
|
26
|
+
const n = i(t);
|
|
27
|
+
return {
|
|
28
|
+
...e,
|
|
29
|
+
context: n
|
|
30
|
+
};
|
|
31
|
+
},
|
|
32
|
+
/**
|
|
33
|
+
* Clean up on plugin unload
|
|
34
|
+
* Sets up cleanup handlers for activity tracking
|
|
35
|
+
*/
|
|
36
|
+
loaded: () => (typeof window < "u" && (window.addEventListener("beforeunload", r), window.addEventListener("pagehide", r)), !0)
|
|
37
|
+
});
|
|
38
|
+
export {
|
|
39
|
+
c as dotAnalyticsIdentityPlugin
|
|
40
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Updates activity timestamp
|
|
3
|
+
*/
|
|
4
|
+
export declare const updateActivityTime: () => void;
|
|
5
|
+
/**
|
|
6
|
+
* Checks if user has been inactive
|
|
7
|
+
*/
|
|
8
|
+
export declare const isUserInactive: () => boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Checks if a new day has started since session creation
|
|
11
|
+
*/
|
|
12
|
+
export declare const hasPassedMidnight: (sessionStartTime: number) => boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Gets the last activity time
|
|
15
|
+
*/
|
|
16
|
+
export declare const getLastActivityTime: () => number;
|
|
17
|
+
/**
|
|
18
|
+
* Extracts UTM parameters from current location
|
|
19
|
+
*/
|
|
20
|
+
export declare const extractUTMParameters: () => Record<string, string>;
|
|
21
|
+
/**
|
|
22
|
+
* Compares UTM parameters to detect campaign changes
|
|
23
|
+
*/
|
|
24
|
+
export declare const hasUTMChanged: (currentUTM: Record<string, string>) => boolean;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { DotCMSAnalyticsConfig } from './dot-content-analytics.model';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Updates session activity with throttling
|
|
5
|
+
*/
|
|
6
|
+
export declare const updateSessionActivity: () => void;
|
|
7
|
+
/**
|
|
8
|
+
* Gets session information for debugging
|
|
9
|
+
*/
|
|
10
|
+
export declare const getSessionInfo: () => {
|
|
11
|
+
lastActivity: number;
|
|
12
|
+
isActive: boolean;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Initializes activity tracking
|
|
16
|
+
*/
|
|
17
|
+
export declare const initializeActivityTracking: (config: DotCMSAnalyticsConfig) => void;
|
|
18
|
+
/**
|
|
19
|
+
* Cleans up activity tracking listeners
|
|
20
|
+
*/
|
|
21
|
+
export declare const cleanupActivityTracking: () => void;
|
|
22
|
+
/**
|
|
23
|
+
* Checks if user has been inactive
|
|
24
|
+
*/
|
|
25
|
+
export declare const isUserInactive: () => boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Gets last activity time
|
|
28
|
+
*/
|
|
29
|
+
export declare const getLastActivity: () => number;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { DEFAULT_SESSION_TIMEOUT_MINUTES as c, ACTIVITY_EVENTS as r } from "./dot-content-analytics.constants.js";
|
|
2
|
+
class o {
|
|
3
|
+
constructor() {
|
|
4
|
+
this.activityListeners = [], this.lastActivityTime = Date.now(), this.inactivityTimer = null, this.isThrottled = !1, this.config = null, this.ACTIVITY_THROTTLE_MS = 1e3;
|
|
5
|
+
}
|
|
6
|
+
// Throttle activity events to max 1 per second
|
|
7
|
+
/**
|
|
8
|
+
* Updates activity timestamp (throttled for performance)
|
|
9
|
+
*/
|
|
10
|
+
updateActivityTime() {
|
|
11
|
+
this.lastActivityTime = Date.now(), this.inactivityTimer && clearTimeout(this.inactivityTimer), this.inactivityTimer = setTimeout(
|
|
12
|
+
() => {
|
|
13
|
+
var i;
|
|
14
|
+
(i = this.config) != null && i.debug && console.warn("DotCMS Analytics: User became inactive after timeout"), this.inactivityTimer = null;
|
|
15
|
+
},
|
|
16
|
+
c * 60 * 1e3
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Checks if user has been inactive
|
|
21
|
+
*/
|
|
22
|
+
isUserInactive() {
|
|
23
|
+
const i = c * 60 * 1e3;
|
|
24
|
+
return Date.now() - this.lastActivityTime > i;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Gets last activity time
|
|
28
|
+
*/
|
|
29
|
+
getLastActivity() {
|
|
30
|
+
return this.lastActivityTime;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Updates session activity with throttling
|
|
34
|
+
*/
|
|
35
|
+
updateSessionActivity() {
|
|
36
|
+
this.isThrottled || (this.isThrottled = !0, this.updateActivityTime(), setTimeout(() => {
|
|
37
|
+
this.isThrottled = !1;
|
|
38
|
+
}, this.ACTIVITY_THROTTLE_MS));
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Initializes activity tracking with event listeners
|
|
42
|
+
*/
|
|
43
|
+
initialize(i) {
|
|
44
|
+
if (this.cleanup(), this.config = i, typeof window > "u")
|
|
45
|
+
return;
|
|
46
|
+
const s = () => this.updateSessionActivity();
|
|
47
|
+
r.forEach((a) => {
|
|
48
|
+
window.addEventListener(a, s, { passive: !0 }), this.activityListeners.push(
|
|
49
|
+
() => window.removeEventListener(a, s)
|
|
50
|
+
);
|
|
51
|
+
});
|
|
52
|
+
const n = () => {
|
|
53
|
+
document.visibilityState === "visible" && (this.updateSessionActivity(), i.debug && console.warn("DotCMS Analytics: User returned to tab, session reactivated"));
|
|
54
|
+
};
|
|
55
|
+
document.addEventListener("visibilitychange", n), this.activityListeners.push(
|
|
56
|
+
() => document.removeEventListener("visibilitychange", n)
|
|
57
|
+
), this.updateActivityTime(), i.debug && console.warn("DotCMS Analytics: Activity tracking initialized");
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Cleans up all activity tracking listeners
|
|
61
|
+
*/
|
|
62
|
+
cleanup() {
|
|
63
|
+
this.activityListeners.forEach((i) => i()), this.activityListeners = [], this.inactivityTimer && (clearTimeout(this.inactivityTimer), this.inactivityTimer = null), this.config = null;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Gets session information for debugging
|
|
67
|
+
*/
|
|
68
|
+
getSessionInfo() {
|
|
69
|
+
return {
|
|
70
|
+
lastActivity: this.getLastActivity(),
|
|
71
|
+
isActive: !this.isUserInactive()
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
const t = new o(), h = () => {
|
|
76
|
+
t.updateSessionActivity();
|
|
77
|
+
}, l = (e) => {
|
|
78
|
+
t.initialize(e);
|
|
79
|
+
}, T = () => {
|
|
80
|
+
t.cleanup();
|
|
81
|
+
};
|
|
82
|
+
export {
|
|
83
|
+
T as cleanupActivityTracking,
|
|
84
|
+
l as initializeActivityTracking,
|
|
85
|
+
h as updateSessionActivity
|
|
86
|
+
};
|
|
@@ -1,13 +1,33 @@
|
|
|
1
1
|
export declare const ANALYTICS_WINDOWS_KEY = "dotAnalytics";
|
|
2
2
|
export declare const ANALYTICS_SOURCE_TYPE = "dotAnalytics";
|
|
3
3
|
export declare const ANALYTICS_ENDPOINT = "/api/v1/analytics/content/event";
|
|
4
|
-
export declare const ANALYTICS_PAGEVIEW_EVENT = "PAGE_REQUEST";
|
|
5
|
-
export declare const ANALYTICS_TRACK_EVENT = "TRACK_EVENT";
|
|
6
|
-
export declare const EXPECTED_UTM_KEYS: string[];
|
|
7
4
|
/**
|
|
8
|
-
*
|
|
5
|
+
* Event Types
|
|
6
|
+
* Only two event types are supported in DotCMS Analytics
|
|
9
7
|
*/
|
|
10
|
-
export declare
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
8
|
+
export declare const EVENT_TYPES: {
|
|
9
|
+
readonly PAGEVIEW: "pageview";
|
|
10
|
+
readonly TRACK: "track";
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Expected UTM parameter keys for campaign tracking
|
|
14
|
+
*/
|
|
15
|
+
export declare const EXPECTED_UTM_KEYS: readonly ["utm_source", "utm_medium", "utm_campaign", "utm_term", "utm_content", "utm_id"];
|
|
16
|
+
/**
|
|
17
|
+
* Session configuration constants
|
|
18
|
+
*/
|
|
19
|
+
export declare const DEFAULT_SESSION_TIMEOUT_MINUTES = 30;
|
|
20
|
+
export declare const SESSION_STORAGE_KEY = "dot_analytics_session_id";
|
|
21
|
+
export declare const SESSION_START_KEY = "dot_analytics_session_start";
|
|
22
|
+
export declare const SESSION_UTM_KEY = "dot_analytics_session_utm";
|
|
23
|
+
/**
|
|
24
|
+
* User ID configuration constants
|
|
25
|
+
*/
|
|
26
|
+
export declare const USER_ID_KEY = "dot_analytics_user_id";
|
|
27
|
+
/**
|
|
28
|
+
* Activity tracking configuration
|
|
29
|
+
* Events used to detect user activity for session management
|
|
30
|
+
* - click: Detects real user interaction with minimal performance impact
|
|
31
|
+
* - visibilitychange: Handled separately to detect tab changes
|
|
32
|
+
*/
|
|
33
|
+
export declare const ACTIVITY_EVENTS: readonly ["click"];
|
|
@@ -1,10 +1,14 @@
|
|
|
1
|
-
const
|
|
2
|
-
|
|
1
|
+
const t = "dotAnalytics", E = t, _ = "/api/v1/analytics/content/event", c = {
|
|
2
|
+
PAGEVIEW: "pageview",
|
|
3
|
+
TRACK: "track"
|
|
4
|
+
}, n = 30, s = "dot_analytics_session_id", S = "dot_analytics_user_id", T = ["click"];
|
|
3
5
|
export {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
T as ACTIVITY_EVENTS,
|
|
7
|
+
_ as ANALYTICS_ENDPOINT,
|
|
8
|
+
E as ANALYTICS_SOURCE_TYPE,
|
|
9
|
+
t as ANALYTICS_WINDOWS_KEY,
|
|
10
|
+
n as DEFAULT_SESSION_TIMEOUT_MINUTES,
|
|
11
|
+
c as EVENT_TYPES,
|
|
12
|
+
s as SESSION_STORAGE_KEY,
|
|
13
|
+
S as USER_ID_KEY
|
|
10
14
|
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DotCMSAnalyticsConfig, DotCMSAnalyticsRequestBody } from './dot-content-analytics.model';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Send an analytics event to the server
|
|
5
|
-
* @param
|
|
6
|
-
* @param
|
|
7
|
-
* @returns A promise that resolves
|
|
5
|
+
* @param payload - The event payload data
|
|
6
|
+
* @param config - The analytics configuration
|
|
7
|
+
* @returns A promise that resolves when the request is complete
|
|
8
8
|
*/
|
|
9
|
-
export declare const sendAnalyticsEventToServer: (
|
|
9
|
+
export declare const sendAnalyticsEventToServer: (payload: DotCMSAnalyticsRequestBody, config: DotCMSAnalyticsConfig) => Promise<void>;
|
|
@@ -1,22 +1,29 @@
|
|
|
1
|
-
import { ANALYTICS_ENDPOINT as
|
|
2
|
-
const
|
|
3
|
-
const r = {
|
|
4
|
-
...n,
|
|
5
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6
|
-
key: t.apiKey
|
|
7
|
-
};
|
|
8
|
-
t.debug && console.warn("DotAnalytics: Event sent:", r);
|
|
1
|
+
import { ANALYTICS_ENDPOINT as a } from "./dot-content-analytics.constants.js";
|
|
2
|
+
const i = async (o, t) => {
|
|
9
3
|
try {
|
|
10
|
-
const e = await fetch(`${t.server}${
|
|
4
|
+
const e = await fetch(`${t.server}${a}`, {
|
|
11
5
|
method: "POST",
|
|
12
6
|
headers: { "Content-Type": "application/json" },
|
|
13
|
-
body: JSON.stringify(
|
|
7
|
+
body: JSON.stringify(o)
|
|
14
8
|
});
|
|
15
|
-
e.ok
|
|
9
|
+
if (!e.ok) {
|
|
10
|
+
const n = e.statusText || "Unknown Error", s = `HTTP ${e.status}: ${n}`;
|
|
11
|
+
try {
|
|
12
|
+
const r = await e.json();
|
|
13
|
+
r.message ? console.warn(`DotAnalytics: ${r.message} (${s})`) : console.warn(
|
|
14
|
+
`DotAnalytics: ${s} - No error message in response`
|
|
15
|
+
);
|
|
16
|
+
} catch (r) {
|
|
17
|
+
console.warn(
|
|
18
|
+
`DotAnalytics: ${s} - Failed to parse error response:`,
|
|
19
|
+
r
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
16
23
|
} catch (e) {
|
|
17
24
|
console.error("DotAnalytics: Error sending event:", e);
|
|
18
25
|
}
|
|
19
26
|
};
|
|
20
27
|
export {
|
|
21
|
-
|
|
28
|
+
i as sendAnalyticsEventToServer
|
|
22
29
|
};
|