@gurulu/web 1.1.0 → 1.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/dist/activate-runtime.d.ts +15 -0
- package/dist/activate-runtime.d.ts.map +1 -0
- package/dist/activate-runtime.js +237 -0
- package/dist/activation.d.ts +106 -0
- package/dist/activation.d.ts.map +1 -0
- package/dist/autocapture/error.d.ts +14 -0
- package/dist/autocapture/error.d.ts.map +1 -0
- package/dist/autocapture/index.d.ts +2 -0
- package/dist/autocapture/index.d.ts.map +1 -1
- package/dist/core.d.ts +3 -0
- package/dist/core.d.ts.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +182 -1
- package/dist/react.js +181 -1
- package/dist/t.js +7 -7
- package/dist/t.js.map +8 -6
- package/package.json +7 -2
package/dist/index.js
CHANGED
|
@@ -1,3 +1,132 @@
|
|
|
1
|
+
// src/activation.ts
|
|
2
|
+
function fnv1a32(str) {
|
|
3
|
+
let h = 2166136261;
|
|
4
|
+
for (let i = 0;i < str.length; i++) {
|
|
5
|
+
h ^= str.charCodeAt(i);
|
|
6
|
+
h = Math.imul(h, 16777619);
|
|
7
|
+
}
|
|
8
|
+
return h >>> 0;
|
|
9
|
+
}
|
|
10
|
+
function activationBucket(key, uid) {
|
|
11
|
+
return fnv1a32(`${key}:${uid}`) % 1e4 / 1e4;
|
|
12
|
+
}
|
|
13
|
+
var EMPTY = {
|
|
14
|
+
workspace_id: "",
|
|
15
|
+
popups: [],
|
|
16
|
+
tours: [],
|
|
17
|
+
personalizations: [],
|
|
18
|
+
experiments: []
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
class GuruluActivation {
|
|
22
|
+
cfg;
|
|
23
|
+
data = null;
|
|
24
|
+
pending = null;
|
|
25
|
+
exposed = new Set;
|
|
26
|
+
served = new Set;
|
|
27
|
+
constructor(cfg) {
|
|
28
|
+
this.cfg = cfg;
|
|
29
|
+
}
|
|
30
|
+
async refresh(opts) {
|
|
31
|
+
if (this.pending)
|
|
32
|
+
return this.pending;
|
|
33
|
+
const f = this.cfg.fetchImpl ?? (typeof fetch !== "undefined" ? fetch.bind(globalThis) : null);
|
|
34
|
+
if (!f)
|
|
35
|
+
return EMPTY;
|
|
36
|
+
const uid = this.cfg.getUid();
|
|
37
|
+
const sp = new URLSearchParams;
|
|
38
|
+
if (uid)
|
|
39
|
+
sp.set("uid", uid);
|
|
40
|
+
const winHref = typeof window !== "undefined" && window.location ? window.location.href : "";
|
|
41
|
+
const url = opts?.url ?? winHref;
|
|
42
|
+
if (url)
|
|
43
|
+
sp.set("url", url);
|
|
44
|
+
const ua = typeof navigator !== "undefined" && navigator.userAgent ? navigator.userAgent : "";
|
|
45
|
+
const device = opts?.device ?? (/Mobi|Android/i.test(ua) ? "mobile" : "desktop");
|
|
46
|
+
sp.set("device", device);
|
|
47
|
+
this.pending = (async () => {
|
|
48
|
+
try {
|
|
49
|
+
const res = await f(`${this.cfg.endpoint}/v1/activate?${sp.toString()}`, {
|
|
50
|
+
method: "GET",
|
|
51
|
+
headers: { Authorization: `Bearer ${this.cfg.workspaceKey}` },
|
|
52
|
+
credentials: "omit"
|
|
53
|
+
});
|
|
54
|
+
if (!res.ok)
|
|
55
|
+
return this.data ?? EMPTY;
|
|
56
|
+
this.data = await res.json();
|
|
57
|
+
return this.data;
|
|
58
|
+
} catch {
|
|
59
|
+
return this.data ?? EMPTY;
|
|
60
|
+
} finally {
|
|
61
|
+
this.pending = null;
|
|
62
|
+
}
|
|
63
|
+
})();
|
|
64
|
+
return this.pending;
|
|
65
|
+
}
|
|
66
|
+
getPopups() {
|
|
67
|
+
return this.data?.popups ?? [];
|
|
68
|
+
}
|
|
69
|
+
getTours() {
|
|
70
|
+
return this.data?.tours ?? [];
|
|
71
|
+
}
|
|
72
|
+
getContent(slot) {
|
|
73
|
+
const p = (this.data?.personalizations ?? []).find((x) => x.slot_key === slot);
|
|
74
|
+
if (!p)
|
|
75
|
+
return null;
|
|
76
|
+
if (!this.served.has(p.key)) {
|
|
77
|
+
this.served.add(p.key);
|
|
78
|
+
this.cfg.track("personalization_served", {
|
|
79
|
+
personalization_key: p.key,
|
|
80
|
+
variant_key: p.variant_key,
|
|
81
|
+
is_holdout: p.is_holdout
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
return p.content;
|
|
85
|
+
}
|
|
86
|
+
getVariant(experimentKey) {
|
|
87
|
+
const e = (this.data?.experiments ?? []).find((x) => x.key === experimentKey);
|
|
88
|
+
if (!e)
|
|
89
|
+
return null;
|
|
90
|
+
const variant = e.assigned_variant ?? assignLocalVariant(experimentKey, this.cfg.getUid(), e.variants);
|
|
91
|
+
if (variant && !this.exposed.has(experimentKey)) {
|
|
92
|
+
this.exposed.add(experimentKey);
|
|
93
|
+
this.cfg.track("experiment_exposed", {
|
|
94
|
+
experiment_key: experimentKey,
|
|
95
|
+
variant_key: variant
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
return variant;
|
|
99
|
+
}
|
|
100
|
+
trackPopup(key, action) {
|
|
101
|
+
this.cfg.track(`popup_${action}`, { popup_key: key });
|
|
102
|
+
}
|
|
103
|
+
trackTour(key, action, stepIndex) {
|
|
104
|
+
this.cfg.track(`tour_${action}`, {
|
|
105
|
+
tour_key: key,
|
|
106
|
+
...stepIndex !== undefined ? { step_index: stepIndex } : {}
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
async saveTourProgress(tourKey, body) {}
|
|
110
|
+
snapshot() {
|
|
111
|
+
return this.data ?? EMPTY;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
function assignLocalVariant(key, uid, variants) {
|
|
115
|
+
const valid = variants.filter((v) => v.weight > 0 && v.key.length > 0);
|
|
116
|
+
if (valid.length === 0 || !uid)
|
|
117
|
+
return null;
|
|
118
|
+
const total = valid.reduce((s, v) => s + v.weight, 0);
|
|
119
|
+
if (total <= 0)
|
|
120
|
+
return null;
|
|
121
|
+
const bucket = activationBucket(key, uid);
|
|
122
|
+
let cum = 0;
|
|
123
|
+
for (const v of valid) {
|
|
124
|
+
cum += v.weight / total;
|
|
125
|
+
if (bucket < cum)
|
|
126
|
+
return v.key;
|
|
127
|
+
}
|
|
128
|
+
return valid[valid.length - 1].key;
|
|
129
|
+
}
|
|
1
130
|
// src/consent.ts
|
|
2
131
|
var DEFAULT_API_URL = "https://api.gurulu.io";
|
|
3
132
|
var STORAGE_PREFIX = "gurulu_consent_";
|
|
@@ -351,6 +480,44 @@ function startClickAutocapture(track) {
|
|
|
351
480
|
};
|
|
352
481
|
}
|
|
353
482
|
|
|
483
|
+
// src/autocapture/error.ts
|
|
484
|
+
var MAX_STACK = 2000;
|
|
485
|
+
var MAX_MESSAGE = 1000;
|
|
486
|
+
function startErrorAutocapture(track) {
|
|
487
|
+
if (typeof window === "undefined")
|
|
488
|
+
return { stop: () => {
|
|
489
|
+
return;
|
|
490
|
+
} };
|
|
491
|
+
const onError = (ev) => {
|
|
492
|
+
const err = ev.error;
|
|
493
|
+
track({
|
|
494
|
+
message: String(ev.message ?? err?.message ?? "Error").slice(0, MAX_MESSAGE),
|
|
495
|
+
error_type: err?.name ?? "Error",
|
|
496
|
+
...ev.filename ? { source: ev.filename } : {},
|
|
497
|
+
...typeof ev.lineno === "number" ? { lineno: ev.lineno } : {},
|
|
498
|
+
...typeof ev.colno === "number" ? { colno: ev.colno } : {},
|
|
499
|
+
...err?.stack ? { stack: String(err.stack).slice(0, MAX_STACK) } : {}
|
|
500
|
+
});
|
|
501
|
+
};
|
|
502
|
+
const onRejection = (ev) => {
|
|
503
|
+
const reason = ev.reason;
|
|
504
|
+
const isErr = reason instanceof Error;
|
|
505
|
+
track({
|
|
506
|
+
message: String(isErr ? reason.message : reason).slice(0, MAX_MESSAGE),
|
|
507
|
+
error_type: isErr ? reason.name : "UnhandledRejection",
|
|
508
|
+
...isErr && reason.stack ? { stack: String(reason.stack).slice(0, MAX_STACK) } : {}
|
|
509
|
+
});
|
|
510
|
+
};
|
|
511
|
+
window.addEventListener("error", onError);
|
|
512
|
+
window.addEventListener("unhandledrejection", onRejection);
|
|
513
|
+
return {
|
|
514
|
+
stop() {
|
|
515
|
+
window.removeEventListener("error", onError);
|
|
516
|
+
window.removeEventListener("unhandledrejection", onRejection);
|
|
517
|
+
}
|
|
518
|
+
};
|
|
519
|
+
}
|
|
520
|
+
|
|
354
521
|
// src/autocapture/form.ts
|
|
355
522
|
var SENSITIVE_INPUT_TYPES = new Set(["password", "tel"]);
|
|
356
523
|
function isSensitiveField(el) {
|
|
@@ -701,6 +868,8 @@ function startAutocapture(cfg, sinks) {
|
|
|
701
868
|
handles.push(startScrollAutocapture(sinks.scrollDepth));
|
|
702
869
|
if (merged.web_vitals)
|
|
703
870
|
handles.push(startWebVitalsAutocapture(sinks.webVital));
|
|
871
|
+
if (merged.js_error)
|
|
872
|
+
handles.push(startErrorAutocapture(sinks.jsError));
|
|
704
873
|
return {
|
|
705
874
|
stopAll() {
|
|
706
875
|
for (const h of handles) {
|
|
@@ -1173,6 +1342,7 @@ class Gurulu {
|
|
|
1173
1342
|
autocaptureHandle = null;
|
|
1174
1343
|
testMode = false;
|
|
1175
1344
|
consent;
|
|
1345
|
+
activation;
|
|
1176
1346
|
init(opts) {
|
|
1177
1347
|
if (this.initialized) {
|
|
1178
1348
|
if (opts.debug && typeof console !== "undefined") {
|
|
@@ -1193,6 +1363,12 @@ class Gurulu {
|
|
|
1193
1363
|
autoBanner: opts.consent_mode === "banner_required"
|
|
1194
1364
|
});
|
|
1195
1365
|
this.consent.init();
|
|
1366
|
+
this.activation = new GuruluActivation({
|
|
1367
|
+
endpoint: opts.endpoint ?? DEFAULT_ENDPOINT,
|
|
1368
|
+
workspaceKey: opts.workspaceKey,
|
|
1369
|
+
getUid: () => getPersonId() ?? this.anonymousId ?? "",
|
|
1370
|
+
track: (key, props) => this.track(key, props)
|
|
1371
|
+
});
|
|
1196
1372
|
const transport = {
|
|
1197
1373
|
endpoint: opts.endpoint ?? DEFAULT_ENDPOINT,
|
|
1198
1374
|
workspaceKey: opts.workspaceKey,
|
|
@@ -1234,7 +1410,8 @@ class Gurulu {
|
|
|
1234
1410
|
formStarted: (p) => this.queueEvent("form_started", "interaction", p),
|
|
1235
1411
|
formSubmitted: (p) => this.queueEvent("form_submitted", "interaction", p),
|
|
1236
1412
|
scrollDepth: (p) => this.queueEvent("scroll_depth", "interaction", p),
|
|
1237
|
-
webVital: (p) => this.queueEvent("web_vital", "interaction", p)
|
|
1413
|
+
webVital: (p) => this.queueEvent("web_vital", "interaction", p),
|
|
1414
|
+
jsError: (p) => this.queueEvent("js_error", "interaction", p)
|
|
1238
1415
|
});
|
|
1239
1416
|
this.initialized = true;
|
|
1240
1417
|
}
|
|
@@ -1380,6 +1557,9 @@ var publicSdk = {
|
|
|
1380
1557
|
get consent() {
|
|
1381
1558
|
return singleton.consent;
|
|
1382
1559
|
},
|
|
1560
|
+
get activation() {
|
|
1561
|
+
return singleton.activation;
|
|
1562
|
+
},
|
|
1383
1563
|
VERSION
|
|
1384
1564
|
};
|
|
1385
1565
|
function autoBootstrap() {
|
|
@@ -1424,6 +1604,7 @@ export {
|
|
|
1424
1604
|
NetworkError,
|
|
1425
1605
|
InitError,
|
|
1426
1606
|
GuruluConsent,
|
|
1607
|
+
GuruluActivation,
|
|
1427
1608
|
Gurulu,
|
|
1428
1609
|
ConsentBlockedError
|
|
1429
1610
|
};
|
package/dist/react.js
CHANGED
|
@@ -1,3 +1,132 @@
|
|
|
1
|
+
// src/activation.ts
|
|
2
|
+
function fnv1a32(str) {
|
|
3
|
+
let h = 2166136261;
|
|
4
|
+
for (let i = 0;i < str.length; i++) {
|
|
5
|
+
h ^= str.charCodeAt(i);
|
|
6
|
+
h = Math.imul(h, 16777619);
|
|
7
|
+
}
|
|
8
|
+
return h >>> 0;
|
|
9
|
+
}
|
|
10
|
+
function activationBucket(key, uid) {
|
|
11
|
+
return fnv1a32(`${key}:${uid}`) % 1e4 / 1e4;
|
|
12
|
+
}
|
|
13
|
+
var EMPTY = {
|
|
14
|
+
workspace_id: "",
|
|
15
|
+
popups: [],
|
|
16
|
+
tours: [],
|
|
17
|
+
personalizations: [],
|
|
18
|
+
experiments: []
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
class GuruluActivation {
|
|
22
|
+
cfg;
|
|
23
|
+
data = null;
|
|
24
|
+
pending = null;
|
|
25
|
+
exposed = new Set;
|
|
26
|
+
served = new Set;
|
|
27
|
+
constructor(cfg) {
|
|
28
|
+
this.cfg = cfg;
|
|
29
|
+
}
|
|
30
|
+
async refresh(opts) {
|
|
31
|
+
if (this.pending)
|
|
32
|
+
return this.pending;
|
|
33
|
+
const f = this.cfg.fetchImpl ?? (typeof fetch !== "undefined" ? fetch.bind(globalThis) : null);
|
|
34
|
+
if (!f)
|
|
35
|
+
return EMPTY;
|
|
36
|
+
const uid = this.cfg.getUid();
|
|
37
|
+
const sp = new URLSearchParams;
|
|
38
|
+
if (uid)
|
|
39
|
+
sp.set("uid", uid);
|
|
40
|
+
const winHref = typeof window !== "undefined" && window.location ? window.location.href : "";
|
|
41
|
+
const url = opts?.url ?? winHref;
|
|
42
|
+
if (url)
|
|
43
|
+
sp.set("url", url);
|
|
44
|
+
const ua = typeof navigator !== "undefined" && navigator.userAgent ? navigator.userAgent : "";
|
|
45
|
+
const device = opts?.device ?? (/Mobi|Android/i.test(ua) ? "mobile" : "desktop");
|
|
46
|
+
sp.set("device", device);
|
|
47
|
+
this.pending = (async () => {
|
|
48
|
+
try {
|
|
49
|
+
const res = await f(`${this.cfg.endpoint}/v1/activate?${sp.toString()}`, {
|
|
50
|
+
method: "GET",
|
|
51
|
+
headers: { Authorization: `Bearer ${this.cfg.workspaceKey}` },
|
|
52
|
+
credentials: "omit"
|
|
53
|
+
});
|
|
54
|
+
if (!res.ok)
|
|
55
|
+
return this.data ?? EMPTY;
|
|
56
|
+
this.data = await res.json();
|
|
57
|
+
return this.data;
|
|
58
|
+
} catch {
|
|
59
|
+
return this.data ?? EMPTY;
|
|
60
|
+
} finally {
|
|
61
|
+
this.pending = null;
|
|
62
|
+
}
|
|
63
|
+
})();
|
|
64
|
+
return this.pending;
|
|
65
|
+
}
|
|
66
|
+
getPopups() {
|
|
67
|
+
return this.data?.popups ?? [];
|
|
68
|
+
}
|
|
69
|
+
getTours() {
|
|
70
|
+
return this.data?.tours ?? [];
|
|
71
|
+
}
|
|
72
|
+
getContent(slot) {
|
|
73
|
+
const p = (this.data?.personalizations ?? []).find((x) => x.slot_key === slot);
|
|
74
|
+
if (!p)
|
|
75
|
+
return null;
|
|
76
|
+
if (!this.served.has(p.key)) {
|
|
77
|
+
this.served.add(p.key);
|
|
78
|
+
this.cfg.track("personalization_served", {
|
|
79
|
+
personalization_key: p.key,
|
|
80
|
+
variant_key: p.variant_key,
|
|
81
|
+
is_holdout: p.is_holdout
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
return p.content;
|
|
85
|
+
}
|
|
86
|
+
getVariant(experimentKey) {
|
|
87
|
+
const e = (this.data?.experiments ?? []).find((x) => x.key === experimentKey);
|
|
88
|
+
if (!e)
|
|
89
|
+
return null;
|
|
90
|
+
const variant = e.assigned_variant ?? assignLocalVariant(experimentKey, this.cfg.getUid(), e.variants);
|
|
91
|
+
if (variant && !this.exposed.has(experimentKey)) {
|
|
92
|
+
this.exposed.add(experimentKey);
|
|
93
|
+
this.cfg.track("experiment_exposed", {
|
|
94
|
+
experiment_key: experimentKey,
|
|
95
|
+
variant_key: variant
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
return variant;
|
|
99
|
+
}
|
|
100
|
+
trackPopup(key, action) {
|
|
101
|
+
this.cfg.track(`popup_${action}`, { popup_key: key });
|
|
102
|
+
}
|
|
103
|
+
trackTour(key, action, stepIndex) {
|
|
104
|
+
this.cfg.track(`tour_${action}`, {
|
|
105
|
+
tour_key: key,
|
|
106
|
+
...stepIndex !== undefined ? { step_index: stepIndex } : {}
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
async saveTourProgress(tourKey, body) {}
|
|
110
|
+
snapshot() {
|
|
111
|
+
return this.data ?? EMPTY;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
function assignLocalVariant(key, uid, variants) {
|
|
115
|
+
const valid = variants.filter((v) => v.weight > 0 && v.key.length > 0);
|
|
116
|
+
if (valid.length === 0 || !uid)
|
|
117
|
+
return null;
|
|
118
|
+
const total = valid.reduce((s, v) => s + v.weight, 0);
|
|
119
|
+
if (total <= 0)
|
|
120
|
+
return null;
|
|
121
|
+
const bucket = activationBucket(key, uid);
|
|
122
|
+
let cum = 0;
|
|
123
|
+
for (const v of valid) {
|
|
124
|
+
cum += v.weight / total;
|
|
125
|
+
if (bucket < cum)
|
|
126
|
+
return v.key;
|
|
127
|
+
}
|
|
128
|
+
return valid[valid.length - 1].key;
|
|
129
|
+
}
|
|
1
130
|
// src/consent.ts
|
|
2
131
|
var DEFAULT_API_URL = "https://api.gurulu.io";
|
|
3
132
|
var STORAGE_PREFIX = "gurulu_consent_";
|
|
@@ -351,6 +480,44 @@ function startClickAutocapture(track) {
|
|
|
351
480
|
};
|
|
352
481
|
}
|
|
353
482
|
|
|
483
|
+
// src/autocapture/error.ts
|
|
484
|
+
var MAX_STACK = 2000;
|
|
485
|
+
var MAX_MESSAGE = 1000;
|
|
486
|
+
function startErrorAutocapture(track) {
|
|
487
|
+
if (typeof window === "undefined")
|
|
488
|
+
return { stop: () => {
|
|
489
|
+
return;
|
|
490
|
+
} };
|
|
491
|
+
const onError = (ev) => {
|
|
492
|
+
const err = ev.error;
|
|
493
|
+
track({
|
|
494
|
+
message: String(ev.message ?? err?.message ?? "Error").slice(0, MAX_MESSAGE),
|
|
495
|
+
error_type: err?.name ?? "Error",
|
|
496
|
+
...ev.filename ? { source: ev.filename } : {},
|
|
497
|
+
...typeof ev.lineno === "number" ? { lineno: ev.lineno } : {},
|
|
498
|
+
...typeof ev.colno === "number" ? { colno: ev.colno } : {},
|
|
499
|
+
...err?.stack ? { stack: String(err.stack).slice(0, MAX_STACK) } : {}
|
|
500
|
+
});
|
|
501
|
+
};
|
|
502
|
+
const onRejection = (ev) => {
|
|
503
|
+
const reason = ev.reason;
|
|
504
|
+
const isErr = reason instanceof Error;
|
|
505
|
+
track({
|
|
506
|
+
message: String(isErr ? reason.message : reason).slice(0, MAX_MESSAGE),
|
|
507
|
+
error_type: isErr ? reason.name : "UnhandledRejection",
|
|
508
|
+
...isErr && reason.stack ? { stack: String(reason.stack).slice(0, MAX_STACK) } : {}
|
|
509
|
+
});
|
|
510
|
+
};
|
|
511
|
+
window.addEventListener("error", onError);
|
|
512
|
+
window.addEventListener("unhandledrejection", onRejection);
|
|
513
|
+
return {
|
|
514
|
+
stop() {
|
|
515
|
+
window.removeEventListener("error", onError);
|
|
516
|
+
window.removeEventListener("unhandledrejection", onRejection);
|
|
517
|
+
}
|
|
518
|
+
};
|
|
519
|
+
}
|
|
520
|
+
|
|
354
521
|
// src/autocapture/form.ts
|
|
355
522
|
var SENSITIVE_INPUT_TYPES = new Set(["password", "tel"]);
|
|
356
523
|
function isSensitiveField(el) {
|
|
@@ -701,6 +868,8 @@ function startAutocapture(cfg, sinks) {
|
|
|
701
868
|
handles.push(startScrollAutocapture(sinks.scrollDepth));
|
|
702
869
|
if (merged.web_vitals)
|
|
703
870
|
handles.push(startWebVitalsAutocapture(sinks.webVital));
|
|
871
|
+
if (merged.js_error)
|
|
872
|
+
handles.push(startErrorAutocapture(sinks.jsError));
|
|
704
873
|
return {
|
|
705
874
|
stopAll() {
|
|
706
875
|
for (const h of handles) {
|
|
@@ -1173,6 +1342,7 @@ class Gurulu {
|
|
|
1173
1342
|
autocaptureHandle = null;
|
|
1174
1343
|
testMode = false;
|
|
1175
1344
|
consent;
|
|
1345
|
+
activation;
|
|
1176
1346
|
init(opts) {
|
|
1177
1347
|
if (this.initialized) {
|
|
1178
1348
|
if (opts.debug && typeof console !== "undefined") {
|
|
@@ -1193,6 +1363,12 @@ class Gurulu {
|
|
|
1193
1363
|
autoBanner: opts.consent_mode === "banner_required"
|
|
1194
1364
|
});
|
|
1195
1365
|
this.consent.init();
|
|
1366
|
+
this.activation = new GuruluActivation({
|
|
1367
|
+
endpoint: opts.endpoint ?? DEFAULT_ENDPOINT,
|
|
1368
|
+
workspaceKey: opts.workspaceKey,
|
|
1369
|
+
getUid: () => getPersonId() ?? this.anonymousId ?? "",
|
|
1370
|
+
track: (key, props) => this.track(key, props)
|
|
1371
|
+
});
|
|
1196
1372
|
const transport = {
|
|
1197
1373
|
endpoint: opts.endpoint ?? DEFAULT_ENDPOINT,
|
|
1198
1374
|
workspaceKey: opts.workspaceKey,
|
|
@@ -1234,7 +1410,8 @@ class Gurulu {
|
|
|
1234
1410
|
formStarted: (p) => this.queueEvent("form_started", "interaction", p),
|
|
1235
1411
|
formSubmitted: (p) => this.queueEvent("form_submitted", "interaction", p),
|
|
1236
1412
|
scrollDepth: (p) => this.queueEvent("scroll_depth", "interaction", p),
|
|
1237
|
-
webVital: (p) => this.queueEvent("web_vital", "interaction", p)
|
|
1413
|
+
webVital: (p) => this.queueEvent("web_vital", "interaction", p),
|
|
1414
|
+
jsError: (p) => this.queueEvent("js_error", "interaction", p)
|
|
1238
1415
|
});
|
|
1239
1416
|
this.initialized = true;
|
|
1240
1417
|
}
|
|
@@ -1380,6 +1557,9 @@ var publicSdk = {
|
|
|
1380
1557
|
get consent() {
|
|
1381
1558
|
return singleton.consent;
|
|
1382
1559
|
},
|
|
1560
|
+
get activation() {
|
|
1561
|
+
return singleton.activation;
|
|
1562
|
+
},
|
|
1383
1563
|
VERSION
|
|
1384
1564
|
};
|
|
1385
1565
|
function autoBootstrap() {
|
package/dist/t.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
class
|
|
2
|
-
<div style="margin-bottom:12px;font-weight:600;">${
|
|
3
|
-
<div style="margin-bottom:16px;color:#a3a3a3;">${
|
|
1
|
+
function Mu(u){let r=2166136261;for(let o=0;o<u.length;o++)r^=u.charCodeAt(o),r=Math.imul(r,16777619);return r>>>0}function zu(u,r){return Mu(`${u}:${r}`)%1e4/1e4}var d={workspace_id:"",popups:[],tours:[],personalizations:[],experiments:[]};class V{cfg;data=null;pending=null;exposed=new Set;served=new Set;constructor(u){this.cfg=u}async refresh(u){if(this.pending)return this.pending;let r=this.cfg.fetchImpl??(typeof fetch<"u"?fetch.bind(globalThis):null);if(!r)return d;let o=this.cfg.getUid(),n=new URLSearchParams;if(o)n.set("uid",o);let m=typeof window<"u"&&window.location?window.location.href:"",_=u?.url??m;if(_)n.set("url",_);let c=typeof navigator<"u"&&navigator.userAgent?navigator.userAgent:"",A=u?.device??(/Mobi|Android/i.test(c)?"mobile":"desktop");return n.set("device",A),this.pending=(async()=>{try{let E=await r(`${this.cfg.endpoint}/v1/activate?${n.toString()}`,{method:"GET",headers:{Authorization:`Bearer ${this.cfg.workspaceKey}`},credentials:"omit"});if(!E.ok)return this.data??d;return this.data=await E.json(),this.data}catch{return this.data??d}finally{this.pending=null}})(),this.pending}getPopups(){return this.data?.popups??[]}getTours(){return this.data?.tours??[]}getContent(u){let r=(this.data?.personalizations??[]).find((o)=>o.slot_key===u);if(!r)return null;if(!this.served.has(r.key))this.served.add(r.key),this.cfg.track("personalization_served",{personalization_key:r.key,variant_key:r.variant_key,is_holdout:r.is_holdout});return r.content}getVariant(u){let r=(this.data?.experiments??[]).find((n)=>n.key===u);if(!r)return null;let o=r.assigned_variant??Du(u,this.cfg.getUid(),r.variants);if(o&&!this.exposed.has(u))this.exposed.add(u),this.cfg.track("experiment_exposed",{experiment_key:u,variant_key:o});return o}trackPopup(u,r){this.cfg.track(`popup_${r}`,{popup_key:u})}trackTour(u,r,o){this.cfg.track(`tour_${r}`,{tour_key:u,...o!==void 0?{step_index:o}:{}})}async saveTourProgress(u,r){}snapshot(){return this.data??d}}function Du(u,r,o){let n=o.filter((A)=>A.weight>0&&A.key.length>0);if(n.length===0||!r)return null;let m=n.reduce((A,E)=>A+E.weight,0);if(m<=0)return null;let _=zu(u,r),c=0;for(let A of n)if(c+=A.weight/m,_<c)return A.key;return n[n.length-1].key}class h{workspaceId;apiUrl;fetchImpl;storage;autoBanner;locale;anonymousIdValue;bannerConfigCache=null;bannerEl=null;constructor(u){this.workspaceId=u.workspaceId,this.apiUrl=(u.apiUrl??"https://api.gurulu.io").replace(/\/+$/,""),this.fetchImpl=u.fetchImpl??(typeof fetch<"u"?fetch.bind(globalThis):$u),this.storage=u.storage??(typeof globalThis<"u"&&"localStorage"in globalThis?globalThis.localStorage:null),this.autoBanner=u.autoBanner??!0,this.locale=u.locale??Vu(),this.anonymousIdValue=u.anonymousId??this.loadOrCreateAnonId()}async init(){if(typeof window>"u")return;try{let r=await this.fetchImpl(`${this.apiUrl}/v1/consent/banner-config?workspace_id=${encodeURIComponent(this.workspaceId)}`,{method:"GET",credentials:"omit"});if(!r.ok)return;this.bannerConfigCache=await r.json()}catch{return}if(!this.getState()&&this.autoBanner&&this.bannerConfigCache?.mode==="banner_required")this.showBanner()}getState(){if(!this.storage)return null;try{let u=this.storage.getItem(this.storageKey());if(!u)return null;let r=JSON.parse(u);if(r.expiresAt&&new Date(r.expiresAt).getTime()<Date.now())return this.storage.removeItem(this.storageKey()),null;return r}catch{return null}}async setState(u){let r=this.getState()?.categories,o={necessary:!0,analytics:u.analytics??r?.analytics??!1,marketing:u.marketing??r?.marketing??!1,functional:u.functional??r?.functional??!1,personalization:u.personalization??r?.personalization??!1},n=new Date,m=this.bannerConfigCache?.renewal_months??13,_=new Date(n);_.setMonth(_.getMonth()+m);let c={workspaceId:this.workspaceId,anonymousId:this.anonymousIdValue,categories:o,grantedAt:n.toISOString(),expiresAt:_.toISOString(),source:"sdk_api"};if(this.storage)try{this.storage.setItem(this.storageKey(),JSON.stringify(c))}catch{}try{await this.fetchImpl(`${this.apiUrl}/v1/consent/state`,{method:"POST",credentials:"omit",headers:{"content-type":"application/json"},body:JSON.stringify({workspace_id:this.workspaceId,anonymous_id:this.anonymousIdValue,necessary:o.necessary,analytics:o.analytics,marketing:o.marketing,functional:o.functional,personalization:o.personalization,source:"sdk_api"})})}catch{}}showBanner(){if(typeof document>"u")return;if(this.bannerEl)return;let u=this.bannerConfigCache?.banner_config??{},r=this.bannerText(),o=u.brand?.primary_color??"#fafafa",n=u.position??"bottom",m=document.createElement("div");m.setAttribute("data-gurulu-consent-banner",""),m.setAttribute("role","dialog"),m.setAttribute("aria-label",r.heading),m.style.cssText=Tu(n),m.innerHTML=qu(r,o);let _=m.querySelector("[data-gurulu-accept]"),c=m.querySelector("[data-gurulu-reject]");_?.addEventListener("click",()=>{this.setState({analytics:!0,marketing:!0,functional:!0,personalization:!0}),this.hideBanner()}),c?.addEventListener("click",()=>{this.setState({analytics:!1,marketing:!1,functional:!1,personalization:!1}),this.hideBanner()}),document.body.appendChild(m),this.bannerEl=m}hideBanner(){if(this.bannerEl?.parentNode)this.bannerEl.parentNode.removeChild(this.bannerEl);this.bannerEl=null}buildIngestHeader(){let u=this.getState();if(!u)return JSON.stringify({necessary:!0});return JSON.stringify(u.categories)}getAnonymousId(){return this.anonymousIdValue}storageKey(){return`gurulu_consent_${this.workspaceId}`}loadOrCreateAnonId(){if(!this.storage)return R();try{let u=this.storage.getItem("gurulu_anon_id");if(u)return u;let r=R();return this.storage.setItem("gurulu_anon_id",r),r}catch{return R()}}bannerText(){let r=this.bannerConfigCache?.banner_config?.text_overrides?.[this.locale];if(this.locale==="tr")return{heading:r?.heading??"Çerezleri tercih et",body:r?.body??"Deneyimini iyileştirmek için analytics + pazarlama çerezleri kullanıyoruz.",accept:r?.accept??"Tümünü kabul et",reject:r?.reject??"Sadece gerekli olanlar"};return{heading:r?.heading??"Manage cookies",body:r?.body??"We use analytics and marketing cookies to improve your experience.",accept:r?.accept??"Accept all",reject:r?.reject??"Necessary only"}}}function Tu(u){switch(u){case"top":return"position:fixed;z-index:2147483647;background:#141414;color:#fafafa;border:1px solid #262626;border-radius:8px;padding:16px;font-family:-apple-system,Segoe UI,Roboto,sans-serif;font-size:14px;line-height:1.5;box-shadow:0 4px 24px rgba(0,0,0,0.4);max-width:480px;top:16px;left:50%;transform:translateX(-50%);";case"bottom-left":return"position:fixed;z-index:2147483647;background:#141414;color:#fafafa;border:1px solid #262626;border-radius:8px;padding:16px;font-family:-apple-system,Segoe UI,Roboto,sans-serif;font-size:14px;line-height:1.5;box-shadow:0 4px 24px rgba(0,0,0,0.4);max-width:480px;bottom:16px;left:16px;";case"bottom-right":return"position:fixed;z-index:2147483647;background:#141414;color:#fafafa;border:1px solid #262626;border-radius:8px;padding:16px;font-family:-apple-system,Segoe UI,Roboto,sans-serif;font-size:14px;line-height:1.5;box-shadow:0 4px 24px rgba(0,0,0,0.4);max-width:480px;bottom:16px;right:16px;";case"modal":return"position:fixed;z-index:2147483647;background:#141414;color:#fafafa;border:1px solid #262626;border-radius:8px;padding:16px;font-family:-apple-system,Segoe UI,Roboto,sans-serif;font-size:14px;line-height:1.5;box-shadow:0 4px 24px rgba(0,0,0,0.4);max-width:480px;top:50%;left:50%;transform:translate(-50%,-50%);";default:return"position:fixed;z-index:2147483647;background:#141414;color:#fafafa;border:1px solid #262626;border-radius:8px;padding:16px;font-family:-apple-system,Segoe UI,Roboto,sans-serif;font-size:14px;line-height:1.5;box-shadow:0 4px 24px rgba(0,0,0,0.4);max-width:480px;bottom:16px;left:50%;transform:translateX(-50%);"}}function qu(u,r){return`
|
|
2
|
+
<div style="margin-bottom:12px;font-weight:600;">${$(u.heading)}</div>
|
|
3
|
+
<div style="margin-bottom:16px;color:#a3a3a3;">${$(u.body)}</div>
|
|
4
4
|
<div style="display:flex;gap:8px;flex-wrap:wrap;">
|
|
5
|
-
<button data-gurulu-accept type="button" style="background:${
|
|
6
|
-
<button data-gurulu-reject type="button" style="background:transparent;color:#fafafa;border:1px solid #404040;padding:8px 16px;border-radius:6px;cursor:pointer;">${
|
|
5
|
+
<button data-gurulu-accept type="button" style="background:${du(r)};color:#0a0a0a;border:none;padding:8px 16px;border-radius:6px;font-weight:600;cursor:pointer;">${$(u.accept)}</button>
|
|
6
|
+
<button data-gurulu-reject type="button" style="background:transparent;color:#fafafa;border:1px solid #404040;padding:8px 16px;border-radius:6px;cursor:pointer;">${$(u.reject)}</button>
|
|
7
7
|
</div>
|
|
8
|
-
`}function M(u){return u.replace(/[&<>"']/g,(m)=>{switch(m){case"&":return"&";case"<":return"<";case">":return">";case'"':return""";case"'":return"'";default:return m}})}function Nu(u){return u.replace(/[^a-zA-Z0-9#()_\-., ]/g,"")}function Vu(){if(typeof navigator>"u")return"en";let u=(navigator.language??"").toLowerCase();if(u.startsWith("tr"))return"tr";if(u.startsWith("zh"))return"zh";if(u.startsWith("ar"))return"ar";return"en"}function G(){if(typeof crypto<"u"&&typeof crypto.randomUUID==="function")return`anon_${crypto.randomUUID()}`;return`anon_${Math.random().toString(36).slice(2)}${Date.now().toString(36)}`}async function Xu(){throw Error("fetch not available — provide opts.fetchImpl")}var $u=new Set(["A","BUTTON"]),hu=/\.(pdf|zip|dmg|exe|tar|gz|rar|7z|mp3|mp4|csv|xlsx?|docx?|pptx?)(\?|$)/i;function Ju(u){let m=u;while(m){if(m.hasAttribute?.("data-gurulu-no-track"))return!1;m=m.parentElement}return!0}function Mu(u){let m=u;while(m){if(!m.tagName){m=m.parentElement;continue}if($u.has(m.tagName))return m;if(m.getAttribute?.("role")==="button")return m;if(m.tagName==="INPUT"){let n=m.type?.toLowerCase();if(n==="submit"||n==="button")return m}m=m.parentElement}return null}function Qu(u){let m={};if(!u.attributes)return m;for(let n=0;n<u.attributes.length;n+=1){let _=u.attributes.item(n);if(!_)continue;if(_.name.startsWith("data-gurulu-prop-")){let A=_.name.slice(17);m[A]=_.value}}return m}function f(u){if(typeof document>"u")return{stop:()=>{return}};let m=(n)=>{let _=Mu(n.target);if(!_||!Ju(_))return;let A={element_tag:_.tagName.toLowerCase()};if(_.id)A.element_id=_.id;if(_.className&&typeof _.className==="string")A.element_class=_.className.slice(0,256);let C=(_.textContent??"").trim().slice(0,200);if(C)A.element_text=C;if(_.tagName==="A"){let l=_.href;if(l){A.href=l;try{let D=new URL(l).hostname;if(typeof window<"u"&&D!==window.location.hostname)A.is_outbound=!0}catch{}if(hu.test(l))A.is_download=!0}}let c=_.getAttribute?.("data-gurulu-event");if(c)A.custom_event=c,A.custom_props=Qu(_);u(A)};return document.addEventListener("click",m,!0),{stop(){document.removeEventListener("click",m,!0)}}}var Zu=new Set(["password","tel"]);function i(u){if(u.tagName!=="INPUT")return!1;let m=u,n=(m.type??"").toLowerCase();if(Zu.has(n))return!0;if((m.autocomplete??"").toLowerCase().startsWith("cc-"))return!0;return!1}function w(u){let m=u;while(m){if(m.hasAttribute?.("data-gurulu-no-track"))return!1;m=m.parentElement}return!0}function Fu(u){let m=u;while(m){if(m.tagName==="FORM")return m;m=m.parentElement}return null}function d(u){let m={count:u.elements?.length??0};if(u.id)m.id=u.id;if(u.name)m.name=u.name;return m}function o(u){if(typeof document>"u")return{stop:()=>{return}};let m=new WeakSet,n=(A)=>{let C=A.target;if(!C)return;if(i(C))return;if(!w(C))return;let c=Fu(C);if(!c||m.has(c))return;m.add(c);let l=d(c),D={field_count:l.count};if(l.id)D.form_id=l.id;if(l.name)D.form_name=l.name;u.onStart(D)},_=(A)=>{let C=A.target;if(!C||C.tagName!=="FORM")return;if(!w(C))return;let c=d(C),l=[],D=C.elements;for(let z=0;z<D.length;z+=1){let H=D[z];if(!H)continue;if(i(H))continue;if(!("value"in H))continue;if(typeof H.value==="string"&&H.value.length>0&&H.name)l.push(H.name)}let j={field_count:c.count};if(c.id)j.form_id=c.id;if(c.name)j.form_name=c.name;if(l.length>0)j.filled_fields=l;u.onSubmit(j)};return document.addEventListener("focus",n,!0),document.addEventListener("submit",_,!0),{stop(){document.removeEventListener("focus",n,!0),document.removeEventListener("submit",_,!0)}}}function g(u){if(typeof window>"u"||typeof document>"u")return{stop:()=>{return}};let m=window.location.pathname+window.location.search;function n(){let c=window.location.pathname+window.location.search;if(c===m)return;m=c,u(window.location.href,document.title,document.referrer)}u(window.location.href,document.title,document.referrer);let _=()=>n();window.addEventListener("popstate",_);let A=history.pushState.bind(history),C=history.replaceState.bind(history);return history.pushState=function(...l){let D=A(...l);return queueMicrotask(n),D},history.replaceState=function(...l){let D=C(...l);return queueMicrotask(n),D},{stop(){window.removeEventListener("popstate",_),history.pushState=A,history.replaceState=C}}}var Bu=[25,50,75,90];function O(u){if(typeof window>"u"||typeof document>"u")return{stop:()=>{return}};let m=new Set,n=0,_=()=>{n=0;let{documentElement:C,body:c}=document;if(!C||!c)return;let l=window.scrollY??C.scrollTop??0,D=window.innerHeight??C.clientHeight??0,j=Math.max(c.scrollHeight??0,C.scrollHeight??0);if(j<=D)return;let z=(l+D)/j*100;for(let H of Bu)if(z>=H&&!m.has(H))m.add(H),u({depth_percent:H})},A=()=>{if(n!==0)return;n=requestAnimationFrame(_)};return window.addEventListener("scroll",A,{passive:!0}),{stop(){if(window.removeEventListener("scroll",A),n!==0)cancelAnimationFrame(n)}}}var Gu={LCP:[2500,4000],FID:[100,300],INP:[200,500],CLS:[0.1,0.25],TTFB:[800,1800],FCP:[1800,3000]};function V(u,m){let[n,_]=Gu[u];if(m<=n)return"good";if(m<=_)return"needs-improvement";return"poor"}function Z(u,m,n){if(typeof PerformanceObserver>"u")return null;try{let _=new PerformanceObserver((A)=>n(A.getEntries()));return _.observe({type:u,buffered:m}),_}catch{return null}}function k(u){if(typeof window>"u")return{stop:()=>{return}};let m=[];try{let S=performance.getEntriesByType("navigation")[0];if(S&&S.responseStart>0)u({metric:"TTFB",value:S.responseStart,rating:V("TTFB",S.responseStart)});let T=performance.getEntriesByName("first-contentful-paint")[0];if(T)u({metric:"FCP",value:T.startTime,rating:V("FCP",T.startTime)})}catch{}let n=0,_=Z("largest-contentful-paint",!0,(S)=>{let T=S[S.length-1];if(T)n=T.startTime});if(_)m.push(_);let A=Z("first-input",!0,(S)=>{let T=S[0];if(T){let b=T.processingStart-T.startTime;u({metric:"FID",value:b,rating:V("FID",b)})}});if(A)m.push(A);let C=0,c=Z("event",!0,(S)=>{for(let T of S){let b=T.duration;if(b>C)C=b}});if(c)m.push(c);let l=0,D=Z("layout-shift",!0,(S)=>{for(let T of S){let b=T;if(!b.hadRecentInput)l+=b.value}});if(D)m.push(D);let j=()=>{if(n>0)u({metric:"LCP",value:n,rating:V("LCP",n)});if(C>0)u({metric:"INP",value:C,rating:V("INP",C)});if(l>0)u({metric:"CLS",value:l,rating:V("CLS",l)});n=0,C=0,l=0},z=null,H=null;if(typeof document<"u")z=()=>{if(document.visibilityState==="hidden")j()},H=j,document.addEventListener("visibilitychange",z),window.addEventListener("pagehide",H);return{stop(){for(let S of m)try{S.disconnect()}catch{}if(typeof document<"u"&&z)document.removeEventListener("visibilitychange",z);if(typeof window<"u"&&H)window.removeEventListener("pagehide",H)}}}var Ru={page_view:!0,click:!0,form_started:!0,form_submitted:!0,scroll_depth:!0,web_vitals:!0,outbound_link_click:!0,download_click:!0,js_error:!1,console_error:!1,network_error:!1};function y(u,m){if(u===!1)return{stopAll:()=>{return}};let n={...Ru,...u??{}},_=[];if(n.page_view)_.push(g(m.pageView));if(n.click)_.push(f(m.click));if(n.form_started||n.form_submitted)_.push(o({onStart:n.form_started?m.formStarted:()=>{return},onSubmit:n.form_submitted?m.formSubmitted:()=>{return}}));if(n.scroll_depth)_.push(O(m.scrollDepth));if(n.web_vitals)_.push(k(m.webVital));return{stopAll(){for(let A of _)try{A.stop()}catch{}}}}function X(){return typeof window<"u"&&typeof document<"u"}function W(){if(typeof crypto<"u"&&typeof crypto.randomUUID==="function")return crypto.randomUUID();return`${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`}function I(u){if(!X())return null;try{return window.localStorage.getItem(u)}catch{return null}}function F(u,m){if(!X())return;try{window.localStorage.setItem(u,m)}catch{}}function r(u){if(!X())return;try{window.localStorage.removeItem(u)}catch{}}function Wu(u){if(!X())return null;let m=document.cookie??"";for(let n of m.split(";")){let[_,A]=n.trim().split("=");if(_===u&&A!==void 0)return decodeURIComponent(A)}return null}function R(u,m,n=365){if(!X())return;let _=new Date(Date.now()+n*86400000).toUTCString(),A=window.location.hostname,C=A.split("."),c=C.length>=2?`.${C.slice(-2).join(".")}`:A;try{document.cookie=`${u}=${encodeURIComponent(m)}; path=/; domain=${c}; expires=${_}; SameSite=Lax`}catch{}}function v(){let u=I("gurulu_aid")??Wu("gurulu_aid_mirror");if(u)return F("gurulu_aid",u),R("gurulu_aid_mirror",u),u;let m=W();return F("gurulu_aid",m),R("gurulu_aid_mirror",m),m}function p(u){F("gurulu_pid",u)}function a(){return I("gurulu_pid")}function e(){r("gurulu_pid"),r("gurulu_aid");let u=W();return F("gurulu_aid",u),R("gurulu_aid_mirror",u),u}function s(){return W()}class E extends Error{code;constructor(u,m){super(m);this.code=u,this.name="SDKError"}}class uu extends E{constructor(u){super("SDK_INIT",u);this.name="InitError"}}class N extends E{status;constructor(u,m){super("SDK_NETWORK",u);if(this.name="NetworkError",m!==void 0)this.status=m}}class mu extends E{constructor(u){super("SDK_QUEUE_FULL",u);this.name="QueueFullError"}}class _u extends E{constructor(){super("SDK_OPTED_OUT","tracking disabled — gurulu.optOut() in effect");this.name="OptedOutError"}}class nu extends E{constructor(){super("SDK_CONSENT_BLOCKED","event queued — awaiting consent grant");this.name="ConsentBlockedError"}}var tu=65536;function Au(u,m){let n=new Headers({"content-type":"application/json",authorization:`Bearer ${u.workspaceKey}`,"x-gurulu-sdk":`@gurulu/web@${u.sdkVersion}`});if(m)for(let[_,A]of Object.entries(m))n.set(_,A);return n}async function Cu(u,m,n){let _=u.fetchImpl??(typeof fetch<"u"?fetch.bind(globalThis):null);if(!_)throw new N("fetch unavailable");let A=`${u.endpoint}/v1/ingest/batch`,C=await _(A,{method:"POST",keepalive:!0,credentials:"omit",headers:Au(u,n),body:JSON.stringify(m)});if(!C.ok)throw new N(`ingest ${C.status}`,C.status)}function cu(u,m){if(typeof navigator>"u"||typeof navigator.sendBeacon!=="function")return!1;let n=`${u.endpoint}/v1/ingest/batch?wk=${encodeURIComponent(u.workspaceKey)}&sdk=${encodeURIComponent(u.sdkVersion)}`;try{let _=JSON.stringify(m);if(_.length>=tu)return!1;let A=new Blob([_],{type:"application/json"});return navigator.sendBeacon(n,A)}catch{return!1}}async function lu(u,m){let n=u.fetchImpl??(typeof fetch<"u"?fetch.bind(globalThis):null);if(!n)throw new N("fetch unavailable");let _=await n(`${u.endpoint}/v1/ingest/identify`,{method:"POST",keepalive:!0,credentials:"omit",headers:Au(u),body:JSON.stringify(m)});if(!_.ok)throw new N(`identify ${_.status}`,_.status)}var Y="gurulu_queue";function L(){return typeof window<"u"}function Yu(){if(!L())return[];try{let u=window.localStorage.getItem(Y);if(!u)return[];let m=JSON.parse(u);return Array.isArray(m)?m:[]}catch{return[]}}function t(u){if(!L())return;try{if(u.length===0)window.localStorage.removeItem(Y);else window.localStorage.setItem(Y,JSON.stringify(u))}catch{}}class P{opts;buffer;timer=null;flushing=!1;constructor(u){if(this.opts=u,this.buffer=Yu(),this.scheduleNext(),this.installUnloadHooks(),this.buffer.length>0)this.scheduleImmediate()}enqueue(u){if(this.buffer.push(u),t(this.buffer),this.buffer.length>=this.opts.maxQueueSize)this.flush();else this.scheduleNext()}size(){return this.buffer.length}async flush(){if(this.flushing||this.buffer.length===0)return;this.flushing=!0;let u=this.buffer.slice(0);try{await this.sendWithRetry(u),this.buffer=this.buffer.slice(u.length),t(this.buffer)}catch(m){if(this.opts.debug&&typeof console<"u")console.warn("[gurulu] flush failed, retain queue",m)}finally{this.flushing=!1}}flushBeacon(){if(this.buffer.length===0)return;if(cu(this.opts.transport,{events:this.buffer}))this.buffer=[],t(this.buffer)}scheduleNext(){if(this.timer!==null)return;this.timer=setTimeout(()=>{this.timer=null,this.flush()},this.opts.flushIntervalMs)}scheduleImmediate(){if(this.timer!==null)clearTimeout(this.timer),this.timer=null;this.timer=setTimeout(()=>{this.timer=null,this.flush()},50)}async sendWithRetry(u){let m=0,n=3;while(m<n)try{await Cu(this.opts.transport,{events:u});return}catch(_){if(m+=1,m>=n)throw _;let A=2**m*1000;await new Promise((C)=>setTimeout(C,A))}}installUnloadHooks(){if(!L()||typeof document>"u")return;let u=()=>{if(document.visibilityState==="hidden")this.flushBeacon()};try{document.addEventListener("visibilitychange",u),window.addEventListener("pagehide",()=>this.flushBeacon())}catch{}}}function Du(){return typeof window<"u"}function Lu(){if(typeof crypto<"u"&&typeof crypto.randomUUID==="function")return crypto.randomUUID();return`${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`}function h(u){if(!Du())return null;try{return window.localStorage.getItem(u)}catch{return null}}function $(u,m){if(!Du())return;try{window.localStorage.setItem(u,m)}catch{}}function B(u=Date.now()){let m=h("gurulu_sid"),n=Number(h("gurulu_session_started_at")??"0"),_=Number(h("gurulu_last_event_at")??"0");if(m&&n&&u-_<1800000)return $("gurulu_last_event_at",String(u)),{session_id:m,session_started_at:n,is_new:!1};let A=Lu();return $("gurulu_sid",A),$("gurulu_session_started_at",String(u)),$("gurulu_last_event_at",String(u)),{session_id:A,session_started_at:u,is_new:!0}}function Hu(u,m){let n={},_={};if(!u)return{utm:n,click_id:_};let A;try{A=new URL(u)}catch{return{utm:n,click_id:_}}let C=A.searchParams,c=C.get("utm_source");if(c)n.source=c;let l=C.get("utm_medium");if(l)n.medium=l;let D=C.get("utm_campaign");if(D)n.campaign=D;let j=C.get("utm_term");if(j)n.term=j;let z=C.get("utm_content");if(z)n.content=z;let H=C.get("gclid");if(H)_.gclid=H;let S=C.get("fbclid");if(S)_.fbclid=S;let T=C.get("ttclid");if(T)_.ttclid=T;let b=C.get("li_fat_id");if(b)_.li_fat_id=b;return{utm:n,click_id:_}}function Su(u){if(h("gurulu_first_source"))return;$("gurulu_first_source",JSON.stringify(u))}function Tu(){let u=h("gurulu_first_source");if(!u)return null;try{return JSON.parse(u)}catch{return null}}var K="0.1.0",ju="https://ingest.gurulu.io",Pu="https://api.gurulu.io",U="gurulu_opt_out";function zu(){if(typeof window>"u")return!1;try{return window.localStorage.getItem(U)==="1"}catch{return!1}}function bu(u){if(typeof window>"u")return;try{if(u)window.localStorage.setItem(U,"1");else window.localStorage.removeItem(U)}catch{}}function Ku(){return new Date().toISOString()}class J{initialized=!1;opts=null;queue=null;session=null;anonymousId=null;autocaptureHandle=null;testMode=!1;consent;init(u){if(this.initialized){if(u.debug&&typeof console<"u")console.warn("[gurulu] init() already called — ignoring");return}if(typeof window>"u")return;this.opts=u,this.testMode=u.test_mode===!0,this.anonymousId=v(),this.session=B(),this.consent=new Q({workspaceId:u.workspaceKey,apiUrl:u.apiUrl??Pu,anonymousId:this.anonymousId,autoBanner:u.consent_mode==="banner_required"}),this.consent.init();let m={endpoint:u.endpoint??ju,workspaceKey:u.workspaceKey,sdkVersion:K};this.queue=new P({transport:m,flushIntervalMs:u.flush_interval_ms??5000,maxQueueSize:u.max_queue_size??50,...u.debug?{debug:!0}:{}});let n=Hu(window.location.href,document.referrer);if(Object.keys(n.utm).length>0||Object.keys(n.click_id).length>0){let _={utm:n.utm,click_id:n.click_id,referrer:document.referrer,landing_url:window.location.href,captured_at:Date.now()};Su(_)}this.autocaptureHandle=y(u.autocapture,{pageView:(_,A,C)=>this.queueEvent("page_view","interaction",{url:_,title:A,referrer:C}),click:(_)=>{let A=_.custom_event??"element_clicked",C={element_tag:_.element_tag,..._.element_id?{element_id:_.element_id}:{},..._.element_class?{element_class:_.element_class}:{},..._.element_text?{element_text:_.element_text}:{},..._.href?{href:_.href}:{},..._.is_outbound?{is_outbound:!0}:{},..._.is_download?{is_download:!0}:{},..._.custom_props??{}};this.queueEvent(A,"interaction",C)},formStarted:(_)=>this.queueEvent("form_started","interaction",_),formSubmitted:(_)=>this.queueEvent("form_submitted","interaction",_),scrollDepth:(_)=>this.queueEvent("scroll_depth","interaction",_),webVital:(_)=>this.queueEvent("web_vital","interaction",_)}),this.initialized=!0}track(u,m){this.queueEvent(u,"interaction",m)}page(u){if(!this.initialized||typeof window>"u")return;let m=u?.url??window.location.href,n=u?.title??document.title,_=u?.referrer??document.referrer;this.queueEvent("page_view","interaction",{url:m,title:n,referrer:_})}async identify(u,m){if(!this.initialized||zu())return;if(p(u),!this.opts)return;try{await lu({endpoint:this.opts.endpoint??ju,workspaceKey:this.opts.workspaceKey,sdkVersion:K},{anonymous_id:this.anonymousId,external_user_id:u,...m?.email?{email:m.email}:{},...m?.phone?{phone:m.phone}:{},...m?{traits:m}:{}})}catch(n){if(this.opts?.debug&&typeof console<"u")console.warn("[gurulu] identify failed",n)}}reset(){if(this.anonymousId=e(),typeof window<"u")try{window.localStorage.removeItem("gurulu_sid"),window.localStorage.removeItem("gurulu_session_started_at"),window.localStorage.removeItem("gurulu_last_event_at"),window.localStorage.removeItem("gurulu_first_source")}catch{}this.session=B()}async flush(){await this.queue?.flush()}optOut(){bu(!0)}optIn(){bu(!1)}queueEvent(u,m,n){if(!this.initialized||!this.queue||zu())return;if(!this.consentAllowsAnalytics()&&this.opts?.consent_mode==="banner_required")return;this.session=B();let _={anonymous_id:this.anonymousId??"anon_unknown",event_id:s(),event_key:u,event_type:m,occurred_at:Ku(),producer:"script",producer_version:K,...this.session?{session_id:this.session.session_id}:{}},A=a();if(A)_.person_id=A;if(n&&Object.keys(n).length>0)_.properties=n;let C=this.buildContext();if(C)_.context=C;let c=this.snapshotConsent();if(c)_.consent_state=c;if(this.testMode)_.test_mode=!0;this.queue.enqueue(_)}snapshotConsent(){let u=this.consent?.getState();if(!u)return;return{necessary:u.categories.necessary,analytics:u.categories.analytics,marketing:u.categories.marketing,functional:u.categories.functional,personalization:u.categories.personalization}}consentAllowsAnalytics(){let u=this.consent?.getState();if(!u)return!1;return u.categories.analytics===!0}buildContext(){if(typeof window>"u")return;let u={url:window.location.href,referrer:document.referrer,page_title:document.title,user_agent:navigator.userAgent,domain:window.location.hostname},m=Tu();if(m?.utm&&Object.keys(m.utm).length>0)u.utm=m.utm;if(m?.click_id&&Object.keys(m.click_id).length>0)u.click_id=m.click_id;return u}}var Uu="0.1.0",q=new J;function Tm(){return new J}var x={init:(u)=>q.init(u),track:(u,m)=>q.track(u,m),identify:(u,m)=>q.identify(u,m),page:(u)=>q.page(u),reset:()=>q.reset(),flush:()=>q.flush(),optOut:()=>q.optOut(),optIn:()=>q.optIn(),get consent(){return q.consent},VERSION:Uu};function xu(){if(typeof document>"u")return;let u=document.currentScript,m=!u?document.querySelector("script[data-workspace]"):u;if(!m)return;let n=m.getAttribute("data-workspace");if(!n)return;let _={workspaceKey:n},A=m.getAttribute("data-endpoint");if(A)_.endpoint=A;let C=m.getAttribute("data-api-url");if(C)_.apiUrl=C;let c=m.getAttribute("data-consent");if(c==="banner_required"||c==="allow_by_default")_.consent_mode=c;let l=m.getAttribute("data-allowlist");if(l)_.cross_domain_allowlist=l.split(",").map((D)=>D.trim());if(x.init(_),typeof window<"u")window.gurulu=x}xu();var Em=x;export{Em as default,Tm as createGurulu,xu as autoBootstrap,Uu as VERSION,E as SDKError,mu as QueueFullError,_u as OptedOutError,N as NetworkError,uu as InitError,Q as GuruluConsent,J as Gurulu,nu as ConsentBlockedError};
|
|
8
|
+
`}function $(u){return u.replace(/[&<>"']/g,(r)=>{switch(r){case"&":return"&";case"<":return"<";case">":return">";case'"':return""";case"'":return"'";default:return r}})}function du(u){return u.replace(/[^a-zA-Z0-9#()_\-., ]/g,"")}function Vu(){if(typeof navigator>"u")return"en";let u=(navigator.language??"").toLowerCase();if(u.startsWith("tr"))return"tr";if(u.startsWith("zh"))return"zh";if(u.startsWith("ar"))return"ar";return"en"}function R(){if(typeof crypto<"u"&&typeof crypto.randomUUID==="function")return`anon_${crypto.randomUUID()}`;return`anon_${Math.random().toString(36).slice(2)}${Date.now().toString(36)}`}async function $u(){throw Error("fetch not available — provide opts.fetchImpl")}var hu=new Set(["A","BUTTON"]),Nu=/\.(pdf|zip|dmg|exe|tar|gz|rar|7z|mp3|mp4|csv|xlsx?|docx?|pptx?)(\?|$)/i;function Gu(u){let r=u;while(r){if(r.hasAttribute?.("data-gurulu-no-track"))return!1;r=r.parentElement}return!0}function Qu(u){let r=u;while(r){if(!r.tagName){r=r.parentElement;continue}if(hu.has(r.tagName))return r;if(r.getAttribute?.("role")==="button")return r;if(r.tagName==="INPUT"){let o=r.type?.toLowerCase();if(o==="submit"||o==="button")return r}r=r.parentElement}return null}function Ru(u){let r={};if(!u.attributes)return r;for(let o=0;o<u.attributes.length;o+=1){let n=u.attributes.item(o);if(!n)continue;if(n.name.startsWith("data-gurulu-prop-")){let m=n.name.slice(17);r[m]=n.value}}return r}function U(u){if(typeof document>"u")return{stop:()=>{return}};let r=(o)=>{let n=Qu(o.target);if(!n||!Gu(n))return;let m={element_tag:n.tagName.toLowerCase()};if(n.id)m.element_id=n.id;if(n.className&&typeof n.className==="string")m.element_class=n.className.slice(0,256);let _=(n.textContent??"").trim().slice(0,200);if(_)m.element_text=_;if(n.tagName==="A"){let A=n.href;if(A){m.href=A;try{let E=new URL(A).hostname;if(typeof window<"u"&&E!==window.location.hostname)m.is_outbound=!0}catch{}if(Nu.test(A))m.is_download=!0}}let c=n.getAttribute?.("data-gurulu-event");if(c)m.custom_event=c,m.custom_props=Ru(n);u(m)};return document.addEventListener("click",r,!0),{stop(){document.removeEventListener("click",r,!0)}}}function K(u){if(typeof window>"u")return{stop:()=>{return}};let r=(n)=>{let m=n.error;u({message:String(n.message??m?.message??"Error").slice(0,1000),error_type:m?.name??"Error",...n.filename?{source:n.filename}:{},...typeof n.lineno==="number"?{lineno:n.lineno}:{},...typeof n.colno==="number"?{colno:n.colno}:{},...m?.stack?{stack:String(m.stack).slice(0,2000)}:{}})},o=(n)=>{let m=n.reason,_=m instanceof Error;u({message:String(_?m.message:m).slice(0,1000),error_type:_?m.name:"UnhandledRejection",..._&&m.stack?{stack:String(m.stack).slice(0,2000)}:{}})};return window.addEventListener("error",r),window.addEventListener("unhandledrejection",o),{stop(){window.removeEventListener("error",r),window.removeEventListener("unhandledrejection",o)}}}var Zu=new Set(["password","tel"]);function O(u){if(u.tagName!=="INPUT")return!1;let r=u,o=(r.type??"").toLowerCase();if(Zu.has(o))return!0;if((r.autocomplete??"").toLowerCase().startsWith("cc-"))return!0;return!1}function k(u){let r=u;while(r){if(r.hasAttribute?.("data-gurulu-no-track"))return!1;r=r.parentElement}return!0}function iu(u){let r=u;while(r){if(r.tagName==="FORM")return r;r=r.parentElement}return null}function x(u){let r={count:u.elements?.length??0};if(u.id)r.id=u.id;if(u.name)r.name=u.name;return r}function y(u){if(typeof document>"u")return{stop:()=>{return}};let r=new WeakSet,o=(m)=>{let _=m.target;if(!_)return;if(O(_))return;if(!k(_))return;let c=iu(_);if(!c||r.has(c))return;r.add(c);let A=x(c),E={field_count:A.count};if(A.id)E.form_id=A.id;if(A.name)E.form_name=A.name;u.onStart(E)},n=(m)=>{let _=m.target;if(!_||_.tagName!=="FORM")return;if(!k(_))return;let c=x(_),A=[],E=_.elements;for(let t=0;t<E.length;t+=1){let l=E[t];if(!l)continue;if(O(l))continue;if(!("value"in l))continue;if(typeof l.value==="string"&&l.value.length>0&&l.name)A.push(l.name)}let j={field_count:c.count};if(c.id)j.form_id=c.id;if(c.name)j.form_name=c.name;if(A.length>0)j.filled_fields=A;u.onSubmit(j)};return document.addEventListener("focus",o,!0),document.addEventListener("submit",n,!0),{stop(){document.removeEventListener("focus",o,!0),document.removeEventListener("submit",n,!0)}}}function I(u){if(typeof window>"u"||typeof document>"u")return{stop:()=>{return}};let r=window.location.pathname+window.location.search;function o(){let c=window.location.pathname+window.location.search;if(c===r)return;r=c,u(window.location.href,document.title,document.referrer)}u(window.location.href,document.title,document.referrer);let n=()=>o();window.addEventListener("popstate",n);let m=history.pushState.bind(history),_=history.replaceState.bind(history);return history.pushState=function(...A){let E=m(...A);return queueMicrotask(o),E},history.replaceState=function(...A){let E=_(...A);return queueMicrotask(o),E},{stop(){window.removeEventListener("popstate",n),history.pushState=m,history.replaceState=_}}}var fu=[25,50,75,90];function v(u){if(typeof window>"u"||typeof document>"u")return{stop:()=>{return}};let r=new Set,o=0,n=()=>{o=0;let{documentElement:_,body:c}=document;if(!_||!c)return;let A=window.scrollY??_.scrollTop??0,E=window.innerHeight??_.clientHeight??0,j=Math.max(c.scrollHeight??0,_.scrollHeight??0);if(j<=E)return;let t=(A+E)/j*100;for(let l of fu)if(t>=l&&!r.has(l))r.add(l),u({depth_percent:l})},m=()=>{if(o!==0)return;o=requestAnimationFrame(n)};return window.addEventListener("scroll",m,{passive:!0}),{stop(){if(window.removeEventListener("scroll",m),o!==0)cancelAnimationFrame(o)}}}var Fu={LCP:[2500,4000],FID:[100,300],INP:[200,500],CLS:[0.1,0.25],TTFB:[800,1800],FCP:[1800,3000]};function M(u,r){let[o,n]=Fu[u];if(r<=o)return"good";if(r<=n)return"needs-improvement";return"poor"}function N(u,r,o){if(typeof PerformanceObserver>"u")return null;try{let n=new PerformanceObserver((m)=>o(m.getEntries()));return n.observe({type:u,buffered:r}),n}catch{return null}}function a(u){if(typeof window>"u")return{stop:()=>{return}};let r=[];try{let C=performance.getEntriesByType("navigation")[0];if(C&&C.responseStart>0)u({metric:"TTFB",value:C.responseStart,rating:M("TTFB",C.responseStart)});let S=performance.getEntriesByName("first-contentful-paint")[0];if(S)u({metric:"FCP",value:S.startTime,rating:M("FCP",S.startTime)})}catch{}let o=0,n=N("largest-contentful-paint",!0,(C)=>{let S=C[C.length-1];if(S)o=S.startTime});if(n)r.push(n);let m=N("first-input",!0,(C)=>{let S=C[0];if(S){let H=S.processingStart-S.startTime;u({metric:"FID",value:H,rating:M("FID",H)})}});if(m)r.push(m);let _=0,c=N("event",!0,(C)=>{for(let S of C){let H=S.duration;if(H>_)_=H}});if(c)r.push(c);let A=0,E=N("layout-shift",!0,(C)=>{for(let S of C){let H=S;if(!H.hadRecentInput)A+=H.value}});if(E)r.push(E);let j=()=>{if(o>0)u({metric:"LCP",value:o,rating:M("LCP",o)});if(_>0)u({metric:"INP",value:_,rating:M("INP",_)});if(A>0)u({metric:"CLS",value:A,rating:M("CLS",A)});o=0,_=0,A=0},t=null,l=null;if(typeof document<"u")t=()=>{if(document.visibilityState==="hidden")j()},l=j,document.addEventListener("visibilitychange",t),window.addEventListener("pagehide",l);return{stop(){for(let C of r)try{C.disconnect()}catch{}if(typeof document<"u"&&t)document.removeEventListener("visibilitychange",t);if(typeof window<"u"&&l)window.removeEventListener("pagehide",l)}}}var gu={page_view:!0,click:!0,form_started:!0,form_submitted:!0,scroll_depth:!0,web_vitals:!0,outbound_link_click:!0,download_click:!0,js_error:!1,console_error:!1,network_error:!1};function e(u,r){if(u===!1)return{stopAll:()=>{return}};let o={...gu,...u??{}},n=[];if(o.page_view)n.push(I(r.pageView));if(o.click)n.push(U(r.click));if(o.form_started||o.form_submitted)n.push(y({onStart:o.form_started?r.formStarted:()=>{return},onSubmit:o.form_submitted?r.formSubmitted:()=>{return}}));if(o.scroll_depth)n.push(v(r.scrollDepth));if(o.web_vitals)n.push(a(r.webVital));if(o.js_error)n.push(K(r.jsError));return{stopAll(){for(let m of n)try{m.stop()}catch{}}}}function z(){return typeof window<"u"&&typeof document<"u"}function i(){if(typeof crypto<"u"&&typeof crypto.randomUUID==="function")return crypto.randomUUID();return`${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`}function s(u){if(!z())return null;try{return window.localStorage.getItem(u)}catch{return null}}function G(u,r){if(!z())return;try{window.localStorage.setItem(u,r)}catch{}}function p(u){if(!z())return;try{window.localStorage.removeItem(u)}catch{}}function wu(u){if(!z())return null;let r=document.cookie??"";for(let o of r.split(";")){let[n,m]=o.trim().split("=");if(n===u&&m!==void 0)return decodeURIComponent(m)}return null}function Z(u,r,o=365){if(!z())return;let n=new Date(Date.now()+o*86400000).toUTCString(),m=window.location.hostname,_=m.split("."),c=_.length>=2?`.${_.slice(-2).join(".")}`:m;try{document.cookie=`${u}=${encodeURIComponent(r)}; path=/; domain=${c}; expires=${n}; SameSite=Lax`}catch{}}function uu(){let u=s("gurulu_aid")??wu("gurulu_aid_mirror");if(u)return G("gurulu_aid",u),Z("gurulu_aid_mirror",u),u;let r=i();return G("gurulu_aid",r),Z("gurulu_aid_mirror",r),r}function ru(u){G("gurulu_pid",u)}function f(){return s("gurulu_pid")}function nu(){p("gurulu_pid"),p("gurulu_aid");let u=i();return G("gurulu_aid",u),Z("gurulu_aid_mirror",u),u}function ou(){return i()}class J extends Error{code;constructor(u,r){super(r);this.code=u,this.name="SDKError"}}class mu extends J{constructor(u){super("SDK_INIT",u);this.name="InitError"}}class b extends J{status;constructor(u,r){super("SDK_NETWORK",u);if(this.name="NetworkError",r!==void 0)this.status=r}}class _u extends J{constructor(u){super("SDK_QUEUE_FULL",u);this.name="QueueFullError"}}class cu extends J{constructor(){super("SDK_OPTED_OUT","tracking disabled — gurulu.optOut() in effect");this.name="OptedOutError"}}class Au extends J{constructor(){super("SDK_CONSENT_BLOCKED","event queued — awaiting consent grant");this.name="ConsentBlockedError"}}var Wu=65536;function Eu(u,r){let o=new Headers({"content-type":"application/json",authorization:`Bearer ${u.workspaceKey}`,"x-gurulu-sdk":`@gurulu/web@${u.sdkVersion}`});if(r)for(let[n,m]of Object.entries(r))o.set(n,m);return o}async function lu(u,r,o){let n=u.fetchImpl??(typeof fetch<"u"?fetch.bind(globalThis):null);if(!n)throw new b("fetch unavailable");let m=`${u.endpoint}/v1/ingest/batch`,_=await n(m,{method:"POST",keepalive:!0,credentials:"omit",headers:Eu(u,o),body:JSON.stringify(r)});if(!_.ok)throw new b(`ingest ${_.status}`,_.status)}function Cu(u,r){if(typeof navigator>"u"||typeof navigator.sendBeacon!=="function")return!1;let o=`${u.endpoint}/v1/ingest/batch?wk=${encodeURIComponent(u.workspaceKey)}&sdk=${encodeURIComponent(u.sdkVersion)}`;try{let n=JSON.stringify(r);if(n.length>=Wu)return!1;let m=new Blob([n],{type:"application/json"});return navigator.sendBeacon(o,m)}catch{return!1}}async function Su(u,r){let o=u.fetchImpl??(typeof fetch<"u"?fetch.bind(globalThis):null);if(!o)throw new b("fetch unavailable");let n=await o(`${u.endpoint}/v1/ingest/identify`,{method:"POST",keepalive:!0,credentials:"omit",headers:Eu(u),body:JSON.stringify(r)});if(!n.ok)throw new b(`identify ${n.status}`,n.status)}var g="gurulu_queue";function w(){return typeof window<"u"}function Bu(){if(!w())return[];try{let u=window.localStorage.getItem(g);if(!u)return[];let r=JSON.parse(u);return Array.isArray(r)?r:[]}catch{return[]}}function F(u){if(!w())return;try{if(u.length===0)window.localStorage.removeItem(g);else window.localStorage.setItem(g,JSON.stringify(u))}catch{}}class W{opts;buffer;timer=null;flushing=!1;constructor(u){if(this.opts=u,this.buffer=Bu(),this.scheduleNext(),this.installUnloadHooks(),this.buffer.length>0)this.scheduleImmediate()}enqueue(u){if(this.buffer.push(u),F(this.buffer),this.buffer.length>=this.opts.maxQueueSize)this.flush();else this.scheduleNext()}size(){return this.buffer.length}async flush(){if(this.flushing||this.buffer.length===0)return;this.flushing=!0;let u=this.buffer.slice(0);try{await this.sendWithRetry(u),this.buffer=this.buffer.slice(u.length),F(this.buffer)}catch(r){if(this.opts.debug&&typeof console<"u")console.warn("[gurulu] flush failed, retain queue",r)}finally{this.flushing=!1}}flushBeacon(){if(this.buffer.length===0)return;if(Cu(this.opts.transport,{events:this.buffer}))this.buffer=[],F(this.buffer)}scheduleNext(){if(this.timer!==null)return;this.timer=setTimeout(()=>{this.timer=null,this.flush()},this.opts.flushIntervalMs)}scheduleImmediate(){if(this.timer!==null)clearTimeout(this.timer),this.timer=null;this.timer=setTimeout(()=>{this.timer=null,this.flush()},50)}async sendWithRetry(u){let r=0,o=3;while(r<o)try{await lu(this.opts.transport,{events:u});return}catch(n){if(r+=1,r>=o)throw n;let m=2**r*1000;await new Promise((_)=>setTimeout(_,m))}}installUnloadHooks(){if(!w()||typeof document>"u")return;let u=()=>{if(document.visibilityState==="hidden")this.flushBeacon()};try{document.addEventListener("visibilitychange",u),window.addEventListener("pagehide",()=>this.flushBeacon())}catch{}}}function ju(){return typeof window<"u"}function Lu(){if(typeof crypto<"u"&&typeof crypto.randomUUID==="function")return crypto.randomUUID();return`${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`}function T(u){if(!ju())return null;try{return window.localStorage.getItem(u)}catch{return null}}function D(u,r){if(!ju())return;try{window.localStorage.setItem(u,r)}catch{}}function Q(u=Date.now()){let r=T("gurulu_sid"),o=Number(T("gurulu_session_started_at")??"0"),n=Number(T("gurulu_last_event_at")??"0");if(r&&o&&u-n<1800000)return D("gurulu_last_event_at",String(u)),{session_id:r,session_started_at:o,is_new:!1};let m=Lu();return D("gurulu_sid",m),D("gurulu_session_started_at",String(u)),D("gurulu_last_event_at",String(u)),{session_id:m,session_started_at:u,is_new:!0}}function tu(u,r){let o={},n={};if(!u)return{utm:o,click_id:n};let m;try{m=new URL(u)}catch{return{utm:o,click_id:n}}let _=m.searchParams,c=_.get("utm_source");if(c)o.source=c;let A=_.get("utm_medium");if(A)o.medium=A;let E=_.get("utm_campaign");if(E)o.campaign=E;let j=_.get("utm_term");if(j)o.term=j;let t=_.get("utm_content");if(t)o.content=t;let l=_.get("gclid");if(l)n.gclid=l;let C=_.get("fbclid");if(C)n.fbclid=C;let S=_.get("ttclid");if(S)n.ttclid=S;let H=_.get("li_fat_id");if(H)n.li_fat_id=H;return{utm:o,click_id:n}}function Hu(u){if(T("gurulu_first_source"))return;D("gurulu_first_source",JSON.stringify(u))}function Xu(){let u=T("gurulu_first_source");if(!u)return null;try{return JSON.parse(u)}catch{return null}}var B="0.1.0",L="https://ingest.gurulu.io",Yu="https://api.gurulu.io",Y="gurulu_opt_out";function Ju(){if(typeof window>"u")return!1;try{return window.localStorage.getItem(Y)==="1"}catch{return!1}}function bu(u){if(typeof window>"u")return;try{if(u)window.localStorage.setItem(Y,"1");else window.localStorage.removeItem(Y)}catch{}}function Pu(){return new Date().toISOString()}class q{initialized=!1;opts=null;queue=null;session=null;anonymousId=null;autocaptureHandle=null;testMode=!1;consent;activation;init(u){if(this.initialized){if(u.debug&&typeof console<"u")console.warn("[gurulu] init() already called — ignoring");return}if(typeof window>"u")return;this.opts=u,this.testMode=u.test_mode===!0,this.anonymousId=uu(),this.session=Q(),this.consent=new h({workspaceId:u.workspaceKey,apiUrl:u.apiUrl??Yu,anonymousId:this.anonymousId,autoBanner:u.consent_mode==="banner_required"}),this.consent.init(),this.activation=new V({endpoint:u.endpoint??L,workspaceKey:u.workspaceKey,getUid:()=>f()??this.anonymousId??"",track:(n,m)=>this.track(n,m)});let r={endpoint:u.endpoint??L,workspaceKey:u.workspaceKey,sdkVersion:B};this.queue=new W({transport:r,flushIntervalMs:u.flush_interval_ms??5000,maxQueueSize:u.max_queue_size??50,...u.debug?{debug:!0}:{}});let o=tu(window.location.href,document.referrer);if(Object.keys(o.utm).length>0||Object.keys(o.click_id).length>0){let n={utm:o.utm,click_id:o.click_id,referrer:document.referrer,landing_url:window.location.href,captured_at:Date.now()};Hu(n)}this.autocaptureHandle=e(u.autocapture,{pageView:(n,m,_)=>this.queueEvent("page_view","interaction",{url:n,title:m,referrer:_}),click:(n)=>{let m=n.custom_event??"element_clicked",_={element_tag:n.element_tag,...n.element_id?{element_id:n.element_id}:{},...n.element_class?{element_class:n.element_class}:{},...n.element_text?{element_text:n.element_text}:{},...n.href?{href:n.href}:{},...n.is_outbound?{is_outbound:!0}:{},...n.is_download?{is_download:!0}:{},...n.custom_props??{}};this.queueEvent(m,"interaction",_)},formStarted:(n)=>this.queueEvent("form_started","interaction",n),formSubmitted:(n)=>this.queueEvent("form_submitted","interaction",n),scrollDepth:(n)=>this.queueEvent("scroll_depth","interaction",n),webVital:(n)=>this.queueEvent("web_vital","interaction",n),jsError:(n)=>this.queueEvent("js_error","interaction",n)}),this.initialized=!0}track(u,r){this.queueEvent(u,"interaction",r)}page(u){if(!this.initialized||typeof window>"u")return;let r=u?.url??window.location.href,o=u?.title??document.title,n=u?.referrer??document.referrer;this.queueEvent("page_view","interaction",{url:r,title:o,referrer:n})}async identify(u,r){if(!this.initialized||Ju())return;if(ru(u),!this.opts)return;try{await Su({endpoint:this.opts.endpoint??L,workspaceKey:this.opts.workspaceKey,sdkVersion:B},{anonymous_id:this.anonymousId,external_user_id:u,...r?.email?{email:r.email}:{},...r?.phone?{phone:r.phone}:{},...r?{traits:r}:{}})}catch(o){if(this.opts?.debug&&typeof console<"u")console.warn("[gurulu] identify failed",o)}}reset(){if(this.anonymousId=nu(),typeof window<"u")try{window.localStorage.removeItem("gurulu_sid"),window.localStorage.removeItem("gurulu_session_started_at"),window.localStorage.removeItem("gurulu_last_event_at"),window.localStorage.removeItem("gurulu_first_source")}catch{}this.session=Q()}async flush(){await this.queue?.flush()}optOut(){bu(!0)}optIn(){bu(!1)}queueEvent(u,r,o){if(!this.initialized||!this.queue||Ju())return;if(!this.consentAllowsAnalytics()&&this.opts?.consent_mode==="banner_required")return;this.session=Q();let n={anonymous_id:this.anonymousId??"anon_unknown",event_id:ou(),event_key:u,event_type:r,occurred_at:Pu(),producer:"script",producer_version:B,...this.session?{session_id:this.session.session_id}:{}},m=f();if(m)n.person_id=m;if(o&&Object.keys(o).length>0)n.properties=o;let _=this.buildContext();if(_)n.context=_;let c=this.snapshotConsent();if(c)n.consent_state=c;if(this.testMode)n.test_mode=!0;this.queue.enqueue(n)}snapshotConsent(){let u=this.consent?.getState();if(!u)return;return{necessary:u.categories.necessary,analytics:u.categories.analytics,marketing:u.categories.marketing,functional:u.categories.functional,personalization:u.categories.personalization}}consentAllowsAnalytics(){let u=this.consent?.getState();if(!u)return!1;return u.categories.analytics===!0}buildContext(){if(typeof window>"u")return;let u={url:window.location.href,referrer:document.referrer,page_title:document.title,user_agent:navigator.userAgent,domain:window.location.hostname},r=Xu();if(r?.utm&&Object.keys(r.utm).length>0)u.utm=r.utm;if(r?.click_id&&Object.keys(r.click_id).length>0)u.click_id=r.click_id;return u}}var Uu="0.1.0",X=new q;function Tr(){return new q}var P={init:(u)=>X.init(u),track:(u,r)=>X.track(u,r),identify:(u,r)=>X.identify(u,r),page:(u)=>X.page(u),reset:()=>X.reset(),flush:()=>X.flush(),optOut:()=>X.optOut(),optIn:()=>X.optIn(),get consent(){return X.consent},get activation(){return X.activation},VERSION:Uu};function Ku(){if(typeof document>"u")return;let u=document.currentScript,r=!u?document.querySelector("script[data-workspace]"):u;if(!r)return;let o=r.getAttribute("data-workspace");if(!o)return;let n={workspaceKey:o},m=r.getAttribute("data-endpoint");if(m)n.endpoint=m;let _=r.getAttribute("data-api-url");if(_)n.apiUrl=_;let c=r.getAttribute("data-consent");if(c==="banner_required"||c==="allow_by_default")n.consent_mode=c;let A=r.getAttribute("data-allowlist");if(A)n.cross_domain_allowlist=A.split(",").map((E)=>E.trim());if(P.init(n),typeof window<"u")window.gurulu=P}Ku();var Nr=P;export{Nr as default,Tr as createGurulu,Ku as autoBootstrap,Uu as VERSION,J as SDKError,_u as QueueFullError,cu as OptedOutError,b as NetworkError,mu as InitError,h as GuruluConsent,V as GuruluActivation,q as Gurulu,Au as ConsentBlockedError};
|
|
9
9
|
|
|
10
|
-
//# debugId=
|
|
10
|
+
//# debugId=AF94586E9911F89164756E2164756E21
|