@indiebob/tracker 0.3.0 → 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 +32 -0
- package/README.md +112 -508
- package/dist/index.cjs +187 -94
- package/dist/index.d.mts +36 -7
- package/dist/index.d.ts +36 -7
- package/dist/index.global.js +2 -2
- package/dist/index.js +187 -94
- package/dist/server.d.mts +17 -2
- package/dist/server.d.ts +17 -2
- package/dist/server.js +15 -2
- package/dist/server.mjs +15 -2
- package/dist/vue.cjs +187 -94
- package/dist/vue.global.js +2 -2
- package/dist/vue.js +187 -94
- package/package.json +2 -2
- package/dist/chunk-4IK5PET7.js +0 -2
- package/dist/chunk-DZOEO647.js +0 -2
- package/dist/chunk-XKQYO25W.js +0 -2
package/dist/server.js
CHANGED
|
@@ -2,12 +2,24 @@
|
|
|
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,
|
|
@@ -15,7 +27,8 @@ function resolveConfig(input) {
|
|
|
15
27
|
respectDnt: input.respectDnt ?? true,
|
|
16
28
|
respectGpc: input.respectGpc ?? true,
|
|
17
29
|
autoDetect: input.autoDetect ?? true,
|
|
18
|
-
hashMode: input.hashMode ?? false
|
|
30
|
+
hashMode: input.hashMode ?? false,
|
|
31
|
+
persistence: input.persistence === "local" ? "local" : "none"
|
|
19
32
|
};
|
|
20
33
|
}
|
|
21
34
|
|
|
@@ -78,7 +91,7 @@ var IndieBobServer = class _IndieBobServer {
|
|
|
78
91
|
device: { width: 0, height: 0, type: "desktop" },
|
|
79
92
|
locale: "en",
|
|
80
93
|
timezone: "UTC",
|
|
81
|
-
sdkVersion: "0.
|
|
94
|
+
sdkVersion: "0.4.1"
|
|
82
95
|
},
|
|
83
96
|
event: extras.event,
|
|
84
97
|
properties: extras.properties,
|
package/dist/server.mjs
CHANGED
|
@@ -1,11 +1,23 @@
|
|
|
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,
|
|
@@ -13,7 +25,8 @@ function resolveConfig(input) {
|
|
|
13
25
|
respectDnt: input.respectDnt ?? true,
|
|
14
26
|
respectGpc: input.respectGpc ?? true,
|
|
15
27
|
autoDetect: input.autoDetect ?? true,
|
|
16
|
-
hashMode: input.hashMode ?? false
|
|
28
|
+
hashMode: input.hashMode ?? false,
|
|
29
|
+
persistence: input.persistence === "local" ? "local" : "none"
|
|
17
30
|
};
|
|
18
31
|
}
|
|
19
32
|
|
|
@@ -76,7 +89,7 @@ var IndieBobServer = class _IndieBobServer {
|
|
|
76
89
|
device: { width: 0, height: 0, type: "desktop" },
|
|
77
90
|
locale: "en",
|
|
78
91
|
timezone: "UTC",
|
|
79
|
-
sdkVersion: "0.
|
|
92
|
+
sdkVersion: "0.4.1"
|
|
80
93
|
},
|
|
81
94
|
event: extras.event,
|
|
82
95
|
properties: extras.properties,
|
package/dist/vue.cjs
CHANGED
|
@@ -2,6 +2,13 @@
|
|
|
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
|
var _a, _b, _c, _d, _e, _f;
|
|
7
14
|
if (!input.projectId || !input.projectId.startsWith("proj_")) {
|
|
@@ -9,6 +16,11 @@ function resolveConfig(input) {
|
|
|
9
16
|
`[IndieBob] Invalid projectId "${input.projectId}". Must start with "proj_".`
|
|
10
17
|
);
|
|
11
18
|
}
|
|
19
|
+
warnUnknown(input, OPTIONS, "");
|
|
20
|
+
if (typeof input.autoDetect === "object") warnUnknown(input.autoDetect, AUTO_OPTIONS, "autoDetect.");
|
|
21
|
+
if (input.persistence !== void 0 && input.persistence !== "local" && input.persistence !== "none") {
|
|
22
|
+
console.warn(`[IndieBob] persistence "${String(input.persistence)}" is not 'none' or 'local'; using 'none'`);
|
|
23
|
+
}
|
|
12
24
|
return {
|
|
13
25
|
projectId: input.projectId,
|
|
14
26
|
endpoint: (_a = input.endpoint) != null ? _a : DEFAULT_ENDPOINT,
|
|
@@ -16,7 +28,8 @@ function resolveConfig(input) {
|
|
|
16
28
|
respectDnt: (_c = input.respectDnt) != null ? _c : true,
|
|
17
29
|
respectGpc: (_d = input.respectGpc) != null ? _d : true,
|
|
18
30
|
autoDetect: (_e = input.autoDetect) != null ? _e : true,
|
|
19
|
-
hashMode: (_f = input.hashMode) != null ? _f : false
|
|
31
|
+
hashMode: (_f = input.hashMode) != null ? _f : false,
|
|
32
|
+
persistence: input.persistence === "local" ? "local" : "none"
|
|
20
33
|
};
|
|
21
34
|
}
|
|
22
35
|
|
|
@@ -279,7 +292,6 @@ async function sendBatch(payload, config, isUnloading = false) {
|
|
|
279
292
|
var OFFLINE_KEY = "_ib_queue";
|
|
280
293
|
var MAX_BATCH = 10;
|
|
281
294
|
var FLUSH_INTERVAL_MS = 5e3;
|
|
282
|
-
var MAX_OFFLINE = 50;
|
|
283
295
|
var EventQueue = class {
|
|
284
296
|
/**
|
|
285
297
|
* @param beforeHide runs right before the hide flush, so an event that
|
|
@@ -287,7 +299,9 @@ var EventQueue = class {
|
|
|
287
299
|
*/
|
|
288
300
|
constructor(config, beforeHide) {
|
|
289
301
|
this.b = [];
|
|
290
|
-
|
|
302
|
+
/** Failed events awaiting a retry, when nothing may be stored ('none'). */
|
|
303
|
+
this.j = [];
|
|
304
|
+
this.k = false;
|
|
291
305
|
this.a = config;
|
|
292
306
|
setInterval(() => {
|
|
293
307
|
if (this.b.length > 0) void this.flush();
|
|
@@ -302,10 +316,10 @@ var EventQueue = class {
|
|
|
302
316
|
});
|
|
303
317
|
window.addEventListener("pagehide", hide);
|
|
304
318
|
window.addEventListener("online", () => {
|
|
305
|
-
void this.
|
|
319
|
+
void this.o();
|
|
306
320
|
});
|
|
307
321
|
if (navigator.onLine) {
|
|
308
|
-
void this.
|
|
322
|
+
void this.o();
|
|
309
323
|
}
|
|
310
324
|
}
|
|
311
325
|
push(event) {
|
|
@@ -315,32 +329,49 @@ var EventQueue = class {
|
|
|
315
329
|
}
|
|
316
330
|
}
|
|
317
331
|
async flush(isUnloading = false) {
|
|
318
|
-
if (this.
|
|
332
|
+
if (this.k && !isUnloading) return;
|
|
319
333
|
if (this.b.length === 0) return;
|
|
320
|
-
this.
|
|
334
|
+
this.k = true;
|
|
321
335
|
const batch = this.b.splice(0);
|
|
322
336
|
const payload = { batch };
|
|
323
337
|
const ok = await sendBatch(payload, this.a, isUnloading);
|
|
324
338
|
if (!ok) {
|
|
325
|
-
|
|
326
|
-
const trimmed = [...this.n(), ...batch].slice(-MAX_OFFLINE);
|
|
327
|
-
localStorage.setItem(OFFLINE_KEY, JSON.stringify(trimmed));
|
|
328
|
-
} catch (e) {
|
|
329
|
-
}
|
|
339
|
+
this.t([...this.p(), ...batch].slice(-50));
|
|
330
340
|
}
|
|
331
|
-
this.
|
|
341
|
+
this.k = false;
|
|
332
342
|
}
|
|
333
|
-
async
|
|
334
|
-
const stored = this.
|
|
343
|
+
async o() {
|
|
344
|
+
const stored = this.p();
|
|
335
345
|
if (stored.length === 0) return;
|
|
346
|
+
this.clearStored();
|
|
347
|
+
const payload = { batch: stored };
|
|
348
|
+
await sendBatch(payload, this.a);
|
|
349
|
+
}
|
|
350
|
+
/** Give events still waiting the ids they lacked (storage was just allowed). */
|
|
351
|
+
stamp(anonymousId, sessionId) {
|
|
352
|
+
for (const e of this.b) if (!e.anonymousId) Object.assign(e, { anonymousId, sessionId });
|
|
353
|
+
}
|
|
354
|
+
/** Drop the retry queue, wherever it is kept. */
|
|
355
|
+
clearStored() {
|
|
356
|
+
this.j = [];
|
|
336
357
|
try {
|
|
337
358
|
localStorage.removeItem(OFFLINE_KEY);
|
|
338
359
|
} catch (e) {
|
|
339
360
|
}
|
|
340
|
-
const payload = { batch: stored };
|
|
341
|
-
await sendBatch(payload, this.a);
|
|
342
361
|
}
|
|
343
|
-
|
|
362
|
+
/** In localStorage only with persistence 'local'; in memory otherwise. */
|
|
363
|
+
t(events) {
|
|
364
|
+
if (this.a.persistence !== "local") {
|
|
365
|
+
this.j = events;
|
|
366
|
+
return;
|
|
367
|
+
}
|
|
368
|
+
try {
|
|
369
|
+
localStorage.setItem(OFFLINE_KEY, JSON.stringify(events));
|
|
370
|
+
} catch (e) {
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
p() {
|
|
374
|
+
if (this.a.persistence !== "local") return this.j;
|
|
344
375
|
try {
|
|
345
376
|
const raw = localStorage.getItem(OFFLINE_KEY);
|
|
346
377
|
if (!raw) return [];
|
|
@@ -351,9 +382,40 @@ var EventQueue = class {
|
|
|
351
382
|
}
|
|
352
383
|
};
|
|
353
384
|
|
|
385
|
+
// src/core/url.ts
|
|
386
|
+
var KEEP = /^(utm_\w+|ref)$/;
|
|
387
|
+
function cleanSearch(search) {
|
|
388
|
+
const out = new URLSearchParams();
|
|
389
|
+
new URLSearchParams(search).forEach((v, k) => {
|
|
390
|
+
if (KEEP.test(k)) out.append(k, v);
|
|
391
|
+
});
|
|
392
|
+
const s = out.toString();
|
|
393
|
+
return s ? "?" + s : "";
|
|
394
|
+
}
|
|
395
|
+
function cleanHash(hash) {
|
|
396
|
+
const route = hash.split("?")[0];
|
|
397
|
+
return route.includes("=") ? "" : route;
|
|
398
|
+
}
|
|
399
|
+
function cleanUrl(href, hashMode) {
|
|
400
|
+
try {
|
|
401
|
+
const u = new URL(href);
|
|
402
|
+
return u.origin + u.pathname + cleanSearch(u.search) + (hashMode ? cleanHash(u.hash) : "");
|
|
403
|
+
} catch (e) {
|
|
404
|
+
return "";
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
function cleanReferrer(ref) {
|
|
408
|
+
try {
|
|
409
|
+
const u = new URL(ref);
|
|
410
|
+
return u.origin + u.pathname;
|
|
411
|
+
} catch (e) {
|
|
412
|
+
return "";
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
|
|
354
416
|
// src/collectors/page.ts
|
|
355
417
|
function pagePath(loc, hashMode) {
|
|
356
|
-
return loc.pathname + loc.search + (hashMode ? loc.hash : "");
|
|
418
|
+
return loc.pathname + cleanSearch(loc.search) + (hashMode ? cleanHash(loc.hash) : "");
|
|
357
419
|
}
|
|
358
420
|
function patchHistory(onNavigate, hashMode) {
|
|
359
421
|
if (typeof window === "undefined") return () => {
|
|
@@ -379,9 +441,9 @@ function patchHistory(onNavigate, hashMode) {
|
|
|
379
441
|
|
|
380
442
|
// src/collectors/context.ts
|
|
381
443
|
var PAYMENT_HOST = /^https?:\/\/[^/]*(stripe\.com|paypal\.com|paddle\.com|lemonsqueezy\.com|gumroad\.com)(\/|$)/i;
|
|
382
|
-
function buildContext(overrides, hashMode) {
|
|
383
|
-
var _a, _b, _c, _d, _e, _f, _g, _h
|
|
384
|
-
const sdkVersion = "0.
|
|
444
|
+
function buildContext(overrides, hashMode, local) {
|
|
445
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
446
|
+
const sdkVersion = "0.4.1" ;
|
|
385
447
|
if (typeof window === "undefined") {
|
|
386
448
|
return {
|
|
387
449
|
page: { path: (_a = overrides == null ? void 0 : overrides.path) != null ? _a : "", url: "", title: (_b = overrides == null ? void 0 : overrides.title) != null ? _b : "", referrer: (_c = overrides == null ? void 0 : overrides.referrer) != null ? _c : "" },
|
|
@@ -396,18 +458,19 @@ function buildContext(overrides, hashMode) {
|
|
|
396
458
|
return {
|
|
397
459
|
page: {
|
|
398
460
|
path: (_e = overrides == null ? void 0 : overrides.path) != null ? _e : pagePath(location, hashMode),
|
|
399
|
-
url: location.href,
|
|
461
|
+
url: cleanUrl(location.href, hashMode),
|
|
400
462
|
title: (_f = overrides == null ? void 0 : overrides.title) != null ? _f : document.title,
|
|
401
463
|
// First touch survives the round trip: a /thanks page reached from Stripe
|
|
402
|
-
// reports the referrer
|
|
403
|
-
// — otherwise every sale files itself under the
|
|
404
|
-
|
|
464
|
+
// reports the referrer the visit STARTED with (stored with 'local'), and
|
|
465
|
+
// never checkout.stripe.com — otherwise every sale files itself under the
|
|
466
|
+
// payment host. Without storage the server's visit already holds it.
|
|
467
|
+
referrer: cleanReferrer(liveReferrer === "" || PAYMENT_HOST.test(liveReferrer) ? local && getStoredReferrer() || "" : liveReferrer)
|
|
405
468
|
},
|
|
406
469
|
// Device class from the viewport width; still required by /api/collect
|
|
407
470
|
device: { width, height: innerHeight, type: width <= 768 ? "mobile" : width <= 1024 ? "tablet" : "desktop" },
|
|
408
|
-
utm: (
|
|
471
|
+
utm: (_g = parseUtm(location.search)) != null ? _g : local ? getStoredFirstUtm() : void 0,
|
|
409
472
|
locale: navigator.language,
|
|
410
|
-
timezone: (
|
|
473
|
+
timezone: (_h = Intl.DateTimeFormat().resolvedOptions().timeZone) != null ? _h : "UTC",
|
|
411
474
|
sdkVersion
|
|
412
475
|
};
|
|
413
476
|
}
|
|
@@ -578,9 +641,9 @@ function trackEngagement() {
|
|
|
578
641
|
window.addEventListener("scroll", sample);
|
|
579
642
|
reset();
|
|
580
643
|
return {
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
644
|
+
u: sample,
|
|
645
|
+
w: reset,
|
|
646
|
+
x(measure) {
|
|
584
647
|
if (measure) sample();
|
|
585
648
|
tick();
|
|
586
649
|
if (!shouldSendEngagement(ms, scroll, sent)) return null;
|
|
@@ -599,17 +662,17 @@ function unseen() {
|
|
|
599
662
|
}
|
|
600
663
|
var IndieBob = class _IndieBob {
|
|
601
664
|
constructor(config) {
|
|
602
|
-
this.f = null;
|
|
603
|
-
this.k = null;
|
|
604
665
|
this.g = null;
|
|
666
|
+
this.m = null;
|
|
667
|
+
this.h = null;
|
|
605
668
|
/** Engagement meter for the current page (browser only). */
|
|
606
|
-
this.
|
|
669
|
+
this.e = null;
|
|
607
670
|
/** Context of the page last counted — what an engagement event describes. */
|
|
608
|
-
this.
|
|
671
|
+
this.n = null;
|
|
609
672
|
/** A first pageview waiting for the tab to become visible. */
|
|
610
|
-
this.
|
|
673
|
+
this.i = false;
|
|
611
674
|
this.a = config;
|
|
612
|
-
this.b = new EventQueue(config, () => this.
|
|
675
|
+
this.b = new EventQueue(config, () => this.s(true));
|
|
613
676
|
if (typeof window !== "undefined") {
|
|
614
677
|
try {
|
|
615
678
|
if (applyIgnore(window.location.search, localStorage)) {
|
|
@@ -617,17 +680,17 @@ var IndieBob = class _IndieBob {
|
|
|
617
680
|
}
|
|
618
681
|
} catch (e) {
|
|
619
682
|
}
|
|
620
|
-
initAttribution(window.location.search, document.referrer);
|
|
621
|
-
this.
|
|
683
|
+
if (this.c && isTrackingAllowed(config)) initAttribution(window.location.search, document.referrer);
|
|
684
|
+
this.e = trackEngagement();
|
|
622
685
|
window.addEventListener("pageshow", (e) => {
|
|
623
|
-
if (e.persisted && this.
|
|
624
|
-
this.
|
|
625
|
-
this.page(this.
|
|
686
|
+
if (e.persisted && this.f !== void 0) {
|
|
687
|
+
this.f = void 0;
|
|
688
|
+
this.page(this.q);
|
|
626
689
|
}
|
|
627
690
|
});
|
|
628
691
|
if (config.autoDetect !== false) {
|
|
629
692
|
const opts = typeof config.autoDetect === "object" ? config.autoDetect : {};
|
|
630
|
-
this.
|
|
693
|
+
this.m = initClickTracking(
|
|
631
694
|
(event, properties) => this.track(event, properties),
|
|
632
695
|
opts.dataAttributes !== false,
|
|
633
696
|
opts.fileDownloads !== false,
|
|
@@ -662,14 +725,14 @@ var IndieBob = class _IndieBob {
|
|
|
662
725
|
page(overrides) {
|
|
663
726
|
var _a;
|
|
664
727
|
if (!isTrackingAllowed(this.a)) return;
|
|
665
|
-
if (this.
|
|
666
|
-
this.
|
|
667
|
-
if (!this.
|
|
668
|
-
this.
|
|
728
|
+
if (this.f === void 0 && unseen()) {
|
|
729
|
+
this.r = overrides;
|
|
730
|
+
if (!this.i) {
|
|
731
|
+
this.i = true;
|
|
669
732
|
const go = () => {
|
|
670
|
-
if (this.
|
|
671
|
-
this.
|
|
672
|
-
this.page(this.
|
|
733
|
+
if (this.i && !unseen()) {
|
|
734
|
+
this.i = false;
|
|
735
|
+
this.page(this.r);
|
|
673
736
|
}
|
|
674
737
|
};
|
|
675
738
|
document.addEventListener("visibilitychange", go);
|
|
@@ -677,34 +740,34 @@ var IndieBob = class _IndieBob {
|
|
|
677
740
|
}
|
|
678
741
|
return;
|
|
679
742
|
}
|
|
680
|
-
const ctx = buildContext(overrides, this.a.hashMode);
|
|
681
|
-
if (ctx.page.path === this.
|
|
682
|
-
this.
|
|
683
|
-
this.
|
|
684
|
-
this.
|
|
685
|
-
this.
|
|
686
|
-
if (this.
|
|
687
|
-
this.
|
|
688
|
-
setTimeout(this.
|
|
743
|
+
const ctx = buildContext(overrides, this.a.hashMode, this.c);
|
|
744
|
+
if (ctx.page.path === this.f) return;
|
|
745
|
+
this.s(false);
|
|
746
|
+
this.f = ctx.page.path;
|
|
747
|
+
this.q = overrides;
|
|
748
|
+
this.n = ctx;
|
|
749
|
+
if (this.e) {
|
|
750
|
+
this.e.w();
|
|
751
|
+
setTimeout(this.e.u, 1e3);
|
|
689
752
|
}
|
|
690
|
-
this.b.push(this.
|
|
753
|
+
this.b.push(this.d("page", { context: ctx }));
|
|
691
754
|
if (this.a.autoDetect !== false) {
|
|
692
755
|
const path = ctx.page.path;
|
|
693
756
|
const opts = typeof this.a.autoDetect === "object" ? this.a.autoDetect : {};
|
|
694
757
|
const intent = detectIntent(path, opts);
|
|
695
758
|
if (intent) {
|
|
696
|
-
this.b.push(this.
|
|
759
|
+
this.b.push(this.d("track", {
|
|
697
760
|
event: intent,
|
|
698
761
|
properties: { auto: true },
|
|
699
762
|
context: ctx
|
|
700
763
|
}));
|
|
701
764
|
log(this.a, `auto-detected: ${intent} on ${path}`);
|
|
702
765
|
if (opts.formSubmit !== false) {
|
|
703
|
-
(_a = this.
|
|
766
|
+
(_a = this.h) == null ? void 0 : _a.call(this);
|
|
704
767
|
const submitEvent = intentToSubmitEvent(intent);
|
|
705
768
|
if (submitEvent) {
|
|
706
|
-
this.
|
|
707
|
-
this.b.push(this.
|
|
769
|
+
this.h = observeFormSubmits(submitEvent, (eventName) => {
|
|
770
|
+
this.b.push(this.d("track", {
|
|
708
771
|
event: eventName,
|
|
709
772
|
properties: { auto: true }
|
|
710
773
|
}));
|
|
@@ -724,7 +787,7 @@ var IndieBob = class _IndieBob {
|
|
|
724
787
|
*/
|
|
725
788
|
track(event, properties) {
|
|
726
789
|
if (!isTrackingAllowed(this.a)) return;
|
|
727
|
-
this.b.push(this.
|
|
790
|
+
this.b.push(this.d("track", { event, properties }));
|
|
728
791
|
}
|
|
729
792
|
/**
|
|
730
793
|
* Associate the current anonymous visitor with a known user ID.
|
|
@@ -749,18 +812,19 @@ var IndieBob = class _IndieBob {
|
|
|
749
812
|
*/
|
|
750
813
|
identify(userId, traits, options) {
|
|
751
814
|
if (!isTrackingAllowed(this.a)) return;
|
|
752
|
-
this.
|
|
753
|
-
this.b.push(this.
|
|
754
|
-
|
|
755
|
-
|
|
815
|
+
this.l = userId;
|
|
816
|
+
this.b.push(this.d("identify", { traits, userId }));
|
|
817
|
+
const known = typeof (options == null ? void 0 : options.isNew) === "boolean";
|
|
818
|
+
if (this.a.autoDetect !== false && (known || this.c)) {
|
|
819
|
+
const first = known ? options.isNew : isFirstIdentify();
|
|
756
820
|
const eventName = first ? "signup" : "login";
|
|
757
|
-
this.b.push(this.
|
|
821
|
+
this.b.push(this.d("track", {
|
|
758
822
|
event: eventName,
|
|
759
823
|
// `auto` says where the verdict came from, so a funnel that looks
|
|
760
824
|
// wrong later can be traced to a guess rather than to the server.
|
|
761
|
-
properties: { auto:
|
|
825
|
+
properties: { auto: !known }
|
|
762
826
|
}));
|
|
763
|
-
markIdentified();
|
|
827
|
+
if (this.c) markIdentified();
|
|
764
828
|
log(this.a, `${eventName} for ${userId}`);
|
|
765
829
|
}
|
|
766
830
|
}
|
|
@@ -773,7 +837,7 @@ var IndieBob = class _IndieBob {
|
|
|
773
837
|
revenue(data) {
|
|
774
838
|
var _a;
|
|
775
839
|
if (!isTrackingAllowed(this.a)) return;
|
|
776
|
-
this.b.push(this.
|
|
840
|
+
this.b.push(this.d("revenue", {
|
|
777
841
|
revenue: {
|
|
778
842
|
amount: data.amount,
|
|
779
843
|
currency: (_a = data.currency) != null ? _a : "USD",
|
|
@@ -791,11 +855,11 @@ var IndieBob = class _IndieBob {
|
|
|
791
855
|
void this.b.flush();
|
|
792
856
|
optOut();
|
|
793
857
|
clearIdentified();
|
|
794
|
-
this.
|
|
795
|
-
(_a = this.
|
|
796
|
-
(_b = this.
|
|
797
|
-
this.
|
|
798
|
-
this.
|
|
858
|
+
this.l = void 0;
|
|
859
|
+
(_a = this.m) == null ? void 0 : _a.call(this);
|
|
860
|
+
(_b = this.h) == null ? void 0 : _b.call(this);
|
|
861
|
+
this.m = null;
|
|
862
|
+
this.h = null;
|
|
799
863
|
log(this.a, "opted out");
|
|
800
864
|
}
|
|
801
865
|
/** Re-enable tracking after optOut(). */
|
|
@@ -818,13 +882,42 @@ var IndieBob = class _IndieBob {
|
|
|
818
882
|
async flush() {
|
|
819
883
|
await this.b.flush();
|
|
820
884
|
}
|
|
821
|
-
/**
|
|
885
|
+
/** The stored anonymous ID with `persistence: 'local'`; '' without storage. */
|
|
822
886
|
getAnonymousId() {
|
|
823
|
-
return getAnonymousId();
|
|
887
|
+
return this.c ? getAnonymousId() : "";
|
|
824
888
|
}
|
|
825
|
-
/**
|
|
889
|
+
/** The stored session ID with `persistence: 'local'`; '' without storage. */
|
|
826
890
|
getSessionId() {
|
|
827
|
-
return getSessionId();
|
|
891
|
+
return this.c ? getSessionId() : "";
|
|
892
|
+
}
|
|
893
|
+
/**
|
|
894
|
+
* Switch storage on or off — call it from your consent banner.
|
|
895
|
+
* `'local'` starts storing the visitor id and first-touch attribution from
|
|
896
|
+
* this page on; `'none'` removes everything the tracker stored.
|
|
897
|
+
*
|
|
898
|
+
* @example
|
|
899
|
+
* onConsent(() => bob.setPersistence('local'))
|
|
900
|
+
* onConsentWithdrawn(() => bob.setPersistence('none'))
|
|
901
|
+
*/
|
|
902
|
+
setPersistence(mode) {
|
|
903
|
+
if (mode !== "local" && mode !== "none") return;
|
|
904
|
+
this.a.persistence = mode;
|
|
905
|
+
if (mode === "local") {
|
|
906
|
+
if (typeof window !== "undefined" && isTrackingAllowed(this.a)) {
|
|
907
|
+
initAttribution(location.search, document.referrer);
|
|
908
|
+
this.b.stamp(getAnonymousId(), getSessionId());
|
|
909
|
+
}
|
|
910
|
+
} else {
|
|
911
|
+
clearAnonymousId();
|
|
912
|
+
clearSession();
|
|
913
|
+
clearAttribution();
|
|
914
|
+
clearIdentified();
|
|
915
|
+
this.b.clearStored();
|
|
916
|
+
}
|
|
917
|
+
log(this.a, `persistence: ${mode}`);
|
|
918
|
+
}
|
|
919
|
+
get c() {
|
|
920
|
+
return this.a.persistence === "local";
|
|
828
921
|
}
|
|
829
922
|
/** Get the resolved configuration (read-only). */
|
|
830
923
|
getConfig() {
|
|
@@ -840,12 +933,12 @@ var IndieBob = class _IndieBob {
|
|
|
840
933
|
*/
|
|
841
934
|
enableAutoPage() {
|
|
842
935
|
var _a;
|
|
843
|
-
(_a = this.
|
|
844
|
-
this.
|
|
936
|
+
(_a = this.g) == null ? void 0 : _a.call(this);
|
|
937
|
+
this.g = patchHistory(() => this.page(), this.a.hashMode);
|
|
845
938
|
return () => {
|
|
846
939
|
var _a2;
|
|
847
|
-
(_a2 = this.
|
|
848
|
-
this.
|
|
940
|
+
(_a2 = this.g) == null ? void 0 : _a2.call(this);
|
|
941
|
+
this.g = null;
|
|
849
942
|
};
|
|
850
943
|
}
|
|
851
944
|
/**
|
|
@@ -853,14 +946,14 @@ var IndieBob = class _IndieBob {
|
|
|
853
946
|
* worth sending. `measure`: sample the scroll first (false on an SPA
|
|
854
947
|
* change, when the DOM already shows the next page).
|
|
855
948
|
*/
|
|
856
|
-
|
|
949
|
+
s(measure) {
|
|
857
950
|
var _a;
|
|
858
|
-
const reading = this.
|
|
951
|
+
const reading = this.n && ((_a = this.e) == null ? void 0 : _a.x(measure));
|
|
859
952
|
if (reading && isTrackingAllowed(this.a)) {
|
|
860
|
-
this.b.push(this.
|
|
953
|
+
this.b.push(this.d("engagement", { context: this.n, engagement: reading }));
|
|
861
954
|
}
|
|
862
955
|
}
|
|
863
|
-
|
|
956
|
+
d(type, extras) {
|
|
864
957
|
var _a, _b;
|
|
865
958
|
return {
|
|
866
959
|
...extras,
|
|
@@ -868,11 +961,11 @@ var IndieBob = class _IndieBob {
|
|
|
868
961
|
id: generateId(),
|
|
869
962
|
projectId: this.a.projectId,
|
|
870
963
|
type,
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
964
|
+
// Without storage the server derives both from its daily hash
|
|
965
|
+
...this.c ? { anonymousId: getAnonymousId(), sessionId: getSessionId() } : {},
|
|
966
|
+
userId: (_a = this.l) != null ? _a : extras.userId,
|
|
874
967
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
875
|
-
context: (_b = extras.context) != null ? _b : buildContext(void 0, this.a.hashMode)
|
|
968
|
+
context: (_b = extras.context) != null ? _b : buildContext(void 0, this.a.hashMode, this.c)
|
|
876
969
|
};
|
|
877
970
|
}
|
|
878
971
|
};
|
package/dist/vue.global.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var IndieBob=(function(exports){'use strict';var it="https://www.indiebob.com/api/collect";function O(e){if(!e.projectId||!e.projectId.startsWith("proj_"))throw new Error(`[IndieBob] Invalid projectId "${e.projectId}". Must start with "proj_".`);return {projectId:e.projectId,endpoint:e.endpoint??it,debug:e.debug??false,respectDnt:e.respectDnt??true,respectGpc:e.respectGpc??true,autoDetect:e.autoDetect??true,hashMode:e.hashMode??false}}var l="_ib_anon";function u(){let e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-",t=new Uint8Array(21);if(typeof crypto<"u"&&crypto.getRandomValues)crypto.getRandomValues(t);else for(let o=0;o<21;o++)t[o]=Math.random()*64;let n="";for(let o of t)n+=e[o&63];return n}function b(){try{let e=localStorage.getItem(l);return e||(e=u(),localStorage.setItem(l,e)),e}catch{try{let e=sessionStorage.getItem(l);return e||(e=u(),sessionStorage.setItem(l,e)),e}catch{return u()}}}function A(){try{localStorage.removeItem(l);}catch{}try{sessionStorage.removeItem(l);}catch{}}var I="_ib_session",E="_ib_session_last",st=1800*1e3;function D(){try{return crypto.randomUUID()}catch{return u()}}function S(){try{let e=Date.now(),t=parseInt(sessionStorage.getItem(E)??"0",10),n=sessionStorage.getItem(I),o=t>0&&e-t>st;return (!n||o)&&(n=D(),sessionStorage.setItem(I,n)),sessionStorage.setItem(E,String(e)),n}catch{return D()}}function N(){try{sessionStorage.removeItem(I);}catch{}try{sessionStorage.removeItem(E);}catch{}}var g="_ib_first_utm",M="_ib_last_utm",m="_ib_referrer";function w(e){let t=new URLSearchParams(e),n={},o=false;!t.has("utm_source")&&t.get("ref")&&(n.source=t.get("ref"),o=true);for(let r of ["source","medium","campaign","term","content"])t.has("utm_"+r)&&(n[r]=t.get("utm_"+r),o=true);return o?n:null}function L(e,t){let n=w(e);try{n&&!localStorage.getItem(g)&&localStorage.setItem(g,JSON.stringify(n)),n&&localStorage.setItem(M,JSON.stringify(n)),t&&!localStorage.getItem(m)&&localStorage.setItem(m,t);}catch{}}function U(){try{let e=localStorage.getItem(g);return e?JSON.parse(e):void 0}catch{return}}function F(){try{return localStorage.getItem(m)??void 0}catch{return}}function j(){try{localStorage.removeItem(g);}catch{}try{localStorage.removeItem(M);}catch{}try{localStorage.removeItem(m);}catch{}}var f="ib_ignore";function K(e,t){let n=new URLSearchParams(e).get(f);return n==="1"?t.setItem(f,"1"):n==="0"&&t.removeItem(f),t.getItem(f)==="1"}function _(){try{return localStorage.getItem(f)==="1"}catch{return false}}function B(){return typeof navigator<"u"&&navigator.webdriver===true||_()}var h="_ib_optout",at="_ib_queue";function d(e){if(B())return false;try{if(localStorage.getItem(h))return !1}catch{}return !(e.respectDnt&&typeof navigator<"u"&&(navigator.doNotTrack==="1"||navigator.msDoNotTrack==="1")||e.respectGpc&&typeof navigator<"u"&&navigator.globalPrivacyControl===true)}function Y(){try{localStorage.setItem(h,"1");}catch{}A(),N(),j();try{localStorage.removeItem(at);}catch{}}function z(){try{localStorage.removeItem(h);}catch{}}function $(){try{return !!localStorage.getItem(h)}catch{return false}}function a(e,...t){e.debug&&console.log("[IndieBob]",...t);}async function x(e,t,n=false){let o=JSON.stringify(e);if(n&&typeof navigator<"u"&&navigator.sendBeacon){let r=new Blob([o],{type:"text/plain;charset=UTF-8"}),i=navigator.sendBeacon(t.endpoint,r);return a(t,"sendBeacon:",i,e.batch.length,"events"),i}for(let r=0;r<3;r++){try{let i=await fetch(t.endpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:o,keepalive:!0});if(i.ok)return a(t,"sent:",e.batch.length,"events"),!0;if(i.status>=400&&i.status<500)return a(t,"4xx error, not retrying:",i.status),!1}catch(i){a(t,"fetch error (attempt",r+1,"):",i);}r<2&&await new Promise(i=>setTimeout(i,1e3<<r));}return a(t,"failed to send after",3,"attempts"),false}var k="_ib_queue",ct=10,ut=5e3,lt=50,v=class{constructor(t,n){this.e=[];this.c=false;if(this.t=t,setInterval(()=>{this.e.length>0&&this.flush();},ut),typeof window>"u")return;let o=()=>{n?.(),this.flush(true);};document.addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"&&o();}),window.addEventListener("pagehide",o),window.addEventListener("online",()=>{this.p();}),navigator.onLine&&this.p();}push(t){this.e.push(t),this.e.length>=ct&&this.flush();}async flush(t=false){if(this.c&&!t||this.e.length===0)return;this.c=true;let n=this.e.splice(0);if(!await x({batch:n},this.t,t))try{let i=[...this.f(),...n].slice(-lt);localStorage.setItem(k,JSON.stringify(i));}catch{}this.c=false;}async p(){let t=this.f();if(t.length===0)return;try{localStorage.removeItem(k);}catch{}await x({batch:t},this.t);}f(){try{let t=localStorage.getItem(k);return t?JSON.parse(t):[]}catch{return []}}};function X(e,t){return e.pathname+e.search+(t?e.hash:"")}function H(e,t){if(typeof window>"u")return ()=>{};let n=history.pushState.bind(history),o=history.replaceState.bind(history);return history.pushState=function(...r){n(...r),e();},history.replaceState=function(...r){o(...r);},window.addEventListener("popstate",e),t&&window.addEventListener("hashchange",e),()=>{history.pushState=n,history.replaceState=o,window.removeEventListener("popstate",e),window.removeEventListener("hashchange",e);}}var dt=/^https?:\/\/[^/]*(stripe\.com|paypal\.com|paddle\.com|lemonsqueezy\.com|gumroad\.com)(\/|$)/i;function T(e,t){let n="0.3.0";if(typeof window>"u")return {page:{path:e?.path??"",url:"",title:e?.title??"",referrer:e?.referrer??""},device:{width:0,height:0,type:"desktop"},locale:"en",timezone:"UTC",sdkVersion:n};let o=e?.referrer??document.referrer,r=innerWidth;return {page:{path:e?.path??X(location,t),url:location.href,title:e?.title??document.title,referrer:o===""||dt.test(o)?F()??o:o},device:{width:r,height:innerHeight,type:r<=768?"mobile":r<=1024?"tablet":"desktop"},utm:w(location.search)??U(),locale:navigator.language,timezone:Intl.DateTimeFormat().resolvedOptions().timeZone??"UTC",sdkVersion:n}}var pt=[["signup","signup_start",/\/(sign-?up|register|join|create-?account|get-?started|onboard|registro|inscription|s-?inscrire|anmeldung|registrieren|cadastro|registrazione|aanmelden|inschrijven)/i],["login","login_view",/\/(log-?in|sign-?in|auth(\/login)?|iniciar-?sesion|connexion|se-?connecter|anmelden|einloggen|entrar|accesso|accedi|inloggen)/i],["pricing","pricing_view",/\/(pricing|plans|upgrade|subscribe|precios|tarifs|preise|precos|prezzi|prijzen)/i],["checkout","checkout_view",/\/(checkout|cart|basket|pay(ment)?|order|comprar|pagar|panier|caisse|warenkorb|kasse|carrinho|carrello|winkelwagen)/i],["success","success_view",/\/(success|thank-?you|thanks|confirmation|confirmed|complete[d]?|gracias|merci|danke|obrigado|grazie|bedankt)/i],["onboarding","onboarding_view",/\/(onboarding|welcome|getting-?started|setup|bienvenido|bienvenue|willkommen|benvenuto|welkom)/i],["contact","contact_view",/\/(contact|contacto|kontakt|contato|contatto|nous-?contacter)/i]];function ft(e,t){return e instanceof RegExp?e.test(t):t.includes(e)}function V(e,t){for(let[n,o,r]of pt)if((t?.[`${n}Paths`]??[r]).some(c=>ft(c,e)))return o;return null}function G(e){let t=/^(signup|login|checkout)_/.exec(e);return t?t[1]+"_submit":null}function J(e,t){if(typeof document>"u")return ()=>{};let n=o=>{o.target instanceof HTMLFormElement&&t(e);};return document.addEventListener("submit",n,true),()=>document.removeEventListener("submit",n,true)}var R="ib_identified";function W(){return typeof localStorage>"u"?true:!localStorage.getItem(R)}function q(){typeof localStorage>"u"||localStorage.setItem(R,"1");}function Q(){typeof localStorage>"u"||localStorage.removeItem(R);}var Z="data-ib-event",tt="data-ib-";function et(e){for(;e&&e!==document.body;){let t=e.getAttribute(Z);if(t){let n={auto:true};for(let o of e.attributes)o.name.startsWith(tt)&&o.name!==Z&&(n[o.name.slice(tt.length)]=o.value);return [t,n]}e=e.parentElement;}return null}var gt=/\.(pdf|zip|dmg|exe|msi|pkg|apk|ipa|deb|rpm|appimage|t?gz|bz2|xz|tar|7z|rar|csv|xlsx?|docx?|pptx?|txt|epub|mp3|wav|mp4|mov|iso)$/i;function mt(e){let t=gt.exec(e);return t?t[1].toLowerCase():null}function ht(e,t,n,o){if(!/^https?:\/\//i.test(e))return null;try{let r=new URL(e),i=n&&mt(r.pathname);if(i)return ["file_download",{auto:!0,url:r.origin+r.pathname,path:r.pathname,ext:i}];if(o&&r.hostname!==t)return ["outbound_click",{auto:!0,url:e,hostname:r.hostname}]}catch{}return null}function nt(e,t,n,o){if(typeof document>"u")return ()=>{};let r=i=>{let c=i.target,s=c?.closest?.("a");for(let p of [t&&et(c),s&&ht(s.href,location.hostname,n,o)])p&&e(p[0],p[1]);};return document.addEventListener("click",r,true),()=>document.removeEventListener("click",r,true)}function vt(e,t,n){return t>n||e>=3e3}function yt(e,t,n){return n>0?Math.min(100,Math.round((e+t)/n*100)):0}function ot(){let e=0,t=0,n=0,o=0,r=()=>{let s=Date.now();t&&(e+=s-t),t=document.visibilityState==="visible"&&document.hasFocus()?s:0;},i=()=>{n=Math.max(n,yt(scrollY,innerHeight,Math.max(document.documentElement.scrollHeight,document.body?.scrollHeight??0)));},c=()=>{e=n=o=t=0,r();};for(let s of ["focus","blur"])window.addEventListener(s,r);return document.addEventListener("visibilitychange",r),window.addEventListener("scroll",i),c(),{y:i,b:c,I(s){if(s&&i(),r(),!vt(e,n,o))return null;let p={ms:Math.min(e,864e5),scroll:n};return e=0,o=n,p}}}var C={};function rt(){return typeof document<"u"&&(document.visibilityState==="hidden"||document.prerendering===true)}var y=class e{constructor(t){this.i=null;this.l=null;this.s=null;this.o=null;this.d=null;this.a=false;if(this.t=t,this.e=new v(t,()=>this.h(true)),typeof window<"u"){try{K(window.location.search,localStorage)&&console.info("IndieBob: this browser is excluded from analytics (ib_ignore)");}catch{}if(L(window.location.search,document.referrer),this.o=ot(),window.addEventListener("pageshow",n=>{n.persisted&&this.r!==void 0&&(this.r=void 0,this.page(this.g));}),t.autoDetect!==false){let n=typeof t.autoDetect=="object"?t.autoDetect:{};this.l=nt((o,r)=>this.track(o,r),n.dataAttributes!==false,n.fileDownloads!==false,n.outboundClicks!==false);}}}static init(t){var o;let n=O(t);return typeof window>"u"?new e(n):C[o=n.projectId]??(C[o]=new e(n))}page(t){if(!d(this.t))return;if(this.r===void 0&&rt()){if(this.m=t,!this.a){this.a=true;let o=()=>{this.a&&!rt()&&(this.a=false,this.page(this.m));};document.addEventListener("visibilitychange",o),document.addEventListener("prerenderingchange",o);}return}let n=T(t,this.t.hashMode);if(n.page.path!==this.r&&(this.h(false),this.r=n.page.path,this.g=t,this.d=n,this.o&&(this.o.b(),setTimeout(this.o.y,1e3)),this.e.push(this.n("page",{context:n})),this.t.autoDetect!==false)){let o=n.page.path,r=typeof this.t.autoDetect=="object"?this.t.autoDetect:{},i=V(o,r);if(i&&(this.e.push(this.n("track",{event:i,properties:{auto:true},context:n})),a(this.t,`auto-detected: ${i} on ${o}`),r.formSubmit!==false)){this.s?.();let c=G(i);c&&(this.s=J(c,s=>{this.e.push(this.n("track",{event:s,properties:{auto:true}})),a(this.t,`auto-detected: ${s}`);}));}}}track(t,n){d(this.t)&&this.e.push(this.n("track",{event:t,properties:n}));}identify(t,n,o){if(d(this.t)&&(this.u=t,this.e.push(this.n("identify",{traits:n,userId:t})),this.t.autoDetect!==false)){let i=(typeof o?.isNew=="boolean"?o.isNew:W())?"signup":"login";this.e.push(this.n("track",{event:i,properties:{auto:typeof o?.isNew!="boolean"}})),q(),a(this.t,`${i} for ${t}`);}}revenue(t){d(this.t)&&this.e.push(this.n("revenue",{revenue:{amount:t.amount,currency:t.currency??"USD",plan:t.plan,type:t.type}}));}optOut(){this.e.flush(),Y(),Q(),this.u=void 0,this.l?.(),this.s?.(),this.l=null,this.s=null,a(this.t,"opted out");}optIn(){z(),a(this.t,"opted in");}isOptedOut(){return $()}isIgnored(){return _()}async flush(){await this.e.flush();}getAnonymousId(){return b()}getSessionId(){return S()}getConfig(){return Object.freeze({...this.t})}enableAutoPage(){return this.i?.(),this.i=H(()=>this.page(),this.t.hashMode),()=>{this.i?.(),this.i=null;}}h(t){let n=this.d&&this.o?.I(t);n&&d(this.t)&&this.e.push(this.n("engagement",{context:this.d,engagement:n}));}n(t,n){return {...n,v:1,id:u(),projectId:this.t.projectId,type:t,anonymousId:b(),userId:this.u??n.userId,sessionId:S(),timestamp:new Date().toISOString(),context:n.context??T(void 0,this.t.hashMode)}}};var bt=Symbol("indiebob"),P=null,re={install(e,t){let n=y.init(t);P=n,e.provide(bt,n),e.config.globalProperties.$bob=n;let o=e.config.globalProperties.$router;o&&o.afterEach(()=>{n.page();});}};function ie(){if(P)return P;throw new Error("[IndieBob] useTracker() called before IndieBobPlugin was installed.")}
|
|
2
|
-
exports.IndieBob=
|
|
1
|
+
var IndieBob=(function(exports){'use strict';var lt="https://www.indiebob.com/api/collect",dt="projectId endpoint debug respectDnt respectGpc autoDetect hashMode persistence",pt="signupPaths loginPaths pricingPaths checkoutPaths successPaths onboardingPaths contactPaths dataAttributes formSubmit outboundClicks fileDownloads";function j(e,t,n){for(let o of Object.keys(e))t.split(" ").includes(o)||console.warn(`[IndieBob] Unknown option ${n}"${o}" ignored`);}function F(e){if(!e.projectId||!e.projectId.startsWith("proj_"))throw new Error(`[IndieBob] Invalid projectId "${e.projectId}". Must start with "proj_".`);return j(e,dt,""),typeof e.autoDetect=="object"&&j(e.autoDetect,pt,"autoDetect."),e.persistence!==void 0&&e.persistence!=="local"&&e.persistence!=="none"&&console.warn(`[IndieBob] persistence "${String(e.persistence)}" is not 'none' or 'local'; using 'none'`),{projectId:e.projectId,endpoint:e.endpoint??lt,debug:e.debug??false,respectDnt:e.respectDnt??true,respectGpc:e.respectGpc??true,autoDetect:e.autoDetect??true,hashMode:e.hashMode??false,persistence:e.persistence==="local"?"local":"none"}}var d="_ib_anon";function l(){let e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-",t=new Uint8Array(21);if(typeof crypto<"u"&&crypto.getRandomValues)crypto.getRandomValues(t);else for(let o=0;o<21;o++)t[o]=Math.random()*64;let n="";for(let o of t)n+=e[o&63];return n}function g(){try{let e=localStorage.getItem(d);return e||(e=l(),localStorage.setItem(d,e)),e}catch{try{let e=sessionStorage.getItem(d);return e||(e=l(),sessionStorage.setItem(d,e)),e}catch{return l()}}}function m(){try{localStorage.removeItem(d);}catch{}try{sessionStorage.removeItem(d);}catch{}}var _="_ib_session",x="_ib_session_last",ft=1800*1e3;function B(){try{return crypto.randomUUID()}catch{return l()}}function h(){try{let e=Date.now(),t=parseInt(sessionStorage.getItem(x)??"0",10),n=sessionStorage.getItem(_),o=t>0&&e-t>ft;return (!n||o)&&(n=B(),sessionStorage.setItem(_,n)),sessionStorage.setItem(x,String(e)),n}catch{return B()}}function v(){try{sessionStorage.removeItem(_);}catch{}try{sessionStorage.removeItem(x);}catch{}}var y="_ib_first_utm",K="_ib_last_utm",b="_ib_referrer";function k(e){let t=new URLSearchParams(e),n={},o=false;!t.has("utm_source")&&t.get("ref")&&(n.source=t.get("ref"),o=true);for(let r of ["source","medium","campaign","term","content"])t.has("utm_"+r)&&(n[r]=t.get("utm_"+r),o=true);return o?n:null}function R(e,t){let n=k(e);try{n&&!localStorage.getItem(y)&&localStorage.setItem(y,JSON.stringify(n)),n&&localStorage.setItem(K,JSON.stringify(n)),t&&!localStorage.getItem(b)&&localStorage.setItem(b,t);}catch{}}function $(){try{let e=localStorage.getItem(y);return e?JSON.parse(e):void 0}catch{return}}function Y(){try{return localStorage.getItem(b)??void 0}catch{return}}function I(){try{localStorage.removeItem(y);}catch{}try{localStorage.removeItem(K);}catch{}try{localStorage.removeItem(b);}catch{}}var f="ib_ignore";function z(e,t){let n=new URLSearchParams(e).get(f);return n==="1"?t.setItem(f,"1"):n==="0"&&t.removeItem(f),t.getItem(f)==="1"}function T(){try{return localStorage.getItem(f)==="1"}catch{return false}}function H(){return typeof navigator<"u"&&navigator.webdriver===true||T()}var E="_ib_optout",gt="_ib_queue";function u(e){if(H())return false;try{if(localStorage.getItem(E))return !1}catch{}return !(e.respectDnt&&typeof navigator<"u"&&(navigator.doNotTrack==="1"||navigator.msDoNotTrack==="1")||e.respectGpc&&typeof navigator<"u"&&navigator.globalPrivacyControl===true)}function X(){try{localStorage.setItem(E,"1");}catch{}m(),v(),I();try{localStorage.removeItem(gt);}catch{}}function G(){try{localStorage.removeItem(E);}catch{}}function V(){try{return !!localStorage.getItem(E)}catch{return false}}function c(e,...t){e.debug&&console.log("[IndieBob]",...t);}async function P(e,t,n=false){let o=JSON.stringify(e);if(n&&typeof navigator<"u"&&navigator.sendBeacon){let r=new Blob([o],{type:"text/plain;charset=UTF-8"}),i=navigator.sendBeacon(t.endpoint,r);return c(t,"sendBeacon:",i,e.batch.length,"events"),i}for(let r=0;r<3;r++){try{let i=await fetch(t.endpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:o,keepalive:!0});if(i.ok)return c(t,"sent:",e.batch.length,"events"),!0;if(i.status>=400&&i.status<500)return c(t,"4xx error, not retrying:",i.status),!1}catch(i){c(t,"fetch error (attempt",r+1,"):",i);}r<2&&await new Promise(i=>setTimeout(i,1e3<<r));}return c(t,"failed to send after",3,"attempts"),false}var C="_ib_queue",mt=10,ht=5e3,S=class{constructor(t,n){this.e=[];this.u=[];this.l=false;if(this.t=t,setInterval(()=>{this.e.length>0&&this.flush();},ht),typeof window>"u")return;let o=()=>{n?.(),this.flush(true);};document.addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"&&o();}),window.addEventListener("pagehide",o),window.addEventListener("online",()=>{this.g();}),navigator.onLine&&this.g();}push(t){this.e.push(t),this.e.length>=mt&&this.flush();}async flush(t=false){if(this.l&&!t||this.e.length===0)return;this.l=true;let n=this.e.splice(0);await P({batch:n},this.t,t)||this.I([...this.m(),...n].slice(-50)),this.l=false;}async g(){let t=this.m();if(t.length===0)return;this.clearStored(),await P({batch:t},this.t);}stamp(t,n){for(let o of this.e)o.anonymousId||Object.assign(o,{anonymousId:t,sessionId:n});}clearStored(){this.u=[];try{localStorage.removeItem(C);}catch{}}I(t){if(this.t.persistence!=="local"){this.u=t;return}try{localStorage.setItem(C,JSON.stringify(t));}catch{}}m(){if(this.t.persistence!=="local")return this.u;try{let t=localStorage.getItem(C);return t?JSON.parse(t):[]}catch{return []}}};var yt=/^(utm_\w+|ref)$/;function O(e){let t=new URLSearchParams;new URLSearchParams(e).forEach((o,r)=>{yt.test(r)&&t.append(r,o);});let n=t.toString();return n?"?"+n:""}function D(e){let t=e.split("?")[0];return t.includes("=")?"":t}function J(e,t){try{let n=new URL(e);return n.origin+n.pathname+O(n.search)+(t?D(n.hash):"")}catch{return ""}}function W(e){try{let t=new URL(e);return t.origin+t.pathname}catch{return ""}}function q(e,t){return e.pathname+O(e.search)+(t?D(e.hash):"")}function Q(e,t){if(typeof window>"u")return ()=>{};let n=history.pushState.bind(history),o=history.replaceState.bind(history);return history.pushState=function(...r){n(...r),e();},history.replaceState=function(...r){o(...r);},window.addEventListener("popstate",e),t&&window.addEventListener("hashchange",e),()=>{history.pushState=n,history.replaceState=o,window.removeEventListener("popstate",e),window.removeEventListener("hashchange",e);}}var bt=/^https?:\/\/[^/]*(stripe\.com|paypal\.com|paddle\.com|lemonsqueezy\.com|gumroad\.com)(\/|$)/i;function A(e,t,n){let o="0.4.1";if(typeof window>"u")return {page:{path:e?.path??"",url:"",title:e?.title??"",referrer:e?.referrer??""},device:{width:0,height:0,type:"desktop"},locale:"en",timezone:"UTC",sdkVersion:o};let r=e?.referrer??document.referrer,i=innerWidth;return {page:{path:e?.path??q(location,t),url:J(location.href,t),title:e?.title??document.title,referrer:W(r===""||bt.test(r)?n&&Y()||"":r)},device:{width:i,height:innerHeight,type:i<=768?"mobile":i<=1024?"tablet":"desktop"},utm:k(location.search)??(n?$():void 0),locale:navigator.language,timezone:Intl.DateTimeFormat().resolvedOptions().timeZone??"UTC",sdkVersion:o}}var It=[["signup","signup_start",/\/(sign-?up|register|join|create-?account|get-?started|onboard|registro|inscription|s-?inscrire|anmeldung|registrieren|cadastro|registrazione|aanmelden|inschrijven)/i],["login","login_view",/\/(log-?in|sign-?in|auth(\/login)?|iniciar-?sesion|connexion|se-?connecter|anmelden|einloggen|entrar|accesso|accedi|inloggen)/i],["pricing","pricing_view",/\/(pricing|plans|upgrade|subscribe|precios|tarifs|preise|precos|prezzi|prijzen)/i],["checkout","checkout_view",/\/(checkout|cart|basket|pay(ment)?|order|comprar|pagar|panier|caisse|warenkorb|kasse|carrinho|carrello|winkelwagen)/i],["success","success_view",/\/(success|thank-?you|thanks|confirmation|confirmed|complete[d]?|gracias|merci|danke|obrigado|grazie|bedankt)/i],["onboarding","onboarding_view",/\/(onboarding|welcome|getting-?started|setup|bienvenido|bienvenue|willkommen|benvenuto|welkom)/i],["contact","contact_view",/\/(contact|contacto|kontakt|contato|contatto|nous-?contacter)/i]];function Et(e,t){return e instanceof RegExp?e.test(t):t.includes(e)}function Z(e,t){for(let[n,o,r]of It)if((t?.[`${n}Paths`]??[r]).some(s=>Et(s,e)))return o;return null}function tt(e){let t=/^(signup|login|checkout)_/.exec(e);return t?t[1]+"_submit":null}function et(e,t){if(typeof document>"u")return ()=>{};let n=o=>{o.target instanceof HTMLFormElement&&t(e);};return document.addEventListener("submit",n,true),()=>document.removeEventListener("submit",n,true)}var N="ib_identified";function nt(){return typeof localStorage>"u"?true:!localStorage.getItem(N)}function ot(){typeof localStorage>"u"||localStorage.setItem(N,"1");}function U(){typeof localStorage>"u"||localStorage.removeItem(N);}var rt="data-ib-event",it="data-ib-";function st(e){for(;e&&e!==document.body;){let t=e.getAttribute(rt);if(t){let n={auto:true};for(let o of e.attributes)o.name.startsWith(it)&&o.name!==rt&&(n[o.name.slice(it.length)]=o.value);return [t,n]}e=e.parentElement;}return null}var St=/\.(pdf|zip|dmg|exe|msi|pkg|apk|ipa|deb|rpm|appimage|t?gz|bz2|xz|tar|7z|rar|csv|xlsx?|docx?|pptx?|txt|epub|mp3|wav|mp4|mov|iso)$/i;function wt(e){let t=St.exec(e);return t?t[1].toLowerCase():null}function _t(e,t,n,o){if(!/^https?:\/\//i.test(e))return null;try{let r=new URL(e),i=n&&wt(r.pathname);if(i)return ["file_download",{auto:!0,url:r.origin+r.pathname,path:r.pathname,ext:i}];if(o&&r.hostname!==t)return ["outbound_click",{auto:!0,url:e,hostname:r.hostname}]}catch{}return null}function at(e,t,n,o){if(typeof document>"u")return ()=>{};let r=i=>{let s=i.target,a=s?.closest?.("a");for(let p of [t&&st(s),a&&_t(a.href,location.hostname,n,o)])p&&e(p[0],p[1]);};return document.addEventListener("click",r,true),()=>document.removeEventListener("click",r,true)}function xt(e,t,n){return t>n||e>=3e3}function kt(e,t,n){return n>0?Math.min(100,Math.round((e+t)/n*100)):0}function ct(){let e=0,t=0,n=0,o=0,r=()=>{let a=Date.now();t&&(e+=a-t),t=document.visibilityState==="visible"&&document.hasFocus()?a:0;},i=()=>{n=Math.max(n,kt(scrollY,innerHeight,Math.max(document.documentElement.scrollHeight,document.body?.scrollHeight??0)));},s=()=>{e=n=o=t=0,r();};for(let a of ["focus","blur"])window.addEventListener(a,r);return document.addEventListener("visibilitychange",r),window.addEventListener("scroll",i),s(),{E:i,S:s,w(a){if(a&&i(),r(),!xt(e,n,o))return null;let p={ms:Math.min(e,864e5),scroll:n};return e=0,o=n,p}}}var L={};function ut(){return typeof document<"u"&&(document.visibilityState==="hidden"||document.prerendering===true)}var w=class e{constructor(t){this.s=null;this.p=null;this.a=null;this.r=null;this.f=null;this.c=false;if(this.t=t,this.e=new S(t,()=>this.b(true)),typeof window<"u"){try{z(window.location.search,localStorage)&&console.info("IndieBob: this browser is excluded from analytics (ib_ignore)");}catch{}if(this.n&&u(t)&&R(window.location.search,document.referrer),this.r=ct(),window.addEventListener("pageshow",n=>{n.persisted&&this.i!==void 0&&(this.i=void 0,this.page(this.h));}),t.autoDetect!==false){let n=typeof t.autoDetect=="object"?t.autoDetect:{};this.p=at((o,r)=>this.track(o,r),n.dataAttributes!==false,n.fileDownloads!==false,n.outboundClicks!==false);}}}static init(t){var o;let n=F(t);return typeof window>"u"?new e(n):L[o=n.projectId]??(L[o]=new e(n))}page(t){if(!u(this.t))return;if(this.i===void 0&&ut()){if(this.y=t,!this.c){this.c=true;let o=()=>{this.c&&!ut()&&(this.c=false,this.page(this.y));};document.addEventListener("visibilitychange",o),document.addEventListener("prerenderingchange",o);}return}let n=A(t,this.t.hashMode,this.n);if(n.page.path!==this.i&&(this.b(false),this.i=n.page.path,this.h=t,this.f=n,this.r&&(this.r.S(),setTimeout(this.r.E,1e3)),this.e.push(this.o("page",{context:n})),this.t.autoDetect!==false)){let o=n.page.path,r=typeof this.t.autoDetect=="object"?this.t.autoDetect:{},i=Z(o,r);if(i&&(this.e.push(this.o("track",{event:i,properties:{auto:true},context:n})),c(this.t,`auto-detected: ${i} on ${o}`),r.formSubmit!==false)){this.a?.();let s=tt(i);s&&(this.a=et(s,a=>{this.e.push(this.o("track",{event:a,properties:{auto:true}})),c(this.t,`auto-detected: ${a}`);}));}}}track(t,n){u(this.t)&&this.e.push(this.o("track",{event:t,properties:n}));}identify(t,n,o){if(!u(this.t))return;this.d=t,this.e.push(this.o("identify",{traits:n,userId:t}));let r=typeof o?.isNew=="boolean";if(this.t.autoDetect!==false&&(r||this.n)){let s=(r?o.isNew:nt())?"signup":"login";this.e.push(this.o("track",{event:s,properties:{auto:!r}})),this.n&&ot(),c(this.t,`${s} for ${t}`);}}revenue(t){u(this.t)&&this.e.push(this.o("revenue",{revenue:{amount:t.amount,currency:t.currency??"USD",plan:t.plan,type:t.type}}));}optOut(){this.e.flush(),X(),U(),this.d=void 0,this.p?.(),this.a?.(),this.p=null,this.a=null,c(this.t,"opted out");}optIn(){G(),c(this.t,"opted in");}isOptedOut(){return V()}isIgnored(){return T()}async flush(){await this.e.flush();}getAnonymousId(){return this.n?g():""}getSessionId(){return this.n?h():""}setPersistence(t){t!=="local"&&t!=="none"||(this.t.persistence=t,t==="local"?typeof window<"u"&&u(this.t)&&(R(location.search,document.referrer),this.e.stamp(g(),h())):(m(),v(),I(),U(),this.e.clearStored()),c(this.t,`persistence: ${t}`));}get n(){return this.t.persistence==="local"}getConfig(){return Object.freeze({...this.t})}enableAutoPage(){return this.s?.(),this.s=Q(()=>this.page(),this.t.hashMode),()=>{this.s?.(),this.s=null;}}b(t){let n=this.f&&this.r?.w(t);n&&u(this.t)&&this.e.push(this.o("engagement",{context:this.f,engagement:n}));}o(t,n){return {...n,v:1,id:l(),projectId:this.t.projectId,type:t,...this.n?{anonymousId:g(),sessionId:h()}:{},userId:this.d??n.userId,timestamp:new Date().toISOString(),context:n.context??A(void 0,this.t.hashMode,this.n)}}};var Rt=Symbol("indiebob"),M=null,me={install(e,t){let n=w.init(t);M=n,e.provide(Rt,n),e.config.globalProperties.$bob=n;let o=e.config.globalProperties.$router;o&&o.afterEach(()=>{n.page();});}};function he(){if(M)return M;throw new Error("[IndieBob] useTracker() called before IndieBobPlugin was installed.")}
|
|
2
|
+
exports.IndieBob=w;exports.IndieBobPlugin=me;exports.useTracker=he;return exports;})({});
|
|
3
3
|
;IndieBob.IndieBob&&(IndieBob=Object.assign(IndieBob.IndieBob,IndieBob));
|