@hanzo/event 0.3.43 → 0.3.44

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/index.cjs CHANGED
@@ -19,20 +19,20 @@ var SOCIAL_HOSTS = [
19
19
  var SEARCH_HOSTS = ["google.", "bing.", "duckduckgo.", "yahoo.", "baidu.", "ecosia."];
20
20
  function parseAttribution(search, referrer) {
21
21
  const q = new URLSearchParams(search || "");
22
- const get = (k) => {
22
+ const get2 = (k) => {
23
23
  const v = q.get(k);
24
24
  return v ? v.trim() : void 0;
25
25
  };
26
26
  const a = {
27
27
  utm: {
28
- source: get("utm_source"),
29
- medium: get("utm_medium"),
30
- campaign: get("utm_campaign"),
31
- term: get("utm_term"),
32
- content: get("utm_content")
28
+ source: get2("utm_source"),
29
+ medium: get2("utm_medium"),
30
+ campaign: get2("utm_campaign"),
31
+ term: get2("utm_term"),
32
+ content: get2("utm_content")
33
33
  },
34
34
  referrer: referrer ? referrer.trim() : void 0,
35
- refCode: get("ref") || get("refCode") || get("ref_code") || void 0
35
+ refCode: get2("ref") || get2("refCode") || get2("ref_code") || void 0
36
36
  };
37
37
  a.channel = deriveChannel(a);
38
38
  return a;
@@ -289,13 +289,13 @@ var HZ_ANON_ADOPT = ["hz_anon_id", "hz_id"];
289
289
  var HZ_ANON_DOMAIN = "hanzo.ai";
290
290
  var HZ_ANON_MAX_AGE = 2 * 365 * 24 * 60 * 60;
291
291
  var hzAnonMemo;
292
- function hzUuidv7(now) {
292
+ function hzUuidv7(now2) {
293
293
  var b = new Uint8Array(16);
294
294
  var i;
295
295
  var c = typeof crypto !== "undefined" ? crypto : void 0;
296
296
  if (c && typeof c.getRandomValues === "function") c.getRandomValues(b);
297
297
  else for (i = 0; i < 16; i++) b[i] = Math.random() * 256 | 0;
298
- var t = Math.floor(now === void 0 ? Date.now() : now);
298
+ var t = Math.floor(now2 === void 0 ? Date.now() : now2);
299
299
  for (i = 5; i >= 0; i--) {
300
300
  b[i] = t % 256;
301
301
  t = Math.floor(t / 256);
@@ -407,7 +407,7 @@ function uuidv7Time(id) {
407
407
  }
408
408
 
409
409
  // package.json
410
- var version = "0.3.43";
410
+ var version = "0.3.44";
411
411
 
412
412
  // src/version.ts
413
413
  var VERSION = version;
@@ -540,22 +540,22 @@ function coerceTag(v) {
540
540
  return s.length > MAX_TAG_LEN ? s.slice(0, MAX_TAG_LEN) : s;
541
541
  }
542
542
  function buildSentryEvent(input) {
543
- const { error, options = {}, identity, capturePII = false } = input;
543
+ const { error, options: options2 = {}, identity, capturePII = false } = input;
544
544
  const norm = normalizeError(error);
545
- const handled = options.handled !== false;
546
- const level = options.level ?? (handled ? "error" : "fatal");
547
- const tags = { handled: String(handled) };
548
- if (identity.product) tags.product = identity.product;
549
- if (identity.sessionId) tags.session = identity.sessionId;
545
+ const handled = options2.handled !== false;
546
+ const level = options2.level ?? (handled ? "error" : "fatal");
547
+ const tags2 = { handled: String(handled) };
548
+ if (identity.product) tags2.product = identity.product;
549
+ if (identity.sessionId) tags2.session = identity.sessionId;
550
550
  try {
551
- const props = options.properties ?? {};
551
+ const props = options2.properties ?? {};
552
552
  let n = 0;
553
553
  for (const k of Object.keys(props)) {
554
554
  if (n >= MAX_TAGS) break;
555
555
  try {
556
556
  const val = props[k];
557
557
  if (val === void 0 || val === null) continue;
558
- tags[k] = scrubText(coerceTag(val), capturePII);
558
+ tags2[k] = scrubText(coerceTag(val), capturePII);
559
559
  n++;
560
560
  } catch {
561
561
  continue;
@@ -580,7 +580,7 @@ function buildSentryEvent(input) {
580
580
  }
581
581
  ]
582
582
  },
583
- tags,
583
+ tags: tags2,
584
584
  sdk: { name: "@hanzo/event", version: VERSION }
585
585
  };
586
586
  if (identity.userId) event.user = { id: identity.userId };
@@ -710,7 +710,7 @@ function ls() {
710
710
  function anonId() {
711
711
  return hzAnonId() || void 0;
712
712
  }
713
- function sessionId(now = Date.now()) {
713
+ function sessionId(now2 = Date.now()) {
714
714
  const s = ls();
715
715
  if (!s) return void 0;
716
716
  let state = null;
@@ -719,17 +719,17 @@ function sessionId(now = Date.now()) {
719
719
  } catch {
720
720
  state = null;
721
721
  }
722
- if (!state || now - state.last > SESSION_TTL_MS) {
723
- state = { id: hzUuidv7(now), last: now };
722
+ if (!state || now2 - state.last > SESSION_TTL_MS) {
723
+ state = { id: hzUuidv7(now2), last: now2 };
724
724
  } else {
725
- state.last = now;
725
+ state.last = now2;
726
726
  }
727
727
  s.setItem(KEY.session, JSON.stringify(state));
728
728
  return state.id;
729
729
  }
730
- function adoptSession(id, now = Date.now()) {
730
+ function adoptSession(id, now2 = Date.now()) {
731
731
  const s = ls();
732
- if (s) s.setItem(KEY.session, JSON.stringify({ id, last: now }));
732
+ if (s) s.setItem(KEY.session, JSON.stringify({ id, last: now2 }));
733
733
  }
734
734
  function adoptAnonId(id) {
735
735
  hzAnonAdopt(id);
@@ -815,10 +815,10 @@ function linkUrl(url, state, fromHost, base) {
815
815
  }
816
816
  if (u.protocol !== "https:" && u.protocol !== "http:") return url;
817
817
  if (!orgOf(u.hostname) || u.hostname === fromHost) return url;
818
- const set = (k, v) => v && u.searchParams.set(k, v);
819
- if (isId(state.anonId)) set(LINK_PARAMS.anon, state.anonId);
820
- if (isId(state.sessionId)) set(LINK_PARAMS.session, state.sessionId);
821
- if (state.firstTouch) set(LINK_PARAMS.firstTouch, encodeFirstTouch(state.firstTouch));
818
+ const set2 = (k, v) => v && u.searchParams.set(k, v);
819
+ if (isId(state.anonId)) set2(LINK_PARAMS.anon, state.anonId);
820
+ if (isId(state.sessionId)) set2(LINK_PARAMS.session, state.sessionId);
821
+ if (state.firstTouch) set2(LINK_PARAMS.firstTouch, encodeFirstTouch(state.firstTouch));
822
822
  return u.toString();
823
823
  }
824
824
  function readLink(search) {
@@ -1168,11 +1168,11 @@ var Analytics = class {
1168
1168
  * or publishable key is attached here — the two planes authenticate
1169
1169
  * independently. Errors are sent one envelope per event, immediately: batching
1170
1170
  * a crash report is how you lose it. */
1171
- sendError(err, options) {
1171
+ sendError(err, options2) {
1172
1172
  if (!this.cfg.enabled || !this.dsn) return;
1173
1173
  const event = buildSentryEvent({
1174
1174
  error: err,
1175
- options,
1175
+ options: options2,
1176
1176
  identity: this.errorIdentity(),
1177
1177
  capturePII: this.cfg.capturePII ?? false
1178
1178
  });
@@ -1259,16 +1259,16 @@ var Analytics = class {
1259
1259
  };
1260
1260
  var CLIENTS = /* @__PURE__ */ Symbol.for("hanzo.event.clients");
1261
1261
  function registry() {
1262
- const g = globalThis;
1263
- const existing = g[CLIENTS];
1262
+ const g2 = globalThis;
1263
+ const existing = g2[CLIENTS];
1264
1264
  if (existing) return existing;
1265
1265
  const fresh = /* @__PURE__ */ new Map();
1266
- g[CLIENTS] = fresh;
1266
+ g2[CLIENTS] = fresh;
1267
1267
  return fresh;
1268
1268
  }
1269
1269
  function resetClients() {
1270
- const g = globalThis;
1271
- delete g[CLIENTS];
1270
+ const g2 = globalThis;
1271
+ delete g2[CLIENTS];
1272
1272
  }
1273
1273
  function createAnalytics(config) {
1274
1274
  if (!isBrowser() || config.enabled === false) return new Analytics(config);
@@ -1284,6 +1284,427 @@ function createAnalytics(config) {
1284
1284
  return fresh;
1285
1285
  }
1286
1286
 
1287
+ // src/cookie.ts
1288
+ var DAY = 86400;
1289
+ function domain() {
1290
+ const h = window.location.hostname;
1291
+ if (h === "localhost" || /^[\d.]+$/.test(h) || h.includes(":")) return "";
1292
+ const parts = h.split(".");
1293
+ return parts.length > 2 ? `; Domain=.${parts.slice(-2).join(".")}` : `; Domain=.${h}`;
1294
+ }
1295
+ function get(name) {
1296
+ if (typeof document === "undefined") return void 0;
1297
+ const hit = document.cookie.split("; ").find((c) => c.startsWith(`${name}=`));
1298
+ return hit ? decodeURIComponent(hit.slice(name.length + 1)) : void 0;
1299
+ }
1300
+ function set(name, value, days) {
1301
+ if (typeof document === "undefined") return;
1302
+ const secure = window.location.protocol === "https:" ? "; Secure" : "";
1303
+ document.cookie = `${name}=${encodeURIComponent(value)}; Max-Age=${days * DAY}; Path=/; SameSite=Lax${domain()}${secure}`;
1304
+ }
1305
+
1306
+ // src/consent.ts
1307
+ var CONSENT_COOKIE = "hz_consent";
1308
+ var CONSENT_EVENT = "hzconsent";
1309
+ var US = /^(America\/(New_York|Chicago|Denver|Los_Angeles|Phoenix|Anchorage|Adak|Boise|Detroit|Juneau|Sitka|Nome|Yakutat|Menominee|Metlakatla|Indiana\/.*|Kentucky\/.*|North_Dakota\/.*)|Pacific\/Honolulu|US\/.*)$/;
1310
+ function gpc() {
1311
+ if (typeof navigator === "undefined") return false;
1312
+ return navigator.globalPrivacyControl === true;
1313
+ }
1314
+ function refused() {
1315
+ if (typeof window === "undefined") return false;
1316
+ const n = navigator;
1317
+ const dnt = n.doNotTrack ?? window.doNotTrack ?? n.msDoNotTrack;
1318
+ return gpc() || dnt === "1" || dnt === "yes";
1319
+ }
1320
+ function region() {
1321
+ try {
1322
+ const zone = Intl.DateTimeFormat().resolvedOptions().timeZone ?? "";
1323
+ return US.test(zone) ? "opt-out" : "opt-in";
1324
+ } catch {
1325
+ return "opt-in";
1326
+ }
1327
+ }
1328
+ function stored() {
1329
+ return get(CONSENT_COOKIE) !== void 0;
1330
+ }
1331
+ function read2() {
1332
+ const kept = get(CONSENT_COOKIE);
1333
+ const on = kept !== void 0 ? kept.split(",") : region() === "opt-in" || refused() ? [] : ["analytics", "marketing", "ads"];
1334
+ const has = (k) => on.includes(k);
1335
+ return { analytics: has("analytics"), marketing: has("marketing") && !gpc(), ads: has("ads") && !gpc() };
1336
+ }
1337
+ function asks() {
1338
+ return typeof document !== "undefined" && region() === "opt-in" && !stored();
1339
+ }
1340
+ function render(c) {
1341
+ return ["analytics", "marketing", "ads"].filter((k) => c[k]).join(",");
1342
+ }
1343
+ function save(c) {
1344
+ const out = { analytics: c.analytics, marketing: c.marketing && !gpc(), ads: c.ads && !gpc() };
1345
+ set(CONSENT_COOKIE, render(out), 395);
1346
+ if (typeof window !== "undefined") window.dispatchEvent(new Event(CONSENT_EVENT));
1347
+ }
1348
+ var acceptAll = () => save({ analytics: true, marketing: true, ads: true });
1349
+ var rejectAll = () => save({ analytics: false, marketing: false, ads: false });
1350
+
1351
+ // src/touch.ts
1352
+ var CLICK_IDS = ["gclid", "gbraid", "wbraid", "fbclid", "li_fat_id", "twclid", "ttclid"];
1353
+ var DAYS = 90;
1354
+ var now = () => Math.floor(Date.now() / 1e3);
1355
+ var rand = () => Math.floor(Math.random() * 2 ** 31);
1356
+ function capture(c) {
1357
+ if (typeof window === "undefined") return;
1358
+ if (c.marketing) {
1359
+ const q = new URLSearchParams(window.location.search);
1360
+ const click = {};
1361
+ for (const k of CLICK_IDS) {
1362
+ const v = q.get(k)?.trim();
1363
+ if (v) click[k] = v;
1364
+ }
1365
+ if (Object.keys(click).length) {
1366
+ click.clicked = now();
1367
+ set("hz_touch", JSON.stringify(click), DAYS);
1368
+ if (click.fbclid) set("_fbc", `fb.1.${Date.now()}.${click.fbclid}`, DAYS);
1369
+ }
1370
+ if (!get("_fbp")) set("_fbp", `fb.1.${Date.now()}.${rand()}`, DAYS);
1371
+ }
1372
+ if (c.analytics && !get("_ga") && !get("hz_cid")) set("hz_cid", `${rand()}.${now()}`, 730);
1373
+ }
1374
+ function touch(c) {
1375
+ const out = {};
1376
+ if (c.marketing) {
1377
+ try {
1378
+ Object.assign(out, JSON.parse(get("hz_touch") ?? "{}"));
1379
+ } catch {
1380
+ }
1381
+ const fbc = get("_fbc");
1382
+ const fbp = get("_fbp");
1383
+ if (fbc) out.fbc = fbc;
1384
+ if (fbp) out.fbp = fbp;
1385
+ }
1386
+ if (c.analytics) {
1387
+ const ga = get("_ga")?.split(".");
1388
+ const cid = ga && ga.length >= 4 ? ga.slice(-2).join(".") : get("hz_cid");
1389
+ if (cid) out.cid = cid;
1390
+ }
1391
+ return out;
1392
+ }
1393
+ var page = () => window;
1394
+ var tags = [];
1395
+ var configured = false;
1396
+ var options = {};
1397
+ var loaded = /* @__PURE__ */ new Set();
1398
+ var google = "idle";
1399
+ var configAnswered = false;
1400
+ var held = [];
1401
+ var leaving = false;
1402
+ function settled() {
1403
+ return configAnswered && google !== "wait";
1404
+ }
1405
+ function flush() {
1406
+ if (settled() || leaving) held.splice(0).forEach((send) => send());
1407
+ }
1408
+ function script(src, onload, onerror) {
1409
+ const s = document.createElement("script");
1410
+ s.async = true;
1411
+ s.src = src;
1412
+ if (onload) s.onload = onload;
1413
+ if (onerror) s.onerror = onerror;
1414
+ document.head.appendChild(s);
1415
+ }
1416
+ function gtagStub() {
1417
+ const p = page();
1418
+ p.dataLayer = p.dataLayer || [];
1419
+ if (!p.gtag) {
1420
+ p.gtag = function() {
1421
+ p.dataLayer.push(arguments);
1422
+ };
1423
+ }
1424
+ return p.gtag;
1425
+ }
1426
+ var g = (on) => on ? "granted" : "denied";
1427
+ function consentMode(c, first) {
1428
+ const gtag = gtagStub();
1429
+ const state = {
1430
+ analytics_storage: g(c.analytics),
1431
+ ad_storage: g(c.marketing),
1432
+ ad_user_data: g(c.marketing),
1433
+ ad_personalization: g(c.marketing && c.ads)
1434
+ };
1435
+ if (first) {
1436
+ gtag("consent", "default", {
1437
+ analytics_storage: "denied",
1438
+ ad_storage: "denied",
1439
+ ad_user_data: "denied",
1440
+ ad_personalization: "denied",
1441
+ wait_for_update: 500
1442
+ });
1443
+ }
1444
+ gtag("consent", "update", state);
1445
+ }
1446
+ function loadGoogle(ids) {
1447
+ const gtag = gtagStub();
1448
+ const fresh = ids.filter((id) => !loaded.has(id));
1449
+ if (!fresh.length) return;
1450
+ if (google === "idle") {
1451
+ google = "wait";
1452
+ gtag("js", /* @__PURE__ */ new Date());
1453
+ const done = (to) => () => {
1454
+ if (google !== "wait") return;
1455
+ google = to;
1456
+ flush();
1457
+ };
1458
+ script(`https://www.googletagmanager.com/gtag/js?id=${encodeURIComponent(fresh[0])}`, done("loaded"), done("failed"));
1459
+ setTimeout(done("failed"), 8e3);
1460
+ }
1461
+ for (const id of fresh) {
1462
+ loaded.add(id);
1463
+ gtag("config", id, options.domains ? { linker: { domains: options.domains } } : {});
1464
+ }
1465
+ }
1466
+ function loadMeta(id, c) {
1467
+ const p = page();
1468
+ if (!p.fbq) {
1469
+ const n = p.fbq = function(...a) {
1470
+ if (n.callMethod) n.callMethod(...a);
1471
+ else n.queue.push(a);
1472
+ };
1473
+ if (!p._fbq) p._fbq = n;
1474
+ n.push = n;
1475
+ n.loaded = true;
1476
+ n.version = "2.0";
1477
+ n.queue = [];
1478
+ script("https://connect.facebook.net/en_US/fbevents.js");
1479
+ }
1480
+ if (!c.ads) p.fbq("dataProcessingOptions", ["LDU"], 0, 0);
1481
+ p.fbq("init", id);
1482
+ p.fbq("track", "PageView");
1483
+ }
1484
+ function loadLinkedIn(id) {
1485
+ const p = page();
1486
+ p._linkedin_data_partner_ids = p._linkedin_data_partner_ids || [];
1487
+ p._linkedin_data_partner_ids.push(id);
1488
+ if (!p.lintrk) {
1489
+ const l = p.lintrk = function(...a) {
1490
+ l.q.push(a);
1491
+ };
1492
+ l.q = [];
1493
+ }
1494
+ script("https://snap.licdn.com/li.lms-analytics/insight.min.js");
1495
+ }
1496
+ function loadX(id) {
1497
+ const p = page();
1498
+ if (!p.twq) {
1499
+ const s = p.twq = function(...a) {
1500
+ if (s.exe) s.exe(...a);
1501
+ else s.queue.push(a);
1502
+ };
1503
+ s.version = "1.1";
1504
+ s.queue = [];
1505
+ script("https://static.ads-twitter.com/uwt.js");
1506
+ }
1507
+ p.twq("config", id);
1508
+ }
1509
+ var TIKTOK_METHODS = ["page", "track", "identify", "instances", "debug", "on", "off", "once", "ready", "alias", "group", "enableCookie", "disableCookie"];
1510
+ function loadTikTok(id) {
1511
+ const p = page();
1512
+ p.TiktokAnalyticsObject = "ttq";
1513
+ const q = p.ttq = p.ttq || [];
1514
+ if (!q._i) {
1515
+ q.methods = TIKTOK_METHODS;
1516
+ for (const m of TIKTOK_METHODS) q[m] = (...a) => q.push([m, ...a]);
1517
+ q._i = {};
1518
+ q._t = {};
1519
+ q._o = {};
1520
+ q.load = (sdk) => {
1521
+ q._i[sdk] = [];
1522
+ q._t[sdk] = Date.now();
1523
+ script(`https://analytics.tiktok.com/i18n/pixel/events.js?sdkid=${encodeURIComponent(sdk)}&lib=ttq`);
1524
+ };
1525
+ }
1526
+ q.load(id);
1527
+ q.page();
1528
+ }
1529
+ var NEEDS = {
1530
+ ga: "analytics",
1531
+ gads: "marketing",
1532
+ meta: "marketing",
1533
+ linkedin: "marketing",
1534
+ x: "marketing",
1535
+ tiktok: "marketing"
1536
+ };
1537
+ var allowed = (t, c) => t.type === "ga" ? c.analytics || c.marketing : Boolean(NEEDS[t.type] && c[NEEDS[t.type]]);
1538
+ function apply() {
1539
+ if (typeof window === "undefined" || !configured) return;
1540
+ const c = read2();
1541
+ capture(c);
1542
+ const on = tags.filter((t) => allowed(t, c));
1543
+ const ids = on.filter((t) => t.type === "ga" || t.type === "gads").map((t) => t.id);
1544
+ if (ids.length) {
1545
+ consentMode(c, !loaded.has("consent"));
1546
+ loaded.add("consent");
1547
+ loadGoogle(ids);
1548
+ }
1549
+ for (const t of on) {
1550
+ const k = `${t.type}:${t.id}`;
1551
+ if (loaded.has(k)) continue;
1552
+ if (t.type === "meta") loadMeta(t.id, c);
1553
+ else if (t.type === "linkedin") loadLinkedIn(t.id);
1554
+ else if (t.type === "x") loadX(t.id);
1555
+ else if (t.type === "tiktok") loadTikTok(t.id);
1556
+ else continue;
1557
+ loaded.add(k);
1558
+ }
1559
+ flush();
1560
+ }
1561
+ function start(o = {}) {
1562
+ if (typeof window === "undefined") return () => void 0;
1563
+ options = o;
1564
+ addEventListener(CONSENT_EVENT, apply);
1565
+ addEventListener("pagehide", pagehide);
1566
+ if (!configured) {
1567
+ configured = true;
1568
+ const base = (o.base ?? "https://api.hanzo.ai").replace(/\/$/, "");
1569
+ const q = new URLSearchParams();
1570
+ if (o.key) q.set("key", o.key);
1571
+ q.set("host", o.host ?? window.location.hostname);
1572
+ const answer = (list) => {
1573
+ tags = list;
1574
+ configAnswered = true;
1575
+ apply();
1576
+ };
1577
+ const cap = setTimeout(() => answer([]), 3e3);
1578
+ fetch(`${base}/v1/project/tags?${q}`).then((r) => r.ok ? r.json() : { tags: [] }).then((j) => {
1579
+ clearTimeout(cap);
1580
+ answer(Array.isArray(j.tags) ? j.tags : []);
1581
+ }).catch(() => {
1582
+ clearTimeout(cap);
1583
+ answer([]);
1584
+ });
1585
+ }
1586
+ return () => {
1587
+ removeEventListener(CONSENT_EVENT, apply);
1588
+ removeEventListener("pagehide", pagehide);
1589
+ };
1590
+ }
1591
+ function pagehide() {
1592
+ leaving = true;
1593
+ flush();
1594
+ }
1595
+ function reach() {
1596
+ const c = read2();
1597
+ const to = [];
1598
+ for (const t of tags) {
1599
+ if (!allowed(t, c)) continue;
1600
+ const running = t.type === "ga" ? google === "loaded" && c.analytics : t.type === "gads" ? google === "loaded" && c.marketing : loaded.has(`${t.type}:${t.id}`);
1601
+ if (running && !to.includes(t.type)) to.push(t.type);
1602
+ }
1603
+ return to.join(",");
1604
+ }
1605
+ var META_STANDARD = /* @__PURE__ */ new Set([
1606
+ "AddPaymentInfo",
1607
+ "AddToCart",
1608
+ "AddToWishlist",
1609
+ "CompleteRegistration",
1610
+ "Contact",
1611
+ "CustomizeProduct",
1612
+ "Donate",
1613
+ "FindLocation",
1614
+ "InitiateCheckout",
1615
+ "Lead",
1616
+ "Purchase",
1617
+ "Schedule",
1618
+ "Search",
1619
+ "StartTrial",
1620
+ "SubmitApplication",
1621
+ "Subscribe",
1622
+ "ViewContent"
1623
+ ]);
1624
+ function shape(platform, p) {
1625
+ const items = Array.isArray(p.items) ? p.items : [];
1626
+ const out = {};
1627
+ if (typeof p.value === "number") out.value = p.value;
1628
+ out.currency = typeof p.currency === "string" ? p.currency : "USD";
1629
+ if (!items.length) return out;
1630
+ if (platform === "meta") {
1631
+ out.content_type = "product";
1632
+ out.content_ids = items.map((i) => i.item_id);
1633
+ out.contents = items.map((i) => ({ id: i.item_id, quantity: i.quantity ?? 1, item_price: i.price }));
1634
+ out.content_name = items[0].item_name;
1635
+ out.num_items = items.reduce((n, i) => n + (i.quantity ?? 1), 0);
1636
+ } else if (platform === "tiktok") {
1637
+ out.content_type = "product";
1638
+ out.contents = items.map((i) => ({ content_id: i.item_id, content_name: i.item_name, quantity: i.quantity ?? 1, price: i.price }));
1639
+ } else {
1640
+ out.contents = items.map((i) => ({ content_id: i.item_id, content_name: i.item_name, content_price: i.price, num_items: i.quantity ?? 1 }));
1641
+ }
1642
+ return out;
1643
+ }
1644
+ function unpriced(p) {
1645
+ const out = { ...p, value: 0 };
1646
+ if (Array.isArray(p.items)) out.items = p.items.map((i) => ({ ...i, price: 0 }));
1647
+ return out;
1648
+ }
1649
+ function mirror(name, params, id, to = reach()) {
1650
+ const p = page();
1651
+ const on = new Set(to.split(",").filter(Boolean));
1652
+ const ga4 = events.namesOn(name, "ga4");
1653
+ const test = params.test === true;
1654
+ if (test) params = unpriced(params);
1655
+ const transaction = typeof params.order_id === "string" ? { transaction_id: params.order_id } : {};
1656
+ for (const t of tags) {
1657
+ if (!on.has(t.type)) continue;
1658
+ const rule = t.events?.[name];
1659
+ if (t.type === "ga") {
1660
+ for (const n of ga4) {
1661
+ p.gtag?.("event", n, { ...params, ...transaction, event_id: id, transport_type: "beacon", ...test ? { debug_mode: true } : {} });
1662
+ }
1663
+ } else if (t.type === "gads" && rule) {
1664
+ p.gtag?.("event", "conversion", {
1665
+ send_to: rule,
1666
+ value: typeof params.value === "number" ? params.value : void 0,
1667
+ currency: typeof params.currency === "string" ? params.currency : "USD",
1668
+ ...transaction
1669
+ });
1670
+ } else if (t.type === "meta") {
1671
+ for (const n of events.namesOn(name, "meta")) {
1672
+ p.fbq?.(META_STANDARD.has(n) ? "track" : "trackCustom", n, shape("meta", params), { eventID: id });
1673
+ }
1674
+ } else if (t.type === "tiktok") {
1675
+ for (const n of events.namesOn(name, "tiktok")) p.ttq?.track?.(n, shape("tiktok", params), { event_id: id });
1676
+ } else if (t.type === "linkedin" && rule && events.namesOn(name, "linkedin").length) {
1677
+ p.lintrk?.("track", { conversion_id: Number(rule) });
1678
+ } else if (t.type === "x" && rule && events.namesOn(name, "x").length) {
1679
+ p.twq?.("event", rule, { ...shape("x", params), conversion_id: id });
1680
+ }
1681
+ }
1682
+ }
1683
+ function track(stream, name, params = {}) {
1684
+ if (typeof window === "undefined") return;
1685
+ if (!leaving && !settled()) {
1686
+ held.push(() => track(stream, name, params));
1687
+ return;
1688
+ }
1689
+ const c = read2();
1690
+ const event_id = crypto.randomUUID();
1691
+ const to = reach();
1692
+ mirror(name, params, event_id, to);
1693
+ stream?.capture(name, {
1694
+ ...params,
1695
+ ...touch(c),
1696
+ event_id,
1697
+ consent: render(c),
1698
+ tags: to,
1699
+ userAgent: navigator.userAgent,
1700
+ url: window.location.href
1701
+ });
1702
+ }
1703
+ function visit() {
1704
+ const c = read2();
1705
+ return { ...touch(c), consent: render(c), tags: reach(), userAgent: navigator.userAgent, url: window.location.href };
1706
+ }
1707
+
1287
1708
  // src/goals.ts
1288
1709
  var GOALS = {
1289
1710
  // Signup: the conversion is signup_completed, along the site signup funnel.
@@ -1369,15 +1790,21 @@ Object.defineProperty(exports, "eventsOf", {
1369
1790
  get: function () { return events.eventsOf; }
1370
1791
  });
1371
1792
  exports.Analytics = Analytics;
1793
+ exports.CLICK_IDS = CLICK_IDS;
1372
1794
  exports.COHORTS = COHORTS;
1795
+ exports.CONSENT_COOKIE = CONSENT_COOKIE;
1796
+ exports.CONSENT_EVENT = CONSENT_EVENT;
1373
1797
  exports.GOALS = GOALS;
1374
1798
  exports.LINK_PARAMS = LINK_PARAMS;
1375
1799
  exports.ORG_DOMAIN = ORG_DOMAIN;
1376
1800
  exports.ORG_KEY = ORG_KEY;
1377
1801
  exports.PRODUCT_PROJECT = PRODUCT_PROJECT;
1378
1802
  exports.VERSION = VERSION;
1803
+ exports.acceptAll = acceptAll;
1804
+ exports.asks = asks;
1379
1805
  exports.buildEnvelope = buildEnvelope;
1380
1806
  exports.buildSentryEvent = buildSentryEvent;
1807
+ exports.captureClick = capture;
1381
1808
  exports.createAnalytics = createAnalytics;
1382
1809
  exports.deriveChannel = deriveChannel;
1383
1810
  exports.digest = digest;
@@ -1388,22 +1815,36 @@ exports.fingerprint = fingerprint;
1388
1815
  exports.framesFromStack = framesFromStack;
1389
1816
  exports.getCohort = getCohort;
1390
1817
  exports.getFirstTouch = getFirstTouch;
1818
+ exports.gpc = gpc;
1391
1819
  exports.hasAttribution = hasAttribution;
1392
1820
  exports.hostOf = hostOf;
1393
1821
  exports.isoWeek = isoWeek;
1394
1822
  exports.keyFor = keyFor;
1395
1823
  exports.keyForPage = keyForPage;
1396
1824
  exports.linkUrl = linkUrl;
1825
+ exports.mirror = mirror;
1397
1826
  exports.orgOf = orgOf;
1398
1827
  exports.parseAttribution = parseAttribution;
1399
1828
  exports.parseDsn = parseDsn;
1829
+ exports.reach = reach;
1830
+ exports.readConsent = read2;
1400
1831
  exports.readLink = readLink;
1401
1832
  exports.redactSecrets = redactSecrets;
1833
+ exports.refused = refused;
1834
+ exports.region = region;
1835
+ exports.rejectAll = rejectAll;
1836
+ exports.renderConsent = render;
1402
1837
  exports.resetClients = resetClients;
1838
+ exports.saveConsent = save;
1403
1839
  exports.scrubPII = scrubPII;
1404
1840
  exports.scrubText = scrubText;
1841
+ exports.startTags = start;
1842
+ exports.storedConsent = stored;
1405
1843
  exports.stripLink = stripLink;
1844
+ exports.touch = touch;
1845
+ exports.track = track;
1406
1846
  exports.uuidv7 = hzUuidv7;
1407
1847
  exports.uuidv7Time = uuidv7Time;
1848
+ exports.visit = visit;
1408
1849
  //# sourceMappingURL=index.cjs.map
1409
1850
  //# sourceMappingURL=index.cjs.map