@epigraph/epigraph-std-lib 4.6.0 → 4.7.0-alpha

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,282 +1,433 @@
1
- const d = Symbol("data"), u = Symbol("next"), v = class y {
2
- constructor(e) {
3
- this[d] = e, this[u] = null;
1
+ var c = /* @__PURE__ */ ((n) => (n.UNAVAILABLE = "unavailable", n.AVAILABLE = "available", n.RESTRICTED = "restricted", n))(c || {});
2
+ const g = Symbol("data"), d = Symbol("next"), P = class v {
3
+ constructor(t) {
4
+ this[g] = t, this[d] = null;
4
5
  }
5
6
  get data() {
6
- return this[d];
7
+ return this[g];
7
8
  }
8
- set next(e) {
9
- if (!(e instanceof y) && e !== null)
9
+ set next(t) {
10
+ if (!(t instanceof v) && t !== null)
10
11
  throw new Error(
11
12
  "This node is not an instance of the custom class 'Node'."
12
13
  );
13
- this[u] = e;
14
+ this[d] = t;
14
15
  }
15
16
  get next() {
16
- return this[u];
17
+ return this[d];
17
18
  }
18
19
  };
19
- let g = v;
20
- const h = Symbol("head");
21
- class m {
20
+ let E = P;
21
+ const p = Symbol("head");
22
+ class O {
22
23
  constructor() {
23
- this[h] = null;
24
+ this[p] = null;
24
25
  }
25
- set head(e) {
26
- this[h] = e;
26
+ set head(t) {
27
+ this[p] = t;
27
28
  }
28
29
  get head() {
29
- return this[h];
30
- }
31
- addToTail(e) {
32
- let t = this.head;
33
- if (t) {
34
- for (; t.next !== null; )
35
- t = t?.next;
36
- return t.next = new g(e);
30
+ return this[p];
31
+ }
32
+ addToTail(t) {
33
+ let e = this.head;
34
+ if (e) {
35
+ for (; e.next !== null; )
36
+ e = e?.next;
37
+ return e.next = new E(t);
37
38
  }
38
- return this.head = new g(e);
39
+ return this.head = new E(t);
39
40
  }
40
41
  removeHead() {
41
- const e = this.head;
42
- if (e)
43
- return this.head = e.next, e.data;
42
+ const t = this.head;
43
+ if (t)
44
+ return this.head = t.next, t.data;
44
45
  }
45
46
  }
46
- const f = Symbol("queue"), o = Symbol("size");
47
- class l {
47
+ const m = Symbol("queue"), _ = Symbol("size");
48
+ class N {
48
49
  constructor() {
49
- this[f] = new m(), this[o] = 0;
50
+ this[m] = new O(), this[_] = 0;
50
51
  }
51
52
  get queue() {
52
- return this[f];
53
+ return this[m];
53
54
  }
54
55
  get size() {
55
- return this[o];
56
+ return this[_];
56
57
  }
57
- enqueue(e) {
58
- this.queue.addToTail(e), this[o]++;
58
+ enqueue(t) {
59
+ this.queue.addToTail(t), this[_]++;
59
60
  }
60
61
  dequeue() {
61
- const e = this.queue.removeHead();
62
- return this[o]--, e;
62
+ const t = this.queue.removeHead();
63
+ return this[_]--, t;
63
64
  }
64
65
  }
65
- class L {
66
- constructor(e, t, n, s) {
67
- this.name = this.pluginName = "GA3-PLUGIN", this.trackingID = e, this.verboseLogging = t, this.user = n, this.trackerName = s, this.queue = new l(), this.trackerInterval = 0, this.trackerCreated = !1;
66
+ class u {
67
+ static {
68
+ this.NOTIFICATION_NAME = "epg-notification";
69
+ }
70
+ static {
71
+ this.ACTION_SEND_EVENT = "send-event";
72
+ }
73
+ static {
74
+ this.ACTION_INITIALIZED = "initialized";
75
+ }
76
+ static {
77
+ this.ACTION_FAILED_INITIALIZATION = "initialization-failed";
78
+ }
79
+ constructor(t, e, i, s, r, o) {
80
+ this._pluginName = t, this._trackingId = e, this._experienceId = i, this._solution = s, this._initializer = r, this._status = o;
81
+ }
82
+ updateStatus(t) {
83
+ this._status = t;
84
+ }
85
+ updateInitializer(t) {
86
+ this._initializer = t;
87
+ }
88
+ notify(t, e) {
89
+ console.log("Notifying", t, e);
90
+ const i = {
91
+ pluginName: this._pluginName,
92
+ trackingId: this._trackingId,
93
+ experienceId: this._experienceId,
94
+ solution: this._solution,
95
+ initializer: this._initializer,
96
+ status: this._status,
97
+ action: t,
98
+ eventDetails: e
99
+ };
100
+ window.dispatchEvent(new CustomEvent("epg-notification", { detail: i }));
101
+ }
102
+ }
103
+ class S {
104
+ constructor({
105
+ trackingID: t,
106
+ experienceID: e,
107
+ solution: i,
108
+ verboseLogging: s = !1
109
+ }) {
110
+ this.__status = c.UNAVAILABLE, this.__sentEventCount = 0, this.__initializationAttempts = 0, this.__lastInitializationAttempt = performance.now(), this.__maxInitializationAttempts = 10, this.__initializationRetryDelay = 2e3, this.__isInitialized = !1, this.__initializationMethod = "NONE", this.__nexusFailureReported = !1, this.name = this.pluginName = "GA4-PLUGIN", this.trackingID = t, this.experienceID = e, this.solution = i, this.verboseLogging = s, this.__queue = new N(), this.__epigraphNotifier = new u(
111
+ this.pluginName,
112
+ this.pluginName,
113
+ this.experienceID,
114
+ this.solution,
115
+ this.__initializationMethod,
116
+ this.__status
117
+ ), this.initializePlugin();
118
+ }
119
+ getStatus() {
120
+ return this.__status;
121
+ }
122
+ setStatus(t) {
123
+ this.__status = t, this.__epigraphNotifier.updateStatus(t);
124
+ }
125
+ getPendingEventCount() {
126
+ return this.__queue.size;
127
+ }
128
+ getSentEventCount() {
129
+ return this.__sentEventCount;
130
+ }
131
+ getTotalEventCount() {
132
+ return this.getPendingEventCount() + this.getSentEventCount();
133
+ }
134
+ /**
135
+ * Returns a unique plugin identifier so that tracking ID's can be the same across multiple plugins.
136
+ */
137
+ getUniquePluginIdentifier() {
138
+ return `${this.name}-${this.trackingID}`;
139
+ }
140
+ setupPlugin() {
141
+ this.__isInitialized && this.dataLayer !== void 0 && this.dequeueAndSendEvents();
68
142
  }
69
143
  /**
70
- * This function will send an Event to GA3.
144
+ * This function will send an Event to Google Analytics 4.
71
145
  *
72
- * @param eventData AnalyticsEvent The event to be tracked
146
+ * @param analyticsEvent
147
+ * @param consent boolean Whether consent is granted
73
148
  */
74
- sendEvent(e) {
75
- if (this.queue.enqueue(e), window.ga !== void 0 && typeof ga == "function")
76
- try {
77
- this.dequeueAndSendEvents();
78
- } catch (t) {
79
- this.logger(t);
149
+ async sendEvent(t, e) {
150
+ if (this.__queue.enqueue(t), !e) {
151
+ this.__status = c.RESTRICTED;
152
+ return;
153
+ }
154
+ if (!this.__isInitialized) {
155
+ this.logger("Cannot send analytics event: dataLayer not defined or plugin not initialized.");
156
+ return;
157
+ }
158
+ try {
159
+ await this.dequeueAndSendEvents();
160
+ } catch (i) {
161
+ this.logger(i), await this.reportFailureToNexus("EVENT_SEND_ERROR", i?.toString() || "Unknown error");
162
+ }
163
+ }
164
+ initializePlugin() {
165
+ if (this.__isInitialized)
166
+ return;
167
+ if (this.__initializationAttempts >= this.__maxInitializationAttempts) {
168
+ this.__nexusFailureReported || (this.reportFailureToNexus("MAX_INITIALIZATION_ATTEMPTS", "Maximum initialization attempts reached"), this.__nexusFailureReported = !0, this.__epigraphNotifier.notify(u.ACTION_FAILED_INITIALIZATION, {}));
169
+ return;
170
+ }
171
+ const t = performance.now();
172
+ if (this.__initializationAttempts > 0 && t - this.__lastInitializationAttempt < this.__initializationRetryDelay)
173
+ return;
174
+ this.__lastInitializationAttempt = t, this.__initializationAttempts++;
175
+ const e = this.detectAndSetupAnalytics();
176
+ e.success ? (this.__isInitialized = !0, this.__status = c.AVAILABLE, this.__initializationMethod = e.method, this.dataLayerName = e.dataLayerName, this.dataLayer = window[this.dataLayerName], this.logger(`Successfully initialized ${e.method} with dataLayer: ${this.dataLayerName}`), this.__epigraphNotifier.notify(u.ACTION_INITIALIZED, {}), this.__queue.size > 0 && this.dequeueAndSendEvents()) : (this.logger(`Initialization attempt ${this.__initializationAttempts} failed: ${e.error}`), this.__initializationAttempts < this.__maxInitializationAttempts && setTimeout(() => {
177
+ this.initializePlugin();
178
+ }, this.__initializationRetryDelay));
179
+ }
180
+ detectAndSetupAnalytics() {
181
+ const t = this.detectGTM();
182
+ if (t)
183
+ return this.logger(`GTM detected with container ID: ${t.containerId}`), this.__epigraphNotifier.updateInitializer("GTM"), {
184
+ success: !0,
185
+ method: "GTM",
186
+ dataLayerName: t.dataLayerName
187
+ };
188
+ const e = this.findGA4Info(this.trackingID);
189
+ if (e) {
190
+ const i = e.l || "dataLayer";
191
+ return this.logger(`GA4 script found, setting up with dataLayer: ${i}`), this.__epigraphNotifier.updateInitializer("GA4"), {
192
+ success: !0,
193
+ method: "GA4",
194
+ dataLayerName: i
195
+ };
196
+ }
197
+ return {
198
+ success: !1,
199
+ method: "NONE",
200
+ dataLayerName: "dataLayer",
201
+ error: "No analytics setup found and unable to create one"
202
+ };
203
+ }
204
+ detectGTM() {
205
+ const t = document.querySelectorAll('script[src*="googletagmanager.com/gtm"]');
206
+ for (const e of Array.from(t)) {
207
+ const i = e.getAttribute("src");
208
+ if (i) {
209
+ const s = i.match(/gtm\.js\?id=([^&]+)/);
210
+ if (s && s.length > 0) {
211
+ const r = i.match(/&l=([^&]+)/), o = r ? r[1] : "dataLayer";
212
+ return {
213
+ containerId: s[1],
214
+ dataLayerName: o
215
+ };
216
+ }
80
217
  }
81
- else
82
- this.logger("Cannot send Google Analytics 3 event: ga function is not defined.");
83
- return !0;
218
+ }
219
+ return null;
84
220
  }
85
221
  /**
86
222
  * Send all events that are in the queue
87
223
  * @private
88
224
  */
89
- dequeueAndSendEvents() {
90
- if (this.trackerCreated) {
91
- let e = this.queue.size;
92
- for (let t = 0; t < e; t++) {
93
- const n = this.queue.dequeue();
94
- ga(
95
- `${this.trackerName}.send`,
96
- n.type,
97
- n.category,
98
- n.action,
99
- n.label,
100
- n.interaction
101
- ), this.logger(`Google Analytics 3 event successfully sent: ${n.action}`);
225
+ async dequeueAndSendEvents() {
226
+ if (!this.__isInitialized || !this.dataLayer)
227
+ return;
228
+ let t = this.__queue.size;
229
+ for (let e = 0; e < t; e++) {
230
+ const i = this.__queue.dequeue();
231
+ try {
232
+ this.__initializationMethod === "GTM" ? (this.sendGTMEvent(i), this.__sentEventCount++, this.logger(`Analytics event successfully sent via ${this.__initializationMethod}: ${i.eventName}`)) : this.__initializationMethod === "GA4" ? (this.sendGA4Event(i), this.__sentEventCount++, this.logger(`Analytics event successfully sent via ${this.__initializationMethod}: ${i.eventName}`)) : this.__queue.enqueue(i);
233
+ } catch (s) {
234
+ this.logger(`Error sending event ${i.eventName}: ${s}`), this.__queue.enqueue(i);
102
235
  }
103
- } else
104
- this.logger("Cannot sent Google Analytics 3 event: tracker was not created.");
236
+ }
105
237
  }
106
238
  /**
107
- * GA3 requires that a tracker be created prior to being sent. This is called from the constructor. It is
108
- * important to note that the promise that is inherently returned is ignored in the constructor at this
109
- * time. This is due to the events that are added will be queued from the page. This script requires
110
- * that the GA script has been imported on the page already as it does not check for it today.
111
- *
239
+ * Send events to GTM based GA4
240
+ * @param event
112
241
  * @private
113
242
  */
114
- async createTracker() {
115
- if (window.ga !== void 0 && typeof ga == "function")
116
- try {
117
- ga("create", this.trackingID, "auto", this.trackerName, {
118
- userId: this.user
119
- });
120
- const e = new URL(window.location.href);
121
- ga(`${this.trackerName}.set`, "page", e.pathname), ga(`${this.trackerName}.set`, "location", e.href), this.trackerCreated = !0, this.logger("Google Analytics 3 tracker successfully created."), this.dequeueAndSendEvents(), window.clearInterval(this.trackerInterval);
122
- } catch (e) {
123
- this.logger(e);
124
- }
125
- else
126
- this.logger("Error: Cannot create tracker, ga function is not defined.");
243
+ async sendGTMEvent(t) {
244
+ let e = t.getGTMParameters(this.solution, this.experienceID, this.trackingID);
245
+ const i = e;
246
+ this.isValidPayload(e) || (e = await this.convertGTMParametersToEpgEventTag(t.eventName, e)), this.dataLayer && (this.dataLayer.push(e), this.__epigraphNotifier.notify(u.ACTION_SEND_EVENT, i));
127
247
  }
128
248
  /**
129
- * Checks if verboseLogging is enabled, then logs the error
130
- * @param err
249
+ * Send events to GA4 via Google Analytics 4.
250
+ * @param event
251
+ * @private
131
252
  */
132
- logger(e) {
133
- this.verboseLogging && console.warn(e);
253
+ async sendGA4Event(t) {
254
+ let e = t.getGa4Parameters(this.solution, this.experienceID, this.trackingID);
255
+ const i = e;
256
+ this.isValidPayload(e) || (e = await this.convertGA4ParametersToEpgEventTag(e)), window.gtag("event", t.eventName, e), this.__epigraphNotifier.notify(u.ACTION_SEND_EVENT, i);
134
257
  }
135
258
  /**
136
- * Returns a unique plugin identifier so that tracking ID's can be the same across multiple plugins.
259
+ * Validates a payload by checking its parameter count and the constraints of parameter names and values.
260
+ * See docs here for requirements: https://support.google.com/analytics/answer/9267744?hl=en
261
+ *
262
+ * @param {Record<string, unknown>} parameterPayload - An object containing the parameters to validate.
263
+ * The keys represent parameter names and the values represent parameter values.
264
+ * @return {boolean} Returns true if the payload meets the validation criteria; false otherwise.
137
265
  */
138
- getUniquePluginIdentifier() {
139
- return this.pluginName + "-" + this.trackingID;
140
- }
141
- setupPlugin() {
142
- var e = 0;
143
- this.trackerInterval = window.setInterval(() => {
144
- this.createTracker(), ++e === 10 && (window.clearInterval(this.trackerInterval), this.logger("Error: Failed to create Google Analytics tracker in the allotted timeframe."));
145
- }, 1e3);
146
- }
147
- }
148
- class I {
149
- constructor(e, t) {
150
- this.name = this.pluginName = "GA4-PLUGIN", this.trackingID = e, this.verboseLogging = t, this.queue = new l(), this.dataLayer = window.dataLayer, this.dataLayerName = "dataLayer", this.setupDataLayer(), this.initGtag(this.dataLayerName, this.trackingID);
151
- }
152
- setupDataLayer() {
153
- if (this.dataLayer) return;
154
- const t = this.findGA4ScriptInfo(this.trackingID)?.l;
155
- t && (this.dataLayerName = t, this.dataLayer = window[t]);
156
- }
157
- initGtag(e = "dataLayer", t) {
158
- window.epgDataLayerName = e, typeof window.gtag != "function" && (window.gtag = function() {
159
- window[window.epgDataLayerName].push(arguments);
160
- }, window.gtag("js", /* @__PURE__ */ new Date()), window.gtag("config", t, { send_page_view: !1 }));
266
+ isValidPayload(t) {
267
+ if (Object.keys(t).length >= 25)
268
+ return !1;
269
+ for (const [s, r] of Object.entries(t))
270
+ if (s !== "items" && (s.length > 40 || String(r).length > 100))
271
+ return !1;
272
+ return !0;
161
273
  }
162
274
  /**
163
- * This function will send an Event to GA3.
275
+ * Converts the given GTM parameters to an EPG event tag, sending specific parameter payloads
276
+ * for processing and returning the formatted result. Falls back to the original payload in case of errors.
164
277
  *
165
- * @param eventData AnalyticsEvent The event to be tracked
166
- * @param consentPlugin
278
+ * @param {string} eventName - The event name associated with the EPG event tag being processed.
279
+ * @param {Record<string, unknown>} parameterPayload - A key-value pair object containing the parameters to be converted.
280
+ * @return {Promise<Record<string, unknown>>} A promise that resolves to an object containing the event name and the generated EPG event tag, or the original payload upon failure.
167
281
  */
168
- async sendEvent(e, t) {
169
- this.queue.enqueue(e);
170
- let n = !0;
171
- if (t && (n = t.hasConsent()), this.dataLayer !== void 0 && n)
172
- try {
173
- await this.dequeueAndSendEvents();
174
- } catch (s) {
175
- this.logger(s);
176
- }
177
- else
178
- this.logger("Cannot send Google Analytics 4 event: dataLayer is not defined.");
282
+ async convertGTMParametersToEpgEventTag(t, e) {
283
+ try {
284
+ let i = await this.sendGA4LongParameters(e);
285
+ return {
286
+ event: t,
287
+ epg_event_tag: i,
288
+ send_to: this.trackingID
289
+ };
290
+ } catch {
291
+ return e;
292
+ }
179
293
  }
180
294
  /**
181
- * Send all events that are in the queue
182
- * @private
295
+ * Converts GA4 parameters into an EPG event tag.
296
+ *
297
+ * @param {Record<string, unknown>} parameterPayload - The GA4 parameters to be converted.
298
+ * @return {Promise<Record<string, any>>} A promise resolving to an object containing the EPG event tag or the original payload if the conversion fails.
183
299
  */
184
- async dequeueAndSendEvents() {
185
- let e = this.queue.size;
186
- for (let t = 0; t < e; t++) {
187
- const n = this.queue.dequeue();
188
- let s = {
189
- send_to: this.trackingID,
190
- event_action: n.action,
191
- event_category: n.category,
192
- event_label: n.label,
193
- epg_event_tag: ""
300
+ async convertGA4ParametersToEpgEventTag(t) {
301
+ try {
302
+ return {
303
+ epg_event_tag: await this.sendGA4LongParameters(t),
304
+ send_to: this.trackingID
194
305
  };
195
- if ("parameters" in n && Object.assign(s, n.parameters), JSON.stringify(s).length > 459)
196
- try {
197
- let r = await this.sendGA4LongParameters(s);
198
- s = {
199
- send_to: this.trackingID,
200
- event_action: n.action,
201
- event_category: n.category,
202
- event_label: n.label,
203
- epg_event_tag: r
204
- };
205
- } catch {
206
- }
207
- gtag("event", n.action, s), this.logger(`Google Analytics 4 event successfully sent: ${n.action}`);
306
+ } catch {
307
+ return t;
208
308
  }
209
309
  }
210
310
  /**
211
311
  * Checks if verboseLogging is enabled, then logs the error
212
312
  * @param err
213
313
  */
214
- logger(e) {
215
- this.verboseLogging && console.warn(e);
216
- }
217
- /**
218
- * Returns a unique plugin identifier so that tracking ID's can be the same across multiple plugins.
219
- */
220
- getUniquePluginIdentifier() {
221
- return this.name + "-" + this.trackingID;
314
+ logger(t) {
315
+ this.verboseLogging && console.warn(t);
222
316
  }
223
- setupPlugin() {
224
- this.dataLayer !== void 0 && this.dequeueAndSendEvents();
225
- }
226
- async sendGA4LongParameters(e) {
227
- const t = "https://api.myepigraph.com/api/analytics/ga4/custom", n = {
228
- parameters: e
229
- };
317
+ async sendGA4LongParameters(t) {
318
+ const e = "https://api.myepigraph.com/api/analytics/ga4/custom", i = { parameters: t };
230
319
  try {
231
- const s = await fetch(t, {
320
+ const s = await fetch(e, {
232
321
  method: "POST",
233
322
  // Assuming it's a POST request, adjust if necessary
234
323
  headers: {
235
324
  "Content-Type": "application/json",
236
325
  Accept: "application/json"
237
326
  },
238
- body: JSON.stringify(n)
327
+ body: JSON.stringify(i)
239
328
  });
240
- if (s.ok) {
241
- const a = await s.json();
242
- return a && a.id ? a.id : "";
243
- } else
244
- return "";
329
+ return s.ok ? (await s.json())?.id ?? "" : "";
245
330
  } catch {
246
331
  return "";
247
332
  }
248
333
  }
249
- findGA4ScriptInfo(e) {
250
- const t = document.querySelectorAll("script[src]");
251
- for (const n of t) {
252
- const s = n.getAttribute("src");
253
- if (s && s.includes(e)) {
254
- const a = new URL(s, location.href), r = Object.fromEntries(a.searchParams.entries());
334
+ async reportFailureToNexus(t, e) {
335
+ try {
336
+ const i = {
337
+ plugin: "GA4",
338
+ trackingId: this.trackingID,
339
+ solution: this.solution,
340
+ experienceId: this.experienceID,
341
+ failureType: t,
342
+ errorMessage: e,
343
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
344
+ url: window.location.href,
345
+ userAgent: navigator.userAgent
346
+ };
347
+ this.logger(`Failure reported to Nexus: ${JSON.stringify(i)}`);
348
+ } catch (i) {
349
+ this.logger(`Error reporting failure to Nexus: ${i}`);
350
+ }
351
+ }
352
+ findGA4Info(t) {
353
+ if (window.google_tag_manager && window.google_tag_manager[t]) {
354
+ const i = window.google_tag_manager[t];
355
+ if (i && i.dataLayerName)
255
356
  return {
256
- fullSrc: a.href,
257
- id: r.id || void 0,
258
- l: r.l || void 0
357
+ fullSrc: "",
358
+ id: t,
359
+ l: i.dataLayerName
360
+ };
361
+ }
362
+ const e = document.querySelectorAll("script[src]");
363
+ for (const i of e) {
364
+ const s = i.getAttribute("src");
365
+ if (s && s.includes(t)) {
366
+ const r = new URL(s, location.href), o = Object.fromEntries(r.searchParams.entries());
367
+ return {
368
+ fullSrc: r.href,
369
+ id: o.id || void 0,
370
+ l: o.l || void 0
259
371
  };
260
372
  }
261
373
  }
262
374
  return null;
263
375
  }
264
376
  }
265
- class A {
266
- constructor(e, t, n, s, a = !1) {
267
- this.sessionId = t, this.xPath = n, this.name = this.pluginName = "NEXUS-PLUGIN", this.trackingID = e, this.verboseLogging = s, this.queue = new l(), this.url = a ? "https://nexus.epigraph.dev/api/analytics/event" : "https://api.myepigraph.com/api/analytics/event";
377
+ class L {
378
+ constructor({
379
+ trackingID: t,
380
+ experienceID: e,
381
+ solution: i,
382
+ sessionId: s,
383
+ xPath: r,
384
+ verboseLogging: o = !1,
385
+ sendToStaging: y = !1
386
+ }) {
387
+ this.__status = c.UNAVAILABLE, this.__sentEventCount = 0, this.sessionId = s, this.xPath = r, this.name = this.pluginName = "NEXUS-PLUGIN", this.trackingID = t, this.experienceID = e, this.solution = i, this.verboseLogging = o, this.__queue = new N(), this.url = y ? "https://nexus.epigraph.dev/api/analytics/event" : "https://api.myepigraph.com/api/analytics/event", this.__status = c.AVAILABLE, this.__epigraphNotifier = new u(
388
+ this.pluginName,
389
+ this.trackingID,
390
+ this.experienceID,
391
+ this.solution,
392
+ "NEXUS",
393
+ this.__status
394
+ ), this.__epigraphNotifier.notify(u.ACTION_INITIALIZED, {});
395
+ }
396
+ getStatus() {
397
+ return this.__status;
398
+ }
399
+ setStatus(t) {
400
+ this.__status = t, this.__epigraphNotifier.updateStatus(t);
401
+ }
402
+ getPendingEventCount() {
403
+ return this.__queue.size;
404
+ }
405
+ getSentEventCount() {
406
+ return this.__sentEventCount;
407
+ }
408
+ getTotalEventCount() {
409
+ return this.getPendingEventCount() + this.getSentEventCount();
268
410
  }
269
- async sendEvent(e, t) {
270
- this.queue.enqueue(e);
271
- let n = !0;
272
- t && (n = t.hasConsent()), n && await this.dequeueAndSendEvents();
411
+ getUniquePluginIdentifier() {
412
+ return this.name + "-" + this.trackingID;
413
+ }
414
+ setupPlugin() {
415
+ }
416
+ async sendEvent(t, e) {
417
+ if (this.__queue.enqueue(t), !e) {
418
+ this.__status = c.RESTRICTED, this.__epigraphNotifier.updateStatus(this.__status);
419
+ return;
420
+ }
421
+ await this.dequeueAndSendEvents();
273
422
  }
274
423
  async dequeueAndSendEvents() {
275
- for (let e = 0; e < this.queue.size; e++) {
276
- const t = this.queue.dequeue(), n = {
277
- experience_id: this.trackingID,
278
- action: t.action,
279
- parameters: t.parameters
424
+ for (let t = 0; t < this.__queue.size; t++) {
425
+ const e = this.__queue.dequeue(), i = {
426
+ send_to: this.trackingID,
427
+ experience_id: this.experienceID,
428
+ solution: this.solution,
429
+ event: e.eventName,
430
+ parameters: e.getNexusParameters()
280
431
  };
281
432
  try {
282
433
  return (await fetch(this.url, {
@@ -289,23 +440,19 @@ class A {
289
440
  "EPG-XPATH": this.xPath,
290
441
  Origin: typeof window < "u" ? window.location.origin : ""
291
442
  },
292
- body: JSON.stringify(n)
293
- })).status === 204, "";
443
+ body: JSON.stringify(i)
444
+ })).ok && this.__epigraphNotifier.notify(u.ACTION_SEND_EVENT, i), "";
294
445
  } catch {
295
446
  return "";
296
447
  }
448
+ this.__sentEventCount++;
297
449
  }
298
450
  return "";
299
451
  }
300
- getUniquePluginIdentifier() {
301
- return this.name + "-" + this.trackingID;
302
- }
303
- setupPlugin() {
304
- }
305
452
  }
306
- class q {
307
- constructor(e) {
308
- this.consentSet = !1, this.consent = !1, this.pluginName = "OneTrustConsentPlugin", this.consentIdentifier = e, this.consent = !1, this.addConsentChangedListener();
453
+ class C {
454
+ constructor(t) {
455
+ this.consentSet = !1, this.consent = !1, this.pluginName = "OneTrustConsentPlugin", this.consentIdentifier = t, this.consent = !1, this.addConsentChangedListener();
309
456
  }
310
457
  /**
311
458
  * Checks to see if the user has consented. If this is false, it will block all analytics
@@ -314,9 +461,9 @@ class q {
314
461
  if (this.consentSet)
315
462
  return this.consent;
316
463
  if (window.OnetrustActiveGroups !== void 0) {
317
- let e = window.OnetrustActiveGroups;
318
- e !== void 0 && e.split(",").forEach((n) => {
319
- n === this.consentIdentifier && (this.consent = !0, this.consentSet = !0);
464
+ let t = window.OnetrustActiveGroups;
465
+ t !== void 0 && t.split(",").forEach((i) => {
466
+ i === this.consentIdentifier && (this.consent = !0, this.consentSet = !0);
320
467
  });
321
468
  }
322
469
  return this.consent;
@@ -329,7 +476,406 @@ class q {
329
476
  });
330
477
  }
331
478
  }
332
- var p = /* @__PURE__ */ ((i) => (i.OneTrust = "onetrust", i))(p || {});
479
+ var f = /* @__PURE__ */ ((n) => (n.OneTrust = "onetrust", n))(f || {});
480
+ class a {
481
+ constructor({
482
+ eventName: t,
483
+ interactiveEvent: e,
484
+ customParameters: i
485
+ }) {
486
+ this.eventName = t, this.interactiveEvent = e, this.customParameters = i;
487
+ }
488
+ getGa4Parameters(t, e, i) {
489
+ let s = {
490
+ solution: t,
491
+ experience_id: e,
492
+ interactive_event: this.interactiveEvent,
493
+ send_to: i
494
+ };
495
+ return s = Object.assign(s, JSON.parse(JSON.stringify(this.customParameters))), s;
496
+ }
497
+ getGTMParameters(t, e, i) {
498
+ let s = {
499
+ solution: t,
500
+ experience_id: e,
501
+ event: this.eventName,
502
+ interactive_event: this.interactiveEvent,
503
+ send_to: i
504
+ };
505
+ return s = Object.assign(s, JSON.parse(JSON.stringify(this.customParameters))), s;
506
+ }
507
+ getNexusParameters() {
508
+ let t = {
509
+ interactive_event: this.interactiveEvent
510
+ };
511
+ return t = Object.assign(t, JSON.parse(JSON.stringify(this.customParameters))), t;
512
+ }
513
+ }
514
+ const I = {
515
+ AR: "ar",
516
+ QR: "qr",
517
+ INFO: "info",
518
+ DOWNLOAD: "download",
519
+ PREVIEW_CART: "preview_cart",
520
+ HOTSPOT_PANEL: "hotspot_panel",
521
+ SHARE_MODAL: "share_modal",
522
+ RESTART_MODAL: "restart_modal",
523
+ REMOVE_MODAL: "remove_modal",
524
+ LOAD_PRECONFIG_MODAL: "load_preconfig_modal",
525
+ MOVE_MODAL: "move_modal",
526
+ OUT_OF_STOCK_MODAL: "out_of_stock_modal"
527
+ }, T = {
528
+ AUTO: "auto",
529
+ BUTTON: "button",
530
+ HOTSPOT: "hotspot",
531
+ GESTURE: "gesture"
532
+ }, l = {
533
+ USD: "USD",
534
+ EUR: "EUR",
535
+ GBP: "GBP",
536
+ CAD: "CAD"
537
+ };
538
+ class w extends a {
539
+ constructor(t) {
540
+ super({
541
+ eventName: "epigraph_ar_requested",
542
+ interactiveEvent: !0,
543
+ customParameters: {
544
+ items: t
545
+ }
546
+ });
547
+ }
548
+ }
549
+ class R extends a {
550
+ constructor(t) {
551
+ super({
552
+ eventName: "epigraph_module_loading",
553
+ interactiveEvent: !1,
554
+ customParameters: {
555
+ is_pre_config: t
556
+ }
557
+ });
558
+ }
559
+ }
560
+ class x extends a {
561
+ constructor(t, e) {
562
+ super({
563
+ eventName: "epigraph_module_ready",
564
+ interactiveEvent: !1,
565
+ customParameters: {
566
+ is_pre_config: t,
567
+ load_time_ms: e
568
+ }
569
+ });
570
+ }
571
+ }
572
+ class D extends a {
573
+ constructor(t, e, i) {
574
+ super({
575
+ eventName: "epigraph_module_failed",
576
+ interactiveEvent: !1,
577
+ customParameters: {
578
+ is_pre_config: t,
579
+ load_time_ms: e,
580
+ error_type: i
581
+ }
582
+ });
583
+ }
584
+ }
585
+ class z extends a {
586
+ constructor(t) {
587
+ super({
588
+ eventName: "epigraph_module_closed",
589
+ interactiveEvent: !0,
590
+ customParameters: {
591
+ items: t
592
+ }
593
+ });
594
+ }
595
+ }
596
+ class G extends a {
597
+ static {
598
+ this.SUPPORT_TYPE = {
599
+ AR: "ar",
600
+ QR: "qr",
601
+ WEBGL2: "webgl2"
602
+ };
603
+ }
604
+ constructor(t, e = {}) {
605
+ super({
606
+ eventName: "epigraph_support_detected",
607
+ interactiveEvent: !1,
608
+ customParameters: {
609
+ support_type: t,
610
+ device_capabilities: e
611
+ }
612
+ });
613
+ }
614
+ }
615
+ class M extends a {
616
+ static {
617
+ this.BUTTON_TYPE = {
618
+ AR_VIEW: "ar_view",
619
+ DIMENSION_SHOW: "dimension_show",
620
+ DIMENSION_HIDE: "dimension_hide",
621
+ HOTSPOTS_SHOW: "hotspots_show",
622
+ HOTSPOTS_HIDE: "hotspots_hide",
623
+ HELP_SHOW: "help_show",
624
+ HELP_HIDE: "help_hide",
625
+ HOTSPOT_ENTER: "hotspot_enter",
626
+ HOTSPOT_EXIT: "hotspot_exit",
627
+ SHARE: "share",
628
+ PDF_DOWNLOAD: "pdf_download",
629
+ COPY: "copy",
630
+ RESTART: "restart",
631
+ INSTRUCTIONS_SHOW: "show_instructions",
632
+ REVIEW_CART: "review_cart",
633
+ // Need these?
634
+ SHOP_NOW: "shop_now",
635
+ SUB_CATEGORY: "sub_category",
636
+ NEXT_STEP: "next_step",
637
+ PREVIOUS_STEP: "previous_step"
638
+ };
639
+ }
640
+ constructor(t, e) {
641
+ super({
642
+ eventName: "epigraph_button_click",
643
+ interactiveEvent: !0,
644
+ customParameters: {
645
+ button_type: t,
646
+ button_name: e
647
+ }
648
+ });
649
+ }
650
+ }
651
+ class q extends a {
652
+ static {
653
+ this.PANEL_TYPE = I;
654
+ }
655
+ static {
656
+ this.TRIGGER_SOURCE = T;
657
+ }
658
+ constructor(t, e, i, s) {
659
+ super({
660
+ eventName: "epigraph_panel_opened",
661
+ interactiveEvent: t,
662
+ customParameters: {
663
+ items: s,
664
+ panel_type: e,
665
+ trigger_source: i
666
+ }
667
+ });
668
+ }
669
+ }
670
+ class b extends a {
671
+ static {
672
+ this.PANEL_TYPE = I;
673
+ }
674
+ static {
675
+ this.TRIGGER_SOURCE = T;
676
+ }
677
+ constructor(t, e, i, s) {
678
+ super({
679
+ eventName: "epigraph_panel_closed",
680
+ interactiveEvent: t,
681
+ customParameters: {
682
+ items: s,
683
+ panel_type: e,
684
+ trigger_source: i
685
+ }
686
+ });
687
+ }
688
+ }
689
+ class U extends a {
690
+ constructor(t) {
691
+ super({
692
+ eventName: "epigraph_add_to_favourites",
693
+ interactiveEvent: !0,
694
+ customParameters: {
695
+ items: t
696
+ }
697
+ });
698
+ }
699
+ }
700
+ class k extends a {
701
+ static {
702
+ this.ACTION_PERFORMED = {
703
+ ZOOM: "zoom",
704
+ ROTATE: "rotate"
705
+ };
706
+ }
707
+ constructor(t) {
708
+ super({
709
+ eventName: "epigraph_keyboard_interaction",
710
+ interactiveEvent: !0,
711
+ customParameters: {
712
+ action_performed: t
713
+ }
714
+ });
715
+ }
716
+ }
717
+ class V extends a {
718
+ static {
719
+ this.INTERACTION_TYPE = {
720
+ ROTATE: "rotate",
721
+ ZOOM: "zoom",
722
+ PAN: "pan"
723
+ };
724
+ }
725
+ constructor(t) {
726
+ super({
727
+ eventName: "epigraph_touch_interaction",
728
+ interactiveEvent: !0,
729
+ customParameters: {
730
+ interaction_type: t
731
+ }
732
+ });
733
+ }
734
+ }
735
+ class $ extends a {
736
+ static {
737
+ this.CURRENCY = l;
738
+ }
739
+ constructor(t, e, i, s, r) {
740
+ super({
741
+ eventName: "epigraph_item_added",
742
+ interactiveEvent: t,
743
+ customParameters: {
744
+ items: r,
745
+ value: e,
746
+ currency: i,
747
+ quantity: s
748
+ }
749
+ });
750
+ }
751
+ }
752
+ class H extends a {
753
+ constructor(t) {
754
+ super({
755
+ eventName: "epigraph_item_moved",
756
+ interactiveEvent: !0,
757
+ customParameters: {
758
+ items: t
759
+ }
760
+ });
761
+ }
762
+ }
763
+ class F extends a {
764
+ static {
765
+ this.CURRENCY = l;
766
+ }
767
+ constructor(t, e, i, s) {
768
+ super({
769
+ eventName: "epigraph_item_removed",
770
+ interactiveEvent: !0,
771
+ customParameters: {
772
+ items: s,
773
+ value: t,
774
+ currency: e,
775
+ quantity: i
776
+ }
777
+ });
778
+ }
779
+ }
780
+ class B extends a {
781
+ constructor(t, e) {
782
+ super({
783
+ eventName: "epigraph_variant_changed",
784
+ interactiveEvent: !0,
785
+ customParameters: {
786
+ items: e,
787
+ change_type: t
788
+ }
789
+ });
790
+ }
791
+ }
792
+ class j extends a {
793
+ constructor(t, e, i) {
794
+ super({
795
+ eventName: "epigraph_content_shared",
796
+ interactiveEvent: !0,
797
+ customParameters: {
798
+ items: i,
799
+ content_type: t,
800
+ share_destination: e
801
+ }
802
+ });
803
+ }
804
+ }
805
+ class Y extends a {
806
+ static {
807
+ this.CURRENCY = l;
808
+ }
809
+ constructor(t, e, i) {
810
+ super({
811
+ eventName: "epigraph_checkout",
812
+ interactiveEvent: !0,
813
+ customParameters: {
814
+ items: i,
815
+ value: t,
816
+ currency: e
817
+ }
818
+ });
819
+ }
820
+ }
821
+ class W extends a {
822
+ static {
823
+ this.CURRENCY = l;
824
+ }
825
+ constructor(t, e, i) {
826
+ super({
827
+ eventName: "epigraph_conversion",
828
+ interactiveEvent: !0,
829
+ customParameters: {
830
+ items: i,
831
+ value: t,
832
+ currency: e
833
+ }
834
+ });
835
+ }
836
+ }
837
+ class J extends a {
838
+ constructor(t) {
839
+ super({
840
+ eventName: "epigraph_changeRate",
841
+ interactiveEvent: !1,
842
+ customParameters: {
843
+ value: t
844
+ }
845
+ });
846
+ }
847
+ }
848
+ class Z extends a {
849
+ constructor(t) {
850
+ super({
851
+ eventName: "epigraph_completionRate",
852
+ interactiveEvent: !1,
853
+ customParameters: {
854
+ value: t
855
+ }
856
+ });
857
+ }
858
+ }
859
+ class X extends a {
860
+ constructor(t) {
861
+ super({
862
+ eventName: "epigraph_engagementRate",
863
+ interactiveEvent: !1,
864
+ customParameters: {
865
+ value: t
866
+ }
867
+ });
868
+ }
869
+ }
870
+ class K extends a {
871
+ constructor(t, e, i) {
872
+ super({
873
+ eventName: t,
874
+ interactiveEvent: e,
875
+ customParameters: i
876
+ });
877
+ }
878
+ }
333
879
  /**
334
880
  * @license
335
881
  * Copyright (c) 2023 Epigraph LLC. All Rights Reserved.
@@ -346,12 +892,18 @@ var p = /* @__PURE__ */ ((i) => (i.OneTrust = "onetrust", i))(p || {});
346
892
  * See the License for the specific language governing permissions and
347
893
  * limitations under the License.
348
894
  */
349
- var w;
350
- const c = Symbol("analyticsPluginsMap");
351
- w = c;
352
- class S {
353
- constructor(e, t) {
354
- this[w] = /* @__PURE__ */ new Map(), this._consentPlugin = null, e && t && (this._consentPlugin = this.buildConsentPlugin(e, t));
895
+ var A;
896
+ const h = Symbol("analyticsPluginsMap");
897
+ A = h;
898
+ class Q {
899
+ constructor(t, e) {
900
+ this[A] = /* @__PURE__ */ new Map(), this.__consentPlugin = null, t && e && (this.__consentPlugin = this.buildConsentPlugin(t, e)), window.addEventListener("epigraphAnalyticsConsentChange", this.__onConsentChangeFromEvent);
901
+ }
902
+ __onConsentChangeFromEvent(t) {
903
+ let e = t;
904
+ this.__overrideConsent = e.detail.hasConsent;
905
+ for (const i of this[h].values())
906
+ this.__hasConsent() || i.setStatus(c.RESTRICTED);
355
907
  }
356
908
  /**
357
909
  * Epigraph Analytics uses plugins to send events to multiple trackers at a time. You can create a customer tracker
@@ -360,20 +912,30 @@ class S {
360
912
  *
361
913
  * @param plugin
362
914
  */
363
- addEventPlugin(e) {
364
- this[c].has(e.getUniquePluginIdentifier()) || (this[c].set(
365
- e.getUniquePluginIdentifier(),
366
- e
367
- ), e.setupPlugin());
915
+ addEventPlugin(t) {
916
+ this[h].has(t.getUniquePluginIdentifier()) || (this[h].set(
917
+ t.getUniquePluginIdentifier(),
918
+ t
919
+ ), t.setupPlugin());
920
+ }
921
+ /**
922
+ * Resolves session consent by prioritizing this._overrideConsent and if not found,
923
+ * getting the value from the consent plugin, if available.
924
+ *
925
+ * @returns {boolean} Whether the session has consent to track analytics or not.
926
+ */
927
+ __hasConsent() {
928
+ let t = !0;
929
+ return this.__overrideConsent !== void 0 ? (t = this.__overrideConsent, t) : (this.__consentPlugin && (t = this.__consentPlugin.hasConsent()), t);
368
930
  }
369
931
  /**
370
932
  * Send an Event to all plugins
371
933
  *
372
934
  * @param eventData
373
935
  */
374
- sendEvent(e) {
375
- this[c].forEach((t) => {
376
- t.sendEvent(e, this._consentPlugin);
936
+ sendEvent(t) {
937
+ this[h].forEach((e) => {
938
+ e.sendEvent(t, this.__hasConsent());
377
939
  });
378
940
  }
379
941
  /**
@@ -382,15 +944,37 @@ class S {
382
944
  * @param consentIdentifier
383
945
  * @private
384
946
  */
385
- buildConsentPlugin(e, t) {
386
- return e.toLowerCase() === p.OneTrust.toLowerCase() ? new q(t) : null;
947
+ buildConsentPlugin(t, e) {
948
+ return t.toLowerCase() === f.OneTrust.toLowerCase() ? new C(e) : null;
387
949
  }
388
950
  }
389
951
  export {
390
- p as ConsentPluginNames,
391
- S as EpigraphAnalytics,
392
- L as GA3AnalyticsPlugin,
393
- I as GA4AnalyticsPlugin,
394
- A as NexusAnalyticsPlugin,
395
- q as OneTrustConsentPlugin
952
+ f as ConsentPluginNames,
953
+ U as EpigraphAddToFavouritesEvent,
954
+ Q as EpigraphAnalytics,
955
+ w as EpigraphArRequestedEvent,
956
+ M as EpigraphButtonClickEvent,
957
+ J as EpigraphChangeRateEvent,
958
+ Y as EpigraphCheckoutEvent,
959
+ Z as EpigraphCompletionRateEvent,
960
+ j as EpigraphContentSharedEvent,
961
+ W as EpigraphConversionEvent,
962
+ K as EpigraphCustomEvent,
963
+ X as EpigraphEngagementRateEvent,
964
+ $ as EpigraphItemAddedEvent,
965
+ H as EpigraphItemMovedEvent,
966
+ F as EpigraphItemRemovedEvent,
967
+ k as EpigraphKeyboardInteractionEvent,
968
+ z as EpigraphModuleClosedEvent,
969
+ D as EpigraphModuleFailedEvent,
970
+ R as EpigraphModuleLoadingEvent,
971
+ x as EpigraphModuleReadyEvent,
972
+ b as EpigraphPanelClosedEvent,
973
+ q as EpigraphPanelOpenedEvent,
974
+ G as EpigraphSupportDetectedEvent,
975
+ V as EpigraphTouchInteractionEvent,
976
+ B as EpigraphVariantChangedEvent,
977
+ S as GA4AnalyticsPlugin,
978
+ L as NexusAnalyticsPlugin,
979
+ C as OneTrustConsentPlugin
396
980
  };