react-marketing-tools 1.0.0-alpha.4 → 1.0.0-beta.3

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.
@@ -1,10 +1,97 @@
1
- //#region lib/core/consent.ts
2
- var e = [
1
+ import { a as e, i as t, n, r, t as i } from "./cookies.js";
2
+ //#region lib/attribution/attribution.ts
3
+ var a = [
4
+ "utm_source",
5
+ "utm_medium",
6
+ "utm_campaign",
7
+ "utm_term",
8
+ "utm_content",
9
+ "utm_id",
10
+ "utm_source_platform",
11
+ "utm_creative_format",
12
+ "utm_marketing_tactic",
13
+ "gclid",
14
+ "gbraid",
15
+ "wbraid",
16
+ "dclid",
17
+ "fbclid",
18
+ "msclkid",
19
+ "ttclid",
20
+ "li_fat_id",
21
+ "twclid"
22
+ ], o = 100, s = (e) => {
23
+ if (!URL.canParse(e)) return;
24
+ let { origin: t, pathname: n } = new URL(e);
25
+ return t + n;
26
+ }, c = ({ url: t, referrer: n, capturedAt: r }) => {
27
+ if (!URL.canParse(t)) return;
28
+ let { searchParams: i } = new URL(t), c = a.flatMap((e) => {
29
+ let t = i.get(e)?.trim();
30
+ return t ? [[e, t]] : [];
31
+ });
32
+ if (c.length === 0) return;
33
+ let { params: l } = e(Object.fromEntries(c)), u = Object.fromEntries(Object.entries(l).map(([e, t]) => [e, String(t).slice(0, o)])), d = n ? s(n) : void 0;
34
+ return {
35
+ ...u,
36
+ landing_page: s(t) ?? t,
37
+ ...d ? { referrer: d } : {},
38
+ captured_at: r
39
+ };
40
+ }, l = (e) => typeof e == "object" && !!e, u = (e) => {
41
+ if (l(e) && typeof e.captured_at == "number" && typeof e.landing_page == "string") return {
42
+ ...Object.fromEntries(a.flatMap((t) => typeof e[t] == "string" ? [[t, e[t]]] : [])),
43
+ landing_page: e.landing_page,
44
+ ...typeof e.referrer == "string" ? { referrer: e.referrer } : {},
45
+ captured_at: e.captured_at
46
+ };
47
+ }, d = ({ fbcCookie: e, touch: t }) => e ?? (t?.fbclid ? `fb.1.${t.captured_at}.${t.fbclid}` : void 0), f = "rmt:attribution:first", p = "rmt:attribution:last", m = 864e5, h = (e, t) => {
48
+ try {
49
+ return t(window[e]);
50
+ } catch {
51
+ return;
52
+ }
53
+ }, g = (e, t) => h(e, (e) => {
54
+ let n = e.getItem(t);
55
+ return n === null ? void 0 : u(JSON.parse(n));
56
+ }), ee = ({ ttlDays: e }) => {
57
+ let t, n, r = (t) => Date.now() - t.captured_at < e * m;
58
+ return {
59
+ observe(e) {
60
+ e && (t ??= e, n = e);
61
+ },
62
+ restore() {
63
+ let e = g("localStorage", f);
64
+ e && r(e) && (!t || e.captured_at <= t.captured_at) && (t = e), n ??= g("sessionStorage", p);
65
+ },
66
+ persist() {
67
+ h("localStorage", (e) => t && r(t) ? e.setItem(f, JSON.stringify(t)) : e.removeItem(f)), n && h("sessionStorage", (e) => e.setItem(p, JSON.stringify(n)));
68
+ },
69
+ erase() {
70
+ h("localStorage", (e) => e.removeItem(f)), h("sessionStorage", (e) => e.removeItem(p));
71
+ },
72
+ get: () => ({
73
+ firstTouch: t,
74
+ lastTouch: n
75
+ })
76
+ };
77
+ }, _ = "data-analytics-event", v = "data-analytics-param-", y = (e) => {
78
+ if (!(e instanceof Element)) return;
79
+ let t = e.closest(`[${_}]`), n = t?.getAttribute(_);
80
+ if (t && n) return {
81
+ name: n,
82
+ params: Object.fromEntries(Array.from(t.attributes).filter((e) => e.name.startsWith(v)).map((e) => [e.name.slice(21).replaceAll("-", "_"), e.value]))
83
+ };
84
+ }, b = (e) => {
85
+ document.addEventListener("click", (t) => {
86
+ let n = y(t.target);
87
+ n && e(n.name, n.params);
88
+ }, { capture: !0 });
89
+ }, x = [
3
90
  "analytics",
4
91
  "ads",
5
92
  "adUserData",
6
93
  "adPersonalization"
7
- ], t = (e) => e === "granted" || e === "denied", n = ({ consent: e, gpc: t }) => {
94
+ ], te = (e) => e === "granted" || e === "denied", ne = ({ consent: e, gpc: t }) => {
8
95
  let n = t ? "denied" : e;
9
96
  return {
10
97
  analytics: e,
@@ -12,35 +99,35 @@ var e = [
12
99
  adUserData: n,
13
100
  adPersonalization: n
14
101
  };
15
- }, r = (e, t) => ({
102
+ }, S = (e, t) => ({
16
103
  analytics: t.analytics ?? e.analytics,
17
104
  ads: t.ads ?? e.ads,
18
105
  adUserData: t.adUserData ?? t.ads ?? e.adUserData,
19
106
  adPersonalization: t.adPersonalization ?? t.ads ?? e.adPersonalization
20
- }), i = (e) => ({
107
+ }), C = (e) => ({
21
108
  analytics_storage: e.analytics,
22
109
  ad_storage: e.ads,
23
110
  ad_user_data: e.adUserData,
24
111
  ad_personalization: e.adPersonalization
25
- }), a = (e) => Object.values(e).includes("denied"), o = () => typeof navigator < "u" && navigator.globalPrivacyControl === !0, s = () => window.dataLayer ??= [], c = () => Array.from(document.scripts).some((e) => URL.canParse(e.src) && new URL(e.src).pathname.endsWith("/gtag/js")), l = () => window.gtag ??= function() {
26
- s().push(arguments);
27
- }, u = ({ consent: e, waitForUpdate: t }) => {
28
- l()("consent", "default", {
29
- ...i(e),
30
- ...a(e) ? { wait_for_update: t } : {}
112
+ }), w = (e) => Object.values(e).includes("denied"), re = () => typeof navigator < "u" && navigator.globalPrivacyControl === !0, T = () => window.dataLayer ??= [], E = () => Array.from(document.scripts).some((e) => URL.canParse(e.src) && new URL(e.src).pathname.endsWith("/gtag/js")), D = () => window.gtag ??= function() {
113
+ T().push(arguments);
114
+ }, O = ({ consent: e, waitForUpdate: t }) => {
115
+ D()("consent", "default", {
116
+ ...C(e),
117
+ ...w(e) ? { wait_for_update: t } : {}
31
118
  });
32
- }, d = (e) => {
33
- l()("consent", "update", i(e));
34
- }, f = (e, t) => {
119
+ }, k = (e) => {
120
+ D()("consent", "update", C(e));
121
+ }, A = (e, t) => {
35
122
  let n = URL.canParse(e) ? new URL(e) : void 0;
36
123
  if (n?.protocol !== "https:") throw Error(`[react-marketing-tools] ${t} must be an https:// URL (received ${JSON.stringify(e)}).`);
37
124
  return n;
38
- }, p = (e) => Array.from(document.scripts).some((t) => t.src === e), m = ({ src: e, nonce: t }) => {
125
+ }, j = (e) => Array.from(document.scripts).some((t) => t.src === e), M = ({ src: e, nonce: t }) => {
39
126
  let n = document.createElement("script");
40
127
  n.async = !0, n.src = e, t && n.setAttribute("nonce", t), document.head.append(n);
41
- }, h = /^G-[A-Z0-9]+$/, g = ({ measurementId: e, pageViews: t = "auto", loadScript: n = !0, serverContainerUrl: r, waitForUpdate: i = 500, nonce: a }) => {
42
- if (!h.test(e)) throw Error(`[react-marketing-tools] ga4.measurementId must look like "G-XXXXXXX" (received ${JSON.stringify(e)}).`);
43
- r !== void 0 && f(r, "ga4.serverContainerUrl");
128
+ }, ie = /^G-[A-Z0-9]+$/, ae = ({ measurementId: e, pageViews: t = "auto", loadScript: n = !0, serverContainerUrl: r, waitForUpdate: i = 500, nonce: a }) => {
129
+ if (!ie.test(e)) throw Error(`[react-marketing-tools] ga4.measurementId must look like "G-XXXXXXX" (received ${JSON.stringify(e)}).`);
130
+ r !== void 0 && A(r, "ga4.serverContainerUrl");
44
131
  let o = `https://www.googletagmanager.com/gtag/js?id=${e}`, s = (e, t) => r ? {
45
132
  ...e,
46
133
  event_id: t
@@ -48,77 +135,78 @@ var e = [
48
135
  return {
49
136
  name: "ga4",
50
137
  start({ consent: s }) {
51
- u({
138
+ O({
52
139
  consent: s,
53
140
  waitForUpdate: i
54
- }), c() || (l()("js", /* @__PURE__ */ new Date()), n && m({
141
+ }), E() || (D()("js", /* @__PURE__ */ new Date()), n && M({
55
142
  src: o,
56
143
  nonce: a
57
- })), l()("config", e, {
144
+ })), D()("config", e, {
58
145
  ...t === "manual" ? { send_page_view: !1 } : {},
59
146
  ...r ? { server_container_url: r } : {}
60
147
  });
61
148
  },
62
149
  track({ name: e, params: t, eventId: n }) {
63
- l()("event", e, s(t, n));
150
+ D()("event", e, s(t, n));
64
151
  },
65
152
  consent(e) {
66
- d(e);
153
+ k(e);
67
154
  },
68
155
  page({ params: e, eventId: n }) {
69
- t === "manual" && l()("event", "page_view", s(e, n));
156
+ t === "manual" && D()("event", "page_view", s(e, n));
70
157
  },
71
158
  identify({ userId: e }) {
72
- l()("set", { user_id: e });
159
+ D()("set", { user_id: e });
73
160
  },
74
161
  reset() {
75
- l()("set", { user_id: null });
162
+ D()("set", { user_id: null });
76
163
  }
77
164
  };
78
- }, _ = /^GTM-[A-Z0-9]+$/, v = (e, t) => {
79
- let n = f(t ?? "https://www.googletagmanager.com/gtm.js", "gtm.scriptUrl");
165
+ }, N = /^GTM-[A-Z0-9]+$/, P = (e, t) => {
166
+ let n = A(t ?? "https://www.googletagmanager.com/gtm.js", "gtm.scriptUrl");
80
167
  return n.searchParams.set("id", e), n.href;
81
- }, y = ({ containerId: e, loadScript: t = !0, scriptUrl: n, waitForUpdate: r = 500, nonce: i }) => {
82
- if (!_.test(e)) throw Error(`[react-marketing-tools] gtm.containerId must look like "GTM-XXXXXXX" (received ${JSON.stringify(e)}).`);
83
- let a = v(e, n);
168
+ }, F = ({ containerId: e, loadScript: t = !0, scriptUrl: n, waitForUpdate: r = 500, nonce: i }) => {
169
+ if (!N.test(e)) throw Error(`[react-marketing-tools] gtm.containerId must look like "GTM-XXXXXXX" (received ${JSON.stringify(e)}).`);
170
+ let a = P(e, n);
84
171
  return {
85
172
  name: "gtm",
86
173
  start({ consent: e }) {
87
- u({
174
+ O({
88
175
  consent: e,
89
176
  waitForUpdate: r
90
- }), t && !p(a) && (s().push({
177
+ }), t && !j(a) && (T().push({
91
178
  "gtm.start": Date.now(),
92
179
  event: "gtm.js"
93
- }), m({
180
+ }), M({
94
181
  src: a,
95
182
  nonce: i
96
183
  }));
97
184
  },
98
- track({ name: e, params: t, eventId: n }) {
99
- s().push({
185
+ track({ name: e, params: t, eventId: n, attribution: r }) {
186
+ T().push({
100
187
  ...t,
188
+ ...r && { attribution: r },
101
189
  event: e,
102
190
  event_id: n
103
191
  });
104
192
  },
105
193
  consent(e) {
106
- d(e);
194
+ k(e);
107
195
  },
108
196
  identify({ userId: e }) {
109
- s().push({
197
+ T().push({
110
198
  event: "identify",
111
199
  user_id: e
112
200
  });
113
201
  },
114
202
  reset() {
115
- s().push({
203
+ T().push({
116
204
  event: "reset",
117
205
  user_id: void 0
118
206
  });
119
207
  }
120
208
  };
121
- }, b = /* @__PURE__ */ new Set([
209
+ }, I = /* @__PURE__ */ new Set([
122
210
  "AddPaymentInfo",
123
211
  "AddToCart",
124
212
  "AddToWishlist",
@@ -137,7 +225,7 @@ var e = [
137
225
  "SubmitApplication",
138
226
  "Subscribe",
139
227
  "ViewContent"
140
- ]), x = {
228
+ ]), L = {
141
229
  purchase: "Purchase",
142
230
  sign_up: "CompleteRegistration",
143
231
  generate_lead: "Lead",
@@ -147,8 +235,8 @@ var e = [
147
235
  search: "Search",
148
236
  add_payment_info: "AddPaymentInfo",
149
237
  add_to_wishlist: "AddToWishlist"
150
- }, S = (e) => typeof e == "object" && !!e, C = (e) => {
151
- let t = e.filter(S).filter((e) => e.item_id !== void 0).map((e) => ({
238
+ }, R = (e) => typeof e == "object" && !!e, z = (e) => {
239
+ let t = e.filter(R).filter((e) => e.item_id !== void 0).map((e) => ({
152
240
  id: String(e.item_id),
153
241
  quantity: typeof e.quantity == "number" ? e.quantity : 1
154
242
  }));
@@ -158,21 +246,21 @@ var e = [
158
246
  num_items: t.reduce((e, t) => e + t.quantity, 0),
159
247
  content_type: "product"
160
248
  };
161
- }, w = ({ items: e, search_term: t, ...n }) => ({
249
+ }, B = ({ items: e, search_term: t, ...n }) => ({
162
250
  ...n,
163
251
  ...typeof t == "string" ? { search_string: t } : {},
164
- ...Array.isArray(e) ? C(e) : {}
165
- }), T = ({ name: e, params: t, options: n }) => {
166
- let r = n?.meta, i = r?.event ?? x[e] ?? e;
252
+ ...Array.isArray(e) ? z(e) : {}
253
+ }), V = ({ name: e, params: t, options: n }) => {
254
+ let r = n?.meta || void 0, i = r?.event ?? L[e] ?? e;
167
255
  return {
168
- command: b.has(i) ? "track" : "trackCustom",
256
+ command: I.has(i) ? "track" : "trackCustom",
169
257
  name: i,
170
258
  params: {
171
- ...w(t),
259
+ ...B(t),
172
260
  ...r?.params
173
261
  }
174
262
  };
175
- }, E = /^\d+$/, D = "https://connect.facebook.net/en_US/fbevents.js", O = () => {
263
+ }, H = /^\d+$/, U = "https://connect.facebook.net/en_US/fbevents.js", W = () => {
176
264
  let e = window;
177
265
  if (!e.fbq) {
178
266
  let t = function() {
@@ -182,152 +270,286 @@ var e = [
182
270
  t.push = t, t.loaded = !0, t.version = "2.0", t.queue = [], e.fbq = t, e._fbq ??= t;
183
271
  }
184
272
  return e.fbq;
185
- }, k = () => Array.from(document.scripts).some((e) => URL.canParse(e.src) && new URL(e.src).pathname.endsWith("/fbevents.js")), A = ({ userId: e, traits: t }) => Object.fromEntries(Object.entries({
273
+ }, G = () => Array.from(document.scripts).some((e) => URL.canParse(e.src) && new URL(e.src).pathname.endsWith("/fbevents.js")), K = ({ userId: e, traits: t }) => Object.fromEntries(Object.entries({
186
274
  external_id: e,
187
275
  em: t.email,
188
276
  ph: t.phone,
189
277
  fn: t.firstName,
190
278
  ln: t.lastName
191
- }).filter(([, e]) => e !== void 0)), j = (e) => e.adUserData === "granted" ? "grant" : "revoke", M = ({ pixelId: e, pageViews: t = "auto", loadScript: n = !0, nonce: r }) => {
192
- if (!E.test(e)) throw Error(`[react-marketing-tools] metaPixel.pixelId must be the numeric pixel ID (received ${JSON.stringify(e)}).`);
279
+ }).filter(([, e]) => e !== void 0)), q = (e) => e.adUserData === "granted" ? "grant" : "revoke", oe = ({ pixelId: e, pageViews: t = "auto", loadScript: n = !0, nonce: r }) => {
280
+ if (!H.test(e)) throw Error(`[react-marketing-tools] metaPixel.pixelId must be the numeric pixel ID (received ${JSON.stringify(e)}).`);
193
281
  return {
194
282
  name: "metaPixel",
195
283
  start({ consent: i, identity: a }) {
196
- let o = O();
197
- t === "manual" && (o.disablePushState = !0), j(i) === "revoke" && o("consent", "revoke"), a ? o("init", e, A(a)) : o("init", e), t === "auto" && o("track", "PageView"), n && !k() && m({
198
- src: D,
284
+ let o = W();
285
+ t === "manual" && (o.disablePushState = !0), q(i) === "revoke" && o("consent", "revoke"), a ? o("init", e, K(a)) : o("init", e), t === "auto" && o("track", "PageView"), n && !G() && M({
286
+ src: U,
199
287
  nonce: r
200
288
  });
201
289
  },
202
290
  track(e) {
203
- let { command: t, name: n, params: r } = T(e);
204
- O()(t, n, r, { eventID: e.eventId });
291
+ if (e.options?.meta === !1) return;
292
+ let { command: t, name: n, params: r } = V(e);
293
+ W()(t, n, r, { eventID: e.eventId });
205
294
  },
206
295
  page({ eventId: e }) {
207
- t === "manual" && O()("track", "PageView", {}, { eventID: e });
296
+ t === "manual" && W()("track", "PageView", {}, { eventID: e });
208
297
  },
209
298
  consent(e) {
210
- O()("consent", j(e));
299
+ W()("consent", q(e));
211
300
  }
212
301
  };
213
- }, N = class extends Error {
302
+ }, J = class extends Error {
214
303
  code;
215
304
  constructor(e, t, n) {
216
305
  super(`[react-marketing-tools] ${t}`, n), this.name = "AnalyticsError", this.code = e;
217
306
  }
218
- }, P = /^[A-Za-z][A-Za-z0-9_]{0,39}$/, F = [
219
- "google_",
220
- "ga_",
221
- "firebase_"
222
- ], I = 25, L = 100, R = {
223
- page_location: 1e3,
224
- page_referrer: 420,
225
- page_title: 300
226
- }, z = [
227
- "email",
228
- "phone",
229
- "first_name",
230
- "last_name",
231
- "address",
232
- "password"
233
- ], B = String.raw`[\w.+-]+(?:@|%40)[\w-]+(?:\.[\w-]+)+`, V = "[redacted]", H = (e) => {
234
- if (!P.test(e)) return "must start with a letter, contain only letters, digits and underscores, and be at most 40 characters";
235
- let t = F.find((t) => e.toLowerCase().startsWith(t));
236
- return t && `must not start with the reserved prefix "${t}"`;
237
- }, U = (e) => {
238
- let t = H(e);
239
- return t && `event name "${e}" ${t}`;
240
- }, W = (e) => {
241
- let t = Object.keys(e), n = t.flatMap((t) => {
242
- let n = H(t);
243
- if (n) return [`param "${t}" ${n}`];
244
- let r = e[t], i = R[t] ?? L;
245
- return typeof r == "string" && r.length > i ? [`param "${t}" is longer than ${i} characters`] : [];
246
- });
247
- return t.length > I ? [`has ${t.length} params; the limit is ${I}`, ...n] : n;
248
- }, G = (e) => new RegExp(B, "i").test(e), K = (e, t) => (typeof t == "string" || typeof t == "number") && z.some((t) => e.toLowerCase().includes(t)) ? V : typeof t == "string" ? t.replace(new RegExp(B, "gi"), V) : t, q = (e) => {
249
- let t = Object.entries(e).map(([e, t]) => [
250
- e,
251
- t,
252
- K(e, t)
253
- ]);
307
+ }, se = (e) => e.startsWith("/") && !e.startsWith("//") || URL.canParse(e) && new URL(e).protocol === "https:", ce = ({ endpoint: e, relayPageViews: t, visitorId: n, onError: r }) => {
308
+ if (!se(e)) throw Error(`[react-marketing-tools] server.endpoint must be a path on your site, such as '/api/track', or an https:// URL (received ${JSON.stringify(e)}).`);
309
+ let a = "denied", o, s = (e) => {
310
+ let t = i(document.cookie, "_fbp"), r = d({
311
+ fbcCookie: i(document.cookie, "_fbc"),
312
+ touch: e.attribution
313
+ }), a = o?.userId ?? n();
314
+ return {
315
+ ...a && { externalId: a },
316
+ ...o?.traits,
317
+ ...r && { fbc: r },
318
+ ...t && { fbp: t }
319
+ };
320
+ }, c = ({ event: t, eventName: n, customData: i }) => {
321
+ let o = {
322
+ v: 1,
323
+ eventName: n,
324
+ eventId: t.eventId,
325
+ customData: i,
326
+ eventSourceUrl: location.href,
327
+ consent: { adUserData: a },
328
+ userData: s(t)
329
+ }, c = JSON.stringify(o);
330
+ typeof navigator.sendBeacon == "function" && navigator.sendBeacon(e, c) || fetch(e, {
331
+ method: "POST",
332
+ body: c,
333
+ keepalive: !0,
334
+ mode: "no-cors"
335
+ }).catch((t) => {
336
+ r(new J("destination_failed", `destination "server" could not reach ${e}`, { cause: t }));
337
+ });
338
+ };
254
339
  return {
255
- params: Object.fromEntries(t.map(([e, , t]) => [e, t])),
256
- redactedKeys: t.filter(([, e, t]) => t !== e).map(([e]) => e)
340
+ name: "server",
341
+ start(e) {
342
+ a = e.consent.adUserData, o = e.identity;
343
+ },
344
+ track(e) {
345
+ if (a !== "granted" || e.options?.meta === !1) return;
346
+ let { name: t, params: n } = V(e);
347
+ c({
348
+ event: e,
349
+ eventName: t,
350
+ customData: n
351
+ });
352
+ },
353
+ page(e) {
354
+ a === "granted" && t && c({
355
+ event: e,
356
+ eventName: "PageView",
357
+ customData: {}
358
+ });
359
+ },
360
+ consent(e) {
361
+ a = e.adUserData;
362
+ },
363
+ identify(e) {
364
+ o = e;
365
+ },
366
+ reset() {
367
+ o = void 0;
368
+ }
257
369
  };
258
- }, J = () => typeof window < "u", Y = () => typeof crypto.randomUUID == "function" ? crypto.randomUUID() : "10000000-1000-4000-8000-100000000000".replace(/[018]/g, (e) => (Number(e) ^ crypto.getRandomValues(/* @__PURE__ */ new Uint8Array(1))[0] & 15 >> Number(e) / 4).toString(16)), X = (e) => {
370
+ }, Y = () => typeof crypto.randomUUID == "function" ? crypto.randomUUID() : "10000000-1000-4000-8000-100000000000".replace(/[018]/g, (e) => (Number(e) ^ crypto.getRandomValues(/* @__PURE__ */ new Uint8Array(1))[0] & 15 >> Number(e) / 4).toString(16)), X = "rmt:vid", le = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/, Z = () => {
371
+ try {
372
+ let e = localStorage.getItem(X);
373
+ return e !== null && le.test(e) ? e : void 0;
374
+ } catch {
375
+ return;
376
+ }
377
+ }, Q = (e) => {
378
+ try {
379
+ e ? localStorage.setItem(X, e) : localStorage.removeItem(X);
380
+ } catch {}
381
+ }, ue = () => {
382
+ let e, t = (t) => {
383
+ if (t.analytics !== "granted") return;
384
+ let n = Z();
385
+ return n ? e = n : (e ??= Y(), Q(e), e);
386
+ };
387
+ return {
388
+ peek: t,
389
+ get: (e) => Promise.resolve(t(e)),
390
+ erase() {
391
+ e = void 0, Q(void 0);
392
+ }
393
+ };
394
+ }, de = ({ fingerprint: e, onError: t }) => {
395
+ let n, r, i = (e) => e.analytics === "granted" && e.ads === "granted";
396
+ return {
397
+ peek: (e) => i(e) ? r : void 0,
398
+ get(a) {
399
+ return i(a) ? (n ??= Promise.resolve().then(e).then((e) => {
400
+ if (typeof e != "string" || e === "") throw TypeError(`expected a non-empty string, received ${JSON.stringify(e)}`);
401
+ return r = e;
402
+ }).catch((e) => {
403
+ t(new J("visitor_id_failed", "visitorId.fingerprint failed, so this page has no visitor ID", { cause: e }));
404
+ }), n) : Promise.resolve(void 0);
405
+ },
406
+ erase() {
407
+ n = void 0, r = void 0;
408
+ }
409
+ };
410
+ }, fe = ({ config: e, onError: t }) => {
411
+ if (e !== !1) {
412
+ if (e === "random") return ue();
413
+ if (typeof e?.fingerprint == "function") return de({
414
+ fingerprint: e.fingerprint,
415
+ onError: t
416
+ });
417
+ throw Error(`[react-marketing-tools] visitorId must be 'random', false or { fingerprint: () => Promise<string> } (received ${JSON.stringify(e)}).`);
418
+ }
419
+ }, pe = ({ name: e, track: t, fail: n }) => {
420
+ let r = {
421
+ journey_id: Y(),
422
+ journey_name: e
423
+ }, i = !1, a, o = 0, s, c = (o) => a ? (n(new J("journey_ended", `journey "${e}" is already ${a}, so ${o} was ignored`)), !1) : (i || (i = !0, t("journey_start", r)), !0);
424
+ return {
425
+ step(e, n = {}) {
426
+ c(`step("${e}")`) && (o += 1, s = e, t("journey_step", {
427
+ ...n,
428
+ ...r,
429
+ step_name: e,
430
+ step_index: o
431
+ }));
432
+ },
433
+ complete(e = {}) {
434
+ c("complete()") && (a = "completed", t("journey_complete", {
435
+ ...e,
436
+ ...r,
437
+ step_count: o
438
+ }));
439
+ },
440
+ abandon(e) {
441
+ c("abandon()") && (a = "abandoned", t("journey_abandon", {
442
+ ...r,
443
+ step_count: o,
444
+ ...s && { step_name: s },
445
+ ...e && { reason: e }
446
+ }));
447
+ }
448
+ };
449
+ }, $ = () => typeof window < "u", me = 90, he = (e) => {
259
450
  if (e.consent !== "granted" && e.consent !== "denied") throw Error(`[react-marketing-tools] createAnalytics: "consent" must be 'granted' or 'denied' (received ${JSON.stringify(e.consent)}).`);
260
- }, Z = (i) => {
261
- X(i);
262
- let { debug: a = !1, onError: s = console.error, respectGpc: c = !0 } = i, l = n({
263
- consent: i.consent,
264
- gpc: c && o()
265
- }), u = l, d, f = [
266
- ...i.gtm ? [y({
267
- ...i.gtm,
268
- nonce: i.nonce
451
+ }, ge = (a) => {
452
+ he(a);
453
+ let { debug: o = !1, onError: s = console.error, respectGpc: l = !0 } = a, u = ne({
454
+ consent: a.consent,
455
+ gpc: l && re()
456
+ }), f = u, p, m = fe({
457
+ config: a.visitorId ?? "random",
458
+ onError: s
459
+ }), h = () => {}, g = new Promise((e) => {
460
+ h = e;
461
+ }), _ = [
462
+ ...a.gtm ? [F({
463
+ ...a.gtm,
464
+ nonce: a.nonce
465
+ })] : [],
466
+ ...a.ga4 ? [ae({
467
+ ...a.ga4,
468
+ nonce: a.nonce
269
469
  })] : [],
270
- ...i.ga4 ? [g({
271
- ...i.ga4,
272
- nonce: i.nonce
470
+ ...a.metaPixel ? [oe({
471
+ ...a.metaPixel,
472
+ nonce: a.nonce
273
473
  })] : [],
274
- ...i.metaPixel ? [M({
275
- ...i.metaPixel,
276
- nonce: i.nonce
474
+ ...a.server ? [ce({
475
+ ...a.server,
476
+ relayPageViews: !a.metaPixel || a.metaPixel.pageViews === "manual",
477
+ visitorId: () => m?.peek(f),
478
+ onError: s
277
479
  })] : [],
278
- ...i.destinations ?? []
279
- ], p = [], m = !1, h = (e) => {
280
- if (a) throw e;
480
+ ...a.destinations ?? []
481
+ ], v = [], y = !1, C = a.attribution === !1 ? void 0 : ee({ ttlDays: typeof a.attribution == "object" && a.attribution.ttlDays || me }), w = !1, T = () => {
482
+ w || (w = !0, C?.observe(c({
483
+ url: location.href,
484
+ referrer: document.referrer,
485
+ capturedAt: Date.now()
486
+ })));
487
+ }, E = () => y && f.analytics === "granted", D = () => {
488
+ y && a.server && m?.get(f);
489
+ }, O = (e) => {
490
+ if (o) throw e;
281
491
  s(e);
282
- }, _ = (e) => {
283
- for (let t of f) try {
492
+ }, k = (e) => {
493
+ for (let t of _) try {
284
494
  e(t);
285
495
  } catch (e) {
286
- s(new N("destination_failed", `destination "${t.name}" failed`, { cause: e }));
496
+ s(new J("destination_failed", `destination "${t.name}" failed`, { cause: e }));
287
497
  }
288
- }, v = (e) => {
289
- m ? _(e) : p.push(e);
290
- }, b = ({ name: e, params: t, options: n }) => {
291
- let r = U(e);
292
- if (r) {
293
- h(new N("invalid_event", r));
498
+ }, A = (e) => {
499
+ y ? k(e) : v.push(e);
500
+ }, j = ({ name: n, params: i, options: a }) => {
501
+ let o = r(n);
502
+ if (o) {
503
+ O(new J("invalid_event", o));
294
504
  return;
295
505
  }
296
- for (let n of W(t)) h(new N("invalid_param", `event "${e}" ${n}`));
297
- let i = q(t), a = n?.meta?.params && q(n.meta.params), o = [...i.redactedKeys, ...a?.redactedKeys.map((e) => `meta.${e}`) ?? []];
298
- return o.length > 0 && h(new N("pii_redacted", `event "${e}": personal data redacted from ${o.join(", ")}`)), {
299
- name: e,
300
- params: i.params,
301
- ...n && { options: a ? {
302
- ...n,
506
+ for (let e of t(i)) O(new J("invalid_param", `event "${n}" ${e}`));
507
+ let s = e(i), c = a?.meta || void 0, l = c?.params && e(c.params), u = [...s.redactedKeys, ...l?.redactedKeys.map((e) => `meta.${e}`) ?? []];
508
+ u.length > 0 && O(new J("pii_redacted", `event "${n}": personal data redacted from ${u.join(", ")}`)), T();
509
+ let d = C?.get().lastTouch;
510
+ return {
511
+ name: n,
512
+ params: s.params,
513
+ ...d && { attribution: d },
514
+ ...a && { options: l ? {
515
+ ...a,
303
516
  meta: {
304
- ...n.meta,
305
- params: a.params
517
+ ...c,
518
+ params: l.params
306
519
  }
307
- } : n },
520
+ } : a },
308
521
  eventId: Y(),
309
522
  timestamp: Date.now()
310
523
  };
524
+ }, M = (e, t = {}, n) => {
525
+ if (!$()) return;
526
+ let r = j({
527
+ name: e,
528
+ params: t,
529
+ options: n
530
+ });
531
+ r && A((e) => e.track(r));
311
532
  };
312
533
  return {
313
534
  start() {
314
- !m && J() && (m = !0, _((e) => e.start({
315
- consent: l,
316
- identity: d
317
- })), p.splice(0).forEach(_));
318
- },
319
- track(e, t = {}, n) {
320
- if (!J()) return;
321
- let r = b({
322
- name: e,
323
- params: t,
324
- options: n
325
- });
326
- r && v((e) => e.track(r));
535
+ !y && $() && (y = !0, T(), E() && (C?.restore(), C?.persist()), D(), k((e) => e.start({
536
+ consent: u,
537
+ identity: p
538
+ })), v.splice(0).forEach(k), a.autocapture?.clicks && b(M), h());
327
539
  },
540
+ track: M,
541
+ journey: (e) => pe({
542
+ name: e,
543
+ track: M,
544
+ fail: O
545
+ }),
328
546
  page(e = {}) {
329
- if (!J()) return;
330
- let t = b({
547
+ if (!$()) return;
548
+ T(), C?.observe(c({
549
+ url: location.href,
550
+ capturedAt: Date.now()
551
+ })), E() && C?.persist();
552
+ let t = j({
331
553
  name: "page_view",
332
554
  params: {
333
555
  page_location: location.href,
@@ -335,37 +557,55 @@ var e = [
335
557
  ...e
336
558
  }
337
559
  });
338
- t && v((e) => e.page ? e.page(t) : e.track(t));
560
+ t && A((e) => e.page ? e.page(t) : e.track(t));
339
561
  },
340
562
  identify(e, t = {}) {
341
- if (!J()) return;
342
- if (!e || G(e)) {
343
- h(new N("invalid_user_id", "identify() needs a non-empty user id that is not personal data such as an email address"));
563
+ if (!$()) return;
564
+ if (!e || n(e)) {
565
+ O(new J("invalid_user_id", "identify() needs a non-empty user id that is not personal data such as an email address"));
344
566
  return;
345
567
  }
346
- let n = {
568
+ let r = {
347
569
  userId: e,
348
570
  traits: t
349
571
  };
350
- d = n, v((e) => e.identify?.(n));
572
+ p = r, A((e) => e.identify?.(r));
351
573
  },
352
574
  reset() {
353
- J() && (d = void 0, v((e) => e.reset?.()));
575
+ $() && (p = void 0, A((e) => e.reset?.()));
354
576
  },
355
577
  consent: {
356
- update(n) {
357
- if (!J()) return;
358
- let i = Object.entries(n).filter(([n, r]) => r !== void 0 && !(e.includes(n) && t(r)));
359
- if (i.length > 0) {
360
- h(new N("invalid_consent", `consent.update() ignored: ${i.map(([e, t]) => `${e}=${JSON.stringify(t)}`).join(", ")}. Use analytics, ads, adUserData or adPersonalization with 'granted' or 'denied'.`));
578
+ update(e) {
579
+ if (!$()) return;
580
+ let t = Object.entries(e).filter(([e, t]) => t !== void 0 && !(x.includes(e) && te(t)));
581
+ if (t.length > 0) {
582
+ O(new J("invalid_consent", `consent.update() ignored: ${t.map(([e, t]) => `${e}=${JSON.stringify(t)}`).join(", ")}. Use analytics, ads, adUserData or adPersonalization with 'granted' or 'denied'.`));
361
583
  return;
362
584
  }
363
- let a = r(u, n);
364
- u = a, v((e) => e.consent?.(a));
585
+ let n = f, r = S(f, e);
586
+ f = r, n.analytics === "granted" && r.analytics === "denied" ? (C?.erase(), m?.erase()) : E() && (C?.restore(), C?.persist()), D(), A((e) => e.consent?.(r));
365
587
  },
366
- get: () => u
588
+ get: () => f
589
+ },
590
+ getAttribution() {
591
+ if (!$()) return {};
592
+ T();
593
+ let e = C?.get() ?? {};
594
+ if (f.adUserData !== "granted") return e;
595
+ let t = i(document.cookie, "_fbp"), n = d({
596
+ fbcCookie: i(document.cookie, "_fbc"),
597
+ touch: e.lastTouch
598
+ });
599
+ return {
600
+ ...e,
601
+ ...n && { fbc: n },
602
+ ...t && { fbp: t }
603
+ };
604
+ },
605
+ getVisitorId() {
606
+ return !$() || !m ? Promise.resolve(void 0) : g.then(() => m.get(f));
367
607
  }
368
608
  };
369
609
  };
370
610
  //#endregion
371
- export { N as n, Z as t };
611
+ export { J as n, ge as t };