@active-reach/web-sdk 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/README.md +576 -0
  2. package/dist/aegis-sw.js +1 -0
  3. package/dist/aegis.min.js +2 -0
  4. package/dist/aegis.min.js.map +1 -0
  5. package/dist/analytics-B11keZ55.mjs +1854 -0
  6. package/dist/analytics-B11keZ55.mjs.map +1 -0
  7. package/dist/cdn.d.ts +18 -0
  8. package/dist/cdn.d.ts.map +1 -0
  9. package/dist/core/analytics.d.ts +47 -0
  10. package/dist/core/analytics.d.ts.map +1 -0
  11. package/dist/core/queue.d.ts +35 -0
  12. package/dist/core/queue.d.ts.map +1 -0
  13. package/dist/core/sdk-config-poller.d.ts +59 -0
  14. package/dist/core/sdk-config-poller.d.ts.map +1 -0
  15. package/dist/core/session.d.ts +41 -0
  16. package/dist/core/session.d.ts.map +1 -0
  17. package/dist/core/transport.d.ts +50 -0
  18. package/dist/core/transport.d.ts.map +1 -0
  19. package/dist/inapp/AegisInAppManager.d.ts +126 -0
  20. package/dist/inapp/AegisInAppManager.d.ts.map +1 -0
  21. package/dist/inapp/index.d.ts +4 -0
  22. package/dist/inapp/index.d.ts.map +1 -0
  23. package/dist/inapp/renderPreview.d.ts +25 -0
  24. package/dist/inapp/renderPreview.d.ts.map +1 -0
  25. package/dist/index.d.ts +23 -0
  26. package/dist/index.d.ts.map +1 -0
  27. package/dist/index.js +4296 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/integrations/react.d.ts +19 -0
  30. package/dist/integrations/react.d.ts.map +1 -0
  31. package/dist/placements/AegisPlacementManager.d.ts +88 -0
  32. package/dist/placements/AegisPlacementManager.d.ts.map +1 -0
  33. package/dist/plugins/registry.d.ts +13 -0
  34. package/dist/plugins/registry.d.ts.map +1 -0
  35. package/dist/push/AegisWebPush.d.ts +51 -0
  36. package/dist/push/AegisWebPush.d.ts.map +1 -0
  37. package/dist/push/AegisWebPush.js +203 -0
  38. package/dist/push/AegisWebPush.js.map +1 -0
  39. package/dist/react.js +70 -0
  40. package/dist/react.js.map +1 -0
  41. package/dist/snippet.min.js +1 -0
  42. package/dist/triggers/TriggerEngine.d.ts +114 -0
  43. package/dist/triggers/TriggerEngine.d.ts.map +1 -0
  44. package/dist/triggers/index.d.ts +3 -0
  45. package/dist/triggers/index.d.ts.map +1 -0
  46. package/dist/types/config.d.ts +73 -0
  47. package/dist/types/config.d.ts.map +1 -0
  48. package/dist/types/events.d.ts +127 -0
  49. package/dist/types/events.d.ts.map +1 -0
  50. package/dist/types/index.d.ts +5 -0
  51. package/dist/types/index.d.ts.map +1 -0
  52. package/dist/types/plugin.d.ts +21 -0
  53. package/dist/types/plugin.d.ts.map +1 -0
  54. package/dist/types/type-safe-events.d.ts +14 -0
  55. package/dist/types/type-safe-events.d.ts.map +1 -0
  56. package/dist/utils/canonical-identity.d.ts +29 -0
  57. package/dist/utils/canonical-identity.d.ts.map +1 -0
  58. package/dist/utils/consent.d.ts +40 -0
  59. package/dist/utils/consent.d.ts.map +1 -0
  60. package/dist/utils/debounce.d.ts +3 -0
  61. package/dist/utils/debounce.d.ts.map +1 -0
  62. package/dist/utils/device.d.ts +6 -0
  63. package/dist/utils/device.d.ts.map +1 -0
  64. package/dist/utils/identity.d.ts +27 -0
  65. package/dist/utils/identity.d.ts.map +1 -0
  66. package/dist/utils/index.d.ts +7 -0
  67. package/dist/utils/index.d.ts.map +1 -0
  68. package/dist/utils/logger.d.ts +15 -0
  69. package/dist/utils/logger.d.ts.map +1 -0
  70. package/dist/utils/storage.d.ts +20 -0
  71. package/dist/utils/storage.d.ts.map +1 -0
  72. package/dist/utils/url-parser.d.ts +23 -0
  73. package/dist/utils/url-parser.d.ts.map +1 -0
  74. package/dist/utils/uuid.d.ts +4 -0
  75. package/dist/utils/uuid.d.ts.map +1 -0
  76. package/dist/widgets/AegisWidgetManager.d.ts +194 -0
  77. package/dist/widgets/AegisWidgetManager.d.ts.map +1 -0
  78. package/dist/widgets/index.d.ts +3 -0
  79. package/dist/widgets/index.d.ts.map +1 -0
  80. package/package.json +73 -0
@@ -0,0 +1,1854 @@
1
+ const DEFAULT_CONFIG = {
2
+ workspace_id: null,
3
+ batch_size: 10,
4
+ batch_interval: 1e3,
5
+ capture_utm: true,
6
+ capture_referrer: true,
7
+ auto_page_view: false,
8
+ session_timeout: 30,
9
+ debug: false,
10
+ respect_dnt: true,
11
+ cross_domain_tracking: false,
12
+ secure_cookie: true,
13
+ enable_offline_mode: true,
14
+ max_offline_events: 100,
15
+ retry_failed_requests: true,
16
+ max_retries: 3,
17
+ retry_backoff_multiplier: 2,
18
+ request_timeout: 5e3,
19
+ auto_region_detection: true,
20
+ wait_for_consent: false,
21
+ enable_consent_mode: false,
22
+ integrate_onetrust: false,
23
+ integrate_cookiebot: false,
24
+ integrate_google_consent_mode: false,
25
+ default_consent: {
26
+ analytics: false,
27
+ marketing: false,
28
+ functional: true
29
+ },
30
+ initialized: false,
31
+ api_host: null,
32
+ cell_endpoints: [],
33
+ preferred_region: null,
34
+ cookie_domain: null,
35
+ plugins: [],
36
+ active_cell: null
37
+ };
38
+ function generateUUID() {
39
+ if (typeof crypto !== "undefined" && crypto.randomUUID) {
40
+ return crypto.randomUUID();
41
+ }
42
+ return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
43
+ const r = Math.random() * 16 | 0;
44
+ const v = c === "x" ? r : r & 3 | 8;
45
+ return v.toString(16);
46
+ });
47
+ }
48
+ function generateSessionId() {
49
+ return `sess_${Date.now()}_${generateUUID().slice(0, 8)}`;
50
+ }
51
+ function generateMessageId() {
52
+ return `msg_${Date.now()}_${generateUUID().slice(0, 8)}`;
53
+ }
54
+ class Logger {
55
+ constructor() {
56
+ this.enabled = false;
57
+ this.prefix = "[Aegis SDK]";
58
+ }
59
+ enable() {
60
+ this.enabled = true;
61
+ }
62
+ disable() {
63
+ this.enabled = false;
64
+ }
65
+ isEnabled() {
66
+ return this.enabled;
67
+ }
68
+ debug(message, ...args) {
69
+ if (!this.enabled) return;
70
+ console.debug(`${this.prefix} ${message}`, ...args);
71
+ }
72
+ info(message, ...args) {
73
+ if (!this.enabled) return;
74
+ console.info(`${this.prefix} ${message}`, ...args);
75
+ }
76
+ warn(message, ...args) {
77
+ console.warn(`${this.prefix} ${message}`, ...args);
78
+ }
79
+ error(message, ...args) {
80
+ console.error(`${this.prefix} ${message}`, ...args);
81
+ }
82
+ }
83
+ const logger = new Logger();
84
+ class Identity {
85
+ constructor(storage) {
86
+ this.userId = null;
87
+ this.traits = {};
88
+ this.storage = storage;
89
+ this.anonymousId = this.getOrCreateAnonymousId();
90
+ this.loadUserIdentity();
91
+ }
92
+ getOrCreateAnonymousId() {
93
+ let id = this.storage.get("anon_id");
94
+ if (!id) {
95
+ id = generateUUID();
96
+ this.storage.set("anon_id", id, 365);
97
+ logger.debug("Created new anonymous ID:", id);
98
+ } else {
99
+ logger.debug("Loaded existing anonymous ID:", id);
100
+ }
101
+ return id;
102
+ }
103
+ loadUserIdentity() {
104
+ const storedUserId = this.storage.get("user_id");
105
+ const storedTraits = this.storage.get("user_traits");
106
+ if (storedUserId) {
107
+ this.userId = storedUserId;
108
+ logger.debug("Loaded user ID:", storedUserId);
109
+ }
110
+ if (storedTraits) {
111
+ try {
112
+ this.traits = JSON.parse(storedTraits);
113
+ logger.debug("Loaded user traits:", this.traits);
114
+ } catch (error) {
115
+ logger.warn("Failed to parse stored traits:", error);
116
+ this.traits = {};
117
+ }
118
+ }
119
+ }
120
+ getAnonymousId() {
121
+ return this.anonymousId;
122
+ }
123
+ setUserId(userId, traits) {
124
+ this.userId = userId;
125
+ this.storage.set("user_id", userId, 365);
126
+ logger.info("User identified:", userId);
127
+ if (traits) {
128
+ this.setTraits(traits);
129
+ }
130
+ }
131
+ getUserId() {
132
+ return this.userId;
133
+ }
134
+ setTraits(traits) {
135
+ this.traits = { ...this.traits, ...traits };
136
+ this.storage.set("user_traits", JSON.stringify(this.traits), 365);
137
+ logger.debug("User traits updated:", this.traits);
138
+ }
139
+ getTraits() {
140
+ return { ...this.traits };
141
+ }
142
+ reset() {
143
+ this.userId = null;
144
+ this.traits = {};
145
+ this.anonymousId = generateUUID();
146
+ this.storage.remove("user_id");
147
+ this.storage.remove("user_traits");
148
+ this.storage.set("anon_id", this.anonymousId, 365);
149
+ logger.info("Identity reset, new anonymous ID:", this.anonymousId);
150
+ }
151
+ alias(newUserId) {
152
+ const previousId = this.userId || this.anonymousId;
153
+ this.setUserId(newUserId);
154
+ logger.info("User aliased:", { previousId, newUserId });
155
+ return { previousId, newUserId };
156
+ }
157
+ getState() {
158
+ return {
159
+ anonymousId: this.anonymousId,
160
+ userId: this.userId,
161
+ traits: this.getTraits()
162
+ };
163
+ }
164
+ }
165
+ class SessionManager {
166
+ constructor(storage, sessionTimeoutMinutes = 30) {
167
+ this.eventCount = 0;
168
+ this.checkInterval = null;
169
+ this.activityThrottle = 1e3;
170
+ this.lastActivityUpdate = 0;
171
+ this.adClickIDs = {};
172
+ this.storage = storage;
173
+ this.sessionTimeout = sessionTimeoutMinutes * 60 * 1e3;
174
+ this.lastActivityTime = Date.now();
175
+ this.sessionStartTime = Date.now();
176
+ const session = this.loadSession();
177
+ if (session) {
178
+ this.sessionId = session.sessionId;
179
+ this.sessionStartTime = session.startTime;
180
+ this.lastActivityTime = session.lastActivityTime;
181
+ this.eventCount = session.eventCount;
182
+ this.adClickIDs = session.adClickIDs || {};
183
+ this.landingPage = session.landingPage;
184
+ logger.debug("Session loaded:", session);
185
+ } else {
186
+ this.sessionId = this.createNewSession();
187
+ }
188
+ this.startActivityTracking();
189
+ this.startExpiryCheck();
190
+ }
191
+ loadSession() {
192
+ const sessionData = this.storage.get("session");
193
+ if (!sessionData) {
194
+ return null;
195
+ }
196
+ try {
197
+ const session = JSON.parse(sessionData);
198
+ const elapsed = Date.now() - session.lastActivityTime;
199
+ if (elapsed < this.sessionTimeout) {
200
+ return session;
201
+ } else {
202
+ logger.debug("Session expired, creating new session");
203
+ this.storage.remove("session");
204
+ return null;
205
+ }
206
+ } catch (error) {
207
+ logger.warn("Failed to parse session data:", error);
208
+ this.storage.remove("session");
209
+ return null;
210
+ }
211
+ }
212
+ createNewSession() {
213
+ const newSessionId = generateSessionId();
214
+ this.sessionStartTime = Date.now();
215
+ this.lastActivityTime = Date.now();
216
+ this.eventCount = 0;
217
+ this.persistSession();
218
+ logger.info("New session created:", newSessionId);
219
+ return newSessionId;
220
+ }
221
+ persistSession() {
222
+ const sessionData = {
223
+ sessionId: this.sessionId,
224
+ startTime: this.sessionStartTime,
225
+ lastActivityTime: this.lastActivityTime,
226
+ eventCount: this.eventCount,
227
+ adClickIDs: this.adClickIDs,
228
+ landingPage: this.landingPage
229
+ };
230
+ this.storage.set("session", JSON.stringify(sessionData));
231
+ }
232
+ startActivityTracking() {
233
+ const events = ["click", "scroll", "keypress", "mousemove", "touchstart"];
234
+ const activityHandler = () => this.onActivity();
235
+ events.forEach((event) => {
236
+ window.addEventListener(event, activityHandler, { passive: true });
237
+ });
238
+ window.addEventListener("visibilitychange", () => {
239
+ if (document.visibilityState === "visible") {
240
+ this.onActivity();
241
+ }
242
+ });
243
+ }
244
+ startExpiryCheck() {
245
+ this.checkInterval = window.setInterval(() => {
246
+ this.checkSessionExpiry();
247
+ }, 6e4);
248
+ }
249
+ onActivity() {
250
+ const now = Date.now();
251
+ const timeSinceLastUpdate = now - this.lastActivityUpdate;
252
+ if (timeSinceLastUpdate < this.activityThrottle) {
253
+ return;
254
+ }
255
+ this.lastActivityUpdate = now;
256
+ const timeSinceLastActivity = now - this.lastActivityTime;
257
+ if (timeSinceLastActivity > this.sessionTimeout) {
258
+ logger.info("Session expired due to inactivity, creating new session");
259
+ this.sessionId = this.createNewSession();
260
+ } else {
261
+ this.lastActivityTime = now;
262
+ this.persistSession();
263
+ }
264
+ }
265
+ checkSessionExpiry() {
266
+ const elapsed = Date.now() - this.lastActivityTime;
267
+ if (elapsed > this.sessionTimeout) {
268
+ logger.info("Session expired during check, creating new session");
269
+ this.sessionId = this.createNewSession();
270
+ }
271
+ }
272
+ getSessionId() {
273
+ return this.sessionId;
274
+ }
275
+ incrementEventCount() {
276
+ this.eventCount++;
277
+ this.lastActivityTime = Date.now();
278
+ this.persistSession();
279
+ }
280
+ getSessionDuration() {
281
+ return Date.now() - this.sessionStartTime;
282
+ }
283
+ getEventCount() {
284
+ return this.eventCount;
285
+ }
286
+ getState() {
287
+ return {
288
+ sessionId: this.sessionId,
289
+ startTime: this.sessionStartTime,
290
+ lastActivityTime: this.lastActivityTime,
291
+ eventCount: this.eventCount,
292
+ adClickIDs: this.adClickIDs,
293
+ landingPage: this.landingPage
294
+ };
295
+ }
296
+ setAdClickIDs(adClickIDs, landingPage) {
297
+ if (Object.keys(adClickIDs).length > 0) {
298
+ this.adClickIDs = { ...this.adClickIDs, ...adClickIDs };
299
+ if (landingPage) {
300
+ this.landingPage = landingPage;
301
+ }
302
+ this.persistSession();
303
+ logger.info("Ad click IDs stored in session:", this.adClickIDs);
304
+ }
305
+ }
306
+ getAdClickIDs() {
307
+ return this.adClickIDs;
308
+ }
309
+ getLandingPage() {
310
+ return this.landingPage;
311
+ }
312
+ destroy() {
313
+ if (this.checkInterval) {
314
+ clearInterval(this.checkInterval);
315
+ this.checkInterval = null;
316
+ }
317
+ }
318
+ }
319
+ class EventQueue {
320
+ constructor(config, transport, storage) {
321
+ this.buffer = [];
322
+ this.flushInterval = null;
323
+ this.isFlushing = false;
324
+ this.offlineQueue = [];
325
+ this.isOnline = navigator.onLine;
326
+ this.config = config;
327
+ this.transport = transport;
328
+ this.storage = storage;
329
+ if (config.enableOfflineMode) {
330
+ this.loadOfflineQueue();
331
+ this.setupOnlineListener();
332
+ }
333
+ this.startFlushTimer();
334
+ this.setupUnloadHandlers();
335
+ }
336
+ loadOfflineQueue() {
337
+ const offlineData = this.storage.get("offline_queue");
338
+ if (!offlineData) {
339
+ return;
340
+ }
341
+ try {
342
+ const events = JSON.parse(offlineData);
343
+ if (Array.isArray(events) && events.length > 0) {
344
+ this.offlineQueue = events.slice(0, this.config.maxOfflineEvents);
345
+ logger.info(`Loaded ${this.offlineQueue.length} offline events`);
346
+ if (this.isOnline) {
347
+ this.flushOfflineQueue();
348
+ }
349
+ }
350
+ } catch (error) {
351
+ logger.warn("Failed to load offline queue:", error);
352
+ this.storage.remove("offline_queue");
353
+ }
354
+ }
355
+ saveOfflineQueue() {
356
+ if (this.offlineQueue.length === 0) {
357
+ this.storage.remove("offline_queue");
358
+ return;
359
+ }
360
+ try {
361
+ const data = JSON.stringify(this.offlineQueue);
362
+ this.storage.set("offline_queue", data);
363
+ logger.debug(`Saved ${this.offlineQueue.length} events to offline queue`);
364
+ } catch (error) {
365
+ logger.warn("Failed to save offline queue:", error);
366
+ }
367
+ }
368
+ setupOnlineListener() {
369
+ window.addEventListener("online", () => {
370
+ logger.info("Connection restored");
371
+ this.isOnline = true;
372
+ this.flushOfflineQueue();
373
+ this.flush();
374
+ });
375
+ window.addEventListener("offline", () => {
376
+ logger.warn("Connection lost, entering offline mode");
377
+ this.isOnline = false;
378
+ });
379
+ }
380
+ async flushOfflineQueue() {
381
+ if (this.offlineQueue.length === 0) {
382
+ return;
383
+ }
384
+ logger.info(`Flushing ${this.offlineQueue.length} offline events`);
385
+ const events = [...this.offlineQueue];
386
+ this.offlineQueue = [];
387
+ this.storage.remove("offline_queue");
388
+ const result = await this.transport.send(events);
389
+ if (!result.success) {
390
+ logger.warn("Failed to send offline events, re-queueing");
391
+ this.offlineQueue = [...events, ...this.offlineQueue].slice(
392
+ 0,
393
+ this.config.maxOfflineEvents
394
+ );
395
+ this.saveOfflineQueue();
396
+ } else {
397
+ logger.info("Offline events sent successfully");
398
+ }
399
+ }
400
+ push(event) {
401
+ if (!this.isOnline && this.config.enableOfflineMode) {
402
+ this.addToOfflineQueue(event);
403
+ return;
404
+ }
405
+ this.buffer.push(event);
406
+ logger.debug("Event queued:", event.type, event);
407
+ if (this.buffer.length >= this.config.batchSize) {
408
+ this.flush();
409
+ }
410
+ }
411
+ addToOfflineQueue(event) {
412
+ if (this.offlineQueue.length >= this.config.maxOfflineEvents) {
413
+ logger.warn("Offline queue full, dropping oldest event");
414
+ this.offlineQueue.shift();
415
+ }
416
+ this.offlineQueue.push(event);
417
+ this.saveOfflineQueue();
418
+ logger.debug("Event added to offline queue");
419
+ }
420
+ async flush() {
421
+ if (this.isFlushing) {
422
+ logger.debug("Flush already in progress, skipping");
423
+ return;
424
+ }
425
+ if (this.buffer.length === 0) {
426
+ return;
427
+ }
428
+ this.isFlushing = true;
429
+ const events = [...this.buffer];
430
+ this.buffer = [];
431
+ logger.info(`Flushing ${events.length} events`);
432
+ try {
433
+ const result = await this.transport.send(events);
434
+ if (!result.success) {
435
+ logger.error("Failed to send events:", result.error);
436
+ if (this.config.enableOfflineMode) {
437
+ this.offlineQueue = [...this.offlineQueue, ...events].slice(
438
+ 0,
439
+ this.config.maxOfflineEvents
440
+ );
441
+ this.saveOfflineQueue();
442
+ logger.info("Events saved to offline queue");
443
+ } else {
444
+ this.buffer.unshift(...events);
445
+ logger.warn("Events re-queued for retry");
446
+ }
447
+ } else {
448
+ logger.info("Events sent successfully");
449
+ }
450
+ } catch (error) {
451
+ logger.error("Flush error:", error);
452
+ if (this.config.enableOfflineMode) {
453
+ this.offlineQueue = [...this.offlineQueue, ...events].slice(
454
+ 0,
455
+ this.config.maxOfflineEvents
456
+ );
457
+ this.saveOfflineQueue();
458
+ }
459
+ } finally {
460
+ this.isFlushing = false;
461
+ }
462
+ }
463
+ startFlushTimer() {
464
+ if (this.flushInterval) {
465
+ clearInterval(this.flushInterval);
466
+ }
467
+ this.flushInterval = window.setInterval(() => {
468
+ this.flush();
469
+ }, this.config.batchInterval);
470
+ logger.debug(
471
+ `Flush timer started with interval: ${this.config.batchInterval}ms`
472
+ );
473
+ }
474
+ setupUnloadHandlers() {
475
+ const flushBeforeUnload = () => {
476
+ if (this.buffer.length > 0 || this.offlineQueue.length > 0) {
477
+ this.persistBufferToOfflineQueue();
478
+ this.flush();
479
+ }
480
+ };
481
+ document.addEventListener("visibilitychange", () => {
482
+ if (document.visibilityState === "hidden") {
483
+ flushBeforeUnload();
484
+ }
485
+ });
486
+ window.addEventListener("beforeunload", flushBeforeUnload);
487
+ window.addEventListener("pagehide", flushBeforeUnload);
488
+ }
489
+ persistBufferToOfflineQueue() {
490
+ if (this.buffer.length === 0) {
491
+ return;
492
+ }
493
+ if (this.config.enableOfflineMode) {
494
+ this.offlineQueue = [...this.offlineQueue, ...this.buffer].slice(
495
+ 0,
496
+ this.config.maxOfflineEvents
497
+ );
498
+ this.saveOfflineQueue();
499
+ logger.debug("Buffer persisted to offline queue before unload");
500
+ }
501
+ }
502
+ getQueueSize() {
503
+ return this.buffer.length;
504
+ }
505
+ getOfflineQueueSize() {
506
+ return this.offlineQueue.length;
507
+ }
508
+ clear() {
509
+ this.buffer = [];
510
+ this.offlineQueue = [];
511
+ this.storage.remove("offline_queue");
512
+ logger.info("Queue cleared");
513
+ }
514
+ destroy() {
515
+ if (this.flushInterval) {
516
+ clearInterval(this.flushInterval);
517
+ this.flushInterval = null;
518
+ }
519
+ this.flush();
520
+ }
521
+ }
522
+ class Transport {
523
+ constructor(config, storage) {
524
+ this.activeCell = null;
525
+ this.healthCheckInterval = null;
526
+ this.regionLatencyMap = /* @__PURE__ */ new Map();
527
+ this.config = config;
528
+ this.storage = storage;
529
+ if (config.cellEndpoints.length > 0) {
530
+ this.initializeCellularArchitecture();
531
+ }
532
+ }
533
+ async initializeCellularArchitecture() {
534
+ const cachedCell = this.loadCachedCell();
535
+ if (cachedCell && this.isCellHealthy(cachedCell)) {
536
+ this.activeCell = cachedCell;
537
+ logger.info("Using cached cell:", cachedCell);
538
+ } else {
539
+ await this.selectOptimalCell();
540
+ }
541
+ this.startHealthChecks();
542
+ }
543
+ loadCachedCell() {
544
+ const cached = this.storage.get("active_cell");
545
+ if (!cached) {
546
+ return null;
547
+ }
548
+ try {
549
+ return JSON.parse(cached);
550
+ } catch (error) {
551
+ logger.warn("Failed to parse cached cell:", error);
552
+ return null;
553
+ }
554
+ }
555
+ saveCachedCell(cell) {
556
+ this.storage.set("active_cell", JSON.stringify(cell), 7);
557
+ }
558
+ isCellHealthy(cell) {
559
+ return cell.healthy && this.config.cellEndpoints.some(
560
+ (c) => c.region === cell.region && c.url === cell.url
561
+ );
562
+ }
563
+ async selectOptimalCell() {
564
+ logger.info("Selecting optimal cell...");
565
+ if (this.config.preferredRegion) {
566
+ const preferredCell = this.config.cellEndpoints.find(
567
+ (cell) => cell.region === this.config.preferredRegion && cell.healthy
568
+ );
569
+ if (preferredCell) {
570
+ this.activeCell = preferredCell;
571
+ this.saveCachedCell(preferredCell);
572
+ logger.info("Using preferred region cell:", preferredCell);
573
+ return;
574
+ }
575
+ }
576
+ if (this.config.autoRegionDetection) {
577
+ await this.detectOptimalRegion();
578
+ } else {
579
+ this.selectCellByPriority();
580
+ }
581
+ }
582
+ async detectOptimalRegion() {
583
+ const healthyCells = this.config.cellEndpoints.filter((cell) => cell.healthy);
584
+ if (healthyCells.length === 0) {
585
+ logger.error("No healthy cells available");
586
+ return;
587
+ }
588
+ const latencyPromises = healthyCells.map(async (cell) => {
589
+ const latency = await this.measureLatency(cell);
590
+ this.regionLatencyMap.set(cell.region, latency);
591
+ return { cell, latency };
592
+ });
593
+ const results = await Promise.all(latencyPromises);
594
+ results.sort((a, b) => a.latency - b.latency);
595
+ const optimalCell = results[0].cell;
596
+ this.activeCell = optimalCell;
597
+ this.saveCachedCell(optimalCell);
598
+ logger.info("Optimal cell selected:", {
599
+ region: optimalCell.region,
600
+ latency: results[0].latency
601
+ });
602
+ }
603
+ async measureLatency(cell) {
604
+ const startTime = performance.now();
605
+ try {
606
+ const controller = new AbortController();
607
+ const timeoutId = setTimeout(() => controller.abort(), 2e3);
608
+ const response = await fetch(`${cell.url}/health`, {
609
+ method: "GET",
610
+ signal: controller.signal
611
+ });
612
+ clearTimeout(timeoutId);
613
+ if (response.ok) {
614
+ return performance.now() - startTime;
615
+ } else {
616
+ return Infinity;
617
+ }
618
+ } catch (error) {
619
+ logger.warn(`Health check failed for ${cell.region}:`, error);
620
+ return Infinity;
621
+ }
622
+ }
623
+ selectCellByPriority() {
624
+ const sortedCells = [...this.config.cellEndpoints].filter((cell) => cell.healthy).sort((a, b) => a.priority - b.priority);
625
+ if (sortedCells.length > 0) {
626
+ this.activeCell = sortedCells[0];
627
+ this.saveCachedCell(sortedCells[0]);
628
+ logger.info("Cell selected by priority:", sortedCells[0]);
629
+ } else {
630
+ logger.error("No healthy cells available");
631
+ }
632
+ }
633
+ startHealthChecks() {
634
+ this.healthCheckInterval = window.setInterval(() => {
635
+ this.performHealthChecks();
636
+ }, 6e4);
637
+ }
638
+ async performHealthChecks() {
639
+ const healthPromises = this.config.cellEndpoints.map(async (cell) => {
640
+ const isHealthy = await this.checkCellHealth(cell);
641
+ cell.healthy = isHealthy;
642
+ return { cell, isHealthy };
643
+ });
644
+ const results = await Promise.all(healthPromises);
645
+ if (this.activeCell && !this.activeCell.healthy) {
646
+ logger.warn("Active cell unhealthy, selecting new cell");
647
+ await this.selectOptimalCell();
648
+ }
649
+ logger.debug("Health check results:", results);
650
+ }
651
+ async checkCellHealth(cell) {
652
+ try {
653
+ const controller = new AbortController();
654
+ const timeoutId = setTimeout(() => controller.abort(), 3e3);
655
+ const response = await fetch(`${cell.url}/health`, {
656
+ method: "GET",
657
+ signal: controller.signal
658
+ });
659
+ clearTimeout(timeoutId);
660
+ return response.ok;
661
+ } catch (error) {
662
+ return false;
663
+ }
664
+ }
665
+ async send(events) {
666
+ if (events.length === 0) {
667
+ return { success: true };
668
+ }
669
+ const endpoint = this.getActiveEndpoint();
670
+ const payload = this.buildPayload(events);
671
+ logger.debug("Sending batch:", { endpoint, eventCount: events.length });
672
+ if (document.visibilityState === "hidden" && typeof navigator.sendBeacon === "function") {
673
+ const result = this.sendViaBeacon(endpoint, payload);
674
+ return Promise.resolve(result);
675
+ } else {
676
+ return this.sendViaFetch(endpoint, payload);
677
+ }
678
+ }
679
+ getActiveEndpoint() {
680
+ if (this.activeCell) {
681
+ return `${this.activeCell.url}/v1/batch`;
682
+ }
683
+ if (this.config.apiHost) {
684
+ return `${this.config.apiHost}/v1/batch`;
685
+ }
686
+ throw new Error("No active endpoint available");
687
+ }
688
+ buildPayload(events) {
689
+ return {
690
+ batch: events,
691
+ sentAt: (/* @__PURE__ */ new Date()).toISOString(),
692
+ writeKey: this.config.writeKey,
693
+ context: this.activeCell ? {
694
+ cell: {
695
+ region: this.activeCell.region,
696
+ endpoint: this.activeCell.url
697
+ }
698
+ } : void 0
699
+ };
700
+ }
701
+ sendViaBeacon(endpoint, payload) {
702
+ try {
703
+ const blob = new Blob([JSON.stringify(payload)], {
704
+ type: "application/json"
705
+ });
706
+ const sent = navigator.sendBeacon(endpoint, blob);
707
+ if (sent) {
708
+ logger.debug("Batch sent via Beacon");
709
+ return { success: true, endpoint };
710
+ } else {
711
+ logger.warn("Beacon send failed, falling back to fetch");
712
+ return this.sendViaFetch(endpoint, payload);
713
+ }
714
+ } catch (error) {
715
+ logger.error("Beacon send error:", error);
716
+ return {
717
+ success: false,
718
+ error,
719
+ endpoint
720
+ };
721
+ }
722
+ }
723
+ async sendViaFetch(endpoint, payload, attempt = 1) {
724
+ try {
725
+ const controller = new AbortController();
726
+ const timeoutId = setTimeout(
727
+ () => controller.abort(),
728
+ this.config.requestTimeout
729
+ );
730
+ const response = await fetch(endpoint, {
731
+ method: "POST",
732
+ headers: {
733
+ "Content-Type": "application/json",
734
+ Authorization: `Bearer ${this.config.writeKey}`
735
+ },
736
+ body: JSON.stringify(payload),
737
+ keepalive: true,
738
+ signal: controller.signal
739
+ });
740
+ clearTimeout(timeoutId);
741
+ if (response.ok) {
742
+ const result = await response.json();
743
+ logger.debug("Batch sent successfully:", result);
744
+ return { success: true, response: result, endpoint };
745
+ } else {
746
+ const errorText = await response.text();
747
+ const error = new Error(
748
+ `HTTP ${response.status}: ${errorText || response.statusText}`
749
+ );
750
+ logger.error("Batch send failed:", error);
751
+ if (this.shouldRetry(response.status, attempt)) {
752
+ return this.retryRequest(endpoint, payload, attempt);
753
+ }
754
+ return { success: false, error, endpoint };
755
+ }
756
+ } catch (error) {
757
+ logger.error("Fetch error:", error);
758
+ if (this.shouldRetry(0, attempt)) {
759
+ return this.retryRequest(endpoint, payload, attempt);
760
+ }
761
+ return {
762
+ success: false,
763
+ error,
764
+ endpoint
765
+ };
766
+ }
767
+ }
768
+ shouldRetry(statusCode, attempt) {
769
+ if (!this.config.retryFailedRequests) {
770
+ return false;
771
+ }
772
+ if (attempt >= this.config.maxRetries) {
773
+ return false;
774
+ }
775
+ if (statusCode === 0) {
776
+ return true;
777
+ }
778
+ return statusCode >= 500 || statusCode === 429;
779
+ }
780
+ async retryRequest(endpoint, payload, attempt) {
781
+ const delay = Math.pow(this.config.retryBackoffMultiplier, attempt) * 1e3;
782
+ logger.info(`Retrying request in ${delay}ms (attempt ${attempt + 1})`);
783
+ await new Promise((resolve) => setTimeout(resolve, delay));
784
+ return this.sendViaFetch(endpoint, payload, attempt + 1);
785
+ }
786
+ getActiveCell() {
787
+ return this.activeCell;
788
+ }
789
+ getRegionLatencies() {
790
+ return new Map(this.regionLatencyMap);
791
+ }
792
+ destroy() {
793
+ if (this.healthCheckInterval) {
794
+ clearInterval(this.healthCheckInterval);
795
+ this.healthCheckInterval = null;
796
+ }
797
+ }
798
+ }
799
+ const STORAGE_PREFIX = "aegis_";
800
+ class Storage {
801
+ constructor(options = {}) {
802
+ this.options = options;
803
+ this.useLocalStorage = this.isLocalStorageAvailable();
804
+ }
805
+ isLocalStorageAvailable() {
806
+ try {
807
+ const test = "__aegis_test__";
808
+ localStorage.setItem(test, test);
809
+ localStorage.removeItem(test);
810
+ return true;
811
+ } catch {
812
+ return false;
813
+ }
814
+ }
815
+ set(key, value, expiryDays = 365) {
816
+ const fullKey = STORAGE_PREFIX + key;
817
+ if (this.useLocalStorage) {
818
+ try {
819
+ const item = {
820
+ value,
821
+ expiry: Date.now() + expiryDays * 24 * 60 * 60 * 1e3
822
+ };
823
+ localStorage.setItem(fullKey, JSON.stringify(item));
824
+ } catch (error) {
825
+ console.warn("[Aegis Storage] localStorage.setItem failed:", error);
826
+ }
827
+ }
828
+ this.setCookie(fullKey, value, expiryDays);
829
+ }
830
+ get(key) {
831
+ const fullKey = STORAGE_PREFIX + key;
832
+ if (this.useLocalStorage) {
833
+ try {
834
+ const itemStr = localStorage.getItem(fullKey);
835
+ if (itemStr) {
836
+ const item = JSON.parse(itemStr);
837
+ if (Date.now() < item.expiry) {
838
+ return item.value;
839
+ } else {
840
+ localStorage.removeItem(fullKey);
841
+ }
842
+ }
843
+ } catch (error) {
844
+ console.warn("[Aegis Storage] localStorage.getItem failed:", error);
845
+ }
846
+ }
847
+ return this.getCookie(fullKey);
848
+ }
849
+ remove(key) {
850
+ const fullKey = STORAGE_PREFIX + key;
851
+ if (this.useLocalStorage) {
852
+ try {
853
+ localStorage.removeItem(fullKey);
854
+ } catch (error) {
855
+ console.warn("[Aegis Storage] localStorage.removeItem failed:", error);
856
+ }
857
+ }
858
+ this.deleteCookie(fullKey);
859
+ }
860
+ clear() {
861
+ if (this.useLocalStorage) {
862
+ try {
863
+ const keys = Object.keys(localStorage);
864
+ keys.forEach((key) => {
865
+ if (key.startsWith(STORAGE_PREFIX)) {
866
+ localStorage.removeItem(key);
867
+ }
868
+ });
869
+ } catch (error) {
870
+ console.warn("[Aegis Storage] localStorage.clear failed:", error);
871
+ }
872
+ }
873
+ const cookies = document.cookie.split(";");
874
+ cookies.forEach((cookie) => {
875
+ const key = cookie.split("=")[0].trim();
876
+ if (key.startsWith(STORAGE_PREFIX)) {
877
+ this.deleteCookie(key);
878
+ }
879
+ });
880
+ }
881
+ setCookie(name, value, days) {
882
+ try {
883
+ const date = /* @__PURE__ */ new Date();
884
+ date.setTime(date.getTime() + days * 24 * 60 * 60 * 1e3);
885
+ const expires = `expires=${date.toUTCString()}`;
886
+ let cookieStr = `${name}=${value};${expires};path=/`;
887
+ if (this.options.secureCookie && window.location.protocol === "https:") {
888
+ cookieStr += ";Secure";
889
+ }
890
+ cookieStr += ";SameSite=Lax";
891
+ if (this.options.cookieDomain) {
892
+ cookieStr += `;domain=${this.options.cookieDomain}`;
893
+ } else if (this.options.crossDomain) {
894
+ const domain = this.getRootDomain();
895
+ if (domain) {
896
+ cookieStr += `;domain=${domain}`;
897
+ }
898
+ }
899
+ document.cookie = cookieStr;
900
+ } catch (error) {
901
+ console.warn("[Aegis Storage] setCookie failed:", error);
902
+ }
903
+ }
904
+ getCookie(name) {
905
+ try {
906
+ const nameEQ = name + "=";
907
+ const ca = document.cookie.split(";");
908
+ for (let i = 0; i < ca.length; i++) {
909
+ let c = ca[i];
910
+ while (c.charAt(0) === " ") {
911
+ c = c.substring(1, c.length);
912
+ }
913
+ if (c.indexOf(nameEQ) === 0) {
914
+ return c.substring(nameEQ.length, c.length);
915
+ }
916
+ }
917
+ } catch (error) {
918
+ console.warn("[Aegis Storage] getCookie failed:", error);
919
+ }
920
+ return null;
921
+ }
922
+ deleteCookie(name) {
923
+ try {
924
+ let cookieStr = `${name}=;expires=Thu, 01 Jan 1970 00:00:00 UTC;path=/`;
925
+ if (this.options.cookieDomain) {
926
+ cookieStr += `;domain=${this.options.cookieDomain}`;
927
+ } else if (this.options.crossDomain) {
928
+ const domain = this.getRootDomain();
929
+ if (domain) {
930
+ cookieStr += `;domain=${domain}`;
931
+ }
932
+ }
933
+ document.cookie = cookieStr;
934
+ } catch (error) {
935
+ console.warn("[Aegis Storage] deleteCookie failed:", error);
936
+ }
937
+ }
938
+ getRootDomain() {
939
+ try {
940
+ const hostname = window.location.hostname;
941
+ if (/^(\d{1,3}\.){3}\d{1,3}$/.test(hostname)) {
942
+ return null;
943
+ }
944
+ if (hostname === "localhost") {
945
+ return null;
946
+ }
947
+ const parts = hostname.split(".");
948
+ if (parts.length <= 2) {
949
+ return `.${hostname}`;
950
+ }
951
+ return `.${parts.slice(-2).join(".")}`;
952
+ } catch (error) {
953
+ console.warn("[Aegis Storage] getRootDomain failed:", error);
954
+ return null;
955
+ }
956
+ }
957
+ }
958
+ function parseUTMParameters(url) {
959
+ try {
960
+ const searchParams = url ? new URL(url).searchParams : new URLSearchParams(window.location.search);
961
+ const utm = {};
962
+ const utmKeys = [
963
+ "source",
964
+ "medium",
965
+ "campaign",
966
+ "term",
967
+ "content",
968
+ "name"
969
+ ];
970
+ utmKeys.forEach((key) => {
971
+ const value = searchParams.get(`utm_${key}`);
972
+ if (value) {
973
+ utm[key] = value;
974
+ }
975
+ });
976
+ return utm;
977
+ } catch (error) {
978
+ console.warn("[Aegis URL Parser] parseUTMParameters failed:", error);
979
+ return {};
980
+ }
981
+ }
982
+ function parseAdClickIDs(url) {
983
+ try {
984
+ const searchParams = url ? new URL(url).searchParams : new URLSearchParams(window.location.search);
985
+ const adClickIDs = {};
986
+ const clickIDKeys = [
987
+ "gclid",
988
+ "fbclid",
989
+ "msclkid",
990
+ "ctwa_clid",
991
+ "ttclid",
992
+ "li_fat_id"
993
+ ];
994
+ clickIDKeys.forEach((key) => {
995
+ const value = searchParams.get(key);
996
+ if (value) {
997
+ adClickIDs[key] = value;
998
+ }
999
+ });
1000
+ return adClickIDs;
1001
+ } catch (error) {
1002
+ console.warn("[Aegis URL Parser] parseAdClickIDs failed:", error);
1003
+ return {};
1004
+ }
1005
+ }
1006
+ function hasAdClickIDs(adClickIDs) {
1007
+ return Object.keys(adClickIDs).length > 0;
1008
+ }
1009
+ function buildContext(config, session) {
1010
+ const utm = config.capture_utm ? parseUTMParameters() : void 0;
1011
+ const device = detectDevice();
1012
+ const os = detectOS();
1013
+ const browser = detectBrowser();
1014
+ const network = detectNetworkInfo();
1015
+ const adClickIDs = session == null ? void 0 : session.getAdClickIDs();
1016
+ const landingPage = session == null ? void 0 : session.getLandingPage();
1017
+ return {
1018
+ library: {
1019
+ name: "@aegis/web-sdk",
1020
+ version: "1.0.0"
1021
+ },
1022
+ page: {
1023
+ path: window.location.pathname,
1024
+ referrer: config.capture_referrer ? document.referrer : "",
1025
+ search: window.location.search,
1026
+ title: document.title,
1027
+ url: window.location.href,
1028
+ hash: window.location.hash
1029
+ },
1030
+ userAgent: navigator.userAgent,
1031
+ locale: navigator.language,
1032
+ timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
1033
+ screen: {
1034
+ width: window.screen.width,
1035
+ height: window.screen.height,
1036
+ density: window.devicePixelRatio || 1
1037
+ },
1038
+ viewport: {
1039
+ width: window.innerWidth,
1040
+ height: window.innerHeight
1041
+ },
1042
+ ...utm && Object.keys(utm).length > 0 && { campaign: utm },
1043
+ ...adClickIDs && Object.keys(adClickIDs).length > 0 && { adClickIDs },
1044
+ ...landingPage && { landingPage },
1045
+ ...network && { network },
1046
+ ...device && { device },
1047
+ ...os && { os },
1048
+ ...browser && { browser },
1049
+ ...config.active_cell && {
1050
+ cell: {
1051
+ region: config.active_cell.region,
1052
+ endpoint: config.active_cell.url
1053
+ }
1054
+ }
1055
+ };
1056
+ }
1057
+ function detectDevice() {
1058
+ const ua = navigator.userAgent;
1059
+ if (/(tablet|ipad|playbook|silk)|(android(?!.*mobi))/i.test(ua)) {
1060
+ return { type: "tablet" };
1061
+ }
1062
+ if (/Mobile|Android|iP(hone|od)|IEMobile|BlackBerry|Kindle|Silk-Accelerated|(hpw|web)OS|Opera M(obi|ini)/.test(ua)) {
1063
+ return { type: "mobile" };
1064
+ }
1065
+ return { type: "desktop" };
1066
+ }
1067
+ function detectOS() {
1068
+ const ua = navigator.userAgent;
1069
+ if (/Windows NT 10/i.test(ua)) return { name: "Windows", version: "10" };
1070
+ if (/Windows NT 6.3/i.test(ua)) return { name: "Windows", version: "8.1" };
1071
+ if (/Windows NT 6.2/i.test(ua)) return { name: "Windows", version: "8" };
1072
+ if (/Windows NT 6.1/i.test(ua)) return { name: "Windows", version: "7" };
1073
+ if (/Windows/i.test(ua)) return { name: "Windows", version: "Unknown" };
1074
+ if (/Mac OS X (\d+)[._](\d+)/.test(ua)) {
1075
+ const match = ua.match(/Mac OS X (\d+)[._](\d+)/);
1076
+ return { name: "macOS", version: `${match[1]}.${match[2]}` };
1077
+ }
1078
+ if (/Mac/i.test(ua)) return { name: "macOS", version: "Unknown" };
1079
+ if (/Android (\d+\.\d+)/.test(ua)) {
1080
+ const match = ua.match(/Android (\d+\.\d+)/);
1081
+ return { name: "Android", version: match[1] };
1082
+ }
1083
+ if (/Android/i.test(ua)) return { name: "Android", version: "Unknown" };
1084
+ if (/iPhone OS (\d+)_(\d+)/.test(ua)) {
1085
+ const match = ua.match(/iPhone OS (\d+)_(\d+)/);
1086
+ return { name: "iOS", version: `${match[1]}.${match[2]}` };
1087
+ }
1088
+ if (/iPad.*OS (\d+)_(\d+)/.test(ua)) {
1089
+ const match = ua.match(/iPad.*OS (\d+)_(\d+)/);
1090
+ return { name: "iOS", version: `${match[1]}.${match[2]}` };
1091
+ }
1092
+ if (/iPhone|iPad/i.test(ua)) return { name: "iOS", version: "Unknown" };
1093
+ if (/Linux/i.test(ua)) return { name: "Linux", version: "Unknown" };
1094
+ return { name: "Unknown", version: "Unknown" };
1095
+ }
1096
+ function detectBrowser() {
1097
+ const ua = navigator.userAgent;
1098
+ if (/Edg\/(\d+\.\d+)/.test(ua)) {
1099
+ const match = ua.match(/Edg\/(\d+\.\d+)/);
1100
+ return { name: "Edge", version: match[1] };
1101
+ }
1102
+ if (/Chrome\/(\d+\.\d+)/.test(ua) && !/Edg/.test(ua)) {
1103
+ const match = ua.match(/Chrome\/(\d+\.\d+)/);
1104
+ return { name: "Chrome", version: match[1] };
1105
+ }
1106
+ if (/Firefox\/(\d+\.\d+)/.test(ua)) {
1107
+ const match = ua.match(/Firefox\/(\d+\.\d+)/);
1108
+ return { name: "Firefox", version: match[1] };
1109
+ }
1110
+ if (/Safari\/(\d+\.\d+)/.test(ua) && !/Chrome/.test(ua)) {
1111
+ const match = ua.match(/Version\/(\d+\.\d+)/);
1112
+ return { name: "Safari", version: match ? match[1] : "Unknown" };
1113
+ }
1114
+ if (/MSIE (\d+\.\d+)/.test(ua) || /Trident\//.test(ua)) {
1115
+ const match = ua.match(/MSIE (\d+\.\d+)/) || ua.match(/rv:(\d+\.\d+)/);
1116
+ return { name: "Internet Explorer", version: match ? match[1] : "Unknown" };
1117
+ }
1118
+ return { name: "Unknown", version: "Unknown" };
1119
+ }
1120
+ function detectNetworkInfo() {
1121
+ try {
1122
+ const connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection;
1123
+ if (connection) {
1124
+ return {
1125
+ effectiveType: connection.effectiveType,
1126
+ downlink: connection.downlink,
1127
+ rtt: connection.rtt
1128
+ };
1129
+ }
1130
+ } catch (error) {
1131
+ console.warn("[Aegis Device] detectNetworkInfo failed:", error);
1132
+ }
1133
+ return void 0;
1134
+ }
1135
+ function isBot() {
1136
+ const ua = navigator.userAgent.toLowerCase();
1137
+ const botPatterns = [
1138
+ "bot",
1139
+ "crawl",
1140
+ "spider",
1141
+ "slurp",
1142
+ "mediapartners",
1143
+ "googlebot",
1144
+ "bingbot",
1145
+ "yahoo",
1146
+ "duckduckbot",
1147
+ "baiduspider",
1148
+ "yandex",
1149
+ "facebookexternalhit",
1150
+ "linkedinbot",
1151
+ "twitterbot",
1152
+ "slackbot",
1153
+ "telegrambot",
1154
+ "whatsapp",
1155
+ "pingdom",
1156
+ "uptimerobot"
1157
+ ];
1158
+ return botPatterns.some((pattern) => ua.includes(pattern));
1159
+ }
1160
+ class PluginRegistry {
1161
+ constructor() {
1162
+ this.plugins = /* @__PURE__ */ new Map();
1163
+ }
1164
+ register(plugin) {
1165
+ if (this.plugins.has(plugin.name)) {
1166
+ logger.warn(`Plugin "${plugin.name}" already registered, skipping`);
1167
+ return;
1168
+ }
1169
+ this.plugins.set(plugin.name, plugin);
1170
+ logger.info(`Plugin registered: ${plugin.name} v${plugin.version}`);
1171
+ }
1172
+ unregister(pluginName) {
1173
+ const plugin = this.plugins.get(pluginName);
1174
+ if (!plugin) {
1175
+ logger.warn(`Plugin "${pluginName}" not found`);
1176
+ return;
1177
+ }
1178
+ if (plugin.destroy) {
1179
+ try {
1180
+ plugin.destroy();
1181
+ } catch (error) {
1182
+ logger.error(`Error destroying plugin "${pluginName}":`, error);
1183
+ }
1184
+ }
1185
+ this.plugins.delete(pluginName);
1186
+ logger.info(`Plugin unregistered: ${pluginName}`);
1187
+ }
1188
+ get(pluginName) {
1189
+ return this.plugins.get(pluginName);
1190
+ }
1191
+ getAll() {
1192
+ return Array.from(this.plugins.values());
1193
+ }
1194
+ async executeHook(hookName, ...args) {
1195
+ for (const plugin of this.plugins.values()) {
1196
+ const hook = plugin[hookName];
1197
+ if (typeof hook === "function") {
1198
+ try {
1199
+ const result = await hook.apply(plugin, args);
1200
+ if (result !== void 0) {
1201
+ return result;
1202
+ }
1203
+ } catch (error) {
1204
+ logger.error(
1205
+ `Error executing ${String(hookName)} in plugin "${plugin.name}":`,
1206
+ error
1207
+ );
1208
+ if (plugin.onError) {
1209
+ try {
1210
+ plugin.onError(error, { hookName, args });
1211
+ } catch (onErrorError) {
1212
+ logger.error(
1213
+ `Error in onError handler for plugin "${plugin.name}":`,
1214
+ onErrorError
1215
+ );
1216
+ }
1217
+ }
1218
+ }
1219
+ }
1220
+ }
1221
+ return void 0;
1222
+ }
1223
+ async executeHookChain(hookName, initialValue, ...additionalArgs) {
1224
+ let value = initialValue;
1225
+ for (const plugin of this.plugins.values()) {
1226
+ const hook = plugin[hookName];
1227
+ if (typeof hook === "function") {
1228
+ try {
1229
+ const result = await hook.apply(plugin, [
1230
+ value,
1231
+ ...additionalArgs
1232
+ ]);
1233
+ if (result !== void 0 && result !== null) {
1234
+ value = result;
1235
+ }
1236
+ } catch (error) {
1237
+ logger.error(
1238
+ `Error executing ${String(hookName)} in plugin "${plugin.name}":`,
1239
+ error
1240
+ );
1241
+ if (plugin.onError) {
1242
+ try {
1243
+ plugin.onError(error, { hookName, value, additionalArgs });
1244
+ } catch (onErrorError) {
1245
+ logger.error(
1246
+ `Error in onError handler for plugin "${plugin.name}":`,
1247
+ onErrorError
1248
+ );
1249
+ }
1250
+ }
1251
+ }
1252
+ }
1253
+ }
1254
+ return value;
1255
+ }
1256
+ async executeHookParallel(hookName, ...args) {
1257
+ const promises = [];
1258
+ for (const plugin of this.plugins.values()) {
1259
+ const hook = plugin[hookName];
1260
+ if (typeof hook === "function") {
1261
+ const promise = (async () => {
1262
+ try {
1263
+ return await hook.apply(plugin, args);
1264
+ } catch (error) {
1265
+ logger.error(
1266
+ `Error executing ${String(hookName)} in plugin "${plugin.name}":`,
1267
+ error
1268
+ );
1269
+ if (plugin.onError) {
1270
+ try {
1271
+ plugin.onError(error, { hookName, args });
1272
+ } catch (onErrorError) {
1273
+ logger.error(
1274
+ `Error in onError handler for plugin "${plugin.name}":`,
1275
+ onErrorError
1276
+ );
1277
+ }
1278
+ }
1279
+ return void 0;
1280
+ }
1281
+ })();
1282
+ promises.push(promise);
1283
+ }
1284
+ }
1285
+ const results = await Promise.all(promises);
1286
+ return results.filter((r) => r !== void 0);
1287
+ }
1288
+ clear() {
1289
+ for (const plugin of this.plugins.values()) {
1290
+ if (plugin.destroy) {
1291
+ try {
1292
+ plugin.destroy();
1293
+ } catch (error) {
1294
+ logger.error(`Error destroying plugin "${plugin.name}":`, error);
1295
+ }
1296
+ }
1297
+ }
1298
+ this.plugins.clear();
1299
+ logger.info("All plugins cleared");
1300
+ }
1301
+ }
1302
+ class ConsentManager {
1303
+ constructor(storage, config = {}) {
1304
+ this.listeners = [];
1305
+ this.storage = storage;
1306
+ this.config = {
1307
+ defaultConsent: config.defaultConsent || {},
1308
+ waitForConsent: config.waitForConsent ?? false,
1309
+ consentStorageKey: config.consentStorageKey || "aegis_consent"
1310
+ };
1311
+ this.preferences = this.loadPreferences();
1312
+ }
1313
+ loadPreferences() {
1314
+ const stored = this.storage.get(this.config.consentStorageKey);
1315
+ if (stored) {
1316
+ try {
1317
+ const parsed = JSON.parse(stored);
1318
+ logger.info("Loaded consent preferences:", parsed);
1319
+ return this.mergeWithDefaults(parsed);
1320
+ } catch (error) {
1321
+ logger.warn("Failed to parse consent preferences:", error);
1322
+ }
1323
+ }
1324
+ return this.getDefaultPreferences();
1325
+ }
1326
+ getDefaultPreferences() {
1327
+ return {
1328
+ analytics: this.config.defaultConsent.analytics ?? false,
1329
+ marketing: this.config.defaultConsent.marketing ?? false,
1330
+ functional: this.config.defaultConsent.functional ?? true,
1331
+ necessary: true
1332
+ };
1333
+ }
1334
+ mergeWithDefaults(preferences) {
1335
+ return {
1336
+ necessary: true,
1337
+ analytics: preferences.analytics ?? this.config.defaultConsent.analytics ?? false,
1338
+ marketing: preferences.marketing ?? this.config.defaultConsent.marketing ?? false,
1339
+ functional: preferences.functional ?? this.config.defaultConsent.functional ?? true
1340
+ };
1341
+ }
1342
+ savePreferences() {
1343
+ try {
1344
+ this.storage.set(
1345
+ this.config.consentStorageKey,
1346
+ JSON.stringify(this.preferences),
1347
+ 365
1348
+ );
1349
+ logger.info("Saved consent preferences:", this.preferences);
1350
+ } catch (error) {
1351
+ logger.error("Failed to save consent preferences:", error);
1352
+ }
1353
+ }
1354
+ setConsent(preferences) {
1355
+ const updated = { ...this.preferences, ...preferences };
1356
+ updated.necessary = true;
1357
+ this.preferences = updated;
1358
+ this.savePreferences();
1359
+ this.notifyListeners();
1360
+ logger.info("Consent updated:", this.preferences);
1361
+ }
1362
+ grantAll() {
1363
+ this.setConsent({
1364
+ analytics: true,
1365
+ marketing: true,
1366
+ functional: true,
1367
+ necessary: true
1368
+ });
1369
+ }
1370
+ denyAll() {
1371
+ this.setConsent({
1372
+ analytics: false,
1373
+ marketing: false,
1374
+ functional: false,
1375
+ necessary: true
1376
+ });
1377
+ }
1378
+ hasConsent(category) {
1379
+ return this.preferences[category];
1380
+ }
1381
+ getPreferences() {
1382
+ return { ...this.preferences };
1383
+ }
1384
+ getStatus(category) {
1385
+ if (this.hasConsent(category)) {
1386
+ return "granted";
1387
+ }
1388
+ const stored = this.storage.get(this.config.consentStorageKey);
1389
+ if (!stored && this.config.waitForConsent) {
1390
+ return "pending";
1391
+ }
1392
+ return "denied";
1393
+ }
1394
+ isAnalyticsEnabled() {
1395
+ return this.hasConsent("analytics");
1396
+ }
1397
+ isMarketingEnabled() {
1398
+ return this.hasConsent("marketing");
1399
+ }
1400
+ onChange(callback) {
1401
+ this.listeners.push(callback);
1402
+ return () => {
1403
+ const index = this.listeners.indexOf(callback);
1404
+ if (index > -1) {
1405
+ this.listeners.splice(index, 1);
1406
+ }
1407
+ };
1408
+ }
1409
+ notifyListeners() {
1410
+ this.listeners.forEach((listener) => {
1411
+ try {
1412
+ listener(this.getPreferences());
1413
+ } catch (error) {
1414
+ logger.error("Consent listener error:", error);
1415
+ }
1416
+ });
1417
+ }
1418
+ reset() {
1419
+ this.storage.remove(this.config.consentStorageKey);
1420
+ this.preferences = this.getDefaultPreferences();
1421
+ this.notifyListeners();
1422
+ logger.info("Consent preferences reset");
1423
+ }
1424
+ integrateOneTrust() {
1425
+ if (typeof window === "undefined") return;
1426
+ const oneTrust = window.OneTrust;
1427
+ if (!oneTrust) {
1428
+ logger.warn("OneTrust not detected");
1429
+ return;
1430
+ }
1431
+ const syncWithOneTrust = () => {
1432
+ const activeGroups = window.OnetrustActiveGroups || "";
1433
+ this.setConsent({
1434
+ necessary: true,
1435
+ functional: activeGroups.includes("C0003"),
1436
+ analytics: activeGroups.includes("C0002"),
1437
+ marketing: activeGroups.includes("C0004")
1438
+ });
1439
+ logger.info("Synced with OneTrust consent");
1440
+ };
1441
+ if (window.OptanonWrapper) {
1442
+ const originalWrapper = window.OptanonWrapper;
1443
+ window.OptanonWrapper = function() {
1444
+ originalWrapper();
1445
+ syncWithOneTrust();
1446
+ };
1447
+ } else {
1448
+ window.OptanonWrapper = syncWithOneTrust;
1449
+ }
1450
+ syncWithOneTrust();
1451
+ }
1452
+ integrateCookiebot() {
1453
+ if (typeof window === "undefined") return;
1454
+ const cookiebot = window.Cookiebot;
1455
+ if (!cookiebot) {
1456
+ logger.warn("Cookiebot not detected");
1457
+ return;
1458
+ }
1459
+ const syncWithCookiebot = () => {
1460
+ const consent = cookiebot.consent || {};
1461
+ this.setConsent({
1462
+ necessary: true,
1463
+ functional: consent.preferences || false,
1464
+ analytics: consent.statistics || false,
1465
+ marketing: consent.marketing || false
1466
+ });
1467
+ logger.info("Synced with Cookiebot consent");
1468
+ };
1469
+ window.addEventListener("CookiebotOnAccept", syncWithCookiebot);
1470
+ window.addEventListener("CookiebotOnDecline", syncWithCookiebot);
1471
+ if (cookiebot.consent) {
1472
+ syncWithCookiebot();
1473
+ }
1474
+ }
1475
+ integrateGoogleConsentMode() {
1476
+ if (typeof window === "undefined") return;
1477
+ const gtag = window.gtag;
1478
+ if (!gtag) {
1479
+ logger.warn("Google Tag Manager not detected");
1480
+ return;
1481
+ }
1482
+ const updateGoogleConsent = () => {
1483
+ gtag("consent", "update", {
1484
+ ad_storage: this.preferences.marketing ? "granted" : "denied",
1485
+ analytics_storage: this.preferences.analytics ? "granted" : "denied",
1486
+ ad_user_data: this.preferences.marketing ? "granted" : "denied",
1487
+ ad_personalization: this.preferences.marketing ? "granted" : "denied",
1488
+ functionality_storage: this.preferences.functional ? "granted" : "denied",
1489
+ personalization_storage: this.preferences.functional ? "granted" : "denied",
1490
+ security_storage: "granted"
1491
+ });
1492
+ logger.info("Updated Google Consent Mode");
1493
+ };
1494
+ this.onChange(updateGoogleConsent);
1495
+ updateGoogleConsent();
1496
+ }
1497
+ }
1498
+ class Aegis {
1499
+ constructor() {
1500
+ this.config = null;
1501
+ this.session = null;
1502
+ this.queue = null;
1503
+ this.transport = null;
1504
+ this.plugins = new PluginRegistry();
1505
+ this.initPromise = null;
1506
+ this.consent = null;
1507
+ }
1508
+ async init(writeKey, config) {
1509
+ if (this.initPromise) {
1510
+ return this.initPromise;
1511
+ }
1512
+ this.initPromise = this._init(writeKey, config);
1513
+ return this.initPromise;
1514
+ }
1515
+ async _init(writeKey, config) {
1516
+ var _a;
1517
+ if ((_a = this.config) == null ? void 0 : _a.initialized) {
1518
+ logger.warn("SDK already initialized");
1519
+ return;
1520
+ }
1521
+ if (this.shouldRespectDNT(config)) {
1522
+ logger.info("Do Not Track is enabled, SDK disabled");
1523
+ return;
1524
+ }
1525
+ if (isBot()) {
1526
+ logger.info("Bot detected, SDK disabled");
1527
+ return;
1528
+ }
1529
+ this.config = this.buildConfig(writeKey, config);
1530
+ if (this.config.debug) {
1531
+ logger.enable();
1532
+ }
1533
+ logger.info("Initializing Aegis SDK...", this.config);
1534
+ this.storage = new Storage({
1535
+ cookieDomain: this.config.cookie_domain,
1536
+ secureCookie: this.config.secure_cookie,
1537
+ crossDomain: this.config.cross_domain_tracking
1538
+ });
1539
+ this.identity = new Identity(this.storage);
1540
+ this.consent = new ConsentManager(this.storage, {
1541
+ defaultConsent: this.config.default_consent,
1542
+ waitForConsent: this.config.wait_for_consent
1543
+ });
1544
+ if (this.config.integrate_onetrust) {
1545
+ this.consent.integrateOneTrust();
1546
+ }
1547
+ if (this.config.integrate_cookiebot) {
1548
+ this.consent.integrateCookiebot();
1549
+ }
1550
+ if (this.config.integrate_google_consent_mode) {
1551
+ this.consent.integrateGoogleConsentMode();
1552
+ }
1553
+ this.session = new SessionManager(
1554
+ this.storage,
1555
+ this.config.session_timeout
1556
+ );
1557
+ this.captureAdClickIDsOnInit();
1558
+ this.transport = new Transport(
1559
+ {
1560
+ writeKey: this.config.write_key,
1561
+ apiHost: this.config.api_host,
1562
+ cellEndpoints: this.config.cell_endpoints,
1563
+ preferredRegion: this.config.preferred_region,
1564
+ autoRegionDetection: this.config.auto_region_detection,
1565
+ requestTimeout: this.config.request_timeout,
1566
+ retryFailedRequests: this.config.retry_failed_requests,
1567
+ maxRetries: this.config.max_retries,
1568
+ retryBackoffMultiplier: this.config.retry_backoff_multiplier
1569
+ },
1570
+ this.storage
1571
+ );
1572
+ this.config.active_cell = this.transport.getActiveCell();
1573
+ this.queue = new EventQueue(
1574
+ {
1575
+ batchSize: this.config.batch_size,
1576
+ batchInterval: this.config.batch_interval,
1577
+ enableOfflineMode: this.config.enable_offline_mode,
1578
+ maxOfflineEvents: this.config.max_offline_events
1579
+ },
1580
+ this.transport,
1581
+ this.storage
1582
+ );
1583
+ await this.initializePlugins();
1584
+ if (this.config.auto_page_view) {
1585
+ this.page();
1586
+ }
1587
+ logger.info("Aegis SDK initialized successfully");
1588
+ }
1589
+ buildConfig(writeKey, config) {
1590
+ return {
1591
+ ...DEFAULT_CONFIG,
1592
+ ...config,
1593
+ write_key: writeKey,
1594
+ initialized: true
1595
+ };
1596
+ }
1597
+ shouldRespectDNT(config) {
1598
+ const respectDNT = (config == null ? void 0 : config.respect_dnt) !== false;
1599
+ if (!respectDNT) return false;
1600
+ const dnt = navigator.doNotTrack || window.doNotTrack || navigator.msDoNotTrack;
1601
+ return dnt === "1" || dnt === "yes";
1602
+ }
1603
+ captureAdClickIDsOnInit() {
1604
+ if (!this.session) return;
1605
+ const adClickIDs = parseAdClickIDs();
1606
+ if (hasAdClickIDs(adClickIDs)) {
1607
+ this.session.setAdClickIDs(adClickIDs, window.location.href);
1608
+ logger.info("Ad click IDs captured on page load:", adClickIDs);
1609
+ }
1610
+ }
1611
+ async initializePlugins() {
1612
+ if (!this.config) return;
1613
+ for (const pluginName of this.config.plugins) {
1614
+ logger.debug(`Initializing plugin: ${pluginName}`);
1615
+ }
1616
+ await this.plugins.executeHook("init", this.config);
1617
+ }
1618
+ use(plugin) {
1619
+ var _a;
1620
+ this.plugins.register(plugin);
1621
+ if (((_a = this.config) == null ? void 0 : _a.initialized) && plugin.init) {
1622
+ Promise.resolve(plugin.init(this.config)).catch((error) => {
1623
+ logger.error(`Failed to initialize plugin "${plugin.name}":`, error);
1624
+ });
1625
+ }
1626
+ }
1627
+ track(eventName, properties) {
1628
+ if (!this.assertInitialized()) return;
1629
+ const event = {
1630
+ type: "track",
1631
+ event: eventName,
1632
+ properties: properties || {},
1633
+ messageId: generateMessageId(),
1634
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
1635
+ anonymousId: this.identity.getAnonymousId(),
1636
+ userId: this.identity.getUserId() || void 0,
1637
+ sessionId: this.session.getSessionId(),
1638
+ context: buildContext(this.config, this.session)
1639
+ };
1640
+ this.captureEvent(event);
1641
+ }
1642
+ identify(userId, traits) {
1643
+ if (!this.assertInitialized()) return;
1644
+ this.identity.setUserId(userId, traits);
1645
+ const event = {
1646
+ type: "identify",
1647
+ traits: traits || {},
1648
+ messageId: generateMessageId(),
1649
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
1650
+ anonymousId: this.identity.getAnonymousId(),
1651
+ userId,
1652
+ sessionId: this.session.getSessionId(),
1653
+ context: buildContext(this.config, this.session)
1654
+ };
1655
+ this.captureEvent(event);
1656
+ }
1657
+ page(name, properties) {
1658
+ if (!this.assertInitialized()) return;
1659
+ const event = {
1660
+ type: "page",
1661
+ name: name || document.title,
1662
+ properties: properties || {},
1663
+ messageId: generateMessageId(),
1664
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
1665
+ anonymousId: this.identity.getAnonymousId(),
1666
+ userId: this.identity.getUserId() || void 0,
1667
+ sessionId: this.session.getSessionId(),
1668
+ context: buildContext(this.config, this.session)
1669
+ };
1670
+ this.captureEvent(event);
1671
+ }
1672
+ group(groupId, traits) {
1673
+ if (!this.assertInitialized()) return;
1674
+ const event = {
1675
+ type: "group",
1676
+ groupId,
1677
+ traits: traits || {},
1678
+ messageId: generateMessageId(),
1679
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
1680
+ anonymousId: this.identity.getAnonymousId(),
1681
+ userId: this.identity.getUserId() || void 0,
1682
+ sessionId: this.session.getSessionId(),
1683
+ context: buildContext(this.config, this.session)
1684
+ };
1685
+ this.captureEvent(event);
1686
+ }
1687
+ alias(newUserId) {
1688
+ if (!this.assertInitialized()) return;
1689
+ const { previousId } = this.identity.alias(newUserId);
1690
+ const event = {
1691
+ type: "alias",
1692
+ previousId,
1693
+ messageId: generateMessageId(),
1694
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
1695
+ anonymousId: this.identity.getAnonymousId(),
1696
+ userId: newUserId,
1697
+ sessionId: this.session.getSessionId(),
1698
+ context: buildContext(this.config, this.session)
1699
+ };
1700
+ this.captureEvent(event);
1701
+ }
1702
+ async captureEvent(event) {
1703
+ var _a;
1704
+ if (((_a = this.config) == null ? void 0 : _a.enable_consent_mode) && this.consent) {
1705
+ if (event.type === "track" || event.type === "page") {
1706
+ if (!this.consent.hasConsent("analytics")) {
1707
+ logger.debug("Event blocked: analytics consent not granted");
1708
+ return;
1709
+ }
1710
+ }
1711
+ }
1712
+ logger.debug("Capturing event:", event);
1713
+ const transformedEvent = await this.plugins.executeHookChain(
1714
+ "beforeEventCapture",
1715
+ event
1716
+ );
1717
+ if (!transformedEvent) {
1718
+ logger.debug("Event cancelled by plugin");
1719
+ return;
1720
+ }
1721
+ this.queue.push(transformedEvent);
1722
+ this.session.incrementEventCount();
1723
+ await this.plugins.executeHook("afterEventCapture", transformedEvent);
1724
+ }
1725
+ reset() {
1726
+ if (!this.assertInitialized()) return;
1727
+ this.identity.reset();
1728
+ logger.info("User identity reset");
1729
+ }
1730
+ async flush() {
1731
+ if (!this.assertInitialized()) return;
1732
+ await this.queue.flush();
1733
+ }
1734
+ getAnonymousId() {
1735
+ if (!this.identity) return null;
1736
+ return this.identity.getAnonymousId();
1737
+ }
1738
+ getUserId() {
1739
+ if (!this.identity) return null;
1740
+ return this.identity.getUserId();
1741
+ }
1742
+ getSessionId() {
1743
+ if (!this.session) return null;
1744
+ return this.session.getSessionId();
1745
+ }
1746
+ debug(enable = true) {
1747
+ if (enable) {
1748
+ logger.enable();
1749
+ } else {
1750
+ logger.disable();
1751
+ }
1752
+ if (this.config) {
1753
+ this.config.debug = enable;
1754
+ }
1755
+ }
1756
+ setCell(cellEndpoint) {
1757
+ if (!this.config) {
1758
+ logger.warn("SDK not initialized");
1759
+ return;
1760
+ }
1761
+ const existingCell = this.config.cell_endpoints.find(
1762
+ (c) => c.region === cellEndpoint.region
1763
+ );
1764
+ if (existingCell) {
1765
+ Object.assign(existingCell, cellEndpoint);
1766
+ } else {
1767
+ this.config.cell_endpoints.push(cellEndpoint);
1768
+ }
1769
+ logger.info("Cell endpoint configured:", cellEndpoint);
1770
+ }
1771
+ getCellInfo() {
1772
+ if (!this.transport) return null;
1773
+ return {
1774
+ activeCell: this.transport.getActiveCell(),
1775
+ latencies: this.transport.getRegionLatencies()
1776
+ };
1777
+ }
1778
+ setConsent(preferences) {
1779
+ if (!this.consent) {
1780
+ logger.warn("Consent manager not initialized");
1781
+ return;
1782
+ }
1783
+ this.consent.setConsent(preferences);
1784
+ logger.info("Consent preferences updated");
1785
+ }
1786
+ grantConsent(category) {
1787
+ if (!this.consent) {
1788
+ logger.warn("Consent manager not initialized");
1789
+ return;
1790
+ }
1791
+ if (category) {
1792
+ this.consent.setConsent({ [category]: true });
1793
+ } else {
1794
+ this.consent.grantAll();
1795
+ }
1796
+ }
1797
+ denyConsent(category) {
1798
+ if (!this.consent) {
1799
+ logger.warn("Consent manager not initialized");
1800
+ return;
1801
+ }
1802
+ if (category) {
1803
+ this.consent.setConsent({ [category]: false });
1804
+ } else {
1805
+ this.consent.denyAll();
1806
+ }
1807
+ }
1808
+ hasConsent(category) {
1809
+ if (!this.consent) {
1810
+ return true;
1811
+ }
1812
+ return this.consent.hasConsent(category);
1813
+ }
1814
+ getConsentPreferences() {
1815
+ if (!this.consent) {
1816
+ return null;
1817
+ }
1818
+ return this.consent.getPreferences();
1819
+ }
1820
+ onConsentChange(callback) {
1821
+ if (!this.consent) {
1822
+ logger.warn("Consent manager not initialized");
1823
+ return () => {
1824
+ };
1825
+ }
1826
+ return this.consent.onChange(callback);
1827
+ }
1828
+ assertInitialized() {
1829
+ var _a;
1830
+ if (!((_a = this.config) == null ? void 0 : _a.initialized)) {
1831
+ logger.warn("SDK not initialized. Call aegis.init() first.");
1832
+ return false;
1833
+ }
1834
+ return true;
1835
+ }
1836
+ destroy() {
1837
+ if (this.queue) {
1838
+ this.queue.destroy();
1839
+ }
1840
+ if (this.session) {
1841
+ this.session.destroy();
1842
+ }
1843
+ if (this.transport) {
1844
+ this.transport.destroy();
1845
+ }
1846
+ this.plugins.clear();
1847
+ logger.info("SDK destroyed");
1848
+ }
1849
+ }
1850
+ export {
1851
+ Aegis as A,
1852
+ logger as l
1853
+ };
1854
+ //# sourceMappingURL=analytics-B11keZ55.mjs.map