@splendidlabz/tracking 0.1.22 → 0.2.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/lib/fb/consts.js +425 -0
- package/lib/fb/node.js +141 -0
- package/lib/fb/readme.md +54 -0
- package/lib/fb/utils.js +15 -337
- package/lib/fb/web.js +148 -0
- package/lib/fb/web.test.js +47 -0
- package/lib/posthog/node.js +140 -0
- package/lib/posthog/readme.md +17 -0
- package/lib/posthog/web.js +79 -0
- package/package.json +6 -6
- package/dist/fb.js +0 -949
- package/lib/fb/browser.js +0 -184
- package/lib/fb/browser.test.js +0 -127
- package/lib/fb/server.js +0 -73
- /package/lib/posthog/{CrossDomainTracking.svelte → old/CrossDomainTracking.svelte} +0 -0
- /package/lib/posthog/{cross-domain.js → old/cross-domain.js} +0 -0
- /package/lib/posthog/{index.js → old/index.js} +0 -0
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { omitEmpty } from '@splendidlabz/utils'
|
|
2
|
+
import { PostHog } from 'posthog-node'
|
|
3
|
+
|
|
4
|
+
// Posthog Persistence docs: https://posthog.com/docs/libraries/js/persistence
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Creates a PostHog analytics client wrapper for server-side tracking
|
|
8
|
+
* @param {Object} config - Configuration object
|
|
9
|
+
* @param {string} config.apiKey - PostHog API key
|
|
10
|
+
* @param {string} config.host - PostHog host URL
|
|
11
|
+
* @param {string} config.framework - Framework name (currently only 'astro' is supported)
|
|
12
|
+
* @param {boolean} [config.trackEvents=true] - Whether to track events. Set to false in development mode to avoid sending events to PostHog.
|
|
13
|
+
* @param {...*} config.rest - Additional PostHog client options
|
|
14
|
+
* @return {Object} PostHog client wrapper
|
|
15
|
+
* @property {Function} capture - Captures analytics events
|
|
16
|
+
* @property {Function} setPersonProperties - Sets person properties
|
|
17
|
+
* @property {Function} removePersonProperties - Removes person properties
|
|
18
|
+
* @property {Function} shutdown - Shuts down the PostHog client
|
|
19
|
+
* @throws {Error} When framework is not 'astro'
|
|
20
|
+
*/
|
|
21
|
+
export default function (config = {}) {
|
|
22
|
+
const { framework, apiKey, host, trackEvents = true, ...rest } = config
|
|
23
|
+
const cookieName = `ph_${apiKey}_posthog`
|
|
24
|
+
|
|
25
|
+
if (framework !== 'astro') {
|
|
26
|
+
throw new Error('Only Astro framework is supported at the moment')
|
|
27
|
+
}
|
|
28
|
+
const client = new PostHog(apiKey, { host, ...rest })
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Gets the distinct ID for tracking, prioritizing email, then userId, then cookie-based ID
|
|
32
|
+
* @param {Object} params - Parameters object
|
|
33
|
+
* @param {string} params.email - User email address
|
|
34
|
+
* @param {string} params.userId - User ID
|
|
35
|
+
* @param {Object} params.context - Request context (for cookie access)
|
|
36
|
+
* @param {string} params.framework - Framework name
|
|
37
|
+
* @return {string|undefined} The distinct ID for tracking
|
|
38
|
+
*/
|
|
39
|
+
function getDistinctId({ email, userId, context, framework }) {
|
|
40
|
+
if (email) return email
|
|
41
|
+
if (userId) return userId
|
|
42
|
+
return getDistinctIdFromCookie({ context, framework })
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// This assumes posthog web is used as well.
|
|
46
|
+
// If not used, we need to generate and store the distinct_id in a cookie instead — maybe in the future.
|
|
47
|
+
// - Need a database to store distinct_id?
|
|
48
|
+
// - Need to use userId or email from the database?
|
|
49
|
+
/**
|
|
50
|
+
* Extracts distinct ID from PostHog cookie (assumes PostHog web client is also used)
|
|
51
|
+
* @param {Object} params - Parameters object
|
|
52
|
+
* @param {Object} params.context - Request context with cookies access
|
|
53
|
+
* @param {string} params.framework - Framework name
|
|
54
|
+
* @return {string|undefined} The distinct ID from cookie, or undefined if not found
|
|
55
|
+
*/
|
|
56
|
+
function getDistinctIdFromCookie({ context, framework }) {
|
|
57
|
+
if (framework === 'astro') {
|
|
58
|
+
const cookie = context.cookies.get(cookieName)
|
|
59
|
+
if (cookie) {
|
|
60
|
+
const { distinct_id } = JSON.parse(cookie.value)
|
|
61
|
+
return distinct_id
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return {
|
|
67
|
+
/**
|
|
68
|
+
* Captures an analytics event
|
|
69
|
+
* @param {string} event - Event name to track
|
|
70
|
+
* @param {Object} [properties={}] - Event properties and user identification
|
|
71
|
+
* @param {string} [properties.email] - User email (used for distinct ID)
|
|
72
|
+
* @param {string} [properties.userId] - User ID (used for distinct ID)
|
|
73
|
+
* @param {Object} [properties.context] - Request context (for cookie access)
|
|
74
|
+
* @param {...*} properties.rest - Additional event properties
|
|
75
|
+
* @return {Promise|undefined} PostHog capture promise, or undefined if trackDevEvents is true
|
|
76
|
+
*/
|
|
77
|
+
capture(event, properties = {}) {
|
|
78
|
+
if (!trackEvents) return
|
|
79
|
+
const { email, userId, context, ...rest } = properties
|
|
80
|
+
|
|
81
|
+
const distinctId = getDistinctId({ email, userId, context, framework })
|
|
82
|
+
|
|
83
|
+
const data = omitEmpty({ event, distinctId, ...rest })
|
|
84
|
+
return client.capture(data)
|
|
85
|
+
},
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Sets person properties on the current user
|
|
89
|
+
* @param {Object} [set={}] - Properties to set (will overwrite existing values)
|
|
90
|
+
* @param {Object} [once={}] - Properties to set only once (won't overwrite existing values)
|
|
91
|
+
* @return {Promise|undefined} PostHog capture promise, or undefined if trackDevEvents is true
|
|
92
|
+
*/
|
|
93
|
+
setPersonProperties(set = {}, once = {}) {
|
|
94
|
+
if (!trackEvents) return
|
|
95
|
+
return client.capture({
|
|
96
|
+
event: '$set',
|
|
97
|
+
properties: omitEmpty({
|
|
98
|
+
$set: set,
|
|
99
|
+
$set_once: once,
|
|
100
|
+
}),
|
|
101
|
+
})
|
|
102
|
+
},
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Removes person properties from the current user
|
|
106
|
+
* @param {string[]} properties - List of property names to remove
|
|
107
|
+
* @return {Promise|undefined} PostHog capture promise, or undefined if trackDevEvents is true
|
|
108
|
+
*/
|
|
109
|
+
removePersonProperties(properties) {
|
|
110
|
+
if (!trackEvents) return
|
|
111
|
+
return client.capture({
|
|
112
|
+
event: '$unset',
|
|
113
|
+
properties: {
|
|
114
|
+
$unset: properties,
|
|
115
|
+
},
|
|
116
|
+
})
|
|
117
|
+
},
|
|
118
|
+
|
|
119
|
+
// identify(distinctId, properties = {}) {
|
|
120
|
+
// return client.identify({ distinctId, properties })
|
|
121
|
+
// },
|
|
122
|
+
|
|
123
|
+
// alias(alias, distinctId) {
|
|
124
|
+
// return client.alias({ alias, distinctId })
|
|
125
|
+
// },
|
|
126
|
+
|
|
127
|
+
// // Not sure about this yet
|
|
128
|
+
// group(groupType, groupKey, properties = {}) {
|
|
129
|
+
// return client.group({ groupType, groupKey, properties })
|
|
130
|
+
// },
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Shuts down the PostHog client and flushes any pending events
|
|
134
|
+
* @return {Promise} Promise that resolves when shutdown is complete
|
|
135
|
+
*/
|
|
136
|
+
shutdown() {
|
|
137
|
+
return client.shutdown()
|
|
138
|
+
},
|
|
139
|
+
}
|
|
140
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
Ok. This is quite complex. So let's break it down.
|
|
2
|
+
|
|
3
|
+
This package assumes you're using Posthog for both web and node.js.
|
|
4
|
+
|
|
5
|
+
## Initializing
|
|
6
|
+
|
|
7
|
+
## Steps
|
|
8
|
+
|
|
9
|
+
1. Init on frontend — everywhere. This will allow posthog to track via their web sdk.
|
|
10
|
+
2. On the backend — use ph.capture as necessary.
|
|
11
|
+
3. When user logs in, or when you have a way to identify the user, use ph.identify on the frontend. (Don't identify on the backend).
|
|
12
|
+
4. No need to alias. ph will replace merge any new `distinct_id` with the one you provided, if any.
|
|
13
|
+
|
|
14
|
+
## Couple of enhancements
|
|
15
|
+
|
|
16
|
+
- Get distinct_id from cookies on the backend automatically when using Astro — just provide context.
|
|
17
|
+
- Use `trackEvents:false` to disable tracking completely when developing.
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { getCookie } from '@splendidlabz/utils/dom'
|
|
2
|
+
import posthog from 'posthog-js'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Creates a PostHog wrapper for web browser tracking
|
|
6
|
+
* @param {object} config - Configuration object
|
|
7
|
+
* @param {string} config.apiKey - PostHog API key
|
|
8
|
+
* @param {string} config.host - PostHog host URL
|
|
9
|
+
* @param {boolean} [config.trackEvents=true] - Whether to track events. Set to false in development mode to avoid sending events to PostHog.
|
|
10
|
+
* @returns {object} PostHog wrapper object with tracking methods
|
|
11
|
+
*/
|
|
12
|
+
export default function (config = {}) {
|
|
13
|
+
const { apiKey, host, trackEvents = true, ...rest } = config
|
|
14
|
+
const cookieName = `ph_${apiKey}_posthog`
|
|
15
|
+
|
|
16
|
+
return {
|
|
17
|
+
...posthog,
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Initialize PostHog tracking
|
|
21
|
+
* @returns {void}
|
|
22
|
+
*/
|
|
23
|
+
init() {
|
|
24
|
+
if (!trackEvents) return
|
|
25
|
+
posthog.init(apiKey, {
|
|
26
|
+
api_host: host,
|
|
27
|
+
...rest,
|
|
28
|
+
})
|
|
29
|
+
},
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Capture a tracking event
|
|
33
|
+
* @param {string} event - Name of the event to track
|
|
34
|
+
* @param {object} [properties={}] - Event properties to send
|
|
35
|
+
* @returns {void}
|
|
36
|
+
*/
|
|
37
|
+
capture(event, properties = {}) {
|
|
38
|
+
if (!trackEvents) return
|
|
39
|
+
return posthog.capture(event, properties)
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Set properties for the current person
|
|
44
|
+
* @param {...any} props - Properties to set for the person
|
|
45
|
+
* @returns {void}
|
|
46
|
+
*/
|
|
47
|
+
setPersonProperties(set = {}, once = {}) {
|
|
48
|
+
if (!trackEvents) return
|
|
49
|
+
return posthog.setPersonProperties(set, once)
|
|
50
|
+
},
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* @param {string} distinctId - New unique identifier for the user (email, userId, etc.)
|
|
54
|
+
* @param {object} properties - The properties to set for the user
|
|
55
|
+
* @returns {void}
|
|
56
|
+
*/
|
|
57
|
+
identify(distinctId, properties = {}) {
|
|
58
|
+
if (!trackEvents) return
|
|
59
|
+
const cookie = getCookie(cookieName)
|
|
60
|
+
const existingId = cookie?.distinct_id
|
|
61
|
+
|
|
62
|
+
if (existingId !== distinctId) {
|
|
63
|
+
return posthog.identify(distinctId, properties)
|
|
64
|
+
} else {
|
|
65
|
+
return this.setPersonProperties(properties)
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* @param {string} distinctId - New unique identifier for the user
|
|
71
|
+
* @param {string} aliasId - Alias for the user
|
|
72
|
+
* @returns {void}
|
|
73
|
+
*/
|
|
74
|
+
alias(distinctId, aliasId) {
|
|
75
|
+
if (!trackEvents) return
|
|
76
|
+
return posthog.alias(distinctId, aliasId)
|
|
77
|
+
},
|
|
78
|
+
}
|
|
79
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@splendidlabz/tracking",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Simple Tracking Helper",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -20,17 +20,17 @@
|
|
|
20
20
|
},
|
|
21
21
|
"author": "Zell Liew <zellwk@gmail.com> (https://zellwk.com/)",
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@splendidlabz/utils": "1.
|
|
23
|
+
"@splendidlabz/utils": "1.6.0",
|
|
24
24
|
"posthog-js": "^1.234.6",
|
|
25
|
-
"posthog-node": "^
|
|
25
|
+
"posthog-node": "^5.5.1",
|
|
26
26
|
"zl-fetch": "^6.0.6"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
|
-
"@rollup/plugin-node-resolve": "^
|
|
29
|
+
"@rollup/plugin-node-resolve": "^16.0.1",
|
|
30
30
|
"@rollup/plugin-terser": "^0.4.4",
|
|
31
|
-
"jsdom": "^
|
|
31
|
+
"jsdom": "^26.1.0",
|
|
32
32
|
"np": "^10.2.0",
|
|
33
|
-
"rollup": "^4.
|
|
33
|
+
"rollup": "^4.45.1",
|
|
34
34
|
"rollup-plugin-commonjs": "^10.1.0",
|
|
35
35
|
"rollup-plugin-filesize": "^10.0.0",
|
|
36
36
|
"vitest": "^3.1.1"
|