ainamika-sdk 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Adarsh Singh - Ainamika
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,226 @@
1
+ # Ainamika SDK
2
+
3
+ [![npm version](https://badge.fury.io/js/ainamika-sdk.svg)](https://badge.fury.io/js/ainamika-sdk)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+
6
+ **Ainamika SDK** is an advanced AI-powered analytics SDK that provides comprehensive error tracking, event management, and real-time insights for web applications. Built with TypeScript and designed for modern web development.
7
+
8
+ ## 🚀 Features
9
+
10
+ - **🤖 AI-Powered Analytics**: Intelligent event tracking with AI-generated insights
11
+ - **🛡️ Advanced Error Tracking**: Comprehensive error capture with stack traces, screenshots, and DOM snapshots
12
+ - **📊 Real-time Event Tracking**: Track user interactions, page views, and custom events
13
+ - **🔧 Auto-Configuration**: Automatically analyze your DOM and suggest optimal tracking configurations
14
+ - **⚡ Web Worker Support**: Batched event processing for optimal performance
15
+ - **🌐 Offline Support**: Queue events when offline and sync when online
16
+ - **🎯 Environment Detection**: Automatic development/production environment detection
17
+ - **📱 Cross-Platform**: Works across all modern browsers and frameworks
18
+
19
+ ## 📦 Installation
20
+
21
+ ```bash
22
+ npm install ainamika-sdk
23
+ ```
24
+
25
+ Or via CDN:
26
+
27
+ ```html
28
+ <script src="https://unpkg.com/ainamika-sdk@latest/dist/ainamika-sdk.js"></script>
29
+ ```
30
+
31
+ ## 🏁 Quick Start
32
+
33
+ ### Basic Usage
34
+
35
+ ```javascript
36
+ import AInamikaSDK from 'ainamika-sdk';
37
+
38
+ // Initialize the SDK
39
+ const analytics = new AInamikaSDK({
40
+ apiKey: '',
41
+ autoConfig: true,
42
+ debug: true,
43
+ clientId: 'YOU_WILL_GET_AFTER_SIGINING_UP_IN_DASHBOARD_UNDER_PROFILE',
44
+ apiDetails: {
45
+
46
+ },
47
+ workerConfig: {
48
+ batchSize: 50, // Increased from 5 to 50
49
+ batchInterval: 3000 // Reduced interval to 3 seconds
50
+ },
51
+ });
52
+
53
+ // Track custom events
54
+ analytics.track('button_click', {
55
+ button_id: 'signup-btn',
56
+ page: 'landing',
57
+ user_id: 'user123'
58
+ });
59
+
60
+ // Track user identification
61
+ analytics.setUser('user123');
62
+ ```
63
+
64
+ ### With Error Tracking
65
+
66
+ ```javascript
67
+ const sdk = new AInamikaSDKPro({
68
+ apiKey: '',
69
+ autoConfig: true,
70
+ debug: true,
71
+ clientId: 'YOU_WILL_GET_AFTER_SIGINING_UP_IN_DASHBOARD_UNDER_PROFILE',
72
+ apiDetails: {
73
+
74
+ },
75
+ workerConfig: {
76
+ batchSize: 50, // Increased from 5 to 50
77
+ batchInterval: 3000 // Reduced interval to 3 seconds
78
+ },
79
+ errorTracking: {
80
+ enabled: true,
81
+ captureScreenshots: true,
82
+ captureDomSnapshots: true,
83
+ maxStackTraceDepth: 10,
84
+ maxErrorsPerSession: 50,
85
+ debounceMs: 1000,
86
+ enableNetworkTracking: true,
87
+ enableConsoleCapture: true
88
+ }
89
+ });
90
+
91
+ // Manually capture exceptions
92
+ try {
93
+ // Your code here
94
+ } catch (error) {
95
+ analytics.captureException(error, {
96
+ context: 'user-action',
97
+ severity: 'high'
98
+ });
99
+ }
100
+ ```
101
+
102
+ ### Auto-Configuration
103
+
104
+ Ainamika SDK can automatically analyze your DOM structure and generate optimal tracking configurations:
105
+
106
+ ```javascript
107
+ const analytics = new window.AInamikaSDK({
108
+ apiKey: '',
109
+ autoConfig: true,
110
+ debug: true,
111
+ clientId: 'YOU_WILL_GET_AFTER_SIGINING_UP_IN_DASHBOARD_UNDER_PROFILE',
112
+ apiDetails: {
113
+
114
+ },
115
+ workerConfig: {
116
+ batchSize: 50, // Increased from 5 to 50
117
+ batchInterval: 3000 // Reduced interval to 3 seconds
118
+ },
119
+ errorTracking: {
120
+ enabled: true,
121
+ captureScreenshots: true,
122
+ captureDomSnapshots: true,
123
+ maxStackTraceDepth: 10,
124
+ maxErrorsPerSession: 50,
125
+ debounceMs: 1000,
126
+ enableNetworkTracking: true,
127
+ enableConsoleCapture: true
128
+ }
129
+ });
130
+
131
+ // The SDK will automatically:
132
+ // 1. Analyze your DOM structure
133
+ // 2. Generate tracking configuration via AI
134
+ // 3. Attach event listeners to relevant elements
135
+ // 4. Track user interactions automatically
136
+ ```
137
+ - **Batching & Retry Logic**: Batches events and sends them to the backend, with retry logic for failed sends.
138
+ - **Web Worker Support**: Offloads event batching and sending to a web worker for performance and reliability.
139
+ - **Manual Event Tracking**: Supports manual `.track(eventName, properties)` calls for custom analytics events.
140
+ - **Flexible API Endpoint**: Can send events to a custom API endpoint with custom headers.
141
+ - **Session & User ID Management**: Generates session and user IDs for event context.
142
+ - **Debug Logging**: Optional debug mode for verbose logging in the browser console.
143
+
144
+ ## Usage
145
+
146
+ 1. **Include the SDK**
147
+ ```html
148
+ <script src="./sdk.js"></script>
149
+ <script>
150
+ new AInamikaSDKPro({
151
+ apiKey: '',
152
+ autoConfig: true,
153
+ debug: true,
154
+ clientId: 'YOU_WILL_GET_AFTER_SIGINING_UP_IN_DASHBOARD_UNDER_PROFILE',
155
+ apiDetails: {
156
+
157
+ },
158
+ workerConfig: {
159
+ batchSize: 50, // Increased from 5 to 50
160
+ batchInterval: 3000 // Reduced interval to 3 seconds
161
+ },
162
+ errorTracking: {
163
+ enabled: true,
164
+ captureScreenshots: true,
165
+ captureDomSnapshots: true,
166
+ maxStackTraceDepth: 10,
167
+ maxErrorsPerSession: 50,
168
+ debounceMs: 1000,
169
+ enableNetworkTracking: true,
170
+ enableConsoleCapture: true
171
+ }
172
+ });
173
+ </script>
174
+ ```
175
+
176
+ 2. **Manual Event Tracking**
177
+ ```js
178
+ window.AInamikaSDKPro.track('custom_event', { foo: 'bar' });
179
+ ```
180
+
181
+ 3. **Config Caching**
182
+ - Configs are cached in localStorage under the key `ainamika_dom_config_cache` by DOM hash.
183
+ - Configs can also be saved/loaded as a JSON file (if debug mode is enabled).
184
+
185
+ 4. **Dynamic DOM Support**
186
+ - The SDK automatically detects DOM changes and fetches/apply new configs as needed.
187
+
188
+ 5. **Batching & Web Worker**
189
+ - Events are batched and sent in the background using a web worker (if supported).
190
+
191
+ ## Advanced
192
+
193
+ - **Custom API Endpoint**: Use the `apiDetails` option to send events to a custom endpoint with custom headers.
194
+ - **Worker Config**: Control batch size and interval via `workerConfig`.
195
+ - **Debug Mode**: Set `debug: true` for verbose logs.
196
+
197
+ ## Example AI generated Config
198
+
199
+ ```
200
+ {
201
+ "events_to_track": [
202
+ {
203
+ "element_selector": "button",
204
+ "event_type": "click",
205
+ "event_name": "user_login_button_click"
206
+ },
207
+ {
208
+ "element_selector": "form",
209
+ "event_type": "submit",
210
+ "event_name": "form_submit"
211
+ }
212
+ ]
213
+ }
214
+ ```
215
+
216
+ ## File Structure
217
+ - `sdk.js` : Main SDK logic (compiled from TypeScript)
218
+ - `sdk.ts` : TypeScript source
219
+ - `worker.js`: Web worker for batching and sending events
220
+
221
+ ## Requirements
222
+ - Modern browser with ES6 support
223
+ - Backend server for config generation and event ingestion
224
+
225
+ ## License
226
+ MIT
@@ -0,0 +1,2 @@
1
+ !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.AInamikaSDKPro=t():e.AInamikaSDKPro=t()}("undefined"!=typeof self?self:"undefined"!=typeof window?window:"undefined"!=typeof global?global:this,function(){return function(){"use strict";var e={d:function(t,r){for(var n in r)e.o(r,n)&&!e.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:r[n]})},o:function(e,t){return Object.prototype.hasOwnProperty.call(e,t)}},t={};e.d(t,{default:function(){return v}});var r=function(){return r=Object.assign||function(e){for(var t,r=1,n=arguments.length;r<n;r++)for(var o in t=arguments[r])Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o]);return e},r.apply(this,arguments)},n=function(e,t,r,n){return new(r||(r=Promise))(function(o,a){function i(e){try{c(n.next(e))}catch(e){a(e)}}function s(e){try{c(n.throw(e))}catch(e){a(e)}}function c(e){var t;e.done?o(e.value):(t=e.value,t instanceof r?t:new r(function(e){e(t)})).then(i,s)}c((n=n.apply(e,t||[])).next())})},o=function(e,t){var r,n,o,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]},i=Object.create(("function"==typeof Iterator?Iterator:Object).prototype);return i.next=s(0),i.throw=s(1),i.return=s(2),"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function s(s){return function(c){return function(s){if(r)throw new TypeError("Generator is already executing.");for(;i&&(i=0,s[0]&&(a=0)),a;)try{if(r=1,n&&(o=2&s[0]?n.return:s[0]?n.throw||((o=n.return)&&o.call(n),0):n.next)&&!(o=o.call(n,s[1])).done)return o;switch(n=0,o&&(s=[2&s[0],o.value]),s[0]){case 0:case 1:o=s;break;case 4:return a.label++,{value:s[1],done:!1};case 5:a.label++,n=s[1],s=[0];continue;case 7:s=a.ops.pop(),a.trys.pop();continue;default:if(!((o=(o=a.trys).length>0&&o[o.length-1])||6!==s[0]&&2!==s[0])){a=0;continue}if(3===s[0]&&(!o||s[1]>o[0]&&s[1]<o[3])){a.label=s[1];break}if(6===s[0]&&a.label<o[1]){a.label=o[1],o=s;break}if(o&&a.label<o[2]){a.label=o[2],a.ops.push(s);break}o[2]&&a.ops.pop(),a.trys.pop();continue}s=t.call(e,a)}catch(e){s=[6,e],n=0}finally{r=o=0}if(5&s[0])throw s[1];return{value:s[0]?s[1]:void 0,done:!0}}([s,c])}}},a=function(e,t,r){if(r||2===arguments.length)for(var n,o=0,a=t.length;o<a;o++)!n&&o in t||(n||(n=Array.prototype.slice.call(t,0,o)),n[o]=t[o]);return e.concat(n||Array.prototype.slice.call(t))},i=function(){function e(e){this.breadcrumbs=[],this.errorCount=0,this.errorDebounceMap=new Map,this.config=r({captureScreenshots:!0,captureDomSnapshots:!0,maxStackTraceDepth:50,maxErrorsPerSession:100,debounceMs:1e3,enableNetworkTracking:!0,enableConsoleCapture:!0},e),this.sessionId=this.generateSessionId(),this.originalConsole=r({},console),this.initialize()}return e.prototype.initialize=function(){var e=this;window.addEventListener("error",function(t){e.handleError({type:"javascript",message:t.message,filename:t.filename,line:t.lineno,column:t.colno,error:t.error})}),window.addEventListener("unhandledrejection",function(t){var r;e.handleError({type:"unhandled",message:(null===(r=t.reason)||void 0===r?void 0:r.message)||"Unhandled Promise Rejection",error:t.reason,promise:!0})}),this.config.enableNetworkTracking&&this.setupNetworkTracking(),this.config.enableConsoleCapture&&this.setupConsoleCapture(),this.setupNavigationTracking(),this.setupClickTracking(),console.log("[AInamika Error Tracker] Initialized successfully")},e.prototype.generateSessionId=function(){return"session_".concat(Date.now(),"_").concat(Math.random().toString(36).substr(2,9))},e.prototype.addBreadcrumb=function(e){this.breadcrumbs.push(r(r({},e),{timestamp:Date.now()})),this.breadcrumbs.length>50&&(this.breadcrumbs=this.breadcrumbs.slice(-50))},e.prototype.handleError=function(e){if(this.errorCount>=this.config.maxErrorsPerSession)console.warn("[AInamika Error Tracker] Max errors per session reached");else{var t="".concat(e.message,"_").concat(e.filename,"_").concat(e.line),r=Date.now();if(this.errorDebounceMap.has(t)&&r-this.errorDebounceMap.get(t)<this.config.debounceMs)return;this.errorDebounceMap.set(t,r),this.errorCount++,this.captureError(e)}},e.prototype.captureError=function(e){return n(this,void 0,void 0,function(){var t,r,n;return o(this,function(o){switch(o.label){case 0:return o.trys.push([0,4,,5]),t={client_id:this.config.clientId,error_type:e.type||"javascript",message:e.message||"Unknown error",stack_trace:this.extractStackTrace(e.error),url:window.location.href,user_agent:navigator.userAgent,timestamp:Date.now(),error_metadata:{line:e.line,column:e.column,filename:e.filename,userId:this.userId,sessionId:this.sessionId,breadcrumbs:a([],this.breadcrumbs,!0),networkInfo:this.getNetworkInfo(),performance:this.getPerformanceInfo()},severity:this.assessSeverity(e),session_id:this.sessionId,user_id:this.userId},this.config.captureDomSnapshots&&(t.dom_snapshot=this.captureDomSnapshot()),this.config.captureScreenshots?(r=t,[4,this.captureScreenshot()]):[3,2];case 1:r.screen_snapshot=o.sent(),o.label=2;case 2:return[4,this.sendError(t)];case 3:return o.sent(),this.addBreadcrumb({type:"error",message:"".concat(t.error_type,": ").concat(t.message),data:{severity:t.severity}}),[3,5];case 4:return n=o.sent(),console.error("[AInamika Error Tracker] Failed to capture error:",n),[3,5];case 5:return[2]}})})},e.prototype.extractStackTrace=function(e){if(!e||!e.stack)return"";var t=e.stack.split("\n"),r=this.config.maxStackTraceDepth;return t.slice(0,r).join("\n")},e.prototype.assessSeverity=function(e){var t,r=(null===(t=e.message)||void 0===t?void 0:t.toLowerCase())||"";return r.includes("out of memory")||r.includes("security")||r.includes("permission denied")||"unhandled"===e.type?"critical":r.includes("network")||r.includes("timeout")||r.includes("failed to fetch")||r.includes("cors")?"high":r.includes("undefined")||r.includes("null")||r.includes("cannot read property")?"medium":"low"},e.prototype.captureDomSnapshot=function(){try{var e={url:window.location.href,title:document.title,viewport:{width:window.innerWidth,height:window.innerHeight},elements:this.extractDomElements()};return JSON.stringify(e)}catch(e){return console.error("[AInamika Error Tracker] Failed to capture DOM snapshot:",e),""}},e.prototype.extractDomElements=function(){var e=this,t=[];return["body > *","[id]",'[class*="error"]','[class*="modal"]',"form","button",'input[type="submit"]'].forEach(function(r){try{var n=document.querySelectorAll(r);Array.from(n).slice(0,100-t.length).forEach(function(r){var n;t.push({tagName:r.tagName,id:r.id,className:r.className,textContent:null===(n=r.textContent)||void 0===n?void 0:n.substring(0,100),attributes:e.getElementAttributes(r)})})}catch(e){}}),t},e.prototype.getElementAttributes=function(e){var t={};return["id","class","type","name","value","href","src"].forEach(function(r){var n=e.getAttribute(r);n&&(t[r]=n)}),t},e.prototype.captureScreenshot=function(){return n(this,void 0,void 0,function(){var e;return o(this,function(t){switch(t.label){case 0:return t.trys.push([0,3,,4]),"function"!=typeof window.html2canvas?[3,2]:[4,window.html2canvas(document.body,{height:Math.min(window.innerHeight,1e3),width:Math.min(window.innerWidth,1e3),useCORS:!0})];case 1:return[2,t.sent().toDataURL("image/jpeg",.7)];case 2:return[2,""];case 3:return e=t.sent(),console.error("[AInamika Error Tracker] Failed to capture screenshot:",e),[2,""];case 4:return[2]}})})},e.prototype.getNetworkInfo=function(){var e=navigator.connection||navigator.mozConnection||navigator.webkitConnection;return e?{effectiveType:e.effectiveType,downlink:e.downlink,rtt:e.rtt,saveData:e.saveData}:{}},e.prototype.getPerformanceInfo=function(){var e={};if(performance.memory&&(e.memory={usedJSHeapSize:performance.memory.usedJSHeapSize,totalJSHeapSize:performance.memory.totalJSHeapSize,jsHeapSizeLimit:performance.memory.jsHeapSizeLimit}),performance.timing){var t=performance.timing;e.timing={domContentLoaded:t.domContentLoadedEventEnd-t.navigationStart,load:t.loadEventEnd-t.navigationStart},performance.getEntriesByType&&performance.getEntriesByType("paint").forEach(function(t){"first-paint"===t.name?e.timing.firstPaint=t.startTime:"first-contentful-paint"===t.name&&(e.timing.firstContentfulPaint=t.startTime)})}return e},e.prototype.setupNetworkTracking=function(){var e=this,t=window.fetch;window.fetch=function(){for(var r=[],a=0;a<arguments.length;a++)r[a]=arguments[a];return n(e,void 0,void 0,function(){var e,n,a,i;return o(this,function(o){switch(o.label){case 0:e=Date.now(),n=r[0]instanceof Request?r[0].url:String(r[0]),o.label=1;case 1:return o.trys.push([1,3,,4]),[4,t.apply(void 0,r)];case 2:return a=o.sent(),this.addBreadcrumb({type:"network",message:"Fetch ".concat(a.status," ").concat(n),data:{url:n,status:a.status,duration:Date.now()-e}}),a.ok||this.handleError({type:"network",message:"Network request failed: ".concat(a.status," ").concat(a.statusText),url:n,status:a.status}),[2,a];case 3:throw i=o.sent(),this.addBreadcrumb({type:"network",message:"Fetch failed ".concat(n),data:{url:n,error:(null==i?void 0:i.message)||"Unknown error"}}),this.handleError({type:"network",message:"Network request failed: ".concat((null==i?void 0:i.message)||"Unknown error"),url:n,error:i}),i;case 4:return[2]}})})};var r=XMLHttpRequest.prototype.open,i=XMLHttpRequest.prototype.send;XMLHttpRequest.prototype.open=function(e,t,n,o,a){return this._errorTracker={method:e,url:t,startTime:Date.now()},r.call(this,e,t,n||!0,o,a)},XMLHttpRequest.prototype.send=function(){for(var e=this,t=[],r=0;r<arguments.length;r++)t[r]=arguments[r];var n=this._errorTracker;return this.addEventListener("loadend",function(){if(n){var t=Date.now()-n.startTime;e.status>=400&&e.dispatchEvent(new CustomEvent("networkerror",{detail:{type:"network",message:"XHR request failed: ".concat(e.status," ").concat(e.statusText),url:n.url,status:e.status}})),e.dispatchEvent(new CustomEvent("networkbreadcrumb",{detail:{type:"network",message:"XHR ".concat(e.status," ").concat(n.url),data:{method:n.method,url:n.url,status:e.status,duration:t}}}))}}),i.call.apply(i,a([this],t,!1))},document.addEventListener("networkerror",function(t){e.handleError(t.detail)}),document.addEventListener("networkbreadcrumb",function(t){e.addBreadcrumb(t.detail)})},e.prototype.setupConsoleCapture=function(){var e=this;["error","warn"].forEach(function(t){var r=e.originalConsole[t];console[t]=function(){for(var n=[],o=0;o<arguments.length;o++)n[o]=arguments[o];"function"==typeof r&&r.call.apply(r,a([console],n,!1)),"error"===t&&e.handleError({type:"console",message:n.map(function(e){return String(e)}).join(" "),consoleMethod:t}),e.addBreadcrumb({type:"console",message:"Console ".concat(t,": ").concat(n.map(function(e){return String(e)}).join(" ")),data:{level:t}})}})},e.prototype.setupNavigationTracking=function(){var e=this,t=window.location.href,r=function(){var r=window.location.href;r!==t&&(e.addBreadcrumb({type:"navigation",message:"Navigation from ".concat(t," to ").concat(r),data:{from:t,to:r}}),t=r)};window.addEventListener("popstate",r),window.addEventListener("hashchange",r);var n=history.pushState,o=history.replaceState;history.pushState=function(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];n.apply(this,e),setTimeout(r,0)},history.replaceState=function(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];o.apply(this,e),setTimeout(r,0)}},e.prototype.setupClickTracking=function(){var e=this;document.addEventListener("click",function(t){var r,n=t.target;if(n){var o=e.getElementSelector(n),a=(null===(r=n.textContent)||void 0===r?void 0:r.trim().substring(0,50))||"";e.addBreadcrumb({type:"click",message:"Clicked ".concat(o).concat(a?": ".concat(a):""),data:{selector:o,text:a,tagName:n.tagName,id:n.id,className:n.className}})}})},e.prototype.getElementSelector=function(e){if(e.id)return"#".concat(e.id);if(e.className){var t=e.className.split(" ").filter(function(e){return e}).slice(0,2);if(t.length)return".".concat(t.join("."))}return e.tagName.toLowerCase()},e.prototype.sendError=function(e){return n(this,void 0,void 0,function(){var t,r;return o(this,function(n){switch(n.label){case 0:return n.trys.push([0,2,,3]),[4,fetch("".concat(this.config.endpoint,"/api/v1/errors"),{method:"POST",headers:{"Content-Type":"application/json",Authorization:"Bearer ".concat(this.config.apiKey)},body:JSON.stringify(e)})];case 1:if(!(t=n.sent()).ok)throw new Error("Failed to send error: ".concat(t.status," ").concat(t.statusText));return console.log("[AInamika Error Tracker] Error sent successfully"),[3,3];case 2:return r=n.sent(),console.error("[AInamika Error Tracker] Failed to send error:",r),this.storeErrorLocally(e),[3,3];case 3:return[2]}})})},e.prototype.storeErrorLocally=function(e){try{var t=localStorage.getItem("ainamika_errors")||"[]",r=JSON.parse(t);r.push(e),r.length>50&&r.splice(0,r.length-50),localStorage.setItem("ainamika_errors",JSON.stringify(r))}catch(e){console.error("[AInamika Error Tracker] Failed to store error locally:",e)}},e.prototype.captureException=function(e,t){this.handleError({type:"custom",message:e.message,error:e,context:t})},e.prototype.setUser=function(e){this.userId=e},e.prototype.addTag=function(e,t){this.config.clientId||(this.config.clientId+="_".concat(e,":").concat(t))},e.prototype.flushStoredErrors=function(){return n(this,void 0,void 0,function(){var e,t,r,n,a,i;return o(this,function(o){switch(o.label){case 0:if(o.trys.push([0,5,,6]),!(e=localStorage.getItem("ainamika_errors")))return[2];if(0===(t=JSON.parse(e)).length)return[2];console.log("[AInamika Error Tracker] Flushing ".concat(t.length," stored errors")),r=0,n=t,o.label=1;case 1:return r<n.length?(a=n[r],[4,this.sendError(a)]):[3,4];case 2:o.sent(),o.label=3;case 3:return r++,[3,1];case 4:return localStorage.removeItem("ainamika_errors"),[3,6];case 5:return i=o.sent(),console.error("[AInamika Error Tracker] Failed to flush stored errors:",i),[3,6];case 6:return[2]}})})},e}(),s=function(){if("undefined"!=typeof window&&window.__AINAMIKA_CONFIG__)return window.__AINAMIKA_CONFIG__;var e="undefined"!=typeof window&&("localhost"===window.location.hostname||"127.0.0.1"===window.location.hostname);return{API_BASE_URL:e?"http://localhost:5000":"https://ainamika-backend-768143418383.europe-west1.run.app",APP_ENV:e?"development":"production",DEBUG:e}}(),c={EVENTS:"".concat(s.API_BASE_URL,"/api/v1/events"),ERRORS:"".concat(s.API_BASE_URL,"/api/errors/report"),CONFIG:"".concat(s.API_BASE_URL,"/api/v1/sdk/config"),DEBUG_EVENTS:"".concat(s.API_BASE_URL,"/api/v1/debug/events")};s.DEBUG&&console.log("[Ainamika SDK] Environment Configuration:",{API_BASE_URL:s.API_BASE_URL,APP_ENV:s.APP_ENV,DEBUG:s.DEBUG,ENDPOINTS:c});var u=function(){return u=Object.assign||function(e){for(var t,r=1,n=arguments.length;r<n;r++)for(var o in t=arguments[r])Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o]);return e},u.apply(this,arguments)},l=function(e,t,r,n){return new(r||(r=Promise))(function(o,a){function i(e){try{c(n.next(e))}catch(e){a(e)}}function s(e){try{c(n.throw(e))}catch(e){a(e)}}function c(e){var t;e.done?o(e.value):(t=e.value,t instanceof r?t:new r(function(e){e(t)})).then(i,s)}c((n=n.apply(e,t||[])).next())})},h=function(e,t){var r,n,o,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]},i=Object.create(("function"==typeof Iterator?Iterator:Object).prototype);return i.next=s(0),i.throw=s(1),i.return=s(2),"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function s(s){return function(c){return function(s){if(r)throw new TypeError("Generator is already executing.");for(;i&&(i=0,s[0]&&(a=0)),a;)try{if(r=1,n&&(o=2&s[0]?n.return:s[0]?n.throw||((o=n.return)&&o.call(n),0):n.next)&&!(o=o.call(n,s[1])).done)return o;switch(n=0,o&&(s=[2&s[0],o.value]),s[0]){case 0:case 1:o=s;break;case 4:return a.label++,{value:s[1],done:!1};case 5:a.label++,n=s[1],s=[0];continue;case 7:s=a.ops.pop(),a.trys.pop();continue;default:if(!((o=(o=a.trys).length>0&&o[o.length-1])||6!==s[0]&&2!==s[0])){a=0;continue}if(3===s[0]&&(!o||s[1]>o[0]&&s[1]<o[3])){a.label=s[1];break}if(6===s[0]&&a.label<o[1]){a.label=o[1],o=s;break}if(o&&a.label<o[2]){a.label=o[2],a.ops.push(s);break}o[2]&&a.ops.pop(),a.trys.pop();continue}s=t.call(e,a)}catch(e){s=[6,e],n=0}finally{r=o=0}if(5&s[0])throw s[1];return{value:s[0]?s[1]:void 0,done:!0}}([s,c])}}},d=function(){function e(e){void 0===e&&(e={}),this.STORAGE_KEY="ainamika_error_queue",this.METADATA_KEY="ainamika_error_metadata",this.isProcessing=!1,this.config=u({maxStorageSize:5242880,maxRetries:5,retryInterval:3e4,compressionEnabled:!0,encryptionEnabled:!1},e),this.initialize()}return e.prototype.initialize=function(){var e=this;this.cleanupOldErrors(),this.startRetryTimer(),this.setupStorageListener(),setTimeout(function(){return e.processQueue()},1e3)},e.prototype.storeError=function(e){return l(this,void 0,void 0,function(){var t,r,n,o=this;return h(this,function(a){switch(a.label){case 0:return a.trys.push([0,2,,3]),t=this.generateErrorId(),r={id:t,errorData:this.config.compressionEnabled?this.compressData(e):e,timestamp:Date.now(),retryCount:0},[4,this.addToQueue(r)];case 1:return a.sent(),this.updateMetadata(),setTimeout(function(){return o.processQueue()},100),[2,t];case 2:throw n=a.sent(),console.error("[AInamika Error Storage] Failed to store error:",n),n;case 3:return[2]}})})},e.prototype.getStoredErrors=function(){var e=this;try{var t=localStorage.getItem(this.STORAGE_KEY);return t?JSON.parse(t).map(function(t){return u(u({},t),{errorData:e.config.compressionEnabled?e.decompressData(t.errorData):t.errorData})}):[]}catch(e){return console.error("[AInamika Error Storage] Failed to get stored errors:",e),[]}},e.prototype.removeError=function(e){try{var t=this.getQueueRaw(),r=t.filter(function(t){return t.id!==e});return r.length!==t.length&&(localStorage.setItem(this.STORAGE_KEY,JSON.stringify(r)),this.updateMetadata(),!0)}catch(e){return console.error("[AInamika Error Storage] Failed to remove error:",e),!1}},e.prototype.clearAll=function(){try{localStorage.removeItem(this.STORAGE_KEY),localStorage.removeItem(this.METADATA_KEY),console.log("[AInamika Error Storage] All errors cleared")}catch(e){console.error("[AInamika Error Storage] Failed to clear errors:",e)}},e.prototype.getStorageStats=function(){try{var e=this.getQueueRaw(),t=new Blob([localStorage.getItem(this.STORAGE_KEY)||""]).size,r=e.map(function(e){return e.timestamp}).sort();return{errorCount:e.length,totalSize:t,oldestError:r[0],newestError:r[r.length-1]}}catch(e){return console.error("[AInamika Error Storage] Failed to get storage stats:",e),{errorCount:0,totalSize:0}}},e.prototype.processQueue=function(){return l(this,void 0,void 0,function(){var e,t,r,n,o;return h(this,function(a){switch(a.label){case 0:if(this.isProcessing)return[2];this.isProcessing=!0,a.label=1;case 1:if(a.trys.push([1,,8,9]),0===(e=this.getQueueRaw()).length)return[2];console.log("[AInamika Error Storage] Processing ".concat(e.length," queued errors")),t=0,r=e,a.label=2;case 2:if(!(t<r.length))return[3,7];if((n=r[t]).retryCount>=this.config.maxRetries)return console.warn("[AInamika Error Storage] Max retries reached for error ".concat(n.id)),this.removeError(n.id),[3,6];if(n.lastRetry&&Date.now()-n.lastRetry<this.config.retryInterval)return[3,6];a.label=3;case 3:return a.trys.push([3,5,,6]),[4,this.sendError(n)];case 4:return a.sent()?(this.removeError(n.id),console.log("[AInamika Error Storage] Successfully sent error ".concat(n.id))):this.incrementRetryCount(n.id),[3,6];case 5:return o=a.sent(),console.error("[AInamika Error Storage] Failed to send error ".concat(n.id,":"),o),this.incrementRetryCount(n.id),[3,6];case 6:return t++,[3,2];case 7:return[3,9];case 8:return this.isProcessing=!1,[7];case 9:return[2]}})})},e.prototype.retryError=function(e){return l(this,void 0,void 0,function(){var t,r,n;return h(this,function(o){switch(o.label){case 0:if(t=this.getQueueRaw(),!(r=t.find(function(t){return t.id===e})))return[2,!1];o.label=1;case 1:return o.trys.push([1,3,,4]),[4,this.sendError(r)];case 2:return o.sent()?(this.removeError(e),[2,!0]):(this.incrementRetryCount(e),[2,!1]);case 3:return n=o.sent(),console.error("[AInamika Error Storage] Failed to retry error ".concat(e,":"),n),this.incrementRetryCount(e),[2,!1];case 4:return[2]}})})},e.prototype.addToQueue=function(e){return l(this,void 0,void 0,function(){var t,r;return h(this,function(n){if((t=this.getQueueRaw()).push(e),r=JSON.stringify(t),new Blob([r]).size>this.config.maxStorageSize)for(;t.length>0&&new Blob([JSON.stringify(t)]).size>this.config.maxStorageSize;)t.shift(),console.warn("[AInamika Error Storage] Removed old error due to size limit");return localStorage.setItem(this.STORAGE_KEY,JSON.stringify(t)),[2]})})},e.prototype.getQueueRaw=function(){try{var e=localStorage.getItem(this.STORAGE_KEY);return e?JSON.parse(e):[]}catch(e){return console.error("[AInamika Error Storage] Failed to parse stored errors:",e),[]}},e.prototype.incrementRetryCount=function(e){try{var t=this.getQueueRaw(),r=t.findIndex(function(t){return t.id===e});-1!==r&&(t[r].retryCount++,t[r].lastRetry=Date.now(),localStorage.setItem(this.STORAGE_KEY,JSON.stringify(t)))}catch(e){console.error("[AInamika Error Storage] Failed to increment retry count:",e)}},e.prototype.sendError=function(e){return l(this,void 0,void 0,function(){var t,r,n,o;return h(this,function(a){switch(a.label){case 0:return a.trys.push([0,2,,3]),t=this.config.compressionEnabled?this.decompressData(e.errorData):e.errorData,r=t.endpoint||c.ERRORS,n=t.apiKey||"",[4,fetch("".concat(r,"/api/v1/errors"),{method:"POST",headers:{"Content-Type":"application/json",Authorization:n?"Bearer ".concat(n):""},body:JSON.stringify(t)})];case 1:return[2,a.sent().ok];case 2:return o=a.sent(),console.error("[AInamika Error Storage] Network error sending stored error:",o),[2,!1];case 3:return[2]}})})},e.prototype.compressData=function(e){try{var t=JSON.stringify(e);return btoa(t)}catch(t){return console.warn("[AInamika Error Storage] Compression failed, storing uncompressed:",t),e}},e.prototype.decompressData=function(e){try{if("string"==typeof e&&e.length>0){var t=atob(e);return JSON.parse(t)}return e}catch(t){return console.warn("[AInamika Error Storage] Decompression failed, returning raw data:",t),e}},e.prototype.generateErrorId=function(){return"error_".concat(Date.now(),"_").concat(Math.random().toString(36).substr(2,9))},e.prototype.cleanupOldErrors=function(){try{var e=this.getQueueRaw(),t=Date.now()-6048e5,r=e.filter(function(e){return e.timestamp>t});r.length!==e.length&&(localStorage.setItem(this.STORAGE_KEY,JSON.stringify(r)),console.log("[AInamika Error Storage] Cleaned up ".concat(e.length-r.length," old errors")))}catch(e){console.error("[AInamika Error Storage] Failed to cleanup old errors:",e)}},e.prototype.startRetryTimer=function(){var e=this;this.retryTimer=window.setInterval(function(){e.processQueue()},this.config.retryInterval)},e.prototype.setupStorageListener=function(){var e=this;window.addEventListener("storage",function(t){t.key===e.STORAGE_KEY&&(console.log("[AInamika Error Storage] Storage updated from another tab"),setTimeout(function(){return e.processQueue()},1e3))}),window.addEventListener("online",function(){console.log("[AInamika Error Storage] Network back online, processing queue"),setTimeout(function(){return e.processQueue()},1e3)}),window.addEventListener("offline",function(){console.log("[AInamika Error Storage] Network offline, errors will be queued")})},e.prototype.updateMetadata=function(){try{var e=this.getStorageStats(),t=u({lastUpdate:Date.now()},e);localStorage.setItem(this.METADATA_KEY,JSON.stringify(t))}catch(e){console.error("[AInamika Error Storage] Failed to update metadata:",e)}},e.prototype.exportErrors=function(){try{var e=this.getStoredErrors(),t={timestamp:Date.now(),version:"1.0",stats:this.getStorageStats(),errors:e};return JSON.stringify(t,null,2)}catch(e){return console.error("[AInamika Error Storage] Failed to export errors:",e),"{}"}},e.prototype.importErrors=function(e){try{var t=JSON.parse(e);if(!t.errors||!Array.isArray(t.errors))throw new Error("Invalid export format");this.clearAll();for(var r=0,n=t.errors;r<n.length;r++){var o=n[r];this.storeError(o.errorData)}return console.log("[AInamika Error Storage] Imported ".concat(t.errors.length," errors")),!0}catch(e){return console.error("[AInamika Error Storage] Failed to import errors:",e),!1}},e.prototype.destroy=function(){this.retryTimer&&(clearInterval(this.retryTimer),this.retryTimer=void 0),this.processQueue(),console.log("[AInamika Error Storage] Storage instance destroyed")},e}(),f=(function(){function e(){}e.getAinamikaStorageUsage=function(){var e=0,t=0,r=0;for(var n in localStorage)if(localStorage.hasOwnProperty(n)){var o=new Blob([localStorage.getItem(n)||""]).size;e+=o,n.startsWith("ainamika_error")?t+=o:n.startsWith("ainamika_")&&(r+=o)}return{totalSize:e,errorSize:t,otherSize:r}},e.checkStorageSpace=function(e){try{var t="ainamika_storage_test",r="x".repeat(Math.min(e,1048576));return localStorage.setItem(t,r),localStorage.removeItem(t),!0}catch(e){return!1}},e.cleanupAllAinamikaStorage=function(){var e=[];for(var t in localStorage)t.startsWith("ainamika_")&&e.push(t);e.forEach(function(e){return localStorage.removeItem(e)}),console.log("[AInamika Storage Utils] Cleaned up ".concat(e.length," storage keys"))},e.generateStorageReport=function(){var t=new d;return{usage:e.getAinamikaStorageUsage(),errors:t.getStoredErrors(),metadata:t.getStorageStats()}}}(),function(){return f=Object.assign||function(e){for(var t,r=1,n=arguments.length;r<n;r++)for(var o in t=arguments[r])Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o]);return e},f.apply(this,arguments)}),p=function(e,t,r,n){return new(r||(r=Promise))(function(o,a){function i(e){try{c(n.next(e))}catch(e){a(e)}}function s(e){try{c(n.throw(e))}catch(e){a(e)}}function c(e){var t;e.done?o(e.value):(t=e.value,t instanceof r?t:new r(function(e){e(t)})).then(i,s)}c((n=n.apply(e,t||[])).next())})},g=function(e,t){var r,n,o,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]},i=Object.create(("function"==typeof Iterator?Iterator:Object).prototype);return i.next=s(0),i.throw=s(1),i.return=s(2),"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function s(s){return function(c){return function(s){if(r)throw new TypeError("Generator is already executing.");for(;i&&(i=0,s[0]&&(a=0)),a;)try{if(r=1,n&&(o=2&s[0]?n.return:s[0]?n.throw||((o=n.return)&&o.call(n),0):n.next)&&!(o=o.call(n,s[1])).done)return o;switch(n=0,o&&(s=[2&s[0],o.value]),s[0]){case 0:case 1:o=s;break;case 4:return a.label++,{value:s[1],done:!1};case 5:a.label++,n=s[1],s=[0];continue;case 7:s=a.ops.pop(),a.trys.pop();continue;default:if(!((o=(o=a.trys).length>0&&o[o.length-1])||6!==s[0]&&2!==s[0])){a=0;continue}if(3===s[0]&&(!o||s[1]>o[0]&&s[1]<o[3])){a.label=s[1];break}if(6===s[0]&&a.label<o[1]){a.label=o[1],o=s;break}if(o&&a.label<o[2]){a.label=o[2],a.ops.push(s);break}o[2]&&a.ops.pop(),a.trys.pop();continue}s=t.call(e,a)}catch(e){s=[6,e],n=0}finally{r=o=0}if(5&s[0])throw s[1];return{value:s[0]?s[1]:void 0,done:!0}}([s,c])}}},m=function(){function e(e){this.eventQueue=[],this.isInitialized=!1,this.batchRetryCount=0,this.maxBatchRetries=5,this.domHashCache={},this.lastDomHash="",this.lastConfigHash="",this.mutationDebounceTimer=null,this.mutationDebounceMs=2e3,this.attachedListeners=new WeakMap,this.config=f({endpoint:s.API_BASE_URL,batchInterval:5e3,useWebWorker:!0,debug:s.DEBUG,errorTracking:{enabled:!0,captureScreenshots:!0,captureDomSnapshots:!0,maxStackTraceDepth:50,maxErrorsPerSession:100,debounceMs:1e3,enableNetworkTracking:!0,enableConsoleCapture:!0}},e),this.sessionId=this.generateSessionId();var t=new Blob(["\n self.eventQueue = [];\n self.config = {\n apiUrl: '',\n batchSize: 10,\n batchInterval: 5000,\n headers: { 'Content-Type': 'application/json' }\n };\n let batchTimer = null;\n function flushQueue() {\n self.postMessage({ status: 'debug', message: '[AInamika Worker] flushQueue called', eventQueue: self.eventQueue, config: self.config });\n if (self.eventQueue.length === 0) return;\n const batch = self.eventQueue.splice(0, self.config.batchSize);\n fetch(self.config.apiUrl, {\n method: 'POST',\n headers: self.config.headers,\n body: JSON.stringify({ events: batch })\n }).then(r => {\n if (r.ok) {\n self.postMessage({ status: 'success' });\n } else {\n self.postMessage({ status: 'error', error: r.statusText, failedEvents: batch });\n }\n }).catch(e => {\n self.postMessage({ status: 'error', error: e.message, failedEvents: batch });\n });\n }\n self.onmessage = function(e) {\n self.postMessage({ status: 'debug', message: '[AInamika Worker] onmessage', data: e.data });\n if (e.data.type === 'config') {\n self.config = { ...self.config, ...e.data.payload };\n if (batchTimer) clearInterval(batchTimer);\n batchTimer = setInterval(flushQueue, self.config.batchInterval);\n self.postMessage({ status: 'debug', message: '[AInamika Worker] config set', config: self.config });\n } else if (e.data.type === 'track') {\n self.eventQueue.push(e.data.payload);\n // Only send when timer triggers, not when batch size is reached\n // This ensures true batching behavior\n } else if (e.data.type === 'batch') {\n // Handle batch flush from main thread\n self.postMessage({ status: 'debug', message: '[AInamika Worker] Received batch from main thread', events: e.data.events });\n self.eventQueue.push(...e.data.events);\n flushQueue();\n } else if (e.data.type === 'initConfig') {\n // No-op for now, can be used for advanced config\n }\n };\n "],{type:"application/javascript"}),r=URL.createObjectURL(t);this.worker=new Worker(r),this.initialize()}return e.prototype.initialize=function(){return p(this,void 0,void 0,function(){var e;return g(this,function(t){switch(t.label){case 0:return this.isInitialized?[2]:(this.isInitialized=!0,(null===(e=this.config.errorTracking)||void 0===e?void 0:e.enabled)&&this.initializeErrorTracking(),this.config.autoConfig?[4,this.setupAutoConfiguration()]:[3,2]);case 1:t.sent(),t.label=2;case 2:return this.setupDynamicDomTracking(),this.config.useWebWorker&&"undefined"!=typeof Worker?this.setupWebWorker():this.startBatchTimer(),this.log("AnalyticsPro SDK initialized",{config:this.config}),[2]}})})},e.prototype.initializeErrorTracking=function(){var e,t,r,n,o,a,c,u,l,h,f,p,g,m;try{this.errorStorage=new d({maxStorageSize:5242880,maxRetries:5,retryInterval:3e4,compressionEnabled:!0,encryptionEnabled:!1});var v={endpoint:s.API_BASE_URL,clientId:this.config.clientId,apiKey:this.config.apiKey,captureScreenshots:null===(t=null===(e=this.config.errorTracking)||void 0===e?void 0:e.captureScreenshots)||void 0===t||t,captureDomSnapshots:null===(n=null===(r=this.config.errorTracking)||void 0===r?void 0:r.captureDomSnapshots)||void 0===n||n,maxStackTraceDepth:null!==(a=null===(o=this.config.errorTracking)||void 0===o?void 0:o.maxStackTraceDepth)&&void 0!==a?a:50,maxErrorsPerSession:null!==(u=null===(c=this.config.errorTracking)||void 0===c?void 0:c.maxErrorsPerSession)&&void 0!==u?u:100,debounceMs:null!==(h=null===(l=this.config.errorTracking)||void 0===l?void 0:l.debounceMs)&&void 0!==h?h:1e3,enableNetworkTracking:null===(p=null===(f=this.config.errorTracking)||void 0===f?void 0:f.enableNetworkTracking)||void 0===p||p,enableConsoleCapture:null===(m=null===(g=this.config.errorTracking)||void 0===g?void 0:g.enableConsoleCapture)||void 0===m||m};this.errorTracker=new i(v);var y=this.getUserId();y&&this.errorTracker&&this.errorTracker.setUser(y),this.log("Error tracking initialized successfully")}catch(e){console.error("[AInamika SDK] Failed to initialize error tracking:",e)}},e.prototype.captureException=function(e,t){this.errorTracker&&this.errorTracker.captureException(e,t)},e.prototype.setUser=function(e){this.errorTracker&&this.errorTracker.setUser(e)},e.prototype.flushStoredErrors=function(){return p(this,void 0,void 0,function(){return g(this,function(e){switch(e.label){case 0:return this.errorStorage?[4,this.errorStorage.processQueue()]:[3,2];case 1:e.sent(),e.label=2;case 2:return this.errorTracker?[4,this.errorTracker.flushStoredErrors()]:[3,4];case 3:e.sent(),e.label=4;case 4:return[2]}})})},e.prototype.setupAutoConfiguration=function(){return p(this,void 0,void 0,function(){var e,t,r,n;return g(this,function(o){switch(o.label){case 0:return o.trys.push([0,7,,8]),this.log("Starting auto-configuration..."),[4,this.getDOMStructure()];case 1:return e=o.sent(),t=this.computeDomHash(e),this.lastDomHash=t,(r=this.getCachedConfigForDomHash(t))?(this.log("Loaded analytics config from localStorage cache for DOM hash:",t),[3,4]):[3,2];case 2:return[4,this.loadConfigFromFile()];case 3:(r=o.sent())&&this.log("Loaded analytics config from file"),o.label=4;case 4:return r?[3,6]:(this.log("No cached config found, fetching from backend for DOM hash:",t),[4,this.fetchGeneratedConfig(e,t)]);case 5:(r=o.sent())&&r.events_to_track&&(this.saveConfigToFile(r),this.setCachedConfigForDomHash(t,r),this.lastConfigHash=r.config_hash||""),o.label=6;case 6:return r&&r.events_to_track?(this.applyGeneratedConfig(r),this.config.useWebWorker&&"undefined"!=typeof Worker&&this.worker.postMessage({type:"initConfig",config:r}),this.log("Auto-configuration applied successfully",r)):this.log("Auto-configuration failed: Invalid config received from backend.",r),[3,8];case 7:return n=o.sent(),this.log("Auto-configuration failed with error",n),[3,8];case 8:return[2]}})})},e.prototype.getDOMStructure=function(){return p(this,void 0,void 0,function(){var e,t,r,n,o;return g(this,function(a){switch(a.label){case 0:return e=function(e){if(e.id)return"#".concat(e.id);if(e.className){var t=e.className.split(" ").filter(function(e){return e.trim()}).join(".");return t?".".concat(t):e.tagName.toLowerCase()}return e.tagName.toLowerCase()},[4,new Promise(function(e){return setTimeout(e,500)})];case 1:return a.sent(),t=Array.from(document.body.querySelectorAll('\n button, a, input, select, textarea, form, img, h1, h2, h3, h4, h5, h6,\n [role=button], [role=link], [onclick], [tabindex], [data-analytics], [data-track],\n .card, .btn, .btn-primary, .btn-secondary, .card-title, .card-description, .card-price, .card-actions,\n [id*="card"], [class*="card"], [class*="btn"], [class*="price"], [class*="title"],\n div, span, p\n ')),r=t.filter(function(e){var t=window.getComputedStyle(e),r="none"!==t.display&&"hidden"!==t.visibility&&"0"!==t.opacity,n="button"===e.tagName.toLowerCase()||"a"===e.tagName.toLowerCase()||e.hasAttribute("onclick")||"button"===e.getAttribute("role")||e.classList.contains("btn")||e.classList.contains("card"),o="cardsContainer"===e.id||e.classList.contains("cards-grid")||e.classList.contains("card")||"img"===e.tagName.toLowerCase()||-1!==["h1","h2","h3"].indexOf(e.tagName.toLowerCase());return r&&(n||o)||"cardsContainer"===e.id}),n=new Set,o=r.map(function(t){var r,n,o={};return Array.from(t.attributes).forEach(function(e){-1===["style","data-timestamp","data-rendered"].indexOf(e.name)&&(o[e.name]=e.value)}),{tagName:t.tagName.toLowerCase(),selector:e(t),id:t.id||"",className:t.className||"",textContent:(t.textContent||"").trim().substring(0,100),attributes:o,isInteractive:"button"===t.tagName.toLowerCase()||"a"===t.tagName.toLowerCase()||t.hasAttribute("onclick")||"button"===t.getAttribute("role")||t.classList.contains("btn"),hasChildren:t.children.length>0,childCount:t.children.length,parentTagName:(null===(r=t.parentElement)||void 0===r?void 0:r.tagName.toLowerCase())||"",index:Array.from((null===(n=t.parentElement)||void 0===n?void 0:n.children)||[]).indexOf(t)}}).filter(function(e){var t=e.tagName+"|"+e.selector+"|"+e.textContent.substring(0,20);return!n.has(t)&&(n.add(t),!0)}),this.log("DOM structure analyzed",{elementCount:o.length,elements:o}),[2,{elements:o}]}})})},e.prototype.fetchGeneratedConfig=function(e,t){return p(this,void 0,void 0,function(){var r,n,o;return g(this,function(a){switch(a.label){case 0:return a.trys.push([0,3,,4]),e&&e.elements&&0===e.elements.length?(this.log("No elements found in DOM structure, skipping config fetch."),[2,null]):(r={structure:e},t&&(r.domHash=t,r.lastConfigHash=this.lastConfigHash),[4,fetch(c.CONFIG,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r)})]);case 1:if(!(n=a.sent()).ok)throw new Error("Backend returned ".concat(n.status));return[4,n.json()];case 2:return[2,a.sent()];case 3:return o=a.sent(),this.log("Error fetching generated config:",o),[2,null];case 4:return[2]}})})},e.prototype.applyGeneratedConfig=function(e){var t=this;e.events_to_track.forEach(function(e){try{var r=document.querySelectorAll(e.element_selector);r.length>0?r.forEach(function(r){var n=t.attachedListeners.get(r);n||(n=new Set,t.attachedListeners.set(r,n)),(Array.isArray(e.event_type)?e.event_type:[e.event_type]).forEach(function(o){n.has(o)||(n.add(o),"click"===o&&(r.addEventListener("click",function(r){var n=r.target,o=t.extractElementData(n);t.sendToWorker(e.event_name,{selector:e.element_selector,eventType:"click",element:o,timestamp:(new Date).toISOString()})}),t.log('Attached click listener for "'.concat(e.event_name,'" on "').concat(e.element_selector,'"'))),"view"===o&&"IntersectionObserver"in window&&(new IntersectionObserver(function(r){r.forEach(function(r){if(r.isIntersecting){var n=r.target,o=t.extractElementData(n);t.sendToWorker(e.event_name,{selector:e.element_selector,eventType:"view",element:o,intersectionRatio:r.intersectionRatio,timestamp:(new Date).toISOString()})}})},{threshold:[.1,.5,1]}).observe(r),t.log('Attached IntersectionObserver for "'.concat(e.event_name,'" on "').concat(e.element_selector,'"'))),"focus"!==o&&"blur"!==o||(r.addEventListener(o,function(){var n=r,a=t.extractElementData(n);t.sendToWorker(e.event_name,{selector:e.element_selector,eventType:o,element:a,timestamp:(new Date).toISOString()})}),t.log("Attached ".concat(o,' listener for "').concat(e.event_name,'" on "').concat(e.element_selector,'"'))))})}):t.log('No elements found for selector: "'.concat(e.element_selector,'"'))}catch(r){t.log('Error applying selector "'.concat(e.element_selector,'":'),r)}}),e.observe_mutations&&"MutationObserver"in window&&(new MutationObserver(function(e){e.forEach(function(e){t.sendToWorker("dom_mutation",{type:e.type,target:e.target.outerHTML,timestamp:(new Date).toISOString()})})}).observe(document.body,{childList:!0,subtree:!0}),this.log("MutationObserver attached for DOM changes"))},e.prototype.extractElementData=function(e){var t=e.getBoundingClientRect();return{tagName:e.tagName.toLowerCase(),id:e.id||"",className:e.className||"",textContent:(e.textContent||"").trim().substring(0,100),attributes:Array.from(e.attributes).reduce(function(e,t){return e[t.name]=t.value,e},{}),position:{x:Math.round(t.x),y:Math.round(t.y),width:Math.round(t.width),height:Math.round(t.height)},href:e.href||void 0,value:e.value||void 0}},e.prototype.sendToWorker=function(e,t){var r={event:e,properties:t,timestamp:Date.now(),userId:this.getUserId(),sessionId:this.sessionId,client_id:this.config.clientId||"demo-client-001"};this.config.useWebWorker&&"undefined"!=typeof Worker?this.worker.postMessage({type:"track",payload:r}):this.eventQueue.push(r),this.log("Event tracked:",r)},e.prototype.setupWebWorker=function(){var e,t,r,n,o=this;this.worker.postMessage({type:"config",payload:{apiUrl:(null===(e=this.config.apiDetails)||void 0===e?void 0:e.apiEndPoint)||"".concat(this.config.endpoint,"/api/v1/events"),batchSize:(null===(t=this.config.workerConfig)||void 0===t?void 0:t.batchSize)||10,batchInterval:(null===(r=this.config.workerConfig)||void 0===r?void 0:r.batchInterval)||5e3,headers:(null===(n=this.config.apiDetails)||void 0===n?void 0:n.headers)||{"Content-Type":"application/json"}}}),this.worker.onmessage=function(e){var t;"success"===e.data.status?o.log("Batch sent successfully by worker"):"debug"===e.data.status?o.log(e.data.message,e.data):"error"===e.data.status&&(o.log("Worker failed to send batch",e.data.error),e.data.failedEvents&&e.data.failedEvents.length>0&&(t=o.eventQueue).unshift.apply(t,e.data.failedEvents))},this.log("Web worker setup complete.")},e.prototype.track=function(e,t){void 0===t&&(t={});var r={event:e,properties:t,timestamp:Date.now(),userId:this.getUserId(),sessionId:this.sessionId,client_id:this.config.clientId||"demo-client-001"};this.config.useWebWorker&&"undefined"!=typeof Worker?this.worker.postMessage({type:"track",payload:r}):this.eventQueue.push(r),this.log("Event tracked public:",r)},e.prototype.startBatchTimer=function(){var e=this;this.batchTimer=window.setInterval(function(){e.flushQueue()},this.config.batchInterval)},e.prototype.flushQueue=function(){return p(this,void 0,void 0,function(){var e;return g(this,function(t){switch(t.label){case 0:return 0===this.eventQueue.length?[2]:(e=function(e,t,r){if(r||2===arguments.length)for(var n,o=0,a=t.length;o<a;o++)!n&&o in t||(n||(n=Array.prototype.slice.call(t,0,o)),n[o]=t[o]);return e.concat(n||Array.prototype.slice.call(t))}([],this.eventQueue,!0),this.eventQueue=[],this.config.useWebWorker&&"undefined"!=typeof Worker?(this.worker.postMessage({type:"batch",events:e,endpoint:"".concat(this.config.endpoint,"/api/v1/events")}),[3,3]):[3,1]);case 1:return[4,this.sendBatchWithRetry(e)];case 2:t.sent(),t.label=3;case 3:return[2]}})})},e.prototype.sendBatchWithRetry=function(e){return p(this,void 0,void 0,function(){var t,r;return g(this,function(n){switch(n.label){case 0:if(this.batchRetryCount>=this.maxBatchRetries)return this.batchTimer&&(clearInterval(this.batchTimer),this.batchTimer=void 0,this.log("Max batch retries reached. BatchTimer cancelled.")),[2];n.label=1;case 1:return n.trys.push([1,3,,4]),[4,this.sendBatch(e)];case 2:return n.sent(),this.batchRetryCount=0,[3,4];case 3:return t=n.sent(),this.batchRetryCount++,this.log("Batch send failed. Retry attempt ".concat(this.batchRetryCount," of ").concat(this.maxBatchRetries,"."),t),(r=this.eventQueue).unshift.apply(r,e),this.batchRetryCount>=this.maxBatchRetries&&this.batchTimer&&(clearInterval(this.batchTimer),this.batchTimer=void 0,this.log("Max batch retries reached. BatchTimer cancelled.")),[3,4];case 4:return[2]}})})},e.prototype.sendBatch=function(e){return p(this,void 0,void 0,function(){var t,r,n,o,a,i;return g(this,function(s){switch(s.label){case 0:t="".concat(this.config.endpoint,"/api/v1/events"),r={"Content-Type":"application/json"},this.config.apiDetails&&this.config.apiDetails.apiEndPoint&&(t=this.config.apiDetails.apiEndPoint,this.config.apiDetails.headers&&(r=f(f({},r),this.config.apiDetails.headers))),n=this.config.clientId||"f01a232e-eacc-4c2e-8a06-f1c522cb8201",o=e.map(function(e){return f({event:e.event,userId:e.userId,client_id:n,timestamp:new Date(e.timestamp).toISOString()},e.properties||{})}),s.label=1;case 1:return s.trys.push([1,3,,4]),[4,fetch(t,{method:"POST",headers:r,body:JSON.stringify({events:o})})];case 2:if(!(a=s.sent()).ok)throw new Error("Failed to send batch: ".concat(a.status));return this.log("Batch sent successfully:",o),[3,4];case 3:throw i=s.sent(),this.log("Error sending batch:",i),i;case 4:return[2]}})})},e.prototype.generateSessionId=function(){return"sess_"+Math.random().toString(36).substr(2,9)},e.prototype.getUserId=function(){return"user_"+Math.random().toString(36).substr(2,9)},e.prototype.log=function(e,t){this.config.debug&&console.log("[AnalyticsPro SDK] ".concat(e),t||"")},e.prototype.saveConfigToFile=function(e){this.config.debug},e.prototype.loadConfigFromFile=function(){return p(this,void 0,void 0,function(){var e;return g(this,function(t){switch(t.label){case 0:return t.trys.push([0,3,,4]),[4,fetch("/AInamika_config.json",{cache:"reload"})];case 1:return(e=t.sent()).ok?[4,e.json()]:[2,null];case 2:return[2,t.sent()];case 3:return t.sent(),[2,null];case 4:return[2]}})})},e.prototype.setupDynamicDomTracking=function(){return p(this,void 0,void 0,function(){var e=this;return g(this,function(t){return"MutationObserver"in window&&(new MutationObserver(function(){e.mutationDebounceTimer&&clearTimeout(e.mutationDebounceTimer),e.mutationDebounceTimer=window.setTimeout(function(){e.handleDomMutation()},e.mutationDebounceMs)}).observe(document.body,{childList:!0,subtree:!0,attributes:!0}),this.log("Dynamic DOM MutationObserver attached")),[2]})})},e.prototype.computeDomHash=function(e){for(var t=JSON.stringify(e),r=2166136261,n=0;n<t.length;n++)r^=t.charCodeAt(n),r+=(r<<1)+(r<<4)+(r<<7)+(r<<8)+(r<<24);return(r>>>0).toString(16)},e.prototype.getCachedConfigForDomHash=function(e){try{return JSON.parse(localStorage.getItem("ainamika_dom_config_cache")||"{}")[e]||null}catch(e){return null}},e.prototype.setCachedConfigForDomHash=function(e,t){try{var r=JSON.parse(localStorage.getItem("ainamika_dom_config_cache")||"{}");r[e]=t,localStorage.setItem("ainamika_dom_config_cache",JSON.stringify(r))}catch(e){}},e.prototype.handleDomMutation=function(){return p(this,void 0,void 0,function(){var e,t,r,n;return g(this,function(o){switch(o.label){case 0:return[4,this.getDOMStructure()];case 1:return e=o.sent(),(t=this.computeDomHash(e))===this.lastDomHash?(this.log("DOM hash unchanged after mutation, skipping config fetch."),[2]):(this.log("DOM hash changed, checking for cached config...",{oldHash:this.lastDomHash,newHash:t}),this.lastDomHash=t,(r=this.getCachedConfigForDomHash(t))?(this.log("Reusing cached config for DOM hash",t),this.applyGeneratedConfig(r),[2]):(this.log("Fetching new config from backend for DOM hash:",t),[4,this.fetchGeneratedConfig(e,t)]));case 2:return(n=o.sent())&&n.events_to_track?(this.applyGeneratedConfig(n),this.setCachedConfigForDomHash(t,n),this.lastConfigHash=n.config_hash||"",this.log("Fetched and applied new config for new DOM hash",t)):this.log("No valid config returned for new DOM hash",t),[2]}})})},e}();"undefined"!=typeof window&&(window.AInamikaSDKPro=m);var v=m;return t.default}()});
2
+ //# sourceMappingURL=ainamika-sdk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ainamika-sdk.js","mappings":"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","sources":["webpack://AInamikaSDKPro/webpack/universalModuleDefinition","webpack://AInamikaSDKPro/webpack/bootstrap","webpack://AInamikaSDKPro/webpack/runtime/define property getters","webpack://AInamikaSDKPro/webpack/runtime/hasOwnProperty shorthand","webpack://AInamikaSDKPro/./src/error-tracker.ts","webpack://AInamikaSDKPro/./src/config.ts","webpack://AInamikaSDKPro/./src/error-storage.ts","webpack://AInamikaSDKPro/./src/sdk.ts"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"AInamikaSDKPro\"] = factory();\n\telse\n\t\troot[\"AInamikaSDKPro\"] = factory();\n})((typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : typeof global !== \"undefined\" ? global : this), function() {\nreturn ","// The require scope\nvar __webpack_require__ = {};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = function(exports, definition) {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }","// error-tracker.ts - Advanced Error Tracking System for AInamika SDK\n\nexport interface ErrorConfig {\n endpoint: string;\n clientId: string;\n apiKey: string;\n captureScreenshots?: boolean;\n captureDomSnapshots?: boolean;\n maxStackTraceDepth?: number;\n maxErrorsPerSession?: number;\n debounceMs?: number;\n enableNetworkTracking?: boolean;\n enableConsoleCapture?: boolean;\n}\n\nexport interface ErrorData {\n id?: string;\n client_id: string;\n error_type: 'javascript' | 'network' | 'unhandled' | 'console' | 'custom';\n message: string;\n stack_trace?: string;\n url: string;\n user_agent: string;\n timestamp: number;\n error_metadata: {\n line?: number;\n column?: number;\n filename?: string;\n component?: string;\n props?: Record<string, any>;\n userId?: string;\n sessionId?: string;\n breadcrumbs?: ErrorBreadcrumb[];\n networkInfo?: NetworkInfo;\n performance?: PerformanceInfo;\n };\n dom_snapshot?: string;\n screen_snapshot?: string;\n severity: 'low' | 'medium' | 'high' | 'critical';\n session_id: string;\n user_id?: string;\n}\n\nexport interface ErrorBreadcrumb {\n timestamp: number;\n type: 'navigation' | 'click' | 'console' | 'network' | 'error';\n message: string;\n data?: Record<string, any>;\n}\n\nexport interface NetworkInfo {\n effectiveType?: string;\n downlink?: number;\n rtt?: number;\n saveData?: boolean;\n}\n\nexport interface PerformanceInfo {\n memory?: {\n usedJSHeapSize: number;\n totalJSHeapSize: number;\n jsHeapSizeLimit: number;\n };\n timing?: {\n domContentLoaded: number;\n load: number;\n firstPaint?: number;\n firstContentfulPaint?: number;\n };\n}\n\nexport class ErrorTracker {\n private config: ErrorConfig;\n private breadcrumbs: ErrorBreadcrumb[] = [];\n private errorCount = 0;\n private errorDebounceMap = new Map<string, number>();\n private originalConsole: Console;\n private sessionId: string;\n private userId?: string;\n\n constructor(config: ErrorConfig) {\n this.config = {\n captureScreenshots: true,\n captureDomSnapshots: true,\n maxStackTraceDepth: 50,\n maxErrorsPerSession: 100,\n debounceMs: 1000,\n enableNetworkTracking: true,\n enableConsoleCapture: true,\n ...config\n };\n\n this.sessionId = this.generateSessionId();\n this.originalConsole = { ...console };\n this.initialize();\n }\n\n private initialize() {\n // Global error handler\n window.addEventListener('error', (event) => {\n this.handleError({\n type: 'javascript',\n message: event.message,\n filename: event.filename,\n line: event.lineno,\n column: event.colno,\n error: event.error\n });\n });\n\n // Unhandled promise rejection handler\n window.addEventListener('unhandledrejection', (event) => {\n this.handleError({\n type: 'unhandled',\n message: event.reason?.message || 'Unhandled Promise Rejection',\n error: event.reason,\n promise: true\n });\n });\n\n // Network error tracking\n if (this.config.enableNetworkTracking) {\n this.setupNetworkTracking();\n }\n\n // Console capture\n if (this.config.enableConsoleCapture) {\n this.setupConsoleCapture();\n }\n\n // Navigation breadcrumbs\n this.setupNavigationTracking();\n\n // Click breadcrumbs\n this.setupClickTracking();\n\n console.log('[AInamika Error Tracker] Initialized successfully');\n }\n\n private generateSessionId(): string {\n return `session_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n }\n\n private addBreadcrumb(breadcrumb: Omit<ErrorBreadcrumb, 'timestamp'>) {\n this.breadcrumbs.push({\n ...breadcrumb,\n timestamp: Date.now()\n });\n\n // Keep only last 50 breadcrumbs\n if (this.breadcrumbs.length > 50) {\n this.breadcrumbs = this.breadcrumbs.slice(-50);\n }\n }\n\n private handleError(errorInfo: any) {\n if (this.errorCount >= this.config.maxErrorsPerSession!) {\n console.warn('[AInamika Error Tracker] Max errors per session reached');\n return;\n }\n\n const errorKey = `${errorInfo.message}_${errorInfo.filename}_${errorInfo.line}`;\n const now = Date.now();\n \n // Debounce duplicate errors\n if (this.errorDebounceMap.has(errorKey)) {\n const lastTime = this.errorDebounceMap.get(errorKey)!;\n if (now - lastTime < this.config.debounceMs!) {\n return;\n }\n }\n this.errorDebounceMap.set(errorKey, now);\n\n this.errorCount++;\n this.captureError(errorInfo);\n }\n\n private async captureError(errorInfo: any) {\n try {\n const errorData: ErrorData = {\n client_id: this.config.clientId,\n error_type: errorInfo.type || 'javascript',\n message: errorInfo.message || 'Unknown error',\n stack_trace: this.extractStackTrace(errorInfo.error),\n url: window.location.href,\n user_agent: navigator.userAgent,\n timestamp: Date.now(),\n error_metadata: {\n line: errorInfo.line,\n column: errorInfo.column,\n filename: errorInfo.filename,\n userId: this.userId,\n sessionId: this.sessionId,\n breadcrumbs: [...this.breadcrumbs],\n networkInfo: this.getNetworkInfo(),\n performance: this.getPerformanceInfo()\n },\n severity: this.assessSeverity(errorInfo),\n session_id: this.sessionId,\n user_id: this.userId\n };\n\n // Capture DOM snapshot\n if (this.config.captureDomSnapshots) {\n errorData.dom_snapshot = this.captureDomSnapshot();\n }\n\n // Capture screenshot\n if (this.config.captureScreenshots) {\n errorData.screen_snapshot = await this.captureScreenshot();\n }\n\n // Send error to backend\n await this.sendError(errorData);\n\n // Add error breadcrumb\n this.addBreadcrumb({\n type: 'error',\n message: `${errorData.error_type}: ${errorData.message}`,\n data: { severity: errorData.severity }\n });\n\n } catch (captureError) {\n console.error('[AInamika Error Tracker] Failed to capture error:', captureError);\n }\n }\n\n private extractStackTrace(error: Error): string {\n if (!error || !error.stack) return '';\n \n const stack = error.stack.split('\\n');\n const maxDepth = this.config.maxStackTraceDepth!;\n \n return stack.slice(0, maxDepth).join('\\n');\n }\n\n private assessSeverity(errorInfo: any): 'low' | 'medium' | 'high' | 'critical' {\n const message = errorInfo.message?.toLowerCase() || '';\n \n // Critical errors\n if (message.includes('out of memory') || \n message.includes('security') ||\n message.includes('permission denied') ||\n errorInfo.type === 'unhandled') {\n return 'critical';\n }\n \n // High severity\n if (message.includes('network') || \n message.includes('timeout') ||\n message.includes('failed to fetch') ||\n message.includes('cors')) {\n return 'high';\n }\n \n // Medium severity\n if (message.includes('undefined') || \n message.includes('null') ||\n message.includes('cannot read property')) {\n return 'medium';\n }\n \n return 'low';\n }\n\n private captureDomSnapshot(): string {\n try {\n // Create a simplified DOM snapshot\n const snapshot = {\n url: window.location.href,\n title: document.title,\n viewport: {\n width: window.innerWidth,\n height: window.innerHeight\n },\n elements: this.extractDomElements()\n };\n \n return JSON.stringify(snapshot);\n } catch (error) {\n console.error('[AInamika Error Tracker] Failed to capture DOM snapshot:', error);\n return '';\n }\n }\n\n private extractDomElements(): any[] {\n const elements: any[] = [];\n const maxElements = 100;\n \n // Get key elements\n const selectors = [\n 'body > *',\n '[id]',\n '[class*=\"error\"]',\n '[class*=\"modal\"]',\n 'form',\n 'button',\n 'input[type=\"submit\"]'\n ];\n \n selectors.forEach(selector => {\n try {\n const els = document.querySelectorAll(selector);\n Array.from(els).slice(0, maxElements - elements.length).forEach(el => {\n elements.push({\n tagName: el.tagName,\n id: el.id,\n className: el.className,\n textContent: el.textContent?.substring(0, 100),\n attributes: this.getElementAttributes(el)\n });\n });\n } catch (e) {\n // Ignore selector errors\n }\n });\n \n return elements;\n }\n\n private getElementAttributes(element: Element): Record<string, string> {\n const attrs: Record<string, string> = {};\n const importantAttrs = ['id', 'class', 'type', 'name', 'value', 'href', 'src'];\n \n importantAttrs.forEach(attr => {\n const value = element.getAttribute(attr);\n if (value) attrs[attr] = value;\n });\n \n return attrs;\n }\n\n private async captureScreenshot(): Promise<string> {\n try {\n // Use html2canvas if available, otherwise return empty\n if (typeof (window as any).html2canvas === 'function') {\n const canvas = await (window as any).html2canvas(document.body, {\n height: Math.min(window.innerHeight, 1000),\n width: Math.min(window.innerWidth, 1000),\n useCORS: true\n });\n return canvas.toDataURL('image/jpeg', 0.7);\n }\n return '';\n } catch (error) {\n console.error('[AInamika Error Tracker] Failed to capture screenshot:', error);\n return '';\n }\n }\n\n private getNetworkInfo(): NetworkInfo {\n const connection = (navigator as any).connection || \n (navigator as any).mozConnection || \n (navigator as any).webkitConnection;\n \n if (!connection) return {};\n \n return {\n effectiveType: connection.effectiveType,\n downlink: connection.downlink,\n rtt: connection.rtt,\n saveData: connection.saveData\n };\n }\n\n private getPerformanceInfo(): PerformanceInfo {\n const info: PerformanceInfo = {};\n \n // Memory info\n if ((performance as any).memory) {\n info.memory = {\n usedJSHeapSize: (performance as any).memory.usedJSHeapSize,\n totalJSHeapSize: (performance as any).memory.totalJSHeapSize,\n jsHeapSizeLimit: (performance as any).memory.jsHeapSizeLimit\n };\n }\n \n // Timing info\n if (performance.timing) {\n const timing = performance.timing;\n info.timing = {\n domContentLoaded: timing.domContentLoadedEventEnd - timing.navigationStart,\n load: timing.loadEventEnd - timing.navigationStart\n };\n \n // Paint timings\n if (performance.getEntriesByType) {\n const paintEntries = performance.getEntriesByType('paint');\n paintEntries.forEach((entry: any) => {\n if (entry.name === 'first-paint') {\n info.timing!.firstPaint = entry.startTime;\n } else if (entry.name === 'first-contentful-paint') {\n info.timing!.firstContentfulPaint = entry.startTime;\n }\n });\n }\n }\n \n return info;\n }\n\n private setupNetworkTracking() {\n // Override fetch\n const originalFetch = window.fetch;\n window.fetch = async (...args) => {\n const startTime = Date.now();\n const url = args[0] instanceof Request ? args[0].url : String(args[0]);\n \n try {\n const response = await originalFetch(...args);\n \n this.addBreadcrumb({\n type: 'network',\n message: `Fetch ${response.status} ${url}`,\n data: {\n url,\n status: response.status,\n duration: Date.now() - startTime\n }\n });\n \n if (!response.ok) {\n this.handleError({\n type: 'network',\n message: `Network request failed: ${response.status} ${response.statusText}`,\n url,\n status: response.status\n });\n }\n \n return response;\n } catch (error: any) {\n this.addBreadcrumb({\n type: 'network',\n message: `Fetch failed ${url}`,\n data: { url, error: error?.message || 'Unknown error' }\n });\n \n this.handleError({\n type: 'network',\n message: `Network request failed: ${error?.message || 'Unknown error'}`,\n url,\n error\n });\n \n throw error;\n }\n };\n\n // Override XMLHttpRequest\n const originalXHROpen = XMLHttpRequest.prototype.open;\n const originalXHRSend = XMLHttpRequest.prototype.send;\n \n XMLHttpRequest.prototype.open = function(method: string, url: string | URL, async?: boolean, username?: string | null, password?: string | null) {\n (this as any)._errorTracker = { method, url, startTime: Date.now() };\n return originalXHROpen.call(this, method, url, async || true, username, password);\n };\n \n XMLHttpRequest.prototype.send = function(...args) {\n const tracker = (this as any)._errorTracker;\n \n this.addEventListener('loadend', () => {\n if (tracker) {\n const duration = Date.now() - tracker.startTime;\n \n if (this.status >= 400) {\n this.dispatchEvent(new CustomEvent('networkerror', {\n detail: {\n type: 'network',\n message: `XHR request failed: ${this.status} ${this.statusText}`,\n url: tracker.url,\n status: this.status\n }\n }));\n }\n \n this.dispatchEvent(new CustomEvent('networkbreadcrumb', {\n detail: {\n type: 'network',\n message: `XHR ${this.status} ${tracker.url}`,\n data: {\n method: tracker.method,\n url: tracker.url,\n status: this.status,\n duration\n }\n }\n }));\n }\n });\n \n return originalXHRSend.call(this, ...args);\n };\n \n // Listen for custom events\n document.addEventListener('networkerror', (event: any) => {\n this.handleError(event.detail);\n });\n \n document.addEventListener('networkbreadcrumb', (event: any) => {\n this.addBreadcrumb(event.detail);\n });\n }\n\n private setupConsoleCapture() {\n // Override console methods\n ['error', 'warn'].forEach(method => {\n const original = this.originalConsole[method as keyof Console] as Function;\n (console as any)[method] = (...args: any[]) => {\n if (typeof original === 'function') {\n original.call(console, ...args);\n }\n \n if (method === 'error') {\n this.handleError({\n type: 'console',\n message: args.map(arg => String(arg)).join(' '),\n consoleMethod: method\n });\n }\n \n this.addBreadcrumb({\n type: 'console',\n message: `Console ${method}: ${args.map(arg => String(arg)).join(' ')}`,\n data: { level: method }\n });\n };\n });\n }\n\n private setupNavigationTracking() {\n // Track page changes\n let currentUrl = window.location.href;\n \n const trackNavigation = () => {\n const newUrl = window.location.href;\n if (newUrl !== currentUrl) {\n this.addBreadcrumb({\n type: 'navigation',\n message: `Navigation from ${currentUrl} to ${newUrl}`,\n data: { from: currentUrl, to: newUrl }\n });\n currentUrl = newUrl;\n }\n };\n \n // Listen for various navigation events\n window.addEventListener('popstate', trackNavigation);\n window.addEventListener('hashchange', trackNavigation);\n \n // Override pushState and replaceState\n const originalPushState = history.pushState;\n const originalReplaceState = history.replaceState;\n \n history.pushState = function(...args) {\n originalPushState.apply(this, args);\n setTimeout(trackNavigation, 0);\n };\n \n history.replaceState = function(...args) {\n originalReplaceState.apply(this, args);\n setTimeout(trackNavigation, 0);\n };\n }\n\n private setupClickTracking() {\n document.addEventListener('click', (event) => {\n const target = event.target as Element;\n if (!target) return;\n \n const selector = this.getElementSelector(target);\n const text = target.textContent?.trim().substring(0, 50) || '';\n \n this.addBreadcrumb({\n type: 'click',\n message: `Clicked ${selector}${text ? `: ${text}` : ''}`,\n data: {\n selector,\n text,\n tagName: target.tagName,\n id: target.id,\n className: target.className\n }\n });\n });\n }\n\n private getElementSelector(element: Element): string {\n if (element.id) return `#${element.id}`;\n if (element.className) {\n const classes = element.className.split(' ').filter(c => c).slice(0, 2);\n if (classes.length) return `.${classes.join('.')}`;\n }\n return element.tagName.toLowerCase();\n }\n\n private async sendError(errorData: ErrorData) {\n try {\n const response = await fetch(`${this.config.endpoint}/api/v1/errors`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.config.apiKey}`\n },\n body: JSON.stringify(errorData)\n });\n\n if (!response.ok) {\n throw new Error(`Failed to send error: ${response.status} ${response.statusText}`);\n }\n\n console.log('[AInamika Error Tracker] Error sent successfully');\n } catch (error) {\n console.error('[AInamika Error Tracker] Failed to send error:', error);\n // Store error locally for retry\n this.storeErrorLocally(errorData);\n }\n }\n\n private storeErrorLocally(errorData: ErrorData) {\n try {\n const stored = localStorage.getItem('ainamika_errors') || '[]';\n const errors = JSON.parse(stored);\n errors.push(errorData);\n \n // Keep only last 50 errors\n if (errors.length > 50) {\n errors.splice(0, errors.length - 50);\n }\n \n localStorage.setItem('ainamika_errors', JSON.stringify(errors));\n } catch (error) {\n console.error('[AInamika Error Tracker] Failed to store error locally:', error);\n }\n }\n\n // Public methods\n public captureException(error: Error, context?: Record<string, any>) {\n this.handleError({\n type: 'custom',\n message: error.message,\n error,\n context\n });\n }\n\n public setUser(userId: string) {\n this.userId = userId;\n }\n\n public addTag(key: string, value: string) {\n // Add custom tags to error metadata\n if (!this.config.clientId) {\n this.config.clientId += `_${key}:${value}`;\n }\n }\n\n public async flushStoredErrors() {\n try {\n const stored = localStorage.getItem('ainamika_errors');\n if (!stored) return;\n \n const errors = JSON.parse(stored);\n if (errors.length === 0) return;\n \n console.log(`[AInamika Error Tracker] Flushing ${errors.length} stored errors`);\n \n for (const error of errors) {\n await this.sendError(error);\n }\n \n localStorage.removeItem('ainamika_errors');\n } catch (error) {\n console.error('[AInamika Error Tracker] Failed to flush stored errors:', error);\n }\n }\n}\n","// config.ts - Environment-based configuration for Ainamika SDK\n\nexport interface EnvironmentConfig {\n API_BASE_URL: string;\n APP_ENV: 'development' | 'production';\n DEBUG: boolean;\n}\n\n// Environment configuration with fallbacks\ndeclare global {\n interface Window {\n __AINAMIKA_CONFIG__?: EnvironmentConfig;\n }\n}\n\n// Get environment configuration\nfunction getEnvironmentConfig(): EnvironmentConfig {\n // Check for explicitly set configuration\n if (typeof window !== 'undefined' && window.__AINAMIKA_CONFIG__) {\n return window.__AINAMIKA_CONFIG__;\n }\n\n // Default configuration based on hostname\n const isLocal = typeof window !== 'undefined' && \n (window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1');\n \n return {\n API_BASE_URL: isLocal ? 'http://localhost:5000' : 'https://ainamika-backend-768143418383.europe-west1.run.app',\n APP_ENV: isLocal ? 'development' : 'production',\n DEBUG: isLocal\n };\n}\n\nexport const ENV_CONFIG = getEnvironmentConfig();\n\n// API endpoint configuration\nexport const API_ENDPOINTS = {\n EVENTS: `${ENV_CONFIG.API_BASE_URL}/api/v1/events`,\n ERRORS: `${ENV_CONFIG.API_BASE_URL}/api/errors/report`,\n CONFIG: `${ENV_CONFIG.API_BASE_URL}/api/v1/sdk/config`,\n DEBUG_EVENTS: `${ENV_CONFIG.API_BASE_URL}/api/v1/debug/events`\n};\n\n// Configuration helper function\nexport function configureSDK(config: Partial<EnvironmentConfig>) {\n if (typeof window !== 'undefined') {\n window.__AINAMIKA_CONFIG__ = { ...ENV_CONFIG, ...config };\n }\n}\n\n// Log configuration for debugging\nif (ENV_CONFIG.DEBUG) {\n console.log('[Ainamika SDK] Environment Configuration:', {\n API_BASE_URL: ENV_CONFIG.API_BASE_URL,\n APP_ENV: ENV_CONFIG.APP_ENV,\n DEBUG: ENV_CONFIG.DEBUG,\n ENDPOINTS: API_ENDPOINTS\n });\n}","// error-storage.ts - Offline Storage and Queue Management for Error Tracking\nimport { API_ENDPOINTS } from './config';\n\nexport interface StoredError {\n id: string;\n errorData: any;\n timestamp: number;\n retryCount: number;\n lastRetry?: number;\n}\n\nexport interface StorageConfig {\n maxStorageSize: number;\n maxRetries: number;\n retryInterval: number;\n compressionEnabled: boolean;\n encryptionEnabled: boolean;\n}\n\nexport class ErrorStorage {\n private config: StorageConfig;\n private readonly STORAGE_KEY = 'ainamika_error_queue';\n private readonly METADATA_KEY = 'ainamika_error_metadata';\n private retryTimer?: number;\n private isProcessing = false;\n\n constructor(config: Partial<StorageConfig> = {}) {\n this.config = {\n maxStorageSize: 5 * 1024 * 1024, // 5MB\n maxRetries: 5,\n retryInterval: 30000, // 30 seconds\n compressionEnabled: true,\n encryptionEnabled: false,\n ...config\n };\n\n this.initialize();\n }\n\n private initialize() {\n this.cleanupOldErrors();\n this.startRetryTimer();\n this.setupStorageListener();\n \n // Process any existing errors on initialization\n setTimeout(() => this.processQueue(), 1000);\n }\n\n /**\n * Store error data with automatic compression and queue management\n */\n public async storeError(errorData: any): Promise<string> {\n try {\n const errorId = this.generateErrorId();\n const storedError: StoredError = {\n id: errorId,\n errorData: this.config.compressionEnabled ? this.compressData(errorData) : errorData,\n timestamp: Date.now(),\n retryCount: 0\n };\n\n await this.addToQueue(storedError);\n this.updateMetadata();\n \n // Trigger immediate processing\n setTimeout(() => this.processQueue(), 100);\n \n return errorId;\n } catch (error) {\n console.error('[AInamika Error Storage] Failed to store error:', error);\n throw error;\n }\n }\n\n /**\n * Get all stored errors\n */\n public getStoredErrors(): StoredError[] {\n try {\n const stored = localStorage.getItem(this.STORAGE_KEY);\n if (!stored) return [];\n \n const errors = JSON.parse(stored) as StoredError[];\n return errors.map(error => ({\n ...error,\n errorData: this.config.compressionEnabled ? this.decompressData(error.errorData) : error.errorData\n }));\n } catch (error) {\n console.error('[AInamika Error Storage] Failed to get stored errors:', error);\n return [];\n }\n }\n\n /**\n * Remove error from storage\n */\n public removeError(errorId: string): boolean {\n try {\n const errors = this.getQueueRaw();\n const filteredErrors = errors.filter(error => error.id !== errorId);\n \n if (filteredErrors.length !== errors.length) {\n localStorage.setItem(this.STORAGE_KEY, JSON.stringify(filteredErrors));\n this.updateMetadata();\n return true;\n }\n return false;\n } catch (error) {\n console.error('[AInamika Error Storage] Failed to remove error:', error);\n return false;\n }\n }\n\n /**\n * Clear all stored errors\n */\n public clearAll(): void {\n try {\n localStorage.removeItem(this.STORAGE_KEY);\n localStorage.removeItem(this.METADATA_KEY);\n console.log('[AInamika Error Storage] All errors cleared');\n } catch (error) {\n console.error('[AInamika Error Storage] Failed to clear errors:', error);\n }\n }\n\n /**\n * Get storage statistics\n */\n public getStorageStats(): {\n errorCount: number;\n totalSize: number;\n oldestError?: number;\n newestError?: number;\n } {\n try {\n const errors = this.getQueueRaw();\n const totalSize = new Blob([localStorage.getItem(this.STORAGE_KEY) || '']).size;\n \n const timestamps = errors.map(e => e.timestamp).sort();\n \n return {\n errorCount: errors.length,\n totalSize,\n oldestError: timestamps[0],\n newestError: timestamps[timestamps.length - 1]\n };\n } catch (error) {\n console.error('[AInamika Error Storage] Failed to get storage stats:', error);\n return { errorCount: 0, totalSize: 0 };\n }\n }\n\n /**\n * Process the error queue - attempt to send stored errors\n */\n public async processQueue(): Promise<void> {\n if (this.isProcessing) return;\n \n this.isProcessing = true;\n \n try {\n const errors = this.getQueueRaw();\n if (errors.length === 0) return;\n \n console.log(`[AInamika Error Storage] Processing ${errors.length} queued errors`);\n \n for (const storedError of errors) {\n if (storedError.retryCount >= this.config.maxRetries) {\n console.warn(`[AInamika Error Storage] Max retries reached for error ${storedError.id}`);\n this.removeError(storedError.id);\n continue;\n }\n\n // Check retry interval\n if (storedError.lastRetry && \n Date.now() - storedError.lastRetry < this.config.retryInterval) {\n continue;\n }\n\n try {\n const success = await this.sendError(storedError);\n if (success) {\n this.removeError(storedError.id);\n console.log(`[AInamika Error Storage] Successfully sent error ${storedError.id}`);\n } else {\n this.incrementRetryCount(storedError.id);\n }\n } catch (error) {\n console.error(`[AInamika Error Storage] Failed to send error ${storedError.id}:`, error);\n this.incrementRetryCount(storedError.id);\n }\n }\n } finally {\n this.isProcessing = false;\n }\n }\n\n /**\n * Force retry of a specific error\n */\n public async retryError(errorId: string): Promise<boolean> {\n const errors = this.getQueueRaw();\n const error = errors.find(e => e.id === errorId);\n \n if (!error) return false;\n \n try {\n const success = await this.sendError(error);\n if (success) {\n this.removeError(errorId);\n return true;\n } else {\n this.incrementRetryCount(errorId);\n return false;\n }\n } catch (err) {\n console.error(`[AInamika Error Storage] Failed to retry error ${errorId}:`, err);\n this.incrementRetryCount(errorId);\n return false;\n }\n }\n\n private async addToQueue(storedError: StoredError): Promise<void> {\n const errors = this.getQueueRaw();\n errors.push(storedError);\n \n // Check storage size limit\n const serialized = JSON.stringify(errors);\n if (new Blob([serialized]).size > this.config.maxStorageSize) {\n // Remove oldest errors until under limit\n while (errors.length > 0 && new Blob([JSON.stringify(errors)]).size > this.config.maxStorageSize) {\n errors.shift();\n console.warn('[AInamika Error Storage] Removed old error due to size limit');\n }\n }\n \n localStorage.setItem(this.STORAGE_KEY, JSON.stringify(errors));\n }\n\n private getQueueRaw(): StoredError[] {\n try {\n const stored = localStorage.getItem(this.STORAGE_KEY);\n return stored ? JSON.parse(stored) : [];\n } catch (error) {\n console.error('[AInamika Error Storage] Failed to parse stored errors:', error);\n return [];\n }\n }\n\n private incrementRetryCount(errorId: string): void {\n try {\n const errors = this.getQueueRaw();\n const errorIndex = errors.findIndex(e => e.id === errorId);\n \n if (errorIndex !== -1) {\n errors[errorIndex].retryCount++;\n errors[errorIndex].lastRetry = Date.now();\n localStorage.setItem(this.STORAGE_KEY, JSON.stringify(errors));\n }\n } catch (error) {\n console.error('[AInamika Error Storage] Failed to increment retry count:', error);\n }\n }\n\n private async sendError(storedError: StoredError): Promise<boolean> {\n try {\n const errorData = this.config.compressionEnabled ? \n this.decompressData(storedError.errorData) : \n storedError.errorData;\n\n // This should match the ErrorTracker's endpoint configuration\n const endpoint = errorData.endpoint || API_ENDPOINTS.ERRORS;\n const apiKey = errorData.apiKey || '';\n \n const response = await fetch(`${endpoint}/api/v1/errors`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': apiKey ? `Bearer ${apiKey}` : ''\n },\n body: JSON.stringify(errorData)\n });\n\n return response.ok;\n } catch (error) {\n console.error('[AInamika Error Storage] Network error sending stored error:', error);\n return false;\n }\n }\n\n private compressData(data: any): string {\n try {\n // Simple compression using JSON + base64\n const jsonString = JSON.stringify(data);\n return btoa(jsonString);\n } catch (error) {\n console.warn('[AInamika Error Storage] Compression failed, storing uncompressed:', error);\n return data;\n }\n }\n\n private decompressData(compressedData: any): any {\n try {\n if (typeof compressedData === 'string' && compressedData.length > 0) {\n const jsonString = atob(compressedData);\n return JSON.parse(jsonString);\n }\n return compressedData;\n } catch (error) {\n console.warn('[AInamika Error Storage] Decompression failed, returning raw data:', error);\n return compressedData;\n }\n }\n\n private generateErrorId(): string {\n return `error_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n }\n\n private cleanupOldErrors(): void {\n try {\n const errors = this.getQueueRaw();\n const cutoffTime = Date.now() - (7 * 24 * 60 * 60 * 1000); // 7 days\n \n const cleanErrors = errors.filter(error => error.timestamp > cutoffTime);\n \n if (cleanErrors.length !== errors.length) {\n localStorage.setItem(this.STORAGE_KEY, JSON.stringify(cleanErrors));\n console.log(`[AInamika Error Storage] Cleaned up ${errors.length - cleanErrors.length} old errors`);\n }\n } catch (error) {\n console.error('[AInamika Error Storage] Failed to cleanup old errors:', error);\n }\n }\n\n private startRetryTimer(): void {\n this.retryTimer = window.setInterval(() => {\n this.processQueue();\n }, this.config.retryInterval);\n }\n\n private setupStorageListener(): void {\n // Listen for storage changes from other tabs\n window.addEventListener('storage', (event) => {\n if (event.key === this.STORAGE_KEY) {\n console.log('[AInamika Error Storage] Storage updated from another tab');\n setTimeout(() => this.processQueue(), 1000);\n }\n });\n\n // Listen for online/offline events\n window.addEventListener('online', () => {\n console.log('[AInamika Error Storage] Network back online, processing queue');\n setTimeout(() => this.processQueue(), 1000);\n });\n\n window.addEventListener('offline', () => {\n console.log('[AInamika Error Storage] Network offline, errors will be queued');\n });\n }\n\n private updateMetadata(): void {\n try {\n const stats = this.getStorageStats();\n const metadata = {\n lastUpdate: Date.now(),\n ...stats\n };\n localStorage.setItem(this.METADATA_KEY, JSON.stringify(metadata));\n } catch (error) {\n console.error('[AInamika Error Storage] Failed to update metadata:', error);\n }\n }\n\n /**\n * Export stored errors for debugging\n */\n public exportErrors(): string {\n try {\n const errors = this.getStoredErrors();\n const exportData = {\n timestamp: Date.now(),\n version: '1.0',\n stats: this.getStorageStats(),\n errors: errors\n };\n return JSON.stringify(exportData, null, 2);\n } catch (error) {\n console.error('[AInamika Error Storage] Failed to export errors:', error);\n return '{}';\n }\n }\n\n /**\n * Import errors from export\n */\n public importErrors(exportData: string): boolean {\n try {\n const data = JSON.parse(exportData);\n if (!data.errors || !Array.isArray(data.errors)) {\n throw new Error('Invalid export format');\n }\n\n this.clearAll();\n \n for (const errorData of data.errors) {\n this.storeError(errorData.errorData);\n }\n \n console.log(`[AInamika Error Storage] Imported ${data.errors.length} errors`);\n return true;\n } catch (error) {\n console.error('[AInamika Error Storage] Failed to import errors:', error);\n return false;\n }\n }\n\n /**\n * Cleanup and destroy the storage instance\n */\n public destroy(): void {\n if (this.retryTimer) {\n clearInterval(this.retryTimer);\n this.retryTimer = undefined;\n }\n \n // Final attempt to process queue\n this.processQueue();\n \n console.log('[AInamika Error Storage] Storage instance destroyed');\n }\n}\n\n/**\n * Utility functions for error storage management\n */\nexport class ErrorStorageUtils {\n /**\n * Get total localStorage usage for AInamika\n */\n static getAinamikaStorageUsage(): { \n totalSize: number; \n errorSize: number; \n otherSize: number; \n } {\n let totalSize = 0;\n let errorSize = 0;\n let otherSize = 0;\n\n for (let key in localStorage) {\n if (localStorage.hasOwnProperty(key)) {\n const size = new Blob([localStorage.getItem(key) || '']).size;\n totalSize += size;\n \n if (key.startsWith('ainamika_error')) {\n errorSize += size;\n } else if (key.startsWith('ainamika_')) {\n otherSize += size;\n }\n }\n }\n\n return { totalSize, errorSize, otherSize };\n }\n\n /**\n * Check if localStorage has enough space\n */\n static checkStorageSpace(requiredBytes: number): boolean {\n try {\n const testKey = 'ainamika_storage_test';\n const testData = 'x'.repeat(Math.min(requiredBytes, 1024 * 1024));\n \n localStorage.setItem(testKey, testData);\n localStorage.removeItem(testKey);\n \n return true;\n } catch (error) {\n return false;\n }\n }\n\n /**\n * Clean up all AInamika storage\n */\n static cleanupAllAinamikaStorage(): void {\n const keysToRemove: string[] = [];\n \n for (let key in localStorage) {\n if (key.startsWith('ainamika_')) {\n keysToRemove.push(key);\n }\n }\n \n keysToRemove.forEach(key => localStorage.removeItem(key));\n console.log(`[AInamika Storage Utils] Cleaned up ${keysToRemove.length} storage keys`);\n }\n\n /**\n * Generate storage report\n */\n static generateStorageReport(): {\n usage: ReturnType<typeof ErrorStorageUtils.getAinamikaStorageUsage>;\n errors: any[];\n metadata: any;\n } {\n const storage = new ErrorStorage();\n \n return {\n usage: ErrorStorageUtils.getAinamikaStorageUsage(),\n errors: storage.getStoredErrors(),\n metadata: storage.getStorageStats()\n };\n }\n}\n","// src/index.ts - Main SDK entry point\nimport { ErrorTracker, ErrorConfig } from './error-tracker';\nimport { ErrorStorage } from './error-storage';\nimport { ENV_CONFIG, API_ENDPOINTS } from './config';\n\ninterface AnalyticsConfig {\n apiKey: string;\n endpoint?: string;\n autoConfig?: boolean;\n batchInterval?: number;\n useWebWorker?: boolean;\n workerPath?: string;\n debug?: boolean;\n clientId: string; // Optional client ID for user tracking\n apiDetails?: {\n apiEndPoint: string;\n headers?: Record<string, string>;\n };\n workerConfig?: {\n batchSize?: number;\n batchInterval?: number;\n };\n errorTracking?: {\n enabled?: boolean;\n captureScreenshots?: boolean;\n captureDomSnapshots?: boolean;\n maxStackTraceDepth?: number;\n maxErrorsPerSession?: number;\n debounceMs?: number;\n enableNetworkTracking?: boolean;\n enableConsoleCapture?: boolean;\n };\n}\n\ninterface EventData {\n event: string;\n properties?: Record<string, any>;\n timestamp?: number;\n userId?: string;\n sessionId?: string;\n}\n\ninterface AutoConfigResult {\n autoTrack: {\n clicks: string[];\n pageViews: boolean;\n formSubmissions: string[];\n customEvents: Record<string, any>;\n };\n metadata: {\n appType: string;\n framework: string;\n confidence: number;\n };\n}\n\nclass AInamikaSDKPro {\n private config: AnalyticsConfig;\n private worker: Worker;\n private sessionId: string;\n private autoConfig?: AutoConfigResult;\n private batchTimer?: number;\n private eventQueue: Map<string, any>[] = [];\n private isInitialized = false;\n private batchRetryCount: number = 0;\n private maxBatchRetries: number = 5;\n\n // --- Error Tracking Components ---\n private errorTracker?: ErrorTracker;\n private errorStorage?: ErrorStorage;\n\n // --- Dynamic DOM Fingerprinting and Smart Debouncing ---\n private domHashCache: Record<string, any> = {};\n private lastDomHash: string = '';\n private lastConfigHash: string = '';\n private mutationDebounceTimer: number | null = null;\n private mutationDebounceMs: number = 2000; // 2s debounce for dynamic DOM\n\n // Track attached event types per element to prevent duplicate listeners\n private attachedListeners: WeakMap<Element, Set<string>> = new WeakMap();\n\n constructor(config: AnalyticsConfig) {\n this.config = {\n endpoint: ENV_CONFIG.API_BASE_URL,\n batchInterval: 5000,\n useWebWorker: true,\n debug: ENV_CONFIG.DEBUG,\n errorTracking: {\n enabled: true,\n captureScreenshots: true,\n captureDomSnapshots: true,\n maxStackTraceDepth: 50,\n maxErrorsPerSession: 100,\n debounceMs: 1000,\n enableNetworkTracking: true,\n enableConsoleCapture: true\n },\n ...config\n };\n\n this.sessionId = this.generateSessionId();\n // Inline the worker code as a Blob to avoid cross-origin issues\n const workerCode = `\n self.eventQueue = [];\n self.config = {\n apiUrl: '',\n batchSize: 10,\n batchInterval: 5000,\n headers: { 'Content-Type': 'application/json' }\n };\n let batchTimer = null;\n function flushQueue() {\n self.postMessage({ status: 'debug', message: '[AInamika Worker] flushQueue called', eventQueue: self.eventQueue, config: self.config });\n if (self.eventQueue.length === 0) return;\n const batch = self.eventQueue.splice(0, self.config.batchSize);\n fetch(self.config.apiUrl, {\n method: 'POST',\n headers: self.config.headers,\n body: JSON.stringify({ events: batch })\n }).then(r => {\n if (r.ok) {\n self.postMessage({ status: 'success' });\n } else {\n self.postMessage({ status: 'error', error: r.statusText, failedEvents: batch });\n }\n }).catch(e => {\n self.postMessage({ status: 'error', error: e.message, failedEvents: batch });\n });\n }\n self.onmessage = function(e) {\n self.postMessage({ status: 'debug', message: '[AInamika Worker] onmessage', data: e.data });\n if (e.data.type === 'config') {\n self.config = { ...self.config, ...e.data.payload };\n if (batchTimer) clearInterval(batchTimer);\n batchTimer = setInterval(flushQueue, self.config.batchInterval);\n self.postMessage({ status: 'debug', message: '[AInamika Worker] config set', config: self.config });\n } else if (e.data.type === 'track') {\n self.eventQueue.push(e.data.payload);\n // Only send when timer triggers, not when batch size is reached\n // This ensures true batching behavior\n } else if (e.data.type === 'batch') {\n // Handle batch flush from main thread\n self.postMessage({ status: 'debug', message: '[AInamika Worker] Received batch from main thread', events: e.data.events });\n self.eventQueue.push(...e.data.events);\n flushQueue();\n } else if (e.data.type === 'initConfig') {\n // No-op for now, can be used for advanced config\n }\n };\n `;\n const blob = new Blob([workerCode], { type: 'application/javascript' });\n const workerUrl = URL.createObjectURL(blob);\n this.worker = new Worker(workerUrl);\n this.initialize();\n }\n\n private async initialize() {\n if (this.isInitialized) return;\n this.isInitialized = true;\n\n // Initialize Error Tracking\n if (this.config.errorTracking?.enabled) {\n this.initializeErrorTracking();\n }\n\n if (this.config.autoConfig) {\n await this.setupAutoConfiguration();\n }\n\n // Always enable dynamic DOM tracking for dynamic apps\n this.setupDynamicDomTracking();\n\n if (this.config.useWebWorker && typeof Worker !== 'undefined') {\n this.setupWebWorker();\n } else {\n // Fallback for environments without web workers\n this.startBatchTimer();\n }\n this.log('AnalyticsPro SDK initialized', { config: this.config });\n }\n\n // --- Error Tracking Initialization ---\n private initializeErrorTracking() {\n try {\n // Initialize error storage\n this.errorStorage = new ErrorStorage({\n maxStorageSize: 5 * 1024 * 1024, // 5MB\n maxRetries: 5,\n retryInterval: 30000, // 30 seconds\n compressionEnabled: true,\n encryptionEnabled: false\n });\n\n // Initialize error tracker\n const errorConfig: ErrorConfig = {\n endpoint: ENV_CONFIG.API_BASE_URL,\n clientId: this.config.clientId,\n apiKey: this.config.apiKey,\n captureScreenshots: this.config.errorTracking?.captureScreenshots ?? true,\n captureDomSnapshots: this.config.errorTracking?.captureDomSnapshots ?? true,\n maxStackTraceDepth: this.config.errorTracking?.maxStackTraceDepth ?? 50,\n maxErrorsPerSession: this.config.errorTracking?.maxErrorsPerSession ?? 100,\n debounceMs: this.config.errorTracking?.debounceMs ?? 1000,\n enableNetworkTracking: this.config.errorTracking?.enableNetworkTracking ?? true,\n enableConsoleCapture: this.config.errorTracking?.enableConsoleCapture ?? true\n };\n\n this.errorTracker = new ErrorTracker(errorConfig);\n \n // Set user for error tracking if available\n const userId = this.getUserId();\n if (userId && this.errorTracker) {\n this.errorTracker.setUser(userId);\n }\n\n this.log('Error tracking initialized successfully');\n } catch (error) {\n console.error('[AInamika SDK] Failed to initialize error tracking:', error);\n }\n }\n\n // Public method to capture custom exceptions\n public captureException(error: Error, context?: Record<string, any>) {\n if (this.errorTracker) {\n this.errorTracker.captureException(error, context);\n }\n }\n\n // Public method to set user for error tracking\n public setUser(userId: string) {\n if (this.errorTracker) {\n this.errorTracker.setUser(userId);\n }\n }\n\n // Public method to flush stored errors\n public async flushStoredErrors() {\n if (this.errorStorage) {\n await this.errorStorage.processQueue();\n }\n if (this.errorTracker) {\n await this.errorTracker.flushStoredErrors();\n }\n }\n\n private async setupAutoConfiguration() {\n try {\n this.log('Starting auto-configuration...');\n // Compute current DOM structure and hash\n const domStructure = await this.getDOMStructure();\n const domHash = this.computeDomHash(domStructure);\n this.lastDomHash = domHash; // Store the initial DOM hash\n \n // Try to load config from localStorage cache first using DOM hash\n let generatedConfig = this.getCachedConfigForDomHash(domHash);\n \n if (generatedConfig) {\n this.log('Loaded analytics config from localStorage cache for DOM hash:', domHash);\n } else {\n // Try to load config from file as fallback\n generatedConfig = await this.loadConfigFromFile();\n if (generatedConfig) {\n this.log('Loaded analytics config from file');\n }\n }\n \n if (!generatedConfig) {\n // Only call API if not found in cache or file, and include DOM hash\n this.log('No cached config found, fetching from backend for DOM hash:', domHash);\n generatedConfig = await this.fetchGeneratedConfig(domStructure, domHash);\n if (generatedConfig && generatedConfig.events_to_track) {\n this.saveConfigToFile(generatedConfig);\n this.setCachedConfigForDomHash(domHash, generatedConfig);\n this.lastConfigHash = generatedConfig.config_hash || '';\n }\n }\n \n if (generatedConfig && generatedConfig.events_to_track) {\n this.applyGeneratedConfig(generatedConfig);\n // Send config to worker for advanced tracking (scroll, focus, etc.)\n if (this.config.useWebWorker && typeof Worker !== 'undefined') {\n this.worker.postMessage({ type: 'initConfig', config: generatedConfig });\n }\n this.log('Auto-configuration applied successfully', generatedConfig);\n } else {\n this.log('Auto-configuration failed: Invalid config received from backend.', generatedConfig);\n }\n } catch (error) {\n this.log('Auto-configuration failed with error', error);\n }\n }\n\n private async getDOMStructure(): Promise<any> {\n const getSelector = (el: Element): string => {\n if (el.id) return `#${el.id}`;\n if (el.className) {\n const classes = el.className.split(' ').filter(c => c.trim()).join('.');\n return classes ? `.${classes}` : el.tagName.toLowerCase();\n }\n return el.tagName.toLowerCase();\n };\n\n // Wait a bit for any dynamic content to load\n await new Promise(resolve => setTimeout(resolve, 500));\n\n // Comprehensive selector for all interactive and important elements\n const elements = Array.from(document.body.querySelectorAll(`\n button, a, input, select, textarea, form, img, h1, h2, h3, h4, h5, h6,\n [role=button], [role=link], [onclick], [tabindex], [data-analytics], [data-track],\n .card, .btn, .btn-primary, .btn-secondary, .card-title, .card-description, .card-price, .card-actions,\n [id*=\"card\"], [class*=\"card\"], [class*=\"btn\"], [class*=\"price\"], [class*=\"title\"],\n div, span, p\n `));\n\n // Filter and enhance elements with more comprehensive logic\n const filteredElements = elements.filter(el => {\n const style = window.getComputedStyle(el);\n const isVisible = style.display !== 'none' && style.visibility !== 'hidden' && style.opacity !== '0';\n const hasInteraction = el.tagName.toLowerCase() === 'button' || \n el.tagName.toLowerCase() === 'a' || \n el.hasAttribute('onclick') ||\n el.getAttribute('role') === 'button' ||\n el.classList.contains('btn') ||\n el.classList.contains('card');\n const isImportantElement = el.id === 'cardsContainer' || \n el.classList.contains('cards-grid') ||\n el.classList.contains('card') ||\n el.tagName.toLowerCase() === 'img' ||\n ['h1', 'h2', 'h3'].indexOf(el.tagName.toLowerCase()) !== -1;\n \n return (isVisible && (hasInteraction || isImportantElement)) || el.id === 'cardsContainer';\n });\n\n // Deduplicate and add stable metadata (exclude dynamic properties)\n const seen = new Set<string>();\n const structure = filteredElements.map(el => {\n // Only include stable attributes that don't change between page loads\n const stableAttributes: Record<string, string> = {};\n Array.from(el.attributes).forEach(attr => {\n // Exclude dynamic attributes that might change\n if (['style', 'data-timestamp', 'data-rendered'].indexOf(attr.name) === -1) {\n stableAttributes[attr.name] = attr.value;\n }\n });\n \n const obj = {\n tagName: el.tagName.toLowerCase(),\n selector: getSelector(el),\n id: el.id || '',\n className: el.className || '',\n textContent: (el.textContent || '').trim().substring(0, 100),\n attributes: stableAttributes,\n // Remove position and computed styles as they can vary\n isInteractive: el.tagName.toLowerCase() === 'button' || \n el.tagName.toLowerCase() === 'a' || \n el.hasAttribute('onclick') ||\n el.getAttribute('role') === 'button' ||\n el.classList.contains('btn'),\n hasChildren: el.children.length > 0,\n childCount: el.children.length,\n // Add stable structural information\n parentTagName: el.parentElement?.tagName.toLowerCase() || '',\n index: Array.from(el.parentElement?.children || []).indexOf(el)\n };\n return obj;\n }).filter(obj => {\n const key = obj.tagName + '|' + obj.selector + '|' + obj.textContent.substring(0, 20);\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n\n this.log('DOM structure analyzed', { elementCount: structure.length, elements: structure });\n return { elements: structure };\n }\n\n private async fetchGeneratedConfig(structure: any, domHash?: string): Promise<any> {\n try {\n if(structure && structure.elements && structure.elements.length === 0) {\n this.log('No elements found in DOM structure, skipping config fetch.');\n return null;\n }\n \n const requestBody: any = { structure };\n if (domHash) {\n requestBody.domHash = domHash;\n requestBody.lastConfigHash = this.lastConfigHash;\n }\n \n const response = await fetch(API_ENDPOINTS.CONFIG, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(requestBody),\n });\n\n if (!response.ok) {\n throw new Error(`Backend returned ${response.status}`);\n }\n return await response.json();\n } catch (error) {\n this.log('Error fetching generated config:', error);\n return null;\n }\n }\n\n private applyGeneratedConfig(config: { events_to_track: any[], observe_mutations?: boolean }) {\n config.events_to_track.forEach(eventToTrack => {\n try {\n const elements = document.querySelectorAll(eventToTrack.element_selector);\n if (elements.length > 0) {\n elements.forEach(element => {\n // Prevent multiple listeners for the same event type on the same element\n let eventSet = this.attachedListeners.get(element);\n if (!eventSet) {\n eventSet = new Set();\n this.attachedListeners.set(element, eventSet);\n }\n \n // Handle array of event types\n const eventTypes = Array.isArray(eventToTrack.event_type) ? eventToTrack.event_type : [eventToTrack.event_type];\n \n eventTypes.forEach((eventType: string) => {\n if (eventSet.has(eventType)) return;\n eventSet.add(eventType);\n \n // Click events\n if (eventType === 'click') {\n element.addEventListener('click', (event: Event) => {\n // Don't prevent default for this demo, let buttons work normally\n const target = event.target as HTMLElement;\n const elementData = this.extractElementData(target);\n \n this.sendToWorker(eventToTrack.event_name, {\n selector: eventToTrack.element_selector,\n eventType: 'click',\n element: elementData,\n timestamp: new Date().toISOString()\n });\n });\n this.log(`Attached click listener for \"${eventToTrack.event_name}\" on \"${eventToTrack.element_selector}\"`);\n }\n \n // View events using IntersectionObserver\n if (eventType === 'view') {\n if ('IntersectionObserver' in window) {\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n const target = entry.target as HTMLElement;\n const elementData = this.extractElementData(target);\n \n this.sendToWorker(eventToTrack.event_name, {\n selector: eventToTrack.element_selector,\n eventType: 'view',\n element: elementData,\n intersectionRatio: entry.intersectionRatio,\n timestamp: new Date().toISOString()\n });\n }\n });\n }, { threshold: [0.1, 0.5, 1.0] });\n observer.observe(element);\n this.log(`Attached IntersectionObserver for \"${eventToTrack.event_name}\" on \"${eventToTrack.element_selector}\"`);\n }\n }\n \n // Focus/blur tracking\n if (eventType === 'focus' || eventType === 'blur') {\n element.addEventListener(eventType, () => {\n const target = element as HTMLElement;\n const elementData = this.extractElementData(target);\n \n this.sendToWorker(eventToTrack.event_name, {\n selector: eventToTrack.element_selector,\n eventType: eventType,\n element: elementData,\n timestamp: new Date().toISOString()\n });\n });\n this.log(`Attached ${eventType} listener for \"${eventToTrack.event_name}\" on \"${eventToTrack.element_selector}\"`);\n }\n });\n });\n } else {\n this.log(`No elements found for selector: \"${eventToTrack.element_selector}\"`);\n }\n } catch (e) {\n this.log(`Error applying selector \"${eventToTrack.element_selector}\":`, e);\n }\n });\n\n // MutationObserver for DOM changes (if requested by config)\n if (config.observe_mutations) {\n if ('MutationObserver' in window) {\n const observer = new MutationObserver((mutations) => {\n mutations.forEach(mutation => {\n this.sendToWorker('dom_mutation', {\n type: mutation.type,\n target: (mutation.target as HTMLElement).outerHTML,\n timestamp: new Date().toISOString()\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n this.log('MutationObserver attached for DOM changes');\n }\n }\n }\n\n private extractElementData(element: HTMLElement): any {\n const rect = element.getBoundingClientRect();\n return {\n tagName: element.tagName.toLowerCase(),\n id: element.id || '',\n className: element.className || '',\n textContent: (element.textContent || '').trim().substring(0, 100),\n attributes: Array.from(element.attributes).reduce((acc, attr) => {\n acc[attr.name] = attr.value;\n return acc;\n }, {} as Record<string, string>),\n position: {\n x: Math.round(rect.x),\n y: Math.round(rect.y),\n width: Math.round(rect.width),\n height: Math.round(rect.height)\n },\n href: (element as HTMLAnchorElement).href || undefined,\n value: (element as HTMLInputElement).value || undefined\n };\n }\n\n // Helper to send events to worker for batching\n private sendToWorker(eventName: string, properties: Record<string, any>) {\n const eventData: any = {\n event: eventName,\n properties,\n timestamp: Date.now(),\n userId: this.getUserId(),\n sessionId: this.sessionId,\n client_id: this.config.clientId || 'demo-client-001' // Ensure client_id is always present\n };\n if (this.config.useWebWorker && typeof Worker !== 'undefined') {\n this.worker.postMessage({ type: 'track', payload: eventData });\n } else {\n this.eventQueue.push(eventData);\n }\n this.log('Event tracked:', eventData);\n }\n\n private setupWebWorker() {\n // Pass worker config to the worker\n this.worker.postMessage({\n type: 'config',\n payload: {\n apiUrl: this.config.apiDetails?.apiEndPoint || `${this.config.endpoint}/api/v1/events`,\n batchSize: this.config.workerConfig?.batchSize || 10,\n batchInterval: this.config.workerConfig?.batchInterval || 5000,\n headers: this.config.apiDetails?.headers || { 'Content-Type': 'application/json' },\n }\n });\n this.worker.onmessage = (event) => {\n if (event.data.status === 'success') {\n this.log('Batch sent successfully by worker');\n // Don't re-queue failed events since we already cleared the queue\n } else if (event.data.status === 'debug') {\n this.log(event.data.message, event.data);\n } else if (event.data.status === 'error') {\n this.log('Worker failed to send batch', event.data.error);\n // Re-queue failed events only if we have them\n if (event.data.failedEvents && event.data.failedEvents.length > 0) {\n this.eventQueue.unshift(...event.data.failedEvents);\n }\n }\n };\n this.log('Web worker setup complete.');\n }\n\n public track(eventName: string, properties: Record<string, any> = {}) {\n const eventData: any = {\n event: eventName,\n properties,\n timestamp: Date.now(),\n userId: this.getUserId(),\n sessionId: this.sessionId,\n client_id: this.config.clientId || 'demo-client-001' // Ensure client_id is always present\n };\n\n // Use the same batching logic as sendToWorker\n if (this.config.useWebWorker && typeof Worker !== 'undefined') {\n this.worker.postMessage({ type: 'track', payload: eventData });\n } else {\n this.eventQueue.push(eventData);\n }\n this.log('Event tracked public:', eventData);\n }\n\n private startBatchTimer() {\n this.batchTimer = window.setInterval(() => {\n this.flushQueue();\n }, this.config.batchInterval);\n }\n\n private async flushQueue() {\n if (this.eventQueue.length === 0) {\n return;\n }\n\n const batch = [...this.eventQueue];\n // Clear the queue immediately to prevent duplicates\n this.eventQueue = [];\n\n if (this.config.useWebWorker && typeof Worker !== 'undefined') {\n this.worker.postMessage({\n type: 'batch',\n events: batch,\n endpoint: `${this.config.endpoint}/api/v1/events`,\n });\n } else {\n // Fallback send mechanism with retry logic\n await this.sendBatchWithRetry(batch);\n }\n }\n\n private async sendBatchWithRetry(batch: Map<string, any>[]) {\n if (this.batchRetryCount >= this.maxBatchRetries) {\n if (this.batchTimer) {\n clearInterval(this.batchTimer);\n this.batchTimer = undefined;\n this.log('Max batch retries reached. BatchTimer cancelled.');\n }\n return;\n }\n try {\n await this.sendBatch(batch);\n // On success, reset retry count (queue already cleared in flushQueue)\n this.batchRetryCount = 0;\n } catch (error) {\n this.batchRetryCount++;\n this.log(`Batch send failed. Retry attempt ${this.batchRetryCount} of ${this.maxBatchRetries}.`, error);\n // Re-queue the failed batch for retry\n this.eventQueue.unshift(...batch);\n if (this.batchRetryCount >= this.maxBatchRetries) {\n if (this.batchTimer) {\n clearInterval(this.batchTimer);\n this.batchTimer = undefined;\n this.log('Max batch retries reached. BatchTimer cancelled.');\n }\n }\n }\n }\n\n // Update sendBatch to support client db endpoint and headers\n private async sendBatch(batch: Map<string, any>[]) {\n let endpoint = `${this.config.endpoint}/api/v1/events`;\n let headers: Record<string, string> = { 'Content-Type': 'application/json' };\n if (this.config.apiDetails && this.config.apiDetails.apiEndPoint) {\n endpoint = this.config.apiDetails.apiEndPoint;\n if (this.config.apiDetails.headers) {\n headers = { ...headers, ...this.config.apiDetails.headers };\n }\n }\n // Transform batch to required format\n const clientId = this.config.clientId || 'f01a232e-eacc-4c2e-8a06-f1c522cb8201';\n const events = batch.map((e: any) => ({\n event: e.event, // keep 'event' key\n userId: e.userId,\n client_id: clientId,\n timestamp: new Date(e.timestamp).toISOString(),\n ...(e.properties || {})\n }));\n try {\n const response = await fetch(endpoint, {\n method: 'POST',\n headers,\n body: JSON.stringify({ events }),\n });\n if (!response.ok) {\n throw new Error(`Failed to send batch: ${response.status}`);\n }\n this.log('Batch sent successfully:', events);\n } catch (error) {\n this.log('Error sending batch:', error);\n throw error; // Let sendBatchWithRetry handle re-queuing\n }\n }\n\n private generateSessionId(): string {\n // Simple session ID generator (could be improved)\n return 'sess_' + Math.random().toString(36).substr(2, 9);\n }\n\n private getUserId(): string {\n // Placeholder for user ID logic (e.g., from cookies, localStorage, or auth context)\n return 'user_' + Math.random().toString(36).substr(2, 9);\n }\n\n private log(message: string, data?: any) {\n if (this.config.debug) {\n console.log(`[AnalyticsPro SDK] ${message}`, data || '');\n }\n }\n\n // Save config as a downloadable JSON file\nprivate saveConfigToFile(config: any) {\n if(!this.config.debug){\n return;\n }\n // const fileName = 'AInamika_config.json';\n // const json = JSON.stringify(config, null, 2);\n // const blob = new Blob([json], { type: 'application/json' });\n // const link = document.createElement('a');\n // link.href = URL.createObjectURL(blob);\n // link.download = fileName;\n // document.body.appendChild(link);\n // link.click();\n // document.body.removeChild(link);\n}\n\n// Load config from /AInamika_config.json in the project root\nprivate async loadConfigFromFile(): Promise<any | null> {\n try {\n const response = await fetch('/AInamika_config.json', { cache: 'reload' });\n if (!response.ok) {\n return null;\n }\n const config = await response.json();\n return config;\n } catch (err) {\n return null;\n }\n}\n\n// --- Dynamic DOM Fingerprinting and Smart Debouncing ---\nprivate async setupDynamicDomTracking() {\n // Use MutationObserver to watch for DOM changes\n if ('MutationObserver' in window) {\n const observer = new MutationObserver(() => {\n if (this.mutationDebounceTimer) {\n clearTimeout(this.mutationDebounceTimer);\n }\n this.mutationDebounceTimer = window.setTimeout(() => {\n this.handleDomMutation();\n }, this.mutationDebounceMs);\n });\n observer.observe(document.body, { childList: true, subtree: true, attributes: true });\n this.log('Dynamic DOM MutationObserver attached');\n }\n}\n\nprivate computeDomHash(structure: any): string {\n // Simple hash: JSON.stringify, then a basic hash (FNV-1a or similar)\n const str = JSON.stringify(structure);\n let hash = 2166136261;\n for (let i = 0; i < str.length; i++) {\n hash ^= str.charCodeAt(i);\n hash += (hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) + (hash << 24);\n }\n return (hash >>> 0).toString(16);\n}\n\nprivate getCachedConfigForDomHash(domHash: string): any | null {\n try {\n const cache = JSON.parse(localStorage.getItem('ainamika_dom_config_cache') || '{}');\n return cache[domHash] || null;\n } catch {\n return null;\n }\n}\n\nprivate setCachedConfigForDomHash(domHash: string, config: any) {\n try {\n const cache = JSON.parse(localStorage.getItem('ainamika_dom_config_cache') || '{}');\n cache[domHash] = config;\n localStorage.setItem('ainamika_dom_config_cache', JSON.stringify(cache));\n } catch {}\n}\n\nprivate async handleDomMutation() {\n const domStructure = await this.getDOMStructure();\n const domHash = this.computeDomHash(domStructure);\n \n if (domHash === this.lastDomHash) {\n this.log('DOM hash unchanged after mutation, skipping config fetch.');\n return;\n }\n \n this.log('DOM hash changed, checking for cached config...', { oldHash: this.lastDomHash, newHash: domHash });\n this.lastDomHash = domHash;\n \n const cachedConfig = this.getCachedConfigForDomHash(domHash);\n if (cachedConfig) {\n this.log('Reusing cached config for DOM hash', domHash);\n this.applyGeneratedConfig(cachedConfig);\n return;\n }\n \n // Send to server: domStructure with domHash and lastConfigHash\n this.log('Fetching new config from backend for DOM hash:', domHash);\n const config = await this.fetchGeneratedConfig(domStructure, domHash);\n if (config && config.events_to_track) {\n this.applyGeneratedConfig(config);\n this.setCachedConfigForDomHash(domHash, config);\n this.lastConfigHash = config.config_hash || '';\n this.log('Fetched and applied new config for new DOM hash', domHash);\n } else {\n this.log('No valid config returned for new DOM hash', domHash);\n }\n}\n}\n\n// Make AnalyticsProSDK available globally for both classic and module scripts\nif (typeof window !== 'undefined') {\n (window as any).AInamikaSDKPro = AInamikaSDKPro;\n}\n\nexport default AInamikaSDKPro;\nexport { AInamikaSDKPro };"],"names":["root","factory","exports","module","define","amd","self","window","global","this","__webpack_require__","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","config","breadcrumbs","errorCount","errorDebounceMap","Map","captureScreenshots","captureDomSnapshots","maxStackTraceDepth","maxErrorsPerSession","debounceMs","enableNetworkTracking","enableConsoleCapture","sessionId","generateSessionId","originalConsole","console","initialize","addEventListener","event","handleError","type","message","filename","line","lineno","column","colno","error","reason","promise","setupNetworkTracking","setupConsoleCapture","setupNavigationTracking","setupClickTracking","log","Date","now","Math","random","toString","substr","addBreadcrumb","breadcrumb","push","timestamp","length","slice","errorInfo","warn","errorKey","has","set","captureError","errorData","client_id","clientId","error_type","stack_trace","extractStackTrace","url","location","href","user_agent","navigator","userAgent","error_metadata","userId","networkInfo","getNetworkInfo","performance","getPerformanceInfo","severity","assessSeverity","session_id","user_id","dom_snapshot","captureDomSnapshot","captureScreenshot","screen_snapshot","sendError","data","stack","split","maxDepth","join","toLowerCase","includes","snapshot","title","document","viewport","width","innerWidth","height","innerHeight","elements","extractDomElements","JSON","stringify","forEach","selector","els","querySelectorAll","Array","from","el","tagName","id","className","textContent","substring","attributes","getElementAttributes","e","element","attrs","attr","value","getAttribute","html2canvas","body","min","useCORS","toDataURL","connection","mozConnection","webkitConnection","effectiveType","downlink","rtt","saveData","info","memory","usedJSHeapSize","totalJSHeapSize","jsHeapSizeLimit","timing","domContentLoaded","domContentLoadedEventEnd","navigationStart","load","loadEventEnd","getEntriesByType","entry","name","firstPaint","startTime","firstContentfulPaint","originalFetch","fetch","args","Request","String","response","status","duration","ok","statusText","originalXHROpen","XMLHttpRequest","open","originalXHRSend","send","method","async","username","password","_errorTracker","tracker","dispatchEvent","CustomEvent","detail","original","map","arg","consoleMethod","level","currentUrl","trackNavigation","newUrl","to","originalPushState","history","pushState","originalReplaceState","replaceState","apply","setTimeout","target","getElementSelector","text","trim","classes","filter","c","endpoint","headers","apiKey","Error","storeErrorLocally","stored","localStorage","getItem","errors","parse","splice","setItem","captureException","context","setUser","addTag","flushStoredErrors","removeItem","ENV_CONFIG","__AINAMIKA_CONFIG__","isLocal","hostname","API_BASE_URL","APP_ENV","DEBUG","getEnvironmentConfig","API_ENDPOINTS","EVENTS","ERRORS","CONFIG","DEBUG_EVENTS","ENDPOINTS","STORAGE_KEY","METADATA_KEY","isProcessing","maxStorageSize","maxRetries","retryInterval","compressionEnabled","encryptionEnabled","cleanupOldErrors","startRetryTimer","setupStorageListener","processQueue","storeError","errorId","generateErrorId","storedError","compressData","retryCount","addToQueue","updateMetadata","getStoredErrors","decompressData","removeError","getQueueRaw","filteredErrors","clearAll","getStorageStats","totalSize","Blob","size","timestamps","sort","oldestError","newestError","lastRetry","incrementRetryCount","retryError","find","serialized","shift","errorIndex","findIndex","jsonString","btoa","compressedData","atob","cleanErrors","retryTimer","setInterval","stats","metadata","lastUpdate","exportErrors","exportData","version","importErrors","isArray","destroy","clearInterval","undefined","getAinamikaStorageUsage","errorSize","otherSize","startsWith","checkStorageSpace","requiredBytes","testKey","testData","repeat","cleanupAllAinamikaStorage","keysToRemove","generateStorageReport","storage","ErrorStorage","usage","ErrorStorageUtils","eventQueue","isInitialized","batchRetryCount","maxBatchRetries","domHashCache","lastDomHash","lastConfigHash","mutationDebounceTimer","mutationDebounceMs","attachedListeners","WeakMap","batchInterval","useWebWorker","debug","errorTracking","enabled","blob","workerUrl","URL","createObjectURL","worker","Worker","initializeErrorTracking","autoConfig","setupAutoConfiguration","setupDynamicDomTracking","setupWebWorker","startBatchTimer","errorStorage","errorConfig","errorTracker","ErrorTracker","getUserId","getDOMStructure","domStructure","domHash","computeDomHash","generatedConfig","getCachedConfigForDomHash","loadConfigFromFile","fetchGeneratedConfig","events_to_track","saveConfigToFile","setCachedConfigForDomHash","config_hash","applyGeneratedConfig","postMessage","getSelector","Promise","resolve","filteredElements","style","getComputedStyle","isVisible","display","visibility","opacity","hasInteraction","hasAttribute","classList","contains","isImportantElement","indexOf","seen","Set","structure","stableAttributes","isInteractive","hasChildren","children","childCount","parentTagName","parentElement","index","add","elementCount","requestBody","json","eventToTrack","element_selector","eventSet","event_type","eventType","elementData","extractElementData","sendToWorker","event_name","toISOString","IntersectionObserver","entries","isIntersecting","intersectionRatio","threshold","observe","observe_mutations","MutationObserver","mutations","mutation","outerHTML","childList","subtree","rect","getBoundingClientRect","reduce","acc","position","x","round","y","eventName","properties","eventData","payload","apiUrl","apiDetails","apiEndPoint","batchSize","workerConfig","onmessage","failedEvents","unshift","track","batchTimer","flushQueue","batch","events","sendBatchWithRetry","sendBatch","cache","clearTimeout","handleDomMutation","str","hash","i","charCodeAt","oldHash","newHash","cachedConfig","AInamikaSDKPro"],"sourceRoot":""}
@@ -0,0 +1,18 @@
1
+ export interface EnvironmentConfig {
2
+ API_BASE_URL: string;
3
+ APP_ENV: 'development' | 'production';
4
+ DEBUG: boolean;
5
+ }
6
+ declare global {
7
+ interface Window {
8
+ __AINAMIKA_CONFIG__?: EnvironmentConfig;
9
+ }
10
+ }
11
+ export declare const ENV_CONFIG: EnvironmentConfig;
12
+ export declare const API_ENDPOINTS: {
13
+ EVENTS: string;
14
+ ERRORS: string;
15
+ CONFIG: string;
16
+ DEBUG_EVENTS: string;
17
+ };
18
+ export declare function configureSDK(config: Partial<EnvironmentConfig>): void;
@@ -0,0 +1,108 @@
1
+ export interface StoredError {
2
+ id: string;
3
+ errorData: any;
4
+ timestamp: number;
5
+ retryCount: number;
6
+ lastRetry?: number;
7
+ }
8
+ export interface StorageConfig {
9
+ maxStorageSize: number;
10
+ maxRetries: number;
11
+ retryInterval: number;
12
+ compressionEnabled: boolean;
13
+ encryptionEnabled: boolean;
14
+ }
15
+ export declare class ErrorStorage {
16
+ private config;
17
+ private readonly STORAGE_KEY;
18
+ private readonly METADATA_KEY;
19
+ private retryTimer?;
20
+ private isProcessing;
21
+ constructor(config?: Partial<StorageConfig>);
22
+ private initialize;
23
+ /**
24
+ * Store error data with automatic compression and queue management
25
+ */
26
+ storeError(errorData: any): Promise<string>;
27
+ /**
28
+ * Get all stored errors
29
+ */
30
+ getStoredErrors(): StoredError[];
31
+ /**
32
+ * Remove error from storage
33
+ */
34
+ removeError(errorId: string): boolean;
35
+ /**
36
+ * Clear all stored errors
37
+ */
38
+ clearAll(): void;
39
+ /**
40
+ * Get storage statistics
41
+ */
42
+ getStorageStats(): {
43
+ errorCount: number;
44
+ totalSize: number;
45
+ oldestError?: number;
46
+ newestError?: number;
47
+ };
48
+ /**
49
+ * Process the error queue - attempt to send stored errors
50
+ */
51
+ processQueue(): Promise<void>;
52
+ /**
53
+ * Force retry of a specific error
54
+ */
55
+ retryError(errorId: string): Promise<boolean>;
56
+ private addToQueue;
57
+ private getQueueRaw;
58
+ private incrementRetryCount;
59
+ private sendError;
60
+ private compressData;
61
+ private decompressData;
62
+ private generateErrorId;
63
+ private cleanupOldErrors;
64
+ private startRetryTimer;
65
+ private setupStorageListener;
66
+ private updateMetadata;
67
+ /**
68
+ * Export stored errors for debugging
69
+ */
70
+ exportErrors(): string;
71
+ /**
72
+ * Import errors from export
73
+ */
74
+ importErrors(exportData: string): boolean;
75
+ /**
76
+ * Cleanup and destroy the storage instance
77
+ */
78
+ destroy(): void;
79
+ }
80
+ /**
81
+ * Utility functions for error storage management
82
+ */
83
+ export declare class ErrorStorageUtils {
84
+ /**
85
+ * Get total localStorage usage for AInamika
86
+ */
87
+ static getAinamikaStorageUsage(): {
88
+ totalSize: number;
89
+ errorSize: number;
90
+ otherSize: number;
91
+ };
92
+ /**
93
+ * Check if localStorage has enough space
94
+ */
95
+ static checkStorageSpace(requiredBytes: number): boolean;
96
+ /**
97
+ * Clean up all AInamika storage
98
+ */
99
+ static cleanupAllAinamikaStorage(): void;
100
+ /**
101
+ * Generate storage report
102
+ */
103
+ static generateStorageReport(): {
104
+ usage: ReturnType<typeof ErrorStorageUtils.getAinamikaStorageUsage>;
105
+ errors: any[];
106
+ metadata: any;
107
+ };
108
+ }
@@ -0,0 +1,98 @@
1
+ export interface ErrorConfig {
2
+ endpoint: string;
3
+ clientId: string;
4
+ apiKey: string;
5
+ captureScreenshots?: boolean;
6
+ captureDomSnapshots?: boolean;
7
+ maxStackTraceDepth?: number;
8
+ maxErrorsPerSession?: number;
9
+ debounceMs?: number;
10
+ enableNetworkTracking?: boolean;
11
+ enableConsoleCapture?: boolean;
12
+ }
13
+ export interface ErrorData {
14
+ id?: string;
15
+ client_id: string;
16
+ error_type: 'javascript' | 'network' | 'unhandled' | 'console' | 'custom';
17
+ message: string;
18
+ stack_trace?: string;
19
+ url: string;
20
+ user_agent: string;
21
+ timestamp: number;
22
+ error_metadata: {
23
+ line?: number;
24
+ column?: number;
25
+ filename?: string;
26
+ component?: string;
27
+ props?: Record<string, any>;
28
+ userId?: string;
29
+ sessionId?: string;
30
+ breadcrumbs?: ErrorBreadcrumb[];
31
+ networkInfo?: NetworkInfo;
32
+ performance?: PerformanceInfo;
33
+ };
34
+ dom_snapshot?: string;
35
+ screen_snapshot?: string;
36
+ severity: 'low' | 'medium' | 'high' | 'critical';
37
+ session_id: string;
38
+ user_id?: string;
39
+ }
40
+ export interface ErrorBreadcrumb {
41
+ timestamp: number;
42
+ type: 'navigation' | 'click' | 'console' | 'network' | 'error';
43
+ message: string;
44
+ data?: Record<string, any>;
45
+ }
46
+ export interface NetworkInfo {
47
+ effectiveType?: string;
48
+ downlink?: number;
49
+ rtt?: number;
50
+ saveData?: boolean;
51
+ }
52
+ export interface PerformanceInfo {
53
+ memory?: {
54
+ usedJSHeapSize: number;
55
+ totalJSHeapSize: number;
56
+ jsHeapSizeLimit: number;
57
+ };
58
+ timing?: {
59
+ domContentLoaded: number;
60
+ load: number;
61
+ firstPaint?: number;
62
+ firstContentfulPaint?: number;
63
+ };
64
+ }
65
+ export declare class ErrorTracker {
66
+ private config;
67
+ private breadcrumbs;
68
+ private errorCount;
69
+ private errorDebounceMap;
70
+ private originalConsole;
71
+ private sessionId;
72
+ private userId?;
73
+ constructor(config: ErrorConfig);
74
+ private initialize;
75
+ private generateSessionId;
76
+ private addBreadcrumb;
77
+ private handleError;
78
+ private captureError;
79
+ private extractStackTrace;
80
+ private assessSeverity;
81
+ private captureDomSnapshot;
82
+ private extractDomElements;
83
+ private getElementAttributes;
84
+ private captureScreenshot;
85
+ private getNetworkInfo;
86
+ private getPerformanceInfo;
87
+ private setupNetworkTracking;
88
+ private setupConsoleCapture;
89
+ private setupNavigationTracking;
90
+ private setupClickTracking;
91
+ private getElementSelector;
92
+ private sendError;
93
+ private storeErrorLocally;
94
+ captureException(error: Error, context?: Record<string, any>): void;
95
+ setUser(userId: string): void;
96
+ addTag(key: string, value: string): void;
97
+ flushStoredErrors(): Promise<void>;
98
+ }
package/dist/sdk.d.ts ADDED
@@ -0,0 +1,77 @@
1
+ interface AnalyticsConfig {
2
+ apiKey: string;
3
+ endpoint?: string;
4
+ autoConfig?: boolean;
5
+ batchInterval?: number;
6
+ useWebWorker?: boolean;
7
+ workerPath?: string;
8
+ debug?: boolean;
9
+ clientId: string;
10
+ apiDetails?: {
11
+ apiEndPoint: string;
12
+ headers?: Record<string, string>;
13
+ };
14
+ workerConfig?: {
15
+ batchSize?: number;
16
+ batchInterval?: number;
17
+ };
18
+ errorTracking?: {
19
+ enabled?: boolean;
20
+ captureScreenshots?: boolean;
21
+ captureDomSnapshots?: boolean;
22
+ maxStackTraceDepth?: number;
23
+ maxErrorsPerSession?: number;
24
+ debounceMs?: number;
25
+ enableNetworkTracking?: boolean;
26
+ enableConsoleCapture?: boolean;
27
+ };
28
+ }
29
+ declare class AInamikaSDKPro {
30
+ private config;
31
+ private worker;
32
+ private sessionId;
33
+ private autoConfig?;
34
+ private batchTimer?;
35
+ private eventQueue;
36
+ private isInitialized;
37
+ private batchRetryCount;
38
+ private maxBatchRetries;
39
+ private errorTracker?;
40
+ private errorStorage?;
41
+ private domHashCache;
42
+ private lastDomHash;
43
+ private lastConfigHash;
44
+ private mutationDebounceTimer;
45
+ private mutationDebounceMs;
46
+ private attachedListeners;
47
+ constructor(config: AnalyticsConfig);
48
+ private initialize;
49
+ private initializeErrorTracking;
50
+ captureException(error: Error, context?: Record<string, any>): void;
51
+ setUser(userId: string): void;
52
+ flushStoredErrors(): Promise<void>;
53
+ private setupAutoConfiguration;
54
+ private getDOMStructure;
55
+ private fetchGeneratedConfig;
56
+ private applyGeneratedConfig;
57
+ private extractElementData;
58
+ private sendToWorker;
59
+ private setupWebWorker;
60
+ track(eventName: string, properties?: Record<string, any>): void;
61
+ private startBatchTimer;
62
+ private flushQueue;
63
+ private sendBatchWithRetry;
64
+ private sendBatch;
65
+ private generateSessionId;
66
+ private getUserId;
67
+ private log;
68
+ private saveConfigToFile;
69
+ private loadConfigFromFile;
70
+ private setupDynamicDomTracking;
71
+ private computeDomHash;
72
+ private getCachedConfigForDomHash;
73
+ private setCachedConfigForDomHash;
74
+ private handleDomMutation;
75
+ }
76
+ export default AInamikaSDKPro;
77
+ export { AInamikaSDKPro };
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "ainamika-sdk",
3
+ "version": "1.0.3",
4
+ "description": "Advanced AI-powered analytics SDK with error tracking, event management, and real-time insights for web applications",
5
+ "main": "dist/ainamika-sdk.js",
6
+ "types": "dist/sdk.d.ts",
7
+ "files": [
8
+ "dist/",
9
+ "README.md",
10
+ "LICENSE"
11
+ ],
12
+ "scripts": {
13
+ "build": "rm -rf dist && webpack --config webpack.config.js",
14
+ "prepublishOnly": "npm run build",
15
+ "test": "echo \"Tests will be added in future versions\" && exit 0"
16
+ },
17
+ "keywords": [
18
+ "analytics",
19
+ "error-tracking",
20
+ "event-tracking",
21
+ "ai-analytics",
22
+ "web-analytics",
23
+ "javascript-sdk",
24
+ "typescript",
25
+ "real-time-analytics",
26
+ "user-behavior",
27
+ "performance-monitoring"
28
+ ],
29
+ "author": {
30
+ "name": "Adarsh Singh",
31
+ "email": "contact@ainamika.com"
32
+ },
33
+ "license": "MIT",
34
+ "repository": {
35
+ "type": "git",
36
+ "url": "https://github.com/adarshsingh/ainamika-sdk.git"
37
+ },
38
+ "homepage": "https://ainamika.com",
39
+ "bugs": {
40
+ "url": "https://github.com/adarshsingh/ainamika-sdk/issues"
41
+ },
42
+ "engines": {
43
+ "node": ">=16.0.0"
44
+ },
45
+ "devDependencies": {
46
+ "ts-loader": "^9.5.2",
47
+ "typescript": "^5.8.3",
48
+ "webpack": "^5.100.2",
49
+ "webpack-cli": "^6.0.1",
50
+ "worker-loader": "^3.0.8"
51
+ },
52
+ "peerDependencies": {},
53
+ "browserslist": [
54
+ "> 1%",
55
+ "last 2 versions",
56
+ "not dead"
57
+ ]
58
+ }