@indiebob/tracker 0.2.4 → 0.4.1
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/CHANGELOG.md +89 -0
- package/README.md +112 -389
- package/dist/index.cjs +973 -2
- package/dist/index.d.mts +91 -16
- package/dist/index.d.ts +91 -16
- package/dist/index.global.js +3 -3
- package/dist/index.js +971 -2
- package/dist/server.d.mts +25 -2
- package/dist/server.d.ts +25 -2
- package/dist/server.js +18 -7
- package/dist/server.mjs +18 -7
- package/dist/vue.cjs +997 -2
- package/dist/vue.global.js +3 -3
- package/dist/vue.js +993 -2
- package/package.json +4 -3
- package/dist/chunk-4IK5PET7.js +0 -2
- package/dist/chunk-DZOEO647.js +0 -2
- package/dist/chunk-XKQYO25W.js +0 -2
package/dist/server.d.mts
CHANGED
|
@@ -4,13 +4,13 @@
|
|
|
4
4
|
interface TrackerConfig {
|
|
5
5
|
/** Your SDK project ID from the IndieBob dashboard. Format: 'proj_...' */
|
|
6
6
|
projectId: string;
|
|
7
|
-
/** Ingestion endpoint URL. Default: 'https://indiebob.com/api/collect' */
|
|
7
|
+
/** Ingestion endpoint URL. Default: 'https://www.indiebob.com/api/collect' */
|
|
8
8
|
endpoint?: string;
|
|
9
9
|
/** Log all events to the browser console. Default: false */
|
|
10
10
|
debug?: boolean;
|
|
11
11
|
/** Honor the browser Do Not Track header. Default: true */
|
|
12
12
|
respectDnt?: boolean;
|
|
13
|
-
/** Honor Global Privacy Control signal (legally binding in
|
|
13
|
+
/** Honor Global Privacy Control signal (legally binding under CCPA in California). Default: true */
|
|
14
14
|
respectGpc?: boolean;
|
|
15
15
|
/**
|
|
16
16
|
* Auto-detect user intent from URL patterns and identify() calls.
|
|
@@ -42,8 +42,31 @@ interface TrackerConfig {
|
|
|
42
42
|
formSubmit?: boolean;
|
|
43
43
|
/** Track clicks on outbound links. Default: true */
|
|
44
44
|
outboundClicks?: boolean;
|
|
45
|
+
/** Track clicks on links to files (pdf, zip, dmg, …) as `file_download`. Default: true */
|
|
46
|
+
fileDownloads?: boolean;
|
|
45
47
|
};
|
|
48
|
+
/**
|
|
49
|
+
* Treat the URL hash as part of the page path (for `/#/route` routers):
|
|
50
|
+
* a hash-only change becomes a pageview and the hash is reported in the
|
|
51
|
+
* path. Default: false (a hash-only change is not a new page).
|
|
52
|
+
*/
|
|
53
|
+
hashMode?: boolean;
|
|
54
|
+
/**
|
|
55
|
+
* What the tracker keeps in the visitor's browser.
|
|
56
|
+
*
|
|
57
|
+
* - `'none'` (default): nothing. No id, no stored UTM or referrer, no offline
|
|
58
|
+
* queue. IndieBob counts the visitor on its server from a hash of a daily
|
|
59
|
+
* salt, the site, the IP address and the user agent; the salt is deleted
|
|
60
|
+
* after a day and the IP is never stored. No consent needed.
|
|
61
|
+
* - `'local'`: a random visitor id, first-touch UTM and referrer in
|
|
62
|
+
* localStorage, so a visitor is recognised across days. Storing an id on
|
|
63
|
+
* the visitor's device needs their consent in the EU (ePrivacy Art. 5(3)):
|
|
64
|
+
* switch to it from your consent banner with `bob.setPersistence('local')`.
|
|
65
|
+
*/
|
|
66
|
+
persistence?: Persistence;
|
|
46
67
|
}
|
|
68
|
+
/** Where the tracker may store anything: nowhere, or localStorage. */
|
|
69
|
+
type Persistence = 'none' | 'local';
|
|
47
70
|
|
|
48
71
|
/**
|
|
49
72
|
* Server-side tracker for Node.js environments.
|
package/dist/server.d.ts
CHANGED
|
@@ -4,13 +4,13 @@
|
|
|
4
4
|
interface TrackerConfig {
|
|
5
5
|
/** Your SDK project ID from the IndieBob dashboard. Format: 'proj_...' */
|
|
6
6
|
projectId: string;
|
|
7
|
-
/** Ingestion endpoint URL. Default: 'https://indiebob.com/api/collect' */
|
|
7
|
+
/** Ingestion endpoint URL. Default: 'https://www.indiebob.com/api/collect' */
|
|
8
8
|
endpoint?: string;
|
|
9
9
|
/** Log all events to the browser console. Default: false */
|
|
10
10
|
debug?: boolean;
|
|
11
11
|
/** Honor the browser Do Not Track header. Default: true */
|
|
12
12
|
respectDnt?: boolean;
|
|
13
|
-
/** Honor Global Privacy Control signal (legally binding in
|
|
13
|
+
/** Honor Global Privacy Control signal (legally binding under CCPA in California). Default: true */
|
|
14
14
|
respectGpc?: boolean;
|
|
15
15
|
/**
|
|
16
16
|
* Auto-detect user intent from URL patterns and identify() calls.
|
|
@@ -42,8 +42,31 @@ interface TrackerConfig {
|
|
|
42
42
|
formSubmit?: boolean;
|
|
43
43
|
/** Track clicks on outbound links. Default: true */
|
|
44
44
|
outboundClicks?: boolean;
|
|
45
|
+
/** Track clicks on links to files (pdf, zip, dmg, …) as `file_download`. Default: true */
|
|
46
|
+
fileDownloads?: boolean;
|
|
45
47
|
};
|
|
48
|
+
/**
|
|
49
|
+
* Treat the URL hash as part of the page path (for `/#/route` routers):
|
|
50
|
+
* a hash-only change becomes a pageview and the hash is reported in the
|
|
51
|
+
* path. Default: false (a hash-only change is not a new page).
|
|
52
|
+
*/
|
|
53
|
+
hashMode?: boolean;
|
|
54
|
+
/**
|
|
55
|
+
* What the tracker keeps in the visitor's browser.
|
|
56
|
+
*
|
|
57
|
+
* - `'none'` (default): nothing. No id, no stored UTM or referrer, no offline
|
|
58
|
+
* queue. IndieBob counts the visitor on its server from a hash of a daily
|
|
59
|
+
* salt, the site, the IP address and the user agent; the salt is deleted
|
|
60
|
+
* after a day and the IP is never stored. No consent needed.
|
|
61
|
+
* - `'local'`: a random visitor id, first-touch UTM and referrer in
|
|
62
|
+
* localStorage, so a visitor is recognised across days. Storing an id on
|
|
63
|
+
* the visitor's device needs their consent in the EU (ePrivacy Art. 5(3)):
|
|
64
|
+
* switch to it from your consent banner with `bob.setPersistence('local')`.
|
|
65
|
+
*/
|
|
66
|
+
persistence?: Persistence;
|
|
46
67
|
}
|
|
68
|
+
/** Where the tracker may store anything: nowhere, or localStorage. */
|
|
69
|
+
type Persistence = 'none' | 'local';
|
|
47
70
|
|
|
48
71
|
/**
|
|
49
72
|
* Server-side tracker for Node.js environments.
|
package/dist/server.js
CHANGED
|
@@ -2,28 +2,38 @@
|
|
|
2
2
|
|
|
3
3
|
// src/core/config.ts
|
|
4
4
|
var DEFAULT_ENDPOINT = "https://www.indiebob.com/api/collect";
|
|
5
|
+
var OPTIONS = "projectId endpoint debug respectDnt respectGpc autoDetect hashMode persistence";
|
|
6
|
+
var AUTO_OPTIONS = "signupPaths loginPaths pricingPaths checkoutPaths successPaths onboardingPaths contactPaths dataAttributes formSubmit outboundClicks fileDownloads";
|
|
7
|
+
function warnUnknown(obj, known, where) {
|
|
8
|
+
for (const k of Object.keys(obj)) {
|
|
9
|
+
if (!known.split(" ").includes(k)) console.warn(`[IndieBob] Unknown option ${where}"${k}" ignored`);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
5
12
|
function resolveConfig(input) {
|
|
6
13
|
if (!input.projectId || !input.projectId.startsWith("proj_")) {
|
|
7
14
|
throw new Error(
|
|
8
15
|
`[IndieBob] Invalid projectId "${input.projectId}". Must start with "proj_".`
|
|
9
16
|
);
|
|
10
17
|
}
|
|
18
|
+
warnUnknown(input, OPTIONS, "");
|
|
19
|
+
if (typeof input.autoDetect === "object") warnUnknown(input.autoDetect, AUTO_OPTIONS, "autoDetect.");
|
|
20
|
+
if (input.persistence !== void 0 && input.persistence !== "local" && input.persistence !== "none") {
|
|
21
|
+
console.warn(`[IndieBob] persistence "${String(input.persistence)}" is not 'none' or 'local'; using 'none'`);
|
|
22
|
+
}
|
|
11
23
|
return {
|
|
12
24
|
projectId: input.projectId,
|
|
13
25
|
endpoint: input.endpoint ?? DEFAULT_ENDPOINT,
|
|
14
26
|
debug: input.debug ?? false,
|
|
15
27
|
respectDnt: input.respectDnt ?? true,
|
|
16
28
|
respectGpc: input.respectGpc ?? true,
|
|
17
|
-
autoDetect: input.autoDetect ?? true
|
|
29
|
+
autoDetect: input.autoDetect ?? true,
|
|
30
|
+
hashMode: input.hashMode ?? false,
|
|
31
|
+
persistence: input.persistence === "local" ? "local" : "none"
|
|
18
32
|
};
|
|
19
33
|
}
|
|
20
34
|
|
|
21
35
|
// src/core/transport.ts
|
|
22
36
|
var MAX_RETRIES = 3;
|
|
23
|
-
var RETRY_DELAYS = [1e3, 2e3, 4e3];
|
|
24
|
-
async function sleep(ms) {
|
|
25
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
26
|
-
}
|
|
27
37
|
async function sendBatchServer(payload, config) {
|
|
28
38
|
for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {
|
|
29
39
|
try {
|
|
@@ -36,7 +46,7 @@ async function sendBatchServer(payload, config) {
|
|
|
36
46
|
if (res.status >= 400 && res.status < 500) return false;
|
|
37
47
|
} catch {
|
|
38
48
|
}
|
|
39
|
-
if (attempt < MAX_RETRIES - 1) await
|
|
49
|
+
if (attempt < MAX_RETRIES - 1) await new Promise((resolve) => setTimeout(resolve, 1e3 << attempt));
|
|
40
50
|
}
|
|
41
51
|
return false;
|
|
42
52
|
}
|
|
@@ -69,6 +79,7 @@ var IndieBobServer = class _IndieBobServer {
|
|
|
69
79
|
buildEvent(type, extras) {
|
|
70
80
|
return {
|
|
71
81
|
v: 1,
|
|
82
|
+
id: generateId(),
|
|
72
83
|
projectId: this.config.projectId,
|
|
73
84
|
type,
|
|
74
85
|
anonymousId: `server_${generateId()}`,
|
|
@@ -80,7 +91,7 @@ var IndieBobServer = class _IndieBobServer {
|
|
|
80
91
|
device: { width: 0, height: 0, type: "desktop" },
|
|
81
92
|
locale: "en",
|
|
82
93
|
timezone: "UTC",
|
|
83
|
-
sdkVersion: "0.
|
|
94
|
+
sdkVersion: "0.4.1"
|
|
84
95
|
},
|
|
85
96
|
event: extras.event,
|
|
86
97
|
properties: extras.properties,
|
package/dist/server.mjs
CHANGED
|
@@ -1,27 +1,37 @@
|
|
|
1
1
|
// src/core/config.ts
|
|
2
2
|
var DEFAULT_ENDPOINT = "https://www.indiebob.com/api/collect";
|
|
3
|
+
var OPTIONS = "projectId endpoint debug respectDnt respectGpc autoDetect hashMode persistence";
|
|
4
|
+
var AUTO_OPTIONS = "signupPaths loginPaths pricingPaths checkoutPaths successPaths onboardingPaths contactPaths dataAttributes formSubmit outboundClicks fileDownloads";
|
|
5
|
+
function warnUnknown(obj, known, where) {
|
|
6
|
+
for (const k of Object.keys(obj)) {
|
|
7
|
+
if (!known.split(" ").includes(k)) console.warn(`[IndieBob] Unknown option ${where}"${k}" ignored`);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
3
10
|
function resolveConfig(input) {
|
|
4
11
|
if (!input.projectId || !input.projectId.startsWith("proj_")) {
|
|
5
12
|
throw new Error(
|
|
6
13
|
`[IndieBob] Invalid projectId "${input.projectId}". Must start with "proj_".`
|
|
7
14
|
);
|
|
8
15
|
}
|
|
16
|
+
warnUnknown(input, OPTIONS, "");
|
|
17
|
+
if (typeof input.autoDetect === "object") warnUnknown(input.autoDetect, AUTO_OPTIONS, "autoDetect.");
|
|
18
|
+
if (input.persistence !== void 0 && input.persistence !== "local" && input.persistence !== "none") {
|
|
19
|
+
console.warn(`[IndieBob] persistence "${String(input.persistence)}" is not 'none' or 'local'; using 'none'`);
|
|
20
|
+
}
|
|
9
21
|
return {
|
|
10
22
|
projectId: input.projectId,
|
|
11
23
|
endpoint: input.endpoint ?? DEFAULT_ENDPOINT,
|
|
12
24
|
debug: input.debug ?? false,
|
|
13
25
|
respectDnt: input.respectDnt ?? true,
|
|
14
26
|
respectGpc: input.respectGpc ?? true,
|
|
15
|
-
autoDetect: input.autoDetect ?? true
|
|
27
|
+
autoDetect: input.autoDetect ?? true,
|
|
28
|
+
hashMode: input.hashMode ?? false,
|
|
29
|
+
persistence: input.persistence === "local" ? "local" : "none"
|
|
16
30
|
};
|
|
17
31
|
}
|
|
18
32
|
|
|
19
33
|
// src/core/transport.ts
|
|
20
34
|
var MAX_RETRIES = 3;
|
|
21
|
-
var RETRY_DELAYS = [1e3, 2e3, 4e3];
|
|
22
|
-
async function sleep(ms) {
|
|
23
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
24
|
-
}
|
|
25
35
|
async function sendBatchServer(payload, config) {
|
|
26
36
|
for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {
|
|
27
37
|
try {
|
|
@@ -34,7 +44,7 @@ async function sendBatchServer(payload, config) {
|
|
|
34
44
|
if (res.status >= 400 && res.status < 500) return false;
|
|
35
45
|
} catch {
|
|
36
46
|
}
|
|
37
|
-
if (attempt < MAX_RETRIES - 1) await
|
|
47
|
+
if (attempt < MAX_RETRIES - 1) await new Promise((resolve) => setTimeout(resolve, 1e3 << attempt));
|
|
38
48
|
}
|
|
39
49
|
return false;
|
|
40
50
|
}
|
|
@@ -67,6 +77,7 @@ var IndieBobServer = class _IndieBobServer {
|
|
|
67
77
|
buildEvent(type, extras) {
|
|
68
78
|
return {
|
|
69
79
|
v: 1,
|
|
80
|
+
id: generateId(),
|
|
70
81
|
projectId: this.config.projectId,
|
|
71
82
|
type,
|
|
72
83
|
anonymousId: `server_${generateId()}`,
|
|
@@ -78,7 +89,7 @@ var IndieBobServer = class _IndieBobServer {
|
|
|
78
89
|
device: { width: 0, height: 0, type: "desktop" },
|
|
79
90
|
locale: "en",
|
|
80
91
|
timezone: "UTC",
|
|
81
|
-
sdkVersion: "0.
|
|
92
|
+
sdkVersion: "0.4.1"
|
|
82
93
|
},
|
|
83
94
|
event: extras.event,
|
|
84
95
|
properties: extras.properties,
|