getu-attribution-v2-sdk 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -102,7 +102,7 @@ await trackPageView({ category: "homepage" });
102
102
  | `data-auto-track` | boolean | `false` | Enable auto-tracking (forms, links) |
103
103
  | `data-auto-track-page-view` | boolean | `false` | Enable auto page view tracking (includes SPA) |
104
104
  | `data-batch-size` | number | `100` | Number of events per batch |
105
- | `data-batch-interval` | number | `5000` | Batch interval in milliseconds |
105
+ | `data-batch-interval` | number | `2000` | Batch interval in milliseconds |
106
106
  | `data-auto-clean-utm` | boolean | `true` | Remove UTM params from URL after capture |
107
107
 
108
108
  ### Configuration Object
@@ -117,7 +117,7 @@ interface SDKConfig {
117
117
 
118
118
  // Batch Settings
119
119
  batchSize?: number; // Default: 100
120
- batchInterval?: number; // Default: 5000 (ms)
120
+ batchInterval?: number; // Default: 2000 (ms)
121
121
  maxRetries?: number; // Default: 3
122
122
  retryDelay?: number; // Default: 1000 (ms)
123
123
 
@@ -264,6 +264,69 @@ await trackFormSubmit("user_123", {
264
264
  });
265
265
  ```
266
266
 
267
+ ### Track Video Play
268
+
269
+ ```javascript
270
+ // Basic
271
+ await trackVideoPlay();
272
+
273
+ // With user ID
274
+ await trackVideoPlay("user_123");
275
+
276
+ // With custom data
277
+ await trackVideoPlay("user_123", {
278
+ video_id: "video_123",
279
+ video_title: "Introduction Video",
280
+ duration: 120,
281
+ position: 30,
282
+ });
283
+ ```
284
+
285
+ ### Track Email Verification
286
+
287
+ ```javascript
288
+ await trackEmailVerification("user_123", {
289
+ email: "user@example.com",
290
+ verification_method: "email_link",
291
+ });
292
+ ```
293
+
294
+ ### Track Product View
295
+
296
+ ```javascript
297
+ // Basic
298
+ await trackProductView();
299
+
300
+ // With user ID
301
+ await trackProductView("user_123");
302
+
303
+ // With product data
304
+ await trackProductView("user_123", {
305
+ product_id: "prod_123",
306
+ product_name: "Widget",
307
+ category: "electronics",
308
+ price: 29.99,
309
+ });
310
+ ```
311
+
312
+ ### Track Add to Cart
313
+
314
+ ```javascript
315
+ // Basic
316
+ await trackAddToCart();
317
+
318
+ // With user ID
319
+ await trackAddToCart("user_123");
320
+
321
+ // With cart data
322
+ await trackAddToCart("user_123", {
323
+ product_id: "prod_123",
324
+ product_name: "Widget",
325
+ quantity: 2,
326
+ price: 29.99,
327
+ });
328
+ ```
329
+
267
330
  ### Track Custom Event
268
331
 
269
332
  ```javascript
@@ -558,6 +621,54 @@ Track a signup event (sent immediately).
558
621
 
559
622
  Track a form submission event (sent immediately).
560
623
 
624
+ #### `trackVideoPlay(tracking_user_id?, videoData?): Promise<void>`
625
+
626
+ Track a video play event.
627
+
628
+ ```javascript
629
+ await trackVideoPlay("user_123", {
630
+ video_id: "video_123",
631
+ video_title: "Introduction Video",
632
+ duration: 120,
633
+ });
634
+ ```
635
+
636
+ #### `trackEmailVerification(tracking_user_id, verificationData?): Promise<void>`
637
+
638
+ Track an email verification event (sent immediately).
639
+
640
+ ```javascript
641
+ await trackEmailVerification("user_123", {
642
+ email: "user@example.com",
643
+ verification_method: "email_link",
644
+ });
645
+ ```
646
+
647
+ #### `trackProductView(tracking_user_id?, productData?): Promise<void>`
648
+
649
+ Track a product view event.
650
+
651
+ ```javascript
652
+ await trackProductView("user_123", {
653
+ product_id: "prod_123",
654
+ product_name: "Widget",
655
+ category: "electronics",
656
+ });
657
+ ```
658
+
659
+ #### `trackAddToCart(tracking_user_id?, cartData?): Promise<void>`
660
+
661
+ Track an add to cart event.
662
+
663
+ ```javascript
664
+ await trackAddToCart("user_123", {
665
+ product_id: "prod_123",
666
+ product_name: "Widget",
667
+ quantity: 2,
668
+ price: 29.99,
669
+ });
670
+ ```
671
+
561
672
  ### Attribution Functions
562
673
 
563
674
  #### `getAttributionData(): AttributionData | null`
@@ -24,6 +24,10 @@ export declare class AttributionSDK {
24
24
  trackLogin(tracking_user_id: string, loginData?: Record<string, any>): Promise<void>;
25
25
  trackSignup(tracking_user_id: string, signupData?: Record<string, any>): Promise<void>;
26
26
  trackFormSubmit(tracking_user_id?: string, formData?: Record<string, any>): Promise<void>;
27
+ trackVideoPlay(tracking_user_id?: string, videoData?: Record<string, any>): Promise<void>;
28
+ trackEmailVerification(tracking_user_id: string, verificationData?: Record<string, any>): Promise<void>;
29
+ trackProductView(tracking_user_id?: string, productData?: Record<string, any>): Promise<void>;
30
+ trackAddToCart(tracking_user_id?: string, cartData?: Record<string, any>): Promise<void>;
27
31
  getAttributionData(): AttributionData | null;
28
32
  addUTMToURL(url: string): string;
29
33
  getCurrentUTMParams(): Record<string, string>;
@@ -1 +1 @@
1
- {"version":3,"file":"AttributionSDK.d.ts","sourceRoot":"","sources":["../../src/core/AttributionSDK.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"AttributionSDK.d.ts","sourceRoot":"","sources":["../../src/core/AttributionSDK.ts"],"names":[],"mappings":"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"}
@@ -17,7 +17,7 @@ export class AttributionSDK {
17
17
  this.config = {
18
18
  apiEndpoint: defaultEndpoint,
19
19
  batchSize: 100,
20
- batchInterval: 5000,
20
+ batchInterval: 2000,
21
21
  maxRetries: 3,
22
22
  retryDelay: 1000,
23
23
  enableDebug: false,
@@ -215,6 +215,22 @@ export class AttributionSDK {
215
215
  async trackFormSubmit(tracking_user_id, formData) {
216
216
  await this.trackEvent(EventType.FORM_SUBMIT, formData, tracking_user_id);
217
217
  }
218
+ // Track video play
219
+ async trackVideoPlay(tracking_user_id, videoData) {
220
+ await this.trackEvent(EventType.VIDEO_PLAY, videoData, tracking_user_id);
221
+ }
222
+ // Track email verification
223
+ async trackEmailVerification(tracking_user_id, verificationData) {
224
+ await this.trackEvent(EventType.EMAIL_VERIFICATION, verificationData, tracking_user_id);
225
+ }
226
+ // Track product view
227
+ async trackProductView(tracking_user_id, productData) {
228
+ await this.trackEvent(EventType.PRODUCT_VIEW, productData, tracking_user_id);
229
+ }
230
+ // Track add to cart
231
+ async trackAddToCart(tracking_user_id, cartData) {
232
+ await this.trackEvent(EventType.ADD_TO_CART, cartData, tracking_user_id);
233
+ }
218
234
  // Get attribution data
219
235
  getAttributionData() {
220
236
  return this.storage.getUTMData();
@@ -1 +1 @@
1
- !function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.GetuAIAttribution=e():t.GetuAIAttribution=e()}(this,()=>(()=>{"use strict";var t,e,i={d:(t,e)=>{for(var r in e)i.o(e,r)&&!i.o(t,r)&&Object.defineProperty(t,r,{enumerable:!0,get:e[r]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e)},r={};i.d(r,{default:()=>N}),function(t){t.PAGE_VIEW="page_view",t.VIDEO_PLAY="video_play",t.FORM_SUBMIT="form_submit",t.EMAIL_VERIFICATION="email_verification",t.LOGIN="login",t.SIGNUP="signup",t.PRODUCT_VIEW="product_view",t.ADD_TO_CART="add_to_cart",t.PURCHASE="purchase"}(t||(t={})),function(t){t.USD="USD"}(e||(e={}));const n="https://attribution.getu.ai/attribution/api",s=[t.PURCHASE,t.LOGIN,t.SIGNUP,t.FORM_SUBMIT,t.EMAIL_VERIFICATION];function a(){return Math.floor(Date.now()/1e3)}function o(){try{const t="__localStorage_test__";return localStorage.setItem(t,t),localStorage.removeItem(t),!0}catch{return!1}}class c{constructor(t=!0){this.enabled=t}debug(t,...e){this.enabled&&console.debug&&console.debug(`[GetuAI Debug] ${t}`,...e)}info(t,...e){this.enabled&&console.info&&console.info(`[GetuAI Info] ${t}`,...e)}warn(t,...e){this.enabled&&console.warn&&console.warn(`[GetuAI Warn] ${t}`,...e)}error(t,...e){this.enabled&&console.error&&console.error(`[GetuAI Error] ${t}`,...e)}}function u(){return document.referrer||""}function l(){return window.location.href}function h(){return document.title||""}function d(t,e){try{const i=new URL(t);return Object.entries(e).forEach(([t,e])=>{e&&!i.searchParams.has(t)&&i.searchParams.set(t,e)}),i.toString()}catch(e){return t}}function g(t,e=["utm_source","utm_medium","utm_campaign"]){const i={};return e.forEach(e=>{t[e]&&(i[e]=t[e])}),i}function m(t){try{const e=t||window.location.href;return new URL(e).search}catch(t){return""}}function p(t){try{const e=t||window.location.href,i=new URL(e),r={};return i.searchParams.forEach((t,e)=>{r[e]=t}),r}catch(t){return{}}}class f{constructor(t){this.logger=t}get(t){try{if(!o())return this.logger.warn("LocalStorage not supported"),null;const e=localStorage.getItem(t);return null===e?null:JSON.parse(e)}catch(t){return this.logger.error("Error reading from localStorage:",t),null}}set(t,e){try{if(!o())return void this.logger.warn("LocalStorage not supported");localStorage.setItem(t,JSON.stringify(e))}catch(t){this.logger.error("Error writing to localStorage:",t),this.handleQuotaExceeded()}}remove(t){try{o()&&localStorage.removeItem(t)}catch(t){this.logger.error("Error removing from localStorage:",t)}}clear(){try{o()&&localStorage.clear()}catch(t){this.logger.error("Error clearing localStorage:",t)}}handleQuotaExceeded(){try{const t=Object.keys(localStorage).filter(t=>t.startsWith("attribution_"));if(t.length>0){t.sort((t,e)=>{const i=this.get(t),r=this.get(e);return(i?.expiresAt||0)-(r?.expiresAt||0)});const e=Math.ceil(.2*t.length);t.slice(0,e).forEach(t=>{this.remove(t)}),this.logger.info(`Cleaned up ${e} old attribution records`)}}catch(t){this.logger.error("Error during quota cleanup:",t)}}}class w{constructor(t){this.dbName="attribution_events",this.dbVersion=1,this.storeName="events",this.db=null,this.logger=t}async init(){if("indexedDB"in window)return new Promise((t,e)=>{const i=indexedDB.open(this.dbName,this.dbVersion);i.onerror=()=>{this.logger.error("Failed to open IndexedDB:",i.error),e(i.error)},i.onsuccess=()=>{this.db=i.result,this.logger.info("IndexedDB initialized successfully"),t()},i.onupgradeneeded=t=>{const e=t.target.result;if(!e.objectStoreNames.contains(this.storeName)){const t=e.createObjectStore(this.storeName,{keyPath:"id",autoIncrement:!0});t.createIndex("timestamp","timestamp",{unique:!1}),t.createIndex("sent","sent",{unique:!1}),t.createIndex("queued_at","queued_at",{unique:!1})}}});this.logger.warn("IndexedDB not supported")}async addEvent(t){if(!this.db)throw new Error("IndexedDB not initialized");return new Promise((e,i)=>{const r=this.db.transaction([this.storeName],"readwrite").objectStore(this.storeName),n={...t,queued_at:Date.now(),sent:!1},s=r.add(n);s.onsuccess=()=>{this.logger.debug("Event added to IndexedDB queue"),e()},s.onerror=()=>{this.logger.error("Failed to add event to IndexedDB:",s.error),i(s.error)}})}async getUnsentEvents(t=100){return this.db?new Promise((e,i)=>{const r=this.db.transaction([this.storeName],"readonly").objectStore(this.storeName).index("sent").getAll(IDBKeyRange.only(!1),t);r.onsuccess=()=>{const t=r.result.map(t=>{const{queued_at:e,sent:i,...r}=t;return r});e(t)},r.onerror=()=>{this.logger.error("Failed to get unsent events:",r.error),i(r.error)}}):[]}async markEventsAsSent(t){if(this.db&&0!==t.length)return new Promise((e,i)=>{const r=this.db.transaction([this.storeName],"readwrite").objectStore(this.storeName);let n=0,s=!1;t.forEach(a=>{const o=r.get(a);o.onsuccess=()=>{if(o.result){const a={...o.result,sent:!0},c=r.put(a);c.onsuccess=()=>{n++,n!==t.length||s||e()},c.onerror=()=>{s=!0,this.logger.error("Failed to mark event as sent:",c.error),i(c.error)}}else n++,n!==t.length||s||e()},o.onerror=()=>{s=!0,this.logger.error("Failed to get event for marking as sent:",o.error),i(o.error)}})})}async cleanupOldEvents(t=6048e5){if(!this.db)return;const e=Date.now()-t;return new Promise((t,i)=>{const r=this.db.transaction([this.storeName],"readwrite").objectStore(this.storeName).index("queued_at").openCursor(IDBKeyRange.upperBound(e));r.onsuccess=()=>{const e=r.result;e?(e.delete(),e.continue()):(this.logger.info("Old events cleanup completed"),t())},r.onerror=()=>{this.logger.error("Failed to cleanup old events:",r.error),i(r.error)}})}async getQueueSize(){return this.db?new Promise((t,e)=>{const i=this.db.transaction([this.storeName],"readonly").objectStore(this.storeName).count();i.onsuccess=()=>{t(i.result)},i.onerror=()=>{this.logger.error("Failed to get queue size:",i.error),e(i.error)}}):0}async clear(){if(this.db)return new Promise((t,e)=>{const i=this.db.transaction([this.storeName],"readwrite").objectStore(this.storeName).clear();i.onsuccess=()=>{this.logger.info("IndexedDB queue cleared"),t()},i.onerror=()=>{this.logger.error("Failed to clear IndexedDB queue:",i.error),e(i.error)}})}}class y{constructor(t){this.UTM_STORAGE_KEY="attribution_utm_data",this.SESSION_STORAGE_KEY="attribution_session",this.logger=t,this.localStorage=new f(t),this.indexedDB=new w(t)}async init(){await this.indexedDB.init()}storeUTMData(t){try{const e=this.getUTMData(),i={utm_source:"",utm_medium:"",utm_campaign:"",utm_term:"",utm_content:"",timestamp:Date.now()},r={firstTouch:e?.firstTouch||i,lastTouch:e?.lastTouch||i,touchpoints:e?.touchpoints||[],...t,expiresAt:Date.now()+2592e6};this.localStorage.set(this.UTM_STORAGE_KEY,r),this.logger.debug("UTM data stored successfully:",{firstTouch:r.firstTouch,lastTouch:r.lastTouch,touchpointsCount:r.touchpoints.length,expiresAt:new Date(r.expiresAt).toISOString()})}catch(t){this.logger.error("Failed to store UTM data:",t)}}getUTMData(){const t=this.localStorage.get(this.UTM_STORAGE_KEY);return t&&t.expiresAt&&t.expiresAt>Date.now()?t:(t&&this.localStorage.remove(this.UTM_STORAGE_KEY),null)}storeSession(t){this.localStorage.set(this.SESSION_STORAGE_KEY,t)}getSession(){return this.localStorage.get(this.SESSION_STORAGE_KEY)}async queueEvent(t){try{await this.indexedDB.addEvent(t)}catch(t){throw this.logger.error("Failed to queue event:",t),t}}async getUnsentEvents(t=100){return await this.indexedDB.getUnsentEvents(t)}async markEventsAsSent(t){await this.indexedDB.markEventsAsSent(t)}async getQueueSize(){return await this.indexedDB.getQueueSize()}async cleanupOldEvents(){await this.indexedDB.cleanupOldEvents()}async clearQueue(){await this.indexedDB.clear()}cleanupExpiredData(){this.getUTMData()}}class S{constructor(t,e,i,r=100,n=5e3,s=3,a=1e3,o){this.queue=[],this.processing=!1,this.batchTimer=null,this.logger=t,this.apiKey=e,this.apiEndpoint=i,this.batchSize=r,this.batchInterval=n,this.maxRetries=s,this.retryDelay=a,this.sendEvents=o,this.debouncedProcess=function(t){let e;return(...i)=>{clearTimeout(e),e=setTimeout(()=>t(...i),100)}}(this.process.bind(this))}add(t){this.queue.push(t),this.logger.debug(`Event added to queue: ${t.event_type}`),s.includes(t.event_type)?(this.logger.debug(`Immediate event detected: ${t.event_type}, processing immediately`),this.processImmediate(t)):this.scheduleBatchProcessing()}async process(){if(!this.processing&&0!==this.queue.length){this.processing=!0;try{const t=this.queue.splice(0,this.batchSize);this.logger.debug(`Processing ${t.length} events from queue`),await this.sendEvents(t),this.logger.info(`Successfully processed ${t.length} events`)}catch(t){this.logger.error("Failed to process events:",t);const e=this.queue.splice(0,this.batchSize);return this.queue.unshift(...e),void setTimeout(()=>{this.processing=!1,this.debouncedProcess()},this.retryDelay)}this.processing=!1,this.queue.length>0&&this.debouncedProcess()}}async processImmediate(t){try{this.logger.debug(`Processing immediate event: ${t.event_type}`),await this.sendEvents([t]),this.logger.info(`Immediate event processed successfully: ${t.event_type}`)}catch(e){this.logger.error(`Failed to process immediate event: ${t.event_type}`,e),this.queue.unshift(t)}}scheduleBatchProcessing(){this.batchTimer&&clearTimeout(this.batchTimer),this.batchTimer=setTimeout(()=>{this.debouncedProcess()},this.batchInterval)}clear(){this.queue=[],this.batchTimer&&(clearTimeout(this.batchTimer),this.batchTimer=null),this.processing=!1,this.logger.info("Event queue cleared")}size(){return this.queue.length}getStats(){return{size:this.queue.length,processing:this.processing}}async flush(){for(this.logger.info("Flushing event queue");this.queue.length>0;)await this.process()}}class b{constructor(t,e,i,r=3,n=1e3){this.logger=t,this.apiKey=e,this.apiEndpoint=i,this.maxRetries=r,this.retryDelay=n}async sendEvents(t){if(0===t.length)return;const e={events:t.map(t=>({event_id:t.event_id,event_type:t.event_type,tracking_user_id:t.tracking_user_id,utm_source:t.utm_source||null,utm_medium:t.utm_medium||null,utm_campaign:t.utm_campaign||null,utm_term:t.utm_term||null,utm_content:t.utm_content||null,revenue:t.revenue||null,currency:t.currency||null,event_data:t.event_data||null,context:t.context||null,timestamp:t.timestamp||a()}))};await async function(t,e=3,i=1e3){let r;for(let n=0;n<=e;n++)try{return await t()}catch(t){if(r=t,n===e)throw r;const s=i*Math.pow(2,n);await new Promise(t=>setTimeout(t,s))}throw r}(async()=>{const i=await fetch(`${this.apiEndpoint}/attribution/events`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`},body:JSON.stringify(e)});if(!i.ok){const t=await i.text();throw new Error(`HTTP ${i.status}: ${t}`)}const r=await i.json();return this.logger.debug("Events sent successfully:",r),{result:r,sentEvents:t}},this.maxRetries,this.retryDelay)}async sendSingleEvent(t){await this.sendEvents([t])}async testConnection(){try{return(await fetch(`${this.apiEndpoint}/health`,{method:"GET",headers:{Authorization:`Bearer ${this.apiKey}`}})).ok}catch(t){return this.logger.error("Connection test failed:",t),!1}}}class T{constructor(t){this.session=null,this.initialized=!1,this.autoTrackEnabled=!1,this.pageViewTrackTimes=new Map,this.spaTrackingEnabled=!1,this.lastTrackedPath="",this.originalPushState=null,this.originalReplaceState=null,this.popstateHandler=null,this.config={apiEndpoint:n,batchSize:100,batchInterval:5e3,maxRetries:3,retryDelay:1e3,enableDebug:!1,autoTrack:!1,autoTrackPageView:!1,sessionTimeout:18e5,enableCrossDomainUTM:!0,crossDomainUTMParams:["utm_source","utm_medium","utm_campaign","utm_term","utm_content"],excludeDomains:[],autoCleanUTM:!0,pageViewDebounceInterval:5e3,...t},this.logger=new c(this.config.enableDebug),this.storage=new y(this.logger),this.httpClient=new b(this.logger,this.config.apiKey,this.config.apiEndpoint||n,this.config.maxRetries,this.config.retryDelay),this.queue=new S(this.logger,this.config.apiKey,this.config.apiEndpoint||n,this.config.batchSize,this.config.batchInterval,this.config.maxRetries,this.config.retryDelay,t=>this.httpClient.sendEvents(t))}async init(){if(this.initialized)this.logger.warn("SDK already initialized");else try{this.logger.info("Initializing GetuAI Attribution SDK"),await this.storage.init(),this.initializeSession(),this.extractAndStoreUTMData(),this.config.autoTrack&&this.setupAutoTracking(),this.setupNetworkHandlers(),this.setupVisibilityHandlers(),this.setupBeforeUnloadHandler(),this.initialized=!0,this.logger.info("🚀 GetuAI Attribution SDK initialized successfully"),this.logger.info("📄 Auto track page view = "+this.config.autoTrackPageView),this.config.autoTrackPageView&&(this.logger.info("📄 Auto track page view enabled (including SPA route tracking)"),this.lastTrackedPath=this.getCurrentPath(),this.setupSPATracking(),setTimeout(()=>{this.trackPageView().then(()=>{this.logger.info("✅ Auto track page view completed")}).catch(t=>this.logger.error("❌ Auto track page view failed:",t))},100))}catch(t){throw this.logger.error("Failed to initialize SDK:",t),t}}async trackEvent(t,i,r,n,s=e.USD){if(this.initialized)try{const e=l();let o=null;try{o=await this.fetchPublicIP()}catch(t){}const c={domain:"undefined"!=typeof window?window.location.hostname:null,path:"undefined"!=typeof window?window.location.pathname:null,title:h(),referrer:u(),url:e.split("?")[0],querystring:m(e),query_params:p(e),ip_address:o},d={session_id:this.session?.sessionId,start_time:this.session?.startTime,last_activity:this.session?.lastActivity,page_views:this.session?.pageViews},g={event_id:"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(t){const e=16*Math.random()|0;return("x"===t?e:3&e|8).toString(16)}),event_type:t,tracking_user_id:r,timestamp:a(),event_data:i,context:{page:c,session:d},revenue:n,currency:s,...this.getUTMParams()};this.logger.debug(`Tracking event: ${t}`,g),this.queue.add(g)}catch(e){this.logger.error(`Failed to track event ${t}:`,e)}else this.logger.warn("SDK not initialized, event not tracked")}async trackPageView(e,i){const r=l(),n=r.split("?")[0],s=Date.now(),a=this.config.pageViewDebounceInterval||5e3,o=this.pageViewTrackTimes.get(n);if(o&&s-o<a)return void this.logger.debug(`Page view debounced: ${n} (last tracked ${s-o}ms ago)`);const c={url:r,title:h(),referrer:u(),user_agent:navigator.userAgent||"",...e};await this.trackEvent(t.PAGE_VIEW,c,i),this.pageViewTrackTimes.set(n,s),this.cleanupPageViewTrackTimes()}cleanupPageViewTrackTimes(){const t=Date.now()-36e5;for(const[e,i]of this.pageViewTrackTimes.entries())i<t&&this.pageViewTrackTimes.delete(e)}async fetchPublicIP(){try{const t=new AbortController,e=setTimeout(()=>t.abort(),2e3),i=await fetch("https://api.ipify.org?format=json",{signal:t.signal,headers:{Accept:"application/json"}});if(clearTimeout(e),!i.ok)return null;const r=await i.json();return"string"==typeof r?.ip?r.ip:null}catch(t){return this.logger.debug("Public IP fetch failed",t),null}}async trackPurchase(i,r,n=e.USD,s){await this.trackEvent(t.PURCHASE,s,i,r,n)}async trackLogin(e,i){await this.trackEvent(t.LOGIN,i,e)}async trackSignup(e,i){await this.trackEvent(t.SIGNUP,i,e)}async trackFormSubmit(e,i){await this.trackEvent(t.FORM_SUBMIT,i,e)}getAttributionData(){return this.storage.getUTMData()}addUTMToURL(t){if(!this.config.enableCrossDomainUTM)return t;const e=this.getAttributionData();return e?d(t,g(e.lastTouch,this.config.crossDomainUTMParams)):t}getCurrentUTMParams(){const t=this.getAttributionData();return t?g(t.lastTouch,this.config.crossDomainUTMParams):{}}getUTMParams(){const t=this.getAttributionData();if(!t)return this.logger.debug("No attribution data available for UTM params"),{};const e={utm_source:t.lastTouch.utm_source||null,utm_medium:t.lastTouch.utm_medium||null,utm_campaign:t.lastTouch.utm_campaign||null,utm_term:t.lastTouch.utm_term||null,utm_content:t.lastTouch.utm_content||null},i={};return e.utm_source&&""!==e.utm_source.trim()?i.utm_source=e.utm_source:i.utm_source=null,e.utm_medium&&""!==e.utm_medium.trim()?i.utm_medium=e.utm_medium:i.utm_medium=null,e.utm_campaign&&""!==e.utm_campaign.trim()?i.utm_campaign=e.utm_campaign:i.utm_campaign=null,e.utm_term&&""!==e.utm_term.trim()?i.utm_term=e.utm_term:i.utm_term=null,e.utm_content&&""!==e.utm_content.trim()?i.utm_content=e.utm_content:i.utm_content=null,this.logger.debug("UTM params for event:",i),i}initializeSession(){const t=this.storage.getSession(),e=Date.now();t&&e-t.lastActivity<this.config.sessionTimeout?this.session={...t,lastActivity:e}:this.session={sessionId:`session_${Date.now()}_${Math.random().toString(36).substr(2,9)}`,startTime:e,lastActivity:e,pageViews:0},this.storage.storeSession(this.session),this.logger.debug("Session initialized:",this.session)}extractAndStoreUTMData(){const t=l(),e=function(t){const e=function(t){const e={};try{new URL(t).searchParams.forEach((t,i)=>{e[i]=t})}catch(t){}return e}(t),i={};return["utm_source","utm_medium","utm_campaign","utm_term","utm_content"].forEach(t=>{e[t]&&""!==e[t].trim()&&(i[t]=e[t].trim())}),i}(t);if(this.logger.debug("Extracting UTM params from URL:",t),this.logger.debug("Found UTM params:",e),0===Object.keys(e).length)return void this.logger.debug("No UTM parameters found in URL");const i={utm_source:e.utm_source||"",utm_medium:e.utm_medium||"",utm_campaign:e.utm_campaign||"",utm_term:e.utm_term||"",utm_content:e.utm_content||"",timestamp:Date.now()},r=this.getAttributionData(),n={firstTouch:r?.firstTouch||i,lastTouch:i,touchpoints:r?.touchpoints||[],expiresAt:Date.now()+2592e6};r&&r.lastTouch.utm_source===i.utm_source&&r.lastTouch.utm_campaign===i.utm_campaign||n.touchpoints.push(i),this.storage.storeUTMData(n),this.logger.info("UTM data extracted and stored successfully:",i),this.config.autoCleanUTM&&function(){try{const t=new URL(window.location.href);let e=!1;["utm_source","utm_medium","utm_campaign","utm_term","utm_content"].forEach(i=>{t.searchParams.has(i)&&(t.searchParams.delete(i),e=!0)}),e&&window.history.replaceState({},document.title,t.toString())}catch(t){console.warn("Failed to clean URL:",t)}}()}setupAutoTracking(){this.autoTrackEnabled=!0,this.setupFormTracking(),this.setupLinkTracking(),this.logger.info("Auto-tracking enabled")}setupFormTracking(){document.addEventListener("submit",e=>{try{const i=e.target;if(!i)return;const r=this.serializeFormFields(i);this.trackEvent(t.FORM_SUBMIT,{...r,form_id:i.id||i.name,form_action:i.action,form_method:i.method})}catch(t){this.logger.error("Failed to auto-track form submit:",t)}})}serializeFormFields(t){const e={};try{const i=new FormData(t);for(const[t,r]of i.entries()){const i=this.serializeFormValue(r);if(Object.prototype.hasOwnProperty.call(e,t)){const r=e[t];Array.isArray(r)?(r.push(i),e[t]=r):e[t]=[r,i]}else e[t]=i}const r=Array.from(t.elements),n=new Map;for(const t of r){const e=t.name;e&&!t.disabled&&(n.has(e)||n.set(e,[]),n.get(e).push(t))}n.forEach((t,i)=>{const r=t.some(t=>"radio"===t.type),n=t.some(t=>"checkbox"===t.type),s=t.some(t=>"file"===t.type),a=t.some(t=>"SELECT"===t.tagName&&t.multiple),o=t.some(t=>"password"===t.type);if(n){const r=t.filter(t=>"checkbox"===t.type).filter(t=>t.checked).map(t=>t.value||"on");return void(Object.prototype.hasOwnProperty.call(e,i)?Array.isArray(e[i])||(e[i]=[e[i],...r]):e[i]=r)}if(r){const r=t.filter(t=>"radio"===t.type).find(t=>t.checked);return void(Object.prototype.hasOwnProperty.call(e,i)||(e[i]=r?r.value:null))}if(a){const r=t.find(t=>"SELECT"===t.tagName&&t.multiple);if(r){const t=Array.from(r.selectedOptions).map(t=>t.value);return void(Object.prototype.hasOwnProperty.call(e,i)||(e[i]=t))}}if(s){const r=t.find(t=>"file"===t.type);if(r){const t=r.files?Array.from(r.files):[];return void(Object.prototype.hasOwnProperty.call(e,i)||(e[i]=t.map(t=>this.serializeFormValue(t))))}}if(o)Object.prototype.hasOwnProperty.call(e,i)?e[i]="string"==typeof e[i]?"*****":e[i]:e[i]="*****";else if(!Object.prototype.hasOwnProperty.call(e,i)){const r=t[0];if("SELECT"===r.tagName){const t=r;e[i]=t.multiple?Array.from(t.selectedOptions).map(t=>t.value):t.value}else r.type,e[i]=r.value??""}})}catch(t){this.logger.error("Failed to serialize form fields:",t)}return e}serializeFormValue(t){return t instanceof File?{file_name:t.name,file_size:t.size,file_type:t.type}:t}setupLinkTracking(){document.addEventListener("click",t=>{const e=t.target.closest("a");e&&function(t){try{const e=new URL(t),i=window.location.hostname;return e.hostname!==i}catch(t){return!1}}(e.href)&&this.handleCrossDomainUTM(e,t)})}handleCrossDomainUTM(t,e){if(!this.config.enableCrossDomainUTM)return;const i=t.href;if(function(t,e=[]){try{const i=new URL(t).hostname.toLowerCase();return e.some(t=>{const e=t.toLowerCase();return i===e||i.endsWith(`.${e}`)})}catch(t){return!1}}(i,this.config.excludeDomains))return void this.logger.debug(`Domain excluded from UTM passing: ${i}`);const r=this.getAttributionData();if(!r)return void this.logger.debug("No UTM data available for cross-domain passing");const n=g(r.lastTouch,this.config.crossDomainUTMParams);if(0===Object.keys(n).length)return void this.logger.debug("No UTM parameters to pass");const s=d(i,n);s!==i&&(t.href=s,this.logger.debug("UTM parameters added to external link:",{original:i,enhanced:s,utmParams:n}),this.logger.debug("Cross-domain UTM passed:",{link_url:s,original_url:i,utm_params_passed:n}))}setupNetworkHandlers(){window.addEventListener("online",()=>{this.logger.info("Network connection restored"),this.queue.flush()}),window.addEventListener("offline",()=>{this.logger.warn("Network connection lost")})}setupVisibilityHandlers(){document.addEventListener("visibilitychange",()=>{"visible"===document.visibilityState&&this.updateSessionActivity()})}setupBeforeUnloadHandler(){window.addEventListener("beforeunload",()=>{this.updateSessionActivity(),this.queue.flush()})}getCurrentPath(){return"undefined"==typeof window?"":window.location.pathname+window.location.search}setupSPATracking(){if("undefined"==typeof window||"undefined"==typeof history)return void this.logger.warn("⚠️ SPA tracking not available in this environment");if(this.spaTrackingEnabled)return void this.logger.warn("⚠️ SPA tracking already enabled");this.spaTrackingEnabled=!0,this.lastTrackedPath=this.getCurrentPath(),this.originalPushState=history.pushState.bind(history),this.originalReplaceState=history.replaceState.bind(history);const t=t=>{const e=this.getCurrentPath();e!==this.lastTrackedPath?(this.logger.debug(`🔄 [SPA] Route change detected (${t}): ${this.lastTrackedPath} -> ${e}`),this.lastTrackedPath=e,setTimeout(()=>{this.trackPageView().then(()=>{this.logger.debug(`✅ [SPA] Page view tracked for: ${e}`)}).catch(t=>{this.logger.error("❌ [SPA] Failed to track page view:",t)})},100)):this.logger.debug(`🔄 [SPA] Route change detected (${t}) but path unchanged: ${e}`)};history.pushState=(e,i,r)=>{const n=this.originalPushState(e,i,r);return t("pushState"),n},history.replaceState=(e,i,r)=>{const n=this.originalReplaceState(e,i,r);return t("replaceState"),n},this.popstateHandler=()=>{t("popstate")},window.addEventListener("popstate",this.popstateHandler),this.logger.info("🔄 SPA tracking setup completed")}cleanupSPATracking(){this.spaTrackingEnabled&&(this.originalPushState&&(history.pushState=this.originalPushState,this.originalPushState=null),this.originalReplaceState&&(history.replaceState=this.originalReplaceState,this.originalReplaceState=null),this.popstateHandler&&(window.removeEventListener("popstate",this.popstateHandler),this.popstateHandler=null),this.spaTrackingEnabled=!1,this.logger.info("🔄 SPA tracking cleaned up"))}updateSessionActivity(){this.session&&(this.session.lastActivity=Date.now(),this.storage.storeSession(this.session))}async flush(){await this.queue.flush()}getStatus(){return{initialized:this.initialized,session:this.session,queueSize:this.queue.size(),online:navigator.onLine,crossDomainUTM:{enabled:this.config.enableCrossDomainUTM||!0,currentParams:this.getCurrentUTMParams()},spaTracking:{enabled:this.spaTrackingEnabled,currentPath:this.lastTrackedPath}}}destroy(){this.queue.clear(),this.autoTrackEnabled=!1,this.cleanupSPATracking(),this.initialized=!1,this.logger.info("🗑️ SDK destroyed")}}let v=null;async function _(t){if(v)return console.warn("GetuAI SDK: Already initialized"),v;try{if(v=new T(t),await v.init(),t.enableDebug&&(window.GetuAISDK=v),console.log("GetuAI Attribution SDK initialized successfully"),"undefined"!=typeof window){const t=new CustomEvent("getuaiSDKReady",{detail:{sdk:v}});window.dispatchEvent(t)}return v}catch(t){if(console.error("GetuAI SDK: Failed to initialize:",t),"undefined"!=typeof window){const e=new CustomEvent("getuaiSDKError",{detail:{error:t}});window.dispatchEvent(e)}throw t}}function E(){return v}function D(){return new Promise((t,e)=>{if(v)return void t(v);const i=e=>{window.removeEventListener("getuaiSDKReady",i),window.removeEventListener("getuaiSDKError",r),t(e.detail.sdk)},r=t=>{window.removeEventListener("getuaiSDKReady",i),window.removeEventListener("getuaiSDKError",r),e(t.detail.error)};window.addEventListener("getuaiSDKReady",i),window.addEventListener("getuaiSDKError",r),setTimeout(()=>{window.removeEventListener("getuaiSDKReady",i),window.removeEventListener("getuaiSDKError",r),e(new Error("SDK initialization timeout"))},1e4)})}async function k(t,i,r,n,s=e.USD){const a=E();a?await a.trackEvent(t,i,r,n,s):console.warn("GetuAI SDK: Not initialized. Call init() first.")}async function A(t,e){const i=E();i?await i.trackPageView(t,e):console.warn("GetuAI SDK: Not initialized. Call init() first.")}async function P(t,i,r=e.USD,n){const s=E();s?await s.trackPurchase(t,i,r,n):console.warn("GetuAI SDK: Not initialized. Call init() first.")}async function U(t,e){const i=E();i?await i.trackLogin(t,e):console.warn("GetuAI SDK: Not initialized. Call init() first.")}async function x(t,e){const i=E();i?await i.trackSignup(t,e):console.warn("GetuAI SDK: Not initialized. Call init() first.")}async function I(t,e){const i=E();i?await i.trackFormSubmit(t,e):console.warn("GetuAI SDK: Not initialized. Call init() first.")}function M(){const t=E();return t?t.getAttributionData():null}async function K(){const t=E();t?await t.flush():console.warn("GetuAI SDK: Not initialized. Call init() first.")}function z(){const t=E();return t?t.getStatus():null}function C(t){const e=E();return e?e.addUTMToURL(t):(console.warn("GetuAI SDK: Not initialized. Call init() first."),t)}function O(){const t=E();return t?t.getCurrentUTMParams():{}}function R(){v&&(v.destroy(),v=null,console.log("GetuAI SDK destroyed"))}class L extends T{static async init(t){return await _(t)}static async trackEvent(t,i,r,n,s=e.USD){return await k(t,i,r,n,s)}static async trackPageView(t,e){return await A(t,e)}static async trackPurchase(t,i,r=e.USD,n){return await P(t,i,r,n)}static async trackLogin(t,e){return await U(t,e)}static async trackSignup(t,e){return await x(t,e)}static async trackFormSubmit(t,e){return await I(t,e)}static getAttributionData(){return M()}static async flush(){return await K()}static getStatus(){return z()}static addUTMToURL(t){return C(t)}static getCurrentUTMParams(){return O()}static destroy(){R()}static getSDK(){return E()}static waitForSDK(){return D()}}"undefined"!=typeof document&&function(){if(v)return;const t=document.currentScript;if(!t)return void console.warn("GetuAI SDK: Could not find script tag for auto-initialization");const e=t.getAttribute("data-api-key");e?_({apiKey:e,apiEndpoint:t.getAttribute("data-api-endpoint")||n,enableDebug:"true"===t.getAttribute("data-debug"),autoTrack:"true"===t.getAttribute("data-auto-track"),autoTrackPageView:"true"===t.getAttribute("data-auto-track-page-view"),autoCleanUTM:"false"!==t.getAttribute("data-auto-clean-utm"),batchSize:parseInt(t.getAttribute("data-batch-size")||"100"),batchInterval:parseInt(t.getAttribute("data-batch-interval")||"5000")}):console.warn("GetuAI SDK: No API key provided. Please add data-api-key attribute to script tag.")}(),"undefined"!=typeof window&&(window.getuaiSDK={init:_,getSDK:E,waitForSDK:D,trackEvent:k,trackPageView:A,trackPurchase:P,trackLogin:U,trackSignup:x,trackFormSubmit:I,getAttributionData:M,flush:K,getStatus:z,addUTMToURL:C,getCurrentUTMParams:O,destroy:R,EventType:t,Currency:e,AttributionSDK:L},window.init=_,window.waitForSDK=D,window.trackEvent=k,window.trackPageView=A,window.trackPurchase=P,window.trackLogin=U,window.trackSignup=x,window.trackFormSubmit=I,window.getAttributionData=M,window.flush=K,window.getStatus=z,window.addUTMToURL=C,window.getCurrentUTMParams=O,window.destroy=R,window.AttributionSDK=L);const N={init:_,getSDK:E,waitForSDK:D,trackEvent:k,trackPageView:A,trackPurchase:P,trackLogin:U,trackSignup:x,trackFormSubmit:I,getAttributionData:M,flush:K,getStatus:z,addUTMToURL:C,getCurrentUTMParams:O,destroy:R,EventType:t,Currency:e,AttributionSDK:L};return r.default})());
1
+ !function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.GetuAIAttribution=e():t.GetuAIAttribution=e()}(this,()=>(()=>{"use strict";var t,e,i={d:(t,e)=>{for(var r in e)i.o(e,r)&&!i.o(t,r)&&Object.defineProperty(t,r,{enumerable:!0,get:e[r]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e)},r={};i.d(r,{default:()=>q}),function(t){t.PAGE_VIEW="page_view",t.VIDEO_PLAY="video_play",t.FORM_SUBMIT="form_submit",t.EMAIL_VERIFICATION="email_verification",t.LOGIN="login",t.SIGNUP="signup",t.PRODUCT_VIEW="product_view",t.ADD_TO_CART="add_to_cart",t.PURCHASE="purchase"}(t||(t={})),function(t){t.USD="USD"}(e||(e={}));const n="https://attribution.getu.ai/attribution/api",a=[t.PURCHASE,t.LOGIN,t.SIGNUP,t.FORM_SUBMIT,t.EMAIL_VERIFICATION];function s(){return Math.floor(Date.now()/1e3)}function o(){try{const t="__localStorage_test__";return localStorage.setItem(t,t),localStorage.removeItem(t),!0}catch{return!1}}class c{constructor(t=!0){this.enabled=t}debug(t,...e){this.enabled&&console.debug&&console.debug(`[GetuAI Debug] ${t}`,...e)}info(t,...e){this.enabled&&console.info&&console.info(`[GetuAI Info] ${t}`,...e)}warn(t,...e){this.enabled&&console.warn&&console.warn(`[GetuAI Warn] ${t}`,...e)}error(t,...e){this.enabled&&console.error&&console.error(`[GetuAI Error] ${t}`,...e)}}function u(){return document.referrer||""}function l(){return window.location.href}function h(){return document.title||""}function d(t,e){try{const i=new URL(t);return Object.entries(e).forEach(([t,e])=>{e&&!i.searchParams.has(t)&&i.searchParams.set(t,e)}),i.toString()}catch(e){return t}}function g(t,e=["utm_source","utm_medium","utm_campaign"]){const i={};return e.forEach(e=>{t[e]&&(i[e]=t[e])}),i}function m(t){try{const e=t||window.location.href;return new URL(e).search}catch(t){return""}}function p(t){try{const e=t||window.location.href,i=new URL(e),r={};return i.searchParams.forEach((t,e)=>{r[e]=t}),r}catch(t){return{}}}class w{constructor(t){this.logger=t}get(t){try{if(!o())return this.logger.warn("LocalStorage not supported"),null;const e=localStorage.getItem(t);return null===e?null:JSON.parse(e)}catch(t){return this.logger.error("Error reading from localStorage:",t),null}}set(t,e){try{if(!o())return void this.logger.warn("LocalStorage not supported");localStorage.setItem(t,JSON.stringify(e))}catch(t){this.logger.error("Error writing to localStorage:",t),this.handleQuotaExceeded()}}remove(t){try{o()&&localStorage.removeItem(t)}catch(t){this.logger.error("Error removing from localStorage:",t)}}clear(){try{o()&&localStorage.clear()}catch(t){this.logger.error("Error clearing localStorage:",t)}}handleQuotaExceeded(){try{const t=Object.keys(localStorage).filter(t=>t.startsWith("attribution_"));if(t.length>0){t.sort((t,e)=>{const i=this.get(t),r=this.get(e);return(i?.expiresAt||0)-(r?.expiresAt||0)});const e=Math.ceil(.2*t.length);t.slice(0,e).forEach(t=>{this.remove(t)}),this.logger.info(`Cleaned up ${e} old attribution records`)}}catch(t){this.logger.error("Error during quota cleanup:",t)}}}class f{constructor(t){this.dbName="attribution_events",this.dbVersion=1,this.storeName="events",this.db=null,this.logger=t}async init(){if("indexedDB"in window)return new Promise((t,e)=>{const i=indexedDB.open(this.dbName,this.dbVersion);i.onerror=()=>{this.logger.error("Failed to open IndexedDB:",i.error),e(i.error)},i.onsuccess=()=>{this.db=i.result,this.logger.info("IndexedDB initialized successfully"),t()},i.onupgradeneeded=t=>{const e=t.target.result;if(!e.objectStoreNames.contains(this.storeName)){const t=e.createObjectStore(this.storeName,{keyPath:"id",autoIncrement:!0});t.createIndex("timestamp","timestamp",{unique:!1}),t.createIndex("sent","sent",{unique:!1}),t.createIndex("queued_at","queued_at",{unique:!1})}}});this.logger.warn("IndexedDB not supported")}async addEvent(t){if(!this.db)throw new Error("IndexedDB not initialized");return new Promise((e,i)=>{const r=this.db.transaction([this.storeName],"readwrite").objectStore(this.storeName),n={...t,queued_at:Date.now(),sent:!1},a=r.add(n);a.onsuccess=()=>{this.logger.debug("Event added to IndexedDB queue"),e()},a.onerror=()=>{this.logger.error("Failed to add event to IndexedDB:",a.error),i(a.error)}})}async getUnsentEvents(t=100){return this.db?new Promise((e,i)=>{const r=this.db.transaction([this.storeName],"readonly").objectStore(this.storeName).index("sent").getAll(IDBKeyRange.only(!1),t);r.onsuccess=()=>{const t=r.result.map(t=>{const{queued_at:e,sent:i,...r}=t;return r});e(t)},r.onerror=()=>{this.logger.error("Failed to get unsent events:",r.error),i(r.error)}}):[]}async markEventsAsSent(t){if(this.db&&0!==t.length)return new Promise((e,i)=>{const r=this.db.transaction([this.storeName],"readwrite").objectStore(this.storeName);let n=0,a=!1;t.forEach(s=>{const o=r.get(s);o.onsuccess=()=>{if(o.result){const s={...o.result,sent:!0},c=r.put(s);c.onsuccess=()=>{n++,n!==t.length||a||e()},c.onerror=()=>{a=!0,this.logger.error("Failed to mark event as sent:",c.error),i(c.error)}}else n++,n!==t.length||a||e()},o.onerror=()=>{a=!0,this.logger.error("Failed to get event for marking as sent:",o.error),i(o.error)}})})}async cleanupOldEvents(t=6048e5){if(!this.db)return;const e=Date.now()-t;return new Promise((t,i)=>{const r=this.db.transaction([this.storeName],"readwrite").objectStore(this.storeName).index("queued_at").openCursor(IDBKeyRange.upperBound(e));r.onsuccess=()=>{const e=r.result;e?(e.delete(),e.continue()):(this.logger.info("Old events cleanup completed"),t())},r.onerror=()=>{this.logger.error("Failed to cleanup old events:",r.error),i(r.error)}})}async getQueueSize(){return this.db?new Promise((t,e)=>{const i=this.db.transaction([this.storeName],"readonly").objectStore(this.storeName).count();i.onsuccess=()=>{t(i.result)},i.onerror=()=>{this.logger.error("Failed to get queue size:",i.error),e(i.error)}}):0}async clear(){if(this.db)return new Promise((t,e)=>{const i=this.db.transaction([this.storeName],"readwrite").objectStore(this.storeName).clear();i.onsuccess=()=>{this.logger.info("IndexedDB queue cleared"),t()},i.onerror=()=>{this.logger.error("Failed to clear IndexedDB queue:",i.error),e(i.error)}})}}class y{constructor(t){this.UTM_STORAGE_KEY="attribution_utm_data",this.SESSION_STORAGE_KEY="attribution_session",this.logger=t,this.localStorage=new w(t),this.indexedDB=new f(t)}async init(){await this.indexedDB.init()}storeUTMData(t){try{const e=this.getUTMData(),i={utm_source:"",utm_medium:"",utm_campaign:"",utm_term:"",utm_content:"",timestamp:Date.now()},r={firstTouch:e?.firstTouch||i,lastTouch:e?.lastTouch||i,touchpoints:e?.touchpoints||[],...t,expiresAt:Date.now()+2592e6};this.localStorage.set(this.UTM_STORAGE_KEY,r),this.logger.debug("UTM data stored successfully:",{firstTouch:r.firstTouch,lastTouch:r.lastTouch,touchpointsCount:r.touchpoints.length,expiresAt:new Date(r.expiresAt).toISOString()})}catch(t){this.logger.error("Failed to store UTM data:",t)}}getUTMData(){const t=this.localStorage.get(this.UTM_STORAGE_KEY);return t&&t.expiresAt&&t.expiresAt>Date.now()?t:(t&&this.localStorage.remove(this.UTM_STORAGE_KEY),null)}storeSession(t){this.localStorage.set(this.SESSION_STORAGE_KEY,t)}getSession(){return this.localStorage.get(this.SESSION_STORAGE_KEY)}async queueEvent(t){try{await this.indexedDB.addEvent(t)}catch(t){throw this.logger.error("Failed to queue event:",t),t}}async getUnsentEvents(t=100){return await this.indexedDB.getUnsentEvents(t)}async markEventsAsSent(t){await this.indexedDB.markEventsAsSent(t)}async getQueueSize(){return await this.indexedDB.getQueueSize()}async cleanupOldEvents(){await this.indexedDB.cleanupOldEvents()}async clearQueue(){await this.indexedDB.clear()}cleanupExpiredData(){this.getUTMData()}}class S{constructor(t,e,i,r=100,n=2e3,a=3,s=1e3,o){this.queue=[],this.processing=!1,this.batchTimer=null,this.logger=t,this.apiKey=e,this.apiEndpoint=i,this.batchSize=r,this.batchInterval=n,this.maxRetries=a,this.retryDelay=s,this.sendEvents=o,this.debouncedProcess=function(t){let e;return(...i)=>{clearTimeout(e),e=setTimeout(()=>t(...i),100)}}(this.process.bind(this))}add(t){this.queue.push(t),this.logger.debug(`Event added to queue: ${t.event_type}`),a.includes(t.event_type)?(this.logger.debug(`Immediate event detected: ${t.event_type}, processing immediately`),this.processImmediate(t)):this.scheduleBatchProcessing()}async process(){if(!this.processing&&0!==this.queue.length){this.processing=!0;try{const t=this.queue.splice(0,this.batchSize);this.logger.debug(`Processing ${t.length} events from queue`),await this.sendEvents(t),this.logger.info(`Successfully processed ${t.length} events`)}catch(t){this.logger.error("Failed to process events:",t);const e=this.queue.splice(0,this.batchSize);return this.queue.unshift(...e),void setTimeout(()=>{this.processing=!1,this.debouncedProcess()},this.retryDelay)}this.processing=!1,this.queue.length>0&&this.debouncedProcess()}}async processImmediate(t){try{this.logger.debug(`Processing immediate event: ${t.event_type}`),await this.sendEvents([t]),this.logger.info(`Immediate event processed successfully: ${t.event_type}`)}catch(e){this.logger.error(`Failed to process immediate event: ${t.event_type}`,e),this.queue.unshift(t)}}scheduleBatchProcessing(){this.batchTimer&&clearTimeout(this.batchTimer),this.batchTimer=setTimeout(()=>{this.debouncedProcess()},this.batchInterval)}clear(){this.queue=[],this.batchTimer&&(clearTimeout(this.batchTimer),this.batchTimer=null),this.processing=!1,this.logger.info("Event queue cleared")}size(){return this.queue.length}getStats(){return{size:this.queue.length,processing:this.processing}}async flush(){for(this.logger.info("Flushing event queue");this.queue.length>0;)await this.process()}}class b{constructor(t,e,i,r=3,n=1e3){this.logger=t,this.apiKey=e,this.apiEndpoint=i,this.maxRetries=r,this.retryDelay=n}async sendEvents(t){if(0===t.length)return;const e={events:t.map(t=>({event_id:t.event_id,event_type:t.event_type,tracking_user_id:t.tracking_user_id,utm_source:t.utm_source||null,utm_medium:t.utm_medium||null,utm_campaign:t.utm_campaign||null,utm_term:t.utm_term||null,utm_content:t.utm_content||null,revenue:t.revenue||null,currency:t.currency||null,event_data:t.event_data||null,context:t.context||null,timestamp:t.timestamp||s()}))};await async function(t,e=3,i=1e3){let r;for(let n=0;n<=e;n++)try{return await t()}catch(t){if(r=t,n===e)throw r;const a=i*Math.pow(2,n);await new Promise(t=>setTimeout(t,a))}throw r}(async()=>{const i=await fetch(`${this.apiEndpoint}/attribution/events`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`},body:JSON.stringify(e)});if(!i.ok){const t=await i.text();throw new Error(`HTTP ${i.status}: ${t}`)}const r=await i.json();return this.logger.debug("Events sent successfully:",r),{result:r,sentEvents:t}},this.maxRetries,this.retryDelay)}async sendSingleEvent(t){await this.sendEvents([t])}async testConnection(){try{return(await fetch(`${this.apiEndpoint}/health`,{method:"GET",headers:{Authorization:`Bearer ${this.apiKey}`}})).ok}catch(t){return this.logger.error("Connection test failed:",t),!1}}}class T{constructor(t){this.session=null,this.initialized=!1,this.autoTrackEnabled=!1,this.pageViewTrackTimes=new Map,this.spaTrackingEnabled=!1,this.lastTrackedPath="",this.originalPushState=null,this.originalReplaceState=null,this.popstateHandler=null,this.config={apiEndpoint:n,batchSize:100,batchInterval:2e3,maxRetries:3,retryDelay:1e3,enableDebug:!1,autoTrack:!1,autoTrackPageView:!1,sessionTimeout:18e5,enableCrossDomainUTM:!0,crossDomainUTMParams:["utm_source","utm_medium","utm_campaign","utm_term","utm_content"],excludeDomains:[],autoCleanUTM:!0,pageViewDebounceInterval:5e3,...t},this.logger=new c(this.config.enableDebug),this.storage=new y(this.logger),this.httpClient=new b(this.logger,this.config.apiKey,this.config.apiEndpoint||n,this.config.maxRetries,this.config.retryDelay),this.queue=new S(this.logger,this.config.apiKey,this.config.apiEndpoint||n,this.config.batchSize,this.config.batchInterval,this.config.maxRetries,this.config.retryDelay,t=>this.httpClient.sendEvents(t))}async init(){if(this.initialized)this.logger.warn("SDK already initialized");else try{this.logger.info("Initializing GetuAI Attribution SDK"),await this.storage.init(),this.initializeSession(),this.extractAndStoreUTMData(),this.config.autoTrack&&this.setupAutoTracking(),this.setupNetworkHandlers(),this.setupVisibilityHandlers(),this.setupBeforeUnloadHandler(),this.initialized=!0,this.logger.info("🚀 GetuAI Attribution SDK initialized successfully"),this.logger.info("📄 Auto track page view = "+this.config.autoTrackPageView),this.config.autoTrackPageView&&(this.logger.info("📄 Auto track page view enabled (including SPA route tracking)"),this.lastTrackedPath=this.getCurrentPath(),this.setupSPATracking(),setTimeout(()=>{this.trackPageView().then(()=>{this.logger.info("✅ Auto track page view completed")}).catch(t=>this.logger.error("❌ Auto track page view failed:",t))},100))}catch(t){throw this.logger.error("Failed to initialize SDK:",t),t}}async trackEvent(t,i,r,n,a=e.USD){if(this.initialized)try{const e=l();let o=null;try{o=await this.fetchPublicIP()}catch(t){}const c={domain:"undefined"!=typeof window?window.location.hostname:null,path:"undefined"!=typeof window?window.location.pathname:null,title:h(),referrer:u(),url:e.split("?")[0],querystring:m(e),query_params:p(e),ip_address:o},d={session_id:this.session?.sessionId,start_time:this.session?.startTime,last_activity:this.session?.lastActivity,page_views:this.session?.pageViews},g={event_id:"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(t){const e=16*Math.random()|0;return("x"===t?e:3&e|8).toString(16)}),event_type:t,tracking_user_id:r,timestamp:s(),event_data:i,context:{page:c,session:d},revenue:n,currency:a,...this.getUTMParams()};this.logger.debug(`Tracking event: ${t}`,g),this.queue.add(g)}catch(e){this.logger.error(`Failed to track event ${t}:`,e)}else this.logger.warn("SDK not initialized, event not tracked")}async trackPageView(e,i){const r=l(),n=r.split("?")[0],a=Date.now(),s=this.config.pageViewDebounceInterval||5e3,o=this.pageViewTrackTimes.get(n);if(o&&a-o<s)return void this.logger.debug(`Page view debounced: ${n} (last tracked ${a-o}ms ago)`);const c={url:r,title:h(),referrer:u(),user_agent:navigator.userAgent||"",...e};await this.trackEvent(t.PAGE_VIEW,c,i),this.pageViewTrackTimes.set(n,a),this.cleanupPageViewTrackTimes()}cleanupPageViewTrackTimes(){const t=Date.now()-36e5;for(const[e,i]of this.pageViewTrackTimes.entries())i<t&&this.pageViewTrackTimes.delete(e)}async fetchPublicIP(){try{const t=new AbortController,e=setTimeout(()=>t.abort(),2e3),i=await fetch("https://api.ipify.org?format=json",{signal:t.signal,headers:{Accept:"application/json"}});if(clearTimeout(e),!i.ok)return null;const r=await i.json();return"string"==typeof r?.ip?r.ip:null}catch(t){return this.logger.debug("Public IP fetch failed",t),null}}async trackPurchase(i,r,n=e.USD,a){await this.trackEvent(t.PURCHASE,a,i,r,n)}async trackLogin(e,i){await this.trackEvent(t.LOGIN,i,e)}async trackSignup(e,i){await this.trackEvent(t.SIGNUP,i,e)}async trackFormSubmit(e,i){await this.trackEvent(t.FORM_SUBMIT,i,e)}async trackVideoPlay(e,i){await this.trackEvent(t.VIDEO_PLAY,i,e)}async trackEmailVerification(e,i){await this.trackEvent(t.EMAIL_VERIFICATION,i,e)}async trackProductView(e,i){await this.trackEvent(t.PRODUCT_VIEW,i,e)}async trackAddToCart(e,i){await this.trackEvent(t.ADD_TO_CART,i,e)}getAttributionData(){return this.storage.getUTMData()}addUTMToURL(t){if(!this.config.enableCrossDomainUTM)return t;const e=this.getAttributionData();return e?d(t,g(e.lastTouch,this.config.crossDomainUTMParams)):t}getCurrentUTMParams(){const t=this.getAttributionData();return t?g(t.lastTouch,this.config.crossDomainUTMParams):{}}getUTMParams(){const t=this.getAttributionData();if(!t)return this.logger.debug("No attribution data available for UTM params"),{};const e={utm_source:t.lastTouch.utm_source||null,utm_medium:t.lastTouch.utm_medium||null,utm_campaign:t.lastTouch.utm_campaign||null,utm_term:t.lastTouch.utm_term||null,utm_content:t.lastTouch.utm_content||null},i={};return e.utm_source&&""!==e.utm_source.trim()?i.utm_source=e.utm_source:i.utm_source=null,e.utm_medium&&""!==e.utm_medium.trim()?i.utm_medium=e.utm_medium:i.utm_medium=null,e.utm_campaign&&""!==e.utm_campaign.trim()?i.utm_campaign=e.utm_campaign:i.utm_campaign=null,e.utm_term&&""!==e.utm_term.trim()?i.utm_term=e.utm_term:i.utm_term=null,e.utm_content&&""!==e.utm_content.trim()?i.utm_content=e.utm_content:i.utm_content=null,this.logger.debug("UTM params for event:",i),i}initializeSession(){const t=this.storage.getSession(),e=Date.now();t&&e-t.lastActivity<this.config.sessionTimeout?this.session={...t,lastActivity:e}:this.session={sessionId:`session_${Date.now()}_${Math.random().toString(36).substr(2,9)}`,startTime:e,lastActivity:e,pageViews:0},this.storage.storeSession(this.session),this.logger.debug("Session initialized:",this.session)}extractAndStoreUTMData(){const t=l(),e=function(t){const e=function(t){const e={};try{new URL(t).searchParams.forEach((t,i)=>{e[i]=t})}catch(t){}return e}(t),i={};return["utm_source","utm_medium","utm_campaign","utm_term","utm_content"].forEach(t=>{e[t]&&""!==e[t].trim()&&(i[t]=e[t].trim())}),i}(t);if(this.logger.debug("Extracting UTM params from URL:",t),this.logger.debug("Found UTM params:",e),0===Object.keys(e).length)return void this.logger.debug("No UTM parameters found in URL");const i={utm_source:e.utm_source||"",utm_medium:e.utm_medium||"",utm_campaign:e.utm_campaign||"",utm_term:e.utm_term||"",utm_content:e.utm_content||"",timestamp:Date.now()},r=this.getAttributionData(),n={firstTouch:r?.firstTouch||i,lastTouch:i,touchpoints:r?.touchpoints||[],expiresAt:Date.now()+2592e6};r&&r.lastTouch.utm_source===i.utm_source&&r.lastTouch.utm_campaign===i.utm_campaign||n.touchpoints.push(i),this.storage.storeUTMData(n),this.logger.info("UTM data extracted and stored successfully:",i),this.config.autoCleanUTM&&function(){try{const t=new URL(window.location.href);let e=!1;["utm_source","utm_medium","utm_campaign","utm_term","utm_content"].forEach(i=>{t.searchParams.has(i)&&(t.searchParams.delete(i),e=!0)}),e&&window.history.replaceState({},document.title,t.toString())}catch(t){console.warn("Failed to clean URL:",t)}}()}setupAutoTracking(){this.autoTrackEnabled=!0,this.setupFormTracking(),this.setupLinkTracking(),this.logger.info("Auto-tracking enabled")}setupFormTracking(){document.addEventListener("submit",e=>{try{const i=e.target;if(!i)return;const r=this.serializeFormFields(i);this.trackEvent(t.FORM_SUBMIT,{...r,form_id:i.id||i.name,form_action:i.action,form_method:i.method})}catch(t){this.logger.error("Failed to auto-track form submit:",t)}})}serializeFormFields(t){const e={};try{const i=new FormData(t);for(const[t,r]of i.entries()){const i=this.serializeFormValue(r);if(Object.prototype.hasOwnProperty.call(e,t)){const r=e[t];Array.isArray(r)?(r.push(i),e[t]=r):e[t]=[r,i]}else e[t]=i}const r=Array.from(t.elements),n=new Map;for(const t of r){const e=t.name;e&&!t.disabled&&(n.has(e)||n.set(e,[]),n.get(e).push(t))}n.forEach((t,i)=>{const r=t.some(t=>"radio"===t.type),n=t.some(t=>"checkbox"===t.type),a=t.some(t=>"file"===t.type),s=t.some(t=>"SELECT"===t.tagName&&t.multiple),o=t.some(t=>"password"===t.type);if(n){const r=t.filter(t=>"checkbox"===t.type).filter(t=>t.checked).map(t=>t.value||"on");return void(Object.prototype.hasOwnProperty.call(e,i)?Array.isArray(e[i])||(e[i]=[e[i],...r]):e[i]=r)}if(r){const r=t.filter(t=>"radio"===t.type).find(t=>t.checked);return void(Object.prototype.hasOwnProperty.call(e,i)||(e[i]=r?r.value:null))}if(s){const r=t.find(t=>"SELECT"===t.tagName&&t.multiple);if(r){const t=Array.from(r.selectedOptions).map(t=>t.value);return void(Object.prototype.hasOwnProperty.call(e,i)||(e[i]=t))}}if(a){const r=t.find(t=>"file"===t.type);if(r){const t=r.files?Array.from(r.files):[];return void(Object.prototype.hasOwnProperty.call(e,i)||(e[i]=t.map(t=>this.serializeFormValue(t))))}}if(o)Object.prototype.hasOwnProperty.call(e,i)?e[i]="string"==typeof e[i]?"*****":e[i]:e[i]="*****";else if(!Object.prototype.hasOwnProperty.call(e,i)){const r=t[0];if("SELECT"===r.tagName){const t=r;e[i]=t.multiple?Array.from(t.selectedOptions).map(t=>t.value):t.value}else r.type,e[i]=r.value??""}})}catch(t){this.logger.error("Failed to serialize form fields:",t)}return e}serializeFormValue(t){return t instanceof File?{file_name:t.name,file_size:t.size,file_type:t.type}:t}setupLinkTracking(){document.addEventListener("click",t=>{const e=t.target.closest("a");e&&function(t){try{const e=new URL(t),i=window.location.hostname;return e.hostname!==i}catch(t){return!1}}(e.href)&&this.handleCrossDomainUTM(e,t)})}handleCrossDomainUTM(t,e){if(!this.config.enableCrossDomainUTM)return;const i=t.href;if(function(t,e=[]){try{const i=new URL(t).hostname.toLowerCase();return e.some(t=>{const e=t.toLowerCase();return i===e||i.endsWith(`.${e}`)})}catch(t){return!1}}(i,this.config.excludeDomains))return void this.logger.debug(`Domain excluded from UTM passing: ${i}`);const r=this.getAttributionData();if(!r)return void this.logger.debug("No UTM data available for cross-domain passing");const n=g(r.lastTouch,this.config.crossDomainUTMParams);if(0===Object.keys(n).length)return void this.logger.debug("No UTM parameters to pass");const a=d(i,n);a!==i&&(t.href=a,this.logger.debug("UTM parameters added to external link:",{original:i,enhanced:a,utmParams:n}),this.logger.debug("Cross-domain UTM passed:",{link_url:a,original_url:i,utm_params_passed:n}))}setupNetworkHandlers(){window.addEventListener("online",()=>{this.logger.info("Network connection restored"),this.queue.flush()}),window.addEventListener("offline",()=>{this.logger.warn("Network connection lost")})}setupVisibilityHandlers(){document.addEventListener("visibilitychange",()=>{"visible"===document.visibilityState&&this.updateSessionActivity()})}setupBeforeUnloadHandler(){window.addEventListener("beforeunload",()=>{this.updateSessionActivity(),this.queue.flush()})}getCurrentPath(){return"undefined"==typeof window?"":window.location.pathname+window.location.search}setupSPATracking(){if("undefined"==typeof window||"undefined"==typeof history)return void this.logger.warn("⚠️ SPA tracking not available in this environment");if(this.spaTrackingEnabled)return void this.logger.warn("⚠️ SPA tracking already enabled");this.spaTrackingEnabled=!0,this.lastTrackedPath=this.getCurrentPath(),this.originalPushState=history.pushState.bind(history),this.originalReplaceState=history.replaceState.bind(history);const t=t=>{const e=this.getCurrentPath();e!==this.lastTrackedPath?(this.logger.debug(`🔄 [SPA] Route change detected (${t}): ${this.lastTrackedPath} -> ${e}`),this.lastTrackedPath=e,setTimeout(()=>{this.trackPageView().then(()=>{this.logger.debug(`✅ [SPA] Page view tracked for: ${e}`)}).catch(t=>{this.logger.error("❌ [SPA] Failed to track page view:",t)})},100)):this.logger.debug(`🔄 [SPA] Route change detected (${t}) but path unchanged: ${e}`)};history.pushState=(e,i,r)=>{const n=this.originalPushState(e,i,r);return t("pushState"),n},history.replaceState=(e,i,r)=>{const n=this.originalReplaceState(e,i,r);return t("replaceState"),n},this.popstateHandler=()=>{t("popstate")},window.addEventListener("popstate",this.popstateHandler),this.logger.info("🔄 SPA tracking setup completed")}cleanupSPATracking(){this.spaTrackingEnabled&&(this.originalPushState&&(history.pushState=this.originalPushState,this.originalPushState=null),this.originalReplaceState&&(history.replaceState=this.originalReplaceState,this.originalReplaceState=null),this.popstateHandler&&(window.removeEventListener("popstate",this.popstateHandler),this.popstateHandler=null),this.spaTrackingEnabled=!1,this.logger.info("🔄 SPA tracking cleaned up"))}updateSessionActivity(){this.session&&(this.session.lastActivity=Date.now(),this.storage.storeSession(this.session))}async flush(){await this.queue.flush()}getStatus(){return{initialized:this.initialized,session:this.session,queueSize:this.queue.size(),online:navigator.onLine,crossDomainUTM:{enabled:this.config.enableCrossDomainUTM||!0,currentParams:this.getCurrentUTMParams()},spaTracking:{enabled:this.spaTrackingEnabled,currentPath:this.lastTrackedPath}}}destroy(){this.queue.clear(),this.autoTrackEnabled=!1,this.cleanupSPATracking(),this.initialized=!1,this.logger.info("🗑️ SDK destroyed")}}let v=null;async function _(t){if(v)return console.warn("GetuAI SDK: Already initialized"),v;try{if(v=new T(t),await v.init(),t.enableDebug&&(window.GetuAISDK=v),console.log("GetuAI Attribution SDK initialized successfully"),"undefined"!=typeof window){const t=new CustomEvent("getuaiSDKReady",{detail:{sdk:v}});window.dispatchEvent(t)}return v}catch(t){if(console.error("GetuAI SDK: Failed to initialize:",t),"undefined"!=typeof window){const e=new CustomEvent("getuaiSDKError",{detail:{error:t}});window.dispatchEvent(e)}throw t}}function k(){return v}function E(){return new Promise((t,e)=>{if(v)return void t(v);const i=e=>{window.removeEventListener("getuaiSDKReady",i),window.removeEventListener("getuaiSDKError",r),t(e.detail.sdk)},r=t=>{window.removeEventListener("getuaiSDKReady",i),window.removeEventListener("getuaiSDKError",r),e(t.detail.error)};window.addEventListener("getuaiSDKReady",i),window.addEventListener("getuaiSDKError",r),setTimeout(()=>{window.removeEventListener("getuaiSDKReady",i),window.removeEventListener("getuaiSDKError",r),e(new Error("SDK initialization timeout"))},1e4)})}async function D(t,i,r,n,a=e.USD){const s=k();s?await s.trackEvent(t,i,r,n,a):console.warn("GetuAI SDK: Not initialized. Call init() first.")}async function A(t,e){const i=k();i?await i.trackPageView(t,e):console.warn("GetuAI SDK: Not initialized. Call init() first.")}async function P(t,i,r=e.USD,n){const a=k();a?await a.trackPurchase(t,i,r,n):console.warn("GetuAI SDK: Not initialized. Call init() first.")}async function I(t,e){const i=k();i?await i.trackLogin(t,e):console.warn("GetuAI SDK: Not initialized. Call init() first.")}async function U(t,e){const i=k();i?await i.trackSignup(t,e):console.warn("GetuAI SDK: Not initialized. Call init() first.")}async function x(t,e){const i=k();i?await i.trackFormSubmit(t,e):console.warn("GetuAI SDK: Not initialized. Call init() first.")}async function M(t,e){const i=k();i?await i.trackVideoPlay(t,e):console.warn("GetuAI SDK: Not initialized. Call init() first.")}async function C(t,e){const i=k();i?await i.trackEmailVerification(t,e):console.warn("GetuAI SDK: Not initialized. Call init() first.")}async function K(t,e){const i=k();i?await i.trackProductView(t,e):console.warn("GetuAI SDK: Not initialized. Call init() first.")}async function z(t,e){const i=k();i?await i.trackAddToCart(t,e):console.warn("GetuAI SDK: Not initialized. Call init() first.")}function O(){const t=k();return t?t.getAttributionData():null}async function R(){const t=k();t?await t.flush():console.warn("GetuAI SDK: Not initialized. Call init() first.")}function N(){const t=k();return t?t.getStatus():null}function V(t){const e=k();return e?e.addUTMToURL(t):(console.warn("GetuAI SDK: Not initialized. Call init() first."),t)}function L(){const t=k();return t?t.getCurrentUTMParams():{}}function F(){v&&(v.destroy(),v=null,console.log("GetuAI SDK destroyed"))}class G extends T{static async init(t){return await _(t)}static async trackEvent(t,i,r,n,a=e.USD){return await D(t,i,r,n,a)}static async trackPageView(t,e){return await A(t,e)}static async trackPurchase(t,i,r=e.USD,n){return await P(t,i,r,n)}static async trackLogin(t,e){return await I(t,e)}static async trackSignup(t,e){return await U(t,e)}static async trackFormSubmit(t,e){return await x(t,e)}static async trackVideoPlay(t,e){return await M(t,e)}static async trackEmailVerification(t,e){return await C(t,e)}static async trackProductView(t,e){return await K(t,e)}static async trackAddToCart(t,e){return await z(t,e)}static getAttributionData(){return O()}static async flush(){return await R()}static getStatus(){return N()}static addUTMToURL(t){return V(t)}static getCurrentUTMParams(){return L()}static destroy(){F()}static getSDK(){return k()}static waitForSDK(){return E()}}"undefined"!=typeof document&&function(){if(v)return;const t=document.currentScript;if(!t)return void console.warn("GetuAI SDK: Could not find script tag for auto-initialization");const e=t.getAttribute("data-api-key");e?_({apiKey:e,apiEndpoint:t.getAttribute("data-api-endpoint")||n,enableDebug:"true"===t.getAttribute("data-debug"),autoTrack:"true"===t.getAttribute("data-auto-track"),autoTrackPageView:"true"===t.getAttribute("data-auto-track-page-view"),autoCleanUTM:"false"!==t.getAttribute("data-auto-clean-utm"),batchSize:parseInt(t.getAttribute("data-batch-size")||"100"),batchInterval:parseInt(t.getAttribute("data-batch-interval")||"2000")}):console.warn("GetuAI SDK: No API key provided. Please add data-api-key attribute to script tag.")}(),"undefined"!=typeof window&&(window.getuaiSDK={init:_,getSDK:k,waitForSDK:E,trackEvent:D,trackPageView:A,trackPurchase:P,trackLogin:I,trackSignup:U,trackFormSubmit:x,trackVideoPlay:M,trackEmailVerification:C,trackProductView:K,trackAddToCart:z,getAttributionData:O,flush:R,getStatus:N,addUTMToURL:V,getCurrentUTMParams:L,destroy:F,EventType:t,Currency:e,AttributionSDK:G},window.init=_,window.waitForSDK=E,window.trackEvent=D,window.trackPageView=A,window.trackPurchase=P,window.trackLogin=I,window.trackSignup=U,window.trackFormSubmit=x,window.trackVideoPlay=M,window.trackEmailVerification=C,window.trackProductView=K,window.trackAddToCart=z,window.getAttributionData=O,window.flush=R,window.getStatus=N,window.addUTMToURL=V,window.getCurrentUTMParams=L,window.destroy=F,window.AttributionSDK=G);const q={init:_,getSDK:k,waitForSDK:E,trackEvent:D,trackPageView:A,trackPurchase:P,trackLogin:I,trackSignup:U,trackFormSubmit:x,trackVideoPlay:M,trackEmailVerification:C,trackProductView:K,trackAddToCart:z,getAttributionData:O,flush:R,getStatus:N,addUTMToURL:V,getCurrentUTMParams:L,destroy:F,EventType:t,Currency:e,AttributionSDK:G};return r.default})());
package/dist/index.d.ts CHANGED
@@ -9,6 +9,10 @@ declare function trackPurchase(tracking_user_id: string, revenue: number, curren
9
9
  declare function trackLogin(tracking_user_id: string, loginData?: Record<string, any>): Promise<void>;
10
10
  declare function trackSignup(tracking_user_id: string, signupData?: Record<string, any>): Promise<void>;
11
11
  declare function trackFormSubmit(tracking_user_id?: string, formData?: Record<string, any>): Promise<void>;
12
+ declare function trackVideoPlay(tracking_user_id?: string, videoData?: Record<string, any>): Promise<void>;
13
+ declare function trackEmailVerification(tracking_user_id: string, verificationData?: Record<string, any>): Promise<void>;
14
+ declare function trackProductView(tracking_user_id?: string, productData?: Record<string, any>): Promise<void>;
15
+ declare function trackAddToCart(tracking_user_id?: string, cartData?: Record<string, any>): Promise<void>;
12
16
  declare function getAttributionData(): AttributionData | null;
13
17
  declare function flush(): Promise<void>;
14
18
  declare function getStatus(): {
@@ -36,6 +40,10 @@ declare class AttributionSDKStatic extends AttributionSDK {
36
40
  static trackLogin(tracking_user_id: string, loginData?: Record<string, any>): Promise<void>;
37
41
  static trackSignup(tracking_user_id: string, signupData?: Record<string, any>): Promise<void>;
38
42
  static trackFormSubmit(tracking_user_id?: string, formData?: Record<string, any>): Promise<void>;
43
+ static trackVideoPlay(tracking_user_id?: string, videoData?: Record<string, any>): Promise<void>;
44
+ static trackEmailVerification(tracking_user_id: string, verificationData?: Record<string, any>): Promise<void>;
45
+ static trackProductView(tracking_user_id?: string, productData?: Record<string, any>): Promise<void>;
46
+ static trackAddToCart(tracking_user_id?: string, cartData?: Record<string, any>): Promise<void>;
39
47
  static getAttributionData(): AttributionData | null;
40
48
  static flush(): Promise<void>;
41
49
  static getStatus(): {
@@ -59,7 +67,7 @@ declare class AttributionSDKStatic extends AttributionSDK {
59
67
  static waitForSDK(): Promise<AttributionSDK>;
60
68
  }
61
69
  export { EventType, Currency, type SDKConfig, type EventData, type AttributionData, };
62
- export { init, getSDK, waitForSDK, trackEvent, trackPageView, trackPurchase, trackLogin, trackSignup, trackFormSubmit, getAttributionData, flush, getStatus, addUTMToURL, getCurrentUTMParams, destroy, };
70
+ export { init, getSDK, waitForSDK, trackEvent, trackPageView, trackPurchase, trackLogin, trackSignup, trackFormSubmit, trackVideoPlay, trackEmailVerification, trackProductView, trackAddToCart, getAttributionData, flush, getStatus, addUTMToURL, getCurrentUTMParams, destroy, };
63
71
  export { AttributionSDKStatic as AttributionSDK };
64
72
  declare const _default: {
65
73
  init: typeof init;
@@ -71,6 +79,10 @@ declare const _default: {
71
79
  trackLogin: typeof trackLogin;
72
80
  trackSignup: typeof trackSignup;
73
81
  trackFormSubmit: typeof trackFormSubmit;
82
+ trackVideoPlay: typeof trackVideoPlay;
83
+ trackEmailVerification: typeof trackEmailVerification;
84
+ trackProductView: typeof trackProductView;
85
+ trackAddToCart: typeof trackAddToCart;
74
86
  getAttributionData: typeof getAttributionData;
75
87
  flush: typeof flush;
76
88
  getStatus: typeof getStatus;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EACL,SAAS,EACT,SAAS,EACT,QAAQ,EACR,SAAS,EACT,eAAe,EAEhB,MAAM,SAAS,CAAC;AAiDjB,iBAAe,IAAI,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,cAAc,CAAC,CAuC9D;AAGD,iBAAS,MAAM,IAAI,cAAc,GAAG,IAAI,CAEvC;AAGD,iBAAS,UAAU,IAAI,OAAO,CAAC,cAAc,CAAC,CAgD7C;AAGD,iBAAe,UAAU,CACvB,SAAS,EAAE,SAAS,EACpB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC/B,gBAAgB,CAAC,EAAE,MAAM,EACzB,OAAO,CAAC,EAAE,MAAM,EAChB,QAAQ,GAAE,QAAuB,GAChC,OAAO,CAAC,IAAI,CAAC,CAcf;AAGD,iBAAe,aAAa,CAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC9B,gBAAgB,CAAC,EAAE,MAAM,GACxB,OAAO,CAAC,IAAI,CAAC,CAQf;AAGD,iBAAe,aAAa,CAC1B,gBAAgB,EAAE,MAAM,EACxB,OAAO,EAAE,MAAM,EACf,QAAQ,GAAE,QAAuB,EACjC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GACjC,OAAO,CAAC,IAAI,CAAC,CAQf;AAGD,iBAAe,UAAU,CACvB,gBAAgB,EAAE,MAAM,EACxB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC9B,OAAO,CAAC,IAAI,CAAC,CAQf;AAID,iBAAe,WAAW,CACxB,gBAAgB,EAAE,MAAM,EACxB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC/B,OAAO,CAAC,IAAI,CAAC,CAQf;AAGD,iBAAe,eAAe,CAC5B,gBAAgB,CAAC,EAAE,MAAM,EACzB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC7B,OAAO,CAAC,IAAI,CAAC,CAQf;AAGD,iBAAS,kBAAkB,2BAO1B;AAGD,iBAAe,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAQpC;AAGD,iBAAS,SAAS;;;;;;;;;;;;;SAOjB;AAGD,iBAAS,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAQxC;AAGD,iBAAS,mBAAmB,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAOrD;AAGD,iBAAS,OAAO,IAAI,IAAI,CAMvB;AAGD,cAAM,oBAAqB,SAAQ,cAAc;WAElC,IAAI,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,cAAc,CAAC;WAKhD,UAAU,CACrB,SAAS,EAAE,SAAS,EACpB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC/B,gBAAgB,CAAC,EAAE,MAAM,EACzB,OAAO,CAAC,EAAE,MAAM,EAChB,QAAQ,GAAE,QAAuB,GAChC,OAAO,CAAC,IAAI,CAAC;WAWH,aAAa,CACxB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC9B,gBAAgB,CAAC,EAAE,MAAM,GACxB,OAAO,CAAC,IAAI,CAAC;WAKH,aAAa,CACxB,gBAAgB,EAAE,MAAM,EACxB,OAAO,EAAE,MAAM,EACf,QAAQ,GAAE,QAAuB,EACjC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GACjC,OAAO,CAAC,IAAI,CAAC;WAUH,UAAU,CACrB,gBAAgB,EAAE,MAAM,EACxB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC9B,OAAO,CAAC,IAAI,CAAC;WAKH,WAAW,CACtB,gBAAgB,EAAE,MAAM,EACxB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC/B,OAAO,CAAC,IAAI,CAAC;WAKH,eAAe,CAC1B,gBAAgB,CAAC,EAAE,MAAM,EACzB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC7B,OAAO,CAAC,IAAI,CAAC;IAKhB,MAAM,CAAC,kBAAkB,IAAI,eAAe,GAAG,IAAI;WAKtC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAKnC,MAAM,CAAC,SAAS;;;;;;;;;;;;;;IAKhB,MAAM,CAAC,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;IAKvC,MAAM,CAAC,mBAAmB,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAKpD,MAAM,CAAC,OAAO,IAAI,IAAI;IAKtB,MAAM,CAAC,MAAM,IAAI,cAAc,GAAG,IAAI;IAKtC,MAAM,CAAC,UAAU,IAAI,OAAO,CAAC,cAAc,CAAC;CAG7C;AAGD,OAAO,EACL,SAAS,EACT,QAAQ,EACR,KAAK,SAAS,EACd,KAAK,SAAS,EACd,KAAK,eAAe,GACrB,CAAC;AAGF,OAAO,EACL,IAAI,EACJ,MAAM,EACN,UAAU,EACV,UAAU,EACV,aAAa,EACb,aAAa,EACb,UAAU,EACV,WAAW,EACX,eAAe,EACf,kBAAkB,EAClB,KAAK,EACL,SAAS,EACT,WAAW,EACX,mBAAmB,EACnB,OAAO,GACR,CAAC;AAGF,OAAO,EAAE,oBAAoB,IAAI,cAAc,EAAE,CAAC;;;;;;;;;;;;;;;;;;;;;AAmDlD,wBAmBE"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.esm.js CHANGED
@@ -638,7 +638,7 @@ class AttributionStorageManager {
638
638
  }
639
639
 
640
640
  class EventQueueManager {
641
- constructor(logger, apiKey, apiEndpoint, batchSize = 100, batchInterval = 5000, maxRetries = 3, retryDelay = 1000, sendEvents) {
641
+ constructor(logger, apiKey, apiEndpoint, batchSize = 100, batchInterval = 2000, maxRetries = 3, retryDelay = 1000, sendEvents) {
642
642
  this.queue = [];
643
643
  this.processing = false;
644
644
  this.batchTimer = null;
@@ -830,7 +830,7 @@ class AttributionSDK {
830
830
  this.config = {
831
831
  apiEndpoint: defaultEndpoint,
832
832
  batchSize: 100,
833
- batchInterval: 5000,
833
+ batchInterval: 2000,
834
834
  maxRetries: 3,
835
835
  retryDelay: 1000,
836
836
  enableDebug: false,
@@ -1028,6 +1028,22 @@ class AttributionSDK {
1028
1028
  async trackFormSubmit(tracking_user_id, formData) {
1029
1029
  await this.trackEvent(EventType.FORM_SUBMIT, formData, tracking_user_id);
1030
1030
  }
1031
+ // Track video play
1032
+ async trackVideoPlay(tracking_user_id, videoData) {
1033
+ await this.trackEvent(EventType.VIDEO_PLAY, videoData, tracking_user_id);
1034
+ }
1035
+ // Track email verification
1036
+ async trackEmailVerification(tracking_user_id, verificationData) {
1037
+ await this.trackEvent(EventType.EMAIL_VERIFICATION, verificationData, tracking_user_id);
1038
+ }
1039
+ // Track product view
1040
+ async trackProductView(tracking_user_id, productData) {
1041
+ await this.trackEvent(EventType.PRODUCT_VIEW, productData, tracking_user_id);
1042
+ }
1043
+ // Track add to cart
1044
+ async trackAddToCart(tracking_user_id, cartData) {
1045
+ await this.trackEvent(EventType.ADD_TO_CART, cartData, tracking_user_id);
1046
+ }
1031
1047
  // Get attribution data
1032
1048
  getAttributionData() {
1033
1049
  return this.storage.getUTMData();
@@ -1549,7 +1565,7 @@ function autoInit() {
1549
1565
  autoTrackPageView: script.getAttribute("data-auto-track-page-view") === "true",
1550
1566
  autoCleanUTM: script.getAttribute("data-auto-clean-utm") !== "false",
1551
1567
  batchSize: parseInt(script.getAttribute("data-batch-size") || "100"),
1552
- batchInterval: parseInt(script.getAttribute("data-batch-interval") || "5000"),
1568
+ batchInterval: parseInt(script.getAttribute("data-batch-interval") || "2000"),
1553
1569
  };
1554
1570
  // Initialize SDK
1555
1571
  init(config);
@@ -1675,6 +1691,42 @@ async function trackFormSubmit(tracking_user_id, formData) {
1675
1691
  }
1676
1692
  await sdk.trackFormSubmit(tracking_user_id, formData);
1677
1693
  }
1694
+ // Track video play
1695
+ async function trackVideoPlay(tracking_user_id, videoData) {
1696
+ const sdk = getSDK();
1697
+ if (!sdk) {
1698
+ console.warn("GetuAI SDK: Not initialized. Call init() first.");
1699
+ return;
1700
+ }
1701
+ await sdk.trackVideoPlay(tracking_user_id, videoData);
1702
+ }
1703
+ // Track email verification
1704
+ async function trackEmailVerification(tracking_user_id, verificationData) {
1705
+ const sdk = getSDK();
1706
+ if (!sdk) {
1707
+ console.warn("GetuAI SDK: Not initialized. Call init() first.");
1708
+ return;
1709
+ }
1710
+ await sdk.trackEmailVerification(tracking_user_id, verificationData);
1711
+ }
1712
+ // Track product view
1713
+ async function trackProductView(tracking_user_id, productData) {
1714
+ const sdk = getSDK();
1715
+ if (!sdk) {
1716
+ console.warn("GetuAI SDK: Not initialized. Call init() first.");
1717
+ return;
1718
+ }
1719
+ await sdk.trackProductView(tracking_user_id, productData);
1720
+ }
1721
+ // Track add to cart
1722
+ async function trackAddToCart(tracking_user_id, cartData) {
1723
+ const sdk = getSDK();
1724
+ if (!sdk) {
1725
+ console.warn("GetuAI SDK: Not initialized. Call init() first.");
1726
+ return;
1727
+ }
1728
+ await sdk.trackAddToCart(tracking_user_id, cartData);
1729
+ }
1678
1730
  // Get attribution data
1679
1731
  function getAttributionData() {
1680
1732
  const sdk = getSDK();
@@ -1755,6 +1807,22 @@ class AttributionSDKStatic extends AttributionSDK {
1755
1807
  static async trackFormSubmit(tracking_user_id, formData) {
1756
1808
  return await trackFormSubmit(tracking_user_id, formData);
1757
1809
  }
1810
+ // Static method to track video play
1811
+ static async trackVideoPlay(tracking_user_id, videoData) {
1812
+ return await trackVideoPlay(tracking_user_id, videoData);
1813
+ }
1814
+ // Static method to track email verification
1815
+ static async trackEmailVerification(tracking_user_id, verificationData) {
1816
+ return await trackEmailVerification(tracking_user_id, verificationData);
1817
+ }
1818
+ // Static method to track product view
1819
+ static async trackProductView(tracking_user_id, productData) {
1820
+ return await trackProductView(tracking_user_id, productData);
1821
+ }
1822
+ // Static method to track add to cart
1823
+ static async trackAddToCart(tracking_user_id, cartData) {
1824
+ return await trackAddToCart(tracking_user_id, cartData);
1825
+ }
1758
1826
  // Static method to get attribution data
1759
1827
  static getAttributionData() {
1760
1828
  return getAttributionData();
@@ -1806,6 +1874,10 @@ if (typeof window !== "undefined") {
1806
1874
  trackLogin,
1807
1875
  trackSignup,
1808
1876
  trackFormSubmit,
1877
+ trackVideoPlay,
1878
+ trackEmailVerification,
1879
+ trackProductView,
1880
+ trackAddToCart,
1809
1881
  getAttributionData,
1810
1882
  flush,
1811
1883
  getStatus,
@@ -1825,6 +1897,10 @@ if (typeof window !== "undefined") {
1825
1897
  window.trackLogin = trackLogin;
1826
1898
  window.trackSignup = trackSignup;
1827
1899
  window.trackFormSubmit = trackFormSubmit;
1900
+ window.trackVideoPlay = trackVideoPlay;
1901
+ window.trackEmailVerification = trackEmailVerification;
1902
+ window.trackProductView = trackProductView;
1903
+ window.trackAddToCart = trackAddToCart;
1828
1904
  window.getAttributionData = getAttributionData;
1829
1905
  window.flush = flush;
1830
1906
  window.getStatus = getStatus;
@@ -1844,6 +1920,10 @@ var index = {
1844
1920
  trackLogin,
1845
1921
  trackSignup,
1846
1922
  trackFormSubmit,
1923
+ trackVideoPlay,
1924
+ trackEmailVerification,
1925
+ trackProductView,
1926
+ trackAddToCart,
1847
1927
  getAttributionData,
1848
1928
  flush,
1849
1929
  getStatus,
@@ -1855,5 +1935,5 @@ var index = {
1855
1935
  AttributionSDK: AttributionSDKStatic, // 包含带静态方法的AttributionSDK类
1856
1936
  };
1857
1937
 
1858
- export { AttributionSDKStatic as AttributionSDK, Currency, EventType, addUTMToURL, index as default, destroy, flush, getAttributionData, getCurrentUTMParams, getSDK, getStatus, init, trackEvent, trackFormSubmit, trackLogin, trackPageView, trackPurchase, trackSignup, waitForSDK };
1938
+ export { AttributionSDKStatic as AttributionSDK, Currency, EventType, addUTMToURL, index as default, destroy, flush, getAttributionData, getCurrentUTMParams, getSDK, getStatus, init, trackAddToCart, trackEmailVerification, trackEvent, trackFormSubmit, trackLogin, trackPageView, trackProductView, trackPurchase, trackSignup, trackVideoPlay, waitForSDK };
1859
1939
  //# sourceMappingURL=index.esm.js.map