@gurulu/web 1.1.0 → 1.2.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/dist/activate-runtime.d.ts +15 -0
- package/dist/activate-runtime.d.ts.map +1 -0
- package/dist/activate-runtime.js +248 -0
- package/dist/activation.d.ts +117 -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 +192 -1
- package/dist/react.d.ts.map +1 -1
- package/dist/react.js +191 -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,142 @@
|
|
|
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
|
+
if (body.completed_step !== undefined) {
|
|
111
|
+
this.trackTour(tourKey, "step_completed", body.completed_step);
|
|
112
|
+
}
|
|
113
|
+
if (body.completed) {
|
|
114
|
+
this.trackTour(tourKey, "completed", body.current_step);
|
|
115
|
+
}
|
|
116
|
+
if (body.dismissed) {
|
|
117
|
+
this.trackTour(tourKey, "dismissed", body.current_step);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
snapshot() {
|
|
121
|
+
return this.data ?? EMPTY;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
function assignLocalVariant(key, uid, variants) {
|
|
125
|
+
const valid = variants.filter((v) => v.weight > 0 && v.key.length > 0);
|
|
126
|
+
if (valid.length === 0 || !uid)
|
|
127
|
+
return null;
|
|
128
|
+
const total = valid.reduce((s, v) => s + v.weight, 0);
|
|
129
|
+
if (total <= 0)
|
|
130
|
+
return null;
|
|
131
|
+
const bucket = activationBucket(key, uid);
|
|
132
|
+
let cum = 0;
|
|
133
|
+
for (const v of valid) {
|
|
134
|
+
cum += v.weight / total;
|
|
135
|
+
if (bucket < cum)
|
|
136
|
+
return v.key;
|
|
137
|
+
}
|
|
138
|
+
return valid[valid.length - 1].key;
|
|
139
|
+
}
|
|
1
140
|
// src/consent.ts
|
|
2
141
|
var DEFAULT_API_URL = "https://api.gurulu.io";
|
|
3
142
|
var STORAGE_PREFIX = "gurulu_consent_";
|
|
@@ -351,6 +490,44 @@ function startClickAutocapture(track) {
|
|
|
351
490
|
};
|
|
352
491
|
}
|
|
353
492
|
|
|
493
|
+
// src/autocapture/error.ts
|
|
494
|
+
var MAX_STACK = 2000;
|
|
495
|
+
var MAX_MESSAGE = 1000;
|
|
496
|
+
function startErrorAutocapture(track) {
|
|
497
|
+
if (typeof window === "undefined")
|
|
498
|
+
return { stop: () => {
|
|
499
|
+
return;
|
|
500
|
+
} };
|
|
501
|
+
const onError = (ev) => {
|
|
502
|
+
const err = ev.error;
|
|
503
|
+
track({
|
|
504
|
+
message: String(ev.message ?? err?.message ?? "Error").slice(0, MAX_MESSAGE),
|
|
505
|
+
error_type: err?.name ?? "Error",
|
|
506
|
+
...ev.filename ? { source: ev.filename } : {},
|
|
507
|
+
...typeof ev.lineno === "number" ? { lineno: ev.lineno } : {},
|
|
508
|
+
...typeof ev.colno === "number" ? { colno: ev.colno } : {},
|
|
509
|
+
...err?.stack ? { stack: String(err.stack).slice(0, MAX_STACK) } : {}
|
|
510
|
+
});
|
|
511
|
+
};
|
|
512
|
+
const onRejection = (ev) => {
|
|
513
|
+
const reason = ev.reason;
|
|
514
|
+
const isErr = reason instanceof Error;
|
|
515
|
+
track({
|
|
516
|
+
message: String(isErr ? reason.message : reason).slice(0, MAX_MESSAGE),
|
|
517
|
+
error_type: isErr ? reason.name : "UnhandledRejection",
|
|
518
|
+
...isErr && reason.stack ? { stack: String(reason.stack).slice(0, MAX_STACK) } : {}
|
|
519
|
+
});
|
|
520
|
+
};
|
|
521
|
+
window.addEventListener("error", onError);
|
|
522
|
+
window.addEventListener("unhandledrejection", onRejection);
|
|
523
|
+
return {
|
|
524
|
+
stop() {
|
|
525
|
+
window.removeEventListener("error", onError);
|
|
526
|
+
window.removeEventListener("unhandledrejection", onRejection);
|
|
527
|
+
}
|
|
528
|
+
};
|
|
529
|
+
}
|
|
530
|
+
|
|
354
531
|
// src/autocapture/form.ts
|
|
355
532
|
var SENSITIVE_INPUT_TYPES = new Set(["password", "tel"]);
|
|
356
533
|
function isSensitiveField(el) {
|
|
@@ -701,6 +878,8 @@ function startAutocapture(cfg, sinks) {
|
|
|
701
878
|
handles.push(startScrollAutocapture(sinks.scrollDepth));
|
|
702
879
|
if (merged.web_vitals)
|
|
703
880
|
handles.push(startWebVitalsAutocapture(sinks.webVital));
|
|
881
|
+
if (merged.js_error)
|
|
882
|
+
handles.push(startErrorAutocapture(sinks.jsError));
|
|
704
883
|
return {
|
|
705
884
|
stopAll() {
|
|
706
885
|
for (const h of handles) {
|
|
@@ -1173,6 +1352,7 @@ class Gurulu {
|
|
|
1173
1352
|
autocaptureHandle = null;
|
|
1174
1353
|
testMode = false;
|
|
1175
1354
|
consent;
|
|
1355
|
+
activation;
|
|
1176
1356
|
init(opts) {
|
|
1177
1357
|
if (this.initialized) {
|
|
1178
1358
|
if (opts.debug && typeof console !== "undefined") {
|
|
@@ -1193,6 +1373,12 @@ class Gurulu {
|
|
|
1193
1373
|
autoBanner: opts.consent_mode === "banner_required"
|
|
1194
1374
|
});
|
|
1195
1375
|
this.consent.init();
|
|
1376
|
+
this.activation = new GuruluActivation({
|
|
1377
|
+
endpoint: opts.endpoint ?? DEFAULT_ENDPOINT,
|
|
1378
|
+
workspaceKey: opts.workspaceKey,
|
|
1379
|
+
getUid: () => getPersonId() ?? this.anonymousId ?? "",
|
|
1380
|
+
track: (key, props) => this.track(key, props)
|
|
1381
|
+
});
|
|
1196
1382
|
const transport = {
|
|
1197
1383
|
endpoint: opts.endpoint ?? DEFAULT_ENDPOINT,
|
|
1198
1384
|
workspaceKey: opts.workspaceKey,
|
|
@@ -1234,7 +1420,8 @@ class Gurulu {
|
|
|
1234
1420
|
formStarted: (p) => this.queueEvent("form_started", "interaction", p),
|
|
1235
1421
|
formSubmitted: (p) => this.queueEvent("form_submitted", "interaction", p),
|
|
1236
1422
|
scrollDepth: (p) => this.queueEvent("scroll_depth", "interaction", p),
|
|
1237
|
-
webVital: (p) => this.queueEvent("web_vital", "interaction", p)
|
|
1423
|
+
webVital: (p) => this.queueEvent("web_vital", "interaction", p),
|
|
1424
|
+
jsError: (p) => this.queueEvent("js_error", "interaction", p)
|
|
1238
1425
|
});
|
|
1239
1426
|
this.initialized = true;
|
|
1240
1427
|
}
|
|
@@ -1380,6 +1567,9 @@ var publicSdk = {
|
|
|
1380
1567
|
get consent() {
|
|
1381
1568
|
return singleton.consent;
|
|
1382
1569
|
},
|
|
1570
|
+
get activation() {
|
|
1571
|
+
return singleton.activation;
|
|
1572
|
+
},
|
|
1383
1573
|
VERSION
|
|
1384
1574
|
};
|
|
1385
1575
|
function autoBootstrap() {
|
|
@@ -1424,6 +1614,7 @@ export {
|
|
|
1424
1614
|
NetworkError,
|
|
1425
1615
|
InitError,
|
|
1426
1616
|
GuruluConsent,
|
|
1617
|
+
GuruluActivation,
|
|
1427
1618
|
Gurulu,
|
|
1428
1619
|
ConsentBlockedError
|
|
1429
1620
|
};
|
package/dist/react.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,SAAS,EAAa,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,SAAS,EAAa,MAAM,OAAO,CAAC;AAClD,OAAO,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAG/D,MAAM,MAAM,mBAAmB,GAAG,WAAW,GAAG;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,CAAC;AAExE,+DAA+D;AAC/D,wBAAgB,cAAc,CAAC,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,EAAE,mBAAmB,GAAG,SAAS,CAOpF;AAED,sEAAsE;AACtE,wBAAgB,SAAS,IAAI,eAAe,CAE3C"}
|
package/dist/react.js
CHANGED
|
@@ -1,3 +1,142 @@
|
|
|
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
|
+
if (body.completed_step !== undefined) {
|
|
111
|
+
this.trackTour(tourKey, "step_completed", body.completed_step);
|
|
112
|
+
}
|
|
113
|
+
if (body.completed) {
|
|
114
|
+
this.trackTour(tourKey, "completed", body.current_step);
|
|
115
|
+
}
|
|
116
|
+
if (body.dismissed) {
|
|
117
|
+
this.trackTour(tourKey, "dismissed", body.current_step);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
snapshot() {
|
|
121
|
+
return this.data ?? EMPTY;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
function assignLocalVariant(key, uid, variants) {
|
|
125
|
+
const valid = variants.filter((v) => v.weight > 0 && v.key.length > 0);
|
|
126
|
+
if (valid.length === 0 || !uid)
|
|
127
|
+
return null;
|
|
128
|
+
const total = valid.reduce((s, v) => s + v.weight, 0);
|
|
129
|
+
if (total <= 0)
|
|
130
|
+
return null;
|
|
131
|
+
const bucket = activationBucket(key, uid);
|
|
132
|
+
let cum = 0;
|
|
133
|
+
for (const v of valid) {
|
|
134
|
+
cum += v.weight / total;
|
|
135
|
+
if (bucket < cum)
|
|
136
|
+
return v.key;
|
|
137
|
+
}
|
|
138
|
+
return valid[valid.length - 1].key;
|
|
139
|
+
}
|
|
1
140
|
// src/consent.ts
|
|
2
141
|
var DEFAULT_API_URL = "https://api.gurulu.io";
|
|
3
142
|
var STORAGE_PREFIX = "gurulu_consent_";
|
|
@@ -351,6 +490,44 @@ function startClickAutocapture(track) {
|
|
|
351
490
|
};
|
|
352
491
|
}
|
|
353
492
|
|
|
493
|
+
// src/autocapture/error.ts
|
|
494
|
+
var MAX_STACK = 2000;
|
|
495
|
+
var MAX_MESSAGE = 1000;
|
|
496
|
+
function startErrorAutocapture(track) {
|
|
497
|
+
if (typeof window === "undefined")
|
|
498
|
+
return { stop: () => {
|
|
499
|
+
return;
|
|
500
|
+
} };
|
|
501
|
+
const onError = (ev) => {
|
|
502
|
+
const err = ev.error;
|
|
503
|
+
track({
|
|
504
|
+
message: String(ev.message ?? err?.message ?? "Error").slice(0, MAX_MESSAGE),
|
|
505
|
+
error_type: err?.name ?? "Error",
|
|
506
|
+
...ev.filename ? { source: ev.filename } : {},
|
|
507
|
+
...typeof ev.lineno === "number" ? { lineno: ev.lineno } : {},
|
|
508
|
+
...typeof ev.colno === "number" ? { colno: ev.colno } : {},
|
|
509
|
+
...err?.stack ? { stack: String(err.stack).slice(0, MAX_STACK) } : {}
|
|
510
|
+
});
|
|
511
|
+
};
|
|
512
|
+
const onRejection = (ev) => {
|
|
513
|
+
const reason = ev.reason;
|
|
514
|
+
const isErr = reason instanceof Error;
|
|
515
|
+
track({
|
|
516
|
+
message: String(isErr ? reason.message : reason).slice(0, MAX_MESSAGE),
|
|
517
|
+
error_type: isErr ? reason.name : "UnhandledRejection",
|
|
518
|
+
...isErr && reason.stack ? { stack: String(reason.stack).slice(0, MAX_STACK) } : {}
|
|
519
|
+
});
|
|
520
|
+
};
|
|
521
|
+
window.addEventListener("error", onError);
|
|
522
|
+
window.addEventListener("unhandledrejection", onRejection);
|
|
523
|
+
return {
|
|
524
|
+
stop() {
|
|
525
|
+
window.removeEventListener("error", onError);
|
|
526
|
+
window.removeEventListener("unhandledrejection", onRejection);
|
|
527
|
+
}
|
|
528
|
+
};
|
|
529
|
+
}
|
|
530
|
+
|
|
354
531
|
// src/autocapture/form.ts
|
|
355
532
|
var SENSITIVE_INPUT_TYPES = new Set(["password", "tel"]);
|
|
356
533
|
function isSensitiveField(el) {
|
|
@@ -701,6 +878,8 @@ function startAutocapture(cfg, sinks) {
|
|
|
701
878
|
handles.push(startScrollAutocapture(sinks.scrollDepth));
|
|
702
879
|
if (merged.web_vitals)
|
|
703
880
|
handles.push(startWebVitalsAutocapture(sinks.webVital));
|
|
881
|
+
if (merged.js_error)
|
|
882
|
+
handles.push(startErrorAutocapture(sinks.jsError));
|
|
704
883
|
return {
|
|
705
884
|
stopAll() {
|
|
706
885
|
for (const h of handles) {
|
|
@@ -1173,6 +1352,7 @@ class Gurulu {
|
|
|
1173
1352
|
autocaptureHandle = null;
|
|
1174
1353
|
testMode = false;
|
|
1175
1354
|
consent;
|
|
1355
|
+
activation;
|
|
1176
1356
|
init(opts) {
|
|
1177
1357
|
if (this.initialized) {
|
|
1178
1358
|
if (opts.debug && typeof console !== "undefined") {
|
|
@@ -1193,6 +1373,12 @@ class Gurulu {
|
|
|
1193
1373
|
autoBanner: opts.consent_mode === "banner_required"
|
|
1194
1374
|
});
|
|
1195
1375
|
this.consent.init();
|
|
1376
|
+
this.activation = new GuruluActivation({
|
|
1377
|
+
endpoint: opts.endpoint ?? DEFAULT_ENDPOINT,
|
|
1378
|
+
workspaceKey: opts.workspaceKey,
|
|
1379
|
+
getUid: () => getPersonId() ?? this.anonymousId ?? "",
|
|
1380
|
+
track: (key, props) => this.track(key, props)
|
|
1381
|
+
});
|
|
1196
1382
|
const transport = {
|
|
1197
1383
|
endpoint: opts.endpoint ?? DEFAULT_ENDPOINT,
|
|
1198
1384
|
workspaceKey: opts.workspaceKey,
|
|
@@ -1234,7 +1420,8 @@ class Gurulu {
|
|
|
1234
1420
|
formStarted: (p) => this.queueEvent("form_started", "interaction", p),
|
|
1235
1421
|
formSubmitted: (p) => this.queueEvent("form_submitted", "interaction", p),
|
|
1236
1422
|
scrollDepth: (p) => this.queueEvent("scroll_depth", "interaction", p),
|
|
1237
|
-
webVital: (p) => this.queueEvent("web_vital", "interaction", p)
|
|
1423
|
+
webVital: (p) => this.queueEvent("web_vital", "interaction", p),
|
|
1424
|
+
jsError: (p) => this.queueEvent("js_error", "interaction", p)
|
|
1238
1425
|
});
|
|
1239
1426
|
this.initialized = true;
|
|
1240
1427
|
}
|
|
@@ -1380,6 +1567,9 @@ var publicSdk = {
|
|
|
1380
1567
|
get consent() {
|
|
1381
1568
|
return singleton.consent;
|
|
1382
1569
|
},
|
|
1570
|
+
get activation() {
|
|
1571
|
+
return singleton.activation;
|
|
1572
|
+
},
|
|
1383
1573
|
VERSION
|
|
1384
1574
|
};
|
|
1385
1575
|
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 qu(u){let n=2166136261;for(let r=0;r<u.length;r++)n^=u.charCodeAt(r),n=Math.imul(n,16777619);return n>>>0}function zu(u,n){return qu(`${u}:${n}`)%1e4/1e4}var N={workspace_id:"",popups:[],tours:[],personalizations:[],experiments:[]};class h{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 n=this.cfg.fetchImpl??(typeof fetch<"u"?fetch.bind(globalThis):null);if(!n)return N;let r=this.cfg.getUid(),m=new URLSearchParams;if(r)m.set("uid",r);let _=typeof window<"u"&&window.location?window.location.href:"",A=u?.url??_;if(A)m.set("url",A);let c=typeof navigator<"u"&&navigator.userAgent?navigator.userAgent:"",E=u?.device??(/Mobi|Android/i.test(c)?"mobile":"desktop");return m.set("device",E),this.pending=(async()=>{try{let o=await n(`${this.cfg.endpoint}/v1/activate?${m.toString()}`,{method:"GET",headers:{Authorization:`Bearer ${this.cfg.workspaceKey}`},credentials:"omit"});if(!o.ok)return this.data??N;return this.data=await o.json(),this.data}catch{return this.data??N}finally{this.pending=null}})(),this.pending}getPopups(){return this.data?.popups??[]}getTours(){return this.data?.tours??[]}getContent(u){let n=(this.data?.personalizations??[]).find((r)=>r.slot_key===u);if(!n)return null;if(!this.served.has(n.key))this.served.add(n.key),this.cfg.track("personalization_served",{personalization_key:n.key,variant_key:n.variant_key,is_holdout:n.is_holdout});return n.content}getVariant(u){let n=(this.data?.experiments??[]).find((m)=>m.key===u);if(!n)return null;let r=n.assigned_variant??Tu(u,this.cfg.getUid(),n.variants);if(r&&!this.exposed.has(u))this.exposed.add(u),this.cfg.track("experiment_exposed",{experiment_key:u,variant_key:r});return r}trackPopup(u,n){this.cfg.track(`popup_${n}`,{popup_key:u})}trackTour(u,n,r){this.cfg.track(`tour_${n}`,{tour_key:u,...r!==void 0?{step_index:r}:{}})}async saveTourProgress(u,n){if(n.completed_step!==void 0)this.trackTour(u,"step_completed",n.completed_step);if(n.completed)this.trackTour(u,"completed",n.current_step);if(n.dismissed)this.trackTour(u,"dismissed",n.current_step)}snapshot(){return this.data??N}}function Tu(u,n,r){let m=r.filter((E)=>E.weight>0&&E.key.length>0);if(m.length===0||!n)return null;let _=m.reduce((E,o)=>E+o.weight,0);if(_<=0)return null;let A=zu(u,n),c=0;for(let E of m)if(c+=E.weight/_,A<c)return E.key;return m[m.length-1].key}class R{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):Qu),this.storage=u.storage??(typeof globalThis<"u"&&"localStorage"in globalThis?globalThis.localStorage:null),this.autoBanner=u.autoBanner??!0,this.locale=u.locale??hu(),this.anonymousIdValue=u.anonymousId??this.loadOrCreateAnonId()}async init(){if(typeof window>"u")return;try{let n=await this.fetchImpl(`${this.apiUrl}/v1/consent/banner-config?workspace_id=${encodeURIComponent(this.workspaceId)}`,{method:"GET",credentials:"omit"});if(!n.ok)return;this.bannerConfigCache=await n.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 n=JSON.parse(u);if(n.expiresAt&&new Date(n.expiresAt).getTime()<Date.now())return this.storage.removeItem(this.storageKey()),null;return n}catch{return null}}async setState(u){let n=this.getState()?.categories,r={necessary:!0,analytics:u.analytics??n?.analytics??!1,marketing:u.marketing??n?.marketing??!1,functional:u.functional??n?.functional??!1,personalization:u.personalization??n?.personalization??!1},m=new Date,_=this.bannerConfigCache?.renewal_months??13,A=new Date(m);A.setMonth(A.getMonth()+_);let c={workspaceId:this.workspaceId,anonymousId:this.anonymousIdValue,categories:r,grantedAt:m.toISOString(),expiresAt:A.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:r.necessary,analytics:r.analytics,marketing:r.marketing,functional:r.functional,personalization:r.personalization,source:"sdk_api"})})}catch{}}showBanner(){if(typeof document>"u")return;if(this.bannerEl)return;let u=this.bannerConfigCache?.banner_config??{},n=this.bannerText(),r=u.brand?.primary_color??"#fafafa",m=u.position??"bottom",_=document.createElement("div");_.setAttribute("data-gurulu-consent-banner",""),_.setAttribute("role","dialog"),_.setAttribute("aria-label",n.heading),_.style.cssText=Vu(m),_.innerHTML=$u(n,r);let A=_.querySelector("[data-gurulu-accept]"),c=_.querySelector("[data-gurulu-reject]");A?.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(_),this.bannerEl=_}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 W();try{let u=this.storage.getItem("gurulu_anon_id");if(u)return u;let n=W();return this.storage.setItem("gurulu_anon_id",n),n}catch{return W()}}bannerText(){let n=this.bannerConfigCache?.banner_config?.text_overrides?.[this.locale];if(this.locale==="tr")return{heading:n?.heading??"Çerezleri tercih et",body:n?.body??"Deneyimini iyileştirmek için analytics + pazarlama çerezleri kullanıyoruz.",accept:n?.accept??"Tümünü kabul et",reject:n?.reject??"Sadece gerekli olanlar"};return{heading:n?.heading??"Manage cookies",body:n?.body??"We use analytics and marketing cookies to improve your experience.",accept:n?.accept??"Accept all",reject:n?.reject??"Necessary only"}}}function Vu(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 $u(u,n){return`
|
|
2
|
+
<div style="margin-bottom:12px;font-weight:600;">${Q(u.heading)}</div>
|
|
3
|
+
<div style="margin-bottom:16px;color:#a3a3a3;">${Q(u.body)}</div>
|
|
4
4
|
<div style="display:flex;gap:8px;flex-wrap:wrap;">
|
|
5
|
-
<button data-gurulu-accept type="button" style="background:${Nu(
|
|
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:${Nu(n)};color:#0a0a0a;border:none;padding:8px 16px;border-radius:6px;font-weight:600;cursor:pointer;">${Q(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;">${Q(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 Q(u){return u.replace(/[&<>"']/g,(n)=>{switch(n){case"&":return"&";case"<":return"<";case">":return">";case'"':return""";case"'":return"'";default:return n}})}function Nu(u){return u.replace(/[^a-zA-Z0-9#()_\-., ]/g,"")}function hu(){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 W(){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 Qu(){throw Error("fetch not available — provide opts.fetchImpl")}var Ru=new Set(["A","BUTTON"]),Zu=/\.(pdf|zip|dmg|exe|tar|gz|rar|7z|mp3|mp4|csv|xlsx?|docx?|pptx?)(\?|$)/i;function Gu(u){let n=u;while(n){if(n.hasAttribute?.("data-gurulu-no-track"))return!1;n=n.parentElement}return!0}function Fu(u){let n=u;while(n){if(!n.tagName){n=n.parentElement;continue}if(Ru.has(n.tagName))return n;if(n.getAttribute?.("role")==="button")return n;if(n.tagName==="INPUT"){let r=n.type?.toLowerCase();if(r==="submit"||r==="button")return n}n=n.parentElement}return null}function Wu(u){let n={};if(!u.attributes)return n;for(let r=0;r<u.attributes.length;r+=1){let m=u.attributes.item(r);if(!m)continue;if(m.name.startsWith("data-gurulu-prop-")){let _=m.name.slice(17);n[_]=m.value}}return n}function i(u){if(typeof document>"u")return{stop:()=>{return}};let n=(r)=>{let m=Fu(r.target);if(!m||!Gu(m))return;let _={element_tag:m.tagName.toLowerCase()};if(m.id)_.element_id=m.id;if(m.className&&typeof m.className==="string")_.element_class=m.className.slice(0,256);let A=(m.textContent??"").trim().slice(0,200);if(A)_.element_text=A;if(m.tagName==="A"){let E=m.href;if(E){_.href=E;try{let o=new URL(E).hostname;if(typeof window<"u"&&o!==window.location.hostname)_.is_outbound=!0}catch{}if(Zu.test(E))_.is_download=!0}}let c=m.getAttribute?.("data-gurulu-event");if(c)_.custom_event=c,_.custom_props=Wu(m);u(_)};return document.addEventListener("click",n,!0),{stop(){document.removeEventListener("click",n,!0)}}}function K(u){if(typeof window>"u")return{stop:()=>{return}};let n=(m)=>{let _=m.error;u({message:String(m.message??_?.message??"Error").slice(0,1000),error_type:_?.name??"Error",...m.filename?{source:m.filename}:{},...typeof m.lineno==="number"?{lineno:m.lineno}:{},...typeof m.colno==="number"?{colno:m.colno}:{},..._?.stack?{stack:String(_.stack).slice(0,2000)}:{}})},r=(m)=>{let _=m.reason,A=_ instanceof Error;u({message:String(A?_.message:_).slice(0,1000),error_type:A?_.name:"UnhandledRejection",...A&&_.stack?{stack:String(_.stack).slice(0,2000)}:{}})};return window.addEventListener("error",n),window.addEventListener("unhandledrejection",r),{stop(){window.removeEventListener("error",n),window.removeEventListener("unhandledrejection",r)}}}var fu=new Set(["password","tel"]);function x(u){if(u.tagName!=="INPUT")return!1;let n=u,r=(n.type??"").toLowerCase();if(fu.has(r))return!0;if((n.autocomplete??"").toLowerCase().startsWith("cc-"))return!0;return!1}function k(u){let n=u;while(n){if(n.hasAttribute?.("data-gurulu-no-track"))return!1;n=n.parentElement}return!0}function Bu(u){let n=u;while(n){if(n.tagName==="FORM")return n;n=n.parentElement}return null}function d(u){let n={count:u.elements?.length??0};if(u.id)n.id=u.id;if(u.name)n.name=u.name;return n}function I(u){if(typeof document>"u")return{stop:()=>{return}};let n=new WeakSet,r=(_)=>{let A=_.target;if(!A)return;if(x(A))return;if(!k(A))return;let c=Bu(A);if(!c||n.has(c))return;n.add(c);let E=d(c),o={field_count:E.count};if(E.id)o.form_id=E.id;if(E.name)o.form_name=E.name;u.onStart(o)},m=(_)=>{let A=_.target;if(!A||A.tagName!=="FORM")return;if(!k(A))return;let c=d(A),E=[],o=A.elements;for(let X=0;X<o.length;X+=1){let C=o[X];if(!C)continue;if(x(C))continue;if(!("value"in C))continue;if(typeof C.value==="string"&&C.value.length>0&&C.name)E.push(C.name)}let l={field_count:c.count};if(c.id)l.form_id=c.id;if(c.name)l.form_name=c.name;if(E.length>0)l.filled_fields=E;u.onSubmit(l)};return document.addEventListener("focus",r,!0),document.addEventListener("submit",m,!0),{stop(){document.removeEventListener("focus",r,!0),document.removeEventListener("submit",m,!0)}}}function y(u){if(typeof window>"u"||typeof document>"u")return{stop:()=>{return}};let n=window.location.pathname+window.location.search;function r(){let c=window.location.pathname+window.location.search;if(c===n)return;n=c,u(window.location.href,document.title,document.referrer)}u(window.location.href,document.title,document.referrer);let m=()=>r();window.addEventListener("popstate",m);let _=history.pushState.bind(history),A=history.replaceState.bind(history);return history.pushState=function(...E){let o=_(...E);return queueMicrotask(r),o},history.replaceState=function(...E){let o=A(...E);return queueMicrotask(r),o},{stop(){window.removeEventListener("popstate",m),history.pushState=_,history.replaceState=A}}}var wu=[25,50,75,90];function v(u){if(typeof window>"u"||typeof document>"u")return{stop:()=>{return}};let n=new Set,r=0,m=()=>{r=0;let{documentElement:A,body:c}=document;if(!A||!c)return;let E=window.scrollY??A.scrollTop??0,o=window.innerHeight??A.clientHeight??0,l=Math.max(c.scrollHeight??0,A.scrollHeight??0);if(l<=o)return;let X=(E+o)/l*100;for(let C of wu)if(X>=C&&!n.has(C))n.add(C),u({depth_percent:C})},_=()=>{if(r!==0)return;r=requestAnimationFrame(m)};return window.addEventListener("scroll",_,{passive:!0}),{stop(){if(window.removeEventListener("scroll",_),r!==0)cancelAnimationFrame(r)}}}var Lu={LCP:[2500,4000],FID:[100,300],INP:[200,500],CLS:[0.1,0.25],TTFB:[800,1800],FCP:[1800,3000]};function q(u,n){let[r,m]=Lu[u];if(n<=r)return"good";if(n<=m)return"needs-improvement";return"poor"}function Z(u,n,r){if(typeof PerformanceObserver>"u")return null;try{let m=new PerformanceObserver((_)=>r(_.getEntries()));return m.observe({type:u,buffered:n}),m}catch{return null}}function a(u){if(typeof window>"u")return{stop:()=>{return}};let n=[];try{let j=performance.getEntriesByType("navigation")[0];if(j&&j.responseStart>0)u({metric:"TTFB",value:j.responseStart,rating:q("TTFB",j.responseStart)});let S=performance.getEntriesByName("first-contentful-paint")[0];if(S)u({metric:"FCP",value:S.startTime,rating:q("FCP",S.startTime)})}catch{}let r=0,m=Z("largest-contentful-paint",!0,(j)=>{let S=j[j.length-1];if(S)r=S.startTime});if(m)n.push(m);let _=Z("first-input",!0,(j)=>{let S=j[0];if(S){let H=S.processingStart-S.startTime;u({metric:"FID",value:H,rating:q("FID",H)})}});if(_)n.push(_);let A=0,c=Z("event",!0,(j)=>{for(let S of j){let H=S.duration;if(H>A)A=H}});if(c)n.push(c);let E=0,o=Z("layout-shift",!0,(j)=>{for(let S of j){let H=S;if(!H.hadRecentInput)E+=H.value}});if(o)n.push(o);let l=()=>{if(r>0)u({metric:"LCP",value:r,rating:q("LCP",r)});if(A>0)u({metric:"INP",value:A,rating:q("INP",A)});if(E>0)u({metric:"CLS",value:E,rating:q("CLS",E)});r=0,A=0,E=0},X=null,C=null;if(typeof document<"u")X=()=>{if(document.visibilityState==="hidden")l()},C=l,document.addEventListener("visibilitychange",X),window.addEventListener("pagehide",C);return{stop(){for(let j of n)try{j.disconnect()}catch{}if(typeof document<"u"&&X)document.removeEventListener("visibilitychange",X);if(typeof window<"u"&&C)window.removeEventListener("pagehide",C)}}}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 p(u,n){if(u===!1)return{stopAll:()=>{return}};let r={...gu,...u??{}},m=[];if(r.page_view)m.push(y(n.pageView));if(r.click)m.push(i(n.click));if(r.form_started||r.form_submitted)m.push(I({onStart:r.form_started?n.formStarted:()=>{return},onSubmit:r.form_submitted?n.formSubmitted:()=>{return}}));if(r.scroll_depth)m.push(v(n.scrollDepth));if(r.web_vitals)m.push(a(n.webVital));if(r.js_error)m.push(K(n.jsError));return{stopAll(){for(let _ of m)try{_.stop()}catch{}}}}function z(){return typeof window<"u"&&typeof document<"u"}function B(){if(typeof crypto<"u"&&typeof crypto.randomUUID==="function")return crypto.randomUUID();return`${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`}function e(u){if(!z())return null;try{return window.localStorage.getItem(u)}catch{return null}}function G(u,n){if(!z())return;try{window.localStorage.setItem(u,n)}catch{}}function s(u){if(!z())return;try{window.localStorage.removeItem(u)}catch{}}function Yu(u){if(!z())return null;let n=document.cookie??"";for(let r of n.split(";")){let[m,_]=r.trim().split("=");if(m===u&&_!==void 0)return decodeURIComponent(_)}return null}function f(u,n,r=365){if(!z())return;let m=new Date(Date.now()+r*86400000).toUTCString(),_=window.location.hostname,A=_.split("."),c=A.length>=2?`.${A.slice(-2).join(".")}`:_;try{document.cookie=`${u}=${encodeURIComponent(n)}; path=/; domain=${c}; expires=${m}; SameSite=Lax`}catch{}}function uu(){let u=e("gurulu_aid")??Yu("gurulu_aid_mirror");if(u)return G("gurulu_aid",u),f("gurulu_aid_mirror",u),u;let n=B();return G("gurulu_aid",n),f("gurulu_aid_mirror",n),n}function nu(u){G("gurulu_pid",u)}function w(){return e("gurulu_pid")}function mu(){s("gurulu_pid"),s("gurulu_aid");let u=B();return G("gurulu_aid",u),f("gurulu_aid_mirror",u),u}function ru(){return B()}class M extends Error{code;constructor(u,n){super(n);this.code=u,this.name="SDKError"}}class _u extends M{constructor(u){super("SDK_INIT",u);this.name="InitError"}}class D extends M{status;constructor(u,n){super("SDK_NETWORK",u);if(this.name="NetworkError",n!==void 0)this.status=n}}class Au extends M{constructor(u){super("SDK_QUEUE_FULL",u);this.name="QueueFullError"}}class cu extends M{constructor(){super("SDK_OPTED_OUT","tracking disabled — gurulu.optOut() in effect");this.name="OptedOutError"}}class Eu extends M{constructor(){super("SDK_CONSENT_BLOCKED","event queued — awaiting consent grant");this.name="ConsentBlockedError"}}var bu=65536;function ou(u,n){let r=new Headers({"content-type":"application/json",authorization:`Bearer ${u.workspaceKey}`,"x-gurulu-sdk":`@gurulu/web@${u.sdkVersion}`});if(n)for(let[m,_]of Object.entries(n))r.set(m,_);return r}async function Cu(u,n,r){let m=u.fetchImpl??(typeof fetch<"u"?fetch.bind(globalThis):null);if(!m)throw new D("fetch unavailable");let _=`${u.endpoint}/v1/ingest/batch`,A=await m(_,{method:"POST",keepalive:!0,credentials:"omit",headers:ou(u,r),body:JSON.stringify(n)});if(!A.ok)throw new D(`ingest ${A.status}`,A.status)}function ju(u,n){if(typeof navigator>"u"||typeof navigator.sendBeacon!=="function")return!1;let r=`${u.endpoint}/v1/ingest/batch?wk=${encodeURIComponent(u.workspaceKey)}&sdk=${encodeURIComponent(u.sdkVersion)}`;try{let m=JSON.stringify(n);if(m.length>=bu)return!1;let _=new Blob([m],{type:"application/json"});return navigator.sendBeacon(r,_)}catch{return!1}}async function Su(u,n){let r=u.fetchImpl??(typeof fetch<"u"?fetch.bind(globalThis):null);if(!r)throw new D("fetch unavailable");let m=await r(`${u.endpoint}/v1/ingest/identify`,{method:"POST",keepalive:!0,credentials:"omit",headers:ou(u),body:JSON.stringify(n)});if(!m.ok)throw new D(`identify ${m.status}`,m.status)}var g="gurulu_queue";function Y(){return typeof window<"u"}function Uu(){if(!Y())return[];try{let u=window.localStorage.getItem(g);if(!u)return[];let n=JSON.parse(u);return Array.isArray(n)?n:[]}catch{return[]}}function L(u){if(!Y())return;try{if(u.length===0)window.localStorage.removeItem(g);else window.localStorage.setItem(g,JSON.stringify(u))}catch{}}class b{opts;buffer;timer=null;flushing=!1;constructor(u){if(this.opts=u,this.buffer=Uu(),this.scheduleNext(),this.installUnloadHooks(),this.buffer.length>0)this.scheduleImmediate()}enqueue(u){if(this.buffer.push(u),L(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),L(this.buffer)}catch(n){if(this.opts.debug&&typeof console<"u")console.warn("[gurulu] flush failed, retain queue",n)}finally{this.flushing=!1}}flushBeacon(){if(this.buffer.length===0)return;if(ju(this.opts.transport,{events:this.buffer}))this.buffer=[],L(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 n=0,r=3;while(n<r)try{await Cu(this.opts.transport,{events:u});return}catch(m){if(n+=1,n>=r)throw m;let _=2**n*1000;await new Promise((A)=>setTimeout(A,_))}}installUnloadHooks(){if(!Y()||typeof document>"u")return;let u=()=>{if(document.visibilityState==="hidden")this.flushBeacon()};try{document.addEventListener("visibilitychange",u),window.addEventListener("pagehide",()=>this.flushBeacon())}catch{}}}function lu(){return typeof window<"u"}function Pu(){if(typeof crypto<"u"&&typeof crypto.randomUUID==="function")return crypto.randomUUID();return`${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`}function V(u){if(!lu())return null;try{return window.localStorage.getItem(u)}catch{return null}}function T(u,n){if(!lu())return;try{window.localStorage.setItem(u,n)}catch{}}function F(u=Date.now()){let n=V("gurulu_sid"),r=Number(V("gurulu_session_started_at")??"0"),m=Number(V("gurulu_last_event_at")??"0");if(n&&r&&u-m<1800000)return T("gurulu_last_event_at",String(u)),{session_id:n,session_started_at:r,is_new:!1};let _=Pu();return T("gurulu_sid",_),T("gurulu_session_started_at",String(u)),T("gurulu_last_event_at",String(u)),{session_id:_,session_started_at:u,is_new:!0}}function Xu(u,n){let r={},m={};if(!u)return{utm:r,click_id:m};let _;try{_=new URL(u)}catch{return{utm:r,click_id:m}}let A=_.searchParams,c=A.get("utm_source");if(c)r.source=c;let E=A.get("utm_medium");if(E)r.medium=E;let o=A.get("utm_campaign");if(o)r.campaign=o;let l=A.get("utm_term");if(l)r.term=l;let X=A.get("utm_content");if(X)r.content=X;let C=A.get("gclid");if(C)m.gclid=C;let j=A.get("fbclid");if(j)m.fbclid=j;let S=A.get("ttclid");if(S)m.ttclid=S;let H=A.get("li_fat_id");if(H)m.li_fat_id=H;return{utm:r,click_id:m}}function Hu(u){if(V("gurulu_first_source"))return;T("gurulu_first_source",JSON.stringify(u))}function Ju(){let u=V("gurulu_first_source");if(!u)return null;try{return JSON.parse(u)}catch{return null}}var U="0.1.0",P="https://ingest.gurulu.io",tu="https://api.gurulu.io",t="gurulu_opt_out";function Mu(){if(typeof window>"u")return!1;try{return window.localStorage.getItem(t)==="1"}catch{return!1}}function Du(u){if(typeof window>"u")return;try{if(u)window.localStorage.setItem(t,"1");else window.localStorage.removeItem(t)}catch{}}function Ou(){return new Date().toISOString()}class ${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=F(),this.consent=new R({workspaceId:u.workspaceKey,apiUrl:u.apiUrl??tu,anonymousId:this.anonymousId,autoBanner:u.consent_mode==="banner_required"}),this.consent.init(),this.activation=new h({endpoint:u.endpoint??P,workspaceKey:u.workspaceKey,getUid:()=>w()??this.anonymousId??"",track:(m,_)=>this.track(m,_)});let n={endpoint:u.endpoint??P,workspaceKey:u.workspaceKey,sdkVersion:U};this.queue=new b({transport:n,flushIntervalMs:u.flush_interval_ms??5000,maxQueueSize:u.max_queue_size??50,...u.debug?{debug:!0}:{}});let r=Xu(window.location.href,document.referrer);if(Object.keys(r.utm).length>0||Object.keys(r.click_id).length>0){let m={utm:r.utm,click_id:r.click_id,referrer:document.referrer,landing_url:window.location.href,captured_at:Date.now()};Hu(m)}this.autocaptureHandle=p(u.autocapture,{pageView:(m,_,A)=>this.queueEvent("page_view","interaction",{url:m,title:_,referrer:A}),click:(m)=>{let _=m.custom_event??"element_clicked",A={element_tag:m.element_tag,...m.element_id?{element_id:m.element_id}:{},...m.element_class?{element_class:m.element_class}:{},...m.element_text?{element_text:m.element_text}:{},...m.href?{href:m.href}:{},...m.is_outbound?{is_outbound:!0}:{},...m.is_download?{is_download:!0}:{},...m.custom_props??{}};this.queueEvent(_,"interaction",A)},formStarted:(m)=>this.queueEvent("form_started","interaction",m),formSubmitted:(m)=>this.queueEvent("form_submitted","interaction",m),scrollDepth:(m)=>this.queueEvent("scroll_depth","interaction",m),webVital:(m)=>this.queueEvent("web_vital","interaction",m),jsError:(m)=>this.queueEvent("js_error","interaction",m)}),this.initialized=!0}track(u,n){this.queueEvent(u,"interaction",n)}page(u){if(!this.initialized||typeof window>"u")return;let n=u?.url??window.location.href,r=u?.title??document.title,m=u?.referrer??document.referrer;this.queueEvent("page_view","interaction",{url:n,title:r,referrer:m})}async identify(u,n){if(!this.initialized||Mu())return;if(nu(u),!this.opts)return;try{await Su({endpoint:this.opts.endpoint??P,workspaceKey:this.opts.workspaceKey,sdkVersion:U},{anonymous_id:this.anonymousId,external_user_id:u,...n?.email?{email:n.email}:{},...n?.phone?{phone:n.phone}:{},...n?{traits:n}:{}})}catch(r){if(this.opts?.debug&&typeof console<"u")console.warn("[gurulu] identify failed",r)}}reset(){if(this.anonymousId=mu(),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=F()}async flush(){await this.queue?.flush()}optOut(){Du(!0)}optIn(){Du(!1)}queueEvent(u,n,r){if(!this.initialized||!this.queue||Mu())return;if(!this.consentAllowsAnalytics()&&this.opts?.consent_mode==="banner_required")return;this.session=F();let m={anonymous_id:this.anonymousId??"anon_unknown",event_id:ru(),event_key:u,event_type:n,occurred_at:Ou(),producer:"script",producer_version:U,...this.session?{session_id:this.session.session_id}:{}},_=w();if(_)m.person_id=_;if(r&&Object.keys(r).length>0)m.properties=r;let A=this.buildContext();if(A)m.context=A;let c=this.snapshotConsent();if(c)m.consent_state=c;if(this.testMode)m.test_mode=!0;this.queue.enqueue(m)}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},n=Ju();if(n?.utm&&Object.keys(n.utm).length>0)u.utm=n.utm;if(n?.click_id&&Object.keys(n.click_id).length>0)u.click_id=n.click_id;return u}}var iu="0.1.0",J=new $;function Vn(){return new $}var O={init:(u)=>J.init(u),track:(u,n)=>J.track(u,n),identify:(u,n)=>J.identify(u,n),page:(u)=>J.page(u),reset:()=>J.reset(),flush:()=>J.flush(),optOut:()=>J.optOut(),optIn:()=>J.optIn(),get consent(){return J.consent},get activation(){return J.activation},VERSION:iu};function Ku(){if(typeof document>"u")return;let u=document.currentScript,n=!u?document.querySelector("script[data-workspace]"):u;if(!n)return;let r=n.getAttribute("data-workspace");if(!r)return;let m={workspaceKey:r},_=n.getAttribute("data-endpoint");if(_)m.endpoint=_;let A=n.getAttribute("data-api-url");if(A)m.apiUrl=A;let c=n.getAttribute("data-consent");if(c==="banner_required"||c==="allow_by_default")m.consent_mode=c;let E=n.getAttribute("data-allowlist");if(E)m.cross_domain_allowlist=E.split(",").map((o)=>o.trim());if(O.init(m),typeof window<"u")window.gurulu=O}Ku();var Zn=O;export{Zn as default,Vn as createGurulu,Ku as autoBootstrap,iu as VERSION,M as SDKError,Au as QueueFullError,cu as OptedOutError,D as NetworkError,_u as InitError,R as GuruluConsent,h as GuruluActivation,$ as Gurulu,Eu as ConsentBlockedError};
|
|
9
9
|
|
|
10
|
-
//# debugId=
|
|
10
|
+
//# debugId=DD5377FE7E5C10A864756E2164756E21
|