@syntropysoft/syntropyfront 0.4.4 → 0.4.5

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/dist/index.min.js CHANGED
@@ -1,2 +1,2 @@
1
- var SyntropyFront=function(){"use strict";const e=new class{constructor(e=25){this.maxBreadcrumbs=e,this.breadcrumbs=[],this.agent=null}setAgent(e){this.agent=e}setMaxBreadcrumbs(e){this.maxBreadcrumbs=e,this.breadcrumbs.length>this.maxBreadcrumbs&&(this.breadcrumbs=this.breadcrumbs.slice(-this.maxBreadcrumbs))}getMaxBreadcrumbs(){return this.maxBreadcrumbs}add(e){const t={...e,timestamp:(new Date).toISOString()};if(this.breadcrumbs.length>=this.maxBreadcrumbs&&this.breadcrumbs.shift(),this.breadcrumbs.push(t),this.onBreadcrumbAdded&&this.onBreadcrumbAdded(t),this.agent&&this.agent.isEnabled)try{this.agent.sendBreadcrumbs([t])}catch(e){console.warn("SyntropyFront: Error enviando breadcrumb al agent:",e)}}getAll(){return[...this.breadcrumbs]}clear(){this.breadcrumbs=[]}getByCategory(e){return this.breadcrumbs.filter(t=>t.category===e)}};class t{constructor(){this.endpoint=null,this.headers={"Content-Type":"application/json"},this.batchSize=10,this.batchTimeout=null,this.isEnabled=!1,this.sendBreadcrumbs=!1,this.encrypt=null,this.usePersistentBuffer=!1,this.maxRetries=5,this.baseDelay=1e3,this.maxDelay=3e4}configure(e){this.endpoint=e.endpoint,this.headers={...this.headers,...e.headers},this.batchSize=e.batchSize||this.batchSize,this.batchTimeout=e.batchTimeout,this.isEnabled=!!e.endpoint,this.encrypt=e.encrypt||null,this.usePersistentBuffer=!0===e.usePersistentBuffer,this.maxRetries=e.maxRetries||this.maxRetries,this.sendBreadcrumbs=!!e.batchTimeout}isAgentEnabled(){return this.isEnabled}shouldSendBreadcrumbs(){return this.sendBreadcrumbs}getConfig(){return{endpoint:this.endpoint,headers:this.headers,batchSize:this.batchSize,batchTimeout:this.batchTimeout,isEnabled:this.isEnabled,sendBreadcrumbs:this.sendBreadcrumbs,encrypt:this.encrypt,usePersistentBuffer:this.usePersistentBuffer,maxRetries:this.maxRetries,baseDelay:this.baseDelay,maxDelay:this.maxDelay}}}class r{constructor(e){this.config=e,this.queue=[],this.batchTimer=null,this.flushCallback=null}add(e){this.queue.push(e),this.queue.length>=this.config.batchSize?this.flush(this.flushCallback):this.config.batchSize&&this.config.batchTimeout&&!this.batchTimer&&(this.batchTimer=setTimeout(()=>{this.flush(this.flushCallback)},this.config.batchTimeout))}getAll(){return[...this.queue]}clear(){this.queue=[],this.clearTimer()}clearTimer(){this.batchTimer&&(clearTimeout(this.batchTimer),this.batchTimer=null)}getSize(){return this.queue.length}isEmpty(){return 0===this.queue.length}async flush(e){if(0===this.queue.length)return;const t=[...this.queue];this.queue=[],this.clearTimer(),e&&await e(t)}}class n{constructor(e){this.config=e,this.retryQueue=[],this.retryTimer=null}addToRetryQueue(e,t=1,r=null){const n=Math.min(this.config.baseDelay*Math.pow(2,t-1),this.config.maxDelay);this.retryQueue.push({items:e,retryCount:t,persistentId:r,nextRetry:Date.now()+n}),this.scheduleRetry()}scheduleRetry(){if(this.retryTimer)return;const e=this.retryQueue.find(e=>e.nextRetry<=Date.now());e&&(this.retryTimer=setTimeout(()=>{this.processRetryQueue()},Math.max(0,e.nextRetry-Date.now())))}async processRetryQueue(e,t){this.retryTimer=null;const r=Date.now(),n=this.retryQueue.filter(e=>e.nextRetry<=r);for(const r of n)try{e&&await e(r.items),this.retryQueue=this.retryQueue.filter(e=>e!==r),r.persistentId&&t&&await t(r.persistentId),console.log(`SyntropyFront: Reintento exitoso después de ${r.retryCount} intentos`)}catch(e){console.warn(`SyntropyFront: Reintento ${r.retryCount} falló:`,e),r.retryCount>=this.config.maxRetries?(this.retryQueue=this.retryQueue.filter(e=>e!==r),console.error("SyntropyFront: Item excedió máximo de reintentos, datos perdidos")):(r.retryCount++,r.nextRetry=Date.now()+Math.min(this.config.baseDelay*Math.pow(2,r.retryCount-1),this.config.maxDelay))}this.retryQueue.length>0&&this.scheduleRetry()}clear(){this.retryQueue=[],this.clearTimer()}clearTimer(){this.retryTimer&&(clearTimeout(this.retryTimer),this.retryTimer=null)}getSize(){return this.retryQueue.length}isEmpty(){return 0===this.retryQueue.length}}const i=new class{constructor(){this.seen=new WeakSet,this.circularRefs=new Map,this.refCounter=0}serialize(e){try{this.seen=new WeakSet,this.circularRefs=new Map,this.refCounter=0;const t=this.makeSerializable(e);return JSON.stringify(t)}catch(t){return console.error("SyntropyFront: Error en serialización robusta:",t),JSON.stringify({__serializationError:!0,error:t.message,originalType:typeof e,isObject:null!==e&&"object"==typeof e,timestamp:(new Date).toISOString()})}}makeSerializable(e,t=""){if(null==e)return e;if("string"==typeof e||"number"==typeof e||"boolean"==typeof e)return e;if(e instanceof Date)return{__type:"Date",value:e.toISOString()};if(e instanceof Error)return{__type:"Error",name:e.name,message:e.message,stack:e.stack,cause:e.cause?this.makeSerializable(e.cause,`${t}.cause`):void 0};if(e instanceof RegExp)return{__type:"RegExp",source:e.source,flags:e.flags};if(Array.isArray(e)){if(this.seen.has(e)){return{__circular:!0,refId:this.circularRefs.get(e)}}this.seen.add(e);const r="ref_"+ ++this.refCounter;return this.circularRefs.set(e,r),e.map((e,r)=>this.makeSerializable(e,`${t}[${r}]`))}if("object"==typeof e){if(this.seen.has(e)){return{__circular:!0,refId:this.circularRefs.get(e)}}this.seen.add(e);const r="ref_"+ ++this.refCounter;this.circularRefs.set(e,r);const n={};for(const r in e)if(Object.prototype.hasOwnProperty.call(e,r))try{const i=e[r],s=this.makeSerializable(i,`${t}.${r}`);n[r]=s}catch(e){n[r]={__serializationError:!0,error:e.message,propertyName:r}}if(Object.getOwnPropertySymbols){const r=Object.getOwnPropertySymbols(e);for(const i of r)try{const r=e[i],s=this.makeSerializable(r,`${t}[Symbol(${i.description})]`);n[`__symbol_${i.description||"anonymous"}`]=s}catch(e){n[`__symbol_${i.description||"anonymous"}`]={__serializationError:!0,error:e.message,symbolName:i.description||"anonymous"}}}return n}return"function"==typeof e?{__type:"Function",name:e.name||"anonymous",length:e.length,toString:`${e.toString().substring(0,200)}...`}:{__type:"Unknown",constructor:e.constructor?e.constructor.name:"Unknown",toString:`${String(e).substring(0,200)}...`}}deserialize(e){try{const t=JSON.parse(e);return this.restoreCircularRefs(t)}catch(e){return console.error("SyntropyFront: Error en deserialización:",e),null}}restoreCircularRefs(e,t=new Map){if(null==e)return e;if("string"==typeof e||"number"==typeof e||"boolean"==typeof e)return e;if("Date"===e.__type)return new Date(e.value);if("Error"===e.__type){const r=new Error(e.message);return r.name=e.name,r.stack=e.stack,e.cause&&(r.cause=this.restoreCircularRefs(e.cause,t)),r}if("RegExp"===e.__type)return new RegExp(e.source,e.flags);if("Function"===e.__type)return`[Function: ${e.name}]`;if(Array.isArray(e)){const r=[];t.set(e,r);for(let n=0;n<e.length;n++)if(e[n]&&e[n].__circular){const i=e[n].refId;t.has(i)?r[n]=t.get(i):r[n]=null}else r[n]=this.restoreCircularRefs(e[n],t);return r}if("object"==typeof e){const r={};t.set(e,r);for(const n in e)if(Object.prototype.hasOwnProperty.call(e,n)){if(n.startsWith("__"))continue;const i=e[n];if(i&&i.__circular){const e=i.refId;t.has(e)?r[n]=t.get(e):r[n]=null}else r[n]=this.restoreCircularRefs(i,t)}return r}return e}serializeForLogging(e){try{return this.serialize(e)}catch(e){return JSON.stringify({__logError:!0,message:"Error serializando para logging",originalError:e.message,timestamp:(new Date).toISOString()})}}};class s{constructor(e){this.config=e}async send(e){const t={timestamp:(new Date).toISOString(),items:e};let r;try{r=i.serialize(t)}catch(t){console.error("SyntropyFront: Error en serialización del payload:",t),r=JSON.stringify({__serializationError:!0,error:t.message,timestamp:(new Date).toISOString(),itemsCount:e.length,fallbackData:"Serialización falló, datos no enviados"})}const n=await fetch(this.config.endpoint,{method:"POST",headers:this.config.headers,body:r});if(!n.ok)throw new Error(`HTTP ${n.status}: ${n.statusText}`);return n.json()}applyEncryption(e){return this.config.encrypt?this.config.encrypt(e):e}isConfigured(){return!!this.config.endpoint}}class a{constructor(e,t,r){this.dbName=e,this.dbVersion=t,this.storeName=r}validateConfig(){const e={isValid:!0,errors:[],timestamp:(new Date).toISOString()};return this.dbName&&"string"==typeof this.dbName||(e.isValid=!1,e.errors.push("dbName debe ser un string no vacío")),(!this.dbVersion||"number"!=typeof this.dbVersion||this.dbVersion<1)&&(e.isValid=!1,e.errors.push("dbVersion debe ser un número mayor a 0")),this.storeName&&"string"==typeof this.storeName||(e.isValid=!1,e.errors.push("storeName debe ser un string no vacío")),e}checkIndexedDBAvailability(){const e={isAvailable:!1,reason:null,timestamp:(new Date).toISOString()};return"undefined"==typeof window?(e.reason="No estamos en un entorno de browser",e):window.indexedDB?(e.isAvailable=!0,e):(e.reason="IndexedDB no está disponible en este browser",e)}getConfig(){return{dbName:this.dbName,dbVersion:this.dbVersion,storeName:this.storeName}}getStoreConfig(){return{keyPath:"id",autoIncrement:!0}}}class o{constructor(e){this.configManager=e,this.db=null,this.isAvailable=!1}async init(){const e={success:!1,error:null,timestamp:(new Date).toISOString()};try{const t=this.configManager.validateConfig();if(!t.isValid)return e.error=`Configuración inválida: ${t.errors.join(", ")}`,e;const r=this.configManager.checkIndexedDBAvailability();if(!r.isAvailable)return e.error=r.reason,e;const n=await this.openConnection();return n.success?(this.db=n.db,this.isAvailable=!0,e.success=!0,e):(e.error=n.error,e)}catch(t){return e.error=`Error inesperado: ${t.message}`,e}}openConnection(){return new Promise(e=>{const t=this.configManager.getConfig(),r=indexedDB.open(t.dbName,t.dbVersion);r.onerror=()=>{e({success:!1,error:"Error abriendo IndexedDB",db:null})},r.onupgradeneeded=e=>{const r=e.target.result,n=this.configManager.getStoreConfig();r.objectStoreNames.contains(t.storeName)||r.createObjectStore(t.storeName,n)},r.onsuccess=()=>{e({success:!0,error:null,db:r.result})}})}close(){const e={success:!1,error:null,timestamp:(new Date).toISOString()};try{this.db?(this.db.close(),this.db=null,this.isAvailable=!1,e.success=!0):e.error="No hay conexión activa para cerrar"}catch(t){e.error=`Error cerrando conexión: ${t.message}`}return e}isDatabaseAvailable(){return this.isAvailable&&null!==this.db}getDatabase(){return this.isDatabaseAvailable()?this.db:null}}class c{constructor(e,t){this.connectionManager=e,this.configManager=t}getReadTransaction(){this.ensureDatabaseAvailable();const e=this.configManager.getConfig();return this.connectionManager.getDatabase().transaction([e.storeName],"readonly")}getWriteTransaction(){this.ensureDatabaseAvailable();const e=this.configManager.getConfig();return this.connectionManager.getDatabase().transaction([e.storeName],"readwrite")}getObjectStore(e){const t=this.configManager.getConfig();return e.objectStore(t.storeName)}async executeReadOperation(e){const t={success:!1,data:null,error:null,timestamp:(new Date).toISOString()};try{const r=this.getReadTransaction(),n=this.getObjectStore(r),i=await e(n);return t.success=!0,t.data=i,t}catch(e){return t.error=`Error en operación de lectura: ${e.message}`,t}}async executeWriteOperation(e){const t={success:!1,data:null,error:null,timestamp:(new Date).toISOString()};try{const r=this.getWriteTransaction(),n=this.getObjectStore(r),i=await e(n);return t.success=!0,t.data=i,t}catch(e){return t.error=`Error en operación de escritura: ${e.message}`,t}}ensureDatabaseAvailable(){if(!this.connectionManager.isDatabaseAvailable())throw new Error("Database not available")}getTransactionStatus(){return{isDatabaseAvailable:this.connectionManager.isDatabaseAvailable(),storeName:this.configManager.getConfig().storeName,timestamp:(new Date).toISOString()}}}class l{constructor(e,t,r){this.configManager=new a(e,t,r),this.connectionManager=new o(this.configManager),this.transactionManager=new c(this.connectionManager,this.configManager)}async init(){const e=await this.connectionManager.init();return e.success?console.log("SyntropyFront: Base de datos inicializada"):console.warn("SyntropyFront: Error inicializando base de datos:",e.error),e.success}getReadTransaction(){return this.transactionManager.getReadTransaction()}getWriteTransaction(){return this.transactionManager.getWriteTransaction()}close(){const e=this.connectionManager.close();return e.success||console.warn("SyntropyFront: Error cerrando base de datos:",e.error),e.success}isDatabaseAvailable(){return this.connectionManager.isDatabaseAvailable()}get dbName(){return this.configManager.dbName}get dbVersion(){return this.configManager.dbVersion}get storeName(){return this.configManager.storeName}get db(){return this.connectionManager.getDatabase()}get isAvailable(){return this.connectionManager.isDatabaseAvailable()}}class u{constructor(e,t){this.databaseManager=e,this.serializationManager=t}async save(e){this.ensureDatabaseAvailable();const t=this.serializationManager.serialize(e),r={items:this.serializationManager.getData(t,"[]"),timestamp:(new Date).toISOString(),retryCount:0,serializationError:t.error};return this.executeWriteOperation(e=>e.add(r))}async retrieve(){if(!this.databaseManager.isDatabaseAvailable())return[];const e=await this.executeReadOperation(e=>e.getAll());return this.deserializeItems(e)}async retrieveById(e){if(!this.databaseManager.isDatabaseAvailable())return null;const t=await this.executeReadOperation(t=>t.get(e));return t?this.deserializeItem(t):null}async remove(e){return this.ensureDatabaseAvailable(),this.executeWriteOperation(t=>t.delete(e))}async update(e,t){this.ensureDatabaseAvailable();const r=await this.retrieveById(e);if(!r)throw new Error("Item not found");const n={...r,...t};return this.executeWriteOperation(e=>e.put(n))}async clear(){return this.ensureDatabaseAvailable(),this.executeWriteOperation(e=>e.clear())}ensureDatabaseAvailable(){if(!this.databaseManager.isDatabaseAvailable())throw new Error("Database not available")}executeReadOperation(e){return new Promise((t,r)=>{try{const n=this.databaseManager.getReadTransaction().objectStore(this.databaseManager.storeName),i=e(n);i.onsuccess=()=>t(i.result),i.onerror=()=>r(i.error)}catch(e){r(e)}})}executeWriteOperation(e){return new Promise((t,r)=>{try{const n=this.databaseManager.getWriteTransaction().objectStore(this.databaseManager.storeName),i=e(n);i.onsuccess=()=>t(i.result),i.onerror=()=>r(i.error)}catch(e){r(e)}})}deserializeItems(e){return e.map(e=>this.deserializeItem(e))}deserializeItem(e){const t=this.serializationManager.deserialize(e.items),r=this.serializationManager.getData(t,[]);return{...e,items:r,deserializationError:t.error}}}class h{constructor(e,t){this.storageManager=e,this.config=t}async retryFailedItems(e,t){if(this.storageManager)try{const r=await this.storageManager.retrieve();for(const n of r)if(n.retryCount<this.config.maxRetries){let r;try{r="string"==typeof n.items?i.deserialize(n.items):n.items}catch(e){console.error("SyntropyFront: Error deserializando items del buffer:",e),await this.removeFailedItem(n.id);continue}if(e)try{await e(r,n.retryCount+1,n.id),t?await t(n.id):await this.removeFailedItem(n.id),console.log(`SyntropyFront: Reintento exitoso para item ${n.id}`)}catch(e){console.warn(`SyntropyFront: Reintento falló para item ${n.id}:`,e),await this.incrementRetryCount(n.id)}}else console.warn(`SyntropyFront: Item ${n.id} excedió máximo de reintentos, removiendo del buffer`),await this.removeFailedItem(n.id)}catch(e){console.error("SyntropyFront: Error procesando reintentos:",e)}else console.warn("SyntropyFront: Storage manager no disponible")}async incrementRetryCount(e){try{const t=await this.storageManager.retrieveById(e);t&&await this.storageManager.update(e,{retryCount:t.retryCount+1})}catch(e){console.error("SyntropyFront: Error incrementando contador de reintentos:",e)}}async removeFailedItem(e){try{await this.storageManager.remove(e)}catch(e){console.error("SyntropyFront: Error removiendo item fallido:",e)}}async cleanupExpiredItems(){try{const e=(await this.storageManager.retrieve()).filter(e=>e.retryCount>=this.config.maxRetries);for(const t of e)await this.removeFailedItem(t.id),console.warn(`SyntropyFront: Item ${t.id} removido por exceder máximo de reintentos`);e.length>0&&console.log(`SyntropyFront: Limpieza completada, ${e.length} items removidos`)}catch(e){console.error("SyntropyFront: Error en limpieza de items expirados:",e)}}async getRetryStats(){try{const e=await this.storageManager.retrieve(),t={totalItems:e.length,itemsByRetryCount:{},averageRetryCount:0};if(e.length>0){const r=e.reduce((e,t)=>e+t.retryCount,0);t.averageRetryCount=r/e.length,e.forEach(e=>{const r=e.retryCount;t.itemsByRetryCount[r]=(t.itemsByRetryCount[r]||0)+1})}return t}catch(e){return console.error("SyntropyFront: Error obteniendo estadísticas de reintentos:",e),{totalItems:0,itemsByRetryCount:{},averageRetryCount:0}}}}class d{constructor(){this.serializer=i}serialize(e){const t={success:!1,data:null,error:null,timestamp:(new Date).toISOString()};try{const r=this.serializer.serialize(e);return{...t,success:!0,data:r}}catch(e){return{...t,error:this.createSerializationError(e),data:this.createFallbackData(e)}}}deserialize(e){const t={success:!1,data:null,error:null,timestamp:(new Date).toISOString()};try{const r=this.serializer.deserialize(e);return{...t,success:!0,data:r}}catch(e){return{...t,error:this.createDeserializationError(e),data:[]}}}createSerializationError(e){return{type:"serialization_error",message:e.message,originalError:e,timestamp:(new Date).toISOString()}}createDeserializationError(e){return{type:"deserialization_error",message:e.message,originalError:e,timestamp:(new Date).toISOString()}}createFallbackData(e){const t={__serializationError:!0,error:e.message,timestamp:(new Date).toISOString(),fallbackData:"Items no serializables - usando fallback"};return JSON.stringify(t)}isSuccessful(e){return Boolean(e&&!0===e.success)}getData(e,t=null){return this.isSuccessful(e)?e.data:t}}class g{constructor(e){this.config=e,this.usePersistentBuffer=!1,this.databaseManager=new l("SyntropyFrontBuffer",1,"failedItems"),this.serializationManager=new d,this.storageManager=new u(this.databaseManager,this.serializationManager),this.retryLogicManager=new h(this.storageManager,this.config),this.initPersistentBuffer()}async initPersistentBuffer(){try{await this.databaseManager.init()&&(this.usePersistentBuffer=this.config.usePersistentBuffer,console.log("SyntropyFront: Buffer persistente inicializado"))}catch(e){console.warn("SyntropyFront: Error inicializando buffer persistente:",e)}}async save(e){if(this.usePersistentBuffer)try{await this.storageManager.save(e),console.log("SyntropyFront: Items guardados en buffer persistente")}catch(e){console.error("SyntropyFront: Error guardando en buffer persistente:",e)}}async retrieve(){if(!this.usePersistentBuffer)return[];try{return await this.storageManager.retrieve()}catch(e){return console.error("SyntropyFront: Error obteniendo del buffer persistente:",e),[]}}async remove(e){if(this.usePersistentBuffer)try{await this.storageManager.remove(e)}catch(e){console.error("SyntropyFront: Error removiendo del buffer persistente:",e)}}async retryFailedItems(e,t){this.usePersistentBuffer&&await this.retryLogicManager.retryFailedItems(e,t)}async cleanupExpiredItems(){this.usePersistentBuffer&&await this.retryLogicManager.cleanupExpiredItems()}async getStats(){if(!this.usePersistentBuffer)return{totalItems:0,itemsByRetryCount:{},averageRetryCount:0,isAvailable:!1};try{return{...await this.retryLogicManager.getRetryStats(),isAvailable:this.isAvailable()}}catch(e){return console.error("SyntropyFront: Error obteniendo estadísticas:",e),{totalItems:0,itemsByRetryCount:{},averageRetryCount:0,isAvailable:this.isAvailable()}}}isAvailable(){return this.usePersistentBuffer&&this.databaseManager.isDatabaseAvailable()}async clear(){if(this.usePersistentBuffer)try{await this.storageManager.clear(),console.log("SyntropyFront: Buffer persistente limpiado")}catch(e){console.error("SyntropyFront: Error limpiando buffer persistente:",e)}}close(){this.databaseManager.close(),this.usePersistentBuffer=!1}}const y=new class{constructor(){this.config=new t,this.queue=new r(this.config),this.retry=new n(this.config),this.transport=new s(this.config),this.buffer=new g(this.config),this.setupCallbacks()}setupCallbacks(){this.queue.flushCallback=async e=>{try{await this.transport.send(e),console.log("SyntropyFront: Datos enviados exitosamente")}catch(t){console.error("SyntropyFront Agent: Error enviando datos:",t),this.retry.addToRetryQueue(e),await this.buffer.save(e)}},this.retry.sendCallback=async e=>await this.transport.send(e),this.retry.removePersistentCallback=async e=>{await this.buffer.remove(e)},this.buffer.sendCallback=(e,t,r)=>{this.retry.addToRetryQueue(e,t,r)}}configure(e){this.config.configure(e)}sendError(e,t=null){if(!this.config.isAgentEnabled())return void console.warn("SyntropyFront Agent: No configurado, error no enviado");const r=t?{...e,context:t}:e,n=this.transport.applyEncryption(r);this.queue.add({type:"error",data:n,timestamp:(new Date).toISOString()})}sendBreadcrumbs(e){if(!this.config.isAgentEnabled()||!this.config.shouldSendBreadcrumbs()||!e.length)return;const t=this.transport.applyEncryption(e);this.queue.add({type:"breadcrumbs",data:t,timestamp:(new Date).toISOString()})}addToQueue(e){this.queue.add(e)}addToRetryQueue(e,t=1,r=null){this.retry.addToRetryQueue(e,t,r)}async processRetryQueue(){await this.retry.processRetryQueue(this.retry.sendCallback,this.retry.removePersistentCallback)}async flush(){await this.queue.flush(this.queue.flushCallback)}async forceFlush(){await this.flush(),this.retry.isEmpty()||(console.log("SyntropyFront: Intentando enviar items en cola de reintentos..."),await this.processRetryQueue())}getStats(){const e=this.config.getConfig();return{queueLength:this.queue.getSize(),retryQueueLength:this.retry.getSize(),isEnabled:this.config.isAgentEnabled(),usePersistentBuffer:e.usePersistentBuffer,maxRetries:e.maxRetries}}async retryFailedItems(){await this.buffer.retryFailedItems(this.buffer.sendCallback)}disable(){this.config.configure({endpoint:null}),this.queue.clear(),this.retry.clear()}};const m=new class{constructor(){this.defaultContexts={device:{userAgent:()=>navigator.userAgent,language:()=>navigator.language,screen:()=>({width:window.screen.width,height:window.screen.height}),timezone:()=>Intl.DateTimeFormat().resolvedOptions().timeZone},window:{url:()=>window.location.href,viewport:()=>({width:window.innerWidth,height:window.innerHeight}),title:()=>document.title},session:{sessionId:()=>this.generateSessionId(),pageLoadTime:()=>performance.now()},ui:{visibility:()=>document.visibilityState,activeElement:()=>document.activeElement?{tagName:document.activeElement.tagName}:null},network:{online:()=>navigator.onLine,connection:()=>navigator.connection?{effectiveType:navigator.connection.effectiveType}:null}},this.allFields={device:{userAgent:()=>navigator.userAgent,language:()=>navigator.language,languages:()=>navigator.languages,screen:()=>({width:window.screen.width,height:window.screen.height,availWidth:window.screen.availWidth,availHeight:window.screen.availHeight,colorDepth:window.screen.colorDepth,pixelDepth:window.screen.pixelDepth}),timezone:()=>Intl.DateTimeFormat().resolvedOptions().timeZone,cookieEnabled:()=>navigator.cookieEnabled,doNotTrack:()=>navigator.doNotTrack},window:{url:()=>window.location.href,pathname:()=>window.location.pathname,search:()=>window.location.search,hash:()=>window.location.hash,referrer:()=>document.referrer,title:()=>document.title,viewport:()=>({width:window.innerWidth,height:window.innerHeight})},storage:{localStorage:()=>{const e=Object.keys(localStorage);return{keys:e.length,size:JSON.stringify(localStorage).length,keyNames:e}},sessionStorage:()=>{const e=Object.keys(sessionStorage);return{keys:e.length,size:JSON.stringify(sessionStorage).length,keyNames:e}}},network:{online:()=>navigator.onLine,connection:()=>navigator.connection?{effectiveType:navigator.connection.effectiveType,downlink:navigator.connection.downlink,rtt:navigator.connection.rtt}:null},ui:{focused:()=>document.hasFocus(),visibility:()=>document.visibilityState,activeElement:()=>document.activeElement?{tagName:document.activeElement.tagName,id:document.activeElement.id,className:document.activeElement.className}:null},performance:{memory:()=>window.performance&&window.performance.memory?{used:Math.round(window.performance.memory.usedJSHeapSize/1048576),total:Math.round(window.performance.memory.totalJSHeapSize/1048576),limit:Math.round(window.performance.memory.jsHeapSizeLimit/1048576)}:null,timing:()=>window.performance?{navigationStart:window.performance.timing.navigationStart,loadEventEnd:window.performance.timing.loadEventEnd}:null},session:{sessionId:()=>this.generateSessionId(),startTime:()=>(new Date).toISOString(),pageLoadTime:()=>performance.now()}}}collect(e={}){const t={};return Object.entries(e).forEach(([e,r])=>{try{!0===r?t[e]=this.collectDefaultContext(e):Array.isArray(r)?t[e]=this.collectSpecificFields(e,r):!1===r||console.warn(`SyntropyFront: Configuración de contexto inválida para ${e}:`,r)}catch(r){console.warn(`SyntropyFront: Error recolectando contexto ${e}:`,r),t[e]={error:"Failed to collect"}}}),t}collectDefaultContext(e){const t=this.defaultContexts[e];if(!t)return console.warn(`SyntropyFront: No hay set por defecto para ${e}`),{};const r={};return Object.entries(t).forEach(([t,n])=>{try{r[t]=n()}catch(n){console.warn(`SyntropyFront: Error recolectando campo ${t} de ${e}:`,n),r[t]=null}}),r}collectSpecificFields(e,t){const r=this.allFields[e];if(!r)return console.warn(`SyntropyFront: Tipo de contexto desconocido: ${e}`),{};const n={};return t.forEach(t=>{try{r[t]?n[t]=r[t]():console.warn(`SyntropyFront: Campo ${t} no disponible en ${e}`)}catch(r){console.warn(`SyntropyFront: Error recolectando campo ${t} de ${e}:`,r),n[t]=null}}),n}generateSecureId(){try{if("undefined"!=typeof crypto&&crypto.randomUUID)return crypto.randomUUID();if("undefined"!=typeof crypto&&crypto.getRandomValues){const e=new Uint8Array(16);crypto.getRandomValues(e);const t=Array.from(e,e=>e.toString(16).padStart(2,"0")).join("");return[t.slice(0,8),t.slice(8,12),t.slice(12,16),t.slice(16,20),t.slice(20,32)].join("-")}const e=Date.now().toString(36);return`${e}-${Math.random().toString(36).substring(2,15)}`}catch(e){return console.warn("SyntropyFront: Error generando ID seguro, usando fallback:",e),`session_${Date.now()}_${Math.random().toString(36).substring(2,9)}`}}generateSessionId(){return this._sessionId||(this._sessionId=`session_${this.generateSecureId()}`),this._sessionId}getAvailableTypes(){return Object.keys(this.allFields)}getAvailableFields(e){const t=this.allFields[e];return t?Object.keys(t):[]}getDefaultContextsInfo(){const e={};return Object.entries(this.defaultContexts).forEach(([t,r])=>{e[t]=Object.keys(r)}),e}};const f=new class{constructor(){this.isInitialized=!1,this.config={captureClicks:!0,captureFetch:!0,captureErrors:!0,captureUnhandledRejections:!0},this.contextTypes=[],this.originalHandlers={fetch:null,onerror:null,onunhandledrejection:null},this.eventListeners=new Map}configure(e){this.config={...this.config,...e},this.contextTypes=e.context||[]}init(){this.isInitialized?console.warn("SyntropyFront: Interceptors ya están inicializados"):(this.config.captureClicks&&this.setupClickInterceptor(),this.config.captureFetch&&this.setupFetchInterceptor(),(this.config.captureErrors||this.config.captureUnhandledRejections)&&this.setupErrorInterceptors(),this.isInitialized=!0,console.log("SyntropyFront: Interceptors inicializados con Chaining Pattern"))}setupClickInterceptor(){if("undefined"==typeof document)return void console.log("SyntropyFront: Click interceptor no disponible (no browser)");let t=0;const r=r=>{const n=r.target;if(!n)return;const i=Date.now();if(i-t<500)return;t=i;const s=e=>{if(!e||1!==e.nodeType)return!1;const t=["button","link","checkbox","radio","menuitem"].includes(e.getAttribute?.("role"));let r=!1;try{r="pointer"===window.getComputedStyle?.(e)?.cursor}catch(e){}return["a","button","input","select","textarea","label","summary"].includes(e.tagName.toLowerCase())||t||r};let a=n;for(;a&&a!==document.body&&!s(a);)a=a.parentElement;if(!a||a===document.body)return;let o=a.tagName.toLowerCase();a.id?o+=`#${a.id}`:a.className&&"string"==typeof a.className&&(o+=`.${a.className.split(" ").filter(Boolean).join(".")}`),e.add({category:"ui",message:`Usuario hizo click en '${o}'`,data:{selector:o,tagName:a.tagName,id:a.id,className:a.className,text:a.innerText?.substring(0,30).trim()||a.value?.substring(0,30)}})};this.eventListeners.set("click",r),document.addEventListener("click",r,!0)}setupFetchInterceptor(){if("undefined"==typeof window||!window.fetch)return void console.log("SyntropyFront: Fetch interceptor no disponible (no browser/fetch)");this.originalHandlers.fetch=window.fetch;window.fetch=(...t)=>{const r=t[0]instanceof Request?t[0].url:t[0],n=t[0]instanceof Request?t[0].method:t[1]?.method||"GET";return e.add({category:"network",message:`Request: ${n} ${r}`,data:{url:r,method:n,timestamp:Date.now()}}),this.originalHandlers.fetch.apply(window,t)}}setupErrorInterceptors(){if("undefined"!=typeof window){if(this.config.captureErrors){this.originalHandlers.onerror=window.onerror;const t=(t,r,n,i,s)=>{const a={type:"uncaught_exception",error:{message:t,source:r,lineno:n,colno:i,stack:s?.stack},breadcrumbs:e.getAll(),timestamp:(new Date).toISOString()};if(this.handleError(a),this.originalHandlers.onerror)try{return this.originalHandlers.onerror(t,r,n,i,s)}catch(e){return console.warn("SyntropyFront: Error en handler original:",e),!1}return!1};window.onerror=t}if(this.config.captureUnhandledRejections){this.originalHandlers.onunhandledrejection=window.onunhandledrejection;const t=t=>{const r={type:"unhandled_rejection",error:{message:t.reason?.message||"Rechazo de promesa sin mensaje",stack:t.reason?.stack},breadcrumbs:e.getAll(),timestamp:(new Date).toISOString()};if(this.handleError(r),this.originalHandlers.onunhandledrejection)try{this.originalHandlers.onunhandledrejection(t)}catch(e){console.warn("SyntropyFront: Error en handler original de rejection:",e)}};window.onunhandledrejection=t}}else console.log("SyntropyFront: Error interceptors no disponibles (no browser)")}handleError(e){const t=this.contextTypes.length>0?m.collect(this.contextTypes):null;y.sendError(e,t),this.onError?this.onError(e):console.error("SyntropyFront - Error detectado:",e)}destroy(){this.isInitialized&&(console.log("SyntropyFront: Limpiando interceptores..."),this.originalHandlers.fetch&&(window.fetch=this.originalHandlers.fetch,console.log("SyntropyFront: fetch original restaurado")),this.originalHandlers.onerror&&(window.onerror=this.originalHandlers.onerror,console.log("SyntropyFront: onerror original restaurado")),this.originalHandlers.onunhandledrejection&&(window.onunhandledrejection=this.originalHandlers.onunhandledrejection,console.log("SyntropyFront: onunhandledrejection original restaurado")),"undefined"!=typeof document&&this.eventListeners.forEach((e,t)=>{document.removeEventListener(t,e,!0),console.log(`SyntropyFront: Event listener ${t} removido`)}),this.originalHandlers={fetch:null,onerror:null,onunhandledrejection:null},this.eventListeners.clear(),this.isInitialized=!1,console.log("SyntropyFront: Interceptors destruidos y handlers restaurados"))}getHandlerInfo(){return{isInitialized:this.isInitialized,hasOriginalFetch:!!this.originalHandlers.fetch,hasOriginalOnError:!!this.originalHandlers.onerror,hasOriginalOnUnhandledRejection:!!this.originalHandlers.onunhandledrejection,eventListenersCount:this.eventListeners.size}}};return new class{constructor(){this.isActive=!1,this.config={maxEvents:50,endpoint:null,headers:{},usePersistentBuffer:!0,captureClicks:!0,captureFetch:!0,captureErrors:!0,captureUnhandledRejections:!0,onError:null},this.init()}init(){this.isActive||(y.configure({endpoint:this.config.endpoint,headers:this.config.headers,usePersistentBuffer:this.config.usePersistentBuffer}),f.configure({captureClicks:this.config.captureClicks,captureFetch:this.config.captureFetch,captureErrors:this.config.captureErrors,captureUnhandledRejections:this.config.captureUnhandledRejections}),this.config.onError&&(f.onError=this.config.onError),f.init(),y.retryFailedItems().catch(e=>{console.warn("SyntropyFront: Error al intentar recuperar items persistentes:",e)}),this.isActive=!0,console.log("🚀 SyntropyFront: Inicializado con arquitectura modular resiliente"))}configure(e={}){this.config={...this.config,...e},e.fetch&&(this.config.endpoint=e.fetch.url,this.config.headers=e.fetch.options?.headers||{}),y.configure({endpoint:this.config.endpoint,headers:this.config.headers,usePersistentBuffer:this.config.usePersistentBuffer}),f.configure({captureClicks:this.config.captureClicks,captureFetch:this.config.captureFetch,captureErrors:this.config.captureErrors,captureUnhandledRejections:this.config.captureUnhandledRejections}),this.config.onError&&(f.onError=this.config.onError);const t=this.config.endpoint?`endpoint: ${this.config.endpoint}`:"console only";console.log(`✅ SyntropyFront: Configurado - ${t}`)}addBreadcrumb(t,r,n={}){return e.add({category:t,message:r,data:n})}getBreadcrumbs(){return e.getAll()}clearBreadcrumbs(){e.clear()}sendError(e,t={}){const r={type:"manual_error",error:{message:e.message||String(e),name:e.name||"Error",stack:e.stack},breadcrumbs:this.getBreadcrumbs(),timestamp:(new Date).toISOString()};return y.sendError(r,t),r}async flush(){await y.forceFlush()}getStats(){return{isActive:this.isActive,breadcrumbs:e.count(),agent:y.getStats(),config:{...this.config}}}destroy(){f.destroy(),y.disable(),this.isActive=!1,console.log("SyntropyFront: Desactivado")}}}();
1
+ var SyntropyFront=function(){"use strict";const e=new class{constructor(e=25){this.maxBreadcrumbs=e,this.breadcrumbs=[],this.onBreadcrumbAdded=null}setMaxBreadcrumbs(e){this.maxBreadcrumbs=e,this.breadcrumbs.length>this.maxBreadcrumbs&&(this.breadcrumbs=this.breadcrumbs.slice(-this.maxBreadcrumbs))}getMaxBreadcrumbs(){return this.maxBreadcrumbs}add(e){const t={...e,timestamp:(new Date).toISOString()};if(this.breadcrumbs=[...this.breadcrumbs,t].slice(-this.maxBreadcrumbs),this.onBreadcrumbAdded)try{this.onBreadcrumbAdded(t)}catch(e){console.warn("SyntropyFront: Error in onBreadcrumbAdded:",e)}}getAll(){return[...this.breadcrumbs]}clear(){this.breadcrumbs=[]}count(){return this.breadcrumbs.length}getByCategory(e){return this.breadcrumbs.filter(t=>t.category===e)}};class t{constructor(){this.endpoint=null,this.headers={"Content-Type":"application/json"},this.batchSize=10,this.batchTimeout=null,this.isEnabled=!1,this.sendBreadcrumbs=!1,this.encrypt=null,this.usePersistentBuffer=!1,this.maxRetries=5,this.baseDelay=1e3,this.maxDelay=3e4,this.samplingRate=1}configure(e){this.endpoint=e.endpoint,this.headers={...this.headers,...e.headers},this.batchSize=e.batchSize||this.batchSize,this.batchTimeout=e.batchTimeout,this.isEnabled=!!e.endpoint,this.encrypt=e.encrypt||null,this.usePersistentBuffer=!0===e.usePersistentBuffer,this.maxRetries=e.maxRetries||this.maxRetries,this.samplingRate="number"==typeof e.samplingRate?e.samplingRate:this.samplingRate,this.sendBreadcrumbs=!!e.batchTimeout}isAgentEnabled(){return this.isEnabled}shouldSendBreadcrumbs(){return this.sendBreadcrumbs}getConfig(){return{endpoint:this.endpoint,headers:this.headers,batchSize:this.batchSize,batchTimeout:this.batchTimeout,isEnabled:this.isEnabled,sendBreadcrumbs:this.sendBreadcrumbs,encrypt:this.encrypt,usePersistentBuffer:this.usePersistentBuffer,maxRetries:this.maxRetries,baseDelay:this.baseDelay,maxDelay:this.maxDelay,samplingRate:this.samplingRate}}}class r{constructor(e){this.config=e,this.queue=[],this.batchTimer=null,this.flushCallback=null}add(e){if(e){if(this.queue.push(e),this.queue.length>=this.config.batchSize)return this.flush(this.flushCallback);this.config.batchTimeout&&!this.batchTimer&&(this.batchTimer=setTimeout(()=>{this.flush(this.flushCallback)},this.config.batchTimeout))}}getAll(){return[...this.queue]}clear(){this.queue=[],this.clearTimer()}clearTimer(){this.batchTimer&&(clearTimeout(this.batchTimer),this.batchTimer=null)}getSize(){return this.queue.length}isEmpty(){return 0===this.queue.length}async flush(e){if(0===this.queue.length)return;const t=[...this.queue];this.queue=[],this.clearTimer(),e&&await e(t)}}class s{constructor(e){this.config=e,this.retryQueue=[],this.retryTimer=null}addToRetryQueue(e,t=1,r=null){if(!e||0===e.length)return;const s=Math.min(this.config.baseDelay*Math.pow(2,t-1),this.config.maxDelay);this.retryQueue.push({items:e,retryCount:t,persistentId:r,nextRetry:Date.now()+s}),this.scheduleRetry()}async processRetryQueue(e,t){if(this.retryTimer=null,0===this.retryQueue.length)return;const r=Date.now(),s=this.retryQueue.filter(e=>e.nextRetry<=r);for(const r of s)await this.handleRetryItem(r,e,t);this.retryQueue.length>0&&this.scheduleRetry()}scheduleRetry(){if(this.retryTimer)return;const e=this.retryQueue.find(e=>e.nextRetry<=Date.now());if(!e)return;const t=Math.max(0,e.nextRetry-Date.now());this.retryTimer=setTimeout(()=>{this.processRetryQueue(this.sendCallback,this.removePersistentCallback)},t)}async handleRetryItem(e,t,r){try{t&&await t(e.items),this.retryQueue=this.retryQueue.filter(t=>t!==e),e.persistentId&&r&&await r(e.persistentId),console.log(`SyntropyFront: Successful retry (${e.retryCount})`)}catch(t){this.handleRetryFailure(e,t)}}handleRetryFailure(e,t){if(console.warn(`SyntropyFront: Retry ${e.retryCount} failed:`,t),e.retryCount>=this.config.maxRetries)return this.retryQueue=this.retryQueue.filter(t=>t!==e),void console.error("SyntropyFront: Item exceeded maximum retries, data lost");e.retryCount++,e.nextRetry=Date.now()+Math.min(this.config.baseDelay*Math.pow(2,e.retryCount-1),this.config.maxDelay)}clear(){this.retryQueue=[],this.clearTimer()}clearTimer(){this.retryTimer&&(clearTimeout(this.retryTimer),this.retryTimer=null)}getSize(){return this.retryQueue.length}isEmpty(){return 0===this.retryQueue.length}}const n=new class{constructor(){this.seen=new WeakSet,this.circularRefs=new Map,this.refCounter=0}serialize(e){try{return this.seen=new WeakSet,this.circularRefs=new Map,this.refCounter=0,JSON.stringify(this.makeSerializable(e))}catch(t){return console.error("SyntropyFront: Error in robust serialization:",t),JSON.stringify({__serializationError:!0,error:t.message,originalType:typeof e,isObject:null!==e&&"object"==typeof e,timestamp:(new Date).toISOString()})}}_serializeKnownType(e,t){return null==e||"string"==typeof e||"number"==typeof e||"boolean"==typeof e?e:e instanceof Date?{__type:"Date",value:e.toISOString()}:e instanceof Error?(s=e=>this.makeSerializable(e,`${t}.cause`),{__type:"Error",name:(r=e).name,message:r.message,stack:r.stack,cause:r.cause?s(r.cause):void 0}):e instanceof RegExp?{__type:"RegExp",source:(n=e).source,flags:n.flags}:"function"==typeof e?{__type:"Function",name:(i=e).name||"anonymous",length:i.length,toString:`${i.toString().substring(0,200)}...`}:void 0;var r,s,n,i}makeSerializable(e,t=""){if(null==e)return e;const r=this._serializeKnownType(e,t);return void 0!==r?r:Array.isArray(e)?this._serializeArray(e,t):"object"==typeof e?this._serializeObject(e,t):(e=>({__type:"Unknown",constructor:e.constructor?e.constructor.name:"Unknown",toString:`${String(e).substring(0,200)}...`}))(e)}_serializeArray(e,t){return this.seen.has(e)?{__circular:!0,refId:this.circularRefs.get(e)}:(this.seen.add(e),this.circularRefs.set(e,"ref_"+ ++this.refCounter),e.map((e,r)=>this.makeSerializable(e,`${t}[${r}]`)))}_serializeObjectKey(e,t,r,s){try{e[r]=this.makeSerializable(t[r],`${s}.${r}`)}catch(t){e[r]={__serializationError:!0,error:t.message,propertyName:r}}}_serializeObjectSymbols(e,t,r){if(!Object.getOwnPropertySymbols)return;const s=Object.getOwnPropertySymbols(e);for(const n of s){const s=`__symbol_${n.description||"anonymous"}`;try{r[s]=this.makeSerializable(e[n],`${t}[Symbol]`)}catch(e){r[s]={__serializationError:!0,error:e.message,symbolName:n.description||"anonymous"}}}}_serializeObject(e,t){if(this.seen.has(e))return{__circular:!0,refId:this.circularRefs.get(e)};this.seen.add(e),this.circularRefs.set(e,"ref_"+ ++this.refCounter);const r={};for(const s in e)Object.prototype.hasOwnProperty.call(e,s)&&this._serializeObjectKey(r,e,s,t);return this._serializeObjectSymbols(e,t,r),r}deserialize(e){try{const t=JSON.parse(e);return this.restoreCircularRefs(t)}catch(e){return console.error("SyntropyFront: Error in deserialization:",e),null}}_restoreKnownType(e,t){return null==e||"string"==typeof e||"number"==typeof e||"boolean"==typeof e?e:"Date"===e.__type?(e=>new Date(e.value))(e):"Error"===e.__type?((e,t)=>{const r=new Error(e.message);return r.name=e.name,r.stack=e.stack,e.cause&&(r.cause=t(e.cause)),r})(e,e=>this.restoreCircularRefs(e,t)):"RegExp"===e.__type?(e=>new RegExp(e.source,e.flags))(e):"Function"===e.__type?(e=>`[Function: ${e.name}]`)(e):void 0}restoreCircularRefs(e,t=new Map){const r=this._restoreKnownType(e,t);return void 0!==r?r:Array.isArray(e)?this._restoreArray(e,t):"object"==typeof e?this._restoreObject(e,t):e}_restoreArray(e,t){const r=[];t.set(e,r);for(let s=0;s<e.length;s++)e[s]?.__circular?r[s]=t.has(e[s].refId)?t.get(e[s].refId):null:r[s]=this.restoreCircularRefs(e[s],t);return r}_restoreObject(e,t){const r={};t.set(e,r);for(const s in e){if(!Object.prototype.hasOwnProperty.call(e,s)||s.startsWith("__"))continue;const n=e[s];r[s]=n?.__circular?t.has(n.refId)?t.get(n.refId):null:this.restoreCircularRefs(n,t)}return r}serializeForLogging(e){try{return this.serialize(e)}catch(e){return JSON.stringify({__logError:!0,message:"Error serializing for logging",originalError:e.message,timestamp:(new Date).toISOString()})}}};class i{constructor(e){this.config=e}async send(e){const t={timestamp:(new Date).toISOString(),items:e};let r;try{r=n.serialize(t)}catch(t){console.error("SyntropyFront: Error in payload serialization:",t),r=JSON.stringify({__serializationError:!0,error:t.message,timestamp:(new Date).toISOString(),itemsCount:e.length,fallbackData:"Serialization failed, data not sent"})}const s=await fetch(this.config.endpoint,{method:"POST",headers:this.config.headers,body:r});if(!s.ok)throw new Error(`HTTP ${s.status}: ${s.statusText}`);return s.json()}applyEncryption(e){return this.config.encrypt?this.config.encrypt(e):e}isConfigured(){return!!this.config.endpoint}}class a{constructor(e,t,r){this.dbName=e,this.dbVersion=t,this.storeName=r}validateConfig(){const e={isValid:!0,errors:[],timestamp:(new Date).toISOString()};return this.dbName&&"string"==typeof this.dbName||(e.isValid=!1,e.errors.push("dbName must be a non-empty string")),(!this.dbVersion||"number"!=typeof this.dbVersion||this.dbVersion<1)&&(e.isValid=!1,e.errors.push("dbVersion must be a number greater than 0")),this.storeName&&"string"==typeof this.storeName||(e.isValid=!1,e.errors.push("storeName must be a non-empty string")),e}checkIndexedDBAvailability(){const e={isAvailable:!1,reason:null,timestamp:(new Date).toISOString()};return"undefined"==typeof window?(e.reason="Not in a browser environment",e):window.indexedDB?(e.isAvailable=!0,e):(e.reason="IndexedDB is not available in this browser",e)}getConfig(){return{dbName:this.dbName,dbVersion:this.dbVersion,storeName:this.storeName}}getStoreConfig(){return{keyPath:"id",autoIncrement:!0}}}class o{constructor(e){this.configManager=e,this.db=null,this.isAvailable=!1}async init(){const e=this.configManager.validateConfig();if(!e.isValid)return{success:!1,error:`Invalid configuration: ${e.errors.join(", ")}`,timestamp:(new Date).toISOString()};const t=this.configManager.checkIndexedDBAvailability();if(!t.isAvailable)return{success:!1,error:t.reason,timestamp:(new Date).toISOString()};try{const e=await this.openConnection();return e.success?(this.db=e.db,this.isAvailable=!0,{success:!0,error:null,timestamp:(new Date).toISOString()}):{success:!1,error:e.error,timestamp:(new Date).toISOString()}}catch(e){return{success:!1,error:`Unexpected error: ${e.message}`,timestamp:(new Date).toISOString()}}}openConnection(){return new Promise(e=>{const t=this.configManager.getConfig(),r=indexedDB.open(t.dbName,t.dbVersion);r.onerror=()=>{e({success:!1,error:"Error opening IndexedDB",db:null})},r.onupgradeneeded=e=>{const r=e.target.result,s=this.configManager.getStoreConfig();r.objectStoreNames.contains(t.storeName)||r.createObjectStore(t.storeName,s)},r.onsuccess=()=>{e({success:!0,error:null,db:r.result})}})}close(){if(!this.db)return{success:!1,error:"No active connection to close",timestamp:(new Date).toISOString()};try{return this.db.close(),this.db=null,this.isAvailable=!1,{success:!0,error:null,timestamp:(new Date).toISOString()}}catch(e){return{success:!1,error:`Error closing connection: ${e.message}`,timestamp:(new Date).toISOString()}}}isDatabaseAvailable(){return this.isAvailable&&null!==this.db}getDatabase(){return this.isDatabaseAvailable()?this.db:null}}class c{constructor(e,t){this.connectionManager=e,this.configManager=t}getReadTransaction(){this.ensureDatabaseAvailable();const e=this.configManager.getConfig();return this.connectionManager.getDatabase().transaction([e.storeName],"readonly")}getWriteTransaction(){this.ensureDatabaseAvailable();const e=this.configManager.getConfig();return this.connectionManager.getDatabase().transaction([e.storeName],"readwrite")}getObjectStore(e){const t=this.configManager.getConfig();return e.objectStore(t.storeName)}async executeReadOperation(e){const t={success:!1,data:null,error:null,timestamp:(new Date).toISOString()};try{const r=this.getReadTransaction(),s=this.getObjectStore(r),n=await e(s);return t.success=!0,t.data=n,t}catch(e){return t.error=`Error in read operation: ${e.message}`,t}}async executeWriteOperation(e){const t={success:!1,data:null,error:null,timestamp:(new Date).toISOString()};try{const r=this.getWriteTransaction(),s=this.getObjectStore(r),n=await e(s);return t.success=!0,t.data=n,t}catch(e){return t.error=`Error in write operation: ${e.message}`,t}}ensureDatabaseAvailable(){if(!this.connectionManager.isDatabaseAvailable())throw new Error("Database not available")}getTransactionStatus(){return{isDatabaseAvailable:this.connectionManager.isDatabaseAvailable(),storeName:this.configManager.getConfig().storeName,timestamp:(new Date).toISOString()}}}class l{constructor(e,t,r){this.configManager=new a(e,t,r),this.connectionManager=new o(this.configManager),this.transactionManager=new c(this.connectionManager,this.configManager)}async init(){const e=await this.connectionManager.init();return e.success?(console.log("SyntropyFront: Database initialized"),!0):(console.warn("SyntropyFront: Error initializing database:",e.error),!1)}getReadTransaction(){return this.transactionManager.getReadTransaction()}getWriteTransaction(){return this.transactionManager.getWriteTransaction()}close(){const e=this.connectionManager.close();return!!e.success||(console.warn("SyntropyFront: Error closing database:",e.error),!1)}isDatabaseAvailable(){return this.connectionManager.isDatabaseAvailable()}get dbName(){return this.configManager.dbName}get dbVersion(){return this.configManager.dbVersion}get storeName(){return this.configManager.storeName}get db(){return this.connectionManager.getDatabase()}get isAvailable(){return this.connectionManager.isDatabaseAvailable()}}class u{constructor(e,t){this.databaseManager=e,this.serializationManager=t}async save(e){this.ensureDatabaseAvailable();const t=this.serializationManager.serialize(e),r={items:this.serializationManager.getData(t,"[]"),timestamp:(new Date).toISOString(),retryCount:0,serializationError:t.error};return this.executeWriteOperation(e=>e.add(r))}async retrieve(){if(!this.databaseManager.isDatabaseAvailable())return[];const e=await this.executeReadOperation(e=>e.getAll());return this.deserializeItems(e)}async retrieveById(e){if(!this.databaseManager.isDatabaseAvailable())return null;const t=await this.executeReadOperation(t=>t.get(e));return t?this.deserializeItem(t):null}async remove(e){return this.ensureDatabaseAvailable(),this.executeWriteOperation(t=>t.delete(e))}async update(e,t){this.ensureDatabaseAvailable();const r=await this.retrieveById(e);if(!r)throw new Error("Item not found");const s={...r,...t};return this.executeWriteOperation(e=>e.put(s))}async clear(){return this.ensureDatabaseAvailable(),this.executeWriteOperation(e=>e.clear())}ensureDatabaseAvailable(){if(!this.databaseManager.isDatabaseAvailable())throw new Error("Database not available")}executeReadOperation(e){return new Promise((t,r)=>{try{const s=this.databaseManager.getReadTransaction().objectStore(this.databaseManager.storeName),n=e(s);n.onsuccess=()=>t(n.result),n.onerror=()=>r(n.error)}catch(e){r(e)}})}executeWriteOperation(e){return new Promise((t,r)=>{try{const s=this.databaseManager.getWriteTransaction().objectStore(this.databaseManager.storeName),n=e(s);n.onsuccess=()=>t(n.result),n.onerror=()=>r(n.error)}catch(e){r(e)}})}deserializeItems(e){return e.map(e=>this.deserializeItem(e))}deserializeItem(e){const t=this.serializationManager.deserialize(e.items),r=this.serializationManager.getData(t,[]);return{...e,items:r,deserializationError:t.error}}}class h{constructor(e,t){this.storageManager=e,this.config=t}async retryFailedItems(e,t){if(this.storageManager)try{const r=await this.storageManager.retrieve();for(const s of r)if(s.retryCount<this.config.maxRetries){let r;try{r="string"==typeof s.items?n.deserialize(s.items):s.items}catch(e){console.error("SyntropyFront: Error deserializing buffer items:",e),await this.removeFailedItem(s.id);continue}if(e)try{await e(r,s.retryCount+1,s.id),t?await t(s.id):await this.removeFailedItem(s.id),console.log(`SyntropyFront: Retry successful for item ${s.id}`)}catch(e){console.warn(`SyntropyFront: Retry failed for item ${s.id}:`,e),await this.incrementRetryCount(s.id)}}else console.warn(`SyntropyFront: Item ${s.id} exceeded maximum retries, removing from buffer`),await this.removeFailedItem(s.id)}catch(e){console.error("SyntropyFront: Error processing retries:",e)}else console.warn("SyntropyFront: Storage manager not available")}async incrementRetryCount(e){try{const t=await this.storageManager.retrieveById(e);t&&await this.storageManager.update(e,{retryCount:t.retryCount+1})}catch(e){console.error("SyntropyFront: Error incrementing retry count:",e)}}async removeFailedItem(e){try{await this.storageManager.remove(e)}catch(e){console.error("SyntropyFront: Error removing failed item:",e)}}async cleanupExpiredItems(){try{const e=(await this.storageManager.retrieve()).filter(e=>e.retryCount>=this.config.maxRetries);for(const t of e)await this.removeFailedItem(t.id),console.warn(`SyntropyFront: Item ${t.id} removed for exceeding maximum retries`);e.length>0&&console.log(`SyntropyFront: Cleanup completed, ${e.length} items removed`)}catch(e){console.error("SyntropyFront: Error cleaning up expired items:",e)}}async getRetryStats(){try{const e=await this.storageManager.retrieve(),t={totalItems:e.length,itemsByRetryCount:{},averageRetryCount:0};if(e.length>0){const r=e.reduce((e,t)=>e+t.retryCount,0);t.averageRetryCount=r/e.length,e.forEach(e=>{const r=e.retryCount;t.itemsByRetryCount[r]=(t.itemsByRetryCount[r]||0)+1})}return t}catch(e){return console.error("SyntropyFront: Error getting retry statistics:",e),{totalItems:0,itemsByRetryCount:{},averageRetryCount:0}}}}const g={credit_card:(e,t)=>{const r=e.replace(/\D/g,"");return t.preserveLength?e.replace(/\d/g,(s,n)=>e.substring(0,n).replace(/\D/g,"").length<r.length-4?t.maskChar:s):`${t.maskChar.repeat(4)}-${t.maskChar.repeat(4)}-${t.maskChar.repeat(4)}-${r.slice(-4)}`},ssn:(e,t)=>{const r=e.replace(/\D/g,"");return t.preserveLength?e.replace(/\d/g,(s,n)=>e.substring(0,n).replace(/\D/g,"").length<r.length-4?t.maskChar:s):`***-**-${r.slice(-4)}`},email:(e,t)=>{const r=e.indexOf("@");if(r<=0)return g.default(e,t);const s=e.substring(0,r),n=e.substring(r);if(t.preserveLength){return(s.length>1?s.charAt(0)+t.maskChar.repeat(s.length-1):t.maskChar.repeat(s.length))+n}return`${s.charAt(0)}***${n}`},phone:(e,t)=>{const r=e.replace(/\D/g,"");return t.preserveLength?e.replace(/\d/g,(s,n)=>e.substring(0,n).replace(/\D/g,"").length<r.length-4?t.maskChar:s):`${t.maskChar.repeat(3)}-${t.maskChar.repeat(3)}-${r.slice(-4)}`},secret:(e,t)=>t.preserveLength?t.maskChar.repeat(e.length):t.maskChar.repeat(8),custom:(e,t)=>"function"==typeof t.customMask?t.customMask(e):e,default:(e,t)=>t.preserveLength?t.maskChar.repeat(e.length):t.maskChar.repeat(Math.min(e.length,8))};g.password=g.secret,g.token=g.secret;const d="credit_card",m="ssn",y="email",p="phone",f="password";const b=new class{constructor(e={}){this.maskChar=e.maskChar||"*",this.preserveLength=!1!==e.preserveLength,this.rules=[],this.strategies=new Map(Object.entries(g)),this.ansiRegex=/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g,!1!==e.enableDefaultRules&&this.addDefaultRules(),e.rules&&e.rules.forEach(e=>this.addRule(e))}addDefaultRules(){[{pattern:/credit_card|card_number|payment_number/i,strategy:d},{pattern:/ssn|social_security|security_number/i,strategy:m},{pattern:/email/i,strategy:y},{pattern:/phone|phone_number|mobile_number/i,strategy:p},{pattern:/password|pass|pwd|secret|api_key|token|auth_token|jwt|bearer/i,strategy:f}].forEach(e=>this.addRule(e))}addRule(e){this.rules.push({...e,_compiledPattern:"string"==typeof e.pattern?new RegExp(e.pattern,"i"):e.pattern,preserveLength:e.preserveLength??this.preserveLength,maskChar:e.maskChar??this.maskChar})}registerStrategy(e,t){"function"==typeof t&&this.strategies.set(e,t)}process(e){if(null==e)return e;return({string:e=>e.replace(this.ansiRegex,""),object:e=>Array.isArray(e)?e.map(e=>this.process(e)):e&&e.constructor===Object?this.maskObject(e):e}[typeof e]||(e=>e))(e)}maskObject(e){return Object.entries(e).reduce((e,[t,r])=>(e[t]=this.maskValue(t,r),e),{})}maskValue(e,t){if("string"!=typeof t)return this.process(t);const r=this.rules.find(t=>t._compiledPattern?.test(e));return r?this.applyStrategy(t,r):t.replace(this.ansiRegex,"")}applyStrategy(e,t){return(this.strategies.get(t.strategy)||this.strategies.get("default"))(e,t)}};class w{constructor(e={}){this.serializer=e.serializer??n,this.masking=e.masking??b}serialize(e){try{if(null==e)return{success:!0,data:this.serializer.serialize([]),error:null,timestamp:(new Date).toISOString()};const t=this.masking.process(e);return{success:!0,data:this.serializer.serialize(t),error:null,timestamp:(new Date).toISOString()}}catch(e){return{success:!1,data:this.createFallbackData(e),error:this.createSerializationError(e),timestamp:(new Date).toISOString()}}}deserialize(e){try{if(!e)return{success:!0,data:[],error:null,timestamp:(new Date).toISOString()};return{success:!0,data:this.serializer.deserialize(e),error:null,timestamp:(new Date).toISOString()}}catch(e){return{success:!1,data:[],error:this.createDeserializationError(e),timestamp:(new Date).toISOString()}}}createSerializationError(e){return{type:"serialization_error",message:e.message,originalError:e,timestamp:(new Date).toISOString()}}createDeserializationError(e){return{type:"deserialization_error",message:e.message,originalError:e,timestamp:(new Date).toISOString()}}createFallbackData(e){const t={__serializationError:!0,error:e.message,timestamp:(new Date).toISOString(),fallbackData:"Items not serializable - using fallback"};return JSON.stringify(t)}isSuccessful(e){return Boolean(e&&!0===e.success)}getData(e,t=null){return this.isSuccessful(e)?e.data:t}}class S{constructor(e,t={}){this.config=e,this.usePersistentBuffer=!1,this.databaseManager=t.databaseManager??new l("SyntropyFrontBuffer",1,"failedItems"),this.serializationManager=t.serializationManager??new w,this.storageManager=t.storageManager??new u(this.databaseManager,this.serializationManager),this.retryLogicManager=t.retryLogicManager??new h(this.storageManager,this.config),this.initPersistentBuffer()}async initPersistentBuffer(){try{await this.databaseManager.init()&&(this.usePersistentBuffer=this.config.usePersistentBuffer,console.log("SyntropyFront: Persistent buffer initialized"))}catch(e){console.warn("SyntropyFront: Error initializing persistent buffer:",e)}}async save(e){if(this.usePersistentBuffer)try{await this.storageManager.save(e),console.log("SyntropyFront: Items saved to persistent buffer")}catch(e){console.error("SyntropyFront: Error saving to persistent buffer:",e)}}async retrieve(){if(!this.usePersistentBuffer)return[];try{return await this.storageManager.retrieve()}catch(e){return console.error("SyntropyFront: Error retrieving from persistent buffer:",e),[]}}async remove(e){if(this.usePersistentBuffer)try{await this.storageManager.remove(e)}catch(e){console.error("SyntropyFront: Error removing from persistent buffer:",e)}}async retryFailedItems(e,t){this.usePersistentBuffer&&await this.retryLogicManager.retryFailedItems(e,t)}async cleanupExpiredItems(){this.usePersistentBuffer&&await this.retryLogicManager.cleanupExpiredItems()}async getStats(){if(!this.usePersistentBuffer)return{totalItems:0,itemsByRetryCount:{},averageRetryCount:0,isAvailable:!1};try{return{...await this.retryLogicManager.getRetryStats(),isAvailable:this.isAvailable()}}catch(e){return console.error("SyntropyFront: Error getting statistics:",e),{totalItems:0,itemsByRetryCount:{},averageRetryCount:0,isAvailable:this.isAvailable()}}}isAvailable(){return this.usePersistentBuffer&&this.databaseManager.isDatabaseAvailable()}async clear(){if(this.usePersistentBuffer)try{await this.storageManager.clear(),console.log("SyntropyFront: Persistent buffer cleared")}catch(e){console.error("SyntropyFront: Error clearing persistent buffer:",e)}}close(){this.databaseManager.close(),this.usePersistentBuffer=!1}}const v=new class{constructor(e={}){this.config=e.config||new t,this.masking=e.masking||b,this.queue=e.queue||new r(this.config),this.retry=e.retry||new s(this.config),this.transport=e.transport||new i(this.config),this.buffer=e.buffer||new S(this.config),this.setupCallbacks()}setupCallbacks(){this.queue.flushCallback=async e=>{try{await this.transport.send(e),console.log("SyntropyFront: Data sent successfully")}catch(t){console.error("SyntropyFront Agent: Error sending data:",t),this.retry.addToRetryQueue(e),await this.buffer.save(e)}},this.retry.sendCallback=async e=>await this.transport.send(e),this.retry.removePersistentCallback=async e=>{await this.buffer.remove(e)},this.buffer.sendCallback=(e,t,r)=>{this.retry.addToRetryQueue(e,t,r)}}configure(e){this.config.configure(e)}sendError(e,t=null){if(!this.config.isAgentEnabled())return void console.warn("SyntropyFront Agent: Not configured, error not sent");if(Math.random()>this.config.samplingRate)return;const r=t?{...e,context:t}:e,s=this.transport.applyEncryption(r),n=this.masking.process(s);this.queue.add({type:"error",data:n,timestamp:(new Date).toISOString()})}sendBreadcrumbs(e){if(!this.config.isAgentEnabled()||!this.config.shouldSendBreadcrumbs()||!e.length)return;if(Math.random()>this.config.samplingRate)return;const t=this.transport.applyEncryption(e),r=this.masking.process(t);this.queue.add({type:"breadcrumbs",data:r,timestamp:(new Date).toISOString()})}addToQueue(e){this.queue.add(e)}addToRetryQueue(e,t=1,r=null){this.retry.addToRetryQueue(e,t,r)}async processRetryQueue(){await this.retry.processRetryQueue(this.retry.sendCallback,this.retry.removePersistentCallback)}async flush(){await this.queue.flush(this.queue.flushCallback)}async forceFlush(){await this.flush(),this.retry.isEmpty()||(console.log("SyntropyFront: Attempting to send pending retries..."),await this.processRetryQueue())}getStats(){const e=this.config.getConfig();return{queueLength:this.queue.getSize(),retryQueueLength:this.retry.getSize(),isEnabled:this.config.isAgentEnabled(),usePersistentBuffer:e.usePersistentBuffer,maxRetries:e.maxRetries}}async retryFailedItems(){await this.buffer.retryFailedItems(this.buffer.sendCallback)}isEnabled(){return this.config.isAgentEnabled()}shouldSendBreadcrumbs(){return this.config.shouldSendBreadcrumbs()}disable(){this.config.configure({endpoint:null}),this.queue.clear(),this.retry.clear()}},I={isBrowser:()=>"undefined"!=typeof window&&"undefined"!=typeof document,getGlobal:()=>"undefined"!=typeof window?window:{},hasApi:e=>null!==e.split(".").reduce((e,t)=>null==e?null:void 0!==e[t]?e[t]:null,I.getGlobal()),runIf:(e,t,r=null)=>("function"==typeof e?e():I.hasApi(e))?t():r},k={INTERACTIVE_SELECTOR:["a","button","input","select","textarea","label","summary",'[role="button"]','[role="link"]','[role="checkbox"]','[role="radio"]','[role="menuitem"]','[role="option"]','[role="switch"]','[role="tab"]',".interactive",".btn",".clickable","[onclick]","[ng-click]","[v-on:click]","[@click]"].join(", "),hasPointerCursor:e=>{try{return"pointer"===window.getComputedStyle(e).cursor}catch(e){return!1}},findTargetByStyle:e=>e&&1===e.nodeType?k.hasPointerCursor(e)?e:e.parentElement&&e.parentElement!==document.body?k.findTargetByStyle(e.parentElement):null:null,findInteractiveTarget:e=>e&&e!==document.body&&1===e.nodeType?e.closest(k.INTERACTIVE_SELECTOR)||k.findTargetByStyle(e):null,generateSelector:e=>{if(!e)return"unknown";return`${e.tagName.toLowerCase()}${e.id?`#${e.id}`:""}${"string"==typeof e.className&&e.className?`.${e.className.split(" ").filter(Boolean).join(".")}`:""}`}};class E{constructor(){this.handler=null,this.lastClickTime=0,this.THROTTLE_MS=500}init(){I.isBrowser()&&(this.handler=e=>this.processClick(e),document.addEventListener("click",this.handler,!0))}processClick(e){const t=e?.target;if(!t||this.isThrottled())return;const r=k.findInteractiveTarget(t);r&&this.recordBreadcrumb(r)}isThrottled(){const e=Date.now(),t=e-this.lastClickTime<this.THROTTLE_MS;return t||(this.lastClickTime=e),t}recordBreadcrumb(t){const r=k.generateSelector(t);e.add({category:"ui",message:`User clicked on '${r}'`,data:{selector:r,tagName:t.tagName,id:t.id||null,className:t.className||null,text:(t.innerText||t.value||"").substring(0,30).trim()}})}destroy(){I.isBrowser()&&this.handler&&(document.removeEventListener("click",this.handler,!0),this.handler=null)}}const C=(e,t,r,s="original handler")=>{if("function"==typeof e)try{return e.apply(t,r)}catch(e){return void console.error(`SyntropyFront: Error in ${s}:`,e)}},R=(e,t,r)=>{if(!e||!(t in e))return null;const s=e[t],n=r(s);return e[t]=n,{target:e,property:t,original:s,wrapped:n,destroy:()=>{e[t]===n&&(e[t]=s)}}};class D{constructor(){this.wrapper=null}init(){"undefined"!=typeof window&&window.fetch&&(this.wrapper=R(window,"fetch",t=>(...r)=>{const s=r[0]instanceof Request?r[0].url:r[0]||"unknown",n=r[0]instanceof Request?r[0].method:r[1]?.method||"GET";return e.add({category:"network",message:`Request: ${n} ${s}`,data:{url:s,method:n,timestamp:Date.now()}}),t.apply(window,r)}))}destroy(){this.wrapper&&(this.wrapper.destroy(),this.wrapper=null)}}const z={device:{userAgent:()=>I.runIf("navigator.userAgent",()=>navigator.userAgent),language:()=>I.runIf("navigator.language",()=>navigator.language),languages:()=>I.runIf("navigator.languages",()=>navigator.languages),screen:()=>I.runIf("window.screen",()=>({width:window.screen.width,height:window.screen.height,availWidth:window.screen.availWidth,availHeight:window.screen.availHeight,colorDepth:window.screen.colorDepth,pixelDepth:window.screen.pixelDepth})),timezone:()=>I.runIf("Intl.DateTimeFormat",()=>{try{return Intl.DateTimeFormat().resolvedOptions().timeZone}catch(e){return null}}),cookieEnabled:()=>I.runIf("navigator.cookieEnabled",()=>navigator.cookieEnabled),doNotTrack:()=>I.runIf("navigator.doNotTrack",()=>navigator.doNotTrack)},window:{url:()=>I.runIf("window.location.href",()=>window.location.href),pathname:()=>I.runIf("window.location.pathname",()=>window.location.pathname),search:()=>I.runIf("window.location.search",()=>window.location.search),hash:()=>I.runIf("window.location.hash",()=>window.location.hash),referrer:()=>I.runIf("document.referrer",()=>document.referrer),title:()=>I.runIf("document.title",()=>document.title),viewport:()=>I.runIf("window.innerWidth",()=>({width:window.innerWidth,height:window.innerHeight}))},storage:{localStorage:()=>I.runIf("localStorage",()=>{try{const e=window.localStorage;return{keys:Object.keys(e).length,size:JSON.stringify(e).length,keyNames:Object.keys(e)}}catch(e){return null}}),sessionStorage:()=>I.runIf("sessionStorage",()=>{try{const e=window.sessionStorage;return{keys:Object.keys(e).length,size:JSON.stringify(e).length,keyNames:Object.keys(e)}}catch(e){return null}})},network:{online:()=>I.runIf("navigator.onLine",()=>navigator.onLine),connection:()=>I.runIf(()=>!("undefined"==typeof navigator||!(navigator.connection||navigator.mozConnection||navigator.webkitConnection)),()=>{const e=navigator.connection||navigator.mozConnection||navigator.webkitConnection;return{effectiveType:e.effectiveType,downlink:e.downlink,rtt:e.rtt}})},ui:{focused:()=>I.runIf("document.hasFocus",()=>document.hasFocus()),visibility:()=>I.runIf("document.visibilityState",()=>document.visibilityState),activeElement:()=>I.runIf("document.activeElement",()=>({tagName:document.activeElement.tagName,id:document.activeElement.id,className:document.activeElement.className}))},performance:{memory:()=>I.runIf("performance.memory",()=>({used:Math.round(performance.memory.usedJSHeapSize/1048576),total:Math.round(performance.memory.totalJSHeapSize/1048576),limit:Math.round(performance.memory.jsHeapSizeLimit/1048576)})),timing:()=>I.runIf("performance.timing",()=>({navigationStart:performance.timing.navigationStart,loadEventEnd:performance.timing.loadEventEnd}))},session:{sessionId:e=>e.generateSessionId(),startTime:()=>(new Date).toISOString(),pageLoadTime:()=>I.runIf("performance.now",()=>performance.now())}},T={device:["userAgent","language","screen","timezone"],window:["url","viewport","title"],session:["sessionId","pageLoadTime"],ui:["visibility","activeElement"],network:["online","connection"]};const M=new class{constructor(){this.sessionId=null,this.providers=new Map(Object.entries(z))}collect(e={}){const t=this.normalizeConfig(e);return Object.entries(t).reduce((e,[t,r])=>{try{const s=this.providers.get(t);if(!1!==r&&!s)throw new Error(`Provider for '${t}' not found`);const n=this.resolveFields(t,s,r);n&&(e[t]=this.extractFields(s,n))}catch(r){console.warn(`SyntropyFront: Error collecting context for ${t}:`,r),e[t]={error:"Collection failed"}}return e},{})}resolveFields(e,t,r){const s=()=>Object.keys(t||{}),n={boolean:t=>t?T[e]||s():null,object:e=>Array.isArray(e)?e:s()}[typeof r];return n?n(r):null}normalizeConfig(e){return Array.isArray(e)?e.reduce((e,t)=>({...e,[t]:!0}),{}):e||{}}extractFields(e,t){return t.reduce((t,r)=>{const s=e[r];if("function"!=typeof s)return t;try{t[r]=s(this)}catch(e){console.warn(`SyntropyFront: Error collecting field ${r}:`,e),t[r]=null}return t},{})}registerProvider(e,t){this.providers.set(e,t)}generateSessionId(){return this.sessionId=this.sessionId||`session_${this.generateSecureId()}`,this.sessionId}generateSecureId(e=("undefined"!=typeof crypto?crypto:null)){return((e=("undefined"!=typeof crypto?crypto:null))=>{if("function"==typeof e?.randomUUID)return e.randomUUID();if("function"==typeof e?.getRandomValues){const t=new Uint8Array(16);return e.getRandomValues(t),Array.from(t,e=>e.toString(16).padStart(2,"0")).join("")}return`${Date.now()}_${Math.random().toString(36).substring(2,9)}`})(e)}getAvailableTypes(){return Array.from(this.providers.keys())}get allFields(){return Array.from(this.providers.entries()).reduce((e,[t,r])=>(e[t]=r,e),{})}get defaultContexts(){return this.allFields}},O=(t,r,s,n,i)=>({type:"uncaught_exception",error:{message:t,source:r,lineno:s,colno:n,stack:i?.stack},breadcrumbs:e.getAll(),timestamp:(new Date).toISOString()}),A=t=>({type:"unhandled_rejection",error:{message:t.reason?.message||"Promise rejection without message",stack:t.reason?.stack},breadcrumbs:e.getAll(),timestamp:(new Date).toISOString()});class _{constructor(){this.errorWrapper=null,this.rejectionWrapper=null,this.config={captureErrors:!0,captureUnhandledRejections:!0},this.contextTypes=[],this.onErrorCallback=null}configure(e,t,r){this.config={...this.config,...e},this.contextTypes=t||[],this.onErrorCallback=r}init(){I.isBrowser()&&(this.setupExceptionCapture(),this.setupRejectionCapture())}setupExceptionCapture(){this.config.captureErrors&&(this.errorWrapper=R(window,"onerror",e=>(t,r,s,n,i)=>{const a=O(t,r,s,n,i);return this.handleError(a),C(e,window,[t,r,s,n,i],"original window.onerror")}))}setupRejectionCapture(){this.config.captureUnhandledRejections&&(this.rejectionWrapper=R(window,"onunhandledrejection",e=>t=>{const r=A(t);this.handleError(r),C(e,window,[t],"original window.onunhandledrejection")}))}handleError(e){const t=this.contextTypes.length>0?M.collect(this.contextTypes):null;v.sendError(e,t),this.onErrorCallback&&this.onErrorCallback(e)}destroy(){this.errorWrapper?.destroy(),this.rejectionWrapper?.destroy(),this.errorWrapper=null,this.rejectionWrapper=null}}const x=new class{constructor(){this.isInitialized=!1,this.config={captureClicks:!0,captureFetch:!0,captureErrors:!0,captureUnhandledRejections:!0},this.registry=new Map,this.initializeRegistry()}initializeRegistry(){this.registry.set("clicks",new E),this.registry.set("fetch",new D),this.registry.set("errors",new _)}configure(e={}){this.config={...this.config,...e},this.registry.get("errors")?.configure?.(this.config,e.context||[],e.onError)}init(){this.isInitialized||(this.runLifecycle("init"),this.isInitialized=!0,console.log("SyntropyFront: Interceptors initialized (Refactored architecture)"))}destroy(){this.isInitialized&&(this.runLifecycle("destroy"),this.isInitialized=!1,console.log("SyntropyFront: Interceptors destroyed"))}runLifecycle(e){[{key:"clicks",enabled:this.config.captureClicks},{key:"fetch",enabled:this.config.captureFetch},{key:"errors",enabled:this.config.captureErrors||this.config.captureUnhandledRejections}].filter(e=>e.enabled).map(e=>this.registry.get(e.key)).filter(t=>t&&"function"==typeof t[e]).forEach(t=>t[e]())}get clickInterceptor(){return this.registry.get("clicks")}get fetchInterceptor(){return this.registry.get("fetch")}get errorInterceptor(){return this.registry.get("errors")}};return new class{constructor(){this.isActive=!1,this.config={maxEvents:50,endpoint:null,headers:{},usePersistentBuffer:!0,captureClicks:!0,captureFetch:!0,captureErrors:!0,captureUnhandledRejections:!0,samplingRate:1,onError:null},this.init()}init(){this.isActive||(this._applyConfig(),x.init(),v.retryFailedItems().catch(e=>{console.warn("SyntropyFront: Error attempting to recover persistent items:",e)}),this.isActive=!0,console.log("🚀 SyntropyFront: Initialized with modular resilient architecture"))}_applyConfig(){v.configure({endpoint:this.config.endpoint,headers:this.config.headers,usePersistentBuffer:this.config.usePersistentBuffer,samplingRate:this.config.samplingRate,batchTimeout:this.config.batchTimeout??(this.config.captureClicks||this.config.captureFetch?5e3:null)}),e.onBreadcrumbAdded=e=>{v.isEnabled()&&v.shouldSendBreadcrumbs()&&v.sendBreadcrumbs([e])},x.configure({captureClicks:this.config.captureClicks,captureFetch:this.config.captureFetch,captureErrors:this.config.captureErrors,captureUnhandledRejections:this.config.captureUnhandledRejections,onError:this.config.onError})}configure(e={}){this.config={...this.config,...e},e.fetch&&(this.config.endpoint=e.fetch.url,this.config.headers=e.fetch.options?.headers||{}),this._applyConfig();const t=this.config.endpoint?`endpoint: ${this.config.endpoint}`:"console only";console.log(`✅ SyntropyFront: Configured - ${t}`)}addBreadcrumb(t,r,s={}){return e.add({category:t,message:r,data:s})}getBreadcrumbs(){return e.getAll()}clearBreadcrumbs(){e.clear()}sendError(e,t={}){const r={type:"manual_error",error:{message:e.message||String(e),name:e.name||"Error",stack:e.stack},breadcrumbs:this.getBreadcrumbs(),timestamp:(new Date).toISOString()};return v.sendError(r,t),r}async flush(){await v.forceFlush()}getStats(){return{isActive:this.isActive,breadcrumbs:e.count(),agent:v.getStats(),config:{...this.config}}}destroy(){x.destroy(),v.disable(),this.isActive=!1,console.log("SyntropyFront: Deactivated")}}}();
2
2
  //# sourceMappingURL=index.min.js.map